Skip to main content

oxilean_std/program_logics/
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::{BTreeMap, HashMap, HashSet};
7
8use super::types::{
9    ApproximateVerification, Assertion, Command, ConcurrentSeparationLogicExt, EffectSystem,
10    FractionalPerm, GhostHeap, Heap, HeapPred, HoareTriple, Namespace, NumericalDomain,
11    ProbabilisticHoareLogic, RelyCondition, RelyGuaranteeLogic, Transition, TypeAndEffect,
12    VerificationCondition, LTS,
13};
14
15pub fn app(f: Expr, a: Expr) -> Expr {
16    Expr::App(Box::new(f), Box::new(a))
17}
18pub fn app2(f: Expr, a: Expr, b: Expr) -> Expr {
19    app(app(f, a), b)
20}
21pub fn app3(f: Expr, a: Expr, b: Expr, c: Expr) -> Expr {
22    app(app2(f, a, b), c)
23}
24pub fn cst(s: &str) -> Expr {
25    Expr::Const(Name::str(s), vec![])
26}
27pub fn prop() -> Expr {
28    Expr::Sort(Level::zero())
29}
30pub fn type0() -> Expr {
31    Expr::Sort(Level::succ(Level::zero()))
32}
33pub fn pi(bi: BinderInfo, name: &str, dom: Expr, body: Expr) -> Expr {
34    Expr::Pi(bi, Name::str(name), Box::new(dom), Box::new(body))
35}
36pub fn arrow(a: Expr, b: Expr) -> Expr {
37    pi(BinderInfo::Default, "_", a, b)
38}
39pub fn bvar(n: u32) -> Expr {
40    Expr::BVar(n)
41}
42pub fn nat_ty() -> Expr {
43    cst("Nat")
44}
45pub fn bool_ty() -> Expr {
46    cst("Bool")
47}
48pub fn string_ty() -> Expr {
49    cst("String")
50}
51pub fn list_ty(elem: Expr) -> Expr {
52    app(cst("List"), elem)
53}
54pub fn option_ty(a: Expr) -> Expr {
55    app(cst("Option"), a)
56}
57/// Assertion: a predicate over program states.
58/// Type: State → Prop  (State is a type parameter)
59pub fn assertion_ty() -> Expr {
60    arrow(type0(), prop())
61}
62/// HoareTriple: {P} C {Q} — partial Hoare triple.
63/// Type: Prop → Program → Prop → Prop
64pub fn hoare_triple_ty() -> Expr {
65    arrow(prop(), arrow(type0(), arrow(prop(), prop())))
66}
67/// TotalHoareTriple: [P] C [Q] — total Hoare triple (guarantees termination).
68/// Type: Prop → Program → Prop → Prop
69pub fn total_hoare_triple_ty() -> Expr {
70    arrow(prop(), arrow(type0(), arrow(prop(), prop())))
71}
72/// SkipRule: {P} skip {P}.
73/// Type: {P : Prop} → HoareTriple P skip P
74pub fn skip_rule_ty() -> Expr {
75    pi(BinderInfo::Default, "P", prop(), prop())
76}
77/// AssignRule: {P[e/x]} x := e {P}.
78/// Type: Prop
79pub fn assign_rule_ty() -> Expr {
80    prop()
81}
82/// SeqRule: {P} C1 {R}, {R} C2 {Q} ⊢ {P} C1;C2 {Q}.
83/// Type: Prop → Prop → Prop → Prop
84pub fn seq_rule_ty() -> Expr {
85    arrow(prop(), arrow(prop(), arrow(prop(), prop())))
86}
87/// WhileRule: {I ∧ b} C {I} ⊢ {I} while b do C {I ∧ ¬b}.
88/// Type: Prop → Prop → Prop
89pub fn while_rule_ty() -> Expr {
90    arrow(prop(), arrow(prop(), prop()))
91}
92/// ConsequenceRule: P ⊢ P', {P'} C {Q'}, Q' ⊢ Q ⊢ {P} C {Q}.
93/// Type: Prop
94pub fn consequence_rule_ty() -> Expr {
95    prop()
96}
97/// VerificationCondition: a formula that must be checked to validate a Hoare proof.
98/// Type: Prop
99pub fn verification_condition_ty() -> Expr {
100    prop()
101}
102/// WP: weakest precondition transformer — wp(C, Q) is the weakest P such that {P} C {Q}.
103/// Type: Program → Prop → Prop
104pub fn wp_ty() -> Expr {
105    arrow(type0(), arrow(prop(), prop()))
106}
107/// WLP: weakest liberal precondition (partial correctness, may diverge).
108/// Type: Program → Prop → Prop
109pub fn wlp_ty() -> Expr {
110    arrow(type0(), arrow(prop(), prop()))
111}
112/// SP: strongest postcondition — sp(C, P) is the strongest Q such that {P} C {Q}.
113/// Type: Prop → Program → Prop
114pub fn sp_ty() -> Expr {
115    arrow(prop(), arrow(type0(), prop()))
116}
117/// WPSoundness: {wp(C,Q)} C {Q}.
118/// Type: {C : Program} → {Q : Prop} → HoareTriple (wp C Q) C Q
119pub fn wp_soundness_ty() -> Expr {
120    pi(
121        BinderInfo::Default,
122        "C",
123        type0(),
124        pi(BinderInfo::Default, "Q", prop(), prop()),
125    )
126}
127/// WPCompleteness: if {P} C {Q} then P ⊢ wp(C, Q).
128/// Type: {P Q : Prop} → {C : Program} → HoareTriple P C Q → Prop
129pub fn wp_completeness_ty() -> Expr {
130    pi(
131        BinderInfo::Default,
132        "P",
133        prop(),
134        pi(
135            BinderInfo::Default,
136            "Q",
137            prop(),
138            pi(BinderInfo::Default, "C", type0(), arrow(prop(), prop())),
139        ),
140    )
141}
142/// PredicateTransformer: a monotone endofunction on predicates.
143/// Type: (Prop → Prop)
144pub fn predicate_transformer_ty() -> Expr {
145    arrow(prop(), prop())
146}
147/// AngelicPT: angelic predicate transformer (may-semantics, liberal).
148/// Type: Program → Prop → Prop
149pub fn angelic_pt_ty() -> Expr {
150    arrow(type0(), arrow(prop(), prop()))
151}
152/// DemonicPT: demonic predicate transformer (must-semantics, conservative).
153/// Type: Program → Prop → Prop
154pub fn demonic_pt_ty() -> Expr {
155    arrow(type0(), arrow(prop(), prop()))
156}
157/// HeapPredicate: a predicate over heaps (including āˆ— and -āˆ— connectives).
158/// Type: Heap → Prop
159pub fn heap_predicate_ty() -> Expr {
160    arrow(type0(), prop())
161}
162/// SepStar: separating conjunction P āˆ— Q.
163/// Type: HeapPred → HeapPred → HeapPred
164pub fn sep_star_ty() -> Expr {
165    arrow(
166        arrow(type0(), prop()),
167        arrow(arrow(type0(), prop()), arrow(type0(), prop())),
168    )
169}
170/// SepWand: separating implication (magic wand) P -āˆ— Q.
171/// Type: HeapPred → HeapPred → HeapPred
172pub fn sep_wand_ty() -> Expr {
173    arrow(
174        arrow(type0(), prop()),
175        arrow(arrow(type0(), prop()), arrow(type0(), prop())),
176    )
177}
178/// PointsTo: l ↦ v — the heap contains exactly location l with value v.
179/// Type: Nat → Nat → HeapPred
180pub fn points_to_ty() -> Expr {
181    arrow(nat_ty(), arrow(nat_ty(), arrow(type0(), prop())))
182}
183/// EmpPredicate: the empty heap predicate emp.
184/// Type: HeapPred
185pub fn emp_predicate_ty() -> Expr {
186    arrow(type0(), prop())
187}
188/// FrameRule: {P} C {Q} ⊢ {P āˆ— R} C {Q āˆ— R} when mod(C) ∩ fv(R) = āˆ….
189/// Type: Prop → Prop → Prop → Prop
190pub fn frame_rule_ty() -> Expr {
191    arrow(prop(), arrow(prop(), arrow(prop(), prop())))
192}
193/// SepLogicTriple: a Hoare triple in separation logic.
194/// Type: HeapPred → Program → HeapPred → Prop
195pub fn sep_logic_triple_ty() -> Expr {
196    arrow(
197        arrow(type0(), prop()),
198        arrow(type0(), arrow(arrow(type0(), prop()), prop())),
199    )
200}
201/// BiAbduction: given P and Q, find A and B such that P āˆ— A ⊢ Q āˆ— B.
202/// Type: HeapPred → HeapPred → Option (HeapPred Ɨ HeapPred)
203pub fn bi_abduction_ty() -> Expr {
204    arrow(
205        arrow(type0(), prop()),
206        arrow(arrow(type0(), prop()), option_ty(type0())),
207    )
208}
209/// SpatiallyDisjoint: two heap predicates have disjoint footprints.
210/// Type: HeapPred → HeapPred → Prop
211pub fn spatially_disjoint_ty() -> Expr {
212    arrow(
213        arrow(type0(), prop()),
214        arrow(arrow(type0(), prop()), prop()),
215    )
216}
217/// ConcurrentTriple: {P} C {Q} for a concurrent program C.
218/// Type: HeapPred → ConcProgram → HeapPred → Prop
219pub fn concurrent_triple_ty() -> Expr {
220    arrow(
221        arrow(type0(), prop()),
222        arrow(type0(), arrow(arrow(type0(), prop()), prop())),
223    )
224}
225/// ParallelCompositionRule: {P1} C1 {Q1}, {P2} C2 {Q2} ⊢ {P1āˆ—P2} C1||C2 {Q1āˆ—Q2}.
226/// Type: Prop
227pub fn parallel_composition_rule_ty() -> Expr {
228    prop()
229}
230/// CriticalSectionRule: resource invariant + lock/unlock rule.
231/// Type: Prop → Prop → Prop
232pub fn critical_section_rule_ty() -> Expr {
233    arrow(prop(), arrow(prop(), prop()))
234}
235/// ThreadLocal: a predicate about the local state of a single thread.
236/// Type: (State → Prop)
237pub fn thread_local_ty() -> Expr {
238    arrow(type0(), prop())
239}
240/// SharedInvariant: a predicate protected by a lock or other synchronization mechanism.
241/// Type: (State → Prop) → Prop
242pub fn shared_invariant_ty() -> Expr {
243    arrow(arrow(type0(), prop()), prop())
244}
245/// OwnershipTransfer: transferring ownership of a resource between threads.
246/// Type: HeapPred → HeapPred → Prop
247pub fn ownership_transfer_ty() -> Expr {
248    arrow(
249        arrow(type0(), prop()),
250        arrow(arrow(type0(), prop()), prop()),
251    )
252}
253/// AtomicTriple: a logically atomic triple ⟨P⟩ C ⟨Q⟩.
254/// Type: Prop → Program → Prop → Prop
255pub fn atomic_triple_ty() -> Expr {
256    arrow(prop(), arrow(type0(), arrow(prop(), prop())))
257}
258/// RelyCondition: an action the environment may perform.
259/// Type: State → State → Prop
260pub fn rely_condition_ty() -> Expr {
261    arrow(type0(), arrow(type0(), prop()))
262}
263/// GuaranteeCondition: an action this thread promises not to violate.
264/// Type: State → State → Prop
265pub fn guarantee_condition_ty() -> Expr {
266    arrow(type0(), arrow(type0(), prop()))
267}
268/// RelyGuaranteeTriple: (R, G) ⊢ {P} C {Q}.
269/// Type: (State → State → Prop) → (State → State → Prop) → Prop → Program → Prop → Prop
270pub fn rely_guarantee_triple_ty() -> Expr {
271    arrow(
272        arrow(type0(), arrow(type0(), prop())),
273        arrow(
274            arrow(type0(), arrow(type0(), prop())),
275            arrow(prop(), arrow(type0(), arrow(prop(), prop()))),
276        ),
277    )
278}
279/// RelyGuaranteeParallel: composition rule for rely-guarantee.
280/// Type: Prop
281pub fn rely_guarantee_parallel_ty() -> Expr {
282    prop()
283}
284/// StabilityCondition: P is stable under R if R-steps preserve P.
285/// Type: (State → Prop) → (State → State → Prop) → Prop
286pub fn stability_condition_ty() -> Expr {
287    arrow(
288        arrow(type0(), prop()),
289        arrow(arrow(type0(), arrow(type0(), prop())), prop()),
290    )
291}
292/// RelyGuaranteeConsequence: consequence rule for R-G.
293/// Type: Prop
294pub fn rely_guarantee_consequence_ty() -> Expr {
295    prop()
296}
297/// IrisProp: a proposition in the Iris base logic (step-indexed).
298/// Type: Type
299pub fn iris_prop_ty() -> Expr {
300    type0()
301}
302/// IrisEntails: Iris entailment P ⊢ Q.
303/// Type: IrisProp → IrisProp → Prop
304pub fn iris_entails_ty() -> Expr {
305    arrow(type0(), arrow(type0(), prop()))
306}
307/// IrisSepStar: separating conjunction in Iris.
308/// Type: IrisProp → IrisProp → IrisProp
309pub fn iris_sep_star_ty() -> Expr {
310    arrow(type0(), arrow(type0(), type0()))
311}
312/// IrisWand: magic wand in Iris.
313/// Type: IrisProp → IrisProp → IrisProp
314pub fn iris_wand_ty() -> Expr {
315    arrow(type0(), arrow(type0(), type0()))
316}
317/// IrisLater: the later modality ā–·P.
318/// Type: IrisProp → IrisProp
319pub fn iris_later_ty() -> Expr {
320    arrow(type0(), type0())
321}
322/// IrisAlways: the always modality ā–”P (persistent propositions).
323/// Type: IrisProp → IrisProp
324pub fn iris_always_ty() -> Expr {
325    arrow(type0(), type0())
326}
327/// IrisExcl: exclusive ownership token Excl(v).
328/// Type: {V : Type} → V → IrisProp
329pub fn iris_excl_ty() -> Expr {
330    pi(BinderInfo::Default, "V", type0(), arrow(bvar(0), type0()))
331}
332/// IrisAgree: agreement resource: both owners agree on a value.
333/// Type: {V : Type} → V → IrisProp
334pub fn iris_agree_ty() -> Expr {
335    pi(BinderInfo::Default, "V", type0(), arrow(bvar(0), type0()))
336}
337/// IrisAuth: authoritative element in the auth camera.
338/// Type: {A : Type} → A → IrisProp
339pub fn iris_auth_ty() -> Expr {
340    pi(BinderInfo::Default, "A", type0(), arrow(bvar(0), type0()))
341}
342/// IrisFragment: fragment element in the auth camera.
343/// Type: {A : Type} → A → IrisProp
344pub fn iris_fragment_ty() -> Expr {
345    pi(BinderInfo::Default, "A", type0(), arrow(bvar(0), type0()))
346}
347/// ResourceAlgebra: a CMRA (Canonical Metric Resource Algebra) — unital, partial monoid
348/// with a validity predicate and core map.
349/// Type: Type → Prop
350pub fn resource_algebra_ty() -> Expr {
351    arrow(type0(), prop())
352}
353/// GhostState: logical (ghost) state tracked in the Iris ghost heap.
354/// Type: {A : Type} → ResourceAlgebra A → IrisProp
355pub fn ghost_state_ty() -> Expr {
356    pi(BinderInfo::Default, "A", type0(), arrow(prop(), type0()))
357}
358/// GhostUpdate: a ghost update modality |==> P (frame-preserving update).
359/// Type: IrisProp → IrisProp
360pub fn ghost_update_ty() -> Expr {
361    arrow(type0(), type0())
362}
363/// FramePreservingUpdate: a → b is frame-preserving if for all frames f valid (aāŠ—f)
364/// there exists b' with b āŠ— f' valid and b ≼ b'.
365/// Type: {A : Type} → A → A → Prop
366pub fn frame_preserving_update_ty() -> Expr {
367    pi(
368        BinderInfo::Default,
369        "A",
370        type0(),
371        arrow(bvar(0), arrow(bvar(1), prop())),
372    )
373}
374/// CMRA: a Camera (generalized RA used in Iris).
375/// Type: Type → Prop
376pub fn cmra_ty() -> Expr {
377    arrow(type0(), prop())
378}
379/// CMRAOp: the partial composition operation of a CMRA.
380/// Type: {A : Type} → A → A → Option A
381pub fn cmra_op_ty() -> Expr {
382    pi(
383        BinderInfo::Default,
384        "A",
385        type0(),
386        arrow(bvar(0), arrow(bvar(1), option_ty(bvar(2)))),
387    )
388}
389/// CMRAValid: validity predicate of a CMRA.
390/// Type: {A : Type} → A → Prop
391pub fn cmra_valid_ty() -> Expr {
392    pi(BinderInfo::Default, "A", type0(), arrow(bvar(0), prop()))
393}
394/// CMRACore: the core map γ : A → Option A (idempotent part).
395/// Type: {A : Type} → A → Option A
396pub fn cmra_core_ty() -> Expr {
397    pi(
398        BinderInfo::Default,
399        "A",
400        type0(),
401        arrow(bvar(0), option_ty(bvar(1))),
402    )
403}
404/// Invariant: a persistent heap predicate protected by an Iris invariant.
405/// Type: Namespace → IrisProp → IrisProp
406pub fn invariant_ty() -> Expr {
407    arrow(nat_ty(), arrow(type0(), type0()))
408}
409/// InvariantAlloc: allocate a new invariant.
410/// Type: {P : IrisProp} → P ⊢ |==> ∃ N, inv(N, P)
411pub fn invariant_alloc_ty() -> Expr {
412    pi(BinderInfo::Default, "P", type0(), prop())
413}
414/// InvariantOpen: open an invariant for one step.
415/// Type: {N : Namespace} → {P Q E : IrisProp} → inv(N,P) āˆ— (P -āˆ— ā–·P āˆ— Q) ⊢ Q
416pub fn invariant_open_ty() -> Expr {
417    pi(
418        BinderInfo::Default,
419        "N",
420        nat_ty(),
421        pi(
422            BinderInfo::Default,
423            "P",
424            type0(),
425            pi(BinderInfo::Default, "Q", type0(), prop()),
426        ),
427    )
428}
429/// NamespaceMask: the set of open invariants (mask E āŠ† Namespace).
430/// Type: Type
431pub fn namespace_mask_ty() -> Expr {
432    type0()
433}
434/// MaskSubset: mask inclusion E1 āŠ† E2.
435/// Type: NamespaceMask → NamespaceMask → Prop
436pub fn mask_subset_ty() -> Expr {
437    arrow(type0(), arrow(type0(), prop()))
438}
439/// FancyUpdate: fancy update modality |={E1,E2}=> P.
440/// Type: NamespaceMask → NamespaceMask → IrisProp → IrisProp
441pub fn fancy_update_ty() -> Expr {
442    arrow(type0(), arrow(type0(), arrow(type0(), type0())))
443}
444/// FractionalPermission: a fractional permission q ∈ (0, 1].
445/// Type: Type
446pub fn fractional_permission_ty() -> Expr {
447    type0()
448}
449/// FractionalPointsTo: l ↦{q} v — fractional ownership of location l.
450/// Type: Nat → Nat → FractionalPermission → HeapPred
451pub fn fractional_points_to_ty() -> Expr {
452    arrow(
453        nat_ty(),
454        arrow(nat_ty(), arrow(type0(), arrow(type0(), prop()))),
455    )
456}
457/// PermissionSplit: p = p1 + p2 justifies l↦{p}v ⊢ l↦{p1}v āˆ— l↦{p2}v.
458/// Type: Prop
459pub fn permission_split_ty() -> Expr {
460    prop()
461}
462/// PermissionCombine: l↦{p1}v āˆ— l↦{p2}v ⊢ l↦{p1+p2}v.
463/// Type: Prop
464pub fn permission_combine_ty() -> Expr {
465    prop()
466}
467/// CountingPermission: a counting-based permission (multiset of capabilities).
468/// Type: Type
469pub fn counting_permission_ty() -> Expr {
470    type0()
471}
472/// WritePermission: full (1) fractional permission, allows mutation.
473/// Type: FractionalPermission
474pub fn write_permission_ty() -> Expr {
475    type0()
476}
477/// ReadPermission: a fraction q < 1, read-only.
478/// Type: FractionalPermission
479pub fn read_permission_ty() -> Expr {
480    type0()
481}
482/// RankingFunction: a function from states to a well-founded set,
483/// decreasing on each loop iteration.
484/// Type: {S : Type} → (S → Nat) → Program → Prop
485pub fn ranking_function_ty() -> Expr {
486    pi(
487        BinderInfo::Default,
488        "S",
489        type0(),
490        arrow(arrow(bvar(0), nat_ty()), arrow(type0(), prop())),
491    )
492}
493/// TerminationProof: a proof that program C terminates from every state satisfying P.
494/// Type: Prop → Program → Prop
495pub fn termination_proof_ty() -> Expr {
496    arrow(prop(), arrow(type0(), prop()))
497}
498/// TotalCorrectnessRule: total correctness proof rule using a ranking function.
499/// Type: Prop
500pub fn total_correctness_rule_ty() -> Expr {
501    prop()
502}
503/// LoopVariant: the variant expression for a while loop (must decrease).
504/// Type: Type
505pub fn loop_variant_ty() -> Expr {
506    type0()
507}
508/// LoopInvariant: the invariant for a while loop.
509/// Type: (State → Prop)
510pub fn loop_invariant_ty() -> Expr {
511    arrow(type0(), prop())
512}
513/// WellFoundedOrder: a well-founded order — every non-empty set has a minimal element.
514/// Type: {A : Type} → (A → A → Prop) → Prop
515pub fn well_founded_order_ty() -> Expr {
516    pi(
517        BinderInfo::Default,
518        "A",
519        type0(),
520        arrow(arrow(bvar(0), arrow(bvar(1), prop())), prop()),
521    )
522}
523/// AbstractSpec: an abstract specification (set of allowed behaviors).
524/// Type: Type
525pub fn abstract_spec_ty() -> Expr {
526    type0()
527}
528/// ConcreteImpl: a concrete implementation.
529/// Type: Type
530pub fn concrete_impl_ty() -> Expr {
531    type0()
532}
533/// DataRefinement: a concrete implementation refines an abstract spec.
534/// Type: AbstractSpec → ConcreteImpl → Prop
535pub fn data_refinement_ty() -> Expr {
536    arrow(type0(), arrow(type0(), prop()))
537}
538/// SimulationRelation: a relation witnessing a simulation (forward simulation).
539/// Type: {A C : Type} → (A → C → Prop) → Prop
540pub fn simulation_relation_ty() -> Expr {
541    pi(
542        BinderInfo::Default,
543        "A",
544        type0(),
545        pi(
546            BinderInfo::Default,
547            "C",
548            type0(),
549            arrow(arrow(bvar(1), arrow(bvar(1), prop())), prop()),
550        ),
551    )
552}
553/// BackwardSimulation: a relation witnessing backward simulation.
554/// Type: {A C : Type} → (C → A → Prop) → Prop
555pub fn backward_simulation_ty() -> Expr {
556    pi(
557        BinderInfo::Default,
558        "A",
559        type0(),
560        pi(
561            BinderInfo::Default,
562            "C",
563            type0(),
564            arrow(arrow(bvar(1), arrow(bvar(2), prop())), prop()),
565        ),
566    )
567}
568/// RefinementMapping: a coupling function between abstract and concrete states.
569/// Type: {A C : Type} → (C → A) → Prop
570pub fn refinement_mapping_ty() -> Expr {
571    pi(
572        BinderInfo::Default,
573        "A",
574        type0(),
575        pi(
576            BinderInfo::Default,
577            "C",
578            type0(),
579            arrow(arrow(bvar(1), bvar(2)), prop()),
580        ),
581    )
582}
583/// AbadiLamport: Abadi-Lamport theorem: forward simulation ∧ backward simulation ⟹ refinement.
584/// Type: Prop
585pub fn abadi_lamport_ty() -> Expr {
586    prop()
587}
588/// Register all program logics axioms in the kernel environment.
589pub fn build_program_logics_env() -> Environment {
590    let mut env = Environment::new();
591    let axioms: &[(&str, Expr)] = &[
592        ("Assertion", assertion_ty()),
593        ("HoareTriple", hoare_triple_ty()),
594        ("TotalHoareTriple", total_hoare_triple_ty()),
595        ("SkipRule", skip_rule_ty()),
596        ("AssignRule", assign_rule_ty()),
597        ("SeqRule", seq_rule_ty()),
598        ("WhileRule", while_rule_ty()),
599        ("ConsequenceRule", consequence_rule_ty()),
600        ("VerificationCondition", verification_condition_ty()),
601        ("WP", wp_ty()),
602        ("WLP", wlp_ty()),
603        ("SP", sp_ty()),
604        ("WPSoundness", wp_soundness_ty()),
605        ("WPCompleteness", wp_completeness_ty()),
606        ("PredicateTransformer", predicate_transformer_ty()),
607        ("AngelicPT", angelic_pt_ty()),
608        ("DemonicPT", demonic_pt_ty()),
609        ("HeapPredicate", heap_predicate_ty()),
610        ("SepStar", sep_star_ty()),
611        ("SepWand", sep_wand_ty()),
612        ("PointsTo", points_to_ty()),
613        ("EmpPredicate", emp_predicate_ty()),
614        ("FrameRule", frame_rule_ty()),
615        ("SepLogicTriple", sep_logic_triple_ty()),
616        ("BiAbduction", bi_abduction_ty()),
617        ("SpatiallyDisjoint", spatially_disjoint_ty()),
618        ("ConcurrentTriple", concurrent_triple_ty()),
619        ("ParallelCompositionRule", parallel_composition_rule_ty()),
620        ("CriticalSectionRule", critical_section_rule_ty()),
621        ("ThreadLocal", thread_local_ty()),
622        ("SharedInvariant", shared_invariant_ty()),
623        ("OwnershipTransfer", ownership_transfer_ty()),
624        ("AtomicTriple", atomic_triple_ty()),
625        ("RelyCondition", rely_condition_ty()),
626        ("GuaranteeCondition", guarantee_condition_ty()),
627        ("RelyGuaranteeTriple", rely_guarantee_triple_ty()),
628        ("RelyGuaranteeParallel", rely_guarantee_parallel_ty()),
629        ("StabilityCondition", stability_condition_ty()),
630        ("RelyGuaranteeConsequence", rely_guarantee_consequence_ty()),
631        ("IrisProp", iris_prop_ty()),
632        ("IrisEntails", iris_entails_ty()),
633        ("IrisSepStar", iris_sep_star_ty()),
634        ("IrisWand", iris_wand_ty()),
635        ("IrisLater", iris_later_ty()),
636        ("IrisAlways", iris_always_ty()),
637        ("IrisExcl", iris_excl_ty()),
638        ("IrisAgree", iris_agree_ty()),
639        ("IrisAuth", iris_auth_ty()),
640        ("IrisFragment", iris_fragment_ty()),
641        ("ResourceAlgebra", resource_algebra_ty()),
642        ("GhostState", ghost_state_ty()),
643        ("GhostUpdate", ghost_update_ty()),
644        ("FramePreservingUpdate", frame_preserving_update_ty()),
645        ("CMRA", cmra_ty()),
646        ("CMRAOp", cmra_op_ty()),
647        ("CMRAValid", cmra_valid_ty()),
648        ("CMRACore", cmra_core_ty()),
649        ("Invariant", invariant_ty()),
650        ("InvariantAlloc", invariant_alloc_ty()),
651        ("InvariantOpen", invariant_open_ty()),
652        ("NamespaceMask", namespace_mask_ty()),
653        ("MaskSubset", mask_subset_ty()),
654        ("FancyUpdate", fancy_update_ty()),
655        ("FractionalPermission", fractional_permission_ty()),
656        ("FractionalPointsTo", fractional_points_to_ty()),
657        ("PermissionSplit", permission_split_ty()),
658        ("PermissionCombine", permission_combine_ty()),
659        ("CountingPermission", counting_permission_ty()),
660        ("WritePermission", write_permission_ty()),
661        ("ReadPermission", read_permission_ty()),
662        ("RankingFunction", ranking_function_ty()),
663        ("TerminationProof", termination_proof_ty()),
664        ("TotalCorrectnessRule", total_correctness_rule_ty()),
665        ("LoopVariant", loop_variant_ty()),
666        ("LoopInvariant", loop_invariant_ty()),
667        ("WellFoundedOrder", well_founded_order_ty()),
668        ("AbstractSpec", abstract_spec_ty()),
669        ("ConcreteImpl", concrete_impl_ty()),
670        ("DataRefinement", data_refinement_ty()),
671        ("SimulationRelation", simulation_relation_ty()),
672        ("BackwardSimulation", backward_simulation_ty()),
673        ("RefinementMapping", refinement_mapping_ty()),
674        ("AbadiLamport", abadi_lamport_ty()),
675    ];
676    for (name, ty) in axioms {
677        env.add(Declaration::Axiom {
678            name: Name::str(*name),
679            univ_params: vec![],
680            ty: ty.clone(),
681        })
682        .ok();
683    }
684    env
685}
686/// A guarantee condition: transitions this thread promises to only perform.
687pub type GuaranteeCondition<S> = RelyCondition<S>;
688/// Check stability: a predicate `P` (given as a set of states) is stable under rely `R`
689/// if for every transition (s → s') in R, s ∈ P → s' ∈ P.
690pub fn is_stable<S: Clone + Eq + std::hash::Hash>(
691    predicate: &HashSet<S>,
692    rely: &RelyCondition<S>,
693) -> bool {
694    rely.transitions.iter().all(|t| {
695        if predicate.contains(&t.before) {
696            predicate.contains(&t.after)
697        } else {
698            true
699        }
700    })
701}
702/// Check (simple) trace inclusion: every trace of `concrete` is a trace of `abstract_lts`.
703/// We check by seeing if the concrete LTS's reachable state-transitions are covered.
704pub fn trace_inclusion_holds<S>(concrete: &LTS<S>, abstract_lts: &LTS<S>) -> bool
705where
706    S: Clone + Eq + std::hash::Hash + std::fmt::Debug,
707{
708    let abstract_labels: HashSet<String> = abstract_lts
709        .transitions
710        .values()
711        .flat_map(|v| v.iter().map(|(l, _)| l.clone()))
712        .collect();
713    concrete.labels_subset_of(&abstract_labels)
714}
715/// Return a list of named Hoare logic proof rules.
716///
717/// ```
718/// use oxilean_std::program_logics::hoare_logic_rules;
719/// let rules = hoare_logic_rules();
720/// assert!(!rules.is_empty());
721/// assert!(rules.iter().any(|(name, _)| *name == "Skip"));
722/// ```
723pub fn hoare_logic_rules() -> Vec<(&'static str, &'static str)> {
724    vec![
725        ("Skip", "{P} skip {P}"), ("Assign", "{P[e/x]} x := e {P}"), ("Seq",
726        "{P} C1 {R}   {R} C2 {Q}\n──────────────────────\n{P} C1; C2 {Q}"),
727        ("If",
728        "{P ∧ b} C1 {Q}   {P ∧ ¬b} C2 {Q}\n──────────────────────────────────\n{P} if b then C1 else C2 {Q}"),
729        ("While",
730        "{I ∧ b} C {I}\n────────────────────────\n{I} while b do C {I ∧ ¬b}"),
731        ("Consequence",
732        "P ⊢ P'   {P'} C {Q'}   Q' ⊢ Q\n──────────────────────────\n{P} C {Q}"),
733        ("Frame",
734        "{P} C {Q}   mod(C) # fv(R) = āˆ…\n──────────────────────────\n{P āˆ— R} C {Q āˆ— R}"),
735        ("Parallel",
736        "{P1} C1 {Q1}   {P2} C2 {Q2}\n──────────────────────────────\n{P1 āˆ— P2} C1 ‖ C2 {Q1 āˆ— Q2}"),
737    ]
738}
739/// Return the weakest precondition calculus rules as strings.
740///
741/// ```
742/// use oxilean_std::program_logics::wp_rules;
743/// let rules = wp_rules();
744/// assert!(rules.iter().any(|(name, _)| *name == "WP-Skip"));
745/// ```
746pub fn wp_rules() -> Vec<(&'static str, &'static str)> {
747    vec![
748        ("WP-Skip", "wp(skip, Q) = Q"),
749        ("WP-Assign", "wp(x := e, Q) = Q[e/x]"),
750        ("WP-Seq", "wp(C1; C2, Q) = wp(C1, wp(C2, Q))"),
751        (
752            "WP-If",
753            "wp(if b then C1 else C2, Q) = (b → wp(C1,Q)) ∧ (¬b → wp(C2,Q))",
754        ),
755        (
756            "WP-While",
757            "wp(while b do C, Q) = lfp(Ī»X. (¬b → Q) ∧ (b → wp(C, X)))",
758        ),
759        ("WP-Sound", "{wp(C,Q)} C {Q}"),
760        ("WP-Complete", "{P} C {Q} ⊢ P → wp(C,Q)"),
761    ]
762}
763/// Return the Iris proof rules for invariant access.
764///
765/// ```
766/// use oxilean_std::program_logics::iris_invariant_rules;
767/// let rules = iris_invariant_rules();
768/// assert!(!rules.is_empty());
769/// ```
770pub fn iris_invariant_rules() -> Vec<(&'static str, &'static str)> {
771    vec![
772        ("Inv-Alloc", "ā–·P ⊢ |={E}=> ∃ N āˆ‰ E, inv(N, P)"),
773        (
774            "Inv-Open",
775            "inv(N, P) āˆ— (ā–·P -āˆ— |={E}=> ā–·P āˆ— Q) ⊢ |={E∪{N},E}=> Q",
776        ),
777        ("Inv-Pers", "ā–” inv(N, P)"),
778        ("GhostAlloc", "⊢ |==> ∃ γ, own(γ, a)"),
779        ("GhostUpdate", "own(γ, a) ⊢ |==> own(γ, b)   (when a ~~> b)"),
780        ("Frame-Iris", "E āŠ† E' → |={E}=> P ⊢ |={E'}=> P"),
781    ]
782}
783#[cfg(test)]
784mod tests {
785    use super::*;
786    #[test]
787    fn test_build_program_logics_env() {
788        let env = build_program_logics_env();
789        assert!(env.get(&Name::str("HoareTriple")).is_some());
790        assert!(env.get(&Name::str("WP")).is_some());
791        assert!(env.get(&Name::str("FrameRule")).is_some());
792        assert!(env.get(&Name::str("IrisProp")).is_some());
793        assert!(env.get(&Name::str("CMRA")).is_some());
794        assert!(env.get(&Name::str("Invariant")).is_some());
795        assert!(env.get(&Name::str("FractionalPermission")).is_some());
796        assert!(env.get(&Name::str("DataRefinement")).is_some());
797    }
798    #[test]
799    fn test_assertion_operations() {
800        let p = Assertion::new("x > 0");
801        let q = Assertion::new("y < 10");
802        let pq = p.and(&q);
803        assert!(pq.formula.contains("x > 0"));
804        assert!(pq.formula.contains("y < 10"));
805        let neg = p.negate();
806        assert!(neg.formula.contains("¬"));
807        let s = p.subst("x", "x + 1");
808        assert_eq!(s.formula, "x + 1 > 0");
809    }
810    #[test]
811    fn test_wp_skip() {
812        let c = Command::Skip;
813        let q = Assertion::new("x >= 0");
814        let wp = c.wp(&q);
815        assert_eq!(wp.formula, "x >= 0");
816    }
817    #[test]
818    fn test_wp_assign() {
819        let c = Command::Assign("x".to_string(), "x + 1".to_string());
820        let q = Assertion::new("x > 5");
821        let wp = c.wp(&q);
822        assert_eq!(wp.formula, "x + 1 > 5");
823    }
824    #[test]
825    fn test_wp_seq() {
826        let c = Command::Seq(
827            Box::new(Command::Assign("x".to_string(), "x + 1".to_string())),
828            Box::new(Command::Skip),
829        );
830        let q = Assertion::new("x > 5");
831        let wp = c.wp(&q);
832        assert_eq!(wp.formula, "x + 1 > 5");
833    }
834    #[test]
835    fn test_heap_disjoint_union() {
836        let mut h1 = Heap::empty();
837        h1.write(0, 42);
838        let mut h2 = Heap::empty();
839        h2.write(1, 99);
840        assert!(h1.is_disjoint(&h2));
841        let h3 = h1.disjoint_union(&h2);
842        assert_eq!(h3.size(), 2);
843        assert_eq!(h3.read(0), Some(42));
844        assert_eq!(h3.read(1), Some(99));
845    }
846    #[test]
847    fn test_fractional_permissions() {
848        let wp = FractionalPerm::write();
849        assert!(wp.is_write());
850        let (h1, h2) = wp.split_half();
851        assert!(!h1.is_write());
852        assert!(!h2.is_write());
853        let combined = h1.combine(&h2).expect("combine should succeed");
854        assert!(combined.is_write());
855        assert!(combined.combine(&h1).is_none());
856    }
857    #[test]
858    fn test_ghost_heap() {
859        let mut gh: GhostHeap<u64> = GhostHeap::empty();
860        gh.alloc("counter", 0u64);
861        assert_eq!(gh.read("counter"), Some(&0u64));
862        let ok = gh.update("counter", 42u64);
863        assert!(ok);
864        assert_eq!(gh.read("counter"), Some(&42u64));
865    }
866    #[test]
867    fn test_stability() {
868        use std::collections::HashSet;
869        let mut pred: HashSet<u32> = HashSet::new();
870        pred.insert(1);
871        pred.insert(2);
872        let mut rely: RelyCondition<u32> = RelyCondition::empty();
873        rely.add(Transition::new(1u32, 2u32));
874        assert!(is_stable(&pred, &rely));
875        rely.add(Transition::new(2u32, 3u32));
876        assert!(!is_stable(&pred, &rely));
877    }
878    #[test]
879    fn test_hoare_logic_rules() {
880        let rules = hoare_logic_rules();
881        assert!(!rules.is_empty());
882        assert!(rules.iter().any(|(n, _)| *n == "Frame"));
883        assert!(rules.iter().any(|(n, _)| *n == "While"));
884    }
885}
886/// Build a kernel environment with all program-logics axioms.
887/// (Alias for `build_program_logics_env` returning a `Result`.)
888pub fn build_env() -> Result<Environment, String> {
889    Ok(build_program_logics_env())
890}
891#[cfg(test)]
892mod tests_proglogics_ext {
893    use super::*;
894    use std::fmt;
895    #[test]
896    fn test_concurrent_separation_logic() {
897        let iris = ConcurrentSeparationLogicExt::iris();
898        assert!(iris.fractional_permissions);
899        assert!(iris.supports_rely_guarantee);
900        let triple = iris.concurrent_triple("emp", "x := 0", "x = 0");
901        assert!(triple.contains("emp"));
902        assert!(iris.race_condition_freedom());
903    }
904    #[test]
905    fn test_rely_guarantee() {
906        let rg = RelyGuaranteeLogic::new("y=0", "x≄0", "x=0", "x≄0");
907        let triple = rg.rg_triple("x := x + 1");
908        assert!(triple.contains("R:"));
909        let stab = rg.stability_check();
910        assert!(stab.contains("stable"));
911    }
912    #[test]
913    fn test_effect_system() {
914        let ae = EffectSystem::algebraic_effects();
915        assert!(ae.is_algebraic);
916        assert!(!ae.monad_based);
917        let desc = ae.effect_handling_description();
918        assert!(desc.contains("algebraically"));
919        let free = ae.free_monad_presentation();
920        assert!(free.contains("IO"));
921    }
922    #[test]
923    fn test_type_and_effect() {
924        let pure_te = TypeAndEffect::pure_type("Int");
925        assert!(pure_te.is_pure());
926        let judge = pure_te.type_and_effect_judgment();
927        assert!(judge.contains("āˆ…"));
928        let eff = TypeAndEffect::effectful("Unit", vec!["IO".to_string()]);
929        assert!(!eff.is_pure());
930    }
931    #[test]
932    fn test_probabilistic_hoare_logic() {
933        let phl = ProbabilisticHoareLogic::phl("μ_init", "flip", "p(heads)=0.5");
934        let wpt = phl.expectation_transformer();
935        assert!(wpt.contains("wp(flip"));
936        let mm = phl.mciver_morgan_rule();
937        assert!(mm.contains("McIver-Morgan"));
938    }
939    #[test]
940    fn test_approximate_verification() {
941        let av = ApproximateVerification::pac_verification(0.01, 0.05, "safety");
942        assert!((av.confidence - 0.95).abs() < 1e-10);
943        let samples = av.sample_complexity();
944        assert!(samples > 0);
945        let stmt = av.soundness_statement();
946        assert!(stmt.contains("safety"));
947    }
948    #[test]
949    fn test_numerical_domain() {
950        let intervals = NumericalDomain::intervals();
951        assert!(!intervals.is_relational);
952        let cost = intervals.precision_cost_tradeoff();
953        assert!(cost.contains("O(n)"));
954        let oct = NumericalDomain::octagons();
955        assert!(oct.is_relational);
956        assert!(oct.is_more_precise_than_intervals());
957        let poly = NumericalDomain::polyhedra();
958        assert!(poly.is_relational);
959    }
960}