1use nom::combinator::opt;
2use nom::multi::{many0, many1};
3use nom::sequence::{delimited, pair, preceded, tuple};
4use nom::IResult;
5use serde::{Deserialize, Serialize};
6
7use crate::domain::expression::Expression;
8use crate::domain::typing::Type;
9use crate::error::ParserError;
10use crate::lexer::{Token, TokenStream};
11use crate::tokens::id;
12
13#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
15pub struct Object {
16 pub name: String,
18 #[serde(rename = "type")]
20 pub type_: Type,
21}
22
23impl Object {
24 pub fn to_pddl(&self) -> String {
26 format!("{} - {}", self.name, self.type_.to_pddl())
27 }
28}
29
30#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
34pub struct Problem {
35 pub name: String,
37 pub domain: String,
39 #[serde(default)]
41 pub objects: Vec<Object>,
42 #[serde(default)]
44 pub init: Vec<Expression>,
45 pub goal: Expression,
47}
48
49impl Problem {
50 pub fn parse(input: TokenStream) -> Result<Self, ParserError> {
52 let (output, problem) = delimited(
53 Token::OpenParen,
54 preceded(Token::Define, Problem::parse_problem),
55 Token::CloseParen,
56 )(input)?;
57 if !output.is_empty() {
58 return Err(ParserError::ExpectedEndOfInput);
59 }
60 Ok(problem)
61 }
62
63 fn parse_problem(input: TokenStream) -> IResult<TokenStream, Problem, ParserError> {
64 let (output, (name, domain, objects, init, goal)) = tuple((
65 Problem::parse_name,
66 Problem::parse_domain,
67 Problem::parse_objects,
68 Problem::parse_init,
69 Problem::parse_goal,
70 ))(input)?;
71 Ok((
72 output,
73 Problem {
74 name,
75 domain,
76 objects,
77 init,
78 goal,
79 },
80 ))
81 }
82
83 fn parse_name(input: TokenStream) -> IResult<TokenStream, String, ParserError> {
84 let (output, name) = delimited(Token::OpenParen, preceded(Token::Problem, id), Token::CloseParen)(input)?;
85 Ok((output, name))
86 }
87
88 fn parse_domain(input: TokenStream) -> IResult<TokenStream, String, ParserError> {
89 let (output, domain) =
90 delimited(Token::OpenParen, preceded(Token::ProblemDomain, id), Token::CloseParen)(input)?;
91 Ok((output, domain))
92 }
93
94 fn parse_objects(input: TokenStream) -> IResult<TokenStream, Vec<Object>, ParserError> {
95 let (output, objects) = delimited(
96 Token::OpenParen,
97 preceded(
98 Token::Objects,
99 many0(pair(many1(id), opt(preceded(Token::Dash, Type::parse_type)))),
100 ),
101 Token::CloseParen,
102 )(input)?;
103 let objects = objects
104 .into_iter()
105 .flat_map(move |(names, type_)| {
106 names
107 .into_iter()
108 .map(|name| Object {
109 name,
110 type_: type_.clone().unwrap_or_default(),
111 })
112 .collect::<Vec<_>>()
113 })
114 .collect();
115 Ok((output, objects))
116 }
117
118 fn parse_init(input: TokenStream) -> IResult<TokenStream, Vec<Expression>, ParserError> {
119 log::debug!("BEGIN > parse_init {:?}", input.span());
120 let (output, init) = delimited(
121 Token::OpenParen,
122 preceded(Token::Init, many0(Expression::parse_expression)),
123 Token::CloseParen,
124 )(input)?;
125 log::debug!("END < parse_init {:?}", output.span());
126 Ok((output, init))
127 }
128
129 fn parse_goal(input: TokenStream) -> IResult<TokenStream, Expression, ParserError> {
130 let (output, goal) = delimited(
131 Token::OpenParen,
132 preceded(Token::Goal, Expression::parse_expression),
133 Token::CloseParen,
134 )(input)?;
135 Ok((output, goal))
136 }
137
138 pub fn to_pddl(&self) -> String {
140 let mut pddl = String::new();
141
142 pddl.push_str(&format!("(define (problem {})\n", self.name));
144 pddl.push_str(&format!("(:domain {})\n", self.domain));
145
146 pddl.push_str(&format!(
148 "(:objects\n{}\n)\n",
149 self.objects.iter().map(Object::to_pddl).collect::<Vec<_>>().join("\n")
150 ));
151
152 pddl.push_str(&format!(
154 "(:init\n{}\n)\n",
155 self.init.iter().map(Expression::to_pddl).collect::<Vec<_>>().join("\n")
156 ));
157
158 pddl.push_str(&format!("(:goal\n{}\n)\n", &self.goal.to_pddl()));
160
161 pddl.push(')');
163
164 pddl
165 }
166}