diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index fc6028e63608820626adef5c62284151bcc2127c..b0fd9361b12f274a8c90c3917eb6eb13530cf52a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,5 +1,5 @@
 # driver source files
-SET(sources types.cpp) # queries.cpp effects.cpp domains.cpp parsing.cpp imagine-planner.cpp)
+SET(sources types.cpp queries.cpp) # effects.cpp domains.cpp parsing.cpp imagine-planner.cpp)
 # application header files
 SET(headers types.h) # queries.h effects.h domains.h parsing.h imagine-planner.h)
 # Ades
diff --git a/src/examples/queries_test.cpp b/src/examples/queries_test.cpp
index cf50c57870a825bb844bd22c1d7939a216a8eea7..9f4fa3def53055792e436f0e0230268bf80915a8 100644
--- a/src/examples/queries_test.cpp
+++ b/src/examples/queries_test.cpp
@@ -17,70 +17,107 @@ using namespace imagine_planner;
 #define INFO(x)
 #endif
 
+
+BOOST_AUTO_TEST_CASE(comparison_query_test_sat)
+{
+  TermFactory T;
+  PlanState dummy;
+  ComparisonQuery query1(Predicate("<", "X", "Y"));
+  ComparisonQuery query2(Predicate(">", "X", "Y"));
+  ComparisonQuery query3(Predicate("!=", "X", "Y"));
+  ComparisonQuery query4(Predicate("==", "X", "Y"));
+  INFO("query1: " << query1);
+  INFO("query2: " << query2);
+  INFO("query3: " << query3);
+  INFO("query4: " << query4);
+  Substitution sigma0_1{{"X",T(1)}, {"Y",T(10)}};
+  Substitution sigma0_2{{"X",T(1)}, {"Y",T(-1)}};
+  Substitution sigma0_3{{"X",T("a")}, {"Y",T("b")}};
+  Substitution sigma0_4{{"X",T("b")}, {"Y",T("b")}};
+  BOOST_CHECK(not query1.exists(dummy));
+  BOOST_CHECK(query1.exists(dummy, sigma0_1));
+  BOOST_CHECK(not query1.exists(dummy, sigma0_2));
+  BOOST_CHECK(not query2.exists(dummy, sigma0_1));
+  BOOST_CHECK(query2.exists(dummy, sigma0_2));
+  BOOST_CHECK(query3.exists(dummy, sigma0_3));
+  BOOST_CHECK(not query3.exists(dummy, sigma0_4));
+  BOOST_CHECK(query4.exists(dummy, sigma0_4));
+  //PlanState state({Predicate("p","a","b"), Predicate("p","a","c"),
+      //Predicate("p", "e", "d"), Predicate("p","d","a"), Predicate("q","b")});
+  //INFO("state: " << state);
+  //SimpleQuery* q1 = new SimpleQuery(state, Predicate("p", "X", "Y"));
+  //ComparisonQuery* q2 = new ComparisonQuery(state, Predicate("<", "X", "Y"));
+  //AndQuery* and1 = new AndQuery(q1, q2);
+  //INFO("and1: " << *and1);
+  //BOOST_REQUIRE(and1->next_solution());
+  //BOOST_CHECK_EQUAL(and1->get_solution().to_str(), "{\n  X -> a,\n  Y -> b\n}");
+  //BOOST_REQUIRE(and1->next_solution());
+  //BOOST_CHECK_EQUAL(and1->get_solution().to_str(), "{\n  X -> a,\n  Y -> c\n}");
+  //BOOST_REQUIRE(not and1->next_solution());
+  //delete and1;
+}
+
 BOOST_AUTO_TEST_CASE(simple_query_test_sat)
 {
   PlanState state({Predicate("p","a","b"), Predicate("p","a","c"),
       Predicate("p","d","a"), Predicate("q","w"), Predicate("q", "s")});
   INFO(state);
-  SimpleQuery q1(state, Predicate("p", "a", "X"));
-  SimpleQuery q2(state, Predicate("q", "w"));
-  INFO("q1: " << q1 << ", " << q2);
-  BOOST_REQUIRE(q1.next_solution());
-  BOOST_CHECK_EQUAL(q1.get_solution().to_str(), "{\n  X -> b\n}");
-  BOOST_REQUIRE(q1.next_solution());
-  BOOST_CHECK_EQUAL(q1.get_solution().to_str(), "{\n  X -> c\n}");
-  BOOST_REQUIRE(not q1.next_solution());
-  BOOST_REQUIRE(q2.next_solution());
-  BOOST_CHECK_EQUAL(q2.get_solution().to_str(), "{}");
-  BOOST_CHECK(not q1.next_solution());
+  SimpleQuery q1(Predicate("p", "a", "X"));
+  SimpleQuery q2(Predicate("q", "w"));
+  INFO("q1: " << q1 << ", q2: " << q2);
+  std::vector<Substitution> results1, results2;
+  q1(state, results1);
+  BOOST_REQUIRE_EQUAL(results1.size(), 2);
+  BOOST_CHECK_EQUAL(results1[0].to_str(), "{\n  X -> b\n}");
+  BOOST_CHECK_EQUAL(results1[1].to_str(), "{\n  X -> c\n}");
+  q2(state, results2);
+  BOOST_REQUIRE_EQUAL(results2.size(), 1);
+  BOOST_CHECK_EQUAL(results2[0].to_str(), "{}");
 }
 
