Skip to content

Commit 96ec37b

Browse files
Add BitVec double-negation optimization (#866)
Signed-off-by: John Kastner <jkastner@amazon.com>
1 parent 8d50049 commit 96ec37b

File tree

3 files changed

+45
-1
lines changed

3 files changed

+45
-1
lines changed

cedar-lean/Cedar/SymCC/Factory.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ def app : UnaryFunction → Term → Term
151151

152152
def bvneg : Term → Term
153153
| .prim (.bitvec b) => b.neg
154+
| .app .bvneg [t] _ => t
154155
| t => .app .bvneg [t] t.typeOf
155156

156157
def bvapp (op : Op) (fn : ∀ {n}, BitVec n → BitVec n → BitVec n) (t₁ t₂ : Term) : Term :=

cedar-lean/Cedar/Thm/SymCC/Term/Interpret/Factory.lean

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,10 +659,48 @@ theorem interpret_bvnego {εs : SymEntities} {I : Interpretation} {t : Term} {n
659659
(Factory.bvnego t).interpret I = Factory.bvnego (t.interpret I)
660660
:= by show_interpret_unary_op Factory.bvnego wfl_of_type_bitvec_is_bitvec interpret_term_app_bvnego
661661

662+
theorem interpret_bvneg_inv {εs : SymEntities} {I : Interpretation} {t : Term} {n : Nat} :
663+
I.WellFormed εs → t.WellFormed εs → t.typeOf = .bitvec n →
664+
bvneg (Term.interpret I t) = Term.prim (TermPrim.bitvec bv) →
665+
Term.interpret I t = Term.prim (TermPrim.bitvec (-bv))
666+
:= by
667+
intro h₁ h₂ h₃ h₄
668+
simp only [bvneg] at h₄
669+
split at h₄
670+
· rename_i h₅
671+
simp only [Term.prim.injEq, TermPrim.bitvec.injEq, h₅] at h₄ ⊢
672+
replace ⟨h₄, h₆⟩ := h₄
673+
subst h₄
674+
simp [←eq_of_heq h₆]
675+
· rename_i h₅
676+
have ⟨_, h₆⟩ : ∃ (bv : BitVec n), Term.interpret I t = Term.prim (TermPrim.bitvec bv) := by
677+
have ⟨hwf₁, hwf₂⟩ := interpret_term_wfl h₁ h₂
678+
simp only [h₃] at hwf₂
679+
simp [wfl_of_type_bitvec_is_bitvec hwf₁ hwf₂]
680+
simp [h₆] at h₅
681+
· contradiction
682+
662683
theorem interpret_bvneg {εs : SymEntities} {I : Interpretation} {t : Term} {n : Nat} :
663684
I.WellFormed εs → t.WellFormed εs → t.typeOf = .bitvec n →
664685
(Factory.bvneg t).interpret I = Factory.bvneg (t.interpret I)
665-
:= by show_interpret_unary_op Factory.bvneg wfl_of_type_bitvec_is_bitvec interpret_term_app_bvneg
686+
:= by
687+
intro h₁ h₂ h₃
688+
conv => lhs; unfold Factory.bvneg
689+
split
690+
· simp only [Factory.bvneg, interpret_term_prim]
691+
· rename_i t' _
692+
have ⟨hwf₁, hwf₂⟩ := interpret_term_wfl h₁ h₂
693+
cases h₂; rename_i hwf hwt
694+
cases hwt; rename_i ht'
695+
replace hwf : Term.WellFormed εs t' := by
696+
simpa using hwf
697+
rw [interpret_term_app_bvneg] at ⊢ hwf₁ hwf₂
698+
simp only [Term.typeOf] at hwf₂
699+
have ⟨bv, h⟩ := wfl_of_type_bitvec_is_bitvec hwf₁ hwf₂
700+
rw [h]
701+
simp only [bvneg, BitVec.neg_eq]
702+
exact interpret_bvneg_inv h₁ hwf ht' h
703+
· exact interpret_term_app_bvneg
666704

667705
local macro "show_interpret_bvop" op_fun:ident pe_fun:ident interpret_op_thm:ident : tactic => do
668706
`(tactic| (

cedar-lean/Cedar/Thm/SymCC/Term/WF.lean

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,11 @@ theorem wf_bvneg {εs : SymEntities} {t : Term} {n : Nat}
839839
split
840840
case h_1 => simp [wf_bv, typeOf_bv, typeOf_bv_width h₂]
841841
case h_2 =>
842+
simp only [Term.typeOf] at h₂
843+
cases h₁; rename_i h₁ h₃
844+
cases h₃; rename_i h₃
845+
simp [h₁, h₂, h₃]
846+
case h_3 =>
842847
simp [Term.typeOf, h₂]
843848
exact Term.WellFormed.app_wf (wf_arg h₁) (Op.WellTyped.bvneg_wt h₂)
844849

0 commit comments

Comments
 (0)