1use crate::env_builder::{app, bvar, pi, pi_implicit, pi_named, prop, sort, var, EnvBuilder};
6use oxilean_kernel::{Declaration, Environment, Expr, Level, Name};
7
8use super::types::{
9 DecisionResult, EqBuilder, EqChain, EqRewriteRule, EqualityDatabase, EqualityWitness, PropEq,
10 RewriteRuleDb, SetoidMorphism,
11};
12
13pub fn eq_refl(alpha: Expr, a: Expr) -> Expr {
18 app(app(app(var("Eq.refl"), alpha), a.clone()), a)
19}
20pub fn eq_symm(alpha: Expr, a: Expr, b: Expr, h: Expr) -> Expr {
24 app(
25 app(app(app(app(var("Eq.symm"), alpha), a), b), h.clone()),
26 h,
27 )
28}
29pub fn eq_trans(alpha: Expr, a: Expr, b: Expr, c: Expr, h1: Expr, h2: Expr) -> Expr {
33 app(
34 app(
35 app(app(app(app(app(var("Eq.trans"), alpha), a), b), c), h1),
36 h2.clone(),
37 ),
38 h2,
39 )
40}
41pub fn eq_subst(alpha: Expr, pred: Expr, a: Expr, b: Expr, h: Expr, ha: Expr) -> Expr {
45 app(
46 app(app(app(app(app(var("Eq.subst"), alpha), pred), a), b), h),
47 ha,
48 )
49}
50pub fn congr_arg(alpha: Expr, beta: Expr, a: Expr, b: Expr, f: Expr, h: Expr) -> Expr {
54 app(
55 app(app(app(app(app(var("congrArg"), alpha), beta), a), b), f),
56 h,
57 )
58}
59pub fn congr_fun(alpha: Expr, beta: Expr, f: Expr, g: Expr, h: Expr, a: Expr) -> Expr {
63 app(
64 app(app(app(app(app(var("congrFun"), alpha), beta), f), g), h),
65 a,
66 )
67}
68pub fn heq_refl(alpha: Expr, a: Expr) -> Expr {
72 app(app(var("HEq.refl"), alpha), a)
73}
74pub fn eq_of_heq(alpha: Expr, a: Expr, b: Expr, h: Expr) -> Expr {
78 app(app(app(app(var("eq_of_heq"), alpha), a), b), h)
79}
80pub fn heq_of_eq(alpha: Expr, a: Expr, b: Expr, h: Expr) -> Expr {
84 app(app(app(app(var("heq_of_eq"), alpha), a), b), h)
85}
86pub fn build_beq_env(env: &mut EnvBuilder, type_name: &str, beq_fn: Expr) {
91 let inst_name = format!("instBEq{type_name}");
92 let ty = var(&format!("{type_name}.BEq"));
93 let body = app(var("BEq.mk"), beq_fn);
94 env.add_definition(Name::from_str(&inst_name), ty, body);
95}
96pub fn build_decidable_eq_env(env: &mut EnvBuilder, type_name: &str, dec_fn: Expr) {
100 let inst_name = format!("instDecidableEq{type_name}");
101 let ty = pi(var(type_name), pi(var(type_name), var("Prop")));
102 let body = app(var("DecidableEq.mk"), dec_fn);
103 env.add_definition(Name::from_str(&inst_name), ty, body);
104}
105pub fn build_heq_env(env: &mut EnvBuilder) {
110 env.add_axiom(Name::from_str("HEq"), sort(1));
111 env.add_axiom(Name::from_str("HEq.refl"), sort(1));
112 env.add_axiom(Name::from_str("HEq.symm"), sort(1));
113 env.add_axiom(Name::from_str("HEq.trans"), sort(1));
114 env.add_axiom(Name::from_str("heq_of_eq"), sort(1));
115 env.add_axiom(Name::from_str("eq_of_heq"), sort(1));
116}
117pub trait DecidableEq: PartialEq {
122 fn decide_eq(&self, other: &Self) -> bool {
124 self == other
125 }
126 fn witness_eq(&self, other: &Self) -> Option<()> {
128 if self == other {
129 Some(())
130 } else {
131 None
132 }
133 }
134}
135impl DecidableEq for u8 {}
136impl DecidableEq for u16 {}
137impl DecidableEq for u32 {}
138impl DecidableEq for u64 {}
139impl DecidableEq for usize {}
140impl DecidableEq for i8 {}
141impl DecidableEq for i16 {}
142impl DecidableEq for i32 {}
143impl DecidableEq for i64 {}
144impl DecidableEq for isize {}
145impl DecidableEq for bool {}
146impl DecidableEq for char {}
147impl DecidableEq for String {}
148impl DecidableEq for str {}
149impl<T: PartialEq> DecidableEq for Vec<T> {}
150impl<T: PartialEq> DecidableEq for Option<T> {}
151impl<A: PartialEq, B: PartialEq> DecidableEq for (A, B) {}
152pub fn structural_eq(a: &Expr, b: &Expr) -> bool {
156 a == b
157}
158pub fn name_eq(a: &Name, b: &Name) -> bool {
160 a == b
161}
162pub fn exprs_eq(xs: &[Expr], ys: &[Expr]) -> bool {
167 xs.len() == ys.len() && xs.iter().zip(ys).all(|(x, y)| x == y)
168}
169pub fn decide_u32_eq(a: u32, b: u32) -> DecisionResult<()> {
171 if a == b {
172 DecisionResult::IsTrue(())
173 } else {
174 DecisionResult::IsFalse(format!("{a} ≠{b}"))
175 }
176}
177pub fn decide_str_eq(a: &str, b: &str) -> DecisionResult<()> {
179 if a == b {
180 DecisionResult::IsTrue(())
181 } else {
182 DecisionResult::IsFalse(format!("{a:?} ≠{b:?}"))
183 }
184}
185pub fn decide_name_eq(a: &Name, b: &Name) -> DecisionResult<()> {
187 if a == b {
188 DecisionResult::IsTrue(())
189 } else {
190 DecisionResult::IsFalse(format!("{a} ≠{b}"))
191 }
192}
193pub trait Setoid {
198 fn equiv(&self, other: &Self) -> bool;
200 fn refl(&self) -> bool {
202 self.equiv(self)
203 }
204 fn symm(&self, other: &Self) -> bool {
206 if self.equiv(other) {
207 other.equiv(self)
208 } else {
209 true
210 }
211 }
212}
213impl<T: PartialEq> Setoid for T {
214 fn equiv(&self, other: &Self) -> bool {
215 self == other
216 }
217}
218pub fn congr<A, B>(f: impl Fn(A) -> B, a: A) -> B {
223 f(a)
224}
225pub fn refl<T: PartialEq>(a: T) -> EqualityWitness<T> {
229 EqualityWitness { value: a }
230}
231pub fn subst<T, P>(_witness: &EqualityWitness<T>, pa: P) -> P {
236 pa
237}
238pub fn as_eq(e: &Expr) -> Option<(Expr, Expr, Expr)> {
243 match e {
244 Expr::App(f, rhs) => match f.as_ref() {
245 Expr::App(g, lhs) => match g.as_ref() {
246 Expr::App(h, ty) => match h.as_ref() {
247 Expr::Const(n, _) if n.to_string() == "Eq" => Some((
248 ty.as_ref().clone(),
249 lhs.as_ref().clone(),
250 rhs.as_ref().clone(),
251 )),
252 _ => None,
253 },
254 _ => None,
255 },
256 _ => None,
257 },
258 _ => None,
259 }
260}
261pub fn as_heq(e: &Expr) -> Option<(Expr, Expr, Expr, Expr)> {
263 match e {
264 Expr::App(f, rhs) => match f.as_ref() {
265 Expr::App(g, lhs) => match g.as_ref() {
266 Expr::App(h, rhs_ty) => match h.as_ref() {
267 Expr::App(i, lhs_ty) => match i.as_ref() {
268 Expr::Const(n, _) if n.to_string() == "HEq" => Some((
269 lhs_ty.as_ref().clone(),
270 lhs.as_ref().clone(),
271 rhs_ty.as_ref().clone(),
272 rhs.as_ref().clone(),
273 )),
274 _ => None,
275 },
276 _ => None,
277 },
278 _ => None,
279 },
280 _ => None,
281 },
282 _ => None,
283 }
284}
285pub fn mk_eq(ty: Expr, lhs: Expr, rhs: Expr) -> Expr {
287 app(app(app(var("Eq"), ty), lhs), rhs)
288}
289pub fn mk_heq(lhs_ty: Expr, lhs: Expr, rhs_ty: Expr, rhs: Expr) -> Expr {
291 app(app(app(app(var("HEq"), lhs_ty), lhs), rhs_ty), rhs)
292}
293pub fn build_eq_env(env: &mut EnvBuilder) {
298 env.add_axiom(Name::from_str("Eq"), sort(1));
299 env.add_axiom(
300 Name::from_str("Eq.refl"),
301 pi_implicit(
302 "α",
303 sort(1),
304 pi_named(
305 "a",
306 bvar(0),
307 app(app(app(var("Eq"), bvar(1)), bvar(0)), bvar(0)),
308 ),
309 ),
310 );
311 env.add_axiom(
312 Name::from_str("Eq.symm"),
313 pi_implicit(
314 "α",
315 sort(1),
316 pi_implicit(
317 "a",
318 bvar(0),
319 pi_implicit(
320 "b",
321 bvar(1),
322 pi(
323 app(app(app(var("Eq"), bvar(2)), bvar(1)), bvar(0)),
324 app(app(app(var("Eq"), bvar(3)), bvar(1)), bvar(2)),
325 ),
326 ),
327 ),
328 ),
329 );
330 env.add_axiom(
331 Name::from_str("Eq.trans"),
332 pi_implicit(
333 "α",
334 sort(1),
335 pi_implicit(
336 "a",
337 bvar(0),
338 pi_implicit(
339 "b",
340 bvar(1),
341 pi_implicit(
342 "c",
343 bvar(2),
344 pi(
345 app(app(app(var("Eq"), bvar(3)), bvar(2)), bvar(1)),
346 pi(
347 app(app(app(var("Eq"), bvar(4)), bvar(2)), bvar(1)),
348 app(app(app(var("Eq"), bvar(5)), bvar(4)), bvar(2)),
349 ),
350 ),
351 ),
352 ),
353 ),
354 ),
355 );
356 env.add_axiom(
357 Name::from_str("Eq.subst"),
358 pi_implicit(
359 "α",
360 sort(1),
361 pi_implicit(
362 "motive",
363 pi(bvar(0), prop()),
364 pi_implicit(
365 "a",
366 bvar(1),
367 pi_implicit(
368 "b",
369 bvar(2),
370 pi(
371 app(app(app(var("Eq"), bvar(3)), bvar(1)), bvar(0)),
372 pi(app(bvar(3), bvar(2)), app(bvar(4), bvar(2))),
373 ),
374 ),
375 ),
376 ),
377 ),
378 );
379 env.add_axiom(
380 Name::from_str("congrArg"),
381 pi_implicit(
382 "α",
383 sort(1),
384 pi_implicit(
385 "β",
386 sort(1),
387 pi_named(
388 "f",
389 pi(bvar(1), bvar(1)),
390 pi_implicit(
391 "a",
392 bvar(2),
393 pi_implicit(
394 "b",
395 bvar(3),
396 pi(
397 app(app(app(var("Eq"), bvar(4)), bvar(1)), bvar(0)),
398 app(
399 app(app(var("Eq"), bvar(4)), app(bvar(3), bvar(2))),
400 app(bvar(3), bvar(1)),
401 ),
402 ),
403 ),
404 ),
405 ),
406 ),
407 ),
408 );
409 env.add_axiom(
410 Name::from_str("congrFun"),
411 pi_implicit(
412 "α",
413 sort(1),
414 pi_implicit(
415 "β",
416 sort(1),
417 pi_implicit(
418 "f",
419 pi(bvar(1), bvar(1)),
420 pi_implicit(
421 "g",
422 pi(bvar(2), bvar(2)),
423 pi(
424 app(app(app(var("Eq"), pi(bvar(3), bvar(3))), bvar(1)), bvar(0)),
425 pi_named(
426 "a",
427 bvar(4),
428 app(
429 app(app(var("Eq"), bvar(4)), app(bvar(3), bvar(0))),
430 app(bvar(2), bvar(0)),
431 ),
432 ),
433 ),
434 ),
435 ),
436 ),
437 ),
438 );
439 env.add_axiom(
440 Name::from_str("congr"),
441 pi_implicit(
442 "α",
443 sort(1),
444 pi_implicit(
445 "β",
446 sort(1),
447 pi_implicit(
448 "f",
449 pi(bvar(1), bvar(1)),
450 pi_implicit(
451 "g",
452 pi(bvar(2), bvar(2)),
453 pi(
454 app(app(app(var("Eq"), pi(bvar(3), bvar(3))), bvar(1)), bvar(0)),
455 pi_implicit(
456 "a",
457 bvar(4),
458 pi_implicit(
459 "b",
460 bvar(5),
461 pi(
462 app(app(app(var("Eq"), bvar(6)), bvar(1)), bvar(0)),
463 app(
464 app(app(var("Eq"), bvar(6)), app(bvar(5), bvar(2))),
465 app(bvar(4), bvar(1)),
466 ),
467 ),
468 ),
469 ),
470 ),
471 ),
472 ),
473 ),
474 ),
475 );
476}
477pub fn build_eq_mpr_env(env: &mut EnvBuilder) {
479 env.add_axiom(
480 Name::from_str("Eq.mpr"),
481 pi_implicit(
482 "α",
483 prop(),
484 pi_implicit(
485 "β",
486 prop(),
487 pi(
488 app(app(app(var("Eq"), prop()), bvar(1)), bvar(0)),
489 pi(bvar(1), bvar(3)),
490 ),
491 ),
492 ),
493 );
494 env.add_axiom(
495 Name::from_str("Eq.mp"),
496 pi_implicit(
497 "α",
498 prop(),
499 pi_implicit(
500 "β",
501 prop(),
502 pi(
503 app(app(app(var("Eq"), prop()), bvar(1)), bvar(0)),
504 pi(bvar(2), bvar(2)),
505 ),
506 ),
507 ),
508 );
509 env.add_axiom(
510 Name::from_str("id.def"),
511 pi_implicit(
512 "α",
513 sort(1),
514 pi_implicit(
515 "a",
516 bvar(0),
517 app(app(app(var("Eq"), bvar(1)), bvar(0)), bvar(0)),
518 ),
519 ),
520 );
521}
522#[cfg(test)]
523mod tests {
524 use super::*;
525 #[test]
526 fn test_prop_eq_refl() {
527 let ty = var("Nat");
528 let a = var("x");
529 let eq = PropEq::refl(ty, a.clone());
530 assert!(eq.is_refl());
531 assert_eq!(eq.lhs, a);
532 assert_eq!(eq.rhs, a);
533 }
534 #[test]
535 fn test_prop_eq_symm() {
536 let ty = var("Nat");
537 let a = var("a");
538 let b = var("b");
539 let eq = PropEq::new(ty.clone(), a.clone(), b.clone());
540 let sym = eq.symm();
541 assert_eq!(sym.lhs, b);
542 assert_eq!(sym.rhs, a);
543 }
544 #[test]
545 fn test_prop_eq_trans() {
546 let ty = var("Nat");
547 let a = var("a");
548 let b = var("b");
549 let c = var("c");
550 let e1 = PropEq::new(ty.clone(), a.clone(), b.clone());
551 let e2 = PropEq::new(ty.clone(), b.clone(), c.clone());
552 let e3 = e1.trans(e2).expect("trans should succeed");
553 assert_eq!(e3.lhs, a);
554 assert_eq!(e3.rhs, c);
555 }
556 #[test]
557 fn test_prop_eq_trans_mismatch() {
558 let ty = var("Nat");
559 let a = var("a");
560 let b = var("b");
561 let c = var("c");
562 let e1 = PropEq::new(ty.clone(), a.clone(), b.clone());
563 let e2 = PropEq::new(ty.clone(), c.clone(), a.clone());
564 assert!(e1.trans(e2).is_none());
565 }
566 #[test]
567 fn test_eq_chain_collapse() {
568 let ty = var("Nat");
569 let a = var("a");
570 let b = var("b");
571 let c = var("c");
572 let mut chain = EqChain::new(ty.clone());
573 chain.push(PropEq::new(ty.clone(), a.clone(), b.clone()));
574 chain.push(PropEq::new(ty.clone(), b.clone(), c.clone()));
575 let collapsed = chain.collapse().expect("collapse should succeed");
576 assert_eq!(collapsed.lhs, a);
577 assert_eq!(collapsed.rhs, c);
578 }
579 #[test]
580 fn test_eq_chain_empty() {
581 let chain = EqChain::new(var("Nat"));
582 assert!(chain.is_empty());
583 assert!(chain.collapse().is_none());
584 }
585 #[test]
586 fn test_decision_result_and() {
587 let a: DecisionResult<()> = DecisionResult::IsTrue(());
588 let b: DecisionResult<()> = DecisionResult::IsTrue(());
589 let ab = a.and(b);
590 assert!(ab.is_true());
591 }
592 #[test]
593 fn test_decision_result_and_false() {
594 let a: DecisionResult<()> = DecisionResult::IsTrue(());
595 let b: DecisionResult<()> = DecisionResult::IsFalse("no".to_string());
596 let ab = a.and(b);
597 assert!(ab.is_false());
598 }
599 #[test]
600 fn test_decision_result_or() {
601 let a: DecisionResult<()> = DecisionResult::IsFalse("no".to_string());
602 let b: DecisionResult<()> = DecisionResult::IsTrue(());
603 let ab = a.or(b);
604 assert!(ab.is_true());
605 }
606 #[test]
607 fn test_equality_database_lookup() {
608 let mut db = EqualityDatabase::new();
609 let a = Name::from_str("a");
610 let b = Name::from_str("b");
611 db.register(a.clone(), b.clone(), var("proof_ab"));
612 let found = db.lookup(&a, &b);
613 assert!(found.is_some());
614 }
615 #[test]
616 fn test_equality_database_symm() {
617 let mut db = EqualityDatabase::new();
618 let a = Name::from_str("a");
619 let b = Name::from_str("b");
620 db.register(a.clone(), b.clone(), var("proof_ab"));
621 let found = db.lookup(&b, &a);
622 assert!(found.is_some());
623 }
624 #[test]
625 fn test_decide_str_eq() {
626 assert!(decide_str_eq("hello", "hello").is_true());
627 assert!(decide_str_eq("hello", "world").is_false());
628 }
629 #[test]
630 fn test_decide_u32_eq() {
631 assert!(decide_u32_eq(42, 42).is_true());
632 assert!(decide_u32_eq(42, 43).is_false());
633 }
634 #[test]
635 fn test_equality_witness() {
636 let w = EqualityWitness::try_new(&42u32, &42u32);
637 assert!(w.is_some());
638 let w = EqualityWitness::try_new(&1u32, &2u32);
639 assert!(w.is_none());
640 }
641 #[test]
642 fn test_exprs_eq() {
643 let a = vec![var("x"), var("y")];
644 let b = vec![var("x"), var("y")];
645 assert!(exprs_eq(&a, &b));
646 let c = vec![var("x"), var("z")];
647 assert!(!exprs_eq(&a, &c));
648 }
649 #[test]
650 fn test_mk_eq_and_as_eq() {
651 let ty = var("Nat");
652 let lhs = var("a");
653 let rhs = var("b");
654 let eq_expr = mk_eq(ty.clone(), lhs.clone(), rhs.clone());
655 let parsed = as_eq(&eq_expr);
656 assert!(parsed.is_some());
657 let (t, l, r) = parsed.expect("parsed should be valid");
658 assert_eq!(t, ty);
659 assert_eq!(l, lhs);
660 assert_eq!(r, rhs);
661 }
662 #[test]
663 fn test_equality_database_len() {
664 let mut db = EqualityDatabase::new();
665 assert_eq!(db.len(), 0);
666 assert!(db.is_empty());
667 db.register(Name::from_str("a"), Name::from_str("b"), var("p"));
668 assert_eq!(db.len(), 1);
669 assert!(!db.is_empty());
670 }
671 #[test]
672 fn test_eq_chain_len() {
673 let ty = var("Nat");
674 let a = var("a");
675 let b = var("b");
676 let c = var("c");
677 let mut chain = EqChain::new(ty.clone());
678 chain.push(PropEq::new(ty.clone(), a.clone(), b.clone()));
679 chain.push(PropEq::new(ty.clone(), b.clone(), c.clone()));
680 assert_eq!(chain.len(), 2);
681 }
682}
683pub fn exprs_eq_pairwise(a: &[oxilean_kernel::Expr], b: &[oxilean_kernel::Expr]) -> Vec<bool> {
685 if a.len() != b.len() {
686 return vec![];
687 }
688 a.iter().zip(b.iter()).map(|(x, y)| x == y).collect()
689}
690pub fn count_diffs(a: &[oxilean_kernel::Expr], b: &[oxilean_kernel::Expr]) -> usize {
692 a.iter().zip(b.iter()).filter(|(x, y)| x != y).count()
693}
694pub fn exprs_eq_mod_permutation(a: &[oxilean_kernel::Expr], b: &[oxilean_kernel::Expr]) -> bool {
698 if a.len() != b.len() {
699 return false;
700 }
701 let mut used = vec![false; b.len()];
702 'outer: for ea in a {
703 for (j, eb) in b.iter().enumerate() {
704 if !used[j] && ea == eb {
705 used[j] = true;
706 continue 'outer;
707 }
708 }
709 return false;
710 }
711 true
712}
713pub fn extensionally_equal<A, B: PartialEq>(
717 f: impl Fn(&A) -> B,
718 g: impl Fn(&A) -> B,
719 test_points: &[A],
720) -> bool {
721 test_points.iter().all(|x| f(x) == g(x))
722}
723pub fn leibniz_subst<T: PartialEq, P>(_a: &T, _b: &T, witness: &EqualityWitness<T>, pa: P) -> P {
728 let _ = witness;
729 pa
730}
731pub fn is_refl_proof(e: &oxilean_kernel::Expr) -> Option<oxilean_kernel::Expr> {
735 match e {
736 oxilean_kernel::Expr::App(f, a) => match f.as_ref() {
737 oxilean_kernel::Expr::App(g, _alpha) => match g.as_ref() {
738 oxilean_kernel::Expr::Const(n, _) if n.to_string() == "Eq.refl" => {
739 Some(a.as_ref().clone())
740 }
741 _ => None,
742 },
743 _ => None,
744 },
745 _ => None,
746 }
747}
748#[cfg(test)]
749mod eq_extended_tests {
750 use super::*;
751 fn v(s: &str) -> oxilean_kernel::Expr {
752 var(s)
753 }
754 fn n(s: &str) -> oxilean_kernel::Name {
755 oxilean_kernel::Name::from_str(s)
756 }
757 #[test]
758 fn test_exprs_eq_pairwise_same() {
759 let a = vec![v("x"), v("y")];
760 let b = vec![v("x"), v("y")];
761 let result = exprs_eq_pairwise(&a, &b);
762 assert!(result.iter().all(|&b| b));
763 }
764 #[test]
765 fn test_exprs_eq_pairwise_diff() {
766 let a = vec![v("x"), v("y")];
767 let b = vec![v("x"), v("z")];
768 let result = exprs_eq_pairwise(&a, &b);
769 assert!(result[0]);
770 assert!(!result[1]);
771 }
772 #[test]
773 fn test_exprs_eq_pairwise_length_mismatch() {
774 let result = exprs_eq_pairwise(&[v("x")], &[v("x"), v("y")]);
775 assert!(result.is_empty());
776 }
777 #[test]
778 fn test_count_diffs() {
779 let a = vec![v("x"), v("y"), v("z")];
780 let b = vec![v("x"), v("a"), v("z")];
781 assert_eq!(count_diffs(&a, &b), 1);
782 }
783 #[test]
784 fn test_exprs_eq_mod_permutation_same() {
785 let a = vec![v("x"), v("y")];
786 let b = vec![v("y"), v("x")];
787 assert!(exprs_eq_mod_permutation(&a, &b));
788 }
789 #[test]
790 fn test_exprs_eq_mod_permutation_diff() {
791 let a = vec![v("x"), v("y")];
792 let b = vec![v("x"), v("z")];
793 assert!(!exprs_eq_mod_permutation(&a, &b));
794 }
795 #[test]
796 fn test_eq_builder_empty() {
797 let b = EqBuilder::start(v("Nat"), v("a"));
798 assert_eq!(b.num_steps(), 0);
799 assert!(b.build().is_none());
800 }
801 #[test]
802 fn test_eq_builder_one_step() {
803 let builder = EqBuilder::start(v("Nat"), v("a")).step(v("b"), v("proof_ab"));
804 let eq = builder.build();
805 assert!(eq.is_some());
806 }
807 #[test]
808 fn test_extensionally_equal() {
809 let f = |x: &u32| x * 2;
810 let g = |x: &u32| x + x;
811 let pts = [0u32, 1, 2, 3, 4];
812 assert!(extensionally_equal(f, g, &pts));
813 }
814 #[test]
815 fn test_extensionally_not_equal() {
816 let f = |x: &u32| x + 1;
817 let g = |x: &u32| x * 2;
818 let pts = [0u32, 1, 2];
819 assert!(!extensionally_equal(f, g, &pts));
820 }
821 #[test]
822 fn test_leibniz_subst() {
823 let w = EqualityWitness { value: 42u32 };
824 let pa = "result";
825 let result = leibniz_subst(&42u32, &42u32, &w, pa);
826 assert_eq!(result, "result");
827 }
828 #[test]
829 fn test_eq_rewrite_rule_apply() {
830 let rule = EqRewriteRule::new(n("r"), v("a"), v("b"));
831 assert!(rule.matches(&v("a")));
832 assert_eq!(rule.apply(&v("a")), Some(v("b")));
833 assert!(rule.apply(&v("c")).is_none());
834 }
835 #[test]
836 fn test_eq_rewrite_rule_reversed() {
837 let rule = EqRewriteRule::new(n("r"), v("a"), v("b")).make_reversible();
838 let rev = rule.reversed().expect("reversed should succeed");
839 assert_eq!(rev.lhs, v("b"));
840 assert_eq!(rev.rhs, v("a"));
841 }
842 #[test]
843 fn test_eq_rewrite_rule_not_reversible() {
844 let rule = EqRewriteRule::new(n("r"), v("a"), v("b"));
845 assert!(rule.reversed().is_none());
846 }
847 #[test]
848 fn test_rewrite_rule_db_add_find() {
849 let mut db = RewriteRuleDb::new();
850 db.add(EqRewriteRule::new(n("r1"), v("x"), v("y")));
851 let found = db.find_match(&v("x"));
852 assert!(found.is_some());
853 assert_eq!(found.expect("found should be valid").rhs, v("y"));
854 }
855 #[test]
856 fn test_rewrite_rule_db_apply_all() {
857 let mut db = RewriteRuleDb::new();
858 db.add(EqRewriteRule::new(n("r1"), v("x"), v("y")));
859 db.add(EqRewriteRule::new(n("r2"), v("x"), v("z")));
860 let results = db.apply_all(&v("x"));
861 assert_eq!(results.len(), 2);
862 }
863 #[test]
864 fn test_rewrite_rule_db_remove() {
865 let mut db = RewriteRuleDb::new();
866 db.add(EqRewriteRule::new(n("r1"), v("x"), v("y")));
867 db.remove(&n("r1"));
868 assert!(db.is_empty());
869 }
870 #[test]
871 fn test_is_refl_proof_none() {
872 let e = v("not_refl");
873 assert!(is_refl_proof(&e).is_none());
874 }
875}
876pub fn eq_ext_app(f: Expr, a: Expr) -> Expr {
877 Expr::App(Box::new(f), Box::new(a))
878}
879pub fn eq_ext_app2(f: Expr, a: Expr, b: Expr) -> Expr {
880 eq_ext_app(eq_ext_app(f, a), b)
881}
882pub fn eq_ext_cst(s: &str) -> Expr {
883 Expr::Const(Name::str(s), vec![])
884}
885pub fn eq_ext_prop() -> Expr {
886 Expr::Sort(Level::zero())
887}
888pub fn eq_ext_type0() -> Expr {
889 Expr::Sort(Level::succ(Level::zero()))
890}
891pub fn eq_ext_bvar(n: u32) -> Expr {
892 Expr::BVar(n)
893}
894pub fn eq_ext_nat_ty() -> Expr {
895 eq_ext_cst("Nat")
896}
897pub fn eq_ext_bool_ty() -> Expr {
898 eq_ext_cst("Bool")
899}
900pub fn eq_ext_arrow(dom: Expr, cod: Expr) -> Expr {
901 Expr::Pi(
902 oxilean_kernel::BinderInfo::Default,
903 Name::Anonymous,
904 Box::new(dom),
905 Box::new(cod),
906 )
907}
908pub fn mk_eq_class_refl_ty() -> Expr {
911 pi_implicit(
912 "α",
913 sort(1),
914 pi_named(
915 "a",
916 bvar(0),
917 app(app(app(var("Eq"), bvar(1)), bvar(0)), bvar(0)),
918 ),
919 )
920}
921pub fn mk_eq_class_symm_ty() -> Expr {
924 pi_implicit(
925 "α",
926 sort(1),
927 pi_implicit(
928 "a",
929 bvar(0),
930 pi_implicit(
931 "b",
932 bvar(1),
933 pi(
934 app(app(app(var("Eq"), bvar(2)), bvar(1)), bvar(0)),
935 app(app(app(var("Eq"), bvar(3)), bvar(1)), bvar(2)),
936 ),
937 ),
938 ),
939 )
940}
941pub fn mk_eq_class_trans_ty() -> Expr {
944 pi_implicit(
945 "α",
946 sort(1),
947 pi_implicit(
948 "a",
949 bvar(0),
950 pi_implicit(
951 "b",
952 bvar(1),
953 pi_implicit(
954 "c",
955 bvar(2),
956 pi(
957 app(app(app(var("Eq"), bvar(3)), bvar(2)), bvar(1)),
958 pi(
959 app(app(app(var("Eq"), bvar(4)), bvar(2)), bvar(1)),
960 app(app(app(var("Eq"), bvar(5)), bvar(4)), bvar(2)),
961 ),
962 ),
963 ),
964 ),
965 ),
966 )
967}
968pub fn mk_beq_eq_consistency_ty() -> Expr {
971 pi_implicit(
972 "α",
973 sort(1),
974 pi_implicit(
975 "a",
976 bvar(0),
977 pi_implicit(
978 "b",
979 bvar(1),
980 pi(
981 app(
982 app(
983 app(var("Eq"), eq_ext_bool_ty()),
984 app(app(var("BEq.beq"), bvar(1)), bvar(0)),
985 ),
986 var("Bool.true"),
987 ),
988 app(app(app(var("Eq"), bvar(3)), bvar(2)), bvar(1)),
989 ),
990 ),
991 ),
992 )
993}
994pub fn mk_nat_decidable_eq_ty() -> Expr {
997 pi_named(
998 "a",
999 eq_ext_nat_ty(),
1000 pi_named(
1001 "b",
1002 eq_ext_nat_ty(),
1003 app(
1004 var("Decidable"),
1005 app(app(app(var("Eq"), eq_ext_nat_ty()), bvar(1)), bvar(0)),
1006 ),
1007 ),
1008 )
1009}
1010pub fn mk_bool_decidable_eq_ty() -> Expr {
1012 pi_named(
1013 "a",
1014 eq_ext_bool_ty(),
1015 pi_named(
1016 "b",
1017 eq_ext_bool_ty(),
1018 app(
1019 var("Decidable"),
1020 app(app(app(var("Eq"), eq_ext_bool_ty()), bvar(1)), bvar(0)),
1021 ),
1022 ),
1023 )
1024}
1025pub fn mk_char_decidable_eq_ty() -> Expr {
1027 pi_named(
1028 "a",
1029 eq_ext_cst("Char"),
1030 pi_named(
1031 "b",
1032 eq_ext_cst("Char"),
1033 app(
1034 var("Decidable"),
1035 app(app(app(var("Eq"), eq_ext_cst("Char")), bvar(1)), bvar(0)),
1036 ),
1037 ),
1038 )
1039}
1040pub fn mk_float_eq_decidable_ty() -> Expr {
1042 pi_named(
1043 "a",
1044 eq_ext_cst("Float"),
1045 pi_named(
1046 "b",
1047 eq_ext_cst("Float"),
1048 app(
1049 var("Decidable"),
1050 app(app(app(var("Eq"), eq_ext_cst("Float")), bvar(1)), bvar(0)),
1051 ),
1052 ),
1053 )
1054}
1055pub fn mk_int_decidable_eq_ty() -> Expr {
1057 pi_named(
1058 "a",
1059 eq_ext_cst("Int"),
1060 pi_named(
1061 "b",
1062 eq_ext_cst("Int"),
1063 app(
1064 var("Decidable"),
1065 app(app(app(var("Eq"), eq_ext_cst("Int")), bvar(1)), bvar(0)),
1066 ),
1067 ),
1068 )
1069}
1070pub fn mk_list_decidable_eq_ty() -> Expr {
1073 pi_implicit(
1074 "α",
1075 sort(1),
1076 pi_named(
1077 "xs",
1078 app(var("List"), bvar(0)),
1079 pi_named(
1080 "ys",
1081 app(var("List"), bvar(1)),
1082 app(
1083 var("Decidable"),
1084 app(
1085 app(app(var("Eq"), app(var("List"), bvar(2))), bvar(1)),
1086 bvar(0),
1087 ),
1088 ),
1089 ),
1090 ),
1091 )
1092}
1093pub fn mk_option_decidable_eq_ty() -> Expr {
1095 pi_implicit(
1096 "α",
1097 sort(1),
1098 pi_named(
1099 "x",
1100 app(var("Option"), bvar(0)),
1101 pi_named(
1102 "y",
1103 app(var("Option"), bvar(1)),
1104 app(
1105 var("Decidable"),
1106 app(
1107 app(app(var("Eq"), app(var("Option"), bvar(2))), bvar(1)),
1108 bvar(0),
1109 ),
1110 ),
1111 ),
1112 ),
1113 )
1114}
1115pub fn mk_pair_decidable_eq_ty() -> Expr {
1117 pi_implicit(
1118 "α",
1119 sort(1),
1120 pi_implicit(
1121 "β",
1122 sort(1),
1123 pi_named(
1124 "p",
1125 app(app(var("Prod"), bvar(1)), bvar(0)),
1126 pi_named(
1127 "q",
1128 app(app(var("Prod"), bvar(2)), bvar(1)),
1129 app(
1130 var("Decidable"),
1131 app(
1132 app(
1133 app(var("Eq"), app(app(var("Prod"), bvar(3)), bvar(2))),
1134 bvar(1),
1135 ),
1136 bvar(0),
1137 ),
1138 ),
1139 ),
1140 ),
1141 ),
1142 )
1143}
1144pub fn mk_leibniz_eq_ty() -> Expr {
1147 pi_implicit(
1148 "α",
1149 sort(1),
1150 pi_named(
1151 "a",
1152 bvar(0),
1153 pi_named(
1154 "b",
1155 bvar(1),
1156 pi(
1157 pi_named(
1158 "P",
1159 pi(bvar(2), eq_ext_prop()),
1160 pi(app(bvar(0), bvar(2)), app(bvar(1), bvar(2))),
1161 ),
1162 app(app(app(var("Eq"), bvar(3)), bvar(2)), bvar(1)),
1163 ),
1164 ),
1165 ),
1166 )
1167}
1168pub fn mk_leibniz_subst_ty() -> Expr {
1171 pi_implicit(
1172 "α",
1173 sort(1),
1174 pi_implicit(
1175 "a",
1176 bvar(0),
1177 pi_implicit(
1178 "b",
1179 bvar(1),
1180 pi(
1181 app(app(app(var("Eq"), bvar(2)), bvar(1)), bvar(0)),
1182 pi_named(
1183 "P",
1184 pi(bvar(3), eq_ext_prop()),
1185 pi(app(bvar(0), bvar(3)), app(bvar(1), bvar(2))),
1186 ),
1187 ),
1188 ),
1189 ),
1190 )
1191}
1192pub fn mk_eq_reflection_ty() -> Expr {
1195 mk_leibniz_subst_ty()
1196}
1197pub fn mk_k_axiom_ty() -> Expr {
1200 pi_implicit(
1201 "α",
1202 sort(1),
1203 pi_implicit(
1204 "a",
1205 bvar(0),
1206 pi_named(
1207 "p",
1208 app(app(app(var("Eq"), bvar(1)), bvar(0)), bvar(0)),
1209 app(
1210 app(
1211 app(
1212 var("Eq"),
1213 app(app(app(var("Eq"), bvar(2)), bvar(1)), bvar(1)),
1214 ),
1215 bvar(0),
1216 ),
1217 app(app(var("Eq.refl"), bvar(2)), bvar(1)),
1218 ),
1219 ),
1220 ),
1221 )
1222}
1223pub fn mk_uip_ty() -> Expr {
1226 pi_implicit(
1227 "α",
1228 sort(1),
1229 pi_implicit(
1230 "a",
1231 bvar(0),
1232 pi_implicit(
1233 "b",
1234 bvar(1),
1235 pi_named(
1236 "p",
1237 app(app(app(var("Eq"), bvar(2)), bvar(1)), bvar(0)),
1238 pi_named(
1239 "q",
1240 app(app(app(var("Eq"), bvar(3)), bvar(2)), bvar(1)),
1241 app(
1242 app(
1243 app(
1244 var("Eq"),
1245 app(app(app(var("Eq"), bvar(4)), bvar(3)), bvar(2)),
1246 ),
1247 bvar(1),
1248 ),
1249 bvar(0),
1250 ),
1251 ),
1252 ),
1253 ),
1254 ),
1255 )
1256}
1257pub fn mk_j_axiom_ty() -> Expr {
1259 pi_implicit(
1260 "α",
1261 sort(1),
1262 pi_implicit(
1263 "a",
1264 bvar(0),
1265 pi_named(
1266 "P",
1267 pi_named(
1268 "b",
1269 bvar(1),
1270 pi(
1271 app(app(app(var("Eq"), bvar(2)), bvar(2)), bvar(0)),
1272 eq_ext_prop(),
1273 ),
1274 ),
1275 pi(
1276 app(
1277 app(bvar(0), bvar(1)),
1278 app(app(var("Eq.refl"), bvar(2)), bvar(1)),
1279 ),
1280 pi_implicit(
1281 "b",
1282 bvar(3),
1283 pi_named(
1284 "h",
1285 app(app(app(var("Eq"), bvar(4)), bvar(4)), bvar(0)),
1286 app(app(bvar(3), bvar(1)), bvar(0)),
1287 ),
1288 ),
1289 ),
1290 ),
1291 ),
1292 )
1293}
1294pub fn mk_heq_intro_ty() -> Expr {
1297 pi_implicit(
1298 "α",
1299 sort(1),
1300 pi_named(
1301 "a",
1302 bvar(0),
1303 app(
1304 app(app(app(var("HEq"), bvar(1)), bvar(0)), bvar(1)),
1305 bvar(0),
1306 ),
1307 ),
1308 )
1309}
1310pub fn mk_heq_type_eq_ty() -> Expr {
1313 pi_implicit(
1314 "α",
1315 sort(1),
1316 pi_implicit(
1317 "β",
1318 sort(1),
1319 pi_implicit(
1320 "a",
1321 bvar(1),
1322 pi_implicit(
1323 "b",
1324 bvar(1),
1325 pi(
1326 app(
1327 app(app(app(var("HEq"), bvar(3)), bvar(1)), bvar(2)),
1328 bvar(0),
1329 ),
1330 app(app(app(var("Eq"), sort(1)), bvar(4)), bvar(3)),
1331 ),
1332 ),
1333 ),
1334 ),
1335 )
1336}
1337pub fn mk_subst_axiom_ty() -> Expr {
1340 pi_implicit(
1341 "α",
1342 sort(1),
1343 pi_implicit(
1344 "a",
1345 bvar(0),
1346 pi_implicit(
1347 "b",
1348 bvar(1),
1349 pi_named(
1350 "P",
1351 pi(bvar(2), sort(1)),
1352 pi(
1353 app(app(app(var("Eq"), bvar(3)), bvar(2)), bvar(1)),
1354 pi(app(bvar(1), bvar(3)), app(bvar(2), bvar(3))),
1355 ),
1356 ),
1357 ),
1358 ),
1359 )
1360}
1361pub fn mk_cong_axiom_ty() -> Expr {
1364 pi_implicit(
1365 "α",
1366 sort(1),
1367 pi_implicit(
1368 "β",
1369 sort(1),
1370 pi_named(
1371 "f",
1372 pi(bvar(1), bvar(1)),
1373 pi_implicit(
1374 "a",
1375 bvar(2),
1376 pi_implicit(
1377 "b",
1378 bvar(3),
1379 pi(
1380 app(app(app(var("Eq"), bvar(4)), bvar(1)), bvar(0)),
1381 app(
1382 app(app(var("Eq"), bvar(4)), app(bvar(2), bvar(2))),
1383 app(bvar(2), bvar(1)),
1384 ),
1385 ),
1386 ),
1387 ),
1388 ),
1389 ),
1390 )
1391}
1392pub fn mk_funext_ty() -> Expr {
1395 pi_implicit(
1396 "α",
1397 sort(1),
1398 pi_implicit(
1399 "β",
1400 sort(1),
1401 pi_named(
1402 "f",
1403 pi(bvar(1), bvar(1)),
1404 pi_named(
1405 "g",
1406 pi(bvar(2), bvar(2)),
1407 pi(
1408 pi_named(
1409 "x",
1410 bvar(3),
1411 app(
1412 app(app(var("Eq"), bvar(3)), app(bvar(2), bvar(0))),
1413 app(bvar(1), bvar(0)),
1414 ),
1415 ),
1416 app(app(app(var("Eq"), pi(bvar(4), bvar(4))), bvar(2)), bvar(1)),
1417 ),
1418 ),
1419 ),
1420 ),
1421 )
1422}
1423pub fn mk_propext_ty() -> Expr {
1426 pi_named(
1427 "P",
1428 eq_ext_prop(),
1429 pi_named(
1430 "Q",
1431 eq_ext_prop(),
1432 pi(
1433 app(app(var("And"), pi(bvar(1), bvar(1))), pi(bvar(1), bvar(2))),
1434 app(app(app(var("Eq"), eq_ext_prop()), bvar(2)), bvar(1)),
1435 ),
1436 ),
1437 )
1438}
1439pub fn mk_quotient_sound_ty() -> Expr {
1441 pi_implicit(
1442 "α",
1443 sort(1),
1444 pi_named(
1445 "r",
1446 pi(bvar(0), pi(bvar(1), eq_ext_prop())),
1447 pi_named(
1448 "a",
1449 bvar(1),
1450 pi_named(
1451 "b",
1452 bvar(2),
1453 pi(
1454 app(app(bvar(2), bvar(1)), bvar(0)),
1455 app(
1456 app(
1457 app(var("Eq"), app(var("Quotient"), bvar(4))),
1458 app(app(var("Quotient.mk"), bvar(4)), bvar(2)),
1459 ),
1460 app(app(var("Quotient.mk"), bvar(5)), bvar(1)),
1461 ),
1462 ),
1463 ),
1464 ),
1465 ),
1466 )
1467}
1468pub fn mk_bisim_eq_ty() -> Expr {
1470 pi_implicit(
1471 "α",
1472 sort(1),
1473 pi_named(
1474 "R",
1475 pi(bvar(0), pi(bvar(1), eq_ext_prop())),
1476 pi(
1477 app(var("Bisimulation"), bvar(0)),
1478 pi_named(
1479 "a",
1480 bvar(2),
1481 pi_named(
1482 "b",
1483 bvar(3),
1484 pi(
1485 app(app(bvar(3), bvar(1)), bvar(0)),
1486 app(app(app(var("Eq"), bvar(5)), bvar(2)), bvar(1)),
1487 ),
1488 ),
1489 ),
1490 ),
1491 ),
1492 )
1493}
1494pub fn mk_obs_eq_ty() -> Expr {
1496 pi_implicit(
1497 "α",
1498 sort(1),
1499 pi_named(
1500 "a",
1501 bvar(0),
1502 pi_named(
1503 "b",
1504 bvar(1),
1505 pi(
1506 pi_named(
1507 "P",
1508 pi(bvar(2), eq_ext_prop()),
1509 app(
1510 app(var("And"), pi(app(bvar(0), bvar(2)), app(bvar(1), bvar(2)))),
1511 pi(app(bvar(1), bvar(2)), app(bvar(0), bvar(3))),
1512 ),
1513 ),
1514 app(app(app(var("Eq"), bvar(3)), bvar(2)), bvar(1)),
1515 ),
1516 ),
1517 ),
1518 )
1519}
1520pub fn mk_setoid_ax_ty() -> Expr {
1522 pi_named(
1523 "α",
1524 sort(1),
1525 pi_named(
1526 "r",
1527 pi(bvar(0), pi(bvar(1), eq_ext_prop())),
1528 pi(
1529 app(var("IsEquivalence"), bvar(0)),
1530 app(var("Setoid"), bvar(2)),
1531 ),
1532 ),
1533 )
1534}
1535pub fn mk_setoid_morphism_ax_ty() -> Expr {
1537 pi_implicit(
1538 "α",
1539 sort(1),
1540 pi_implicit(
1541 "β",
1542 sort(1),
1543 pi_named(
1544 "f",
1545 pi(bvar(1), bvar(1)),
1546 pi(
1547 app(var("Respects"), bvar(0)),
1548 app(var("SetoidMorphism"), bvar(1)),
1549 ),
1550 ),
1551 ),
1552 )
1553}
1554pub fn mk_path_concat_ty() -> Expr {
1556 mk_eq_class_trans_ty()
1557}
1558pub fn mk_path_inv_ty() -> Expr {
1560 mk_eq_class_symm_ty()
1561}
1562pub fn mk_def_eq_mltt_ty() -> Expr {
1564 pi_implicit(
1565 "α",
1566 sort(1),
1567 pi_named(
1568 "a",
1569 bvar(0),
1570 app(app(app(var("Eq"), bvar(1)), bvar(0)), bvar(0)),
1571 ),
1572 )
1573}
1574pub fn mk_decidable_eq_instance_ty() -> Expr {
1576 pi_implicit(
1577 "α",
1578 sort(1),
1579 pi_named(
1580 "a",
1581 bvar(0),
1582 pi_named(
1583 "b",
1584 bvar(1),
1585 app(
1586 var("Decidable"),
1587 app(app(app(var("Eq"), bvar(2)), bvar(1)), bvar(0)),
1588 ),
1589 ),
1590 ),
1591 )
1592}
1593pub fn mk_homotopy_equiv_ty() -> Expr {
1595 pi_implicit(
1596 "α",
1597 sort(1),
1598 pi_implicit(
1599 "β",
1600 sort(1),
1601 pi(
1602 app(app(var("HomotopyEquiv"), bvar(1)), bvar(0)),
1603 app(var("Nonempty"), app(app(var("Equiv"), bvar(2)), bvar(1))),
1604 ),
1605 ),
1606 )
1607}
1608pub fn mk_cong_closure_ty() -> Expr {
1610 pi_implicit(
1611 "α",
1612 sort(1),
1613 pi_named(
1614 "f",
1615 pi(bvar(0), bvar(0)),
1616 pi_named(
1617 "a",
1618 bvar(1),
1619 pi_named(
1620 "b",
1621 bvar(2),
1622 pi(
1623 app(app(app(var("Eq"), bvar(3)), bvar(1)), bvar(0)),
1624 app(
1625 app(app(var("Eq"), bvar(4)), app(bvar(2), bvar(2))),
1626 app(bvar(2), bvar(1)),
1627 ),
1628 ),
1629 ),
1630 ),
1631 ),
1632 )
1633}
1634pub fn mk_subsingleton_eq_ty() -> Expr {
1636 pi_implicit(
1637 "α",
1638 sort(1),
1639 pi_named(
1640 "a",
1641 bvar(0),
1642 pi_named(
1643 "b",
1644 bvar(1),
1645 app(app(app(var("Eq"), bvar(2)), bvar(1)), bvar(0)),
1646 ),
1647 ),
1648 )
1649}
1650pub fn mk_sigma_eq_ty() -> Expr {
1652 pi_implicit(
1653 "α",
1654 sort(1),
1655 pi_named(
1656 "s",
1657 app(var("Sigma"), bvar(0)),
1658 pi_named(
1659 "t",
1660 app(var("Sigma"), bvar(1)),
1661 pi(
1662 app(
1663 app(app(var("Eq"), app(var("Sigma"), bvar(2))), bvar(1)),
1664 bvar(0),
1665 ),
1666 app(
1667 app(app(var("Eq"), bvar(3)), app(var("Sigma.fst"), bvar(2))),
1668 app(var("Sigma.fst"), bvar(1)),
1669 ),
1670 ),
1671 ),
1672 ),
1673 )
1674}
1675pub fn mk_subtype_eq_ty() -> Expr {
1677 pi_implicit(
1678 "α",
1679 sort(1),
1680 pi_named(
1681 "s",
1682 app(var("Subtype"), bvar(0)),
1683 pi_named(
1684 "t",
1685 app(var("Subtype"), bvar(1)),
1686 pi(
1687 app(
1688 app(app(var("Eq"), bvar(2)), app(var("Subtype.val"), bvar(1))),
1689 app(var("Subtype.val"), bvar(0)),
1690 ),
1691 app(
1692 app(app(var("Eq"), app(var("Subtype"), bvar(3))), bvar(2)),
1693 bvar(1),
1694 ),
1695 ),
1696 ),
1697 ),
1698 )
1699}
1700pub fn mk_fun_eq_pointwise_ty() -> Expr {
1702 pi_implicit(
1703 "α",
1704 sort(1),
1705 pi_implicit(
1706 "β",
1707 sort(1),
1708 pi_implicit(
1709 "f",
1710 pi(bvar(1), bvar(1)),
1711 pi_implicit(
1712 "g",
1713 pi(bvar(2), bvar(2)),
1714 pi(
1715 app(app(app(var("Eq"), pi(bvar(3), bvar(3))), bvar(1)), bvar(0)),
1716 pi_named(
1717 "x",
1718 bvar(4),
1719 app(
1720 app(app(var("Eq"), bvar(4)), app(bvar(3), bvar(0))),
1721 app(bvar(2), bvar(0)),
1722 ),
1723 ),
1724 ),
1725 ),
1726 ),
1727 ),
1728 )
1729}
1730pub fn mk_either_decidable_eq_ty() -> Expr {
1732 pi_implicit(
1733 "α",
1734 sort(1),
1735 pi_implicit(
1736 "β",
1737 sort(1),
1738 pi_named(
1739 "x",
1740 app(app(var("Sum"), bvar(1)), bvar(0)),
1741 pi_named(
1742 "y",
1743 app(app(var("Sum"), bvar(2)), bvar(1)),
1744 app(
1745 var("Decidable"),
1746 app(
1747 app(
1748 app(var("Eq"), app(app(var("Sum"), bvar(3)), bvar(2))),
1749 bvar(1),
1750 ),
1751 bvar(0),
1752 ),
1753 ),
1754 ),
1755 ),
1756 ),
1757 )
1758}
1759pub fn mk_result_decidable_eq_ty() -> Expr {
1761 pi_implicit(
1762 "α",
1763 sort(1),
1764 pi_implicit(
1765 "ε",
1766 sort(1),
1767 pi_named(
1768 "x",
1769 app(app(var("Except"), bvar(1)), bvar(0)),
1770 pi_named(
1771 "y",
1772 app(app(var("Except"), bvar(2)), bvar(1)),
1773 app(
1774 var("Decidable"),
1775 app(
1776 app(
1777 app(var("Eq"), app(app(var("Except"), bvar(3)), bvar(2))),
1778 bvar(1),
1779 ),
1780 bvar(0),
1781 ),
1782 ),
1783 ),
1784 ),
1785 ),
1786 )
1787}
1788pub fn mk_eq_ndrec_ty() -> Expr {
1790 pi_implicit(
1791 "α",
1792 sort(1),
1793 pi_implicit(
1794 "a",
1795 bvar(0),
1796 pi_named(
1797 "P",
1798 pi(bvar(1), sort(1)),
1799 pi_named(
1800 "ha",
1801 app(bvar(0), bvar(1)),
1802 pi_implicit(
1803 "b",
1804 bvar(3),
1805 pi(
1806 app(app(app(var("Eq"), bvar(4)), bvar(3)), bvar(0)),
1807 app(bvar(2), bvar(1)),
1808 ),
1809 ),
1810 ),
1811 ),
1812 ),
1813 )
1814}