petri_net_simulation/
dynamic.rs

1use std::ops::{Deref, DerefMut};
2
3use event_simulation::{DynamicSimulation, Editable};
4use pns::{Pid, Tid};
5
6use crate::{EditNet, PetriNetInfo};
7
8/// Represents a dynamic net.
9pub type DynamicNet<E> = DynamicSimulation<PetriNetInfo, E>;
10
11macro_rules! dynamic {
12    ($type:ident, $value:ident, $net:pat, $e:expr) => {
13        match $value {
14            $type::Default($net) => $e,
15            $type::Simulated($net) => $e,
16        }
17    };
18}
19
20/// A type for editing a dynamic net safely.
21pub enum DynamicNetEdit<'a, Edit: Deref<Target = EditNet<'a>> + 'a> {
22    /// A editable reference to a default net.
23    Default(&'a mut PetriNetInfo),
24    /// A editable reference to a simulated net.
25    Simulated(Edit),
26}
27
28impl<'a, Edit: Deref<Target = EditNet<'a>> + 'a> Deref for DynamicNetEdit<'a, Edit> {
29    type Target = PetriNetInfo;
30    fn deref(&self) -> &PetriNetInfo {
31        dynamic!(Self, self, net, net)
32    }
33}
34
35impl<'a, Edit: DerefMut<Target = EditNet<'a>> + 'a> DynamicNetEdit<'a, Edit> {
36    /// Creates a new dynamic net edit for editing the simulated net safely.
37    pub fn new<E: Editable<Edit<'a> = Edit>>(net: &'a mut DynamicNet<E>) -> Self {
38        use DynamicSimulation::*;
39        match net {
40            Default(net) => Self::Default(net),
41            Simulated(net) => Self::Simulated(net.edit()),
42        }
43    }
44
45    /// Add a new place to the petri net and get the index and refresh states if necessary.
46    #[inline]
47    pub fn add_place(&mut self) -> Pid {
48        dynamic!(Self, self, net, net.add_place())
49    }
50
51    /// Add a new transition to the petri net and get the index and refresh states if necessary.
52    #[inline]
53    pub fn add_transition(&mut self) -> Tid {
54        dynamic!(Self, self, net, net.add_transition())
55    }
56
57    /// Add a new transition to the petri net, connct it to the specified places and get the index and refresh states if necessary.
58    #[inline]
59    pub fn add_connected_transition(&mut self, in_pids: &[Pid], out_pids: &[Pid]) -> Tid {
60        dynamic!(
61            Self,
62            self,
63            net,
64            net.add_connected_transition(in_pids, out_pids)
65        )
66    }
67
68    /// Remove a place at index `pid` from petri net and refresh states if necessary.
69    #[inline]
70    pub fn remove_place(&mut self, pid: Pid) {
71        dynamic!(Self, self, net, net.remove_place(pid));
72    }
73
74    /// Make a connection in to the transition with index `tid` from place with index `pid` and refresh states if necessary.
75    /// Result represents success.
76    #[inline]
77    pub fn connect_place_to_transition(&mut self, pid: Pid, tid: Tid) -> bool {
78        dynamic!(Self, self, net, net.connect_place_to_transition(pid, tid))
79    }
80
81    /// Make a connection out from the transition with index `tid` to place with index `pid` and refresh states if necessary.
82    /// Result represents success.
83    #[inline]
84    pub fn connect_transition_to_place(&mut self, tid: Tid, pid: Pid) -> bool {
85        dynamic!(Self, self, net, net.connect_transition_to_place(tid, pid))
86    }
87
88    /// Duplicate the transition and get the index of the clone and refresh states if necessary.
89    #[inline]
90    pub fn duplicate_transition(&mut self, tid: Tid) -> Tid {
91        dynamic!(Self, self, net, net.duplicate_transition(tid))
92    }
93
94    /// Duplicate the place and get the index of the clone and refresh states if necessary.
95    #[inline]
96    pub fn duplicate_place(&mut self, pid: Pid) -> Pid {
97        dynamic!(Self, self, net, net.duplicate_place(pid))
98    }
99
100    /// Increase the initial token count in place indexed by `pid` and refresh states if necessary.
101    #[inline]
102    pub fn add_initial_tokens(&mut self, pid: Pid, count: usize) -> usize {
103        dynamic!(Self, self, net, net.add_initial_tokens(pid, count))
104    }
105}