@@ -48,15 +48,11 @@ then the leading coefficient of the equation must also divide `k`
4848def _root_.Lean.Grind.CommRing.Mon.findSimp? (k : Int) (m : Mon) : RingM (Option EqCnstr) := do
4949 let checkCoeff ← checkCoeffDvd
5050 let noZeroDiv ← noZeroDivisors
51- let rec go : Mon → RingM (Option EqCnstr)
52- | .unit => return none
53- | .mult pw m' => do
54- for c in (← getRing).varToBasis[pw.x]! do
55- if !checkCoeff || noZeroDiv || (c.p.lc ∣ k) then
56- if c.p.divides m then
57- return some c
58- go m'
59- go m
51+ for c in (← getRing).basis do
52+ if !checkCoeff || noZeroDiv || (c.p.lc ∣ k) then
53+ if c.p.divides m then
54+ return some c
55+ return none
6056
6157/--
6258Returns `some c`, where `c` is an equation from the basis whose leading monomial divides some
@@ -129,6 +125,7 @@ def EqCnstr.checkConstant (c : EqCnstr) : RingM Bool := do
129125 c.setUnsat
130126 else
131127 -- Remark: we currently don't do anything if the characteristic is not known.
128+ -- TODO: if `k.natAbs` is `1`, we could set all terms of this ring `0`.
132129 trace_goal[grind.ring.assert.discard] "{← c.denoteExpr}"
133130 return true
134131
@@ -153,10 +150,9 @@ private def addSorted (c : EqCnstr) : List EqCnstr → List EqCnstr
153150 c' :: addSorted c cs
154151
155152def addToBasisCore (c : EqCnstr) : RingM Unit := do
156- let .add _ m _ := c.p | return ()
157- let .mult pw _ := m | return ()
153+ trace[grind.debug.ring.basis] "{← c.denoteExpr}"
158154 modifyRing fun s => { s with
159- varToBasis := s.varToBasis.modify pw.x ( addSorted c)
155+ basis := addSorted c s.basis
160156 recheck := true
161157 }
162158
@@ -168,18 +164,12 @@ def EqCnstr.addToQueue (c : EqCnstr) : RingM Unit := do
168164def EqCnstr.superposeWith (c : EqCnstr) : RingM Unit := do
169165 if (← checkMaxSteps) then return ()
170166 let .add _ m _ := c.p | return ()
171- go m
172- where
173- go : Mon → RingM Unit
174- | .unit => return ()
175- | .mult pw m => do
176- let x := pw.x
177- let cs := (← getRing).varToBasis[x]!
178- for c' in cs do
179- let r ← c.p.spolM c'.p
180- trace_goal[grind.ring.superpose] "{← c.denoteExpr}\n with: {← c'.denoteExpr}\n result: {← r.spol.denoteExpr} = 0"
181- addToQueue (← mkEqCnstr r.spol <| .superpose r.k₁ r.m₁ c r.k₂ r.m₂ c')
182- go m
167+ for c' in (← getRing).basis do
168+ let .add _ m' _ := c'.p | pure ()
169+ if m.sharesVar m' then
170+ let r ← c.p.spolM c'.p
171+ trace_goal[grind.ring.superpose] "{← c.denoteExpr}\n with: {← c'.denoteExpr}\n result: {← r.spol.denoteExpr} = 0"
172+ addToQueue (← mkEqCnstr r.spol <| .superpose r.k₁ r.m₁ c r.k₂ r.m₂ c')
183173
184174/--
185175Tries to convert the leading monomial into a monic one.
@@ -215,25 +205,23 @@ def EqCnstr.toMonic (c : EqCnstr) : RingM EqCnstr := do
215205def EqCnstr.simplifyBasis (c : EqCnstr) : RingM Unit := do
216206 trace[grind.debug.ring.simpBasis] "using: {← c.denoteExpr}"
217207 let .add _ m _ := c.p | return ()
218- let rec go (m' : Mon) : RingM Unit := do
219- match m' with
220- | .unit => return ()
221- | .mult pw m' => goVar m pw.x; go m'
222- go m
223- where
224- goVar (m : Mon) (x : Var) : RingM Unit := do
225- let cs := (← getRing).varToBasis[x]!
226- if cs.isEmpty then return ()
227- modifyRing fun s => { s with varToBasis := s.varToBasis.set x {} }
228- for c' in cs do
229- trace[grind.debug.ring.simpBasis] "target: {← c'.denoteExpr}"
230- let .add _ m' _ := c'.p | pure ()
231- if m.divides m' then
232- let c'' ← c'.simplifyWithExhaustively c
233- trace[grind.debug.ring.simpBasis] "simplified: {← c''.denoteExpr}"
234- addToQueue c''
235- else
236- addToBasisCore c'
208+ let rec go (basis : List EqCnstr) (acc : List EqCnstr) : RingM (List EqCnstr) := do
209+ match basis with
210+ | [] => return acc.reverse
211+ | c' :: basis =>
212+ match c'.p with
213+ | .add _ m' _ =>
214+ if m.divides m' then
215+ let c'' ← c'.simplifyWithExhaustively c
216+ trace[grind.debug.ring.simpBasis] "simplified: {← c''.denoteExpr}"
217+ unless (← checkConstant c'') do
218+ addToQueue c''
219+ go basis acc
220+ else
221+ go basis (c' :: acc)
222+ | _ => go basis (c' :: acc)
223+ let basis ← go (← getRing).basis []
224+ modifyRing fun s => { s with basis }
237225
238226def EqCnstr.addToBasisAfterSimp (c : EqCnstr) : RingM Unit := do
239227 let c ← c.toMonic
0 commit comments