diff --git a/src/examples/queries_test.cpp b/src/examples/queries_test.cpp index e520790997570e3e0f7d8e42b4159e015140c6d9..ca9aa7c50df273ef1a9273e1f762aedb9ddb16bd 100644 --- a/src/examples/queries_test.cpp +++ b/src/examples/queries_test.cpp @@ -45,3 +45,19 @@ BOOST_AUTO_TEST_CASE(simple_query_test_unsat) BOOST_REQUIRE(not q2.next_solution()); } +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","a"), + Predicate("q", "d")}); + INFO("state: " << state); + SimpleQuery q1(state, Predicate("p", "X", "Y")); + SimpleQuery q2(state, Predicate("q", "X")); + //NotQuery not1(q2); + AndQuery and1(q1, q2); + while (and1.next_solution()) + { + INFO(and1.get_solution()); + } +} + diff --git a/src/queries.cpp b/src/queries.cpp index b6ddecd77f9354809c0f443d5fc3c59078d8b793..9ec9d7bde3121b2d5668c4c7d27c40149ca56766 100644 --- a/src/queries.cpp +++ b/src/queries.cpp @@ -3,11 +3,13 @@ namespace imagine_planner { +// Simple query methods + bool SimpleQuery::unify(const Predicate& goal) { - assignment_.clear(); if (goal.arity() != target_.arity()) return false; if (goal.get_name() != target_.get_name()) return false; + sigma_ = sigma0_; for (int idx = 0; idx < goal.arity(); ++idx) { const TermWrapper& term1 = target_.get_arguments()[idx]; @@ -16,20 +18,21 @@ bool SimpleQuery::unify(const Predicate& goal) { if (term1 != term2) return false; } - else if (const Term* assig = assignment_.get(term1.to_str())) + else if (const Term* assig = sigma_.get(term1.to_str())) { if (*assig != *term2.get_term()) return false; } else { - assignment_.put(term1.to_str(), term2); + sigma_.put(term1.to_str(), term2); } } return true; } -SimpleQuery::SimpleQuery(const PlanState& state, const Predicate& target) : - state_(state), target_(target) +SimpleQuery::SimpleQuery(const PlanState& state, const Predicate& target, + const Substitution& sigma0) : + state_(state), target_(target), sigma0_(sigma0) { cursor_ = state_.begin(); } @@ -54,5 +57,52 @@ bool SimpleQuery::next_solution() return false; } +void SimpleQuery::reset(const Substitution& sigma0) +{ + sigma0_ = sigma0; + cursor_ = state_.begin(); +} + +// NotQuery methods + +NotQuery::NotQuery(Query& q) : query_(q), done_(false) {} + +bool NotQuery::next_solution() +{ + if (done_) return false; + done_ = true; + return not query_.next_solution(); +} + +void NotQuery::reset(const Substitution& sigma0) +{ + query_.reset(sigma0); + done_ = false; +} + +// AndQuery methods + +AndQuery::AndQuery(Query& q1, Query& q2) : + q1_(q1), q2_(q2), first_fixed_(false) {} + +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; +} + } diff --git a/src/queries.h b/src/queries.h index 2750220500817d45c3f9a3b1463958b39c829783..3efe6e4f5f660b41333cda521410133fbec859d5 100644 --- a/src/queries.h +++ b/src/queries.h @@ -13,7 +13,12 @@ class Query virtual bool next_solution() =0; - virtual const Substitution& get_solution() const=0; + virtual const Substitution& get_solution() const =0; + + virtual const Substitution& get_sigma0() const =0; + + virtual void reset(const Substitution& sigma0) =0; + }; class SimpleQuery : public Query @@ -21,24 +26,76 @@ class SimpleQuery : public Query private: const PlanState& state_; Predicate target_; - Substitution assignment_; + Substitution sigma0_, sigma_; PlanState::CIter cursor_; bool unify(const Predicate& goal); public: - SimpleQuery(const PlanState& state, const Predicate& target); + SimpleQuery(const PlanState& state, const Predicate& target, + const Substitution& sigma0=Substitution()); virtual bool next_solution() override; - const Substitution& get_solution() const { return assignment_; } + virtual const Substitution& get_solution() const override { return sigma_; } + + virtual const Substitution& get_sigma0() const override { return sigma0_; } + + virtual void reset(const Substitution& sigma0) override; }; class NotQuery : public Query { private: - Query q_; + Query& query_; + bool done_; + + public: + NotQuery(Query& q); + + virtual bool next_solution() override; + + virtual const Substitution& get_solution() const override + { + return query_.get_sigma0(); + } + + virtual const Substitution& get_sigma0() const override + { + return query_.get_sigma0(); + } + + virtual void reset(const Substitution& sigma0) override; +}; + +class AndQuery : public Query +{ + private: + Query& q1_; + Query& q2_; + bool first_fixed_; + + public: + AndQuery(Query& q1, Query& q2); + + 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); + } + }; } /* end namespace imagine-planner */