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}