ebi_objects/
marking.rs

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>, //for each place: number of tokens in that place
11}
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    /**
58     * Returns whether all places are at least equal, and at least one has a larger number of tokens.
59     */
60    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    /**
77     * Returns whether all places are at least equal.
78     */
79    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}