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
//! Provides parsers for timed effects.
use crate::parsers::{parens, prefix_expr};
use crate::parsers::{
parse_assign_op_t, parse_cond_effect, parse_f_assign_da, parse_f_exp_t, parse_f_head,
parse_time_specifier,
};
use crate::types::TimedEffect;
use nom::branch::alt;
use nom::character::complete::multispace1;
use nom::combinator::map;
use nom::sequence::{preceded, tuple};
use nom::IResult;
/// Parser that parses timed effects.
///
/// ## Example
/// ```
/// # use pddl::parsers::parse_timed_effect;
/// # use pddl::types::{AssignOp, AssignOpT, AtomicFormula, CEffect, ConditionalEffect, EqualityAtomicFormula, FAssignDa, FExpDa, FExpT, FHead, PEffect, Term, TimedEffect, TimeSpecifier};
/// # use pddl::types::FExpDa::FExp;
/// assert_eq!(parse_timed_effect("(at start (= x y))"), Ok(("",
/// TimedEffect::new_conditional(
/// TimeSpecifier::Start,
/// ConditionalEffect::new(
/// PEffect::AtomicFormula(AtomicFormula::Equality(
/// EqualityAtomicFormula::new(
/// Term::Name("x".into()),
/// Term::Name("y".into()))
/// )
/// )
/// )
/// )
/// )));
///
/// assert_eq!(parse_timed_effect("(at end (assign fun-sym ?duration))"), Ok(("",
/// TimedEffect::new_fluent(
/// TimeSpecifier::End,
/// FAssignDa::new(
/// AssignOp::Assign,
/// FHead::Simple("fun-sym".into()),
/// FExpDa::Duration
/// )
/// )
/// )));
///
/// assert_eq!(parse_timed_effect("(increase fun-sym #t)"), Ok(("",
/// TimedEffect::new_continuous(
/// AssignOpT::Increase,
/// FHead::Simple("fun-sym".into()),
/// FExpT::Now
/// )
/// )));
/// ```
pub fn parse_timed_effect(input: &str) -> IResult<&str, TimedEffect> {
let cond = map(
prefix_expr(
"at",
tuple((
parse_time_specifier,
preceded(multispace1, parse_cond_effect),
)),
),
TimedEffect::from,
);
// :numeric-fluents
let fluent = map(
prefix_expr(
"at",
tuple((
parse_time_specifier,
preceded(multispace1, parse_f_assign_da),
)),
),
TimedEffect::from,
);
// :continuous-effects + :numeric-fluents
let continuous = map(
parens(tuple((
parse_assign_op_t,
preceded(multispace1, parse_f_head),
preceded(multispace1, parse_f_exp_t),
))),
TimedEffect::from,
);
alt((fluent, cond, continuous))(input)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let input = "(at end (increase (distance-travelled) 5))";
let (_, _effect) = parse_timed_effect(input).unwrap();
}
}