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 an Atom into a vector of strings.
44  * Note that this does not return a CLIPS fact because we do not store atoms
45  * (parameter names or constants) as separate facts. This needs to be further
46  * processed by the caller instead.
47  * @param a The atom to translate into a string.
48  * @return A vector that only contains the atom as is.
49  */
50 vector<string>
52 {
53  return vector<string>({a});
54 }
55 
56 /** Translate a Predicate into a vector of strings.
57  * This creates proper CLIPS effect fact strings for the Predicate and all its
58  * arguments. For compound formulae (e.g., conjunctions), this also translates
59  * all sub-formulae recursively.
60  * @param p The predicate to translate.
61  * @return A vector of strings, each string is a properly formed CLIPS fact.
62  */
63 vector<string>
65 {
66  vector<string> res;
67  if (p.function == "and") {
68  for (Expression &sub : p.arguments) {
69  vector<string> sub_effects =
70  boost::apply_visitor(EffectToCLIPSFactVisitor(pddl_operator_, positive_effect_), sub);
71  res.insert(res.end(), sub_effects.begin(), sub_effects.end());
72  }
73  } else if (p.function == "not") {
74  if (p.arguments.size() != 1) {
75  throw PddlParserException("Expected exactly one sub-formula for 'not'");
76  }
77  vector<string> sub_effects =
78  boost::apply_visitor(EffectToCLIPSFactVisitor(pddl_operator_, !positive_effect_),
79  p.arguments[0]);
80  res.insert(res.end(), sub_effects.begin(), sub_effects.end());
81  } else {
82  // We expect p.function to be a predicate name.
83  string params = "";
84  string constants = "";
85  for (auto &p : p.arguments) {
86  vector<string> p_strings =
87  boost::apply_visitor(EffectToCLIPSFactVisitor(pddl_operator_, positive_effect_), p);
88  if (p_strings.size() != 1) {
89  throw PddlParserException("Unexpected parameter length for a predicate parameter, "
90  "expected exactly one");
91  }
92  string p_string = p_strings[0];
93  if (p_string[0] == '?') {
94  // It's really a parameter.
95  if (p_string.length() <= 1) {
96  throw PddlParserException("Invalid parameter name " + p_string);
97  }
98  params += " " + p_string.substr(1);
99  constants += " nil";
100  } else {
101  // It's a constant.
102  params += " c";
103  constants += " " + p_string;
104  }
105  }
106  res.push_back(string("(domain-effect"
107  " (part-of "
108  + pddl_operator_
109  + ")"
110  " (predicate "
111  + p.function
112  + ")"
113  " (param-names "
114  + params
115  + ")"
116  " (param-constants "
117  + constants
118  + ")"
119  " (type "
120  + (positive_effect_ ? "POSITIVE" : "NEGATIVE")
121  + ")"
122  ")"));
123  }
124  return res;
125 }
pddl_parser::Predicate::arguments
std::vector< Expression > arguments
The arguments of the predicate or the subformulae of the compound formula.
Definition: pddl_ast.h:68
EffectToCLIPSFactVisitor::operator()
std::vector< std::string > operator()(pddl_parser::Atom &a) const
Translate an Atom into a vector of strings.
Definition: effect_visitor.cpp:51
pddl_parser::Predicate
A PDDL formula (either part of a precondition or an effect(.
Definition: pddl_ast.h:60
EffectToCLIPSFactVisitor::EffectToCLIPSFactVisitor
EffectToCLIPSFactVisitor(const std::string &pddl_operator, bool positive)
Constructor.
Definition: effect_visitor.cpp:38
pddl_parser::Predicate::function
Atom function
The name of the predicate for atomic formulae, 'and' for a conjunction, 'or' for a disjunction,...
Definition: pddl_ast.h:64
pddl_parser::PddlParserException
Exception thrown by the parser if an error occurs during parsing.
Definition: pddl_parser.h:47