Skip to content

Commit 75570f3

Browse files
authored
refactor: thunk field-less alternatives of casesOnSameCtor (#11254)
This RP adds a `Unit` argument to `casesOnSameCtor` to make it behave moere similar to a matcher. Follow up in spirit to #11239.
1 parent 52d05b6 commit 75570f3

File tree

6 files changed

+21
-9
lines changed

6 files changed

+21
-9
lines changed

src/Lean/Elab/Deriving/BEq.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ def mkMatchNew (header : Header) (indVal : InductiveVal) (auxFunName : Name) : T
164164
rhs_empty := false
165165
else
166166
rhs ← `($a:ident == $b:ident && $rhs)
167+
if ctorArgs1.isEmpty then
168+
-- Unit thunking argument
169+
ctorArgs1 := ctorArgs1.push (← `(()))
167170
`(@fun $ctorArgs1.reverse:term* $ctorArgs2.reverse:term* =>$rhs:term)
168171
if indVal.numCtors == 1 then
169172
`( $(mkCIdent casesOnSameCtorName) $x1:term $x2:term rfl $alts:term* )

src/Lean/Elab/Deriving/DecEq.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ def mkMatchNew (ctx : Context) (header : Header) (indVal : InductiveVal) : TermE
140140
let recField := indValNum.map (ctx.auxFunNames[·]!)
141141
let isProof ← isProp xType
142142
todo := todo.push (a, b, recField, isProof)
143+
if ctorArgs1.isEmpty then
144+
-- Unit thunking argument
145+
ctorArgs1 := ctorArgs1.push (← `(()))
143146
let rhs ← mkSameCtorRhs todo.toList
144147
`(@fun $ctorArgs1:term* $ctorArgs2:term* =>$rhs:term)
145148
if indVal.numCtors == 1 then

src/Lean/Elab/Deriving/Ord.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ def mkMatchNew (header : Header) (indVal : InductiveVal) : TermElabM Term := do
118118
else
119119
rhsCont := fun rhs => `(Ordering.then (compare $a $b) $rhs) >>= rhsCont
120120
let rhs ← rhsCont (← `(Ordering.eq))
121+
if ctorArgs1.isEmpty then
122+
-- Unit thunking argument
123+
ctorArgs1 := ctorArgs1.push (← `(()))
121124
`(@fun $ctorArgs1:term* $ctorArgs2:term* =>$rhs:term)
122125
if indVal.numCtors == 1 then
123126
`( $(mkCIdent casesOnSameCtorName) $x1:term $x2:term rfl $alts:term* )

src/Lean/Meta/Constructions/CasesOnSameCtor.lean

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ public def mkCasesOnSameCtor (declName : Name) (indName : Name) : MetaM Unit :=
160160
let ctorApp2 := mkAppN ctor fields2
161161
let e := mkAppN motive (is ++ #[ctorApp1, ctorApp2, (← mkEqRefl (mkNatLit i))])
162162
let e ← mkForallFVars zs12 e
163+
let e ← if zs12.isEmpty then mkArrow (mkConst ``Unit) e else pure e
163164
let name := match ctorName with
164165
| Name.str _ s => Name.mkSimple s
165166
| _ => Name.mkSimple s!"alt{i+1}"
@@ -190,8 +191,10 @@ public def mkCasesOnSameCtor (declName : Name) (indName : Name) : MetaM Unit :=
190191
let goal := alt.mvarId!
191192
let some (goal, _) ← Cases.unifyEqs? newRefls.size goal {}
192193
| throwError "unifyEqns? unexpectedly closed goal"
193-
let [] ← goal.apply alts[i]!
194-
| throwError "could not apply {alts[i]!} to close\n{goal}"
194+
let hyp := alts[i]!
195+
let hyp := if zs1.isEmpty && zs2.isEmpty then mkApp hyp (mkConst ``Unit.unit) else hyp
196+
let [] ← goal.apply hyp
197+
| throwError "could not apply {hyp} to close\n{goal}"
195198
mkLambdaFVars (zs1 ++ zs2) (← instantiateMVars alt)
196199
let casesOn2 := mkAppN casesOn2 alts'
197200
let casesOn2 := mkAppN casesOn2 newRefls

tests/lean/decEqMutualInductives.lean.expected.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
def instDecidableEqListTree.decEq_2 (x✝² : @B.ListTree✝) (x✝³ : @B.ListTree✝) : Decidable✝ (x✝² = x✝³) :=
6666
match decEq✝ (B.ListTree.ctorIdx✝ x✝²) (B.ListTree.ctorIdx✝ x✝³) with
6767
| .isTrue✝¹ h✝¹ =>
68-
B.ListTree.match_on_same_ctor✝ x✝² x✝³ h✝¹ (@fun => isTrue✝¹ rfl✝)
68+
B.ListTree.match_on_same_ctor✝ x✝² x✝³ h✝¹ (@fun () => isTrue✝¹ rfl✝)
6969
@fun a✝¹ a✝² b✝¹ b✝² =>
7070
let inst✝¹ := instDecidableEqListTree.decEq_1 @a✝¹ @b✝¹;
7171
if h✝² : @a✝¹ = @b✝¹ then by subst h✝²;
@@ -84,7 +84,7 @@
8484
def instDecidableEqFoo₁.decEq_1 (x✝ : @B.Foo₁✝) (x✝¹ : @B.Foo₁✝) : Decidable✝ (x✝ = x✝¹) :=
8585
match decEq✝ (B.Foo₁.ctorIdx✝ x✝) (B.Foo₁.ctorIdx✝ x✝¹) with
8686
| .isTrue✝ h✝ =>
87-
B.Foo₁.match_on_same_ctor✝ x✝ x✝¹ h✝ (@fun => isTrue✝ rfl✝)
87+
B.Foo₁.match_on_same_ctor✝ x✝ x✝¹ h✝ (@fun () => isTrue✝ rfl✝)
8888
@fun a✝ b✝ =>
8989
let inst✝ := instDecidableEqFoo₁.decEq_2 @a✝ @b✝;
9090
if h✝¹ : @a✝ = @b✝ then by subst h✝¹; exact isTrue✝¹ rfl✝¹

tests/lean/run/casesOnSameCtor.lean

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ info: Vec.match_on_same_ctor.het.{u_1, u} {α : Type u} {motive : {a : Nat} →
2727
/--
2828
info: Vec.match_on_same_ctor.{u_1, u} {α : Type u}
2929
{motive : {a : Nat} → (t t_1 : Vec α a) → t.ctorIdx = t_1.ctorIdx → Sort u_1} {a✝ : Nat} (t t✝ : Vec α a✝)
30-
(h : t.ctorIdx = t✝.ctorIdx) (nil : motive nil nil ⋯)
30+
(h : t.ctorIdx = t✝.ctorIdx) (nil : Unit → motive nil nil ⋯)
3131
(cons : (a : α) → {n : Nat} → (a_1 : Vec α n) → (a' : α) → (a'_1 : Vec α n) → motive (cons a a_1) (cons a' a'_1) ⋯) :
3232
motive t t✝ h
3333
-/
@@ -54,10 +54,10 @@ info: Vec.match_on_same_ctor.splitter.{u_1, u} {α : Type u}
5454
/--
5555
info: Vec.match_on_same_ctor.eq_2.{u_1, u} {α : Type u}
5656
{motive : {a : Nat} → (t t_1 : Vec α a) → t.ctorIdx = t_1.ctorIdx → Sort u_1} (a✝ : α) (n : Nat) (a✝¹ : Vec α n)
57-
(a'✝ : α) (a'✝¹ : Vec α n) (nil : motive nil nil ⋯)
57+
(a'✝ : α) (a'✝¹ : Vec α n) (nil : Unit → motive nil nil ⋯)
5858
(cons : (a : α) → {n : Nat} → (a_1 : Vec α n) → (a' : α) → (a'_1 : Vec α n) → motive (cons a a_1) (cons a' a'_1) ⋯) :
5959
(match n + 1, Vec.cons a✝ a✝¹, Vec.cons a'✝ a'✝¹ with
60-
| 0, Vec.nil, Vec.nil, ⋯ => nil
60+
| 0, Vec.nil, Vec.nil, ⋯ => nil ()
6161
| n + 1, Vec.cons a a_1, Vec.cons a' a'_1, ⋯ => cons a a_1 a' a'_1) =
6262
cons a✝ a✝¹ a'✝ a'✝¹
6363
-/
@@ -72,7 +72,7 @@ info: Vec.match_on_same_ctor.eq_2.{u_1, u} {α : Type u}
7272

7373
def decEqVec {α} {a} [DecidableEq α] (x : @Vec α a) (x_1 : @Vec α a) : Decidable (x = x_1) :=
7474
if h : Vec.ctorIdx x = Vec.ctorIdx x_1 then
75-
Vec.match_on_same_ctor x x_1 h (isTrue rfl)
75+
Vec.match_on_same_ctor x x_1 h (fun _ => isTrue rfl)
7676
@fun a_1 _ a_2 b b_1 =>
7777
if h_1 : @a_1 = @b then by
7878
subst h_1
@@ -137,7 +137,7 @@ run_meta mkCasesOnSameCtor `List.match_on_same_ctor ``List
137137

138138
/--
139139
info: List.match_on_same_ctor.{u_1, u} {α : Type u} {motive : (t t_1 : List α) → t.ctorIdx = t_1.ctorIdx → Sort u_1}
140-
(t t✝ : List α) (h : t.ctorIdx = t✝.ctorIdx) (nil : motive [] [] ⋯)
140+
(t t✝ : List α) (h : t.ctorIdx = t✝.ctorIdx) (nil : Unit → motive [] [] ⋯)
141141
(cons : (head : α) → (tail : List α) → (head' : α) → (tail' : List α) → motive (head :: tail) (head' :: tail') ⋯) :
142142
motive t t✝ h
143143
-/

0 commit comments

Comments
 (0)