taco_threshold_automaton/lib.rs
1//! A library to interact with threshold automata
2//!
3//! This crate contains the definitions of the types used to represent and
4//! interact with threshold automata. In particular, it contains the
5//! traits:
6//! - [`ThresholdAutomaton`]: common interface for all flavors of threshold
7//! automata
8//! - [`RuleDefinition`]: common interface for rules in a threshold automaton
9//! - [`ActionDefinition`]: trait to represent different flavors of actions
10
11//! - [`VariableConstraint`]: different forms of constraints over variables
12//!
13//! The most general type implementing the interface is the
14//! [`general_threshold_automaton::GeneralThresholdAutomaton`] type. However,
15//! the type is more general than the theoretical definition of threshold
16//! automata, as it for example allows variable comparisons or resets.
17//!
18//! To the best of our knowledge, verification algorithms for threshold automata
19//! only exist for threshold automata that use linear integer arithmetic in
20//! their guards / thresholds. Therefore, when implementing a new model
21//! checker, you will usually want to work with the
22//! [`lia_threshold_automaton::LIAThresholdAutomaton`] flavor of threshold
23//! automata.
24
25use std::fmt::Debug;
26use std::{fmt, hash::Hash};
27
28use expressions::{BooleanExpression, IntegerExpression, Location, Parameter, Variable};
29
30use crate::expressions::IsDeclared;
31
32pub mod expressions;
33pub mod general_threshold_automaton;
34pub mod lia_threshold_automaton;
35
36pub mod path;
37
38#[cfg(feature = "dot")]
39pub mod dot;
40
41/// Constraint over the number of processes in a certain location
42pub type LocationConstraint = BooleanExpression<Location>;
43
44/// Constraint over the valuation of parameters
45pub type ParameterConstraint = BooleanExpression<Parameter>;
46
47/// Constraint over the valuation of the shared variables
48pub type BooleanVarConstraint = BooleanExpression<Variable>;
49
50/// Common trait for different types of threshold automata
51///
52/// This trait is implemented by all types and flavors of threshold
53/// automata and provides a common interface for interacting with threshold
54/// automata.
55///
56/// This trait is for example implemented by
57/// [`general_threshold_automaton::GeneralThresholdAutomaton`]
58/// or [`lia_threshold_automaton::LIAThresholdAutomaton`].
59pub trait ThresholdAutomaton:
60 Debug + Clone + fmt::Display + IsDeclared<Parameter> + IsDeclared<Variable> + IsDeclared<Location>
61{
62 /// Type of the rules of the threshold automaton
63 type Rule: RuleDefinition;
64 /// Type of the initial variable conditions of the threshold automaton
65 type InitialVariableConstraintType: VariableConstraint;
66
67 /// Get the name of the threshold automaton
68 fn name(&self) -> &str;
69
70 /// Get the parameters of the threshold automaton
71 fn parameters(&self) -> impl Iterator<Item = &Parameter>;
72
73 /// Get the initial location constraints of the threshold automaton
74 fn initial_location_constraints(&self) -> impl Iterator<Item = &LocationConstraint>;
75
76 /// Get the initial variable constraints of the threshold automaton
77 fn initial_variable_constraints(
78 &self,
79 ) -> impl Iterator<Item = &Self::InitialVariableConstraintType>;
80
81 /// Get the resilience condition of the threshold automaton
82 fn resilience_conditions(&self) -> impl Iterator<Item = &BooleanExpression<Parameter>>;
83
84 /// Get the shared variables of the threshold automaton
85 fn variables(&self) -> impl Iterator<Item = &Variable>;
86
87 /// Get the locations of the threshold automaton
88 fn locations(&self) -> impl Iterator<Item = &Location>;
89
90 /// Check if a location can be initial by the location constraints of the
91 /// threshold automaton
92 ///
93 /// Returns true if the location can be an initial location of the threshold
94 fn can_be_initial_location(&self, location: &Location) -> bool;
95
96 /// Get the rules of the threshold automaton
97 fn rules(&self) -> impl Iterator<Item = &Self::Rule>;
98
99 /// Get incoming rules to a location
100 ///
101 /// Returns the rules that have the given location as target location.
102 /// This means that the location is the target of the transition.
103 fn incoming_rules(&self, location: &Location) -> impl Iterator<Item = &Self::Rule>;
104
105 /// Get outgoing rules for a location
106 ///
107 /// Returns the rules that have the given location as source location.
108 fn outgoing_rules(&self, location: &Location) -> impl Iterator<Item = &Self::Rule>;
109
110 /// Check whether the threshold automaton contains any decrements or resets
111 fn has_decrements_or_resets(&self) -> bool {
112 self.rules().any(|r| r.has_decrements() || r.has_resets())
113 }
114
115 /// Check whether the threshold automaton contains any decrements
116 fn has_decrements(&self) -> bool {
117 self.rules().any(|r| r.has_decrements())
118 }
119
120 /// Check whether the threshold automaton contains any resets
121 fn has_resets(&self) -> bool {
122 self.rules().any(|r| r.has_resets())
123 }
124}
125
126/// Trait implemented by all flavors of rules
127///
128/// Trait for common functionality of rules. This trait is implemented for
129/// the [`general_threshold_automaton::Rule`] type for
130/// [`general_threshold_automaton::GeneralThresholdAutomaton`] and
131/// [`lia_threshold_automaton::LIARule`] for
132/// [`lia_threshold_automaton::LIAThresholdAutomaton`].
133pub trait RuleDefinition: Clone + Debug + fmt::Display + PartialEq + Hash + Eq {
134 /// Type of the actions of the rule
135 type Action: ActionDefinition;
136 /// Type of the guard of the rule
137 type Guard: VariableConstraint;
138
139 /// Returns the id of the rule
140 ///
141 /// The id is a unique identifier assigned to the rule in the specification.
142 /// It is used to refer to the rule in the specification.
143 fn id(&self) -> u32;
144
145 /// Returns the source location of the rule
146 ///
147 /// The source location is the location from which the rule transitions
148 /// to the target location.
149 fn source(&self) -> &Location;
150
151 /// Returns the target location of the rule
152 ///
153 /// The target location is the location to which the rule transitions
154 /// from the source location.
155 fn target(&self) -> &Location;
156
157 /// Returns the guard of the rule
158 ///
159 /// The guard is a boolean expression over shared variables that must be
160 /// satisfied for the rule to be enabled.
161 fn guard(&self) -> &Self::Guard;
162
163 /// Returns the actions of the rule
164 ///
165 /// The actions are the updates to shared variables that are performed
166 /// when the rule is executed.
167 fn actions(&self) -> impl Iterator<Item = &Self::Action>;
168
169 /// Check whether the rule has a decrement action
170 fn has_decrements(&self) -> bool {
171 self.actions().any(|ac| ac.is_decrement())
172 }
173
174 /// Check whether the rule has a reset action
175 fn has_resets(&self) -> bool {
176 self.actions().any(|ac| ac.is_reset())
177 }
178}
179
180/// Trait implemented by all flavors of actions
181///
182/// This trait is for example implemented for the
183/// [`general_threshold_automaton::Action`] type.
184pub trait ActionDefinition: Clone + Debug + fmt::Display + PartialEq + Hash + Eq + Ord {
185 /// Returns the variable to be updated by the action
186 fn variable(&self) -> &Variable;
187
188 /// Check whether the action does not change any variables, i.e. is a noop
189 fn is_unchanged(&self) -> bool;
190
191 /// Check whether the action is a reset action
192 fn is_reset(&self) -> bool;
193
194 /// Check whether the action is an increment action
195 fn is_increment(&self) -> bool;
196
197 /// Check whether the action is a decrement action
198 fn is_decrement(&self) -> bool;
199}
200
201/// Trait implemented by all flavors of constraints over variables that can
202/// serve as Guards
203///
204/// This trait is for example implemented by [`BooleanExpression<Variable>`] or
205/// [`lia_threshold_automaton::LIAVariableConstraint`]
206pub trait VariableConstraint: Clone + Debug + fmt::Display + PartialEq + Ord {
207 /// Get the guard as a boolean expression over variables
208 fn as_boolean_expr(&self) -> BooleanExpression<Variable>;
209}
210
211/// Trait for threshold automata that can be modified
212///
213/// This trait is implemented by threshold automata that can be modified.
214/// for example, through preprocessing or other means. It provides methods to
215/// modify, remove or add components of the threshold automaton.
216///
217/// Note the resulting threshold automaton is not validated. It is up to the
218/// user to ensure that transformations result in a valid threshold automaton.
219/// Invalid threshold automata can lead to panics of other methods or functions.
220/// If a type does not implement this trait, you should modify a higher level
221/// representation.
222///
223/// Methods from this trait should not be used to construct a threshold
224/// automaton, but rather to modify an existing one. To build a threshold
225/// automaton, use the corresponding builder, e.g.,
226/// [`general_threshold_automaton::builder::GeneralThresholdAutomatonBuilder`].
227pub trait ModifiableThresholdAutomaton: ThresholdAutomaton {
228 /// Rename the threshold automaton
229 fn set_name(&mut self, new_name: String);
230
231 /// Add a new rule to the threshold automaton
232 ///
233 /// **Note**: The rule that is inserted is not validated. To build a threshold
234 /// automaton, you should use the corresponding builder, e.g.,
235 /// `GeneralThresholdAutomatonBuilder`.
236 fn add_rule(&mut self, rule: Self::Rule);
237
238 /// Add a new resilience condition to the threshold automaton
239 ///
240 /// **Note**: The resilience condition that is inserted is not validated. To
241 /// build a threshold automaton, you should use the corresponding builder,
242 /// e.g., `GeneralThresholdAutomatonBuilder`.
243 fn add_resilience_conditions<C: IntoIterator<Item = BooleanExpression<Parameter>>>(
244 &mut self,
245 conditions: C,
246 );
247
248 /// Add a new initial location constraint to the threshold automaton
249 ///
250 /// **Note**: The initial location constraint that is inserted is not
251 /// validated. To build a threshold automaton, you should use the
252 /// corresponding builder, e.g., `GeneralThresholdAutomatonBuilder`.
253 fn add_initial_location_constraints<C: IntoIterator<Item = LocationConstraint>>(
254 &mut self,
255 constraints: C,
256 );
257
258 /// Add a new initial variable constraint to the threshold automaton
259 ///
260 /// **Note**: The initial variable constraint that is inserted is not
261 /// validated. To build a threshold automaton, you should use the
262 /// corresponding builder, e.g., `GeneralThresholdAutomatonBuilder`.
263 fn add_initial_variable_constraints<C: IntoIterator<Item = BooleanVarConstraint>>(
264 &mut self,
265 constraints: C,
266 );
267
268 /// Retains only the rules specified by the predicate.
269 ///
270 /// In other words, remove all rules r for which predicate(&r) returns false.
271 ///
272 /// **Note**: The method `predicate` can be called multiple times per rule.
273 fn retain_rules<F>(&mut self, predicate: F)
274 where
275 F: Fn(&Self::Rule) -> bool;
276
277 /// Apply a transformation to each rule
278 ///
279 /// This method is used to apply a transformation to each rule of the
280 /// threshold automaton. The transformation is applied in place, meaning
281 /// that the rule is modified directly.
282 ///
283 /// **Note**:
284 /// - The method `f` can be called multiple times per rule.
285 /// - The transformed rule is not validated
286 fn transform_rules<F>(&mut self, f: F)
287 where
288 F: FnMut(&mut Self::Rule);
289
290 /// Remove a location `location` from the threshold automaton, removes rules
291 /// referencing the location and replace every occurrence in initial
292 /// conditions with `subst`
293 ///
294 /// **Note**: The resulting location constraints are not validated
295 fn remove_location_and_replace_with(
296 &mut self,
297 location: &Location,
298 subst: IntegerExpression<Location>,
299 );
300
301 /// Remove a variable `variable` from the threshold automaton, replace every
302 /// occurrence in initial conditions or guards with `subst` and remove all
303 /// updates to `variable` from the rules
304 ///
305 /// **Note**: The resulting variable constraints and guards are not validated
306 fn remove_variable_and_replace_with(
307 &mut self,
308 variable: &Variable,
309 subst: IntegerExpression<Variable>,
310 );
311
312 /// Remove all location_constraints from the threshold automaton
313 /// Needed to specify initial configurations for coverability and
314 /// reachability through the CLI.
315 fn replace_initial_location_constraints<C: IntoIterator<Item = LocationConstraint>>(
316 &mut self,
317 constraints: C,
318 );
319
320 /// Remove all variable_constraints from the threshold automaton
321 /// Needed to specify initial configurations for coverability and
322 /// reachability through the CLI.
323 fn replace_initial_variable_constraints<C: IntoIterator<Item = BooleanVarConstraint>>(
324 &mut self,
325 constraints: C,
326 );
327}