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>
Inhabited in Init.Prelude
Lean.ToExpr in Lean.ToExpr
Nat in Init.Prelude
Repr in Init.Data.Repr
Bool in Init.Prelude
Int.xor in Mathlib.Data.Int.Bitwise
BitVec in Init.Prelude
BitVec.adcb in Init.Data.BitVec.Bitblast
Prod in Init.Prelude
Fin in Init.Prelude
Fin.last in Init.Data.Fin.Basic
Fin.mk in Init.Prelude
List in Init.Prelude
List.Vector in Mathlib.Data.Vector.Defs
BitVec.ofNat in Init.Prelude
BitVec.zero in Init.Data.BitVec.Basic
Fin.castLE in Init.Data.Fin.Basic
Set in Mathlib.Data.Set.Defs
Fin.cast in Init.Data.Fin.Basic
Fin.castLT in Init.Data.Fin.Basic
Fin.subNat in Init.Data.Fin.Basic
List.Vector.get in Mathlib.Data.Vector.Defs
List.Vector.nil in Mathlib.Data.Vector.Defs

syntax "xor" : MLIR.Pretty.uniform_op

syntax "max" : MLIR.Pretty.uniform_op

macro_rules
  | `(mlir_op| $res:mlir_op_operand = const ($x)
      $[: $outer_type]? ) => do
      let outer_type ← outer_type.getDM `(mlir_type| _)
      `(mlir_op| $res:mlir_op_operand = "const"()
          {val = $x:num : $outer_type} : ($outer_type) -> ($outer_type) )

macro_rules
  | `(mlir_op| $res:mlir_op_operand = li ($x)
     $[: $outer_type]?  ) => do
      let outer_type ← outer_type.getDM `(mlir_type| _ )
      `(mlir_op| $res:mlir_op_operand = "li"()
          {imm = $x:num : $outer_type } : ($outer_type) -> ($outer_type))

macro_rules
| `(mlir_op| $res:mlir_op_operand = $op1:MLIR.Pretty.RV.opWithImmediate $reg1 , $x : $t)  => do
    let some opName := MLIR.EDSL.Pretty.extractOpName op1.raw
      | Macro.throwUnsupported
    `(mlir_op| $res:mlir_op_operand = $opName ($reg1) {imm = $x:num : $t} : ($t) -> ($t) )

macro_rules
| `(mlir_op| $res:mlir_op_operand = $op1:MLIR.Pretty.RV.opWithShamt $reg1 , $x  : $t )  => do
    let some opName := MLIR.EDSL.Pretty.extractOpName op1.raw
      | Macro.throwUnsupported
    `(mlir_op| $res:mlir_op_operand = $opName ($reg1) {shamt = $x:num : $t}  : ($t) -> ($t) )

inductive Term : Type
| var : Nat → Term
 
| zero : Term
 
| negOne : Term
 
| one : Term
 
| ofNat (n : Nat) : Term
 
| and : Term → Term → Term
 
| or : Term → Term → Term
 
| xor : Term → Term → Term
 
| not : Term → Term
 
| add : Term → Term → Term
 
| sub : Term → Term → Term
 
| neg : Term → Term

| shiftL : Term → Nat → Term

deriving Repr, Inhabited, Lean.ToExpr

def neg (x : BitStream) : BitStream :=
  fun n => (negAux x n).1

def negAux (x : BitStream) : Nat → Bool × Bool
  | 0 => (x 0, !(x 0))
  | n+1 =>
    let borrow := (negAux x n).2
    let a := x (n + 1)
    (xor (!a) borrow, !a && borrow)

def BitStream : Type := Nat → Bool

def sub (x y : BitStream) : BitStream :=
  fun n => (subAux x y n).1

def subAux (x y : BitStream) : Nat → Bool × Bool
  | 0 => (xor (x 0) (y 0), !(x 0) && y 0)
  | n+1 =>
    let borrow := (subAux x y n).2
    let a := x (n + 1)
    let b := y (n + 1)
    (xor a (xor b borrow), !a && b || ((!(xor a b)) && borrow))

def add (x y : BitStream) : BitStream :=
  fun n => (addAux x y n).1

def addAux (x y : BitStream) (i : Nat) :  Bool × Bool :=
  let carryIn : Bool := match i with
    | 0 => false
    | i + 1 => (addAux x y i).2
  Prod.swap (BitVec.adcb (x i) (y i) carryIn)

structure BitVecs (n : Nat) where
  w : Nat
  bvs : List.Vector (BitVec w) n

def liftMaxSuccSucc2 (n m : Nat) : Fin (m + 1) → Fin (max n m + 3) :=
  fun k => if _ : k = Fin.last m then max n m + 1 else k.castLE (by admit /- proof elided -/
  )

def liftMaxSuccSucc1 (n m : Nat) : Fin (n + 1) → Fin (max n m + 3) :=
  fun k => if _ : k = Fin.last n then (max n m).cast else k.castLE (by admit /- proof elided -/
  )

def liftLast3 n : Fin 3 → Fin (n + 3)
| 0 => n
| 1 => n + 1
| 2 => Fin.last (n + 2)

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

def Valuation.cons {Γ : Ctxt Ty} {t : Ty} (x : toType t) (V : Γ.Valuation) :
    (Γ.cons t).Valuation :=

def Term.language (t : Term) : Set (BitVecs (t.arity + 1)) :=
  { bvs : BitVecs (t.arity + 1) | t.evalFinBV (fun n => bvs.bvs.get n) = bvs.bvs.get t.arity }

@[simp]
def Formula.arity : Formula → Nat
| width _ _ => 0
| atom _ t1 t2 => max t1.arity t2.arity
| msbSet t => t.arity
| unop _ φ => φ.arity
| binop _ φ1 φ2 => max φ1.arity φ2.arity

@[simp] def Term.evalFinBV (t : Term) (vars : Fin (arity t) → BitVec w) : BitVec w :=
  match t with
  | .var n => vars (Fin.last n)
  | .zero    => BitVec.zero w
  | .one     => 1
  | .negOne  => -1
  | .ofNat n => BitVec.ofNat _ n
  | .and t₁ t₂ =>
      let x₁ := t₁.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      let x₂ := t₂.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      x₁ &&& x₂
  | .or t₁ t₂ =>
      let x₁ := t₁.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      let x₂ := t₂.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      x₁ ||| x₂
  | .xor t₁ t₂ =>
      let x₁ := t₁.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      let x₂ := t₂.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      x₁ ^^^ x₂
  | .not t     => ~~~(t.evalFinBV vars)
  
  | .add t₁ t₂ =>
      let x₁ := t₁.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      let x₂ := t₂.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      x₁ + x₂
  | .sub t₁ t₂ =>
      let x₁ := t₁.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      let x₂ := t₂.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      x₁ - x₂
  | .neg t       => -(t.evalFinBV vars)
  | .shiftL a n => (a.evalFinBV vars) <<< n

@[simp] def Term.arity : Term → Nat
| (var n) => n+1
| zero => 0
| one => 0
| negOne => 0
| ofNat _ => 0
| Term.and t₁ t₂ => max (arity t₁) (arity t₂)
| Term.or t₁ t₂ => max (arity t₁) (arity t₂)
| Term.xor t₁ t₂ => max (arity t₁) (arity t₂)
| Term.not t => arity t
| add t₁ t₂ => max (arity t₁) (arity t₂)
| sub t₁ t₂ => max (arity t₁) (arity t₂)
| neg t => arity t

| shiftL t .. => arity t

