// Path: src/main/java/de/danielbasedow/prospecter/core/MatchCondition.java
// public enum MatchCondition {
//     EQUALS,
//     LESS_THAN,
//     GREATER_THAN,
//     LESS_THAN_EQUALS,
//     GREATER_THAN_EQUALS,
//     NONE,
//     IN,
//     RADIUS
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/Token.java
// public class Token<T> {
//     private final T token;
//     private final MatchCondition condition;
// 
//     public Token(T token) {
//         this(token, MatchCondition.NONE);
//     }
// 
//     public Token(T token, MatchCondition condition) {
//         this.token = token;
//         this.condition = condition;
//     }
// 
//     public T getToken() {
//         return token;
//     }
// 
//     public int hashCode() {
//         return token.hashCode();
//     }
// 
//     public boolean equals(Object compare) {
//         if (compare instanceof Token) {
//             return token.equals(((Token) compare).getToken());
//         }
//         return false;
//     }
// 
//     public MatchCondition getCondition() {
//         return condition;
//     }
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/query/build/Clause.java
// public class Clause implements ClauseNode {
// 
//     public static enum ClauseType {
//         AND,
//         OR,
//         NOT
//     }
// 
//     private final ClauseType type;
//     private final List<ClauseNode> subClauses;
// 
//     public Clause(ClauseType type, List<ClauseNode> clauses) {
//         this.type = type;
//         this.subClauses = clauses;
//     }
// 
//     @Override
//     public boolean isLeaf() {
//         return false;
//     }
// 
//     public List<ClauseNode> getSubClauses() {
//         return subClauses;
//     }
// 
//     public ClauseType getType() {
//         return type;
//     }
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/query/build/ClauseNode.java
// public interface ClauseNode {
//     public boolean isLeaf();
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/query/build/Conjunction.java
// public class Conjunction extends FlatComplexSentence {
// 
//     @Override
//     public Connective getConnective() {
//         return Connective.AND;
//     }
// 
//     public boolean isAndSentence() {
//         return true;
//     }
// 
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/query/build/PropositionalSentenceMapper.java
// public class PropositionalSentenceMapper {
//     public static Sentence map(ClauseNode clause) {
//         if (!clause.isLeaf()) {
//             return mapAsComplexSentence((Clause) clause);
//         } else {
//             return mapAsAtomicSentence((Condition) clause);
//         }
//     }
// 
//     private static Sentence mapAsAtomicSentence(Condition clause) {
//         return new PropositionSymbol(clause);
//     }
// 
//     private static Sentence mapAsComplexSentence(Clause clause) {
//         ArrayList<Sentence> subSentences = new ArrayList<Sentence>();
//         for (ClauseNode clauseNode : clause.getSubClauses()) {
//             subSentences.add(map(clauseNode));
//         }
// 
//         Connective connective;
//         switch (clause.getType()) {
//             case AND:
//                 connective = Connective.AND;
//                 break;
//             case OR:
//                 connective = Connective.OR;
//                 break;
//             case NOT:
//                 connective = Connective.NOT;
//                 break;
//             default:
//                 connective = Connective.AND;
//         }
// 
//         return bracketIfNecessary(connective, subSentences);
//     }
// 
//     private static Sentence bracketIfNecessary(Connective connective, List<Sentence> sentences) {
//         if (connective == Connective.NOT && sentences.size() == 1) {
//             return new ComplexSentence(connective, sentences.get(0));
//         }
//         while (sentences.size() > 1) {
//             ComplexSentence newComplex = new ComplexSentence(
//                     connective,
//                     sentences.remove(sentences.size() - 1),
//                     sentences.remove(sentences.size() - 1)
//             );
//             sentences.add(newComplex);
//         }
//         return sentences.get(0);
//     }
// }


import aima.core.logic.propositional.parsing.ast.Connective;
import aima.core.logic.propositional.parsing.ast.Sentence;
import de.danielbasedow.prospecter.core.MatchCondition;
import de.danielbasedow.prospecter.core.Token;
import de.danielbasedow.prospecter.core.query.build.Clause;
import de.danielbasedow.prospecter.core.query.build.ClauseNode;
import de.danielbasedow.prospecter.core.query.build.Conjunction;
import de.danielbasedow.prospecter.core.query.build.PropositionalSentenceMapper;
import junit.framework.TestCase;
import java.util.ArrayList;
import java.util.List;
package de.danielbasedow.prospecter.core.query;



public class QueryTest extends TestCase {
    public void testFlattenOr() {
        List<ClauseNode> conditionsA = new ArrayList<ClauseNode>();
        conditionsA.add(new Condition("price", new Token<Integer>(100, MatchCondition.GREATER_THAN_EQUALS)));
        conditionsA.add(new Condition("floor", new Token<Integer>(4, MatchCondition.LESS_THAN)));
        Clause clauseA = new Clause(Clause.ClauseType.OR, conditionsA);

        List<ClauseNode> conditionsB = new ArrayList<ClauseNode>();
        conditionsB.add(new Condition("category", new Token<String>("foo", MatchCondition.EQUALS)));
        conditionsB.add(new Condition("category", new Token<String>("bar", MatchCondition.EQUALS)));
        Clause clauseB = new Clause(Clause.ClauseType.OR, conditionsB);

        List<ClauseNode> clauses = new ArrayList<ClauseNode>();
        clauses.add(clauseA);
        clauses.add(clauseB);

        Clause root = new Clause(Clause.ClauseType.OR, clauses);
        Sentence sentence = PropositionalSentenceMapper.map(root);
        assertEquals(Connective.OR, sentence.getConnective());
// Path: src/main/java/de/danielbasedow/prospecter/core/MatchCondition.java
// public enum MatchCondition {
//     EQUALS,
//     LESS_THAN,
//     GREATER_THAN,
//     LESS_THAN_EQUALS,
//     GREATER_THAN_EQUALS,
//     NONE,
//     IN,
//     RADIUS
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/Token.java
// public class Token<T> {
//     private final T token;
//     private final MatchCondition condition;
// 
//     public Token(T token) {
//         this(token, MatchCondition.NONE);
//     }
// 
//     public Token(T token, MatchCondition condition) {
//         this.token = token;
//         this.condition = condition;
//     }
// 
//     public T getToken() {
//         return token;
//     }
// 
//     public int hashCode() {
//         return token.hashCode();
//     }
// 
//     public boolean equals(Object compare) {
//         if (compare instanceof Token) {
//             return token.equals(((Token) compare).getToken());
//         }
//         return false;
//     }
// 
//     public MatchCondition getCondition() {
//         return condition;
//     }
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/query/build/Clause.java
// public class Clause implements ClauseNode {
// 
//     public static enum ClauseType {
//         AND,
//         OR,
//         NOT
//     }
// 
//     private final ClauseType type;
//     private final List<ClauseNode> subClauses;
// 
//     public Clause(ClauseType type, List<ClauseNode> clauses) {
//         this.type = type;
//         this.subClauses = clauses;
//     }
// 
//     @Override
//     public boolean isLeaf() {
//         return false;
//     }
// 
//     public List<ClauseNode> getSubClauses() {
//         return subClauses;
//     }
// 
//     public ClauseType getType() {
//         return type;
//     }
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/query/build/ClauseNode.java
// public interface ClauseNode {
//     public boolean isLeaf();
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/query/build/Conjunction.java
// public class Conjunction extends FlatComplexSentence {
// 
//     @Override
//     public Connective getConnective() {
//         return Connective.AND;
//     }
// 
//     public boolean isAndSentence() {
//         return true;
//     }
// 
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/query/build/PropositionalSentenceMapper.java
// public class PropositionalSentenceMapper {
//     public static Sentence map(ClauseNode clause) {
//         if (!clause.isLeaf()) {
//             return mapAsComplexSentence((Clause) clause);
//         } else {
//             return mapAsAtomicSentence((Condition) clause);
//         }
//     }
// 
//     private static Sentence mapAsAtomicSentence(Condition clause) {
//         return new PropositionSymbol(clause);
//     }
// 
//     private static Sentence mapAsComplexSentence(Clause clause) {
//         ArrayList<Sentence> subSentences = new ArrayList<Sentence>();
//         for (ClauseNode clauseNode : clause.getSubClauses()) {
//             subSentences.add(map(clauseNode));
//         }
// 
//         Connective connective;
//         switch (clause.getType()) {
//             case AND:
//                 connective = Connective.AND;
//                 break;
//             case OR:
//                 connective = Connective.OR;
//                 break;
//             case NOT:
//                 connective = Connective.NOT;
//                 break;
//             default:
//                 connective = Connective.AND;
//         }
// 
//         return bracketIfNecessary(connective, subSentences);
//     }
// 
//     private static Sentence bracketIfNecessary(Connective connective, List<Sentence> sentences) {
//         if (connective == Connective.NOT && sentences.size() == 1) {
//             return new ComplexSentence(connective, sentences.get(0));
//         }
//         while (sentences.size() > 1) {
//             ComplexSentence newComplex = new ComplexSentence(
//                     connective,
//                     sentences.remove(sentences.size() - 1),
//                     sentences.remove(sentences.size() - 1)
//             );
//             sentences.add(newComplex);
//         }
//         return sentences.get(0);
//     }
// }


// Path: src/test/java/de/danielbasedow/prospecter/core/query/QueryTest.java
import aima.core.logic.propositional.parsing.ast.Connective;
import aima.core.logic.propositional.parsing.ast.Sentence;
import de.danielbasedow.prospecter.core.MatchCondition;
import de.danielbasedow.prospecter.core.Token;
import de.danielbasedow.prospecter.core.query.build.Clause;
import de.danielbasedow.prospecter.core.query.build.ClauseNode;
import de.danielbasedow.prospecter.core.query.build.Conjunction;
import de.danielbasedow.prospecter.core.query.build.PropositionalSentenceMapper;
import junit.framework.TestCase;
import java.util.ArrayList;
import java.util.List;

package de.danielbasedow.prospecter.core.query;



public class QueryTest extends TestCase {
    public void testFlattenOr() {
        List<ClauseNode> conditionsA = new ArrayList<ClauseNode>();
        conditionsA.add(new Condition("price", new Token<Integer>(100, MatchCondition.GREATER_THAN_EQUALS)));
        conditionsA.add(new Condition("floor", new Token<Integer>(4, MatchCondition.LESS_THAN)));
        Clause clauseA = new Clause(Clause.ClauseType.OR, conditionsA);

        List<ClauseNode> conditionsB = new ArrayList<ClauseNode>();
        conditionsB.add(new Condition("category", new Token<String>("foo", MatchCondition.EQUALS)));
        conditionsB.add(new Condition("category", new Token<String>("bar", MatchCondition.EQUALS)));
        Clause clauseB = new Clause(Clause.ClauseType.OR, conditionsB);

        List<ClauseNode> clauses = new ArrayList<ClauseNode>();
        clauses.add(clauseA);
        clauses.add(clauseB);

        Clause root = new Clause(Clause.ClauseType.OR, clauses);
        Sentence sentence = PropositionalSentenceMapper.map(root);
        assertEquals(Connective.OR, sentence.getConnective());
        assertEquals(2, sentence.getNumberSimplerSentences());