pddl/types/domain.rs
1//! Contains the [`Domain`] type.
2
3use crate::types::{
4 ConGD, Constants, DomainConstraintsDef, Functions, PredicateDefinitions, Requirements,
5 StructureDefs, Timeless,
6};
7use crate::types::{Name, Types};
8
9/// The `Domain` type specifies a problem domain in which to plan.
10///
11/// ## Usage
12/// This is the top-level type of a domain description. See also [`Problem`](crate::Problem).
13///
14/// ## Example
15/// ```
16/// # use pddl::{Domain, Name, Parser};
17/// let input = r#"(define (domain briefcase-world)
18/// (:requirements :strips :equality :typing :conditional-effects)
19/// (:types location physob)
20/// (:constants
21/// B ; the briefcase
22/// P ; the paycheck
23/// D
24/// - physob)
25/// (:predicates (at ?x - physob ?y - location) ; an item is at a location
26/// (in ?x ?y - physob)) ; an item is in another item
27/// (:constraints (and))
28///
29/// ; Move briefcase from one location to another.
30/// (:action mov-B
31/// :parameters (?m ?l - location)
32/// :precondition (and (at B ?m) (not (= ?m ?l)))
33/// :effect (and (at B ?l) (not (at B ?m))
34/// (forall (?z)
35/// (when (and (in ?z) (not (= ?z B)))
36/// (and (at ?z ?l) (not (at ?z ?m)))))) )
37///
38/// ; Put the item in the briefcase.
39/// (:action put-in
40/// :parameters (?x - physob ?l - location)
41/// :precondition (not (= ?x B)) ; the item must not be the briefcase itself
42/// :effect (when (and (at ?x ?l) (at B ?l))
43/// (in ?x)) )
44///
45/// ; Take the item out of the briefcase.
46/// (:action take-out
47/// :parameters (?x - physob)
48/// :precondition (not (= ?x B)) ; the item must be the briefcase itself
49/// :effect (not (in ?x)) )
50/// )"#;
51///
52/// let domain = Domain::from_str(input).unwrap();
53///
54/// assert_eq!(domain.name(), "briefcase-world");
55/// assert_eq!(domain.requirements().len(), 4);
56/// assert_eq!(domain.types().len(), 2);
57/// assert_eq!(domain.constants().len(), 3);
58/// assert_eq!(domain.predicates().len(), 2);
59/// assert!(domain.constraints().is_empty());
60/// assert_eq!(domain.structure().len(), 3);
61/// ```
62#[derive(Debug, Clone, PartialEq)]
63pub struct Domain {
64 /// The domain name.
65 name: Name,
66 /// The domain extension list.
67 // TODO: PDDL 1.2 - deprecated?
68 extends: Vec<Name>,
69 /// The specified requirements.
70 requirements: Requirements,
71 /// The optional type declarations.
72 ///
73 /// ## Requirements
74 /// Requires [Typing](crate::Requirement::Typing).
75 types: Types,
76 /// The optional constant declarations.
77 constants: Constants,
78 /// The predicate definitions.
79 predicates: PredicateDefinitions,
80 /// The optional function definitions.
81 ///
82 /// ## Requirements
83 /// Requires [Fluents](crate::Requirement::Fluents).
84 functions: Functions,
85 /// The optional constraint definitions.
86 ///
87 /// ## Requirements
88 /// Requires [Constraints](crate::Requirement::Constraints).
89 constraints: DomainConstraintsDef,
90 /// The optional timeless predicate definitions.
91 // TODO: PDDL 1.2 - deprecated?
92 timeless: Timeless,
93 /// The structure definition, i.e. [action](crate::ActionDefinition),
94 /// [durative action](crate::DurativeActionDefinition), and/or
95 /// [derived predicate](crate::DerivedPredicate) definitions.
96 structure: StructureDefs,
97}
98
99impl Domain {
100 /// Creates a builder to easily construct [`Domain`] instances.
101 pub fn builder(name: Name, structure: StructureDefs) -> Self {
102 Self {
103 name,
104 extends: Vec::default(),
105 requirements: Requirements::default(),
106 types: Types::default(),
107 constants: Constants::default(),
108 predicates: PredicateDefinitions::default(),
109 functions: Functions::default(),
110 constraints: DomainConstraintsDef::default(),
111 timeless: Timeless::default(),
112 structure,
113 }
114 }
115
116 /// Adds a list of optional domain names this domain definition extends upon.
117 /// This is a PDDL 1.2 construct.
118 pub fn with_extends<N: IntoIterator<Item = Name>>(mut self, names: N) -> Self {
119 self.extends = names.into_iter().collect();
120 self
121 }
122
123 /// Adds a list of optional domain requirements.
124 pub fn with_requirements(mut self, requirements: Requirements) -> Self {
125 self.requirements = requirements;
126 self
127 }
128
129 /// Adds a list of optional type declarations.
130 pub fn with_types<T: Into<Types>>(mut self, types: T) -> Self {
131 self.types = types.into();
132 self
133 }
134
135 /// Adds a list of optional constant declarations.
136 pub fn with_constants<C: Into<Constants>>(mut self, constants: C) -> Self {
137 self.constants = constants.into();
138 self
139 }
140
141 /// Adds a list of optional predicate definitions.
142 pub fn with_predicates<P: Into<PredicateDefinitions>>(mut self, predicates: P) -> Self {
143 self.predicates = predicates.into();
144 self
145 }
146
147 /// Adds a list of optional function definitions.
148 pub fn with_functions<F: Into<Functions>>(mut self, functions: F) -> Self {
149 self.functions = functions.into();
150 self
151 }
152
153 /// Adds a list of optional constraints.
154 pub fn with_constraints(mut self, constraints: DomainConstraintsDef) -> Self {
155 self.constraints = constraints;
156 self
157 }
158
159 /// Adds a list of timeless predicates.
160 pub fn with_timeless(mut self, timeless: Timeless) -> Self {
161 self.timeless = timeless;
162 self
163 }
164
165 /// Gets the domain name.
166 pub const fn name(&self) -> &Name {
167 &self.name
168 }
169
170 /// Gets the names of the domains this definition extends.
171 /// This is a PDDL 1.2 construct.
172 pub fn extends(&self) -> &[Name] {
173 self.extends.as_slice()
174 }
175
176 /// Returns the optional domain requirements.
177 /// If no requirements were specified by the domain, [STRIPS](crate::Requirement::Strips) is implied.
178 pub const fn requirements(&self) -> &Requirements {
179 &self.requirements
180 }
181
182 /// Returns the optional type declarations.
183 /// ## Requirements
184 /// Requires [Typing](crate::Requirement::Typing).
185 pub const fn types(&self) -> &Types {
186 &self.types
187 }
188
189 /// Returns the optional constant definitions.
190 pub const fn constants(&self) -> &Constants {
191 &self.constants
192 }
193
194 /// Returns the optional predicate definitions.
195 pub const fn predicates(&self) -> &PredicateDefinitions {
196 &self.predicates
197 }
198
199 /// Returns the optional function definitions.
200 /// ## Requirements
201 /// Requires [Fluents](Requirement::Fluents).
202 pub const fn functions(&self) -> &Functions {
203 &self.functions
204 }
205
206 /// Returns the optional constraint declaration.
207 pub const fn constraints(&self) -> &ConGD {
208 self.constraints.value()
209 }
210
211 /// Returns the domain structure definitions.
212 pub const fn structure(&self) -> &StructureDefs {
213 &self.structure
214 }
215}
216
217impl AsRef<Requirements> for Domain {
218 fn as_ref(&self) -> &Requirements {
219 &self.requirements
220 }
221}
222
223impl AsRef<Types> for Domain {
224 fn as_ref(&self) -> &Types {
225 &self.types
226 }
227}
228
229impl AsRef<PredicateDefinitions> for Domain {
230 fn as_ref(&self) -> &PredicateDefinitions {
231 &self.predicates
232 }
233}
234
235impl AsRef<Functions> for Domain {
236 fn as_ref(&self) -> &Functions {
237 &self.functions
238 }
239}
240
241impl AsRef<StructureDefs> for Domain {
242 fn as_ref(&self) -> &StructureDefs {
243 &self.structure
244 }
245}