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
//! Provides parsers for atomic formulae.
use crate::parsers::parse_predicate;
use crate::parsers::{parens, space_separated_list0, ws};
use crate::types::AtomicFormula;
use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::character::complete::{char, multispace1};
use nom::combinator::map;
use nom::sequence::{delimited, preceded, tuple};
use nom::IResult;
/// Parses an atomic formula, i.e. `(<predicate> t*) | (= t t)`.
///
/// ## Example
/// ```
/// # use nom::character::complete::alpha1;
/// # use pddl::parsers::atomic_formula;
/// # use pddl::parsers::parse_name;
/// # use pddl::{AtomicFormula, EqualityAtomicFormula, PredicateAtomicFormula, Predicate};
/// assert_eq!(atomic_formula(parse_name)("(= x y)"), Ok(("",
/// AtomicFormula::Equality(EqualityAtomicFormula::new("x".into(), "y".into()))
/// )));
/// assert_eq!(atomic_formula(parse_name)("(move a b)"), Ok(("",
/// AtomicFormula::Predicate(PredicateAtomicFormula::new(Predicate::from("move"), vec!["a".into(), "b".into()]))
/// )));
/// ```
pub fn atomic_formula<'a, F, O>(
inner: F,
) -> impl FnMut(&'a str) -> IResult<&'a str, AtomicFormula<O>>
where
F: Clone + FnMut(&'a str) -> IResult<&'a str, O>,
{
let equality = map(
delimited(
tag("(="),
preceded(
multispace1,
tuple((inner.clone(), preceded(multispace1, inner.clone()))),
),
char(')'),
),
|tuple| AtomicFormula::Equality(tuple.into()),
);
let predicate = map(
parens(tuple((parse_predicate, ws(space_separated_list0(inner))))),
|tuple| AtomicFormula::Predicate(tuple.into()),
);
alt((equality, predicate))
}
#[cfg(test)]
mod tests {
use super::*;
use crate::parsers::parse_term;
#[test]
fn it_works() {
let input = "(can-move ?from-waypoint ?to-waypoint)";
let (_, _effect) = atomic_formula(parse_term)(input).unwrap();
}
}