Skip to main content

oxilean_std/lambda_calculus/
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    AlphaEquivalenceChecker, BetaReducer, BinarySession, Context, LinearTypeChecker,
9    SessionTypeCompatibility, SimpleType, Strategy, Term, TypeInferenceSystem,
10};
11
12pub fn app(f: Expr, a: Expr) -> Expr {
13    Expr::App(Box::new(f), Box::new(a))
14}
15pub fn app2(f: Expr, a: Expr, b: Expr) -> Expr {
16    app(app(f, a), b)
17}
18pub fn app3(f: Expr, a: Expr, b: Expr, c: Expr) -> Expr {
19    app(app2(f, a, b), c)
20}
21pub fn cst(s: &str) -> Expr {
22    Expr::Const(Name::str(s), vec![])
23}
24pub fn prop() -> Expr {
25    Expr::Sort(Level::zero())
26}
27pub fn type0() -> Expr {
28    Expr::Sort(Level::succ(Level::zero()))
29}
30pub fn type1() -> Expr {
31    Expr::Sort(Level::succ(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 impl_pi(name: &str, dom: Expr, body: Expr) -> Expr {
40    pi(BinderInfo::Implicit, name, dom, body)
41}
42pub fn bvar(n: u32) -> Expr {
43    Expr::BVar(n)
44}
45pub fn nat_ty() -> Expr {
46    cst("Nat")
47}
48pub fn bool_ty() -> Expr {
49    cst("Bool")
50}
51pub fn list_ty(elem: Expr) -> Expr {
52    app(cst("List"), elem)
53}
54pub fn option_ty(elem: Expr) -> Expr {
55    app(cst("Option"), elem)
56}
57/// UntypedTerm: the type of untyped lambda terms (de Bruijn representation)
58pub fn untyped_term_ty() -> Expr {
59    type0()
60}
61/// Variable: de Bruijn index n refers to the n-th enclosing binder
62pub fn variable_ty() -> Expr {
63    arrow(nat_ty(), untyped_term_ty())
64}
65/// Abstraction: λ.t (binder in de Bruijn — no variable name needed)
66pub fn abstraction_ty() -> Expr {
67    arrow(untyped_term_ty(), untyped_term_ty())
68}
69/// Application: t s
70pub fn application_ty() -> Expr {
71    arrow(
72        untyped_term_ty(),
73        arrow(untyped_term_ty(), untyped_term_ty()),
74    )
75}
76/// Substitution: t[s/n] — substitute s for de Bruijn index n in t
77pub fn substitution_ty() -> Expr {
78    arrow(
79        untyped_term_ty(),
80        arrow(untyped_term_ty(), arrow(nat_ty(), untyped_term_ty())),
81    )
82}
83/// BetaRedex: t is a beta redex iff t = (λ.s) u
84pub fn beta_redex_ty() -> Expr {
85    arrow(untyped_term_ty(), prop())
86}
87/// EtaRedex: t is an eta redex iff t = λ.(s (BVar 0)) with BVar 0 not free in s
88pub fn eta_redex_ty() -> Expr {
89    arrow(untyped_term_ty(), prop())
90}
91/// BetaStep: one-step β-reduction t →β s
92pub fn beta_step_ty() -> Expr {
93    arrow(untyped_term_ty(), arrow(untyped_term_ty(), prop()))
94}
95/// EtaStep: one-step η-reduction t →η s
96pub fn eta_step_ty() -> Expr {
97    arrow(untyped_term_ty(), arrow(untyped_term_ty(), prop()))
98}
99/// BetaReduction: reflexive transitive closure of →β
100pub fn beta_reduction_ty() -> Expr {
101    arrow(untyped_term_ty(), arrow(untyped_term_ty(), prop()))
102}
103/// BetaEquiv: β-equivalence (=β)
104pub fn beta_equiv_ty() -> Expr {
105    arrow(untyped_term_ty(), arrow(untyped_term_ty(), prop()))
106}
107/// NormalForm: t has no β-redex
108pub fn normal_form_ty() -> Expr {
109    arrow(untyped_term_ty(), prop())
110}
111/// WeakNormalForm: t can be reduced to a normal form
112pub fn weak_normal_form_ty() -> Expr {
113    arrow(untyped_term_ty(), prop())
114}
115/// HeadNormalForm: the head of t is not a redex
116pub fn head_normal_form_ty() -> Expr {
117    arrow(untyped_term_ty(), prop())
118}
119/// ChurchNumeral: the Church encoding of n as λf.λx.f^n x
120pub fn church_numeral_ty() -> Expr {
121    arrow(nat_ty(), untyped_term_ty())
122}
123/// ChurchSucc: the successor combinator S = λn.λf.λx.f (n f x)
124pub fn church_succ_ty() -> Expr {
125    untyped_term_ty()
126}
127/// ChurchPlus: addition combinator M = λm.λn.λf.λx.m f (n f x)
128pub fn church_plus_ty() -> Expr {
129    untyped_term_ty()
130}
131/// ChurchMul: multiplication combinator M = λm.λn.λf.m (n f)
132pub fn church_mul_ty() -> Expr {
133    untyped_term_ty()
134}
135/// ChurchExp: exponentiation combinator E = λm.λn.n m
136pub fn church_exp_ty() -> Expr {
137    untyped_term_ty()
138}
139/// ChurchPred: predecessor combinator (Kleene encoding)
140pub fn church_pred_ty() -> Expr {
141    untyped_term_ty()
142}
143/// ChurchIsZero: test whether a Church numeral is zero
144pub fn church_is_zero_ty() -> Expr {
145    arrow(untyped_term_ty(), bool_ty())
146}
147/// ChurchNumeralCorrect: church_numeral n reduces to the standard encoding
148pub fn church_numeral_correct_ty() -> Expr {
149    arrow(nat_ty(), prop())
150}
151/// ChurchArithCorrect: Church arithmetic is correct w.r.t. Nat arithmetic
152pub fn church_arith_correct_ty() -> Expr {
153    prop()
154}
155/// YCombinator: Curry's Y = λf.(λx.f(x x))(λx.f(x x))
156pub fn y_combinator_ty() -> Expr {
157    untyped_term_ty()
158}
159/// TuringCombinator: Turing's Θ fixed point combinator
160pub fn turing_combinator_ty() -> Expr {
161    untyped_term_ty()
162}
163/// RecursionTheorem: every function has a fixed point
164pub fn recursion_theorem_ty() -> Expr {
165    arrow(arrow(untyped_term_ty(), untyped_term_ty()), prop())
166}
167/// YFixedPoint: Y f =β f (Y f)
168pub fn y_fixed_point_ty() -> Expr {
169    arrow(untyped_term_ty(), prop())
170}
171/// OmegaCombinator: Ω = (λx.x x)(λx.x x) — diverging term
172pub fn omega_combinator_ty() -> Expr {
173    untyped_term_ty()
174}
175/// OmegaDiverges: Ω has no normal form
176pub fn omega_diverges_ty() -> Expr {
177    prop()
178}
179/// NormalOrderRedex: leftmost-outermost redex
180pub fn normal_order_redex_ty() -> Expr {
181    arrow(untyped_term_ty(), option_ty(untyped_term_ty()))
182}
183/// ApplicativeOrderRedex: leftmost-innermost redex (call by value)
184pub fn applicative_order_redex_ty() -> Expr {
185    arrow(untyped_term_ty(), option_ty(untyped_term_ty()))
186}
187/// HeadReduction: reduce the head redex (lazy evaluation)
188pub fn head_reduction_ty() -> Expr {
189    arrow(untyped_term_ty(), option_ty(untyped_term_ty()))
190}
191/// NormalOrderStrategy: normal order finds normal form if one exists
192pub fn normal_order_strategy_ty() -> Expr {
193    prop()
194}
195/// StandardizationTheorem: if t has a normal form, normal order reaches it
196pub fn standardization_theorem_ty() -> Expr {
197    prop()
198}
199/// CallByValueReduction: strict/CBV evaluation
200pub fn cbv_reduction_ty() -> Expr {
201    arrow(untyped_term_ty(), option_ty(untyped_term_ty()))
202}
203/// CallByNeedReduction: lazy/sharing evaluation
204pub fn cbn_reduction_ty() -> Expr {
205    arrow(untyped_term_ty(), option_ty(untyped_term_ty()))
206}
207/// DiamondProperty: if t →₁ u and t →₁ v then ∃ w, u →₁ w and v →₁ w
208pub fn diamond_property_ty() -> Expr {
209    pi(
210        BinderInfo::Default,
211        "t",
212        untyped_term_ty(),
213        pi(
214            BinderInfo::Default,
215            "u",
216            untyped_term_ty(),
217            pi(BinderInfo::Default, "v", untyped_term_ty(), prop()),
218        ),
219    )
220}
221/// ChurchRosserTheorem: β-reduction is confluent
222pub fn church_rosser_theorem_ty() -> Expr {
223    prop()
224}
225/// Confluence: the reflexive transitive closure of →β has the diamond property
226pub fn confluence_ty() -> Expr {
227    prop()
228}
229/// ParallelReduction: parallel β-reduction (β∥) — key for CR proof
230pub fn parallel_reduction_ty() -> Expr {
231    arrow(untyped_term_ty(), arrow(untyped_term_ty(), prop()))
232}
233/// ParallelReductionComplete: t →β s implies t →β∥ s
234pub fn parallel_reduction_complete_ty() -> Expr {
235    prop()
236}
237/// ParallelMaxReduct: complete parallel development
238pub fn parallel_max_reduct_ty() -> Expr {
239    arrow(untyped_term_ty(), untyped_term_ty())
240}
241/// ParallelMaxReductProperty: diamond property for complete development
242pub fn parallel_max_reduct_property_ty() -> Expr {
243    prop()
244}
245/// BohmTree: the Böhm tree of a lambda term (possibly infinite)
246pub fn bohm_tree_ty() -> Expr {
247    type0()
248}
249/// BohmTreeOf: compute the Böhm tree of a term
250pub fn bohm_tree_of_ty() -> Expr {
251    arrow(untyped_term_ty(), bohm_tree_ty())
252}
253/// UnsolvableTerm: a term with no head normal form
254pub fn unsolvable_term_ty() -> Expr {
255    arrow(untyped_term_ty(), prop())
256}
257/// SolvableTerm: a term with a head normal form
258pub fn solvable_term_ty() -> Expr {
259    arrow(untyped_term_ty(), prop())
260}
261/// BohmEquiv: two terms are Böhm-equal iff their Böhm trees are equal
262pub fn bohm_equiv_ty() -> Expr {
263    arrow(untyped_term_ty(), arrow(untyped_term_ty(), prop()))
264}
265/// ObservationalEquiv: contextual equivalence in the untyped λ-calculus
266pub fn observational_equiv_ty() -> Expr {
267    arrow(untyped_term_ty(), arrow(untyped_term_ty(), prop()))
268}
269/// BohmTheorem: two distinct β-normal forms are separable by a context
270pub fn bohm_theorem_ty() -> Expr {
271    prop()
272}
273/// SimpleType: the type of simple types over a base type set
274pub fn simple_type_ty() -> Expr {
275    type0()
276}
277/// BaseType: a ground/atomic type
278pub fn base_type_ty() -> Expr {
279    arrow(type0(), simple_type_ty())
280}
281/// ArrowType: function type A → B in simple type theory
282pub fn arrow_type_ty() -> Expr {
283    arrow(simple_type_ty(), arrow(simple_type_ty(), simple_type_ty()))
284}
285/// TypingContext: a finite map from variables to simple types
286pub fn typing_context_ty() -> Expr {
287    type0()
288}
289/// STLCTyping: Γ ⊢ t : τ (simple type assignment)
290pub fn stlc_typing_ty() -> Expr {
291    arrow(
292        typing_context_ty(),
293        arrow(untyped_term_ty(), arrow(simple_type_ty(), prop())),
294    )
295}
296/// STLCSubjectReduction: if Γ ⊢ t : τ and t →β s then Γ ⊢ s : τ
297pub fn stlc_subject_reduction_ty() -> Expr {
298    prop()
299}
300/// STLCStrongNormalization: all well-typed STLC terms are strongly normalizing
301pub fn stlc_strong_normalization_ty() -> Expr {
302    prop()
303}
304/// STLCChurchRosser: STLC β-reduction is confluent
305pub fn stlc_church_rosser_ty() -> Expr {
306    prop()
307}
308/// STLCDecidability: type-checking STLC is decidable
309pub fn stlc_decidability_ty() -> Expr {
310    prop()
311}
312/// SystemFType: types of System F (including type variables and ∀)
313pub fn system_f_type_ty() -> Expr {
314    type0()
315}
316/// SystemFTerm: terms of System F (including type abstraction and application)
317pub fn system_f_term_ty() -> Expr {
318    type0()
319}
320/// SystemFTyping: typing judgment for System F
321pub fn system_f_typing_ty() -> Expr {
322    arrow(
323        typing_context_ty(),
324        arrow(system_f_term_ty(), arrow(system_f_type_ty(), prop())),
325    )
326}
327/// SystemFStrongNormalization: System F is strongly normalizing
328pub fn system_f_sn_ty() -> Expr {
329    prop()
330}
331/// SystemFConfluence: System F β-reduction is confluent
332pub fn system_f_confluence_ty() -> Expr {
333    prop()
334}
335/// SystemFParametricity: Reynolds's abstraction theorem
336pub fn system_f_parametricity_ty() -> Expr {
337    prop()
338}
339/// SystemFUndecidableTyping: type inference for System F is undecidable (Wells)
340pub fn system_f_undecidable_ty() -> Expr {
341    prop()
342}
343/// ChurchEncoding_NatF: System F encoding of natural numbers
344/// ∀ α. (α → α) → α → α
345pub fn church_nat_f_ty() -> Expr {
346    system_f_type_ty()
347}
348/// ChurchEncoding_BoolF: System F encoding of booleans
349/// ∀ α. α → α → α
350pub fn church_bool_f_ty() -> Expr {
351    system_f_type_ty()
352}
353/// ChurchEncoding_ListF: System F encoding of lists
354/// ∀ α β. β → (α → β → β) → β
355pub fn church_list_f_ty() -> Expr {
356    system_f_type_ty()
357}
358/// Kind: the kind language of System Fω (* and →)
359pub fn kind_ty() -> Expr {
360    type0()
361}
362/// StarKind: the base kind *
363pub fn star_kind_ty() -> Expr {
364    kind_ty()
365}
366/// KindArrow: kind constructor A ⇒ B
367pub fn kind_arrow_ty() -> Expr {
368    arrow(kind_ty(), arrow(kind_ty(), kind_ty()))
369}
370/// TypeConstructor: a type-level function with a kind
371pub fn type_constructor_ty() -> Expr {
372    type0()
373}
374/// SystemFOmegaType: types of System Fω
375pub fn system_fomega_type_ty() -> Expr {
376    type0()
377}
378/// SystemFOmegaTerm: terms of System Fω
379pub fn system_fomega_term_ty() -> Expr {
380    type0()
381}
382/// SystemFOmegaTyping: typing judgment for Fω
383pub fn system_fomega_typing_ty() -> Expr {
384    arrow(
385        typing_context_ty(),
386        arrow(
387            system_fomega_term_ty(),
388            arrow(system_fomega_type_ty(), prop()),
389        ),
390    )
391}
392/// SystemFOmegaSN: Fω is strongly normalizing
393pub fn system_fomega_sn_ty() -> Expr {
394    prop()
395}
396/// SystemFOmegaKindSoundness: well-kinded types have sound interpretations
397pub fn system_fomega_kind_soundness_ty() -> Expr {
398    prop()
399}
400/// PTS_Axiom: the set of axioms (s : s') for a pure type system
401pub fn pts_axiom_ty() -> Expr {
402    type0()
403}
404/// PTS_Rule: the set of rules (s₁, s₂, s₃) for Π-type formation
405pub fn pts_rule_ty() -> Expr {
406    type0()
407}
408/// PureTypeSystem: a PTS defined by sorts S, axioms A, rules R
409pub fn pure_type_system_ty() -> Expr {
410    type0()
411}
412/// PTSTyping: Γ ⊢ t : T in a PTS
413pub fn pts_typing_ty() -> Expr {
414    arrow(
415        pure_type_system_ty(),
416        arrow(
417            typing_context_ty(),
418            arrow(untyped_term_ty(), arrow(untyped_term_ty(), prop())),
419        ),
420    )
421}
422/// CoC: the Calculus of Constructions (top of the λ-cube)
423pub fn coc_ty() -> Expr {
424    pure_type_system_ty()
425}
426/// LambdaArrow: simply-typed lambda calculus corner of cube
427pub fn lambda_arrow_ty() -> Expr {
428    pure_type_system_ty()
429}
430/// Lambda2: System F corner of cube (type polymorphism)
431pub fn lambda2_ty() -> Expr {
432    pure_type_system_ty()
433}
434/// LambdaOmega: System Fω corner (type constructors)
435pub fn lambda_omega_ty() -> Expr {
436    pure_type_system_ty()
437}
438/// LambdaP: λP (dependent types, Edinburgh LF)
439pub fn lambda_p_ty() -> Expr {
440    pure_type_system_ty()
441}
442/// PTSSubjectReduction: subject reduction holds for all functional PTS
443pub fn pts_subject_reduction_ty() -> Expr {
444    arrow(pure_type_system_ty(), prop())
445}
446/// PTSConfluence: confluence holds for all PTS (β-reduction)
447pub fn pts_confluence_ty() -> Expr {
448    arrow(pure_type_system_ty(), prop())
449}
450/// CoCStrongNormalization: the Calculus of Constructions is SN
451pub fn coc_sn_ty() -> Expr {
452    prop()
453}
454/// PCFType: types of PCF (Plotkin's Programming Computable Functions)
455/// PCF = STLC + fixpoint + nat + bool
456pub fn pcf_type_ty() -> Expr {
457    type0()
458}
459/// PCFTerm: terms of PCF (including `fix`, `pred`, `succ`, `if-then-else`)
460pub fn pcf_term_ty() -> Expr {
461    type0()
462}
463/// PCFFixpoint: the fixed-point operator `fix : (τ → τ) → τ` in PCF
464pub fn pcf_fixpoint_ty() -> Expr {
465    pi(
466        BinderInfo::Default,
467        "tau",
468        simple_type_ty(),
469        arrow(arrow(bvar(0), bvar(1)), bvar(0)),
470    )
471}
472/// PCFTyping: typing judgment for PCF
473pub fn pcf_typing_ty() -> Expr {
474    arrow(
475        typing_context_ty(),
476        arrow(pcf_term_ty(), arrow(pcf_type_ty(), prop())),
477    )
478}
479/// PCFDenotationalSemantics: Scott domain semantics for PCF
480pub fn pcf_denotational_semantics_ty() -> Expr {
481    prop()
482}
483/// PCFAdequacy: operational and denotational semantics agree for PCF
484pub fn pcf_adequacy_ty() -> Expr {
485    prop()
486}
487/// PCFFullAbstraction: Milner's full abstraction problem for PCF
488pub fn pcf_full_abstraction_ty() -> Expr {
489    prop()
490}
491/// SubtypeRelation: A <: B (A is a subtype of B)
492pub fn subtype_relation_ty() -> Expr {
493    arrow(simple_type_ty(), arrow(simple_type_ty(), prop()))
494}
495/// SubtypingReflexivity: A <: A
496pub fn subtyping_reflexivity_ty() -> Expr {
497    arrow(simple_type_ty(), prop())
498}
499/// SubtypingTransitivity: A <: B → B <: C → A <: C
500pub fn subtyping_transitivity_ty() -> Expr {
501    arrow(
502        simple_type_ty(),
503        arrow(simple_type_ty(), arrow(simple_type_ty(), prop())),
504    )
505}
506/// BoundedQuantification: ∀ X <: T. U (F-sub style bounded ∀)
507pub fn bounded_quantification_ty() -> Expr {
508    arrow(
509        simple_type_ty(),
510        arrow(arrow(simple_type_ty(), simple_type_ty()), simple_type_ty()),
511    )
512}
513/// FBoundedPolymorphism: F-bounded quantification ∀ X <: F[X]. U
514pub fn f_bounded_polymorphism_ty() -> Expr {
515    arrow(
516        arrow(simple_type_ty(), simple_type_ty()),
517        arrow(arrow(simple_type_ty(), simple_type_ty()), simple_type_ty()),
518    )
519}
520/// CoercionFunction: a coercion c : A → B witnessing A <: B
521pub fn coercion_function_ty() -> Expr {
522    arrow(simple_type_ty(), arrow(simple_type_ty(), prop()))
523}
524/// SubtypingSubjectReduction: subtying is preserved under reduction
525pub fn subtyping_subject_reduction_ty() -> Expr {
526    prop()
527}
528/// EffectLabel: a label for a computational effect
529pub fn effect_label_ty() -> Expr {
530    type0()
531}
532/// EffectSet: a set of effect labels
533pub fn effect_set_ty() -> Expr {
534    type0()
535}
536/// EffectType: a type annotated with effects τ !ε
537pub fn effect_type_ty() -> Expr {
538    arrow(simple_type_ty(), arrow(effect_set_ty(), simple_type_ty()))
539}
540/// EffectTyping: Γ ⊢ t : τ ! ε
541pub fn effect_typing_ty() -> Expr {
542    arrow(
543        typing_context_ty(),
544        arrow(
545            untyped_term_ty(),
546            arrow(simple_type_ty(), arrow(effect_set_ty(), prop())),
547        ),
548    )
549}
550/// RegionType: a type annotated with memory region ρ
551pub fn region_type_ty() -> Expr {
552    type0()
553}
554/// RegionInference: algorithm to infer region annotations
555pub fn region_inference_ty() -> Expr {
556    arrow(untyped_term_ty(), region_type_ty())
557}
558/// GradedType: a type T graded by a semiring element r (coeffect)
559pub fn graded_type_ty() -> Expr {
560    type0()
561}
562/// CoeffectSystem: a type system tracking resource usage via graded types
563pub fn coeffect_system_ty() -> Expr {
564    type0()
565}
566/// CoeffectTyping: Γ ⊢ t : T graded by r
567pub fn coeffect_typing_ty() -> Expr {
568    arrow(
569        typing_context_ty(),
570        arrow(untyped_term_ty(), arrow(graded_type_ty(), prop())),
571    )
572}
573/// LinearType: a type that must be used exactly once
574pub fn linear_type_ty() -> Expr {
575    type0()
576}
577/// LinearContext: a linear typing context (each variable used exactly once)
578pub fn linear_context_ty() -> Expr {
579    type0()
580}
581/// LinearTyping: linear typing judgment Γ ⊢_L t : A
582pub fn linear_typing_ty() -> Expr {
583    arrow(
584        linear_context_ty(),
585        arrow(untyped_term_ty(), arrow(linear_type_ty(), prop())),
586    )
587}
588/// LinearArrow: the linear function type A ⊸ B
589pub fn linear_arrow_ty() -> Expr {
590    arrow(linear_type_ty(), arrow(linear_type_ty(), linear_type_ty()))
591}
592/// LinearExchangeability: linear contexts can be reordered
593pub fn linear_exchangeability_ty() -> Expr {
594    prop()
595}
596/// AffineType: a type that may be used at most once (weakening allowed)
597pub fn affine_type_ty() -> Expr {
598    type0()
599}
600/// AffineTyping: affine typing judgment (weakening OK, no contraction)
601pub fn affine_typing_ty() -> Expr {
602    arrow(
603        typing_context_ty(),
604        arrow(untyped_term_ty(), arrow(affine_type_ty(), prop())),
605    )
606}
607/// RelevantType: a type that must be used at least once (contraction OK, no weakening)
608pub fn relevant_type_ty() -> Expr {
609    type0()
610}
611/// RelevantTyping: relevant typing judgment
612pub fn relevant_typing_ty() -> Expr {
613    arrow(
614        typing_context_ty(),
615        arrow(untyped_term_ty(), arrow(relevant_type_ty(), prop())),
616    )
617}
618/// BangModality: the `!A` modality — unrestricted use of A
619pub fn bang_modality_ty() -> Expr {
620    arrow(linear_type_ty(), linear_type_ty())
621}
622/// LFSignature: a signature Σ in Edinburgh LF
623pub fn lf_signature_ty() -> Expr {
624    type0()
625}
626/// LFContext: a context Γ in Edinburgh LF
627pub fn lf_context_ty() -> Expr {
628    type0()
629}
630/// LFTyping: Σ; Γ ⊢ t : T in Edinburgh LF
631pub fn lf_typing_ty() -> Expr {
632    arrow(
633        lf_signature_ty(),
634        arrow(
635            lf_context_ty(),
636            arrow(untyped_term_ty(), arrow(untyped_term_ty(), prop())),
637        ),
638    )
639}
640/// LFKindValidity: Σ; Γ ⊢ K kind
641pub fn lf_kind_validity_ty() -> Expr {
642    arrow(
643        lf_signature_ty(),
644        arrow(lf_context_ty(), arrow(kind_ty(), prop())),
645    )
646}
647/// UTTUniverse: a universe in Luo's Unified Theory of Types
648pub fn utt_universe_ty() -> Expr {
649    type0()
650}
651/// UTTELType: a type in UTT (el-form, deriving a type from a set)
652pub fn utt_el_type_ty() -> Expr {
653    arrow(utt_universe_ty(), type0())
654}
655/// CICInductiveType: an inductive type in the Calculus of Inductive Constructions
656pub fn cic_inductive_type_ty() -> Expr {
657    type0()
658}
659/// CICElimination: the elimination/recursor for an inductive type
660pub fn cic_elimination_ty() -> Expr {
661    arrow(cic_inductive_type_ty(), untyped_term_ty())
662}
663/// CICPositivityCondition: strict positivity for inductive types
664pub fn cic_positivity_condition_ty() -> Expr {
665    arrow(cic_inductive_type_ty(), prop())
666}
667/// IntersectionType: A ∩ B — a term has both types A and B
668pub fn intersection_type_ty() -> Expr {
669    arrow(simple_type_ty(), arrow(simple_type_ty(), simple_type_ty()))
670}
671/// IntersectionTyping: Γ ⊢ t : A ∩ B
672pub fn intersection_typing_ty() -> Expr {
673    arrow(
674        typing_context_ty(),
675        arrow(untyped_term_ty(), arrow(simple_type_ty(), prop())),
676    )
677}
678/// FilterModel: a filter model of the untyped λ-calculus via intersection types
679pub fn filter_model_ty() -> Expr {
680    type0()
681}
682/// IntersectionTypeCompleteness: every normalizable term is typeable
683pub fn intersection_type_completeness_ty() -> Expr {
684    prop()
685}
686/// PrincipalTyping: every typeable term has a principal type scheme
687pub fn principal_typing_ty() -> Expr {
688    arrow(untyped_term_ty(), prop())
689}
690/// UnionType: A ∪ B — occurrence typing context
691pub fn union_type_ty() -> Expr {
692    arrow(simple_type_ty(), arrow(simple_type_ty(), simple_type_ty()))
693}
694/// OccurrenceTyping: type assignment based on control flow occurrences
695pub fn occurrence_typing_ty() -> Expr {
696    arrow(
697        typing_context_ty(),
698        arrow(untyped_term_ty(), arrow(simple_type_ty(), prop())),
699    )
700}
701/// FlowAnalysis: 0-CFA / control-flow analysis as a type system
702pub fn flow_analysis_ty() -> Expr {
703    arrow(untyped_term_ty(), type0())
704}
705/// GradualType: a type that may be partially unknown (includes `?`)
706pub fn gradual_type_ty() -> Expr {
707    type0()
708}
709/// DynType: the dynamic type `?` (unknown type)
710pub fn dyn_type_ty() -> Expr {
711    gradual_type_ty()
712}
713/// TypeConsistency: A ~ B (types are consistent, i.e., compatible under `?`)
714pub fn type_consistency_ty() -> Expr {
715    arrow(gradual_type_ty(), arrow(gradual_type_ty(), prop()))
716}
717/// GradualTyping: Γ ⊢ t : A in the gradually-typed λ-calculus
718pub fn gradual_typing_ty() -> Expr {
719    arrow(
720        typing_context_ty(),
721        arrow(untyped_term_ty(), arrow(gradual_type_ty(), prop())),
722    )
723}
724/// BlameLabel: a label tracking the source of a runtime type failure
725pub fn blame_label_ty() -> Expr {
726    type0()
727}
728/// BlameCalculusTerm: a term in the blame calculus (with casts and labels)
729pub fn blame_calculus_term_ty() -> Expr {
730    type0()
731}
732/// BlameTheorem: well-typed programs can only be blamed at boundaries
733pub fn blame_theorem_ty() -> Expr {
734    prop()
735}
736/// AbstractingGradualTyping: AGT framework lifting predicates to gradual types
737pub fn abstracting_gradual_typing_ty() -> Expr {
738    prop()
739}
740/// SessionType: the type of a communication channel endpoint
741pub fn session_type_ty() -> Expr {
742    type0()
743}
744/// SendType: !T.S — send a value of type T then continue as S
745pub fn send_type_ty() -> Expr {
746    arrow(
747        simple_type_ty(),
748        arrow(session_type_ty(), session_type_ty()),
749    )
750}
751/// RecvType: ?T.S — receive a value of type T then continue as S
752pub fn recv_type_ty() -> Expr {
753    arrow(
754        simple_type_ty(),
755        arrow(session_type_ty(), session_type_ty()),
756    )
757}
758/// EndType: the completed session
759pub fn end_type_ty() -> Expr {
760    session_type_ty()
761}
762/// DualSession: the dual of a session type (swap sends and receives)
763pub fn dual_session_ty() -> Expr {
764    arrow(session_type_ty(), session_type_ty())
765}
766/// BinarySessionTyping: Γ ⊢ P : S (binary session typing)
767pub fn binary_session_typing_ty() -> Expr {
768    arrow(
769        typing_context_ty(),
770        arrow(untyped_term_ty(), arrow(session_type_ty(), prop())),
771    )
772}
773/// MultipartySessionType: a global type for multiparty session protocols
774pub fn multiparty_session_type_ty() -> Expr {
775    type0()
776}
777/// GlobalToLocal: project a global type to a local session type for a role
778pub fn global_to_local_ty() -> Expr {
779    arrow(
780        multiparty_session_type_ty(),
781        arrow(nat_ty(), session_type_ty()),
782    )
783}
784/// DeadlockFreedom: well-typed session processes do not deadlock
785pub fn deadlock_freedom_ty() -> Expr {
786    prop()
787}
788/// SessionTypeCompleteness: every interaction satisfying the global type is typeable
789pub fn session_type_completeness_ty() -> Expr {
790    prop()
791}
792/// RecursiveType: a type μX.F[X] — least fixed point of type functor F
793pub fn recursive_type_ty() -> Expr {
794    arrow(arrow(simple_type_ty(), simple_type_ty()), simple_type_ty())
795}
796/// IsoRecursiveFold: fold : F[μX.F] → μX.F
797pub fn iso_recursive_fold_ty() -> Expr {
798    arrow(
799        arrow(simple_type_ty(), simple_type_ty()),
800        arrow(simple_type_ty(), simple_type_ty()),
801    )
802}
803/// IsoRecursiveUnfold: unfold : μX.F → F[μX.F]
804pub fn iso_recursive_unfold_ty() -> Expr {
805    arrow(
806        arrow(simple_type_ty(), simple_type_ty()),
807        arrow(simple_type_ty(), simple_type_ty()),
808    )
809}
810/// EquiRecursiveType: equi-recursive interpretation (fold/unfold invisible)
811pub fn equi_recursive_type_ty() -> Expr {
812    arrow(arrow(simple_type_ty(), simple_type_ty()), simple_type_ty())
813}
814/// TypeUnrolling: μX.F ≡ F[μX.F] (equi-recursive unrolling)
815pub fn type_unrolling_ty() -> Expr {
816    arrow(arrow(simple_type_ty(), simple_type_ty()), prop())
817}
818/// RecursiveTypeContraction: well-founded recursive types have unique fixed points
819pub fn recursive_type_contraction_ty() -> Expr {
820    prop()
821}
822/// KindPolymorphism: ∀κ. F[κ] — quantification over kinds
823pub fn kind_polymorphism_ty() -> Expr {
824    arrow(arrow(kind_ty(), kind_ty()), kind_ty())
825}
826/// HigherKindedType: a type constructor of kind κ ⇒ κ'
827pub fn higher_kinded_type_ty() -> Expr {
828    arrow(kind_ty(), arrow(kind_ty(), type0()))
829}
830/// KindInference: algorithm to infer kinds for type expressions
831pub fn kind_inference_ty() -> Expr {
832    arrow(system_fomega_type_ty(), option_ty(kind_ty()))
833}
834/// KindSoundness: well-kinded type applications have well-kinded results
835pub fn kind_soundness_ty() -> Expr {
836    prop()
837}
838/// KindCompleteness: kind inference is complete for Fω types
839pub fn kind_completeness_ty() -> Expr {
840    prop()
841}
842/// RowType: a row of labeled types (for records or variants)
843pub fn row_type_ty() -> Expr {
844    type0()
845}
846/// ExtendRow: add a field l : T to a row R
847pub fn extend_row_ty() -> Expr {
848    arrow(
849        nat_ty(),
850        arrow(simple_type_ty(), arrow(row_type_ty(), row_type_ty())),
851    )
852}
853/// EmptyRow: the empty row
854pub fn empty_row_ty() -> Expr {
855    row_type_ty()
856}
857/// RecordType: a closed record type from a row
858pub fn record_type_ty() -> Expr {
859    arrow(row_type_ty(), simple_type_ty())
860}
861/// VariantType: a closed variant type from a row
862pub fn variant_type_ty() -> Expr {
863    arrow(row_type_ty(), simple_type_ty())
864}
865/// RowPolymorphicTyping: Γ ⊢ t : {R} with row variable R
866pub fn row_polymorphic_typing_ty() -> Expr {
867    arrow(
868        typing_context_ty(),
869        arrow(untyped_term_ty(), arrow(row_type_ty(), prop())),
870    )
871}
872/// StructuralSubtyping: subtyping determined by structure, not names
873pub fn structural_subtyping_ty() -> Expr {
874    arrow(row_type_ty(), arrow(row_type_ty(), prop()))
875}
876/// SetoidCarrier: the carrier set of a setoid
877pub fn setoid_carrier_ty() -> Expr {
878    type0()
879}
880/// SetoidRelation: the equivalence relation of a setoid
881pub fn setoid_relation_ty() -> Expr {
882    arrow(setoid_carrier_ty(), arrow(setoid_carrier_ty(), prop()))
883}
884/// Setoid: a pair of a carrier and an equivalence relation
885pub fn setoid_ty() -> Expr {
886    type0()
887}
888/// QuotientType: the quotient A / ~ of a setoid
889pub fn quotient_type_ty() -> Expr {
890    arrow(setoid_ty(), type0())
891}
892/// QuotientIntro: [a] : A / ~ (introduction rule)
893pub fn quotient_intro_ty() -> Expr {
894    arrow(setoid_ty(), arrow(setoid_carrier_ty(), quotient_type_ty()))
895}
896/// QuotientElim: elimination from A / ~ to a P that respects ~
897pub fn quotient_elim_ty() -> Expr {
898    arrow(
899        setoid_ty(),
900        arrow(
901            arrow(setoid_carrier_ty(), type0()),
902            arrow(quotient_type_ty(), type0()),
903        ),
904    )
905}
906/// QuotientComputation: [a] elim f = f a
907pub fn quotient_computation_ty() -> Expr {
908    arrow(setoid_ty(), prop())
909}
910/// ProofIrrelevance: any two proofs of the same proposition are equal
911pub fn proof_irrelevance_ty() -> Expr {
912    pi(
913        BinderInfo::Default,
914        "P",
915        prop(),
916        pi(
917            BinderInfo::Default,
918            "p",
919            bvar(0),
920            pi(BinderInfo::Default, "q", bvar(1), prop()),
921        ),
922    )
923}
924/// IrrelevantArgument: a term whose type-theoretic argument is proof-irrelevant
925pub fn irrelevant_argument_ty() -> Expr {
926    arrow(prop(), prop())
927}
928/// SquashType: propositional truncation ||A|| (collapse all proofs)
929pub fn squash_type_ty() -> Expr {
930    arrow(type0(), prop())
931}
932/// SquashIntro: a : A → ||A||
933pub fn squash_intro_ty() -> Expr {
934    arrow(type0(), arrow(type0(), prop()))
935}
936/// SquashElim: ||A|| → (A → P) → P for P : Prop
937pub fn squash_elim_ty() -> Expr {
938    arrow(prop(), arrow(arrow(type0(), prop()), prop()))
939}
940/// UniverseLevel: the type of universe levels (ω-many levels)
941pub fn universe_level_ty() -> Expr {
942    nat_ty()
943}
944/// RussellUniverse: Uᵢ : Uᵢ₊₁ in the Russell style (types live in universes)
945pub fn russell_universe_ty() -> Expr {
946    arrow(universe_level_ty(), type1())
947}
948/// TarskiUniverse: a Tarski-style universe Uᵢ with a decoding map elᵢ
949pub fn tarski_universe_ty() -> Expr {
950    type0()
951}
952/// TarskiDecode: el : Uᵢ → Type (decode a code to a type)
953pub fn tarski_decode_ty() -> Expr {
954    arrow(tarski_universe_ty(), type0())
955}
956/// CumulativeHierarchy: Uᵢ ⊆ Uᵢ₊₁ (lifting from one universe to the next)
957pub fn cumulative_hierarchy_ty() -> Expr {
958    arrow(
959        universe_level_ty(),
960        arrow(tarski_universe_ty(), tarski_universe_ty()),
961    )
962}
963/// UniversePolymorphism: quantification over universe levels
964pub fn universe_polymorphism_ty() -> Expr {
965    arrow(arrow(universe_level_ty(), type1()), type1())
966}
967/// ResizingAxiom: propositional resizing (all propositions are small)
968pub fn resizing_axiom_ty() -> Expr {
969    prop()
970}
971/// DelimitedContinuation: type of delimited continuation operators (shift/reset)
972pub fn delimited_continuation_ty() -> Expr {
973    arrow(simple_type_ty(), arrow(simple_type_ty(), simple_type_ty()))
974}
975/// MonadicType: a monadic type T M (T wrapped in monad M)
976pub fn monadic_type_ty() -> Expr {
977    arrow(
978        arrow(simple_type_ty(), simple_type_ty()),
979        arrow(simple_type_ty(), simple_type_ty()),
980    )
981}
982/// MonadicTyping: Γ ⊢ t : M[A] for monad M
983pub fn monadic_typing_ty() -> Expr {
984    arrow(
985        typing_context_ty(),
986        arrow(
987            untyped_term_ty(),
988            arrow(
989                arrow(simple_type_ty(), simple_type_ty()),
990                arrow(simple_type_ty(), prop()),
991            ),
992        ),
993    )
994}
995/// AlgebraicEffectType: a type for algebraic effects with operations Op
996pub fn algebraic_effect_type_ty() -> Expr {
997    type0()
998}
999/// HandlerType: a handler mapping effects to values of type A
1000pub fn handler_type_ty() -> Expr {
1001    arrow(
1002        algebraic_effect_type_ty(),
1003        arrow(simple_type_ty(), simple_type_ty()),
1004    )
1005}
1006/// DependentSessionType: a session type indexed by values (dependent sessions)
1007pub fn dependent_session_type_ty() -> Expr {
1008    type0()
1009}
1010/// RefinementType: {x : T | P x} — a type refined by predicate P
1011pub fn refinement_type_ty() -> Expr {
1012    arrow(
1013        simple_type_ty(),
1014        arrow(arrow(simple_type_ty(), prop()), simple_type_ty()),
1015    )
1016}
1017/// LiquidType: refinement type with decidable predicates (Liquid Haskell style)
1018pub fn liquid_type_ty() -> Expr {
1019    arrow(
1020        simple_type_ty(),
1021        arrow(arrow(simple_type_ty(), bool_ty()), simple_type_ty()),
1022    )
1023}
1024/// NominalType: a type with freshness/name-binding (nominal logic)
1025pub fn nominal_type_ty() -> Expr {
1026    type0()
1027}
1028/// FreshnessPredicate: `a # t` — name a is fresh in term t
1029pub fn freshness_predicate_ty() -> Expr {
1030    arrow(nat_ty(), arrow(untyped_term_ty(), prop()))
1031}
1032/// AbstractionNominal: `⟨a⟩t` — nominal abstraction over fresh name a
1033pub fn abstraction_nominal_ty() -> Expr {
1034    arrow(nat_ty(), arrow(untyped_term_ty(), nominal_type_ty()))
1035}
1036/// Populate an `Environment` with lambda-calculus axioms and theorem stubs.
1037pub fn build_lambda_calculus_env() -> Environment {
1038    let mut env = Environment::new();
1039    let axioms: &[(&str, Expr)] = &[
1040        ("UntypedTerm", untyped_term_ty()),
1041        ("LcVariable", variable_ty()),
1042        ("LcAbstraction", abstraction_ty()),
1043        ("LcApplication", application_ty()),
1044        ("LcSubstitution", substitution_ty()),
1045        ("BetaRedex", beta_redex_ty()),
1046        ("EtaRedex", eta_redex_ty()),
1047        ("BetaStep", beta_step_ty()),
1048        ("EtaStep", eta_step_ty()),
1049        ("BetaReduction", beta_reduction_ty()),
1050        ("BetaEquiv", beta_equiv_ty()),
1051        ("NormalForm", normal_form_ty()),
1052        ("WeakNormalForm", weak_normal_form_ty()),
1053        ("HeadNormalForm", head_normal_form_ty()),
1054        ("ChurchNumeral", church_numeral_ty()),
1055        ("ChurchSucc", church_succ_ty()),
1056        ("ChurchPlus", church_plus_ty()),
1057        ("ChurchMul", church_mul_ty()),
1058        ("ChurchExp", church_exp_ty()),
1059        ("ChurchPred", church_pred_ty()),
1060        ("ChurchIsZero", church_is_zero_ty()),
1061        ("ChurchNumeralCorrect", church_numeral_correct_ty()),
1062        ("ChurchArithCorrect", church_arith_correct_ty()),
1063        ("YCombinator", y_combinator_ty()),
1064        ("TuringCombinator", turing_combinator_ty()),
1065        ("RecursionTheorem", recursion_theorem_ty()),
1066        ("YFixedPoint", y_fixed_point_ty()),
1067        ("OmegaCombinator", omega_combinator_ty()),
1068        ("OmegaDiverges", omega_diverges_ty()),
1069        ("NormalOrderRedex", normal_order_redex_ty()),
1070        ("ApplicativeOrderRedex", applicative_order_redex_ty()),
1071        ("HeadReduction", head_reduction_ty()),
1072        ("NormalOrderStrategy", normal_order_strategy_ty()),
1073        ("StandardizationTheorem", standardization_theorem_ty()),
1074        ("CallByValueReduction", cbv_reduction_ty()),
1075        ("CallByNeedReduction", cbn_reduction_ty()),
1076        ("DiamondProperty", diamond_property_ty()),
1077        ("ChurchRosserTheorem", church_rosser_theorem_ty()),
1078        ("Confluence", confluence_ty()),
1079        ("ParallelReduction", parallel_reduction_ty()),
1080        (
1081            "ParallelReductionComplete",
1082            parallel_reduction_complete_ty(),
1083        ),
1084        ("ParallelMaxReduct", parallel_max_reduct_ty()),
1085        (
1086            "ParallelMaxReductProperty",
1087            parallel_max_reduct_property_ty(),
1088        ),
1089        ("BohmTree", bohm_tree_ty()),
1090        ("BohmTreeOf", bohm_tree_of_ty()),
1091        ("UnsolvableTerm", unsolvable_term_ty()),
1092        ("SolvableTerm", solvable_term_ty()),
1093        ("BohmEquiv", bohm_equiv_ty()),
1094        ("ObservationalEquiv", observational_equiv_ty()),
1095        ("BohmTheorem", bohm_theorem_ty()),
1096        ("SimpleType", simple_type_ty()),
1097        ("BaseType", base_type_ty()),
1098        ("ArrowType", arrow_type_ty()),
1099        ("TypingContext", typing_context_ty()),
1100        ("STLCTyping", stlc_typing_ty()),
1101        ("STLCSubjectReduction", stlc_subject_reduction_ty()),
1102        ("STLCStrongNormalization", stlc_strong_normalization_ty()),
1103        ("STLCChurchRosser", stlc_church_rosser_ty()),
1104        ("STLCDecidability", stlc_decidability_ty()),
1105        ("SystemFType", system_f_type_ty()),
1106        ("SystemFTerm", system_f_term_ty()),
1107        ("SystemFTyping", system_f_typing_ty()),
1108        ("SystemFStrongNormalization", system_f_sn_ty()),
1109        ("SystemFConfluence", system_f_confluence_ty()),
1110        ("SystemFParametricity", system_f_parametricity_ty()),
1111        ("SystemFUndecidableTyping", system_f_undecidable_ty()),
1112        ("ChurchNatF", church_nat_f_ty()),
1113        ("ChurchBoolF", church_bool_f_ty()),
1114        ("ChurchListF", church_list_f_ty()),
1115        ("Kind", kind_ty()),
1116        ("StarKind", star_kind_ty()),
1117        ("KindArrow", kind_arrow_ty()),
1118        ("TypeConstructor", type_constructor_ty()),
1119        ("SystemFOmegaType", system_fomega_type_ty()),
1120        ("SystemFOmegaTerm", system_fomega_term_ty()),
1121        ("SystemFOmegaTyping", system_fomega_typing_ty()),
1122        ("SystemFOmegaSN", system_fomega_sn_ty()),
1123        (
1124            "SystemFOmegaKindSoundness",
1125            system_fomega_kind_soundness_ty(),
1126        ),
1127        ("PTSAxiom", pts_axiom_ty()),
1128        ("PTSRule", pts_rule_ty()),
1129        ("PureTypeSystem", pure_type_system_ty()),
1130        ("PTSTyping", pts_typing_ty()),
1131        ("CoC", coc_ty()),
1132        ("LambdaArrow", lambda_arrow_ty()),
1133        ("Lambda2", lambda2_ty()),
1134        ("LambdaOmega", lambda_omega_ty()),
1135        ("LambdaP", lambda_p_ty()),
1136        ("PTSSubjectReduction", pts_subject_reduction_ty()),
1137        ("PTSConfluence", pts_confluence_ty()),
1138        ("CoCStrongNormalization", coc_sn_ty()),
1139        ("PCFType", pcf_type_ty()),
1140        ("PCFTerm", pcf_term_ty()),
1141        ("PCFFixpoint", pcf_fixpoint_ty()),
1142        ("PCFTyping", pcf_typing_ty()),
1143        ("PCFDenotationalSemantics", pcf_denotational_semantics_ty()),
1144        ("PCFAdequacy", pcf_adequacy_ty()),
1145        ("PCFFullAbstraction", pcf_full_abstraction_ty()),
1146        ("SubtypeRelation", subtype_relation_ty()),
1147        ("SubtypingReflexivity", subtyping_reflexivity_ty()),
1148        ("SubtypingTransitivity", subtyping_transitivity_ty()),
1149        ("BoundedQuantification", bounded_quantification_ty()),
1150        ("FBoundedPolymorphism", f_bounded_polymorphism_ty()),
1151        ("CoercionFunction", coercion_function_ty()),
1152        (
1153            "SubtypingSubjectReduction",
1154            subtyping_subject_reduction_ty(),
1155        ),
1156        ("EffectLabel", effect_label_ty()),
1157        ("EffectSet", effect_set_ty()),
1158        ("EffectType", effect_type_ty()),
1159        ("EffectTyping", effect_typing_ty()),
1160        ("RegionType", region_type_ty()),
1161        ("RegionInference", region_inference_ty()),
1162        ("GradedType", graded_type_ty()),
1163        ("CoeffectSystem", coeffect_system_ty()),
1164        ("CoeffectTyping", coeffect_typing_ty()),
1165        ("LinearType", linear_type_ty()),
1166        ("LinearContext", linear_context_ty()),
1167        ("LinearTyping", linear_typing_ty()),
1168        ("LinearArrow", linear_arrow_ty()),
1169        ("LinearExchangeability", linear_exchangeability_ty()),
1170        ("AffineType", affine_type_ty()),
1171        ("AffineTyping", affine_typing_ty()),
1172        ("RelevantType", relevant_type_ty()),
1173        ("RelevantTyping", relevant_typing_ty()),
1174        ("BangModality", bang_modality_ty()),
1175        ("LFSignature", lf_signature_ty()),
1176        ("LFContext", lf_context_ty()),
1177        ("LFTyping", lf_typing_ty()),
1178        ("LFKindValidity", lf_kind_validity_ty()),
1179        ("UTTUniverse", utt_universe_ty()),
1180        ("UTTELType", utt_el_type_ty()),
1181        ("CICInductiveType", cic_inductive_type_ty()),
1182        ("CICElimination", cic_elimination_ty()),
1183        ("CICPositivityCondition", cic_positivity_condition_ty()),
1184        ("IntersectionType", intersection_type_ty()),
1185        ("IntersectionTyping", intersection_typing_ty()),
1186        ("FilterModel", filter_model_ty()),
1187        (
1188            "IntersectionTypeCompleteness",
1189            intersection_type_completeness_ty(),
1190        ),
1191        ("PrincipalTyping", principal_typing_ty()),
1192        ("UnionType", union_type_ty()),
1193        ("OccurrenceTyping", occurrence_typing_ty()),
1194        ("FlowAnalysis", flow_analysis_ty()),
1195        ("GradualType", gradual_type_ty()),
1196        ("DynType", dyn_type_ty()),
1197        ("TypeConsistency", type_consistency_ty()),
1198        ("GradualTyping", gradual_typing_ty()),
1199        ("BlameLabel", blame_label_ty()),
1200        ("BlameCalculusTerm", blame_calculus_term_ty()),
1201        ("BlameTheorem", blame_theorem_ty()),
1202        ("AbstractingGradualTyping", abstracting_gradual_typing_ty()),
1203        ("SessionType", session_type_ty()),
1204        ("SendType", send_type_ty()),
1205        ("RecvType", recv_type_ty()),
1206        ("EndType", end_type_ty()),
1207        ("DualSession", dual_session_ty()),
1208        ("BinarySessionTyping", binary_session_typing_ty()),
1209        ("MultipartySessionType", multiparty_session_type_ty()),
1210        ("GlobalToLocal", global_to_local_ty()),
1211        ("DeadlockFreedom", deadlock_freedom_ty()),
1212        ("SessionTypeCompleteness", session_type_completeness_ty()),
1213        ("RecursiveType", recursive_type_ty()),
1214        ("IsoRecursiveFold", iso_recursive_fold_ty()),
1215        ("IsoRecursiveUnfold", iso_recursive_unfold_ty()),
1216        ("EquiRecursiveType", equi_recursive_type_ty()),
1217        ("TypeUnrolling", type_unrolling_ty()),
1218        ("RecursiveTypeContraction", recursive_type_contraction_ty()),
1219        ("KindPolymorphism", kind_polymorphism_ty()),
1220        ("HigherKindedType", higher_kinded_type_ty()),
1221        ("KindInference", kind_inference_ty()),
1222        ("KindSoundness", kind_soundness_ty()),
1223        ("KindCompleteness", kind_completeness_ty()),
1224        ("RowType", row_type_ty()),
1225        ("ExtendRow", extend_row_ty()),
1226        ("EmptyRow", empty_row_ty()),
1227        ("RecordType", record_type_ty()),
1228        ("VariantType", variant_type_ty()),
1229        ("RowPolymorphicTyping", row_polymorphic_typing_ty()),
1230        ("StructuralSubtyping", structural_subtyping_ty()),
1231        ("SetoidCarrier", setoid_carrier_ty()),
1232        ("SetoidRelation", setoid_relation_ty()),
1233        ("Setoid", setoid_ty()),
1234        ("QuotientType", quotient_type_ty()),
1235        ("QuotientIntro", quotient_intro_ty()),
1236        ("QuotientElim", quotient_elim_ty()),
1237        ("QuotientComputation", quotient_computation_ty()),
1238        ("ProofIrrelevance", proof_irrelevance_ty()),
1239        ("IrrelevantArgument", irrelevant_argument_ty()),
1240        ("SquashType", squash_type_ty()),
1241        ("SquashIntro", squash_intro_ty()),
1242        ("SquashElim", squash_elim_ty()),
1243        ("UniverseLevel", universe_level_ty()),
1244        ("RussellUniverse", russell_universe_ty()),
1245        ("TarskiUniverse", tarski_universe_ty()),
1246        ("TarskiDecode", tarski_decode_ty()),
1247        ("CumulativeHierarchy", cumulative_hierarchy_ty()),
1248        ("UniversePolymorphism", universe_polymorphism_ty()),
1249        ("ResizingAxiom", resizing_axiom_ty()),
1250        ("DelimitedContinuation", delimited_continuation_ty()),
1251        ("MonadicType", monadic_type_ty()),
1252        ("MonadicTyping", monadic_typing_ty()),
1253        ("AlgebraicEffectType", algebraic_effect_type_ty()),
1254        ("HandlerType", handler_type_ty()),
1255        ("DependentSessionType", dependent_session_type_ty()),
1256        ("RefinementType", refinement_type_ty()),
1257        ("LiquidType", liquid_type_ty()),
1258        ("NominalType", nominal_type_ty()),
1259        ("FreshnessPredicate", freshness_predicate_ty()),
1260        ("AbstractionNominal", abstraction_nominal_ty()),
1261    ];
1262    for (name, ty) in axioms {
1263        env.add(Declaration::Axiom {
1264            name: Name::str(*name),
1265            univ_params: vec![],
1266            ty: ty.clone(),
1267        })
1268        .ok();
1269    }
1270    env
1271}
1272/// Build the Church numeral for `n`.
1273/// c_n = λf. λx. f^n x
1274pub fn church(n: usize) -> Term {
1275    let x = Term::Var(0);
1276    let f = Term::Var(1);
1277    let mut body = x;
1278    for _ in 0..n {
1279        body = Term::App(Box::new(f.clone()), Box::new(body));
1280    }
1281    Term::Lam(Box::new(Term::Lam(Box::new(body))))
1282}
1283/// Church successor: S = λn. λf. λx. f (n f x)
1284pub fn church_succ() -> Term {
1285    let n = Term::Var(2);
1286    let f = Term::Var(1);
1287    let x = Term::Var(0);
1288    let nfx = Term::App(
1289        Box::new(Term::App(Box::new(n), Box::new(f.clone()))),
1290        Box::new(x),
1291    );
1292    let body = Term::App(Box::new(f), Box::new(nfx));
1293    Term::Lam(Box::new(Term::Lam(Box::new(Term::Lam(Box::new(body))))))
1294}
1295/// Church addition: PLUS = λm. λn. λf. λx. m f (n f x)
1296pub fn church_plus() -> Term {
1297    let m = Term::Var(3);
1298    let n = Term::Var(2);
1299    let f = Term::Var(1);
1300    let x = Term::Var(0);
1301    let nfx = Term::App(
1302        Box::new(Term::App(Box::new(n), Box::new(f.clone()))),
1303        Box::new(x),
1304    );
1305    let body = Term::App(Box::new(Term::App(Box::new(m), Box::new(f))), Box::new(nfx));
1306    Term::Lam(Box::new(Term::Lam(Box::new(Term::Lam(Box::new(
1307        Term::Lam(Box::new(body)),
1308    ))))))
1309}
1310/// Church multiplication: MUL = λm. λn. λf. m (n f)
1311pub fn church_mul() -> Term {
1312    let m = Term::Var(2);
1313    let n = Term::Var(1);
1314    let f = Term::Var(0);
1315    let nf = Term::App(Box::new(n), Box::new(f));
1316    let body = Term::App(Box::new(m), Box::new(nf));
1317    Term::Lam(Box::new(Term::Lam(Box::new(Term::Lam(Box::new(body))))))
1318}
1319/// Apply PLUS to two Church numerals and reduce to normal form.
1320pub fn church_add(m: usize, n: usize) -> Term {
1321    let plus = church_plus();
1322    let cm = church(m);
1323    let cn = church(n);
1324    let applied = Term::App(
1325        Box::new(Term::App(Box::new(plus), Box::new(cm))),
1326        Box::new(cn),
1327    );
1328    let (result, _) = applied.normalize(10000);
1329    result
1330}
1331/// Type inference for the simply-typed lambda calculus (Curry style).
1332/// Returns `Some(ty)` if the term is typeable, `None` otherwise.
1333pub fn infer_type(ctx: &Context, term: &Term) -> Option<SimpleType> {
1334    match term {
1335        Term::Var(k) => ctx.get(*k).cloned(),
1336        Term::Lam(body) => {
1337            let _ = body;
1338            None
1339        }
1340        Term::App(f, a) => match infer_type(ctx, f)? {
1341            SimpleType::Arrow(dom, cod) => {
1342                if check_type(ctx, a, &dom) {
1343                    Some(*cod)
1344                } else {
1345                    None
1346                }
1347            }
1348            _ => None,
1349        },
1350    }
1351}
1352/// Type checking for the simply-typed lambda calculus.
1353/// Returns `true` iff `ctx ⊢ term : ty`.
1354pub fn check_type(ctx: &Context, term: &Term, ty: &SimpleType) -> bool {
1355    match (term, ty) {
1356        (Term::Lam(body), SimpleType::Arrow(dom, cod)) => {
1357            let ctx2 = ctx.extend(*dom.clone());
1358            check_type(&ctx2, body, cod)
1359        }
1360        (Term::App(f, a), _) => {
1361            if let Some(ft) = infer_type(ctx, f) {
1362                match ft {
1363                    SimpleType::Arrow(dom, cod) => *cod == *ty && check_type(ctx, a, &dom),
1364                    _ => false,
1365                }
1366            } else {
1367                false
1368            }
1369        }
1370        (Term::Var(k), _) => ctx.get(*k).map(|t| t == ty).unwrap_or(false),
1371        _ => false,
1372    }
1373}
1374/// Perform one-step β-reduction under the given strategy.
1375pub fn beta_step(term: &Term, strategy: Strategy) -> Option<Term> {
1376    match strategy {
1377        Strategy::NormalOrder => term.beta_step_normal(),
1378        Strategy::ApplicativeOrder => beta_step_applicative(term),
1379        Strategy::HeadReduction => beta_step_head(term),
1380    }
1381}
1382pub fn beta_step_applicative(term: &Term) -> Option<Term> {
1383    match term {
1384        Term::App(f, a) => {
1385            if let Some(a2) = beta_step_applicative(a) {
1386                return Some(Term::App(f.clone(), Box::new(a2)));
1387            }
1388            if let Some(f2) = beta_step_applicative(f) {
1389                return Some(Term::App(Box::new(f2), a.clone()));
1390            }
1391            if let Term::Lam(body) = f.as_ref() {
1392                return Some(body.subst(0, a));
1393            }
1394            None
1395        }
1396        Term::Lam(body) => beta_step_applicative(body).map(|b2| Term::Lam(Box::new(b2))),
1397        Term::Var(_) => None,
1398    }
1399}
1400pub fn beta_step_head(term: &Term) -> Option<Term> {
1401    match term {
1402        Term::App(f, a) => {
1403            if let Term::Lam(body) = f.as_ref() {
1404                return Some(body.subst(0, a));
1405            }
1406            beta_step_head(f).map(|f2| Term::App(Box::new(f2), a.clone()))
1407        }
1408        Term::Lam(body) => beta_step_head(body).map(|b2| Term::Lam(Box::new(b2))),
1409        Term::Var(_) => None,
1410    }
1411}
1412/// Result of linearity checking: a map from de Bruijn level → usage count.
1413#[allow(dead_code)]
1414pub type UsageMap = Vec<usize>;
1415#[cfg(test)]
1416mod tests {
1417    use super::*;
1418    /// Verify that the environment builds and contains key axioms.
1419    #[test]
1420    fn test_build_lambda_calculus_env() {
1421        let env = build_lambda_calculus_env();
1422        assert!(env.get(&Name::str("UntypedTerm")).is_some());
1423        assert!(env.get(&Name::str("YCombinator")).is_some());
1424        assert!(env.get(&Name::str("ChurchRosserTheorem")).is_some());
1425        assert!(env.get(&Name::str("SystemFStrongNormalization")).is_some());
1426        assert!(env.get(&Name::str("CoC")).is_some());
1427        assert!(env.get(&Name::str("BohmTheorem")).is_some());
1428    }
1429    /// Test Church numeral construction and normalization.
1430    #[test]
1431    fn test_church_numerals() {
1432        let c0 = church(0);
1433        assert_eq!(c0, Term::Lam(Box::new(Term::Lam(Box::new(Term::Var(0))))));
1434        let c1 = church(1);
1435        assert_eq!(
1436            c1,
1437            Term::Lam(Box::new(Term::Lam(Box::new(Term::App(
1438                Box::new(Term::Var(1)),
1439                Box::new(Term::Var(0))
1440            )))))
1441        );
1442        let c2 = church(2);
1443        assert!(c2.is_normal());
1444    }
1445    /// Test Church addition: 2 + 3 = 5.
1446    #[test]
1447    fn test_church_addition() {
1448        let result = church_add(2, 3);
1449        let expected = church(5);
1450        let (rn, _) = result.normalize(10000);
1451        let (en, _) = expected.normalize(10000);
1452        assert_eq!(rn, en);
1453    }
1454    /// Test beta-reduction: (λx.x) t →β t.
1455    #[test]
1456    fn test_identity_reduction() {
1457        let id = Term::Lam(Box::new(Term::Var(0)));
1458        let arg = Term::Var(0);
1459        let redex = Term::App(Box::new(id), Box::new(arg.clone()));
1460        let (result, steps) = redex.normalize(100);
1461        assert!(steps > 0);
1462        assert!(result.is_normal());
1463    }
1464    /// Test is_normal: variable and abstraction of variable are normal.
1465    #[test]
1466    fn test_is_normal() {
1467        assert!(Term::Var(0).is_normal());
1468        assert!(Term::Lam(Box::new(Term::Var(0))).is_normal());
1469        let redex = Term::App(
1470            Box::new(Term::Lam(Box::new(Term::Var(0)))),
1471            Box::new(Term::Var(1)),
1472        );
1473        assert!(!redex.is_normal());
1474    }
1475    /// Test type checking: identity function I : (α → α).
1476    #[test]
1477    fn test_stlc_identity() {
1478        let alpha = SimpleType::Base("α".into());
1479        let id = Term::Lam(Box::new(Term::Var(0)));
1480        let arrow_ty = SimpleType::arr(alpha.clone(), alpha.clone());
1481        let ctx = Context::empty();
1482        assert!(check_type(&ctx, &id, &arrow_ty));
1483    }
1484    /// Test type checking: K combinator K : α → β → α.
1485    #[test]
1486    fn test_stlc_k_combinator() {
1487        let alpha = SimpleType::Base("α".into());
1488        let beta = SimpleType::Base("β".into());
1489        let k = Term::Lam(Box::new(Term::Lam(Box::new(Term::Var(1)))));
1490        let ty = SimpleType::arr(alpha.clone(), SimpleType::arr(beta.clone(), alpha.clone()));
1491        let ctx = Context::empty();
1492        assert!(check_type(&ctx, &k, &ty));
1493    }
1494    /// Test reduction strategies: normal order vs. applicative order.
1495    #[test]
1496    fn test_reduction_strategies() {
1497        let id = || Term::Lam(Box::new(Term::Var(0)));
1498        let t = Term::App(
1499            Box::new(id()),
1500            Box::new(Term::App(Box::new(id()), Box::new(Term::Var(1)))),
1501        );
1502        assert!(!t.is_normal());
1503        let step_no = beta_step(&t, Strategy::NormalOrder);
1504        assert!(step_no.is_some());
1505        let step_ao = beta_step(&t, Strategy::ApplicativeOrder);
1506        assert!(step_ao.is_some());
1507    }
1508    /// Test that church(n) has correct size (2n+3 nodes).
1509    #[test]
1510    fn test_church_size() {
1511        assert_eq!(church(0).size(), 3);
1512        assert_eq!(church(1).size(), 5);
1513        let c3 = church(3);
1514        assert_eq!(c3.size(), 2 * 3 + 3);
1515    }
1516    /// Verify new axioms are registered in the environment.
1517    #[test]
1518    fn test_new_axioms_registered() {
1519        let env = build_lambda_calculus_env();
1520        assert!(env.get(&Name::str("PCFFixpoint")).is_some());
1521        assert!(env.get(&Name::str("PCFAdequacy")).is_some());
1522        assert!(env.get(&Name::str("BoundedQuantification")).is_some());
1523        assert!(env.get(&Name::str("FBoundedPolymorphism")).is_some());
1524        assert!(env.get(&Name::str("CoeffectSystem")).is_some());
1525        assert!(env.get(&Name::str("RegionInference")).is_some());
1526        assert!(env.get(&Name::str("LinearTyping")).is_some());
1527        assert!(env.get(&Name::str("BangModality")).is_some());
1528        assert!(env.get(&Name::str("AffineTyping")).is_some());
1529        assert!(env.get(&Name::str("LFTyping")).is_some());
1530        assert!(env.get(&Name::str("CICInductiveType")).is_some());
1531        assert!(env.get(&Name::str("FilterModel")).is_some());
1532        assert!(env.get(&Name::str("PrincipalTyping")).is_some());
1533        assert!(env.get(&Name::str("FlowAnalysis")).is_some());
1534        assert!(env.get(&Name::str("TypeConsistency")).is_some());
1535        assert!(env.get(&Name::str("BlameTheorem")).is_some());
1536        assert!(env.get(&Name::str("DualSession")).is_some());
1537        assert!(env.get(&Name::str("DeadlockFreedom")).is_some());
1538        assert!(env.get(&Name::str("MultipartySessionType")).is_some());
1539        assert!(env.get(&Name::str("IsoRecursiveFold")).is_some());
1540        assert!(env.get(&Name::str("TypeUnrolling")).is_some());
1541        assert!(env.get(&Name::str("KindPolymorphism")).is_some());
1542        assert!(env.get(&Name::str("HigherKindedType")).is_some());
1543        assert!(env.get(&Name::str("RecordType")).is_some());
1544        assert!(env.get(&Name::str("StructuralSubtyping")).is_some());
1545        assert!(env.get(&Name::str("QuotientType")).is_some());
1546        assert!(env.get(&Name::str("QuotientElim")).is_some());
1547        assert!(env.get(&Name::str("ProofIrrelevance")).is_some());
1548        assert!(env.get(&Name::str("SquashType")).is_some());
1549        assert!(env.get(&Name::str("RussellUniverse")).is_some());
1550        assert!(env.get(&Name::str("CumulativeHierarchy")).is_some());
1551        assert!(env.get(&Name::str("RefinementType")).is_some());
1552        assert!(env.get(&Name::str("NominalType")).is_some());
1553        assert!(env.get(&Name::str("AlgebraicEffectType")).is_some());
1554    }
1555    #[test]
1556    fn test_beta_reducer_converges() {
1557        let reducer = BetaReducer::new(Strategy::NormalOrder, 1000);
1558        let id = Term::Lam(Box::new(Term::Var(0)));
1559        let t = Term::App(Box::new(id), Box::new(Term::Var(0)));
1560        let (result, steps, converged) = reducer.reduce(&t);
1561        assert!(converged);
1562        assert!(steps >= 1);
1563        assert!(reducer.is_normal_form(&result));
1564    }
1565    #[test]
1566    fn test_beta_reducer_step_count() {
1567        let reducer = BetaReducer::new(Strategy::NormalOrder, 10000);
1568        let one_plus_one = church_add(1, 1);
1569        let steps_opt = reducer.count_steps(&one_plus_one);
1570        assert!(steps_opt.is_some());
1571    }
1572    #[test]
1573    fn test_alpha_equiv_identical() {
1574        let checker = AlphaEquivalenceChecker::new();
1575        let t = Term::Lam(Box::new(Term::Var(0)));
1576        assert!(checker.alpha_equiv(&t, &t));
1577    }
1578    #[test]
1579    fn test_alpha_equiv_different() {
1580        let checker = AlphaEquivalenceChecker::new();
1581        let t1 = Term::Lam(Box::new(Term::Var(0)));
1582        let t2 = Term::Lam(Box::new(Term::Var(1)));
1583        assert!(!checker.alpha_equiv(&t1, &t2));
1584    }
1585    #[test]
1586    fn test_alpha_equiv_normalized() {
1587        let checker = AlphaEquivalenceChecker::new();
1588        let id = Term::Lam(Box::new(Term::Var(0)));
1589        let t = Term::App(Box::new(id), Box::new(Term::Var(1)));
1590        let expected = Term::Var(1);
1591        assert!(checker.alpha_equiv_normalized(&t, &expected, 100));
1592    }
1593    #[test]
1594    fn test_type_inference_var() {
1595        let system = TypeInferenceSystem::new();
1596        let alpha = SimpleType::Base("α".into());
1597        let ctx = Context(vec![alpha.clone()]);
1598        assert_eq!(system.synthesize(&ctx, &Term::Var(0)), Some(alpha));
1599    }
1600    #[test]
1601    fn test_type_inference_app() {
1602        let system = TypeInferenceSystem::new();
1603        let alpha = SimpleType::Base("α".into());
1604        let beta = SimpleType::Base("β".into());
1605        let ctx = Context(vec![
1606            alpha.clone(),
1607            SimpleType::arr(alpha.clone(), beta.clone()),
1608        ]);
1609        let term = Term::App(Box::new(Term::Var(1)), Box::new(Term::Var(0)));
1610        assert_eq!(system.synthesize(&ctx, &term), Some(beta));
1611    }
1612    #[test]
1613    fn test_type_check_identity() {
1614        let system = TypeInferenceSystem::new();
1615        let alpha = SimpleType::Base("α".into());
1616        let id = Term::Lam(Box::new(Term::Var(0)));
1617        let ctx = Context::empty();
1618        assert!(system.check(&ctx, &id, &SimpleType::arr(alpha.clone(), alpha)));
1619    }
1620    #[test]
1621    fn test_type_inference_with_hint() {
1622        let system = TypeInferenceSystem::new();
1623        let alpha = SimpleType::Base("α".into());
1624        let id = Term::Lam(Box::new(Term::Var(0)));
1625        let ty = SimpleType::arr(alpha.clone(), alpha);
1626        let ctx = Context::empty();
1627        let result = system.infer_with_annotation(&ctx, &id, Some(&ty));
1628        assert!(result.is_some());
1629    }
1630    #[test]
1631    fn test_linear_identity_is_linear() {
1632        let checker = LinearTypeChecker::new();
1633        let id = Term::Lam(Box::new(Term::Var(0)));
1634        let uses = checker.count_uses(&id, 0);
1635        assert!(uses.is_empty());
1636        let uses_body = checker.count_uses(&Term::Var(0), 1);
1637        assert_eq!(uses_body, vec![1]);
1638    }
1639    #[test]
1640    fn test_linear_k_combinator_is_not_linear() {
1641        let checker = LinearTypeChecker::new();
1642        let body = Term::Var(1);
1643        let uses = checker.count_uses(&body, 2);
1644        assert_eq!(uses, vec![0, 1]);
1645        assert!(!checker.is_linear(&body, 2));
1646        assert!(checker.is_affine(&body, 2));
1647    }
1648    #[test]
1649    fn test_affine_vs_relevant() {
1650        let checker = LinearTypeChecker::new();
1651        let body = Term::App(
1652            Box::new(Term::App(Box::new(Term::Var(1)), Box::new(Term::Var(0)))),
1653            Box::new(Term::Var(0)),
1654        );
1655        let uses = checker.count_uses(&body, 2);
1656        assert_eq!(uses, vec![2, 1]);
1657        assert!(!checker.is_linear(&body, 2));
1658        assert!(!checker.is_affine(&body, 2));
1659        assert!(checker.is_relevant(&body, 2));
1660    }
1661    #[test]
1662    fn test_session_dual_send_recv() {
1663        let compat = SessionTypeCompatibility::new();
1664        let s = BinarySession::Send("Int".into(), Box::new(BinarySession::End));
1665        let dual = compat.dual(&s);
1666        assert_eq!(
1667            dual,
1668            BinarySession::Recv("Int".into(), Box::new(BinarySession::End))
1669        );
1670    }
1671    #[test]
1672    fn test_session_dual_involutive() {
1673        let compat = SessionTypeCompatibility::new();
1674        let s = BinarySession::Send(
1675            "Bool".into(),
1676            Box::new(BinarySession::Recv(
1677                "Int".into(),
1678                Box::new(BinarySession::End),
1679            )),
1680        );
1681        let d = compat.dual(&compat.dual(&s));
1682        assert_eq!(d, s);
1683    }
1684    #[test]
1685    fn test_session_compatible_send_recv() {
1686        let compat = SessionTypeCompatibility::new();
1687        let s1 = BinarySession::Send("Int".into(), Box::new(BinarySession::End));
1688        let s2 = BinarySession::Recv("Int".into(), Box::new(BinarySession::End));
1689        assert!(compat.compatible(&s1, &s2));
1690        assert!(compat.compatible(&s2, &s1));
1691    }
1692    #[test]
1693    fn test_session_incompatible_type_mismatch() {
1694        let compat = SessionTypeCompatibility::new();
1695        let s1 = BinarySession::Send("Int".into(), Box::new(BinarySession::End));
1696        let s2 = BinarySession::Recv("Bool".into(), Box::new(BinarySession::End));
1697        assert!(!compat.compatible(&s1, &s2));
1698    }
1699    #[test]
1700    fn test_session_compatible_end_end() {
1701        let compat = SessionTypeCompatibility::new();
1702        assert!(compat.compatible(&BinarySession::End, &BinarySession::End));
1703    }
1704    #[test]
1705    fn test_session_are_dual() {
1706        let compat = SessionTypeCompatibility::new();
1707        let s1 = BinarySession::Send("Nat".into(), Box::new(BinarySession::End));
1708        let s2 = BinarySession::Recv("Nat".into(), Box::new(BinarySession::End));
1709        assert!(compat.are_dual(&s1, &s2));
1710        assert!(compat.are_dual(&s2, &s1));
1711        assert!(!compat.are_dual(&s1, &s1));
1712    }
1713    #[test]
1714    fn test_session_select_offer_compatible() {
1715        let compat = SessionTypeCompatibility::new();
1716        let s1 = BinarySession::Select(vec![
1717            ("ok".into(), BinarySession::End),
1718            ("err".into(), BinarySession::End),
1719        ]);
1720        let s2 = BinarySession::Offer(vec![
1721            ("ok".into(), BinarySession::End),
1722            ("err".into(), BinarySession::End),
1723        ]);
1724        assert!(compat.compatible(&s1, &s2));
1725    }
1726}