Skip to content
Snippets Groups Projects
Commit 85769d6e authored by Alejandro Suarez Hernandez's avatar Alejandro Suarez Hernandez
Browse files

SimpleQuery class

parent f441b825
No related branches found
No related tags found
No related merge requests found
# driver source files # driver source files
SET(sources imagine-planner.cpp types.cpp) SET(sources imagine-planner.cpp types.cpp queries.cpp)
# application header files # application header files
SET(headers imagine-planner.h types.h) SET(headers imagine-planner.h types.h queries.h)
# Boost # Boost
FIND_PACKAGE(Boost COMPONENTS system filesystem unit_test_framework REQUIRED) FIND_PACKAGE(Boost COMPONENTS system filesystem unit_test_framework REQUIRED)
# Swi-pl # Swi-pl
......
...@@ -10,4 +10,10 @@ TARGET_LINK_LIBRARIES(types_test ...@@ -10,4 +10,10 @@ TARGET_LINK_LIBRARIES(types_test
${Boost_SYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY}
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
ADD_EXECUTABLE(queries_test queries_test.cpp)
TARGET_LINK_LIBRARIES(queries_test
imagine-planner
${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY}
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
#define BOOST_TEST_MODULE Types Test
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
#include "queries.h"
#include <iostream>
using namespace imagine_planner;
#if 0 // Set to 1 if __PRETTY_FUNCTION__ macro is not available
#define __PRETTY_FUNCTION__ __func__
#endif
#if 1
#define INFO(x)\
std::cout << "\e[1m\e[32m\e[4m" << __PRETTY_FUNCTION__ << " [" << __LINE__ << "]" << "\e[24m: " << x << "\e[0m" << std::endl;
#else
#define INFO(x)
#endif
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"));
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());
}
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"));
BOOST_REQUIRE(not q1.next_solution());
BOOST_REQUIRE(not q2.next_solution());
}
...@@ -241,6 +241,20 @@ BOOST_AUTO_TEST_CASE(substitution_test) ...@@ -241,6 +241,20 @@ BOOST_AUTO_TEST_CASE(substitution_test)
BOOST_AUTO_TEST_CASE(planstate_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")});
INFO(state); PlanState state_(state), state__(state);
PlanState state2(state);
state__.remove(Predicate("p", "x", "y"));
state2.put(Predicate("q", "z"));
INFO("state: " << state << " (" << state.hash() << ')');
INFO("state_: " << state_ << " (" << state_.hash() << ')');
INFO("state__: " << state__ << " (" << state__.hash() << ')');
INFO("state2: " << state2 << " (" << state2.hash() << ')');
BOOST_CHECK_EQUAL(state, state_);
BOOST_CHECK_NE(state, state__);
BOOST_CHECK_NE(state, state2);
BOOST_CHECK(state.subset_of(state2));
BOOST_CHECK(state__.subset_of(state));
BOOST_CHECK(not state.subset_of(state__));
BOOST_CHECK(not state2.subset_of(state));
} }
#include "queries.h"
namespace imagine_planner
{
bool SimpleQuery::unify(const Predicate& goal)
{
assignment_.clear();
if (goal.arity() != target_.arity()) return false;
if (goal.get_name() != target_.get_name()) return false;
for (int idx = 0; idx < goal.arity(); ++idx)
{
const TermWrapper& term1 = target_.get_arguments()[idx];
const TermWrapper& term2 = goal.get_arguments()[idx];
if (term1.is_ground())
{
if (term1 != term2) return false;
}
else if (const Term* assig = assignment_.get(term1.to_str()))
{
if (*assig != *term2.get_term()) return false;
}
else
{
assignment_.put(term1.to_str(), term2);
}
}
return true;
}
SimpleQuery::SimpleQuery(const PlanState& state, const Predicate& target) :
state_(state), target_(target)
{
cursor_ = state_.begin();
}
bool SimpleQuery::next_solution()
{
if (cursor_ != state_.end() and target_.is_ground())
{
cursor_ = state_.end();
return state_.has(target_);
}
while (cursor_ != state_.end())
{
if (unify(*cursor_))
{
++cursor_;
return true;
}
++cursor_;
}
return false;
}
}
#ifndef _LIBIMAGINE_PLANNER_QUERIES_H_
#define _LIBIMAGINE_PLANNER_QUERIES_H_
#include "types.h"
namespace imagine_planner
{
class Query
{
public:
virtual ~Query() {};
virtual bool next_solution() =0;
virtual const Substitution& get_solution() const=0;
};
class SimpleQuery : public Query
{
private:
const PlanState& state_;
Predicate target_;
Substitution assignment_;
PlanState::CIter cursor_;
bool unify(const Predicate& goal);
public:
SimpleQuery(const PlanState& state, const Predicate& target);
virtual bool next_solution() override;
const Substitution& get_solution() const { return assignment_; }
};
class NotQuery : public Query
{
private:
Query q_;
};
} /* end namespace imagine-planner */
#endif
...@@ -109,6 +109,8 @@ TermWrapper::~TermWrapper() ...@@ -109,6 +109,8 @@ TermWrapper::~TermWrapper()
delete term_; delete term_;
} }
TermV create_term_v() { return TermV(); }
// Predicate // Predicate
Predicate::Predicate(const std::string& name, const TermV& arguments) : Predicate::Predicate(const std::string& name, const TermV& arguments) :
...@@ -306,7 +308,6 @@ std::size_t PlanState::hash() const ...@@ -306,7 +308,6 @@ std::size_t PlanState::hash() const
return acc; return acc;
} }
bool PlanState::subset_of(const PlanState& other) const bool PlanState::subset_of(const PlanState& other) const
{ {
if (predicates_.size() > other.predicates_.size()) return false; if (predicates_.size() > other.predicates_.size()) return false;
......
...@@ -191,7 +191,7 @@ class TermWrapper : public Stringifiable, ...@@ -191,7 +191,7 @@ class TermWrapper : public Stringifiable,
typedef std::vector<TermWrapper> TermV; typedef std::vector<TermWrapper> TermV;
TermV create_term_v() { return TermV(); } TermV create_term_v();
template <typename First, typename... Args> template <typename First, typename... Args>
TermV create_term_v(const First& fst, Args... args) TermV create_term_v(const First& fst, Args... args)
...@@ -261,6 +261,8 @@ class Substitution : public Stringifiable ...@@ -261,6 +261,8 @@ class Substitution : public Stringifiable
void remove(const std::string& varname); void remove(const std::string& varname);
void clear() { sigma_.clear(); }
void operator+=(const Substitution& other); void operator+=(const Substitution& other);
void operator-=(const Substitution& other); void operator-=(const Substitution& other);
...@@ -355,6 +357,6 @@ struct hash<imagine_planner::Hashable> ...@@ -355,6 +357,6 @@ struct hash<imagine_planner::Hashable>
std::size_t operator()(const imagine_planner::Hashable& hashable) const; std::size_t operator()(const imagine_planner::Hashable& hashable) const;
}; };
} } /* end std namespace */
#endif #endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment