1use crate::petri_net::{PetriNet, PlaceRef, TransitionRef};
7
8macro_rules! place_label_from_index {
9 ($index:expr) => {
10 format!("P{}", $index)
11 };
12}
13
14macro_rules! transition_label_from_index {
15 ($index:expr) => {
16 format!("T{}", $index)
17 };
18}
19
20#[must_use]
24pub fn create_basic_unconnected_net(
25 number_of_places: usize,
26 number_of_transitions: usize,
27) -> (PetriNet, Vec<PlaceRef>, Vec<TransitionRef>) {
28 let mut net = PetriNet::new();
29 let mut place_refs: Vec<PlaceRef> = Vec::new();
30 let mut transition_refs: Vec<TransitionRef> = Vec::new();
31
32 for i in 1..=number_of_places {
33 let place_ref = net.add_place(&place_label_from_index!(i));
34 place_refs.push(place_ref);
35 }
36 for i in 1..=number_of_transitions {
37 let transition_ref = net.add_transition(&transition_label_from_index!(i));
38 transition_refs.push(transition_ref);
39 }
40
41 (net, place_refs, transition_refs)
42}
43
44#[must_use]
53pub fn create_net_chain_topology(length: usize) -> (PetriNet, Vec<PlaceRef>, Vec<TransitionRef>) {
54 if length == 0 {
55 return (PetriNet::new(), Vec::new(), Vec::new());
56 }
57 let (mut net, place_refs, transition_refs) = create_basic_unconnected_net(length, length - 1);
58
59 for i in 0..length - 1 {
60 let place_ref = &place_refs[i];
61 let transition_ref = &transition_refs[i];
62 net.add_arc_place_transition(place_ref, transition_ref)
63 .expect("Failed while creating a net with chain topology");
64 }
65
66 for i in 0..length - 1 {
67 let transition_ref = &transition_refs[i];
68 let place_ref = &place_refs[i + 1];
69 net.add_arc_transition_place(transition_ref, place_ref)
70 .expect("Failed while creating a net with chain topology");
71 }
72
73 (net, place_refs, transition_refs)
74}
75
76#[must_use]
83pub fn create_net_loop_topology() -> (PetriNet, PlaceRef, TransitionRef) {
84 let mut net = PetriNet::new();
85 let place_ref = net.add_place("P1");
86 let transition_ref = net.add_transition("T1");
87
88 net.add_arc_place_transition(&place_ref, &transition_ref)
89 .expect("Failed while trying to create a simple net with a loop topology");
90 net.add_arc_transition_place(&transition_ref, &place_ref)
91 .expect("Failed while trying to create a simple net with a loop topology");
92
93 (net, place_ref, transition_ref)
94}
95
96#[cfg(test)]
97mod net_creator_tests {
98 use super::*;
99
100 #[test]
101 fn create_basic_unconnected_net_has_correct_number_of_nodes() {
102 let (net, place_refs, transition_refs) = create_basic_unconnected_net(8, 14);
103
104 assert_eq!(net.get_cardinality_places(), 8);
105 assert_eq!(net.get_cardinality_transitions(), 14);
106 assert_eq!(place_refs.len(), 8);
107 assert_eq!(transition_refs.len(), 14)
108 }
109
110 #[test]
111 fn create_basic_unconnected_net_has_correct_number_of_nodes_from_0_to_10() {
112 for number_of_places in 0..=10 {
113 for number_of_transitions in 0..=10 {
114 let (net, place_refs, transition_refs) =
115 create_basic_unconnected_net(number_of_places, number_of_transitions);
116
117 assert_eq!(net.get_cardinality_places(), number_of_places);
118 assert_eq!(net.get_cardinality_transitions(), number_of_transitions);
119 assert_eq!(place_refs.len(), number_of_places);
120 assert_eq!(transition_refs.len(), number_of_transitions);
121 }
122 }
123 }
124
125 #[test]
126 fn create_basic_unconnected_net_has_no_arcs() {
127 let (net, place_refs, transition_refs) = create_basic_unconnected_net(8, 14);
128 let arcs_1 = net.find_arcs_place_transition();
129 let arcs_2 = net.find_arcs_transition_place();
130
131 assert!(arcs_1.is_empty());
132 assert!(arcs_2.is_empty());
133 assert_eq!(place_refs.len(), 8);
134 assert_eq!(transition_refs.len(), 14)
135 }
136
137 #[test]
138 fn create_basic_unconnected_net_has_valid_references() {
139 let (net, place_refs, transition_refs) = create_basic_unconnected_net(8, 14);
140
141 for place_ref in place_refs.iter() {
142 assert!(net.check_place_ref(place_ref));
143 }
144 for transition_ref in transition_refs.iter() {
145 assert!(net.check_transition_ref(transition_ref));
146 }
147 }
148
149 #[test]
150 fn create_basic_unconnected_net_has_no_arcs_from_0_to_10() {
151 for number_of_places in 0..=10 {
152 for number_of_transitions in 0..=10 {
153 let (net, _, _) =
154 create_basic_unconnected_net(number_of_places, number_of_transitions);
155 let arcs_1 = net.find_arcs_place_transition();
156 let arcs_2 = net.find_arcs_transition_place();
157
158 assert!(arcs_1.is_empty());
159 assert!(arcs_2.is_empty());
160 }
161 }
162 }
163
164 #[test]
165 fn create_net_chain_topology_has_correct_number_of_nodes() {
166 let (net, place_refs, transition_refs) = create_net_chain_topology(3);
167
168 assert_eq!(net.get_cardinality_places(), 3);
169 assert_eq!(net.get_cardinality_transitions(), 2);
170 assert_eq!(place_refs.len(), 3);
171 assert_eq!(transition_refs.len(), 2);
172 }
173
174 #[test]
175 fn create_net_chain_topology_has_valid_references() {
176 let (net, place_refs, transition_refs) = create_net_chain_topology(3);
177
178 for place_ref in place_refs.iter() {
179 assert!(net.check_place_ref(place_ref));
180 }
181 for transition_ref in transition_refs.iter() {
182 assert!(net.check_transition_ref(transition_ref));
183 }
184 }
185
186 #[test]
187 fn create_net_chain_topology_length_zero_returns_empty_net() {
188 let (net, place_refs, transition_refs) = create_net_chain_topology(0);
189
190 assert_eq!(net.get_cardinality_places(), 0);
191 assert_eq!(net.get_cardinality_transitions(), 0);
192 assert_eq!(place_refs.len(), 0);
193 assert_eq!(transition_refs.len(), 0);
194 }
195
196 #[test]
197 fn create_net_chain_topology_has_correct_number_of_nodes_from_1_to_10() {
198 for length in 1..=10 {
199 let (net, place_refs, transition_refs) = create_net_chain_topology(length);
200
201 assert_eq!(net.get_cardinality_places(), length);
202 assert_eq!(net.get_cardinality_transitions(), length - 1);
203 assert_eq!(place_refs.len(), length);
204 assert_eq!(transition_refs.len(), length - 1);
205 }
206 }
207
208 #[test]
209 fn create_net_chain_topology_has_correct_number_of_arcs() {
210 let (net, place_refs, transition_refs) = create_net_chain_topology(3);
211 let arcs_1 = net.find_arcs_place_transition();
212 let arcs_2 = net.find_arcs_transition_place();
213
214 assert_eq!(arcs_1.len(), 2);
215 assert_eq!(arcs_2.len(), 2);
216 assert_eq!(place_refs.len(), 3);
217 assert_eq!(transition_refs.len(), 2);
218 }
219
220 #[test]
221 fn create_net_chain_topology_has_correct_number_of_arcs_from_1_to_10() {
222 for length in 1..=10 {
223 let (net, _, _) = create_net_chain_topology(length);
224 let arcs_1 = net.find_arcs_place_transition();
225 let arcs_2 = net.find_arcs_transition_place();
226
227 assert_eq!(arcs_1.len(), length - 1);
228 assert_eq!(arcs_2.len(), length - 1);
229 }
230 }
231
232 #[test]
233 fn create_net_loop_topology_has_correct_number_of_places() {
234 let (net, place_ref, transition_ref) = create_net_loop_topology();
235
236 assert_eq!(net.get_cardinality_places(), 1);
237 assert_eq!(net.get_cardinality_transitions(), 1);
238 assert!(net.check_place_ref(&place_ref));
239 assert!(net.check_transition_ref(&transition_ref));
240 }
241
242 #[test]
243 fn create_net_loop_topology_has_valid_references() {
244 let (net, place_ref, transition_ref) = create_net_loop_topology();
245
246 assert!(net.check_place_ref(&place_ref));
247 assert!(net.check_transition_ref(&transition_ref));
248 }
249
250 #[test]
251 fn create_net_loop_topology_has_correct_number_of_arcs() {
252 let (net, _, _) = create_net_loop_topology();
253 let arcs_1 = net.find_arcs_place_transition();
254 let arcs_2 = net.find_arcs_transition_place();
255
256 assert_eq!(arcs_1.len(), 1);
257 assert_eq!(arcs_2.len(), 1);
258 }
259}