6 #include <boost/spirit/include/phoenix.hpp>
7 #include "knowrob/queries/parsers/common.h"
8 #include "knowrob/queries/parsers/formula.h"
9 #include "knowrob/queries/parsers/terms.h"
10 #include "knowrob/queries/parsers/strings.h"
11 #include "knowrob/queries/QueryError.h"
12 #include "knowrob/formulas/Predicate.h"
13 #include "knowrob/formulas/Implication.h"
14 #include "knowrob/formulas/Conjunction.h"
15 #include "knowrob/formulas/Disjunction.h"
16 #include "knowrob/formulas/Negation.h"
17 #include "knowrob/formulas/ModalFormula.h"
18 #include "knowrob/terms/ListTerm.h"
19 #include "knowrob/terms/Term.h"
20 #include "knowrob/terms/Numeric.h"
21 #include "knowrob/TimeInterval.h"
22 #include "knowrob/Logger.h"
24 #define RETURN_FORMULA_RULE(expr) static FormulaRule r(expr); return r
25 #define RETURN_PREDICATE_RULE(expr) static PredicateRule r(expr); return r
27 #define REPORT_UNRECOGNIZED(opt) throw QueryError("Unrecognized option ({}) in modal operator.", *(opt))
35 if (optionsTerm && optionsTerm.get() !=
ListTerm::nil().get()) {
36 auto listTerm = (
ListTerm *) optionsTerm.get();
37 std::optional<std::string> agentName;
39 for (
auto &
option: *listTerm) {
41 if (!agentName.has_value() &&
option->isAtom()) {
43 agentName = std::static_pointer_cast<Atomic>(
option)->stringForm();
49 auto fn = std::static_pointer_cast<Function>(
option);
50 if (fn->arity() == 2) {
51 auto &key = fn->arguments()[0];
52 auto &value = fn->arguments()[1];
53 if (!agentName.has_value() && value->isAtom() &&
54 (*key == *a_agent1 || *key == *a_agent2)) {
55 agentName = std::static_pointer_cast<Atomic>(value)->stringForm();
64 if (agentName.has_value() && agentName.value() !=
"self") {
74 static const auto a_confidence1 =
Atom::Tabled(
"confidence");
77 if (optionsTerm && optionsTerm.get() !=
ListTerm::nil().get()) {
78 auto listTerm = (
ListTerm *) optionsTerm.get();
79 std::optional<std::string> agentName;
80 std::optional<double> confidenceValue;
82 for (
auto &
option: *listTerm) {
84 if (!agentName.has_value() &&
option->isAtom()) {
86 agentName = std::static_pointer_cast<Atomic>(
option)->stringForm();
88 }
else if (!confidenceValue.has_value() &&
option->isNumeric()) {
90 confidenceValue = std::static_pointer_cast<Numeric>(
option)->asDouble();
94 else if (
option->isFunction()) {
96 auto fn = std::static_pointer_cast<Function>(
option);
97 if (fn->arity() == 2) {
98 auto &key = fn->arguments()[0];
99 auto &value = fn->arguments()[1];
100 if (!agentName.has_value() && value->isAtom() &&
101 (*key == *a_agent1 || *key == *a_agent2)) {
102 agentName = std::static_pointer_cast<Atomic>(value)->stringForm();
104 }
else if (!confidenceValue.has_value() && value->isNumeric() &&
105 (*key == *a_confidence1 || *key == *a_confidence2)) {
106 confidenceValue = std::static_pointer_cast<Numeric>(value)->asDouble();
114 if (agentName.has_value() && agentName.value() ==
"self") agentName = std::nullopt;
116 if (agentName.has_value()) {
117 if (confidenceValue.has_value()) {
118 return modals::B(agentName.value(), confidenceValue.value());
122 }
else if (confidenceValue.has_value()) {
123 return modals::B(confidenceValue.value());
129 static inline std::optional<TimeInterval> readTimeInterval(
ListTerm *
options) {
135 std::optional<TimePoint> beginTime, endTime;
136 bool nextIsBegin =
true;
146 auto &key =
function->arguments()[0];
147 auto &value =
function->arguments()[1];
149 if (value->isNumeric()) {
150 auto numeric = std::static_pointer_cast<Numeric>(value);
151 if ((*key == *a_begin || *key == *a_since)) {
154 }
else if ((*key == *a_end || *key == *a_until)) {
161 }
else if (
option->isNumeric()) {
163 auto numeric = std::static_pointer_cast<Numeric>(
option);
172 }
else if (
option->isAtomic() && std::static_pointer_cast<Atomic>(
option)->stringForm() ==
"_") {
179 if (beginTime.has_value() || endTime.has_value()) {
187 if (optionsTerm && optionsTerm.get() !=
ListTerm::nil().get()) {
188 auto listTerm = (
ListTerm *) optionsTerm.get();
189 auto timeInterval = readTimeInterval(listTerm);
190 if (timeInterval.has_value()) {
198 if (optionsTerm && optionsTerm.get() !=
ListTerm::nil().get()) {
199 auto listTerm = (
ListTerm *) optionsTerm.get();
200 auto timeInterval = readTimeInterval(listTerm);
201 if (timeInterval.has_value()) {
210 namespace qi = boost::spirit::qi;
225 struct parsers_struct {
227 formula %= implication | brackets;
228 brackets %= (
'(' >>
formula >>
')');
230 implication = (((disjunction | brackets)
232 >> (implication | brackets))
234 | disjunction[qi::_val = qi::_1]
236 disjunction = (((conjunction | brackets)
237 >> (qi::char_(
';') | qi::char_(
'|'))
238 >> (disjunction | brackets))
239 [qi::_val = (qi::_1 | qi::_3)]
240 | conjunction[qi::_val = qi::_1]);
241 conjunction = (((unary | brackets)
242 >> (qi::char_(
',') | qi::char_(
'&'))
243 >> (conjunction | brackets))
244 [qi::_val = (qi::_1 & qi::_3)]
245 | unary[qi::_val = qi::_1]);
248 negation = ((
'~' >> (unary | brackets)) [qi::_val = ~qi::_1]);
249 modal %= belief | knowledge | occasional | always;
275 FormulaRule modal, belief, knowledge, occasional, always;
279 static parsers_struct p;
static std::shared_ptr< knowrob::Atom > Tabled(std::string_view stringForm)
static std::shared_ptr< ListTerm > nil()
std::shared_ptr< ModalFormula > K(const FormulaPtr &phi)
std::shared_ptr< ModalFormula > P(const FormulaPtr &phi)
std::shared_ptr< ModalFormula > B(const FormulaPtr &phi)
std::shared_ptr< ModalFormula > H(const FormulaPtr &phi)
StringRule & atom_or_iri()
FunctionRule & function()
TermRule & options_or_nil()
boost::phoenix::function< make_shared_f< T > > ptr_
TimePoint fromSeconds(double seconds)
std::shared_ptr< Term > TermPtr
std::shared_ptr< const ModalOperator > ModalOperatorPtr