feat: replace ToExpr Int (#3472)

The current `ToExpr Int` instance produces `@Int.ofNat (@OfNat.ofNat Nat
i ...)` for nonnegative `i` and `@Int.negSucc (@OfNat.ofNat Nat (-i+1)
...)` for negative `i`.

However it should be producing `@OfNat.ofNat Int i ...` for nonnegative
`i`, and `@Neg.neg ... (@OfNat.ofNat Int (-i) ...)` for negative `i`.
This commit is contained in:
Scott Morrison 2024-02-23 13:30:05 +11:00 committed by GitHub
parent b9b4d8f41d
commit 5a32473f66
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 16 additions and 25 deletions

View file

@ -23,22 +23,6 @@ Allow elaboration of `OmegaConfig` arguments to tactics.
-/
declare_config_elab elabOmegaConfig Lean.Meta.Omega.OmegaConfig
/--
The current `ToExpr` instance for `Int` is bad,
so we roll our own here.
-/
def mkInt (i : Int) : Expr :=
if 0 ≤ i then
mkNat i.toNat
else
mkApp3 (.const ``Neg.neg [0]) (.const ``Int []) (mkNat (-i).toNat)
(.const ``Int.instNegInt [])
where
mkNat (n : Nat) : Expr :=
let r := mkRawNatLit n
mkApp3 (.const ``OfNat.ofNat [0]) (.const ``Int []) r
(.app (.const ``instOfNat []) r)
/-- Match on the two defeq expressions for successor: `n+1`, `n.succ`. -/
def succ? (e : Expr) : Option Expr :=
match e.getAppFnArgs with
@ -202,16 +186,16 @@ partial def asLinearComboImpl (e : Expr) : OmegaM (LinearCombo × OmegaM Expr ×
| (``HMod.hMod, #[_, _, _, _, n, k]) =>
match groundNat? k with
| some k' => do
let k' := mkInt k'
let k' := toExpr (k' : Int)
rewrite (← mkAppM ``HMod.hMod #[n, k']) (mkApp2 (.const ``Int.emod_def []) n k')
| none => mkAtomLinearCombo e
| (``HDiv.hDiv, #[_, _, _, _, x, z]) =>
match groundInt? z with
| some 0 => rewrite e (mkApp (.const ``Int.ediv_zero []) x)
| some i => do
let e' ← mkAppM ``HDiv.hDiv #[x, mkInt i]
let e' ← mkAppM ``HDiv.hDiv #[x, toExpr i]
if i < 0 then
rewrite e' (mkApp2 (.const ``Int.ediv_neg []) x (mkInt (-i)))
rewrite e' (mkApp2 (.const ``Int.ediv_neg []) x (toExpr (-i)))
else
mkAtomLinearCombo e'
| _ => mkAtomLinearCombo e

View file

@ -31,9 +31,16 @@ instance : ToExpr Nat where
instance : ToExpr Int where
toTypeExpr := .const ``Int []
toExpr i := match i with
| .ofNat n => mkApp (.const ``Int.ofNat []) (toExpr n)
| .negSucc n => mkApp (.const ``Int.negSucc []) (toExpr n)
toExpr i := if 0 ≤ i then
mkNat i.toNat
else
mkApp3 (.const ``Neg.neg [0]) (.const ``Int []) (.const ``Int.instNegInt [])
(mkNat (-i).toNat)
where
mkNat (n : Nat) : Expr :=
let r := mkRawNatLit n
mkApp3 (.const ``OfNat.ofNat [0]) (.const ``Int []) r
(.app (.const ``instOfNat []) r)
instance : ToExpr Bool where
toExpr := fun b => if b then mkConst ``Bool.true else mkConst ``Bool.false

View file

@ -414,13 +414,13 @@ example (i : Fin 7) : (i : Nat) < 8 := by omega
example (x y z i : Nat) (hz : z ≤ 1) : x % 2 ^ i + y % 2 ^ i + z < 2 * 2^ i := by omega
-- Check that we correctly process base^(e+1) for constant base.
example (x e : Nat) (hx : x < 2^(e+1)) : x < 2^e *2 := by omega
example (x e : Nat) (hx : x < 2^(e+1)) : x < 2^e * 2 := by omega
-- Check that we correctly handle `e.succ`
example (x e : Nat) (hx : x < 2^(e.succ)) : x < 2^e *2 := by omega
example (x e : Nat) (hx : x < 2^(e.succ)) : x < 2^e * 2 := by omega
-- Check that this works for integer base.
example (x : Int) (e : Nat) (hx : x < (2 : Int)^(e+1)) : x < 2^e *2 := by omega
example (x : Int) (e : Nat) (hx : x < (2 : Int)^(e+1)) : x < 2^e * 2 := by omega
/-! ### Ground terms -/