Skip to content

Commit

Permalink
feat: use RArray in simp_arith meta code (#6068 part 2)
Browse files Browse the repository at this point in the history
This PR makes `simp_arith` use `RArray` for the context of the
reflection proofs, which scales better when there are many variables.
  • Loading branch information
nomeata committed Nov 14, 2024
1 parent f75cde6 commit a652e9c
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 15 deletions.
10 changes: 3 additions & 7 deletions src/Init/Data/Nat/Linear.lean
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Authors: Leonardo de Moura
prelude
import Init.ByCases
import Init.Data.Prod
import Init.Data.RArray

namespace Nat.Linear

Expand All @@ -15,20 +16,15 @@ namespace Nat.Linear

abbrev Var := Nat

abbrev Context := List Nat
abbrev Context := Lean.RArray Nat

/--
When encoding polynomials. We use `fixedVar` for encoding numerals.
The denotation of `fixedVar` is always `1`. -/
def fixedVar := 100000000 -- Any big number should work here

def Var.denote (ctx : Context) (v : Var) : Nat :=
bif v == fixedVar then 1 else go ctx v
where
go : List Nat → Nat → Nat
| [], _ => 0
| a::_, 0 => a
| _::as, i+1 => go as i
bif v == fixedVar then 1 else ctx.get v

inductive Expr where
| num (v : Nat)
Expand Down
26 changes: 19 additions & 7 deletions tests/lean/run/linearByRefl.lean
Original file line number Diff line number Diff line change
@@ -1,48 +1,60 @@
import Lean

open Nat.Linear

-- Convenient RArray literals
elab tk:"#R[" ts:term,* "]" : term => do
let ts : Array Lean.Syntax := ts
let es ← ts.mapM fun stx => Lean.Elab.Term.elabTerm stx none
if h : 0 < es.size then
return (Lean.RArray.toExpr (← Lean.Meta.inferType es[0]!) id (Lean.RArray.ofArray es h))
else
throwErrorAt tk "RArray cannot be empty"


example (x₁ x₂ x₃ : Nat) : (x₁ + x₂) + (x₂ + x₃) = x₃ + 2*x₂ + x₁ :=
Expr.eq_of_toNormPoly [x₁, x₂, x₃]
Expr.eq_of_toNormPoly #R[x₁, x₂, x₃]
(Expr.add (Expr.add (Expr.var 0) (Expr.var 1)) (Expr.add (Expr.var 1) (Expr.var 2)))
(Expr.add (Expr.add (Expr.var 2) (Expr.mulL 2 (Expr.var 1))) (Expr.var 0))
rfl

example (x₁ x₂ x₃ : Nat) : ((x₁ + x₂) + (x₂ + x₃) = x₃ + x₂) = (x₁ + x₂ = 0) :=
Expr.of_cancel_eq [x₁, x₂, x₃]
Expr.of_cancel_eq #R[x₁, x₂, x₃]
(Expr.add (Expr.add (Expr.var 0) (Expr.var 1)) (Expr.add (Expr.var 1) (Expr.var 2)))
(Expr.add (Expr.var 2) (Expr.var 1))
(Expr.add (Expr.var 0) (Expr.var 1))
(Expr.num 0)
rfl

example (x₁ x₂ x₃ : Nat) : ((x₁ + x₂) + (x₂ + x₃) ≤ x₃ + x₂) = (x₁ + x₂ ≤ 0) :=
Expr.of_cancel_le [x₁, x₂, x₃]
Expr.of_cancel_le #R[x₁, x₂, x₃]
(Expr.add (Expr.add (Expr.var 0) (Expr.var 1)) (Expr.add (Expr.var 1) (Expr.var 2)))
(Expr.add (Expr.var 2) (Expr.var 1))
(Expr.add (Expr.var 0) (Expr.var 1))
(Expr.num 0)
rfl

example (x₁ x₂ x₃ : Nat) : ((x₁ + x₂) + (x₂ + x₃) < x₃ + x₂) = (x₁ + x₂ < 0) :=
Expr.of_cancel_lt [x₁, x₂, x₃]
Expr.of_cancel_lt #R[x₁, x₂, x₃]
(Expr.add (Expr.add (Expr.var 0) (Expr.var 1)) (Expr.add (Expr.var 1) (Expr.var 2)))
(Expr.add (Expr.var 2) (Expr.var 1))
(Expr.add (Expr.var 0) (Expr.var 1))
(Expr.num 0)
rfl

example (x₁ x₂ : Nat) : x₁ + 23*x₂ → 4*x₂ ≤ 3 + x₁ → 32*x₂ → False :=
Certificate.of_combine_isUnsat [x₁, x₂]
Certificate.of_combine_isUnsat #R[x₁, x₂]
[ (1, { eq := false, lhs := Expr.add (Expr.var 0) (Expr.num 2), rhs := Expr.mulL 3 (Expr.var 1) }),
(1, { eq := false, lhs := Expr.mulL 4 (Expr.var 1), rhs := Expr.add (Expr.num 3) (Expr.var 0) }),
(0, { eq := false, lhs := Expr.num 3, rhs := Expr.mulL 2 (Expr.var 1) }) ]
rfl

example (x : Nat) (xs : List Nat) : (sizeOf x < 1 + (1 + sizeOf x + sizeOf xs)) = True :=
ExprCnstr.eq_true_of_isValid [sizeOf x, sizeOf xs]
ExprCnstr.eq_true_of_isValid #R[sizeOf x, sizeOf xs]
{ eq := false, lhs := Expr.inc (Expr.var 0), rhs := Expr.add (Expr.num 1) (Expr.add (Expr.add (Expr.num 1) (Expr.var 0)) (Expr.var 1)) }
rfl

example (x : Nat) (xs : List Nat) : (1 + (1 + sizeOf x + sizeOf xs) < sizeOf x) = False :=
ExprCnstr.eq_false_of_isUnsat [sizeOf x, sizeOf xs]
ExprCnstr.eq_false_of_isUnsat #R[sizeOf x, sizeOf xs]
{ eq := false, lhs := Expr.inc <| Expr.add (Expr.num 1) (Expr.add (Expr.add (Expr.num 1) (Expr.var 0)) (Expr.var 1)), rhs := Expr.var 0 }
rfl
14 changes: 13 additions & 1 deletion tests/lean/run/som1.lean
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
import Lean

open Nat.SOM

-- Convenient RArray literals
elab tk:"#R[" ts:term,* "]" : term => do
let ts : Array Lean.Syntax := ts
let es ← ts.mapM fun stx => Lean.Elab.Term.elabTerm stx none
if h : 0 < es.size then
return (Lean.RArray.toExpr (← Lean.Meta.inferType es[0]!) id (Lean.RArray.ofArray es h))
else
throwErrorAt tk "RArray cannot be empty"

example : (x + y) * (x + y + 1) = x * (1 + y + x) + (y + 1 + x) * y :=
let ctx := [x, y]
let ctx := #R[x, y]
let lhs : Expr := .mul (.add (.var 0) (.var 1)) (.add (.add (.var 0) (.var 1)) (.num 1))
let rhs : Expr := .add (.mul (.var 0) (.add (.add (.num 1) (.var 1)) (.var 0)))
(.mul (.add (.add (.var 1) (.num 1)) (.var 0)) (.var 1))
Expand Down

0 comments on commit a652e9c

Please sign in to comment.