21#include "pddl_semantics.h"
23#include "pddl_exception.h"
27namespace pddl_parser {
29namespace semantics_utils {
31typing_required(
const Domain &d)
33 auto typing_reqs = {
"typing",
"adl",
"ucpop"};
34 for (
const auto &type_req : typing_reqs) {
35 if (d.requirements.end() != std::find(d.requirements.begin(), d.requirements.end(), type_req)) {
43check_type_vs_requirement(
const iterator_type &where,
bool typing_required,
const std::string &type)
45 if ((type ==
"") && typing_required) {
46 throw PddlTypeException(std::string(
"Missing type."), where);
48 if ((type !=
"") && !typing_required) {
49 throw PddlTypeException(std::string(
"Requirement typing disabled, unexpected type found."),
58 const pair_type & parsed,
59 const Domain & domain)
const
61 if (!semantics_utils::typing_required(domain)) {
62 throw PddlTypeException(std::string(
"Requirement typing disabled, unexpected type found."),
70 const pair_strings_type &parsed,
71 string_pairs_type & target)
const
73 if (parsed.second.empty()) {
74 std::transform(parsed.first.begin(),
76 std::back_inserter(target),
77 [](
const std::string &s) { return std::make_pair(s,
""); });
79 for (
const auto &variant_type : parsed.second) {
80 std::transform(parsed.first.begin(),
82 std::back_inserter(target),
83 [variant_type](
const std::string &s) {
84 return std::make_pair(s, variant_type);
88 pair_type res = target.back();
95 const pair_multi_const & parsed,
97 std::vector<std::string> &warnings)
const
100 bool typing_enabled = semantics_utils::typing_required(domain);
101 if (typing_enabled) {
103 std::find_if(domain.
types.begin(), domain.
types.end(), [parsed](
const pair_type &p) {
104 return p.first == parsed.second || p.second == parsed.second;
110 semantics_utils::check_type_vs_requirement(where, typing_enabled, parsed.second);
111 for (
const auto &constant : parsed.first) {
112 for (
const auto &dom_constants : domain.
constants) {
113 std::for_each(dom_constants.first.begin(),
114 dom_constants.first.end(),
115 [&parsed, &constant, &dom_constants, &warnings](
const auto &c)
mutable {
116 if (c == constant && parsed.second != dom_constants.second) {
117 warnings.push_back(std::string(
"Ambiguous type: ") + constant +
" type "
118 + parsed.second +
" and " + dom_constants.second);
127ActionSemantics::operator()(
const iterator_type &where,
129 const Domain & domain)
const
131 bool typing_enabled = semantics_utils::typing_required(domain);
133 if (typing_enabled) {
135 std::find_if(domain.
types.begin(), domain.
types.end(), [action_param](
const pair_type &p) {
136 return p.first == action_param.second || p.second == action_param.second;
139 throw PddlTypeException(std::string(
"Unknown type: ") + action_param.first +
" - "
140 + action_param.second,
144 semantics_utils::check_type_vs_requirement(where, typing_enabled, action_param.second);
147 string_pairs_type bound_vars;
148 check_action_condition(where, parsed.
precondition, domain, parsed, bound_vars);
149 check_action_condition(where, parsed.
effect, domain, parsed, bound_vars);
155ActionSemantics::check_type(
const iterator_type &where,
156 const std::string & got,
157 const std::string & expected,
160 if (got != expected) {
161 auto generalized_it = std::find_if(domain.
types.begin(),
163 [got](
const pair_type &p) { return p.first == got; });
164 if (generalized_it == domain.
types.end()) {
167 return check_type(where, generalized_it->second, expected, domain);
175ActionSemantics::check_action_condition(
const iterator_type &where,
178 const Action & curr_action,
179 string_pairs_type & bound_vars)
183 if (curr_obj_type == std::type_index(
typeid(Atom))) {
190 bound_vars.insert(bound_vars.end(), f.
args.begin(), f.
args.end());
191 check_action_condition(where, f.
sub_expr, domain, curr_action, bound_vars);
194 if (curr_obj_type == std::type_index(
typeid(
Predicate))) {
195 return check_action_predicate(
196 where, boost::get<Predicate>(expr.
expression), expr.
type, domain, curr_action, bound_vars);
201ActionSemantics::check_action_predicate(
const iterator_type & where,
203 const ExpressionType &type,
205 const Action & curr_action,
206 string_pairs_type & bound_vars)
208 bool typing_enabled = semantics_utils::typing_required(domain);
210 case ExpressionType::BOOL: {
211 for (
const auto &sub_expr : pred.
arguments) {
213 check_action_condition(where, sub_expr, domain, curr_action, bound_vars);
217 case ExpressionType::PREDICATE: {
222 [pred](
const predicate_type &p) { return pred.function == p.first; });
223 if (defined_pred == domain.
predicates.end()) {
228 if (defined_pred->second.size() != pred.
arguments.size()) {
230 + std::to_string(defined_pred->second.size()) +
" but got "
235 for (
size_t i = 0; i < pred.
arguments.size(); i++) {
237 != std::type_index(
typeid(Atom))) {
240 Atom curr_arg = boost::get<Atom>(pred.
arguments[i].expression);
241 bool is_type_error =
false;
242 std::string arg_type =
"";
243 if (curr_arg.front() !=
'?') {
245 bool constant_found =
false;
246 auto constant_match = std::find_if(
249 [&curr_arg, &domain, &defined_pred, &i, &where, &constant_found, &arg_type](
250 const pair_multi_const &c)
mutable {
251 if (c.first.end() != std::find(c.first.begin(), c.first.end(), curr_arg)) {
252 constant_found = true;
253 arg_type +=
" " + c.second;
254 return check_type(where, c.second, defined_pred->second[i].second, domain);
259 if (constant_match == domain.
constants.end()) {
260 is_type_error =
true;
261 if (!constant_found) {
266 auto bound_vars_match =
267 std::find_if(bound_vars.begin(), bound_vars.end(), [curr_arg](
const pair_type &c) {
268 return c.first == curr_arg.substr(1, std::string::npos);
270 if (bound_vars_match == bound_vars.end()) {
271 auto parameter_match =
274 [curr_arg](
const pair_type &c) {
275 return c.first == curr_arg.substr(1, std::string::npos);
280 arg_type = parameter_match->second;
283 arg_type = bound_vars_match->second;
285 is_type_error = !check_type(where, arg_type, defined_pred->second[i].second, domain);
288 if (typing_enabled && is_type_error) {
289 throw PddlTypeException(std::string(
"Type missmatch: Argument ") + std::to_string(i)
290 +
" of " + defined_pred->first +
" expects "
291 + defined_pred->second[i].second +
" but got " + arg_type,
Exception thrown by the parser if a declared constant does not match a defined one.
Exception thrown by the parser if an expression is invalid.
Exception thrown by the parser if a parameter mismatch is encountered.
Exception thrown by the parser if a declared relation does not match the defined predicate.
Exception thrown by the parser if declared type does not match the defined one.
This class tries to translate the found plan to interpreteable data for the rest of the program.
A structured representation of a PDDL action.
string_pairs_type action_params
A typed list of action parameters.
Expression effect
The effect of an action.
Expression precondition
The precondition of an action.
pair_multi_const operator()(const iterator_type &where, const pair_multi_const &parsed, const Domain &domain, std::vector< std::string > &warnings) const
Check whether the given type for a set of constants is defined and registers warnings if constants ar...
A structured representation of a PDDL domain.
pairs_multi_consts constants
A typed list of constants defined in the domain.
pairs_type types
A list of types with their super types.
std::vector< predicate_type > predicates
A list of predicate names in the domain, including the types of their arguments.
Retrieve the type index of an expression_t expression to determine the underlying type of the variant...
expression_t expression
The expression formula.
ExpressionType type
The type of the expression, determined at parsing time.
A PDDL formula (either part of a precondition or an effect(.
std::vector< Expression > arguments
The arguments of the predicate or the subformulae of the compound formula.
Atom function
The name of the predicate for atomic formulae, 'and' for a conjunction, 'or' for a disjunction,...
pair_type operator()(const iterator_type &where, const pair_type &parsed, const Domain &domain) const
Throw an exception if the parsed type is a sub-type but the domain does not have the requirement :typ...