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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
//! Contains the [`Domain`] type.
use crate::types::{
ConGD, Constants, DomainConstraintsDef, Functions, PredicateDefinitions, Requirements,
StructureDefs, Timeless,
};
use crate::types::{Name, Types};
/// The `Domain` type specifies a problem domain in which to plan.
///
/// ## Usage
/// This is the top-level type of a domain description. See also [`Problem`](crate::Problem).
///
/// ## Example
/// ```
/// # use pddl::{Domain, Name, Parser};
/// let input = r#"(define (domain briefcase-world)
/// (:requirements :strips :equality :typing :conditional-effects)
/// (:types location physob)
/// (:constants
/// B ; the briefcase
/// P ; the paycheck
/// D
/// - physob)
/// (:predicates (at ?x - physob ?y - location) ; an item is at a location
/// (in ?x ?y - physob)) ; an item is in another item
/// (:constraints (and))
///
/// ; Move briefcase from one location to another.
/// (:action mov-B
/// :parameters (?m ?l - location)
/// :precondition (and (at B ?m) (not (= ?m ?l)))
/// :effect (and (at B ?l) (not (at B ?m))
/// (forall (?z)
/// (when (and (in ?z) (not (= ?z B)))
/// (and (at ?z ?l) (not (at ?z ?m)))))) )
///
/// ; Put the item in the briefcase.
/// (:action put-in
/// :parameters (?x - physob ?l - location)
/// :precondition (not (= ?x B)) ; the item must not be the briefcase itself
/// :effect (when (and (at ?x ?l) (at B ?l))
/// (in ?x)) )
///
/// ; Take the item out of the briefcase.
/// (:action take-out
/// :parameters (?x - physob)
/// :precondition (not (= ?x B)) ; the item must be the briefcase itself
/// :effect (not (in ?x)) )
/// )"#;
///
/// let domain = Domain::from_str(input).unwrap();
///
/// assert_eq!(domain.name(), "briefcase-world");
/// assert_eq!(domain.requirements().len(), 4);
/// assert_eq!(domain.types().len(), 2);
/// assert_eq!(domain.constants().len(), 3);
/// assert_eq!(domain.predicates().len(), 2);
/// assert!(domain.constraints().is_empty());
/// assert_eq!(domain.structure().len(), 3);
/// ```
#[derive(Debug, Clone, PartialEq)]
pub struct Domain {
/// The domain name.
name: Name,
/// The domain extension list.
// TODO: PDDL 1.2 - deprecated?
extends: Vec<Name>,
/// The specified requirements.
requirements: Requirements,
/// The optional type declarations.
///
/// ## Requirements
/// Requires [Typing](crate::Requirement::Typing).
types: Types,
/// The optional constant declarations.
constants: Constants,
/// The predicate definitions.
predicates: PredicateDefinitions,
/// The optional function definitions.
///
/// ## Requirements
/// Requires [Fluents](crate::Requirement::Fluents).
functions: Functions,
/// The optional constraint definitions.
///
/// ## Requirements
/// Requires [Constraints](crate::Requirement::Constraints).
constraints: DomainConstraintsDef,
/// The optional timeless predicate definitions.
// TODO: PDDL 1.2 - deprecated?
timeless: Timeless,
/// The structure definition, i.e. [action](crate::ActionDefinition),
/// [durative action](crate::DurativeActionDefinition), and/or
/// [derived predicate](crate::DerivedPredicate) definitions.
structure: StructureDefs,
}
impl Domain {
/// Creates a builder to easily construct [`Domain`] instances.
pub fn builder(name: Name, structure: StructureDefs) -> Self {
Self {
name,
extends: Vec::default(),
requirements: Requirements::default(),
types: Types::default(),
constants: Constants::default(),
predicates: PredicateDefinitions::default(),
functions: Functions::default(),
constraints: DomainConstraintsDef::default(),
timeless: Timeless::default(),
structure,
}
}
/// Adds a list of optional domain names this domain definition extends upon.
/// This is a PDDL 1.2 construct.
pub fn with_extends<N: IntoIterator<Item = Name>>(mut self, names: N) -> Self {
self.extends = names.into_iter().collect();
self
}
/// Adds a list of optional domain requirements.
pub fn with_requirements(mut self, requirements: Requirements) -> Self {
self.requirements = requirements;
self
}
/// Adds a list of optional type declarations.
pub fn with_types<T: Into<Types>>(mut self, types: T) -> Self {
self.types = types.into();
self
}
/// Adds a list of optional constant declarations.
pub fn with_constants<C: Into<Constants>>(mut self, constants: C) -> Self {
self.constants = constants.into();
self
}
/// Adds a list of optional predicate definitions.
pub fn with_predicates<P: Into<PredicateDefinitions>>(mut self, predicates: P) -> Self {
self.predicates = predicates.into();
self
}
/// Adds a list of optional function definitions.
pub fn with_functions<F: Into<Functions>>(mut self, functions: F) -> Self {
self.functions = functions.into();
self
}
/// Adds a list of optional constraints.
pub fn with_constraints(mut self, constraints: DomainConstraintsDef) -> Self {
self.constraints = constraints;
self
}
/// Adds a list of timeless predicates.
pub fn with_timeless(mut self, timeless: Timeless) -> Self {
self.timeless = timeless;
self
}
/// Gets the domain name.
pub const fn name(&self) -> &Name {
&self.name
}
/// Gets the names of the domains this definition extends.
/// This is a PDDL 1.2 construct.
pub fn extends(&self) -> &[Name] {
self.extends.as_slice()
}
/// Returns the optional domain requirements.
/// If no requirements were specified by the domain, [STRIPS](crate::Requirement::Strips) is implied.
pub const fn requirements(&self) -> &Requirements {
&self.requirements
}
/// Returns the optional type declarations.
/// ## Requirements
/// Requires [Typing](crate::Requirement::Typing).
pub const fn types(&self) -> &Types {
&self.types
}
/// Returns the optional constant definitions.
pub const fn constants(&self) -> &Constants {
&self.constants
}
/// Returns the optional predicate definitions.
pub const fn predicates(&self) -> &PredicateDefinitions {
&self.predicates
}
/// Returns the optional function definitions.
/// ## Requirements
/// Requires [Fluents](Requirement::Fluents).
pub const fn functions(&self) -> &Functions {
&self.functions
}
/// Returns the optional constraint declaration.
pub const fn constraints(&self) -> &ConGD {
self.constraints.value()
}
/// Returns the domain structure definitions.
pub const fn structure(&self) -> &StructureDefs {
&self.structure
}
}
impl AsRef<Requirements> for Domain {
fn as_ref(&self) -> &Requirements {
&self.requirements
}
}
impl AsRef<Types> for Domain {
fn as_ref(&self) -> &Types {
&self.types
}
}
impl AsRef<PredicateDefinitions> for Domain {
fn as_ref(&self) -> &PredicateDefinitions {
&self.predicates
}
}
impl AsRef<Functions> for Domain {
fn as_ref(&self) -> &Functions {
&self.functions
}
}
impl AsRef<StructureDefs> for Domain {
fn as_ref(&self) -> &StructureDefs {
&self.structure
}
}