Skip to main content

oxilean_std/env_builder/
functions_2.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4#![allow(clippy::items_after_test_module)]
5
6use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name, ReducibilityHint};
7
8use super::functions::*;
9use super::types::EnvBuilder;
10
11/// Add `RBMap` (ordered map).
12#[allow(dead_code)]
13pub fn add_rb_map(b: &mut EnvBuilder) {
14    if !b.contains("Ord") {
15        b.axiom("Ord", pi(type0(), prop()));
16    }
17    b.axiom("RBMap", pi(type0(), pi(type0(), type1())));
18    b.axiom(
19        "RBMap.empty",
20        pi_implicit(
21            "k",
22            type0(),
23            pi_implicit(
24                "v",
25                type0(),
26                pi(
27                    app(var("Ord"), bvar(1)),
28                    app(app(var("RBMap"), bvar(2)), bvar(1)),
29                ),
30            ),
31        ),
32    );
33    b.axiom(
34        "RBMap.insert",
35        pi_implicit(
36            "k",
37            type0(),
38            pi_implicit(
39                "v",
40                type0(),
41                pi(
42                    app(var("Ord"), bvar(1)),
43                    pi(
44                        bvar(2),
45                        pi(
46                            bvar(2),
47                            pi(
48                                app(app(var("RBMap"), bvar(4)), bvar(3)),
49                                app(app(var("RBMap"), bvar(5)), bvar(4)),
50                            ),
51                        ),
52                    ),
53                ),
54            ),
55        ),
56    );
57    b.axiom(
58        "RBMap.find",
59        pi_implicit(
60            "k",
61            type0(),
62            pi_implicit(
63                "v",
64                type0(),
65                pi(
66                    app(var("Ord"), bvar(1)),
67                    pi(
68                        bvar(2),
69                        pi(
70                            app(app(var("RBMap"), bvar(3)), bvar(2)),
71                            app(var("Option"), bvar(3)),
72                        ),
73                    ),
74                ),
75            ),
76        ),
77    );
78    b.axiom(
79        "RBMap.size",
80        pi_implicit(
81            "k",
82            type0(),
83            pi_implicit(
84                "v",
85                type0(),
86                pi_implicit(
87                    "_",
88                    app(var("Ord"), bvar(1)),
89                    pi(app(app(var("RBMap"), bvar(2)), bvar(1)), var("Nat")),
90                ),
91            ),
92        ),
93    );
94    b.axiom(
95        "RBMap.keys",
96        pi_implicit(
97            "k",
98            type0(),
99            pi_implicit(
100                "v",
101                type0(),
102                pi_implicit(
103                    "_",
104                    app(var("Ord"), bvar(1)),
105                    pi(
106                        app(app(var("RBMap"), bvar(2)), bvar(1)),
107                        app(var("List"), bvar(3)),
108                    ),
109                ),
110            ),
111        ),
112    );
113    b.axiom(
114        "RBMap.values",
115        pi_implicit(
116            "k",
117            type0(),
118            pi_implicit(
119                "v",
120                type0(),
121                pi_implicit(
122                    "_",
123                    app(var("Ord"), bvar(1)),
124                    pi(
125                        app(app(var("RBMap"), bvar(2)), bvar(1)),
126                        app(var("List"), bvar(1)),
127                    ),
128                ),
129            ),
130        ),
131    );
132}
133/// Add `Task` and concurrency primitives.
134#[allow(dead_code)]
135pub fn add_task(b: &mut EnvBuilder) {
136    b.axiom("Task", pi(type0(), type0()));
137    b.axiom(
138        "Task.pure",
139        pi_implicit("α", type0(), pi(bvar(0), app(var("Task"), bvar(1)))),
140    );
141    b.axiom(
142        "Task.bind",
143        pi_implicit(
144            "α",
145            type0(),
146            pi_implicit(
147                "β",
148                type0(),
149                pi(
150                    app(var("Task"), bvar(1)),
151                    pi(
152                        pi(bvar(2), app(var("Task"), bvar(2))),
153                        app(var("Task"), bvar(2)),
154                    ),
155                ),
156            ),
157        ),
158    );
159    b.axiom(
160        "Task.spawn",
161        pi_implicit(
162            "α",
163            type0(),
164            pi(pi(var("Unit"), bvar(1)), app(var("Task"), bvar(2))),
165        ),
166    );
167    b.axiom(
168        "Task.get",
169        pi_implicit("α", type0(), pi(app(var("Task"), bvar(0)), bvar(1))),
170    );
171    b.axiom(
172        "Task.map",
173        pi_implicit(
174            "α",
175            type0(),
176            pi_implicit(
177                "β",
178                type0(),
179                pi(
180                    pi(bvar(1), bvar(1)),
181                    pi(app(var("Task"), bvar(2)), app(var("Task"), bvar(2))),
182                ),
183            ),
184        ),
185    );
186    b.axiom(
187        "Task.cancel",
188        pi_implicit("α", type0(), pi(app(var("Task"), bvar(0)), var("Unit"))),
189    );
190}
191/// Add `ST` (state thread) monad.
192#[allow(dead_code)]
193pub fn add_st_monad(b: &mut EnvBuilder) {
194    b.axiom("ST", pi(type0(), pi(type0(), type0())));
195    b.axiom("STRef", pi(type0(), pi(type0(), type0())));
196    b.axiom(
197        "ST.run",
198        pi_implicit(
199            "α",
200            type0(),
201            pi(
202                pi_implicit("s", type0(), app(app(var("ST"), bvar(1)), bvar(1))),
203                bvar(1),
204            ),
205        ),
206    );
207    b.axiom(
208        "STRef.new",
209        pi_implicit(
210            "s",
211            type0(),
212            pi_implicit(
213                "α",
214                type0(),
215                pi(
216                    bvar(0),
217                    app(
218                        app(var("ST"), bvar(2)),
219                        app(app(var("STRef"), bvar(2)), bvar(1)),
220                    ),
221                ),
222            ),
223        ),
224    );
225    b.axiom(
226        "STRef.read",
227        pi_implicit(
228            "s",
229            type0(),
230            pi_implicit(
231                "α",
232                type0(),
233                pi(
234                    app(app(var("STRef"), bvar(1)), bvar(0)),
235                    app(app(var("ST"), bvar(2)), bvar(1)),
236                ),
237            ),
238        ),
239    );
240    b.axiom(
241        "STRef.write",
242        pi_implicit(
243            "s",
244            type0(),
245            pi_implicit(
246                "α",
247                type0(),
248                pi(
249                    app(app(var("STRef"), bvar(1)), bvar(0)),
250                    pi(bvar(1), app(app(var("ST"), bvar(3)), var("Unit"))),
251                ),
252            ),
253        ),
254    );
255    b.axiom(
256        "STRef.modify",
257        pi_implicit(
258            "s",
259            type0(),
260            pi_implicit(
261                "α",
262                type0(),
263                pi(
264                    app(app(var("STRef"), bvar(1)), bvar(0)),
265                    pi(
266                        pi(bvar(1), bvar(2)),
267                        app(app(var("ST"), bvar(3)), var("Unit")),
268                    ),
269                ),
270            ),
271        ),
272    );
273}
274/// Register a simple unary type constructor: `Name : Type 0 → Type 0`.
275#[allow(dead_code)]
276pub fn add_unary_type_ctor(b: &mut EnvBuilder, name: &str) {
277    b.axiom(name, pi(type0(), type0()));
278}
279/// Register a binary type constructor: `Name : Type 0 → Type 0 → Type 0`.
280#[allow(dead_code)]
281pub fn add_binary_type_ctor(b: &mut EnvBuilder, name: &str) {
282    b.axiom(name, pi(type0(), pi(type0(), type0())));
283}
284/// Batch-register unary type constructors.
285#[allow(dead_code)]
286pub fn add_unary_type_ctors(b: &mut EnvBuilder, names: &[&str]) {
287    for &n in names {
288        add_unary_type_ctor(b, n);
289    }
290}
291/// Batch-register binary type constructors.
292#[allow(dead_code)]
293pub fn add_binary_type_ctors(b: &mut EnvBuilder, names: &[&str]) {
294    for &n in names {
295        add_binary_type_ctor(b, n);
296    }
297}
298/// Add `OfNat` / `OfScientific` numeric literal helpers.
299#[allow(dead_code)]
300pub fn add_numeric_literals(b: &mut EnvBuilder) {
301    b.axiom("OfScientific", pi(type0(), prop()));
302    b.axiom(
303        "OfScientific.ofScientific",
304        pi_implicit(
305            "α",
306            type0(),
307            pi(
308                app(var("OfScientific"), bvar(0)),
309                pi(var("Nat"), pi(var("Bool"), pi(var("Nat"), bvar(3)))),
310            ),
311        ),
312    );
313    b.axiom("OfNat", pi(type0(), pi(var("Nat"), prop())));
314    b.axiom(
315        "OfNat.ofNat",
316        pi_implicit(
317            "α",
318            type0(),
319            pi_implicit(
320                "n",
321                var("Nat"),
322                pi(app(app(var("OfNat"), bvar(1)), bvar(0)), bvar(2)),
323            ),
324        ),
325    );
326}
327/// Add `Decidable` type class.
328#[allow(dead_code)]
329pub fn add_decidable_ext(b: &mut EnvBuilder) {
330    if !b.contains("Decidable") {
331        b.axiom("Decidable", pi(prop(), type0()));
332    }
333    b.axiom(
334        "Decidable.isTrue",
335        pi_named("p", prop(), pi(bvar(0), app(var("Decidable"), bvar(1)))),
336    );
337    b.axiom(
338        "Decidable.isFalse",
339        pi_named(
340            "p",
341            prop(),
342            pi(app(var("Not"), bvar(0)), app(var("Decidable"), bvar(1))),
343        ),
344    );
345    b.axiom(
346        "decide",
347        pi_named("p", prop(), pi(app(var("Decidable"), bvar(0)), var("Bool"))),
348    );
349    b.axiom(
350        "Decidable.decide",
351        pi_named("p", prop(), pi(app(var("Decidable"), bvar(0)), var("Bool"))),
352    );
353    b.axiom(
354        "instDecidableAnd",
355        pi_named(
356            "p",
357            prop(),
358            pi_named(
359                "q",
360                prop(),
361                pi(
362                    app(var("Decidable"), bvar(1)),
363                    pi(
364                        app(var("Decidable"), bvar(1)),
365                        app(var("Decidable"), app(app(var("And"), bvar(3)), bvar(2))),
366                    ),
367                ),
368            ),
369        ),
370    );
371    b.axiom(
372        "instDecidableOr",
373        pi_named(
374            "p",
375            prop(),
376            pi_named(
377                "q",
378                prop(),
379                pi(
380                    app(var("Decidable"), bvar(1)),
381                    pi(
382                        app(var("Decidable"), bvar(1)),
383                        app(var("Decidable"), app(app(var("Or"), bvar(3)), bvar(2))),
384                    ),
385                ),
386            ),
387        ),
388    );
389    b.axiom(
390        "instDecidableNot",
391        pi_named(
392            "p",
393            prop(),
394            pi(
395                app(var("Decidable"), bvar(0)),
396                app(var("Decidable"), app(var("Not"), bvar(1))),
397            ),
398        ),
399    );
400    b.axiom(
401        "instDecidableEqNat",
402        pi_named(
403            "a",
404            var("Nat"),
405            pi_named(
406                "b",
407                var("Nat"),
408                app(var("Decidable"), app(app(var("Eq"), bvar(1)), bvar(0))),
409            ),
410        ),
411    );
412    b.axiom(
413        "instDecidableEqBool",
414        pi_named(
415            "a",
416            var("Bool"),
417            pi_named(
418                "b",
419                var("Bool"),
420                app(var("Decidable"), app(app(var("Eq"), bvar(1)), bvar(0))),
421            ),
422        ),
423    );
424}
425/// Add `Classical` logic axioms.
426#[allow(dead_code)]
427pub fn add_classical(b: &mut EnvBuilder) {
428    b.axiom("Nonempty", pi(type0(), prop()));
429    b.axiom(
430        "Nonempty.intro",
431        pi_implicit("α", type0(), pi(bvar(0), app(var("Nonempty"), bvar(1)))),
432    );
433    b.axiom(
434        "Classical.em",
435        pi_named(
436            "p",
437            prop(),
438            app(app(var("Or"), bvar(0)), app(var("Not"), bvar(0))),
439        ),
440    );
441    b.axiom(
442        "Classical.choice",
443        pi_implicit("α", type0(), pi(app(var("Nonempty"), bvar(0)), bvar(1))),
444    );
445    b.axiom(
446        "Classical.propDecidable",
447        pi_named("p", prop(), app(var("Decidable"), bvar(0))),
448    );
449    b.axiom(
450        "Classical.byContradiction",
451        pi_named(
452            "p",
453            prop(),
454            pi(pi(app(var("Not"), bvar(0)), var("False")), bvar(1)),
455        ),
456    );
457    b.axiom(
458        "Classical.not_not",
459        pi_named(
460            "p",
461            prop(),
462            pi(app(var("Not"), app(var("Not"), bvar(0))), bvar(1)),
463        ),
464    );
465    b.axiom(
466        "Classical.axiomOfChoice",
467        pi_implicit(
468            "α",
469            type0(),
470            pi_implicit(
471                "β",
472                pi(bvar(0), type0()),
473                pi(
474                    pi_implicit("x", bvar(1), app(var("Nonempty"), app(bvar(1), bvar(0)))),
475                    pi_named(
476                        "f",
477                        pi(bvar(2), app(bvar(2), bvar(1))),
478                        pi_implicit(
479                            "x",
480                            bvar(3),
481                            app(app(bvar(3), bvar(2)), app(bvar(1), bvar(0))),
482                        ),
483                    ),
484                ),
485            ),
486        ),
487    );
488}
489/// Build a complete standard environment with all core primitives.
490#[allow(dead_code)]
491pub fn build_full_std_env() -> EnvBuilder {
492    let mut b = EnvBuilder::fresh();
493    add_empty(&mut b);
494    add_unit_full(&mut b);
495    add_bool(&mut b);
496    add_list(&mut b);
497    add_prod(&mut b);
498    add_array(&mut b);
499    add_hashmap(&mut b);
500    add_io(&mut b);
501    add_eq(&mut b);
502    add_prop_logic(&mut b);
503    add_nat_arith(&mut b);
504    add_int_arith(&mut b);
505    add_float_ops(&mut b);
506    add_string_ops(&mut b);
507    add_char_ops(&mut b);
508    add_option(&mut b);
509    add_result(&mut b);
510    add_ordering(&mut b);
511    add_format(&mut b);
512    add_fin(&mut b);
513    add_sigma(&mut b);
514    add_subtype(&mut b);
515    add_well_founded(&mut b);
516    add_type_classes(&mut b);
517    add_decidable(&mut b);
518    add_classical(&mut b);
519    b
520}
521#[cfg(test)]
522mod extended_tests {
523    use super::*;
524    #[test]
525    fn test_add_eq_extended() {
526        let mut b = EnvBuilder::fresh();
527        add_eq(&mut b);
528        assert!(b.contains("Eq"));
529        assert!(b.contains("Eq.refl"));
530    }
531    #[test]
532    fn test_add_prop_logic() {
533        let mut b = EnvBuilder::fresh();
534        add_prop_logic(&mut b);
535        assert!(b.contains("True"));
536        assert!(b.contains("False"));
537        assert!(b.contains("And"));
538        assert!(b.contains("Or"));
539        assert!(b.contains("Not"));
540        assert!(b.contains("Iff"));
541        assert!(b.contains("And.intro"));
542        assert!(b.contains("And.left"));
543        assert!(b.contains("And.right"));
544    }
545    #[test]
546    fn test_add_nat_arith() {
547        let mut b = EnvBuilder::fresh();
548        add_nat_arith(&mut b);
549        assert!(b.contains("Nat"));
550        assert!(b.contains("Nat.zero"));
551        assert!(b.contains("Nat.succ"));
552        assert!(b.contains("Nat.add"));
553        assert!(b.contains("Nat.mul"));
554        assert!(b.contains("Nat.factorial"));
555    }
556    #[test]
557    fn test_add_option() {
558        let mut b = EnvBuilder::fresh();
559        add_option(&mut b);
560        assert!(b.contains("Option"));
561        assert!(b.contains("Option.none"));
562        assert!(b.contains("Option.some"));
563        assert!(b.contains("Option.map"));
564        assert!(b.contains("Option.bind"));
565        assert!(b.contains("Option.isSome"));
566    }
567    #[test]
568    fn test_add_result() {
569        let mut b = EnvBuilder::fresh();
570        add_result(&mut b);
571        assert!(b.contains("Result"));
572        assert!(b.contains("Result.ok"));
573        assert!(b.contains("Result.err"));
574        assert!(b.contains("Result.isOk"));
575        assert!(b.contains("Result.isErr"));
576    }
577    #[test]
578    fn test_add_vector() {
579        let mut b = EnvBuilder::fresh();
580        add_vector(&mut b);
581        assert!(b.contains("Vector"));
582        assert!(b.contains("Vector.nil"));
583        assert!(b.contains("Vector.cons"));
584        assert!(b.contains("Vector.head"));
585        assert!(b.contains("Vector.tail"));
586        assert!(b.contains("Vector.map"));
587        assert!(b.contains("Vector.append"));
588    }
589    #[test]
590    fn test_add_fin() {
591        let mut b = EnvBuilder::fresh();
592        add_nat_arith(&mut b);
593        add_fin(&mut b);
594        assert!(b.contains("Fin"));
595        assert!(b.contains("Fin.mk"));
596        assert!(b.contains("Fin.val"));
597        assert!(b.contains("Fin.zero"));
598    }
599    #[test]
600    fn test_add_sigma() {
601        let mut b = EnvBuilder::fresh();
602        add_sigma(&mut b);
603        assert!(b.contains("Sigma"));
604        assert!(b.contains("Sigma.mk"));
605        assert!(b.contains("Sigma.fst"));
606        assert!(b.contains("Sigma.snd"));
607    }
608    #[test]
609    fn test_add_subtype() {
610        let mut b = EnvBuilder::fresh();
611        add_subtype(&mut b);
612        assert!(b.contains("Subtype"));
613        assert!(b.contains("Subtype.mk"));
614        assert!(b.contains("Subtype.val"));
615        assert!(b.contains("Subtype.property"));
616    }
617    #[test]
618    fn test_add_ordering() {
619        let mut b = EnvBuilder::fresh();
620        add_ordering(&mut b);
621        assert!(b.contains("Ordering"));
622        assert!(b.contains("Ordering.lt"));
623        assert!(b.contains("Ordering.eq"));
624        assert!(b.contains("Ordering.gt"));
625    }
626    #[test]
627    fn test_add_type_classes() {
628        let mut b = EnvBuilder::fresh();
629        add_type_classes(&mut b);
630        assert!(b.contains("Functor"));
631        assert!(b.contains("Applicative"));
632        assert!(b.contains("Monad"));
633        assert!(b.contains("Monad.pure"));
634        assert!(b.contains("Monad.bind"));
635        assert!(b.contains("Ord"));
636        assert!(b.contains("BEq"));
637        assert!(b.contains("Hashable"));
638        assert!(b.contains("ToString"));
639    }
640    #[test]
641    fn test_add_state_monad() {
642        let mut b = EnvBuilder::fresh();
643        add_state_monad(&mut b);
644        assert!(b.contains("StateT"));
645        assert!(b.contains("StateT.pure"));
646        assert!(b.contains("StateT.bind"));
647        assert!(b.contains("StateT.get"));
648        assert!(b.contains("StateT.set"));
649        assert!(b.contains("StateT.run"));
650    }
651    #[test]
652    fn test_add_rb_tree() {
653        let mut b = EnvBuilder::fresh();
654        add_type_classes(&mut b);
655        add_rb_tree(&mut b);
656        assert!(b.contains("RBTree"));
657        assert!(b.contains("RBTree.empty"));
658        assert!(b.contains("RBTree.insert"));
659        assert!(b.contains("RBTree.find"));
660        assert!(b.contains("RBTree.contains"));
661    }
662    #[test]
663    fn test_add_decidable() {
664        let mut b = EnvBuilder::fresh();
665        add_prop_logic(&mut b);
666        add_decidable(&mut b);
667        assert!(b.contains("Decidable"));
668        assert!(b.contains("Decidable.isTrue"));
669        assert!(b.contains("Decidable.isFalse"));
670        assert!(b.contains("decide"));
671        assert!(b.contains("instDecidableAnd"));
672    }
673    #[test]
674    fn test_add_classical() {
675        let mut b = EnvBuilder::fresh();
676        add_prop_logic(&mut b);
677        add_classical(&mut b);
678        assert!(b.contains("Classical.em"));
679        assert!(b.contains("Classical.choice"));
680        assert!(b.contains("Classical.byContradiction"));
681        assert!(b.contains("Nonempty"));
682    }
683    #[test]
684    fn test_build_full_std_env() {
685        let b = build_full_std_env();
686        assert!(b.is_ok(), "full std env errors: {:?}", b.errors());
687        assert!(b.contains("Nat"));
688        assert!(b.contains("List"));
689        assert!(b.contains("Option"));
690        assert!(b.contains("And"));
691        assert!(b.contains("Monad"));
692    }
693    #[test]
694    fn test_pi_chain() {
695        let ty = pi_chain(vec![var("Nat"), var("Nat")], var("Nat"));
696        assert!(matches!(ty, Expr::Pi(_, _, _, _)));
697    }
698    #[test]
699    fn test_app_n() {
700        let f = var("f");
701        let result = app_n(f, vec![var("a"), var("b"), var("c")]);
702        assert!(matches!(result, Expr::App(_, _)));
703    }
704    #[test]
705    fn test_lam_ext() {
706        let _l = lam_ext("x", var("Nat"), bvar(0));
707    }
708    #[test]
709    fn test_sort_levels() {
710        let _t0 = type0();
711        let _t1 = type1();
712        let _su = sort_u();
713        let _sv = sort_v();
714        let _s5 = sort(5);
715    }
716    #[test]
717    fn test_add_float_ops() {
718        let mut b = EnvBuilder::fresh();
719        add_float_ops(&mut b);
720        assert!(b.contains("Float"));
721        assert!(b.contains("Float.sqrt"));
722        assert!(b.contains("Float.exp"));
723        assert!(b.contains("Float.sin"));
724        assert!(b.contains("Float.cos"));
725        assert!(b.contains("Float.isNaN"));
726    }
727    #[test]
728    fn test_add_st_monad() {
729        let mut b = EnvBuilder::fresh();
730        add_st_monad(&mut b);
731        assert!(b.contains("ST"));
732        assert!(b.contains("STRef"));
733        assert!(b.contains("ST.run"));
734        assert!(b.contains("STRef.new"));
735        assert!(b.contains("STRef.read"));
736        assert!(b.contains("STRef.write"));
737    }
738    #[test]
739    fn test_add_task() {
740        let mut b = EnvBuilder::fresh();
741        add_task(&mut b);
742        assert!(b.contains("Task"));
743        assert!(b.contains("Task.pure"));
744        assert!(b.contains("Task.bind"));
745        assert!(b.contains("Task.spawn"));
746        assert!(b.contains("Task.get"));
747    }
748    #[test]
749    fn test_add_format() {
750        let mut b = EnvBuilder::fresh();
751        add_format(&mut b);
752        assert!(b.contains("Format"));
753        assert!(b.contains("Format.nil"));
754        assert!(b.contains("Format.text"));
755        assert!(b.contains("Format.pretty"));
756    }
757    #[test]
758    fn test_env_builder_errors() {
759        let b = EnvBuilder::fresh();
760        assert!(b.is_ok());
761        assert!(b.errors().is_empty());
762    }
763    #[test]
764    fn test_add_quotient() {
765        let mut b = EnvBuilder::fresh();
766        add_quotient(&mut b);
767        assert!(b.contains("Setoid"));
768        assert!(b.contains("Quotient"));
769        assert!(b.contains("Quotient.mk"));
770        assert!(b.contains("Quotient.lift"));
771    }
772    #[test]
773    fn test_add_well_founded() {
774        let mut b = EnvBuilder::fresh();
775        add_well_founded(&mut b);
776        assert!(b.contains("WellFounded"));
777        assert!(b.contains("WellFounded.rec"));
778        assert!(b.contains("Acc"));
779        assert!(b.contains("Acc.intro"));
780    }
781}
782/// Add `Sum` (coproduct / disjoint union) type with `.inl` and `.inr`.
783#[allow(dead_code)]
784pub fn add_sum(b: &mut EnvBuilder) {
785    b.axiom("Sum", pi(type0(), pi(type0(), type0())));
786    b.axiom(
787        "Sum.inl",
788        pi_implicit(
789            "α",
790            type0(),
791            pi_implicit(
792                "β",
793                type0(),
794                pi(bvar(1), app(app(var("Sum"), bvar(2)), bvar(1))),
795            ),
796        ),
797    );
798    b.axiom(
799        "Sum.inr",
800        pi_implicit(
801            "α",
802            type0(),
803            pi_implicit(
804                "β",
805                type0(),
806                pi(bvar(0), app(app(var("Sum"), bvar(2)), bvar(1))),
807            ),
808        ),
809    );
810    b.axiom(
811        "Sum.elim",
812        pi_implicit(
813            "α",
814            type0(),
815            pi_implicit(
816                "β",
817                type0(),
818                pi_implicit(
819                    "γ",
820                    type0(),
821                    pi(
822                        pi(bvar(2), bvar(2)),
823                        pi(
824                            pi(bvar(2), bvar(2)),
825                            pi(app(app(var("Sum"), bvar(4)), bvar(3)), bvar(3)),
826                        ),
827                    ),
828                ),
829            ),
830        ),
831    );
832    b.axiom(
833        "Sum.isLeft",
834        pi_implicit(
835            "α",
836            type0(),
837            pi_implicit(
838                "β",
839                type0(),
840                pi(app(app(var("Sum"), bvar(1)), bvar(0)), var("Bool")),
841            ),
842        ),
843    );
844    b.axiom(
845        "Sum.isRight",
846        pi_implicit(
847            "α",
848            type0(),
849            pi_implicit(
850                "β",
851                type0(),
852                pi(app(app(var("Sum"), bvar(1)), bvar(0)), var("Bool")),
853            ),
854        ),
855    );
856}
857/// Add `Prod.fst` and `Prod.snd` accessors (extends `add_prod`).
858#[allow(dead_code)]
859pub fn add_prod_accessors(b: &mut EnvBuilder) {
860    if !b.contains("Prod") {
861        add_prod(b);
862    }
863    b.axiom(
864        "Prod.fst",
865        pi_implicit(
866            "α",
867            type0(),
868            pi_implicit(
869                "β",
870                type0(),
871                pi(app(app(var("Prod"), bvar(1)), bvar(0)), bvar(2)),
872            ),
873        ),
874    );
875    b.axiom(
876        "Prod.snd",
877        pi_implicit(
878            "α",
879            type0(),
880            pi_implicit(
881                "β",
882                type0(),
883                pi(app(app(var("Prod"), bvar(1)), bvar(0)), bvar(1)),
884            ),
885        ),
886    );
887    b.axiom(
888        "Prod.map",
889        pi_implicit(
890            "α",
891            type0(),
892            pi_implicit(
893                "β",
894                type0(),
895                pi_implicit(
896                    "γ",
897                    type0(),
898                    pi_implicit(
899                        "δ",
900                        type0(),
901                        pi(
902                            pi(bvar(3), bvar(3)),
903                            pi(
904                                pi(bvar(2), bvar(2)),
905                                pi(
906                                    app(app(var("Prod"), bvar(4)), bvar(3)),
907                                    app(app(var("Prod"), bvar(4)), bvar(3)),
908                                ),
909                            ),
910                        ),
911                    ),
912                ),
913            ),
914        ),
915    );
916    b.axiom(
917        "Prod.swap",
918        pi_implicit(
919            "α",
920            type0(),
921            pi_implicit(
922                "β",
923                type0(),
924                pi(
925                    app(app(var("Prod"), bvar(1)), bvar(0)),
926                    app(app(var("Prod"), bvar(1)), bvar(2)),
927                ),
928            ),
929        ),
930    );
931}
932/// Add extended list operations beyond `nil`/`cons`.
933#[allow(dead_code)]
934pub fn add_list_ext(b: &mut EnvBuilder) {
935    if !b.contains("List") {
936        add_list(b);
937    }
938    b.axiom(
939        "List.length",
940        pi_implicit("α", type0(), pi(app(var("List"), bvar(0)), var("Nat"))),
941    );
942    b.axiom(
943        "List.append",
944        pi_implicit(
945            "α",
946            type0(),
947            pi(
948                app(var("List"), bvar(0)),
949                pi(app(var("List"), bvar(1)), app(var("List"), bvar(2))),
950            ),
951        ),
952    );
953    b.axiom(
954        "List.head",
955        pi_implicit(
956            "α",
957            type0(),
958            pi(app(var("List"), bvar(0)), app(var("Option"), bvar(1))),
959        ),
960    );
961    b.axiom(
962        "List.tail",
963        pi_implicit(
964            "α",
965            type0(),
966            pi(app(var("List"), bvar(0)), app(var("List"), bvar(1))),
967        ),
968    );
969    b.axiom(
970        "List.get",
971        pi_implicit(
972            "α",
973            type0(),
974            pi(
975                app(var("List"), bvar(0)),
976                pi(var("Nat"), app(var("Option"), bvar(2))),
977            ),
978        ),
979    );
980    b.axiom(
981        "List.map",
982        pi_implicit(
983            "α",
984            type0(),
985            pi_implicit(
986                "β",
987                type0(),
988                pi(
989                    pi(bvar(1), bvar(1)),
990                    pi(app(var("List"), bvar(2)), app(var("List"), bvar(2))),
991                ),
992            ),
993        ),
994    );
995    b.axiom(
996        "List.filter",
997        pi_implicit(
998            "α",
999            type0(),
1000            pi(
1001                pi(bvar(0), var("Bool")),
1002                pi(app(var("List"), bvar(1)), app(var("List"), bvar(2))),
1003            ),
1004        ),
1005    );
1006    b.axiom(
1007        "List.foldl",
1008        pi_implicit(
1009            "α",
1010            type0(),
1011            pi_implicit(
1012                "β",
1013                type0(),
1014                pi(
1015                    bvar(1),
1016                    pi(
1017                        pi(bvar(2), pi(bvar(3), bvar(3))),
1018                        pi(app(var("List"), bvar(3)), bvar(3)),
1019                    ),
1020                ),
1021            ),
1022        ),
1023    );
1024    b.axiom(
1025        "List.foldr",
1026        pi_implicit(
1027            "α",
1028            type0(),
1029            pi_implicit(
1030                "β",
1031                type0(),
1032                pi(
1033                    bvar(1),
1034                    pi(
1035                        pi(bvar(2), pi(bvar(2), bvar(2))),
1036                        pi(app(var("List"), bvar(3)), bvar(2)),
1037                    ),
1038                ),
1039            ),
1040        ),
1041    );
1042    b.axiom(
1043        "List.reverse",
1044        pi_implicit(
1045            "α",
1046            type0(),
1047            pi(app(var("List"), bvar(0)), app(var("List"), bvar(1))),
1048        ),
1049    );
1050    b.axiom(
1051        "List.zip",
1052        pi_implicit(
1053            "α",
1054            type0(),
1055            pi_implicit(
1056                "β",
1057                type0(),
1058                pi(
1059                    app(var("List"), bvar(1)),
1060                    pi(
1061                        app(var("List"), bvar(1)),
1062                        app(var("List"), app(app(var("Prod"), bvar(2)), bvar(2))),
1063                    ),
1064                ),
1065            ),
1066        ),
1067    );
1068    b.axiom(
1069        "List.join",
1070        pi_implicit(
1071            "α",
1072            type0(),
1073            pi(
1074                app(var("List"), app(var("List"), bvar(0))),
1075                app(var("List"), bvar(1)),
1076            ),
1077        ),
1078    );
1079    b.axiom(
1080        "List.any",
1081        pi_implicit(
1082            "α",
1083            type0(),
1084            pi(
1085                pi(bvar(0), var("Bool")),
1086                pi(app(var("List"), bvar(1)), var("Bool")),
1087            ),
1088        ),
1089    );
1090    b.axiom(
1091        "List.all",
1092        pi_implicit(
1093            "α",
1094            type0(),
1095            pi(
1096                pi(bvar(0), var("Bool")),
1097                pi(app(var("List"), bvar(1)), var("Bool")),
1098            ),
1099        ),
1100    );
1101    b.axiom(
1102        "List.find",
1103        pi_implicit(
1104            "α",
1105            type0(),
1106            pi(
1107                pi(bvar(0), var("Bool")),
1108                pi(app(var("List"), bvar(1)), app(var("Option"), bvar(2))),
1109            ),
1110        ),
1111    );
1112    b.axiom(
1113        "List.partition",
1114        pi_implicit(
1115            "α",
1116            type0(),
1117            pi(
1118                pi(bvar(0), var("Bool")),
1119                pi(
1120                    app(var("List"), bvar(1)),
1121                    app(
1122                        app(var("Prod"), app(var("List"), bvar(2))),
1123                        app(var("List"), bvar(2)),
1124                    ),
1125                ),
1126            ),
1127        ),
1128    );
1129    b.axiom(
1130        "List.take",
1131        pi_implicit(
1132            "α",
1133            type0(),
1134            pi(
1135                var("Nat"),
1136                pi(app(var("List"), bvar(1)), app(var("List"), bvar(2))),
1137            ),
1138        ),
1139    );
1140    b.axiom(
1141        "List.drop",
1142        pi_implicit(
1143            "α",
1144            type0(),
1145            pi(
1146                var("Nat"),
1147                pi(app(var("List"), bvar(1)), app(var("List"), bvar(2))),
1148            ),
1149        ),
1150    );
1151    b.axiom(
1152        "List.splitAt",
1153        pi_implicit(
1154            "α",
1155            type0(),
1156            pi(
1157                var("Nat"),
1158                pi(
1159                    app(var("List"), bvar(1)),
1160                    app(
1161                        app(var("Prod"), app(var("List"), bvar(2))),
1162                        app(var("List"), bvar(2)),
1163                    ),
1164                ),
1165            ),
1166        ),
1167    );
1168    b.axiom(
1169        "List.flatten",
1170        pi_implicit(
1171            "α",
1172            type0(),
1173            pi(
1174                app(var("List"), app(var("List"), bvar(0))),
1175                app(var("List"), bvar(1)),
1176            ),
1177        ),
1178    );
1179    b.axiom(
1180        "List.contains",
1181        pi_implicit(
1182            "α",
1183            type0(),
1184            pi(
1185                app(var("BEq"), bvar(0)),
1186                pi(bvar(1), pi(app(var("List"), bvar(2)), var("Bool"))),
1187            ),
1188        ),
1189    );
1190    b.axiom(
1191        "List.eraseFirst",
1192        pi_implicit(
1193            "α",
1194            type0(),
1195            pi(
1196                app(var("BEq"), bvar(0)),
1197                pi(
1198                    bvar(1),
1199                    pi(app(var("List"), bvar(2)), app(var("List"), bvar(3))),
1200                ),
1201            ),
1202        ),
1203    );
1204    b.axiom(
1205        "List.enum",
1206        pi_implicit(
1207            "α",
1208            type0(),
1209            pi(
1210                app(var("List"), bvar(0)),
1211                app(var("List"), app(app(var("Prod"), var("Nat")), bvar(1))),
1212            ),
1213        ),
1214    );
1215    b.axiom("List.range", pi(var("Nat"), app(var("List"), var("Nat"))));
1216    b.axiom("List.iota", pi(var("Nat"), app(var("List"), var("Nat"))));
1217    b.axiom(
1218        "List.replicate",
1219        pi_implicit(
1220            "α",
1221            type0(),
1222            pi(var("Nat"), pi(bvar(1), app(var("List"), bvar(2)))),
1223        ),
1224    );
1225}
1226/// Add `Array` extended operations.
1227#[allow(dead_code)]
1228pub fn add_array_ext(b: &mut EnvBuilder) {
1229    if !b.contains("Array") {
1230        add_array(b);
1231    }
1232    b.axiom(
1233        "Array.map",
1234        pi_implicit(
1235            "α",
1236            type0(),
1237            pi_implicit(
1238                "β",
1239                type0(),
1240                pi(
1241                    pi(bvar(1), bvar(1)),
1242                    pi(app(var("Array"), bvar(2)), app(var("Array"), bvar(2))),
1243                ),
1244            ),
1245        ),
1246    );
1247    b.axiom(
1248        "Array.filter",
1249        pi_implicit(
1250            "α",
1251            type0(),
1252            pi(
1253                pi(bvar(0), var("Bool")),
1254                pi(app(var("Array"), bvar(1)), app(var("Array"), bvar(2))),
1255            ),
1256        ),
1257    );
1258    b.axiom(
1259        "Array.foldl",
1260        pi_implicit(
1261            "α",
1262            type0(),
1263            pi_implicit(
1264                "β",
1265                type0(),
1266                pi(
1267                    bvar(1),
1268                    pi(
1269                        pi(bvar(2), pi(bvar(3), bvar(3))),
1270                        pi(app(var("Array"), bvar(3)), bvar(3)),
1271                    ),
1272                ),
1273            ),
1274        ),
1275    );
1276    b.axiom(
1277        "Array.foldr",
1278        pi_implicit(
1279            "α",
1280            type0(),
1281            pi_implicit(
1282                "β",
1283                type0(),
1284                pi(
1285                    bvar(1),
1286                    pi(
1287                        pi(bvar(2), pi(bvar(2), bvar(2))),
1288                        pi(app(var("Array"), bvar(3)), bvar(2)),
1289                    ),
1290                ),
1291            ),
1292        ),
1293    );
1294    b.axiom(
1295        "Array.set",
1296        pi_implicit(
1297            "α",
1298            type0(),
1299            pi(
1300                app(var("Array"), bvar(0)),
1301                pi(var("Nat"), pi(bvar(2), app(var("Array"), bvar(3)))),
1302            ),
1303        ),
1304    );
1305    b.axiom(
1306        "Array.modify",
1307        pi_implicit(
1308            "α",
1309            type0(),
1310            pi(
1311                app(var("Array"), bvar(0)),
1312                pi(
1313                    var("Nat"),
1314                    pi(pi(bvar(2), bvar(2)), app(var("Array"), bvar(3))),
1315                ),
1316            ),
1317        ),
1318    );
1319    b.axiom(
1320        "Array.toList",
1321        pi_implicit(
1322            "α",
1323            type0(),
1324            pi(app(var("Array"), bvar(0)), app(var("List"), bvar(1))),
1325        ),
1326    );
1327    b.axiom(
1328        "Array.ofList",
1329        pi_implicit(
1330            "α",
1331            type0(),
1332            pi(app(var("List"), bvar(0)), app(var("Array"), bvar(1))),
1333        ),
1334    );
1335    b.axiom(
1336        "Array.append",
1337        pi_implicit(
1338            "α",
1339            type0(),
1340            pi(
1341                app(var("Array"), bvar(0)),
1342                pi(app(var("Array"), bvar(1)), app(var("Array"), bvar(2))),
1343            ),
1344        ),
1345    );
1346    b.axiom(
1347        "Array.zip",
1348        pi_implicit(
1349            "α",
1350            type0(),
1351            pi_implicit(
1352                "β",
1353                type0(),
1354                pi(
1355                    app(var("Array"), bvar(1)),
1356                    pi(
1357                        app(var("Array"), bvar(1)),
1358                        app(var("Array"), app(app(var("Prod"), bvar(2)), bvar(2))),
1359                    ),
1360                ),
1361            ),
1362        ),
1363    );
1364    b.axiom(
1365        "Array.any",
1366        pi_implicit(
1367            "α",
1368            type0(),
1369            pi(
1370                pi(bvar(0), var("Bool")),
1371                pi(app(var("Array"), bvar(1)), var("Bool")),
1372            ),
1373        ),
1374    );
1375    b.axiom(
1376        "Array.all",
1377        pi_implicit(
1378            "α",
1379            type0(),
1380            pi(
1381                pi(bvar(0), var("Bool")),
1382                pi(app(var("Array"), bvar(1)), var("Bool")),
1383            ),
1384        ),
1385    );
1386    b.axiom(
1387        "Array.find",
1388        pi_implicit(
1389            "α",
1390            type0(),
1391            pi(
1392                pi(bvar(0), var("Bool")),
1393                pi(app(var("Array"), bvar(1)), app(var("Option"), bvar(2))),
1394            ),
1395        ),
1396    );
1397    b.axiom(
1398        "Array.reverse",
1399        pi_implicit(
1400            "α",
1401            type0(),
1402            pi(app(var("Array"), bvar(0)), app(var("Array"), bvar(1))),
1403        ),
1404    );
1405    b.axiom(
1406        "Array.sort",
1407        pi_implicit(
1408            "α",
1409            type0(),
1410            pi(
1411                app(var("Ord"), bvar(0)),
1412                pi(app(var("Array"), bvar(1)), app(var("Array"), bvar(2))),
1413            ),
1414        ),
1415    );
1416    b.axiom(
1417        "Array.deduplicate",
1418        pi_implicit(
1419            "α",
1420            type0(),
1421            pi(
1422                app(var("BEq"), bvar(0)),
1423                pi(app(var("Array"), bvar(1)), app(var("Array"), bvar(2))),
1424            ),
1425        ),
1426    );
1427}
1428/// Add `HashMap` extended operations.
1429#[allow(dead_code)]
1430pub fn add_hashmap_ext(b: &mut EnvBuilder) {
1431    if !b.contains("HashMap") {
1432        add_hashmap(b);
1433    }
1434    b.axiom(
1435        "HashMap.size",
1436        pi_implicit(
1437            "k",
1438            type0(),
1439            pi_implicit(
1440                "v",
1441                type0(),
1442                pi_implicit(
1443                    "_",
1444                    app(var("BEq"), bvar(1)),
1445                    pi_implicit(
1446                        "_",
1447                        app(var("Hashable"), bvar(2)),
1448                        pi(app(app(var("HashMap"), bvar(3)), bvar(2)), var("Nat")),
1449                    ),
1450                ),
1451            ),
1452        ),
1453    );
1454    b.axiom(
1455        "HashMap.toList",
1456        pi_implicit(
1457            "k",
1458            type0(),
1459            pi_implicit(
1460                "v",
1461                type0(),
1462                pi_implicit(
1463                    "_",
1464                    app(var("BEq"), bvar(1)),
1465                    pi_implicit(
1466                        "_",
1467                        app(var("Hashable"), bvar(2)),
1468                        pi(
1469                            app(app(var("HashMap"), bvar(3)), bvar(2)),
1470                            app(var("List"), app(app(var("Prod"), bvar(4)), bvar(3))),
1471                        ),
1472                    ),
1473                ),
1474            ),
1475        ),
1476    );
1477    b.axiom(
1478        "HashMap.keys",
1479        pi_implicit(
1480            "k",
1481            type0(),
1482            pi_implicit(
1483                "v",
1484                type0(),
1485                pi_implicit(
1486                    "_",
1487                    app(var("BEq"), bvar(1)),
1488                    pi_implicit(
1489                        "_",
1490                        app(var("Hashable"), bvar(2)),
1491                        pi(
1492                            app(app(var("HashMap"), bvar(3)), bvar(2)),
1493                            app(var("List"), bvar(4)),
1494                        ),
1495                    ),
1496                ),
1497            ),
1498        ),
1499    );
1500    b.axiom(
1501        "HashMap.values",
1502        pi_implicit(
1503            "k",
1504            type0(),
1505            pi_implicit(
1506                "v",
1507                type0(),
1508                pi_implicit(
1509                    "_",
1510                    app(var("BEq"), bvar(1)),
1511                    pi_implicit(
1512                        "_",
1513                        app(var("Hashable"), bvar(2)),
1514                        pi(
1515                            app(app(var("HashMap"), bvar(3)), bvar(2)),
1516                            app(var("List"), bvar(2)),
1517                        ),
1518                    ),
1519                ),
1520            ),
1521        ),
1522    );
1523    b.axiom(
1524        "HashMap.contains",
1525        pi_implicit(
1526            "k",
1527            type0(),
1528            pi_implicit(
1529                "v",
1530                type0(),
1531                pi_implicit(
1532                    "_",
1533                    app(var("BEq"), bvar(1)),
1534                    pi_implicit(
1535                        "_",
1536                        app(var("Hashable"), bvar(2)),
1537                        pi(
1538                            app(app(var("HashMap"), bvar(3)), bvar(2)),
1539                            pi(bvar(4), var("Bool")),
1540                        ),
1541                    ),
1542                ),
1543            ),
1544        ),
1545    );
1546    b.axiom(
1547        "HashMap.map",
1548        pi_implicit(
1549            "k",
1550            type0(),
1551            pi_implicit(
1552                "v",
1553                type0(),
1554                pi_implicit(
1555                    "w",
1556                    type0(),
1557                    pi_implicit(
1558                        "_",
1559                        app(var("BEq"), bvar(2)),
1560                        pi_implicit(
1561                            "_",
1562                            app(var("Hashable"), bvar(3)),
1563                            pi(
1564                                pi(bvar(3), bvar(3)),
1565                                pi(
1566                                    app(app(var("HashMap"), bvar(5)), bvar(4)),
1567                                    app(app(var("HashMap"), bvar(6)), bvar(3)),
1568                                ),
1569                            ),
1570                        ),
1571                    ),
1572                ),
1573            ),
1574        ),
1575    );
1576    b.axiom(
1577        "HashMap.filter",
1578        pi_implicit(
1579            "k",
1580            type0(),
1581            pi_implicit(
1582                "v",
1583                type0(),
1584                pi_implicit(
1585                    "_",
1586                    app(var("BEq"), bvar(1)),
1587                    pi_implicit(
1588                        "_",
1589                        app(var("Hashable"), bvar(2)),
1590                        pi(
1591                            pi(bvar(3), pi(bvar(3), var("Bool"))),
1592                            pi(
1593                                app(app(var("HashMap"), bvar(4)), bvar(3)),
1594                                app(app(var("HashMap"), bvar(5)), bvar(4)),
1595                            ),
1596                        ),
1597                    ),
1598                ),
1599            ),
1600        ),
1601    );
1602    b.axiom(
1603        "HashMap.erase",
1604        pi_implicit(
1605            "k",
1606            type0(),
1607            pi_implicit(
1608                "v",
1609                type0(),
1610                pi_implicit(
1611                    "_",
1612                    app(var("BEq"), bvar(1)),
1613                    pi_implicit(
1614                        "_",
1615                        app(var("Hashable"), bvar(2)),
1616                        pi(
1617                            app(app(var("HashMap"), bvar(3)), bvar(2)),
1618                            pi(bvar(4), app(app(var("HashMap"), bvar(5)), bvar(4))),
1619                        ),
1620                    ),
1621                ),
1622            ),
1623        ),
1624    );
1625    b.axiom(
1626        "HashMap.merge",
1627        pi_implicit(
1628            "k",
1629            type0(),
1630            pi_implicit(
1631                "v",
1632                type0(),
1633                pi_implicit(
1634                    "_",
1635                    app(var("BEq"), bvar(1)),
1636                    pi_implicit(
1637                        "_",
1638                        app(var("Hashable"), bvar(2)),
1639                        pi(
1640                            app(app(var("HashMap"), bvar(3)), bvar(2)),
1641                            pi(
1642                                app(app(var("HashMap"), bvar(4)), bvar(3)),
1643                                app(app(var("HashMap"), bvar(5)), bvar(4)),
1644                            ),
1645                        ),
1646                    ),
1647                ),
1648            ),
1649        ),
1650    );
1651}
1652/// Add basic numeric casts and conversions.
1653#[allow(dead_code)]
1654pub fn add_numeric_casts(b: &mut EnvBuilder) {
1655    b.axiom(
1656        "Nat.cast",
1657        pi_implicit(
1658            "α",
1659            type0(),
1660            pi(app(var("OfNat"), bvar(0)), pi(var("Nat"), bvar(2))),
1661        ),
1662    );
1663    b.axiom(
1664        "Int.cast",
1665        pi_implicit("α", type0(), pi(prop(), pi(var("Int"), bvar(2)))),
1666    );
1667    b.axiom(
1668        "Float.cast",
1669        pi_implicit("α", type0(), pi(prop(), pi(var("Float"), bvar(2)))),
1670    );
1671    b.axiom("Rat", type0());
1672    b.axiom("Rat.mk", pi(var("Int"), pi(var("Nat"), var("Rat"))));
1673    b.axiom("Rat.num", pi(var("Rat"), var("Int")));
1674    b.axiom("Rat.den", pi(var("Rat"), var("Nat")));
1675    b.axiom("Rat.add", pi(var("Rat"), pi(var("Rat"), var("Rat"))));
1676    b.axiom("Rat.sub", pi(var("Rat"), pi(var("Rat"), var("Rat"))));
1677    b.axiom("Rat.mul", pi(var("Rat"), pi(var("Rat"), var("Rat"))));
1678    b.axiom("Rat.div", pi(var("Rat"), pi(var("Rat"), var("Rat"))));
1679    b.axiom("Rat.neg", pi(var("Rat"), var("Rat")));
1680    b.axiom("Rat.inv", pi(var("Rat"), var("Rat")));
1681    b.axiom("Rat.lt", pi(var("Rat"), pi(var("Rat"), prop())));
1682    b.axiom("Rat.le", pi(var("Rat"), pi(var("Rat"), prop())));
1683    b.axiom("Rat.ofInt", pi(var("Int"), var("Rat")));
1684    b.axiom("Rat.ofNat", pi(var("Nat"), var("Rat")));
1685    b.axiom("Rat.toFloat", pi(var("Rat"), var("Float")));
1686}
1687/// Add `IO` extended operations.
1688#[allow(dead_code)]
1689pub fn add_io_ext(b: &mut EnvBuilder) {
1690    if !b.contains("IO") {
1691        add_io(b);
1692    }
1693    b.axiom(
1694        "IO.println",
1695        pi_implicit(
1696            "α",
1697            type0(),
1698            pi(
1699                app(var("ToString"), bvar(0)),
1700                pi(bvar(1), app(var("IO"), var("Unit"))),
1701            ),
1702        ),
1703    );
1704    b.axiom("IO.readLine", app(var("IO"), var("String")));
1705    b.axiom(
1706        "IO.getArgs",
1707        app(var("IO"), app(var("List"), var("String"))),
1708    );
1709    b.axiom("IO.exitSuccess", app(var("IO"), var("Empty")));
1710    b.axiom(
1711        "IO.exitFailure",
1712        pi(var("Nat"), app(var("IO"), var("Empty"))),
1713    );
1714    b.axiom(
1715        "IO.throwError",
1716        pi_implicit("α", type0(), pi(var("String"), app(var("IO"), bvar(1)))),
1717    );
1718    b.axiom(
1719        "IO.catchError",
1720        pi_implicit(
1721            "α",
1722            type0(),
1723            pi(
1724                app(var("IO"), bvar(0)),
1725                pi(
1726                    pi(var("String"), app(var("IO"), bvar(1))),
1727                    app(var("IO"), bvar(2)),
1728                ),
1729            ),
1730        ),
1731    );
1732    b.axiom("IO.sleep", pi(var("Nat"), app(var("IO"), var("Unit"))));
1733    b.axiom(
1734        "IO.fileRead",
1735        pi(
1736            var("String"),
1737            app(
1738                var("IO"),
1739                app(app(var("Result"), var("String")), var("String")),
1740            ),
1741        ),
1742    );
1743    b.axiom(
1744        "IO.fileWrite",
1745        pi(
1746            var("String"),
1747            pi(
1748                var("String"),
1749                app(
1750                    var("IO"),
1751                    app(app(var("Result"), var("Unit")), var("String")),
1752                ),
1753            ),
1754        ),
1755    );
1756    b.axiom(
1757        "IO.fileExists",
1758        pi(var("String"), app(var("IO"), var("Bool"))),
1759    );
1760    b.axiom(
1761        "IO.envVar",
1762        pi(
1763            var("String"),
1764            app(var("IO"), app(var("Option"), var("String"))),
1765        ),
1766    );
1767}
1768/// Add `Nat` induction and recursion principles.
1769#[allow(dead_code)]
1770pub fn add_nat_induction(b: &mut EnvBuilder) {
1771    b.axiom(
1772        "Nat.rec",
1773        pi_implicit(
1774            "motive",
1775            pi(var("Nat"), type1()),
1776            pi(
1777                app(bvar(0), var("Nat.zero")),
1778                pi(
1779                    pi_named(
1780                        "n",
1781                        var("Nat"),
1782                        pi(
1783                            app(bvar(2), bvar(0)),
1784                            app(bvar(3), app(var("Nat.succ"), bvar(1))),
1785                        ),
1786                    ),
1787                    pi_named("n", var("Nat"), app(bvar(3), bvar(0))),
1788                ),
1789            ),
1790        ),
1791    );
1792    b.axiom(
1793        "Nat.casesOn",
1794        pi_implicit(
1795            "motive",
1796            pi(var("Nat"), type1()),
1797            pi_named(
1798                "n",
1799                var("Nat"),
1800                pi(
1801                    app(bvar(1), var("Nat.zero")),
1802                    pi(
1803                        pi_named("k", var("Nat"), app(bvar(3), app(var("Nat.succ"), bvar(0)))),
1804                        app(bvar(3), bvar(2)),
1805                    ),
1806                ),
1807            ),
1808        ),
1809    );
1810    b.axiom(
1811        "Nat.strongInduction",
1812        pi_implicit(
1813            "motive",
1814            pi(var("Nat"), prop()),
1815            pi(
1816                pi_named(
1817                    "n",
1818                    var("Nat"),
1819                    pi(
1820                        pi_named(
1821                            "m",
1822                            var("Nat"),
1823                            pi(
1824                                app(app(var("Nat.lt"), bvar(0)), bvar(1)),
1825                                app(bvar(3), bvar(1)),
1826                            ),
1827                        ),
1828                        app(bvar(2), bvar(1)),
1829                    ),
1830                ),
1831                pi_named("n", var("Nat"), app(bvar(2), bvar(0))),
1832            ),
1833        ),
1834    );
1835    b.axiom(
1836        "Nat.div2Ind",
1837        pi_implicit(
1838            "motive",
1839            pi(var("Nat"), prop()),
1840            pi(
1841                app(bvar(0), var("Nat.zero")),
1842                pi(
1843                    pi_named(
1844                        "n",
1845                        var("Nat"),
1846                        pi(
1847                            app(
1848                                bvar(2),
1849                                app(
1850                                    app(var("Nat.div"), app(var("Nat.succ"), bvar(0))),
1851                                    var("Nat.zero"),
1852                                ),
1853                            ),
1854                            app(bvar(3), app(var("Nat.succ"), bvar(1))),
1855                        ),
1856                    ),
1857                    pi_named("n", var("Nat"), app(bvar(3), bvar(0))),
1858                ),
1859            ),
1860        ),
1861    );
1862}