Skip to main content

oxilean_std/model_checking/
functions.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
6use std::collections::{HashMap, HashSet, VecDeque};
7
8use super::types::{
9    AbstractDomain, AbstractTransformer, AtomicProposition, BDDManager, BDDModelChecker,
10    BuchiAutomaton, CounterExample, CounterExampleGuidedRefinement, CtlFormula, CtlModelChecker,
11    CtlStarFormula, KripkeStructure, LtlFormula, LtlModelChecker, MuCalculusEvaluator, MuFormula,
12    ParityGameZielonka, ProbabilisticMCVerifier, SpuriousCounterexample, StateLabel,
13    SymbolicTransitionRelation, BDD,
14};
15
16pub fn app(f: Expr, a: Expr) -> Expr {
17    Expr::App(Box::new(f), Box::new(a))
18}
19pub fn app2(f: Expr, a: Expr, b: Expr) -> Expr {
20    app(app(f, a), b)
21}
22pub fn app3(f: Expr, a: Expr, b: Expr, c: Expr) -> Expr {
23    app(app2(f, a, b), c)
24}
25pub fn cst(s: &str) -> Expr {
26    Expr::Const(Name::str(s), vec![])
27}
28pub fn prop() -> Expr {
29    Expr::Sort(Level::zero())
30}
31pub fn type0() -> Expr {
32    Expr::Sort(Level::succ(Level::zero()))
33}
34pub fn pi(bi: BinderInfo, name: &str, dom: Expr, body: Expr) -> Expr {
35    Expr::Pi(bi, Name::str(name), Box::new(dom), Box::new(body))
36}
37pub fn arrow(a: Expr, b: Expr) -> Expr {
38    pi(BinderInfo::Default, "_", a, b)
39}
40pub fn impl_pi(name: &str, dom: Expr, body: Expr) -> Expr {
41    pi(BinderInfo::Implicit, name, dom, body)
42}
43pub fn bvar(n: u32) -> Expr {
44    Expr::BVar(n)
45}
46pub fn nat_ty() -> Expr {
47    cst("Nat")
48}
49pub fn bool_ty() -> Expr {
50    cst("Bool")
51}
52/// KripkeStructure: (S, S_0, R, L)
53pub fn kripke_structure_ty() -> Expr {
54    type0()
55}
56/// AtomicProposition: boolean-valued proposition on states
57pub fn atomic_proposition_ty() -> Expr {
58    type0()
59}
60/// StateLabel: set of atomic propositions true in a state
61pub fn state_label_ty() -> Expr {
62    arrow(cst("State"), type0())
63}
64/// reachable_states: the set of states reachable from initial states
65pub fn reachable_states_ty() -> Expr {
66    arrow(cst("KripkeStructure"), app(cst("List"), cst("State")))
67}
68/// is_connected: every state is reachable from some initial state
69pub fn is_connected_ty() -> Expr {
70    arrow(cst("KripkeStructure"), prop())
71}
72/// compute_scc: Tarjan's SCC decomposition
73pub fn compute_scc_ty() -> Expr {
74    arrow(
75        cst("KripkeStructure"),
76        app(cst("List"), app(cst("List"), cst("State"))),
77    )
78}
79/// LTL formula type
80pub fn ltl_formula_ty() -> Expr {
81    type0()
82}
83/// CTL formula type
84pub fn ctl_formula_ty() -> Expr {
85    type0()
86}
87/// CTL* formula type
88pub fn ctl_star_formula_ty() -> Expr {
89    type0()
90}
91/// ltl_is_safety: φ is a safety property
92pub fn ltl_is_safety_ty() -> Expr {
93    arrow(cst("LtlFormula"), prop())
94}
95/// ltl_is_liveness: φ is a liveness property
96pub fn ltl_is_liveness_ty() -> Expr {
97    arrow(cst("LtlFormula"), prop())
98}
99/// ltl_is_fairness: φ is a fairness constraint
100pub fn ltl_is_fairness_ty() -> Expr {
101    arrow(cst("LtlFormula"), prop())
102}
103/// LtlModelChecker: automaton-theoretic LTL checking
104pub fn ltl_model_checker_ty() -> Expr {
105    type0()
106}
107/// CtlModelChecker: fixpoint computation for CTL
108pub fn ctl_model_checker_ty() -> Expr {
109    type0()
110}
111/// CounterExample: trace witnessing formula violation
112pub fn counter_example_ty() -> Expr {
113    type0()
114}
115/// BuchiAutomaton: (Q, Σ, δ, q_0, F) ω-automaton
116pub fn buchi_automaton_ty() -> Expr {
117    type0()
118}
119/// check_ltl: check whether K ⊨ φ (LTL)
120pub fn check_ltl_ty() -> Expr {
121    arrow(cst("KripkeStructure"), arrow(cst("LtlFormula"), bool_ty()))
122}
123/// check_ctl: check whether K ⊨ φ (CTL)
124pub fn check_ctl_ty() -> Expr {
125    arrow(cst("KripkeStructure"), arrow(cst("CtlFormula"), bool_ty()))
126}
127/// find_counterexample: produce a counterexample trace if formula fails
128pub fn find_counterexample_ty() -> Expr {
129    arrow(
130        cst("KripkeStructure"),
131        arrow(cst("LtlFormula"), app(cst("Option"), cst("CounterExample"))),
132    )
133}
134/// BDD: Binary Decision Diagram node
135pub fn bdd_ty() -> Expr {
136    type0()
137}
138/// BDDManager: unique table + apply cache
139pub fn bdd_manager_ty() -> Expr {
140    type0()
141}
142/// SymbolicTransitionRelation: T(s,s') as BDD
143pub fn symbolic_transition_relation_ty() -> Expr {
144    type0()
145}
146/// image: compute the forward image of a set of states
147pub fn image_ty() -> Expr {
148    arrow(
149        cst("BDDManager"),
150        arrow(
151            cst("BDD"),
152            arrow(cst("SymbolicTransitionRelation"), cst("BDD")),
153        ),
154    )
155}
156/// pre_image: compute the backward image of a set of states
157pub fn pre_image_ty() -> Expr {
158    arrow(
159        cst("BDDManager"),
160        arrow(
161            cst("BDD"),
162            arrow(cst("SymbolicTransitionRelation"), cst("BDD")),
163        ),
164    )
165}
166/// AbstractDomain: predicate abstraction / interval / octagon domain
167pub fn abstract_domain_ty() -> Expr {
168    type0()
169}
170/// AbstractTransformer: post[τ](α(S))
171pub fn abstract_transformer_ty() -> Expr {
172    arrow(
173        cst("AbstractDomain"),
174        arrow(cst("AbstractDomain"), cst("AbstractDomain")),
175    )
176}
177/// CounterExampleGuidedRefinement: CEGAR loop
178pub fn cegar_ty() -> Expr {
179    type0()
180}
181/// SpuriousCounterexample: infeasible concrete path
182pub fn spurious_counterexample_ty() -> Expr {
183    type0()
184}
185/// abstract_states: map concrete states to abstract domain
186pub fn abstract_states_ty() -> Expr {
187    arrow(app(cst("List"), cst("State")), cst("AbstractDomain"))
188}
189/// refine_abstraction: refine abstract domain using a spurious counterexample
190pub fn refine_abstraction_ty() -> Expr {
191    arrow(
192        cst("AbstractDomain"),
193        arrow(cst("SpuriousCounterexample"), cst("AbstractDomain")),
194    )
195}
196/// check_feasibility: determine if a counterexample is spurious
197pub fn check_feasibility_ty() -> Expr {
198    arrow(cst("CounterExample"), bool_ty())
199}
200/// MuFormula: a μ-calculus formula type
201pub fn mu_formula_ty() -> Expr {
202    type0()
203}
204/// mu_fixpoint: the least fixpoint operator μX.φ(X)
205/// mu_fixpoint : (State → Prop) → (State → Prop)
206pub fn mu_fixpoint_ty() -> Expr {
207    arrow(arrow(cst("State"), prop()), arrow(cst("State"), prop()))
208}
209/// nu_fixpoint: the greatest fixpoint operator νX.φ(X)
210/// nu_fixpoint : (State → Prop) → (State → Prop)
211pub fn nu_fixpoint_ty() -> Expr {
212    arrow(arrow(cst("State"), prop()), arrow(cst("State"), prop()))
213}
214/// check_mu: model check a μ-calculus formula
215/// check_mu : KripkeStructure → MuFormula → Bool
216pub fn check_mu_ty() -> Expr {
217    arrow(cst("KripkeStructure"), arrow(cst("MuFormula"), bool_ty()))
218}
219/// AlternatingTuringMachine: ATM used in alternation-based μ-calculus model checking
220pub fn alternating_turing_machine_ty() -> Expr {
221    type0()
222}
223/// ALC: the description logic ALC (attribute language with complement)
224pub fn alc_concept_ty() -> Expr {
225    type0()
226}
227/// ParityGame: a game graph with priority function
228pub fn parity_game_ty() -> Expr {
229    type0()
230}
231/// ParityCondition: ω-winning condition: the highest priority seen inf-often is even
232/// ParityCondition : (Nat → Bool) → Prop
233pub fn parity_condition_ty() -> Expr {
234    arrow(arrow(nat_ty(), bool_ty()), prop())
235}
236/// ZielonkaSolver: Zielonka's recursive parity game algorithm
237/// ZielonkaSolver : ParityGame → Bool
238pub fn zielonka_solver_ty() -> Expr {
239    arrow(cst("ParityGame"), bool_ty())
240}
241/// parity_game_winner: which player wins from a given vertex?
242/// parity_game_winner : ParityGame → Nat → Bool
243pub fn parity_game_winner_ty() -> Expr {
244    arrow(cst("ParityGame"), arrow(nat_ty(), bool_ty()))
245}
246/// mu_calculus_parity_reduction: reduction of μ-calc. to parity games
247/// mu_calculus_parity_reduction : MuFormula → ParityGame
248pub fn mu_calculus_parity_reduction_ty() -> Expr {
249    arrow(cst("MuFormula"), cst("ParityGame"))
250}
251/// SatSolver: a SAT/SMT oracle used in bounded model checking
252pub fn sat_solver_ty() -> Expr {
253    type0()
254}
255/// BoundedMCQuery: a bounded model checking problem (BMC)
256/// BoundedMCQuery : KripkeStructure → LtlFormula → Nat → Bool
257pub fn bounded_mc_query_ty() -> Expr {
258    arrow(
259        cst("KripkeStructure"),
260        arrow(cst("LtlFormula"), arrow(nat_ty(), bool_ty())),
261    )
262}
263/// KInductionResult: result of a k-induction proof step
264pub fn k_induction_result_ty() -> Expr {
265    type0()
266}
267/// k_induction_check: run k-induction for LTL safety properties
268/// k_induction_check : KripkeStructure → LtlFormula → Nat → KInductionResult
269pub fn k_induction_check_ty() -> Expr {
270    arrow(
271        cst("KripkeStructure"),
272        arrow(cst("LtlFormula"), arrow(nat_ty(), cst("KInductionResult"))),
273    )
274}
275/// ProbabilisticKripke: a Markov Decision Process / Markov chain
276pub fn probabilistic_kripke_ty() -> Expr {
277    type0()
278}
279/// PCTLFormula: a PCTL (probabilistic CTL) formula type
280pub fn pctl_formula_ty() -> Expr {
281    type0()
282}
283/// check_pctl: check whether M ⊨ φ (PCTL)
284/// check_pctl : ProbabilisticKripke → PCTLFormula → Bool
285pub fn check_pctl_ty() -> Expr {
286    arrow(
287        cst("ProbabilisticKripke"),
288        arrow(cst("PCTLFormula"), bool_ty()),
289    )
290}
291/// reachability_probability: P[reach(T) from s] in a Markov chain
292/// reachability_probability : ProbabilisticKripke → State → Set State → Real
293pub fn reachability_probability_ty() -> Expr {
294    arrow(
295        cst("ProbabilisticKripke"),
296        arrow(
297            cst("State"),
298            arrow(app(cst("Set"), cst("State")), cst("Real")),
299        ),
300    )
301}
302/// TimedAutomaton: automaton with clock variables
303pub fn timed_automaton_ty() -> Expr {
304    type0()
305}
306/// TCTLFormula: a timed CTL formula
307pub fn tctl_formula_ty() -> Expr {
308    type0()
309}
310/// ZoneGraph: zone-based abstract state space for timed systems
311pub fn zone_graph_ty() -> Expr {
312    type0()
313}
314/// check_tctl: verify a timed CTL formula over a timed automaton
315/// check_tctl : TimedAutomaton → TCTLFormula → Bool
316pub fn check_tctl_ty() -> Expr {
317    arrow(cst("TimedAutomaton"), arrow(cst("TCTLFormula"), bool_ty()))
318}
319/// zone_reachability: compute the reachable zone graph of a timed automaton
320/// zone_reachability : TimedAutomaton → ZoneGraph
321pub fn zone_reachability_ty() -> Expr {
322    arrow(cst("TimedAutomaton"), cst("ZoneGraph"))
323}
324/// HybridAutomaton: automaton with continuous flow conditions
325pub fn hybrid_automaton_ty() -> Expr {
326    type0()
327}
328/// FlowCondition: ODE describing continuous evolution in a mode
329/// FlowCondition : Type → Prop
330pub fn flow_condition_ty() -> Expr {
331    arrow(type0(), prop())
332}
333/// GuardRegion: a polyhedral region enabling a discrete transition
334/// GuardRegion : Type → Prop
335pub fn guard_region_ty() -> Expr {
336    arrow(type0(), prop())
337}
338/// HybridReachability: reachable set of a hybrid system
339/// HybridReachability : HybridAutomaton → Set Type
340pub fn hybrid_reachability_ty() -> Expr {
341    arrow(cst("HybridAutomaton"), app(cst("Set"), type0()))
342}
343/// PushdownSystem: a recursive program modeled as a pushdown automaton
344pub fn pushdown_system_ty() -> Expr {
345    type0()
346}
347/// ContextFreeLTL: an LTL formula interpreted over pushdown system runs
348pub fn context_free_ltl_ty() -> Expr {
349    type0()
350}
351/// check_pushdown_ltl: model check a pushdown system against an LTL formula
352/// check_pushdown_ltl : PushdownSystem → LtlFormula → Bool
353pub fn check_pushdown_ltl_ty() -> Expr {
354    arrow(cst("PushdownSystem"), arrow(cst("LtlFormula"), bool_ty()))
355}
356/// pushdown_reachability: backwards reachability in a pushdown system
357/// pushdown_reachability : PushdownSystem → Set State
358pub fn pushdown_reachability_ty() -> Expr {
359    arrow(cst("PushdownSystem"), app(cst("Set"), cst("State")))
360}
361/// HigherOrderRecursionScheme: a HORS defining a tree language
362pub fn hors_ty() -> Expr {
363    type0()
364}
365/// HORSModelChecking: model check a HORS against an MSO property
366/// HORSModelChecking : HigherOrderRecursionScheme → MuFormula → Bool
367pub fn hors_model_checking_ty() -> Expr {
368    arrow(
369        cst("HigherOrderRecursionScheme"),
370        arrow(cst("MuFormula"), bool_ty()),
371    )
372}
373/// CraigInterpolant: a formula I with A ⊨ I and I ∧ B unsatisfiable
374/// CraigInterpolant : LtlFormula → LtlFormula → LtlFormula → Prop
375pub fn craig_interpolant_ty() -> Expr {
376    arrow(
377        cst("LtlFormula"),
378        arrow(cst("LtlFormula"), arrow(cst("LtlFormula"), prop())),
379    )
380}
381/// lazy_cegar: CEGAR with lazy abstraction refinement
382/// lazy_cegar : KripkeStructure → LtlFormula → Bool
383pub fn lazy_cegar_ty() -> Expr {
384    arrow(cst("KripkeStructure"), arrow(cst("LtlFormula"), bool_ty()))
385}
386/// AssumeGuaranteeContract: an AG specification (A, G)
387pub fn assume_guarantee_contract_ty() -> Expr {
388    type0()
389}
390/// ag_decomposition: decompose a verification task using A-G reasoning
391/// ag_decomposition : KripkeStructure → AssumeGuaranteeContract → Bool
392pub fn ag_decomposition_ty() -> Expr {
393    arrow(
394        cst("KripkeStructure"),
395        arrow(cst("AssumeGuaranteeContract"), bool_ty()),
396    )
397}
398/// interface_verification: check compatibility of component interfaces
399/// interface_verification : List AssumeGuaranteeContract → Bool
400pub fn interface_verification_ty() -> Expr {
401    arrow(app(cst("List"), cst("AssumeGuaranteeContract")), bool_ty())
402}
403/// MazurkiewiczTrace: an equivalence class of runs under independence
404pub fn mazurkiewicz_trace_ty() -> Expr {
405    type0()
406}
407/// PersistentSet: a persistent set for partial order reduction
408/// PersistentSet : KripkeStructure → State → Set (State → State) → Prop
409pub fn persistent_set_ty() -> Expr {
410    arrow(
411        cst("KripkeStructure"),
412        arrow(
413            cst("State"),
414            arrow(app(cst("Set"), arrow(cst("State"), cst("State"))), prop()),
415        ),
416    )
417}
418/// AmpleSet: an ample set satisfying C0–C3 for POR
419/// AmpleSet : KripkeStructure → State → Set (State → State) → Prop
420pub fn ample_set_ty() -> Expr {
421    arrow(
422        cst("KripkeStructure"),
423        arrow(
424            cst("State"),
425            arrow(app(cst("Set"), arrow(cst("State"), cst("State"))), prop()),
426        ),
427    )
428}
429/// por_reduction: apply partial order reduction to a Kripke structure
430/// por_reduction : KripkeStructure → KripkeStructure
431pub fn por_reduction_ty() -> Expr {
432    arrow(cst("KripkeStructure"), cst("KripkeStructure"))
433}
434/// PSLFormula: a PSL (Property Specification Language) formula
435pub fn psl_formula_ty() -> Expr {
436    type0()
437}
438/// SVAFormula: a SystemVerilog assertion formula
439pub fn sva_formula_ty() -> Expr {
440    type0()
441}
442/// check_psl: check a PSL formula against a Kripke structure
443/// check_psl : KripkeStructure → PSLFormula → Bool
444pub fn check_psl_ty() -> Expr {
445    arrow(cst("KripkeStructure"), arrow(cst("PSLFormula"), bool_ty()))
446}
447/// TemporalLogicPattern: a reusable specification pattern (Dwyer patterns)
448pub fn temporal_logic_pattern_ty() -> Expr {
449    type0()
450}
451/// Register all model checking axioms into the kernel environment.
452pub fn build_env(env: &mut Environment) {
453    let axioms: &[(&str, Expr)] = &[
454        ("KripkeStructure", kripke_structure_ty()),
455        ("AtomicProposition", atomic_proposition_ty()),
456        ("StateLabel", state_label_ty()),
457        ("State", type0()),
458        ("reachable_states", reachable_states_ty()),
459        ("is_connected", is_connected_ty()),
460        ("compute_scc", compute_scc_ty()),
461        ("LtlFormula", ltl_formula_ty()),
462        ("CtlFormula", ctl_formula_ty()),
463        ("CtlStarFormula", ctl_star_formula_ty()),
464        ("ltl_is_safety", ltl_is_safety_ty()),
465        ("ltl_is_liveness", ltl_is_liveness_ty()),
466        ("ltl_is_fairness", ltl_is_fairness_ty()),
467        ("LtlModelChecker", ltl_model_checker_ty()),
468        ("CtlModelChecker", ctl_model_checker_ty()),
469        ("CounterExample", counter_example_ty()),
470        ("BuchiAutomaton", buchi_automaton_ty()),
471        ("Option", arrow(type0(), type0())),
472        ("check_ltl", check_ltl_ty()),
473        ("check_ctl", check_ctl_ty()),
474        ("find_counterexample", find_counterexample_ty()),
475        ("BDD", bdd_ty()),
476        ("BDDManager", bdd_manager_ty()),
477        (
478            "SymbolicTransitionRelation",
479            symbolic_transition_relation_ty(),
480        ),
481        ("image", image_ty()),
482        ("pre_image", pre_image_ty()),
483        ("AbstractDomain", abstract_domain_ty()),
484        ("AbstractTransformer", abstract_transformer_ty()),
485        ("CounterExampleGuidedRefinement", cegar_ty()),
486        ("SpuriousCounterexample", spurious_counterexample_ty()),
487        ("abstract_states", abstract_states_ty()),
488        ("refine_abstraction", refine_abstraction_ty()),
489        ("check_feasibility", check_feasibility_ty()),
490        ("MuFormula", mu_formula_ty()),
491        ("mu_fixpoint", mu_fixpoint_ty()),
492        ("nu_fixpoint", nu_fixpoint_ty()),
493        ("check_mu", check_mu_ty()),
494        ("AlternatingTuringMachine", alternating_turing_machine_ty()),
495        ("ALCConcept", alc_concept_ty()),
496        ("ParityGame", parity_game_ty()),
497        ("ParityCondition", parity_condition_ty()),
498        ("ZielonkaSolver", zielonka_solver_ty()),
499        ("parity_game_winner", parity_game_winner_ty()),
500        (
501            "mu_calculus_parity_reduction",
502            mu_calculus_parity_reduction_ty(),
503        ),
504        ("SatSolver", sat_solver_ty()),
505        ("BoundedMCQuery", bounded_mc_query_ty()),
506        ("KInductionResult", k_induction_result_ty()),
507        ("k_induction_check", k_induction_check_ty()),
508        ("ProbabilisticKripke", probabilistic_kripke_ty()),
509        ("PCTLFormula", pctl_formula_ty()),
510        ("check_pctl", check_pctl_ty()),
511        ("reachability_probability", reachability_probability_ty()),
512        ("TimedAutomaton", timed_automaton_ty()),
513        ("TCTLFormula", tctl_formula_ty()),
514        ("ZoneGraph", zone_graph_ty()),
515        ("check_tctl", check_tctl_ty()),
516        ("zone_reachability", zone_reachability_ty()),
517        ("HybridAutomaton", hybrid_automaton_ty()),
518        ("FlowCondition", flow_condition_ty()),
519        ("GuardRegion", guard_region_ty()),
520        ("HybridReachability", hybrid_reachability_ty()),
521        ("PushdownSystem", pushdown_system_ty()),
522        ("ContextFreeLTL", context_free_ltl_ty()),
523        ("check_pushdown_ltl", check_pushdown_ltl_ty()),
524        ("pushdown_reachability", pushdown_reachability_ty()),
525        ("HigherOrderRecursionScheme", hors_ty()),
526        ("HORSModelChecking", hors_model_checking_ty()),
527        ("CraigInterpolant", craig_interpolant_ty()),
528        ("lazy_cegar", lazy_cegar_ty()),
529        ("AssumeGuaranteeContract", assume_guarantee_contract_ty()),
530        ("ag_decomposition", ag_decomposition_ty()),
531        ("interface_verification", interface_verification_ty()),
532        ("MazurkiewiczTrace", mazurkiewicz_trace_ty()),
533        ("PersistentSet", persistent_set_ty()),
534        ("AmpleSet", ample_set_ty()),
535        ("por_reduction", por_reduction_ty()),
536        ("PSLFormula", psl_formula_ty()),
537        ("SVAFormula", sva_formula_ty()),
538        ("check_psl", check_psl_ty()),
539        ("TemporalLogicPattern", temporal_logic_pattern_ty()),
540        ("Real", cst("Real")),
541    ];
542    for (name, ty) in axioms {
543        env.add(Declaration::Axiom {
544            name: Name::str(*name),
545            univ_params: vec![],
546            ty: ty.clone(),
547        })
548        .ok();
549    }
550}
551#[cfg(test)]
552mod new_impl_tests {
553    use super::*;
554    fn small_kripke() -> KripkeStructure {
555        let mut k = KripkeStructure::new(3);
556        k.add_initial(0);
557        k.add_transition(0, 1);
558        k.add_transition(1, 2);
559        k.add_transition(2, 0);
560        k.label_state(0, "p");
561        k.label_state(1, "q");
562        k
563    }
564    #[test]
565    fn test_mu_calculus_evaluator_true() {
566        let k = small_kripke();
567        let mc = MuCalculusEvaluator::new(k);
568        let f = MuFormula::True_;
569        assert!(mc.check(&f));
570    }
571    #[test]
572    fn test_mu_calculus_evaluator_prop() {
573        let k = small_kripke();
574        let mc = MuCalculusEvaluator::new(k);
575        let f = MuFormula::Prop("p".to_string());
576        assert!(mc.check(&f));
577    }
578    #[test]
579    fn test_mu_calculus_evaluator_diamond() {
580        let k = small_kripke();
581        let mc = MuCalculusEvaluator::new(k);
582        let f = MuFormula::Diamond(Box::new(MuFormula::Prop("q".to_string())));
583        assert!(mc.check(&f));
584    }
585    #[test]
586    fn test_mu_calculus_evaluator_nu_box() {
587        let k = small_kripke();
588        let mc = MuCalculusEvaluator::new(k.clone());
589        let f = MuFormula::Nu("X".to_string(), Box::new(MuFormula::True_));
590        let mut env = HashMap::new();
591        let sat = mc.eval(&f, &mut env);
592        assert_eq!(sat.len(), k.num_states);
593    }
594    #[test]
595    fn test_parity_game_zielonka_trivial() {
596        let mut pg = ParityGameZielonka::new(1);
597        pg.set_priority(0, 0);
598        pg.set_owner(0, 1);
599        pg.add_edge(0, 0);
600        let (w0, _w1) = pg.solve();
601        assert!(w0.contains(&0));
602    }
603    #[test]
604    fn test_parity_game_zielonka_two_nodes() {
605        let mut pg = ParityGameZielonka::new(2);
606        pg.set_priority(0, 1);
607        pg.set_priority(1, 2);
608        pg.set_owner(0, 0);
609        pg.set_owner(1, 1);
610        pg.add_edge(0, 1);
611        pg.add_edge(1, 0);
612        let (w0, _w1) = pg.solve();
613        assert!(!w0.is_empty() || pg.player0_wins(0));
614    }
615    #[test]
616    fn test_bdd_model_checker_new() {
617        let mut bmc = BDDModelChecker::new(2);
618        let t = bmc.mgr.true_node();
619        let f = bmc.mgr.false_node();
620        bmc.set_init(t);
621        bmc.set_trans(f);
622        let reach = bmc.reachable();
623        assert_eq!(reach, t);
624        assert!(bmc.check_ag_safe(t));
625        assert!(!bmc.check_ef(f));
626    }
627    #[test]
628    fn test_bdd_model_checker_variable() {
629        let mut bmc = BDDModelChecker::new(2);
630        let v0 = bmc.mgr.var(0);
631        let v1 = bmc.mgr.var(1);
632        let combined = bmc.mgr.bdd_and(v0, v1);
633        assert!(combined < bmc.mgr.nodes.len());
634    }
635    #[test]
636    fn test_probabilistic_mc_verifier() {
637        let mut mc = ProbabilisticMCVerifier::new(3);
638        mc.set_initial(0, 1.0);
639        mc.add_transition(0, 1, 0.6);
640        mc.add_transition(0, 2, 0.4);
641        mc.add_transition(1, 1, 1.0);
642        mc.add_transition(2, 2, 1.0);
643        mc.label_state(1, "good");
644        mc.label_state(2, "bad");
645        let target: HashSet<usize> = [1].iter().copied().collect();
646        let prob = mc.reachability_prob(&target);
647        assert!((prob[0] - 0.6).abs() < 1e-6);
648        assert!(mc.check_prob_reach("good", 0.5));
649        assert!(!mc.check_prob_reach("good", 0.7));
650    }
651    #[test]
652    fn test_mc_env_new_axioms() {
653        let mut env = Environment::new();
654        build_env(&mut env);
655        assert!(env.get(&Name::str("MuFormula")).is_some());
656        assert!(env.get(&Name::str("mu_fixpoint")).is_some());
657        assert!(env.get(&Name::str("check_mu")).is_some());
658        assert!(env.get(&Name::str("ParityGame")).is_some());
659        assert!(env.get(&Name::str("ZielonkaSolver")).is_some());
660        assert!(env
661            .get(&Name::str("mu_calculus_parity_reduction"))
662            .is_some());
663        assert!(env.get(&Name::str("BoundedMCQuery")).is_some());
664        assert!(env.get(&Name::str("k_induction_check")).is_some());
665        assert!(env.get(&Name::str("PCTLFormula")).is_some());
666        assert!(env.get(&Name::str("reachability_probability")).is_some());
667        assert!(env.get(&Name::str("TimedAutomaton")).is_some());
668        assert!(env.get(&Name::str("zone_reachability")).is_some());
669        assert!(env.get(&Name::str("HybridAutomaton")).is_some());
670        assert!(env.get(&Name::str("HybridReachability")).is_some());
671        assert!(env.get(&Name::str("PushdownSystem")).is_some());
672        assert!(env.get(&Name::str("check_pushdown_ltl")).is_some());
673        assert!(env.get(&Name::str("HigherOrderRecursionScheme")).is_some());
674        assert!(env.get(&Name::str("CraigInterpolant")).is_some());
675        assert!(env.get(&Name::str("lazy_cegar")).is_some());
676        assert!(env.get(&Name::str("AssumeGuaranteeContract")).is_some());
677        assert!(env.get(&Name::str("interface_verification")).is_some());
678        assert!(env.get(&Name::str("MazurkiewiczTrace")).is_some());
679        assert!(env.get(&Name::str("AmpleSet")).is_some());
680        assert!(env.get(&Name::str("por_reduction")).is_some());
681        assert!(env.get(&Name::str("PSLFormula")).is_some());
682        assert!(env.get(&Name::str("SVAFormula")).is_some());
683        assert!(env.get(&Name::str("check_psl")).is_some());
684    }
685}