Skip to content

Commit 6271d8f

Browse files
authored
feat: bitvec ground SymM simprocs for bit-vectors (#14031)
This PR implements `SymM` simprocs for reducing bit-vector conversion operations.
1 parent b118504 commit 6271d8f

1 file changed

Lines changed: 73 additions & 0 deletions

File tree

src/Lean/Meta/Sym/Simp/EvalGround.lean

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ public import Lean.Meta.Sym.Simp.SimpM
99
import Init.Sym.Lemmas
1010
import Lean.Meta.Sym.LitValues
1111
import Lean.Meta.StringLitProof
12+
import Lean.Meta.Offset
1213
namespace Lean.Meta.Sym.Simp
1314

1415
/-!
@@ -534,6 +535,67 @@ def evalNot (a : Expr) : SimpM Result :=
534535
| False => return .step (← getTrueExpr) (mkConst ``Sym.not_false_eq) (done := true)
535536
| _ => return .rfl
536537

538+
abbrev mkRflBitVec (a : Expr) (n : Nat) : Expr :=
539+
mkApp2 (mkConst ``Eq.refl [1]) (mkApp (mkConst ``BitVec) (toExpr n)) a
540+
541+
def evalInt8ToBitVec (a : Expr) : SimpM Result := do
542+
let some v ← getInt8Value? a |>.run | return .rfl
543+
let v ← share <| toExpr v.toBitVec
544+
return .step v (mkRflBitVec v 8) (done := true)
545+
546+
def evalInt16ToBitVec (a : Expr) : SimpM Result := do
547+
let some v ← getInt16Value? a |>.run | return .rfl
548+
let v ← share <| toExpr v.toBitVec
549+
return .step v (mkRflBitVec v 16) (done := true)
550+
551+
def evalInt32ToBitVec (a : Expr) : SimpM Result := do
552+
let some v ← getInt32Value? a |>.run | return .rfl
553+
let v ← share <| toExpr v.toBitVec
554+
return .step v (mkRflBitVec v 32) (done := true)
555+
556+
def evalInt64ToBitVec (a : Expr) : SimpM Result := do
557+
let some v ← getInt64Value? a |>.run | return .rfl
558+
let v ← share <| toExpr v.toBitVec
559+
return .step v (mkRflBitVec v 64) (done := true)
560+
561+
def evalUInt8ToBitVec (a : Expr) : SimpM Result := do
562+
let some v ← getUInt8Value? a |>.run | return .rfl
563+
let v ← share <| toExpr v.toBitVec
564+
return .step v (mkRflBitVec v 8) (done := true)
565+
566+
def evalUInt16ToBitVec (a : Expr) : SimpM Result := do
567+
let some v ← getUInt16Value? a |>.run | return .rfl
568+
let v ← share <| toExpr v.toBitVec
569+
return .step v (mkRflBitVec v 16) (done := true)
570+
571+
def evalUInt32ToBitVec (a : Expr) : SimpM Result := do
572+
let some v ← getUInt32Value? a |>.run | return .rfl
573+
let v ← share <| toExpr v.toBitVec
574+
return .step v (mkRflBitVec v 32) (done := true)
575+
576+
def evalUInt64ToBitVec (a : Expr) : SimpM Result := do
577+
let some v ← getUInt64Value? a |>.run | return .rfl
578+
let v ← share <| toExpr v.toBitVec
579+
return .step v (mkRflBitVec v 64) (done := true)
580+
581+
def evalSetWidth (v x : Expr) : SimpM Result := do
582+
let some v ← getNatValue? v |>.run | return .rfl
583+
let some x := getBitVecValue? x | return .rfl
584+
let x ← share <| toExpr <| x.val.setWidth v
585+
return .step x (mkRflBitVec x v) (done := true)
586+
587+
def evalBitVecToNat (a : Expr) : SimpM Result := do
588+
let some a := getBitVecValue? a | return .rfl
589+
let a ← share (toExpr a.val.toNat)
590+
return .step a (mkApp2 (mkConst ``Eq.refl [1]) Nat.mkType a) (done := true)
591+
592+
def evalBitVecOfNat (n a : Expr) : SimpM Result := do
593+
let some a ← getNatValue? a |>.run | return .rfl
594+
if (← getNatValue? n |>.run).isSome then return .rfl -- already in normal form
595+
let some n ← evalNat n |>.run | return .rfl -- TODO: consider using dsimp
596+
let r ← share (toExpr (BitVec.ofNat n a))
597+
return .step r (mkRflBitVec r n) (done := true)
598+
537599
public structure EvalStepConfig where
538600
maxExponent := 255
539601

@@ -580,6 +642,17 @@ public def evalGround (config : EvalStepConfig := {}) : Simproc := fun e =>
580642
| BEq.beq α _ a b => evalBEq α a b
581643
| bne α _ a b => evalBNe α a b
582644
| Not a => evalNot a
645+
| BitVec.setWidth _ v x => evalSetWidth v x
646+
| BitVec.toNat _ a => evalBitVecToNat a
647+
| BitVec.ofNat n a => evalBitVecOfNat n a
648+
| Int8.toBitVec a => evalInt8ToBitVec a
649+
| Int16.toBitVec a => evalInt16ToBitVec a
650+
| Int32.toBitVec a => evalInt32ToBitVec a
651+
| Int64.toBitVec a => evalInt64ToBitVec a
652+
| UInt8.toBitVec a => evalUInt8ToBitVec a
653+
| UInt16.toBitVec a => evalUInt16ToBitVec a
654+
| UInt32.toBitVec a => evalUInt32ToBitVec a
655+
| UInt64.toBitVec a => evalUInt64ToBitVec a
583656
| _ => return .rfl
584657

585658
end Lean.Meta.Sym.Simp

0 commit comments

Comments
 (0)