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>
Fin in Init.Prelude
Fin.last in Init.Data.Fin.Basic
Nat in Init.Prelude
Fin.castLE in Init.Data.Fin.Basic
BitVec in Init.Prelude
BitVec.ofNat in Init.Prelude
BitVec.zero in Init.Data.BitVec.Basic
List in Init.Prelude
List.Vector in Mathlib.Data.Vector.Defs
Set in Mathlib.Data.Set.Defs
Fintype in Mathlib.Data.Fintype.Defs
Repr in Init.Data.Repr
Bool in Init.Prelude
BitVec.iunfoldr in Init.Data.BitVec.Folds
Vector in Init.Data.Vector.Basic
Vector.ofFn in Init.Data.Vector.Basic
impl in Mathlib.Deprecated.MLList.BestFirst
FinEnum in Mathlib.Data.FinEnum
FinEnum.card in Mathlib.Data.FinEnum
Fin.isValue in Lean.Meta.Tactic.Simp.BuiltinSimprocs.Fin
List.Vector.nil in Mathlib.Data.Vector.Defs
Set.Mem in Mathlib.Data.Set.Defs
Set.instMembership in Mathlib.Data.Set.Defs
List.Vector.get in Mathlib.Data.Vector.Defs
Inhabited in Init.Prelude
Lean.ToExpr in Lean.ToExpr

syntax "max" : MLIR.Pretty.uniform_op

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

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

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

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

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

| shiftL : Term → Nat → Term

deriving Repr, Inhabited, Lean.ToExpr

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

| shiftL t .. => arity t

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

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

def BitVecs.transport (f : Fin n → Fin m) (bvs : BitVecs m) : BitVecs n :=
  { w := bvs.w, bvs := bvs.bvs.transport f }

def BitVec.transport (f : Fin n2 → Fin n1) (bv : BitVec n1) : BitVec n2 :=
  BitVec.ofFn fun i => bv.getLsbD (f i)

def BitVec.ofFn {w : Nat} (f : Fin w → Bool) : BitVec w :=
  BitVec.iunfoldr (fun i _ => ((), f i)) () |>.2

def List.Vector.transport (v : Vector α m) (f : Fin n → Fin m) : Vector α n :=
  Vector.ofFn fun i => v.get (f i)

def BitVecs'.transport (f : Fin n → Fin m) (bvs' : BitVecs' m): BitVecs' n :=
  bvs'.map fun bv => bv.transport f

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

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

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

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

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

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

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

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

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

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

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

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

def BuilderM.isOk {α : Type} (x : BuilderM d α) : Bool :=
  match x.run [] with
  | Except.ok _ => true
  | Except.error _ => false

def op0 : Op 0 := [mlir_op| %0 = llvm.mlir.constant(8) : i32]

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

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

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

BitVec.carry in Init.Data.BitVec.Bitblast

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

def MLIRTy.i (width : Nat) : MLIRTy φ := MLIRType.int Signedness.Signless width

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

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

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

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

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

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

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

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

