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}