-BOOST_AUTO_TEST_CASE(simple_query_test_unsat)
+BOOST_AUTO_TEST_CASE(not_query_test)
 {
   PlanState state({Predicate("p","a","b"), Predicate("p","a","c"),
       Predicate("p","d","a"), Predicate("q","w"), Predicate("q", "s")});
   INFO(state);
-  SimpleQuery q1(state, Predicate("p", "c", "X"));
-  SimpleQuery q2(state, Predicate("p", "a", "d"));
-  INFO("q1: " << q1 << ", " << q2);
-  BOOST_REQUIRE(not q1.next_solution());
-  BOOST_REQUIRE(not q2.next_solution());
+  Query::Ptr q1 = std::make_shared<SimpleQuery>(Predicate("p", "a", "X"));
+  Query::Ptr q1_ = std::make_shared<SimpleQuery>(Predicate("p", "Z", "d"));
+  NotQuery q2(q1);
+  NotQuery q2_(q1_);
+  INFO("q2: " << q2 << ", q2_: " << q2_);
+  BOOST_CHECK(not q2.exists(state));
+  BOOST_CHECK(q2_.exists(state));
 }
 
-BOOST_AUTO_TEST_CASE(and_query_test_sat)
-{
-  PlanState state({Predicate("p","a","b"), Predicate("p","a","c"),
-      Predicate("p", "b", "d"), Predicate("p","d","a"), Predicate("q","b")});
-  INFO("state: " << state);
-  SimpleQuery* q1 = new SimpleQuery(state, Predicate("p", "X", "Y"));
-  SimpleQuery* q2 = new SimpleQuery(state, Predicate("q", "X"));
-  NotQuery* not1 = new NotQuery(q2);
-  AndQuery* and1 = new AndQuery(q1, not1);
-  INFO("and1: " << *and1);
-  BOOST_REQUIRE(and1->next_solution());
-  BOOST_CHECK_EQUAL(and1->get_solution().to_str(), "{\n  X -> a,\n  Y -> b\n}");
-  BOOST_REQUIRE(and1->next_solution());
-  BOOST_CHECK_EQUAL(and1->get_solution().to_str(), "{\n  X -> a,\n  Y -> c\n}");
-  BOOST_REQUIRE(and1->next_solution());
-  BOOST_CHECK_EQUAL(and1->get_solution().to_str(), "{\n  X -> d,\n  Y -> a\n}");
-  BOOST_REQUIRE(not and1->next_solution());
-  delete and1;
-}
+//BOOST_AUTO_TEST_CASE(simple_query_test_unsat)
+//{
+  //PlanState state({Predicate("p","a","b"), Predicate("p","a","c"),
+      //Predicate("p","d","a"), Predicate("q","w"), Predicate("q", "s")});
+  //INFO(state);
+  //SimpleQuery q1(state, Predicate("p", "c", "X"));
+  //SimpleQuery q2(state, Predicate("p", "a", "d"));
+  //INFO("q1: " << q1 << ", " << q2);
+  //BOOST_REQUIRE(not q1.next_solution());
+  //BOOST_REQUIRE(not q2.next_solution());
+//}
 
-BOOST_AUTO_TEST_CASE(comparison_query_test_sat)
-{
-  PlanState state({Predicate("p","a","b"), Predicate("p","a","c"),
-      Predicate("p", "e", "d"), Predicate("p","d","a"), Predicate("q","b")});
-  INFO("state: " << state);
-  SimpleQuery* q1 = new SimpleQuery(state, Predicate("p", "X", "Y"));
-  ComparisonQuery* q2 = new ComparisonQuery(state, Predicate("<", "X", "Y"));
-  AndQuery* and1 = new AndQuery(q1, q2);
-  INFO("and1: " << *and1);
-  BOOST_REQUIRE(and1->next_solution());
-  BOOST_CHECK_EQUAL(and1->get_solution().to_str(), "{\n  X -> a,\n  Y -> b\n}");
-  BOOST_REQUIRE(and1->next_solution());
-  BOOST_CHECK_EQUAL(and1->get_solution().to_str(), "{\n  X -> a,\n  Y -> c\n}");
-  BOOST_REQUIRE(not and1->next_solution());
-  delete and1;
-}
+//BOOST_AUTO_TEST_CASE(and_query_test_sat)
+//{
+  //PlanState state({Predicate("p","a","b"), Predicate("p","a","c"),
+      //Predicate("p", "b", "d"), Predicate("p","d","a"), Predicate("q","b")});
+  //INFO("state: " << state);
+  //SimpleQuery* q1 = new SimpleQuery(state, Predicate("p", "X", "Y"));
+  //SimpleQuery* q2 = new SimpleQuery(state, Predicate("q", "X"));
+  //NotQuery* not1 = new NotQuery(q2);
+  //AndQuery* and1 = new AndQuery(q1, not1);
+  //INFO("and1: " << *and1);
+  //BOOST_REQUIRE(and1->next_solution());
+  //BOOST_CHECK_EQUAL(and1->get_solution().to_str(), "{\n  X -> a,\n  Y -> b\n}");
+  //BOOST_REQUIRE(and1->next_solution());
+  //BOOST_CHECK_EQUAL(and1->get_solution().to_str(), "{\n  X -> a,\n  Y -> c\n}");
+  //BOOST_REQUIRE(and1->next_solution());
+  //BOOST_CHECK_EQUAL(and1->get_solution().to_str(), "{\n  X -> d,\n  Y -> a\n}");
+  //BOOST_REQUIRE(not and1->next_solution());
+  //delete and1;
+//}
 
