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

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

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

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

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

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

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

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

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

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

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

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

open Set
open Mathlib
open SetRel

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

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

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

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

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

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

@[simp]
</local_ctx>

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

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

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

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

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

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

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

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

### Your task:
<all_available_defs>
Bool in Init.Prelude
Nat in Init.Prelude
Int.xor in Mathlib.Data.Int.Bitwise
List in Init.Prelude
Nat.testBit in Init.Data.Nat.Bitwise.Basic
BitVec in Init.Prelude
BitVec.ofNat in Init.Prelude
List.map in Init.Prelude
BitVec.ult in Init.Data.BitVec.Basic
BitVec.carry in Init.Data.BitVec.Bitblast

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

def BitStream : Type := Nat → Bool

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

def Term.denote (w : Nat) (t : Term) (vars : List (BitVec w)) : BitVec w :=
  match t with
  | ofNat n => BitVec.ofNat w n
  | var n => vars.getD n default
  | zero => 0#w
  | negOne => -1#w
  | one  => 1#w
  | and a b => (a.denote w vars) &&& (b.denote w vars)
  | or a b => (a.denote w vars) ||| (b.denote w vars)
  | xor a b => (a.denote w vars) ^^^ (b.denote w vars)
  | not a => ~~~ (a.denote w vars)
  | add a b => (a.denote w vars) + (b.denote w vars)
  | sub a b => (a.denote w vars) - (b.denote w vars)
  | neg a => - (a.denote w vars)
  
  
  | shiftL a n => (a.denote w vars) <<< n

def Predicate.denote (p : Predicate) (w : Nat) (vars : List (BitVec w)) : Prop :=
  match p with
  | .width .ge k => k ≤ w 
  | .width .gt k => k < w 
  | .width .le k => w ≤ k
  | .width .lt k => w < k
  | .width .neq k => w ≠ k
  | .width .eq k => w = k
  | .binary .eq t₁ t₂ => t₁.denote w vars = t₂.denote w vars
  | .binary .neq t₁ t₂ => t₁.denote w vars ≠ t₂.denote w vars
  | .binary .sle  t₁ t₂ => ((t₁.denote w vars).sle (t₂.denote w vars)) = true
  | .binary .slt  t₁ t₂ => ((t₁.denote w vars).slt (t₂.denote w vars)) = true
  | .binary .ule  t₁ t₂ => ((t₁.denote w vars).ule (t₂.denote w vars)) = true
  | .binary .ult  t₁ t₂ => (t₁.denote w vars).ult (t₂.denote w vars) = true
  | .land  p q => p.denote w vars ∧ q.denote w vars
  | .lor  p q => p.denote w vars ∨ q.denote w vars

inductive Predicate : Type where
 
| width (wp : WidthPredicate) (n : Nat) : Predicate
| binary (p : BinaryPredicate) (t₁ t₂ : Term)
| land  (p q : Predicate) : Predicate
| lor (p q : Predicate) : Predicate
deriving Repr, Inhabited, Lean.ToExpr

inductive WidthPredicate
| eq
| neq
| lt
| le
| gt
| ge
deriving Repr, Inhabited, Lean.ToExpr

abbrev ofBitVecSext {w} (x : BitVec w) : BitStream :=
  fun i => if i < w then x.getLsbD i else x.msb

def toBitVec (w : Nat) (x : BitStream) : BitVec w :=
  match w with
  | 0   => 0#0
  | w+1 => (x.toBitVec w).cons (x w)

