You are an expert Lean4 and formal verification agent proving a Lean4 theorem. Your output **must** strictly adhere to the specified format.

### Input Information
You will receive the following components, relevant to the target theorem:
* <all_available_defs>: Definitions available from imported modules (either from the current Lean repository or from Mathlib)
* <all_available_lemmas>: Lemmas/theorems available that may assist the proof.
* <local_ctx>...</local_ctx>: The local file context (imports, namespaces, definitions, comments, etc.) from the top of the file up to—but not including—the target theorem or any previously defined local lemmas/theorems.
* <target_theorem>...</target_theorem>: The target theorem statement, ending with `:=`.

**Notes**
1. Definitions include their full bodies, but for definitions whose bodies contain proofs, the proof parts are replaced by `admit` (i.e., admit /- proof elided -/), while the rest of the definition is kept unchanged; lemmas include only their statements.
2. You may freely reference any definition or lemma contained in these tags without redefining them.
3. The tags for available definitions and lemmas (all_available_defs, all_available_lemmas) may be omitted if empty.

### Output Format & Requirements
Your output MUST contain a complete, syntactically correct Lean 4 proof for the target theorem.

**Strict Output Structure:**
<reasoning> 
...
</reasoning> 

<lean4_invented_lemmas>
-- each lemma is a full Lean 4 declaration with a complete proof
...
</lean4_invented_lemmas>

<lean4_proof>
-- Lean 4 proof body of the target theorem
...
</lean4_proof>

**Requirements:**
1. <reasoning> and <lean4_invented_lemmas> are OPTIONAL. Include them only if they aid proof construction.
2. <lean4_proof> MUST contain only the proof body (tactics/terms), starting by "by", NOT the theorem declaration.
3. <lean4_invented_lemmas> (if present) MUST contain syntactically correct lemma declarations that type checks AND complete proof bodies. Defining a lemma using `axiom` is NOT allowed.
4. <reasoning> contains high-level proof planning.
5. If you create a lemma under <lean4_invented_lemmas> whose name is namespaced (e.g., X.Y.Z), you MUST always refer to it using its fully qualified name. Do NOT rely on shortened names. For example, write rw [X.Y.Z], not rw [Z] for invented lemmas.
6. All Lean 4 code MUST be syntactically correct. No `sorry`, `admit`, or non-Lean text. Comments allowed using `--` or `/- ... -/`.
7. Follow the tags and structure EXACTLY. No extra text before, between, or after the sections.
8. Do NOT wrap invented lemmas in a `mutual` block unless they have genuine mutual recursion. Declare each lemma independently.

### Examples are provided here (example input are under "User Prompt", and example assistant response are under "Agent Response"):
Example 1 ------------------- 
User Prompt:
<all_available_defs>
structure BitVec (w : Nat) where
  /-- Construct a `BitVec w` from a number less than `2^w`.
  O(1), because we use `Fin` as the internal representation of a bitvector. -/
  ofFin ::

  /-- Interpret a bitvector as a number less than `2^w`.
  O(1), because we use `Fin` as the internal representation of a bitvector. -/
  toFin : Fin (hPow 2 w)
</all_available_defs>

<all_available_lemmas>
theorem List.getElem_append_left{α : Type u_1} {l₁ l₂ : List α} {i : Nat} (hn : i < l₁.length) : (l₁ ++ l₂)[i] = l₁[i]
theorem getElem_eq_testBit_toNat (x : BitVec w) (i : Nat) (h : i < w) :
  x[i] = x.toNat.testBit i := rfl
@[simp, grind =] theorem toNat_cons (b : Bool) (x : BitVec w) :
    (cons b x).toNat = (b.toNat <<< w) ||| x.toNat
@[simp, grind =] theorem getLsbD_of_ge (x : BitVec w) (i : Nat) (ge : w ≤ i) : getLsbD x i = false
theorem testBit_toNat (x : BitVec w) : x.toNat.testBit i = x.getLsbD i
</all_available_lemmas>

<local_ctx>
import Mathlib.Computability.NFA
import Mathlib.Data.FinEnum
import Mathlib.Data.Rel
import Mathlib.Data.Vector.Basic
import Blase.AutoStructs.ForLean

open Set
open Mathlib
open SetRel

-- this is better because card is defeq to n
instance (α : Type) : Inter (Language α) := ⟨Set.inter⟩
instance (α : Type) : Union (Language α) := ⟨Set.union⟩

/--
The set of `n`-tuples of bit vectors of an arbitrary width.
-/
structure BitVecs (n : Nat) where
  w : Nat
  bvs : List.Vector (BitVec w) n

def BitVecs.cast (bvs : BitVecs n) (h : n = n') : BitVecs n' :=
  { w := bvs.w, bvs := h ▸ bvs.bvs }

abbrev BitVecs.empty : BitVecs n := ⟨0, List.Vector.replicate n .nil⟩
abbrev BitVecs.singleton {w : Nat} (bv : BitVec w) : BitVecs 1 := ⟨w, bv ::ᵥ .nil⟩
abbrev BitVecs.pair {w : Nat} (bv1 bv2 : BitVec w) : BitVecs 2 := ⟨w, bv1 ::ᵥ bv2 ::ᵥ .nil⟩

/--
The set of `n`-tuples of bit vectors of an arbitrary width, encoded as a list of
bit vectors of width `n`. The width of the encoded bit vectors is the length of
the list.
-/
abbrev BitVecs' (n : Nat) := List (BitVec n)

@[simps]
def dec (bvs' : BitVecs' n) : BitVecs n where
  w := bvs'.length
  bvs := List.Vector.ofFn fun k => BitVec.ofFn fun i => bvs'[i].getLsbD k

@[simp]
</local_ctx>

<target_theorem>
lemma dec_snoc n (bvs' : BitVecs' n) (a : BitVec n) :
  dec (bvs' ++ [a]) =
    { w := bvs'.length + 1
      bvs := List.Vector.ofFn fun k =>
        BitVec.cons (a.getLsbD k) ((dec bvs').bvs.get k) } :=
</target_theorem>

Agent Response:
<reasoning> 
The goal is to understand what `dec` does after appending one more bitvector `a` to `bvs'`. By definition, `dec` builds a width `= length` and a vector of bitvectors whose `i`-th bit at position `k` is `bvs'[i].getLsbD k`. So for `bvs' ++ [a]`, we expect the width to increase by 1 and each resulting bitvector to be `BitVec.cons` of the new bit coming from `a`.

First, I use `ext` twice: once on the record to focus on the `bvs` field, and once on the resulting bitvector. This reduces everything to a pointwise statement:
for fixed `k` and `i` with `i < bvs'.length + 1`,
the bit `(bvs' ++ [a])[i].getLsbD k` should match the bit at index `i` of `BitVec.cons (a.getLsbD k) ((dec bvs').bvs.get k)`.

At this point I need a clean description of indexing into `BitVec.cons`: if we have `x : BitVec n`, then `(cons b x)[i]` should give `b` at the new “last” index `n` and `x[i]` otherwise. That motivates an auxiliary lemma `getElem_cons` expressing exactly this behavior, proved via the `testBit`/`toNat` characterization and a case split on `i < n`, `i = n`, `i > n`.

Using `getElem_cons`, the RHS becomes an `if` on whether `i = bvs'.length`. So I split into cases:
- If `i = bvs'.length`, then `(bvs' ++ [a])[i]` is the appended `a`, so both sides reduce to `a.getLsbD k`.
- If `i ≠ bvs'.length`, the bound `i < bvs'.length + 1` forces `i < bvs'.length`. Then `(bvs' ++ [a])[i] = bvs'[i]` by `List.getElem_append_left`, and the RHS takes the “else” branch and likewise gives the bit from `bvs'[i]`. In both subcases, `simp` (plus the definition of `dec`) finishes.

So the whole proof is: `ext` to bit level, unfold `dec` with `simp_all`, rewrite with `getElem_cons`, split on the boundary index `i = length bvs'`, and in the “< length” branch use `List.getElem_append_left` and bounds to line up both sides.
</reasoning> 

<lean4_invented_lemmas>
@[grind =]
theorem getElem_cons {b : Bool} {n} {x : BitVec n} {i : Nat} (h : i < n + 1) :
    (cons b x)[i] = if h : i = n then b else x[i] := by
  simp only [BitVec.getElem_eq_testBit_toNat, BitVec.toNat_cons, Nat.testBit_or]
  rw [Nat.testBit_shiftLeft]
  rcases Nat.lt_trichotomy i n with i_lt_n | i_eq_n | n_lt_i
  · have p1 : ¬(n ≤ i) := by omega
    have p2 : i ≠ n := by omega
    simp [p1, p2]
  · simp only [i_eq_n, ge_iff_le, Nat.le_refl, decide_true, Nat.sub_self, Nat.testBit_zero,
    Bool.true_and, BitVec.testBit_toNat, BitVec.getLsbD_of_ge, Bool.or_false]
    cases b <;> trivial
  · have p1 : i ≠ n := by omega
    have p2 : i - n ≠ 0 := by omega
    simp [p1, p2, Nat.testBit_bool_toNat]
</lean4_invented_lemmas>

<lean4_proof>
by
  ext k i hi <;> simp_all
  rw [getElem_cons]
  split
  next heq => simp_all
  next h =>
    have hlt : i < List.length bvs' := by simp at hi; omega
    rw [List.getElem_append_left hlt]
    simp
</lean4_proof>

### Your task:
<all_available_defs>
Std.HashMap in Std.Data.HashMap.Basic
Std.HashMap.emptyWithCapacity in Std.Data.HashMap.Basic
Nat in Init.Prelude
BEq in Init.Prelude
DecidableEq in Init.Prelude
FinEnum in Mathlib.Data.FinEnum
Hashable in Init.Prelude
Repr in Init.Data.Repr
Std.HashSet in Std.Data.HashSet.Basic
Finset in Mathlib.Data.Finset.Defs
Finset.range in Mathlib.Data.Finset.Range
Option in Init.Prelude
Set in Mathlib.Data.Set.Defs
LawfulBEq in Init.Core
Function.update in Mathlib.Logic.Function.Basic
Prod in Init.Prelude
Prod.snd in Init.Prelude
Std.HashMap.map in Std.Data.HashMap.AdditionalOperations
LawfulHashable in Init.Data.LawfulHashable
Inhabited in Init.Prelude

instance RawCNFA.statesFinset (m : RawCNFA A) : Fintype m.states := (Finset.range m.stateMax).fintypeCoeSort

abbrev State := Nat

def RawCNFA.states (m : RawCNFA A) : Finset State := Finset.range m.stateMax

@[inline]
def RawCNFA.tr (m : RawCNFA A) s a := m.trans.getD (s, a) ∅

def Std.HashSet.toSet [BEq α] [Hashable α] (m : HashSet α) : Set α := { x | x ∈ m }

def Std.HashMap.toPFun [BEq α] [Hashable α] (m : HashMap α β) (x : α) : Option β := m[x]?

def p_after := [llvm|
{
^0(%arg60 : i32, %arg61 : i32, %arg62 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg60, %arg62 : i32
  %2 = llvm.xor %arg62, %0 : i32
  %3 = llvm.and %arg61, %2 : i32
  %4 = llvm.or disjoint %1, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def masked_and_notallones_logical_before := [llvm|
{
^0(%arg128 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(39 : i32) : i32
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.and %arg128, %0 : i32
  %4 = llvm.icmp "ne" %3, %0 : i32
  %5 = llvm.and %arg128, %1 : i32
  %6 = llvm.icmp "ne" %5, %1 : i32
  %7 = "llvm.select"(%4, %6, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%7) : (i1) -> ()
}
]

def testExampleSource : DCOp.TokenStream :=
  exampleSink.denote (Ctxt.Valuation.ofHVector (.cons inputSource <| .nil))

def or_xor_common_op_commute7_after := [llvm|
{
^0(%arg114 : i8, %arg115 : i8, %arg116 : i8):
  %0 = llvm.or %arg115, %arg114 : i8
  %1 = llvm.or %0, %arg116 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def and_logic_and_logic_or_1_before := [llvm|
{
^0(%arg138 : i1, %arg139 : i1, %arg140 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.and %arg138, %arg139 : i1
  %3 = "llvm.select"(%arg138, %arg140, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = "llvm.select"(%2, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def xor_icmp_to_icmp_add_after := [llvm|
{
^0(%arg4 : i32):
  %0 = llvm.mlir.constant(-6 : i32) : i32
  %1 = llvm.mlir.constant(-2 : i32) : i32
  %2 = llvm.add %arg4, %0 : i32
  %3 = llvm.icmp "ult" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def slt_or_not_max_logical_before := [llvm|
{
^0(%arg60 : i8, %arg61 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "slt" %arg60, %arg61 : i8
  %3 = llvm.icmp "ne" %arg60, %0 : i8
  %4 = "llvm.select"(%2, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def alive_AddSub_1043_tgt  (w : Nat)  :=
[llvm( w )| {
^bb0(%C1 : _, %Z : _, %RHS : _):
  %v1 = llvm.not %C1
  %v2 = llvm.or %Z, %v1
  %v3 = llvm.and %Z, %C1
  %v4 = llvm.xor %v3, %C1
  %v5 = llvm.mlir.constant 1
  %v6 = llvm.add %v4, %v5
  %v7 = llvm.sub %RHS, %v2
  llvm.return %v7
}]

def factorize4_after := [llvm|
{
^0(%arg3 : i32, %arg4 : i32):
  %0 = llvm.mul %arg4, %arg3 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def TypedSSAVal.mkVal [instTransformTy : TransformTy d φ] (Γ : Ctxt d.Ty) : TypedSSAVal φ →
    ReaderM d (Σ (ty : d.Ty), Ctxt.Var Γ ty)
| (.name valStx, tyStx) => do
    let ty ← instTransformTy.mkTy tyStx
    let var ← getValFromCtxt Γ valStx ty
    return ⟨ty, var⟩

def bb0 : Region 0 := [mlir_region|
{
  ^bb0(%arg0: i32):
    %0 = llvm.mlir.constant(8) : i32
    %1 = llvm.mlir.constant(31) : i32
    %2 = llvm.ashr %arg0, %1 : i32
    %3 = llvm.and %2, %0 : i32
    %4 = llvm.add %3, %2 : i32
    llvm.return %4 : i32
  }]

def shl_nsw_nuw_add_nsw_after := [llvm|
{
^0(%arg13 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.shl %0, %arg13 overflow<nsw> : i32
  %2 = llvm.xor %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def negtest_near_pow2_cmpval_isnt_close_to_pow2_before := [llvm|
{
^0(%arg1 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(6 : i8) : i8
  %2 = llvm.ashr exact %arg1, %0 : i8
  %3 = llvm.icmp "slt" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def xor_or_xor_common_op_commute8_before := [llvm|
{
^0(%arg59 : i32, %arg60 : i32, %arg61 : i32):
  %0 = llvm.xor %arg61, %arg59 : i32
  %1 = llvm.or %arg60, %arg59 : i32
  %2 = llvm.xor %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

Int.succ in Mathlib.Data.Int.Init

def shl_bad_sub_i64_before := [llvm|
{
^0(%arg7 : i64):
  %0 = llvm.mlir.constant(67) : i64
  %1 = llvm.mlir.constant(1) : i64
  %2 = llvm.sub %0, %arg7 : i64
  %3 = llvm.shl %1, %2 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

instance : ToFormat (MLIRType φ) := ⟨repr⟩

def bools_logical_after := [llvm|
{
^0(%arg48 : i1, %arg49 : i1, %arg50 : i1):
  %0 = "llvm.select"(%arg50, %arg49, %arg48) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def icmp_ult_riscv_eq_icmp_ult_llvm_64 : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] :=
  {lhs:= icmp_ult_llvm_64, rhs:= icmp_ult_riscv_64}

def sub_from_constant_of_sub_from_constant_after := [llvm|
{
^0(%arg170 : i8):
  %0 = llvm.mlir.constant(-31 : i8) : i8
  %1 = llvm.add %arg170, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def sle_or_min_logical_before := [llvm|
{
^0(%arg156 : i8, %arg157 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "sle" %arg156, %arg157 : i8
  %3 = llvm.icmp "eq" %arg156, %0 : i8
  %4 = "llvm.select"(%2, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def test13_logical_after := [llvm|
{
^0(%arg286 : i32, %arg287 : i32):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def llvm_sext_lower_riscv_i16_to_32 : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 16)] :=
  {lhs:= sext_llvm_i16_to_32, rhs:= sext_riscv_i16_to_32}

def scalar_i16_shl_ult_const_after := [llvm|
{
^0(%arg16 : i16):
  %0 = llvm.mlir.constant(252 : i16) : i16
  %1 = llvm.mlir.constant(0 : i16) : i16
  %2 = llvm.and %arg16, %0 : i16
  %3 = llvm.icmp "eq" %2, %1 : i16
  "llvm.return"(%3) : (i1) -> ()
}
]

def srem2_ashr_mask_after := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.srem %arg6, %0 : i32
  %2 = llvm.and %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def shl_xor_xor_no_const_before := [llvm|
{
^0(%arg134 : i8, %arg135 : i8, %arg136 : i8, %arg137 : i8):
  %0 = llvm.shl %arg134, %arg136 : i8
  %1 = llvm.shl %arg135, %arg136 : i8
  %2 = llvm.xor %1, %arg137 : i8
  %3 = llvm.xor %0, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def icmp_slt_0_and_icmp_sge_neg1_i64_fail_after := [llvm|
{
^0(%arg59 : i64):
  %0 = llvm.mlir.constant(-2) : i64
  %1 = llvm.mlir.constant(62) : i64
  %2 = llvm.mlir.constant(1) : i64
  %3 = llvm.mlir.constant(0) : i64
  %4 = llvm.icmp "sgt" %arg59, %0 : i64
  %5 = llvm.lshr %arg59, %1 : i64
  %6 = llvm.and %5, %2 : i64
  %7 = "llvm.select"(%4, %6, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%7) : (i64) -> ()
}
]

def p0_after := [llvm|
{
^0(%arg17 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.icmp "ugt" %arg17, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def mul_add_to_mul_3_before := [llvm|
{
^0(%arg30 : i16):
  %0 = llvm.mlir.constant(2 : i16) : i16
  %1 = llvm.mlir.constant(3 : i16) : i16
  %2 = llvm.mul %arg30, %0 : i16
  %3 = llvm.mul %arg30, %1 : i16
  %4 = llvm.add %2, %3 overflow<nsw> : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

def add_nsw_mul_nsw_before := [llvm|
{
^0(%arg33 : i16):
  %0 = llvm.add %arg33, %arg33 overflow<nsw> : i16
  %1 = llvm.add %0, %arg33 overflow<nsw> : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

def test_with_3_before := [llvm|
{
^0(%arg316 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.shl %0, %arg316 : i32
  %3 = llvm.and %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def slt_zero_slt_i1_fail_before := [llvm|
{
^0(%arg4 : i32, %arg5 : i1):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.zext %arg5 : i1 to i32
  %2 = llvm.lshr %arg4, %0 : i32
  %3 = llvm.icmp "slt" %1, %2 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def in_constant_varx_mone_invmask_after := [llvm|
{
^0(%arg41 : i4, %arg42 : i4):
  %0 = llvm.or %arg41, %arg42 : i4
  "llvm.return"(%0) : (i4) -> ()
}
]

def lshr_2_add_zext_basic_after := [llvm|
{
^0(%arg37 : i1, %arg38 : i1):
  %0 = llvm.and %arg37, %arg38 : i1
  %1 = llvm.zext %0 : i1 to i2
  "llvm.return"(%1) : (i2) -> ()
}
]

def and1_lshr1_is_cmp_eq_0_after := [llvm|
{
^0(%arg11 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.lshr %0, %arg11 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def BasicBlock.substitute (σ : Substitution) : BasicBlock Op T → BasicBlock Op T
  | ⟨label, args, program⟩ =>
      let σ' := args.foldl Substitution.removeMappingFor σ
      ⟨label, args, program.substitute σ'⟩

@[simp_denote]
def slti_llvm_i64 :=
  [LV| {
    ^entry (%a: i64):
    %0 = llvm.mlir.constant (2) : i64
    %1 = llvm.icmp.slt %a, %0 : i64
    %2 = llvm.zext %1 : i1 to i64
    llvm.return %2 : i64
  }]

def ashrsgt_03_13_before := [llvm|
{
^0(%arg272 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(-3 : i4) : i4
  %2 = llvm.ashr %arg272, %0 : i4
  %3 = llvm.icmp "sgt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

HAppend.hAppend in Init.Prelude

def a_false_implies_b_false2_after := [llvm|
{
^0(%arg3 : i8, %arg4 : i1, %arg5 : i1):
  %0 = llvm.mlir.constant(10 : i8) : i8
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "ugt" %arg3, %0 : i8
  %3 = "llvm.select"(%2, %1, %arg5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def neg_slt_n1_after := [llvm|
{
^0(%arg27 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.add %arg27, %0 : i8
  %3 = llvm.icmp "sgt" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def xor_i16_test: LLVMPeepholeRewriteRefine 16 [Ty.llvm (.bitvec 16), Ty.llvm (.bitvec 16) ] where
  lhs := xor_llvm_i16
  rhs := xor_riscv_i16

def bools_logical_commute1_and2_after := [llvm|
{
^0(%arg91 : i1, %arg92 : i1, %arg93 : i1):
  %0 = "llvm.select"(%arg93, %arg92, %arg91) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def lshrult_01_14_after := [llvm|
{
^0(%arg353 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def a_false_implies_b_false_after := [llvm|
{
^0(%arg6 : i8, %arg7 : i1, %arg8 : i1):
  %0 = llvm.mlir.constant(10 : i8) : i8
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "ugt" %arg6, %0 : i8
  %3 = "llvm.select"(%2, %1, %arg8) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def icmp_eq_zext_ne_non_boolean_after := [llvm|
{
^0(%arg31 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.icmp "eq" %arg31, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

def irc_constants_AMinusC1PlusC2_2_neg1 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (2) : i64
      %c2 = llvm.mlir.constant (-1) : i64
      %0 = llvm.sub %a, %c1 : i64
      %1 = llvm.add %0, %c2 : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (2) : i64
      %c2 = llvm.mlir.constant (-1) : i64
      %0 = llvm.sub %c2, %c1 : i64
      %1 = llvm.add %a, %0 : i64
      llvm.return %1 : i64
  }]

def select_icmp_and_8_eq_0_xor_8_before := [llvm|
{
^0(%arg181 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg181, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  %4 = llvm.xor %arg181, %0 : i32
  %5 = "llvm.select"(%3, %4, %arg181) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def negative4_before := [llvm|
{
^0(%arg6 : i32, %arg7 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg7, %0 : i32
  %3 = llvm.icmp "ne" %arg6, %2 : i32
  %4 = llvm.icmp "sge" %arg6, %1 : i32
  %5 = llvm.and %3, %4 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def test25_before := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.and %arg0, %0 : i32
  %2 = llvm.icmp "ugt" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def is_ascii_alphabetic_after := [llvm|
{
^0(%arg248 : i32):
  %0 = llvm.mlir.constant(-33 : i32) : i32
  %1 = llvm.mlir.constant(-65 : i32) : i32
  %2 = llvm.mlir.constant(26 : i32) : i32
  %3 = llvm.and %arg248, %0 : i32
  %4 = llvm.add %3, %1 : i32
  %5 = llvm.icmp "ult" %4, %2 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

def test_ne_0_and_15_add_3_before := [llvm|
{
^0(%arg2 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(15 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.add %arg2, %0 : i8
  %4 = llvm.and %3, %1 : i8
  %5 = llvm.icmp "ne" %4, %2 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

def land_land_left2_before := [llvm|
{
^0(%arg100 : i1, %arg101 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = "llvm.select"(%arg101, %arg100, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %2 = "llvm.select"(%1, %arg100, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%2) : (i1) -> ()
}
]

def logic_or_logic_and_7_before := [llvm|
{
^0(%arg69 : i1, %arg70 : i1, %arg71 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = "llvm.select"(%arg70, %0, %arg69) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = "llvm.select"(%arg71, %0, %arg69) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = "llvm.select"(%3, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def t20_before := [llvm|
{
^0(%arg145 : i8, %arg146 : i16):
  %0 = llvm.mlir.constant(-42 : i16) : i16
  %1 = llvm.shl %0, %arg146 : i16
  %2 = llvm.trunc %1 : i16 to i8
  %3 = llvm.sub %arg145, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def ashrsgt_01_13_exact_before := [llvm|
{
^0(%arg88 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(-3 : i4) : i4
  %2 = llvm.ashr exact %arg88, %0 : i4
  %3 = llvm.icmp "sgt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def lshrugt_03_06_exact_after := [llvm|
{
^0(%arg183 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

inductive NFA.msbState : Type where
| i | f
deriving DecidableEq, Fintype

def pr40493_neg3_after := [llvm|
{
^0(%arg15 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(4 : i32) : i32
  %2 = llvm.shl %arg15, %0 : i32
  %3 = llvm.and %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def OrZextOr_after := [llvm|
{
^0(%arg4 : i3):
  %0 = llvm.mlir.constant(11 : i5) : i5
  %1 = llvm.zext %arg4 : i3 to i5
  %2 = llvm.or %1, %0 : i5
  "llvm.return"(%2) : (i5) -> ()
}
]

def masked_icmps_mask_notallzeros_bmask_mixed_5_logical_after := [llvm|
{
^0(%arg81 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.and %arg81, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def mbaTac (g : MVarId) : TermElabM (List MVarId) := do
  g.withContext do
    let [g] ← g.apply (mkConst ``BitVec.eq_of_sub_zero)
      | throwError m!"unable to apply `BitVec.eq_of_sub_zero`."
    let .some g ← runBvMbaPreprocess  g
      | do
         trace[Bits.MBA] "goal closed by Mba normalizer."
         return []
    trace[Bits.MBA] m!"Normalized goal state to {indentD g}"
    let ((widthExpr, eqn), reflectState) ← g.withContext do runM <| reflectEqn (← g.getType)
    trace[Bits.MBA] m!"found expression of width: '{indentD widthExpr}'"
    let env ← State.envToExpr widthExpr reflectState
    trace[Bits.MBA] m!"replacing goal with reflected version. Equation: {indentD <| repr eqn}"
    trace[Bits.MBA] m!"Environment: {indentD (toMessageData reflectState.e2ix.toList)}"
    
    
    
    
    

    let gs ← g.withContext do g.apply (mkAppN (mkConst ``Eqn.forall_width_reflect_zero_of_width_one_denote_zero []) #[Eqn.toExpr eqn, widthExpr, env])
    let [g] := gs
      | throwError m!"expected single goal after applying reflection theorem, found {gs}"
    let dec ← mkDecideProof <| ← g.getType
    if ← isDefEq (mkMVar g) dec then
      trace[Bits.MBA] "successfully decided!"
      return []
    else
      logWarning "failed to prove theorem using decision procedure, statement is false."
      return [g]

def test_sub_sub_lhs_rhs_lhs_LHS := [mod_arith q, hq| {
  ^bb0(%a : !R, %b : !R):
    %sub = mod_arith.sub %a, %b : !R
    %sub2 = mod_arith.sub %sub, %a : !R
    return %sub2 : !R
}]

def or_not_and_commute7_before := [llvm|
{
^0(%arg516 : i32, %arg517 : i32, %arg518 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg517, %arg516 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.and %2, %arg518 : i32
  %4 = llvm.or %arg516, %arg518 : i32
  %5 = llvm.xor %4, %0 : i32
  %6 = llvm.and %5, %arg517 : i32
  %7 = llvm.or %3, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def uaddo_commute4_before := [llvm|
{
^0(%arg22 : i32, %arg23 : i32, %arg24 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg23, %0 : i32
  %2 = llvm.add %arg23, %arg22 : i32
  %3 = llvm.icmp "ult" %1, %arg22 : i32
  %4 = "llvm.select"(%3, %arg24, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def icmp_eq_and_pow2_shl_pow2_negative3_after := [llvm|
{
^0(%arg59 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def src_is_mask_p2_m1_before := [llvm|
{
^0(%arg90 : i8, %arg91 : i8):
  %0 = llvm.mlir.constant(123 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.mlir.constant(-1 : i8) : i8
  %3 = llvm.xor %arg90, %0 : i8
  %4 = llvm.shl %1, %arg91 : i8
  %5 = llvm.add %4, %2 : i8
  %6 = llvm.and %5, %3 : i8
  %7 = llvm.icmp "ult" %6, %3 : i8
  "llvm.return"(%7) : (i1) -> ()
}
]

def test_and3_after := [llvm|
{
^0(%arg44 : i32, %arg45 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.and %arg45, %0 : i32
  %2 = llvm.icmp "ult" %arg44, %1 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def sge_swap_and_max_logical_after := [llvm|
{
^0(%arg244 : i8, %arg245 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.icmp "eq" %arg244, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def zext_sext_sgt_known_nonneg_after := [llvm|
{
^0(%arg24 : i8, %arg25 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.udiv %0, %arg24 : i8
  %2 = llvm.icmp "sgt" %1, %arg25 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def p1_scalar_urem_by_nonconst_after := [llvm|
{
^0(%arg18 : i32, %arg19 : i32):
  %0 = llvm.mlir.constant(128 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg18, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def lshrugt_03_11_before := [llvm|
{
^0(%arg372 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(-5 : i4) : i4
  %2 = llvm.lshr %arg372, %0 : i4
  %3 = llvm.icmp "ugt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def elabDefSignatureFor (dialect : Term) (alts : TSyntax ``matchAltsSig) : CommandElabM Unit := do
  let msg := (return m!"{exceptEmoji ·} Defining operation signature for {dialect} dialect")
  withTraceNode `LeanMLIR.Elab msg (collapsed := false) <| do
    let alts := getMatchAlts alts
    let alts ← do
      alts.mapM fun view => do
        trace[LeanMLIR.Elab] m!"Parsing match alternative with\n\
          \tpatterns: {view.patterns}\n\
          \tsignature: {view.rhs}"
        let rhs ← parseSignature view.rhs
        return { view with rhs }

    |

def ashrslt_01_13_exact_after := [llvm|
{
^0(%arg40 : i4):
  %0 = llvm.mlir.constant(-6 : i4) : i4
  %1 = llvm.icmp "slt" %arg40, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

def lshr_and_or_after := [llvm|
{
^0(%arg45 : i8, %arg46 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.mlir.constant(52 : i8) : i8
  %3 = llvm.srem %arg45, %0 : i8
  %4 = llvm.shl %3, %1 : i8
  %5 = llvm.and %arg46, %2 : i8
  %6 = llvm.or %5, %4 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

def test_nsw_and_signed_pred_before := [llvm|
{
^0(%arg56 : i64):
  %0 = llvm.mlir.constant(3) : i64
  %1 = llvm.mlir.constant(10) : i64
  %2 = llvm.sub %0, %arg56 overflow<nsw> : i64
  %3 = llvm.icmp "sgt" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

def udiv2_before := [llvm|
{
^0(%arg30 : i32, %arg31 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.shl %0, %arg31 : i32
  %2 = llvm.udiv exact %arg30, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def masked_bit_set_after := [llvm|
{
^0(%arg83 : i32, %arg84 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.lshr %arg83, %arg84 : i32
  %2 = llvm.and %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

Function.uncurry in Init.Data.Function

def hoist_ashr_ahead_of_sext_1_before := [llvm|
{
^0(%arg3 : i8):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.sext %arg3 : i8 to i32
  %2 = llvm.ashr %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def irc_constants_AMinusC1MinusC2_neg2_1 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (-2) : i64
      %c2 = llvm.mlir.constant (1) : i64
      %0 = llvm.sub %a, %c1 : i64
      %1 = llvm.sub %0, %c2 : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (-2) : i64
      %c2 = llvm.mlir.constant (1) : i64
      %0 = llvm.add %c1, %c2 : i64
      %1 = llvm.sub %a, %0 : i64
      llvm.return %1 : i64
  }]

@[simp_denote]
def sdiv_llvm_no_exact_64 := [LV| {
  ^entry (%x: i64, %y: i64):
    %1 = llvm.sdiv %x, %y : i64
    llvm.return %1 : i64
  }]

def negative_with_uniform_bad_mask_logical_before := [llvm|
{
^0(%arg12 : i32):
  %0 = llvm.mlir.constant(-16777152 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(128 : i32) : i32
  %3 = llvm.mlir.constant(256 : i32) : i32
  %4 = llvm.mlir.constant(false) : i1
  %5 = llvm.and %arg12, %0 : i32
  %6 = llvm.icmp "eq" %5, %1 : i32
  %7 = llvm.add %arg12, %2 : i32
  %8 = llvm.icmp "ult" %7, %3 : i32
  %9 = "llvm.select"(%6, %8, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%9) : (i1) -> ()
}
]

def carry' (initCarry : Bool) (x y : BitStream) : BitStream :=
  fun n =>
  match n with
  | 0 => initCarry
  | n + 1 => (addAux' initCarry x y n).2

def select_lshr_icmp_bad_after := [llvm|
{
^0(%arg48 : i32, %arg49 : i32, %arg50 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.icmp "eq" %arg48, %0 : i32
  %2 = llvm.lshr %arg50, %0 : i32
  %3 = "llvm.select"(%1, %2, %arg49) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def ashrsgt_03_07_before := [llvm|
{
^0(%arg278 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(7 : i4) : i4
  %2 = llvm.ashr %arg278, %0 : i4
  %3 = llvm.icmp "sgt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def shift_xor_multiuse_cmp_with_xor_before := [llvm|
{
^0(%arg80 : i32, %arg81 : i32, %arg82 : i32, %arg83 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(2048 : i32) : i32
  %3 = llvm.and %arg80, %0 : i32
  %4 = llvm.icmp "ne" %1, %3 : i32
  %5 = llvm.xor %arg81, %2 : i32
  %6 = "llvm.select"(%4, %arg81, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg82, %arg83) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %8 = llvm.mul %6, %7 : i32
  "llvm.return"(%8) : (i32) -> ()
}
]

def zero_sign_bit_before := [llvm|
{
^0(%arg31 : i16):
  %0 = llvm.mlir.constant(32767 : i16) : i16
  %1 = llvm.mlir.constant(512 : i16) : i16
  %2 = llvm.and %arg31, %0 : i16
  %3 = llvm.add %2, %1 : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

def sub_shl_same_amount_partial_nsw1_after := [llvm|
{
^0(%arg11 : i6, %arg12 : i6, %arg13 : i6):
  %0 = llvm.sub %arg11, %arg12 : i6
  %1 = llvm.shl %0, %arg13 : i6
  "llvm.return"(%1) : (i6) -> ()
}
]

noncomputable def nonesUntilSome (x : Stream α) (not_stuck : x ≠ stuck α) : Nat :=
  prop.choose
where
  prop : ∃ i, (x.drop i).head.isSome ∧ ∀ j < i, x.get j = none := by admit /- proof elided -/

def test_shift_and_cmp_changed4_after := [llvm|
{
^0(%arg0 : i8):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def lowmask_add_2_before := [llvm|
{
^0(%arg144 : i8):
  %0 = llvm.mlir.constant(-64 : i8) : i8
  %1 = llvm.mlir.constant(63 : i8) : i8
  %2 = llvm.add %arg144, %0 : i8
  %3 = llvm.and %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def test87_before := [llvm|
{
^0(%arg58 : i16):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.sext %arg58 : i16 to i32
  %2 = llvm.mul %1, %0 overflow<nsw> : i32
  %3 = llvm.ashr %2, %0 : i32
  %4 = llvm.trunc %3 : i32 to i16
  "llvm.return"(%4) : (i16) -> ()
}
]

def ashrsgt_03_01_before := [llvm|
{
^0(%arg284 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(1 : i4) : i4
  %2 = llvm.ashr %arg284, %0 : i4
  %3 = llvm.icmp "sgt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def or_and_or_pat8_after := [llvm|
{
^0(%arg10 : i8, %arg11 : i8, %arg12 : i8, %arg13 : i8):
  %0 = llvm.or %arg13, %arg10 : i8
  %1 = llvm.and %0, %arg11 : i8
  %2 = llvm.or %1, %arg12 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def zext_ashr_before := [llvm|
{
^0(%arg11 : i8):
  %0 = llvm.mlir.constant(2 : i16) : i16
  %1 = llvm.zext %arg11 : i8 to i16
  %2 = llvm.ashr %1, %0 : i16
  %3 = llvm.and %2, %1 : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

def test11_after := [llvm|
{
^0(%arg43 : i1):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def tryFactorization_add_mul_nuw_mul_var_after := [llvm|
{
^0(%arg0 : i32, %arg1 : i32, %arg2 : i32):
  %0 = llvm.add %arg1, %arg2 : i32
  %1 = llvm.mul %arg0, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def lshr_shl_pow2_const_overflow_before := [llvm|
{
^0(%arg57 : i16):
  %0 = llvm.mlir.constant(8192 : i16) : i16
  %1 = llvm.mlir.constant(6 : i16) : i16
  %2 = llvm.mlir.constant(32 : i16) : i16
  %3 = llvm.lshr %0, %arg57 : i16
  %4 = llvm.shl %3, %1 : i16
  %5 = llvm.and %4, %2 : i16
  "llvm.return"(%5) : (i16) -> ()
}
]

def icmp_slt_0_and_icmp_ne_neg2_i32_fail_before := [llvm|
{
^0(%arg44 : i32):
  %0 = llvm.mlir.constant(-2 : i32) : i32
  %1 = llvm.mlir.constant(31 : i32) : i32
  %2 = llvm.icmp "ne" %arg44, %0 : i32
  %3 = llvm.zext %2 : i1 to i32
  %4 = llvm.lshr %arg44, %1 : i32
  %5 = llvm.and %4, %3 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def t3_singlebit_before := [llvm|
{
^0(%arg38 : i32, %arg39 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(-16 : i32) : i32
  %2 = llvm.mlir.constant(65536) : i64
  %3 = llvm.mlir.constant(0 : i32) : i32
  %4 = llvm.sub %0, %arg39 : i32
  %5 = llvm.shl %arg38, %4 : i32
  %6 = llvm.add %arg39, %1 : i32
  %7 = llvm.zext %6 : i32 to i64
  %8 = llvm.lshr %2, %7 : i64
  %9 = llvm.trunc %8 : i64 to i32
  %10 = llvm.and %5, %9 : i32
  %11 = llvm.icmp "ne" %10, %3 : i32
  "llvm.return"(%11) : (i1) -> ()
}
]

def n0_after := [llvm|
{
^0(%arg9 : i8, %arg10 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.shl %0, %arg10 overflow<nuw> : i8
  %3 = llvm.xor %2, %1 : i8
  %4 = llvm.icmp "ugt" %arg9, %3 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

def main3d_before := [llvm|
{
^0(%arg143 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(16 : i32) : i32
  %3 = llvm.mlir.constant(1 : i32) : i32
  %4 = llvm.and %arg143, %0 : i32
  %5 = llvm.icmp "ne" %4, %1 : i32
  %6 = llvm.and %arg143, %2 : i32
  %7 = llvm.icmp "eq" %6, %2 : i32
  %8 = llvm.or %5, %7 : i1
  %9 = "llvm.select"(%8, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%9) : (i32) -> ()
}
]

def sge_swap_or_not_max_after := [llvm|
{
^0(%arg312 : i8, %arg313 : i8):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def ashrslt_01_00_exact_after := [llvm|
{
^0(%arg53 : i4):
  %0 = llvm.mlir.constant(0 : i4) : i4
  %1 = llvm.icmp "slt" %arg53, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

def ult_rem_zero_before := [llvm|
{
^0(%arg174 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(21 : i8) : i8
  %2 = llvm.mul %arg174, %0 overflow<nuw> : i8
  %3 = llvm.icmp "ult" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def xor  {Γ : Ctxt _} (e₁ e₂: Ctxt.Var Γ .bv) : Expr RV64 Γ .pure [.bv]  :=
  Expr.mk
    (op := Op.xor)
    (eff_le := by admit /- proof elided -/
    )
    (ty_eq := by admit /- proof elided -/
    )
    (args := .cons e₁ <| .cons e₂ .nil)
    (regArgs := HVector.nil)

def or_shl_after := [llvm|
{
^0(%arg640 : i8, %arg641 : i8, %arg642 : i8, %arg643 : i8):
  %0 = llvm.or %arg640, %arg641 : i8
  %1 = llvm.shl %0, %arg643 : i8
  %2 = llvm.or %1, %arg642 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def foo1_or_signbit_lshr_without_shifting_signbit_both_sides_after := [llvm|
{
^0(%arg100 : i32, %arg101 : i32, %arg102 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.shl %arg100, %arg101 : i32
  %2 = llvm.shl %arg100, %arg102 : i32
  %3 = llvm.and %1, %2 : i32
  %4 = llvm.icmp "slt" %3, %0 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def src_x_and_nmask_slt_before := [llvm|
{
^0(%arg19 : i8, %arg20 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.shl %0, %arg20 : i8
  %2 = llvm.and %arg19, %1 : i8
  %3 = llvm.icmp "slt" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def testi16i8_before := [llvm|
{
^0(%arg9 : i16):
  %0 = llvm.mlir.constant(15 : i16) : i16
  %1 = llvm.mlir.constant(27 : i8) : i8
  %2 = llvm.ashr %arg9, %0 : i16
  %3 = llvm.trunc %2 : i16 to i8
  %4 = llvm.xor %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def or_and_not_not_wrong_b_before := [llvm|
{
^0(%arg378 : i32, %arg379 : i32, %arg380 : i32, %arg381 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg381, %arg378 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.or %arg378, %arg380 : i32
  %4 = llvm.xor %3, %0 : i32
  %5 = llvm.and %4, %arg379 : i32
  %6 = llvm.or %5, %2 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

instance : Inhabited (Ctxt Ty) := ⟨Ctxt.empty⟩

Std.Tactic.BVDecide.BVLogicalExpr in Std.Tactic.BVDecide.Bitblast.BVExpr.Basic

def masked_icmps_mask_notallzeros_bmask_mixed_swapped_0_logical_before := [llvm|
{
^0(%arg51 : i32):
  %0 = llvm.mlir.constant(12 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(3 : i32) : i32
  %3 = llvm.mlir.constant(1 : i32) : i32
  %4 = llvm.mlir.constant(false) : i1
  %5 = llvm.and %arg51, %0 : i32
  %6 = llvm.icmp "ne" %5, %1 : i32
  %7 = llvm.and %arg51, %2 : i32
  %8 = llvm.icmp "eq" %7, %3 : i32
  %9 = "llvm.select"(%8, %6, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%9) : (i1) -> ()
}
]

def add_nsw_poison_constant_fold_after := [llvm|
{
^0(%arg2 : i1, %arg3 : i8):
  %0 = llvm.mlir.constant(64 : i8) : i8
  %1 = llvm.mlir.constant(-127 : i8) : i8
  %2 = llvm.add %arg3, %0 overflow<nsw> : i8
  %3 = "llvm.select"(%arg2, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def bools2_logical_commute0_and2_before := [llvm|
{
^0(%arg58 : i1, %arg59 : i1, %arg60 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.xor %arg60, %0 : i1
  %3 = "llvm.select"(%arg60, %arg58, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = llvm.and %2, %arg59 : i1
  %5 = "llvm.select"(%3, %0, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def test29_after := [llvm|
{
^0(%arg260 : i8):
  %0 = llvm.zext %arg260 : i8 to i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def test9_after := [llvm|
{
^0(%arg15 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.icmp "ult" %arg15, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

def combined_sdiv_srem_correct := [LV| {
  ^entry (%a: i64, %b: i64):
    %0= llvm.sdiv %a, %b : i64
    %1 = llvm.mul %b, %0 : i64
    %2 = llvm.sub %a, %1 : i64
    llvm.return %2 : i64
  }]

def t5_ugt_slt_0_after := [llvm|
{
^0(%arg51 : i32, %arg52 : i32, %arg53 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(65535 : i32) : i32
  %2 = llvm.icmp "slt" %arg51, %0 : i32
  %3 = llvm.icmp "sgt" %arg51, %1 : i32
  %4 = "llvm.select"(%2, %arg52, %arg51) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %5 = "llvm.select"(%3, %arg53, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def ashr_mul_sign_bits_after := [llvm|
{
^0(%arg101 : i8, %arg102 : i8):
  %0 = llvm.mlir.constant(3 : i16) : i16
  %1 = llvm.sext %arg101 : i8 to i16
  %2 = llvm.sext %arg102 : i8 to i16
  %3 = llvm.mul %1, %2 overflow<nsw> : i16
  %4 = llvm.ashr %3, %0 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

def ashr_xor_before := [llvm|
{
^0(%arg20 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.mlir.constant(-64 : i8) : i8
  %3 = llvm.ashr %0, %arg20 : i8
  %4 = llvm.add %arg20, %1 : i8
  %5 = llvm.ashr %2, %4 : i8
  %6 = llvm.xor %3, %5 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

def mkOutputAssignCircuitLeN {arity : Type _}
  [DecidableEq arity]
  [Fintype arity]
  [Hashable arity]
  (p : FSM arity) (n : Nat) :
  Circuit (Vars p.α arity (n + 1)) :=
    let ixs := List.range (n + 1) |>.attach
    let circs := ixs.map fun ⟨i, hi⟩ =>
      mkOutputAssignCircuitN p i |>.map (fun v => v.castLe (by admit /- proof elided -/
      ))
    Circuit.bigOr circs

def exampleSink := [DCxComb_com| {
  ^entry(%0: !TokenStream):
    %src = "DCxComb.sink" (%0) : (!TokenStream) -> (!TokenStream)
    "return" (%src) : (!TokenStream) -> ()
  }]

def uadd_sat_flipped_wrong_bounds6_before := [llvm|
{
^0(%arg91 : i32):
  %0 = llvm.mlir.constant(-12 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.mlir.constant(-1 : i32) : i32
  %3 = llvm.icmp "ule" %arg91, %0 : i32
  %4 = llvm.add %arg91, %1 : i32
  %5 = "llvm.select"(%3, %4, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

Polynomial.natDegree in Mathlib.Algebra.Polynomial.Degree.Definitions

def eq_smax3_after := [llvm|
{
^0(%arg59 : i32, %arg60 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg59, %0 : i32
  %2 = llvm.icmp "sge" %1, %arg60 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def icmp_sge_riscv_eq_icmp_sge_llvm_32 : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] :=
  {lhs:= icmp_sge_llvm_32, rhs:= icmp_sge_riscv_32}

def main5c_like_logical_before := [llvm|
{
^0(%arg101 : i32, %arg102 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.mlir.constant(1 : i32) : i32
  %4 = llvm.and %arg101, %0 : i32
  %5 = llvm.icmp "ne" %4, %0 : i32
  %6 = llvm.and %arg102, %0 : i32
  %7 = llvm.icmp "ne" %6, %0 : i32
  %8 = "llvm.select"(%5, %1, %7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %9 = "llvm.select"(%8, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%9) : (i32) -> ()
}
]

@[simp_denote]
def select {Γ : Ctxt _} (w : ℕ) (l m r : Nat)
    (lp : (Γ[l]? = some (InstCombine.MTy.bitvec (ConcreteOrMVar.concrete 1)))
      := by admit /- proof elided -/
      )
    (mp : (Γ[m]? = some (InstCombine.MTy.bitvec (ConcreteOrMVar.concrete w)))
      := by admit /- proof elided -/
      )
    (rp : (Γ[r]? = some (InstCombine.MTy.bitvec (ConcreteOrMVar.concrete w)))
      := by admit /- proof elided -/
      ) :
    Expr InstCombine.LLVM Γ .pure (LLVM.Ty.bitvec w)  :=
  Expr.mk
    (op := InstCombine.MOp.select w)
    (eff_le := by admit /- proof elided -/
    )
    (ty_eq := rfl)
    (args := .cons ⟨l, lp⟩ <| .cons ⟨m, mp⟩ <| .cons ⟨r, rp⟩ .nil)
    (regArgs := .nil)

def negate_select_of_op_vs_negated_op_nsw_after := [llvm|
{
^0(%arg21 : i8, %arg22 : i8, %arg23 : i1):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.sub %0, %arg21 : i8
  %2 = "llvm.select"(%arg23, %arg21, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %3 = llvm.add %2, %arg22 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def t4_commutative_after := [llvm|
{
^0(%arg22 : i8, %arg23 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.xor %arg23, %0 : i8
  %2 = llvm.icmp "ugt" %arg22, %1 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def and_two_ranges_to_mask_and_range_no_add_on_one_range_before := [llvm|
{
^0(%arg249 : i16):
  %0 = llvm.mlir.constant(12 : i16) : i16
  %1 = llvm.mlir.constant(16 : i16) : i16
  %2 = llvm.mlir.constant(28 : i16) : i16
  %3 = llvm.icmp "uge" %arg249, %0 : i16
  %4 = llvm.icmp "ult" %arg249, %1 : i16
  %5 = llvm.icmp "uge" %arg249, %2 : i16
  %6 = llvm.or %4, %5 : i1
  %7 = llvm.and %3, %6 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

def or_signbit_select_shl_before := [llvm|
{
^0(%arg42 : i32, %arg43 : i1):
  %0 = llvm.mlir.constant(-65536 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.or %arg42, %0 : i32
  %3 = "llvm.select"(%arg43, %2, %arg42) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.shl %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

@[simp_denote] def RegionRet (t : Arith.Ty) {Γ : Ctxt Arith.Ty} (v : Var Γ t) :
    Com ScfArith Γ .impure t := .ret v

def ashr_xor_before := [llvm|
{
^0(%arg46 : i32, %arg47 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(5 : i32) : i32
  %2 = llvm.mlir.constant(7 : i32) : i32
  %3 = llvm.srem %arg47, %0 : i32
  %4 = llvm.ashr %arg46, %1 : i32
  %5 = llvm.xor %3, %4 : i32
  %6 = llvm.ashr %5, %2 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def and_slt_to_mask_before := [llvm|
{
^0(%arg5 : i8):
  %0 = llvm.mlir.constant(-124 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.icmp "slt" %arg5, %0 : i8
  %4 = llvm.and %arg5, %1 : i8
  %5 = llvm.icmp "eq" %4, %2 : i8
  %6 = llvm.and %3, %5 : i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def shl_add_lshr_flag_preservation_before := [llvm|
{
^0(%arg157 : i32, %arg158 : i32, %arg159 : i32):
  %0 = llvm.shl %arg157, %arg158 overflow<nuw> : i32
  %1 = llvm.add %0, %arg159 overflow<nsw,nuw> : i32
  %2 = llvm.lshr exact %1, %arg158 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def test_zext_nneg_after := [llvm|
{
^0(%arg25 : i32, %arg26 : i64, %arg27 : i64):
  %0 = llvm.mlir.constant(-4) : i64
  %1 = llvm.add %arg26, %0 : i64
  %2 = llvm.sext %arg25 : i32 to i64
  %3 = llvm.sub %2, %arg27 : i64
  %4 = llvm.add %1, %3 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

private def levelParamsToMessageData (levelParams : List Name) : MessageData :=
  match levelParams with
  | []    => ""
  | u::us => Id.run do
    let mut m := m!".\{{u}"
    for u in us do
      m := m ++ ", " ++ toMessageData u
    return m ++ "}"

def select_sub_icmp_after := [llvm|
{
^0(%arg214 : i32, %arg215 : i32, %arg216 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "eq" %arg214, %0 : i32
  %2 = "llvm.select"(%1, %arg216, %arg215) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def test19_after := [llvm|
{
^0(%arg7 : i10):
  %0 = llvm.mlir.constant(1 : i3) : i3
  %1 = llvm.mlir.constant(0 : i3) : i3
  %2 = llvm.trunc %arg7 : i10 to i3
  %3 = llvm.and %2, %0 : i3
  %4 = llvm.sub %1, %3 overflow<nsw> : i3
  %5 = llvm.sext %4 : i3 to i10
  "llvm.return"(%5) : (i10) -> ()
}
]

def test1_after := [llvm|
{
^0(%arg14 : i32, %arg15 : i32):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

BitVec.extractLsb in Init.Data.BitVec.Basic

def and_logic_and_logic_or_8_before := [llvm|
{
^0(%arg117 : i1, %arg118 : i1, %arg119 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.and %arg118, %arg117 : i1
  %3 = "llvm.select"(%arg119, %arg117, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = "llvm.select"(%3, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def and_zext_eq_even_after := [llvm|
{
^0(%arg33 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def sub_select_not_sext_before := [llvm|
{
^0(%arg20 : i1, %arg21 : i64):
  %0 = llvm.mlir.constant(64) : i64
  %1 = llvm.mlir.constant(true) : i1
  %2 = "llvm.select"(%arg20, %arg21, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  %3 = llvm.xor %arg20, %1 : i1
  %4 = llvm.sext %3 : i1 to i64
  %5 = llvm.sub %2, %4 : i64
  "llvm.return"(%5) : (i64) -> ()
}
]

def or_or_logic_and_2_after := [llvm|
{
^0(%arg9 : i1, %arg10 : i1, %arg11 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = "llvm.select"(%arg11, %arg10, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %2 = llvm.or %arg9, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

elab "[handshake_com| " reg:mlir_region "]" : term => do SSA.elabIntoCom' reg Handshake

def exact_lshr_ne_both_equal_after := [llvm|
{
^0(%arg165 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "ne" %arg165, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def two_inst_com_proof (w : Nat) :
    two_inst_com w ⊑ two_inst_com w :=

def no_masks_with_logical_or2_after := [llvm|
{
^0(%arg7 : i32, %arg8 : i32, %arg9 : i32):
  %0 = llvm.mlir.constant(63 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.icmp "ne" %arg8, %0 : i32
  %4 = llvm.and %arg7, %arg9 : i32
  %5 = llvm.icmp "ne" %4, %1 : i32
  %6 = "llvm.select"(%5, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def IntToString (i: Int): String := i.repr

def fold_select_trunc_nsw_true_before := [llvm|
{
^0(%arg6 : i128, %arg7 : i128):
  %0 = llvm.trunc %arg6 overflow<nsw> : i128 to i1
  %1 = "llvm.select"(%0, %arg6, %arg7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i128, i128) -> i128
  "llvm.return"(%1) : (i128) -> ()
}
]

def or_before := [llvm|
{
^0(%arg678 : i64, %arg679 : i64):
  %0 = llvm.and %arg679, %arg678 : i64
  %1 = llvm.xor %arg679, %arg678 : i64
  %2 = llvm.add %0, %1 : i64
  "llvm.return"(%2) : (i64) -> ()
}
]

def select_icmp_ne_0_and_32_xor_4096_after := [llvm|
{
^0(%arg199 : i32, %arg200 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(4096 : i32) : i32
  %2 = llvm.shl %arg199, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.xor %3, %arg200 : i32
  %5 = llvm.xor %4, %1 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def c0_after := [llvm|
{
^0(%arg7 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "slt" %arg7, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def lt_signed_to_small_negative_before := [llvm|
{
^0(%arg48 : i8):
  %0 = llvm.mlir.constant(-17 : i32) : i32
  %1 = llvm.sext %arg48 : i8 to i32
  %2 = llvm.icmp "slt" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def sge_smin1_before := [llvm|
{
^0(%arg79 : i32, %arg80 : i32):
  %0 = llvm.icmp "slt" %arg79, %arg80 : i32
  %1 = "llvm.select"(%0, %arg79, %arg80) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %2 = llvm.icmp "sge" %1, %arg79 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def lshrult_02_14_before := [llvm|
{
^0(%arg337 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.mlir.constant(-2 : i4) : i4
  %2 = llvm.lshr %arg337, %0 : i4
  %3 = llvm.icmp "ult" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def icmp_ne_zext_eq_zero_before := [llvm|
{
^0(%arg42 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "eq" %arg42, %0 : i32
  %2 = llvm.zext %1 : i1 to i32
  %3 = llvm.icmp "ne" %2, %arg42 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def ashrslt_03_05_exact_after := [llvm|
{
^0(%arg16 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def ExplicitISL : Dialect where
  Op := ISLOp
  Ty := ExpTy
  m := Id 

def negate_add_with_single_negatible_operand_depth2_after := [llvm|
{
^0(%arg21 : i8, %arg22 : i8):
  %0 = llvm.mlir.constant(-21 : i8) : i8
  %1 = llvm.sub %0, %arg21 : i8
  %2 = llvm.mul %1, %arg22 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def select_xor_icmp_bad_6_after := [llvm|
{
^0(%arg169 : i32, %arg170 : i32, %arg171 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.icmp "eq" %arg169, %0 : i32
  %2 = llvm.xor %arg171, %0 : i32
  %3 = "llvm.select"(%1, %2, %arg170) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def OrZextOr_before := [llvm|
{
^0(%arg4 : i3):
  %0 = llvm.mlir.constant(3 : i3) : i3
  %1 = llvm.mlir.constant(8 : i5) : i5
  %2 = llvm.or %arg4, %0 : i3
  %3 = llvm.zext %2 : i3 to i5
  %4 = llvm.or %3, %1 : i5
  "llvm.return"(%4) : (i5) -> ()
}
]

def size : FpPredicate → Nat
| .bin lhs _ rhs => 1 + lhs.size + rhs.size

def icmp_ne_zext_ne_non_boolean_after := [llvm|
{
^0(%arg33 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.icmp "ne" %arg33, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

structure Item where
 name : String
 tac : Syntax

def alive_InstCombineShift__279_src :=
[sllvm| {
^bb0(%X : i64, %C : i64):
  %v1 = llvm.lshr %X, %C : i64
  %v2 = llvm.shl %v1, %C : i64
  llvm.return %v2 : i64
}]

def main4e_like_logical_before := [llvm|
{
^0(%arg125 : i32, %arg126 : i32, %arg127 : i32):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.and %arg125, %arg126 : i32
  %4 = llvm.icmp "eq" %3, %arg126 : i32
  %5 = llvm.and %arg125, %arg127 : i32
  %6 = llvm.icmp "eq" %5, %arg127 : i32
  %7 = "llvm.select"(%4, %6, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %8 = "llvm.select"(%7, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%8) : (i32) -> ()
}
]

@[simp_denote]
def icmp_ule_llvm_32 : Com LLVMPlusRiscV ⟨[.llvm (.bitvec 32), .llvm (.bitvec 32)]⟩
  .pure (.llvm (.bitvec 1)) := [LV| {
  ^entry (%lhs: i32, %rhs: i32):
    %1 = llvm.icmp.ule %lhs, %rhs : i32
    llvm.return %1 : i1
  }]

def ashrslt_01_07_before := [llvm|
{
^0(%arg262 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(7 : i4) : i4
  %2 = llvm.ashr %arg262, %0 : i4
  %3 = llvm.icmp "slt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def masked_icmps_mask_notallzeros_bmask_mixed_negated_4_after := [llvm|
{
^0(%arg62 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.and %arg62, %0 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def GLobalISelO0PreLegalizerCombiner :
    List (Σ Γ, Σ ty, PeepholeRewrite LLVMPlusRiscV Γ ty) :=
  (List.map (fun ⟨_,y⟩ => mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND y))
  not_cmp_fold)
  ++
  (List.map (fun ⟨_,y⟩ => mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND y))
  double_icmp_zero_combine)
  ++
  (List.map (fun ⟨_,y⟩ => mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND y))
   mul_by_neg_one)
  ++
  (List.map (fun ⟨_,y⟩ => mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND y))
    sub_to_add)
  ++
  (List.map (fun ⟨_,y⟩ => mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND y))
  mul_to_shl)
  ++
  (List.map (fun ⟨_,y⟩ => mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND y))
  udiv_pow2)

def trunc_lshr_trunc_before := [llvm|
{
^0(%arg14 : i64):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.trunc %arg14 : i64 to i32
  %2 = llvm.lshr %1, %0 : i32
  %3 = llvm.trunc %2 : i32 to i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def narrow_sext_and_before := [llvm|
{
^0(%arg56 : i16, %arg57 : i32):
  %0 = llvm.sext %arg56 : i16 to i32
  %1 = llvm.and %0, %arg57 : i32
  %2 = llvm.trunc %1 : i32 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

def or_xor_commute3_before := [llvm|
{
^0(%arg162 : i32, %arg163 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.udiv %0, %arg162 : i32
  %2 = llvm.udiv %0, %arg163 : i32
  %3 = llvm.or %2, %1 : i32
  %4 = llvm.xor %3, %2 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def shl_add_nuw_before := [llvm|
{
^0(%arg69 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.mlir.constant(6 : i32) : i32
  %2 = llvm.add %arg69, %0 overflow<nuw> : i32
  %3 = llvm.shl %1, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def ashr_overshift_before := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(17 : i32) : i32
  %2 = llvm.ashr %arg6, %0 : i32
  %3 = llvm.ashr %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def test1_after := [llvm|
{
^0(%arg26 : i23):
  %0 = llvm.mlir.constant(0 : i23) : i23
  "llvm.return"(%0) : (i23) -> ()
}
]

def test_sext1_after := [llvm|
{
^0(%arg49 : i1, %arg50 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = "llvm.select"(%arg50, %arg49, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %2 = llvm.sext %1 : i1 to i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def dcAdd := [DCxComb_com| {
  ^entry(%a: !ValueStream_32, %b: !ValueStream_32):
    %unpacka = "DCxComb.unpack" (%a) : (!ValueStream_32) -> (!ValueTokenStream_32)
    
    %output = "DCxComb.fstVal" (%unpacka) : (!ValueTokenStream_32) -> (!ValueStream_32)
    %token = "DCxComb.sndVal" (%unpacka) : (!ValueTokenStream_32) -> (!TokenStream)
    %output1 = "DCxComb.fstVal" (%unpacka) : (!ValueTokenStream_32) -> (!ValueStream_32)
    %token0 = "DCxComb.sndVal" (%unpacka) : (!ValueTokenStream_32) -> (!TokenStream)
    %0 = "DCxComb.join" (%token, %token0) : (!TokenStream, !TokenStream) -> (!TokenStream)
    %1 = "DCxComb.add" (%output, %output1) : (!ValueStream_32, !ValueStream_32) -> (!ValueStream_32)
    
    %2 = "DCxComb.pack" (%1, %0) : (!ValueStream_32, !TokenStream) -> (!ValueStream_32)
    %unpack2 = "DCxComb.unpack" (%2) : (!ValueStream_32) -> (!ValueTokenStream_32)
    %output3 = "DCxComb.fstVal" (%unpack2) : (!ValueTokenStream_32) -> (!ValueStream_32)
    %token2 = "DCxComb.sndVal" (%unpack2) : (!ValueTokenStream_32) -> (!TokenStream)
    %unpackb = "DCxComb.unpack" (%b) : (!ValueStream_32) -> (!ValueTokenStream_32)
    %output5 = "DCxComb.fstVal" (%unpackb) : (!ValueTokenStream_32) -> (!ValueStream_32)
    %token4 = "DCxComb.sndVal" (%unpackb) : (!ValueTokenStream_32) -> (!TokenStream)
    %3 = "DCxComb.join" (%token2, %token4) : (!TokenStream, !TokenStream) -> (!TokenStream)
    %4 = "DCxComb.pack" (%output3, %3) : (!ValueStream_32, !TokenStream) -> (!ValueStream_32)
    %5 = "DCxComb.pack" (%output5, %3) : (!ValueStream_32, !TokenStream) -> (!ValueStream_32)
    %unpack5 = "DCxComb.unpack" (%5) : (!ValueStream_32) -> (!ValueTokenStream_32)
    %output7 = "DCxComb.fstVal" (%unpack5) : (!ValueTokenStream_32) -> (!ValueStream_32)
    %token6 = "DCxComb.sndVal" (%unpack5) : (!ValueTokenStream_32) -> (!TokenStream)
    %unpackabis = "DCxComb.unpack" (%a) : (!ValueStream_32) -> (!ValueTokenStream_32)
    %output9 = "DCxComb.fstVal" (%unpackabis) : (!ValueTokenStream_32) -> (!ValueStream_32)
    %token8 = "DCxComb.sndVal" (%unpackabis) : (!ValueTokenStream_32) -> (!TokenStream)
    %6 = "DCxComb.join" (%token6, %token8) : (!TokenStream, !TokenStream) -> (!TokenStream)
    %7 = "DCxComb.add" (%output7, %output9) : (!ValueStream_32, !ValueStream_32) -> (!ValueStream_32)
    %8 = "DCxComb.pack" (%7, %6) : (!ValueStream_32, !TokenStream) -> (!ValueStream_32)
    "return" (%8) : (!ValueStream_32) -> ()
  }]

instance : EmptyCollection MedusaSynthGeneralizeConfig where
  emptyCollection := {}

declare_config_elab elabMedusaSynthGeneralizeConfig MedusaSynthGeneralizeConfig

def and_or_not_not_commute4_after := [llvm|
{
^0(%arg363 : i32, %arg364 : i32, %arg365 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg365, %arg364 : i32
  %2 = llvm.and %1, %arg363 : i32
  %3 = llvm.xor %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def add_nsw_after := [llvm|
{
^0(%arg0 : i1, %arg1 : i8):
  %0 = llvm.mlir.constant(64 : i8) : i8
  %1 = llvm.mlir.constant(71 : i8) : i8
  %2 = llvm.add %arg1, %0 overflow<nsw> : i8
  %3 = "llvm.select"(%arg0, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%3) : (i8) -> ()
}
]

instance : HydrablePackedBitvecToSubstitutionValue FpPredicate FpExpr where
  packedBitVecToSubstitutionValue := packedBitVecToFpSubstitutionValue

RV64.sllw in RISCV.Instructions

def Expr.op : Expr Op T → Op
  | ⟨_, op, _, _⟩ => op

def factorize4_after := [llvm|
{
^0(%arg3 : i32, %arg4 : i32):
  %0 = llvm.mul %arg4, %arg3 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def alive_AndOrXor_2627_tgt  (w : Nat)  :=
[llvm( w )| {
^bb0(%a : _, %c : _, %b : _):
  %v1 = llvm.mlir.constant -1
  %v2 = llvm.xor %a, %v1
  %v3 = llvm.and %v2, %b
  %v4 = llvm.xor %a, %c
  %v5 = llvm.or %a, %b
  %v6 = llvm.xor %v3, %c
  llvm.return %v6
}]

@[simp] def evalv [DecidableEq α] : ∀ (c : Circuit α), (∀ a ∈ vars c, Bool) → Bool
  | tru, _ => true
  | fals, _ => false
  | var b x, f => if b then f x (by admit /- proof elided -/
  ) else !(f x (by admit /- proof elided -/
  ))
  | and c₁ c₂, f => (evalv c₁ (fun i hi => f i (by admit /- proof elided -/
  ))) &&
    (evalv c₂ (fun i hi => f i (by admit /- proof elided -/
    )))
  | or c₁ c₂, f => (evalv c₁ (fun i hi => f i (by admit /- proof elided -/
  ))) ||
    (evalv c₂ (fun i hi => f i (by admit /- proof elided -/
    )))
  | xor c₁ c₂, f => Bool.xor (evalv c₁ (fun i hi => f i (by admit /- proof elided -/
  )))
    (evalv c₂ (fun i hi => f i (by admit /- proof elided -/
    )))

def select_add_after := [llvm|
{
^0(%arg15 : i1, %arg16 : i64, %arg17 : i64):
  %0 = llvm.mlir.constant(0) : i64
  %1 = "llvm.select"(%arg15, %arg17, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  %2 = llvm.add %arg16, %1 : i64
  "llvm.return"(%2) : (i64) -> ()
}
]

def mul_constant_eq_before := [llvm|
{
^0(%arg140 : i32, %arg141 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.mul %arg140, %0 : i32
  %2 = llvm.mul %arg141, %0 : i32
  %3 = llvm.icmp "eq" %1, %2 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def n12_before := [llvm|
{
^0(%arg0 : i8, %arg1 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.sub %0, %arg0 overflow<nsw> : i8
  %2 = llvm.icmp "sgt" %1, %arg1 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def andn_or_cmp_2_logical_after := [llvm|
{
^0(%arg120 : i16, %arg121 : i16, %arg122 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.icmp "slt" %arg120, %arg121 : i16
  %2 = "llvm.select"(%arg122, %1, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%2) : (i1) -> ()
}
]

private def mkElab (ext : NameExt) (ty : Lean.Expr) : Elab.Term.TermElabM Lean.Expr := do
  let mut stx := #[]
  for (_, n4) in ext.getState (← getEnv) do
    stx := stx.push $ ← `($(mkIdent n4):ident)
  let listStx := (← `([$stx,*]))
  let list ← `($listStx)
  Elab.Term.elabTerm list (some ty)

def lshrugt_02_05_exact_before := [llvm|
{
^0(%arg200 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.mlir.constant(5 : i4) : i4
  %2 = llvm.lshr exact %arg200, %0 : i4
  %3 = llvm.icmp "ugt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def exact_ashr_eq_both_equal_before := [llvm|
{
^0(%arg168 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.ashr exact %0, %arg168 : i8
  %2 = llvm.icmp "eq" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def samesign_inverted_commute3_before := [llvm|
{
^0(%arg97 : i32, %arg98 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg97, %arg98 : i32
  %3 = llvm.icmp "sgt" %2, %0 : i32
  %4 = llvm.or %arg98, %arg97 : i32
  %5 = llvm.icmp "slt" %4, %1 : i32
  %6 = llvm.and %5, %3 : i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def sgt_negative_multip_rem_zero_after := [llvm|
{
^0(%arg169 : i8):
  %0 = llvm.mlir.constant(-3 : i8) : i8
  %1 = llvm.icmp "slt" %arg169, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def test24_logical_before := [llvm|
{
^0(%arg272 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.icmp "sgt" %arg272, %0 : i32
  %4 = llvm.icmp "ne" %arg272, %1 : i32
  %5 = "llvm.select"(%3, %4, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def t2_commutative_before := [llvm|
{
^0(%arg20 : i8, %arg21 : i8):
  %0 = llvm.sub %arg20, %arg21 : i8
  %1 = llvm.icmp "uge" %arg20, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

instance [Ring α] : Ring (Holor α ds) :=

def max_of_min_swap_after := [llvm|
{
^0(%arg21 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def PR75692_1_after := [llvm|
{
^0(%arg3 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def sle_swap_or_not_min_logical_after := [llvm|
{
^0(%arg278 : i8, %arg279 : i8):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def mul_of_udiv_fail_bad_remainder_before := [llvm|
{
^0(%arg2 : i8):
  %0 = llvm.mlir.constant(11 : i8) : i8
  %1 = llvm.mlir.constant(6 : i8) : i8
  %2 = llvm.udiv exact %arg2, %0 : i8
  %3 = llvm.mul %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def lshrugt_03_04_exact_after := [llvm|
{
^0(%arg185 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def test13_before := [llvm|
{
^0(%arg44 : i32, %arg45 : i32):
  %0 = llvm.mlir.constant(-1431655767 : i32) : i32
  %1 = llvm.mlir.constant(1431655766 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.or %arg44, %0 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.add %arg45, %2 : i32
  %6 = llvm.add %5, %4 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def ashrslt_03_06_exact_after := [llvm|
{
^0(%arg15 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def liRiscv34 := [LV| {
  ^entry ():
    %0 = "li"() {imm = 34 : !i64} : (!i64) -> (!i64)
    %1 = "builtin.unrealized_conversion_cast"(%0) : (!i64) -> (i64)
    llvm.return %1 : i64
  }]

def select_mul_icmp_bad_after := [llvm|
{
^0(%arg158 : i32, %arg159 : i32, %arg160 : i32, %arg161 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.icmp "eq" %arg158, %0 : i32
  %2 = llvm.mul %arg160, %0 : i32
  %3 = "llvm.select"(%1, %2, %arg159) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def lshr_not_nneg2_after := [llvm|
{
^0(%arg20 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(-128 : i8) : i8
  %2 = llvm.lshr %arg20, %0 : i8
  %3 = llvm.or disjoint %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def fold_sext_to_and1_after := [llvm|
{
^0(%arg16 : i8):
  %0 = llvm.mlir.constant(-127 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.and %arg16, %0 : i8
  %3 = llvm.icmp "ne" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def ashr_ule_exact_after := [llvm|
{
^0(%arg168 : i8):
  %0 = llvm.mlir.constant(88 : i8) : i8
  %1 = llvm.icmp "ult" %arg168, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def zext_nneg_sext_sle_op0_narrow_before := [llvm|
{
^0(%arg50 : i8, %arg51 : i16):
  %0 = llvm.zext nneg %arg50 : i8 to i32
  %1 = llvm.sext %arg51 : i16 to i32
  %2 = llvm.icmp "sle" %0, %1 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

@[simp_denote]
def icmp_ult_riscv_32 := [LV| {
  ^entry (%lhs: i32, %rhs: i32 ):
    %lhsr = "builtin.unrealized_conversion_cast"(%lhs) : (i32) -> (!i64)
    %rhsr = "builtin.unrealized_conversion_cast"(%rhs) : (i32) -> (!i64)
    %0 = sltu %lhsr, %rhsr : !i64
    %1 = "builtin.unrealized_conversion_cast"(%0) : (!i64) -> (i1)
    llvm.return %1 : i1
  }]

def trunc_equality_nsw_zext_after := [llvm|
{
^0(%arg16 : i32, %arg17 : i8):
  %0 = llvm.zext %arg17 : i8 to i32
  %1 = llvm.icmp "ne" %arg16, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

def lshrult_03_05_exact_after := [llvm|
{
^0(%arg112 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def substitute_constant_and_eq_eq_commute_logical_before := [llvm|
{
^0(%arg316 : i8, %arg317 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "eq" %arg316, %0 : i8
  %3 = llvm.icmp "eq" %arg316, %arg317 : i8
  %4 = "llvm.select"(%3, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def llvm_const_lower_riscv_li_21 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_21, rhs:= liRiscv_21,
   correct := by admit /- proof elided -/

def visitSUB_APlusBNegCNegB : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%a: i64, %b: i64, %c: i64):
      %0 = llvm.sub %b, %c : i64
      %1 = llvm.add %a, %0 : i64
      %2 = llvm.sub %1, %b : i64
      llvm.return %2 : i64
  }]
  rhs := [LV| {
    ^entry (%a: i64, %b: i64, %c: i64):
      %0 = llvm.sub %a, %c : i64
      llvm.return %0 : i64
  }]

def mul_of_bools_before := [llvm|
{
^0(%arg91 : i32, %arg92 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.and %arg91, %0 : i32
  %3 = llvm.and %arg92, %0 : i32
  %4 = llvm.mul %2, %3 : i32
  %5 = llvm.icmp "ult" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

def test5_after := [llvm|
{
^0(%arg205 : i32):
  %0 = llvm.mlir.constant(-124 : i32) : i32
  %1 = llvm.and %arg205, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def zext? {w: Nat} (w': Nat) (x: BitVec w) : IntW w' := do
  .value <| (BitVec.zeroExtend w' x)

def ugt_rem_zero_after := [llvm|
{
^0(%arg167 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.icmp "ugt" %arg167, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def or_nosignbit_select_shl_after := [llvm|
{
^0(%arg40 : i32, %arg41 : i1):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(-16777216 : i32) : i32
  %2 = llvm.shl %arg40, %0 : i32
  %3 = llvm.or %2, %1 : i32
  %4 = "llvm.select"(%arg41, %3, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def nestedAttrDict0 : AttrDict 0 := [mlir_attr_dict| {foo = {bar = "baz"} }]

def or_not_and_wrong_c_after := [llvm|
{
^0(%arg488 : i32, %arg489 : i32, %arg490 : i32, %arg491 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg488, %arg489 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.and %arg490, %2 : i32
  %4 = llvm.or %arg488, %arg491 : i32
  %5 = llvm.xor %4, %0 : i32
  %6 = llvm.and %arg489, %5 : i32
  %7 = llvm.or %3, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def llvm_mul_lower_riscv_nsw_flag_32 : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := mul_llvm_nsw_32
  rhs := mul_riscv_32

def ult_1_impliesF_eq_1_after := [llvm|
{
^0(%arg3 : i8, %arg4 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "ne" %arg3, %0 : i8
  %3 = llvm.icmp "eq" %arg4, %arg3 : i8
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def sdiv_exact_ne_1_after := [llvm|
{
^0(%arg12 : i8, %arg13 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "eq" %arg12, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def trunc_shl_zext_32_before := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(4 : i16) : i16
  %1 = llvm.trunc %arg1 : i32 to i16
  %2 = llvm.shl %1, %0 : i16
  %3 = llvm.zext %2 : i16 to i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def select_or_disjoint_or_before := [llvm|
{
^0(%arg14 : i32, %arg15 : i1):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(4 : i32) : i32
  %2 = "llvm.select"(%arg15, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %3 = llvm.shl %arg14, %1 : i32
  %4 = llvm.or disjoint %2, %3 : i32
  %5 = llvm.add %4, %1 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def test_sub_nsw__all_are_safe_after := [llvm|
{
^0(%arg29 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.mlir.constant(-254 : i32) : i32
  %2 = llvm.and %arg29, %0 : i32
  %3 = llvm.sub %1, %2 overflow<nsw,nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def ugt_umax4_before := [llvm|
{
^0(%arg30 : i32, %arg31 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg30, %0 : i32
  %2 = llvm.icmp "ugt" %arg31, %1 : i32
  %3 = "llvm.select"(%2, %arg31, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.icmp "ult" %1, %3 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def CollectState.icard (state : CollectState) : Nat :=
  state.iToIx.size

def main6b_after := [llvm|
{
^0(%arg92 : i32):
  %0 = llvm.mlir.constant(23 : i32) : i32
  %1 = llvm.mlir.constant(19 : i32) : i32
  %2 = llvm.and %arg92, %0 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  %4 = llvm.zext %3 : i1 to i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def test35_with_trunc_after := [llvm|
{
^0(%arg48 : i64):
  %0 = llvm.mlir.constant(2147483648) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.mlir.constant(60 : i32) : i32
  %3 = llvm.mlir.constant(100 : i32) : i32
  %4 = llvm.and %arg48, %0 : i64
  %5 = llvm.icmp "eq" %4, %1 : i64
  %6 = "llvm.select"(%5, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def select_riscv_select_llvm_32 : LLVMPeepholeRewriteRefine 32
  [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 1)] where
  lhs := select_llvm_32
  rhs := select_riscv_32

def demorgan_nand_before := [llvm|
{
^0(%arg38 : i8, %arg39 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.xor %arg38, %0 : i8
  %2 = llvm.and %1, %arg39 : i8
  %3 = llvm.xor %2, %0 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

elab "[Comb_com| " reg:mlir_region "]" : term => do
  SSA.elabIntoCom' reg Comb

def shl1_trunc_sgt4_before := [llvm|
{
^0(%arg15 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(4 : i16) : i16
  %2 = llvm.shl %0, %arg15 : i32
  %3 = llvm.trunc %2 : i32 to i16
  %4 = llvm.icmp "sgt" %3, %1 : i16
  "llvm.return"(%4) : (i1) -> ()
}
]

def sle_swap_or_min_after := [llvm|
{
^0(%arg150 : i8, %arg151 : i8):
  %0 = llvm.icmp "sge" %arg151, %arg150 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

def t0_before := [llvm|
{
^0(%arg32 : i8):
  %0 = llvm.mlir.constant(15 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.mlir.constant(16 : i8) : i8
  %3 = llvm.mlir.constant(-16 : i8) : i8
  %4 = llvm.and %arg32, %0 : i8
  %5 = llvm.icmp "eq" %4, %1 : i8
  %6 = llvm.add %arg32, %2 : i8
  %7 = llvm.and %6, %3 : i8
  %8 = "llvm.select"(%5, %arg32, %7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%8) : (i8) -> ()
}
]

def test22_before := [llvm|
{
^0(%arg189 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.xor %arg189, %0 : i1
  %3 = llvm.zext %2 : i1 to i32
  %4 = llvm.xor %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def scalar_zext_slt_before := [llvm|
{
^0(%arg1 : i16):
  %0 = llvm.mlir.constant(500 : i32) : i32
  %1 = llvm.zext %arg1 : i16 to i32
  %2 = llvm.icmp "slt" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def testi64i32_ne_before := [llvm|
{
^0(%arg7 : i64):
  %0 = llvm.mlir.constant(32) : i64
  %1 = llvm.mlir.constant(31 : i32) : i32
  %2 = llvm.lshr %arg7, %0 : i64
  %3 = llvm.trunc %2 : i64 to i32
  %4 = llvm.trunc %arg7 : i64 to i32
  %5 = llvm.ashr %4, %1 : i32
  %6 = llvm.icmp "ne" %5, %3 : i32
  "llvm.return"(%6) : (i1) -> ()
}
]

def lshrult_03_13_exact_before := [llvm|
{
^0(%arg104 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(-3 : i4) : i4
  %2 = llvm.lshr exact %arg104, %0 : i4
  %3 = llvm.icmp "ult" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def add_or_and_before := [llvm|
{
^0(%arg19 : i32, %arg20 : i32):
  %0 = llvm.or %arg19, %arg20 : i32
  %1 = llvm.and %arg19, %arg20 : i32
  %2 = llvm.add %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def unsigned_sign_bit_extract_with_trunc_after := [llvm|
{
^0(%arg3 : i64):
  %0 = llvm.mlir.constant(0) : i64
  %1 = llvm.icmp "slt" %arg3, %0 : i64
  "llvm.return"(%1) : (i1) -> ()
}
]

def mul_setnzV_unkV_nuw_eq_before := [llvm|
{
^0(%arg2 : i8, %arg3 : i8):
  %0 = llvm.mlir.constant(2 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.or %arg2, %0 : i8
  %3 = llvm.mul %2, %arg3 overflow<nuw> : i8
  %4 = llvm.icmp "eq" %3, %1 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

def t2_after := [llvm|
{
^0(%arg11 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "sgt" %arg11, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def land_lor_right1_after := [llvm|
{
^0(%arg46 : i1, %arg47 : i1):
  "llvm.return"(%arg46) : (i1) -> ()
}
]

def printParsedFpExprState (s: ParsedInputState) :=
    s!"ParsedFpExprState:\n" ++
    s!"  maxFreeVarId: {s.maxFreeVarId}\n" ++
    s!"  numSymVars: {s.numSymVars}\n" ++
    s!"  displayNameToVariable: {s.displayNameToVariable}\n" ++
    s!"  BVExprIdToFreeVar: {s.inputVarIdToVariable}\n" ++
    s!"  symVarToVal: {s.symVarToVal}" ++
    s!"  symVarToDisplayName: {s.symVarIdToVariable}"

def neg_slt_0_before := [llvm|
{
^0(%arg26 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.sub %0, %arg26 : i8
  %2 = llvm.icmp "slt" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def test1_after := [llvm|
{
^0(%arg3 : i16):
  %0 = llvm.mlir.constant(8 : i16) : i16
  %1 = llvm.mlir.constant(5 : i16) : i16
  %2 = llvm.lshr %arg3, %0 : i16
  %3 = llvm.mul %arg3, %1 : i16
  %4 = llvm.or %2, %3 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

def not_signbit_trunc_before := [llvm|
{
^0(%arg16 : i16):
  %0 = llvm.mlir.constant(-1 : i16) : i16
  %1 = llvm.mlir.constant(15 : i16) : i16
  %2 = llvm.xor %arg16, %0 : i16
  %3 = llvm.lshr %2, %1 : i16
  %4 = llvm.trunc %3 : i16 to i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def add_shl_same_amount_constants_after := [llvm|
{
^0(%arg1 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.shl %0, %arg1 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def positive_sameconst_shlnuwnsw_lshrexact_before := [llvm|
{
^0(%arg26 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.lshr exact %arg26, %0 : i8
  %2 = llvm.shl %1, %0 overflow<nsw,nuw> : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def shift_trunc_wrong_cmp_after := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(24 : i32) : i32
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.lshr %arg0, %0 : i32
  %3 = llvm.trunc %2 overflow<nuw> : i32 to i8
  %4 = llvm.icmp "slt" %3, %1 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

def zext_nneg_after := [llvm|
{
^0(%arg0 : i16):
  %0 = llvm.mlir.constant(32767 : i16) : i16
  %1 = llvm.and %arg0, %0 : i16
  %2 = llvm.zext nneg %1 : i16 to i24
  "llvm.return"(%2) : (i24) -> ()
}
]

def src4_after := [llvm|
{
^0(%arg6 : i32, %arg7 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg6, %arg7 : i32
  %2 = llvm.xor %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def positive_biggerlshr_shlnuwnsw_lshrexact_after := [llvm|
{
^0(%arg25 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.lshr exact %arg25, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def shl_lshr_pow2_const_case2_after := [llvm|
{
^0(%arg72 : i16):
  %0 = llvm.mlir.constant(2 : i16) : i16
  %1 = llvm.mlir.constant(8 : i16) : i16
  %2 = llvm.mlir.constant(0 : i16) : i16
  %3 = llvm.icmp "eq" %arg72, %0 : i16
  %4 = "llvm.select"(%3, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i16, i16) -> i16
  "llvm.return"(%4) : (i16) -> ()
}
]

partial def Expr.print (e : Expr d Γ eff t) : Format :=
  let regions :=
    match h : e.regArgs.length with
    | 0 => f!""
    | 1 =>
      let reg := e.regArgs.getN 0 (by admit /- proof elided -/
      )
      f!" ({reg.print})"
    | _ =>
      let regs :=
        e.regArgs.mapToList (Format.align true ++ Com.print ·)
        |> f!", ".joinSep
        |> Format.nest 2
      f!" ({regs})"
  Format.align true ++ f!"{e.printResultList}\"{printOpName e.op}\"{e.printArgs}{printAttributes e.op}{regions} : {e.printType}"

Lean.mkConst in Lean.Expr

def ashr_mul_times_3_div_2_exact_2_after := [llvm|
{
^0(%arg17 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.ashr exact %arg17, %0 : i32
  %2 = llvm.add %arg17, %1 overflow<nsw> : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def sgt_smin2_before := [llvm|
{
^0(%arg45 : i32, %arg46 : i32):
  %0 = llvm.icmp "slt" %arg46, %arg45 : i32
  %1 = "llvm.select"(%0, %arg46, %arg45) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %2 = llvm.icmp "sgt" %1, %arg45 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def positive_sameconst_before := [llvm|
{
^0(%arg61 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.lshr %arg61, %0 : i8
  %2 = llvm.shl %1, %0 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def n7_wrong_pred2_before := [llvm|
{
^0(%arg10 : i8, %arg11 : i8):
  %0 = llvm.sub %arg10, %arg11 : i8
  %1 = llvm.icmp "eq" %0, %arg10 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

Lean.Parser.mkAntiquot in Lean.Parser.Basic

def neg_nsw_slt_0_before := [llvm|
{
^0(%arg20 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.sub %0, %arg20 overflow<nsw> : i8
  %2 = llvm.icmp "slt" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def fold_sext_to_and_wrong4_before := [llvm|
{
^0(%arg6 : i8):
  %0 = llvm.mlir.constant(128 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.sext %arg6 : i8 to i32
  %3 = llvm.and %2, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def different_size_sext_sext_sle_before := [llvm|
{
^0(%arg12 : i7, %arg13 : i4):
  %0 = llvm.sext %arg12 : i7 to i25
  %1 = llvm.sext %arg13 : i4 to i25
  %2 = llvm.icmp "sle" %0, %1 : i25
  "llvm.return"(%2) : (i1) -> ()
}
]

def slt_swap_and_not_max_logical_before := [llvm|
{
^0(%arg116 : i8, %arg117 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "sgt" %arg117, %arg116 : i8
  %3 = llvm.icmp "ne" %arg116, %0 : i8
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

instance : Inhabited BVExprWrapper where
  default := {bvExpr := GenBVExpr.const (BitVec.ofNat 0 0), width := 0}

def ashrslt_01_08_exact_after := [llvm|
{
^0(%arg45 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def test11_after := [llvm|
{
^0(%arg84 : i32, %arg85 : i32):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.zext %arg84 : i32 to i64
  %2 = llvm.and %arg85, %0 : i32
  %3 = llvm.zext nneg %2 : i32 to i64
  %4 = llvm.shl %1, %3 overflow<nsw,nuw> : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

def masked_and_notA_slightly_optimized_after := [llvm|
{
^0(%arg123 : i32):
  %0 = llvm.mlir.constant(-40 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg123, %0 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def constLLVM7 : Com LLVMPlusRiscV ⟨[]⟩ .pure (.llvm (.bitvec 64)) := [LV| {
  ^entry ():
    %1 = llvm.mlir.constant (7) : i64
    llvm.return %1 : i64
  }]

def getIntAttr (attr : String) (coeBool : Bool := true) : Except TransformError (Int × MLIRType φ) := do
  let attrVal ← op.getAttr attr
  if coeBool then if let .bool b := attrVal then
    return (if b then 1 else 0, .int .Signless (.concrete 1))

  let .int val ty := attrVal
    | .error <| .generic s!"Expected attribute `{attr}` to be of type Int, but found:\n\
        \t{attr}"
  return (val, ty)

def lshrult_02_07_before := [llvm|
{
^0(%arg344 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.mlir.constant(7 : i4) : i4
  %2 = llvm.lshr %arg344, %0 : i4
  %3 = llvm.icmp "ult" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def or_logic_or_logic_and_5_before := [llvm|
{
^0(%arg36 : i1, %arg37 : i1, %arg38 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.or %arg37, %arg36 : i1
  %3 = "llvm.select"(%arg36, %0, %arg38) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

abbrev Width φ := ConcreteOrMVar Nat φ

def three_inst_concrete_macro :=
  [llvm()|{
  ^bb0(%arg0: i1):
    %0 = llvm.not %arg0 : i1
    %1 = llvm.not %0 : i1
    %2 = llvm.not %1 : i1
    llvm.return %2 : i1
  }]

def ult_umin4_after := [llvm|
{
^0(%arg30 : i32, %arg31 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg30, %0 : i32
  %2 = llvm.icmp "ult" %arg31, %1 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def llvm_udiv_lower_riscv_no_flag_32: LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] :=
  {lhs := udiv_llvm_no_exact_32, rhs := udiv_riscv_32, correct :=
  by admit /- proof elided -/

def pruneEquivalentFpLogicalExprs(expressions : List FpPredicate): GeneralizerStateM ParsedFpExpr FpPredicate (List FpPredicate) := do
  withTraceNode `Generalize (fun _ => return "Pruned equivalent bvLogicalExprs") do
    let mut pruned: List FpPredicate:= []
    
    for expr in expressions do
      if pruned.isEmpty then
        pruned := expr :: pruned
        continue
      let newConstraints := pruned.map (fun f =>
          
          
          BoolExpr.not (BoolExpr.gate Gate.beq (BoolExpr.literal f) (BoolExpr.literal expr)))
      let subsumeCheckExpr :=  bigAnd newConstraints

      if let some _ ← solve subsumeCheckExpr then
        pruned := expr :: pruned

    logInfo m! "Removed {expressions.length - pruned.length} expressions after pruning"
    pure pruned

@[simp_denote]
def trunc_llvm_64_to_32_nuw := [LV| {
  ^entry (%lhs: i64):
    %0 = llvm.trunc %lhs overflow<nuw> : i64 to i32
    llvm.return %0 : i32
  }]

def t0_before := [llvm|
{
^0(%arg15 : i8):
  %0 = llvm.mlir.constant(-32 : i8) : i8
  %1 = llvm.sdiv exact %arg15, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def negtest_near_pow2_cmpval_ashr_wrong_cmp_pred_before := [llvm|
{
^0(%arg2 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(5 : i8) : i8
  %2 = llvm.ashr exact %arg2, %0 : i8
  %3 = llvm.icmp "eq" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def udiv_exact_eq_1_before := [llvm|
{
^0(%arg10 : i8, %arg11 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.udiv exact %arg10, %arg11 : i8
  %2 = llvm.icmp "ne" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def positive_biggerashr_ashrexact_after := [llvm|
{
^0(%arg40 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.ashr exact %arg40, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def sgt_swap_and_min_logical_after := [llvm|
{
^0(%arg342 : i8, %arg343 : i8):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def n6_after := [llvm|
{
^0(%arg6 : i8, %arg7 : i8, %arg8 : i8):
  "llvm.return"(%arg8) : (i8) -> ()
}
]

def ashr_16_to_64_add_zext_basic_after := [llvm|
{
^0(%arg7 : i16, %arg8 : i16):
  %0 = llvm.mlir.constant(-1 : i16) : i16
  %1 = llvm.xor %arg7, %0 : i16
  %2 = llvm.icmp "ugt" %arg8, %1 : i16
  %3 = llvm.zext %2 : i1 to i64
  "llvm.return"(%3) : (i64) -> ()
}
]

def PR42691_8_logical_after := [llvm|
{
^0(%arg328 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.mlir.constant(-2147483635 : i32) : i32
  %2 = llvm.add %arg328, %0 : i32
  %3 = llvm.icmp "ult" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

abbrev WidthExpr := Expr

@[simp]
def langMsb : Set (BitVecs 1) := { bvs | bvs.bvs.get 0 |>.msb }

@[simp_denote]
def llvm_sub_nsw_16 := [LV| {
  ^entry (%x: i16, %y: i16 ):
    %1 = llvm.sub    %x, %y overflow<nsw> : i16
    llvm.return %1 : i16
  }]

def icmp_ne_zext_eq_one_before := [llvm|
{
^0(%arg38 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.icmp "eq" %arg38, %0 : i32
  %2 = llvm.zext %1 : i1 to i32
  %3 = llvm.icmp "ne" %2, %arg38 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def ugt_umax4_after := [llvm|
{
^0(%arg30 : i32, %arg31 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg30, %0 : i32
  %2 = llvm.icmp "ugt" %arg31, %1 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def test51_after := [llvm|
{
^0(%arg133 : i64, %arg134 : i1):
  %0 = llvm.mlir.constant(-2 : i32) : i32
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.trunc %arg133 : i64 to i32
  %3 = llvm.and %2, %0 : i32
  %4 = llvm.xor %arg134, %1 : i1
  %5 = llvm.zext %4 : i1 to i32
  %6 = llvm.or disjoint %3, %5 : i32
  %7 = llvm.sext %6 : i32 to i64
  "llvm.return"(%7) : (i64) -> ()
}
]

def test_zext4_after := [llvm|
{
^0(%arg35 : i1, %arg36 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg36, %0 : i1
  %2 = "llvm.select"(%1, %0, %arg35) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = llvm.zext %2 : i1 to i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def constLLVM5 : Com LLVMPlusRiscV ⟨[]⟩ .pure (.llvm (.bitvec 64)) := [LV| {
  ^entry ():
    %1 = llvm.mlir.constant (5) : i64
    llvm.return %1 : i64
  }]

def lshrugt_02_14_exact_after := [llvm|
{
^0(%arg191 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def sle_smax4_before := [llvm|
{
^0(%arg49 : i32, %arg50 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg49, %0 : i32
  %2 = llvm.icmp "sgt" %arg50, %1 : i32
  %3 = "llvm.select"(%2, %arg50, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.icmp "sge" %1, %3 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def sdiv_eq_smin_after := [llvm|
{
^0(%arg28 : i8, %arg29 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.icmp "eq" %arg28, %0 : i8
  %3 = llvm.icmp "eq" %arg29, %1 : i8
  %4 = llvm.and %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def icmp_shl_eq_1_after := [llvm|
{
^0(%arg7 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "eq" %arg7, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def negative5_after := [llvm|
{
^0(%arg2 : i32, %arg3 : i32):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def not_mul_of_pow2_before := [llvm|
{
^0(%arg77 : i32, %arg78 : i8):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.mlir.constant(1530 : i32) : i32
  %2 = llvm.and %arg77, %0 : i32
  %3 = llvm.zext %arg78 : i8 to i32
  %4 = llvm.mul %2, %3 : i32
  %5 = llvm.icmp "ugt" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

def and_not_or_wrong_c_after := [llvm|
{
^0(%arg432 : i32, %arg433 : i32, %arg434 : i32, %arg435 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg432, %arg433 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.or %arg434, %2 : i32
  %4 = llvm.and %arg432, %arg435 : i32
  %5 = llvm.xor %4, %0 : i32
  %6 = llvm.or %arg433, %5 : i32
  %7 = llvm.and %3, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def icmp_and_ashr_multiuse_logical_after := [llvm|
{
^0(%arg4 : i32):
  %0 = llvm.mlir.constant(240 : i32) : i32
  %1 = llvm.mlir.constant(224 : i32) : i32
  %2 = llvm.mlir.constant(496 : i32) : i32
  %3 = llvm.mlir.constant(432 : i32) : i32
  %4 = llvm.and %arg4, %0 : i32
  %5 = llvm.icmp "ne" %4, %1 : i32
  %6 = llvm.and %arg4, %2 : i32
  %7 = llvm.icmp "ne" %6, %3 : i32
  %8 = llvm.and %5, %7 : i1
  "llvm.return"(%8) : (i1) -> ()
}
]

def positive_with_aggressive_icmp_before := [llvm|
{
^0(%arg56 : i32):
  %0 = llvm.mlir.constant(128 : i32) : i32
  %1 = llvm.mlir.constant(256 : i32) : i32
  %2 = llvm.mlir.constant(512 : i32) : i32
  %3 = llvm.icmp "ult" %arg56, %0 : i32
  %4 = llvm.add %arg56, %1 : i32
  %5 = llvm.icmp "ult" %4, %2 : i32
  %6 = llvm.and %3, %5 : i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def t4_const_after_fold_lshr_shl_ne_before := [llvm|
{
^0(%arg85 : i32, %arg86 : i32, %arg87 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.sub %0, %arg87 : i32
  %4 = llvm.shl %arg85, %3 : i32
  %5 = llvm.add %arg87, %1 : i32
  %6 = llvm.lshr %arg86, %5 : i32
  %7 = llvm.and %4, %6 : i32
  %8 = llvm.icmp "ne" %7, %2 : i32
  "llvm.return"(%8) : (i1) -> ()
}
]

def scalar_i32_shl_and_negC_eq_after := [llvm|
{
^0(%arg31 : i32, %arg32 : i32):
  %0 = llvm.mlir.constant(262144 : i32) : i32
  %1 = llvm.shl %arg31, %arg32 : i32
  %2 = llvm.icmp "ult" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def test : DCOp.ValueStream (BitVec 8) × DCOp.ValueStream (BitVec 8) :=
  DCFork.denote (Ctxt.Valuation.ofHVector (.cons x <| .nil))

instance : DecidableEq VarName :=

def test23_before := [llvm|
{
^0(%arg276 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.icmp "sgt" %arg276, %0 : i32
  %3 = llvm.icmp "sle" %arg276, %1 : i32
  %4 = llvm.and %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def shl_add_nsw_after := [llvm|
{
^0(%arg25 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.shl %0, %arg25 overflow<nsw> : i32
  %2 = llvm.xor %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def irc_constants_C1Minus2MinusC2_2_1 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (2) : i64
      %c2 = llvm.mlir.constant (1) : i64
      %0 = llvm.sub %c1, %a : i64
      %1 = llvm.sub %0, %c2 : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (2) : i64
      %c2 = llvm.mlir.constant (1) : i64
      %0 = llvm.sub %c1, %c2 : i64
      %1 = llvm.sub %0, %a : i64
      llvm.return %1 : i64
  }]

def source : TokenStream :=
  Stream.corec () fun () => (some (), ())

def test_shr_and_1_ne_0_before := [llvm|
{
^0(%arg11 : i32, %arg12 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.lshr %arg11, %arg12 : i32
  %3 = llvm.and %2, %0 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def test6a_after := [llvm|
{
^0(%arg1 : i1):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def lshrugt_01_04_exact_before := [llvm|
{
^0(%arg217 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(4 : i4) : i4
  %2 = llvm.lshr exact %arg217, %0 : i4
  %3 = llvm.icmp "ugt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def altMerge (x y : Stream α) : Stream α :=
  Stream.corec (β := Stream α × Stream α × ConsumeFrom) (x, y, .left) fun ⟨x, y, consume⟩ =>
    match consume with
      | .left  =>
        let x0 := x.head
        let x := x.tail
        let nextConsume := match x0 with
          | some _ => .right
          | none   => .left
        (x0, x, y, nextConsume)
      | .right =>
        let y0 := y.head
        let y := y.tail
        let nextConsume := match y0 with
          | some _ => .left
          | none   => .right
        (y0, x, y, nextConsume)

def uge_swap_and_max_logical_before := [llvm|
{
^0(%arg228 : i8, %arg229 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "ule" %arg229, %arg228 : i8
  %3 = llvm.icmp "eq" %arg228, %0 : i8
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def lshr_mul_times_3_div_2_exact_2_after := [llvm|
{
^0(%arg28 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.lshr exact %arg28, %0 : i32
  %2 = llvm.add %arg28, %1 overflow<nuw> : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def scalar_i8_shl_and_negC_eq_before := [llvm|
{
^0(%arg35 : i8, %arg36 : i8):
  %0 = llvm.mlir.constant(-4 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.shl %arg35, %arg36 : i8
  %3 = llvm.and %2, %0 : i8
  %4 = llvm.icmp "eq" %3, %1 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

def select_icmp_ne_0_and_32_or_4096_before := [llvm|
{
^0(%arg203 : i32, %arg204 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(4096 : i32) : i32
  %3 = llvm.and %arg203, %0 : i32
  %4 = llvm.icmp "ne" %1, %3 : i32
  %5 = llvm.or %arg204, %2 : i32
  %6 = "llvm.select"(%4, %arg204, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%6) : (i32) -> ()
}
]

@[match_pattern]
def last (Γ : Ctxt Ty) (t : Ty) : Ctxt.Var (Ctxt.cons t Γ) t :=
  ⟨0, by admit /- proof elided -/
  ⟩

def Pointer.offsetInBits (p : Pointer) : Nat :=
  8 * p.offset.toNat

def alive_Select_1100_src  (w : Nat)   :=
[llvm( w )| {
^bb0(%Y : _, %X : _):
  %v1 = llvm.mlir.constant 1 :  i1
  %v2 = llvm.select %v1, %X, %Y
  llvm.return %v2
}]

def t9_before := [llvm|
{
^0(%arg176 : i8, %arg177 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.sub %arg177, %arg176 : i8
  %2 = llvm.sub %0, %1 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def AMinusBPlusBMinusC : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%a: i64, %b: i64, %c: i64):
      %0 = llvm.sub %a, %b : i64
      %1 = llvm.sub %b, %c : i64
      %2 = llvm.add %0, %1 : i64
      llvm.return %2 : i64
  }]
  rhs := [LV| {
    ^entry (%a: i64, %b: i64, %c: i64):
      %0 = llvm.sub %a, %c : i64
      llvm.return %0 : i64
  }]

def nonexact_ashr_ne_exactdiv_before := [llvm|
{
^0(%arg145 : i8):
  %0 = llvm.mlir.constant(-80 : i8) : i8
  %1 = llvm.mlir.constant(-5 : i8) : i8
  %2 = llvm.ashr %0, %arg145 : i8
  %3 = llvm.icmp "ne" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

getThe in Init.Prelude

def lshrult_01_06_before := [llvm|
{
^0(%arg361 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(6 : i4) : i4
  %2 = llvm.lshr %arg361, %0 : i4
  %3 = llvm.icmp "ult" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

inductive BasicBlock
  | mk (label : BlockLabel) (args : List VarName) (body : Body)

def alive_AndOrXor_1280_ABA___AB_src :=
[sllvm| {
^bb0(%A : i64, %B : i64):
  %v1 = llvm.mlir.constant -1 : i64
  %v2 = llvm.xor %A, %v1 : i64
  %v3 = llvm.or %v2, %B : i64
  %v4 = llvm.and %v3, %A : i64
  llvm.return %v4 : i64
}]

def composeQuinaryAux' (p : FSM (Fin 5)) (q₀ q₁ q₂ q₃ q₄: FSM α) : FSM α :=
  p.compose (α)
    (λ _ => α)
    (λ _ i => i)
    (λ v =>
      v.cases q₀ fun v =>
        v.cases q₁ fun v =>
          v.cases q₂ fun v =>
            v.cases q₃ fun v =>
              v.cases q₄ fun v => v.elim0)

def is_ascii_alphabetic_inverted_before := [llvm|
{
^0(%arg247 : i32):
  %0 = llvm.mlir.constant(-91 : i32) : i32
  %1 = llvm.mlir.constant(-26 : i32) : i32
  %2 = llvm.mlir.constant(-123 : i32) : i32
  %3 = llvm.mlir.constant(false) : i1
  %4 = llvm.add %arg247, %0 overflow<nsw> : i32
  %5 = llvm.icmp "ult" %4, %1 : i32
  %6 = llvm.add %arg247, %2 overflow<nsw> : i32
  %7 = llvm.icmp "ult" %6, %1 : i32
  %8 = "llvm.select"(%5, %7, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%8) : (i1) -> ()
}
]

def trunc_lshr_sext_narrow_input_before := [llvm|
{
^0(%arg24 : i8):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.sext %arg24 : i8 to i32
  %2 = llvm.lshr %1, %0 : i32
  %3 = llvm.trunc %2 : i32 to i16
  "llvm.return"(%3) : (i16) -> ()
}
]

def tok2 : CIRCTStream.DCOp.TokenStream := ofList [none, some (), some (), some (), none]

def fold_mask_cmps_to_false_before := [llvm|
{
^0(%arg111 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg111, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  %4 = llvm.icmp "eq" %arg111, %0 : i32
  %5 = llvm.and %4, %3 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def mul64_low_after := [llvm|
{
^0(%arg20 : i64, %arg21 : i64):
  %0 = llvm.mul %arg20, %arg21 : i64
  "llvm.return"(%0) : (i64) -> ()
}
]

def Substitution.removeMappingFor (σ : Substitution) (v : VarName) : Substitution :=
  List.filter (·.fst != v) σ

def select_icmp_ne_0_and_32_or_4096_after := [llvm|
{
^0(%arg203 : i32, %arg204 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(4096 : i32) : i32
  %2 = llvm.shl %arg203, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.or %arg204, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

Function.comp in Init.Prelude

def test_mul_nuw__nsw_is_safe_before := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(-83886080 : i32) : i32
  %1 = llvm.mlir.constant(-83886079 : i32) : i32
  %2 = llvm.mlir.constant(9 : i32) : i32
  %3 = llvm.mlir.constant(-754974711 : i32) : i32
  %4 = llvm.or %arg6, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.mul %4, %2 overflow<nuw> : i32
  %7 = "llvm.select"(%5, %3, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def test3_before := [llvm|
{
^0(%arg4 : i123):
  %0 = llvm.xor %arg4, %arg4 : i123
  "llvm.return"(%0) : (i123) -> ()
}
]

def test17_after := [llvm|
{
^0(%arg36 : i32, %arg37 : i32):
  %0 = llvm.mlir.constant(1431655765 : i32) : i32
  %1 = llvm.or %arg36, %0 : i32
  %2 = llvm.sub %arg37, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def bool_eq0_before := [llvm|
{
^0(%arg33 : i64):
  %0 = llvm.mlir.constant(0) : i64
  %1 = llvm.mlir.constant(1) : i64
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.icmp "sgt" %arg33, %0 : i64
  %4 = llvm.icmp "eq" %arg33, %1 : i64
  %5 = llvm.icmp "eq" %4, %2 : i1
  %6 = llvm.and %3, %5 : i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def not_not_false_before := [llvm|
{
^0(%arg236 : i1, %arg237 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.xor %arg236, %0 : i1
  %3 = llvm.xor %arg237, %0 : i1
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def test13_before := [llvm|
{
^0(%arg16 : i8, %arg17 : i8):
  %0 = llvm.icmp "ult" %arg16, %arg17 : i8
  %1 = llvm.icmp "ugt" %arg16, %arg17 : i8
  %2 = llvm.xor %0, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

def constLLVM_18 : Com LLVMPlusRiscV ⟨[]⟩ .pure (.llvm (.bitvec 64)) := [LV| {
  ^entry ():
    %1 = llvm.mlir.constant (-18) : i64
    llvm.return %1 : i64
  }]

def test_after := [llvm|
{
^0(%arg0 : i26):
  "llvm.return"(%arg0) : (i26) -> ()
}
]

def lshrugt_02_07_after := [llvm|
{
^0(%arg392 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def reduce_xor_common_op_commute0_before := [llvm|
{
^0(%arg10 : i4, %arg11 : i4, %arg12 : i4):
  %0 = llvm.xor %arg10, %arg11 : i4
  %1 = llvm.xor %0, %arg12 : i4
  %2 = llvm.or %1, %arg10 : i4
  "llvm.return"(%2) : (i4) -> ()
}
]

def ult_swap_and_max_commute_after := [llvm|
{
^0(%arg356 : i8, %arg357 : i8):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def CNFA.recognizes (m : CNFA n) (L : Language (BitVec n)) :=
  ∃ (M : NFA' n), m.Sim M ∧ M.M.accepts = L

structure Bisimul (R : SetRel σ ς) (M₁ : NFA α σ) (M₂ : NFA α ς) where
  accept : q₁ ~[R] q₂ → (q₁ ∈ M₁.accept ↔ q₂ ∈ M₂.accept)
  start : R.set_eq M₁.start M₂.start
  trans_match₁ : q₁ ~[R] q₂ → q₁' ∈ M₁.step q₁ a → ∃ q₂', q₂' ∈ M₂.step q₂ a ∧ q₁' ~[R] q₂'
  trans_match₂ : q₁ ~[R] q₂ → q₂' ∈ M₂.step q₂ a → ∃ q₁', q₁' ∈ M₁.step q₁ a ∧ q₁' ~[R] q₂'

def ashr_pow2_ult_before := [llvm|
{
^0(%arg59 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(-96 : i8) : i8
  %2 = llvm.ashr %0, %arg59 : i8
  %3 = llvm.icmp "ult" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

@[inline] private unsafe def Std.HashSet.attachWithImpl [BEq α] [LawfulBEq α] [Hashable α] [LawfulHashable α]
    (xs : Std.HashSet α) (P : α → Prop) (_ : ∀ x ∈ xs, P x) : Std.HashSet {x // P x} := unsafeCast xs

def fold_add_udiv_urem_or_disjoint_before := [llvm|
{
^0(%arg5 : i32):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.mlir.constant(4 : i32) : i32
  %2 = llvm.udiv %arg5, %0 : i32
  %3 = llvm.shl %2, %1 : i32
  %4 = llvm.urem %arg5, %0 : i32
  %5 = llvm.or disjoint %3, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def liRiscv29 := [LV| {
  ^entry ():
    %0 = "li"() {imm = 29 : !i64} : (!i64) -> (!i64)
    %1 = "builtin.unrealized_conversion_cast"(%0) : (!i64) -> (i64)
    llvm.return %1 : i64
  }]

def icmp_mul_nsw_sle_before := [llvm|
{
^0(%arg17 : i8, %arg18 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mul %arg17, %0 overflow<nsw> : i8
  %2 = llvm.mul %arg18, %0 overflow<nsw> : i8
  %3 = llvm.icmp "sle" %1, %2 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def and_two_ranges_to_mask_and_range_before := [llvm|
{
^0(%arg252 : i8):
  %0 = llvm.mlir.constant(-97 : i8) : i8
  %1 = llvm.mlir.constant(25 : i8) : i8
  %2 = llvm.mlir.constant(-65 : i8) : i8
  %3 = llvm.add %arg252, %0 : i8
  %4 = llvm.icmp "ugt" %3, %1 : i8
  %5 = llvm.add %arg252, %2 : i8
  %6 = llvm.icmp "ugt" %5, %1 : i8
  %7 = llvm.and %4, %6 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

def no_shift_xor_multiuse_xor_after := [llvm|
{
^0(%arg132 : i32, %arg133 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.and %arg132, %0 : i32
  %2 = llvm.xor %arg133, %0 : i32
  %3 = llvm.xor %1, %arg133 : i32
  %4 = llvm.xor %3, %0 : i32
  %5 = llvm.mul %4, %2 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

@[simp]
def EnvFin.get_castLe {w n n' : Nat} (env : EnvFin w n) (h : n' ≤ n) (i : Fin n') :
  (env.castLe h) i = env ⟨i, by admit /- proof elided -/
  ⟩ := rfl

def positive_biggerShl_after := [llvm|
{
^0(%arg34 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.mlir.constant(134217696 : i32) : i32
  %2 = llvm.shl %arg34, %0 : i32
  %3 = llvm.and %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def add_shl_moreOneUse_sh4add_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := add_shl_moreOneUse_sh4add_llvm
  rhs :=add_shl_moreOneUse_sh4add_riscv

instLEBitVec in Init.Prelude

def ule_umax2_after := [llvm|
{
^0(%arg50 : i32, %arg51 : i32):
  %0 = llvm.icmp "ule" %arg51, %arg50 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

def umod  (op1 : GenBVExpr w) (op2 : GenBVExpr w) : GenBVExpr w :=
  GenBVExpr.bin op1 BVBinOp.umod op2

def udiv_eq_big_after := [llvm|
{
^0(%arg38 : i8, %arg39 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.icmp "eq" %arg38, %0 : i8
  %3 = llvm.icmp "eq" %arg39, %1 : i8
  %4 = llvm.and %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def test15_after := [llvm|
{
^0(%arg44 : i8, %arg45 : i8):
  %0 = llvm.mlir.constant(33 : i8) : i8
  %1 = llvm.xor %arg45, %arg44 : i8
  %2 = llvm.xor %arg44, %arg45 : i8
  %3 = llvm.xor %2, %0 : i8
  %4 = llvm.and %1, %3 : i8
  %5 = llvm.mul %4, %3 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

@[simp_denote]
def riscvArgsFromHybrid_nil_eq :
  (riscvArgsFromHybrid HVector.nil) = HVector.nil := rfl

def pr64558_after := [llvm|
{
^0(%arg108 : i1, %arg109 : i1):
  %0 = llvm.or %arg109, %arg108 : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def eq_nsw_rem_nz_before := [llvm|
{
^0(%arg158 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.mlir.constant(-11 : i8) : i8
  %2 = llvm.mul %arg158, %0 overflow<nsw> : i8
  %3 = llvm.icmp "eq" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def pr33078_1_before := [llvm|
{
^0(%arg5 : i8):
  %0 = llvm.mlir.constant(8 : i16) : i16
  %1 = llvm.sext %arg5 : i8 to i16
  %2 = llvm.lshr %1, %0 : i16
  %3 = llvm.trunc %2 : i16 to i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def test4_after := [llvm|
{
^0(%arg1 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.icmp "ne" %arg1, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def ne_smax4_before := [llvm|
{
^0(%arg41 : i32, %arg42 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg41, %0 : i32
  %2 = llvm.icmp "sgt" %arg42, %1 : i32
  %3 = "llvm.select"(%2, %arg42, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.icmp "ne" %1, %3 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def masked_icmps_mask_notallzeros_bmask_mixed_7b_after := [llvm|
{
^0(%arg76 : i32):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def shl_add_and_after := [llvm|
{
^0(%arg96 : i8, %arg97 : i8):
  %0 = llvm.mlir.constant(61 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.add %arg97, %0 : i8
  %3 = llvm.and %arg96, %2 : i8
  %4 = llvm.shl %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def and_logic_and_logic_or_3_before := [llvm|
{
^0(%arg132 : i1, %arg133 : i1, %arg134 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.and %arg133, %arg132 : i1
  %3 = "llvm.select"(%arg132, %arg134, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = "llvm.select"(%2, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

private def bb2SingleArg : Region φ :=
  [mlir_region| {
     ^entry(%argp : i32):
     "foo"(%x, %y) : (i32, i32) -> ()
      %z = "bar"(%x) : (i32) -> (i32)
      "std.return"(%x0) : (i42) -> ()
  }]

def test7_after := [llvm|
{
^0(%arg0 : i47):
  %0 = llvm.mlir.constant(-70368744177664 : i47) : i47
  %1 = llvm.mlir.constant(70368040490200 : i47) : i47
  %2 = llvm.and %arg0, %0 : i47
  %3 = llvm.or disjoint %2, %1 : i47
  "llvm.return"(%3) : (i47) -> ()
}
]

def ugt_swap_or_not_min_logical_after := [llvm|
{
^0(%arg4 : i8, %arg5 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "ne" %arg4, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def shl_nsw_add_nuw_before := [llvm|
{
^0(%arg20 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.shl %0, %arg20 overflow<nsw> : i32
  %3 = llvm.add %2, %1 overflow<nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def badimm3_before := [llvm|
{
^0(%arg26 : i16):
  %0 = llvm.mlir.constant(8 : i16) : i16
  %1 = llvm.mlir.constant(7 : i8) : i8
  %2 = llvm.mlir.constant(14 : i16) : i16
  %3 = llvm.mlir.constant(127 : i8) : i8
  %4 = llvm.lshr %arg26, %0 : i16
  %5 = llvm.trunc %4 : i16 to i8
  %6 = llvm.trunc %arg26 : i16 to i8
  %7 = llvm.ashr %6, %1 : i8
  %8 = llvm.icmp "eq" %7, %5 : i8
  %9 = llvm.ashr %arg26, %2 : i16
  %10 = llvm.trunc %9 : i16 to i8
  %11 = llvm.xor %10, %3 : i8
  %12 = "llvm.select"(%8, %6, %11) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%12) : (i8) -> ()
}
]

def test26_before := [llvm|
{
^0(%arg48 : i32, %arg49 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %0, %arg49 : i32
  %3 = llvm.srem %arg48, %2 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def VarName : Type := String

def Env.ofEnvFin (envFin : EnvFin w n) : Env w := (List.finRange n).map envFin

def ashr_ult_7_after := [llvm|
{
^0(%arg89 : i4):
  %0 = llvm.mlir.constant(-1 : i4) : i4
  %1 = llvm.icmp "sgt" %arg89, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

def alive_Select_859'_src :=
[sllvm| {
^bb0(%a : i1, %b : i1):
  %v1 = llvm.mlir.constant -1 :  i1
  %v2 = llvm.xor %a, %v1 : i1
  %v3 = llvm.select %a,%b, %v2 : i1
  llvm.return %v3 : i1
}]

def test1_after := [llvm|
{
^0(%arg24 : i32, %arg25 : i32):
  %0 = llvm.mlir.constant(65280 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.xor %arg24, %arg25 : i32
  %3 = llvm.and %2, %0 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def neg_sgt_0_after := [llvm|
{
^0(%arg23 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.icmp "ugt" %arg23, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def same_signbit_wrong_type_before := [llvm|
{
^0(%arg34 : i8, %arg35 : i32):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.lshr %arg34, %0 : i8
  %3 = llvm.icmp "sgt" %arg35, %1 : i32
  %4 = llvm.zext %3 : i1 to i8
  %5 = llvm.icmp "ne" %2, %4 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

def and_and_logic_or_2_before := [llvm|
{
^0(%arg99 : i1, %arg100 : i1, %arg101 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.and %arg100, %arg99 : i1
  %2 = llvm.and %arg99, %arg101 : i1
  %3 = "llvm.select"(%2, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def ashr_sge_noexact_before := [llvm|
{
^0(%arg156 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(10 : i8) : i8
  %2 = llvm.ashr %arg156, %0 : i8
  %3 = llvm.icmp "sge" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def irc_constants_APlusC1MinusC2_1_neg1 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (1) : i64
      %c2 = llvm.mlir.constant (-1) : i64
      %0 = llvm.add %a, %c1 : i64
      %1 = llvm.sub %0, %c2 : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (1) : i64
      %c2 = llvm.mlir.constant (-1) : i64
      %0 = llvm.sub %c1, %c2 : i64
      %1 = llvm.add %a, %0 : i64
      llvm.return %1 : i64
  }]

def slt_swap_or_not_max_commute_logical_after := [llvm|
{
^0(%arg48 : i8, %arg49 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.icmp "ne" %arg48, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def ult_to_sgt_before := [llvm|
{
^0(%arg24 : i8, %arg25 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.xor %arg24, %0 : i8
  %2 = llvm.xor %arg25, %0 : i8
  %3 = llvm.icmp "ult" %1, %2 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def test2_before := [llvm|
{
^0(%arg0 : i999, %arg1 : i999):
  %0 = llvm.mlir.constant(65280 : i999) : i999
  %1 = llvm.and %arg0, %0 : i999
  %2 = llvm.and %arg1, %0 : i999
  %3 = llvm.icmp "ne" %1, %2 : i999
  "llvm.return"(%3) : (i1) -> ()
}
]

def shr_umax_before := [llvm|
{
^0(%arg16 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(4 : i32) : i32
  %2 = llvm.icmp "ugt" %0, %arg16 : i32
  %3 = "llvm.select"(%2, %0, %arg16) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.lshr %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

Polynomial.map in Mathlib.Algebra.Polynomial.Eval.Defs

def shl_xor_xor_good_mask_before := [llvm|
{
^0(%arg100 : i8, %arg101 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(88 : i8) : i8
  %2 = llvm.shl %arg100, %0 : i8
  %3 = llvm.shl %arg101, %0 : i8
  %4 = llvm.xor %3, %1 : i8
  %5 = llvm.xor %2, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def pr40493_neg1_before := [llvm|
{
^0(%arg17 : i32):
  %0 = llvm.mlir.constant(11 : i32) : i32
  %1 = llvm.mlir.constant(4 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.mul %arg17, %0 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.icmp "eq" %4, %2 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

def scalar_i32_shl_and_signbit_eq_X_is_constant2_after := [llvm|
{
^0(%arg4 : i32):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.icmp "ne" %arg4, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

@[match_pattern] def freeze (w : Width φ) : MOp φ := .unary w .freeze

def compose [FinEnum arity] [DecidableEq arity] [Hashable arity]
    (new_arity : Type)        
    (q_arity : arity → Type)  
    (vars : ∀ (a : arity), q_arity a → new_arity)
    
    
    (q : ∀ (a : arity), FSM (q_arity a)) : 
    FSM new_arity :=
  { α := p.α ⊕ (Σ a, (q a).α),
    i := by admit /- proof elided -/

def and_not_or_commute8_after := [llvm|
{
^0(%arg457 : i32, %arg458 : i32, %arg459 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg457 : i32
  %3 = llvm.sdiv %0, %arg458 : i32
  %4 = llvm.xor %3, %arg459 : i32
  %5 = llvm.and %4, %2 : i32
  %6 = llvm.xor %5, %1 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

HSub.hSub in Init.Prelude

def test12commuted_after := [llvm|
{
^0(%arg87 : i32, %arg88 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg87, %arg88 : i32
  %2 = llvm.xor %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

instance : Coe (String × MLIRType φ) (AttrEntry φ) where
  coe v := AttrEntry.mk v.fst (AttrValue.type v.snd)

def shrink_or_after := [llvm|
{
^0(%arg11 : i6):
  %0 = llvm.mlir.constant(1 : i3) : i3
  %1 = llvm.trunc %arg11 : i6 to i3
  %2 = llvm.or %1, %0 : i3
  "llvm.return"(%2) : (i3) -> ()
}
]

def shl_and_lshr_before := [llvm|
{
^0(%arg94 : i32, %arg95 : i32, %arg96 : i32):
  %0 = llvm.shl %arg94, %arg95 overflow<nuw> : i32
  %1 = llvm.and %0, %arg96 : i32
  %2 = llvm.lshr %1, %arg95 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def ne_21_comm_or_after := [llvm|
{
^0(%arg70 : i32, %arg71 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.lshr %arg70, %0 : i32
  %2 = llvm.trunc %1 : i32 to i16
  %3 = llvm.lshr %arg71, %0 : i32
  %4 = llvm.trunc %3 : i32 to i16
  %5 = llvm.icmp "ne" %2, %4 : i16
  "llvm.return"(%5) : (i1) -> ()
}
]

def xor_signbit_lshr_before := [llvm|
{
^0(%arg11 : i32):
  %0 = llvm.mlir.constant(-65536 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.xor %arg11, %0 : i32
  %3 = llvm.lshr %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def hasType (Γ : Context Ty) (v : VarName) (ty : Ty) : Prop :=
  Γ.lookup v = some ty

def land_lor_right1_before := [llvm|
{
^0(%arg46 : i1, %arg47 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = "llvm.select"(%arg46, %arg47, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = "llvm.select"(%arg46, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

inductive NatPredicate (wcard : Nat) : Type
| eq : WidthExpr wcard → WidthExpr wcard → NatPredicate wcard

def test_nsw_and_signed_pred_after := [llvm|
{
^0(%arg56 : i64):
  %0 = llvm.mlir.constant(-7) : i64
  %1 = llvm.icmp "slt" %arg56, %0 : i64
  "llvm.return"(%1) : (i1) -> ()
}
]

def sel_sext_before := [llvm|
{
^0(%arg93 : i32, %arg94 : i1):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = "llvm.select"(%arg94, %arg93, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %2 = llvm.sext %1 : i32 to i64
  "llvm.return"(%2) : (i64) -> ()
}
]

def lshr_xor_after := [llvm|
{
^0(%arg65 : i8, %arg66 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.mlir.constant(-8 : i8) : i8
  %3 = llvm.srem %arg65, %0 : i8
  %4 = llvm.shl %3, %1 : i8
  %5 = llvm.and %arg66, %2 : i8
  %6 = llvm.xor %5, %4 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

def test73_after := [llvm|
{
^0(%arg32 : i32):
  %0 = llvm.mlir.constant(128 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(40 : i32) : i32
  %3 = llvm.mlir.constant(42 : i32) : i32
  %4 = llvm.and %arg32, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = "llvm.select"(%5, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def mul_may_overflow_after := [llvm|
{
^0(%arg8 : i32, %arg9 : i32):
  %0 = llvm.mlir.constant(4294967296 : i34) : i34
  %1 = llvm.zext %arg8 : i32 to i34
  %2 = llvm.zext %arg9 : i32 to i34
  %3 = llvm.mul %1, %2 : i34
  %4 = llvm.icmp "ult" %3, %0 : i34
  %5 = llvm.zext %4 : i1 to i32
  "llvm.return"(%5) : (i32) -> ()
}
]

instance : Repr Eqn := inferInstanceAs (Repr (List Term))

def BinaryRelationKind.toSmtLib : BinaryRelationKind → SexprPBV.BinaryRelationKind
| .eq => .eq
| .ne => .ne
| .ule => .ule
| .slt => .slt
| .sle => .sle
| .ult => .ult

def test_shl_nuw_nsw__nuw_is_safe_before := [llvm|
{
^0(%arg82 : i32, %arg83 : i64):
  %0 = llvm.mlir.constant(1073741822 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.and %arg82, %0 : i32
  %4 = llvm.shl %3, %1 overflow<nsw,nuw> : i32
  %5 = llvm.zext %4 : i32 to i64
  %6 = llvm.icmp "eq" %3, %2 : i32
  %7 = llvm.ashr %arg83, %5 : i64
  %8 = "llvm.select"(%6, %arg83, %7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%8) : (i64) -> ()
}
]

@[simp_llvm]
def sext? {w: Nat} (w': Nat) (x: BitVec w) : IntW w' := do
  .value <| (BitVec.signExtend w' x)

def ugt_or_not_min_commute_logical_after := [llvm|
{
^0(%arg8 : i8, %arg9 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "ne" %arg8, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def or_or_and_complex_after := [llvm|
{
^0(%arg82 : i64):
  %0 = llvm.mlir.constant(8) : i64
  %1 = llvm.mlir.constant(71777214294589695) : i64
  %2 = llvm.mlir.constant(-71777214294589696) : i64
  %3 = llvm.lshr %arg82, %0 : i64
  %4 = llvm.shl %arg82, %0 : i64
  %5 = llvm.and %3, %1 : i64
  %6 = llvm.and %4, %2 : i64
  %7 = llvm.or disjoint %5, %6 : i64
  "llvm.return"(%7) : (i64) -> ()
}
]

def ult_and_max_logical_after := [llvm|
{
^0(%arg366 : i8, %arg367 : i8):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def test3_before := [llvm|
{
^0(%arg58 : i32):
  %0 = llvm.mlir.constant(128 : i32) : i32
  %1 = llvm.mlir.constant(30 : i32) : i32
  %2 = llvm.and %arg58, %0 : i32
  %3 = llvm.lshr %arg58, %1 : i32
  %4 = llvm.add %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def PR42691_3_logical_after := [llvm|
{
^0(%arg338 : i32):
  %0 = llvm.mlir.constant(-2147483647 : i32) : i32
  %1 = llvm.icmp "ult" %arg338, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

def lor_land_right1_after := [llvm|
{
^0(%arg26 : i1, %arg27 : i1):
  "llvm.return"(%arg26) : (i1) -> ()
}
]

def test13commuted_before := [llvm|
{
^0(%arg83 : i32, %arg84 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg83, %0 : i32
  %2 = llvm.xor %arg84, %0 : i32
  %3 = llvm.and %2, %arg83 : i32
  %4 = llvm.xor %1, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def icmp_mul_nsw_sgt_after := [llvm|
{
^0(%arg15 : i8, %arg16 : i8):
  %0 = llvm.icmp "sgt" %arg15, %arg16 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

def lshrult_03_07_exact_before := [llvm|
{
^0(%arg110 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(7 : i4) : i4
  %2 = llvm.lshr exact %arg110, %0 : i4
  %3 = llvm.icmp "ult" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def or_xor_tree_0100_before := [llvm|
{
^0(%arg33 : i32, %arg34 : i32, %arg35 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mul %arg33, %0 : i32
  %2 = llvm.mul %arg34, %0 : i32
  %3 = llvm.mul %arg35, %0 : i32
  %4 = llvm.xor %1, %2 : i32
  %5 = llvm.xor %2, %3 : i32
  %6 = llvm.xor %1, %5 : i32
  %7 = llvm.or %4, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def select_of_symmetric_selects_after := [llvm|
{
^0(%arg33 : i32, %arg34 : i32, %arg35 : i1, %arg36 : i1):
  %0 = llvm.xor %arg35, %arg36 : i1
  %1 = "llvm.select"(%0, %arg34, %arg33) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def icmp_eq_x_invertable_y2_todo_after := [llvm|
{
^0(%arg3 : i8, %arg4 : i1, %arg5 : i8):
  %0 = llvm.mlir.constant(-8 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = "llvm.select"(%arg4, %0, %arg5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %3 = llvm.and %arg3, %2 : i8
  %4 = llvm.icmp "eq" %3, %1 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

def bool_add_ashr_before := [llvm|
{
^0(%arg10 : i1, %arg11 : i1):
  %0 = llvm.mlir.constant(1 : i2) : i2
  %1 = llvm.zext %arg10 : i1 to i2
  %2 = llvm.zext %arg11 : i1 to i2
  %3 = llvm.add %1, %2 : i2
  %4 = llvm.ashr %3, %0 : i2
  "llvm.return"(%4) : (i2) -> ()
}
]

def add_and_or_commutative_after := [llvm|
{
^0(%arg13 : i32, %arg14 : i32):
  %0 = llvm.add %arg13, %arg14 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

@[match_pattern] abbrev and    : Nat → LLVM.Op := MOp.and    ∘ .concrete

def select_icmp_eq_and_32_0_or_8_before := [llvm|
{
^0(%arg241 : i32, %arg242 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(8 : i32) : i32
  %3 = llvm.and %arg241, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.or %arg242, %2 : i32
  %6 = "llvm.select"(%4, %arg242, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def ashrslt_03_03_exact_before := [llvm|
{
^0(%arg18 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.ashr exact %arg18, %0 : i4
  %2 = llvm.icmp "slt" %1, %0 : i4
  "llvm.return"(%2) : (i1) -> ()
}
]

def zero_sign_bit2_after := [llvm|
{
^0(%arg29 : i16, %arg30 : i16):
  %0 = llvm.mlir.constant(32767 : i16) : i16
  %1 = llvm.and %arg29, %0 : i16
  %2 = llvm.and %arg30, %0 : i16
  %3 = llvm.add %1, %2 overflow<nuw> : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

def ne_3210_after := [llvm|
{
^0(%arg74 : i32, %arg75 : i32):
  %0 = llvm.icmp "ne" %arg74, %arg75 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

def test2_before := [llvm|
{
^0(%arg230 : i32, %arg231 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg230, %arg231 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.or %arg231, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

Pure in Init.Prelude

def src_x_and_nmask_uge_after := [llvm|
{
^0(%arg21 : i8, %arg22 : i8, %arg23 : i1):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.shl %0, %arg22 overflow<nsw> : i8
  %3 = llvm.icmp "ule" %2, %arg21 : i8
  %4 = llvm.xor %arg23, %1 : i1
  %5 = "llvm.select"(%4, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def test_simplify_decrement_invalid_ne_after := [llvm|
{
^0(%arg209 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "eq" %arg209, %0 : i8
  %2 = llvm.sext %1 : i1 to i8
  "llvm.return"(%2) : (i8) -> ()
}
]

partial def existsForAll
    [H : HydrableExistsForall parsedExpr genPred genExpr]
    (origExpr : BoolExpr genPred) (existsVars: List Nat) (forAllVars: List Nat)  (numExamples: Nat := 1) :
    GeneralizerStateM parsedExpr genPred (List (Std.HashMap Nat BVExpr.PackedBitVec)) := do

    let rec constantsSynthesis (bvExpr: BoolExpr genPred) (existsVars: List Nat) (forAllVars: List Nat)
            : GeneralizerStateM parsedExpr genPred (Option (Std.HashMap Nat BVExpr.PackedBitVec)) := do
      let existsRes ← solve bvExpr

      match existsRes with
        | none => trace[Generalize] m! "Could not satisfy exists formula for {bvExpr}"
                  return none
        | some assignment =>
          let existsVals := assignment.filter fun c _ => existsVars.contains c
          let substExpr := subsituteGenLogicalExpr bvExpr (H.packedBitVecToSubstitutionValue existsVals)
          let forAllRes ← solve (BoolExpr.not substExpr)

          match forAllRes with
            | none =>
              return some existsVals
            | some counterEx =>
                let newExpr := subsituteGenLogicalExpr bvExpr (H.packedBitVecToSubstitutionValue counterEx)
                constantsSynthesis (BoolExpr.gate .and bvExpr newExpr) existsVars forAllVars

    let mut res : List (Std.HashMap Nat BVExpr.PackedBitVec) := []
    let identityAndAbsorptionConstraints := getIdentityAndAbsorptionConstraints origExpr (Std.HashSet.ofList existsVars)
    let targetExpr := (BoolExpr.gate .and origExpr (bigAnd (identityAndAbsorptionConstraints)))

    match numExamples with
    | 0 => return res
    | n + 1 =>  let consts ← constantsSynthesis targetExpr existsVars forAllVars
                match consts with
                | none => return res
                | some assignment =>
                      res := assignment :: res
                      let newConstraints := assignment.toList.map (fun c => H.eq (H.genExprVar c.fst) (H.genExprConst c.snd.bv))
                      let constrainedBVExpr := BoolExpr.not (bigAnd newConstraints)
                      return res ++ (← existsForAll (BoolExpr.gate .and origExpr constrainedBVExpr) existsVars forAllVars n)

def lshrugt_02_12_after := [llvm|
{
^0(%arg387 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def not_lshr_bitwidth_mask_before := [llvm|
{
^0(%arg95 : i8, %arg96 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.lshr %arg95, %0 : i8
  %3 = llvm.xor %2, %1 : i8
  %4 = llvm.and %3, %arg96 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def debugCheck (e : Expr) : SolverM Unit := do
    if ← check?
    then
      check e
    else return ()

def or_signbit_ashr_before := [llvm|
{
^0(%arg5 : i32):
  %0 = llvm.mlir.constant(-65536 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.or %arg5, %0 : i32
  %3 = llvm.ashr %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def udiv_shl_shl_nuw_nsw2_before := [llvm|
{
^0(%arg55 : i8, %arg56 : i8, %arg57 : i8):
  %0 = llvm.shl %arg55, %arg57 overflow<nsw,nuw> : i8
  %1 = llvm.shl %arg56, %arg57 overflow<nsw> : i8
  %2 = llvm.udiv %0, %1 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def test3_after := [llvm|
{
^0(%arg10 : i15):
  "llvm.return"(%arg10) : (i15) -> ()
}
]

def negate_lshr_after := [llvm|
{
^0(%arg108 : i8, %arg109 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.ashr %arg109, %0 : i8
  %2 = llvm.add %1, %arg108 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def List.product (l₁ : List α) (l₂ : List β) : List (α × β) := l₁.flatMap fun a => l₂.map (Prod.mk a)

def andn_or_cmp_2_before := [llvm|
{
^0(%arg170 : i16, %arg171 : i16, %arg172 : i16):
  %0 = llvm.mlir.constant(42 : i16) : i16
  %1 = llvm.icmp "sge" %arg170, %arg171 : i16
  %2 = llvm.icmp "slt" %arg170, %arg171 : i16
  %3 = llvm.icmp "ugt" %arg172, %0 : i16
  %4 = llvm.or %3, %1 : i1
  %5 = llvm.and %4, %2 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def select_and_icmp_zero_after := [llvm|
{
^0(%arg152 : i32, %arg153 : i32, %arg154 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "eq" %arg152, %0 : i32
  %2 = "llvm.select"(%1, %0, %arg153) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def c_0_1_0_after := [llvm|
{
^0(%arg18 : i4, %arg19 : i4):
  %0 = llvm.mlir.constant(-2 : i4) : i4
  %1 = llvm.mlir.constant(1 : i4) : i4
  %2 = llvm.and %arg19, %0 : i4
  %3 = llvm.and %arg18, %1 : i4
  %4 = llvm.or disjoint %2, %3 : i4
  "llvm.return"(%4) : (i4) -> ()
}
]

def matchArg [DecidableEq d.Op]
    (lets : Lets d Γ_in eff Γ_out) (matchLets : Lets d Δ_in .pure Δ_out) :
    {l : List d.Ty} → HVector (Var Γ_out) l → HVector (Var Δ_out) l →
    MatchVar Δ_in Γ_out
  | _, .nil, .nil => return
  | t::l, .cons vₗ vsₗ, .cons vᵣ vsᵣ => do
      matchVar (t := t) lets vₗ matchLets vᵣ
      matchArg lets matchLets vsₗ vsᵣ
  termination_by l => (sizeOf matchLets, l.length + 1)

def constLLVM_35 : Com LLVMPlusRiscV ⟨[]⟩ .pure (.llvm (.bitvec 64)) := [LV| {
  ^entry ():
    %1 = llvm.mlir.constant (-35) : i64
    llvm.return %1 : i64
  }]

def mkExpr (Γ : Ctxt _) (opStx : MLIR.AST.Op 0) :
    MLIR.AST.ReaderM (Handshake) (Σ eff ty, Expr (Handshake) Γ eff ty) := do
  match opStx.name with
  | op@"handshake.branch" | op@"handshake.merge" =>
    match opStx.args with
    | v₁Stx::v₂Stx::[] =>
      let ⟨ty₁, v₁⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₁Stx
      let ⟨ty₂, v₂⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₂Stx
      match ty₁, ty₂, op with
      | .stream r₁, .stream (.bitvec 1), "handshake.branch" => return ⟨_, [.stream2 r₁], @branch r₁ _ v₁ v₂⟩
      
      | .stream r₁, _, "handshake.merge" => return ⟨_, [.stream r₁], merge v₁ v₁⟩
      | _, _, _ => throw <| .generic s!"type mismatch"
    | _ => throw <| .generic s!"expected two operands for `monomial`, found #'{opStx.args.length}' in '{repr opStx.args}'"
  | op@"handshake.fst" | op@"handshake.snd" =>
    match opStx.args with
    | v₁Stx::[] =>
      let ⟨ty₁, v₁⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₁Stx
      match ty₁, op with
      | .stream2 r, "handshake.fst" => return ⟨_, [.stream r], fst v₁⟩
      | .stream2 r, "handshake.snd"  => return ⟨_, [.stream r], snd v₁⟩
      | _, _ => throw <| .generic s!"type mismatch"
    | _ => throw <| .generic s!"expected two operands for `monomial`, found #'{opStx.args.length}' in '{repr opStx.args}'"
  | op@"handshake.not" =>
    match opStx.args with
    | v₁Stx::[] =>
      let ⟨ty₁, v₁⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₁Stx
      match ty₁, op with
      | .stream (.bitvec 1), "handshake.not" => return ⟨_, [.stream (.bitvec 1)], not v₁⟩
      | _, _ => throw <| .generic s!"type mismatch"
    | _ => throw <| .generic s!"expected one operand for `monomial`, found #'{opStx.args.length}' in '{repr opStx.args}'"
  | op@"handshake.supp" =>
    match opStx.args with
    | v₁Stx::v₂Stx::[] =>
      let ⟨ty₁, v₁⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₁Stx
      let ⟨ty₂, v₂⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₂Stx
      match ty₁, ty₂, op with
      | .stream r, .stream (.bitvec 1), "handshake.supp" => return ⟨_, [.stream r], supp v₁ v₂⟩
      | _, _, _ => throw <| .generic s!"type mismatch"
    | _ => throw <| .generic s!"expected one operand for `monomial`, found #'{opStx.args.length}' in '{repr opStx.args}'"
  | op@"handshake.sync" =>
    match opStx.args with
    | v₁Stx::v₂Stx::[] =>
      let ⟨ty₁, v₁⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₁Stx
      let ⟨ty₂, v₂⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₂Stx
      match ty₁, ty₂, op with
      | .stream r₁, .stream r₂, "handshake.sync" =>
        if h : r₁ = r₂ then
          have h': Γ.Var (Ty.stream r₁) = Γ.Var (Ty.stream r₂) := by admit /- proof elided -/

def bitwise_and_logical_and_masked_icmp_allones_after := [llvm|
{
^0(%arg139 : i1, %arg140 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.and %arg140, %0 : i32
  %3 = llvm.icmp "eq" %2, %0 : i32
  %4 = "llvm.select"(%3, %arg139, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def ashr_lshr_no_ashr_after := [llvm|
{
^0(%arg75 : i32, %arg76 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.lshr %arg75, %arg76 : i32
  %2 = llvm.xor %arg75, %arg76 : i32
  %3 = llvm.icmp "slt" %arg75, %0 : i32
  %4 = "llvm.select"(%3, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def slt_and_not_max_commute_before := [llvm|
{
^0(%arg122 : i8, %arg123 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.icmp "slt" %arg122, %arg123 : i8
  %2 = llvm.icmp "ne" %arg122, %0 : i8
  %3 = llvm.and %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def instantiateOne (a : α) : ConcreteOrMVar α (φ+1) → ConcreteOrMVar α φ
  | .concrete w => .concrete w
  | .mvar i => i.lastCases
      (.concrete a)       
      (fun j => .mvar j)  

def test9_before := [llvm|
{
^0(%arg72 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.and %arg72, %0 : i32
  %2 = llvm.trunc %1 : i32 to i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def llvm_const_lower_riscv_li24 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM24, rhs:= liRiscv24,
   correct := by admit /- proof elided -/

def trunc_sandwich_max_sum_shift2_before := [llvm|
{
^0(%arg65 : i32):
  %0 = llvm.mlir.constant(30 : i32) : i32
  %1 = llvm.mlir.constant(1 : i12) : i12
  %2 = llvm.lshr %arg65, %0 : i32
  %3 = llvm.trunc %2 : i32 to i12
  %4 = llvm.lshr %3, %1 : i12
  "llvm.return"(%4) : (i12) -> ()
}
]

def or_not_and_and_not_and_xor_after := [llvm|
{
^0(%arg289 : i32, %arg290 : i32, %arg291 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg290, %arg291 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.or %arg289, %2 : i32
  %4 = llvm.xor %arg290, %arg291 : i32
  %5 = llvm.and %4, %arg289 : i32
  %6 = llvm.xor %5, %3 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

instance : Min EffectKind where
  min := inf

def test4_after := [llvm|
{
^0(%arg206 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def icmp_sle_x_negy_before := [llvm|
{
^0(%arg28 : i8, %arg29 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.or %arg29, %0 : i8
  %2 = llvm.and %1, %arg28 : i8
  %3 = llvm.icmp "sle" %2, %arg28 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def eg₀val := Com.denote eg₀ Ctxt.Valuation.nil

def set_to_set_decomposebittest_after := [llvm|
{
^0(%arg11 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.and %arg11, %0 : i8
  %3 = llvm.or disjoint %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def parseAsRiscv (fileName : String ) : IO UInt32 := do
  let icom? ← Com.parseFromFile RV64 fileName
  match icom? with
  | none => return 1
  | some (Sigma.mk _Γ ⟨_eff, ⟨_retTy, c⟩⟩) => do
    IO.println c.printModule
    return 0

def masked_or_allzeroes_notoptimised_logical_after := [llvm|
{
^0(%arg116 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(39 : i32) : i32
  %3 = llvm.and %arg116, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.and %arg116, %2 : i32
  %6 = llvm.icmp "eq" %5, %1 : i32
  %7 = llvm.or %4, %6 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

def sub_0xffffffffff_i64_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := sub_0xffffffffff_llvm_i64
  rhs :=  sub_0xffffffffff_riscv_i64

def main4f_like_logical_after := [llvm|
{
^0(%arg115 : i32, %arg116 : i32, %arg117 : i32):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.and %arg115, %arg116 : i32
  %2 = llvm.icmp "eq" %1, %arg116 : i32
  %3 = llvm.and %arg115, %arg117 : i32
  %4 = llvm.icmp "eq" %3, %arg117 : i32
  %5 = "llvm.select"(%2, %4, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %6 = llvm.zext %5 : i1 to i32
  "llvm.return"(%6) : (i32) -> ()
}
]

instance : DialectToExpr DC where
  toExprM := .const ``Id [0]
  toExprDialect := .const ``DC []

structure BlockId where
  id : Nat
  deriving DecidableEq, Hashable, Inhabited

def or_logic_or_logic_and_6_after := [llvm|
{
^0(%arg33 : i1, %arg34 : i1, %arg35 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = "llvm.select"(%arg34, %arg35, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = "llvm.select"(%arg33, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def or_eq_with_one_bit_diff_constants1_logical_before := [llvm|
{
^0(%arg365 : i32):
  %0 = llvm.mlir.constant(50 : i32) : i32
  %1 = llvm.mlir.constant(51 : i32) : i32
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.icmp "eq" %arg365, %0 : i32
  %4 = llvm.icmp "eq" %arg365, %1 : i32
  %5 = "llvm.select"(%3, %2, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def test5_apint_after := [llvm|
{
^0(%arg40 : i71, %arg41 : i71):
  %0 = llvm.and %arg40, %arg41 : i71
  "llvm.return"(%0) : (i71) -> ()
}
]

def select_exact_lshr_icmp_const_after := [llvm|
{
^0(%arg146 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.lshr %arg146, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def positive_easyinvert_after := [llvm|
{
^0(%arg7 : i16, %arg8 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i16) : i16
  %2 = llvm.icmp "slt" %arg8, %0 : i8
  %3 = llvm.icmp "sgt" %arg7, %1 : i16
  %4 = llvm.xor %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def squared_nsw_eq0_after := [llvm|
{
^0(%arg185 : i5):
  %0 = llvm.mlir.constant(0 : i5) : i5
  %1 = llvm.icmp "eq" %arg185, %0 : i5
  "llvm.return"(%1) : (i1) -> ()
}
]

def test_after := [llvm|
{
  %0 = llvm.mlir.constant(0 : i32) : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def test3a_before := [llvm|
{
^0(%arg100 : i32):
  %0 = llvm.mlir.constant(-8 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.srem %arg100, %0 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def function : Parser :=
  leading_parser argumentList >> arrow >> termParser

def testi32i8_after := [llvm|
{
^0(%arg32 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(7 : i8) : i8
  %2 = llvm.mlir.constant(15 : i32) : i32
  %3 = llvm.mlir.constant(127 : i8) : i8
  %4 = llvm.lshr %arg32, %0 : i32
  %5 = llvm.trunc %4 : i32 to i8
  %6 = llvm.trunc %arg32 : i32 to i8
  %7 = llvm.ashr %6, %1 : i8
  %8 = llvm.icmp "eq" %7, %5 : i8
  %9 = llvm.lshr %arg32, %2 : i32
  %10 = llvm.trunc %9 : i32 to i8
  %11 = llvm.xor %10, %3 : i8
  %12 = "llvm.select"(%8, %6, %11) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%12) : (i8) -> ()
}
]

def xor_signbit_shl_before := [llvm|
{
^0(%arg19 : i32):
  %0 = llvm.mlir.constant(-65536 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.xor %arg19, %0 : i32
  %3 = llvm.shl %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def llvm_shl_lower_riscv_nsw_8: LLVMPeepholeRewriteRefine 8 [Ty.llvm (.bitvec 8), Ty.llvm (.bitvec 8)] where
  lhs := shl_llvm_nsw_8
  rhs := shl_riscv_8

def llvm_or_lower_riscv_noflag_64 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := or_llvm_noflag_64
  rhs := or_riscv_64

def test_logical_and_ne_a_b_before := [llvm|
{
^0(%arg3 : i1, %arg4 : i8, %arg5 : i8):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.icmp "ne" %arg4, %arg5 : i8
  %2 = "llvm.select"(%arg3, %1, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = "llvm.select"(%2, %arg4, %arg5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def ripple_nsw1_before := [llvm|
{
^0(%arg23 : i16, %arg24 : i16):
  %0 = llvm.mlir.constant(1 : i16) : i16
  %1 = llvm.mlir.constant(-16385 : i16) : i16
  %2 = llvm.and %arg24, %0 : i16
  %3 = llvm.and %arg23, %1 : i16
  %4 = llvm.add %2, %3 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

def t10_shift_by_one_before := [llvm|
{
^0(%arg16 : i32, %arg17 : i64, %arg18 : i32):
  %0 = llvm.mlir.constant(64 : i32) : i32
  %1 = llvm.mlir.constant(-63 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.sub %0, %arg18 : i32
  %4 = llvm.shl %arg16, %3 : i32
  %5 = llvm.add %arg18, %1 : i32
  %6 = llvm.zext %5 : i32 to i64
  %7 = llvm.lshr %arg17, %6 : i64
  %8 = llvm.trunc %7 : i64 to i32
  %9 = llvm.and %4, %8 : i32
  %10 = llvm.icmp "ne" %9, %2 : i32
  "llvm.return"(%10) : (i1) -> ()
}
]

def not_not_cmp_after := [llvm|
{
^0(%arg147 : i32, %arg148 : i32):
  %0 = llvm.icmp "sgt" %arg147, %arg148 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

def lshrugt_03_05_exact_after := [llvm|
{
^0(%arg184 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3_logical_after := [llvm|
{
^0(%arg21 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.and %arg21, %0 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def t11_no_shift_after := [llvm|
{
^0(%arg19 : i32, %arg20 : i64, %arg21 : i32):
  %0 = llvm.mlir.constant(0) : i64
  %1 = llvm.zext %arg19 : i32 to i64
  %2 = llvm.and %arg20, %1 : i64
  %3 = llvm.icmp "ne" %2, %0 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

def and_not_or_or_not_or_xor_commute4_after := [llvm|
{
^0(%arg313 : i32, %arg314 : i32, %arg315 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg313 : i32
  %3 = llvm.or %arg314, %arg315 : i32
  %4 = llvm.xor %arg314, %arg315 : i32
  %5 = llvm.or %2, %4 : i32
  %6 = llvm.and %3, %5 : i32
  %7 = llvm.xor %6, %1 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def sle_swap_and_min_logical_after := [llvm|
{
^0(%arg212 : i8, %arg213 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.icmp "eq" %arg212, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

class DialectPrint (d : Dialect) where
   
  printOpName : d.Op → String
   
  printAttributes : d.Op → String

   
  printTy : d.Ty → String

   
  dialectName : String
  

   
  printReturn : List d.Ty → String
   
  printFunc : List d.Ty → String := fun _ => "^entry"

@[simp_denote]
def srli_demandedbits_riscv_i32 :=
  [LV| {
    ^entry (%arg: i32):
    %a = "builtin.unrealized_conversion_cast" (%arg) : (i32) -> (!i64)
    %0 = srliw %a, 3 : !i64
    %1 = ori %0, 1 : !i64
    %2 = "builtin.unrealized_conversion_cast" (%1) : (!i64) -> (i32)
    llvm.return %2 : i32
  }]

def shl_xor_xor_good_mask_after := [llvm|
{
^0(%arg100 : i8, %arg101 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(88 : i8) : i8
  %2 = llvm.xor %arg101, %arg100 : i8
  %3 = llvm.shl %2, %0 : i8
  %4 = llvm.xor %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def or_and_not_constant_commute3_before := [llvm|
{
^0(%arg106 : i32, %arg107 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(-2 : i32) : i32
  %2 = llvm.or %arg106, %arg107 : i32
  %3 = llvm.and %0, %2 : i32
  %4 = llvm.and %1, %arg107 : i32
  %5 = llvm.or %4, %3 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def t8_lshr_exact_flag_preservation_after := [llvm|
{
^0(%arg27 : i32, %arg28 : i32):
  %0 = llvm.mlir.constant(30 : i32) : i32
  %1 = llvm.lshr exact %arg27, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def precondSynthesisUpdateCache (previousLevelCache synthesisComponents: Std.HashMap (FpExpr w)  PreconditionSynthesisCacheValue)
      (positiveExamples negativeExamples: List (Std.HashMap Nat FpExprWrapper)) (specialConstants : Std.HashMap (FpExpr w) FpExprWrapper)
      (ops : List (FpExpr w → FpExpr w → FpExpr w)) : GeneralizerStateM ParsedFpExpr FpPredicate (Std.HashMap (FpExpr w) PreconditionSynthesisCacheValue) := do
  return {}

def sle_swap_or_not_min_after := [llvm|
{
^0(%arg280 : i8, %arg281 : i8):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def add_constant_equal_with_the_top_bit_of_demandedbits_pass_before := [llvm|
{
^0(%arg9 : i32):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.mlir.constant(24 : i32) : i32
  %2 = llvm.add %arg9, %0 : i32
  %3 = llvm.and %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def scalar_i32_signbit_lshr_and_eq_after := [llvm|
{
^0(%arg31 : i32, %arg32 : i32):
  %0 = llvm.mlir.constant(-2147483648 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.lshr exact %0, %arg32 : i32
  %3 = llvm.and %2, %arg31 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def test51_before := [llvm|
{
^0(%arg133 : i64, %arg134 : i1):
  %0 = llvm.mlir.constant(-2 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.trunc %arg133 : i64 to i32
  %3 = llvm.and %2, %0 : i32
  %4 = llvm.or %2, %1 : i32
  %5 = "llvm.select"(%arg134, %3, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %6 = llvm.sext %5 : i32 to i64
  "llvm.return"(%6) : (i64) -> ()
}
]

def llvm_const_lower_riscv_li38 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM38, rhs:= liRiscv38,
   correct := by admit /- proof elided -/

def State.cseExpr
 {Γstart Γ : Ctxt d.Ty}
 {lets : Lets d Γstart .pure Γ}
 (s : State d lets)
 (e : Expr d Γ .pure α) :
 {e' : Expr d Γ .pure α //
  ∀ (V : Γstart.Valuation), e'.denote (lets.denote V) =
    e.denote (lets.denote V) }
    × Option ({ v' : HVector Γ.Var α // ∀ (V : Γstart.Valuation),
      v'.map (lets.denote V) = e.denoteOp (lets.denote V) }) :=
  match E : e with
  | .mk op ty_eq eff_le args regArgs =>
      let ⟨args', hargs'⟩ := s.cseArgList args
      let regArgs' := s.cseRegionArgList regArgs
      let ⟨regArgs', hregArgs'⟩ := regArgs'
      let e' : Expr d Γ .pure α  := .mk op ty_eq eff_le args' regArgs'
      ⟨⟨e', by admit /- proof elided -/
      ⟩,
        match s.expr2cache _ e with
        | .some ⟨v', hv'⟩ =>
          .some ⟨v', by admit /- proof elided -/
          ⟩
        | .none => .none
      ⟩

def zext_sext_add_icmp_eq_1_before := [llvm|
{
^0(%arg72 : i1, %arg73 : i1):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.zext %arg72 : i1 to i8
  %2 = llvm.sext %arg73 : i1 to i8
  %3 = llvm.add %1, %2 : i8
  %4 = llvm.icmp "eq" %3, %0 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

def add_and_or_commutative_before := [llvm|
{
^0(%arg13 : i32, %arg14 : i32):
  %0 = llvm.or %arg13, %arg14 : i32
  %1 = llvm.and %arg14, %arg13 : i32
  %2 = llvm.add %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def sub_to_add_2 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant 2 : i64
      %1 = llvm.sub %x, %c : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant -2 : i64
      %1 = llvm.add %x, %c : i64
      llvm.return %1 : i64
  }]

def signbit_splat_mask_before := [llvm|
{
^0(%arg117 : i8, %arg118 : i16):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.ashr %arg117, %0 : i8
  %2 = llvm.sext %1 : i8 to i16
  %3 = llvm.and %2, %arg118 : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

def not_ashr_bitwidth_mask_after := [llvm|
{
^0(%arg105 : i8, %arg106 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "slt" %arg105, %0 : i8
  %2 = "llvm.select"(%1, %0, %arg106) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%2) : (i8) -> ()
}
]

instance : DecidableEq BlockLabel :=

def fold_inverted_icmp_preds_before := [llvm|
{
^0(%arg97 : i32, %arg98 : i32, %arg99 : i32, %arg100 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "slt" %arg97, %arg98 : i32
  %2 = "llvm.select"(%1, %arg99, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %3 = llvm.icmp "sge" %arg97, %arg98 : i32
  %4 = "llvm.select"(%3, %arg100, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %5 = llvm.or %2, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def test19_commutative0_before := [llvm|
{
^0(%arg74 : i32, %arg75 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.shl %0, %arg74 : i32
  %2 = llvm.shl %0, %arg75 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.add %3, %1 : i32
  %5 = llvm.urem %arg75, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def and_logic_and_logic_or_8_after := [llvm|
{
^0(%arg117 : i1, %arg118 : i1, %arg119 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = "llvm.select"(%arg119, %0, %arg118) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %2 = llvm.and %arg117, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

def sextbool_add_commute_before := [llvm|
{
^0(%arg10 : i1, %arg11 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.urem %arg11, %0 : i32
  %2 = llvm.sext %arg10 : i1 to i32
  %3 = llvm.add %1, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def icmp_eq_mul_nsw_nonequal_commuted_before := [llvm|
{
^0(%arg30 : i8, %arg31 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.add %arg30, %0 : i8
  %2 = llvm.mul %arg30, %arg31 overflow<nsw> : i8
  %3 = llvm.mul %arg31, %1 overflow<nsw> : i8
  %4 = llvm.icmp "eq" %2, %3 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

abbrev Term.Ctx.Env
  (tctx : Term.Ctx wcard tcard)
  (wenv : WidthExpr.Env wcard) :=
  (v : Fin tcard) → BitVec ((tctx v).toNat wenv)

def lshr_shl_pow2_const_case1_before := [llvm|
{
^0(%arg60 : i16):
  %0 = llvm.mlir.constant(256 : i16) : i16
  %1 = llvm.mlir.constant(2 : i16) : i16
  %2 = llvm.mlir.constant(8 : i16) : i16
  %3 = llvm.lshr %0, %arg60 : i16
  %4 = llvm.shl %3, %1 : i16
  %5 = llvm.and %4, %2 : i16
  "llvm.return"(%5) : (i16) -> ()
}
]

def select_bittest_to_shl_negative_test_after := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(4 : i32) : i32
  %3 = llvm.mlir.constant(6 : i32) : i32
  %4 = llvm.and %arg0, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = "llvm.select"(%5, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def lshrult_01_05_exact_after := [llvm|
{
^0(%arg144 : i4):
  %0 = llvm.mlir.constant(-6 : i4) : i4
  %1 = llvm.icmp "ult" %arg144, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

def positive_with_signbit_logical_after := [llvm|
{
^0(%arg61 : i32):
  %0 = llvm.mlir.constant(128 : i32) : i32
  %1 = llvm.icmp "ult" %arg61, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

def scalar_i8_shl_uge_const_before := [llvm|
{
^0(%arg13 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.mlir.constant(64 : i8) : i8
  %2 = llvm.shl %arg13, %0 : i8
  %3 = llvm.icmp "uge" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def scalar_i32_lshr_and_negC_eq_X_is_constant1_after := [llvm|
{
^0(%arg9 : i32):
  %0 = llvm.mlir.constant(12345 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.lshr %0, %arg9 : i32
  %3 = llvm.icmp "ult" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def select_icmp_ne_0_and_4096_xor_4096_before := [llvm|
{
^0(%arg229 : i32, %arg230 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg229, %0 : i32
  %3 = llvm.icmp "ne" %1, %2 : i32
  %4 = llvm.xor %arg230, %0 : i32
  %5 = "llvm.select"(%3, %arg230, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def test_or1_before := [llvm|
{
^0(%arg36 : i32, %arg37 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg37, %0 : i32
  %3 = llvm.icmp "slt" %arg36, %1 : i32
  %4 = llvm.icmp "sge" %arg36, %2 : i32
  %5 = llvm.or %3, %4 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def corrected_ISEL_pattern : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs:= original_sdiv_srem_correct
  rhs:= combined_sdiv_srem_correct
  correct := by admit /- proof elided -/

def t1_before := [llvm|
{
^0(%arg12 : i4):
  %0 = llvm.mlir.constant(-4 : i4) : i4
  %1 = llvm.mlir.constant(-6 : i4) : i4
  %2 = llvm.or %arg12, %0 : i4
  %3 = llvm.xor %2, %1 : i4
  "llvm.return"(%3) : (i4) -> ()
}
]

def t8_after := [llvm|
{
^0(%arg5 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "eq" %arg5, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def lshrult_01_02_after := [llvm|
{
^0(%arg365 : i4):
  %0 = llvm.mlir.constant(4 : i4) : i4
  %1 = llvm.icmp "ult" %arg365, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

def and_i32_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := and_llvm_i64
  rhs := and_riscv_i64

def or_umin_after := [llvm|
{
^0(%arg4 : i32):
  %0 = llvm.mlir.constant(31 : i32) : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def eq_smin2_after := [llvm|
{
^0(%arg85 : i32, %arg86 : i32):
  %0 = llvm.icmp "sle" %arg85, %arg86 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

BitVec.sub in Init.Data.BitVec.BasicAux

def add_smax_simplify_after := [llvm|
{
^0(%arg25 : i8):
  %0 = llvm.mlir.constant(126 : i8) : i8
  %1 = llvm.add %arg25, %0 overflow<nsw> : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

List.Perm in Init.Data.List.Basic

def fold_sext_to_and_wrong10_after := [llvm|
{
^0(%arg0 : i8):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def or_and_xor_not_constant_commute0_after := [llvm|
{
^0(%arg168 : i32, %arg169 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.and %arg168, %0 : i32
  %2 = llvm.xor %1, %arg169 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

Monad in Init.Prelude

def f_after := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def genTable.getGenTable (n : Name) (args : Array Expr) : GenM (Option (Array Bool)) := do
  
  
  if n == ``BitVec then
    if hx : args.size ≠ 1 then
      throwError "BitVec expected 1 argument, got {args.size}"
    else
      
      if let some 1 ← Meta.getNatValue? args[0] then
        return some #[false]
      
      return some #[true]
  
  

  let constInfo ← getConstInfo n
  let ty := constInfo.type
  withTraceNode `WidthGeneralize
    (fun _ => return m!"genTable.getGenTable for {n}") do
      forallTelescope ty fun xs ret => do
        trace[WidthGeneralize] m!"getGenTable for {n} : {xs} → {ret}"
        let mut widths : Std.HashSet Expr := {}
        for x in xs do
          let ty ← inferType x
          
          
          
          
          trace[WidthGeneralize] m!"inspecting arg {x} : {ty}"
          widths ← getBitVecTypeWidths ty widths
        
        
        
        
        widths ← getBitVecTypeWidths ret widths
        trace[WidthGeneralize] m!"found concrete widths: {widths.toArray}"
        let mut out := #[]
        for (x, arg) in xs.zip args do
          
          if let some 1 ← getNatValue? arg then
            trace[WidthGeneralize] m!"arg {arg} is BitVec 1, skipping width generalization"
            out := out.push false
            continue
          let x ← whnf x
          let isWidth := widths.contains x
          trace[WidthGeneralize] m!"inspecting concrete arg {x} isWidth: {isWidth}"
          out := out.push isWidth
        trace[WidthGeneralize] m!"genTable for {n} @ {out}"
        return some out

def mkCarryAssignCircuitNAux {arity : Type _}
  [DecidableEq arity]
  [Fintype arity]
  [Hashable arity]
  (p : FSM arity) (s : p.α) (n : Nat) : Circuit (Vars p.α arity (n + 1)) :=
    (p.nextStateCirc s).map fun v =>
      match v with
        | .inl t => Vars.stateN t n
        | .inr i => Vars.inputN i n

def RawCNFA.transBV' (m : RawCNFA A) (res : BitVec m.stateMax) (s : m.states) (a : A) : BitVec m.stateMax :=
  let ts := m.tr s a
  ts.fold (init := res) fun res s => res ||| 1#m.stateMax <<< s

def canonicalize_icmp_eq_3 : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant 3 : i64
      %1 = llvm.icmp.eq %c, %x : i64
      llvm.return %1 : i1
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant 3 : i64
      %1 = llvm.icmp.eq %x, %c : i64
      llvm.return %1 : i1
  }]

def accepts (M : NFA' n) : Set (BitVecs n) := dec '' M.accepts'

def ult_swap_or_not_max_commute_before := [llvm|
{
^0(%arg34 : i8, %arg35 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.icmp "ugt" %arg35, %arg34 : i8
  %2 = llvm.icmp "ne" %arg34, %0 : i8
  %3 = llvm.or %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def x : DCOp.ValueStream (BitVec 8) := ofList [some 1, none, some 2, some 5, none]

def uge_swap_and_max_commute_before := [llvm|
{
^0(%arg226 : i8, %arg227 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.icmp "ule" %arg227, %arg226 : i8
  %2 = llvm.icmp "eq" %arg226, %0 : i8
  %3 = llvm.and %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def Body.return : (body : Body Op Γ ty) → Var body.returnContext ty
  | ⟨⟨_, ret⟩, h⟩ => ⟨ret, by admit /- proof elided -/
  ⟩

def shl_nsw_add_negative_before := [llvm|
{
^0(%arg45 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.add %arg45, %0 : i32
  %3 = llvm.shl %1, %2 overflow<nsw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

@[reducible]
instance : TyDenote ExTy where
  toType
    | .nat => Nat

def rewritePeephole_go (fuel : ℕ) (pr : PeepholeRewrite d Γ t)
    (ix : ℕ) (target : Com d Γ₂ eff t₂) : (Com d Γ₂ eff t₂) :=
  match fuel with
  | 0 => target
  | fuel' + 1 =>
     let target' := rewritePeepholeAt pr ix target
     rewritePeephole_go fuel' pr (ix + 1) target'

def test_add_nuw_nsw__nsw_is_safe_after := [llvm|
{
^0(%arg39 : i32):
  %0 = llvm.mlir.constant(-2147483648 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.or %arg39, %0 : i32
  %3 = llvm.add %2, %1 overflow<nsw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def sext_ule_sext_after := [llvm|
{
^0(%arg119 : i1, %arg120 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mul %arg120, %arg120 : i8
  %2 = llvm.icmp "eq" %1, %0 : i8
  %3 = llvm.or %2, %arg119 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def div {Γ : Ctxt _} (e₁ e₂: Ctxt.Var Γ .bv) : Expr RV64 Γ .pure [.bv]  :=
  Expr.mk
    (op := Op.div)
    (eff_le := by admit /- proof elided -/
    )
    (ty_eq := by admit /- proof elided -/
    )
    (args := .cons e₁ <| .cons e₂ .nil)
    (regArgs := HVector.nil)

def or_or_xor_commute1_before := [llvm|
{
^0(%arg103 : i4, %arg104 : i4, %arg105 : i4):
  %0 = llvm.or %arg103, %arg105 : i4
  %1 = llvm.or %arg105, %arg104 : i4
  %2 = llvm.xor %0, %1 : i4
  "llvm.return"(%2) : (i4) -> ()
}
]

def trunc_shl_15_i16_i64_before := [llvm|
{
^0(%arg39 : i64):
  %0 = llvm.mlir.constant(15) : i64
  %1 = llvm.shl %arg39, %0 : i64
  %2 = llvm.trunc %1 : i64 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

def sdiv_icmp6_after := [llvm|
{
^0(%arg8 : i64):
  %0 = llvm.mlir.constant(5) : i64
  %1 = llvm.icmp "eq" %arg8, %0 : i64
  "llvm.return"(%1) : (i1) -> ()
}
]

def ashrsgt_01_12_after := [llvm|
{
^0(%arg305 : i4):
  %0 = llvm.mlir.constant(-7 : i4) : i4
  %1 = llvm.icmp "sgt" %arg305, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

def neg_mask1_lshr_before := [llvm|
{
^0(%arg22 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.lshr %arg22, %0 : i8
  %4 = llvm.and %3, %1 : i8
  %5 = llvm.sub %2, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def lshr_or_before := [llvm|
{
^0(%arg69 : i8, %arg70 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(4 : i8) : i8
  %2 = llvm.srem %arg69, %0 : i8
  %3 = llvm.lshr %arg70, %1 : i8
  %4 = llvm.or %2, %3 : i8
  %5 = llvm.shl %4, %1 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def masked_icmps_mask_notallzeros_bmask_mixed_swapped_1b_logical_before := [llvm|
{
^0(%arg47 : i32):
  %0 = llvm.mlir.constant(14 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(3 : i32) : i32
  %3 = llvm.mlir.constant(1 : i32) : i32
  %4 = llvm.mlir.constant(false) : i1
  %5 = llvm.and %arg47, %0 : i32
  %6 = llvm.icmp "ne" %5, %1 : i32
  %7 = llvm.and %arg47, %2 : i32
  %8 = llvm.icmp "eq" %7, %3 : i32
  %9 = "llvm.select"(%8, %6, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%9) : (i1) -> ()
}
]

@[simp_denote]
def add_llvm_nuw_flags_8 := [LV| {
  ^entry (%lhs: i8, %rhs: i8):
    %1 = llvm.add %lhs, %rhs overflow<nuw> : i8
    llvm.return %1 : i8
  }]

def test_lshr_exact__exact_is_unsafe_before := [llvm|
{
^0(%arg58 : i32, %arg59 : i64):
  %0 = llvm.mlir.constant(63 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.and %arg58, %0 : i32
  %4 = llvm.lshr exact %3, %1 : i32
  %5 = llvm.zext %4 : i32 to i64
  %6 = llvm.icmp "eq" %3, %2 : i32
  %7 = llvm.ashr %arg59, %5 : i64
  %8 = "llvm.select"(%6, %arg59, %7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%8) : (i64) -> ()
}
]

def trunc_shl_1_i32_i64_after := [llvm|
{
^0(%arg50 : i64):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.trunc %arg50 : i64 to i32
  %2 = llvm.shl %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def sub_const_add_const_before := [llvm|
{
^0(%arg45 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.sub %arg45, %0 : i32
  %3 = llvm.add %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def ugt_swap_or_not_min_commute_logical_after := [llvm|
{
^0(%arg0 : i823, %arg1 : i823):
  %0 = llvm.mlir.constant(0 : i823) : i823
  %1 = llvm.icmp "ne" %arg0, %0 : i823
  "llvm.return"(%1) : (i1) -> ()
}
]

def test24_before := [llvm|
{
^0(%arg171 : i1):
  %0 = llvm.mlir.constant(14 : i32) : i32
  %1 = llvm.mlir.constant(1234 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = "llvm.select"(%arg171, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.icmp "ne" %3, %2 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def ashrslt_02_12_after := [llvm|
{
^0(%arg241 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def and_or_not_not_wrong_a_before := [llvm|
{
^0(%arg332 : i32, %arg333 : i32, %arg334 : i32, %arg335 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg333, %arg335 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.and %arg332, %arg334 : i32
  %4 = llvm.xor %3, %0 : i32
  %5 = llvm.or %4, %arg333 : i32
  %6 = llvm.and %5, %2 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def eq_umin1_after := [llvm|
{
^0(%arg60 : i32, %arg61 : i32):
  %0 = llvm.icmp "ule" %arg60, %arg61 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

def main8_logical_before := [llvm|
{
^0(%arg27 : i32):
  %0 = llvm.mlir.constant(64 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.mlir.constant(true) : i1
  %4 = llvm.mlir.constant(2 : i32) : i32
  %5 = llvm.mlir.constant(1 : i32) : i32
  %6 = llvm.and %arg27, %0 : i32
  %7 = llvm.icmp "ne" %6, %1 : i32
  %8 = llvm.trunc %arg27 : i32 to i8
  %9 = llvm.icmp "slt" %8, %2 : i8
  %10 = "llvm.select"(%7, %3, %9) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %11 = "llvm.select"(%10, %4, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%11) : (i32) -> ()
}
]

def positive_biggerShl_before := [llvm|
{
^0(%arg34 : i32):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.mlir.constant(5 : i32) : i32
  %2 = llvm.shl %arg34, %0 : i32
  %3 = llvm.lshr %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def t7_before := [llvm|
{
^0(%arg197 : i8, %arg198 : i1, %arg199 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.shl %0, %arg199 : i8
  %3 = "llvm.select"(%arg198, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = llvm.sub %arg197, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def test_shl_nsw__all_are_safe_after := [llvm|
{
^0(%arg86 : i32, %arg87 : i64):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(60 : i32) : i32
  %2 = llvm.shl %arg86, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.zext nneg %3 : i32 to i64
  %5 = llvm.ashr %arg87, %4 : i64
  "llvm.return"(%5) : (i64) -> ()
}
]

def eq (v : Γ.Var t) (w : Γ.Var u) : Prop :=
  ∃ (h : t = u), v = h ▸ w

def arithShiftRight (op1 : GenBVExpr w) (op2: GenBVExpr w) : GenBVExpr w :=
  GenBVExpr.arithShiftRight op1 op2

def src_is_notmask_neg_p2_fail_not_invertable_after := [llvm|
{
^0(%arg51 : i8, %arg52 : i8):
  %0 = llvm.mlir.constant(-124 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.xor %arg51, %0 : i8
  %3 = llvm.sub %1, %arg52 : i8
  %4 = llvm.or %arg52, %3 : i8
  %5 = llvm.icmp "uge" %2, %4 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

def masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_2_logical_before := [llvm|
{
^0(%arg23 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(7 : i32) : i32
  %3 = llvm.mlir.constant(true) : i1
  %4 = llvm.and %arg23, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.and %arg23, %2 : i32
  %7 = llvm.icmp "ne" %6, %1 : i32
  %8 = "llvm.select"(%7, %3, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%8) : (i1) -> ()
}
]

@[simp_denote]
def add_b32_llvm_i64 := [LV| {
    ^entry (%x: i64):
    %0 = llvm.mlir.constant (-4294967296) : i64
    %1 = llvm.add %x, %0 : i64
    llvm.return %1 : i64
  }]

def load (p : SLLVM.Ptr) (w : Nat) : MemorySSAM (LLVM.IntW w) := do
  let p ← p.getOrUB
  let block ← getLiveBlockOrUB p
  throwUBIf <| p.offsetInBits + w > block.lengthInBits
  return .value <| block.bytes.extractLsb' p.offsetInBits w

def test29_before := [llvm|
{
^0(%arg166 : i32, %arg167 : i32):
  %0 = llvm.trunc %arg166 : i32 to i8
  %1 = llvm.trunc %arg167 : i32 to i8
  %2 = llvm.or %1, %0 : i8
  %3 = llvm.zext %2 : i8 to i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def zext_nneg_signbit_extract_before := [llvm|
{
^0(%arg4 : i32):
  %0 = llvm.mlir.constant(31) : i64
  %1 = llvm.zext nneg %arg4 : i32 to i64
  %2 = llvm.lshr %1, %0 : i64
  "llvm.return"(%2) : (i64) -> ()
}
]

def Signature.map (f : Ty → Ty') : Signature Ty → Signature Ty' :=
  fun sig => {
    sig         := sig.sig.map f
    regSig      := sig.regSig.map f
    returnTypes := sig.returnTypes.map f
  }

def select_constants_and_icmp_ne0_zero_tval_before := [llvm|
{
^0(%arg12 : i1, %arg13 : i1):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(12 : i8) : i8
  %2 = "llvm.select"(%arg12, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %3 = "llvm.select"(%arg13, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = llvm.and %2, %3 : i8
  %5 = llvm.icmp "ne" %4, %0 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

def lshr_and_add_fail_before := [llvm|
{
^0(%arg94 : i8, %arg95 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(123 : i8) : i8
  %2 = llvm.lshr %arg94, %0 : i8
  %3 = llvm.lshr %arg95, %0 : i8
  %4 = llvm.and %3, %1 : i8
  %5 = llvm.add %2, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

instance {n : Nat} : Cli.ParseableType (BitVec n) where
  name := s!"BitVec {n}"
  parse? str := do
   let intVal ← Cli.instParseableTypeInt.parse? str
   return BitVec.ofInt n intVal

def test_or2_after := [llvm|
{
^0(%arg32 : i32, %arg33 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.and %arg33, %0 : i32
  %2 = llvm.icmp "ugt" %arg32, %1 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def t6_no_extrause_after := [llvm|
{
^0(%arg19 : i8, %arg20 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.xor %arg20, %0 : i8
  %2 = llvm.icmp "ule" %arg19, %1 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def icmp_sle5_before := [llvm|
{
^0(%arg8 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.shl %arg8, %0 overflow<nsw> : i8
  %2 = llvm.icmp "sle" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def ult_swap_or_not_max_logical_before := [llvm|
{
^0(%arg36 : i8, %arg37 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "ugt" %arg37, %arg36 : i8
  %3 = llvm.icmp "ne" %arg36, %0 : i8
  %4 = "llvm.select"(%2, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def trunc_shl_nsw_nuw_31_i32_i64_before := [llvm|
{
^0(%arg55 : i64):
  %0 = llvm.mlir.constant(31) : i64
  %1 = llvm.shl %arg55, %0 overflow<nsw,nuw> : i64
  %2 = llvm.trunc %1 : i64 to i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def Com.returnVars : (com : Com d Γ eff ts) → HVector (Var com.outContext) ts
  | .rets vs => vs
  | .var _ body => body.returnVars

def head : Stream α → Option α := Stream'.head

def zext_sext_add_icmp_slt_1_type_not_i1_after := [llvm|
{
^0(%arg47 : i2, %arg48 : i1):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.zext %arg47 : i2 to i8
  %2 = llvm.sext %arg48 : i1 to i8
  %3 = llvm.add %1, %2 overflow<nsw> : i8
  %4 = llvm.icmp "slt" %3, %0 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

def PR45977_f2_after := [llvm|
{
^0(%arg138 : i32, %arg139 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg138, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def Expr.KInductionCircuits.mkIndHypCycleBreaking (circs : Expr) : MetaM Expr :=
  mkAppM ``ReflectVerif.BvDecide.KInductionCircuits.mkIndHypCycleBreaking #[circs]

def or_xor_tree_1001_before := [llvm|
{
^0(%arg18 : i32, %arg19 : i32, %arg20 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mul %arg18, %0 : i32
  %2 = llvm.mul %arg19, %0 : i32
  %3 = llvm.mul %arg20, %0 : i32
  %4 = llvm.xor %2, %1 : i32
  %5 = llvm.xor %2, %3 : i32
  %6 = llvm.xor %5, %1 : i32
  %7 = llvm.or %6, %4 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def ashr_sge_exact_after := [llvm|
{
^0(%arg166 : i8):
  %0 = llvm.mlir.constant(72 : i8) : i8
  %1 = llvm.icmp "sgt" %arg166, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def and_sgt_to_mask_before := [llvm|
{
^0(%arg3 : i8):
  %0 = llvm.mlir.constant(123 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.icmp "sgt" %arg3, %0 : i8
  %4 = llvm.and %arg3, %1 : i8
  %5 = llvm.icmp "eq" %4, %2 : i8
  %6 = llvm.and %3, %5 : i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def bool_zext_after := [llvm|
{
^0(%arg172 : i1):
  %0 = llvm.zext %arg172 : i1 to i16
  "llvm.return"(%0) : (i16) -> ()
}
]

def Expr.KInductionCircuits.mkIsLawful_mkN (fsm : Expr) (n : Expr) : MetaM Expr :=
  mkAppM ``ReflectVerif.BvDecide.KInductionCircuits.IsLawful_mkN #[fsm, n]

def fold_add_udiv_urem_after := [llvm|
{
^0(%arg10 : i32):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.mlir.constant(6 : i32) : i32
  %2 = llvm.udiv %arg10, %0 : i32
  %3 = llvm.mul %2, %1 overflow<nuw> : i32
  %4 = llvm.add %3, %arg10 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def anyext_trunc_fold_zext_32 : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := [LV| {
    ^entry (%x: i32):
      %0 = llvm.zext %x: i32 to i64
      %1 = llvm.trunc %0: i64 to i32
      llvm.return %1 : i32
  }]
  rhs := [LV| {
    ^entry (%x: i32):
      llvm.return %x : i32
  }]

def positive_biggerashr_ashrexact_before := [llvm|
{
^0(%arg40 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.ashr exact %arg40, %0 : i8
  %3 = llvm.shl %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def or_and_shift_shift_and_after := [llvm|
{
^0(%arg12 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(56 : i32) : i32
  %2 = llvm.mlir.constant(2 : i32) : i32
  %3 = llvm.mlir.constant(28 : i32) : i32
  %4 = llvm.shl %arg12, %0 : i32
  %5 = llvm.and %4, %1 : i32
  %6 = llvm.shl %arg12, %2 : i32
  %7 = llvm.and %6, %3 : i32
  %8 = llvm.or %5, %7 : i32
  "llvm.return"(%8) : (i32) -> ()
}
]

def PR42691_10_before := [llvm|
{
^0(%arg325 : i32):
  %0 = llvm.mlir.constant(13 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.icmp "ugt" %arg325, %0 : i32
  %3 = llvm.icmp "ne" %arg325, %1 : i32
  %4 = llvm.and %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7_logical_after := [llvm|
{
^0(%arg11 : i32):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

Union in Init.Core
</all_available_defs>

<all_available_lemmas>
Function.update_apply in Mathlib.Logic.Function.Basic
true_and in Init.SimpLemmas

theorem Std.HashSet.fold_induction [BEq α] [LawfulBEq α] [Hashable α]
  {f : β → α → β} {m : HashSet α} {motive : β → Set α → Prop} :
    motive b ∅ →
    (∀ b x s, x ∉ s → motive b s → motive (f b x) (s ∪ {x})) →
    motive (m.fold f b) m.toSet

theorem Std.HashSet.toSet_toList[BEq α] [LawfulBEq α] [Hashable α] (m : HashSet α) : m.toSet = { x | x ∈ m.toList }

theorem Std.HashMap.fold_induction [BEq α] [LawfulBEq α] [DecidableEq α] [Hashable α]
  {f : γ → α → β → γ} {m : HashMap α β} {motive : γ → (α → Option β) → Prop} :
    motive b (λ _ ↦ none) →
    (∀ b x y m, m x = none → motive b m → motive (f b x y) (Function.update m x y)) →
    motive (m.fold f b) m.toPFun

theorem Std.HashMap.toPFun_toList[BEq α] [LawfulBEq α] [Hashable α] (m : HashMap α β) :
    m.toPFun = λ k ↦ m.toList.find? (λ x ↦ x.1 == k) |>.map Prod.snd

@[aesop 50% unsafe]
theorem Std.HashMap.mem_of_getElem? [BEq K] [LawfulBEq K] [Hashable K] [LawfulHashable K] {m : Std.HashMap K V} {k : K} :
    m[k]? = some v → k ∈ m

theorem Std.HashMap.mem_iff_getElem? [BEq K] [LawfulBEq K] [Hashable K] [LawfulHashable K] [Inhabited V] {m : Std.HashMap K V} {k : K} :
     k ∈ m ↔ ∃ v, m[k]? = some v

theorem ashr_mul_times_3_div_2_exact_proof : ashr_mul_times_3_div_2_exact_before ⊑ ashr_mul_times_3_div_2_exact_after

theorem and_logic_and_logic_or_4_thm.extracted_1._9 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 &&& x_1 = 1#1 → ¬x = 1#1 → x_1 = 1#1 → ¬x_2 = 1#1 → 0#1 = x

theorem splat_mul_known_lz_proof : splat_mul_known_lz_before ⊑ splat_mul_known_lz_after

theorem no_shift_no_xor_multiuse_cmp_thm (e e_1 e_2 e_3 : IntW 32) :
  mul (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) e_2 (LLVM.or e_2 (const? 32 4096)))
      (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) e_1 e) ⊑
    mul (LLVM.or e_2 (LLVM.and e_3 (const? 32 4096)))
      (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) e_1 e)

theorem test2_proof : test2_before ⊑ test2_after

theorem demo3 (x y : BitVec 8) :
    (x ^^^ -1#8 ||| 7#8) ^^^ 12#8 = x &&& BitVec.ofInt 8 (-8) ^^^ BitVec.ofInt 8 (-13)

theorem p_commutative0_proof : p_commutative0_before ⊑ p_commutative0_after

theorem e_328 :
     - 1 *  ~~~x - 2 * (x ||| y) - 6 *  ~~~y + 7 * (x ^^^ y) - 3 *  ~~~(x ^^^ y) + 10 *  ~~~(x ||| y) + 1 * (x &&&  ~~~y) + 5 * (x &&& y) = 4 *  ~~~(x |||  ~~~y)

theorem and_consts_thm (e : IntW 32) :
  LLVM.or (icmp IntPred.eq (LLVM.and (const? 32 4) e) (const? 32 0))
      (icmp IntPred.eq (LLVM.and (const? 32 8) e) (const? 32 0)) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 12)) (const? 32 12)

theorem udiv_shl_pair1_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ x_2 <<< x_1 >>> x_1 ≠ x_2 ∨ x_1 ≥ ↑32 ∨ True ∧ x_2 <<< x >>> x ≠ x_2 ∨ x ≥ ↑32 ∨ x_2 <<< x = 0) →
    ¬(True ∧ 1#32 <<< x_1 >>> x_1 ≠ 1#32 ∨ x_1 ≥ ↑32 ∨ x ≥ ↑32) → x_2 <<< x_1 / x_2 <<< x = 1#32 <<< x_1 >>> x

theorem PR23309v2_proof : PR23309v2_before ⊑ PR23309v2_after

theorem ashr_ugt_noexact_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬3#8 ≥ ↑8 → ofBool (10#8 <ᵤ x.sshiftRight' 3#8) = ofBool (87#8 <ᵤ x)

theorem t2_ult_sgt_65536_thm.extracted_1._5 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 <ᵤ 65536#32) = 1#1 → ¬ofBool (65535#32 <ₛ x_1) = 1#1 → ofBool (x_1 <ₛ 0#32) = 1#1 → x_1 = x

theorem xor_logic_and_or2_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 = 1#1 → ¬x_1 = 1#1 → 0#1 ^^^ (x_1 ||| x) = x

theorem test_proof : test_before ⊑ test_after

theorem ugt_and_not_min_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.ugt e_1 e) (icmp IntPred.ne e_1 (const? 8 0)) (const? 1 0) ⊑
    icmp IntPred.ugt e_1 e

theorem test22_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬24#32 ≥ ↑32 → signExtend 32 (truncate 8 x) <<< 24#32 = x <<< 24#32

theorem ashrslt_03_05_exact_proof : ashrslt_03_05_exact_before ⊑ ashrslt_03_05_exact_after

theorem trunc_shl_ashr_var_proof : trunc_shl_ashr_var_before ⊑ trunc_shl_ashr_var_after

theorem t4_c1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), x_1 - 42#8 - x = x_1 + BitVec.ofInt 8 (-42) - x

theorem main5e_like_logical_thm.extracted_1._12 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 &&& x_1 == x_2) = 1#1 →
    ¬ofBool (x_2 &&& x_1 != x_2) = 1#1 → ¬0#1 = 1#1 → 1#32 = zeroExtend 32 (ofBool (x_2 &&& x != x_2))

theorem trunc_shl_nsw_nuw_31_i32_i64_thm (e : IntW 64) :
  trunc 32 (shl e (const? 64 31) { «nsw» := true, «nuw» := true }) ⊑ shl (trunc 32 e) (const? 32 31)

theorem sub_ashr_or_i32_nuw_nsw_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.ssubOverflow x = true ∨ True ∧ x_1.usubOverflow x = true ∨ 31#32 ≥ ↑32) →
    ¬ofBool (x_1 <ₛ x) = 1#1 → (x_1 - x).sshiftRight' 31#32 ||

theorem and_or_not_not_wrong_a_thm (e e_1 e_2 e_3 : IntW 32) :
  LLVM.and (LLVM.or (LLVM.xor (LLVM.and e_3 e_2) (const? 32 (-1))) e_1) (LLVM.xor (LLVM.and e_1 e) (const? 32 (-1))) ⊑
    LLVM.xor (LLVM.and e_1 e) (LLVM.or e_1 (LLVM.xor (LLVM.and e_3 e_2) (const? 32 (-1))))

theorem mul_of_bool_no_lz_other_op_proof : mul_of_bool_no_lz_other_op_before ⊑ mul_of_bool_no_lz_other_op_after

@[simp] theorem toBitVec_add' (a b : BitStream) (w i : Nat) (hi : i < w) :
    ((a + b).toBitVec w).getLsbD i = ((a.toBitVec w) + (b.toBitVec w)).getLsbD i ∧
    (a.addAux b i).2 = (BitVec.carry (i + 1) (a.toBitVec w) (b.toBitVec w) false)

@[simp] lemma eval_foldl_and :
    ∀ (s : List α) (f : α → Circuit β) (c : Circuit β) (g : β → Bool),
      (eval (s.foldl (λ c x => c &&& (f x)) c) g : Prop) ↔
        eval c g ∧ (∀ a ∈ s, eval (f a) g)

theorem trunc_sel_smaller_zext_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  x_1 = 1#1 → zeroExtend 32 (truncate 16 x) = truncate 32 x &&& 65535#32

theorem testi16i8_proof : testi16i8_before ⊑ testi16i8_after

theorem main7g_logical_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 &&& x_1 == x_2 &&& x_1 &&& x) = 1#1 →
    ofBool (x_2 &&& x_1 != x_2 &&& x_1 &&& x) = 1#1 → ¬0#1 = 1#1 → 1#32 = zeroExtend 32 1#1

theorem e_2258 :
     - 2 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 2 * (d |||  ~~~e) - 1 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 6 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 7 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 2 *  ~~~(d ^^^ ( ~~~e &&& f)) + 5 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 2 *  ~~~(d &&& (e &&& f)) + 1 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 11 * (f ^^^ ( ~~~d ||| (e ||| f))) - 1 * (f &&& (d |||  ~~~e)) + 11 * (e |||  ~~~(d |||  ~~~f)) + 3 * (f ^^^ (d ||| ( ~~~e ||| f))) - 5 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 1 * (f ^^^  ~~~(d &&& e)) - 7 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 1 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 11 * (d ||| (e &&& f)) + 3 * ((d &&& e) ||| (e ^^^ f)) + 3 * (f ^^^ (d &&& (e ||| f))) - 6 * (e &&&  ~~~(d &&&  ~~~f)) + 3 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 2 * (e ^^^ ( ~~~d ||| (e ||| f))) - 1 * (e ^^^ (d &&& ( ~~~e ||| f))) - 3 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 6 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) + 1 * (d &&& f) - 2 * (f ||| (d &&& e)) - 1 * (e ^^^ (d |||  ~~~f)) - 7 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 11 * (f ^^^  ~~~(d ||| e)) - 7 *  ~~~(d ^^^ ( ~~~e ||| f)) - 2 * ((d &&& e) |||  ~~~(e ||| f)) - 1 * ( ~~~d &&& (e ^^^ f)) + 11 * (e ^^^ (d ||| (e ^^^ f))) + 7 * (d ||| (e ||| f)) + 2 * ( ~~~e &&&  ~~~(d ^^^ f)) + 11 *  ~~~(e &&&  ~~~f) - 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 5 * (e ^^^  ~~~(d &&& (e &&& f))) - 1 * (d ||| ( ~~~e ||| f)) + 3 * ((d &&& f) ||| (e &&&  ~~~f)) + 1 * (f ||| (d ^^^ e)) + 4 * ( ~~~d ||| (e ^^^ f)) - 3 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 5 * (f ^^^ (d ||| e)) + 2 * ((d &&& e) |||  ~~~(e ^^^ f)) + 1 *  ~~~(d |||  ~~~e) - 11 *  ~~~(d ||| (e ||| f)) + 9 *  ~~~(d ||| ( ~~~e ||| f)) - 29 *  ~~~( ~~~d ||| (e ||| f)) - 22 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 45 * ( ~~~d &&& ( ~~~e &&& f)) - 32 * ( ~~~d &&& (e &&& f)) - 35 * (d &&& ( ~~~e &&& f)) - 32 * (d &&& (e &&& f)) = 11 * (e ||| (d &&&  ~~~f)) - 5 * (e ^^^ ( ~~~d &&& (e ^^^ f)))

theorem both_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(x_1 ≥ ↑8 ∨ x ≥ ↑8) → True ∧ 1#8 <<< x >>> x ≠ 1#8 ∨ x ≥ ↑8 ∨ x_1 ≥ ↑8 → False

theorem main7d_logical_proof : main7d_logical_before ⊑ main7d_logical_after

theorem lshr_32_add_zext_trunc_proof : lshr_32_add_zext_trunc_before ⊑ lshr_32_add_zext_trunc_after

theorem ashrsgt_01_12_exact_thm (e : IntW 4) :
  icmp IntPred.sgt (ashr e (const? 4 1) { «exact» := true }) (const? 4 (-4)) ⊑
    icmp IntPred.ne e (const? 4 (-8))

theorem test3_apint_thm.extracted_1._1 : ∀ (x x_1 : BitVec 47),
  (x_1 ^^^ -1#47) &&& (x ^^^ -1#47) ^^^ -1#47 = x_1 ||

theorem sub_sel_op1_thm.extracted_1._1 : ∀ (x : BitVec 1),
  x = 1#1 → ¬(True ∧ (42#32).ssubOverflow 42#32 = true) → 42#32 - 42#32 = zeroExtend 32 (x ^^^ 1#1)

theorem add_or_sub_comb_i8_negative_y_add_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  (0#8 - x_1 ||| x_1) + x = (x_1 ||| 0#8 - x_1) + x

theorem bv_AndOrXor_698 :
    ∀ (e e_1 e_2 : LLVM.IntW w),
      LLVM.and (LLVM.icmp LLVM.IntPred.eq (LLVM.and e e_1) (LLVM.const? w 0))
          (LLVM.icmp LLVM.IntPred.eq (LLVM.and e e_2) (LLVM.const? w 0)) ⊑
        LLVM.icmp LLVM.IntPred.eq (LLVM.and e (LLVM.or e_1 e_2)) (LLVM.const? w 0)

theorem or_and3_commuted_proof : or_and3_commuted_before ⊑ or_and3_commuted_after

theorem icmp_select_var_select_thm.extracted_1._11 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  x_2 = 1#1 →
    ¬(ofBool (x_1 == 0#8) = 1#1 ∧ x_2 = 1#1) →
      ¬ofBool (x_1 == 0#8) = 1#1 → x_2 ^^^ 1#1 = 1#1 → ofBool (x_1 == x) = 1#1

theorem t3_exact_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬(True ∧ x >>> 63#64 <<< 63#64 ≠ x ∨ 63#64 ≥ ↑64) →
    ¬(True ∧ x >>> 63#64 <<< 63#64 ≠ x ∨
          63#64 ≥ ↑64 ∨
            True ∧ signExtend 64 (truncate 32 (x >>> 63#64)) ≠ x >>> 63#64 ∨
              True ∧ zeroExtend 64 (truncate 32 (x >>> 63#64)) ≠ x >>> 63#64) →
      0#32 - truncate 32 (x.sshiftRight' 63#64) = truncate 32 (x >>> 63#64)

theorem t6_no_extrause_proof : t6_no_extrause_before ⊑ t6_no_extrause_after

theorem verifyAIG_correct {α : Type} [DecidableEq α] [Fintype α] [Hashable α]
    {entry : Entrypoint α} {cert : String}
    (h : verifyAIG entry cert) :
    entry.Unsat

theorem trunc_shl_ashr_infloop_proof : trunc_shl_ashr_infloop_before ⊑ trunc_shl_ashr_infloop_after

theorem e_2246 :
    4 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 2 * (e ^^^ ( ~~~d &&& (e ||| f))) - 3 * e + 1 *  ~~~( ~~~d &&& (e &&& f)) + 5 * (e |||  ~~~(d ||| f)) + 4 * (f ^^^  ~~~(d &&& (e &&& f))) + 3 * (d ||| e) + 11 *  ~~~(d ^^^ (e ^^^ f)) + 2 * (e ^^^ (d ||| ( ~~~e &&& f))) + 1 * (d ||| (e ^^^ f)) + 1 *  ~~~(d ||| ( ~~~e &&& f)) + 7 * (d ^^^ ( ~~~e ||| f)) - 11 * (f ^^^ (d &&&  ~~~e)) - 7 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) - 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 5 * (e &&& (d ^^^ f)) - 2 *  ~~~(d &&& (e ||| f)) + 7 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) + 5 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 4 * (e &&& (d |||  ~~~f)) + 1 * (f ||| (d ^^^ e)) + 2 * ( ~~~f |||  ~~~(d ^^^ e)) + 3 *  ~~~(e &&& f) + 1 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 2 * (d &&&  ~~~f) - 3 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 1 * (f |||  ~~~(d ^^^ e)) + 1 * ( ~~~e |||  ~~~(d ^^^ f)) + 1 * (e ||| (d ^^^ f)) - 2 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 3 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 1 * (f &&&  ~~~(d &&&  ~~~e)) - 5 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 11 * ((d &&& e) ^^^ (e |||  ~~~f)) - 1 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 7 * (f ^^^  ~~~(d |||  ~~~e)) - 3 * (f ^^^ (d &&& e)) - 2 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * (d ||| ( ~~~e &&& f)) + 11 * (d &&& f) - 2 * (d ||| f) + 2 * (f &&& (d ^^^ e)) - 11 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 6 * (d ^^^ e) + 3 * (e ^^^  ~~~(d &&&  ~~~f)) + 11 * (f ^^^ (d ||| ( ~~~e &&& f))) + 3 *  ~~~(d ^^^ ( ~~~e ||| f)) - 7 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 11 * ((d |||  ~~~e) &&& (e ^^^ f)) - 47 *  ~~~(d ||| (e ||| f)) - 39 *  ~~~(d ||| ( ~~~e ||| f)) + 2 *  ~~~( ~~~d ||| (e ||| f)) - 36 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 4 * ( ~~~d &&& ( ~~~e &&& f)) - 12 * ( ~~~d &&& (e &&& f)) - 39 * (d &&& ( ~~~e &&& f)) - 27 * (d &&& (e &&& f)) =  - 1 * (f ^^^  ~~~(d ||| (e &&& f)))

theorem ashr_ugt_2_proof : ashr_ugt_2_before ⊑ ashr_ugt_2_after

theorem trunc_lshr_exact_mask_thm.extracted_1._1 : ∀ (x : BitVec 8), ¬2#8 ≥ ↑8 → 2#6 ≥ ↑6 → False

theorem or_not_xor_common_op_commute5_proof : or_not_xor_common_op_commute5_before ⊑ or_not_xor_common_op_commute5_after

theorem main4e_like_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& x == x) = 1#1 → ofBool (x_1 &&& x != x) = 1#1 → 0#1 = 1#1 → 0#32 = zeroExtend 32 1#1

theorem test1_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ¬zeroExtend 32 x ≥ ↑32 → True ∧ x.msb = true ∨ zeroExtend 32 x ≥ ↑32 → False

theorem or_and1_commuted_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1),
  ¬x_1 &&& (x ^^^ 1#1) = 1#1 → ¬x = 1#1 → ¬x_1 = 1#1 → x = 0#1

theorem icmp_select_var_pred_ne_proof : icmp_select_var_pred_ne_before ⊑ icmp_select_var_pred_ne_after

theorem demorgan_nor_use2c_proof : demorgan_nor_use2c_before ⊑ demorgan_nor_use2c_after

theorem src3_proof : src3_before ⊑ src3_after

theorem test1_thm.extracted_1._2 : ∀ (x : BitVec 333),
  ¬70368744177664#333 = 0 → ¬46#333 ≥ ↑333 → x / 70368744177664#333 = x >>> 46#333

theorem icmp_ne_zext_eq_non_boolean_proof : icmp_ne_zext_eq_non_boolean_before ⊑ icmp_ne_zext_eq_non_boolean_after

theorem mul_selectp2_x_non_const_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  x_1 = 1#1 → ¬1#8 ≥ ↑8 → 2#8 * x = x <<< 1#8

theorem and_or2_thm.extracted_1._8 : ∀ (x x_1 x_2 : BitVec 1), ¬(x_2 ^^^ 1#1) &&& x_1 = 1#1 → ¬x_1 = 1#1 → x_1 = 0#1

theorem cast_test_2002h08h02_thm (e : IntW 64) : zext 64 (trunc 8 e) ⊑ LLVM.and e (const? 64 255)

theorem e_2113 :
     - 11 * ((d &&& f) ^^^ (e ||| f)) - 3 * ( ~~~d ||| (e &&& f)) - 1 * (e ||| (d ^^^ f)) + 5 * (f &&&  ~~~(d ^^^ e)) + 7 * ( ~~~f &&& (d ^^^ e)) + 3 * (f ^^^ (d &&& (e ||| f))) - 6 * ( ~~~d ||| ( ~~~e ||| f)) + 3 * ( ~~~d ||| (e ^^^ f)) + 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 1 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 3 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 1 *  ~~~(d &&& ( ~~~e ||| f)) + 2 * (e ^^^  ~~~(d &&&  ~~~f)) + 2 *  ~~~(e ^^^ f) - 6 *  ~~~(e &&&  ~~~f) - 5 * (d &&& f) + 2 * (f ^^^  ~~~(d ||| e)) + 2 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 5 * (e ^^^  ~~~(d &&& (e &&& f))) - 2 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) - 3 * (d ^^^ (e ||| f)) + 11 * ( ~~~e &&&  ~~~(d ^^^ f)) + 1 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 3 * (f ||| (d &&&  ~~~e)) + 7 * (f &&& (d ||| e)) - 5 * (e ^^^ (d &&&  ~~~f)) - 2 * (e &&& (d ^^^ f)) + 5 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 11 * (d ||| (e &&& f)) - 5 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 1 * (f |||  ~~~(d ||| e)) - 11 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 1 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 5 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * ( ~~~e ||| (d ^^^ f)) + 4 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) + 13 *  ~~~(d ||| (e ||| f)) + 21 *  ~~~(d ||| ( ~~~e ||| f)) + 18 *  ~~~( ~~~d ||| (e ||| f)) - 7 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 39 * ( ~~~d &&& ( ~~~e &&& f)) + 12 * ( ~~~d &&& (e &&& f)) - 8 * (d &&& ( ~~~e &&& f)) + 9 * (d &&& (e &&& f)) =  - 1 * (d ^^^ (e &&& f))

theorem add_and_or_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), (x_1 &&& x) + (x_1 ||| x) = x_1 + x

theorem e_215 :
     - 6 * (x ||| y) + 5 * (x |||  ~~~y) - 3 *  ~~~y + 2 * x + 13 *  ~~~(x |||  ~~~y) + 9 * (x &&&  ~~~y) + 6 * (x &&& y) = 7 *  ~~~(x &&&  ~~~x) - 5 *  ~~~(x ||| y)

theorem select_icmp_ne_0_and_1073741824_xor_8_thm (e : IntW 8) (e_1 : IntW 32) :
  select (icmp IntPred.ne (const? 32 0) (LLVM.and e_1 (const? 32 1073741824))) e (LLVM.xor e (const? 8 8)) ⊑
    select (icmp IntPred.eq (LLVM.and e_1 (const? 32 1073741824)) (const? 32 0)) (LLVM.xor e (const? 8 8))
      e

theorem ashr_uge_noexact_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬3#8 ≥ ↑8 → ofBool (10#8 ≤ᵤ x.sshiftRight' 3#8) = ofBool (79#8 <ᵤ x)

theorem ashrslt_01_11_exact_thm (e : IntW 4) :
  icmp IntPred.slt (ashr e (const? 4 1) { «exact» := true }) (const? 4 (-5)) ⊑ const? 1 0

theorem scalar_i32_lshr_and_negC_eq_X_is_constant2_proof : scalar_i32_lshr_and_negC_eq_X_is_constant2_before ⊑ scalar_i32_lshr_and_negC_eq_X_is_constant2_after

theorem testi8i8_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬7#8 ≥ ↑8 → ofBool (-1#8 <ₛ x) = 1#1 → x.sshiftRight' 7#8 ^^^ 127#8 = 127#8

theorem main4e_like_logical_thm.extracted_1._9 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 &&& x_1 == x_1) = 1#1 → ofBool (x_2 &&& x_1 != x_1) = 1#1 → 0#1 = 1#1 → 0#32 = zeroExtend 32 1#1

theorem main4f_like_logical_thm.extracted_1._10 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 &&& x_1 != x_1) = 1#1 →
    ofBool (x_2 &&& x_1 == x_1) = 1#1 →
      ¬ofBool (x_2 &&& x != x) = 1#1 → 1#32 = zeroExtend 32 (ofBool (x_2 &&& x == x))

theorem main7a_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& x == x_1) = 1#1 → ofBool (x_1 &&& x != x_1) = 1#1 → ¬0#1 = 1#1 → 1#32 = zeroExtend 32 1#1

@[simp]
theorem mkStateNeqCircuit_eq_false_iff {arity : Type _} {i : Nat}
  [DecidableEq arity] [Fintype arity] [Hashable arity]
  (p : FSM arity) (s t : p.α → Circuit (Vars p.α arity i)) :
  (∀ envBool, (mkStateNeqCircuit p s t).eval envBool = false) ↔
  (∀ (envBool : Vars p.α arity i → Bool), ∃ (a : p.α), (s a).eval envBool ≠ (t a).eval envBool)

theorem t6_shl_thm (e e_1 : IntW 32) :
  shl (shl e_1 (sub (const? 32 32) e) { «nsw» := false, «nuw» := true }) (add e (const? 32 (-2)))
      { «nsw» := true, «nuw» := false } ⊑
    shl e_1 (const? 32 30)

theorem sgt_x_impliesF_eq_smin_todo_thm.extracted_1._3 : ∀ (x x_1 x_2 : BitVec 8),
  ofBool (x_1 <ₛ x_2) = 1#1 → ofBool (x_2 ≤ₛ x_1) = 1#1 → ofBool (BitVec.ofInt 8 (-128) == x_2) = ofBool (x == x_2)

theorem test_ult_xor_thm (e e_1 : IntW 32) :
  icmp IntPred.ult (LLVM.xor (LLVM.xor e_1 (const? 32 (-1))) e) (LLVM.xor e_1 (const? 32 (-1))) ⊑
    icmp IntPred.ugt (LLVM.xor e e_1) e_1

theorem masked_icmps_mask_notallzeros_bmask_mixed_1b_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_1b_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_1b_logical_after

theorem test1_thm (e : IntW 33) : LLVM.udiv e (const? 33 4096) ⊑ lshr e (const? 33 12)

theorem ashrslt_02_11_thm (e : IntW 4) : icmp IntPred.slt (ashr e (const? 4 2)) (const? 4 (-5)) ⊑ const? 1 0

theorem sgt_swap_and_not_min_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 != BitVec.ofInt 8 (-128)) &&& ofBool (x <ₛ x_1) = ofBool (x <ₛ x_1)

theorem different_size_zext_zext_slt_thm.extracted_1._1 : ∀ (x : BitVec 4) (x_1 : BitVec 7),
  ofBool (zeroExtend 25 x_1 <ₛ zeroExtend 25 x) = ofBool (x_1 <ᵤ zeroExtend 7 x)

theorem e_203 :
     - 5 *  ~~~(x &&& y) - 2 * (x |||  ~~~y) + 7 *  ~~~x + 7 *  ~~~(x ||| y) - 2 *  ~~~(x |||  ~~~y) + 2 * (x &&& y) = 7 *  ~~~y - 14 * (x &&&  ~~~y)

theorem add_or_sub_comb_i8_negative_y_add_proof : add_or_sub_comb_i8_negative_y_add_before ⊑ add_or_sub_comb_i8_negative_y_add_after

theorem select_bittest_to_sub_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 1#32 == 0#32) = 1#1 →
    True ∧ (4#32).ssubOverflow (x &&& 1#32) = true ∨ True ∧ (4#32).usubOverflow (x &&& 1#32) = true → False

theorem test94_proof : test94_before ⊑ test94_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_2_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_2_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_2_after

theorem xor_signbit_select_shl_proof : xor_signbit_select_shl_before ⊑ xor_signbit_select_shl_after

theorem n1_proof : n1_before ⊑ n1_after

theorem tryFactorization_add_nuw_mul_proof : tryFactorization_add_nuw_mul_before ⊑ tryFactorization_add_nuw_mul_after

theorem test19_proof : test19_before ⊑ test19_after

theorem test6_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬32#128 ≥ ↑128 →
    ¬(32#64 ≥ ↑64 ∨ True ∧ zeroExtend 64 (truncate 32 (x >>> 32#64)) ≠ x >>> 32#64) →
      truncate 32 (zeroExtend 128 x >>> 32#128) = truncate 32 (x >>> 32#64)

theorem e_1392 :
    7 * (z |||  ~~~t) - 11 * z + 2 *  ~~~t + 3 * (z ^^^ t) - 3 *  ~~~(z &&& t) + 1 *  ~~~(z &&&  ~~~z) - 2 * t + 12 *  ~~~(z |||  ~~~t) + 1 * (z &&&  ~~~t) + 5 * (z &&& t) =  - 4 *  ~~~(z ||| t) + 11 *  ~~~z

theorem udiv_mul_shl_nuw_exact_commute1_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 5),
  ¬(True ∧ x_2.umulOverflow x_1 = true ∨
        True ∧ x_1 <<< x >>> x ≠ x_1 ∨ x ≥ ↑5 ∨ True ∧ (x_2 * x_1).umod (x_1 <<< x) ≠ 0 ∨ x_1 <<< x = 0) →
    True ∧ x_2 >>> x <<< x ≠ x_2 ∨ x ≥ ↑5 → False

theorem bar_thm.extracted_1._1 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ofBool (x_2 <ₛ x_1) = 1#1 →
    x_3 &&& (signExtend 32 (ofBool (x_2 <ₛ x_1)) ^^^ -1#32) ||

theorem e_384 :
    4 *  ~~~x + 2 * (x |||  ~~~y) - 2 * (x ^^^ y) + 1 *  ~~~(x ^^^ y) - 2 *  ~~~(x &&&  ~~~x) - 5 *  ~~~(x ||| y) + 3 *  ~~~(x |||  ~~~y) + 5 * (x &&&  ~~~y) = 3 * (x ||| y) - 2 * (x &&& y)

theorem lshrugt_02_06_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 2#4 <<< 2#4 ≠ x ∨ 2#4 ≥ ↑4) → ofBool (6#4 <ᵤ x >>> 2#4) = 0#1

theorem test8_thm (e : IntW 32) : LLVM.srem (shl e (const? 32 4)) (const? 32 8) ⊑ const? 32 0

theorem multiuse2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ ((x &&& 96#32) <<< 8#32).sshiftRight' 8#32 ≠ x &&& 96#32 ∨
        True ∧ (x &&& 96#32) <<< 8#32 >>> 8#32 ≠ x &&& 96#32 ∨
          8#32 ≥ ↑32 ∨
            True ∧ ((x &&& 6#32) <<< 8#32).sshiftRight' 8#32 ≠ x &&& 6#32 ∨
              True ∧ (x &&& 6#32) <<< 8#32 >>> 8#32 ≠ x &&& 6#32 ∨
                8#32 ≥ ↑32 ∨
                  True ∧ ((x &&& 24#32) <<< 8#32).sshiftRight' 8#32 ≠ x &&& 24#32 ∨
                    True ∧ (x &&& 24#32) <<< 8#32 >>> 8#32 ≠ x &&& 24#32 ∨
                      8#32 ≥ ↑32 ∨
                        True ∧ ((x &&& 6#32) <<< 1#32).sshiftRight' 1#32 ≠ x &&& 6#32 ∨
                          True ∧ (x &&& 6#32) <<< 1#32 >>> 1#32 ≠ x &&& 6#32 ∨
                            1#32 ≥ ↑32 ∨
                              True ∧ ((x &&& 96#32) <<< 1#32).sshiftRight' 1#32 ≠ x &&& 96#32 ∨
                                True ∧ (x &&& 96#32) <<< 1#32 >>> 1#32 ≠ x &&& 96#32 ∨
                                  1#32 ≥ ↑32 ∨
                                    True ∧ ((x &&& 24#32) <<< 1#32).sshiftRight' 1#32 ≠ x &&& 24#32 ∨
                                      True ∧ (x &&& 24#32) <<< 1#32 >>> 1#32 ≠ x &&& 24#32 ∨ 1#32 ≥ ↑32) →
    8#32 ≥ ↑32 ∨
        1#32 ≥ ↑32 ∨
          1#32 ≥ ↑32 ∨
            1#32 ≥ ↑32 ∨
              True ∧ (x <<< 1#32 &&& 192#32 &&& (x <<< 1#32 &&& 48#32) != 0) = true ∨
                True ∧ (x <<< 1#32 &&& 12#32 &&& (x <<< 1#32 &&& 192#32 ||| x <<< 1#32 &&& 48#32) != 0) = true ∨
                  True ∧
                    (x <<< 8#32 &&& 32256#32 &&&
                          (x <<< 1#32 &&& 12#32 ||| (x <<< 1#32 &&& 192#32 ||| x <<< 1#32 &&& 48#32)) !=
                        0) =
                      true →
      False

@[simp]
theorem f_eq_zero : (f q n) = (0 : R q n)

theorem test_shr_and_1_ne_0_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (LLVM.and (lshr e_1 e) (const? 32 1)) (const? 32 0) ⊑
    icmp IntPred.ne (LLVM.and e_1 (shl (const? 32 1) e { «nsw» := false, «nuw» := true })) (const? 32 0)

theorem shl_add_lshr_flag_preservation_thm (e e_1 e_2 : IntW 32) :
  lshr (add (shl e_2 e_1 { «nsw» := false, «nuw» := true }) e { «nsw» := true, «nuw» := true }) e_1
      { «exact» := true } ⊑
    add (lshr e e_1 { «exact» := true }) e_2 { «nsw» := true, «nuw» := true }

@[simp]
lemma CNFA.SignedCmp_states cmp : s ∈ (autSignedCmp cmp).m.states ↔  s < 5

theorem bools_logical_commute0_and2_thm.extracted_1._14 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 ^^^ 1#1 = 1#1 → ¬x_2 = 1#1 → ¬x_1 = 1#1 → x_2 &&& x = x_1

theorem bv_InstCombineShift__497 :
    ∀ (e e_1 e_2 : LLVM.IntW w), LLVM.lshr (LLVM.xor e e_2) e_1 ⊑ LLVM.xor (LLVM.lshr e e_1) (LLVM.lshr e_2 e_1)

theorem max_sub_ult_c12_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x <ᵤ 1#32) = 1#1 → ofBool (x == 0#32) = 1#1 → x + BitVec.ofInt 32 (-2) = BitVec.ofInt 32 (-2)

theorem main3c_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 7#32 != 0#32) = 1#1 → ¬True → 0#32 = zeroExtend 32 (ofBool (x &&& 55#32 == 0#32))

theorem test_invalid_simplify_eq2_proof : test_invalid_simplify_eq2_before ⊑ test_invalid_simplify_eq2_after

theorem test_ult_thm (e : IntW 16) (e_1 : IntW 32) :
  icmp IntPred.ult (trunc 8 e_1 { «nsw» := true, «nuw» := false }) (trunc 8 e { «nsw» := true, «nuw» := false }) ⊑
    icmp IntPred.ult e_1 (sext 32 e)

@[simp]
theorem Term.toBV_var {wenv : WidthExpr.Env wcard}
    {tctx : Term.Ctx wcard tcard}
    (benv : Term.BoolEnv bcard)
    (tenv : tctx.Env wenv) :
  Term.toBV benv nenv ienv penv tenv (.var v) = tenv v

theorem ashrslt_03_03_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 3#4 <<< 3#4 ≠ x ∨ 3#4 ≥ ↑4) → ofBool (x.sshiftRight' 3#4 <ₛ 3#4) = 1#1

theorem PR42691_5_logical_proof : PR42691_5_logical_before ⊑ PR42691_5_logical_after

theorem src_is_mask_p2_m1_proof : src_is_mask_p2_m1_before ⊑ src_is_mask_p2_m1_after

theorem test_with_even_proof : test_with_even_before ⊑ test_with_even_after

lemma TermBinop.subst_arity' {op : TermBinop} : (op.subst t₁ t₂).arity + 1= t₁.arity ⊔ t₂.arity + 1

theorem zext_sext_add_icmp_sgt_minus1_proof : zext_sext_add_icmp_sgt_minus1_before ⊑ zext_sext_add_icmp_sgt_minus1_after

theorem e_338 :
     - 6 *  ~~~y + 1 * (x ^^^ y) + 2 * y + 1 *  ~~~(x &&& y) + 1 * x + 12 *  ~~~(x ||| y) + 3 *  ~~~(x |||  ~~~y) + 4 * (x &&& y) =  - 10 * (x &&&  ~~~y) + 7 *  ~~~(x &&&  ~~~x)

theorem test55_proof : test55_before ⊑ test55_after

theorem icmp_slt_0_or_icmp_sgt_0_i64_fail3_proof : icmp_slt_0_or_icmp_sgt_0_i64_fail3_before ⊑ icmp_slt_0_or_icmp_sgt_0_i64_fail3_after

theorem t3_ult_sgt_neg1_thm.extracted_1._14 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 <ᵤ 65536#32) = 1#1 → ¬ofBool (-1#32 <ₛ x_2) = 1#1 → ofBool (65535#32 <ₛ x_2) = 1#1 → x = x_1

theorem e_244 :
     - 5 * x - 5 *  ~~~x + 11 * (x |||  ~~~y) + 7 * y - 2 *  ~~~(x |||  ~~~y) - 6 * (x &&&  ~~~y) - 13 * (x &&& y) = 6 *  ~~~(x ||| y)

theorem icmp_ne_and_z_and_onefail_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x != 0#8) &&& ofBool (x != 1#8) &&& ofBool (x != 2#8) = ofBool (2#8 <ᵤ x)

theorem e_967 :
     - 1 *  ~~~(z ^^^ t) - 5 * (z ||| t) - 6 *  ~~~t + 2 *  ~~~(z &&&  ~~~z) + 3 *  ~~~(z ||| t) + 1 *  ~~~(z |||  ~~~t) + 4 * (z &&& t) =  - 2 *  ~~~z - 9 * (z &&&  ~~~t)

theorem dist_over_add' 
  (hppot : ppot &&& (ppot - 1) = 0)
  (hqpot : qpot &&& (qpot - 1) = 0)
  (hrpot : rpot &&& (rpot - 1) = 0)
  (hspot : spot &&& (spot - 1) = 0)
  (htpot : tpot &&& (tpot - 1) = 0)
  (hupot : upot &&& (upot - 1) = 0)
  (hpmask : pmask = ppot - 1)
  (hqmask : qmask = qpot - 1)
  (hrmask : rmask = rpot - 1)
  (hsmask : smask = spot - 1)
  (htmask : tmask = tpot - 1)
  (humask : umask = upot - 1)
  (hq : UnaryGe qmask rmask) (hu : UnaryGe umask rmask) (hv : UnaryGe vmask rmask) :
  (bw' rmask 
    (mulMax'
      (bw' pmask a')
      pmask
      (addMax' (bw' smask b') smask (bw' tmask c') tmask)
      (addMax'Mask smask tmask)))  =
  (bw' rmask
    (addMax' 
      (bw' umask (mulMax' (bw' pmask a') pmask (bw' smask b') smask)) umask
      (bw' vmask (mulMax' (bw' pmask a') pmask (bw' tmask c') tmask)) vmask))

theorem and_not_or_commute4_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬((x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true ∨
        (x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true) →
    ¬(x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true →
      ((42#32).sdiv x_2 ||| x_1 &&& x ^^^ -1#32) &&& (x_1 &&& (42#32).sdiv x_2 ^^^ -1#32 ||| x) =
        (x ^^^ (42#32).sdiv x_2) &&& x_1 ^^^ -1#32

theorem Holor.pointwise_mul_index [Mul α] (h₁ h₂ : Holor α ds) :
  (h₁ * h₂) i = h₁ i * h₂ i

theorem test_mul_nsw__nuw_is_safe_proof : test_mul_nsw__nuw_is_safe_before ⊑ test_mul_nsw__nuw_is_safe_after

theorem ashr_ult_2_proof : ashr_ult_2_before ⊑ ashr_ult_2_after

theorem nonexact_lshr_ne_noexactlog_proof : nonexact_lshr_ne_noexactlog_before ⊑ nonexact_lshr_ne_noexactlog_after

theorem sub_to_xor_proof : sub_to_xor_before ⊑ sub_to_xor_after

theorem test2_proof : test2_before ⊑ test2_after

lemma NFA'.autUnsignedCmp_correct cmp : autUnsignedCmp cmp |>.correct2 autUnsignedCmpSA cmp.urel

theorem ule_or_not_min_logical_proof : ule_or_not_min_logical_before ⊑ ule_or_not_min_logical_after

theorem t0_ult_slt_128_thm.extracted_1._4 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 + 16#32 <ᵤ 144#32) = 1#1 → ofBool (x_1 <ₛ 128#32) = 1#1 → ofBool (127#32 <ₛ x_1) = 1#1 → False

theorem t1_thm (e : IntW 64) (e_1 : IntW 32) :
  icmp IntPred.ne
      (LLVM.and (shl (const? 32 65535) (sub (const? 32 32) e_1))
        (trunc 32 (lshr e (zext 64 (add e_1 (const? 32 (-16)))))))
      (const? 32 0) ⊑
    icmp IntPred.ne (LLVM.and e (const? 64 4294901760)) (const? 64 0)

@[simp] theorem toBitVec_zero : BitStream.toBitVec w BitStream.zero = 0#w

theorem t2_commutative_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x_1 <ᵤ x_1 - x) = ofBool (x_1 <ᵤ x)

theorem lshr_mul_times_5_div_4_exact_proof : lshr_mul_times_5_div_4_exact_before ⊑ lshr_mul_times_5_div_4_exact_after

theorem lshr_32_add_not_known_32_leading_zeroes_proof : lshr_32_add_not_known_32_leading_zeroes_before ⊑ lshr_32_add_not_known_32_leading_zeroes_after

theorem a_thm (e : IntW 32) :
  LLVM.and (sub (const? 32 8) e) (const? 32 7) ⊑ LLVM.and (sub (const? 32 0) e) (const? 32 7)

theorem e_319 :
    1 *  ~~~(x &&&  ~~~x) + 3 * (x |||  ~~~y) + 2 * x - 1 *  ~~~(x ||| y) + 2 *  ~~~(x |||  ~~~y) - 6 * (x &&&  ~~~y) - 6 * (x &&& y) = 3 *  ~~~x

theorem shl_or_disjoint_lshr_comm_thm (e e_1 e_2 : IntW 32) :
  lshr (LLVM.or e_2 (shl e_1 e { «nsw» := false, «nuw» := true }) { «disjoint» := true }) e ⊑
    LLVM.or (lshr e_2 e) e_1 { «disjoint» := true }

theorem or_xor_tree_0111_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  x_2 * 42#32 ^^^ x_1 * 42#32 ||

theorem c0_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x <ᵤ x &&& 3#8) = 0#1

theorem test51_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  x_1 = 1#1 →
    ¬(True ∧ (truncate 32 x &&& BitVec.ofInt 32 (-2) &&& zeroExtend 32 (x_1 ^^^ 1#1) != 0) = true) →
      signExtend 64 (truncate 32 x &&& BitVec.ofInt 32 (-2)) =
        signExtend 64 (truncate 32 x &&& BitVec.ofInt 32 (-2) ||| zeroExtend 32 (x_1 ^^^ 1#1))

theorem n0_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x &&& 4#8 == x) = ofBool (x &&& BitVec.ofInt 8 (-5) == 0#8)

theorem exact_ashr_ne_noexactdiv_proof : exact_ashr_ne_noexactdiv_before ⊑ exact_ashr_ne_noexactdiv_after

theorem ashr_16_to_64_add_zext_basic_proof : ashr_16_to_64_add_zext_basic_before ⊑ ashr_16_to_64_add_zext_basic_after

theorem different_size_zext_zext_ne_commute_proof : different_size_zext_zext_ne_commute_before ⊑ different_size_zext_zext_ne_commute_after

theorem udiv2_proof : udiv2_before ⊑ udiv2_after

theorem t4_ugt_slt_65536_thm.extracted_1._6 : ∀ (x x_1 : BitVec 32),
  ofBool (65535#32 <ᵤ x_1) = 1#1 →
    ¬ofBool (x_1 <ₛ 65536#32) = 1#1 → ¬ofBool (65535#32 <ₛ x_1) = 1#1 → ofBool (x_1 <ₛ 0#32) = 1#1 → False

theorem e_527 :
    4 * (x ||| y) - 2 * (x |||  ~~~y) - 5 *  ~~~(x &&&  ~~~y) + 7 *  ~~~x + 3 *  ~~~(x &&&  ~~~x) + 3 *  ~~~(x &&& y) - 1 *  ~~~y - 12 *  ~~~(x |||  ~~~y) - 7 * (x &&&  ~~~y) = 5 *  ~~~(x ||| y)

lemma CNFA.reverse_language {m : CNFA n} (hl : m.recognizes L) : m.reverse.recognizes L.reverse

theorem test2_thm.extracted_1._1 : ∀ (x : BitVec 1), x ^^^ x = 0#1

@[simp_denote]
theorem valuation_var_cons_eq.lemma {Ty : Type} [TyDenote Ty] {Γ : Ctxt Ty} {t t' : Ty}
  {s : Γ.Valuation} {x : TyDenote.toType t} {v : Γ.Var t'} :
  (s.cons x) (Ctxt.Var.toCons v) = s v

theorem evalWith_eq_outputWith_carryWith_of_eq
    {p : FSM arity} {carryState : p.α → Bool} {n : Nat}
    (env : arity → BitStream)
    (outEnv : arity → Bool)
    (henv : (fun a => env a n) = outEnv) :
    p.evalWith carryState env n =
    p.outputWith (p.carryWith carryState env n) outEnv

theorem ashr_sgt_noexact_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬3#8 ≥ ↑8 → ofBool (10#8 <ₛ x.sshiftRight' 3#8) = ofBool (87#8 <ₛ x)

theorem and_xor_or3_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 64),
  ¬(x_2 = 0 ∨ x_1 = 0 ∨ x = 0 ∨ x = 0) →
    ¬(x_2 = 0 ∨ x = 0) → 42#64 / x_2 ^^^ 42#64 / x_1 &&& 42#64 / x ||

theorem test2_proof : test2_before ⊑ test2_after

theorem t1_ult_slt_0_thm.extracted_1._5 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 <ᵤ 65536#32) = 1#1 → ofBool (65535#32 <ₛ x_1) = 1#1 → x_1 = x

theorem test_mul__none_are_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x == 805306368#32) = 1#1 → BitVec.ofInt 32 (-1342177280) = x * 9#32

theorem test_shl__none_are_safe_thm.extracted_1._4 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& BitVec.ofInt 32 (-2) == 0#32) = 1#1 →
    ¬(2#32 ≥ ↑32 ∨ zeroExtend 64 ((x_1 &&& BitVec.ofInt 32 (-2)) <<< 2#32) ≥ ↑64) →
      ¬(2#32 ≥ ↑32 ∨
            True ∧ (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)).msb = true ∨
              zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)) ≥ ↑64) →
        x.sshiftRight' (zeroExtend 64 ((x_1 &&& BitVec.ofInt 32 (-2)) <<< 2#32)) =
          x.sshiftRight' (zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)))

theorem e_631 :
    2 *  ~~~(x ^^^ y) - 1 *  ~~~x + 1 * (x ^^^ y) - 7 *  ~~~(x &&& y) + 5 *  ~~~y + 2 * (x |||  ~~~y) - 2 *  ~~~(x ||| y) - 5 *  ~~~(x |||  ~~~y) - 12 * (x &&&  ~~~y) - 16 * (x &&& y) =  - 1 *  ~~~(x &&&  ~~~y) - 11 * (x ||| y)

theorem e_1763 :
     - 11 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) - 3 * ( ~~~b &&& (a ^^^ c)) - 6 *  ~~~(b ||| c) - 6 * ((a |||  ~~~b) &&& (b ^^^ c)) - 1 * ((a &&& b) ||| (b ^^^ c)) + 7 * (b ^^^  ~~~(a &&& (b ||| c))) - 6 *  ~~~(a &&& (b ||| c)) + 3 * (a ||| ( ~~~b &&& c)) + 3 *  ~~~(a |||  ~~~c) - 7 *  ~~~(b &&& c) + 11 * ((a ^^^ b) ||| (a ^^^ c)) - 2 *  ~~~( ~~~a ||| (b ^^^ c)) + 1 * (c ^^^ ( ~~~a ||| (b &&& c))) + 7 * (a &&&  ~~~b) - 7 * (c ^^^  ~~~(a &&&  ~~~b)) + 7 * (a ^^^ c) + 1 * (b |||  ~~~c) - 3 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 1 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 3 * (b ||| (a &&&  ~~~c)) + 2 * ( ~~~a ||| ( ~~~b ||| c)) + 1 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 2 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 3 * (a ||| (b ||| c)) + 5 * (b ^^^ (a ||| ( ~~~b ||| c))) - 2 * (b &&& (a ^^^ c)) + 2 * (b ^^^ (a ||| ( ~~~b &&& c))) + 3 * (c ^^^ (a |||  ~~~b)) + 14 *  ~~~(a ||| (b ||| c)) - 4 *  ~~~(a ||| ( ~~~b ||| c)) - 29 *  ~~~( ~~~a ||| (b ||| c)) + 1 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 11 * ( ~~~a &&& (b &&& c)) + 3 * (a &&& ( ~~~b &&& c)) - 5 * (a &&& (b &&& c)) = 13 * ( ~~~a &&& ( ~~~b &&& c)) - 5 *  ~~~( ~~~a &&& ( ~~~b &&& c))

theorem test_logical_proof : test_logical_before ⊑ test_logical_after

theorem e_176 :
     - 1 *  ~~~(x &&& y) + 11 * (x ^^^ y) + 1 *  ~~~(x ||| y) + 1 *  ~~~(x |||  ~~~y) - 10 * (x &&&  ~~~y) + 11 * (x &&& y) = 11 * y

theorem mkSafetyCircuit_eval_eq_false_thm
    {circs : KInductionCircuits fsm n}
    (hCircs : circs.IsLawful)
    (h : ∀ (env : _), (mkSafetyCircuit circs).eval env = false) :
    (∀ (envBitstream : _) (i : Nat), i < n + 1 → fsm.eval envBitstream i = false)

theorem t3_ult_sgt_neg1_thm.extracted_1._5 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 + 16#32 <ᵤ 144#32) = 1#1 →
    ofBool (BitVec.ofInt 32 (-17) <ₛ x_1) = 1#1 →
      ¬ofBool (127#32 <ₛ x_1) = 1#1 → ¬ofBool (x_1 <ₛ BitVec.ofInt 32 (-16)) = 1#1 → x = x_1

theorem urem_i32_c_thm (e : IntW 8) :
  urem (zext 32 e) (const? 32 10) ⊑ zext 32 (urem e (const? 8 10)) { «nneg» := true }

theorem exact_ashr_eq_noexactdiv_proof : exact_ashr_eq_noexactdiv_before ⊑ exact_ashr_eq_noexactdiv_after

theorem ult_rem_nz_nsw_proof : ult_rem_nz_nsw_before ⊑ ult_rem_nz_nsw_after

theorem sle_or_not_min_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 ≤ₛ x) ||

theorem pr64558_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), ¬(x_1 ^^^ 1#1) &&& x = 1#1 → x_1 = x_1 ||

theorem icmp_ne_zext_eq_one_proof : icmp_ne_zext_eq_one_before ⊑ icmp_ne_zext_eq_one_after

theorem test_ashr__exact_is_unsafe_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& BitVec.ofInt 32 (-2147483585) == 0#32) = 1#1 →
    ¬(2#32 ≥ ↑32 ∨ zeroExtend 64 ((x_1 &&& BitVec.ofInt 32 (-2147483585)).sshiftRight' 2#32) ≥ ↑64) →
      2#32 ≥ ↑32 ∨
          True ∧ (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)).msb = true ∨
            zeroExtend 64 (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)) ≥ ↑64 →
        False

theorem land_lor_right1_proof : land_lor_right1_before ⊑ land_lor_right1_after

theorem lor_lor_right1_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 ∨ x = 1#1 → ¬x = 1#1 → False

theorem ashr_ugt_0_proof : ashr_ugt_0_before ⊑ ashr_ugt_0_after

theorem not_and_and_or_not_or_or_commute3_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬((x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true ∨
        (x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true) →
    (x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true → False

theorem masked_bit_set_thm (e e_1 : IntW 32) :
  zext 32 (icmp IntPred.ne (LLVM.and (shl (const? 32 1) e_1) e) (const? 32 0)) ⊑
    LLVM.and (lshr e e_1) (const? 32 1)

theorem e_1084 :
     - 6 * t + 1 *  ~~~(z &&& t) + 1 * z - 6 *  ~~~(z ^^^ t) - 1 * (z ||| t) + 5 *  ~~~(z ||| t) + 6 *  ~~~(z |||  ~~~t) - 1 * (z &&&  ~~~t) =  - 12 * (z &&& t)

theorem test68_xor_proof : test68_xor_before ⊑ test68_xor_after

theorem e_766 :
    1 *  ~~~(z &&& t) - 1 *  ~~~(z &&&  ~~~t) + 1 *  ~~~(z ||| t) + 2 * (z &&& t) = 1 * (z |||  ~~~t)

theorem xor_or_thm.extracted_1._4 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 → ¬x_1 ^^^ 1#1 = 1#1 → 1#1 ^^^ 1#1 = 0#1

theorem ashrsgt_02_04_exact_proof : ashrsgt_02_04_exact_before ⊑ ashrsgt_02_04_exact_after

theorem t1_flags_thm (e e_1 e_2 : IntW 8) :
  sub (sub e_2 e_1 { «nsw» := true, «nuw» := true }) e { «nsw» := true, «nuw» := true } ⊑
    sub e_2 (add e_1 e { «nsw» := true, «nuw» := true }) { «nsw» := true, «nuw» := true }

theorem and_logic_and_logic_or_4_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 &&& x_1 = 1#1 → ¬x_1 = 1#1 → 1#1 = 0#1

theorem e_2244 :
    7 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 3 * (e &&&  ~~~(d &&& f)) - 1 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 2 *  ~~~(d ||| ( ~~~e &&& f)) - 1 *  ~~~( ~~~d &&& (e ^^^ f)) - 5 * ( ~~~d ||| ( ~~~e ||| f)) + 3 * (d ^^^ f) + 11 *  ~~~d + 1 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 3 * (e &&&  ~~~(d &&&  ~~~f)) + 1 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 7 *  ~~~(d ^^^ (e &&& f)) + 4 * ((d ^^^ e) &&& (d ^^^ f)) - 3 * ( ~~~d ||| ( ~~~e &&& f)) - 2 *  ~~~(d &&&  ~~~e) - 1 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 2 * (e ^^^ (d &&&  ~~~f)) + 11 * (f ^^^  ~~~(d &&& (e &&& f))) - 1 * (e |||  ~~~(d ^^^ f)) + 2 * d - 5 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 7 *  ~~~( ~~~d &&& (e ||| f)) - 3 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 1 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 4 * (f ^^^ (d ||| (e ||| f))) - 1 * ((d &&& e) ^^^ (e ||| f)) - 11 * (e ^^^ (d ||| f)) - 1 * ( ~~~e &&& (d ^^^ f)) + 2 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 5 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 7 * (f ^^^ ( ~~~d ||| (e &&& f))) + 2 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 2 * (f |||  ~~~(d |||  ~~~e)) + 2 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 3 *  ~~~(d |||  ~~~f) + 1 *  ~~~(d ||| e) - 1 * ( ~~~e |||  ~~~(d ^^^ f)) + 5 * (f ^^^ (d |||  ~~~e)) + 1 * (f ^^^ (d ||| (e &&& f))) + 7 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 2 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 2 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 5 * (f ^^^  ~~~(d |||  ~~~e)) - 7 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * (f |||  ~~~(d ^^^ e)) + 1 *  ~~~(e &&&  ~~~f) + 2 * (d |||  ~~~e) - 11 * ((d &&& e) |||  ~~~(e ||| f)) + 4 *  ~~~(d ||| (e ||| f)) + 7 *  ~~~(d ||| ( ~~~e ||| f)) + 2 *  ~~~( ~~~d ||| (e ||| f)) + 15 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 4 * ( ~~~d &&& ( ~~~e &&& f)) - 2 * ( ~~~d &&& (e &&& f)) + 47 * (d &&& ( ~~~e &&& f)) + 4 * (d &&& (e &&& f)) = 2 * ((d &&& f) ^^^ (d ^^^ (e &&& f)))

theorem _root_.Pure.pure_cast {f} [inst : Pure f] (b : β) (h : β = α) :
    (pure (cast h b) : f α) = cast (by rw[h]) (pure b : f β)

theorem test10_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ (0#64).ssubOverflow x = true ∨ True ∧ (0#64).ssubOverflow x = true) →
    0#64 - x + (0#64 - x &&& 1#64) = 0#64 - (x &&& BitVec.ofInt 64 (-2))

theorem e_158 :
     - 3 *  ~~~y - 11 *  ~~~(x &&&  ~~~y) - 2 *  ~~~x + 11 *  ~~~(x &&& y) + 2 *  ~~~(x |||  ~~~y) - 8 * (x &&&  ~~~y) =  - 11 * (x &&& y) - 5 *  ~~~(x ||| y)

theorem sdiv_icmp5_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ x.smod (BitVec.ofInt 64 (-5)) ≠ 0 ∨
        (BitVec.ofInt 64 (-5) == 0 || 64 != 1 && x == intMin 64 && BitVec.ofInt 64 (-5) == -1) = true) →
    ofBool (x.sdiv (BitVec.ofInt 64 (-5)) == 1#64) = ofBool (x == BitVec.ofInt 64 (-5))

theorem eq_optimized_highbits_cmp_proof : eq_optimized_highbits_cmp_before ⊑ eq_optimized_highbits_cmp_after

theorem substitute_constant_and_eq_eq_logical_proof : substitute_constant_and_eq_eq_logical_before ⊑ substitute_constant_and_eq_eq_logical_after

theorem t2_ult_sgt_128_thm.extracted_1._4 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 + 16#32 <ᵤ 144#32) = 1#1 → ofBool (127#32 <ₛ x_1) = 1#1 → False

theorem icmp_sgt7_thm (e : IntW 8) :
  icmp IntPred.sgt (shl e (const? 8 1) { «nsw» := true, «nuw» := false }) (const? 8 124) ⊑
    icmp IntPred.sgt e (const? 8 62)

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_5_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 15#32 != 8#32) = 1#1 → ofBool (x &&& 15#32 == 0#32) = ofBool (x &&& 15#32 != 8#32)

theorem main7a_logical_thm.extracted_1._8 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 &&& x_1 == x_2) = 1#1 →
    ¬ofBool (x_2 &&& x_1 != x_2) = 1#1 →
      ¬ofBool (x &&& x_1 == x) = 1#1 → 1#32 = zeroExtend 32 (ofBool (x &&& x_1 != x))

theorem test7_proof : test7_before ⊑ test7_after

theorem e_1217 :
    7 *  ~~~z + 4 *  ~~~(z ^^^ t) - 2 *  ~~~(z &&& t) - 5 * z - 5 *  ~~~(z &&&  ~~~z) - 4 *  ~~~(z ||| t) + 1 *  ~~~(z |||  ~~~t) + 13 * (z &&&  ~~~t) + 6 * (z &&& t) = 1 * (z ^^^ t)

theorem xor_logic_and_logic_or4_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 1), x_2 = 1#1 → ¬x_1 = 1#1 → x_1 ^^^ x = x

theorem e_1363 :
     - 2 *  ~~~(z &&& t) + 7 * t - 2 * (z |||  ~~~t) - 6 * (z ^^^ t) + 11 *  ~~~t - 1 * (z ||| t) + 3 *  ~~~(z ||| t) + 1 *  ~~~(z |||  ~~~t) - 1 * (z &&&  ~~~t) + 6 * (z &&& t) = 11 *  ~~~(z ^^^ t) - 1 *  ~~~(z &&&  ~~~z)

theorem a_true_implies_b_false2_comm_thm.extracted_1._5 : ∀ (x x_1 : BitVec 1) (x_2 : BitVec 8),
  ofBool (x_2 == 10#8) = 1#1 → ofBool (20#8 <ᵤ x_2) = 1#1 → x_1 &&& ofBool (20#8 <ᵤ x_2) = x

theorem icmp_eq_sext_eq_otherwise_proof : icmp_eq_sext_eq_otherwise_before ⊑ icmp_eq_sext_eq_otherwise_after

theorem e_762 :
    1 *  ~~~(z &&&  ~~~z) + 7 * t - 1 * (z |||  ~~~t) - 1 *  ~~~(z |||  ~~~t) =  - 7 * (z &&&  ~~~t) + 7 * (z ||| t)

theorem e_267 :
     - 1 *  ~~~(x ^^^ y) - 3 *  ~~~(x &&&  ~~~y) - 6 * y - 11 *  ~~~(x &&&  ~~~x) + 15 *  ~~~(x ||| y) + 20 *  ~~~(x |||  ~~~y) + 4 * (x &&&  ~~~y) =  - 14 * (x &&& y) - 7 * x

theorem test23_proof : test23_before ⊑ test23_after

theorem not_signbit_proof : not_signbit_before ⊑ not_signbit_after

@[simp_denote] theorem Expr.denote_unfold' {ty} (e : Expr d Γ eff ty) :
    e.denote V = do
      let x ← e.denoteOp V
      return x ++ V

theorem select_icmp_x_and_8_ne_0_y_xor_8_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& 8#32 == 0#32) = 1#1 →
    ¬(True ∧ (x_1 &&& 8#32 ^^^ 8#32).msb = true) → x ^^^ 8#64 = x ^^^ zeroExtend 64 (x_1 &&& 8#32 ^^^ 8#32)

@[simp] theorem toHom_unCons {Γ₁ Γ₂ : Ctxt Ty} (d : Diff (Γ₁.cons t) Γ₂) :
    toHom (unCons d) = fun _ v => (toHom d) v.toCons

theorem or_xor_tree_0100_thm (e e_1 e_2 : IntW 32) :
  LLVM.or (LLVM.xor (mul e_2 (const? 32 42)) (mul e_1 (const? 32 42)))
      (LLVM.xor (mul e_2 (const? 32 42)) (LLVM.xor (mul e_1 (const? 32 42)) (mul e (const? 32 42)))) ⊑
    LLVM.or (LLVM.xor (mul e_2 (const? 32 42)) (mul e_1 (const? 32 42))) (mul e (const? 32 42))

theorem dec_mask_neg_i32_proof : dec_mask_neg_i32_before ⊑ dec_mask_neg_i32_after

theorem main7c_logical_thm.extracted_1._11 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 == x_2 &&& x_1) = 1#1 →
    ¬ofBool (x_2 != x_2 &&& x_1) = 1#1 → 0#1 = 1#1 → 0#32 = zeroExtend 32 (ofBool (x != x &&& x_1))

theorem not_sext_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → -1#999 = signExtend 999 (x ^^^ 1#1)

theorem icmp_eq_sext_ne_zero_thm (e : IntW 32) :
  icmp IntPred.eq (sext 32 (icmp IntPred.ne e (const? 32 0))) e ⊑
    icmp IntPred.ult (add e (const? 32 1)) (const? 32 2)

theorem gt_signed_to_small_negative_proof : gt_signed_to_small_negative_before ⊑ gt_signed_to_small_negative_after

theorem mul_of_pow2_proof : mul_of_pow2_before ⊑ mul_of_pow2_after

theorem test1_thm (e : IntW 33) : urem e (const? 33 4096) ⊑ LLVM.and e (const? 33 4095)

theorem ashr_ult_1_proof : ashr_ult_1_before ⊑ ashr_ult_1_after

theorem ne_smax1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x <ₛ x_1) = 1#1 → ofBool (x != x_1) = ofBool (x_1 <ₛ x)

theorem t3_thm (e : IntW 8) (e_1 : IntW 2) :
  LLVM.xor (add (sext 8 e_1) e) (sext 8 e_1) ⊑ LLVM.xor (add e (sext 8 e_1)) (sext 8 e_1)

theorem ule_swap_or_not_min_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 != 0#8) ||

theorem ashrslt_03_06_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 3#4 <<< 3#4 ≠ x ∨ 3#4 ≥ ↑4) → ofBool (x.sshiftRight' 3#4 <ₛ 6#4) = 1#1

theorem lshr_xor_thm.extracted_1._1 : ∀ (x : BitVec 8), ¬(x ≥ ↑8 ∨ x + 1#8 ≥ ↑8) → x ≥ ↑8 → False

theorem eq_umax1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x <ᵤ x_1) = 1#1 → ofBool (x == x_1) = ofBool (x ≤ᵤ x_1)

theorem a_false_implies_b_true2_thm (e e_1 : IntW 1) (e_2 : IntW 8) :
  LLVM.or (icmp IntPred.ugt e_2 (const? 8 10)) (select (icmp IntPred.ult e_2 (const? 8 20)) e_1 e) ⊑
    select (icmp IntPred.ugt e_2 (const? 8 10)) (const? 1 1) e_1

theorem negation_of_increment_via_or_with_no_common_bits_set_proof : negation_of_increment_via_or_with_no_common_bits_set_before ⊑ negation_of_increment_via_or_with_no_common_bits_set_after

theorem test_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬(17#32 ≥ ↑32 ∨ 17#32 ≥ ↑32) → 31#32 ≥ ↑32 → False

theorem ugt_rem_nz_nsw_thm (e : IntW 8) :
  icmp IntPred.ugt (mul e (const? 8 5) { «nsw» := true, «nuw» := true }) (const? 8 21) ⊑
    icmp IntPred.ugt e (const? 8 4)

theorem ashr_ne_exact_proof : ashr_ne_exact_before ⊑ ashr_ne_exact_after

theorem PR2539_A_proof : PR2539_A_before ⊑ PR2539_A_after

theorem add_or_sub_comb_i64_commuted4_thm (e : IntW 64) :
  add (mul e e) (LLVM.or (mul e e) (sub (const? 64 0) (mul e e))) ⊑
    LLVM.and (add (mul e e) (const? 64 (-1))) (mul e e)

theorem drop_nsw_trunc_proof : drop_nsw_trunc_before ⊑ drop_nsw_trunc_after

theorem BitVec.getLsbD_eq_toInt_testBit' (b : BitVec w) (hk : k < w) : b.getLsbD k = b.toInt.testBit' k

theorem t3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(32#32 - x ≥ ↑32 ∨ zeroExtend 64 (x + BitVec.ofInt 32 (-16)) ≥ ↑64) →
    ofBool (x_1 <<< (32#32 - x) &&& truncate 32 (131071#64 >>> zeroExtend 64 (x + BitVec.ofInt 32 (-16))) != 0#32) =
      ofBool (x_1 &&& 1#32 != 0#32)

theorem land_bor_right1_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1), ¬x_1 = 1#1 → x_1 ||

@[bv_multi_width_normalize] theorem BitVec.lt_eq_ult {x y : BitVec w} :
    (x < y) = ((x.ult y) = true)

theorem trunc_sel_larger_zext_proof : trunc_sel_larger_zext_before ⊑ trunc_sel_larger_zext_after

theorem test7_thm.extracted_1._1 : ∀ (x : BitVec 1024),
  ¬(1023#1024 ≥ ↑1024 ∨ 1023#1024 ≥ ↑1024) → (x ^^^ 1#1024 <<< 1023#1024) + 1#1024 <<< 1023#1024 = x

theorem trunc_shl_shl_var_thm.extracted_1._2 : ∀ (x x_1 : BitVec 64),
  ¬(x ≥ ↑64 ∨ 2#64 ≥ ↑64) →
    ¬(x ≥ ↑64 ∨ 2#32 ≥ ↑32) → truncate 32 (x_1 <<< x <<< 2#64) = truncate 32 (x_1 <<< x) <<< 2#32

theorem test5_proof : test5_before ⊑ test5_after

theorem icmp_eq_and_pow2_minus1_shl1_thm (e : IntW 32) :
  zext 32 (icmp IntPred.eq (LLVM.and (shl (const? 32 1) e) (const? 32 15)) (const? 32 0)) ⊑
    zext 32 (icmp IntPred.ugt e (const? 32 3))

theorem lshrugt_02_04_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 2#4 <<< 2#4 ≠ x ∨ 2#4 ≥ ↑4) → ofBool (4#4 <ᵤ x >>> 2#4) = 0#1

theorem negate_add_with_single_negatible_operand_depth2_proof : negate_add_with_single_negatible_operand_depth2_before ⊑ negate_add_with_single_negatible_operand_depth2_after

theorem test_nuw_nsw_and_unsigned_pred_proof : test_nuw_nsw_and_unsigned_pred_before ⊑ test_nuw_nsw_and_unsigned_pred_after

theorem lshrugt_03_07_exact_thm (e : IntW 4) :
  icmp IntPred.ugt (lshr e (const? 4 3) { «exact» := true }) (const? 4 7) ⊑ const? 1 0

theorem src_is_mask_const_sle_thm (e : IntW 8) :
  icmp IntPred.sle (LLVM.and (LLVM.xor e (const? 8 123)) (const? 8 31)) (LLVM.xor e (const? 8 123)) ⊑
    icmp IntPred.sgt e (const? 8 (-1))

theorem negate_sdiv_proof : negate_sdiv_before ⊑ negate_sdiv_after

theorem n1_proof : n1_before ⊑ n1_after

theorem test11b_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  (x_1 ^^^ -1#32 ^^^ x) &&& (x ^^^ x_1) = (x ^^^ x_1) &&& (x_1 ^^^ x ^^^ -1#32)

theorem lshr_shl_pow2_const_xor_proof : lshr_shl_pow2_const_xor_before ⊑ lshr_shl_pow2_const_xor_after

theorem e_643 :
    4 * (x |||  ~~~y) + 1 * (x ||| y) - 1 *  ~~~(x &&&  ~~~y) - 11 *  ~~~(x ^^^ y) + 5 * x + 1 * y + 10 *  ~~~(x ||| y) - 6 *  ~~~(x |||  ~~~y) - 15 * (x &&&  ~~~y) + 3 * (x &&& y) =  - 7 * (x ^^^ y) + 2 *  ~~~(x &&&  ~~~x)

theorem ashr_ne_both_equal_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → ofBool ((BitVec.ofInt 8 (-128)).sshiftRight' x != BitVec.ofInt 8 (-128)) = ofBool (x != 0#8)

@[simp] theorem Lets.getPureExpr_var_appendInl (lets : Lets d Γ_in eff Γ_out)
    (e : Expr d Γ_out eff ty) (v : Var ⟨ty⟩ u) :
    getPureExpr (lets.var e) v.appendInl
    = e.toPure?.map (fun e => ⟨_, v, e.changeVars <| e.contextHom⟩)

theorem e_891 :
     - 7 * (z |||  ~~~t) - 6 *  ~~~t - 6 * (z ^^^ t) + 7 * (z ||| t) + 13 *  ~~~(z ||| t) - 1 *  ~~~(z |||  ~~~t) =  - 12 * (z &&&  ~~~t)

theorem ashrsgt_01_07_exact_thm (e : IntW 4) :
  icmp IntPred.sgt (ashr e (const? 4 1) { «exact» := true }) (const? 4 7) ⊑ const? 1 0

theorem sub_select_not_zext_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  x_1 = 1#1 → x - zeroExtend 64 (x_1 ^^^ 1#1) = x

theorem test_proof : test_before ⊑ test_after

theorem t0_thm (e e_1 : IntW 8) :
  ashr (LLVM.xor e_1 (const? 8 (-1))) e ⊑ LLVM.xor (ashr e_1 e) (const? 8 (-1))

theorem xor_icmp_invalid_range_proof : xor_icmp_invalid_range_before ⊑ xor_icmp_invalid_range_after

theorem e_1827 :
     - 3 * (c ^^^ (a |||  ~~~b)) - 1 * (c &&& (a ^^^ b)) - 7 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 11 *  ~~~( ~~~a ||| (b ^^^ c)) + 11 *  ~~~(a &&&  ~~~c) - 1 * (a ^^^ b) + 3 *  ~~~b + 4 * ((a &&& c) |||  ~~~(b ||| c)) - 2 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) - 11 * (c ^^^ ( ~~~a &&& (b ||| c))) + 4 * (b &&&  ~~~(a &&&  ~~~c)) - 6 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) + 2 * a + 1 * ((a &&& b) ^^^  ~~~(a ^^^ (b &&& c))) - 3 *  ~~~c + 7 * ((a ^^^ b) |||  ~~~(a ^^^ c)) + 5 * ( ~~~b &&&  ~~~(a ^^^ c)) + 1 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) - 11 * (a &&& b) + 5 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) + 11 * ((a ^^^ b) ||| (a ^^^ c)) - 5 * (a |||  ~~~c) - 2 *  ~~~(a ||| b) - 1 * (b ^^^  ~~~(a ||| (b &&& c))) + 7 * (a &&& (b ||| c)) + 4 * (b &&& c) + 2 *  ~~~(b |||  ~~~c) + 1 * (a ^^^ c) - 6 * ((a |||  ~~~b) &&& (b ^^^ c)) + 1 * ((a &&& b) ||| (b ^^^ c)) + 1 * ((b &&& c) ||| (a &&& (b ||| c))) - 3 * ((a &&&  ~~~b) ||| (b ^^^ c)) + 2 * (b |||  ~~~(a |||  ~~~c)) - 6 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 1 *  ~~~(a ^^^ (b ||| c)) - 6 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) - 12 *  ~~~(a ||| (b ||| c)) + 26 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 3 * ( ~~~a &&& ( ~~~b &&& c)) - 19 * ( ~~~a &&& (b &&& c)) - 12 * (a &&& ( ~~~b &&& c)) - 15 * (a &&& (b &&& c)) = 1 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 11 * ((a ||| b) &&& (a ^^^ (b ^^^ c)))

theorem lshrult_01_13_exact_thm (e : IntW 4) :
  icmp IntPred.ult (lshr e (const? 4 1) { «exact» := true }) (const? 4 (-3)) ⊑ const? 1 1

theorem main1_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 1#32 != 0#32) = 1#1 →
    ¬ofBool (x &&& 3#32 == 3#32) = 1#1 → ofBool (x &&& 2#32 != 0#32) = 1#1 → 2#32 = 1#32

theorem e_97 :
     - 2 * x + 7 *  ~~~(x &&&  ~~~y) + 4 *  ~~~x + 11 *  ~~~y - 9 * (x &&&  ~~~y) - 5 * (x &&& y) = 22 *  ~~~(x ||| y) + 11 *  ~~~(x |||  ~~~y)

theorem t13_x_is_one_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬(32#32 - x_1 ≥ ↑32 ∨ zeroExtend 64 (x_1 + BitVec.ofInt 32 (-16)) ≥ ↑64) →
    ofBool (1#32 <<< (32#32 - x_1) &&& truncate 32 (x >>> zeroExtend 64 (x_1 + BitVec.ofInt 32 (-16))) != 0#32) =
      ofBool (x &&& 65536#64 != 0#64)

theorem bad_add1_proof : bad_add1_before ⊑ bad_add1_after

theorem main7c_logical_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 == x_2 &&& x_1) = 1#1 →
    ofBool (x_2 != x_2 &&& x_1) = 1#1 → ¬ofBool (x == x &&& x_1) = 1#1 → 1#32 = zeroExtend 32 1#1

theorem e_1790 :
     - 1 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) - 11 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) - 6 *  ~~~(a ^^^ (b &&& c)) + 4 * ((a ^^^ b) &&& (a ^^^ c)) - 2 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 1 * ( ~~~a &&& ( ~~~b ||| c)) - 5 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) - 1 *  ~~~(b &&&  ~~~c) + 1 * (a &&&  ~~~b) + 1 * (c ^^^ (a ||| b)) + 2 * ((a &&& c) ^^^ (a ^^^ (b &&& c))) + 3 * (b &&&  ~~~(a &&&  ~~~c)) + 3 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) - 5 * ( ~~~a &&& (b ||| c)) + 7 * (b &&& (a ^^^ c)) + 5 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) - 2 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) - 1 *  ~~~(a |||  ~~~b) - 7 * ( ~~~c |||  ~~~(a ^^^ b)) - 7 * ( ~~~b &&&  ~~~(a ^^^ c)) + 2 * ((a &&& b) ^^^ (a ^^^ ( ~~~b ||| c))) + 1 * ( ~~~b |||  ~~~(a ^^^ c)) - 11 * (b ^^^ c) - 11 * (c ^^^ (a |||  ~~~b)) + 4 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 5 * (c ^^^ (a &&& b)) - 3 * (b ^^^ (a ||| (b &&& c))) + 2 *  ~~~(a ||| (b ^^^ c)) + 3 * (b ^^^ (a ||| (b ||| c))) + 7 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) + 23 *  ~~~(a ||| (b ||| c)) + 52 *  ~~~(a ||| ( ~~~b ||| c)) + 11 *  ~~~( ~~~a ||| (b ||| c)) + 21 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 22 * ( ~~~a &&& ( ~~~b &&& c)) - 22 * ( ~~~a &&& (b &&& c)) + 2 * (a &&& ( ~~~b &&& c)) + 5 * (a &&& (b &&& c)) = 3 * (c ^^^  ~~~(a &&&  ~~~b)) - 2 * (a &&& (b ||| c))

theorem annihilate_xor_common_op_commute2_thm (e e_1 e_2 e_3 : IntW 4) :
  LLVM.xor (LLVM.xor (LLVM.xor (mul e_3 e_3) (LLVM.xor e_2 e_1)) e) e_2 ⊑
    LLVM.xor (LLVM.xor e_1 (mul e_3 e_3)) e

theorem positive_biggerashr_shlnsw_thm (e : IntW 8) :
  shl (ashr e (const? 8 6)) (const? 8 3) { «nsw» := true, «nuw» := false } ⊑
    LLVM.and (ashr e (const? 8 3)) (const? 8 (-8))

theorem and_xor_or3_proof : and_xor_or3_before ⊑ and_xor_or3_after

theorem lowmask_sub_zext_commute_proof : lowmask_sub_zext_commute_before ⊑ lowmask_sub_zext_commute_after

theorem negative_and_odd_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬((2#32 == 0 || 32 != 1 && x == intMin 32 && 2#32 == -1) = true ∨ 31#32 ≥ ↑32) →
    ¬31#32 ≥ ↑32 → x.srem 2#32 >>> 31#32 = x >>> 31#32 &&& x

theorem t0_commutative_thm.extracted_1._7 : ∀ (x x_1 x_2 : BitVec 8),
  ¬ofBool (x_2 == x_1) = 1#1 → ¬ofBool (x_2 != x_1) = 1#1 → ¬0#1 = 1#1 → False

theorem icmp_sgt10_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (x <<< 7#8).sshiftRight' 7#8 ≠ x ∨ 7#8 ≥ ↑8) →
    ofBool (BitVec.ofInt 8 (-127) <ₛ x <<< 7#8) = ofBool (-1#8 <ₛ x)

@[simp]
theorem EnvFin.getLsbD_getLsb {w : Nat} (env : EnvFin (w + 1) n) (bit : Nat) : (env.getLsb i).getLsbD bit =
    if bit = 0 then (env i)[0] else false

theorem test_sub_nuw__all_are_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 255#32 == 6#32) = 1#1 →
    True ∧ (BitVec.ofInt 32 (-254)).ssubOverflow (x &&& 255#32) = true ∨
        True ∧ (BitVec.ofInt 32 (-254)).usubOverflow (x &&& 255#32) = true →
      False

theorem t0_commutative_thm.extracted_1._18 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1) (x_3 x_4 : BitVec 8),
  ofBool (x_4 == x_3) = 1#1 → ofBool (x_4 != x_3) = 1#1 → ¬True → x_2 = 1#1 → x_1 = x

theorem t4_ugt_slt_128_thm.extracted_1._12 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (143#32 <ᵤ x_2 + 16#32) = 1#1 →
    ¬ofBool (x_2 <ₛ 128#32) = 1#1 →
      ¬ofBool (127#32 <ₛ x_2) = 1#1 → ofBool (x_2 <ₛ BitVec.ofInt 32 (-16)) = 1#1 → x = x_1

theorem sext_diff_i1_xor_sub_1_proof : sext_diff_i1_xor_sub_1_before ⊑ sext_diff_i1_xor_sub_1_after

theorem reassoc_x2_sub_nuw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.usubOverflow 4#32 = true ∨
        True ∧ x.usubOverflow 8#32 = true ∨ True ∧ (x_1 - 4#32).usubOverflow (x - 8#32) = true) →
    x_1 - 4#32 - (x - 8#32) = x_1 - x + 4#32

theorem is_ascii_alphabetic_thm (e : IntW 32) :
  select (icmp IntPred.ult (add e (const? 32 (-65)) { «nsw» := true, «nuw» := false }) (const? 32 26)) (const? 1 1)
      (icmp IntPred.ult (add e (const? 32 (-97)) { «nsw» := true, «nuw» := false }) (const? 32 26)) ⊑
    icmp IntPred.ult (add (LLVM.and e (const? 32 (-33))) (const? 32 (-65))) (const? 32 26)

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_7_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_swapped_7_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_swapped_7_logical_after

theorem ashrslt_02_01_proof : ashrslt_02_01_before ⊑ ashrslt_02_01_after

theorem reassoc_add_nuw_proof : reassoc_add_nuw_before ⊑ reassoc_add_nuw_after

theorem or_not_and_and_not_and_xor_commute2_thm (e e_1 e_2 : IntW 32) :
  LLVM.and (LLVM.or (LLVM.sdiv (const? 32 42) e_2) (LLVM.xor (LLVM.and e_1 e) (const? 32 (-1))))
      (LLVM.xor (LLVM.and (LLVM.xor e_1 e) (LLVM.sdiv (const? 32 42) e_2)) (const? 32 (-1))) ⊑
    LLVM.xor (LLVM.and (LLVM.xor e_1 e) (LLVM.sdiv (const? 32 42) e_2))
      (LLVM.or (LLVM.sdiv (const? 32 42) e_2) (LLVM.xor (LLVM.and e_1 e) (const? 32 (-1))))

theorem main4d_proof : main4d_before ⊑ main4d_after

theorem bools2_logical_commute0_thm.extracted_1._2 : ∀ (x : BitVec 1),
  ¬x = 1#1 → ¬x ^^^ 1#1 = 1#1 → 0#1 = 1#1 → False

theorem ne_irregular_bit_widths_thm.extracted_1._1 : ∀ (x x_1 : BitVec 31),
  ¬(13#31 ≥ ↑31 ∨ 13#31 ≥ ↑31 ∨ 7#31 ≥ ↑31 ∨ 7#31 ≥ ↑31) → 7#31 ≥ ↑31 ∨ 7#31 ≥ ↑31 → False

theorem main5f_like_logical_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 &&& x_1 != x_2) = 1#1 →
    ofBool (x_2 &&& x_1 == x_2) = 1#1 → ¬True → 0#32 = zeroExtend 32 (ofBool (x_2 &&& x == x_2))

theorem pr40493_neg2_thm (e : IntW 32) :
  icmp IntPred.eq (LLVM.and (mul e (const? 32 12)) (const? 32 15)) (const? 32 0) ⊑
    icmp IntPred.eq (LLVM.and (mul e (const? 32 12)) (const? 32 12)) (const? 32 0)

theorem e_1909 :
    11 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) + 3 *  ~~~(a &&& (b &&& c)) + 11 * ((a &&&  ~~~b) ||| (a ^^^ (b ^^^ c))) + 5 * (c ^^^ ( ~~~a ||| (b &&& c))) - 7 * (b |||  ~~~c) + 1 * ((a &&& b) |||  ~~~(b |||  ~~~c)) - 7 *  ~~~(a ^^^ ( ~~~b ||| c)) - 3 * ( ~~~a &&& (b ||| c)) - 7 * (b ||| c) + 1 * (a ^^^ b) - 1 * (b ^^^ (a ||| c)) - 1 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) - 11 * (a ||| b) - 1 * (a ||| ( ~~~b ||| c)) + 4 * (c ^^^  ~~~(a &&& (b &&& c))) + 7 * (b ^^^ (a ||| (b &&& c))) + 11 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) + 2 * (b ||| (a ^^^ c)) + 1 * (c &&&  ~~~(a ^^^ b)) + 11 * (c ^^^ (a &&& ( ~~~b ||| c))) + 1 * ( ~~~a ||| (b ||| c)) - 2 * (c ^^^  ~~~(a &&&  ~~~b)) + 1 * (a ||| (b ||| c)) - 2 * (c ^^^ (a ||| ( ~~~b ||| c))) + 3 * ( ~~~b &&&  ~~~(a ^^^ c)) + 4 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 2 *  ~~~(b |||  ~~~c) - 1 * (a ^^^ c) + 1 *  ~~~(b &&& c) + 3 * (c &&&  ~~~(a &&& b)) - 3 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 1 * (a ^^^ (b &&& c)) - 6 *  ~~~(a ||| c) - 1 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) - 11 * (b ^^^ ( ~~~a &&& (b ||| c))) + 1 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 2 * ((a &&& b) ^^^ (b |||  ~~~c)) - 7 * (a |||  ~~~c) - 3 * (c &&& (a ^^^ b)) + 11 *  ~~~(a &&& c) - 2 * ((a &&& c) ^^^ (a ^^^ (b &&& c))) + 2 * (c |||  ~~~(a |||  ~~~b)) - 13 *  ~~~(a ||| (b ||| c)) - 5 *  ~~~(a ||| ( ~~~b ||| c)) - 9 *  ~~~( ~~~a ||| (b ||| c)) + 27 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 36 * ( ~~~a &&& ( ~~~b &&& c)) + 6 * ( ~~~a &&& (b &&& c)) - 5 * (a &&& ( ~~~b &&& c)) + 8 * (a &&& (b &&& c)) = 2 * (c ^^^ (a &&& (b ||| c))) + 11 * (b ^^^ ( ~~~a ||| (b &&& c)))

theorem e_1679 :
    1 * (a ||| (b ||| c)) + 11 * (b &&&  ~~~(a ^^^ c)) - 11 * (a &&&  ~~~b) + 5 * ( ~~~(a &&& b) &&& (b ^^^ c)) + 7 * ( ~~~c &&& (a ^^^ b)) - 1 * (c ^^^  ~~~(a &&&  ~~~b)) - 1 * (a ^^^ (b ^^^ c)) + 1 * (c ^^^  ~~~(a &&& ( ~~~b ||| c))) + 11 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) + 4 * ((a &&& b) ||| (b ^^^ c)) - 1 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 2 * (b ^^^ (a ||| (b ||| c))) - 11 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) + 7 * (b ^^^ ( ~~~a ||| (b ^^^ c))) + 2 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 11 * ((a &&& b) ^^^ (b ||| c)) - 1 * (c |||  ~~~(a |||  ~~~b)) + 1 * (c ^^^ ( ~~~a ||| (b ||| c))) + 1 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 11 *  ~~~(a ||| (b ||| c)) - 26 *  ~~~(a ||| ( ~~~b ||| c)) + 10 *  ~~~( ~~~a ||| (b ||| c)) - 29 * ( ~~~a &&& ( ~~~b &&& c)) - 23 * ( ~~~a &&& (b &&& c)) - 31 * (a &&& ( ~~~b &&& c)) - 11 * (a &&& (b &&& c)) =  - 1 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 7 *  ~~~( ~~~a ||| ( ~~~b ||| c))

theorem mul_constant_mismatch_wrap_eq_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.smulOverflow 54#32 = true ∨ True ∧ x.umulOverflow 54#32 = true) →
    ofBool (x_1 * 54#32 == x * 54#32) = ofBool ((x_1 ^^^ x) &&& 2147483647#32 == 0#32)

theorem lshrugt_01_13_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬1#4 ≥ ↑4 → ofBool (BitVec.ofInt 4 (-3) <ᵤ x >>> 1#4) = 0#1

theorem neg_or_lshr_i32_proof : neg_or_lshr_i32_before ⊑ neg_or_lshr_i32_after

theorem select_icmp_ne_0_and_32_or_4096_thm.extracted_1._4 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (0#32 != x_1 &&& 32#32) = 1#1 → ¬7#32 ≥ ↑32 → x ||

theorem sgt_smin4_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x <ₛ x_1 + 3#32) = 1#1 → ofBool (x_1 + 3#32 <ₛ x_1 + 3#32) = 0#1

theorem slt_zero_eq_ne_0_fail2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬30#32 ≥ ↑32 →
    ofBool (zeroExtend 32 (ofBool (x != 0#32)) == x >>> 30#32) =
      ofBool (x >>> 30#32 == zeroExtend 32 (ofBool (x != 0#32)))

theorem sle_smin2_thm (e e_1 : IntW 32) :
  icmp IntPred.sle (select (icmp IntPred.slt e_1 e) e_1 e) e ⊑ const? 1 1

theorem lshr_add_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(5#8 ≥ ↑8 ∨ (42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true ∨ 5#8 ≥ ↑8) →
    (42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true ∨ 5#8 ≥ ↑8 → False

theorem test_sgt_xor_thm (e e_1 : IntW 32) :
  icmp IntPred.sgt (LLVM.xor (LLVM.xor e_1 (const? 32 (-1))) e) (LLVM.xor e_1 (const? 32 (-1))) ⊑
    icmp IntPred.slt (LLVM.xor e e_1) e_1

theorem Holor.reindex_functorial
  (ix : HolorIndex ds₂ → HolorIndex ds₁) (iy : HolorIndex ds₃ → HolorIndex ds₂)
  (h : Holor α ds₁) : Holor.reindex iy (Holor.reindex ix h) = Holor.reindex (ix ∘ iy) h

theorem e_2157 :
     - 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 2 * ( ~~~d ||| (e ^^^ f)) + 2 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 1 * ( ~~~d &&& ( ~~~e ||| f)) + 1 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 *  ~~~(d ^^^ f) - 1 * (e ^^^ (d &&& (e ^^^ f))) - 2 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 1 *  ~~~(d |||  ~~~e) - 6 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 11 * (e ||| (d &&& f)) + 1 *  ~~~(d ||| (e ^^^ f)) - 6 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 6 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 1 * ((d &&& e) ||| (e ^^^ f)) - 1 * (e &&& (d |||  ~~~f)) + 11 *  ~~~(d &&&  ~~~d) - 3 *  ~~~( ~~~d ||| (e &&& f)) + 3 * (d &&& e) + 1 * ((d &&& e) ^^^ (e |||  ~~~f)) - 11 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 5 * (e ^^^ (d ||| (e &&& f))) - 2 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) + 1 * (f &&& (d |||  ~~~e)) + 1 * (f ^^^ (d ||| ( ~~~e ||| f))) + 2 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 1 * (e ^^^  ~~~(d &&& f)) + 1 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 4 * ((d ^^^ e) ||| (d ^^^ f)) + 2 * (f ^^^ ( ~~~d ||| (e &&& f))) + 1 * ((d &&& f) ||| (e &&&  ~~~f)) - 3 *  ~~~(d ||| f) - 6 * (e ^^^ (d |||  ~~~f)) + 4 *  ~~~( ~~~d ||| ( ~~~e &&& f)) + 11 * (e &&&  ~~~(d &&&  ~~~f)) - 7 *  ~~~( ~~~d &&& (e ^^^ f)) + 2 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 7 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 5 * (d ||| (e ||| f)) - 2 *  ~~~(d &&& (e ^^^ f)) - 3 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 15 *  ~~~(d ||| (e ||| f)) - 1 *  ~~~(d ||| ( ~~~e ||| f)) - 8 *  ~~~( ~~~d ||| (e ||| f)) + 6 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 1 * ( ~~~d &&& ( ~~~e &&& f)) + 22 * (d &&& ( ~~~e &&& f)) + 7 * (d &&& (e &&& f)) =  - 2 * ( ~~~d ||| (e &&& f))

theorem select_shl_icmp_bad_thm.extracted_1._3 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 == 1#32) = 1#1 → ¬x_2 ≥ ↑32 → 1#32 ≥ ↑32 → False

@[simp_llvm_option]
theorem LLVM.IntW.value_isRefinedBy_iff (a : BitVec w) (b? : PoisonOr (BitVec w)) :
    value a ⊑ b? ↔ b? = value a

theorem not_or_or_and_no_and_commute1_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  (x_2 ^^^ -1#32 ||| x_1 ||| x) &&& (x_2 &&& x_1 ^^^ -1#32) = x &&& (x_1 ^^^ -1#32) ||

theorem test51_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  x_1 = 1#1 →
    ¬(True ∧ (truncate 32 x &&& BitVec.ofInt 32 (-2) &&& zeroExtend 32 (x_1 ^^^ 1#1) != 0) = true) →
      signExtend 64 (truncate 32 x &&& BitVec.ofInt 32 (-2)) =
        signExtend 64 (truncate 32 x &&& BitVec.ofInt 32 (-2) ||| zeroExtend 32 (x_1 ^^^ 1#1))

theorem sub_ashr_or_i32_nuw_nsw_proof : sub_ashr_or_i32_nuw_nsw_before ⊑ sub_ashr_or_i32_nuw_nsw_after

theorem ashrsgt_01_00_exact_proof : ashrsgt_01_00_exact_before ⊑ ashrsgt_01_00_exact_after

theorem bool_add_ashr_thm (e e_1 : IntW 1) :
  ashr (add (zext 2 e_1) (zext 2 e)) (const? 2 1) ⊑
    ashr (add (zext 2 e_1) (zext 2 e) { «nsw» := false, «nuw» := true }) (const? 2 1)

theorem test10_commuted_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  x_1 ^^^ -1#32 ^^^ x ||

theorem t1_otherbitwidth_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(15#16 ≥ ↑16 ∨ 15#16 ≥ ↑16) →
    ¬(True ∧ (0#16).ssubOverflow (x &&& 1#16) = true) → (x <<< 15#16).sshiftRight' 15#16 = 0#16 - (x &&& 1#16)

theorem test32_thm (e : IntW 32) :
  LLVM.and (lshr (LLVM.and e (const? 32 16)) (const? 32 2)) (const? 32 1) ⊑ const? 32 0

theorem e_723 :
     - 5 *  ~~~y - 11 *  ~~~x - 5 * (x ^^^ y) + 1 *  ~~~(x &&& y) + 1 *  ~~~(x &&&  ~~~y) - 1 * (x ||| y) + 2 * y + 14 *  ~~~(x ||| y) + 13 *  ~~~(x |||  ~~~y) + 9 * (x &&&  ~~~y) - 3 * (x &&& y) =  - 1 * x

theorem test7_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(4#32 == 0 || 32 != 1 && x * 8#32 == intMin 32 && 4#32 == -1) = true → (x * 8#32).srem 4#32 = 0#32

theorem sdiv_x_by_const_cmp_x_proof : sdiv_x_by_const_cmp_x_before ⊑ sdiv_x_by_const_cmp_x_after

theorem or_to_nxor3_thm (e e_1 : IntW 32) :
  LLVM.or (LLVM.xor (LLVM.or e_1 e) (const? 32 (-1))) (LLVM.and e_1 e) ⊑
    LLVM.xor (LLVM.xor e_1 e) (const? 32 (-1))

theorem lshr_C1_add_A_C2_i32_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(x &&& 65535#32) + 5#32 ≥ ↑32 →
    ¬x &&& 65535#32 ≥ ↑32 → 6#32 <<< ((x &&& 65535#32) + 5#32) = 192#32 <<< (x &&& 65535#32)

theorem test13_thm (e e_1 : IntW 8) :
  LLVM.xor (icmp IntPred.ult e_1 e) (icmp IntPred.ugt e_1 e) ⊑ icmp IntPred.ne e_1 e

theorem udiv_common_divisor_defined_cond_proof : udiv_common_divisor_defined_cond_before ⊑ udiv_common_divisor_defined_cond_after

theorem substitute_constant_and_ne_ugt_swap_logical_proof : substitute_constant_and_ne_ugt_swap_logical_before ⊑ substitute_constant_and_ne_ugt_swap_logical_after

theorem zext_sext_add_icmp_ne_minus1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  ofBool (zeroExtend 8 x_1 + signExtend 8 x != -1#8) = x_1 ||

theorem bitwise_or_logical_or_icmps_comm1_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 8),
  ¬x_1 ≥ ↑8 →
    ¬ofBool (x == 42#8) = 1#1 →
      True ∧ 1#8 <<< x_1 >>> x_1 ≠ 1#8 ∨ x_1 ≥ ↑8 ∨ True ∧ 1#8 <<< x_1 >>> x_1 ≠ 1#8 ∨ x_1 ≥ ↑8 → False

theorem t0_thm.extracted_1._22 : ∀ (x x_1 x_2 x_3 : BitVec 8) (x_4 : BitVec 1),
  ¬x_4 ^^^ 1#1 = 1#1 → x_4 = 1#1 → 0#1 = 1#1 → x_1 = x

theorem icmp_eq_zext_ne_zero_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (zeroExtend 32 (ofBool (x != 0#32)) == x) = ofBool (x <ᵤ 2#32)

theorem fixed (x : BitVec 4) (y : BitVec 7) : 
    (BitVec.signExtend 32 x < BitVec.signExtend 32 y) ↔ (BitVec.signExtend 7 x < y)

theorem test40_proof : test40_before ⊑ test40_after

theorem test_shl_nsw__none_are_safe_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& BitVec.ofInt 32 (-2) == 0#32) = 1#1 →
    ¬(2#32 ≥ ↑32 ∨
          True ∧ (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)).msb = true ∨
            zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)) ≥ ↑64) →
      x = x.sshiftRight' (zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)))

theorem e_851 :
    3 *  ~~~(z &&&  ~~~z) - 2 * (z ^^^ t) - 1 *  ~~~(z &&&  ~~~t) - 7 * (z |||  ~~~t) + 5 *  ~~~(z ||| t) + 5 * (z &&& t) =  - 6 * (z &&&  ~~~t)

theorem test_const_shr_exact_and_1_ne_0_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ 42#32 >>> x <<< x ≠ 42#32 ∨ x ≥ ↑32) → True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨ x ≥ ↑32 → False

theorem t0_thm (e : IntW 8) :
  LLVM.sdiv e (const? 8 32) { «exact» := true } ⊑ ashr e (const? 8 5) { «exact» := true }

theorem ashrsgt_01_06_thm.extracted_1._1 : ∀ (x : BitVec 4), ¬1#4 ≥ ↑4 → ofBool (6#4 <ₛ x.sshiftRight' 1#4) = 0#1

theorem foo_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ (x &&& 223#32 ^^^ 29#32).uaddOverflow (BitVec.ofInt 32 (-784568073)) = true ∨
        True ∧
            (((x &&& 223#32 ^^^ 29#32 ||| 1874836915#32) ^^^
                      ((x &&& 223#32 ^^^ 29#32) &&& 221#32 ^^^ 1874836915#32)) <<<
                    1#32).sshiftRight'
                1#32 ≠
              (x &&& 223#32 ^^^ 29#32 ||| 1874836915#32) ^^^ ((x &&& 223#32 ^^^ 29#32) &&& 221#32 ^^^ 1874836915#32) ∨
          True ∧
              ((x &&& 223#32 ^^^ 29#32 ||| 1874836915#32) ^^^
                      ((x &&& 223#32 ^^^ 29#32) &&& 221#32 ^^^ 1874836915#32)) <<<
                    1#32 >>>
                  1#32 ≠
                (x &&& 223#32 ^^^ 29#32 ||| 1874836915#32) ^^^ ((x &&& 223#32 ^^^ 29#32) &&& 221#32 ^^^ 1874836915#32) ∨
            1#32 ≥ ↑32 ∨
              True ∧
                ((x &&& 223#32 ^^^ 29#32) + BitVec.ofInt 32 (-784568073) -
                        ((x &&& 223#32 ^^^ 29#32 ||| 1874836915#32) ^^^
                            ((x &&& 223#32 ^^^ 29#32) &&& 221#32 ^^^ 1874836915#32)) <<<
                          1#32).saddOverflow
                    1533579450#32 =
                  true) →
    True ∧ (x &&& 223#32 ^^^ 29#32).saddOverflow 1362915575#32 = true ∨
        True ∧ (x &&& 223#32 ^^^ 29#32).uaddOverflow 1362915575#32 = true ∨
          True ∧ ((x &&& 223#32 ^^^ 29#32) <<< 1#32).sshiftRight' 1#32 ≠ x &&& 223#32 ^^^ 29#32 ∨
            True ∧ (x &&& 223#32 ^^^ 29#32) <<< 1#32 >>> 1#32 ≠ x &&& 223#32 ^^^ 29#32 ∨
              1#32 ≥ ↑32 ∨
                True ∧
                    ((x &&& 223#32 ^^^ 29#32) + 1362915575#32).ssubOverflow
                        ((x &&& 223#32 ^^^ 29#32) <<< 1#32 &&& 290#32) =
                      true ∨
                  True ∧
                      ((x &&& 223#32 ^^^ 29#32) + 1362915575#32).usubOverflow
                          ((x &&& 223#32 ^^^ 29#32) <<< 1#32 &&& 290#32) =
                        true ∨
                    True ∧
                      ((x &&& 223#32 ^^^ 29#32) + 1362915575#32 -
                              ((x &&& 223#32 ^^^ 29#32) <<< 1#32 &&& 290#32)).uaddOverflow
                          1533579450#32 =
                        true →
      False

theorem icmp_power2_and_icmp_shifted_mask_swapped_2147483648_2147483647_proof : icmp_power2_and_icmp_shifted_mask_swapped_2147483648_2147483647_before ⊑ icmp_power2_and_icmp_shifted_mask_swapped_2147483648_2147483647_after

theorem zext_sext_add_icmp_eq_1_proof : zext_sext_add_icmp_eq_1_before ⊑ zext_sext_add_icmp_eq_1_after

theorem icmp_equality_test_commute_select2_proof : icmp_equality_test_commute_select2_before ⊑ icmp_equality_test_commute_select2_after

theorem e_1934 :
    4 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) + 11 * (a ^^^ (b &&& c)) - 6 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) + 11 * (c &&& (a ||| b)) - 5 * (c ^^^ ( ~~~a ||| (b ||| c))) - 7 * (b &&& (a |||  ~~~c)) + 1 * (c ||| (a ^^^ b)) + 1 * b + 7 * (c ||| (a &&&  ~~~b)) - 2 * c - 1 * (c ^^^ (a &&& ( ~~~b ||| c))) - 1 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) - 2 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) - 6 *  ~~~( ~~~a &&& (b ^^^ c)) + 1 * (c |||  ~~~(a |||  ~~~b)) - 1 *  ~~~a - 11 *  ~~~(a &&& c) + 5 *  ~~~(a ||| (b &&& c)) - 6 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 2 *  ~~~(b |||  ~~~c) + 1 * (a ||| c) - 7 * (a |||  ~~~c) + 2 * ((a &&& c) ^^^ (a ^^^ (b &&& c))) - 11 * (c ^^^ (a ||| ( ~~~b &&& c))) + 2 * (c ^^^  ~~~(a &&& b)) - 3 * (b ^^^ (a &&& c)) - 2 *  ~~~( ~~~a ||| (b ^^^ c)) - 11 *  ~~~(a ||| (b ^^^ c)) + 2 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 1 * ( ~~~a ||| (b ||| c)) - 11 * ( ~~~c |||  ~~~(a ^^^ b)) + 4 * (b ^^^ (a ||| (b ||| c))) + 3 * (c &&& (a |||  ~~~b)) - 1 * (c ^^^  ~~~(a ||| b)) + 2 * ((a &&& b) |||  ~~~(b ||| c)) + 4 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) - 1 * ((a &&& c) ||| (b &&&  ~~~c)) - 2 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) - 11 * (b ||| (a &&& c)) + 1 * (c |||  ~~~(a ||| b)) + 2 * ( ~~~a ||| ( ~~~b &&& c)) - 6 * (b ^^^ (a &&& ( ~~~b ||| c))) + 4 * (b ^^^  ~~~(a ||| (b ^^^ c))) - 1 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 43 *  ~~~(a ||| (b ||| c)) + 52 *  ~~~(a ||| ( ~~~b ||| c)) + 29 *  ~~~( ~~~a ||| (b ||| c)) + 55 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 1 * ( ~~~a &&& ( ~~~b &&& c)) + 39 * ( ~~~a &&& (b &&& c)) - 2 * (a &&& ( ~~~b &&& c)) + 23 * (a &&& (b &&& c)) = 2 * (b ^^^ (a |||  ~~~c))

theorem not_xor_to_or_not2_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 3),
  x_2 &&& x_1 ^^^ (x_1 ||| x) ^^^ -1#3 = x_2 &&& x_1 ||

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_7b_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_swapped_7b_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_swapped_7b_logical_after

theorem bools_logical_commute1_thm.extracted_1._4 : ∀ (x x_1 : BitVec 1),
  x_1 = 1#1 → ¬x = 1#1 → ¬x ^^^ 1#1 = 1#1 → 0#1 = x_1

theorem ashr_overshift_proof : ashr_overshift_before ⊑ ashr_overshift_after

theorem bv_AddSub_1043 :
    ∀ (e e_1 e_2 : LLVM.IntW w),
      LLVM.add (LLVM.add (LLVM.xor (LLVM.and e_1 e) e) (LLVM.const? w 1)) e_2 ⊑ LLVM.sub e_2 (LLVM.or e_1 (LLVM.not e))

theorem zext_nneg_proof : zext_nneg_before ⊑ zext_nneg_after

theorem test45_proof : test45_before ⊑ test45_after

theorem e_1825 :
    11 * ((a &&&  ~~~b) ||| (b ^^^ c)) + 7 * ((a &&& b) ^^^ (b ||| c)) - 11 * ((a &&& c) ||| (b &&&  ~~~c)) - 6 * (a ^^^ ( ~~~b &&& c)) - 6 * ((a &&& b) ^^^ (b |||  ~~~c)) + 1 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) + 11 * (b ^^^  ~~~( ~~~a ||| (b ^^^ c))) + 5 * ((a &&& b) |||  ~~~(b ^^^ c)) - 1 * (c ^^^  ~~~(a &&& (b &&& c))) - 2 * (c ^^^ (a ||| (b &&& c))) - 1 *  ~~~( ~~~a ||| (b ^^^ c)) + 5 * (b ^^^ ( ~~~a &&& (b ||| c))) + 11 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) + 7 * (c ^^^ ( ~~~a &&& (b ||| c))) + 3 * (b ^^^  ~~~(a ||| (b ^^^ c))) - 5 * (b |||  ~~~(a ^^^ c)) + 7 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) - 1 * ( ~~~b &&&  ~~~(a ^^^ c)) + 1 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) + 5 *  ~~~(a &&& c) - 2 * (c ^^^  ~~~(a &&&  ~~~b)) - 3 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 1 * ( ~~~a ||| (b ^^^ c)) - 11 * (c ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 3 * (a |||  ~~~c) - 5 *  ~~~(a ^^^ (b ||| c)) - 5 * ((a &&& b) |||  ~~~(b |||  ~~~c)) + 5 * ((a ||| b) &&& (b ^^^ c)) - 2 * ( ~~~a ||| ( ~~~b &&& c)) + 2 * (b ^^^ (a |||  ~~~c)) + 5 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) + 1 * ( ~~~a &&& (b ||| c)) - 2 * (b ||| (a ^^^ c)) + 11 * ((a &&& c) ^^^ (b ||| c)) - 13 *  ~~~(a ||| (b ||| c)) - 23 *  ~~~(a ||| ( ~~~b ||| c)) + 11 *  ~~~( ~~~a ||| (b ||| c)) - 7 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 15 * ( ~~~a &&& ( ~~~b &&& c)) - 14 * ( ~~~a &&& (b &&& c)) + 12 * (a &&& ( ~~~b &&& c)) + 5 * (a &&& (b &&& c)) = 11 * (b ^^^  ~~~( ~~~a ||| (b &&& c)))

theorem neg_of_add_with_constant_thm.extracted_1._1 : ∀ (x : BitVec 8), 0#8 - (x + 42#8) = BitVec.ofInt 8 (-42) - x

theorem bitvec_AddSub_1309 :
  [llvm(w)| {
    ^bb0(%X : _, %Y : _):
      %v1 = llvm.and %X, %Y
      %v2 = llvm.or %X, %Y
      %v3 = llvm.add %v1, %v2
      llvm.return %v3
  }] ⊑ [llvm(w)| {
    ^bb0(%X : _, %Y : _):
      %v3 = llvm.add %X, %Y
      llvm.return %v3
  }]

theorem zext_sext_add_icmp_slt_1_rhs_not_const_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 x_2 : BitVec 1),
  True ∧ (zeroExtend 8 x_2).saddOverflow (signExtend 8 x_1) = true → False

theorem ugt_swap_and_min_commute_logical_proof : ugt_swap_and_min_commute_logical_before ⊑ ugt_swap_and_min_commute_logical_after

theorem cast_test_2002h08h02_thm.extracted_1._1 : ∀ (x : BitVec 64), zeroExtend 64 (truncate 8 x) = x &&& 255#64

theorem ne_shift_in_zeros_thm (e e_1 : IntW 32) :
  LLVM.or (icmp IntPred.ne (trunc 24 (lshr e_1 (const? 32 16))) (trunc 24 (lshr e (const? 32 16))))
      (icmp IntPred.ne (trunc 8 (lshr e_1 (const? 32 8))) (trunc 8 (lshr e (const? 32 8)))) ⊑
    icmp IntPred.ugt (LLVM.xor e_1 e) (const? 32 255)

theorem test16_proof : test16_before ⊑ test16_after

theorem icmp_sle2_proof : icmp_sle2_before ⊑ icmp_sle2_after

@[simp] theorem lt_length (v : Γ.Var t) : v.1 < Γ.length

theorem bools2_logical_commute1_and1_thm.extracted_1._9 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 &&& x_1 = 1#1 → ¬x_1 ^^^ 1#1 = 1#1 → ¬x_1 = 1#1 → 0#1 = x

theorem t9_ashr_thm (e : IntW 16) (e_1 : IntW 32) :
  ashr (trunc 16 (ashr e_1 (zext 32 (sub (const? 16 32) e)))) (add e (const? 16 (-2))) ⊑
    ashr (trunc 16 (ashr e_1 (zext 32 (sub (const? 16 32) e) { «nneg» := true }))) (add e (const? 16 (-2)))

theorem src_srem_shl_demand_min_signbit_mask_hit_last_demand_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬((536870912#32 == 0 || 32 != 1 && x == intMin 32 && 536870912#32 == -1) = true ∨ 1#32 ≥ ↑32) →
    (536870912#32 == 0 || 32 != 1 && x == intMin 32 && 536870912#32 == -1) = true ∨
        True ∧ (x.srem 536870912#32 <<< 1#32).sshiftRight' 1#32 ≠ x.srem 536870912#32 ∨ 1#32 ≥ ↑32 →
      False

theorem and_not_or_or_not_or_xor_commute3_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ((x_2 ||| x_1) ^^^ -1#32) &&& x ||

theorem a_true_implies_b_true2_proof : a_true_implies_b_true2_before ⊑ a_true_implies_b_true2_after

theorem test2_proof : test2_before ⊑ test2_after

theorem mul_five (x : BitVec w) : 5 * x = x + x + x + x + x

theorem AvoidCollision_setWidth_setWidth_succ_eq_setWidth_setWidth_of_getLsbD_false {x : BitVec w} {i : Nat} (hx : x.getLsbD i = false) :
    setWidth w (x.setWidth (i + 1)) =
      setWidth w (x.setWidth i)

theorem e_1903 :
    7 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) + 1 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) + 5 * ( ~~~a &&& (b ^^^ c)) + 1 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 1 * (c ^^^ (a &&& (b ||| c))) + 1 *  ~~~(a ^^^ (b ^^^ c)) + 1 * (b |||  ~~~(a ^^^ c)) - 6 * (b ^^^  ~~~(a &&& (b &&& c))) + 3 * (b &&& (a ^^^ c)) + 1 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) - 2 * (c ^^^ (a ||| (b &&& c))) - 6 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) - 5 * (a &&&  ~~~c) + 1 * ( ~~~b ||| (a ^^^ c)) + 2 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) - 1 * (c &&& (a ^^^ b)) + 11 * (b &&&  ~~~c) - 6 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) + 3 * ( ~~~a &&& (b ||| c)) + 1 *  ~~~(b |||  ~~~c) - 2 * (b ||| (a ^^^ c)) - 1 *  ~~~( ~~~a &&& ( ~~~b ||| c)) - 5 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) + 3 * (b ^^^ ( ~~~a &&& (b ||| c))) + 2 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) + 5 * (a |||  ~~~b) - 6 * ((a &&& c) |||  ~~~(b ||| c)) + 11 * ((a &&& b) ^^^ (b |||  ~~~c)) + 2 *  ~~~a + 1 * (b &&& (a |||  ~~~c)) - 7 * (b ^^^ (a &&& ( ~~~b ||| c))) - 2 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) + 4 * (b ^^^  ~~~(a &&& (b ||| c))) - 7 * (a &&& (b ^^^ c)) - 6 * (b |||  ~~~(a ||| c)) - 1 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) - 1 * (a ^^^ (b ||| c)) - 1 * (a ^^^ b) + 1 * (b ^^^ (a |||  ~~~c)) + 7 *  ~~~(b &&& c) - 1 * a - 12 *  ~~~(a ||| (b ||| c)) - 22 *  ~~~(a ||| ( ~~~b ||| c)) + 12 *  ~~~( ~~~a ||| (b ||| c)) - 10 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 20 * ( ~~~a &&& ( ~~~b &&& c)) + 14 * ( ~~~a &&& (b &&& c)) - 3 * (a &&& ( ~~~b &&& c)) + 13 * (a &&& (b &&& c)) =  - 5 * ( ~~~b &&&  ~~~(a ^^^ c))

theorem e_1507 :
    7 *  ~~~(a ^^^ c) - 1 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 1 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) - 8 *  ~~~(a ||| (b ||| c)) - 8 *  ~~~(a ||| ( ~~~b ||| c)) + 1 *  ~~~( ~~~a ||| (b ||| c)) + 1 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 1 * ( ~~~a &&& ( ~~~b &&& c)) - 8 * (a &&& (b &&& c)) = 6 * (a &&& ( ~~~b &&& c))

theorem or_signbit_ashr_thm (e : IntW 32) :
  ashr (LLVM.or e (const? 32 (-65536))) (const? 32 8) ⊑ LLVM.or (lshr e (const? 32 8)) (const? 32 (-256))

theorem add_smax_simplify2_proof : add_smax_simplify2_before ⊑ add_smax_simplify2_after

theorem test9_proof : test9_before ⊑ test9_after

theorem sub_ult_zext_proof : sub_ult_zext_before ⊑ sub_ult_zext_after

theorem fold_inverted_icmp_preds_proof : fold_inverted_icmp_preds_before ⊑ fold_inverted_icmp_preds_after

theorem test_shl_nsw__nuw_is_safe_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& 1073741822#32 == 0#32) = 1#1 →
    ¬(2#32 ≥ ↑32 ∨
          True ∧ (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)).msb = true ∨
            zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)) ≥ ↑64) →
      x = x.sshiftRight' (zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)))

theorem main10_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 64#32 == 0#32) = 1#1 →
    ¬ofBool (x &&& 192#32 == 0#32) = 1#1 → ofBool (0#8 ≤ₛ truncate 8 x) = 1#1 → 2#32 = 1#32

theorem main7f_thm.extracted_1._1 : ∀ (x x_1 x_2 x_3 x_4 : BitVec 32),
  ofBool (x_4 &&& x_3 == x_2 &&& (x_4 &&& x_3)) &&& ofBool (x_1 &&& x == x_2 &&& (x_1 &&& x)) = 1#1 →
    0#32 = zeroExtend 32 (ofBool (x_2 &&& (x_4 &&& x_3 ||| x_1 &&& x) != x_4 &&& x_3 ||| x_1 &&& x))

theorem main3c_logical_proof : main3c_logical_before ⊑ main3c_logical_after

theorem positive_samevar_proof : positive_samevar_before ⊑ positive_samevar_after

theorem demorgan_nor_use2c_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬((x_1 ^^^ -1#8 ||| x) * 23#8 == 0 ||
          8 != 1 && (x_1 ^^^ -1#8 ||| x) ^^^ -1#8 == intMin 8 && (x_1 ^^^ -1#8 ||| x) * 23#8 == -1) =
        true →
    ¬((x ||| x_1 ^^^ -1#8) * 23#8 == 0 ||
            8 != 1 && (x ||| x_1 ^^^ -1#8) ^^^ -1#8 == intMin 8 && (x ||| x_1 ^^^ -1#8) * 23#8 == -1) =
          true →
      ((x_1 ^^^ -1#8 ||| x) ^^^ -1#8).sdiv ((x_1 ^^^ -1#8 ||| x) * 23#8) =
        ((x ||| x_1 ^^^ -1#8) ^^^ -1#8).sdiv ((x ||| x_1 ^^^ -1#8) * 23#8)

theorem foo1_or_commuted_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(x_1 ≥ ↑32 ∨ x ≥ ↑32) →
    ¬(True ∧ 1#32 <<< x_1 >>> x_1 ≠ 1#32 ∨
          x_1 ≥ ↑32 ∨
            True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨
              x ≥ ↑32 ∨ True ∧ 1#32 <<< x_1 >>> x_1 ≠ 1#32 ∨ x_1 ≥ ↑32 ∨ True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨ x ≥ ↑32) →
      ofBool (x_2 * x_2 &&& 1#32 <<< x_1 != 0#32) &&& ofBool (1#32 <<< x &&& x_2 * x_2 != 0#32) =
        ofBool (x_2 * x_2 &&& (1#32 <<< x_1 ||| 1#32 <<< x) == 1#32 <<< x_1 ||| 1#32 <<< x)

theorem main4e_like_proof : main4e_like_before ⊑ main4e_like_after

theorem bv_AndOrXor_2367 :
    ∀ (e e_1 e_2 : LLVM.IntW w), LLVM.or (LLVM.or e e_1) e_2 ⊑ LLVM.or (LLVM.or e e_2) e_1

theorem alive_AddSub_1539  (w : Nat)   : alive_AddSub_1539_src w  ⊑ alive_AddSub_1539_tgt w

theorem ashrslt_03_08_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬3#4 ≥ ↑4 → ofBool (x.sshiftRight' 3#4 <ₛ BitVec.ofInt 4 (-8)) = 0#1

theorem sgt_and_min_logical_thm (e e_1 : IntW 9) :
  select (icmp IntPred.sgt e_1 e) (icmp IntPred.eq e_1 (const? 9 (-256))) (const? 1 0) ⊑ const? 1 0

theorem t1_flags_proof : t1_flags_before ⊑ t1_flags_after

theorem main4b_logical_thm.extracted_1._4 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 == 7#32) = 1#1 → ¬0#1 = 1#1 → 1#32 = zeroExtend 32 (ofBool (x &&& 23#32 != 23#32))

theorem udiv_shl_mul_nuw_proof : udiv_shl_mul_nuw_before ⊑ udiv_shl_mul_nuw_after

theorem test6_proof : test6_before ⊑ test6_after

theorem lshrugt_01_00_proof : lshrugt_01_00_before ⊑ lshrugt_01_00_after

@[simp]
theorem FSM.eval_ite_eq_decide {α : Type}
    (cond t e : FSM α)
    (env : α → BitStream) (i : Nat) :
    (FSM.ite cond t e).eval env i =
    if (cond.eval env i) then t.eval env i else e.eval env i

@[simp] theorem Valuation.append_inj_right {V : Γ.Valuation} {W W' : Δ.Valuation} :
    (V ++ W) = (V ++ W') ↔ W = W'

theorem select_icmp_eq_and_32_0_xor_8_thm.extracted_1._4 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 32#32 == 0#32) = 1#1 → ¬2#32 ≥ ↑32 → x ^^^ 8#32 = x ^^^ x_1 >>> 2#32 &&& 8#32

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_3_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 15#32 == 0#32) = 1#1 → ofBool (x &&& 7#32 != 0#32) = ofBool (x &&& 15#32 != 8#32)

theorem e_2075 :
     - 3 * (f &&& (d |||  ~~~e)) + 1 * (e ^^^ (d &&& (e ||| f))) - 5 * ( ~~~d ||| (e ||| f)) + 1 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 5 * (f ^^^ (d ||| ( ~~~e &&& f))) - 1 * (f |||  ~~~(d |||  ~~~e)) + 1 *  ~~~(d &&& e) - 2 * ( ~~~d ||| ( ~~~e &&& f)) - 1 *  ~~~(d &&& (e ^^^ f)) - 3 * (f ^^^  ~~~(d ||| e)) - 2 * ((d |||  ~~~e) &&& (e ^^^ f)) - 3 * (e ^^^  ~~~(d ||| (e &&& f))) - 1 *  ~~~( ~~~d &&& (e ||| f)) - 1 * (d ||| (e ^^^ f)) + 1 *  ~~~(d &&& f) + 2 * (f ^^^  ~~~(d &&& (e &&& f))) - 11 * ( ~~~e |||  ~~~(d ^^^ f)) - 1 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 6 * ( ~~~d &&& (e ^^^ f)) + 2 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 2 * (e ^^^  ~~~(d ||| f)) + 4 * (e ^^^ ( ~~~d &&& (e ||| f))) - 6 * ( ~~~d ||| (e &&& f)) - 1 * (d &&& f) + 11 * (d ||| e) + 11 * (f ^^^ (d &&& ( ~~~e ||| f))) - 2 * (e ^^^ (d &&& (e ^^^ f))) - 7 * (f ^^^ ( ~~~d ||| (e ||| f))) - 2 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 7 *  ~~~(d ^^^ (e ^^^ f)) + 1 * ( ~~~f &&& (d ^^^ e)) + 2 * (f &&&  ~~~(d ^^^ e)) + 28 *  ~~~(d ||| (e ||| f)) + 23 *  ~~~(d ||| ( ~~~e ||| f)) - 10 *  ~~~( ~~~d ||| (e ||| f)) + 2 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 21 * ( ~~~d &&& ( ~~~e &&& f)) - 4 * ( ~~~d &&& (e &&& f)) + 20 * (d &&& (e &&& f)) =  - 10 * (d &&& ( ~~~e &&& f))

theorem negative3_proof : negative3_before ⊑ negative3_after

theorem add_nsw_poison_constant_fold_proof : add_nsw_poison_constant_fold_before ⊑ add_nsw_poison_constant_fold_after

theorem icmp_slt_sext_ne_allones_nofold_proof : icmp_slt_sext_ne_allones_nofold_before ⊑ icmp_slt_sext_ne_allones_nofold_after

theorem negate_select_of_op_vs_negated_op_nsw_xyyx_proof : negate_select_of_op_vs_negated_op_nsw_xyyx_before ⊑ negate_select_of_op_vs_negated_op_nsw_xyyx_after

theorem logical_or_not_cond_reuse_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1),
  x_1 = 1#1 → x_1 ^^^ 1#1 = 1#1 → x_1 ^^^ 1#1 = x

theorem slt_smin3_proof : slt_smin3_before ⊑ slt_smin3_after

theorem e_964 :
     - 6 *  ~~~(z &&& t) + 5 * (z ||| t) + 3 *  ~~~(z &&&  ~~~t) + 2 * (z ^^^ t) + 2 *  ~~~(z ||| t) - 2 * (z &&&  ~~~t) - 8 * (z &&& t) =  - 1 *  ~~~t + 4 *  ~~~(z |||  ~~~t)

theorem multiuse2_proof : multiuse2_before ⊑ multiuse2_after

theorem test3_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬30#32 ≥ ↑32 →
    ¬(30#32 ≥ ↑32 ∨ True ∧ (x &&& 128#32 &&& x >>> 30#32 != 0) = true) →
      (x &&& 128#32) + x >>> 30#32 = x &&& 128#32 ||

theorem ashrsgt_01_08_exact_proof : ashrsgt_01_08_exact_before ⊑ ashrsgt_01_08_exact_after

theorem one_side_fold_slt_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 32) (x_3 : BitVec 1),
  ¬x_3 = 1#1 → ofBool (x_1 <ₛ x_1) = 0#1

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 1), x &&& 0#1 = 0#1

theorem unsigned_sign_bit_extract_with_trunc_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬63#64 ≥ ↑64 → ofBool (truncate 32 (x >>> 63#64) != 0#32) = ofBool (x <ₛ 0#64)

theorem e_1314 :
     - 5 * (z ^^^ t) - 1 *  ~~~z + 1 *  ~~~t + 1 *  ~~~(z &&&  ~~~t) - 7 * (z ||| t) - 8 *  ~~~(z ||| t) + 5 *  ~~~(z |||  ~~~t) + 4 * (z &&&  ~~~t) + 6 * (z &&& t) =  - 7 *  ~~~(z &&& t)

theorem e_664 :
     - 11 * (x |||  ~~~y) + 1 * (x ||| y) + 1 *  ~~~y + 3 * (x ^^^ y) + 4 *  ~~~x - 5 *  ~~~(x &&& y) - 7 * x + 2 *  ~~~(x &&&  ~~~x) + 16 * (x &&&  ~~~y) + 15 * (x &&& y) = 5 *  ~~~(x |||  ~~~y) - 9 *  ~~~(x ||| y)

theorem ashr_mul_times_3_div_2_proof : ashr_mul_times_3_div_2_before ⊑ ashr_mul_times_3_div_2_after

theorem basic_thm (e e_1 : IntW 8) :
  LLVM.xor (add (LLVM.xor e_1 (const? 8 (-1))) e) (const? 8 (-1)) ⊑ sub e_1 e

theorem ashrslt_02_09_proof : ashrslt_02_09_before ⊑ ashrslt_02_09_after

theorem t17_nocse_mismatching_x_proof : t17_nocse_mismatching_x_before ⊑ t17_nocse_mismatching_x_after

theorem ule_swap_and_min_logical_proof : ule_swap_and_min_logical_before ⊑ ule_swap_and_min_logical_after

theorem e_1410 :
     - 6 * z - 3 *  ~~~z - 11 * (z ^^^ t) - 5 *  ~~~(z &&&  ~~~t) - 1 * t - 1 *  ~~~(z &&& t) + 7 *  ~~~(z ||| t) + 21 *  ~~~(z |||  ~~~t) + 18 * (z &&&  ~~~t) + 10 * (z &&& t) =  - 2 *  ~~~(z ^^^ t)

theorem e_439 :
     - 11 * y + 11 * (x |||  ~~~y) - 7 *  ~~~y + 3 *  ~~~(x &&&  ~~~y) - 17 *  ~~~(x ||| y) - 2 *  ~~~(x |||  ~~~y) - 3 * (x &&&  ~~~y) - 2 * (x &&& y) =  - 11 *  ~~~x + 1 *  ~~~(x &&&  ~~~x)

theorem c0_thm (e : IntW 8) :
  icmp IntPred.sle (LLVM.and e (const? 8 3)) e ⊑ icmp IntPred.sgt e (const? 8 (-1))

theorem and_ashr_not_commuted_thm (e e_1 e_2 : IntW 8) :
  LLVM.and (LLVM.xor (ashr e_2 e_1) (const? 8 (-1))) (ashr e e_1) ⊑
    ashr (LLVM.and e (LLVM.xor e_2 (const? 8 (-1)))) e_1

theorem icmp_mul_nsw_sgt_proof : icmp_mul_nsw_sgt_before ⊑ icmp_mul_nsw_sgt_after

theorem e_94 :
    7 *  ~~~x - 3 *  ~~~(x ^^^ y) + 1 * y - 4 *  ~~~(x ||| y) + 2 * (x &&& y) = 8 *  ~~~(x |||  ~~~y)

theorem t14_x_is_one_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(32#32 - x ≥ ↑32 ∨ zeroExtend 64 (x + BitVec.ofInt 32 (-16)) ≥ ↑64) →
    ofBool (x_1 <<< (32#32 - x) &&& truncate 32 (1#64 >>> zeroExtend 64 (x + BitVec.ofInt 32 (-16))) != 0#32) = 0#1

theorem or_and1_thm (e e_1 e_2 : IntW 1) :
  select (LLVM.and (LLVM.xor e_2 (const? 1 1)) e_1) e e_2 ⊑ select e_2 (const? 1 1) (select e_1 e (const? 1 0))

theorem test_shl_nuw__nuw_is_safe_proof : test_shl_nuw__nuw_is_safe_before ⊑ test_shl_nuw__nuw_is_safe_after

theorem p0_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x &&& 3#8 == x) = ofBool (x <ᵤ 4#8)

theorem test1_proof : test1_before ⊑ test1_after

theorem const_sub_sub_const_thm (e : IntW 32) : sub (sub (const? 32 8) e) (const? 32 2) ⊑ sub (const? 32 6) e

theorem test_imply_not2_thm.extracted_1._5 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  ¬ofBool (x_1 == 0#32) = 1#1 → ofBool (x_1 != 0#32) = 1#1 → 0#1 ||

theorem lshrult_01_07_proof : lshrult_01_07_before ⊑ lshrult_01_07_after

theorem test8_proof : test8_before ⊑ test8_after

theorem t0_thm (e e_1 e_2 e_3 : IntW 32) :
  LLVM.xor (select (icmp IntPred.eq e_3 e_2) (icmp IntPred.eq e_1 e) (const? 1 0)) (const? 1 1) ⊑
    select (icmp IntPred.ne e_3 e_2) (const? 1 1) (icmp IntPred.ne e_1 e)

theorem alive_AddSub_1156  (w : Nat)   : alive_AddSub_1156_src w  ⊑ alive_AddSub_1156_tgt w

theorem n7_wrong_pred2_proof : n7_wrong_pred2_before ⊑ n7_wrong_pred2_after

theorem test1_proof : test1_before ⊑ test1_after

theorem test25_proof : test25_before ⊑ test25_after

theorem test_zext1_proof : test_zext1_before ⊑ test_zext1_after

@[simp] theorem Ctxt.get_add_bvars (e : Expr d Γ eff ts) (i : Nat) :
    e.outContext[i + e.bvars]? = Γ[i]?

theorem trunc_sel_smaller_zext_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → zeroExtend 32 42#16 = 42#32

theorem e_237 :
    4 *  ~~~(x ^^^ y) + 3 * (x ^^^ y) - 2 *  ~~~x + 1 * (x |||  ~~~y) + 2 *  ~~~(x |||  ~~~y) - 4 * (x &&&  ~~~y) - 2 * (x &&& y) = 3 *  ~~~(x &&&  ~~~y)

theorem shift_xor_multiuse_cmp_with_and_thm (e e_1 e_2 e_3 : IntW 32) :
  mul
      (select (icmp IntPred.ne (const? 32 0) (LLVM.and e_3 (const? 32 4096))) e_2
        (LLVM.and e_2 (const? 32 (-2049))))
      (select (icmp IntPred.ne (const? 32 0) (LLVM.and e_3 (const? 32 4096))) e_1 e) ⊑
    mul
      (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) (LLVM.and e_2 (const? 32 (-2049)))
        e_2)
      (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) e e_1)

theorem sdiv_shl_pair2_thm (e e_1 e_2 : IntW 32) :
  LLVM.sdiv (shl e_2 e_1 { «nsw» := true, «nuw» := true }) (shl e_2 e { «nsw» := true, «nuw» := false }) ⊑
    lshr (shl (const? 32 1) e_1 { «nsw» := true, «nuw» := true }) e

theorem e_571 :
    5 * (x |||  ~~~y) - 1 *  ~~~(x &&& y) - 6 * y - 2 *  ~~~(x ^^^ y) + 1 *  ~~~(x &&&  ~~~y) - 11 * (x ^^^ y) + 20 *  ~~~(x |||  ~~~y) + 15 * (x &&&  ~~~y) + 10 * (x &&& y) = 3 *  ~~~(x &&&  ~~~x) + 5 * x

theorem one_side_fold_eq_thm.extracted_1._10 : ∀ (x x_1 x_2 : BitVec 32) (x_3 : BitVec 1),
  ¬x_3 = 1#1 → ¬x_3 ^^^ 1#1 = 1#1 → ofBool (x_1 == x_1) = ofBool (x_2 == x)

theorem select_constants_and_icmp_ne0_zero_tval_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1),
  ¬x_1 = 1#1 → x = 1#1 → ofBool (12#8 &&& 0#8 != 0#8) = x ^^^ 1#1

theorem icmp_sgt9_proof : icmp_sgt9_before ⊑ icmp_sgt9_after

theorem and_umin_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (15#32 <ᵤ x) = 1#1 → x &&& BitVec.ofInt 32 (-32) = 0#32

theorem main3f_like_logical_thm.extracted_1._9 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 &&& x_1 != 0#32) = 1#1 →
    ofBool (x_2 &&& x_1 == 0#32) = 1#1 →
      ofBool (x_2 &&& x != 0#32) = 1#1 → 0#32 = zeroExtend 32 (ofBool (x_2 &&& x == 0#32))

theorem select_sub_icmp_bad_proof : select_sub_icmp_bad_before ⊑ select_sub_icmp_bad_after

theorem negtest_near_pow2_cmpval_would_overflow_into_signbit_thm (e : IntW 8) :
  icmp IntPred.ult (ashr e (const? 8 2) { «exact» := true }) (const? 8 33) ⊑
    icmp IntPred.sgt e (const? 8 (-1))

theorem ne_umax3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x <ᵤ x_1 + 3#32) = 1#1 → ofBool (x_1 + 3#32 != x_1 + 3#32) = ofBool (x_1 + 3#32 <ᵤ x)

theorem test13_thm (e e_1 : IntW 32) :
  LLVM.and (icmp IntPred.ult e_1 e) (icmp IntPred.ugt e_1 e) ⊑ const? 1 0

theorem e_233 :
    3 *  ~~~(x &&& y) - 7 *  ~~~y + 5 * (x |||  ~~~y) + 1 * (x ||| y) + 4 *  ~~~(x ||| y) - 4 *  ~~~(x |||  ~~~y) - 1 * (x &&& y) = 5 *  ~~~(x ^^^ y) + 2 * (x &&&  ~~~y)

theorem a_or_b_const2_thm (e e_1 e_2 e_3 : IntW 32) :
  LLVM.or (LLVM.and (icmp IntPred.eq e_3 e_2) (icmp IntPred.ne e_1 e))
      (LLVM.and (icmp IntPred.ne e_3 e_2) (icmp IntPred.eq e_1 e)) ⊑
    LLVM.xor (icmp IntPred.eq e_3 e_2) (icmp IntPred.eq e_1 e)

theorem smear_sign_and_widen_proof : smear_sign_and_widen_before ⊑ smear_sign_and_widen_after

theorem e_1953 :
     - 11 *  ~~~(a &&&  ~~~b) - 5 * ((a &&& b) ||| (b ^^^ c)) - 1 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) - 7 * (b ^^^ ( ~~~a ||| (b ^^^ c))) - 1 * (a &&& (b ^^^ c)) - 6 *  ~~~(a ^^^ ( ~~~b &&& c)) + 7 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) - 2 * (a ^^^ ( ~~~b ||| c)) + 2 * (b ^^^  ~~~(a &&&  ~~~c)) - 1 * (b ^^^ (a ||| (b &&& c))) + 2 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 5 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) + 7 * (a &&&  ~~~b) - 1 * (b &&&  ~~~(a ^^^ c)) + 1 *  ~~~(b ||| c) + 2 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 5 * (c ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 4 * (c ^^^ ( ~~~a ||| (b ||| c))) - 2 * ( ~~~(a ||| b) |||  ~~~(b ^^^ c)) + 2 * (b ^^^ (a &&& ( ~~~b ||| c))) + 3 * (b &&&  ~~~(a &&& c)) + 1 *  ~~~(a ||| b) - 1 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) + 1 * (c ^^^ (a ||| ( ~~~b ||| c))) + 7 * (b &&& (a |||  ~~~c)) - 2 * ( ~~~c &&&  ~~~(a ^^^ b)) + 11 * (c ^^^  ~~~(a ||| b)) + 1 * (a &&& c) - 5 * (c &&& (a ||| b)) + 4 * (b ^^^ (a &&&  ~~~c)) - 1 * (b ^^^ (a &&& (b ^^^ c))) - 6 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) - 6 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 11 *  ~~~(a ||| (b ^^^ c)) - 1 * (c ^^^  ~~~(a &&& ( ~~~b ||| c))) + 4 *  ~~~( ~~~a &&& (b ^^^ c)) - 7 * ( ~~~a ||| (b ||| c)) - 1 * (a ^^^ c) + 3 * ((a &&& b) ^^^ (b ||| c)) - 1 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 1 *  ~~~( ~~~a ||| ( ~~~b &&& c)) - 1 * (a ||| b) + 2 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) - 2 * (a |||  ~~~c) - 1 * ((b &&& c) ||| (a &&& (b ||| c))) + 4 *  ~~~(a ||| ( ~~~b &&& c)) + 11 *  ~~~(a &&& b) - 13 *  ~~~(a ||| (b ||| c)) + 10 *  ~~~(a ||| ( ~~~b ||| c)) - 14 *  ~~~( ~~~a ||| (b ||| c)) + 12 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 26 * ( ~~~a &&& ( ~~~b &&& c)) - 6 * (a &&& ( ~~~b &&& c)) + 10 * (a &&& (b &&& c)) = 18 * ( ~~~a &&& (b &&& c))

theorem t_2_192_proof : t_2_192_before ⊑ t_2_192_after

theorem and1_shl1_is_cmp_eq_0_multiuse_thm (e : IntW 8) :
  add (shl (const? 8 1) e) (LLVM.and (shl (const? 8 1) e) (const? 8 1)) ⊑
    add (shl (const? 8 1) e { «nsw» := false, «nuw» := true })
      (LLVM.and (shl (const? 8 1) e { «nsw» := false, «nuw» := true }) (const? 8 1))
      { «nsw» := false, «nuw» := true }

theorem e_422 :
    1 *  ~~~y + 2 *  ~~~x + 2 * (x ||| y) - 2 * y - 2 *  ~~~(x ^^^ y) - 1 *  ~~~(x |||  ~~~y) - 3 * (x &&&  ~~~y) + 3 * (x &&& y) = 1 *  ~~~(x &&&  ~~~y)

theorem neg_sgt_0_proof : neg_sgt_0_before ⊑ neg_sgt_0_after

theorem masked_and_notA_slightly_optimized_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (8#32 ≤ᵤ x) = 1#1 → 0#1 = ofBool (x &&& BitVec.ofInt 32 (-40) != 0#32)

theorem sel_false_val_is_a_masked_ashr_of_true_val1_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& BitVec.ofInt 32 (-2147483588) == 0#32) = 1#1 →
    ¬(2#32 ≥ ↑32 ∨
          True ∧ (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)).msb = true ∨
            zeroExtend 64 (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)) ≥ ↑64) →
      x = x.sshiftRight' (zeroExtend 64 (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)))

theorem select_icmp_ne_pow2_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬ofBool (x &&& 4#8 != 0#8) = 1#1 → x = x &&& BitVec.ofInt 8 (-5)

theorem differentconsts_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x + 16#32 <ᵤ 144#32) = 1#1 →
    ¬ofBool (127#32 <ₛ x) = 1#1 → ofBool (x <ₛ BitVec.ofInt 32 (-16)) = 1#1 → truncate 16 x = 256#16

theorem icmp_eq_and_pow2_shl_pow2_thm (e : IntW 32) :
  zext 32 (icmp IntPred.eq (LLVM.and (shl (const? 32 2) e) (const? 32 16)) (const? 32 0)) ⊑
    zext 32 (icmp IntPred.ne e (const? 32 3))

theorem sextinreg2_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(24#32 ≥ ↑32 ∨ True ∧ x <<< 24#32 >>> 24#32 <<< 24#32 ≠ x <<< 24#32 ∨ 24#32 ≥ ↑32) →
    (x &&& 255#32 ^^^ 128#32) + BitVec.ofInt 32 (-128) = (x <<< 24#32).sshiftRight' 24#32

theorem PR42691_10_proof : PR42691_10_before ⊑ PR42691_10_after

theorem test94_proof : test94_before ⊑ test94_after

theorem and_add_bool_to_select_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 → -1#32 + zeroExtend 32 x_1 &&& x = 0#32

theorem main7a_logical_thm.extracted_1._12 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 &&& x_1 == x_2) = 1#1 →
    ¬ofBool (x_2 &&& x_1 != x_2) = 1#1 → ¬0#1 = 1#1 → 1#32 = zeroExtend 32 (ofBool (x &&& x_1 != x))

theorem a_true_implies_b_false2_thm.extracted_1._5 : ∀ (x x_1 : BitVec 1) (x_2 : BitVec 8),
  ofBool (x_2 == 10#8) = 1#1 → ofBool (20#8 <ᵤ x_2) = 1#1 → ofBool (20#8 <ᵤ x_2) &&& x_1 = x

theorem lshr_exact_add_negative_shift_positive_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ 2#32 >>> (x + -1#32) <<< (x + -1#32) ≠ 2#32 ∨ x + -1#32 ≥ ↑32) →
    True ∧ 4#32 >>> x <<< x ≠ 4#32 ∨ x ≥ ↑32 → False

theorem not_xor_to_or_not3_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 3),
  x_2 &&& x_1 ^^^ (x_2 ||| x) ^^^ -1#3 = x_2 &&& x_1 ||

theorem signed_sign_bit_extract_thm (e : IntW 32) :
  icmp IntPred.ne (ashr e (const? 32 31)) (const? 32 0) ⊑ icmp IntPred.slt e (const? 32 0)

theorem ashrslt_03_00_exact_proof : ashrslt_03_00_exact_before ⊑ ashrslt_03_00_exact_after

theorem demorganize_constant2_proof : demorganize_constant2_before ⊑ demorganize_constant2_after

theorem ashr_add_fail_proof : ashr_add_fail_before ⊑ ashr_add_fail_after

theorem lshr_mul_times_5_div_4_exact_2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.umulOverflow 5#32 = true ∨ True ∧ (x * 5#32) >>> 2#32 <<< 2#32 ≠ x * 5#32 ∨ 2#32 ≥ ↑32) →
    True ∧ x >>> 2#32 <<< 2#32 ≠ x ∨ 2#32 ≥ ↑32 ∨ True ∧ x.uaddOverflow (x >>> 2#32) = true → False

theorem sge_or_not_max_logical_proof : sge_or_not_max_logical_before ⊑ sge_or_not_max_logical_after

theorem select_icmp_sgt_allones_smin_flipped_proof : select_icmp_sgt_allones_smin_flipped_before ⊑ select_icmp_sgt_allones_smin_flipped_after

theorem alive_Select_1105  (w : Nat)   : alive_Select_1105_src w  ⊑ alive_Select_1105_tgt w

theorem e_1750 :
    4 * ((a ||| b) &&& (b ^^^ c)) - 2 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) - 1 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) + 1 * ( ~~~b |||  ~~~(a ^^^ c)) - 3 * (b ^^^ (a ||| (b ||| c))) + 2 * (b ^^^  ~~~(a &&& c)) - 1 *  ~~~(a ^^^ b) - 1 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) - 5 * (a |||  ~~~c) - 6 *  ~~~(a &&&  ~~~b) - 2 * ( ~~~a &&& (b ^^^ c)) + 1 * (b ^^^  ~~~(a &&& (b ^^^ c))) + 1 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) - 3 * (b ^^^ ( ~~~a ||| (b ^^^ c))) + 11 * (c ^^^ (a ||| (b ||| c))) - 11 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) + 5 * (c ^^^ ( ~~~a &&& ( ~~~b ||| c))) + 1 * (a ||| c) + 1 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) - 11 * (c &&& (a |||  ~~~b)) - 7 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) + 1 * (b ^^^ (a &&& c)) + 2 * (a &&& ( ~~~b ||| c)) + 3 * ((a &&& b) ^^^ (a ^^^ ( ~~~b ||| c))) + 5 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 1 * ((a &&& c) ||| (b &&&  ~~~c)) + 3 * (c ^^^  ~~~(a |||  ~~~b)) - 1 *  ~~~(a ||| (b ||| c)) + 12 *  ~~~(a ||| ( ~~~b ||| c)) - 3 *  ~~~( ~~~a ||| (b ||| c)) - 4 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 33 * ( ~~~a &&& ( ~~~b &&& c)) + 14 * ( ~~~a &&& (b &&& c)) + 26 * (a &&& (b &&& c)) = 1 * (a &&& ( ~~~b &&& c))

theorem slt_swap_or_not_max_commute_logical_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 != 127#8) = 1#1 → ofBool (x_1 <ₛ x) = ofBool (x_1 != 127#8)

theorem or_or_and_pat7_proof : or_or_and_pat7_before ⊑ or_or_and_pat7_after

theorem exact_ashr_ne_noexactdiv_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ BitVec.ofInt 8 (-80) >>> x <<< x ≠ BitVec.ofInt 8 (-80) ∨ x ≥ ↑8) →
    ofBool ((BitVec.ofInt 8 (-80)).sshiftRight' x != BitVec.ofInt 8 (-31)) = 1#1

theorem test20_thm (e e_1 : IntW 32) :
  LLVM.xor (LLVM.or e_1 e) (LLVM.or (LLVM.xor e (const? 32 (-1))) (LLVM.xor e_1 (const? 32 (-1)))) ⊑
    LLVM.xor (LLVM.xor e_1 e) (const? 32 (-1))

theorem in_constant_14_vary_thm (e : IntW 4) :
  LLVM.xor (LLVM.and (LLVM.xor e (const? 4 (-2))) (const? 4 1)) e ⊑ LLVM.and e (const? 4 (-2))

theorem add_zero_eq : a + 0 = a

theorem shrink_select_proof : shrink_select_before ⊑ shrink_select_after

theorem no_shift_xor_multiuse_cmp_with_xor_thm.extracted_1._8 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ¬ofBool (0#32 != x_3 &&& 4096#32) = 1#1 →
    ¬ofBool (x_3 &&& 4096#32 == 0#32) = 1#1 → (x_2 ^^^ 4096#32) * x = (x_3 &&& 4096#32 ^^^ x_2 ^^^ 4096#32) * x_1

theorem xor_and_logic_or2_proof : xor_and_logic_or2_before ⊑ xor_and_logic_or2_after

theorem test_lshr__exact_is_unsafe_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 63#32 == 0#32) = 1#1 →
    ¬(2#32 ≥ ↑32 ∨ zeroExtend 64 ((x_1 &&& 63#32) >>> 2#32) ≥ ↑64) →
      2#32 ≥ ↑32 ∨ True ∧ (x_1 >>> 2#32 &&& 15#32).msb = true ∨ zeroExtend 64 (x_1 >>> 2#32 &&& 15#32) ≥ ↑64 → False

theorem ult_to_slt_proof : ult_to_slt_before ⊑ ult_to_slt_after

theorem sge_swap_and_max_proof : sge_swap_and_max_before ⊑ sge_swap_and_max_after

theorem main14_logical_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (0#16 ≤ₛ truncate 16 x) = 1#1 → ofBool (x &&& 32896#32 == 0#32) = 1#1 → ¬0#1 = 1#1 → 1#32 = 2#32

theorem e_1515 :
     - 3 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) + 1 * (c ^^^ (a ||| b)) + 2 * (c &&&  ~~~(a &&& b)) + 7 * (c &&&  ~~~(a ^^^ b)) + 3 *  ~~~(a ||| (b ||| c)) + 2 *  ~~~(a ||| ( ~~~b ||| c)) - 1 *  ~~~( ~~~a ||| (b ||| c)) - 1 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 7 * ( ~~~a &&& ( ~~~b &&& c)) - 2 * ( ~~~a &&& (b &&& c)) =  - 1 * (a &&& ( ~~~b &&& c)) + 7 * (a &&& (b &&& c))

theorem ugt_swap_and_min_proof : ugt_swap_and_min_before ⊑ ugt_swap_and_min_after

omit [Fintype S] [DecidableEq S] in
lemma processOneElem_trans_preserve (st : worklist.St A S) (final : S → Bool) (a b : A) (sa : S) (s s1 s2 : State) :
    s2 ∈ st.m.tr s1 b →
    s2 ∈ (processOneElem A S final s st (a, sa)).m.tr s1 b

theorem badimm3_thm.extracted_1._4 : ∀ (x : BitVec 16),
  ¬(7#8 ≥ ↑8 ∨ 8#16 ≥ ↑16) →
    ¬ofBool ((truncate 8 x).sshiftRight' 7#8 == truncate 8 (x >>> 8#16)) = 1#1 →
      ¬14#16 ≥ ↑16 →
        ¬ofBool (x + 128#16 <ᵤ 256#16) = 1#1 →
          14#16 ≥ ↑16 ∨ True ∧ signExtend 16 (truncate 8 (x.sshiftRight' 14#16)) ≠ x.sshiftRight' 14#16 → False

theorem sub_from_constant_of_sub_from_constant_proof : sub_from_constant_of_sub_from_constant_before ⊑ sub_from_constant_of_sub_from_constant_after

@[simp]
theorem tail_eq (x : BitStream) (i : Nat) : x.tail i = x (i + 1)

theorem ashrslt_03_00_proof : ashrslt_03_00_before ⊑ ashrslt_03_00_after

theorem fold_inverted_icmp_preds_reverse_thm.extracted_1._5 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ¬ofBool (x_3 <ₛ x_2) = 1#1 → ¬ofBool (x_2 ≤ₛ x_3) = 1#1 → x_1 ||

theorem test1_proof : test1_before ⊑ test1_after

theorem sext_true_val_must_be_all_ones_proof : sext_true_val_must_be_all_ones_before ⊑ sext_true_val_must_be_all_ones_after

theorem ashrsgt_02_15_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬2#4 ≥ ↑4 → ofBool (-1#4 <ₛ x.sshiftRight' 2#4) = ofBool (-1#4 <ₛ x)

theorem test_or_eq_a_b_proof : test_or_eq_a_b_before ⊑ test_or_eq_a_b_after

theorem bools2_logical_commute1_and1_and2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1),
  x_1 &&& x = 1#1 → ¬x = 1#1 → False

theorem e_901 :
     - 2 * (z ^^^ t) + 11 *  ~~~t - 12 *  ~~~(z ||| t) - 4 *  ~~~(z |||  ~~~t) - 9 * (z &&&  ~~~t) - 5 * (z &&& t) =  - 5 * t - 1 *  ~~~z

theorem not_and_and_not_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true →
    (42#32).sdiv x_2 &&& (x_1 ^^^ -1#32) &&& (x ^^^ -1#32) = (42#32).sdiv x_2 &&& ((x_1 ||| x) ^^^ -1#32)

theorem uge_swap_and_max_commute_logical_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬ofBool (x == -1#8) = 1#1 → 0#1 = ofBool (x == -1#8)

theorem xor_or2_thm (e : IntW 8) :
  LLVM.or (LLVM.xor e (const? 8 33)) (const? 8 7) ⊑ LLVM.xor (LLVM.and e (const? 8 (-8))) (const? 8 39)

theorem main3c_logical_thm.extracted_1._4 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 != 0#32) = 1#1 →
    ¬ofBool (x &&& 48#32 != 0#32) = 1#1 → 1#32 = zeroExtend 32 (ofBool (x &&& 55#32 == 0#32))

theorem sub_select_zext_op_swapped_non_const_args_thm.extracted_1._1 : ∀ (x : BitVec 6) (x_1 : BitVec 1),
  x_1 = 1#1 → zeroExtend 6 x_1 - x = 1#6 - x

theorem R.fromTensor_eq_fromTensorFinsupp_fromPoly {coeffs : List Int} :
    R.fromTensor (q := q) (n := n) coeffs =
  R.fromPoly (q := q) (n := n) (R.fromTensorFinsupp q coeffs)

theorem main3c_logical_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 != 0#32) = 1#1 →
    ofBool (x &&& 48#32 != 0#32) = 1#1 → 0#32 = zeroExtend 32 (ofBool (x &&& 55#32 == 0#32))

theorem ashr_lshr2_proof : ashr_lshr2_before ⊑ ashr_lshr2_after

theorem shl_nsw_add_nuw_thm (e : IntW 32) :
  shl (const? 32 (-1)) (add e (const? 32 1) { «nsw» := false, «nuw» := true }) { «nsw» := true, «nuw» := false } ⊑
    shl (const? 32 (-2)) e { «nsw» := true, «nuw» := false }

theorem a_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1),
  x_1 = 1#1 →
    ¬(True ∧ (2#32).saddOverflow (signExtend 32 x) = true) →
      zeroExtend 32 x_1 + 1#32 + (0#32 - zeroExtend 32 x) = 2#32 + signExtend 32 x

theorem udiv_i32_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬zeroExtend 32 x = 0 → ¬x = 0 → zeroExtend 32 x_1 / zeroExtend 32 x = zeroExtend 32 (x_1 / x)

theorem lshr_add_exact_proof : lshr_add_exact_before ⊑ lshr_add_exact_after

theorem e_236 :
     - 7 * (x ||| y) - 6 * x - 1 *  ~~~(x &&&  ~~~x) - 2 *  ~~~(x ||| y) + 8 *  ~~~(x |||  ~~~y) + 11 * (x &&&  ~~~y) + 11 * (x &&& y) =  - 3 * (x |||  ~~~y)

theorem lor_land_left2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1), ¬x_1 = 1#1 → ¬x = 1#1 → 0#1 = x

theorem test23_logical_thm (e : IntW 32) :
  select (icmp IntPred.sgt e (const? 32 1)) (icmp IntPred.sle e (const? 32 2)) (const? 1 0) ⊑
    icmp IntPred.eq e (const? 32 2)

theorem e_70 :
     - 1 *  ~~~y - 5 *  ~~~(x &&&  ~~~y) + 8 *  ~~~(x ||| y) + 7 *  ~~~(x |||  ~~~y) + 5 * (x &&& y) =  - 1 * (x &&&  ~~~y) + 2 *  ~~~x

lemma helper_dec_enc (bvs : BitVecs n) (h : w' = bvs.w) i (j : Nat) :
    (bvs.bvs.get i)[j]?.getD false = (h ▸ bvs.bvs.get i)[j]?.getD false

theorem ashr_lshr_shift_amt_mismatch_proof : ashr_lshr_shift_amt_mismatch_before ⊑ ashr_lshr_shift_amt_mismatch_after

theorem ashrsgt_02_04_exact_proof : ashrsgt_02_04_exact_before ⊑ ashrsgt_02_04_exact_after

theorem sel_false_val_is_a_masked_shl_of_true_val2_thm.extracted_1._4 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬(True ∧ ((x_1 &&& 15#32) <<< 2#32).sshiftRight' 2#32 ≠ x_1 &&& 15#32 ∨
        True ∧ (x_1 &&& 15#32) <<< 2#32 >>> 2#32 ≠ x_1 &&& 15#32 ∨ 2#32 ≥ ↑32) →
    ¬ofBool ((x_1 &&& 15#32) <<< 2#32 == 0#32) = 1#1 →
      ¬(True ∧ ((x_1 &&& 15#32) <<< 2#32).sshiftRight' 2#32 ≠ x_1 &&& 15#32 ∨
            True ∧ (x_1 &&& 15#32) <<< 2#32 >>> 2#32 ≠ x_1 &&& 15#32 ∨
              2#32 ≥ ↑32 ∨ zeroExtend 64 ((x_1 &&& 15#32) <<< 2#32) ≥ ↑64) →
        ¬(2#32 ≥ ↑32 ∨ True ∧ (x_1 <<< 2#32 &&& 60#32).msb = true ∨ zeroExtend 64 (x_1 <<< 2#32 &&& 60#32) ≥ ↑64) →
          x.sshiftRight' (zeroExtend 64 ((x_1 &&& 15#32) <<< 2#32)) =
            x.sshiftRight' (zeroExtend 64 (x_1 <<< 2#32 &&& 60#32))

theorem lshrult_01_14_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 1#4 <<< 1#4 ≠ x ∨ 1#4 ≥ ↑4) → ofBool (x >>> 1#4 <ᵤ BitVec.ofInt 4 (-2)) = 1#1

theorem eq_signed_to_small_unsigned_proof : eq_signed_to_small_unsigned_before ⊑ eq_signed_to_small_unsigned_after

theorem negtest_near_pow2_cmpval_ashr_slt_noexact_thm (e : IntW 8) :
  icmp IntPred.slt (ashr e (const? 8 1)) (const? 8 5) ⊑ icmp IntPred.slt e (const? 8 10)

theorem e_1078 :
     - 2 *  ~~~z + 1 *  ~~~(z &&&  ~~~z) - 3 * z - 1 *  ~~~(z &&&  ~~~t) + 7 * (z ||| t) + 2 *  ~~~(z ||| t) + 6 *  ~~~(z |||  ~~~t) - 5 * (z &&&  ~~~t) =  - 7 * (z &&& t) + 11 * t

theorem select_icmp_eq_and_32_0_xor_8_proof : select_icmp_eq_and_32_0_xor_8_before ⊑ select_icmp_eq_and_32_0_xor_8_after

theorem test15_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(x ≥ ↑32 ∨ zeroExtend 64 (1#32 <<< x) = 0) →
    ¬(True ∧ ((-1#32) <<< x).sshiftRight' x ≠ -1#32 ∨ x ≥ ↑32 ∨ True ∧ (x_1 &&& ((-1#32) <<< x ^^^ -1#32)).msb = true) →
      zeroExtend 64 x_1 % zeroExtend 64 (1#32 <<< x) = zeroExtend 64 (x_1 &&& ((-1#32) <<< x ^^^ -1#32))

theorem ashrslt_01_10_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬1#4 ≥ ↑4 → ofBool (x.sshiftRight' 1#4 <ₛ BitVec.ofInt 4 (-6)) = 0#1

@[simp] theorem addAux_zero (x y : BitStream) : (x.addAux y 0) =
  ((x 0) ^^ (y 0), (x 0) && (y 0))

theorem mul_mask_pow2_eq4_thm (e : IntW 8) :
  icmp IntPred.eq (LLVM.and (mul e (const? 8 44)) (const? 8 4)) (const? 8 4) ⊑
    icmp IntPred.ne (LLVM.and e (const? 8 1)) (const? 8 0)

theorem main7g_logical_thm.extracted_1._16 : ∀ (x x_1 x_2 x_3 x_4 : BitVec 32),
  ¬ofBool (x_4 &&& x_3 == x_4 &&& x_3 &&& x_2) = 1#1 →
    ¬ofBool (x_4 &&& x_3 != x_4 &&& x_3 &&& x_2) = 1#1 →
      ¬0#1 = 1#1 → 1#32 = zeroExtend 32 (ofBool (x_1 &&& x != x_1 &&& x &&& x_2))

theorem test_simplify_decrement_invalid_ne_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬ofBool (x != 0#8) = 1#1 → x - 1#8 = signExtend 8 (ofBool (x == 0#8))

theorem bools2_logical_commute0_thm.extracted_1._5 : ∀ (x x_1 : BitVec 1),
  x_1 = 1#1 → ¬x_1 ^^^ 1#1 = 1#1 → x = 1#1 → 1#1 = x

theorem t2_proof : t2_before ⊑ t2_after

theorem e_1415 :
    5 * (z ||| t) - 3 *  ~~~t - 7 *  ~~~(z &&& t) + 2 *  ~~~z + 1 * z - 2 *  ~~~(z ^^^ t) - 6 *  ~~~(z &&&  ~~~t) + 22 *  ~~~(z ||| t) + 6 *  ~~~(z |||  ~~~t) + 8 * (z &&& t) =  - 10 * (z &&&  ~~~t) + 6 * (z |||  ~~~t)

theorem not_and_and_or_no_or_commute2_and_proof : not_and_and_or_no_or_commute2_and_before ⊑ not_and_and_or_no_or_commute2_and_after

theorem t0_proof : t0_before ⊑ t0_after

theorem and_not_or_commute3_proof : and_not_or_commute3_before ⊑ and_not_or_commute3_after

theorem lt_unsigned_to_large_unsigned_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (zeroExtend 32 x <ᵤ 1024#32) = 1#1

theorem or_xor_tree_0111_proof : or_xor_tree_0111_before ⊑ or_xor_tree_0111_after

theorem e_663 :
    4 * (x |||  ~~~y) + 7 *  ~~~(x &&&  ~~~x) + 11 *  ~~~(x &&& y) + 2 * (x ^^^ y) - 1 * (x ||| y) + 4 * x - 5 * y + 5 *  ~~~y - 27 *  ~~~(x ||| y) - 14 *  ~~~(x |||  ~~~y) = 9 * (x &&& y) + 32 * (x &&&  ~~~y)

theorem test_shl_nsw__nuw_is_safe_thm (e : IntW 64) (e_1 : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e_1 (const? 32 1073741822)) (const? 32 0)) e
      (ashr e (zext 64 (shl (LLVM.and e_1 (const? 32 1073741822)) (const? 32 2) { «nsw» := true, «nuw» := false }))) ⊑
    ashr e (zext 64 (LLVM.and (shl e_1 (const? 32 2)) (const? 32 (-8))) { «nneg» := true })

theorem ashrslt_02_09_exact_proof : ashrslt_02_09_exact_before ⊑ ashrslt_02_09_exact_after

theorem uge_umin2_proof : uge_umin2_before ⊑ uge_umin2_after

theorem test_sub_255_Y_eq_255_proof : test_sub_255_Y_eq_255_before ⊑ test_sub_255_Y_eq_255_after

theorem xor_add_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ (73#32).ssubOverflow (x &&& 31#32) = true ∨ True ∧ (73#32).usubOverflow (x &&& 31#32) = true) →
    (x &&& 31#32 ^^^ 31#32) + 42#32 = 73#32 - (x &&& 31#32)

theorem negative_not_less_than_logical_proof : negative_not_less_than_logical_before ⊑ negative_not_less_than_logical_after

theorem test_sub__nuw_is_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 2147483647)) (const? 32 1073741824)) (const? 32 1073741824)
      (sub (const? 32 (-2147483648)) (LLVM.and e (const? 32 2147483647))) ⊑
    sub (const? 32 (-2147483648)) (LLVM.and e (const? 32 2147483647)) { «nsw» := false, «nuw» := true }

theorem n2_thm (e : IntW 8) :
  LLVM.sdiv e (const? 8 (-128)) ⊑ zext 8 (icmp IntPred.eq e (const? 8 (-128)))

theorem t2_thm (e : IntW 8) :
  icmp IntPred.slt (sub (const? 8 0) e { «nsw» := true, «nuw» := false }) e ⊑
    icmp IntPred.sgt e (const? 8 0)

theorem lshrugt_02_05_thm (e : IntW 4) : icmp IntPred.ugt (lshr e (const? 4 2)) (const? 4 5) ⊑ const? 1 0

theorem ashrslt_02_14_exact_thm (e : IntW 4) :
  icmp IntPred.slt (ashr e (const? 4 2) { «exact» := true }) (const? 4 (-2)) ⊑ const? 1 0

theorem ripple_nsw2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  True ∧ (x_1 &&& BitVec.ofInt 16 (-16385)).saddOverflow (x &&& 1#16) = true ∨
      True ∧ (x_1 &&& BitVec.ofInt 16 (-16385)).uaddOverflow (x &&& 1#16) = true →
    False

theorem test_srem_canonicalize_op0_proof : test_srem_canonicalize_op0_before ⊑ test_srem_canonicalize_op0_after

theorem Polynomial.degree_toFinsupp [Semiring M] [DecidableEq M]
  (xs : List M) :
  degree { toFinsupp := List.toFinsupp (l := xs) } ≤ List.length xs

theorem test1_proof : test1_before ⊑ test1_after

theorem udiv_c_i32_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬zeroExtend 32 x = 0 → x = 0 ∨ True ∧ (10#8 / x).msb = true → False

theorem e_1045 :
     - 1 *  ~~~(z &&&  ~~~t) + 1 *  ~~~(z &&&  ~~~z) + 1 * (z ||| t) - 5 * (z |||  ~~~t) + 1 *  ~~~(z |||  ~~~t) + 5 * (z &&&  ~~~t) + 4 * (z &&& t) = 2 *  ~~~(z &&& t) - 7 *  ~~~(z ||| t)

theorem e_565 :
     - 11 *  ~~~(x &&& y) - 11 *  ~~~(x &&&  ~~~x) + 1 * x - 2 *  ~~~y - 6 * (x ||| y) + 4 *  ~~~(x ^^^ y) + 22 *  ~~~(x ||| y) + 31 * (x &&&  ~~~y) + 14 * (x &&& y) = 2 * (x |||  ~~~y) - 28 *  ~~~(x |||  ~~~y)

theorem e_1255 :
     - 11 * (z ^^^ t) - 3 *  ~~~(z &&&  ~~~z) + 2 *  ~~~z - 1 * z + 1 * (z |||  ~~~t) - 8 *  ~~~(z ||| t) + 1 *  ~~~(z |||  ~~~t) + 14 * (z &&&  ~~~t) - 5 * (z &&& t) =  - 11 *  ~~~(z &&&  ~~~t) + 3 *  ~~~(z ^^^ t)

theorem ult_swap_and_not_max_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x <ᵤ x_1) &&& ofBool (x != -1#8) = ofBool (x <ᵤ x_1)

theorem test84_proof : test84_before ⊑ test84_after

theorem not_logicalAnd_not_op1_thm (e e_1 : IntW 1) :
  LLVM.xor (select e_1 (LLVM.xor e (const? 1 1)) (const? 1 0)) (const? 1 1) ⊑
    select (LLVM.xor e_1 (const? 1 1)) (const? 1 1) e

theorem test10_proof : test10_before ⊑ test10_after

theorem land_band_right1_proof : land_band_right1_before ⊑ land_band_right1_after

theorem lshrugt_01_03_thm (e : IntW 4) :
  icmp IntPred.ugt (lshr e (const? 4 1)) (const? 4 3) ⊑ icmp IntPred.slt e (const? 4 0)

@[simp] theorem Valuation.ofHVector_inj (xs ys : HVector toType ts) :
    ofHVector xs = ofHVector ys ↔ xs = ys

theorem shl_add_lshr_comm_thm (e e_1 e_2 : IntW 32) :
  lshr (add (mul e_2 e_2) (shl e_1 e { «nsw» := false, «nuw» := true }) { «nsw» := false, «nuw» := true }) e ⊑
    add (lshr (mul e_2 e_2) e) e_1 { «nsw» := false, «nuw» := true }

theorem sdiv_exact_eq_0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ x_1.smod x ≠ 0 ∨ (x == 0 || 8 != 1 && x_1 == intMin 8 && x == -1) = true) →
    ofBool (x_1.sdiv x == 0#8) = ofBool (x_1 == 0#8)

theorem eq_smax4_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 + 3#32 <ₛ x) = 1#1 → ofBool (x_1 + 3#32 == x) = ofBool (x ≤ₛ x_1 + 3#32)

theorem PR2330_thm (e : IntW 32) :
  icmp IntPred.eq (LLVM.and (shl (const? 32 1) e) (const? 32 1)) (const? 32 0) ⊑
    icmp IntPred.ne e (const? 32 0)

theorem e_1073 :
    1 *  ~~~t + 3 * (z ^^^ t) + 1 *  ~~~(z &&& t) + 1 *  ~~~z - 3 *  ~~~(z ||| t) + 2 *  ~~~(z |||  ~~~t) + 7 * (z &&& t) = 5 * (z &&&  ~~~t) + 7 * t

theorem icmp_uge_x_y_2_thm (e e_1 : IntW 8) :
  icmp IntPred.ule (mul e_1 e_1) (LLVM.and (mul e_1 e_1) e) ⊑
    icmp IntPred.eq (LLVM.and (mul e_1 e_1) e) (mul e_1 e_1)

theorem ashrslt_03_10_proof : ashrslt_03_10_before ⊑ ashrslt_03_10_after

theorem n1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ¬x_1 ≥ ↑8 → True ∧ 1#8 <<< x_1 >>> x_1 ≠ 1#8 ∨ x_1 ≥ ↑8 → False

theorem main3d_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 != 0#32) ||

theorem select_icmp_sgt_allones_smin_proof : select_icmp_sgt_allones_smin_before ⊑ select_icmp_sgt_allones_smin_after

theorem demorgan_nand_apint1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 7),
  (x_1 ^^^ -1#7) &&& x ^^^ -1#7 = x_1 ||

theorem not_add_thm.extracted_1._1 : ∀ (x : BitVec 32), x + 123#32 ^^^ -1#32 = BitVec.ofInt 32 (-124) - x

theorem sle_swap_and_min_commute_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == BitVec.ofInt 8 (-128)) = 1#1 → ofBool (x_1 ≤ₛ x) = ofBool (x_1 == BitVec.ofInt 8 (-128))

theorem shrink_xor_thm.extracted_1._1 : ∀ (x : BitVec 64), truncate 32 (x ^^^ 1#64) = truncate 32 x ^^^ 1#32

theorem uadd_sat_flipped_wrong_bounds4_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (BitVec.ofInt 32 (-8) ≤ᵤ x) = 1#1 → ¬ofBool (BitVec.ofInt 32 (-9) <ᵤ x) = 1#1 → -1#32 = x + 9#32

theorem test8_proof : test8_before ⊑ test8_after

theorem udiv_i32_thm (e e_1 : IntW 8) : LLVM.udiv (zext 32 e_1) (zext 32 e) ⊑ zext 32 (LLVM.udiv e_1 e)

theorem select_icmp_eq_0_and_1_or_1_proof : select_icmp_eq_0_and_1_or_1_before ⊑ select_icmp_eq_0_and_1_or_1_after

theorem main4_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 7#32 == 7#32) &&& ofBool (x &&& 48#32 == 48#32) = 1#1 →
    0#32 = zeroExtend 32 (ofBool (x &&& 55#32 != 55#32))

theorem t7_ugt_sgt_neg1_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.ugt (add e_2 (const? 32 16)) (const? 32 143))
      (select (icmp IntPred.sgt e_2 (const? 32 (-17))) e_1 e) e_2 ⊑
    select (icmp IntPred.sgt e_2 (const? 32 127)) e_1
      (select (icmp IntPred.slt e_2 (const? 32 (-16))) e e_2)

theorem sext_zext_apint1_thm.extracted_1._1 : ∀ (x : BitVec 77),
  signExtend 1024 (zeroExtend 533 x) = zeroExtend 1024 x

theorem test3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 49), ¬1#49 ≥ ↑49 → (x_1 ||| x <<< 1#49) &&& 1#49 = x_1 &&& 1#49

theorem negate_zext_proof : negate_zext_before ⊑ negate_zext_after

theorem pr40493_neg2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x * 12#32 &&& 15#32 == 0#32) = ofBool (x * 12#32 &&& 12#32 == 0#32)

theorem positive_biggerLshr_shlnuw_lshrexact_proof : positive_biggerLshr_shlnuw_lshrexact_before ⊑ positive_biggerLshr_shlnuw_lshrexact_after

theorem src2_thm (e e_1 : IntW 32) :
  add (LLVM.and e_1 e) (LLVM.xor (LLVM.or e e_1) (const? 32 (-1))) ⊑ LLVM.xor (LLVM.xor e_1 e) (const? 32 (-1))

theorem test5_thm (e : IntW 8) (e_1 : IntW 32) :
  urem e_1 (shl (const? 32 32) (zext 32 e)) ⊑
    LLVM.and e_1
      (add (shl (const? 32 32) (zext 32 e { «nneg» := true }) { «nsw» := false, «nuw» := true })
        (const? 32 (-1)))

theorem or_simplify_ugt_fail_proof : or_simplify_ugt_fail_before ⊑ or_simplify_ugt_fail_after

theorem demorgan_nor_use2a_thm (e e_1 : IntW 8) :
  LLVM.sdiv (LLVM.xor (LLVM.or (LLVM.xor e_1 (const? 8 (-1))) e) (const? 8 (-1)))
      (mul (LLVM.xor e_1 (const? 8 (-1))) (const? 8 23)) ⊑
    LLVM.sdiv (LLVM.and e_1 (LLVM.xor e (const? 8 (-1)))) (mul (LLVM.xor e_1 (const? 8 (-1))) (const? 8 23))

theorem e_711 :
    4 *  ~~~(x &&&  ~~~y) + 7 * (x |||  ~~~y) - 6 *  ~~~(x &&& y) + 4 *  ~~~(x ^^^ y) + 1 * (x ^^^ y) - 1 *  ~~~x - 2 * x - 2 *  ~~~y - 6 *  ~~~(x ||| y) + 2 * (x &&&  ~~~y) - 11 * (x &&& y) = 2 * y - 4 *  ~~~(x |||  ~~~y)

theorem xor_or2_proof : xor_or2_before ⊑ xor_or2_after

theorem slt_zero_eq_i1_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  ¬31#32 ≥ ↑32 → ofBool (zeroExtend 32 x_1 == x >>> 31#32) = ofBool (-1#32 <ₛ x) ^^^ x_1

theorem test2_thm (e : IntW 1005) : LLVM.xor e (const? 1005 0) ⊑ e

theorem drop_nsw_trunc_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬(True ∧ signExtend 16 (truncate 8 (x_1 &&& 255#16 &&& x)) ≠ x_1 &&& 255#16 &&& x) →
    truncate 8 (x_1 &&& 255#16 &&& x) = truncate 8 (x_1 &&& x)

theorem xor_ugt_2_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8), True ∧ (x &&& 63#8 &&& 64#8 != 0) = true → False

theorem pr51551_neg2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (x_1 &&& BitVec.ofInt 32 (-7)).smulOverflow x = true) →
    truncate 1 x_1 ^^^ 1#1 = 1#1 → ofBool ((x_1 &&& BitVec.ofInt 32 (-7)) * x &&& 7#32 == 0#32) = 1#1

theorem and_xor_commute2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(x_1 = 0 ∨ x = 0 ∨ x = 0) →
    ¬(x = 0 ∨ x_1 = 0) → 42#32 / x_1 &&& 42#32 / x ^^^ 42#32 / x = 42#32 / x &&& (42#32 / x_1 ^^^ -1#32)

theorem select_xor_icmp_bad_3_proof : select_xor_icmp_bad_3_before ⊑ select_xor_icmp_bad_3_after

theorem bitwise_and_logical_and_masked_icmp_allones_thm (e : IntW 1) (e_1 : IntW 32) :
  LLVM.and (select (icmp IntPred.eq (LLVM.and e_1 (const? 32 8)) (const? 32 8)) e (const? 1 0))
      (icmp IntPred.eq (LLVM.and e_1 (const? 32 7)) (const? 32 7)) ⊑
    select (icmp IntPred.eq (LLVM.and e_1 (const? 32 15)) (const? 32 15)) e (const? 1 0)

theorem or_not_and_commute8_proof : or_not_and_commute8_before ⊑ or_not_and_commute8_after

theorem logical_and_implies_folds_proof : logical_and_implies_folds_before ⊑ logical_and_implies_folds_after

theorem testi16i8_com_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(8#16 ≥ ↑16 ∨ 7#8 ≥ ↑8) →
    ofBool (truncate 8 (x >>> 8#16) == (truncate 8 x).sshiftRight' 7#8) = ofBool (x + 128#16 <ᵤ 256#16)

theorem lshr_16_add_zext_basic_proof : lshr_16_add_zext_basic_before ⊑ lshr_16_add_zext_basic_after

theorem shl_nsw_nuw_add_nsw_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ (1#32 <<< x).sshiftRight' x ≠ 1#32 ∨
        True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨ x ≥ ↑32 ∨ True ∧ (1#32 <<< x).saddOverflow (-1#32) = true) →
    True ∧ ((-1#32) <<< x).sshiftRight' x ≠ -1#32 ∨ x ≥ ↑32 → False

theorem lshrult_02_09_exact_proof : lshrult_02_09_exact_before ⊑ lshrult_02_09_exact_after

theorem ule_swap_or_min_proof : ule_swap_or_min_before ⊑ ule_swap_or_min_after

theorem icmp_slt_0_and_icmp_sge_neg1_i64_fail_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬62#64 ≥ ↑64 →
    ¬ofBool (BitVec.ofInt 64 (-2) <ₛ x) = 1#1 → x >>> 62#64 &&& zeroExtend 64 (ofBool (-1#64 ≤ₛ x)) = 0#64

theorem and_or_not_not_commute3_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  (x_2 &&& x_1 ^^^ -1#32 ||| x) &&& (x &&& x_1 ^^^ -1#32) = (x_2 ||| x) &&& x_1 ^^^ -1#32

theorem or_not_and_commute1_proof : or_not_and_commute1_before ⊑ or_not_and_commute1_after

theorem e_2350 :
    1 * (f ^^^ (d ||| ( ~~~e &&& f))) + 11 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 5 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 2 * ((d |||  ~~~e) &&& (e ^^^ f)) - 6 * (f ^^^ (d ||| ( ~~~e ||| f))) - 1 * ( ~~~e &&& (d ^^^ f)) - 2 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 1 * (f ||| (d &&&  ~~~e)) + 1 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 11 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 2 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 1 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 11 * (e ||| (d ^^^ f)) + 4 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 6 * (f &&& (d ^^^ e)) - 7 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 6 * ( ~~~d ||| ( ~~~e ||| f)) - 2 * (e ^^^  ~~~(d |||  ~~~f)) + 2 *  ~~~(d &&& ( ~~~e ||| f)) + 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 1 *  ~~~(d &&& f) - 11 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 1 * ((d &&& e) ||| (e ^^^ f)) + 11 * ((d ^^^ e) ||| (d ^^^ f)) - 6 *  ~~~(d &&&  ~~~d) - 3 * ((d &&& e) ^^^ (e |||  ~~~f)) + 4 * ((d &&& f) ^^^ (e ||| f)) - 3 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 1 * ( ~~~f ||| (d ^^^ e)) + 1 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 3 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 6 * ( ~~~e &&&  ~~~(d ^^^ f)) + 3 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) - 5 *  ~~~(d &&& e) - 2 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 3 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 4 * (d ^^^ e) - 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 3 * (f |||  ~~~(d ||| e)) - 5 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 2 * (d &&&  ~~~f) + 1 * (f ||| (d ^^^ e)) + 1 * ((d &&& f) ||| (e &&&  ~~~f)) - 7 * (e &&& (d ||| f)) + 2 * (f |||  ~~~(d |||  ~~~e)) - 7 * (e ^^^ (d &&& (e ||| f))) - 5 * ( ~~~d ||| (e &&& f)) + 7 * (e ^^^ (d ||| (e ^^^ f))) + 4 * (e &&& (d ^^^ f)) - 2 * ( ~~~d &&& (e ||| f)) - 1 * (e ^^^ ( ~~~d ||| (e ^^^ f))) + 3 * (d ^^^ (e &&& f)) - 3 * (e ^^^  ~~~(d ||| f)) - 2 * (f |||  ~~~(d ^^^ e)) + 7 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) + 2 * (e ||| f) + 1 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 1 *  ~~~(d |||  ~~~f) + 1 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 7 *  ~~~(d ||| (e ||| f)) + 15 *  ~~~(d ||| ( ~~~e ||| f)) - 20 *  ~~~( ~~~d ||| (e ||| f)) + 38 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 18 * ( ~~~d &&& ( ~~~e &&& f)) - 8 * ( ~~~d &&& (e &&& f)) - 15 * (d &&& ( ~~~e &&& f)) + 38 * (d &&& (e &&& f)) =  - 2 * (f ^^^  ~~~(d &&& (e ||| f)))

theorem n2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬x_1 ≥ ↑8 →
    ¬(True ∧ ((-1#8) <<< x_1).sshiftRight' x_1 ≠ -1#8 ∨ x_1 ≥ ↑8) →
      ofBool (((-1#8) <<< x_1 ^^^ 1#8) &&& x == x) = ofBool (x &&& ((-1#8) <<< x_1 ^^^ BitVec.ofInt 8 (-2)) == 0#8)

theorem sub_select_not_sext_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → 64#64 - signExtend 64 (x_1 ^^^ 1#1) = 65#64

theorem sub_not_proof : sub_not_before ⊑ sub_not_after

theorem eq_umax3_proof : eq_umax3_before ⊑ eq_umax3_after

theorem ult_1_impliesF_eq_1_thm.extracted_1._6 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 <ᵤ 1#8) = 1#1 → ¬ofBool (x_1 != 0#8) = 1#1 → ofBool (x_1 == x) = 0#1

omit [LawfulBEq A] [Fintype S] [DecidableEq S] in
@[simp]
lemma processOneElem_initials (st : worklist.St A S) (final : S → Bool) (a : A) (sa : S) (s : State) :
    (processOneElem A S final s st (a, sa)).m.initials = st.m.initials

theorem icmp_slt_0_or_icmp_sge_neg1_i32_proof : icmp_slt_0_or_icmp_sge_neg1_i32_before ⊑ icmp_slt_0_or_icmp_sge_neg1_i32_after

theorem test4_thm (e e_1 : IntW 32) :
  zext 32 (zext 8 (icmp IntPred.slt e_1 e)) ⊑ zext 32 (icmp IntPred.slt e_1 e)

@[simp]
theorem toBitVec_neg (a : BitStream) :
    (- a).toBitVec w = - (a.toBitVec w)

theorem fold_sext_to_and3_proof : fold_sext_to_and3_before ⊑ fold_sext_to_and3_after

theorem lshrult_01_03_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 1#4 <<< 1#4 ≠ x ∨ 1#4 ≥ ↑4) → ofBool (x >>> 1#4 <ᵤ 3#4) = ofBool (x <ᵤ 6#4)

theorem and_comm (x y : BitStream) : x &&& y = y &&& x

theorem or_nosignbit_select_lshr_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 → ¬8#32 ≥ ↑32 → (x ||| 2147418112#32) >>> 8#32 = x >>> 8#32 ||

theorem bv_283 :
    ∀ (e e_1 : LLVM.IntW 1), LLVM.mul e_1 e ⊑ LLVM.and e_1 e

theorem ashr_C1_add_A_C2_i32_thm (e : IntW 32) :
  ashr (const? 32 6) (add (LLVM.and e (const? 32 65535)) (const? 32 5)) ⊑ const? 32 0

theorem test11_proof : test11_before ⊑ test11_after

theorem shl_and_lshr_comm_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ x_1 <<< x >>> x ≠ x_1 ∨ x ≥ ↑32 ∨ x ≥ ↑32) → x ≥ ↑32 → False

theorem eq_basic_equal_minus_1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == -1#8) ||

theorem p0_proof : p0_before ⊑ p0_after

theorem or_logic_or_logic_and_6_thm.extracted_1._7 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 ||

theorem ashrslt_03_05_exact_proof : ashrslt_03_05_exact_before ⊑ ashrslt_03_05_exact_after

theorem e_1991 :
     - 11 * ((a &&&  ~~~b) ||| (b ^^^ c)) - 2 * (b ^^^ ( ~~~a ||| (b ^^^ c))) - 1 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) - 2 * (b ^^^ (a &&& ( ~~~b ||| c))) - 6 * (a ^^^ (b ||| c)) + 4 * ( ~~~(a ||| b) |||  ~~~(b ^^^ c)) - 1 * (c &&& (a |||  ~~~b)) - 1 * (a ||| ( ~~~b ||| c)) + 1 * (b ||| c) - 11 *  ~~~(a &&& (b ^^^ c)) - 11 *  ~~~( ~~~a ||| (b ^^^ c)) + 4 * ((a &&& b) |||  ~~~(b ^^^ c)) - 11 *  ~~~(a ^^^ b) - 2 * (a ^^^ ( ~~~b &&& c)) - 1 *  ~~~(a ||| b) + 2 * (c ^^^ (a ||| ( ~~~b ||| c))) - 6 * (b ^^^  ~~~(a ||| (b ^^^ c))) + 7 * ((a &&& c) ||| (b &&&  ~~~c)) + 5 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) + 11 *  ~~~(a ^^^ (b &&& c)) + 1 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) + 2 * (c |||  ~~~(a ||| b)) - 5 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) - 6 *  ~~~( ~~~a &&& ( ~~~b &&& c)) - 11 * ((a &&& b) ^^^ (a ^^^ ( ~~~b ||| c))) - 3 * (b ||| (a ^^^ c)) + 5 *  ~~~(a &&&  ~~~a) - 7 * (b ||| (a &&&  ~~~c)) - 5 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) + 1 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) + 3 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 5 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) + 1 * (c &&& (a ||| b)) - 1 * (b ^^^  ~~~(a &&& (b ||| c))) - 6 *  ~~~(a ^^^ (b ^^^ c)) + 1 *  ~~~( ~~~a &&& (b ||| c)) + 5 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) - 6 * (b ^^^ (a ||| ( ~~~b &&& c))) - 3 * ( ~~~(a ||| b) ||| (b ^^^ c)) - 2 * (c ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 2 * ((a &&& c) ^^^ (b ||| c)) - 11 * (c ^^^ ( ~~~a ||| (b &&& c))) - 5 * ((a &&&  ~~~b) ||| (a ^^^ (b ^^^ c))) - 6 * ( ~~~a ||| (b ||| c)) - 5 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) + 2 *  ~~~(a &&&  ~~~b) + 3 * (c ^^^  ~~~(a |||  ~~~b)) - 1 * (a &&& (b ^^^ c)) - 2 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) - 7 * ((a ^^^ b) &&& (a ^^^ c)) + 48 *  ~~~(a ||| (b ||| c)) + 69 *  ~~~(a ||| ( ~~~b ||| c)) + 66 *  ~~~( ~~~a ||| (b ||| c)) + 42 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 55 * ( ~~~a &&& ( ~~~b &&& c)) + 57 * ( ~~~a &&& (b &&& c)) + 40 * (a &&& ( ~~~b &&& c)) + 56 * (a &&& (b &&& c)) =  - 4 *  ~~~(a ||| (b ^^^ c))

theorem test23_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.sgt e (const? 32 1)) (icmp IntPred.sle e (const? 32 2)) ⊑
    icmp IntPred.eq e (const? 32 2)

theorem ne_21_comm_ne2_proof : ne_21_comm_ne2_before ⊑ ne_21_comm_ne2_after

theorem e_1418 :
     - 7 * z - 11 * (z ||| t) - 6 * (z ^^^ t) + 3 *  ~~~t + 1 * (z |||  ~~~t) - 2 * t - 3 *  ~~~(z ||| t) + 20 *  ~~~(z |||  ~~~t) + 21 * (z &&&  ~~~t) + 19 * (z &&& t) = 1 *  ~~~(z &&& t)

@[simp] theorem Valuation.nil_append {V : Γ.Valuation} :
    HAppend.hAppend (α := Valuation no_index _) (γ := Valuation no_index _)
      (nil (Ty:=Ty)) V -- nil ++ V
    = V

theorem test29_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  zeroExtend 32 (truncate 8 x_1 ||| truncate 8 x) = (x_1 ||| x) &&& 255#32

theorem sdiv6_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.smod 3#32 ≠ 0 ∨ (3#32 == 0 || 32 != 1 && x == intMin 32 && 3#32 == -1) = true) →
    x.sdiv 3#32 * BitVec.ofInt 32 (-3) = 0#32 - x

theorem nonexact_ashr_ne_exactdiv_proof : nonexact_ashr_ne_exactdiv_before ⊑ nonexact_ashr_ne_exactdiv_after

theorem e_1361 :
    4 *  ~~~z + 2 * t + 1 *  ~~~(z &&&  ~~~z) - 3 *  ~~~(z ^^^ t) + 2 *  ~~~(z &&&  ~~~t) + 7 *  ~~~(z &&& t) + 4 *  ~~~t + 5 * (z ^^^ t) - 21 *  ~~~(z |||  ~~~t) - 17 * (z &&&  ~~~t) = 2 * (z &&& t) + 15 *  ~~~(z ||| t)

theorem main1_logical_proof : main1_logical_before ⊑ main1_logical_after

theorem e_1335 :
     - 1 *  ~~~(z &&&  ~~~z) - 7 * t + 5 *  ~~~(z &&& t) + 11 *  ~~~t + 2 * (z ^^^ t) + 5 *  ~~~(z ^^^ t) - 20 *  ~~~(z ||| t) - 18 * (z &&&  ~~~t) + 2 * (z &&& t) =  - 1 * (z ||| t)

theorem select_or_disjoint_or_proof : select_or_disjoint_or_before ⊑ select_or_disjoint_or_after

theorem test_mul__nsw_is_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.or e (const? 32 (-83886080))) (const? 32 (-83886079))) (const? 32 (-754974711))
      (mul (LLVM.or e (const? 32 (-83886080))) (const? 32 9)) ⊑
    mul (LLVM.or e (const? 32 (-83886080))) (const? 32 9) { «nsw» := true, «nuw» := false }

theorem test3_proof : test3_before ⊑ test3_after

theorem test31_proof : test31_before ⊑ test31_after

theorem test9_proof : test9_before ⊑ test9_after

theorem t0_proof : t0_before ⊑ t0_after

theorem lshrugt_02_10_exact_proof : lshrugt_02_10_exact_before ⊑ lshrugt_02_10_exact_after

theorem test_logical_and_ne_a_b_thm (e e_1 : IntW 8) (e_2 : IntW 1) :
  select (select e_2 (icmp IntPred.ne e_1 e) (const? 1 0)) e_1 e ⊑ select e_2 e_1 e

theorem or_nosignbit_lshr_proof : or_nosignbit_lshr_before ⊑ or_nosignbit_lshr_after

theorem lshrult_01_10_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 1#4 <<< 1#4 ≠ x ∨ 1#4 ≥ ↑4) → ofBool (x >>> 1#4 <ᵤ BitVec.ofInt 4 (-6)) = 1#1

theorem test7_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬32#128 ≥ ↑128 →
    ¬(32#64 ≥ ↑64 ∨ True ∧ (x >>> 32#64).msb = true) →
      truncate 92 (zeroExtend 128 x >>> 32#128) = zeroExtend 92 (x >>> 32#64)

theorem xor_signbit_select_ashr_proof : xor_signbit_select_ashr_before ⊑ xor_signbit_select_ashr_after

theorem e_57 :
     - 1 * (x ^^^ y) + 1 *  ~~~(x ||| y) - 9 *  ~~~(x |||  ~~~y) + 1 * (x &&&  ~~~y) - 11 * (x &&& y) =  - 11 * y + 1 *  ~~~x

theorem R.trimTensor_append_not_zero (tensor : List Int) (x : Int) (hX : x ≠ 0) :
  trimTensor (tensor ++ [x]) = tensor ++ [x]

theorem pr33078_4_thm.extracted_1._1 : ∀ (x : BitVec 3),
  ¬13#16 ≥ ↑16 →
    13#16 ≥ ↑16 ∨
        True ∧ signExtend 16 (truncate 8 (signExtend 16 x >>> 13#16)) ≠ signExtend 16 x >>> 13#16 ∨
          True ∧ zeroExtend 16 (truncate 8 (signExtend 16 x >>> 13#16)) ≠ signExtend 16 x >>> 13#16 →
      False

theorem lshr_pow2_sgt_proof : lshr_pow2_sgt_before ⊑ lshr_pow2_sgt_after

theorem icmp_slt_0_and_icmp_sge_neg1_i32_proof : icmp_slt_0_and_icmp_sge_neg1_i32_before ⊑ icmp_slt_0_and_icmp_sge_neg1_i32_after

theorem e_1742 :
    1 *  ~~~(a ^^^ (b &&& c)) - 11 * ( ~~~b &&&  ~~~(a ^^^ c)) + 2 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 * (b ^^^ ( ~~~a ||| (b ||| c))) - 1 * (c ^^^ (a &&&  ~~~b)) + 5 * (a ^^^ (b ^^^ c)) - 1 * (c ^^^ (a ||| (b &&& c))) + 7 *  ~~~( ~~~a &&& (b &&& c)) + 1 * (b |||  ~~~(a |||  ~~~c)) - 2 * (b ^^^ (a ||| c)) + 1 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 1 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) - 1 * (b &&& (a ||| c)) - 2 * ((a &&& c) |||  ~~~(b ||| c)) + 3 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) - 7 * ( ~~~b ||| (a ^^^ c)) - 5 *  ~~~(a ^^^ ( ~~~b &&& c)) + 4 * (c &&& (a |||  ~~~b)) - 2 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) - 1 * (b ^^^ (a ||| (b &&& c))) - 3 *  ~~~( ~~~a &&& ( ~~~b &&& c)) - 7 * (a ^^^ c) - 5 * (c ^^^ (a ||| (b ||| c))) + 1 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) - 7 * (b ||| (a &&&  ~~~c)) + 14 *  ~~~(a ||| (b ||| c)) + 3 *  ~~~(a ||| ( ~~~b ||| c)) + 20 *  ~~~( ~~~a ||| (b ||| c)) + 17 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 4 * ( ~~~a &&& ( ~~~b &&& c)) + 28 * ( ~~~a &&& (b &&& c)) + 10 * (a &&& ( ~~~b &&& c)) - 7 * (a &&& (b &&& c)) =  - 2 * (a &&& (b ||| c)) - 1 * (b ^^^  ~~~(a &&& (b ^^^ c)))

theorem and_nosignbit_select_shl_proof : and_nosignbit_select_shl_before ⊑ and_nosignbit_select_shl_after

theorem test_and4_logical_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sge (LLVM.and e_1 (const? 32 2147483647)) e) (icmp IntPred.sge e (const? 32 0))
      (const? 1 0) ⊑
    icmp IntPred.ule e (LLVM.and e_1 (const? 32 2147483647))

theorem e_184 :
     - 11 *  ~~~y - 3 *  ~~~(x &&&  ~~~y) + 5 * (x |||  ~~~y) + 9 *  ~~~(x ||| y) + 6 * (x &&&  ~~~y) - 2 * (x &&& y) =  - 3 *  ~~~(x |||  ~~~y)

theorem ashr_mul_thm (e e_1 : IntW 8) :
  trunc 16 (ashr (mul (sext 20 e_1) (sext 20 e)) (const? 20 8)) ⊑
    ashr (mul (sext 16 e_1) (sext 16 e) { «nsw» := true, «nuw» := false }) (const? 16 8)

theorem main7g_proof : main7g_before ⊑ main7g_after

theorem and_orn_cmp_1_thm (e e_1 e_2 : IntW 32) :
  LLVM.and (icmp IntPred.sgt e_2 e_1)
      (LLVM.or (icmp IntPred.ugt e (const? 32 42)) (icmp IntPred.sle e_2 e_1)) ⊑
    LLVM.and (icmp IntPred.sgt e_2 e_1) (icmp IntPred.ugt e (const? 32 42))

theorem bv_AndOrXor_2265 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.or (LLVM.and e e_1) (LLVM.xor e e_1) ⊑ LLVM.or e e_1

theorem mul_unkV_evenC_ne_proof : mul_unkV_evenC_ne_before ⊑ mul_unkV_evenC_ne_after

theorem mul_select_zext_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  x_1 = 1#1 → x * zeroExtend 64 x_1 = x

theorem test15_proof : test15_before ⊑ test15_after

theorem and_zext_eq_odd_thm.extracted_1._1 : ∀ (x : BitVec 32),
  x &&& zeroExtend 32 (ofBool (x == 3#32)) = zeroExtend 32 (ofBool (x == 3#32))

theorem icmp_ne_zext_eq_non_boolean_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (zeroExtend 32 (ofBool (x == 2#32)) != x) = ofBool (x != 0#32)

theorem or_xor_tree_1110_thm (e e_1 e_2 : IntW 32) :
  LLVM.or (LLVM.xor (mul e_2 (const? 32 42)) (LLVM.xor (mul e_1 (const? 32 42)) (mul e (const? 32 42))))
      (LLVM.xor (mul e_2 (const? 32 42)) (mul e (const? 32 42))) ⊑
    LLVM.or (LLVM.xor (mul e_2 (const? 32 42)) (mul e (const? 32 42))) (mul e_1 (const? 32 42))

theorem scalar_i64_lshr_and_signbit_eq_proof : scalar_i64_lshr_and_signbit_eq_before ⊑ scalar_i64_lshr_and_signbit_eq_after

theorem trunc_sel_smaller_sext_proof : trunc_sel_smaller_sext_before ⊑ trunc_sel_smaller_sext_after

theorem sext_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → -1#41 = signExtend 41 x

theorem or_xor_xor_normal_binops_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  x_2 ^^^ x_1 ^^^ (x_2 ^^^ x_1) &&& (x ^^^ x_1) ||

theorem ashrsgt_03_12_proof : ashrsgt_03_12_before ⊑ ashrsgt_03_12_after

theorem lshrugt_01_07_exact_proof : lshrugt_01_07_exact_before ⊑ lshrugt_01_07_exact_after

theorem e_601 :
     - 1 *  ~~~(x ^^^ y) - 1 *  ~~~x + 4 * y + 5 * x - 5 * (x |||  ~~~y) - 11 *  ~~~(x &&&  ~~~x) + 25 *  ~~~(x ||| y) + 7 *  ~~~(x |||  ~~~y) + 17 * (x &&&  ~~~y) + 8 * (x &&& y) = 7 *  ~~~y - 1 * (x ^^^ y)

theorem scalar_i32_shl_and_signbit_eq_nonzero_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬x ≥ ↑32 → ofBool (x_1 <<< x &&& BitVec.ofInt 32 (-2147483648) == 1#32) = 0#1

theorem lshr_or_or_no_const_proof : lshr_or_or_no_const_before ⊑ lshr_or_or_no_const_after

theorem trunc_lshr_sext_narrow_input_thm.extracted_1._1 : ∀ (x : BitVec 8), ¬6#32 ≥ ↑32 → 6#8 ≥ ↑8 → False

theorem bv_AndOrXor_1288_A__B__B__C__A___A__B__C :
    ∀ (e e_1 e_2 : LLVM.IntW w),
      LLVM.and (LLVM.xor e e_2) (LLVM.xor (LLVM.xor e_2 e_1) e) ⊑
        LLVM.and (LLVM.xor e e_2) (LLVM.xor e_1 (LLVM.const? w (-1)))

theorem R.fromPoly_representatitive'_toFun (a : R q n) :
    (R.fromPoly (q := q) (n := n)).toFun (R.representative' q n a) = ↑a

theorem sub_select_sext_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → x - signExtend 64 x_1 = x

theorem substitute_constant_or_ne_uge_commute_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.uge e_1 e) (icmp IntPred.ne e_1 (const? 8 42)) ⊑
    LLVM.or (icmp IntPred.ne e_1 (const? 8 42)) (icmp IntPred.ult e (const? 8 43))

theorem lsb_mask_sign_sext_commuted_proof : lsb_mask_sign_sext_commuted_before ⊑ lsb_mask_sign_sext_commuted_after

theorem lshr_and_and_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(2#8 ≥ ↑8 ∨ (42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true ∨ 2#8 ≥ ↑8) →
    ¬((42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true ∨ 2#8 ≥ ↑8) →
      (x_1 >>> 2#8 &&& 13#8 &&& x.srem 42#8) <<< 2#8 = x_1 &&& 52#8 &&& x.srem 42#8 <<< 2#8

theorem scalar_i32_shl_and_signbit_eq_nonzero_proof : scalar_i32_shl_and_signbit_eq_nonzero_before ⊑ scalar_i32_shl_and_signbit_eq_nonzero_after

theorem AvoidCollision_signExtend_eq_not_setWidth_not_of_msb_true {x : BitVec w} {v : Nat} (hmsb : x.msb = true) :
    x.signExtend v = ~~~((~~~x).setWidth v)

theorem bar_proof : bar_before ⊑ bar_after

theorem sge_swap_or_max_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 ≤ₛ x) ||

theorem test_not_const_shr_and_1_ne_0_thm (e : IntW 32) :
  icmp IntPred.eq (LLVM.and (lshr (const? 32 42) e) (const? 32 1)) (const? 32 0) ⊑
    icmp IntPred.eq (LLVM.and (shl (const? 32 1) e { «nsw» := false, «nuw» := true }) (const? 32 42))
      (const? 32 0)

theorem ashrsgt_03_11_proof : ashrsgt_03_11_before ⊑ ashrsgt_03_11_after

theorem hoist_ashr_ahead_of_sext_2_proof : hoist_ashr_ahead_of_sext_2_before ⊑ hoist_ashr_ahead_of_sext_2_after

theorem demorgan_and_apint1_proof : demorgan_and_apint1_before ⊑ demorgan_and_apint1_after

theorem lshrugt_02_04_thm (e : IntW 4) : icmp IntPred.ugt (lshr e (const? 4 2)) (const? 4 4) ⊑ const? 1 0

theorem sub_ashr_or_i32_nuw_nsw_proof : sub_ashr_or_i32_nuw_nsw_before ⊑ sub_ashr_or_i32_nuw_nsw_after

theorem and_logic_and_logic_or_2_thm.extracted_1._9 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 &&& x_1 = 1#1 → ¬x = 1#1 → x_2 = 1#1 → ¬x_1 = 1#1 → 0#1 = x

theorem shl_nuw_add_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨ x ≥ ↑32) → True ∧ ((-1#32) <<< x).sshiftRight' x ≠ -1#32 ∨ x ≥ ↑32 → False

theorem shift_no_xor_multiuse_xor_proof : shift_no_xor_multiuse_xor_before ⊑ shift_no_xor_multiuse_xor_after

theorem positive_biggerlshr_lshrexact_proof : positive_biggerlshr_lshrexact_before ⊑ positive_biggerlshr_lshrexact_after

theorem add_five (x : BitVec w) : (x + x) + (x + x) + x = x + x + x + x + x

theorem e_2251 :
     - 2 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 11 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 5 * (f ^^^ (d ||| ( ~~~e ||| f))) + 2 * (e ^^^  ~~~(d &&&  ~~~f)) - 6 * ((d &&& e) ||| (e ^^^ f)) - 7 * ( ~~~f ||| (d ^^^ e)) + 5 * (f ^^^ (d &&& ( ~~~e ||| f))) + 1 * (e ^^^  ~~~(d &&& (e &&& f))) + 1 * (d ^^^ f) + 7 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 *  ~~~(e &&& f) + 1 *  ~~~(e &&&  ~~~f) - 1 * (f ^^^ (d &&&  ~~~e)) - 11 * (e ^^^ (d ||| (e &&& f))) - 2 * (e ^^^ (d ||| ( ~~~e ||| f))) - 1 * (e &&&  ~~~(d &&& f)) - 5 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 7 * (f ^^^ (d ||| e)) + 2 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 3 *  ~~~(e ||| f) + 5 * (e ^^^ (d &&&  ~~~f)) + 7 * (f ^^^  ~~~(d &&& (e ||| f))) - 6 * (e &&&  ~~~(d &&&  ~~~f)) - 6 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 5 * (f &&&  ~~~(d ^^^ e)) - 7 * ( ~~~d &&& (e ||| f)) - 5 * (e ||| (d &&&  ~~~f)) - 3 *  ~~~(d |||  ~~~e) + 5 *  ~~~(d &&& ( ~~~e ||| f)) + 5 * f - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 6 * (d ||| (e ^^^ f)) - 1 * (e ^^^  ~~~(d &&& (e ||| f))) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 *  ~~~( ~~~d &&& (e ||| f)) - 2 * ( ~~~e &&&  ~~~(d ^^^ f)) + 4 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 2 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * (e ^^^ (d &&& f)) - 1 * (f ^^^  ~~~(d ||| e)) + 1 * (d ^^^ ( ~~~e ||| f)) + 1 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 11 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 2 * (f &&& (d ||| e)) - 3 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 1 * (f &&& (d ^^^ e)) + 7 * (f ^^^ (d ||| (e &&& f))) + 11 * (e ^^^ (d ||| (e ^^^ f))) - 12 *  ~~~(d ||| (e ||| f)) + 26 *  ~~~(d ||| ( ~~~e ||| f)) - 10 *  ~~~( ~~~d ||| (e ||| f)) + 2 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 2 * ( ~~~d &&& ( ~~~e &&& f)) - 12 * ( ~~~d &&& (e &&& f)) - 16 * (d &&& ( ~~~e &&& f)) - 8 * (d &&& (e &&& f)) = 1 * d - 4 *  ~~~( ~~~d &&& (e ^^^ f))

theorem test_and_ne_a_b_commuted_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  ¬x_2 &&& ofBool (x_1 != x) = 1#1 → x_2 = 1#1 → x_1 = x

theorem bools2_logical_commute2_thm.extracted_1._8 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 → x = 1#1 → x_1 = 1#1 → 1#1 = x_1

@[simp]
theorem fst_nextBit_fsmCarry'_eq_atLeastTwo {state : Unit → Bool} {env : Bool → Bool} :
    ((fsmCarry' initCarry).nextBit state env).1 =
      fun () => Bool.atLeastTwo (env true) (env false) (state ())

theorem main7f_logical_thm.extracted_1._3 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 &&& x_1 == x &&& (x_2 &&& x_1)) = 1#1 →
    ¬ofBool (x_2 &&& x_1 != x &&& (x_2 &&& x_1)) = 1#1 → 0#1 = 1#1 → False

theorem select_icmp_eq_and_4096_0_xor_4096_proof : select_icmp_eq_and_4096_0_xor_4096_before ⊑ select_icmp_eq_and_4096_0_xor_4096_after

theorem rem_euclid_pow2_true_arm_folded_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(2#32 == 0 || 32 != 1 && x == intMin 32 && 2#32 == -1) = true →
    ¬ofBool (x.srem 2#32 <ₛ 0#32) = 1#1 → x.srem 2#32 = x &&& 1#32

theorem ashrsgt_03_08_exact_proof : ashrsgt_03_08_exact_before ⊑ ashrsgt_03_08_exact_after

@[grind =, simp]
lemma createSink_trans [LawfulBEq A] {m : RawCNFA A} (hwf : m.WF) :
    s₂ ∈ m.createSink.2.tr s₁ a ↔
      (s₁ = m.stateMax ∧ s₂ = m.stateMax) ∨
      (s₁ ∈ m.states ∧ s₂ ∈ m.states ∧ s₂ ∈ m.tr s₁ a)

@[simp] theorem dropUntilHom_toCons {v : Var Γ t} :
  dropUntilHom (v := v.toCons (t' := t')) = (dropUntilHom (v:=v)).consRight

theorem icmp_eq_mul_nuw_nonequal_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ x_1.umulOverflow x = true ∨ True ∧ (x_1 + 1#8).umulOverflow x = true) →
    ofBool (x_1 * x == (x_1 + 1#8) * x) = ofBool (x == 0#8)

theorem andn_or_cmp_1_proof : andn_or_cmp_1_before ⊑ andn_or_cmp_1_after

theorem icmp_sle5_thm (e : IntW 8) :
  icmp IntPred.sle (shl e (const? 8 1) { «nsw» := true, «nuw» := false }) (const? 8 1) ⊑
    icmp IntPred.slt e (const? 8 1)

theorem reassoc_mul_nuw_proof : reassoc_mul_nuw_before ⊑ reassoc_mul_nuw_after

theorem f_var1_commutative_and_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 &&& x == 0#32) = 1#1 → x &&& 1#32 = zeroExtend 32 (ofBool (x &&& (x_1 ||| 1#32) != 0#32))

theorem lshrugt_03_03_proof : lshrugt_03_03_before ⊑ lshrugt_03_03_after

theorem test_shl_nuw_nsw__all_are_safe_proof : test_shl_nuw_nsw__all_are_safe_before ⊑ test_shl_nuw_nsw__all_are_safe_after

theorem test_ult_nuw_proof : test_ult_nuw_before ⊑ test_ult_nuw_after

lemma RawCNFA.lift_wf (m : RawCNFA (BitVec n₁)) {f : Fin n₁ → Fin n₂} (hwf : m.WF) :
    m.lift f |>.WF

theorem positive_biggerlshr_shlnuwnsw_lshrexact_proof : positive_biggerlshr_shlnuwnsw_lshrexact_before ⊑ positive_biggerlshr_shlnuwnsw_lshrexact_after

theorem test9_thm (e : IntW 32) :
  mul (sext 64 (ashr e (const? 32 16))) (const? 64 (-32767)) ⊑
    sext 64 (mul (ashr e (const? 32 16)) (const? 32 (-32767)) { «nsw» := true, «nuw» := false })

theorem main7c_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 == x_1 &&& x) = 1#1 → ofBool (x_1 != x_1 &&& x) = 1#1 → ¬0#1 = 1#1 → 1#32 = zeroExtend 32 1#1

theorem test_mul_nuw_nsw__nuw_is_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 268435457)) (const? 32 268435456)) (const? 32 (-1879048192))
      (mul (LLVM.and e (const? 32 268435457)) (const? 32 9) { «nsw» := true, «nuw» := true }) ⊑
    mul (LLVM.and e (const? 32 268435457)) (const? 32 9) { «nsw» := false, «nuw» := true }

theorem lshr_not_nneg2_thm (e : IntW 8) :
  LLVM.xor (lshr (LLVM.xor e (const? 8 (-1))) (const? 8 1)) (const? 8 (-1)) ⊑
    LLVM.or (lshr e (const? 8 1)) (const? 8 (-128)) { «disjoint» := true }

theorem not_or_or_and_no_and_commute2_proof : not_or_or_and_no_and_commute2_before ⊑ not_or_or_and_no_and_commute2_after

omit [Fintype S] in
lemma processOneElem_spec {st : worklist.St A S} (s : State) (sa : S) (k : ℕ) :
    ∀ a sa', (f sa)[k]? = some (a, sa') →
    processOneElem_mot inits final f s sa k st →
    processOneElem_mot inits final f s sa (k+1) (processOneElem A S final s st (a, sa'))

theorem ashrslt_02_04_proof : ashrslt_02_04_before ⊑ ashrslt_02_04_after

theorem e_751 :
     - 7 * (z ||| t) + 2 *  ~~~z + 7 * z =  - 5 *  ~~~(z |||  ~~~t) + 2 *  ~~~(z ||| t)

theorem or_nontrivial_mask2_proof : or_nontrivial_mask2_before ⊑ or_nontrivial_mask2_after

theorem test5_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), (x_1 ^^^ -1#32 ||| x ^^^ -1#32) ^^^ -1#32 = x_1 &&& x

theorem and_shl_thm (e e_1 e_2 e_3 : IntW 8) :
  LLVM.and (shl e_3 e_2) (LLVM.and (shl e_1 e_2) e) ⊑ LLVM.and (shl (LLVM.and e_1 e_3) e_2) e

theorem udiv_shl_pair1_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ x_2 <<< x_1 >>> x_1 ≠ x_2 ∨ x_1 ≥ ↑32 ∨ True ∧ x_2 <<< x >>> x ≠ x_2 ∨ x ≥ ↑32 ∨ x_2 <<< x = 0) →
    True ∧ 1#32 <<< x_1 >>> x_1 ≠ 1#32 ∨ x_1 ≥ ↑32 ∨ x ≥ ↑32 → False

theorem sgt_or_not_min_proof : sgt_or_not_min_before ⊑ sgt_or_not_min_after

theorem main7e_logical_thm.extracted_1._15 : ∀ (x x_1 x_2 x_3 x_4 : BitVec 32),
  ¬ofBool (x_4 &&& x_3 &&& x_2 == x_4 &&& x_3) = 1#1 →
    ¬ofBool (x_4 &&& x_3 &&& x_2 != x_4 &&& x_3) = 1#1 →
      0#1 = 1#1 → 0#32 = zeroExtend 32 (ofBool (x_1 &&& x &&& x_2 != x_1 &&& x))

theorem invert_both_cmp_operands_sub_proof : invert_both_cmp_operands_sub_before ⊑ invert_both_cmp_operands_sub_after

theorem not_and_and_or_not_or_or_commute2_or_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  (x_2 ^^^ -1#32) &&& x_1 &&& x ||

theorem shl_nsw_add_proof : shl_nsw_add_before ⊑ shl_nsw_add_after

theorem and_signbit_select_ashr_proof : and_signbit_select_ashr_before ⊑ and_signbit_select_ashr_after

theorem icmp_eq_sext_ne_allones_proof : icmp_eq_sext_ne_allones_before ⊑ icmp_eq_sext_ne_allones_after

theorem trunc_shl_ashr_infloop_proof : trunc_shl_ashr_infloop_before ⊑ trunc_shl_ashr_infloop_after

theorem ne_umin3_proof : ne_umin3_before ⊑ ne_umin3_after

theorem t0_proof : t0_before ⊑ t0_after

theorem lshrugt_01_10_exact_thm (e : IntW 4) :
  icmp IntPred.ugt (lshr e (const? 4 1) { «exact» := true }) (const? 4 (-6)) ⊑ const? 1 0

theorem add_or_sub_comb_i128_commuted3_nuw_nsw_thm.extracted_1._1 : ∀ (x : BitVec 128),
  ¬(True ∧ (x * x ||| 0#128 - x * x).saddOverflow (x * x) = true ∨
        True ∧ (x * x ||| 0#128 - x * x).uaddOverflow (x * x) = true) →
    (x * x ||| 0#128 - x * x) + x * x = x * x

theorem icmp_ne_and_pow2_shl_pow2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → zeroExtend 32 (ofBool (2#32 <<< x &&& 16#32 != 0#32)) = zeroExtend 32 (ofBool (x == 3#32))

theorem and_or3_thm.extracted_1._6 : ∀ (x : BitVec 1) (x_1 x_2 : BitVec 32) (x_3 : BitVec 1),
  ¬x_3 &&& ofBool (x_2 == x_1) = 1#1 → x_3 = 1#1 → ofBool (x_2 != x_1) = 1#1 → x_3 = 1#1

theorem alive_229 : alive_229_src ⊑ alive_229_tgt

theorem bad_add0_proof : bad_add0_before ⊑ bad_add0_after

theorem select_replace_udiv_non_speculatable_thm (e e_1 : IntW 32) : select (icmp IntPred.eq e_1 (const? 32 0)) (LLVM.udiv e e_1) e ⊑ e

theorem bswap_and_mask_1_proof : bswap_and_mask_1_before ⊑ bswap_and_mask_1_after

theorem both_sides_fold_slt_thm (e : IntW 32) (e_1 : IntW 1) :
  icmp IntPred.slt (select e_1 (const? 32 9) e) (select e_1 (const? 32 1) e) ⊑ const? 1 0

theorem main4_thm (e : IntW 32) :
  select
      (LLVM.and (icmp IntPred.eq (LLVM.and e (const? 32 7)) (const? 32 7))
        (icmp IntPred.eq (LLVM.and e (const? 32 48)) (const? 32 48)))
      (const? 32 0) (const? 32 1) ⊑
    zext 32 (icmp IntPred.ne (LLVM.and e (const? 32 55)) (const? 32 55))

theorem zext_sext_add_icmp_slt_0_proof : zext_sext_add_icmp_slt_0_before ⊑ zext_sext_add_icmp_slt_0_after

theorem e_68 :
    5 *  ~~~(x &&&  ~~~y) - 2 * (x ^^^ y) - 5 *  ~~~(x ||| y) + 3 *  ~~~(x |||  ~~~y) + 8 * (x &&&  ~~~y) = 6 * (x ||| y) - 1 * (x &&& y)

theorem icmp_ult_x_y_2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 * x_1 &&& x <ᵤ x_1 * x_1) = ofBool (x_1 * x_1 &&& x != x_1 * x_1)

theorem sgt_or_not_min_commute_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 != BitVec.ofInt 8 (-128)) = 1#1 → 1#1 = ofBool (x_1 != BitVec.ofInt 8 (-128))

theorem e_2474 :
     - 2 *  ~~~(d ^^^ (e &&& f)) + 5 * (e ^^^  ~~~(d &&& (e &&& f))) + 3 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) - 5 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 1 * (f ^^^ ( ~~~d ||| (e &&& f))) + 4 * ((d |||  ~~~e) &&& (e ^^^ f)) - 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 6 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * ((d &&& e) |||  ~~~(e ^^^ f)) - 7 * (e &&& (d ||| f)) - 2 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 1 * (d ||| (e ^^^ f)) - 5 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 2 * (e ||| (d &&&  ~~~f)) + 1 * (d ^^^ (e ||| f)) - 7 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 5 * (f ^^^  ~~~(d ||| e)) + 2 * (f ^^^  ~~~(d |||  ~~~e)) + 3 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 5 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) - 2 * (f ^^^ (d ||| (e &&& f))) - 1 * ( ~~~d ||| ( ~~~e ||| f)) - 5 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 1 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 7 * (d &&& (e ^^^ f)) - 6 * (e |||  ~~~f) + 4 * d + 2 * (e ^^^ (d ||| f)) - 2 * (f ^^^ (d ||| (e ||| f))) + 1 * ( ~~~d &&& (e ^^^ f)) - 3 * (d &&& (e ||| f)) + 1 * (d ||| e) + 3 * (d ^^^ e) - 1 * (e &&& (d ^^^ f)) - 5 * ( ~~~e &&& (d ^^^ f)) + 1 * (e ^^^ (d &&&  ~~~f)) - 2 * ((d &&& e) ^^^ (e |||  ~~~f)) + 2 *  ~~~(d ^^^ ( ~~~e &&& f)) + 2 * (e ^^^ (d ||| (e &&& f))) + 2 * (f ^^^ (d &&& ( ~~~e ||| f))) + 2 *  ~~~(d ^^^ (e ^^^ f)) - 5 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 2 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 11 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 3 * (e ^^^ (d &&& ( ~~~e ||| f))) - 7 * (d ^^^ ( ~~~e &&& f)) + 5 *  ~~~(d ||| (e &&& f)) + 3 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 7 *  ~~~( ~~~d &&& (e ||| f)) + 4 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) - 1 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 4 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 7 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 6 * (f ||| (d &&& e)) + 11 * ( ~~~f &&& (d ^^^ e)) + 3 * ( ~~~e |||  ~~~(d ^^^ f)) + 1 * ((d &&& e) |||  ~~~(e ||| f)) + 5 * (e |||  ~~~(d |||  ~~~f)) + 2 *  ~~~(e ^^^ f) + 11 * ( ~~~d ||| ( ~~~e &&& f)) - 11 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 2 *  ~~~(d ||| (e ^^^ f)) - 11 * (d ||| (e ||| f)) + 11 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 * ((d ^^^ e) ||| (d ^^^ f)) + 1 * ( ~~~f &&&  ~~~(d ^^^ e)) - 11 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 2 * (f ^^^  ~~~(d &&& (e &&& f))) + 2 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 11 * (e ^^^ (d ||| (e ||| f))) - 3 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 2 *  ~~~(d ^^^ ( ~~~e ||| f)) + 3 *  ~~~(d ||| ( ~~~e ||| f)) + 17 *  ~~~( ~~~d ||| (e ||| f)) + 52 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 10 * ( ~~~d &&& ( ~~~e &&& f)) + 50 * ( ~~~d &&& (e &&& f)) - 20 * (d &&& ( ~~~e &&& f)) + 40 * (d &&& (e &&& f)) =  - 1 * (f ^^^ (d &&& e)) + 1 * (d ||| ( ~~~e &&& f))

theorem fold_sext_to_and_wrong6_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x &&& BitVec.ofInt 32 (-2147483647) != -1#32) = 1#1

theorem test15a_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (x &&& 16#32 == 0#32) = 1#1 → 0#32 = x &&& 16#32

theorem icmp_shl_eq_1_proof : icmp_shl_eq_1_before ⊑ icmp_shl_eq_1_after

theorem ashrslt_02_10_proof : ashrslt_02_10_before ⊑ ashrslt_02_10_after
</all_available_lemmas>

<local_ctx>
import Mathlib.Data.Fintype.Prod

import Blase.AutoStructs.Worklist

import Mathlib.Tactic.ApplyFun

open SetRel

section sink

variable {A : Type} [BEq A] [Hashable A] [DecidableEq A] [FinEnum A]

end sink

section generic_prod

variable {α} [BEq α] [Hashable α] [LawfulBEq α]

variable {β} [BEq β] [Hashable β] [LawfulBEq β]

variable {S₁ : Finset α} {S₂ : Finset β}

variable {γ} (f : S₁ → S₂ → γ) (hinj : Function.Injective2 f)

variable {m₁ : Std.HashSet α} (hm₁ : ∀ s₁ ∈ m₁, s₁ ∈ S₁)

variable {m₂ : Std.HashSet β} (hm₂ : ∀ s₂ ∈ m₂, s₂ ∈ S₂)

end generic_prod

section product

variable {A : Type} [BEq A] [LawfulBEq A] [Hashable A] [DecidableEq A] [FinEnum A]

end product

section determinization

variable {A : Type} [BEq A] [LawfulBEq A] [Hashable A] [DecidableEq A] [FinEnum A]

def RawCNFA.reverse (m : RawCNFA A) : RawCNFA A :=
  let m' := { stateMax := m.stateMax, trans := Std.HashMap.emptyWithCapacity m.trans.size, initials := m.finals, finals := m.initials}
  m.trans.fold (init := m') processState
where
  processState := fun m' (s, a) ss' =>
    ss'.fold (init := m') fun m' s' => m'.addTrans a s' s
</local_ctx>

<target_theorem>
lemma RawCNFA.reverse_spec {m : RawCNFA A} (hwf : m.WF) :
    let m' :=
</target_theorem>