diff --git a/src/examples/types_test.cpp b/src/examples/types_test.cpp
index 3d2ad7153f5acb7696eac1c98e1d15384e897938..6503555f23d51cc620fec64dd1b8ad9f143c9e46 100644
--- a/src/examples/types_test.cpp
+++ b/src/examples/types_test.cpp
@@ -233,8 +233,8 @@ BOOST_AUTO_TEST_CASE(substitution_test)
   Predicate p4("q", "Y");
   Predicate p5("q", "Z");
   Predicate p6("r");
-  Substitution sigma({{"X", T("a")}, {"Y", T("b")}});
-  Substitution sigma_({{"W", T("c")}});
+  Substitution sigma{{"X", T("a")}, {"Y", T("b")}};
+  Substitution sigma_{{"W", T("c")}};
   INFO("p1 = " << p1);
   INFO("p2 = " << p2);
   INFO("p3 = " << p3);
@@ -260,7 +260,7 @@ BOOST_AUTO_TEST_CASE(substitution_test)
 
 BOOST_AUTO_TEST_CASE(planstate_test)
 {
-  PlanState state({Predicate("p", "x", "y"), Predicate("q", "y"), Predicate("r")});
+  PlanState state{Predicate("p", "x", "y"), Predicate("q", "y"), Predicate("r")};
   PlanState state_(state), state__(state);
   PlanState state2(state);
   state__.remove(Predicate("p", "x", "y"));
@@ -278,3 +278,17 @@ BOOST_AUTO_TEST_CASE(planstate_test)
   BOOST_CHECK(not state2.subset_of(state));
 }
 
