Fawkes API Fawkes Development Version
effect_visitor.cpp
1/***************************************************************************
2 * effect_visitor.cpp - A static visitor to translate an effect
3 *
4 * Created: Tue 31 Oct 2017 12:39:11 CET 12:39
5 * Copyright 2017 Till Hofmann <hofmann@kbsg.rwth-aachen.de>
6 ****************************************************************************/
7
8/* This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Library General Public License for more details.
17 *
18 * Read the full text in the LICENSE.GPL file in the doc directory.
19 */
20
21#include "effect_visitor.h"
22
23using namespace std;
24using namespace pddl_parser;
25
26/** @class EffectToCLIPSFactVisitor "effect_visitor.h"
27 * Translate a PDDL effect into CLIPS facts.
28 * @author Till Hofmann
29 * Helper class to translate an effect from pddl_parser::Expression to a CLIPS
30 * fact. An expression is a boost::variant, and this class is a visitor for the
31 * variant that translates the Expression into a a vector of CLIPS facts.
32 */
33
34/** Constructor.
35 * @param pddl_operator The name of the operator this effect belongs to.
36 * @param positive True iff this is a positive (not a negative) effect.
37 */
38EffectToCLIPSFactVisitor::EffectToCLIPSFactVisitor(const string &pddl_operator, bool positive)
39: pddl_operator_(pddl_operator), positive_effect_(positive)
40{
41}
42
43/** Translate a quantified formula to a vector of strings.
44 * Not implemented yet.
45 * @param q The quantified formula to translate into a string.
46 * @return An empty vector.
47 */
48vector<string>
50{
51 throw PddlParserException("QuantifiedFormulas are not supported in CLIPS yet.");
52 return vector<string>();
53}
54
55/** Translate an Atom into a vector of strings.
56 * Note that this does not return a CLIPS fact because we do not store atoms
57 * (parameter names or constants) as separate facts. This needs to be further
58 * processed by the caller instead.
59 * @param a The atom to translate into a string.
60 * @return A vector that only contains the atom as is.
61 */
62vector<string>
64{
65 return vector<string>({a});
66}
67
68/** Translate a Predicate into a vector of strings.
69 * This creates proper CLIPS effect fact strings for the Predicate and all its
70 * arguments. For compound formulae (e.g., conjunctions), this also translates
71 * all sub-formulae recursively.
72 * @param p The predicate to translate.
73 * @return A vector of strings, each string is a properly formed CLIPS fact.
74 */
75vector<string>
77{
78 vector<string> res;
79 if (p.function == "and") {
80 for (Expression &sub : p.arguments) {
81 vector<string> sub_effects =
82 boost::apply_visitor(EffectToCLIPSFactVisitor(pddl_operator_, positive_effect_),
83 sub.expression);
84 res.insert(res.end(), sub_effects.begin(), sub_effects.end());
85 }
86 } else if (p.function == "not") {
87 if (p.arguments.size() != 1) {
88 throw PddlParserException("Expected exactly one sub-formula for 'not'");
89 }
90 vector<string> sub_effects =
91 boost::apply_visitor(EffectToCLIPSFactVisitor(pddl_operator_, !positive_effect_),
92 p.arguments[0].expression);
93 res.insert(res.end(), sub_effects.begin(), sub_effects.end());
94 } else {
95 // We expect p.function to be a predicate name.
96 string params = "";
97 string constants = "";
98 for (auto &p : p.arguments) {
99 vector<string> p_strings =
100 boost::apply_visitor(EffectToCLIPSFactVisitor(pddl_operator_, positive_effect_),
101 p.expression);
102 if (p_strings.size() != 1) {
103 throw PddlParserException("Unexpected parameter length for a predicate parameter, "
104 "expected exactly one");
105 }
106 string p_string = p_strings[0];
107 if (p_string[0] == '?') {
108 // It's really a parameter.
109 if (p_string.length() <= 1) {
110 throw PddlParserException("Invalid parameter name " + p_string);
111 }
112 params += " " + p_string.substr(1);
113 constants += " nil";
114 } else {
115 // It's a constant.
116 params += " c";
117 constants += " " + p_string;
118 }
119 }
120 res.push_back(string("(domain-effect"
121 " (part-of "
122 + pddl_operator_
123 + ")"
124 " (predicate "
125 + p.function
126 + ")"
127 " (param-names "
128 + params
129 + ")"
130 " (param-constants "
131 + constants
132 + ")"
133 " (type "
134 + (positive_effect_ ? "POSITIVE" : "NEGATIVE")
135 + ")"
136 ")"));
137 }
138 return res;
139}
std::vector< std::string > operator()(pddl_parser::Atom &a) const
Translate an Atom into a vector of strings.
EffectToCLIPSFactVisitor(const std::string &pddl_operator, bool positive)
Constructor.
Exception thrown by the parser if an error occurs during parsing.
A PDDL Expression.
Definition: pddl_ast.h:78
expression_t expression
The expression formula.
Definition: pddl_ast.h:82
A PDDL formula (either part of a precondition or an effect(.
Definition: pddl_ast.h:107
std::vector< Expression > arguments
The arguments of the predicate or the subformulae of the compound formula.
Definition: pddl_ast.h:115
Atom function
The name of the predicate for atomic formulae, 'and' for a conjunction, 'or' for a disjunction,...
Definition: pddl_ast.h:111
A PDDL quantified formula.
Definition: pddl_ast.h:89