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>
Bool in Init.Prelude
Nat in Init.Prelude
Vector in Init.Data.Vector.Basic
Fin in Init.Prelude
String in Init.Prelude
Unit in Init.Prelude
List in Init.Prelude
Field in Mathlib.Algebra.Field.Defs
DecidableEq in Init.Prelude
FinEnum in Mathlib.Data.FinEnum
Hashable in Init.Prelude
Empty in Init.Prelude
Empty.elim in Init.Core
Sum in Init.Core
Sum.elim in Init.Data.Sum.Basic
ZMod in Mathlib.Data.ZMod.Defs

syntax "llvm.and"     : MLIR.Pretty.uniform_op

syntax "llvm.ashr"    : MLIR.Pretty.exact_op

syntax "llvm.add"     : MLIR.Pretty.overflow_op

syntax "llvm.return"  : MLIR.Pretty.uniform_op

syntax "return" : MLIR.Pretty.uniform_op

macro_rules
  
  | `(mlir_op| $v:mlir_op_operand = mod_arith.constant $x:neg_num : $t) =>
    `(mlir_op| $v:mlir_op_operand = "mod_arith.constant" () {value = $x:neg_num} : () -> ($t))

| `(mlir_op| $v:mlir_op_operand = mod_arith.constant ${ $x:term } : $t) => do
      let ctor := mkIdent ``MLIR.AST.AttrValue.int
      let x ← `($ctor $x [mlir_type| i64])
      `(mlir_op| $v:mlir_op_operand = "mod_arith.constant" () {value = $$($x)} : () -> ($t))

macro_rules
  | `(mlir_op| $resName:mlir_op_operand = $name:InstCombine.cmp_op_name $x, $y $[: $t]?) => do
    let some opName := extractOpName name.raw
      | Macro.throwUnsupported
    let t ← t.getDM `(mlir_type| _)
    `(mlir_op| $resName:mlir_op_operand = $opName ($x, $y) : ($t, $t) -> (i1) )

