diff --git a/.gitignore b/.gitignore index 9c975f121abf3137eda44530ea880e33ab094774..9a631c161cca74d926535103e0063b3a7c9262b0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +bin/ doc/html doc/images diff --git a/CMakeLists.txt b/CMakeLists.txt index 31ed2bf0abc49a84a589e7e4ff0f5fcfe43b453e..3cc336dfa7ec7df5ac8e88f4cd3d69be673c504b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,8 @@ IF (NOT CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE "DEBUG") ENDIF (NOT CMAKE_BUILD_TYPE) +SET(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}") + SET(CMAKE_CXX_FLAGS_DEBUG "-g -Wall -D_REENTRANT") SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -D_REENTRANT") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c21ef23e78736c90ff9874c96873175d74f905c3..2cfb4bebc8f093c43acdf22b7bf6e325732089ee 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,7 +1,7 @@ # driver source files -SET(sources imagine-planner.cpp) +SET(sources imagine-planner.cpp types.cpp) # application header files -SET(headers imagine-planner.h) +SET(headers imagine-planner.h types.h) # locate the necessary dependencies # add the necessary include directories INCLUDE_DIRECTORIES(.) diff --git a/src/examples/CMakeLists.txt b/src/examples/CMakeLists.txt index 0e52b5a59e98661447b769a90a8ae72ab710c40c..0d77386b771a7412909d6a27b572a44f745b791c 100644 --- a/src/examples/CMakeLists.txt +++ b/src/examples/CMakeLists.txt @@ -1,3 +1,6 @@ +ADD_EXECUTABLE(types_test types_test.cpp) +TARGET_LINK_LIBRARIES(types_test imagine-planner) + # create an example application ADD_EXECUTABLE(imagine-planner_test imagine-planner_test.cpp) # link necessary libraries diff --git a/src/examples/types_test.cpp b/src/examples/types_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..74ca6ad1bd0e36ab4f84139e8d3d022c670c1e0e --- /dev/null +++ b/src/examples/types_test.cpp @@ -0,0 +1,20 @@ +#include <iostream> +#include "types.h" +using namespace imagine_planner; + +const char* b2s(bool b) +{ + return b? "true" : "false"; +} + +int main(int argc, char* argv[]) +{ + std::hash<Term> h; + Term* atom = new Atom("my_atom"); + Term* atom_ = new Atom("another_atom"); + std::cout << "Testing stream operator for Atom: " << *atom << std::endl; + std::cout << "Testing hash function for Atom: " << h(*atom) << std::endl; + std::cout << "Testing == operator (equal): " << b2s(*atom == *atom) << std::endl; + std::cout << "Testing == operator (not equal): " << b2s(*atom == *atom_) << std::endl; +} + diff --git a/src/imagine-planner.cpp b/src/imagine-planner.cpp index 764e4d579565085a72c6255b083be8ba2e41a5b5..3ec12725d53d977af12b82479d4359ab9507d26b 100644 --- a/src/imagine-planner.cpp +++ b/src/imagine-planner.cpp @@ -1,10 +1,10 @@ #include "imagine-planner.h" -CImagine-Planner::CImagine-Planner() +CImaginePlanner::CImaginePlanner() { } -CImagine-Planner::~CImagine-Planner() +CImaginePlanner::~CImaginePlanner() { } diff --git a/src/imagine-planner.h b/src/imagine-planner.h index 025557cc3eb5653e1068cb143864018807de77a1..22c2a6fa6049aeb6874914318805913c2c15124f 100644 --- a/src/imagine-planner.h +++ b/src/imagine-planner.h @@ -1,11 +1,11 @@ -#ifndef _IMAGINE-PLANNER_H -#define _IMAGINE-PLANNER_H +#ifndef _IMAGINE_PLANNER_H_ +#define _IMAGINE_PLANNER_H_ -class CImagine-Planner +class CImaginePlanner { public: - CImagine-Planner(); - ~CImagine-Planner(); + CImaginePlanner(); + ~CImaginePlanner(); }; #endif diff --git a/src/types.cpp b/src/types.cpp new file mode 100644 index 0000000000000000000000000000000000000000..09174c7399b75e4ba81a2e7efa05f85d38a85dbd --- /dev/null +++ b/src/types.cpp @@ -0,0 +1,70 @@ +#include "types.h" +#include <cmath> + +namespace imagine_planner +{ + +// Implementation of Atom's methods + +Atom::Atom(const std::string& name) : name_(name) {} + +bool Atom::operator==(const Term& other) const +{ + if (const Atom* c_other = dynamic_cast<const Atom*>(&other)) + { + return c_other->name_ == this->name_; + } + return false; +} + +std::size_t Atom::hash() const +{ + std::hash<std::string> h; + return h(name_); +} + +// Implementation of Number's methods + +Number::Number(double number) : number_(number) {} + +bool Number::operator==(const Term& other) const +{ + if (const Number* c_other = dynamic_cast<const Number*>(&other)) + { + return std::fabs(number_ - c_other->number_) < 1E-9; + } + return false; +} + +std::size_t Number::hash() const +{ + std::hash<int> h; + return is_int()? h(int(number_)) : 0; // Return 0 for non-integer values to + // avoid problems in maps and sets +} + +bool Number::is_int() const +{ + return std::fabs(number_ - int(number_)) < 1E-9; +} + +// Implementation of stream operator + +std::ostream& operator<<(std::ostream& os, const Term& term) +{ + os << term.to_str(); + return os; +} + +} /* end imagine_planner namespace */ + +namespace std +{ + +std::size_t hash<imagine_planner::Term>::operator()(const imagine_planner::Term& term) const +{ + return term.hash(); +} + +} + diff --git a/src/types.h b/src/types.h new file mode 100644 index 0000000000000000000000000000000000000000..6b8b074f4341df0a81d74913454e58c222a83309 --- /dev/null +++ b/src/types.h @@ -0,0 +1,143 @@ +#ifndef _LIBIMAGINE_PLANNER_TYPES_H_ +#define _LIBIMAGINE_PLANNER_TYPES_H_ + +#include <functional> +#include <ostream> +#include <string> +#include <vector> + +namespace imagine_planner +{ + +/** + * @brief Generic Term class. + */ +class Term +{ + public: + + virtual std::string to_str() const =0; + + virtual bool is_ground() const =0; + + virtual bool is_atomic() const =0; + + virtual bool operator==(const Term& other) const =0; + + virtual std::size_t hash() const =0; + + virtual ~Term() {} +}; + + +/** + * @brief + */ +class Atom : public Term +{ + private: + + std::string name_; + + public: + + Atom(const std::string& name); + + virtual std::string to_str() const override { return name_; } + + virtual bool is_ground() const override { return true; } + + virtual bool is_atomic() const override { return true; } + + virtual bool operator==(const Term& other) const override; + + virtual std::size_t hash() const override; + + virtual std::string name() const { return name_; } + +}; + + +class Number : public Term +{ + private: + + double number_; + + public: + + Number(double number); + + virtual std::string to_str() const override { return std::to_string(number_); } + + virtual bool is_ground() const override { return true; } + + virtual bool is_atomic() const override { return true; } + + virtual bool operator==(const Term& other) const override; + + virtual std::size_t hash() const override; + + bool is_int() const; + + double number() const { return number_; } + +}; + + +class Variable : public Term +{ + +}; + + +class TermV : public Term +{ + private: + + std::vector<Term> term_v_; + + public: + + TermV(const std::vector<Term>& term_v); + + TermV(std::initializer_list<Term> il); + +}; + + +class Compound : public Term +{ + +}; + +/** + * @brief Stream operator that conveniently puts a Term printable version into + * an output stream. + * + * @param os Output stream + * @param term Term to be written into the stream + * + * @return os after the insertion + */ +std::ostream& operator<<(std::ostream& os, const Term& term); + + +} /* end imagine_planner namespace */ + +namespace std +{ + +/** + * @brief hash struct specialized to Term instances, so they can be used in + * unordered sets or maps. + */ +template<> +struct hash<imagine_planner::Term> +{ + std::size_t operator()(const imagine_planner::Term& term) const; +}; + +} + +#endif