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