ptnet_elementary/
lib.rs

1/*!
2This crate provides an implementation of the
3[`ptnet-core`](https://docs.rs/ptnet-core) traits for Elementary net (EN) systems.
4
5
6# Example
7
8```rust
9use ptnet_core::{
10    fmt::{print_net, NetMatrixFormatter},
11    net::Net,
12    sim::{Marking, Simulation},
13    trace::{MatrixTracer, TraceableSimulation},
14};
15use ptnet_elementary::{
16    Dot, ElementaryNet, ElementaryNetBuilder, ElementarySimulation, GraphvizNetFormatter,
17    SimpleArc, SimpleMarking, SimplePlace, SimpleTransition,
18};
19
20let mut net = ElementaryNet::default();
21let p0 = net.add_place();
22let p1 = net.add_place();
23let p2 = net.add_place();
24let t0 = net.add_transition();
25let t1 = net.add_transition();
26net.add_arc(p0, t0);
27net.add_arc(t0, p1);
28net.add_arc(p1, t1);
29net.add_arc(t1, p2);
30
31println!("-----");
32let mut f = NetMatrixFormatter::default();
33print_net(&net, &mut f).unwrap();
34println!("-----");
35let mut f = GraphvizNetFormatter::default();
36print_net(&net, &mut f).unwrap();
37println!("-----");
38
39let mut im = SimpleMarking::from(&net);
40im.mark(p0, Dot::from(true));
41
42let tracer: MatrixTracer<
43    SimplePlace,
44    SimpleTransition,
45    SimpleArc,
46    ElementaryNet,
47    Dot,
48    SimpleMarking,
49    ElementarySimulation,
50> = MatrixTracer::default();
51let mut sim = ElementarySimulation::new(net.into(), im.clone());
52sim.add_tracer(tracer.into());
53
54while !sim.is_complete().unwrap_or_default() {
55    sim.step().unwrap();
56}
57```
58
59# Features
60
61*/
62
63#![warn(
64    unknown_lints,
65    // ---------- Stylistic
66    absolute_paths_not_starting_with_crate,
67    elided_lifetimes_in_paths,
68    explicit_outlives_requirements,
69    macro_use_extern_crate,
70    nonstandard_style, /* group */
71    noop_method_call,
72    rust_2018_idioms,
73    single_use_lifetimes,
74    trivial_casts,
75    trivial_numeric_casts,
76    // ---------- Future
77    future_incompatible, /* group */
78    rust_2021_compatibility, /* group */
79    // ---------- Public
80    missing_debug_implementations,
81    // missing_docs,
82    unreachable_pub,
83    // ---------- Unsafe
84    unsafe_code,
85    unsafe_op_in_unsafe_fn,
86    // ---------- Unused
87    unused, /* group */
88)]
89#![deny(
90    // ---------- Public
91    exported_private_dependencies,
92    // ---------- Deprecated
93    anonymous_parameters,
94    bare_trait_objects,
95    ellipsis_inclusive_range_patterns,
96    // ---------- Unsafe
97    deref_nullptr,
98    drop_bounds,
99    dyn_drop,
100)]
101
102use ptnet_core::error::Error;
103use ptnet_core::fmt::{MarkedNetFormatter, NetFormatter};
104use ptnet_core::net::{Arc, Net, NetBuilder, Place, PlaceBuilder, Transition, TransitionBuilder};
105use ptnet_core::sim::{Duration, Marking, Simulation, Step, Tokens};
106use ptnet_core::trace::{SimulationTracer, TraceableSimulation};
107use ptnet_core::{HasIdentity, HasLabel, NodeId, NodeIdValue};
108use rand::seq::SliceRandom;
109use rand::thread_rng;
110use std::cell::RefCell;
111use std::collections::{HashMap, HashSet};
112use std::fmt::{Debug, Display};
113use std::rc::Rc;
114
115// ------------------------------------------------------------------------------------------------
116// Public Macros
117// ------------------------------------------------------------------------------------------------
118
119// ------------------------------------------------------------------------------------------------
120// Public Types  Net
121// ------------------------------------------------------------------------------------------------
122
123///
124/// A simple implementation of a net Place with no extensions.
125///
126#[derive(Debug)]
127pub struct SimplePlace {
128    id: NodeId,
129    label: Option<String>,
130}
131
132///
133/// A simple implementation of a net Transition with no extensions.
134///
135#[derive(Debug)]
136pub struct SimpleTransition {
137    id: NodeId,
138    label: Option<String>,
139}
140
141///
142/// A simple implementation of a net Arc with no extensions.
143///
144#[derive(Clone, Debug, PartialEq, Eq, Hash)]
145pub struct SimpleArc {
146    source: NodeId,
147    target: NodeId,
148}
149
150///
151/// A simple implementation of an Elementary net (EN) with no extensions.
152///
153#[derive(Debug, Default)]
154pub struct ElementaryNet {
155    next_id: NodeIdValue,
156    places: HashMap<NodeId, SimplePlace>,
157    transitions: HashMap<NodeId, SimpleTransition>,
158    arcs: HashSet<SimpleArc>,
159}
160
161#[derive(Debug, Default)]
162pub struct GraphvizNetFormatter;
163
164// ------------------------------------------------------------------------------------------------
165// Public Types  Markings
166// ------------------------------------------------------------------------------------------------
167
168#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
169pub struct Dot {
170    value: bool,
171}
172
173#[derive(Clone, Debug)]
174pub struct SimpleMarking {
175    step: Step,
176    markings: HashMap<NodeId, Dot>,
177}
178
179// ------------------------------------------------------------------------------------------------
180// Public Types  Simulation
181// ------------------------------------------------------------------------------------------------
182
183#[allow(clippy::type_complexity)]
184pub struct ElementarySimulation {
185    net: Rc<ElementaryNet>,
186    marking: SimpleMarking,
187    step: Step,
188    tracer: Option<
189        Rc<
190            dyn SimulationTracer<
191                Place = SimplePlace,
192                Transition = SimpleTransition,
193                Arc = SimpleArc,
194                Net = ElementaryNet,
195                Tokens = Dot,
196                Marking = SimpleMarking,
197                Simulation = ElementarySimulation,
198            >,
199        >,
200    >,
201}
202
203// ------------------------------------------------------------------------------------------------
204// Public Types  Builders
205// ------------------------------------------------------------------------------------------------
206
207#[derive(Debug, Default)]
208pub struct ElementaryNetBuilder {
209    inner: Rc<RefCell<BuilderInternal>>,
210}
211
212#[derive(Debug)]
213pub struct SimplePlaceBuilder {
214    inner: Rc<RefCell<BuilderInternal>>,
215    place: NodeId,
216}
217
218#[derive(Debug)]
219pub struct SimpleTransitionBuilder {
220    inner: Rc<RefCell<BuilderInternal>>,
221    transition: NodeId,
222}
223
224// ------------------------------------------------------------------------------------------------
225// Public Functions
226// ------------------------------------------------------------------------------------------------
227
228// ------------------------------------------------------------------------------------------------
229// Private Macros
230// ------------------------------------------------------------------------------------------------
231
232// ------------------------------------------------------------------------------------------------
233// Private Types
234// ------------------------------------------------------------------------------------------------
235
236#[derive(Debug, Default)]
237pub struct BuilderInternal {
238    net: ElementaryNet,
239    memory: HashMap<&'static str, NodeId>,
240}
241
242// ------------------------------------------------------------------------------------------------
243// Implementations  Net
244// ------------------------------------------------------------------------------------------------
245
246impl HasIdentity for SimplePlace {
247    fn new(id: NodeId) -> Self {
248        Self { id, label: None }
249    }
250
251    fn id(&self) -> NodeId {
252        self.id
253    }
254}
255
256impl HasLabel for SimplePlace {
257    fn label(&self) -> Option<&String> {
258        self.label.as_ref()
259    }
260
261    fn set_label<S>(&mut self, label: S)
262    where
263        S: Into<String>,
264    {
265        self.label = Some(label.into());
266    }
267
268    fn unset_label(&mut self) {
269        self.label = None;
270    }
271
272    fn with_label<S>(self, label: S) -> Self
273    where
274        S: Into<String>,
275        Self: Sized,
276    {
277        let mut self_mut = self;
278        self_mut.set_label(label);
279        self_mut
280    }
281}
282
283impl Place for SimplePlace {}
284
285impl SimplePlace {
286    fn new_with_label<S>(id: NodeId, label: S) -> Self
287    where
288        S: Into<String>,
289    {
290        Self::new(id).with_label(label)
291    }
292}
293
294// ------------------------------------------------------------------------------------------------
295
296impl HasIdentity for SimpleTransition {
297    fn new(id: NodeId) -> Self {
298        Self { id, label: None }
299    }
300
301    fn id(&self) -> NodeId {
302        self.id
303    }
304}
305
306impl HasLabel for SimpleTransition {
307    fn label(&self) -> Option<&String> {
308        self.label.as_ref()
309    }
310
311    fn set_label<S>(&mut self, label: S)
312    where
313        S: Into<String>,
314    {
315        self.label = Some(label.into());
316    }
317
318    fn unset_label(&mut self) {
319        self.label = None;
320    }
321
322    fn with_label<S>(self, label: S) -> Self
323    where
324        S: Into<String>,
325        Self: Sized,
326    {
327        let mut self_mut = self;
328        self_mut.set_label(label);
329        self_mut
330    }
331}
332
333impl Transition for SimpleTransition {}
334
335impl SimpleTransition {
336    fn new_with_label<S>(id: NodeId, label: S) -> Self
337    where
338        S: Into<String>,
339    {
340        Self::new(id).with_label(label)
341    }
342}
343
344// ------------------------------------------------------------------------------------------------
345
346impl Arc for SimpleArc {
347    fn source(&self) -> NodeId {
348        self.source
349    }
350
351    fn target(&self) -> NodeId {
352        self.target
353    }
354}
355
356impl SimpleArc {
357    fn new(source: NodeId, target: NodeId) -> Self {
358        Self { source, target }
359    }
360}
361
362// ------------------------------------------------------------------------------------------------
363
364impl Net for ElementaryNet {
365    type Place = SimplePlace;
366    type Transition = SimpleTransition;
367    type Arc = SimpleArc;
368
369    fn places(&self) -> Vec<&Self::Place> {
370        self.places.values().collect()
371    }
372
373    fn place(&self, id: &NodeId) -> Option<&Self::Place> {
374        self.places.get(id)
375    }
376
377    fn place_mut(&mut self, id: &NodeId) -> Option<&mut Self::Place> {
378        self.places.get_mut(id)
379    }
380
381    fn transitions(&self) -> Vec<&Self::Transition> {
382        self.transitions.values().collect()
383    }
384
385    fn transition(&self, id: &NodeId) -> Option<&Self::Transition> {
386        self.transitions.get(id)
387    }
388
389    fn transition_mut(&mut self, id: &NodeId) -> Option<&mut Self::Transition> {
390        self.transitions.get_mut(id)
391    }
392
393    fn arcs(&self) -> Vec<&Self::Arc> {
394        self.arcs.iter().collect()
395    }
396
397    fn inputs(&self, id: &NodeId) -> Vec<&NodeId> {
398        self.arcs
399            .iter()
400            .filter_map(|arc| {
401                if *id == arc.target {
402                    Some(&arc.source)
403                } else {
404                    None
405                }
406            })
407            .collect()
408    }
409
410    fn outputs(&self, id: &NodeId) -> Vec<&NodeId> {
411        self.arcs
412            .iter()
413            .filter_map(|arc| {
414                if *id == arc.source {
415                    Some(&arc.target)
416                } else {
417                    None
418                }
419            })
420            .collect()
421    }
422
423    fn add_place(&mut self) -> NodeId {
424        let id = self.next_id();
425        self.places.insert(id, SimplePlace::new(id));
426        id
427    }
428
429    fn add_labeled_place<S>(&mut self, label: S) -> NodeId
430    where
431        S: Into<String>,
432    {
433        let id = self.next_id();
434        self.places
435            .insert(id, SimplePlace::new_with_label(id, label.into()));
436        id
437    }
438
439    fn add_transition(&mut self) -> NodeId {
440        let id = self.next_id();
441        self.transitions.insert(id, SimpleTransition::new(id));
442        id
443    }
444
445    fn add_labeled_transition<S>(&mut self, label: S) -> NodeId
446    where
447        S: Into<String>,
448    {
449        let id = self.next_id();
450        self.transitions
451            .insert(id, SimpleTransition::new_with_label(id, label.into()));
452        id
453    }
454
455    fn add_arc(&mut self, source: NodeId, target: NodeId) {
456        if (self.place(&source).is_some() && self.transition(&target).is_some())
457            || (self.transition(&source).is_some() && self.place(&target).is_some())
458        {
459            self.arcs.insert(SimpleArc::new(source, target));
460        } else {
461            panic!("Nope");
462        }
463    }
464}
465
466impl ElementaryNet {
467    fn next_id(&mut self) -> NodeId {
468        let id = self.next_id;
469        self.next_id += 1;
470        NodeId::new_unchecked(id)
471    }
472}
473
474// ------------------------------------------------------------------------------------------------
475
476impl NetFormatter for GraphvizNetFormatter {
477    type Place = SimplePlace;
478    type Transition = SimpleTransition;
479    type Arc = SimpleArc;
480    type Net = ElementaryNet;
481
482    fn fmt_net<W: std::io::Write>(&self, w: &mut W, net: &Self::Net) -> Result<(), Error> {
483        self.fmt_internal(w, net, None, None)
484    }
485}
486
487impl MarkedNetFormatter for GraphvizNetFormatter {
488    type Place = SimplePlace;
489    type Transition = SimpleTransition;
490    type Arc = SimpleArc;
491    type Net = ElementaryNet;
492    type Tokens = Dot;
493    type Marking = SimpleMarking;
494
495    fn fmt_marked_net<W: std::io::Write>(
496        &self,
497        w: &mut W,
498        net: &Self::Net,
499        marking: &Self::Marking,
500        enabled: Option<&[NodeId]>,
501    ) -> Result<(), Error> {
502        self.fmt_internal(w, net, Some(marking), enabled)
503    }
504}
505
506impl GraphvizNetFormatter {
507    fn fmt_internal<W: std::io::Write>(
508        &self,
509        w: &mut W,
510        net: &ElementaryNet,
511        marking: Option<&SimpleMarking>,
512        enabled: Option<&[NodeId]>,
513    ) -> Result<(), Error> {
514        let separation = "0.75";
515        let rank_direction = "LR";
516        let places = net
517            .places
518            .values()
519            .map(|place| self.place_to_dot(place, marking))
520            .collect::<Vec<String>>()
521            .join("\n");
522        let transitions = net
523            .transitions
524            .values()
525            .map(|transition| self.transition_to_dot(transition, &enabled))
526            .collect::<Vec<String>>()
527            .join("\n");
528        let arcs = net
529            .arcs()
530            .iter()
531            .map(|arc| self.arc_to_dot(arc, net))
532            .collect::<Vec<String>>()
533            .join("\n");
534
535        writeln!(
536            w,
537            "strict digraph {{
538    id=\"net0\";
539    bgcolor=\"transparent\";
540    fontname=\"Helvetica Neue,Helvetica,Arial,sans-serif\";
541    nodesep={separation};
542    rankdir={rank_direction};
543    ranksep={separation};
544
545    // All place nodes.
546{places}
547
548    // All transition nodes.
549{transitions}
550
551    // All arcs.
552{arcs}
553}}"
554        )?;
555        Ok(())
556    }
557
558    fn place_to_dot(&self, place: &SimplePlace, marking: Option<&SimpleMarking>) -> String {
559        let id = format!("p{}", place.id());
560        let label = if let Some(label) = place.label() {
561            label
562        } else {
563            &id
564        };
565        let marking = if let Some(marking) = marking {
566            marking.marking(&place.id()).to_string()
567        } else {
568            String::new()
569        };
570        format!(
571            "    {id} [id=\"{id}\"; shape=\"circle\"; label=\"{marking}\"; xlabel=\"{label}\"];"
572        )
573    }
574
575    fn transition_to_dot(
576        &self,
577        transition: &SimpleTransition,
578        enabled: &Option<&[NodeId]>,
579    ) -> String {
580        let id = format!("t{}", transition.id());
581        let label = if let Some(label) = transition.label() {
582            label
583        } else {
584            &id
585        };
586        let (line_color, fill_color) = if let Some(enabled) = enabled {
587            if enabled.contains(&transition.id()) {
588                ("darkgreen", "lightgreen")
589            } else {
590                ("darkgrey", "lightgrey")
591            }
592        } else {
593            ("black", "darkgrey")
594        };
595        format!("    {id} [id=\"{id}\"; shape=\"rectangle\"; style=\"filled\"; color=\"{line_color}\"; fillcolor=\"{fill_color}\"; height=0.5; width=0.1; label=\"\"; xlabel=\"{label}\"];")
596    }
597
598    fn arc_to_dot(&self, arc: &SimpleArc, net: &ElementaryNet) -> String {
599        let source = self.display_id(&arc.source(), net);
600        let target = self.display_id(&arc.target(), net);
601        // inhibitor: "odot"
602        // reset: "normalnormal"
603        format!("    {source} -> {target} [id=\"{source}_{target}\"; arrowhead=\"normal\"; arrowsize=1.0];")
604    }
605
606    fn display_id(&self, id: &NodeId, net: &ElementaryNet) -> String {
607        match (
608            net.places.contains_key(id),
609            net.transitions.contains_key(id),
610        ) {
611            (true, false) => id.as_place_string(),
612            (false, true) => id.as_transition_string(),
613            _ => panic!(),
614        }
615    }
616}
617
618// ------------------------------------------------------------------------------------------------
619// Implementations  Markings
620// ------------------------------------------------------------------------------------------------
621
622impl Display for Dot {
623    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
624        write!(
625            f,
626            "{}",
627            if self.value {
628                "●"
629            } else if f.alternate() {
630                "○"
631            } else {
632                ""
633            }
634        )
635    }
636}
637
638impl From<bool> for Dot {
639    fn from(value: bool) -> Self {
640        Self { value }
641    }
642}
643
644impl AsRef<bool> for Dot {
645    fn as_ref(&self) -> &bool {
646        &self.value
647    }
648}
649
650impl Tokens for Dot {
651    type Value = bool;
652
653    fn value(&self) -> &Self::Value {
654        &self.value
655    }
656
657    fn set_value(&mut self, value: Self::Value) {
658        self.value = value;
659    }
660}
661
662// ------------------------------------------------------------------------------------------------
663
664impl From<&ElementaryNet> for SimpleMarking {
665    fn from(net: &ElementaryNet) -> Self {
666        Self {
667            step: Step::ZERO,
668            markings: net
669                .places()
670                .iter()
671                .map(|place| (place.id(), Default::default()))
672                .collect(),
673        }
674    }
675}
676
677impl Marking for SimpleMarking {
678    type Value = bool;
679    type Tokens = Dot;
680
681    fn step(&self) -> Step {
682        self.step
683    }
684
685    fn marked(&self) -> Vec<&NodeId> {
686        self.markings
687            .iter()
688            .filter_map(|(id, marking)| if !marking.is_empty() { Some(id) } else { None })
689            .collect()
690    }
691
692    fn marking(&self, id: &NodeId) -> &Self::Tokens {
693        self.markings.get(id).unwrap()
694    }
695
696    fn mark(&mut self, id: NodeId, marking: Self::Tokens) {
697        self.markings.insert(id, marking);
698    }
699
700    fn mark_as(&mut self, id: NodeId, marking: Self::Value) {
701        self.mark(id, Dot::from(marking));
702    }
703}
704
705impl SimpleMarking {
706    pub fn set_step(&mut self, step: Step) {
707        self.step = step;
708    }
709}
710
711// ------------------------------------------------------------------------------------------------
712// Implementations  Simulation
713// ------------------------------------------------------------------------------------------------
714
715impl Debug for ElementarySimulation {
716    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
717        f.debug_struct("ElementarySimulation")
718            .field("net", &self.net)
719            .field("marking", &self.marking)
720            .field("step", &self.step)
721            .field("tracer", &self.tracer.is_some())
722            .finish()
723    }
724}
725impl Simulation for ElementarySimulation {
726    type Place = SimplePlace;
727    type Transition = SimpleTransition;
728    type Arc = SimpleArc;
729    type Net = ElementaryNet;
730    type Tokens = Dot;
731    type Marking = SimpleMarking;
732
733    fn net(&self) -> Rc<Self::Net> {
734        self.net.clone()
735    }
736
737    fn current_marking(&self) -> &Self::Marking {
738        &self.marking
739    }
740
741    fn current_step(&self) -> Step {
742        self.step
743    }
744
745    fn step(&mut self) -> Result<(), Error> {
746        self.steps(Duration::ONE)
747    }
748
749    fn steps(&mut self, steps: Duration) -> Result<(), Error> {
750        if let (Some(tracer), Step::ZERO) = (&self.tracer, self.step) {
751            tracer.started(self);
752        }
753        for _ in 0..*steps.as_ref() {
754            // 1. Get a list of all enabled transitions
755            let mut enabled = self.enabled();
756
757            if enabled.is_empty() {
758                if let Some(tracer) = &self.tracer {
759                    tracer.ended(self);
760                }
761                break;
762            } else {
763                let this_step = self.step.next();
764                if let Some(tracer) = &self.tracer {
765                    tracer.step_started(this_step, self);
766                }
767                // 2. Shuffle the list, ensure the order of firing is non-deterministic.
768                enabled.shuffle(&mut thread_rng());
769
770                // 3. Fire all enabled transitions.
771                for transition in enabled {
772                    if let Some(tracer) = &self.tracer {
773                        tracer.transition_started(transition, self);
774                    }
775                    self.fire(transition)?;
776                    if let Some(tracer) = &self.tracer {
777                        tracer.transition_ended(transition, self);
778                    }
779                }
780
781                self.step = this_step;
782                self.marking.set_step(this_step);
783                if let Some(tracer) = &self.tracer {
784                    tracer.step_ended(this_step, self);
785                }
786            }
787        }
788
789        Ok(())
790    }
791
792    fn enabled(&self) -> Vec<NodeId> {
793        self.net
794            .transitions()
795            .iter()
796            .filter_map(|transition| {
797                if self.is_enabled(transition) {
798                    Some(transition.id())
799                } else {
800                    None
801                }
802            })
803            .collect()
804    }
805
806    fn is_enabled(&self, transition: &Self::Transition) -> bool {
807        let marked_places = self.marking.marked();
808        self.net
809            .inputs(&transition.id())
810            .iter()
811            .all(|input| marked_places.contains(input))
812    }
813
814    fn is_complete(&self) -> Option<bool> {
815        Some(
816            !self
817                .net
818                .transitions()
819                .iter()
820                .any(|transition| self.is_enabled(transition)),
821        )
822    }
823}
824
825impl TraceableSimulation for ElementarySimulation {
826    fn add_tracer<Tracer>(&mut self, tracer: Rc<Tracer>)
827    where
828        Tracer: SimulationTracer<
829                Place = SimplePlace,
830                Transition = Self::Transition,
831                Arc = Self::Arc,
832                Net = Self::Net,
833                Tokens = Self::Tokens,
834                Marking = Self::Marking,
835                Simulation = Self,
836            > + 'static,
837    {
838        self.tracer = Some(tracer);
839    }
840
841    fn remove_tracer(&mut self) {
842        self.tracer = None
843    }
844}
845
846impl ElementarySimulation {
847    pub fn new(net: Rc<ElementaryNet>, initial: SimpleMarking) -> Self {
848        Self {
849            net,
850            marking: initial,
851            step: Step::ZERO,
852            tracer: None,
853        }
854    }
855
856    fn fire(&mut self, transition: NodeId) -> Result<(), Error> {
857        // 1. Take tokens from inputs
858        for place_id in self.net.inputs(&transition) {
859            self.marking.reset(*place_id);
860        }
861        // 2. Give tokens to outputs
862        for place_id in self.net.outputs(&transition) {
863            self.marking.mark(*place_id, Dot::from(true));
864        }
865        Ok(())
866    }
867}
868
869// ------------------------------------------------------------------------------------------------
870// Implementations  Builders
871// ------------------------------------------------------------------------------------------------
872
873// ------------------------------------------------------------------------------------------------
874
875impl NetBuilder for ElementaryNetBuilder {
876    type Place = SimplePlace;
877    type Transition = SimpleTransition;
878    type Arc = SimpleArc;
879    type Net = ElementaryNet;
880    type PlaceBuilder = SimplePlaceBuilder;
881    type TransitionBuilder = SimpleTransitionBuilder;
882
883    fn place(&mut self) -> Self::PlaceBuilder {
884        add_place(&self.inner)
885    }
886
887    fn place_with_id(&mut self, id: &NodeId) -> Self::PlaceBuilder {
888        get_place_with_id(&self.inner, id)
889    }
890
891    fn recall_place(&mut self, tag: &'static str) -> Self::PlaceBuilder {
892        get_remembered_place(&self.inner, tag)
893    }
894
895    fn transition(&mut self) -> Self::TransitionBuilder {
896        add_transition(&self.inner)
897    }
898
899    fn transition_with_id(&mut self, id: &NodeId) -> Self::TransitionBuilder {
900        get_transition_with_id(&self.inner, id)
901    }
902
903    fn recall_transition(&mut self, tag: &'static str) -> Self::TransitionBuilder {
904        get_remembered_transition(&self.inner, tag)
905    }
906
907    fn arc(&mut self, source: NodeId, target: NodeId) -> &mut Self {
908        add_arc(&self.inner, source, target);
909        self
910    }
911
912    fn recall(&self, tag: &'static str) -> Option<NodeId> {
913        tag_to_id(&self.inner, tag)
914    }
915
916    fn build(self) -> Self::Net {
917        Rc::into_inner(self.inner).unwrap().into_inner().net
918    }
919}
920
921// ------------------------------------------------------------------------------------------------
922
923impl PlaceBuilder for SimplePlaceBuilder {
924    type TransitionBuilder = SimpleTransitionBuilder;
925
926    fn with_label<S>(self, label: S) -> Self
927    where
928        S: Into<String>,
929    {
930        {
931            let net = &mut self.inner.borrow_mut().net;
932            let place = net.place_mut(&self.place).unwrap();
933            place.set_label(label);
934        }
935        self
936    }
937
938    fn id(&self) -> NodeId {
939        self.place
940    }
941
942    fn remember_as(self, tag: &'static str) -> Self {
943        {
944            let memory = &mut self.inner.borrow_mut().memory;
945            memory.insert(tag, self.id());
946        }
947        self
948    }
949
950    fn to_transition(self) -> Self::TransitionBuilder {
951        let node = add_transition(&self.inner);
952        self.to_id(&node.id())
953    }
954
955    fn to_id(self, id: &NodeId) -> Self::TransitionBuilder {
956        let node = get_transition_with_id(&self.inner, id);
957        add_arc(&self.inner, self.id(), node.id());
958        node
959    }
960
961    fn to_remembered(self, tag: &'static str) -> Self::TransitionBuilder {
962        let id = tag_to_id(&self.inner, tag).unwrap();
963        self.to_id(&id)
964    }
965
966    fn from_transition(self) -> Self::TransitionBuilder {
967        let node = add_transition(&self.inner);
968        self.from_id(&node.id())
969    }
970
971    fn from_id(self, id: &NodeId) -> Self::TransitionBuilder {
972        let node = get_transition_with_id(&self.inner, id);
973        add_arc(&self.inner, node.id(), self.id());
974        node
975    }
976
977    fn from_remembered(self, tag: &'static str) -> Self::TransitionBuilder {
978        let id = tag_to_id(&self.inner, tag).unwrap();
979        self.from_id(&id)
980    }
981}
982
983// ------------------------------------------------------------------------------------------------
984
985impl TransitionBuilder for SimpleTransitionBuilder {
986    type PlaceBuilder = SimplePlaceBuilder;
987
988    fn with_label<S>(self, label: S) -> Self
989    where
990        S: Into<String>,
991    {
992        {
993            let net = &mut self.inner.borrow_mut().net;
994            let transition = net.transition_mut(&self.transition).unwrap();
995            transition.set_label(label);
996        }
997        self
998    }
999
1000    fn id(&self) -> NodeId {
1001        self.transition
1002    }
1003
1004    fn remember_as(self, tag: &'static str) -> Self {
1005        {
1006            let memory = &mut self.inner.borrow_mut().memory;
1007            memory.insert(tag, self.id());
1008        }
1009        self
1010    }
1011
1012    fn to_place(self) -> Self::PlaceBuilder {
1013        let node = add_place(&self.inner);
1014        self.to_id(&node.id())
1015    }
1016
1017    fn to_id(self, id: &NodeId) -> Self::PlaceBuilder {
1018        let node = get_place_with_id(&self.inner, id);
1019        add_arc(&self.inner, self.id(), node.id());
1020        node
1021    }
1022
1023    fn to_remembered(self, tag: &'static str) -> Self::PlaceBuilder {
1024        let id = tag_to_id(&self.inner, tag).unwrap();
1025        self.to_id(&id)
1026    }
1027
1028    fn from_place(self) -> Self::PlaceBuilder {
1029        let node = add_place(&self.inner);
1030        self.from_id(&node.id())
1031    }
1032
1033    fn from_id(self, id: &NodeId) -> Self::PlaceBuilder {
1034        let node = get_place_with_id(&self.inner, id);
1035        add_arc(&self.inner, node.id(), self.id());
1036        node
1037    }
1038
1039    fn from_remembered(self, tag: &'static str) -> Self::PlaceBuilder {
1040        let id = tag_to_id(&self.inner, tag).unwrap();
1041        self.from_id(&id)
1042    }
1043}
1044
1045// ------------------------------------------------------------------------------------------------
1046// Private Functions
1047// ------------------------------------------------------------------------------------------------
1048
1049#[inline(always)]
1050fn new_place(builder: &Rc<RefCell<BuilderInternal>>, id: NodeId) -> SimplePlaceBuilder {
1051    SimplePlaceBuilder {
1052        inner: builder.clone(),
1053        place: id,
1054    }
1055}
1056
1057#[inline(always)]
1058fn add_place(builder: &Rc<RefCell<BuilderInternal>>) -> SimplePlaceBuilder {
1059    let place = builder.borrow_mut().net.add_place();
1060    new_place(builder, place)
1061}
1062
1063fn get_place_with_id(builder: &Rc<RefCell<BuilderInternal>>, id: &NodeId) -> SimplePlaceBuilder {
1064    if let Some(place) = builder.borrow_mut().net.place(id) {
1065        let place = place.id();
1066        new_place(builder, place)
1067    } else {
1068        panic!()
1069    }
1070}
1071
1072fn get_remembered_place(
1073    builder: &Rc<RefCell<BuilderInternal>>,
1074    tag: &'static str,
1075) -> SimplePlaceBuilder {
1076    let id = if let Some(id) = builder.borrow_mut().memory.get(tag).cloned() {
1077        id
1078    } else {
1079        panic!()
1080    };
1081    get_place_with_id(builder, &id)
1082}
1083
1084#[inline(always)]
1085fn new_transition(builder: &Rc<RefCell<BuilderInternal>>, id: NodeId) -> SimpleTransitionBuilder {
1086    SimpleTransitionBuilder {
1087        inner: builder.clone(),
1088        transition: id,
1089    }
1090}
1091
1092#[inline(always)]
1093fn add_transition(builder: &Rc<RefCell<BuilderInternal>>) -> SimpleTransitionBuilder {
1094    let transition = builder.borrow_mut().net.add_transition();
1095    new_transition(builder, transition)
1096}
1097
1098fn get_transition_with_id(
1099    builder: &Rc<RefCell<BuilderInternal>>,
1100    id: &NodeId,
1101) -> SimpleTransitionBuilder {
1102    if let Some(transition) = &((builder.borrow()).net).transition(id) {
1103        let transition = transition.id();
1104        new_transition(builder, transition)
1105    } else {
1106        panic!()
1107    }
1108}
1109
1110fn get_remembered_transition(
1111    builder: &Rc<RefCell<BuilderInternal>>,
1112    tag: &'static str,
1113) -> SimpleTransitionBuilder {
1114    let id = if let Some(id) = builder.borrow().memory.get(tag).cloned() {
1115        id
1116    } else {
1117        panic!()
1118    };
1119    get_transition_with_id(builder, &id)
1120}
1121
1122#[inline(always)]
1123fn add_arc(builder: &Rc<RefCell<BuilderInternal>>, source: NodeId, target: NodeId) {
1124    builder.borrow_mut().net.add_arc(source, target);
1125}
1126
1127#[inline(always)]
1128fn tag_to_id(builder: &Rc<RefCell<BuilderInternal>>, tag: &'static str) -> Option<NodeId> {
1129    builder.borrow().memory.get(tag).cloned()
1130}