ptnet_core/
sim.rs

1/*!
2This module provides the basic behavioral traits for a net.
3
4The traits in this module are used to develop a simulation of a net, also known as a *token game*.
5The [`Simulation`] trait describes the component that executes the net [`Step`] by step.
6*/
7
8use crate::error::Error;
9use crate::net::{Arc, Net, Place, Transition};
10use crate::NodeId;
11use std::ops::{Add, Sub};
12use std::{fmt::Debug, fmt::Display, hash::Hash, rc::Rc};
13
14// ------------------------------------------------------------------------------------------------
15// Public Types  Marking
16// ------------------------------------------------------------------------------------------------
17
18///
19/// Note that this trait requires an implementation of `Display` which by convention will return an
20/// empty string if `is_empty` is `true`. To return a representation of the empty value use
21/// alternate marker in the format, `"{#}"` instead of `"{}"`.
22///
23/// For example, an elementary net allows only boolean tokens and will write `"●"` for a present
24/// token and `"○"` for the alternate representation for an empty token.
25///
26pub trait Tokens:
27    AsRef<Self::Value> + Clone + Debug + Default + Display + PartialEq + Eq + PartialOrd + Ord + Hash
28{
29    type Value: Default + Display + PartialEq + Eq + PartialOrd + Ord + Hash;
30
31    fn value(&self) -> &Self::Value;
32    fn set_value(&mut self, value: Self::Value);
33    fn empty(&mut self) {
34        self.set_value(Self::Value::default());
35    }
36    fn is_empty(&self) -> bool {
37        self.value() == &Self::Value::default()
38    }
39}
40
41///
42///
43///
44pub trait Marking: Clone + Debug {
45    type Value: Default + Display + PartialEq + Eq + PartialOrd + Ord + Hash;
46    type Tokens: Tokens<Value = Self::Value>;
47
48    fn step(&self) -> Step;
49    fn marked(&self) -> Vec<&NodeId>;
50    fn marking(&self, id: &NodeId) -> &Self::Tokens;
51    fn mark(&mut self, id: NodeId, marking: Self::Tokens);
52    fn mark_as(&mut self, id: NodeId, marking: Self::Value);
53    fn reset(&mut self, id: NodeId) {
54        self.mark(id, Self::Tokens::default());
55    }
56}
57
58// ------------------------------------------------------------------------------------------------
59// Public Types  Simulation
60// ------------------------------------------------------------------------------------------------
61
62///
63/// The type that represents steps in the simulation. Note that it is not possible to perform
64/// operations directly on a step, you can add and subtract durations.
65///
66#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
67pub struct Step(u64);
68
69///
70/// The type that represents a duration, or number of steps in the simulation.
71///
72#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
73pub struct Duration(u64);
74
75///
76/// A constant used to denote an instantaneous event.
77///
78pub const IMMEDIATE: Duration = Duration::ZERO;
79
80///
81///
82///
83pub trait Simulation: Debug {
84    type Place: Place;
85    type Transition: Transition;
86    type Arc: Arc;
87    type Net: Net<Place = Self::Place, Transition = Self::Transition, Arc = Self::Arc>;
88    type Tokens: Tokens;
89    type Marking: Marking<Tokens = Self::Tokens>;
90
91    ///
92    /// Return a reference to the net that is being executed.
93    ///
94    fn net(&self) -> Rc<Self::Net>;
95
96    ///
97    /// Return a reference to the current marking of the net. If the simulation has not been
98    /// advanced by calling `step` or `steps` this is the initial marking.
99    ///
100    fn current_marking(&self) -> &Self::Marking;
101
102    ///
103    /// Return the current step in the simulation. If the simulation has not been advanced by
104    /// calling `step` or `steps` this is `Step::ZERO`.
105    ///
106    fn current_step(&self) -> Step;
107
108    ///
109    /// Advance the simulation by one step returning the marking after the step has been taken.
110    ///
111    fn step(&mut self) -> Result<(), Error>;
112
113    ///
114    /// Advance the simulation by `steps` returning the marking after all steps were taken.
115    ///
116    fn steps(&mut self, steps: Duration) -> Result<(), Error>;
117
118    ///
119    /// Return a list of node identifiers corresponding to all the enabled transitions at this
120    /// step.
121    ///
122    fn enabled(&self) -> Vec<NodeId>;
123
124    ///
125    /// Return `true` if `transition` is enabled at this step, else `false`.
126    ///
127    fn is_enabled(&self, transition: &Self::Transition) -> bool;
128
129    ///
130    /// Not all nets can determine termination, if it is possible to determine termination return
131    /// `Some(...)`, else `None`.
132    ///
133    fn is_complete(&self) -> Option<bool> {
134        None
135    }
136}
137
138// ------------------------------------------------------------------------------------------------
139// Implementations
140// ------------------------------------------------------------------------------------------------
141
142impl Display for Step {
143    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
144        write!(f, "{}", self.0)
145    }
146}
147
148impl AsRef<u64> for Step {
149    fn as_ref(&self) -> &u64 {
150        &self.0
151    }
152}
153
154impl From<Step> for u64 {
155    fn from(value: Step) -> u64 {
156        value.0
157    }
158}
159
160impl Add<Duration> for Step {
161    type Output = Self;
162
163    fn add(self, rhs: Duration) -> Self::Output {
164        Self(self.0 + rhs.0)
165    }
166}
167
168impl Sub<Duration> for Step {
169    type Output = Self;
170
171    fn sub(self, rhs: Duration) -> Self::Output {
172        Self(self.0 - rhs.0)
173    }
174}
175
176impl Step {
177    ///
178    /// The constant value `Step′0`.
179    ///
180    pub const ZERO: Self = Self(0);
181
182    ///
183    /// The constant value `Step′1`
184    ///
185    pub const ONE: Self = Self(1);
186
187    ///
188    /// Return the value of this step plus `Step′1`
189    ///
190    pub const fn next(&self) -> Self {
191        Self(self.0 + 1)
192    }
193}
194
195// ------------------------------------------------------------------------------------------------
196
197impl Display for Duration {
198    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
199        write!(f, "{}", self.0)
200    }
201}
202
203impl AsRef<u64> for Duration {
204    fn as_ref(&self) -> &u64 {
205        &self.0
206    }
207}
208
209impl From<Duration> for u64 {
210    fn from(value: Duration) -> u64 {
211        value.0
212    }
213}
214
215impl Add for Duration {
216    type Output = Self;
217
218    fn add(self, rhs: Self) -> Self::Output {
219        Self(self.0 + rhs.0)
220    }
221}
222
223impl Sub for Duration {
224    type Output = Self;
225
226    fn sub(self, rhs: Self) -> Self::Output {
227        Self(self.0 - rhs.0)
228    }
229}
230
231impl Duration {
232    ///
233    /// The constant value `Duration′0`.
234    ///
235    pub const ZERO: Self = Self(0);
236
237    ///
238    /// The constant value `Duration′1`.
239    ///
240    pub const ONE: Self = Self(1);
241}