added prolog support
src/examples/query_test.cpp
0 → 100644
#include "types.h" | ||
#include <iostream> | ||
#include <cmath> | ||
#include <sstream> | ||
namespace imagine_planner | ||
{ | ||
// Implementation of Atom's methods | ||
// LiteralTerm | ||
Atom::Atom(const std::string& name) : name_(name) {} | ||
LiteralTerm::LiteralTerm(const std::string& literal) : literal_(literal) {} | ||
bool Atom::operator==(const Term& other) const | ||
std::size_t LiteralTerm::hash() const | ||
{ | ||
if (const Atom* c_other = dynamic_cast<const Atom*>(&other)) | ||
{ | ||
return this->name_ == c_other->name_; | ||
} | ||
return false; | ||
} | ||
bool Atom::operator<(const Term& other) const | ||
{ | ||
if (const Atom* c_other = dynamic_cast<const Atom*>(&other)) | ||
{ | ||
return this->name_ < c_other->name_; | ||
} | ||
return this->type() < other.type(); | ||
std::hash<std::string> h; | ||
return h(literal_); | ||
} | ||
std::size_t Atom::hash() const | ||
bool LiteralTerm::is_ground() const | ||
{ | ||
std::hash<std::string> h; | ||
return h(name_); | ||
if (literal_.empty()) return false; | ||
if (literal_[0] == '_') return false; | ||
if (literal_[0] >= 'A' and literal_[0] <= 'Z') return false; | ||
return true; | ||
} | ||
// Implementation of Number's methods | ||
double Number::EPSILON_ = 1E-9; | ||
Number::Number(double number) : number_(number) {} | ||
bool Number::operator==(const Term& other) const | ||
bool LiteralTerm::operator==(const Term& term) const | ||
{ | ||
if (const Number* c_other = dynamic_cast<const Number*>(&other)) | ||
if (auto other = dynamic_cast<const LiteralTerm*>(&term)) | ||
{ | ||
return std::fabs(this->number_ - c_other->number_) < EPSILON_; | ||
return this->literal_ == other->literal_; | ||
} | ||
return false; | ||
} | ||
bool Number::operator<(const Term& other) const | ||
bool LiteralTerm::operator<(const Term& term) const | ||
{ | ||
if (const Number* c_other = dynamic_cast<const Number*>(&other)) | ||
if (auto other = dynamic_cast<const LiteralTerm*>(&term)) | ||
{ | ||
return c_other->number_ - this->number_ >= EPSILON_; | ||
return this->literal_ < other->literal_; | ||
} | ||
return this->type() < other.type(); | ||
return type() < term.type(); | ||
} | ||
std::size_t Number::hash() const | ||
// NumberTerm | ||
double NumberTerm::EPSILON_ = 1E-9; | ||
NumberTerm::NumberTerm(double number) : number_(number) {} | ||
std::size_t NumberTerm::hash() const | ||
{ | ||
std::hash<int> h; | ||
// Return 0 for non-integer values to avoid problems in maps and sets | ||
// (non-integer quantities would be assigned to the same bucket). | ||
return is_int()? h(std::round(number_)) : 0; | ||
return is_int()? h((int)std::round(number_)) : 0; | ||
} | ||
bool Number::is_int() const | ||
bool NumberTerm::is_int() const | ||
{ | ||
return std::fabs(number_ - std::round(number_)) < EPSILON_; | ||
} | ||
// Implementation of Variable's methods | ||
Variable::Variable(const std::string& name) : name_(name) {} | ||
bool Variable::operator==(const Term& other) const | ||
bool NumberTerm::operator==(const Term& term) const | ||
{ | ||
if (const Variable* c_other = dynamic_cast<const Variable*>(&other)) | ||
if (auto other = dynamic_cast<const NumberTerm*>(&term)) | ||
{ | ||
return this->name_ == c_other->name_; | ||
return std::fabs(this->number_ - other->number_) < EPSILON_; | ||
} | ||
return false; | ||
} | ||
bool Variable::operator<(const Term& other) const | ||
bool NumberTerm::operator<(const Term& term) const | ||
{ | ||
if (const Variable* c_other = dynamic_cast<const Variable*>(&other)) | ||
if (auto other = dynamic_cast<const NumberTerm*>(&term)) | ||
{ | ||
return this->name_ < c_other->name_; | ||
return other->number_ - this->number_ >= EPSILON_; | ||
} | ||
return this->type() < other.type(); | ||
} | ||
std::size_t Variable::hash() const | ||
{ | ||
std::hash<std::string> h; | ||
return h(name_); | ||
return type() < term.type(); | ||
} | ||
< |