+BOOST_AUTO_TEST_CASE(goal_condition)
+{
+  PlanState state{Predicate("p", "x", "y"), Predicate("q", "y"), Predicate("r")};
+  GoalCondition goal_condition1({Predicate("q", "y")}, {Predicate("p", "x", "y")});
+  GoalCondition goal_condition2({Predicate("q", "y")}, {Predicate("q", "x")});
+  GoalCondition goal_condition3({Predicate("r")}, {});
+  INFO("goal_condition1: " << goal_condition1);
+  INFO("goal_condition2: " << goal_condition2);
+  INFO("goal_condition3: " << goal_condition3);
+  BOOST_CHECK(not goal_condition1(state));
+  BOOST_CHECK(goal_condition2(state));
+  BOOST_CHECK(goal_condition3(state));
+}
+
diff --git a/src/queries.cpp b/src/queries.cpp
index 69ed107679e452f986c93353e61b58b223cbe771..9c908fc4f8156db9bfacce48398b4a8284dec309 100644
--- a/src/queries.cpp
+++ b/src/queries.cpp
@@ -3,284 +3,289 @@
 namespace imagine_planner
 {
 
-// ComparisonQuery methods
-
-ComparisonQuery::ComparisonQuery(const PlanState&, const Predicate& op,
-    const Substitution& sigma0) : op_(op), sigma0_(sigma0) {}
+// Query members
 
-std::string ComparisonQuery::to_str() const
+bool Query::exists(const PlanState& state, const Substitution& sigma0) const
 {
-  return op_.to_str();
+  std::vector<Substitution> dont_care;
+  return (*this)(state, dont_care, sigma0);
 }
 
-bool ComparisonQuery::next_solution()
+// ComparisonQuery methods
+
+
+ComparisonQuery::ComparisonQuery(const Predicate& cmp) : cmp_(cmp)
 {
-  if (done_) return false;
-  done_ = true;
-  Predicate op_sub = sigma0_(op_);
-  if (not op_sub.is_ground() or op_sub.arity() != 2) return false;
-  const TermWrapper& arg1 = op_sub.get_arguments()[0];
-  const TermWrapper& arg2 = op_sub.get_arguments()[1];
-  if (op_sub.get_name() == "==") return arg1 == arg2;
-  else if (op_sub.get_name() == "!=") return arg1 != arg2;
-  else if (op_sub.get_name() == "<") return arg1 < arg2;
-  else if (op_sub.get_name() == ">") return arg1 > arg2;
-  else if (op_sub.get_name() == "=<") return arg1 <= arg2;
-  else if (op_sub.get_name() == ">=") return arg1 >= arg2;
-  return false;
+  if (cmp.arity() != 2)
+  {
+    throw ImaginePlannerException("Arity of comparison query should be 2");
+  }
+  std::string op = cmp.get_name();
+  if (op != "<" and op != "<=" and op != "==" and
+      op != ">" and op != ">=" and op != "!=")
+  {
+    throw ImaginePlannerException("Non valid comparison");
+  }
 }
 
-void ComparisonQuery::reset(const Substitution& sigma0)
+
+std::string ComparisonQuery::to_str() const
 {
-  sigma0_ = sigma0;
-  done_ = false;
+  const Term::Ptr& arg1 = cmp_.get_arguments()[0];
+  const Term::Ptr& arg2 = cmp_.get_arguments()[1];
+  return arg1->to_str() + cmp_.get_name() + arg2->to_str();
 }
 
-// Simple query methods
-
-bool SimpleQuery::unify(const Predicate& goal)
+bool ComparisonQuery::operator()(const PlanState& state,
+    std::vector<Substitution>& results, const Substitution& sigma0) const
 {
-  if (goal.arity() != pattern_.arity()) return false;
-  if (goal.get_name() != pattern_.get_name()) return false;
-  sigma_ = sigma0_;
-  for (int idx = 0; idx < goal.arity(); ++idx)
+  bool ans = false;
+  Predicate cmp = sigma0(cmp_);
+  if (cmp.is_ground())
   {
-    const TermWrapper& term1 = pattern_.get_arguments()[idx];
-    const TermWrapper& term2 = goal.get_arguments()[idx];
-    if (term1.is_ground())
-    {
-      if (term1 != term2) return false;
-    }
-    else if (const Term* assig = sigma_.get(term1.to_str()))
-    {
-      if (*assig != *term2.get_term()) return false;
-    }
-    else
-    {
-      sigma_.put(term1.to_str(), term2);
-    }
+    const Term& arg1 = *cmp.get_arguments()[0];
+    const Term& arg2 = *cmp.get_arguments()[1];
+    std::string op = cmp.get_name();
+    if (op == "==") ans = arg1 == arg2;
+    else if (op == "!=") ans = arg1 != arg2;
+    else if (op == "<") ans = arg1 < arg2;
+    else if (op == ">") ans = arg1 > arg2;
+    else if (op == "=<") ans = arg1 <= arg2;
+    else ans = arg1 >= arg2; // op = ">="
   }
-  return true;
+  if (ans) results.push_back(sigma0);
+  return ans;
 }
 
-SimpleQuery::SimpleQuery(const PlanState& state, const Predicate& pattern,
-    const Substitution& sigma0) :
-  state_(state), pattern_(pattern), sigma0_(sigma0)
-{
-  cursor_ = state_.begin();
-}
+
+// Simple query methods
 
 std::string SimpleQuery::to_str() const
 {
   return pattern_.to_str();
 }
 
-bool SimpleQuery::next_solution()
+bool SimpleQuery::operator()(const PlanState& state,
+    std::vector<Substitution>& results, const Substitution& sigma0) const
 {
-  if (cursor_ != state_.end() and pattern_.is_ground())
+  bool found = false;
+  for (const Predicate& p : state)
   {
-    cursor_ = state_.end();
-    return state_.has(pattern_);
+    Substitution sigma(sigma0);
+    if (unify(p, sigma))
+    {
+      results.push_back(std::move(sigma));
+      found = true;
+    }
   }
+  return found;
+}
 
-  while (cursor_ != state_.end())
+bool SimpleQuery::unify(const Predicate& goal, Substitution& sigma) const
+{
+  if (goal.arity() != pattern_.arity()) return false;
+  if (goal.get_name() != pattern_.get_name()) return false;
+  for (int idx = 0; idx < goal.arity(); ++idx)
   {
-    if (unify(*cursor_))
+    const Term::Ptr& term1 = pattern_.get_arguments()[idx];
+    const Term::Ptr& term2 = goal.get_arguments()[idx];
+    if (term1->is_ground())
+    {
+      if (*term1 != *term2) return false;
+    }
+    else if (Term::Ptr assig = sigma.get(term1->to_str()))
     {
-      ++cursor_;
-      return true;
+      if (*assig != *term2) return false;
+    }
+    else
+    {
+      sigma.put(term1->to_str(), term2);
     }
-    ++cursor_;
   }
-  return false;
+  return true;
 }
 
-void SimpleQuery::reset(const Substitution& sigma0)
-{
-  sigma0_ = sigma0;
-  cursor_ = state_.begin();
-}
 
 // NotQuery methods
 
-NotQuery::NotQuery(Query* q) : query_(q), done_(false) {}
-
 std::string NotQuery::to_str() const
 {
-  if (dynamic_cast<const AndQuery*>(query_))
+  if (std::dynamic_pointer_cast<const AndQuery>(query_))
   {
     return std::string("\\+(") + query_->to_str() + ')';
   }
   return std::string("\\+") + query_->to_str();
 }
 
-bool NotQuery::next_solution()
-{
-  if (done_) return false;
-  done_ = true;
-  return not query_->next_solution();
-}
-
-void NotQuery::reset(const Substitution& sigma0)
+bool NotQuery::operator()(const PlanState& state,
+    std::vector<Substitution>& results, const Substitution& sigma0) const
 {
-  query_->reset(sigma0);
-  done_ = false;
+  bool ans = not query_->exists(state);
+  if (ans) results.push_back(sigma0);
+  return ans;
 }
 
-NotQuery::~NotQuery()
-{
-  delete query_;
-}
 
 // AndQuery methods
 
-AndQuery::AndQuery(Query* q1, Query* q2) :
-  q1_(q1), q2_(q2), first_fixed_(false) {}
-
 std::string AndQuery::to_str() const
 {
   return q1_->to_str() + ',' + q2_->to_str();
 }
 
-bool AndQuery::next_solution()
-{
-  if (first_fixed_ and q2_->next_solution())
-  {
-    return true;
-  }
-  first_fixed_ = false;
-  while (q1_->next_solution())
-  {
-    q2_->reset(q1_->get_solution());
-    if (q2_->next_solution())
-    {
-      first_fixed_ = true;
-      return true;
-    }
-  }
-  return false;
-}
-
-AndQuery::~AndQuery()
-{
-  delete q1_;
-  delete q2_;
-}
-
-// ComparisonQuerySpecification methods
-
-std::string ComparisonQuerySpecification::to_str() const
-{
-  return op_.to_str();
-}
-
-ComparisonQuerySpecification::ComparisonQuerySpecification(
-    const Predicate& op) : op_(op) {}
-
-Query* ComparisonQuerySpecification::operator()(const PlanState& state,
-    const Substitution& sigma0) const
-{
-  return new ComparisonQuery(state, op_, sigma0);
-}
-
-// SimpleQuerySpecification methods
-
-std::string SimpleQuerySpecification::to_str() const
-{
-  return pattern_.to_str();
-}
-
-SimpleQuerySpecification::SimpleQuerySpecification(const Predicate& pattern)
-  : pattern_(pattern) {}
-
-Query* SimpleQuerySpecification::operator()(const PlanState& state,
-    const Substitution& sigma0) const
-{
-  return new SimpleQuery(state, pattern_, sigma0);
-}
-
-
-// NotQuerySpecification methods
-
-void NotQuerySpecification::copy_other(const NotQuerySpecification& other)
-{
-  query_ = other.query_->clone();
-}
-
-NotQuerySpecification::NotQuerySpecification(const NotQuerySpecification& other)
-{
-  copy_other(other);
-}
-
-NotQuerySpecification::NotQuerySpecification(QuerySpecification* query)
-  : query_(query) {}
-
-NotQuerySpecification& NotQuerySpecification::operator=(
-    const NotQuerySpecification& other)
-{
-  copy_other(other);
-  return *this;
-}
-
-std::string NotQuerySpecification::to_str() const
+bool AndQuery::operator()(const PlanState& state,
+    std::vector<Substitution>& results, const Substitution& sigma0) const
 {
-  if (dynamic_cast<const AndQuerySpecification*>(query_))
+  bool ans = false;
+  std::vector<Substitution> results1;
+  (*q1_)(state, results1, sigma0);
+  for (const Substitution& sigma1 : results1)
   {
-    return std::string("\\+(") + query_->to_str() + ')';
+    std::vector<Substitution> results2;
+    ans = ans or (*q2_)(state, results2, sigma1);
   }
-  return std::string("\\+") + query_->to_str();
-}
-
-Query* NotQuerySpecification::operator()(const PlanState& state,
-    const Substitution& sigma0) const
-{
-  return new NotQuery((*query_)(state, sigma0));
-}
-
-NotQuerySpecification::~NotQuerySpecification()
-{
-  delete query_;
-}
-
-// AndQuerySpecification methods
-
-void AndQuerySpecification::copy_other(const AndQuerySpecification& other)
-{
-  q1_ = other.q1_->clone();
-  q2_ = other.q2_->clone();
-}
-
-AndQuerySpecification::AndQuerySpecification(const AndQuerySpecification& other)
-{
-  copy_other(other);
-}
-
-AndQuerySpecification& AndQuerySpecification::operator=(
-    const AndQuerySpecification& other)
-{
-  copy_other(other);
-  return *this;
-}
-
-AndQuerySpecification::AndQuerySpecification(QuerySpecification* q1,
-    QuerySpecification* q2) : q1_(q1), q2_(q2) {}
-
-std::string AndQuerySpecification::to_str() const
-{
-  return q1_->to_str() + ',' + q2_->to_str();
-}
-
-Query* AndQuerySpecification::operator()(const PlanState& state,
-    const Substitution& sigma0) const
-{
-  return new AndQuery((*q1_)(state, sigma0), (*q2_)(state, sigma0));
-}
-
-AndQuerySpecification::~AndQuerySpecification()
-{
-  delete q1_;
-  delete q2_;
-}
+  return ans;
+}
+
+//bool AndQuery::next_solution()
+//{
+  //if (first_fixed_ and q2_->next_solution())
+  //{
+    //return true;
+  //}
+  //first_fixed_ = false;
+  //while (q1_->next_solution())
+  //{
+    //q2_->reset(q1_->get_solution());
+    //if (q2_->next_solution())
+    //{
+      //first_fixed_ = true;
+      //return true;
+    //}
+  //}
+  //return false;
+//}
+
+//AndQuery::~AndQuery()
+//{
+  //delete q1_;
+  //delete q2_;
+//}
+
+//// ComparisonQuerySpecification methods
+
+//std::string ComparisonQuerySpecification::to_str() const
+//{
+  //return op_.to_str();
+//}
+
+//ComparisonQuerySpecification::ComparisonQuerySpecification(
+    //const Predicate& op) : op_(op) {}
+
+//Query* ComparisonQuerySpecification::operator()(const PlanState& state,
+    //const Substitution& sigma0) const
+//{
+  //return new ComparisonQuery(state, op_, sigma0);
+//}
+
+//// SimpleQuerySpecification methods
+
+//std::string SimpleQuerySpecification::to_str() const
+//{
+  //return pattern_.to_str();
+//}
+
+//SimpleQuerySpecification::SimpleQuerySpecification(const Predicate& pattern)
+  //: pattern_(pattern) {}
+
+//Query* SimpleQuerySpecification::operator()(const PlanState& state,
+    //const Substitution& sigma0) const
+//{
+  //return new SimpleQuery(state, pattern_, sigma0);
+//}
+
+
+//// NotQuerySpecification methods
+
+//void NotQuerySpecification::copy_other(const NotQuerySpecification& other)
+//{
+  //query_ = other.query_->clone();
+//}
+
+//NotQuerySpecification::NotQuerySpecification(const NotQuerySpecification& other)
+//{
+  //copy_other(other);
+//}
+
+//NotQuerySpecification::NotQuerySpecification(QuerySpecification* query)
+  //: query_(query) {}
+
+//NotQuerySpecification& NotQuerySpecification::operator=(
+    //const NotQuerySpecification& other)
+//{
+  //copy_other(other);
+  //return *this;
+//}
+
+//std::string NotQuerySpecification::to_str() const
+//{
+  //if (dynamic_cast<const AndQuerySpecification*>(query_))
+  //{
+    //return std::string("\\+(") + query_->to_str() + ')';
+  //}
+  //return std::string("\\+") + query_->to_str();
+//}
+
+//Query* NotQuerySpecification::operator()(const PlanState& state,
+    //const Substitution& sigma0) const
+//{
+  //return new NotQuery((*query_)(state, sigma0));
+//}
+
+//NotQuerySpecification::~NotQuerySpecification()
+//{
+  //delete query_;
+//}
+
+//// AndQuerySpecification methods
+
+//void AndQuerySpecification::copy_other(const AndQuerySpecification& other)
+//{
+  //q1_ = other.q1_->clone();
+  //q2_ = other.q2_->clone();
+//}
+
+//AndQuerySpecification::AndQuerySpecification(const AndQuerySpecification& other)
+//{
+  //copy_other(other);
+//}
+
+//AndQuerySpecification& AndQuerySpecification::operator=(
+    //const AndQuerySpecification& other)
+//{
+  //copy_other(other);
+  //return *this;
+//}
+
+//AndQuerySpecification::AndQuerySpecification(QuerySpecification* q1,
+    //QuerySpecification* q2) : q1_(q1), q2_(q2) {}
+
+//std::string AndQuerySpecification::to_str() const
+//{
+  //return q1_->to_str() + ',' + q2_->to_str();
+//}
+
+//Query* AndQuerySpecification::operator()(const PlanState& state,
+    //const Substitution& sigma0) const
+//{
+  //return new AndQuery((*q1_)(state, sigma0), (*q2_)(state, sigma0));
+//}
+
+//AndQuerySpecification::~AndQuerySpecification()
+//{
+  //delete q1_;
+  //delete q2_;
+//}
 
 }
 
