pddl_parser/domain/
simple_action.rs

1use nom::combinator::{map, opt};
2use nom::sequence::{delimited, preceded, tuple};
3use nom::IResult;
4use serde::{Deserialize, Serialize};
5
6use super::expression::Expression;
7use super::typed_parameter::TypedParameter;
8use crate::error::ParserError;
9use crate::lexer::{Token, TokenStream};
10use crate::tokens::id;
11
12/// An action with typed parameters.
13#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
14pub struct SimpleAction {
15    /// The name of the action.
16    pub name: String,
17    /// The parameters of the action.
18    #[serde(default)]
19    pub parameters: Vec<TypedParameter>,
20    /// The precondition of the action.
21    pub precondition: Option<Expression>,
22    /// The effect of the action.
23    pub effect: Expression,
24}
25
26impl SimpleAction {
27    /// Parse a list of actions from a token stream.
28    pub fn parse(input: TokenStream) -> IResult<TokenStream, SimpleAction, ParserError> {
29        log::debug!("BEGIN > parse_action {:?}", input.span());
30        log::debug!("Parsing action: {:?}", input.peek_n(10));
31        let (output, action) = map(
32            delimited(
33                Token::OpenParen,
34                preceded(
35                    Token::Action,
36                    tuple((
37                        id,
38                        preceded(
39                            Token::Parameters,
40                            delimited(
41                                Token::OpenParen,
42                                TypedParameter::parse_typed_parameters,
43                                Token::CloseParen,
44                            ),
45                        ),
46                        opt(preceded(Token::Precondition, Expression::parse_expression)),
47                        preceded(Token::Effect, Expression::parse_expression),
48                    )),
49                ),
50                Token::CloseParen,
51            ),
52            |(name, parameters, precondition, effect)| SimpleAction {
53                name,
54                parameters,
55                precondition,
56                effect,
57            },
58        )(input)?;
59        log::debug!("END < parse_action {:?}", output.span());
60        Ok((output, action))
61    }
62
63    /// Convert the action to PDDL.
64    pub fn to_pddl(&self) -> String {
65        let mut pddl = String::new();
66
67        // Action name
68        pddl.push_str(&format!("(:action {}\n", self.name));
69
70        // Parameters
71        pddl.push_str(&format!(
72            ":parameters ({})\n",
73            self.parameters
74                .iter()
75                .map(TypedParameter::to_pddl)
76                .collect::<Vec<_>>()
77                .join(" ")
78        ));
79
80        // Precondition
81        if let Some(precondition) = &self.precondition {
82            pddl.push_str(&format!(":precondition {}\n", precondition.to_pddl()));
83        }
84
85        // Effect
86        pddl.push_str(&format!(":effect \n{}\n", self.effect.to_pddl()));
87
88        pddl.push(')');
89        pddl
90    }
91}