def test2_after := [llvm|
{
^0(%arg18 : i8):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(3 : i32) : i32
  %2 = llvm.zext %arg18 : i8 to i32
  %3 = llvm.add %2, %0 overflow<nsw,nuw> : i32
  %4 = llvm.lshr %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def sge_swap_or_max_commute_before := [llvm|
{
^0(%arg178 : i8, %arg179 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.icmp "sle" %arg179, %arg178 : i8
  %2 = llvm.icmp "eq" %arg178, %0 : i8
  %3 = llvm.or %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def negation_of_increment_via_or_disjoint_before := [llvm|
{
^0(%arg81 : i8, %arg82 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.or disjoint %arg82, %0 : i8
  %2 = llvm.sub %arg81, %1 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

instance : DialectPrint RV64 where
  printOpName op := "riscv." ++ opName op
  printTy := toString
  printAttributes := printAttributes
  dialectName := "riscv"
  printReturn _ := "riscv.ret"
  printFunc _ := "riscv_func.func @f"

def or_lshr_before := [llvm|
{
^0(%arg628 : i8, %arg629 : i8, %arg630 : i8, %arg631 : i8):
  %0 = llvm.lshr %arg628, %arg631 : i8
  %1 = llvm.lshr %arg629, %arg631 : i8
  %2 = llvm.or %0, %arg630 : i8
  %3 = llvm.or %1, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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

def bools2_logical_commute0_after := [llvm|
{
^0(%arg64 : i1, %arg65 : i1, %arg66 : i1):
  %0 = "llvm.select"(%arg66, %arg64, %arg65) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

def llvm_const_lower_riscv_li_24 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_24, rhs:= liRiscv_24,
   correct := by admit /- proof elided -/

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

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

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

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

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

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

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

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

def add_shl_moreOneUse_sh3add_no_ZBA_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := add_shl_moreOneUse_sh3add
  rhs := add_shl_moreOneUse_sh3add_riscv_no_ZBA

partial def reflectTermUnchecked (map : ReflectMap) (w : Expr) (e : Expr) : MetaM (ReflectResult _root_.Term) := do
  if let some (v, _bvTy) ← getOfNatValue? e ``BitVec then
    return { exprToIx := map, e := Term.ofNat v }
  
  match_expr e with
  | BitVec.ofInt _wExpr iExpr =>
    let i ← getIntValue? iExpr
    match i with
    | _ =>
      let (e, map) := map.findOrInsertExpr e
      return { exprToIx := map, e := Term.var e }
  | BitVec.ofNat _wExpr nExpr =>
    let n ← getNatValue? nExpr
    match n with
    | .some 0 =>
      return {exprToIx := map, e := Term.zero }
    | .some 1 =>
      let _ := (mkConst ``Term.one)
      return {exprToIx := map, e := Term.one }
    | .some n =>
      return { exprToIx := map, e := Term.ofNat n }
    | none =>
      logWarning "expected concrete BitVec.ofNat, found symbol '{n}', creating free variable"
      reflectAtomUnchecked map w e

  | HAnd.hAnd _bv _bv _bv _inst a b =>
      let a ← reflectTermUnchecked map w a
      let b ← reflectTermUnchecked a.exprToIx w b
      let out := Term.and a.e b.e
      return { b with e := out }
  | HOr.hOr _bv _bv _bv _inst a b =>
      let a ← reflectTermUnchecked map w a
      let b ← reflectTermUnchecked a.exprToIx w b
      let out := Term.or a.e b.e
      return { b with e := out }
  | HXor.hXor _bv _bv _bv _inst a b =>
      let a ← reflectTermUnchecked map w a
      let b ← reflectTermUnchecked a.exprToIx w b
      let out := Term.xor a.e b.e
      return { b with e := out }
  | Complement.complement _bv _inst a =>
      let a ← reflectTermUnchecked map w a
      let out := Term.not a.e
      return { a with e := out }
  | HAdd.hAdd _bv _bv _bv _inst a b =>
      let a ← reflectTermUnchecked map w a
      let b ← reflectTermUnchecked a.exprToIx w b
      let out := Term.add a.e b.e
      return { b with e := out }
  | HShiftLeft.hShiftLeft _bv _nat _bv _inst a n =>
      let a ← reflectTermUnchecked map w a
      let some n ← getNatValue? n
        | throwError m!"expected shiftLeft by natural number, found symbolic shift amount '{n}' at '{indentD e}'"
      return { a with e := Term.shiftL a.e n }

  | HSub.hSub _bv _bv _bv _inst a b =>
      let a ← reflectTermUnchecked map w a
      let b ← reflectTermUnchecked a.exprToIx w b
      let out := Term.sub a.e b.e
      return { b with e := out }
  | Neg.neg _bv _inst a =>
      let a ← reflectTermUnchecked map w a
      let out := Term.neg a.e
      return { a with e := out }
  
  
  | _ =>
    let (e, map) := map.findOrInsertExpr e
    return { exprToIx := map, e := Term.var e }

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

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

BitVec.clz in Init.Data.BitVec.Basic

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

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

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

def or_or_and_pat4_before := [llvm|
{
^0(%arg62 : i8, %arg63 : i8, %arg64 : i8, %arg65 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.udiv %0, %arg64 : i8
  %2 = llvm.and %arg62, %arg63 : i8
  %3 = llvm.and %arg65, %arg63 : i8
  %4 = llvm.or %1, %3 : i8
  %5 = llvm.or %4, %2 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

BitVec.ofNat in Init.Prelude

def Term.bcard (t : Term) : Nat :=
  match t with
  | .ofNat _w _n => 0
  | .var _v _w => 0
  | .add _w a b => max (Term.bcard a) (Term.bcard b)
  | .zext a _wnew => (Term.bcard a)
  | .sext a _wnew => (Term.bcard a)
  | .setWidth a _wnew => (Term.bcard a)
  | .bor _w a b => (max (Term.bcard a) (Term.bcard b))
  | .band _w a b => (max (Term.bcard a) (Term.bcard b))
  | .bxor _w a b => (max (Term.bcard a) (Term.bcard b))
  | .bnot _w a => (Term.bcard a)
  | .boolVar v => v + 1
  | .boolConst _b => 0
  | .shiftl _w a _k => (Term.bcard a)
  | bvOfBool b => b.bcard
  | binWidthRel _k _wa _wb => 0
  | binRel _k _w a b => max (Term.bcard a) (Term.bcard b)
  | or p1 p2 => max (Term.bcard p1) (Term.bcard p2)
  | and p1 p2 => max (Term.bcard p1) (Term.bcard p2)
  | pvar _v => 0
  | boolBinRel _k a b => max (a.bcard) (b.bcard)

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

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

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

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

def test19_after := [llvm|
{
^0(%arg4 : i39, %arg5 : i39):
  "llvm.return"(%arg4) : (i39) -> ()
}
]

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

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

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 test_or_eq_different_operands_after := [llvm|
{
^0(%arg24 : i8, %arg25 : i8, %arg26 : i8):
  %0 = llvm.icmp "eq" %arg24, %arg26 : i8
  %1 = "llvm.select"(%0, %arg24, %arg25) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

abbrev SimpleReg.int : SimpleReg.Ty := .int

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

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

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

def add_sub_reg_frags : List (Σ Γ, RISCVPeepholeRewrite Γ) :=
  [⟨_, add_sub_reg_frags_left⟩,
  ⟨_, add_sub_reg_frags_right⟩]

def or_test2_after := [llvm|
{
^0(%arg0 : i8, %arg1 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  "llvm.return"(%0) : (i8) -> ()
}
]

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

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

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

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

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

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

def not_and_and_or_no_or_commute3_after := [llvm|
{
^0(%arg148 : i32, %arg149 : i32, %arg150 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg150 : i32
  %3 = llvm.xor %arg148, %1 : i32
  %4 = llvm.xor %arg149, %1 : i32
  %5 = llvm.or %2, %4 : i32
  %6 = llvm.and %5, %3 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

def pr33078_3_after := [llvm|
{
^0(%arg3 : i8):
  %0 = llvm.mlir.constant(12 : i16) : i16
  %1 = llvm.sext %arg3 : i8 to i16
  %2 = llvm.lshr %1, %0 : i16
  %3 = llvm.trunc %2 overflow<nuw> : i16 to i4
  "llvm.return"(%3) : (i4) -> ()
}
]

BitVec.iunfoldr in Init.Data.BitVec.Folds

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

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

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

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

def main7e_before := [llvm|
{
^0(%arg54 : i32, %arg55 : i32, %arg56 : i32, %arg57 : i32, %arg58 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.and %arg55, %arg57 : i32
  %3 = llvm.and %arg56, %arg58 : i32
  %4 = llvm.and %2, %arg54 : i32
  %5 = llvm.icmp "eq" %4, %2 : i32
  %6 = llvm.and %3, %arg54 : i32
  %7 = llvm.icmp "eq" %6, %3 : 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) -> ()
}
]

def llvm00:=
  [LV|{
  ^bb0(%X : i64, %Y : i64 ):
    %1 = llvm.add %X, %Y : i64
    %2 = llvm.sub %X, %X : i64
    %3 = llvm.add %1, %Y : i64
    %4 = llvm.add %3, %Y : i64
    %5 = llvm.add %3, %4 : i64
    llvm.return %5 : i64
  }]

structure StInv (m : RawCNFA A) (map : Std.HashMap S State) where
  wf : m.WF
  map_states : ∀ (sa : S) s, map[sa]? = some s → s ∈ m.states
  map_surj : ∀ s : m.states, ∃ (sa : S), map[sa]? = some s.val
  map_inj : ∀ {s} {sa sa' : S}, map[sa]? = some s → map[sa']? = some s → sa = sa'

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

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

def test83_before := [llvm|
{
^0(%arg62 : i16, %arg63 : i64):
  %0 = llvm.mlir.constant(-1) : i64
  %1 = llvm.sext %arg62 : i16 to i32
  %2 = llvm.add %arg63, %0 overflow<nsw> : i64
  %3 = llvm.trunc %2 : i64 to i32
  %4 = llvm.shl %1, %3 : i32
  %5 = llvm.zext %4 : i32 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

def shl_and_and_after := [llvm|
{
^0(%arg172 : i8, %arg173 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.mlir.constant(80 : i8) : i8
  %2 = llvm.and %arg173, %arg172 : i8
  %3 = llvm.shl %2, %0 : i8
  %4 = llvm.and %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

structure DerivedCtxt (Γ : Ctxt Ty) where
  ctxt : Ctxt Ty
  diff : Ctxt.Diff Γ ctxt

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

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

Int.instAdd in Init.Data.Int.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 ule_swap_or_not_min_commute_before := [llvm|
{
^0(%arg260 : i8, %arg261 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "uge" %arg261, %arg260 : i8
  %2 = llvm.icmp "ne" %arg260, %0 : i8
  %3 = llvm.or %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def mkReturn (Γ : Ctxt (FHE q n).Ty) (opStx : MLIR.AST.Op 0) : MLIR.AST.ReaderM (FHE q n)
    (Σ eff ty, Com (FHE q n) Γ eff ty) :=
  if opStx.name == "return"
  then match opStx.args with
  | vStx::[] => do
    let ⟨ty, v⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ vStx
    return ⟨.pure, [ty], Com.ret v⟩
  | _ => throw <| .generic (s!"Ill-formed return statement (wrong arity, expected 1," ++
    s!" got {opStx.args.length})")
  else throw <| .generic s!"Tried to build return out of non-return statement {opStx.name}"

def xor_or_xor_common_op_commute6_before := [llvm|
{
^0(%arg65 : i32, %arg66 : i32, %arg67 : i32):
  %0 = llvm.xor %arg67, %arg65 : i32
  %1 = llvm.or %arg65, %arg66 : i32
  %2 = llvm.xor %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

Lean.Level.zero in Lean.Level

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

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

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

Min in Init.Prelude

Set.compl in Mathlib.Data.Set.Defs

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

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

@[simp_denote]
def or_riscv_i32 :=
  [LV| {
    ^entry (%arg0: i32, %arg1: i32):
    %a = "builtin.unrealized_conversion_cast" (%arg0) : (i32) -> (!i64)
    %b = "builtin.unrealized_conversion_cast" (%arg1) : (i32) -> (!i64)
    %0 = or %a, %b : !i64
    %1 = "builtin.unrealized_conversion_cast" (%0) : (!i64) -> (i32)
    llvm.return %1 : 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 ashr_ule_noexact_before := [llvm|
{
^0(%arg158 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(10 : i8) : i8
  %2 = llvm.ashr %arg158, %0 : i8
  %3 = llvm.icmp "ule" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def factorize3_before := [llvm|
{
^0(%arg5 : i32, %arg6 : i32, %arg7 : i32):
  %0 = llvm.or %arg6, %arg7 : i32
  %1 = llvm.or %arg5, %0 : i32
  %2 = llvm.or %arg5, %arg7 : i32
  %3 = llvm.and %1, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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 shl_lshr_demand1_after := [llvm|
{
^0(%arg20 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.mlir.constant(-32 : i8) : i8
  %2 = llvm.shl %0, %arg20 : i8
  %3 = llvm.or %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

def test14_after := [llvm|
{
^0(%arg26 : i35):
  %0 = llvm.mlir.constant(-19760 : i35) : i35
  %1 = llvm.mlir.constant(19744 : i35) : i35
  %2 = llvm.and %arg26, %0 : i35
  %3 = llvm.or disjoint %2, %1 : i35
  "llvm.return"(%3) : (i35) -> ()
}
]

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 ripple_no_nsw2_after := [llvm|
{
^0(%arg9 : i16, %arg10 : i16):
  %0 = llvm.mlir.constant(1 : i16) : i16
  %1 = llvm.mlir.constant(32767 : i16) : i16
  %2 = llvm.and %arg10, %0 : i16
  %3 = llvm.and %arg9, %1 : i16
  %4 = llvm.add %2, %3 overflow<nuw> : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

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

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

def fold_select_trunc_nuw_false_after := [llvm|
{
^0(%arg8 : i8, %arg9 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.trunc %arg8 overflow<nuw> : i8 to i1
  %2 = "llvm.select"(%1, %arg9, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

def llvm_trunc_riscv_32_to_8_nuw_nsw : LLVMPeepholeRewriteRefine 8 [Ty.llvm (.bitvec 32)] :=
  {lhs:= trunc_llvm_32_to_8_nsw_nuw, rhs:= trunc_riscv_32_to_8_nsw_nuw}

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

structure _root_.SetRel.set_eq (R : SetRel α β) (A : Set α) (B : Set β) where
  fwd : a ∈ A → ∃ b ∈ B, a ~[R] b
  bwd : b ∈ B → ∃ a ∈ A, a ~[R] b

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

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

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

def test_xor_eq_before := [llvm|
{
^0(%arg61 : i8, %arg62 : i8, %arg63 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.xor %arg63, %0 : i8
  %2 = llvm.xor %arg62, %0 : i8
  %3 = llvm.xor %2, %arg61 : i8
  %4 = llvm.icmp "eq" %1, %3 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

def Region.substitute (σ : Substitution) : Region Op T → Region Op T
  | ⟨entry, blocks⟩ => ⟨entry, subBlocks blocks⟩
  where subBlocks : List (BasicBlock Op T) → List (BasicBlock Op T)
    | []    => []
    | b::bs => b.substitute σ :: subBlocks bs

Std.Format.nest in Init.Data.Format.Basic

def llvm_sext_lower_riscv_i1_to_32 : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 1)] :=
  {lhs:= sext_llvm_i1_to_32, rhs:= sext_riscv_i1_to_32}

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

def test6_before := [llvm|
{
^0(%arg103 : i64):
  %0 = llvm.mlir.constant(32 : i128) : i128
  %1 = llvm.zext %arg103 : i64 to i128
  %2 = llvm.lshr %1, %0 : i128
  %3 = llvm.trunc %2 : i128 to i32
  "llvm.return"(%3) : (i32) -> ()
}
]

abbrev DC : Dialect where
  Op := Op
  Ty := Ty

def_signature for DC where
  | .fst => (Ty.tokenstream2) → (Ty.tokenstream)
  | .fstVal t => (Ty.valuetokenstream t) → Ty.valuestream t
  | .fstVal' t => (Ty.variadicvaluetokenstream t) → Ty.valuestream t
  | .snd => (Ty.tokenstream2) → (Ty.tokenstream)
  | .pair w => (Ty.valuestream w, Ty.valuestream w) → Ty.valuestream2 w
  | .sndVal t => (Ty.valuetokenstream t) → Ty.tokenstream
  | .sndVal' t => (Ty.variadicvaluetokenstream t) → Ty.valuestream t
  | .tokVal' t => (Ty.variadicvaluetokenstream t) → Ty.tokenstream
  | .merge => (Ty.tokenstream, Ty.tokenstream) → Ty.valuestream 1
  | .branch => (Ty.valuestream 1) → Ty.tokenstream2
  | .fork => (Ty.tokenstream) → Ty.tokenstream2
  | .join => (Ty.tokenstream, Ty.tokenstream) → Ty.tokenstream
  | .select => (Ty.tokenstream, Ty.tokenstream, Ty.valuestream 1) → Ty.tokenstream
  | .sink => (Ty.tokenstream) → Ty.tokenstream
  | .source => () → Ty.tokenstream
  | .pack t => (Ty.valuestream t, Ty.tokenstream) → Ty.valuestream t
  | .pack2 t => (Ty.variadicvaluetokenstream t) → Ty.valuestream2 t
  | .unpack t => (Ty.valuestream t) → Ty.valuetokenstream t
  | .unpack2 t => (Ty.valuestream t, Ty.valuestream t) → Ty.variadicvaluetokenstream t

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

def icmp {w : Nat} (c : IntPred) (x y : IntW w) : IntW 1 := do
  let x' ← x
  let y' ← y
  icmp? c x' y'

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

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

def not_ashr_not_after := [llvm|
{
^0(%arg139 : i32, %arg140 : i32):
  %0 = llvm.ashr %arg139, %arg140 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

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

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 xor_i8_to_i64_shl_save_and_ne_after := [llvm|
{
^0(%arg8 : i8, %arg9 : i64):
  %0 = llvm.mlir.constant(63) : i64
  %1 = llvm.zext %arg8 : i8 to i64
  %2 = llvm.shl %1, %0 : i64
  %3 = llvm.xor %arg9, %2 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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

def lshr_add_exact_after := [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 exact %2, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def test_ult_xor_after := [llvm|
{
^0(%arg36 : i32, %arg37 : i32):
  %0 = llvm.xor %arg37, %arg36 : i32
  %1 = llvm.icmp "ugt" %0, %arg36 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

def Eqn.reflect {w : Nat} (e : Eqn) (env : Env w) : BitVec w :=
  match e with
  | [] => 0
  | t :: [] => t.reflect env
  | t :: ts => t.reflect env + Eqn.reflect ts env

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

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 MatchVarResult := { mapOut : Mapping _ _ //
  ∃ (mapIn' mapOut' : Mapping _ _),
    mapIn.entries ⊆ mapIn'.entries
    ∧ mapOut'.entries ⊆ mapOut.entries
    ∧ matchVar lets v matchLets w mapIn' = some ((), mapOut') }

def bitwise_and_logical_and_icmps_after := [llvm|
{
^0(%arg232 : i8, %arg233 : i8, %arg234 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.icmp "eq" %arg233, %0 : i8
  %4 = llvm.shl %1, %arg234 overflow<nuw> : i8
  %5 = llvm.or %4, %1 : i8
  %6 = llvm.and %arg232, %5 : i8
  %7 = llvm.icmp "eq" %6, %5 : i8
  %8 = "llvm.select"(%3, %7, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%8) : (i1) -> ()
}
]

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

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

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

def test67_before := [llvm|
{
^0(%arg113 : i1, %arg114 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(24 : i32) : i32
  %2 = llvm.mlir.constant(-16777216 : i32) : i32
  %3 = llvm.mlir.constant(0 : i8) : i8
  %4 = llvm.zext %arg113 : i1 to i32
  %5 = llvm.xor %4, %0 : i32
  %6 = llvm.and %arg114, %5 : i32
  %7 = llvm.shl %6, %1 overflow<nsw,nuw> : i32
  %8 = llvm.xor %7, %2 : i32
  %9 = llvm.ashr exact %8, %1 : i32
  %10 = llvm.trunc %9 : i32 to i8
  %11 = llvm.icmp "eq" %10, %3 : i8
  "llvm.return"(%11) : (i1) -> ()
}
]

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

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

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

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

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

def test_add_zero_lhs_LHS := [mod_arith q, hq| {
  ^bb0(%x : !R):
    %zero = mod_arith.constant 0 : !R
    %add = mod_arith.add %zero, %x : !R
    return %add : !R
}]

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

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

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

def test_before := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(12 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %arg0, %0 : i32
  %3 = llvm.lshr %2, %0 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

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

def reassoc_mul_nuw_after := [llvm|
{
^0(%arg24 : i32):
  %0 = llvm.mlir.constant(260 : i32) : i32
  %1 = llvm.mul %arg24, %0 overflow<nuw> : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

Std.Tactic.BVDecide.BoolExpr.literal in Std.Tactic.BVDecide.Bitblast.BoolExpr.Basic

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

def zext_sext_sle_known_nonneg_op0_narrow_before := [llvm|
{
^0(%arg18 : i8, %arg19 : i16):
  %0 = llvm.mlir.constant(12 : i8) : i8
  %1 = llvm.and %arg18, %0 : i8
  %2 = llvm.zext %1 : i8 to i32
  %3 = llvm.sext %arg19 : i16 to i32
  %4 = llvm.icmp "sle" %2, %3 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

instance : AST.TransformExpr (MetaLLVM φ) φ := { mkExpr }

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

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

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

instance : Lean.ToExpr RegIndex := inherit

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

def xor_with_or_disjoint_ba_before := [llvm|
{
^0(%arg24 : i32, %arg25 : i32):
  %0 = llvm.or disjoint %arg25, %arg24 : i32
  %1 = llvm.xor %arg25, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

def test13_before := [llvm|
{
^0(%arg87 : i32):
  %0 = llvm.srem %arg87, %arg87 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def test35_after := [llvm|
{
^0(%arg246 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(240 : i32) : i32
  %2 = llvm.sub %0, %arg246 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.zext nneg %3 : i32 to i64
  "llvm.return"(%4) : (i64) -> ()
}
]

def mul_splat_fold_after := [llvm|
{
^0(%arg161 : i32):
  "llvm.return"(%arg161) : (i32) -> ()
}
]

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

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

RV64.div in RISCV.Instructions

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

def syncMap₂ (f : α → β → γ) (xs : Stream α) (ys : Stream β) : Stream γ :=
  Stream.corec (xs, ys) fun ⟨xs, ys ⟩ =>
    match xs 0, ys 0 with
    | some x, some y => ⟨some <| f x y, xs.tail, ys.tail⟩
    | _, _ =>
      let xs := if (xs 0).isNone then xs.tail else xs
      let ys := if (ys 0).isNone then ys.tail else ys
      ⟨none, xs, ys⟩

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

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

def AttrEntry.destructure {φ} : AttrEntry φ → String × AttrValue φ
  | .mk name value => (name,value)

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

def add_i64_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := add_llvm_i64
  rhs := add_riscv_i64

def lshr_and_xor_before := [llvm|
{
^0(%arg37 : i8, %arg38 : 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 %arg37, %0 : i8
  %4 = llvm.lshr %arg38, %1 : i8
  %5 = llvm.and %4, %2 : i8
  %6 = llvm.xor %5, %3 : i8
  %7 = llvm.shl %6, %1 : i8
  "llvm.return"(%7) : (i8) -> ()
}
]

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

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

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

structure Item where
 name : String
 tac : Syntax

def negate_shl_xor_before := [llvm|
{
^0(%arg138 : i4, %arg139 : i4):
  %0 = llvm.mlir.constant(5 : i4) : i4
  %1 = llvm.mlir.constant(0 : i4) : i4
  %2 = llvm.xor %arg138, %0 : i4
  %3 = llvm.shl %2, %arg139 : i4
  %4 = llvm.sub %1, %3 : i4
  "llvm.return"(%4) : (i4) -> ()
}
]

def ConcreteCliTest.inputToString (test : ConcreteCliTest) : Nat → Array (Option ℤ) → String
  | i, arr =>
    let tys : List (InstCombine.MTy 0) := test.context.reverse 
    match tys[i]? with
    | .none => "<none>"
    | .some (.bitvec (.concrete w)) =>
        BitVec.inputToString <| Option.map (BitVec.ofInt w) arr[i]!

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

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

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

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

def not_xor_to_or_not1_after := [llvm|
{
^0(%arg39 : i3, %arg40 : i3, %arg41 : i3):
  %0 = llvm.mlir.constant(-1 : i3) : i3
  %1 = llvm.or %arg40, %arg41 : i3
  %2 = llvm.and %arg39, %arg41 : i3
  %3 = llvm.xor %1, %0 : i3
  %4 = llvm.or %2, %3 : i3
  "llvm.return"(%4) : (i3) -> ()
}
]

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

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

Stream'.const in Mathlib.Data.Stream.Defs

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

private def pretty_test_overflow :=
  [llvm()|{
  ^bb0(%arg0: i32):
    %0 = llvm.mlir.constant 8 : i32
    %1 = llvm.add %0, %arg0 overflow<nsw> : i32
    %2 = llvm.mul %1, %arg0 : i32
    %3 = llvm.not %2 : i32
    llvm.return %3 : i32
  }]

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

def 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 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 ule_and_min_commute_logical_before := [llvm|
{
^0(%arg200 : i8, %arg201 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "ule" %arg200, %arg201 : i8
  %3 = llvm.icmp "eq" %arg200, %0 : i8
  %4 = "llvm.select"(%3, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def llvm_const_lower_riscv_li0_1bit : LLVMPeepholeRewriteRefine 1 [] where
  lhs := constLLVM0_1bit
  rhs := liRiscv0_1bit

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

def sel_false_val_is_a_masked_ashr_of_true_val1_after := [llvm|
{
^0(%arg2 : i32, %arg3 : i64):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(-536870897 : i32) : i32
  %2 = llvm.ashr %arg2, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.zext nneg %3 : i32 to i64
  %5 = llvm.ashr %arg3, %4 : i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

@[simp_llvm]
def mul? {w : Nat} (x y : BitVec w) : IntW w :=
  .value <| x * y

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

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

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

    |

def llvm_add_lower_riscv_nsw_flag_32 : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)]
where
  lhs:= add_llvm_nsw_flags_32
  rhs:= add_riscv_32

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

def test46_after := [llvm|
{
^0(%arg199 : i32, %arg200 : i32):
  %0 = llvm.and %arg200, %arg199 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

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

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

@[simp_denote]
def add_positive_high_bound_accept_llvm := [LV| {
    ^entry (%a: i32):
    %0 = llvm.mlir.constant (4094) : i32
    %1 = llvm.add %0, %a : i32
    llvm.return %1 :i32
  }]

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

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

def lshrugt_01_05_after := [llvm|
{
^0(%arg410 : i4):
  %0 = llvm.mlir.constant(-5 : i4) : i4
  %1 = llvm.icmp "ugt" %arg410, %0 : i4
  "llvm.return"(%1) : (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 test85_before := [llvm|
{
^0(%arg60 : i32):
  %0 = llvm.mlir.constant(-16777216 : i32) : i32
  %1 = llvm.mlir.constant(23 : i32) : i32
  %2 = llvm.add %arg60, %0 overflow<nuw> : i32
  %3 = llvm.lshr exact %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 alive_AndOrXor_1280_ABA___AB_src :=
[sllvm| {
^bb0(%A : i64, %B : i64):
  %v1 = llvm.mlir.constant -1 : i64
  %v2 = llvm.xor %A, %v1 : i64
  %v3 = llvm.or %v2, %B : i64
  %v4 = llvm.and %v3, %A : i64
  llvm.return %v4 : i64
}]

instance instDCTyDenote : TyDenote Ty where
toType := fun
| Ty.tokenstream => CIRCTStream.DCOp.TokenStream
| Ty.tokenstream2 => CIRCTStream.DCOp.TokenStream × CIRCTStream.DCOp.TokenStream
| Ty.valuestream w => CIRCTStream.DCOp.ValueStream (BitVec w)
| Ty.valuestream2 w => CIRCTStream.DCOp.ValueStream (BitVec w) × CIRCTStream.DCOp.ValueStream (BitVec w)
| Ty.valuetokenstream w => CIRCTStream.DCOp.ValueStream (BitVec w) × CIRCTStream.DCOp.TokenStream
| Ty.variadicvaluetokenstream w => CIRCTStream.DCOp.VariadicValueStream w × CIRCTStream.DCOp.TokenStream


def_denote for DC where
  | .fst => fun s => [s.fst]ₕ
  | .fstVal _ => fun s => [s.fst]ₕ
  | .fstVal' _ => fun s => [s.fst.mapOpt (·[0]?)]ₕ
  | .snd => fun s => [s.snd]ₕ
  | .pair _ => fun s₁ s₂ => [(s₁, s₂)]ₕ
  | .sndVal _ => fun s => [s.snd]ₕ
  | .sndVal' _ => fun s => [s.fst.mapOpt (·[0]?)]ₕ
  | .tokVal' _ => fun s => [s.snd]ₕ
  | .merge => fun s₁ s₂ => [CIRCTStream.DCOp.merge s₁ s₂]ₕ
  | .branch => fun s => [CIRCTStream.DCOp.branch s]ₕ
  | .fork => fun s => [CIRCTStream.DCOp.fork s]ₕ
  | .join => fun s₁ s₂ => [CIRCTStream.DCOp.join s₁ s₂]ₕ
  | .select => fun s₁ s₂ c => [CIRCTStream.DCOp.select s₁ s₂ c]ₕ
  | .sink => fun s => [CIRCTStream.DCOp.sink s]ₕ
  | .source => [CIRCTStream.DCOp.source]ₕ
  | .pack _ => fun s₁ s₂ => [CIRCTStream.DCOp.pack s₁ s₂]ₕ
  | .pack2 _ => fun s₁ => [CIRCTStream.DCOp.pack2 s₁]ₕ
  | .unpack _ => fun s => [CIRCTStream.DCOp.unpack s]ₕ
  | .unpack2 _ => fun s₁ s₂ => [CIRCTStream.DCOp.unpack2 s₁ s₂]ₕ

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

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

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

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

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

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 ashr? {n} (op1 : BitVec n) (op2 : BitVec n) : IntW n :=
  if op2 >= n
  then .poison
  else .value (op1.sshiftRight' op2)

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

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

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

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

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

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

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

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

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

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

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 zext_or_masked_bit_test_after := [llvm|
{
^0(%arg54 : i32, %arg55 : i32, %arg56 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %0, %arg55 overflow<nuw> : i32
  %3 = llvm.and %2, %arg54 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  %5 = llvm.icmp "eq" %arg56, %arg55 : i32
  %6 = llvm.or %4, %5 : i1
  %7 = llvm.zext %6 : i1 to i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

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

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

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

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

Lean.Expr.app in Lean.Expr

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

def 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 n10_before := [llvm|
{
^0(%arg0 : i64):
  %0 = llvm.mlir.constant(63) : i64
  %1 = llvm.mlir.constant(1) : i64
  %2 = llvm.lshr %arg0, %0 : i64
  %3 = llvm.sub %1, %2 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

def foo1_and_after := [llvm|
{
^0(%arg181 : i32, %arg182 : i32, %arg183 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.shl %0, %arg182 overflow<nuw> : i32
  %2 = llvm.shl %0, %arg183 overflow<nuw> : i32
  %3 = llvm.or %1, %2 : i32
  %4 = llvm.and %arg181, %3 : i32
  %5 = llvm.icmp "ne" %4, %3 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

List.Vector.ofFn in Mathlib.Data.Vector.Defs

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

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

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

def negate_xor_before := [llvm|
{
^0(%arg142 : i4):
  %0 = llvm.mlir.constant(5 : i4) : i4
  %1 = llvm.mlir.constant(0 : i4) : i4
  %2 = llvm.xor %arg142, %0 : i4
  %3 = llvm.sub %1, %2 : i4
  "llvm.return"(%3) : (i4) -> ()
}
]

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

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

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

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

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

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

def test12_after := [llvm|
{
^0(%arg182 : i32, %arg183 : i32):
  %0 = llvm.and %arg183, %arg182 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def add_umax_simplify_before := [llvm|
{
^0(%arg45 : i37):
  %0 = llvm.mlir.constant(42 : i37) : i37
  %1 = llvm.add %arg45, %0 overflow<nuw> : i37
  %2 = llvm.icmp "ugt" %1, %0 : i37
  %3 = "llvm.select"(%2, %1, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i37, i37) -> i37
  "llvm.return"(%3) : (i37) -> ()
}
]

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 one_inst_com_proof (w : Nat) :
    one_inst_com w ⊑ one_inst_com w :=

def unopNfa (op : Unop) (m : CNFA n) : CNFA n :=
  match op with
  | .neg => m.neg

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

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

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

def icmp_power2_and_icmp_shifted_mask_2147483648_1610612736_before := [llvm|
{
^0(%arg45 : i32):
  %0 = llvm.mlir.constant(-2147483648 : i32) : i32
  %1 = llvm.mlir.constant(1610612736 : i32) : i32
  %2 = llvm.icmp "ult" %arg45, %0 : i32
  %3 = llvm.and %arg45, %1 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  %5 = llvm.and %2, %4 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def sdiv2_before := [llvm|
{
^0(%arg39 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.sdiv exact %arg39, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

def test58_after := [llvm|
{
^0(%arg124 : i64):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(128 : i32) : i32
  %2 = llvm.trunc %arg124 : i64 to i32
  %3 = llvm.lshr %2, %0 : i32
  %4 = llvm.or %3, %1 : i32
  %5 = llvm.zext nneg %4 : i32 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

def simplify_or_common_op_commute2_before := [llvm|
{
^0(%arg38 : i4, %arg39 : i4, %arg40 : i4, %arg41 : i4):
  %0 = llvm.mlir.constant(-1 : i4) : i4
  %1 = llvm.mul %arg40, %arg40 : i4
  %2 = llvm.and %arg38, %arg39 : i4
  %3 = llvm.and %1, %2 : i4
  %4 = llvm.and %3, %arg41 : i4
  %5 = llvm.xor %4, %0 : i4
  %6 = llvm.or %5, %arg38 : i4
  "llvm.return"(%6) : (i4) -> ()
}
]

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

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

def zext_sext_add_icmp_ne_minus1_after := [llvm|
{
^0(%arg82 : i1, %arg83 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg83, %0 : i1
  %2 = llvm.or %arg82, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

def 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 pr51551_2_after := [llvm|
{
^0(%arg6 : i32, %arg7 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg6, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def add_of_mul_before := [llvm|
{
^0(%arg4 : i8, %arg5 : i8, %arg6 : i8):
  %0 = llvm.mul %arg4, %arg5 overflow<nsw> : i8
  %1 = llvm.mul %arg4, %arg6 overflow<nsw> : i8
  %2 = llvm.add %0, %1 overflow<nsw> : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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 test4_after := [llvm|
{
^0(%arg33 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.udiv %arg33, %0 : i32
  %2 = llvm.zext nneg %1 : i32 to i64
  "llvm.return"(%2) : (i64) -> ()
}
]

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

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

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

def scalar_i16_shl_ult_const_before := [llvm|
{
^0(%arg16 : i16):
  %0 = llvm.mlir.constant(8 : i16) : i16
  %1 = llvm.mlir.constant(1024 : i16) : i16
  %2 = llvm.shl %arg16, %0 : i16
  %3 = llvm.icmp "ult" %2, %1 : i16
  "llvm.return"(%3) : (i1) -> ()
}
]

def args : BasicBlock Op T → List VarName
  | ⟨_, args, _⟩ => args

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

def add_mask_ashr28_non_pow2_i32_before := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(28 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.ashr %arg1, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.add %3, %2 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

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

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

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

Int.sub in Init.Data.Int.Basic

def argVector.decEq : DecidableEq (HVector (Ctxt.Var Γ) ts) := inferInstance

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

def fstVal (a : Γ.Var (MLIR2DCPlus.Ty.valuetokenstream r)) : Expr (DCPlus) Γ .pure (.valuestream r) :=
    Expr.mk
    (op := .fstVal r)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .cons a <| .nil)
    (regArgs := .nil)

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

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

def 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 XorSextSext : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := [LV| {
    ^entry (%x: i32, %y: i32):
      %0 = llvm.sext %x : i32 to i64
      %1 = llvm.sext %y : i32 to i64
      %2 = llvm.xor %0, %1 : i64
      llvm.return %2 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i32, %y: i32):
      %0 = llvm.xor %x, %y : i32
      %1 = llvm.sext %0 : i32 to i64
      llvm.return %1 : i64
  }]

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

def not_or_or_not_commute1_after := [llvm|
{
^0(%arg546 : i32, %arg547 : i32, %arg548 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg547, %arg548 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.or %arg546, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def test86_after := [llvm|
{
^0(%arg59 : i16):
  %0 = llvm.mlir.constant(4 : i16) : i16
  %1 = llvm.ashr %arg59, %0 : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

def product.inits_nodup : inits m₁ m₂ |>.toList.Nodup :=

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

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

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

def mul_of_pow2s_after := [llvm|
{
^0(%arg79 : i32, %arg80 : i32):
  %0 = llvm.mlir.constant(128 : i32) : i32
  "llvm.return"(%0) : (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) -> ()
}
]

Array.size in Init.Prelude

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

def add_or_sub_comb_i64_commuted4_after := [llvm|
{
^0(%arg13 : i64):
  %0 = llvm.mlir.constant(-1) : i64
  %1 = llvm.mul %arg13, %arg13 : i64
  %2 = llvm.add %1, %0 : i64
  %3 = llvm.and %2, %1 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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

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

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

def n0_after := [llvm|
{
^0(%arg48 : i32, %arg49 : i64, %arg50 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(-16 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.sub %0, %arg50 : i32
  %4 = llvm.shl %arg48, %3 : i32
  %5 = llvm.add %arg50, %1 : i32
  %6 = llvm.zext nneg %5 : i32 to i64
  %7 = llvm.lshr %arg49, %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) -> ()
}
]

abbrev Arith : Dialect := {Op, Ty}

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

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

def isGteZeroCheck (expr : BoolExpr GenBVPred) : Bool :=
  match expr with
  | .literal (GenBVPred.bin _ BVBinPred.ult (GenBVExpr.shiftLeft (GenBVExpr.const bv) (GenBVExpr.bin (GenBVExpr.var _) BVBinOp.add (GenBVExpr.bin (GenBVExpr.const bv') BVBinOp.add (GenBVExpr.un BVUnOp.not (GenBVExpr.const bv'')))))) =>
          bv.toInt == 1 && bv'.toInt == 1 && bv''.toInt == 1
  | _ => false

def EnvFin (w : Nat) (n : Nat) := Fin n → (BitVec w)

  def llvm_urem_lower_riscv: LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] :=
  {lhs := llvm_urem, rhs := urem_riscv }

def sourceOnes : ValueStream (BitVec 1) :=
  Stream.corec () fun () => (1#1, ())

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

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

Lean.Elab.Tactic.run in Lean.Elab.Tactic.Basic

def State.add? (e : Expr) : GenM Expr := do
  match ← get? e with
  | some x => pure x
  | none =>
    if e.isFVar || e.isBVar then pure e else
    let x ← mkFreshExprMVar (some (.const ``Nat [])) (userName := `w)
    setMapping e x
    modify fun s => { s with invMapping := s.invMapping.insert x e }
    pure x

instance {α : Type u} [DEQ : DecidableEq α] : DecidableRel (@Refinement α) :=

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

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

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

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

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

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

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

def test9_after := [llvm|
{
^0(%arg111 : i32, %arg112 : i32):
  %0 = llvm.or %arg111, %arg112 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

BitVec.sub in Init.Data.BitVec.BasicAux

def zext_sext_add_icmp_ne_1_after := [llvm|
{
^0(%arg70 : i1, %arg71 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg70, %0 : i1
  %2 = llvm.or %arg71, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

def test16_after := [llvm|
{
^0(%arg283 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  "llvm.return"(%0) : (i8) -> ()
}
]

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

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

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 negative_and_odd_after := [llvm|
{
^0(%arg76 : i32):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.lshr %arg76, %0 : i32
  %2 = llvm.and %1, %arg76 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

System.FilePath in Init.System.FilePath

structure GlobalState where
  alloc : AllocState
  mem : MemoryState

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

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

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

def example00 := [RV64_com| {
^bb0(%0 : !riscv.reg, %1 : !riscv.reg):
    %2 = "slt"(%0, %1) : (!riscv.reg, !riscv.reg) -> (!riscv.reg)
    %3 = "andi" (%2){imm = 1 : !i64} : (!riscv.reg) -> (!riscv.reg)
    %4 = "sra"(%0, %0) : (!riscv.reg, !riscv.reg) -> (!riscv.reg)
    %5 = "add"(%0, %0) : (!riscv.reg, !riscv.reg) -> (!riscv.reg)
    %6 = "sra"(%2, %5) : (!riscv.reg, !riscv.reg) -> (!riscv.reg)
  "ret" (%0) : (!riscv.reg) -> ()
 }].denote

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

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

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

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

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

CoeHead in Init.Coe

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

def test6_after := [llvm|
{
^0(%arg117 : i32):
  %0 = llvm.mlir.constant(1234 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.xor %arg117, %0 : i32
  %3 = llvm.lshr %arg117, %1 : i32
  %4 = llvm.add %3, %2 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def bools2_logical_commute2_and1_after := [llvm|
{
^0(%arg37 : i1, %arg38 : i1, %arg39 : i1):
  %0 = "llvm.select"(%arg39, %arg37, %arg38) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (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) -> ()
}
]

HPow.hPow in Init.Prelude

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

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

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

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

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

def ashr_and_or_disjoint_before := [llvm|
{
^0(%arg41 : i8, %arg42 : 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 %arg41, %0 : i8
  %4 = llvm.ashr %arg42, %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) -> ()
}
]

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

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

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

def lowmask_add_zext_before := [llvm|
{
^0(%arg235 : i8, %arg236 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.zext %arg235 : i8 to i32
  %2 = llvm.add %1, %arg236 : i32
  %3 = llvm.and %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def not_invert_signbit_splat_mask1_before := [llvm|
{
^0(%arg83 : i8, %arg84 : i16):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.ashr %arg83, %0 : i8
  %3 = llvm.xor %2, %1 : i8
  %4 = llvm.zext %3 : i8 to i16
  %5 = llvm.and %4, %arg84 : i16
  "llvm.return"(%5) : (i16) -> ()
}
]

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

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

def MatchVarResult.isTotal_of
    (map : MatchVarResult lets v matchLets w mapIn)
    (hvars : ∀ t (v : Var Δ_in t), ⟨t, v⟩ ∈ matchLets.vars w) :
    map.val.IsTotal :=

instance (priority := low) [DecidableEq α] :
    Decidable (HRefinement.IsRefinedBy (self := @instHRefinementOfRefinement α .ofEq) x y) :=
  decidable_of_iff (x = y) (by admit /- proof elided -/
  )

class DialectSignature (d : Dialect) where
  signature : d.Op → Signature d.Ty

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

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

@[simp]
instance LLVMPlusRiscVSignature : DialectSignature LLVMPlusRiscV where
  signature
  | .llvm llvmOp => .llvm <$> DialectSignature.signature llvmOp
  | .riscv riscvOp => .riscv <$> DialectSignature.signature riscvOp
  | .castRiscv w =>
      {sig := [Ty.riscv .bv], returnTypes := [Ty.llvm (.bitvec w)], regSig := []}
  | .castLLVM w =>
      {sig := [Ty.llvm (.bitvec w)], returnTypes := [Ty.riscv .bv], regSig := []}

def xori_i64_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := xori_llvm_i64
  rhs := xori_riscv_i64

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

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

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

def test_sext_zext_before := [llvm|
{
^0(%arg14 : i16):
  %0 = llvm.zext %arg14 : i16 to i32
  %1 = llvm.sext %0 : i32 to i64
  "llvm.return"(%1) : (i64) -> ()
}
]

def test10_after := [llvm|
{
^0(%arg16 : i64):
  %0 = llvm.mlir.constant(-2) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.and %arg16, %0 : i64
  %3 = llvm.sub %1, %2 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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

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

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

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

def test_mul_nuw_nsw__nuw_is_safe_after := [llvm|
{
^0(%arg11 : i32):
  %0 = llvm.mlir.constant(268435457 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.and %arg11, %0 : i32
  %3 = llvm.mul %2, %1 overflow<nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

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

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

BitVec.sle in Init.Data.BitVec.Basic

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

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

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

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

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

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

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

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

structure PreconditionSynthesisCacheValue where
  positiveExampleValues : List BVExpr.PackedBitVec
  negativeExampleValues : List BVExpr.PackedBitVec

instance : HydrablePrettify GenBVPred where
  prettify := prettify
  prettifyAsSexpr  pred vars widthVals := GenBVPred.toSmtLib pred vars widthVals |>.toSexpr

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

instance [ToString α] [Hashable α] [BEq α] : ToString (Std.HashSet α ) where
  toString set := toString set.toList

def not_or_or_not_commute1_after := [llvm|
{
^0(%arg546 : i32, %arg547 : i32, %arg548 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg547, %arg548 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.or %arg546, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def demorgan_nor_use2bc_after := [llvm|
{
^0(%arg20 : i8, %arg21 : i8):
  %0 = llvm.mlir.constant(23 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.mul %arg21, %0 : i8
  %3 = llvm.xor %arg20, %1 : i8
  %4 = llvm.or %arg21, %3 : i8
  %5 = llvm.mul %4, %0 : i8
  %6 = llvm.xor %4, %1 : i8
  %7 = llvm.sdiv %6, %5 : i8
  %8 = llvm.sdiv %7, %2 : i8
  "llvm.return"(%8) : (i8) -> ()
}
]

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

def test16_before := [llvm|
{
^0(%arg38 : i32, %arg39 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(-1431655767 : i32) : i32
  %2 = llvm.add %arg39, %0 overflow<nsw> : i32
  %3 = llvm.and %arg38, %1 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.add %2, %4 overflow<nsw> : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

def xvar := @MultiWidth.Term.var (wcard := 1) (bcard := 0) (ncard := 0) (icard := 0) (pcard := 0) (tcard := 1) 
  (tctx := tctx) (v := ⟨0, by admit /- proof elided -/
  ⟩)

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

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

AList in Mathlib.Data.List.AList

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

def shl_xor_lshr_after := [llvm|
{
^0(%arg100 : i32, %arg101 : i32, %arg102 : i32):
  %0 = llvm.lshr %arg102, %arg101 : i32
  %1 = llvm.xor %0, %arg100 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

def NFA'.autWidth (wp : WidthPredicate) (n : Nat) : NFA' 0 := ⟨_, NFA.autWidth wp n⟩

instance instDCTyDenote : TyDenote Ty where
toType := fun
| Ty.tokenstream => CIRCTStream.DCPlusOp.TokenStream
| Ty.tokenstream2 => CIRCTStream.DCPlusOp.TokenStream × CIRCTStream.DCPlusOp.TokenStream
| Ty.valuestream w => CIRCTStream.DCPlusOp.ValueStream (BitVec w)
| Ty.valuestream2 w => CIRCTStream.DCPlusOp.ValueStream (BitVec w) × CIRCTStream.DCPlusOp.ValueStream (BitVec w)
| Ty.valuetokenstream w => CIRCTStream.DCPlusOp.ValueStream (BitVec w) × CIRCTStream.DCPlusOp.TokenStream
| Ty.variadicvaluetokenstream w => CIRCTStream.DCPlusOp.VariadicValueStream w × CIRCTStream.DCPlusOp.TokenStream


def_denote for DCPlus where
  | .fst => fun s => [s.fst]ₕ
  | .fstVal _ => fun s => [s.fst]ₕ
  | .fstValPure _ => fun s => [s.fst]ₕ
  | .fstVal' _ => fun s => [s.fst.mapOpt (·[0]?)]ₕ
  | .snd => fun s => [s.snd]ₕ
  | .sndValPure _ => fun s => [s.snd]ₕ
  | .pair _ => fun s₁ s₂ => [(s₁, s₂)]ₕ
  | .sndVal _ => fun s => [s.snd]ₕ
  | .sndVal' _ => fun s => [s.fst.mapOpt (·[0]?)]ₕ
  | .tokVal' _ => fun s => [s.snd]ₕ
  | .merge => fun s₁ s₂ => [CIRCTStream.DCPlusOp.merge s₁ s₂]ₕ
  | .branch => fun s₁ s₂ => [CIRCTStream.DCPlusOp.branch s₁ s₂]ₕ
  | .fork => fun s => [CIRCTStream.DCPlusOp.fork s]ₕ
  | .forkVal => fun s => [CIRCTStream.DCPlusOp.forkVal s]ₕ
  | .join => fun s₁ s₂ => [CIRCTStream.DCPlusOp.join s₁ s₂]ₕ
  | .mux => fun s₁ s₂ c => [CIRCTStream.DCPlusOp.mux s₁ s₂ c]ₕ
  | .muxVal => fun s₁ s₂ c => [CIRCTStream.DCPlusOp.muxVal s₁ s₂ c]ₕ
  | .sink => fun s => [CIRCTStream.DCPlusOp.sink s]ₕ
  | .source => [CIRCTStream.DCPlusOp.source]ₕ
  | .sourceOnes => [CIRCTStream.DCPlusOp.sourceOnes]ₕ
  | .cMerge => fun s₁ s₂ => [CIRCTStream.DCPlusOp.cMerge s₁ s₂]ₕ
  | .supp => fun s₁ s₂ => [CIRCTStream.DCPlusOp.supp s₁ s₂]ₕ
  | .not => fun s₁ => [CIRCTStream.DCPlusOp.not s₁]ₕ

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

def llvm_const_lower_riscv_li_39 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_39, rhs:= liRiscv_39,
   correct := by admit /- proof elided -/

def shl_bad_sub_i32_before := [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 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def foo_before := [llvm|
{
^0(%arg0 : i8, %arg1 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(84 : i8) : i8
  %2 = llvm.mlir.constant(-118 : i8) : i8
  %3 = llvm.mlir.constant(33 : i8) : i8
  %4 = llvm.mlir.constant(-88 : i8) : i8
  %5 = llvm.mlir.constant(5 : i8) : i8
  %6 = llvm.shl %arg0, %0 : i8
  %7 = llvm.and %arg1, %1 : i8
  %8 = llvm.and %arg1, %2 : i8
  %9 = llvm.and %arg1, %3 : i8
  %10 = llvm.sub %4, %7 : i8
  %11 = llvm.and %10, %1 : i8
  %12 = llvm.or %9, %11 : i8
  %13 = llvm.xor %6, %8 : i8
  %14 = llvm.or %12, %13 : i8
  %15 = llvm.lshr %13, %0 : i8
  %16 = llvm.shl %15, %5 : i8
  %17 = llvm.xor %16, %14 : i8
  "llvm.return"(%17) : (i8) -> ()
}
]

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

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

def select_cond_f : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 1)] where
  lhs := [LV| {
    ^entry (%c: i1, %f : i64):
      %0 = llvm.sext %c: i1 to i64
      %1 = llvm.select %c, %0, %f : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%c: i1, %f: i64):
      %0 = llvm.sext %c: i1 to i64
      %1 = llvm.freeze %f : i64
      %2 = llvm.or %0, %1 : i64
      llvm.return %2 : i64
  }]

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

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

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

def shl_or_before := [llvm|
{
^0(%arg67 : i16, %arg68 : i16):
  %0 = llvm.mlir.constant(42 : i16) : i16
  %1 = llvm.mlir.constant(5 : i16) : i16
  %2 = llvm.mlir.constant(7 : i16) : i16
  %3 = llvm.srem %arg68, %0 : i16
  %4 = llvm.shl %arg67, %1 : i16
  %5 = llvm.or %3, %4 : i16
  %6 = llvm.shl %5, %2 : i16
  "llvm.return"(%6) : (i16) -> ()
}
]

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 trunc_shl_7_i8_i64_after := [llvm|
{
^0(%arg37 : i64):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.trunc %arg37 : i64 to i8
  %2 = llvm.shl %1, %0 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

def x : Stream (BitVec 1) := ofList [some 1, none, some 1, some 0, none]

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

instance : Coe Int (AttrValue φ) where
  coe (i: Int) := AttrValue.int i (MLIRType.int .Signless 64)

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 function : Parser :=
  leading_parser argumentList >> arrow >> termParser

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

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

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

def 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 test3_logical_before := [llvm|
{
^0(%arg306 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = "llvm.select"(%arg306, %0, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%1) : (i1) -> ()
}
]

Lean.Name.mkSimple in Init.Prelude

Except.ok in Init.Prelude

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

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 one_side_fold_sgt_after := [llvm|
{
^0(%arg29 : i32, %arg30 : i32, %arg31 : i32, %arg32 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "sgt" %arg30, %arg29 : i32
  %3 = llvm.xor %arg32, %0 : i1
  %4 = "llvm.select"(%3, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def test37_before := [llvm|
{
^0(%arg241 : i32):
  %0 = llvm.mlir.constant(7) : i64
  %1 = llvm.mlir.constant(240) : i64
  %2 = llvm.zext %arg241 : i32 to i64
  %3 = llvm.mul %2, %0 : i64
  %4 = llvm.and %3, %1 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

Mul in Init.Prelude

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

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

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

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

def trunc_nsw_xor_before := [llvm|
{
^0(%arg3 : i8, %arg4 : i8):
  %0 = llvm.xor %arg3, %arg4 : i8
  %1 = llvm.trunc %0 overflow<nsw> : i8 to i1
  "llvm.return"(%1) : (i1) -> ()
}
]

def t4_after := [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.add %2, %arg210 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

Lean.Meta.getSimpCongrTheorems in Lean.Meta.Tactic.Simp.SimpCongrTheorems

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

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

def binopNfa (op : Binop) (m1 m2 : CNFA n) : CNFA n :=
  match op with
  | .and => m1.inter m2
  | .or => m1.union m2
  | .impl => m1.neg.union m2
  | .equiv => (m1.neg.union m2).inter (m2.neg.union m1)

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

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

def neg_mask_before := [llvm|
{
^0(%arg1 : i32, %arg2 : i16):
  %0 = llvm.mlir.constant(15 : 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.lshr %arg2, %0 : i16
  %5 = llvm.zext %4 : i16 to i32
  %6 = llvm.sub %1, %5 overflow<nsw> : i32
  %7 = llvm.and %3, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

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

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 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 slt_and_max_after := [llvm|
{
^0(%arg382 : i8, %arg383 : i8):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

def abs_diff_signed_slt_swap_wrong_pred1_before := [llvm|
{
^0(%arg15 : i32, %arg16 : i32):
  %0 = llvm.icmp "eq" %arg15, %arg16 : i32
  %1 = llvm.sub %arg16, %arg15 overflow<nsw> : i32
  %2 = llvm.sub %arg15, %arg16 overflow<nsw> : i32
  %3 = "llvm.select"(%0, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

def sub_1_before := [llvm|
{
^0(%arg113 : i8, %arg114 : i1, %arg115 : i8, %arg116 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(123 : i8) : i8
  %2 = llvm.xor %arg115, %0 : i8
  %3 = llvm.xor %arg116, %1 : i8
  %4 = "llvm.select"(%arg114, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %5 = llvm.sub %4, %arg113 : i8
  %6 = llvm.xor %5, %0 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

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

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

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

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

def Term.quote (t : _root_.Term) : Expr :=
  match t with
  | ofNat n => mkApp (mkConst ``Term.ofNat) (mkNatLit n)
  | var n => mkApp (mkConst ``Term.var) (mkNatLit n)
  | zero => mkConst ``Term.zero
  | one => mkConst ``Term.one
  | negOne => mkConst ``Term.negOne

  
  | neg t => mkApp (mkConst ``Term.neg) (t.quote)
  | not t => mkApp (mkConst ``Term.not) (t.quote)
  | sub t₁ t₂ => mkApp2 (mkConst ``Term.sub) (t₁.quote) (t₂.quote)
  | add t₁ t₂ => mkApp2 (mkConst ``Term.add) (t₁.quote) (t₂.quote)
  | xor t₁ t₂ => mkApp2 (mkConst ``Term.xor) (t₁.quote) (t₂.quote)
  | or t₁ t₂ => mkApp2 (mkConst ``Term.or) (t₁.quote) (t₂.quote)
  | and t₁ t₂ => mkApp2 (mkConst ``Term.and) (t₁.quote) (t₂.quote)
  | shiftL t₁ n => mkApp2 (mkConst ``Term.shiftL) (t₁.quote) (mkNatLit n)

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

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

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

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

instance : MLIR.AST.TransformReturn (Handshake) 0 where
  mkReturn := mkReturn

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 select_add_before := [llvm|
{
^0(%arg15 : i1, %arg16 : i64, %arg17 : i64):
  %0 = llvm.add %arg16, %arg17 : i64
  %1 = "llvm.select"(%arg15, %0, %arg16) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%1) : (i64) -> ()
}
]

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

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

def c : DCOp.ValueStream Bool := ofList [true, true, none, none, false]

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

def VarRemapVar
  (w': HVector Γ'.Var β) :
  {w : HVector Γ.Var β //
    ∀ (Vstart : Ctxt.Valuation Γstart),
      w.map (lets.denote Vstart)
      = w'.map ((lets.denote Vstart).comap hom)  } :=
    if TY : β = α then
      if H : TY ▸ w' = vnew then
        ⟨TY ▸ vold, by admit /- proof elided -/
          ⟩
      else ⟨w'.map hom, by admit /- proof elided -/
      ⟩
    else ⟨w'.map hom, by admit /- proof elided -/
    ⟩

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

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

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

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

def no_shift_xor_multiuse_cmp_with_xor_after := [llvm|
{
^0(%arg92 : i32, %arg93 : i32, %arg94 : i32, %arg95 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg92, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  %4 = llvm.xor %2, %arg93 : i32
  %5 = llvm.xor %4, %0 : i32
  %6 = "llvm.select"(%3, %arg95, %arg94) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = llvm.mul %5, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

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

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

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

def inter (M N : NFA' n) : NFA' n := ⟨_, M.M.inter N.M⟩

def add_select_not_zext_before := [llvm|
{
^0(%arg27 : i1):
  %0 = llvm.mlir.constant(64) : i64
  %1 = llvm.mlir.constant(1) : i64
  %2 = llvm.mlir.constant(true) : i1
  %3 = "llvm.select"(%arg27, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  %4 = llvm.xor %arg27, %2 : i1
  %5 = llvm.zext %4 : i1 to i64
  %6 = llvm.add %3, %5 : i64
  "llvm.return"(%6) : (i64) -> ()
}
]

Polynomial.coeffs in Mathlib.Algebra.Polynomial.Basic

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

def ashr_add_exact_after := [llvm|
{
^0(%arg2 : i8, %arg3 : i8):
  %0 = llvm.mlir.constant(-14 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.and %arg2, %0 : i8
  %3 = llvm.and %arg3, %1 : i8
  %4 = llvm.ashr exact %2, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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 or_eq_with_one_bit_diff_constants3_after := [llvm|
{
^0(%arg358 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.mlir.constant(126 : i8) : i8
  %2 = llvm.and %arg358, %0 : i8
  %3 = llvm.icmp "eq" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

@[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 tail : Stream α → Stream α := Stream'.tail

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

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

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

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

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

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

def test_xor_ne_before := [llvm|
{
^0(%arg64 : i8, %arg65 : i8, %arg66 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.xor %arg66, %0 : i8
  %2 = llvm.xor %arg65, %0 : i8
  %3 = llvm.xor %2, %arg64 : i8
  %4 = llvm.icmp "ne" %1, %3 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

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

def ex1 := [HSxComb_com| {
  ^entry(%0: !Stream_BitVec_1):
    "return" (%0) : (!Stream_BitVec_1) -> ()
  }]

def logical_and_bitwise_and_icmps_comm1_before := [llvm|
{
^0(%arg217 : i8, %arg218 : i8, %arg219 : 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" %arg218, %0 : i8
  %5 = llvm.and %arg217, %1 : i8
  %6 = llvm.shl %1, %arg219 : i8
  %7 = llvm.and %arg217, %6 : i8
  %8 = llvm.icmp "ne" %5, %2 : i8
  %9 = llvm.icmp "ne" %7, %2 : i8
  %10 = llvm.and %4, %8 : i1
  %11 = "llvm.select"(%9, %10, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%11) : (i1) -> ()
}
]

def zext_zext_ule_op0_wide_before := [llvm|
{
^0(%arg76 : i9, %arg77 : i8):
  %0 = llvm.zext %arg76 : i9 to i32
  %1 = llvm.zext %arg77 : i8 to i32
  %2 = llvm.icmp "ule" %0, %1 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def alive_AddSub_1176_tgt :=
[sllvm| {
^bb0(%a : i64, %b : i64):
  %v1 = llvm.mlir.constant 0 : i64
  %v2 = llvm.sub %v1, %b : i64
  %v3 = llvm.sub %a, %b : i64
  llvm.return %v3 : i64
}]

def add {Γ : Ctxt _} (e₁ e₂ : Var Γ .nat) : Expr Γ .nat :=
  Expr.mk
    (op := .add)
    (ty_eq := rfl)
    (eff_le := EffectKind.pure_le _)
    (args := .cons e₁ <| .cons e₂ .nil)
    (regArgs := .nil)

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

def main4b_logical_before := [llvm|
{
^0(%arg131 : 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(false) : i1
  %4 = llvm.mlir.constant(1 : i32) : i32
  %5 = llvm.and %arg131, %0 : i32
  %6 = llvm.icmp "eq" %5, %0 : i32
  %7 = llvm.and %arg131, %1 : i32
  %8 = llvm.icmp "ne" %7, %2 : i32
  %9 = "llvm.select"(%6, %8, %3) <{"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_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 ashr_pow2_ult_before := [llvm|
{
^0(%arg59 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(-96 : i8) : i8
  %2 = llvm.ashr %0, %arg59 : i8
  %3 = llvm.icmp "ult" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def test_before := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(12 : i32) : i32
  %1 = llvm.mlir.constant(-6 : i32) : i32
  %2 = llvm.sdiv %arg1, %0 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

def State.cseRegionArgList
  {Γstart Γ : Ctxt d.Ty}
  {lets : Lets d Γstart .pure Γ}
  (_ : State d lets)
  {ts : RegionSignature d.Ty}
  (rs : HVector ((fun t => Com d t.1 .impure t.2)) <| ts) :
  {rs' : HVector ((fun t => Com d t.1 .impure t.2)) <| ts //
    HVector.denote rs = HVector.denote rs' } :=
  let _ := HVector.map (fun _Γα com => Com.denote com) rs
  match ts, rs with
  | _, .nil => ⟨.nil, by admit /- proof elided -/
    ⟩
  | ⟨Γ, t⟩::ts, .cons region rs =>
    
    
    
    
    ⟨.cons region rs, by admit /- proof elided -/
    ⟩

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

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

def bitwise_and_logical_and_icmps_comm1_before := [llvm|
{
^0(%arg229 : i8, %arg230 : i8, %arg231 : 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" %arg230, %0 : i8
  %5 = llvm.and %arg229, %1 : i8
  %6 = llvm.shl %1, %arg231 : i8
  %7 = llvm.and %arg229, %6 : i8
  %8 = llvm.icmp "ne" %5, %2 : i8
  %9 = llvm.icmp "ne" %7, %2 : i8
  %10 = "llvm.select"(%4, %8, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %11 = llvm.and %9, %10 : i1
  "llvm.return"(%11) : (i1) -> ()
}
]

Id.run in Init.Control.Id

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

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

def sext_negate_before := [llvm|
{
^0(%arg29 : i1):
  %0 = llvm.mlir.constant(0) : i64
  %1 = llvm.sext %arg29 : i1 to i64
  %2 = llvm.sub %0, %1 : i64
  "llvm.return"(%2) : (i64) -> ()
}
]

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

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

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

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

def sge_smin1_after := [llvm|
{
^0(%arg79 : i32, %arg80 : i32):
  %0 = llvm.icmp "sge" %arg80, %arg79 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

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

def and_to_xor2_after := [llvm|
{
^0(%arg117 : i32, %arg118 : i32):
  %0 = llvm.xor %arg117, %arg118 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def or_or_xor_before := [llvm|
{
^0(%arg106 : i4, %arg107 : i4, %arg108 : i4):
  %0 = llvm.or %arg108, %arg106 : i4
  %1 = llvm.or %arg108, %arg107 : i4
  %2 = llvm.xor %0, %1 : i4
  "llvm.return"(%2) : (i4) -> ()
}
]

structure Deterministic (M : NFA α σ) : Prop where
  start : M.start.Subsingleton
  step : ∀ q a, M.step q a |>.Subsingleton

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

def t10_constants_after := [llvm|
{
^0(%arg14 : i32, %arg15 : i64):
  %0 = llvm.mlir.constant(26 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.trunc %arg15 : i64 to i32
  %3 = llvm.lshr %arg14, %0 : i32
  %4 = llvm.and %3, %2 : i32
  %5 = llvm.icmp "ne" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

def test15_after := [llvm|
{
^0(%arg24 : i1):
  %0 = llvm.mlir.constant(12 : i45) : i45
  %1 = llvm.mlir.constant(4 : i45) : i45
  %2 = "llvm.select"(%arg24, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i45, i45) -> i45
  "llvm.return"(%2) : (i45) -> ()
}
]

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

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

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

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

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

def not_match_inconsistent_signs_before := [llvm|
{
^0(%arg13 : i64):
  %0 = llvm.mlir.constant(299) : i64
  %1 = llvm.mlir.constant(64) : i64
  %2 = llvm.urem %arg13, %0 : i64
  %3 = llvm.sdiv %arg13, %0 : i64
  %4 = llvm.urem %3, %1 : i64
  %5 = llvm.mul %4, %0 : i64
  %6 = llvm.add %2, %5 : i64
  "llvm.return"(%6) : (i64) -> ()
}
]

def or_xor_xor_normal_variant3_after := [llvm|
{
^0(%arg13 : i16, %arg14 : i16):
  %0 = llvm.xor %arg14, %arg13 : i16
  "llvm.return"(%0) : (i16) -> ()
}
]

@[simp_denote]
def zext_llvm_16_to_64 := [LV| {
  ^entry (%arg: i16):
    %0 = llvm.zext %arg: i16 to i64
    llvm.return %0: i64
  }]

def DCFork := [DC_com| {
  ^entry(%0 : !ValueStream_8):
    %unpack12 = "DC.unpack" (%0) : (!ValueStream_8) -> (!ValueTokenStream_8)
    %unpack1 = "DC.fstVal" (%unpack12) : (!ValueTokenStream_8) -> (!ValueStream_8)
    %unpack2 = "DC.sndVal" (%unpack12) : (!ValueTokenStream_8) -> (!TokenStream)
    %fork12 = "DC.fork" (%unpack2) : (!TokenStream) -> (!TokenStream2)
    %fork1 = "DC.fst" (%fork12) : (!TokenStream2) -> (!TokenStream)
    %fork2 = "DC.snd" (%fork12) : (!TokenStream2) -> (!TokenStream)
    %pack1 = "DC.pack" (%unpack1, %fork1) : (!ValueStream_8, !TokenStream) -> (!ValueStream_8)
    %pack2 = "DC.pack" (%unpack1, %fork2) : (!ValueStream_8, !TokenStream) -> (!ValueStream_8)
    %pack12 = "DC.pair" (%pack1, %pack2) : (!ValueStream_8, !ValueStream_8) -> (!ValueStream2_8)
    "return" (%pack12) : (!ValueStream2_8) -> ()
  }]

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

def or_basic_before := [llvm|
{
^0(%arg15 : i16):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.mlir.constant(-256 : i16) : i16
  %2 = llvm.mlir.constant(17664 : i16) : i16
  %3 = llvm.trunc %arg15 : i16 to i8
  %4 = llvm.icmp "ne" %3, %0 : i8
  %5 = llvm.and %arg15, %1 : i16
  %6 = llvm.icmp "ne" %5, %2 : i16
  %7 = llvm.or %4, %6 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

abbrev BitVecs' (n : Nat) := List (BitVec n)

List.range in Init.Data.List.Basic
</all_available_defs>

<all_available_lemmas>
BitVec.lt_def in Init.Data.BitVec.Lemmas
BitVec.of_length_zero in Init.Data.BitVec.Lemmas
BitVec.ult_eq_not_carry in Init.Data.BitVec.Bitblast

@[simp] theorem subAux_eq_BitVec_carry (a b : BitStream) (w i : Nat) (hi : i < w) :
    (a.subAux b i).2 = !(BitVec.carry (i + 1) (a.toBitVec w) ((~~~b).toBitVec w) true)

theorem zext_nneg_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(True ∧ (x &&& 32767#16).msb = true) →
    zeroExtend 24 (x &&& 32767#16) &&& 8388607#24 = zeroExtend 24 (x &&& 32767#16)

theorem udiv400_proof : udiv400_before ⊑ udiv400_after

theorem a_false_implies_b_true2_proof : a_false_implies_b_true2_before ⊑ a_false_implies_b_true2_after

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

theorem add_umax_simplify2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.uaddOverflow 57#32 = true) → ¬ofBool (56#32 <ᵤ x + 57#32) = 1#1 → 56#32 = x + 57#32

@[simp] theorem appendList_eq : Γ ++ tys = Γ ++ ⟨tys⟩

theorem ne_smax2_proof : ne_smax2_before ⊑ ne_smax2_after

theorem select_icmp_ne_0_and_8_xor_1073741824_proof : select_icmp_ne_0_and_8_xor_1073741824_before ⊑ select_icmp_ne_0_and_8_xor_1073741824_after

theorem icmp_ne_sext_slt_otherwise_nofold_proof : icmp_ne_sext_slt_otherwise_nofold_before ⊑ icmp_ne_sext_slt_otherwise_nofold_after

@[simp] theorem HVector.changeDialect_nil {eff : EffectKind} (f : DialectMorphism d d') :
    HVector.changeDialect (eff := eff) f nil = nil

@[simp]
lemma CNFA.lift_bv_language {m : CNFA n1} {f : Fin n1 → Fin n2} :
    m.bv_recognizes L → (m.lift f |>.bv_recognizes (BitVecs.transport f ⁻¹' L))

theorem and_ashr_not_thm (e e_1 e_2 : IntW 8) :
  LLVM.and (ashr e_2 e_1) (LLVM.xor (ashr e e_1) (const? 8 (-1))) ⊑
    ashr (LLVM.and e_2 (LLVM.xor e (const? 8 (-1)))) e_1

theorem nonexact_ashr_ne_proof : nonexact_ashr_ne_before ⊑ nonexact_ashr_ne_after

theorem n6_proof : n6_before ⊑ n6_after

theorem pv_proof : pv_before ⊑ pv_after

theorem trunc_shl_nsw_31_i32_i64_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ (x <<< 31#64).sshiftRight' 31#64 ≠ x ∨ 31#64 ≥ ↑64) → 31#32 ≥ ↑32 → False

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

theorem e_2022 :
     - 1 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 5 * (d &&& f) + 1 * ((e &&& f) ||| (d &&& (e ||| f))) - 2 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 1 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 7 *  ~~~(d &&& (e &&& f)) + 2 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 11 * ((d ^^^ e) ||| (d ^^^ f)) + 2 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 1 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 3 *  ~~~(d ^^^ (e &&& f)) - 1 * (f ^^^ ( ~~~d ||| (e &&& f))) + 1 *  ~~~(d &&& ( ~~~e &&& f)) + 2 * (f ^^^ (d ||| ( ~~~e &&& f))) + 4 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 1 * f - 2 *  ~~~( ~~~d ||| (e &&& f)) - 6 * (e ^^^ (d ||| f)) - 7 * ( ~~~f &&& (d ^^^ e)) + 4 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 7 * (e &&&  ~~~f) + 3 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 5 *  ~~~( ~~~d &&& (e ||| f)) + 1 * ( ~~~d ||| (e ||| f)) + 11 * (d &&& ( ~~~e ||| f)) + 2 * ( ~~~d &&& (e ||| f)) + 1 * ((d ^^^ e) &&& (d ^^^ f)) - 9 *  ~~~(d ||| (e ||| f)) - 3 *  ~~~(d ||| ( ~~~e ||| f)) - 24 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 9 * ( ~~~d &&& ( ~~~e &&& f)) - 15 * ( ~~~d &&& (e &&& f)) - 29 * (d &&& ( ~~~e &&& f)) - 26 * (d &&& (e &&& f)) = 12 *  ~~~( ~~~d ||| (e ||| f))

theorem is_rem4_neg_i16_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(4#16 == 0 || 16 != 1 && x == intMin 16 && 4#16 == -1) = true →
    ofBool (x.srem 4#16 <ₛ 0#16) = ofBool (BitVec.ofInt 16 (-32768) <ᵤ x &&& BitVec.ofInt 16 (-32765))

theorem mul32_low_proof : mul32_low_before ⊑ mul32_low_after

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

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

theorem test_thm.extracted_1._2 : ∀ (x : BitVec 31),
  ¬15#32 ≥ ↑32 →
    ¬(True ∧ (zeroExtend 32 x).uaddOverflow 16384#32 = true ∨ 15#32 ≥ ↑32) →
      truncate 16 ((signExtend 32 x + 16384#32) >>> 15#32) = truncate 16 ((zeroExtend 32 x + 16384#32) >>> 15#32)

@[simp] lemma BitVec.lk10 : (1#2 : BitVec 2)[0] = true

theorem not_or_or_and_not_and_and_commute1_proof : not_or_or_and_not_and_and_commute1_before ⊑ not_or_or_and_not_and_and_commute1_after

@[simp]
lemma swapLastTwo_eq1' : swapLastTwo (n := n) (Fin.last (n + 1)) = n

theorem t1_lshr_proof : t1_lshr_before ⊑ t1_lshr_after

theorem negate_add_with_single_negatible_operand_depth2_proof : negate_add_with_single_negatible_operand_depth2_before ⊑ negate_add_with_single_negatible_operand_depth2_after

theorem ashrslt_01_08_exact_proof : ashrslt_01_08_exact_before ⊑ ashrslt_01_08_exact_after

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

theorem add_constant_equal_with_the_top_bit_of_demandedbits_pass_proof : add_constant_equal_with_the_top_bit_of_demandedbits_pass_before ⊑ add_constant_equal_with_the_top_bit_of_demandedbits_pass_after

theorem test_invalid_simplify_eq2_proof : test_invalid_simplify_eq2_before ⊑ test_invalid_simplify_eq2_after

theorem sub_select_not_zext_proof : sub_select_not_zext_before ⊑ sub_select_not_zext_after

theorem zext_zext_sgt_proof : zext_zext_sgt_before ⊑ zext_zext_sgt_after

theorem e_2091 :
     - 1 * (d ||| ( ~~~e ||| f)) - 6 * (d &&& (e ^^^ f)) + 3 * (d &&& ( ~~~e ||| f)) + 1 * ((d &&& f) ^^^ (e ||| f)) - 11 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 6 * (d ^^^ ( ~~~e ||| f)) - 11 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 *  ~~~(d ||| (e ^^^ f)) + 11 * ( ~~~f &&& (d ^^^ e)) - 2 * ((d |||  ~~~e) &&& (e ^^^ f)) + 2 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 4 *  ~~~(e |||  ~~~f) + 1 * (f ^^^  ~~~(d &&&  ~~~e)) - 1 * ( ~~~f &&&  ~~~(d ^^^ e)) + 1 * (e ^^^ (d ||| ( ~~~e &&& f))) - 2 *  ~~~(d &&& (e &&& f)) - 3 *  ~~~(d &&&  ~~~e) - 1 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 7 *  ~~~(d ^^^ ( ~~~e ||| f)) + 2 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 1 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 5 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 11 * (f ^^^ (d ||| (e &&& f))) + 2 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 1 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 6 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 3 * (f &&& (d ^^^ e)) - 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 3 * (e ^^^ (d |||  ~~~f)) + 2 *  ~~~(d &&&  ~~~d) - 11 *  ~~~(d &&& (e ^^^ f)) - 11 * (d ^^^ ( ~~~e &&& f)) + 1 * (f ^^^  ~~~(d &&& e)) + 2 * (f ^^^  ~~~(d |||  ~~~e)) + 50 *  ~~~(d ||| (e ||| f)) + 8 *  ~~~(d ||| ( ~~~e ||| f)) - 1 *  ~~~( ~~~d ||| (e ||| f)) + 34 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 38 * ( ~~~d &&& ( ~~~e &&& f)) + 22 * ( ~~~d &&& (e &&& f)) + 5 * (d &&& ( ~~~e &&& f)) + 43 * (d &&& (e &&& f)) = 11 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f)))

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

theorem mul_add_to_mul_6_proof : mul_add_to_mul_6_before ⊑ mul_add_to_mul_6_after

theorem udiv_i32_thm (e e_1 : IntW 8) : LLVM.udiv (zext 32 e_1) (zext 32 e) ⊑ zext 32 (LLVM.udiv e_1 e)

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

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

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

theorem nonexact_ashr_ne_proof : nonexact_ashr_ne_before ⊑ nonexact_ashr_ne_after

@[simp]
lemma transSetBV_spec {m : CNFA n} {ss : BitVec m.m.stateMax} :
    s' ∈ bv_to_set (m.m.transSetBV ss a) ↔
      ∃ s ∈ bv_to_set ss, s' ∈ m.m.tr s a

theorem sub_ult_zext_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 x_2 : BitVec 8),
  ofBool (x_2 - x_1 <ᵤ zeroExtend 8 x) = ofBool (x_2 == x_1) &&& x

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

theorem bv_InstCombineShift__279 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.shl (LLVM.lshr e e_1) e_1 ⊑ LLVM.and e (LLVM.shl (LLVM.const? w (-1)) e_1)

theorem test29_proof : test29_before ⊑ test29_after

theorem lt_signed_to_large_negative_proof : lt_signed_to_large_negative_before ⊑ lt_signed_to_large_negative_after

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

theorem not_signbit_splat_mask2_thm (e : IntW 16) (e_1 : IntW 8) :
  LLVM.and (sext 16 (ashr e_1 (const? 8 6))) e ⊑ LLVM.and e (sext 16 (ashr e_1 (const? 8 6)))

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

theorem logic_or_logic_and_4_thm (e e_1 e_2 : IntW 1) :
  select (select e_2 (const? 1 1) e_1) (select e (const? 1 1) e_2) (const? 1 0) ⊑
    select e_2 (const? 1 1) (select e_1 e (const? 1 0))

theorem test_shl__nuw_is_safe_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 1073741822#32 == 0#32) = 1#1 →
    ¬(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 →
        False

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

theorem ashrslt_01_11_exact_proof : ashrslt_01_11_exact_before ⊑ ashrslt_01_11_exact_after

theorem test_invalid_simplify_eq2_thm (e : IntW 8) :
  select (icmp IntPred.eq e (const? 8 2)) (const? 8 0) (sub e (const? 8 1)) ⊑
    select (icmp IntPred.eq e (const? 8 2)) (const? 8 0) (add e (const? 8 (-1)))

theorem shl_and_lshr_proof : shl_and_lshr_before ⊑ shl_and_lshr_after

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

theorem sext_sub_nuw_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 8),
  ¬(True ∧ x_1.usubOverflow (signExtend 8 x) = true) → x_1 - signExtend 8 x = x_1 + zeroExtend 8 x

theorem e_786 :
     - 1 *  ~~~t - 1 * (z |||  ~~~t) - 7 * z + 2 *  ~~~(z ||| t) + 9 * (z &&&  ~~~t) =  - 8 * (z &&& t)

theorem positive_with_icmp_logical_thm (e : IntW 32) :
  select (icmp IntPred.ult e (const? 32 512)) (icmp IntPred.ult (add e (const? 32 128)) (const? 32 256))
      (const? 1 0) ⊑
    icmp IntPred.ult e (const? 32 128)

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

theorem not_or_or_and_no_and_commute1_or_proof : not_or_or_and_no_and_commute1_or_before ⊑ not_or_or_and_no_and_commute1_or_after

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

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

theorem p_commutative0_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ (x_2 &&& x_1 &&& (x &&& (x_2 ^^^ -1#32)) != 0) = true) →
    x_2 &&& x_1 ||

theorem c0_thm (e : IntW 8) :
  icmp IntPred.sgt (LLVM.and e (const? 8 3)) e ⊑ icmp IntPred.slt e (const? 8 0)

theorem xor_or_xor_common_op_commute7_proof : xor_or_xor_common_op_commute7_before ⊑ xor_or_xor_common_op_commute7_after

theorem pr51551_neg1_proof : pr51551_neg1_before ⊑ pr51551_neg1_after

theorem tryFactorization_add_nuw_mul_proof : tryFactorization_add_nuw_mul_before ⊑ tryFactorization_add_nuw_mul_after

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

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

theorem and_or2_wrong_operand_thm.extracted_1._3 : ∀ (x x_1 x_2 x_3 : BitVec 1),
  (x_3 ^^^ 1#1) &&& x_2 = 1#1 → ¬x_2 &&& (x_3 ^^^ 1#1) = 1#1 → x_1 = x

theorem test11_logical_proof : test11_logical_before ⊑ test11_logical_after

theorem t2_thm (e : IntW 7) : sext 16 (trunc 4 (lshr e (const? 7 3))) ⊑ sext 16 (ashr e (const? 7 3))

theorem icmp_ne_and_pow2_minus1_shl1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → zeroExtend 32 (ofBool (1#32 <<< x &&& 15#32 != 0#32)) = zeroExtend 32 (ofBool (x <ᵤ 4#32))

theorem test15i_proof : test15i_before ⊑ test15i_after

theorem PR2844_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x == 0#32) = 1#1 →
    True → 0#32 = zeroExtend 32 (ofBool (x != 0#32) &&& ofBool (BitVec.ofInt 32 (-638208502) <ₛ x))

theorem ashr_ult_6_proof : ashr_ult_6_before ⊑ ashr_ult_6_after

theorem not_not_cmp_proof : not_not_cmp_before ⊑ not_not_cmp_after

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

theorem main7b_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 == x_1 &&& x) = 1#1 → 0#32 = zeroExtend 32 (ofBool (x != x_1 &&& x))

theorem bor_lor_left2_proof : bor_lor_left2_before ⊑ bor_lor_left2_after

theorem const_sub_add_const_proof : const_sub_add_const_before ⊑ const_sub_add_const_after

theorem and_two_ranges_to_mask_and_range_no_add_on_one_range_proof : and_two_ranges_to_mask_and_range_no_add_on_one_range_before ⊑ and_two_ranges_to_mask_and_range_no_add_on_one_range_after

theorem ashrslt_02_06_proof : ashrslt_02_06_before ⊑ ashrslt_02_06_after

theorem ashr_lshr_exact_ashr_only_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (-1#32 <ₛ x_1) = 1#1 → ¬x ≥ ↑32 → x_1 >>> x = x_1.sshiftRight' x

theorem lshrugt_02_12_exact_proof : lshrugt_02_12_exact_before ⊑ lshrugt_02_12_exact_after

theorem lshr_and_or_disjoint_thm (e e_1 : IntW 8) :
  shl (LLVM.or (LLVM.srem e_1 (const? 8 42)) (LLVM.and (lshr e (const? 8 2)) (const? 8 13)) { «disjoint» := true })
      (const? 8 2) ⊑
    LLVM.or (LLVM.and e (const? 8 52)) (shl (LLVM.srem e_1 (const? 8 42)) (const? 8 2)) { «disjoint» := true }

theorem ashr_lshr_shift_base_mismatch_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (0#32 ≤ₛ x_1) = 1#1 → ¬x ≥ ↑32 → ofBool (x_1 <ₛ 0#32) = 1#1 ∨ x ≥ ↑32 → False

theorem ule_or_min_proof : ule_or_min_before ⊑ ule_or_min_after

theorem test_nuw_nsw_and_unsigned_pred_proof : test_nuw_nsw_and_unsigned_pred_before ⊑ test_nuw_nsw_and_unsigned_pred_after

theorem lshrult_03_03_exact_proof : lshrult_03_03_exact_before ⊑ lshrult_03_03_exact_after

theorem test_eq_11_and_15_add_10_proof : test_eq_11_and_15_add_10_before ⊑ test_eq_11_and_15_add_10_after

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

theorem ashrslt_02_09_exact_proof : ashrslt_02_09_exact_before ⊑ ashrslt_02_09_exact_after

theorem both_sides_fold_eq_thm.extracted_1._3 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → ofBool (x == x) = x_1 ^^^ 1#1

theorem select_icmp_ne_0_and_32_xor_4096_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (0#32 != x_1 &&& 32#32) = 1#1 → 7#32 ≥ ↑32 → False

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

theorem positive_trunc_signbit_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.sgt (trunc 8 e) (const? 8 (-1)))
      (icmp IntPred.ult (add e (const? 32 128)) (const? 32 256)) ⊑
    icmp IntPred.ult e (const? 32 128)

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7b_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7b_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7b_after

theorem masked_and_notA_slightly_optimized_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (8#32 ≤ᵤ x) &&& ofBool (x &&& 39#32 != x) = ofBool (x &&& BitVec.ofInt 32 (-40) != 0#32)

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

theorem and_or3_thm.extracted_1._8 : ∀ (x : BitVec 1) (x_1 x_2 : BitVec 32) (x_3 : BitVec 1),
  ¬x_3 &&& ofBool (x_2 == x_1) = 1#1 → ¬x_3 = 1#1 → x_3 = 0#1

theorem select_xor_icmp_bad_6_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 != 1#32) = 1#1 → ofBool (x_1 == 1#32) = 1#1 → x_1 ^^^ x = x ^^^ 1#32

theorem test4_proof : test4_before ⊑ test4_after

theorem test5_proof : test5_before ⊑ test5_after

theorem test5_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬1#32 ≥ ↑32 →
    ¬(1#32 ≥ ↑32 ∨ True ∧ (x.sshiftRight' 1#32).saddOverflow 1073741823#32 = true) →
      signExtend 64 (x.sshiftRight' 1#32) + 1073741823#64 = signExtend 64 (x.sshiftRight' 1#32 + 1073741823#32)

theorem icmp_ne_and_pow2_shl1_proof : icmp_ne_and_pow2_shl1_before ⊑ icmp_ne_and_pow2_shl1_after

theorem shl_add_nuw_proof : shl_add_nuw_before ⊑ shl_add_nuw_after

theorem ne_umax4_proof : ne_umax4_before ⊑ ne_umax4_after

theorem test20_proof : test20_before ⊑ test20_after

theorem nonexact_lshr_eq_noexactlog_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → ofBool (90#8 >>> x == 30#8) = 0#1

theorem ashrsgt_03_00_exact_thm (e : IntW 4) :
  icmp IntPred.sgt (ashr e (const? 4 3) { «exact» := true }) (const? 4 0) ⊑ const? 1 0

theorem icmp_sle2_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (x <<< 1#8).sshiftRight' 1#8 ≠ x ∨ 1#8 ≥ ↑8) →
    ofBool (x <<< 1#8 ≤ₛ BitVec.ofInt 8 (-127)) = ofBool (x <ₛ BitVec.ofInt 8 (-63))

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_2_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_2_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_2_after

theorem test4c_proof : test4c_before ⊑ test4c_after

theorem shl_add_log_may_cause_poison_pr62175_with_nuw_proof : shl_add_log_may_cause_poison_pr62175_with_nuw_before ⊑ shl_add_log_may_cause_poison_pr62175_with_nuw_after

theorem lshrult_01_06_exact_proof : lshrult_01_06_exact_before ⊑ lshrult_01_06_exact_after

theorem eq_21_comm_eq_thm (e e_1 : IntW 32) :
  LLVM.and (icmp IntPred.eq (trunc 8 (lshr e_1 (const? 32 16))) (trunc 8 (lshr e (const? 32 16))))
      (icmp IntPred.eq (trunc 8 (lshr e (const? 32 8))) (trunc 8 (lshr e_1 (const? 32 8)))) ⊑
    icmp IntPred.eq (trunc 16 (lshr e_1 (const? 32 8))) (trunc 16 (lshr e (const? 32 8)))

theorem p_commutative0_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  True ∧ (x_2 &&& x_1 &&& (x &&& (x_2 ^^^ -1#32)) != 0) = true → False

theorem main5c_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 →
      ¬ofBool (x &&& 7#32 != 7#32) = 1#1 → 1#32 = zeroExtend 32 (ofBool (x &&& 7#32 == 7#32))

theorem test1_proof : test1_before ⊑ test1_after

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

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

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

theorem Tensor2d'.transpose_transpose (t : Tensor2d' α) : t.transpose.transpose = t

theorem ashrsgt_01_14_exact_proof : ashrsgt_01_14_exact_before ⊑ ashrsgt_01_14_exact_after

theorem no_shift_xor_multiuse_cmp_thm.extracted_1._8 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ¬ofBool (0#32 != x_3 &&& 4096#32) = 1#1 →
    ¬ofBool (x_3 &&& 4096#32 == 0#32) = 1#1 → (x_2 ||| 4096#32) * x = (x_2 ||| x_3 &&& 4096#32 ^^^ 4096#32) * x_1

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

theorem and_or_not_not_commute6_proof : and_or_not_not_commute6_before ⊑ and_or_not_not_commute6_after

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

theorem udiv_i32_c_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬10#32 = 0 → ¬(10#8 = 0 ∨ True ∧ (x / 10#8).msb = true) → zeroExtend 32 x / 10#32 = zeroExtend 32 (x / 10#8)

theorem p0_thm (e : IntW 8) :
  icmp IntPred.eq (ashr (shl e (const? 8 5)) (const? 8 5) { «exact» := true }) e ⊑
    icmp IntPred.ult (add e (const? 8 4)) (const? 8 8)

theorem demorganize_constant2_thm (e : IntW 32) :
  LLVM.xor (LLVM.or e (const? 32 15)) (const? 32 (-1)) ⊑
    LLVM.xor (LLVM.and e (const? 32 (-16))) (const? 32 (-16))

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

theorem test3_proof : test3_before ⊑ test3_after

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

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

@[simp]
theorem BitVec.intCast_zero : ((0 : Int) : BitVec w) = 0#w

theorem shl_sub_lshr_reverse_proof : shl_sub_lshr_reverse_before ⊑ shl_sub_lshr_reverse_after

theorem or_eq_with_one_bit_diff_constants2_logical_proof : or_eq_with_one_bit_diff_constants2_logical_before ⊑ or_eq_with_one_bit_diff_constants2_logical_after

theorem test38_thm.extracted_1._1 : ∀ (x : BitVec 32),
  zeroExtend 64 (zeroExtend 8 (ofBool (x == BitVec.ofInt 32 (-2))) ^^^ 1#8) =
    zeroExtend 64 (ofBool (x != BitVec.ofInt 32 (-2)))

theorem AvoidCollision_signExtend_xor {x y : BitVec w} :
    (x ^^^ y).signExtend v = (x.signExtend v) ^^^ (y.signExtend v)

theorem test67_thm (e : IntW 1) (e_1 : IntW 32) :
  icmp IntPred.eq
      (trunc 8
        (ashr
          (LLVM.xor
            (shl (LLVM.and e_1 (LLVM.xor (zext 32 e) (const? 32 1))) (const? 32 24) { «nsw» := true, «nuw» := true })
            (const? 32 (-16777216)))
          (const? 32 24) { «exact» := true }))
      (const? 8 0) ⊑
    const? 1 0

theorem sgt_and_min_proof : sgt_and_min_before ⊑ sgt_and_min_after

theorem e_2099 :
    3 *  ~~~(d ||| ( ~~~e &&& f)) - 11 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 11 * ( ~~~f &&&  ~~~(d ^^^ e)) - 2 * (f &&&  ~~~(d &&& e)) - 7 * (e ^^^ (d ||| f)) - 5 * ((d ^^^ e) ||| (d ^^^ f)) + 3 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 3 * (e ^^^  ~~~(d &&& f)) - 1 *  ~~~(d ||| (e ^^^ f)) + 7 * (d &&&  ~~~f) - 1 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 4 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 6 * ( ~~~f |||  ~~~(d ^^^ e)) - 3 * (f |||  ~~~(d ^^^ e)) - 2 * (e ^^^ ( ~~~d ||| (e ||| f))) + 1 * (f ^^^ ( ~~~d ||| (e &&& f))) + 7 * (f ^^^ (d &&&  ~~~e)) + 1 * (f ^^^ ( ~~~d ||| (e ||| f))) + 1 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * ((d ^^^ e) &&& (d ^^^ f)) - 2 * (f |||  ~~~(d |||  ~~~e)) - 2 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 2 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 7 *  ~~~(d |||  ~~~e) - 5 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 6 * ( ~~~d ||| ( ~~~e ||| f)) + 1 * ( ~~~d ||| (e ||| f)) + 2 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 1 * (e |||  ~~~(d ||| f)) + 4 * (e ^^^  ~~~(d &&& (e &&& f))) - 1 * ( ~~~d ||| (e &&& f)) + 1 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 7 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 3 * ((d &&& e) |||  ~~~(e ||| f)) + 18 *  ~~~(d ||| (e ||| f)) + 33 *  ~~~(d ||| ( ~~~e ||| f)) + 21 *  ~~~( ~~~d ||| (e ||| f)) + 28 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 15 * ( ~~~d &&& ( ~~~e &&& f)) + 15 * ( ~~~d &&& (e &&& f)) + 20 * (d &&& ( ~~~e &&& f)) + 17 * (d &&& (e &&& f)) = 1 * (f ||| (d &&&  ~~~e))

theorem denote_multiRewritePeepholeAt (fuel : ℕ)
  (prs : List (Σ Γ, Σ ty, PeepholeRewrite d Γ ty)) (ix : ℕ) (target : Com d Γ₂ eff t₂) :
    (multiRewritePeepholeAt fuel prs ix target).denote = target.denote

theorem logical_or_logical_or_icmps_comm3_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 8),
  ¬x_1 ≥ ↑8 →
    ¬(ofBool (x_2 &&& 1#8 <<< x_1 == 0#8) = 1#1 ∨ ofBool (x_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 → False

theorem e_772 :
    4 *  ~~~(z &&&  ~~~z) + 4 *  ~~~(z &&&  ~~~t) - 6 * (z ^^^ t) - 2 *  ~~~(z |||  ~~~t) - 8 * (z &&& t) = 8 *  ~~~(z ||| t) - 2 * (z &&&  ~~~t)

theorem add_nosignbit_select_shl_proof : add_nosignbit_select_shl_before ⊑ add_nosignbit_select_shl_after

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

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

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

theorem mul8_low_miss_half_width_proof : mul8_low_miss_half_width_before ⊑ mul8_low_miss_half_width_after

theorem foo_thm.extracted_1._1 : ∀ (x x_1 : BitVec 64),
  zeroExtend 64 (truncate 32 x_1 &&& truncate 32 x) = x_1 &&& x &&& 4294967295#64

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

theorem logical_and_bitwise_and_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 ∨ ofBool (x_1 &&& 1#8 <<< x != 0#8) = 1#1 → False

theorem zext_nneg_i1_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬(True ∧ x.msb = true) → zeroExtend 32 x = 0#32

theorem test9_thm.extracted_1._1 : ∀ (x : BitVec 77), True ∧ (x &&& 562949953421310#77 &&& 1#77 != 0) = true → False

theorem sdiv4_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.smod 3#32 ≠ 0 ∨ (3#32 == 0 || 32 != 1 && x == intMin 32 && 3#32 == -1) = true) → x.sdiv 3#32 * 3#32 = x

theorem e_1863 :
     - 7 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) - 6 *  ~~~b + 4 *  ~~~(a &&&  ~~~b) + 7 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 5 * (b ^^^ (a &&& ( ~~~b ||| c))) + 7 * ((b &&& c) ||| (a &&& (b ||| c))) - 2 * (a |||  ~~~b) + 5 * (b |||  ~~~(a |||  ~~~c)) + 7 *  ~~~(a &&& c) + 2 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) + 1 *  ~~~(a &&& b) + 1 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) + 4 *  ~~~(b &&& c) + 5 *  ~~~(b |||  ~~~c) + 1 * ((a &&& b) |||  ~~~(b ^^^ c)) - 2 * ( ~~~(a ||| b) ||| (b ^^^ c)) - 1 * (b ||| (a ^^^ c)) - 11 * (a &&& (b ^^^ c)) + 11 *  ~~~(a &&& (b &&& c)) - 7 * (b ^^^ ( ~~~a ||| (b ^^^ c))) + 2 * (b ^^^ (a &&&  ~~~c)) + 3 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) - 11 * (c ^^^  ~~~(a &&& ( ~~~b ||| c))) - 11 * (c ^^^ (a |||  ~~~b)) - 2 * (c &&&  ~~~(a &&& b)) + 4 * ( ~~~b &&&  ~~~(a ^^^ c)) - 2 * ( ~~~a &&& (b ||| c)) - 3 * (a ||| (b &&& c)) - 7 * (b ^^^ (a &&& c)) - 1 *  ~~~(a ^^^ (b ^^^ c)) + 2 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) + 11 * (b ^^^ ( ~~~a &&& (b ||| c))) + 1 * ((a &&& c) ^^^ (a ^^^ (b &&& c))) - 2 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) + 2 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) - 7 * (a &&& c) - 1 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) + 4 * (b ^^^ (a &&& (b ||| c))) + 1 * (a &&& (b ||| c)) + 3 *  ~~~(a ||| (b ||| c)) - 21 *  ~~~(a ||| ( ~~~b ||| c)) - 11 *  ~~~( ~~~a ||| (b ||| c)) - 4 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 30 * ( ~~~a &&& ( ~~~b &&& c)) - 32 * ( ~~~a &&& (b &&& c)) + 13 * (a &&& ( ~~~b &&& c)) = 1 * (b ^^^ (a ||| (b &&& c))) + 6 * (a &&& (b &&& c))

theorem trunc_shl_lshr_infloop_thm (e : IntW 64) :
  trunc 32 (shl (lshr e (const? 64 1)) (const? 64 2)) ⊑
    LLVM.and (shl (trunc 32 e) (const? 32 1)) (const? 32 (-4))

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

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 demorgan_nand_proof : demorgan_nand_before ⊑ demorgan_nand_after

theorem neg_nsw_sgt_1_proof : neg_nsw_sgt_1_before ⊑ neg_nsw_sgt_1_after

theorem lshrult_01_08_proof : lshrult_01_08_before ⊑ lshrult_01_08_after

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

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

theorem substitute_constant_and_eq_eq_logical_proof : substitute_constant_and_eq_eq_logical_before ⊑ substitute_constant_and_eq_eq_logical_after

theorem or_ashr_not_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 ||

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

theorem set_bits_thm.extracted_1._4 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  ¬x_1 = 1#1 →
    ¬(True ∧ (x &&& BitVec.ofInt 8 (-6) &&& 0#8 != 0) = true) →
      x &&& BitVec.ofInt 8 (-6) = x &&& BitVec.ofInt 8 (-6) ||

theorem not_or_or_and_no_and_commute2_or_proof : not_or_or_and_no_and_commute2_or_before ⊑ not_or_or_and_no_and_commute2_or_after

theorem test95_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬6#8 ≥ ↑8 →
    6#8 ≥ ↑8 ∨
        True ∧ (truncate 8 x >>> 6#8 &&& 2#8 &&& 40#8 != 0) = true ∨
          True ∧ (truncate 8 x >>> 6#8 &&& 2#8 ||| 40#8).msb = true →
      False

theorem sub_from_constant_commute_thm (e e_1 : IntW 5) :
  add (mul e_1 e_1) (sub (const? 5 10) e { «nsw» := true, «nuw» := false }) { «nsw» := true, «nuw» := false } ⊑
    add (sub (mul e_1 e_1) e) (const? 5 10)

theorem select_bittest_to_shl_negative_test_proof : select_bittest_to_shl_negative_test_before ⊑ select_bittest_to_shl_negative_test_after

theorem lshr_and_or_disjoint_proof : lshr_and_or_disjoint_before ⊑ lshr_and_or_disjoint_after

theorem logical_and_logical_and_icmps_comm1_proof : logical_and_logical_and_icmps_comm1_before ⊑ logical_and_logical_and_icmps_comm1_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 test15a_thm.extracted_1._1 : ∀ (x : BitVec 1),
  x = 1#1 → ¬zeroExtend 53 3#8 ≥ ↑53 → 64#53 <<< zeroExtend 53 3#8 = 512#53

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

theorem zext_sub_const_proof : zext_sub_const_before ⊑ zext_sub_const_after

theorem test_negative_nuw_and_signed_pred_proof : test_negative_nuw_and_signed_pred_before ⊑ test_negative_nuw_and_signed_pred_after

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

theorem e_385 :
     - 2 *  ~~~(x &&& y) + 2 *  ~~~x + 7 *  ~~~(x &&&  ~~~y) - 5 * (x |||  ~~~y) - 11 * x - 7 *  ~~~(x |||  ~~~y) + 20 * (x &&&  ~~~y) + 9 * (x &&& y) = 2 *  ~~~y

theorem ugt_253_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (BitVec.ofInt 8 (-3) <ᵤ truncate 8 x) = ofBool (x &&& 254#32 == 254#32)

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 main8_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 64#32 != 0#32) = 1#1 → ofBool (x &&& 192#32 == 0#32) = 1#1 → ¬True → 2#32 = 1#32

theorem lshrugt_02_08_proof : lshrugt_02_08_before ⊑ lshrugt_02_08_after

theorem append_valid {Γ₁ Γ₂ Γ₃  : Ctxt Ty} {d₁ d₂ : Nat} :
  Diff.Valid Γ₁ Γ₂ d₁ →  Diff.Valid Γ₂ Γ₃ d₂ → Diff.Valid Γ₁ Γ₃ (d₁ + d₂)

theorem scalar_i32_signbit_lshr_and_eq_X_is_constant2_thm (e : IntW 32) :
  icmp IntPred.eq (LLVM.and (lshr (const? 32 (-2147483648)) e) (const? 32 1)) (const? 32 0) ⊑
    icmp IntPred.ne e (const? 32 31)

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

theorem udiv_icmp2_thm (e : IntW 64) :
  icmp IntPred.eq (LLVM.udiv e (const? 64 5) { «exact» := true }) (const? 64 0) ⊑
    icmp IntPred.eq e (const? 64 0)

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

theorem eq_21_proof : eq_21_before ⊑ eq_21_after

theorem bmod_ofNat_eq_of_lt (n m : Nat) (h : n < (m + 1) / 2) :
    (↑n : Int).bmod m = ↑(n % m)

@[simp] theorem msb_signExtend_of_ge {i} (h : i ≥ w) (x : BitVec w) :
    (x.signExtend i).msb = x.msb

theorem different_size_sext_sext_sle_thm (e : IntW 4) (e_1 : IntW 7) :
  icmp IntPred.sle (sext 25 e_1) (sext 25 e) ⊑ icmp IntPred.sle e_1 (sext 7 e)

theorem ashrslt_03_05_proof : ashrslt_03_05_before ⊑ ashrslt_03_05_after

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

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

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

theorem test0_proof : test0_before ⊑ test0_after

theorem e_17' (x y : BitVec 6) :
     - 11 *  ~~~(x &&& y) + 14 *  ~~~(x ||| y) + 9 *  ~~~(x |||  ~~~y) + 16 * (x &&&  ~~~y) =  - 2 *  ~~~x + 5 *  ~~~y

theorem icmp_ult_x_y_thm (e e_1 : IntW 8) :
  icmp IntPred.ult (LLVM.and e_1 e) e_1 ⊑ icmp IntPred.ne (LLVM.and e_1 e) e_1

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

@[simp] theorem removeNone_stuck : (stuck α).removeNone = stuck α

theorem ashr_lshr_shift_amt_mismatch_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (0#32 ≤ₛ x_1) = 1#1 → ¬x ≥ ↑32 → ofBool (x_1 <ₛ 0#32) = 1#1 ∨ x ≥ ↑32 → False

theorem not_sub_eq_not_add :
    ~~~ (x - y) = ~~~x + y

theorem main3d_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 7#32 != 0#32) = 1#1 → True → 0#32 = zeroExtend 32 (ofBool (x &&& 23#32 == 0#32))

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

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

theorem XorZextXor_thm.extracted_1._1 : ∀ (x : BitVec 3), zeroExtend 5 (x ^^^ 3#3) ^^^ 12#5 = zeroExtend 5 x ^^^ 15#5

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

theorem ule_and_min_commute_proof : ule_and_min_commute_before ⊑ ule_and_min_commute_after

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

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

theorem urem_common_divisor_proof : urem_common_divisor_before ⊑ urem_common_divisor_after

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

theorem t7_ugt_sgt_neg1_thm.extracted_1._15 : ∀ (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 not_and_and_or_no_or_commute1_and_proof : not_and_and_or_no_or_commute1_and_before ⊑ not_and_and_or_no_or_commute1_and_after

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

theorem ne_smax1_proof : ne_smax1_before ⊑ ne_smax1_after

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

theorem test_nuw_nsw_and_signed_pred_proof : test_nuw_nsw_and_signed_pred_before ⊑ test_nuw_nsw_and_signed_pred_after

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

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

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 test5_thm (e e_1 : IntW 399) :
  LLVM.or
      (LLVM.and (add e_1 (LLVM.and e (const? 399 18446742974197923840)))
        (LLVM.xor (const? 399 274877906943) (const? 399 (-1))))
      (LLVM.and e_1 (const? 399 274877906943)) ⊑
    add e_1 (LLVM.and e (const? 399 18446742974197923840))

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 shl_shl_constants_div_proof : shl_shl_constants_div_before ⊑ shl_shl_constants_div_after

theorem PR75692_1_thm.extracted_1._1 : ∀ (x : BitVec 32), (x ^^^ 4#32) &&& (x ^^^ BitVec.ofInt 32 (-5)) = 0#32

theorem or_nosignbit_shl_proof : or_nosignbit_shl_before ⊑ or_nosignbit_shl_after

theorem bitwise_or_logical_or_icmps_comm1_thm (e e_1 e_2 : IntW 8) :
  LLVM.or (icmp IntPred.eq (LLVM.and e_2 (shl (const? 8 1) e_1)) (const? 8 0))
      (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 (icmp IntPred.eq e (const? 8 42)) (const? 1 1)
      (icmp IntPred.ne
        (LLVM.and e_2 (LLVM.or (shl (const? 8 1) e_1 { «nsw» := false, «nuw» := true }) (const? 8 1)))
        (LLVM.or (shl (const? 8 1) e_1 { «nsw» := false, «nuw» := true }) (const? 8 1)))

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

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

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

theorem test_shl_nsw__nsw_is_safe_proof : test_shl_nsw__nsw_is_safe_before ⊑ test_shl_nsw__nsw_is_safe_after

theorem a_false_implies_b_false2_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 → ofBool (10#8 <ᵤ x_2) ||

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 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 e_836 :
    1 *  ~~~(z &&&  ~~~t) + 11 * (z ^^^ t) - 1 * z - 11 *  ~~~(z |||  ~~~t) - 9 * (z &&&  ~~~t) = 1 *  ~~~(z &&&  ~~~z) - 1 * (z &&& t)

theorem not_and_and_or_no_or_proof : not_and_and_or_no_or_before ⊑ not_and_and_or_no_or_after

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

theorem cmpne_xor_cst3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 ^^^ 10#32 != x ^^^ 10#32) = ofBool (x_1 != x)

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

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

theorem abs_must_be_positive_proof : abs_must_be_positive_before ⊑ abs_must_be_positive_after

theorem orcond.110.inv.inner.cond.in.inner.sel.inv.inner.cond.in.outer.cond_proof : orcond.110.inv.inner.cond.in.inner.sel.inv.inner.cond.in.outer.cond_before ⊑ orcond.110.inv.inner.cond.in.inner.sel.inv.inner.cond.in.outer.cond_after

theorem prove_exact_with_high_mask_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(BitVec.ofInt 8 (-4) == 0 || 8 != 1 && x &&& BitVec.ofInt 8 (-32) == intMin 8 && BitVec.ofInt 8 (-4) == -1) = true →
    ¬(2#8 ≥ ↑8 ∨ True ∧ (0#8).ssubOverflow (x.sshiftRight' 2#8 &&& BitVec.ofInt 8 (-8)) = true) →
      (x &&& BitVec.ofInt 8 (-32)).sdiv (BitVec.ofInt 8 (-4)) = 0#8 - (x.sshiftRight' 2#8 &&& BitVec.ofInt 8 (-8))

theorem select_zext_different_condition_proof : select_zext_different_condition_before ⊑ select_zext_different_condition_after

theorem t9_ashr_proof : t9_ashr_before ⊑ t9_ashr_after

theorem ugt_or_not_min_commute_logical_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 != 0#8) = 1#1 → ofBool (x <ᵤ x_1) = ofBool (x_1 != 0#8)

theorem main13_proof : main13_before ⊑ main13_after

theorem lshr_and_thm.extracted_1._1 : ∀ (x : BitVec 8), ¬(x ≥ ↑8 ∨ x + 1#8 ≥ ↑8) → x ≥ ↑8 → False

theorem trunc_shl_32_i32_i64_thm (e : IntW 64) : trunc 32 (shl e (const? 64 32)) ⊑ const? 32 0

theorem t3_ult_sgt_neg1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x <ᵤ 65536#32) = 1#1 → ofBool (65535#32 <ₛ x) = 1#1 ∨ ofBool (x <ₛ 0#32) = 1#1 → False

theorem lor_bor_left1_proof : lor_bor_left1_before ⊑ lor_bor_left1_after

theorem ashr_ugt_14_proof : ashr_ugt_14_before ⊑ ashr_ugt_14_after

theorem icmp_slt_0_or_icmp_sgt_0_i64_proof : icmp_slt_0_or_icmp_sgt_0_i64_before ⊑ icmp_slt_0_or_icmp_sgt_0_i64_after

@[simp] theorem ofBitVec_not : ofBitVecSext (~~~ x) = ~~~ (ofBitVecSext x)

theorem test7_proof : test7_before ⊑ test7_after

theorem sub_3_thm (e e_1 : IntW 128) (e_2 : IntW 1) (e_3 : IntW 128) :
  LLVM.xor (sub e_3 (select e_2 (LLVM.xor e_1 (const? 128 (-1))) (LLVM.xor e (const? 128 123)))) (const? 128 (-1)) ⊑
    sub (const? 128 (-2)) (add (select e_2 e_1 (LLVM.xor e (const? 128 (-124)))) e_3)

theorem unsigned_sign_bit_extract_proof : unsigned_sign_bit_extract_before ⊑ unsigned_sign_bit_extract_after

theorem test3_proof : test3_before ⊑ test3_after

theorem select_icmp_ne_0_and_4096_xor_4096_proof : select_icmp_ne_0_and_4096_xor_4096_before ⊑ select_icmp_ne_0_and_4096_xor_4096_after

theorem test1_proof : test1_before ⊑ test1_after

theorem lshr_mul_times_5_div_4_exact_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.smulOverflow 5#32 = true ∨ True ∧ (x * 5#32) >>> 2#32 <<< 2#32 ≠ x * 5#32 ∨ 2#32 ≥ ↑32) →
    True ∧ x >>> 2#32 <<< 2#32 ≠ x ∨ 2#32 ≥ ↑32 ∨ True ∧ x.saddOverflow (x >>> 2#32) = true → False

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

theorem sgt_3_impliesF_eq_2_proof : sgt_3_impliesF_eq_2_before ⊑ sgt_3_impliesF_eq_2_after

theorem lor_bor_left2_proof : lor_bor_left2_before ⊑ lor_bor_left2_after

theorem signbit_splat_mask_proof : signbit_splat_mask_before ⊑ signbit_splat_mask_after

theorem xor_nosignbit_select_shl_proof : xor_nosignbit_select_shl_before ⊑ xor_nosignbit_select_shl_after

theorem lshr_sub_nsw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.ssubOverflow x = true ∨ 31#32 ≥ ↑32) → (x_1 - x) >>> 31#32 = zeroExtend 32 (ofBool (x_1 <ₛ x))

theorem substitute_constant_or_ne_swap_sle_proof : substitute_constant_or_ne_swap_sle_before ⊑ substitute_constant_or_ne_swap_sle_after

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

theorem pv_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (LLVM.and (lshr (const? 8 (-1)) e_1) e) e ⊑
    icmp IntPred.ule e (lshr (const? 8 (-1)) e_1)

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

theorem icmp_equality_test_wrong_and_thm (e e_1 e_2 : IntW 64) :
  select (icmp IntPred.eq e_2 e_1) (icmp IntPred.eq e e_1)
      (select (LLVM.xor (icmp IntPred.eq e e_1) (const? 1 1)) (const? 1 0) (icmp IntPred.eq e_2 e)) ⊑
    select (icmp IntPred.eq e_2 e_1) (icmp IntPred.eq e e_1)
      (select (icmp IntPred.eq e e_1) (icmp IntPred.eq e_2 e) (const? 1 0))

theorem negate_shl_xor_proof : negate_shl_xor_before ⊑ negate_shl_xor_after

theorem trunc_shl_shl_var_proof : trunc_shl_shl_var_before ⊑ trunc_shl_shl_var_after

theorem e_591 :
     - 1 *  ~~~(x &&&  ~~~y) - 5 *  ~~~x - 3 *  ~~~(x &&&  ~~~x) - 3 * y - 1 * (x ||| y) + 7 * x + 9 *  ~~~(x ||| y) + 20 *  ~~~(x |||  ~~~y) + 4 * (x &&&  ~~~y) + 1 * (x &&& y) = 7 * (x ^^^ y)

theorem trunc_shl_7_i8_i64_thm.extracted_1._1 : ∀ (x : BitVec 64), ¬7#64 ≥ ↑64 → 7#8 ≥ ↑8 → False

theorem ugt_swap_and_min_commute_logical_proof : ugt_swap_and_min_commute_logical_before ⊑ ugt_swap_and_min_commute_logical_after

theorem scalar_i32_shl_and_negC_slt_proof : scalar_i32_shl_and_negC_slt_before ⊑ scalar_i32_shl_and_negC_slt_after

theorem t10_shl_nuw_flag_preservation_thm.extracted_1._2 : ∀ (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) ∨
            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 >>> 30#32 ≠ x_1 ∨ 30#32 ≥ ↑32) →
      x_1 <<< (32#32 - x) <<< (x + BitVec.ofInt 32 (-2)) = x_1 <<< 30#32

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

theorem and_two_ranges_to_mask_and_range_not_pow2_diff_proof : and_two_ranges_to_mask_and_range_not_pow2_diff_before ⊑ and_two_ranges_to_mask_and_range_not_pow2_diff_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 test4_proof : test4_before ⊑ test4_after

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

theorem or_def {α : Type _} (c d : Circuit α) :
  (c ||| d) = Circuit.simplifyOr c d

theorem masked_and_notallzeroes_proof : masked_and_notallzeroes_before ⊑ masked_and_notallzeroes_after

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

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

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

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

theorem scalar0_proof : scalar0_before ⊑ scalar0_after

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

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

theorem sdiv_shl_pair3_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ (x_2 <<< x_1).sshiftRight' x_1 ≠ x_2 ∨
        x_1 ≥ ↑32 ∨
          True ∧ (x_2 <<< x).sshiftRight' x ≠ x_2 ∨
            x ≥ ↑32 ∨ (x_2 <<< x == 0 || 32 != 1 && x_2 <<< x_1 == intMin 32 && x_2 <<< x == -1) = true) →
    ¬(True ∧ 1#32 <<< x_1 >>> x_1 ≠ 1#32 ∨ x_1 ≥ ↑32 ∨ x ≥ ↑32) → (x_2 <<< x_1).sdiv (x_2 <<< x) = 1#32 <<< x_1 >>> x

@[simp, simp_denote]
theorem liftEffect_pure_impure [Pure m] (hle : pure ≤ impure) :
    liftEffect hle (α := α) (m := m) = Pure.pure

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

theorem slt_positive_multip_rem_nz_thm (e : IntW 8) :
  icmp IntPred.slt (mul e (const? 8 5) { «nsw» := true, «nuw» := false }) (const? 8 21) ⊑
    icmp IntPred.slt e (const? 8 5)

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

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

theorem test16_thm (e : IntW 8) : LLVM.and (shl e (const? 8 2)) (const? 8 3) ⊑ const? 8 0

theorem is_ascii_alphabetic_inverted_thm (e : IntW 32) :
  select (icmp IntPred.ult (add e (const? 32 (-91)) { «nsw» := true, «nuw» := false }) (const? 32 (-26)))
      (icmp IntPred.ult (add e (const? 32 (-123)) { «nsw» := true, «nuw» := false }) (const? 32 (-26)))
      (const? 1 0) ⊑
    icmp IntPred.ult (add (LLVM.and e (const? 32 (-33))) (const? 32 (-91))) (const? 32 (-26))

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

theorem slt_zero_eq_ne_0_fail2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬30#32 ≥ ↑32 →
    ofBool (zeroExtend 32 (ofBool (x != 0#32)) == x >>> 30#32) =
      ofBool (x >>> 30#32 == zeroExtend 32 (ofBool (x != 0#32)))

theorem sub_select_not_zext_proof : sub_select_not_zext_before ⊑ sub_select_not_zext_after

theorem ashrslt_03_04_proof : ashrslt_03_04_before ⊑ ashrslt_03_04_after

theorem ashrslt_02_06_proof : ashrslt_02_06_before ⊑ ashrslt_02_06_after

theorem test_shl_nuw__nuw_is_safe_thm (e : IntW 64) (e_1 : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e_1 (const? 32 1073741822)) (const? 32 0)) e
      (ashr e (zext 64 (shl (LLVM.and e_1 (const? 32 1073741822)) (const? 32 2) { «nsw» := false, «nuw» := true }))) ⊑
    ashr e (zext 64 (LLVM.and (shl e_1 (const? 32 2)) (const? 32 (-8))) { «nneg» := true })

theorem urem_constant_dividend_select_of_constants_divisor_thm.extracted_1._1 : ∀ (x : BitVec 1),
  x = 1#1 → ¬12#32 = 0 → 42#32 % 12#32 = 6#32

theorem and_ne_with_diff_one_logical_proof : and_ne_with_diff_one_logical_before ⊑ and_ne_with_diff_one_logical_after

theorem or_nosignbit_shl_proof : or_nosignbit_shl_before ⊑ or_nosignbit_shl_after

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

theorem AndZextAnd_proof : AndZextAnd_before ⊑ AndZextAnd_after

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

theorem eq_umin3_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 + 3#32 <ᵤ x) = 1#1 → ofBool (x_1 + 3#32 == x) = ofBool (x_1 + 3#32 ≤ᵤ x)

theorem f_thm (e : IntW 32) :
  icmp IntPred.ne (LLVM.srem (LLVM.or e (const? 32 1)) (const? 32 1)) (const? 32 0) ⊑ const? 1 0

theorem e_344 :
     - 11 * (x ^^^ y) - 2 *  ~~~x - 2 * (x ||| y) - 3 * (x |||  ~~~y) + 2 *  ~~~(x ||| y) + 12 *  ~~~(x |||  ~~~y) + 16 * (x &&&  ~~~y) + 2 * (x &&& y) =  - 3 *  ~~~(x &&&  ~~~y)

theorem neg_sgt_eq_slt_neg {A B : BitVec w} (h : A ≠ intMin w) (h2 : B ≠ intMin w) :
    (-A >ₛ B) = (A <ₛ -B)

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

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

theorem tryFactorization_xor_ashr_lshr_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(x ≥ ↑32 ∨ x ≥ ↑32) →
    ¬x ≥ ↑32 → (BitVec.ofInt 32 (-3)).sshiftRight' x ^^^ 5#32 >>> x = (BitVec.ofInt 32 (-8)).sshiftRight' x

theorem or_xor_common_op_commute6_thm (e e_1 e_2 : IntW 8) :
  LLVM.or (LLVM.xor e_2 e_1) (LLVM.or e_1 e) ⊑ LLVM.or (LLVM.or e_1 e) e_2

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

theorem and_add_bool_to_select_multi_use_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 → (-1#32 + zeroExtend 32 x_1 &&& x) + (-1#32 + zeroExtend 32 x_1) = 0#32

theorem test9_proof : test9_before ⊑ test9_after

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

theorem e_625 :
     - 11 *  ~~~(x &&& y) - 1 * (x ||| y) + 2 * x + 4 *  ~~~y - 11 * (x ^^^ y) + 7 *  ~~~(x ^^^ y) - 6 *  ~~~(x &&&  ~~~y) + 6 *  ~~~(x ||| y) + 29 *  ~~~(x |||  ~~~y) - 2 * (x &&& y) =  - 17 * (x &&&  ~~~y)

theorem eq_irregular_bit_widths_proof : eq_irregular_bit_widths_before ⊑ eq_irregular_bit_widths_after

theorem mullo_variant3_proof : mullo_variant3_before ⊑ mullo_variant3_after

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

theorem gt_unsigned_to_large_negative_proof : gt_unsigned_to_large_negative_before ⊑ gt_unsigned_to_large_negative_after

theorem shl1_nsw_proof : shl1_nsw_before ⊑ shl1_nsw_after

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

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

theorem alive_AddSub_1560  (w : Nat)   : alive_AddSub_1560_src w  ⊑ alive_AddSub_1560_tgt w

@[simp] theorem carry_zero (x : arity → BitStream) : carry p x 0 = p.initCarry

theorem alive_AndOrXor_2595 : alive_AndOrXor_2595_src ⊑ alive_AndOrXor_2595_tgt

theorem test_proof : test_before ⊑ test_after

theorem e_1423 :
     - 1 *  ~~~(z ^^^ t) - 2 * (z |||  ~~~t) + 5 * (z ^^^ t) - 5 * (z ||| t) + 2 * t + 1 *  ~~~t + 11 *  ~~~(z &&&  ~~~t) - 9 *  ~~~(z ||| t) - 13 *  ~~~(z |||  ~~~t) - 6 * (z &&&  ~~~t) = 12 * (z &&& t) - 7 * z

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

theorem e_2210 :
    11 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 5 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 2 *  ~~~(d &&&  ~~~f) + 1 * (e ^^^ (d &&& (e ||| f))) + 4 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 4 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 1 * ((d &&& e) |||  ~~~(e ^^^ f)) + 11 * ( ~~~e &&& (d ^^^ f)) - 6 * (d ^^^ ( ~~~e ||| f)) + 11 *  ~~~(d ^^^ e) + 1 * (d &&& (e ||| f)) - 7 *  ~~~e - 6 * (e ^^^ (d |||  ~~~f)) - 2 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 1 *  ~~~(e ^^^ f) + 7 * (f ^^^ (d ||| ( ~~~e ||| f))) + 7 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 1 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 5 * (e ^^^ (d ||| (e ^^^ f))) + 7 * (d ||| (e ^^^ f)) - 1 *  ~~~f - 3 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) - 2 * ((d ^^^ e) |||  ~~~(d ^^^ f)) + 4 * (f &&& (d ||| e)) - 2 * ( ~~~e ||| (d ^^^ f)) + 3 * f + 11 *  ~~~(e ||| f) - 2 * (f ^^^ (d &&& e)) - 1 * (f ^^^ (d &&& (e ||| f))) + 1 * ( ~~~e |||  ~~~(d ^^^ f)) + 3 * (f ||| (d &&& e)) + 2 * (f &&& (d |||  ~~~e)) - 7 *  ~~~(d ^^^ f) + 1 * ((d &&& e) ^^^ (e ||| f)) + 2 * (e ^^^ f) - 5 * (f ^^^ (d ||| (e ||| f))) + 1 * ( ~~~f &&&  ~~~(d ^^^ e)) - 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 1 * ((d &&& e) ||| (e ^^^ f)) + 1 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 3 * (e ^^^  ~~~(d ||| f)) + 2 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 2 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 2 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 3 * (e &&&  ~~~(d &&&  ~~~f)) - 4 *  ~~~(d ||| (e ||| f)) - 3 *  ~~~(d ||| ( ~~~e ||| f)) - 27 *  ~~~( ~~~d ||| (e ||| f)) - 22 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 59 * ( ~~~d &&& ( ~~~e &&& f)) - 5 * ( ~~~d &&& (e &&& f)) - 15 * (d &&& ( ~~~e &&& f)) = 43 * (d &&& (e &&& f))

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

@[bv_multi_width_normalize] theorem not_ofBool_eq_ofBool_ne (x y : Bool) :
  (¬ (BitVec.ofBool x = BitVec.ofBool y)) ↔ (x ≠ y)

theorem test_sub__nsw_is_safe_thm.extracted_1._2 : ∀ (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) →
      -1#32 = BitVec.ofInt 32 (-2147483648) - (x ||| BitVec.ofInt 32 (-2147483648))

theorem substitute_constant_and_eq_ugt_swap_proof : substitute_constant_and_eq_ugt_swap_before ⊑ substitute_constant_and_eq_ugt_swap_after

theorem poo_thm (e e_1 e_2 e_3 : IntW 32) :
  LLVM.or (LLVM.and (select (icmp IntPred.slt e_3 e_2) (const? 32 (-1)) (const? 32 0)) e_1)
      (LLVM.and (select (icmp IntPred.slt e_3 e_2) (const? 32 0) (const? 32 (-1))) e) ⊑
    select (icmp IntPred.slt e_3 e_2) e_1 e

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

theorem or_logic_or_logic_and_3_thm.extracted_1._3 : ∀ (x x_1 x_2 : BitVec 1), x_2 = 1#1 → True → x_2 ||

theorem icmp_eq_mul_nsw_nonequal_commuted_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ x_1.smulOverflow x = true ∨ True ∧ x.smulOverflow (x_1 + 1#8) = true) →
    ofBool (x_1 * x == x * (x_1 + 1#8)) = ofBool (x == 0#8)

theorem add_of_mul_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8),
  ¬(True ∧ x_2.smulOverflow x_1 = true ∨
        True ∧ x_2.smulOverflow x = true ∨ True ∧ (x_2 * x_1).saddOverflow (x_2 * x) = true) →
    x_2 * x_1 + x_2 * x = x_2 * (x_1 + x)

theorem t1_const_shl_lshr_ne_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(1#32 ≥ ↑32 ∨ 1#32 ≥ ↑32) →
    ¬2#32 ≥ ↑32 → ofBool (x_1 >>> 1#32 &&& x <<< 1#32 != 0#32) = ofBool (x_1 >>> 2#32 &&& x != 0#32)

theorem or_ranges_adjacent_proof : or_ranges_adjacent_before ⊑ or_ranges_adjacent_after

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

theorem shl_nuw_add_nsw_nuw_proof : shl_nuw_add_nsw_nuw_before ⊑ shl_nuw_add_nsw_nuw_after

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

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

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

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

@[simp]
private theorem _root_.Nat.testBit_one_eq_false_iff (i : Nat) :
    Nat.testBit 1 i = false ↔ i ≠ 0

theorem lshrult_01_09_exact_proof : lshrult_01_09_exact_before ⊑ lshrult_01_09_exact_after

theorem different_size_zext_zext_eq_thm.extracted_1._1 : ∀ (x : BitVec 7) (x_1 : BitVec 4),
  ofBool (zeroExtend 25 x_1 == zeroExtend 25 x) = ofBool (x == zeroExtend 7 x_1)

theorem select_zext_different_condition_proof : select_zext_different_condition_before ⊑ select_zext_different_condition_after

theorem e_1271 :
     - 3 *  ~~~(z ^^^ t) - 3 *  ~~~(z &&& t) + 3 * z + 2 *  ~~~(z &&&  ~~~z) - 2 *  ~~~z - 5 *  ~~~(z ||| t) + 3 *  ~~~(z |||  ~~~t) - 13 * (z &&&  ~~~t) - 13 * (z &&& t) =  - 11 * (z |||  ~~~t)

theorem test_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬8#32 ≥ ↑32 →
    ofBool (x <<< 8#32 &&& BitVec.ofInt 32 (-16777216) == 167772160#32) = ofBool (x &&& 16711680#32 == 655360#32)

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

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

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

theorem e_1492 :
     - 2 *  ~~~(z &&&  ~~~t) - 6 *  ~~~(z &&& t) - 1 *  ~~~(z &&&  ~~~z) - 6 * (z ^^^ t) - 1 * (z |||  ~~~t) + 11 * t - 1 *  ~~~(z ^^^ t) + 11 *  ~~~(z ||| t) + 9 *  ~~~(z |||  ~~~t) + 19 * (z &&&  ~~~t) - 1 * (z &&& t) = 5 * (z ||| t)

theorem or_ranges_overlap_proof : or_ranges_overlap_before ⊑ or_ranges_overlap_after

theorem trunc_sel_smaller_zext_proof : trunc_sel_smaller_zext_before ⊑ trunc_sel_smaller_zext_after

theorem or_xor_commute3_proof : or_xor_commute3_before ⊑ or_xor_commute3_after

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

theorem ashr_exact_poison_constant_fold_thm.extracted_1._3 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → ¬(True ∧ 42#8 >>> 3#8 <<< 3#8 ≠ 42#8 ∨ 3#8 ≥ ↑8) → (42#8).sshiftRight' 3#8 = 5#8

theorem land_land_left2_proof : land_land_left2_before ⊑ land_land_left2_after

theorem dec_mask_commute_neg_i32_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬((x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true ∨
        (x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true) →
    ¬((x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true ∨
          True ∧ ((42#32).sdiv x).saddOverflow (-1#32) = true ∨
            (x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true) →
      ((42#32).sdiv x &&& 0#32 - (42#32).sdiv x) + -1#32 = (42#32).sdiv x + -1#32 &&& ((42#32).sdiv x ^^^ -1#32)

theorem sle_smax2_proof : sle_smax2_before ⊑ sle_smax2_after

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

theorem demorgan_nor_proof : demorgan_nor_before ⊑ demorgan_nor_after

theorem scalar_i32_shl_and_negC_ne_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬x ≥ ↑32 → ofBool (x_1 <<< x &&& BitVec.ofInt 32 (-262144) != 0#32) = ofBool (262143#32 <ᵤ x_1 <<< x)

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

theorem icmp_ne_sext_sgt_zero_nofold_proof : icmp_ne_sext_sgt_zero_nofold_before ⊑ icmp_ne_sext_sgt_zero_nofold_after

theorem shl1_nsw_not_exact_proof : shl1_nsw_not_exact_before ⊑ shl1_nsw_not_exact_after

theorem factorize2_thm.extracted_1._1 : ∀ (x : BitVec 32), 3#32 * x - 2#32 * x = x

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

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

theorem xor_lshr_multiuse_thm (e e_1 e_2 e_3 : IntW 8) :
  LLVM.sdiv (LLVM.xor (lshr e_3 e_2) e_1) (LLVM.xor (LLVM.xor (lshr e_3 e_2) e_1) (lshr e e_2)) ⊑
    LLVM.sdiv (LLVM.xor (lshr e_3 e_2) e_1) (LLVM.xor (lshr (LLVM.xor e_3 e) e_2) e_1)

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

theorem slt3 (w : Nat) (a b : BitVec w) : ((a.sle b) ∧ (b.sle a)) → a = b

theorem src_x_or_mask_ne_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → ofBool (0#8 ||| x ^^^ -1#8 != -1#8) = ofBool (0#8 <ᵤ x)

theorem ashr_slt_exact_near_pow2_cmpval_thm (e : IntW 8) :
  icmp IntPred.slt (ashr e (const? 8 1) { «exact» := true }) (const? 8 5) ⊑
    icmp IntPred.slt e (const? 8 9)

theorem e_940 :
     - 6 *  ~~~(z &&& t) - 2 * (z ^^^ t) + 2 * z + 6 *  ~~~(z ||| t) + 6 * (z &&&  ~~~t) - 2 * (z &&& t) =  - 8 *  ~~~(z |||  ~~~t)

theorem t_2_63_or_proof : t_2_63_or_before ⊑ t_2_63_or_after

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

theorem test3_proof : test3_before ⊑ test3_after

theorem lshrult_01_08_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬1#4 ≥ ↑4 → ofBool (x >>> 1#4 <ᵤ BitVec.ofInt 4 (-8)) = 1#1

theorem and_sext_sext_thm (e : IntW 8) (e_1 : IntW 4) :
  LLVM.and (sext 16 e_1) (sext 16 e) ⊑ sext 16 (LLVM.and e (sext 8 e_1))

theorem scalar_i8_shl_ult_const_2_proof : scalar_i8_shl_ult_const_2_before ⊑ scalar_i8_shl_ult_const_2_after

theorem alive_AddSub_1539  (w : Nat)   : alive_AddSub_1539_src w  ⊑ alive_AddSub_1539_tgt w

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

theorem lowmask_mul_zext_thm (e : IntW 32) (e_1 : IntW 8) :
  LLVM.and (mul (zext 32 e_1) e) (const? 32 255) ⊑ zext 32 (mul e_1 (trunc 8 e))

theorem lshr_by_const_cmp_sge_value_proof : lshr_by_const_cmp_sge_value_before ⊑ lshr_by_const_cmp_sge_value_after

theorem neg_or_lshr_i32_commute_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬((x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true ∨
        (x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true ∨ 31#32 ≥ ↑32) →
    ¬(x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true →
      ((42#32).sdiv x ||| 0#32 - (42#32).sdiv x) >>> 31#32 = zeroExtend 32 (ofBool ((42#32).sdiv x != 0#32))

theorem t1_otherbitwidth_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(15#16 ≥ ↑16 ∨ 15#16 ≥ ↑16) → True ∧ (0#16).ssubOverflow (x &&& 1#16) = true → False

theorem icmp_select_var_pred_ult_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 8),
  ofBool (x_2 == 0#8) = 1#1 → ¬(True ∧ x_1.uaddOverflow 2#8 = true) → ofBool (x_1 <ᵤ x_1 + 2#8) = 1#1

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 e_2418 :
    1 * (d ^^^ (e &&& f)) - 1 * (f ^^^  ~~~(d &&& (e &&& f))) - 5 * (f ^^^ ( ~~~d ||| (e ||| f))) + 4 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 2 *  ~~~(d &&&  ~~~e) + 11 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 7 * ( ~~~d ||| (e ||| f)) - 1 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 11 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 7 * (e &&&  ~~~(d &&&  ~~~f)) - 3 * ((d ^^^ e) &&& (d ^^^ f)) - 1 * (f &&&  ~~~(d ^^^ e)) + 5 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 2 * (e ^^^ (d &&& (e ||| f))) + 1 * (f ^^^ ( ~~~d ||| (e &&& f))) - 5 * (f ||| (d ^^^ e)) - 1 * (f ||| (d &&& e)) + 1 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 11 * d + 5 *  ~~~(d |||  ~~~e) + 1 * (d &&& (e ||| f)) - 2 * (f &&& (d ^^^ e)) + 2 * (f ^^^ (d &&& e)) - 2 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 1 * (d &&&  ~~~f) + 5 *  ~~~(d ^^^ f) - 6 * e - 11 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 5 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 6 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 3 * (d &&& f) + 5 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 2 * (d &&&  ~~~e) - 7 * (e &&& (d |||  ~~~f)) + 1 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 2 *  ~~~(d |||  ~~~f) - 7 * (e ^^^  ~~~(d &&&  ~~~f)) + 1 * (e ^^^ f) - 6 * (d ^^^ ( ~~~e ||| f)) + 4 * (e &&& (d ^^^ f)) - 1 * (e |||  ~~~(d |||  ~~~f)) + 2 *  ~~~(d ^^^ ( ~~~e &&& f)) + 1 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 4 * (d ||| ( ~~~e &&& f)) + 1 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 2 * ( ~~~d ||| (e &&& f)) - 2 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 5 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 3 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 3 * (e ^^^  ~~~(d |||  ~~~f)) - 7 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * ( ~~~d ||| (e ^^^ f)) + 1 *  ~~~(d ^^^ e) + 2 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 3 * ((d &&& e) ^^^ (e ||| f)) + 1 *  ~~~(e ^^^ f) + 1 *  ~~~(d &&&  ~~~d) - 7 * (f ^^^  ~~~(d ||| e)) + 2 * (f |||  ~~~(d ||| e)) - 2 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 7 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 5 * (e ||| (d &&& f)) + 1 * (e ^^^  ~~~(d &&& (e ||| f))) + 7 * (f &&&  ~~~(d &&&  ~~~e)) - 1 * (e ^^^ (d &&& ( ~~~e ||| f))) + 1 *  ~~~(d ||| ( ~~~e &&& f)) + 8 *  ~~~(d ||| (e ||| f)) + 23 *  ~~~(d ||| ( ~~~e ||| f)) - 25 *  ~~~( ~~~d ||| (e ||| f)) + 23 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 1 * ( ~~~d &&& ( ~~~e &&& f)) + 3 * ( ~~~d &&& (e &&& f)) - 7 * (d &&& ( ~~~e &&& f)) - 9 * (d &&& (e &&& f)) =  - 7 * (e &&&  ~~~(d &&& f))

theorem e_2308 :
     - 1 * (e ^^^ f) - 2 * (d ||| ( ~~~e ||| f)) + 3 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 2 *  ~~~(d &&&  ~~~d) + 7 * (e ^^^ ( ~~~d &&& (e ||| f))) - 1 *  ~~~(d ^^^ ( ~~~e ||| f)) - 3 * ((d &&& f) ^^^ (e ||| f)) + 5 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 4 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 5 * ( ~~~d ||| (e ^^^ f)) + 4 * (f ^^^ (d &&&  ~~~e)) - 1 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 5 * (d ||| (e ||| f)) - 6 * (d ^^^ (e ||| f)) + 7 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 1 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 3 * (f ^^^ (d &&& ( ~~~e ||| f))) + 7 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 7 * (f ||| (d &&& e)) + 1 * (f ^^^  ~~~(d ||| (e &&& f))) - 7 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 3 * ((d |||  ~~~e) &&& (e ^^^ f)) + 2 * (f &&& (d ^^^ e)) - 1 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 4 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 1 * (e ^^^ (d &&& f)) + 3 * ((d &&& e) ^^^ (e ||| f)) - 2 * (f ||| (d &&&  ~~~e)) - 6 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 1 *  ~~~(d ||| ( ~~~e &&& f)) - 1 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 2 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 2 * (e ^^^ (d ||| (e ||| f))) - 11 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 7 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 4 * (e ^^^ (d ||| (e ^^^ f))) - 1 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 1 * (f ^^^  ~~~(d &&& (e &&& f))) - 3 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 4 * (f ^^^  ~~~(d ||| e)) + 2 * (d |||  ~~~f) - 1 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 3 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 11 * (e ^^^  ~~~(d &&& f)) + 5 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 11 *  ~~~e + 2 * (e ||| f) - 6 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 1 * (e &&& (d ^^^ f)) - 7 *  ~~~( ~~~d &&& (e &&& f)) - 5 *  ~~~(d ^^^ (e ||| f)) + 1 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 2 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 5 * (e &&& (d |||  ~~~f)) - 1 *  ~~~(d ^^^ f) - 27 *  ~~~(d ||| (e ||| f)) + 4 *  ~~~(d ||| ( ~~~e ||| f)) - 1 *  ~~~( ~~~d ||| (e ||| f)) + 3 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 30 * ( ~~~d &&& ( ~~~e &&& f)) + 3 * ( ~~~d &&& (e &&& f)) + 11 * (d &&& (e &&& f)) =  - 4 * ( ~~~e ||| (d ^^^ f))

@[simp] theorem cons_get_zero {A : α → Type*} {a: α} {as : List α} {e : A a} {vec : HVector A as} :
   (HVector.cons e vec).get (@OfNat.ofNat (Fin (as.length + 1)) 0 Fin.instOfNat) = e

theorem sext_ule_sext_thm (e : IntW 1) (e_1 : IntW 8) :
  icmp IntPred.ule (sext 16 (mul e_1 e_1)) (sext 16 e) ⊑
    LLVM.or (icmp IntPred.eq (mul e_1 e_1) (const? 8 0)) e

theorem canonicalize_logic_first_xor_0_nsw_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.saddOverflow 96#8 = true) → True ∧ (x ^^^ 31#8).saddOverflow 96#8 = true → False

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

theorem addhshlhsdivhscalar1_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬((BitVec.ofInt 8 (-64) == 0 || 8 != 1 && x == intMin 8 && BitVec.ofInt 8 (-64) == -1) = true ∨ 6#8 ≥ ↑8) →
    ¬(64#8 == 0 || 8 != 1 && x == intMin 8 && 64#8 == -1) = true →
      x.sdiv (BitVec.ofInt 8 (-64)) <<< 6#8 + x = x.srem 64#8

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

theorem icmp_sle3_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (x <<< 1#8).sshiftRight' 1#8 ≠ x ∨ 1#8 ≥ ↑8) →
    ofBool (x <<< 1#8 ≤ₛ BitVec.ofInt 8 (-16)) = ofBool (x <ₛ BitVec.ofInt 8 (-7))

theorem or_and_shifts1_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(3#32 ≥ ↑32 ∨ 5#32 ≥ ↑32) →
    ¬(3#32 ≥ ↑32 ∨ 5#32 ≥ ↑32 ∨ True ∧ (x <<< 3#32 &&& 8#32 &&& (x <<< 5#32 &&& 32#32) != 0) = true) →
      x <<< 3#32 &&& 15#32 ||

theorem e_418 :
     - 6 *  ~~~y - 7 *  ~~~x + 1 *  ~~~(x ^^^ y) - 1 *  ~~~(x &&& y) + 13 *  ~~~(x ||| y) + 10 *  ~~~(x |||  ~~~y) + 9 * (x &&&  ~~~y) + 1 * (x &&& y) = 2 * (x ||| y)

lemma NFA'.autSignedCmp_correct cmp : autSignedCmp cmp |>.correct2 autSignedCmpSA cmp.srel

theorem uge_or_max_logical_proof : uge_or_max_logical_before ⊑ uge_or_max_logical_after

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

theorem ashr_x_by_const_cmp_sge_x_proof : ashr_x_by_const_cmp_sge_x_before ⊑ ashr_x_by_const_cmp_sge_x_after

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

theorem IsLawful_mkSucc_of_IsLawful {arity : Type _}
    [DecidableEq arity] [Fintype arity] [Hashable arity]
    {fsm : FSM arity} {n : Nat}
    (prev : KInductionCircuits fsm n)
    (hPrev : prev.IsLawful) :
    (mkSucc prev).IsLawful

theorem urem_common_dividend_defined_cond_proof : urem_common_dividend_defined_cond_before ⊑ urem_common_dividend_defined_cond_after

theorem and_logic_and_logic_or_1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  x_1 &&& x = 1#1 → x_1 = 1#1 → ¬x = 1#1 → False

theorem sgt_swap_and_min_commute_proof : sgt_swap_and_min_commute_before ⊑ sgt_swap_and_min_commute_after

theorem bitwise_and_logical_and_masked_icmp_asymmetric_thm.extracted_1._3 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  ofBool (x_1 &&& 255#32 != 0#32) = 1#1 →
    ofBool (x_1 &&& 11#32 == 11#32) = 1#1 → x &&& ofBool (x_1 &&& 11#32 == 11#32) = x

theorem narrow_zext_sub_proof : narrow_zext_sub_before ⊑ narrow_zext_sub_after

theorem ofBitVec_sub_congr (h1 : ofBitVecSext x ≈ʷ a) (h2 : ofBitVecSext y ≈ʷ b) : ofBitVecSext (x - y) ≈ʷ a - b

theorem xor_or_proof : xor_or_before ⊑ xor_or_after

theorem zext_sext_add_icmp_sgt_minus1_proof : zext_sext_add_icmp_sgt_minus1_before ⊑ zext_sext_add_icmp_sgt_minus1_after

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

theorem shift_xor_multiuse_or_proof : shift_xor_multiuse_or_before ⊑ shift_xor_multiuse_or_after

theorem wide_source_matching_signbits_proof : wide_source_matching_signbits_before ⊑ wide_source_matching_signbits_after

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

theorem udiv_common_divisor_defined_cond_thm.extracted_1._2 : ∀ (x x_1 : BitVec 5) (x_2 : BitVec 1),
  ¬(x_2 = 1#1 ∨ x_1 = 0) → x_2 = 1#1 → ¬x_1 = 0 → False

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

@[bv_multi_width_normalize] theorem BitVec.lt_eq_ult {x y : BitVec w} :
    (x < y) = ((x.ult y) = true)

theorem ashrslt_03_13_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬3#4 ≥ ↑4 → ofBool (x.sshiftRight' 3#4 <ₛ BitVec.ofInt 4 (-3)) = 0#1

theorem sge_and_max_logical_samesign_proof : sge_and_max_logical_samesign_before ⊑ sge_and_max_logical_samesign_after

theorem test16_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬x = 0 → ofBool (4#32 / x <ᵤ -1#32) = 1#1

theorem lshrult_01_10_proof : lshrult_01_10_before ⊑ lshrult_01_10_after

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

theorem lshrugt_03_10_exact_proof : lshrugt_03_10_exact_before ⊑ lshrugt_03_10_exact_after

theorem uge_umin2_proof : uge_umin2_before ⊑ uge_umin2_after

theorem eq_shift_in_zeros_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(16#32 ≥ ↑32 ∨ 16#32 ≥ ↑32 ∨ 8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32) →
    ofBool (truncate 24 (x_1 >>> 16#32) == truncate 24 (x >>> 16#32)) &&&
        ofBool (truncate 8 (x_1 >>> 8#32) == truncate 8 (x >>> 8#32)) =
      ofBool (x_1 ^^^ x <ᵤ 256#32)

@[simp, grind=] theorem getElem_ofList (i : Nat) (h : _) : (ofList ts)[i]'h = ts[i]'h

@[simp]
theorem Expr.args_mk {Γ : Ctxt d.Ty} {ty eff op}
    (ty_eq : ty = DialectSignature.returnTypes op)
    (eff_le : DialectSignature.effectKind op ≤ eff)
    (args : HVector (Var Γ) (DialectSignature.sig op)) (regArgs) :
    (Expr.mk op ty_eq eff_le args regArgs).args = args

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

theorem n8_wrong_pred3_proof : n8_wrong_pred3_before ⊑ n8_wrong_pred3_after

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

theorem hoist_ashr_ahead_of_sext_1_thm (e : IntW 8) : ashr (sext 32 e) (const? 32 3) ⊑ sext 32 (ashr e (const? 8 3))

theorem main5f_like_logical_thm.extracted_1._9 : ∀ (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 ne_rem_zero_nonuw_proof : ne_rem_zero_nonuw_before ⊑ ne_rem_zero_nonuw_after

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

theorem set_shl_mask_proof : set_shl_mask_before ⊑ set_shl_mask_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

@[simp] theorem Expr.comap_denote_contextHom (e : Expr d Γ .pure ty) (V : Γ.Valuation) :
    (Valuation.comap (e.denote V) e.contextHom) = V

@[simp] theorem toCom_var {lets : Lets d Γ_in eff Γ_mid} :
    toCom ⟨Lets.var lets e, com⟩ = toCom ⟨lets, Com.var e com⟩

theorem lshr_ne_msb_low_last_zero_proof : lshr_ne_msb_low_last_zero_before ⊑ lshr_ne_msb_low_last_zero_after

theorem sub_mask1_trunc_lshr_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬15#64 ≥ ↑64 →
    ¬(48#64 ≥ ↑64 ∨
          63#64 ≥ ↑64 ∨
            True ∧ signExtend 64 (truncate 8 ((x <<< 48#64).sshiftRight' 63#64)) ≠ (x <<< 48#64).sshiftRight' 63#64 ∨
              True ∧ (truncate 8 ((x <<< 48#64).sshiftRight' 63#64)).saddOverflow 10#8 = true) →
      10#8 - (truncate 8 (x >>> 15#64) &&& 1#8) = truncate 8 ((x <<< 48#64).sshiftRight' 63#64) + 10#8

theorem ashrslt_02_04_proof : ashrslt_02_04_before ⊑ ashrslt_02_04_after

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

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

theorem ashrsgt_01_05_proof : ashrsgt_01_05_before ⊑ ashrsgt_01_05_after

theorem and_zext_proof : and_zext_before ⊑ and_zext_after

theorem e_552 :
     - 2 * y - 1 *  ~~~(x &&&  ~~~x) - 6 *  ~~~(x &&&  ~~~y) + 1 *  ~~~x + 11 * (x |||  ~~~y) - 11 * x - 5 *  ~~~(x ||| y) + 1 * (x &&&  ~~~y) + 9 * (x &&& y) =  - 8 *  ~~~(x |||  ~~~y)

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

theorem and_two_ranges_to_mask_and_range_thm (e : IntW 8) :
  LLVM.and (icmp IntPred.ugt (add e (const? 8 (-97))) (const? 8 25))
      (icmp IntPred.ugt (add e (const? 8 (-65))) (const? 8 25)) ⊑
    icmp IntPred.ult (add (LLVM.and e (const? 8 (-33))) (const? 8 (-91))) (const? 8 (-26))

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

theorem foo_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(7#8 ≥ ↑8 ∨ 7#8 ≥ ↑8 ∨ 5#8 ≥ ↑8 ∨ 7#8 ≥ ↑8) →
    7#8 ≥ ↑8 ∨
        2#8 ≥ ↑8 ∨
          True ∧ (40#8).ssubOverflow (x &&& 84#8) = true ∨
            True ∧ (x &&& 33#8 &&& (40#8 - (x &&& 84#8) &&& 84#8) != 0) = true ∨
              7#8 ≥ ↑8 ∨
                True ∧
                  ((x &&& 33#8 ||| 40#8 - (x &&& 84#8) &&& 84#8) &&& (x_1 <<< 7#8 ^^^ x &&& BitVec.ofInt 8 (-118)) !=
                      0) =
                    true →
      False

theorem or_shl_thm.extracted_1._2 : ∀ (x x_1 x_2 x_3 : BitVec 8),
  ¬(x_2 ≥ ↑8 ∨ x_2 ≥ ↑8) → ¬x_2 ≥ ↑8 → x_3 <<< x_2 ||

theorem bv_AndOrXor_1280_ABA___AB :
    ∀ (e e_1 : LLVM.IntW w), LLVM.and (LLVM.or (LLVM.xor e (LLVM.const? w (-1))) e_1) e ⊑ LLVM.and e e_1

theorem xor_ashr_not_commuted_thm (e e_1 e_2 : IntW 8) :
  LLVM.xor (LLVM.xor (ashr e_2 e_1) (const? 8 (-1))) (ashr e e_1) ⊑
    LLVM.xor (ashr (LLVM.xor e_2 e) e_1) (const? 8 (-1))

theorem zext_nneg_i1_proof : zext_nneg_i1_before ⊑ zext_nneg_i1_after

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

theorem sge_swap_and_max_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == 127#8) &&& ofBool (x ≤ₛ x_1) = ofBool (x_1 == 127#8)

theorem e_603 :
     - 1 *  ~~~(x &&&  ~~~y) - 2 *  ~~~(x &&& y) + 2 * x + 7 *  ~~~(x ^^^ y) + 3 * (x |||  ~~~y) + 5 * (x ||| y) - 7 *  ~~~(x ||| y) - 3 *  ~~~(x |||  ~~~y) - 8 * (x &&&  ~~~y) - 17 * (x &&& y) =  - 1 * y

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

theorem test_logical_thm (e e_1 : IntW 32) :
  select (icmp IntPred.slt e_1 e) (const? 1 1) (icmp IntPred.eq e_1 e) ⊑ icmp IntPred.sle e_1 e

theorem test0_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 41),
  ¬(x_1 ≥ ↑41 ∨ x_1 ≥ ↑41) → ¬x_1 ≥ ↑41 → x_2 <<< x_1 &&& x <<< x_1 = (x_2 &&& x) <<< x_1

theorem is_ascii_alphabetic_inverted_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.saddOverflow (BitVec.ofInt 32 (-91)) = true) →
    ofBool (x + BitVec.ofInt 32 (-91) <ᵤ BitVec.ofInt 32 (-26)) = 1#1 →
      ¬(True ∧ x.saddOverflow (BitVec.ofInt 32 (-123)) = true) →
        ofBool (x + BitVec.ofInt 32 (-123) <ᵤ BitVec.ofInt 32 (-26)) =
          ofBool ((x &&& BitVec.ofInt 32 (-33)) + BitVec.ofInt 32 (-91) <ᵤ BitVec.ofInt 32 (-26))

theorem fixed : ∀ (x : BitVec 4) (y : BitVec 7),
  (signExtend 25 y = signExtend 25 x) ↔ (y = signExtend 7 x)

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

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

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_6_proof : masked_icmps_mask_notallzeros_bmask_mixed_swapped_6_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_swapped_6_after

theorem test18_proof : test18_before ⊑ test18_after

theorem test2_proof : test2_before ⊑ test2_after

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

theorem test_not_const_shr_and_1_ne_0_proof : test_not_const_shr_and_1_ne_0_before ⊑ test_not_const_shr_and_1_ne_0_after

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

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

theorem slt_zero_eq_ne_0_fail2_proof : slt_zero_eq_ne_0_fail2_before ⊑ slt_zero_eq_ne_0_fail2_after

theorem n3_constmask_samemask_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  (x_1 ||| BitVec.ofInt 32 (-65281)) &&& (x ||| BitVec.ofInt 32 (-65281)) = x_1 &&& x ||

theorem n14_trunc_of_lshr_proof : n14_trunc_of_lshr_before ⊑ n14_trunc_of_lshr_after

theorem test_const_shr_and_1_ne_0_i1_negative_proof : test_const_shr_and_1_ne_0_i1_negative_before ⊑ test_const_shr_and_1_ne_0_i1_negative_after

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

theorem and_ashr_not_commuted_proof : and_ashr_not_commuted_before ⊑ and_ashr_not_commuted_after

theorem test15f_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 128#32 != 0#32) = 1#1 → ¬1#32 ≥ ↑32 → 0#32 = x <<< 1#32 &&& 256#32 ^^^ 256#32

theorem sub_congr (e1 : a ≈ʷ b) (e2 : c ≈ʷ d) : (a - c) ≈ʷ (b - d)

theorem lshr_eq_opposite_msb_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → ofBool (BitVec.ofInt 8 (-128) >>> x == 1#8) = ofBool (x == 7#8)

theorem t5_c2_thm (e e_1 : IntW 8) : sub (sub e_1 e) (const? 8 42) ⊑ add (sub e_1 e) (const? 8 (-42))

@[simp, simp_denote] theorem nil_isRefinedBy_nil    : (nil : HVector A _) ⊑ (nil : HVector B _)

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

lemma CNFA.bv_recognizes_equiv {m : CNFA n} :
    m.bv_recognizes L ↔ ∃ (M : NFA' n), m.Sim M ∧ M.accepts = L

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 t4_ugt_slt_128_thm.extracted_1._8 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (143#32 <ᵤ x_1 + 16#32) = 1#1 → ofBool (127#32 <ₛ x_1) = 1#1 → x_1 = x

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

theorem e_1947 :
    7 * (b ^^^ (a &&& c)) - 1 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) + 2 * (b &&&  ~~~c) - 5 * (c ||| (a &&&  ~~~b)) - 1 * (b &&& c) - 7 * (b ^^^  ~~~(a ||| (b &&& c))) + 11 * ((a &&& b) ^^^ (b ||| c)) - 2 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) + 2 * ( ~~~a ||| (b ^^^ c)) - 3 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) + 5 * (a ^^^ b) - 1 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 7 *  ~~~(a ^^^ c) + 11 *  ~~~(b ||| c) + 1 *  ~~~(a &&& ( ~~~b &&& c)) - 7 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) - 1 * (b ^^^  ~~~(a ||| c)) + 4 *  ~~~( ~~~a &&& ( ~~~b ||| c)) - 3 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) + 7 * ((a &&& b) ||| (b ^^^ c)) - 1 * ( ~~~a ||| ( ~~~b &&& c)) - 2 *  ~~~(a ||| (b &&& c)) + 2 * (b |||  ~~~(a |||  ~~~c)) - 5 *  ~~~( ~~~a ||| (b ^^^ c)) + 2 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) + 3 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) + 7 * (b ^^^ ( ~~~a ||| (b ||| c))) - 2 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 3 * ((a &&& b) |||  ~~~(b |||  ~~~c)) + 5 * (c ^^^ ( ~~~a ||| (b ||| c))) - 1 * (b ^^^ (a ||| c)) - 3 * (c ^^^ ( ~~~a &&& ( ~~~b ||| c))) + 3 * (c |||  ~~~(a ||| b)) + 4 * ((a |||  ~~~b) &&& (b ^^^ c)) - 1 * (c ^^^ (a ||| b)) + 1 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 4 * (b |||  ~~~(a ^^^ c)) - 2 * b + 1 *  ~~~(a &&& ( ~~~b ||| c)) + 2 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) - 2 *  ~~~(a ^^^ (b ||| c)) - 2 * (b ^^^  ~~~(a &&&  ~~~c)) + 3 * ( ~~~a ||| ( ~~~b ||| c)) - 3 *  ~~~(a ^^^ b) - 1 * (b ^^^ (a ||| ( ~~~b &&& c))) - 7 *  ~~~(a ||| (b ||| c)) - 37 *  ~~~(a ||| ( ~~~b ||| c)) + 1 *  ~~~( ~~~a ||| (b ||| c)) - 6 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 17 * ( ~~~a &&& ( ~~~b &&& c)) - 9 * ( ~~~a &&& (b &&& c)) - 28 * (a &&& ( ~~~b &&& c)) + 10 * (a &&& (b &&& c)) =  - 1 * (c ^^^  ~~~(a &&& ( ~~~b ||| c)))

theorem fold_add_udiv_urem_without_noundef_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(10#32 = 0 ∨ 4#32 ≥ ↑32 ∨ 10#32 = 0) →
    ¬(10#32 = 0 ∨ 4#32 ≥ ↑32 ∨ 10#32 = 0 ∨ True ∧ ((x / 10#32) <<< 4#32 &&& x % 10#32 != 0) = true) →
      (x / 10#32) <<< 4#32 + x % 10#32 = (x / 10#32) <<< 4#32 ||

theorem add_2_proof : add_2_before ⊑ add_2_after

theorem ashr_ult_12_proof : ashr_ult_12_before ⊑ ashr_ult_12_after

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

theorem sle_smax3_thm (e e_1 : IntW 32) :
  icmp IntPred.sge (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.sle e (add e_1 (const? 32 3))

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

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

theorem slt_swap_or_not_max_commute_proof : slt_swap_or_not_max_commute_before ⊑ slt_swap_or_not_max_commute_after

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

theorem not_match_inconsistent_values_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(299#64 = 0 ∨ 29#64 = 0 ∨ 64#64 = 0) →
    299#64 = 0 ∨
        29#64 = 0 ∨
          True ∧ (x / 29#64 &&& 63#64).smulOverflow 299#64 = true ∨
            True ∧ (x / 29#64 &&& 63#64).umulOverflow 299#64 = true ∨
              True ∧ (x % 299#64).saddOverflow ((x / 29#64 &&& 63#64) * 299#64) = true ∨
                True ∧ (x % 299#64).uaddOverflow ((x / 29#64 &&& 63#64) * 299#64) = true →
      False

theorem pv_thm (e e_1 : IntW 8) :
  icmp IntPred.ult (LLVM.and (lshr (const? 8 (-1)) e_1) e) e ⊑
    icmp IntPred.ugt e (lshr (const? 8 (-1)) e_1)

theorem ule_swap_or_min_proof : ule_swap_or_min_before ⊑ ule_swap_or_min_after

theorem and_orn_cmp_1_logical_proof : and_orn_cmp_1_logical_before ⊑ and_orn_cmp_1_logical_after

theorem t3_no_extrause_proof : t3_no_extrause_before ⊑ t3_no_extrause_after

theorem t1_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬ofBool (x &&& 31#8 == 0#8) = 1#1 → x + 32#8 &&& BitVec.ofInt 8 (-32) = x + 31#8 &&& BitVec.ofInt 8 (-32)

theorem test15_proof : test15_before ⊑ test15_after

theorem icmp_equality_test_swift_optional_pointers_thm.extracted_1._1 : ∀ (x x_1 : BitVec 64),
  ofBool (x_1 == 0#64) = 1#1 → True → ofBool (x == 0#64) = ofBool (x_1 == x)

theorem e_79 :
    3 *  ~~~y - 11 * x + 11 *  ~~~(x &&&  ~~~x) - 14 *  ~~~(x ||| y) - 3 * (x &&&  ~~~y) = 11 *  ~~~(x |||  ~~~y)

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

theorem lor_band_right1_thm (e e_1 : IntW 1) : LLVM.and e_1 (select e_1 (const? 1 1) e) ⊑ e_1

theorem land_lor_right1_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1), x_1 = 1#1 → 1#1 = x_1

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

theorem icmp_ne_mul_nsw_nonequal_proof : icmp_ne_mul_nsw_nonequal_before ⊑ icmp_ne_mul_nsw_nonequal_after

theorem zext_add_thm.extracted_1._1 : ∀ (x : BitVec 8),
  zeroExtend 16 x + 44#16 &&& zeroExtend 16 x = zeroExtend 16 (x + 44#8 &&& x)

theorem bitwise_and_logical_and_icmps_comm3_thm.extracted_1._4 : ∀ (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) &&& ofBool (x == 42#8) = ofBool (x == 42#8)

theorem n9_wrong_x2_thm (e e_1 : IntW 8) :
  select (icmp IntPred.eq (LLVM.and e_1 (const? 8 15)) (const? 8 0)) e
      (LLVM.and (add e (const? 8 16)) (const? 8 (-16))) ⊑
    select (icmp IntPred.eq (LLVM.and e_1 (const? 8 15)) (const? 8 0)) e
      (add (LLVM.and e (const? 8 (-16))) (const? 8 16))

theorem main7d_logical_thm.extracted_1._15 : ∀ (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 →
      0#1 = 1#1 → 0#32 = zeroExtend 32 (ofBool (x_4 &&& (x_1 &&& x) != x_1 &&& x))

theorem bar_proof : bar_before ⊑ bar_after

theorem masked_or_A_proof : masked_or_A_before ⊑ masked_or_A_after

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

theorem src_proof : src_before ⊑ src_after

theorem e_961 :
    4 * (z |||  ~~~t) + 1 *  ~~~t + 11 * (z ^^^ t) - 5 *  ~~~(z ||| t) - 15 *  ~~~(z |||  ~~~t) - 8 * (z &&& t) = 16 * (z &&&  ~~~t) - 4 * t

theorem e_2245 :
    2 *  ~~~(d &&&  ~~~d) - 1 * (f |||  ~~~(d ||| e)) + 4 * ((d &&& e) ^^^ (e |||  ~~~f)) - 6 * (e ^^^  ~~~(d &&& (e &&& f))) - 2 * (d ^^^ e) - 2 * ((d &&& e) ||| (e ^^^ f)) + 1 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 6 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 5 * (d &&& f) - 3 * (f ^^^ (d ||| ( ~~~e ||| f))) + 1 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 5 * (f ||| (d &&& e)) - 5 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 3 * (e ||| f) + 4 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 5 * (f ^^^  ~~~(d ||| e)) - 1 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 7 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 7 *  ~~~(e ^^^ f) - 3 * (d &&& (e ^^^ f)) + 7 * (e &&& (d ||| f)) + 7 * (f &&&  ~~~(d &&& e)) + 11 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 6 * (e ^^^  ~~~(d ||| (e &&& f))) + 1 * ((d ||| e) &&& (e ^^^ f)) - 1 * (e |||  ~~~(d ||| f)) - 1 *  ~~~e + 1 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 5 * ( ~~~d ||| ( ~~~e ||| f)) + 1 * ((d &&& e) ^^^ (e ||| f)) - 1 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 2 *  ~~~(d &&& f) + 2 * (f ^^^  ~~~(d &&& e)) - 3 *  ~~~( ~~~d &&& (e ^^^ f)) + 5 * ((d &&& f) ^^^ (e ||| f)) - 1 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 1 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 2 * ( ~~~d ||| (e &&& f)) + 2 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) + 1 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * (d &&&  ~~~e) + 11 * ( ~~~d &&& (e ||| f)) + 4 * ((d ^^^ e) ||| (d ^^^ f)) + 11 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 3 * (f &&&  ~~~(d ^^^ e)) - 1 * (e ^^^  ~~~(d &&& (e ||| f))) - 6 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 1 * ( ~~~f |||  ~~~(d ^^^ e)) + 11 * ( ~~~f &&& (d ^^^ e)) - 23 *  ~~~(d ||| (e ||| f)) - 53 *  ~~~(d ||| ( ~~~e ||| f)) - 19 *  ~~~( ~~~d ||| (e ||| f)) - 27 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 23 * ( ~~~d &&& ( ~~~e &&& f)) - 43 * ( ~~~d &&& (e &&& f)) - 33 * (d &&& ( ~~~e &&& f)) - 45 * (d &&& (e &&& f)) =  - 5 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 2 * ((d ||| e) &&&  ~~~(e ^^^ f))

theorem sub_shl_same_amount_partial_nuw1_proof : sub_shl_same_amount_partial_nuw1_before ⊑ sub_shl_same_amount_partial_nuw1_after

theorem and_or_not_not_commute6_proof : and_or_not_not_commute6_before ⊑ and_or_not_not_commute6_after

theorem sel_false_val_is_a_masked_ashr_of_true_val2_thm.extracted_1._2 : ∀ (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 ∨
            True ∧ (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)).msb = true ∨
              zeroExtend 64 (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)) ≥ ↑64) →
        x = x.sshiftRight' (zeroExtend 64 (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)))

theorem ashrsgt_01_05_exact_proof : ashrsgt_01_05_exact_before ⊑ ashrsgt_01_05_exact_after

@[simp]
theorem and_add_xor_eq_or {a b : BitVec w} : (a &&& b) + (a ^^^ b) = a ||

theorem or_not_xor_common_op_commute2_thm (e e_1 e_2 : IntW 8) :
  LLVM.or (LLVM.xor e_2 e_1) (LLVM.or (sub (const? 8 0) e) (LLVM.xor e_2 (const? 8 (-1)))) ⊑
    LLVM.or (LLVM.xor (LLVM.and e_2 e_1) (const? 8 (-1))) (sub (const? 8 0) e)

theorem test44_thm.extracted_1._1 : ∀ (x : BitVec 8), True ∧ (zeroExtend 16 x ||| 1234#16).msb = true → False

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

theorem urem_illegal_type_c_thm.extracted_1._1 : ∀ (x : BitVec 9),
  ¬10#32 = 0 → 10#9 = 0 ∨ True ∧ (x % 10#9).msb = true → False

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

theorem pr51551_neg2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (x_1 &&& BitVec.ofInt 32 (-7)).smulOverflow x = true) →
    ¬truncate 1 x_1 ^^^ 1#1 = 1#1 →
      ofBool ((x_1 &&& BitVec.ofInt 32 (-7)) * x &&& 7#32 == 0#32) = ofBool (x &&& 7#32 == 0#32)

theorem ashr_ult_14_proof : ashr_ult_14_before ⊑ ashr_ult_14_after

theorem main_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(6#8 ≥ ↑8 ∨ 7#8 ≥ ↑8) → 5#8 ≥ ↑8 ∨ True ∧ ((truncate 8 x ^^^ -1#8) <<< 5#8 &&& 64#8).msb = true → False

theorem liftEffect_eq_pure_cast {m : Type → Type} [Pure m]
    {eff : EffectKind} (eff_eq : eff = .pure) (eff_le : eff ≤ .impure) :
    liftEffect eff_le = fun (x : eff.toMonad m α) =>
      Pure.pure (cast (by rw [eff_eq]; rfl) x)

theorem test6_proof : test6_before ⊑ test6_after

theorem ule_swap_and_min_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x ≤ᵤ x_1) = 1#1 → 0#1 = ofBool (x == 0#8)

theorem ule_swap_or_not_min_logical_proof : ule_swap_or_not_min_logical_before ⊑ ule_swap_or_not_min_logical_after

theorem lshrult_02_04_exact_proof : lshrult_02_04_exact_before ⊑ lshrult_02_04_exact_after

theorem select_icmp_eq_and_4096_0_xor_4096_proof : select_icmp_eq_and_4096_0_xor_4096_before ⊑ select_icmp_eq_and_4096_0_xor_4096_after

theorem test1_thm.extracted_1._2 : ∀ (x : BitVec 17),
  ¬(8#37 ≥ ↑37 ∨ 8#37 ≥ ↑37) →
    ¬(8#17 ≥ ↑17 ∨ 8#17 ≥ ↑17) →
      truncate 17 (zeroExtend 37 x >>> 8#37 ||| zeroExtend 37 x <<< 8#37) = x >>> 8#17 ||

theorem icmp_shl_nsw_sge0_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ (x <<< 21#32).sshiftRight' 21#32 ≠ x ∨ 21#32 ≥ ↑32) → ofBool (0#32 ≤ₛ x <<< 21#32) = ofBool (-1#32 <ₛ x)

theorem xor_to_xor1_proof : xor_to_xor1_before ⊑ xor_to_xor1_after

theorem ashr_eq_both_equal_proof : ashr_eq_both_equal_before ⊑ ashr_eq_both_equal_after

@[simp]
theorem eval_map_id_eq' {c : Circuit α} {f : α → Bool} :
    eval (map c fun v => v) f = eval c f

theorem slt_and_max_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.slt e_1 e) (icmp IntPred.eq e_1 (const? 8 127)) (const? 1 0) ⊑ const? 1 0

theorem exact_lshr_eq_both_equal_proof : exact_lshr_eq_both_equal_before ⊑ exact_lshr_eq_both_equal_after

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

theorem ashrslt_03_11_exact_proof : ashrslt_03_11_exact_before ⊑ ashrslt_03_11_exact_after

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

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

theorem t3_no_extrause_proof : t3_no_extrause_before ⊑ t3_no_extrause_after

theorem n10_thm (e : IntW 8) :
  icmp IntPred.sgt (sub (const? 8 0) e) e ⊑ icmp IntPred.slt e (sub (const? 8 0) e)

theorem foo1_and_signbit_lshr_without_shifting_signbit_both_sides_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(x_1 ≥ ↑32 ∨ x ≥ ↑32) →
    ofBool (-1#32 <ₛ x_2 <<< x_1) ||

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

theorem gt_signed_to_large_signed_thm (e : IntW 8) : icmp IntPred.sgt (sext 32 e) (const? 32 1024) ⊑ const? 1 0

theorem positive_biggerLshr_lshrexact_proof : positive_biggerLshr_lshrexact_before ⊑ positive_biggerLshr_lshrexact_after

theorem not_or_or_and_not_and_and_commute2_or_proof : not_or_or_and_not_and_and_commute2_or_before ⊑ not_or_or_and_not_and_and_commute2_or_after

theorem lshrugt_01_06_proof : lshrugt_01_06_before ⊑ lshrugt_01_06_after

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

@[simp]
theorem instantiate_mvar_zero' :
    (mvar (φ := 1) ⟨0, by simp⟩).instantiate (Subtype.mk [w] (by simp)) = w

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

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

theorem t3_no_extrause_thm (e e_1 : IntW 8) :
  icmp IntPred.uge (LLVM.xor e_1 (const? 8 (-1))) e ⊑
    icmp IntPred.ule e (LLVM.xor e_1 (const? 8 (-1)))

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

theorem icmp_sgt7_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (x <<< 1#8).sshiftRight' 1#8 ≠ x ∨ 1#8 ≥ ↑8) → ofBool (124#8 <ₛ x <<< 1#8) = ofBool (62#8 <ₛ x)

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

theorem 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 a_true_implies_b_false2_comm_thm.extracted_1._4 : ∀ (x : BitVec 1) (x_1 : BitVec 8),
  ¬ofBool (x_1 == 10#8) = 1#1 → ¬ofBool (20#8 <ᵤ x_1) = 1#1 → x &&& ofBool (20#8 <ᵤ x_1) = 0#1

theorem xor_ashr_not_proof : xor_ashr_not_before ⊑ xor_ashr_not_after

theorem lshr_pow2_ult_smin_proof : lshr_pow2_ult_smin_before ⊑ lshr_pow2_ult_smin_after

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

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

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

theorem test86_proof : test86_before ⊑ test86_after

theorem e_934 :
    2 *  ~~~(z &&&  ~~~t) - 1 *  ~~~(z &&& t) + 11 * t - 1 *  ~~~(z ||| t) - 12 *  ~~~(z |||  ~~~t) - 17 * (z &&& t) = 3 * (z &&&  ~~~t) - 4 * z

theorem trunc_ashr_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬8#36 ≥ ↑36 →
    ¬8#32 ≥ ↑32 →
      truncate 32 ((zeroExtend 36 x ||| BitVec.ofInt 36 (-2147483648)).sshiftRight' 8#36) =
        x >>> 8#32 ||

theorem or_xor_and_commuted2_proof : or_xor_and_commuted2_before ⊑ or_xor_and_commuted2_after

theorem eq_smax4_proof : eq_smax4_before ⊑ eq_smax4_after

theorem test18_thm.extracted_1._4 : ∀ (x : BitVec 16) (x_1 : BitVec 32),
  ¬ofBool (x &&& 4#16 != 0#16) = 1#1 → ¬ofBool (x &&& 4#16 == 0#16) = 1#1 → ¬64#32 = 0 → x_1 % 64#32 = x_1 &&& 31#32

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

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

theorem src_srem_shl_demand_max_signbit_mask_hit_first_demand_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬((4#32 == 0 || 32 != 1 && x == intMin 32 && 4#32 == -1) = true ∨ 29#32 ≥ ↑32) →
    (4#32 == 0 || 32 != 1 && x == intMin 32 && 4#32 == -1) = true ∨
        True ∧ (x.srem 4#32 <<< 29#32).sshiftRight' 29#32 ≠ x.srem 4#32 ∨ 29#32 ≥ ↑32 →
      False

theorem C0zero_thm.extracted_1._4 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 + 10#8 <ᵤ 0#8) = 1#1 → ¬ofBool (x_1 <ₛ BitVec.ofInt 8 (-10)) = 1#1 → False

theorem icmp_x_slt_0_and_icmp_y_sgt_neg1_i32_fail_proof : icmp_x_slt_0_and_icmp_y_sgt_neg1_i32_fail_before ⊑ icmp_x_slt_0_and_icmp_y_sgt_neg1_i32_fail_after

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

theorem set_to_set_decomposebittest_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ofBool (x <ₛ 0#8) = 1#1 →
    ¬(True ∧ (x &&& BitVec.ofInt 8 (-128) &&& 3#8 != 0) = true) →
      BitVec.ofInt 8 (-125) = x &&& BitVec.ofInt 8 (-128) ||

theorem select_icmp_eq_and_1_0_or_2_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 1#32 == 0#32) = 1#1 → 1#32 ≥ ↑32 → False

@[simp]
theorem eval_mkCarryAssignCircuitN_eq_false_iff {arity : Type _}
  [DecidableEq arity]
  [Fintype arity]
  [Hashable arity]
  (p : FSM arity) (n : Nat)
  {env : Vars p.α arity (n + 1) → Bool} :
  ((mkCarryAssignCircuitN p n).eval env = false) ↔
    (∀ (s : p.α), env (Vars.stateN s (n + 1)) = (mkCarryAssignCircuitNAux p s n).eval env)

theorem eq_nsw_rem_zero_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.smulOverflow (BitVec.ofInt 8 (-5)) = true) →
    ofBool (x * BitVec.ofInt 8 (-5) == 20#8) = ofBool (x == BitVec.ofInt 8 (-4))

theorem icmp_ne_sext_eq_zero_proof : icmp_ne_sext_eq_zero_before ⊑ icmp_ne_sext_eq_zero_after

theorem mul_constant_nuw_eq_proof : mul_constant_nuw_eq_before ⊑ mul_constant_nuw_eq_after

theorem lshrugt_02_12_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬2#4 ≥ ↑4 → ofBool (BitVec.ofInt 4 (-4) <ᵤ x >>> 2#4) = 0#1

theorem test19_thm (e e_1 : IntW 32) :
  urem e_1 (add (LLVM.and (shl (const? 32 1) e) (shl (const? 32 1) e_1)) (shl (const? 32 1) e)) ⊑
    LLVM.and e_1
      (add
        (add
          (LLVM.and (shl (const? 32 1) e { «nsw» := false, «nuw» := true })
            (shl (const? 32 1) e_1 { «nsw» := false, «nuw» := true }))
          (shl (const? 32 1) e { «nsw» := false, «nuw» := true }))
        (const? 32 (-1)))

theorem n10_proof : n10_before ⊑ n10_after

@[simp]
lemma tru_or (c : Circuit α) :
  Circuit.tru ||

theorem sle_smax1_proof : sle_smax1_before ⊑ sle_smax1_after

theorem icmp_ne_and_pow2_minus1_shl1_thm (e : IntW 32) :
  zext 32 (icmp IntPred.ne (LLVM.and (shl (const? 32 1) e) (const? 32 15)) (const? 32 0)) ⊑
    zext 32 (icmp IntPred.ult e (const? 32 4))

theorem select_icmp_ne_0_and_1073741824_xor_8_proof : select_icmp_ne_0_and_1073741824_xor_8_before ⊑ select_icmp_ne_0_and_1073741824_xor_8_after

theorem positive_with_mask_logical_proof : positive_with_mask_logical_before ⊑ positive_with_mask_logical_after

@[simp, simp_sllvm]
theorem bind_eq (x : EffectM α) (f : α → EffectM β) (s) :
    (x >>= f) s = x s >>= (fun (x, s) => f x s)

theorem select_ashr_icmp_bad_proof : select_ashr_icmp_bad_before ⊑ select_ashr_icmp_bad_after

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

theorem exact_lshr_eq_both_equal_thm (e : IntW 8) :
  icmp IntPred.eq (lshr (const? 8 126) e { «exact» := true }) (const? 8 126) ⊑
    icmp IntPred.eq e (const? 8 0)

theorem AvoidCollision_toNat_signExtend (x : BitVec w) {v : Nat} :
    (x.signExtend v).toNat = (x.setWidth v).toNat + if x.msb then 2^v - 2^w else 0

theorem unfold :
    x ~ y → ∃ n m,
      x.drop (n+1) ~ y.drop (m+1)
      ∧ x.get n = y.get m
      ∧ (∀ i < n, x.get i = none)
      ∧ (∀ j < m, y.get j = none)

theorem add_const_add_const_thm (e : IntW 32) : add (add e (const? 32 8)) (const? 32 2) ⊑ add e (const? 32 10)

theorem max_of_min_swap_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬ofBool (x <ₛ 0#32) = 1#1 → ofBool (-1#32 <ₛ x ^^^ -1#32) = 1#1 → x ^^^ -1#32 = -1#32

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

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

theorem 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 lshrugt_01_15_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 1#4 <<< 1#4 ≠ x ∨ 1#4 ≥ ↑4) → ofBool (-1#4 <ᵤ x >>> 1#4) = 0#1

theorem uge_swap_or_not_max_proof : uge_swap_or_not_max_before ⊑ uge_swap_or_not_max_after

theorem trunc_sel_larger_zext_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → zeroExtend 64 42#16 = 42#64

theorem select_replace_one_use_proof : select_replace_one_use_before ⊑ select_replace_one_use_after

theorem land_land_right2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), x_1 = 1#1 ∧ x = 1#1 → ¬x_1 = 1#1 → x_1 = 0#1

theorem src_is_mask_zext_proof : src_is_mask_zext_before ⊑ src_is_mask_zext_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1b_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1b_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1b_logical_after

theorem and_ne_with_one_bit_diff_constants3_logical_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x != 65#8) = 1#1 → ofBool (x != BitVec.ofInt 8 (-63)) = ofBool (x &&& 127#8 != 65#8)

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

theorem gt_signed_to_small_unsigned_thm (e : IntW 8) :
  icmp IntPred.ugt (sext 32 e) (const? 32 17) ⊑ icmp IntPred.ugt e (const? 8 17)

theorem uadd_sat_flipped_wrong_bounds_thm (e : IntW 32) :
  select (icmp IntPred.uge e (const? 32 (-12))) (const? 32 (-1)) (add e (const? 32 9)) ⊑
    select (icmp IntPred.ugt e (const? 32 (-13))) (const? 32 (-1)) (add e (const? 32 9))

theorem positive_and_odd_eq_proof : positive_and_odd_eq_before ⊑ positive_and_odd_eq_after

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

theorem test_logical_and_ne_a_b_proof : test_logical_and_ne_a_b_before ⊑ test_logical_and_ne_a_b_after

theorem positive_with_icmp_proof : positive_with_icmp_before ⊑ positive_with_icmp_after

theorem test_trunc_thm (e : IntW 8) :
  LLVM.xor (trunc 8 (ashr (add (zext 32 e) (const? 32 (-1)) { «nsw» := true, «nuw» := false }) (const? 32 31)))
      (const? 8 (-1)) ⊑
    sext 8 (icmp IntPred.ne e (const? 8 0))

theorem select_replace_nested_no_simplify_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 == 1#32) = 1#1 → x_1 - x_2 + x = x_1 + -1#32 + x

theorem com_ty : com.2.2.1 = [.bitvec 32]

theorem t8_proof : t8_before ⊑ t8_after

theorem BitVec.even_mul_eq_shiftLeft_mul_of_eq_mul_two
    (w : Nat) (x : BitVec w) (n e : Nat) (he : e = n * 2) :
    (BitVec.ofNat w e) * x = (BitVec.ofNat w n) * (x <<< (1 : Nat))

theorem cv2_proof : cv2_before ⊑ cv2_after

theorem PR42691_3_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (0#32 ≤ₛ x) ||

theorem udiv_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 bools_logical_commute1_thm.extracted_1._14 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 = 1#1 → ¬x_1 = 1#1 → ¬0#1 = 1#1 → 0#1 = x_2

theorem uadd_sat_flipped_wrong_bounds6_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x ≤ᵤ BitVec.ofInt 32 (-12)) = 1#1 → ¬ofBool (x <ᵤ BitVec.ofInt 32 (-11)) = 1#1 → x + 9#32 = -1#32

theorem flip_masked_bit_proof : flip_masked_bit_before ⊑ flip_masked_bit_after

theorem test_ne_11_and_15_add_10_proof : test_ne_11_and_15_add_10_before ⊑ test_ne_11_and_15_add_10_after

theorem sge_or_not_max_logical_proof : sge_or_not_max_logical_before ⊑ sge_or_not_max_logical_after

theorem icmp_eq_zext_eq_non_boolean_proof : icmp_eq_zext_eq_non_boolean_before ⊑ icmp_eq_zext_eq_non_boolean_after

theorem a_true_implies_b_false2_thm.extracted_1._4 : ∀ (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 e_1233 :
    7 * (z ||| t) - 7 *  ~~~(z &&&  ~~~t) - 5 *  ~~~t + 4 *  ~~~(z &&& t) - 1 * (z ^^^ t) + 7 * (z |||  ~~~t) + 1 * z + 1 *  ~~~(z ||| t) - 3 *  ~~~(z |||  ~~~t) = 13 * (z &&&  ~~~t) + 8 * (z &&& t)

theorem neg_of_sub_from_constant_proof : neg_of_sub_from_constant_before ⊑ neg_of_sub_from_constant_after

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

theorem exact_lshr_ne_opposite_msb_proof : exact_lshr_ne_opposite_msb_before ⊑ exact_lshr_ne_opposite_msb_after

theorem alive_276 : alive_276_src ⊑ alive_276_tgt

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

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

theorem test_trunc_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (zeroExtend 32 x).saddOverflow (-1#32) = true ∨ 31#32 ≥ ↑32) →
    truncate 8 ((zeroExtend 32 x + -1#32).sshiftRight' 31#32) ^^^ -1#8 = signExtend 8 (ofBool (x != 0#8))

theorem select_icmp_x_and_8_eq_0_y_xor_8_thm (e : IntW 64) (e_1 : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e_1 (const? 32 8)) (const? 32 0)) e (LLVM.xor e (const? 64 8)) ⊑
    LLVM.xor e (zext 64 (LLVM.and e_1 (const? 32 8)) { «nneg» := true })

@[simp] theorem  or_eq : (x ||| y) i = (x i || y i)

theorem matchVar_appendInl {w : Var ⟨te⟩ t} :
    matchVar lets v (.var matchLets matchExpr) w.appendInl ma = some ma' →
    ∃ args,
      lets.getPureExpr v
        = some ⟨_, w, matchExpr.op, matchExpr.ty_eq, matchExpr.eff_le, args, matchExpr.regArgs⟩
      ∧ matchArg lets matchLets args matchExpr.args ma = some ma'

theorem eq_signed_to_small_unsigned_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x == 17#32) = ofBool (x == 17#8)

theorem PR42691_4_proof : PR42691_4_before ⊑ PR42691_4_after

theorem and_ashr_not_proof : and_ashr_not_before ⊑ and_ashr_not_after

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

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

theorem positive_sameconst_shlnuwnsw_proof : positive_sameconst_shlnuwnsw_before ⊑ positive_sameconst_shlnuwnsw_after

theorem or_min_31_30_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬ofBool (x <ᵤ BitVec.ofInt 8 (-30)) = 1#1 → BitVec.ofInt 8 (-30) ||

theorem ite_eq_of_eq_false {cond t f : Circuit α} (h : cond.eval g = false) :
    (ite cond t f).eval g = f.eval g

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

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

theorem ugt_rem_nz_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.umulOverflow 5#8 = true) → ofBool (21#8 <ᵤ x * 5#8) = ofBool (4#8 <ᵤ x)

theorem shl_trunc_smaller_ashr_thm (e : IntW 32) :
  shl (trunc 24 (ashr e (const? 32 10))) (const? 24 13) ⊑
    LLVM.and (shl (trunc 24 e) (const? 24 3)) (const? 24 (-8192))

theorem ashr_lowmask_proof : ashr_lowmask_before ⊑ ashr_lowmask_after

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

theorem src_proof : src_before ⊑ src_after

theorem t6_no_extrause_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x_1 + x <ᵤ x) = ofBool (x ^^^ -1#8 <ᵤ x_1)

theorem p_constmask2_proof : p_constmask2_before ⊑ p_constmask2_after

@[simp] lemma eval_scanor_false_iff (x : Unit → BitStream) (n : Nat) : scanOr.eval x n = false ↔ (∀ (i : Nat), (hi : i ≤ n) → x () i = false)

theorem ashr_ult_11_thm (e : IntW 4) :
  icmp IntPred.ult (ashr e (const? 4 1)) (const? 4 (-5)) ⊑ icmp IntPred.sgt e (const? 4 (-1))

@[simp]
lemma in_enc : x ∈ enc '' S ↔ dec x ∈ S

omit [LawfulBEq A] [Fintype S] [DecidableEq S] in
lemma addOrCreateElem_visited final? (st : worklist.St A S) sa :
    st.addOrCreateState _ _ final? sa |>.2.visited = st.visited

theorem test_negative_combined_sub_unsigned_overflow_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ (10#64).usubOverflow x = true) → ofBool (10#64 - x <ᵤ 11#64) = 1#1

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

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

theorem ashrslt_03_06_exact_proof : ashrslt_03_06_exact_before ⊑ ashrslt_03_06_exact_after

theorem sub_eq_add_not_add_one :
    x - y = x + ~~~ y + 1

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

theorem sub_ashr_and_i8_thm (e e_1 : IntW 8) :
  LLVM.and (ashr (sub e_1 e { «nsw» := true, «nuw» := false }) (const? 8 7)) e ⊑
    select (icmp IntPred.slt e_1 e) e (const? 8 0)

theorem mul_constant_mismatch_wrap_eq_thm (e e_1 : IntW 32) :
  icmp IntPred.eq (mul e_1 (const? 32 54) { «nsw» := true, «nuw» := false })
      (mul e (const? 32 54) { «nsw» := false, «nuw» := true }) ⊑
    icmp IntPred.eq (LLVM.and (LLVM.xor e_1 e) (const? 32 2147483647)) (const? 32 0)

theorem sle_swap_and_min_proof : sle_swap_and_min_before ⊑ sle_swap_and_min_after

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

theorem p0_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x ≤ₛ x &&& 3#8) = ofBool (x <ₛ 4#8)

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

theorem fold_sext_to_and3_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x &&& 1073741826#32 != 2#32) = ofBool (x &&& BitVec.ofInt 8 (-126) != 2#8)

theorem sext_ule_sext_proof : sext_ule_sext_before ⊑ sext_ule_sext_after

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

theorem zext_sext_add_icmp_ne_1_proof : zext_sext_add_icmp_ne_1_before ⊑ zext_sext_add_icmp_ne_1_after

theorem main7a_logical_proof : main7a_logical_before ⊑ main7a_logical_after

theorem test4_proof : test4_before ⊑ test4_after

theorem main5c_like_proof : main5c_like_before ⊑ main5c_like_after

theorem add_eq (x : BitVec w) : x = x + 0

theorem xor_of_icmps_proof : xor_of_icmps_before ⊑ xor_of_icmps_after

theorem e_562 :
    2 * (x |||  ~~~y) + 5 *  ~~~y + 1 *  ~~~(x &&&  ~~~x) + 2 * (x ||| y) + 2 *  ~~~(x ^^^ y) - 10 *  ~~~(x ||| y) - 2 *  ~~~(x |||  ~~~y) - 9 * (x &&&  ~~~y) - 7 * (x &&& y) = 1 * (x ^^^ y)

theorem not_match_inconsistent_signs_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬(299#64 = 0 ∨ (299#64 == 0 || 64 != 1 && x == intMin 64 && 299#64 == -1) = true ∨ 64#64 = 0) →
    ¬(299#64 = 0 ∨
          (299#64 == 0 || 64 != 1 && x == intMin 64 && 299#64 == -1) = true ∨
            True ∧ (x.sdiv 299#64 &&& 63#64).smulOverflow 299#64 = true ∨
              True ∧ (x.sdiv 299#64 &&& 63#64).umulOverflow 299#64 = true ∨
                True ∧ (x % 299#64).saddOverflow ((x.sdiv 299#64 &&& 63#64) * 299#64) = true ∨
                  True ∧ (x % 299#64).uaddOverflow ((x.sdiv 299#64 &&& 63#64) * 299#64) = true) →
      x % 299#64 + x.sdiv 299#64 % 64#64 * 299#64 = x % 299#64 + (x.sdiv 299#64 &&& 63#64) * 299#64

theorem add_signbit_select_shl_proof : add_signbit_select_shl_before ⊑ add_signbit_select_shl_after

theorem udiv_icmp1_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ x.umod 5#64 ≠ 0 ∨ 5#64 = 0) → ofBool (x / 5#64 != 0#64) = ofBool (x != 0#64)

theorem lowmask_sub_zext_commute_thm.extracted_1._1 : ∀ (x : BitVec 5) (x_1 : BitVec 17),
  x_1 - zeroExtend 17 x &&& 31#17 = zeroExtend 17 (truncate 5 x_1 - x)

theorem e_802 :
     - 3 *  ~~~z + 1 *  ~~~(z &&&  ~~~t) - 7 *  ~~~t + 9 *  ~~~(z ||| t) - 1 * (z &&& t) =  - 7 * (z &&&  ~~~t) - 2 *  ~~~(z |||  ~~~t)

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

lemma reduce_eval {M : NFA α σ} {w} (q : σ) : (∃ hq, ⟨q, hq⟩ ∈ M.reduce.eval w) ↔ q ∈ M.eval w

theorem bswap_and_mask_1_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(40#64 ≥ ↑64 ∨ 56#64 ≥ ↑64) →
    40#64 ≥ ↑64 ∨ 56#64 ≥ ↑64 ∨ True ∧ (x >>> 40#64 &&& 65280#64 &&& x >>> 56#64 != 0) = true → False

@[simp] theorem Ctxt.get_add_bvars (e : Expr d Γ eff ts) (i : Nat) :
    e.outContext[i + e.bvars]? = Γ[i]?

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

@[grind ., simp]
lemma wf_createSink [LawfulBEq A] {m : RawCNFA A} (hwf : m.WF) : m.createSink.2.WF

theorem test52_thm.extracted_1._1 : ∀ (x : BitVec 64),
  True ∧ (truncate 16 x &&& 7224#16 &&& BitVec.ofInt 16 (-32574) != 0) = true → False

theorem ashr_ugt_5_thm (e : IntW 4) :
  icmp IntPred.ugt (ashr e (const? 4 1)) (const? 4 5) ⊑ icmp IntPred.slt e (const? 4 0)

theorem test_shl_nsw__nuw_is_safe_proof : test_shl_nsw__nuw_is_safe_before ⊑ test_shl_nsw__nuw_is_safe_after

theorem ashr_ugt_4_proof : ashr_ugt_4_before ⊑ ashr_ugt_4_after

theorem test10_proof : test10_before ⊑ test10_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 bools2_logical_commute1_and1_and2_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 &&& x_1 = 1#1 → x_1 = 1#1 → (x_1 ^^^ 1#1) &&& x = x_2

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

theorem icmp_power2_and_icmp_shifted_mask_2147483648_1610612736_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x <ᵤ BitVec.ofInt 32 (-2147483648)) &&& ofBool (x &&& 1610612736#32 != 1610612736#32) =
    ofBool (x <ᵤ 1610612736#32)

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

theorem p0_proof : p0_before ⊑ p0_after

theorem test_add__none_are_safe_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (x == 3#32) = 1#1 → 4#32 = x + 1#32

theorem PR51351_proof : PR51351_before ⊑ PR51351_after

theorem reused_mul_nuw_xy_z_selectnonzero_ugt_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 8),
  ofBool (x_2 != 0#8) = 1#1 →
    ¬(True ∧ x_1.umulOverflow x_2 = true ∨ True ∧ x.umulOverflow x_2 = true) →
      ofBool (x_2 == 0#8) = 1#1 → ofBool (x * x_2 <ᵤ x_1 * x_2) = 1#1

theorem and_not_or_or_not_or_xor_commute5_proof : and_not_or_or_not_or_xor_commute5_before ⊑ and_not_or_or_not_or_xor_commute5_after

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

theorem lshr_2_add_zext_basic_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  ¬1#2 ≥ ↑2 → (zeroExtend 2 x_1 + zeroExtend 2 x) >>> 1#2 = zeroExtend 2 (x_1 &&& x)

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

theorem PR2844_logical_proof : PR2844_logical_before ⊑ PR2844_logical_after

theorem com_Γ : com.1 = (Γn 1)

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

theorem ashr_lshr_wrong_cond_proof : ashr_lshr_wrong_cond_before ⊑ ashr_lshr_wrong_cond_after

theorem shl_xor_xor_good_mask_proof : shl_xor_xor_good_mask_before ⊑ shl_xor_xor_good_mask_after

theorem bv_AndOrXor_887_2 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.and (LLVM.icmp LLVM.IntPred.eq e e_1) (LLVM.icmp LLVM.IntPred.ne e e_1) ⊑ LLVM.const? 1 0

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

theorem bools2_logical_commute1_thm.extracted_1._9 : ∀ (x x_1 : BitVec 1),
  ¬x_1 = 1#1 → ¬x ^^^ 1#1 = 1#1 → ¬x = 1#1 → 0#1 = 1#1 → False

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

theorem shl_add_nuw_and_nsw_proof : shl_add_nuw_and_nsw_before ⊑ shl_add_nuw_and_nsw_after

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

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

theorem test1_proof : test1_before ⊑ test1_after

theorem substitute_constant_or_ne_swap_sle_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.ne e_1 (const? 8 42)) (const? 1 1) (icmp IntPred.sle e e_1) ⊑
    select (icmp IntPred.ne e_1 (const? 8 42)) (const? 1 1) (icmp IntPred.slt e (const? 8 43))

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 lshr_not_nneg2_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬1#8 ≥ ↑8 → 1#8 ≥ ↑8 ∨ True ∧ (x >>> 1#8 &&& BitVec.ofInt 8 (-128) != 0) = true → False

theorem zext_sext_add_icmp_slt_1_rhs_not_const_proof : zext_sext_add_icmp_slt_1_rhs_not_const_before ⊑ zext_sext_add_icmp_slt_1_rhs_not_const_after

theorem positive_with_aggressive_icmp_proof : positive_with_aggressive_icmp_before ⊑ positive_with_aggressive_icmp_after

theorem ult_swap_and_max_proof : ult_swap_and_max_before ⊑ ult_swap_and_max_after

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

theorem main4c_proof : main4c_before ⊑ main4c_after

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

theorem e_2073 :
     - 7 * (e &&& (d ^^^ f)) - 1 * (d ^^^ ( ~~~e &&& f)) - 6 *  ~~~( ~~~d ||| (e ^^^ f)) - 1 * (d ||| ( ~~~e ||| f)) + 2 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 4 *  ~~~(d &&&  ~~~d) + 7 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 11 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 5 *  ~~~(d &&& f) - 3 * (f ^^^ ( ~~~d ||| (e ||| f))) + 2 *  ~~~(d &&& (e ||| f)) + 11 *  ~~~(d ||| (e &&& f)) + 3 * (e ^^^ (d ||| f)) - 3 * ( ~~~d ||| ( ~~~e &&& f)) - 2 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 11 * ((d &&& f) ^^^ (e ||| f)) + 2 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 11 *  ~~~(d ^^^ (e &&& f)) + 1 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 3 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 11 * (d &&& (e ||| f)) - 11 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 1 * (f ^^^  ~~~(d ||| e)) + 1 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 4 * (e ^^^ (d &&& (e ||| f))) - 1 * (e |||  ~~~f) - 6 * ( ~~~f &&&  ~~~(d ^^^ e)) - 1 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) - 6 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 1 *  ~~~(d &&& e) + 2 *  ~~~( ~~~d &&& (e ||| f)) - 1 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 * (e ||| (d &&& f)) + 14 *  ~~~(d ||| (e ||| f)) - 18 *  ~~~(d ||| ( ~~~e ||| f)) - 10 *  ~~~( ~~~d ||| (e ||| f)) - 16 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 11 * ( ~~~d &&& ( ~~~e &&& f)) - 22 * (d &&& ( ~~~e &&& f)) - 9 * (d &&& (e &&& f)) = 30 * ( ~~~d &&& (e &&& f)) - 7 * (d &&& f)

theorem ashrslt_02_02_proof : ashrslt_02_02_before ⊑ ashrslt_02_02_after

theorem e_2429 :
     - 1 *  ~~~( ~~~d ||| (e &&& f)) + 5 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 1 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 2 * (e ^^^ (d &&&  ~~~f)) - 7 *  ~~~( ~~~d &&& (e ||| f)) + 4 * (e |||  ~~~(d ||| f)) + 11 *  ~~~(e ||| f) - 1 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 3 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 7 * (f ^^^  ~~~(d &&& (e &&& f))) - 5 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 2 * (e ^^^ (d |||  ~~~f)) + 3 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 2 * (e ||| (d &&&  ~~~f)) + 11 * (f ||| (d &&&  ~~~e)) + 1 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 6 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 1 *  ~~~(d &&& ( ~~~e &&& f)) - 1 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 11 *  ~~~f - 11 * (e ^^^ (d ||| ( ~~~e &&& f))) + 7 * (f ^^^ (d ||| (e ||| f))) + 7 * (d |||  ~~~f) - 2 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 2 * (f ^^^  ~~~(d |||  ~~~e)) + 3 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 3 * ((d &&& e) |||  ~~~(e |||  ~~~f)) - 7 * (e ^^^ (d &&& f)) + 2 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 * (f ||| (d ^^^ e)) + 1 * (e &&&  ~~~(d ^^^ f)) - 3 * (e ^^^ (d ||| (e &&& f))) - 1 * (d ^^^ e) - 6 * (d ^^^ (e ||| f)) + 7 *  ~~~d + 1 *  ~~~(d &&& ( ~~~e ||| f)) + 1 * ( ~~~d ||| ( ~~~e ||| f)) + 11 * (f ^^^  ~~~(d &&& e)) + 1 * (e ^^^  ~~~(d &&& f)) + 2 * ( ~~~e &&&  ~~~(d ^^^ f)) - 2 *  ~~~(d |||  ~~~f) + 1 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 6 *  ~~~(d &&& (e &&& f)) - 2 *  ~~~(d &&&  ~~~e) - 3 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * (f &&& (d |||  ~~~e)) + 1 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 11 *  ~~~(e &&& f) - 5 * ( ~~~d ||| (e ||| f)) - 6 * (f ^^^ (d &&&  ~~~e)) - 2 * (f ^^^ ( ~~~d &&& (e ||| f))) + 1 * (e ^^^ (d &&& (e ||| f))) + 2 *  ~~~(d ||| ( ~~~e &&& f)) + 11 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 3 * ((d &&& f) ||| (e &&&  ~~~f)) - 5 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 1 * (d &&& f) - 5 * d + 4 * ((d &&& f) ^^^ (e ||| f)) + 5 * (e &&&  ~~~(d &&& f)) - 1 * (d &&& ( ~~~e ||| f)) + 2 * (d ^^^ f) - 7 * (e &&& f) + 5 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 2 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) + 11 * (d ^^^ ( ~~~e &&& f)) - 9 *  ~~~(d ||| (e ||| f)) + 16 *  ~~~(d ||| ( ~~~e ||| f)) + 27 *  ~~~( ~~~d ||| (e ||| f)) + 22 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 2 * ( ~~~d &&& ( ~~~e &&& f)) + 14 * ( ~~~d &&& (e &&& f)) + 28 * (d &&& ( ~~~e &&& f)) - 20 * (d &&& (e &&& f)) =  - 2 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 2 *  ~~~(d ^^^ ( ~~~e ||| f))

theorem Array.mem_take_get_succ {a : Array α} {n} (h : n < a.size) : x ∈ a.take (n + 1) ↔ (a[n]'h = x ∨ x ∈ a.take n)

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

theorem xor_of_icmps_to_ne_commute_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ofBool (x <ₛ 6#64) ^^^ ofBool (4#64 <ₛ x) = ofBool (x != 5#64)

theorem lshr_xor_thm (e e_1 : IntW 8) :
  shl (LLVM.xor (lshr e_1 (const? 8 3)) (LLVM.srem e (const? 8 42))) (const? 8 3) ⊑
    LLVM.xor (LLVM.and e_1 (const? 8 (-8))) (shl (LLVM.srem e (const? 8 42)) (const? 8 3))

theorem t0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 == x) = 1#1 → ofBool (x_1 != x) = 1#1 → 0#1 ^^^ 1#1 = 1#1
</all_available_lemmas>

<local_ctx>
import Mathlib.Data.Bool.Basic

import Mathlib.Data.Fin.Basic

import Blase.Fast.BitStream

import Blase.SingleWidth.Defs

open Term

open BitStream in

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.evalEq (t₁ t₂ : BitStream) : BitStream := (t₁ ^^^ t₂).concat false |>.scanOr

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

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

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

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

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

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

open BitStream in

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

section Predicate

end Predicate
</local_ctx>

<target_theorem>
theorem Predicate.evalUlt_denote_true_iff {w : Nat} (a b : Term) (vars : List (BitVec w)) :
    evalUlt (a.eval (List.map .ofBitVecSext vars)) (b.eval (List.map .ofBitVecSext vars)) w = true ↔
      (Term.denote w b vars) ≤ (Term.denote w a vars) :=
</target_theorem>

