@@ -9,6 +9,7 @@ public import Lean.Meta.Sym.Simp.SimpM
99import Init.Sym.Lemmas
1010import Lean.Meta.Sym.LitValues
1111import Lean.Meta.StringLitProof
12+ import Lean.Meta.Offset
1213namespace 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+
537599public 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
585658end Lean.Meta.Sym.Simp
0 commit comments