Skip to content

Commit 85a0190

Browse files
committed
fix: FunInd to beta-reduce abstracted proofs
This PR lets FunInd beta-reduce abstracted proofs if necessary. This fixes #10838.
1 parent efbbb0b commit 85a0190

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

src/Lean/Meta/Tactic/FunInd.lean

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,8 @@ partial def foldAndCollect (oldIH newIH : FVarId) (isRecCall : Expr → Option E
347347
if e.getAppArgs.any (·.isFVarOf oldIH) then
348348
-- Sometimes Fix.lean abstracts over oldIH in a proof definition.
349349
-- So beta-reduce that definition. We need to look through theorems here!
350+
if e.isHeadBetaTarget then
351+
return ← foldAndCollect oldIH newIH isRecCall e.headBeta
350352
if let some e' ← withTransparency .all do unfoldDefinition? e then
351353
return ← foldAndCollect oldIH newIH isRecCall e'
352354
else

tests/lean/run/issue10838.lean

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
set_option warn.sorry false
2+
3+
4+
inductive Ty where
5+
| unit : Ty
6+
| arrow (t₁ t₂ : Ty) : Ty
7+
8+
def Env (n : Nat) := Fin n → Ty
9+
10+
def Env.add (Γ : Env n) (t : Ty) : Env (n + 1) :=
11+
Fin.cases t Γ
12+
13+
inductive Term : Env n → Ty → Type where
14+
| var (i : Fin n) : Term Γ (Γ i)
15+
| app (e₁ : Term Γ (.arrow t₁ t₂)) (e₂ : Term Γ t₁) : Term Γ t₂
16+
| lam (e : Term (Γ.add t₁) t₂) : Term Γ (.arrow t₁ t₂)
17+
18+
def Subst (Γ : Env n) (Δ : Env m) := (i : Fin n) → Term Δ (Γ i)
19+
20+
def Subst.id {Γ : Env n} : Subst Γ Γ :=
21+
fun i => .var i
22+
23+
def Subst.shift {Γ : Env n} : Subst Γ (Γ.add t) :=
24+
fun i => .var i.succ
25+
26+
def IsVar : Term Γ t → Bool
27+
| .var _ => true
28+
| .app _ _ => false
29+
| .lam _ => false
30+
31+
attribute [simp] IsVar.eq_1 IsVar.eq_2 IsVar.eq_3
32+
33+
def IsRenaming (σ : Subst Γ Δ) : Bool := ∀ i, IsVar (σ i)
34+
35+
set_option trace.Meta.FunInd true
36+
37+
def Term.subst' (e : Term Γ t) (σ : Subst Γ Δ) :
38+
{r : Term Δ t // IsVar e → IsRenaming σ → IsVar r } :=
39+
match e with
40+
| .var i => ⟨σ i, by sorry
41+
| .app e₁ e₂ => ⟨.app (e₁.subst' σ).val (e₂.subst' σ).val, by sorry
42+
| .lam e₁ =>
43+
let r := .lam (e₁.subst' (Fin.cases (.var 0) (fun i => ((σ i).subst' .shift).1))).1
44+
⟨r, by sorry
45+
termination_by (if IsVar e then 0 else 1, if IsRenaming σ then 0 else 1, sizeOf e)
46+
decreasing_by
47+
· sorry
48+
· sorry
49+
· sorry
50+
· sorry
51+
· simp [*]
52+
apply Prod.Lex.right'
53+
· grind
54+
apply Prod.Lex.right'
55+
· sorry
56+
· sorry
57+
58+
/--
59+
error: Failed to realize constant Term.subst'.induct:
60+
Cannot derive functional induction principle (please report this issue)
61+
Internal error in `foldAndCollect`: Cannot reduce application of `fun n Γ n_1 Δ σ t₂ t₁ e x =>
62+
Classical.byContradiction
63+
(Lean.Grind.intro_with_eq (¬(if IsVar e = true then 0 else 1) ≤ 1) (2 ≤ if IsVar e = true then 0 else 1) False
64+
(Nat.not_le_eq (if IsVar e = true then 0 else 1) 1) fun h =>
65+
Or.casesOn (Lean.Grind.em (IsVar e = true))
66+
(fun h_1 =>
67+
id
68+
(Lean.Grind.Nat.unsat_le_lo (if IsVar e = true then 0 else 1) 0 2 Lean.Grind.rfl_true
69+
(Lean.Grind.Nat.le_of_eq_1 (if IsVar e = true then 0 else 1) 0 (ite_cond_eq_true 0 1 (eq_true h_1)))
70+
h))
71+
fun h_1 =>
72+
id
73+
(Lean.Grind.Nat.unsat_le_lo (if IsVar e = true then 0 else 1) 1 1 Lean.Grind.rfl_true
74+
(Lean.Grind.Nat.le_of_eq_1 (if IsVar e = true then 0 else 1) 1 (ite_cond_eq_false 0 1 (eq_false h_1)))
75+
(Lean.Grind.Nat.ro_lo_2 1 0 (if IsVar e = true then 0 else 1) 1 2 Lean.Grind.rfl_true (Nat.le_refl 1)
76+
h)))` in:
77+
(fun n Γ n_1 Δ σ t₂ t₁ e x =>
78+
Classical.byContradiction
79+
(Lean.Grind.intro_with_eq (¬(if IsVar e = true then 0 else 1) ≤ 1) (2 ≤ if IsVar e = true then 0 else 1)
80+
False (Nat.not_le_eq (if IsVar e = true then 0 else 1) 1) fun h =>
81+
Or.casesOn (Lean.Grind.em (IsVar e = true))
82+
(fun h_1 =>
83+
id
84+
(Lean.Grind.Nat.unsat_le_lo (if IsVar e = true then 0 else 1) 0 2 Lean.Grind.rfl_true
85+
(Lean.Grind.Nat.le_of_eq_1 (if IsVar e = true then 0 else 1) 0
86+
(ite_cond_eq_true 0 1 (eq_true h_1)))
87+
h))
88+
fun h_1 =>
89+
id
90+
(Lean.Grind.Nat.unsat_le_lo (if IsVar e = true then 0 else 1) 1 1 Lean.Grind.rfl_true
91+
(Lean.Grind.Nat.le_of_eq_1 (if IsVar e = true then 0 else 1) 1
92+
(ite_cond_eq_false 0 1 (eq_false h_1)))
93+
(Lean.Grind.Nat.ro_lo_2 1 0 (if IsVar e = true then 0 else 1) 1 2 Lean.Grind.rfl_true
94+
(Nat.le_refl 1) h))))
95+
n✝² Γ n✝ Δ σ t₂✝ t₁✝ e✝ x✝¹
96+
---
97+
error: Unknown constant `Term.subst'.induct`
98+
-/
99+
#guard_msgs(pass trace, all) in
100+
#print Term.subst'.induct

0 commit comments

Comments
 (0)