1use anyhow::{Result, anyhow};
2use std::{
3 cmp::Ordering,
4 fmt::{Debug, Display, Formatter},
5 ops::MulAssign,
6};
7
8#[derive(Clone, PartialEq, Eq, Hash)]
9pub struct Marking {
10 pub place2token: Vec<u64>, }
12
13impl Marking {
14 pub fn new(size: usize) -> Self {
15 Marking {
16 place2token: vec![0; size],
17 }
18 }
19
20 pub fn get_place2token(&self) -> &Vec<u64> {
21 &self.place2token
22 }
23
24 pub fn from_vec(place2token: Vec<u64>) -> Self {
25 Marking {
26 place2token: place2token,
27 }
28 }
29
30 pub fn increase(&mut self, place: usize, amount: u64) -> Result<()> {
31 if self.place2token[place] == u64::MAX - amount {
32 return Err(anyhow!(
33 "tried to put too many places in a marking for place {}",
34 place
35 ));
36 }
37
38 self.place2token[place] += amount;
39 Ok(())
40 }
41
42 pub fn decrease(&mut self, place: usize, amount: u64) -> Result<()> {
43 if self.place2token[place] < amount {
44 return Err(anyhow!(
45 "tried to obtain a negative number of places in a marking for place {}",
46 place
47 ));
48 }
49 self.place2token[place] -= amount;
50 Ok(())
51 }
52
53 pub fn add_place(&mut self) {
54 self.place2token.push(0);
55 }
56
57 pub fn is_larger_than(&self, other: &Self) -> bool {
61 let mut at_least_one_larger = false;
62 for (me, you) in self.place2token.iter().zip(other.place2token.iter()) {
63 match me.partial_cmp(you) {
64 Some(Ordering::Equal) => {}
65 Some(Ordering::Greater) => {
66 return false;
67 }
68 Some(Ordering::Less) => at_least_one_larger = true,
69 None => return false,
70 }
71 }
72
73 at_least_one_larger
74 }
75
76 pub fn is_larger_than_or_equal_to(&self, other: &Self) -> bool {
80 for (me, you) in self.place2token.iter().zip(other.place2token.iter()) {
81 match me.partial_cmp(you) {
82 Some(Ordering::Equal) => {}
83 Some(Ordering::Greater) => {
84 return false;
85 }
86 Some(Ordering::Less) => {}
87 None => return false,
88 }
89 }
90 return true;
91 }
92}
93
94impl From<Vec<u64>> for Marking {
95 fn from(value: Vec<u64>) -> Self {
96 Self { place2token: value }
97 }
98}
99
100impl Display for Marking {
101 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
102 write!(f, "{{")?;
103 let mut first = true;
104 for (place, multiplicity) in self.place2token.iter().enumerate() {
105 if *multiplicity > 0 {
106 if !first {
107 write!(f, ", ")?;
108 }
109 first = false;
110 write!(f, "{}:{}", place, multiplicity)?;
111 }
112 }
113 write!(f, "}}")
114 }
115}
116
117impl Debug for Marking {
118 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
119 write!(f, "{{")?;
120 let mut first = true;
121 for (place, multiplicity) in self.place2token.iter().enumerate() {
122 if *multiplicity > 0 {
123 if !first {
124 write!(f, ", ")?;
125 }
126 first = false;
127 write!(f, "{}:{}", place, multiplicity)?;
128 }
129 }
130 write!(f, "}}")
131 }
132}
133
134impl MulAssign<u64> for Marking {
135 fn mul_assign(&mut self, rhs: u64) {
136 self.place2token.iter_mut().for_each(|x| *x *= rhs);
137 }
138}