Commit 85769d6e authored by Alejandro Suarez Hernandez's avatar Alejandro Suarez Hernandez
Browse files

SimpleQuery class

parent f441b825
# 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
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment