1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//! Provides parsers for domain structure definitions.
use nom::branch::alt;
use nom::combinator::map;
use nom::Parser;
use crate::parsers::{parse_action_def, parse_da_def, parse_derived_predicate, ParseResult, Span};
use crate::types::StructureDef;
/// Parses a domain structure definition.
///
/// ## Example
///
/// ```
/// # use pddl::parsers::{parse_structure_def, preamble::*};
/// # use pddl::{ActionDefinition, ActionSymbol, AtomicFormula, ConditionalEffect, Effects, GoalDefinition, Literal, PrimitiveEffect, Predicate, Preference, PreferenceGoalDefinition, PreconditionGoalDefinitions, StructureDef, Term, Variable};
/// # use pddl::{Name, ToTyped, TypedList};
/// let input = r#"(:action take-out
/// :parameters (?x - physob)
/// :precondition (not (= ?x B))
/// :effect (not (in ?x))
/// )"#;
///
/// let action = parse_structure_def(input);
///
/// assert!(action.is_value(
/// StructureDef::action(ActionDefinition::new(
/// ActionSymbol::from("take-out"),
/// TypedList::from_iter([
/// Variable::from("x").to_typed("physob")
/// ]),
/// PreconditionGoalDefinitions::preference(PreferenceGoalDefinition::from_gd(
/// GoalDefinition::not(
/// GoalDefinition::atomic_formula(
/// AtomicFormula::equality(
/// Term::Variable(Variable::from("x")),
/// Term::Name(Name::new("B"))
/// )
/// )
/// )
/// )),
/// Some(Effects::new(ConditionalEffect::new_primitive_effect(
/// PrimitiveEffect::NotAtomicFormula(
/// AtomicFormula::predicate(
/// Predicate::from("in"),
/// vec![Term::Variable(Variable::from("x"))]
/// )
/// )
/// )))
/// )
/// )));
/// ```
pub fn parse_structure_def<'a, T: Into<Span<'a>>>(input: T) -> ParseResult<'a, StructureDef> {
let action = map(parse_action_def, StructureDef::new_action);
// :durative-actions
let durative = map(parse_da_def, StructureDef::new_durative_action);
// :derived-predicates
let derived = map(parse_derived_predicate, StructureDef::new_derived);
alt((derived, action, durative)).parse(input.into())
}
impl crate::parsers::Parser for StructureDef {
type Item = StructureDef;
/// See [`parse_structure_def`].
fn parse<'a, S: Into<Span<'a>>>(input: S) -> ParseResult<'a, Self::Item> {
parse_structure_def(input)
}
}
#[cfg(test)]
mod tests {
use crate::parsers::preamble::*;
use crate::{
ActionDefinition, ActionSymbol, AtomicFormula, ConditionalEffect, Effects, GoalDefinition,
Name, PreconditionGoalDefinitions, Predicate, PreferenceGoalDefinition, PrimitiveEffect,
StructureDef, Term, ToTyped, TypedList, Variable,
};
#[test]
fn test_parse() {
let input = r#"(:action take-out
:parameters (?x - physob)
:precondition (not (= ?x B))
:effect (not (in ?x))
)"#;
let action = StructureDef::parse(input);
assert!(action.is_value(StructureDef::action(ActionDefinition::new(
ActionSymbol::from("take-out"),
TypedList::from_iter([Variable::from("x").to_typed("physob")]),
PreconditionGoalDefinitions::preference(PreferenceGoalDefinition::from_gd(
GoalDefinition::not(GoalDefinition::atomic_formula(AtomicFormula::equality(
Term::Variable(Variable::from("x")),
Term::Name(Name::new("B"))
)))
)),
Some(Effects::new(ConditionalEffect::new_primitive_effect(
PrimitiveEffect::NotAtomicFormula(AtomicFormula::predicate(
Predicate::from("in"),
vec![Term::Variable(Variable::from("x"))]
))
)))
))));
}
}