mirror of
https://github.com/leanprover/lean4.git
synced 2026-04-05 03:34:08 +00:00
Compare commits
4 Commits
grind_proo
...
grind_proo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
caf2ba7c8b | ||
|
|
57050be3ab | ||
|
|
37b53b70d0 | ||
|
|
8a1e50f0b9 |
@@ -82,7 +82,7 @@ instance : ToExpr Gate where
|
||||
| .and => mkConst ``Gate.and
|
||||
| .xor => mkConst ``Gate.xor
|
||||
| .beq => mkConst ``Gate.beq
|
||||
| .imp => mkConst ``Gate.imp
|
||||
| .or => mkConst ``Gate.or
|
||||
toTypeExpr := mkConst ``Gate
|
||||
|
||||
instance : ToExpr BVPred where
|
||||
|
||||
@@ -91,7 +91,7 @@ where
|
||||
| .and => ``Std.Tactic.BVDecide.Reflect.Bool.and_congr
|
||||
| .xor => ``Std.Tactic.BVDecide.Reflect.Bool.xor_congr
|
||||
| .beq => ``Std.Tactic.BVDecide.Reflect.Bool.beq_congr
|
||||
| .imp => ``Std.Tactic.BVDecide.Reflect.Bool.imp_congr
|
||||
| .or => ``Std.Tactic.BVDecide.Reflect.Bool.or_congr
|
||||
|
||||
/--
|
||||
Construct the reified version of `Bool.not subExpr`.
|
||||
@@ -136,7 +136,7 @@ def mkIte (discr lhs rhs : ReifiedBVLogical) (discrExpr lhsExpr rhsExpr : Expr)
|
||||
lhsEvalExpr lhsProof?
|
||||
rhsEvalExpr rhsProof? | return none
|
||||
return mkApp9
|
||||
(mkConst ``Std.Tactic.BVDecide.Reflect.Bool.ite_congr)
|
||||
(mkConst ``Std.Tactic.BVDecide.Reflect.Bool.cond_congr)
|
||||
discrExpr lhsExpr rhsExpr
|
||||
discrEvalExpr lhsEvalExpr rhsEvalExpr
|
||||
discrProof lhsProof rhsProof
|
||||
|
||||
@@ -22,67 +22,70 @@ This function adds the two lemmas:
|
||||
- `discrExpr = false → atomExpr = rhsExpr`
|
||||
It assumes that `discrExpr`, `lhsExpr` and `rhsExpr` are the expressions corresponding to `discr`,
|
||||
`lhs` and `rhs`. Furthermore it assumes that `atomExpr` is of the form
|
||||
`if discrExpr = true then lhsExpr else rhsExpr`.
|
||||
`bif discrExpr then lhsExpr else rhsExpr`.
|
||||
-/
|
||||
def addIfLemmas (discr : ReifiedBVLogical) (atom lhs rhs : ReifiedBVExpr)
|
||||
def addCondLemmas (discr : ReifiedBVLogical) (atom lhs rhs : ReifiedBVExpr)
|
||||
(discrExpr atomExpr lhsExpr rhsExpr : Expr) : LemmaM Unit := do
|
||||
let some trueLemma ← mkIfTrueLemma discr atom lhs rhs discrExpr atomExpr lhsExpr rhsExpr | return ()
|
||||
let some trueLemma ← mkCondTrueLemma discr atom lhs discrExpr atomExpr lhsExpr rhsExpr | return ()
|
||||
LemmaM.addLemma trueLemma
|
||||
let some falseLemma ← mkIfFalseLemma discr atom lhs rhs discrExpr atomExpr lhsExpr rhsExpr | return ()
|
||||
let some falseLemma ← mkCondFalseLemma discr atom rhs discrExpr atomExpr lhsExpr rhsExpr | return ()
|
||||
LemmaM.addLemma falseLemma
|
||||
where
|
||||
mkIfTrueLemma (discr : ReifiedBVLogical) (atom lhs rhs : ReifiedBVExpr)
|
||||
(discrExpr atomExpr lhsExpr rhsExpr : Expr) : M (Option SatAtBVLogical) :=
|
||||
mkIfLemma true discr atom lhs rhs discrExpr atomExpr lhsExpr rhsExpr
|
||||
|
||||
mkIfFalseLemma (discr : ReifiedBVLogical) (atom lhs rhs : ReifiedBVExpr)
|
||||
(discrExpr atomExpr lhsExpr rhsExpr : Expr) : M (Option SatAtBVLogical) :=
|
||||
mkIfLemma false discr atom lhs rhs discrExpr atomExpr lhsExpr rhsExpr
|
||||
|
||||
mkIfLemma (discrVal : Bool) (discr : ReifiedBVLogical) (atom lhs rhs : ReifiedBVExpr)
|
||||
mkCondTrueLemma (discr : ReifiedBVLogical) (atom lhs : ReifiedBVExpr)
|
||||
(discrExpr atomExpr lhsExpr rhsExpr : Expr) : M (Option SatAtBVLogical) := do
|
||||
let resExpr := if discrVal then lhsExpr else rhsExpr
|
||||
let resValExpr := if discrVal then lhs else rhs
|
||||
let lemmaName :=
|
||||
if discrVal then
|
||||
``Std.Tactic.BVDecide.Reflect.BitVec.if_true
|
||||
else
|
||||
``Std.Tactic.BVDecide.Reflect.BitVec.if_false
|
||||
let discrValExpr := toExpr discrVal
|
||||
let discrVal ← ReifiedBVLogical.mkBoolConst discrVal
|
||||
let resExpr := lhsExpr
|
||||
let resValExpr := lhs
|
||||
let lemmaName := ``Std.Tactic.BVDecide.Reflect.BitVec.cond_true
|
||||
|
||||
let eqDiscrExpr ← mkAppM ``BEq.beq #[discrExpr, discrValExpr]
|
||||
let eqDiscr ← ReifiedBVLogical.mkGate discr discrVal discrExpr discrValExpr .beq
|
||||
|
||||
let notDiscrExpr := mkApp (mkConst ``Bool.not) discrExpr
|
||||
let notDiscr ← ReifiedBVLogical.mkNot discr discrExpr
|
||||
|
||||
let eqBVExpr ← mkAppM ``BEq.beq #[atomExpr, resExpr]
|
||||
let some eqBVPred ← ReifiedBVPred.mkBinPred atom resValExpr atomExpr resExpr .eq | return none
|
||||
let eqBV ← ReifiedBVLogical.ofPred eqBVPred
|
||||
|
||||
let imp ← ReifiedBVLogical.mkGate eqDiscr eqBV eqDiscrExpr eqBVExpr .imp
|
||||
let imp ← ReifiedBVLogical.mkGate notDiscr eqBV notDiscrExpr eqBVExpr .or
|
||||
|
||||
let proof := do
|
||||
let evalExpr ← ReifiedBVLogical.mkEvalExpr imp.expr
|
||||
let congrProof := (← imp.evalsAtAtoms).getD (ReifiedBVLogical.mkRefl evalExpr)
|
||||
let lemmaProof := mkApp4 (mkConst lemmaName) (toExpr lhs.width) discrExpr lhsExpr rhsExpr
|
||||
|
||||
let trueExpr := mkConst ``Bool.true
|
||||
let eqDiscrTrueExpr ← mkEq eqDiscrExpr trueExpr
|
||||
let eqBVExprTrueExpr ← mkEq eqBVExpr trueExpr
|
||||
let impExpr ← mkArrow eqDiscrTrueExpr eqBVExprTrueExpr
|
||||
-- construct a `Decidable` instance for the implication using forall_prop_decidable
|
||||
let decEqDiscrTrue := mkApp2 (mkConst ``instDecidableEqBool) eqDiscrExpr trueExpr
|
||||
let decEqBVExprTrue := mkApp2 (mkConst ``instDecidableEqBool) eqBVExpr trueExpr
|
||||
let impDecidable := mkApp4 (mkConst ``forall_prop_decidable)
|
||||
eqDiscrTrueExpr
|
||||
(.lam .anonymous eqDiscrTrueExpr eqBVExprTrueExpr .default)
|
||||
decEqDiscrTrue
|
||||
(.lam .anonymous eqDiscrTrueExpr decEqBVExprTrue .default)
|
||||
|
||||
let decideImpExpr := mkApp2 (mkConst ``Decidable.decide) impExpr impDecidable
|
||||
-- !discr || (atom == rhs)
|
||||
let impExpr := mkApp2 (mkConst ``Bool.or) notDiscrExpr eqBVExpr
|
||||
|
||||
return mkApp4
|
||||
(mkConst ``Std.Tactic.BVDecide.Reflect.Bool.lemma_congr)
|
||||
decideImpExpr
|
||||
impExpr
|
||||
evalExpr
|
||||
congrProof
|
||||
lemmaProof
|
||||
return some ⟨imp.bvExpr, proof, imp.expr⟩
|
||||
|
||||
mkCondFalseLemma (discr : ReifiedBVLogical) (atom rhs : ReifiedBVExpr)
|
||||
(discrExpr atomExpr lhsExpr rhsExpr : Expr) : M (Option SatAtBVLogical) := do
|
||||
let resExpr := rhsExpr
|
||||
let resValExpr := rhs
|
||||
let lemmaName := ``Std.Tactic.BVDecide.Reflect.BitVec.cond_false
|
||||
|
||||
let eqBVExpr ← mkAppM ``BEq.beq #[atomExpr, resExpr]
|
||||
let some eqBVPred ← ReifiedBVPred.mkBinPred atom resValExpr atomExpr resExpr .eq | return none
|
||||
let eqBV ← ReifiedBVLogical.ofPred eqBVPred
|
||||
|
||||
let imp ← ReifiedBVLogical.mkGate discr eqBV discrExpr eqBVExpr .or
|
||||
|
||||
let proof := do
|
||||
let evalExpr ← ReifiedBVLogical.mkEvalExpr imp.expr
|
||||
let congrProof := (← imp.evalsAtAtoms).getD (ReifiedBVLogical.mkRefl evalExpr)
|
||||
let lemmaProof := mkApp4 (mkConst lemmaName) (toExpr rhs.width) discrExpr lhsExpr rhsExpr
|
||||
|
||||
-- discr || (atom == rhs)
|
||||
let impExpr := mkApp2 (mkConst ``Bool.or) discrExpr eqBVExpr
|
||||
|
||||
return mkApp4
|
||||
(mkConst ``Std.Tactic.BVDecide.Reflect.Bool.lemma_congr)
|
||||
impExpr
|
||||
evalExpr
|
||||
congrProof
|
||||
lemmaProof
|
||||
|
||||
@@ -220,15 +220,12 @@ where
|
||||
.rotateRight
|
||||
``BVUnOp.rotateRight
|
||||
``Std.Tactic.BVDecide.Reflect.BitVec.rotateRight_congr
|
||||
| ite _ discrExpr _ lhsExpr rhsExpr =>
|
||||
let_expr Eq α discrExpr val := discrExpr | return none
|
||||
let_expr Bool := α | return none
|
||||
let_expr Bool.true := val | return none
|
||||
| cond _ discrExpr lhsExpr rhsExpr =>
|
||||
let some atom ← ReifiedBVExpr.bitVecAtom x true | return none
|
||||
let some discr ← ReifiedBVLogical.of discrExpr | return none
|
||||
let some lhs ← goOrAtom lhsExpr | return none
|
||||
let some rhs ← goOrAtom rhsExpr | return none
|
||||
addIfLemmas discr atom lhs rhs discrExpr x lhsExpr rhsExpr
|
||||
addCondLemmas discr atom lhs rhs discrExpr x lhsExpr rhsExpr
|
||||
return some atom
|
||||
| _ => return none
|
||||
|
||||
@@ -392,10 +389,7 @@ where
|
||||
| Bool => gateReflection lhsExpr rhsExpr .beq
|
||||
| BitVec _ => goPred t
|
||||
| _ => return none
|
||||
| ite _ discrExpr _ lhsExpr rhsExpr =>
|
||||
let_expr Eq α discrExpr val := discrExpr | return none
|
||||
let_expr Bool := α | return none
|
||||
let_expr Bool.true := val | return none
|
||||
| cond _ discrExpr lhsExpr rhsExpr =>
|
||||
let some discr ← goOrAtom discrExpr | return none
|
||||
let some lhs ← goOrAtom lhsExpr | return none
|
||||
let some rhs ← goOrAtom rhsExpr | return none
|
||||
|
||||
@@ -127,8 +127,6 @@ builtin_simproc [bv_normalize] bv_add_const' (((_ : BitVec _) + (_ : BitVec _))
|
||||
else
|
||||
return .continue
|
||||
|
||||
attribute [builtin_bv_normalize_proc↓] reduceIte
|
||||
|
||||
/-- Return a number `k` such that `2^k = n`. -/
|
||||
private def Nat.log2Exact (n : Nat) : Option Nat := do
|
||||
guard <| n ≠ 0
|
||||
|
||||
@@ -31,5 +31,7 @@ builtin_initialize registerTraceClass `grind.debug
|
||||
builtin_initialize registerTraceClass `grind.debug.proofs
|
||||
builtin_initialize registerTraceClass `grind.simp
|
||||
builtin_initialize registerTraceClass `grind.congr
|
||||
builtin_initialize registerTraceClass `grind.proof
|
||||
builtin_initialize registerTraceClass `grind.proof.detail
|
||||
|
||||
end Lean
|
||||
|
||||
@@ -142,7 +142,6 @@ where
|
||||
flipped
|
||||
}
|
||||
let parents ← removeParents lhsRoot.self
|
||||
-- TODO: set propagateBool
|
||||
updateRoots lhs rhsNode.root
|
||||
trace[grind.debug] "{← ppENodeRef lhs} new root {← ppENodeRef rhsNode.root}, {← ppENodeRef (← getRoot lhs)}"
|
||||
reinsertParents parents
|
||||
@@ -162,7 +161,6 @@ where
|
||||
|
||||
updateRoots (lhs : Expr) (rootNew : Expr) : GoalM Unit := do
|
||||
let rec loop (e : Expr) : GoalM Unit := do
|
||||
-- TODO: propagateBool
|
||||
let n ← getENode e
|
||||
setENode e { n with root := rootNew }
|
||||
unless (← isInconsistent) do
|
||||
|
||||
@@ -20,6 +20,9 @@ private def checkEqc (root : ENode) : GoalM Unit := do
|
||||
size := size + 1
|
||||
-- The root of `curr` must be `root`
|
||||
assert! isSameExpr (← getRoot curr) root.self
|
||||
-- If the equivalence class does not have HEq proofs, then the types must be definitionally equal.
|
||||
unless root.heqProofs do
|
||||
assert! (← withDefault <| isDefEq (← inferType curr) (← inferType root.self))
|
||||
-- Starting at `curr`, following the `target?` field leads to `root`.
|
||||
let mut n := curr
|
||||
repeat
|
||||
|
||||
@@ -81,6 +81,7 @@ mutual
|
||||
else
|
||||
flipProof h flipped heq
|
||||
|
||||
/-- Given `acc : lhs₀ = lhs`, returns a proof of `lhs₀ = common`. -/
|
||||
private partial def mkProofTo (lhs : Expr) (common : Expr) (acc : Option Expr) (heq : Bool) : GoalM (Option Expr) := do
|
||||
if isSameExpr lhs common then
|
||||
return acc
|
||||
@@ -92,9 +93,7 @@ mutual
|
||||
let acc ← mkTrans' acc h heq
|
||||
mkProofTo target common (some acc) heq
|
||||
|
||||
/--
|
||||
Given `lhsEqCommon : lhs = common`, returns a proof for `lhs = rhs`.
|
||||
-/
|
||||
/-- Given `lhsEqCommon : lhs = common`, returns a proof for `lhs = rhs`. -/
|
||||
private partial def mkProofFrom (rhs : Expr) (common : Expr) (lhsEqCommon? : Option Expr) (heq : Bool) : GoalM (Option Expr) := do
|
||||
if isSameExpr rhs common then
|
||||
return lhsEqCommon?
|
||||
@@ -124,13 +123,22 @@ Returns a proof that `a = b` (or `HEq a b`).
|
||||
It assumes `a` and `b` are in the same equivalence class.
|
||||
-/
|
||||
def mkEqProof (a b : Expr) : GoalM Expr := do
|
||||
let n ← getENode a
|
||||
if !n.heqProofs then
|
||||
mkEqProofCore a b (heq := false)
|
||||
else if (← withDefault <| isDefEq (← inferType a) (← inferType b)) then
|
||||
mkEqProofCore a b (heq := false)
|
||||
else
|
||||
mkEqProofCore a b (heq := true)
|
||||
let p ← go
|
||||
trace[grind.proof.detail] "{p}"
|
||||
return p
|
||||
where
|
||||
go : GoalM Expr := do
|
||||
let n ← getRootENode a
|
||||
if !n.heqProofs then
|
||||
trace[grind.proof] "{a} = {b}"
|
||||
mkEqProofCore a b (heq := false)
|
||||
else
|
||||
if (← withDefault <| isDefEq (← inferType a) (← inferType b)) then
|
||||
trace[grind.proof] "{a} = {b}"
|
||||
mkEqOfHEq (← mkEqProofCore a b (heq := true))
|
||||
else
|
||||
trace[grind.proof] "{a} ≡ {b}"
|
||||
mkEqProofCore a b (heq := true)
|
||||
|
||||
/--
|
||||
Returns a proof that `a = True`.
|
||||
|
||||
@@ -330,6 +330,10 @@ def getRoot? (e : Expr) : GoalM (Option Expr) := do
|
||||
def getRoot (e : Expr) : GoalM Expr :=
|
||||
return (← getENode e).root
|
||||
|
||||
/-- Returns the root enode in the equivalence class of `e`. -/
|
||||
def getRootENode (e : Expr) : GoalM ENode := do
|
||||
getENode (← getRoot e)
|
||||
|
||||
/-- Returns the next element in the equivalence class of `e`. -/
|
||||
def getNext (e : Expr) : GoalM Expr :=
|
||||
return (← getENode e).next
|
||||
@@ -350,7 +354,7 @@ def pushEqCore (lhs rhs proof : Expr) (isHEq : Bool) : GoalM Unit :=
|
||||
modify fun s => { s with newEqs := s.newEqs.push { lhs, rhs, proof, isHEq } }
|
||||
|
||||
@[inline] def pushEqHEq (lhs rhs proof : Expr) : GoalM Unit := do
|
||||
if (← isDefEq (← inferType lhs) (← inferType rhs)) then
|
||||
if (← withDefault <| isDefEq (← inferType lhs) (← inferType rhs)) then
|
||||
pushEqCore lhs rhs proof (isHEq := false)
|
||||
else
|
||||
pushEqCore lhs rhs proof (isHEq := true)
|
||||
|
||||
@@ -293,8 +293,15 @@ The semantics for `BVExpr`.
|
||||
-/
|
||||
def eval (assign : Assignment) : BVExpr w → BitVec w
|
||||
| .var idx =>
|
||||
let ⟨bv⟩ := assign.get idx
|
||||
bv.truncate w
|
||||
let packedBv := assign.get idx
|
||||
/-
|
||||
This formulation improves performance, as in a well formed expression the condition always holds
|
||||
so there is no need for the more involved `BitVec.truncate` logic.
|
||||
-/
|
||||
if h : packedBv.w = w then
|
||||
h ▸ packedBv.bv
|
||||
else
|
||||
packedBv.bv.truncate w
|
||||
| .const val => val
|
||||
| .zeroExtend v expr => BitVec.zeroExtend v (eval assign expr)
|
||||
| .extract start len expr => BitVec.extractLsb' start len (eval assign expr)
|
||||
@@ -308,8 +315,13 @@ def eval (assign : Assignment) : BVExpr w → BitVec w
|
||||
| .arithShiftRight lhs rhs => BitVec.sshiftRight' (eval assign lhs) (eval assign rhs)
|
||||
|
||||
@[simp]
|
||||
theorem eval_var : eval assign ((.var idx) : BVExpr w) = (assign.get idx).bv.truncate _ := by
|
||||
rfl
|
||||
theorem eval_var : eval assign ((.var idx) : BVExpr w) = (assign.get idx).bv.truncate w := by
|
||||
rw [eval]
|
||||
split
|
||||
· next h =>
|
||||
subst h
|
||||
simp
|
||||
· rfl
|
||||
|
||||
@[simp]
|
||||
theorem eval_const : eval assign (.const val) = val := by rfl
|
||||
@@ -454,7 +466,7 @@ def eval (assign : BVExpr.Assignment) (expr : BVLogicalExpr) : Bool :=
|
||||
@[simp] theorem eval_not : eval assign (.not x) = !eval assign x := rfl
|
||||
@[simp] theorem eval_gate : eval assign (.gate g x y) = g.eval (eval assign x) (eval assign y) := rfl
|
||||
@[simp] theorem eval_ite :
|
||||
eval assign (.ite d l r) = if (eval assign d) then (eval assign l) else (eval assign r) := rfl
|
||||
eval assign (.ite d l r) = bif (eval assign d) then (eval assign l) else (eval assign r) := rfl
|
||||
|
||||
def Sat (x : BVLogicalExpr) (assign : BVExpr.Assignment) : Prop := eval assign x = true
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ inductive Gate
|
||||
| and
|
||||
| xor
|
||||
| beq
|
||||
| imp
|
||||
| or
|
||||
|
||||
namespace Gate
|
||||
|
||||
@@ -26,13 +26,13 @@ def toString : Gate → String
|
||||
| and => "&&"
|
||||
| xor => "^^"
|
||||
| beq => "=="
|
||||
| imp => "->"
|
||||
| or => "||"
|
||||
|
||||
def eval : Gate → Bool → Bool → Bool
|
||||
| and => (· && ·)
|
||||
| xor => (· ^^ ·)
|
||||
| beq => (· == ·)
|
||||
| imp => (· → ·)
|
||||
| or => (· || ·)
|
||||
|
||||
end Gate
|
||||
|
||||
@@ -59,13 +59,13 @@ def eval (a : α → Bool) : BoolExpr α → Bool
|
||||
| .const b => b
|
||||
| .not x => !eval a x
|
||||
| .gate g x y => g.eval (eval a x) (eval a y)
|
||||
| .ite d l r => if d.eval a then l.eval a else r.eval a
|
||||
| .ite d l r => bif d.eval a then l.eval a else r.eval a
|
||||
|
||||
@[simp] theorem eval_literal : eval a (.literal l) = a l := rfl
|
||||
@[simp] theorem eval_const : eval a (.const b) = b := rfl
|
||||
@[simp] theorem eval_not : eval a (.not x) = !eval a x := rfl
|
||||
@[simp] theorem eval_gate : eval a (.gate g x y) = g.eval (eval a x) (eval a y) := rfl
|
||||
@[simp] theorem eval_ite : eval a (.ite d l r) = if d.eval a then l.eval a else r.eval a := rfl
|
||||
@[simp] theorem eval_ite : eval a (.ite d l r) = bif d.eval a then l.eval a else r.eval a := rfl
|
||||
|
||||
def Sat (a : α → Bool) (x : BoolExpr α) : Prop := eval a x = true
|
||||
def Unsat (x : BoolExpr α) : Prop := ∀ f, eval f x = false
|
||||
|
||||
@@ -75,9 +75,9 @@ where
|
||||
let ret := aig.mkBEqCached input
|
||||
have := LawfulOperator.le_size (f := mkBEqCached) aig input
|
||||
⟨ret, by dsimp only [ret] at lextend rextend ⊢; omega⟩
|
||||
| .imp =>
|
||||
let ret := aig.mkImpCached input
|
||||
have := LawfulOperator.le_size (f := mkImpCached) aig input
|
||||
| .or =>
|
||||
let ret := aig.mkOrCached input
|
||||
have := LawfulOperator.le_size (f := mkOrCached) aig input
|
||||
⟨ret, by dsimp only [ret] at lextend rextend ⊢; omega⟩
|
||||
|
||||
namespace ofBoolExprCached
|
||||
@@ -127,9 +127,9 @@ theorem go_decl_eq (idx) (aig : AIG β) (h : idx < aig.decls.size) (hbounds) :
|
||||
| beq =>
|
||||
simp only [go]
|
||||
rw [AIG.LawfulOperator.decl_eq (f := mkBEqCached), rih, lih]
|
||||
| imp =>
|
||||
| or =>
|
||||
simp only [go]
|
||||
rw [AIG.LawfulOperator.decl_eq (f := mkImpCached), rih, lih]
|
||||
rw [AIG.LawfulOperator.decl_eq (f := mkOrCached), rih, lih]
|
||||
|
||||
theorem go_isPrefix_aig {aig : AIG β} :
|
||||
IsPrefix aig.decls (go aig expr atomHandler).val.aig.decls := by
|
||||
|
||||
@@ -118,7 +118,6 @@ theorem BitVec.srem_umod (x y : BitVec w) :
|
||||
rw [BitVec.srem_eq]
|
||||
cases x.msb <;> cases y.msb <;> simp
|
||||
|
||||
attribute [bv_normalize] Bool.cond_eq_if
|
||||
attribute [bv_normalize] BitVec.abs_eq
|
||||
attribute [bv_normalize] BitVec.twoPow_eq
|
||||
|
||||
|
||||
@@ -41,7 +41,14 @@ attribute [bv_normalize] Bool.not_not
|
||||
attribute [bv_normalize] Bool.and_self_left
|
||||
attribute [bv_normalize] Bool.and_self_right
|
||||
attribute [bv_normalize] eq_self
|
||||
attribute [bv_normalize] ite_self
|
||||
attribute [bv_normalize] Bool.cond_self
|
||||
attribute [bv_normalize] cond_false
|
||||
attribute [bv_normalize] cond_true
|
||||
attribute [bv_normalize] Bool.cond_not
|
||||
|
||||
@[bv_normalize]
|
||||
theorem if_eq_cond {b : Bool} {x y : α} : (if b = true then x else y) = (bif b then x else y) := by
|
||||
rw [cond_eq_if]
|
||||
|
||||
@[bv_normalize]
|
||||
theorem Bool.not_xor : ∀ (a b : Bool), !(a ^^ b) = (a == b) := by decide
|
||||
|
||||
@@ -13,8 +13,6 @@ This module contains the `Prop` simplifying part of the `bv_normalize` simp set.
|
||||
namespace Std.Tactic.BVDecide
|
||||
namespace Frontend.Normalize
|
||||
|
||||
attribute [bv_normalize] ite_true
|
||||
attribute [bv_normalize] ite_false
|
||||
attribute [bv_normalize] dite_true
|
||||
attribute [bv_normalize] dite_false
|
||||
attribute [bv_normalize] and_true
|
||||
|
||||
@@ -123,12 +123,12 @@ theorem umod_congr (lhs rhs lhs' rhs' : BitVec w) (h1 : lhs' = lhs) (h2 : rhs' =
|
||||
(lhs' % rhs') = (lhs % rhs) := by
|
||||
simp[*]
|
||||
|
||||
theorem if_true (discr : Bool) (lhs rhs : BitVec w) :
|
||||
decide ((discr == true) = true → ((if discr = true then lhs else rhs) == lhs) = true) = true := by
|
||||
theorem cond_true (discr : Bool) (lhs rhs : BitVec w) :
|
||||
(!discr || ((bif discr then lhs else rhs) == lhs)) = true := by
|
||||
cases discr <;> simp
|
||||
|
||||
theorem if_false (discr : Bool) (lhs rhs : BitVec w) :
|
||||
decide ((discr == false) = true → ((if discr = true then lhs else rhs) == rhs) = true) = true := by
|
||||
theorem cond_false (discr : Bool) (lhs rhs : BitVec w) :
|
||||
(discr || ((bif discr then lhs else rhs) == rhs)) = true := by
|
||||
cases discr <;> simp
|
||||
|
||||
end BitVec
|
||||
@@ -150,13 +150,13 @@ theorem beq_congr (lhs rhs lhs' rhs' : Bool) (h1 : lhs' = lhs) (h2 : rhs' = rhs)
|
||||
(lhs' == rhs') = (lhs == rhs) := by
|
||||
simp[*]
|
||||
|
||||
theorem imp_congr (lhs rhs lhs' rhs' : Bool) (h1 : lhs' = lhs) (h2 : rhs' = rhs) :
|
||||
(decide (lhs' → rhs')) = (decide (lhs → rhs)) := by
|
||||
theorem or_congr (lhs rhs lhs' rhs' : Bool) (h1 : lhs' = lhs) (h2 : rhs' = rhs) :
|
||||
(lhs' || rhs') = (lhs || rhs) := by
|
||||
simp[*]
|
||||
|
||||
theorem ite_congr (discr lhs rhs discr' lhs' rhs' : Bool) (h1 : discr' = discr) (h2 : lhs' = lhs)
|
||||
theorem cond_congr (discr lhs rhs discr' lhs' rhs' : Bool) (h1 : discr' = discr) (h2 : lhs' = lhs)
|
||||
(h3 : rhs' = rhs) :
|
||||
(if discr' = true then lhs' else rhs') = (if discr = true then lhs else rhs) := by
|
||||
(bif discr' = true then lhs' else rhs') = (bif discr = true then lhs else rhs) := by
|
||||
simp[*]
|
||||
|
||||
theorem false_of_eq_true_of_eq_false (h₁ : x = true) (h₂ : x = false) : False := by
|
||||
|
||||
6
tests/lean/run/6043.lean
Normal file
6
tests/lean/run/6043.lean
Normal file
@@ -0,0 +1,6 @@
|
||||
import Std.Tactic.BVDecide
|
||||
|
||||
theorem extracted_1 (x : BitVec 32) :
|
||||
BitVec.ofBool (x != 51#32) &&& BitVec.ofBool (x != 50#32) =
|
||||
BitVec.ofBool (4294967294#32 > x + 4294967244#32) := by
|
||||
bv_decide
|
||||
@@ -85,6 +85,7 @@ example : (BitVec.twoPow 16 2) = 4#16 := by bv_normalize
|
||||
example {x : BitVec 16} : x / (BitVec.twoPow 16 2) = x >>> 2 := by bv_normalize
|
||||
example {x : BitVec 16} : x / (BitVec.ofNat 16 8) = x >>> 3 := by bv_normalize
|
||||
example {x y : Bool} (h1 : x && y) : x || y := by bv_normalize
|
||||
example (a b c: Bool) : (if a then b else c) = (if !a then c else b) := by bv_normalize
|
||||
|
||||
section
|
||||
|
||||
|
||||
@@ -23,17 +23,8 @@ theorem substructure_unit_3' (x y : BitVec 8) : Bool.xor (x = y) (y ≠ x) := by
|
||||
theorem substructure_unit_4 (a b : Bool) : (a && b) = (b && a) := by
|
||||
bv_decide
|
||||
|
||||
theorem substructure_unit_5 (a : Bool) (b c : BitVec 32) (h1 : b < c ↔ a) (h2 : a = true) : b < c := by
|
||||
theorem substructure_unit_5 (x : BitVec 32) : (if x.getLsbD 0 then !x.getLsbD 0 else x.getLsbD 0) = false := by
|
||||
bv_decide
|
||||
|
||||
theorem substructure_unit_6 (a b c: Bool) : (if a then b else c) = (if !a then c else b) := by
|
||||
bv_decide
|
||||
|
||||
theorem substructure_unit_7 (a b c: Bool) : (bif a then b else c) = (bif !a then c else b) := by
|
||||
bv_decide
|
||||
|
||||
theorem substructure_unit_8 (x : BitVec 32) : (if x.getLsbD 0 then !x.getLsbD 0 else x.getLsbD 0) = false := by
|
||||
bv_decide
|
||||
|
||||
theorem substructure_unit_9 (x y : BitVec 32) (h : x.getLsbD 0 = false) : (if x.getLsbD 0 then x else y) = y := by
|
||||
theorem substructure_unit_6 (x y : BitVec 32) (h : x.getLsbD 0 = false) : (if x.getLsbD 0 then x else y) = y := by
|
||||
bv_decide
|
||||
|
||||
@@ -13,8 +13,7 @@ elab "grind_test" : tactic => withMainContext do
|
||||
logInfo (← getEqc n.self)
|
||||
|
||||
set_option grind.debug true
|
||||
-- TODO: fix nested proof support
|
||||
-- set_option grind.debug.proofs true
|
||||
set_option grind.debug.proofs true
|
||||
|
||||
/-
|
||||
Recall that array access terms, such as `a[i]`, have nested proofs.
|
||||
|
||||
@@ -9,6 +9,7 @@ elab "grind_pre" : tactic => do
|
||||
abbrev f (a : α) := a
|
||||
|
||||
set_option grind.debug true
|
||||
set_option grind.debug.proofs true
|
||||
|
||||
/--
|
||||
warning: declaration uses 'sorry'
|
||||
@@ -112,7 +113,13 @@ theorem ex3 (h : a₁ :: { x := a₂, y := a₃ : Point } :: as = b₁ :: { x :=
|
||||
|
||||
def h (a : α) := a
|
||||
|
||||
set_option trace.grind.pre true
|
||||
set_option trace.grind.pre true in
|
||||
example (p : Prop) (a b c : Nat) : p → a = 0 → a = b → h a = h c → a = c ∧ c = a → a = b ∧ b = a → a ≠ c := by
|
||||
grind_pre
|
||||
sorry
|
||||
|
||||
set_option trace.grind.proof.detail true in
|
||||
set_option trace.grind.proof true in
|
||||
example (a : α) (p q r : Prop) : (h₁ : HEq p a) → (h₂ : HEq q a) → (h₃ : p = r) → False := by
|
||||
grind_pre
|
||||
sorry
|
||||
|
||||
Reference in New Issue
Block a user