Skip to main content

oxilean_std/abstract_interpretation/
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};
6
7use super::types::{
8    AbstractState, AbstractTransformer, AbstractionFunction, ArrayBoundsAnalysis,
9    AssumeGuaranteeContract, Bound, ConcretizationFunction, DataflowAnalysis, DelayedWidening,
10    FixpointComputation, GaloisConnection, IntervalDomain, IntervalWidening, LoopBound,
11    NullPointerAnalysis, OctagonDomain, ParityDomain, PolyhedralDomain,
12    ProbabilisticAbstractDomain, ReachabilityAnalysis, SignDomain, TaintAnalysis,
13    TemplatePolyhedronDomain, ZonotopeDomain,
14};
15
16pub fn app(f: Expr, a: Expr) -> Expr {
17    Expr::App(Box::new(f), Box::new(a))
18}
19pub fn app2(f: Expr, a: Expr, b: Expr) -> Expr {
20    app(app(f, a), b)
21}
22pub fn app3(f: Expr, a: Expr, b: Expr, c: Expr) -> Expr {
23    app(app2(f, a, b), c)
24}
25pub fn cst(s: &str) -> Expr {
26    Expr::Const(Name::str(s), vec![])
27}
28pub fn prop() -> Expr {
29    Expr::Sort(Level::zero())
30}
31pub fn type0() -> Expr {
32    Expr::Sort(Level::succ(Level::zero()))
33}
34pub fn pi(bi: BinderInfo, name: &str, dom: Expr, body: Expr) -> Expr {
35    Expr::Pi(bi, Name::str(name), Box::new(dom), Box::new(body))
36}
37pub fn arrow(a: Expr, b: Expr) -> Expr {
38    pi(BinderInfo::Default, "_", a, b)
39}
40pub fn impl_pi(name: &str, dom: Expr, body: Expr) -> Expr {
41    pi(BinderInfo::Implicit, name, dom, body)
42}
43pub fn bvar(n: u32) -> Expr {
44    Expr::BVar(n)
45}
46pub fn nat_ty() -> Expr {
47    cst("Nat")
48}
49pub fn bool_ty() -> Expr {
50    cst("Bool")
51}
52/// `AbstractDomain : Type โ†’ Type`
53///
54/// An abstract domain for type A: a lattice structure (โŠฅ, โŠค, โŠ‘, โŠ”, โŠ“)
55/// equipped with widening โ–ฝ and narrowing โ–ณ operators.
56pub fn abstract_domain_ty() -> Expr {
57    impl_pi("A", type0(), type0())
58}
59/// `AbstractLattice : โˆ€ (A : Type), AbstractDomain A โ†’ Prop`
60///
61/// Proof that an abstract domain forms a complete lattice.
62pub fn abstract_lattice_ty() -> Expr {
63    impl_pi(
64        "A",
65        type0(),
66        arrow(app(cst("AbstractDomain"), bvar(0)), prop()),
67    )
68}
69/// `IntervalDomain : Type`
70///
71/// The interval domain: elements are pairs [l, u] where l, u โˆˆ โ„คโˆช{-โˆž,+โˆž}.
72/// Provides a sound over-approximation of sets of integers.
73pub fn interval_domain_ty() -> Expr {
74    type0()
75}
76/// `OctagonDomain : Nat โ†’ Type`
77///
78/// The octagon domain for n variables: constraints of the form ยฑxi ยฑ xj โ‰ค c.
79/// A weakly relational domain that is more precise than intervals.
80pub fn octagon_domain_ty() -> Expr {
81    arrow(nat_ty(), type0())
82}
83/// `PolyhedralDomain : Nat โ†’ Type`
84///
85/// The polyhedral domain for n variables: linear constraints Ax โ‰ค b.
86/// Exact but computationally expensive (exponential in general).
87pub fn polyhedral_domain_ty() -> Expr {
88    arrow(nat_ty(), type0())
89}
90/// `SignDomain : Type`
91///
92/// The sign domain: abstract values are Bottom, Neg, Zero, Pos, NonNeg, NonPos, Top.
93pub fn sign_domain_ty() -> Expr {
94    type0()
95}
96/// `ParityDomain : Type`
97///
98/// The parity domain: abstract values are Bottom, Even, Odd, Top.
99pub fn parity_domain_ty() -> Expr {
100    type0()
101}
102/// `AbstractJoin : โˆ€ (A : Type), A โ†’ A โ†’ A`
103///
104/// The join (least upper bound โŠ”) of two abstract values.
105pub fn abstract_join_ty() -> Expr {
106    impl_pi("A", type0(), arrow(bvar(0), arrow(bvar(1), bvar(2))))
107}
108/// `AbstractMeet : โˆ€ (A : Type), A โ†’ A โ†’ A`
109///
110/// The meet (greatest lower bound โŠ“) of two abstract values.
111pub fn abstract_meet_ty() -> Expr {
112    impl_pi("A", type0(), arrow(bvar(0), arrow(bvar(1), bvar(2))))
113}
114/// `AbstractWiden : โˆ€ (A : Type), A โ†’ A โ†’ A`
115///
116/// The widening operator โ–ฝ: a โ–ฝ b extrapolates to ensure convergence.
117/// Satisfies: a โŠ‘ a โ–ฝ b and b โŠ‘ a โ–ฝ b (over-approximation).
118pub fn abstract_widen_ty() -> Expr {
119    impl_pi("A", type0(), arrow(bvar(0), arrow(bvar(1), bvar(2))))
120}
121/// `AbstractNarrow : โˆ€ (A : Type), A โ†’ A โ†’ A`
122///
123/// The narrowing operator โ–ณ: a โ–ณ b refines a using constraints from b.
124/// Satisfies: a โ–ณ b โŠ‘ a (monotone refinement).
125pub fn abstract_narrow_ty() -> Expr {
126    impl_pi("A", type0(), arrow(bvar(0), arrow(bvar(1), bvar(2))))
127}
128/// `AbstractState : Type`
129///
130/// An abstract state: a map from variable names to abstract values.
131/// Represents a set of concrete program states.
132pub fn abstract_state_ty() -> Expr {
133    type0()
134}
135/// `AbstractTransformer : AbstractState โ†’ AbstractState`
136///
137/// The abstract transformer [stmt]^#: maps pre-states to post-states.
138/// Must be a sound over-approximation of the concrete transformer.
139pub fn abstract_transformer_ty() -> Expr {
140    arrow(cst("AbstractState"), cst("AbstractState"))
141}
142/// `TransferFunction : Type`
143///
144/// The abstract semantics of a statement: assigns/conditions map to
145/// abstract transformers. Composes to give semantics of programs.
146pub fn transfer_function_ty() -> Expr {
147    type0()
148}
149/// `JoinSemilattice : AbstractState โ†’ AbstractState โ†’ AbstractState`
150///
151/// Combines two abstract states from different control-flow paths via โŠ”.
152/// Used at join points in the CFG.
153pub fn join_semilattice_ty() -> Expr {
154    arrow(
155        cst("AbstractState"),
156        arrow(cst("AbstractState"), cst("AbstractState")),
157    )
158}
159/// `FixpointComputation : TransferFunction โ†’ AbstractState โ†’ AbstractState`
160///
161/// Computes lfp([[while P: C]]^#) via Kleene iteration with widening.
162/// Terminates because widening accelerates convergence.
163pub fn fixpoint_computation_ty() -> Expr {
164    arrow(
165        cst("TransferFunction"),
166        arrow(cst("AbstractState"), cst("AbstractState")),
167    )
168}
169/// `SoundnessCondition : AbstractTransformer โ†’ Prop`
170///
171/// Soundness: ฮณ(F^#(a)) โЇ F(ฮณ(a)) for all abstract values a.
172pub fn soundness_condition_ty() -> Expr {
173    arrow(cst("AbstractTransformer"), prop())
174}
175/// `GaloisConnection : โˆ€ (C A : Type), (C โ†’ A) โ†’ (A โ†’ C) โ†’ Prop`
176///
177/// A Galois connection (ฮฑ, ฮณ): โ„˜(C) โ‡Œ A with
178/// ฮฑ(S) โŠ‘ a โ†” S โІ ฮณ(a) (adjunction condition).
179pub fn galois_connection_ty() -> Expr {
180    impl_pi(
181        "C",
182        type0(),
183        impl_pi(
184            "A",
185            type0(),
186            arrow(
187                arrow(bvar(1), bvar(1)),
188                arrow(arrow(bvar(2), bvar(2)), prop()),
189            ),
190        ),
191    )
192}
193/// `AbstractionFunction : โˆ€ (C A : Type), List C โ†’ A`
194///
195/// ฮฑ(S) = smallest abstract value containing all elements of S.
196/// The abstraction function is the left adjoint.
197pub fn abstraction_function_ty() -> Expr {
198    impl_pi(
199        "C",
200        type0(),
201        impl_pi("A", type0(), arrow(app(cst("List"), bvar(1)), bvar(1))),
202    )
203}
204/// `ConcretizationFunction : โˆ€ (C A : Type), A โ†’ List C`
205///
206/// ฮณ(a) = set of all concrete values a represents.
207/// The concretization function is the right adjoint.
208pub fn concretization_function_ty() -> Expr {
209    impl_pi(
210        "C",
211        type0(),
212        impl_pi("A", type0(), arrow(bvar(0), app(cst("List"), bvar(2)))),
213    )
214}
215/// `OptimalAbstraction : โˆ€ (C A : Type), List C โ†’ A`
216///
217/// ฮฑ(S) = โŠ“{a : S โІ ฮณ(a)} = the best (most precise) abstract value for S.
218/// Exists when A has all meets and ฮณ preserves them.
219pub fn optimal_abstraction_ty() -> Expr {
220    impl_pi(
221        "C",
222        type0(),
223        impl_pi("A", type0(), arrow(app(cst("List"), bvar(1)), bvar(1))),
224    )
225}
226/// `GaloisInsertion : โˆ€ (C A : Type), GaloisConnection C A โ†’ Prop`
227///
228/// A Galois insertion: additionally satisfies ฮฑ(ฮณ(a)) = a (surjectivity of ฮฑ).
229pub fn galois_insertion_ty() -> Expr {
230    impl_pi(
231        "C",
232        type0(),
233        impl_pi(
234            "A",
235            type0(),
236            arrow(app2(cst("GaloisConnection"), bvar(1), bvar(0)), prop()),
237        ),
238    )
239}
240/// `DataflowAnalysis : Type`
241///
242/// Forward or backward dataflow analysis: associates abstract values to
243/// program points satisfying the dataflow equations.
244pub fn dataflow_analysis_ty() -> Expr {
245    type0()
246}
247/// `ReachabilityAnalysis : Type โ†’ Prop`
248///
249/// Which states are reachable from the initial state?
250/// Computes the set of reachable abstract states via forward analysis.
251pub fn reachability_analysis_ty() -> Expr {
252    arrow(type0(), prop())
253}
254/// `NullPointerAnalysis : Type`
255///
256/// May/must null pointer analysis: tracks whether pointers may be null,
257/// must be null, or are definitely non-null at each program point.
258pub fn null_pointer_analysis_ty() -> Expr {
259    type0()
260}
261/// `ArrayBoundsAnalysis : Type`
262///
263/// Interval analysis for array indices: proves array accesses are within bounds.
264/// Combines the interval domain with loop invariant generation.
265pub fn array_bounds_analysis_ty() -> Expr {
266    type0()
267}
268/// `TaintAnalysis : Type`
269///
270/// Track information flow from sources (user input) to sinks (security-critical ops).
271/// A non-relational analysis using a two-element lattice {clean, tainted}.
272pub fn taint_analysis_ty() -> Expr {
273    type0()
274}
275/// `LiveVariableAnalysis : Type`
276///
277/// Backward analysis: a variable is live at a point if its value may be used later.
278/// Used for dead code elimination and register allocation.
279pub fn live_variable_analysis_ty() -> Expr {
280    type0()
281}
282/// `AvailableExprAnalysis : Type`
283///
284/// Forward analysis: an expression is available if it has been computed and
285/// its operands have not changed since. Used for common subexpression elimination.
286pub fn available_expr_analysis_ty() -> Expr {
287    type0()
288}
289/// `IntervalWidening : IntervalDomain โ†’ IntervalDomain โ†’ IntervalDomain`
290///
291/// Standard interval widening: if lower bound decreased, jump to -โˆž;
292/// if upper bound increased, jump to +โˆž. Ensures termination.
293pub fn interval_widening_ty() -> Expr {
294    arrow(
295        cst("IntervalDomain"),
296        arrow(cst("IntervalDomain"), cst("IntervalDomain")),
297    )
298}
299/// `ConvexHullWidening : PolyhedralDomain โ†’ PolyhedralDomain โ†’ PolyhedralDomain`
300///
301/// Polyhedral widening via convex hull followed by constraint removal.
302/// Keeps only constraints that held in both input polyhedra.
303pub fn convex_hull_widening_ty() -> Expr {
304    arrow(
305        app(cst("PolyhedralDomain"), nat_ty()),
306        arrow(
307            app(cst("PolyhedralDomain"), nat_ty()),
308            app(cst("PolyhedralDomain"), nat_ty()),
309        ),
310    )
311}
312/// `DelayedWidening : Nat โ†’ AbstractState โ†’ AbstractState โ†’ AbstractState`
313///
314/// Apply widening only after k fixpoint iterations, then switch to widening.
315/// Improves precision for loops with small iteration counts.
316pub fn delayed_widening_ty() -> Expr {
317    arrow(
318        nat_ty(),
319        arrow(
320            cst("AbstractState"),
321            arrow(cst("AbstractState"), cst("AbstractState")),
322        ),
323    )
324}
325/// `LoopBound : AbstractState โ†’ Nat`
326///
327/// Estimated upper bound on loop iteration count, derived from the abstract state.
328/// Used to decide when to apply widening in DelayedWidening.
329pub fn loop_bound_ty() -> Expr {
330    arrow(cst("AbstractState"), nat_ty())
331}
332/// Register all abstract interpretation axioms into the given environment.
333pub fn build_env(env: &mut Environment) {
334    let axioms: &[(&str, Expr)] = &[
335        ("AbstractDomain", abstract_domain_ty()),
336        ("AbstractLattice", abstract_lattice_ty()),
337        ("IntervalDomain", interval_domain_ty()),
338        ("OctagonDomain", octagon_domain_ty()),
339        ("PolyhedralDomain", polyhedral_domain_ty()),
340        ("SignDomain", sign_domain_ty()),
341        ("ParityDomain", parity_domain_ty()),
342        ("AbstractJoin", abstract_join_ty()),
343        ("AbstractMeet", abstract_meet_ty()),
344        ("AbstractWiden", abstract_widen_ty()),
345        ("AbstractNarrow", abstract_narrow_ty()),
346        ("AbstractState", abstract_state_ty()),
347        ("AbstractTransformer", abstract_transformer_ty()),
348        ("TransferFunction", transfer_function_ty()),
349        ("JoinSemilattice", join_semilattice_ty()),
350        ("FixpointComputation", fixpoint_computation_ty()),
351        ("SoundnessCondition", soundness_condition_ty()),
352        ("GaloisConnection", galois_connection_ty()),
353        ("AbstractionFunction", abstraction_function_ty()),
354        ("ConcretizationFunction", concretization_function_ty()),
355        ("OptimalAbstraction", optimal_abstraction_ty()),
356        ("GaloisInsertion", galois_insertion_ty()),
357        ("DataflowAnalysis", dataflow_analysis_ty()),
358        ("ReachabilityAnalysis", reachability_analysis_ty()),
359        ("NullPointerAnalysis", null_pointer_analysis_ty()),
360        ("ArrayBoundsAnalysis", array_bounds_analysis_ty()),
361        ("TaintAnalysis", taint_analysis_ty()),
362        ("LiveVariableAnalysis", live_variable_analysis_ty()),
363        ("AvailableExprAnalysis", available_expr_analysis_ty()),
364        ("IntervalWidening", interval_widening_ty()),
365        ("ConvexHullWidening", convex_hull_widening_ty()),
366        ("DelayedWidening", delayed_widening_ty()),
367        ("LoopBound", loop_bound_ty()),
368    ];
369    for (name, ty) in axioms {
370        env.add(Declaration::Axiom {
371            name: Name::str(*name),
372            univ_params: vec![],
373            ty: ty.clone(),
374        })
375        .ok();
376    }
377}
378/// `EllipsoidDomain : Nat โ†’ Type`
379///
380/// Ellipsoidal abstract domain for n variables: x^T P x โ‰ค 1 (P positive definite).
381/// Used in control verification and Lyapunov-based analysis.
382pub fn ellipsoid_domain_ty() -> Expr {
383    arrow(nat_ty(), type0())
384}
385/// `ZonotopeDomain : Nat โ†’ Nat โ†’ Type`
386///
387/// Zonotope domain with n dimensions and m generators: x = c + ฮฃ ฮต_i g_i, |ฮต_i| โ‰ค 1.
388/// Closed under linear maps, used in Taylor model arithmetic and reachability.
389pub fn zonotope_domain_ty() -> Expr {
390    arrow(nat_ty(), arrow(nat_ty(), type0()))
391}
392/// `TemplatePolyhedronDomain : Nat โ†’ Nat โ†’ Type`
393///
394/// Template polyhedron domain: cx โ‰ค d for a fixed template matrix C.
395/// Balances precision and efficiency by fixing constraint directions.
396pub fn template_polyhedron_domain_ty() -> Expr {
397    arrow(nat_ty(), arrow(nat_ty(), type0()))
398}
399/// `ReducedProductDomain : โˆ€ (A B : Type), A โ†’ B โ†’ Type`
400///
401/// Reduced product of two abstract domains: pairs (a, b) with reduction
402/// operator to improve precision via information exchange.
403pub fn reduced_product_domain_ty() -> Expr {
404    impl_pi(
405        "A",
406        type0(),
407        impl_pi("B", type0(), arrow(bvar(1), arrow(bvar(1), type0()))),
408    )
409}
410/// `SmashingDomain : โˆ€ (A : Type), AbstractDomain A โ†’ Type`
411///
412/// Smashing (direct) product: collapse all abstract values into a single
413/// abstract element. Used when domain precision exceeds analysis needs.
414pub fn smashing_domain_ty() -> Expr {
415    impl_pi(
416        "A",
417        type0(),
418        arrow(app(cst("AbstractDomain"), bvar(0)), type0()),
419    )
420}
421/// `PowersetLiftingDomain : โˆ€ (A : Type), AbstractDomain A โ†’ Type`
422///
423/// Powerset lifting: abstract values are finite sets of base-domain elements.
424/// Exponential cost but can express disjunctive information.
425pub fn powerset_lifting_domain_ty() -> Expr {
426    impl_pi(
427        "A",
428        type0(),
429        arrow(app(cst("AbstractDomain"), bvar(0)), type0()),
430    )
431}
432/// `TraceAbstraction : Type โ†’ Type`
433///
434/// Abstraction of execution traces: maps concrete trace sets to abstract traces.
435/// Underpins hyperproperties and relational verification.
436pub fn trace_abstraction_ty() -> Expr {
437    impl_pi("A", type0(), type0())
438}
439/// `AbstractTrace : Type`
440///
441/// An abstract execution trace: sequence of abstract states over time.
442/// Used in temporal abstract interpretation and model checking.
443pub fn abstract_trace_ty() -> Expr {
444    type0()
445}
446/// `TraceSemanticsMonotone : AbstractTrace โ†’ AbstractTrace โ†’ Prop`
447///
448/// Monotonicity of abstract trace transformers: longer traces refine shorter.
449pub fn trace_semantics_monotone_ty() -> Expr {
450    arrow(cst("AbstractTrace"), arrow(cst("AbstractTrace"), prop()))
451}
452/// `ThreadModularAnalysis : Nat โ†’ AbstractState โ†’ AbstractState`
453///
454/// Thread-modular abstract interpretation: analyze each thread independently
455/// with an interference abstraction summarizing effects of other threads.
456pub fn thread_modular_analysis_ty() -> Expr {
457    arrow(nat_ty(), arrow(cst("AbstractState"), cst("AbstractState")))
458}
459/// `InterferenceAbstraction : AbstractState โ†’ AbstractState โ†’ AbstractState`
460///
461/// Abstract interference from concurrent threads: over-approximate writes
462/// by other threads to establish sound sequential reasoning per thread.
463pub fn interference_abstraction_ty() -> Expr {
464    arrow(
465        cst("AbstractState"),
466        arrow(cst("AbstractState"), cst("AbstractState")),
467    )
468}
469/// `PartialOrderReductionAbs : AbstractState โ†’ AbstractState`
470///
471/// Partial-order reduction in abstract interpretation: prune redundant
472/// interleavings while preserving abstract reachability.
473pub fn partial_order_reduction_abs_ty() -> Expr {
474    arrow(cst("AbstractState"), cst("AbstractState"))
475}
476/// `LocksetAnalysis : Type`
477///
478/// Lockset-based data race detection: tracks which locks protect each
479/// memory location across concurrent threads.
480pub fn lockset_analysis_ty() -> Expr {
481    type0()
482}
483/// `WideningOperator : โˆ€ (A : Type), AbstractDomain A โ†’ A โ†’ A โ†’ A`
484///
485/// Generic widening operator: given a domain, produces the widened element.
486/// Must satisfy: a โŠ‘ a โ–ฝ b and b โŠ‘ a โ–ฝ b.
487pub fn widening_operator_ty() -> Expr {
488    impl_pi(
489        "A",
490        type0(),
491        arrow(
492            app(cst("AbstractDomain"), bvar(0)),
493            arrow(bvar(1), arrow(bvar(2), bvar(3))),
494        ),
495    )
496}
497/// `NarrowingOperator : โˆ€ (A : Type), AbstractDomain A โ†’ A โ†’ A โ†’ A`
498///
499/// Generic narrowing operator: a โ–ณ b โŠ‘ a (refinement below a).
500/// Used after fixpoint to improve precision without losing soundness.
501pub fn narrowing_operator_ty() -> Expr {
502    impl_pi(
503        "A",
504        type0(),
505        arrow(
506            app(cst("AbstractDomain"), bvar(0)),
507            arrow(bvar(1), arrow(bvar(2), bvar(3))),
508        ),
509    )
510}
511/// `ExtrapolationLemma : โˆ€ (A : Type), WideningOperator A โ†’ Prop`
512///
513/// Termination guarantee for Kleene iteration with widening:
514/// every ascending chain aโ‚€ โŠ‘ aโ‚ โŠ‘ ... stabilizes under โ–ฝ.
515pub fn extrapolation_lemma_ty() -> Expr {
516    impl_pi(
517        "A",
518        type0(),
519        arrow(app(cst("WideningOperator"), bvar(0)), prop()),
520    )
521}
522/// `AcceleratedFixpoint : AbstractState โ†’ AbstractState`
523///
524/// Accelerated fixpoint: detect linear recurrences in the Kleene sequence
525/// and jump to the closed-form limit (acceleration by closed forms).
526pub fn accelerated_fixpoint_ty() -> Expr {
527    arrow(cst("AbstractState"), cst("AbstractState"))
528}
529/// `ProbabilisticAbstractDomain : Type`
530///
531/// Abstract domain for probabilistic programs: over-approximates distributions
532/// over concrete states, e.g., interval-valued probability masses.
533pub fn probabilistic_abstract_domain_ty() -> Expr {
534    type0()
535}
536/// `AbstractDistribution : Type โ†’ Type`
537///
538/// Abstract probability distribution over A: a sound over-approximation of
539/// sets of probability distributions (e.g., by bounding probabilities).
540pub fn abstract_distribution_ty() -> Expr {
541    impl_pi("A", type0(), type0())
542}
543/// `AbstractExpectation : AbstractDistribution โ†’ (Type โ†’ Real) โ†’ Real`
544///
545/// Abstract expected value: an over-approximation of E_ฮผ[f] for abstract ฮผ.
546/// Used in abstract interpretation of probabilistic loops.
547pub fn abstract_expectation_ty() -> Expr {
548    arrow(
549        app(cst("AbstractDistribution"), type0()),
550        arrow(arrow(type0(), cst("Real")), cst("Real")),
551    )
552}
553/// `ProbabilisticSoundness : AbstractDistribution โ†’ Prop`
554///
555/// Soundness of probabilistic abstraction: ฮณ(a_ฮผ) โЇ ฮผ_concrete for all
556/// concrete distributions consistent with abstract state.
557pub fn probabilistic_soundness_ty() -> Expr {
558    arrow(app(cst("AbstractDistribution"), type0()), prop())
559}
560/// `BddAbstractDomain : Nat โ†’ Type`
561///
562/// BDD-based abstract domain for Boolean programs: abstract values are
563/// Boolean formulae represented as reduced ordered BDDs.
564pub fn bdd_abstract_domain_ty() -> Expr {
565    arrow(nat_ty(), type0())
566}
567/// `SatAbstractDomain : Type`
568///
569/// SAT-based abstract domain: abstract values are propositional formulae;
570/// emptiness checking reduces to SAT solving.
571pub fn sat_abstract_domain_ty() -> Expr {
572    type0()
573}
574/// `SymbolicTransformer : SatAbstractDomain โ†’ SatAbstractDomain`
575///
576/// Symbolic abstract transformer: abstract assignment x := e maps a
577/// formula ฯ† to โˆƒx. ฯ† โˆง x' = e (image computation via SAT/BDD).
578pub fn symbolic_transformer_ty() -> Expr {
579    arrow(cst("SatAbstractDomain"), cst("SatAbstractDomain"))
580}
581/// `AbstractModelChecking : AbstractState โ†’ Prop โ†’ Bool`
582///
583/// Abstract model checking: verify that all states in the abstract
584/// invariant satisfy property P (may return false positives).
585pub fn abstract_model_checking_ty() -> Expr {
586    arrow(cst("AbstractState"), arrow(prop(), cst("Bool")))
587}
588/// `SeparationLogicAbsDomain : Type`
589///
590/// Abstract domain based on separation logic: abstract heap predicates
591/// (e.g., list segments, tree shapes) for shape analysis.
592pub fn separation_logic_abs_domain_ty() -> Expr {
593    type0()
594}
595/// `AbstractHeapPredicate : Type โ†’ Prop`
596///
597/// An abstract heap predicate: describes a set of memory configurations.
598/// Composable via separating conjunction โˆ—.
599pub fn abstract_heap_predicate_ty() -> Expr {
600    arrow(type0(), prop())
601}
602/// `SeparatingConjunction : AbstractHeapPredicate โ†’ AbstractHeapPredicate โ†’ AbstractHeapPredicate`
603///
604/// The separating conjunction P โˆ— Q: P and Q hold on disjoint heap parts.
605pub fn separating_conjunction_ty() -> Expr {
606    arrow(
607        app(cst("AbstractHeapPredicate"), type0()),
608        arrow(
609            app(cst("AbstractHeapPredicate"), type0()),
610            app(cst("AbstractHeapPredicate"), type0()),
611        ),
612    )
613}
614/// `ShapeAnalysis : SeparationLogicAbsDomain โ†’ AbstractHeapPredicate`
615///
616/// Shape analysis result: maps an abstract domain element to the
617/// corresponding heap shape predicate (list, tree, dag, etc.).
618pub fn shape_analysis_ty() -> Expr {
619    arrow(
620        cst("SeparationLogicAbsDomain"),
621        app(cst("AbstractHeapPredicate"), type0()),
622    )
623}
624/// `HigherOrderAbstractDomain : (Type โ†’ Type) โ†’ Type`
625///
626/// Abstract domain lifted to higher-order types (functionals, closures).
627/// Approximates sets of functions F : A โ†’ B by abstract function spaces.
628pub fn higher_order_abstract_domain_ty() -> Expr {
629    arrow(arrow(type0(), type0()), type0())
630}
631/// `AbstractClosure : AbstractState โ†’ (AbstractState โ†’ AbstractState) โ†’ Type`
632///
633/// Abstract closure: a pair of captured abstract environment and abstract
634/// function body, used in higher-order program analysis.
635pub fn abstract_closure_ty() -> Expr {
636    arrow(
637        cst("AbstractState"),
638        arrow(arrow(cst("AbstractState"), cst("AbstractState")), type0()),
639    )
640}
641/// `ClosureAbstraction : AbstractClosure โ†’ AbstractState โ†’ AbstractState`
642///
643/// Abstract application of a closure to an abstract argument.
644pub fn closure_abstraction_ty() -> Expr {
645    arrow(
646        app2(
647            cst("AbstractClosure"),
648            cst("AbstractState"),
649            arrow(cst("AbstractState"), cst("AbstractState")),
650        ),
651        arrow(cst("AbstractState"), cst("AbstractState")),
652    )
653}
654/// `HigherOrderFixpoint : (AbstractState โ†’ AbstractState) โ†’ AbstractState`
655///
656/// Fixpoint of a higher-order transformer: least fixpoint of a functional
657/// on the abstract domain, for recursive procedure analysis.
658pub fn higher_order_fixpoint_ty() -> Expr {
659    arrow(
660        arrow(cst("AbstractState"), cst("AbstractState")),
661        cst("AbstractState"),
662    )
663}
664/// `InformationFlowLattice : Type`
665///
666/// Security lattice for information flow control: elements are security
667/// levels (e.g., Low โŠ‘ High) with flow relation.
668pub fn information_flow_lattice_ty() -> Expr {
669    type0()
670}
671/// `NonInterference : AbstractState โ†’ InformationFlowLattice โ†’ Prop`
672///
673/// Non-interference: public outputs depend only on public inputs.
674/// Formally: โˆ€ s1 s2, s1 =_L s2 โ†’ out(s1) =_L out(s2).
675pub fn non_interference_ty() -> Expr {
676    arrow(
677        cst("AbstractState"),
678        arrow(cst("InformationFlowLattice"), prop()),
679    )
680}
681/// `DeclassificationPolicy : Type โ†’ InformationFlowLattice โ†’ Prop`
682///
683/// Declassification policy: specifies what secret information may be
684/// intentionally revealed (e.g., checking a password hash).
685pub fn declassification_policy_ty() -> Expr {
686    arrow(type0(), arrow(cst("InformationFlowLattice"), prop()))
687}
688/// `SecureAbstractInterpreter : AbstractState โ†’ InformationFlowLattice โ†’ Prop`
689///
690/// A security-aware abstract interpreter that tracks security levels
691/// alongside abstract values for combined functional+security analysis.
692pub fn secure_abstract_interpreter_ty() -> Expr {
693    arrow(
694        cst("AbstractState"),
695        arrow(cst("InformationFlowLattice"), prop()),
696    )
697}
698/// `TypeLattice : Type`
699///
700/// A type lattice: types ordered by subtyping. Abstract interpretation
701/// over the type lattice gives type inference as a special case.
702pub fn type_lattice_ty() -> Expr {
703    type0()
704}
705/// `TypeRefinement : TypeLattice โ†’ AbstractDomain โ†’ Type`
706///
707/// A type refinement: an abstract domain element that refines a base type.
708/// E.g., {x : Int | x > 0} refines Int with a positivity predicate.
709pub fn type_refinement_ty() -> Expr {
710    arrow(
711        cst("TypeLattice"),
712        arrow(app(cst("AbstractDomain"), type0()), type0()),
713    )
714}
715/// `TypedAbstractTransformer : TypeLattice โ†’ AbstractState โ†’ AbstractState`
716///
717/// Type-directed abstract transformer: uses type information to improve
718/// precision of transfer functions (e.g., numeric types vs. pointer types).
719pub fn typed_abstract_transformer_ty() -> Expr {
720    arrow(
721        cst("TypeLattice"),
722        arrow(cst("AbstractState"), cst("AbstractState")),
723    )
724}
725/// `DeepPolyDomain : Nat โ†’ Type`
726///
727/// The DeepPoly abstract domain for neural network verification: each
728/// neuron's activation is over-approximated by a linear constraint.
729pub fn deep_poly_domain_ty() -> Expr {
730    arrow(nat_ty(), type0())
731}
732/// `AbstractRelu : DeepPolyDomain โ†’ DeepPolyDomain`
733///
734/// Abstract ReLU transformer in DeepPoly: propagates linear bounds through
735/// the ReLU nonlinearity using case analysis on the sign of bounds.
736pub fn abstract_relu_ty() -> Expr {
737    arrow(
738        app(cst("DeepPolyDomain"), nat_ty()),
739        app(cst("DeepPolyDomain"), nat_ty()),
740    )
741}
742/// `NeuralNetworkVerification : DeepPolyDomain โ†’ Prop โ†’ Bool`
743///
744/// Neural network verification: checks that for all inputs in the abstract
745/// domain, the network output satisfies a given property (robustness, safety).
746pub fn neural_network_verification_ty() -> Expr {
747    arrow(
748        app(cst("DeepPolyDomain"), nat_ty()),
749        arrow(prop(), cst("Bool")),
750    )
751}
752/// `AbstractAffineTransform : Nat โ†’ Nat โ†’ DeepPolyDomain โ†’ DeepPolyDomain`
753///
754/// Abstract affine transformation Wยทx + b over DeepPoly domain:
755/// propagates linear bounds through a fully-connected layer exactly.
756pub fn abstract_affine_transform_ty() -> Expr {
757    arrow(
758        nat_ty(),
759        arrow(
760            nat_ty(),
761            arrow(
762                app(cst("DeepPolyDomain"), nat_ty()),
763                app(cst("DeepPolyDomain"), nat_ty()),
764            ),
765        ),
766    )
767}
768/// `AssumeGuaranteeContract : AbstractState โ†’ AbstractState โ†’ Type`
769///
770/// An assume-guarantee contract (A, G): if the environment satisfies
771/// assumption A, the component guarantees G. Enables compositional reasoning.
772pub fn assume_guarantee_contract_ty() -> Expr {
773    arrow(cst("AbstractState"), arrow(cst("AbstractState"), type0()))
774}
775/// `ContractComposition : AssumeGuaranteeContract โ†’ AssumeGuaranteeContract โ†’ AssumeGuaranteeContract`
776///
777/// Compose two contracts: the output guarantee of one becomes the input
778/// assumption of the other. Sound if no circular dependencies.
779pub fn contract_composition_ty() -> Expr {
780    let ag = app2(
781        cst("AssumeGuaranteeContract"),
782        cst("AbstractState"),
783        cst("AbstractState"),
784    );
785    arrow(ag.clone(), arrow(ag.clone(), ag))
786}
787/// `SummaryFunction : AbstractState โ†’ AbstractState`
788///
789/// Procedure summary: maps abstract pre-states to abstract post-states.
790/// Enables modular interprocedural analysis without inlining.
791pub fn summary_function_ty() -> Expr {
792    arrow(cst("AbstractState"), cst("AbstractState"))
793}
794/// `CompositionSoundness : SummaryFunction โ†’ AssumeGuaranteeContract โ†’ Prop`
795///
796/// Soundness of compositional reasoning: a procedure satisfies its contract
797/// whenever its summary function is sound with respect to the contract.
798pub fn composition_soundness_ty() -> Expr {
799    arrow(
800        cst("SummaryFunction"),
801        arrow(
802            app2(
803                cst("AssumeGuaranteeContract"),
804                cst("AbstractState"),
805                cst("AbstractState"),
806            ),
807            prop(),
808        ),
809    )
810}
811/// `ModularFixpoint : (AbstractState โ†’ AbstractState) โ†’ AbstractState โ†’ AbstractState`
812///
813/// Modular fixpoint computation: compute procedure fixpoints compositionally,
814/// reusing summaries across call sites for efficiency.
815pub fn modular_fixpoint_ty() -> Expr {
816    arrow(
817        arrow(cst("AbstractState"), cst("AbstractState")),
818        arrow(cst("AbstractState"), cst("AbstractState")),
819    )
820}
821/// Register the extended abstract interpretation axioms into the environment.
822pub fn build_env_extended(env: &mut Environment) {
823    let axioms: &[(&str, Expr)] = &[
824        ("EllipsoidDomain", ellipsoid_domain_ty()),
825        ("ZonotopeDomain", zonotope_domain_ty()),
826        ("TemplatePolyhedronDomain", template_polyhedron_domain_ty()),
827        ("ReducedProductDomain", reduced_product_domain_ty()),
828        ("SmashingDomain", smashing_domain_ty()),
829        ("PowersetLiftingDomain", powerset_lifting_domain_ty()),
830        ("TraceAbstraction", trace_abstraction_ty()),
831        ("AbstractTrace", abstract_trace_ty()),
832        ("TraceSemanticsMonotone", trace_semantics_monotone_ty()),
833        ("ThreadModularAnalysis", thread_modular_analysis_ty()),
834        ("InterferenceAbstraction", interference_abstraction_ty()),
835        ("PartialOrderReductionAbs", partial_order_reduction_abs_ty()),
836        ("LocksetAnalysis", lockset_analysis_ty()),
837        ("WideningOperator", widening_operator_ty()),
838        ("NarrowingOperator", narrowing_operator_ty()),
839        ("ExtrapolationLemma", extrapolation_lemma_ty()),
840        ("AcceleratedFixpoint", accelerated_fixpoint_ty()),
841        (
842            "ProbabilisticAbstractDomain",
843            probabilistic_abstract_domain_ty(),
844        ),
845        ("AbstractDistribution", abstract_distribution_ty()),
846        ("AbstractExpectation", abstract_expectation_ty()),
847        ("ProbabilisticSoundness", probabilistic_soundness_ty()),
848        ("BddAbstractDomain", bdd_abstract_domain_ty()),
849        ("SatAbstractDomain", sat_abstract_domain_ty()),
850        ("SymbolicTransformer", symbolic_transformer_ty()),
851        ("AbstractModelChecking", abstract_model_checking_ty()),
852        ("SeparationLogicAbsDomain", separation_logic_abs_domain_ty()),
853        ("AbstractHeapPredicate", abstract_heap_predicate_ty()),
854        ("SeparatingConjunction", separating_conjunction_ty()),
855        ("ShapeAnalysis", shape_analysis_ty()),
856        (
857            "HigherOrderAbstractDomain",
858            higher_order_abstract_domain_ty(),
859        ),
860        ("AbstractClosure", abstract_closure_ty()),
861        ("ClosureAbstraction", closure_abstraction_ty()),
862        ("HigherOrderFixpoint", higher_order_fixpoint_ty()),
863        ("InformationFlowLattice", information_flow_lattice_ty()),
864        ("NonInterference", non_interference_ty()),
865        ("DeclassificationPolicy", declassification_policy_ty()),
866        (
867            "SecureAbstractInterpreter",
868            secure_abstract_interpreter_ty(),
869        ),
870        ("TypeLattice", type_lattice_ty()),
871        ("TypeRefinement", type_refinement_ty()),
872        ("TypedAbstractTransformer", typed_abstract_transformer_ty()),
873        ("DeepPolyDomain", deep_poly_domain_ty()),
874        ("AbstractRelu", abstract_relu_ty()),
875        (
876            "NeuralNetworkVerification",
877            neural_network_verification_ty(),
878        ),
879        ("AbstractAffineTransform", abstract_affine_transform_ty()),
880        ("AssumeGuaranteeContract", assume_guarantee_contract_ty()),
881        ("ContractComposition", contract_composition_ty()),
882        ("SummaryFunction", summary_function_ty()),
883        ("CompositionSoundness", composition_soundness_ty()),
884        ("ModularFixpoint", modular_fixpoint_ty()),
885    ];
886    for (name, ty) in axioms {
887        env.add(Declaration::Axiom {
888            name: Name::str(*name),
889            univ_params: vec![],
890            ty: ty.clone(),
891        })
892        .ok();
893    }
894}
895#[cfg(test)]
896mod tests {
897    use super::*;
898    fn registered_env() -> Environment {
899        let mut env = Environment::new();
900        build_env(&mut env);
901        env
902    }
903    #[test]
904    fn test_abstract_domain_registered() {
905        let env = registered_env();
906        assert!(env.get(&Name::str("AbstractDomain")).is_some());
907    }
908    #[test]
909    fn test_interval_domain_registered() {
910        let env = registered_env();
911        assert!(env.get(&Name::str("IntervalDomain")).is_some());
912    }
913    #[test]
914    fn test_galois_connection_registered() {
915        let env = registered_env();
916        assert!(env.get(&Name::str("GaloisConnection")).is_some());
917    }
918    #[test]
919    fn test_sign_domain_join() {
920        assert_eq!(SignDomain::Pos.join(&SignDomain::Zero), SignDomain::NonNeg);
921        assert_eq!(SignDomain::Neg.join(&SignDomain::Pos), SignDomain::Top);
922        assert_eq!(SignDomain::Bottom.join(&SignDomain::Neg), SignDomain::Neg);
923    }
924    #[test]
925    fn test_parity_domain_add() {
926        assert_eq!(
927            ParityDomain::Even.add(&ParityDomain::Even),
928            ParityDomain::Even
929        );
930        assert_eq!(
931            ParityDomain::Odd.add(&ParityDomain::Odd),
932            ParityDomain::Even
933        );
934        assert_eq!(
935            ParityDomain::Even.add(&ParityDomain::Odd),
936            ParityDomain::Odd
937        );
938    }
939    #[test]
940    fn test_interval_join_widen() {
941        let a = IntervalDomain::new(Bound::Finite(0), Bound::Finite(5));
942        let b = IntervalDomain::new(Bound::Finite(3), Bound::Finite(10));
943        let j = a.join(&b);
944        assert_eq!(j.lower, Bound::Finite(0));
945        assert_eq!(j.upper, Bound::Finite(10));
946        let a2 = IntervalDomain::new(Bound::Finite(0), Bound::Finite(5));
947        let b2 = IntervalDomain::new(Bound::Finite(0), Bound::Finite(20));
948        let w = a2.widen(&b2);
949        assert_eq!(w.upper, Bound::PosInf);
950    }
951    #[test]
952    fn test_interval_contains() {
953        let i = IntervalDomain::new(Bound::Finite(1), Bound::Finite(10));
954        assert!(i.contains(5));
955        assert!(!i.contains(0));
956        assert!(!i.contains(11));
957    }
958    #[test]
959    fn test_galois_connection() {
960        let gc = GaloisConnection::interval_galois();
961        let abs = gc.abstract_of(&[1, 3, 5, 7]);
962        assert_eq!(abs.lower, Bound::Finite(1));
963        assert_eq!(abs.upper, Bound::Finite(7));
964    }
965    #[test]
966    fn test_abstract_state_widen() {
967        let mut s1 = AbstractState::bottom();
968        s1.set("x", IntervalDomain::new(Bound::Finite(0), Bound::Finite(5)));
969        let mut s2 = AbstractState::bottom();
970        s2.set(
971            "x",
972            IntervalDomain::new(Bound::Finite(0), Bound::Finite(10)),
973        );
974        let w = s1.widen(&s2);
975        assert_eq!(w.get("x").upper, Bound::PosInf);
976    }
977    #[test]
978    fn test_taint_analysis() {
979        let mut ta = TaintAnalysis::new();
980        ta.add_source("user_input");
981        assert!(ta.is_tainted("user_input"));
982        ta.propagate("result", &["user_input", "constant"]);
983        assert!(ta.is_tainted("result"));
984    }
985    #[test]
986    fn test_delayed_widening() {
987        let a = IntervalDomain::new(Bound::Finite(0), Bound::Finite(5));
988        let b = IntervalDomain::new(Bound::Finite(0), Bound::Finite(10));
989        let mut dw = DelayedWidening::new(2);
990        let r1 = dw.apply(&a, &b);
991        assert_eq!(r1.upper, Bound::Finite(10));
992        let r2 = dw.apply(&a, &b);
993        assert_eq!(r2.upper, Bound::Finite(10));
994        let r3 = dw.apply(&a, &b);
995        assert_eq!(r3.upper, Bound::PosInf);
996    }
997    #[test]
998    fn test_octagon_satisfiable() {
999        let mut oct = OctagonDomain::top(2);
1000        oct.add_upper_bound(0, 10);
1001        assert!(oct.is_satisfiable());
1002    }
1003    #[test]
1004    fn test_polyhedral_contains() {
1005        let mut poly = PolyhedralDomain::top(2);
1006        poly.add_constraint(vec![1.0, 0.0], 5.0);
1007        poly.add_constraint(vec![0.0, 1.0], 3.0);
1008        assert!(poly.contains(&[4.0, 2.0]));
1009        assert!(!poly.contains(&[6.0, 2.0]));
1010    }
1011}