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