()
| 59 | /// funEta : ∀ (α β : Type) (f : α → β), (fun x => f x) = f := fun _ _ f => rfl |
| 60 | #[test] |
| 61 | fn good_fun_eta() { |
| 62 | let mut env = KEnv::<Meta>::new(); |
| 63 | add_eq_axioms(&mut env); |
| 64 | |
| 65 | // ∀ (α : Type) (β : Type) (f : α → β), (fun x => f x) = f |
| 66 | // At f_ty position (depth 2): α=var(1), β=var(0) |
| 67 | // α → β at depth 2: pi(var(1), var(1)) — inside pi body β shifts from 0→1 |
| 68 | let f_ty = pi(var(1), var(1)); |
| 69 | // Inside body (depth 3): f=var(0), β=var(1), α=var(2) |
| 70 | // eta_lhs = fun (x : α) => f x. α at depth 3 = var(2). |
| 71 | // Inside lambda (depth 4): x=var(0), f=var(1), β=var(2), α=var(3) |
| 72 | let eta_lhs = nlam("x", var(2), app(var(1), var(0))); |
| 73 | // α → β at depth 3: pi(var(2), var(2)) — inside pi body β shifts from 1→2 |
| 74 | let eq_app = apps( |
| 75 | cnst("Eq", &[usucc(uzero())]), |
| 76 | &[pi(var(2), var(2)), eta_lhs, var(0)], |
| 77 | ); |
| 78 | let ty = npi("α", sort1(), npi("β", sort1(), npi("f", f_ty, eq_app))); |
| 79 | |
| 80 | // fun α β f => Eq.refl.{1} (α → β) f |
| 81 | // At depth 3 inside val: f=var(0), β=var(1), α=var(2) |
| 82 | let val = nlam( |
| 83 | "α", |
| 84 | sort1(), |
| 85 | nlam( |
| 86 | "β", |
| 87 | sort1(), |
| 88 | nlam( |
| 89 | "f", |
| 90 | pi(var(1), var(1)), |
| 91 | apps( |
| 92 | cnst("Eq.refl", &[usucc(uzero())]), |
| 93 | &[pi(var(2), var(2)), var(0)], |
| 94 | ), |
| 95 | ), |
| 96 | ), |
| 97 | ); |
| 98 | |
| 99 | let (id, c) = mk_thm("funEta", 0, vec![], ty, val); |
| 100 | env.insert(id.clone(), c); |
| 101 | check_accepts(&mut env, &id); |
| 102 | } |
| 103 | |
| 104 | /// funEtaBad : ∀ (α β : Type) (g : α → α) (f : α → β), (fun x => f (g x)) = f |
| 105 | /// BAD: eta should NOT identify functions with different bodies. |
nothing calls this directly
no test coverage detected