diff --git a/src/queries.h b/src/queries.h
index bc6538499837d6ff927d9fd5b3b016f2d366e5c3..db2fe0e2ca81582e08fef1b19c41d2b511013377 100644
--- a/src/queries.h
+++ b/src/queries.h
@@ -14,234 +14,193 @@ class ComparisonQuery;
 class SimpleQuery;
 class NotQuery;
 class AndQuery;
-class QuerySpecification;
-class ComparisonQuerySpecification;
-class SimpleQuerySpecification;
-class NotQuerySpecification;
-class AndQuerySpecification;
+
 
 class Query : public Stringifiable
 {
   public:
-    virtual ~Query() {}
 
-    virtual bool next_solution() =0;
+    typedef std::shared_ptr<const Query> Ptr;
 
-    virtual const Substitution& get_solution() const =0;
-
-    virtual const Substitution& get_sigma0() const =0;
+    virtual ~Query() {}
 
-    virtual void reset(const Substitution& sigma0) =0;
+    virtual bool operator()(const PlanState& state,
+        std::vector<Substitution>& results,
+        const Substitution& sigma0) const =0;
 
+    virtual bool exists(const PlanState& state,
+        const Substitution& sigma0=Substitution::EMPTY) const;
 };
 
+
 class ComparisonQuery : public Query
 {
-  private:
-    Predicate op_;
-    Substitution sigma0_;
-    bool done_;
-
   public:
-    ComparisonQuery(const PlanState&, const Predicate& op,
-        const Substitution& sigma0=Substitution());
 
-    virtual std::string to_str() const override;
+    ComparisonQuery(const Predicate& cmp);
 
-    virtual bool next_solution() override;
-
-    virtual const Substitution& get_solution() const override { return sigma0_; }
+    virtual std::string to_str() const override;
 
-    virtual const Substitution& get_sigma0() const override { return sigma0_; }
+    virtual bool operator()(const PlanState& state,
+        std::vector<Substitution>& results,
+        const Substitution& sigma0=Substitution::EMPTY) const override;
 
-    virtual void reset(const Substitution& sigma0) override;
+  private:
 
+    Predicate cmp_;
 };
 