infixr:67 "::ᵥ" => Valuation.cons

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 and_not_xor_common_op_after := [llvm|
{
^0(%arg681 : i32, %arg682 : i32):
  %0 = llvm.and %arg681, %arg682 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

@[simp_denote]
def sltu_riscv :=
  [LV| {
    ^entry (%arg0: i16, %arg1: i16):
    %a0 = "builtin.unrealized_conversion_cast" (%arg0) : (i16) -> (!i64)
    %a1 = "builtin.unrealized_conversion_cast" (%arg1) : (i16) -> (!i64)
    %0 = li (149595403036) : !i64 
    %1 = "lui" (%0) {imm = 16 : !i64} : (!i64) -> (!i64)
    %2 = "addi" (%1) {imm = -1 : !i64} : (!i64) -> (!i64)
    %3 = and %2, %a1 : !i64
    %4 = and %2, %a0 : !i64
    %5 = sltu %4, %3 : !i64
    %6 = "builtin.unrealized_conversion_cast" (%5) : (!i64) -> (i16)
    llvm.return %6 :i16
  }]

def src_before := [llvm|
{
^0(%arg0 : i1):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.zext %arg0 : i1 to i32
  %2 = llvm.shl %0, %1 : i32
  %3 = llvm.xor %2, %0 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.shl %4, %1 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def select_icmp_ne_0_and_4096_or_32_after := [llvm|
{
^0(%arg209 : i32, %arg210 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(32 : i32) : i32
  %2 = llvm.lshr %arg209, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.or %arg210, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def test7_before := [llvm|
{
^0(%arg0 : i47):
  %0 = llvm.mlir.constant(70368744177663 : i47) : i47
  %1 = llvm.mlir.constant(703687463 : i47) : i47
  %2 = llvm.or %arg0, %0 : i47
  %3 = llvm.xor %2, %1 : i47
  "llvm.return"(%3) : (i47) -> ()
}
]

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

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

def test_cast_select_before := [llvm|
{
^0(%arg12 : i1):
  %0 = llvm.mlir.constant(3 : i16) : i16
  %1 = llvm.mlir.constant(5 : i16) : i16
  %2 = "llvm.select"(%arg12, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i16, i16) -> i16
  %3 = llvm.zext %2 : i16 to i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def C0zero_before := [llvm|
{
^0(%arg8 : i8, %arg9 : i8, %arg10 : i8):
  %0 = llvm.mlir.constant(10 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.mlir.constant(-10 : i8) : i8
  %3 = llvm.add %arg8, %0 : i8
  %4 = llvm.icmp "ult" %3, %1 : i8
  %5 = llvm.icmp "slt" %arg8, %2 : i8
  %6 = "llvm.select"(%5, %arg9, %arg10) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %7 = "llvm.select"(%4, %arg8, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%7) : (i8) -> ()
}
]

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

Nat.reduceAdd in Lean.Meta.Tactic.Simp.BuiltinSimprocs.Nat

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

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

def main7a_logical_after := [llvm|
{
^0(%arg81 : i32, %arg82 : i32, %arg83 : i32):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.and %arg82, %arg81 : i32
  %2 = llvm.icmp "ne" %1, %arg82 : i32
  %3 = llvm.and %arg83, %arg81 : i32
  %4 = llvm.icmp "ne" %3, %arg83 : i32
  %5 = "llvm.select"(%2, %0, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %6 = llvm.zext %5 : i1 to i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

def ult_to_slt_after := [llvm|
{
^0(%arg32 : i8, %arg33 : i8):
  %0 = llvm.icmp "slt" %arg32, %arg33 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

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 positive_biggershl_shlnsw_ashrexact_before := [llvm|
{
^0(%arg34 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(6 : i8) : i8
  %2 = llvm.ashr exact %arg34, %0 : i8
  %3 = llvm.shl %2, %1 overflow<nsw> : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

@[simp_denote]
def sext_riscv_i16_to_32 := [LV| {
  ^entry (%arg: i16):
    %0 = "builtin.unrealized_conversion_cast"(%arg) : (i16) -> (!i64)
    %1 = sext.h %0 : !i64
    %res = "builtin.unrealized_conversion_cast"(%1) : (!i64) -> (i32)
    llvm.return %res : i32
  }]

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

def different_size_sext_sext_ule_before := [llvm|
{
^0(%arg8 : i7, %arg9 : i4):
  %0 = llvm.sext %arg8 : i7 to i25
  %1 = llvm.sext %arg9 : i4 to i25
  %2 = llvm.icmp "ule" %0, %1 : i25
  "llvm.return"(%2) : (i1) -> ()
}
]

def bools2_logical_commute0_and1_and2_before := [llvm|
{
^0(%arg55 : i1, %arg56 : i1, %arg57 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg57, %0 : i1
  %2 = llvm.and %arg57, %arg55 : i1
  %3 = llvm.and %1, %arg56 : i1
  %4 = "llvm.select"(%2, %0, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def trunc {w: Nat} (w': Nat) (x: IntW w) (noWrapFlags : NoWrapFlags := {nsw := false , nuw := false}) : IntW w' := do
  let x' <- x
  if noWrapFlags.nsw ∧ ((x'.truncate w').signExtend w ≠ x') then
    .poison
  else if noWrapFlags.nuw ∧ ((x'.truncate w').zeroExtend w ≠ x') then
    .poison
  else
    trunc? w' x'

def is_rem32_pos_i8_after := [llvm|
{
^0(%arg55 : i8):
  %0 = llvm.mlir.constant(-97 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.and %arg55, %0 : i8
  %3 = llvm.icmp "sgt" %2, %1 : i8
  "llvm.return"(%3) : (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) -> ()
}
]

def icmp_ne_sext_slt_allones_nofold_before := [llvm|
{
^0(%arg4 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.icmp "slt" %arg4, %0 : i32
  %2 = llvm.sext %1 : i1 to i32
  %3 = llvm.icmp "ne" %2, %arg4 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def PR2330_after := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "ne" %arg0, %0 : i32
  "llvm.return"(%1) : (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 sdiv_shl_pair3_before := [llvm|
{
^0(%arg37 : i32, %arg38 : i32, %arg39 : i32):
  %0 = llvm.shl %arg37, %arg38 overflow<nsw> : i32
  %1 = llvm.shl %arg37, %arg39 overflow<nsw> : i32
  %2 = llvm.sdiv %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

private def pretty_test_icmp :=
  [llvm()|{
  ^bb0(%arg0: i1):
    %1 = llvm.icmp "eq" %arg0, %arg0 : i1
    llvm.return %1 : i1
  }]

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

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

def test_before := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(12 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %arg0, %0 : i32
  %3 = llvm.lshr %2, %0 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  "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 ashrsgt_02_06_exact_before := [llvm|
{
^0(%arg79 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.mlir.constant(6 : i4) : i4
  %2 = llvm.ashr exact %arg79, %0 : i4
  %3 = llvm.icmp "sgt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def bv3 : BitVec 4 := BitVec.ofNat 4 2 

def xor_or_xor_common_op_commute1_after := [llvm|
{
^0(%arg80 : i32, %arg81 : i32, %arg82 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg80, %0 : i32
  %2 = llvm.and %arg81, %1 : i32
  %3 = llvm.xor %2, %arg82 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

instance : AST.TransformReturn LLVM 0 := { mkReturn }

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

def n0_before := [llvm|
{
^0(%arg4 : i8, %arg5 : i8, %arg6 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.shl %0, %arg5 : i8
  %2 = llvm.xor %1, %0 : i8
  %3 = llvm.and %2, %arg4 : i8
  %4 = llvm.icmp "ne" %3, %arg6 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

def t0_before := [llvm|
{
^0(%arg23 : i32, %arg24 : i16):
  %0 = llvm.mlir.constant(32 : i16) : i16
  %1 = llvm.mlir.constant(-24 : i16) : i16
  %2 = llvm.sub %0, %arg24 : i16
  %3 = llvm.zext %2 : i16 to i32
  %4 = llvm.shl %arg23, %3 : i32
  %5 = llvm.trunc %4 : i32 to i16
  %6 = llvm.add %arg24, %1 : i16
  %7 = llvm.shl %5, %6 : i16
  "llvm.return"(%7) : (i16) -> ()
}
]

def test3_after := [llvm|
{
^0(%arg195 : i64):
  %0 = llvm.mlir.constant(255) : i64
  %1 = llvm.and %arg195, %0 : i64
  "llvm.return"(%1) : (i64) -> ()
}
]

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

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 wrongimm2_before := [llvm|
{
^0(%arg4 : i16):
  %0 = llvm.mlir.constant(8 : i16) : i16
  %1 = llvm.mlir.constant(6 : i8) : i8
  %2 = llvm.lshr %arg4, %0 : i16
  %3 = llvm.trunc %2 : i16 to i8
  %4 = llvm.trunc %arg4 : i16 to i8
  %5 = llvm.ashr %4, %1 : i8
  %6 = llvm.icmp "eq" %5, %3 : i8
  "llvm.return"(%6) : (i1) -> ()
}
]

def srl_i32_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := srl_llvm_i32
  rhs := srl_riscv_i32

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

def bitwise_and_bitwise_and_icmps_comm1_after := [llvm|
{
^0(%arg241 : i8, %arg242 : i8, %arg243 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.icmp "eq" %arg242, %0 : i8
  %3 = llvm.shl %1, %arg243 overflow<nuw> : i8
  %4 = llvm.or %3, %1 : i8
  %5 = llvm.and %arg241, %4 : i8
  %6 = llvm.icmp "eq" %5, %4 : i8
  %7 = llvm.and %2, %6 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

def neg_of_add_with_constant_after := [llvm|
{
^0(%arg171 : i8):
  %0 = llvm.mlir.constant(-42 : i8) : i8
  %1 = llvm.sub %0, %arg171 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def test12_before := [llvm|
{
^0(%arg76 : i32, %arg77 : i32):
  %0 = llvm.mlir.constant(31 : i128) : i128
  %1 = llvm.zext %arg76 : i32 to i128
  %2 = llvm.zext %arg77 : i32 to i128
  %3 = llvm.and %2, %0 : i128
  %4 = llvm.lshr %1, %3 : i128
  %5 = llvm.trunc %4 : i128 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

@[simp_llvm]
def not? {w : Nat} (x : BitVec w) : IntW w := do
  .value (~~~x)

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

def ult_swap_and_not_max_logical_after := [llvm|
{
^0(%arg100 : i8, %arg101 : i8):
  %0 = llvm.icmp "ugt" %arg101, %arg100 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

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

def sext_sub_const_after := [llvm|
{
^0(%arg25 : i1):
  %0 = llvm.mlir.constant(43) : i64
  %1 = llvm.mlir.constant(42) : i64
  %2 = "llvm.select"(%arg25, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%2) : (i64) -> ()
}
]

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

def scalar_i32_shl_and_signbit_slt_after := [llvm|
{
^0(%arg2 : i32, %arg3 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.shl %arg2, %arg3 : i32
  %2 = llvm.icmp "slt" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def sext_xor_sub_3_before := [llvm|
{
^0(%arg22 : i64, %arg23 : i1):
  %0 = llvm.sext %arg23 : i1 to i64
  %1 = llvm.xor %0, %arg22 : i64
  %2 = llvm.sub %0, %1 : i64
  "llvm.return"(%2) : (i64) -> ()
}
]

Lean.Elab.Term.TermElabM in Lean.Elab.Term.TermElabM

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

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

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

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) -> ()
}
]

instance {d : Dialect} [TyDenote d.Ty] [DialectSignature d] [DialectDenote d] :
    Coe d.Op (Scf d).Op where
  coe o := .coe o

def t1_flags_nuw_nsw_first_before := [llvm|
{
^0(%arg33 : i8, %arg34 : i8, %arg35 : i8):
  %0 = llvm.sub %arg33, %arg34 overflow<nsw,nuw> : i8
  %1 = llvm.sub %0, %arg35 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def cmpeq_xor_cst1_after := [llvm|
{
^0(%arg26 : i32, %arg27 : i32):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.xor %arg26, %arg27 : i32
  %2 = llvm.icmp "eq" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def addi_i32_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := addi_llvm_i32
  rhs := addi_riscv_i32

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

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

def narrow_sext_xor_after := [llvm|
{
^0(%arg48 : i16, %arg49 : i32):
  %0 = llvm.trunc %arg49 : i32 to i16
  %1 = llvm.xor %arg48, %0 : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

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

def select_sub_icmp_bad_before := [llvm|
{
^0(%arg71 : i32, %arg72 : i32, %arg73 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "eq" %arg71, %0 : i32
  %2 = llvm.sub %arg71, %arg73 : i32
  %3 = "llvm.select"(%1, %2, %arg72) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def or_eq_with_one_bit_diff_constants2_before := [llvm|
{
^0(%arg362 : i32):
  %0 = llvm.mlir.constant(97 : i32) : i32
  %1 = llvm.mlir.constant(65 : i32) : i32
  %2 = llvm.icmp "eq" %arg362, %0 : i32
  %3 = llvm.icmp "eq" %arg362, %1 : i32
  %4 = llvm.or %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

noncomputable def R.fromTensor {q n} (coeffs : List Int) : R q n :=
  coeffs.zipIdx.foldl (init := 0) fun res (c, i) =>
    res + R.monomial ↑c i

def test36_before := [llvm|
{
^0(%arg158 : i32):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.lshr %arg158, %0 : i32
  %3 = llvm.trunc %2 : i32 to i8
  %4 = llvm.icmp "eq" %3, %1 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

def exact_lshr_ne_before := [llvm|
{
^0(%arg157 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.lshr exact %0, %arg157 : i8
  %3 = llvm.icmp "ne" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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 lshrult_01_07_exact_after := [llvm|
{
^0(%arg142 : i4):
  %0 = llvm.mlir.constant(-2 : i4) : i4
  %1 = llvm.icmp "ne" %arg142, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

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 shl_lshr_eq_amt_multi_use_before := [llvm|
{
^0(%arg7 : i44):
  %0 = llvm.mlir.constant(33 : i44) : i44
  %1 = llvm.shl %arg7, %0 : i44
  %2 = llvm.lshr %1, %0 : i44
  %3 = llvm.add %1, %2 : i44
  "llvm.return"(%3) : (i44) -> ()
}
]

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 ashrslt_03_13_after := [llvm|
{
^0(%arg224 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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 test28_sub_after := [llvm|
{
^0(%arg175 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.sub %0, %arg175 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def flip_masked_bit_before := [llvm|
{
^0(%arg132 : i8):
  %0 = llvm.mlir.constant(16 : i8) : i8
  %1 = llvm.add %arg132, %0 : i8
  %2 = llvm.and %1, %0 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

Std.Tactic.BVDecide.BVBinOp.xor in Std.Tactic.BVDecide.Bitblast.BVExpr.Basic

def add_nosignbit_select_shl_before := [llvm|
{
^0(%arg32 : i32, %arg33 : i1):
  %0 = llvm.mlir.constant(2147418112 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.add %arg32, %0 : i32
  %3 = "llvm.select"(%arg33, %2, %arg32) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.shl %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def test4_logical_after := [llvm|
{
^0(%arg304 : i1):
  "llvm.return"(%arg304) : (i1) -> ()
}
]

Fin.clamp in Batteries.Data.Fin.Basic

def not_lshr_after := [llvm|
{
^0(%arg82 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(5 : i8) : i8
  %2 = llvm.xor %arg82, %0 : i8
  %3 = llvm.lshr %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def n3_constmask_samemask_after := [llvm|
{
^0(%arg0 : i32, %arg1 : i32):
  %0 = llvm.mlir.constant(65280 : i32) : i32
  %1 = llvm.and %arg0, %0 : i32
  %2 = llvm.and %arg1, %0 : i32
  %3 = llvm.add %1, %2 overflow<nsw,nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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 slt_zero_sgt_minus1_after := [llvm|
{
^0(%arg22 : i4, %arg23 : i4):
  %0 = llvm.mlir.constant(-1 : i4) : i4
  %1 = llvm.xor %arg22, %arg23 : i4
  %2 = llvm.icmp "sgt" %1, %0 : i4
  "llvm.return"(%2) : (i1) -> ()
}
]

@[simps]
instance finenum_fin : FinEnum (Fin n) where
  card := n
  equiv := by admit /- proof elided -/

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

def zext_sext_add_icmp_sgt_minus2_after := [llvm|
{
^0(%arg90 : i1, %arg91 : i1):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def ule_or_not_min_before := [llvm|
{
^0(%arg272 : i427, %arg273 : i427):
  %0 = llvm.mlir.constant(0 : i427) : i427
  %1 = llvm.icmp "ule" %arg272, %arg273 : i427
  %2 = llvm.icmp "ne" %arg272, %0 : i427
  %3 = llvm.or %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def positive_samevar_shlnsw_lshrexact_after := [llvm|
{
^0(%arg37 : i8, %arg38 : i8):
  "llvm.return"(%arg37) : (i8) -> ()
}
]

def runNNFSimpSet (g : MVarId) : MetaM (Option MVarId) := do
  let some ext ← (getSimpExtension? `bv_automata_nnf)
    | throwError m!"[bv_nnf] Error: 'bv_automata_nnf' simp attribute not found!"
  let theorems ← ext.getTheorems
  let some ext ← (Simp.getSimprocExtension? `bv_automata_nnf)
    | throwError m!"[bv_nnf] Error: 'bv_automata_nnf' simp attribute not found!"
  let simprocs ← ext.getSimprocs
  let config : Simp.Config := { Simp.neutralConfig with
    failIfUnchanged   := false,
  }
  let ctx ← Simp.mkContext (config := config)
    (simpTheorems := #[theorems])
    (congrTheorems := ← Meta.getSimpCongrTheorems)
  match ← simpGoal g ctx (simprocs := #[simprocs]) with
  | (none, _) => return none
  | (some (_newHyps, g'), _) => pure g'

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

def mul8_low_miss_half_width_before := [llvm|
{
^0(%arg2 : i8, %arg3 : i8):
  %0 = llvm.mlir.constant(15 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.and %arg2, %0 : i8
  %3 = llvm.lshr %arg2, %1 : i8
  %4 = llvm.and %arg3, %0 : i8
  %5 = llvm.lshr %arg3, %1 : i8
  %6 = llvm.mul %5, %2 : i8
  %7 = llvm.mul %4, %3 : i8
  %8 = llvm.mul %4, %2 : i8
  %9 = llvm.add %6, %7 : i8
  %10 = llvm.shl %9, %1 : i8
  %11 = llvm.add %10, %8 : i8
  "llvm.return"(%11) : (i8) -> ()
}
]

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

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

@[match_pattern] abbrev binary (w : Nat) (op : MOp.BinaryOp) : LLVM.Op :=
  MOp.binary (.concrete w) op

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

def Factor.numVars : Factor → Nat
| .var n => n+1
| .and x y | .or x y | xor x y => max (x.numVars) (y.numVars)
| .not x => x.numVars

def ule_swap_or_not_min_commute_before := [llvm|
{
^0(%arg260 : i8, %arg261 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "uge" %arg261, %arg260 : i8
  %2 = llvm.icmp "ne" %arg260, %0 : i8
  %3 = llvm.or %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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) -> ()
}
]

@[simp]
def foldl {α β : Type u} {n : Nat} (f : β → α → β) (acc : β) : LengthIndexedList α n → β
  | nil => acc
  | cons x xs => LengthIndexedList.foldl f (f acc x) xs

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

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

def PR51351_after := [llvm|
{
^0(%arg0 : i64, %arg1 : i32):
  %0 = llvm.mlir.constant(-33 : i32) : i32
  %1 = llvm.add %arg1, %0 : i32
  %2 = llvm.trunc %arg0 : i64 to i32
  %3 = llvm.shl %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def test_negative_combined_sub_unsigned_overflow_before := [llvm|
{
^0(%arg51 : i64):
  %0 = llvm.mlir.constant(10) : i64
  %1 = llvm.mlir.constant(11) : i64
  %2 = llvm.sub %0, %arg51 overflow<nuw> : i64
  %3 = llvm.icmp "ult" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def sdiv_pow2 : List (Σ Γ, LLVMPeepholeRewriteRefine 64 Γ) :=
  [
    ⟨_, sdiv_pow2_2⟩,
    ⟨_, sdiv_pow2_4⟩,
    ⟨_, sdiv_pow2_8⟩,
    ⟨_, sdiv_pow2_16⟩,
    ⟨_, sdiv_pow2_32⟩,
    ⟨_, sdiv_pow2_64⟩,
    ⟨_, sdiv_pow2_128⟩,
    ⟨_, sdiv_pow2_256⟩,
    ⟨_, sdiv_pow2_512⟩
  ]

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

def strictlyGTZero  (expr: GenBVExpr w) (widthId : Nat) : BoolExpr (GenBVPred) :=
  BoolExpr.gate Gate.and
    (.literal (GenBVPred.bin (zero w) BVBinPred.ult expr))
    (positive expr widthId)

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 ashrslt_03_12_exact_after := [llvm|
{
^0(%arg9 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

@[simp_denote]
def and_llvm_i32 := [LV| {
    ^entry (%a: i32, %b: i32):
    %0 = llvm.and %a, %b : i32
    llvm.return %0 : i32
  }]

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 and_not_or_commute5_after := [llvm|
{
^0(%arg466 : i32, %arg467 : i32, %arg468 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg466 : i32
  %3 = llvm.sdiv %0, %arg468 : i32
  %4 = llvm.xor %arg467, %3 : i32
  %5 = llvm.and %4, %2 : i32
  %6 = llvm.xor %5, %1 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

def lshr_mul_negative_nonuw_before := [llvm|
{
^0(%arg30 : i64):
  %0 = llvm.mlir.constant(52) : i64
  %1 = llvm.mlir.constant(2) : i64
  %2 = llvm.mul %arg30, %0 : i64
  %3 = llvm.lshr %2, %1 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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 narrow_zext_add_before := [llvm|
{
^0(%arg42 : i16, %arg43 : i32):
  %0 = llvm.zext %arg42 : i16 to i32
  %1 = llvm.add %0, %arg43 : i32
  %2 = llvm.trunc %1 : i32 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

def invert_icmp_before := [llvm|
{
^0(%arg151 : i32, %arg152 : i32):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.icmp "sle" %arg151, %arg152 : i32
  %2 = llvm.xor %1, %0 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

Min in Init.Prelude

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

def ofList (vals : List (Option α)) : Stream α :=
  fun i => (vals.get? i).join

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 llvm_add_lower_riscv_noflags_32 : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)]
where
  lhs:= add_llvm_no_flags_32
  rhs:= add_riscv_32

def test1_before := [llvm|
{
^0(%arg121 : i32):
  %0 = llvm.mlir.constant(12345 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.xor %arg121, %0 : i32
  %3 = llvm.icmp "slt" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def sgt_and_min_logical_before := [llvm|
{
^0(%arg350 : i9, %arg351 : i9):
  %0 = llvm.mlir.constant(-256 : i9) : i9
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "sgt" %arg350, %arg351 : i9
  %3 = llvm.icmp "eq" %arg350, %0 : i9
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

@[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
  }]

@[simp]
def dec_transport_idx {bvs' : BitVecs' n} (f : Fin m → Fin n) :
    have h : (BitVecs.transport f (dec bvs')).w = (dec (BitVecs'.transport f bvs')).w := by admit /- proof elided -/

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

instance : Repr (Module φ) where
  reprPrec
  | Module.mk fs attrs, _ =>
      attrs.map repr ++ fs.map repr |>.map (Format.align true ++ ·) |> Format.join

def ule_or_min_commute_before := [llvm|
{
^0(%arg138 : i8, %arg139 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "ule" %arg138, %arg139 : i8
  %2 = llvm.icmp "eq" %arg138, %0 : i8
  %3 = llvm.or %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def lshrugt_02_01_exact_after := [llvm|
{
^0(%arg204 : i4):
  %0 = llvm.mlir.constant(4 : i4) : i4
  %1 = llvm.icmp "ugt" %arg204, %0 : i4
  "llvm.return"(%1) : (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 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) -> ()
}
]

Bool.atLeastTwo in Init.Data.BitVec.Bitblast

def ne_10_after := [llvm|
{
^0(%arg78 : i32, %arg79 : i32):
  %0 = llvm.trunc %arg78 : i32 to i16
  %1 = llvm.trunc %arg79 : i32 to i16
  %2 = llvm.icmp "ne" %0, %1 : i16
  "llvm.return"(%2) : (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 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 lshrugt_02_09_before := [llvm|
{
^0(%arg390 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.mlir.constant(-7 : i4) : i4
  %2 = llvm.lshr %arg390, %0 : i4
  %3 = llvm.icmp "ugt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def mul_add_to_mul_6_before := [llvm|
{
^0(%arg26 : i32, %arg27 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.mul %arg26, %arg27 overflow<nsw> : i32
  %2 = llvm.mul %1, %0 overflow<nsw> : i32
  %3 = llvm.add %1, %2 overflow<nsw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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 ashrsgt_01_11_exact_after := [llvm|
{
^0(%arg90 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

partial def Com.printModule (com : Com d Γ eff ts) : Format :=
  f!"builtin.module {com.print}"

def fpExprWrapperToSubstitutionValue (map: Std.HashMap Nat FpExprWrapper) :
      Std.HashMap Nat (SubstitutionValue (FpExpr)) :=
        Std.HashMap.ofList (List.map (fun item => (item.fst, SubstitutionValue.genExpr item.snd.bvExpr)) map.toList)

def icmp_sle11_after := [llvm|
{
^0(%arg2 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "slt" %arg2, %0 : i8
  "llvm.return"(%1) : (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) -> ()
}
]

structure Tensor2d (α : Type) where
  size0 : Nat
  size1 : Nat
  val :  Fin size0 → Fin size1 → α

def test_logical_or_eq_a_b_before := [llvm|
{
^0(%arg9 : i1, %arg10 : i8, %arg11 : i8):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.icmp "eq" %arg10, %arg11 : i8
  %2 = "llvm.select"(%arg9, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = "llvm.select"(%2, %arg10, %arg11) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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 RawCNFA.autSignedCmp (cmp: RelationOrdering) : RawCNFA (BitVec 2) :=
  let (m, sltfin, sgtfin, seq) := m
  match cmp with
  | .lt => m.addFinal sltfin
  | .le => (m.addFinal sltfin).addFinal seq
  | .gt => m.addFinal sgtfin
  | .ge => (m.addFinal sgtfin).addFinal seq
where

def srem_constant_dividend_select_of_constants_divisor_after := [llvm|
{
^0(%arg37 : i1):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = "llvm.select"(%arg37, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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) -> ()
}
]

BitVec.instHShiftLeft in Init.Data.BitVec.Basic

def test_and1_logical_after := [llvm|
{
^0(%arg50 : i32, %arg51 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.and %arg51, %0 : i32
  %4 = llvm.icmp "sgt" %arg50, %1 : i32
  %5 = llvm.icmp "slt" %arg50, %3 : i32
  %6 = "llvm.select"(%4, %5, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%6) : (i1) -> ()
}
]

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

def n5_after := [llvm|
{
^0(%arg9 : i8, %arg10 : i8, %arg11 : i8):
  "llvm.return"(%arg11) : (i8) -> ()
}
]

def or_trunc_lshr_more_before := [llvm|
{
^0(%arg1 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.mlir.constant(-4 : i6) : i6
  %2 = llvm.lshr %arg1, %0 : i8
  %3 = llvm.trunc %2 : i8 to i6
  %4 = llvm.or %3, %1 : i6
  "llvm.return"(%4) : (i6) -> ()
}
]

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

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

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

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

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

def negation_of_increment_via_or_disjoint_after := [llvm|
{
^0(%arg81 : i8, %arg82 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.xor %arg82, %0 : i8
  %2 = llvm.add %arg81, %1 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def Expr.printType (e : Expr d Γ eff ts) : Format :=
  let argTys := e.args.mapToList (@fun t _ => printTy t)
  let argTys := Format.group <| Format.joinSep argTys ", "
  let retTys := ts.map printTy
  let retTys := Format.group <| Format.joinSep retTys ", "
  f!"({argTys}) -> ({retTys})"

def shl_and_xor_after := [llvm|
{
^0(%arg158 : i8, %arg159 : i8):
  %0 = llvm.mlir.constant(10 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.and %arg158, %0 : i8
  %3 = llvm.xor %arg159, %2 : i8
  %4 = llvm.shl %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

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

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

def xor_sext_sext_before := [llvm|
{
^0(%arg48 : i8, %arg49 : i4):
  %0 = llvm.sext %arg48 : i8 to i16
  %1 = llvm.sext %arg49 : i4 to i16
  %2 = llvm.xor %0, %1 : i16
  "llvm.return"(%2) : (i16) -> ()
}
]

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) -> ()
}
]

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

def Tensor2d'.transpose (t : Tensor2d' α) : Tensor2d' α where
  dim₀ := t.dim₁
  dim₁ := t.dim₀
  mat := t.mat.transpose

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

def or_logic_or_logic_and_4_before := [llvm|
{
^0(%arg39 : i1, %arg40 : i1, %arg41 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.or %arg39, %arg40 : i1
  %3 = "llvm.select"(%arg41, %0, %arg39) <{"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 test_sub_nuw__none_are_safe_before := [llvm|
{
^0(%arg18 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(-2147483648 : i32) : i32
  %2 = llvm.mlir.constant(2147483647 : i32) : i32
  %3 = llvm.icmp "eq" %arg18, %0 : i32
  %4 = llvm.sub %1, %arg18 overflow<nuw> : i32
  %5 = "llvm.select"(%3, %2, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def src_srem_shl_demand_max_signbit_before := [llvm|
{
^0(%arg24 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(30 : i32) : i32
  %2 = llvm.mlir.constant(-2147483648 : i32) : i32
  %3 = llvm.srem %arg24, %0 : i32
  %4 = llvm.shl %3, %1 : i32
  %5 = llvm.and %4, %2 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

structure Item where
 name : String
 tac : Syntax

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

def Expr.toPure? (e : Expr d Γ eff ty) : Option (Expr d Γ .pure ty) :=
  if h : e.HasPureOp then
    some <| e.toPure h
  else
    none

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

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

def ult_rem_zero_after := [llvm|
{
^0(%arg174 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.icmp "ult" %arg174, %0 : i8
  "llvm.return"(%1) : (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 lshrugt_03_07_after := [llvm|
{
^0(%arg376 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def add_2_before := [llvm|
{
^0(%arg121 : i8, %arg122 : i1, %arg123 : i8, %arg124 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(123 : i8) : i8
  %2 = llvm.xor %arg123, %0 : i8
  %3 = llvm.xor %arg124, %1 : i8
  %4 = "llvm.select"(%arg122, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %5 = llvm.add %arg121, %4 : i8
  %6 = llvm.xor %5, %0 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

def carry (initCarry : Bool) (x y : BitStream) : BitStream :=
  fun n => (addAux' initCarry x y n).2

def lshr_or_and_after := [llvm|
{
^0(%arg152 : i8, %arg153 : i8):
  %0 = llvm.mlir.constant(-64 : i8) : i8
  %1 = llvm.mlir.constant(5 : i8) : i8
  %2 = llvm.or %arg152, %0 : i8
  %3 = llvm.and %arg153, %2 : i8
  %4 = llvm.lshr %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def select_xor_icmp2_before := [llvm|
{
^0(%arg290 : i32, %arg291 : i32, %arg292 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "ne" %arg290, %0 : i32
  %2 = llvm.xor %arg290, %arg292 : i32
  %3 = "llvm.select"(%1, %arg291, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def p_commutative0_before := [llvm|
{
^0(%arg32 : i32, %arg33 : i32, %arg34 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg34, %arg32 : i32
  %2 = llvm.xor %arg34, %0 : i32
  %3 = llvm.and %2, %arg33 : i32
  %4 = llvm.or %1, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def binop_left_to_zero_udiv : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (0) : i64
      %0 = llvm.udiv %c, %x : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (0) : i64
      llvm.return %c : i64
  }]

def productsList : List (List α) -> List (List α)
| [] => [[]] 
| (xs::xss) => Id.run do
  let mut out := []
  let xss' := productsList xss 
  for x in xs do  
    out := out.append (xss'.map (fun xs => x :: xs))
  return out

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 test24_logical_after := [llvm|
{
^0(%arg272 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.icmp "sgt" %arg272, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

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

def CNFA.inter_bv_language (m₁ m₂ : CNFA n) :
    m₁.bv_recognizes L₁ →
    m₂.bv_recognizes L₂ →
    (m₁.inter m₂).bv_recognizes (L₁ ∩ L₂) :=

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

def region0Expr := (Expr.app (Expr.const `MLIR.AST.Region []) (Expr.const `Nat.zero []))

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 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 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 main9_after := [llvm|
{
^0(%arg26 : i32):
  %0 = llvm.mlir.constant(192 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.and %arg26, %0 : i32
  %4 = llvm.icmp "eq" %3, %0 : i32
  %5 = "llvm.select"(%4, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

@[simp_denote]
def shl_riscv_32 := [LV| {
  ^entry (%reg1: i32, %reg2: i32 ):
    %0 = "builtin.unrealized_conversion_cast"(%reg1) : (i32) -> (!i64)
    %1 = "builtin.unrealized_conversion_cast"(%reg2) : (i32) -> (!i64)
    %2 = sll %0, %1 : !i64
    %3 = "builtin.unrealized_conversion_cast"(%2) : (!i64) -> (i32)
    llvm.return %3 : i32
  }]

def t15_and_with_const1_after := [llvm|
{
^0(%arg3 : i32, %arg4 : i32, %arg5 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %0, %arg4 overflow<nuw> : i32
  %3 = llvm.and %arg3, %2 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def wrongimm2_before := [llvm|
{
^0(%arg4 : i16):
  %0 = llvm.mlir.constant(8 : i16) : i16
  %1 = llvm.mlir.constant(6 : i8) : i8
  %2 = llvm.lshr %arg4, %0 : i16
  %3 = llvm.trunc %2 : i16 to i8
  %4 = llvm.trunc %arg4 : i16 to i8
  %5 = llvm.ashr %4, %1 : i8
  %6 = llvm.icmp "eq" %5, %3 : i8
  "llvm.return"(%6) : (i1) -> ()
}
]

noncomputable def TV_add_mul_neg_one_lhs : PeepholeRewrite (ModArith q) [.modLike, .modLike] .modLike :=
{
  lhs := test_add_mul_neg_one_lhs_LHS,
  rhs := test_add_mul_neg_one_lhs_RHS,
  correct := by admit /- proof elided -/

@[coe]
def toCons {Γ : Ctxt Ty} {t t' : Ty} (var : Var Γ t) : Var (cons t' Γ) t  :=
  ⟨var.1+1, var.2⟩

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

def not_and_and_not_after := [llvm|
{
^0(%arg567 : i32, %arg568 : i32, %arg569 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg567 : i32
  %3 = llvm.or %arg568, %arg569 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.and %2, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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 shl_lshr_demand6_after := [llvm|
{
^0(%arg10 : i16):
  %0 = llvm.mlir.constant(2057 : i16) : i16
  %1 = llvm.mlir.constant(4094 : i16) : i16
  %2 = llvm.shl %0, %arg10 : i16
  %3 = llvm.and %2, %1 : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

BitVec.smod in Init.Data.BitVec.Basic

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

def bool_add_lshr_before := [llvm|
{
^0(%arg14 : i1, %arg15 : i1):
  %0 = llvm.mlir.constant(1 : i2) : i2
  %1 = llvm.zext %arg14 : i1 to i2
  %2 = llvm.zext %arg15 : i1 to i2
  %3 = llvm.add %1, %2 : i2
  %4 = llvm.lshr %3, %0 : i2
  "llvm.return"(%4) : (i2) -> ()
}
]

def test46_after := [llvm|
{
^0(%arg141 : i64):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(10752 : i32) : i32
  %2 = llvm.trunc %arg141 : i64 to i32
  %3 = llvm.shl %2, %0 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.zext nneg %4 : i32 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

@[simp_llvm_option]
def sdiv {w : Nat} (x y : IntW w) (flag : ExactFlag := {exact := false}) : IntW w := do
  let x' ← x
  let y' ← y
  if flag.exact ∧ x'.smod y' ≠ 0 then
    .poison
  else
    sdiv? x' y'

Lean.Expr.bvar in Lean.Expr

def trunc_equality_both_before := [llvm|
{
^0(%arg40 : i16, %arg41 : i16):
  %0 = llvm.trunc %arg40 overflow<nsw,nuw> : i16 to i8
  %1 = llvm.trunc %arg41 overflow<nsw,nuw> : i16 to i8
  %2 = llvm.icmp "eq" %0, %1 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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) -> ()
}
]

def positive_samevar_shlnuw_after := [llvm|
{
^0(%arg57 : i8, %arg58 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.shl %0, %arg58 overflow<nsw> : i8
  %2 = llvm.and %1, %arg57 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def urem_illegal_type_after := [llvm|
{
^0(%arg15 : i9, %arg16 : i9):
  %0 = llvm.urem %arg15, %arg16 : i9
  %1 = llvm.zext %0 : i9 to i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def test_negative_combined_sub_unsigned_overflow_before := [llvm|
{
^0(%arg51 : i64):
  %0 = llvm.mlir.constant(10) : i64
  %1 = llvm.mlir.constant(11) : i64
  %2 = llvm.sub %0, %arg51 overflow<nuw> : i64
  %3 = llvm.icmp "ult" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

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

private unsafe def evalExprOfTypeRegionAux (φ : Nat) : Q(Region $φ) → MetaM (Region φ) :=
  evalExpr (Region φ) q(Region $φ)

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

def generalizeTactic
      (H : HydrableParseAndGeneralize parsedExpr genLogicalExpr genExpr)
      (cfg : MedusaSynthGeneralizeConfig)
      (expr : Expr) : TacticM Unit := do
  let name ← mkAuxDeclName `generalized
  let msg ← withoutModifyingEnv <| withoutModifyingState do
    Lean.Elab.Tactic.withMainContext do
      
      
      let res ← parseAndGeneralize (H := H) cfg expr (GeneralizeContext.Tactic name)
      pure m! "{res}"
  logInfo m! "{msg}"

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

def sub_mask1_lshr_after := [llvm|
{
^0(%arg21 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.mlir.constant(7 : i8) : i8
  %2 = llvm.mlir.constant(10 : i8) : i8
  %3 = llvm.shl %arg21, %0 : i8
  %4 = llvm.ashr %3, %1 : i8
  %5 = llvm.add %4, %2 overflow<nsw> : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

def p0_after := [llvm|
{
^0(%arg28 : i8, %arg29 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.lshr %arg28, %arg29 : i8
  %2 = llvm.icmp "ne" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def mkExpr (Γ : Ctxt _) (opStx : MLIR.AST.Op 0) :
    MLIR.AST.ReaderM (DC) (Σ eff ty, Expr (DC) Γ eff ty) := do
  match opStx.name with
  | op@"DC.source" =>
    if opStx.args.length > 0 then
      throw <| .generic s!"expected one operand for `monomial`, found #'{opStx.args.length}' in '{repr opStx.args}'"
    else
      return ⟨_, [.tokenstream], source⟩
  | op@"DC.sink" | op@"DC.unpack" | op@"DC.fork" | op@"DC.branch" | op@"DC.fst" | op@"DC.snd" | op@"DC.fstVal" | op@"DC.sndVal" =>
    match opStx.args with
    | v₁Stx::[] =>
      let ⟨ty₁, v₁⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₁Stx
      match ty₁, op with
      | .tokenstream2, "DC.fst" => return ⟨_, [.tokenstream], fst v₁⟩
      | .tokenstream2, "DC.snd"  => return ⟨_, [.tokenstream], snd v₁⟩
      | .valuetokenstream r, "DC.fstVal" => return ⟨_, [.valuestream r], fstVal v₁⟩
      | .valuetokenstream _, "DC.sndVal"  => return ⟨_, [.tokenstream], sndVal v₁⟩
      | .tokenstream, "DC.sink" => return ⟨_, [.tokenstream], sink v₁⟩
      | .valuestream r, "DC.unpack"  => return ⟨_, [.valuetokenstream r], unpack v₁⟩
      | .tokenstream, "DC.fork"  => return ⟨_, [.tokenstream2], fork v₁⟩
      | .valuestream 1, "DC.branch"  => return ⟨_, [.tokenstream2], branch v₁⟩
      | _, _ => throw <| .generic s!"type mismatch"
    | _ => throw <| .generic s!"expected one operand for `monomial`, found #'{opStx.args.length}' in '{repr opStx.args}'"
  | op@"DC.merge" | op@"DC.join" | op@"DC.pack" | op@"DC.pair" =>
    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
      | .tokenstream, .tokenstream, "DC.merge" => return ⟨_, [.valuestream 1], merge v₁ v₂⟩
      | .tokenstream, .tokenstream, "DC.join"  => return ⟨_, [.tokenstream], join v₁ v₂⟩
      | .valuestream r, .tokenstream, "DC.pack"  => return ⟨_, [.valuestream r], pack v₁ v₂⟩
      | .valuestream r₁, .valuestream r₂, "DC.pair"  =>
        if h : r₁ = r₂ then
          let v₂' : Γ.Var (Ty.valuestream r₁) := Eq.mp (by admit /- proof elided -/
          ) v₂
          return ⟨_, [.valuestream2 r₁], pair v₁ v₂'⟩
        else throw <| .generic s!"type mismatch, expected same width for pair, got {r₁} and {r₂}"
      | _, _, _ => throw <| .generic s!"type mismatch"
    | _ => throw <| .generic s!"expected two operands for `monomial`, found #'{opStx.args.length}' in '{repr opStx.args}'"
  | op@"DC.select" =>
    match opStx.args with
    | v₁Stx::v₂Stx::v₃Stx::[] =>
      let ⟨ty₁, v₁⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₁Stx
      let ⟨ty₂, v₂⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₂Stx
      let ⟨ty₃, v₃⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₃Stx
      match ty₁, ty₂, ty₃, op with
      | .tokenstream, .tokenstream, .valuestream 1, "DC.select" => return ⟨_, [.tokenstream], select v₁ v₂ v₃⟩
      | _, _, _, _=> throw <| .generic s!"type mismatch"
    | _ => throw <| .generic s!"expected three operands for `monomial`, found #'{opStx.args.length}' in '{repr opStx.args}'"
  | _ => throw <| .unsupportedOp s!"unsupported operation {repr opStx}"

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

Lean.Level.zero in Lean.Level

def Region.appendOp (bb: Region φ) (op: Op φ): Region φ :=
  match bb with
  | Region.mk name args bbs => Region.mk name args (bbs ++ [op])

Function.Surjective in Init.Data.Function

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

def zext_zext_eq_before := [llvm|
{
^0(%arg80 : i8, %arg81 : i8):
  %0 = llvm.zext %arg80 : i8 to i32
  %1 = llvm.zext %arg81 : i8 to i32
  %2 = llvm.icmp "eq" %0, %1 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

addParenHeuristic in Init.Data.ToString.Basic

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

def src_is_notmask_lshr_shl_after := [llvm|
{
^0(%arg61 : i8, %arg62 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(-124 : i8) : i8
  %2 = llvm.shl %0, %arg62 overflow<nsw> : i8
  %3 = llvm.xor %arg61, %1 : i8
  %4 = llvm.icmp "uge" %3, %2 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

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

def masked_icmps_mask_notallzeros_bmask_mixed_1b_logical_after := [llvm|
{
^0(%arg91 : 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.and %arg91, %0 : i32
  %5 = llvm.icmp "ne" %4, %1 : i32
  %6 = llvm.and %arg91, %2 : i32
  %7 = llvm.icmp "eq" %6, %3 : i32
  %8 = llvm.and %5, %7 : i1
  "llvm.return"(%8) : (i1) -> ()
}
]

def ashr_and_or_disjoint_after := [llvm|
{
^0(%arg41 : i8, %arg42 : 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 %arg41, %0 : i8
  %4 = llvm.shl %3, %1 : i8
  %5 = llvm.and %arg42, %2 : i8
  %6 = llvm.or disjoint %5, %4 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

def PR45977_f2_before := [llvm|
{
^0(%arg138 : i32, %arg139 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg138, %arg139 : i32
  %2 = llvm.xor %arg139, %0 : i32
  %3 = llvm.or %arg138, %2 : i32
  %4 = llvm.xor %1, %3 : i32
  "llvm.return"(%4) : (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) -> ()
}
]

instance : TyDenote (Scf d).Ty := inferInstanceAs (TyDenote d.Ty)

def lor_lor_left2_after := [llvm|
{
^0(%arg68 : i1, %arg69 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = "llvm.select"(%arg69, %0, %arg68) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%1) : (i1) -> ()
}
]

def ex1_post_cse_post_dce :
  { com : Com Ex ∅ .pure [.nat] // ∀ V, ex1_post_cse.val.denote V = com.denote V } :=
    (DCE.dce' ex1_post_cse.val)

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) -> ()
}
]

FinEnum.toList in Mathlib.Data.FinEnum

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 add_nosignbit_select_shl_after := [llvm|
{
^0(%arg32 : i32, %arg33 : i1):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(-16777216 : i32) : i32
  %2 = llvm.shl %arg32, %0 : i32
  %3 = llvm.add %2, %1 : i32
  %4 = "llvm.select"(%arg33, %3, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def test : Stream (BitVec 1) :=
  BranchEg1.denote (Ctxt.Valuation.ofPair c x) |>.getN 0


unseal String.splitOnAux in

def test1_before := [llvm|
{
^0(%arg27 : i32, %arg28 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.icmp "sgt" %arg27, %0 : i32
  %3 = llvm.icmp "slt" %arg28, %1 : i32
  %4 = llvm.xor %3, %2 : i1
  %5 = llvm.zext %4 : i1 to i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

BitVec.instHShiftRight in Init.Data.BitVec.Basic

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

def toHom (m : Mapping Γ Δ) (h : m.IsTotal) : Γ.Hom Δ :=
  fun t v =>
    m.lookup ⟨t, v⟩ |>.get <| by
      simpa [AList.lookup_isSome] using h _

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) -> ()
}
]

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

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

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

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

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

instance instRefinement : HRefinement (Id α) (Id β) := inst

def generateCombinations {α} (num: Nat) (values: List α) : List (List α) :=
    match num, values with
    | 0, _ => [[]]
    | _, [] => []
    | n + 1, x::xs =>
            let combosWithoutX := (generateCombinations (n + 1) xs)
            let combosWithX := (generateCombinations n xs).map (λ combo => x :: combo)
            combosWithoutX ++ combosWithX

instance : MLIR.AST.TransformExpr (Handshake) 0 where
  mkExpr := mkExpr

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

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

def test3_after := [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.or disjoint %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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 or_logic_or_logic_and_4_after := [llvm|
{
^0(%arg39 : i1, %arg40 : i1, %arg41 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = "llvm.select"(%arg41, %arg40, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %2 = llvm.or %arg39, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

private def succ0 : BBName := ([mlir_op_successor_arg| ^bb])

def llvm01:=
  [LV|{
  ^bb0(%X : i64, %Y : i64 ):
    %1 = llvm.icmp.eq %X, %Y : i64
    %2 = llvm.sub %X, %X : i64
    llvm.return %1 : i1
  }]

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

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

def not_match_inconsistent_values_after := [llvm|
{
^0(%arg12 : i64):
  %0 = llvm.mlir.constant(299) : i64
  %1 = llvm.mlir.constant(29) : i64
  %2 = llvm.mlir.constant(63) : i64
  %3 = llvm.urem %arg12, %0 : i64
  %4 = llvm.udiv %arg12, %1 : i64
  %5 = llvm.and %4, %2 : i64
  %6 = llvm.mul %5, %0 overflow<nsw,nuw> : i64
  %7 = llvm.add %3, %6 overflow<nsw,nuw> : i64
  "llvm.return"(%7) : (i64) -> ()
}
]

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

def one_side_fold_eq_before := [llvm|
{
^0(%arg25 : i32, %arg26 : i32, %arg27 : i32, %arg28 : i1):
  %0 = "llvm.select"(%arg28, %arg25, %arg27) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %1 = "llvm.select"(%arg28, %arg26, %arg27) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %2 = llvm.icmp "eq" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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 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) -> ()
}
]

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

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

def mulh_to_lshr : List (Σ Γ, RISCVPeepholeRewrite Γ) :=
  [
    ⟨_, mulh_to_lshr_2⟩,
    ⟨_, mulh_to_lshr_4⟩,
    ⟨_, mulh_to_lshr_8⟩,
    ⟨_, mulh_to_lshr_16⟩,
    ⟨_, mulh_to_lshr_32⟩,
    ⟨_, mulh_to_lshr_64⟩,
    ⟨_, mulh_to_lshr_128⟩,
    ⟨_, mulh_to_lshr_256⟩,
    ⟨_, mulh_to_lshr_512⟩
  ]

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

elab "[RV64_com| " reg:mlir_region "]" : term => do
  SSA.elabIntoCom reg q(RV64)

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

def div_bit_set_before := [llvm|
{
^0(%arg61 : i32, %arg62 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %0, %arg62 : i32
  %3 = llvm.sdiv %2, %arg61 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  %5 = llvm.zext %4 : i1 to i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

def select_constant_cmp : List (Σ Γ, LLVMPeepholeRewriteRefine 64  Γ) :=
  [⟨_, select_constant_cmp_true⟩,
  ⟨_, select_constant_cmp_false⟩]

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) -> ()
}
]

Array.size in Init.Prelude

def different_size_sext_sext_ule_after := [llvm|
{
^0(%arg8 : i7, %arg9 : i4):
  %0 = llvm.sext %arg9 : i4 to i7
  %1 = llvm.icmp "ule" %arg8, %0 : i7
  "llvm.return"(%1) : (i1) -> ()
}
]

def test1_after := [llvm|
{
^0(%arg1 : i17):
  %0 = llvm.mlir.constant(8 : i17) : i17
  %1 = llvm.lshr %arg1, %0 : i17
  %2 = llvm.shl %arg1, %0 : i17
  %3 = llvm.or %1, %2 : i17
  "llvm.return"(%3) : (i17) -> ()
}
]

def lowmask_mul_zext_before := [llvm|
{
^0(%arg221 : i8, %arg222 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.zext %arg221 : i8 to i32
  %2 = llvm.mul %1, %arg222 : i32
  %3 = llvm.and %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

def ne_basic_equal_5_after := [llvm|
{
^0(%arg32 : i8, %arg33 : i8):
  %0 = llvm.mlir.constant(-6 : i8) : i8
  %1 = llvm.add %arg32, %0 : i8
  %2 = llvm.icmp "ult" %1, %arg33 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def sub_from_constant_of_sub_from_constant_before := [llvm|
{
^0(%arg170 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(11 : i8) : i8
  %2 = llvm.sub %0, %arg170 : i8
  %3 = llvm.sub %1, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def shl_lshr_eq_amt_multi_use_after := [llvm|
{
^0(%arg7 : i44):
  %0 = llvm.mlir.constant(33 : i44) : i44
  %1 = llvm.mlir.constant(2047 : i44) : i44
  %2 = llvm.shl %arg7, %0 : i44
  %3 = llvm.and %arg7, %1 : i44
  %4 = llvm.or disjoint %2, %3 : i44
  "llvm.return"(%4) : (i44) -> ()
}
]

def test0_before := [llvm|
{
^0(%arg13 : i39):
  %0 = llvm.mlir.constant(0 : i39) : i39
  %1 = llvm.and %arg13, %0 : i39
  "llvm.return"(%1) : (i39) -> ()
}
]

def bools_logical_commute0_after := [llvm|
{
^0(%arg108 : i1, %arg109 : i1, %arg110 : i1):
  %0 = "llvm.select"(%arg110, %arg109, %arg108) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

instance : BEq BVExpr.PackedBitVec where
  beq a b := if h : a.w = b.w then
                let b' := h ▸ b.bv
                a.bv == b'
              else
                false

Lean.Parser.Tactic.unknown in Lean.Parser.Tactic

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

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

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

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 neg_nsw_slt_n1_before := [llvm|
{
^0(%arg21 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.sub %0, %arg21 overflow<nsw> : i8
  %3 = llvm.icmp "slt" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def or_and3_after := [llvm|
{
^0(%arg104 : i1, %arg105 : i1, %arg106 : i32, %arg107 : i32):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "ne" %arg106, %arg107 : i32
  %3 = "llvm.select"(%2, %arg105, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = "llvm.select"(%arg104, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

instance instFinEnumBV : FinEnum (BitVec w) where
  card := 2^w
  equiv := {
    toFun := fun x => x.toFin
    invFun := fun x => BitVec.ofFin x
    left_inv := by admit /- proof elided -/

def CollectState.pcard (state : CollectState) : Nat :=
  state.pToIx.size

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

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

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

def Diff (Γ₁ Γ₂ : Ctxt Ty) : Type :=
  {d : Nat // Diff.Valid Γ₁ Γ₂ d}

def icmp_x_slt_0_and_icmp_y_sgt_neg1_i32_fail_after := [llvm|
{
^0(%arg40 : i32, %arg41 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.icmp "sgt" %arg40, %0 : i32
  %3 = llvm.icmp "slt" %arg41, %1 : i32
  %4 = llvm.and %3, %2 : i1
  %5 = llvm.zext %4 : i1 to i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def and_sequence_15_rhs (w : Nat)  :=
[llvm( w )| {
^bb0(%C1 : _, %Z : _):
  %v1 = llvm.and %Z,  %C1
  llvm.return %v1
}]

def Lets.inner : Lets Op T → List (Expr Op T)
  | ⟨inner⟩ => inner

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 or_simplify_uge_before := [llvm|
{
^0(%arg15 : i8, %arg16 : i8, %arg17 : i1):
  %0 = llvm.mlir.constant(-127 : i8) : i8
  %1 = llvm.mlir.constant(127 : i8) : i8
  %2 = llvm.or %arg15, %0 : i8
  %3 = llvm.and %arg16, %1 : i8
  %4 = llvm.or %2, %3 : i8
  %5 = llvm.icmp "uge" %3, %4 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

def PR42691_8_before := [llvm|
{
^0(%arg329 : i32):
  %0 = llvm.mlir.constant(14 : i32) : i32
  %1 = llvm.mlir.constant(-2147483648 : i32) : i32
  %2 = llvm.icmp "slt" %arg329, %0 : i32
  %3 = llvm.icmp "ne" %arg329, %1 : i32
  %4 = llvm.and %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def or_xor_common_op_commute5_before := [llvm|
{
^0(%arg120 : i8, %arg121 : i8, %arg122 : i8):
  %0 = llvm.or %arg121, %arg120 : i8
  %1 = llvm.xor %arg120, %arg122 : i8
  %2 = llvm.or %1, %0 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

class DialectParse (d : Dialect) (φ : outParam Nat) [DialectSignature d]
    [DecidableEq d.Ty] [ToString d.Ty]
    extends TransformTy d φ where
   
  isValidReturn : (Γ : Ctxt d.Ty) → (opStx : Op φ) → ReaderM d Bool

   
  
  mkExpr [TransformTy d φ] : (Γ : Ctxt d.Ty) → (opStx : Op φ) → ReaderM d (Σ eff ty, Expr d Γ eff ty)

def test_sdiv_canonicalize_op0_before := [llvm|
{
^0(%arg15 : i32, %arg16 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.sub %0, %arg15 overflow<nsw> : i32
  %2 = llvm.sdiv %1, %arg16 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

def shrink_select_before := [llvm|
{
^0(%arg52 : i1, %arg53 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = "llvm.select"(%arg52, %arg53, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %2 = llvm.trunc %1 : i32 to i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def binop_left_to_zero_lshr : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (0) : i64
      %0 = llvm.lshr %c, %x : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (0) : i64
      llvm.return %c : i64
  }]

def lshrult_02_08_after := [llvm|
{
^0(%arg343 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (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 APlusBMinusA : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%a: i64, %b: i64):
      %0 = llvm.sub %b, %a : i64
      %1 = llvm.add %a, %0 : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%a: i64, %b: i64):
      llvm.return %b : i64
  }]

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

def not_shl_before := [llvm|
{
^0(%arg86 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(-128 : i8) : i8
  %2 = llvm.shl %arg86, %0 : i8
  %3 = llvm.xor %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def uge_umin1_before := [llvm|
{
^0(%arg52 : i32, %arg53 : i32):
  %0 = llvm.icmp "ult" %arg52, %arg53 : i32
  %1 = "llvm.select"(%0, %arg52, %arg53) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %2 = llvm.icmp "uge" %1, %arg52 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

def test1_after := [llvm|
{
^0(%arg60 : i64, %arg61 : i32):
  %0 = llvm.mlir.constant(123) : i64
  %1 = llvm.and %arg60, %0 : i64
  "llvm.return"(%1) : (i64) -> ()
}
]

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

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

Lean.Expr.isFVar in Lean.Expr

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

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

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

def srem {w : Nat} (x y : IntW w) : IntW w := do
  let x' ← x
  let y' ← y
  srem? x' y'

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

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 in_constant_varx_mone_before := [llvm|
{
^0(%arg28 : i4, %arg29 : i4):
  %0 = llvm.mlir.constant(-1 : i4) : i4
  %1 = llvm.mlir.constant(1 : i4) : i4
  %2 = llvm.xor %arg28, %0 : i4
  %3 = llvm.and %2, %1 : i4
  %4 = llvm.xor %3, %0 : i4
  "llvm.return"(%4) : (i4) -> ()
}
]

def scalar_i64_lshr_and_negC_eq_after := [llvm|
{
^0(%arg33 : i64, %arg34 : i64):
  %0 = llvm.mlir.constant(8589934592) : i64
  %1 = llvm.lshr %arg33, %arg34 : i64
  %2 = llvm.icmp "ult" %1, %0 : i64
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

def test0_before := [llvm|
{
^0(%arg210 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.xor %arg210, %0 : i1
  "llvm.return"(%1) : (i1) -> ()
}
]

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

def or_nosignbit_shl_before := [llvm|
{
^0(%arg20 : i32):
  %0 = llvm.mlir.constant(2147418112 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.or %arg20, %0 : i32
  %3 = llvm.shl %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

instance : DialectSignature Ex where
  signature
    | .add    => ⟨[.nat, .nat], [], [.nat], .pure⟩
    | .beq    => ⟨[.nat, .nat], [], [.bool], .pure⟩
    | .cst _  => ⟨[], [], [.nat], .pure⟩

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 test3_before := [llvm|
{
^0(%arg307 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.and %arg307, %0 : i1
  "llvm.return"(%1) : (i1) -> ()
}
]

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
}]

def test_sext_before := [llvm|
{
^0(%arg30 : i32, %arg31 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.icmp "eq" %arg30, %0 : i32
  %3 = llvm.sext %2 : i1 to i32
  %4 = llvm.add %arg31, %3 : i32
  %5 = llvm.xor %4, %1 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

def Deleted (Γ: Ctxt Ty) (vs : DeleteRange Γ) (Γ' : Ctxt Ty) : Prop :=
  Γ' = Γ.delete vs

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) -> ()
}
]

def not_mul_of_pow2_after := [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 overflow<nsw,nuw> : i32
  %5 = llvm.icmp "ugt" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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) -> ()
}
]

instance : Complement BitStream := ⟨map Bool.not⟩

Stream'.head in Mathlib.Data.Stream.Defs

def icmp_slt_0_or_icmp_sgt_0_i64_fail3_after := [llvm|
{
^0(%arg69 : i64):
  %0 = llvm.mlir.constant(62) : i64
  %1 = llvm.mlir.constant(63) : i64
  %2 = llvm.ashr %arg69, %0 : i64
  %3 = llvm.lshr %arg69, %1 : i64
  %4 = llvm.or %2, %3 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

def multiuse2_before := [llvm|
{
^0(%arg10 : i32):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.mlir.constant(24 : i32) : i32
  %4 = llvm.mlir.constant(96 : i32) : i32
  %5 = llvm.and %arg10, %0 : i32
  %6 = llvm.shl %5, %1 overflow<nsw,nuw> : i32
  %7 = llvm.shl %5, %2 overflow<nsw,nuw> : i32
  %8 = llvm.and %arg10, %3 : i32
  %9 = llvm.shl %8, %1 overflow<nsw,nuw> : i32
  %10 = llvm.shl %8, %2 overflow<nsw,nuw> : i32
  %11 = llvm.and %arg10, %4 : i32
  %12 = llvm.shl %11, %1 overflow<nsw,nuw> : i32
  %13 = llvm.shl %11, %2 overflow<nsw,nuw> : i32
  %14 = llvm.or %6, %9 : i32
  %15 = llvm.or %12, %14 : i32
  %16 = llvm.or %13, %10 : i32
  %17 = llvm.or %7, %16 : i32
  %18 = llvm.or %15, %17 : i32
  "llvm.return"(%18) : (i32) -> ()
}
]

def sdiv_icmp1_before := [llvm|
{
^0(%arg18 : i64):
  %0 = llvm.mlir.constant(5) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.sdiv exact %arg18, %0 : i64
  %3 = llvm.icmp "eq" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

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 splat_mul_known_lz_after := [llvm|
{
^0(%arg72 : i32):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def Term.toExpr (t : Term) : Expr :=
  mkApp2 (mkConst ``Term.mk) (ToExpr.toExpr t.c) (t.f.toExpr)

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 positive_samevar_ashrexact_before := [llvm|
{
^0(%arg42 : i8, %arg43 : i8):
  %0 = llvm.ashr exact %arg42, %arg43 : i8
  %1 = llvm.shl %0, %arg43 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def urem_match : List (Σ Γ, Σ ty, PeepholeRewrite LLVMPlusRiscV Γ ty) := [
   mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_urem_lower_riscv_64)
]

def rem_euclid_wrong_operands_select_before := [llvm|
{
^0(%arg8 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.srem %arg8, %0 : i32
  %3 = llvm.icmp "slt" %2, %1 : i32
  %4 = llvm.add %2, %0 : i32
  %5 = "llvm.select"(%3, %2, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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 or_not_and_commute4_after := [llvm|
{
^0(%arg525 : i32, %arg526 : i32, %arg527 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg527 : i32
  %3 = llvm.xor %arg526, %2 : i32
  %4 = llvm.xor %arg525, %1 : i32
  %5 = llvm.and %3, %4 : i32
  "llvm.return"(%5) : (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 mul_add_to_mul_9_before := [llvm|
{
^0(%arg23 : i16):
  %0 = llvm.mlir.constant(16384 : i16) : i16
  %1 = llvm.mul %arg23, %0 overflow<nsw> : i16
  %2 = llvm.mul %arg23, %0 overflow<nsw> : i16
  %3 = llvm.add %1, %2 overflow<nsw> : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

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 xor_lshr_before := [llvm|
{
^0(%arg624 : i8, %arg625 : i8, %arg626 : i8, %arg627 : i8):
  %0 = llvm.lshr %arg624, %arg627 : i8
  %1 = llvm.lshr %arg625, %arg627 : i8
  %2 = llvm.xor %0, %arg626 : i8
  %3 = llvm.xor %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def ConcreteCliTest.printSignature (test : ConcreteCliTest) : String :=
  s!"{test.context.toList.reverse} → {test.ty}"

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 lshrugt_02_14_before := [llvm|
{
^0(%arg385 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.mlir.constant(-2 : i4) : i4
  %2 = llvm.lshr %arg385, %0 : i4
  %3 = llvm.icmp "ugt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

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 positive_with_mask_after := [llvm|
{
^0(%arg60 : i32):
  %0 = llvm.mlir.constant(128 : i32) : i32
  %1 = llvm.icmp "ult" %arg60, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

def test18_before := [llvm|
{
^0(%arg194 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(123 : i32) : i32
  %2 = llvm.xor %arg194, %0 : i32
  %3 = llvm.sub %1, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

def add_nuw_const_const_sub_after := [llvm|
{
^0(%arg55 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.sub %0, %arg55 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

def ripple_nsw3_after := [llvm|
{
^0(%arg19 : i16, %arg20 : i16):
  %0 = llvm.mlir.constant(-21845 : i16) : i16
  %1 = llvm.mlir.constant(21843 : i16) : i16
  %2 = llvm.and %arg20, %0 : i16
  %3 = llvm.and %arg19, %1 : i16
  %4 = llvm.add %2, %3 overflow<nsw,nuw> : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

def scalar_i32_lshr_and_negC_eq_nonzero_before := [llvm|
{
^0(%arg2 : i32, %arg3 : i32):
  %0 = llvm.mlir.constant(-8 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.lshr %arg2, %arg3 : i32
  %3 = llvm.and %2, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def scf.for (n: Nat) (f: Nat → β → β) (seed: β) : β :=
  let i := 0
  scf.for.loop f n (n - i) seed

def test1_before := [llvm|
{
^0(%arg14 : i32, %arg15 : i32):
  %0 = llvm.icmp "slt" %arg14, %arg15 : i32
  %1 = llvm.zext %0 : i1 to i32
  %2 = llvm.icmp "sgt" %arg14, %arg15 : i32
  %3 = llvm.zext %2 : i1 to i32
  %4 = llvm.and %1, %3 : i32
  %5 = llvm.trunc %4 : i32 to i1
  "llvm.return"(%5) : (i1) -> ()
}
]

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

def select2_after := [llvm|
{
^0(%arg9 : i1, %arg10 : i8, %arg11 : i8, %arg12 : i8):
  %0 = llvm.add %arg10, %arg11 : i8
  %1 = "llvm.select"(%arg9, %arg12, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

@[simp_denote]
def and_llvm_16 := [LV| {
  ^entry (%lhs: i16, %rhs: i16):
    %1 = llvm.and %lhs, %rhs : i16
    llvm.return %1 : i16
  }]

def lshr_and_add_before := [llvm|
{
^0(%arg57 : i8, %arg58 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.mlir.constant(12 : i8) : i8
  %3 = llvm.srem %arg57, %0 : i8
  %4 = llvm.lshr %arg58, %1 : i8
  %5 = llvm.and %4, %2 : i8
  %6 = llvm.add %3, %5 : i8
  %7 = llvm.shl %6, %1 : i8
  "llvm.return"(%7) : (i8) -> ()
}
]

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

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

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

instance (ty : LLVM.Ty) : Inhabited (TyDenote.toType ty) where
  default := match ty with
    | bitvec _ => (default : LLVM.IntW _)

def sub_zext_trunc_lshr_after := [llvm|
{
^0(%arg15 : i64):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.mlir.constant(31 : i32) : i32
  %2 = llvm.mlir.constant(10 : i32) : i32
  %3 = llvm.trunc %arg15 : i64 to i32
  %4 = llvm.shl %3, %0 : i32
  %5 = llvm.ashr %4, %1 : i32
  %6 = llvm.add %5, %2 overflow<nsw> : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

def ex1_lhs : Com [.nat] .nat :=
  Com.var (rgn (k := 0) ⟨0, by admit /- proof elided -/
  ⟩ (
      Com.var (add ⟨0, by admit /- proof elided -/
      ⟩ ⟨0, by admit /- proof elided -/
      ⟩) 
      <| Com.ret ⟨0, by admit /- proof elided -/
      ⟩
  )) <|
  Com.ret ⟨0, by admit /- proof elided -/
  ⟩

def and_xor_commute3_after := [llvm|
{
^0(%arg151 : i32, %arg152 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.udiv %0, %arg151 : i32
  %3 = llvm.udiv %0, %arg152 : i32
  %4 = llvm.xor %2, %1 : i32
  %5 = llvm.and %3, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

def redundant_binop_in_equality_XXorYNeX : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64, %y: i64):
      %0 = llvm.xor %x, %y : i64
      %1 = llvm.icmp.ne %0, %x : i64
      llvm.return %1 : i1
  }]
  rhs := [LV| {
    ^entry (%x: i64, %y: i64):
      %0 = llvm.mlir.constant (0) : i64
      %1 = llvm.icmp.ne %y, %0 : i64
      llvm.return %1 : i1
  }]

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 revertBvHyps (g : MVarId) : MetaM MVarId := do
  let (_, g) ← g.revert (← g.getNondepPropHyps)
  return g

noncomputable instance :
  CoeDep (MatchVarResult lets v (.var matchLets matchExpr) w.appendInl mapIn)
        mapOut
        (let args := mapOut.getPureExpr_eq_some.choose
         MatchArgResult lets matchLets args matchExpr.args mapIn) where
  coe := mapOut.toArgResult

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 main14_logical_after := [llvm|
{
^0(%arg15 : i32):
  %0 = llvm.mlir.constant(32896 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(2 : i32) : i32
  %3 = llvm.mlir.constant(1 : i32) : i32
  %4 = llvm.and %arg15, %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 test28_sub_before := [llvm|
{
^0(%arg175 : i32):
  %0 = llvm.mlir.constant(-2147483647 : i32) : i32
  %1 = llvm.mlir.constant(-2147483648 : i32) : i32
  %2 = llvm.sub %0, %arg175 : i32
  %3 = llvm.xor %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def different_size_zext_zext_ult_before := [llvm|
{
^0(%arg24 : i4, %arg25 : i7):
  %0 = llvm.zext %arg24 : i4 to i25
  %1 = llvm.zext %arg25 : i7 to i25
  %2 = llvm.icmp "ult" %0, %1 : i25
  "llvm.return"(%2) : (i1) -> ()
}
]

def not_and_and_or_no_or_commute1_after := [llvm|
{
^0(%arg154 : i32, %arg155 : i32, %arg156 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg154, %0 : i32
  %2 = llvm.xor %arg155, %0 : i32
  %3 = llvm.or %arg156, %2 : i32
  %4 = llvm.and %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

instance : HydrableExistsForall ParsedBVExpr GenBVPred GenBVExpr where

def ashr_lshr_shift_wrong_pred_before := [llvm|
{
^0(%arg82 : i32, %arg83 : i32, %arg84 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "sle" %arg82, %0 : i32
  %2 = llvm.lshr %arg82, %arg83 : i32
  %3 = llvm.ashr %arg82, %arg83 : i32
  %4 = "llvm.select"(%1, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

def masked_bit_clear_commute_after := [llvm|
{
^0(%arg77 : i32, %arg78 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.srem %0, %arg77 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.lshr %4, %arg78 : i32
  %6 = llvm.and %5, %2 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

@[simp_denote]
def llvmArgsFromHybrid_nil_eq :
  (llvmArgsFromHybrid HVector.nil) = HVector.nil := rfl

Lean.Meta.getOfNatValue? in Lean.Meta.LitValues

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 lshrult_03_15_exact_after := [llvm|
{
^0(%arg102 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def test_after := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.icmp "ugt" %arg1, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

def MetaLLVM.printAttributes : (MetaLLVM φ).Op → String
  | .const w v => s!"\{value = {v} : {w}}"
  | .or w ⟨true⟩ => s!"\{disjoint = true : {w}}"
  | .add _ f | .shl _ f | .sub _ f | .mul _ f => printOverflowFlags f
  | .udiv _ ⟨true⟩ | .sdiv _ ⟨true⟩ | .lshr _ ⟨true⟩ => "<{isExact}> "
  | _ => ""
where
  printOverflowFlags : NoWrapFlags → String
  | ⟨false, false⟩ => "<{overflowFlags = #llvm.overflow<none>}>"
  
  
  | ⟨true, false⟩  => "<{overflowFlags = #llvm.overflow<nsw>}>"
  | ⟨false, true⟩  => "<{overflowFlags = #llvm.overflow<nuw>}>"
  | ⟨true, true⟩   => "<{overflowFlags = #llvm.overflow<nsw,nuw>}>"

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

def foo1_or_signbit_lshr_without_shifting_signbit_after := [llvm|
{
^0(%arg112 : i32, %arg113 : i32, %arg114 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %0, %arg113 overflow<nuw> : i32
  %3 = llvm.and %2, %arg112 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  %5 = llvm.shl %arg112, %arg114 : i32
  %6 = llvm.icmp "slt" %5, %1 : i32
  %7 = llvm.and %4, %6 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

instance : DialectSignature HSxComb where
  signature := fun op =>
    match op with
    | .comb o => liftSig (signature o) 
    
    
    | .hs o => MLIR2Handshake.instDialectSignatureHandshake.signature o

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 lshr_and_after := [llvm|
{
^0(%arg73 : i8, %arg74 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(6 : i8) : i8
  %2 = llvm.srem %arg73, %0 : i8
  %3 = llvm.shl %2, %1 : i8
  %4 = llvm.and %arg74, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

@[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

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

def generatePreconditions (bvLogicalExpr: BoolExpr GenBVPred) (positiveExamples negativeExamples: List (Std.HashMap Nat BVExpr.PackedBitVec))
              (_numConjunctions: Nat) : GeneralizerStateM ParsedBVExpr GenBVPred (Option (BoolExpr GenBVPred)) := do

    let state ← get
    let widthId := state.widthId

    let validCandidates ← withTraceNode `Generalize (fun _ => return "Attempted to generate valid preconditions") do
      let mut preconditionCandidates : Std.HashSet (BoolExpr GenBVPred) := Std.HashSet.emptyWithCapacity

      
      for (const, val) in positiveExamples[0]!.toArray do
        let bvExprVar := GenBVExpr.var const
        let powerOf2Expr :=  GenBVExpr.bin bvExprVar BVBinOp.and (GenBVExpr.bin bvExprVar BVBinOp.add (minusOne val.w))
        let powerOfTwoResults := positiveExamples.map (λ pos => evalBVExpr pos powerOf2Expr)

        if powerOfTwoResults.any (λ val => val == 0) then
          let powerOf2 := BoolExpr.literal (GenBVPred.bin powerOf2Expr BVBinPred.eq (zero val.w))
          preconditionCandidates := preconditionCandidates.insert powerOf2

      let mut bitwidth := negativeExamples[0]!.values[0]!.w 

      let specialConstants : Std.HashMap (GenBVExpr bitwidth) BVExpr.PackedBitVec := Std.HashMap.ofList [
      ((one bitwidth), {bv := BitVec.ofNat bitwidth 1}),
      ((minusOne bitwidth), {bv := BitVec.ofInt bitwidth (-1)}),
      (GenBVExpr.var widthId, {bv := BitVec.ofNat bitwidth bitwidth})]

      let synthesisComponents : Std.HashMap (GenBVExpr bitwidth)  PreconditionSynthesisCacheValue := getPreconditionSynthesisComponents positiveExamples negativeExamples specialConstants
      let mut previousLevelCache : Std.HashMap (GenBVExpr bitwidth) PreconditionSynthesisCacheValue := synthesisComponents

      let numVariables := positiveExamples[0]!.keys.length + 1 
      let ops : List (GenBVExpr bitwidth -> GenBVExpr bitwidth -> GenBVExpr bitwidth):= [add, subtract, multiply, and, or, xor, shiftLeft, shiftRight, arithShiftRight]

      let mut currentLevel := 0
      let mut validCandidates : List (BoolExpr GenBVPred) := []
      let mut visited : Std.HashSet (BoolExpr GenBVPred) := Std.HashSet.emptyWithCapacity

      while currentLevel < numVariables do
          logInfo m! "Precondition Synthesis: Processing level {currentLevel}"

          let origCandidatesSize := preconditionCandidates.size
          for (bvExpr, intermediateRes) in previousLevelCache.toArray do
            let evaluatedNegativeExs := intermediateRes.negativeExampleValues.map (λ ex => ex.bv.toInt)
            let evaluatedPositiveExs := intermediateRes.positiveExampleValues.map (λ ex => ex.bv.toInt)

            if (evaluatedPositiveExs.all ( λ val => val == 0)) && evaluatedNegativeExs.all (λ val => val != 0) then
              preconditionCandidates := preconditionCandidates.insert (eqToZero bvExpr)
              continue

            if (evaluatedPositiveExs.any ( λ val => val < 0 || val == 0)) && evaluatedNegativeExs.all (λ val => val > 0) then
              let mut cand := lteZero bvExpr widthId
              if (evaluatedPositiveExs.all ( λ val => val < 0)) then
                cand := strictlyLTZero bvExpr widthId

              preconditionCandidates := preconditionCandidates.insert cand

            if (evaluatedPositiveExs.any ( λ val => val > 0 || val == 0)) && evaluatedNegativeExs.all (λ val => val < 0) then
              let mut cand := gteZero bvExpr widthId
              if (evaluatedPositiveExs.all ( λ val => val > 0)) then
                  cand := strictlyGTZero bvExpr widthId

              preconditionCandidates := preconditionCandidates.insert cand

          
          if preconditionCandidates.size > origCandidatesSize then
            validCandidates ← filterCandidatePredicates bvLogicalExpr preconditionCandidates visited
            match validCandidates with
            | [] => visited := preconditionCandidates
            | _ => return validCandidates

          checkTimeout

          previousLevelCache ← precondSynthesisUpdateCache previousLevelCache synthesisComponents positiveExamples negativeExamples specialConstants ops
          currentLevel := currentLevel + 1

      pure validCandidates

    if validCandidates.isEmpty then
      return none

    if validCandidates.length == 1 then
      return validCandidates[0]?

    
    let prunedResults ← pruneEquivalentBVLogicalExprs validCandidates
    match prunedResults with
    | [] => return none
    | _ =>  return some (bigOr prunedResults)

def and_orn_cmp_1_before := [llvm|
{
^0(%arg194 : i32, %arg195 : i32, %arg196 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.icmp "sgt" %arg194, %arg195 : i32
  %2 = llvm.icmp "sle" %arg194, %arg195 : i32
  %3 = llvm.icmp "ugt" %arg196, %0 : i32
  %4 = llvm.or %3, %2 : i1
  %5 = llvm.and %1, %4 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def t15_before := [llvm|
{
^0(%arg198 : i32, %arg199 : i32):
  %0 = llvm.shl %arg198, %arg199 overflow<nuw> : i32
  %1 = llvm.udiv %0, %arg198 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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 icmp_eq_or_z_or_pow2orz_fail_bad_pred2_after := [llvm|
{
^0(%arg6 : i8, %arg7 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.sub %0, %arg7 : i8
  %3 = llvm.and %arg7, %2 : i8
  %4 = llvm.icmp "slt" %arg6, %1 : i8
  %5 = llvm.icmp "sle" %arg6, %3 : i8
  %6 = llvm.or %4, %5 : i1
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

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

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

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

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

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

instance : TyDenote Ty where toType := Ty.toType

def binop_left_to_zero_srem : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (0) : i64
      %0 = llvm.srem %c, %x : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (0) : i64
      llvm.return %c : i64
  }]

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

@[simp_denote]
def add_shl_moreOneUse_sh4add_riscv := [LV| {
    ^entry (%a: i64):
    %a0 = "builtin.unrealized_conversion_cast" (%a) : (i64) -> (!i64)
    %0 = ori %a0, 1 : !i64
    %1 = slli %a0, 4 : !i64
    %2 = ori %1, 16 : !i64
    %3 = add %2, %0 : !i64
    %4 = "builtin.unrealized_conversion_cast" (%3) : (!i64) -> (i64)
    llvm.return %4 : i64
  }]

def shl_mul_mask_wrong_mul_const_before := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.mlir.constant(65535 : i32) : i32
  %2 = llvm.mlir.constant(8 : i32) : i32
  %3 = llvm.and %arg0, %0 : i32
  %4 = llvm.mul %3, %1 : i32
  %5 = llvm.shl %3, %2 : i32
  %6 = llvm.or %4, %5 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def shl_add_lshr_comm_after := [llvm|
{
^0(%arg151 : i32, %arg152 : i32, %arg153 : i32):
  %0 = llvm.mul %arg153, %arg153 : i32
  %1 = llvm.lshr %0, %arg152 : i32
  %2 = llvm.add %1, %arg151 overflow<nuw> : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

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 test15a_before := [llvm|
{
^0(%arg27 : i32):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg27, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  %4 = "llvm.select"(%3, %1, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def ugt_and_min_before := [llvm|
{
^0(%arg336 : i8, %arg337 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "ugt" %arg336, %arg337 : i8
  %2 = llvm.icmp "eq" %arg336, %0 : i8
  %3 = llvm.and %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def test_add_mul_neg_one_lhs_LHS := [mod_arith q, hq| {
  ^bb0(%x : !R, %y : !R):
    %neg_one = mod_arith.constant 41 : !R
    %mul = mod_arith.mul %neg_one, %x : !R
    %add = mod_arith.add %mul, %y : !R
    return %add : !R
}]

def lshr_and_after := [llvm|
{
^0(%arg59 : i64, %arg60 : i64):
  %0 = llvm.mlir.constant(42) : i64
  %1 = llvm.mlir.constant(12) : i64
  %2 = llvm.mlir.constant(7) : i64
  %3 = llvm.srem %arg60, %0 : i64
  %4 = llvm.lshr %arg59, %1 : i64
  %5 = llvm.lshr %3, %2 : i64
  %6 = llvm.and %4, %5 : i64
  "llvm.return"(%6) : (i64) -> ()
}
]

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 fold_zext_xor_sandwich_after := [llvm|
{
^0(%arg188 : i1):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.zext %arg188 : i1 to i32
  %2 = llvm.xor %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def xor_lshr_multiuse_after := [llvm|
{
^0(%arg596 : i8, %arg597 : i8, %arg598 : i8, %arg599 : i8):
  %0 = llvm.lshr %arg596, %arg599 : i8
  %1 = llvm.xor %0, %arg598 : i8
  %2 = llvm.xor %arg596, %arg597 : i8
  %3 = llvm.lshr %2, %arg599 : i8
  %4 = llvm.xor %3, %arg598 : i8
  %5 = llvm.sdiv %1, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

@[simp, reducible]
def Op.outTy : Op q n → Ty q n
| Op.add | Op.sub | Op.mul | Op.mul_constant | Op.leading_term | Op.monomial
| Op.monomial_mul | Op.from_tensor | Op.const _  => Ty.polynomialLike
| Op.to_tensor => Ty.tensor
| Op.const_int _ => Ty.integer
| Op.const_idx _ => Ty.index

def mul_of_pow2_after := [llvm|
{
^0(%arg83 : i32, %arg84 : i8):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

def eq_21_comm_and_before := [llvm|
{
^0(%arg122 : i32, %arg123 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.lshr %arg122, %0 : i32
  %3 = llvm.trunc %2 : i32 to i8
  %4 = llvm.lshr %arg122, %1 : i32
  %5 = llvm.trunc %4 : i32 to i8
  %6 = llvm.lshr %arg123, %0 : i32
  %7 = llvm.trunc %6 : i32 to i8
  %8 = llvm.lshr %arg123, %1 : i32
  %9 = llvm.trunc %8 : i32 to i8
  %10 = llvm.icmp "eq" %3, %7 : i8
  %11 = llvm.icmp "eq" %5, %9 : i8
  %12 = llvm.and %10, %11 : i1
  "llvm.return"(%12) : (i1) -> ()
}
]

def t0_sub_from_trueval_before := [llvm|
{
^0(%arg13 : i1, %arg14 : i8, %arg15 : i8):
  %0 = "llvm.select"(%arg13, %arg14, %arg15) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %1 = llvm.sub %arg14, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

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

def subtract (op1 : GenBVExpr w) (op2 : GenBVExpr w) : GenBVExpr w :=
  add op1 (negate op2)

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

def shift_xor_multiuse_cmp_xor_after := [llvm|
{
^0(%arg32 : i32, %arg33 : i32, %arg34 : i32, %arg35 : 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 %arg32, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.xor %arg33, %2 : i32
  %6 = "llvm.select"(%4, %5, %arg33) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg35, %arg34) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %8 = llvm.mul %6, %7 : i32
  %9 = llvm.mul %8, %5 : i32
  "llvm.return"(%9) : (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) -> ()
}
]

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

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

def eq_umax2_before := [llvm|
{
^0(%arg58 : i32, %arg59 : i32):
  %0 = llvm.icmp "ugt" %arg59, %arg58 : i32
  %1 = "llvm.select"(%0, %arg59, %arg58) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %2 = llvm.icmp "eq" %1, %arg58 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

def t10_shl_nuw_flag_preservation_before := [llvm|
{
^0(%arg23 : i32, %arg24 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(-2 : i32) : i32
  %2 = llvm.sub %0, %arg24 : i32
  %3 = llvm.shl %arg23, %2 overflow<nuw> : i32
  %4 = llvm.add %arg24, %1 : i32
  %5 = llvm.shl %3, %4 overflow<nsw,nuw> : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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 lshrugt_02_14_exact_before := [llvm|
{
^0(%arg191 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.mlir.constant(-2 : i4) : i4
  %2 = llvm.lshr exact %arg191, %0 : i4
  %3 = llvm.icmp "ugt" %2, %1 : i4
  "llvm.return"(%3) : (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 ashr_ult_0_before := [llvm|
{
^0(%arg98 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(0 : i4) : i4
  %2 = llvm.ashr %arg98, %0 : i4
  %3 = llvm.icmp "ult" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def t0_before := [llvm|
{
^0(%arg30 : i1, %arg31 : i8, %arg32 : i8, %arg33 : i8, %arg34 : i8):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.icmp "eq" %arg31, %arg32 : i8
  %2 = llvm.xor %arg30, %0 : i1
  %3 = llvm.or %2, %1 : i1
  %4 = "llvm.select"(%3, %arg33, %arg34) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def test2_after := [llvm|
{
^0(%arg3 : i39, %arg4 : i39):
  %0 = llvm.mlir.constant(-274877906944 : i39) : i39
  %1 = llvm.and %arg4, %0 : i39
  %2 = llvm.add %arg3, %1 : i39
  "llvm.return"(%2) : (i39) -> ()
}
]

def add_mask_sign_commute_i32_before := [llvm|
{
^0(%arg5 : i32):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.ashr %arg5, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.add %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

Lean.initSearchPath in Lean.Util.Path

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 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) -> ()
}
]

Lean.Syntax.SepArray.ofElems in Init.Meta.Defs

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

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 Expr.mkVerifyCircuit (c cert : Expr) : MetaM Expr :=
  mkAppM ``Circuit.verifyCircuit #[c, cert]

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

instance : Lean.ToExpr RegIndex := inherit

def negative_not_next_power_of_two_logical_before := [llvm|
{
^0(%arg4 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(64 : i32) : i32
  %2 = llvm.mlir.constant(256 : i32) : i32
  %3 = llvm.mlir.constant(false) : i1
  %4 = llvm.icmp "sgt" %arg4, %0 : i32
  %5 = llvm.add %arg4, %1 : i32
  %6 = llvm.icmp "ult" %5, %2 : i32
  %7 = "llvm.select"(%4, %6, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%7) : (i1) -> ()
}
]

def main14_before := [llvm|
{
^0(%arg16 : i32):
  %0 = llvm.mlir.constant(0 : i16) : i16
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.mlir.constant(2 : i32) : i32
  %3 = llvm.mlir.constant(1 : i32) : i32
  %4 = llvm.trunc %arg16 : i32 to i16
  %5 = llvm.icmp "sge" %4, %0 : i16
  %6 = llvm.trunc %arg16 : i32 to i8
  %7 = llvm.icmp "sge" %6, %1 : i8
  %8 = llvm.and %5, %7 : i1
  %9 = "llvm.select"(%8, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%9) : (i32) -> ()
}
]

AList.insert in Mathlib.Data.List.AList

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

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

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 shl_nsw_sgt_n1_before := [llvm|
{
^0(%arg18 : i8, %arg19 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.shl %arg18, %arg19 overflow<nsw> : i8
  %2 = llvm.icmp "sgt" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

@[simp_denote]
def lshr_llvm_exact_64 := [LV| {
  ^entry (%x: i64, %amount: i64):
    %1 = llvm.lshr exact %x, %amount : i64
    llvm.return %1 : i64
  }]

@[simp_denote]
def sext_llvm_i32_to_64 := [LV| {
  ^entry (%arg: i32):
    %0 = llvm.sext %arg: i32 to i64
    llvm.return %0: i64
  }]

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

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 sndVal {r} {Γ : Ctxt _} (a : Γ.Var (.valuetokenstream r))  : Expr (DC) Γ .pure (.tokenstream)  :=
  Expr.mk
    (op := .sndVal r)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .cons a <| .nil)
    (regArgs := .nil)

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

def t7_after := [llvm|
{
^0(%arg181 : i8, %arg182 : i1, %arg183 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.shl %0, %arg183 overflow<nsw> : i8
  %3 = "llvm.select"(%arg182, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = llvm.add %3, %arg181 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

def test6_before := [llvm|
{
^0(%arg204 : i8):
  %0 = llvm.mlir.constant(17 : i8) : i8
  %1 = llvm.xor %arg204, %0 : i8
  %2 = llvm.xor %1, %0 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def and_logic_and_logic_or_5_before := [llvm|
{
^0(%arg126 : i1, %arg127 : i1, %arg128 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.and %arg126, %arg127 : i1
  %3 = "llvm.select"(%arg126, %arg128, %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 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 lshrult_01_09_exact_after := [llvm|
{
^0(%arg140 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def elabIntoCom (region : TSyntax `mlir_region) (d : Q(Dialect)) {φ : Q(Nat)}
    (_dialectSignature : Q(DialectSignature $d) := by admit /- proof elided -/
    )
    (_transformTy      : Q(TransformTy $d $φ)     := by admit /- proof elided -/
    )
    (_transformExpr    : Q(TransformExpr $d $φ)   := by admit /- proof elided -/
    )
    (_transformReturn  : Q(TransformReturn $d $φ) := by admit /- proof elided -/
    ) :
    TermElabM Expr := do
  let com : Q(ExceptM $d (Σ Γ' eff ty, Com $d Γ' eff ty)) ←
    withTraceNode `LeanMLIR.Elab (return m!"{exceptEmoji ·} building `Com` expression") <| do
    let ast_stx ← `([mlir_region| $region])
    let ast ← elabTermEnsuringTypeQ ast_stx q(Region $φ)
    return q(MLIR.AST.mkCom $ast)
  withTraceNode `LeanMLIR.Elab (return m!"{exceptEmoji ·} synthesizingMVars") <|
    synthesizeSyntheticMVarsNoPostponing

  withTraceNode `LeanMLIR.Elab (return m!"{exceptEmoji ·} unwrapping `Com` expression") <| do
     
    let com : Q(ExceptM $d (Σ Γ' eff ty, Com $d Γ' eff ty)) ← whnf com
    match com.app3? ``Except.ok with
    | .some (_εexpr, _αexpr, expr) =>
        let (expr : Q(Σ Γ eff ty, Com $d Γ eff ty)) ← whnf expr
        match expr.app4? ``Sigma.mk with
        | .some (_αexpr, _βexpr, (_Γ : Q(Ctxt ($d).Ty)), expr) =>
          let (expr : Q(Σ eff ty, Com $d $_Γ eff ty)) ← whnf expr
          match expr.app4? ``Sigma.mk with
          | .some (_αexpr, _βexpr, (_eff : Q(EffectKind)), expr) =>
            match expr.app4? ``Sigma.mk with
            | .some (_αexpr, _βexpr, (_ty : Q(List ($d).Ty)), (com : Q(Com $d $_Γ $_eff $_ty))) =>
                 
                withTraceNode `LeanMLIR.Elab (return m!"{exceptEmoji ·} reducing `Com` expression") <|
                  comNf com
            | .none => throwError "Expected (Sigma.mk _ _), found {expr}"
          | .none => throwError "Expected (Sigma.mk _ _), found {expr}"
        | .none => throwError "Expected (Sigma.mk _ _), found {expr}"
    | .none => throwError "Expected `Except.ok`, found {com}"

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) -> ()
}
]

@[nospecialize]
partial def decideIfZerosAuxVerified' {arity : Type _}
    [DecidableEq arity] [Fintype arity] [Hashable arity]
    (iter : Nat) (maxIter : Nat) (startVerifyAtIter : Nat := 0)
    (fsm : FSM arity)
    (circs : KInductionCircuits fsm iter)
    (stats : Array CircuitStats) :
    TermElabM (DecideIfZerosOutput × Array CircuitStats) := do
  withTraceNode `trace.Bits.Fast (fun _ => return s!"K-induction (iter={iter})") do
    if iter ≥ maxIter && maxIter != 0 then
      return (.exhaustedIterations maxIter, stats.push circs.stats)
    let tStart ← IO.monoMsNow
    let cSafety : Circuit (Vars fsm.α arity (iter+2)) := circs.mkSafetyCircuit
    let tEnd ← IO.monoMsNow
    let tElapsedMs := (tEnd - tStart)
    trace[Bits.FastVerif] m!"Built new safety circuit in '{tElapsedMs}ms'"
    trace[Bits.FastVerif] m!"safety circuit size : {cSafety.size}"
    trace[Bits.FastVerif] s!"Building induction circuit..."
    let tStart ← IO.monoMsNow
    let cIndHyp := circs.mkIndHypCycleBreaking
    let tEnd ← IO.monoMsNow
    let tElapsedMs := (tEnd - tStart)
    trace[Bits.FastVerif] m!"Built induction circuit in '{tElapsedMs}ms'"


    if iter < startVerifyAtIter then
      trace[Bits.FastVerif] s!"Skipping inductive invariant check until iteration {startVerifyAtIter}."
      decideIfZerosAuxVerified' (iter + 1) maxIter startVerifyAtIter fsm  circs.mkSucc (stats.push circs.stats)
    else
      trace[Bits.FastVerif] s!"Verifying safety property..."
      let tStart ← IO.monoMsNow
      let safetyCert? ← Circuit.checkCircuitUnsatAux cSafety
      let tEnd ← IO.monoMsNow
      let tElapsedMs := (tEnd - tStart)
      trace[Bits.FastVerif] m!"Established safety property in {tElapsedMs}ms (iter={iter})."
      match safetyCert? with
      | .none =>
        trace[Bits.FastVerif] s!"Safety property failed on initial state."
        return (.safetyFailure iter, stats.push circs.stats)
      | .some safetyCert =>
        trace[Bits.FastVerif] s!"Safety property established (iter={iter})."
        trace[Bits.FastVerif] s!"Establishing Inductive Invariant..."
        let tStart ← IO.monoMsNow
        let indCert? ← Circuit.checkCircuitUnsatAux cIndHyp
        let tEnd ← IO.monoMsNow
        let tElapsedMs := (tEnd - tStart)
        trace[Bits.FastVerif] s!"Checked inductive invariant in '{tElapsedMs}ms'."
        match indCert? with
        | .some indCert =>
          trace[Bits.FastVerif] s!"Inductive invariant established (iter={iter})."
          return (.provenByKIndCycleBreaking iter safetyCert indCert, stats.push circs.stats)
        | .none =>
          trace[Bits.FastVerif] s!"Unable to establish inductive invariant. Trying next iteration ({iter+1})..."
        decideIfZerosAuxVerified' (iter + 1) maxIter startVerifyAtIter fsm  circs.mkSucc (stats.push circs.stats)

def or_nosignbit_select_lshr_before := [llvm|
{
^0(%arg24 : i32, %arg25 : i1):
  %0 = llvm.mlir.constant(2147418112 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.or %arg24, %0 : i32
  %3 = "llvm.select"(%arg25, %2, %arg24) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.lshr %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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 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 select_non_const_sides_after := [llvm|
{
^0(%arg9 : i1, %arg10 : i64, %arg11 : i64):
  %0 = llvm.mlir.constant(-1) : i64
  %1 = llvm.add %arg10, %0 : i64
  %2 = "llvm.select"(%arg9, %1, %arg11) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%2) : (i64) -> ()
}
]

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

def sameBothSides (bvLogicalExpr : (BoolExpr GenBVPred)) : Bool :=
    match bvLogicalExpr with
  | .literal (GenBVPred.bin lhs _ rhs) => lhs == rhs
  | _ => false

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

def ripple_nsw2_after := [llvm|
{
^0(%arg21 : i16, %arg22 : i16):
  %0 = llvm.mlir.constant(1 : i16) : i16
  %1 = llvm.mlir.constant(-16385 : i16) : i16
  %2 = llvm.and %arg22, %0 : i16
  %3 = llvm.and %arg21, %1 : i16
  %4 = llvm.add %3, %2 overflow<nsw,nuw> : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

def to_loop_run (δ : Int) (f : LoopBody α) (niters : ℕ) (val : α) : α :=
  (counterDecorator δ f (niters,val)).2

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 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) -> ()
}
]

def test43_before := [llvm|
{
^0(%arg145 : i8):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.zext %arg145 : i8 to i32
  %2 = llvm.add %1, %0 : i32
  %3 = llvm.sext %2 : i32 to i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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

def xor_ugt_2_before := [llvm|
{
^0(%arg13 : i8, %arg14 : i8, %arg15 : i8):
  %0 = llvm.mlir.constant(63 : i8) : i8
  %1 = llvm.mlir.constant(64 : i8) : i8
  %2 = llvm.add %arg13, %arg15 : i8
  %3 = llvm.and %arg14, %0 : i8
  %4 = llvm.or %3, %1 : i8
  %5 = llvm.xor %2, %4 : i8
  %6 = llvm.icmp "ugt" %2, %5 : i8
  "llvm.return"(%6) : (i1) -> ()
}
]

instance instTransformTy : MLIR.AST.TransformTy DC 0 where
  mkTy := mkTy

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

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

def xor_to_xor2_after := [llvm|
{
^0(%arg83 : i32, %arg84 : i32):
  %0 = llvm.xor %arg83, %arg84 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def sink {Γ : Ctxt _} (a : Γ.Var (MLIR2DCPlus.Ty.tokenstream)) : Expr (DCPlus) Γ .pure (.tokenstream) :=
  Expr.mk
    (op := .sink)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .cons a <| .nil)
    (regArgs := .nil)

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

def mul_add_to_mul_7_after := [llvm|
{
^0(%arg25 : i16):
  %0 = llvm.mlir.constant(15 : i16) : i16
  %1 = llvm.shl %arg25, %0 : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

def add64_accept_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := add64_accept_llvm
  rhs := add64_accept_riscv

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

Int.succ in Mathlib.Data.Int.Init

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

def lshr_lshr_pow2_const_negative_overflow_before := [llvm|
{
^0(%arg61 : i16):
  %0 = llvm.mlir.constant(-32768 : i16) : i16
  %1 = llvm.mlir.constant(15 : i16) : i16
  %2 = llvm.mlir.constant(4 : i16) : i16
  %3 = llvm.lshr %0, %arg61 : i16
  %4 = llvm.lshr %3, %1 : i16
  %5 = llvm.and %4, %2 : i16
  "llvm.return"(%5) : (i16) -> ()
}
]

def main7c_logical_after := [llvm|
{
^0(%arg69 : i32, %arg70 : i32, %arg71 : i32):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.and %arg70, %arg69 : i32
  %2 = llvm.icmp "ne" %arg70, %1 : i32
  %3 = llvm.and %arg71, %arg69 : i32
  %4 = llvm.icmp "ne" %arg71, %3 : i32
  %5 = "llvm.select"(%2, %0, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %6 = llvm.zext %5 : i1 to i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def RawCNFA.empty : RawCNFA A := {
  stateMax := 0
  initials := ∅
  finals := ∅
  trans := ∅
}

def positive_biggershl_shlnuwnsw_before := [llvm|
{
^0(%arg44 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(6 : i8) : i8
  %2 = llvm.ashr %arg44, %0 : i8
  %3 = llvm.shl %2, %1 overflow<nsw,nuw> : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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

def lshr_or_and_before := [llvm|
{
^0(%arg152 : i8, %arg153 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.mlir.constant(-58 : i8) : i8
  %2 = llvm.lshr %arg152, %0 : i8
  %3 = llvm.lshr %arg153, %0 : i8
  %4 = llvm.or %2, %1 : i8
  %5 = llvm.and %4, %3 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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 n14_trunc_of_lshr_after := [llvm|
{
^0(%arg4 : i64, %arg5 : i32, %arg6 : 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, %arg6 : i32
  %4 = llvm.zext nneg %3 : i32 to i64
  %5 = llvm.lshr %arg4, %4 : i64
  %6 = llvm.trunc %5 : i64 to i32
  %7 = llvm.add %arg6, %1 : i32
  %8 = llvm.shl %arg5, %7 : i32
  %9 = llvm.and %8, %6 : i32
  %10 = llvm.icmp "ne" %9, %2 : i32
  "llvm.return"(%10) : (i1) -> ()
}
]

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

def PoisonOr.getOrUB  : PoisonOr α → m α
  | .value x => pure x
  | .poison => throwUB

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

inductive TransformError
  | nameAlreadyDeclared (var : String)
  | undeclaredName (var : String)
  | indexOutOfBounds (name : String) (index len : Nat)
  | typeError (expected got : String)
  | widthError {φ} (expected got : Width φ)
  
  
  | unsupportedUnaryOp
  | unsupportedBinaryOp (error : String)
  | unsupportedOp (error : String)
  | unsupportedType
  | generic (error : String)

instance : Preorder (Circuit α) :=
  { inferInstanceAs (LE (Circuit α)) with
    le_refl := λ c f h => h,
    le_trans := λ c₁ c₂ c₃ h₁₂ h₂₃ f h₁ => h₂₃ f (h₁₂ f h₁) }

@[simp_denote]
def zext_riscv_1_to_8 := [LV| {
  ^entry (%arg: i1):
    %0 = "builtin.unrealized_conversion_cast"(%arg) : (i1) -> !i64
    %1 = andi %0, 1 : !i64
    %res = "builtin.unrealized_conversion_cast"(%1) : (!i64) -> (i8)
    llvm.return %res: i8
  }]

def xor_of_icmps_to_ne_commute_before := [llvm|
{
^0(%arg28 : i64):
  %0 = llvm.mlir.constant(4) : i64
  %1 = llvm.mlir.constant(6) : i64
  %2 = llvm.icmp "sgt" %arg28, %0 : i64
  %3 = llvm.icmp "slt" %arg28, %1 : i64
  %4 = llvm.xor %3, %2 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def not_add_before := [llvm|
{
^0(%arg124 : i32):
  %0 = llvm.mlir.constant(123 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.add %arg124, %0 : i32
  %3 = llvm.xor %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

@[simp_denote]
def zext_riscv_8_to_32 := [LV| {
  ^entry (%arg: i8):
    %0 = "builtin.unrealized_conversion_cast"(%arg) : (i8) -> (!i64)
    %1 = zext.b %0 : !i64
    %res = "builtin.unrealized_conversion_cast"(%1) : (!i64) -> (i32)
    llvm.return %res : i32
  }]

def addhshlhsdivhnegative0_before := [llvm|
{
^0(%arg8 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.sdiv %arg8, %0 : i8
  %3 = llvm.shl %2, %1 : i8
  %4 = llvm.add %3, %arg8 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

def sel_zext_constants_before := [llvm|
{
^0(%arg96 : i1):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(42 : i8) : i8
  %2 = "llvm.select"(%arg96, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %3 = llvm.zext %2 : i8 to i16
  "llvm.return"(%3) : (i16) -> ()
}
]

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

def reassoc_add_nuw_before := [llvm|
{
^0(%arg26 : i32):
  %0 = llvm.mlir.constant(4 : i32) : i32
  %1 = llvm.mlir.constant(64 : i32) : i32
  %2 = llvm.add %arg26, %0 overflow<nuw> : i32
  %3 = llvm.add %2, %1 overflow<nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def not_or_or_and_not_and_and_commute2_after := [llvm|
{
^0(%arg190 : i32, %arg191 : i32, %arg192 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg192 : i32
  %3 = llvm.xor %arg190, %1 : i32
  %4 = llvm.xor %2, %arg191 : i32
  %5 = llvm.or %4, %3 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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 add_signbit_select_shl_after := [llvm|
{
^0(%arg34 : i32, %arg35 : i1):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(-16777216 : i32) : i32
  %2 = llvm.shl %arg34, %0 : i32
  %3 = llvm.add %2, %1 : i32
  %4 = "llvm.select"(%arg35, %3, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def test18_before := [llvm|
{
^0(%arg16 : i11):
  %0 = llvm.mlir.constant(10 : i11) : i11
  %1 = llvm.mlir.constant(123 : i11) : i11
  %2 = llvm.lshr %arg16, %0 : i11
  %3 = llvm.icmp "eq" %2, %1 : i11
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

Lean.findSysroot in Lean.Util.Path

def test1_before := [llvm|
{
^0(%arg3 : i33):
  %0 = llvm.mlir.constant(4096 : i33) : i33
  %1 = llvm.urem %arg3, %0 : i33
  "llvm.return"(%1) : (i33) -> ()
}
]
</all_available_defs>

<all_available_lemmas>
Nat.add_comm in Init.Data.Nat.Basic
Fin.add_def in Init.Data.Fin.Lemmas
Fin.castLE_castLE in Init.Data.Fin.Lemmas
Nat.le_of_eq in Init.Data.Nat.Basic
Nat.mod_eq_of_lt in Init.Data.Nat.Div.Basic

@[simp]
lemma List.Vector.append_get_ge {x : List.Vector α n} {y : List.Vector α m} {i : Fin (n+m)} (hlt: n ≤ i) :
    (x ++ y).get i = y.get ((i.cast (Nat.add_comm n m) |>.subNat n hlt))

@[simp]
lemma List.Vector.append_get_lt {x : List.Vector α n} {y : List.Vector α m} {i : Fin (n+m)} (hlt: i < n) :
    (x ++ y).get i = x.get (i.castLT hlt)

@[ext]
theorem ext {x y : BitStream} (h : ∀ i, x i = y i) : x = y

theorem demorgan_or_apint2_thm (e e_1 : IntW 129) :
  LLVM.or (LLVM.xor e_1 (const? 129 (-1))) (LLVM.xor e (const? 129 (-1))) ⊑
    LLVM.xor (LLVM.and e_1 e) (const? 129 (-1))

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 bools2_logical_commute1_thm.extracted_1._17 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 = 1#1 → x_1 ^^^ 1#1 = 1#1 → ¬x_1 = 1#1 → 0#1 = 1#1 → 1#1 = x

theorem not_logicalOr_not_op1_proof : not_logicalOr_not_op1_before ⊑ not_logicalOr_not_op1_after

theorem test12_proof : test12_before ⊑ test12_after

theorem one_side_fold_eq_thm.extracted_1._7 : ∀ (x x_1 : BitVec 32) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → ¬x_2 ^^^ 1#1 = 1#1 → False

theorem test2_thm.extracted_1._1 : ∀ (x : BitVec 49),
  ¬(11#49 ≥ ↑49 ∨ 4096#49 <<< 11#49 = 0) → x % 4096#49 <<< 11#49 = x &&& 8388607#49

theorem trunc_ashr_thm (e : IntW 32) :
  trunc 32 (ashr (LLVM.or (zext 36 e) (const? 36 (-2147483648))) (const? 36 8)) ⊑
    LLVM.or (lshr e (const? 32 8)) (const? 32 (-8388608))

theorem ashr_C1_add_A_C2_i32_proof : ashr_C1_add_A_C2_i32_before ⊑ ashr_C1_add_A_C2_i32_after

theorem main3e_like_logical_thm.extracted_1._4 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& x == 0#32) = 1#1 → ¬ofBool (x_1 &&& x != 0#32) = 1#1 → ¬0#1 = 1#1 → False

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 i_proof : i_before ⊑ i_after

theorem min_of_max_thm (e : IntW 32) :
  select
      (icmp IntPred.slt
        (select (icmp IntPred.slt e (const? 32 0)) (LLVM.xor e (const? 32 (-1))) (const? 32 (-1)))
        (const? 32 (-1)))
      (select (icmp IntPred.slt e (const? 32 0)) (LLVM.xor e (const? 32 (-1))) (const? 32 (-1))) (const? 32 (-1)) ⊑
    const? 32 (-1)

theorem ashr_ult_14_proof : ashr_ult_14_before ⊑ ashr_ult_14_after

theorem samesign_commute1_proof : samesign_commute1_before ⊑ samesign_commute1_after

theorem e_2321 :
     - 11 *  ~~~(e ^^^ f) + 2 * (e ^^^ (d &&& (e ^^^ f))) + 2 * ( ~~~f |||  ~~~(d ^^^ e)) - 11 * ( ~~~d ||| (e ||| f)) + 3 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 7 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 3 * (f &&&  ~~~(d &&& e)) - 7 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 * (d &&& ( ~~~e ||| f)) + 1 *  ~~~(d &&& ( ~~~e ||| f)) - 1 * (d &&&  ~~~f) + 1 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 11 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 2 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 2 *  ~~~(d &&& (e ^^^ f)) - 2 * (e |||  ~~~(d ||| f)) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 11 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 11 * (d ^^^ (e ^^^ f)) - 1 * ( ~~~d ||| (e &&& f)) - 1 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 2 * ( ~~~f &&&  ~~~(d ^^^ e)) - 1 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 1 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 1 * (e ^^^ (d &&& f)) + 1 *  ~~~(d ^^^ (e &&& f)) - 2 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 4 * (d |||  ~~~e) + 11 * ( ~~~d &&& (e ||| f)) - 3 * (d &&& e) + 7 * (e ^^^  ~~~(d ||| f)) + 3 * (e &&&  ~~~(d &&&  ~~~f)) + 7 * (f ^^^ (d ||| ( ~~~e ||| f))) - 1 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 3 * ( ~~~d &&& (e ^^^ f)) - 6 * ((d ||| e) &&& (e ^^^ f)) - 5 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 3 * (f &&& (d ||| e)) + 1 * ((d &&&  ~~~e) ||| (e ^^^ f)) - 3 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 11 * (e ^^^ (d ||| f)) - 11 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 11 * (f &&&  ~~~(d &&&  ~~~e)) + 1 * (f ^^^ ( ~~~d ||| (e &&& f))) + 5 * ((d ^^^ e) &&& (d ^^^ f)) - 5 * (e ^^^ (d &&& (e ||| f))) - 1 * (d ||| (e &&& f)) + 2 * (e ^^^ (d |||  ~~~f)) + 1 * (d |||  ~~~f) - 7 * (f |||  ~~~(d ^^^ e)) - 5 *  ~~~( ~~~d ||| (e &&& f)) + 1 *  ~~~d + 3 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 11 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 7 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 14 *  ~~~(d ||| (e ||| f)) + 38 *  ~~~(d ||| ( ~~~e ||| f)) - 13 *  ~~~( ~~~d ||| (e ||| f)) + 23 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 23 * ( ~~~d &&& ( ~~~e &&& f)) - 18 * ( ~~~d &&& (e &&& f)) + 66 * (d &&& ( ~~~e &&& f)) - 12 * (d &&& (e &&& f)) =  - 2 * (e ^^^  ~~~(d ||| (e &&& f)))

theorem scalar_i32_shl_and_negC_eq_X_is_constant1_proof : scalar_i32_shl_and_negC_eq_X_is_constant1_before ⊑ scalar_i32_shl_and_negC_eq_X_is_constant1_after

@[grind =, simp]
lemma RawCNFA.addManyTrans_nil (m : RawCNFA A) {s s' : State} :
    m.addManyTrans [] s s' = m

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

theorem negate_select_of_op_vs_negated_op_nsw_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 1) (x_2 : BitVec 8),
  ¬x_1 = 1#1 → x_2 - x = 0#8 - x + x_2

theorem shl_add_lshr_comm_proof : shl_add_lshr_comm_before ⊑ shl_add_lshr_comm_after

theorem ashrsgt_03_11_exact_proof : ashrsgt_03_11_exact_before ⊑ ashrsgt_03_11_exact_after

theorem not_xor_to_or_not3_thm (e e_1 e_2 : IntW 3) :
  LLVM.xor (LLVM.xor (LLVM.and e_2 e_1) (LLVM.or e_2 e)) (const? 3 (-1)) ⊑
    LLVM.or (LLVM.and e_2 e_1) (LLVM.xor (LLVM.or e_2 e) (const? 3 (-1)))

theorem lt_unsigned_to_large_signed_proof : lt_unsigned_to_large_signed_before ⊑ lt_unsigned_to_large_signed_after

@[simp]
theorem evalWith_initCarry_eq_init (p : FSM arity)
    : p.evalWith p.initCarry = p.eval

theorem absdiff1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 64),
  ¬ofBool (x_1 <ᵤ x) = 1#1 →
    (x_1 - x ^^^ signExtend 64 (ofBool (x_1 <ᵤ x))) - signExtend 64 (ofBool (x_1 <ᵤ x)) = x_1 - x

theorem masked_icmps_bmask_notmixed_and_expected_false_proof : masked_icmps_bmask_notmixed_and_expected_false_before ⊑ masked_icmps_bmask_notmixed_and_expected_false_after

theorem trunc_equality_nuw_zext_proof : trunc_equality_nuw_zext_before ⊑ trunc_equality_nuw_zext_after

@[simp] lemma eval_ls (b : Bool) (x : Unit → BitStream) :
    (ls b).eval x = (x ()).concat b

theorem lt_unsigned_to_large_signed_thm (e : IntW 8) : icmp IntPred.slt (zext 32 e) (const? 32 1024) ⊑ const? 1 1

theorem main14_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (0#16 ≤ₛ truncate 16 x) = 1#1 →
    ¬ofBool (x &&& 32896#32 == 0#32) = 1#1 → ofBool (0#8 ≤ₛ truncate 8 x) = 1#1 → 2#32 = 1#32

theorem bools_multi_uses1_logical_thm.extracted_1._5 : ∀ (x x_1 : BitVec 1),
  x_1 ^^^ 1#1 = 1#1 → ¬x_1 = 1#1 → x = 1#1 → 1#1 ^^^ x = x ^^^ x

theorem test_sext1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), ¬x_1 = 1#1 → 0#32 = signExtend 32 0#1

theorem not_or_or_and_no_and_commute2_or_proof : not_or_or_and_no_and_commute2_or_before ⊑ not_or_or_and_no_and_commute2_or_after

theorem test16_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(12#16 ≥ ↑16 ∨ 15#16 ≥ ↑16) →
    signExtend 32 (ofBool (x &&& 8#16 == 8#16)) = signExtend 32 ((x <<< 12#16).sshiftRight' 15#16)

theorem e_2265 :
     - 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 2 * (f ^^^ ( ~~~d ||| (e &&& f))) - 5 * ((d &&& f) ^^^ (e ||| f)) + 5 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) - 11 * ( ~~~f |||  ~~~(d ^^^ e)) - 7 *  ~~~(d ^^^ f) - 1 * (f ^^^  ~~~(d &&& (e ||| f))) - 3 * (e ||| f) + 1 * ((d &&& e) ^^^ (e ||| f)) - 3 * (f ||| (d ^^^ e)) + 7 * (e ^^^ (d &&& (e ||| f))) + 1 * (f ||| (d &&&  ~~~e)) + 3 * (f ^^^  ~~~(d ||| e)) - 6 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 11 * (d ^^^ (e &&& f)) + 7 * ( ~~~d &&& (e ^^^ f)) + 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 11 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) + 11 * (e &&&  ~~~(d ^^^ f)) - 3 *  ~~~(e ^^^ f) + 2 *  ~~~( ~~~d &&& (e ||| f)) + 11 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 4 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 5 * d - 2 * ((d ||| e) &&& (e ^^^ f)) - 11 *  ~~~( ~~~d ||| (e ^^^ f)) + 2 * (f ^^^ (d ||| (e ||| f))) - 3 * (d |||  ~~~f) - 7 * (e ^^^  ~~~(d ||| f)) + 1 * ( ~~~f ||| (d ^^^ e)) - 2 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 1 *  ~~~(e &&& f) + 7 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 1 *  ~~~e - 7 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) - 5 * ((d &&& f) ||| (e &&&  ~~~f)) + 2 *  ~~~(d ^^^ (e ^^^ f)) - 1 * (e ^^^ ( ~~~d &&& (e ||| f))) - 7 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 2 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 6 * (e ^^^ (d ||| ( ~~~e &&& f))) - 1 *  ~~~(d &&& (e ^^^ f)) + 1 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 7 *  ~~~(d &&&  ~~~f) + 2 * (f &&& (d ||| e)) - 2 * (f ^^^  ~~~(d &&& e)) + 7 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 7 * ( ~~~e &&& (d ^^^ f)) + 3 *  ~~~(d ||| (e ^^^ f)) - 2 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 1 * (e ^^^ (d ||| (e &&& f))) + 2 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 23 *  ~~~(d ||| ( ~~~e ||| f)) + 51 *  ~~~( ~~~d ||| (e ||| f)) + 29 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 9 * ( ~~~d &&& ( ~~~e &&& f)) + 21 * ( ~~~d &&& (e &&& f)) + 32 * (d &&& ( ~~~e &&& f)) + 19 * (d &&& (e &&& f)) = 1 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * (e |||  ~~~(d |||  ~~~f))

theorem test_sub_127_Y_eq_127_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (127#8 - x == 127#8) = ofBool (x == 0#8)

theorem udiv_i32_proof : udiv_i32_before ⊑ udiv_i32_after

theorem ashrslt_03_07_exact_proof : ashrslt_03_07_exact_before ⊑ ashrslt_03_07_exact_after

theorem n2_thm.extracted_1._6 : ∀ (x x_1 : BitVec 32) (x_2 : BitVec 1),
  x_2 = 1#1 → ¬x_2 ^^^ 1#1 = 1#1 → 1#1 ^^^ 1#1 = 0#1

theorem ashr_pow2_ult_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → True ∧ BitVec.ofInt 8 (-128) >>> x <<< x ≠ BitVec.ofInt 8 (-128) ∨ x ≥ ↑8 → False

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

theorem evalWith_add_eq_evalWith_carryWith
  (p : FSM arity) (carryState : p.α → Bool) (x : arity → BitStream) (n : Nat) :
  p.evalWith carryState x (n + m) =
  p.evalWith (p.carryWith carryState x n) (fun a i => x a (n + i)) m

theorem icmp_select_const_proof : icmp_select_const_before ⊑ icmp_select_const_after

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

theorem not_or_or_and_not_and_and_commute4_proof : not_or_or_and_not_and_and_commute4_before ⊑ not_or_or_and_not_and_and_commute4_after

theorem e_1494 :
     - 1 * (z ^^^ t) - 7 * (z |||  ~~~t) - 6 *  ~~~(z &&&  ~~~z) - 2 *  ~~~z - 5 * t + 2 *  ~~~t - 2 * (z ||| t) - 11 *  ~~~(z &&&  ~~~t) + 24 *  ~~~(z ||| t) + 27 *  ~~~(z |||  ~~~t) + 31 * (z &&& t) =  - 14 * (z &&&  ~~~t)

theorem bools_logical_commute0_thm.extracted_1._5 : ∀ (x x_1 : BitVec 1),
  x_1 ^^^ 1#1 = 1#1 → ¬x_1 = 1#1 → x = 1#1 → 1#1 = x

theorem zext_nneg_sext_ule_op0_wide_proof : zext_nneg_sext_ule_op0_wide_before ⊑ zext_nneg_sext_ule_op0_wide_after

lemma RawCNFA.autSignedCmp_wf {cmp} : autSignedCmp cmp |>.WF

theorem positive_and_odd_ne_proof : positive_and_odd_ne_before ⊑ positive_and_odd_ne_after

theorem test1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 447),
  ¬(True ∧ (x_1 &&& 70368744177664#447 &&& (x &&& 70368744177663#447) != 0) = true) →
    x_1 &&& 70368744177664#447 ^^^ x &&& 70368744177663#447 = x_1 &&& 70368744177664#447 ||

theorem alive_many_consts: forall (w : Nat) (Z : Int), TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec w)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (Bitvec.ofInt w Z) %v0
  dsl_ret %v1
  ]  ⊑
  TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec w)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (Bitvec.ofInt w Z) %v0;
  %v2 := op:const (Bitvec.ofInt w Z) %v0;
  %v3 := op:const (Bitvec.ofInt w Z) %v0;
  %v4 := op:const (Bitvec.ofInt w Z) %v0;
  %v5 := op:const (Bitvec.ofInt w Z) %v0;
  %v6 := op:const (Bitvec.ofInt w Z) %v0;
  %v7 := op:const (Bitvec.ofInt w Z) %v0;
  %v8 := op:const (Bitvec.ofInt w Z) %v0;
  %v9 := op:const (Bitvec.ofInt w Z) %v0;
  %v10 := op:const (Bitvec.ofInt w Z) %v0;
  %v11 := op:const (Bitvec.ofInt w Z) %v0;
  %v12 := op:const (Bitvec.ofInt w Z) %v0;
  %v13 := op:const (Bitvec.ofInt w Z) %v0;
  %v14 := op:const (Bitvec.ofInt w Z) %v0;
  %v15 := op:const (Bitvec.ofInt w Z) %v0;
  %v16 := op:const (Bitvec.ofInt w Z) %v0;
  %v17 := op:const (Bitvec.ofInt w Z) %v0;
  %v18 := op:const (Bitvec.ofInt w Z) %v0;
  %v19 := op:const (Bitvec.ofInt w Z) %v0;
  %v20 := op:const (Bitvec.ofInt w Z) %v0;
  %v21 := op:const (Bitvec.ofInt w Z) %v0;
  %v22 := op:const (Bitvec.ofInt w Z) %v0;
  %v23 := op:const (Bitvec.ofInt w Z) %v0;
  %v24 := op:const (Bitvec.ofInt w Z) %v0;
  %v25 := op:const (Bitvec.ofInt w Z) %v0;
  %v26 := op:const (Bitvec.ofInt w Z) %v0;
  %v27 := op:const (Bitvec.ofInt w Z) %v0;
  %v28 := op:const (Bitvec.ofInt w Z) %v0;
  %v29 := op:const (Bitvec.ofInt w Z) %v0;
  %v30 := op:const (Bitvec.ofInt w Z) %v0;
  %v31 := op:const (Bitvec.ofInt w Z) %v0;
  %v32 := op:const (Bitvec.ofInt w Z) %v0;
  %v33 := op:const (Bitvec.ofInt w Z) %v0;
  %v34 := op:const (Bitvec.ofInt w Z) %v0;
  %v35 := op:const (Bitvec.ofInt w Z) %v0;
  %v36 := op:const (Bitvec.ofInt w Z) %v0;
  %v37 := op:const (Bitvec.ofInt w Z) %v0;
  %v38 := op:const (Bitvec.ofInt w Z) %v0;
  %v39 := op:const (Bitvec.ofInt w Z) %v0;
  %v40 := op:const (Bitvec.ofInt w Z) %v0;
  %v41 := op:const (Bitvec.ofInt w Z) %v0;
  %v42 := op:const (Bitvec.ofInt w Z) %v0;
  %v43 := op:const (Bitvec.ofInt w Z) %v0;
  %v44 := op:const (Bitvec.ofInt w Z) %v0;
  %v45 := op:const (Bitvec.ofInt w Z) %v0;
  %v46 := op:const (Bitvec.ofInt w Z) %v0;
  %v47 := op:const (Bitvec.ofInt w Z) %v0;
  %v48 := op:const (Bitvec.ofInt w Z) %v0;
  %v49 := op:const (Bitvec.ofInt w Z) %v0;
  %v50 := op:const (Bitvec.ofInt w Z) %v0;
  %v51 := op:const (Bitvec.ofInt w Z) %v0;
  %v52 := op:const (Bitvec.ofInt w Z) %v0;
  %v53 := op:const (Bitvec.ofInt w Z) %v0;
  %v54 := op:const (Bitvec.ofInt w Z) %v0;
  %v55 := op:const (Bitvec.ofInt w Z) %v0;
  %v56 := op:const (Bitvec.ofInt w Z) %v0;
  %v57 := op:const (Bitvec.ofInt w Z) %v0;
  %v58 := op:const (Bitvec.ofInt w Z) %v0;
  %v59 := op:const (Bitvec.ofInt w Z) %v0;
  %v60 := op:const (Bitvec.ofInt w Z) %v0;
  %v61 := op:const (Bitvec.ofInt w Z) %v0;
  %v62 := op:const (Bitvec.ofInt w Z) %v0;
  %v63 := op:const (Bitvec.ofInt w Z) %v0;
  %v64 := op:const (Bitvec.ofInt w Z) %v0;
  %v65 := op:const (Bitvec.ofInt w Z) %v0;
  %v66 := op:const (Bitvec.ofInt w Z) %v0;
  %v67 := op:const (Bitvec.ofInt w Z) %v0;
  %v68 := op:const (Bitvec.ofInt w Z) %v0;
  %v69 := op:const (Bitvec.ofInt w Z) %v0;
  %v70 := op:const (Bitvec.ofInt w Z) %v0;
  %v71 := op:const (Bitvec.ofInt w Z) %v0;
  %v72 := op:const (Bitvec.ofInt w Z) %v0;
  %v73 := op:const (Bitvec.ofInt w Z) %v0;
  %v74 := op:const (Bitvec.ofInt w Z) %v0;
  %v75 := op:const (Bitvec.ofInt w Z) %v0;
  %v76 := op:const (Bitvec.ofInt w Z) %v0;
  %v77 := op:const (Bitvec.ofInt w Z) %v0;
  %v78 := op:const (Bitvec.ofInt w Z) %v0;
  %v79 := op:const (Bitvec.ofInt w Z) %v0;
  %v80 := op:const (Bitvec.ofInt w Z) %v0;
  %v81 := op:const (Bitvec.ofInt w Z) %v0;
  %v82 := op:const (Bitvec.ofInt w Z) %v0;
  %v83 := op:const (Bitvec.ofInt w Z) %v0;
  %v84 := op:const (Bitvec.ofInt w Z) %v0;
  %v85 := op:const (Bitvec.ofInt w Z) %v0;
  %v86 := op:const (Bitvec.ofInt w Z) %v0;
  %v87 := op:const (Bitvec.ofInt w Z) %v0;
  %v88 := op:const (Bitvec.ofInt w Z) %v0;
  %v89 := op:const (Bitvec.ofInt w Z) %v0;
  %v90 := op:const (Bitvec.ofInt w Z) %v0;
  %v91 := op:const (Bitvec.ofInt w Z) %v0;
  %v92 := op:const (Bitvec.ofInt w Z) %v0;
  %v93 := op:const (Bitvec.ofInt w Z) %v0;
  %v94 := op:const (Bitvec.ofInt w Z) %v0;
  %v95 := op:const (Bitvec.ofInt w Z) %v0;
  %v96 := op:const (Bitvec.ofInt w Z) %v0;
  %v97 := op:const (Bitvec.ofInt w Z) %v0;
  %v98 := op:const (Bitvec.ofInt w Z) %v0;
  %v99 := op:const (Bitvec.ofInt w Z) %v0;
  %v100 := op:const (Bitvec.ofInt w Z) %v0
  dsl_ret %v100
  ]

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

theorem ashr_ult_1_proof : ashr_ult_1_before ⊑ ashr_ult_1_after

theorem bad_add1_proof : bad_add1_before ⊑ bad_add1_after

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

theorem e_1865 :
     - 1 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 5 * (a ^^^ ( ~~~b &&& c)) + 2 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) - 2 *  ~~~(a |||  ~~~c) + 1 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 7 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) - 3 *  ~~~(a &&& (b ^^^ c)) + 1 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 4 * (a ^^^ ( ~~~b ||| c)) + 1 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 11 *  ~~~a + 11 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) + 11 * (a &&& (b ^^^ c)) + 1 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) + 1 *  ~~~(a ^^^ c) + 11 *  ~~~(a &&& b) + 5 * (a &&& (b ||| c)) + 5 *  ~~~( ~~~a &&& (b &&& c)) - 3 * (a &&& c) - 2 * (c ^^^ (a ||| ( ~~~b ||| c))) + 4 * (a ||| (b ^^^ c)) - 7 * (b ^^^ (a ||| (b ^^^ c))) + 3 * (b ||| (a &&& c)) - 3 * (b &&& (a |||  ~~~c)) - 1 * ((b &&&  ~~~c) ^^^ (a ||| (b ^^^ c))) + 1 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) + 1 * ((a &&& c) ^^^ (b ||| c)) - 7 * ( ~~~c &&&  ~~~(a ^^^ b)) - 1 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) + 2 * (b ^^^  ~~~(a ||| c)) - 11 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) + 5 *  ~~~(a &&& c) + 2 * (a ||| c) - 6 * (b |||  ~~~(a |||  ~~~c)) - 11 * (a ^^^ (b ||| c)) + 4 * (c &&& (a ^^^ b)) - 5 * (c ||| (a &&&  ~~~b)) - 2 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 2 * (c ^^^  ~~~(a &&& ( ~~~b ||| c))) - 24 *  ~~~(a ||| (b ||| c)) - 23 *  ~~~(a ||| ( ~~~b ||| c)) + 22 *  ~~~( ~~~a ||| (b ||| c)) - 20 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 4 * ( ~~~a &&& ( ~~~b &&& c)) - 4 * ( ~~~a &&& (b &&& c)) - 1 * (a &&& (b &&& c)) = 35 * (a &&& ( ~~~b &&& c))

theorem t2_proof : t2_before ⊑ t2_after

theorem select_icmp_ne_0_and_32_xor_4096_proof : select_icmp_ne_0_and_32_xor_4096_before ⊑ select_icmp_ne_0_and_32_xor_4096_after

theorem n2_thm (e e_1 : IntW 8) (e_2 : IntW 1) :
  LLVM.or (LLVM.xor e_2 (const? 1 1)) (icmp IntPred.eq e_1 e) ⊑
    LLVM.or (icmp IntPred.eq e_1 e) (LLVM.xor e_2 (const? 1 1))

theorem lshr_lshr_pow2_const_thm (e : IntW 16) :
  LLVM.and (lshr (lshr (const? 16 2048) e) (const? 16 6)) (const? 16 4) ⊑
    select (icmp IntPred.eq e (const? 16 3)) (const? 16 4) (const? 16 0)

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

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

theorem test7_thm (e : IntW 32) : LLVM.and e (LLVM.xor e (const? 32 (-1))) ⊑ const? 32 0

theorem lshr_pow2_slt_proof : lshr_pow2_slt_before ⊑ lshr_pow2_slt_after

theorem same_source_matching_signbits_proof : same_source_matching_signbits_before ⊑ same_source_matching_signbits_after

theorem test1_proof : test1_before ⊑ test1_after

theorem sdiv_icmp5_thm (e : IntW 64) :
  icmp IntPred.eq (LLVM.sdiv e (const? 64 (-5)) { «exact» := true }) (const? 64 1) ⊑
    icmp IntPred.eq e (const? 64 (-5))

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

theorem neg_sgt_0_proof : neg_sgt_0_before ⊑ neg_sgt_0_after

theorem or_sext_sext_thm (e : IntW 4) (e_1 : IntW 8) :
  LLVM.or (sext 16 e_1) (sext 16 e) ⊑ sext 16 (LLVM.or e_1 (sext 8 e))

theorem slt_smin4_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 <ₛ x_1 + 3#32)

theorem zext_nneg_sext_eq_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ x_1.msb = true) → ofBool (zeroExtend 32 x_1 == signExtend 32 x) = ofBool (x_1 == x)

theorem test_add_nuw_nsw__nsw_is_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x ||| BitVec.ofInt 32 (-2147483648) == -1#32) = 1#1 →
    True ∧ (x ||| BitVec.ofInt 32 (-2147483648)).saddOverflow 1#32 = true → False

theorem scalar_i32_shl_and_negC_slt_proof : scalar_i32_shl_and_negC_slt_before ⊑ scalar_i32_shl_and_negC_slt_after

theorem test10b_thm (e e_1 : IntW 32) : LLVM.xor (LLVM.xor e_1 e) (LLVM.and e e_1) ⊑ LLVM.or e_1 e

theorem uge_or_max_logical_proof : uge_or_max_logical_before ⊑ uge_or_max_logical_after

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 xor_or_xor_common_op_commute8_proof : xor_or_xor_common_op_commute8_before ⊑ xor_or_xor_common_op_commute8_after

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_7b_logical_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 6)) (const? 32 0)) (const? 1 1)
      (icmp IntPred.ne (LLVM.and e (const? 32 15)) (const? 32 8)) ⊑
    const? 1 1

theorem negtest_near_pow2_cmpval_would_overflow_into_signbit_proof : negtest_near_pow2_cmpval_would_overflow_into_signbit_before ⊑ negtest_near_pow2_cmpval_would_overflow_into_signbit_after

theorem src_x_and_nmask_eq_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  x_2 = 1#1 → ¬x_1 ≥ ↑8 → x_2 ^^^ 1#1 = 1#1 → ofBool ((-1#8) <<< x_1 == x &&& (-1#8) <<< x_1) = 1#1

theorem eq_irregular_bit_widths_thm.extracted_1._2 : ∀ (x x_1 : BitVec 31),
  ¬(13#31 ≥ ↑31 ∨ 13#31 ≥ ↑31 ∨ 7#31 ≥ ↑31 ∨ 7#31 ≥ ↑31) →
    ¬(7#31 ≥ ↑31 ∨ 7#31 ≥ ↑31) →
      ofBool (truncate 5 (x_1 >>> 13#31) == truncate 5 (x >>> 13#31)) &&&
          ofBool (truncate 6 (x_1 >>> 7#31) == truncate 6 (x >>> 7#31)) =
        ofBool (truncate 11 (x_1 >>> 7#31) == truncate 11 (x >>> 7#31))

theorem test_negative_combined_sub_unsigned_overflow_proof : test_negative_combined_sub_unsigned_overflow_before ⊑ test_negative_combined_sub_unsigned_overflow_after

theorem and_consts_logical_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and (const? 32 4) e) (const? 32 0)) (const? 1 1)
      (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 ashr_lshr_shift_amt_mismatch_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (0#32 ≤ₛ x_2) = 1#1 → ¬x ≥ ↑32 → ¬ofBool (x_2 <ₛ 0#32) = 1#1 → x_1 ≥ ↑32 → False

theorem exact_lshr_eq_exactdiv_proof : exact_lshr_eq_exactdiv_before ⊑ exact_lshr_eq_exactdiv_after

theorem icmp_eq_or_z_or_pow2orz_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == 0#8 - x &&& x) ||

theorem main11_logical_thm.extracted_1._4 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 64#32 == 0#32) = 1#1 →
    ¬ofBool (x &&& 192#32 == 192#32) = 1#1 → ¬ofBool (0#8 ≤ₛ truncate 8 x) = 1#1 → 1#32 = 2#32

theorem fold_ne_rhs_thm (e e_1 : IntW 8) :
  icmp IntPred.ne (LLVM.and (LLVM.xor e_1 (const? 8 123)) (shl (const? 8 (-1)) e)) (const? 8 0) ⊑
    icmp IntPred.ne (lshr (LLVM.xor e_1 (const? 8 123)) e) (const? 8 0)

theorem nomask_rhs_proof : nomask_rhs_before ⊑ nomask_rhs_after

theorem not_mul_of_bool_commute_thm (e e_1 : IntW 32) :
  icmp IntPred.ugt (mul (LLVM.and e_1 (const? 32 255)) (lshr e (const? 32 30))) (const? 32 255) ⊑
    icmp IntPred.ugt (mul (LLVM.and e_1 (const? 32 255)) (lshr e (const? 32 30)) { «nsw» := true, «nuw» := true })
      (const? 32 255)

theorem e_2088 :
     - 1 * (d ^^^ e) - 1 *  ~~~(e ||| f) - 2 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 11 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 7 * (f ||| (d &&&  ~~~e)) + 5 * (d ^^^ ( ~~~e ||| f)) - 3 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 7 *  ~~~( ~~~d ||| ( ~~~e &&& f)) + 3 * ((d &&& f) ^^^ (e ||| f)) - 3 * (e ^^^ (d ||| ( ~~~e ||| f))) + 7 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 1 * (e ^^^  ~~~(d &&& (e ||| f))) + 11 * (f &&& (d ^^^ e)) + 3 *  ~~~(d ^^^ ( ~~~e &&& f)) - 3 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 2 *  ~~~(e |||  ~~~f) - 1 * ((d |||  ~~~e) &&& (e ^^^ f)) + 1 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 6 * ( ~~~f ||| (d ^^^ e)) + 4 * (d ^^^ f) - 5 * (e |||  ~~~(d ||| f)) - 2 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 2 *  ~~~(d ||| ( ~~~e &&& f)) - 1 * ((d ^^^ e) &&& (d ^^^ f)) + 1 * (f ||| (d &&& e)) + 3 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 7 *  ~~~(d ||| (e ^^^ f)) - 5 * (f &&&  ~~~(d &&&  ~~~e)) - 11 * ( ~~~f &&&  ~~~(d ^^^ e)) + 1 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 11 * (f ^^^  ~~~(d &&&  ~~~e)) + 11 * (e ^^^ (d ||| (e ^^^ f))) + 14 *  ~~~(d ||| (e ||| f)) + 22 *  ~~~(d ||| ( ~~~e ||| f)) + 7 *  ~~~( ~~~d ||| (e ||| f)) + 42 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 9 * ( ~~~d &&& ( ~~~e &&& f)) - 26 * ( ~~~d &&& (e &&& f)) - 5 * (d &&& ( ~~~e &&& f)) + 9 * (d &&& (e &&& f)) =  - 11 * (f ^^^  ~~~(d |||  ~~~e)) - 2 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f)))

theorem scalar_i32_lshr_and_signbit_ne_proof : scalar_i32_lshr_and_signbit_ne_before ⊑ scalar_i32_lshr_and_signbit_ne_after

theorem test73_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (-1#8 <ₛ truncate 8 x) = 1#1 → ofBool (x &&& 128#32 == 0#32) = 1#1 → 42#32 = 40#32

theorem t2_const_lshr_shl_eq_proof : t2_const_lshr_shl_eq_before ⊑ t2_const_lshr_shl_eq_after

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

theorem main10_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 64#32 == 0#32) &&& ofBool (0#8 ≤ₛ truncate 8 x) = 1#1 →
    ofBool (x &&& 192#32 == 0#32) = 1#1 → 1#32 = 2#32

theorem main2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 1#32 == 0#32) ||

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

@[simp] lemma eval_or (x : Bool → BitStream) : or.eval x = (x true) ||

theorem bv_229 :
    ∀ (e e_1 e_2 : LLVM.IntW w), LLVM.mul (LLVM.add e e_1) e_2 ⊑ LLVM.add (LLVM.mul e e_2) (LLVM.mul e_1 e_2)

theorem lsb_mask_sign_sext_wrong_cst2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → (x + -1#32 &&& (x ^^^ 2#32)).sshiftRight' 31#32 = (x + -1#32 &&& x).sshiftRight' 31#32

theorem t17_nocse_mismatching_x_proof : t17_nocse_mismatching_x_before ⊑ t17_nocse_mismatching_x_after

theorem c_0_1_0_proof : c_0_1_0_before ⊑ c_0_1_0_after

theorem scalar_i16_shl_ult_const_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬8#16 ≥ ↑16 → ofBool (x <<< 8#16 <ᵤ 1024#16) = ofBool (x &&& 252#16 == 0#16)

theorem a_false_implies_b_false2_thm.extracted_1._2 : ∀ (x : BitVec 1) (x_1 : BitVec 8),
  ofBool (20#8 <ᵤ x_1) = 1#1 → ¬ofBool (10#8 <ᵤ x_1) = 1#1 → False

theorem substitute_constant_and_eq_eq_proof : substitute_constant_and_eq_eq_before ⊑ substitute_constant_and_eq_eq_after

theorem PR45977_f1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  (x_1 ||| x) ^^^ -1#32 ||

theorem e_572 :
     - 11 *  ~~~(x ^^^ y) + 3 * (x ^^^ y) + 1 * y - 2 *  ~~~(x &&&  ~~~x) - 1 *  ~~~(x &&&  ~~~y) + 14 *  ~~~(x ||| y) - 3 *  ~~~(x |||  ~~~y) - 3 * (x &&&  ~~~y) + 11 * (x &&& y) =  - 2 * (x ||| y)

theorem test_logical_thm (e : IntW 32) :
  select (icmp IntPred.sgt e (const? 32 (-1))) (icmp IntPred.eq e (const? 32 1)) (const? 1 0) ⊑
    icmp IntPred.eq e (const? 32 1)

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

theorem test3_logical_proof : test3_logical_before ⊑ test3_logical_after

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

theorem icmp_equality_test_commute_icmp2_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 64),
  ¬ofBool (x_2 == x_1) = 1#1 → ¬ofBool (x == x_2) ^^^ 1#1 = 1#1 → 0#1 = ofBool (x == x_1)

theorem e_1993 :
     - 2 * ( ~~~c |||  ~~~(a ^^^ b)) - 7 * (b ^^^  ~~~(a ||| (b ^^^ c))) - 11 * (a |||  ~~~b) - 5 * ((a &&& c) ||| (b &&&  ~~~c)) + 1 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 1 * (b ^^^ (a &&& ( ~~~b ||| c))) - 2 * (c ^^^ (a &&&  ~~~b)) - 11 * b - 1 *  ~~~(b ||| c) - 2 * (b &&& c) + 2 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) + 11 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) + 3 * (a ^^^ (b ||| c)) - 1 * (c ^^^ (a &&& b)) + 5 *  ~~~(a &&& (b ||| c)) + 1 * (b ^^^  ~~~(a &&&  ~~~c)) + 1 *  ~~~(a &&& b) - 5 * (b ^^^  ~~~(a &&& c)) + 1 * (c ^^^ (a ||| (b &&& c))) + 2 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 4 * (a ^^^ c) - 1 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) - 6 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) - 3 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) - 2 * (c &&&  ~~~(a &&&  ~~~b)) + 1 * ((b &&& c) ||| (a &&& (b ||| c))) - 1 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) + 3 * (c &&& (a ^^^ b)) - 1 * (b ^^^ ( ~~~a ||| (b ||| c))) + 7 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 5 * (b ^^^  ~~~(a ||| c)) + 4 * (c ^^^ (a ||| ( ~~~b &&& c))) - 6 * (a &&& c) + 5 *  ~~~(a ^^^ c) + 2 *  ~~~( ~~~a &&& (b ||| c)) + 5 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) + 1 * (b &&& (a ||| c)) + 5 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) + 7 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) - 11 * (c ^^^ (a &&& (b ||| c))) + 4 * ( ~~~c &&& (a ^^^ b)) - 2 * (c ^^^ (a ||| (b ||| c))) - 3 * (c ^^^  ~~~(a &&& (b &&& c))) + 5 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 6 * (b &&&  ~~~c) - 1 * (a &&& (b ^^^ c)) + 3 * (b ^^^ ( ~~~a &&& (b ||| c))) + 7 * (c &&&  ~~~(a ^^^ b)) + 7 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 2 * (b ||| (a &&& c)) - 15 *  ~~~(a ||| (b ||| c)) + 5 *  ~~~(a ||| ( ~~~b ||| c)) - 16 *  ~~~( ~~~a ||| (b ||| c)) + 36 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 13 * ( ~~~a &&& ( ~~~b &&& c)) - 8 * ( ~~~a &&& (b &&& c)) - 10 * (a &&& ( ~~~b &&& c)) + 21 * (a &&& (b &&& c)) =  - 2 * ((a ^^^ b) &&& (a ^^^ c)) + 1 * (c ||| (a &&&  ~~~b))

theorem sext_xor_sub_1_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → (signExtend 64 x_1 ^^^ x) - signExtend 64 x_1 = x

theorem rem_euclid_i128_thm.extracted_1._2 : ∀ (x : BitVec 128),
  ¬(8#128 == 0 || 128 != 1 && x == intMin 128 && 8#128 == -1) = true →
    ¬ofBool (x.srem 8#128 <ₛ 0#128) = 1#1 → x.srem 8#128 = x &&& 7#128

theorem not_signbit_zext_proof : not_signbit_zext_before ⊑ not_signbit_zext_after

theorem urem_i32_c_proof : urem_i32_c_before ⊑ urem_i32_c_after

theorem logical_and_bitwise_and_icmps_comm1_thm (e e_1 e_2 : IntW 8) :
  select (icmp IntPred.ne (LLVM.and e_2 (shl (const? 8 1) e_1)) (const? 8 0))
      (LLVM.and (icmp IntPred.eq e (const? 8 42)) (icmp IntPred.ne (LLVM.and e_2 (const? 8 1)) (const? 8 0)))
      (const? 1 0) ⊑
    select (icmp IntPred.ne (LLVM.and e_2 (shl (const? 8 1) e_1 { «nsw» := false, «nuw» := true })) (const? 8 0))
      (LLVM.and (icmp IntPred.eq e (const? 8 42)) (icmp IntPred.ne (LLVM.and e_2 (const? 8 1)) (const? 8 0)))
      (const? 1 0)

theorem icmp_ne_sext_eq_zero_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (x == 0#32)) != x) = 1#1

theorem t5_thm.extracted_1._5 : ∀ (x x_1 : BitVec 1) (x_2 : BitVec 32),
  x_1 = 1#1 → x = 1#1 → ¬32#32 = 0 → ¬5#32 ≥ ↑32 → x_2 / 32#32 = x_2 >>> 5#32

theorem sub_zext_trunc_lshr_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬15#64 ≥ ↑64 →
    ¬(16#32 ≥ ↑32 ∨ 31#32 ≥ ↑32 ∨ True ∧ ((truncate 32 x <<< 16#32).sshiftRight' 31#32).saddOverflow 10#32 = true) →
      10#32 - zeroExtend 32 (truncate 1 (x >>> 15#64)) = (truncate 32 x <<< 16#32).sshiftRight' 31#32 + 10#32

theorem test_or2_thm (e e_1 : IntW 32) :
  LLVM.or (icmp IntPred.sle e_1 (const? 32 (-1))) (icmp IntPred.sgt e_1 (LLVM.and e (const? 32 2147483647))) ⊑
    icmp IntPred.ugt e_1 (LLVM.and e (const? 32 2147483647))

theorem sext_diff_i1_xor_sub_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1),
  ¬(True ∧ (zeroExtend 64 x).saddOverflow (signExtend 64 x_1) = true) →
    signExtend 64 x_1 - signExtend 64 x = zeroExtend 64 x + signExtend 64 x_1

theorem p1_proof : p1_before ⊑ p1_after

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

theorem positive_biggerlshr_shlnsw_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(6#8 ≥ ↑8 ∨ True ∧ (x >>> 6#8 <<< 3#8).sshiftRight' 3#8 ≠ x >>> 6#8 ∨ 3#8 ≥ ↑8) →
    ¬3#8 ≥ ↑8 → x >>> 6#8 <<< 3#8 = x >>> 3#8 &&& 24#8

theorem no_shift_xor_multiuse_cmp_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (0#32 != x_2 &&& 4096#32) = 1#1 → ofBool (x_2 &&& 4096#32 == 0#32) = 1#1 → False

theorem select_icmp_eq_0_and_1_or_1_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 64),
  ofBool (x_1 &&& 1#64 == 0#64) = 1#1 → x = x ||

theorem add_or_sub_comb_i8_commuted2_nsw_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(True ∧ (x * x).saddOverflow (0#8 - x * x ||| x * x) = true) →
    ¬(True ∧ (x * x).saddOverflow (-1#8) = true) → x * x + (0#8 - x * x ||| x * x) = x * x + -1#8 &&& x * x

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

theorem ne_21_comm_ne2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(16#32 ≥ ↑32 ∨ 16#32 ≥ ↑32 ∨ 8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32) → 8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32 → False

theorem main2_logical_proof : main2_logical_before ⊑ main2_logical_after

theorem test_with_3_proof : test_with_3_before ⊑ test_with_3_after

@[bv_multi_width_normalize] theorem BitVec.le_eq_ule {x y : BitVec w} :
    (x ≤ y) = ((x.ule y) = true)

theorem ashrslt_03_01_exact_proof : ashrslt_03_01_exact_before ⊑ ashrslt_03_01_exact_after

theorem add_signbit_select_shl_proof : add_signbit_select_shl_before ⊑ add_signbit_select_shl_after

theorem n0_proof : n0_before ⊑ n0_after

theorem sel_false_val_is_a_masked_ashr_of_true_val1_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& BitVec.ofInt 32 (-2147483588) == 0#32) = 1#1 →
    ¬(2#32 ≥ ↑32 ∨ zeroExtend 64 ((x_1 &&& BitVec.ofInt 32 (-2147483588)).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 and_not_xor_common_op_proof : and_not_xor_common_op_before ⊑ and_not_xor_common_op_after

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

theorem lshrugt_02_11_exact_proof : lshrugt_02_11_exact_before ⊑ lshrugt_02_11_exact_after

theorem ugt_or_not_min_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x <ᵤ x_1) ||

theorem demorgan_nor_use2ab_proof : demorgan_nor_use2ab_before ⊑ demorgan_nor_use2ab_after

theorem test_sub__nsw_is_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.or e (const? 32 (-2147483648))) (const? 32 (-2147483647))) (const? 32 (-1))
      (sub (const? 32 (-2147483648)) (LLVM.or e (const? 32 (-2147483648)))) ⊑
    sub (const? 32 (-2147483648)) (LLVM.or e (const? 32 (-2147483648))) { «nsw» := true, «nuw» := false }

theorem or_and3_proof : or_and3_before ⊑ or_and3_after

theorem add_select_not_sext_proof : add_select_not_sext_before ⊑ add_select_not_sext_after

theorem and_or_not_not_commute6_proof : and_or_not_not_commute6_before ⊑ and_or_not_not_commute6_after

theorem test18_thm (e e_1 : IntW 8) :
  mul (LLVM.or (LLVM.xor (LLVM.xor e_1 (const? 8 33)) e) (LLVM.xor e e_1)) (LLVM.xor (LLVM.xor e_1 (const? 8 33)) e) ⊑
    mul (LLVM.or (LLVM.xor (LLVM.xor e_1 e) (const? 8 33)) (LLVM.xor e e_1))
      (LLVM.xor (LLVM.xor e_1 e) (const? 8 33))

theorem p_commutative0_proof : p_commutative0_before ⊑ p_commutative0_after

theorem add_umin_simplify2_proof : add_umin_simplify2_before ⊑ add_umin_simplify2_after

theorem test_zext2_proof : test_zext2_before ⊑ test_zext2_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_0_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_swapped_0_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_swapped_0_logical_after

theorem ashrsgt_02_05_thm.extracted_1._1 : ∀ (x : BitVec 4), ¬2#4 ≥ ↑4 → ofBool (5#4 <ₛ x.sshiftRight' 2#4) = 0#1

theorem shl_lshr_pow2_not_const_case2_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(x ≥ ↑16 ∨ 3#16 ≥ ↑16) → ¬ofBool (x == 2#16) = 1#1 → 16#16 <<< x >>> 3#16 &&& 8#16 ^^^ 8#16 = 8#16

theorem sle_smax4_proof : sle_smax4_before ⊑ sle_smax4_after

theorem bad_add1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨ x ≥ ↑32 ∨ True ∧ (1#32 <<< x).uaddOverflow 1#32 = true → False

theorem scalar_i32_shl_and_signbit_ne_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (LLVM.and (shl e_1 e) (const? 32 (-2147483648))) (const? 32 0) ⊑
    icmp IntPred.slt (shl e_1 e) (const? 32 0)

theorem PR42691_3_thm (e : IntW 32) :
  LLVM.or (icmp IntPred.sge e (const? 32 0)) (icmp IntPred.eq e (const? 32 (-2147483648))) ⊑
    icmp IntPred.ult e (const? 32 (-2147483647))

theorem ashr_mul_times_5_div_4_exact_thm (e : IntW 32) :
  ashr (mul e (const? 32 5) { «nsw» := true, «nuw» := false }) (const? 32 2) { «exact» := true } ⊑
    add e (ashr e (const? 32 2) { «exact» := true }) { «nsw» := true, «nuw» := false }

theorem e_773 :
     - 3 * (z |||  ~~~t) + 3 *  ~~~z - 11 * z - 3 *  ~~~(z |||  ~~~t) + 14 * (z &&&  ~~~t) =  - 14 * (z &&& t)

theorem or_xor_tree_0111_proof : or_xor_tree_0111_before ⊑ or_xor_tree_0111_after

theorem e_854 :
    2 * t - 7 *  ~~~(z &&&  ~~~z) + 13 *  ~~~(z ||| t) + 7 *  ~~~(z |||  ~~~t) + 15 * (z &&&  ~~~t) + 7 * (z &&& t) = 2 * (z ||| t) + 6 *  ~~~t

theorem lshr_lshr_pow2_const_negative_nopow2_2_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(x ≥ ↑16 ∨ 6#16 ≥ ↑16) → x ≥ ↑16 → False

theorem icmp_select_var_select_thm.extracted_1._16 : ∀ (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 → True → ofBool (x == x) = 1#1

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

theorem icmp_select_var_select_thm.extracted_1._19 : ∀ (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 == x) = ofBool (x_1 == x)

theorem main5c_like_logical_thm.extracted_1._5 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 &&& 7#32 != 7#32) = 1#1 →
    ofBool (x_1 &&& 7#32 == 7#32) = 1#1 → True → 0#32 = zeroExtend 32 (ofBool (x &&& 7#32 == 7#32))

theorem main2_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 1#32 == 0#32) = 1#1 → True → 0#32 = zeroExtend 32 (ofBool (x &&& 3#32 == 3#32))

theorem main7g_logical_proof : main7g_logical_before ⊑ main7g_logical_after

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

theorem test66_proof : test66_before ⊑ test66_after

theorem slt_and_not_max_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 != 127#8) &&& ofBool (x_1 <ₛ x) = ofBool (x_1 <ₛ x)

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 n5_thm (e e_1 e_2 : IntW 8) :
  select (icmp IntPred.eq (LLVM.and e_2 (const? 8 1)) (const? 8 2)) e_1 e ⊑ e

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 test16_proof : test16_before ⊑ test16_after

@[simp]
theorem xor_ne_self {a b : Bool} : (a ^^ ((!a) != b)) = !b

theorem ashr_icmp1_proof : ashr_icmp1_before ⊑ ashr_icmp1_after

theorem OrZextOr_thm.extracted_1._1 : ∀ (x : BitVec 3), zeroExtend 5 (x ||| 3#3) ||

theorem sle_and_min_commute_proof : sle_and_min_commute_before ⊑ sle_and_min_commute_after

theorem foo1_and_signbit_lshr_proof : foo1_and_signbit_lshr_before ⊑ foo1_and_signbit_lshr_after

theorem icmp_mul_nsw_sge_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ x_1.smulOverflow 7#8 = true ∨ True ∧ x.smulOverflow 7#8 = true) →
    ofBool (x * 7#8 ≤ₛ x_1 * 7#8) = ofBool (x ≤ₛ x_1)

theorem test_add_nsw__nuw_is_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 2147483647#32 == 2147483647#32) = 1#1 → True ∧ (x &&& 2147483647#32).uaddOverflow 1#32 = true → False

theorem t0_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → signExtend 8 x_1 + x ^^^ signExtend 8 x_1 = x

theorem shl_nsw_add_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ (1#32 <<< x).sshiftRight' x ≠ 1#32 ∨ x ≥ ↑32) →
    ¬(True ∧ ((-1#32) <<< x).sshiftRight' x ≠ -1#32 ∨ x ≥ ↑32) → 1#32 <<< x + -1#32 = (-1#32) <<< x ^^^ -1#32

theorem select_icmp_and_2147483648_ne_0_xor_2147483648_proof : select_icmp_and_2147483648_ne_0_xor_2147483648_before ⊑ select_icmp_and_2147483648_ne_0_xor_2147483648_after

theorem ule_swap_and_min_commute_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.eq e_1 (const? 8 0)) (icmp IntPred.uge e e_1) ⊑
    icmp IntPred.eq e_1 (const? 8 0)

theorem logical_and_logical_and_icmps_comm2_proof : logical_and_logical_and_icmps_comm2_before ⊑ logical_and_logical_and_icmps_comm2_after

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

theorem sgt_smin4_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x <ₛ x_1 + 3#32) = 1#1 → ofBool (x_1 + 3#32 <ₛ x) = 0#1

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_5_proof : masked_icmps_mask_notallzeros_bmask_mixed_swapped_5_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_swapped_5_after

theorem sext_sext_slt_thm (e e_1 : IntW 8) :
  icmp IntPred.slt (sext 32 e_1) (sext 32 e) ⊑ icmp IntPred.slt e_1 e

theorem thisdoesnotloop_proof : thisdoesnotloop_before ⊑ thisdoesnotloop_after

theorem one_side_fold_sgt_thm.extracted_1._9 : ∀ (x x_1 x_2 : BitVec 32) (x_3 : BitVec 1),
  x_3 = 1#1 → ¬x_3 ^^^ 1#1 = 1#1 → ofBool (x_2 <ₛ x_2) = 0#1

theorem sgt_3_impliesF_eq_2_proof : sgt_3_impliesF_eq_2_before ⊑ sgt_3_impliesF_eq_2_after

theorem select_replace_one_use_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 == 0#32) = 1#1 → x_1 - x = 0#32 - x

theorem test_sub__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 udiv_shl_pair_const_proof : udiv_shl_pair_const_before ⊑ udiv_shl_pair_const_after

theorem icmp_ne_sext_slt_allones_nofold_proof : icmp_ne_sext_slt_allones_nofold_before ⊑ icmp_ne_sext_slt_allones_nofold_after

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 test_ashr__exact_is_safe_thm.extracted_1._1 : ∀ (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 →
      False

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

theorem p_constmask_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  True ∧ (x_1 &&& 65280#32 &&& (x &&& BitVec.ofInt 32 (-65281)) != 0) = true → False

theorem icmp_select_implied_cond_relational_proof : icmp_select_implied_cond_relational_before ⊑ icmp_select_implied_cond_relational_after

theorem or_and_not_constant_commute0_proof : or_and_not_constant_commute0_before ⊑ or_and_not_constant_commute0_after

theorem sub_to_xor_or_commuted_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  (x_1 &&& x) - (x ||| x_1) = 0#32 - (x_1 ^^^ x)

theorem e_1366 :
    5 *  ~~~t - 2 *  ~~~(z &&&  ~~~z) + 5 *  ~~~(z ^^^ t) + 11 * z + 4 * (z ^^^ t) - 7 *  ~~~(z &&& t) + 10 *  ~~~(z ||| t) + 16 *  ~~~(z |||  ~~~t) - 11 * (z &&&  ~~~t) - 14 * (z &&& t) = 11 *  ~~~z

theorem positive_biggershl_shlnsw_lshrexact_proof : positive_biggershl_shlnsw_lshrexact_before ⊑ positive_biggershl_shlnsw_lshrexact_after

theorem n7_proof : n7_before ⊑ n7_after

theorem PR42691_9_logical_proof : PR42691_9_logical_before ⊑ PR42691_9_logical_after

theorem test3_thm (e : IntW 1) (e_1 : IntW 599) :
  LLVM.udiv e_1 (select e (const? 599 70368744177664) (const? 599 4096)) ⊑
    lshr e_1 (select e (const? 599 46) (const? 599 12))

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

theorem zext_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → 1#41 = zeroExtend 41 x

theorem positive_biggershl_shlnuw_lshrexact_thm (e : IntW 8) :
  shl (lshr e (const? 8 3) { «exact» := true }) (const? 8 6) { «nsw» := false, «nuw» := true } ⊑
    shl e (const? 8 3) { «nsw» := false, «nuw» := true }

@[simp]
theorem BitStream.EqualUpTo_of_concat_EqualUpTo_concat
  (x y : BitStream) (n : Nat) :
  BitStream.EqualUpTo (n + 1) (.concat b x) (.concat b y) ↔
  BitStream.EqualUpTo n x y

theorem test21_proof : test21_before ⊑ test21_after

theorem or_test2_thm (e : IntW 7) : LLVM.or (shl e (const? 7 6)) (const? 7 (-64)) ⊑ const? 7 (-64)

theorem or_to_nxor2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  x_1 &&& x ||

theorem trunc_lshr_sext_exact_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(True ∧ signExtend 32 x >>> 6#32 <<< 6#32 ≠ signExtend 32 x ∨ 6#32 ≥ ↑32) →
    ¬(True ∧ x >>> 6#8 <<< 6#8 ≠ x ∨ 6#8 ≥ ↑8) → truncate 8 (signExtend 32 x >>> 6#32) = x.sshiftRight' 6#8

theorem logical_and_bitwise_and_icmps_comm2_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8),
  ofBool (x_2 &&& 1#8 != 0#8) &&& ofBool (x_1 == 42#8) = 1#1 →
    ¬x ≥ ↑8 → True ∧ 1#8 <<< x >>> x ≠ 1#8 ∨ x ≥ ↑8 → False

theorem eq_umax3_proof : eq_umax3_before ⊑ eq_umax3_after

theorem select_lshr_icmp_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 == 0#32) = 1#1 → ¬x_1 ≥ ↑32 → x >>> x_1 = x

theorem R.fromTensor_eq_fromTensor_trimTensor (tensor : List Int) :
   R.fromTensor (q := q) (n := n) (trimTensor tensor) = R.fromTensor (q := q) (n := n) tensor

theorem t0_proof : t0_before ⊑ t0_after

theorem test3_proof : test3_before ⊑ test3_after

theorem f1_logical_thm (e : IntW 32) :
  select (icmp IntPred.ne (trunc 8 e) (const? 8 0))
      (icmp IntPred.ne (LLVM.and e (const? 32 16711680)) (const? 32 0)) (const? 1 0) ⊑
    LLVM.and (icmp IntPred.ne (trunc 8 e) (const? 8 0))
      (icmp IntPred.ne (LLVM.and e (const? 32 16711680)) (const? 32 0))

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

theorem sdiv2_proof : sdiv2_before ⊑ sdiv2_after

theorem sdiv_mul_shl_nsw_proof : sdiv_mul_shl_nsw_before ⊑ sdiv_mul_shl_nsw_after

theorem e_2387 :
    1 *  ~~~(d &&& e) + 2 * (e &&&  ~~~(d ^^^ f)) + 7 * ((d &&& e) |||  ~~~(e |||  ~~~f)) - 3 *  ~~~(d ^^^ f) - 11 * (f &&&  ~~~(d &&&  ~~~e)) + 4 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 5 * (e ^^^ (d &&& (e ||| f))) + 11 * (d ^^^ (e ||| f)) - 2 * (f ^^^  ~~~(d &&&  ~~~e)) + 2 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) - 3 * (d &&&  ~~~e) + 7 * (d &&& (e ||| f)) + 4 * (f ^^^ (d ||| ( ~~~e ||| f))) + 5 * (f ^^^ (d &&& e)) + 3 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 2 * ( ~~~d &&& ( ~~~e ||| f)) - 1 *  ~~~(d &&& ( ~~~e ||| f)) + 1 * (f ^^^  ~~~(d |||  ~~~e)) + 1 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 7 *  ~~~(d |||  ~~~e) - 5 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 1 * (f ^^^  ~~~(d ||| e)) - 2 * (f ^^^ (d &&& (e ||| f))) + 11 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 2 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 3 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 3 * (d &&& (e ^^^ f)) + 1 *  ~~~(d &&& (e &&& f)) - 7 * (e ^^^ (d ||| (e ||| f))) + 4 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 2 * (f ||| (d &&& e)) - 11 * ((d ^^^ e) ||| (d ^^^ f)) - 1 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 2 * (f ^^^  ~~~(d &&& (e &&& f))) - 2 * (d ||| (e ^^^ f)) - 5 *  ~~~( ~~~d &&& (e ^^^ f)) - 2 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 11 * (e &&& (d |||  ~~~f)) + 1 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 2 * (e ||| (d ^^^ f)) - 1 * (d ^^^ ( ~~~e &&& f)) + 2 * (e ^^^ (d &&&  ~~~f)) - 1 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 3 *  ~~~(e &&&  ~~~f) + 1 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 1 * f + 2 * (e ^^^  ~~~(d ||| f)) - 7 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 3 * ((d ||| e) &&& (e ^^^ f)) + 5 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 6 * (d ^^^ f) + 11 * (e &&&  ~~~f) + 2 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 1 * (d &&& e) + 1 * ((d &&& e) ||| (e ^^^ f)) - 7 * (f &&&  ~~~(d &&& e)) - 5 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 7 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 11 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 4 * (e ^^^ (d ||| f)) - 2 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 2 * d - 5 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 1 *  ~~~(d ||| (e ||| f)) - 8 *  ~~~(d ||| ( ~~~e ||| f)) - 4 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 8 * ( ~~~d &&& ( ~~~e &&& f)) + 44 * ( ~~~d &&& (e &&& f)) + 12 * (d &&& ( ~~~e &&& f)) + 22 * (d &&& (e &&& f)) = 6 *  ~~~(d ^^^ (e &&& f)) - 1 * ((d &&& e) |||  ~~~(e ||| f))

theorem ashrsgt_03_15_exact_proof : ashrsgt_03_15_exact_before ⊑ ashrsgt_03_15_exact_after

theorem test2_proof : test2_before ⊑ test2_after

theorem icmp_sgt1_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (x <<< 1#8).sshiftRight' 1#8 ≠ x ∨ 1#8 ≥ ↑8) →
    ofBool (BitVec.ofInt 8 (-128) <ₛ x <<< 1#8) = ofBool (x != BitVec.ofInt 8 (-64))

theorem or_eq_with_one_bit_diff_constants3_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x == BitVec.ofInt 8 (-2)) ||

theorem xor_of_icmps_to_ne_commute_thm (e : IntW 64) :
  LLVM.xor (icmp IntPred.slt e (const? 64 6)) (icmp IntPred.sgt e (const? 64 4)) ⊑
    icmp IntPred.ne e (const? 64 5)

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

theorem test32_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬2#32 ≥ ↑32 → (x &&& 16#32) >>> 2#32 &&& 1#32 = 0#32

theorem shift_no_xor_multiuse_cmp_thm.extracted_1._7 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ¬ofBool (x_3 &&& 1#32 == 0#32) = 1#1 →
    True ∧ ((x_3 &&& 1#32) <<< 1#32).sshiftRight' 1#32 ≠ x_3 &&& 1#32 ∨
        True ∧ (x_3 &&& 1#32) <<< 1#32 >>> 1#32 ≠ x_3 &&& 1#32 ∨ 1#32 ≥ ↑32 →
      False

theorem and_orn_cmp_3_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 72),
  ofBool (x <ᵤ x_1) = 1#1 → ofBool (x_1 ≤ᵤ x) = 1#1 → False

theorem select_xor_icmp2_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 != 0#32) = 1#1 → ¬ofBool (x_1 == 0#32) = 1#1 → False

theorem e_1574 :
     - 5 * (b &&& c) + 1 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 2 * ((a &&& c) ||| (b &&&  ~~~c)) - 6 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) + 2 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) - 7 * (b ^^^ (a ||| c)) + 1 * (b ^^^  ~~~( ~~~a ||| (b ^^^ c))) + 4 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) - 5 *  ~~~(a ||| (b ||| c)) + 12 *  ~~~(a ||| ( ~~~b ||| c)) + 4 *  ~~~( ~~~a ||| (b ||| c)) - 7 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 7 * ( ~~~a &&& ( ~~~b &&& c)) + 6 * ( ~~~a &&& (b &&& c)) + 10 * (a &&& ( ~~~b &&& c)) + 14 * (a &&& (b &&& c)) = 5 *  ~~~(a ^^^ ( ~~~b ||| c))

theorem e_2038 :
     - 6 * f + 5 * ( ~~~e &&&  ~~~(d ^^^ f)) - 1 *  ~~~(d &&& (e &&& f)) - 11 *  ~~~(d ||| ( ~~~e &&& f)) - 2 *  ~~~(d &&& e) + 3 * ( ~~~d &&& (e ||| f)) - 2 * ( ~~~e ||| (d ^^^ f)) + 3 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 2 * (e &&& (d ||| f)) + 11 * (f |||  ~~~(d ||| e)) + 1 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) - 5 * (d ^^^ e) - 1 * (f ^^^ ( ~~~d &&& (e ||| f))) - 5 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 1 * (e |||  ~~~f) + 1 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 3 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 5 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 1 * ((d &&& f) |||  ~~~(e ||| f)) + 11 *  ~~~(d &&&  ~~~e) - 6 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 5 * ((d ^^^ e) ||| (d ^^^ f)) - 11 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 7 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 2 * (d ||| (e ^^^ f)) - 1 *  ~~~(d ^^^ (e ^^^ f)) - 7 * (d ^^^ f) + 2 * (f ^^^ (d ||| ( ~~~e &&& f))) + 3 *  ~~~(d &&& ( ~~~e &&& f)) + 16 *  ~~~(d ||| (e ||| f)) + 3 *  ~~~(d ||| ( ~~~e ||| f)) + 24 *  ~~~( ~~~d ||| (e ||| f)) + 12 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 2 * ( ~~~d &&& ( ~~~e &&& f)) + 13 * ( ~~~d &&& (e &&& f)) - 20 * (d &&& (e &&& f)) =  - 16 * (d &&& ( ~~~e &&& f))

theorem test_lshr_exact__exact_is_unsafe_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 63#32 == 0#32) = 1#1 →
    ¬(True ∧ (x_1 &&& 63#32) >>> 2#32 <<< 2#32 ≠ x_1 &&& 63#32 ∨
          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 bools_logical_thm.extracted_1._8 : ∀ (x x_1 : BitVec 1),
  ¬x_1 ^^^ 1#1 = 1#1 → ¬x_1 = 1#1 → 0#1 = 1#1 → 1#1 = x

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

theorem zext_zext_sgt_proof : zext_zext_sgt_before ⊑ zext_zext_sgt_after

theorem add_eq_xor_add_mul_and_1 (x y : BitVec w) :
    x + y = (x ^^^ y) + 2 * (x &&& y)

theorem bv_AndOrXor_2663 :
    ∀ (e e_1 : LLVM.IntW w),
      LLVM.xor (LLVM.icmp LLVM.IntPred.ule e e_1) (LLVM.icmp LLVM.IntPred.ne e e_1) ⊑ LLVM.icmp LLVM.IntPred.uge e e_1

theorem sub_select_not_zext_thm.extracted_1._1 : ∀ (x : BitVec 1),
  ¬x = 1#1 → 64#64 - zeroExtend 64 (x ^^^ 1#1) = 63#64

theorem positive_biggerShl_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬(10#32 ≥ ↑32 ∨ 5#32 ≥ ↑32) → 5#32 ≥ ↑32 → False

theorem samesign_commute3_thm (e e_1 : IntW 32) :
  LLVM.or (icmp IntPred.sgt (LLVM.or e_1 e) (const? 32 (-1)))
      (icmp IntPred.slt (LLVM.and e e_1) (const? 32 0)) ⊑
    icmp IntPred.sgt (LLVM.xor e_1 e) (const? 32 (-1))

theorem sel_false_val_is_a_masked_lshr_of_true_val1_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& 60#32 == 0#32) = 1#1 →
    2#32 ≥ ↑32 ∨ True ∧ (x_1 >>> 2#32 &&& 15#32).msb = true ∨ zeroExtend 64 (x_1 >>> 2#32 &&& 15#32) ≥ ↑64 → False

theorem or_to_nxor_multiuse_thm (e e_1 : IntW 32) :
  mul (mul (LLVM.and e_1 e) (LLVM.xor (LLVM.or e_1 e) (const? 32 (-1))))
      (LLVM.or (LLVM.and e_1 e) (LLVM.xor (LLVM.or e_1 e) (const? 32 (-1)))) ⊑
    mul (mul (LLVM.and e_1 e) (LLVM.xor (LLVM.or e_1 e) (const? 32 (-1))))
      (LLVM.or (LLVM.and e_1 e) (LLVM.xor (LLVM.or e_1 e) (const? 32 (-1))) { «disjoint» := true })

theorem PR52261_thm.extracted_1._2 : ∀ (x : BitVec 1),
  ¬x = 1#1 →
    ¬(True ∧ (0#32).ssubOverflow (BitVec.ofInt 32 (-2)) = true) →
      BitVec.ofInt 32 (-2) &&& 0#32 - BitVec.ofInt 32 (-2) = 2#32

theorem e_427 :
     - 11 * (x ^^^ y) + 7 * y + 1 *  ~~~(x &&& y) - 1 *  ~~~(x &&&  ~~~y) - 1 *  ~~~(x ^^^ y) + 4 *  ~~~(x |||  ~~~y) + 9 * (x &&&  ~~~y) - 5 * (x &&& y) =  - 1 *  ~~~y

theorem slt_zero_ult_i1_fail1_thm (e : IntW 32) (e_1 : IntW 1) :
  icmp IntPred.ult (zext 32 e_1) (lshr e (const? 32 30)) ⊑
    icmp IntPred.ugt (lshr e (const? 32 30)) (zext 32 e_1)

theorem test_add__nuw_is_safe_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 2147483647#32 == 2147483647#32) = 1#1 →
    True ∧ (x &&& 2147483647#32).uaddOverflow 1#32 = true → False

theorem t2_proof : t2_before ⊑ t2_after

theorem t2_symmetry_proof : t2_symmetry_before ⊑ t2_symmetry_after

theorem p_constmask2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (x_1 &&& 61440#32 &&& (x &&& BitVec.ofInt 32 (-65281)) != 0) = true) →
    x_1 &&& 61440#32 ^^^ x &&& BitVec.ofInt 32 (-65281) = x_1 &&& 61440#32 ||

theorem lshrult_03_00_exact_proof : lshrult_03_00_exact_before ⊑ lshrult_03_00_exact_after

theorem ashr_ugt_4_proof : ashr_ugt_4_before ⊑ ashr_ugt_4_after

theorem sge_or_not_max_commute_proof : sge_or_not_max_commute_before ⊑ sge_or_not_max_commute_after

theorem main7d_logical_thm.extracted_1._11 : ∀ (x x_1 x_2 x_3 x_4 : BitVec 32),
  ofBool (x_4 &&& (x_3 &&& x_2) == x_3 &&& x_2) = 1#1 →
    ¬ofBool (x_4 &&& (x_3 &&& x_2) != x_3 &&& x_2) = 1#1 →
      ofBool (x_4 &&& (x_1 &&& x) == x_1 &&& x) = 1#1 →
        0#32 = zeroExtend 32 (ofBool (x_4 &&& (x_1 &&& x) != x_1 &&& x))

theorem bools_multi_uses2_logical_proof : bools_multi_uses2_logical_before ⊑ bools_multi_uses2_logical_after

theorem multiuse_select_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → 64#64 * (64#64 - zeroExtend 64 x) = 4032#64

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 t7_twoshifts2_proof : t7_twoshifts2_before ⊑ t7_twoshifts2_after

theorem sel_false_val_is_a_masked_lshr_of_true_val1_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& 60#32 == 0#32) = 1#1 →
    ¬(2#32 ≥ ↑32 ∨ True ∧ (x_1 >>> 2#32 &&& 15#32).msb = true ∨ zeroExtend 64 (x_1 >>> 2#32 &&& 15#32) ≥ ↑64) →
      x = x.sshiftRight' (zeroExtend 64 (x_1 >>> 2#32 &&& 15#32))

theorem shl_xor_proof : shl_xor_before ⊑ shl_xor_after

lemma reduce_stepSet' {M : NFA α σ} (q : M.Reachable) (S1 : Set M.Reachable) (S2 : Set σ) :
    (∀ q, (∃ hq, S1 ⟨q, hq⟩) ↔ S2 q) →
    (q ∈ M.reduce.stepSet S1 a → q.val ∈ M.stepSet S2 a)

@[simp] theorem cons_getElem_toCons (x : A a) (v : Var Γ u)
    (h : as = Γ.toList := by rfl) (h' : a :: as = (Γ.cons a).toList := by rfl) :
    (HVector.cons x xs)[v.toCons (t' := a)]'h' = xs[v]'h

theorem test2_thm (e : IntW 15) : LLVM.xor e (const? 15 0) ⊑ e

theorem sgt_smin3_thm (e e_1 : IntW 32) :
  icmp IntPred.slt (add e_1 (const? 32 3))
      (select (icmp IntPred.slt (add e_1 (const? 32 3)) e) (add e_1 (const? 32 3)) e) ⊑
    const? 1 0

theorem shl_shl_proof : shl_shl_before ⊑ shl_shl_after

theorem e_1317 :
    4 * t - 7 *  ~~~t + 1 * (z ||| t) - 6 *  ~~~(z ^^^ t) - 6 *  ~~~(z &&& t) + 7 *  ~~~(z &&&  ~~~z) + 1 * (z |||  ~~~t) - 6 *  ~~~(z |||  ~~~t) + 4 * (z &&&  ~~~t) = 7 * (z &&& t) - 11 *  ~~~(z ||| t)

theorem or_ne_notY_eq_1s_proof : or_ne_notY_eq_1s_before ⊑ or_ne_notY_eq_1s_after

theorem no_shift_no_xor_multiuse_cmp_or_proof : no_shift_no_xor_multiuse_cmp_or_before ⊑ no_shift_no_xor_multiuse_cmp_or_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_4_thm (e : IntW 32) :
  LLVM.or (icmp IntPred.ne (LLVM.and e (const? 32 15)) (const? 32 8))
      (icmp IntPred.eq (LLVM.and e (const? 32 255)) (const? 32 0)) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 15)) (const? 32 8)

theorem sub_ule_sext_proof : sub_ule_sext_before ⊑ sub_ule_sext_after

theorem scalar_i32_shl_and_signbit_slt_thm (e e_1 : IntW 32) :
  icmp IntPred.slt (LLVM.and (shl e_1 e) (const? 32 (-2147483648))) (const? 32 0) ⊑
    icmp IntPred.slt (shl e_1 e) (const? 32 0)

theorem sdiv_common_dividend_defined_cond_proof : sdiv_common_dividend_defined_cond_before ⊑ sdiv_common_dividend_defined_cond_after

theorem trunc_sel_larger_sext_proof : trunc_sel_larger_sext_before ⊑ trunc_sel_larger_sext_after

theorem test7_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬32#128 ≥ ↑128 → 32#64 ≥ ↑64 ∨ True ∧ (x >>> 32#64).msb = true → False

theorem test8_thm.extracted_1._1 : ∀ (x : BitVec 7), ¬(4#7 ≥ ↑7 ∨ 3#7 ≥ ↑7) → x <<< 4#7 <<< 3#7 = 0#7

theorem e_1150 :
    1 *  ~~~t - 3 *  ~~~(z &&& t) + 2 * (z ||| t) + 7 * z + 11 *  ~~~z - 14 *  ~~~(z ||| t) - 15 *  ~~~(z |||  ~~~t) - 14 * (z &&& t) = 12 * (z &&&  ~~~t) - 5 *  ~~~(z &&&  ~~~z)

theorem select_and_icmp_zero_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.eq e_2 (const? 32 0)) (LLVM.and e_2 e_1) e ⊑
    select (icmp IntPred.eq e_2 (const? 32 0)) (const? 32 0) e

@[simp, simp_denote, simp_sllvm]
lemma run_pure : StateT.run (pure x : EffectM α) s = .value (x, s)

theorem samesign_inverted_commute3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 ||| x <ₛ 0#32) &&& ofBool (-1#32 <ₛ x &&& x_1) = ofBool (x_1 ^^^ x <ₛ 0#32)

theorem lshrugt_01_13_proof : lshrugt_01_13_before ⊑ lshrugt_01_13_after

theorem e_1585 :
    5 * (b ^^^  ~~~(a &&& (b ^^^ c))) - 1 *  ~~~( ~~~a &&& (b &&& c)) - 1 * (a ||| b) - 2 * (c ||| (a &&&  ~~~b)) - 7 * ( ~~~b ||| (a ^^^ c)) + 4 * (a ^^^ (b &&& c)) - 2 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) - 5 * (b ^^^ (a &&& (b ||| c))) - 6 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 2 * (c &&& (a |||  ~~~b)) + 1 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) + 10 *  ~~~(a ||| (b ||| c)) + 7 *  ~~~(a ||| ( ~~~b ||| c)) - 1 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 12 * ( ~~~a &&& ( ~~~b &&& c)) + 12 * ( ~~~a &&& (b &&& c)) + 14 * (a &&& ( ~~~b &&& c)) =  - 14 * (a &&& (b &&& c)) - 1 *  ~~~( ~~~a ||| (b ||| c))

theorem sub_to_xor_proof : sub_to_xor_before ⊑ sub_to_xor_after

theorem e_1578 :
    1 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) + 3 * (c &&& (a ||| b)) - 1 *  ~~~c + 4 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 1 *  ~~~(b &&& c) + 1 * (c ^^^ (a &&& (b ||| c))) - 5 * ((a ^^^ b) ||| (a ^^^ c)) + 2 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) - 7 * ((a &&&  ~~~b) ||| (a ^^^ (b ^^^ c))) - 3 * (b ^^^  ~~~(a ||| (b &&& c))) + 3 * (b ^^^ ( ~~~a &&& (b ||| c))) + 12 *  ~~~(a ||| ( ~~~b ||| c)) + 11 *  ~~~( ~~~a ||| (b ||| c)) + 4 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 7 * ( ~~~a &&& ( ~~~b &&& c)) + 7 * (a &&& ( ~~~b &&& c)) =  - 3 * ( ~~~a &&& (b &&& c))

theorem test5_apint_proof : test5_apint_before ⊑ test5_apint_after

theorem sub_to_and_and_commuted_thm (e e_1 : IntW 32) :
  sub (LLVM.xor e_1 e) (LLVM.or e e_1) ⊑ sub (const? 32 0) (LLVM.and e_1 e)

theorem t0_thm.extracted_1._14 : ∀ (x x_1 x_2 : BitVec 8) (x_3 : BitVec 1),
  ¬x_3 ^^^ 1#1 = 1#1 → ¬x_3 = 1#1 → ofBool (x_2 == x_1) = 1#1 → 0#1 = 1#1 → False

theorem p_constmask2_proof : p_constmask2_before ⊑ p_constmask2_after

theorem shl_sub_lshr_reverse_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ x_1 <<< x >>> x ≠ x_1 ∨
        x ≥ ↑32 ∨
          True ∧ x_2.ssubOverflow (x_1 <<< x) = true ∨
            True ∧ x_2.usubOverflow (x_1 <<< x) = true ∨
              True ∧ (x_2 - x_1 <<< x) >>> x <<< x ≠ x_2 - x_1 <<< x ∨ x ≥ ↑32) →
    ¬(True ∧ x_2 >>> x <<< x ≠ x_2 ∨
          x ≥ ↑32 ∨ True ∧ (x_2 >>> x).ssubOverflow x_1 = true ∨ True ∧ (x_2 >>> x).usubOverflow x_1 = true) →
      (x_2 - x_1 <<< x) >>> x = x_2 >>> x - x_1

theorem t6_no_extrause_proof : t6_no_extrause_before ⊑ t6_no_extrause_after

theorem lshr_shl_eq_amt_multi_use_thm.extracted_1._2 : ∀ (x : BitVec 43),
  ¬(23#43 ≥ ↑43 ∨ 23#43 ≥ ↑43 ∨ 23#43 ≥ ↑43) →
    ¬23#43 ≥ ↑43 → x >>> 23#43 * x >>> 23#43 <<< 23#43 = x >>> 23#43 * (x &&& BitVec.ofInt 43 (-8388608))

theorem scalar_i32_lshr_and_negC_slt_thm (e e_1 : IntW 32) :
  icmp IntPred.slt (LLVM.and (lshr e_1 e) (const? 32 (-2147483648))) (const? 32 0) ⊑
    icmp IntPred.slt (lshr e_1 e) (const? 32 0)

@[simp] theorem cons_append : (x ::ₕ xs) ++ ys = (x ::ₕ (xs ++ ys))

theorem fast_div_201_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(8#16 ≥ ↑16 ∨ 8#16 ≥ ↑16 ∨ 1#8 ≥ ↑8 ∨ 7#8 ≥ ↑8) →
    ¬(True ∧ (zeroExtend 16 x).smulOverflow 71#16 = true ∨
          True ∧ (zeroExtend 16 x).umulOverflow 71#16 = true ∨
            8#16 ≥ ↑16 ∨
              True ∧
                  signExtend 16 (truncate 8 ((zeroExtend 16 x * 71#16) >>> 8#16)) ≠ (zeroExtend 16 x * 71#16) >>> 8#16 ∨
                True ∧
                    zeroExtend 16 (truncate 8 ((zeroExtend 16 x * 71#16) >>> 8#16)) ≠
                      (zeroExtend 16 x * 71#16) >>> 8#16 ∨
                  1#8 ≥ ↑8 ∨
                    True ∧ (zeroExtend 16 x).smulOverflow 71#16 = true ∨
                      True ∧ (zeroExtend 16 x).umulOverflow 71#16 = true ∨
                        8#16 ≥ ↑16 ∨
                          True ∧
                              signExtend 16 (truncate 8 ((zeroExtend 16 x * 71#16) >>> 8#16)) ≠
                                (zeroExtend 16 x * 71#16) >>> 8#16 ∨
                            True ∧
                                zeroExtend 16 (truncate 8 ((zeroExtend 16 x * 71#16) >>> 8#16)) ≠
                                  (zeroExtend 16 x * 71#16) >>> 8#16 ∨
                              True ∧
                                  ((x - truncate 8 ((zeroExtend 16 x * 71#16) >>> 8#16)) >>> 1#8).uaddOverflow
                                      (truncate 8 ((zeroExtend 16 x * 71#16) >>> 8#16)) =
                                    true ∨
                                7#8 ≥ ↑8) →
      (truncate 8 ((zeroExtend 16 x * 71#16) >>> 8#16) +
            (x - truncate 8 ((zeroExtend 16 x * 71#16) >>> 8#16)) >>> 1#8) >>>
          7#8 =
        ((x - truncate 8 ((zeroExtend 16 x * 71#16) >>> 8#16)) >>> 1#8 +
            truncate 8 ((zeroExtend 16 x * 71#16) >>> 8#16)) >>>
          7#8

theorem positive_sameconst_shlnuwnsw_proof : positive_sameconst_shlnuwnsw_before ⊑ positive_sameconst_shlnuwnsw_after

theorem ashrslt_03_07_proof : ashrslt_03_07_before ⊑ ashrslt_03_07_after

theorem test_add_nsw__all_are_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 1073741823#32 == 3#32) = 1#1 →
    ¬(True ∧ (x &&& 1073741823#32).saddOverflow 1#32 = true ∨ True ∧ (x &&& 1073741823#32).uaddOverflow 1#32 = true) →
      4#32 = (x &&& 1073741823#32) + 1#32

theorem pow2_or_zero_is_negative_commute_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (0#8 - 42#8 * x &&& 42#8 * x <ₛ 0#8) = ofBool (x * 42#8 == BitVec.ofInt 8 (-128))

theorem a_false_implies_b_true_thm (e e_1 : IntW 1) (e_2 : IntW 8) :
  select (icmp IntPred.ugt e_2 (const? 8 10)) (const? 1 1)
      (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 t1_ult_slt_0_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.ult e_2 (const? 32 65536)) e_2 (select (icmp IntPred.slt e_2 (const? 32 0)) e_1 e) ⊑
    select (icmp IntPred.sgt e_2 (const? 32 65535)) e
      (select (icmp IntPred.slt e_2 (const? 32 0)) e_1 e_2)

theorem not_mul_of_pow2_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  True ∧ (x_1 &&& 255#32).smulOverflow (x &&& 12#32) = true ∨
      True ∧ (x_1 &&& 255#32).umulOverflow (x &&& 12#32) = true →
    False

theorem t2_proof : t2_before ⊑ t2_after

theorem n7_proof : n7_before ⊑ n7_after

theorem bitwise_and_bitwise_and_icmps_comm3_thm (e e_1 e_2 : IntW 8) :
  LLVM.and (icmp IntPred.ne (LLVM.and e_2 (shl (const? 8 1) e_1)) (const? 8 0))
      (LLVM.and (icmp IntPred.ne (LLVM.and e_2 (const? 8 1)) (const? 8 0))
        (icmp IntPred.eq e (const? 8 42))) ⊑
    LLVM.and
      (icmp IntPred.eq
        (LLVM.and e_2 (LLVM.or (shl (const? 8 1) e_1 { «nsw» := false, «nuw» := true }) (const? 8 1)))
        (LLVM.or (shl (const? 8 1) e_1 { «nsw» := false, «nuw» := true }) (const? 8 1)))
      (icmp IntPred.eq e (const? 8 42))

theorem not_and_and_or_not_or_or_commute3_proof : not_and_and_or_not_or_or_commute3_before ⊑ not_and_and_or_not_or_or_commute3_after

theorem e_1246 :
    4 *  ~~~t + 4 *  ~~~(z &&&  ~~~t) - 1 * z + 1 * (z ^^^ t) + 1 *  ~~~z + 4 *  ~~~(z &&& t) - 13 *  ~~~(z ||| t) - 9 * (z &&&  ~~~t) - 4 * (z &&& t) =  - 1 * (z ||| t) + 11 *  ~~~(z |||  ~~~t)

theorem scalar1_proof : scalar1_before ⊑ scalar1_after

theorem and_not_eq_or_sub:
    x &&& ~~~ y = (x ||| y) - y

theorem scalar_i32_shl_and_signbit_eq_proof : scalar_i32_shl_and_signbit_eq_before ⊑ scalar_i32_shl_and_signbit_eq_after

theorem e_570 :
     - 2 * (x |||  ~~~y) - 2 *  ~~~(x ^^^ y) - 1 *  ~~~(x &&&  ~~~x) - 2 * y - 1 *  ~~~x + 11 *  ~~~y + 3 *  ~~~(x &&& y) + 1 *  ~~~(x |||  ~~~y) + 7 * (x &&& y) = 8 *  ~~~(x ||| y) + 11 * (x &&&  ~~~y)

theorem uge_and_max_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == -1#8) &&& ofBool (x ≤ᵤ x_1) = ofBool (x_1 == -1#8)

theorem no_reassoc_add_nuw_none_proof : no_reassoc_add_nuw_none_before ⊑ no_reassoc_add_nuw_none_after

theorem icmp_ne_sext_slt_otherwise_nofold_proof : icmp_ne_sext_slt_otherwise_nofold_before ⊑ icmp_ne_sext_slt_otherwise_nofold_after

@[simp] theorem Com.denote_rets {eff : EffectKind} (Γ : Ctxt d.Ty) (vs : HVector Γ.Var ts) :
    (Com.rets (eff := eff) vs).denote = fun V => pure (vs.map V)

theorem e_2329 :
    7 * ( ~~~e |||  ~~~(d ^^^ f)) - 7 * (f &&& (d ||| e)) - 1 *  ~~~(d ^^^ (e ||| f)) + 2 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 3 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * ( ~~~e &&& (d ^^^ f)) + 1 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 11 * ( ~~~f &&& (d ^^^ e)) + 1 * (f ||| (d &&&  ~~~e)) - 2 *  ~~~(d &&&  ~~~f) - 7 * (e &&&  ~~~(d ^^^ f)) - 3 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 2 * d - 7 *  ~~~(d &&& (e &&& f)) - 1 * ( ~~~d &&& ( ~~~e ||| f)) - 2 *  ~~~( ~~~d &&& (e &&& f)) + 5 * ((e &&& f) ||| (d &&& (e ||| f))) + 1 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 2 *  ~~~(d &&& e) + 1 * (e ^^^  ~~~(d &&& (e ||| f))) + 2 * ( ~~~e &&&  ~~~(d ^^^ f)) + 2 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 1 * (f |||  ~~~(d ||| e)) - 5 * (e ^^^ (d ||| ( ~~~e ||| f))) - 6 *  ~~~(e &&&  ~~~f) + 1 * (f ^^^ (d ||| (e ||| f))) - 1 * (e ^^^ ( ~~~d &&& (e ||| f))) - 6 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 1 *  ~~~(e &&& f) + 1 * (f &&&  ~~~(d ^^^ e)) + 4 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 1 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 2 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 1 * (e |||  ~~~(d ^^^ f)) + 1 *  ~~~(d ||| e) + 1 * ( ~~~f &&&  ~~~(d ^^^ e)) - 11 * (d ||| ( ~~~e ||| f)) - 11 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 6 * (e ^^^ (d ||| ( ~~~e &&& f))) + 2 * (e ^^^ (d &&& f)) - 11 * (f ^^^ (d ||| ( ~~~e ||| f))) + 2 * (d ||| (e &&& f)) - 11 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 4 * (d ||| (e ||| f)) - 7 * (e ^^^ (d |||  ~~~f)) - 7 *  ~~~(d |||  ~~~f) - 5 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 3 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 2 * (e &&& (d ||| f)) + 3 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 2 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 3 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 7 * ( ~~~f |||  ~~~(d ^^^ e)) - 2 * (e |||  ~~~(d |||  ~~~f)) + 1 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 6 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 82 *  ~~~(d ||| (e ||| f)) + 13 *  ~~~(d ||| ( ~~~e ||| f)) + 30 *  ~~~( ~~~d ||| (e ||| f)) + 46 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 46 * ( ~~~d &&& ( ~~~e &&& f)) + 59 * ( ~~~d &&& (e &&& f)) + 41 * (d &&& ( ~~~e &&& f)) + 37 * (d &&& (e &&& f)) =  - 4 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) - 2 * ((d ^^^ e) ||| (d ^^^ f))

theorem e_166 :
     - 7 * (x ^^^ y) + 3 * (x |||  ~~~y) - 2 *  ~~~(x ||| y) - 4 *  ~~~(x |||  ~~~y) + 4 * (x &&&  ~~~y) - 13 * (x &&& y) = 1 *  ~~~(x ^^^ y) - 11 * y

theorem select_2_thm.extracted_1._9 : ∀ (x x_1 : BitVec 8) (x_2 x_3 : BitVec 1),
  ¬x_3 = 1#1 → x ^^^ 45#8 ^^^ -1#8 = x ^^^ BitVec.ofInt 8 (-46)

theorem t0_thm.extracted_1._1 : ∀ (x : BitVec 8), ¬(x ≥ ↑8 ∨ x ≥ ↑8) → 7#8 - x ≥ ↑8 → False

theorem lshrult_03_02_proof : lshrult_03_02_before ⊑ lshrult_03_02_after

theorem List.perm_subset_iff_right {l1 l2 : List α} (hperm : l1.Perm l2) (l : List α) :
  l ⊆ l1 ↔ l ⊆ l2

theorem PR44545_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 == 0#32) = 1#1 →
    ¬(True ∧ x.saddOverflow 1#32 = true ∨ True ∧ x.uaddOverflow 1#32 = true) →
      ¬(True ∧ (truncate 16 (x + 1#32)).saddOverflow (-1#16) = true) → truncate 16 (x + 1#32) + -1#16 = truncate 16 x

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

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 zext_sext_sle_known_nonneg_op0_narrow_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 8),
  True ∧ (x_1 &&& 12#8).msb = true → False

theorem negative5_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 <ₛ x &&& 2147483647#32) = 1#1 → ofBool (0#32 ≤ₛ x_1) = 1#1

theorem lshr_and_add_proof : lshr_and_add_before ⊑ lshr_and_add_after

theorem e_754 :
    5 *  ~~~(z ^^^ t) - 2 * (z ^^^ t) + 2 * (z &&&  ~~~t) = 5 *  ~~~(z &&&  ~~~t) - 7 *  ~~~(z |||  ~~~t)

theorem shift_no_xor_multiuse_cmp_with_xor_proof : shift_no_xor_multiuse_cmp_with_xor_before ⊑ shift_no_xor_multiuse_cmp_with_xor_after

theorem unmasked_shlop_insufficient_mask_shift_amount_proof : unmasked_shlop_insufficient_mask_shift_amount_before ⊑ unmasked_shlop_insufficient_mask_shift_amount_after

theorem bor_lor_left1_thm (e e_1 : IntW 1) : select (LLVM.or e_1 e) (const? 1 1) e_1 ⊑ LLVM.or e_1 e

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

theorem sdiv_exact_eq_0_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (LLVM.sdiv e_1 e { «exact» := true }) (const? 8 0) ⊑
    icmp IntPred.eq e_1 (const? 8 0)

theorem alive_AndOrXor_2247__A__B__A__B : alive_AndOrXor_2247__A__B__A__B_src ⊑ alive_AndOrXor_2247__A__B__A__B_tgt

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

theorem positive_biggershl_shlnuw_lshrexact_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(True ∧ x >>> 3#8 <<< 3#8 ≠ x ∨ 3#8 ≥ ↑8 ∨ True ∧ x >>> 3#8 <<< 6#8 >>> 6#8 ≠ x >>> 3#8 ∨ 6#8 ≥ ↑8) →
    ¬(True ∧ x <<< 3#8 >>> 3#8 ≠ x ∨ 3#8 ≥ ↑8) → x >>> 3#8 <<< 6#8 = x <<< 3#8

theorem not_and_and_or_not_or_or_commute3_thm (e e_1 e_2 : IntW 32) :
  LLVM.or (LLVM.and (LLVM.and (LLVM.sdiv (const? 32 42) e_2) (LLVM.xor e_1 (const? 32 (-1)))) e)
      (LLVM.xor (LLVM.or (LLVM.or (LLVM.sdiv (const? 32 42) e_2) e_1) e) (const? 32 (-1))) ⊑
    LLVM.xor (LLVM.or (LLVM.xor e (LLVM.sdiv (const? 32 42) e_2)) e_1) (const? 32 (-1))

theorem test10_proof : test10_before ⊑ test10_after

theorem and_def {α : Type _} (c d : Circuit α) :
  (c &&& d) = Circuit.simplifyAnd c d

theorem scalar_i8_shl_ult_const_2_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬6#8 ≥ ↑8 → ofBool (x <<< 6#8 <ᵤ 64#8) = ofBool (x &&& 3#8 == 0#8)

theorem negate_zext_thm (e : IntW 1) (e_1 : IntW 8) : sub e_1 (zext 8 e) ⊑ add e_1 (sext 8 e)

theorem badimm2_thm.extracted_1._4 : ∀ (x : BitVec 16),
  ¬(6#8 ≥ ↑8 ∨ 8#16 ≥ ↑16) →
    ¬ofBool ((truncate 8 x).sshiftRight' 6#8 == truncate 8 (x >>> 8#16)) = 1#1 →
      ¬15#16 ≥ ↑16 →
        ¬(6#8 ≥ ↑8 ∨ 8#16 ≥ ↑16 ∨ True ∧ zeroExtend 16 (truncate 8 (x >>> 8#16)) ≠ x >>> 8#16) →
          ¬ofBool (-1#16 <ₛ x) = 1#1 → truncate 8 (x.sshiftRight' 15#16) ^^^ 127#8 = BitVec.ofInt 8 (-128)

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

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

theorem ashrsgt_03_02_proof : ashrsgt_03_02_before ⊑ ashrsgt_03_02_after

theorem logical_or_not_proof : logical_or_not_before ⊑ logical_or_not_after

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

theorem sgt_smin4_proof : sgt_smin4_before ⊑ sgt_smin4_after

theorem a_false_implies_b_false_proof : a_false_implies_b_false_before ⊑ a_false_implies_b_false_after

theorem and_not_or_commute9_thm (e e_1 e_2 : IntW 32) :
  LLVM.and
      (LLVM.or (LLVM.xor (LLVM.and (LLVM.sdiv (const? 32 42) e_2) (LLVM.sdiv (const? 32 42) e_1)) (const? 32 (-1)))
        (LLVM.sdiv (const? 32 42) e))
      (LLVM.or (LLVM.sdiv (const? 32 42) e_1)
        (LLVM.xor (LLVM.and (LLVM.sdiv (const? 32 42) e_2) (LLVM.sdiv (const? 32 42) e)) (const? 32 (-1)))) ⊑
    LLVM.xor
      (LLVM.and (LLVM.xor (LLVM.sdiv (const? 32 42) e_1) (LLVM.sdiv (const? 32 42) e)) (LLVM.sdiv (const? 32 42) e_2))
      (const? 32 (-1))

theorem lshrugt_01_14_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬1#4 ≥ ↑4 → ofBool (BitVec.ofInt 4 (-2) <ᵤ x >>> 1#4) = 0#1

theorem select_sub_icmp_bad_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.eq e_2 (const? 32 0)) (sub e_2 e_1) e ⊑
    select (icmp IntPred.eq e_2 (const? 32 0)) (sub (const? 32 0) e_1) e

theorem lt_unsigned_to_small_signed_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (zeroExtend 32 x <ₛ 17#32) = ofBool (x <ᵤ 17#8)

theorem main7e_logical_thm.extracted_1._2 : ∀ (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 → 1#32 = zeroExtend 32 1#1

theorem select_constants_and_icmp_eq0_zero_tval_proof : select_constants_and_icmp_eq0_zero_tval_before ⊑ select_constants_and_icmp_eq0_zero_tval_after

theorem test_slt_nuw_proof : test_slt_nuw_before ⊑ test_slt_nuw_after

theorem trunc_shl_31_i32_i64_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬31#64 ≥ ↑64 → ¬31#32 ≥ ↑32 → truncate 32 (x <<< 31#64) = truncate 32 x <<< 31#32

theorem uge_swap_or_max_commute_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.eq e_1 (const? 8 (-1))) (icmp IntPred.ule e e_1) ⊑
    icmp IntPred.ule e e_1

theorem test93_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬64#96 ≥ ↑96 → ¬31#32 ≥ ↑32 → truncate 32 (signExtend 96 x >>> 64#96) = x.sshiftRight' 31#32

theorem test9_thm.extracted_1._2 : ∀ (x : BitVec 77),
  ¬(True ∧ (x &&& 562949953421310#77 &&& 1#77 != 0) = true) →
    (x &&& 562949953421310#77) + 1#77 = x &&& 562949953421310#77 ||

theorem test18a_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x &&& BitVec.ofInt 8 (-2) == 0#8) = ofBool (x <ᵤ 2#8)

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 positive_samevar_shlnsw_lshrexact_thm (e e_1 : IntW 8) :
  shl (lshr e_1 e { «exact» := true }) e { «nsw» := true, «nuw» := false } ⊑ e_1

theorem eq_umin3_proof : eq_umin3_before ⊑ eq_umin3_after

@[simp]
theorem BitVec.intCast_eq_ofInt : ((i : Int) : BitVec w) = BitVec.ofInt w i

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

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 shl_add_lshr_flag_preservation_proof : shl_add_lshr_flag_preservation_before ⊑ shl_add_lshr_flag_preservation_after

theorem test67_proof : test67_before ⊑ test67_after

theorem shl_add_nuw_proof : shl_add_nuw_before ⊑ shl_add_nuw_after

theorem alive_AndOrXor_2113___A__B__A___A__B : alive_AndOrXor_2113___A__B__A___A__B_src ⊑ alive_AndOrXor_2113___A__B__A___A__B_tgt

theorem and_slt_to_mask_proof : and_slt_to_mask_before ⊑ and_slt_to_mask_after

theorem fold_icmp_shl_nuw_c2_indivisible_thm (e : IntW 32) :
  icmp IntPred.ult (shl (const? 32 16) e { «nsw» := false, «nuw» := true }) (const? 32 63) ⊑
    icmp IntPred.ult e (const? 32 2)

theorem sle_smax1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x <ₛ x_1) = 1#1 → ofBool (x_1 ≤ₛ x_1) = ofBool (x ≤ₛ x_1)

theorem icmp_eq_sext_ne_zero_proof : icmp_eq_sext_ne_zero_before ⊑ icmp_eq_sext_ne_zero_after

theorem t1_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬24#32 ≥ ↑32 →
    zeroExtend 32 x <<< 24#32 &&& BitVec.ofInt 32 (-2147483648) = signExtend 32 x &&& BitVec.ofInt 32 (-2147483648)

theorem ule_or_min_commute_proof : ule_or_min_commute_before ⊑ ule_or_min_commute_after

theorem lshr_16_add_zext_basic_proof : lshr_16_add_zext_basic_before ⊑ lshr_16_add_zext_basic_after

theorem test2_proof : test2_before ⊑ test2_after

theorem no_shift_no_xor_multiuse_cmp_or_thm (e e_1 e_2 e_3 : IntW 32) :
  mul
      (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))
      (LLVM.or e_2 (const? 32 4096)) ⊑
    mul
      (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))
      (LLVM.or e_2 (const? 32 4096))

theorem exact_lshr_eq_opposite_msb_thm (e : IntW 8) :
  icmp IntPred.eq (lshr (const? 8 (-128)) e { «exact» := true }) (const? 8 1) ⊑
    icmp IntPred.eq e (const? 8 7)

theorem ne_basic_equal_5_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.ne e_1 (const? 8 5)) (icmp IntPred.ule (add e_1 (const? 8 (-5))) e) ⊑
    icmp IntPred.ult (add e_1 (const? 8 (-6))) e

theorem trunc_shl_shl_var_thm (e e_1 : IntW 64) :
  trunc 32 (shl (shl e_1 e) (const? 64 2)) ⊑ shl (trunc 32 (shl e_1 e)) (const? 32 2)

theorem icmp_eq_mul_nsw_nonequal_commuted_proof : icmp_eq_mul_nsw_nonequal_commuted_before ⊑ icmp_eq_mul_nsw_nonequal_commuted_after

lemma CNFA.reverse_spec {m : CNFA n} : m.reverse.Sim m.toNFA'.reverse

theorem add_smax_simplify2_proof : add_smax_simplify2_before ⊑ add_smax_simplify2_after

@[simp] theorem borrow_zero (x y : BitStream) : (x.borrow y 0) = (!(x 0) && y 0)

theorem land_band_left2_proof : land_band_left2_before ⊑ land_band_left2_after

theorem ule_swap_or_not_min_commute_proof : ule_swap_or_not_min_commute_before ⊑ ule_swap_or_not_min_commute_after

theorem zext_sext_add_icmp_slt_minus1_proof : zext_sext_add_icmp_slt_minus1_before ⊑ zext_sext_add_icmp_slt_minus1_after

theorem icmp_eq_and_pow2_shl_pow2_negative1_proof : icmp_eq_and_pow2_shl_pow2_negative1_before ⊑ icmp_eq_and_pow2_shl_pow2_negative1_after

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

theorem land_band_left2_thm (e e_1 : IntW 1) : LLVM.and (select e_1 e (const? 1 0)) e ⊑ select e_1 e (const? 1 0)

theorem e_2492 :
     - 1 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 5 * ((d &&& e) |||  ~~~(e ||| f)) + 2 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 11 * (d &&& e) - 1 * (e ^^^ (d ||| (e &&& f))) - 2 * ((d ^^^ e) &&& (d ^^^ f)) - 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 3 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 3 * (f ^^^  ~~~(d &&& (e ||| f))) + 5 * (f ^^^  ~~~(d &&& (e &&& f))) - 6 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 4 * (e ^^^ (d &&& f)) + 4 *  ~~~( ~~~d &&& (e ||| f)) + 3 * d - 11 * (e ^^^ (d ||| (e ^^^ f))) - 11 * (e ^^^ (d &&&  ~~~f)) + 2 * (d &&&  ~~~f) - 3 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 1 * (e ||| (d &&& f)) - 1 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 6 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 2 * (d &&& (e ||| f)) + 3 * (d ^^^ ( ~~~e ||| f)) - 7 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 3 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) - 5 * ((d &&& e) ^^^ (e |||  ~~~f)) + 4 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 11 * (e &&& f) - 7 * ( ~~~d ||| (e ^^^ f)) - 1 * ((d ^^^ e) ||| (d ^^^ f)) + 11 * (e |||  ~~~(d ||| f)) + 1 *  ~~~(e |||  ~~~f) - 2 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) - 2 * (e ^^^ ( ~~~d ||| (e &&& f))) - 11 * ( ~~~d ||| ( ~~~e ||| f)) + 2 * ((d &&& f) ||| (e &&&  ~~~f)) - 11 *  ~~~(d ^^^ f) + 1 *  ~~~(d &&& e) + 7 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 6 * (e ^^^  ~~~(d &&& (e ||| f))) - 5 * (f &&&  ~~~(d &&&  ~~~e)) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 5 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) + 5 * (f ||| (d ^^^ e)) - 2 * (f ^^^ (d ||| ( ~~~e &&& f))) - 2 *  ~~~(d &&& (e ^^^ f)) + 1 *  ~~~(d &&& f) + 5 * (f ^^^ (d &&& e)) - 2 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 1 * (e ^^^ (d ||| f)) - 3 * (f ||| (d &&& e)) - 1 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 2 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 2 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 11 *  ~~~(d |||  ~~~e) - 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) + 11 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 1 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 7 * ( ~~~d &&& (e ^^^ f)) + 1 * (d ||| e) + 7 * ( ~~~e &&&  ~~~(d ^^^ f)) - 5 * (f ^^^ (d ||| (e ||| f))) + 2 *  ~~~(e &&&  ~~~f) + 4 * (e ^^^  ~~~(d ||| (e &&& f))) + 1 * (e ||| f) + 11 * (d ^^^ (e ||| f)) + 1 *  ~~~(d ^^^ (e &&& f)) + 4 * (f ^^^  ~~~(d ||| e)) - 2 *  ~~~(d &&& ( ~~~e ||| f)) + 11 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 7 * (d ||| ( ~~~e ||| f)) + 1 * (e ||| (d &&&  ~~~f)) + 7 *  ~~~(d ||| (e ||| f)) + 17 *  ~~~(d ||| ( ~~~e ||| f)) + 44 *  ~~~( ~~~d ||| (e ||| f)) - 41 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 13 * ( ~~~d &&& ( ~~~e &&& f)) + 42 * ( ~~~d &&& (e &&& f)) + 20 * (d &&& ( ~~~e &&& f)) + 29 * (d &&& (e &&& f)) = 5 * (e ^^^ ( ~~~d &&& (e ||| f)))

theorem zext_sext_sle_known_nonneg_op0_narrow_proof : zext_sext_sle_known_nonneg_op0_narrow_before ⊑ zext_sext_sle_known_nonneg_op0_narrow_after

theorem test_shift_negative_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧
          ((x_1 ||| BitVec.ofInt 32 (-2147483648)) <<< (x &&& 7#32)).sshiftRight' (x &&& 7#32) ≠
            x_1 ||| BitVec.ofInt 32 (-2147483648) ∨
        x &&& 7#32 ≥ ↑32) →
    ofBool ((x_1 ||| BitVec.ofInt 32 (-2147483648)) <<< (x &&& 7#32) <ₛ 0#32) = 1#1

theorem or_umin_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (15#32 <ᵤ x) = 1#1 → 15#32 ||

theorem icmp_sle3_proof : icmp_sle3_before ⊑ icmp_sle3_after

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 mul_splat_fold_thm (e : IntW 32) :
  lshr (mul e (const? 32 65537) { «nsw» := false, «nuw» := true }) (const? 32 16) ⊑ e

@[simp] theorem Lets.denote_nil {Γ : Ctxt d.Ty} :
    (Lets.nil : Lets d Γ eff Γ).denote = (return ·)

theorem bools_multi_uses2_logical_thm.extracted_1._24 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 ^^^ 1#1 = 1#1 → x_2 = 1#1 → ¬x_1 = 1#1 → x = 1#1 → x_1 + x = x_1 ^^^ x

theorem bv_AndOrXor_2595 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.xor (LLVM.and e e_1) (LLVM.or e e_1) ⊑ LLVM.xor e e_1

theorem no_shift_xor_multiuse_cmp_and_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (0#32 != x_2 &&& 4096#32) = 1#1 → ofBool (x_2 &&& 4096#32 == 0#32) = 1#1 → False

theorem lshr_mul_times_3_div_2_exact_2_thm (e : IntW 32) :
  lshr (mul e (const? 32 3) { «nsw» := false, «nuw» := true }) (const? 32 1) { «exact» := true } ⊑
    add e (lshr e (const? 32 1) { «exact» := true }) { «nsw» := false, «nuw» := true }

theorem test_logical_thm (e : IntW 32) :
  select (icmp IntPred.ne e (const? 32 34)) (icmp IntPred.sgt e (const? 32 (-1))) (const? 1 0) ⊑
    LLVM.and (icmp IntPred.ne e (const? 32 34)) (icmp IntPred.sgt e (const? 32 (-1)))

theorem e_436 :
    1 *  ~~~(x &&& y) + 11 * (x ||| y) + 1 *  ~~~y + 2 *  ~~~(x &&&  ~~~y) - 4 *  ~~~(x ||| y) - 11 *  ~~~(x |||  ~~~y) - 13 * (x &&&  ~~~y) - 10 * (x &&& y) = 3 * y

theorem positive_samevar_shlnsw_ashrexact_proof : positive_samevar_shlnsw_ashrexact_before ⊑ positive_samevar_shlnsw_ashrexact_after

theorem xor_1_proof : xor_1_before ⊑ xor_1_after

theorem masked_or_A_proof : masked_or_A_before ⊑ masked_or_A_after

theorem test37_thm (e : IntW 32) :
  LLVM.and (mul (zext 64 e) (const? 64 7)) (const? 64 240) ⊑
    zext 64 (LLVM.and (mul e (const? 32 7)) (const? 32 240)) { «nneg» := true }

theorem add_eq (x : BitVec w) : x = x + 0

theorem test_logical_proof : test_logical_before ⊑ test_logical_after

theorem positive_samevar_shlnuwnsw_proof : positive_samevar_shlnuwnsw_before ⊑ positive_samevar_shlnuwnsw_after

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

theorem e_1511 :
     - 2 * ((a &&&  ~~~b) ||| (a ^^^ (b ^^^ c))) + 4 * (a &&&  ~~~b) + 5 *  ~~~(a ||| (b ^^^ c)) - 5 *  ~~~(a ||| (b ||| c)) + 2 *  ~~~(a ||| ( ~~~b ||| c)) - 2 *  ~~~( ~~~a ||| (b ||| c)) + 2 * ( ~~~a &&& ( ~~~b &&& c)) - 5 * ( ~~~a &&& (b &&& c)) + 2 * (a &&& (b &&& c)) = 2 * (a &&& ( ~~~b &&& c))

theorem e_961 :
    4 * (z |||  ~~~t) + 1 *  ~~~t + 11 * (z ^^^ t) - 5 *  ~~~(z ||| t) - 15 *  ~~~(z |||  ~~~t) - 8 * (z &&& t) = 16 * (z &&&  ~~~t) - 4 * t

theorem ule_umax4_proof : ule_umax4_before ⊑ ule_umax4_after

theorem sub_not_thm (e e_1 : IntW 8) :
  LLVM.xor (sub e_1 e) (const? 8 (-1)) ⊑ add e (LLVM.xor e_1 (const? 8 (-1)))

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 or_xor_tree_0001_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 (LLVM.xor (mul e_2 (const? 32 42)) (mul e (const? 32 42))) (mul e_1 (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 test19_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬3#32 ≥ ↑32 → x <<< 3#32 &&& BitVec.ofInt 32 (-2) = x <<< 3#32

theorem xor_sge_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool ((x ||| BitVec.ofInt 8 (-128)) ^^^ x_1 * x_1 ≤ₛ x_1 * x_1) =
    ofBool ((x ||| BitVec.ofInt 8 (-128)) ^^^ x_1 * x_1 <ₛ x_1 * x_1)

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

theorem trunc_lshr_sext_exact_thm (e : IntW 8) :
  trunc 8 (lshr (sext 32 e) (const? 32 6) { «exact» := true }) ⊑ ashr e (const? 8 6) { «exact» := true }

theorem testi128i128_proof : testi128i128_before ⊑ testi128i128_after

theorem select_lshr_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

theorem sgt_x_impliesF_eq_smin_todo_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 8),
  ¬ofBool (x_1 <ₛ x_2) = 1#1 → ¬ofBool (x_2 ≤ₛ x_1) = 1#1 → ofBool (x == x_2) = 0#1

theorem sub_select_sext_proof : sub_select_sext_before ⊑ sub_select_sext_after

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

theorem intMin_neq_one {w : Nat} (h : w > 1): BitVec.intMin w ≠ 1

theorem e_1538 :
    2 *  ~~~(a &&&  ~~~a) + 1 * ( ~~~c &&& (a ^^^ b)) + 5 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) - 2 * (b ^^^  ~~~(a &&& (b ^^^ c))) + 4 * (b ^^^ (a ||| (b &&& c))) - 4 *  ~~~(a ||| (b ||| c)) - 12 *  ~~~(a ||| ( ~~~b ||| c)) - 5 *  ~~~( ~~~a ||| (b ||| c)) - 9 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 9 * ( ~~~a &&& ( ~~~b &&& c)) - 10 * (a &&& ( ~~~b &&& c)) - 6 * (a &&& (b &&& c)) = 2 * ( ~~~a &&& (b &&& c)) - 4 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c)))

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_2345 :
     - 2 *  ~~~(d ||| e) - 7 *  ~~~(d ^^^ ( ~~~e ||| f)) + 5 * ((d &&& f) ^^^ (e ||| f)) - 7 * (f |||  ~~~(d ^^^ e)) - 11 * (f ^^^  ~~~(d |||  ~~~e)) + 3 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) - 2 * (f ||| (d &&&  ~~~e)) + 2 * ((d &&& e) |||  ~~~(e ^^^ f)) + 1 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 1 * (d &&&  ~~~f) - 3 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 2 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 3 *  ~~~(d |||  ~~~e) - 5 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 11 * (e ^^^ ( ~~~d ||| (e ^^^ f))) + 2 * ((e &&& f) ||| (d &&& (e ||| f))) + 1 * (f ^^^  ~~~(d ||| e)) + 1 *  ~~~f + 1 * ((d &&& e) ||| (e ^^^ f)) + 2 *  ~~~(d &&& ( ~~~e &&& f)) - 5 * (d ^^^ e) - 1 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 11 * (d &&& ( ~~~e ||| f)) + 1 *  ~~~(d &&&  ~~~e) - 1 * ( ~~~d ||| (e &&& f)) - 2 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 1 * ((d &&& f) |||  ~~~(e ||| f)) - 11 * ( ~~~d &&& (e ||| f)) + 1 * (e ^^^ (d &&& ( ~~~e ||| f))) + 4 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 * (f ^^^ (d &&&  ~~~e)) - 7 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 11 *  ~~~( ~~~d ||| (e ^^^ f)) - 1 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) - 3 * ( ~~~e &&& (d ^^^ f)) + 11 * (d ^^^ (e &&& f)) + 1 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 4 * (f ^^^ (d ||| (e &&& f))) + 4 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 1 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 1 * ( ~~~d ||| ( ~~~e &&& f)) - 2 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 1 * (f ^^^  ~~~(d &&&  ~~~e)) - 1 * (e &&&  ~~~(d ^^^ f)) - 2 * (d ||| (e &&& f)) + 5 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 2 * (e ^^^ (d ||| ( ~~~e &&& f))) - 2 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 5 *  ~~~(d &&& f) + 7 *  ~~~(e ^^^ f) + 2 *  ~~~(d &&& (e &&& f)) - 3 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 6 *  ~~~(d &&& (e ^^^ f)) + 1 *  ~~~( ~~~d &&& (e &&& f)) + 1 * (e ||| (d ^^^ f)) - 2 * (d ||| (e ||| f)) - 3 *  ~~~(d ^^^ ( ~~~e &&& f)) + 3 * (d ^^^ f) + 33 *  ~~~(d ||| (e ||| f)) + 39 *  ~~~(d ||| ( ~~~e ||| f)) - 9 *  ~~~( ~~~d ||| (e ||| f)) - 34 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 41 * ( ~~~d &&& ( ~~~e &&& f)) + 14 * ( ~~~d &&& (e &&& f)) + 51 * (d &&& ( ~~~e &&& f)) + 13 * (d &&& (e &&& f)) =  - 11 * (d &&& (e ||| f)) + 1 *  ~~~(e |||  ~~~f)

theorem or_xor_xor_normal_binops_thm (e e_1 e_2 : IntW 32) :
  LLVM.or (LLVM.xor (LLVM.xor e_2 e_1) (LLVM.and (LLVM.xor e_2 e_1) (LLVM.xor e e_1)))
      (LLVM.xor (LLVM.xor e e_1) (LLVM.and (LLVM.xor e_2 e_1) (LLVM.xor e e_1))) ⊑
    LLVM.xor e_2 e

theorem add_shl_same_amount_partial_nuw1_proof : add_shl_same_amount_partial_nuw1_before ⊑ add_shl_same_amount_partial_nuw1_after

theorem test11d_proof : test11d_before ⊑ test11d_after

theorem icmp_lshr_and_overshift_thm (e : IntW 8) :
  icmp IntPred.ne (LLVM.and (lshr e (const? 8 5)) (const? 8 15)) (const? 8 0) ⊑
    icmp IntPred.ugt e (const? 8 31)

theorem AvoidCollision_toInt_setWidth (x : BitVec w) :
    (x.setWidth v).toInt = Int.bmod x.toNat (2^v)

theorem icmp_ult_x_y_proof : icmp_ult_x_y_before ⊑ icmp_ult_x_y_after

theorem f_var0_proof : f_var0_before ⊑ f_var0_after

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

theorem bitwise_and_bitwise_and_icmps_thm (e e_1 e_2 : IntW 8) :
  LLVM.and
      (LLVM.and (icmp IntPred.eq e_2 (const? 8 42))
        (icmp IntPred.ne (LLVM.and e_1 (const? 8 1)) (const? 8 0)))
      (icmp IntPred.ne (LLVM.and e_1 (shl (const? 8 1) e)) (const? 8 0)) ⊑
    LLVM.and (icmp IntPred.eq e_2 (const? 8 42))
      (icmp IntPred.eq (LLVM.and e_1 (LLVM.or (shl (const? 8 1) e { «nsw» := false, «nuw» := true }) (const? 8 1)))
        (LLVM.or (shl (const? 8 1) e { «nsw» := false, «nuw» := true }) (const? 8 1)))

theorem add_congr (e1 : a ≈ʷ b) (e2 : c ≈ʷ d) : (a + c) ≈ʷ (b + d)

theorem signed_sign_bit_extract_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → ofBool (x.sshiftRight' 31#32 != 0#32) = ofBool (x <ₛ 0#32)

theorem icmp_slt_0_and_icmp_sge_neg1_i64_proof : icmp_slt_0_and_icmp_sge_neg1_i64_before ⊑ icmp_slt_0_and_icmp_sge_neg1_i64_after

theorem lor_land_right2_thm (e e_1 : IntW 1) : select e_1 (select e (const? 1 1) e_1) (const? 1 0) ⊑ e_1

theorem ashr_and_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ x + 1#8 ≥ ↑8) →
    ¬x ≥ ↑8 →
      (BitVec.ofInt 8 (-64)).sshiftRight' x &&& (BitVec.ofInt 8 (-128)).sshiftRight' (x + 1#8) =
        (BitVec.ofInt 8 (-64)).sshiftRight' x

theorem shl_bad_sub_i32_proof : shl_bad_sub_i32_before ⊑ shl_bad_sub_i32_after

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 main5c_like_logical_proof : main5c_like_logical_before ⊑ main5c_like_logical_after

theorem test22_proof : test22_before ⊑ test22_after

theorem ashrslt_02_03_exact_proof : ashrslt_02_03_exact_before ⊑ ashrslt_02_03_exact_after

theorem land_band_left1_proof : land_band_left1_before ⊑ land_band_left1_after

@[simp]
theorem Term.toBV_bor {wenv : WidthExpr.Env wcard}
    {tctx : Term.Ctx wcard tcard}
    (benv : Term.BoolEnv bcard)
    (tenv : tctx.Env wenv) (a b : Term bcard ncard icard pcard tctx (.bv w)) :
  Term.toBV benv nenv ienv penv tenv (.bor a b) = a.toBV benv nenv ienv penv tenv ||

theorem icmp_ne_zext_ne_one_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (zeroExtend 32 (ofBool (x != 1#32)) != x) = 1#1

theorem e_705 :
     - 1 *  ~~~(x &&&  ~~~y) + 5 *  ~~~y - 11 * (x ^^^ y) - 2 * x - 1 * (x |||  ~~~y) + 4 * y - 4 *  ~~~(x ||| y) + 8 *  ~~~(x |||  ~~~y) + 9 * (x &&&  ~~~y) - 1 * (x &&& y) =  - 1 *  ~~~(x ^^^ y)

theorem positive_trunc_signbit_proof : positive_trunc_signbit_before ⊑ positive_trunc_signbit_after

theorem ashr_ugt_3_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬1#4 ≥ ↑4 → ofBool (3#4 <ᵤ x.sshiftRight' 1#4) = ofBool (x <ₛ 0#4)

theorem test4_proof : test4_before ⊑ test4_after

theorem shl_trunc_smaller_shl_thm (e : IntW 32) :
  shl (trunc 8 (shl e (const? 32 2))) (const? 8 4) ⊑ shl (trunc 8 e) (const? 8 6)

theorem main3_proof : main3_before ⊑ main3_after

theorem e_2253 :
    1 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) - 1 *  ~~~(d ||| (e &&& f)) - 2 * ( ~~~e ||| (d ^^^ f)) + 1 * (f ^^^ ( ~~~d ||| (e ||| f))) + 2 * (e &&& f) - 11 * (e ^^^ (d ||| ( ~~~e &&& f))) - 2 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 6 *  ~~~(d &&& ( ~~~e ||| f)) - 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 4 *  ~~~( ~~~d &&& (e ||| f)) - 11 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 6 * (e ^^^  ~~~(d &&& (e ||| f))) - 11 * (d ||| ( ~~~e &&& f)) + 1 *  ~~~(e ||| f) - 7 *  ~~~(d &&& ( ~~~e &&& f)) - 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 2 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) - 1 * (d &&& e) - 2 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 1 * (f &&& (d |||  ~~~e)) + 5 * ( ~~~d ||| ( ~~~e &&& f)) + 1 *  ~~~(d |||  ~~~e) + 11 *  ~~~( ~~~d ||| (e ^^^ f)) + 11 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 5 * (e ||| f) - 2 * d - 6 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 * (e ^^^ ( ~~~d ||| (e &&& f))) + 3 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 11 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 5 * (e &&&  ~~~f) + 1 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 7 *  ~~~d + 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 7 * (d ^^^ (e ^^^ f)) + 4 * (d |||  ~~~e) - 2 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 2 *  ~~~(e |||  ~~~f) - 6 * (e |||  ~~~f) - 2 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 6 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 3 *  ~~~( ~~~d ||| ( ~~~e &&& f)) + 3 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 5 * (e ^^^ (d ||| (e &&& f))) + 1 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 7 *  ~~~( ~~~d ||| (e &&& f)) - 3 * ((d ||| e) &&& (e ^^^ f)) + 7 * (e ^^^ ( ~~~d ||| (e ||| f))) + 7 * ( ~~~e &&&  ~~~(d ^^^ f)) - 17 *  ~~~(d ||| (e ||| f)) + 27 *  ~~~(d ||| ( ~~~e ||| f)) + 26 *  ~~~( ~~~d ||| (e ||| f)) + 43 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 36 * ( ~~~d &&& ( ~~~e &&& f)) + 33 * ( ~~~d &&& (e &&& f)) + 18 * (d &&& ( ~~~e &&& f)) + 21 * (d &&& (e &&& f)) =  - 2 * (f ^^^  ~~~(d ||| (e &&& f)))

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 ashrsgt_01_09_exact_proof : ashrsgt_01_09_exact_before ⊑ ashrsgt_01_09_exact_after

theorem and_signbit_select_ashr_proof : and_signbit_select_ashr_before ⊑ and_signbit_select_ashr_after

theorem gt_signed_to_large_signed_proof : gt_signed_to_large_signed_before ⊑ gt_signed_to_large_signed_after

theorem t2_const_lshr_shl_eq_thm (e e_1 : IntW 32) :
  icmp IntPred.eq (LLVM.and (shl e_1 (const? 32 1)) (lshr e (const? 32 1))) (const? 32 0) ⊑
    icmp IntPred.eq (LLVM.and (lshr e (const? 32 2)) e_1) (const? 32 0)

theorem sle_smin3_thm (e e_1 : IntW 32) :
  icmp IntPred.sge (add e_1 (const? 32 3))
      (select (icmp IntPred.slt (add e_1 (const? 32 3)) e) (add e_1 (const? 32 3)) e) ⊑
    const? 1 1

theorem sgt_x_impliesF_eq_smin_todo_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x <ₛ x_1) = 1#1 → ofBool (x_1 ≤ₛ x) = 1#1 → False

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

theorem eq_commuted_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(x == 0 || 8 != 1 && 43#8 == intMin 8 && x == -1) = true →
    ofBool (x_1 == 0#8) ||

theorem shl_xor_lshr_comm_proof : shl_xor_lshr_comm_before ⊑ shl_xor_lshr_comm_after

theorem shl_xor_lshr_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ x_2 <<< x_1 >>> x_1 ≠ x_2 ∨ x_1 ≥ ↑32 ∨ x_1 ≥ ↑32) →
    ¬x_1 ≥ ↑32 → (x_2 <<< x_1 ^^^ x) >>> x_1 = x >>> x_1 ^^^ x_2

theorem t4_ugt_slt_65536_thm.extracted_1._2 : ∀ (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 → False

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

theorem not_lshr_const_proof : not_lshr_const_before ⊑ not_lshr_const_after

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

theorem positive_biggerlshr_shlnuw_lshrexact_proof : positive_biggerlshr_shlnuw_lshrexact_before ⊑ positive_biggerlshr_shlnuw_lshrexact_after

theorem ashrslt_03_03_proof : ashrslt_03_03_before ⊑ ashrslt_03_03_after

theorem zext_or_eq_ult_add_thm.extracted_1._1 : ∀ (x : BitVec 32),
  zeroExtend 32 (ofBool (x + BitVec.ofInt 32 (-3) <ᵤ 3#32) ||| ofBool (x == 5#32)) =
    zeroExtend 32 (ofBool (x + BitVec.ofInt 32 (-3) <ᵤ 3#32))

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

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

theorem pr33078_3_proof : pr33078_3_before ⊑ pr33078_3_after

theorem logic_or_logic_and_2_proof : logic_or_logic_and_2_before ⊑ logic_or_logic_and_2_after

theorem test7_proof : test7_before ⊑ test7_after

theorem and_orn_cmp_3_proof : and_orn_cmp_3_before ⊑ and_orn_cmp_3_after

theorem ashr_ult_1_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬1#4 ≥ ↑4 → ofBool (x.sshiftRight' 1#4 <ᵤ 1#4) = ofBool (x <ᵤ 2#4)

theorem exactly_one_set_signbit_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬7#8 ≥ ↑8 → ofBool (x_1 >>> 7#8 == zeroExtend 8 (ofBool (-1#8 <ₛ x))) = ofBool (x_1 ^^^ x <ₛ 0#8)

theorem lor_lor_left1_proof : lor_lor_left1_before ⊑ lor_lor_left1_after

theorem e_1429 :
     - 3 *  ~~~(z ^^^ t) + 1 *  ~~~z + 2 *  ~~~(z &&& t) - 2 * t + 11 * (z ||| t) - 3 * (z ^^^ t) - 4 *  ~~~(z ||| t) - 13 *  ~~~(z |||  ~~~t) - 10 * (z &&&  ~~~t) - 10 * (z &&& t) =  - 4 *  ~~~(z &&&  ~~~t)

theorem t2_thm.extracted_1._1 : ∀ (x : BitVec 64), ¬63#64 ≥ ↑64 → 0#64 - x.sshiftRight' 63#64 = x >>> 63#64

theorem testi64i32_ne_proof : testi64i32_ne_before ⊑ testi64i32_ne_after

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

theorem bv_Select_858 :
    ∀ (e e_1 : LLVM.IntW 1),
      LLVM.select e (LLVM.xor e (LLVM.const? 1 (-1))) e_1 ⊑ LLVM.and (LLVM.xor e (LLVM.const? 1 (-1))) e_1

theorem uadd_sat_canon_nuw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.uaddOverflow x = true) → ofBool (x_1 + x <ᵤ x_1) = 1#1 → -1#32 = x_1 + x

theorem e_585 :
    4 *  ~~~(x &&&  ~~~x) - 11 * x - 1 * y - 1 *  ~~~y - 1 *  ~~~(x ^^^ y) - 1 *  ~~~(x ||| y) - 2 *  ~~~(x |||  ~~~y) + 9 * (x &&&  ~~~y) + 9 * (x &&& y) = 1 *  ~~~(x &&& y)

theorem test4_thm (e : IntW 8) :
  icmp IntPred.sle e (const? 8 126) ⊑ icmp IntPred.ne e (const? 8 127)

theorem not_or_or_and_not_and_and_commute2_or_proof : not_or_or_and_not_and_and_commute2_or_before ⊑ not_or_or_and_not_and_and_commute2_or_after

theorem samesign_different_sign_bittest2_proof : samesign_different_sign_bittest2_before ⊑ samesign_different_sign_bittest2_after

theorem positive_biggerashr_shlnuwnsw_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(6#8 ≥ ↑8 ∨
        True ∧ (x.sshiftRight' 6#8 <<< 3#8).sshiftRight' 3#8 ≠ x.sshiftRight' 6#8 ∨
          True ∧ x.sshiftRight' 6#8 <<< 3#8 >>> 3#8 ≠ x.sshiftRight' 6#8 ∨ 3#8 ≥ ↑8) →
    ¬3#8 ≥ ↑8 → x.sshiftRight' 6#8 <<< 3#8 = x.sshiftRight' 3#8 &&& BitVec.ofInt 8 (-8)

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

theorem n11_uge_slt_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.ult e_2 (const? 32 129)) (select (icmp IntPred.slt e_2 (const? 32 0)) e_1 e) e_2 ⊑
    select (icmp IntPred.ult e_2 (const? 32 129)) e e_2

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 select1_thm (e e_1 e_2 : IntW 32) (e_3 : IntW 1) :
  zext 32 (select e_3 (trunc 8 e_2) (add (trunc 8 e_1) (trunc 8 e))) ⊑
    LLVM.and (select e_3 e_2 (add e_1 e)) (const? 32 255)

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

theorem lshrult_01_11_thm (e : IntW 4) : icmp IntPred.ult (lshr e (const? 4 1)) (const? 4 (-5)) ⊑ const? 1 1

theorem test5_thm.extracted_1._1 : ∀ (x : BitVec 32), x &&& x = x

theorem sel_false_val_is_a_masked_ashr_of_true_val1_thm.extracted_1._1 : ∀ (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 →
      False

theorem e_1654 :
    1 *  ~~~(a &&& (b ||| c)) - 5 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 3 * (a |||  ~~~b) + 1 * (b |||  ~~~c) - 1 * (c &&& (a |||  ~~~b)) - 6 * ( ~~~a ||| (b ^^^ c)) + 1 * (b ^^^  ~~~(a |||  ~~~c)) + 1 * ( ~~~a &&& (b ||| c)) + 1 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 2 * ((a &&& b) ||| (b ^^^ c)) - 5 * ((a &&& b) ^^^ (a ^^^ ( ~~~b ||| c))) - 5 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) + 11 * (b &&& (a |||  ~~~c)) + 3 * (a ||| b) + 1 * ( ~~~a &&& (b ^^^ c)) - 6 *  ~~~(b |||  ~~~c) - 6 *  ~~~( ~~~a &&& ( ~~~b ||| c)) + 7 * (c ^^^ (a &&&  ~~~b)) + 4 *  ~~~(a ||| (b ||| c)) - 7 *  ~~~( ~~~a ||| (b ||| c)) - 1 * ( ~~~a &&& ( ~~~b &&& c)) + 7 * ( ~~~a &&& (b &&& c)) + 12 * (a &&& ( ~~~b &&& c)) - 7 * (a &&& (b &&& c)) =  - 7 *  ~~~b + 5 *  ~~~( ~~~a ||| ( ~~~b ||| c))

theorem test_shl_nuw__none_are_safe_thm (e : IntW 64) (e_1 : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e_1 (const? 32 (-2))) (const? 32 0)) e
      (ashr e (zext 64 (shl (LLVM.and e_1 (const? 32 (-2))) (const? 32 2) { «nsw» := false, «nuw» := true }))) ⊑
    ashr e (zext 64 (LLVM.and (shl e_1 (const? 32 2)) (const? 32 (-8))) { «nneg» := true })

theorem and_min_7_7_proof : and_min_7_7_before ⊑ and_min_7_7_after

theorem c_1_1_0_proof : c_1_1_0_before ⊑ c_1_1_0_after

theorem ashrsgt_02_03_exact_proof : ashrsgt_02_03_exact_before ⊑ ashrsgt_02_03_exact_after

@[simp] theorem Com.returnVars_castPureToEff (eff : _) (com : Com d Γ .pure tys) :
    (com.castPureToEff eff).returnVars = com.returnVars.map (fun _ v => v.castCtxt (by simp))

theorem src_is_mask_shl_lshr_fail_not_allones_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(x ≥ ↑8 ∨ x ≥ ↑8) →
    ¬x ≥ ↑8 →
      ofBool (0#8 != (x_1 ^^^ 123#8) &&& (BitVec.ofInt 8 (-2) <<< x >>> x ^^^ -1#8)) =
        ofBool (x_1 ^^^ BitVec.ofInt 8 (-124) ||| (-1#8) >>> x &&& BitVec.ofInt 8 (-2) != -1#8)

theorem sext_sext_ne_proof : sext_sext_ne_before ⊑ sext_sext_ne_after

theorem zext_nneg_sext_eq_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (zext 32 e_1 { «nneg» := true }) (sext 32 e) ⊑ icmp IntPred.eq e_1 e

theorem uge_swap_or_not_max_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 != -1#8) ||

theorem negative_trunc_not_arg_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ofBool (-1#8 <ₛ truncate 8 x_1) = 1#1 →
    ¬ofBool (x_1 &&& 128#32 == 0#32) = 1#1 → ofBool (x + 128#32 <ᵤ 256#32) = 0#1

theorem unmasked_shlop_insufficient_mask_shift_amount_proof : unmasked_shlop_insufficient_mask_shift_amount_before ⊑ unmasked_shlop_insufficient_mask_shift_amount_after

theorem e_1420 :
    5 *  ~~~(z &&& t) + 2 *  ~~~(z &&&  ~~~z) - 3 * t - 7 *  ~~~(z &&&  ~~~t) + 5 * (z |||  ~~~t) - 5 *  ~~~t + 2 *  ~~~z - 2 *  ~~~(z ||| t) + 1 *  ~~~(z |||  ~~~t) + 3 * (z &&& t) = 7 * (z &&&  ~~~t)

theorem logical_or_logical_or_icmps_comm3_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 8),
  ¬x_1 ≥ ↑8 →
    ¬(ofBool (x_2 &&& 1#8 <<< x_1 == 0#8) = 1#1 ∨ ofBool (x_2 &&& 1#8 == 0#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) →
        ofBool (x_2 &&& (1#8 <<< x_1 ||| 1#8) != 1#8 <<< x_1 ||| 1#8) = 1#1 → ofBool (x == 42#8) = 1#1

theorem e_2008 :
     - 11 * (e ^^^ ( ~~~d ||| (e &&& f))) + 1 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 4 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 2 *  ~~~(e &&&  ~~~f) + 1 * ( ~~~d &&& (e ||| f)) + 1 * ((d ^^^ e) &&& (d ^^^ f)) - 1 * d - 3 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 1 *  ~~~(d &&&  ~~~e) + 2 * (e ^^^ (d &&& (e ||| f))) - 6 * (d |||  ~~~f) + 7 * (d ^^^ e) - 5 * (e ^^^ (d &&& f)) + 3 * (e ||| f) - 11 * (e ^^^  ~~~(d &&& (e &&& f))) - 5 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 2 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 1 * ( ~~~f &&&  ~~~(d ^^^ e)) - 2 *  ~~~( ~~~d &&& (e ^^^ f)) - 2 * (f ^^^ (d &&&  ~~~e)) - 11 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 2 * ((d &&& e) ||| (e ^^^ f)) + 1 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 1 *  ~~~e + 1 * (e ||| (d ^^^ f)) + 7 * (e ^^^ ( ~~~d &&& (e ||| f))) + 17 *  ~~~(d ||| (e ||| f)) + 10 *  ~~~(d ||| ( ~~~e ||| f)) + 13 *  ~~~( ~~~d ||| (e ||| f)) + 13 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 9 * ( ~~~d &&& (e &&& f)) + 30 * (d &&& ( ~~~e &&& f)) + 5 * (d &&& (e &&& f)) =  - 2 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 26 * ( ~~~d &&& ( ~~~e &&& f))

theorem add_five (x : BitVec w) : (x + x) + (x + x) + x = x + x + x + x + x

theorem e_1944 :
     - 7 * (b &&& (a |||  ~~~c)) + 7 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) + 1 * (a ^^^ c) - 11 * ((b &&& c) ||| (a &&& (b ||| c))) - 1 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) - 1 * (b &&& c) - 5 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) + 3 *  ~~~(a ^^^ (b &&& c)) - 3 * (a &&& c) + 4 * ( ~~~b |||  ~~~(a ^^^ c)) - 1 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 6 * ((a &&& b) ^^^ (a ^^^ ( ~~~b ||| c))) - 1 * ((a &&& b) |||  ~~~(b ^^^ c)) - 2 * (c &&& (a |||  ~~~b)) + 3 *  ~~~(a ^^^ (b ^^^ c)) - 1 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) + 1 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) + 1 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) + 1 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) - 11 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 3 * ( ~~~a &&& (b ||| c)) + 11 * ( ~~~(a &&& b) &&& (b ^^^ c)) - 2 * (a ||| (b ^^^ c)) - 1 * (c |||  ~~~(a |||  ~~~b)) - 1 * (b &&&  ~~~c) - 2 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 *  ~~~(a &&& (b &&& c)) - 2 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) - 11 *  ~~~(a &&& (b ^^^ c)) - 1 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) + 2 * (b ||| (a &&& c)) + 11 *  ~~~(a ^^^ b) - 7 * (c ^^^  ~~~(a &&&  ~~~b)) + 1 * (b ^^^ (a ||| (b ||| c))) + 5 * ((a &&& b) |||  ~~~(b ||| c)) - 2 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) + 5 * (a ^^^ ( ~~~b ||| c)) + 7 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) - 1 *  ~~~(a ||| c) + 11 * (c ^^^ (a |||  ~~~b)) - 1 * (a ||| ( ~~~b &&& c)) + 3 * ( ~~~a ||| ( ~~~b ||| c)) - 11 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) + 2 * (c ^^^ (a ||| b)) - 11 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) + 10 *  ~~~(a ||| (b ||| c)) + 7 *  ~~~(a ||| ( ~~~b ||| c)) - 4 *  ~~~( ~~~a ||| (b ||| c)) + 14 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 2 * ( ~~~a &&& ( ~~~b &&& c)) + 1 * ( ~~~a &&& (b &&& c)) + 24 * (a &&& ( ~~~b &&& c)) + 56 * (a &&& (b &&& c)) =  - 3 * (c &&&  ~~~(a &&& b)) + 2 * ( ~~~a ||| ( ~~~b &&& c))

theorem pr40493_neg2_proof : pr40493_neg2_before ⊑ pr40493_neg2_after

theorem eg6 (u w : Nat) (x : BitVec w) :
    (x.zeroExtend u).signExtend u = x.zeroExtend u

theorem icmp_eq_and_pow2_minus1_shl_pow2_proof : icmp_eq_and_pow2_minus1_shl_pow2_before ⊑ icmp_eq_and_pow2_minus1_shl_pow2_after

theorem nonexact_lshr_eq_proof : nonexact_lshr_eq_before ⊑ nonexact_lshr_eq_after

theorem t2_thm (e : IntW 32) (e_1 : IntW 64) :
  LLVM.udiv e_1 (zext 64 (shl (const? 32 1) e)) ⊑ lshr e_1 (zext 64 e { «nneg» := true })

theorem test55_thm (e : IntW 32) :
  sext 64 (LLVM.and (LLVM.or (trunc 16 e) (const? 16 (-32574))) (const? 16 (-25350))) ⊑
    sext 64 (LLVM.or (LLVM.and (trunc 16 e) (const? 16 7224)) (const? 16 (-32574)) { «disjoint» := true })

@[simp]
lemma accepts_cast {M : NFA α σ} (h : σ = ς): (h ▸ M).accepts = M.accepts

theorem alive_276_2 : alive_276_2_src ⊑ alive_276_2_tgt

theorem zext_or_eq_ult_add_thm.extracted_1._1 : ∀ (x : BitVec 32),
  zeroExtend 32 (ofBool (x + BitVec.ofInt 32 (-3) <ᵤ 3#32) ||| ofBool (x == 5#32)) =
    zeroExtend 32 (ofBool (x + BitVec.ofInt 32 (-3) <ᵤ 3#32))

@[simp] theorem Ctxt.get_add_bvars (e : Expr d Γ eff ts) (i : Nat) :
    e.outContext[i + e.bvars]? = Γ[i]?

theorem nonexact_lshr_ne_noexactdiv_proof : nonexact_lshr_ne_noexactdiv_before ⊑ nonexact_lshr_ne_noexactdiv_after

theorem icmp_eq_x_invertable_y2_proof : icmp_eq_x_invertable_y2_before ⊑ icmp_eq_x_invertable_y2_after

theorem low_bitmask_ult_thm (e : IntW 8) :
  icmp IntPred.ult (LLVM.and (add e (const? 8 31)) (const? 8 31)) e ⊑ icmp IntPred.ne e (const? 8 0)

theorem uge_to_sgt_proof : uge_to_sgt_before ⊑ uge_to_sgt_after

theorem addhshlhsdivhnegative1_thm (e : IntW 32) :
  add (shl (LLVM.sdiv e (const? 32 (-1))) (const? 32 1)) e ⊑ sub (const? 32 0) e

theorem e_75 :
    1 *  ~~~(x &&&  ~~~y) + 1 * x - 12 *  ~~~(x ||| y) - 1 *  ~~~(x |||  ~~~y) - 2 * (x &&& y) =  - 11 *  ~~~y + 12 * (x &&&  ~~~y)

theorem t7_ugt_sgt_neg1_proof : t7_ugt_sgt_neg1_before ⊑ t7_ugt_sgt_neg1_after

theorem test15_proof : test15_before ⊑ test15_after

theorem sge_swap_or_max_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 ≤ₛ x) = 1#1 → 1#1 = ofBool (x_1 ≤ₛ x)

theorem PR52261_proof : PR52261_before ⊑ PR52261_after

theorem scalar1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 4),
  True ∧ (x_1 &&& BitVec.ofInt 4 (-2) &&& (x &&& 1#4) != 0) = true → False

theorem test_nuw_and_unsigned_pred_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ (10#64).usubOverflow x = true) → ofBool (10#64 - x <ᵤ 3#64) = ofBool (7#64 <ᵤ x)

theorem n2_badmask_proof : n2_badmask_before ⊑ n2_badmask_after

theorem masked_and_notallzeroes_logical_proof : masked_and_notallzeroes_logical_before ⊑ masked_and_notallzeroes_logical_after

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 two_signed_truncation_checks_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.ult (add e (const? 32 512)) (const? 32 1024))
      (icmp IntPred.ult (add e (const? 32 128)) (const? 32 256)) ⊑
    icmp IntPred.ult (add e (const? 32 128)) (const? 32 256)

theorem or_trunc_lshr_small_mask_proof : or_trunc_lshr_small_mask_before ⊑ or_trunc_lshr_small_mask_after

theorem t_0_10_proof : t_0_10_before ⊑ t_0_10_after

theorem test_shl_nuw_nsw__none_are_safe_proof : test_shl_nuw_nsw__none_are_safe_before ⊑ test_shl_nuw_nsw__none_are_safe_after

theorem main5e_like_logical_thm.extracted_1._3 : ∀ (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 → False

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

theorem commutativity_constant_varx_6_invmask_proof : commutativity_constant_varx_6_invmask_before ⊑ commutativity_constant_varx_6_invmask_after

theorem c_0_1_0_thm (e e_1 : IntW 4) :
  LLVM.xor (LLVM.and (LLVM.xor e_1 e) (const? 4 (-2))) e_1 ⊑
    LLVM.or (LLVM.and e (const? 4 (-2))) (LLVM.and e_1 (const? 4 1)) { «disjoint» := true }

theorem shift_xor_multiuse_cmp_with_xor_thm.extracted_1._4 : ∀ (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 ^^^ 2048#32) * x = x_2 * x_1

theorem sext_diff_i1_xor_sub_1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  True ∧ (zeroExtend 64 x).saddOverflow (signExtend 64 x_1) = true → False

theorem masked_or_A_thm (e : IntW 32) :
  LLVM.or (icmp IntPred.eq (LLVM.and e (const? 32 14)) e) (icmp IntPred.eq (LLVM.and e (const? 32 78)) e) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 (-79))) (const? 32 0)

theorem bitwise_and_logical_and_masked_icmp_allzeros_poison1_proof : bitwise_and_logical_and_masked_icmp_allzeros_poison1_before ⊑ bitwise_and_logical_and_masked_icmp_allzeros_poison1_after

theorem test4_proof : test4_before ⊑ test4_after

theorem and_or3_thm.extracted_1._7 : ∀ (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 = x

theorem ule_swap_and_min_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x ≤ᵤ x_1) = 1#1 → 0#1 = ofBool (x == 0#8)

theorem e_508 :
     - 1 *  ~~~x - 1 *  ~~~(x &&&  ~~~x) + 2 * y + 7 * (x |||  ~~~y) - 2 * (x ||| y) + 1 *  ~~~(x &&&  ~~~y) - 5 * x + 1 *  ~~~(x &&& y) - 5 *  ~~~(x ||| y) = 2 *  ~~~(x ^^^ y)

@[bv_multi_width_normalize] theorem not_eq_eq {α : Sort u} (a b : α) : (¬ (a = b)) = (a ≠ b)

theorem e_1113 :
     - 11 * z + 1 *  ~~~(z &&& t) + 2 *  ~~~t + 1 *  ~~~(z &&&  ~~~t) - 4 *  ~~~(z ||| t) - 1 *  ~~~(z |||  ~~~t) + 9 * (z &&&  ~~~t) + 11 * (z &&& t) = 1 * (z ||| t)

theorem ashrsgt_02_07_exact_thm (e : IntW 4) :
  icmp IntPred.sgt (ashr e (const? 4 2) { «exact» := true }) (const? 4 7) ⊑ const? 1 0

theorem test47_proof : test47_before ⊑ test47_after

theorem positive_biggerashr_shlnsw_ashrexact_proof : positive_biggerashr_shlnsw_ashrexact_before ⊑ positive_biggerashr_shlnsw_ashrexact_after

theorem lshr_add_or_fail_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(1#8 ≥ ↑8 ∨ 1#8 ≥ ↑8) → 1#8 ≥ ↑8 ∨ 1#8 ≥ ↑8 ∨ True ∧ (x >>> 1#8).uaddOverflow 123#8 = true → False

theorem pr4917_3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (4294967295#64 <ᵤ zeroExtend 64 x_1 * zeroExtend 64 x) = 1#1 →
    True ∧ (zeroExtend 64 x_1).umulOverflow (zeroExtend 64 x) = true → False

theorem t0_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬63#64 ≥ ↑64 →
    63#64 ≥ ↑64 ∨ True ∧ signExtend 64 (truncate 32 (x.sshiftRight' 63#64)) ≠ x.sshiftRight' 63#64 → False

theorem AvoidCollision_getLsbD_signExtend (x  : BitVec w) {v i : Nat} :
    (x.signExtend v).getLsbD i = (decide (i < v) && if i < w then x.getLsbD i else x.msb)

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

theorem test4b_proof : test4b_before ⊑ test4b_after

theorem main7b_logical_thm.extracted_1._5 : ∀ (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 → 0#32 = zeroExtend 32 1#1

theorem positive_samevar_shlnsw_thm (e e_1 : IntW 8) :
  shl (ashr e_1 e) e { «nsw» := true, «nuw» := false } ⊑
    LLVM.and (shl (const? 8 (-1)) e { «nsw» := true, «nuw» := false }) e_1

theorem sgt_and_min_commute_proof : sgt_and_min_commute_before ⊑ sgt_and_min_commute_after

theorem and_or3_proof : and_or3_before ⊑ and_or3_after

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

theorem isEmpty_iff_forall_not_mem [EquivBEq α] [LawfulHashable α] :
    m.isEmpty = true ↔ ∀ a, ¬a ∈ m

theorem slt_or_not_max_commute_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.ne e_1 (const? 8 127)) (icmp IntPred.slt e_1 e) ⊑
    icmp IntPred.ne e_1 (const? 8 127)

theorem not_match_inconsistent_values_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(299#64 = 0 ∨ 29#64 = 0 ∨ 64#64 = 0) →
    299#64 = 0 ∨
        29#64 = 0 ∨
          True ∧ (x / 29#64 &&& 63#64).smulOverflow 299#64 = true ∨
            True ∧ (x / 29#64 &&& 63#64).umulOverflow 299#64 = true ∨
              True ∧ (x % 299#64).saddOverflow ((x / 29#64 &&& 63#64) * 299#64) = true ∨
                True ∧ (x % 299#64).uaddOverflow ((x / 29#64 &&& 63#64) * 299#64) = true →
      False

theorem add_nsw_or_and_thm (e e_1 : IntW 32) :
  add (LLVM.or e_1 e) (LLVM.and e_1 e) { «nsw» := true, «nuw» := false } ⊑
    add e_1 e { «nsw» := true, «nuw» := false }

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_2_thm (e : IntW 32) :
  LLVM.or (icmp IntPred.eq (LLVM.and e (const? 32 3)) (const? 32 0))
      (icmp IntPred.ne (LLVM.and e (const? 32 7)) (const? 32 0)) ⊑
    const? 1 1

theorem sext_zext_nneg_sge_op0_narrow_proof : sext_zext_nneg_sge_op0_narrow_before ⊑ sext_zext_nneg_sge_op0_narrow_after

theorem not_not_true_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), x_1 ^^^ 1#1 = 1#1 → x_1 = 1#1 → x ^^^ 1#1 = 1#1

theorem e_659 :
     - 6 * (x ^^^ y) - 1 * x - 1 * (x ||| y) - 11 *  ~~~(x ^^^ y) - 2 *  ~~~(x &&& y) + 1 * y - 11 * (x |||  ~~~y) + 8 *  ~~~(x |||  ~~~y) + 32 * (x &&&  ~~~y) + 23 * (x &&& y) = 11 *  ~~~y - 35 *  ~~~(x ||| y)

theorem left_shift_add_2 (hu : u >= r) (hs : s > p) (hsq : s > q) :
  (bw r (shlMax (bw s (addMax (bw p a) (bw q b))) (bw t c)))  =
  (bw r (addMax (bw u (shlMax (bw p a) (bw t c))) (bw u (shlMax (bw q b) (bw t c)))))

theorem test42_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  (x_2 ^^^ -1#32 ^^^ x_1 * x) &&& (x_2 ||| x_1 * x) = x_1 * x &&& x_2

theorem e_13 :
     - 1 *  ~~~(x ^^^ y) + 5 * x - 6 * (x &&&  ~~~y) - 5 * (x &&& y) = 1 *  ~~~(x |||  ~~~y) - 1 *  ~~~(x &&&  ~~~x)

@[simp]
lemma CNFA.SignedCmp_stateMax cmp : (autSignedCmp cmp).m.stateMax = 5

theorem e_1673 :
     - 1 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) + 3 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 3 * (b |||  ~~~(a |||  ~~~c)) - 6 * (a ||| ( ~~~b ||| c)) - 1 * (b ^^^ (a ||| ( ~~~b ||| c))) + 2 * ( ~~~c |||  ~~~(a ^^^ b)) - 1 * (c ^^^ (a ||| (b ||| c))) + 5 * (b &&&  ~~~(a ^^^ c)) - 1 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) + 2 * (b ^^^  ~~~(a ||| c)) - 1 * (c ^^^ (a ||| ( ~~~b ||| c))) - 2 * (a &&&  ~~~c) + 11 * ((a ||| b) &&&  ~~~(b ^^^ c)) + 1 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 1 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 1 *  ~~~( ~~~a ||| (b ^^^ c)) + 2 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) + 7 * (c |||  ~~~(a ^^^ b)) - 7 *  ~~~(a ||| (b ||| c)) - 3 *  ~~~(a ||| ( ~~~b ||| c)) - 11 *  ~~~( ~~~a ||| (b ||| c)) - 3 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 4 * ( ~~~a &&& ( ~~~b &&& c)) - 9 * ( ~~~a &&& (b &&& c)) - 8 * (a &&& ( ~~~b &&& c)) - 21 * (a &&& (b &&& c)) =  - 4 * (a &&&  ~~~b) - 5 *  ~~~( ~~~a ||| (b &&& c))

theorem ashrslt_03_08_proof : ashrslt_03_08_before ⊑ ashrslt_03_08_after

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

theorem test_ashr_exact__exact_is_safe_thm.extracted_1._1 : ∀ (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 →
      False

lemma carry_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))
    (x : new_arity → BitStream) : ∀ (n : ℕ),
    (p.compose new_arity q_arity vars q).carry x n =
      let z := p.carry (λ a => (q a).eval (fun i => x (vars _ i))) n
      Sum.elim z (fun a => (q a.1).carry (fun t => x (vars _ t)) n a.2)

theorem e_361 :
     - 2 *  ~~~x - 11 *  ~~~(x &&&  ~~~x) + 3 *  ~~~(x ^^^ y) - 7 *  ~~~y - 1 *  ~~~(x &&& y) + 19 *  ~~~(x ||| y) + 14 *  ~~~(x |||  ~~~y) + 20 * (x &&&  ~~~y) = 1 * (x |||  ~~~y) - 9 * (x &&& y)

theorem not_or_xor_proof : not_or_xor_before ⊑ not_or_xor_after

@[simp] theorem pure_pure (eff : EffectKind) (x : α) :
    (Pure.pure (Pure.pure x : pure.toMonad m (no_index α)) : eff.toMonad m α) = Pure.pure x

theorem andcond.100.inv.inner.cond.in.outer.cond_proof : andcond.100.inv.inner.cond.in.outer.cond_before ⊑ andcond.100.inv.inner.cond.in.outer.cond_after

theorem mul_may_overflow_proof : mul_may_overflow_before ⊑ mul_may_overflow_after

theorem test_shl_nuw__all_are_safe_thm.extracted_1._4 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 15#32 == 0#32) = 1#1 →
    ¬(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 test84_proof : test84_before ⊑ test84_after

theorem PR42691_9_logical_thm (e : IntW 32) :
  select (icmp IntPred.sgt e (const? 32 13)) (icmp IntPred.ne e (const? 32 2147483647)) (const? 1 0) ⊑
    icmp IntPred.ult (add e (const? 32 (-14))) (const? 32 2147483633)

theorem not_invert_signbit_splat_mask1_proof : not_invert_signbit_splat_mask1_before ⊑ not_invert_signbit_splat_mask1_after

theorem lshr_mul_times_3_div_2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.smulOverflow 3#32 = true ∨ True ∧ x.umulOverflow 3#32 = true ∨ 1#32 ≥ ↑32) →
    1#32 ≥ ↑32 ∨ True ∧ x.saddOverflow (x >>> 1#32) = true ∨ True ∧ x.uaddOverflow (x >>> 1#32) = true → False

theorem ashr_eq_noexact_proof : ashr_eq_noexact_before ⊑ ashr_eq_noexact_after

theorem zext_sub_const_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → 42#64 - zeroExtend 64 x = 42#64

theorem ashr_lshr_exact_lshr_only_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sgt e_1 (const? 32 (-1))) (lshr e_1 e { «exact» := true }) (ashr e_1 e) ⊑
    ashr e_1 e

theorem negate_select_of_op_vs_negated_op_nsw_commuted_thm (e : IntW 8) (e_1 : IntW 1) (e_2 : IntW 8) :
  sub e_2 (select e_1 e (sub (const? 8 0) e { «nsw» := true, «nuw» := false })) ⊑
    add (select e_1 (sub (const? 8 0) e) e) e_2

theorem t4_ugt_slt_128_thm.extracted_1._14 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (143#32 <ᵤ x_2 + 16#32) = 1#1 → ofBool (127#32 <ₛ x_2) = 1#1 → x_2 = x

theorem or_trunc_lshr_proof : or_trunc_lshr_before ⊑ or_trunc_lshr_after

theorem test26_proof : test26_before ⊑ test26_after

theorem n10_ashr_lshr_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 32),
  ¬(zeroExtend 32 (32#16 - x) ≥ ↑32 ∨ x + -1#16 ≥ ↑16) →
    True ∧ (32#16 - x).msb = true ∨ zeroExtend 32 (32#16 - x) ≥ ↑32 ∨ x + -1#16 ≥ ↑16 → False

theorem and_zext_eq_zero_thm (e e_1 : IntW 32) :
  LLVM.and (zext 32 (icmp IntPred.eq e_1 (const? 32 0))) (LLVM.xor (lshr e_1 e) (const? 32 (-1))) ⊑
    zext 32 (icmp IntPred.eq e_1 (const? 32 0))

theorem test_sext2_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → -1#32 = signExtend 32 1#1

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

theorem or_test1_proof : or_test1_before ⊑ or_test1_after

@[simp]
theorem le_trans {e1 e2 e3 : EffectKind} (h12: e1 ≤ e2) (h23: e2 ≤ e3) : e1 ≤ e3

@[simp, grind=] lemma val_num_appendInr (r : DeleteRange ⟨ts⟩) :
    (r.appendInr (Γ := Γ)).num.val = r.num.val

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

theorem ashrsgt_02_15_exact_proof : ashrsgt_02_15_exact_before ⊑ ashrsgt_02_15_exact_after

theorem reassoc_mul_nuw_proof : reassoc_mul_nuw_before ⊑ reassoc_mul_nuw_after

theorem main5f_like_logical_thm.extracted_1._7 : ∀ (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 0#1

theorem reassoc_x2_mul_nuw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.umulOverflow 5#32 = true ∨
        True ∧ x.umulOverflow 9#32 = true ∨ True ∧ (x_1 * 5#32).umulOverflow (x * 9#32) = true) →
    True ∧ (x_1 * x).umulOverflow 45#32 = true → False

theorem urem_constant_dividend_select_of_constants_divisor_thm.extracted_1._2 : ∀ (x : BitVec 1),
  ¬x = 1#1 → ¬BitVec.ofInt 32 (-3) = 0 → 42#32 % BitVec.ofInt 32 (-3) = 42#32

theorem test_invert_demorgan_or3_proof : test_invert_demorgan_or3_before ⊑ test_invert_demorgan_or3_after

theorem zext_zext_sgt_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (zeroExtend 32 x <ₛ zeroExtend 32 x_1) = ofBool (x <ᵤ x_1)

theorem t2_ashr_thm (e : IntW 8) (e_1 : IntW 32) :
  ashr e_1 (sext 32 e) ⊑ ashr e_1 (zext 32 e { «nneg» := true })

theorem test6_thm.extracted_1._1 : ∀ (x : BitVec 1), ofBool (zeroExtend 32 x != 0#32) = x

theorem and_or1_thm.extracted_1._8 : ∀ (x x_1 x_2 : BitVec 1), ¬x_2 ^^^ 1#1 ||

theorem ugt_and_min_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.ugt e_1 e) (icmp IntPred.eq e_1 (const? 8 0)) ⊑ const? 1 0

theorem test_shl_nuw_nsw__nuw_is_safe_proof : test_shl_nuw_nsw__nuw_is_safe_before ⊑ test_shl_nuw_nsw__nuw_is_safe_after

theorem positive_sameconst_shlnsw_ashrexact_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x >>> 3#8 <<< 3#8 ≠ x ∨
        3#8 ≥ ↑8 ∨ True ∧ (x.sshiftRight' 3#8 <<< 3#8).sshiftRight' 3#8 ≠ x.sshiftRight' 3#8 ∨ 3#8 ≥ ↑8) →
    x.sshiftRight' 3#8 <<< 3#8 = x

theorem urem_illegal_type_c_thm.extracted_1._2 : ∀ (x : BitVec 9),
  ¬10#32 = 0 → ¬(10#9 = 0 ∨ True ∧ (x % 10#9).msb = true) → zeroExtend 32 x % 10#32 = zeroExtend 32 (x % 10#9)

theorem testi16i8_ne_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(7#8 ≥ ↑8 ∨ 8#16 ≥ ↑16) →
    ofBool ((truncate 8 x).sshiftRight' 7#8 != truncate 8 (x >>> 8#16)) =
      ofBool (x + BitVec.ofInt 16 (-128) <ᵤ BitVec.ofInt 16 (-256))

lemma CNFA.autWidth_spec : autWidth wp n |>.Sim (NFA'.autWidth wp n)

theorem e_113 :
     - 5 *  ~~~(x ^^^ y) - 11 *  ~~~(x &&&  ~~~y) + 14 *  ~~~(x ||| y) + 9 *  ~~~(x |||  ~~~y) - 2 * (x &&&  ~~~y) + 14 * (x &&& y) =  - 2 *  ~~~(x &&&  ~~~x)

theorem test_proof : test_before ⊑ test_after

theorem lshr_xor_proof : lshr_xor_before ⊑ lshr_xor_after

theorem or_to_nxor1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  x_1 &&& x ||

theorem sub_sext_mask1_trunc_lshr_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬15#64 ≥ ↑64 →
    ¬(48#64 ≥ ↑64 ∨
          63#64 ≥ ↑64 ∨
            True ∧ signExtend 64 (truncate 8 ((x <<< 48#64).sshiftRight' 63#64)) ≠ (x <<< 48#64).sshiftRight' 63#64 ∨
              True ∧ (truncate 8 ((x <<< 48#64).sshiftRight' 63#64)).saddOverflow 10#8 = true) →
      10#32 - signExtend 32 (truncate 8 (x >>> 15#64) &&& 1#8) =
        zeroExtend 32 (truncate 8 ((x <<< 48#64).sshiftRight' 63#64) + 10#8)

theorem PR2539_A_thm (e : IntW 1) : icmp IntPred.slt (zext 32 e) (const? 32 1) ⊑ LLVM.xor e (const? 1 1)

theorem test_shl_nuw_nsw__all_are_safe_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 15#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 → False

theorem fold_sext_to_and3_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x &&& 1073741826#32 != 2#32) = ofBool (x &&& BitVec.ofInt 8 (-126) != 2#8)

theorem in_constant_varx_14_thm.extracted_1._1 : ∀ (x : BitVec 4),
  (x ^^^ BitVec.ofInt 4 (-2)) &&& 1#4 ^^^ BitVec.ofInt 4 (-2) = x ||

theorem ashrsgt_02_00_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬2#4 ≥ ↑4 → ofBool (0#4 <ₛ x.sshiftRight' 2#4) = ofBool (3#4 <ₛ x)

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 invert_both_cmp_operands_sub_thm (e e_1 : IntW 32) :
  icmp IntPred.ult (sub (LLVM.xor e_1 (const? 32 (-1))) e) (const? 32 42) ⊑
    icmp IntPred.ugt (add e_1 e) (const? 32 (-43))

theorem add_1_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 8) (x_3 : BitVec 1),
  ¬x_3 = 1#1 → (x_1 ^^^ 123#8) + x ^^^ -1#8 = (x_1 ^^^ BitVec.ofInt 8 (-124)) - x

theorem xor_with_or_disjoint_ab_proof : xor_with_or_disjoint_ab_before ⊑ xor_with_or_disjoint_ab_after

theorem and_xor_common_op_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(x_1 = 0 ∨ x_1 = 0 ∨ x = 0) →
    ¬(x_1 = 0 ∨ x = 0) → 42#32 / x_1 &&& (42#32 / x_1 ^^^ 43#32 / x) = 42#32 / x_1 &&& (43#32 / x ^^^ -1#32)

theorem or_signbit_select_shl_proof : or_signbit_select_shl_before ⊑ or_signbit_select_shl_after

theorem or_sext_sext_thm.extracted_1._1 : ∀ (x : BitVec 4) (x_1 : BitVec 8),
  signExtend 16 x_1 ||

theorem logical_and_cond_reuse_thm (e e_1 : IntW 1) : select e_1 e e_1 ⊑ select e_1 e (const? 1 0)

theorem icmp_eq_zext_ne_one_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (zeroExtend 32 (ofBool (x != 1#32)) == x) = 0#1

theorem sub_2_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 1) (x_2 : BitVec 8),
  x_1 = 1#1 → x_2 - (x ^^^ -1#8) ^^^ -1#8 = BitVec.ofInt 8 (-2) - (x + x_2)

theorem ashrsgt_02_06_thm.extracted_1._1 : ∀ (x : BitVec 4), ¬2#4 ≥ ↑4 → ofBool (6#4 <ₛ x.sshiftRight' 2#4) = 0#1

theorem t10_constants_thm (e : IntW 64) (e_1 : IntW 32) :
  icmp IntPred.ne (LLVM.and (lshr e_1 (const? 32 12)) (trunc 32 (shl e (const? 64 14)))) (const? 32 0) ⊑
    icmp IntPred.ne (LLVM.and (lshr e_1 (const? 32 26)) (trunc 32 e)) (const? 32 0)

theorem const_sub_sub_const_thm (e : IntW 32) : sub (sub (const? 32 8) e) (const? 32 2) ⊑ sub (const? 32 6) e

theorem test15_proof : test15_before ⊑ test15_after

theorem lshrult_03_03_proof : lshrult_03_03_before ⊑ lshrult_03_03_after

theorem e_1060 :
    2 * t + 2 *  ~~~(z &&&  ~~~z) + 1 *  ~~~(z &&& t) - 3 *  ~~~(z ||| t) - 4 *  ~~~(z |||  ~~~t) - 2 * (z &&&  ~~~t) - 4 * (z &&& t) = 1 * (z ^^^ t)

@[simp] theorem lookup_matchVar_nil (m : MatchVarResult lets v .nil w ma) :
    m.val.lookup ⟨_, w⟩ = some v

theorem PR44545_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x == 0#32) = 1#1 →
    ¬(True ∧ (truncate 16 0#32).saddOverflow (-1#16) = true) → truncate 16 0#32 + -1#16 = -1#16

theorem n5_proof : n5_before ⊑ n5_after

theorem xor_lshr_thm.extracted_1._2 : ∀ (x x_1 x_2 x_3 : BitVec 8),
  ¬(x_2 ≥ ↑8 ∨ x_2 ≥ ↑8) → ¬x_2 ≥ ↑8 → x_3 >>> x_2 ^^^ x_1 ^^^ x >>> x_2 = (x_3 ^^^ x) >>> x_2 ^^^ x_1

theorem PR42691_6_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x <ᵤ BitVec.ofInt 32 (-2147483647)) ||

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

omit [LawfulBEq A] [Fintype S] in
lemma processOneElem_rel_preserve_olds :
    s₂ ~[(processOneElem A S final s₁ st (a, sa)).rel] sa' →
    s₂ ∈ st.m.states → s₂ ~[st.rel] sa'

theorem sdiv_x_by_const_cmp_x_proof : sdiv_x_by_const_cmp_x_before ⊑ sdiv_x_by_const_cmp_x_after

theorem e_107 :
     - 1 * y + 7 * x + 1 *  ~~~x + 11 *  ~~~(x &&& y) - 18 * (x &&&  ~~~y) - 6 * (x &&& y) = 11 *  ~~~(x |||  ~~~y) + 12 *  ~~~(x ||| y)

theorem test13commuted_thm (e e_1 : IntW 32) :
  LLVM.xor (LLVM.xor e_1 (const? 32 (-1))) (LLVM.and (LLVM.xor e (const? 32 (-1))) e_1) ⊑
    LLVM.xor (LLVM.and e_1 e) (const? 32 (-1))

theorem logical_or_logical_or_icmps_comm3_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 8),
  ¬x_1 ≥ ↑8 →
    ofBool (x_2 &&& 1#8 <<< x_1 == 0#8) = 1#1 ∨ ofBool (x_2 &&& 1#8 == 0#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) →
        ¬ofBool (x_2 &&& (1#8 <<< x_1 ||| 1#8) != 1#8 <<< x_1 ||| 1#8) = 1#1 → 1#1 = ofBool (x == 42#8)

theorem test_lshr__exact_is_safe_proof : test_lshr__exact_is_safe_before ⊑ test_lshr__exact_is_safe_after

theorem shift_xor_multiuse_cmp_with_xor_proof : shift_xor_multiuse_cmp_with_xor_before ⊑ shift_xor_multiuse_cmp_with_xor_after

theorem lshr_pow2_slt_thm (e : IntW 8) :
  icmp IntPred.slt (lshr (const? 8 (-128)) e) (const? 8 3) ⊑
    icmp IntPred.slt (lshr (const? 8 (-128)) e { «exact» := true }) (const? 8 3)

theorem t1_flags_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 8),
  ¬(True ∧ x_2.ssubOverflow x_1 = true ∨
        True ∧ x_2.usubOverflow x_1 = true ∨
          True ∧ (x_2 - x_1).ssubOverflow x = true ∨ True ∧ (x_2 - x_1).usubOverflow x = true) →
    ¬(True ∧ x_1.saddOverflow x = true ∨
          True ∧ x_1.uaddOverflow x = true ∨
            True ∧ x_2.ssubOverflow (x_1 + x) = true ∨ True ∧ x_2.usubOverflow (x_1 + x) = true) →
      x_2 - x_1 - x = x_2 - (x_1 + x)

theorem positive_biggershl_shlnsw_lshrexact_proof : positive_biggershl_shlnsw_lshrexact_before ⊑ positive_biggershl_shlnsw_lshrexact_after

theorem fold_zext_xor_sandwich_thm.extracted_1._1 : ∀ (x : BitVec 1),
  zeroExtend 32 (x ^^^ 1#1) ^^^ 2#32 = zeroExtend 32 x ^^^ 3#32

theorem test_shl_nsw__nsw_is_safe_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x ||| BitVec.ofInt 32 (-83886080) == BitVec.ofInt 32 (-83886079)) = 1#1 →
    ¬(True ∧ ((x ||| BitVec.ofInt 32 (-83886080)) <<< 2#32).sshiftRight' 2#32 ≠ x ||| BitVec.ofInt 32 (-83886080) ∨
          2#32 ≥ ↑32) →
      True ∧ ((x ||| BitVec.ofInt 32 (-83886080)) <<< 2#32).sshiftRight' 2#32 ≠ x ||

theorem e_2301 :
     - 1 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 1 * (f ^^^ (d |||  ~~~e)) + 11 * (e &&& (d ^^^ f)) - 6 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 6 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 6 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 3 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 7 *  ~~~(e |||  ~~~f) + 2 * (d ^^^ ( ~~~e ||| f)) + 1 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 3 * (d ||| (e ^^^ f)) - 2 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 5 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 1 * (f ^^^  ~~~(d ||| (e &&& f))) - 11 * (f &&& (d ^^^ e)) + 4 * (f ^^^  ~~~(d &&&  ~~~e)) - 2 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 11 * ( ~~~d &&& ( ~~~e ||| f)) - 2 * (f ^^^  ~~~(d ||| e)) + 7 * (f ^^^ (d ||| e)) - 1 * (f ^^^ (d ||| ( ~~~e &&& f))) + 2 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 4 *  ~~~(e ||| f) - 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 1 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 3 *  ~~~(d ^^^ f) - 7 * ((d &&& e) ||| (e ^^^ f)) - 7 * (e ^^^  ~~~(d |||  ~~~f)) + 3 *  ~~~(d &&&  ~~~f) + 5 * ( ~~~d ||| ( ~~~e ||| f)) - 1 * (f ^^^ ( ~~~d ||| (e &&& f))) - 2 * ((d &&& e) ^^^ (e |||  ~~~f)) + 11 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 2 * ((d &&& e) ^^^ (e ||| f)) + 2 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 3 * (e ^^^  ~~~(d ||| (e &&& f))) - 3 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 7 * (f ||| (d &&&  ~~~e)) - 3 * (d ||| (e &&& f)) - 7 * (f ^^^ (d ||| ( ~~~e ||| f))) - 2 * (e ^^^ (d ||| f)) + 1 * (e ||| f) - 7 * ( ~~~d &&& (e ^^^ f)) + 3 * ( ~~~d ||| (e &&& f)) + 4 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 7 * (f &&&  ~~~(d &&&  ~~~e)) + 2 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 2 *  ~~~(d ||| (e &&& f)) + 3 * ((d ^^^ e) ||| (d ^^^ f)) - 1 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 1 * (d ^^^ (e &&& f)) + 4 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 2 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 4 * (f ^^^  ~~~(d &&& e)) - 1 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 1 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 8 *  ~~~(d ||| ( ~~~e ||| f)) - 9 *  ~~~( ~~~d ||| (e ||| f)) - 20 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 23 * ( ~~~d &&& ( ~~~e &&& f)) + 8 * ( ~~~d &&& (e &&& f)) - 1 * (d &&& ( ~~~e &&& f)) = 8 *  ~~~(d ||| (e ||| f))

theorem bool_eq0_logical_thm (e : IntW 64) :
  select (icmp IntPred.sgt e (const? 64 0))
      (icmp IntPred.eq (icmp IntPred.eq e (const? 64 1)) (const? 1 0)) (const? 1 0) ⊑
    icmp IntPred.sgt e (const? 64 1)

theorem lshr_ne_opposite_msb_thm (e : IntW 8) :
  icmp IntPred.ne (lshr (const? 8 (-128)) e) (const? 8 1) ⊑ icmp IntPred.ne e (const? 8 7)

theorem ashr_overshift_proof : ashr_overshift_before ⊑ ashr_overshift_after

theorem test11_proof : test11_before ⊑ test11_after

theorem substitute_constant_and_eq_ugt_swap_proof : substitute_constant_and_eq_ugt_swap_before ⊑ substitute_constant_and_eq_ugt_swap_after

theorem ule_umax3_proof : ule_umax3_before ⊑ ule_umax3_after

theorem e_804 :
    1 * (z ^^^ t) + 4 *  ~~~(z ||| t) - 8 *  ~~~(z |||  ~~~t) - 1 * (z &&&  ~~~t) + 4 * (z &&& t) = 11 *  ~~~(z ^^^ t) - 7 *  ~~~(z &&&  ~~~t)

theorem ashr_ult_10_thm (e : IntW 4) :
  icmp IntPred.ult (ashr e (const? 4 1)) (const? 4 (-6)) ⊑ icmp IntPred.sgt e (const? 4 (-1))

theorem udiv_i32_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ¬zeroExtend 32 x = 0 → x = 0 → False

theorem e_2090 :
    2 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 1 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 7 * (e |||  ~~~(d |||  ~~~f)) - 7 * ((d &&&  ~~~e) ||| (e ^^^ f)) - 3 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * f - 2 *  ~~~(e &&&  ~~~f) - 5 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 3 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 4 * (f &&&  ~~~(d &&&  ~~~e)) - 6 * (f ^^^ (d ||| (e &&& f))) + 1 *  ~~~(d |||  ~~~f) - 2 * (e ^^^ (d &&& f)) - 5 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 2 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 2 * (e ||| (d &&&  ~~~f)) - 6 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 11 * (d |||  ~~~e) + 11 * ( ~~~e |||  ~~~(d ^^^ f)) + 7 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (e ^^^  ~~~(d &&& (e ||| f))) - 1 *  ~~~(d ||| (e &&& f)) - 5 * (d ^^^ (e ||| f)) - 7 * ((d &&& f) |||  ~~~(e ||| f)) + 1 * ((d &&& f) ^^^ (e ||| f)) + 4 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 2 * (e ||| (d &&& f)) + 4 *  ~~~(d &&& ( ~~~e &&& f)) + 2 * (e &&& (d |||  ~~~f)) + 5 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 11 * (f ^^^ (d ||| (e ||| f))) + 11 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 5 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 11 *  ~~~(d ||| (e ||| f)) + 3 *  ~~~(d ||| ( ~~~e ||| f)) + 27 *  ~~~( ~~~d ||| (e ||| f)) + 11 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 11 * ( ~~~d &&& ( ~~~e &&& f)) - 32 * ( ~~~d &&& (e &&& f)) + 6 * (d &&& ( ~~~e &&& f)) - 5 * (d &&& (e &&& f)) =  - 5 * ((d ^^^ e) &&& (d ^^^ f)) - 3 * ((d &&& e) ||| (e ^^^ f))

theorem icmp_equality_test_commute_select1_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 64),
  ¬ofBool (x_2 == x_1) = 1#1 → ofBool (x == x_1) = 1#1 → 0#1 = ofBool (x_2 == x)

@[aesop 50% unsafe]
theorem Std.HashMap.insert_keys_perm_new [BEq K] [LawfulBEq K] [Hashable K] [LawfulHashable K] (m : Std.HashMap K V) (k : K) (v : V) :
    k ∉ m → (m.insert k v).keys.Perm (k :: m.keys)

theorem main4c_logical_proof : main4c_logical_before ⊑ main4c_logical_after

theorem not_or_or_and_not_and_and_commute2_proof : not_or_or_and_not_and_and_commute2_before ⊑ not_or_or_and_not_and_and_commute2_after

theorem e_524 :
     - 1 *  ~~~x + 1 * x - 7 *  ~~~(x &&& y) - 1 *  ~~~(x &&&  ~~~y) - 1 * y + 31 *  ~~~(x ||| y) + 21 *  ~~~(x |||  ~~~y) + 17 * (x &&&  ~~~y) + 23 * (x &&& y) = 11 *  ~~~(x &&&  ~~~x) + 11 *  ~~~(x ^^^ y)

theorem e_1941 :
     - 6 * ( ~~~a ||| (b &&& c)) - 1 * (b ^^^  ~~~(a ||| (b &&& c))) - 7 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 7 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 1 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) - 3 *  ~~~(a ||| ( ~~~b &&& c)) - 1 * (b ^^^ (a &&& (b ^^^ c))) - 6 * (b ^^^  ~~~(a &&&  ~~~c)) - 7 * (a &&& (b ^^^ c)) + 2 *  ~~~(b &&& c) + 11 * (a &&& ( ~~~b ||| c)) + 1 * (b ^^^ (a &&& c)) - 6 *  ~~~( ~~~a &&& ( ~~~b &&& c)) + 4 *  ~~~a - 11 * (c ^^^  ~~~(a &&& (b &&& c))) - 11 *  ~~~(a &&& b) + 5 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) + 3 * (c ^^^ ( ~~~a &&& (b ||| c))) - 1 * (b ^^^ (a ||| (b ^^^ c))) + 7 *  ~~~(b ||| c) - 5 *  ~~~( ~~~a &&& (b ^^^ c)) - 2 * (b &&&  ~~~(a ^^^ c)) - 11 * ((b &&& c) ||| (a &&& (b ||| c))) + 2 * (b ^^^ ( ~~~a &&& (b ||| c))) + 1 * (c ^^^  ~~~(a &&& b)) + 4 * (c ^^^ (a ||| (b ||| c))) + 1 * (c ^^^  ~~~(a ||| b)) + 1 * ((a &&& b) |||  ~~~(b ||| c)) - 6 * (c ^^^  ~~~(a ||| (b &&& c))) + 5 * (b ^^^  ~~~(a &&& c)) + 2 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 1 * ( ~~~b |||  ~~~(a ^^^ c)) + 2 * ( ~~~c |||  ~~~(a ^^^ b)) - 2 * (b ||| c) - 11 * (c ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 2 * (c ^^^ ( ~~~a ||| (b ||| c))) + 4 *  ~~~(a |||  ~~~c) - 7 * (b &&& c) + 4 * (c ||| (a &&&  ~~~b)) - 3 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 5 * ((a &&& b) |||  ~~~(b |||  ~~~c)) - 1 *  ~~~c + 4 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) + 1 *  ~~~(a ||| b) - 1 * b + 24 *  ~~~(a ||| (b ||| c)) + 30 *  ~~~(a ||| ( ~~~b ||| c)) + 7 *  ~~~( ~~~a ||| (b ||| c)) + 30 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 1 * ( ~~~a &&& ( ~~~b &&& c)) + 34 * ( ~~~a &&& (b &&& c)) + 16 * (a &&& ( ~~~b &&& c)) + 16 * (a &&& (b &&& c)) =  - 7 * ( ~~~b ||| (a ^^^ c))

theorem canonicalize_logic_first_and0_proof : canonicalize_logic_first_and0_before ⊑ canonicalize_logic_first_and0_after

theorem not_or_or_not_commute1_proof : not_or_or_not_commute1_before ⊑ not_or_or_not_commute1_after

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 bmod_eq_of_ge_and_le (z : Int) (m : Nat)
    (hlower_bound : m/2 ≤ z) (hupper_bound : z < m/2) :
    z.bmod m = z

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

theorem negative5_logical_proof : negative5_logical_before ⊑ negative5_logical_after

theorem test1_proof : test1_before ⊑ test1_after

theorem select_or_disjoint_or_proof : select_or_disjoint_or_before ⊑ select_or_disjoint_or_after

theorem modulo2_thm (e : IntW 32) :
  add (select (icmp IntPred.slt (LLVM.srem e (const? 32 2)) (const? 32 0)) (const? 32 2) (const? 32 0))
      (LLVM.srem e (const? 32 2)) { «nsw» := true, «nuw» := false } ⊑
    LLVM.and e (const? 32 1)

theorem test11_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬zeroExtend 128 x &&& 31#128 ≥ ↑128 →
    ¬(True ∧ (x &&& 31#32).msb = true ∨
          True ∧
              (zeroExtend 64 x_1 <<< zeroExtend 64 (x &&& 31#32)).sshiftRight' (zeroExtend 64 (x &&& 31#32)) ≠
                zeroExtend 64 x_1 ∨
            True ∧
                zeroExtend 64 x_1 <<< zeroExtend 64 (x &&& 31#32) >>> zeroExtend 64 (x &&& 31#32) ≠ zeroExtend 64 x_1 ∨
              zeroExtend 64 (x &&& 31#32) ≥ ↑64) →
      truncate 64 (zeroExtend 128 x_1 <<< (zeroExtend 128 x &&& 31#128)) =
        zeroExtend 64 x_1 <<< zeroExtend 64 (x &&& 31#32)

theorem sext_zext_ult_known_nonneg_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬6#8 ≥ ↑8 → ofBool (signExtend 32 x_1 <ᵤ zeroExtend 32 (x >>> 6#8)) = ofBool (x_1 <ᵤ x >>> 6#8)

theorem t0_thm.extracted_1._21 : ∀ (x x_1 x_2 x_3 : BitVec 8) (x_4 : BitVec 1),
  x_4 ^^^ 1#1 = 1#1 → ¬x_4 = 1#1 → ¬ofBool (x_3 == x_2) = 1#1 → ¬ofBool (x_3 != x_2) = 1#1 → x = x_1

theorem PR38139_proof : PR38139_before ⊑ PR38139_after

theorem select_icmp_ne_0_and_8_or_1073741824_proof : select_icmp_ne_0_and_8_or_1073741824_before ⊑ select_icmp_ne_0_and_8_or_1073741824_after

theorem test48_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬8#32 ≥ ↑32 →
    True ∧ (zeroExtend 32 x <<< 8#32).sshiftRight' 8#32 ≠ zeroExtend 32 x ∨
        True ∧ zeroExtend 32 x <<< 8#32 >>> 8#32 ≠ zeroExtend 32 x ∨
          8#32 ≥ ↑32 ∨
            True ∧ (zeroExtend 32 x <<< 8#32 &&& zeroExtend 32 x != 0) = true ∨
              True ∧ (zeroExtend 32 x <<< 8#32 ||| zeroExtend 32 x).msb = true →
      False

theorem select_icmp_slt_zero_smin_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x <ₛ 0#8) = 1#1 → x = x ||

theorem ashr_mul_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬8#20 ≥ ↑20 → True ∧ (signExtend 16 x_1).smulOverflow (signExtend 16 x) = true ∨ 8#16 ≥ ↑16 → False

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

theorem test_sext1_thm (e e_1 : IntW 1) :
  select e_1 (sext 32 e) (const? 32 0) ⊑ sext 32 (select e_1 e (const? 1 0))

theorem test25_proof : test25_before ⊑ test25_after

theorem test_slt_proof : test_slt_before ⊑ test_slt_after

theorem test2_proof : test2_before ⊑ test2_after
</all_available_lemmas>

<local_ctx>
import Batteries.Data.Fin.Basic

import Batteries.Data.Fin.Lemmas

import Blase.SingleWidth.Defs

import Blase.AutoStructs.Constructions

import Blase.AutoStructs.Defs

import Blase.AutoStructs.FiniteStateMachine

import Mathlib.Tactic.Ring

import Mathlib.Data.Nat.Size -- TODO: remove and get rid of shiftLeft_eq_mul_pow use

import Mathlib.Data.BitVec

import Mathlib.Tactic.FinCases

open Fin.NatCast

open Mathlib

section fsm

variable {arity : Type} [FinEnum arity]

open BitStream in

end fsm

section nfas_relations

end nfas_relations

def liftOp n : Fin (n + 1) → Fin (n + 3) :=
  fun k =>
    if k = n then Fin.last (n+2) else k.castLE (by admit /- proof elided -/
    )

@[simp]
def liftOp_unchanged (k : Fin n) : liftOp n k.castSucc = k.castLE (by simp) :=

inductive TermBinop where
| and | or | xor | add | sub

def TermBinop.subst (op : TermBinop) (t₁ t₂ : Term) : Term :=
  match op with
  | .and => .and t₁ t₂
  | .or => .or t₁ t₂
  | .xor => .xor t₁ t₂
  | .add => .add t₁ t₂
  | .sub => .sub t₁ t₂

def TermBinop.openTerm (op : TermBinop) : Term := op.subst (.var 0) (.var 1)

@[simp]
def TermBinop.openTerm_arity (op : TermBinop) : op.openTerm.arity + 1 = 3 :=

def swapLastTwoBlock (x : Fin (n + 3)) : Fin (n + 3) :=
  if x = Fin.last (n+2) then n
  else if x = n+1 then Fin.last (n + 2)
  else if x = n then n + 1
  else x
</local_ctx>

<target_theorem>
lemma TermBinop.alt_lang {t₁ t₂ : Term} (op : TermBinop) :
  (op.subst_arity' ▸ (op.subst t₁ t₂).language) =
    let lop : Set (BitVecs 3) :=
</target_theorem>