macro_rules
  | `(mlir_op| $resName:mlir_op_operand = $name:InstCombine.int_cast_op $x : $t to $t') => do
    let some opName := extractOpName name.raw
      | Macro.throwUnsupported
    `(mlir_op| $resName:mlir_op_operand = $opName ($x) : ($t) -> $t')

macro_rules
  | `(mlir_op| $res:mlir_op_operand = llvm.mlir.constant( $x $[: $inner_type]?)
      $[: $outer_type]? ) => do
       
      let outer_type ← outer_type.getDM `(mlir_type| _)
      let inner_type := inner_type.getD outer_type
      `(mlir_op| $res:mlir_op_operand = "llvm.mlir.constant"()
          {value = $x:neg_num : $inner_type} : () -> ($outer_type) )
  | `(mlir_op| $res:mlir_op_operand = llvm.mlir.constant( ${ $x:term }) $[: $t]?) => do
      let t ← t.getDM `(mlir_type| _)
      let x ← `(MLIR.AST.AttrValue.int $x [mlir_type| $t])
      `(mlir_op| $res:mlir_op_operand = "llvm.mlir.constant"() {value = $$($x) } : () -> ($t) )

macro_rules
  | `(mlir_op| $res:mlir_op_operand = llvm.mlir.constant (true) $[: $t]?) =>
      `(mlir_op| $res:mlir_op_operand = llvm.mlir.constant (1 : i1) : i1)
  | `(mlir_op| $res:mlir_op_operand = llvm.mlir.constant (false) $[: $t]?) =>
      `(mlir_op| $res:mlir_op_operand = llvm.mlir.constant (0 : i1) : i1)
  | `(mlir_op| $res:mlir_op_operand = llvm.mlir.constant $x $[: $t]?) =>
      `(mlir_op| $res:mlir_op_operand = llvm.mlir.constant($x $[: $t]?) $[: $t]?)
  | `(mlir_op| $res:mlir_op_operand = llvm.mlir.constant ${ $x:term } $[: $t]?) =>
      `(mlir_op| $res:mlir_op_operand = llvm.mlir.constant($$($x) $[: $t]?) $[: $t]?)

macro_rules
  | `(mlir_op| $res:mlir_op_operand = llvm.icmp $p $x, $y $[: $t]?) => do
    let t ← t.getDM `(mlir_type| _)
    match p.getString with
      | "eq" => `(mlir_op| $res:mlir_op_operand = "llvm.icmp.eq" ($x, $y) : ($t, $t) -> (i1))
      | "ne" => `(mlir_op| $res:mlir_op_operand = "llvm.icmp.ne" ($x, $y) : ($t, $t) -> (i1))
      | "slt" => `(mlir_op| $res:mlir_op_operand = "llvm.icmp.slt" ($x, $y) : ($t, $t) -> (i1))
      | "sle" => `(mlir_op| $res:mlir_op_operand = "llvm.icmp.sle" ($x, $y) : ($t, $t) -> (i1))
      | "sgt" => `(mlir_op| $res:mlir_op_operand = "llvm.icmp.sgt" ($x, $y) : ($t, $t) -> (i1))
      | "sge" => `(mlir_op| $res:mlir_op_operand = "llvm.icmp.sge" ($x, $y) : ($t, $t) -> (i1))
      | "ult" => `(mlir_op| $res:mlir_op_operand = "llvm.icmp.ult" ($x, $y) : ($t, $t) -> (i1))
      | "ule" => `(mlir_op| $res:mlir_op_operand = "llvm.icmp.ule" ($x, $y) : ($t, $t) -> (i1))
      | "ugt" => `(mlir_op| $res:mlir_op_operand = "llvm.icmp.ugt" ($x, $y) : ($t, $t) -> (i1))
      | "uge" => `(mlir_op| $res:mlir_op_operand = "llvm.icmp.uge" ($x, $y) : ($t, $t) -> (i1))
      | _ => Macro.throwErrorAt p s!"unexpected predicate {p.getString}"

macro_rules
  | `(mlir_op| $res:mlir_op_operand = llvm.select $c, $x, $y $[: $t]?) => do
    let t ← t.getDM `(mlir_type| _)
    `(mlir_op| $res:mlir_op_operand = "llvm.select" ($c, $x, $y) : (i1, $t, $t) -> ($t))

macro_rules
  | `(mlir_op| $v:mlir_op_operand = arith.const $x:neg_num : $t) =>
      `(mlir_op| $v:mlir_op_operand = "arith.const" () {value = $x:neg_num } : () -> ($t))
  | `(mlir_op| $v:mlir_op_operand = arith.const ${ $x:term } : $t) => do
      let ctor := mkIdent ``MLIR.AST.AttrValue.int
      let x ← `($ctor $x [mlir_type| i64])
      
      
      
      
      `(mlir_op| $v:mlir_op_operand = "arith.const" () {value = $$($x) } : () -> ($t))

macro_rules
  | `(mlir_op| $v:mlir_op_operand = poly.const $x:neg_num : $t) =>
      `(mlir_op| $v:mlir_op_operand = "poly.const" () {value = $x:neg_num } : () -> ($t))
  | `(mlir_op| $v:mlir_op_operand = poly.const ${ $x:term } : $t) => do
      let ctor := mkIdent ``MLIR.AST.AttrValue.int
      let x ← `($ctor $x [mlir_type| i64])
      
      
      
      
      `(mlir_op| $v:mlir_op_operand = "poly.const" () {value = $$($x) } : () -> ($t))

macro_rules
  | `(mlir_op| $v:mlir_op_operand = poly.monomial $xs,* : ($ts,*) -> $t) =>
      `(mlir_op| $v:mlir_op_operand = "poly.monomial" ($xs,*) : ($ts,*) -> $t)

def BitStream : Type := Nat → Bool

structure FSM (arity : Type) : Type 1 where
   
  ( α  : Type )
  [ i : FinEnum α ]
  [ h : Hashable α ]
  [ dec_eq : DecidableEq α ]
   
  ( initCarry : α → Bool )
   
  outputCirc : Circuit (α ⊕ arity)
  nextStateCirc : α → Circuit (α ⊕ arity)

inductive Circuit (α : Type u) : Type u
  | tru : Circuit α
  | fals : Circuit α
   
  | var : (positive: Bool) → α → Circuit α
  | and : Circuit α → Circuit α → Circuit α
  | or : Circuit α → Circuit α → Circuit α
  | xor : Circuit α → Circuit α → Circuit α
deriving Repr, DecidableEq

def Var (Γ : Context Ty) (ty : Ty) : Type := { v : VarName // Γ.hasType v ty }

def carryWith (p : FSM arity) (carryState : p.α → Bool) (x : arity → BitStream) (n : Nat) : p.α → Bool := fun a =>
  (p.changeInitCarry carryState).carry x n a

def changeInitCarry (p : FSM arity) (c : p.α → Bool) : FSM arity :=
  { p with initCarry := c }

def zero : FSM (Fin 0) :=
  { α := Empty,
    initCarry := Empty.elim,
    nextStateCirc := Empty.elim,
    outputCirc := Circuit.fals
  }

def carry (x : arity → BitStream) : ℕ → p.State
  | 0 => p.initCarry
  | n+1 => (p.nextBit (carry x n) (fun i => x i n)).1

abbrev State : Type := p.α → Bool

def nextBit : p.State → (arity → Bool) → p.State × Bool :=
  fun carry inputBits =>
    let input := Sum.elim carry inputBits
    let newState : p.State  := fun (a : p.α) => (p.nextStateCirc a).eval input
    let outBit : Bool       := (p.outputCirc).eval input
    (newState, outBit)

def rhs := [poly q, n, hq | {
^bb0(%a : !R):
  return %a : !R

}]

inductive AttrValue where
  | symbol: String -> AttrValue 
  | str : String -> AttrValue
  | int : Int -> MLIRType φ -> AttrValue
  | nat: Nat -> AttrValue
  | bool : Bool -> AttrValue
  | float : Float -> MLIRType φ -> AttrValue
  | type : MLIRType φ -> AttrValue
  | affine: AffineMap -> AttrValue
  | permutation: List Nat -> AttrValue 
  | list: List AttrValue -> AttrValue
  | nestedsymbol: AttrValue -> AttrValue -> AttrValue
  | alias: String -> AttrValue
  | dict: AttrDict -> AttrValue
  | opaque_: (dialect: String) -> (value: String) -> AttrValue
  | opaqueElements: (dialect: String) -> (value: String) -> (type: MLIRType φ) -> AttrValue
  | unit: AttrValue

abbrev R := (ZMod q)[X] ⧸ (Ideal.span {f q n})

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

structure Region where
  (name: String)
  (args: List <| TypedSSAVal φ)
  (ops: List Op)

private def operand1 := [mlir_op_operand| %x]

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

def scalar_i16_lshr_and_signbit_eq_before := [llvm|
{
^0(%arg33 : i16, %arg34 : i16):
  %0 = llvm.mlir.constant(-32768 : i16) : i16
  %1 = llvm.mlir.constant(0 : i16) : i16
  %2 = llvm.lshr %arg33, %arg34 : i16
  %3 = llvm.and %2, %0 : i16
  %4 = llvm.icmp "eq" %3, %1 : i16
  "llvm.return"(%4) : (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 src_after := [llvm|
{
^0(%arg0 : i1):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.zext %arg0 : i1 to i32
  %2 = llvm.shl %0, %1 overflow<nsw> : i32
  %3 = llvm.xor %2, %0 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.shl %4, %1 overflow<nsw,nuw> : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def p0_scalar_urem_by_const_before := [llvm|
{
^0(%arg20 : i32, %arg21 : i32):
  %0 = llvm.mlir.constant(128 : i32) : i32
  %1 = llvm.mlir.constant(6 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.and %arg20, %0 : i32
  %4 = llvm.urem %3, %1 : i32
  %5 = llvm.icmp "eq" %4, %2 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

def alive_AddSub_1165_src  (w : Nat)   :=
[llvm( w )| {
^bb0(%a : _, %b : _):
  %v1 = llvm.mlir.constant 0
  %v2 = llvm.sub %v1, %a
  %v3 = llvm.mlir.constant 0
  %v4 = llvm.sub %v3, %b
  %v5 = llvm.add %v2, %v4
  llvm.return %v5
}]

def fold_nested_logic_zext_icmp_before := [llvm|
{
^0(%arg87 : i64, %arg88 : i64, %arg89 : i64, %arg90 : i64):
  %0 = llvm.icmp "sgt" %arg87, %arg88 : i64
  %1 = llvm.zext %0 : i1 to i8
  %2 = llvm.icmp "slt" %arg87, %arg89 : i64
  %3 = llvm.zext %2 : i1 to i8
  %4 = llvm.and %1, %3 : i8
  %5 = llvm.icmp "eq" %arg87, %arg90 : i64
  %6 = llvm.zext %5 : i1 to i8
  %7 = llvm.or %4, %6 : i8
  "llvm.return"(%7) : (i8) -> ()
}
]

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

def or_logic_or_logic_and_7_before := [llvm|
{
^0(%arg30 : i1, %arg31 : i1, %arg32 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.or %arg31, %arg30 : i1
  %3 = "llvm.select"(%arg30, %0, %arg32) <{"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 worklist.initState (inits : Array S) (hinits : inits.toList.Nodup) (final? : S → Bool) : worklist.St A S :=
  let m := RawCNFA.empty (A := A)
  let mapm := inits.foldl (init := (Std.HashMap.emptyWithCapacity, m)) fun (map, m) sa =>
    let (s, m) := m.newState
    let m := m.addInitial s
    let m := if final? sa then m.addFinal s else m
    (map.insert sa s, m)
  let map := mapm.1
  let m := mapm.2
  let worklist_incl : ∀ sa ∈ inits, sa ∈ map :=

Prod.fst in Init.Prelude

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

def urem_illegal_type_c_after := [llvm|
{
^0(%arg7 : i9):
  %0 = llvm.mlir.constant(10 : i9) : i9
  %1 = llvm.urem %arg7, %0 : i9
  %2 = llvm.zext nneg %1 : i9 to i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

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

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

def right_identity_zero_or : RISCVPeepholeRewrite [Ty.riscv (.bv)] where
  lhs := [LV| {
    ^entry (%x: !riscv.reg):
      %c = li (0) : !riscv.reg
      %0 = or %x, %c : !riscv.reg
      ret %0 : !riscv.reg
  }]
  rhs := [LV| {
    ^entry (%x: !riscv.reg):
      ret %x : !riscv.reg
  }]

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

def ashr_x_by_const_cmp_sge_x_before := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.ashr %arg6, %0 : i32
  %2 = llvm.icmp "sge" %1, %arg6 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def llvm_sext_lower_riscv_i16_to_64 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 16)] :=
  {lhs:= sext_llvm_i16_to_64, rhs:= sext_riscv_i16_to_64}

def scalar_i64_shl_ult_const_after := [llvm|
{
^0(%arg14 : i64):
  %0 = llvm.mlir.constant(549755813632) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.and %arg14, %0 : i64
  %3 = llvm.icmp "eq" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def 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 zext_sext_add_icmp_slt_1_rhs_not_const_before := [llvm|
{
^0(%arg49 : i1, %arg50 : i1, %arg51 : i8):
  %0 = llvm.zext %arg49 : i1 to i8
  %1 = llvm.sext %arg50 : i1 to i8
  %2 = llvm.add %0, %1 : i8
  %3 = llvm.icmp "slt" %2, %arg51 : i8
  "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 shl {w : Nat} (x y : IntW w) (flags : NoWrapFlags := {nsw := false , nuw := false}) : IntW w := do
  let x' ← x
  let y' ← y
    
  if flags.nsw ∧ ((x' <<< y').sshiftRight'  y' ≠ x') then
    .poison
  else if flags.nuw ∧ ((x' <<< y') >>> y' ≠ x') then
    .poison
  else
    shl? x' y'

private partial def valuationElements (e : Expr) (elems : Array Expr := #[]) : Array Expr :=
  match_expr e with
  | Valuation.cons _Ty _instTyDenote _Γ _t x V => valuationElements V (elems.push x)
  | _ => elems

@[tactic bvAutomataFragmentNoUninterpreted]
def evalBvAutomataFragmentNoUninterpreted : Tactic := fun
| `(tactic| bv_automata_fragment_no_uninterpreted) => do
  let g ← getMainGoal
  g.withContext do
    let ws ← findExprBitwidths (← g.getType)
    let ws := ws.toArray
    if h0: ws.size = 0 then
      throwError m!"found no bitvector in the target: {indentD (← g.getType)}"
    else if hgt: ws.size > 1 then
      let (w1, wExample1) := ws[0]
      let (w2, wExample2) := ws[1]
      let mExample := m!"{w1} → {wExample1}; {w2} → {wExample2}"
      throwError m!"found multiple bitvector widths in the target: {indentD mExample}"
    else
      let (w, wExample) := ws[0]
      let g ← revertBvHyps g
      
      
      let .some g ← NNF.runNNFSimpSet g
        | trace[Bits.Frontend] m!"Converting to negation normal form automatically closed goal."
          return ()
      trace[Bits.Frontend] m!"goal after NNF: {indentD g}"
      let .some g ← Simplifications.runPreprocessing g
        | trace[Bits.Frontend] m!"Preprocessing automatically closed goal."
          return ()
      trace[Bits.Frontend] m!"goal after preprocessing: {indentD g}"
      
      let result ← reflectPredicateAux ∅ (← g.getType) w
      
      let exprs := result.exprToIx.exprs.toArray.qsort (fun ei ej => ei.1.lt ej.1)
      let mut out? : Option MessageData := .none
      let header := m!"Tactic has not understood the following expressions, and will treat them as symbolic:"
      for (e, _) in exprs do
        if e.isFVar then continue
        let eshow := indentD m!"- '{e}'"
        out? := match out? with
          | .none => header ++ Format.line ++ eshow
          | .some out => .some (out ++ eshow)
      match out? with
      | .none => pure ()
      | .some out => throwError out
| _  => throwUnsupportedSyntax

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

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

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

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

def size (α : Type u) : Circuit α → Nat
| tru | fals | var .. => 1
| and l r | or l r | xor l r => 1 + l.size  + r.size

def GLobalISelPostLegalizerCombiner :
    List (Σ Γ, Σ ty, PeepholeRewrite LLVMPlusRiscV Γ ty) :=
  (List.map (fun ⟨_,y⟩ => mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND y))
  redundant_binop_in_equality)
  ++
  (List.map (fun ⟨_,y⟩ => mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND y))
  PostLegalizerCombiner_LLVMIR_64)
  ++
  (List.map (fun ⟨_,y⟩ => mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND y))
  PostLegalizerCombiner_LLVMIR_32)
  ++
  (List.map (fun ⟨_,y⟩ => mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND y))
  canonicalize_icmp)
  ++
  List.map (fun ⟨_,y⟩ => mkRewrite (RISCVPeepholeRewriteToRiscvPeephole y))
  PostLegalizerCombiner_RISCV

instance : ToString LLVM.Op :=

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

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

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

def n15_variable_shamts_after := [llvm|
{
^0(%arg0 : i32, %arg1 : i64, %arg2 : i32, %arg3 : i64):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.lshr %arg0, %arg2 : i32
  %2 = llvm.shl %arg1, %arg3 : i64
  %3 = llvm.trunc %2 : i64 to i32
  %4 = llvm.and %1, %3 : i32
  %5 = llvm.icmp "ne" %4, %0 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

def test9_before := [llvm|
{
^0(%arg0 : i77):
  %0 = llvm.mlir.constant(562949953421310 : i77) : i77
  %1 = llvm.mlir.constant(1 : i77) : i77
  %2 = llvm.and %arg0, %0 : i77
  %3 = llvm.add %2, %1 : i77
  "llvm.return"(%3) : (i77) -> ()
}
]

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

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

IO in Init.System.IO

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

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

def sltu_i32_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := sltu_llvm_i64
  rhs := sltu_riscv_i64

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

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

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

def test7_before := [llvm|
{
^0(%arg93 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(4 : i32) : i32
  %2 = llvm.mul %arg93, %0 : i32
  %3 = llvm.srem %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

@[inline]
def CNFA.autMsbSet : CNFA 1 :=
  ⟨RawCNFA.autMsbSet, RawCNFA.autMsbSet_wf⟩

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

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

def Op.addAttr (o: Op φ) (k: String) (v: AttrValue φ): Op φ :=
 match o with
 | Op.mk name res args regions attrs =>
    Op.mk name res args regions (attrs.add (k, v))

def or_ugt_after := [llvm|
{
^0(%arg58 : i8, %arg59 : i8):
  %0 = llvm.or %arg58, %arg59 : i8
  %1 = llvm.icmp "ne" %0, %arg58 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

def slt_to_ult_before := [llvm|
{
^0(%arg36 : i8, %arg37 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.xor %arg36, %0 : i8
  %2 = llvm.xor %arg37, %0 : i8
  %3 = llvm.icmp "slt" %1, %2 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

Lattice in Mathlib.Order.Lattice

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

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 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 and_or3_before := [llvm|
{
^0(%arg168 : i1, %arg169 : i1, %arg170 : i32, %arg171 : i32):
  %0 = llvm.icmp "eq" %arg170, %arg171 : i32
  %1 = llvm.and %arg169, %0 : i1
  %2 = "llvm.select"(%1, %arg168, %arg169) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

inductive BBName
  | mk: String -> BBName
  deriving DecidableEq, Repr

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

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

def and_or1_wrong_operand_after := [llvm|
{
^0(%arg176 : i1, %arg177 : i1, %arg178 : i1, %arg179 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg176, %0 : i1
  %2 = llvm.or %arg178, %1 : i1
  %3 = "llvm.select"(%2, %arg179, %arg177) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

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

    |

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

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

Nat.zero in Init.Prelude

def a_after := [llvm|
{
^0(%arg48 : i1, %arg49 : i1):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.sext %arg49 : i1 to i32
  %3 = "llvm.select"(%arg48, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.add %3, %2 overflow<nsw> : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def sdiv_ult_smin_before := [llvm|
{
^0(%arg18 : i8, %arg19 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.sdiv %arg18, %arg19 : i8
  %2 = llvm.icmp "ult" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

def ripple_nsw3_before := [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 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

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

def nondeterminify (f : Stream α → Stream α) (x : StreamWithoutNones α) : Set (StreamWithoutNones α) :=
  
  
  
  { Quotient.mk _ (f y) | y ∈ StreamWithoutNones.hasStream x }

def eq_umax4_after := [llvm|
{
^0(%arg54 : i32, %arg55 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg54, %0 : i32
  %2 = llvm.icmp "uge" %1, %arg55 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

def select_icmp_ne_0_and_4096_or_4096_after := [llvm|
{
^0(%arg233 : i32, %arg234 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.and %arg233, %0 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.or %arg234, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

def test27_before := [llvm|
{
^0(%arg178 : i32, %arg179 : i32, %arg180 : i32):
  %0 = llvm.xor %arg180, %arg178 : i32
  %1 = llvm.xor %arg180, %arg179 : i32
  %2 = llvm.icmp "eq" %0, %1 : i32
  %3 = llvm.zext %2 : i1 to i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def test42_before := [llvm|
{
^0(%arg146 : i32):
  %0 = llvm.trunc %arg146 : i32 to i8
  %1 = llvm.zext %0 : i8 to i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def test13_before := [llvm|
{
^0(%arg40 : i1, %arg41 : i1):
  %0 = llvm.icmp "uge" %arg40, %arg41 : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

def a_or_b_const2_after := [llvm|
{
^0(%arg6 : i32, %arg7 : i32, %arg8 : i32, %arg9 : i32):
  %0 = llvm.icmp "eq" %arg6, %arg8 : i32
  %1 = llvm.icmp "eq" %arg7, %arg9 : i32
  %2 = llvm.xor %0, %1 : i1
  "llvm.return"(%2) : (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 test1 : DCOp.TokenStream :=
  SourceEg.denote (Ctxt.Valuation.nil) |>.getN 0

def scalar_after := [llvm|
{
^0(%arg43 : i4, %arg44 : i4, %arg45 : i4):
  %0 = llvm.xor %arg43, %arg44 : i4
  %1 = llvm.and %0, %arg45 : i4
  %2 = llvm.xor %1, %arg43 : i4
  "llvm.return"(%2) : (i4) -> ()
}
]

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

def test44_after := [llvm|
{
^0(%arg203 : i32, %arg204 : i32):
  %0 = llvm.and %arg203, %arg204 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

def icmp_slt_0_or_icmp_add_1_sge_100_i32_fail_before := [llvm|
{
^0(%arg38 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(100 : i32) : i32
  %2 = llvm.mlir.constant(31 : i32) : i32
  %3 = llvm.add %arg38, %0 : i32
  %4 = llvm.icmp "sge" %3, %1 : i32
  %5 = llvm.zext %4 : i1 to i32
  %6 = llvm.lshr %arg38, %2 : i32
  %7 = llvm.or %6, %5 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

def src_is_mask_shl_lshr_before := [llvm|
{
^0(%arg103 : i8, %arg104 : i8, %arg105 : i1):
  %0 = llvm.mlir.constant(123 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.xor %arg103, %0 : i8
  %4 = llvm.shl %1, %arg104 : i8
  %5 = llvm.lshr %4, %arg104 : i8
  %6 = llvm.xor %5, %1 : i8
  %7 = llvm.and %3, %6 : i8
  %8 = llvm.icmp "ne" %2, %7 : i8
  "llvm.return"(%8) : (i1) -> ()
}
]

def zext_ult_zext_after := [llvm|
{
^0(%arg159 : i1, %arg160 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mul %arg160, %arg160 : i8
  %2 = llvm.icmp "eq" %1, %0 : i8
  %3 = llvm.and %2, %arg159 : i1
  "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) -> ()
}
]

LE in Init.Prelude

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

@[simp, deprecated "Use `getElem?`" (since := "")]
def get? : Ctxt Ty → Nat → Option Ty := (·[·]?)

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

def parseExprs (lhsExpr rhsExpr : Expr) (width : Nat): ParseExprM (Option ParsedFpLogicalExpr)  := do
  let some lhsRes ← toBVExpr lhsExpr width | throwError "Could not extract lhs: {lhsExpr}"

  let state ← get
  let lhs: ParsedFpExpr := {bvExpr := lhsRes.bvExpr, width := lhsRes.width, symVars := state.symVarToVal, inputVars := state.inputVarIdToVariable}

  let some rhsRes ← toBVExpr rhsExpr width | throwError "Could not extract rhs: {rhsExpr}"
  let state ← get

  let rhsInputVars := state.inputVarIdToVariable.filter fun k _ => !lhs.inputVars.contains k
  let rhsSymVars := state.symVarToVal.filter fun k _ => !lhs.symVars.contains k

  let rhs: ParsedFpExpr := {bvExpr := rhsRes.bvExpr, width := rhsRes.width, symVars := rhsSymVars, inputVars := rhsInputVars}

  trace[Generalize] m! "lhs width: {lhsRes.width}; rhs width: {rhsRes.width}"
  if h : lhsRes.width = rhsRes.width then
    let rhsExpr := h ▸ rhsRes.bvExpr
    
    
    let bvLogicalExpr := BoolExpr.literal (FpPredicate.bin lhsRes.bvExpr FpBinaryPredKind.eq rhsExpr)
    trace[Generalize] m! "BVLogicalExpr: {bvLogicalExpr}"
    return some {lhs := lhs, rhs := rhs, state := state, logicalExpr := bvLogicalExpr}

  return none

inductive Op : Type _
  | comb (o : MLIR2Comb.Comb.Op)
  | hs (o : MLIR2Handshake.Handshake.Op)
  deriving Inhabited, DecidableEq, Repr, Lean.ToExpr

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

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

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

def test_and1_logical_before := [llvm|
{
^0(%arg50 : i32, %arg51 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.and %arg51, %0 : i32
  %4 = llvm.icmp "sge" %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 positive_biggerlshr_shlnsw_before := [llvm|
{
^0(%arg50 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.lshr %arg50, %0 : i8
  %3 = llvm.shl %2, %1 overflow<nsw> : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

structure KInductionCircuits {arity : Type _}
  [DecidableEq arity] [Fintype arity] [Hashable arity] (fsm : FSM arity) (n : Nat) where
  
  cInitCarryAssignCirc : Circuit (Vars fsm.α arity 0)
  
  cSuccCarryAssignCirc : Circuit (Vars fsm.α arity (n+2))
  
  cOutAssignCirc : Circuit (Vars fsm.α arity (n + 2))
  
  cStatesUniqueCirc : Circuit (Vars fsm.α arity n)

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

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

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 shl_add_before := [llvm|
{
^0(%arg26 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.shl %0, %arg26 : i32
  %3 = llvm.add %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

RV64.xor in RISCV.Instructions

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

Lean.Syntax.TSepArray in Init.Prelude

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

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 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 sle_and_min_commute_after := [llvm|
{
^0(%arg218 : i8, %arg219 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.icmp "eq" %arg218, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def shl_sub_lshr_before := [llvm|
{
^0(%arg139 : i32, %arg140 : i32, %arg141 : i32):
  %0 = llvm.shl %arg139, %arg140 overflow<nuw> : i32
  %1 = llvm.sub %0, %arg141 overflow<nsw,nuw> : i32
  %2 = llvm.lshr exact %1, %arg140 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def sub_select_sext_before := [llvm|
{
^0(%arg24 : i1, %arg25 : i64):
  %0 = llvm.mlir.constant(64) : i64
  %1 = "llvm.select"(%arg24, %0, %arg25) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  %2 = llvm.sext %arg24 : i1 to i64
  %3 = llvm.sub %1, %2 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

def slt_zero_eq_i1_fail_signed_before := [llvm|
{
^0(%arg0 : i32, %arg1 : i1):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.sext %arg1 : i1 to i32
  %2 = llvm.lshr %arg0, %0 : i32
  %3 = llvm.icmp "eq" %1, %2 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def n2_before := [llvm|
{
^0(%arg19 : i1, %arg20 : i8, %arg21 : i8, %arg22 : i8, %arg23 : i8):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.icmp "eq" %arg20, %arg21 : i8
  %2 = llvm.xor %arg19, %0 : i1
  %3 = llvm.and %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def udiv_common_divisor_after := [llvm|
{
^0(%arg65 : i1, %arg66 : i5, %arg67 : i5, %arg68 : i5):
  %0 = "llvm.select"(%arg65, %arg68, %arg67) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i5, i5) -> i5
  %1 = llvm.udiv %0, %arg66 : i5
  "llvm.return"(%1) : (i5) -> ()
}
]

def f1_logical_after := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(16711680 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.trunc %arg0 : i32 to i8
  %4 = llvm.icmp "ne" %3, %0 : i8
  %5 = llvm.and %arg0, %1 : i32
  %6 = llvm.icmp "ne" %5, %2 : i32
  %7 = llvm.and %4, %6 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

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

def t4_before := [llvm|
{
^0(%arg192 : i8, %arg193 : i1):
  %0 = llvm.mlir.constant(-42 : i8) : i8
  %1 = llvm.mlir.constant(44 : i8) : i8
  %2 = "llvm.select"(%arg193, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %3 = llvm.sub %arg192, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

unsafe def elabIntoCore {α : Type} (expectedType : Expr) (stx : Lean.Syntax) : CoreM α :=
  elabIntoMeta (α := α) expectedType stx |>.run'

structure Tensor2d' (α : Type) where
  dim₀ : Index
  dim₁ : Index
  mat : Matrix (Fin dim₀) (Fin dim₁) α

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

instance : HasUB PoisonOr where
  throwUB := .poison

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

private def tyi32NoGap : MLIRTy := [mlir_type| i32]

def select_icmp_eq_0_and_1_or_1_after := [llvm|
{
^0(%arg217 : i64, %arg218 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.trunc %arg217 : i64 to i32
  %2 = llvm.and %1, %0 : i32
  %3 = llvm.or %arg218, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

def xor_logic_and_or1_before := [llvm|
{
^0(%arg18 : i1, %arg19 : i1, %arg20 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.or %arg20, %arg18 : i1
  %2 = "llvm.select"(%arg18, %arg19, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = llvm.xor %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def register_wrapper
    (inputs : Stream' (Vector α m))
    
    (init_regs : Vector α nfeed)
    
    (update_fun : (Vector α m × Vector α nfeed) → (Vector α r × Vector α nfeed))
      : Stream' (Vector α r) :=
   
  let β := Stream' (Vector α m) × (Vector α nfeed) × Option (Vector α nfeed)
   
  let f : β → Vector α r :=
    fun (input_stream, current_regs_opt, init_regs) =>
       
      match init_regs with
      | some iv =>
                   
                  let (output, _) := update_fun (input_stream.head, iv)
                  output
      | _ =>   
              let (output, _) := update_fun (input_stream.head, current_regs_opt)
              output
   
  let g : β → β :=
    fun (input_stream, current_regs_opt, init_regs) =>
 
    match init_regs with
    | some iv =>
                 
                let (_, output_feedback) := update_fun (input_stream.head, iv)
                (input_stream.tail, output_feedback, none)
    | _ =>   
            let (_, output_feedback) := update_fun (input_stream.head, current_regs_opt)
            (input_stream.tail, output_feedback, none)
  Stream'.corec f g (inputs, init_regs, none)

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

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

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

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

def dec_mask_commute_neg_i32_before := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(-1 : i32) : i32
  %3 = llvm.sdiv %0, %arg6 : i32
  %4 = llvm.sub %1, %3 : i32
  %5 = llvm.and %3, %4 : i32
  %6 = llvm.add %5, %2 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def PR20945_before := [llvm|
{
^0(%arg132 : i32):
  %0 = llvm.mlir.constant(-9 : i32) : i32
  %1 = llvm.mlir.constant(-5 : i32) : i32
  %2 = llvm.ashr %0, %arg132 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def eval (assign : Std.HashMap Nat BVExpr.PackedBitVec) : GenBVExpr w → BitVec w
  | .var idx =>
    let packedBv := assign[idx]!
     
    if h : packedBv.w = w then
      h ▸ packedBv.bv
    else
      packedBv.bv.truncate w
  | .const val => val
  | .extract start len expr => BitVec.extractLsb' start len (eval assign expr)
  | .bin lhs op rhs => op.eval (eval assign lhs) (eval assign rhs)
  | .un op operand => op.eval (eval assign operand)
  | .append lhs rhs h => h ▸ ((eval assign lhs) ++ (eval assign rhs))
  | .replicate n expr h => h ▸ (BitVec.replicate n (eval assign expr))
  | .shiftLeft lhs rhs => (eval assign lhs) <<< (eval assign rhs)
  | .shiftRight lhs rhs => (eval assign lhs) >>> (eval assign rhs)
  | .arithShiftRight lhs rhs => BitVec.sshiftRight' (eval assign lhs) (eval assign rhs)
  | .signExtend n expr => BitVec.signExtend n (eval assign expr)
  | .zeroExtend n expr => BitVec.zeroExtend n (eval assign expr)
  | .truncate n expr => BitVec.truncate n (eval assign expr)

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

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

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

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

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

structure Item where
 name : String
 tac : Syntax

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

def n2_before := [llvm|
{
^0(%arg19 : i1, %arg20 : i8, %arg21 : i8, %arg22 : i8, %arg23 : i8):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.icmp "eq" %arg20, %arg21 : i8
  %2 = llvm.xor %arg19, %0 : i1
  %3 = llvm.and %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def src_is_mask_and_fail_mixed_after := [llvm|
{
^0(%arg119 : i8, %arg120 : i8, %arg121 : i8):
  %0 = llvm.mlir.constant(-8 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.mlir.constant(-124 : i8) : i8
  %3 = llvm.ashr %0, %arg120 : i8
  %4 = llvm.lshr %1, %arg121 : i8
  %5 = llvm.and %3, %4 : i8
  %6 = llvm.xor %arg119, %2 : i8
  %7 = llvm.or %5, %6 : i8
  %8 = llvm.icmp "eq" %7, %1 : i8
  "llvm.return"(%8) : (i1) -> ()
}
]

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 src3_after := [llvm|
{
^0(%arg8 : i32, %arg9 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg9, %arg8 : i32
  %2 = llvm.xor %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

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

def or_and3_commuted_after := [llvm|
{
^0(%arg100 : i1, %arg101 : i1, %arg102 : i32, %arg103 : i32):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "ne" %arg102, %arg103 : i32
  %3 = "llvm.select"(%2, %arg101, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = "llvm.select"(%arg100, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

String.Pos in Init.Data.String.Defs

private def mkNonTerminalParser (syntaxcat : Name)
    (ntparser : Syntax → EIO ParseError ParseOutput)
    (env : Environment) (s : String) : EIO ParseError ParseOutput :=
  let parseFun := mkParseFun syntaxcat ntparser
  parseFun s env

def multiuse_shl_shl_before := [llvm|
{
^0(%arg36 : i42):
  %0 = llvm.mlir.constant(8 : i42) : i42
  %1 = llvm.mlir.constant(9 : i42) : i42
  %2 = llvm.shl %arg36, %0 : i42
  %3 = llvm.shl %2, %1 : i42
  %4 = llvm.mul %2, %3 : i42
  "llvm.return"(%4) : (i42) -> ()
}
]

def or_and_xor_not_constant_commute1_before := [llvm|
{
^0(%arg166 : i9, %arg167 : i9):
  %0 = llvm.mlir.constant(42 : i9) : i9
  %1 = llvm.mlir.constant(-43 : i9) : i9
  %2 = llvm.xor %arg167, %arg166 : i9
  %3 = llvm.and %2, %0 : i9
  %4 = llvm.and %arg167, %1 : i9
  %5 = llvm.or %3, %4 : i9
  "llvm.return"(%5) : (i9) -> ()
}
]

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

def select_replace_udiv_non_speculatable_before := [llvm|
{
^0(%arg1 : i32, %arg2 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "eq" %arg1, %0 : i32
  %2 = llvm.udiv %arg2, %arg1 : i32
  %3 = "llvm.select"(%1, %2, %arg2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def select_icmp_sgt_allones_smin_flipped_before := [llvm|
{
^0(%arg2 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(-128 : i8) : i8
  %2 = llvm.icmp "sgt" %arg2, %0 : i8
  %3 = llvm.xor %arg2, %1 : i8
  %4 = "llvm.select"(%2, %3, %arg2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def alive_152_src  (w : Nat)   :=
[llvm( w )| {
^bb0(%x : _):
  %v1 = llvm.mlir.constant -1
  %v2 = llvm.mul %x, %v1
  llvm.return %v2
}]

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

def mul_constant_mismatch_wrap_eq_before := [llvm|
{
^0(%arg102 : i32, %arg103 : i32):
  %0 = llvm.mlir.constant(54 : i32) : i32
  %1 = llvm.mul %arg102, %0 overflow<nsw> : i32
  %2 = llvm.mul %arg103, %0 overflow<nuw> : i32
  %3 = llvm.icmp "eq" %1, %2 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def alive_InstCombineShift__497'''_src :=
[sllvm| {
^bb0(%X : i64, %C : i64, %C2 : i64):
  %v1 = llvm.add %X, %C2 : i64
  %v2 = llvm.shl %v1, %C : i64
  llvm.return %v2 : i64
}]

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

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

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

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

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

def test_add_nuw__none_are_safe_after := [llvm|
{
^0(%arg34 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.add %arg34, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

def genLogicalExprToExpr
  [HydrableInstances genPred]
  [H : HydrableGenPredToExpr parsedExpr genPred]
  (parsedExpr : ParsedLogicalExpr parsedExpr genPred) (logicalExpr : BoolExpr genPred) : MetaM Expr :=
  match logicalExpr with
  | .literal pred => H.genPredToExpr parsedExpr pred
  | .const b =>
      match b with
      | true => return (mkConst ``Bool.true)
      | _ => return (mkConst ``Bool.false)
  | .not boolExpr =>
    return mkApp (.const ``Bool.not []) (← genLogicalExprToExpr parsedExpr boolExpr)
  | .gate gate lhs rhs => do
      let lhs ← genLogicalExprToExpr parsedExpr lhs
      let rhs ← genLogicalExprToExpr parsedExpr rhs
      match gate with
      | .or => return mkApp2 (.const ``Bool.or []) lhs rhs
      | .xor => return mkApp2 (.const ``Bool.xor []) lhs rhs
      | .and => return mkApp2 (.const ``Bool.and []) lhs rhs
      | .beq =>
          mkAppM ``BEq.beq #[lhs, rhs]
  | _ => throwError m! "Unsupported operation {logicalExpr}"

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

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

def sge_swap_or_max_logical_after := [llvm|
{
^0(%arg180 : i8, %arg181 : i8):
  %0 = llvm.icmp "sle" %arg181, %arg180 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

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

def slt_or_not_max_commute_before := [llvm|
{
^0(%arg58 : i8, %arg59 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.icmp "slt" %arg58, %arg59 : i8
  %2 = llvm.icmp "ne" %arg58, %0 : i8
  %3 = llvm.or %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def or_and1_before := [llvm|
{
^0(%arg141 : i1, %arg142 : i1, %arg143 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg142, %0 : i1
  %2 = llvm.and %1, %arg143 : i1
  %3 = "llvm.select"(%2, %arg141, %arg142) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def EnvFin.getAll1 (n : Nat) : { envs : List (EnvFin 1 n) // ∀ (envFin : EnvFin 1 n), envFin ∈ envs } :=
  match hn : n with
  | 0 => ⟨[fun i => i.elim0], by admit /- proof elided -/
  ⟩
  | n' + 1 =>
     let ⟨envs, henvs⟩ := EnvFin.getAll1 n'
     let out := envs.flatMap (fun env => [env.cons (BitVec.ofBool false), env.cons (BitVec.ofBool true)])
     ⟨out, by admit /- proof elided -/
     ⟩

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 right_identity_one_mul : RISCVPeepholeRewrite [Ty.riscv (.bv)] where
  lhs := [LV| {
    ^entry (%x: !riscv.reg):
      %c = li (1) : !riscv.reg
      %0 = mul %c, %x : !riscv.reg
      ret %0 : !riscv.reg
  }]
  rhs := [LV| {
    ^entry (%x: !riscv.reg):
      ret %x : !riscv.reg
  }]

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 select_xor_icmp_bad_3_before := [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 %arg179, %arg181 : i32
  %3 = "llvm.select"(%1, %2, %arg180) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def llvm_ashr_lower_riscv_flag_8 : LLVMPeepholeRewriteRefine 8 [Ty.llvm (.bitvec 8), Ty.llvm (.bitvec 8)] where
  lhs := ashr_llvm_exact_flag_8
  rhs := ashr_riscv_8

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

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

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

def not_and_and_not_before := [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.xor %arg568, %1 : i32
  %4 = llvm.xor %arg569, %1 : i32
  %5 = llvm.and %2, %3 : i32
  %6 = llvm.and %5, %4 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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 test_const_shr_and_1_ne_0_after := [llvm|
{
^0(%arg8 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(42 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.shl %0, %arg8 overflow<nuw> : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.icmp "ne" %4, %2 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

def sdiv_pow2_16 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (16) : i64
      %0 = llvm.sdiv %x, %c : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %c0 = llvm.mlir.constant (63) : i64
      %c1 = llvm.mlir.constant (60) : i64
      %c2 = llvm.mlir.constant (4) : i64
      %0 = llvm.ashr %x, %c0 : i64
      %1 = llvm.lshr %0, %c1 : i64
      %2 = llvm.add %x, %1 : i64 
      %3 = llvm.ashr %2, %c2 : i64
      llvm.return %3 : i64
  }]

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

def DialectMorphism.preserves_sig (op : d.Op) :
    DialectSignature.sig (f.mapOp op) = (DialectSignature.sig op).map f.mapTy :=

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 irc_constants_AMinusC1MinusC2_neg2_2 : 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.sub %a, %c1 : i64
      %1 = llvm.sub %0, %c2 : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (-2) : i64
      %c2 = llvm.mlir.constant (2) : i64
      %0 = llvm.add %c1, %c2 : i64
      %1 = llvm.sub %a, %0 : i64
      llvm.return %1 : i64
  }]

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

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

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

def Predicate.Env.empty : Predicate.Env 0 :=
  fun v => v.elim0

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

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

def IsLawful_mkN {arity : Type _}
    [DecidableEq arity] [Fintype arity] [Hashable arity]
    (fsm : FSM arity) (n : Nat) :
    (mkN fsm n).IsLawful :=

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

def Tensor2D : Dialect where
  Op := Op
  Ty := Ty

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

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

def test2_before := [llvm|
{
^0(%arg0 : i23, %arg1 : i23, %arg2 : i23):
  %0 = llvm.and %arg1, %arg0 : i23
  %1 = llvm.or %arg1, %arg0 : i23
  %2 = llvm.xor %0, %1 : i23
  "llvm.return"(%2) : (i23) -> ()
}
]

instance : ToString Ty where
  toString t := repr t |>.pretty

def_signature for Comb where
  | .add w n => ${List.replicate n (Ty.bitvec w)} → (Ty.bitvec w)
  | .and w n => ${List.replicate n (Ty.bitvec w)} → (Ty.bitvec w)
  
  | .divs w => (Ty.bitvec w, Ty.bitvec w) → (Ty.bitvec w)
  | .divu w => (Ty.bitvec w, Ty.bitvec w) → (Ty.bitvec w)
  | .extract w n => (Ty.bitvec w) → (Ty.bitvec (w - n))
  | .icmp _ w => (Ty.bitvec w, Ty.bitvec w) → (Ty.bitvec 1)
  | .mods w => (Ty.bitvec w, Ty.bitvec w) → (Ty.bitvec w)
  | .modu w => (Ty.bitvec w, Ty.bitvec w) → (Ty.bitvec w)
  | .mul w n => ${List.replicate n (Ty.bitvec w)} → (Ty.bitvec w)
  | .mux w => (Ty.bitvec w, Ty.bitvec w, Ty.bitvec 1) → (Ty.bitvec w)
  | .or w n => ${List.replicate n (Ty.bitvec w)} → (Ty.bitvec w)
  | .parity w => (Ty.bitvec w) → (Ty.bitvec 1)
  | .replicate w n => (Ty.bitvec w) → (Ty.bitvec (w * n))
  | .shl w => (Ty.bitvec w, Ty.bitvec w) → (Ty.bitvec w)
  | .shlPar w _ => (Ty.bitvec w) → (Ty.bitvec w)
  | .shrs w => (Ty.bitvec w, Ty.bitvec w) → (Ty.bitvec w)
  | .shru w => (Ty.bitvec w, Ty.bitvec w) → (Ty.bitvec w)
  | .sub w => (Ty.bitvec w, Ty.bitvec w) → (Ty.bitvec w)
  | .xor w n => ${List.replicate n (Ty.bitvec w)} → (Ty.bitvec w)

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

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

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

def test_invert_demorgan_or3_before := [llvm|
{
^0(%arg13 : i32, %arg14 : i32):
  %0 = llvm.mlir.constant(178206 : i32) : i32
  %1 = llvm.mlir.constant(-195102 : i32) : i32
  %2 = llvm.mlir.constant(1506 : i32) : i32
  %3 = llvm.mlir.constant(-201547 : i32) : i32
  %4 = llvm.mlir.constant(716213 : i32) : i32
  %5 = llvm.mlir.constant(-918000 : i32) : i32
  %6 = llvm.mlir.constant(196112 : i32) : i32
  %7 = llvm.mlir.constant(true) : i1
  %8 = llvm.icmp "eq" %arg13, %0 : i32
  %9 = llvm.add %arg14, %1 : i32
  %10 = llvm.icmp "ult" %9, %2 : i32
  %11 = llvm.add %arg14, %3 : i32
  %12 = llvm.icmp "ult" %11, %4 : i32
  %13 = llvm.add %arg14, %5 : i32
  %14 = llvm.icmp "ult" %13, %6 : i32
  %15 = llvm.or %8, %10 : i1
  %16 = llvm.or %15, %12 : i1
  %17 = llvm.or %16, %14 : i1
  %18 = llvm.xor %17, %7 : i1
  "llvm.return"(%18) : (i1) -> ()
}
]

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

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

def div_bit_set_after := [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 overflow<nuw> : 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 bools2_logical_commute1_after := [llvm|
{
^0(%arg52 : i1, %arg53 : i1, %arg54 : i1):
  %0 = "llvm.select"(%arg54, %arg52, %arg53) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def narrow_zext_or_after := [llvm|
{
^0(%arg50 : i16, %arg51 : i32):
  %0 = llvm.trunc %arg51 : i32 to i16
  %1 = llvm.or %arg50, %0 : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

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

instance : TyDenote Ty where toType := Ty.toType

instance [HRefinement α α] [DecidableRel (· ⊑ · : α → α → _)] :
    DecidableRel (· ⊑ · : PoisonOr α → PoisonOr α → _)
  | .poison, _ => .isTrue <| by simp
  | .value _, .poison => .isFalse <| by simp
  | .value a, .value b => decidable_of_decidable_of_iff (p := a ⊑ b) <| by simp

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

structure HPredicateEnv {wcard tcard bcard ncard icard pcard : Nat}
    (fsmEnv : StateSpace wcard tcard bcard ncard icard pcard → BitStream)
    (penv : Fin pcard → Prop) : Prop where
    heq_width : ∀ (v : Fin pcard),
      fsmEnv (StateSpace.predVar v) = BitStream.ofProp (penv v)

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

abbrev ofTerm (t : Term) : FSM (Fin t.arity) := termEvalEqFSM t |>.toFSM

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

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

abbrev ReaderM  (d : Dialect) := ReaderT NameMapping (ExceptM d)

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

def and_or_not_not_commute7_after := [llvm|
{
^0(%arg354 : i32, %arg355 : i32, %arg356 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg356, %arg355 : i32
  %2 = llvm.and %1, %arg354 : i32
  %3 = llvm.xor %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

abbrev one    : BitStream := (· == 0)

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 logic_and_logic_or_2_before := [llvm|
{
^0(%arg174 : i1, %arg175 : i1, %arg176 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = "llvm.select"(%arg175, %arg174, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = "llvm.select"(%arg174, %arg176, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = "llvm.select"(%2, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

Valuation.mk in Mathlib.RingTheory.Valuation.Basic

Complement.complement in Init.Prelude

def test13_before := [llvm|
{
^0(%arg68 : i32, %arg69 : i32):
  %0 = llvm.mlir.constant(31 : i128) : i128
  %1 = llvm.sext %arg68 : i32 to i128
  %2 = llvm.zext %arg69 : i32 to i128
  %3 = llvm.and %2, %0 : i128
  %4 = llvm.ashr %1, %3 : i128
  %5 = llvm.trunc %4 : i128 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

def test1_after := [llvm|
{
^0(%arg232 : i32, %arg233 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg233, %0 : i32
  %2 = llvm.or %arg232, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def mul_splat_fold_too_narrow_before := [llvm|
{
^0(%arg77 : i2):
  %0 = llvm.mlir.constant(-2 : i2) : i2
  %1 = llvm.mlir.constant(1 : i2) : i2
  %2 = llvm.mul %arg77, %0 overflow<nuw> : i2
  %3 = llvm.lshr %2, %1 : i2
  "llvm.return"(%3) : (i2) -> ()
}
]

def test12_before := [llvm|
{
^0(%arg29 : i47):
  %0 = llvm.mlir.constant(8 : i47) : i47
  %1 = llvm.ashr %arg29, %0 : i47
  %2 = llvm.shl %1, %0 : i47
  "llvm.return"(%2) : (i47) -> ()
}
]

def sext_shl_trunc_same_size_before := [llvm|
{
^0(%arg13 : i16, %arg14 : i32):
  %0 = llvm.sext %arg13 : i16 to i32
  %1 = llvm.shl %0, %arg14 : i32
  %2 = llvm.trunc %1 : i32 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

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

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

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

instance : TyDenote (Ty q n) where
toType := fun
  | .index => Nat
  | .integer => Int
  | .tensor => List Int
  | .polynomialLike => (R q n)

def xor_or_xor_common_op_commute1_before := [llvm|
{
^0(%arg80 : i32, %arg81 : i32, %arg82 : i32):
  %0 = llvm.xor %arg80, %arg82 : i32
  %1 = llvm.or %arg80, %arg81 : i32
  %2 = llvm.xor %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def llvm_trunc_riscv_64_to_32_nuw_nsw : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 64)] :=
  {lhs:= trunc_llvm_64_to_32_nsw_nuw, rhs:= trunc_riscv_to_32_nsw_nuw}

def ashr_lshr_shift_amt_mismatch_before := [llvm|
{
^0(%arg72 : i32, %arg73 : i32, %arg74 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "sge" %arg72, %0 : i32
  %2 = llvm.lshr %arg72, %arg73 : i32
  %3 = llvm.ashr %arg72, %arg74 : i32
  %4 = "llvm.select"(%1, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

abbrev AttrVal (φ := 0) := AttrValue φ

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 lowbitmask_casted_shift_after := [llvm|
{
^0(%arg157 : i8):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.sext %arg157 : i8 to i32
  %2 = llvm.lshr %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def match_andAsRem_lshrAsDiv_shlAsMul_after := [llvm|
{
^0(%arg16 : i64):
  %0 = llvm.mlir.constant(576) : i64
  %1 = llvm.urem %arg16, %0 : i64
  "llvm.return"(%1) : (i64) -> ()
}
]

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

def urem_i32_multiuse_after := [llvm|
{
^0(%arg17 : i8, %arg18 : i8):
  %0 = llvm.zext %arg17 : i8 to i32
  %1 = llvm.zext %arg18 : i8 to i32
  %2 = llvm.urem %0, %1 : i32
  %3 = llvm.add %0, %1 overflow<nsw,nuw> : i32
  %4 = llvm.mul %2, %3 overflow<nsw,nuw> : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def t14_x_is_one_after := [llvm|
{
^0(%arg6 : i32, %arg7 : i32):
  %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) -> ()
}
]

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

def or_not_and_commute1_before := [llvm|
{
^0(%arg534 : i32, %arg535 : i32, %arg536 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg535 : i32
  %3 = llvm.or %arg534, %2 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.and %4, %arg536 : i32
  %6 = llvm.or %arg534, %arg536 : i32
  %7 = llvm.xor %6, %1 : i32
  %8 = llvm.and %2, %7 : i32
  %9 = llvm.or %5, %8 : i32
  "llvm.return"(%9) : (i32) -> ()
}
]

Sigma in Init.Core

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

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

def test53_after := [llvm|
{
^0(%arg131 : i32):
  %0 = llvm.mlir.constant(7224 : i16) : i16
  %1 = llvm.mlir.constant(-32574 : i16) : i16
  %2 = llvm.trunc %arg131 : i32 to i16
  %3 = llvm.and %2, %0 : i16
  %4 = llvm.or disjoint %3, %1 : i16
  %5 = llvm.zext %4 : i16 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

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

def RawCNFA.transBV (m : RawCNFA A) (s : m.states) (a : A) : BitVec m.stateMax :=
  let ts := m.trans.getD (s, a) ∅
  BitVec.ofFn (fun n => n ∈ ts)

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

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

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

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

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

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

@[simp] def ofBool (b : Bool) : Circuit α :=
  if b then tru else fals

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

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

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

def test6_after := [llvm|
{
^0(%arg1 : i77):
  "llvm.return"(%arg1) : (i77) -> ()
}
]

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

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

def test_sub_nuw_nsw__nuw_is_safe_after := [llvm|
{
^0(%arg27 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.mlir.constant(-2147483648 : i32) : i32
  %2 = llvm.and %arg27, %0 : i32
  %3 = llvm.sub %1, %2 overflow<nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def icmp_ult_8_before := [llvm|
{
^0(%arg12 : i64):
  %0 = llvm.mlir.constant(8) : i64
  %1 = llvm.mlir.constant(4095) : i64
  %2 = llvm.shl %arg12, %0 overflow<nuw> : i64
  %3 = llvm.icmp "ult" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def not_or_neg_before := [llvm|
{
^0(%arg79 : i8, %arg80 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.sub %0, %arg80 : i8
  %3 = llvm.or %2, %arg79 : i8
  %4 = llvm.xor %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

instance : Repr LLVM.Ty :=

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 icmp_power2_and_icmp_shifted_mask_swapped_1073741824_1073741823_before := [llvm|
{
^0(%arg38 : i32):
  %0 = llvm.mlir.constant(1073741824 : i32) : i32
  %1 = llvm.mlir.constant(1073741823 : i32) : i32
  %2 = llvm.icmp "ult" %arg38, %0 : i32
  %3 = llvm.and %arg38, %1 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  %5 = llvm.and %4, %2 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def sextinreg_after := [llvm|
{
^0(%arg14 : i32):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.shl %arg14, %0 : i32
  %2 = llvm.ashr exact %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

def test53_before := [llvm|
{
^0(%arg131 : i32):
  %0 = llvm.mlir.constant(-32574 : i16) : i16
  %1 = llvm.mlir.constant(-25350 : i16) : i16
  %2 = llvm.trunc %arg131 : i32 to i16
  %3 = llvm.or %2, %0 : i16
  %4 = llvm.and %3, %1 : i16
  %5 = llvm.zext %4 : i16 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

def Expr.mkTermFsmNondep (wcard tcard bcard ncard icard pcard : Nat) (pNondep : Expr) : SolverM Expr := do
  let out ← mkAppM (``mkTermFsmNondep) #[toExpr wcard, toExpr tcard, toExpr bcard, toExpr ncard, toExpr icard, toExpr pcard, pNondep]
  debugCheck out
  return out

def positive_trunc_base_before := [llvm|
{
^0(%arg39 : i32):
  %0 = llvm.mlir.constant(-1 : i16) : i16
  %1 = llvm.mlir.constant(128 : i16) : i16
  %2 = llvm.mlir.constant(256 : i16) : i16
  %3 = llvm.trunc %arg39 : i32 to i16
  %4 = llvm.icmp "sgt" %3, %0 : i16
  %5 = llvm.add %3, %1 : i16
  %6 = llvm.icmp "ult" %5, %2 : i16
  %7 = llvm.and %4, %6 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

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

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

def alive_InstCombineShift__279_tgt  (w : Nat)  :=
[llvm( w )| {
^bb0(%X : _, %C : _):
  %v1 = llvm.lshr %X, %C
  %v2 = llvm.mlir.constant -1
  %v3 = llvm.shl %v2, %C
  %v4 = llvm.and %X, %v3
  llvm.return %v4
}]

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

def VariadicValueStream (w : Nat) := CIRCTStream.Stream (List (BitVec w))

AList.keys in Mathlib.Data.List.AList

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

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

def repeatN (b : Bool) (n : Nat) : FSM Unit :=
  match n with
  | 0 => FSM.id
  | n' + 1 =>
    composeUnaryAux (FSM.ls b) (repeatN b n')

def CNFA.union_language (m₁ m₂ : CNFA n) :
    m₁.recognizes L₁ →
    m₂.recognizes L₂ →
    (m₁.union m₂).recognizes (L₁ ∪ L₂) :=

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

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

instance : HydrableInitialParserState where
  initialParserState := defaultParsedExprState

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

def cmpeq_bitwise_before := [llvm|
{
^0(%arg102 : i8, %arg103 : i8, %arg104 : i8, %arg105 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.xor %arg102, %arg103 : i8
  %2 = llvm.xor %arg104, %arg105 : i8
  %3 = llvm.or %1, %2 : i8
  %4 = llvm.icmp "eq" %3, %0 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

RV64.zexth in RISCV.Instructions

def cmpne_xor_cst1_before := [llvm|
{
^0(%arg20 : i32, %arg21 : i32):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.xor %arg20, %0 : i32
  %2 = llvm.icmp "ne" %1, %arg21 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

def fork (x : TokenStream) : TokenStream × TokenStream  :=
  Stream.corec₂ (β := TokenStream) x
    fun x => Id.run <| do
      (x 0, x 0, x.tail)

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

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

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

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

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

def shl_add_after := [llvm|
{
^0(%arg179 : i8, %arg180 : i8):
  %0 = llvm.mlir.constant(2 : i8) : i8
  %1 = llvm.mlir.constant(63 : i8) : i8
  %2 = llvm.lshr %arg180, %0 : i8
  %3 = llvm.add %2, %arg179 : i8
  %4 = llvm.and %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

def test54_after := [llvm|
{
^0(%arg130 : i64):
  %0 = llvm.mlir.constant(7224 : i16) : i16
  %1 = llvm.mlir.constant(-32574 : i16) : i16
  %2 = llvm.trunc %arg130 : i64 to i16
  %3 = llvm.and %2, %0 : i16
  %4 = llvm.or disjoint %3, %1 : i16
  %5 = llvm.sext %4 : i16 to i32
  "llvm.return"(%5) : (i32) -> ()
}
]

Int.emod in Init.Data.Int.DivMod.Basic

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

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

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

inductive TermKind (wcard : Nat) : Type
| bool
| bv (w : WidthExpr wcard)  : TermKind wcard
| prop
| nat
| int

@[simp_denote]
def srl_riscv_i32 :=
  [LV| {
    ^entry (%arg0: i32, %arg1: i32):
    %a = "builtin.unrealized_conversion_cast" (%arg0) : (i32) -> (!i64)
    %b = "builtin.unrealized_conversion_cast" (%arg1) : (i32) -> (!i64)
    %0 = srlw %a, %b : !i64
    %1 = "builtin.unrealized_conversion_cast" (%0) : (!i64) -> (i32)
    llvm.return %1 : i32
  }]

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

def test3_before := [llvm|
{
^0(%arg0 : i599, %arg1 : i1):
  %0 = llvm.mlir.constant(70368744177664 : i599) : i599
  %1 = llvm.mlir.constant(4096 : i599) : i599
  %2 = "llvm.select"(%arg1, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i599, i599) -> i599
  %3 = llvm.udiv %arg0, %2 : i599
  "llvm.return"(%3) : (i599) -> ()
}
]

def original_sdiv_srem := [LV| {
  ^entry (%a: i64, %b: i64):
    %0= llvm.sdiv exact %a, %b : i64
    %1 = llvm.srem %a, %b : i64
    llvm.return %1 : i64
  }]

def sub_const_const_sub_after := [llvm|
{
^0(%arg35 : i32):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.sub %0, %arg35 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

instance [DecidableEq d.Op] [DecidableEq d.Ty] : DecidableEq (Scf d).Op :=
  inferInstanceAs (DecidableEq <| Scf.Op ..)


example [DecidableEq d.Ty] : DecidableEq (Scf d).Ty := inferInstance

def ne_umax2_after := [llvm|
{
^0(%arg42 : i32, %arg43 : i32):
  %0 = llvm.icmp "ult" %arg42, %arg43 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

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

@[simp_denote]
def add32_sext_accept_riscv := [LV| {
  ^entry (%arg: i32):
  %0 = "builtin.unrealized_conversion_cast" (%arg) : (i32) -> (!i64)
  %1 = "addi" (%0) {imm = 2047 : !i64} : (!i64) -> (!i64)
  %2 = addiw %1, 952 : !i64
  %3 =  "builtin.unrealized_conversion_cast" (%2) : (!i64) -> (i32)
  llvm.return %3 : i32
}]

def iso_binary (a b : Stream' (BitVec 1)) : Stream' (Vector (BitVec 1) 2) :=
    fun n =>
      {toArray := [a n, b n].toArray, size_toArray := by admit /- proof elided -/

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

def Valuation.cast {Γ Δ : Ctxt Ty} (h : Γ = Δ) (V : Valuation Γ) : Valuation Δ :=
  fun _ v => V <| v.castCtxt h.symm

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

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

@[match_pattern] abbrev lshr (w : Nat) (flag : ExactFlag := {} ) : LLVM.Op := MOp.lshr (.concrete w) flag

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

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

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

def or_and_or_pat6_before := [llvm|
{
^0(%arg18 : i8, %arg19 : i8, %arg20 : i8, %arg21 : i8):
  %0 = llvm.and %arg18, %arg19 : i8
  %1 = llvm.and %arg21, %arg18 : i8
  %2 = llvm.or %1, %arg20 : i8
  %3 = llvm.or %0, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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 trunc_shl_ashr_var_after := [llvm|
{
^0(%arg31 : i64, %arg32 : i64):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.ashr %arg31, %arg32 : i64
  %2 = llvm.trunc %1 : i64 to i32
  %3 = llvm.shl %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def shl_sub_lshr_reverse_nsw_on_op1_after := [llvm|
{
^0(%arg130 : i32, %arg131 : i32, %arg132 : i32):
  %0 = llvm.lshr exact %arg132, %arg131 : i32
  %1 = llvm.sub %0, %arg130 overflow<nuw> : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

def not_bool_add_lshr_after := [llvm|
{
^0(%arg12 : i2, %arg13 : i2):
  %0 = llvm.mlir.constant(-1 : i2) : i2
  %1 = llvm.xor %arg12, %0 : i2
  %2 = llvm.icmp "ugt" %arg13, %1 : i2
  %3 = llvm.zext %2 : i1 to i4
  "llvm.return"(%3) : (i4) -> ()
}
]

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

abbrev mfixed : Nat := 3 

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 uaddo_commute8_before := [llvm|
{
^0(%arg10 : i32, %arg11 : i32, %arg12 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg11, %0 : i32
  %2 = llvm.add %arg11, %arg10 : i32
  %3 = llvm.icmp "ult" %1, %arg10 : i32
  %4 = "llvm.select"(%3, %2, %arg12) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

def icmp_ult_x_y_2_before := [llvm|
{
^0(%arg40 : i8, %arg41 : i8):
  %0 = llvm.mul %arg40, %arg40 : i8
  %1 = llvm.and %0, %arg41 : i8
  %2 = llvm.icmp "ugt" %0, %1 : i8
  "llvm.return"(%2) : (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 select_icmp_slt_zero_smin_after := [llvm|
{
^0(%arg7 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.or %arg7, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def no_shift_no_xor_multiuse_cmp_before := [llvm|
{
^0(%arg108 : i32, %arg109 : i32, %arg110 : i32, %arg111 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg108, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  %4 = llvm.or %arg109, %0 : i32
  %5 = "llvm.select"(%3, %arg109, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %6 = "llvm.select"(%3, %arg110, %arg111) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = llvm.mul %5, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

def simplify (p : FSM arity) : FSM arity := p

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

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

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

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

def zext_sext_add_icmp_slt_0_after := [llvm|
{
^0(%arg74 : i1, %arg75 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg74, %0 : i1
  %2 = llvm.and %arg75, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

def cmpne_xor_cst1_before := [llvm|
{
^0(%arg20 : i32, %arg21 : i32):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.xor %arg20, %0 : i32
  %2 = llvm.icmp "ne" %1, %arg21 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

def p_constmask_after := [llvm|
{
^0(%arg49 : i32, %arg50 : i32):
  %0 = llvm.mlir.constant(65280 : i32) : i32
  %1 = llvm.mlir.constant(-65281 : i32) : i32
  %2 = llvm.and %arg49, %0 : i32
  %3 = llvm.and %arg50, %1 : i32
  %4 = llvm.or disjoint %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def Term.toBV {wenv : WidthExpr.Env wcard}
    {tctx : Term.Ctx wcard tcard}
    (benv : Term.BoolEnv bcard)
    (nenv : Term.NatEnv ncard)
    (ienv : Term.IntEnv icard)
    (penv : Predicate.Env pcard)
    (tenv : tctx.Env wenv)
    (t : Term bcard ncard icard pcard tctx k) : k.denote wenv :=
match t with
| .ofNat w n => BitVec.ofNat (w.toNat wenv) n
| .boolConst b => b
| .var v => tenv.get v.1 v.2
| .add (w := w) a b =>
    let a : BitVec (w.toNat wenv) := (a.toBV benv nenv ienv penv tenv)
    let b : BitVec (w.toNat wenv) := (b.toBV benv nenv ienv penv tenv)
    a + b
| .zext a v => (a.toBV benv nenv ienv penv tenv).zeroExtend (v.toNat wenv)
| .setWidth a v => (a.toBV benv nenv ienv penv tenv).zeroExtend (v.toNat wenv)
| .sext a v => (a.toBV benv nenv ienv penv tenv).signExtend (v.toNat wenv)
| .bor a b (w := w) =>
    let a : BitVec (w.toNat wenv) := (a.toBV benv nenv ienv penv tenv)
    let b : BitVec (w.toNat wenv) := (b.toBV benv nenv ienv penv tenv)
    a ||| b
| .band (w := w) a b =>
    let a : BitVec (w.toNat wenv) := (a.toBV benv nenv ienv penv tenv)
    let b : BitVec (w.toNat wenv) := (b.toBV benv nenv ienv penv tenv)
    a &&& b
| .bxor (w := w) a b =>
    let a : BitVec (w.toNat wenv) := (a.toBV benv nenv ienv penv tenv)
    let b : BitVec (w.toNat wenv) := (b.toBV benv nenv ienv penv tenv)
    a ^^^ b
| .bnot (w := w) a =>
    let a : BitVec (w.toNat wenv) := (a.toBV benv nenv ienv penv tenv)
    ~~~ a
| .boolVar v => benv v
| .shiftl (w := w) a k =>
    let a : BitVec (w.toNat wenv) := (a.toBV benv nenv ienv penv tenv)
    a <<< k
| .bvOfBool b => BitVec.ofBool (b.toBV benv nenv ienv penv tenv)

| .binWidthRel rel wa wb =>
  match rel with
  | .eq => wa.toNat wenv = wb.toNat wenv
  | .le => wa.toNat wenv ≤ wb.toNat wenv
| .binRel rel _w a b =>
  match rel with
  | .eq => a.toBV benv nenv ienv penv tenv = b.toBV benv nenv ienv penv tenv
  | .ne => a.toBV benv nenv ienv penv tenv ≠ b.toBV benv nenv ienv penv tenv
  | .ult => (a.toBV benv nenv ienv penv tenv).ult (b.toBV benv nenv ienv penv tenv) = true
  | .ule => (a.toBV benv nenv ienv penv tenv).ule (b.toBV benv nenv ienv penv tenv) = true
  | .slt => (a.toBV benv nenv ienv penv tenv).slt (b.toBV benv nenv ienv penv tenv) = true
  | .sle => (a.toBV benv nenv ienv penv tenv).sle (b.toBV benv nenv ienv penv tenv) = true
| .and p1 p2 => p1.toBV benv nenv ienv penv tenv  ∧ p2.toBV benv nenv ienv penv tenv
| .or p1 p2 => p1.toBV benv nenv ienv penv tenv ∨ p2.toBV benv nenv ienv penv tenv
| .boolBinRel rel a b =>
  match rel with
  
  | .eq => (a.toBV benv nenv ienv penv tenv) = (b.toBV benv nenv ienv penv tenv)
| .pvar v => penv v

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

def not_ashr_const_before := [llvm|
{
^0(%arg138 : i8):
  %0 = llvm.mlir.constant(-42 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.ashr %0, %arg138 : i8
  %3 = llvm.xor %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

def commute_int_constant_to_rhs_mulhu: RISCVPeepholeRewrite [Ty.riscv (.bv)] where
  lhs := [LV| {
    ^entry (%x: !riscv.reg):
      %c = li (1) : !riscv.reg
      %0 = mulhu %c, %x : !riscv.reg
      ret %0 : !riscv.reg
  }]
  rhs := [LV| {
    ^entry (%x: !riscv.reg):
      %c = li (1) : !riscv.reg
      %0 = mulhu %x, %c : !riscv.reg
      ret %0 : !riscv.reg
  }]

def lshr_and_or_disjoint_before := [llvm|
{
^0(%arg43 : i8, %arg44 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.mlir.constant(13 : i8) : i8
  %3 = llvm.srem %arg43, %0 : i8
  %4 = llvm.lshr %arg44, %1 : i8
  %5 = llvm.and %4, %2 : i8
  %6 = llvm.or disjoint %3, %5 : i8
  %7 = llvm.shl %6, %1 : i8
  "llvm.return"(%7) : (i8) -> ()
}
]

def Com.ret {Γ : Ctxt d.Ty} {ty : d.Ty} {eff : EffectKind} : Γ.Var ty → Com d Γ eff [ty] :=
  (Com.rets [·]ₕ)

def land_bor_right2_after := [llvm|
{
^0(%arg36 : i1, %arg37 : i1):
  "llvm.return"(%arg36) : (i1) -> ()
}
]

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

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

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

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

List.foldr in Init.Data.List.Basic

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

def NFA.msbLang : Language (BitVec 1) := { bvs  | bvs.getLast? = some 1 }

def test0_before := [llvm|
{
^0(%arg123 : i32):
  %0 = llvm.mlir.constant(-2147483648 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.xor %arg123, %0 : i32
  %3 = llvm.icmp "sgt" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def test1_after := [llvm|
{
^0(%arg19 : i32, %arg20 : i8):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.zext nneg %arg20 : i8 to i32
  %2 = llvm.lshr %arg19, %1 : i32
  %3 = llvm.and %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def logical_and_logical_and_icmps_comm2_before := [llvm|
{
^0(%arg202 : i8, %arg203 : i8, %arg204 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.mlir.constant(false) : i1
  %4 = llvm.icmp "eq" %arg203, %0 : i8
  %5 = llvm.and %arg202, %1 : i8
  %6 = llvm.shl %1, %arg204 : i8
  %7 = llvm.and %arg202, %6 : i8
  %8 = llvm.icmp "ne" %5, %2 : i8
  %9 = llvm.icmp "ne" %7, %2 : i8
  %10 = "llvm.select"(%8, %4, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %11 = "llvm.select"(%10, %9, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%11) : (i1) -> ()
}
]

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

@[simp_denote]
def llvm_urem: Com  LLVMPlusRiscV ⟨[.llvm (.bitvec 64), .llvm (.bitvec 64)]⟩
  .pure (.llvm (.bitvec 64)) := [LV| {
  ^entry (%x: i64, %y: i64 ):
    %1 = llvm.urem    %x, %y : i64
    llvm.return %1 : i64
  }]

def liftTy : MLIR2Comb.Ty → MLIR2Handshake.Ty
| .bitvec w => .stream (.bitvec w)

def alive_InstCombineShift__279_tgt :=
[sllvm| {
^bb0(%X : i64, %C : i64):
  %v1 = llvm.lshr %X, %C : i64
  %v2 = llvm.mlir.constant -1 : i64
  %v3 = llvm.shl %v2, %C : i64
  %v4 = llvm.and %X, %v3 : i64
  llvm.return %v4 : i64
}]

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

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

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

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

def eq_21_logical_before := [llvm|
{
^0(%arg104 : i32, %arg105 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.lshr %arg104, %0 : i32
  %4 = llvm.trunc %3 : i32 to i8
  %5 = llvm.lshr %arg104, %1 : i32
  %6 = llvm.trunc %5 : i32 to i8
  %7 = llvm.lshr %arg105, %0 : i32
  %8 = llvm.trunc %7 : i32 to i8
  %9 = llvm.lshr %arg105, %1 : i32
  %10 = llvm.trunc %9 : i32 to i8
  %11 = llvm.icmp "eq" %4, %8 : i8
  %12 = llvm.icmp "eq" %6, %10 : i8
  %13 = "llvm.select"(%12, %11, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%13) : (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 positive_samevar_shlnsw_before := [llvm|
{
^0(%arg52 : i8, %arg53 : i8):
  %0 = llvm.lshr %arg52, %arg53 : i8
  %1 = llvm.shl %0, %arg53 overflow<nsw> : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

def and_not_or_commute2_after := [llvm|
{
^0(%arg475 : i32, %arg476 : i32, %arg477 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg476 : i32
  %3 = llvm.xor %arg477, %2 : i32
  %4 = llvm.and %3, %arg475 : i32
  %5 = llvm.xor %4, %1 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def p2_scalar_shifted_urem_by_const_after := [llvm|
{
^0(%arg16 : i32, %arg17 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(3 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.and %arg16, %0 : i32
  %4 = llvm.shl %3, %arg17 overflow<nuw> : i32
  %5 = llvm.urem %4, %1 : i32
  %6 = llvm.icmp "eq" %5, %2 : i32
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

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

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

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

def not_and_and_or_not_or_or_commute3_before := [llvm|
{
^0(%arg232 : i32, %arg233 : i32, %arg234 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg233 : i32
  %3 = llvm.or %2, %arg232 : i32
  %4 = llvm.or %3, %arg234 : i32
  %5 = llvm.xor %4, %1 : i32
  %6 = llvm.xor %arg232, %1 : i32
  %7 = llvm.and %2, %6 : i32
  %8 = llvm.and %7, %arg234 : i32
  %9 = llvm.or %8, %5 : i32
  "llvm.return"(%9) : (i32) -> ()
}
]

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

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

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

Std.Tactic.BVDecide.BVUnOp.rotateLeft in Std.Tactic.BVDecide.Bitblast.BVExpr.Basic

def CNFA.autWidth (wp : WidthPredicate) (n : Nat) : CNFA 0 :=
  ⟨RawCNFA.autWidth wp n, RawCNFA.autWidth_wf⟩

def canonicalize_logic_first_xor_0_nsw_before := [llvm|
{
^0(%arg16 : i8):
  %0 = llvm.mlir.constant(96 : i8) : i8
  %1 = llvm.mlir.constant(31 : i8) : i8
  %2 = llvm.add %arg16, %0 overflow<nsw> : i8
  %3 = llvm.xor %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

def urem? {w : Nat} (x y : BitVec w) : IntW w :=
  if y = 0 then
    .poison
  else
    .value <| x % y

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

def shl_mask_weird_type_after := [llvm|
{
^0(%arg4 : i37):
  %0 = llvm.mlir.constant(255 : i37) : i37
  %1 = llvm.mlir.constant(8 : i37) : i37
  %2 = llvm.and %arg4, %0 : i37
  %3 = llvm.shl %2, %1 overflow<nsw,nuw> : i37
  %4 = llvm.or disjoint %2, %3 : i37
  "llvm.return"(%4) : (i37) -> ()
}
]

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

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

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

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

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

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

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

def test91_before := [llvm|
{
^0(%arg49 : i64):
  %0 = llvm.mlir.constant(48 : i96) : i96
  %1 = llvm.sext %arg49 : i64 to i96
  %2 = llvm.lshr %1, %0 : i96
  %3 = llvm.trunc %2 : i96 to i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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

def test11_before := [llvm|
{
^0(%arg89 : i32):
  %0 = llvm.mlir.constant(-2 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.mlir.constant(4 : i32) : i32
  %3 = llvm.and %arg89, %0 : i32
  %4 = llvm.mul %3, %1 : i32
  %5 = llvm.urem %4, %2 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

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

def add_multiuse_riscv_i64_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := add_multiuse_llvm_i64
  rhs :=  add_multiuse_riscv_i64

def negate_zext_after := [llvm|
{
^0(%arg96 : i8, %arg97 : i1):
  %0 = llvm.sext %arg97 : i1 to i8
  %1 = llvm.add %arg96, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

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

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

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

def bools_logical_commute3_and2_after := [llvm|
{
^0(%arg69 : i1, %arg70 : i1, %arg71 : i1):
  %0 = "llvm.select"(%arg71, %arg70, %arg69) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

def mul16_low_before := [llvm|
{
^0(%arg24 : i16, %arg25 : i16):
  %0 = llvm.mlir.constant(255 : i16) : i16
  %1 = llvm.mlir.constant(8 : i16) : i16
  %2 = llvm.and %arg24, %0 : i16
  %3 = llvm.lshr %arg24, %1 : i16
  %4 = llvm.and %arg25, %0 : i16
  %5 = llvm.lshr %arg25, %1 : i16
  %6 = llvm.mul %5, %2 : i16
  %7 = llvm.mul %4, %3 : i16
  %8 = llvm.mul %4, %2 : i16
  %9 = llvm.add %6, %7 : i16
  %10 = llvm.shl %9, %1 : i16
  %11 = llvm.add %10, %8 : i16
  "llvm.return"(%11) : (i16) -> ()
}
]

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

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

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

def srli_i32_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := srli_llvm_i32
  rhs := srli_riscv_i32

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

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

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 or_logic_or_logic_and_3_after := [llvm|
{
^0(%arg42 : i1, %arg43 : i1, %arg44 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = "llvm.select"(%arg44, %arg43, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = "llvm.select"(%arg42, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def runMainCmd (args : Cli.Parsed) : IO UInt32 := do
  let fileName := args.positionalArg! "file" |>.as! String
  if args.hasFlag "verbose" then 
    let code ← verbose_flag fileName
    return code
  if args.hasFlag "riscv" then 
    let code ←  parseAsRiscv fileName
    return code
  if args.hasFlag "passriscv64" then 
    let code ← passriscv64 fileName
    return code
  if args.hasFlag "passriscv64_optimized" then 
    let code ← passriscv64_optimized fileName
    return code
  if args.hasFlag "passriscv64_optimized_const" then 
    let code ← passriscv64_optimized fileName
    return code
  if args.hasFlag "passriscv64_selectiondag" then 
    let code ← passriscv64_selectiondag fileName
    return code
  else
    let code ← wellformed fileName
    return code

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

def t9_after := [llvm|
{
^0(%arg192 : i8, %arg193 : i8):
  %0 = llvm.sub %arg192, %arg193 : i8
  "llvm.return"(%0) : (i8) -> ()
}
]

instance : DecidableEq (Var Γ t) :=

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

Lean.Syntax.mkNumLit in Init.Meta.Defs

def doBvGeneralize (g : MVarId) : GenM (Expr × MVarId) := do
  let lctx ← getLCtx
  let mut allFVars := #[]
  for h in lctx do
    if not h.isImplementationDetail then
      allFVars := allFVars.push h.fvarId
  let (_, g) ← g.revert allFVars
  let e ← visit (← g.getType)
  let mut newVars := #[]
  for x in (←get).mapping.elements do
    newVars := newVars.push x

  let e ← mkForallFVars newVars e (binderInfoForMVars := .default)
  let e ← instantiateMVars e
  pure (e, g)

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

def negative_trunc_not_arg_logical_before := [llvm|
{
^0(%arg20 : i32, %arg21 : i32):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(128 : i32) : i32
  %2 = llvm.mlir.constant(256 : i32) : i32
  %3 = llvm.mlir.constant(false) : i1
  %4 = llvm.trunc %arg20 : i32 to i8
  %5 = llvm.icmp "sgt" %4, %0 : i8
  %6 = llvm.add %arg21, %1 : i32
  %7 = llvm.icmp "ult" %6, %2 : i32
  %8 = "llvm.select"(%5, %7, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%8) : (i1) -> ()
}
]

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

@[simp_llvm]
def ashr? {n} (op1 : BitVec n) (op2 : BitVec n) : IntW n :=
  if op2 >= n
  then .poison
  else .value (op1.sshiftRight' op2)

def add_umax_simplify_after := [llvm|
{
^0(%arg45 : i37):
  %0 = llvm.mlir.constant(42 : i37) : i37
  %1 = llvm.add %arg45, %0 overflow<nuw> : i37
  "llvm.return"(%1) : (i37) -> ()
}
]

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

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

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

Finset.range in Mathlib.Data.Finset.Range

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

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

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

def different_size_zext_zext_sgt_after := [llvm|
{
^0(%arg16 : i7, %arg17 : i4):
  %0 = llvm.zext %arg17 : i4 to i7
  %1 = llvm.icmp "ugt" %arg16, %0 : i7
  "llvm.return"(%1) : (i1) -> ()
}
]

def rgn {Γ : Ctxt _} (k : Nat) (input : Var Γ .nat) (body : Com [ExTy.nat] ExTy.nat) :
    Expr Γ .nat :=
  Expr.mk
    (op := .runK k)
    (ty_eq := rfl)
    (eff_le := EffectKind.pure_le _)
    (args := .cons input .nil)
    (regArgs := HVector.cons (body.castPureToEff _) HVector.nil)

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

def twoway_clamp_lt_after := [llvm|
{
^0(%arg15 : i32):
  %0 = llvm.mlir.constant(13767 : i32) : i32
  %1 = llvm.mlir.constant(13768 : i32) : i32
  %2 = llvm.icmp "sgt" %arg15, %0 : i32
  %3 = "llvm.select"(%2, %1, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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 icmp_mul_nsw_sgt_before := [llvm|
{
^0(%arg15 : i8, %arg16 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mul %arg15, %0 overflow<nsw> : i8
  %2 = llvm.mul %arg16, %0 overflow<nsw> : i8
  %3 = llvm.icmp "sgt" %1, %2 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def udiv_lshr_mul_nuw_before := [llvm|
{
^0(%arg106 : i8, %arg107 : i8, %arg108 : i8):
  %0 = llvm.mul %arg106, %arg107 overflow<nuw> : i8
  %1 = llvm.lshr %0, %arg108 : i8
  %2 = llvm.udiv %1, %arg106 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

LT.lt in Init.Prelude

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

@[simp_denote]
def sext_riscv_i1_to_32 := [LV| {
  ^entry (%arg: i1):
    %0 = "builtin.unrealized_conversion_cast"(%arg) : (i1) -> (!i64)
    %1 = slli %0, 63 : !i64
    %2 = srai %1, 63 : !i64
    %res = "builtin.unrealized_conversion_cast"(%2) : (!i64) -> (i32)
    llvm.return %res : i32
  }]

def sub_ashr_and_i32_nuw_nsw_before := [llvm|
{
^0(%arg23 : i32, %arg24 : i32):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.sub %arg24, %arg23 overflow<nsw,nuw> : i32
  %2 = llvm.ashr %1, %0 : i32
  %3 = llvm.and %2, %arg23 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def scalar_i8_shl_ugt_const_before := [llvm|
{
^0(%arg11 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.mlir.constant(63 : i8) : i8
  %2 = llvm.shl %arg11, %0 : i8
  %3 = llvm.icmp "ugt" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

def llvm_const_lower_riscv_li34 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM34, rhs:= liRiscv34,
   correct := by admit /- proof elided -/

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 and_orn_xor_commute8_after := [llvm|
{
^0(%arg66 : i32, %arg67 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mul %arg66, %arg66 : i32
  %2 = llvm.mul %arg67, %arg67 : i32
  %3 = llvm.xor %1, %0 : i32
  %4 = llvm.and %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def lowmask_add_zext_after := [llvm|
{
^0(%arg235 : i8, %arg236 : i32):
  %0 = llvm.trunc %arg236 : i32 to i8
  %1 = llvm.add %arg235, %0 : i8
  %2 = llvm.zext %1 : i8 to i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def icmp_eq_select_after := [llvm|
{
^0(%arg3 : i1, %arg4 : i32, %arg5 : i32):
  %0 = llvm.icmp "eq" %arg4, %arg5 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

def test25_before := [llvm|
{
^0(%arg2 : i37, %arg3 : i37):
  %0 = llvm.mlir.constant(17 : i37) : i37
  %1 = llvm.lshr %arg3, %0 : i37
  %2 = llvm.lshr %arg2, %0 : i37
  %3 = llvm.add %2, %1 : i37
  %4 = llvm.shl %3, %0 : i37
  "llvm.return"(%4) : (i37) -> ()
}
]

def mul130_low_after := [llvm|
{
^0(%arg12 : i130, %arg13 : i130):
  %0 = llvm.mul %arg12, %arg13 : i130
  "llvm.return"(%0) : (i130) -> ()
}
]

@[simp_denote]
def xor_riscv_64: Com  LLVMPlusRiscV ⟨[.llvm (.bitvec 64), .llvm (.bitvec 64)]⟩
  .pure (.llvm (.bitvec 64)) := [LV| {
  ^entry (%x: i64, %y: i64):
    %x1 = "builtin.unrealized_conversion_cast"(%x) : (i64) -> (!i64)
    %x2 = "builtin.unrealized_conversion_cast"(%y) : (i64) -> (!i64)
    %1 = xor %x1, %x2 : !i64
    %2 = "builtin.unrealized_conversion_cast"(%1) : (!i64) -> (i64)
    llvm.return %2 : i64
  }]

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

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

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

def sub_undemanded_low_bits_before := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(1616 : i32) : i32
  %2 = llvm.mlir.constant(4 : i32) : i32
  %3 = llvm.or %arg0, %0 : i32
  %4 = llvm.sub %3, %1 : i32
  %5 = llvm.lshr %4, %2 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def add_shl_same_amount_before := [llvm|
{
^0(%arg59 : i6, %arg60 : i6, %arg61 : i6):
  %0 = llvm.shl %arg59, %arg61 : i6
  %1 = llvm.shl %arg60, %arg61 : i6
  %2 = llvm.add %0, %1 : i6
  "llvm.return"(%2) : (i6) -> ()
}
]

def add_mask_ashr28_i32_after := [llvm|
{
^0(%arg2 : i32):
  %0 = llvm.mlir.constant(28 : i32) : i32
  %1 = llvm.mlir.constant(7 : i32) : i32
  %2 = llvm.lshr %arg2, %0 : i32
  %3 = llvm.and %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

@[simp]
abbrev envOfList {w} (a : List (BitVec w)) : Nat → BitVec w := fun n => a.getD n 0

def t0_exact_after := [llvm|
{
^0(%arg9 : i64):
  %0 = llvm.mlir.constant(63) : i64
  %1 = llvm.ashr exact %arg9, %0 : i64
  "llvm.return"(%1) : (i64) -> ()
}
]

instance : Refinement (BitVec w) := .ofEq

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

@[elab_as_elim, induction_eliminator]
def Lets.recOn {Γ_out} {motive : ∀ {Γ_in}, Lets Op Γ_in Γ_out → Sort u}
    (nil : motive Lets.nil)
    (lete : ∀ {Γ_in ty} (e : Expr Op Γ_in ty) (lets : Lets Op _ Γ_out), motive (Lets.lete e lets)) :
    ∀ {Γ_in} (lets : Lets Op Γ_in Γ_out), motive lets
  | Γ_in, ⟨⟨[]⟩, (h   )⟩ => by admit /- proof elided -/
  | Γ_in, ⟨⟨e :: lets⟩, h⟩ =>
      have h := by admit /- proof elided -/

def or_eq_with_one_bit_diff_constants2_after := [llvm|
{
^0(%arg362 : i32):
  %0 = llvm.mlir.constant(-33 : i32) : i32
  %1 = llvm.mlir.constant(65 : i32) : i32
  %2 = llvm.and %arg362, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  "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 State.setMapping (e x : Expr) : GenM Unit := do
  let s ← get
  let m ← s.mapping.insert e x
  set {s with mapping := m}

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

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

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

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

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

def n2_before := [llvm|
{
^0(%arg19 : i1, %arg20 : i8, %arg21 : i8, %arg22 : i8, %arg23 : i8):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.icmp "eq" %arg20, %arg21 : i8
  %2 = llvm.xor %arg19, %0 : i1
  %3 = llvm.or %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def not_cmp_constant_before := [llvm|
{
^0(%arg144 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(42 : i32) : i32
  %2 = llvm.xor %arg144, %0 : i32
  %3 = llvm.icmp "ugt" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def x : DCOp.ValueStream Int := ofList [some 1, none, some 2, some 5, none]

Fin.elim0 in Init.Data.Fin.Basic

def positive_biggerashr_shlnsw_ashrexact_after := [llvm|
{
^0(%arg35 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.ashr exact %arg35, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]
</all_available_defs>

<all_available_lemmas>
...

theorem carryWith_congrEnv {p : FSM arity}
    {carryState : p.α → Bool} {x y : arity → BitStream} {n : Nat}
    (h : ∀ a i, i < n → x a i = y a i) :
    p.carryWith carryState x n = p.carryWith carryState y n

theorem carry_congrEnv {p : FSM arity}
    {x y : arity → BitStream} {n : Nat} (h : ∀ a i, i < n → x a i = y a i) :
    p.carry x n = p.carry y n

theorem add_nsw_const_const_sub_nsw_ov_thm (e : IntW 8) :
  sub (const? 8 (-127)) (add e (const? 8 2) { «nsw» := true, «nuw» := false }) { «nsw» := true, «nuw» := false } ⊑
    sub (const? 8 127) e

theorem lshrugt_02_05_exact_thm (e : IntW 4) :
  icmp IntPred.ugt (lshr e (const? 4 2) { «exact» := true }) (const? 4 5) ⊑ const? 1 0

theorem scalar_i32_lshr_and_negC_slt_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬x ≥ ↑32 → ofBool (x_1 >>> x &&& BitVec.ofInt 32 (-8) <ₛ 0#32) = ofBool (x_1 >>> x <ₛ 0#32)

theorem test_lshr_exact__exact_is_safe_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 lshrult_01_15_proof : lshrult_01_15_before ⊑ lshrult_01_15_after

theorem eq_smax2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x <ₛ x_1) = 1#1 → ofBool (x == x) = ofBool (x_1 ≤ₛ x)

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 32), True ∧ (x &&& 32#32 &&& 8#32 != 0) = true → False

@[simp] theorem Lets.denote_nil {Γ : Ctxt d.Ty} :
    (Lets.nil : Lets d Γ eff Γ).denote = (return ·)

theorem select_xor_icmp2_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.ne e_2 (const? 32 0)) e_1 (LLVM.xor e_2 e) ⊑
    select (icmp IntPred.eq e_2 (const? 32 0)) e e_1

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 alive_AndOrXor_2265 : alive_AndOrXor_2265_src ⊑ alive_AndOrXor_2265_tgt

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

theorem e_1019 :
     - 2 *  ~~~(z ^^^ t) - 2 * (z ||| t) - 11 * z - 7 * (z ^^^ t) + 7 *  ~~~(z ||| t) + 9 *  ~~~(z |||  ~~~t) + 25 * (z &&&  ~~~t) = 5 * (z |||  ~~~t) - 20 * (z &&& t)

theorem ne_umax3_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (add e_1 (const? 32 3))
      (select (icmp IntPred.ugt (add e_1 (const? 32 3)) e) (add e_1 (const? 32 3)) e) ⊑
    icmp IntPred.ult (add e_1 (const? 32 3)) e

theorem bswap_and_mask_1_thm (e : IntW 64) :
  LLVM.or (LLVM.and (lshr e (const? 64 40)) (const? 64 65280)) (lshr e (const? 64 56)) ⊑
    LLVM.or (LLVM.and (lshr e (const? 64 40)) (const? 64 65280)) (lshr e (const? 64 56)) { «disjoint» := true }

theorem src_x_and_nmask_eq_proof : src_x_and_nmask_eq_before ⊑ src_x_and_nmask_eq_after

theorem bools2_logical_commute1_and1_proof : bools2_logical_commute1_and1_before ⊑ bools2_logical_commute1_and1_after

theorem p0_thm (e e_1 : IntW 8) :
  icmp IntPred.ugt (shl (const? 8 1) e_1) e ⊑ icmp IntPred.eq (lshr e e_1) (const? 8 0)

theorem ult_x_impliesT_eq_umax_todo_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 8),
  ofBool (x_1 <ᵤ x_2) = 1#1 → ofBool (-1#8 != x_1) = 1#1

theorem main4b_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 == 7#32) &&& ofBool (x &&& 16#32 != 0#32) = 1#1 →
    1#32 = zeroExtend 32 (ofBool (x &&& 23#32 != 23#32))

theorem test_with_3_proof : test_with_3_before ⊑ test_with_3_after

theorem ashrsgt_03_06_thm (e : IntW 4) : icmp IntPred.sgt (ashr e (const? 4 3)) (const? 4 6) ⊑ const? 1 0

theorem test1_thm.extracted_1._1 : ∀ (x : BitVec 17), 10#17 ≥ ↑17 → False

theorem src_is_mask_xor_proof : src_is_mask_xor_before ⊑ src_is_mask_xor_after

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

theorem xor_signbit_shl_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬8#32 ≥ ↑32 → (x ^^^ BitVec.ofInt 32 (-65536)) <<< 8#32 = x <<< 8#32 ^^^ BitVec.ofInt 32 (-16777216)

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 e_2266 :
    2 * (d |||  ~~~e) - 1 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 4 * ((d ||| e) &&& (e ^^^ f)) + 11 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 5 *  ~~~(e &&&  ~~~f) - 5 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 7 * ((d ^^^ e) ||| (d ^^^ f)) + 5 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 5 *  ~~~(e &&& f) + 1 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 7 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 5 * (d ||| f) - 1 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 4 * ((d &&&  ~~~e) ||| (e ^^^ f)) - 6 * ( ~~~e ||| (d ^^^ f)) - 1 * (e ^^^ (d &&& f)) + 7 * (e ^^^ ( ~~~d ||| (e &&& f))) + 1 * (d ^^^ (e ^^^ f)) + 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 5 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 3 * (e ^^^ f) - 1 * ( ~~~d &&& (e ||| f)) + 5 * (e ^^^ (d ||| (e ^^^ f))) + 5 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 2 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 2 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 2 * (f |||  ~~~(d |||  ~~~e)) + 1 * (f &&& (d ^^^ e)) + 2 * (e ^^^  ~~~(d &&& (e &&& f))) - 1 * (d ||| ( ~~~e ||| f)) + 1 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 11 * ((d &&& e) ||| (e ^^^ f)) + 4 * ((d &&& e) |||  ~~~(e ^^^ f)) + 1 * (d &&& ( ~~~e ||| f)) + 1 * ( ~~~d ||| (e &&& f)) - 1 * (f ^^^ (d &&& ( ~~~e ||| f))) - 11 *  ~~~(d &&& e) + 3 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 2 * ( ~~~d &&& (e ^^^ f)) - 1 * ( ~~~d ||| (e ||| f)) + 11 * (f ^^^ (d ||| e)) - 2 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 7 * (d |||  ~~~f) - 2 *  ~~~( ~~~d &&& (e ^^^ f)) - 7 * ((d &&& f) ||| (e &&&  ~~~f)) + 2 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 2 * (d ||| e) - 6 *  ~~~(d ||| (e ^^^ f)) + 2 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 4 * (e ^^^ ( ~~~d ||| (e ||| f))) + 2 * (f ^^^ ( ~~~d ||| (e &&& f))) - 1 *  ~~~(d ||| (e ||| f)) - 7 *  ~~~(d ||| ( ~~~e ||| f)) - 2 *  ~~~( ~~~d ||| (e ||| f)) - 11 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 10 * ( ~~~d &&& ( ~~~e &&& f)) + 36 * ( ~~~d &&& (e &&& f)) + 10 * (d &&& ( ~~~e &&& f)) - 12 * (d &&& (e &&& f)) = 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 11 *  ~~~(d &&& f)

theorem lshrult_03_00_proof : lshrult_03_00_before ⊑ lshrult_03_00_after

theorem sub_ule_sext_thm (e : IntW 1) (e_1 e_2 : IntW 8) :
  icmp IntPred.ule (sub e_2 e_1) (sext 8 e) ⊑ LLVM.or (icmp IntPred.eq e_2 e_1) e

theorem t0_thm.extracted_1._25 : ∀ (x x_1 x_2 x_3 : BitVec 8) (x_4 : BitVec 1),
  x_4 ^^^ 1#1 = 1#1 → x_4 = 1#1 → True → ofBool (x_3 != x_2) = 1#1 → x_1 = x

theorem shl_add_proof : shl_add_before ⊑ shl_add_after

theorem ashrslt_03_07_exact_proof : ashrslt_03_07_exact_before ⊑ ashrslt_03_07_exact_after

theorem sextinreg_alt_thm.extracted_1._1 : ∀ (x : BitVec 32),
  16#32 ≥ ↑32 ∨ True ∧ x <<< 16#32 >>> 16#32 <<< 16#32 ≠ x <<< 16#32 ∨ 16#32 ≥ ↑32 → False

theorem nonexact_lshr_eq_proof : nonexact_lshr_eq_before ⊑ nonexact_lshr_eq_after

theorem ashrslt_01_12_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 (-4)) = 0#1

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

theorem e_800 :
    7 *  ~~~(z &&& t) - 7 * (z ||| t) - 6 *  ~~~(z &&&  ~~~z) + 6 *  ~~~(z |||  ~~~t) + 13 * (z &&& t) =  - 6 * (z &&&  ~~~t) + 1 *  ~~~(z ||| t)

theorem sgt_minus1_proof : sgt_minus1_before ⊑ sgt_minus1_after

theorem sgt_negative_multip_rem_zero_proof : sgt_negative_multip_rem_zero_before ⊑ sgt_negative_multip_rem_zero_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_1b_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 3#32 == 1#32) = 1#1 →
    ofBool (x &&& 14#32 != 0#32) = ofBool (x &&& 3#32 == 1#32) &&& ofBool (x &&& 14#32 != 0#32)

theorem test_and2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (-1#32 <ₛ x_1) &&& ofBool (x_1 ≤ₛ x &&& 2147483647#32) = ofBool (x_1 ≤ᵤ x &&& 2147483647#32)

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

theorem t0_proof : t0_before ⊑ t0_after

theorem t3_exact_proof : t3_exact_before ⊑ t3_exact_after

theorem trunc_lshr_sext_wide_input_thm (e : IntW 16) :
  trunc 8 (lshr (sext 32 e) (const? 32 9)) ⊑ trunc 8 (ashr e (const? 16 9)) { «nsw» := true, «nuw» := false }

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

theorem test9_proof : test9_before ⊑ test9_after

theorem test3_thm (e : IntW 32) :
  add (LLVM.and e (const? 32 128)) (lshr e (const? 32 30)) ⊑
    LLVM.or (LLVM.and e (const? 32 128)) (lshr e (const? 32 30)) { «disjoint» := true }

theorem shl_mask_wrong_shl_const_proof : shl_mask_wrong_shl_const_before ⊑ shl_mask_wrong_shl_const_after

theorem test2_thm.extracted_1._2 : ∀ (x : BitVec 167),
  ¬(9#577 ≥ ↑577 ∨ 8#577 ≥ ↑577) →
    ¬(9#167 ≥ ↑167 ∨ 8#167 ≥ ↑167) →
      truncate 167 (zeroExtend 577 x >>> 9#577 ||| zeroExtend 577 x <<< 8#577) = x >>> 9#167 ||

theorem positive_with_extra_and_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  ofBool (x_1 + 128#32 <ᵤ 256#32) &&& (ofBool (-1#32 <ₛ x_1) &&& x) = ofBool (x_1 <ᵤ 128#32) &&& x

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 add_and_or_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), (x_1 &&& x) + (x_1 ||| x) = x_1 + x

theorem t0_proof : t0_before ⊑ t0_after

theorem icmp_ne_sext_ne_otherwise_i128_thm.extracted_1._1 : ∀ (x : BitVec 128),
  ofBool (signExtend 128 (ofBool (x != 2#128)) != x) = ofBool (x != -1#128)

theorem and_xor_common_op_commute1_thm (e e_1 : IntW 32) :
  LLVM.and (LLVM.udiv (const? 32 42) e_1) (LLVM.xor (LLVM.udiv (const? 32 43) e) (LLVM.udiv (const? 32 42) e_1)) ⊑
    LLVM.and (LLVM.udiv (const? 32 42) e_1) (LLVM.xor (LLVM.udiv (const? 32 43) e) (const? 32 (-1)))

theorem cmp_x_and_negp2_with_eq_thm (e : IntW 8) :
  icmp IntPred.eq (LLVM.and e (const? 8 (-2))) (const? 8 (-128)) ⊑
    icmp IntPred.slt e (const? 8 (-126))

theorem positive_biggershl_shlnuwnsw_thm (e : IntW 8) :
  shl (lshr e (const? 8 3)) (const? 8 6) { «nsw» := true, «nuw» := true } ⊑
    LLVM.and (shl e (const? 8 3) { «nsw» := true, «nuw» := true }) (const? 8 64)

theorem narrow_zext_ashr_keep_trunc_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ (signExtend 32 x_1).saddOverflow (signExtend 32 x) = true ∨ 1#32 ≥ ↑32) →
    True ∧ (signExtend 16 x_1).saddOverflow (signExtend 16 x) = true ∨ 1#16 ≥ ↑16 → False

theorem test27_thm (e e_1 e_2 : IntW 32) :
  zext 32 (icmp IntPred.eq (LLVM.xor e_2 e_1) (LLVM.xor e_2 e)) ⊑ zext 32 (icmp IntPred.eq e_1 e)

theorem e_543 :
    4 *  ~~~x + 1 *  ~~~y + 4 *  ~~~(x &&&  ~~~x) + 5 *  ~~~(x &&& y) + 7 *  ~~~(x ^^^ y) - 21 *  ~~~(x ||| y) - 18 *  ~~~(x |||  ~~~y) - 15 * (x &&&  ~~~y) - 16 * (x &&& y) =  - 5 * (x ||| y)

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

theorem mul_select_sext_thm (e : IntW 1) :
  mul (select e (const? 64 64) (const? 64 1)) (sext 64 e) ⊑ select e (const? 64 (-64)) (const? 64 0)

theorem test11_proof : test11_before ⊑ test11_after

@[simp] theorem Valuation.append_appendInr {v : Var Δ t} :
    (V ++ W) v.appendInr = W v

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

theorem positive_samevar_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(x ≥ ↑8 ∨ x ≥ ↑8) →
    ¬(True ∧ ((-1#8) <<< x).sshiftRight' x ≠ -1#8 ∨ x ≥ ↑8) → x_1.sshiftRight' x <<< x = (-1#8) <<< x &&& x_1

theorem e_1562 :
     - 1 * (b ||| (a ^^^ c)) + 4 *  ~~~( ~~~a ||| (b &&& c)) - 2 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 11 * (b ^^^ ( ~~~a ||| (b ||| c))) - 5 *  ~~~( ~~~a ||| ( ~~~b &&& c)) - 6 * ( ~~~b ||| (a ^^^ c)) - 7 * ((a &&& b) ^^^ (b |||  ~~~c)) + 7 *  ~~~(b ^^^ c) + 22 *  ~~~(a ||| (b ||| c)) + 8 *  ~~~( ~~~a ||| (b ||| c)) + 13 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 21 * ( ~~~a &&& ( ~~~b &&& c)) + 10 * ( ~~~a &&& (b &&& c)) + 18 * (a &&& ( ~~~b &&& c)) + 2 * (a &&& (b &&& c)) = 3 * ( ~~~a ||| (b ||| c)) - 11 *  ~~~(a ||| ( ~~~b ||| c))

theorem or_and_xor_not_constant_commute1_proof : or_and_xor_not_constant_commute1_before ⊑ or_and_xor_not_constant_commute1_after

theorem e_930 :
    7 *  ~~~(z ^^^ t) + 2 * (z |||  ~~~t) + 1 * (z ||| t) - 9 *  ~~~(z ||| t) - 8 *  ~~~(z |||  ~~~t) - 17 * (z &&& t) = 3 * (z &&&  ~~~t) - 7 * t

@[simp] theorem Com.rec'_rets (v : HVector Γ.Var t) :
    (Com.rets (d:=d) (eff := eff) v).rec' (motive:=motive) rets var = rets v

theorem ashrsgt_03_07_exact_proof : ashrsgt_03_07_exact_before ⊑ ashrsgt_03_07_exact_after

theorem test6_proof : test6_before ⊑ test6_after

theorem sext_sext_ult_proof : sext_sext_ult_before ⊑ sext_sext_ult_after

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

theorem e_2057 :
     - 11 * (d ^^^ f) + 5 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 7 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 2 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 3 * (d |||  ~~~f) - 1 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 * (f ^^^ (d &&& (e ||| f))) + 1 * (f ^^^  ~~~(d &&& e)) + 4 * (e ^^^ f) - 1 * (f ||| (d &&& e)) - 1 * (f ^^^  ~~~(d &&& (e &&& f))) + 11 * ( ~~~d ||| ( ~~~e ||| f)) - 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 4 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 7 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 2 *  ~~~(d ^^^ f) - 2 * d + 2 * ((d &&& e) |||  ~~~(e ||| f)) + 11 * (d &&& e) + 11 *  ~~~(d ||| (e &&& f)) - 11 *  ~~~(d ^^^ e) - 1 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 7 * (e &&&  ~~~(d &&& f)) - 3 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 3 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 1 * (e ^^^ ( ~~~d ||| (e &&& f))) - 1 * (f ^^^ (d ||| (e ||| f))) + 4 * (e ||| (d ^^^ f)) - 3 * (d ^^^ (e ^^^ f)) + 1 * (e ||| (d &&& f)) - 37 *  ~~~(d ||| ( ~~~e ||| f)) - 8 *  ~~~( ~~~d ||| (e ||| f)) - 14 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 3 * ( ~~~d &&& ( ~~~e &&& f)) - 18 * ( ~~~d &&& (e &&& f)) - 13 * (d &&& ( ~~~e &&& f)) - 20 * (d &&& (e &&& f)) = 17 *  ~~~(d ||| (e ||| f))

@[simp] theorem getElem?_map (Γ : Ctxt Ty) (f : Ty → Ty') (i : Nat) :
    (Γ.map f)[i]? = Γ[i]?.map f

theorem and_or1_wrong_operand_thm.extracted_1._3 : ∀ (x x_1 x_2 x_3 : BitVec 1),
  x_3 ^^^ 1#1 ||

theorem mul_setnzV_unkV_nuw_eq_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (mul (LLVM.or e_1 (const? 8 2)) e { «nsw» := false, «nuw» := true }) (const? 8 0) ⊑
    icmp IntPred.eq e (const? 8 0)

theorem e_884 :
    1 *  ~~~z - 5 *  ~~~t - 6 * z + 4 *  ~~~(z ||| t) - 1 *  ~~~(z |||  ~~~t) + 6 * (z &&& t) =  - 11 * (z &&&  ~~~t)

@[simp]
lemma autMsbSet_accepts : NFA'.autMsbSet.accepts = langMsb

theorem main12_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (truncate 16 x <ₛ 0#16) = 1#1 → ofBool (x &&& 32896#32 == 0#32) = 1#1 → True → 2#32 = 1#32

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬30#32 ≥ ↑32 → 30#32 ≥ ↑32 ∨ True ∧ (x &&& 128#32 &&& x >>> 30#32 != 0) = true → False

theorem and_sgt_to_mask_thm (e : IntW 8) :
  LLVM.and (icmp IntPred.sgt e (const? 8 123)) (icmp IntPred.eq (LLVM.and e (const? 8 2)) (const? 8 0)) ⊑
    icmp IntPred.eq (LLVM.and e (const? 8 (-2))) (const? 8 124)

theorem substitute_constant_and_eq_ugt_swap_logical_proof : substitute_constant_and_eq_ugt_swap_logical_before ⊑ substitute_constant_and_eq_ugt_swap_logical_after

theorem add_nsw_const_const_sub_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.saddOverflow 1#8 = true) → BitVec.ofInt 8 (-127) - (x + 1#8) = BitVec.ofInt 8 (-128) - x

theorem add_signbit_select_shl_proof : add_signbit_select_shl_before ⊑ add_signbit_select_shl_after

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

theorem exact_lshr_eq_exactdiv_proof : exact_lshr_eq_exactdiv_before ⊑ exact_lshr_eq_exactdiv_after

theorem test31_thm (e : IntW 1) :
  LLVM.and (shl (zext 32 e) (const? 32 4)) (const? 32 16) ⊑ select e (const? 32 16) (const? 32 0)

theorem or_or_logic_and_1_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 ||

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

theorem test65_thm (e : IntW 64) :
  select (icmp IntPred.ne (LLVM.and e (const? 64 16)) (const? 64 0)) (const? 32 40) (const? 32 42) ⊑
    select (icmp IntPred.eq (LLVM.and e (const? 64 16)) (const? 64 0)) (const? 32 42) (const? 32 40)

theorem test10_proof : test10_before ⊑ test10_after

@[simp]
theorem EnvFin.getLsbD_getLsb {w : Nat} (env : EnvFin (w + 1) n) (bit : Nat) : (env.getLsb i).getLsbD bit =
    if bit = 0 then (env i)[0] else false

theorem c0_proof : c0_before ⊑ c0_after

theorem test4_proof : test4_before ⊑ test4_after

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

theorem test_sext3_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1), x_1 = 1#1 → x_1 ^^^ 1#1 = 1#1 → 0#32 = signExtend 32 x

theorem icmp_eq_sext_eq_allones_proof : icmp_eq_sext_eq_allones_before ⊑ icmp_eq_sext_eq_allones_after

theorem shl_lshr_pow2_const_negative_overflow2_proof : shl_lshr_pow2_const_negative_overflow2_before ⊑ shl_lshr_pow2_const_negative_overflow2_after

theorem positive_trunc_signbit_proof : positive_trunc_signbit_before ⊑ positive_trunc_signbit_after

theorem ugt_rem_zero_nsw_proof : ugt_rem_zero_nsw_before ⊑ ugt_rem_zero_nsw_after

theorem sle_smax4_proof : sle_smax4_before ⊑ sle_smax4_after

theorem squared_nsw_eq0_thm (e : IntW 5) :
  icmp IntPred.eq (mul e e { «nsw» := true, «nuw» := false }) (const? 5 0) ⊑
    icmp IntPred.eq e (const? 5 0)

theorem icmp_equality_test_constant_proof : icmp_equality_test_constant_before ⊑ icmp_equality_test_constant_after

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

theorem test_mul_nuw_nsw__nsw_is_safe_proof : test_mul_nuw_nsw__nsw_is_safe_before ⊑ test_mul_nuw_nsw__nsw_is_safe_after

theorem test4_proof : test4_before ⊑ test4_after

omit [LawfulBEq A] [Fintype S] [LawfulBEq S] [DecidableEq S] in
lemma rel_in_states {st : worklist.St A S} (hinv : StInv A S st.m st.map) :
    s ~[st.rel] sa → s ∈ st.m.states

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

theorem test8_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬32#128 ≥ ↑128 →
    True ∧ zeroExtend 64 x_1 <<< 32#64 >>> 32#64 ≠ zeroExtend 64 x_1 ∨
        32#64 ≥ ↑64 ∨ True ∧ (zeroExtend 64 x_1 <<< 32#64 &&& zeroExtend 64 x != 0) = true →
      False

theorem masked_and_notA_slightly_optimized_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (8#32 ≤ᵤ x) = 1#1 → 0#1 = ofBool (x &&& BitVec.ofInt 32 (-40) != 0#32)

theorem invert_both_cmp_operands_sub_proof : invert_both_cmp_operands_sub_before ⊑ invert_both_cmp_operands_sub_after

theorem neg_or_lshr_i32_commute_proof : neg_or_lshr_i32_commute_before ⊑ neg_or_lshr_i32_commute_after

theorem e_2282 :
    1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 11 *  ~~~(d &&& (e &&& f)) + 4 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 1 * (d &&&  ~~~f) - 1 * (e ^^^  ~~~(d &&& (e ||| f))) + 5 * (f ^^^  ~~~(d &&& (e ||| f))) - 2 * ((d ^^^ e) &&& (d ^^^ f)) + 1 * (d ^^^ ( ~~~e &&& f)) + 2 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 1 * (e ||| (d ^^^ f)) + 4 * (f |||  ~~~(d ^^^ e)) + 5 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (d ^^^ (e ^^^ f)) - 1 * ( ~~~d ||| ( ~~~e &&& f)) - 1 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 4 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 2 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 2 *  ~~~e - 5 * ((d &&& f) ^^^ (e ||| f)) - 5 *  ~~~(d &&& e) + 4 * (d ||| (e &&& f)) - 2 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 2 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 2 *  ~~~d + 7 *  ~~~(d ||| ( ~~~e &&& f)) + 3 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 3 * ((d &&& e) ^^^ (e ||| f)) - 7 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 11 *  ~~~( ~~~d &&& (e ||| f)) - 6 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 7 * ((e &&& f) ||| (d &&& (e ||| f))) + 11 * (d &&&  ~~~e) - 1 *  ~~~(d |||  ~~~f) - 1 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 11 * ( ~~~d &&& (e ||| f)) - 1 * (e &&& (d ||| f)) + 1 *  ~~~(d ^^^ (e ||| f)) - 1 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 2 * ( ~~~e &&&  ~~~(d ^^^ f)) - 11 *  ~~~(e &&& f) + 2 * (e ^^^ (d ||| (e ||| f))) + 4 * (e ^^^ ( ~~~d ||| (e &&& f))) + 3 * (f &&& (d ^^^ e)) + 2 * (e ^^^ (d ||| ( ~~~e &&& f))) - 6 * (f ^^^ (d &&& e)) + 2 * ( ~~~e |||  ~~~(d ^^^ f)) - 7 *  ~~~(d ^^^ (e ^^^ f)) - 11 *  ~~~(e &&&  ~~~f) - 11 * (d ||| f) - 11 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 7 * ( ~~~d &&& (e ^^^ f)) + 2 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 25 *  ~~~(d ||| (e ||| f)) + 4 *  ~~~(d ||| ( ~~~e ||| f)) + 44 *  ~~~( ~~~d ||| (e ||| f)) + 13 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 33 * ( ~~~d &&& ( ~~~e &&& f)) + 28 * ( ~~~d &&& (e &&& f)) + 7 * (d &&& ( ~~~e &&& f)) + 33 * (d &&& (e &&& f)) = 5 * (d ^^^ (e ||| f)) + 7 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f))

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

@[simp] theorem sup_impure_eq : max e impure  = impure

theorem not_sub_thm (e : IntW 32) :
  LLVM.xor (sub (const? 32 123) e) (const? 32 (-1)) ⊑ add e (const? 32 (-124))

theorem positive_samevar_shlnuwnsw_ashrexact_thm (e e_1 : IntW 8) :
  shl (ashr e_1 e { «exact» := true }) e { «nsw» := true, «nuw» := true } ⊑ e_1

theorem or_xor_tree_0010_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 (const? 32 42)) (mul e_1 (const? 32 42))) (mul e_2 (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 test_with_3_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → 3#32 <<< x &&& 1#32 = zeroExtend 32 (ofBool (x == 0#32))

theorem e_1830 :
    2 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) - 1 *  ~~~(a &&& (b ^^^ c)) - 1 * ((a ||| b) &&&  ~~~(b ^^^ c)) - 11 *  ~~~a - 6 * (c |||  ~~~(a |||  ~~~b)) + 1 * (c ||| (a ^^^ b)) - 2 * ( ~~~c ||| (a ^^^ b)) - 2 * ( ~~~(a ||| b) ||| (b ^^^ c)) + 4 * (b ^^^ ( ~~~a ||| (b ^^^ c))) - 6 * (b |||  ~~~(a ^^^ c)) + 4 * ( ~~~a ||| (b ||| c)) + 7 * (a &&& ( ~~~b ||| c)) - 5 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) - 5 * (b ^^^  ~~~(a ||| c)) - 1 * (a ^^^ (b &&& c)) - 3 * (a ||| ( ~~~b ||| c)) - 7 * (c ^^^ (a &&& b)) + 2 * (b ^^^ (a ||| (b ||| c))) + 4 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 3 * (c ^^^  ~~~(a &&& (b &&& c))) - 7 *  ~~~( ~~~a ||| (b &&& c)) + 1 * ( ~~~c &&& (a ^^^ b)) - 2 * ((a &&& b) |||  ~~~(b ||| c)) - 1 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) - 1 * ((a &&& b) |||  ~~~(b ^^^ c)) - 2 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) - 3 * (c &&& (a ^^^ b)) - 1 * (b ^^^ (a &&& c)) + 2 * (b &&&  ~~~(a &&& c)) - 1 * (b &&&  ~~~(a ^^^ c)) - 5 *  ~~~( ~~~a &&& (b ^^^ c)) - 5 * ((a |||  ~~~b) &&& (b ^^^ c)) + 1 * ((a ^^^ b) ||| (a ^^^ c)) + 2 * ((a &&& b) ^^^  ~~~(a ^^^ (b &&& c))) + 3 * (b ||| (a &&&  ~~~c)) + 31 *  ~~~(a ||| (b ||| c)) + 13 *  ~~~(a ||| ( ~~~b ||| c)) + 1 *  ~~~( ~~~a ||| (b ||| c)) + 26 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 20 * ( ~~~a &&& ( ~~~b &&& c)) + 41 * ( ~~~a &&& (b &&& c)) + 28 * (a &&& ( ~~~b &&& c)) + 10 * (a &&& (b &&& c)) =  - 2 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c)))

theorem lsb_mask_sign_sext_commuted_thm (e : IntW 32) :
  ashr (LLVM.and (LLVM.xor e (const? 32 (-1))) (add e (const? 32 (-1)))) (const? 32 31) ⊑
    sext 32 (icmp IntPred.eq e (const? 32 0))

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

theorem sext_thm.extracted_1._1 : ∀ (x : BitVec 16),
  (zeroExtend 32 x ^^^ 32768#32) + BitVec.ofInt 32 (-32768) = signExtend 32 x

theorem or_xor_tree_0000_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_1 (const? 32 42)) (mul e (const? 32 42))) (mul e_2 (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 alive_AndOrXor_794 : alive_AndOrXor_794_src ⊑ alive_AndOrXor_794_tgt

theorem ashrsgt_02_11_exact_proof : ashrsgt_02_11_exact_before ⊑ ashrsgt_02_11_exact_after

theorem test_add_nuw_nsw__nsw_is_safe_proof : test_add_nuw_nsw__nsw_is_safe_before ⊑ test_add_nuw_nsw__nsw_is_safe_after

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

theorem ashrsgt_03_14_thm (e : IntW 4) : icmp IntPred.sgt (ashr e (const? 4 3)) (const? 4 (-2)) ⊑ const? 1 1

theorem scalar_i32_lshr_and_negC_eq_nonzero_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬x ≥ ↑32 → ofBool (x_1 >>> x &&& BitVec.ofInt 32 (-2147483648) == 1#32) = 0#1

theorem slt_swap_or_not_max_proof : slt_swap_or_not_max_before ⊑ slt_swap_or_not_max_after

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

theorem shl_add_log_may_cause_poison_pr62175_with_nuw_proof : shl_add_log_may_cause_poison_pr62175_with_nuw_before ⊑ shl_add_log_may_cause_poison_pr62175_with_nuw_after

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 sge_swap_or_not_max_logical_proof : sge_swap_or_not_max_logical_before ⊑ sge_swap_or_not_max_logical_after

theorem icmp_eq_x_invertable_y2_proof : icmp_eq_x_invertable_y2_before ⊑ icmp_eq_x_invertable_y2_after

theorem e_2020 :
    1 * (d ||| ( ~~~e &&& f)) + 2 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 7 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 2 * (f ||| (d &&&  ~~~e)) - 6 * (e ^^^ f) - 1 * (e &&& f) - 5 * (e ^^^ (d ||| f)) - 6 * (d ||| (e &&& f)) + 3 * ((d &&& e) |||  ~~~(e ^^^ f)) - 1 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 4 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 3 * (d ||| f) + 5 * (e ^^^ (d ||| (e ^^^ f))) - 5 * ((d ^^^ e) |||  ~~~(d ^^^ f)) + 1 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 3 * (e ||| (d &&& f)) + 2 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 11 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 1 * (d ||| ( ~~~e ||| f)) - 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 11 * (d &&& (e ^^^ f)) - 2 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 4 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 1 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 11 * (e ^^^ ( ~~~d ||| (e &&& f))) - 3 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 11 * (e ^^^  ~~~(d ||| (e &&& f))) + 11 * (f |||  ~~~(d |||  ~~~e)) + 7 *  ~~~(d ||| (e ||| f)) - 4 *  ~~~( ~~~d ||| (e ||| f)) + 45 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 12 * ( ~~~d &&& ( ~~~e &&& f)) - 14 * ( ~~~d &&& (e &&& f)) - 7 * (d &&& ( ~~~e &&& f)) =  - 11 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) - 7 *  ~~~(d ||| ( ~~~e ||| f))

theorem icmp_slt_0_or_icmp_sgt_0_i32_thm.extracted_1._1 : ∀ (x : BitVec 32),
  zeroExtend 32 (ofBool (x <ₛ 0#32)) ||

theorem select1_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 32) (x_3 : BitVec 1),
  x_3 = 1#1 → zeroExtend 32 (truncate 8 x_2) = x_2 &&& 255#32

theorem test8_thm (e : IntW 27) : sub (mul (const? 27 9) e) e ⊑ shl e (const? 27 3)

theorem ashr_lshr_cst2_thm (e : IntW 32) :
  select (icmp IntPred.sgt e (const? 32 (-1))) (lshr e (const? 32 8)) (ashr e (const? 32 8) { «exact» := true }) ⊑
    ashr e (const? 32 8)

theorem src_is_mask_zext_fail_not_mask_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 16),
  ¬x ≥ ↑8 →
    ofBool ((x_1 ^^^ 123#16) &&& zeroExtend 16 (BitVec.ofInt 8 (-2) >>> x) == x_1 ^^^ 123#16) =
      ofBool (x_1 ^^^ BitVec.ofInt 16 (-124) ||| zeroExtend 16 (BitVec.ofInt 8 (-2) >>> x) == -1#16)

theorem alive_AndOrXor_144  (w : Nat)   : alive_AndOrXor_144_src w  ⊑ alive_AndOrXor_144_tgt w

theorem main7d_logical_thm.extracted_1._9 : ∀ (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 1#1

theorem test_invert_demorgan_or2_proof : test_invert_demorgan_or2_before ⊑ test_invert_demorgan_or2_after

theorem nonexact_ashr_ne_exactdiv_thm (e : IntW 8) :
  icmp IntPred.ne (ashr (const? 8 (-80)) e) (const? 8 (-5)) ⊑ icmp IntPred.ne e (const? 8 4)

theorem e_1054 :
    1 * (z |||  ~~~t) - 5 *  ~~~(z &&&  ~~~t) + 7 *  ~~~z - 7 * t + 3 *  ~~~(z ||| t) + 5 *  ~~~(z |||  ~~~t) + 11 * (z &&& t) = 6 *  ~~~t - 5 * (z &&&  ~~~t)

theorem e_2425 :
    3 * (d ||| ( ~~~e &&& f)) - 1 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 1 * (e ^^^ (d ||| (e ^^^ f))) + 11 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 2 *  ~~~( ~~~d &&& (e &&& f)) - 5 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 6 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 1 * (e ^^^ (d &&& ( ~~~e ||| f))) + 11 *  ~~~(d ||| ( ~~~e &&& f)) + 3 * ((d &&& e) ||| (e ^^^ f)) + 4 * (e ^^^  ~~~(d &&& (e ||| f))) + 2 * (f ^^^  ~~~(d ||| e)) - 11 * ( ~~~e &&& (d ^^^ f)) + 7 *  ~~~( ~~~d &&& (e ||| f)) + 2 *  ~~~(d |||  ~~~f) + 7 *  ~~~(e |||  ~~~f) - 6 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 1 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) - 2 * ( ~~~f &&&  ~~~(d ^^^ e)) + 7 * ((d &&& f) ^^^ (e ||| f)) - 1 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 1 * (d ||| e) - 3 * ((d ^^^ e) &&& (d ^^^ f)) + 3 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 3 * (f |||  ~~~(d |||  ~~~e)) + 2 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 5 * (f ^^^  ~~~(d &&&  ~~~e)) + 2 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 2 * (e &&& (d |||  ~~~f)) + 5 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 2 * ((d &&& e) |||  ~~~(e ^^^ f)) - 2 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 1 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 2 * (e &&& f) + 1 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * (f |||  ~~~(d ^^^ e)) + 2 * (f ||| (d &&&  ~~~e)) + 1 * (d |||  ~~~f) - 3 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 7 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 5 * (f &&& (d ^^^ e)) + 11 * (e &&& (d ||| f)) - 6 * (d ||| ( ~~~e ||| f)) - 6 *  ~~~( ~~~d ||| (e ^^^ f)) + 5 * (e ^^^ (d ||| f)) - 2 * (e ^^^  ~~~(d |||  ~~~f)) - 11 *  ~~~(d ^^^ (e &&& f)) + 2 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * (e ^^^  ~~~(d ||| (e &&& f))) - 7 * (d ^^^ (e &&& f)) - 7 * ( ~~~e &&&  ~~~(d ^^^ f)) - 3 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 7 * (e ^^^ (d ||| ( ~~~e ||| f))) - 1 * (e ^^^ f) - 2 *  ~~~(d &&& (e ||| f)) - 7 * (e ^^^ (d &&& (e ^^^ f))) + 2 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 11 * (e ^^^ (d ||| (e ||| f))) - 1 * (d ^^^ ( ~~~e ||| f)) - 3 * (e ||| f) + 11 * (d ^^^ (e ^^^ f)) - 5 * (d ||| (e ||| f)) - 1 * (f ^^^ (d ||| (e ||| f))) - 6 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 7 * (f ||| (d ^^^ e)) - 6 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 7 *  ~~~(d ^^^ ( ~~~e &&& f)) + 30 *  ~~~(d ||| (e ||| f)) - 16 *  ~~~(d ||| ( ~~~e ||| f)) + 31 *  ~~~( ~~~d ||| (e ||| f)) - 12 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 17 * ( ~~~d &&& ( ~~~e &&& f)) + 13 * ( ~~~d &&& (e &&& f)) + 10 * (d &&& ( ~~~e &&& f)) + 6 * (d &&& (e &&& f)) =  - 1 * e

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 7#32 != 1#32) = 1#1 → 1#1 = ofBool (x &&& 15#32 != 9#32)

theorem test11_proof : test11_before ⊑ test11_after

theorem trunc_shl_nsw_nuw_31_i32_i64_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬(True ∧ (x <<< 31#64).sshiftRight' 31#64 ≠ x ∨ True ∧ x <<< 31#64 >>> 31#64 ≠ x ∨ 31#64 ≥ ↑64) →
    ¬31#32 ≥ ↑32 → truncate 32 (x <<< 31#64) = truncate 32 x <<< 31#32

theorem max_sub_ult_c1_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x <ᵤ 1#32) = 1#1 → 0#32 = signExtend 32 (ofBool (x == 0#32))

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

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 ashr_ne_exact_proof : ashr_ne_exact_before ⊑ ashr_ne_exact_after

theorem xor_signbit_select_shl_proof : xor_signbit_select_shl_before ⊑ xor_signbit_select_shl_after

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

theorem trunc_sel_smaller_sext_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → signExtend 32 42#16 = 42#32

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 lshr_shl_demand1_thm.extracted_1._1 : ∀ (x : BitVec 8), ¬(x ≥ ↑8 ∨ 3#8 ≥ ↑8) → x ≥ ↑8 → False

theorem test16_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(11#32 ≥ ↑32 ∨ (x >>> 11#32 &&& 4#32) + 4#32 = 0) →
    ¬(11#32 ≥ ↑32 ∨ True ∧ (x >>> 11#32 &&& 4#32 &&& 3#32 != 0) = true) →
      x_1 % ((x >>> 11#32 &&& 4#32) + 4#32) = x_1 &&& (x >>> 11#32 &&& 4#32 ||| 3#32)

theorem test15a_thm.extracted_1._2 : ∀ (x : BitVec 32), ¬ofBool (x &&& 16#32 == 0#32) = 1#1 → 16#32 = x &&& 16#32

theorem test_or_eq_a_b_proof : test_or_eq_a_b_before ⊑ test_or_eq_a_b_after

theorem bools_multi_uses2_logical_thm.extracted_1._23 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 ^^^ 1#1 = 1#1 → x_2 = 1#1 → x_1 = 1#1 → ¬x = 1#1 → ¬True → x_1 + x = 0#1

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

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

theorem e_2442 :
     - 1 * (f ^^^ (d &&& e)) + 4 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 11 *  ~~~( ~~~d &&& (e ^^^ f)) + 11 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 5 * (d ||| f) - 2 * (e ^^^ (d |||  ~~~f)) - 1 * (e ^^^  ~~~(d ||| f)) + 1 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 7 * (f ^^^ (d |||  ~~~e)) + 2 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) + 5 *  ~~~(d |||  ~~~f) - 3 * (d &&&  ~~~f) - 5 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 7 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 1 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 2 *  ~~~(d &&&  ~~~f) - 2 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 6 * (d &&&  ~~~e) - 7 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 *  ~~~e - 2 * (d ^^^ ( ~~~e &&& f)) - 11 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 3 * (f ^^^ ( ~~~d ||| (e &&& f))) - 6 * (f ^^^  ~~~(d |||  ~~~e)) - 2 * (e ^^^ (d &&&  ~~~f)) - 7 * (e |||  ~~~f) - 2 * ( ~~~d &&& (e ||| f)) + 1 * (f ^^^ (d ||| (e ||| f))) + 7 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 2 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) + 1 *  ~~~(e &&& f) - 2 * (d &&& (e ||| f)) + 4 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 11 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 3 * ((d &&& e) |||  ~~~(e ^^^ f)) + 11 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 6 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 2 * ((d |||  ~~~e) &&& (e ^^^ f)) - 2 *  ~~~(d &&&  ~~~d) + 5 *  ~~~(d &&& e) + 2 * (d &&& f) + 2 * (d &&& ( ~~~e ||| f)) - 1 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 7 * (e ^^^ (d &&& f)) + 7 * (e ^^^ ( ~~~d ||| (e &&& f))) - 6 * (d &&& (e ^^^ f)) + 3 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 1 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 5 * (f ^^^ ( ~~~d &&& (e ||| f))) + 7 *  ~~~(d &&& (e &&& f)) - 11 *  ~~~(e ||| f) + 4 *  ~~~(d &&& (e ||| f)) - 3 * ((d &&& e) |||  ~~~(e |||  ~~~f)) - 3 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 11 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 11 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 *  ~~~(d &&& (e ^^^ f)) + 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 2 * (d ^^^ e) + 2 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 5 * (e ^^^  ~~~(d &&& f)) + 3 * (e ^^^  ~~~(d ||| (e &&& f))) - 1 *  ~~~(d ||| f) - 2 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * (e |||  ~~~(d |||  ~~~f)) - 1 * (f |||  ~~~(d ||| e)) - 36 *  ~~~(d ||| (e ||| f)) - 30 *  ~~~(d ||| ( ~~~e ||| f)) - 46 *  ~~~( ~~~d ||| (e ||| f)) - 24 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 40 * ( ~~~d &&& ( ~~~e &&& f)) - 40 * ( ~~~d &&& (e &&& f)) - 27 * (d &&& ( ~~~e &&& f)) - 32 * (d &&& (e &&& f)) =  - 4 *  ~~~(d &&& ( ~~~e ||| f))

theorem main12_thm (e : IntW 32) :
  select (LLVM.or (icmp IntPred.slt (trunc 16 e) (const? 16 0)) (icmp IntPred.slt (trunc 8 e) (const? 8 0)))
      (const? 32 2) (const? 32 1) ⊑
    select (icmp IntPred.eq (LLVM.and e (const? 32 32896)) (const? 32 0)) (const? 32 1) (const? 32 2)

theorem test_shl_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 ∨
          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 PR52261_proof : PR52261_before ⊑ PR52261_after

theorem ashr_ult_exact_near_pow2_cmpval_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x >>> 1#8 <<< 1#8 ≠ x ∨ 1#8 ≥ ↑8) → ofBool (x.sshiftRight' 1#8 <ᵤ 5#8) = ofBool (x <ᵤ 9#8)

theorem main7b_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 and_xor_or5_thm (e e_1 e_2 : IntW 64) :
  LLVM.or (LLVM.udiv (const? 64 42) e_2)
      (LLVM.xor (LLVM.and (LLVM.udiv (const? 64 42) e_1) (LLVM.udiv (const? 64 42) e_2)) (LLVM.udiv (const? 64 42) e)) ⊑
    LLVM.or (LLVM.udiv (const? 64 42) e_2) (LLVM.udiv (const? 64 42) e)

theorem main5_like_proof : main5_like_before ⊑ main5_like_after

theorem shrink_select_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → truncate 8 42#32 = 42#8

theorem shl_nsw_add_negative_invalid_constant3_thm.extracted_1._2 : ∀ (x : BitVec 4),
  ¬(True ∧ (2#4 <<< (x + BitVec.ofInt 4 (-8))).sshiftRight' (x + BitVec.ofInt 4 (-8)) ≠ 2#4 ∨
        x + BitVec.ofInt 4 (-8) ≥ ↑4) →
    ¬(True ∧ (2#4 <<< (x ^^^ BitVec.ofInt 4 (-8))).sshiftRight' (x ^^^ BitVec.ofInt 4 (-8)) ≠ 2#4 ∨
          x ^^^ BitVec.ofInt 4 (-8) ≥ ↑4) →
      2#4 <<< (x + BitVec.ofInt 4 (-8)) = 2#4 <<< (x ^^^ BitVec.ofInt 4 (-8))

theorem e_1729 :
    2 * ((a ||| b) &&&  ~~~(b ^^^ c)) - 1 * (b ^^^ (a &&&  ~~~c)) + 7 *  ~~~(b &&& c) - 1 * ((a &&& b) ^^^ (b |||  ~~~c)) - 1 *  ~~~(a &&&  ~~~b) - 1 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) + 3 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) + 3 * (b &&&  ~~~(a &&&  ~~~c)) + 1 * (b &&&  ~~~(a ^^^ c)) - 6 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 2 *  ~~~(a |||  ~~~c) - 1 *  ~~~( ~~~a &&& ( ~~~b &&& c)) + 1 * ( ~~~a &&& ( ~~~b ||| c)) + 11 * (a &&& b) + 7 *  ~~~(a ||| b) - 2 * (a ^^^ (b ^^^ c)) + 7 * (a ||| (b &&& c)) - 3 *  ~~~( ~~~a &&& (b &&& c)) + 3 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 4 * (a ||| b) + 11 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) - 5 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) + 1 *  ~~~(a &&& ( ~~~b ||| c)) - 13 *  ~~~(a ||| (b ||| c)) - 13 *  ~~~(a ||| ( ~~~b ||| c)) - 32 *  ~~~( ~~~a ||| (b ||| c)) - 17 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 14 * ( ~~~a &&& ( ~~~b &&& c)) - 16 * ( ~~~a &&& (b &&& c)) - 32 * (a &&& ( ~~~b &&& c)) - 25 * (a &&& (b &&& c)) =  - 4 * (b ^^^ (a ||| c))

theorem e_2481 :
    1 * (f ^^^ (d &&&  ~~~e)) - 1 * (d ||| e) + 4 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 3 * (d &&& f) + 2 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 1 * ( ~~~d ||| ( ~~~e ||| f)) - 2 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 7 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 2 * (e ||| f) + 2 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 2 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 3 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 2 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 1 * (e ^^^ (d ||| (e &&& f))) - 2 *  ~~~( ~~~d &&& (e ||| f)) + 11 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 11 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 6 * (f &&&  ~~~(d &&&  ~~~e)) - 7 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 1 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 11 * (f ^^^ (d ||| (e ||| f))) + 2 *  ~~~(d &&& (e ^^^ f)) - 1 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 4 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 1 * ( ~~~e &&& (d ^^^ f)) - 7 * (f ^^^ (d |||  ~~~e)) - 3 * (e |||  ~~~(d ||| f)) - 7 *  ~~~(d ^^^ (e &&& f)) - 11 *  ~~~(e ||| f) - 1 * (f &&& (d |||  ~~~e)) + 5 * (f &&& (d ||| e)) + 5 * d - 2 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 3 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 2 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) + 1 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 1 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 1 * (d ^^^ (e &&& f)) + 2 *  ~~~(d ^^^ (e ||| f)) + 2 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 11 * ((d &&& f) ^^^ (e ||| f)) + 4 * ( ~~~d &&& (e ||| f)) - 5 * (f &&&  ~~~(d ^^^ e)) + 1 *  ~~~(d &&& ( ~~~e &&& f)) - 5 * (e ^^^ f) + 1 * (f &&& (d ^^^ e)) + 7 *  ~~~( ~~~d ||| (e &&& f)) - 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 3 * (d ||| ( ~~~e ||| f)) - 7 *  ~~~(d |||  ~~~e) + 3 * (d |||  ~~~f) - 7 * (e &&& f) - 1 * (f ^^^ ( ~~~d &&& (e ||| f))) - 2 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 11 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 1 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) - 11 *  ~~~d + 1 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 11 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 6 * ((d &&& e) |||  ~~~(e ||| f)) - 1 *  ~~~(d ||| ( ~~~e &&& f)) + 1 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 11 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 2 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 6 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 7 * (e ^^^ (d ||| ( ~~~e ||| f))) - 3 *  ~~~( ~~~d &&& (e ^^^ f)) + 1 * (f ^^^ (d &&& (e ||| f))) + 5 * ((d &&& e) |||  ~~~(e |||  ~~~f)) - 6 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 5 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 39 *  ~~~(d ||| (e ||| f)) + 22 *  ~~~(d ||| ( ~~~e ||| f)) - 26 *  ~~~( ~~~d ||| (e ||| f)) - 3 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 21 * ( ~~~d &&& ( ~~~e &&& f)) + 41 * ( ~~~d &&& (e &&& f)) - 1 * (d &&& ( ~~~e &&& f)) + 10 * (d &&& (e &&& f)) = 1 * ( ~~~d ||| (e ^^^ f))

theorem or_xor_tree_1011_proof : or_xor_tree_1011_before ⊑ or_xor_tree_1011_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3_logical_after

theorem ult_1_impliesF_eq_1_proof : ult_1_impliesF_eq_1_before ⊑ ult_1_impliesF_eq_1_after

theorem lshr_and_thm (e e_1 : IntW 64) :
  lshr (LLVM.and (LLVM.srem e_1 (const? 64 42)) (lshr e (const? 64 5))) (const? 64 7) ⊑
    LLVM.and (lshr e (const? 64 12)) (lshr (LLVM.srem e_1 (const? 64 42)) (const? 64 7))

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

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

theorem bools_logical_commute3_and2_thm.extracted_1._11 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 = 1#1 → x_1 = 1#1 → 0#1 = 1#1 → 1#1 = x

theorem udiv_shl_mul_nuw_proof : udiv_shl_mul_nuw_before ⊑ udiv_shl_mul_nuw_after

theorem shl_sub_lshr_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_1).ssubOverflow x = true ∨
            True ∧ (x_2 <<< x_1).usubOverflow x = true ∨
              True ∧ (x_2 <<< x_1 - x) >>> x_1 <<< x_1 ≠ x_2 <<< x_1 - x ∨ x_1 ≥ ↑32) →
    True ∧ x >>> x_1 <<< x_1 ≠ x ∨
        x_1 ≥ ↑32 ∨ True ∧ x_2.ssubOverflow (x >>> x_1) = true ∨ True ∧ x_2.usubOverflow (x >>> x_1) = true →
      False

theorem sel_false_val_is_a_masked_lshr_of_true_val1_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 60#32 == 0#32) = 1#1 →
    ¬(2#32 ≥ ↑32 ∨ zeroExtend 64 ((x_1 &&& 60#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 e_1327 :
    1 * (z |||  ~~~t) + 5 * (z ^^^ t) - 1 *  ~~~(z &&&  ~~~t) - 2 * z - 5 *  ~~~z + 3 *  ~~~(z &&&  ~~~z) - 15 *  ~~~(z |||  ~~~t) - 9 * (z &&&  ~~~t) - 12 * (z &&& t) =  - 2 *  ~~~(z &&& t) - 11 * t

theorem trunc_shl_zext_32_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬4#16 ≥ ↑16 → ¬4#32 ≥ ↑32 → zeroExtend 32 (truncate 16 x <<< 4#16) = x <<< 4#32 &&& 65520#32

theorem test_with_neg_even_proof : test_with_neg_even_before ⊑ test_with_neg_even_after

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 ule_umax1_proof : ule_umax1_before ⊑ ule_umax1_after

lemma RawCNFA.Simul.rel_preserved_letter {m : RawCNFA A} {M : NFA A Q} (hsim : m.Simul M R ⊤ ∅) :
    R.set_eq S₁ Q₁ → ∃ S₂, R.set_eq S₂ (M.stepSet Q₁ a)

theorem e_2341 :
     - 1 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 7 * (e ||| f) - 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 7 *  ~~~(e ^^^ f) - 2 * (e ^^^  ~~~(d &&& (e ||| f))) - 5 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 2 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 4 * (e ^^^ (d &&& f)) + 4 * e + 2 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 1 *  ~~~(d &&& (e &&& f)) + 1 *  ~~~( ~~~d ||| (e &&& f)) - 11 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 7 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 2 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 1 *  ~~~(d |||  ~~~e) - 3 * (d ^^^ ( ~~~e &&& f)) - 11 * (e &&&  ~~~(d &&&  ~~~f)) + 5 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 11 *  ~~~(d &&&  ~~~d) - 11 * (f &&&  ~~~(d &&&  ~~~e)) + 7 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 * ((d &&& e) ^^^ (e |||  ~~~f)) + 1 *  ~~~(e &&&  ~~~f) - 3 * (f ^^^ (d &&& ( ~~~e ||| f))) + 1 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 1 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 3 * ( ~~~e &&& (d ^^^ f)) - 1 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) + 5 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 11 * (e |||  ~~~(d ^^^ f)) - 2 * (e ^^^ (d ||| ( ~~~e &&& f))) + 1 * (e ^^^  ~~~(d &&& (e &&& f))) + 1 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 2 *  ~~~(e &&& f) + 11 *  ~~~(d ^^^ (e ||| f)) + 3 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 5 *  ~~~(d ^^^ (e &&& f)) - 7 * ((e &&& f) ||| (d &&& (e ||| f))) + 1 * (d |||  ~~~f) - 3 * (e ^^^ (d ||| (e ||| f))) - 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 1 * (f ||| (d &&&  ~~~e)) + 4 * (e &&&  ~~~(d ^^^ f)) + 1 * ( ~~~d &&& (e ^^^ f)) - 2 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 5 * (e &&& (d ||| f)) - 2 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 11 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 7 * ( ~~~d ||| ( ~~~e &&& f)) - 11 * ( ~~~e |||  ~~~(d ^^^ f)) + 3 * ((d &&& e) ||| (e ^^^ f)) + 3 * (e ^^^ (d &&&  ~~~f)) - 6 *  ~~~( ~~~d &&& (e ||| f)) - 7 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 4 *  ~~~(d |||  ~~~f) - 13 *  ~~~(d ||| (e ||| f)) - 39 *  ~~~(d ||| ( ~~~e ||| f)) + 31 *  ~~~( ~~~d ||| (e ||| f)) - 14 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 7 * ( ~~~d &&& ( ~~~e &&& f)) - 4 * ( ~~~d &&& (e &&& f)) + 2 * (d &&& ( ~~~e &&& f)) - 11 * (d &&& (e &&& f)) = 5 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 5 * ((e &&& f) ||| ( ~~~d &&& (e ||| f)))

theorem ashrsgt_02_02_thm (e : IntW 4) : icmp IntPred.sgt (ashr e (const? 4 2)) (const? 4 2) ⊑ const? 1 0

theorem logical_and_not_cond_reuse_proof : logical_and_not_cond_reuse_before ⊑ logical_and_not_cond_reuse_after

theorem test_mul_nuw__all_are_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 255)) (const? 32 17)) (const? 32 153)
      (mul (LLVM.and e (const? 32 255)) (const? 32 9) { «nsw» := false, «nuw» := true }) ⊑
    mul (LLVM.and e (const? 32 255)) (const? 32 9) { «nsw» := true, «nuw» := true }

theorem pr33078_1_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬8#16 ≥ ↑16 → ¬7#8 ≥ ↑8 → truncate 8 (signExtend 16 x >>> 8#16) = x.sshiftRight' 7#8

theorem nonexact_ashr_ne_noexactlog_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → ofBool ((BitVec.ofInt 8 (-90)).sshiftRight' x != BitVec.ofInt 8 (-30)) = 1#1

theorem e_2292 :
    2 *  ~~~(d ||| f) - 11 * (e &&& f) + 11 *  ~~~(e &&&  ~~~f) + 7 * (f ^^^ ( ~~~d &&& (e ||| f))) + 4 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 7 * (d ||| ( ~~~e &&& f)) + 1 *  ~~~( ~~~d ||| (e &&& f)) - 2 * (d |||  ~~~e) - 2 * (e ^^^  ~~~(d &&& f)) + 1 *  ~~~(d &&& e) + 2 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 6 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 1 * (d &&& e) + 2 * (e &&& (d |||  ~~~f)) + 7 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 7 * (f ^^^ (d &&& (e ||| f))) - 3 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 1 * (e ^^^ (d &&& ( ~~~e ||| f))) - 7 * (d ^^^ ( ~~~e &&& f)) - 1 *  ~~~(d ^^^ ( ~~~e ||| f)) - 7 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 5 *  ~~~(d ^^^ ( ~~~e &&& f)) + 2 *  ~~~(d ||| e) + 1 * (f ^^^ (d &&& e)) - 1 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 11 * ( ~~~d ||| ( ~~~e ||| f)) + 7 * (e ^^^  ~~~(d |||  ~~~f)) + 2 * ((d &&& f) |||  ~~~(e ||| f)) + 1 * (e &&&  ~~~(d &&&  ~~~f)) + 11 * ( ~~~f |||  ~~~(d ^^^ e)) - 5 *  ~~~(d ||| (e ^^^ f)) - 1 * (d ||| (e &&& f)) + 2 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 3 * ( ~~~d ||| (e ^^^ f)) + 2 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 2 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 11 * (e ^^^ ( ~~~d ||| (e ||| f))) - 11 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 2 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 5 *  ~~~(e &&& f) + 4 * (d ||| e) - 1 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 3 * ((e &&& f) ||| (d &&& (e ||| f))) + 4 * ( ~~~d &&& (e ^^^ f)) - 11 *  ~~~(d ||| (e &&& f)) - 1 * d - 2 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 2 *  ~~~(d &&& f) - 3 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 2 * (e |||  ~~~(d ||| f)) + 1 *  ~~~( ~~~d &&& (e ||| f)) + 11 *  ~~~(d &&&  ~~~f) + 2 * (f ^^^ (d ||| (e &&& f))) - 51 *  ~~~(d ||| (e ||| f)) - 43 *  ~~~(d ||| ( ~~~e ||| f)) - 11 *  ~~~( ~~~d ||| (e ||| f)) - 5 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 41 * ( ~~~d &&& ( ~~~e &&& f)) - 32 * ( ~~~d &&& (e &&& f)) - 53 * (d &&& ( ~~~e &&& f)) - 25 * (d &&& (e &&& f)) =  - 7 * (f &&& (d ^^^ e)) + 1 *  ~~~(d &&& (e &&& f))

theorem udiv_shl_pair3_proof : udiv_shl_pair3_before ⊑ udiv_shl_pair3_after

theorem lshrult_01_13_proof : lshrult_01_13_before ⊑ lshrult_01_13_after

theorem p1_ugt_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ofBool (65534#32 <ᵤ x_1) = 1#1 → ofBool (x_1 <ᵤ 65535#32) = 1#1 → x = 65535#32

theorem test_or3_logical_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sle (LLVM.and e_1 (const? 32 2147483647)) e) (const? 1 1)
      (icmp IntPred.slt e (const? 32 0)) ⊑
    icmp IntPred.uge e (LLVM.and e_1 (const? 32 2147483647))

theorem sgt_3_impliesT_sgt_2_proof : sgt_3_impliesT_sgt_2_before ⊑ sgt_3_impliesT_sgt_2_after

theorem lshr_shl_eq_amt_multi_use_proof : lshr_shl_eq_amt_multi_use_before ⊑ lshr_shl_eq_amt_multi_use_after

theorem src_proof : src_before ⊑ src_after

theorem sgt_swap_or_not_min_commute_proof : sgt_swap_or_not_min_commute_before ⊑ sgt_swap_or_not_min_commute_after

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

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

theorem test1_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 57), ¬(x_1 ≥ ↑57 ∨ x_1 ≥ ↑57) → x_1 ≥ ↑57 → False

theorem ashr_eq_both_equal_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → ofBool ((BitVec.ofInt 8 (-128)).sshiftRight' x == BitVec.ofInt 8 (-128)) = ofBool (x == 0#8)

theorem uge_umin3_proof : uge_umin3_before ⊑ uge_umin3_after

theorem select_mul_icmp_bad_proof : select_mul_icmp_bad_before ⊑ select_mul_icmp_bad_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_1_logical_thm (e : IntW 32) :
  select (icmp IntPred.ne (LLVM.and e (const? 32 12)) (const? 32 0))
      (icmp IntPred.eq (LLVM.and e (const? 32 7)) (const? 32 1)) (const? 1 0) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 15)) (const? 32 9)

@[simp, simp_llvm]
theorem isRefinedBy_iff (x y : LLVM.IntW w) :
    x ⊑ y ↔ @HRefinement.IsRefinedBy (PoisonOr _) (PoisonOr _) _ x y

theorem or_logic_or_logic_and_6_thm.extracted_1._9 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 ||

theorem test_mul_nuw__nuw_is_safe_proof : test_mul_nuw__nuw_is_safe_before ⊑ test_mul_nuw__nuw_is_safe_after

theorem lshr_lshr_thm.extracted_1._1 : ∀ (x : BitVec 232),
  ¬(231#232 ≥ ↑232 ∨ 1#232 ≥ ↑232) → x >>> 231#232 >>> 1#232 = 0#232

theorem icmp_sle8_thm (e : IntW 8) :
  icmp IntPred.sle (shl e (const? 8 1) { «nsw» := true, «nuw» := false }) (const? 8 125) ⊑
    icmp IntPred.ne e (const? 8 63)

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 e_1401 :
    4 * t - 2 * (z |||  ~~~t) + 2 * (z ^^^ t) - 2 *  ~~~(z &&&  ~~~z) + 1 *  ~~~(z ^^^ t) + 3 * (z ||| t) - 4 *  ~~~(z ||| t) - 14 *  ~~~(z |||  ~~~t) - 1 * (z &&&  ~~~t) - 4 * (z &&& t) =  - 7 *  ~~~z

theorem test15a_proof : test15a_before ⊑ test15a_after

theorem t0_shl_proof : t0_shl_before ⊑ t0_shl_after

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

theorem e_1689 :
    11 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 1 * (a ||| ( ~~~b &&& c)) - 1 * ( ~~~a ||| (b &&& c)) + 7 * (b |||  ~~~c) + 5 * ((a &&&  ~~~b) ||| (b ^^^ c)) + 11 * ( ~~~a &&& ( ~~~b ||| c)) - 6 * ( ~~~a &&& (b ||| c)) + 1 * (b ||| (a &&& c)) + 11 * a - 1 *  ~~~(a ||| (b ^^^ c)) + 11 *  ~~~(a ^^^ ( ~~~b ||| c)) - 2 * (a &&&  ~~~c) - 1 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) - 2 * (c ^^^ ( ~~~a &&& ( ~~~b ||| c))) - 7 * ((b &&& c) ||| (a &&& (b ||| c))) + 1 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) + 2 * ((a &&& b) |||  ~~~(b ^^^ c)) + 1 * (b ^^^ ( ~~~a &&& (b ||| c))) - 3 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) - 7 * (b ^^^ ( ~~~a ||| (b ||| c))) - 18 *  ~~~(a ||| (b ||| c)) - 26 *  ~~~(a ||| ( ~~~b ||| c)) - 45 *  ~~~( ~~~a ||| (b ||| c)) - 16 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 2 * ( ~~~a &&& ( ~~~b &&& c)) - 7 * ( ~~~a &&& (b &&& c)) - 10 * (a &&& ( ~~~b &&& c)) - 21 * (a &&& (b &&& c)) =  - 1 * ((a &&& b) ^^^  ~~~(a ^^^ (b &&& c)))

theorem lshrugt_01_02_proof : lshrugt_01_02_before ⊑ lshrugt_01_02_after

theorem urem_i1_is_zero_thm (e e_1 : IntW 1) : urem e_1 e ⊑ const? 1 0

theorem shift_xor_multiuse_and_proof : shift_xor_multiuse_and_before ⊑ shift_xor_multiuse_and_after

theorem mul_constant_eq_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 * 5#32 == x * 5#32) = ofBool (x_1 == x)

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

theorem logical_and_icmps2_proof : logical_and_icmps2_before ⊑ logical_and_icmps2_after

theorem t7_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 8), x = 1#1 → x_1 - 0#8 = 0#8 + x_1

theorem tail_iterate'' {α} {n} {s : Stream' α} : Stream'.iterate Stream'.tail s n m = s (n + m)

theorem alive_AndOrXor_1705  (w : Nat)   : alive_AndOrXor_1705_src w  ⊑ alive_AndOrXor_1705_tgt w

theorem test_sub_0_Y_eq_0_proof : test_sub_0_Y_eq_0_before ⊑ test_sub_0_Y_eq_0_after

theorem no_reassoc_add_none_nuw_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.uaddOverflow 4#32 = true) → x + 4#32 + 64#32 = x + 68#32

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

@[simp] theorem Com.denote_changeVars
    (varsMap : Γ.Hom Γ') (c : Com d Γ eff ty) :
    (c.changeVars varsMap).denote =
    fun V => c.denote (V.comap varsMap)

theorem or_not_and_and_not_and_xor_proof : or_not_and_and_not_and_xor_before ⊑ or_not_and_and_not_and_xor_after

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

theorem ult_rem_nz_nsw_proof : ult_rem_nz_nsw_before ⊑ ult_rem_nz_nsw_after

theorem alive_AndOrXor_2663  (w : Nat)   : alive_AndOrXor_2663_src w  ⊑ alive_AndOrXor_2663_tgt w

theorem test12_proof : test12_before ⊑ test12_after

theorem sel_false_val_is_a_masked_ashr_of_true_val1_thm.extracted_1._4 : ∀ (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) →
        x.sshiftRight' (zeroExtend 64 ((x_1 &&& BitVec.ofInt 32 (-2147483588)).sshiftRight' 2#32)) =
          x.sshiftRight' (zeroExtend 64 (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)))

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

theorem test30_thm (e : IntW 1) : LLVM.and (zext 32 e) (const? 32 1) ⊑ zext 32 e

theorem select_mul_icmp_bad_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 == 3#32) = 1#1 → x_1 * x = x * 3#32

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

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

theorem c_0_1_0_thm.extracted_1._2 : ∀ (x x_1 : BitVec 4),
  ¬(True ∧ (x &&& BitVec.ofInt 4 (-2) &&& (x_1 &&& 1#4) != 0) = true) →
    (x_1 ^^^ x) &&& BitVec.ofInt 4 (-2) ^^^ x_1 = x &&& BitVec.ofInt 4 (-2) ||

theorem and_two_ranges_to_mask_and_range_not_pow2_diff_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (25#8 <ᵤ x + BitVec.ofInt 8 (-97)) &&& ofBool (25#8 <ᵤ x + BitVec.ofInt 8 (-64)) =
    ofBool (x + BitVec.ofInt 8 (-123) <ᵤ BitVec.ofInt 8 (-26)) &&&
      ofBool (x + BitVec.ofInt 8 (-90) <ᵤ BitVec.ofInt 8 (-26))

theorem test_thm : zext 32 (icmp IntPred.eq (const? 32 1) (const? 32 2)) ⊑ const? 32 0

@[bv_automata_nnf] theorem Int.lt_eq (a b : Int) : (a < b) = (a + 1 ≤ b)

theorem bv_283 :
    ∀ (e e_1 : LLVM.IntW 1), LLVM.mul e_1 e ⊑ LLVM.and e_1 e

theorem test_shl_nuw_nsw__nsw_is_safe_proof : test_shl_nuw_nsw__nsw_is_safe_before ⊑ test_shl_nuw_nsw__nsw_is_safe_after

theorem n15_variable_shamts_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32) (x_2 x_3 : BitVec 64),
  ¬(x_2 ≥ ↑64 ∨ x ≥ ↑32) →
    ¬(x ≥ ↑32 ∨ x_2 ≥ ↑64) →
      ofBool (truncate 32 (x_3 <<< x_2) &&& x_1 >>> x != 0#32) =
        ofBool (x_1 >>> x &&& truncate 32 (x_3 <<< x_2) != 0#32)

theorem negative_not_less_than_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (-1#32 <ₛ x) = 1#1 → ofBool (x + 256#32 <ᵤ 256#32) = 0#1

theorem e_2357 :
     - 6 *  ~~~(d ||| (e ^^^ f)) + 1 * ( ~~~e |||  ~~~(d ^^^ f)) - 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 5 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 *  ~~~(d ||| f) + 3 * ( ~~~f &&& (d ^^^ e)) + 1 * ((d ^^^ e) ||| (d ^^^ f)) + 1 * (f ||| (d &&&  ~~~e)) - 6 * (e &&&  ~~~(d ^^^ f)) + 7 *  ~~~(d ^^^ ( ~~~e &&& f)) + 4 * (f ||| (d &&& e)) + 7 * (d ||| (e &&& f)) + 11 * ( ~~~f ||| (d ^^^ e)) - 6 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 5 * (f &&&  ~~~(d &&& e)) + 5 * (d &&& f) - 11 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 2 * (f ^^^ (d ||| (e ||| f))) + 7 * (d ||| (e ||| f)) + 3 * (f ^^^  ~~~(d &&&  ~~~e)) - 3 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 1 * (f &&& (d ||| e)) - 11 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 2 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) + 5 * (f ^^^ (d &&& e)) + 7 * ( ~~~e ||| (d ^^^ f)) + 5 * ((d &&& e) |||  ~~~(e ^^^ f)) - 2 * ( ~~~d ||| (e &&& f)) - 2 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 1 * (e ^^^  ~~~(d &&&  ~~~f)) - 1 * (e |||  ~~~f) - 2 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 5 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 11 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 2 * (e |||  ~~~(d ||| f)) + 4 *  ~~~(d ^^^ e) + 4 * (e ^^^ (d &&& (e ||| f))) - 1 * ((d &&& e) |||  ~~~(e |||  ~~~f)) - 2 * (d &&&  ~~~f) - 1 *  ~~~f + 2 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 1 * (e ^^^ ( ~~~d ||| (e &&& f))) + 11 *  ~~~( ~~~d &&& (e &&& f)) + 3 * (f ^^^  ~~~(d &&& (e ||| f))) - 1 * (e ^^^  ~~~(d &&& f)) - 1 * ((d ^^^ e) &&& (d ^^^ f)) - 1 * (d ^^^ (e ^^^ f)) + 1 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 5 *  ~~~(d |||  ~~~f) + 2 * (f ^^^ ( ~~~d ||| (e &&& f))) + 2 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 3 * ((d &&& f) |||  ~~~(e ||| f)) - 7 *  ~~~(d ^^^ (e ||| f)) - 3 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 7 * (f ^^^  ~~~(d |||  ~~~e)) - 1 * (e ^^^  ~~~(d &&& (e &&& f))) + 2 * (e ^^^ f) + 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 2 * ((d &&& f) ||| (e &&&  ~~~f)) + 1 *  ~~~(e &&&  ~~~f) - 16 *  ~~~(d ||| (e ||| f)) - 17 *  ~~~(d ||| ( ~~~e ||| f)) - 38 *  ~~~( ~~~d ||| (e ||| f)) - 5 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 27 * ( ~~~d &&& ( ~~~e &&& f)) - 6 * ( ~~~d &&& (e &&& f)) - 71 * (d &&& ( ~~~e &&& f)) - 18 * (d &&& (e &&& f)) = 3 * (e ^^^ (d ||| (e &&& f)))

theorem ashrslt_01_10_exact_proof : ashrslt_01_10_exact_before ⊑ ashrslt_01_10_exact_after

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

theorem BitVec.odd_mul_eq_shiftLeft_mul_of_eq_mul_two_add_one (w : Nat) (x : BitVec w) (n o : Nat)
    (ho : o = n * 2 + 1) : (BitVec.ofNat w o) * x = x + (BitVec.ofNat w n) * (x <<< (1 : Nat))

theorem bools_logical_commute0_and2_thm.extracted_1._2 : ∀ (x : BitVec 1),
  ¬x ^^^ 1#1 = 1#1 → ¬x = 1#1 → 0#1 = 1#1 → False

theorem lshr_32_add_known_32_leading_zeroes_proof : lshr_32_add_known_32_leading_zeroes_before ⊑ lshr_32_add_known_32_leading_zeroes_after

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

theorem udiv_i32_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ¬zeroExtend 32 x = 0 → x = 0 → False

theorem ashrslt_02_09_exact_proof : ashrslt_02_09_exact_before ⊑ ashrslt_02_09_exact_after

theorem lshrult_03_10_exact_thm (e : IntW 4) :
  icmp IntPred.ult (lshr e (const? 4 3) { «exact» := true }) (const? 4 (-6)) ⊑ const? 1 1

theorem intMin_neq_one {w : Nat} (h : w > 1): BitVec.intMin w ≠ 1

theorem t2_proof : t2_before ⊑ t2_after

theorem PR30273_three_bools_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 →
    x_1 = 1#1 →
      ¬(True ∧ (zeroExtend 32 x).saddOverflow 1#32 = true) →
        x = 1#1 →
          ¬(True ∧ (zeroExtend 32 x + 1#32).saddOverflow 1#32 = true) →
            True ∧ (2#32).saddOverflow (zeroExtend 32 x_2) = true ∨
                True ∧ (2#32).uaddOverflow (zeroExtend 32 x_2) = true →
              False

theorem test10_thm (e : IntW 8) :
  trunc 32 (urem (sext 64 (mul (zext 32 e) (const? 32 4))) (const? 64 4)) ⊑ const? 32 0

theorem masked_icmps_mask_notallzeros_bmask_mixed_1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 12#32 != 0#32) &&& ofBool (x &&& 7#32 == 1#32) = ofBool (x &&& 15#32 == 9#32)

theorem rotateleft_9_neg_mask_wide_amount_commute_thm.extracted_1._1 : ∀ (x : BitVec 33) (x_1 : BitVec 9),
  ¬(x &&& 8#33 ≥ ↑33 ∨ 0#33 - x &&& 8#33 ≥ ↑33) →
    True ∧ (zeroExtend 33 x_1 <<< (x &&& 8#33)).sshiftRight' (x &&& 8#33) ≠ zeroExtend 33 x_1 ∨
        True ∧ zeroExtend 33 x_1 <<< (x &&& 8#33) >>> (x &&& 8#33) ≠ zeroExtend 33 x_1 ∨
          x &&& 8#33 ≥ ↑33 ∨ 0#33 - x &&& 8#33 ≥ ↑33 →
      False

theorem ashr_uge_noexact_proof : ashr_uge_noexact_before ⊑ ashr_uge_noexact_after

theorem rem_euclid_non_const_pow2_thm.extracted_1._4 : ∀ (x x_1 : BitVec 8),
  ¬(x ≥ ↑8 ∨ (1#8 <<< x == 0 || 8 != 1 && x_1 == intMin 8 && 1#8 <<< x == -1) = true) →
    ¬ofBool (x_1.srem (1#8 <<< x) <ₛ 0#8) = 1#1 →
      ¬(True ∧ ((-1#8) <<< x).sshiftRight' x ≠ -1#8 ∨ x ≥ ↑8) →
        x_1.srem (1#8 <<< x) = x_1 &&& ((-1#8) <<< x ^^^ -1#8)

theorem shift_xor_multiuse_cmp_or_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 t0_thm.extracted_1._27 : ∀ (x x_1 x_2 x_3 : BitVec 8) (x_4 : BitVec 1),
  x_4 ^^^ 1#1 = 1#1 → ¬x_4 = 1#1 → True → 0#1 = 1#1 → x_1 = x

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

theorem e_600 :
     - 11 *  ~~~(x ^^^ y) - 11 *  ~~~(x &&&  ~~~y) - 1 * (x |||  ~~~y) + 11 * (x ^^^ y) + 5 *  ~~~(x &&& y) + 4 * y + 18 *  ~~~(x ||| y) - 9 *  ~~~(x |||  ~~~y) - 13 * (x &&&  ~~~y) + 21 * (x &&& y) = 2 * x

theorem trunc_sel_equal_sext_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → signExtend 32 42#16 = 42#32

theorem eq_smax4_thm (e e_1 : IntW 32) :
  icmp IntPred.eq (add e_1 (const? 32 3))
      (select (icmp IntPred.sgt e (add e_1 (const? 32 3))) e (add e_1 (const? 32 3))) ⊑
    icmp IntPred.sge (add e_1 (const? 32 3)) e

theorem test_invalid_simplify_sub2_proof : test_invalid_simplify_sub2_before ⊑ test_invalid_simplify_sub2_after

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

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

theorem n1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬x_1 ≥ ↑8 →
    ¬(True ∧ 1#8 <<< x_1 >>> x_1 ≠ 1#8 ∨ x_1 ≥ ↑8) →
      ofBool ((1#8 <<< x_1 ^^^ -1#8) &&& x == x) = ofBool (x &&& 1#8 <<< x_1 == 0#8)

theorem shift_no_xor_multiuse_cmp_with_xor_thm.extracted_1._5 : ∀ (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 lshr_16_to_64_add_zext_basic_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬16#64 ≥ ↑64 → (zeroExtend 64 x_1 + zeroExtend 64 x) >>> 16#64 = zeroExtend 64 (ofBool (x_1 ^^^ -1#16 <ᵤ x))

theorem lowbitmask_casted_shift_proof : lowbitmask_casted_shift_before ⊑ lowbitmask_casted_shift_after

theorem pr33078_2_proof : pr33078_2_before ⊑ pr33078_2_after

theorem uge_swap_or_not_max_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 != -1#8) ||

theorem land_lor_left2_proof : land_lor_left2_before ⊑ land_lor_left2_after

theorem e_1665 :
    2 *  ~~~(a ||| c) + 11 * ((a &&& b) |||  ~~~(b |||  ~~~c)) + 4 *  ~~~(a &&& ( ~~~b ||| c)) - 1 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) + 4 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) + 7 *  ~~~(a &&&  ~~~a) + 2 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) - 1 * (c ^^^  ~~~(a &&& (b ||| c))) + 1 * (a ^^^ ( ~~~b &&& c)) - 7 *  ~~~(b |||  ~~~c) + 11 * (c &&&  ~~~(a ^^^ b)) - 5 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) - 11 * (c ^^^ (a ||| (b ||| c))) + 1 *  ~~~(a ^^^ ( ~~~b ||| c)) - 5 *  ~~~(a &&& c) + 1 * ((a &&& c) |||  ~~~(b ||| c)) + 5 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) - 8 *  ~~~(a ||| (b ||| c)) - 7 *  ~~~(a ||| ( ~~~b ||| c)) + 7 *  ~~~( ~~~a ||| (b ||| c)) - 6 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 19 * ( ~~~a &&& ( ~~~b &&& c)) - 7 * ( ~~~a &&& (b &&& c)) - 18 * (a &&& ( ~~~b &&& c)) - 35 * (a &&& (b &&& c)) = 1 * (a ||| (b ||| c))

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

theorem lshr_add_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(5#8 ≥ ↑8 ∨ (42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true ∨ 5#8 ≥ ↑8) →
    (42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true ∨ 5#8 ≥ ↑8 → False

@[simp] theorem Lets.denote_var_appendInl_pure (lets : Lets d Γ_in .pure Γ_out)
    (e : Expr d Γ_out .pure tys) (V_in : Valuation Γ_in) (v : Var _ u) :
    Lets.denote (var lets e) V_in v.appendInl
    = let xs : HVector .. := e.denoteOp (lets.denote V_in)
      xs[v]

theorem positive_biggershl_shlnuwnsw_proof : positive_biggershl_shlnuwnsw_before ⊑ positive_biggershl_shlnuwnsw_after

theorem e_2318 :
    7 * (e &&&  ~~~(d &&&  ~~~f)) - 2 * ((d &&& f) |||  ~~~(e ||| f)) + 2 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 5 * (d &&&  ~~~e) + 2 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 2 * (d ^^^ e) - 11 *  ~~~(d ^^^ ( ~~~e ||| f)) - 6 * (f ^^^  ~~~(d ||| (e &&& f))) - 2 *  ~~~(d &&& f) - 11 * ((d |||  ~~~e) &&& (e ^^^ f)) - 2 * (d ||| e) - 3 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 2 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (f ^^^ ( ~~~d ||| (e ||| f))) + 11 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 1 * (e ^^^ (d ||| (e ||| f))) + 1 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 7 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 2 * (e ^^^  ~~~(d |||  ~~~f)) - 1 * (d ||| (e ^^^ f)) - 2 * (e ||| (d &&&  ~~~f)) - 3 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 * (f ||| (d ^^^ e)) + 1 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 11 * (e ^^^ (d ||| ( ~~~e &&& f))) - 5 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 5 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 2 * (e ^^^ ( ~~~d ||| (e &&& f))) + 1 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 1 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 1 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 7 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * (f ^^^ ( ~~~d &&& (e ||| f))) - 2 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 1 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 4 *  ~~~(d &&& e) + 5 * (e ^^^ ( ~~~d ||| (e ||| f))) + 2 *  ~~~(e &&&  ~~~f) + 3 * (e ^^^ (d ||| f)) - 11 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 2 * ( ~~~d ||| ( ~~~e ||| f)) - 2 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) + 4 * ( ~~~f ||| (d ^^^ e)) - 2 *  ~~~(d ^^^ e) - 7 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 6 * (f ^^^  ~~~(d &&& (e ||| f))) + 7 * (f ^^^  ~~~(d &&& e)) + 3 * (e ^^^  ~~~(d ||| f)) + 5 *  ~~~(d ||| (e &&& f)) + 1 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 7 *  ~~~( ~~~d &&& (e &&& f)) + 1 *  ~~~(d ^^^ (e ^^^ f)) + 1 *  ~~~(d &&& ( ~~~e ||| f)) - 1 *  ~~~(d ^^^ (e &&& f)) - 1 * (d ^^^ f) - 19 *  ~~~(d ||| (e ||| f)) + 11 *  ~~~(d ||| ( ~~~e ||| f)) + 23 *  ~~~( ~~~d ||| (e ||| f)) + 25 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 49 * ( ~~~d &&& ( ~~~e &&& f)) - 17 * ( ~~~d &&& (e &&& f)) + 42 * (d &&& ( ~~~e &&& f)) + 48 * (d &&& (e &&& f)) = 11 * (e ^^^ ( ~~~d &&& (e ||| f)))

theorem lt_unsigned_to_small_negative_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (zeroExtend 32 x <ₛ BitVec.ofInt 32 (-17)) = 0#1

theorem p0_proof : p0_before ⊑ p0_after

theorem add_eq (a b : BitStream) : a.add b = a + b

theorem t15_proof : t15_before ⊑ t15_after

theorem n0_thm (e : IntW 8) :
  icmp IntPred.ne (LLVM.and e (const? 8 4)) e ⊑
    icmp IntPred.ne (LLVM.and e (const? 8 (-5))) (const? 8 0)

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

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

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

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

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 slt_or_not_max_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 != 127#8) ||

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

theorem add_nosignbit_shl_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬8#32 ≥ ↑32 → (x + 2147418112#32) <<< 8#32 = x <<< 8#32 + BitVec.ofInt 32 (-16777216)

theorem slt_zero_eq_i1_proof : slt_zero_eq_i1_before ⊑ slt_zero_eq_i1_after

theorem lshrugt_01_13_exact_proof : lshrugt_01_13_exact_before ⊑ lshrugt_01_13_exact_after

theorem icmp_ne_sext_ne_otherwise_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (x != 2#32)) != x) = ofBool (x != -1#32)

theorem t0_thm.extracted_1._31 : ∀ (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 → 0#1 = 1#1 → x_1 = x

theorem or_ranges_single_elem_right_proof : or_ranges_single_elem_right_before ⊑ or_ranges_single_elem_right_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_3_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_3_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_3_after

theorem positive_samevar_shlnuwnsw_proof : positive_samevar_shlnuwnsw_before ⊑ positive_samevar_shlnuwnsw_after

theorem logical_and_bitwise_and_icmps_comm3_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.ne (LLVM.and e_2 (const? 8 1)) (const? 8 0)) (icmp IntPred.eq e (const? 8 42)))
      (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.ne (LLVM.and e_2 (const? 8 1)) (const? 8 0)) (icmp IntPred.eq e (const? 8 42)))
      (const? 1 0)

theorem test25_thm.extracted_1._1 : ∀ (x x_1 : BitVec 37),
  ¬(17#37 ≥ ↑37 ∨ 17#37 ≥ ↑37 ∨ 17#37 ≥ ↑37) →
    (x_1 >>> 17#37 + x >>> 17#37) <<< 17#37 = x + (x_1 &&& BitVec.ofInt 37 (-131072)) &&& BitVec.ofInt 37 (-131072)

@[simp] theorem Expr.op_mk {varName} {op : Op} {args} {regions : List (Region Op T)} :
    Expr.op ⟨varName, op, args, regions⟩ = op

theorem add_select_sext_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → 1#64 + signExtend 64 x = 1#64

theorem add_nosignbit_select_shl_thm (e : IntW 32) (e_1 : IntW 1) :
  shl (select e_1 (add e (const? 32 2147418112)) e) (const? 32 8) ⊑
    select e_1 (add (shl e (const? 32 8)) (const? 32 (-16777216))) (shl e (const? 32 8))

theorem test13_proof : test13_before ⊑ test13_after

theorem zext (b : BitVec 8) : (b.zeroExtend 10 |>.zeroExtend 8) = b

theorem lshrugt_03_00_proof : lshrugt_03_00_before ⊑ lshrugt_03_00_after

private theorem if_else_if_then_poison_eq {α : Type} (c₁ c₂ : Prop) [Decidable c₁] [Decidable c₂]
      (x y : PoisonOr α):
    (if c₁ then x else (if c₂ then poison else y)) =
    (if ¬c₁ ∧ c₂ then poison else (if c₁ then x else y))

theorem e_1044 :
     - 1 * (z ^^^ t) + 1 * t + 7 * (z ||| t) - 2 *  ~~~z + 7 *  ~~~(z &&&  ~~~t) - 12 *  ~~~(z |||  ~~~t) - 15 * (z &&& t) = 6 * (z &&&  ~~~t) + 5 *  ~~~(z ||| t)

theorem test2_proof : test2_before ⊑ test2_after

theorem test21_thm.extracted_1._1 : ∀ (x x_1 : BitVec 256), ofBool (x_1 - x != x_1) = ofBool (x != 0#256)

theorem lshrugt_03_11_proof : lshrugt_03_11_before ⊑ lshrugt_03_11_after

theorem AvoidCollision_signExtend_or {x y : BitVec w} :
    (x ||| y).signExtend v = (x.signExtend v) ||

theorem OrZextOr_thm (e : IntW 3) :
  LLVM.or (zext 5 (LLVM.or e (const? 3 3))) (const? 5 8) ⊑ LLVM.or (zext 5 e) (const? 5 11)

theorem test14_thm.extracted_1._1 : ∀ (x : BitVec 35),
  ¬(4#35 ≥ ↑35 ∨ 4#35 ≥ ↑35) → True ∧ (x &&& BitVec.ofInt 35 (-19760) &&& 19744#35 != 0) = true → False

theorem a_proof : a_before ⊑ a_after

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

theorem width5 (w : Nat) (a b : BitVec w) : (a + b = a - a) → a = - b

theorem land_band_left1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), x_1 = 1#1 → x &&& x_1 = x

theorem alive_Select_747 : forall (w : Nat) (A : Bitvec 1)
, TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 1)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (A) %v0;
  %v2 := op:const (0) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:icmp sgt  w %v3;
  %v5 := op:const (0) %v0;
  %v6 := pair:%v5 %v1;
  %v7 := op:sub 1 %v6;
  %v8 := triple:%v4 %v1 %v7;
  %v9 := op:select w %v8;
  %v10 := op:const (0) %v0;
  %v11 := pair:%v9 %v10;
  %v12 := op:icmp slt  w %v11;
  %v13 := op:const (0) %v0;
  %v14 := pair:%v13 %v9;
  %v15 := op:sub w %v14;
  %v16 := triple:%v12 %v9 %v15;
  %v17 := op:select w %v16
  dsl_ret %v17
  ]  ⊑
  TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 1)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (0) %v0;
  %v2 := op:const (A) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:sub 1 %v3;
  %v5 := op:const (0) %v0;
  %v6 := pair:%v2 %v5;
  %v7 := op:icmp slt  1 %v6;
  %v8 := op:const (0) %v0;
  %v9 := pair:%v2 %v8;
  %v10 := op:icmp sgt  1 %v9;
  %v11 := triple:%v10 %v2 %v4;
  %v12 := op:select 1 %v11;
  %v13 := op:const (0) %v0;
  %v14 := pair:%v12 %v13;
  %v15 := op:icmp slt  1 %v14;
  %v16 := op:const (0) %v0;
  %v17 := pair:%v16 %v12;
  %v18 := op:sub 1 %v17;
  %v19 := triple:%v7 %v2 %v4;
  %v20 := op:select 1 %v19
  dsl_ret %v20
  ]

theorem PR42691_8_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x <ₛ 14#32) &&& ofBool (x != BitVec.ofInt 32 (-2147483648)) =
    ofBool (x + 2147483647#32 <ᵤ BitVec.ofInt 32 (-2147483635))

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

theorem trunc_lshr_zext_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬6#32 ≥ ↑32 → ¬6#8 ≥ ↑8 → truncate 8 (zeroExtend 32 x >>> 6#32) = x >>> 6#8

theorem and_logic_and_logic_or_2_thm (e e_1 e_2 : IntW 1) :
  select (LLVM.and e_2 e_1) (const? 1 1) (select e e_2 (const? 1 0)) ⊑
    select e_2 (select e_1 (const? 1 1) e) (const? 1 0)

theorem icmp_ne_mul_nsw_nonequal_proof : icmp_ne_mul_nsw_nonequal_before ⊑ icmp_ne_mul_nsw_nonequal_after

theorem PR42691_3_proof : PR42691_3_before ⊑ PR42691_3_after

theorem logic_and_logic_or_5_proof : logic_and_logic_or_5_before ⊑ logic_and_logic_or_5_after

theorem masked_bit_set_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬x_1 ≥ ↑32 → zeroExtend 32 (ofBool (1#32 <<< x_1 &&& x != 0#32)) = x >>> x_1 &&& 1#32

theorem canonicalize_logic_first_xor_0_nswnuw_proof : canonicalize_logic_first_xor_0_nswnuw_before ⊑ canonicalize_logic_first_xor_0_nswnuw_after

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

theorem e_1142 :
     - 1 *  ~~~(z &&&  ~~~z) + 1 * t - 11 * (z ^^^ t) - 2 *  ~~~(z ^^^ t) + 8 *  ~~~(z ||| t) + 16 *  ~~~(z |||  ~~~t) + 17 * (z &&&  ~~~t) + 2 * (z &&& t) = 5 *  ~~~(z &&& t)

@[bv_automata_nnf] theorem not_eq_prop (p q : Prop) : (¬(p = q)) = (p = ¬q)

theorem xor_signbit_select_ashr_proof : xor_signbit_select_ashr_before ⊑ xor_signbit_select_ashr_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 test_sext2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), x_1 = 1#1 → -1#32 = signExtend 32 1#1

theorem and_or_not_not_wrong_a_thm.extracted_1._1 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  (x_3 &&& x_2 ^^^ -1#32 ||| x_1) &&& (x_1 &&& x ^^^ -1#32) = x_1 &&& x ^^^ (x_1 ||| x_3 &&& x_2 ^^^ -1#32)

theorem andn_or_cmp_4_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 == x) = 1#1 → ofBool (x_1 != x) = 1#1 → True → False

theorem match_signed_proof : match_signed_before ⊑ match_signed_after

theorem negative5_proof : negative5_before ⊑ negative5_after

theorem one_side_fold_eq_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_1 == x_1) = 1#1

theorem test_zext2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), x_1 = 1#1 → 1#32 = zeroExtend 32 1#1

theorem trunc_sandwich_proof : trunc_sandwich_before ⊑ trunc_sandwich_after

theorem e_702 :
    2 *  ~~~x + 2 *  ~~~(x &&& y) - 1 *  ~~~y + 1 * (x ||| y) + 4 * x - 11 *  ~~~(x ^^^ y) + 5 * y + 8 *  ~~~(x ||| y) - 10 *  ~~~(x |||  ~~~y) - 6 * (x &&&  ~~~y) =  - 1 * (x &&& y)

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

@[simp]
lemma BitVec.transport_getElem (f : Fin n2 → Fin n1) (bv : BitVec n1) (i : Nat) (hlt : i < n2) :
    (bv.transport f)[i] = bv.getLsbD (f ⟨i, hlt⟩)

theorem par_proof : par_before ⊑ par_after

theorem icmp_select_var_pred_ne_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == 0#8) = 1#1 → ¬ofBool (x_1 != 0#8) = 1#1 → ofBool (x != x) = 0#1

theorem ult_to_sgt_thm (e e_1 : IntW 8) :
  icmp IntPred.ult (LLVM.xor e_1 (const? 8 127)) (LLVM.xor e (const? 8 127)) ⊑ icmp IntPred.sgt e_1 e

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

theorem main11_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 64#32 == 0#32) ||

theorem src_is_mask_select_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  x_2 = 1#1 →
    ofBool ((x_1 ^^^ x_1 + -1#8) &&& (x ^^^ 123#8) != x ^^^ 123#8) = ofBool (x_1 ^^^ x_1 + -1#8 <ᵤ x ^^^ 123#8)

theorem icmp_shl_nsw_sge0_proof : icmp_shl_nsw_sge0_before ⊑ icmp_shl_nsw_sge0_after

theorem n1_proof : n1_before ⊑ n1_after

theorem shift_no_xor_multiuse_or_thm (e e_1 : IntW 32) :
  mul (select (icmp IntPred.eq (LLVM.and e_1 (const? 32 1)) (const? 32 0)) e (LLVM.or e (const? 32 2)))
      (LLVM.or e (const? 32 2)) ⊑
    mul (LLVM.or e (LLVM.and (shl e_1 (const? 32 1)) (const? 32 2))) (LLVM.or e (const? 32 2))

theorem shl_trunc_bigger_ashr_thm (e : IntW 32) :
  shl (trunc 24 (ashr e (const? 32 12))) (const? 24 3) ⊑
    LLVM.and (trunc 24 (ashr e (const? 32 9)) { «nsw» := true, «nuw» := false }) (const? 24 (-8))

theorem alive_AndOrXor_716 : alive_AndOrXor_716_src ⊑ alive_AndOrXor_716_tgt

theorem not_lshr_bitwidth_mask_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬7#8 ≥ ↑8 → (x_1 >>> 7#8 ^^^ -1#8) &&& x = x &&& (x_1 >>> 7#8 ^^^ -1#8)

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

theorem substitute_constant_and_eq_eq_commute_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == x) = 1#1 → ofBool (x_1 == 42#8) = ofBool (x_1 == 42#8) &&& ofBool (x == 42#8)

theorem negate_sdiv_thm (e e_1 : IntW 8) :
  sub e_1 (LLVM.sdiv e (const? 8 42)) ⊑ add (LLVM.sdiv e (const? 8 (-42))) e_1

theorem no_shift_xor_multiuse_cmp_with_and_proof : no_shift_xor_multiuse_cmp_with_and_before ⊑ no_shift_xor_multiuse_cmp_with_and_after

theorem andn_or_cmp_1_proof : andn_or_cmp_1_before ⊑ andn_or_cmp_1_after

@[simp]
theorem toBitVec_concat_zero (a : BitStream) :
    (a.concat b).toBitVec 0 = 0#0

theorem sext_zext_slt_known_nonneg_proof : sext_zext_slt_known_nonneg_before ⊑ sext_zext_slt_known_nonneg_after

theorem test_imply_not2_thm.extracted_1._5 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  ¬ofBool (x_1 == 0#32) = 1#1 → ofBool (x_1 != 0#32) = 1#1 → 0#1 ||

theorem one_side_fold_sgt_thm.extracted_1._5 : ∀ (x x_1 : BitVec 32) (x_2 : BitVec 1),
  x_2 = 1#1 → x_2 ^^^ 1#1 = 1#1 → False

theorem lshr_neg_slt_zero_thm (e : IntW 8) :
  icmp IntPred.slt (lshr (const? 8 (-17)) e) (const? 8 0) ⊑ icmp IntPred.eq e (const? 8 0)

theorem icmp_sle11_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (x <<< 7#8).sshiftRight' 7#8 ≠ x ∨ 7#8 ≥ ↑8) →
    ofBool (x <<< 7#8 ≤ₛ BitVec.ofInt 8 (-2)) = ofBool (x <ₛ 0#8)

theorem main5f_like_thm (e e_1 e_2 : IntW 32) :
  select (LLVM.or (icmp IntPred.ne (LLVM.and e_2 e_1) e_2) (icmp IntPred.ne (LLVM.and e_2 e) e_2))
      (const? 32 0) (const? 32 1) ⊑
    zext 32 (icmp IntPred.eq (LLVM.and e_2 (LLVM.and e_1 e)) e_2)

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

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

theorem sle_swap_or_not_min_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.sge e_1 e) (const? 1 1) (icmp IntPred.ne e (const? 8 (-128))) ⊑ const? 1 1

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

theorem logic_and_logic_or_7_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 → x = 1#1 → x_1 = 1#1 → 1#1 = x_1

theorem src_is_mask_xor_fail_notmask_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool ((x_1 ^^^ 123#8) &&& (x ^^^ x + -1#8 ^^^ -1#8) != x_1 ^^^ 123#8) =
    ofBool (x ^^^ 0#8 - x ||| x_1 ^^^ BitVec.ofInt 8 (-124) != -1#8)

theorem neg_mask2_lshr_thm (e : IntW 8) :
  sub (const? 8 0) (LLVM.and (lshr e (const? 8 3)) (const? 8 2)) ⊑
    sub (const? 8 0) (LLVM.and (lshr e (const? 8 3)) (const? 8 2)) { «nsw» := true, «nuw» := false }

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_2_logical_thm (e : IntW 32) :
  select (icmp IntPred.ne (LLVM.and e (const? 32 7)) (const? 32 0)) (const? 1 1)
      (icmp IntPred.eq (LLVM.and e (const? 32 3)) (const? 32 0)) ⊑
    const? 1 1

theorem test14_proof : test14_before ⊑ test14_after

theorem neg_or_ashr_i32_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → (0#32 - x ||| x).sshiftRight' 31#32 = signExtend 32 (ofBool (x != 0#32))

theorem e_1652 :
    7 * ((a &&& c) ||| (b &&&  ~~~c)) - 1 * (c ^^^  ~~~(a &&& (b &&& c))) + 2 * ((a &&& b) |||  ~~~(b ||| c)) + 2 * (c ^^^ ( ~~~a ||| (b &&& c))) + 1 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) - 2 *  ~~~(b &&& c) + 3 * ((a &&&  ~~~b) ||| (a ^^^ (b ^^^ c))) - 7 *  ~~~(a &&& (b ^^^ c)) + 5 * (c ^^^ (a ||| (b ||| c))) + 11 * (b &&& (a |||  ~~~c)) + 11 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) - 5 * (b ^^^ (a &&& (b ^^^ c))) + 3 * (b ^^^ (a ||| (b ^^^ c))) + 5 * (c ||| (a ^^^ b)) - 6 * (a ^^^ (b ^^^ c)) + 8 *  ~~~(a ||| (b ||| c)) - 22 *  ~~~(a ||| ( ~~~b ||| c)) - 3 *  ~~~( ~~~a ||| (b ||| c)) - 20 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 7 * ( ~~~a &&& ( ~~~b &&& c)) - 8 * ( ~~~a &&& (b &&& c)) - 12 * (a &&& ( ~~~b &&& c)) - 19 * (a &&& (b &&& c)) = 2 * (c ^^^  ~~~(a &&& ( ~~~b ||| c)))

theorem sgt_swap_and_min_proof : sgt_swap_and_min_before ⊑ sgt_swap_and_min_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_3b_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_3b_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_3b_logical_after

theorem zext_negate_thm (e : IntW 1) : sub (const? 64 0) (zext 64 e) ⊑ sext 64 e

theorem bv_AddSub_1614 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.sub e_1 (LLVM.add e_1 e) ⊑ LLVM.sub (LLVM.const? w 0) e

theorem main3b_logical_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 == 0#32) = 1#1 → 0#1 = 1#1 → 0#32 = zeroExtend 32 (ofBool (x &&& 23#32 != 0#32))

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

theorem and_umin_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (15#32 <ᵤ x) = 1#1 → x &&& BitVec.ofInt 32 (-32) = 0#32

theorem exact_lshr_ne_thm (e : IntW 8) :
  icmp IntPred.ne (lshr (const? 8 4) e { «exact» := true }) (const? 8 1) ⊑
    icmp IntPred.ne e (const? 8 2)

theorem sel_zext_constants_proof : sel_zext_constants_before ⊑ sel_zext_constants_after

theorem lshrugt_03_02_proof : lshrugt_03_02_before ⊑ lshrugt_03_02_after

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

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 e_2424 :
    1 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 11 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 2 * (e ^^^  ~~~(d ||| (e &&& f))) + 2 * (e ^^^ (d &&& f)) - 1 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) - 6 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 1 * (e ^^^ (d ||| (e ||| f))) + 3 * ( ~~~d &&& ( ~~~e ||| f)) + 5 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 1 * ( ~~~d ||| ( ~~~e &&& f)) - 7 * (e ^^^ (d ||| f)) + 3 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 5 * (f &&&  ~~~(d &&&  ~~~e)) - 11 * (f |||  ~~~(d ||| e)) + 5 * ((d &&& f) ||| (e &&&  ~~~f)) + 2 * ( ~~~f &&& (d ^^^ e)) + 7 *  ~~~(d ^^^ (e ||| f)) + 11 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 11 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * (e ^^^ ( ~~~d &&& (e ||| f))) + 1 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 3 * (d ||| (e ^^^ f)) + 11 * (e |||  ~~~(d |||  ~~~f)) + 7 * (f ^^^  ~~~(d ||| e)) + 1 * (d ||| ( ~~~e ||| f)) - 6 * (e ^^^  ~~~(d |||  ~~~f)) - 1 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 3 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 1 * (e ||| (d ^^^ f)) + 7 *  ~~~(d &&& e) - 6 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 3 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 6 *  ~~~(d &&& f) - 7 * (d ^^^ e) - 1 * (d ||| f) - 1 *  ~~~(d &&& (e ^^^ f)) - 1 * ( ~~~f &&&  ~~~(d ^^^ e)) + 7 * (d |||  ~~~f) - 2 * (f ||| (d ^^^ e)) - 1 * (f ^^^ (d ||| (e &&& f))) + 4 * ( ~~~e &&&  ~~~(d ^^^ f)) - 2 *  ~~~( ~~~d ||| (e &&& f)) - 1 * (e |||  ~~~(d ^^^ f)) - 5 *  ~~~(d ^^^ (e ^^^ f)) - 5 * (f ^^^ (d |||  ~~~e)) + 1 * (d ||| e) - 2 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 5 * (e ^^^ f) + 1 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 3 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 5 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 4 * (f &&& (d ||| e)) + 1 * ( ~~~f ||| (d ^^^ e)) - 1 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 2 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 1 * ( ~~~d ||| (e ||| f)) + 3 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 4 *  ~~~(d &&& (e ||| f)) + 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 11 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 5 * (d &&& e) + 2 * ( ~~~e ||| (d ^^^ f)) + 4 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 11 * (e ^^^ (d ||| (e ^^^ f))) - 7 *  ~~~(d |||  ~~~f) - 2 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 5 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 7 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 13 *  ~~~(d ||| (e ||| f)) - 25 *  ~~~(d ||| ( ~~~e ||| f)) + 11 *  ~~~( ~~~d ||| (e ||| f)) - 26 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 1 * ( ~~~d &&& ( ~~~e &&& f)) - 2 * (d &&& ( ~~~e &&& f)) - 11 * (d &&& (e &&& f)) =  - 24 * ( ~~~d &&& (e &&& f)) + 7 *  ~~~(d &&& (e &&& f))

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

theorem lowmask_add_zext_commute_thm (e : IntW 16) (e_1 : IntW 32) :
  LLVM.and (add (mul e_1 e_1) (zext 32 e)) (const? 32 65535) ⊑ zext 32 (add e (trunc 16 (mul e_1 e_1)))

theorem src_fv_ne_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  x_2 = 1#1 → ¬(True ∧ x_1.uaddOverflow 1#8 = true) → ofBool (x_1 + 1#8 ||| x != 0#8) = ofBool (x != 0#8) ||

theorem t0_commutative_thm.extracted_1._8 : ∀ (x : BitVec 8) (x_1 : BitVec 1) (x_2 x_3 : BitVec 8),
  ofBool (x_3 == x_2) = 1#1 → ¬ofBool (x_3 != x_2) = 1#1 → ¬x_1 ^^^ 1#1 = 1#1 → ¬x_1 = 1#1 → False

theorem ashrsgt_03_01_exact_proof : ashrsgt_03_01_exact_before ⊑ ashrsgt_03_01_exact_after

theorem test_and_ne_a_b_thm (e e_1 : IntW 8) (e_2 : IntW 1) :
  select (LLVM.and e_2 (icmp IntPred.ne e_1 e)) e_1 e ⊑ select e_2 e_1 e

theorem demo2 (x : BitVec 64) : BitVec.zeroExtend 64 (BitVec.truncate 32 x) = x &&& 4294967295#64

theorem two_signed_truncation_checks_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x + 512#32 <ᵤ 1024#32) &&& ofBool (x + 128#32 <ᵤ 256#32) = ofBool (x + 128#32 <ᵤ 256#32)

theorem p_commutative0_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ (x_2 &&& x_1 &&& (x &&& (x_2 ^^^ -1#32)) != 0) = true) →
    (x_2 &&& x_1) + ((x_2 ^^^ -1#32) &&& x) = x_2 &&& x_1 ||

theorem e_1033 :
     - 1 * t + 11 *  ~~~(z &&&  ~~~z) + 2 *  ~~~(z ^^^ t) + 3 * (z |||  ~~~t) - 1 *  ~~~t - 15 *  ~~~(z ||| t) - 10 *  ~~~(z |||  ~~~t) = 15 * (z &&& t) + 13 * (z &&&  ~~~t)

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

theorem e_2177 :
    5 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 3 * (e ^^^ (d &&&  ~~~f)) - 11 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 1 * ((d |||  ~~~e) &&& (e ^^^ f)) + 1 * (d |||  ~~~e) + 2 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 1 * (f ^^^ (d ||| (e &&& f))) + 7 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 1 *  ~~~( ~~~d &&& (e ||| f)) + 1 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 3 *  ~~~d + 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 1 * ( ~~~d &&& (e ^^^ f)) + 5 * ((d &&& f) |||  ~~~(e ||| f)) + 4 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 11 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 1 * ( ~~~e |||  ~~~(d ^^^ f)) - 7 * (e ^^^ ( ~~~d &&& (e ||| f))) + 1 *  ~~~(d ^^^ e) - 6 * (f ^^^  ~~~(d ||| e)) - 2 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 7 * (f &&& (d |||  ~~~e)) + 2 * (f |||  ~~~(d ||| e)) - 3 *  ~~~(d ||| (e &&& f)) - 2 * (e ^^^ (d &&& (e ||| f))) - 2 *  ~~~(d ^^^ (e ||| f)) + 11 * (f ^^^  ~~~(d &&& (e &&& f))) + 2 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 2 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 1 *  ~~~(d &&& ( ~~~e &&& f)) + 2 *  ~~~f + 3 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 2 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 3 * (e ^^^ (d &&& ( ~~~e ||| f))) + 2 * (e |||  ~~~(d ||| f)) - 5 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 11 * (e ^^^  ~~~(d &&& f)) + 1 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 6 * (d ^^^ e) - 7 * (d &&& f) + 11 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 3 * (d ^^^ (e ^^^ f)) - 1 *  ~~~(d ||| f) - 6 * d - 25 *  ~~~(d ||| ( ~~~e ||| f)) + 1 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 16 * ( ~~~d &&& ( ~~~e &&& f)) + 2 * ( ~~~d &&& (e &&& f)) + 7 * (d &&& ( ~~~e &&& f)) + 15 * (d &&& (e &&& f)) = 23 *  ~~~( ~~~d ||| (e ||| f))

theorem lshr_lshr_pow2_const_negative_nopow2_1_thm (e : IntW 16) :
  LLVM.and (lshr (lshr (const? 16 2047) e) (const? 16 6)) (const? 16 4) ⊑
    LLVM.and (lshr (const? 16 31) e) (const? 16 4)

theorem lshrult_02_09_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 (-7)) = 1#1

theorem test_eq_0_and_15_add_1_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x + 1#8 &&& 15#8 == 0#8) = ofBool (x &&& 15#8 == 15#8)

theorem test3_proof : test3_before ⊑ test3_after

theorem p_constmask_commutative_proof : p_constmask_commutative_before ⊑ p_constmask_commutative_after

theorem ult_swap_and_max_proof : ult_swap_and_max_before ⊑ ult_swap_and_max_after

theorem scalar_i8_signbit_lshr_and_eq_proof : scalar_i8_signbit_lshr_and_eq_before ⊑ scalar_i8_signbit_lshr_and_eq_after

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

theorem e_91 :
     - 5 * (x |||  ~~~y) - 5 *  ~~~(x &&& y) + 11 *  ~~~(x ||| y) + 10 * (x &&&  ~~~y) + 6 * (x &&& y) = 1 *  ~~~(x &&&  ~~~y) - 6 *  ~~~(x |||  ~~~y)

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

theorem demorgan_nor_use2ac_proof : demorgan_nor_use2ac_before ⊑ demorgan_nor_use2ac_after

theorem Bisim.trans {a b} : a ~ b → b ~ c → a ~ c

theorem bv_239 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.mul (LLVM.sub (LLVM.const? w 0) e_1) (LLVM.sub (LLVM.const? w 0) e) ⊑ LLVM.mul e_1 e

theorem test4_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬31#32 ≥ ↑32 → (x_1 ||| x >>> 31#32) &&& 2#32 = x_1 &&& 2#32

theorem t1_thm.extracted_1._1 : ∀ (x : BitVec 16), ¬(x ≥ ↑16 ∨ x ≥ ↑16) → 15#16 - x ≥ ↑16 → False

theorem icmp_select_implied_cond_swapped_select_proof : icmp_select_implied_cond_swapped_select_before ⊑ icmp_select_implied_cond_swapped_select_after

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

theorem e_1382 :
     - 1 * t + 2 *  ~~~(z ^^^ t) + 3 * (z ||| t) - 2 *  ~~~(z &&&  ~~~t) + 11 * (z |||  ~~~t) - 1 *  ~~~(z &&& t) + 5 * z - 10 *  ~~~(z ||| t) - 19 * (z &&&  ~~~t) - 18 * (z &&& t) =  - 1 * (z ^^^ t)

theorem bitwise_or_logical_or_icmps_comm1_proof : bitwise_or_logical_or_icmps_comm1_before ⊑ bitwise_or_logical_or_icmps_comm1_after

theorem lshr_mul_times_3_div_2_proof : lshr_mul_times_3_div_2_before ⊑ lshr_mul_times_3_div_2_after

theorem sge_swap_or_not_max_commute_proof : sge_swap_or_not_max_commute_before ⊑ sge_swap_or_not_max_commute_after

theorem test11_logical_proof : test11_logical_before ⊑ test11_logical_after

theorem and_not_or_commute4_proof : and_not_or_commute4_before ⊑ and_not_or_commute4_after

theorem test_implied_true_falseval_proof : test_implied_true_falseval_before ⊑ test_implied_true_falseval_after

@[simp]
lemma product_eval {M : NFA α σ} {N : NFA α ς} {w} :
  (M.product accept? N).eval w = M.eval w ×ˢ N.eval w

theorem lshr_add_and_shl_proof : lshr_add_and_shl_before ⊑ lshr_add_and_shl_after

@[simp]
theorem or_sub_xor_eq_and {a b : BitVec w} : (a ||| b) - (a ^^^ b) = a &&& b

theorem trunc_shl_16_i32_i64_proof : trunc_shl_16_i32_i64_before ⊑ trunc_shl_16_i32_i64_after

theorem neg_nsw_sgt_0_proof : neg_nsw_sgt_0_before ⊑ neg_nsw_sgt_0_after

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

theorem pr40493_neg3_proof : pr40493_neg3_before ⊑ pr40493_neg3_after

theorem shl_or_thm.extracted_1._2 : ∀ (x x_1 : BitVec 16),
  ¬((42#16 == 0 || 16 != 1 && x_1 == intMin 16 && 42#16 == -1) = true ∨ 5#16 ≥ ↑16 ∨ 7#16 ≥ ↑16) →
    ¬(12#16 ≥ ↑16 ∨
          (42#16 == 0 || 16 != 1 && x_1 == intMin 16 && 42#16 == -1) = true ∨
            True ∧ (x_1.srem 42#16 <<< 7#16).sshiftRight' 7#16 ≠ x_1.srem 42#16 ∨ 7#16 ≥ ↑16) →
      (x_1.srem 42#16 ||| x <<< 5#16) <<< 7#16 = x <<< 12#16 ||

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

theorem t0_ult_slt_65536_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 65536)) 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 lshrugt_02_14_proof : lshrugt_02_14_before ⊑ lshrugt_02_14_after

theorem substitute_constant_and_eq_eq_proof : substitute_constant_and_eq_eq_before ⊑ substitute_constant_and_eq_eq_after

@[trans]
theorem equal_up_to_trans (e1 : a ≈ʷ b) (e2 : b ≈ʷ c) : a ≈ʷ c

theorem ashrslt_03_06_exact_thm (e : IntW 4) :
  icmp IntPred.slt (ashr e (const? 4 3) { «exact» := true }) (const? 4 6) ⊑ const? 1 1

theorem n15_wrong_comparison_predicate_and_constant_thm.extracted_1._3 : ∀ (x : BitVec 8),
  ¬ofBool (x &&& 15#8 <ᵤ 2#8) = 1#1 →
    ¬ofBool (x &&& 14#8 == 0#8) = 1#1 → x + 16#8 &&& BitVec.ofInt 8 (-16) = (x &&& BitVec.ofInt 8 (-16)) + 16#8

theorem or_xor_tree_0111_thm (e e_1 e_2 : IntW 32) :
  LLVM.or (LLVM.xor (mul e_2 (const? 32 42)) (mul e_1 (const? 32 42)))
      (LLVM.xor (mul e_1 (const? 32 42)) (LLVM.xor (mul e (const? 32 42)) (mul e_2 (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 src_srem_shl_demand_max_signbit_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬((2#32 == 0 || 32 != 1 && x == intMin 32 && 2#32 == -1) = true ∨ 30#32 ≥ ↑32) →
    (2#32 == 0 || 32 != 1 && x == intMin 32 && 2#32 == -1) = true → False

theorem scalar_i32_lshr_and_signbit_eq_X_is_constant1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → ofBool (12345#32 >>> x &&& BitVec.ofInt 32 (-2147483648) == 0#32) = 1#1

theorem main11_thm (e : IntW 32) :
  select
      (LLVM.or (icmp IntPred.eq (LLVM.and e (const? 32 64)) (const? 32 0))
        (icmp IntPred.sge (trunc 8 e) (const? 8 0)))
      (const? 32 2) (const? 32 1) ⊑
    select (icmp IntPred.eq (LLVM.and e (const? 32 192)) (const? 32 192)) (const? 32 1) (const? 32 2)

theorem and_or1_wrong_operand_proof : and_or1_wrong_operand_before ⊑ and_or1_wrong_operand_after

theorem test_lshr__exact_is_unsafe_proof : test_lshr__exact_is_unsafe_before ⊑ test_lshr__exact_is_unsafe_after

theorem sge_or_not_max_logical_proof : sge_or_not_max_logical_before ⊑ sge_or_not_max_logical_after

theorem PR42691_6_proof : PR42691_6_before ⊑ PR42691_6_after

theorem t1_ult_slt_0_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x + 16#32 <ᵤ 144#32) = 1#1 → ofBool (127#32 <ₛ x) = 1#1 ∨ ofBool (x <ₛ BitVec.ofInt 32 (-16)) = 1#1 → False

theorem n2_thm.extracted_1._5 : ∀ (x x_1 : BitVec 32) (x_2 : BitVec 1),
  x_2 = 1#1 → x_2 ^^^ 1#1 = 1#1 → ofBool (x_1 == x) ^^^ 1#1 = 1#1

theorem shl_add_nsw_proof : shl_add_nsw_before ⊑ shl_add_nsw_after

theorem test_sub_nuw__nuw_is_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 2147483647#32 == 1073741824#32) = 1#1 →
    True ∧ (BitVec.ofInt 32 (-2147483648)).usubOverflow (x &&& 2147483647#32) = true → False

theorem alive_820   : alive_820_src ⊑ alive_820_tgt

theorem n2_badmask_proof : n2_badmask_before ⊑ n2_badmask_after

theorem smear_sign_and_widen_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬24#32 ≥ ↑32 → ¬7#8 ≥ ↑8 → signExtend 32 x >>> 24#32 = zeroExtend 32 (x.sshiftRight' 7#8)

theorem test6_thm (e : IntW 64) :
  trunc 32 (lshr (zext 128 e) (const? 128 32)) ⊑
    trunc 32 (lshr e (const? 64 32)) { «nsw» := false, «nuw» := true }

theorem different_size_zext_zext_ne_commute_thm.extracted_1._1 : ∀ (x : BitVec 4) (x_1 : BitVec 7),
  ofBool (zeroExtend 25 x_1 != zeroExtend 25 x) = ofBool (x_1 != zeroExtend 7 x)

theorem or_and_or_pat7_proof : or_and_or_pat7_before ⊑ or_and_or_pat7_after

theorem trunc_shl_shl_infloop_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬(1#64 ≥ ↑64 ∨ 2#64 ≥ ↑64) → ¬3#32 ≥ ↑32 → truncate 32 (x <<< 1#64 <<< 2#64) = truncate 32 x <<< 3#32

theorem is_ascii_alphabetic_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.saddOverflow (BitVec.ofInt 32 (-65)) = true) →
    ofBool (x + BitVec.ofInt 32 (-65) <ᵤ 26#32) = 1#1 →
      1#1 = ofBool ((x &&& BitVec.ofInt 32 (-33)) + BitVec.ofInt 32 (-65) <ᵤ 26#32)

theorem test37_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ (x * 7#32 &&& 240#32).msb = true) →
    zeroExtend 64 x * 7#64 &&& 240#64 = zeroExtend 64 (x * 7#32 &&& 240#32)

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

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

theorem e_2039 :
    11 * ((d ^^^ e) ||| (d ^^^ f)) + 1 * (f ^^^  ~~~(d |||  ~~~e)) - 6 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) - 2 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 1 * (e ^^^  ~~~(d &&& f)) + 2 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * ( ~~~d &&& (e ^^^ f)) - 2 * ((d ||| e) &&& (e ^^^ f)) - 1 * ( ~~~e |||  ~~~(d ^^^ f)) - 1 *  ~~~( ~~~d &&& (e &&& f)) - 1 *  ~~~(d &&& (e &&& f)) + 11 * (e ^^^  ~~~(d &&& (e ||| f))) - 2 * (e ^^^ (d ||| f)) + 5 * ((e &&& f) ||| (d &&& (e ||| f))) + 3 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 4 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 2 * (f ^^^  ~~~(d &&& (e &&& f))) - 1 *  ~~~(d &&& (e ||| f)) - 5 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) - 1 * (e ^^^  ~~~(d |||  ~~~f)) - 1 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 1 *  ~~~(d &&& ( ~~~e ||| f)) - 5 * (d ^^^ ( ~~~e &&& f)) + 1 * (f &&&  ~~~(d ^^^ e)) - 3 *  ~~~( ~~~d ||| ( ~~~e &&& f)) + 1 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 2 * (f |||  ~~~(d ||| e)) - 3 *  ~~~(d ||| (e ||| f)) + 3 *  ~~~(d ||| ( ~~~e ||| f)) + 1 *  ~~~( ~~~d ||| (e ||| f)) - 8 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 2 * ( ~~~d &&& ( ~~~e &&& f)) - 21 * ( ~~~d &&& (e &&& f)) - 1 * (d &&& ( ~~~e &&& f)) - 10 * (d &&& (e &&& f)) = 3 * (d |||  ~~~e)

theorem poison_ne_value (a : α) :
    @Ne (no_index _) poison (value a)

theorem const_sub_const_sub_thm (e : IntW 32) : sub (const? 32 2) (sub (const? 32 8) e) ⊑ add e (const? 32 (-6))

theorem e_1523 :
    2 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) + 1 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 2 * (b |||  ~~~(a |||  ~~~c)) - 1 * ((a &&& c) ||| (b &&&  ~~~c)) - 3 *  ~~~(a ||| (b ||| c)) - 1 *  ~~~(a ||| ( ~~~b ||| c)) - 3 *  ~~~( ~~~a ||| (b ||| c)) - 1 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 4 * ( ~~~a &&& (b &&& c)) - 2 * (a &&& ( ~~~b &&& c)) - 1 * (a &&& (b &&& c)) = 4 * ( ~~~a &&& ( ~~~b &&& c))

theorem signbit_splat_mask_thm.extracted_1._2 : ∀ (x : BitVec 16) (x_1 : BitVec 8),
  ¬7#8 ≥ ↑8 → ¬ofBool (x_1 <ₛ 0#8) = 1#1 → signExtend 16 (x_1.sshiftRight' 7#8) &&& x = 0#16

theorem test_mul_nsw__none_are_safe_proof : test_mul_nsw__none_are_safe_before ⊑ test_mul_nsw__none_are_safe_after

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

theorem f_t15_t01_t09_proof : f_t15_t01_t09_before ⊑ f_t15_t01_t09_after

theorem test_cast_select_proof : test_cast_select_before ⊑ test_cast_select_after

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

theorem lshrult_01_07_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬1#4 ≥ ↑4 → ofBool (x >>> 1#4 <ᵤ 7#4) = ofBool (x <ᵤ BitVec.ofInt 4 (-2))

theorem ugt_or_not_min_commute_logical_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x != 0#8) = 1#1 → 1#1 = ofBool (x != 0#8)

theorem negtest_near_pow2_cmpval_ashr_wrong_cmp_pred_proof : negtest_near_pow2_cmpval_ashr_wrong_cmp_pred_before ⊑ negtest_near_pow2_cmpval_ashr_wrong_cmp_pred_after

theorem e_796 :
    1 * (z ^^^ t) + 1 *  ~~~(z ^^^ t) - 1 *  ~~~(z ||| t) - 1 * (z &&&  ~~~t) + 10 * (z &&& t) =  - 10 *  ~~~(z |||  ~~~t) + 11 * t

@[bv_multi_width_normalize] theorem not_eq_prop (p q : Prop) : (¬(p = q)) = (p = ¬q)

theorem test3_logical_thm (e e_1 : IntW 32) :
  select (icmp IntPred.eq (sub e_1 e { «nsw» := true, «nuw» := false }) (const? 32 0)) (const? 1 1)
      (icmp IntPred.eq (sub e_1 e { «nsw» := true, «nuw» := false }) (const? 32 31)) ⊑
    select (icmp IntPred.eq e_1 e) (const? 1 1)
      (icmp IntPred.eq (sub e_1 e { «nsw» := true, «nuw» := false }) (const? 32 31))

theorem e_2358 :
     - 2 * ((d ^^^ e) &&& (d ^^^ f)) + 4 *  ~~~(d ^^^ (e ||| f)) - 5 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 2 * e - 11 * ((d &&& e) ^^^ (e |||  ~~~f)) + 1 *  ~~~(e &&&  ~~~f) - 7 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 1 * (e ^^^ (d ||| ( ~~~e &&& f))) + 2 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 3 * (d |||  ~~~e) - 1 *  ~~~(d |||  ~~~f) + 3 *  ~~~(d &&& ( ~~~e &&& f)) - 1 * (e &&&  ~~~(d &&&  ~~~f)) - 3 * (e ||| (d &&& f)) - 2 * (d ||| ( ~~~e &&& f)) - 6 * ( ~~~d &&& (e ^^^ f)) + 2 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 1 *  ~~~(d &&&  ~~~d) - 11 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 * ( ~~~d ||| (e &&& f)) - 2 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 11 * (f ^^^  ~~~(d &&& e)) - 5 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 3 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 1 * (d ||| (e &&& f)) - 3 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 3 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 5 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 11 *  ~~~( ~~~d &&& (e ^^^ f)) + 1 * (f ^^^  ~~~(d &&&  ~~~e)) + 5 *  ~~~(d ||| ( ~~~e &&& f)) - 11 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 1 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 5 *  ~~~( ~~~d ||| (e &&& f)) - 3 * (f &&&  ~~~(d &&&  ~~~e)) + 3 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 1 * (f &&& (d ^^^ e)) + 2 * ( ~~~f &&& (d ^^^ e)) + 3 *  ~~~(d ^^^ ( ~~~e &&& f)) - 2 * (e ^^^  ~~~(d &&& f)) - 5 * (e &&&  ~~~(d ^^^ f)) + 5 *  ~~~f - 11 * (f ||| (d &&&  ~~~e)) - 1 * (e &&& f) + 4 * (d &&&  ~~~f) - 6 * (f ^^^ ( ~~~d ||| (e &&& f))) - 6 * (e &&&  ~~~f) - 2 * (d ^^^ (e ||| f)) + 2 * ((e &&& f) ||| (d &&& (e ||| f))) + 4 *  ~~~(d &&&  ~~~e) - 6 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 1 * (e ^^^ (d &&&  ~~~f)) + 11 * (d ^^^ (e &&& f)) + 7 * (f ^^^ (d ||| ( ~~~e &&& f))) + 5 *  ~~~(e |||  ~~~f) - 1 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 11 * (f &&&  ~~~(d &&& e)) + 4 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 3 *  ~~~(d ||| (e ||| f)) + 17 *  ~~~(d ||| ( ~~~e ||| f)) - 10 *  ~~~( ~~~d ||| (e ||| f)) - 17 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 41 * ( ~~~d &&& ( ~~~e &&& f)) + 13 * ( ~~~d &&& (e &&& f)) + 10 * (d &&& ( ~~~e &&& f)) + 29 * (d &&& (e &&& f)) =  - 2 * (e ^^^ (d &&& (e ||| f)))

theorem test20_thm (e : IntW 8) : LLVM.and (lshr e (const? 8 7)) (const? 8 1) ⊑ lshr e (const? 8 7)

theorem test11_proof : test11_before ⊑ test11_after

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

theorem icmp_slt_0_and_icmp_sge_neg1_i64_fail_proof : icmp_slt_0_and_icmp_sge_neg1_i64_fail_before ⊑ icmp_slt_0_and_icmp_sge_neg1_i64_fail_after

theorem ashr_ult_10_proof : ashr_ult_10_before ⊑ ashr_ult_10_after

theorem smear_set_bit_thm (e : IntW 32) :
  sext 32 (ashr (trunc 8 e) (const? 8 7)) ⊑ ashr (shl e (const? 32 24)) (const? 32 31)

theorem main5c_like_logical_thm.extracted_1._8 : ∀ (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 0#1

@[grind ., simp, aesop 50% unsafe]
lemma RawCNFA.WF.trans_src_lt' {m : RawCNFA A} (hwf : m.WF) :
    ∀ {s a}, (s, a) ∈ m.trans → s ∈ m.states

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

theorem t0_proof : t0_before ⊑ t0_after

theorem PR2539_A_thm (e : IntW 1) : icmp IntPred.slt (zext 32 e) (const? 32 1) ⊑ LLVM.xor e (const? 1 1)

theorem and_congr (e1 : a ≈ʷ b) (e2 : c ≈ʷ d) : (a &&& c) ≈ʷ (b &&& d)

theorem and_xor_commute2_thm (e e_1 : IntW 32) :
  LLVM.xor (LLVM.and (LLVM.udiv (const? 32 42) e_1) (LLVM.udiv (const? 32 42) e)) (LLVM.udiv (const? 32 42) e) ⊑
    LLVM.and (LLVM.udiv (const? 32 42) e) (LLVM.xor (LLVM.udiv (const? 32 42) e_1) (const? 32 (-1)))

theorem alive_275_2   : alive_275_2_src ⊑ alive_275_2_tgt

theorem fold_sext_to_and_wrong2_proof : fold_sext_to_and_wrong2_before ⊑ fold_sext_to_and_wrong2_after

theorem main5f_like_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 → True → 0#32 = zeroExtend 32 (ofBool (x_2 &&& x == x_2))

theorem eq_21_comm_and_proof : eq_21_comm_and_before ⊑ eq_21_comm_and_after

theorem lor_land_right1_thm (e e_1 : IntW 1) : select e_1 (select e_1 (const? 1 1) e) (const? 1 0) ⊑ e_1

theorem tctx_at_1 : tctx ⟨1, by omega⟩ = WidthExpr.var ⟨0, by omega⟩

theorem f_var1_commutative_and_proof : f_var1_commutative_and_before ⊑ f_var1_commutative_and_after

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 lshr_xor_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(3#8 ≥ ↑8 ∨ (42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true ∨ 3#8 ≥ ↑8) →
    (42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true ∨ 3#8 ≥ ↑8 → False

theorem lshrult_01_10_exact_proof : lshrult_01_10_exact_before ⊑ lshrult_01_10_exact_after

lemma formula_predicate_match {p : Predicate} :
    p.denote w vars ↔ (formula_of_predicate p).sat' (vars[·]!)

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 uge_umin4_proof : uge_umin4_before ⊑ uge_umin4_after

theorem icmp_power2_and_icmp_shifted_mask_swapped_2147483648_1610612736_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 1610612736#32 != 1610612736#32) &&& ofBool (x <ᵤ BitVec.ofInt 32 (-2147483648)) =
    ofBool (x <ᵤ 1610612736#32)

theorem ule_umax4_proof : ule_umax4_before ⊑ ule_umax4_after

theorem ashrsgt_02_12_exact_proof : ashrsgt_02_12_exact_before ⊑ ashrsgt_02_12_exact_after

theorem select_xor_icmp_meta_proof : select_xor_icmp_meta_before ⊑ select_xor_icmp_meta_after

theorem and_two_ranges_to_mask_and_range_no_add_on_one_range_proof : and_two_ranges_to_mask_and_range_no_add_on_one_range_before ⊑ and_two_ranges_to_mask_and_range_no_add_on_one_range_after

theorem trunc_ashr_proof : trunc_ashr_before ⊑ trunc_ashr_after

theorem select_2_proof : select_2_before ⊑ select_2_after

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

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

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

theorem ashr_mul_sign_bits_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬3#32 ≥ ↑32 →
    ¬(True ∧ (signExtend 16 x_1).smulOverflow (signExtend 16 x) = true ∨ 3#16 ≥ ↑16) →
      truncate 16 ((signExtend 32 x_1 * signExtend 32 x).sshiftRight' 3#32) =
        (signExtend 16 x_1 * signExtend 16 x).sshiftRight' 3#16

private theorem sge_eq_sle (A B : BitVec w) : (A ≥ₛ B) = (B ≤ₛ A)

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

theorem shl_add_log_may_cause_poison_pr62175_with_nuw_proof : shl_add_log_may_cause_poison_pr62175_with_nuw_before ⊑ shl_add_log_may_cause_poison_pr62175_with_nuw_after

theorem ult_umin2_proof : ult_umin2_before ⊑ ult_umin2_after

theorem icmp_eq_zext_eq_non_boolean_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (zeroExtend 32 (ofBool (x == 2#32)) == x) = ofBool (x == 0#32)

theorem test3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.ssubOverflow x = true ∨ True ∧ x_1.ssubOverflow x = true) → True ∧ x_1.ssubOverflow x = true → False

@[simp] theorem getElem_map (xs : HVector A as) (v : Var ⟨as⟩ a) :
    (xs.map f)[v] = f _ xs[v]

theorem main6b_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 == 3#32) &&& ofBool (x &&& 16#32 != 0#32) = 1#1 →
    1#32 = zeroExtend 32 (ofBool (x &&& 23#32 != 19#32))

theorem test15_proof : test15_before ⊑ test15_after

theorem test9_proof : test9_before ⊑ test9_after

theorem trunc_equality_nsw_zext_proof : trunc_equality_nsw_zext_before ⊑ trunc_equality_nsw_zext_after

theorem lshrugt_02_11_thm (e : IntW 4) : icmp IntPred.ugt (lshr e (const? 4 2)) (const? 4 (-5)) ⊑ const? 1 0

theorem udiv_exact_eq_1_thm (e e_1 : IntW 8) :
  icmp IntPred.ne (LLVM.udiv e_1 e { «exact» := true }) (const? 8 1) ⊑ icmp IntPred.ne e_1 e

theorem trunc_ashr_trunc_outofrange_proof : trunc_ashr_trunc_outofrange_before ⊑ trunc_ashr_trunc_outofrange_after

theorem logical_and_logical_and_icmps_comm3_proof : logical_and_logical_and_icmps_comm3_before ⊑ logical_and_logical_and_icmps_comm3_after

theorem icmp_eq_and_pow2_lshr_pow2_case2_proof : icmp_eq_and_pow2_lshr_pow2_case2_before ⊑ icmp_eq_and_pow2_lshr_pow2_case2_after

theorem trunc_lshr_big_mask_proof : trunc_lshr_big_mask_before ⊑ trunc_lshr_big_mask_after

theorem ofBitVecZextMsb_EqualUpTo_ofBitVecSext
  (x : BitVec w) :
  EqualUpTo (w + 1)
    (BitStream.ofBitVecZextMsb x)
    (BitStream.concat false (BitStream.ofBitVecSext x))

theorem band_land_left2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), ¬x_1 &&& x = 1#1 → 0#1 = x_1 &&& x

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

theorem t0_commutative_thm.extracted_1._18 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1) (x_3 x_4 : BitVec 8),
  ¬ofBool (x_4 == x_3) = 1#1 → ¬ofBool (x_4 != x_3) = 1#1 → ¬0#1 = 1#1 → ¬x_2 = 1#1 → x = x_1

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_2204 :
    4 * (e ^^^ (d ||| (e &&& f))) + 4 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 11 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 3 *  ~~~(d |||  ~~~e) - 2 * (d |||  ~~~e) - 7 * ((d ^^^ e) &&& (d ^^^ f)) - 1 *  ~~~(d &&&  ~~~d) + 5 * (e ^^^  ~~~(d &&& (e &&& f))) - 1 * (e ^^^ ( ~~~d ||| (e &&& f))) + 1 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 6 *  ~~~(d ^^^ ( ~~~e ||| f)) - 2 * (f ^^^ (d &&& ( ~~~e ||| f))) + 5 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 5 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 11 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 6 * (e ^^^  ~~~(d ||| (e &&& f))) - 1 * ((d &&& e) |||  ~~~(e ||| f)) + 5 *  ~~~(d |||  ~~~f) - 11 *  ~~~(d ^^^ (e ||| f)) + 1 * (e |||  ~~~(d ^^^ f)) + 11 * (e &&&  ~~~f) - 6 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 3 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 2 * (f ^^^  ~~~(d &&& (e ||| f))) + 1 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 1 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 6 * (d &&& (e ||| f)) + 7 * ( ~~~e |||  ~~~(d ^^^ f)) - 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 4 *  ~~~(d ^^^ (e ^^^ f)) + 1 * (e ^^^ (d |||  ~~~f)) - 2 * ((d &&& f) ||| (e &&&  ~~~f)) + 5 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 11 * (f ^^^  ~~~(d &&& (e &&& f))) - 5 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 7 *  ~~~(d &&& e) - 7 * (d &&& f) - 1 * (e ^^^  ~~~(d &&& f)) + 2 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 1 * (d &&&  ~~~e) - 1 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 2 *  ~~~(e ||| f) + 2 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 2 *  ~~~(d &&& ( ~~~e ||| f)) - 11 *  ~~~(d ||| (e ||| f)) - 40 *  ~~~(d ||| ( ~~~e ||| f)) + 11 *  ~~~( ~~~d ||| (e ||| f)) - 11 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 6 * ( ~~~d &&& ( ~~~e &&& f)) + 15 * ( ~~~d &&& (e &&& f)) + 21 * (d &&& ( ~~~e &&& f)) + 17 * (d &&& (e &&& f)) = 3 * (d ||| ( ~~~e &&& f)) - 1 * ((d |||  ~~~e) &&& (e ^^^ f))

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 15#32 != 8#32) ||

lemma RawCNFA.autMsbSet_wf : autMsbSet.WF

theorem lshr_exact_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(2#8 ≥ ↑8 ∨ 2#8 ≥ ↑8) → (x <<< 2#8 + 4#8) >>> 2#8 = x + 1#8 &&& 63#8

theorem t0_proof : t0_before ⊑ t0_after

theorem test18_proof : test18_before ⊑ test18_after

theorem lshr_sext_i1_to_i128_thm (e : IntW 1) :
  lshr (sext 128 e) (const? 128 42) ⊑ select e (const? 128 77371252455336267181195263) (const? 128 0)

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

theorem ult_and_max_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 <ᵤ x) = 1#1 → ofBool (x_1 == -1#8) = 0#1

theorem not_and_and_or_no_or_proof : not_and_and_or_no_or_before ⊑ not_and_and_or_no_or_after

theorem test_invert_demorgan_or2_proof : test_invert_demorgan_or2_before ⊑ test_invert_demorgan_or2_after

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

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

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

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

theorem rawspeed_signbit_proof : rawspeed_signbit_before ⊑ rawspeed_signbit_after

theorem ugt_swap_or_not_min_commute_logical_thm.extracted_1._3 : ∀ (x x_1 : BitVec 823),
  ¬ofBool (x_1 != 0#823) = 1#1 → ofBool (x <ᵤ x_1) = ofBool (x_1 != 0#823)

theorem not_cmp_constant_thm (e : IntW 32) :
  icmp IntPred.ugt (LLVM.xor e (const? 32 (-1))) (const? 32 42) ⊑
    icmp IntPred.ult e (const? 32 (-43))

theorem ashr_shl_constants_proof : ashr_shl_constants_before ⊑ ashr_shl_constants_after

theorem test11e_proof : test11e_before ⊑ test11e_after

theorem test16_proof : test16_before ⊑ test16_after

theorem sgt_smin1_proof : sgt_smin1_before ⊑ sgt_smin1_after

theorem widget_proof : widget_before ⊑ widget_after

theorem select_icmp_ne_0_and_1073741824_or_8_proof : select_icmp_ne_0_and_1073741824_or_8_before ⊑ select_icmp_ne_0_and_1073741824_or_8_after

theorem negate_ashr_thm (e e_1 : IntW 8) : sub e_1 (ashr e (const? 8 7)) ⊑ add (lshr e (const? 8 7)) e_1

theorem select_lshr_icmp_const_reordered_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x <ᵤ 32#32) = 1#1 → ¬5#32 ≥ ↑32 → 0#32 = x >>> 5#32

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 t1_otherbitwidth_proof : t1_otherbitwidth_before ⊑ t1_otherbitwidth_after

theorem lshrult_01_11_proof : lshrult_01_11_before ⊑ lshrult_01_11_after

theorem ne_210_thm (e e_1 : IntW 32) :
  LLVM.or (icmp IntPred.ne (trunc 8 (lshr e_1 (const? 32 16))) (trunc 8 (lshr e (const? 32 16))))
      (LLVM.or (icmp IntPred.ne (trunc 8 e_1) (trunc 8 e))
        (icmp IntPred.ne (trunc 8 (lshr e_1 (const? 32 8))) (trunc 8 (lshr e (const? 32 8))))) ⊑
    icmp IntPred.ne (trunc 24 e_1) (trunc 24 e)

theorem add_select_sext_thm (e : IntW 1) :
  add (select e (const? 64 64) (const? 64 1)) (sext 64 e) ⊑ select e (const? 64 63) (const? 64 1)

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

theorem positive_with_icmp_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x <ᵤ 512#32) = 1#1 → ofBool (x + 128#32 <ᵤ 256#32) = ofBool (x <ᵤ 128#32)

@[simp]
theorem Factor.denote_width_zero  (f : Factor) (env : Env 0) : f.denote env = 0

theorem e_2397 :
     - 11 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 2 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 3 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 3 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) + 3 * (d ||| (e &&& f)) + 2 * ((d ||| e) &&& (e ^^^ f)) - 2 * (f ^^^  ~~~(d &&& (e ||| f))) - 1 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 5 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 1 * (f ^^^ (d ||| ( ~~~e ||| f))) + 11 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 5 * ((d &&&  ~~~e) ||| (e ^^^ f)) - 2 * (f &&& (d ||| e)) - 6 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 5 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 1 *  ~~~(d &&& ( ~~~e &&& f)) + 3 * (e &&& (d ^^^ f)) + 1 * (f |||  ~~~(d |||  ~~~e)) - 1 * (f ^^^ (d &&& (e ||| f))) - 7 * (e ^^^ (d &&&  ~~~f)) + 2 * (d ^^^ (e ||| f)) + 1 * (f ^^^ ( ~~~d &&& (e ||| f))) - 1 * (d &&&  ~~~e) + 1 *  ~~~(d ^^^ ( ~~~e ||| f)) - 5 * (d |||  ~~~e) + 7 * (f ^^^  ~~~(d &&& (e &&& f))) - 2 * (d &&& ( ~~~e ||| f)) - 1 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 2 * ( ~~~d ||| ( ~~~e &&& f)) - 6 * ( ~~~e &&& (d ^^^ f)) - 1 *  ~~~e - 6 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 5 * (f ^^^ (d &&& ( ~~~e ||| f))) + 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 2 * ((d &&& f) ^^^ (e ||| f)) - 2 *  ~~~(d &&& (e ||| f)) + 2 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 1 * (d ^^^ ( ~~~e ||| f)) + 2 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 3 * ( ~~~e |||  ~~~(d ^^^ f)) - 7 * (f ^^^ (d |||  ~~~e)) - 5 * (f ^^^ (d ||| ( ~~~e &&& f))) + 7 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 1 * ((d &&& e) |||  ~~~(e ||| f)) + 11 * (e ||| (d ^^^ f)) + 1 * (f ^^^ (d &&& e)) - 6 *  ~~~(d &&&  ~~~d) + 7 * (f &&&  ~~~(d &&&  ~~~e)) - 2 * (f ^^^ (d ||| (e &&& f))) - 6 *  ~~~(d ^^^ ( ~~~e &&& f)) + 1 * ((d ^^^ e) ||| (d ^^^ f)) + 2 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 1 * ( ~~~f &&&  ~~~(d ^^^ e)) + 4 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 3 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 7 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 1 * (e ^^^ f) + 7 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 1 * ((d &&& f) ||| (e &&&  ~~~f)) - 2 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 4 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 7 * (e ^^^ (d &&& (e ||| f))) - 1 * ( ~~~e &&&  ~~~(d ^^^ f)) + 4 * (e ||| (d &&&  ~~~f)) + 33 *  ~~~(d ||| (e ||| f)) - 15 *  ~~~(d ||| ( ~~~e ||| f)) + 33 *  ~~~( ~~~d ||| (e ||| f)) - 19 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 21 * ( ~~~d &&& ( ~~~e &&& f)) + 1 * ( ~~~d &&& (e &&& f)) + 12 * (d &&& ( ~~~e &&& f)) - 1 * (d &&& (e &&& f)) = 7 * (f ^^^  ~~~(d &&& e))

theorem sdiv4_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.smod 3#32 ≠ 0 ∨ (3#32 == 0 || 32 != 1 && x == intMin 32 && 3#32 == -1) = true) → x.sdiv 3#32 * 3#32 = x

@[simp]
theorem Std.HashSet.isEmpty_union_iff_isEmpty [BEq α] [Hashable α] [LawfulBEq α] {m₁ m₂ : HashSet α} :
    (m₁.union m₂).isEmpty ↔ m₁.isEmpty ∧ m₂.isEmpty

theorem test_sub__nsw_is_safe_proof : test_sub__nsw_is_safe_before ⊑ test_sub__nsw_is_safe_after

theorem nonexact_lshr_eq_exactdiv_proof : nonexact_lshr_eq_exactdiv_before ⊑ nonexact_lshr_eq_exactdiv_after

theorem trunc_ashr_trunc_thm.extracted_1._1 : ∀ (x : BitVec 64), ¬8#32 ≥ ↑32 → 8#64 ≥ ↑64 → False

theorem negate_add_with_single_negatible_operand_depth2_thm (e e_1 : IntW 8) :
  sub (const? 8 0) (mul (add e_1 (const? 8 21)) e) ⊑ mul (sub (const? 8 (-21)) e_1) e

theorem test3_proof : test3_before ⊑ test3_after

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

theorem 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 t9_lshr_proof : t9_lshr_before ⊑ t9_lshr_after

theorem appendInl_toCons {v : Var Γ t} :
    v.toCons (t':=t').appendInl (Δ := Δ) = v.appendInl.toCons

theorem lshr_xor_or_good_mask_thm (e e_1 : IntW 8) :
  LLVM.or (lshr e_1 (const? 8 4)) (LLVM.xor (lshr e (const? 8 4)) (const? 8 48)) ⊑
    LLVM.or (lshr (LLVM.or e e_1) (const? 8 4)) (const? 8 48) { «disjoint» := true }

theorem no_shift_no_xor_multiuse_cmp_or_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 &&& 4096#32 == 0#32) = 1#1 →
    (x_1 ||| 4096#32) * x * (x_1 ||| 4096#32) = (x_1 ||| x_2 &&& 4096#32) * x * (x_1 ||| 4096#32)

theorem bools2_logical_commute1_thm.extracted_1._16 : ∀ (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 → x = x_2

theorem test18_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.saddOverflow 1#32 = true ∨
        True ∧
          (x_1 + 1#32).saddOverflow (x &&& BitVec.ofInt 32 (-1431655766) ^^^ BitVec.ofInt 32 (-1431655766)) = true) →
    x_1 + 1#32 + (x &&& BitVec.ofInt 32 (-1431655766) ^^^ BitVec.ofInt 32 (-1431655766)) =
      x_1 - (x ||| 1431655765#32)

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

theorem sle_smax1_proof : sle_smax1_before ⊑ sle_smax1_after

theorem PR2539_B_proof : PR2539_B_before ⊑ PR2539_B_after

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

theorem main6d_logical_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 != 3#32) = 1#1 →
    ofBool (x &&& 16#32 == 0#32) = 1#1 → 0#32 = zeroExtend 32 (ofBool (x &&& 23#32 == 19#32))

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

theorem ugt_umax1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x <ᵤ x_1) = 1#1 → ofBool (x_1 <ᵤ x_1) = ofBool (x_1 <ᵤ x)

theorem lshrult_03_01_exact_proof : lshrult_03_01_exact_before ⊑ lshrult_03_01_exact_after

theorem lshrult_01_15_exact_proof : lshrult_01_15_exact_before ⊑ lshrult_01_15_exact_after

theorem xor_or_proof : xor_or_before ⊑ xor_or_after

theorem shl_nuw_add_nuw_thm (e : IntW 32) :
  shl (const? 32 1) (add e (const? 32 1) { «nsw» := false, «nuw» := true }) { «nsw» := false, «nuw» := true } ⊑
    shl (const? 32 2) e { «nsw» := false, «nuw» := true }

theorem shl_lshr_pow2_not_const_case2_thm (e : IntW 16) :
  LLVM.xor (LLVM.and (lshr (shl (const? 16 16) e) (const? 16 3)) (const? 16 8)) (const? 16 8) ⊑
    select (icmp IntPred.eq e (const? 16 2)) (const? 16 0) (const? 16 8)

theorem eval_sext_multi_use_in_one_inst_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ (truncate 16 x &&& 14#16).smulOverflow (truncate 16 x &&& 14#16) = true ∨
        True ∧ (truncate 16 x &&& 14#16).umulOverflow (truncate 16 x &&& 14#16) = true) →
    True ∧ (truncate 16 x &&& 14#16).smulOverflow (truncate 16 x &&& 14#16) = true ∨
        True ∧ (truncate 16 x &&& 14#16).umulOverflow (truncate 16 x &&& 14#16) = true ∨
          True ∧ ((truncate 16 x &&& 14#16) * (truncate 16 x &&& 14#16) &&& BitVec.ofInt 16 (-32768) != 0) = true →
      False

theorem lshrult_03_15_exact_proof : lshrult_03_15_exact_before ⊑ lshrult_03_15_exact_after

theorem sge_swap_and_max_proof : sge_swap_and_max_before ⊑ sge_swap_and_max_after

theorem test10_proof : test10_before ⊑ test10_after

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

theorem select_constants_and_icmp_eq0_proof : select_constants_and_icmp_eq0_before ⊑ select_constants_and_icmp_eq0_after

theorem icmp_sle11_thm (e : IntW 8) :
  icmp IntPred.sle (shl e (const? 8 7) { «nsw» := true, «nuw» := false }) (const? 8 (-2)) ⊑
    icmp IntPred.slt e (const? 8 0)

@[simp] theorem liftEffect_impure [Pure m] {e} (hle : e ≤ impure) :
    liftEffect hle (α := α) (m := m) = match e with

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_2_logical_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 7)) (const? 32 0))
      (icmp IntPred.ne (LLVM.and e (const? 32 3)) (const? 32 0)) (const? 1 0) ⊑
    const? 1 0

theorem e_1553 :
     - 6 *  ~~~(a ^^^ c) - 1 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 5 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 1 * (b ||| (a ^^^ c)) - 1 *  ~~~( ~~~a &&& ( ~~~b ||| c)) + 5 * ( ~~~a &&& (b ||| c)) - 5 * ((a &&& c) ||| (b &&&  ~~~c)) + 12 *  ~~~(a ||| (b ||| c)) + 8 *  ~~~(a ||| ( ~~~b ||| c)) + 8 *  ~~~( ~~~a ||| (b ||| c)) + 8 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 3 * ( ~~~a &&& (b &&& c)) + 13 * (a &&& ( ~~~b &&& c)) + 14 * (a &&& (b &&& c)) =  - 2 * ( ~~~a &&& ( ~~~b &&& c)) + 1 *  ~~~(a ^^^ b)

theorem set_to_clear_decomposebittest_thm (e : IntW 8) :
  select (icmp IntPred.slt e (const? 8 0)) (const? 8 3) (const? 8 (-125)) ⊑
    LLVM.xor (LLVM.and e (const? 8 (-128))) (const? 8 (-125))

theorem add_right_shift (hq : q >= t) (hs : s >= p + (2 ^ u - 1)) (hv_s : v > s) (hv_t : v > t) :
  (bw r (addMax (bw p a) (bw q (shrMax (bw t b) (bw u c)))))  =
  (bw r (shrMax (bw v (addMax (bw s (shlMax (bw p a) (bw u c))) (bw t b))) (bw u c)))

theorem or_and3_thm.extracted_1._6 : ∀ (x : BitVec 1) (x_1 x_2 : BitVec 32) (x_3 : BitVec 1),
  x_3 ||

theorem src_srem_shl_demand_max_signbit_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬((2#32 == 0 || 32 != 1 && x == intMin 32 && 2#32 == -1) = true ∨ 30#32 ≥ ↑32) →
    ¬(2#32 == 0 || 32 != 1 && x == intMin 32 && 2#32 == -1) = true →
      x.srem 2#32 <<< 30#32 &&& BitVec.ofInt 32 (-2147483648) = x.srem 2#32 &&& BitVec.ofInt 32 (-2147483648)

theorem sext_sub_const_proof : sext_sub_const_before ⊑ sext_sub_const_after

theorem and_ne_with_one_bit_diff_constants1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x != 51#32) &&& ofBool (x != 50#32) = ofBool (x + BitVec.ofInt 32 (-52) <ᵤ BitVec.ofInt 32 (-2))

theorem tryFactorization_xor_ashr_lshr_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬(x ≥ ↑32 ∨ x ≥ ↑32) → x ≥ ↑32 → False

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

@[simp_llvm_option]
theorem LLVM.IntW.value_isRefinedBy_iff (a : BitVec w) (b? : PoisonOr (BitVec w)) :
    value a ⊑ b? ↔ b? = value a

theorem udiv_i80_thm (e : IntW 80) :
  LLVM.udiv (lshr e (const? 80 2)) (const? 80 100) ⊑ LLVM.udiv e (const? 80 400)

theorem shl_trunc_smaller_ashr_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(10#32 ≥ ↑32 ∨ 13#24 ≥ ↑24) →
    ¬3#24 ≥ ↑24 → truncate 24 (x.sshiftRight' 10#32) <<< 13#24 = truncate 24 x <<< 3#24 &&& BitVec.ofInt 24 (-8192)

@[simp] theorem map_append (f : Ty₁ → Ty₂) (Γ Δ : Ctxt Ty₁) :
    (Γ ++ Δ).map f = Γ.map f ++ Δ.map f

theorem alive_Select_1078 : forall (w : Nat) (X c Z W : Bitvec 1)
, TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 1)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (c) %v0;
  %v2 := op:const (W) %v0;
  %v3 := op:const (Z) %v0;
  %v4 := triple:%v1 %v2 %v3;
  %v5 := op:select w %v4;
  %v6 := op:const (X) %v0;
  %v7 := triple:%v1 %v6 %v5;
  %v8 := op:select w %v7
  dsl_ret %v8
  ]  ⊑
  TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 1)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (c) %v0;
  %v2 := op:const (W) %v0;
  %v3 := op:const (Z) %v0;
  %v4 := triple:%v1 %v2 %v3;
  %v5 := op:select 1 %v4;
  %v6 := op:const (X) %v0;
  %v7 := triple:%v1 %v6 %v3;
  %v8 := op:select 1 %v7
  dsl_ret %v8
  ]

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

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

theorem e_1099 :
    11 *  ~~~z - 6 *  ~~~(z ^^^ t) - 5 * z + 1 *  ~~~(z &&&  ~~~z) + 7 * t + 4 * (z ^^^ t) - 6 *  ~~~(z ||| t) + 3 * (z &&& t) = 23 *  ~~~(z |||  ~~~t)

theorem ashr_lshr_no_lshr_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ofBool (0#32 ≤ₛ x_1) = 1#1 → ofBool (x_1 <ₛ 0#32) = 1#1 → ¬x ≥ ↑32 → x_1 + x = x_1.sshiftRight' x

theorem e_2235 :
     - 2 *  ~~~(d &&& e) + 1 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 5 * ((d ^^^ e) ||| (d ^^^ f)) - 3 * (f ||| (d &&&  ~~~e)) - 1 * ( ~~~d ||| (e ||| f)) + 4 *  ~~~(d ^^^ ( ~~~e &&& f)) - 6 * (e ^^^ ( ~~~d ||| (e ^^^ f))) + 1 * (e ^^^ (d ||| (e &&& f))) + 1 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 2 * (e ||| f) + 5 *  ~~~(d &&& (e ||| f)) - 2 * (f ^^^  ~~~(d &&& (e ||| f))) + 1 * (f ^^^ (d &&& e)) + 3 *  ~~~(d &&&  ~~~e) - 2 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 2 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 3 * ((d ^^^ e) &&& (d ^^^ f)) + 1 *  ~~~(d |||  ~~~f) + 2 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 1 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 1 * (e &&& (d ^^^ f)) + 5 * (f ^^^ ( ~~~d &&& (e ||| f))) + 1 * f - 2 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 1 * (d &&& ( ~~~e ||| f)) - 3 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 2 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 5 * (e |||  ~~~(d ^^^ f)) - 6 * ( ~~~f &&& (d ^^^ e)) - 1 *  ~~~(d &&&  ~~~d) + 3 * (e ^^^ (d ||| ( ~~~e ||| f))) + 5 * ( ~~~d ||| ( ~~~e ||| f)) + 5 *  ~~~(d &&& (e ^^^ f)) - 1 *  ~~~(d ^^^ (e ||| f)) - 11 *  ~~~(d &&& (e &&& f)) + 2 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 5 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 1 *  ~~~(d ||| ( ~~~e &&& f)) + 2 * ( ~~~d &&& ( ~~~e ||| f)) - 1 * e + 2 * (f &&&  ~~~(d &&&  ~~~e)) - 2 * (d ||| (e ^^^ f)) + 7 * ((e &&& f) ||| (d &&& (e ||| f))) + 11 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 2 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) + 7 * (f ^^^ (d ||| ( ~~~e &&& f))) - 11 * (f ^^^  ~~~(d &&& (e &&& f))) + 2 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 5 *  ~~~(d ||| (e ||| f)) + 7 *  ~~~(d ||| ( ~~~e ||| f)) + 19 *  ~~~( ~~~d ||| (e ||| f)) + 8 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 4 * ( ~~~d &&& ( ~~~e &&& f)) - 9 * ( ~~~d &&& (e &&& f)) + 11 * (d &&& ( ~~~e &&& f)) =  - 1 * (d &&& (e &&& f))

theorem p_constmask2_thm (e e_1 : IntW 32) :
  add (LLVM.and e_1 (const? 32 61440)) (LLVM.and e (const? 32 (-65281))) ⊑
    LLVM.or (LLVM.and e_1 (const? 32 61440)) (LLVM.and e (const? 32 (-65281))) { «disjoint» := true }

theorem positive_sameconst_shlnsw_thm (e : IntW 8) :
  shl (ashr e (const? 8 3)) (const? 8 3) { «nsw» := true, «nuw» := false } ⊑ LLVM.and e (const? 8 (-8))

theorem neg_mask_const_proof : neg_mask_const_before ⊑ neg_mask_const_after

theorem positive_sameconst_proof : positive_sameconst_before ⊑ positive_sameconst_after

theorem unsigned_sign_bit_extract_with_trunc_proof : unsigned_sign_bit_extract_with_trunc_before ⊑ unsigned_sign_bit_extract_with_trunc_after

theorem trunc_equality_nuw_zext_proof : trunc_equality_nuw_zext_before ⊑ trunc_equality_nuw_zext_after

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

theorem p_proof : p_before ⊑ p_after

theorem test_op_op_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.sgt e_2 (const? 32 0)) (sext 32 (icmp IntPred.sgt e_1 (const? 32 0)))
      (sext 32 (icmp IntPred.sgt e (const? 32 0))) ⊑
    sext 32 (icmp IntPred.sgt (select (icmp IntPred.sgt e_2 (const? 32 0)) e_1 e) (const? 32 0))

theorem urem_i32_c_proof : urem_i32_c_before ⊑ urem_i32_c_after

theorem invert_both_cmp_operands_complex_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 32) (x_3 : BitVec 1),
  ¬x_3 = 1#1 → ofBool (x ^^^ -1#32 ≤ₛ x_2 ^^^ -1#32) = ofBool (x_2 ≤ₛ x)

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

theorem test1_thm.extracted_1._1 : ∀ (x : BitVec 61), zeroExtend 61 (truncate 41 x) = x &&& 2199023255551#61

theorem lshrult_01_06_proof : lshrult_01_06_before ⊑ lshrult_01_06_after

theorem main_proof : main_before ⊑ main_after

theorem sle_smax1_thm (e e_1 : IntW 32) :
  icmp IntPred.sle (select (icmp IntPred.sgt e_1 e) e_1 e) e_1 ⊑ icmp IntPred.sle e e_1

theorem eq_umax4_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 + 3#32 <ᵤ x) = 1#1 → ofBool (x_1 + 3#32 == x) = ofBool (x ≤ᵤ x_1 + 3#32)

theorem test2_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 49), ¬(x_1 ≥ ↑49 ∨ x_1 ≥ ↑49) → x_1 ≥ ↑49 → False

theorem rev8_mul_and_lshr_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (zeroExtend 64 x).smulOverflow 2050#64 = true ∨
        True ∧ (zeroExtend 64 x).umulOverflow 2050#64 = true ∨
          True ∧ (zeroExtend 64 x).smulOverflow 32800#64 = true ∨
            True ∧ (zeroExtend 64 x).umulOverflow 32800#64 = true ∨
              True ∧
                  (zeroExtend 64 x * 2050#64 &&& 139536#64 ||| zeroExtend 64 x * 32800#64 &&& 558144#64).smulOverflow
                      65793#64 =
                    true ∨
                True ∧
                    (zeroExtend 64 x * 2050#64 &&& 139536#64 ||| zeroExtend 64 x * 32800#64 &&& 558144#64).umulOverflow
                        65793#64 =
                      true ∨
                  16#64 ≥ ↑64) →
    True ∧ (zeroExtend 64 x).smulOverflow 2050#64 = true ∨
        True ∧ (zeroExtend 64 x).umulOverflow 2050#64 = true ∨
          True ∧ (zeroExtend 64 x).smulOverflow 32800#64 = true ∨
            True ∧ (zeroExtend 64 x).umulOverflow 32800#64 = true ∨
              True ∧
                  (zeroExtend 64 x * 2050#64 &&& 139536#64 &&& (zeroExtend 64 x * 32800#64 &&& 558144#64) != 0) = true ∨
                True ∧
                    (zeroExtend 64 x * 2050#64 &&& 139536#64 ||| zeroExtend 64 x * 32800#64 &&& 558144#64).smulOverflow
                        65793#64 =
                      true ∨
                  True ∧
                      (zeroExtend 64 x * 2050#64 &&& 139536#64 |||
                              zeroExtend 64 x * 32800#64 &&& 558144#64).umulOverflow
                          65793#64 =
                        true ∨
                    16#64 ≥ ↑64 →
      False

theorem sdiv_x_by_const_cmp_x_thm (e : IntW 32) :
  icmp IntPred.eq (LLVM.sdiv e (const? 32 13)) e ⊑ icmp IntPred.eq e (const? 32 0)

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

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

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

theorem ashr_lshr2_proof : ashr_lshr2_before ⊑ ashr_lshr2_after

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_logical_after

theorem uadd_sat_flipped_wrong_bounds7_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x ≤ᵤ BitVec.ofInt 32 (-12)) = 1#1 → ¬ofBool (x <ᵤ BitVec.ofInt 32 (-11)) = 1#1 → x + 9#32 = -1#32

theorem trunc_ashr_proof : trunc_ashr_before ⊑ trunc_ashr_after

theorem tryFactorization_add_mul_nuw_mul_var_proof : tryFactorization_add_mul_nuw_mul_var_before ⊑ tryFactorization_add_mul_nuw_mul_var_after

theorem or_nosignbit_shl_thm (e : IntW 32) :
  shl (LLVM.or e (const? 32 2147418112)) (const? 32 8) ⊑ LLVM.or (shl e (const? 32 8)) (const? 32 (-16777216))

theorem mul_constant_eq_proof : mul_constant_eq_before ⊑ mul_constant_eq_after

theorem or_xor_commute4_thm (e e_1 : IntW 32) :
  LLVM.xor (LLVM.udiv (const? 32 42) e_1) (LLVM.or (LLVM.udiv (const? 32 42) e) (LLVM.udiv (const? 32 42) e_1)) ⊑
    LLVM.and (LLVM.udiv (const? 32 42) e) (LLVM.xor (LLVM.udiv (const? 32 42) e_1) (const? 32 (-1)))

theorem test1_proof : test1_before ⊑ test1_after

theorem urem_i1_is_zero_proof : urem_i1_is_zero_before ⊑ urem_i1_is_zero_after

theorem positive_biggerShl_shlnuw_proof : positive_biggerShl_shlnuw_before ⊑ positive_biggerShl_shlnuw_after

theorem bitwise_or_logical_or_icmps_comm1_proof : bitwise_or_logical_or_icmps_comm1_before ⊑ bitwise_or_logical_or_icmps_comm1_after

theorem test12_thm (e e_1 : IntW 32) :
  trunc 64 (lshr (zext 128 e_1) (LLVM.and (zext 128 e) (const? 128 31))) ⊑
    lshr (zext 64 e_1) (zext 64 (LLVM.and e (const? 32 31)) { «nneg» := true })

@[simp]
theorem Factor.reflect_zero_of_denote_zero {w : Nat} {f : Factor} {xs : Env w} (h : f.denote xs = 0) :
    f.reflect xs = 0#w

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

theorem and_signbit_ashr_proof : and_signbit_ashr_before ⊑ and_signbit_ashr_after

theorem test11_proof : test11_before ⊑ test11_after

theorem e_1557 :
     - 7 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 5 * (c ^^^ (a &&& b)) + 5 * (c ^^^  ~~~(a &&& (b ||| c))) + 2 * (b ^^^ ( ~~~a ||| (b &&& c))) - 5 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) - 3 * (b ||| (a ^^^ c)) - 1 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) + 7 *  ~~~(a ||| (b ||| c)) + 7 *  ~~~(a ||| ( ~~~b ||| c)) - 1 *  ~~~( ~~~a ||| (b ||| c)) + 12 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 12 * ( ~~~a &&& ( ~~~b &&& c)) + 15 * ( ~~~a &&& (b &&& c)) + 6 * (a &&& ( ~~~b &&& c)) = 1 *  ~~~(a &&& ( ~~~b ||| c)) - 5 * (a &&& (b &&& c))

theorem EqualUpTo_ofBitVecZextMsb_add (a b : BitVec w) :
    EqualUpTo (w + 1)
    (BitStream.ofBitVecZextMsb a + BitStream.ofBitVecZextMsb b)
    (BitStream.ofBitVecZextMsb (a + b))

theorem positive_biggershl_shlnsw_proof : positive_biggershl_shlnsw_before ⊑ positive_biggershl_shlnsw_after

theorem e_2322 :
    5 *  ~~~( ~~~d &&& (e ^^^ f)) + 4 *  ~~~(d &&& ( ~~~e &&& f)) - 1 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 7 * (e ^^^ (d ||| f)) - 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 1 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 2 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 11 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 2 * ( ~~~e &&& (d ^^^ f)) + 5 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 1 * (f ^^^ (d ||| (e ||| f))) - 2 *  ~~~(d &&& f) + 1 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 5 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 5 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 5 *  ~~~e - 1 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 11 * (e ^^^  ~~~(d &&& (e ||| f))) + 3 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 4 * (f ^^^ (d &&& ( ~~~e ||| f))) + 2 * (e &&& f) - 6 * ( ~~~d ||| (e ^^^ f)) + 5 * (e ^^^ (d |||  ~~~f)) + 11 * (e ^^^ (d &&& (e ^^^ f))) + 7 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 1 *  ~~~(d ||| e) - 6 *  ~~~(d &&& (e &&& f)) + 1 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 7 * (e ^^^ (d &&& (e ||| f))) + 4 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 3 *  ~~~(e &&&  ~~~f) + 1 * (f &&&  ~~~(d ^^^ e)) + 2 * (f ^^^  ~~~(d ||| e)) - 1 * (e ^^^  ~~~(d &&&  ~~~f)) - 11 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 *  ~~~(d ||| (e ^^^ f)) - 1 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 2 * d - 6 * (f ^^^ (d ||| (e &&& f))) - 2 *  ~~~(d ^^^ (e ^^^ f)) + 1 * (e &&& (d ^^^ f)) + 7 * (e ^^^ (d &&& f)) - 1 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 1 * ( ~~~d &&& (e ^^^ f)) - 2 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 7 * (e ^^^  ~~~(d ||| f)) + 7 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 2 *  ~~~(d &&& (e ^^^ f)) - 1 * (d &&& (e ||| f)) + 3 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 3 *  ~~~( ~~~d ||| ( ~~~e &&& f)) + 4 * ((d &&& f) |||  ~~~(e ||| f)) + 2 * ((d &&& f) ||| (e &&&  ~~~f)) - 11 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 1 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 5 * ( ~~~d ||| (e &&& f)) - 1 *  ~~~(d ||| (e ||| f)) - 18 *  ~~~(d ||| ( ~~~e ||| f)) + 9 *  ~~~( ~~~d ||| (e ||| f)) + 12 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 7 * ( ~~~d &&& ( ~~~e &&& f)) - 31 * ( ~~~d &&& (e &&& f)) - 37 * (d &&& (e &&& f)) = 38 * (d &&& ( ~~~e &&& f))

theorem xor_sext_sext_thm.extracted_1._1 : ∀ (x : BitVec 4) (x_1 : BitVec 8),
  signExtend 16 x_1 ^^^ signExtend 16 x = signExtend 16 (x_1 ^^^ signExtend 8 x)

theorem e_290 :
    5 *  ~~~(x ^^^ y) + 2 * x + 2 *  ~~~(x &&&  ~~~y) + 11 *  ~~~(x &&& y) - 18 *  ~~~(x ||| y) - 13 *  ~~~(x |||  ~~~y) - 13 * (x &&&  ~~~y) = 9 * (x &&& y)

theorem test_logical_and_ne_a_b_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → 0#1 = 1#1 → False
</all_available_lemmas>

<local_ctx>
import Mathlib.Data.Bool.Basic

import Mathlib.Data.Fin.Basic

import Mathlib.Data.Finset.Basic

import Mathlib.Data.Finset.Defs

import Mathlib.Data.Multiset.FinsetOps

import Blase.Fast.BitStream

import Blase.Fast.Defs

import Blase.Fast.FiniteStateMachine

import Blase.Fast.Decide

import Blase.SingleWidth.Syntax

import Lean.Meta.ForEachExpr

import Lean.Meta.Tactic.Simp.BuiltinSimprocs.BitVec

import Blase.Fast.ForLean

import Blase.Vars

import Blase.EnvBitstream

import Lean

open Fin.NatCast

namespace ReflectVerif

open Lean Meta Elab Tactic

namespace BvDecide

open Std Sat AIG

structure KInductionCircuits {arity : Type _}
  [DecidableEq arity] [Fintype arity] [Hashable arity] (fsm : FSM arity) (n : Nat) where
  
  cInitCarryAssignCirc : Circuit (Vars fsm.α arity 0)
  
  cSuccCarryAssignCirc : Circuit (Vars fsm.α arity (n+2))
  
  cOutAssignCirc : Circuit (Vars fsm.α arity (n + 2))
  
  cStatesUniqueCirc : Circuit (Vars fsm.α arity n)

namespace KInductionCircuits

variable {arity : Type _}
  {fsm : FSM arity}

variable [DecidableEq arity] [Fintype arity] [Hashable arity]

def envBitstream_set (x : arity → BitStream) (n : Nat) (v : arity → Bool) :
    arity → BitStream :=
  fun a j => if j = n then v a else x a j
</local_ctx>

<target_theorem>
theorem FSM.carryWith_congrEnv_envBitstream_set_of_le (fsm : FSM arity)
    (s0 : fsm.α → Bool) (env : arity → BitStream) (n : Nat) (v : arity → Bool)
    (k : Nat) (hk : k ≤ n) :
  fsm.carryWith s0 (envBitstream_set env n v) k =
  fsm.carryWith s0 env k :=
</target_theorem>

