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