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 
23 using namespace std;
24 using 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  */
38 EffectToCLIPSFactVisitor::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  */
48 vector<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  */
62 vector<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  */
75 vector<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