use nom::combinator::{map, opt};
use nom::sequence::{delimited, preceded, tuple};
use nom::IResult;
use serde::{Deserialize, Serialize};
use super::expression::Expression;
use super::typed_parameter::TypedParameter;
use crate::error::ParserError;
use crate::lexer::{Token, TokenStream};
use crate::tokens::id;
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DurativeAction {
pub name: String,
#[serde(default)]
pub parameters: Vec<TypedParameter>,
pub duration: Expression,
pub condition: Option<Expression>,
pub effect: Expression,
}
impl DurativeAction {
pub fn parse(input: TokenStream) -> IResult<TokenStream, DurativeAction, ParserError> {
log::debug!("BEGIN > parse_durative_action {:?}", input.span());
log::debug!("Parsing action: {:?}", input.peek_n(10));
let (output, action) = map(
delimited(
Token::OpenParen,
preceded(
Token::DurativeAction,
tuple((
id,
preceded(
Token::Parameters,
delimited(
Token::OpenParen,
TypedParameter::parse_typed_parameters,
Token::CloseParen,
),
),
preceded(Token::Duration, Expression::parse_expression),
opt(preceded(Token::Condition, Expression::parse_expression)),
preceded(Token::Effect, Expression::parse_expression),
)),
),
Token::CloseParen,
),
|(name, parameters, duration, condition, effect)| DurativeAction {
name,
parameters,
duration,
condition,
effect,
},
)(input)?;
log::debug!("END < parse_action {:?}", output.span());
Ok((output, action))
}
pub fn to_pddl(&self) -> String {
let mut pddl = String::new();
pddl.push_str(&format!("(:durative-action {}\n", self.name));
pddl.push_str(&format!(
":parameters ({})\n",
self.parameters
.iter()
.map(TypedParameter::to_pddl)
.collect::<Vec<_>>()
.join(" ")
));
pddl.push_str(&format!(":duration {}\n", self.duration.to_pddl()));
if let Some(condition) = &self.condition {
pddl.push_str(&format!(":condition {}\n", condition.to_pddl()));
}
pddl.push_str(&format!(":effect \n{}\n", self.effect.to_pddl()));
pddl.push(')');
pddl
}
}