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>
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
Bool in Init.Prelude
DecidableEq in Init.Prelude
FinEnum in Mathlib.Data.FinEnum
Hashable in Init.Prelude
Nat in Init.Prelude
Sum in Init.Core
Sum.elim in Init.Data.Sum.Basic
Int.xor in Mathlib.Data.Int.Bitwise
Nat.testBit in Init.Data.Nat.Bitwise.Basic
Fintype in Mathlib.Data.Fintype.Defs
Finset in Mathlib.Data.Finset.Defs
Finset.card in Mathlib.Data.Finset.Card
Finset.univ in Mathlib.Data.Fintype.Defs
Bool.xor in Init.Data.Bool
Set in Mathlib.Data.Set.Defs
Sum.inl in Init.Core
Sum.inr in Init.Core
Polynomial.X in Mathlib.Algebra.Polynomial.Basic
ZMod in Mathlib.Data.ZMod.Defs
id in Init.Prelude

syntax "slt" : MLIR.Pretty.uniform_op

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

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

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

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

inductive 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 BitStream : Type := Nat → Bool

def Term.eval (t : Term) (vars : List BitStream) : BitStream :=
  match t with
  | var n       => vars.getD n default
  | zero        => BitStream.zero
  | one         => BitStream.one
  | negOne      => BitStream.negOne
  | ofNat n     => BitStream.ofNat n
  | and t₁ t₂   => (t₁.eval vars) &&& (t₂.eval vars)
  | or t₁ t₂    => (t₁.eval vars) ||| (t₂.eval vars)
  | xor t₁ t₂   => (t₁.eval vars) ^^^ (t₂.eval vars)
  | not t       => ~~~(t.eval vars)
  | add t₁ t₂   => (Term.eval t₁ vars) + (Term.eval t₂ vars)
  | sub t₁ t₂   => (Term.eval t₁ vars) - (Term.eval t₂ vars)
  | neg t       => -(Term.eval t vars)

| shiftL t n  => BitStream.shiftLeft (Term.eval t vars) n

def Predicate.eval (p : Predicate) (vars : List BitStream) : BitStream :=
  match p with
  | .width .eq n => BitStream.falseIffEq n
  | .width .neq n => BitStream.falseIffNeq n
  | .width .lt n => BitStream.falseIffLt n
  | .width .le n => BitStream.falseIffLe n
  | .width .gt n => BitStream.falseIffGt n
  | .width .ge n => BitStream.falseIffGe n
  | lor p q => Predicate.evalLor (p.eval vars) (q.eval vars)
  | land p q => Predicate.evalLand (p.eval vars) (q.eval vars)
  | binary .eq t₁ t₂ => Predicate.evalEq (t₁.eval vars) (t₂.eval vars)
   
  | binary .neq t1 t2 => Predicate.evalNeq (t1.eval vars) (t2.eval vars)
  | binary .ult t₁ t₂ => Predicate.evalUlt (t₁.eval vars) (t₂.eval vars)
  | binary .ule t₁ t₂ =>
     Predicate.evalLor
       (Predicate.evalEq (t₁.eval vars) (t₂.eval vars))
       (Predicate.evalUlt (t₁.eval vars) (t₂.eval vars))
  | binary .slt t₁ t₂ => Predicate.evalSlt (t₁.eval vars) (t₂.eval vars)
  | binary .sle t₁ t₂ => Predicate.evalLor
       (Predicate.evalEq (t₁.eval vars) (t₂.eval vars))
       (Predicate.evalSlt (t₁.eval vars) (t₂.eval vars))

def Predicate.evalUlt (t₁ t₂ : BitStream) : BitStream := (~~~ (t₁.borrow t₂)).concat true

def borrow (x y : BitStream) : BitStream :=
  fun n => (subAux x y n).2

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

def Predicate.evalSlt (t₁ t₂ : BitStream) : BitStream :=
    (((Predicate.evalUlt t₁ t₂)) ^^^ (Predicate.evalMsbEq t₁ t₂))

def Predicate.evalMsbEq (t₁ t₂ : BitStream) : BitStream :=
  (t₁ ^^^ t₂).concat false

def Predicate.evalLand (t₁ t₂ : BitStream) : BitStream := (t₁ ||| t₂)

def Predicate.evalNeq (t₁ t₂ : BitStream) : BitStream := (t₁.nxor t₂).concat true |>.scanAnd

def nxor (a b : BitStream) : BitStream := fun i => a i == b i

def scanAnd (s : BitStream) : BitStream := scanl true Bool.and s

abbrev scanl (init : Bool) (f : Bool → Bool → Bool) (s : BitStream) : BitStream :=
  fun n => match n with
    | 0 => f init (s 0)
    | n+1 => f (scanl init f s n) (s (n + 1))

def Predicate.evalLor (t₁ t₂ : BitStream) : BitStream := (t₁ &&& t₂)

def Predicate.evalEq (t₁ t₂ : BitStream) : BitStream := (t₁ ^^^ t₂).concat false |>.scanOr

def scanOr (s : BitStream) : BitStream := scanl false Bool.or s

abbrev falseIffNeq (n : Nat) : BitStream := fun i => decide (i == n)

abbrev falseIffLt (n : Nat) : BitStream := fun i => decide (i ≥ n)

abbrev falseIffGe (n : Nat) : BitStream := fun i => decide (i < n)

abbrev falseIffEq (n : Nat) : BitStream := fun i => decide (i != n)

abbrev falseIffGt (n : Nat) : BitStream := fun i => decide (i ≤ n)

def Term.width (t : Term) : WidthExpr :=
  match t with

| .ofNat w _n => w
  | .var _v w => w
  | .add w _a _b => w
  | .zext _a wnew => wnew
  | .setWidth _a wnew => wnew
  | .sext _a wnew => wnew
  | .bor w _a _b => w
  | .band w _a _b => w
  | .bxor w _a _b => w
  | .bnot w _a => w
  | .boolVar _v => WidthExpr.const 1 
  | .boolConst _b => WidthExpr.const 1
  | .shiftl w _a _k => w
  | .bvOfBool _b => WidthExpr.const 1
  | binWidthRel _k wa wb => WidthExpr.const 0
  | binRel _k w _a _b => w
  | or _p1 _p2 => WidthExpr.const 0
  | and _p1 _p2 => WidthExpr.const 0
  | pvar _v => WidthExpr.const 0
  | boolBinRel _k _a _b => WidthExpr.const 0

abbrev falseIffLe (n : Nat) : BitStream := fun i => decide (i > n)

abbrev negOne : BitStream := fun _ => true

def shiftLeft (x : BitStream) (k : Nat) : BitStream :=
  fun i => if i < k then false else x (i - k)

def ofNat (x : Nat) : BitStream :=
  Nat.testBit x

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

abbrev zero   : BitStream := fun _ => false

@[simp]
def eval : Circuit α → (α → Bool) → Bool
  | tru, _ => true
  | fals, _ => false
  | var b x, f => if b then f x else !(f x)
  | and c₁ c₂, f => (eval c₁ f) && (eval c₂ f)
  | or c₁ c₂, f => (eval c₁ f) || (eval c₂ f)
  | xor c₁ c₂, f => Bool.xor (eval c₁ f) (eval c₂ f)

def sumVarsRight [DecidableEq α] [DecidableEq β] : Circuit (α ⊕ β) → List β
  | tru => []
  | fals => []
  | var _ (Sum.inl _) => []
  | var _ (Sum.inr x) => [x]
  | and c₁ c₂ => (sumVarsRight c₁ ++ sumVarsRight c₂).dedup
  | or c₁ c₂ => (sumVarsRight c₁ ++ sumVarsRight c₂).dedup
  | xor c₁ c₂ => (sumVarsRight c₁ ++ sumVarsRight c₂).dedup

def fst {α β : Type _} [DecidableEq α] [DecidableEq β]
    (c : Circuit (α ⊕ β)) : Circuit α :=
  Circuit.bOr (c.sumVarsRight.pi (λ _ => [true, false]))
  (λ x => Circuit.assignVars c
    (λ i => Sum.rec (λ i _ => Sum.inl i) (λ i hi => Sum.inr (x i (by admit /- proof elided -/
    ))) i))

def bOr : ∀ (_s : List α) (_f : α → Circuit β), Circuit β
| [], _ => fals
| a::l, f => l.foldl (λ c x => c ||| (f x)) (f a)

def assignVars [DecidableEq α] :
    ∀ (c : Circuit α) (_f : ∀ (a : α) (_ha : a ∈ c.vars), β ⊕ Bool), Circuit β
  | tru, _ => tru
  | fals, _ => fals
  | var b x, f =>
    Sum.elim
      (var b)
      (λ c : Bool => if Bool.xor b c then fals else tru)
      (f x (by admit /- proof elided -/
      ))
  | and c₁ c₂, f => (assignVars c₁ (λ x hx => f x (by admit /- proof elided -/
  ))) &&&
                    (assignVars c₂ (λ x hx => f x (by admit /- proof elided -/
                    )))
  | or c₁ c₂, f =>  (assignVars c₁ (λ x hx => f x (by admit /- proof elided -/
  ))) |||
                    (assignVars c₂ (λ x hx => f x (by admit /- proof elided -/
                    )))
  | xor c₁ c₂, f => (assignVars c₁ (λ x hx => f x (by admit /- proof elided -/
  ))) ^^^
                    (assignVars c₂ (λ x hx => f x (by admit /- proof elided -/
                    )))

def vars [DecidableEq α] : Circuit α → List α
  | tru => []
  | fals => []
  | var _ x => [x]
  | and c₁ c₂ => (vars c₁ ++ vars c₂).dedup
  | or c₁ c₂ => (vars c₁ ++ vars c₂).dedup
  | xor c₁ c₂ => (vars c₁ ++ vars c₂).dedup

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

noncomputable def f : (ZMod q)[X] := X^(2^n) + 1

def simplifyOr : Circuit α → Circuit α → Circuit α
  | tru, _ => tru
  | _, tru => tru
  | fals, c => c
  | c, fals => c
  | c₁, c₂ => or c₁ c₂

