Skip to content

Commit d4c832e

Browse files
authored
perf: de-fuel some recursive definitions in Core (#11416)
This PR follows up on #7965 and avoids manual fuel constructions in some recursive definitions.
1 parent 9cbff55 commit d4c832e

File tree

5 files changed

+93
-138
lines changed

5 files changed

+93
-138
lines changed

src/Init/Data/String/Basic.lean

Lines changed: 57 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -64,103 +64,73 @@ not a sequence of Unicode scalar values.
6464
-/
6565
@[inline, expose]
6666
def ByteArray.utf8Decode? (b : ByteArray) : Option (Array Char) :=
67-
go (b.size + 1) 0 #[] (by simp) (by simp)
67+
go 0 #[] (by simp)
6868
where
69-
go (fuel : Nat) (i : Nat) (acc : Array Char) (hi : i ≤ b.size) (hf : b.size - i < fuel) : Option (Array Char) :=
70-
match fuel, hf with
71-
| fuel + 1, _ =>
72-
if i = b.size then
73-
some acc
74-
else
75-
match h : utf8DecodeChar? b i with
76-
| none => none
77-
| some c => go fuel (i + c.utf8Size) (acc.push c)
78-
(le_size_of_utf8DecodeChar?_eq_some h)
79-
(have := c.utf8Size_pos; have := le_size_of_utf8DecodeChar?_eq_some h; by omega)
80-
termination_by structural fuel
69+
@[semireducible]
70+
go (i : Nat) (acc : Array Char) (hi : i ≤ b.size) : Option (Array Char) :=
71+
if i < b.size then
72+
match h : utf8DecodeChar? b i with
73+
| none => none
74+
| some c => go (i + c.utf8Size) (acc.push c) (le_size_of_utf8DecodeChar?_eq_some h)
75+
else
76+
some acc
77+
termination_by b.size - i
78+
decreasing_by have := c.utf8Size_pos; omega
8179

8280
@[expose, extern "lean_string_validate_utf8"]
8381
def ByteArray.validateUTF8 (b : @& ByteArray) : Bool :=
84-
go (b.size + 1) 0 (by simp) (by simp)
82+
go 0 (by simp)
8583
where
86-
go (fuel : Nat) (i : Nat) (hi : i ≤ b.size) (hf : b.size - i < fuel) : Bool :=
87-
match fuel, hf with
88-
| fuel + 1, _ =>
89-
if hi : i = b.size then
90-
true
91-
else
92-
match h : validateUTF8At b i with
93-
| false => false
94-
| true => go fuel (i + b[i].utf8ByteSize (isUTF8FirstByte_of_validateUTF8At h))
95-
?_ ?_
96-
termination_by structural fuel
84+
@[semireducible]
85+
go (i : Nat) (hi : i ≤ b.size) : Bool :=
86+
if hi : i < b.size then
87+
match h : validateUTF8At b i with
88+
| false => false
89+
| true => go (i + b[i].utf8ByteSize (isUTF8FirstByte_of_validateUTF8At h)) ?_
90+
else
91+
true
92+
termination_by b.size - i
93+
decreasing_by
94+
have := b[i].utf8ByteSize_pos (isUTF8FirstByte_of_validateUTF8At h); omega
9795
finally
9896
all_goals rw [ByteArray.validateUTF8At_eq_isSome_utf8DecodeChar?] at h
9997
· rw [← ByteArray.utf8Size_utf8DecodeChar (h := h)]
10098
exact add_utf8Size_utf8DecodeChar_le_size
101-
· rw [← ByteArray.utf8Size_utf8DecodeChar (h := h)]
102-
have := add_utf8Size_utf8DecodeChar_le_size (h := h)
103-
have := (b.utf8DecodeChar i h).utf8Size_pos
104-
omega
10599

106-
theorem ByteArray.isSome_utf8Decode?Go_eq_validateUTF8Go {b : ByteArray} {fuel : Nat}
107-
{i : Nat} {acc : Array Char} {hi : i ≤ b.size} {hf : b.size - i < fuel} :
108-
(utf8Decode?.go b fuel i acc hi hf).isSome = validateUTF8.go b fuel i hi hf := by
100+
theorem ByteArray.isSome_utf8Decode?Go_eq_validateUTF8Go {b : ByteArray}
101+
{i : Nat} {acc : Array Char} {hi : i ≤ b.size} :
102+
(utf8Decode?.go b i acc hi).isSome = validateUTF8.go b i hi := by
109103
fun_induction utf8Decode?.go with
110-
| case1 => simp [validateUTF8.go]
111-
| case2 i acc hi fuel hf h₁ h₂ =>
112-
simp only [Option.isSome_none, validateUTF8.go, h₁, ↓reduceDIte, Bool.false_eq]
104+
| case1 i acc hi h₁ h₂ =>
105+
unfold validateUTF8.go
106+
simp only [Option.isSome_none, ↓reduceDIte, Bool.false_eq, h₁]
113107
split
114108
· rfl
115109
· rename_i heq
116110
simp [validateUTF8At_eq_isSome_utf8DecodeChar?, h₂] at heq
117-
| case3 i acc hi fuel hf h₁ c h₂ ih =>
118-
simp [validateUTF8.go, h₁]
111+
| case2 i acc hi h₁ c h₂ ih =>
112+
unfold validateUTF8.go
113+
simp only [↓reduceDIte, ih, h₁]
119114
split
120115
· rename_i heq
121116
simp [validateUTF8At_eq_isSome_utf8DecodeChar?, h₂] at heq
122-
· rw [ih]
123-
congr
117+
· congr
124118
rw [← ByteArray.utf8Size_utf8DecodeChar (h := by simp [h₂])]
125119
simp [utf8DecodeChar, h₂]
120+
| case3 => unfold validateUTF8.go; simp [*]
126121

127122
theorem ByteArray.isSome_utf8Decode?_eq_validateUTF8 {b : ByteArray} :
128123
b.utf8Decode?.isSome = b.validateUTF8 :=
129124
b.isSome_utf8Decode?Go_eq_validateUTF8Go
130125

131-
theorem ByteArray.utf8Decode?.go.congr {b b' : ByteArray} {fuel fuel' i i' : Nat} {acc acc' : Array Char} {hi hi' hf hf'}
132-
(hbb' : b = b') (hii' : i = i') (hacc : acc = acc') :
133-
ByteArray.utf8Decode?.go b fuel i acc hi hf = ByteArray.utf8Decode?.go b' fuel' i' acc' hi' hf' := by
134-
subst hbb' hii' hacc
135-
fun_induction ByteArray.utf8Decode?.go b fuel i acc hi hf generalizing fuel' with
136-
| case1 =>
137-
rw [go.eq_def]
138-
split
139-
simp
140-
| case2 =>
141-
rw [go.eq_def]
142-
split <;> split
143-
· simp_all
144-
· split <;> simp_all
145-
| case3 =>
146-
conv => rhs; rw [go.eq_def]
147-
split <;> split
148-
· simp_all
149-
· split
150-
· simp_all
151-
· rename_i c₁ hc₁ ih _ _ _ _ _ c₂ hc₂
152-
obtain rfl : c₁ = c₂ := by rw [← Option.some_inj, ← hc₁, ← hc₂]
153-
apply ih
154-
155126
@[simp]
156127
theorem ByteArray.utf8Decode?_empty : ByteArray.empty.utf8Decode? = some #[] := by
157128
simp [utf8Decode?, utf8Decode?.go]
158129

159-
private theorem ByteArray.isSome_utf8Decode?go_iff {b : ByteArray} {fuel i : Nat} {hi : i ≤ b.size} {hf} {acc : Array Char} :
160-
(ByteArray.utf8Decode?.go b fuel i acc hi hf).isSome ↔ IsValidUTF8 (b.extract i b.size) := by
130+
private theorem ByteArray.isSome_utf8Decode?go_iff {b : ByteArray} {hi : i ≤ b.size} {acc : Array Char} :
131+
(ByteArray.utf8Decode?.go b i acc hi).isSome ↔ IsValidUTF8 (b.extract i b.size) := by
161132
fun_induction ByteArray.utf8Decode?.go with
162-
| case1 => simp
163-
| case2 fuel i hi hf acc h₁ h₂ =>
133+
| case1 i hi acc h₁ h₂ =>
164134
simp only [Option.isSome_none, Bool.false_eq_true, false_iff]
165135
rintro ⟨l, hl⟩
166136
have : l ≠ [] := by
@@ -170,7 +140,7 @@ private theorem ByteArray.isSome_utf8Decode?go_iff {b : ByteArray} {fuel i : Nat
170140
rw [← l.cons_head_tail this] at hl
171141
rw [utf8DecodeChar?_eq_utf8DecodeChar?_extract, hl, List.utf8DecodeChar?_utf8Encode_cons] at h₂
172142
simp at h₂
173-
| case3 i acc hi fuel hf h₁ c h₂ ih =>
143+
| case2 i acc hi h₁ c h₂ ih =>
174144
rw [ih]
175145
have h₂' := h₂
176146
rw [utf8DecodeChar?_eq_utf8DecodeChar?_extract] at h₂'
@@ -179,6 +149,9 @@ private theorem ByteArray.isSome_utf8Decode?go_iff {b : ByteArray} {fuel i : Nat
179149
(le_size_of_utf8DecodeChar?_eq_some h₂)] at hl ⊢
180150
rw [ByteArray.append_inj_left hl (by have := le_size_of_utf8DecodeChar?_eq_some h₂; simp; omega),
181151
← List.utf8Encode_singleton, isValidUTF8_utf8Encode_singleton_append_iff]
152+
| case3 i =>
153+
have : i = b.size := by omega
154+
simp [*]
182155

183156
theorem ByteArray.isSome_utf8Decode?_iff {b : ByteArray} :
184157
b.utf8Decode?.isSome ↔ IsValidUTF8 b := by
@@ -305,27 +278,21 @@ theorem String.length_toList {s : String} : s.toList.length = s.length := (rfl)
305278
@[deprecated String.length_toList (since := "2025-10-30")]
306279
theorem String.length_data {b : String} : b.toList.length = b.length := (rfl)
307280

308-
private theorem ByteArray.utf8Decode?go_eq_utf8Decode?go_extract {b : ByteArray} {fuel i : Nat} {hi : i ≤ b.size} {hf} {acc : Array Char} :
309-
utf8Decode?.go b fuel i acc hi hf = (utf8Decode?.go (b.extract i b.size) fuel 0 #[] (by simp) (by simp [hf])).map (acc ++ ·) := by
310-
fun_cases utf8Decode?.go b fuel i acc hi hf with
311-
| case1 =>
312-
rw [utf8Decode?.go]
313-
simp only [size_extract, Nat.le_refl, Nat.min_eq_left, Nat.zero_add, List.push_toArray,
314-
List.nil_append]
315-
rw [if_pos (by omega)]
316-
simp
317-
| case2 fuel hf₁ h₁ h₂ hf₂ =>
281+
private theorem ByteArray.utf8Decode?go_eq_utf8Decode?go_extract {b : ByteArray} {hi : i ≤ b.size} {acc : Array Char} :
282+
utf8Decode?.go b i acc hi = (utf8Decode?.go (b.extract i b.size) 0 #[] (by simp)).map (acc ++ ·) := by
283+
fun_cases utf8Decode?.go b i acc hi with
284+
| case1 h₁ h₂ =>
318285
rw [utf8Decode?.go]
319286
simp only [size_extract, Nat.le_refl, Nat.min_eq_left, Nat.zero_add, List.push_toArray,
320287
List.nil_append]
321-
rw [if_neg (by omega)]
288+
rw [if_pos (by omega)]
322289
rw [utf8DecodeChar?_eq_utf8DecodeChar?_extract] at h₂
323290
split <;> simp_all
324-
| case3 fuel hf₁ h₁ c h₂ hf₂ =>
291+
| case2 h₁ c h₂ =>
325292
conv => rhs; rw [utf8Decode?.go]
326293
simp only [size_extract, Nat.le_refl, Nat.min_eq_left, Nat.zero_add, List.push_toArray,
327294
List.nil_append]
328-
rw [if_neg (by omega)]
295+
rw [if_pos (by omega)]
329296
rw [utf8DecodeChar?_eq_utf8DecodeChar?_extract] at h₂
330297
split
331298
· simp_all
@@ -338,20 +305,25 @@ private theorem ByteArray.utf8Decode?go_eq_utf8Decode?go_extract {b : ByteArray}
338305
simp only [size_extract, Nat.le_refl, Nat.min_eq_left, Option.map_map, ByteArray.extract_extract]
339306
have : (fun x => acc ++ x) ∘ (fun x => #[c] ++ x) = fun x => acc.push c ++ x := by funext; simp
340307
simp [(by omega : i + (b.size - i) = b.size), this]
341-
termination_by fuel
308+
| case3 =>
309+
rw [utf8Decode?.go]
310+
simp only [size_extract, Nat.le_refl, Nat.min_eq_left, Nat.zero_add, List.push_toArray,
311+
List.nil_append]
312+
rw [if_neg (by omega)]
313+
simp
314+
termination_by b.size - i
342315

343316
theorem ByteArray.utf8Decode?_utf8Encode_singleton_append {l : ByteArray} {c : Char} :
344317
([c].utf8Encode ++ l).utf8Decode? = l.utf8Decode?.map (#[c] ++ ·) := by
345318
rw [utf8Decode?, utf8Decode?.go,
346-
if_neg (by simp [List.utf8Encode_singleton]; have := c.utf8Size_pos; omega)]
319+
if_pos (by simp [List.utf8Encode_singleton]; have := c.utf8Size_pos; omega)]
347320
split
348321
· simp_all [List.utf8DecodeChar?_utf8Encode_singleton_append]
349322
· rename_i d h
350323
obtain rfl : c = d := by simpa [List.utf8DecodeChar?_utf8Encode_singleton_append] using h
351324
rw [utf8Decode?go_eq_utf8Decode?go_extract, utf8Decode?]
352325
simp only [List.push_toArray, List.nil_append, Nat.zero_add]
353-
congr 1
354-
apply ByteArray.utf8Decode?.go.congr _ rfl rfl
326+
congr 2
355327
apply extract_append_eq_right _ (by simp)
356328
simp [List.utf8Encode_singleton]
357329

src/Init/Data/String/Decode.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,6 +1441,9 @@ public def utf8ByteSize (c : UInt8) (_h : c.IsUTF8FirstByte) : Nat :=
14411441
else
14421442
4
14431443

1444+
public theorem utf8ByteSize_pos (c : UInt8) (h : c.IsUTF8FirstByte) : 0 < c.utf8ByteSize h := by
1445+
fun_cases utf8ByteSize <;> simp
1446+
14441447
def _root_.ByteArray.utf8DecodeChar?.FirstByte.utf8ByteSize : FirstByte → Nat
14451448
| .invalid => 0
14461449
| .done => 1

src/Init/Grind/Module/NatModuleNorm.lean

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ theorem Poly.denoteN_append {α} [NatModule α] (ctx : Context α) (p₁ p₂ :
7979

8080
attribute [local simp] Poly.denoteN_append
8181

82-
theorem Poly.denoteN_combine' {α} [NatModule α] (ctx : Context α) (fuel : Nat) (p₁ p₂ : Poly)
83-
: p₁.NonnegCoeffs → p₂.NonnegCoeffs → (p₁.combine' fuel p₂).denoteN ctx = p₁.denoteN ctx + p₂.denoteN ctx := by
84-
fun_induction p₁.combine' fuel p₂ <;> intro h₁ h₂ <;> try simp [*, zero_add, add_zero]
82+
theorem Poly.denoteN_combine {α} [NatModule α] (ctx : Context α) (p₁ p₂ : Poly)
83+
: p₁.NonnegCoeffs → p₂.NonnegCoeffs → (p₁.combine p₂).denoteN ctx = p₁.denoteN ctx + p₂.denoteN ctx := by
84+
fun_induction p₁.combine p₂ <;> intro h₁ h₂ <;> try simp [*, zero_add, add_zero]
8585
next hx _ h ih =>
8686
simp at hx
8787
simp +zetaDelta at h
@@ -103,10 +103,6 @@ theorem Poly.denoteN_combine' {α} [NatModule α] (ctx : Context α) (fuel : Nat
103103
cases h₂; next h₂ =>
104104
simp [ih h₁ h₂, *]; ac_rfl
105105

106-
theorem Poly.denoteN_combine {α} [NatModule α] (ctx : Context α) (p₁ p₂ : Poly)
107-
: p₁.NonnegCoeffs → p₂.NonnegCoeffs → (p₁.combine p₂).denoteN ctx = p₁.denoteN ctx + p₂.denoteN ctx := by
108-
intros; simp [combine, denoteN_combine', *]
109-
110106
theorem Poly.denoteN_mul' {α} [NatModule α] (ctx : Context α) (p : Poly) (k : Nat) : p.NonnegCoeffs → (p.mul' k).denoteN ctx = k • p.denoteN ctx := by
111107
induction p <;> simp [mul', *, nsmul_zero]
112108
next ih =>
@@ -151,9 +147,8 @@ theorem Poly.append_Nonneg (p₁ p₂ : Poly) : p₁.NonnegCoeffs → p₂.Nonne
151147
fun_induction append <;> intro h₁ h₂; simp [*]
152148
next ih => cases h₁; constructor; assumption; apply ih <;> assumption
153149

154-
theorem Poly.combine'_Nonneg (fuel : Nat) (p₁ p₂ : Poly) : p₁.NonnegCoeffs → p₂.NonnegCoeffs → (p₁.combine' fuel p₂).NonnegCoeffs := by
155-
fun_induction Poly.combine'
156-
next => apply Poly.append_Nonneg
150+
theorem Poly.combine_Nonneg (p₁ p₂ : Poly) : p₁.NonnegCoeffs → p₂.NonnegCoeffs → (p₁.combine p₂).NonnegCoeffs := by
151+
fun_induction Poly.combine
157152
next => intros; assumption
158153
next => intros; assumption
159154
next ih =>
@@ -172,9 +167,6 @@ theorem Poly.combine'_Nonneg (fuel : Nat) (p₁ p₂ : Poly) : p₁.NonnegCoeffs
172167
constructor; assumption
173168
apply ih; constructor; assumption; assumption; assumption
174169

175-
theorem Poly.combine_Nonneg (p₁ p₂ : Poly) : p₁.NonnegCoeffs → p₂.NonnegCoeffs → (p₁.combine p₂).NonnegCoeffs := by
176-
simp [combine]; apply Poly.combine'_Nonneg
177-
178170
theorem Expr.toPolyN_Nonneg (e : Expr) : e.toPolyN.NonnegCoeffs := by
179171
fun_induction toPolyN <;> try constructor <;> simp
180172
next => constructor; simp; constructor

src/Init/Grind/Ordered/Linarith.lean

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -123,26 +123,22 @@ def Poly.append (p₁ p₂ : Poly) : Poly :=
123123
| .nil => p₂
124124
| .add k x p₁ => .add k x (append p₁ p₂)
125125

126-
def Poly.combine' (fuel : Nat) (p₁ p₂ : Poly) : Poly :=
127-
match fuel with
128-
| 0 => p₁.append p₂
129-
| fuel + 1 => match p₁, p₂ with
126+
def Poly.combine (p₁ p₂ : Poly) : Poly :=
127+
match p₁, p₂ with
130128
| .nil, p₂ => p₂
131129
| p₁, .nil => p₁
132130
| .add a₁ x₁ p₁, .add a₂ x₂ p₂ =>
133131
bif Nat.beq x₁ x₂ then
134132
let a := a₁ + a₂
135133
bif a == 0 then
136-
combine' fuel p₁ p₂
134+
combine p₁ p₂
137135
else
138-
.add a x₁ (combine' fuel p₁ p₂)
136+
.add a x₁ (combine p₁ p₂)
139137
else bif Nat.blt x₂ x₁ then
140-
.add a₁ x₁ (combine' fuel p₁ (.add a₂ x₂ p₂))
138+
.add a₁ x₁ (combine p₁ (.add a₂ x₂ p₂))
141139
else
142-
.add a₂ x₂ (combine' fuel (.add a₁ x₁ p₁) p₂)
143-
144-
def Poly.combine (p₁ p₂ : Poly) : Poly :=
145-
combine' 100000000 p₁ p₂
140+
.add a₂ x₂ (combine (.add a₁ x₁ p₁) p₂)
141+
termination_by sizeOf p₁ + sizeOf p₂
146142

147143
/-- Converts the given expression into a polynomial. -/
148144
def Expr.toPoly' (e : Expr) : Poly :=
@@ -205,18 +201,15 @@ theorem Poly.denote_append {α} [IntModule α] (ctx : Context α) (p₁ p₂ : P
205201

206202
attribute [local simp] Poly.denote_append
207203

208-
theorem Poly.denote_combine' {α} [IntModule α] (ctx : Context α) (fuel : Nat) (p₁ p₂ : Poly) : (p₁.combine' fuel p₂).denote ctx = p₁.denote ctx + p₂.denote ctx := by
209-
fun_induction p₁.combine' fuel p₂ <;>
204+
theorem Poly.denote_combine {α} [IntModule α] (ctx : Context α) (p₁ p₂ : Poly) : (p₁.combine p₂).denote ctx = p₁.denote ctx + p₂.denote ctx := by
205+
fun_induction p₁.combine p₂ <;>
210206
simp_all +zetaDelta [denote]
211207
next h _ =>
212208
rw [Int.add_comm] at h
213209
rw [add_left_comm, add_assoc, ← add_assoc, ← add_zsmul, h, zero_zsmul, zero_add]
214210
next => rw [add_zsmul]; ac_rfl
215211
all_goals ac_rfl
216212

217-
theorem Poly.denote_combine {α} [IntModule α] (ctx : Context α) (p₁ p₂ : Poly) : (p₁.combine p₂).denote ctx = p₁.denote ctx + p₂.denote ctx := by
218-
simp [combine, denote_combine']
219-
220213
attribute [local simp] Poly.denote_combine
221214

222215
private theorem Expr.denote_toPoly'_go {α} [IntModule α] {k p} (ctx : Context α) (e : Expr)

src/Init/Grind/Ring/CommSolver.lean

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -889,26 +889,22 @@ where
889889
| .num k' => acc.insert (k*k' % c) m
890890
| .add k' m' p => go p (acc.insert (k*k' % c) (m.mul_nc m'))
891891

892-
def Poly.combineC (p₁ p₂ : Poly) (c : Nat) : Poly :=
893-
go hugeFuel p₁ p₂
894-
where
895-
go (fuel : Nat) (p₁ p₂ : Poly) : Poly :=
896-
match fuel with
897-
| 0 => p₁.concat p₂
898-
| fuel + 1 => match p₁, p₂ with
899-
| .num k₁, .num k₂ => .num ((k₁ + k₂) % c)
900-
| .num k₁, .add k₂ m₂ p₂ => addConstC (.add k₂ m₂ p₂) k₁ c
901-
| .add k₁ m₁ p₁, .num k₂ => addConstC (.add k₁ m₁ p₁) k₂ c
902-
| .add k₁ m₁ p₁, .add k₂ m₂ p₂ =>
903-
match m₁.grevlex m₂ with
904-
| .eq =>
905-
let k := (k₁ + k₂) % c
906-
bif k == 0 then
907-
go fuel p₁ p₂
908-
else
909-
.add k m₁ (go fuel p₁ p₂)
910-
| .gt => .add k₁ m₁ (go fuel p₁ (.add k₂ m₂ p₂))
911-
| .lt => .add k₂ m₂ (go fuel (.add k₁ m₁ p₁) p₂)
892+
@[semireducible]
893+
def Poly.combineC (p₁ p₂ : Poly) (c : Nat) : Poly := match p₁, p₂ with
894+
| .num k₁, .num k₂ => .num ((k₁ + k₂) % c)
895+
| .num k₁, .add k₂ m₂ p₂ => addConstC (.add k₂ m₂ p₂) k₁ c
896+
| .add k₁ m₁ p₁, .num k₂ => addConstC (.add k₁ m₁ p₁) k₂ c
897+
| .add k₁ m₁ p₁, .add k₂ m₂ p₂ =>
898+
match m₁.grevlex m₂ with
899+
| .eq =>
900+
let k := (k₁ + k₂) % c
901+
bif k == 0 then
902+
combineC p₁ p₂ c
903+
else
904+
.add k m₁ (combineC p₁ p₂ c)
905+
| .gt => .add k₁ m₁ (combineC p₁ (.add k₂ m₂ p₂) c)
906+
| .lt => .add k₂ m₂ (combineC (.add k₁ m₁ p₁) p₂ c)
907+
termination_by sizeOf p₁ + sizeOf p₂
912908

913909
def Poly.mulC (p₁ : Poly) (p₂ : Poly) (c : Nat) : Poly :=
914910
go p₁ (.num 0)
@@ -1432,10 +1428,9 @@ theorem Poly.denote_mulMonC_nc {α c} [Ring α] [IsCharP α c] (ctx : Context α
14321428

14331429
theorem Poly.denote_combineC {α c} [Ring α] [IsCharP α c] (ctx : Context α) (p₁ p₂ : Poly)
14341430
: (combineC p₁ p₂ c).denote ctx = p₁.denote ctx + p₂.denote ctx := by
1435-
unfold combineC; generalize hugeFuel = fuel
1436-
fun_induction combineC.go
1437-
<;> simp [*, denote_concat, denote_addConstC, denote, intCast_add,
1438-
add_comm, add_left_comm, add_assoc, IsCharP.intCast_emod, zsmul_eq_intCast_mul]
1431+
fun_induction combineC
1432+
<;> simp [*, denote_addConstC, denote, intCast_add, add_comm, add_left_comm, add_assoc,
1433+
IsCharP.intCast_emod, zsmul_eq_intCast_mul]
14391434
next hg _ h _ =>
14401435
simp +zetaDelta at h
14411436
rw [← add_assoc, Mon.eq_of_grevlex hg, ← right_distrib, ← intCast_add,

0 commit comments

Comments
 (0)