-class SimpleQuery : public Query
-{
-  private:
-    const PlanState& state_;
-    Predicate pattern_;
-    Substitution sigma0_, sigma_;
-    PlanState::CIter cursor_;
 
-    bool unify(const Predicate& goal);
-    
+class SimpleQuery : public Query
+{   
   public:
-    SimpleQuery(const PlanState& state, const Predicate& pattern,
-        const Substitution& sigma0=Substitution());
 
-    virtual std::string to_str() const override;
+    SimpleQuery(const Predicate& pattern) : pattern_(pattern) {}
 
-    virtual bool next_solution() override;
+    virtual std::string to_str() const override;
 
-    virtual const Substitution& get_solution() const override { return sigma_; }
+    virtual bool operator()(const PlanState& state,
+        std::vector<Substitution>& results,
+        const Substitution& sigma0=Substitution::EMPTY) const override;
 
-    virtual const Substitution& get_sigma0() const override { return sigma0_; }
+  private:
 
-    virtual void reset(const Substitution& sigma0) override;
+    Predicate pattern_;
 
+    bool unify(const Predicate& goal, Substitution& sigma) const;
 };
 
+
 class NotQuery : public Query
 {
-  private:
-    Query* query_;
-    bool done_;
-
   public:
-    NotQuery(Query* q);
-
-    virtual std::string to_str() const override;
 
-    virtual bool next_solution() override;
+    NotQuery(const Query::Ptr& query) : query_(query) {}
 
-    virtual const Substitution& get_solution() const override
-    {
-      return query_->get_sigma0();
-    }
+    virtual std::string to_str() const override;
 
-    virtual const Substitution& get_sigma0() const override
-    {
-      return query_->get_sigma0();
-    }
+    virtual bool operator()(const PlanState& state,
+        std::vector<Substitution>& results,
+        const Substitution& sigma0=Substitution::EMPTY) const override;
 
-    virtual void reset(const Substitution& sigma0) override;
+  private:
 
-    virtual ~NotQuery() override;
+    Query::Ptr query_;
 };
 
 class AndQuery : public Query
 {
-  private:
-    Query* q1_;
-    Query* q2_;
-    bool first_fixed_;
-
   public:
-    AndQuery(Query* q1, Query* q2);
+    AndQuery(const Query::Ptr& q1, const Query::Ptr& q2) : q1_(q1), q2_(q2) {}
 
     virtual std::string to_str() const override;
 
-    virtual bool next_solution() override;
-
-    virtual const Substitution& get_solution() const override
-    {
-      return q2_->get_solution();
-    }
-
-    virtual const Substitution& get_sigma0() const override
-    {
-      return q1_->get_sigma0();
-    }
-
-    virtual void reset(const Substitution& sigma0) override
-    {
-      q1_->reset(sigma0);
-    }
-
-    virtual ~AndQuery() override;
+    virtual bool operator()(const PlanState& state,
+        std::vector<Substitution>& results,
+        const Substitution& sigma0=Substitution::EMPTY) const override;
+ 
+  private:
 
+    Query::Ptr q1_, q2_;
 };
 
-class QuerySpecification : public Stringifiable
-{
-  public:
-    virtual Query* operator()(const PlanState& state,
-        const Substitution& sigma0=Substitution()) const=0;
+//class QuerySpecification : public Stringifiable
+//{
+  //public:
+    //virtual Query* operator()(const PlanState& state,
+        //const Substitution& sigma0=Substitution()) const=0;
 
-    virtual ~QuerySpecification() {}
+    //virtual ~QuerySpecification() {}
 
-    virtual QuerySpecification* clone() const =0;
-};
+    //virtual QuerySpecification* clone() const =0;
+//};
 
-class ComparisonQuerySpecification : public QuerySpecification
-{
-  private:
-    Predicate op_;
+//class ComparisonQuerySpecification : public QuerySpecification
+//{
+  //private:
+    //Predicate op_;
 
-  public:
-    virtual std::string to_str() const override;
+  //public:
+    //virtual std::string to_str() const override;
 
-    ComparisonQuerySpecification(const Predicate& op);
+    //ComparisonQuerySpecification(const Predicate& op);
 
-    const Predicate& get_op() const { return op_; }
+    //const Predicate& get_op() const { return op_; }
 
-    virtual Query* operator()(const PlanState& state,
-        const Substitution& sigma0=Substitution()) const override;
+    //virtual Query* operator()(const PlanState& state,
+        //const Substitution& sigma0=Substitution()) const override;
 
-    QUERY_SPEC_COMMON(ComparisonQuerySpecification);
-};
+    //QUERY_SPEC_COMMON(ComparisonQuerySpecification);
+//};
 
-// Query specifications: they don't need a state to be instantiated
+//// Query specifications: they don't need a state to be instantiated
 
-class SimpleQuerySpecification : public QuerySpecification
-{
-  private:
-    Predicate pattern_;
+//class SimpleQuerySpecification : public QuerySpecification
+//{
+  //private:
+    //Predicate pattern_;
 
-  public:
-    virtual std::string to_str() const override;
+  //public:
+    //virtual std::string to_str() const override;
 
-    SimpleQuerySpecification(const Predicate& pattern);
+    //SimpleQuerySpecification(const Predicate& pattern);
 
-    const Predicate& get_pattern() const { return pattern_; }
+    //const Predicate& get_pattern() const { return pattern_; }
 
-    virtual Query* operator()(const PlanState& state,
-        const Substitution& sigma0=Substitution()) const override;
+    //virtual Query* operator()(const PlanState& state,
+        //const Substitution& sigma0=Substitution()) const override;
 
-    QUERY_SPEC_COMMON(SimpleQuerySpecification);
-};
+    //QUERY_SPEC_COMMON(SimpleQuerySpecification);
+//};
 
-class NotQuerySpecification : public QuerySpecification
-{
-  private:
-    QuerySpecification* query_;
+//class NotQuerySpecification : public QuerySpecification
+//{
+  //private:
+    //QuerySpecification* query_;
 
-    void copy_other(const NotQuerySpecification& other);
+    //void copy_other(const NotQuerySpecification& other);
 
-  public:
-    NotQuerySpecification(const NotQuerySpecification& other);
+  //public:
+    //NotQuerySpecification(const NotQuerySpecification& other);
 
-    NotQuerySpecification(QuerySpecification* query);
+    //NotQuerySpecification(QuerySpecification* query);
 
-    NotQuerySpecification& operator=(const NotQuerySpecification& other);
+    //NotQuerySpecification& operator=(const NotQuerySpecification& other);
 
-    virtual std::string to_str() const override;
+    //virtual std::string to_str() const override;
 
-    virtual Query* operator()(const PlanState& state,
-        const Substitution& sigma0=Substitution()) const override;
+    //virtual Query* operator()(const PlanState& state,
+        //const Substitution& sigma0=Substitution()) const override;
 
-    virtual ~NotQuerySpecification() override;
+    //virtual ~NotQuerySpecification() override;
 
-    QUERY_SPEC_COMMON(NotQuerySpecification);
-};
+    //QUERY_SPEC_COMMON(NotQuerySpecification);
+//};
 
-class AndQuerySpecification : public QuerySpecification
-{
-  private:
-    QuerySpecification* q1_;
-    QuerySpecification* q2_;
+//class AndQuerySpecification : public QuerySpecification
+//{
+  //private:
+    //QuerySpecification* q1_;
+    //QuerySpecification* q2_;
 
-    void copy_other(const AndQuerySpecification& other);
+    //void copy_other(const AndQuerySpecification& other);
 
-  public:
-    AndQuerySpecification(const AndQuerySpecification& other);
+  //public:
+    //AndQuerySpecification(const AndQuerySpecification& other);
 
-    AndQuerySpecification(QuerySpecification* q1, QuerySpecification* q2);
+    //AndQuerySpecification(QuerySpecification* q1, QuerySpecification* q2);
 
-    AndQuerySpecification& operator=(const AndQuerySpecification& other);
+    //AndQuerySpecification& operator=(const AndQuerySpecification& other);
 
-    virtual std::string to_str() const override;
+    //virtual std::string to_str() const override;
 
-    virtual Query* operator()(const PlanState& state,
-        const Substitution& sigma0=Substitution()) const override;
+    //virtual Query* operator()(const PlanState& state,
+        //const Substitution& sigma0=Substitution()) const override;
 
-    virtual ~AndQuerySpecification() override;
+    //virtual ~AndQuerySpecification() override;
 
-    QUERY_SPEC_COMMON(AndQuerySpecification);
-};
+    //QUERY_SPEC_COMMON(AndQuerySpecification);
+//};
 
 } /* end namespace imagine-planner */
 