def shl_add_add_no_const_before := [llvm|
{
^0(%arg122 : i8, %arg123 : i8, %arg124 : i8, %arg125 : i8):
  %0 = llvm.shl %arg122, %arg124 : i8
  %1 = llvm.shl %arg123, %arg124 : i8
  %2 = llvm.add %1, %arg125 : i8
  %3 = llvm.add %0, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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

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

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

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

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

def ashr_2_add_zext_basic_after := [llvm|
{
^0(%arg35 : i1, %arg36 : i1):
  %0 = llvm.mlir.constant(1 : i2) : i2
  %1 = llvm.zext %arg35 : i1 to i2
  %2 = llvm.zext %arg36 : i1 to i2
  %3 = llvm.add %1, %2 overflow<nuw> : i2
  %4 = llvm.ashr %3, %0 : i2
  "llvm.return"(%4) : (i2) -> ()
}
]

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

class SubstituteableTerminator (T : Type u) where
  substituteTerminator (σ : VarName → VarName) : T → T

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

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

HMul in Init.Prelude

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

def unsigned_equiv cmp : (CNFA.autUnsignedCmp cmp).m.states ≃ (NFA'.autUnsignedCmp cmp).σ where
  toFun := fun ⟨s, hs⟩ =>
    match s with
    | 0 => .eq
    | 1 => .gt
    | _ => .lt
  invFun q :=
    match q with
    | .eq => ⟨0, by admit /- proof elided -/
    ⟩
    | .gt => ⟨1, by admit /- proof elided -/
    ⟩
    | .lt => ⟨2, by admit /- proof elided -/
    ⟩
  left_inv := by admit /- proof elided -/

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 XorZextXor_before := [llvm|
{
^0(%arg6 : i3):
  %0 = llvm.mlir.constant(3 : i3) : i3
  %1 = llvm.mlir.constant(12 : i5) : i5
  %2 = llvm.xor %arg6, %0 : i3
  %3 = llvm.zext %2 : i3 to i5
  %4 = llvm.xor %3, %1 : i5
  "llvm.return"(%4) : (i5) -> ()
}
]

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

inductive ISLTy
  | regIndex
  | bits (w : Nat)
  deriving DecidableEq, ToExpr, Repr

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

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

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

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

def src_is_mask_lshr_after := [llvm|
{
^0(%arg96 : i8, %arg97 : i8, %arg98 : i8, %arg99 : i1):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(15 : i8) : i8
  %2 = llvm.mlir.constant(123 : i8) : i8
  %3 = llvm.add %arg97, %0 : i8
  %4 = llvm.xor %arg97, %3 : i8
  %5 = "llvm.select"(%arg99, %4, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %6 = llvm.lshr %5, %arg98 : i8
  %7 = llvm.xor %arg96, %2 : i8
  %8 = llvm.icmp "ugt" %7, %6 : i8
  "llvm.return"(%8) : (i1) -> ()
}
]

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

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

def sext_zext_nneg_uge_op0_wide_after := [llvm|
{
^0(%arg26 : i16, %arg27 : i8):
  %0 = llvm.sext %arg27 : i8 to i16
  %1 = llvm.icmp "uge" %arg26, %0 : i16
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

    |

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

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

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

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

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

HEq in Init.Prelude

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

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

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

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

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

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

def shift_xor_multiuse_cmp_with_and_before := [llvm|
{
^0(%arg76 : i32, %arg77 : i32, %arg78 : i32, %arg79 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(-2049 : i32) : i32
  %3 = llvm.and %arg76, %0 : i32
  %4 = llvm.icmp "ne" %1, %3 : i32
  %5 = llvm.and %arg77, %2 : i32
  %6 = "llvm.select"(%4, %arg77, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg78, %arg79) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %8 = llvm.mul %6, %7 : i32
  "llvm.return"(%8) : (i32) -> ()
}
]

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

def sub_shl_same_amount_partial_nsw2_after := [llvm|
{
^0(%arg8 : i6, %arg9 : i6, %arg10 : i6):
  %0 = llvm.sub %arg8, %arg9 : i6
  %1 = llvm.shl %0, %arg10 : i6
  "llvm.return"(%1) : (i6) -> ()
}
]

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

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

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

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

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

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

def tryFactorization_add_nuw_mul_mul_nuw_var_after := [llvm|
{
^0(%arg6 : i32, %arg7 : i32, %arg8 : i32):
  %0 = llvm.add %arg7, %arg8 : i32
  %1 = llvm.mul %arg6, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

def both_before := [llvm|
{
^0(%arg17 : i8, %arg18 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.shl %0, %arg17 : i8
  %2 = llvm.xor %1, %0 : i8
  %3 = llvm.shl %0, %arg18 : i8
  %4 = llvm.xor %3, %0 : i8
  %5 = llvm.icmp "ult" %2, %4 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

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

def sge_swap_or_not_max_commute_before := [llvm|
{
^0(%arg308 : i8, %arg309 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.icmp "sle" %arg309, %arg308 : i8
  %2 = llvm.icmp "ne" %arg308, %0 : i8
  %3 = llvm.or %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

def and_shl_after := [llvm|
{
^0(%arg644 : i8, %arg645 : i8, %arg646 : i8, %arg647 : i8):
  %0 = llvm.and %arg644, %arg645 : i8
  %1 = llvm.shl %0, %arg647 : i8
  %2 = llvm.and %1, %arg646 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def foo1_and_signbit_lshr_without_shifting_signbit_both_sides_after := [llvm|
{
^0(%arg106 : i32, %arg107 : i32, %arg108 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.shl %arg106, %arg107 : i32
  %2 = llvm.shl %arg106, %arg108 : i32
  %3 = llvm.and %1, %2 : i32
  %4 = llvm.icmp "sgt" %3, %0 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def src_x_and_nmask_sge_before := [llvm|
{
^0(%arg17 : i8, %arg18 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.shl %0, %arg18 : i8
  %2 = llvm.and %arg17, %1 : i8
  %3 = llvm.icmp "sge" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def or_and_not_not_wrong_a_before := [llvm|
{
^0(%arg382 : i32, %arg383 : i32, %arg384 : i32, %arg385 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg383, %arg385 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.or %arg382, %arg384 : i32
  %4 = llvm.xor %3, %0 : i32
  %5 = llvm.and %4, %arg383 : i32
  %6 = llvm.or %5, %2 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

@[deprecated cons (since := "2025-09-14")]
abbrev snoc := fun Γ t => @cons Ty t Γ

BitVec.add in Init.Data.BitVec.BasicAux

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

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

def bools2_logical_commute0_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 ashr_lowmask_before := [llvm|
{
^0(%arg267 : i32):
  %0 = llvm.mlir.constant(24 : i32) : i32
  %1 = llvm.mlir.constant(255 : i32) : i32
  %2 = llvm.ashr %arg267, %0 : i32
  %3 = llvm.and %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

def shl_xor_before := [llvm|
{
^0(%arg22 : i8):
  %0 = llvm.mlir.constant(16 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.mlir.constant(3 : i8) : i8
  %3 = llvm.shl %0, %arg22 : i8
  %4 = llvm.add %arg22, %1 : i8
  %5 = llvm.shl %2, %4 : i8
  %6 = llvm.xor %3, %5 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

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

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

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

Polynomial.coeffs in Mathlib.Algebra.Polynomial.Basic

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

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

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

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

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

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

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

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

abbrev instHadd : HAdd ⟦ScfFunctor.Arith.Ty.int⟧ ⟦ScfFunctor.Arith.Ty.int⟧
  ⟦ScfFunctor.Arith.Ty.int⟧ := @instHAdd ℤ Int.instAdd

def shl_xor_after := [llvm|
{
^0(%arg63 : i32, %arg64 : i32):
  %0 = llvm.mlir.constant(12 : i32) : i32
  %1 = llvm.mlir.constant(7 : i32) : i32
  %2 = llvm.shl %arg63, %0 : i32
  %3 = llvm.shl %arg64, %1 : i32
  %4 = llvm.xor %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def fake_sext_after := [llvm|
{
^0(%arg166 : i3):
  %0 = llvm.mlir.constant(2 : i3) : i3
  %1 = llvm.lshr %arg166, %0 : i3
  %2 = llvm.zext nneg %1 : i3 to i18
  "llvm.return"(%2) : (i18) -> ()
}
]

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

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

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

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

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

Ideal.Quotient.mk in Mathlib.RingTheory.Ideal.Quotient.Defs

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

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

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

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

class HasUB (m : Type u → Type v) where
   
  throwUB {α : Type u} : m α

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

def three_inst_macro (w: Nat) :=
  [llvm(w)|{
  ^bb0(%arg0: _):
    %0 = llvm.not %arg0
    %1 = llvm.not %0
    %2 = llvm.not %1
    llvm.return %2
  }]

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

@[combinator_parenthesizer MLIR.EDSL.balancedBrackets]
def MLIR.EDSL.balancedBracketsParenthesizer : Parenthesizer := pure ()

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

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

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

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

def lt_unsigned_to_large_unsigned_before := [llvm|
{
^0(%arg47 : i8):
  %0 = llvm.mlir.constant(1024 : i32) : i32
  %1 = llvm.zext %arg47 : i8 to i32
  %2 = llvm.icmp "ult" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

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

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

def Com.parseFromFile (d : Dialect)
    [DialectSignature d] [TransformTy d 0] [TransformExpr d 0] [TransformReturn d 0]
    (fileName : String) :
    IO (Option (Σ (Γ' : Ctxt d.Ty) (eff : EffectKind) (ty : List d.Ty), Com d Γ' eff ty)) := do
  parseRegionFromFile fileName fun region =>
    let res := mkCom (d:= d) region
    match res with
    | Except.error e => Except.error s!"Error:\n{reprStr e}"
    | Except.ok res => Except.ok res

instance : ToString FpPredicate := ⟨toString⟩

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

structure Item where
 name : String
 tac : Syntax

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

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

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

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

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

def LLVMIR_cast_combines_32 : List (Σ Γ, LLVMPeepholeRewriteRefine 32 Γ) := select_of_truncate

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

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

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

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 test2_before := [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 : i32
  %4 = llvm.ashr %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def test2_after := [llvm|
{
^0(%arg25 : i47):
  "llvm.return"(%arg25) : (i47) -> ()
}
]

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

def handshakeAdd := [HSxComb_com| {
  ^entry(%a: !Stream_BitVec_32, %b: !Stream_BitVec_32):
    %add1 = "HSxComb.add" (%a, %a) : (!Stream_BitVec_32, !Stream_BitVec_32) -> (!Stream_BitVec_32)
    %syncAdd = "HSxComb.sync" (%add1, %b) : (!Stream_BitVec_32, !Stream_BitVec_32) -> (!Stream2_BitVec_32)
    %syncAdd1 = "HSxComb.snd" (%syncAdd) : (!Stream2_BitVec_32) -> !Stream_BitVec_32
    %add2 = "HSxComb.add" (%syncAdd1, %a) : (!Stream_BitVec_32, !Stream_BitVec_32) -> (!Stream_BitVec_32)
    "return" (%add2) : (!Stream_BitVec_32) -> ()
  }]

class HydrableGetInputWidth where
  getWidth : Expr → MetaM (Option Nat)

def and_or_not_not_commute2_after := [llvm|
{
^0(%arg369 : i32, %arg370 : i32, %arg371 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg371, %arg370 : i32
  %2 = llvm.and %1, %arg369 : i32
  %3 = llvm.xor %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

instance : HydrableParseExprs ParsedFpExpr FpPredicate where
  parseExprs := parseExprs

RV64.sltiu in RISCV.Instructions

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

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

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

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

def foo2_after := [llvm|
{
^0(%arg46 : i32, %arg47 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.icmp "sgt" %arg46, %0 : i32
  %3 = llvm.sub %1, %arg47 : i32
  %4 = "llvm.select"(%2, %arg47, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %5 = llvm.add %arg46, %4 : i32
  "llvm.return"(%5) : (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 t9_before := [llvm|
{
^0(%arg4 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.sub %0, %arg4 overflow<nsw> : i8
  %2 = llvm.icmp "ne" %1, %arg4 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

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

def test25_before := [llvm|
{
^0(%arg271 : i32):
  %0 = llvm.mlir.constant(50 : i32) : i32
  %1 = llvm.mlir.constant(100 : i32) : i32
  %2 = llvm.icmp "sge" %arg271, %0 : i32
  %3 = llvm.icmp "slt" %arg271, %1 : i32
  %4 = llvm.and %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def t0_basic_before := [llvm|
{
^0(%arg24 : i8, %arg25 : i8):
  %0 = llvm.sub %arg24, %arg25 : i8
  %1 = llvm.icmp "ule" %0, %arg24 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

instance  [Mul α] : Mul (Holor α ds) where
  mul := Holor.pointwise_mul

def min_of_max_swap_before := [llvm|
{
^0(%arg19 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.xor %arg19, %0 : i32
  %3 = llvm.icmp "sgt" %arg19, %1 : i32
  %4 = "llvm.select"(%3, %0, %2) <{"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 test2_after := [llvm|
{
^0(%arg6 : i32, %arg7 : i32, %arg8 : i32):
  %0 = llvm.xor %arg7, %arg6 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

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

def test12_before := [llvm|
{
^0(%arg46 : i32, %arg47 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(-1431655766 : i32) : i32
  %2 = llvm.mlir.constant(1431655765 : i32) : i32
  %3 = llvm.add %arg47, %0 overflow<nsw> : i32
  %4 = llvm.or %arg46, %1 : i32
  %5 = llvm.xor %4, %2 : i32
  %6 = llvm.add %3, %5 overflow<nsw> : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

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

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 select_1_after := [llvm|
{
^0(%arg87 : i1, %arg88 : i8, %arg89 : i8, %arg90 : i1, %arg91 : i8, %arg92 : i8):
  %0 = llvm.mlir.constant(-46 : i8) : i8
  %1 = llvm.mlir.constant(-124 : i8) : i8
  %2 = llvm.xor %arg88, %arg89 : i8
  %3 = llvm.xor %2, %0 : i8
  %4 = llvm.xor %arg92, %1 : i8
  %5 = "llvm.select"(%arg90, %arg91, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %6 = "llvm.select"(%arg87, %3, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%6) : (i8) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

def udiv_exact_eq_1_after := [llvm|
{
^0(%arg10 : i8, %arg11 : i8):
  %0 = llvm.icmp "ne" %arg10, %arg11 : i8
  "llvm.return"(%0) : (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 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 test_sub_nuw_nsw__all_are_safe_after := [llvm|
{
^0(%arg31 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.mlir.constant(-254 : i32) : i32
  %2 = llvm.and %arg31, %0 : i32
  %3 = llvm.sub %1, %2 overflow<nsw,nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def 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 collectWidthAtom (state : CollectState) (e : Expr) :
    SolverM (MultiWidth.Nondep.WidthExpr × CollectState) := do
    if ← check? then
      if !(← isDefEq (← inferType e) (mkConst ``Nat)) then
        throwError m!"expected width to be a Nat, found: {indentD e}"
    
    if let .some n ← getNatValue? e then
      match (← read).widthAbstraction with
      | .never =>
        return (MultiWidth.Nondep.WidthExpr.const n, state)
      | .generalizeGeq cutoff =>
        if n < cutoff then
          return (MultiWidth.Nondep.WidthExpr.const n, state)
        else
          mkAtom
      | .always => mkAtom
    else
      mkAtom
    where
      mkAtom := do
        let (wix, wToIx) := state.wToIx.findOrInsertVal e
        
        return (.var wix, { state with wToIx := wToIx })

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

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

@[simp_denote]
def select_llvm_16 := [LV| {
  ^entry (%cond : i1, %arg0: i16, %arg1: i16):
    %0 = "llvm.select"(%cond, %arg0, %arg1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i16, i16) -> i16
    llvm.return %0 : i16
  }]

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 lshr_eq_msb_low_last_zero_after := [llvm|
{
^0(%arg177 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.icmp "ugt" %arg177, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

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

def sle_swap_or_min_commute_before := [llvm|
{
^0(%arg146 : i8, %arg147 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.icmp "sge" %arg147, %arg146 : i8
  %2 = llvm.icmp "eq" %arg146, %0 : i8
  %3 = llvm.or %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def or_test1_before := [llvm|
{
^0(%arg2 : i231, %arg3 : i231):
  %0 = llvm.mlir.constant(1 : i231) : i231
  %1 = llvm.and %arg2, %0 : i231
  %2 = llvm.or %1, %0 : i231
  "llvm.return"(%2) : (i231) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

def sub_shl_same_amount_partial_nuw1_after := [llvm|
{
^0(%arg5 : i6, %arg6 : i6, %arg7 : i6):
  %0 = llvm.sub %arg5, %arg6 : i6
  %1 = llvm.shl %0, %arg7 : i6
  "llvm.return"(%1) : (i6) -> ()
}
]

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

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

def AndZextAnd_before := [llvm|
{
^0(%arg2 : i3):
  %0 = llvm.mlir.constant(3 : i3) : i3
  %1 = llvm.mlir.constant(14 : i5) : i5
  %2 = llvm.and %arg2, %0 : i3
  %3 = llvm.zext %2 : i3 to i5
  %4 = llvm.and %3, %1 : i5
  "llvm.return"(%4) : (i5) -> ()
}
]

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

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

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

partial def Com.print (com : Com d Γ eff ts) : Format :=
  f!"\{\n"
  ++ (Format.nest 2 <|
    Format.align true ++ f!"{printFunc ts}{printBlockArgs Γ}:\n"
    ++ (Format.nest 2 com.printAux))
  ++ Format.align true ++ f!"}"

Lean.mkNatLit in Lean.Expr

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

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

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

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

Lean.PrettyPrinter.Formatter in Lean.PrettyPrinter.Formatter

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

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

def different_size_sext_sext_eq_before := [llvm|
{
^0(%arg10 : i7, %arg11 : i4):
  %0 = llvm.sext %arg10 : i7 to i25
  %1 = llvm.sext %arg11 : i4 to i25
  %2 = llvm.icmp "eq" %0, %1 : i25
  "llvm.return"(%2) : (i1) -> ()
}
]

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

def changeBVExprWidth (bvExpr: GenBVExpr w) (target: Nat) : GenBVExpr target := Id.run do
  if h : w = target then
    return (h ▸ bvExpr)

  match bvExpr with
  | .var idx => (GenBVExpr.var idx : GenBVExpr target)
  | .const val => GenBVExpr.const (val.signExtend target)
  | .extract start len expr => GenBVExpr.extract start target (changeBVExprWidth expr (start + target))
  | .bin lhs op rhs => GenBVExpr.bin (changeBVExprWidth lhs target) op (changeBVExprWidth rhs target)
  | .un op operand => GenBVExpr.un op (changeBVExprWidth operand target)
  | .shiftLeft lhs rhs =>  GenBVExpr.shiftLeft (changeBVExprWidth lhs target)  (changeBVExprWidth rhs target)
  | .shiftRight lhs rhs =>  GenBVExpr.shiftRight (changeBVExprWidth lhs target) (changeBVExprWidth rhs target)
  | .arithShiftRight lhs rhs => GenBVExpr.arithShiftRight (changeBVExprWidth lhs target) (changeBVExprWidth rhs target)
  | .signExtend v expr => GenBVExpr.signExtend target (changeBVExprWidth expr target)
  | .zeroExtend v expr => GenBVExpr.zeroExtend target (changeBVExprWidth expr target)
  | .truncate v expr => GenBVExpr.truncate target (changeBVExprWidth expr target)
  | _ => GenBVExpr.const (BitVec.zero target)

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

def test8_after := [llvm|
{
^0(%arg94 : i32, %arg95 : i32):
  %0 = llvm.mlir.constant(32) : i64
  %1 = llvm.zext %arg94 : i32 to i64
  %2 = llvm.zext %arg95 : i32 to i64
  %3 = llvm.shl %2, %0 overflow<nuw> : i64
  %4 = llvm.or disjoint %3, %1 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

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

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

structure ParsedArgs (Γ : Ctxt d.Ty) (n? : Option Nat := none) where
  toList : List (Σ t, Γ.Var t)
  length_eq : match n? with
    | some n => toList.length = n
    | none => True

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

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

abbrev Width.mvar : Fin φ → Width φ := ConcreteOrMVar.mvar

def three_inst_concrete_stmt (e : LLVM.IntW 1) :
    (LLVM.not (LLVM.not (LLVM.not e)))
      ⊑ (LLVM.not (LLVM.not (LLVM.not e))) :=

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

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

instance : HydrableReduceWidth ParsedFpExpr FpPredicate FpExpr where
  shrink := shrink

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

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

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

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

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

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

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

def lshr_32_add_zext_trunc_after := [llvm|
{
^0(%arg5 : i32, %arg6 : i32):
  %0 = llvm.add %arg5, %arg6 : i32
  %1 = llvm.icmp "ult" %0, %arg5 : i32
  %2 = llvm.zext %1 : i1 to i32
  %3 = llvm.add %0, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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 runM (x : M α) : MetaM (α × State) := x.run {}

@[simp]
def WidthPredicate.sat (wp : WidthPredicate) (w n : Nat) : Bool :=
  match wp with
  | .eq => w = n
  | .neq => w ≠ n
  | .lt => w < n
  | .le => w ≤ n
  | .gt => w > n
  | .ge => w ≥ n

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

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

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

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

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

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

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

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

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

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

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

def not_mul_of_pow2_commute_before := [llvm|
{
^0(%arg75 : i32, %arg76 : i32):
  %0 = llvm.mlir.constant(12 : i32) : i32
  %1 = llvm.mlir.constant(255 : i32) : i32
  %2 = llvm.mlir.constant(3060 : i32) : i32
  %3 = llvm.and %arg75, %0 : i32
  %4 = llvm.and %arg76, %1 : i32
  %5 = llvm.mul %4, %3 : i32
  %6 = llvm.icmp "ugt" %5, %2 : i32
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

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

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

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

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

inductive Expr
  | mk (varName : VarName) (op : Op) (args : List VarName) (regions : List Region)

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

def wrongimm_after := [llvm|
{
^0(%arg4 : i16):
  %0 = llvm.mlir.constant(14 : i16) : i16
  %1 = llvm.mlir.constant(27 : i8) : i8
  %2 = llvm.ashr %arg4, %0 : i16
  %3 = llvm.trunc %2 overflow<nsw> : i16 to i8
  %4 = llvm.xor %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

def sendReadyValue (_ : Unit) (_ : Unit) : BitVec 1 := 1

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

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

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

def controlMerge (x y : Stream α) : Stream α × Stream (BitVec 1) :=
  Stream.corec₂ (β := Stream α × Stream α) (x, y) fun ⟨x, y⟩ =>
    match x 0, y 0 with
    | some x', some _ => (some x', some 1, (x.tail, y))
    | some x', none => (some x', some 1, (x.tail, y.tail))
    | none, some y' => (some y', some 0, (x.tail, y.tail))
    | none, none => (none, none, (x.tail, y.tail))

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

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

instance : MLIR.AST.TransformExpr (FHE q n) 0 where
  mkExpr := mkExpr

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

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

structure GlobalState where
  alloc : AllocState
  mem : MemoryState

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

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

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

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

StateT.lift in Init.Control.State

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

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

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

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

def bitwise_and_bitwise_and_icmps_before := [llvm|
{
^0(%arg244 : i8, %arg245 : i8, %arg246 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.icmp "eq" %arg245, %0 : i8
  %4 = llvm.and %arg244, %1 : i8
  %5 = llvm.shl %1, %arg246 : i8
  %6 = llvm.and %arg244, %5 : i8
  %7 = llvm.icmp "ne" %4, %2 : i8
  %8 = llvm.icmp "ne" %6, %2 : i8
  %9 = llvm.and %3, %7 : i1
  %10 = llvm.and %9, %8 : i1
  "llvm.return"(%10) : (i1) -> ()
}
]

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

def testExampleFst : DCOp.TokenStream :=
  exampleFst.denote (Ctxt.Valuation.ofHVector (.cons inputFst <| .nil))

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

def mul16_low_after := [llvm|
{
^0(%arg24 : i16, %arg25 : i16):
  %0 = llvm.mul %arg24, %arg25 : i16
  "llvm.return"(%0) : (i16) -> ()
}
]

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

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

Int.neg in Init.Data.Int.Basic

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

def test1_after := [llvm|
{
^0(%arg6 : i447, %arg7 : i447):
  %0 = llvm.mlir.constant(70368744177664 : i447) : i447
  %1 = llvm.mlir.constant(70368744177663 : i447) : i447
  %2 = llvm.and %arg6, %0 : i447
  %3 = llvm.and %arg7, %1 : i447
  %4 = llvm.or disjoint %2, %3 : i447
  "llvm.return"(%4) : (i447) -> ()
}
]

def test16_after := [llvm|
{
^0(%arg38 : i32, %arg39 : i32):
  %0 = llvm.mlir.constant(1431655766 : i32) : i32
  %1 = llvm.or %arg38, %0 : i32
  %2 = llvm.sub %arg39, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

def test14_before := [llvm|
{
^0(%arg14 : i8, %arg15 : i8):
  %0 = llvm.icmp "eq" %arg14, %arg15 : i8
  %1 = llvm.icmp "ne" %arg15, %arg14 : i8
  %2 = llvm.xor %0, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

def sgt_and_min_before := [llvm|
{
^0(%arg352 : i9, %arg353 : i9):
  %0 = llvm.mlir.constant(-256 : i9) : i9
  %1 = llvm.icmp "sgt" %arg352, %arg353 : i9
  %2 = llvm.icmp "eq" %arg352, %0 : i9
  %3 = llvm.and %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

structure RawCNFA.SimulFun (m : RawCNFA A) (M : NFA A Q) (f : m.states ≃ Q)  where
  accept {q} : ((f.invFun q).val ∈ m.finals ↔ q ∈ M.accept)
  initial {q} : q ∈ M.start ↔ (f.invFun q).val ∈ m.initials
  trans_match {a q q'} : q' ∈ M.step q a ↔ (f.invFun q').val ∈ m.tr (f.invFun q) a

class DecidableNFA [Fintype σ] [Fintype α] [DecidableEq σ] [DecidableEq α] (m : NFA α σ) where
  decidable_start : Decidable (q ∈ m.start)
  decidable_accept : Decidable (q ∈ m.accept)
  decidable_step : Decidable (s' ∈ m.step s a)

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 test1_before := [llvm|
{
^0(%arg0 : i61):
  %0 = llvm.trunc %arg0 : i61 to i41
  %1 = llvm.zext %0 : i41 to i61
  "llvm.return"(%1) : (i61) -> ()
}
]

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

def llvm_const_lower_riscv_li29 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM29, rhs:= liRiscv29,
   correct := by admit /- proof elided -/

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

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

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

def EnvFin.cons (env : EnvFin w n) (b : BitVec w) : EnvFin w (n + 1) :=
  fun i => i.cases b env

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

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

Lean.mkApp2 in Lean.Expr

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

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

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

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

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

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

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

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

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

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

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

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

private def op2 : Op φ :=
  [mlir_op| %z = "foo"(%x, %y) : (i32, i32) -> (i32)]

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

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

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

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

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

instance : DecidableEq VarName :=

@[simp]
def Env.get_ofEnvFin (envFin : EnvFin w n) (i : Fin n) :
    (Env.ofEnvFin envFin)[i] = envFin i :=

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

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

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

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

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

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

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

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

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

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

HolorIndex in Mathlib.Data.Holor

def shl_xor_xor_bad_mask_distribute_before := [llvm|
{
^0(%arg98 : i8, %arg99 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(-68 : i8) : i8
  %2 = llvm.shl %arg98, %0 : i8
  %3 = llvm.shl %arg99, %0 : i8
  %4 = llvm.xor %3, %1 : i8
  %5 = llvm.xor %2, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

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

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

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

Neg in Init.Prelude

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

instance : Coe (List (AttrEntry φ)) (AttrDict φ) where
  coe
  | v => AttrDict.mk v

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

def shl_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 ne_21_after := [llvm|
{
^0(%arg72 : i32, %arg73 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.lshr %arg72, %0 : i32
  %2 = llvm.trunc %1 : i32 to i16
  %3 = llvm.lshr %arg73, %0 : i32
  %4 = llvm.trunc %3 : i32 to i16
  %5 = llvm.icmp "ne" %2, %4 : i16
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

def testDCShl2 : DCOp.ValueStream (BitVec 32)  :=
  dcShl.denote (Ctxt.Valuation.ofHVector (.cons a <| .cons b <| .nil))

instance : ToExpr Eqn where
  toExpr := Eqn.toExpr
  toTypeExpr := mkConst ``Eqn

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

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

@[simp_llvm_option]
def freeze (x: IntW w) : IntW w := do
  match x with
  | poison => value (0)
  | value a => value (a)

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

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

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

def test2_before := [llvm|
{
^0(%arg59 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(32 : i32) : i32
  %2 = llvm.and %arg59, %0 : i32
  %3 = llvm.and %arg59, %1 : i32
  %4 = llvm.add %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

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

def add_nsw_or_and_after := [llvm|
{
^0(%arg11 : i32, %arg12 : i32):
  %0 = llvm.add %arg11, %arg12 overflow<nsw> : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def deepCasesOn {motive : ∀ {φ}, MOp φ → Sort*}
    (neg    : ∀ {φ} {w : Width φ},               motive (neg  w))
    (not    : ∀ {φ} {w : Width φ},               motive (not  w))
    (trunc  : ∀ {φ noWrapFlags} {w w' : Width φ},            motive (trunc w w' noWrapFlags))
    (zext   : ∀ {φ NonNegFlag} {w w' : Width φ}, motive (zext  w w' NonNegFlag))
    (sext   : ∀ {φ} {w w' : Width φ},            motive (sext  w w'))
    (copy   : ∀ {φ} {w : Width φ},               motive (copy w))
    (freeze : ∀ {φ} {w : Width φ},               motive (freeze w))
    (and    : ∀ {φ} {w : Width φ},               motive (and  w))
    (or     : ∀ {φ DisjointFlag} {w : Width φ},  motive (or w DisjointFlag))
    (xor    : ∀ {φ} {w : Width φ},               motive (xor  w))
    (shl    : ∀ {φ NoWrapFlags} {w : Width φ},   motive (shl  w NoWrapFlags))
    (lshr   : ∀ {φ ExactFlag} {w : Width φ},     motive (lshr w ExactFlag))
    (ashr   : ∀ {φ ExactFlag} {w : Width φ},     motive (ashr w ExactFlag))
    (urem   : ∀ {φ} {w : Width φ},               motive (urem w))
    (srem   : ∀ {φ} {w : Width φ},               motive (srem w))
    (add    : ∀ {φ NoWrapFlags} {w : Width φ},   motive (add w NoWrapFlags))
    (mul    : ∀ {φ NoWrapFlags} {w : Width φ},   motive (mul w NoWrapFlags))
    (sub    : ∀ {φ NoWrapFlags} {w : Width φ},   motive (sub w NoWrapFlags))
    (sdiv   : ∀ {φ ExactFlag} {w : Width φ},     motive (sdiv w ExactFlag))
    (udiv   : ∀ {φ ExactFlag} {w : Width φ},     motive (udiv w ExactFlag))
    (select : ∀ {φ} {w : Width φ},               motive (select w))
    (icmp   : ∀ {φ c} {w : Width φ},             motive (icmp c w))
    (const  : ∀ {φ v} {w : Width φ},             motive (const w v)) :
    ∀ {φ} (op : MOp φ), motive op
  | _, .neg _      => neg
  | _, .not _      => not
  | _, .trunc _ _ _  => trunc
  | _, .zext _ _ _ => zext
  | _, .sext _ _   => sext
  | _, .copy _     => copy
  | _, .freeze _   => freeze
  | _, .and _      => and
  | _, .or _ _     => or
  | _, .xor _      => xor
  | _, .shl _ _    => shl
  | _, .lshr _ _   => lshr
  | _, .ashr _ _   => ashr
  | _, .urem _     => urem
  | _, .srem _     => srem
  | _, .add _ _    => add
  | _, .mul _ _    => mul
  | _, .sub _ _    => sub
  | _, .sdiv _ _   => sdiv
  | _, .udiv _ _   => udiv
  | _, .select _   => select
  | _, .icmp ..    => icmp
  | _, .const ..   => const

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

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

def ne_210_after := [llvm|
{
^0(%arg76 : i32, %arg77 : i32):
  %0 = llvm.trunc %arg76 : i32 to i24
  %1 = llvm.trunc %arg77 : i32 to i24
  %2 = llvm.icmp "ne" %0, %1 : i24
  "llvm.return"(%2) : (i1) -> ()
}
]

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

modifyGetThe in Init.Prelude

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

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

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

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

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

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

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

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

def test1_after := [llvm|
{
^0(%arg12 : i1):
  "llvm.return"(%arg12) : (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 generatePreconditions (bvLogicalExpr: BoolExpr GenBVPred) (positiveExamples negativeExamples: List (Std.HashMap Nat BVExpr.PackedBitVec))
              (_numConjunctions: Nat) : GeneralizerStateM ParsedBVExpr GenBVPred (Option (BoolExpr GenBVPred)) := do

    let state ← get
    let widthId := state.widthId

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

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

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

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

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

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

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

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

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

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

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

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

              preconditionCandidates := preconditionCandidates.insert cand

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

              preconditionCandidates := preconditionCandidates.insert cand

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

          checkTimeout

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

      pure validCandidates

    if validCandidates.isEmpty then
      return none

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

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

def andn_or_cmp_2_logical_before := [llvm|
{
^0(%arg167 : i16, %arg168 : i16, %arg169 : i16):
  %0 = llvm.mlir.constant(42 : i16) : i16
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.icmp "sge" %arg167, %arg168 : i16
  %4 = llvm.icmp "slt" %arg167, %arg168 : i16
  %5 = llvm.icmp "ugt" %arg169, %0 : i16
  %6 = "llvm.select"(%5, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %7 = "llvm.select"(%6, %4, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%7) : (i1) -> ()
}
]

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

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

def MatchVarResult := { mapOut : Mapping _ _ //
  ∃ (mapIn' mapOut' : Mapping _ _),
    mapIn.entries ⊆ mapIn'.entries
    ∧ mapOut'.entries ⊆ mapOut.entries
    ∧ matchVar lets v matchLets w mapIn' = some ((), mapOut') }

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

def mkReturn (Γ : Ctxt _) (opStx : MLIR.AST.Op 0) : MLIR.AST.ReaderM (Handshake)
    (Σ eff ty, Com Handshake Γ 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, got {opStx.args.length})"
  else throw <| .generic s!"Tried to build return out of non-return statement {opStx.name}"

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

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

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

@[simp]
def ofNat_eq_concrete (x : Nat) :
    (OfNat.ofNat x) = (ConcreteOrMVar.concrete x : ConcreteOrMVar Nat φ) := rfl

def test8_before := [llvm|
{
^0(%arg79 : i32, %arg80 : i32):
  %0 = llvm.mlir.constant(32 : i128) : i128
  %1 = llvm.zext %arg79 : i32 to i128
  %2 = llvm.zext %arg80 : i32 to i128
  %3 = llvm.shl %2, %0 : i128
  %4 = llvm.or %3, %1 : i128
  %5 = llvm.trunc %4 : i128 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

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

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

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

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

def icmp_ult_x_y_2_after := [llvm|
{
^0(%arg40 : i8, %arg41 : i8):
  %0 = llvm.mul %arg40, %arg40 : i8
  %1 = llvm.and %0, %arg41 : i8
  %2 = llvm.icmp "ne" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

elab "[simple_com| " reg:mlir_region "]" : term => SSA.elabIntoCom' reg (Simple)

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

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

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 add_b32_test_no_ZBS_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := add_b32_llvm_i64
  rhs := add_b32_riscv_i64_no_ZBS

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

instance : DialectPrint DC where
  printOpName := reprStr
  printTy := reprStr
  printAttributes _ := ""
  dialectName := "dc"
  printReturn _ := "return"

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

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

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

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

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

def liftEffect_compose {e1 e2 e3 : EffectKind} {α : Type} [Pure m]
    (h12 : e1 ≤ e2)
    (h23 : e2 ≤ e3)
    (h13 : e1 ≤ e3 := le_trans h12 h23) :
    ((liftEffect (α := α) h23) ∘ (liftEffect h12)) = liftEffect (m := m) h13 :=

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

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

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

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

def differentconsts_after := [llvm|
{
^0(%arg29 : i32, %arg30 : i16, %arg31 : i16):
  %0 = llvm.mlir.constant(-16 : i32) : i32
  %1 = llvm.mlir.constant(127 : i32) : i32
  %2 = llvm.mlir.constant(256 : i16) : i16
  %3 = llvm.mlir.constant(-1 : i16) : i16
  %4 = llvm.icmp "slt" %arg29, %0 : i32
  %5 = llvm.icmp "sgt" %arg29, %1 : i32
  %6 = llvm.trunc %arg29 : i32 to i16
  %7 = "llvm.select"(%4, %2, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i16, i16) -> i16
  %8 = "llvm.select"(%5, %3, %7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i16, i16) -> i16
  "llvm.return"(%8) : (i16) -> ()
}
]

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

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

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

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

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

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

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

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

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

def t9_highest_bit_after := [llvm|
{
^0(%arg25 : i32, %arg26 : i64, %arg27 : i32):
  %0 = llvm.mlir.constant(63) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.zext %arg25 : i32 to i64
  %3 = llvm.lshr %arg26, %0 : i64
  %4 = llvm.and %3, %2 : i64
  %5 = llvm.icmp "ne" %4, %1 : i64
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

instance instReprTy : Repr (Dialect.Ty d) where reprPrec t _ := printTy t

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

def shl_xor_xor_bad_mask_distribute_after := [llvm|
{
^0(%arg98 : i8, %arg99 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(-68 : i8) : i8
  %2 = llvm.xor %arg99, %arg98 : i8
  %3 = llvm.shl %2, %0 : i8
  %4 = llvm.xor %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

instance : ToString PreconditionSynthesisCacheValue where
  toString val :=
    s! "⟨positiveExampleValues := {val.positiveExampleValues}, negativeExampleValues := {val.negativeExampleValues}⟩"

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

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

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

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 constLLVM39 : Com LLVMPlusRiscV ⟨[]⟩ .pure (.llvm (.bitvec 64)) := [LV| {
  ^entry ():
    %1 = llvm.mlir.constant (39) : i64
    llvm.return %1 : i64
  }]

instance : Inhabited (
          {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' }) where
  default := fun _s _ts rs => ⟨rs, rfl⟩

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

def add_nsw_or_and_before := [llvm|
{
^0(%arg11 : i32, %arg12 : i32):
  %0 = llvm.or %arg11, %arg12 : i32
  %1 = llvm.and %arg11, %arg12 : i32
  %2 = llvm.add %0, %1 overflow<nsw> : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

inductive Lets
  | mk (lets : List Expr)

def fold_inverted_icmp_preds_reverse_after := [llvm|
{
^0(%arg93 : i32, %arg94 : i32, %arg95 : i32, %arg96 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "slt" %arg93, %arg94 : i32
  %2 = "llvm.select"(%1, %0, %arg95) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %3 = llvm.icmp "slt" %arg93, %arg94 : i32
  %4 = "llvm.select"(%3, %arg96, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %5 = llvm.or %2, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

def sext_sub_nuw_before := [llvm|
{
^0(%arg14 : i8, %arg15 : i1):
  %0 = llvm.sext %arg15 : i1 to i8
  %1 = llvm.sub %arg14, %0 overflow<nuw> : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

def lshr_lshr_pow2_const_negative_nopow2_2_after := [llvm|
{
^0(%arg62 : i16):
  %0 = llvm.mlir.constant(128 : i16) : i16
  %1 = llvm.mlir.constant(3 : i16) : i16
  %2 = llvm.lshr %0, %arg62 : i16
  %3 = llvm.and %2, %1 : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

def or_i32_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := or_llvm_i32
  rhs := or_riscv_i32

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

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

HPow.hPow in Init.Prelude

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

List.next in Mathlib.Data.List.Cycle

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

def test15_after := [llvm|
{
^0(%arg172 : i32, %arg173 : i32):
  %0 = llvm.xor %arg172, %arg173 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

Std.Format in Init.Data.Format.Basic

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

def State.setMapping (e x : Expr) : GenM Unit := do
  let s ← get
  let m ← s.mapping.insert e x
  set {s with mapping := m}

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

def RawCNFA.addFinal (m : RawCNFA A) (s : State) : RawCNFA A :=
  { m with finals := m.finals.insert s }

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

def product (final? : Prop → Prop → Prop) (M N : NFA' n) : NFA' n where
  σ := _
  M := M.M.product final? N.M

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

def mullo_variant3_before := [llvm|
{
^0(%arg4 : i64, %arg5 : i64):
  %0 = llvm.mlir.constant(4294967295) : i64
  %1 = llvm.mlir.constant(32) : i64
  %2 = llvm.and %arg4, %0 : i64
  %3 = llvm.lshr %arg4, %1 : i64
  %4 = llvm.and %arg5, %0 : i64
  %5 = llvm.lshr %arg5, %1 : i64
  %6 = llvm.mul %4, %2 overflow<nuw> : i64
  %7 = llvm.mul %4, %3 overflow<nuw> : i64
  %8 = llvm.mul %5, %2 overflow<nuw> : i64
  %9 = llvm.add %8, %7 : i64
  %10 = llvm.shl %9, %1 : i64
  %11 = llvm.add %10, %6 : i64
  "llvm.return"(%11) : (i64) -> ()
}
]

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

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

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

instance : DialectSignature ExOp ExTy where
  signature
  | .add    => ⟨[.nat, .nat], [], .nat, .pure⟩
  | .runK _ => ⟨[.nat], [([.nat], .nat)], .nat, .pure⟩

def multiRewritePeephole (fuel : ℕ)
    (prs : List (Σ Γ, Σ ty, PeepholeRewrite d Γ ty)) (target : Com d Γ₂ eff t₂) : (Com d Γ₂ eff t₂) :=
  multiRewritePeepholeAt fuel prs 0 target

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

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

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

def or_or_xor_commute2_before := [llvm|
{
^0(%arg100 : i4, %arg101 : i4, %arg102 : i4):
  %0 = llvm.or %arg102, %arg100 : i4
  %1 = llvm.or %arg101, %arg102 : i4
  %2 = llvm.xor %0, %1 : i4
  "llvm.return"(%2) : (i4) -> ()
}
]

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

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

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

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

def lshr_sub_after := [llvm|
{
^0(%arg77 : i8, %arg78 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.srem %arg77, %0 : i8
  %3 = llvm.lshr %arg78, %1 : i8
  %4 = llvm.sub %2, %3 overflow<nsw> : i8
  %5 = llvm.shl %4, %1 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

def llvm_add_lower_riscv_nuw_nsw_flag_1 : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 1), Ty.llvm (.bitvec 1)] where
  lhs:= add_llvm_nsw_nuw_flags_1
  rhs:= add_riscv_1

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

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

def add_nuw_const_const_sub_before := [llvm|
{
^0(%arg55 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(-127 : i8) : i8
  %2 = llvm.add %arg55, %0 overflow<nuw> : i8
  %3 = llvm.sub %1, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def SLLVM : Dialect where
  Op := SLLVMOp
  Ty := SLLVMTy
  m := EffectM

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

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

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

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

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

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

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

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

instance [DecidableEq Ty] {Γ : Ctxt Ty} {t : Ty} : Fintype (Γ.Var t) where
  elems := {
      val := .ofList <|
                List.range Γ.length
                |>.filterMap fun i =>
                    if h : Γ[i]? = some t then
                      some ⟨i, h⟩
                    else
                      none
      nodup := by admit /- proof elided -/

def one (w: Nat) := GenBVExpr.const (BitVec.ofNat w 1)

def src_is_notmask_ashr_before := [llvm|
{
^0(%arg55 : i16, %arg56 : i8, %arg57 : i16):
  %0 = llvm.mlir.constant(123 : i16) : i16
  %1 = llvm.mlir.constant(-32 : i8) : i8
  %2 = llvm.mlir.constant(-1 : i16) : i16
  %3 = llvm.xor %arg55, %0 : i16
  %4 = llvm.shl %1, %arg56 : i8
  %5 = llvm.sext %4 : i8 to i16
  %6 = llvm.ashr %5, %arg57 : i16
  %7 = llvm.xor %6, %2 : i16
  %8 = llvm.and %3, %7 : i16
  %9 = llvm.icmp "eq" %3, %8 : i16
  "llvm.return"(%9) : (i1) -> ()
}
]

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

def t3_after := [llvm|
{
^0(%arg23 : i8, %arg24 : i2):
  %0 = llvm.sext %arg24 : i2 to i8
  %1 = llvm.add %arg23, %0 : i8
  %2 = llvm.xor %1, %0 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

def zext_nneg_flag_drop_before := [llvm|
{
^0(%arg7 : i8, %arg8 : i16):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.mlir.constant(128 : i16) : i16
  %2 = llvm.and %arg7, %0 : i8
  %3 = llvm.zext nneg %2 : i8 to i16
  %4 = llvm.or %3, %arg8 : i16
  %5 = llvm.or %4, %1 : i16
  "llvm.return"(%5) : (i16) -> ()
}
]

def RegionSignature.map (f : Ty → Ty') : RegionSignature Ty → RegionSignature Ty' :=
  List.map fun ⟨Γ, ty⟩ => (Γ.map f, ty.map f)

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

def lshr_add_or_fail_before := [llvm|
{
^0(%arg92 : i8, %arg93 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(123 : i8) : i8
  %2 = llvm.lshr %arg92, %0 : i8
  %3 = llvm.lshr %arg93, %0 : i8
  %4 = llvm.add %3, %1 : i8
  %5 = llvm.or %2, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

structure CliTest where
  name : Name
  mvars : Nat
  context : MContext mvars
  ty : MTy mvars
  eff : EffectKind
  code : MCom mvars context eff [ty]

def test_or1_after := [llvm|
{
^0(%arg36 : i32, %arg37 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.and %arg37, %0 : i32
  %2 = llvm.icmp "uge" %arg36, %1 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def test1_trunc_before := [llvm|
{
^0(%arg53 : i32):
  %0 = llvm.mlir.constant(24 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.mlir.constant(65280 : i32) : i32
  %3 = llvm.lshr %arg53, %0 : i32
  %4 = llvm.lshr %arg53, %1 : i32
  %5 = llvm.and %4, %2 : i32
  %6 = llvm.or %3, %5 : i32
  %7 = llvm.trunc %6 : i32 to i16
  "llvm.return"(%7) : (i16) -> ()
}
]

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

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

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

def Com.outContextDiff (com : Com d Γ eff ts) : Γ.Diff com.outContext :=
  ⟨com.bvars, by admit /- proof elided -/
      ⟩

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

def zext_sext_add_icmp_slt_1_rhs_not_const_after := [llvm|
{
^0(%arg49 : i1, %arg50 : i1, %arg51 : i8):
  %0 = llvm.zext %arg49 : i1 to i8
  %1 = llvm.sext %arg50 : i1 to i8
  %2 = llvm.add %0, %1 overflow<nsw> : i8
  %3 = llvm.icmp "slt" %2, %arg51 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def Expr.mkVerifyCircuit (c cert : Expr) : MetaM Expr :=
  mkAppM ``Circuit.verifyCircuit #[c, cert]

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

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

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

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

def Expr.mkToFSM (self : Expr) : MetaM Expr :=
  mkAppM ``FSMPredicateSolution.toFSM #[self]

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

def binop_left_to_zero: List (Σ Γ, LLVMPeepholeRewriteRefine 64 Γ) :=
  [⟨_, binop_left_to_zero_shl⟩,
  ⟨_, binop_left_to_zero_lshr⟩,
  ⟨_, binop_left_to_zero_ashr⟩,
  ⟨_, binop_left_to_zero_sdiv⟩,
  ⟨_, binop_left_to_zero_udiv⟩,
  ⟨_, binop_left_to_zero_srem⟩,
  ⟨_, binop_left_to_zero_urem⟩,
  ⟨_, binop_left_to_zero_mul⟩]

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

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

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

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

Functor in Init.Prelude
</all_available_defs>

<all_available_lemmas>
Nat.add_comm in Init.Data.Nat.Basic
Fin.val_last in Init.Data.Fin.Lemmas
Nat.mod_eq_of_lt in Init.Data.Nat.Div.Basic
Set.mem_setOf_eq in Mathlib.Data.Set.Operations
le_add_iff_nonneg_right in Mathlib.Algebra.Order.Monoid.Unbundled.Basic
zero_le in Mathlib.Algebra.Order.Monoid.Canonical.Defs

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

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

@[simp]
lemma BitVecs.transport_getElem {bvs : BitVecs m} (f : Fin n → Fin m) (i : Fin n) :
    (bvs.transport f).bvs.get i = bvs.bvs.get (f i)

theorem ashr_mul_times_3_div_2_exact_proof : ashr_mul_times_3_div_2_exact_before ⊑ ashr_mul_times_3_div_2_exact_after

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

theorem icmp_eq_mul_nsw_nonequal_proof : icmp_eq_mul_nsw_nonequal_before ⊑ icmp_eq_mul_nsw_nonequal_after

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

theorem test2_proof : test2_before ⊑ test2_after

theorem demo4 (x y : BitVec 32) : (x ^^^ y) &&& 1#32 ||

theorem p_commutative0_proof : p_commutative0_before ⊑ p_commutative0_after

theorem e_331 :
     - 6 *  ~~~x + 2 * (x |||  ~~~y) - 3 * x + 2 * (x ||| y) - 10 *  ~~~(x ||| y) - 10 *  ~~~(x |||  ~~~y) - 4 * (x &&&  ~~~y) - 15 * (x &&& y) =  - 3 *  ~~~(x &&&  ~~~x) - 11 *  ~~~(x &&&  ~~~y)

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

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

theorem test92_proof : test92_before ⊑ test92_after

theorem positive_different_trunc_both_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (-1#15 <ₛ truncate 15 x) &&& ofBool (truncate 16 x + 128#16 <ᵤ 256#16) =
    ofBool (x &&& 16384#32 == 0#32) &&& ofBool (truncate 16 x + 128#16 <ᵤ 256#16)

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

theorem icmp_eq_and_pow2_shl_pow2_negative2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → zeroExtend 32 (ofBool (2#32 <<< x &&& 14#32 == 0#32)) = zeroExtend 32 (ofBool (2#32 <ᵤ x))

theorem test1_thm.extracted_1._1 : ∀ (x : BitVec 33), ¬4096#33 = 0 → 12#33 ≥ ↑33 → False

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

theorem test23_thm.extracted_1._1 : ∀ (x : BitVec 32), zeroExtend 32 (truncate 16 x) = x &&& 65535#32

theorem ashrslt_03_08_exact_proof : ashrslt_03_08_exact_before ⊑ ashrslt_03_08_exact_after

theorem trunc_shl_shl_var_proof : trunc_shl_shl_var_before ⊑ trunc_shl_shl_var_after

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

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

theorem trunc_shl_7_i8_i64_thm (e : IntW 64) : trunc 8 (shl e (const? 64 7)) ⊑ shl (trunc 8 e) (const? 8 7)

theorem ashr_16_add_zext_basic_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬16#32 ≥ ↑32 → (zeroExtend 32 x_1 + zeroExtend 32 x) >>> 16#32 = zeroExtend 32 (ofBool (x_1 ^^^ -1#16 <ᵤ x))

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

theorem mul_of_pow2s_proof : mul_of_pow2s_before ⊑ mul_of_pow2s_after

@[simp]
theorem toBitVec_sub (a b : BitStream) :
    (a - b).toBitVec w = (a.toBitVec w) - (b.toBitVec w)

@[simp]
lemma eval_assignAllVars [DecidableEq α] {c : Circuit α} {f : α → Bool} :
    eval (assignAllVars c f) env = c.eval f

theorem trunc_sel_smaller_zext_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → zeroExtend 32 42#16 = 42#32

theorem testi64i32_proof : testi64i32_before ⊑ testi64i32_after

theorem test6a_proof : test6a_before ⊑ test6a_after

theorem e_2261 :
    2 *  ~~~(d &&& f) + 4 * (d &&& e) - 11 *  ~~~(e &&& f) - 1 * ((d &&& e) |||  ~~~(e ||| f)) - 3 * (f &&&  ~~~(d &&& e)) + 1 * (e &&&  ~~~(d ^^^ f)) - 3 * (f ^^^  ~~~(d ||| (e &&& f))) + 5 * ( ~~~f &&& (d ^^^ e)) - 7 * (f &&& (d ^^^ e)) + 5 * (f &&&  ~~~(d ^^^ e)) + 11 * (e ^^^  ~~~(d &&& (e &&& f))) - 1 * (e ^^^ (d &&& ( ~~~e ||| f))) + 4 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 1 * (e ^^^ (d &&& f)) + 7 * (e ||| f) - 7 * ((e &&& f) ||| (d &&& (e ||| f))) + 7 * (d ^^^ ( ~~~e &&& f)) - 3 * (e ^^^ ( ~~~d ||| (e ^^^ f))) + 4 *  ~~~(d &&&  ~~~d) - 1 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 1 * (e ^^^  ~~~(d &&&  ~~~f)) - 1 * ( ~~~e &&&  ~~~(d ^^^ f)) + 1 *  ~~~(d ^^^ (e ^^^ f)) - 2 * (f ||| (d &&&  ~~~e)) + 1 * (f ^^^ (d &&& (e ||| f))) + 5 *  ~~~(d &&& (e ^^^ f)) - 3 * (d ||| (e ||| f)) + 2 * e + 11 * ((d &&& e) ^^^ (e ||| f)) - 3 * (f &&& (d |||  ~~~e)) - 11 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 2 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 11 * ( ~~~d &&& (e ||| f)) - 6 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 2 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 5 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) - 5 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 *  ~~~( ~~~d &&& (e &&& f)) + 4 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 5 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) + 3 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 5 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 11 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 7 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 6 *  ~~~f + 5 * ((d ^^^ e) ||| (d ^^^ f)) + 1 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) + 5 * f + 3 * (e ^^^ (d ||| ( ~~~e ||| f))) - 7 * (d &&& ( ~~~e ||| f)) + 5 *  ~~~(d ||| (e ||| f)) + 21 *  ~~~(d ||| ( ~~~e ||| f)) + 27 *  ~~~( ~~~d ||| (e ||| f)) - 7 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 14 * ( ~~~d &&& ( ~~~e &&& f)) - 17 * ( ~~~d &&& (e &&& f)) + 4 * (d &&& ( ~~~e &&& f)) - 11 * (d &&& (e &&& f)) = 5 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f)))

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

theorem main7d_logical_proof : main7d_logical_before ⊑ main7d_logical_after

theorem test_add__none_are_safe_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (x == 3#32) = 1#1 → 4#32 = x + 1#32

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

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

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

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

theorem bv_AndOrXor_794 :
    ∀ (e e_1 : LLVM.IntW w),
      LLVM.and (LLVM.icmp LLVM.IntPred.sgt e e_1) (LLVM.icmp LLVM.IntPred.ne e e_1) ⊑ LLVM.icmp LLVM.IntPred.sgt e e_1

theorem test_or_eq_a_b_proof : test_or_eq_a_b_before ⊑ test_or_eq_a_b_after

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

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

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

theorem icmp_eq_x_invertable_y2_todo_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → ofBool (x_1 ^^^ -1#8 == x ||| x_1 ^^^ -1#8) = ofBool (x &&& x_1 == 0#8)

theorem trunc_shl_ashr_var_proof : trunc_shl_ashr_var_before ⊑ trunc_shl_ashr_var_after

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

theorem ashr_ugt_5_proof : ashr_ugt_5_before ⊑ ashr_ugt_5_after

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

theorem or_not_xor_common_op_commute5_proof : or_not_xor_common_op_commute5_before ⊑ or_not_xor_common_op_commute5_after

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

theorem test1_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ¬zeroExtend 32 x ≥ ↑32 →
    ¬(True ∧ x.msb = true ∨ zeroExtend 32 x ≥ ↑32) →
      x_1.sshiftRight' (zeroExtend 32 x) &&& 1#32 = x_1 >>> zeroExtend 32 x &&& 1#32

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

theorem icmp_select_var_pred_uge_commuted_proof : icmp_select_var_pred_uge_commuted_before ⊑ icmp_select_var_pred_uge_commuted_after

theorem demorgan_nor_use2bc_proof : demorgan_nor_use2bc_before ⊑ demorgan_nor_use2bc_after

theorem src3_proof : src3_before ⊑ src3_after

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

theorem icmp_eq_zext_ne_non_boolean_proof : icmp_eq_zext_ne_non_boolean_before ⊑ icmp_eq_zext_ne_non_boolean_after

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

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

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

theorem e_2116 :
    2 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 2 * (e ||| f) - 11 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) + 7 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 6 * (e ^^^ (d &&& (e ^^^ f))) - 2 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 7 *  ~~~(d &&& ( ~~~e &&& f)) + 4 * (e &&&  ~~~(d ^^^ f)) - 2 * ((d ||| e) &&& (e ^^^ f)) - 2 *  ~~~(d ^^^ (e &&& f)) + 5 * (e &&& (d |||  ~~~f)) - 1 * (f &&& (d ^^^ e)) - 1 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 2 * ( ~~~f ||| (d ^^^ e)) - 3 * (f ||| (d ^^^ e)) + 2 * ( ~~~e &&& (d ^^^ f)) - 2 * (e &&& (d ^^^ f)) - 6 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 4 *  ~~~(e &&& f) + 3 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 3 * ( ~~~d &&& (e ||| f)) - 1 * (f ^^^ (d ||| ( ~~~e ||| f))) - 1 * (f ^^^  ~~~(d &&& e)) - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 1 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 11 * (e ^^^ ( ~~~d &&& (e ||| f))) - 2 * (f |||  ~~~(d |||  ~~~e)) - 2 * (e ^^^  ~~~(d &&&  ~~~f)) + 4 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 2 * ((d ^^^ e) &&& (d ^^^ f)) - 1 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 1 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 1 * ( ~~~d &&& (e ^^^ f)) - 2 *  ~~~( ~~~d ||| (e &&& f)) + 11 * (e ^^^  ~~~(d &&& (e ||| f))) + 11 * ((d &&& e) ^^^ (e ||| f)) - 6 *  ~~~(d ||| (e ||| f)) - 21 *  ~~~(d ||| ( ~~~e ||| f)) - 31 *  ~~~( ~~~d ||| (e ||| f)) - 39 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 33 * ( ~~~d &&& ( ~~~e &&& f)) - 9 * (d &&& ( ~~~e &&& f)) - 20 * (d &&& (e &&& f)) = 4 * ( ~~~d &&& (e &&& f))

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

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

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

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

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

theorem scalar_i32_lshr_and_negC_eq_X_is_constant2_proof : scalar_i32_lshr_and_negC_eq_X_is_constant2_before ⊑ scalar_i32_lshr_and_negC_eq_X_is_constant2_after

theorem t8_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (0#8).ssubOverflow x = true) → ofBool (0#8 - x == x) = ofBool (x == 0#8)

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

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

theorem main7a_logical_thm.extracted_1._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

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

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

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

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_3_proof : masked_icmps_mask_notallzeros_bmask_mixed_3_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_3_after

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

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

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

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

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

theorem add_or_sub_comb_i8_negative_y_add_proof : add_or_sub_comb_i8_negative_y_add_before ⊑ add_or_sub_comb_i8_negative_y_add_after

theorem 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 t0_thm.extracted_1._5 : ∀ (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 = 1#1

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_2_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_2_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_2_logical_after

theorem xor_signbit_select_shl_proof : xor_signbit_select_shl_before ⊑ xor_signbit_select_shl_after

theorem n1_proof : n1_before ⊑ n1_after

theorem tryFactorization_add_nuw_mul_nuw_mul_var_proof : tryFactorization_add_nuw_mul_nuw_mul_var_before ⊑ tryFactorization_add_nuw_mul_nuw_mul_var_after

theorem test21_proof : test21_before ⊑ test21_after

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

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

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

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

theorem e_387 :
    5 * x + 2 * (x ||| y) + 7 *  ~~~y - 11 * (x ^^^ y) - 7 *  ~~~(x ||| y) + 12 *  ~~~(x |||  ~~~y) - 3 * (x &&&  ~~~y) - 7 * (x &&& y) =  - 3 * (x |||  ~~~y) + 3 *  ~~~(x &&&  ~~~x)

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

theorem test11_thm (e : IntW 32) :
  urem (mul (LLVM.and e (const? 32 (-2))) (const? 32 2)) (const? 32 4) ⊑ const? 32 0

theorem scalar_zext_slt_proof : scalar_zext_slt_before ⊑ scalar_zext_slt_after

theorem add_f_eq (a : R q n) : a + (f q n) = a

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

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

theorem Nat.add_lt_is_or {a} (a_lt : a < 2^i) :
    2^i + a = 2^i ||

theorem and_or1_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 1), x_2 ^^^ 1#1 ||

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

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

theorem ashr_mul_times_5_div_4_exact_2_thm.extracted_1._2 : ∀ (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.sshiftRight' 2#32) = true) →
      (x * 5#32).sshiftRight' 2#32 = x + x.sshiftRight' 2#32

theorem test_invalid_simplify_select_1_proof : test_invalid_simplify_select_1_before ⊑ test_invalid_simplify_select_1_after

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

@[simp]
theorem Term.toBV_sext {wenv : WidthExpr.Env wcard}
    {tctx : Term.Ctx wcard tcard}
    (benv : Term.BoolEnv bcard)
    (tenv : tctx.Env wenv) (a : Term bcard ncard icard pcard tctx (.bv w)) (v : WidthExpr wcard) :
  Term.toBV benv nenv ienv penv tenv (.sext a v) =
    (a.toBV benv nenv ienv penv tenv).signExtend (v.toNat wenv)

theorem uaddo_commute4_proof : uaddo_commute4_before ⊑ uaddo_commute4_after

theorem PR42691_7_proof : PR42691_7_before ⊑ PR42691_7_after

theorem src_is_notmask_sext_proof : src_is_notmask_sext_before ⊑ src_is_notmask_sext_after

theorem test_with_neg_even_proof : test_with_neg_even_before ⊑ test_with_neg_even_after

@[simp]
lemma List.Vector.cast_get {bvs : List.Vector (BitVec w) n} {h : n = n'} :
    (h ▸ bvs).get i = bvs.get (i.cast h.symm)

theorem zext_sext_add_icmp_ult_minus1_proof : zext_sext_add_icmp_ult_minus1_before ⊑ zext_sext_add_icmp_ult_minus1_after

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

theorem test58_proof : test58_before ⊑ test58_after

theorem icmp_slt_0_or_icmp_sgt_0_i64_fail3_proof : icmp_slt_0_or_icmp_sgt_0_i64_fail3_before ⊑ icmp_slt_0_or_icmp_sgt_0_i64_fail3_after

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

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

theorem or_basic_proof : or_basic_before ⊑ or_basic_after

theorem e_970 :
     - 1 *  ~~~t - 6 *  ~~~(z &&& t) + 1 * z - 7 *  ~~~(z ^^^ t) + 14 *  ~~~(z ||| t) + 6 *  ~~~(z |||  ~~~t) + 6 * (z &&& t) =  - 6 * (z &&&  ~~~t)

theorem left_shift_add_1 (hu : u >= r) (hs : s >= r) :
  (bw r (shlMax (bw s (addMax (bw p a) (bw q b))) (bw t c)))  =
  (bw r (addMax (bw u (shlMax (bw p a) (bw t c))) (bw u (shlMax (bw q b) (bw t c)))))

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

theorem ashr_xor_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ x + 1#8 ≥ ↑8) →
    ¬x ≥ ↑8 → (BitVec.ofInt 8 (-128)).sshiftRight' x ^^^ (BitVec.ofInt 8 (-64)).sshiftRight' (x + 1#8) = 96#8 >>> x

theorem test_mul__nuw_is_safe_proof : test_mul__nuw_is_safe_before ⊑ test_mul__nuw_is_safe_after

theorem ashr_ult_5_proof : ashr_ult_5_before ⊑ ashr_ult_5_after

theorem PR20945_proof : PR20945_before ⊑ PR20945_after

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

theorem test2_proof : test2_before ⊑ test2_after

@[simp]
lemma CNFA.SignedCmp_stateMax cmp : (autSignedCmp cmp).m.stateMax = 5

theorem ule_swap_or_not_min_proof : ule_swap_or_not_min_before ⊑ ule_swap_or_not_min_after

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

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

@[simp]
theorem toBitVec_ofNat : BitStream.toBitVec w (BitStream.ofNat n) = BitVec.ofNat w n

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

theorem lshr_mul_times_5_div_4_exact_proof : lshr_mul_times_5_div_4_exact_before ⊑ lshr_mul_times_5_div_4_exact_after

theorem ashr_16_to_64_add_zext_basic_proof : ashr_16_to_64_add_zext_basic_before ⊑ ashr_16_to_64_add_zext_basic_after

theorem main7a_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 → 0#1 = 1#1 → 0#32 = zeroExtend 32 1#1

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

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

theorem sge_swap_and_max_commute_logical_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬ofBool (x == 127#8) = 1#1 → 0#1 = ofBool (x == 127#8)

theorem positive_sameconst_shlnuwnsw_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(3#8 ≥ ↑8 ∨
        True ∧ (x >>> 3#8 <<< 3#8).sshiftRight' 3#8 ≠ x >>> 3#8 ∨
          True ∧ x >>> 3#8 <<< 3#8 >>> 3#8 ≠ x >>> 3#8 ∨ 3#8 ≥ ↑8) →
    x >>> 3#8 <<< 3#8 = x &&& BitVec.ofInt 8 (-8)

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

theorem Tensor1d.extract_map [Inhabited α] (t: Tensor1d α) (left len: Index) :
  (t.extract left len).map f = (t.map f).extract left len

theorem exact_ashr_ne_noexactdiv_proof : exact_ashr_ne_noexactdiv_before ⊑ exact_ashr_ne_noexactdiv_after

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

theorem different_size_zext_zext_ne_commute_proof : different_size_zext_zext_ne_commute_before ⊑ different_size_zext_zext_ne_commute_after

theorem ashr_icmp2_proof : ashr_icmp2_before ⊑ ashr_icmp2_after

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

theorem e_530 :
     - 6 *  ~~~(x &&&  ~~~x) - 6 *  ~~~(x ^^^ y) - 1 * (x ||| y) - 1 *  ~~~y - 1 *  ~~~(x &&&  ~~~y) + 12 *  ~~~(x ||| y) + 7 *  ~~~(x |||  ~~~y) + 5 * (x &&&  ~~~y) + 12 * (x &&& y) =  - 1 * (x ^^^ y) - 2 * (x |||  ~~~y)

theorem CNFA.isEmpty_spec {m : CNFA n} {M : NFA' n} :
    m.Sim M → m.isEmpty → M.accepts = ∅

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

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

theorem carryWith_delta_eq_delta_carryWith
  {carryState : p.α → Bool} {x : arity → BitStream} {n : Nat} :
  p.carryWith (p.delta carryState x) (fun a i => x a (i + 1)) n =
  p.delta (p.carryWith carryState x n) (fun a i => x a (n + i))

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

theorem test_const_shr_exact_and_1_ne_0_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ 42#32 >>> x <<< x ≠ 42#32 ∨ x ≥ ↑32) →
    ¬(True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨ x ≥ ↑32) →
      ofBool (42#32 >>> x &&& 1#32 != 0#32) = ofBool (1#32 <<< x &&& 42#32 != 0#32)

theorem test9_proof : test9_before ⊑ test9_after

theorem or_and3_thm.extracted_1._6 : ∀ (x : BitVec 1) (x_1 x_2 : BitVec 32) (x_3 : BitVec 1),
  x_3 ||

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

theorem test_shl__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 e_634 :
     - 2 *  ~~~(x ^^^ y) - 5 * y + 2 *  ~~~(x &&& y) + 5 * x - 1 * (x ^^^ y) - 3 *  ~~~(x &&&  ~~~x) - 6 *  ~~~(x &&&  ~~~y) + 9 *  ~~~(x ||| y) - 1 * (x &&&  ~~~y) + 13 * (x &&& y) =  - 15 *  ~~~(x |||  ~~~y) + 2 * (x ||| y)

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

theorem signed_sign_bit_extract_trunc_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬63#64 ≥ ↑64 → ofBool (truncate 32 (x.sshiftRight' 63#64) != 0#32) = ofBool (x <ₛ 0#64)

theorem e_179 :
    2 *  ~~~(x ^^^ y) - 6 * (x |||  ~~~y) + 11 *  ~~~y + 4 *  ~~~(x &&&  ~~~y) - 4 *  ~~~(x |||  ~~~y) - 5 * (x &&&  ~~~y) = 11 *  ~~~(x ||| y)

@[simp] theorem StatesUniqueLe_zero {fsm : FSM arity} {s0 : fsm.α → Bool} {inputs : arity → BitStream} :
  StatesUniqueLe fsm s0 inputs 0

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

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

theorem exact_ashr_eq_noexactdiv_proof : exact_ashr_eq_noexactdiv_before ⊑ exact_ashr_eq_noexactdiv_after

theorem ult_rem_nz_nsw_proof : ult_rem_nz_nsw_before ⊑ ult_rem_nz_nsw_after

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

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

theorem icmp_eq_zext_ne_one_proof : icmp_eq_zext_ne_one_before ⊑ icmp_eq_zext_ne_one_after

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

theorem land_bor_right2_proof : land_bor_right2_before ⊑ land_bor_right2_after

theorem t22_sign_check2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ofBool (-1#32 <ₛ x_1) = 1#1 → ofBool (x_1 <ₛ 0#32) = 1#1 → 0#32 = x

theorem ashr_ugt_0_proof : ashr_ugt_0_before ⊑ ashr_ugt_0_after

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

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

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

theorem test68_xor_proof : test68_xor_before ⊑ test68_xor_after

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

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 ashrsgt_02_07_exact_proof : ashrsgt_02_07_exact_before ⊑ ashrsgt_02_07_exact_after

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

theorem ugt_zext_thm (e : IntW 8) (e_1 : IntW 1) :
  icmp IntPred.ugt (zext 8 e_1) e ⊑ LLVM.and (icmp IntPred.eq e (const? 8 0)) e_1

theorem e_2247 :
     - 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 1 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 7 * (e ^^^ (d ||| ( ~~~e &&& f))) + 1 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 5 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 2 * (e ^^^ (d ||| (e &&& f))) - 1 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 2 * (f &&&  ~~~(d &&&  ~~~e)) + 1 * (e ^^^ ( ~~~d &&& (e ||| f))) + 2 *  ~~~(d |||  ~~~e) + 11 * (f ||| (d ^^^ e)) + 7 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 7 * ( ~~~f ||| (d ^^^ e)) - 2 * (d ||| (e &&& f)) - 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 7 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 11 * (e ^^^  ~~~(d &&&  ~~~f)) - 1 *  ~~~(d ||| f) - 11 * (d ^^^ e) + 4 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 11 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 1 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 2 * (e ^^^ ( ~~~d ||| (e ||| f))) - 5 * ((d ||| e) &&& (e ^^^ f)) - 11 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 7 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 6 * (f ||| (d &&&  ~~~e)) + 2 * (d &&&  ~~~f) - 1 * (e ||| (d &&& f)) + 11 * ((d &&& e) ||| (e ^^^ f)) - 1 *  ~~~(d ^^^ f) + 1 * (d ||| ( ~~~e ||| f)) + 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 4 * (d &&&  ~~~e) + 2 * (f &&& (d |||  ~~~e)) + 2 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 1 *  ~~~(d &&& (e ||| f)) + 5 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 3 * (e ||| f) + 5 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 7 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 2 * (e |||  ~~~(d |||  ~~~f)) + 1 * (e |||  ~~~f) - 1 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 11 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 3 * (f ^^^ (d ||| e)) + 1 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 28 *  ~~~(d ||| (e ||| f)) - 26 *  ~~~(d ||| ( ~~~e ||| f)) - 19 *  ~~~( ~~~d ||| (e ||| f)) - 25 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 19 * ( ~~~d &&& ( ~~~e &&& f)) - 21 * ( ~~~d &&& (e &&& f)) - 10 * (d &&& ( ~~~e &&& f)) - 40 * (d &&& (e &&& f)) =  - 3 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 2 * (d |||  ~~~e)

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

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

theorem e_161 :
     - 11 *  ~~~(x &&&  ~~~y) - 7 * y + 11 *  ~~~(x ||| y) + 19 *  ~~~(x |||  ~~~y) + 1 * (x &&&  ~~~y) + 19 * (x &&& y) = 1 * (x ||| y)

theorem p0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬x_1 ≥ ↑8 → ofBool (((-1#8) <<< x_1 ^^^ -1#8) &&& x != x) = ofBool (x >>> x_1 != 0#8)

theorem ne_optimized_highbits_cmp_proof : ne_optimized_highbits_cmp_before ⊑ ne_optimized_highbits_cmp_after

theorem substitute_constant_and_eq_eq_logical_proof : substitute_constant_and_eq_eq_logical_before ⊑ substitute_constant_and_eq_eq_logical_after

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

theorem icmp_sgt10_thm (e : IntW 8) :
  icmp IntPred.sgt (shl e (const? 8 7) { «nsw» := true, «nuw» := false }) (const? 8 (-127)) ⊑
    icmp IntPred.sgt e (const? 8 (-1))

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

theorem main7a_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 → 0#1 = 1#1 → 0#32 = zeroExtend 32 1#1

theorem test8_proof : test8_before ⊑ test8_after

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

theorem shl_xor_lshr_comm_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ x_1 <<< x >>> x ≠ x_1 ∨ x ≥ ↑32 ∨ x ≥ ↑32) → ¬x ≥ ↑32 → (x_2 ^^^ x_1 <<< x) >>> x = x_2 >>> x ^^^ x_1

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

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

theorem icmp_ne_sext_ne_otherwise_i128_proof : icmp_ne_sext_ne_otherwise_i128_before ⊑ icmp_ne_sext_ne_otherwise_i128_after

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

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

theorem test23_logical_proof : test23_logical_before ⊑ test23_logical_after

theorem not_signbit_alt_xor_proof : not_signbit_alt_xor_before ⊑ not_signbit_alt_xor_after

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

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

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

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

theorem dec_mask_neg_i32_proof : dec_mask_neg_i32_before ⊑ dec_mask_neg_i32_after

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

theorem not_sext_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → -1#999 = signExtend 999 (x ^^^ 1#1)

theorem icmp_ne_sext_eq_allones_thm (e : IntW 32) :
  icmp IntPred.ne (sext 32 (icmp IntPred.eq e (const? 32 (-1)))) e ⊑
    icmp IntPred.ult (add e (const? 32 (-1))) (const? 32 (-2))

theorem gt_signed_to_small_negative_proof : gt_signed_to_small_negative_before ⊑ gt_signed_to_small_negative_after

theorem not_mul_of_pow2_proof : not_mul_of_pow2_before ⊑ not_mul_of_pow2_after

theorem test87_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(True ∧ (signExtend 32 x).smulOverflow 16#32 = true ∨ 16#32 ≥ ↑32) →
    ¬12#16 ≥ ↑16 → truncate 16 ((signExtend 32 x * 16#32).sshiftRight' 16#32) = x.sshiftRight' 12#16

theorem ashr_ult_4_proof : ashr_ult_4_before ⊑ ashr_ult_4_after

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

theorem t3_thm (e : IntW 8) (e_1 : IntW 2) :
  LLVM.xor (add (sext 8 e_1) e) (sext 8 e_1) ⊑ LLVM.xor (add e (sext 8 e_1)) (sext 8 e_1)

theorem t6_shl_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) ∨
            x + BitVec.ofInt 32 (-2) ≥ ↑32) →
    ¬30#32 ≥ ↑32 → x_1 <<< (32#32 - x) <<< (x + BitVec.ofInt 32 (-2)) = x_1 <<< 30#32

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

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

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

theorem a_false_implies_b_false2_thm (e e_1 : IntW 1) (e_2 : IntW 8) :
  LLVM.or (icmp IntPred.ugt e_2 (const? 8 10)) (select (icmp IntPred.ugt e_2 (const? 8 20)) e_1 e) ⊑
    select (icmp IntPred.ugt e_2 (const? 8 10)) (const? 1 1) e

theorem negation_of_increment_via_or_with_no_common_bits_set_proof : negation_of_increment_via_or_with_no_common_bits_set_before ⊑ negation_of_increment_via_or_with_no_common_bits_set_after

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

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

theorem ashr_ult_exact_proof : ashr_ult_exact_before ⊑ ashr_ult_exact_after

theorem ule_and_min_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 ≤ᵤ x) = 1#1 → 0#1 = ofBool (x_1 == 0#8)

theorem add_or_sub_comb_i8_negative_y_add_thm (e e_1 : IntW 8) :
  add (LLVM.or (sub (const? 8 0) e_1) e_1) e ⊑ add (LLVM.or e_1 (sub (const? 8 0) e_1)) e

theorem drop_nuw_trunc_proof : drop_nuw_trunc_before ⊑ drop_nuw_trunc_after

@[simp]
theorem eval_repeatN_zero (b : Bool) (env : Unit → BitStream) :
  (repeatN b 0).eval env = (env ())

theorem t9_highest_bit_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 x_2 : BitVec 32),
  ¬(64#32 - x_1 ≥ ↑32 ∨ zeroExtend 64 (x_1 + -1#32) ≥ ↑64) → 63#64 ≥ ↑64 → False

theorem test31_thm.extracted_1._1 : ∀ (x : BitVec 1),
  ¬4#32 ≥ ↑32 → x = 1#1 → zeroExtend 32 x <<< 4#32 &&& 16#32 = 16#32

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 trunc_sel_larger_zext_proof : trunc_sel_larger_zext_before ⊑ trunc_sel_larger_zext_after

theorem a_false_implies_b_true2_thm.extracted_1._8 : ∀ (x x_1 : BitVec 1) (x_2 : BitVec 8),
  ¬ofBool (x_2 <ᵤ 20#8) = 1#1 → ¬ofBool (10#8 <ᵤ x_2) = 1#1 → ofBool (10#8 <ᵤ x_2) ||

theorem trunc_shl_shl_var_thm.extracted_1._2 : ∀ (x x_1 : BitVec 64),
  ¬(x ≥ ↑64 ∨ 2#64 ≥ ↑64) →
    ¬(x ≥ ↑64 ∨ 2#32 ≥ ↑32) → truncate 32 (x_1 <<< x <<< 2#64) = truncate 32 (x_1 <<< x) <<< 2#32

theorem test1_thm (e e_1 : IntW 32) :
  LLVM.or (icmp IntPred.slt e_1 (const? 32 0)) (icmp IntPred.slt e (const? 32 0)) ⊑
    icmp IntPred.slt (LLVM.or e_1 e) (const? 32 0)

theorem icmp_eq_and_pow2_minus1_shl1_thm (e : IntW 32) :
  zext 32 (icmp IntPred.eq (LLVM.and (shl (const? 32 1) e) (const? 32 15)) (const? 32 0)) ⊑
    zext 32 (icmp IntPred.ugt e (const? 32 3))

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

theorem negate_add_with_single_negatible_operand_depth2_proof : negate_add_with_single_negatible_operand_depth2_before ⊑ negate_add_with_single_negatible_operand_depth2_after

theorem test_nuw_nsw_and_signed_pred_proof : test_nuw_nsw_and_signed_pred_before ⊑ test_nuw_nsw_and_signed_pred_after

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

theorem src_is_mask_const_sle_thm (e : IntW 8) :
  icmp IntPred.sle (LLVM.and (LLVM.xor e (const? 8 123)) (const? 8 31)) (LLVM.xor e (const? 8 123)) ⊑
    icmp IntPred.sgt e (const? 8 (-1))

theorem negate_sext_proof : negate_sext_before ⊑ negate_sext_after

theorem p0_proof : p0_before ⊑ p0_after

theorem test3_thm (e e_1 : IntW 49) :
  LLVM.and (LLVM.or e_1 (shl e (const? 49 1))) (const? 49 1) ⊑ LLVM.and e_1 (const? 49 1)

theorem lshr_shl_pow2_const_case2_proof : lshr_shl_pow2_const_case2_before ⊑ lshr_shl_pow2_const_case2_after

theorem e_646 :
    3 * (x |||  ~~~y) + 3 *  ~~~(x &&&  ~~~y) - 2 * y - 11 *  ~~~x + 1 * (x ||| y) + 2 *  ~~~(x &&& y) - 2 * x - 4 *  ~~~(x |||  ~~~y) - 15 * (x &&&  ~~~y) - 3 * (x &&& y) =  - 11 * (x ^^^ y) - 3 *  ~~~(x ||| y)

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

@[simp] theorem Lets.getPureExprAux_var_appendInr (lets : Lets d Γ_in eff Γ_out)
    (e : Expr d Γ_out eff ty₁) (v : Var Γ_out ty₂) :
    getPureExprAux (lets.var e) v.appendInr
    = (getPureExprAux lets v).map fun ⟨_, w, e⟩ =>
        ⟨_, w, e.changeVars <| Hom.id.castCodomain (by simp)⟩

theorem e_894 :
    3 *  ~~~t - 6 *  ~~~(z &&&  ~~~z) + 10 *  ~~~(z ||| t) + 6 *  ~~~(z |||  ~~~t) + 10 * (z &&&  ~~~t) + 13 * (z &&& t) = 7 * (z |||  ~~~t)

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

theorem a_false_implies_b_true2_thm.extracted_1._3 : ∀ (x : BitVec 1) (x_1 : BitVec 8),
  ¬ofBool (x_1 <ᵤ 20#8) = 1#1 → ofBool (10#8 <ᵤ x_1) = 1#1 → ofBool (10#8 <ᵤ x_1) ||

theorem ule_and_min_commute_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == 0#8) = 1#1 → ofBool (x_1 ≤ᵤ x) = ofBool (x_1 == 0#8)

theorem t1_thm (e e_1 : IntW 8) :
  ashr (LLVM.xor e_1 (const? 8 (-1))) e { «exact» := true } ⊑ LLVM.xor (ashr e_1 e) (const? 8 (-1))

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

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

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

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

theorem e_100 :
     - 11 * (x |||  ~~~y) + 3 *  ~~~(x &&& y) - 5 *  ~~~y + 13 *  ~~~(x ||| y) - 4 *  ~~~(x |||  ~~~y) + 12 * (x &&&  ~~~y) =  - 1 * (x ^^^ y) - 11 * (x &&& y)

theorem t14_x_is_one_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(32#32 - x ≥ ↑32 ∨ zeroExtend 64 (x + BitVec.ofInt 32 (-16)) ≥ ↑64) →
    ofBool (x_1 <<< (32#32 - x) &&& truncate 32 (1#64 >>> zeroExtend 64 (x + BitVec.ofInt 32 (-16))) != 0#32) = 0#1

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

theorem main4f_like_logical_thm.extracted_1._12 : ∀ (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 0#1

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

theorem lshrult_01_10_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬1#4 ≥ ↑4 → ofBool (x >>> 1#4 <ᵤ BitVec.ofInt 4 (-6)) = 1#1

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

theorem and_xor_or6_proof : and_xor_or6_before ⊑ and_xor_or6_after

theorem lowmask_sub_zext_commute_proof : lowmask_sub_zext_commute_before ⊑ lowmask_sub_zext_commute_after

theorem different_size_sext_sext_eq_thm.extracted_1._1 : ∀ (x : BitVec 4) (x_1 : BitVec 7),
  ofBool (signExtend 25 x_1 == signExtend 25 x) = ofBool (x_1 == signExtend 7 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 icmp_sgt10_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (x <<< 7#8).sshiftRight' 7#8 ≠ x ∨ 7#8 ≥ ↑8) →
    ofBool (BitVec.ofInt 8 (-127) <ₛ x <<< 7#8) = ofBool (-1#8 <ₛ x)

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

theorem test_sub_nuw__all_are_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 255#32 == 6#32) = 1#1 →
    True ∧ (BitVec.ofInt 32 (-254)).ssubOverflow (x &&& 255#32) = true ∨
        True ∧ (BitVec.ofInt 32 (-254)).usubOverflow (x &&& 255#32) = true →
      False

theorem t0_commutative_thm.extracted_1._18 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1) (x_3 x_4 : BitVec 8),
  ofBool (x_4 == x_3) = 1#1 → ofBool (x_4 != x_3) = 1#1 → ¬True → x_2 = 1#1 → x_1 = x

theorem sgt_x_impliesF_eq_smin_todo_thm (e e_1 e_2 : IntW 8) :
  icmp IntPred.eq (select (icmp IntPred.sgt e_2 e_1) (const? 8 (-128)) e) e_2 ⊑
    select (icmp IntPred.sle e_2 e_1) (icmp IntPred.eq e e_2) (const? 1 0)

theorem absdiff1_proof : absdiff1_before ⊑ absdiff1_after

theorem reassoc_x2_sub_nuw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.usubOverflow 4#32 = true ∨
        True ∧ x.usubOverflow 8#32 = true ∨ True ∧ (x_1 - 4#32).usubOverflow (x - 8#32) = true) →
    x_1 - 4#32 - (x - 8#32) = x_1 - x + 4#32

theorem is_ascii_alphabetic_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 masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_0_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_0_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_0_logical_after

theorem ashrslt_02_04_proof : ashrslt_02_04_before ⊑ ashrslt_02_04_after

theorem no_reassoc_add_nuw_none_proof : no_reassoc_add_nuw_none_before ⊑ no_reassoc_add_nuw_none_after

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

theorem main4f_like_logical_proof : main4f_like_logical_before ⊑ main4f_like_logical_after

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

theorem ne_3210_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(24#32 ≥ ↑32 ∨ 24#32 ≥ ↑32 ∨ 16#32 ≥ ↑32 ∨ 16#32 ≥ ↑32 ∨ 8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32) →
    ofBool (truncate 8 (x_1 >>> 24#32) != truncate 8 (x >>> 24#32)) ||

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

theorem pr51551_2_thm (e e_1 : IntW 32) :
  icmp IntPred.eq
      (LLVM.and (mul (LLVM.or (LLVM.and e_1 (const? 32 (-7))) (const? 32 1)) e { «nsw» := true, «nuw» := false })
        (const? 32 1))
      (const? 32 0) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 1)) (const? 32 0)

theorem e_1912 :
    1 * (c ^^^ (a ||| (b &&& c))) + 11 * (c ^^^ ( ~~~a &&& ( ~~~b ||| c))) - 2 * (a ||| ( ~~~b &&& c)) - 1 * (b ^^^ (a &&&  ~~~c)) + 2 * (b &&& (a ^^^ c)) - 1 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 1 * ((a &&& b) ||| (b ^^^ c)) + 2 * (c &&&  ~~~(a &&&  ~~~b)) - 6 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) - 2 * (a ||| ( ~~~b ||| c)) - 5 * (c &&& (a ^^^ b)) - 1 * ( ~~~a ||| (b ^^^ c)) + 5 * (c ||| (a &&&  ~~~b)) - 2 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 7 *  ~~~(a ^^^ (b &&& c)) - 2 * (b ||| (a &&& c)) + 1 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) - 6 * ( ~~~(a &&& b) &&&  ~~~(b ^^^ c)) - 1 * (b ^^^ (a &&& (b ^^^ c))) + 3 * (c ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 2 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) - 6 * (c |||  ~~~(a |||  ~~~b)) - 2 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) - 6 * (c ^^^  ~~~(a &&& ( ~~~b ||| c))) - 1 * (b ||| c) + 2 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) - 11 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) + 2 * ((a &&&  ~~~b) ||| (a ^^^ (b ^^^ c))) + 4 * (b |||  ~~~(a ^^^ c)) + 2 *  ~~~(b ^^^ c) - 3 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 6 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 1 * (c &&&  ~~~(a &&& b)) - 2 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) - 3 *  ~~~( ~~~a &&& ( ~~~b &&& c)) + 5 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) + 2 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) - 1 * (b ^^^ c) + 1 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 5 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) + 1 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 2 *  ~~~(b &&& c) + 24 *  ~~~(a ||| (b ||| c)) + 8 *  ~~~(a ||| ( ~~~b ||| c)) + 14 *  ~~~( ~~~a ||| (b ||| c)) + 29 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 22 * ( ~~~a &&& ( ~~~b &&& c)) + 34 * ( ~~~a &&& (b &&& c)) + 17 * (a &&& ( ~~~b &&& c)) + 20 * (a &&& (b &&& c)) = 7 * ( ~~~c &&&  ~~~(a ^^^ b)) + 3 * ((a ^^^ b) &&& (a ^^^ c))

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

theorem sdiv_shl_pair2_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ (x_2 <<< x_1).sshiftRight' x_1 ≠ x_2 ∨
        True ∧ x_2 <<< x_1 >>> 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).sshiftRight' x_1 ≠ 1#32 ∨ True ∧ 1#32 <<< x_1 >>> x_1 ≠ 1#32 ∨ x_1 ≥ ↑32 ∨ x ≥ ↑32 → False

theorem trunc_lshr_big_mask_proof : trunc_lshr_big_mask_before ⊑ trunc_lshr_big_mask_after

theorem neg_or_lshr_i32_commute_proof : neg_or_lshr_i32_commute_before ⊑ neg_or_lshr_i32_commute_after

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

theorem icmp_and_ashr_multiuse_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬4#32 ≥ ↑32 →
    ¬ofBool (x.sshiftRight' 4#32 &&& 15#32 != 14#32) = 1#1 →
      0#1 = ofBool (x &&& 240#32 != 224#32) &&& ofBool (x &&& 496#32 != 432#32)

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

theorem sgt_smin1_thm (e e_1 : IntW 32) :
  icmp IntPred.sgt (select (icmp IntPred.slt e_1 e) e_1 e) e_1 ⊑ const? 1 0

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

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

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

theorem e_2160 :
     - 1 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 7 * (e &&& (d ||| f)) + 5 *  ~~~(d &&& (e ^^^ f)) + 4 * ((d |||  ~~~e) &&& (e ^^^ f)) + 3 * (e ^^^  ~~~(d &&&  ~~~f)) + 2 * (f ^^^  ~~~(d &&& (e &&& f))) - 2 * ((d &&& f) |||  ~~~(e ||| f)) - 6 * (d &&&  ~~~f) - 11 *  ~~~(e |||  ~~~f) - 7 * (e &&& (d ^^^ f)) + 4 *  ~~~(e ||| f) + 1 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 1 * e - 3 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) - 1 * (e |||  ~~~(d ^^^ f)) - 6 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 3 * (f &&&  ~~~(d &&& e)) + 2 * ((e &&& f) ||| (d &&& (e ||| f))) - 2 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) - 2 * (e ^^^ (d &&& (e ||| f))) + 1 * (f ^^^ (d &&&  ~~~e)) + 5 * (e &&&  ~~~f) + 5 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 5 * (e ^^^ f) - 6 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 2 * (e ^^^ (d ||| f)) + 1 *  ~~~(d &&&  ~~~e) - 7 *  ~~~e - 7 *  ~~~(d |||  ~~~e) + 1 *  ~~~(d ||| f) - 1 * (f &&&  ~~~(d &&&  ~~~e)) + 2 * (f &&& (d |||  ~~~e)) - 1 * (e ^^^  ~~~(d |||  ~~~f)) - 2 * (e |||  ~~~(d ||| f)) - 5 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 7 * (e ^^^ (d &&& (e ^^^ f))) - 11 *  ~~~( ~~~d ||| (e &&& f)) + 4 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 11 *  ~~~(d ||| (e ^^^ f)) - 5 * (f ||| (d ^^^ e)) + 1 * (d ^^^ e) - 1 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 4 *  ~~~(d ||| (e ||| f)) + 15 *  ~~~(d ||| ( ~~~e ||| f)) + 26 *  ~~~( ~~~d ||| (e ||| f)) + 14 * ( ~~~d &&& ( ~~~e &&& f)) + 30 * (d &&& ( ~~~e &&& f)) - 13 * (d &&& (e &&& f)) = 1 * (e &&&  ~~~(d &&&  ~~~f)) - 14 *  ~~~( ~~~d ||| ( ~~~e ||| f))

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

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

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

theorem srem2_ashr_mask_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬((2#32 == 0 || 32 != 1 && x == intMin 32 && 2#32 == -1) = true ∨ 31#32 ≥ ↑32) →
    (2#32 == 0 || 32 != 1 && x == intMin 32 && 2#32 == -1) = true → False

theorem sub_ashr_or_i32_nuw_nsw_proof : sub_ashr_or_i32_nuw_nsw_before ⊑ sub_ashr_or_i32_nuw_nsw_after

theorem ashrsgt_01_03_exact_proof : ashrsgt_01_03_exact_before ⊑ ashrsgt_01_03_exact_after

theorem bool_add_ashr_thm (e e_1 : IntW 1) :
  ashr (add (zext 2 e_1) (zext 2 e)) (const? 2 1) ⊑
    ashr (add (zext 2 e_1) (zext 2 e) { «nsw» := false, «nuw» := true }) (const? 2 1)

theorem pow2_or_zero_is_negative_commute_thm (e : IntW 8) :
  icmp IntPred.slt (LLVM.and (sub (const? 8 0) (mul (const? 8 42) e)) (mul (const? 8 42) e)) (const? 8 0) ⊑
    icmp IntPred.eq (mul e (const? 8 42)) (const? 8 (-128))

theorem t1_otherbitwidth_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(15#16 ≥ ↑16 ∨ 15#16 ≥ ↑16) →
    ¬(True ∧ (0#16).ssubOverflow (x &&& 1#16) = true) → (x <<< 15#16).sshiftRight' 15#16 = 0#16 - (x &&& 1#16)

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

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

theorem sub_1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → (x_1 ^^^ 123#8) - x ^^^ -1#8 = (x_1 ^^^ BitVec.ofInt 8 (-124)) + x

theorem lshr_by_const_cmp_sge_value_proof : lshr_by_const_cmp_sge_value_before ⊑ lshr_by_const_cmp_sge_value_after

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

theorem lshr_C1_add_A_C2_i32_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(x &&& 65535#32) + 5#32 ≥ ↑32 →
    ¬x &&& 65535#32 ≥ ↑32 → 6#32 <<< ((x &&& 65535#32) + 5#32) = 192#32 <<< (x &&& 65535#32)

theorem test14_thm (e e_1 : IntW 8) :
  LLVM.xor (icmp IntPred.eq e_1 e) (icmp IntPred.ne e e_1) ⊑ const? 1 1

theorem udiv_common_divisor_defined_cond_proof : udiv_common_divisor_defined_cond_before ⊑ udiv_common_divisor_defined_cond_after

theorem substitute_constant_or_ne_uge_commute_proof : substitute_constant_or_ne_uge_commute_before ⊑ substitute_constant_or_ne_uge_commute_after

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

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

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

theorem icmp_ne_sext_eq_allones_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (x == -1#32)) != x) = ofBool (x + -1#32 <ᵤ BitVec.ofInt 32 (-2))

theorem generic {p q r : Nat}
    (x : BitVec p) (hpq : p < q) (hqr : q < r) :
    BitVec.sle (twoPow r q) (x.signExtend r) = false

theorem test44_proof : test44_before ⊑ test44_after

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

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

theorem fold_add_udiv_urem_commuted_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(10#32 = 0 ∨ 10#32 = 0 ∨ 4#32 ≥ ↑32) →
    ¬(10#32 = 0 ∨ True ∧ (x / 10#32).umulOverflow 6#32 = true) →
      x % 10#32 + (x / 10#32) <<< 4#32 = x / 10#32 * 6#32 + x

theorem shl1_nsw_not_exact_thm (e e_1 : IntW 8) :
  LLVM.sdiv e_1 (shl (const? 8 1) e { «nsw» := true, «nuw» := false }) ⊑
    LLVM.sdiv e_1 (shl (const? 8 1) e { «nsw» := true, «nuw» := true })

theorem add_shl_same_amount_partial_nsw1_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 6),
  ¬(True ∧ (x_2 <<< x_1).sshiftRight' x_1 ≠ x_2 ∨ x_1 ≥ ↑6 ∨ True ∧ (x <<< x_1).sshiftRight' x_1 ≠ x ∨ x_1 ≥ ↑6) →
    ¬x_1 ≥ ↑6 → x_2 <<< x_1 + x <<< x_1 = (x_2 + x) <<< x_1

theorem t0_thm (e : IntW 64) : sub (const? 64 0) (lshr e (const? 64 63)) ⊑ ashr e (const? 64 63)

theorem icmp_power2_and_icmp_shifted_mask_1073741824_1073741823_proof : icmp_power2_and_icmp_shifted_mask_1073741824_1073741823_before ⊑ icmp_power2_and_icmp_shifted_mask_1073741824_1073741823_after

theorem zext_sext_add_icmp_ugt_1_proof : zext_sext_add_icmp_ugt_1_before ⊑ zext_sext_add_icmp_ugt_1_after

theorem shl_shl_thm (e : IntW 32) : shl (shl e (const? 32 6)) (const? 32 28) ⊑ const? 32 0

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

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_logical_after

theorem 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 hoist_ashr_ahead_of_sext_1_proof : hoist_ashr_ahead_of_sext_1_before ⊑ hoist_ashr_ahead_of_sext_1_after

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

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

theorem test45_proof : test45_before ⊑ test45_after

theorem e_1828 :
    4 * (c &&& (a |||  ~~~b)) + 7 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) - 1 * ((a &&& b) |||  ~~~(b ^^^ c)) + 11 *  ~~~(a ^^^ ( ~~~b &&& c)) - 6 * (b &&&  ~~~(a &&&  ~~~c)) - 1 * ((a ||| b) &&&  ~~~(b ^^^ c)) + 4 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 1 * (b ^^^ (a &&& (b ^^^ c))) + 3 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) + 1 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) + 2 * ( ~~~(a &&& b) &&&  ~~~(b ^^^ c)) + 2 * ( ~~~a ||| (b ^^^ c)) - 11 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) - 1 * (a ||| ( ~~~b &&& c)) + 2 *  ~~~(b |||  ~~~c) - 1 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) + 4 * (c ^^^ (a &&& ( ~~~b ||| c))) - 7 * (b ^^^ ( ~~~a ||| (b ||| c))) - 2 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) + 2 * (c ||| (a ^^^ b)) + 7 * (c ||| (a &&& b)) - 1 * ( ~~~a ||| ( ~~~b &&& c)) + 4 * (b ^^^ ( ~~~a ||| (b &&& c))) - 1 * (b ^^^ c) - 2 * (c &&&  ~~~(a &&&  ~~~b)) + 5 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) + 1 * c - 11 * (a ||| (b ||| c)) + 11 * ((a |||  ~~~b) &&& (b ^^^ c)) + 3 * ((a &&& c) |||  ~~~(b ||| c)) + 2 * (b ^^^ (a &&& (b ||| c))) + 1 * (a ^^^ ( ~~~b &&& c)) - 1 * (a ^^^ (b ||| c)) + 1 * ((a &&& c) ||| (b &&&  ~~~c)) - 2 * (c ^^^ (a ||| (b ||| c))) + 5 * (c ^^^ (a &&& (b ||| c))) - 30 *  ~~~(a ||| (b ||| c)) - 5 *  ~~~(a ||| ( ~~~b ||| c)) - 25 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 24 * ( ~~~a &&& ( ~~~b &&& c)) - 6 * ( ~~~a &&& (b &&& c)) - 40 * (a &&& ( ~~~b &&& c)) + 8 * (a &&& (b &&& c)) =  - 5 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c)))

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

theorem bitvec_AddSub_1309 :
  [llvm(w)| {
    ^bb0(%X : _, %Y : _):
      %v1 = llvm.and %X, %Y
      %v2 = llvm.or %X, %Y
      %v3 = llvm.add %v1, %v2
      llvm.return %v3
  }] ⊑ [llvm(w)| {
    ^bb0(%X : _, %Y : _):
      %v3 = llvm.add %X, %Y
      llvm.return %v3
  }]

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

theorem ugt_swap_and_min_commute_logical_proof : ugt_swap_and_min_commute_logical_before ⊑ ugt_swap_and_min_commute_logical_after

theorem shrink_and_thm.extracted_1._1 : ∀ (x : BitVec 64),
  True ∧ signExtend 64 (truncate 31 (x &&& 42#64)) ≠ x &&& 42#64 ∨
      True ∧ zeroExtend 64 (truncate 31 (x &&& 42#64)) ≠ x &&& 42#64 →
    False

theorem t0_proof : t0_before ⊑ t0_after

theorem test16_proof : test16_before ⊑ test16_after

theorem icmp_sle3_proof : icmp_sle3_before ⊑ icmp_sle3_after

@[simp] theorem lt_length (v : Γ.Var t) : v.1 < Γ.length

theorem land_land_left2_proof : land_land_left2_before ⊑ land_land_left2_after

theorem n10_lshr_ashr_thm (e : IntW 16) (e_1 : IntW 32) :
  ashr (trunc 16 (lshr e_1 (zext 32 (sub (const? 16 32) e)))) (add e (const? 16 (-1))) ⊑
    ashr (trunc 16 (lshr e_1 (zext 32 (sub (const? 16 32) e) { «nneg» := true }))) (add e (const? 16 (-1)))

theorem src_srem_shl_demand_min_signbit_mask_hit_last_demand_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬((536870912#32 == 0 || 32 != 1 && x == intMin 32 && 536870912#32 == -1) = true ∨ 1#32 ≥ ↑32) →
    (536870912#32 == 0 || 32 != 1 && x == intMin 32 && 536870912#32 == -1) = true ∨
        True ∧ (x.srem 536870912#32 <<< 1#32).sshiftRight' 1#32 ≠ x.srem 536870912#32 ∨ 1#32 ≥ ↑32 →
      False

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

theorem a_true_implies_b_true2_proof : a_true_implies_b_true2_before ⊑ a_true_implies_b_true2_after

theorem test2_proof : test2_before ⊑ test2_after

theorem mul_eleven'' (x : BitVec w) : 11 * x =
  x <<< (3 : ℕ) + x <<< (1 : ℕ) + x

theorem shiftLeft_eq' {x : BitVec w₁} {y : BitVec w₂} : x <<< y = x <<< y.toNat

theorem e_1906 :
    4 * (a &&&  ~~~c) - 1 * (a ^^^ b) - 5 *  ~~~(b ^^^ c) + 7 * ( ~~~a ||| (b &&& c)) + 4 * (b ^^^ (a ||| (b ^^^ c))) - 5 * (c &&& (a ||| b)) - 1 * (a ||| b) - 1 * (c &&&  ~~~(a &&&  ~~~b)) + 3 *  ~~~(a ^^^ (b ^^^ c)) + 7 * a + 5 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) + 4 * (c ^^^ (a ||| ( ~~~b &&& c))) - 1 * (c ^^^ (a &&& ( ~~~b ||| c))) + 1 * ( ~~~a &&& ( ~~~b ||| c)) + 3 * (b |||  ~~~c) - 2 * (c ^^^ (a &&& (b ||| c))) + 1 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) - 1 * (a &&& (b ^^^ c)) - 1 * (a |||  ~~~b) - 3 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 3 *  ~~~(a ^^^ (b ||| c)) + 1 *  ~~~b - 1 * (a &&& b) + 2 * (a &&&  ~~~b) + 7 * (b ^^^ c) - 2 *  ~~~( ~~~a &&& ( ~~~b ||| c)) + 5 * (c ^^^  ~~~(a &&& (b ||| c))) + 2 * (b ^^^ (a &&& c)) + 7 * (b ^^^  ~~~(a ||| c)) - 7 * ( ~~~(a &&& b) &&& (b ^^^ c)) + 1 * ( ~~~c ||| (a ^^^ b)) + 3 * (b &&& (a ^^^ c)) + 1 *  ~~~(a ^^^ b) - 3 * (a ^^^ (b ^^^ c)) - 2 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 11 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 11 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) - 1 * (c ^^^ ( ~~~a &&& (b ||| c))) - 11 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) + 1 * c + 7 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 7 * ((a &&& b) ^^^ (b |||  ~~~c)) + 2 * (c ^^^ ( ~~~a ||| (b ||| c))) + 1 * ( ~~~a ||| (b ||| c)) - 27 *  ~~~(a ||| (b ||| c)) - 18 *  ~~~(a ||| ( ~~~b ||| c)) - 2 *  ~~~( ~~~a ||| (b ||| c)) - 44 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 9 * ( ~~~a &&& (b &&& c)) + 1 * (a &&& (b &&& c)) = 10 * (a &&& ( ~~~b &&& c))

theorem e_1510 :
     - 11 *  ~~~c + 3 * ( ~~~c &&&  ~~~(a ^^^ b)) + 10 *  ~~~(a ||| (b ||| c)) + 11 *  ~~~(a ||| ( ~~~b ||| c)) + 13 *  ~~~( ~~~a ||| (b ||| c)) + 8 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 2 * ( ~~~a &&& ( ~~~b &&& c)) + 2 * (a &&& ( ~~~b &&& c)) + 2 * (a &&& (b &&& c)) =  - 2 * ( ~~~a &&& (b &&& c)) + 2 *  ~~~(b &&&  ~~~c)

theorem xor_nosignbit_ashr_thm (e : IntW 32) :
  ashr (LLVM.xor e (const? 32 2147418112)) (const? 32 8) ⊑ LLVM.xor (ashr e (const? 32 8)) (const? 32 8388352)

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

theorem test12_proof : test12_before ⊑ test12_after

theorem zext_ult_zext_proof : zext_ult_zext_before ⊑ zext_ult_zext_after

theorem fold_inverted_icmp_preds_proof : fold_inverted_icmp_preds_before ⊑ fold_inverted_icmp_preds_after

theorem test_shl_nsw__nuw_is_safe_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 1073741822#32 == 0#32) = 1#1 →
    ¬(True ∧ ((x_1 &&& 1073741822#32) <<< 2#32).sshiftRight' 2#32 ≠ x_1 &&& 1073741822#32 ∨
          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 main10_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 64#32 == 0#32) &&& ofBool (0#8 ≤ₛ truncate 8 x) = 1#1 →
    ¬ofBool (x &&& 192#32 == 0#32) = 1#1 → 2#32 = 1#32

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

theorem main3c_logical_proof : main3c_logical_before ⊑ main3c_logical_after

theorem positive_samevar_proof : positive_samevar_before ⊑ positive_samevar_after

theorem low_mask_nsw_nuw_proof : low_mask_nsw_nuw_before ⊑ low_mask_nsw_nuw_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 main4c_logical_proof : main4c_logical_before ⊑ main4c_logical_after

theorem bv_AndOrXor_2429 :
    ∀ (e e_1 : LLVM.IntW w),
      LLVM.xor (LLVM.and e_1 e) (LLVM.const? w (-1)) ⊑
        LLVM.or (LLVM.xor e_1 (LLVM.const? w (-1))) (LLVM.xor e (LLVM.const? w (-1)))

theorem alive_AddSub_1560  (w : Nat)   : alive_AddSub_1560_src w  ⊑ alive_AddSub_1560_tgt w

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

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

theorem t1_flags_nuw_first_proof : t1_flags_nuw_first_before ⊑ t1_flags_nuw_first_after

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

theorem udiv_shl_mul_nuw_proof : udiv_shl_mul_nuw_before ⊑ udiv_shl_mul_nuw_after

theorem test13_proof : test13_before ⊑ test13_after

theorem lshrugt_01_03_proof : lshrugt_01_03_before ⊑ lshrugt_01_03_after

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

@[simp] theorem Valuation.append_inj_right {V : Γ.Valuation} {W W' : Δ.Valuation} :
    (V ++ W) = (V ++ W') ↔ W = W'

theorem t2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ¬x ≥ ↑8 → x_1 - BitVec.ofInt 8 (-42) <<< x = 42#8 <<< x + x_1

theorem sub_select_sext_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → x - signExtend 64 x_1 = x

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

theorem negative4_logical_proof : negative4_logical_before ⊑ negative4_logical_after

theorem positive_samevar_lshrexact_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ x_1 >>> x <<< x ≠ x_1 ∨ x ≥ ↑8 ∨ x ≥ ↑8) → x_1 >>> x <<< x = x_1

theorem icmp_ne_sext_slt_otherwise_nofold_proof : icmp_ne_sext_slt_otherwise_nofold_before ⊑ icmp_ne_sext_slt_otherwise_nofold_after

theorem negate_select_of_op_vs_negated_op_nsw_xyyx_proof : negate_select_of_op_vs_negated_op_nsw_xyyx_before ⊑ negate_select_of_op_vs_negated_op_nsw_xyyx_after

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

theorem slt_smin3_proof : slt_smin3_before ⊑ slt_smin3_after

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

theorem shl_mask_wrong_shl_const_proof : shl_mask_wrong_shl_const_before ⊑ shl_mask_wrong_shl_const_after

theorem invert_both_cmp_operands_complex_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32) (x_2 : BitVec 1),
  x_2 = 1#1 → ofBool (x_1 + (x ^^^ -1#32) ≤ₛ x_1 ^^^ -1#32) = ofBool (x_1 ≤ₛ x - x_1)

theorem ashrsgt_01_11_exact_proof : ashrsgt_01_11_exact_before ⊑ ashrsgt_01_11_exact_after

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

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 1), x &&& 0#1 = 0#1

theorem n2_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬15#32 ≥ ↑32 → zeroExtend 32 x <<< 15#32 &&& BitVec.ofInt 32 (-2147483648) = 0#32

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

theorem e_667 :
    7 * x - 1 * (x ||| y) + 1 * (x |||  ~~~y) + 7 * (x ^^^ y) - 5 *  ~~~(x ^^^ y) + 1 *  ~~~(x &&&  ~~~y) - 6 *  ~~~(x &&& y) + 18 *  ~~~(x ||| y) + 8 *  ~~~(x |||  ~~~y) - 5 * (x &&&  ~~~y) = 3 *  ~~~(x &&&  ~~~x) + 6 *  ~~~x

theorem ashr_mul_times_3_div_2_proof : ashr_mul_times_3_div_2_before ⊑ ashr_mul_times_3_div_2_after

theorem basic_preserve_nuw_thm (e e_1 : IntW 8) :
  LLVM.xor (add (LLVM.xor e_1 (const? 8 (-1))) e { «nsw» := false, «nuw» := true }) (const? 8 (-1)) ⊑
    sub e_1 e { «nsw» := false, «nuw» := true }

theorem ashrslt_02_12_proof : ashrslt_02_12_before ⊑ ashrslt_02_12_after

theorem t17_nocse_mismatching_x_proof : t17_nocse_mismatching_x_before ⊑ t17_nocse_mismatching_x_after

theorem sge_or_max_proof : sge_or_max_before ⊑ sge_or_max_after

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

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

theorem c0_thm (e : IntW 8) :
  icmp IntPred.sle (LLVM.and e (const? 8 3)) e ⊑ icmp IntPred.sgt e (const? 8 (-1))

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

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

theorem e_97 :
     - 2 * x + 7 *  ~~~(x &&&  ~~~y) + 4 *  ~~~x + 11 *  ~~~y - 9 * (x &&&  ~~~y) - 5 * (x &&& y) = 22 *  ~~~(x ||| y) + 11 *  ~~~(x |||  ~~~y)

theorem t1_single_bit_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬(32#32 - x_1 ≥ ↑32 ∨ zeroExtend 64 (x_1 + BitVec.ofInt 32 (-16)) ≥ ↑64) →
    ofBool (32768#32 <<< (32#32 - x_1) &&& truncate 32 (x >>> zeroExtend 64 (x_1 + BitVec.ofInt 32 (-16))) != 0#32) =
      ofBool (x &&& 2147483648#64 != 0#64)

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

theorem test_shl_nsw__nuw_is_safe_proof : test_shl_nsw__nuw_is_safe_before ⊑ test_shl_nsw__nuw_is_safe_after

theorem testi64i32_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬63#64 ≥ ↑64 → ofBool (-1#64 <ₛ x) = 1#1 → truncate 32 (x.sshiftRight' 63#64) ^^^ 127#32 = 127#32

theorem shrink_and_proof : shrink_and_before ⊑ shrink_and_after

theorem sub_from_constant_thm (e e_1 : IntW 5) : add (sub (const? 5 10) e_1) e ⊑ add (sub e e_1) (const? 5 10)

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

theorem lshrult_01_10_proof : lshrult_01_10_before ⊑ lshrult_01_10_after

theorem test11_proof : test11_before ⊑ test11_after

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

theorem alive_AddSub_1176  (w : Nat)   : alive_AddSub_1176_src w  ⊑ alive_AddSub_1176_tgt w

theorem n8_wrong_pred3_proof : n8_wrong_pred3_before ⊑ n8_wrong_pred3_after

theorem test1_proof : test1_before ⊑ test1_after

theorem positive_and_odd_eq_proof : positive_and_odd_eq_before ⊑ positive_and_odd_eq_after

theorem test_zext1_proof : test_zext1_before ⊑ test_zext1_after

@[simp] theorem Com.outContext_rets (vs : HVector Γ.Var t) : (rets vs : Com d Γ eff t).outContext = Γ

theorem zext_false_val_must_be_zero_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → zeroExtend 32 x = 0#32

theorem e_240 :
    1 *  ~~~(x ^^^ y) - 1 *  ~~~(x &&&  ~~~x) + 1 * (x ||| y) + 5 * x + 3 *  ~~~(x ||| y) - 5 * (x &&&  ~~~y) - 6 * (x &&& y) = 3 *  ~~~x - 3 *  ~~~(x |||  ~~~y)

theorem shift_xor_multiuse_cmp_with_and_thm (e e_1 e_2 e_3 : IntW 32) :
  mul
      (select (icmp IntPred.ne (const? 32 0) (LLVM.and e_3 (const? 32 4096))) e_2
        (LLVM.and e_2 (const? 32 (-2049))))
      (select (icmp IntPred.ne (const? 32 0) (LLVM.and e_3 (const? 32 4096))) e_1 e) ⊑
    mul
      (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) (LLVM.and e_2 (const? 32 (-2049)))
        e_2)
      (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) e e_1)

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

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

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

@[simp] theorem tail_corec : tail (corec b f) = corec (f b).snd f

theorem icmp_sgt10_proof : icmp_sgt10_before ⊑ icmp_sgt10_after

theorem eq3 (w : Nat) (a b : BitVec w) : a = a ||

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

theorem select_lshr_icmp_bad_proof : select_lshr_icmp_bad_before ⊑ select_lshr_icmp_bad_after

theorem zext_zext_eq_proof : zext_zext_eq_before ⊑ zext_zext_eq_after

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

theorem test15_thm (e : IntW 8) : LLVM.and (lshr e (const? 8 7)) (const? 8 2) ⊑ const? 8 0

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

theorem test1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 33),
  ofBool (x_1 &&& 65280#33 != x &&& 65280#33) = ofBool ((x_1 ^^^ x) &&& 65280#33 != 0#33)

theorem fake_sext_proof : fake_sext_before ⊑ fake_sext_after

theorem e_1956 :
     - 11 * ((a &&& c) |||  ~~~(b ||| c)) + 7 * (c ^^^  ~~~(a &&& (b &&& c))) - 1 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) + 1 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) + 1 * ((a ||| b) &&& (b ^^^ c)) + 5 * (b ^^^ ( ~~~a &&& (b ||| c))) - 6 *  ~~~(a ^^^ (b ^^^ c)) + 11 * (c ^^^ ( ~~~a ||| (b &&& c))) - 2 * ((a &&& b) |||  ~~~(b ||| c)) + 2 * (b ^^^ (a |||  ~~~c)) - 7 *  ~~~(a |||  ~~~c) + 11 * ( ~~~a &&& (b ||| c)) - 5 * (b ^^^ (a ||| ( ~~~b ||| c))) + 4 * ((a &&& b) |||  ~~~(b |||  ~~~c)) + 1 *  ~~~(a ^^^ b) + 3 * (c ^^^  ~~~(a ||| (b &&& c))) - 11 *  ~~~(a &&& ( ~~~b &&& c)) + 2 * (b |||  ~~~(a ^^^ c)) + 2 * (b ||| (a &&&  ~~~c)) - 3 *  ~~~(a ^^^ (b ||| c)) - 1 * (a ||| c) + 1 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) - 1 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) - 2 * (a &&& c) + 2 * (b &&& (a |||  ~~~c)) - 3 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 3 * ( ~~~a &&& ( ~~~b ||| c)) + 1 * (a |||  ~~~b) + 1 * (c ^^^ (a ||| ( ~~~b &&& c))) - 5 * (b ^^^ ( ~~~a ||| (b ^^^ c))) - 6 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) - 6 * (c ^^^ (a |||  ~~~b)) - 2 * (c ||| (a &&&  ~~~b)) - 3 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) + 1 * ( ~~~b ||| (a ^^^ c)) - 2 * (c ^^^ (a &&& b)) - 3 * (a ^^^ c) + 1 * (b ^^^ c) - 1 * b + 7 *  ~~~(a ||| c) - 5 *  ~~~( ~~~a ||| ( ~~~b &&& c)) + 4 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 3 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) + 7 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) - 6 *  ~~~( ~~~a ||| (b ^^^ c)) + 1 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) + 19 *  ~~~(a ||| (b ||| c)) - 32 *  ~~~(a ||| ( ~~~b ||| c)) + 36 *  ~~~( ~~~a ||| (b ||| c)) + 11 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 16 * ( ~~~a &&& ( ~~~b &&& c)) + 15 * ( ~~~a &&& (b &&& c)) + 13 * (a &&& ( ~~~b &&& c)) + 17 * (a &&& (b &&& c)) =  - 5 * (c ^^^ (a &&& (b ||| c)))

theorem or_umin_proof : or_umin_before ⊑ or_umin_after

theorem test11_thm (e e_1 : IntW 32) :
  mul (LLVM.and (add (shl e_1 (const? 32 8)) e) (const? 32 128)) (shl e_1 (const? 32 8)) ⊑
    mul (LLVM.and e (const? 32 128)) (shl e_1 (const? 32 8))

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

theorem neg_sgt_1_proof : neg_sgt_1_before ⊑ neg_sgt_1_after

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

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

@[simp] theorem toCom_nil {com : Com d Γ eff ty} : toCom ⟨.nil, com⟩ = com

theorem differentconsts_thm.extracted_1._4 : ∀ (x : BitVec 32),
  ¬ofBool (x + 16#32 <ᵤ 144#32) = 1#1 →
    ofBool (x <ₛ 128#32) = 1#1 →
      ¬ofBool (127#32 <ₛ x) = 1#1 → ¬ofBool (x <ₛ BitVec.ofInt 32 (-16)) = 1#1 → 256#16 = truncate 16 x

theorem icmp_eq_and_pow2_shl_pow2_thm (e : IntW 32) :
  zext 32 (icmp IntPred.eq (LLVM.and (shl (const? 32 2) e) (const? 32 16)) (const? 32 0)) ⊑
    zext 32 (icmp IntPred.ne e (const? 32 3))

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

theorem PR42691_10_proof : PR42691_10_before ⊑ PR42691_10_after

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

theorem ugt_rem_zero_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.umulOverflow 7#8 = true) → ofBool (21#8 <ᵤ x * 7#8) = ofBool (3#8 <ᵤ x)

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

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

theorem scalar_i16_lshr_and_negC_eq_thm (e e_1 : IntW 16) :
  icmp IntPred.eq (LLVM.and (lshr e_1 e) (const? 16 (-128))) (const? 16 0) ⊑
    icmp IntPred.ult (lshr e_1 e) (const? 16 128)

theorem lt_signed_to_small_negative_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x <ₛ BitVec.ofInt 32 (-17)) = ofBool (x <ₛ BitVec.ofInt 8 (-17))

theorem signed_sign_bit_extract_thm (e : IntW 32) :
  icmp IntPred.ne (ashr e (const? 32 31)) (const? 32 0) ⊑ icmp IntPred.slt e (const? 32 0)

theorem ashrslt_03_03_exact_proof : ashrslt_03_03_exact_before ⊑ ashrslt_03_03_exact_after

theorem demorganize_constant2_proof : demorganize_constant2_before ⊑ demorganize_constant2_after

theorem shl_or_with_or_disjoint_instead_of_add_proof : shl_or_with_or_disjoint_instead_of_add_before ⊑ shl_or_with_or_disjoint_instead_of_add_after

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

theorem sge_or_not_max_logical_proof : sge_or_not_max_logical_before ⊑ sge_or_not_max_logical_after

theorem select_icmp_sgt_not_smin_proof : select_icmp_sgt_not_smin_before ⊑ select_icmp_sgt_not_smin_after

theorem alive_InstCombineShift__440  (w : Nat)   : alive_InstCombineShift__440_src w  ⊑ alive_InstCombineShift__440_tgt w

theorem e_1753 :
     - 7 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) - 1 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) - 6 * ( ~~~c ||| (a ^^^ b)) - 1 * (b ^^^  ~~~(a &&&  ~~~c)) + 2 * (b ^^^  ~~~(a &&& c)) + 11 * (b ^^^ c) - 1 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) + 7 * (c ^^^  ~~~(a &&& (b &&& c))) - 11 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) + 3 * (a ^^^ c) - 7 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) - 6 * ((a &&& b) ^^^ (b |||  ~~~c)) + 1 *  ~~~(a &&& ( ~~~b ||| c)) + 1 * (c &&& (a ||| b)) - 5 * ((a |||  ~~~b) &&& (b ^^^ c)) - 2 * ( ~~~c |||  ~~~(a ^^^ b)) - 3 *  ~~~(b |||  ~~~c) + 7 * (a &&& b) + 1 * ( ~~~b |||  ~~~(a ^^^ c)) - 2 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) - 6 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 2 * ( ~~~a ||| ( ~~~b ||| c)) + 1 * a - 2 * (a ^^^ (b ^^^ c)) + 1 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) - 7 * ((a &&& b) |||  ~~~(b |||  ~~~c)) + 7 * ( ~~~a &&& ( ~~~b ||| c)) + 18 *  ~~~(a ||| (b ||| c)) + 15 *  ~~~(a ||| ( ~~~b ||| c)) + 20 *  ~~~( ~~~a ||| (b ||| c)) + 10 * ( ~~~a &&& ( ~~~b &&& c)) + 21 * ( ~~~a &&& (b &&& c)) + 21 * (a &&& ( ~~~b &&& c)) + 19 * (a &&& (b &&& c)) =  - 1 *  ~~~( ~~~a ||| ( ~~~b ||| c))

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

theorem or_and_or_pat2_proof : or_and_or_pat2_before ⊑ or_and_or_pat2_after

theorem exact_ashr_ne_noexactdiv_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ BitVec.ofInt 8 (-80) >>> x <<< x ≠ BitVec.ofInt 8 (-80) ∨ x ≥ ↑8) →
    ofBool ((BitVec.ofInt 8 (-80)).sshiftRight' x != BitVec.ofInt 8 (-31)) = 1#1

theorem test23_thm (e : IntW 8) :
  LLVM.xor (LLVM.or (LLVM.xor (LLVM.or e (const? 8 (-2))) (const? 8 13)) (const? 8 1)) (const? 8 12) ⊑
    const? 8 (-1)

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

theorem rep_zero [Fact (q > 1)]: R.representative q n 0 = 0

theorem select_add_proof : select_add_before ⊑ select_add_after

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

theorem xor_logic_and_or1_proof : xor_logic_and_or1_before ⊑ xor_logic_and_or1_after

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

theorem sge_to_ugt_proof : sge_to_ugt_before ⊑ sge_to_ugt_after

theorem sge_swap_and_max_commute_logical_proof : sge_swap_and_max_commute_logical_before ⊑ sge_swap_and_max_commute_logical_after

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 e_1518 :
     - 1 * (a ^^^ (b ^^^ c)) - 1 * (b ^^^ (a &&& (b ||| c))) + 1 *  ~~~(a ||| (b &&& c)) + 3 * ((a &&& c) ||| (b &&&  ~~~c)) - 1 *  ~~~(a ||| (b ||| c)) - 2 *  ~~~(a ||| ( ~~~b ||| c)) + 1 *  ~~~( ~~~a ||| (b ||| c)) - 3 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 1 * ( ~~~a &&& (b &&& c)) - 2 * (a &&& (b &&& c)) = 2 * (a &&& ( ~~~b &&& c))

theorem ugt_swap_and_min_proof : ugt_swap_and_min_before ⊑ ugt_swap_and_min_after

omit [LawfulBEq A] [Fintype S] in
lemma processOneElem_rel_preserve :
    s₂ ~[st.rel] sa' →
    s₂ ~[(processOneElem A S final s₁ st (a, sa)).rel] sa'

theorem badimm4_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(7#8 ≥ ↑8 ∨ 8#16 ≥ ↑16) →
    ofBool ((truncate 8 x).sshiftRight' 7#8 == truncate 8 (x >>> 8#16)) = 1#1 →
      ofBool (127#16 <ₛ x) = 1#1 → truncate 8 x = 126#8

theorem sub_from_constant_of_add_with_constant_proof : sub_from_constant_of_add_with_constant_before ⊑ sub_from_constant_of_add_with_constant_after

@[simp]
theorem concat_eq_sub_of_lt
    {b : Bool} {x : BitStream} {i : Nat} (hi : 0 < i) :
    concat b x i = x (i - 1)

theorem ashrslt_03_03_proof : ashrslt_03_03_before ⊑ ashrslt_03_03_after

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

theorem test4_proof : test4_before ⊑ test4_after

theorem zext_false_val_must_be_zero_proof : zext_false_val_must_be_zero_before ⊑ zext_false_val_must_be_zero_after

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

theorem test_and_ne_a_b_commuted_proof : test_and_ne_a_b_commuted_before ⊑ test_and_ne_a_b_commuted_after

theorem icmp_ugt_32_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ x <<< 32#64 >>> 32#64 ≠ x ∨ 32#64 ≥ ↑64) → ofBool (4294967295#64 <ᵤ x <<< 32#64) = ofBool (x != 0#64)

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

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

theorem test_sub_nuw_nsw__nsw_is_safe_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x ||| BitVec.ofInt 32 (-2147483648) == BitVec.ofInt 32 (-2147483647)) = 1#1 →
    ¬(True ∧ (BitVec.ofInt 32 (-2147483648)).ssubOverflow (x ||| BitVec.ofInt 32 (-2147483648)) = true ∨
          True ∧ (BitVec.ofInt 32 (-2147483648)).usubOverflow (x ||| BitVec.ofInt 32 (-2147483648)) = true) →
      True ∧ (BitVec.ofInt 32 (-2147483648)).ssubOverflow (x ||| BitVec.ofInt 32 (-2147483648)) = true → False

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

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

theorem sext_xor_sub_2_proof : sext_xor_sub_2_before ⊑ sext_xor_sub_2_after

theorem coeff_modByMonic_degree_lt_f {i : Nat} (p : (ZMod q)[X])
    (DEGREE : p.degree < (f q n).degree) :
  (p %ₘ f q n).coeff i = p.coeff i

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

theorem ashr_lshr_cst2_proof : ashr_lshr_cst2_before ⊑ ashr_lshr_cst2_after

theorem lshr_exact_add_nuw_thm (e : IntW 32) :
  lshr (const? 32 4) (add e (const? 32 1) { «nsw» := false, «nuw» := true }) { «exact» := true } ⊑
    lshr (const? 32 2) e { «exact» := true }

theorem test12_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(2#32 == 0 || 32 != 1 && x &&& BitVec.ofInt 32 (-4) == intMin 32 && 2#32 == -1) = true →
    (x &&& BitVec.ofInt 32 (-4)).srem 2#32 = 0#32

theorem test_add_nuw__nsw_is_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x ||| BitVec.ofInt 32 (-2147483648) == -1#32) = 1#1 →
    ¬(True ∧ (x ||| BitVec.ofInt 32 (-2147483648)).saddOverflow 1#32 = true) →
      0#32 = (x ||| BitVec.ofInt 32 (-2147483648)) + 1#32

theorem lshr_add_exact_proof : lshr_add_exact_before ⊑ lshr_add_exact_after

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

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

theorem test25_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.sge e (const? 32 50)) (icmp IntPred.slt e (const? 32 100)) ⊑
    icmp IntPred.ult (add e (const? 32 (-50))) (const? 32 50)

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

@[simp]
lemma dec_enc' : dec (enc bvs) = bvs

theorem lshr_sub_nsw_proof : lshr_sub_nsw_before ⊑ lshr_sub_nsw_after

theorem ashrsgt_02_07_exact_proof : ashrsgt_02_07_exact_before ⊑ ashrsgt_02_07_exact_after

theorem test35_with_trunc_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ofBool (0#32 ≤ₛ truncate 32 x) = 1#1 → ¬ofBool (x &&& 2147483648#64 == 0#64) = 1#1 → 60#32 = 100#32

theorem test3_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.ssubOverflow x = true) →
    ofBool (x_1 - x == 0#32) = 1#1 → ¬ofBool (x_1 == x) = 1#1 → 1#1 = ofBool (x_1 - x == 31#32)

theorem eq_signed_to_small_unsigned_proof : eq_signed_to_small_unsigned_before ⊑ eq_signed_to_small_unsigned_after

theorem negtest_near_pow2_cmpval_would_overflow_into_signbit_thm (e : IntW 8) :
  icmp IntPred.ult (ashr e (const? 8 2) { «exact» := true }) (const? 8 33) ⊑
    icmp IntPred.sgt e (const? 8 (-1))

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

theorem select_icmp_ne_0_and_4096_and_not_4096_proof : select_icmp_ne_0_and_4096_and_not_4096_before ⊑ select_icmp_ne_0_and_4096_and_not_4096_after

theorem test15_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(x ≥ ↑32 ∨ zeroExtend 64 (1#32 <<< x) = 0) →
    ¬(True ∧ ((-1#32) <<< x).sshiftRight' x ≠ -1#32 ∨ x ≥ ↑32 ∨ True ∧ (x_1 &&& ((-1#32) <<< x ^^^ -1#32)).msb = true) →
      zeroExtend 64 x_1 % zeroExtend 64 (1#32 <<< x) = zeroExtend 64 (x_1 &&& ((-1#32) <<< x ^^^ -1#32))

theorem lor_bor_right1_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → x ||

@[simp] theorem carry_succ (initCarry : Bool) (x y : BitStream) :
    (carry initCarry x y (i + 1)) =
  let out

theorem pr40493_neg1_thm (e : IntW 32) :
  icmp IntPred.eq (LLVM.and (mul e (const? 32 11)) (const? 32 4)) (const? 32 0) ⊑
    icmp IntPred.eq (LLVM.and (mul e (const? 32 3)) (const? 32 4)) (const? 32 0)

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

theorem n2_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(BitVec.ofInt 8 (-128) == 0 || 8 != 1 && x == intMin 8 && BitVec.ofInt 8 (-128) == -1) = true →
    x.sdiv (BitVec.ofInt 8 (-128)) = zeroExtend 8 (ofBool (x == BitVec.ofInt 8 (-128)))

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

theorem t2_proof : t2_before ⊑ t2_after

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

theorem not_and_and_or_no_or_commute1_proof : not_and_and_or_no_or_commute1_before ⊑ not_and_and_or_no_or_commute1_after

theorem t0_proof : t0_before ⊑ t0_after

theorem and_not_or_commute4_proof : and_not_or_commute4_before ⊑ and_not_or_commute4_after

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

theorem or_xor_tree_0111_proof : or_xor_tree_0111_before ⊑ or_xor_tree_0111_after

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

theorem test_shl_nuw__nsw_is_safe_thm (e : IntW 32) :
  mul
      (mul
        (select (icmp IntPred.eq (LLVM.or e (const? 32 (-83886080))) (const? 32 (-83886079)))
          (const? 32 (-335544316))
          (shl (LLVM.or e (const? 32 (-83886080))) (const? 32 2) { «nsw» := false, «nuw» := true }))
        (LLVM.or e (const? 32 (-83886080))))
      (shl (LLVM.or e (const? 32 (-83886080))) (const? 32 2) { «nsw» := false, «nuw» := true }) ⊑
    const? 32 0

theorem ashrslt_02_12_exact_proof : ashrslt_02_12_exact_before ⊑ ashrslt_02_12_exact_after

theorem ne_umin1_proof : ne_umin1_before ⊑ ne_umin1_after

theorem neg_slt_n1_proof : neg_slt_n1_before ⊑ neg_slt_n1_after

theorem xor_add_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ (73#32).ssubOverflow (x &&& 31#32) = true ∨ True ∧ (73#32).usubOverflow (x &&& 31#32) = true) →
    (x &&& 31#32 ^^^ 31#32) + 42#32 = 73#32 - (x &&& 31#32)

theorem negative_not_less_than_logical_proof : negative_not_less_than_logical_before ⊑ negative_not_less_than_logical_after

theorem test_sub_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 prove_exact_with_high_mask_thm (e : IntW 8) :
  LLVM.sdiv (LLVM.and e (const? 8 (-8))) (const? 8 4) ⊑ LLVM.and (ashr e (const? 8 2)) (const? 8 (-2))

theorem t3_thm (e : IntW 8) :
  icmp IntPred.sle (sub (const? 8 0) e { «nsw» := true, «nuw» := false }) e ⊑
    icmp IntPred.sgt e (const? 8 (-1))

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

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

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

theorem mul16_low_miss_shift_amount_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬(8#16 ≥ ↑16 ∨ 8#16 ≥ ↑16 ∨ 8#16 ≥ ↑16) →
    8#16 ≥ ↑16 ∨
        True ∧ (x_1 >>> 8#16).smulOverflow (x &&& 127#16) = true ∨
          True ∧ (x_1 >>> 8#16).umulOverflow (x &&& 127#16) = true ∨
            8#16 ≥ ↑16 ∨
              True ∧ (x_1 &&& 127#16).smulOverflow (x >>> 8#16) = true ∨
                True ∧ (x_1 &&& 127#16).umulOverflow (x >>> 8#16) = true ∨
                  True ∧ (x_1 >>> 8#16 * (x &&& 127#16)).uaddOverflow ((x_1 &&& 127#16) * x >>> 8#16) = true ∨
                    8#16 ≥ ↑16 ∨
                      True ∧ (x_1 &&& 127#16).smulOverflow (x &&& 127#16) = true ∨
                        True ∧ (x_1 &&& 127#16).umulOverflow (x &&& 127#16) = true →
      False

theorem R.fromTensorFinsupp_degree (q : Nat) (coeffs : List Int):
  (R.fromTensorFinsupp q coeffs).degree ≤ coeffs.length

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

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

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

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

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

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

theorem test87_proof : test87_before ⊑ test87_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 test13_proof : test13_before ⊑ test13_after

theorem land_lor_right2_proof : land_lor_right2_before ⊑ land_lor_right2_after

theorem lshrugt_01_06_thm (e : IntW 4) :
  icmp IntPred.ugt (lshr e (const? 4 1)) (const? 4 6) ⊑ icmp IntPred.ugt e (const? 4 (-3))

@[simp] theorem Valuation.ofHVector_inj (xs ys : HVector toType ts) :
    ofHVector xs = ofHVector ys ↔ xs = ys

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

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

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

theorem PR2330_thm (e : IntW 32) :
  icmp IntPred.eq (LLVM.and (shl (const? 32 1) e) (const? 32 1)) (const? 32 0) ⊑
    icmp IntPred.ne e (const? 32 0)

theorem e_1076 :
     - 6 * t + 2 * (z ||| t) - 6 *  ~~~(z &&&  ~~~t) - 1 *  ~~~(z ||| t) + 10 *  ~~~(z |||  ~~~t) - 9 * (z &&&  ~~~t) + 3 * (z &&& t) =  - 7 * (z |||  ~~~t)

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

theorem ashrslt_03_13_proof : ashrslt_03_13_before ⊑ ashrslt_03_13_after

theorem bools_logical_commute1_and2_thm.extracted_1._4 : ∀ (x x_1 : BitVec 1),
  ¬x_1 = 1#1 → x = 1#1 → 0#1 = 1#1 → False

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

theorem select_icmp_sgt_allones_smin_flipped_proof : select_icmp_sgt_allones_smin_flipped_before ⊑ select_icmp_sgt_allones_smin_flipped_after

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

theorem not_add_thm.extracted_1._1 : ∀ (x : BitVec 32), x + 123#32 ^^^ -1#32 = BitVec.ofInt 32 (-124) - x

theorem test_invalid_simplify_sub2_proof : test_invalid_simplify_sub2_before ⊑ test_invalid_simplify_sub2_after

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

theorem lshrult_03_07_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 3#4 <<< 3#4 ≠ x ∨ 3#4 ≥ ↑4) → ofBool (x >>> 3#4 <ᵤ 7#4) = 1#1

theorem test11_proof : test11_before ⊑ test11_after

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

theorem select_icmp_ne_0_and_4096_xor_32_proof : select_icmp_ne_0_and_4096_xor_32_before ⊑ select_icmp_ne_0_and_4096_xor_32_after

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

theorem t7_ugt_sgt_neg1_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.ugt (add e_2 (const? 32 16)) (const? 32 143))
      (select (icmp IntPred.sgt e_2 (const? 32 (-17))) e_1 e) e_2 ⊑
    select (icmp IntPred.sgt e_2 (const? 32 127)) e_1
      (select (icmp IntPred.slt e_2 (const? 32 (-16))) e e_2)

theorem sext_zext_apint1_thm.extracted_1._1 : ∀ (x : BitVec 77),
  signExtend 1024 (zeroExtend 533 x) = zeroExtend 1024 x

theorem 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 negate_zext_proof : negate_zext_before ⊑ negate_zext_after

theorem select_icmp_eq_and_32_0_or_8_proof : select_icmp_eq_and_32_0_or_8_before ⊑ select_icmp_eq_and_32_0_or_8_after

theorem or_not_xor_common_op_commute2_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8),
  x_2 ^^^ x_1 ||

theorem src3_thm (e e_1 : IntW 32) :
  add (LLVM.and e_1 e) (LLVM.and (LLVM.xor e (const? 32 (-1))) (LLVM.xor e_1 (const? 32 (-1)))) ⊑
    LLVM.xor (LLVM.xor e_1 e) (const? 32 (-1))

theorem test9_thm (e : IntW 32) : urem (mul e (const? 32 64)) (const? 32 32) ⊑ const? 32 0

theorem or_simplify_ugt_fail_proof : or_simplify_ugt_fail_before ⊑ or_simplify_ugt_fail_after

theorem demorgan_nor_use2ab_thm (e e_1 : IntW 8) :
  LLVM.sdiv (LLVM.sdiv (LLVM.xor (LLVM.or (LLVM.xor e_1 (const? 8 (-1))) e) (const? 8 (-1))) (mul e (const? 8 23)))
      (mul (LLVM.xor e_1 (const? 8 (-1))) (const? 8 17)) ⊑
    LLVM.sdiv (LLVM.sdiv (LLVM.and e_1 (LLVM.xor e (const? 8 (-1)))) (mul e (const? 8 23)))
      (mul (LLVM.xor e_1 (const? 8 (-1))) (const? 8 17))

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

theorem test17_proof : test17_before ⊑ test17_after

theorem slt_zero_eq_ne_0_fail1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 →
    ofBool (zeroExtend 32 (ofBool (x != 0#32)) == x.sshiftRight' 31#32) =
      ofBool (x.sshiftRight' 31#32 == zeroExtend 32 (ofBool (x != 0#32)))

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

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

theorem select_icmp_ne_0_and_1073741824_and_not_8_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ¬ofBool (0#32 != x_1 &&& 1073741824#32) = 1#1 →
    ¬ofBool (x_1 &&& 1073741824#32 == 0#32) = 1#1 → x &&& BitVec.ofInt 8 (-9) = x

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 sgt_smax4_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 + 3#32 <ₛ x) = 1#1 → ofBool (x_1 + 3#32 <ₛ x_1 + 3#32) = ofBool (x_1 + 3#32 <ₛ x)

theorem select_mul_icmp_bad_proof : select_mul_icmp_bad_before ⊑ select_mul_icmp_bad_after

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

theorem or_not_and_wrong_b_proof : or_not_and_wrong_b_before ⊑ or_not_and_wrong_b_after

theorem not_not_true_proof : not_not_true_before ⊑ not_not_true_after

theorem test_srem_canonicalize_op0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (0#32).ssubOverflow x_1 = true ∨ (x == 0 || 32 != 1 && 0#32 - x_1 == intMin 32 && x == -1) = true) →
    (x == 0 || 32 != 1 && x_1 == intMin 32 && x == -1) = true ∨ True ∧ (0#32).ssubOverflow (x_1.srem x) = true →
      False

theorem lshr_16_add_zext_basic_proof : lshr_16_add_zext_basic_before ⊑ lshr_16_add_zext_basic_after

theorem demorganize_constant2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  (x ||| 15#32) ^^^ -1#32 = x &&& BitVec.ofInt 32 (-16) ^^^ BitVec.ofInt 32 (-16)

theorem lshrult_02_12_exact_proof : lshrult_02_12_exact_before ⊑ lshrult_02_12_exact_after

theorem ule_swap_or_min_proof : ule_swap_or_min_before ⊑ ule_swap_or_min_after

theorem icmp_slt_0_and_icmp_sge_neg1_i64_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬63#64 ≥ ↑64 → x >>> 63#64 &&& zeroExtend 64 (ofBool (-1#64 ≤ₛ x)) = zeroExtend 64 (ofBool (x == -1#64))

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

theorem or_not_and_commute2_proof : or_not_and_commute2_before ⊑ or_not_and_commute2_after

theorem e_2353 :
     - 5 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 11 * ( ~~~f &&& (d ^^^ e)) + 7 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 6 *  ~~~(d ^^^ e) - 2 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) + 1 * (e ^^^  ~~~(d |||  ~~~f)) + 3 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 4 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 2 * ( ~~~f &&&  ~~~(d ^^^ e)) - 2 * (d ^^^ ( ~~~e &&& f)) - 1 * (e ^^^ f) - 2 *  ~~~( ~~~d &&& (e ||| f)) + 11 * (e |||  ~~~(d |||  ~~~f)) + 1 * (e ^^^ (d ||| (e ||| f))) - 2 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 1 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 3 * (e |||  ~~~f) + 11 *  ~~~d + 5 *  ~~~( ~~~d &&& (e ^^^ f)) + 5 * (e ^^^ ( ~~~d &&& (e ||| f))) + 5 * (d &&& e) + 1 * ((d &&& f) ^^^ (e ||| f)) - 1 * (e ^^^  ~~~(d ||| (e &&& f))) + 4 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 3 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 7 * ( ~~~e ||| (d ^^^ f)) - 5 * (e ^^^ ( ~~~d ||| (e ^^^ f))) + 7 *  ~~~(d ^^^ ( ~~~e ||| f)) - 2 * (e ^^^ (d ||| ( ~~~e &&& f))) - 2 *  ~~~(d &&& (e ||| f)) - 3 *  ~~~(d &&& ( ~~~e &&& f)) + 2 * (f &&& (d |||  ~~~e)) - 6 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 5 * (f ^^^  ~~~(d &&& (e ||| f))) - 11 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 7 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 1 * (e ^^^ (d &&&  ~~~f)) - 1 * ((d |||  ~~~e) &&& (e ^^^ f)) - 1 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 7 * (f ||| (d &&& e)) + 11 * ( ~~~d &&& (e ^^^ f)) + 5 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 11 * (d &&& f) - 6 * ( ~~~e &&&  ~~~(d ^^^ f)) + 2 * (f ^^^  ~~~(d &&&  ~~~e)) + 1 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 2 *  ~~~(e ^^^ f) + 2 * (f ^^^ (d ||| e)) - 6 *  ~~~(d &&& (e ^^^ f)) - 1 * e - 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 *  ~~~(d &&& f) + 7 * (f |||  ~~~(d ||| e)) - 7 *  ~~~(d ||| f) - 3 * (f ^^^ (d |||  ~~~e)) + 4 * (f ^^^ (d &&& ( ~~~e ||| f))) - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 6 * ((d &&& f) ||| (e &&&  ~~~f)) + 2 * (d &&&  ~~~e) - 10 *  ~~~(d ||| (e ||| f)) - 6 *  ~~~(d ||| ( ~~~e ||| f)) - 11 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 28 * ( ~~~d &&& ( ~~~e &&& f)) - 44 * ( ~~~d &&& (e &&& f)) - 20 * (d &&& ( ~~~e &&& f)) - 8 * (d &&& (e &&& f)) =  - 2 * (f ^^^ (d ||| (e ||| f))) + 14 *  ~~~( ~~~d ||| (e ||| f))

theorem xor_add_thm.extracted_1._1 : ∀ (x : BitVec 32),
  True ∧ (73#32).ssubOverflow (x &&& 31#32) = true ∨ True ∧ (73#32).usubOverflow (x &&& 31#32) = true → False

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

theorem sub_dec_proof : sub_dec_before ⊑ sub_dec_after

theorem eq_umax3_proof : eq_umax3_before ⊑ eq_umax3_after

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

omit [Fintype S] [DecidableEq S] in
lemma processOneElem_trans_preserve (st : worklist.St A S) (final : S → Bool) (a b : A) (sa : S) (s s1 s2 : State) :
    s2 ∈ st.m.tr s1 b →
    s2 ∈ (processOneElem A S final s st (a, sa)).m.tr s1 b

theorem icmp_slt_0_and_icmp_sge_neg2_i64_proof : icmp_slt_0_and_icmp_sge_neg2_i64_before ⊑ icmp_slt_0_and_icmp_sge_neg2_i64_after

theorem test9_thm (e : IntW 16) : trunc 16 (sext 32 e) ⊑ e

@[simp]
theorem toBitVec_shiftL (a : BitStream) (k : Nat) :
    (a.shiftLeft k).toBitVec w = (a.toBitVec w).shiftLeft k

theorem fold_sext_to_and_wrong3_proof : fold_sext_to_and_wrong3_before ⊑ fold_sext_to_and_wrong3_after

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

@[simp]
theorem scanOr_succ (s : BitStream) : scanOr s (n+1) = ((s.scanOr n) || s (n + 1))

theorem icmp_slt_0_or_icmp_sgt_0_i64_fail3_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬62#64 ≥ ↑64 → 62#64 ≥ ↑64 ∨ 63#64 ≥ ↑64 → False

theorem bv_820' :
    ∀ (e e_1 : LLVM.IntW 9), LLVM.udiv (LLVM.sub e (LLVM.urem e e_1)) e_1 ⊑ LLVM.udiv e e_1

theorem ashr_C1_add_A_C2_i32_thm (e : IntW 32) :
  ashr (const? 32 6) (add (LLVM.and e (const? 32 65535)) (const? 32 5)) ⊑ const? 32 0

theorem test11_proof : test11_before ⊑ test11_after

theorem mul_sel_op0_proof : mul_sel_op0_before ⊑ mul_sel_op0_after

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

theorem shl_trunc_bigger_ashr_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(12#32 ≥ ↑32 ∨ 3#24 ≥ ↑24) →
    9#32 ≥ ↑32 ∨ True ∧ signExtend 32 (truncate 24 (x.sshiftRight' 9#32)) ≠ x.sshiftRight' 9#32 → False

theorem not_or_or_and_not_and_and_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 ashrslt_03_08_exact_proof : ashrslt_03_08_exact_before ⊑ ashrslt_03_08_exact_after

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

theorem test24_logical_thm (e : IntW 32) :
  select (icmp IntPred.sgt e (const? 32 1)) (icmp IntPred.ne e (const? 32 2)) (const? 1 0) ⊑
    icmp IntPred.sgt e (const? 32 2)

theorem ne_shift_in_zeros_proof : ne_shift_in_zeros_before ⊑ ne_shift_in_zeros_after

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

@[simp] theorem Valuation.nil_append {V : Γ.Valuation} :
    HAppend.hAppend (α := Valuation no_index _) (γ := Valuation no_index _)
      (nil (Ty:=Ty)) V -- nil ++ V
    = V

theorem test2_thm.extracted_1._1 : ∀ (x : BitVec 8),
  zeroExtend 64 (zeroExtend 32 (zeroExtend 16 x)) = zeroExtend 64 x

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

theorem nonexact_ashr_ne_exactdiv_proof : nonexact_ashr_ne_exactdiv_before ⊑ nonexact_ashr_ne_exactdiv_after

theorem e_1364 :
    5 *  ~~~(z &&&  ~~~t) + 11 * (z ||| t) + 5 * (z ^^^ t) + 11 *  ~~~(z &&& t) + 4 * z + 2 *  ~~~t + 2 * t - 29 *  ~~~(z |||  ~~~t) - 28 * (z &&&  ~~~t) - 17 * (z &&& t) = 5 *  ~~~(z &&&  ~~~z) + 13 *  ~~~(z ||| t)

theorem main1_logical_proof : main1_logical_before ⊑ main1_logical_after

theorem e_1338 :
    5 * t + 11 *  ~~~(z &&&  ~~~t) - 2 *  ~~~t + 1 *  ~~~z - 11 *  ~~~(z ^^^ t) + 2 * (z ||| t) + 1 *  ~~~(z &&&  ~~~z) - 5 *  ~~~(z ||| t) - 25 *  ~~~(z |||  ~~~t) - 6 * (z &&&  ~~~t) =  - 5 *  ~~~(z &&& t) + 8 * (z &&& t)

theorem select_or_disjoint_or_proof : select_or_disjoint_or_before ⊑ select_or_disjoint_or_after

theorem test_mul_nsw__none_are_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq e (const? 32 805306368)) (const? 32 (-1342177280))
      (mul e (const? 32 9) { «nsw» := true, «nuw» := false }) ⊑
    mul e (const? 32 9)

theorem test9_logical_proof : test9_logical_before ⊑ test9_logical_after

theorem test31_proof : test31_before ⊑ test31_after

theorem test13_proof : test13_before ⊑ test13_after

theorem n2_proof : n2_before ⊑ n2_after

theorem lshrugt_02_13_exact_proof : lshrugt_02_13_exact_before ⊑ lshrugt_02_13_exact_after

theorem or_and_shift_shift_and_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(3#32 ≥ ↑32 ∨ 2#32 ≥ ↑32) →
    (x &&& 7#32) <<< 3#32 ||

theorem and_signbit_ashr_proof : and_signbit_ashr_before ⊑ and_signbit_ashr_after

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

theorem test19a_thm.extracted_1._1 : ∀ (x : BitVec 39),
  ¬2#39 ≥ ↑39 → ofBool (x.sshiftRight' 2#39 == -1#39) = ofBool (BitVec.ofInt 39 (-5) <ᵤ x)

theorem xor_signbit_select_ashr_proof : xor_signbit_select_ashr_before ⊑ xor_signbit_select_ashr_after

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

theorem R.trimTensor_trimTensor (tensor : List Int) :
  trimTensor (trimTensor tensor) = trimTensor tensor

theorem test10_thm.extracted_1._1 : ∀ (x : BitVec 16), truncate 16 (signExtend 32 x) = x

theorem lshr_pow2_ult_smin_proof : lshr_pow2_ult_smin_before ⊑ lshr_pow2_ult_smin_after

theorem icmp_slt_0_and_icmp_sge_neg1_i32_proof : icmp_slt_0_and_icmp_sge_neg1_i32_before ⊑ icmp_slt_0_and_icmp_sge_neg1_i32_after

theorem e_1745 :
    1 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 *  ~~~(b ^^^ c) + 1 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 5 * ((b &&&  ~~~c) ^^^ (a ||| (b ^^^ c))) + 11 * (c &&& (a ||| b)) - 2 * (c ^^^ (a &&& b)) + 7 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) - 6 * (b ||| (a &&& c)) + 2 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 5 * (a &&& ( ~~~b ||| c)) - 7 * (c ^^^ (a ||| b)) - 1 * (b &&&  ~~~(a &&& c)) - 1 * ( ~~~a &&& (b ||| c)) + 2 * ( ~~~a ||| (b ||| c)) + 1 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) - 1 *  ~~~b - 5 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) + 7 * (a &&&  ~~~c) + 3 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 5 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 2 * (b ^^^ (a &&& ( ~~~b ||| c))) + 5 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 2 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) + 7 * ((a &&&  ~~~b) ||| (b ^^^ c)) - 2 * (b ^^^  ~~~(a &&& (b &&& c))) + 11 * (a ||| c) - 17 *  ~~~(a ||| (b ||| c)) + 4 *  ~~~(a ||| ( ~~~b ||| c)) - 39 *  ~~~( ~~~a ||| (b ||| c)) - 18 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 17 * ( ~~~a &&& ( ~~~b &&& c)) - 11 * ( ~~~a &&& (b &&& c)) - 35 * (a &&& ( ~~~b &&& c)) - 23 * (a &&& (b &&& c)) = 6 * (b |||  ~~~(a ||| c))

theorem or_signbit_select_shl_proof : or_signbit_select_shl_before ⊑ or_signbit_select_shl_after

theorem test_and4_logical_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sge (LLVM.and e_1 (const? 32 2147483647)) e) (icmp IntPred.sge e (const? 32 0))
      (const? 1 0) ⊑
    icmp IntPred.ule e (LLVM.and e_1 (const? 32 2147483647))

theorem e_187 :
     - 2 * (x ||| y) - 7 * (x ^^^ y) + 1 *  ~~~(x ||| y) + 10 *  ~~~(x |||  ~~~y) + 10 * (x &&&  ~~~y) + 3 * (x &&& y) = 1 *  ~~~(x &&&  ~~~x)

theorem test8_thm (e e_1 : IntW 32) :
  trunc 64 (LLVM.or (shl (zext 128 e_1) (const? 128 32)) (zext 128 e)) ⊑
    LLVM.or (shl (zext 64 e_1) (const? 64 32) { «nsw» := false, «nuw» := true }) (zext 64 e)
      { «disjoint» := true }

theorem main8_logical_proof : main8_logical_before ⊑ main8_logical_after

theorem and_orn_cmp_3_logical_thm (e e_1 e_2 : IntW 72) :
  select (icmp IntPred.ugt e_2 e_1)
      (select (icmp IntPred.ule e_2 e_1) (const? 1 1) (icmp IntPred.ugt e (const? 72 42))) (const? 1 0) ⊑
    select (icmp IntPred.ugt e_2 e_1) (icmp IntPred.ugt e (const? 72 42)) (const? 1 0)

theorem bv_AndOrXor_2265 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.or (LLVM.and e e_1) (LLVM.xor e e_1) ⊑ LLVM.or e e_1

theorem select_1_thm.extracted_1._20 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1) (x_3 x_4 : BitVec 8) (x_5 : BitVec 1),
  ¬x_5 = 1#1 → ¬x_2 = 1#1 → x ^^^ 123#8 ^^^ -1#8 = x ^^^ BitVec.ofInt 8 (-124)

theorem mul_select_zext_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → 1#64 * zeroExtend 64 x_1 = 0#64

theorem test19_proof : test19_before ⊑ test19_after

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

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

theorem bitwise_and_logical_and_masked_icmp_allzeros_poison1_thm.extracted_1._3 : ∀ (x : BitVec 1)
  (x_1 x_2 : BitVec 32),
  ofBool (x_2 &&& x_1 == 0#32) = 1#1 →
    ofBool (x_2 &&& (x_1 ||| 7#32) == 0#32) = 1#1 → x &&& ofBool (x_2 &&& 7#32 == 0#32) = x

theorem scalar_i32_lshr_and_signbit_ne_proof : scalar_i32_lshr_and_signbit_ne_before ⊑ scalar_i32_lshr_and_signbit_ne_after

theorem trunc_sel_smaller_zext_proof : trunc_sel_smaller_zext_before ⊑ trunc_sel_smaller_zext_after

theorem n0_proof : n0_before ⊑ n0_after

theorem ashr_ne_exact_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x >>> 3#8 <<< 3#8 ≠ x ∨ 3#8 ≥ ↑8) → ofBool (x.sshiftRight' 3#8 != 10#8) = ofBool (x != 80#8)

theorem ashrsgt_03_15_proof : ashrsgt_03_15_before ⊑ ashrsgt_03_15_after

theorem lshrugt_01_10_exact_proof : lshrugt_01_10_exact_before ⊑ lshrugt_01_10_exact_after

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

theorem t22_sign_check2_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (-1#32 <ₛ x_1) = 1#1 → ¬ofBool (x_1 <ₛ 0#32) = 1#1 → x = 0#32

theorem lshr_or_or_no_const_proof : lshr_or_or_no_const_before ⊑ lshr_or_or_no_const_after

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

theorem bv_AndOrXor_1683_2 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.or (LLVM.icmp LLVM.IntPred.uge e e_1) (LLVM.icmp LLVM.IntPred.ne e e_1) ⊑ LLVM.const? 1 1

@[simp]
theorem R.fromPoly_kernel_eq_zero (x : (ZMod q)[X]) : R.fromPoly (n := n) (f q n * x) = 0

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

theorem substitute_constant_or_ne_uge_commute_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.uge e_1 e) (const? 1 1) (icmp IntPred.ne e_1 (const? 8 42)) ⊑
    LLVM.or (icmp IntPred.ne e_1 (const? 8 42)) (icmp IntPred.ult e (const? 8 43))

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

theorem lshr_and_and_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(2#8 ≥ ↑8 ∨ (42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true ∨ 2#8 ≥ ↑8) →
    ¬((42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true ∨ 2#8 ≥ ↑8) →
      (x_1 >>> 2#8 &&& 13#8 &&& x.srem 42#8) <<< 2#8 = x_1 &&& 52#8 &&& x.srem 42#8 <<< 2#8

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

theorem signExtend_eq (x : BitVec w) : x.signExtend w = x  := sorry

--

theorem bar_proof : bar_before ⊑ bar_after

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

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

theorem ashrsgt_03_14_proof : ashrsgt_03_14_before ⊑ ashrsgt_03_14_after

theorem test3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.ssubOverflow x = true ∨ True ∧ x_1.ssubOverflow x = true) → True ∧ x_1.ssubOverflow x = true → False

theorem demorgan_and_apint1_proof : demorgan_and_apint1_before ⊑ demorgan_and_apint1_after

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

theorem sub_ashr_or_i32_nuw_nsw_proof : sub_ashr_or_i32_nuw_nsw_before ⊑ sub_ashr_or_i32_nuw_nsw_after

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

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

theorem shift_no_xor_multiuse_xor_proof : shift_no_xor_multiuse_xor_before ⊑ shift_no_xor_multiuse_xor_after

theorem positive_biggerlshr_lshrexact_proof : positive_biggerlshr_lshrexact_before ⊑ positive_biggerlshr_lshrexact_after

theorem mul_eleven' (x : BitVec w) : 11 * x =
  (x + x + x + x + x +
   x + x + x + x + x +
   x)

theorem e_2254 :
    2 * (d ||| (e ||| f)) + 2 * (d ||| f) + 1 * (f ^^^ (d ||| (e ||| f))) + 1 * (d ||| e) - 1 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 3 * (e ^^^ (d ||| (e ||| f))) - 1 * ((d ^^^ e) |||  ~~~(d ^^^ f)) + 2 * ( ~~~f ||| (d ^^^ e)) + 2 *  ~~~( ~~~d &&& (e ||| f)) - 1 * (e ||| (d ^^^ f)) - 7 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 2 * ((d &&& e) |||  ~~~(e ^^^ f)) + 11 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 2 *  ~~~(d ||| (e &&& f)) + 3 * ((d |||  ~~~e) &&& (e ^^^ f)) + 3 * ( ~~~d ||| ( ~~~e ||| f)) - 11 * (f &&&  ~~~(d &&&  ~~~e)) + 4 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) + 5 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 7 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) - 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 5 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 3 * (f ^^^ ( ~~~d ||| (e &&& f))) - 6 * (d ^^^ ( ~~~e &&& f)) - 3 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) + 2 * ((d ||| e) &&& (e ^^^ f)) - 3 *  ~~~(d |||  ~~~e) + 11 * (f ^^^ ( ~~~d ||| (e ||| f))) - 5 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 5 *  ~~~(d &&&  ~~~d) - 1 *  ~~~(d ^^^ ( ~~~e &&& f)) - 7 * (f |||  ~~~(d ||| e)) - 2 *  ~~~( ~~~d ||| (e &&& f)) + 4 * ( ~~~f &&&  ~~~(d ^^^ e)) + 1 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 5 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 11 *  ~~~(d ||| e) + 7 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 4 * (d &&&  ~~~e) + 11 * ((d &&& f) ^^^ (e ||| f)) - 11 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 4 * (e ^^^ (d &&&  ~~~f)) - 1 * (f ^^^  ~~~(d ||| e)) - 2 * (e |||  ~~~(d |||  ~~~f)) - 2 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 11 * ( ~~~e &&&  ~~~(d ^^^ f)) + 7 * (d &&& ( ~~~e ||| f)) - 1 * ((e &&& f) ||| (d &&& (e ||| f))) + 1 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 19 *  ~~~(d ||| (e ||| f)) - 28 *  ~~~(d ||| ( ~~~e ||| f)) - 26 *  ~~~( ~~~d ||| (e ||| f)) - 35 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 8 * ( ~~~d &&& ( ~~~e &&& f)) + 1 * ( ~~~d &&& (e &&& f)) - 17 * (d &&& ( ~~~e &&& f)) + 13 * (d &&& (e &&& f)) = 1 * ((d &&& e) |||  ~~~(e |||  ~~~f))

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

theorem bools2_logical_commute2_thm.extracted_1._8 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 → x = 1#1 → x_1 = 1#1 → 1#1 = x_1

@[simp]
theorem initCarry_fsmCarry'' : (fsmCarry'' initCarry).initCarry =
    fun _ => initCarry

theorem demo (x y : BitVec 8) : (0#8 - x ||| y) + y = (y ||| 0#8 - x) + y

theorem select_icmp_ne_0_and_4096_or_32_proof : select_icmp_ne_0_and_4096_or_32_before ⊑ select_icmp_ne_0_and_4096_or_32_after

theorem trunc_sandwich_small_shift1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(19#32 ≥ ↑32 ∨ 1#12 ≥ ↑12) → 20#32 ≥ ↑32 ∨ True ∧ zeroExtend 32 (truncate 12 (x >>> 20#32)) ≠ x >>> 20#32 → False

theorem ashrsgt_03_11_exact_proof : ashrsgt_03_11_exact_before ⊑ ashrsgt_03_11_exact_after

lemma CNFA.canonicalSimul (m : CNFA n) : m.m.Simul m.toNFA {(s, s') | s = s'.val} ⊤ ∅

@[simp] theorem dropUntilHom_toCons {v : Var Γ t} :
  dropUntilHom (v := v.toCons (t' := t')) = (dropUntilHom (v:=v)).consRight

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

theorem andn_or_cmp_1_logical_proof : andn_or_cmp_1_logical_before ⊑ andn_or_cmp_1_logical_after

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

theorem reassoc_x2_add_nuw_proof : reassoc_x2_add_nuw_before ⊑ reassoc_x2_add_nuw_after

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

theorem lshrugt_03_06_proof : lshrugt_03_06_before ⊑ lshrugt_03_06_after

theorem test_shl__all_are_safe_proof : test_shl__all_are_safe_before ⊑ test_shl__all_are_safe_after

theorem test_ult_nuw_proof : test_ult_nuw_before ⊑ test_ult_nuw_after

lemma CNFA.lift_spec (m : CNFA n1) (f : Fin n1 → Fin n2) {M : NFA' n1} :
    m.Sim M → (m.lift f |>.Sim (M.lift f))

theorem positive_biggerlshr_shlnuwnsw_lshrexact_proof : positive_biggerlshr_shlnuwnsw_lshrexact_before ⊑ positive_biggerlshr_shlnuwnsw_lshrexact_after

theorem test16_thm (e : IntW 32) :
  sub (const? 64 4294967294) (zext 64 (lshr e (const? 32 1))) ⊑
    zext 64 (sub (const? 32 (-2)) (lshr e (const? 32 1)) { «nsw» := false, «nuw» := true })

theorem main7c_logical_thm.extracted_1._5 : ∀ (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 → 0#32 = zeroExtend 32 1#1

theorem test_mul__nuw_is_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 268435457)) (const? 32 268435456)) (const? 32 (-1879048192))
      (mul (LLVM.and e (const? 32 268435457)) (const? 32 9)) ⊑
    mul (LLVM.and e (const? 32 268435457)) (const? 32 9) { «nsw» := false, «nuw» := true }

theorem icmp_select_var_pred_ult_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == 0#8) = 1#1 → ¬(True ∧ x.uaddOverflow 2#8 = true) → ofBool (x <ᵤ x + 2#8) = 1#1

theorem not_or_or_and_no_and_commute3_proof : not_or_or_and_no_and_commute3_before ⊑ not_or_or_and_no_and_commute3_after

theorem test70_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x_1 <ₛ 0#8) = 1#1 → 6#8 ≥ ↑8 → False

theorem ashrslt_02_07_proof : ashrslt_02_07_before ⊑ ashrslt_02_07_after

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

theorem or_wrong_const1_proof : or_wrong_const1_before ⊑ or_wrong_const1_after

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

theorem xor_lshr_thm (e e_1 e_2 e_3 : IntW 8) :
  LLVM.xor (LLVM.xor (lshr e_3 e_2) e_1) (lshr e e_2) ⊑ LLVM.xor (lshr (LLVM.xor e_3 e) e_2) e_1

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

theorem sgt_or_not_min_proof : sgt_or_not_min_before ⊑ sgt_or_not_min_after

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

theorem invert_both_cmp_operands_sub_proof : invert_both_cmp_operands_sub_before ⊑ invert_both_cmp_operands_sub_after

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

theorem shl_nsw_add_nsw_nuw_proof : shl_nsw_add_nsw_nuw_before ⊑ shl_nsw_add_nsw_nuw_after

theorem and_signbit_select_ashr_proof : and_signbit_select_ashr_before ⊑ and_signbit_select_ashr_after

theorem icmp_ne_sext_eq_otherwise_proof : icmp_ne_sext_eq_otherwise_before ⊑ icmp_ne_sext_eq_otherwise_after

theorem trunc_shl_shl_infloop_proof : trunc_shl_shl_infloop_before ⊑ trunc_shl_shl_infloop_after

theorem ne_umin3_proof : ne_umin3_before ⊑ ne_umin3_after

theorem t0_proof : t0_before ⊑ t0_after

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

theorem lshrugt_02_15_thm.extracted_1._1 : ∀ (x : BitVec 4), ¬2#4 ≥ ↑4 → ofBool (-1#4 <ᵤ x >>> 2#4) = 0#1

theorem mismatched_shifts_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ x + 1#8 ≥ ↑8) → x ≥ ↑8 ∨ x + 1#8 ≥ ↑8 ∨ True ∧ (16#8 <<< x &&& 3#8 >>> (x + 1#8) != 0) = true → False

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

theorem alive_275_2   : alive_275_2_src ⊑ alive_275_2_tgt

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

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

theorem both_proof : both_before ⊑ both_after

theorem both_sides_fold_eq_thm (e : IntW 32) (e_1 : IntW 1) :
  icmp IntPred.eq (select e_1 (const? 32 9) e) (select e_1 (const? 32 1) e) ⊑ LLVM.xor e_1 (const? 1 1)

theorem main4_thm (e : IntW 32) :
  select
      (LLVM.and (icmp IntPred.eq (LLVM.and e (const? 32 7)) (const? 32 7))
        (icmp IntPred.eq (LLVM.and e (const? 32 48)) (const? 32 48)))
      (const? 32 0) (const? 32 1) ⊑
    zext 32 (icmp IntPred.ne (LLVM.and e (const? 32 55)) (const? 32 55))

theorem zext_sext_add_icmp_slt_1_proof : zext_sext_add_icmp_slt_1_before ⊑ zext_sext_add_icmp_slt_1_after

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

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

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

theorem fold_sext_to_and_wrong7_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x &&& BitVec.ofInt 32 (-2147483647) != 128#32) = 1#1

theorem test_sdiv_canonicalize_op0_exact_thm (e e_1 : IntW 32) :
  LLVM.sdiv (sub (const? 32 0) e_1 { «nsw» := true, «nuw» := false }) e { «exact» := true } ⊑
    sub (const? 32 0) (LLVM.sdiv e_1 e { «exact» := true }) { «nsw» := true, «nuw» := false }
</all_available_lemmas>

<local_ctx>
import Blase.AutoStructs.ForMathlib

import Blase.SingleWidth.Defs

open Fin.NatCast

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

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

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

def liftExcept2 n : Fin n → Fin (n + 2) :=
  fun k => Fin.castLE (by admit /- proof elided -/
  ) k

def liftMax1 (n m : Nat) : Fin n → Fin (max n m) :=
  fun k => k.castLE (by admit /- proof elided -/
  )

def liftMax2 (n m : Nat) : Fin m → Fin (max n m) :=
  fun k => k.castLE (by admit /- proof elided -/
  )

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

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

inductive RelationOrdering
| lt | le | gt | ge
deriving Repr, Fintype

inductive Relation
| eq
| signed (ord : RelationOrdering)
| unsigned (ord : RelationOrdering)
deriving Repr

def evalRelation (rel : Relation) {w} (bv1 bv2 : BitVec w) : Prop :=
  match rel with
  | .eq => bv1 = bv2
  | .signed .lt => bv1.slt bv2
  | .signed .le => bv1.sle  bv2
  | .signed .gt => bv2.slt bv1
  | .signed .ge => bv2.sle bv1
  | .unsigned .lt => bv1.ult bv2
  | .unsigned .le => bv1.ule bv2
  | .unsigned .gt => bv2.ult bv1
  | .unsigned .ge => bv2.ule bv1

@[simp]
def Relation.language (rel : Relation) : Set (BitVecs 2) :=
  { bvs | evalRelation rel (bvs.bvs.get 0) (bvs.bvs.get 1) }

inductive Binop
| and | or | impl | equiv
deriving Repr

def evalBinop (op : Binop) (b1 b2 : Prop) : Prop :=
  match op with
  | .and => b1 ∧ b2
  | .or => b1 ∨ b2
  | .impl => b1 → b2
  | .equiv => b1 ↔ b2

def langBinop (op : Binop) (l1 l2 : Set (BitVecs n)) : Set (BitVecs n) :=
  match op with
  | .and => l1 ∩ l2
  | .or => l1 ∪ l2
  | .impl => l1ᶜ ∪ l2
  | .equiv => (l1ᶜ ∪ l2) ∩ (l2ᶜ ∪ l1)

inductive Unop
| neg
deriving Repr

inductive Formula : Type
| width : WidthPredicate → Nat → Formula
| atom : Relation → Term → Term → Formula
| msbSet : Term → Formula
| unop : Unop → Formula → Formula
| binop : Binop → Formula → Formula → Formula
deriving Repr

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

@[simp]
def WidthPredicate.sat (wp : WidthPredicate) (w n : Nat) : Bool :=
  match wp with
  | .eq => w = n
  | .neq => w ≠ n
  | .lt => w < n
  | .le => w ≤ n
  | .gt => w > n
  | .ge => w ≥ n

@[simp]
def Formula.sat {w : Nat} (φ : Formula) (ρ : Fin φ.arity → BitVec w) : Prop :=
  match φ with
  | .width wp n => wp.sat w n
  | .atom rel t1 t2 =>
    let bv1 := t1.evalFinBV (fun n => ρ $ Fin.castLE (by admit /- proof elided -/
    ) n)
    let bv2 := t2.evalFinBV (fun n => ρ $ Fin.castLE (by admit /- proof elided -/
    ) n)
    evalRelation rel bv1 bv2
  | .unop .neg φ => ¬ φ.sat ρ
  | .binop op φ1 φ2 =>
    let b1 := φ1.sat (fun n => ρ $ Fin.castLE (by admit /- proof elided -/
    ) n)
    let b2 := φ2.sat (fun n => ρ $ Fin.castLE (by admit /- proof elided -/
    ) n)
    evalBinop op b1 b2
  | .msbSet t => (t.evalFinBV ρ).msb

@[simp]
def _root_.Set.lift (f : Fin n → Fin m) (bvs : Set (BitVecs n)) : Set (BitVecs m) :=
  BitVecs.transport f ⁻¹' bvs

@[simp]
def _root_.Set.proj (f : Fin n → Fin m) (bvs : Set (BitVecs m)) : Set (BitVecs n) :=
  BitVecs.transport f '' bvs

@[simp]
def Formula.language (φ : Formula) : Set (BitVecs φ.arity) :=
  match φ with
  | .width wp n => { bvs | wp.sat bvs.w n }
  | .atom rel t1 t2 =>
    let l1 := t1.language.lift (liftMaxSucc1 (FinEnum.card $ Fin t1.arity) (FinEnum.card $ Fin t2.arity))
    let l2 := t2.language.lift (liftMaxSucc2 (FinEnum.card $ Fin t1.arity) (FinEnum.card $ Fin t2.arity))
    let lrel := rel.language.lift $ liftLast2 (max (FinEnum.card (Fin t1.arity)) (FinEnum.card (Fin t2.arity)))
    let l := lrel ∩ l1 ∩ l2
    l.proj (liftExcept2 _)
  | .unop .neg φ => φ.languageᶜ
  | .binop op φ1 φ2 =>
    let l1 := φ1.language.lift $ liftMax1 φ1.arity φ2.arity
    let l2 := φ2.language.lift $ liftMax2 φ1.arity φ2.arity
    langBinop op l1 l2
  | .msbSet t =>
    let lmsb := langMsb.lift $ fun _ => Fin.last t.arity
    let l' := t.language ∩ lmsb
    l'.proj fun n => n.castLE (by admit /- proof elided -/
    )
</local_ctx>

<target_theorem>
lemma formula_language_case_atom :
    let φ :=
</target_theorem>