def bind : ∀ (_c : Circuit α) (_f : α → Circuit β), Circuit β
  | tru, _ => tru
  | fals, _ => fals
  | var b x, f => if b then f x else ~~~ (f x)
  | and c₁ c₂, f => (bind c₁ f) &&& (bind c₂ f)
  | or c₁ c₂, f => (bind c₁ f) ||| (bind c₂ f)
  | xor c₁ c₂, f => (bind c₁ f) ^^^ (bind c₂ f)

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 test_before := [llvm|
{
^0(%arg0 : i1, %arg1 : i1):
  %0 = llvm.add %arg0, %arg1 : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

@[simp_denote]
def slli_riscv_i64 :=
  [LV| {
    ^entry (%arg: i64):
    %a = "builtin.unrealized_conversion_cast" (%arg) : (i64) -> (!i64)
    %0 = slli %a, 7 : !i64
    %1 = "builtin.unrealized_conversion_cast" (%0) : (!i64) -> (i64)
    llvm.return %1 : i64
  }]

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

def or_xor_tree_1011_after := [llvm|
{
^0(%arg12 : i32, %arg13 : i32, %arg14 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mul %arg12, %0 : i32
  %2 = llvm.mul %arg13, %0 : i32
  %3 = llvm.mul %arg14, %0 : i32
  %4 = llvm.xor %2, %1 : i32
  %5 = llvm.or %4, %3 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def and_xor_or1_after := [llvm|
{
^0(%arg673 : i64, %arg674 : i64, %arg675 : i64):
  %0 = llvm.mlir.constant(42) : i64
  %1 = llvm.udiv %0, %arg674 : i64
  %2 = llvm.udiv %0, %arg675 : i64
  %3 = llvm.or %2, %1 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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

def positive_samevar_shlnuwnsw_ashrexact_before := [llvm|
{
^0(%arg27 : i8, %arg28 : i8):
  %0 = llvm.ashr exact %arg27, %arg28 : i8
  %1 = llvm.shl %0, %arg28 overflow<nsw,nuw> : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def scalar_i64_shl_and_signbit_eq_after := [llvm|
{
^0(%arg29 : i64, %arg30 : i64):
  %0 = llvm.mlir.constant(-1) : i64
  %1 = llvm.shl %arg29, %arg30 : i64
  %2 = llvm.icmp "sgt" %1, %0 : i64
  "llvm.return"(%2) : (i1) -> ()
}
]

def test_const_shr_and_1_ne_0_i1_negative_before := [llvm|
{
^0(%arg2 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.lshr %0, %arg2 : i1
  %3 = llvm.and %2, %0 : i1
  %4 = llvm.icmp "ne" %3, %1 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

def f2_before := [llvm|
{
^0(%arg0 : i32, %arg1 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(7 : i32) : i32
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.icmp "slt" %arg0, %0 : i32
  %4 = llvm.ashr %1, %arg1 : i32
  %5 = llvm.icmp "sgt" %arg0, %4 : i32
  %6 = "llvm.select"(%3, %2, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %7 = llvm.zext %6 : i1 to i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

def test_sub_nuw__nsw_is_safe_after := [llvm|
{
^0(%arg22 : i32):
  %0 = llvm.mlir.constant(-2147483648 : i32) : i32
  %1 = llvm.or %arg22, %0 : i32
  %2 = llvm.sub %0, %1 overflow<nsw> : i32
  "llvm.return"(%2) : (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 binop_same_val : List (Σ Γ, RISCVPeepholeRewrite  Γ) :=
    [⟨_, binop_same_val_and⟩,
    ⟨_, binop_same_val_or⟩]

def neg_mask_after := [llvm|
{
^0(%arg1 : i32, %arg2 : i16):
  %0 = llvm.mlir.constant(0 : i16) : i16
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.sext %arg2 : i16 to i32
  %3 = llvm.sub %arg1, %2 overflow<nsw> : i32
  %4 = llvm.icmp "slt" %arg2, %0 : i16
  %5 = "llvm.select"(%4, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def test_const_shr_exact_and_1_ne_0_after := [llvm|
{
^0(%arg6 : 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, %arg6 overflow<nuw> : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.icmp "ne" %4, %2 : i32
  "llvm.return"(%5) : (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 ult_1_impliesF_eq_1_after := [llvm|
{
^0(%arg3 : i8, %arg4 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "ne" %arg3, %0 : i8
  %3 = llvm.icmp "eq" %arg4, %arg3 : i8
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

def t0_basic_before := [llvm|
{
^0(%arg41 : i8, %arg42 : i8):
  %0 = llvm.add %arg41, %arg42 : i8
  %1 = llvm.icmp "uge" %0, %arg42 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

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

def cmpeq_xor_cst1_commuted_after := [llvm|
{
^0(%arg12 : i32, %arg13 : i32):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.mul %arg13, %arg13 : i32
  %2 = llvm.xor %arg12, %1 : i32
  %3 = llvm.icmp "eq" %2, %0 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def test_or_eq_a_b_commuted_after := [llvm|
{
^0(%arg30 : i1, %arg31 : i8, %arg32 : i8):
  %0 = "llvm.select"(%arg30, %arg32, %arg31) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%0) : (i8) -> ()
}
]

def Term.numVars (t : Term) : Nat := t.f.numVars

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

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

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

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

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

Lean.ReducibilityStatus.semireducible in Lean.ReducibilityAttrs

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

def a_true_implies_b_true2_after := [llvm|
{
^0(%arg30 : i8, %arg31 : i1, %arg32 : i1):
  %0 = llvm.mlir.constant(20 : i8) : i8
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "ugt" %arg30, %0 : i8
  %3 = "llvm.select"(%2, %arg31, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def neg_not_signbit2_after := [llvm|
{
^0(%arg4 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.lshr %arg4, %0 : i8
  %3 = llvm.zext nneg %2 : i8 to i32
  %4 = llvm.sub %1, %3 overflow<nsw> : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def test10_before := [llvm|
{
^0(%arg41 : i19):
  %0 = llvm.mlir.constant(18 : i19) : i19
  %1 = llvm.lshr %arg41, %0 : i19
  %2 = llvm.shl %1, %0 : i19
  "llvm.return"(%2) : (i19) -> ()
}
]

def test29_before := [llvm|
{
^0(%arg173 : i1):
  %0 = llvm.mlir.constant(1000 : i32) : i32
  %1 = llvm.mlir.constant(10 : i32) : i32
  %2 = llvm.mlir.constant(123 : i32) : i32
  %3 = "llvm.select"(%arg173, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.xor %3, %2 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

@[simp]
abbrev Hom.consRight {Γ Γ' : Ctxt Ty} (f : Hom Γ Γ') {t : Ty} : Γ.Hom (Γ'.cons t) :=
  fun _ v => (f v).toCons

def and_two_ranges_to_mask_and_range_no_add_on_one_range_after := [llvm|
{
^0(%arg249 : i16):
  %0 = llvm.mlir.constant(-20 : i16) : i16
  %1 = llvm.mlir.constant(11 : i16) : i16
  %2 = llvm.and %arg249, %0 : i16
  %3 = llvm.icmp "ugt" %2, %1 : i16
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

Lean.mkStateFromImportedEntries in Lean.EnvExtension

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

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

def NFA.autWidth_correct : (autWidth wp n).correct (autWidthSA n) (autWidthLang wp n) :=

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

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

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

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

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

def ne_shift_in_zeros_before := [llvm|
{
^0(%arg32 : i32, %arg33 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.lshr %arg32, %0 : i32
  %3 = llvm.trunc %2 : i32 to i8
  %4 = llvm.lshr %arg32, %1 : i32
  %5 = llvm.trunc %4 : i32 to i24
  %6 = llvm.lshr %arg33, %0 : i32
  %7 = llvm.trunc %6 : i32 to i8
  %8 = llvm.lshr %arg33, %1 : i32
  %9 = llvm.trunc %8 : i32 to i24
  %10 = llvm.icmp "ne" %3, %7 : i8
  %11 = llvm.icmp "ne" %5, %9 : i24
  %12 = llvm.or %11, %10 : i1
  "llvm.return"(%12) : (i1) -> ()
}
]

def getWidth (expr : Expr) : MetaM (Option Nat) := do
  match_expr expr with
  | BitVec n => getNatValue? n
  | _ => pure none

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

def select_2_after := [llvm|
{
^0(%arg82 : i1, %arg83 : i8, %arg84 : i1, %arg85 : i8, %arg86 : i8):
  %0 = llvm.mlir.constant(-124 : i8) : i8
  %1 = llvm.mlir.constant(-46 : i8) : i8
  %2 = llvm.xor %arg86, %0 : i8
  %3 = "llvm.select"(%arg84, %arg85, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = llvm.xor %arg83, %1 : i8
  %5 = "llvm.select"(%arg82, %3, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

def sge_to_ugt_before := [llvm|
{
^0(%arg21 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(15 : i8) : i8
  %2 = llvm.xor %arg21, %0 : i8
  %3 = llvm.icmp "sge" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def bind₂ (a : PoisonOr α) (b : PoisonOr β) (f : α → β → PoisonOr γ) : PoisonOr γ :=
  (a >>= fun x => b >>= f x)

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

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

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

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

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

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

def t1_flags_nuw_only_after := [llvm|
{
^0(%arg45 : i8, %arg46 : i8, %arg47 : i8):
  %0 = llvm.add %arg46, %arg47 overflow<nuw> : i8
  %1 = llvm.sub %arg45, %0 overflow<nuw> : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

def test85_after := [llvm|
{
^0(%arg60 : i32):
  %0 = llvm.mlir.constant(2130706432 : i32) : i32
  %1 = llvm.mlir.constant(23 : i32) : i32
  %2 = llvm.add %arg60, %0 : i32
  %3 = llvm.lshr %2, %1 : i32
  %4 = llvm.trunc %3 : i32 to i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

def FpBinOp.toString : FpBinOp → String
  | FpBinOp.add => "+"

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

BitVec.allOnes in Init.Data.BitVec.Basic

def canonicalize_logic_first_and0_nsw_after := [llvm|
{
^0(%arg27 : i8):
  %0 = llvm.mlir.constant(-10 : i8) : i8
  %1 = llvm.mlir.constant(48 : i8) : i8
  %2 = llvm.and %arg27, %0 : i8
  %3 = llvm.add %2, %1 overflow<nsw> : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

instance {n} : ShiftRight (BitVec n) := ⟨fun x y => x >>> y.toNat⟩

Array.size in Init.Prelude

def test0_before := [llvm|
{
^0(%arg6 : i41, %arg7 : i41, %arg8 : i41):
  %0 = llvm.shl %arg6, %arg8 : i41
  %1 = llvm.shl %arg7, %arg8 : i41
  %2 = llvm.and %0, %1 : i41
  "llvm.return"(%2) : (i41) -> ()
}
]

def shl_add_lshr_after := [llvm|
{
^0(%arg154 : i32, %arg155 : i32, %arg156 : i32):
  %0 = llvm.lshr %arg156, %arg155 : i32
  %1 = llvm.add %0, %arg154 overflow<nuw> : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

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

RV64.rol in RISCV.Instructions

def shrink_and_before := [llvm|
{
^0(%arg9 : i64):
  %0 = llvm.mlir.constant(42) : i64
  %1 = llvm.and %arg9, %0 : i64
  %2 = llvm.trunc %1 : i64 to i31
  "llvm.return"(%2) : (i31) -> ()
}
]

def uge_umin1_after := [llvm|
{
^0(%arg52 : i32, %arg53 : i32):
  %0 = llvm.icmp "uge" %arg53, %arg52 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

def reduce_xor_common_op_commute1_after := [llvm|
{
^0(%arg7 : i4, %arg8 : i4, %arg9 : i4):
  %0 = llvm.xor %arg8, %arg9 : i4
  %1 = llvm.or %0, %arg7 : i4
  "llvm.return"(%1) : (i4) -> ()
}
]

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

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

def NFA.autWidthSA (n : Nat) (q : Fin (n+2)) : Language (BitVec 0) :=
  if q = Fin.last (n+1) then { w | w.length > n } else { w | w.length = q }

def lor_bor_left1_before := [llvm|
{
^0(%arg66 : i1, %arg67 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = "llvm.select"(%arg66, %0, %arg67) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %2 = llvm.or %1, %arg66 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

def sdiv_one_one : BitVec.sdiv 1#w 1#w = 1#w :=

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

WithBot.unbotD in Mathlib.Order.WithBot

def Factor.toExpr (f : Factor) : Expr :=
  match f with
  | .var i => mkApp (mkConst ``Factor.var) (mkNatLit i)
  | .xor i j => mkApp2 (mkConst ``Factor.xor) i.toExpr j.toExpr
  | .and i j => mkApp2 (mkConst ``Factor.and) i.toExpr j.toExpr
  | .or i j => mkApp2 (mkConst ``Factor.or) i.toExpr j.toExpr
  | .not x => mkApp (mkConst ``Factor.not) x.toExpr

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

def visitADD : List (Σ Γ, LLVMPeepholeRewriteRefine 64 Γ) :=
[⟨_, visitADD_0⟩,
 ⟨_, visitADD_Sameop⟩,
 ⟨_, visitADD_Neg1⟩,
 ⟨_, visitADD_ZeroNegAPlusB⟩,
 ⟨_, visitADD_APlusZeroNegB⟩,
 ⟨_, visitADD_APlusBNegA⟩,
 ⟨_, visitADD_BNegAPlusA⟩,
 ⟨_, visitADD_ANegBPlusCNegA⟩,
 ⟨_, visitADD_ANegBPlusBNegC⟩,
 ⟨_, visitADD_APlusBNegAPlusC⟩,
 ⟨_, visitADD_APlusBNegCPlusA⟩,
 ⟨_, visitADD_XorNeg1Plus1⟩,
 ⟨_, visitADD_XorNeg1PlusBPlus1⟩,
 ⟨_, visitADD_PlusNeg1⟩]

def sext_zext_nneg_sge_op0_narrow_before := [llvm|
{
^0(%arg30 : i5, %arg31 : i8):
  %0 = llvm.sext %arg30 : i5 to i32
  %1 = llvm.zext nneg %arg31 : i8 to i32
  %2 = llvm.icmp "sge" %0, %1 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

structure PeepholeRewrite (Γ : List d.Ty) (ts : List d.Ty) where
  lhs : Com d (.ofList Γ) .pure ts
  rhs : Com d (.ofList Γ) .pure ts
  correct : lhs.denote = rhs.denote

def test16_after := [llvm|
{
^0(%arg81 : i32, %arg82 : i32):
  %0 = llvm.mlir.constant(11 : i32) : i32
  %1 = llvm.mlir.constant(4 : i32) : i32
  %2 = llvm.mlir.constant(3 : i32) : i32
  %3 = llvm.lshr %arg82, %0 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.or disjoint %4, %2 : i32
  %6 = llvm.and %arg81, %5 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def select_same_val_self : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 1), Ty.llvm (.bitvec 64) ] where
  lhs := [LV| {
    ^entry (%x: i64, %c: i1):
      %0 = llvm.select %c, %x, %x : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64, %c: i1):
      llvm.return %x : i64
  }]

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

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

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

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

Vector.ofFn in Init.Data.Vector.Basic

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

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

def test2_after := [llvm|
{
^0(%arg2 : i49):
  %0 = llvm.mlir.constant(8388607 : i49) : i49
  %1 = llvm.and %arg2, %0 : i49
  "llvm.return"(%1) : (i49) -> ()
}
]

def Expr.KInductionCircuits.mkMkSafetyCircuit (circs : Expr) : SolverM Expr := do
  let out ← mkAppM ``ReflectVerif.BvDecide.KInductionCircuits.mkSafetyCircuit #[circs]
  debugCheck out
  return out

@[simp_denote]
def udiv_riscv_64: Com  LLVMPlusRiscV ⟨[.llvm (.bitvec 64), .llvm (.bitvec 64)]⟩
  .pure (.llvm (.bitvec 64)) := [LV| {
  ^entry (%reg1: i64, %reg2: i64):
    %0 = "builtin.unrealized_conversion_cast"(%reg1) : (i64) -> (!i64)
    %1 = "builtin.unrealized_conversion_cast"(%reg2) : (i64) -> (!i64)
    %2 = divu %0, %1 : !i64
    %3 = "builtin.unrealized_conversion_cast"(%2) : (!i64) -> (i64)
    llvm.return %3 : i64
  }]

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 main6d_logical_after := [llvm|
{
^0(%arg87 : i32):
  %0 = llvm.mlir.constant(23 : i32) : i32
  %1 = llvm.mlir.constant(19 : i32) : i32
  %2 = llvm.and %arg87, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  %4 = llvm.zext %3 : i1 to i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def t1_otherbitwidth_after := [llvm|
{
^0(%arg11 : i16):
  %0 = llvm.mlir.constant(1 : i16) : i16
  %1 = llvm.mlir.constant(0 : i16) : i16
  %2 = llvm.and %arg11, %0 : i16
  %3 = llvm.sub %1, %2 overflow<nsw> : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

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

@[simp_denote]
def trunc_llvm_32_to_16 := [LV| {
  ^entry (%lhs: i32):
    %0 = llvm.trunc %lhs : i32 to i16
    llvm.return %0 : i16
  }]

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

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

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

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

def irc_constants_APlusC1MinusC2_2_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.add %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.sub %c1, %c2 : i64
      %1 = llvm.add %a, %0 : i64
      llvm.return %1 : i64
  }]

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

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

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

instance {n} : ShiftLeft (BitVec n) := ⟨fun x y => x <<< y.toNat⟩

def transpose' {A : α → Type} {as : List α}
    (xs : HVector (fun a => Stream (A a)) as) :
    Stream (HVector A as) :=
  corec xs fun xs =>
    let xs := xs.map fun _ x => x.dropFirstNone
    let out := xs.mapM fun _ x => x.head
    
    let xs :=
      if out.isSome
        then xs.map fun _ x => x.tail
        else xs

    (out, xs)

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

NeZero in Init.Data.NeZero

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

def add_negative_high_bound_accept_test: LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := add_negative_high_bound_accept_llvm
  rhs := add_negative_high_bound_accept_riscv

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

def sext_diff_i1_xor_sub_before := [llvm|
{
^0(%arg15 : i64, %arg16 : i1, %arg17 : i1):
  %0 = llvm.sext %arg16 : i1 to i64
  %1 = llvm.sext %arg17 : i1 to i64
  %2 = llvm.xor %arg15, %0 : i64
  %3 = llvm.sub %0, %1 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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

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

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

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

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

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

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

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

def foo_before := [llvm|
{
^0(%arg2 : i32, %arg3 : i32):
  %0 = llvm.add %arg3, %arg2 overflow<nsw> : i32
  %1 = llvm.mul %0, %arg3 overflow<nsw> : i32
  %2 = llvm.mul %arg3, %arg3 overflow<nsw> : i32
  %3 = llvm.sub %1, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def test1_before := [llvm|
{
^0(%arg2 : i177):
  %0 = llvm.mlir.constant(1 : i177) : i177
  %1 = llvm.mlir.constant(155 : i177) : i177
  %2 = llvm.shl %0, %1 : i177
  %3 = llvm.mul %arg2, %2 : i177
  "llvm.return"(%3) : (i177) -> ()
}
]

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

def icmp_select_var_pred_ult_after := [llvm|
{
^0(%arg68 : i8, %arg69 : i8, %arg70 : i8):
  %0 = llvm.mlir.constant(2 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.add %arg70, %0 overflow<nuw> : i8
  %4 = llvm.icmp "eq" %arg68, %1 : i8
  %5 = llvm.icmp "ult" %arg69, %3 : i8
  %6 = "llvm.select"(%4, %2, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

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

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

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

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

instance :   XorOp BitStream := ⟨map₂ Bool.xor⟩

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

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

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

instance : Lean.ToExpr RegIndex := inherit

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

def orn_and_cmp_2_logical_before := [llvm|
{
^0(%arg9 : i16, %arg10 : i16, %arg11 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "sge" %arg9, %arg10 : i16
  %3 = llvm.icmp "slt" %arg9, %arg10 : i16
  %4 = "llvm.select"(%arg11, %2, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %5 = "llvm.select"(%4, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def p_constmask2_after := [llvm|
{
^0(%arg41 : i32, %arg42 : i32):
  %0 = llvm.mlir.constant(61440 : i32) : i32
  %1 = llvm.mlir.constant(-65281 : i32) : i32
  %2 = llvm.and %arg41, %0 : i32
  %3 = llvm.and %arg42, %1 : i32
  %4 = llvm.or disjoint %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

@[simp_denote]
def add_shl_moreOneUse_sh1add := [LV| {
    ^entry (%a: i32):
    %0 = llvm.mlir.constant (1) : i32
    %1 = llvm.or %a, %0 : i32
    %2 = llvm.shl %1, %0 : i32
    %3 = llvm.add %2, %1 : i32
    llvm.return %3 : i32
  }]

def t11_shl_nsw_flag_preservation_after := [llvm|
{
^0(%arg21 : i32, %arg22 : i32):
  %0 = llvm.mlir.constant(30 : i32) : i32
  %1 = llvm.shl %arg21, %0 overflow<nsw> : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

def substBvEqualities (g : MVarId) : MetaM (Option MVarId) := g.withContext do
  let gs ← g.casesRec fun localDecl => do
    let some (ty, _lhs, _rhs) := localDecl.type.eq?
      | return false
    return ty.isConstOf ``BitVec
  ensureAtMostOne gs

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

def cadicalTimeoutSec : Nat := 1000

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

def not_and_and_not_commute1_after := [llvm|
{
^0(%arg561 : i32, %arg562 : i32, %arg563 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg562, %arg563 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.and %arg561, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

@[simp_denote]
def shl_llvm_nsw_nuw_8 := [LV| {
  ^entry (%x: i8, %y: i8):
    %1 = llvm.shl    %x, %y overflow<nsw,nuw> : i8
    llvm.return %1 : i8
  }]

def t9_ashr_exact_flag_preservation_after := [llvm|
{
^0(%arg25 : i32, %arg26 : i32):
  %0 = llvm.mlir.constant(30 : i32) : i32
  %1 = llvm.ashr exact %arg25, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

instance [ToString w] : ToString (Option w) where
  toString
    | some x => s!"(some {toString x})"
    | none   => "(none)"

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

def 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 test_lshr_exact__exact_is_safe_after := [llvm|
{
^0(%arg62 : i32, %arg63 : i64):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(15 : i32) : i32
  %2 = llvm.lshr %arg62, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.zext nneg %3 : i32 to i64
  %5 = llvm.ashr %arg63, %4 : i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

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

def test23_before := [llvm|
{
^0(%arg143 : i8):
  %0 = llvm.mlir.constant(-2 : i8) : i8
  %1 = llvm.mlir.constant(13 : i8) : i8
  %2 = llvm.mlir.constant(1 : i8) : i8
  %3 = llvm.mlir.constant(12 : i8) : i8
  %4 = llvm.or %arg143, %0 : i8
  %5 = llvm.xor %4, %1 : i8
  %6 = llvm.or %5, %2 : i8
  %7 = llvm.xor %6, %3 : i8
  "llvm.return"(%7) : (i8) -> ()
}
]

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

def xori_i32_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := xori_llvm_i32
  rhs := xori_riscv_i32

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

def uge_swap_or_max_logical_after := [llvm|
{
^0(%arg164 : i8, %arg165 : i8):
  %0 = llvm.icmp "ule" %arg165, %arg164 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

def AndShlShl : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64, %y: i64, %z: i64):
      %0 = llvm.shl %x, %z : i64
      %1 = llvm.shl %y, %z : i64
      %2 = llvm.and %0, %1 : i64
      llvm.return %2 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64, %y: i64, %z: i64):
      %0 = llvm.and %x, %y : i64
      %1 = llvm.shl %0, %z : i64
      llvm.return %1 : i64
  }]

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

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

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

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

def lshr_add_fail_before := [llvm|
{
^0(%arg15 : i8):
  %0 = llvm.mlir.constant(16 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.mlir.constant(7 : i8) : i8
  %3 = llvm.lshr %0, %arg15 : i8
  %4 = llvm.add %arg15, %1 : i8
  %5 = llvm.lshr %2, %4 : i8
  %6 = llvm.add %3, %5 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

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

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

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

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

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

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

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

def select_icmp_ne_0_and_1073741824_and_not_8_before := [llvm|
{
^0(%arg191 : i32, %arg192 : i8):
  %0 = llvm.mlir.constant(1073741824 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(-9 : i8) : i8
  %3 = llvm.and %arg191, %0 : i32
  %4 = llvm.icmp "ne" %1, %3 : i32
  %5 = llvm.and %arg192, %2 : i8
  %6 = "llvm.select"(%4, %arg192, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%6) : (i8) -> ()
}
]

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

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

def udiv_i32_c_multiuse_after := [llvm|
{
^0(%arg12 : i8):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.zext %arg12 : i8 to i32
  %2 = llvm.udiv %1, %0 : i32
  %3 = llvm.add %2, %1 overflow<nsw,nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def Body.WellTyped (Γ : Context Ty) : UnTyped.Body Op VarName → Ty → Prop
  | ⟨lets, v⟩, ty =>
      let Γ_out := Lets.outContext lets Γ
      
      
      Lets.WellTyped Γ lets Γ_out ∧ Γ_out.hasType v ty

def alive_AndOrXor_1704_src :=
[sllvm| {
^bb0(%A : i64, %B : i64):
  %v1 = llvm.mlir.constant 0 : i64
  %v2 = llvm.icmp.eq %B, %v1 : i64
  %v3 = llvm.icmp.ult %A, %B : i64
  %v4 = llvm.or %v2, %v3 : i1
  llvm.return %v4 : i1
}]

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 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 test_ne_11_and_15_add_10_after := [llvm|
{
^0(%arg0 : i8):
  %0 = llvm.mlir.constant(15 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.and %arg0, %0 : i8
  %3 = llvm.icmp "ne" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def test17_before := [llvm|
{
^0(%arg154 : i8, %arg155 : i8):
  %0 = llvm.mlir.constant(33 : i8) : i8
  %1 = llvm.xor %arg155, %arg154 : i8
  %2 = llvm.xor %arg154, %0 : i8
  %3 = llvm.xor %2, %arg155 : i8
  %4 = llvm.or %1, %3 : i8
  %5 = llvm.mul %4, %3 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

def t0_after := [llvm|
{
^0(%arg8 : i8, %arg9 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.ashr %arg8, %arg9 : i8
  %2 = llvm.xor %1, %0 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

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

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

def initialGeneralizerState (startTime timeout widthId targetWidth: Nat) (parsedLogicalExpr : ParsedBVLogicalExpr)
            : BVGeneralizerState := { startTime := startTime
                                    , widthId := widthId
                                    , timeout := timeout
                                    , processingWidth           := targetWidth
                                    , targetWidth               := targetWidth
                                    , parsedLogicalExpr       := parsedLogicalExpr
                                    , needsPreconditionsExprs   := []
                                    , visitedSubstitutions      := Std.HashSet.emptyWithCapacity
                                    }

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

def prettifyBVExpr (bvExpr : GenBVExpr w) (displayNames: Std.HashMap Nat HydraVariable) (widthVals: Std.HashMap Nat HydraVariable): String :=
    match bvExpr with
    | .var idx => displayNames[idx]!.name.toString
    | .const bv =>
       toString bv.toInt
    | .bin lhs BVBinOp.add (.bin  (GenBVExpr.const bv) BVBinOp.add (GenBVExpr.un BVUnOp.not rhs)) =>
      if bv.toInt == 1 then 
        s! "({prettifyBVExpr lhs displayNames widthVals} - {prettifyBVExpr rhs displayNames widthVals})"
      else
        s! "({prettifyBVExpr lhs displayNames widthVals} + ({prettifyBVExpr (GenBVExpr.const bv) displayNames widthVals} + {prettifyBVExpr (GenBVExpr.un BVUnOp.not rhs) displayNames widthVals}))"
    | .bin lhs op rhs =>
       s! "({prettifyBVExpr lhs displayNames widthVals} {prettifyBVBinOp op} {prettifyBVExpr rhs displayNames widthVals})"
    | .un op operand =>
       s! "({op.toString} {prettifyBVExpr operand displayNames widthVals})"
    | .shiftLeft lhs rhs =>
        s! "({prettifyBVExpr lhs displayNames widthVals} <<< {prettifyBVExpr rhs displayNames widthVals})"
    | .shiftRight lhs rhs =>
        s! "({prettifyBVExpr lhs displayNames widthVals} >>> {prettifyBVExpr rhs displayNames widthVals})"
    | .arithShiftRight lhs rhs =>
        s! "({prettifyBVExpr lhs displayNames widthVals} >>>a {prettifyBVExpr rhs displayNames widthVals})"
    | .signExtend v expr => s! "BitVec.signExtend {widthVals[v]!.name.toString} {prettifyBVExpr expr displayNames widthVals}"
    | .zeroExtend v expr => s! "BitVec.zeroExtend {widthVals[v]!.name.toString} {prettifyBVExpr expr displayNames widthVals}"
    | .truncate v expr =>   s! "BitVec.truncate {widthVals[v]!.name.toString} {prettifyBVExpr expr displayNames widthVals}"
    | _ => bvExpr.toString

def ule_or_not_min_logical_before := [llvm|
{
^0(%arg270 : i427, %arg271 : i427):
  %0 = llvm.mlir.constant(0 : i427) : i427
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "ule" %arg270, %arg271 : i427
  %3 = llvm.icmp "ne" %arg270, %0 : i427
  %4 = "llvm.select"(%2, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def or_xor_tree_1011_after := [llvm|
{
^0(%arg12 : i32, %arg13 : i32, %arg14 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mul %arg12, %0 : i32
  %2 = llvm.mul %arg13, %0 : i32
  %3 = llvm.mul %arg14, %0 : i32
  %4 = llvm.xor %2, %1 : i32
  %5 = llvm.or %4, %3 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def xor_and_or_before := [llvm|
{
^0(%arg6 : i1, %arg7 : i1, %arg8 : i1):
  %0 = llvm.or %arg8, %arg6 : i1
  %1 = llvm.and %arg6, %arg7 : i1
  %2 = llvm.xor %1, %0 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

RV64.addw in RISCV.Instructions

def sext_zext_apint1_before := [llvm|
{
^0(%arg86 : i77):
  %0 = llvm.zext %arg86 : i77 to i533
  %1 = llvm.sext %0 : i533 to i1024
  "llvm.return"(%1) : (i1024) -> ()
}
]

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 or_and_not_not_commute4_after := [llvm|
{
^0(%arg413 : i32, %arg414 : i32, %arg415 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg415, %arg414 : i32
  %2 = llvm.or %1, %arg413 : i32
  %3 = llvm.xor %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

structure Item where
 name : String
 tac : Syntax

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_sandwich_min_shift1_before := [llvm|
{
^0(%arg68 : i32):
  %0 = llvm.mlir.constant(20 : i32) : i32
  %1 = llvm.mlir.constant(1 : i12) : i12
  %2 = llvm.lshr %arg68, %0 : i32
  %3 = llvm.trunc %2 : i32 to i12
  %4 = llvm.lshr %3, %1 : i12
  "llvm.return"(%4) : (i12) -> ()
}
]

def test_sub_nuw__nuw_is_safe_before := [llvm|
{
^0(%arg26 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.mlir.constant(1073741824 : i32) : i32
  %2 = llvm.mlir.constant(-2147483648 : i32) : i32
  %3 = llvm.and %arg26, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.sub %2, %3 overflow<nuw> : i32
  %6 = "llvm.select"(%4, %1, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def TermBinop.openTerm (op : TermBinop) : Term := op.subst (.var 0) (.var 1)

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

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

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

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

def demorgan_nor_use2ab_after := [llvm|
{
^0(%arg24 : i8, %arg25 : i8):
  %0 = llvm.mlir.constant(23 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.mlir.constant(17 : i8) : i8
  %3 = llvm.mul %arg25, %0 : i8
  %4 = llvm.xor %arg24, %1 : i8
  %5 = llvm.mul %4, %2 : i8
  %6 = llvm.xor %arg25, %1 : i8
  %7 = llvm.and %arg24, %6 : i8
  %8 = llvm.sdiv %7, %3 : i8
  %9 = llvm.sdiv %8, %5 : i8
  "llvm.return"(%9) : (i8) -> ()
}
]

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

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

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

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 ofList (vals : List (Option α)) : Stream α :=
  fun i => (vals[i]?).join

def scalar_i64_shl_and_negC_eq_before := [llvm|
{
^0(%arg29 : i64, %arg30 : i64):
  %0 = llvm.mlir.constant(-8589934592) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.shl %arg29, %arg30 : i64
  %3 = llvm.and %2, %0 : i64
  %4 = llvm.icmp "eq" %3, %1 : i64
  "llvm.return"(%4) : (i1) -> ()
}
]

@[simp_denote]
def add_b32_riscv_i64_no_ZBS :=
  [LV| {
    ^entry (%x: i64):
    %0 ="li"() {imm = -1 : !i64} : (!i64) -> (!i64)
    %1 = slli %0, 32 : !i64
    %a0 = "builtin.unrealized_conversion_cast" (%x) : (i64) -> (!i64)
    %2 = add %a0, %1 : !i64
    %3 = "builtin.unrealized_conversion_cast" (%2) : (!i64) -> (i64)
    llvm.return %3 : i64
  }]

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 freeze_match : List (Σ Γ, Σ ty, PeepholeRewrite LLVMPlusRiscV Γ ty) := [
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_freeze_lower_riscv_8),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_freeze_lower_riscv_16),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_freeze_lower_riscv_32),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_freeze_lower_riscv_64)
]

def test9_before := [llvm|
{
^0(%arg14 : i42):
  %0 = llvm.mlir.constant(3 : i42) : i42
  %1 = llvm.mul %0, %arg14 : i42
  %2 = llvm.sub %arg14, %1 : i42
  "llvm.return"(%2) : (i42) -> ()
}
]

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

def PR60818_eq_commuted_before := [llvm|
{
^0(%arg3 : i32):
  %0 = llvm.mlir.constant(43 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mul %arg3, %0 : i32
  %3 = llvm.sub %1, %2 : i32
  %4 = llvm.icmp "eq" %2, %3 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def Expr.WellTyped (Γ : Context Ty) : UnTyped.Expr Op VarName → Ty → Prop
  | ⟨_, op, args, regions⟩, ty =>
    let ⟨argTys, rgnTys, retTy⟩ := signature op
    args.length = argTys.length
      ∧ (∀ x ∈ args.zip argTys, Γ.hasType x.fst x.snd)
    ∧ RegionList.WellTyped regions rgnTys
    ∧ ty = retTy

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

def src_is_mask_or_after := [llvm|
{
^0(%arg117 : i8, %arg118 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(7 : i8) : i8
  %2 = llvm.mlir.constant(123 : i8) : i8
  %3 = llvm.lshr %0, %arg118 : i8
  %4 = llvm.and %3, %1 : i8
  %5 = llvm.xor %arg117, %2 : i8
  %6 = llvm.icmp "ule" %5, %4 : i8
  "llvm.return"(%6) : (i1) -> ()
}
]

def yw : WidthExpr 1 := WidthExpr.var ⟨0, by admit /- proof elided -/
⟩

def lshr_mul_nuw_nsw_before := [llvm|
{
^0(%arg34 : i64):
  %0 = llvm.mlir.constant(52) : i64
  %1 = llvm.mlir.constant(2) : i64
  %2 = llvm.mul %arg34, %0 overflow<nsw,nuw> : i64
  %3 = llvm.lshr %2, %1 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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

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

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

Ring in Mathlib.Algebra.Ring.Defs

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

def add_1_after := [llvm|
{
^0(%arg125 : i8, %arg126 : i1, %arg127 : i8, %arg128 : i8):
  %0 = llvm.mlir.constant(-124 : i8) : i8
  %1 = llvm.xor %arg128, %0 : i8
  %2 = "llvm.select"(%arg126, %arg127, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %3 = llvm.sub %2, %arg125 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

def test7_before := [llvm|
{
^0(%arg202 : i32, %arg203 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(128 : i32) : i32
  %2 = llvm.and %arg202, %0 : i32
  %3 = llvm.and %arg203, %1 : i32
  %4 = llvm.xor %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

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

def t2_after := [llvm|
{
^0(%arg15 : i7):
  %0 = llvm.mlir.constant(3 : i7) : i7
  %1 = llvm.ashr %arg15, %0 : i7
  %2 = llvm.sext %1 : i7 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

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

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

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

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

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

def and_not_or_commute9_after := [llvm|
{
^0(%arg454 : i32, %arg455 : i32, %arg456 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg454 : i32
  %3 = llvm.sdiv %0, %arg455 : i32
  %4 = llvm.sdiv %0, %arg456 : i32
  %5 = llvm.xor %3, %4 : i32
  %6 = llvm.and %5, %2 : i32
  %7 = llvm.xor %6, %1 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

def and_xor_or8_before := [llvm|
{
^0(%arg652 : i64, %arg653 : i64, %arg654 : i64):
  %0 = llvm.mlir.constant(42) : i64
  %1 = llvm.udiv %0, %arg652 : i64
  %2 = llvm.udiv %0, %arg653 : i64
  %3 = llvm.udiv %0, %arg654 : i64
  %4 = llvm.and %2, %1 : i64
  %5 = llvm.xor %3, %4 : i64
  %6 = llvm.or %2, %5 : i64
  "llvm.return"(%6) : (i64) -> ()
}
]

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 trunc_equality_nuw_after := [llvm|
{
^0(%arg44 : i16, %arg45 : i16):
  %0 = llvm.icmp "eq" %arg44, %arg45 : i16
  "llvm.return"(%0) : (i1) -> ()
}
]

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

inductive GenBVPred where
   
  | bin (lhs : GenBVExpr w) (op : BVBinPred) (rhs : GenBVExpr w)
   
  | getLsbD (expr : GenBVExpr w) (idx : Nat)
deriving Hashable, BEq, DecidableEq

Lean.FileMap.ofString in Lean.Data.Position

def no_shift_no_xor_multiuse_cmp_xor_before := [llvm|
{
^0(%arg56 : i32, %arg57 : i32, %arg58 : i32, %arg59 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg56, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  %4 = llvm.xor %arg57, %0 : i32
  %5 = "llvm.select"(%3, %arg57, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %6 = "llvm.select"(%3, %arg58, %arg59) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = llvm.mul %5, %6 : i32
  %8 = llvm.mul %7, %4 : i32
  "llvm.return"(%8) : (i32) -> ()
}
]

def lshr_sext_i1_to_i16_after := [llvm|
{
^0(%arg54 : i1):
  %0 = llvm.mlir.constant(4095 : i16) : i16
  %1 = llvm.mlir.constant(0 : i16) : i16
  %2 = "llvm.select"(%arg54, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i16, i16) -> i16
  "llvm.return"(%2) : (i16) -> ()
}
]

def drop_both_trunc_before := [llvm|
{
^0(%arg9 : i16, %arg10 : i16):
  %0 = llvm.mlir.constant(255 : i16) : i16
  %1 = llvm.and %arg9, %0 : i16
  %2 = llvm.and %1, %arg10 : i16
  %3 = llvm.trunc %2 overflow<nsw,nuw> : i16 to i8
  "llvm.return"(%3) : (i8) -> ()
}
]

@[simp]
def mkOutEqZeroCircuitN {arity : Type _}
  [DecidableEq arity]
  [Fintype arity]
  [Hashable arity]
  (p : FSM arity) (n : Nat) :
  Circuit (Vars p.α arity (n + 1)) :=
    
    
    Circuit.xor
      (Circuit.ofBool false)
      (Circuit.var true <| Vars.outputs ⟨n, by admit /- proof elided -/
      ⟩)

instance : ToString Row where
  toString r :=
    s!"{r.opName}, {r.bitwidth}, {r.v1}, {r.v2}, {r.v3}, {r.retval}"

def shl_trunc_smaller_lshr_after := [llvm|
{
^0(%arg43 : i32):
  %0 = llvm.mlir.constant(2 : i8) : i8
  %1 = llvm.mlir.constant(-32 : i8) : i8
  %2 = llvm.trunc %arg43 : i32 to i8
  %3 = llvm.shl %2, %0 : i8
  %4 = llvm.and %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

noncomputable def dropLeadingNones (x : Stream α) (not_stuck : x ≠ stuck α) : Stream α:=
  x.drop (nonesUntilSome x not_stuck)

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

Lean.Elab.Tactic.withMainContext in Lean.Elab.Tactic.Basic

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

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

def liftTy : MLIR2Comb.Ty → MLIR2DC.Ty
| .bitvec w => .valuestream w

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

partial def prettify (generalization: BoolExpr  GenBVPred) (displayNames: Std.HashMap Nat HydraVariable) (widthVals: Std.HashMap Nat HydraVariable)  : String :=
  match (prettifyComparison generalization displayNames widthVals) with
  | some s => s
  | none =>
      match generalization with
      | .literal (GenBVPred.bin lhs op rhs) =>
          s! "{prettifyBVExpr lhs displayNames widthVals} {prettifyBVBinPred op} {prettifyBVExpr rhs displayNames widthVals}"
      | .not boolExpr =>
          s! "!({prettify boolExpr displayNames widthVals})"
      | .gate op lhs rhs =>
          match (lhs, rhs) with
          | (BoolExpr.const _, rhs) =>
             s! "({prettify rhs displayNames widthVals})"
          | (lhs, BoolExpr.const _) =>
             s! "({prettify lhs displayNames widthVals})"
          | _ =>
             s! "({prettify lhs displayNames widthVals}) {op.toString} ({prettify rhs displayNames widthVals})"
      | .ite cond positive _ =>
          s! "(h : {prettify cond displayNames widthVals}) : ({prettify positive displayNames widthVals})"
      | _ => generalization.toString

def narrow_zext_add_after := [llvm|
{
^0(%arg42 : i16, %arg43 : i32):
  %0 = llvm.trunc %arg43 : i32 to i16
  %1 = llvm.add %arg42, %0 : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

@[simp_denote]
def add_negative_high_bound_reject_riscv :=
  [LV| {
    ^entry (%arg: i32):
    %a =  "builtin.unrealized_conversion_cast" (%arg) : (i32) -> (!i64)
    %0 = "addiw"  (%a) {imm = -2048 : !i64} : (!i64) -> (!i64)
    %1 =  "builtin.unrealized_conversion_cast" (%0) : (!i64) -> (i32)
    llvm.return %1 :i32
  }]

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

@[irreducible]
def irreduciblePow (q n : Nat) : Nat := q^n

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

def or_ranges_single_elem_left_before := [llvm|
{
^0(%arg257 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.mlir.constant(10 : i8) : i8
  %2 = llvm.mlir.constant(4 : i8) : i8
  %3 = llvm.icmp "uge" %arg257, %0 : i8
  %4 = llvm.icmp "ule" %arg257, %1 : i8
  %5 = llvm.and %3, %4 : i1
  %6 = llvm.icmp "eq" %arg257, %2 : i8
  %7 = llvm.or %5, %6 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

def trunc_lshr_sext_wide_input_after := [llvm|
{
^0(%arg33 : i16):
  %0 = llvm.mlir.constant(9 : i16) : i16
  %1 = llvm.ashr %arg33, %0 : i16
  %2 = llvm.trunc %1 overflow<nsw> : i16 to i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

def or_not_xor_common_op_commute3_after := [llvm|
{
^0(%arg98 : i8, %arg99 : i8, %arg100 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.sub %0, %arg100 : i8
  %3 = llvm.and %arg98, %arg99 : i8
  %4 = llvm.xor %3, %1 : i8
  %5 = llvm.or %4, %2 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def sext {w: Nat} (w': Nat) (x: IntW w) : IntW w' := do
  let x' <- x
  sext? w' x'

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

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

def 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 PackedFloat.ofBV (bv : BitVec (1 + e + M)) : PackedFloat e M where
  sign := bv[e + M]
  ex := bv.extractLsb' M e
  sig := bv.extractLsb' 0 M

instance {n} : ShiftLeft (BitVec n) := ⟨fun x y => x <<< y.toNat⟩

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

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

def test25_logical_before := [llvm|
{
^0(%arg270 : i32):
  %0 = llvm.mlir.constant(50 : i32) : i32
  %1 = llvm.mlir.constant(100 : i32) : i32
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.icmp "sge" %arg270, %0 : i32
  %4 = llvm.icmp "slt" %arg270, %1 : i32
  %5 = "llvm.select"(%3, %4, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%5) : (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 revertNonDepPropHyps (g : MVarId) : MetaM MVarId := do
  g.withContext do
    let (_, g) ← g.revert (← g.getNondepPropHyps)
    return g

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

def addValToMapping (Γ : Ctxt d.Ty) (name : String) (ty : d.Ty) :
    BuilderM d (Σ (Γ' : DerivedCtxt Γ), Ctxt.Var Γ'.ctxt ty) := do
  let some nm := (←get).add name
    | throw <| .nameAlreadyDeclared name
  set nm
  return ⟨DerivedCtxt.ofCtxt Γ |>.cons ty, Ctxt.Var.last ..⟩

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

def p2_scalar_shifted_urem_by_const_before := [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 : i32
  %5 = llvm.urem %4, %1 : i32
  %6 = llvm.icmp "eq" %5, %2 : i32
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

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

def sgt_and_not_min_before := [llvm|
{
^0(%arg94 : i8, %arg95 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.icmp "sgt" %arg94, %arg95 : i8
  %2 = llvm.icmp "ne" %arg94, %0 : i8
  %3 = llvm.and %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

instance {test : ConcreteCliTest} : ToString (toType test.ty) where
  toString :=
    match test.ty with
    | bitvec w => inferInstanceAs (ToString (PoisonOr <| BitVec w)) |>.toString

def shift_no_xor_multiuse_cmp_before := [llvm|
{
^0(%arg120 : i32, %arg121 : i32, %arg122 : i32, %arg123 : 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 %arg120, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.or %arg121, %2 : i32
  %6 = "llvm.select"(%4, %arg121, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg122, %arg123) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %8 = llvm.mul %6, %7 : i32
  "llvm.return"(%8) : (i32) -> ()
}
]

def and_or_not_not_wrong_b_before := [llvm|
{
^0(%arg328 : i32, %arg329 : i32, %arg330 : i32, %arg331 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg331, %arg328 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.and %arg328, %arg330 : i32
  %4 = llvm.xor %3, %0 : i32
  %5 = llvm.or %4, %arg329 : i32
  %6 = llvm.and %5, %2 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def mkCarryAssignCircuitN {arity : Type _}
  [DecidableEq arity]
  [Fintype arity]
  [Hashable arity]
  (p : FSM arity) (n : Nat) :
  Circuit (Vars p.α arity (n + 1)) :=
  let carrys := FinEnum.toList p.α |>.map fun s =>
    
    Circuit.xor
      (mkCarryAssignCircuitNAux p s n)
      (Circuit.var true <| Vars.stateN s (n + 1))
  Circuit.bigOr carrys

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

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

def shl_or_lshr_comm_after := [llvm|
{
^0(%arg106 : i32, %arg107 : i32, %arg108 : i32):
  %0 = llvm.lshr %arg108, %arg107 : i32
  %1 = llvm.or %0, %arg106 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def CombEg4 := [Comb_com| {
  ^entry(%0: i4, %1 : i4):
    %2 = "Comb.icmp_eq" (%0, %1) : (i4, i4) -> i1
    "return" (%2) : (i1) -> ()
  }]

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

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

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

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

instHAdd in Init.Prelude

def mul_selectp2_x_non_const_before := [llvm|
{
^0(%arg15 : i8, %arg16 : i1, %arg17 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.shl %0, %arg17 : i8
  %3 = "llvm.select"(%arg16, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = llvm.mul %3, %arg15 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

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

def bitwise_and_logical_and_icmps_comm3_before := [llvm|
{
^0(%arg223 : i8, %arg224 : i8, %arg225 : 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" %arg224, %0 : i8
  %5 = llvm.and %arg223, %1 : i8
  %6 = llvm.shl %1, %arg225 : i8
  %7 = llvm.and %arg223, %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.and %9, %10 : i1
  "llvm.return"(%11) : (i1) -> ()
}
]

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

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

def shl_bad_sub_i32_after := [llvm|
{
^0(%arg12 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.sub %0, %arg12 : i32
  %3 = llvm.shl %1, %2 overflow<nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

def fpExprToExpr (ParsedFpExpr : ParsedFpLogicalExpr)
  (bvExpr : FpExpr w) : MetaM Expr := do
  let ParsedFpExprState := ParsedFpExpr.state
  let allVars := Std.HashMap.union ParsedFpExprState.inputVarIdToVariable ParsedFpExprState.symVarIdToVariable

  match bvExpr with
  | .var idx => let some var := allVars[idx]? | throwError m! "Could not find var: {idx} in {bvExpr}"
                let localDecl ← getLocalDeclFromUserName var.name
                pure (mkFVar localDecl.fvarId)
  | .bin lhs op rhs  =>
    match op with
    | .add => return mkApp3 (.const ``BitVec.add []) (mkNatLit w) (← fpExprToExpr ParsedFpExpr lhs) (← fpExprToExpr ParsedFpExpr rhs)
  
  | .const val => return mkApp2 (.const ``Float.ofNat []) (mkNatLit w) (mkNatLit (val.toNat))

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

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

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

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

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

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

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

structure NonNegFlag where
  nneg : Bool := false
  deriving Repr, DecidableEq, Lean.ToExpr

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

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

def select_ashr_icmp_bad_before := [llvm|
{
^0(%arg45 : i32, %arg46 : i32, %arg47 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.icmp "eq" %arg45, %0 : i32
  %2 = llvm.ashr %arg47, %arg45 : i32
  %3 = "llvm.select"(%1, %2, %arg46) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def debugCheck (check? : Bool) (e : Expr)  : MetaM Unit :=
    if check?
    then check e
    else return ()

def exactly_one_set_signbit_wrong_pred_after := [llvm|
{
^0(%arg28 : i8, %arg29 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.and %arg29, %arg28 : i8
  %2 = llvm.icmp "slt" %1, %0 : i8
  "llvm.return"(%2) : (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 a_true_implies_b_true2_before := [llvm|
{
^0(%arg30 : i8, %arg31 : i1, %arg32 : i1):
  %0 = llvm.mlir.constant(20 : i8) : i8
  %1 = llvm.mlir.constant(10 : i8) : i8
  %2 = llvm.icmp "ugt" %arg30, %0 : i8
  %3 = llvm.icmp "ugt" %arg30, %1 : i8
  %4 = "llvm.select"(%3, %arg31, %arg32) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %5 = llvm.and %2, %4 : i1
  "llvm.return"(%5) : (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) -> ()
}
]

private def mkHeader (kind : String) (id : Name) (levelParams : List Name) (type : Expr) (safety : DefinitionSafety) (sig : Bool := true) : MetaM MessageData := do
  let mut attrs := #[]
  match (← getReducibilityStatus id) with
  | ReducibilityStatus.irreducible =>   attrs := attrs.push m!"irreducible"
  | ReducibilityStatus.reducible =>     attrs := attrs.push m!"reducible"
  | ReducibilityStatus.semireducible => pure ()

  if defeqAttr.hasTag (← getEnv) id then
    attrs := attrs.push m!"defeq"

  let mut m : MessageData := m!""
  unless attrs.isEmpty do
    m := m ++ "@[" ++ MessageData.joinSep attrs.toList ", " ++ "] "

  match safety with
  | DefinitionSafety.unsafe  => m := m ++ "unsafe "
  | DefinitionSafety.partial => m := m ++ "partial "
  | DefinitionSafety.safe    => pure ()

  if isProtected (← getEnv) id then
    m := m ++ "protected "

  let id' ← match privateToUserName? id with
    | some id' =>
      m := m ++ "private "
      pure id'
    | none =>
      pure id

  if sig then
    return m!"{m}{kind} {id'}{levelParamsToMessageData levelParams} : {type}"
  else
    return m!"{m}{kind}"

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

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

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

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

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

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

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

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

def test_after := [llvm|
{
^0(%arg0 : i31):
  %0 = llvm.mlir.constant(16384 : i32) : i32
  %1 = llvm.mlir.constant(15 : i32) : i32
  %2 = llvm.zext %arg0 : i31 to i32
  %3 = llvm.add %2, %0 overflow<nuw> : i32
  %4 = llvm.lshr %3, %1 : i32
  %5 = llvm.trunc %4 : i32 to i16
  "llvm.return"(%5) : (i16) -> ()
}
]

def positive_sameconst_after := [llvm|
{
^0(%arg61 : i8):
  %0 = llvm.mlir.constant(-8 : i8) : i8
  %1 = llvm.and %arg61, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

def Expr.mk {Γ} {ty}
    (varName : VarName)
    (op : Op) (ty_eq : ty = (signature op).returnType)
    (args : VarList Γ (signature op).arguments)
    (regions : RegionList Op (signature op).regions) :
    Expr Op Γ ty :=
  ⟨⟨varName, op, args.val, regions.val⟩, by admit /- proof elided -/
  ⟩

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 EnvFin.comap {w n n' : Nat} (env : EnvFin w n) (f : Fin n' → Fin n) : EnvFin w n' :=
  fun i' => env (f i')

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

def land_land_left2_after := [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
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

def testi128i128_before := [llvm|
{
^0(%arg7 : i128):
  %0 = llvm.mlir.constant(127 : i128) : i128
  %1 = llvm.mlir.constant(27 : i128) : i128
  %2 = llvm.ashr %arg7, %0 : i128
  %3 = llvm.xor %2, %1 : i128
  "llvm.return"(%3) : (i128) -> ()
}
]

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

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

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

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

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

@[simp_denote]
def sub_riscv_64 := [LV| {
  ^entry (%x: i64, %y: i64 ):
    %0 = "builtin.unrealized_conversion_cast"(%x) : (i64) -> (!i64)
    %1 = "builtin.unrealized_conversion_cast"(%y) : (i64) -> (!i64)
    %2 = sub %0, %1 : !i64
    %3 = "builtin.unrealized_conversion_cast"(%2) : (!i64) -> (i64)
    llvm.return %3 : i64
  }]

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 trunc_shl_zext_32_after := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(4 : i32) : i32
  %1 = llvm.mlir.constant(65520 : i32) : i32
  %2 = llvm.shl %arg1, %0 : i32
  %3 = llvm.and %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def masked_icmps_mask_notallzeros_bmask_mixed_negated_6_logical_before := [llvm|
{
^0(%arg57 : i32):
  %0 = llvm.mlir.constant(12 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(15 : i32) : i32
  %3 = llvm.mlir.constant(8 : i32) : i32
  %4 = llvm.mlir.constant(true) : i1
  %5 = llvm.and %arg57, %0 : i32
  %6 = llvm.icmp "eq" %5, %1 : i32
  %7 = llvm.and %arg57, %2 : i32
  %8 = llvm.icmp "ne" %7, %3 : i32
  %9 = "llvm.select"(%6, %4, %8) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%9) : (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 APlusBMinusA : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%a: i64, %b: i64):
      %0 = llvm.sub %b, %a : i64
      %1 = llvm.add %a, %0 : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%a: i64, %b: i64):
      llvm.return %b : i64
  }]

def 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 t4_commutative_before := [llvm|
{
^0(%arg34 : i8, %arg35 : i8):
  %0 = llvm.add %arg34, %arg35 : i8
  %1 = llvm.icmp "ule" %arg35, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

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

def MatchArgResult.isTotal_of
    (map : MatchArgResult lets matchLets vs ws mapIn)
    (hvars : ∀ t (v : Var Δ_in t), ⟨t, v⟩ ∈ matchLets.varsOfVec ws) :
    map.val.IsTotal :=

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

def srem_common_dividend_defined_cond_after := [llvm|
{
^0(%arg21 : i1, %arg22 : i5, %arg23 : i5, %arg24 : i5):
  %0 = "llvm.select"(%arg21, %arg24, %arg23) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i5, i5) -> i5
  %1 = llvm.srem %arg22, %0 : i5
  "llvm.return"(%1) : (i5) -> ()
}
]

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

inductive CircuitBackend
 
| automata
 
| circuit_lean
 
| circuit_cadical_verified (maxIter : Nat := 4) (checkTypes? : Bool := false)
 
| dryrun
deriving Repr, DecidableEq

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

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

def mul8_low_A0_B0_after := [llvm|
{
^0(%arg60 : i8, %arg61 : i8):
  %0 = llvm.mul %arg60, %arg61 : i8
  "llvm.return"(%0) : (i8) -> ()
}
]

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

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

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

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

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

inductive Ty
| stream (ty2 : Ty2) : Ty 
| stream2 (ty2 : Ty2) : Ty 
| stream2token (ty2 : Ty2) : Ty 
deriving Inhabited, DecidableEq, Repr, Lean.ToExpr

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

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

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

def icmp_ne_and_pow2_shl1_before := [llvm|
{
^0(%arg67 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.shl %0, %arg67 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.icmp "ne" %4, %2 : i32
  %6 = llvm.zext %5 : i1 to i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

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

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

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

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

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

def uge_to_sgt_before := [llvm|
{
^0(%arg19 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(15 : i8) : i8
  %2 = llvm.xor %arg19, %0 : i8
  %3 = llvm.icmp "uge" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def test_eq2_after := [llvm|
{
^0(%arg8 : i32, %arg9 : i16):
  %0 = llvm.trunc %arg8 : i32 to i16
  %1 = llvm.icmp "eq" %arg9, %0 : i16
  "llvm.return"(%1) : (i1) -> ()
}
]

def r : Com (.ofList [.nat, .nat]) .nat :=
  .var (add ⟨1, by admit /- proof elided -/
  ⟩ ⟨0, by admit /- proof elided -/
  ⟩) (.ret ⟨0, by admit /- proof elided -/
  ⟩)

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

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

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

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

def ashr_1_before := [llvm|
{
^0(%arg97 : i8, %arg98 : i1, %arg99 : i8, %arg100 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(123 : i8) : i8
  %2 = llvm.xor %arg99, %0 : i8
  %3 = llvm.xor %arg100, %1 : i8
  %4 = "llvm.select"(%arg98, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %5 = llvm.ashr %4, %arg97 : i8
  %6 = llvm.xor %5, %0 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

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

def simplify_and_common_op_commute1_after := [llvm|
{
^0(%arg29 : i4, %arg30 : i4, %arg31 : i4):
  %0 = llvm.mlir.constant(0 : i4) : i4
  "llvm.return"(%0) : (i4) -> ()
}
]

def test4_before := [llvm|
{
^0(%arg97 : i32, %arg98 : i1):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = "llvm.select"(%arg98, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %3 = llvm.urem %arg97, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

Lean.Parser.Term.type in Lean.Parser.Term

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

def Expr.mkSubtypeVal (e : Expr) : MetaM Expr :=
  mkAppM ``Subtype.val #[e]

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

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

def andn_or_cmp_4_after := [llvm|
{
^0(%arg161 : i32, %arg162 : i32, %arg163 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.icmp "ne" %arg161, %arg162 : i32
  %2 = llvm.icmp "ugt" %arg163, %0 : i32
  %3 = llvm.and %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def xor_and_logic_or1_after := [llvm|
{
^0(%arg30 : i1, %arg31 : i1, %arg32 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg31, %0 : i1
  %2 = "llvm.select"(%arg30, %1, %arg32) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

instance : AndOp BitStream := ⟨map₂ Bool.and⟩

def test3_before := [llvm|
{
^0(%arg26 : i32, %arg27 : i32):
  %0 = llvm.and %arg26, %arg27 : i32
  %1 = llvm.and %arg27, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def precondSynthesisUpdateCache (previousLevelCache synthesisComponents: Std.HashMap (GenBVExpr w)  PreconditionSynthesisCacheValue)
    (positiveExamples negativeExamples: List (Std.HashMap Nat BVExpr.PackedBitVec)) (specialConstants : Std.HashMap (GenBVExpr w) BVExpr.PackedBitVec)
    (ops : List (GenBVExpr w → GenBVExpr w → GenBVExpr w)) : GeneralizerStateM ParsedBVExpr GenBVPred (Std.HashMap (GenBVExpr w) PreconditionSynthesisCacheValue) := do
    let mut currentCache := Std.HashMap.emptyWithCapacity
    let mut observationalEquivFilter : Std.HashSet String := Std.HashSet.emptyWithCapacity

    let evaluateCombinations (combos :  List (BVExpr.PackedBitVec × BVExpr.PackedBitVec)) (examples: List (Std.HashMap Nat BVExpr.PackedBitVec))
            (op : GenBVExpr w → GenBVExpr w → GenBVExpr w) : GeneralizerStateM ParsedBVExpr GenBVPred  (List (BitVec w)) := do
          let mut res : List (BitVec w) := []
          let mut index := 0
          for (lhs, rhs) in combos do
            let h : lhs.w = w := sorry
            let h' : rhs.w = w := sorry
            if h : lhs.w = w ∧ rhs.w = w then
              res := (evalBVExpr examples[index]! (op  (GenBVExpr.const (h.left ▸ lhs.bv)) (GenBVExpr.const (h.right ▸ rhs.bv)))) :: res
              index := index + 1
            else
              throwError m! "Invalid width for lhs:{lhs} and rhs:{rhs}"
          pure res

    for (bvExpr, intermediateRes) in previousLevelCache.toArray do
      let intermediateNegValues := intermediateRes.negativeExampleValues
      let intermediatePosValues := intermediateRes.positiveExampleValues

      for op in ops do
        for (var, componentValue) in synthesisComponents.toArray do
          if specialConstants.contains bvExpr && specialConstants.contains var then 
            continue

          
          let negExCombinations := List.zip intermediateNegValues componentValue.negativeExampleValues
          let evaluatedNegativeExs ← evaluateCombinations negExCombinations negativeExamples op

          let posExCombinations := List.zip intermediatePosValues componentValue.positiveExampleValues
          let evaluatedPositiveExs  ← evaluateCombinations posExCombinations positiveExamples op

          let filterCheckStr := toString (evaluatedNegativeExs ++ evaluatedPositiveExs)
          if observationalEquivFilter.contains filterCheckStr then
            continue

          let newExpr := op bvExpr var
          currentCache := currentCache.insert newExpr { negativeExampleValues := evaluatedNegativeExs.map (λ ex => {bv := ex, w := w})
                                                      , positiveExampleValues := evaluatedPositiveExs.map (λ ex => {bv := ex, w := w}) : PreconditionSynthesisCacheValue}
          observationalEquivFilter := observationalEquivFilter.insert filterCheckStr

    return currentCache

def CliTest.signature (test : CliTest) :
  Ctxt (InstCombine.MTy test.mvars) × (InstCombine.MTy test.mvars) :=
  (test.context, test.ty)

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

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

noncomputable def R.monomial {q n : Nat} (c : ZMod q) (i : Nat): R q n :=
  R.fromPoly (Polynomial.monomial i c)

def prove_exact_with_high_mask_limit_before := [llvm|
{
^0(%arg6 : i8, %arg7 : i8):
  %0 = llvm.mlir.constant(-8 : i8) : i8
  %1 = llvm.mlir.constant(8 : i8) : i8
  %2 = llvm.and %arg6, %0 : i8
  %3 = llvm.sdiv %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def canonicalize_logic_first_or0_after := [llvm|
{
^0(%arg40 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(112 : i32) : i32
  %2 = llvm.or %arg40, %0 : i32
  %3 = llvm.add %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

def format (f : ι → Format) (is : Inputs ι n) : Format :=
  f!"⟨{f is.input}@{is.ix}⟩"

def a_true_implies_b_false2_before := [llvm|
{
^0(%arg21 : i8, %arg22 : i1, %arg23 : i1):
  %0 = llvm.mlir.constant(20 : i8) : i8
  %1 = llvm.mlir.constant(10 : i8) : i8
  %2 = llvm.icmp "ugt" %arg21, %0 : i8
  %3 = llvm.icmp "eq" %arg21, %1 : i8
  %4 = "llvm.select"(%3, %arg22, %arg23) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %5 = llvm.and %2, %4 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

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

def constantExprsEnumerationFromCache (previousLevelCache allLhsVars : EnumerativeSearchCache) (lhsSymVars rhsSymVars : Std.HashMap Nat BVExpr.PackedBitVec)
                                          (ops: List (GenBVExpr w → GenBVExpr w → GenBVExpr w))
                                          : GeneralizerStateM ParsedBVExpr GenBVPred (ExpressionSynthesisResult × EnumerativeSearchCache) := do
    let zero := BitVec.ofNat w 0
    let one := BitVec.ofNat w 1
    let minusOne := BitVec.ofInt w (-1)

    let specialConstants : Std.HashMap (GenBVExpr w) BVExpr.PackedBitVec := Std.HashMap.ofList [
      (GenBVExpr.const one, {bv := one}),
      (GenBVExpr.const minusOne, {bv := minusOne})
    ]

    let mut rhsVarByValue : Std.HashMap (BitVec w) Nat := Std.HashMap.emptyWithCapacity
    for (var, value) in rhsSymVars.toArray do
      let h : value.w = w := sorry
      rhsVarByValue := rhsVarByValue.insert (h ▸ value.bv) var

    let mut currentCache := Std.HashMap.emptyWithCapacity

    let mut res : Std.HashMap Nat (List BVExprWrapper) := Std.HashMap.emptyWithCapacity
    for (wrappedBvExpr, packedBV) in previousLevelCache.toArray do
      let packedBVExpr : GenBVExpr packedBV.w := GenBVExpr.const packedBV.bv

      for (lhsVar, lhsVal) in allLhsVars.toArray do
        for op in ops do
          if packedBV.w == lhsVar.width then
            let h : packedBV.w = w ∧ lhsVar.width = w := sorry

            let evaluatedRes := evalBVExpr lhsSymVars (op (h.left ▸ packedBVExpr) (h.right ▸ lhsVar.bvExpr))

            let h' : w = wrappedBvExpr.width := sorry
            let mut newExpr := wrap (op (h' ▸ wrappedBvExpr.bvExpr) (h.right ▸ lhsVar.bvExpr))
            let rhsVarForValue := rhsVarByValue[evaluatedRes]?

            match rhsVarForValue with
            | some rhsVar =>
                let existingCandidates := res.getD rhsVar []
                res := res.insert rhsVar (newExpr::existingCandidates)
            | none =>
              if evaluatedRes == h.left ▸ packedBV.bv then
                newExpr := wrappedBvExpr
              currentCache := currentCache.insert newExpr {bv := evaluatedRes : BVExpr.PackedBitVec}

    pure (res, currentCache)

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

def src_is_mask_ashr_after := [llvm|
{
^0(%arg92 : i8, %arg93 : i8, %arg94 : i8, %arg95 : i1):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(15 : i8) : i8
  %2 = llvm.mlir.constant(123 : i8) : i8
  %3 = llvm.add %arg93, %0 : i8
  %4 = llvm.xor %arg93, %3 : i8
  %5 = "llvm.select"(%arg95, %4, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %6 = llvm.ashr %5, %arg94 : i8
  %7 = llvm.xor %arg92, %2 : i8
  %8 = llvm.icmp "ugt" %7, %6 : i8
  "llvm.return"(%8) : (i1) -> ()
}
]

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

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

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

def andn_or_cmp_1_after := [llvm|
{
^0(%arg176 : i37, %arg177 : i37, %arg178 : i37):
  %0 = llvm.mlir.constant(42 : i37) : i37
  %1 = llvm.icmp "sle" %arg176, %arg177 : i37
  %2 = llvm.icmp "ugt" %arg178, %0 : i37
  %3 = llvm.and %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def sub_shl_same_amount_nuw_before := [llvm|
{
^0(%arg23 : i64, %arg24 : i64, %arg25 : i64):
  %0 = llvm.shl %arg23, %arg25 overflow<nuw> : i64
  %1 = llvm.shl %arg24, %arg25 overflow<nuw> : i64
  %2 = llvm.sub %0, %1 overflow<nuw> : i64
  "llvm.return"(%2) : (i64) -> ()
}
]

def test5_before := [llvm|
{
^0(%arg118 : i32):
  %0 = llvm.mlir.constant(1234 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.xor %arg118, %0 : i32
  %4 = llvm.lshr %3, %1 : i32
  %5 = llvm.xor %4, %2 : i32
  %6 = llvm.add %5, %3 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

@[simps]
def proj (M: NFA (BitVec n1) σ) (f : Fin n2 → Fin n1) : NFA (BitVec n2) σ where
  start := M.start
  accept := M.accept
  step q a := { q' | ∃ a', a'.transport f = a ∧ q' ∈ M.step q a' }

def test_sub_nuw__all_are_safe_before := [llvm|
{
^0(%arg30 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.mlir.constant(6 : i32) : i32
  %2 = llvm.mlir.constant(-254 : i32) : i32
  %3 = llvm.mlir.constant(-260 : i32) : i32
  %4 = llvm.and %arg30, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.sub %2, %4 overflow<nuw> : i32
  %7 = "llvm.select"(%5, %3, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

def test_sub_lhs_add_const_LHS := [mod_arith q, hq| {
  ^bb0(%x : !R):
    %c0 = mod_arith.constant 12 : !R
    %c1 = mod_arith.constant 34 : !R
    %add = mod_arith.add %x, %c0 : !R
    %sub = mod_arith.sub %c1, %add : !R
    return %sub : !R
}]

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

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

def sub_dec_before := [llvm|
{
^0(%arg4 : i8, %arg5 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.add %arg4, %0 : i8
  %2 = llvm.sub %1, %arg5 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

@[simp_denote]
def optimized_correct := [LV| {
  ^entry (%x : i1):
  llvm.return %x : 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 llvm_xor_lower_riscv_64: LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] :=
  {lhs := llvm_xor_64, rhs := xor_riscv_64}

def dropFirstNone (x : Stream α) : Stream α :=
  if x.head.isNone then
    x.tail
  else
    x

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

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

instance : HydrableGeneralize ParsedBVExpr GenBVPred GenBVExpr where

def mkWidthEnvEmpty : SolverM Expr := do
  let out := (mkConst ``MultiWidth.WidthExpr.Env.empty)
  debugCheck out
  return out

def unpack {r} {Γ : Ctxt _} (a : Γ.Var (.valuestream r)) : Expr (DC) Γ .pure (.valuetokenstream r) :=
  Expr.mk
    (op := .unpack r)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .cons a <| .nil)
    (regArgs := .nil)

def lshrult_03_08_exact_after := [llvm|
{
^0(%arg109 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (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 CNFA.ofFSM (p : FSM arity) : CNFA (FinEnum.card arity + 1) :=
  worklistRun (BitVec (FinEnum.card p.α))
    (fun _ => true)
    #[finFunToBitVec p.initCarry]
    (by admit /- proof elided -/
    )
    f
  where

def addhshlhsdivhscalar2_before := [llvm|
{
^0(%arg17 : i32):
  %0 = llvm.mlir.constant(-1073741824 : i32) : i32
  %1 = llvm.mlir.constant(30 : i32) : i32
  %2 = llvm.sdiv %arg17, %0 : i32
  %3 = llvm.shl %2, %1 : i32
  %4 = llvm.add %3, %arg17 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def commute_int_constant_to_rhs: List (Σ Γ, RISCVPeepholeRewrite  Γ) :=
  [⟨_, commute_int_constant_to_rhs_add⟩,
  ⟨_, commute_int_constant_to_rhs_mul⟩,
  ⟨_, commute_int_constant_to_rhs_and⟩,
  ⟨_, commute_int_constant_to_rhs_or⟩,
  ⟨_, commute_int_constant_to_rhs_xor⟩,
  ⟨_, commute_int_constant_to_rhs_mulhu⟩]

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

def n12_wrong_bias_after := [llvm|
{
^0(%arg9 : 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(32 : i8) : i8
  %4 = llvm.and %arg9, %0 : i8
  %5 = llvm.icmp "eq" %4, %1 : i8
  %6 = llvm.and %arg9, %2 : i8
  %7 = llvm.add %6, %3 : i8
  %8 = "llvm.select"(%5, %arg9, %7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%8) : (i8) -> ()
}
]

def t0_after := [llvm|
{
^0(%arg42 : i32, %arg43 : i32, %arg44 : i32, %arg45 : i32):
  %0 = llvm.icmp "ne" %arg42, %arg43 : i32
  %1 = llvm.icmp "ne" %arg44, %arg45 : i32
  %2 = llvm.and %1, %0 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

def squared_nsw_sgt0_before := [llvm|
{
^0(%arg178 : i5):
  %0 = llvm.mlir.constant(0 : i5) : i5
  %1 = llvm.mul %arg178, %arg178 overflow<nsw> : i5
  %2 = llvm.icmp "sgt" %1, %0 : i5
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

def test6a_after := [llvm|
{
^0(%arg47 : i55):
  %0 = llvm.mlir.constant(6 : i55) : i55
  %1 = llvm.mul %arg47, %0 : i55
  "llvm.return"(%1) : (i55) -> ()
}
]

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

instance : LawfulMonad (MetaLLVM φ).m :=

def sext_multi_uses_before := [llvm|
{
^0(%arg9 : i64, %arg10 : i1, %arg11 : i64):
  %0 = llvm.sext %arg10 : i1 to i64
  %1 = llvm.xor %arg9, %0 : i64
  %2 = llvm.sub %1, %0 : i64
  %3 = llvm.mul %arg11, %0 : i64
  %4 = llvm.add %3, %2 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

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

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

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

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

def RawCNFA.newState (m : RawCNFA A) : State × RawCNFA A :=
  let old := m.stateMax
  let m := { m with stateMax := old + 1 }
  (old, m)

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

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

Function.Injective2 in Mathlib.Logic.Function.Basic

def test48_after := [llvm|
{
^0(%arg137 : i8, %arg138 : i8):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.zext %arg137 : i8 to i32
  %2 = llvm.shl %1, %0 overflow<nsw,nuw> : i32
  %3 = llvm.or disjoint %2, %1 : i32
  %4 = llvm.zext nneg %3 : i32 to i64
  "llvm.return"(%4) : (i64) -> ()
}
]

Int.lt in Init.Data.Int.Basic

def testi128i128_after := [llvm|
{
^0(%arg7 : i128):
  %0 = llvm.mlir.constant(-1 : i128) : i128
  %1 = llvm.mlir.constant(27 : i128) : i128
  %2 = llvm.mlir.constant(-28 : i128) : i128
  %3 = llvm.icmp "sgt" %arg7, %0 : i128
  %4 = "llvm.select"(%3, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i128, i128) -> i128
  "llvm.return"(%4) : (i128) -> ()
}
]

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

structure NatFSM (wcard tcard bcard ncard icard pcard : Nat) (v : Nondep.WidthExpr) where
  toFsm : FSM (StateSpace wcard tcard bcard ncard icard pcard)

abbrev TypedSSAVal := SSAVal × MLIRType φ

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

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

def sdiv400_yes_after := [llvm|
{
^0(%arg3 : i32):
  %0 = llvm.mlir.constant(400 : i32) : i32
  %1 = llvm.udiv %arg3, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def slt_swap_or_not_max_before := [llvm|
{
^0(%arg54 : i8, %arg55 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.icmp "sgt" %arg55, %arg54 : i8
  %2 = llvm.icmp "ne" %arg54, %0 : i8
  %3 = llvm.or %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def Term.Ctx.Env.empty
  {wcard : Nat} (wenv : WidthExpr.Env wcard) (ctx : Term.Ctx wcard 0) :
  Term.Ctx.Env ctx wenv :=
  fun v => v.elim0

def NatPredicate.toProp (env : Fin wcard → Nat) : NatPredicate wcard → Prop
| .eq e1 e2 => WidthExpr.toNat e1 env = WidthExpr.toNat e2 env

def sup : EffectKind → EffectKind → EffectKind
  | .pure, .pure => .pure
  | _, _ => .impure

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 shl_trunc_smaller_lshr_before := [llvm|
{
^0(%arg43 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(5 : i8) : i8
  %2 = llvm.lshr %arg43, %0 : i32
  %3 = llvm.trunc %2 : i32 to i8
  %4 = llvm.shl %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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 PR24873_after := [llvm|
{
^0(%arg130 : i64):
  %0 = llvm.mlir.constant(61) : i64
  %1 = llvm.icmp "ugt" %arg130, %0 : i64
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

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

def t1_flags_before := [llvm|
{
^0(%arg48 : i8, %arg49 : i8, %arg50 : i8):
  %0 = llvm.sub %arg48, %arg49 overflow<nsw,nuw> : i8
  %1 = llvm.sub %0, %arg50 overflow<nsw,nuw> : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def test_sub_nuw_nsw__nuw_is_safe_before := [llvm|
{
^0(%arg27 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.mlir.constant(1073741824 : i32) : i32
  %2 = llvm.mlir.constant(-2147483648 : i32) : i32
  %3 = llvm.and %arg27, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.sub %2, %3 overflow<nsw,nuw> : i32
  %6 = "llvm.select"(%4, %1, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

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

def or_ashr_not_before := [llvm|
{
^0(%arg54 : i8, %arg55 : i8, %arg56 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.ashr %arg54, %arg56 : i8
  %2 = llvm.ashr %arg55, %arg56 : i8
  %3 = llvm.xor %2, %0 : i8
  %4 = llvm.or %1, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

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

Lean.Name in Init.Prelude

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

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

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

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

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

def stats {arity : Type _}
    [DecidableEq arity] [Fintype arity] [Hashable arity]
    {fsm : FSM arity} (circs : KInductionCircuits fsm n) : CircuitStats where
  iter := n
  size := circs.cSuccCarryAssignCirc.size +
    circs.cOutAssignCirc.size +
    circs.cInitCarryAssignCirc.size

def push (Γ : Context Ty) (v : VarName) (ty : Ty) : Context Ty :=
  (v, ty) :: Γ

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

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

noncomputable def R.representative :
    R q n → (ZMod q)[X] := fun x => R.representative' q n x %ₘ (f q n)

StateM in Init.Control.State

def test_mul_nuw__nsw_is_safe_after := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(-83886080 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.or %arg6, %0 : i32
  %3 = llvm.mul %2, %1 overflow<nsw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

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

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 t0_const_after_fold_lshr_shl_ne_before := [llvm|
{
^0(%arg43 : i32, %arg44 : i64, %arg45 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.sub %0, %arg45 : i32
  %4 = llvm.lshr %arg43, %3 : i32
  %5 = llvm.add %arg45, %1 : i32
  %6 = llvm.zext %5 : i32 to i64
  %7 = llvm.shl %arg44, %6 : i64
  %8 = llvm.trunc %7 : i64 to i32
  %9 = llvm.and %4, %8 : i32
  %10 = llvm.icmp "ne" %9, %2 : i32
  "llvm.return"(%10) : (i1) -> ()
}
]

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

def selection00 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs:= [LV| {
  ^entry (%arg0: i64):
    %c = llvm.mlir.constant (4) : i64
    %1 = llvm.mul %arg0, %c : i64
    llvm.return %1 : i64
  }]
  rhs:= [LV| {
  ^entry (%arg0: i64):
    %r1 = "builtin.unrealized_conversion_cast" (%arg0) : (i64) -> (!riscv.reg)
    %c = slli %r1, 2 : !riscv.reg
    %rd = "builtin.unrealized_conversion_cast" (%c) : (!riscv.reg) -> (i64)
    llvm.return %rd : i64
  }]

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

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

instance [Hashable α] [BEq α] : EmptyCollection (TotalOrder α) where
  emptyCollection := {}

def p14_commutativity1_before := [llvm|
{
^0(%arg26 : i32, %arg27 : i32):
  %0 = llvm.mlir.constant(65536 : i32) : i32
  %1 = llvm.mlir.constant(65535 : i32) : i32
  %2 = llvm.mlir.constant(42 : i32) : i32
  %3 = llvm.icmp "ult" %arg26, %0 : i32
  %4 = "llvm.select"(%3, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

FinEnum in Mathlib.Data.FinEnum

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

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

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

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

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

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

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

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

def test_invert_demorgan_logical_or_before := [llvm|
{
^0(%arg11 : i64, %arg12 : i64):
  %0 = llvm.mlir.constant(27) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.icmp "eq" %arg11, %0 : i64
  %4 = llvm.icmp "eq" %arg12, %1 : i64
  %5 = "llvm.select"(%3, %2, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %6 = llvm.icmp "eq" %arg11, %1 : i64
  %7 = llvm.or %6, %5 : i1
  %8 = llvm.xor %7, %2 : i1
  "llvm.return"(%8) : (i1) -> ()
}
]

def icmp_eq_and_pow2_shl_pow2_negative1_before := [llvm|
{
^0(%arg61 : i32):
  %0 = llvm.mlir.constant(11 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.shl %0, %arg61 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.icmp "eq" %4, %2 : i32
  %6 = llvm.zext %5 : i1 to i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

Std.Format.group in Init.Data.Format.Basic

def rotateleft_9_neg_mask_wide_amount_commute_after := [llvm|
{
^0(%arg29 : i9, %arg30 : i33):
  %0 = llvm.mlir.constant(0 : i33) : i33
  %1 = llvm.mlir.constant(8 : i33) : i33
  %2 = llvm.sub %0, %arg30 : i33
  %3 = llvm.and %arg30, %1 : i33
  %4 = llvm.and %2, %1 : i33
  %5 = llvm.zext %arg29 : i9 to i33
  %6 = llvm.shl %5, %3 overflow<nsw,nuw> : i33
  %7 = llvm.lshr %5, %4 : i33
  %8 = llvm.or %6, %7 : i33
  %9 = llvm.trunc %8 : i33 to i9
  "llvm.return"(%9) : (i9) -> ()
}
]

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

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

def demorgan_and_apint4_before := [llvm|
{
^0(%arg52 : i66, %arg53 : i66):
  %0 = llvm.mlir.constant(-1 : i66) : i66
  %1 = llvm.xor %arg52, %0 : i66
  %2 = llvm.xor %arg53, %0 : i66
  %3 = llvm.and %1, %2 : i66
  "llvm.return"(%3) : (i66) -> ()
}
]

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

@[simp_sllvm]
def urem (x y : LLVM.IntW w) : EffectM (LLVM.IntW w) := do
  if y.canBe 0#w then
    throwUB
  else
    pure <| LLVM.urem x y

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

def udiv_i32_before := [llvm|
{
^0(%arg29 : i8, %arg30 : i8):
  %0 = llvm.zext %arg29 : i8 to i32
  %1 = llvm.zext %arg30 : i8 to i32
  %2 = llvm.udiv %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

Lean.Meta.mkDecideProof in Lean.Meta.AppBuilder

private noncomputable instance {M : NFA α σ} : Decidable M.Complete :=
  Classical.propDecidable _

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

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

Exists in Init.Core
</all_available_defs>

<all_available_lemmas>
Bool.not_eq_true in Init.SimpLemmas
Finset.card_lt_card in Mathlib.Data.Finset.Card
Finset.ssubset_iff in Mathlib.Data.Finset.Insert
Finset.subset_iff in Mathlib.Data.Finset.Defs
not_imp_not in Mathlib.Logic.Basic
Bool.or_eq_true in Init.SimpLemmas
Nat.rec_zero in Mathlib.Data.Nat.Init
or_true in Init.SimpLemmas
true_iff in Init.SimpLemmas

lemma le_def : ∀ (c₁ c₂ : Circuit α), c₁ ≤ c₂ ↔ ∀ f, eval c₁ f → eval c₂ f

theorem eval_fst {α β : Type _} [DecidableEq α] [DecidableEq β]
    (c : Circuit (α ⊕ β)) (g : α → Bool) :
    c.fst.eval g ↔ ∃ g' : β → Bool, c.eval (Sum.elim g g')

lemma eval_assignVars [DecidableEq α] : ∀ {c : Circuit α}
    {f : ∀ (a : α) (_ha : a ∈ c.vars), β ⊕ Bool} {g : β → Bool},
    eval (assignVars c f) g = evalv c (λ a ha => Sum.elim g id (f a ha))

@[simp] lemma eval_bOr :
  ∀ {s : List α} {f : α → Circuit β} {g : β → Bool},
    eval (bOr s f) g = ∃ a ∈ s, eval (f a) g

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

@[simp] lemma eval_or : ∀ (c₁ c₂ : Circuit α) (f : α → Bool),
    (eval (c₁ ||| c₂) f) = ((eval c₁ f) || (eval c₂ f))

lemma eval_eq_evalv [DecidableEq α] : ∀ (c : Circuit α) (f : α → Bool),
    eval c f = evalv c (λ x _ => f x)

lemma eval_bind : ∀ (c : Circuit α) (f : α → Circuit β) (g : β → Bool),
    eval (bind c f) g = eval c (λ a => eval (f a) g)

theorem test12_proof : test12_before ⊑ test12_after

theorem icmp_ne_sext_sgt_zero_nofold_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (0#32 <ₛ x)) != x) = ofBool (x != signExtend 32 (ofBool (0#32 <ₛ x)))

theorem lshrult_01_00_exact_proof : lshrult_01_00_exact_before ⊑ lshrult_01_00_exact_after

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

theorem e_1975 :
    1 * (b |||  ~~~(a |||  ~~~c)) + 1 * c - 5 * (c ^^^  ~~~(a |||  ~~~b)) - 1 * (b |||  ~~~c) + 11 * (c &&&  ~~~(a ^^^ b)) + 2 *  ~~~(a &&& b) - 5 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) - 1 * (c ||| (a ^^^ b)) + 7 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) - 2 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 7 * ((a &&& b) |||  ~~~(b |||  ~~~c)) + 1 * (c &&&  ~~~(a &&& b)) - 1 * ( ~~~c &&&  ~~~(a ^^^ b)) - 11 * (a ||| (b ^^^ c)) + 1 * (c ||| (a &&& b)) + 1 *  ~~~( ~~~a &&& ( ~~~b ||| c)) + 4 * (c &&& (a ^^^ b)) - 7 * (a |||  ~~~b) + 5 * (b ^^^  ~~~(a &&& (b ^^^ c))) + 11 * (b ^^^  ~~~(a ||| (b ^^^ c))) - 3 *  ~~~(b &&&  ~~~c) + 5 * (c |||  ~~~(a ||| b)) - 2 * (a ||| b) - 1 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) - 6 * (c ^^^ (a &&& (b ||| c))) - 3 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 1 * ((a ^^^ b) &&& (a ^^^ c)) - 5 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 3 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) + 2 *  ~~~b + 3 * ( ~~~b ||| (a ^^^ c)) - 2 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) + 1 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) - 1 *  ~~~(a |||  ~~~c) - 11 * (b ^^^ ( ~~~a &&& (b ^^^ c))) - 7 * (c ^^^ ( ~~~a ||| (b ||| c))) - 6 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) - 2 * (c ^^^ (a ||| (b ||| c))) + 3 * ((a &&& b) ||| (b ^^^ c)) + 4 * (b ||| c) - 2 * (b &&& (a ||| c)) + 7 * (c ^^^  ~~~(a &&& (b ||| c))) + 11 * (b ^^^ (a ||| (b ^^^ c))) - 1 * ( ~~~a &&& ( ~~~b ||| c)) - 1 *  ~~~(a ^^^ ( ~~~b ||| c)) - 11 * ((a ^^^ b) ||| (a ^^^ c)) - 11 * (a ||| ( ~~~b &&& c)) + 5 * (a |||  ~~~c) + 1 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 2 *  ~~~(a ||| c) - 17 *  ~~~(a ||| (b ||| c)) + 10 *  ~~~(a ||| ( ~~~b ||| c)) + 29 *  ~~~( ~~~a ||| (b ||| c)) + 54 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 26 * ( ~~~a &&& ( ~~~b &&& c)) + 6 * ( ~~~a &&& (b &&& c)) + 9 * (a &&& (b &&& c)) =  - 6 * (a &&& ( ~~~b &&& c))

theorem udiv2_proof : udiv2_before ⊑ udiv2_after

theorem ule_or_not_min_thm (e e_1 : IntW 427) :
  LLVM.or (icmp IntPred.ule e_1 e) (icmp IntPred.ne e_1 (const? 427 0)) ⊑ const? 1 1

theorem e_76 :
     - 1 * y - 1 * (x ||| y) - 7 *  ~~~(x ||| y) - 5 *  ~~~(x |||  ~~~y) + 1 * (x &&&  ~~~y) =  - 7 *  ~~~(x &&&  ~~~y) + 5 * (x &&& y)

theorem e_447 :
     - 2 * (x ^^^ y) + 7 *  ~~~(x ^^^ y) + 1 *  ~~~(x &&& y) + 11 *  ~~~(x &&&  ~~~x) - 3 * y - 7 *  ~~~(x |||  ~~~y) - 10 * (x &&&  ~~~y) - 15 * (x &&& y) = 19 *  ~~~(x ||| y)

theorem test_ne_proof : test_ne_before ⊑ test_ne_after

theorem lshrult_01_00_exact_thm (e : IntW 4) :
  icmp IntPred.ult (lshr e (const? 4 1) { «exact» := true }) (const? 4 0) ⊑ const? 1 0

theorem e_1713 :
     - 2 * (b ^^^ (a ||| ( ~~~b &&& c))) + 11 * ((a &&& b) |||  ~~~(b ||| c)) - 7 * ((a &&& b) ^^^  ~~~(a ^^^ (b &&& c))) - 6 *  ~~~(a &&& c) - 2 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 1 * (a ||| (b ^^^ c)) - 11 * (b ^^^  ~~~(a ||| (b &&& c))) + 3 * (b ^^^ ( ~~~a &&& (b ||| c))) - 6 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) + 1 * ((a &&& c) ^^^ (b ||| c)) - 2 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) - 1 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) + 4 * ( ~~~a &&& ( ~~~b ||| c)) + 3 *  ~~~(a ^^^ ( ~~~b &&& c)) - 2 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) + 11 * (a &&& ( ~~~b ||| c)) + 1 * (c ||| (a ^^^ b)) - 3 *  ~~~( ~~~a &&& (b &&& c)) - 1 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 7 * ( ~~~b &&& (a ^^^ c)) - 3 * (c ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 1 * (c &&& (a ||| b)) - 1 * (b &&& (a ||| c)) + 13 *  ~~~(a ||| (b ||| c)) + 28 *  ~~~(a ||| ( ~~~b ||| c)) - 14 *  ~~~( ~~~a ||| (b ||| c)) + 22 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 13 * ( ~~~a &&& ( ~~~b &&& c)) + 16 * ( ~~~a &&& (b &&& c)) - 12 * (a &&& ( ~~~b &&& c)) = 8 * (a &&& (b &&& c)) - 7 * ((b &&&  ~~~c) ^^^ (a ||| (b ^^^ c)))

theorem logical_and_logical_and_icmps_comm2_proof : logical_and_logical_and_icmps_comm2_before ⊑ logical_and_logical_and_icmps_comm2_after

theorem lshr_32_add_zext_basic_proof : lshr_32_add_zext_basic_before ⊑ lshr_32_add_zext_basic_after

theorem ofDep_xvar_eq_xvar' : MultiWidth.Nondep.Term.ofDepTerm xvar = xvar'

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 or_logic_or_logic_and_8_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 → True → x ||

theorem e_2189 :
     - 7 * (f ^^^  ~~~(d &&& e)) + 1 * (e &&& (d |||  ~~~f)) - 2 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 2 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 1 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 7 * (f &&& (d ||| e)) - 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 5 *  ~~~(d &&&  ~~~e) - 1 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 2 * (f ^^^ (d &&& e)) + 1 * (e ^^^  ~~~(d &&& (e ||| f))) - 11 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 1 * ( ~~~d &&& (e ||| f)) + 4 * ( ~~~d ||| ( ~~~e ||| f)) + 3 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 7 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 5 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 3 * (d &&& e) + 1 * ((d ^^^ e) ||| (d ^^^ f)) - 11 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 11 * (e &&& f) + 1 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 7 * (d &&&  ~~~e) + 7 * (d |||  ~~~e) + 4 * (f |||  ~~~(d |||  ~~~e)) - 5 * (e ^^^ (d &&& (e ||| f))) + 7 * (f ^^^ (d ||| ( ~~~e &&& f))) - 1 * ( ~~~f &&& (d ^^^ e)) - 2 * (d ^^^ f) + 4 *  ~~~(d &&& ( ~~~e &&& f)) + 1 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 11 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 1 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 5 * ( ~~~f ||| (d ^^^ e)) + 1 * (e &&&  ~~~(d ^^^ f)) + 1 *  ~~~(d &&&  ~~~d) - 11 *  ~~~f - 1 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 3 * (d ||| ( ~~~e ||| f)) - 11 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 5 * e + 11 *  ~~~(d ||| (e ||| f)) - 4 *  ~~~(d ||| ( ~~~e ||| f)) + 12 *  ~~~( ~~~d ||| (e ||| f)) + 17 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 11 * ( ~~~d &&& ( ~~~e &&& f)) - 13 * ( ~~~d &&& (e &&& f)) + 13 * (d &&& ( ~~~e &&& f)) - 18 * (d &&& (e &&& f)) = 3 *  ~~~(e &&& f)

theorem t3_singlebit_proof : t3_singlebit_before ⊑ t3_singlebit_after

theorem fold_nested_logic_zext_icmp_thm.extracted_1._1 : ∀ (x x_1 x_2 x_3 : BitVec 64),
  zeroExtend 8 (ofBool (x_2 <ₛ x_3)) &&& zeroExtend 8 (ofBool (x_3 <ₛ x_1)) ||

theorem sdiv_shl_pair3_proof : sdiv_shl_pair3_before ⊑ sdiv_shl_pair3_after

theorem masked_and_notA_logical_proof : masked_and_notA_logical_before ⊑ masked_and_notA_logical_after

theorem e_1922 :
     - 1 * (b ^^^  ~~~(a ||| (b ^^^ c))) - 2 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) - 6 * ( ~~~(a &&& b) &&&  ~~~(b ^^^ c)) + 2 * (c ^^^ ( ~~~a ||| (b ||| c))) + 3 * (a ||| (b &&& c)) - 2 * ( ~~~b &&& (a ^^^ c)) + 7 *  ~~~( ~~~a ||| ( ~~~b &&& c)) - 3 *  ~~~(a |||  ~~~c) - 6 * (c ^^^  ~~~(a ||| b)) + 1 * (b ^^^ (a &&&  ~~~c)) + 2 * (b ^^^  ~~~(a &&& (b ||| c))) - 1 *  ~~~(a &&& c) - 11 * (a ||| c) + 7 * (b |||  ~~~c) + 1 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) + 5 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) + 2 * (b ^^^  ~~~( ~~~a ||| (b ^^^ c))) - 6 *  ~~~(a ^^^ (b &&& c)) + 5 *  ~~~( ~~~a &&& ( ~~~b ||| c)) - 7 * (c ||| (a &&&  ~~~b)) - 2 * (c ^^^ ( ~~~a &&& (b ||| c))) - 11 * (b ^^^ (a ||| ( ~~~b &&& c))) - 3 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 1 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 11 * (a &&& (b ^^^ c)) - 2 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) - 1 *  ~~~(a &&&  ~~~a) - 2 * (b ^^^ (a ||| (b ||| c))) + 11 * (c &&& (a |||  ~~~b)) + 3 * (a ^^^ (b ^^^ c)) - 1 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) + 1 * ( ~~~c &&& (a ^^^ b)) - 7 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) - 5 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 1 * ( ~~~b &&&  ~~~(a ^^^ c)) - 1 *  ~~~(a &&& b) + 7 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) + 1 * (b &&&  ~~~(a &&&  ~~~c)) - 2 * (a ||| ( ~~~b ||| c)) + 1 * (b ^^^ (a &&& c)) - 5 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 1 *  ~~~(a &&& (b ||| c)) - 5 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) + 12 *  ~~~(a ||| (b ||| c)) - 7 *  ~~~(a ||| ( ~~~b ||| c)) + 23 *  ~~~( ~~~a ||| (b ||| c)) - 2 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 29 * ( ~~~a &&& ( ~~~b &&& c)) + 30 * ( ~~~a &&& (b &&& c)) + 41 * (a &&& ( ~~~b &&& c)) - 4 * (a &&& (b &&& c)) =  - 7 *  ~~~(b &&& c)

theorem bv_276 :
    ∀ (e e_1 : LLVM.IntW 5), LLVM.mul (LLVM.sdiv e_1 e) (LLVM.sub (LLVM.const? 5 0) e) ⊑ LLVM.sub (LLVM.srem e_1 e) e_1

theorem f_proof : f_before ⊑ f_after

theorem masked_icmps_bmask_notmixed_and_expected_false_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.ne (LLVM.and e (const? 32 3)) (const? 32 15))
      (icmp IntPred.ne (LLVM.and e (const? 32 255)) (const? 32 242)) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 255)) (const? 32 242)

theorem lshrugt_01_05_thm (e : IntW 4) :
  icmp IntPred.ugt (lshr e (const? 4 1)) (const? 4 5) ⊑ icmp IntPred.ugt e (const? 4 (-5))

theorem bv_AddSub_1176 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.add e (LLVM.sub (LLVM.const? w 0) e_1) ⊑ LLVM.sub e e_1

theorem test20_proof : test20_before ⊑ test20_after

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

theorem test19_proof : test19_before ⊑ test19_after

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

theorem test15e_thm (e : IntW 32) :
  select (icmp IntPred.ne (LLVM.and e (const? 32 128)) (const? 32 0)) (const? 32 256) (const? 32 0) ⊑
    LLVM.and (shl e (const? 32 1)) (const? 32 256)

theorem test9_proof : test9_before ⊑ test9_after

theorem trunc_shl_1_i32_i64_thm.extracted_1._1 : ∀ (x : BitVec 64), ¬1#64 ≥ ↑64 → 1#32 ≥ ↑32 → False

theorem exact_lshr_ne_exactdiv_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ 80#8 >>> x <<< x ≠ 80#8 ∨ x ≥ ↑8) → ofBool (80#8 >>> x != 5#8) = ofBool (x != 4#8)

theorem icmp_slt_0_and_icmp_ne_neg2_i32_fail_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 →
    x >>> 31#32 &&& zeroExtend 32 (ofBool (x != BitVec.ofInt 32 (-2))) =
      zeroExtend 32 (ofBool (x <ₛ 0#32) &&& ofBool (x != BitVec.ofInt 32 (-2)))

theorem select_icmp_sgt_not_smin_thm (e : IntW 8) :
  select (icmp IntPred.sgt e (const? 8 (-1))) e (LLVM.xor e (const? 8 (-127))) ⊑
    select (icmp IntPred.slt e (const? 8 0)) (LLVM.xor e (const? 8 (-127))) e

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

theorem test_sub_nsw__nuw_is_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 2147483647#32 == 1073741824#32) = 1#1 →
    ¬(True ∧ (BitVec.ofInt 32 (-2147483648)).usubOverflow (x &&& 2147483647#32) = true) →
      1073741824#32 = BitVec.ofInt 32 (-2147483648) - (x &&& 2147483647#32)

theorem e_2421 :
    4 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 1 * (f ^^^ (d &&& ( ~~~e ||| f))) + 1 * ((d ||| e) &&& (e ^^^ f)) + 1 * (d &&& (e ^^^ f)) - 1 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 7 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 * (d &&&  ~~~e) + 2 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 6 *  ~~~(d &&& ( ~~~e ||| f)) - 1 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 2 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 2 * d - 6 * (f &&& (d ^^^ e)) + 4 * ((d &&& e) ^^^ (e |||  ~~~f)) - 1 * (d &&& e) + 3 * (e ^^^ (d |||  ~~~f)) - 7 *  ~~~(e ^^^ f) - 11 * (e &&&  ~~~(d ^^^ f)) + 1 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) - 2 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) + 5 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 4 * (d ||| (e ^^^ f)) - 7 * (e &&&  ~~~(d &&& f)) + 7 * (f |||  ~~~(d ||| e)) + 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 7 * (d ^^^ ( ~~~e ||| f)) - 1 *  ~~~(d ^^^ ( ~~~e &&& f)) + 2 * ( ~~~d ||| ( ~~~e ||| f)) - 2 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 1 * (d ^^^ f) - 11 * ((d ^^^ e) ||| (d ^^^ f)) + 2 *  ~~~(d ^^^ ( ~~~e ||| f)) + 1 *  ~~~(d |||  ~~~f) + 1 * (e ^^^  ~~~(d &&&  ~~~f)) - 3 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 4 * (d ^^^ e) - 7 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 7 * (f &&& (d ||| e)) - 3 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 11 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 5 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 2 * ( ~~~d &&& (e ^^^ f)) - 2 * (f ^^^  ~~~(d &&& (e &&& f))) + 2 * (d ||| (e ||| f)) + 3 *  ~~~(e &&&  ~~~f) - 1 * (f ^^^ (d ||| ( ~~~e &&& f))) - 2 *  ~~~(d ^^^ (e ^^^ f)) - 11 * (e ^^^ (d &&& (e ||| f))) - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 5 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) + 1 * (e ||| (d ^^^ f)) - 1 * (f ^^^ (d |||  ~~~e)) - 1 * (e &&& (d ||| f)) - 5 * (e |||  ~~~(d ^^^ f)) - 2 * (e ^^^ (d ||| (e ^^^ f))) - 2 * (f ^^^ ( ~~~d &&& (e ||| f))) - 11 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 2 * (f ||| (d &&& e)) - 3 * ((d &&& e) |||  ~~~(e ||| f)) + 4 * ( ~~~f ||| (d ^^^ e)) + 3 * (e &&&  ~~~f) + 3 * (f ^^^  ~~~(d |||  ~~~e)) - 7 * (e &&& f) - 2 * (e ^^^  ~~~(d &&& (e ||| f))) + 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 5 * f + 16 *  ~~~(d ||| (e ||| f)) + 7 *  ~~~(d ||| ( ~~~e ||| f)) + 9 *  ~~~( ~~~d ||| (e ||| f)) + 27 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 7 * ( ~~~d &&& ( ~~~e &&& f)) + 64 * ( ~~~d &&& (e &&& f)) - 19 * (d &&& ( ~~~e &&& f)) + 25 * (d &&& (e &&& f)) = 5 * (d ^^^ (e &&& f))

theorem substitute_constant_and_eq_ugt_swap_proof : substitute_constant_and_eq_ugt_swap_before ⊑ substitute_constant_and_eq_ugt_swap_after

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

theorem lshrugt_02_00_exact_proof : lshrugt_02_00_exact_before ⊑ lshrugt_02_00_exact_after

theorem logic_or_logic_and_4_proof : logic_or_logic_and_4_before ⊑ logic_or_logic_and_4_after

theorem lshr_16_add_zext_basic_multiuse_thm (e e_1 : IntW 16) :
  LLVM.or (lshr (add (zext 32 e_1) (zext 32 e)) (const? 32 16)) (zext 32 e_1) ⊑
    LLVM.or (lshr (add (zext 32 e_1) (zext 32 e) { «nsw» := true, «nuw» := true }) (const? 32 16))
      (zext 32 e_1)

theorem udiv_i1_is_op0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1), ¬x = 0 → x_1 / x = x_1

theorem sub_1_proof : sub_1_before ⊑ sub_1_after

theorem testi16i8_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(7#8 ≥ ↑8 ∨ 8#16 ≥ ↑16) →
    ofBool ((truncate 8 x).sshiftRight' 7#8 == truncate 8 (x >>> 8#16)) = ofBool (x + 128#16 <ᵤ 256#16)

theorem test_sub__nsw_is_safe_proof : test_sub__nsw_is_safe_before ⊑ test_sub__nsw_is_safe_after

theorem sext_sext_slt_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (signExtend 32 x_1 <ₛ signExtend 32 x) = ofBool (x_1 <ₛ x)

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

theorem t0_thm.extracted_1._26 : ∀ (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 slt_or_not_max_commute_proof : slt_or_not_max_commute_before ⊑ slt_or_not_max_commute_after

theorem appendInl_toCons {v : Var Γ t} :
    v.toCons (t':=t').appendInl (Δ := Δ) = v.appendInl.toCons

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

theorem lt_unsigned_to_large_signed_proof : lt_unsigned_to_large_signed_before ⊑ lt_unsigned_to_large_signed_after

theorem p0_proof : p0_before ⊑ p0_after

theorem AvoidCollision_setWidth_zero (m n : Nat) : setWidth m 0#n = 0#m

theorem test_zext_nneg_thm (e : IntW 64) (e_1 : IntW 32) (e_2 : IntW 64) :
  sub (add e_2 (const? 64 (-5))) (add (zext 64 (LLVM.xor e_1 (const? 32 (-1))) { «nneg» := true }) e) ⊑
    add (add e_2 (const? 64 (-4))) (sub (sext 64 e_1) e)

theorem test2_proof : test2_before ⊑ test2_after

@[simp]
theorem castLe_eq_self {α : Type _} {n : Nat} (i : Inputs α n) (h : n ≤ n) :
    i.castLe h = i

theorem logical_or_not_cond_reuse_proof : logical_or_not_cond_reuse_before ⊑ logical_or_not_cond_reuse_after

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

theorem and_zext_zext_thm.extracted_1._1 : ∀ (x : BitVec 4) (x_1 : BitVec 8),
  True ∧ (x_1 &&& zeroExtend 8 x).msb = true → False

theorem test11d_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  (x_1 ^^^ -1#32 ^^^ x) &&& (x_1 ^^^ x) = (x_1 ^^^ x) &&& (x_1 ^^^ x ^^^ -1#32)

theorem test4_thm.extracted_1._3 : ∀ (x : BitVec 1023), ¬ofBool (x <ₛ 0#1023) = 1#1 → 1022#1023 ≥ ↑1023 → False

theorem badimm1_proof : badimm1_before ⊑ badimm1_after

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

theorem tryFactorization_xor_ashr_lshr_proof : tryFactorization_xor_ashr_lshr_before ⊑ tryFactorization_xor_ashr_lshr_after

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 uge_to_slt_proof : uge_to_slt_before ⊑ uge_to_slt_after

theorem trunc_lshr_zext_exact_proof : trunc_lshr_zext_exact_before ⊑ trunc_lshr_zext_exact_after

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

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

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

theorem or_and2_commuted_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1),
  x_1 ||

theorem and_zext_zext_thm.extracted_1._2 : ∀ (x : BitVec 4) (x_1 : BitVec 8),
  ¬(True ∧ (x_1 &&& zeroExtend 8 x).msb = true) →
    zeroExtend 16 x_1 &&& zeroExtend 16 x = zeroExtend 16 (x_1 &&& zeroExtend 8 x)

theorem negative5_logical_proof : negative5_logical_before ⊑ negative5_logical_after

theorem XorZextXor_proof : XorZextXor_before ⊑ XorZextXor_after

theorem PR60818_eq_commuted_proof : PR60818_eq_commuted_before ⊑ PR60818_eq_commuted_after

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

theorem ne_10_proof : ne_10_before ⊑ ne_10_after

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

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

@[simp] theorem size_rets  : (rets v : Com d Γ eff t).size = 0

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

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

theorem trunc_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ofBool (x_1 <ᵤ x) = 1#1 → truncate 16 42#32 = 42#16

theorem ashrsgt_03_05_exact_proof : ashrsgt_03_05_exact_before ⊑ ashrsgt_03_05_exact_after

theorem bv_275 :
    ∀ (e e_1 : LLVM.IntW 5), LLVM.mul (LLVM.udiv e_1 e) e ⊑ LLVM.sub e_1 (LLVM.urem e_1 e)

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

theorem test47_thm.extracted_1._1 : ∀ (x : BitVec 8),
  zeroExtend 64 (signExtend 32 x ||| 42#32) = zeroExtend 64 (signExtend 32 (x ||| 42#8))

theorem sdiv_exact_eq_9_no_of_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ x_1.smod (x &&& 7#8) ≠ 0 ∨ (x &&& 7#8 == 0 || 8 != 1 && x_1 == intMin 8 && x &&& 7#8 == -1) = true) →
    True ∧ (x &&& 7#8).smulOverflow 9#8 = true ∨ True ∧ (x &&& 7#8).umulOverflow 9#8 = true → False

theorem and_slt_to_mask_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x <ₛ BitVec.ofInt 8 (-124)) &&& ofBool (x &&& 2#8 == 0#8) = ofBool (x <ₛ BitVec.ofInt 8 (-126))

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

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (x <ₛ x) = 0#1

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)

theorem sdiv6_thm (e : IntW 32) :
  mul (LLVM.sdiv e (const? 32 3) { «exact» := true }) (const? 32 (-3)) ⊑ sub (const? 32 0) e

theorem add_eq_sll (a : Nat) : a + a = a <<< 1

theorem zext_sext_add_icmp_eq_minus1_thm (e e_1 : IntW 1) :
  icmp IntPred.eq (add (zext 8 e_1) (sext 8 e)) (const? 8 (-1)) ⊑ LLVM.and e (LLVM.xor e_1 (const? 1 1))

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

theorem e_1777 :
    3 * (b ||| (a &&&  ~~~c)) + 1 * ( ~~~b &&& (a ^^^ c)) - 1 * (c ^^^ ( ~~~a &&& ( ~~~b ||| c))) + 4 * (b ^^^ ( ~~~a ||| (b &&& c))) - 7 * ( ~~~c &&& (a ^^^ b)) + 7 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) + 3 * ( ~~~(a ||| b) ||| (b ^^^ c)) - 2 * (b ^^^ (a ||| (b ^^^ c))) + 4 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) + 2 * ((a &&& c) ||| (b &&&  ~~~c)) + 1 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) + 5 * ( ~~~(a &&& b) &&& (b ^^^ c)) + 2 * (a ^^^ c) - 5 *  ~~~(a ^^^ (b ^^^ c)) - 3 * (b ^^^ (a ||| (b ||| c))) + 3 * (b ^^^ c) - 1 * (c &&&  ~~~(a &&&  ~~~b)) - 3 * (c &&& (a ||| b)) - 5 * (c ||| (a &&& b)) - 2 * (c ^^^ (a ||| (b ||| c))) - 6 * a - 1 * ( ~~~b |||  ~~~(a ^^^ c)) + 2 * (a &&& ( ~~~b ||| c)) - 1 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) - 1 *  ~~~( ~~~a ||| ( ~~~b &&& c)) + 2 * ((a &&& b) ^^^ (b |||  ~~~c)) - 3 * (b ||| (a &&& c)) + 11 * (c ^^^  ~~~(a |||  ~~~b)) - 7 * (b &&&  ~~~(a &&&  ~~~c)) - 2 *  ~~~(a ||| (b ||| c)) - 9 *  ~~~(a ||| ( ~~~b ||| c)) + 8 *  ~~~( ~~~a ||| (b ||| c)) + 6 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 14 * ( ~~~a &&& ( ~~~b &&& c)) + 20 * ( ~~~a &&& (b &&& c)) + 1 * (a &&& ( ~~~b &&& c)) - 1 * (a &&& (b &&& c)) = 5 * ((a ||| b) &&& (b ^^^ c)) + 7 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c))

lemma CNFA.union_spec (m1 m2 : CNFA n)
  {M1 : NFA' n} {M2 : NFA' n} :
    m1.Sim M1 →
    m2.Sim M2 →
    (m1.union m2).Sim (M1.union M2)

theorem test8_proof : test8_before ⊑ test8_after

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

theorem zext_masked_bit_zero_to_smaller_bitwidth_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬x_1 ≥ ↑32 → zeroExtend 16 (ofBool (1#32 <<< x_1 &&& x == 0#32)) = truncate 16 ((x ^^^ -1#32) >>> x_1) &&& 1#16

theorem positive_with_extra_and_logical_proof : positive_with_extra_and_logical_before ⊑ positive_with_extra_and_logical_after

theorem in_constant_varx_mone_invmask_proof : in_constant_varx_mone_invmask_before ⊑ in_constant_varx_mone_invmask_after

theorem t1_ult_slt_0_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.ult e_2 (const? 32 65536)) e_2 (select (icmp IntPred.slt e_2 (const? 32 0)) e_1 e) ⊑
    select (icmp IntPred.sgt e_2 (const? 32 65535)) e
      (select (icmp IntPred.slt e_2 (const? 32 0)) e_1 e_2)

theorem icmp_ugt_16_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ x <<< 16#64 >>> 16#64 ≠ x ∨ 16#64 ≥ ↑64) → ofBool (1048575#64 <ᵤ x <<< 16#64) = ofBool (15#64 <ᵤ x)

theorem lshrugt_01_07_exact_proof : lshrugt_01_07_exact_before ⊑ lshrugt_01_07_exact_after

theorem sdiv400_yes_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(2#32 ≥ ↑32 ∨ (100#32 == 0 || 32 != 1 && x >>> 2#32 == intMin 32 && 100#32 == -1) = true) →
    ¬400#32 = 0 → (x >>> 2#32).sdiv 100#32 = x / 400#32

theorem lshrult_02_03_exact_proof : lshrult_02_03_exact_before ⊑ lshrult_02_03_exact_after

theorem test2_thm (e : IntW 49) :
  urem e (shl (const? 49 4096) (const? 49 11)) ⊑ LLVM.and e (const? 49 8388607)

theorem low_mask_nsw_nuw_thm (e : IntW 32) :
  sub (const? 32 63) (LLVM.and e (const? 32 31)) ⊑ LLVM.xor (LLVM.and e (const? 32 31)) (const? 32 63)

theorem add_shl_same_amount_partial_nsw1_proof : add_shl_same_amount_partial_nsw1_before ⊑ add_shl_same_amount_partial_nsw1_after

theorem ne_commuted_equal_minus_1_proof : ne_commuted_equal_minus_1_before ⊑ ne_commuted_equal_minus_1_after

theorem different_size_zext_zext_slt_thm (e : IntW 4) (e_1 : IntW 7) :
  icmp IntPred.slt (zext 25 e_1) (zext 25 e) ⊑ icmp IntPred.ult e_1 (zext 7 e)

theorem shift_xor_multiuse_cmp_with_xor_thm.extracted_1._3 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ofBool (0#32 != x_3 &&& 4096#32) = 1#1 → ofBool (x_3 &&& 4096#32 == 0#32) = 1#1 → x_2 * x_1 = (x_2 ^^^ 2048#32) * x

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

theorem ashr_ult_2_thm (e : IntW 4) :
  icmp IntPred.ult (ashr e (const? 4 1)) (const? 4 2) ⊑ icmp IntPred.ult e (const? 4 4)

theorem not_xor_to_or_not2_proof : not_xor_to_or_not2_before ⊑ not_xor_to_or_not2_after

theorem neg_mask_const_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(True ∧ (1000#32).ssubOverflow (signExtend 32 x) = true ∨
        15#16 ≥ ↑16 ∨ True ∧ (0#32).ssubOverflow (zeroExtend 32 (x >>> 15#16)) = true) →
    ofBool (x <ₛ 0#16) = 1#1 →
      ¬(True ∧ (1000#32).ssubOverflow (signExtend 32 x) = true) →
        1000#32 - signExtend 32 x &&& 0#32 - zeroExtend 32 (x >>> 15#16) = 1000#32 - signExtend 32 x

theorem t10_proof : t10_before ⊑ t10_after

theorem icmp_slt_0_and_icmp_ne_neg2_i32_fail_proof : icmp_slt_0_and_icmp_ne_neg2_i32_fail_before ⊑ icmp_slt_0_and_icmp_ne_neg2_i32_fail_after

theorem shl_add_and_fail_mismatch_shift_thm (e e_1 : IntW 8) :
  LLVM.and (shl e_1 (const? 8 1)) (add (lshr e (const? 8 1)) (const? 8 123)) ⊑
    LLVM.and (shl e_1 (const? 8 1))
      (add (lshr e (const? 8 1)) (const? 8 123) { «nsw» := false, «nuw» := true })

theorem e_1530 :
     - 11 * (b ^^^ (a &&&  ~~~c)) - 1 * ( ~~~b &&& (a ^^^ c)) - 1 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) + 1 * (b &&&  ~~~c) + 4 *  ~~~( ~~~a ||| ( ~~~b &&& c)) + 1 *  ~~~(a ||| (b ||| c)) + 8 *  ~~~( ~~~a ||| (b ||| c)) - 4 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 2 * ( ~~~a &&& ( ~~~b &&& c)) + 11 * ( ~~~a &&& (b &&& c)) + 8 * (a &&& (b &&& c)) =  - 11 *  ~~~(a ||| ( ~~~b ||| c))

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

theorem shl_nsw_nuw_add_nsw_nuw_proof : shl_nsw_nuw_add_nsw_nuw_before ⊑ shl_nsw_nuw_add_nsw_nuw_after

theorem test_ashr_exact__exact_is_safe_proof : test_ashr_exact__exact_is_safe_before ⊑ test_ashr_exact__exact_is_safe_after

theorem test84_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ x.saddOverflow (BitVec.ofInt 32 (-16777216)) = true ∨
        True ∧ (x + BitVec.ofInt 32 (-16777216)) >>> 23#32 <<< 23#32 ≠ x + BitVec.ofInt 32 (-16777216) ∨ 23#32 ≥ ↑32) →
    ¬23#32 ≥ ↑32 →
      truncate 8 ((x + BitVec.ofInt 32 (-16777216)) >>> 23#32) = truncate 8 ((x + 2130706432#32) >>> 23#32)

theorem slt_and_max_proof : slt_and_max_before ⊑ slt_and_max_after

@[simp]
lemma complete_eval {M : NFA α σ} {w} (q : σ) :
    (.inl q ∈ M.complete.eval w) ↔ q ∈ M.eval w

theorem icmp_ne_and_z_and_onefail_proof : icmp_ne_and_z_and_onefail_before ⊑ icmp_ne_and_z_and_onefail_after

theorem n6_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 8), ofBool (x_2 &&& 1#8 == 3#8) = 1#1 → x_1 = x

theorem ashr_16_add_zext_basic_proof : ashr_16_add_zext_basic_before ⊑ ashr_16_add_zext_basic_after

theorem select_bittest_to_add_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 1#32 == 0#32) = 1#1 →
    True ∧ (x &&& 1#32).saddOverflow 3#32 = true ∨ True ∧ (x &&& 1#32).uaddOverflow 3#32 = true → False

theorem signExtend_succ (i : Nat) (x : BitVec w) :
    x.signExtend (i+1) = cons (if i < w then x.getLsbD i else x.msb) (x.signExtend i)

theorem e_669 :
     - 7 * x + 11 *  ~~~x + 1 * y + 7 * (x ||| y) + 1 *  ~~~(x &&&  ~~~y) - 1 *  ~~~(x &&&  ~~~x) - 9 *  ~~~(x ||| y) - 19 *  ~~~(x |||  ~~~y) + 3 * (x &&&  ~~~y) + 1 * (x &&& y) = 2 * (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

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

theorem sge_or_not_max_commute_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 != 127#8) = 1#1 → ofBool (x ≤ₛ x_1) = 1#1

theorem or_signbit_select_lshr_proof : or_signbit_select_lshr_before ⊑ or_signbit_select_lshr_after

theorem and_ashr_not_commuted_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 8),
  ¬(x_1 ≥ ↑8 ∨ x_1 ≥ ↑8) →
    ¬x_1 ≥ ↑8 → (x_2.sshiftRight' x_1 ^^^ -1#8) &&& x.sshiftRight' x_1 = (x &&& (x_2 ^^^ -1#8)).sshiftRight' x_1

theorem udiv_shl_mul_nuw_thm (e e_1 e_2 : IntW 5) :
  LLVM.udiv (shl e_2 e_1 { «nsw» := false, «nuw» := true }) (mul e_2 e { «nsw» := false, «nuw» := true }) ⊑
    LLVM.udiv (shl (const? 5 1) e_1 { «nsw» := false, «nuw» := true }) e

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

theorem xor_andn_commute2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 33),
  ¬x_1 = 0 → 42#33 / x_1 &&& (x ^^^ -1#33) ^^^ x = x ||

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

theorem main15_proof : main15_before ⊑ main15_after

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

theorem multiuse3_thm (e : IntW 32) :
  LLVM.or
      (LLVM.or (lshr (LLVM.and e (const? 32 96)) (const? 32 1) { «exact» := true })
        (LLVM.and (lshr e (const? 32 1)) (const? 32 15)))
      (LLVM.or (shl (LLVM.and e (const? 32 96)) (const? 32 6) { «nsw» := true, «nuw» := true })
        (LLVM.and (shl e (const? 32 6)) (const? 32 1920))) ⊑
    LLVM.or
      (LLVM.or (LLVM.and (lshr e (const? 32 1)) (const? 32 48)) (LLVM.and (lshr e (const? 32 1)) (const? 32 15))
        { «disjoint» := true })
      (LLVM.and (shl e (const? 32 6)) (const? 32 8064)) { «disjoint» := true }

theorem xor_nosignbit_select_lshr_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 → ¬8#32 ≥ ↑32 → (x ^^^ 2147418112#32) >>> 8#32 = x >>> 8#32 ^^^ 8388352#32

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

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

theorem test67_proof : test67_before ⊑ test67_after

theorem lt_two_pow_succ_of_lt (x y : Nat) :
    (x / 2) < 2 ^ y → x < 2 ^ (y + 1)

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

theorem select_icmp_ne_0_and_4096_xor_32_proof : select_icmp_ne_0_and_4096_xor_32_before ⊑ select_icmp_ne_0_and_4096_xor_32_after

theorem sext_shl_trunc_same_size_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 16),
  ¬x ≥ ↑32 → truncate 16 (signExtend 32 x_1 <<< x) = truncate 16 (zeroExtend 32 x_1 <<< x)

theorem neg_signbit_proof : neg_signbit_before ⊑ neg_signbit_after

theorem testtrunclowhigh_thm.extracted_1._4 : ∀ (x x_1 : BitVec 16) (x_2 : BitVec 32),
  ¬ofBool (x_2 + 128#32 <ᵤ 256#32) = 1#1 → ¬ofBool (-1#32 <ₛ x_2) = 1#1 → ¬ofBool (x_2 <ₛ 0#32) = 1#1 → x = x_1

theorem lshrugt_02_12_thm (e : IntW 4) : icmp IntPred.ugt (lshr e (const? 4 2)) (const? 4 (-4)) ⊑ const? 1 0

theorem e_1289 :
    11 *  ~~~t - 3 * t - 1 * z + 4 * (z ^^^ t) + 1 *  ~~~z - 11 *  ~~~(z &&&  ~~~t) - 1 *  ~~~(z ||| t) + 9 *  ~~~(z |||  ~~~t) - 14 * (z &&&  ~~~t) =  - 15 * (z &&& t)

theorem alive_AndOrXor_1683_2 : alive_AndOrXor_1683_2_src ⊑ alive_AndOrXor_1683_2_tgt

theorem test6_thm.extracted_1._1 : ∀ (x x_1 : BitVec 57), x_1 - (x_1 &&& x) = x_1 &&& (x ^^^ -1#57)

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

@[simp] lemma liftMaxSuccSucc2_cast {x : Fin m} : liftMaxSuccSucc2 n m x.castSucc = x.castLE (by omega)

theorem test5_proof : test5_before ⊑ test5_after

theorem not_or_or_and_not_and_and_commute3_proof : not_or_or_and_not_and_and_commute3_before ⊑ not_or_or_and_not_and_and_commute3_after

theorem test19_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (signExtend 64 x <ₛ 12345#64) = ofBool (x <ₛ 12345#32)

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_3b_logical_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 15)) (const? 32 0)) (const? 1 1)
      (icmp IntPred.ne (LLVM.and e (const? 32 3)) (const? 32 0)) ⊑
    LLVM.or (icmp IntPred.eq (LLVM.and e (const? 32 15)) (const? 32 0))
      (icmp IntPred.ne (LLVM.and e (const? 32 3)) (const? 32 0))

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

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

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

theorem test_with_neg_5_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → BitVec.ofInt 32 (-5) <<< x &&& 1#32 = zeroExtend 32 (ofBool (x == 0#32))

theorem icmp_uge_x_y_2_proof : icmp_uge_x_y_2_before ⊑ icmp_uge_x_y_2_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 main12_logical_thm.extracted_1._4 : ∀ (x : BitVec 32),
  ¬ofBool (truncate 16 x <ₛ 0#16) = 1#1 →
    ¬ofBool (x &&& 32896#32 == 0#32) = 1#1 → ¬ofBool (truncate 8 x <ₛ 0#8) = 1#1 → 1#32 = 2#32

theorem Tensor2d'.fill_extract (δ₀ δ₁ sz₀ sz₁ : ℕ) (t : Tensor2d' α) (v : β) :
  (t.fill v).extract δ₀ δ₁ sz₀ sz₁ = (t.extract δ₀ δ₁ sz₀ sz₁).fill v

theorem icmp_ule_proof : icmp_ule_before ⊑ icmp_ule_after

theorem e_1169 :
    1 *  ~~~(z &&&  ~~~z) - 1 *  ~~~(z &&&  ~~~t) - 7 *  ~~~z + 1 * t - 2 *  ~~~(z ||| t) + 6 *  ~~~(z |||  ~~~t) - 8 * (z &&&  ~~~t) - 10 * (z &&& t) =  - 2 *  ~~~(z ^^^ t) - 7 * (z |||  ~~~t)

theorem zext_sext_add_icmp_sgt_1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  ofBool (1#8 <ₛ zeroExtend 8 x_1 + signExtend 8 x) = 0#1

theorem e_1325 :
    11 *  ~~~z + 1 * (z |||  ~~~t) + 2 * (z ^^^ t) - 11 *  ~~~t + 1 *  ~~~(z ^^^ t) + 2 * (z ||| t) - 4 *  ~~~(z ||| t) - 17 *  ~~~(z |||  ~~~t) + 6 * (z &&&  ~~~t) =  - 2 *  ~~~(z &&&  ~~~t) + 6 * (z &&& t)

theorem test14_thm (e e_1 : IntW 32) :
  mul (LLVM.and (sub (shl e_1 (const? 32 8)) e) (const? 32 128)) (shl e_1 (const? 32 8)) ⊑
    mul (LLVM.and (sub (const? 32 0) e) (const? 32 128)) (shl e_1 (const? 32 8))

theorem rotateleft_9_neg_mask_wide_amount_commute_proof : rotateleft_9_neg_mask_wide_amount_commute_before ⊑ rotateleft_9_neg_mask_wide_amount_commute_after

@[simp] lemma NFA'.autUnsignedCmp_σ (cmp : RelationOrdering) : (NFA'.autUnsignedCmp cmp).σ = NFA.unsignedCmpState

theorem ult_and_max_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.ult e_1 e) (icmp IntPred.eq e_1 (const? 8 (-1))) ⊑ const? 1 0

theorem ule_umax3_thm (e e_1 : IntW 32) :
  icmp IntPred.uge (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.ule e (add e_1 (const? 32 3))

theorem test_shift_nonnegative_thm (e : IntW 32) :
  icmp IntPred.sge (shl (lshr e (const? 32 2)) (const? 32 3) { «nsw» := true, «nuw» := false }) (const? 32 0) ⊑
    const? 1 1

theorem shl1_trunc_sgt0_proof : shl1_trunc_sgt0_before ⊑ shl1_trunc_sgt0_after

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

theorem test11_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32) →
    ¬8#32 ≥ ↑32 → (x_1 <<< 8#32 + x &&& 128#32) * x_1 <<< 8#32 = (x &&& 128#32) * x_1 <<< 8#32

theorem e_1605 :
    5 * ((a |||  ~~~b) &&& (b ^^^ c)) + 2 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) + 1 * (b ^^^ (a &&& (b ^^^ c))) - 1 * (a ^^^ ( ~~~b ||| c)) - 7 *  ~~~(b ||| c) - 7 *  ~~~(a ^^^ (b ^^^ c)) - 7 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 2 * ( ~~~a &&& (b ^^^ c)) - 5 * ( ~~~(a &&& b) &&& (b ^^^ c)) - 5 * ( ~~~c &&&  ~~~(a ^^^ b)) + 2 * ((a &&& c) |||  ~~~(b ||| c)) + 24 *  ~~~(a ||| (b ||| c)) - 1 *  ~~~(a ||| ( ~~~b ||| c)) + 2 *  ~~~( ~~~a ||| (b ||| c)) + 12 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 1 * ( ~~~a &&& ( ~~~b &&& c)) + 7 * ( ~~~a &&& (b &&& c)) + 9 * (a &&& ( ~~~b &&& c)) - 4 * (a &&& (b &&& c)) =  - 1 * (c ^^^  ~~~(a &&& (b &&& c)))

theorem test_sub_255_Y_eq_255_proof : test_sub_255_Y_eq_255_before ⊑ test_sub_255_Y_eq_255_after

theorem ult_x_impliesT_eq_umax_todo_proof : ult_x_impliesT_eq_umax_todo_before ⊑ ult_x_impliesT_eq_umax_todo_after

theorem foo1_and_signbit_lshr_proof : foo1_and_signbit_lshr_before ⊑ foo1_and_signbit_lshr_after

theorem src_srem_shl_demand_eliminate_signbit_proof : src_srem_shl_demand_eliminate_signbit_before ⊑ src_srem_shl_demand_eliminate_signbit_after

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

theorem lshr_or_or_no_const_thm.extracted_1._1 : ∀ (x x_1 x_2 x_3 : BitVec 8),
  ¬(x_2 ≥ ↑8 ∨ x_2 ≥ ↑8) → x_2 ≥ ↑8 → False

theorem test_nsw_dropped_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 1073741823#32 == 0#32) = 1#1 → 2#32 ≥ ↑32 → False

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

theorem slt_and_not_max_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.slt e_1 e) (icmp IntPred.ne e_1 (const? 8 127)) ⊑
    icmp IntPred.slt e_1 e

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

theorem test_ashr_exact__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 →
    ¬(True ∧ (x_1 &&& BitVec.ofInt 32 (-2147483585)) >>> 2#32 <<< 2#32 ≠ x_1 &&& BitVec.ofInt 32 (-2147483585) ∨
          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 test4_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), x_1 ||

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

theorem test_thm (e : IntW 32) : ashr (ashr e (const? 32 17)) (const? 32 17) ⊑ ashr e (const? 32 31)

theorem ne_smax3_proof : ne_smax3_before ⊑ ne_smax3_after

theorem e_819 :
    2 *  ~~~(z &&&  ~~~z) - 1 *  ~~~(z ^^^ t) + 1 * (z ^^^ t) + 2 *  ~~~(z ||| t) - 3 *  ~~~(z |||  ~~~t) = 1 * (z &&& t) + 3 *  ~~~t

theorem test11_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬4#32 = 0 → (x &&& BitVec.ofInt 32 (-2)) * 2#32 % 4#32 = 0#32

theorem both_sides_fold_slt_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → ofBool (9#32 <ₛ 1#32) = 0#1

theorem ashr_1_thm (e e_1 e_2 : IntW 8) (e_3 : IntW 1) :
  LLVM.xor (ashr (select e_3 (LLVM.xor e_2 (const? 8 (-1))) (LLVM.xor e_1 (const? 8 123))) e) (const? 8 (-1)) ⊑
    ashr (select e_3 e_2 (LLVM.xor e_1 (const? 8 (-124)))) e

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

theorem bv_820 :
    ∀ (e e_1 : LLVM.IntW 9), LLVM.sdiv (LLVM.sub e (LLVM.srem e e_1)) e_1 ⊑ LLVM.sdiv e e_1

theorem ashr_or_proof : ashr_or_before ⊑ ashr_or_after

@[simp]
theorem mem_mkLowerTriangularPairs₂  {n : Nat} {ij :  Nat × Nat} :
  (ij ∈ mkLowerTriangularPairs n) ↔
  (ij.1 < ij.2 ∧ ij.2 ≤ n)

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

theorem scalar_i32_lshr_and_negC_eq_nonzero_proof : scalar_i32_lshr_and_negC_eq_nonzero_before ⊑ scalar_i32_lshr_and_negC_eq_nonzero_after

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

theorem 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 positive_samevar_ashrexact_proof : positive_samevar_ashrexact_before ⊑ positive_samevar_ashrexact_after

theorem e_2095 :
     - 1 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 11 *  ~~~(d &&&  ~~~e) + 1 * (e |||  ~~~(d ||| f)) + 4 * (f ^^^  ~~~(d &&& (e ||| f))) + 1 *  ~~~(d |||  ~~~e) - 11 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 5 * (e ^^^ ( ~~~d ||| (e ||| f))) + 7 *  ~~~(d ^^^ (e &&& f)) - 1 * ( ~~~d ||| ( ~~~e &&& f)) + 1 *  ~~~(d &&& e) - 3 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 3 * (e ^^^  ~~~(d |||  ~~~f)) - 7 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 7 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 6 * ((d &&& f) |||  ~~~(e ||| f)) + 11 * (e ^^^ (d ||| (e ^^^ f))) + 4 * ((d &&& e) ||| (e ^^^ f)) - 1 *  ~~~d - 11 * (f ^^^ (d |||  ~~~e)) + 1 * (f ||| (d ^^^ e)) + 2 * (d ^^^ (e ^^^ f)) - 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 5 * ( ~~~d ||| ( ~~~e ||| f)) - 7 * (f ^^^ (d &&& e)) - 1 * (e &&&  ~~~(d &&&  ~~~f)) + 1 * (f &&& (d ||| e)) + 1 * ( ~~~f ||| (d ^^^ e)) - 5 * (d ^^^ ( ~~~e &&& f)) - 1 *  ~~~(d ^^^ ( ~~~e ||| f)) + 7 * ((d &&& e) |||  ~~~(e ||| f)) + 2 * (f |||  ~~~(d ^^^ e)) + 11 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 6 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 5 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 7 * (f ^^^  ~~~(d ||| e)) + 45 *  ~~~(d ||| (e ||| f)) - 1 *  ~~~( ~~~d ||| (e ||| f)) + 53 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 26 * ( ~~~d &&& ( ~~~e &&& f)) + 40 * ( ~~~d &&& (e &&& f)) + 23 * (d &&& ( ~~~e &&& f)) + 18 * (d &&& (e &&& f)) =  - 7 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 5 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f)))

theorem alive_AndOrXor_887_2 : alive_AndOrXor_887_2_src ⊑ alive_AndOrXor_887_2_tgt

theorem icmp_sgt10_proof : icmp_sgt10_before ⊑ icmp_sgt10_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_6_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_6_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_6_after

theorem test_invert_demorgan_logical_or_thm.extracted_1._3 : ∀ (x x_1 : BitVec 64),
  ofBool (x_1 == 27#64) = 1#1 →
    ofBool (x_1 != 27#64) = 1#1 →
      (ofBool (x_1 == 0#64) ||| 1#1) ^^^ 1#1 = ofBool (x_1 != 0#64) &&& ofBool (x != 0#64)

theorem and_ne_with_one_bit_diff_constants1_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x != 51#32) = 1#1 → 0#1 = ofBool (x + BitVec.ofInt 32 (-52) <ᵤ BitVec.ofInt 32 (-2))

theorem icmp_slt_0_xor_icmp_sgt_neg2_i32_proof : icmp_slt_0_xor_icmp_sgt_neg2_i32_before ⊑ icmp_slt_0_xor_icmp_sgt_neg2_i32_after

@[simp]
theorem R.representative_add (a b : R q n) :
    (a + b).representative = a.representative + b.representative

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 e_1854 :
     - 11 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) - 5 *  ~~~(a ^^^ ( ~~~b ||| c)) - 6 * ((a ||| b) &&& (b ^^^ c)) - 11 * (a ^^^ (b ^^^ c)) - 3 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) - 1 * (a ||| b) + 11 * (a ||| ( ~~~b ||| c)) + 1 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) - 7 * (a |||  ~~~c) - 1 * ((a ||| b) &&&  ~~~(b ^^^ c)) + 11 *  ~~~(b ||| c) - 1 * (b &&&  ~~~(a ^^^ c)) + 4 * (b ^^^  ~~~(a &&& (b ||| c))) - 1 * (a ||| (b ^^^ c)) - 1 * ( ~~~b |||  ~~~(a ^^^ c)) - 3 * (c |||  ~~~(a ||| b)) + 3 * ( ~~~a &&& (b ^^^ c)) - 1 * ( ~~~b &&& (a ^^^ c)) - 2 * (b ^^^ c) - 7 * (a ||| (b &&& c)) + 3 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) - 3 * ( ~~~a &&& (b ||| c)) + 2 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) - 2 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) - 1 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 5 * ((a &&&  ~~~b) ||| (b ^^^ c)) + 2 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 7 * (b ^^^  ~~~(a &&& c)) + 11 * (b ^^^  ~~~(a |||  ~~~c)) + 1 *  ~~~(a ^^^ b) - 2 *  ~~~(a &&& (b &&& c)) - 1 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) + 11 * ((a &&& b) |||  ~~~(b |||  ~~~c)) - 1 *  ~~~( ~~~a &&& (b ^^^ c)) + 5 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 5 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) - 1 * (c |||  ~~~(a ^^^ b)) - 16 *  ~~~(a ||| (b ||| c)) + 26 *  ~~~(a ||| ( ~~~b ||| c)) + 1 *  ~~~( ~~~a ||| (b ||| c)) - 3 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 30 * ( ~~~a &&& ( ~~~b &&& c)) + 9 * ( ~~~a &&& (b &&& c)) + 13 * (a &&& ( ~~~b &&& c)) + 6 * (a &&& (b &&& c)) = 3 *  ~~~(a ||| ( ~~~b &&& c)) - 3 *  ~~~a

theorem sle_swap_and_min_logical_proof : sle_swap_and_min_logical_before ⊑ sle_swap_and_min_logical_after

theorem slt_to_ult_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 ^^^ BitVec.ofInt 8 (-128) <ₛ x ^^^ BitVec.ofInt 8 (-128)) = ofBool (x_1 <ᵤ x)

theorem sub_3_thm.extracted_1._4 : ∀ (x x_1 : BitVec 128) (x_2 : BitVec 1) (x_3 : BitVec 128),
  ¬x_2 = 1#1 → x_3 - (x ^^^ 123#128) ^^^ -1#128 = BitVec.ofInt 128 (-2) - ((x ^^^ BitVec.ofInt 128 (-124)) + x_3)

theorem test36_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 e_2493 :
     - 3 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 1 * (d ^^^ ( ~~~e ||| f)) + 4 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 7 *  ~~~(d &&& e) - 1 * ((d ||| e) &&& (e ^^^ f)) + 4 * (f &&&  ~~~(d ^^^ e)) - 2 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 11 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 7 * ((d &&& e) ^^^ (e |||  ~~~f)) + 2 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 11 * (e ^^^ (d |||  ~~~f)) + 2 * (f ^^^  ~~~(d ||| (e &&& f))) + 1 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 2 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 4 *  ~~~(d ^^^ ( ~~~e &&& f)) - 11 * (f &&& (d ^^^ e)) + 1 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 5 * (f ^^^ (d ||| ( ~~~e &&& f))) - 3 * (d ||| e) + 3 * ((d ^^^ e) |||  ~~~(d ^^^ f)) + 1 * ((d |||  ~~~e) &&& (e ^^^ f)) + 2 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 11 *  ~~~(d ^^^ (e &&& f)) - 5 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * (e &&&  ~~~(d &&& f)) + 1 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 1 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 2 * (f |||  ~~~(d ||| e)) - 6 * (d ||| (e ^^^ f)) - 7 * ( ~~~d ||| (e &&& f)) + 2 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 4 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 1 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 6 *  ~~~(d &&& (e ||| f)) + 11 *  ~~~f + 4 * (d ^^^ ( ~~~e &&& f)) - 6 * (d ^^^ (e ||| f)) - 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 2 *  ~~~(d &&& (e ^^^ f)) + 3 * (e ||| (d &&&  ~~~f)) - 11 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 1 * (d &&& ( ~~~e ||| f)) - 11 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 5 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 3 * (d ||| ( ~~~e ||| f)) - 1 *  ~~~(d ^^^ (e ^^^ f)) + 1 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 5 * ( ~~~f &&&  ~~~(d ^^^ e)) + 5 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 5 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 3 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 11 *  ~~~(d &&&  ~~~f) + 1 *  ~~~(e |||  ~~~f) - 1 * (e ^^^ (d &&& (e ^^^ f))) + 1 * (e ^^^  ~~~(d |||  ~~~f)) + 3 * (f ^^^  ~~~(d |||  ~~~e)) - 5 * (f ^^^ ( ~~~d ||| (e ||| f))) - 5 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 2 * (d &&& e) + 1 * (f ^^^ (d ||| (e ||| f))) + 2 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 5 * ((e &&& f) ||| (d &&& (e ||| f))) - 3 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 5 * (e ^^^ (d &&&  ~~~f)) - 7 * (d ||| (e &&& f)) - 6 * ( ~~~d ||| (e ||| f)) - 2 * (e ^^^  ~~~(d &&& (e &&& f))) - 1 * (f &&& (d ||| e)) + 5 *  ~~~(d ||| (e &&& f)) - 5 * (e ^^^ (d &&& ( ~~~e ||| f))) + 1 * (e |||  ~~~(d |||  ~~~f)) - 1 * (d ^^^ f) - 1 * ( ~~~f |||  ~~~(d ^^^ e)) + 15 *  ~~~(d ||| (e ||| f)) + 50 *  ~~~(d ||| ( ~~~e ||| f)) + 63 *  ~~~( ~~~d ||| (e ||| f)) + 33 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 3 * ( ~~~d &&& ( ~~~e &&& f)) + 46 * ( ~~~d &&& (e &&& f)) + 55 * (d &&& ( ~~~e &&& f)) + 1 * (d &&& (e &&& f)) = 2 * (d &&& (e ||| f))

theorem PR30273_three_bools_thm.extracted_1._2 : ∀ (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) →
              zeroExtend 32 x + 1#32 + 1#32 = 2#32 + zeroExtend 32 x_2

theorem factorize5_thm (e e_1 : IntW 32) : sub (mul (mul e_1 (const? 32 2)) e) (mul e e_1) ⊑ mul e_1 e

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

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

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

theorem shl_bad_sub2_i32_proof : shl_bad_sub2_i32_before ⊑ shl_bad_sub2_i32_after

theorem shl_sub_i8_thm (e : IntW 8) :
  shl (const? 8 1) (sub (const? 8 7) e) ⊑ lshr (const? 8 (-128)) e { «exact» := true }

theorem e_588 :
    1 *  ~~~x + 3 * (x ^^^ y) + 11 *  ~~~(x &&& y) - 1 * x + 7 * (x ||| y) + 5 *  ~~~(x ^^^ y) + 2 *  ~~~(x &&&  ~~~x) - 19 *  ~~~(x ||| y) - 24 *  ~~~(x |||  ~~~y) - 22 * (x &&&  ~~~y) = 13 * (x &&& y)

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

theorem test11_thm (e e_1 : IntW 32) :
  trunc 64 (shl (zext 128 e_1) (LLVM.and (zext 128 e) (const? 128 31))) ⊑
    shl (zext 64 e_1) (zext 64 (LLVM.and e (const? 32 31)) { «nneg» := true }) { «nsw» := true, «nuw» := true }

@[simp]
lemma Fin.clamp_eq_bound : Fin.clamp m n = Fin.last n ↔ n ≤ m

theorem test17_thm (e : IntW 1) : sub (const? 32 0) (sext 32 e) ⊑ zext 32 e

theorem ashrslt_03_03_exact_proof : ashrslt_03_03_exact_before ⊑ ashrslt_03_03_exact_after

theorem fold_select_trunc_nsw_true_thm.extracted_1._2 : ∀ (x x_1 : BitVec 128),
  ¬(True ∧ signExtend 128 (truncate 1 x_1) ≠ x_1) → truncate 1 x_1 = 1#1 → x_1 = -1#128

theorem fold_add_sdiv_srem_proof : fold_add_sdiv_srem_before ⊑ fold_add_sdiv_srem_after

theorem shift_xor_multiuse_cmp_with_xor_proof : shift_xor_multiuse_cmp_with_xor_before ⊑ shift_xor_multiuse_cmp_with_xor_after

theorem icmp_x_slt_0_xor_icmp_y_sgt_neg1_i32_proof : icmp_x_slt_0_xor_icmp_y_sgt_neg1_i32_before ⊑ icmp_x_slt_0_xor_icmp_y_sgt_neg1_i32_after

theorem or_lshr_thm (e e_1 e_2 e_3 : IntW 8) :
  LLVM.or (lshr e_3 e_2) (LLVM.or (lshr e_1 e_2) e) ⊑ LLVM.or (lshr (LLVM.or e_1 e_3) e_2) e

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 599),
  x = 1#1 → ¬70368744177664#599 = 0 → 46#599 ≥ ↑599 → False

theorem ashr_lshr_no_exact_proof : ashr_lshr_no_exact_before ⊑ ashr_lshr_no_exact_after

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

theorem trunc_shl_ashr_var_thm (e e_1 : IntW 64) :
  trunc 32 (shl (ashr e_1 e) (const? 64 2)) ⊑ shl (trunc 32 (ashr e_1 e)) (const? 32 2)

@[grind =, simp, aesop 50% unsafe]
lemma newState_finals (m : RawCNFA A) :
    m.newState.2.finals = m.finals

theorem substitute_constant_and_ne_ugt_swap_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x <ᵤ x_1) = 1#1 → ofBool (x != 42#8) = ofBool (x <ᵤ x_1) &&& ofBool (x != 42#8)

theorem test13_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  x_1 ^^^ -1#32 ^^^ x_1 &&& (x ^^^ -1#32) = x_1 &&& x ^^^ -1#32

theorem ashr_ugt_14_proof : ashr_ugt_14_before ⊑ ashr_ugt_14_after

theorem test10_proof : test10_before ⊑ test10_after

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

theorem ashrsgt_03_14_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬3#4 ≥ ↑4 → ofBool (BitVec.ofInt 4 (-2) <ₛ x.sshiftRight' 3#4) = 1#1

theorem ashr_x_by_const_cmp_sge_x_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬5#32 ≥ ↑32 → ofBool (x ≤ₛ x.sshiftRight' 5#32) = ofBool (x <ₛ 1#32)

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3b_logical_thm (e : IntW 32) :
  select (icmp IntPred.ne (LLVM.and e (const? 32 3)) (const? 32 0)) (const? 1 1)
      (icmp IntPred.eq (LLVM.and e (const? 32 15)) (const? 32 0)) ⊑
    LLVM.or (icmp IntPred.ne (LLVM.and e (const? 32 3)) (const? 32 0))
      (icmp IntPred.eq (LLVM.and e (const? 32 15)) (const? 32 0))

theorem sge_smin4_proof : sge_smin4_before ⊑ sge_smin4_after

@[simp]
theorem BitVec.ofInt_zero (w : ℕ) :
    BitVec.ofInt w 0 = 0

theorem sgt_and_min_thm (e e_1 : IntW 9) :
  LLVM.and (icmp IntPred.sgt e_1 e) (icmp IntPred.eq e_1 (const? 9 (-256))) ⊑ const? 1 0

theorem xor_or_thm.extracted_1._7 : ∀ (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 = ofBool (x ≤ᵤ x_1)

theorem and_xor_commute1_proof : and_xor_commute1_before ⊑ and_xor_commute1_after

theorem and_zext_zext_thm (e : IntW 4) (e_1 : IntW 8) :
  LLVM.and (zext 16 e_1) (zext 16 e) ⊑ zext 16 (LLVM.and e_1 (zext 8 e)) { «nneg» := true }

theorem lshr_or_or_fail_thm (e e_1 : IntW 8) :
  LLVM.or (lshr e_1 (const? 8 5)) (LLVM.or (lshr e (const? 8 5)) (const? 8 (-58))) ⊑
    LLVM.or (lshr (LLVM.or e e_1) (const? 8 5)) (const? 8 (-58))

theorem or_not_xor_common_op_commute3_proof : or_not_xor_common_op_commute3_before ⊑ or_not_xor_common_op_commute3_after

omit [Fintype S] [DecidableEq S] [LawfulBEq A] in
theorem processOneElem_grow (st : worklist.St A S) (final : S → Bool) (a : A) (sa' : S) (s : State) :
      let st' := processOneElem _ _ final s st (a, sa')
      ∃ sas, List.Perm st'.map.keys (sas ++ st.map.keys) ∧ st'.worklist.toList = st.worklist.toList ++ sas

theorem sub_from_constant_proof : sub_from_constant_before ⊑ sub_from_constant_after

theorem PR1817_1_proof : PR1817_1_before ⊑ PR1817_1_after

theorem must_drop_poison_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ ((x_1 &&& 255#32) <<< x).sshiftRight' x ≠ x_1 &&& 255#32 ∨
        True ∧ (x_1 &&& 255#32) <<< x >>> x ≠ x_1 &&& 255#32 ∨ x ≥ ↑32) →
    x ≥ ↑32 → False

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 ashrslt_02_14_proof : ashrslt_02_14_before ⊑ ashrslt_02_14_after

theorem test24_proof : test24_before ⊑ test24_after

theorem ashr_16_add_zext_basic_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬16#32 ≥ ↑32 → (zeroExtend 32 x_1 + zeroExtend 32 x) >>> 16#32 = zeroExtend 32 (ofBool (x_1 ^^^ -1#16 <ᵤ x))

theorem test1_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 57),
  ¬(x_1 ≥ ↑57 ∨ x_1 ≥ ↑57) → ¬x_1 ≥ ↑57 → x_2 >>> x_1 ||

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

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

theorem n2_proof : n2_before ⊑ n2_after

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

theorem or_logic_or_logic_and_1_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 ||

theorem p13_commutativity0_thm (e e_1 : IntW 32) :
  select (icmp IntPred.ult e_1 (const? 32 65536)) (const? 32 65535) e ⊑
    select (icmp IntPred.ugt e_1 (const? 32 65535)) e (const? 32 65535)

theorem sle_smax4_thm (e e_1 : IntW 32) :
  icmp IntPred.sge (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.sle e (add e_1 (const? 32 3))

theorem positive_sameconst_proof : positive_sameconst_before ⊑ positive_sameconst_after

theorem ripple_nsw2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  True ∧ (x_1 &&& BitVec.ofInt 16 (-16385)).saddOverflow (x &&& 1#16) = true ∨
      True ∧ (x_1 &&& BitVec.ofInt 16 (-16385)).uaddOverflow (x &&& 1#16) = true →
    False

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

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

@[simp_denote (high)] -- high priority so that this is tried before the `reduceIsRefinedBy` simproc
theorem pure_isRefinedBy_pure (x : α) (y : β) :
  (pure x : Id _) ⊑ (pure y : Id _) ↔ x ⊑ y

theorem trunc_lshr_sext_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬6#32 ≥ ↑32 → ¬6#8 ≥ ↑8 → truncate 8 (signExtend 32 x >>> 6#32) = x.sshiftRight' 6#8

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

@[simp] lemma eval_single [DecidableEq α] {s : List α} (x : ∀ a ∈ s, Bool) (g : α → Bool):
  eval (single x) g ↔ (∀ a (ha : a ∈ s), g a = x a (by simpa))

theorem ashrslt_01_12_exact_proof : ashrslt_01_12_exact_before ⊑ ashrslt_01_12_exact_after

theorem t0_proof : t0_before ⊑ t0_after

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

theorem eq_3210_proof : eq_3210_before ⊑ eq_3210_after

theorem ne_smax3_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (add e_1 (const? 32 3))
      (select (icmp IntPred.sgt (add e_1 (const? 32 3)) e) (add e_1 (const? 32 3)) e) ⊑
    icmp IntPred.slt (add e_1 (const? 32 3)) e

omit [Fintype S] [DecidableEq S] [LawfulBEq A] in
lemma processOneElem_preserves_mem (st : worklist.St A S) (final : S → Bool) (a : A) (sa sa' : S) (s : State) :
    let st' := processOneElem _ _  final s st (a, sa')
    sa ∈ st.map →
    sa ∈ st'.map

theorem and_ne_with_one_bit_diff_constants2_logical_proof : and_ne_with_one_bit_diff_constants2_logical_before ⊑ and_ne_with_one_bit_diff_constants2_logical_after

theorem n10_wrong_low_bit_mask_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬ofBool (x &&& 31#8 == 0#8) = 1#1 → x + 16#8 &&& BitVec.ofInt 8 (-16) = (x &&& BitVec.ofInt 8 (-16)) + 16#8

theorem sle_swap_or_not_min_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.sge e_1 e) (icmp IntPred.ne e (const? 8 (-128))) ⊑ const? 1 1

theorem negative_trunc_not_arg_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬ofBool (-1#8 <ₛ truncate 8 x) = 1#1 → ofBool (x &&& 128#32 == 0#32) = 1#1 → False

theorem src_is_mask_const_slt_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x ^^^ 123#8 <ₛ (x ^^^ 123#8) &&& 7#8) = ofBool (x <ₛ 0#8)

theorem test18_proof : test18_before ⊑ test18_after

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

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

theorem e_594 :
     - 3 *  ~~~y - 5 * (x ^^^ y) + 11 * y + 7 *  ~~~x + 7 *  ~~~(x &&&  ~~~x) + 2 *  ~~~(x &&&  ~~~y) - 13 *  ~~~(x ||| y) - 11 *  ~~~(x |||  ~~~y) + 12 * (x &&&  ~~~y) - 9 * (x &&& y) = 11 * (x ||| y)

theorem t0_basic_thm (e e_1 : IntW 8) : icmp IntPred.ugt (sub e_1 e) e_1 ⊑ icmp IntPred.ugt e e_1

theorem reduce_xor_common_op_commute1_proof : reduce_xor_common_op_commute1_before ⊑ reduce_xor_common_op_commute1_after

theorem positive_with_mask_logical_proof : positive_with_mask_logical_before ⊑ positive_with_mask_logical_after

theorem test_const_shr_and_1_ne_0_proof : test_const_shr_and_1_ne_0_before ⊑ test_const_shr_and_1_ne_0_after

theorem nonexact_lshr_ne_proof : nonexact_lshr_ne_before ⊑ nonexact_lshr_ne_after

theorem p0_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x &&& 3#8 <ₛ x) = ofBool (3#8 <ₛ x)

theorem urem_i8_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬zeroExtend 32 x = 0 → ¬x = 0 → truncate 8 (zeroExtend 32 x_1 % zeroExtend 32 x) = x_1 % x

theorem sge_or_not_max_logical_proof : sge_or_not_max_logical_before ⊑ sge_or_not_max_logical_after

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

theorem fold_sext_to_and_wrong5_proof : fold_sext_to_and_wrong5_before ⊑ fold_sext_to_and_wrong5_after

theorem ashr_can_be_lshr_2_proof : ashr_can_be_lshr_2_before ⊑ ashr_can_be_lshr_2_after

theorem add_or_and_commutative_proof : add_or_and_commutative_before ⊑ add_or_and_commutative_after

theorem shl_sub_lshr_reverse_nsw_on_op1_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ (x_1 <<< x).sshiftRight' x ≠ x_1 ∨
        True ∧ x_1 <<< x >>> x ≠ x_1 ∨
          x ≥ ↑32 ∨
            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).usubOverflow x_1 = true → False

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

@[simp] lemma composeUnaryAux_eval
    (p : FSM Unit)
    (q : FSM arity)
    (x : arity → BitStream) :
    (composeUnaryAux p q).eval x = p.eval (λ _ => q.eval x)

theorem lshrult_02_13_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 (-3)) = 1#1

theorem alive_InstCombineShift__582  (w : Nat)   : alive_InstCombineShift__582_src w  ⊑ alive_InstCombineShift__582_tgt w

theorem not_bool_add_lshr_thm.extracted_1._1 : ∀ (x x_1 : BitVec 2),
  ¬2#4 ≥ ↑4 → (zeroExtend 4 x_1 + zeroExtend 4 x) >>> 2#4 = zeroExtend 4 (ofBool (x_1 ^^^ -1#2 <ᵤ x))

theorem test9_proof : test9_before ⊑ test9_after

@[grind =, simp]
lemma createSink_states [LawfulBEq A] {m : RawCNFA A} : m.createSink.2.states = m.states ∪ {m.stateMax}

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

@[simp]
theorem syncMap2_syncMap2_eq_syncMap3 (f : α → β → γ) (g : γ → ε → φ)
    (as : Stream α) (bs : Stream β) (es : Stream ε) :
    syncMap₂ g (syncMap₂ f as bs) es = syncMap₃ (fun a b e => g (f a b) e) as bs es

theorem slt_zero_ult_i1_fail1_proof : slt_zero_ult_i1_fail1_before ⊑ slt_zero_ult_i1_fail1_after

theorem scalar_i8_shl_uge_const_proof : scalar_i8_shl_uge_const_before ⊑ scalar_i8_shl_uge_const_after

theorem sgt_swap_and_not_min_logical_proof : sgt_swap_and_not_min_logical_before ⊑ sgt_swap_and_not_min_logical_after

theorem ashr_lshr_shift_amt_mismatch_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (0#32 ≤ₛ x_2) = 1#1 → ¬x ≥ ↑32 → ¬ofBool (x_2 <ₛ 0#32) = 1#1 → x_1 ≥ ↑32 → False

theorem test22_proof : test22_before ⊑ test22_after

theorem lshr_not_nneg2_proof : lshr_not_nneg2_before ⊑ lshr_not_nneg2_after

theorem sge_smin1_proof : sge_smin1_before ⊑ sge_smin1_after

theorem narrow_sext_or_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 16),
  truncate 16 (signExtend 32 x_1 ||| x) = x_1 ||

theorem t7_ashr_thm (e e_1 : IntW 32) :
  ashr (ashr e_1 (sub (const? 32 32) e) { «exact» := true }) (add e (const? 32 (-2))) ⊑ ashr e_1 (const? 32 30)

theorem ashr_slt_exact_near_pow2_cmpval_proof : ashr_slt_exact_near_pow2_cmpval_before ⊑ ashr_slt_exact_near_pow2_cmpval_after

theorem icmp_ugt_proof : icmp_ugt_before ⊑ icmp_ugt_after

theorem test8_thm.extracted_1._1 : ∀ (x : BitVec 128),
  ¬(127#128 ≥ ↑128 ∨ 120#128 ≥ ↑128 ∨ 127#128 ≥ ↑128) →
    (x ^^^ (1#128 <<< 127#128).sshiftRight' 120#128) + 1#128 <<< 127#128 =
      x ^^^ 170141183460469231731687303715884105600#128

@[simp]
theorem flipAccept_eval {M : NFA α σ} : M.flipAccept.eval w = M.eval w

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

theorem exact_lshr_ne_both_equal_thm (e : IntW 8) :
  icmp IntPred.ne (lshr (const? 8 126) e { «exact» := true }) (const? 8 126) ⊑
    icmp IntPred.ne e (const? 8 0)

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

include hinj in
lemma product.prodArray_spec_full :
    (product.prodArray f hm₁ hm₂).toList.Nodup ∧
    ∀ s₁ s₂, f s₁ s₂ ∈ product.prodArray f hm₁ hm₂ ↔ (s₁.val ∈ m₁ ∧ s₂.val ∈ m₂)

theorem bools_logical_commute0_proof : bools_logical_commute0_before ⊑ bools_logical_commute0_after

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

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

theorem main11_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 64#32 == 0#32) = 1#1 → ofBool (x &&& 192#32 == 192#32) = 1#1 → True → 2#32 = 1#32

theorem icmp_ne_and_pow2_shl_pow2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → zeroExtend 32 (ofBool (2#32 <<< x &&& 16#32 != 0#32)) = zeroExtend 32 (ofBool (x == 3#32))

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

theorem e_53 :
     - 7 * (x ^^^ y) + 2 * (x |||  ~~~y) - 2 *  ~~~(x ||| y) + 8 *  ~~~(x |||  ~~~y) - 1 * (x &&& y) = 1 * y - 5 * (x &&&  ~~~y)

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

theorem and_or3_commuted_thm.extracted_1._5 : ∀ (x x_1 : BitVec 1) (x_2 x_3 : BitVec 32),
  ofBool (x_3 == x_2) &&& x_1 = 1#1 → ¬x_1 = 1#1 → x = 0#1

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

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

theorem ashrslt_01_10_exact_proof : ashrslt_01_10_exact_before ⊑ ashrslt_01_10_exact_after

theorem ashrslt_01_14_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 (-2)) = ofBool (x <ₛ BitVec.ofInt 4 (-4))

theorem test35_proof : test35_before ⊑ test35_after

theorem negate_zext_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 8),
  x_1 - zeroExtend 8 x = x_1 + signExtend 8 x

theorem ashr_ugt_13_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬1#4 ≥ ↑4 → ofBool (BitVec.ofInt 4 (-3) <ᵤ x.sshiftRight' 1#4) = ofBool (BitVec.ofInt 4 (-5) <ᵤ x)

theorem or_nosignbit_select_ashr_proof : or_nosignbit_select_ashr_before ⊑ or_nosignbit_select_ashr_after

theorem e_971 :
     - 11 * (z |||  ~~~t) + 4 *  ~~~(z &&&  ~~~t) + 2 * z - 5 *  ~~~t + 12 *  ~~~(z ||| t) - 4 *  ~~~(z |||  ~~~t) + 14 * (z &&&  ~~~t) =  - 5 * (z &&& t)

theorem test4_proof : test4_before ⊑ test4_after

theorem test20_proof : test20_before ⊑ test20_after

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

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 or_eq_notY_eq_0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 ||| x ^^^ -1#8 == x ^^^ -1#8) = ofBool (x_1 &&& x == 0#8)

theorem bad_shl2_sub_i32_thm (e : IntW 32) :
  shl (const? 32 1) (sub e (const? 32 31)) ⊑
    shl (const? 32 1) (add e (const? 32 (-31))) { «nsw» := false, «nuw» := true }

theorem no_shift_no_xor_multiuse_cmp_proof : no_shift_no_xor_multiuse_cmp_before ⊑ no_shift_no_xor_multiuse_cmp_after

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

theorem e_1687 :
    1 *  ~~~(a &&&  ~~~c) - 1 * (c ||| (a &&&  ~~~b)) + 5 *  ~~~(b ||| c) + 3 * (b |||  ~~~(a ||| c)) - 2 *  ~~~b - 2 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) - 1 *  ~~~(a &&& b) + 1 * ((a ^^^ b) ||| (a ^^^ c)) - 3 * ((a &&& c) ^^^ (b ||| c)) - 2 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 5 *  ~~~(a |||  ~~~c) + 4 * (c ^^^  ~~~(a &&& b)) + 3 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) + 1 * (a &&&  ~~~c) + 1 * ( ~~~c &&& (a ^^^ b)) - 5 *  ~~~(a ||| b) - 11 * c + 1 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 2 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 2 * a - 14 *  ~~~(a ||| (b ||| c)) - 13 *  ~~~(a ||| ( ~~~b ||| c)) - 18 *  ~~~( ~~~a ||| (b ||| c)) - 12 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 23 * ( ~~~a &&& ( ~~~b &&& c)) + 17 * ( ~~~a &&& (b &&& c)) + 3 * (a &&& ( ~~~b &&& c)) - 6 * (a &&& (b &&& c)) =  - 11 * (a |||  ~~~c)

theorem test3_proof : test3_before ⊑ test3_after

theorem n5_thm (e e_1 e_2 : IntW 8) :
  select (icmp IntPred.eq (LLVM.and e_2 (const? 8 1)) (const? 8 2)) e_1 e ⊑ e

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

theorem test_eq1_proof : test_eq1_before ⊑ test_eq1_after

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

theorem ne_smin2_proof : ne_smin2_before ⊑ ne_smin2_after

theorem ult_or_not_max_commute_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.ne e_1 (const? 8 (-1))) (const? 1 1) (icmp IntPred.ult e_1 e) ⊑
    icmp IntPred.ne e_1 (const? 8 (-1))

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

theorem 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 andcond_proof : andcond_before ⊑ andcond_after

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

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 and_or1_commuted_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1), x_1 ||

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

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

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

theorem and_logic_and_logic_or_8_proof : and_logic_and_logic_or_8_before ⊑ and_logic_and_logic_or_8_after

theorem select_or_icmp_bad_proof : select_or_icmp_bad_before ⊑ select_or_icmp_bad_after

theorem ashr_16_add_zext_basic_proof : ashr_16_add_zext_basic_before ⊑ ashr_16_add_zext_basic_after

theorem narrow_zext_ashr_keep_trunc3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ (signExtend 64 x_1).saddOverflow (signExtend 64 x) = true ∨ 1#64 ≥ ↑64) →
    True ∧ (zeroExtend 14 x_1).saddOverflow (zeroExtend 14 x) = true ∨
        True ∧ (zeroExtend 14 x_1).uaddOverflow (zeroExtend 14 x) = true ∨ 1#14 ≥ ↑14 →
      False

theorem arbitrary_mask_sub_i8_proof : arbitrary_mask_sub_i8_before ⊑ arbitrary_mask_sub_i8_after

theorem icmp_eq_zext_ne_non_boolean_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (zeroExtend 32 (ofBool (x != 2#32)) == x) = ofBool (x == 1#32)

theorem ashrslt_03_11_exact_proof : ashrslt_03_11_exact_before ⊑ ashrslt_03_11_exact_after

theorem test65_proof : test65_before ⊑ test65_after

theorem orn_and_cmp_1_logical_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 x_2 : BitVec 37),
  ¬ofBool (x_2 ≤ₛ x_1) = 1#1 → x = 1#1 → ofBool (x_1 <ₛ x_2) = x

theorem p0_proof : p0_before ⊑ p0_after

theorem no_shift_xor_multiuse_cmp_or_proof : no_shift_xor_multiuse_cmp_or_before ⊑ no_shift_xor_multiuse_cmp_or_after

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

theorem or_eq_with_diff_one_logical_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x == 13#8) = 1#1 → 1#1 = ofBool (x + BitVec.ofInt 8 (-13) <ᵤ 2#8)

theorem not_mul_of_bool_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  True ∧ (x_1 &&& 3#32).smulOverflow (zeroExtend 32 x) = true ∨
      True ∧ (x_1 &&& 3#32).umulOverflow (zeroExtend 32 x) = true →
    False

theorem src_x_and_nmask_eq_thm.extracted_1._7 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → ¬x_2 ^^^ 1#1 = 1#1 → True ∧ ((-1#8) <<< x_1).sshiftRight' x_1 ≠ -1#8 ∨ x_1 ≥ ↑8 → False

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

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

theorem narrow_sext_xor_proof : narrow_sext_xor_before ⊑ narrow_sext_xor_after

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

theorem select_bittest_to_add_proof : select_bittest_to_add_before ⊑ select_bittest_to_add_after

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

theorem test3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(31#32 ≥ ↑32 ∨ 31#32 ≥ ↑32) →
    zeroExtend 32 (ofBool (x_1 >>> 31#32 == x >>> 31#32)) = zeroExtend 32 (ofBool (-1#32 <ₛ x_1 ^^^ x))

theorem and_not_or_commute2_proof : and_not_or_commute2_before ⊑ and_not_or_commute2_after

theorem in_constant_6_vary_invmask_proof : in_constant_6_vary_invmask_before ⊑ in_constant_6_vary_invmask_after

theorem Factor.denote_eq_toNat_reflect {w : Nat} (xs : Env w) (f : Factor) :
  f.denote xs = (f.reflect xs |>.toNat)

theorem test87_proof : test87_before ⊑ test87_after

theorem uge_umin4_proof : uge_umin4_before ⊑ uge_umin4_after

theorem sext_sext_ne_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (signExtend 32 x_1 != signExtend 32 x) = ofBool (x_1 != x)

theorem shl_lshr_demand1_thm (e : IntW 8) :
  LLVM.or (lshr (shl (const? 8 40) e) (const? 8 3)) (const? 8 (-32)) ⊑
    LLVM.or (shl (const? 8 5) e) (const? 8 (-32))

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

theorem lshr_shl_demand1_thm (e : IntW 8) :
  LLVM.or (shl (lshr (const? 8 28) e) (const? 8 3)) (const? 8 7) ⊑
    LLVM.or (lshr (const? 8 (-32)) e) (const? 8 7)

theorem t4_commutative_proof : t4_commutative_before ⊑ t4_commutative_after

theorem zext_zext_sgt_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (zeroExtend 32 x <ₛ zeroExtend 32 x_1) = ofBool (x <ᵤ x_1)

theorem e_2002 :
    4 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 5 * (e ||| (d ^^^ f)) + 1 *  ~~~(d &&& ( ~~~e &&& f)) - 6 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 11 * f - 11 * ( ~~~e &&& (d ^^^ f)) - 3 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 7 *  ~~~(d &&&  ~~~d) + 7 * (d ^^^ e) + 11 *  ~~~(e ||| f) + 1 * (e &&&  ~~~(d &&& f)) - 7 * (e &&&  ~~~f) + 11 *  ~~~(d &&& ( ~~~e ||| f)) - 2 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * (e ^^^ (d ||| ( ~~~e ||| f))) - 5 * (f ^^^ (d &&& ( ~~~e ||| f))) + 7 * (e ^^^ f) - 1 * (d ||| e) - 7 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 5 * (d ||| (e &&& f)) + 1 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 3 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 1 * ( ~~~d ||| ( ~~~e ||| f)) + 3 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) - 5 * (d &&& ( ~~~e ||| f)) + 2 * (d ^^^ (e ^^^ f)) - 22 *  ~~~(d ||| (e ||| f)) - 13 *  ~~~(d ||| ( ~~~e ||| f)) + 17 *  ~~~( ~~~d ||| (e ||| f)) - 6 * ( ~~~d &&& ( ~~~e &&& f)) - 13 * ( ~~~d &&& (e &&& f)) - 5 * (d &&& ( ~~~e &&& f)) = 7 * (d &&& (e &&& f)) + 4 *  ~~~( ~~~d ||| ( ~~~e ||| f))

theorem t0_proof : t0_before ⊑ t0_after

theorem xor_orn_commute1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ¬(x_1 = 0 ∨ x_1 = 0) → x_1 = 0 → False

theorem sub_eq (a b : BitStream) : a.sub b = a - b

theorem not_ashr_const_proof : not_ashr_const_before ⊑ not_ashr_const_after

theorem e_2400 :
     - 1 * (d ^^^ e) - 1 * f - 11 * (e ^^^ (d &&& f)) - 6 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 5 *  ~~~( ~~~d ||| (e &&& f)) + 5 * (f ||| (d ^^^ e)) - 11 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 2 * (f &&&  ~~~(d ^^^ e)) - 3 *  ~~~(d &&& ( ~~~e ||| f)) - 11 * ( ~~~d &&& (e ||| f)) - 1 * (f ^^^  ~~~(d &&& (e &&& f))) - 3 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 7 * (e ^^^ (d &&&  ~~~f)) + 1 * ( ~~~f &&&  ~~~(d ^^^ e)) + 4 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 2 *  ~~~(d ^^^ (e ||| f)) - 2 * (e ^^^  ~~~(d &&&  ~~~f)) + 3 * (f &&& (d ^^^ e)) + 1 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 3 *  ~~~(d ||| f) + 1 * ( ~~~e &&&  ~~~(d ^^^ f)) + 2 * ((d |||  ~~~e) &&& (e ^^^ f)) - 6 * (f &&& (d |||  ~~~e)) + 2 * (e ^^^ (d ||| f)) + 1 * (e ||| (d &&& f)) + 2 * (e ^^^ (d &&& (e ||| f))) + 5 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 1 * (e ^^^ ( ~~~d ||| (e ||| f))) - 5 * (e ^^^ (d ||| (e &&& f))) + 2 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 3 * (d |||  ~~~e) + 5 * (e &&&  ~~~(d &&&  ~~~f)) - 6 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 2 *  ~~~f + 3 * (e &&& (d ||| f)) - 7 * ( ~~~d ||| (e ^^^ f)) + 7 * ( ~~~d ||| (e &&& f)) - 7 * (d ||| (e &&& f)) + 2 * (d &&& (e ||| f)) + 11 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 11 * (f ^^^  ~~~(d &&&  ~~~e)) + 11 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 1 * (f ^^^  ~~~(d ||| (e &&& f))) + 4 * (f ^^^ (d &&&  ~~~e)) + 2 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 2 * (e ||| f) - 1 * (f &&&  ~~~(d &&&  ~~~e)) - 2 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 1 * ( ~~~d ||| ( ~~~e &&& f)) - 7 * (f ^^^  ~~~(d ||| e)) - 2 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 2 *  ~~~(e |||  ~~~f) + 1 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 4 * (e ^^^ (d &&& ( ~~~e ||| f))) + 3 *  ~~~( ~~~d &&& (e ^^^ f)) + 11 *  ~~~( ~~~d &&& (e ||| f)) - 5 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 2 *  ~~~(d &&& (e ||| f)) - 1 * (e |||  ~~~f) - 1 *  ~~~(d ||| (e &&& f)) - 6 * (f ||| (d &&&  ~~~e)) - 3 *  ~~~(d ^^^ ( ~~~e ||| f)) - 1 * (f |||  ~~~(d ^^^ e)) - 6 *  ~~~(d &&&  ~~~d) + 25 *  ~~~(d ||| (e ||| f)) + 19 *  ~~~(d ||| ( ~~~e ||| f)) + 1 *  ~~~( ~~~d ||| (e ||| f)) + 21 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 29 * ( ~~~d &&& ( ~~~e &&& f)) + 19 * ( ~~~d &&& (e &&& f)) + 39 * (d &&& ( ~~~e &&& f)) - 2 * (d &&& (e &&& f)) =  - 1 * (d &&&  ~~~f)

theorem ne_21_logical_thm (e e_1 : IntW 32) :
  select (icmp IntPred.ne (trunc 8 (lshr e_1 (const? 32 16))) (trunc 8 (lshr e (const? 32 16)))) (const? 1 1)
      (icmp IntPred.ne (trunc 8 (lshr e_1 (const? 32 8))) (trunc 8 (lshr e (const? 32 8)))) ⊑
    icmp IntPred.ne (trunc 16 (lshr e_1 (const? 32 8))) (trunc 16 (lshr e (const? 32 8)))

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

theorem lshrult_03_07_exact_proof : lshrult_03_07_exact_before ⊑ lshrult_03_07_exact_after

theorem shl_sub_lshr_reverse_nsw_on_op1_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ (x_1 <<< x).sshiftRight' x ≠ x_1 ∨
        True ∧ x_1 <<< x >>> x ≠ x_1 ∨
          x ≥ ↑32 ∨
            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).usubOverflow x_1 = true) →
      (x_2 - x_1 <<< x) >>> x = x_2 >>> x - x_1

theorem t10_shift_by_one_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 x_2 : BitVec 32),
  ¬(64#32 - x_1 ≥ ↑32 ∨ zeroExtend 64 (x_1 + BitVec.ofInt 32 (-63)) ≥ ↑64) →
    64#32 - x_1 ≥ ↑32 ∨
        True ∧ (x_1 + BitVec.ofInt 32 (-63)).msb = true ∨ zeroExtend 64 (x_1 + BitVec.ofInt 32 (-63)) ≥ ↑64 →
      False

theorem xor_or_xor_common_op_commute5_proof : xor_or_xor_common_op_commute5_before ⊑ xor_or_xor_common_op_commute5_after

theorem lshrugt_02_04_proof : lshrugt_02_04_before ⊑ lshrugt_02_04_after

theorem test2_proof : test2_before ⊑ test2_after

theorem ashr_ule_exact_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x >>> 3#8 <<< 3#8 ≠ x ∨ 3#8 ≥ ↑8) → ofBool (x.sshiftRight' 3#8 ≤ᵤ 10#8) = ofBool (x <ᵤ 88#8)

theorem lshr_pow2_sgt_proof : lshr_pow2_sgt_before ⊑ lshr_pow2_sgt_after

theorem negate_lowbitmask_proof : negate_lowbitmask_before ⊑ negate_lowbitmask_after

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

theorem ashrsgt_01_13_proof : ashrsgt_01_13_before ⊑ ashrsgt_01_13_after

theorem test10_proof : test10_before ⊑ test10_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 select_xor_icmp_bad_6_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 != 1#32) = 1#1 → ofBool (x_1 == 1#32) = 1#1 → False

theorem t6_shl_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1 <<< (32#32 - x) >>> (32#32 - x) ≠ x_1 ∨
        32#32 - x ≥ ↑32 ∨
          True ∧
              (x_1 <<< (32#32 - x) <<< (x + BitVec.ofInt 32 (-2))).sshiftRight' (x + BitVec.ofInt 32 (-2)) ≠
                x_1 <<< (32#32 - x) ∨
            x + BitVec.ofInt 32 (-2) ≥ ↑32) →
    30#32 ≥ ↑32 → False

theorem ult_2_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (truncate 8 x <ᵤ 2#8) = ofBool (x &&& 254#32 == 0#32)

theorem uaddo_commute3_proof : uaddo_commute3_before ⊑ uaddo_commute3_after

theorem sgt_and_min_proof : sgt_and_min_before ⊑ sgt_and_min_after

theorem main12_proof : main12_before ⊑ main12_after

theorem not_shl_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬7#8 ≥ ↑8 → x <<< 7#8 ^^^ BitVec.ofInt 8 (-128) = (x ^^^ -1#8) <<< 7#8

theorem canonicalize_logic_first_and0_thm (e : IntW 8) :
  LLVM.and (add e (const? 8 48)) (const? 8 (-10)) ⊑ add (LLVM.and e (const? 8 (-10))) (const? 8 48)

theorem ult_or_not_max_commute_proof : ult_or_not_max_commute_before ⊑ ult_or_not_max_commute_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_7b_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_7b_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_7b_logical_after

theorem bools_logical_commute3_and2_proof : bools_logical_commute3_and2_before ⊑ bools_logical_commute3_and2_after

theorem multiuse_lshr_lshr_thm.extracted_1._1 : ∀ (x : BitVec 9),
  ¬(2#9 ≥ ↑9 ∨ 2#9 ≥ ↑9 ∨ 3#9 ≥ ↑9) → 2#9 ≥ ↑9 ∨ 5#9 ≥ ↑9 → False

theorem main5e_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 →
      ofBool (x_2 &&& x == x_2) = 1#1 → 0#32 = zeroExtend 32 (ofBool (x_2 &&& x != x_2))

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

theorem reassoc_x2_mul_nuw_thm (e e_1 : IntW 32) :
  mul (mul e_1 (const? 32 5) { «nsw» := false, «nuw» := true }) (mul e (const? 32 9) { «nsw» := false, «nuw» := true })
      { «nsw» := false, «nuw» := true } ⊑
    mul (mul e_1 e) (const? 32 45) { «nsw» := false, «nuw» := true }

theorem select_icmp_sgt_allones_smin_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬ofBool (-1#8 <ₛ x) = 1#1 → x ^^^ BitVec.ofInt 8 (-128) = x &&& 127#8

theorem positive_samevar_shlnuw_proof : positive_samevar_shlnuw_before ⊑ positive_samevar_shlnuw_after

theorem sgt_swap_or_not_min_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 != BitVec.ofInt 8 (-128)) ||

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

theorem shl_mul_mask_proof : shl_mul_mask_before ⊑ shl_mul_mask_after

theorem e_408 :
     - 11 *  ~~~(x ^^^ y) - 5 *  ~~~(x &&&  ~~~y) + 7 * (x ||| y) + 5 * (x |||  ~~~y) + 18 *  ~~~(x ||| y) + 5 *  ~~~(x |||  ~~~y) - 5 * (x &&&  ~~~y) + 4 * (x &&& y) = 7 *  ~~~(x &&& y)

theorem a_thm (e : IntW 32) :
  LLVM.and (LLVM.srem e (const? 32 8)) (const? 32 1) ⊑ LLVM.and e (const? 32 1)

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_after

theorem masked_or_A_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 14#32 == x) = 1#1 → 1#1 = ofBool (x &&& BitVec.ofInt 32 (-79) == 0#32)

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

theorem n3_proof : n3_before ⊑ n3_after

theorem shl_ashr_pow2_const_case1_proof : shl_ashr_pow2_const_case1_before ⊑ shl_ashr_pow2_const_case1_after

theorem uadd_sat_flipped_wrong_bounds6_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x ≤ᵤ BitVec.ofInt 32 (-12)) = 1#1 → ofBool (x <ᵤ BitVec.ofInt 32 (-11)) = 1#1 → -1#32 = x + 9#32

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

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

theorem test11_proof : test11_before ⊑ test11_after

theorem sel_false_val_is_a_masked_ashr_of_true_val2_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬2#32 ≥ ↑32 →
    ¬ofBool ((x_1 &&& BitVec.ofInt 32 (-2147483588)).sshiftRight' 2#32 == 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 src_is_mask_zext_thm (e : IntW 8) (e_1 : IntW 16) :
  icmp IntPred.eq (LLVM.and (LLVM.xor e_1 (const? 16 123)) (zext 16 (lshr (const? 8 (-1)) e)))
      (LLVM.xor e_1 (const? 16 123)) ⊑
    icmp IntPred.ule (LLVM.xor e_1 (const? 16 123)) (zext 16 (lshr (const? 8 (-1)) e))

@[simp] theorem eval_shiftLeft_of_lt {x : BitStream} {k : Nat} (hi : i < k) :
  (shiftLeft x k) i = false

theorem shl_or_disjoint_lshr_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ x_2 <<< x_1 >>> x_1 ≠ x_2 ∨ x_1 ≥ ↑32 ∨ True ∧ (x_2 <<< x_1 &&& x != 0) = true ∨ x_1 ≥ ↑32) →
    ¬(x_1 ≥ ↑32 ∨ True ∧ (x >>> x_1 &&& x_2 != 0) = true) → (x_2 <<< x_1 ||| x) >>> x_1 = x >>> x_1 ||

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

theorem select_add_icmp_bad_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 == 1#32) = 1#1 → x_2 + x_1 = x_1 + 1#32

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

theorem same_source_matching_signbits_thm (e : IntW 32) :
  sext 32 (trunc 8 (shl (const? 32 (-1)) (LLVM.and e (const? 32 7)) { «nsw» := true, «nuw» := false })) ⊑
    shl (const? 32 (-1)) (LLVM.and e (const? 32 7)) { «nsw» := true, «nuw» := false }

theorem not_xor_to_or_not3_proof : not_xor_to_or_not3_before ⊑ not_xor_to_or_not3_after

theorem test3_proof : test3_before ⊑ test3_after

@[grind =, simp, aesop 50% unsafe]
lemma states_addFinal (m : RawCNFA A) (s' : State) :
    (m.addFinal s').states = m.states

theorem t11_shl_nsw_flag_preservation_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (x_1 <<< (32#32 - x)).sshiftRight' (32#32 - x) ≠ x_1 ∨
        32#32 - x ≥ ↑32 ∨
          True ∧
              (x_1 <<< (32#32 - x) <<< (x + BitVec.ofInt 32 (-2))).sshiftRight' (x + BitVec.ofInt 32 (-2)) ≠
                x_1 <<< (32#32 - x) ∨
            True ∧
                x_1 <<< (32#32 - x) <<< (x + BitVec.ofInt 32 (-2)) >>> (x + BitVec.ofInt 32 (-2)) ≠
                  x_1 <<< (32#32 - x) ∨
              x + BitVec.ofInt 32 (-2) ≥ ↑32) →
    ¬(True ∧ (x_1 <<< 30#32).sshiftRight' 30#32 ≠ x_1 ∨ 30#32 ≥ ↑32) →
      x_1 <<< (32#32 - x) <<< (x + BitVec.ofInt 32 (-2)) = x_1 <<< 30#32

theorem bools_multi_uses1_logical_proof : bools_multi_uses1_logical_before ⊑ bools_multi_uses1_logical_after

theorem invert_both_cmp_operands_sub_proof : invert_both_cmp_operands_sub_before ⊑ invert_both_cmp_operands_sub_after

theorem pv_proof : pv_before ⊑ pv_after

theorem or_eq_and_not_add :
    x ||

theorem eq_umin3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 + 3#32 <ᵤ x) = 1#1 → ofBool (x_1 + 3#32 == x_1 + 3#32) = ofBool (x_1 + 3#32 ≤ᵤ x)

theorem neg_signbit_thm (e : IntW 8) :
  sub (const? 32 0) (zext 32 (lshr e (const? 8 7))) ⊑ sext 32 (ashr e (const? 8 7))

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

theorem gt_signed_to_small_negative_proof : gt_signed_to_small_negative_before ⊑ gt_signed_to_small_negative_after

theorem i_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬((BitVec.ofInt 8 (-3) == 0 || 8 != 1 && x == intMin 8 && BitVec.ofInt 8 (-3) == -1) = true ∨
        (BitVec.ofInt 8 (-3) == 0 || 8 != 1 && x.sdiv (BitVec.ofInt 8 (-3)) == intMin 8 && BitVec.ofInt 8 (-3) == -1) =
          true) →
    (9#8 == 0 || 8 != 1 && x == intMin 8 && 9#8 == -1) = true → False

theorem e_2331 :
     - 1 * ((d &&& e) |||  ~~~(e ||| f)) - 7 *  ~~~(d |||  ~~~f) - 7 * ( ~~~e &&&  ~~~(d ^^^ f)) + 1 * (e |||  ~~~(d ||| f)) + 4 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 1 *  ~~~f + 1 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 1 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 3 * (f ^^^ (d ||| (e &&& f))) + 3 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 1 *  ~~~(d &&& (e &&& f)) - 2 * (e &&& (d |||  ~~~f)) - 1 * ((d ^^^ e) ||| (d ^^^ f)) - 2 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 2 * (e |||  ~~~f) + 3 * (e ^^^ (d &&& (e ^^^ f))) - 2 * (e ||| (d ^^^ f)) - 2 * (e ^^^ (d |||  ~~~f)) - 1 * (e ^^^ (d &&&  ~~~f)) - 5 * (e ^^^ ( ~~~d ||| (e &&& f))) + 2 * ( ~~~d &&& (e ^^^ f)) - 5 *  ~~~(d &&& ( ~~~e &&& f)) - 7 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 11 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 2 *  ~~~( ~~~d &&& (e ^^^ f)) - 3 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) - 6 *  ~~~(d ^^^ ( ~~~e ||| f)) + 5 * (f ^^^ (d ||| ( ~~~e &&& f))) - 6 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 11 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 3 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 3 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 1 * (f ^^^  ~~~(d &&& (e ||| f))) + 2 * (f ^^^ (d &&& e)) + 2 * (d |||  ~~~f) - 1 * (e ||| (d &&&  ~~~f)) + 1 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 5 *  ~~~(d ^^^ ( ~~~e &&& f)) - 6 *  ~~~( ~~~d &&& (e ||| f)) + 7 *  ~~~( ~~~d &&& (e &&& f)) + 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 7 *  ~~~(e |||  ~~~f) + 1 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * ( ~~~d ||| (e &&& f)) - 2 * ((d &&& f) ^^^ (e ||| f)) + 11 * (f ^^^  ~~~(d &&& (e &&& f))) + 1 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 11 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) - 6 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 7 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 1 * (f ^^^  ~~~(d ||| (e &&& f))) + 1 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 3 *  ~~~(d ||| e) - 6 * f + 1 * (e ^^^  ~~~(d ||| f)) - 5 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 11 * e + 18 *  ~~~(d ||| (e ||| f)) + 34 *  ~~~(d ||| ( ~~~e ||| f)) + 10 *  ~~~( ~~~d ||| (e ||| f)) + 8 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 31 * ( ~~~d &&& ( ~~~e &&& f)) + 24 * ( ~~~d &&& (e &&& f)) + 26 * (d &&& ( ~~~e &&& f)) + 12 * (d &&& (e &&& f)) =  - 4 * (e ^^^  ~~~(d &&& f))

theorem a_false_implies_b_false2_comm_thm.extracted_1._6 : ∀ (x x_1 : BitVec 1) (x_2 : BitVec 8),
  ofBool (20#8 <ᵤ x_2) = 1#1 → ¬ofBool (10#8 <ᵤ x_2) = 1#1 → x_1 ||

theorem not_not_true_proof : not_not_true_before ⊑ not_not_true_after

theorem nodup_vars [DecidableEq α] (c : Circuit α) : c.vars.Nodup

theorem test6_proof : test6_before ⊑ test6_after

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

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

theorem test24_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (1#32 <ₛ x) &&& ofBool (x != 2#32) = ofBool (2#32 <ₛ x)

theorem e_1388 :
     - 3 * (z ||| t) + 2 * (z ^^^ t) + 3 * t - 2 *  ~~~(z ^^^ t) + 4 *  ~~~(z &&&  ~~~z) + 11 *  ~~~t + 1 * z + 1 * (z |||  ~~~t) - 6 *  ~~~(z |||  ~~~t) - 16 * (z &&&  ~~~t) = 4 * (z &&& t) + 14 *  ~~~(z ||| t)

theorem test1_proof : test1_before ⊑ test1_after

theorem test6_proof : test6_before ⊑ test6_after

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

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

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

theorem PR60818_eq_proof : PR60818_eq_before ⊑ PR60818_eq_after

theorem add_select_sext_proof : add_select_sext_before ⊑ add_select_sext_after

theorem shl_or_commuted_proof : shl_or_commuted_before ⊑ shl_or_commuted_after

theorem lshr_and_xor_proof : lshr_and_xor_before ⊑ lshr_and_xor_after

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 or_eq_with_diff_one_logical_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬ofBool (x == 13#8) = 1#1 → ofBool (x == 14#8) = ofBool (x + BitVec.ofInt 8 (-13) <ᵤ 2#8)

theorem test46_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬8#32 ≥ ↑32 → 8#32 ≥ ↑32 ∨ True ∧ (truncate 32 x <<< 8#32 &&& 10752#32).msb = true → False

theorem mul_select_sext_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → 1#64 * signExtend 64 x = 0#64

theorem eq_signed_to_small_unsigned_thm (e : IntW 8) :
  icmp IntPred.eq (sext 32 e) (const? 32 17) ⊑ icmp IntPred.eq e (const? 8 17)

theorem test16_thm (e : IntW 32) : icmp IntPred.eq (LLVM.and e (const? 32 5)) (const? 32 8) ⊑ const? 1 0

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

theorem fold_add_udiv_urem_to_mul_proof : fold_add_udiv_urem_to_mul_before ⊑ fold_add_udiv_urem_to_mul_after

theorem test2_proof : test2_before ⊑ test2_after

theorem sle_or_min_commute_proof : sle_or_min_commute_before ⊑ sle_or_min_commute_after

theorem bitwise_or_logical_or_icmps_comm3_thm.extracted_1._8 : ∀ (x x_1 x_2 : BitVec 8),
  ¬x_1 ≥ ↑8 →
    ¬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_2 &&& 1#8 <<< x_1 == 0#8) ||

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

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

theorem p0_ult_65536_proof : p0_ult_65536_before ⊑ p0_ult_65536_after

theorem trunc_ashr_trunc_proof : trunc_ashr_trunc_before ⊑ trunc_ashr_trunc_after

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

theorem bitwise_and_logical_and_masked_icmp_allones_poison1_proof : bitwise_and_logical_and_masked_icmp_allones_poison1_before ⊑ bitwise_and_logical_and_masked_icmp_allones_poison1_after

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

theorem andn_or_cmp_1_logical_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 37),
  ofBool (x_2 ≤ₛ x_1) = 1#1 → ¬ofBool (42#37 <ᵤ x) = 1#1 → ofBool (x_1 <ₛ x_2) = ofBool (42#37 <ᵤ x)

theorem sgt_swap_and_not_min_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 <ₛ x) = 1#1 → ofBool (x != BitVec.ofInt 8 (-128)) = ofBool (x_1 <ₛ x)

theorem e_120 :
    1 *  ~~~x - 11 * (x ||| y) - 7 * (x |||  ~~~y) + 6 *  ~~~(x ||| y) + 10 *  ~~~(x |||  ~~~y) + 18 * (x &&&  ~~~y) =  - 18 * (x &&& y)

theorem decideIfZeroAux_wf {α : Type _} [Fintype α] [DecidableEq α]
    {c c' : Circuit α} (h : ¬c' ≤ c) : card_compl (c' ||| c) < card_compl c

theorem sdiv_mul_shl_nsw_exact_commute1_thm (e e_1 e_2 : IntW 5) :
  LLVM.sdiv (mul e_2 e_1 { «nsw» := true, «nuw» := false }) (shl e_1 e { «nsw» := true, «nuw» := false })
      { «exact» := true } ⊑
    LLVM.sdiv e_2 (shl (const? 5 1) e { «nsw» := false, «nuw» := true }) { «exact» := true }

theorem test16_proof : test16_before ⊑ test16_after

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_3_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_swapped_3_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_swapped_3_logical_after

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

theorem test3_proof : test3_before ⊑ test3_after

theorem sge_and_max_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.sge e_1 e) (icmp IntPred.eq e_1 (const? 8 127)) (const? 1 0) ⊑
    icmp IntPred.eq e_1 (const? 8 127)

theorem e_1143 :
    7 * t + 7 * (z ||| t) + 1 *  ~~~z + 5 * (z ^^^ t) - 10 *  ~~~(z ||| t) - 27 *  ~~~(z |||  ~~~t) - 21 * (z &&&  ~~~t) - 14 * (z &&& t) =  - 7 *  ~~~(z &&& t) - 2 *  ~~~t

@[simp] theorem Com.changeDialect_rets (f : DialectMorphism d d') (vs) :
    Com.changeDialect f (Com.rets vs : Com d Γ eff t)
    = Com.rets (vs.map' f.mapTy (fun _ v => v.toMap))

theorem icmp_select_var_pred_uge_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == 0#8) = 1#1 → ¬(True ∧ x.uaddOverflow 2#8 = true) → ofBool (x_1 != 0#8) = 1#1 → False

theorem sub_select_sext_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  x_1 = 1#1 → 64#64 - signExtend 64 x_1 = 65#64

theorem canonicalize_logic_first_or0_nswnuw_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.saddOverflow 112#32 = true ∨ True ∧ x.uaddOverflow 112#32 = true) →
    True ∧ (x ||| 15#32).saddOverflow 112#32 = true ∨ True ∧ (x ||| 15#32).uaddOverflow 112#32 = true → False

theorem rem_euclid_non_const_pow2_thm.extracted_1._1 : ∀ (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 →
      ¬(x ≥ ↑8 ∨ (1#8 <<< x == 0 || 8 != 1 && x_1 == intMin 8 && 1#8 <<< x == -1) = true ∨ x ≥ ↑8) →
        True ∧ ((-1#8) <<< x).sshiftRight' x ≠ -1#8 ∨ x ≥ ↑8 → False

@[grind =, simp]
lemma RawCNFA.same_stateMax (m : RawCNFA A) x y (z : Std.HashMap (State × A) (Std.HashSet State)) :
    (RawCNFA.mk m.stateMax x y z).states = m.states

theorem neg_or_lshr_i32_thm (e : IntW 32) :
  lshr (LLVM.or (sub (const? 32 0) e) e) (const? 32 31) ⊑ zext 32 (icmp IntPred.ne e (const? 32 0))

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

theorem test_shl_nuw__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 >>> 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 test22_logical_proof : test22_logical_before ⊑ test22_logical_after

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

theorem lshr_add_and_shl_thm (e e_1 : IntW 32) :
  shl (add e_1 (LLVM.and (lshr e (const? 32 5)) (const? 32 127))) (const? 32 5) ⊑
    add (LLVM.and e (const? 32 4064)) (shl e_1 (const? 32 5))

theorem test_mul_nuw_nsw__none_are_safe_proof : test_mul_nuw_nsw__none_are_safe_before ⊑ test_mul_nuw_nsw__none_are_safe_after

theorem mul_of_bool_no_lz_other_op_thm (e : IntW 8) (e_1 : IntW 32) :
  icmp IntPred.sgt (mul (LLVM.and e_1 (const? 32 1)) (sext 32 e) { «nsw» := true, «nuw» := true })
      (const? 32 127) ⊑
    const? 1 0

theorem ashrslt_03_02_proof : ashrslt_03_02_before ⊑ ashrslt_03_02_after

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

@[simp]
theorem BitVec.intCast_eq_ofInt : ((i : Int) : BitVec w) = BitVec.ofInt w i

theorem no_shift_xor_multiuse_or_proof : no_shift_xor_multiuse_or_before ⊑ no_shift_xor_multiuse_or_after

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

theorem test_sub_nuw_nsw__nsw_is_safe_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x ||| BitVec.ofInt 32 (-2147483648) == BitVec.ofInt 32 (-2147483647)) = 1#1 →
    ¬(True ∧ (BitVec.ofInt 32 (-2147483648)).ssubOverflow (x ||| BitVec.ofInt 32 (-2147483648)) = true ∨
          True ∧ (BitVec.ofInt 32 (-2147483648)).usubOverflow (x ||| BitVec.ofInt 32 (-2147483648)) = true) →
      True ∧ (BitVec.ofInt 32 (-2147483648)).ssubOverflow (x ||| BitVec.ofInt 32 (-2147483648)) = true → False

@[simp, grind=] theorem Hom.comp_apply : f.comp g v = g (f v)

theorem shl_add_add_thm (e e_1 : IntW 8) :
  add (shl e_1 (const? 8 2)) (add (shl e (const? 8 2)) (const? 8 48)) ⊑
    add (shl (add e e_1) (const? 8 2)) (const? 8 48)

theorem udiv_mul_shl_nuw_exact_commute1_thm (e e_1 e_2 : IntW 5) :
  LLVM.udiv (mul e_2 e_1 { «nsw» := false, «nuw» := true }) (shl e_1 e { «nsw» := false, «nuw» := true })
      { «exact» := true } ⊑
    lshr e_2 e { «exact» := true }

theorem test8_proof : test8_before ⊑ test8_after

theorem test8_thm.extracted_1._2 : ∀ (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) →
      truncate 64 (zeroExtend 128 x_1 <<< 32#128 ||| zeroExtend 128 x) =
        zeroExtend 64 x_1 <<< 32#64 ||

theorem test_add_nuw__all_are_safe_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 1073741823#32 == 3#32) = 1#1 →
    ¬(True ∧ (x &&& 1073741823#32).uaddOverflow 1#32 = true) →
      True ∧ (x &&& 1073741823#32).saddOverflow 1#32 = true ∨ True ∧ (x &&& 1073741823#32).uaddOverflow 1#32 = true →
        False

theorem sext_xor_sub_3_proof : sext_xor_sub_3_before ⊑ sext_xor_sub_3_after

theorem lshrult_01_06_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬1#4 ≥ ↑4 → ofBool (x >>> 1#4 <ᵤ 6#4) = ofBool (x <ᵤ BitVec.ofInt 4 (-4))

theorem e_1571 :
    11 *  ~~~(b |||  ~~~c) - 6 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) + 5 * ( ~~~b &&& (a ^^^ c)) + 2 *  ~~~(a ||| ( ~~~b &&& c)) - 2 * (c ^^^ (a ||| (b ||| c))) + 1 * (a ||| (b ^^^ c)) + 1 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) + 7 *  ~~~( ~~~a ||| (b &&& c)) - 6 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) + 9 *  ~~~(a ||| (b ||| c)) - 2 *  ~~~(a ||| ( ~~~b ||| c)) - 8 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 7 * ( ~~~a &&& ( ~~~b &&& c)) + 9 * ( ~~~a &&& (b &&& c)) - 14 * (a &&& ( ~~~b &&& c)) - 1 * (a &&& (b &&& c)) =  - 1 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 *  ~~~( ~~~a ||| (b ||| c))

theorem test_sub_4_Y_ne_4_proof : test_sub_4_Y_ne_4_before ⊑ test_sub_4_Y_ne_4_after

theorem ne_umax1_proof : ne_umax1_before ⊑ ne_umax1_after

theorem test84_thm (e : IntW 32) :
  trunc 8 (lshr (add e (const? 32 (-16777216)) { «nsw» := true, «nuw» := false }) (const? 32 23) { «exact» := true }) ⊑
    trunc 8 (lshr (add e (const? 32 2130706432)) (const? 32 23))

theorem or_logic_or_logic_and_8_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 = 1#1 → ¬x_1 = 1#1 → 0#1 = x_1 ||

theorem bools_multi_uses2_logical_thm.extracted_1._20 : ∀ (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 = x_1 ^^^ x

theorem e_1264 :
    5 *  ~~~(z &&& t) + 1 * z + 7 * (z ^^^ t) - 1 * (z |||  ~~~t) + 3 *  ~~~(z ^^^ t) - 9 *  ~~~(z ||| t) - 16 *  ~~~(z |||  ~~~t) - 16 * (z &&&  ~~~t) - 7 * (z &&& t) =  - 2 *  ~~~(z &&&  ~~~z) - 2 * (z ||| t)

theorem test1_thm.extracted_1._2 : ∀ (x : BitVec 33), ¬4096#33 = 0 → ¬12#33 ≥ ↑33 → x / 4096#33 = x >>> 12#33

theorem PR42691_9_logical_proof : PR42691_9_logical_before ⊑ PR42691_9_logical_after

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

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

theorem main3_logical_proof : main3_logical_before ⊑ main3_logical_after

theorem mul_splat_fold_too_narrow_proof : mul_splat_fold_too_narrow_before ⊑ mul_splat_fold_too_narrow_after

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

theorem icmp_sle9_proof : icmp_sle9_before ⊑ icmp_sle9_after

theorem test71_proof : test71_before ⊑ test71_after

theorem icmp_slt_0_or_icmp_add_1_sge_100_i32_fail_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 →
    x >>> 31#32 ||

theorem main9_thm (e : IntW 32) :
  select
      (LLVM.and (icmp IntPred.ne (LLVM.and e (const? 32 64)) (const? 32 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 192)) (const? 32 192)) (const? 32 2) (const? 32 1)

@[simp] theorem Valuation.cons_map_inj {V : Γ.Valuation} {x y : m ⟦t⟧} :
    (V.cons <$> x) = (V.cons <$> y) ↔ x = y

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

theorem test_shift_and_cmp_changed4_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬5#8 ≥ ↑8 → ofBool (x >>> 5#8 &&& BitVec.ofInt 8 (-64) <ₛ 32#8) = 1#1

theorem ne_umax4_proof : ne_umax4_before ⊑ ne_umax4_after

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

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

theorem urem_c_i32_proof : urem_c_i32_before ⊑ urem_c_i32_after

@[simp]
lemma accepts_cast {M : NFA α σ} (h : σ = ς): (h ▸ M).accepts = M.accepts

theorem test6_proof : test6_before ⊑ test6_after

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

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 scalar_i8_shl_uge_const_proof : scalar_i8_shl_uge_const_before ⊑ scalar_i8_shl_uge_const_after

theorem and_zext_proof : and_zext_before ⊑ and_zext_after

theorem eq_21_comm_eq2_proof : eq_21_comm_eq2_before ⊑ eq_21_comm_eq2_after

theorem lshrugt_02_03_thm.extracted_1._1 : ∀ (x : BitVec 4), ¬2#4 ≥ ↑4 → ofBool (3#4 <ᵤ x >>> 2#4) = 0#1

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

theorem ashrslt_01_02_thm (e : IntW 4) :
  icmp IntPred.slt (ashr e (const? 4 1)) (const? 4 2) ⊑ icmp IntPred.slt e (const? 4 4)

theorem test3_proof : test3_before ⊑ test3_after

theorem vars_or [DecidableEq α] (c₁ c₂ : Circuit α) :
    (vars (c₁ ||| c₂)) ⊆ (vars c₁ ++ vars c₂).dedup

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

theorem or_xor_xor_normal_variant4_thm.extracted_1._1 : ∀ (x x_1 : BitVec 64),
  x_1 &&& x ^^^ x_1 ||

theorem ne_nuw_rem_nz_proof : ne_nuw_rem_nz_before ⊑ ne_nuw_rem_nz_after

theorem test13_logical_thm (e e_1 : IntW 32) :
  select (icmp IntPred.ult e_1 e) (icmp IntPred.ugt e_1 e) (const? 1 0) ⊑ const? 1 0

theorem sub_to_xor_or_commuted_proof : sub_to_xor_or_commuted_before ⊑ sub_to_xor_or_commuted_after

theorem trunc_sel_equal_sext_thm.extracted_1._3 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 →
    ¬(16#32 ≥ ↑32 ∨ True ∧ x <<< 16#32 >>> 16#32 <<< 16#32 ≠ x <<< 16#32 ∨ 16#32 ≥ ↑32) →
      signExtend 32 (truncate 16 x) = (x <<< 16#32).sshiftRight' 16#32

theorem slt_swap_and_not_max_logical_proof : slt_swap_and_not_max_logical_before ⊑ slt_swap_and_not_max_logical_after

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 slt_swap_and_max_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.sgt e_1 e) (icmp IntPred.eq e (const? 8 127)) (const? 1 0) ⊑ const? 1 0

@[bv_multi_width_normalize]
theorem BitVec.msb_eq_twoPow_ule_two_mul_zext (x : BitVec w) :
  x.msb = (BitVec.twoPow (w + 1) w).ule (2 * x.zeroExtend (w + 1))

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

@[grind =, simp, aesop 50% unsafe]
lemma newState_initials (m : RawCNFA A) :
    m.newState.2.initials = m.initials

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

theorem negative_with_wrong_mask_logical_proof : negative_with_wrong_mask_logical_before ⊑ negative_with_wrong_mask_logical_after

theorem positive_samevar_lshrexact_thm (e e_1 : IntW 8) : shl (lshr e_1 e { «exact» := true }) e ⊑ e_1

theorem nonexact_lshr_ne_exactdiv_proof : nonexact_lshr_ne_exactdiv_before ⊑ nonexact_lshr_ne_exactdiv_after

@[simp] theorem Com.returnVars_var :
    returnVars (var (d:=d) (eff:=eff) e body) = body.returnVars

theorem canonicalize_logic_first_and0_nswnuw_thm (e : IntW 8) :
  LLVM.and (add e (const? 8 48) { «nsw» := true, «nuw» := true }) (const? 8 (-10)) ⊑
    add (LLVM.and e (const? 8 (-10))) (const? 8 48) { «nsw» := true, «nuw» := true }

theorem trunc_lshr_sext_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬6#32 ≥ ↑32 → ¬6#8 ≥ ↑8 → truncate 8 (signExtend 32 x >>> 6#32) = x.sshiftRight' 6#8

theorem ashr_lshr_wrong_operands_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sge e_1 (const? 32 0)) (ashr e_1 e) (lshr e_1 e) ⊑
    select (icmp IntPred.slt e_1 (const? 32 0)) (lshr e_1 e) (ashr e_1 e)

theorem e_587 :
     - 6 *  ~~~(x &&&  ~~~x) - 11 *  ~~~x + 11 * x - 11 *  ~~~(x &&&  ~~~y) - 1 * (x ||| y) + 4 * y + 7 * (x ^^^ y) + 28 *  ~~~(x ||| y) + 18 *  ~~~(x |||  ~~~y) - 11 * (x &&&  ~~~y) =  - 3 * (x &&& y)

lemma RawCNFA.autMsbSet_wf : autMsbSet.WF

theorem foo1_or_signbit_lshr_without_shifting_signbit_proof : foo1_or_signbit_lshr_without_shifting_signbit_before ⊑ foo1_or_signbit_lshr_without_shifting_signbit_after

theorem trunc_shl_1_i32_i64_proof : trunc_shl_1_i32_i64_before ⊑ trunc_shl_1_i32_i64_after

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

theorem and_ne_with_diff_one_signed_logical_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬ofBool (x != -1#64) = 1#1 → 0#1 = ofBool (x + -1#64 <ᵤ BitVec.ofInt 64 (-2))

theorem ne_and_lshr_minval_proof : ne_and_lshr_minval_before ⊑ ne_and_lshr_minval_after

theorem not_or_or_and_not_and_and_commute4_proof : not_or_or_and_not_and_and_commute4_before ⊑ not_or_or_and_not_and_and_commute4_after

theorem shl_nsw_ule_Csle0_fail_missing_flag_thm (e e_1 : IntW 8) :
  icmp IntPred.ule (shl e_1 e { «nsw» := true, «nuw» := false }) (const? 8 (-19)) ⊑
    icmp IntPred.ult (shl e_1 e { «nsw» := true, «nuw» := false }) (const? 8 (-18))

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

theorem test22_proof : test22_before ⊑ test22_after

theorem test5_thm (e : IntW 1) : zext 32 (zext 8 e) ⊑ zext 32 e

theorem icmp_sgt8_proof : icmp_sgt8_before ⊑ icmp_sgt8_after

theorem icmp_eq_and1_lshr_pow2_minus_one_thm (e : IntW 32) :
  zext 32 (icmp IntPred.eq (LLVM.and (lshr (const? 32 7) e) (const? 32 1)) (const? 32 0)) ⊑
    zext 32 (icmp IntPred.ugt e (const? 32 2))

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 test0_thm (e : IntW 39) : LLVM.and e (const? 39 0) ⊑ const? 39 0

theorem not_false_not_thm (e e_1 : IntW 1) :
  select (LLVM.xor e_1 (const? 1 1)) (const? 1 0) (LLVM.xor e (const? 1 1)) ⊑
    select e_1 (LLVM.xor e (const? 1 1)) (const? 1 0)

theorem sub_zext_trunc_lshr_proof : sub_zext_trunc_lshr_before ⊑ sub_zext_trunc_lshr_after

theorem negate_select_of_op_vs_negated_op_nsw_xyyx_proof : negate_select_of_op_vs_negated_op_nsw_xyyx_before ⊑ negate_select_of_op_vs_negated_op_nsw_xyyx_after

theorem test20_proof : test20_before ⊑ test20_after

theorem test1_trunc_thm (e : IntW 32) :
  trunc 16 (LLVM.or (lshr e (const? 32 24)) (LLVM.and (lshr e (const? 32 8)) (const? 32 65280))) ⊑
    trunc 16
      (LLVM.or (lshr e (const? 32 24)) (LLVM.and (lshr e (const? 32 8)) (const? 32 65280)) { «disjoint» := true })
      { «nsw» := false, «nuw» := true }

theorem lowbitmask_casted_shift_proof : lowbitmask_casted_shift_before ⊑ lowbitmask_casted_shift_after

theorem tryFactorization_add_nuw_mul_nuw_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ x.umulOverflow 3#32 = true ∨ True ∧ (x * 3#32).uaddOverflow x = true) →
    ¬(True ∧ x <<< 2#32 >>> 2#32 ≠ x ∨ 2#32 ≥ ↑32) → x * 3#32 + x = x <<< 2#32

theorem icmp_ne_sext_slt_allones_nofold_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (x <ₛ -1#32)) != x) = ofBool (x != signExtend 32 (ofBool (x <ₛ -1#32)))

theorem e_152 :
    3 *  ~~~(x &&& y) + 2 *  ~~~(x &&&  ~~~x) + 7 *  ~~~y - 2 * x - 12 *  ~~~(x ||| y) - 10 * (x &&&  ~~~y) = 5 *  ~~~(x |||  ~~~y)

theorem and_signbit_select_lshr_proof : and_signbit_select_lshr_before ⊑ and_signbit_select_lshr_after

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

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

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

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

theorem test8_thm (e : IntW 32) : icmp IntPred.ult e (const? 32 0) ⊑ const? 1 0

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

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

theorem sle_smax1_proof : sle_smax1_before ⊑ sle_smax1_after

theorem lor_lor_right2_thm (e e_1 : IntW 1) :
  select e_1 (const? 1 1) (select e (const? 1 1) e_1) ⊑ select e_1 (const? 1 1) e

theorem and_ugt_to_mask_thm (e : IntW 8) :
  LLVM.and (icmp IntPred.ugt e (const? 8 (-5))) (icmp IntPred.eq (LLVM.and e (const? 8 2)) (const? 8 0)) ⊑
    icmp IntPred.eq (LLVM.and e (const? 8 (-2))) (const? 8 (-4))

theorem sub_shl_same_amount_partial_nsw1_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 6),
  ¬(True ∧ (x_2 <<< x_1).sshiftRight' x_1 ≠ x_2 ∨ x_1 ≥ ↑6 ∨ True ∧ (x <<< x_1).sshiftRight' x_1 ≠ x ∨ x_1 ≥ ↑6) →
    ¬x_1 ≥ ↑6 → x_2 <<< x_1 - x <<< x_1 = (x_2 - x) <<< x_1

theorem test2_gen (x y : BitVec w) : (~~~(x ^^^ y)) = ((x &&& y) + ~~~(x ||| y))

theorem masked_icmps_mask_notallzeros_bmask_mixed_4_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_4_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_4_logical_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 i_proof : i_before ⊑ i_after

theorem add_zero (a : ZMod q) : a + 0 = a

theorem negative_with_nonuniform_bad_mask_logical_proof : negative_with_nonuniform_bad_mask_logical_before ⊑ negative_with_nonuniform_bad_mask_logical_after

@[simp]
theorem mkOutEqZeroCircuitN_eval_eq_false_iff {arity : Type _}
  [DecidableEq arity]
  [Fintype arity]
  [Hashable arity]
  (p : FSM arity) (n : Nat)
  {env : Vars p.α arity (n + 1) → Bool} :
  ((mkOutEqZeroCircuitN p n).eval env = false) ↔
    env (Vars.outputs ⟨n, by omega⟩) = false

theorem ult_and_not_max_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.ult e_1 e) (icmp IntPred.ne e_1 (const? 8 (-1))) (const? 1 0) ⊑
    icmp IntPred.ult e_1 e

theorem ne_umax1_proof : ne_umax1_before ⊑ ne_umax1_after

theorem sub_ashr_or_i32_commute_proof : sub_ashr_or_i32_commute_before ⊑ sub_ashr_or_i32_commute_after

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

theorem e_484 :
     - 1 * y - 3 *  ~~~x - 11 *  ~~~(x ^^^ y) - 1 * (x ||| y) + 2 * (x ^^^ y) + 20 *  ~~~(x ||| y) + 9 *  ~~~(x |||  ~~~y) + 2 * (x &&&  ~~~y) + 10 * (x &&& y) =  - 3 * x + 6 *  ~~~(x &&& y)

theorem pv_thm (e e_1 : IntW 8) :
  icmp IntPred.uge (LLVM.and (lshr (const? 8 (-1)) e_1) e) e ⊑
    icmp IntPred.ule e (lshr (const? 8 (-1)) e_1)

theorem or_xor_tree_0111_proof : or_xor_tree_0111_before ⊑ or_xor_tree_0111_after

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

theorem alive_AddSub_1165 : alive_AddSub_1165_src ⊑ alive_AddSub_1165_tgt

theorem n5_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x_1 &&& 1#8 == 2#8) = 1#1 → False

theorem mul_of_bool_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (255#32 <ᵤ (x_1 &&& 255#32) * (x &&& 1#32)) = 0#1

theorem e_346 :
    11 *  ~~~(x &&&  ~~~x) + 4 * (x |||  ~~~y) - 1 *  ~~~x - 1 * (x ||| y) + 3 * x + 4 * y - 17 * (x &&&  ~~~y) - 21 * (x &&& y) = 14 *  ~~~(x ||| y) + 13 *  ~~~(x |||  ~~~y)

theorem trunc_lshr_zext_exact_proof : trunc_lshr_zext_exact_before ⊑ trunc_lshr_zext_exact_after

theorem test8_thm.extracted_1._2 : ∀ (x : BitVec 27), ¬3#27 ≥ ↑27 → 9#27 * x - x = x <<< 3#27

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

theorem select_icmp_sgt_allones_smin_proof : select_icmp_sgt_allones_smin_before ⊑ select_icmp_sgt_allones_smin_after

theorem e_799 :
     - 1 *  ~~~(z &&&  ~~~t) + 11 * z + 3 *  ~~~t - 12 * (z &&&  ~~~t) - 9 * (z &&& t) = 2 * (z |||  ~~~t) - 1 * t

theorem e_2193 :
     - 5 * (d ||| (e &&& f)) - 6 * ((d &&& f) |||  ~~~(e ||| f)) - 11 *  ~~~(d &&& f) - 7 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 3 * (e &&&  ~~~(d &&&  ~~~f)) - 3 * (f ^^^ (d ||| (e &&& f))) - 3 *  ~~~e + 2 * (d &&& (e ||| f)) + 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 3 * (f &&&  ~~~(d &&& e)) - 1 *  ~~~(d ||| (e &&& f)) + 4 * ( ~~~d &&& (e ||| f)) - 2 * (f |||  ~~~(d ||| e)) - 1 *  ~~~(d ||| ( ~~~e &&& f)) + 7 * (e ^^^  ~~~(d &&&  ~~~f)) + 1 * (e ^^^ (d &&& ( ~~~e ||| f))) + 1 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 4 * (f ^^^ (d |||  ~~~e)) - 3 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 2 *  ~~~f - 7 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 1 * (f ^^^ (d &&&  ~~~e)) + 1 * ( ~~~f |||  ~~~(d ^^^ e)) - 2 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 2 *  ~~~d - 1 * ((d &&& e) ^^^ (e ||| f)) + 4 *  ~~~(d ||| e) + 7 * (f &&& (d ^^^ e)) + 1 * (e |||  ~~~f) - 1 * (d |||  ~~~e) - 2 * ( ~~~f ||| (d ^^^ e)) + 11 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 2 * (e &&&  ~~~(d &&& f)) - 1 * (e ||| f) - 2 * ( ~~~d ||| ( ~~~e &&& f)) - 7 * (d &&& ( ~~~e ||| f)) + 11 *  ~~~(d &&& (e ^^^ f)) - 11 *  ~~~(d &&& (e &&& f)) - 1 * ((d &&& e) ||| (e ^^^ f)) - 5 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 5 *  ~~~(d |||  ~~~e) + 1 * (d ^^^ e) - 11 *  ~~~(d ^^^ e) + 29 *  ~~~(d ||| (e ||| f)) + 22 *  ~~~(d ||| ( ~~~e ||| f)) + 58 *  ~~~( ~~~d ||| (e ||| f)) + 47 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 24 * ( ~~~d &&& ( ~~~e &&& f)) + 29 * ( ~~~d &&& (e &&& f)) + 25 * (d &&& ( ~~~e &&& f)) + 25 * (d &&& (e &&& f)) = 6 * (d ||| ( ~~~e &&& f)) + 3 * (e ^^^ (d ||| (e ^^^ f)))

theorem test_zext3_proof : test_zext3_before ⊑ test_zext3_after

theorem e_707 :
     - 3 *  ~~~y + 11 * x + 2 * (x ^^^ y) + 1 * (x ||| y) - 6 *  ~~~(x &&& y) + 1 * y + 11 *  ~~~(x ||| y) + 4 *  ~~~(x |||  ~~~y) - 3 * (x &&&  ~~~y) - 11 * (x &&& y) = 2 *  ~~~(x &&&  ~~~x)

theorem Term.eval_eq_denote_apply (t : Term) {w : Nat} {vars : List (BitVec w)}
    {i : Nat} (hi : i < w) :
    (t.eval (vars.map BitStream.ofBitVecSext)) i = (t.denote w vars).getLsbD i

theorem e_1916 :
    7 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) - 5 * (b ^^^ (a ||| (b &&& c))) + 1 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 6 * (b &&&  ~~~(a &&& c)) - 7 * (b ^^^ ( ~~~a &&& (b ^^^ c))) - 5 *  ~~~(a ^^^ c) + 1 * (b ^^^ ( ~~~a &&& (b ||| c))) - 3 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) + 1 * (c ^^^  ~~~(a ||| b)) - 6 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 1 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) + 2 *  ~~~( ~~~a &&& (b &&& c)) + 11 * (b ^^^ (a |||  ~~~c)) + 3 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 3 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) + 5 * (c ^^^  ~~~(a &&& b)) - 1 * (c &&& (a ||| b)) + 4 * (a &&& b) + 5 * ( ~~~c |||  ~~~(a ^^^ b)) - 1 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) + 1 * ( ~~~a ||| ( ~~~b ||| c)) + 1 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 1 * (a ||| b) - 2 *  ~~~(a &&& ( ~~~b ||| c)) - 3 * ((a &&&  ~~~b) ||| (b ^^^ c)) + 3 * b + 1 * (a ^^^ (b ||| c)) - 5 *  ~~~(b ^^^ c) - 5 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) + 7 * (b ^^^ (a ||| ( ~~~b &&& c))) + 1 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 2 * (b ^^^  ~~~(a |||  ~~~c)) - 1 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) - 5 *  ~~~a - 2 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 11 * (a |||  ~~~b) - 1 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) + 5 *  ~~~(a &&& c) + 3 *  ~~~(a ||| c) - 11 *  ~~~( ~~~a ||| (b &&& c)) - 1 * (b |||  ~~~c) + 1 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) - 32 *  ~~~(a ||| (b ||| c)) - 13 *  ~~~(a ||| ( ~~~b ||| c)) - 23 *  ~~~( ~~~a ||| (b ||| c)) + 7 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 19 * ( ~~~a &&& ( ~~~b &&& c)) + 1 * ( ~~~a &&& (b &&& c)) - 10 * (a &&& ( ~~~b &&& c)) - 19 * (a &&& (b &&& c)) =  - 4 * (b ^^^ (a &&& (b ^^^ c)))

theorem ashrslt_03_08_exact_proof : ashrslt_03_08_exact_before ⊑ ashrslt_03_08_exact_after

theorem e_1925 :
    7 * (c ^^^  ~~~(a &&&  ~~~b)) + 1 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 3 * ((b &&& c) ||| (a &&& (b ||| c))) + 1 * ( ~~~b ||| (a ^^^ c)) - 1 *  ~~~(a ^^^ ( ~~~b ||| c)) - 3 * (c |||  ~~~(a |||  ~~~b)) + 1 * ( ~~~a ||| ( ~~~b &&& c)) - 7 *  ~~~( ~~~a &&& ( ~~~b ||| c)) - 6 *  ~~~( ~~~a ||| ( ~~~b &&& c)) + 4 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 1 * (c ^^^ ( ~~~a ||| (b ||| c))) + 11 * ( ~~~c |||  ~~~(a ^^^ b)) - 1 * (c ||| (a &&& b)) + 11 * (b ^^^  ~~~(a &&& (b ^^^ c))) - 7 * (a ||| (b ||| c)) + 4 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) + 11 * (b &&& c) + 1 * (a &&& ( ~~~b ||| c)) + 5 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) + 2 * ((a &&& c) ^^^ (b ||| c)) + 7 *  ~~~(a &&& b) + 2 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) + 7 * ((a &&& c) |||  ~~~(b ||| c)) - 5 * ( ~~~a ||| ( ~~~b ||| c)) + 3 * (b ^^^  ~~~(a &&& (b ||| c))) + 7 * b - 6 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) - 6 * ((a &&&  ~~~b) ||| (b ^^^ c)) - 1 * ( ~~~a &&& (b ^^^ c)) + 3 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) + 2 * (b ^^^  ~~~(a &&& (b &&& c))) + 3 *  ~~~c + 1 * ( ~~~c &&&  ~~~(a ^^^ b)) - 3 * ( ~~~a &&& ( ~~~b ||| c)) + 1 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 7 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) + 1 * (a ||| (b &&& c)) - 11 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 7 * (c ^^^ (a &&& b)) - 3 * (c ^^^ (a &&& ( ~~~b ||| c))) - 2 * ( ~~~(a ||| b) |||  ~~~(b ^^^ c)) + 2 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 11 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) - 6 * (a &&& (b ^^^ c)) - 43 *  ~~~(a ||| (b ||| c)) + 5 *  ~~~(a ||| ( ~~~b ||| c)) + 8 *  ~~~( ~~~a ||| (b ||| c)) - 17 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 19 * ( ~~~a &&& ( ~~~b &&& c)) + 6 * ( ~~~a &&& (b &&& c)) - 14 * (a &&& (b &&& c)) = 5 * (c ^^^ ( ~~~a &&& (b ||| c)))

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

theorem canonicalize_logic_first_xor_0_nsw_thm (e : IntW 8) :
  LLVM.xor (add e (const? 8 96) { «nsw» := true, «nuw» := false }) (const? 8 31) ⊑
    add (LLVM.xor e (const? 8 31)) (const? 8 96) { «nsw» := true, «nuw» := false }

theorem c_0_1_0_thm (e e_1 e_2 : IntW 4) :
  LLVM.xor (LLVM.and (LLVM.xor e_2 e_1) (LLVM.xor e (const? 4 (-1)))) e_2 ⊑
    LLVM.xor (LLVM.and (LLVM.xor e_2 e_1) e) e_1

theorem nonexact_ashr_eq_thm (e : IntW 8) :
  icmp IntPred.eq (ashr (const? 8 (-128)) e) (const? 8 (-1)) ⊑ icmp IntPred.eq e (const? 8 7)

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

theorem test11d_proof : test11d_before ⊑ test11d_after

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

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

theorem land_bor_left2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1), x_1 = 1#1 → x ||

theorem XorZextXor_thm.extracted_1._1 : ∀ (x : BitVec 3), zeroExtend 5 (x ^^^ 3#3) ^^^ 12#5 = zeroExtend 5 x ^^^ 15#5

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

@[simp]
theorem Term.toBV_add {wenv : WidthExpr.Env wcard}
    {tctx : Term.Ctx wcard tcard}
    (benv : Term.BoolEnv bcard)
    (tenv : tctx.Env wenv) (a b : Term bcard ncard icard pcard tctx (.bv w)) :
  Term.toBV benv nenv ienv penv tenv (.add a b) = a.toBV benv nenv ienv penv tenv + b.toBV benv nenv ienv penv tenv

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

theorem e_44 :
    2 * (x ||| y) - 1 * y + 11 * (x ^^^ y) - 12 *  ~~~(x |||  ~~~y) - 13 * (x &&&  ~~~y) = 1 * (x &&& y)

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

theorem icmp_mul_nsw_sge_proof : icmp_mul_nsw_sge_before ⊑ icmp_mul_nsw_sge_after

theorem positive_biggershl_shlnuwnsw_proof : positive_biggershl_shlnuwnsw_before ⊑ positive_biggershl_shlnuwnsw_after

theorem e_564 :
    2 * (x |||  ~~~y) + 3 *  ~~~(x &&& y) + 1 * x + 2 * (x ||| y) - 2 * y - 11 *  ~~~(x &&&  ~~~y) + 4 *  ~~~(x |||  ~~~y) - 12 * (x &&&  ~~~y) + 8 * (x &&& y) =  - 6 *  ~~~(x ||| y) - 4 * (x ^^^ y)

theorem e_1517 :
     - 11 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) - 5 * (c ^^^ (a ||| (b &&& c))) + 18 *  ~~~(a ||| (b ||| c)) + 11 *  ~~~(a ||| ( ~~~b ||| c)) + 12 *  ~~~( ~~~a ||| (b ||| c)) + 16 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 12 * ( ~~~a &&& ( ~~~b &&& c)) + 11 * ( ~~~a &&& (b &&& c)) + 7 * (a &&& ( ~~~b &&& c)) + 7 * (a &&& (b &&& c)) = 7 * (b ^^^  ~~~(a &&& (b &&& c)))

theorem lt_unsigned_to_large_signed_proof : lt_unsigned_to_large_signed_before ⊑ lt_unsigned_to_large_signed_after

theorem icmp_ult_8_thm (e : IntW 64) :
  icmp IntPred.ult (shl e (const? 64 8) { «nsw» := false, «nuw» := true }) (const? 64 4095) ⊑
    icmp IntPred.ult e (const? 64 16)

theorem test7_proof : test7_before ⊑ test7_after
</all_available_lemmas>

<local_ctx>
import Mathlib.Data.FinEnum

import Mathlib.Data.Fintype.Card

import Mathlib.Data.Fintype.Sum

import Mathlib.Data.Fintype.Sigma

import Mathlib.Data.Fintype.Pi

import Mathlib.Data.Fintype.BigOperators

import Mathlib.Tactic.Zify

import Mathlib.Tactic.Ring

import Blase.FinEnum

import Blase.Fast.Defs

import Blase.Fast.Circuit

import Blase.Vars

open Sum

section FSM

variable {α β α' β' : Type} {γ : β → Type}

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

open Lean in

open Lean in

open Lean in

open Lean in

namespace FSM

variable {arity : Type} (p : FSM arity)

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 carry (x : arity → BitStream) : ℕ → p.State
  | 0 => p.initCarry
  | n+1 => (p.nextBit (carry x n) (fun i => x i n)).1

def eval (x : arity → BitStream) : BitStream :=
  fun n => (p.nextBit (p.carry x n) (fun i => x i n)).2

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

section EvalInduction

end EvalInduction

end FSM

namespace FSM

end FSM

open Term

def card_compl [Fintype α] [DecidableEq α] (c : Circuit α) : ℕ :=
  Finset.card $ (@Finset.univ (α → Bool) _).filter (fun a => c.eval a = false)

def decideIfZerosAux {arity : Type _} [DecidableEq arity]
    (p : FSM arity) (c : Circuit p.α) : Bool :=
  
  if c.eval p.initCarry 
  then false 
  else
    
    
    have c' := (c.bind (p.nextStateCirc)).fst
    if h : c' ≤ c then true
    else
      have _wf : card_compl (c' ||| c) < card_compl c :=
        decideIfZeroAux_wf h
      decideIfZerosAux p (c' ||| c)
  termination_by card_compl c
</local_ctx>

<target_theorem>
theorem decideIfZerosAux_correct {arity : Type _} [DecidableEq arity]
    (p : FSM arity) (c : Circuit p.α)
    (hc : ∀ s, c.eval s = true →
      ∃ m y, (p.changeInitCarry s).eval y m = true)
    (hc₂ : ∀ (x : arity → Bool) (s : p.α → Bool),
      (FSM.nextBit p s x).snd = true → Circuit.eval c s = true) :
    decideIfZerosAux p c = true ↔ ∀ n x, p.eval x n = false :=
</target_theorem>