diff --git a/src/types.cpp b/src/types.cpp
index ba18032b1223ba90ad88ecaec201fabd03972258..677e3de4362f8f06614fad285507800016b32a9c 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -151,6 +151,8 @@ bool Predicate::operator<(const Predicate& predicate) const
 
 // Implementation of Substitution
 
+Substitution Substitution::EMPTY;
+
 std::string Substitution::to_str() const
 {
   std::ostringstream oss;
@@ -236,7 +238,6 @@ Predicate Substitution::operator()(const Predicate& predicate) const
   return Predicate(predicate.get_name(), arguments);
 }
 
-
 // Implementation of PlanState
 
 std::string PlanState::to_str() const
@@ -293,19 +294,17 @@ std::string GoalCondition::to_str() const
 {
   std::ostringstream oss;
   bool first = true;
-  oss << "Must appear: [";
+  oss << "[";
   for (const Predicate& pred : must_appear_)
   {
     if (not first) oss << ',';
     oss << pred;
     first = false;
   }
-  oss << "]\nCannot appear: [";
-  first = true;
   for (const Predicate& pred : cannot_appear_)
   {
     if (not first) oss << ',';
-    oss << pred;
+    oss << "\\+" << pred;
     first = false;
   }
   oss << ']';
diff --git a/src/types.h b/src/types.h
index 29d8b7d90617682486089c89d0ff87c6cb0c7f92..87899395ed9a367b335949d2df14fc8ca4d2e840 100644
--- a/src/types.h
+++ b/src/types.h
@@ -22,7 +22,7 @@ class NumberTerm;
 class Predicate;
 class Substitution;
 class PlanState;
-class GoalSpecification;
+class GoalCondition;
 
 class ImaginePlannerException : public std::exception
 {
@@ -255,8 +255,15 @@ class Substitution : public Stringifiable
     typedef std::map<std::string, Term::Ptr> Container;
     typedef Container::const_iterator CIter;
 
+    // static empty substitution for using as constant reference in some
+    // methods
+    static Substitution EMPTY;
+
     Substitution() {}
 
+    Substitution(std::initializer_list<std::pair<const std::string,Term::Ptr>> il) :
+      sigma_(il) {}
+
     Substitution(const Container& sigma) : sigma_(sigma) {}
 
     std::string to_str() const override;
@@ -311,6 +318,9 @@ class PlanState : public Stringifiable,
 
     PlanState() : hash_cached_(false) {}
 
+    PlanState(std::initializer_list<Predicate> il)
+      : predicates_(il), hash_cached_(false) {}
+
     PlanState(const Container& predicates)
       : predicates_(predicates), hash_cached_(false) {}