Fawkes API  Fawkes Development Version
clips_pddl_parser_feature.cpp
1 /***************************************************************************
2  * clips_pddl_parser_feature.cpp - CLIPS PDDL Parser Feature
3  *
4  * Created: Mon 16 Oct 2017 11:14:41 CEST 11:14
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 "clips_pddl_parser_feature.h"
22 
23 #include "effect_visitor.h"
24 #include "precondition_visitor.h"
25 
26 #include <core/threading/mutex_locker.h>
27 #include <logging/logger.h>
28 #include <pddl_parser/pddl_parser.h>
29 
30 #include <clipsmm.h>
31 #include <fstream>
32 
33 using namespace std;
34 using namespace pddl_parser;
35 
36 /** @class PDDLCLIPSFeature "clips_pddl_parser_feature.h"
37  * Provide a PDDL parser to a CLIPS environment.
38  * @author Till Hofmann
39  */
40 
41 /** Initialize the CLIPS feature.
42  */
43 PDDLCLIPSFeature::PDDLCLIPSFeature() : CLIPSFeature("pddl-parser")
44 {
45 }
46 
47 /** Initialize the looger to use.
48  * @param logger The logger to use for logging in the feature
49  */
50 void
52 {
53  logger_ = logger;
54 }
55 
56 /** Initialize the context and add a parse-pddl-domain CLIPS function.
57  * @param env_name The name of the environment.
58  * @param clips The CLIPS environment to add the parser functionality to.
59  */
60 void
61 PDDLCLIPSFeature::clips_context_init(const string & env_name,
63 {
64  envs_[env_name] = clips;
65  //clips->evaluate("(path-load \"pddl.clp\")");
66  clips->add_function("parse-pddl-domain",
67  sigc::slot<void, string>(
68  sigc::bind<0>(sigc::mem_fun(*this, &PDDLCLIPSFeature::parse_domain),
69  env_name)));
70 }
71 
72 /** Clean up a context.
73  * @param env_name The name of the environment to clean.
74  */
75 void
77 {
78  envs_.erase(env_name);
79 }
80 
81 /** CLIPS function to parse a PDDL domain.
82  * This parses the given domain and asserts domain facts for all parts of the
83  * domain.
84  * @param env_name The name of the calling environment
85  * @param domain_file The path of the domain file to parse.
86  */
87 void
88 PDDLCLIPSFeature::parse_domain(std::string env_name, std::string domain_file)
89 {
90  fawkes::MutexLocker lock(envs_[env_name].objmutex_ptr());
91  CLIPS::Environment &env = **(envs_[env_name]);
92  Domain domain;
93  try {
94  ifstream df(domain_file);
95  stringstream buffer;
96  buffer << df.rdbuf();
97  domain = PddlParser::parseDomain(buffer.str());
98  } catch (PddlParserException &e) {
99  logger_->log_error(("PDDLCLIPS|" + env_name).c_str(),
100  "Failed to parse domain: %s",
101  e.what_no_backtrace());
102  return;
103  }
104  for (auto &type : domain.types) {
105  string super_type = "";
106  if (!type.second.empty()) {
107  super_type = "(super-type " + type.second + ")";
108  }
109  env.assert_fact("(domain-object-type "
110  "(name "
111  + type.first + ")" + super_type + ")");
112  }
113  for (auto &predicate : domain.predicates) {
114  string param_string = "";
115  string type_string = "";
116  for (auto &param : predicate.second) {
117  param_string += " " + param.first;
118  type_string += " " + param.second;
119  }
120  env.assert_fact("(domain-predicate"
121  " (name "
122  + predicate.first
123  + ")"
124  " (param-names "
125  + param_string
126  + ")"
127  " (param-types "
128  + type_string
129  + ")"
130  ")");
131  }
132 
133  for (auto &action : domain.actions) {
134  string params_string = "(param-names";
135  for (auto &param_pair : action.action_params) {
136  string param_name = param_pair.first;
137  string param_type = param_pair.second;
138  params_string += " " + param_name;
139  env.assert_fact("(domain-operator-parameter"
140  " (name "
141  + param_name
142  + ")"
143  " (operator "
144  + action.name
145  + ")"
146  " (type "
147  + param_type
148  + ")"
149  ")");
150  }
151  params_string += ")";
152  env.assert_fact("(domain-operator (name " + action.name + ")" + params_string + ")");
153  vector<string> precondition_facts =
154  boost::apply_visitor(PreconditionToCLIPSFactVisitor(action.name, 1, true),
155  action.precondition.expression);
156  for (auto &fact : precondition_facts) {
157  env.assert_fact(fact);
158  }
159  vector<string> effect_facts =
160  boost::apply_visitor(EffectToCLIPSFactVisitor(action.name, true), action.effect.expression);
161  for (auto &fact : effect_facts) {
162  env.assert_fact(fact);
163  }
164  }
165 }
Translate a PDDL effect into CLIPS facts.
PDDLCLIPSFeature()
Initialize the CLIPS feature.
virtual void clips_context_destroyed(const std::string &env_name)
Clean up a context.
void init_logger(fawkes::Logger *logger)
Initialize the looger to use.
virtual void clips_context_init(const std::string &env_name, fawkes::LockPtr< CLIPS::Environment > &clips)
Initialize the context and add a parse-pddl-domain CLIPS function.
Translate a PDDL precondition into CLIPS facts.
virtual const char * what_no_backtrace() const noexcept
Get primary string (does not implicitly print the back trace).
Definition: exception.cpp:663
Interface for logging.
Definition: logger.h:42
virtual void log_error(const char *component, const char *format,...)=0
Log error message.
Mutex locking helper.
Definition: mutex_locker.h:34
Exception thrown by the parser if an error occurs during parsing.
A structured representation of a PDDL domain.
Definition: pddl_ast.h:157
std::vector< Action > actions
A list of actions defined in the domain.
Definition: pddl_ast.h:173
pairs_type types
A list of types with their super types.
Definition: pddl_ast.h:163
std::vector< predicate_type > predicates
A list of predicate names in the domain, including the types of their arguments.
Definition: pddl_ast.h:169