Skip to content

Commit 6dc769a

Browse files
committed
fix(Tactic/Ring): sort terms when evaluating nested powers (#37494)
`ring` currently misorders the terms in a product when evaluating nested powers. When evaluating e.g. `(x^a*x)^b` where `x` is an atom, it returns `x^(a*b)*x^b` even if `b` is supposed to come before `a*b` in the ordering on `ExProd`s. We fix this by running `evalMulProd` instead of using the `.mul` constructor directly. This in effect does an insertion sort on the terms in the `ExProd`s. We do a similar thing when evaluating multiplication. ``` /-- error: ring failed, ring expressions not equal a : ℚ m n : ℕ ⊢ a ^ n * a ^ (m * n) = a ^ (m * n) * a ^ n -/ #guard_msgs in example (a : ℚ) (m n : ℕ) : (a ^ (m + 1)) ^ n = a ^ (n * (m + 1)) := by ring1 ```
1 parent f5da5c5 commit 6dc769a

File tree

2 files changed

+8
-1
lines changed

2 files changed

+8
-1
lines changed

Mathlib/Tactic/Ring/Common.lean

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,11 @@ theorem mul_pow {ea₁ b c₁ : ℕ} {xa₁ : R}
899899
(_ : ea₁ * b = c₁) (_ : a₂ ^ b = c₂) : (xa₁ ^ ea₁ * a₂ : R) ^ b = xa₁ ^ c₁ * c₂ := by
900900
subst_vars; simp [_root_.mul_pow, pow_mul]
901901

902+
theorem mul_pow_mul {ea₁ b c₁ : ℕ} {xa₁ d : R} (_ : ea₁ * b = c₁) (_ : a₂ ^ b = c₂)
903+
(_ : (xa₁ ^ c₁ * (nat_lit 1).rawCast) * c₂ = d) :
904+
(xa₁ ^ ea₁ * a₂ : R) ^ b = d := by
905+
subst_vars; simp [_root_.mul_pow, pow_mul, Nat.rawCast]
906+
902907
-- needed to lift from `OptionT CoreM` to `OptionT MetaM`
903908
private local instance {m m'} [Monad m] [Monad m'] [MonadLiftT m m'] :
904909
MonadLiftT (OptionT m) (OptionT m') where
@@ -933,7 +938,8 @@ def evalPowProd {a : Q($α)} {b : Q(ℕ)} (va : ExProd sα a) (vb : ExProd sℕ
933938
| .mul vxa₁ vea₁ va₂, vb =>
934939
let ⟨_, vc₁, pc₁⟩ ← evalMulProd sℕ vea₁ vb
935940
let ⟨_, vc₂, pc₂⟩ ← evalPowProd va₂ vb
936-
return ⟨_, .mul vxa₁ vc₁ vc₂, q(mul_pow $pc₁ $pc₂)⟩
941+
let ⟨_, vd, pd⟩ ← evalMulProd sα (vxa₁.toProd vc₁) vc₂
942+
return ⟨_, vd, q(mul_pow_mul $pc₁ $pc₂ $pd)⟩
937943
| _, _ => OptionT.fail
938944
return (← res.run).getD (evalPowProdAtom sα va vb)
939945

MathlibTest/ring.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ example (a b : ℤ) : a+b=0 ↔ b+a=0 := by
166166

167167
-- Powers in the exponent get evaluated correctly
168168
example (X : ℤ) : (X^5 + 1) * (X^2^3 + X) = X^13 + X^8 + X^6 + X := by ring
169+
example (a : ℚ) (m n : ℕ) : (a ^ (m + 1)) ^ n = a ^ (n * (m + 1)) := by ring
169170

170171
-- simulate the type of MvPolynomial
171172
def R : Type u → Type v → Sort (max (u+1) (v+1)) := test_sorry

0 commit comments

Comments
 (0)