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