1use crate::context::Context;
11use crate::term::{Term, Universe};
12
13pub struct StandardLibrary;
15
16impl StandardLibrary {
17 pub fn register(ctx: &mut Context) {
19 Self::register_entity(ctx);
20 Self::register_nat(ctx);
21 Self::register_bool(ctx);
22 Self::register_tlist(ctx);
23 Self::register_true(ctx);
24 Self::register_false(ctx);
25 Self::register_not(ctx);
26 Self::register_eq(ctx);
27 Self::register_and(ctx);
28 Self::register_or(ctx);
29 Self::register_ex(ctx);
30 Self::register_primitives(ctx);
31 Self::register_reflection(ctx);
32 Self::register_hardware(ctx);
33 }
34
35 fn register_primitives(ctx: &mut Context) {
46 ctx.add_inductive("Int", Term::Sort(Universe::Type(0)));
48 ctx.add_inductive("Float", Term::Sort(Universe::Type(0)));
49 ctx.add_inductive("Text", Term::Sort(Universe::Type(0)));
50
51 ctx.add_inductive("Duration", Term::Sort(Universe::Type(0)));
53 ctx.add_inductive("Date", Term::Sort(Universe::Type(0)));
54 ctx.add_inductive("Moment", Term::Sort(Universe::Type(0)));
55
56 let int = Term::Global("Int".to_string());
57
58 let bin_int_type = Term::Pi {
60 param: "_".to_string(),
61 param_type: Box::new(int.clone()),
62 body_type: Box::new(Term::Pi {
63 param: "_".to_string(),
64 param_type: Box::new(int.clone()),
65 body_type: Box::new(int.clone()),
66 }),
67 };
68
69 ctx.add_declaration("add", bin_int_type.clone());
71 ctx.add_declaration("sub", bin_int_type.clone());
72 ctx.add_declaration("mul", bin_int_type.clone());
73 ctx.add_declaration("div", bin_int_type.clone());
74 ctx.add_declaration("mod", bin_int_type);
75
76 let duration = Term::Global("Duration".to_string());
78 let date = Term::Global("Date".to_string());
79 let moment = Term::Global("Moment".to_string());
80 let bool_type = Term::Global("Bool".to_string());
81
82 let bin_duration_type = Term::Pi {
84 param: "_".to_string(),
85 param_type: Box::new(duration.clone()),
86 body_type: Box::new(Term::Pi {
87 param: "_".to_string(),
88 param_type: Box::new(duration.clone()),
89 body_type: Box::new(duration.clone()),
90 }),
91 };
92
93 let duration_int_duration_type = Term::Pi {
95 param: "_".to_string(),
96 param_type: Box::new(duration.clone()),
97 body_type: Box::new(Term::Pi {
98 param: "_".to_string(),
99 param_type: Box::new(int.clone()),
100 body_type: Box::new(duration.clone()),
101 }),
102 };
103
104 ctx.add_declaration("add_duration", bin_duration_type.clone());
106 ctx.add_declaration("sub_duration", bin_duration_type.clone());
107 ctx.add_declaration("mul_duration", duration_int_duration_type.clone());
108 ctx.add_declaration("div_duration", duration_int_duration_type);
109
110 let date_int_date_type = Term::Pi {
112 param: "_".to_string(),
113 param_type: Box::new(date.clone()),
114 body_type: Box::new(Term::Pi {
115 param: "_".to_string(),
116 param_type: Box::new(int.clone()),
117 body_type: Box::new(date.clone()),
118 }),
119 };
120 ctx.add_declaration("date_add_days", date_int_date_type);
121
122 let date_date_int_type = Term::Pi {
124 param: "_".to_string(),
125 param_type: Box::new(date.clone()),
126 body_type: Box::new(Term::Pi {
127 param: "_".to_string(),
128 param_type: Box::new(date.clone()),
129 body_type: Box::new(int.clone()),
130 }),
131 };
132 ctx.add_declaration("date_sub_date", date_date_int_type);
133
134 let moment_duration_moment_type = Term::Pi {
136 param: "_".to_string(),
137 param_type: Box::new(moment.clone()),
138 body_type: Box::new(Term::Pi {
139 param: "_".to_string(),
140 param_type: Box::new(duration.clone()),
141 body_type: Box::new(moment.clone()),
142 }),
143 };
144 ctx.add_declaration("moment_add_duration", moment_duration_moment_type);
145
146 let moment_moment_duration_type = Term::Pi {
148 param: "_".to_string(),
149 param_type: Box::new(moment.clone()),
150 body_type: Box::new(Term::Pi {
151 param: "_".to_string(),
152 param_type: Box::new(moment.clone()),
153 body_type: Box::new(duration.clone()),
154 }),
155 };
156 ctx.add_declaration("moment_sub_moment", moment_moment_duration_type);
157
158 let date_date_bool_type = Term::Pi {
160 param: "_".to_string(),
161 param_type: Box::new(date.clone()),
162 body_type: Box::new(Term::Pi {
163 param: "_".to_string(),
164 param_type: Box::new(date),
165 body_type: Box::new(bool_type.clone()),
166 }),
167 };
168 ctx.add_declaration("date_lt", date_date_bool_type);
169
170 let moment_moment_bool_type = Term::Pi {
171 param: "_".to_string(),
172 param_type: Box::new(moment.clone()),
173 body_type: Box::new(Term::Pi {
174 param: "_".to_string(),
175 param_type: Box::new(moment),
176 body_type: Box::new(bool_type.clone()),
177 }),
178 };
179 ctx.add_declaration("moment_lt", moment_moment_bool_type);
180
181 let duration_duration_bool_type = Term::Pi {
182 param: "_".to_string(),
183 param_type: Box::new(duration.clone()),
184 body_type: Box::new(Term::Pi {
185 param: "_".to_string(),
186 param_type: Box::new(duration),
187 body_type: Box::new(bool_type),
188 }),
189 };
190 ctx.add_declaration("duration_lt", duration_duration_bool_type);
191 }
192
193 fn register_entity(ctx: &mut Context) {
199 ctx.add_inductive("Entity", Term::Sort(Universe::Type(0)));
200 }
201
202 fn register_nat(ctx: &mut Context) {
206 let nat = Term::Global("Nat".to_string());
207
208 ctx.add_inductive("Nat", Term::Sort(Universe::Type(0)));
210
211 ctx.add_constructor("Zero", "Nat", nat.clone());
213
214 ctx.add_constructor(
216 "Succ",
217 "Nat",
218 Term::Pi {
219 param: "_".to_string(),
220 param_type: Box::new(nat.clone()),
221 body_type: Box::new(nat),
222 },
223 );
224 }
225
226 fn register_bool(ctx: &mut Context) {
230 let bool_type = Term::Global("Bool".to_string());
231
232 ctx.add_inductive("Bool", Term::Sort(Universe::Type(0)));
234
235 ctx.add_constructor("true", "Bool", bool_type.clone());
237
238 ctx.add_constructor("false", "Bool", bool_type);
240 }
241
242 fn register_tlist(ctx: &mut Context) {
246 let type0 = Term::Sort(Universe::Type(0));
247 let a = Term::Var("A".to_string());
248
249 let tlist_type = Term::Pi {
251 param: "A".to_string(),
252 param_type: Box::new(type0.clone()),
253 body_type: Box::new(type0.clone()),
254 };
255 ctx.add_inductive("TList", tlist_type);
256
257 let tlist_a = Term::App(
259 Box::new(Term::Global("TList".to_string())),
260 Box::new(a.clone()),
261 );
262
263 let tnil_type = Term::Pi {
265 param: "A".to_string(),
266 param_type: Box::new(type0.clone()),
267 body_type: Box::new(tlist_a.clone()),
268 };
269 ctx.add_constructor("TNil", "TList", tnil_type);
270
271 let tcons_type = Term::Pi {
273 param: "A".to_string(),
274 param_type: Box::new(type0),
275 body_type: Box::new(Term::Pi {
276 param: "_".to_string(),
277 param_type: Box::new(a.clone()),
278 body_type: Box::new(Term::Pi {
279 param: "_".to_string(),
280 param_type: Box::new(tlist_a.clone()),
281 body_type: Box::new(tlist_a),
282 }),
283 }),
284 };
285 ctx.add_constructor("TCons", "TList", tcons_type);
286
287 Self::register_tactic_list_helpers(ctx);
289 }
290
291 fn register_tactic_list_helpers(ctx: &mut Context) {
297 let syntax = Term::Global("Syntax".to_string());
298 let derivation = Term::Global("Derivation".to_string());
299
300 let tactic_type = Term::Pi {
302 param: "_".to_string(),
303 param_type: Box::new(syntax.clone()),
304 body_type: Box::new(derivation.clone()),
305 };
306
307 let ttactics = Term::App(
309 Box::new(Term::Global("TList".to_string())),
310 Box::new(tactic_type.clone()),
311 );
312
313 ctx.add_definition("TTactics".to_string(), Term::Sort(Universe::Type(0)), ttactics.clone());
315
316 let tac_nil_body = Term::App(
318 Box::new(Term::Global("TNil".to_string())),
319 Box::new(tactic_type.clone()),
320 );
321 ctx.add_definition("TacNil".to_string(), ttactics.clone(), tac_nil_body);
322
323 let tac_cons_type = Term::Pi {
325 param: "t".to_string(),
326 param_type: Box::new(tactic_type.clone()),
327 body_type: Box::new(Term::Pi {
328 param: "ts".to_string(),
329 param_type: Box::new(ttactics.clone()),
330 body_type: Box::new(ttactics.clone()),
331 }),
332 };
333
334 let tac_cons_body = Term::Lambda {
336 param: "t".to_string(),
337 param_type: Box::new(tactic_type.clone()),
338 body: Box::new(Term::Lambda {
339 param: "ts".to_string(),
340 param_type: Box::new(ttactics.clone()),
341 body: Box::new(Term::App(
342 Box::new(Term::App(
343 Box::new(Term::App(
344 Box::new(Term::Global("TCons".to_string())),
345 Box::new(tactic_type),
346 )),
347 Box::new(Term::Var("t".to_string())),
348 )),
349 Box::new(Term::Var("ts".to_string())),
350 )),
351 }),
352 };
353 ctx.add_definition("TacCons".to_string(), tac_cons_type, tac_cons_body);
354 }
355
356 fn register_true(ctx: &mut Context) {
359 ctx.add_inductive("True", Term::Sort(Universe::Prop));
360 ctx.add_constructor("I", "True", Term::Global("True".to_string()));
361 }
362
363 fn register_false(ctx: &mut Context) {
366 ctx.add_inductive("False", Term::Sort(Universe::Prop));
367 }
368
369 fn register_not(ctx: &mut Context) {
372 let not_type = Term::Pi {
374 param: "P".to_string(),
375 param_type: Box::new(Term::Sort(Universe::Prop)),
376 body_type: Box::new(Term::Sort(Universe::Prop)),
377 };
378
379 let not_body = Term::Lambda {
381 param: "P".to_string(),
382 param_type: Box::new(Term::Sort(Universe::Prop)),
383 body: Box::new(Term::Pi {
384 param: "_".to_string(),
385 param_type: Box::new(Term::Var("P".to_string())),
386 body_type: Box::new(Term::Global("False".to_string())),
387 }),
388 };
389
390 ctx.add_definition("Not".to_string(), not_type, not_body);
391 }
392
393 fn register_eq(ctx: &mut Context) {
396 let eq_type = Term::Pi {
398 param: "A".to_string(),
399 param_type: Box::new(Term::Sort(Universe::Type(0))),
400 body_type: Box::new(Term::Pi {
401 param: "x".to_string(),
402 param_type: Box::new(Term::Var("A".to_string())),
403 body_type: Box::new(Term::Pi {
404 param: "y".to_string(),
405 param_type: Box::new(Term::Var("A".to_string())),
406 body_type: Box::new(Term::Sort(Universe::Prop)),
407 }),
408 }),
409 };
410 ctx.add_inductive("Eq", eq_type);
411
412 let refl_type = Term::Pi {
414 param: "A".to_string(),
415 param_type: Box::new(Term::Sort(Universe::Type(0))),
416 body_type: Box::new(Term::Pi {
417 param: "x".to_string(),
418 param_type: Box::new(Term::Var("A".to_string())),
419 body_type: Box::new(Term::App(
420 Box::new(Term::App(
421 Box::new(Term::App(
422 Box::new(Term::Global("Eq".to_string())),
423 Box::new(Term::Var("A".to_string())),
424 )),
425 Box::new(Term::Var("x".to_string())),
426 )),
427 Box::new(Term::Var("x".to_string())),
428 )),
429 }),
430 };
431 ctx.add_constructor("refl", "Eq", refl_type);
432
433 Self::register_eq_rec(ctx);
436
437 Self::register_eq_sym(ctx);
439
440 Self::register_eq_trans(ctx);
442 }
443
444 fn register_eq_rec(ctx: &mut Context) {
447 let a = Term::Var("A".to_string());
448 let x = Term::Var("x".to_string());
449 let y = Term::Var("y".to_string());
450 let p = Term::Var("P".to_string());
451
452 let p_x = Term::App(Box::new(p.clone()), Box::new(x.clone()));
454
455 let p_y = Term::App(Box::new(p.clone()), Box::new(y.clone()));
457
458 let eq_a_x_y = Term::App(
460 Box::new(Term::App(
461 Box::new(Term::App(
462 Box::new(Term::Global("Eq".to_string())),
463 Box::new(a.clone()),
464 )),
465 Box::new(x.clone()),
466 )),
467 Box::new(y.clone()),
468 );
469
470 let p_type = Term::Pi {
472 param: "_".to_string(),
473 param_type: Box::new(a.clone()),
474 body_type: Box::new(Term::Sort(Universe::Prop)),
475 };
476
477 let eq_rec_type = Term::Pi {
479 param: "A".to_string(),
480 param_type: Box::new(Term::Sort(Universe::Type(0))),
481 body_type: Box::new(Term::Pi {
482 param: "x".to_string(),
483 param_type: Box::new(a.clone()),
484 body_type: Box::new(Term::Pi {
485 param: "P".to_string(),
486 param_type: Box::new(p_type),
487 body_type: Box::new(Term::Pi {
488 param: "_".to_string(),
489 param_type: Box::new(p_x),
490 body_type: Box::new(Term::Pi {
491 param: "y".to_string(),
492 param_type: Box::new(a),
493 body_type: Box::new(Term::Pi {
494 param: "_".to_string(),
495 param_type: Box::new(eq_a_x_y),
496 body_type: Box::new(p_y),
497 }),
498 }),
499 }),
500 }),
501 }),
502 };
503
504 ctx.add_declaration("Eq_rec", eq_rec_type);
505 }
506
507 fn register_eq_sym(ctx: &mut Context) {
510 let a = Term::Var("A".to_string());
511 let x = Term::Var("x".to_string());
512 let y = Term::Var("y".to_string());
513
514 let eq_a_x_y = Term::App(
516 Box::new(Term::App(
517 Box::new(Term::App(
518 Box::new(Term::Global("Eq".to_string())),
519 Box::new(a.clone()),
520 )),
521 Box::new(x.clone()),
522 )),
523 Box::new(y.clone()),
524 );
525
526 let eq_a_y_x = Term::App(
528 Box::new(Term::App(
529 Box::new(Term::App(
530 Box::new(Term::Global("Eq".to_string())),
531 Box::new(a.clone()),
532 )),
533 Box::new(y.clone()),
534 )),
535 Box::new(x.clone()),
536 );
537
538 let eq_sym_type = Term::Pi {
540 param: "A".to_string(),
541 param_type: Box::new(Term::Sort(Universe::Type(0))),
542 body_type: Box::new(Term::Pi {
543 param: "x".to_string(),
544 param_type: Box::new(a.clone()),
545 body_type: Box::new(Term::Pi {
546 param: "y".to_string(),
547 param_type: Box::new(a),
548 body_type: Box::new(Term::Pi {
549 param: "_".to_string(),
550 param_type: Box::new(eq_a_x_y),
551 body_type: Box::new(eq_a_y_x),
552 }),
553 }),
554 }),
555 };
556
557 ctx.add_declaration("Eq_sym", eq_sym_type);
558 }
559
560 fn register_eq_trans(ctx: &mut Context) {
563 let a = Term::Var("A".to_string());
564 let x = Term::Var("x".to_string());
565 let y = Term::Var("y".to_string());
566 let z = Term::Var("z".to_string());
567
568 let eq_a_x_y = Term::App(
570 Box::new(Term::App(
571 Box::new(Term::App(
572 Box::new(Term::Global("Eq".to_string())),
573 Box::new(a.clone()),
574 )),
575 Box::new(x.clone()),
576 )),
577 Box::new(y.clone()),
578 );
579
580 let eq_a_y_z = Term::App(
582 Box::new(Term::App(
583 Box::new(Term::App(
584 Box::new(Term::Global("Eq".to_string())),
585 Box::new(a.clone()),
586 )),
587 Box::new(y.clone()),
588 )),
589 Box::new(z.clone()),
590 );
591
592 let eq_a_x_z = Term::App(
594 Box::new(Term::App(
595 Box::new(Term::App(
596 Box::new(Term::Global("Eq".to_string())),
597 Box::new(a.clone()),
598 )),
599 Box::new(x.clone()),
600 )),
601 Box::new(z.clone()),
602 );
603
604 let eq_trans_type = Term::Pi {
606 param: "A".to_string(),
607 param_type: Box::new(Term::Sort(Universe::Type(0))),
608 body_type: Box::new(Term::Pi {
609 param: "x".to_string(),
610 param_type: Box::new(a.clone()),
611 body_type: Box::new(Term::Pi {
612 param: "y".to_string(),
613 param_type: Box::new(a.clone()),
614 body_type: Box::new(Term::Pi {
615 param: "z".to_string(),
616 param_type: Box::new(a),
617 body_type: Box::new(Term::Pi {
618 param: "_".to_string(),
619 param_type: Box::new(eq_a_x_y),
620 body_type: Box::new(Term::Pi {
621 param: "_".to_string(),
622 param_type: Box::new(eq_a_y_z),
623 body_type: Box::new(eq_a_x_z),
624 }),
625 }),
626 }),
627 }),
628 }),
629 };
630
631 ctx.add_declaration("Eq_trans", eq_trans_type);
632 }
633
634 fn register_and(ctx: &mut Context) {
637 let and_type = Term::Pi {
639 param: "P".to_string(),
640 param_type: Box::new(Term::Sort(Universe::Prop)),
641 body_type: Box::new(Term::Pi {
642 param: "Q".to_string(),
643 param_type: Box::new(Term::Sort(Universe::Prop)),
644 body_type: Box::new(Term::Sort(Universe::Prop)),
645 }),
646 };
647 ctx.add_inductive("And", and_type);
648
649 let conj_type = Term::Pi {
651 param: "P".to_string(),
652 param_type: Box::new(Term::Sort(Universe::Prop)),
653 body_type: Box::new(Term::Pi {
654 param: "Q".to_string(),
655 param_type: Box::new(Term::Sort(Universe::Prop)),
656 body_type: Box::new(Term::Pi {
657 param: "p".to_string(),
658 param_type: Box::new(Term::Var("P".to_string())),
659 body_type: Box::new(Term::Pi {
660 param: "q".to_string(),
661 param_type: Box::new(Term::Var("Q".to_string())),
662 body_type: Box::new(Term::App(
663 Box::new(Term::App(
664 Box::new(Term::Global("And".to_string())),
665 Box::new(Term::Var("P".to_string())),
666 )),
667 Box::new(Term::Var("Q".to_string())),
668 )),
669 }),
670 }),
671 }),
672 };
673 ctx.add_constructor("conj", "And", conj_type);
674 }
675
676 fn register_or(ctx: &mut Context) {
680 let or_type = Term::Pi {
682 param: "P".to_string(),
683 param_type: Box::new(Term::Sort(Universe::Prop)),
684 body_type: Box::new(Term::Pi {
685 param: "Q".to_string(),
686 param_type: Box::new(Term::Sort(Universe::Prop)),
687 body_type: Box::new(Term::Sort(Universe::Prop)),
688 }),
689 };
690 ctx.add_inductive("Or", or_type);
691
692 let left_type = Term::Pi {
694 param: "P".to_string(),
695 param_type: Box::new(Term::Sort(Universe::Prop)),
696 body_type: Box::new(Term::Pi {
697 param: "Q".to_string(),
698 param_type: Box::new(Term::Sort(Universe::Prop)),
699 body_type: Box::new(Term::Pi {
700 param: "p".to_string(),
701 param_type: Box::new(Term::Var("P".to_string())),
702 body_type: Box::new(Term::App(
703 Box::new(Term::App(
704 Box::new(Term::Global("Or".to_string())),
705 Box::new(Term::Var("P".to_string())),
706 )),
707 Box::new(Term::Var("Q".to_string())),
708 )),
709 }),
710 }),
711 };
712 ctx.add_constructor("left", "Or", left_type);
713
714 let right_type = Term::Pi {
716 param: "P".to_string(),
717 param_type: Box::new(Term::Sort(Universe::Prop)),
718 body_type: Box::new(Term::Pi {
719 param: "Q".to_string(),
720 param_type: Box::new(Term::Sort(Universe::Prop)),
721 body_type: Box::new(Term::Pi {
722 param: "q".to_string(),
723 param_type: Box::new(Term::Var("Q".to_string())),
724 body_type: Box::new(Term::App(
725 Box::new(Term::App(
726 Box::new(Term::Global("Or".to_string())),
727 Box::new(Term::Var("P".to_string())),
728 )),
729 Box::new(Term::Var("Q".to_string())),
730 )),
731 }),
732 }),
733 };
734 ctx.add_constructor("right", "Or", right_type);
735 }
736
737 fn register_ex(ctx: &mut Context) {
743 let ex_type = Term::Pi {
745 param: "A".to_string(),
746 param_type: Box::new(Term::Sort(Universe::Type(0))),
747 body_type: Box::new(Term::Pi {
748 param: "P".to_string(),
749 param_type: Box::new(Term::Pi {
750 param: "_".to_string(),
751 param_type: Box::new(Term::Var("A".to_string())),
752 body_type: Box::new(Term::Sort(Universe::Prop)),
753 }),
754 body_type: Box::new(Term::Sort(Universe::Prop)),
755 }),
756 };
757 ctx.add_inductive("Ex", ex_type);
758
759 let a = Term::Var("A".to_string());
767 let p = Term::Var("P".to_string());
768 let x = Term::Var("x".to_string());
769
770 let p_x = Term::App(Box::new(p.clone()), Box::new(x.clone()));
772
773 let ex_a_p = Term::App(
775 Box::new(Term::App(
776 Box::new(Term::Global("Ex".to_string())),
777 Box::new(a.clone()),
778 )),
779 Box::new(p.clone()),
780 );
781
782 let witness_type = Term::Pi {
783 param: "A".to_string(),
784 param_type: Box::new(Term::Sort(Universe::Type(0))),
785 body_type: Box::new(Term::Pi {
786 param: "P".to_string(),
787 param_type: Box::new(Term::Pi {
788 param: "_".to_string(),
789 param_type: Box::new(a.clone()),
790 body_type: Box::new(Term::Sort(Universe::Prop)),
791 }),
792 body_type: Box::new(Term::Pi {
793 param: "x".to_string(),
794 param_type: Box::new(a),
795 body_type: Box::new(Term::Pi {
796 param: "_".to_string(),
797 param_type: Box::new(p_x),
798 body_type: Box::new(ex_a_p),
799 }),
800 }),
801 }),
802 };
803 ctx.add_constructor("witness", "Ex", witness_type);
804 }
805
806 fn register_reflection(ctx: &mut Context) {
817 Self::register_univ(ctx);
818 Self::register_syntax(ctx);
819 Self::register_syn_size(ctx);
820 Self::register_syn_max_var(ctx);
821 Self::register_syn_lift(ctx);
822 Self::register_syn_subst(ctx);
823 Self::register_syn_beta(ctx);
824 Self::register_syn_step(ctx);
825 Self::register_syn_eval(ctx);
826 Self::register_syn_quote(ctx);
827 Self::register_syn_diag(ctx);
828 Self::register_derivation(ctx);
829 Self::register_concludes(ctx);
830 Self::register_try_refl(ctx);
831 Self::register_try_compute(ctx);
832 Self::register_try_cong(ctx);
833 Self::register_tact_fail(ctx);
834 Self::register_tact_orelse(ctx);
835 Self::register_tact_try(ctx);
836 Self::register_tact_repeat(ctx);
837 Self::register_tact_then(ctx);
838 Self::register_tact_first(ctx);
839 Self::register_tact_solve(ctx);
840 Self::register_try_ring(ctx);
841 Self::register_try_lia(ctx);
842 Self::register_try_cc(ctx);
843 Self::register_try_simp(ctx);
844 Self::register_try_omega(ctx);
845 Self::register_try_auto(ctx);
846 Self::register_try_induction(ctx);
847 Self::register_induction_helpers(ctx);
848 Self::register_try_inversion_tactic(ctx);
849 Self::register_operator_tactics(ctx);
850 Self::register_hw_tactics(ctx);
851 }
852
853 fn register_univ(ctx: &mut Context) {
857 let univ = Term::Global("Univ".to_string());
858 let int = Term::Global("Int".to_string());
859
860 ctx.add_inductive("Univ", Term::Sort(Universe::Type(0)));
862
863 ctx.add_constructor("UProp", "Univ", univ.clone());
865
866 ctx.add_constructor(
868 "UType",
869 "Univ",
870 Term::Pi {
871 param: "_".to_string(),
872 param_type: Box::new(int),
873 body_type: Box::new(univ),
874 },
875 );
876 }
877
878 fn register_syntax(ctx: &mut Context) {
887 let syntax = Term::Global("Syntax".to_string());
888 let int = Term::Global("Int".to_string());
889 let univ = Term::Global("Univ".to_string());
890
891 ctx.add_inductive("Syntax", Term::Sort(Universe::Type(0)));
893
894 ctx.add_constructor(
896 "SVar",
897 "Syntax",
898 Term::Pi {
899 param: "_".to_string(),
900 param_type: Box::new(int.clone()),
901 body_type: Box::new(syntax.clone()),
902 },
903 );
904
905 ctx.add_constructor(
907 "SGlobal",
908 "Syntax",
909 Term::Pi {
910 param: "_".to_string(),
911 param_type: Box::new(int.clone()),
912 body_type: Box::new(syntax.clone()),
913 },
914 );
915
916 ctx.add_constructor(
918 "SSort",
919 "Syntax",
920 Term::Pi {
921 param: "_".to_string(),
922 param_type: Box::new(univ),
923 body_type: Box::new(syntax.clone()),
924 },
925 );
926
927 ctx.add_constructor(
929 "SApp",
930 "Syntax",
931 Term::Pi {
932 param: "_".to_string(),
933 param_type: Box::new(syntax.clone()),
934 body_type: Box::new(Term::Pi {
935 param: "_".to_string(),
936 param_type: Box::new(syntax.clone()),
937 body_type: Box::new(syntax.clone()),
938 }),
939 },
940 );
941
942 ctx.add_constructor(
944 "SLam",
945 "Syntax",
946 Term::Pi {
947 param: "_".to_string(),
948 param_type: Box::new(syntax.clone()),
949 body_type: Box::new(Term::Pi {
950 param: "_".to_string(),
951 param_type: Box::new(syntax.clone()),
952 body_type: Box::new(syntax.clone()),
953 }),
954 },
955 );
956
957 ctx.add_constructor(
959 "SPi",
960 "Syntax",
961 Term::Pi {
962 param: "_".to_string(),
963 param_type: Box::new(syntax.clone()),
964 body_type: Box::new(Term::Pi {
965 param: "_".to_string(),
966 param_type: Box::new(syntax.clone()),
967 body_type: Box::new(syntax.clone()),
968 }),
969 },
970 );
971
972 ctx.add_constructor(
974 "SLit",
975 "Syntax",
976 Term::Pi {
977 param: "_".to_string(),
978 param_type: Box::new(int),
979 body_type: Box::new(syntax.clone()),
980 },
981 );
982
983 let text = Term::Global("Text".to_string());
985 ctx.add_constructor(
986 "SName",
987 "Syntax",
988 Term::Pi {
989 param: "_".to_string(),
990 param_type: Box::new(text),
991 body_type: Box::new(syntax),
992 },
993 );
994 }
995
996 fn register_syn_size(ctx: &mut Context) {
1001 let syntax = Term::Global("Syntax".to_string());
1002 let int = Term::Global("Int".to_string());
1003
1004 let syn_size_type = Term::Pi {
1006 param: "_".to_string(),
1007 param_type: Box::new(syntax),
1008 body_type: Box::new(int),
1009 };
1010
1011 ctx.add_declaration("syn_size", syn_size_type);
1012 }
1013
1014 fn register_syn_max_var(ctx: &mut Context) {
1020 let syntax = Term::Global("Syntax".to_string());
1021 let int = Term::Global("Int".to_string());
1022
1023 let syn_max_var_type = Term::Pi {
1024 param: "_".to_string(),
1025 param_type: Box::new(syntax),
1026 body_type: Box::new(int),
1027 };
1028
1029 ctx.add_declaration("syn_max_var", syn_max_var_type);
1030 }
1031
1032 fn register_syn_lift(ctx: &mut Context) {
1044 let syntax = Term::Global("Syntax".to_string());
1045 let int = Term::Global("Int".to_string());
1046
1047 let syn_lift_type = Term::Pi {
1049 param: "_".to_string(),
1050 param_type: Box::new(int.clone()),
1051 body_type: Box::new(Term::Pi {
1052 param: "_".to_string(),
1053 param_type: Box::new(int),
1054 body_type: Box::new(Term::Pi {
1055 param: "_".to_string(),
1056 param_type: Box::new(syntax.clone()),
1057 body_type: Box::new(syntax),
1058 }),
1059 }),
1060 };
1061
1062 ctx.add_declaration("syn_lift", syn_lift_type);
1063 }
1064
1065 fn register_syn_subst(ctx: &mut Context) {
1074 let syntax = Term::Global("Syntax".to_string());
1075 let int = Term::Global("Int".to_string());
1076
1077 let syn_subst_type = Term::Pi {
1079 param: "_".to_string(),
1080 param_type: Box::new(syntax.clone()),
1081 body_type: Box::new(Term::Pi {
1082 param: "_".to_string(),
1083 param_type: Box::new(int),
1084 body_type: Box::new(Term::Pi {
1085 param: "_".to_string(),
1086 param_type: Box::new(syntax.clone()),
1087 body_type: Box::new(syntax),
1088 }),
1089 }),
1090 };
1091
1092 ctx.add_declaration("syn_subst", syn_subst_type);
1093 }
1094
1095 fn register_syn_beta(ctx: &mut Context) {
1105 let syntax = Term::Global("Syntax".to_string());
1106
1107 let syn_beta_type = Term::Pi {
1109 param: "_".to_string(),
1110 param_type: Box::new(syntax.clone()),
1111 body_type: Box::new(Term::Pi {
1112 param: "_".to_string(),
1113 param_type: Box::new(syntax.clone()),
1114 body_type: Box::new(syntax),
1115 }),
1116 };
1117
1118 ctx.add_declaration("syn_beta", syn_beta_type);
1119 }
1120
1121 fn register_syn_step(ctx: &mut Context) {
1129 let syntax = Term::Global("Syntax".to_string());
1130
1131 let syn_step_type = Term::Pi {
1133 param: "_".to_string(),
1134 param_type: Box::new(syntax.clone()),
1135 body_type: Box::new(syntax),
1136 };
1137
1138 ctx.add_declaration("syn_step", syn_step_type);
1139 }
1140
1141 fn register_syn_eval(ctx: &mut Context) {
1153 let syntax = Term::Global("Syntax".to_string());
1154 let int = Term::Global("Int".to_string());
1155
1156 let syn_eval_type = Term::Pi {
1158 param: "_".to_string(),
1159 param_type: Box::new(int),
1160 body_type: Box::new(Term::Pi {
1161 param: "_".to_string(),
1162 param_type: Box::new(syntax.clone()),
1163 body_type: Box::new(syntax),
1164 }),
1165 };
1166
1167 ctx.add_declaration("syn_eval", syn_eval_type);
1168 }
1169
1170 fn register_syn_quote(ctx: &mut Context) {
1179 let syntax = Term::Global("Syntax".to_string());
1180
1181 let syn_quote_type = Term::Pi {
1183 param: "_".to_string(),
1184 param_type: Box::new(syntax.clone()),
1185 body_type: Box::new(syntax),
1186 };
1187
1188 ctx.add_declaration("syn_quote", syn_quote_type);
1189 }
1190
1191 fn register_syn_diag(ctx: &mut Context) {
1200 let syntax = Term::Global("Syntax".to_string());
1201
1202 let syn_diag_type = Term::Pi {
1203 param: "_".to_string(),
1204 param_type: Box::new(syntax.clone()),
1205 body_type: Box::new(syntax),
1206 };
1207
1208 ctx.add_declaration("syn_diag", syn_diag_type);
1209 }
1210
1211 fn register_derivation(ctx: &mut Context) {
1222 let syntax = Term::Global("Syntax".to_string());
1223 let derivation = Term::Global("Derivation".to_string());
1224
1225 ctx.add_inductive("Derivation", Term::Sort(Universe::Type(0)));
1227
1228 ctx.add_constructor(
1230 "DAxiom",
1231 "Derivation",
1232 Term::Pi {
1233 param: "_".to_string(),
1234 param_type: Box::new(syntax.clone()),
1235 body_type: Box::new(derivation.clone()),
1236 },
1237 );
1238
1239 ctx.add_constructor(
1241 "DModusPonens",
1242 "Derivation",
1243 Term::Pi {
1244 param: "_".to_string(),
1245 param_type: Box::new(derivation.clone()),
1246 body_type: Box::new(Term::Pi {
1247 param: "_".to_string(),
1248 param_type: Box::new(derivation.clone()),
1249 body_type: Box::new(derivation.clone()),
1250 }),
1251 },
1252 );
1253
1254 ctx.add_constructor(
1256 "DUnivIntro",
1257 "Derivation",
1258 Term::Pi {
1259 param: "_".to_string(),
1260 param_type: Box::new(derivation.clone()),
1261 body_type: Box::new(derivation.clone()),
1262 },
1263 );
1264
1265 ctx.add_constructor(
1267 "DUnivElim",
1268 "Derivation",
1269 Term::Pi {
1270 param: "_".to_string(),
1271 param_type: Box::new(derivation.clone()),
1272 body_type: Box::new(Term::Pi {
1273 param: "_".to_string(),
1274 param_type: Box::new(syntax.clone()),
1275 body_type: Box::new(derivation.clone()),
1276 }),
1277 },
1278 );
1279
1280 ctx.add_constructor(
1283 "DRefl",
1284 "Derivation",
1285 Term::Pi {
1286 param: "_".to_string(),
1287 param_type: Box::new(syntax.clone()),
1288 body_type: Box::new(Term::Pi {
1289 param: "_".to_string(),
1290 param_type: Box::new(syntax.clone()),
1291 body_type: Box::new(derivation.clone()),
1292 }),
1293 },
1294 );
1295
1296 ctx.add_constructor(
1302 "DInduction",
1303 "Derivation",
1304 Term::Pi {
1305 param: "_".to_string(),
1306 param_type: Box::new(syntax.clone()), body_type: Box::new(Term::Pi {
1308 param: "_".to_string(),
1309 param_type: Box::new(derivation.clone()), body_type: Box::new(Term::Pi {
1311 param: "_".to_string(),
1312 param_type: Box::new(derivation.clone()), body_type: Box::new(derivation.clone()),
1314 }),
1315 }),
1316 },
1317 );
1318
1319 ctx.add_constructor(
1323 "DCompute",
1324 "Derivation",
1325 Term::Pi {
1326 param: "_".to_string(),
1327 param_type: Box::new(syntax.clone()),
1328 body_type: Box::new(derivation.clone()),
1329 },
1330 );
1331
1332 ctx.add_constructor(
1338 "DCong",
1339 "Derivation",
1340 Term::Pi {
1341 param: "_".to_string(),
1342 param_type: Box::new(syntax.clone()), body_type: Box::new(Term::Pi {
1344 param: "_".to_string(),
1345 param_type: Box::new(derivation.clone()), body_type: Box::new(derivation.clone()),
1347 }),
1348 },
1349 );
1350
1351 ctx.add_constructor(
1354 "DCase",
1355 "Derivation",
1356 Term::Pi {
1357 param: "_".to_string(),
1358 param_type: Box::new(derivation.clone()), body_type: Box::new(Term::Pi {
1360 param: "_".to_string(),
1361 param_type: Box::new(derivation.clone()), body_type: Box::new(derivation.clone()),
1363 }),
1364 },
1365 );
1366
1367 ctx.add_constructor("DCaseEnd", "Derivation", derivation.clone());
1370
1371 ctx.add_constructor(
1377 "DElim",
1378 "Derivation",
1379 Term::Pi {
1380 param: "_".to_string(),
1381 param_type: Box::new(syntax.clone()), body_type: Box::new(Term::Pi {
1383 param: "_".to_string(),
1384 param_type: Box::new(syntax.clone()), body_type: Box::new(Term::Pi {
1386 param: "_".to_string(),
1387 param_type: Box::new(derivation.clone()), body_type: Box::new(derivation.clone()),
1389 }),
1390 }),
1391 },
1392 );
1393
1394 ctx.add_constructor(
1399 "DInversion",
1400 "Derivation",
1401 Term::Pi {
1402 param: "_".to_string(),
1403 param_type: Box::new(syntax.clone()),
1404 body_type: Box::new(derivation.clone()),
1405 },
1406 );
1407
1408 ctx.add_constructor(
1412 "DRewrite",
1413 "Derivation",
1414 Term::Pi {
1415 param: "_".to_string(),
1416 param_type: Box::new(derivation.clone()), body_type: Box::new(Term::Pi {
1418 param: "_".to_string(),
1419 param_type: Box::new(syntax.clone()), body_type: Box::new(Term::Pi {
1421 param: "_".to_string(),
1422 param_type: Box::new(syntax.clone()), body_type: Box::new(derivation.clone()),
1424 }),
1425 }),
1426 },
1427 );
1428
1429 ctx.add_constructor(
1435 "DDestruct",
1436 "Derivation",
1437 Term::Pi {
1438 param: "_".to_string(),
1439 param_type: Box::new(syntax.clone()), body_type: Box::new(Term::Pi {
1441 param: "_".to_string(),
1442 param_type: Box::new(syntax.clone()), body_type: Box::new(Term::Pi {
1444 param: "_".to_string(),
1445 param_type: Box::new(derivation.clone()), body_type: Box::new(derivation.clone()),
1447 }),
1448 }),
1449 },
1450 );
1451
1452 ctx.add_constructor(
1459 "DApply",
1460 "Derivation",
1461 Term::Pi {
1462 param: "_".to_string(),
1463 param_type: Box::new(syntax.clone()), body_type: Box::new(Term::Pi {
1465 param: "_".to_string(),
1466 param_type: Box::new(derivation.clone()), body_type: Box::new(Term::Pi {
1468 param: "_".to_string(),
1469 param_type: Box::new(syntax.clone()), body_type: Box::new(Term::Pi {
1471 param: "_".to_string(),
1472 param_type: Box::new(syntax), body_type: Box::new(derivation),
1474 }),
1475 }),
1476 }),
1477 },
1478 );
1479 }
1480
1481 fn register_concludes(ctx: &mut Context) {
1486 let derivation = Term::Global("Derivation".to_string());
1487 let syntax = Term::Global("Syntax".to_string());
1488
1489 let concludes_type = Term::Pi {
1491 param: "_".to_string(),
1492 param_type: Box::new(derivation),
1493 body_type: Box::new(syntax),
1494 };
1495
1496 ctx.add_declaration("concludes", concludes_type);
1497 }
1498
1499 fn register_try_refl(ctx: &mut Context) {
1510 let syntax = Term::Global("Syntax".to_string());
1511 let derivation = Term::Global("Derivation".to_string());
1512
1513 let try_refl_type = Term::Pi {
1515 param: "_".to_string(),
1516 param_type: Box::new(syntax),
1517 body_type: Box::new(derivation),
1518 };
1519
1520 ctx.add_declaration("try_refl", try_refl_type);
1521 }
1522
1523 fn register_try_compute(ctx: &mut Context) {
1530 let syntax = Term::Global("Syntax".to_string());
1531 let derivation = Term::Global("Derivation".to_string());
1532
1533 let try_compute_type = Term::Pi {
1535 param: "_".to_string(),
1536 param_type: Box::new(syntax),
1537 body_type: Box::new(derivation),
1538 };
1539
1540 ctx.add_declaration("try_compute", try_compute_type);
1541 }
1542
1543 fn register_try_cong(ctx: &mut Context) {
1550 let syntax = Term::Global("Syntax".to_string());
1551 let derivation = Term::Global("Derivation".to_string());
1552
1553 let try_cong_type = Term::Pi {
1555 param: "_".to_string(),
1556 param_type: Box::new(syntax), body_type: Box::new(Term::Pi {
1558 param: "_".to_string(),
1559 param_type: Box::new(derivation.clone()), body_type: Box::new(derivation),
1561 }),
1562 };
1563
1564 ctx.add_declaration("try_cong", try_cong_type);
1565 }
1566
1567 fn register_tact_fail(ctx: &mut Context) {
1577 let syntax = Term::Global("Syntax".to_string());
1578 let derivation = Term::Global("Derivation".to_string());
1579
1580 let tact_fail_type = Term::Pi {
1582 param: "_".to_string(),
1583 param_type: Box::new(syntax),
1584 body_type: Box::new(derivation),
1585 };
1586
1587 ctx.add_declaration("tact_fail", tact_fail_type);
1588 }
1589
1590 fn register_tact_orelse(ctx: &mut Context) {
1596 let syntax = Term::Global("Syntax".to_string());
1597 let derivation = Term::Global("Derivation".to_string());
1598
1599 let tactic_type = Term::Pi {
1601 param: "_".to_string(),
1602 param_type: Box::new(syntax.clone()),
1603 body_type: Box::new(derivation.clone()),
1604 };
1605
1606 let tact_orelse_type = Term::Pi {
1608 param: "_".to_string(),
1609 param_type: Box::new(tactic_type.clone()), body_type: Box::new(Term::Pi {
1611 param: "_".to_string(),
1612 param_type: Box::new(tactic_type), body_type: Box::new(Term::Pi {
1614 param: "_".to_string(),
1615 param_type: Box::new(syntax), body_type: Box::new(derivation),
1617 }),
1618 }),
1619 };
1620
1621 ctx.add_declaration("tact_orelse", tact_orelse_type);
1622 }
1623
1624 fn register_tact_try(ctx: &mut Context) {
1630 let syntax = Term::Global("Syntax".to_string());
1631 let derivation = Term::Global("Derivation".to_string());
1632
1633 let tactic_type = Term::Pi {
1635 param: "_".to_string(),
1636 param_type: Box::new(syntax.clone()),
1637 body_type: Box::new(derivation.clone()),
1638 };
1639
1640 let tact_try_type = Term::Pi {
1642 param: "_".to_string(),
1643 param_type: Box::new(tactic_type), body_type: Box::new(Term::Pi {
1645 param: "_".to_string(),
1646 param_type: Box::new(syntax),
1647 body_type: Box::new(derivation),
1648 }),
1649 };
1650
1651 ctx.add_declaration("tact_try", tact_try_type);
1652 }
1653
1654 fn register_tact_repeat(ctx: &mut Context) {
1660 let syntax = Term::Global("Syntax".to_string());
1661 let derivation = Term::Global("Derivation".to_string());
1662
1663 let tactic_type = Term::Pi {
1665 param: "_".to_string(),
1666 param_type: Box::new(syntax.clone()),
1667 body_type: Box::new(derivation.clone()),
1668 };
1669
1670 let tact_repeat_type = Term::Pi {
1672 param: "_".to_string(),
1673 param_type: Box::new(tactic_type), body_type: Box::new(Term::Pi {
1675 param: "_".to_string(),
1676 param_type: Box::new(syntax),
1677 body_type: Box::new(derivation),
1678 }),
1679 };
1680
1681 ctx.add_declaration("tact_repeat", tact_repeat_type);
1682 }
1683
1684 fn register_tact_then(ctx: &mut Context) {
1691 let syntax = Term::Global("Syntax".to_string());
1692 let derivation = Term::Global("Derivation".to_string());
1693
1694 let tactic_type = Term::Pi {
1696 param: "_".to_string(),
1697 param_type: Box::new(syntax.clone()),
1698 body_type: Box::new(derivation.clone()),
1699 };
1700
1701 let tact_then_type = Term::Pi {
1703 param: "_".to_string(),
1704 param_type: Box::new(tactic_type.clone()), body_type: Box::new(Term::Pi {
1706 param: "_".to_string(),
1707 param_type: Box::new(tactic_type), body_type: Box::new(Term::Pi {
1709 param: "_".to_string(),
1710 param_type: Box::new(syntax),
1711 body_type: Box::new(derivation),
1712 }),
1713 }),
1714 };
1715
1716 ctx.add_declaration("tact_then", tact_then_type);
1717 }
1718
1719 fn register_tact_first(ctx: &mut Context) {
1725 let syntax = Term::Global("Syntax".to_string());
1726 let derivation = Term::Global("Derivation".to_string());
1727
1728 let tactic_type = Term::Pi {
1730 param: "_".to_string(),
1731 param_type: Box::new(syntax.clone()),
1732 body_type: Box::new(derivation.clone()),
1733 };
1734
1735 let tactic_list_type = Term::App(
1737 Box::new(Term::Global("TList".to_string())),
1738 Box::new(tactic_type),
1739 );
1740
1741 let tact_first_type = Term::Pi {
1743 param: "_".to_string(),
1744 param_type: Box::new(tactic_list_type), body_type: Box::new(Term::Pi {
1746 param: "_".to_string(),
1747 param_type: Box::new(syntax),
1748 body_type: Box::new(derivation),
1749 }),
1750 };
1751
1752 ctx.add_declaration("tact_first", tact_first_type);
1753 }
1754
1755 fn register_tact_solve(ctx: &mut Context) {
1762 let syntax = Term::Global("Syntax".to_string());
1763 let derivation = Term::Global("Derivation".to_string());
1764
1765 let tactic_type = Term::Pi {
1767 param: "_".to_string(),
1768 param_type: Box::new(syntax.clone()),
1769 body_type: Box::new(derivation.clone()),
1770 };
1771
1772 let tact_solve_type = Term::Pi {
1774 param: "_".to_string(),
1775 param_type: Box::new(tactic_type), body_type: Box::new(Term::Pi {
1777 param: "_".to_string(),
1778 param_type: Box::new(syntax),
1779 body_type: Box::new(derivation),
1780 }),
1781 };
1782
1783 ctx.add_declaration("tact_solve", tact_solve_type);
1784 }
1785
1786 fn register_try_ring(ctx: &mut Context) {
1796 let syntax = Term::Global("Syntax".to_string());
1797 let derivation = Term::Global("Derivation".to_string());
1798
1799 ctx.add_constructor(
1802 "DRingSolve",
1803 "Derivation",
1804 Term::Pi {
1805 param: "_".to_string(),
1806 param_type: Box::new(syntax.clone()),
1807 body_type: Box::new(derivation.clone()),
1808 },
1809 );
1810
1811 let try_ring_type = Term::Pi {
1814 param: "_".to_string(),
1815 param_type: Box::new(syntax),
1816 body_type: Box::new(derivation),
1817 };
1818
1819 ctx.add_declaration("try_ring", try_ring_type);
1820 }
1821
1822 fn register_try_lia(ctx: &mut Context) {
1832 let syntax = Term::Global("Syntax".to_string());
1833 let derivation = Term::Global("Derivation".to_string());
1834
1835 ctx.add_constructor(
1838 "DLiaSolve",
1839 "Derivation",
1840 Term::Pi {
1841 param: "_".to_string(),
1842 param_type: Box::new(syntax.clone()),
1843 body_type: Box::new(derivation.clone()),
1844 },
1845 );
1846
1847 let try_lia_type = Term::Pi {
1850 param: "_".to_string(),
1851 param_type: Box::new(syntax),
1852 body_type: Box::new(derivation),
1853 };
1854
1855 ctx.add_declaration("try_lia", try_lia_type);
1856 }
1857
1858 fn register_try_cc(ctx: &mut Context) {
1865 let syntax = Term::Global("Syntax".to_string());
1866 let derivation = Term::Global("Derivation".to_string());
1867
1868 ctx.add_constructor(
1871 "DccSolve",
1872 "Derivation",
1873 Term::Pi {
1874 param: "_".to_string(),
1875 param_type: Box::new(syntax.clone()),
1876 body_type: Box::new(derivation.clone()),
1877 },
1878 );
1879
1880 let try_cc_type = Term::Pi {
1883 param: "_".to_string(),
1884 param_type: Box::new(syntax),
1885 body_type: Box::new(derivation),
1886 };
1887
1888 ctx.add_declaration("try_cc", try_cc_type);
1889 }
1890
1891 fn register_try_simp(ctx: &mut Context) {
1899 let syntax = Term::Global("Syntax".to_string());
1900 let derivation = Term::Global("Derivation".to_string());
1901
1902 ctx.add_constructor(
1905 "DSimpSolve",
1906 "Derivation",
1907 Term::Pi {
1908 param: "_".to_string(),
1909 param_type: Box::new(syntax.clone()),
1910 body_type: Box::new(derivation.clone()),
1911 },
1912 );
1913
1914 let try_simp_type = Term::Pi {
1917 param: "_".to_string(),
1918 param_type: Box::new(syntax),
1919 body_type: Box::new(derivation),
1920 };
1921
1922 ctx.add_declaration("try_simp", try_simp_type);
1923 }
1924
1925 fn register_try_omega(ctx: &mut Context) {
1934 let syntax = Term::Global("Syntax".to_string());
1935 let derivation = Term::Global("Derivation".to_string());
1936
1937 ctx.add_constructor(
1940 "DOmegaSolve",
1941 "Derivation",
1942 Term::Pi {
1943 param: "_".to_string(),
1944 param_type: Box::new(syntax.clone()),
1945 body_type: Box::new(derivation.clone()),
1946 },
1947 );
1948
1949 let try_omega_type = Term::Pi {
1952 param: "_".to_string(),
1953 param_type: Box::new(syntax),
1954 body_type: Box::new(derivation),
1955 };
1956
1957 ctx.add_declaration("try_omega", try_omega_type);
1958 }
1959
1960 fn register_try_auto(ctx: &mut Context) {
1968 let syntax = Term::Global("Syntax".to_string());
1969 let derivation = Term::Global("Derivation".to_string());
1970
1971 ctx.add_constructor(
1974 "DAutoSolve",
1975 "Derivation",
1976 Term::Pi {
1977 param: "_".to_string(),
1978 param_type: Box::new(syntax.clone()),
1979 body_type: Box::new(derivation.clone()),
1980 },
1981 );
1982
1983 let try_auto_type = Term::Pi {
1986 param: "_".to_string(),
1987 param_type: Box::new(syntax),
1988 body_type: Box::new(derivation),
1989 };
1990
1991 ctx.add_declaration("try_auto", try_auto_type);
1992 }
1993
1994 fn register_try_induction(ctx: &mut Context) {
2004 let syntax = Term::Global("Syntax".to_string());
2005 let derivation = Term::Global("Derivation".to_string());
2006
2007 let try_induction_type = Term::Pi {
2009 param: "_".to_string(),
2010 param_type: Box::new(syntax.clone()), body_type: Box::new(Term::Pi {
2012 param: "_".to_string(),
2013 param_type: Box::new(syntax.clone()), body_type: Box::new(Term::Pi {
2015 param: "_".to_string(),
2016 param_type: Box::new(derivation.clone()), body_type: Box::new(derivation),
2018 }),
2019 }),
2020 };
2021
2022 ctx.add_declaration("try_induction", try_induction_type);
2023 }
2024
2025 fn register_induction_helpers(ctx: &mut Context) {
2032 let syntax = Term::Global("Syntax".to_string());
2033 let nat = Term::Global("Nat".to_string());
2034
2035 ctx.add_declaration(
2038 "induction_base_goal",
2039 Term::Pi {
2040 param: "_".to_string(),
2041 param_type: Box::new(syntax.clone()),
2042 body_type: Box::new(Term::Pi {
2043 param: "_".to_string(),
2044 param_type: Box::new(syntax.clone()),
2045 body_type: Box::new(syntax.clone()),
2046 }),
2047 },
2048 );
2049
2050 ctx.add_declaration(
2053 "induction_step_goal",
2054 Term::Pi {
2055 param: "_".to_string(),
2056 param_type: Box::new(syntax.clone()),
2057 body_type: Box::new(Term::Pi {
2058 param: "_".to_string(),
2059 param_type: Box::new(syntax.clone()),
2060 body_type: Box::new(Term::Pi {
2061 param: "_".to_string(),
2062 param_type: Box::new(nat),
2063 body_type: Box::new(syntax.clone()),
2064 }),
2065 }),
2066 },
2067 );
2068
2069 ctx.add_declaration(
2072 "induction_num_cases",
2073 Term::Pi {
2074 param: "_".to_string(),
2075 param_type: Box::new(syntax),
2076 body_type: Box::new(Term::Global("Nat".to_string())),
2077 },
2078 );
2079 }
2080
2081 fn register_try_inversion_tactic(ctx: &mut Context) {
2095 let syntax = Term::Global("Syntax".to_string());
2096 let derivation = Term::Global("Derivation".to_string());
2097
2098 ctx.add_declaration(
2100 "try_inversion",
2101 Term::Pi {
2102 param: "_".to_string(),
2103 param_type: Box::new(syntax),
2104 body_type: Box::new(derivation),
2105 },
2106 );
2107 }
2108
2109 fn register_operator_tactics(ctx: &mut Context) {
2120 let syntax = Term::Global("Syntax".to_string());
2121 let derivation = Term::Global("Derivation".to_string());
2122
2123 ctx.add_declaration(
2126 "try_rewrite",
2127 Term::Pi {
2128 param: "_".to_string(),
2129 param_type: Box::new(derivation.clone()), body_type: Box::new(Term::Pi {
2131 param: "_".to_string(),
2132 param_type: Box::new(syntax.clone()), body_type: Box::new(derivation.clone()),
2134 }),
2135 },
2136 );
2137
2138 ctx.add_declaration(
2141 "try_rewrite_rev",
2142 Term::Pi {
2143 param: "_".to_string(),
2144 param_type: Box::new(derivation.clone()), body_type: Box::new(Term::Pi {
2146 param: "_".to_string(),
2147 param_type: Box::new(syntax.clone()), body_type: Box::new(derivation.clone()),
2149 }),
2150 },
2151 );
2152
2153 ctx.add_declaration(
2156 "try_destruct",
2157 Term::Pi {
2158 param: "_".to_string(),
2159 param_type: Box::new(syntax.clone()), body_type: Box::new(Term::Pi {
2161 param: "_".to_string(),
2162 param_type: Box::new(syntax.clone()), body_type: Box::new(Term::Pi {
2164 param: "_".to_string(),
2165 param_type: Box::new(derivation.clone()), body_type: Box::new(derivation.clone()),
2167 }),
2168 }),
2169 },
2170 );
2171
2172 ctx.add_declaration(
2175 "try_apply",
2176 Term::Pi {
2177 param: "_".to_string(),
2178 param_type: Box::new(syntax.clone()), body_type: Box::new(Term::Pi {
2180 param: "_".to_string(),
2181 param_type: Box::new(derivation.clone()), body_type: Box::new(Term::Pi {
2183 param: "_".to_string(),
2184 param_type: Box::new(syntax), body_type: Box::new(derivation),
2186 }),
2187 }),
2188 },
2189 );
2190 }
2191
2192 fn register_hw_tactics(ctx: &mut Context) {
2197 let syntax = Term::Global("Syntax".to_string());
2198 let derivation = Term::Global("Derivation".to_string());
2199
2200 ctx.add_constructor(
2202 "DBitblastSolve",
2203 "Derivation",
2204 Term::Pi {
2205 param: "_".to_string(),
2206 param_type: Box::new(syntax.clone()),
2207 body_type: Box::new(derivation.clone()),
2208 },
2209 );
2210
2211 ctx.add_declaration(
2213 "try_bitblast",
2214 Term::Pi {
2215 param: "_".to_string(),
2216 param_type: Box::new(syntax.clone()),
2217 body_type: Box::new(derivation.clone()),
2218 },
2219 );
2220
2221 ctx.add_constructor(
2223 "DTabulateSolve",
2224 "Derivation",
2225 Term::Pi {
2226 param: "_".to_string(),
2227 param_type: Box::new(syntax.clone()),
2228 body_type: Box::new(derivation.clone()),
2229 },
2230 );
2231
2232 ctx.add_declaration(
2234 "try_tabulate",
2235 Term::Pi {
2236 param: "_".to_string(),
2237 param_type: Box::new(syntax.clone()),
2238 body_type: Box::new(derivation.clone()),
2239 },
2240 );
2241
2242 ctx.add_constructor(
2244 "DHwAutoSolve",
2245 "Derivation",
2246 Term::Pi {
2247 param: "_".to_string(),
2248 param_type: Box::new(syntax.clone()),
2249 body_type: Box::new(derivation.clone()),
2250 },
2251 );
2252
2253 ctx.add_declaration(
2255 "try_hw_auto",
2256 Term::Pi {
2257 param: "_".to_string(),
2258 param_type: Box::new(syntax.clone()),
2259 body_type: Box::new(derivation),
2260 },
2261 );
2262 }
2263
2264 fn register_hardware(ctx: &mut Context) {
2270 Self::register_bit(ctx);
2271 Self::register_hw_unit(ctx);
2272 Self::register_bvec(ctx);
2273 Self::register_gate_ops(ctx);
2274 Self::register_circuit(ctx);
2275 Self::register_bvec_ops(ctx);
2276 }
2277
2278 fn register_bit(ctx: &mut Context) {
2282 let bit = Term::Global("Bit".to_string());
2283 ctx.add_inductive("Bit", Term::Sort(Universe::Type(0)));
2284 ctx.add_constructor("B0", "Bit", bit.clone());
2285 ctx.add_constructor("B1", "Bit", bit);
2286 }
2287
2288 fn register_hw_unit(ctx: &mut Context) {
2291 let unit = Term::Global("Unit".to_string());
2292 ctx.add_inductive("Unit", Term::Sort(Universe::Type(0)));
2293 ctx.add_constructor("Tt", "Unit", unit);
2294 }
2295
2296 fn register_bvec(ctx: &mut Context) {
2300 let type0 = Term::Sort(Universe::Type(0));
2301 let nat = Term::Global("Nat".to_string());
2302 let n = Term::Var("n".to_string());
2303
2304 let bvec_type = Term::Pi {
2306 param: "n".to_string(),
2307 param_type: Box::new(nat.clone()),
2308 body_type: Box::new(type0),
2309 };
2310 ctx.add_inductive("BVec", bvec_type);
2311
2312 let bvec_zero = Term::App(
2314 Box::new(Term::Global("BVec".to_string())),
2315 Box::new(Term::Global("Zero".to_string())),
2316 );
2317 ctx.add_constructor("BVNil", "BVec", bvec_zero);
2318
2319 let bit = Term::Global("Bit".to_string());
2321 let bvec_n = Term::App(
2322 Box::new(Term::Global("BVec".to_string())),
2323 Box::new(n.clone()),
2324 );
2325 let bvec_succ_n = Term::App(
2326 Box::new(Term::Global("BVec".to_string())),
2327 Box::new(Term::App(
2328 Box::new(Term::Global("Succ".to_string())),
2329 Box::new(n.clone()),
2330 )),
2331 );
2332 let bvcons_type = Term::Pi {
2333 param: "_".to_string(),
2334 param_type: Box::new(bit),
2335 body_type: Box::new(Term::Pi {
2336 param: "n".to_string(),
2337 param_type: Box::new(nat),
2338 body_type: Box::new(Term::Pi {
2339 param: "_".to_string(),
2340 param_type: Box::new(bvec_n),
2341 body_type: Box::new(bvec_succ_n),
2342 }),
2343 }),
2344 };
2345 ctx.add_constructor("BVCons", "BVec", bvcons_type);
2346 }
2347
2348 fn register_gate_ops(ctx: &mut Context) {
2356 let bit = Term::Global("Bit".to_string());
2357
2358 let bit2_type = Term::Pi {
2360 param: "_".to_string(),
2361 param_type: Box::new(bit.clone()),
2362 body_type: Box::new(Term::Pi {
2363 param: "_".to_string(),
2364 param_type: Box::new(bit.clone()),
2365 body_type: Box::new(bit.clone()),
2366 }),
2367 };
2368
2369 let bit1_type = Term::Pi {
2371 param: "_".to_string(),
2372 param_type: Box::new(bit.clone()),
2373 body_type: Box::new(bit.clone()),
2374 };
2375
2376 let bit3_type = Term::Pi {
2378 param: "_".to_string(),
2379 param_type: Box::new(bit.clone()),
2380 body_type: Box::new(Term::Pi {
2381 param: "_".to_string(),
2382 param_type: Box::new(bit.clone()),
2383 body_type: Box::new(Term::Pi {
2384 param: "_".to_string(),
2385 param_type: Box::new(bit.clone()),
2386 body_type: Box::new(bit.clone()),
2387 }),
2388 }),
2389 };
2390
2391 let motive = Term::Lambda {
2393 param: "_".to_string(),
2394 param_type: Box::new(bit.clone()),
2395 body: Box::new(bit.clone()),
2396 };
2397
2398 let bit_and_body = Term::Lambda {
2400 param: "a".to_string(),
2401 param_type: Box::new(bit.clone()),
2402 body: Box::new(Term::Lambda {
2403 param: "b".to_string(),
2404 param_type: Box::new(bit.clone()),
2405 body: Box::new(Term::Match {
2406 discriminant: Box::new(Term::Var("a".to_string())),
2407 motive: Box::new(motive.clone()),
2408 cases: vec![
2409 Term::Global("B0".to_string()), Term::Var("b".to_string()), ],
2412 }),
2413 }),
2414 };
2415 ctx.add_definition("bit_and".to_string(), bit2_type.clone(), bit_and_body);
2416
2417 let bit_or_body = Term::Lambda {
2419 param: "a".to_string(),
2420 param_type: Box::new(bit.clone()),
2421 body: Box::new(Term::Lambda {
2422 param: "b".to_string(),
2423 param_type: Box::new(bit.clone()),
2424 body: Box::new(Term::Match {
2425 discriminant: Box::new(Term::Var("a".to_string())),
2426 motive: Box::new(motive.clone()),
2427 cases: vec![
2428 Term::Var("b".to_string()), Term::Global("B1".to_string()), ],
2431 }),
2432 }),
2433 };
2434 ctx.add_definition("bit_or".to_string(), bit2_type.clone(), bit_or_body);
2435
2436 let bit_not_body = Term::Lambda {
2438 param: "a".to_string(),
2439 param_type: Box::new(bit.clone()),
2440 body: Box::new(Term::Match {
2441 discriminant: Box::new(Term::Var("a".to_string())),
2442 motive: Box::new(motive.clone()),
2443 cases: vec![
2444 Term::Global("B1".to_string()), Term::Global("B0".to_string()), ],
2447 }),
2448 };
2449 ctx.add_definition("bit_not".to_string(), bit1_type, bit_not_body);
2450
2451 let bit_xor_body = Term::Lambda {
2456 param: "a".to_string(),
2457 param_type: Box::new(bit.clone()),
2458 body: Box::new(Term::Lambda {
2459 param: "b".to_string(),
2460 param_type: Box::new(bit.clone()),
2461 body: Box::new(Term::Match {
2462 discriminant: Box::new(Term::Var("a".to_string())),
2463 motive: Box::new(motive.clone()),
2464 cases: vec![
2465 Term::Var("b".to_string()),
2467 Term::App(
2469 Box::new(Term::Global("bit_not".to_string())),
2470 Box::new(Term::Var("b".to_string())),
2471 ),
2472 ],
2473 }),
2474 }),
2475 };
2476 ctx.add_definition("bit_xor".to_string(), bit2_type, bit_xor_body);
2477
2478 let bit_mux_body = Term::Lambda {
2481 param: "sel".to_string(),
2482 param_type: Box::new(bit.clone()),
2483 body: Box::new(Term::Lambda {
2484 param: "then_v".to_string(),
2485 param_type: Box::new(bit.clone()),
2486 body: Box::new(Term::Lambda {
2487 param: "else_v".to_string(),
2488 param_type: Box::new(bit.clone()),
2489 body: Box::new(Term::Match {
2490 discriminant: Box::new(Term::Var("sel".to_string())),
2491 motive: Box::new(motive),
2492 cases: vec![
2493 Term::Var("else_v".to_string()), Term::Var("then_v".to_string()), ],
2496 }),
2497 }),
2498 }),
2499 };
2500 ctx.add_definition("bit_mux".to_string(), bit3_type, bit_mux_body);
2501 }
2502
2503 fn register_circuit(ctx: &mut Context) {
2507 let type0 = Term::Sort(Universe::Type(0));
2508 let s = Term::Var("S".to_string());
2509 let i = Term::Var("I".to_string());
2510 let o = Term::Var("O".to_string());
2511
2512 let circuit_type = Term::Pi {
2514 param: "S".to_string(),
2515 param_type: Box::new(type0.clone()),
2516 body_type: Box::new(Term::Pi {
2517 param: "I".to_string(),
2518 param_type: Box::new(type0.clone()),
2519 body_type: Box::new(Term::Pi {
2520 param: "O".to_string(),
2521 param_type: Box::new(type0.clone()),
2522 body_type: Box::new(type0.clone()),
2523 }),
2524 }),
2525 };
2526 ctx.add_inductive("Circuit", circuit_type);
2527
2528 let circuit_s_i_o = Term::App(
2530 Box::new(Term::App(
2531 Box::new(Term::App(
2532 Box::new(Term::Global("Circuit".to_string())),
2533 Box::new(s.clone()),
2534 )),
2535 Box::new(i.clone()),
2536 )),
2537 Box::new(o.clone()),
2538 );
2539
2540 let trans_type = Term::Pi {
2542 param: "_".to_string(),
2543 param_type: Box::new(s.clone()),
2544 body_type: Box::new(Term::Pi {
2545 param: "_".to_string(),
2546 param_type: Box::new(i.clone()),
2547 body_type: Box::new(s.clone()),
2548 }),
2549 };
2550
2551 let out_type = Term::Pi {
2553 param: "_".to_string(),
2554 param_type: Box::new(s.clone()),
2555 body_type: Box::new(Term::Pi {
2556 param: "_".to_string(),
2557 param_type: Box::new(i.clone()),
2558 body_type: Box::new(o.clone()),
2559 }),
2560 };
2561
2562 let mkcircuit_type = Term::Pi {
2565 param: "S".to_string(),
2566 param_type: Box::new(type0.clone()),
2567 body_type: Box::new(Term::Pi {
2568 param: "I".to_string(),
2569 param_type: Box::new(type0.clone()),
2570 body_type: Box::new(Term::Pi {
2571 param: "O".to_string(),
2572 param_type: Box::new(type0),
2573 body_type: Box::new(Term::Pi {
2574 param: "_".to_string(),
2575 param_type: Box::new(trans_type),
2576 body_type: Box::new(Term::Pi {
2577 param: "_".to_string(),
2578 param_type: Box::new(out_type),
2579 body_type: Box::new(Term::Pi {
2580 param: "_".to_string(),
2581 param_type: Box::new(s),
2582 body_type: Box::new(circuit_s_i_o),
2583 }),
2584 }),
2585 }),
2586 }),
2587 }),
2588 };
2589 ctx.add_constructor("MkCircuit", "Circuit", mkcircuit_type);
2590 }
2591
2592 fn register_bvec_ops(ctx: &mut Context) {
2595 let nat = Term::Global("Nat".to_string());
2596 let n = Term::Var("n".to_string());
2597 let bvec_n = Term::App(
2598 Box::new(Term::Global("BVec".to_string())),
2599 Box::new(n.clone()),
2600 );
2601
2602 let bv_binop_type = Term::Pi {
2604 param: "n".to_string(),
2605 param_type: Box::new(nat.clone()),
2606 body_type: Box::new(Term::Pi {
2607 param: "_".to_string(),
2608 param_type: Box::new(bvec_n.clone()),
2609 body_type: Box::new(Term::Pi {
2610 param: "_".to_string(),
2611 param_type: Box::new(bvec_n.clone()),
2612 body_type: Box::new(bvec_n.clone()),
2613 }),
2614 }),
2615 };
2616
2617 let bv_unop_type = Term::Pi {
2619 param: "n".to_string(),
2620 param_type: Box::new(nat.clone()),
2621 body_type: Box::new(Term::Pi {
2622 param: "_".to_string(),
2623 param_type: Box::new(bvec_n.clone()),
2624 body_type: Box::new(bvec_n.clone()),
2625 }),
2626 };
2627
2628 let bvec_of = |m: Term| -> Term {
2630 Term::App(Box::new(Term::Global("BVec".to_string())), Box::new(m))
2631 };
2632
2633 let motive_n = Term::Lambda {
2636 param: "_".to_string(),
2637 param_type: Box::new(bvec_n.clone()),
2638 body: Box::new(bvec_n.clone()),
2639 };
2640
2641 let bit = Term::Global("Bit".to_string());
2651
2652 let bv_and_body = Self::make_bvec_binop_fix(
2653 "bv_and_rec", "bit_and", &nat, &bvec_n, &bit, &motive_n,
2654 );
2655 ctx.add_definition("bv_and".to_string(), bv_binop_type.clone(), bv_and_body);
2656
2657 let bv_or_body = Self::make_bvec_binop_fix(
2659 "bv_or_rec", "bit_or", &nat, &bvec_n, &bit, &motive_n,
2660 );
2661 ctx.add_definition("bv_or".to_string(), bv_binop_type.clone(), bv_or_body);
2662
2663 let bv_xor_body = Self::make_bvec_binop_fix(
2665 "bv_xor_rec", "bit_xor", &nat, &bvec_n, &bit, &motive_n,
2666 );
2667 ctx.add_definition("bv_xor".to_string(), bv_binop_type, bv_xor_body);
2668
2669 let bv_not_body = Self::make_bvec_unop_fix(
2676 "bv_not_rec", "bit_not", &nat, &bvec_n, &bit, &motive_n,
2677 );
2678 ctx.add_definition("bv_not".to_string(), bv_unop_type, bv_not_body);
2679 }
2680
2681 fn make_bvec_binop_fix(
2685 rec_name: &str,
2686 bit_op: &str,
2687 nat: &Term,
2688 bvec_n: &Term,
2689 bit: &Term,
2690 motive: &Term,
2691 ) -> Term {
2692 let m_var = Term::Var("m".to_string());
2693 let bvec_m = Term::App(Box::new(Term::Global("BVec".to_string())), Box::new(m_var.clone()));
2694 let motive_m = Term::Lambda {
2695 param: "_".to_string(),
2696 param_type: Box::new(bvec_m.clone()),
2697 body: Box::new(bvec_m.clone()),
2698 };
2699
2700 let bit_op_applied = Term::App(
2702 Box::new(Term::App(
2703 Box::new(Term::Global(bit_op.to_string())),
2704 Box::new(Term::Var("b1".to_string())),
2705 )),
2706 Box::new(Term::Var("b2".to_string())),
2707 );
2708 let rec_call = Term::App(
2709 Box::new(Term::App(
2710 Box::new(Term::App(
2711 Box::new(Term::Var(rec_name.to_string())),
2712 Box::new(m_var.clone()),
2713 )),
2714 Box::new(Term::Var("tail1".to_string())),
2715 )),
2716 Box::new(Term::Var("tail2".to_string())),
2717 );
2718 let bvcons_result = Term::App(
2719 Box::new(Term::App(
2720 Box::new(Term::App(
2721 Box::new(Term::Global("BVCons".to_string())),
2722 Box::new(bit_op_applied),
2723 )),
2724 Box::new(m_var.clone()),
2725 )),
2726 Box::new(rec_call),
2727 );
2728
2729 let inner_bvcons_case = Term::Lambda {
2731 param: "b2".to_string(),
2732 param_type: Box::new(bit.clone()),
2733 body: Box::new(Term::Lambda {
2734 param: "_m2".to_string(),
2735 param_type: Box::new(nat.clone()),
2736 body: Box::new(Term::Lambda {
2737 param: "tail2".to_string(),
2738 param_type: Box::new(bvec_m.clone()),
2739 body: Box::new(bvcons_result),
2740 }),
2741 }),
2742 };
2743
2744 let inner_match = Term::Match {
2745 discriminant: Box::new(Term::Var("v2".to_string())),
2746 motive: Box::new(motive_m.clone()),
2747 cases: vec![
2748 Term::Global("BVNil".to_string()), inner_bvcons_case, ],
2751 };
2752
2753 let outer_bvcons_case = Term::Lambda {
2755 param: "b1".to_string(),
2756 param_type: Box::new(bit.clone()),
2757 body: Box::new(Term::Lambda {
2758 param: "m".to_string(),
2759 param_type: Box::new(nat.clone()),
2760 body: Box::new(Term::Lambda {
2761 param: "tail1".to_string(),
2762 param_type: Box::new(bvec_m.clone()),
2763 body: Box::new(inner_match),
2764 }),
2765 }),
2766 };
2767
2768 let outer_match = Term::Match {
2770 discriminant: Box::new(Term::Var("v1".to_string())),
2771 motive: Box::new(motive.clone()),
2772 cases: vec![
2773 Term::Global("BVNil".to_string()), outer_bvcons_case, ],
2776 };
2777
2778 Term::Fix {
2780 name: rec_name.to_string(),
2781 body: Box::new(Term::Lambda {
2782 param: "n".to_string(),
2783 param_type: Box::new(nat.clone()),
2784 body: Box::new(Term::Lambda {
2785 param: "v1".to_string(),
2786 param_type: Box::new(bvec_n.clone()),
2787 body: Box::new(Term::Lambda {
2788 param: "v2".to_string(),
2789 param_type: Box::new(bvec_n.clone()),
2790 body: Box::new(outer_match),
2791 }),
2792 }),
2793 }),
2794 }
2795 }
2796
2797 fn make_bvec_unop_fix(
2801 rec_name: &str,
2802 bit_op: &str,
2803 nat: &Term,
2804 bvec_n: &Term,
2805 bit: &Term,
2806 motive: &Term,
2807 ) -> Term {
2808 let m_var = Term::Var("m".to_string());
2809 let bvec_m = Term::App(Box::new(Term::Global("BVec".to_string())), Box::new(m_var.clone()));
2810
2811 let bit_op_applied = Term::App(
2813 Box::new(Term::Global(bit_op.to_string())),
2814 Box::new(Term::Var("b".to_string())),
2815 );
2816 let rec_call = Term::App(
2817 Box::new(Term::App(
2818 Box::new(Term::Var(rec_name.to_string())),
2819 Box::new(m_var.clone()),
2820 )),
2821 Box::new(Term::Var("tail".to_string())),
2822 );
2823 let bvcons_result = Term::App(
2824 Box::new(Term::App(
2825 Box::new(Term::App(
2826 Box::new(Term::Global("BVCons".to_string())),
2827 Box::new(bit_op_applied),
2828 )),
2829 Box::new(m_var.clone()),
2830 )),
2831 Box::new(rec_call),
2832 );
2833
2834 let bvcons_case = Term::Lambda {
2836 param: "b".to_string(),
2837 param_type: Box::new(bit.clone()),
2838 body: Box::new(Term::Lambda {
2839 param: "m".to_string(),
2840 param_type: Box::new(nat.clone()),
2841 body: Box::new(Term::Lambda {
2842 param: "tail".to_string(),
2843 param_type: Box::new(bvec_m),
2844 body: Box::new(bvcons_result),
2845 }),
2846 }),
2847 };
2848
2849 let match_expr = Term::Match {
2851 discriminant: Box::new(Term::Var("v".to_string())),
2852 motive: Box::new(motive.clone()),
2853 cases: vec![
2854 Term::Global("BVNil".to_string()), bvcons_case, ],
2857 };
2858
2859 Term::Fix {
2861 name: rec_name.to_string(),
2862 body: Box::new(Term::Lambda {
2863 param: "n".to_string(),
2864 param_type: Box::new(nat.clone()),
2865 body: Box::new(Term::Lambda {
2866 param: "v".to_string(),
2867 param_type: Box::new(bvec_n.clone()),
2868 body: Box::new(match_expr),
2869 }),
2870 }),
2871 }
2872 }
2873}