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>
DecidableEq in Init.Prelude
Lean.ToExpr in Lean.ToExpr
List in Init.Prelude
Repr in Init.Data.Repr
Nat in Init.Prelude
String in Init.Prelude
Fin in Init.Prelude
List.ofFn in Init.Data.List.OfFn
Subtype in Init.Prelude
Option in Init.Prelude
List.length in Init.Prelude

structure Ctxt (Ty : Type) : Type where
  ofList :: toList : List Ty
  
  deriving Repr, Lean.ToExpr, DecidableEq

@[grind=]
def length (Γ : Ctxt Ty) : Nat := Γ.toList.length

inductive Ty (q : Nat) (n : Nat)
  | index : Ty q n
  | integer : Ty q n
  | tensor : Ty q n
  | polynomialLike : Ty q n
  deriving DecidableEq, Repr

def Hom.append {ζ : Ctxt Ty} (f : Γ.Hom Δ) : Hom (ζ ++ Γ) (ζ ++ Δ) :=
  fun _ => Var.appendCases
    (fun v => v.appendInl)
    (fun v => (f v).appendInr)

@[elab_as_elim]
def appendCases
    {motive : (Γ ++ Δ).Var t → Sort u}
    (left : (v : Var Γ t) → motive (appendInl v))
    (right : (v : Var Δ t) → motive (appendInr v)) :
    (v : (Γ ++ Δ).Var t) → motive v
  | ⟨idx, h⟩ =>
    if hv : idx < Γ.length then
      left ⟨idx, by admit /- proof elided -/
      ⟩
    else
      let v' : Var _ _ := ⟨idx - Γ.length, by admit /- proof elided -/
      ⟩
      have eq : v'.appendInr = ⟨idx, h⟩ := by admit /- proof elided -/

def appendInl (v : Γ.Var t) : (Γ ++ Δ).Var t :=
  ⟨v.val, by admit /- proof elided -/
  ⟩

def Var (Γ : Ctxt Ty) (t : Ty) : Type :=
  { i : Nat // Γ[i]? = some t }

def toHom (d : Diff Γ₁ Γ₂) : Hom Γ₁ Γ₂ :=
  fun _ v => ⟨v.val + d.val, d.property v.property⟩

abbrev Hom (Γ Γ' : Ctxt Ty) := ⦃t : Ty⦄ → Γ.Var t → Γ'.Var t

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

@[simp]
abbrev Diff.Valid (Γ₁ Γ₂ : Ctxt Ty) (d : Nat) : Prop :=
  ∀ {i t}, Γ₁[i]? = some t → Γ₂[i+d]? = some t

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 PR2539_A_after := [llvm|
{
^0(%arg1 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg1, %0 : i1
  "llvm.return"(%1) : (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 ne_irregular_bit_widths_before := [llvm|
{
^0(%arg62 : i31, %arg63 : i31):
  %0 = llvm.mlir.constant(7 : i31) : i31
  %1 = llvm.mlir.constant(13 : i31) : i31
  %2 = llvm.lshr %arg62, %0 : i31
  %3 = llvm.trunc %2 : i31 to i6
  %4 = llvm.lshr %arg62, %1 : i31
  %5 = llvm.trunc %4 : i31 to i5
  %6 = llvm.lshr %arg63, %0 : i31
  %7 = llvm.trunc %6 : i31 to i6
  %8 = llvm.lshr %arg63, %1 : i31
  %9 = llvm.trunc %8 : i31 to i5
  %10 = llvm.icmp "ne" %3, %7 : i6
  %11 = llvm.icmp "ne" %5, %9 : i5
  %12 = llvm.or %11, %10 : i1
  "llvm.return"(%12) : (i1) -> ()
}
]

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

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

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

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

def sext_diff_i1_xor_sub_1_after := [llvm|
{
^0(%arg12 : i64, %arg13 : i1, %arg14 : i1):
  %0 = llvm.sext %arg13 : i1 to i64
  %1 = llvm.zext %arg14 : i1 to i64
  %2 = llvm.add %1, %0 overflow<nsw> : i64
  "llvm.return"(%2) : (i64) -> ()
}
]

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

BitVec.abs in Init.Data.BitVec.Basic

def sdiv6_before := [llvm|
{
^0(%arg34 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(-3 : i32) : i32
  %2 = llvm.sdiv exact %arg34, %0 : i32
  %3 = llvm.mul %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

def p_after := [llvm|
{
^0(%arg73 : i32, %arg74 : i32, %arg75 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg75, %0 : i32
  %2 = llvm.or %arg73, %1 : i32
  %3 = llvm.or %arg74, %arg75 : i32
  %4 = llvm.and %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 positive_samevar_ashrexact_before := [llvm|
{
^0(%arg42 : i8, %arg43 : i8):
  %0 = llvm.ashr exact %arg42, %arg43 : i8
  %1 = llvm.shl %0, %arg43 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

def different_size_zext_zext_eq_after := [llvm|
{
^0(%arg22 : i4, %arg23 : i7):
  %0 = llvm.zext %arg22 : i4 to i7
  %1 = llvm.icmp "eq" %arg23, %0 : i7
  "llvm.return"(%1) : (i1) -> ()
}
]

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 icmp {w : Nat} (c : IntPred) (x y : IntW w) : IntW 1 := do
  let x' ← x
  let y' ← y
  icmp? c x' y'

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

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

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

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

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

def sdiv_shl_pair1_before := [llvm|
{
^0(%arg43 : i32, %arg44 : i32, %arg45 : i32):
  %0 = llvm.shl %arg43, %arg44 overflow<nsw> : i32
  %1 = llvm.shl %arg43, %arg45 overflow<nsw,nuw> : i32
  %2 = llvm.sdiv %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def positive (expr: GenBVExpr w) (widthId : Nat) : BoolExpr GenBVPred :=
  let shiftDistance : GenBVExpr w :=  subtract (GenBVExpr.var widthId) (one w)
  let signVal := GenBVExpr.shiftLeft (one w) shiftDistance
  .literal <| GenBVPred.bin expr BVBinPred.ult signVal 

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

@[simp_denote]
def add_hi_and_lo_negone_llvm_i64 := [LV| {
    ^entry (%arg: i64):
    %1 = llvm.mlir.constant (-1) : i64
    %0 = llvm.add %arg, %1 overflow<nsw> : i64
    llvm.return %0 : i64
  }]

def lshr_32_add_known_32_leading_zeroes_before := [llvm|
{
^0(%arg15 : i64, %arg16 : i64):
  %0 = llvm.mlir.constant(4294967295) : i64
  %1 = llvm.mlir.constant(32) : i64
  %2 = llvm.and %arg15, %0 : i64
  %3 = llvm.and %arg16, %0 : i64
  %4 = llvm.add %2, %3 : i64
  %5 = llvm.lshr %4, %1 : i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

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

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

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

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

def shl_add_nsw_nuw_after := [llvm|
{
^0(%arg23 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  "llvm.return"(%0) : (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 xor_with_or_disjoint_ab_before := [llvm|
{
^0(%arg26 : i32, %arg27 : i32):
  %0 = llvm.or disjoint %arg26, %arg27 : i32
  %1 = llvm.xor %arg26, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

def n0_after := [llvm|
{
^0(%arg4 : i8, %arg5 : i8, %arg6 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.shl %0, %arg5 overflow<nsw> : i8
  %2 = llvm.xor %1, %0 : i8
  %3 = llvm.and %arg4, %2 : i8
  %4 = llvm.icmp "eq" %3, %arg6 : i8
  "llvm.return"(%4) : (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 test_before := [llvm|
{
^0(%arg0 : i26):
  %0 = llvm.mlir.constant(2885 : i26) : i26
  %1 = llvm.mlir.constant(2884 : i26) : i26
  %2 = llvm.mul %arg0, %0 : i26
  %3 = llvm.mul %arg0, %1 : i26
  %4 = llvm.sub %2, %3 : i26
  "llvm.return"(%4) : (i26) -> ()
}
]

def sll_negative_constant_lhs_i32_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := sll_negative_constant_lhs_llvm_i32
  rhs := sll_negative_constant_lhs_riscv_i32

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

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

def test_sub_sub_lhs_rhs_lhs_LHS := [mod_arith q, hq| {
  ^bb0(%a : !R, %b : !R):
    %sub = mod_arith.sub %a, %b : !R
    %sub2 = mod_arith.sub %sub, %a : !R
    return %sub2 : !R
}]

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

def ashr_mul_sign_bits_after := [llvm|
{
^0(%arg101 : i8, %arg102 : i8):
  %0 = llvm.mlir.constant(3 : i16) : i16
  %1 = llvm.sext %arg101 : i8 to i16
  %2 = llvm.sext %arg102 : i8 to i16
  %3 = llvm.mul %1, %2 overflow<nsw> : i16
  %4 = llvm.ashr %3, %0 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

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

def or_simplify_ult_before := [llvm|
{
^0(%arg9 : i8, %arg10 : i8):
  %0 = llvm.mlir.constant(36 : i8) : i8
  %1 = llvm.mlir.constant(-5 : i8) : i8
  %2 = llvm.or %arg9, %0 : i8
  %3 = llvm.and %arg10, %1 : i8
  %4 = llvm.or %2, %3 : i8
  %5 = llvm.icmp "ult" %3, %4 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

def ult_and_not_max_commute_after := [llvm|
{
^0(%arg106 : i8, %arg107 : i8):
  %0 = llvm.icmp "ult" %arg106, %arg107 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

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

def a_before := [llvm|
{
^0(%arg48 : i1, %arg49 : i1):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.zext %arg48 : i1 to i32
  %3 = llvm.zext %arg49 : i1 to i32
  %4 = llvm.sub %0, %3 : i32
  %5 = llvm.add %2, %1 : i32
  %6 = llvm.add %5, %4 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

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

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

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

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

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

instance [inst : Monad d.m] : Monad (Scf d).m := inst

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

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

def t14_x_is_one_before := [llvm|
{
^0(%arg6 : i32, %arg7 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(-16 : i32) : i32
  %2 = llvm.mlir.constant(1) : i64
  %3 = llvm.mlir.constant(0 : i32) : i32
  %4 = llvm.sub %0, %arg7 : i32
  %5 = llvm.shl %arg6, %4 : i32
  %6 = llvm.add %arg7, %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 test9_after := [llvm|
{
^0(%arg72 : i32):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.trunc %arg72 : i32 to i8
  %2 = llvm.and %1, %0 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

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

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

def PR1817_2_before := [llvm|
{
^0(%arg372 : i32):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.icmp "slt" %arg372, %0 : i32
  %2 = llvm.icmp "ult" %arg372, %0 : i32
  %3 = llvm.or %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def val2 : DCOp.ValueStream (BitVec 8) := ofList [some 5, some 0, some 2, some 3, none]

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

def ZMod.toInt (x : ZMod q) : Int := ZMod.cast x

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

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

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

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

example : productsList [["a"], ["x", "y", "z"]] = [["a", "x"], ["a", "y"], ["a", "z"]] := rfl
example : productsList [["a"], ["p", "q"], ["x", "y", "z"]] =
  [["a", "p", "x"], ["a", "p", "y"], ["a", "p", "z"],
   ["a", "q", "x"], ["a", "q", "y"], ["a", "q", "z"]] := rfl

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

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

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

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

def test20_after := [llvm|
{
^0(%arg11 : i13):
  %0 = llvm.mlir.constant(false) : i1
  "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 ashrslt_03_07_before := [llvm|
{
^0(%arg230 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(7 : i4) : i4
  %2 = llvm.ashr %arg230, %0 : i4
  %3 = llvm.icmp "slt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def test22_after := [llvm|
{
^0(%arg189 : i1):
  %0 = llvm.zext %arg189 : i1 to i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def andn_or_cmp_1_logical_after := [llvm|
{
^0(%arg173 : i37, %arg174 : i37, %arg175 : i37):
  %0 = llvm.mlir.constant(42 : i37) : i37
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "sle" %arg173, %arg174 : i37
  %3 = llvm.icmp "ugt" %arg175, %0 : i37
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

def sle_swap_or_min_after := [llvm|
{
^0(%arg150 : i8, %arg151 : i8):
  %0 = llvm.icmp "sge" %arg151, %arg150 : i8
  "llvm.return"(%0) : (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 shrink_or_after := [llvm|
{
^0(%arg11 : i6):
  %0 = llvm.mlir.constant(1 : i3) : i3
  %1 = llvm.trunc %arg11 : i6 to i3
  %2 = llvm.or %1, %0 : i3
  "llvm.return"(%2) : (i3) -> ()
}
]

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

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

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

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

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

inductive Ty
  | int
   
  | int2
  deriving DecidableEq, Lean.ToExpr

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

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

def select_icmp_x_and_2147483648_ne_0_or_2147483648_after := [llvm|
{
^0(%arg168 : i32):
  %0 = llvm.mlir.constant(-2147483648 : i32) : i32
  %1 = llvm.or %arg168, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def pr40493_neg1_after := [llvm|
{
^0(%arg17 : i32):
  %0 = llvm.mlir.constant(3 : 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) -> ()
}
]

@[match_pattern] def or (w : Width φ)
  (DisjointFlag : DisjointFlag := {disjoint := false} ) : MOp φ
    := .binary w (.or DisjointFlag )

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

def mkExpr (Γ : Ctxt _) (opStx : MLIR.AST.Op 0) :
    MLIR.AST.ReaderM (Handshake) (Σ eff ty, Expr (Handshake) Γ eff ty) := do
  match opStx.name with
  | op@"handshake.branch" | op@"handshake.merge" =>
    match opStx.args with
    | v₁Stx::v₂Stx::[] =>
      let ⟨ty₁, v₁⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₁Stx
      let ⟨ty₂, v₂⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₂Stx
      match ty₁, ty₂, op with
      | .stream r₁, .stream (.bitvec 1), "handshake.branch" => return ⟨_, [.stream2 r₁], @branch r₁ _ v₁ v₂⟩
      
      | .stream r₁, _, "handshake.merge" => return ⟨_, [.stream r₁], merge v₁ v₁⟩
      | _, _, _ => throw <| .generic s!"type mismatch"
    | _ => throw <| .generic s!"expected two operands for `monomial`, found #'{opStx.args.length}' in '{repr opStx.args}'"
  | op@"handshake.fst" | op@"handshake.snd" =>
    match opStx.args with
    | v₁Stx::[] =>
      let ⟨ty₁, v₁⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₁Stx
      match ty₁, op with
      | .stream2 r, "handshake.fst" => return ⟨_, [.stream r], fst v₁⟩
      | .stream2 r, "handshake.snd"  => return ⟨_, [.stream r], snd v₁⟩
      | _, _ => throw <| .generic s!"type mismatch"
    | _ => throw <| .generic s!"expected two operands for `monomial`, found #'{opStx.args.length}' in '{repr opStx.args}'"
  | op@"handshake.not" =>
    match opStx.args with
    | v₁Stx::[] =>
      let ⟨ty₁, v₁⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₁Stx
      match ty₁, op with
      | .stream (.bitvec 1), "handshake.not" => return ⟨_, [.stream (.bitvec 1)], not v₁⟩
      | _, _ => throw <| .generic s!"type mismatch"
    | _ => throw <| .generic s!"expected one operand for `monomial`, found #'{opStx.args.length}' in '{repr opStx.args}'"
  | op@"handshake.supp" =>
    match opStx.args with
    | v₁Stx::v₂Stx::[] =>
      let ⟨ty₁, v₁⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₁Stx
      let ⟨ty₂, v₂⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₂Stx
      match ty₁, ty₂, op with
      | .stream r, .stream (.bitvec 1), "handshake.supp" => return ⟨_, [.stream r], supp v₁ v₂⟩
      | _, _, _ => throw <| .generic s!"type mismatch"
    | _ => throw <| .generic s!"expected one operand for `monomial`, found #'{opStx.args.length}' in '{repr opStx.args}'"
  | op@"handshake.sync" =>
    match opStx.args with
    | v₁Stx::v₂Stx::[] =>
      let ⟨ty₁, v₁⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₁Stx
      let ⟨ty₂, v₂⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₂Stx
      match ty₁, ty₂, op with
      | .stream r₁, .stream r₂, "handshake.sync" =>
        if h : r₁ = r₂ then
          have h': Γ.Var (Ty.stream r₁) = Γ.Var (Ty.stream r₂) := by admit /- proof elided -/

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 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 p2 : PeepholeRewrite SimpleReg [int] [int] :=
  { lhs := lhs, rhs := rhs, correct := by admit /- proof elided -/

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

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

RV64.sub in RISCV.Instructions

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

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

def 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 eq_mul_constants_with_tz_after := [llvm|
{
^0(%arg100 : i32, %arg101 : i32):
  %0 = llvm.mlir.constant(1073741823 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.xor %arg100, %arg101 : i32
  %3 = llvm.and %2, %0 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

Lean.ReducibilityStatus.reducible in Lean.ReducibilityAttrs

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

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

def sgt_or_not_min_before := [llvm|
{
^0(%arg30 : i8, %arg31 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.icmp "sgt" %arg30, %arg31 : i8
  %2 = llvm.icmp "ne" %arg30, %0 : i8
  %3 = llvm.or %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

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

def rewriteAt
    (lhs rhs : Com d Γ₁ .pure ts₁)
    (hlhs : ∀ t (v : Var Γ₁ t), ⟨t, v⟩ ∈ lhs.vars)
    (pos : ℕ) (target : Com d Γ₂ eff t₂) :
    Option (Com d Γ₂ eff t₂) := do
  let splitRes ← splitProgramAt pos target
  if h : ts₁ = splitRes.midTypes then
    let m ← matchArgRes splitRes.top lhs.toLets splitRes.midRet (h ▸ lhs.returnVars)
    let m := m.toHom <| by
      subst h; exact hlhs
    let rhs := rhs.changeVars m
    let zip := splitRes.insertPureCom splitRes.midRet (cast (by admit /- proof elided -/
    ) rhs)
    return zip.toCom
  else none

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

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

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

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

def n0_before := [llvm|
{
^0(%arg9 : i8, %arg10 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.shl %0, %arg10 : i8
  %3 = llvm.xor %2, %1 : i8
  %4 = llvm.icmp "uge" %3, %arg9 : i8
  "llvm.return"(%4) : (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 llvm_add_lower_riscv_nuw_flag_16 : LLVMPeepholeRewriteRefine 16 [Ty.llvm (.bitvec 16), Ty.llvm (.bitvec 16)] where
  lhs:= add_llvm_nuw_flags_16
  rhs:= add_riscv_16

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

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

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

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

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 AttrDict.find_nat {φ} (attrs : AttrDict φ) (name : String) : Option Nat :=
  match attrs.find name with
  | .some (AttrValue.nat i) =>  .some i
  | _ => .none

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

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

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

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

@[simp_denote]
def constLLVM0_1bit : Com LLVMPlusRiscV ⟨[]⟩ .pure (.llvm (.bitvec 1)) := [LV| {
  ^entry ():
    %1 = llvm.mlir.constant (0) : i1
    llvm.return %1 : i1
  }]

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

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

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

    |

def foo_before := [llvm|
{
^0(%arg113 : i32, %arg114 : i32, %arg115 : i32, %arg116 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.icmp "slt" %arg113, %arg114 : i32
  %2 = llvm.sext %1 : i1 to i32
  %3 = llvm.and %arg115, %2 : i32
  %4 = llvm.xor %2, %0 : i32
  %5 = llvm.and %arg116, %4 : i32
  %6 = llvm.or %3, %5 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def lshrugt_02_02_after := [llvm|
{
^0(%arg397 : i4):
  %0 = llvm.mlir.constant(-5 : i4) : i4
  %1 = llvm.icmp "ugt" %arg397, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

def mux (x : BitVec w) (y : BitVec w) (cond : BitVec 1) : BitVec w :=
  if cond.msb then x else y

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

def coeWidth {m n : Nat} : BitVec m → BitVec n
  | x => BitVec.ofNat n x.toNat

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

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

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

inductive FpPredicate where
 
| bin (lhs : FpExpr e) (op : FpBinaryPredKind) (rhs : FpExpr e)
deriving Hashable, DecidableEq, Repr, BEq

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

def select_riscv_select_llvm_32 : LLVMPeepholeRewriteRefine 32
  [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 1)] where
  lhs := select_llvm_32
  rhs := select_riscv_32

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

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

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

def 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 NFA'.autUnsignedCmp (cmp: RelationOrdering) : NFA' 2 :=
  ⟨_, NFA.autUnsignedCmp cmp⟩

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

def 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 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 fold_select_trunc_nsw_false_after := [llvm|
{
^0(%arg4 : i8, %arg5 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.trunc %arg4 overflow<nsw> : i8 to i1
  %2 = "llvm.select"(%1, %arg5, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def shl_nsw_nuw_before := [llvm|
{
^0(%arg4 : i1, %arg5 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(7 : i8) : i8
  %2 = "llvm.select"(%arg4, %0, %arg5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %3 = llvm.shl %1, %2 overflow<nsw,nuw> : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

instance : DialectToExpr HSxComb where
  toExprM := .const ``Id [0]
  toExprDialect := .const ``HSxComb []

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

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

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

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

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

def negative_not_next_power_of_two_before := [llvm|
{
^0(%arg5 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(64 : i32) : i32
  %2 = llvm.mlir.constant(256 : i32) : i32
  %3 = llvm.icmp "sgt" %arg5, %0 : i32
  %4 = llvm.add %arg5, %1 : i32
  %5 = llvm.icmp "ult" %4, %2 : i32
  %6 = llvm.and %3, %5 : i1
  "llvm.return"(%6) : (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 test9a_before := [llvm|
{
^0(%arg297 : i32):
  %0 = llvm.mlir.constant(-2147483648 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg297, %0 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

def parseRegionFromFile (fileName : String)
    (regionParseFun : MLIR.AST.Region 0 → Except ParseError α) : IO (Option α)  := do
  let ast ← runParser regionParser fileName
  match Option.map regionParseFun ast with
  | .some (.ok res) => return res
  | .some (.error msg) => throw <| IO.userError s!"Error parsing {fileName}:\n{msg}"; return none
  | .none => return none

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

def ripple_nsw6_before := [llvm|
{
^0(%arg13 : i16, %arg14 : i16):
  %0 = llvm.mlir.constant(-21845 : i16) : i16
  %1 = llvm.mlir.constant(-10923 : i16) : i16
  %2 = llvm.or %arg14, %0 : i16
  %3 = llvm.or %arg13, %1 : i16
  %4 = llvm.add %3, %2 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

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

structure Item where
 name : String
 tac : Syntax

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

@[simp] abbrev FlatCom.denote [DialectDenote d]
    (flatCom : FlatCom d Γ eff Γ_out ts)
    (V : Γ.Valuation) : eff.toMonad d.m (HVector toType ts) :=
  flatCom.lets.denote V >>= (return flatCom.rets.map ·)

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

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

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

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

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

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

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

@[simps]
def lift (M: NFA (BitVec n1) σ) (f : Fin n1 → Fin n2) : NFA (BitVec n2) σ where
  start := M.start
  accept := M.accept
  step q a := M.step q (a.transport f)

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

def shrink (origExpr : ParsedFpLogicalExpr) (targetWidth : Nat) : MetaM ParsedFpLogicalExpr := do
  let lhs ← shrinkParsedFpExpr origExpr.lhs targetWidth
  let rhs ← shrinkParsedFpExpr origExpr.rhs targetWidth

  if h :  targetWidth = lhs.width ∧ lhs.width = rhs.width then
    let rhsExpr := h.right ▸ rhs.bvExpr

    let mut displayNameToShrinkedVar : Std.HashMap Name HydraVariable := Std.HashMap.emptyWithCapacity
    let mut inputVarIdToShrinkedVar : Std.HashMap Nat HydraVariable := Std.HashMap.emptyWithCapacity
    let mut symVarIdToShrinkedVar : Std.HashMap Nat HydraVariable := Std.HashMap.emptyWithCapacity

    for (name, var) in origExpr.state.displayNameToVariable do
      let mut resultWidth := 1

      if var.width != 1 then
        resultWidth := (var.width * targetWidth) / origExpr.lhs.width

      let var := {name := name, width := resultWidth, id := var.id}
      displayNameToShrinkedVar := displayNameToShrinkedVar.insert name var

      if origExpr.state.inputVarIdToVariable.contains var.id then
        inputVarIdToShrinkedVar := inputVarIdToShrinkedVar.insert var.id var

      if origExpr.state.symVarIdToVariable.contains var.id then
        symVarIdToShrinkedVar := symVarIdToShrinkedVar.insert var.id var

    let bvLogicalExpr := BoolExpr.literal (FpPredicate.bin lhs.bvExpr .eq rhsExpr)

    let shrinkedState := {origExpr.state with displayNameToVariable := displayNameToShrinkedVar, symVarIdToVariable := symVarIdToShrinkedVar, inputVarIdToVariable := inputVarIdToShrinkedVar}
    return {origExpr with lhs := lhs, rhs := rhs, logicalExpr := bvLogicalExpr, state := shrinkedState}
  throwError m! "Expected lhsWidth:{lhs.width} and rhsWidth:{rhs.width} to equal targetWidth:{targetWidth}"

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

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

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

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

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

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

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

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

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

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

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

def foo_before := [llvm|
{
^0(%arg8 : i16):
  %0 = llvm.mlir.constant(255 : i16) : i16
  %1 = llvm.mlir.constant(255 : i32) : i32
  %2 = llvm.and %arg8, %0 : i16
  %3 = llvm.zext %2 : i16 to i32
  %4 = llvm.icmp "ult" %3, %1 : i32
  %5 = "llvm.select"(%4, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %6 = llvm.trunc %5 : i32 to i16
  %7 = llvm.and %6, %0 : i16
  "llvm.return"(%7) : (i16) -> ()
}
]

def map (f : Ty₁ → Ty₂) : Ctxt Ty₁ → Ctxt Ty₂ :=
  ofList ∘ (List.map f) ∘ toList

def not_ashr_not_before := [llvm|
{
^0(%arg139 : i32, %arg140 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg139, %0 : i32
  %2 = llvm.ashr %1, %arg140 : i32
  %3 = llvm.xor %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

Quotient.mk in Init.Core

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

def lshr_sext_i1_to_i128_after := [llvm|
{
^0(%arg53 : i1):
  %0 = llvm.mlir.constant(77371252455336267181195263 : i128) : i128
  %1 = llvm.mlir.constant(0 : i128) : i128
  %2 = "llvm.select"(%arg53, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i128, i128) -> i128
  "llvm.return"(%2) : (i128) -> ()
}
]

Array.back? in Init.Data.Array.Basic

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

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

Valuation in Mathlib.RingTheory.Valuation.Basic

def trunc_unsigned_nuw_before := [llvm|
{
^0(%arg60 : i16, %arg61 : i16):
  %0 = llvm.trunc %arg60 overflow<nuw> : i16 to i8
  %1 = llvm.trunc %arg61 overflow<nuw> : i16 to i8
  %2 = llvm.icmp "ult" %0, %1 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

def urem_i8_before := [llvm|
{
^0(%arg33 : i8, %arg34 : i8):
  %0 = llvm.zext %arg33 : i8 to i32
  %1 = llvm.zext %arg34 : i8 to i32
  %2 = llvm.urem %0, %1 : i32
  %3 = llvm.trunc %2 : i32 to i8
  "llvm.return"(%3) : (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) -> ()
}
]

BitVec.truncate in Init.Data.BitVec.Basic

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 shl_nuw_eq_0_before := [llvm|
{
^0(%arg34 : i8, %arg35 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.shl %arg34, %arg35 overflow<nuw> : i8
  %2 = llvm.icmp "eq" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

instance instTransformTy : AST.TransformTy (Comb) 0 := { mkTy }

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

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

Lean.Expr.int? in Lean.Expr

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 Op.empty {φ} (name : String) : Op φ := Op.mk name [] [] [] AttrDict.empty

def llvm_const_lower_riscv_li_27 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_27, rhs:= liRiscv_27,
   correct := by admit /- proof elided -/

def no_shift_xor_multiuse_cmp_and_before := [llvm|
{
^0(%arg40 : i32, %arg41 : i32, %arg42 : i32, %arg43 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(-4097 : i32) : i32
  %3 = llvm.and %arg40, %0 : i32
  %4 = llvm.icmp "ne" %1, %3 : i32
  %5 = llvm.and %arg41, %2 : i32
  %6 = "llvm.select"(%4, %arg41, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg42, %arg43) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %8 = llvm.mul %6, %7 : i32
  %9 = llvm.mul %8, %5 : i32
  "llvm.return"(%9) : (i32) -> ()
}
]

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

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

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

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

def 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 llvm_const_lower_riscv_li46 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM46, rhs:= liRiscv46,
   correct := by admit /- proof elided -/

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 sgt_and_not_min_after := [llvm|
{
^0(%arg94 : i8, %arg95 : i8):
  %0 = llvm.icmp "sgt" %arg94, %arg95 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

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

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

inductive Scf.Op (Op' Ty' : Type) (m') [TyDenote Ty'] [DialectSignature ⟨Op', Ty', m'⟩]
    [DialectDenote ⟨Op', Ty', m'⟩] : Type _
  | coe (o : Op')
  | iterate (k : ℕ) 
  | run (inputty : Ty')  
  | if (inputty retty' : Ty')  
  | for (ty : Ty')
  deriving DecidableEq, Repr

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

def State.cseCom {α}
  {lets : Lets d Γstart .pure Γ}
  (s : State d lets)
  (com: Com d Γ .pure α) :
  { com' : Com d Γ .pure α
    // ∀ (V : Ctxt.Valuation Γstart), com.denote (lets.denote V) = com'.denote (lets.denote V) } :=
  match com with
  | .rets vs =>
      let ⟨vs', hvs'⟩ := s.vars2vars vs
      ⟨.rets vs', by admit /- proof elided -/
        ⟩
  | .var e body =>
      let ⟨⟨e', he'⟩, v'?⟩ := s.cseExpr e
      match v'? with
      | .none =>  
        let s' := s.consNewExpr2Cache (e := e')
         
        let ⟨body', hbody'⟩ := s'.cseCom body
        ⟨.var e' body',  by admit /- proof elided -/
            ⟩
      | .some ⟨v', hv'⟩ =>
        let s' := s.consOldExpr2Cache (enew := e') (eold := e) (henew := by admit /- proof elided -/
        )
          (vold := v') (hv := by admit /- proof elided -/
          )
          
        let ⟨body', hbody'⟩ := s'.cseCom body
        
        ⟨.var e body' 
        , by admit /- proof elided -/
        ⟩

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

structure GlobalState where
  alloc : AllocState
  mem : MemoryState

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

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

BitVec.add in Init.Data.BitVec.BasicAux

def and_ne_with_one_bit_diff_constants3_before := [llvm|
{
^0(%arg356 : i8):
  %0 = llvm.mlir.constant(65 : i8) : i8
  %1 = llvm.mlir.constant(-63 : i8) : i8
  %2 = llvm.icmp "ne" %arg356, %0 : i8
  %3 = llvm.icmp "ne" %arg356, %1 : i8
  %4 = llvm.and %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def neg_not_signbit3_after := [llvm|
{
^0(%arg3 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.ashr %arg3, %0 : i8
  %3 = llvm.zext %2 : i8 to i32
  %4 = llvm.sub %1, %3 overflow<nsw> : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

Equiv in Mathlib.Logic.Equiv.Defs

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

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

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

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

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

private partial def varToIndex (e : Expr) : Option Nat :=
  match_expr e with
  | Var.mk _Ty _Γ _t i _hi      => Expr.numeral? i
  | Subtype.mk _α _p i _hi      => Expr.numeral? i
  | Var.last _Ty _Γ _t          => some 0
  | Var.toCons _Ty _Γ _t _t' v  => (· + 1) <$> varToIndex v
  | _                           => none

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

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

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

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

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

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

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

  return none

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

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

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

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

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

def balancedBracketsFnEntry (ctx: ParserContext) (s: ParserState): ParserState :=
  if ctx.get s.pos == '<'
  then balancedBracketsFnAux
   (startPos := s.pos)
   (i := s.pos)
   (bs := [])
   ctx s
  else s.mkError "Expected '<'"

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

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

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

def sub_to_and_after := [llvm|
{
^0(%arg14 : i32, %arg15 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.and %arg14, %arg15 : i32
  %2 = llvm.sub %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def or_simplify_ule_before := [llvm|
{
^0(%arg18 : i8, %arg19 : i8, %arg20 : i1):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(-2 : i8) : i8
  %2 = llvm.or %arg18, %0 : i8
  %3 = llvm.and %arg19, %1 : i8
  %4 = llvm.or %2, %3 : i8
  %5 = llvm.icmp "ule" %4, %3 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

def canonicalize_icmp_sge_5 : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant 5 : i64
      %1 = llvm.icmp.sge %c, %x : i64
      llvm.return %1 : i1
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant 5 : i64
      %1 = llvm.icmp.sle %x, %c : i64
      llvm.return %1 : 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 narrow_source_matching_signbits_before := [llvm|
{
^0(%arg7 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.and %arg7, %0 : i32
  %3 = llvm.shl %1, %2 overflow<nsw> : i32
  %4 = llvm.trunc %3 : i32 to i8
  %5 = llvm.sext %4 : i8 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

def and_ne_with_one_bit_diff_constants2_after := [llvm|
{
^0(%arg360 : i19):
  %0 = llvm.mlir.constant(-129 : i19) : i19
  %1 = llvm.mlir.constant(65 : i19) : i19
  %2 = llvm.and %arg360, %0 : i19
  %3 = llvm.icmp "ne" %2, %1 : i19
  "llvm.return"(%3) : (i1) -> ()
}
]

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

@[simp_denote]
def icmp_ne_riscv_32_pseudo := [LV| {
  ^entry (%lhs: i32, %rhs: i32):
    %lhsr = "builtin.unrealized_conversion_cast"(%lhs) : (i32) -> (!riscv.reg)
    %rhsr = "builtin.unrealized_conversion_cast"(%rhs) : (i32) -> (!riscv.reg)
    %0 = xor    %lhsr, %rhsr : !riscv.reg
    %1 = snez    %0 : !riscv.reg
    %2 = "builtin.unrealized_conversion_cast"(%1) : (!riscv.reg) -> (i1)
    llvm.return %2 : i1
  }]

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

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

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

def passriscv64 (fileName : String) : IO UInt32 := do
    let icom? ← Com.parseFromFile LLVMPlusRiscV fileName
    match icom? with
    | none => return 1
    | some (Sigma.mk _Γ ⟨eff, ⟨retTy, c⟩⟩) =>
      match eff with
      | EffectKind.pure =>
        match retTy with
        | [Ty.llvm (.bitvec _w)]  =>
           
          let lowered := selectionPipeFuelWithCSE 150 c true

          IO.println <| lowered.printModule
          return 0
        | _ =>
        IO.println s!" debug: WRONG RETURN TYPE : expected Ty.llvm (Ty.bitvec 64) "
        return 1
      | _ =>
      IO.println s!" debug: WRONG EFFECT KIND : expected pure program "
      return 1

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

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

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

def test21_before := [llvm|
{
^0(%arg10 : i12):
  %0 = llvm.mlir.constant(6 : i12) : i12
  %1 = llvm.mlir.constant(-128 : i12) : i12
  %2 = llvm.shl %arg10, %0 : i12
  %3 = llvm.icmp "eq" %2, %1 : i12
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def mkRewrite {Γ ty}
  (rw : PeepholeRewrite LLVMPlusRiscV Γ ty) :
  Σ Γ ty, PeepholeRewrite LLVMPlusRiscV Γ ty :=
  ⟨_, _, rw⟩

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

def icmp_equality_test_commute_icmp2_before := [llvm|
{
^0(%arg20 : i64, %arg21 : i64, %arg22 : i64):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "eq" %arg22, %arg20 : i64
  %3 = llvm.icmp "eq" %arg21, %arg22 : i64
  %4 = llvm.icmp "eq" %arg21, %arg20 : i64
  %5 = llvm.xor %3, %0 : i1
  %6 = "llvm.select"(%5, %4, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %7 = "llvm.select"(%2, %3, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%7) : (i1) -> ()
}
]

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

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

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

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

def neg_slt_42_after := [llvm|
{
^0(%arg30 : i128):
  %0 = llvm.mlir.constant(-1 : i128) : i128
  %1 = llvm.mlir.constant(-43 : i128) : i128
  %2 = llvm.add %arg30, %0 : i128
  %3 = llvm.icmp "sgt" %2, %1 : i128
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def and_or3_commuted_before := [llvm|
{
^0(%arg164 : i1, %arg165 : i1, %arg166 : i32, %arg167 : i32):
  %0 = llvm.icmp "eq" %arg166, %arg167 : i32
  %1 = llvm.and %0, %arg165 : i1
  %2 = "llvm.select"(%1, %arg164, %arg165) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

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

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

    (out, xs)

def 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 absdiff1_after := [llvm|
{
^0(%arg2 : i64, %arg3 : i64):
  %0 = llvm.mlir.constant(0) : i64
  %1 = llvm.icmp "ult" %arg2, %arg3 : i64
  %2 = llvm.sub %arg2, %arg3 : i64
  %3 = llvm.sub %0, %2 : i64
  %4 = "llvm.select"(%1, %3, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%4) : (i64) -> ()
}
]

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

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

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

def getBoolAttr (attr : String) : Except TransformError Bool := do
  let .bool b ← op.getAttr attr
    | .error <| .generic s!"Expected attribute `{attr}` to be of type Bool, but found:\n\
        \t{attr}"
  return b

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

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

CoeDep in Init.Coe

def a_or_b_const2_after := [llvm|
{
^0(%arg6 : i32, %arg7 : i32, %arg8 : i32, %arg9 : i32):
  %0 = llvm.icmp "eq" %arg6, %arg8 : i32
  %1 = llvm.icmp "eq" %arg7, %arg9 : i32
  %2 = llvm.xor %0, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

def lshrult_02_02_before := [llvm|
{
^0(%arg349 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.lshr %arg349, %0 : i4
  %2 = llvm.icmp "ult" %1, %0 : i4
  "llvm.return"(%2) : (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 select_t_cond : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 1)] where
  lhs := [LV| {
    ^entry (%c: i1, %t: i64):
      %0 = llvm.sext %c: i1 to i64
      %1 = llvm.select %c, %t, %0 : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%c: i1, %t: i64):
      %0 = llvm.sext %c: i1 to i64
      %1 = llvm.freeze %t : i64
      %2 = llvm.and %0, %1 : i64
      llvm.return %2 : i64
  }]

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

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

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

def rewrite_patterns : List (Σ Γ, Σ ty, PeepholeRewrite DCPlus Γ ty) :=[
  mkRewrite rewrite_a_T,
  mkRewrite rewrite_a_F,
  mkRewrite rewrite_c_A,
  mkRewrite rewrite_c_B,
  mkRewrite rewrite_h_A,
  mkRewrite rewrite_h_B,
  mkRewrite rewrite_g,
  mkRewrite rewrite_e,
]

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

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

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

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

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

def foo2_before := [llvm|
{
^0(%arg46 : i32, %arg47 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.icmp "sgt" %arg46, %0 : i32
  %2 = llvm.add %arg46, %arg47 overflow<nsw> : i32
  %3 = llvm.sub %arg46, %arg47 overflow<nsw> : i32
  %4 = "llvm.select"(%1, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def udiv {w : Nat} (x y : IntW w) (flag : ExactFlag := {exact := false}) : IntW w := do
  let x' ← x
  let y' ← y
  if flag.exact ∧ x'.umod y' ≠ 0 then
    .poison
  else
    udiv? x' y'

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

def inter (M : NFA α σ) (N : NFA α ς) : NFA α (σ × ς) := product And M N

def icmp_equality_test_constant_samesign_after := [llvm|
{
^0(%arg30 : i42, %arg31 : i42):
  %0 = llvm.icmp "eq" %arg30, %arg31 : i42
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

def lshr_sext_i1_to_i16_before := [llvm|
{
^0(%arg54 : i1):
  %0 = llvm.mlir.constant(4 : i16) : i16
  %1 = llvm.sext %arg54 : i1 to i16
  %2 = llvm.lshr %1, %0 : i16
  "llvm.return"(%2) : (i16) -> ()
}
]

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

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

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

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

def ExprRemapVar [DecidableEq d.Ty] [DecidableEq d.Op]
    {Γstart Γ Γ' : Ctxt d.Ty} {α}
    (lets : Lets d Γstart .pure Γ)
    (hom : Ctxt.Hom Γ' Γ)
    (vold : HVector Γ.Var α)
    (vnew : HVector Γ'.Var α)
    (VNEW: ∀ (Vstart : Ctxt.Valuation Γstart), vold.map (lets.denote Vstart) =
      vnew.map ((lets.denote Vstart).comap hom))
    (e' : Expr d Γ' .pure β) :
    {e : Expr d Γ .pure β // ∀ (V : Ctxt.Valuation Γstart),
          e.denoteOp (lets.denote V)
          = e'.denoteOp ((lets.denote V).comap hom) } :=
  match e' with
  | ⟨op, ty_eq, eff_le, args, regArgs⟩ =>
    let ⟨args', hargs'⟩ := VarRemapVar lets hom vold vnew VNEW args
    ⟨.mk op ty_eq eff_le args' regArgs, by admit /- proof elided -/
    ⟩

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 test_with_3_before := [llvm|
{
^0(%arg316 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.shl %0, %arg316 : i32
  %3 = llvm.and %2, %1 : i32
  "llvm.return"(%3) : (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 not_select_bool_const1_before := [llvm|
{
^0(%arg68 : i1, %arg69 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = "llvm.select"(%arg68, %arg69, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %2 = llvm.xor %1, %0 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

def printPrefix (x : BitStream) : Nat → String
  | 0   => "0b"
  | n+1 =>
    let h := if x.head then "1" else "0"
    let t := x.tail.printPrefix n
    t ++ h

List.lookup in Init.Data.List.Basic

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

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

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

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

def mul_of_bool_no_lz_other_op_before := [llvm|
{
^0(%arg85 : i32, %arg86 : i8):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(127 : i32) : i32
  %2 = llvm.and %arg85, %0 : i32
  %3 = llvm.sext %arg86 : i8 to i32
  %4 = llvm.mul %2, %3 overflow<nsw,nuw> : i32
  %5 = llvm.icmp "sgt" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

def EnvFin.getNonLsbs {w : Nat} (env : EnvFin (w + 1) n) : EnvFin w n := fun n => (env n).extractLsb' 1 w

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

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

def test5_before := [llvm|
{
^0(%arg4 : i111):
  %0 = llvm.mlir.constant(1 : i111) : i111
  %1 = llvm.mlir.constant(110 : i111) : i111
  %2 = llvm.shl %0, %1 : i111
  %3 = llvm.xor %arg4, %2 : i111
  %4 = llvm.add %3, %2 : i111
  "llvm.return"(%4) : (i111) -> ()
}
]

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

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 not_or_or_not_after := [llvm|
{
^0(%arg552 : i32, %arg553 : i32, %arg554 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg552 : i32
  %3 = llvm.and %arg553, %arg554 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.or %2, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

def 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 and_xor_or6_before := [llvm|
{
^0(%arg658 : i64, %arg659 : i64, %arg660 : i64):
  %0 = llvm.mlir.constant(42) : i64
  %1 = llvm.udiv %0, %arg658 : i64
  %2 = llvm.udiv %0, %arg659 : i64
  %3 = llvm.udiv %0, %arg660 : i64
  %4 = llvm.and %2, %1 : i64
  %5 = llvm.xor %4, %3 : i64
  %6 = llvm.or %2, %5 : i64
  "llvm.return"(%6) : (i64) -> ()
}
]

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

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

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

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

def substitute  (pred : FpPredicate) (assignment: Std.HashMap Nat (SubstitutionValue FpExpr)) :
          FpPredicate :=
  match pred with
  | (FpPredicate.bin lhs op rhs) =>
    (FpPredicate.bin (substituteBVExpr lhs assignment) op (substituteBVExpr rhs assignment))

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

IntCast in Init.Data.Int.Basic

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

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

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

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

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

def scalar_i32_lshr_and_negC_eq_after := [llvm|
{
^0(%arg35 : i32, %arg36 : i32):
  %0 = llvm.mlir.constant(262144 : i32) : i32
  %1 = llvm.lshr %arg35, %arg36 : i32
  %2 = llvm.icmp "ult" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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 scalar_i32_signbit_lshr_and_ne_after := [llvm|
{
^0(%arg27 : i32, %arg28 : i32):
  %0 = llvm.mlir.constant(-2147483648 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.lshr exact %0, %arg28 : i32
  %3 = llvm.and %2, %arg27 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

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

def icmpRows (pred : LLVM.IntPredicate) : Array Row := Id.run do
  let mut rows := #[]
  for w in [1:MAXW+1] do
    for i in BitVec.inputsForWidth w do
      for j in BitVec.inputsForWidth w do
        let retv := InstCombine.Op.denote (.icmp pred w) (.cons i <| .cons j <| .nil)
        let retv := BitVec.outputToString retv
        let row : Row := {
          opName := s!"icmp.{pred}",
          bitwidth := toString w,
          v1 := BitVec.inputToString i,
          v2 := BitVec.inputToString j,
          retval := retv
        }
        rows := rows.push row
  rows

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

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

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

instance : DialectPrint (MetaLLVM φ) where
  printOpName := MetaLLVM.opName
  printTy := MetaLLVM.printType
  printAttributes := MetaLLVM.printAttributes
  dialectName := "llvm"
  printReturn _:= "llvm.return"
  printFunc _:= "^bb0"

@[simp_llvm]
def trunc? {w: Nat} (w': Nat) (x: BitVec w) : IntW w' := do
  .value <| (BitVec.truncate w' x)

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

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

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

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

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

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

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

partial def reflectPredicateAux (exprToIx : ReflectMap) (e : Expr) (wExpected : Expr) : MetaM (ReflectResult Predicate) := do
  match_expr e with
  | Eq α a b =>
    match_expr α with
    | Nat =>
       
      
      if wExpected != a then
        throwError m!"Only Nat expressions allowed are '{wExpected} ≠ <concrete value>'. Found {indentD e}."
      let some natVal ← Lean.Meta.getNatValue? b
        | throwError m!"Expected '{wExpected} ≠ <concrete width>', found symbolic width {indentD b}."
      let out := Predicate.width .eq natVal
      return { exprToIx := exprToIx, e := out }

    | BitVec w =>
      let a ←  reflectTermUnchecked exprToIx w a
      let b ← reflectTermUnchecked a.exprToIx w b
      return { exprToIx := b.exprToIx, e := Predicate.binary .eq a.e b.e }
    | Bool =>
      
      
      
      
      let_expr true := b
        | throwError m!"only boolean conditionals allowed are 'bv.\{u,s}l\{t,e} bv = true'. Found {indentD e}."
      match_expr a with
      | BitVec.slt w a b =>
        let a ← reflectTermUnchecked exprToIx w a
        let b ← reflectTermUnchecked a.exprToIx w b
        return { exprToIx := b.exprToIx, e := Predicate.binary .slt a.e b.e }
      | BitVec.sle w a b =>
        let a ← reflectTermUnchecked exprToIx w a
        let b ← reflectTermUnchecked a.exprToIx w b
        return { exprToIx := b.exprToIx, e := Predicate.binary .sle a.e b.e }
      | BitVec.ult w a b =>
        let a ← reflectTermUnchecked exprToIx w a
        let b ← reflectTermUnchecked a.exprToIx w b
        return { exprToIx := b.exprToIx, e := Predicate.binary .ult a.e b.e }
      | BitVec.ule w a b =>
        let a ← reflectTermUnchecked exprToIx w a
        let b ← reflectTermUnchecked a.exprToIx w b
        return { exprToIx := b.exprToIx, e := Predicate.binary .ule a.e b.e }
      | _ =>
        throwError m!"unknown boolean conditional, expected 'bv.slt bv = true' or 'bv.sle bv = true'. Found {indentD e}"
    | _ =>
      throwError m!"unknown equality kind, expected 'bv = bv' or 'bv.slt bv = true' or 'bv.sle bv = true'. Found {indentD e}"
  | Ne α a b =>
     
    match_expr α with
    | Nat => do
      
      if wExpected != a then
        throwError m!"Only Nat expressions allowed are '{wExpected} ≠ <concrete value>'. Found {indentD e}."
      let some natVal ← Lean.Meta.getNatValue? b
        | throwError m!"Expected '{wExpected} ≠ <concrete width>', found symbolic width {indentD b}."
      let out := Predicate.width .neq natVal
      return { exprToIx := exprToIx, e := out }
    | BitVec w =>
      let a ← reflectTermUnchecked exprToIx w a
      let b ← reflectTermUnchecked a.exprToIx w b
      return { exprToIx := b.exprToIx, e := Predicate.binary .neq a.e b.e }
    | _ =>
      throwError m!"Expected typeclass to be 'BitVec w' / 'Nat', found '{indentD α}' in {e} when matching against 'Ne'"
  | LT.lt α _inst a b =>
    let_expr BitVec w := α | throwError m!"Expected typeclass to be BitVec w, found '{indentD α}' in {indentD e} when matching against 'LT.lt'"
    let a ← reflectTermUnchecked exprToIx w a
    let b ← reflectTermUnchecked a.exprToIx w b
    return { exprToIx := b.exprToIx, e := Predicate.binary .ult a.e b.e }
  | LE.le α _inst a b =>
    let_expr BitVec w := α | throwError m!"Expected typeclass to be BitVec w, found '{indentD α}' in {indentD e} when matching against 'LE.le'"
    let a ← reflectTermUnchecked exprToIx w a
    let b ← reflectTermUnchecked a.exprToIx w b
    return { exprToIx := b.exprToIx, e := Predicate.binary .ule a.e b.e }
  | Or p q =>
    let p ← reflectPredicateAux exprToIx p wExpected
    let q ← reflectPredicateAux p.exprToIx q wExpected
    let out := Predicate.lor p.e q.e
    return { q with e := out }
  | And p q =>
    let p ← reflectPredicateAux exprToIx p wExpected
    let q ← reflectPredicateAux p.exprToIx q wExpected
    let out := Predicate.land p.e q.e
    return { q with e := out }
  | _ =>
     throwError m!"expected predicate over bitvectors (no quantification), found:  {indentD e}"

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

def ne_and_lshr_minval_before := [llvm|
{
^0(%arg31 : i8, %arg32 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mul %arg31, %arg31 : i8
  %2 = llvm.lshr %0, %arg32 : i8
  %3 = llvm.and %1, %2 : i8
  %4 = llvm.icmp "ne" %3, %2 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

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

instance : HydrableInstances GenBVPred where

def getBoolLit? : Expr → Option Bool
  | Expr.const ``Bool.true _  => some true
  | Expr.const ``Bool.false _ => some false
  | _                         => none

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

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

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

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

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

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

instance : Lean.ToExpr (LLVM.Op) :=

def llvm_const_lower_riscv_li44 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM44, rhs:= liRiscv44,
   correct := by admit /- proof elided -/

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

def foo1_or_after := [llvm|
{
^0(%arg154 : i32, %arg155 : i32, %arg156 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.shl %0, %arg155 overflow<nuw> : i32
  %2 = llvm.shl %0, %arg156 overflow<nuw> : i32
  %3 = llvm.or %1, %2 : i32
  %4 = llvm.and %arg154, %3 : i32
  %5 = llvm.icmp "eq" %4, %3 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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 add_constant_equal_with_the_top_bit_of_demandedbits_pass_before := [llvm|
{
^0(%arg9 : i32):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.mlir.constant(24 : i32) : i32
  %2 = llvm.add %arg9, %0 : i32
  %3 = llvm.and %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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 or_xor_or_before := [llvm|
{
^0(%arg156 : i8):
  %0 = llvm.mlir.constant(33 : i8) : i8
  %1 = llvm.mlir.constant(12 : i8) : i8
  %2 = llvm.mlir.constant(7 : i8) : i8
  %3 = llvm.or %arg156, %0 : i8
  %4 = llvm.xor %3, %1 : i8
  %5 = llvm.or %4, %2 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

elab "#reducewidth" expr:term " : " target:term : command =>

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

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

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

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

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

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

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

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

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

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

def llvm_const_lower_riscv_li_38 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_38, rhs:= liRiscv_38,
   correct := by admit /- proof elided -/

def zext_nneg_before := [llvm|
{
^0(%arg0 : i16):
  %0 = llvm.mlir.constant(32767 : i16) : i16
  %1 = llvm.mlir.constant(8388607 : i24) : i24
  %2 = llvm.and %arg0, %0 : i16
  %3 = llvm.zext nneg %2 : i16 to i24
  %4 = llvm.and %3, %1 : i24
  "llvm.return"(%4) : (i24) -> ()
}
]

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

inductive Ty
| bitvec (w : Nat) : Ty 
deriving DecidableEq, Repr, ToExpr

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

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

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

def multiuse1_after := [llvm|
{
^0(%arg11 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.mlir.constant(6 : i32) : i32
  %3 = llvm.mlir.constant(384 : i32) : i32
  %4 = llvm.lshr %arg11, %0 : i32
  %5 = llvm.and %4, %0 : i32
  %6 = llvm.lshr %arg11, %0 : i32
  %7 = llvm.and %6, %1 : i32
  %8 = llvm.shl %arg11, %2 : i32
  %9 = llvm.and %8, %3 : i32
  %10 = llvm.or disjoint %5, %7 : i32
  %11 = llvm.or disjoint %10, %9 : i32
  "llvm.return"(%11) : (i32) -> ()
}
]

@[simp_denote] def neg {Γ : Ctxt _} (a : Var Γ .int) : Expr ScfArith Γ .pure .int :=
  Expr.mk
    (op := .coe <| .neg)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .cons a <| .nil)
    (regArgs := .nil)

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

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

def test35_with_trunc_before := [llvm|
{
^0(%arg48 : i64):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(60 : i32) : i32
  %2 = llvm.mlir.constant(100 : i32) : i32
  %3 = llvm.trunc %arg48 : i64 to i32
  %4 = llvm.icmp "sge" %3, %0 : i32
  %5 = "llvm.select"(%4, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

BitVec.udiv in Init.Data.BitVec.Basic

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

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

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

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

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

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

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

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

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

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

def sub_ashr_or_i32_before := [llvm|
{
^0(%arg35 : i32, %arg36 : i32):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.sub %arg36, %arg35 overflow<nsw> : i32
  %2 = llvm.ashr %1, %0 : i32
  %3 = llvm.or %2, %arg35 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def test12_after := [llvm|
{
^0(%arg46 : i32, %arg47 : i32):
  %0 = llvm.mlir.constant(1431655765 : i32) : i32
  %1 = llvm.and %arg46, %0 : i32
  %2 = llvm.sub %arg47, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def testExampleSndVal : DCOp.TokenStream :=
  exampleSndVal.denote (Ctxt.Valuation.ofHVector (.cons inputFstVal <| .nil))

instance : Inhabited BVExprWrapper where
  default := {bvExpr := GenBVExpr.const (BitVec.ofNat 0 0), width := 0}

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

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

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

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

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

def lift (f : Fin n → Fin m) (M : NFA' n) : NFA' m where
  σ := _
  M := M.M.lift f

def t0_before := [llvm|
{
^0(%arg42 : i32, %arg43 : i32, %arg44 : i32, %arg45 : i32):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.icmp "eq" %arg42, %arg43 : i32
  %2 = llvm.icmp "eq" %arg44, %arg45 : i32
  %3 = llvm.or %2, %1 : i1
  %4 = llvm.xor %3, %0 : i1
  "llvm.return"(%4) : (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 sle_swap_or_not_min_after := [llvm|
{
^0(%arg280 : i8, %arg281 : i8):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def test1_before := [llvm|
{
^0(%arg1 : i17):
  %0 = llvm.mlir.constant(8 : i37) : i37
  %1 = llvm.zext %arg1 : i17 to i37
  %2 = llvm.lshr %1, %0 : i37
  %3 = llvm.shl %1, %0 : i37
  %4 = llvm.or %2, %3 : i37
  %5 = llvm.trunc %4 : i37 to i17
  "llvm.return"(%5) : (i17) -> ()
}
]

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

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

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

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

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

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

def mul64_low_after := [llvm|
{
^0(%arg20 : i64, %arg21 : i64):
  %0 = llvm.mul %arg20, %arg21 : i64
  "llvm.return"(%0) : (i64) -> ()
}
]

Lean.Meta.Context in Lean.Meta.Basic

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

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

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

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

instance : Lean.ToExpr RegIndex := inherit

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

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

def negate_sext_after := [llvm|
{
^0(%arg98 : i8, %arg99 : i1):
  %0 = llvm.zext %arg99 : i1 to i8
  %1 = llvm.add %arg98, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

private def oprgn0 : Op φ := [mlir_op|
 "func"() ({ ^entry: %x = "foo.add"() : () -> (i64) } ) : () -> ()
]

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

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

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

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

def source : Expr (DC) Γ .pure (.tokenstream) :=
  Expr.mk
    (op := .source)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .nil)
    (regArgs := .nil)

def in_constant_varx_14_after := [llvm|
{
^0(%arg26 : i4, %arg27 : i4):
  %0 = llvm.mlir.constant(-2 : i4) : i4
  %1 = llvm.or %arg26, %0 : i4
  "llvm.return"(%1) : (i4) -> ()
}
]

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

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

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

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

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

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

@[simp_denote]
def udiv {Γ : 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.udiv w)
    (eff_le := by admit /- proof elided -/
    )
    (ty_eq := rfl)
    (args := .cons ⟨l, lp⟩ <| .cons ⟨r, rp⟩ .nil)
    (regArgs := .nil)

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


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

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

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

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

def sub_select_not_zext_after := [llvm|
{
^0(%arg22 : i1, %arg23 : i64):
  %0 = llvm.mlir.constant(63) : i64
  %1 = "llvm.select"(%arg22, %arg23, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%1) : (i64) -> ()
}
]

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

def eval (assign : Std.HashMap Nat BVExpr.PackedBitVec) : GenBVPred → Bool
  | bin lhs op rhs => op.eval (lhs.eval assign) (rhs.eval assign)
  | getLsbD expr idx => (expr.eval assign).getLsbD idx

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

def test_sub_lhs_add_const_RHS := [mod_arith q, hq| {
  ^bb0(%x : !R):
    %res0 = mod_arith.constant 22 : !R
    %res1 = mod_arith.sub %res0, %x : !R
    return %res1 : !R
}]

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

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

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

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

def test_sgt_xor_after := [llvm|
{
^0(%arg40 : i32, %arg41 : i32):
  %0 = llvm.xor %arg41, %arg40 : i32
  %1 = llvm.icmp "slt" %0, %arg40 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

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

def shl_lshr_demand4_before := [llvm|
{
^0(%arg17 : i8):
  %0 = llvm.mlir.constant(44 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.mlir.constant(-32 : i8) : i8
  %3 = llvm.shl %0, %arg17 : i8
  %4 = llvm.lshr %3, %1 : i8
  %5 = llvm.or %4, %2 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def test2_before := [llvm|
{
^0(%arg0 : i167):
  %0 = llvm.mlir.constant(9 : i577) : i577
  %1 = llvm.mlir.constant(8 : i577) : i577
  %2 = llvm.zext %arg0 : i167 to i577
  %3 = llvm.lshr %2, %0 : i577
  %4 = llvm.shl %2, %1 : i577
  %5 = llvm.or %3, %4 : i577
  %6 = llvm.trunc %5 : i577 to i167
  "llvm.return"(%6) : (i167) -> ()
}
]

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

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

def narrow_zext_ashr_keep_trunc3_before := [llvm|
{
^0(%arg4 : i8, %arg5 : i8):
  %0 = llvm.mlir.constant(1) : i64
  %1 = llvm.sext %arg4 : i8 to i64
  %2 = llvm.sext %arg5 : i8 to i64
  %3 = llvm.add %1, %2 overflow<nsw> : i64
  %4 = llvm.ashr %3, %0 : i64
  %5 = llvm.trunc %4 : i64 to i7
  "llvm.return"(%5) : (i7) -> ()
}
]

def not_signbit_zext_before := [llvm|
{
^0(%arg17 : i16):
  %0 = llvm.mlir.constant(-1 : i16) : i16
  %1 = llvm.mlir.constant(15 : i16) : i16
  %2 = llvm.xor %arg17, %0 : i16
  %3 = llvm.lshr %2, %1 : i16
  %4 = llvm.zext %3 : i16 to i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

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

def not_mul_of_bool_commute_before := [llvm|
{
^0(%arg87 : i32, %arg88 : i32):
  %0 = llvm.mlir.constant(30 : i32) : i32
  %1 = llvm.mlir.constant(255 : i32) : i32
  %2 = llvm.lshr %arg87, %0 : i32
  %3 = llvm.and %arg88, %1 : i32
  %4 = llvm.mul %3, %2 : i32
  %5 = llvm.icmp "ugt" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

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

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

def positive_samevar_shlnsw_before := [llvm|
{
^0(%arg52 : i8, %arg53 : i8):
  %0 = llvm.ashr %arg52, %arg53 : i8
  %1 = llvm.shl %0, %arg53 overflow<nsw> : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

def src_is_notmask_x_xor_neg_x_after := [llvm|
{
^0(%arg69 : i8, %arg70 : i8, %arg71 : i1):
  %0 = llvm.mlir.constant(123 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.mlir.constant(7 : i8) : i8
  %3 = llvm.xor %arg69, %0 : i8
  %4 = llvm.add %arg70, %1 : i8
  %5 = llvm.xor %arg70, %4 : i8
  %6 = "llvm.select"(%arg71, %5, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %7 = llvm.icmp "ule" %3, %6 : i8
  "llvm.return"(%7) : (i1) -> ()
}
]

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

def ptradd (p : SLLVM.Ptr) (x : LLVM.IntW 64) : SLLVM.Ptr := do
  let p ← p
  let x ← x
  return { p with offset := p.offset + x}

inductive BasicBlock
  | mk (label : BlockLabel) (args : List VarName) (body : Body)

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

instance (ty : LLVM.Ty) : Coe ℤ (TyDenote.toType ty) where
  coe z := match ty with
    | bitvec w => .value <| BitVec.ofInt w z

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

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

IO.monoMsNow in Init.System.IO

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

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

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 add_nuw_or_and_before := [llvm|
{
^0(%arg9 : i32, %arg10 : i32):
  %0 = llvm.or %arg9, %arg10 : i32
  %1 = llvm.and %arg9, %arg10 : i32
  %2 = llvm.add %0, %1 overflow<nuw> : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

def trunc_nsw_xor_after := [llvm|
{
^0(%arg3 : i8, %arg4 : i8):
  %0 = llvm.icmp "ne" %arg3, %arg4 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

def multiuse2_after := [llvm|
{
^0(%arg10 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(12 : i32) : i32
  %2 = llvm.mlir.constant(48 : i32) : i32
  %3 = llvm.mlir.constant(192 : i32) : i32
  %4 = llvm.mlir.constant(8 : i32) : i32
  %5 = llvm.mlir.constant(32256 : i32) : i32
  %6 = llvm.shl %arg10, %0 : i32
  %7 = llvm.and %6, %1 : i32
  %8 = llvm.shl %arg10, %0 : i32
  %9 = llvm.and %8, %2 : i32
  %10 = llvm.shl %arg10, %0 : i32
  %11 = llvm.and %10, %3 : i32
  %12 = llvm.shl %arg10, %4 : i32
  %13 = llvm.and %12, %5 : i32
  %14 = llvm.or disjoint %11, %9 : i32
  %15 = llvm.or disjoint %7, %14 : i32
  %16 = llvm.or disjoint %13, %15 : i32
  "llvm.return"(%16) : (i32) -> ()
}
]

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

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

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

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

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

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 test8_before := [llvm|
{
^0(%arg20 : i32):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.mlir.constant(32767) : i64
  %2 = llvm.ashr %arg20, %0 : i32
  %3 = llvm.sext %2 : i32 to i64
  %4 = llvm.mul %3, %1 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

def test13_before := [llvm|
{
^0(%arg27 : i18):
  %0 = llvm.mlir.constant(3 : i18) : i18
  %1 = llvm.mlir.constant(8 : i18) : i18
  %2 = llvm.mlir.constant(9 : i18) : i18
  %3 = llvm.mul %arg27, %0 : i18
  %4 = llvm.ashr %3, %1 : i18
  %5 = llvm.shl %4, %2 : i18
  "llvm.return"(%5) : (i18) -> ()
}
]

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

Lean.Expr.numeral? in Mathlib.Lean.Expr.Basic

Lean.FileMap.ofString in Lean.Data.Position

def both_sides_fold_eq_after := [llvm|
{
^0(%arg37 : i32, %arg38 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg38, %0 : i1
  "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 xor_nosignbit_ashr_before := [llvm|
{
^0(%arg2 : i32):
  %0 = llvm.mlir.constant(2147418112 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.xor %arg2, %0 : i32
  %3 = llvm.ashr %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]
</all_available_defs>

<all_available_lemmas>
Fin.coe_cast in Init.Data.Fin.Lemmas
List.getElem?_append in Init.Data.List.Lemmas
List.getElem?_ofFn in Init.Data.List.OfFn
List.getElem_append_right in Init.Data.List.BasicAux
List.length_append in Init.Data.List.Basic
Nat.ge_of_not_lt in Init.Data.Nat.Basic
Option.dite_none_right_eq_some in Init.Data.Option.Lemmas
Valuation.ext in Mathlib.RingTheory.Valuation.Basic
dite_eq_ite in Init.ByCases

@[simp] theorem ofList_append {ts us : List Ty} :
    Ctxt.ofList ts ++ Ctxt.ofList us = Ctxt.ofList (ts ++ us)

@[simp, grind=] theorem length_ofList : (ofList ts).length = ts.length

@[simp, grind=] theorem getElem?_ofList (i : Nat) : (ofList ts)[i]? = ts[i]?

@[simp, grind=] theorem getElem_ofList (i : Nat) (h : _) : (ofList ts)[i]'h = ts[i]'h

theorem val_lt (v : Γ.Var t) : v.val < Γ.length

@[simp, grind=] theorem castCtxt_rfl (h : Γ = Γ) : v.castCtxt h = v

@[simp, grind=] theorem val_castCtxt : (castCtxt h v).val = v.val

theorem ashr_ne_exact_proof : ashr_ne_exact_before ⊑ ashr_ne_exact_after

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

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

theorem test_lshr_exact__exact_is_safe_proof : test_lshr_exact__exact_is_safe_before ⊑ test_lshr_exact__exact_is_safe_after

theorem select_constants_and_icmp_eq0_zero_tval_proof : select_constants_and_icmp_eq0_zero_tval_before ⊑ select_constants_and_icmp_eq0_zero_tval_after

theorem ashrslt_03_01_proof : ashrslt_03_01_before ⊑ ashrslt_03_01_after

theorem t9_ashr_exact_flag_preservation_proof : t9_ashr_exact_flag_preservation_before ⊑ t9_ashr_exact_flag_preservation_after

theorem t7_thm.extracted_1._3 : ∀ (x : BitVec 8) (x_1 : BitVec 1) (x_2 : BitVec 8),
  ¬x_1 = 1#1 → ¬x ≥ ↑8 → True ∧ ((-1#8) <<< x).sshiftRight' x ≠ -1#8 ∨ x ≥ ↑8 → False

theorem or_trunc_lshr_small_mask_proof : or_trunc_lshr_small_mask_before ⊑ or_trunc_lshr_small_mask_after

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

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

theorem test_sub_nsw__all_are_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 255)) (const? 32 6)) (const? 32 (-260))
      (sub (const? 32 (-254)) (LLVM.and e (const? 32 255)) { «nsw» := true, «nuw» := false }) ⊑
    sub (const? 32 (-254)) (LLVM.and e (const? 32 255)) { «nsw» := true, «nuw» := true }

lemma TermUnop.alt_lang {t : Term} (op : TermUnop) :
  (op.subst_arity' ▸ (op.subst t).language) =
    let lop : Set (BitVecs 2) := op.openTerm_arity' ▸ op.openTerm.language
    let lop' : Set (BitVecs (t.arity + 2)) := lop.lift (λ i ↦ i.natAdd t.arity)
    let lt : Set (BitVecs (t.arity + 2)) := t.language.lift (λ i ↦ i.castLE (by omega))
    let l := lt ∩ lop'
    l.proj (liftUnop t.arity)

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

theorem ult_swap_or_not_max_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.ugt e_1 e) (const? 1 1) (icmp IntPred.ne e (const? 8 (-1))) ⊑
    icmp IntPred.ne e (const? 8 (-1))

theorem bitwise_and_logical_and_masked_icmp_allones_poison1_proof : bitwise_and_logical_and_masked_icmp_allones_poison1_before ⊑ bitwise_and_logical_and_masked_icmp_allones_poison1_after

theorem e_2316 :
    3 *  ~~~(d &&& ( ~~~e ||| f)) + 1 * (f &&&  ~~~(d &&& e)) + 7 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 2 *  ~~~( ~~~d &&& (e &&& f)) - 1 * (e ^^^  ~~~(d |||  ~~~f)) - 1 * (f ^^^ (d &&& ( ~~~e ||| f))) - 1 * (e |||  ~~~(d ||| f)) - 7 * (e ^^^ ( ~~~d ||| (e ||| f))) - 7 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 1 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 11 * (d ^^^ (e ||| f)) + 5 *  ~~~(e &&&  ~~~f) + 7 * (e ^^^ (d ||| (e &&& f))) - 6 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 5 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 5 *  ~~~(d |||  ~~~f) - 1 *  ~~~(d ^^^ e) + 1 *  ~~~d - 2 * ( ~~~d ||| (e &&& f)) + 2 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 1 * (e &&&  ~~~f) - 11 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 3 * (e ^^^ (d &&& ( ~~~e ||| f))) - 2 * (f &&&  ~~~(d &&&  ~~~e)) - 2 *  ~~~(e ||| f) + 11 *  ~~~(d &&&  ~~~f) - 11 * ((d &&& e) ^^^ (e |||  ~~~f)) + 3 * (d ||| ( ~~~e &&& f)) + 1 * (f ^^^ (d &&& e)) + 2 * (d |||  ~~~e) + 2 * (e ^^^ (d &&& (e ||| f))) - 11 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 7 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 1 * (d &&&  ~~~f) - 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 1 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 7 * (f |||  ~~~(d |||  ~~~e)) + 2 * ((d ||| e) &&& (e ^^^ f)) + 1 * (e ||| (d &&& f)) + 5 * (e ^^^  ~~~(d &&& (e ||| f))) - 5 *  ~~~( ~~~d ||| (e ^^^ f)) - 1 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 2 * ( ~~~d ||| (e ||| f)) - 3 *  ~~~(d ^^^ (e ||| f)) - 6 * (e ^^^ (d &&& f)) + 1 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 2 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 11 * ((d &&& e) |||  ~~~(e ^^^ f)) - 3 * ( ~~~e &&&  ~~~(d ^^^ f)) - 2 * (d ||| (e ^^^ f)) + 3 * (e ^^^ (d ||| (e ||| f))) - 3 * ((d &&& e) |||  ~~~(e ||| f)) + 3 * ((d ^^^ e) &&& (d ^^^ f)) + 5 * (f ^^^ ( ~~~d ||| (e ||| f))) - 1 * (e ^^^  ~~~(d &&&  ~~~f)) + 24 *  ~~~(d ||| (e ||| f)) + 28 *  ~~~(d ||| ( ~~~e ||| f)) + 1 *  ~~~( ~~~d ||| (e ||| f)) - 6 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 26 * ( ~~~d &&& ( ~~~e &&& f)) - 3 * ( ~~~d &&& (e &&& f)) - 11 * (d &&& ( ~~~e &&& f)) - 16 * (d &&& (e &&& f)) =  - 11 * (e &&& f)

theorem drop_nuw_trunc_thm (e e_1 : IntW 16) :
  trunc 8 (LLVM.and (LLVM.and e_1 (const? 16 255)) e) { «nsw» := false, «nuw» := true } ⊑
    trunc 8 (LLVM.and e_1 e)

@[grind ., simp] lemma RawCNFA.empty_mem_tr {s s' : State} : s' ∉ empty (A := A).tr s a

theorem test16_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ((x_1 ^^^ 33#8 ^^^ x) &&& (x ^^^ x_1)) * (x_1 ^^^ 33#8 ^^^ x) =
    ((x_1 ^^^ x ^^^ 33#8) &&& (x ^^^ x_1)) * (x_1 ^^^ x ^^^ 33#8)

theorem lshr_by_const_cmp_sge_value_thm (e : IntW 32) :
  icmp IntPred.sge (lshr e (const? 32 3)) e ⊑ icmp IntPred.slt e (const? 32 1)

theorem smear_sign_and_widen_proof : smear_sign_and_widen_before ⊑ smear_sign_and_widen_after

theorem ashrsgt_03_06_exact_proof : ashrsgt_03_06_exact_before ⊑ ashrsgt_03_06_exact_after

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

theorem lt_signed_to_large_unsigned_proof : lt_signed_to_large_unsigned_before ⊑ lt_signed_to_large_unsigned_after

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

theorem add_smin_simplify2_thm (e : IntW 32) :
  select (icmp IntPred.slt (add e (const? 32 (-3)) { «nsw» := true, «nuw» := false }) (const? 32 2147483645))
      (add e (const? 32 (-3)) { «nsw» := true, «nuw» := false }) (const? 32 2147483645) ⊑
    add e (const? 32 (-3)) { «nsw» := true, «nuw» := false }

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7b_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7b_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7b_after

theorem trunc_unsigned_nsw_zext_proof : trunc_unsigned_nsw_zext_before ⊑ trunc_unsigned_nsw_zext_after

theorem ashrslt_01_07_proof : ashrslt_01_07_before ⊑ ashrslt_01_07_after

theorem lowmask_mul_zext_proof : lowmask_mul_zext_before ⊑ lowmask_mul_zext_after

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

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

theorem sel_zext_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → zeroExtend 64 42#32 = 42#64

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

theorem sext_zext_uge_known_nonneg_op0_wide_thm (e : IntW 8) (e_1 : IntW 16) :
  icmp IntPred.uge (sext 32 e_1) (zext 32 (LLVM.and e (const? 8 12))) ⊑
    icmp IntPred.uge e_1 (zext 16 (LLVM.and e (const? 8 12)) { «nneg» := true })

theorem e_2260 :
    7 * (e ||| f) + 5 * (d ||| ( ~~~e ||| f)) + 5 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 2 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 5 * (f ^^^  ~~~(d ||| e)) + 2 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 2 * (d ||| ( ~~~e &&& f)) - 1 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 1 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 2 * (e ^^^ (d &&&  ~~~f)) + 3 *  ~~~(d &&& e) - 5 * ( ~~~f |||  ~~~(d ^^^ e)) + 2 * (e ^^^ (d &&& (e ^^^ f))) - 11 * (e ^^^  ~~~(d ||| f)) - 2 * f - 6 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 1 * ((d &&& e) |||  ~~~(e |||  ~~~f)) - 6 * (f ^^^ ( ~~~d ||| (e &&& f))) + 7 * (f ^^^ (d |||  ~~~e)) - 1 * (d ^^^ ( ~~~e &&& f)) - 2 * (e &&&  ~~~(d &&& f)) + 5 *  ~~~(d &&&  ~~~d) - 1 * (f ||| (d &&&  ~~~e)) - 7 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 2 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 1 * (f ^^^ (d ||| ( ~~~e &&& f))) + 2 * ((d &&& f) |||  ~~~(e ||| f)) + 1 * (f ^^^  ~~~(d &&& (e ||| f))) - 3 * (f ^^^ (d &&& e)) + 11 *  ~~~(d ^^^ (e ^^^ f)) + 3 * (e &&& (d |||  ~~~f)) - 5 * (f ^^^  ~~~(d &&&  ~~~e)) - 5 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 1 * ((d &&& e) |||  ~~~(e ||| f)) - 1 * (d &&& (e ||| f)) - 2 * ( ~~~f &&&  ~~~(d ^^^ e)) - 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 11 *  ~~~(d &&& ( ~~~e &&& f)) + 1 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 2 * (d ^^^ ( ~~~e ||| f)) - 7 *  ~~~( ~~~d &&& (e ^^^ f)) + 7 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 2 * (f ^^^  ~~~(d &&& e)) + 7 * (e ^^^ (d &&& ( ~~~e ||| f))) + 7 * (f |||  ~~~(d ||| e)) + 7 * ((d ^^^ e) ||| (d ^^^ f)) - 1 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 1 * (f ^^^  ~~~(d |||  ~~~e)) - 1 * (d &&&  ~~~e) - 1 *  ~~~(d ||| (e ||| f)) - 8 *  ~~~(d ||| ( ~~~e ||| f)) - 13 *  ~~~( ~~~d ||| (e ||| f)) + 13 * ( ~~~d &&& ( ~~~e &&& f)) - 27 * ( ~~~d &&& (e &&& f)) - 38 * (d &&& ( ~~~e &&& f)) + 14 * (d &&& (e &&& f)) =  - 11 *  ~~~( ~~~d ||| ( ~~~e ||| f))

theorem xor_icmp_to_ne_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (4#32 <ₛ x) ^^^ ofBool (x <ₛ 6#32) = ofBool (x != 5#32)

theorem test5_proof : test5_before ⊑ test5_after

theorem ashrslt_03_02_exact_proof : ashrslt_03_02_exact_before ⊑ ashrslt_03_02_exact_after

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

theorem icmp_shl_ne_2_proof : icmp_shl_ne_2_before ⊑ icmp_shl_ne_2_after

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

theorem eval_eq_outputWith_carryWith (p : FSM arity) :
  p.eval x n =
  p.outputWith (p.carryWith p.initCarry x n) (fun a => x a n)

theorem scalar_i32_shl_and_signbit_eq_nonzero_proof : scalar_i32_shl_and_signbit_eq_nonzero_before ⊑ scalar_i32_shl_and_signbit_eq_nonzero_after

theorem sle_smax2_proof : sle_smax2_before ⊑ sle_smax2_after

theorem not_or_or_and_not_and_and_commute2_or_proof : not_or_or_and_not_and_and_commute2_or_before ⊑ not_or_or_and_not_and_and_commute2_or_after

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

theorem select_bittest_to_sub_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 1#32 == 0#32) = 1#1 →
    True ∧ (4#32).ssubOverflow (x &&& 1#32) = true ∨ True ∧ (4#32).usubOverflow (x &&& 1#32) = true → False

theorem sext_sext_sge_op0_narrow_proof : sext_sext_sge_op0_narrow_before ⊑ sext_sext_sge_op0_narrow_after

theorem Eqn.denoteFin_eq_add {w : Nat} (eqn : Eqn) (env : EnvFin (w + 1) eqn.numVars) :
    eqn.denoteFin env = 2 * eqn.denoteFin env.getNonLsbs + eqn.denoteFin env.getLsb

theorem positive_with_extra_and_logical_thm.extracted_1._2 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  ofBool (x_1 + 128#32 <ᵤ 256#32) = 1#1 ∧ ofBool (-1#32 <ₛ x_1) = 1#1 → ¬ofBool (x_1 <ᵤ 128#32) = 1#1 → x = 0#1

theorem test_shl_nuw_nsw__none_are_safe_proof : test_shl_nuw_nsw__none_are_safe_before ⊑ test_shl_nuw_nsw__none_are_safe_after

theorem pr89516_proof : pr89516_before ⊑ pr89516_after

theorem icmp_eq_zext_ne_one_proof : icmp_eq_zext_ne_one_before ⊑ icmp_eq_zext_ne_one_after

theorem ashr_ugt_10_proof : ashr_ugt_10_before ⊑ ashr_ugt_10_after

theorem icmp_eq_x_invertable_y2_todo_proof : icmp_eq_x_invertable_y2_todo_before ⊑ icmp_eq_x_invertable_y2_todo_after

theorem positive_samevar_shlnsw_proof : positive_samevar_shlnsw_before ⊑ positive_samevar_shlnsw_after

theorem ashr_ne_both_equal_proof : ashr_ne_both_equal_before ⊑ ashr_ne_both_equal_after

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

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

theorem t6_no_extrause_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x_1 + x <ᵤ x) = ofBool (x ^^^ -1#8 <ᵤ x_1)

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

theorem select_constants_and_icmp_ne0_common_bit_thm (e e_1 : IntW 1) :
  icmp IntPred.ne (LLVM.and (select e_1 (const? 8 2) (const? 8 3)) (select e (const? 8 2) (const? 8 3)))
      (const? 8 0) ⊑
    const? 1 1

theorem fold_sext_to_and_wrong3_proof : fold_sext_to_and_wrong3_before ⊑ fold_sext_to_and_wrong3_after

theorem lshr_pow2_ult_proof : lshr_pow2_ult_before ⊑ lshr_pow2_ult_after

theorem test_negative_combined_sub_signed_overflow_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (127#8).ssubOverflow x = true) → ofBool (127#8 - x <ₛ -1#8) = 0#1

theorem i_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬((BitVec.ofInt 8 (-3) == 0 || 8 != 1 && x == intMin 8 && BitVec.ofInt 8 (-3) == -1) = true ∨
        (BitVec.ofInt 8 (-3) == 0 || 8 != 1 && x.sdiv (BitVec.ofInt 8 (-3)) == intMin 8 && BitVec.ofInt 8 (-3) == -1) =
          true) →
    (9#8 == 0 || 8 != 1 && x == intMin 8 && 9#8 == -1) = true → False

theorem trunc_shl_33_i32_i64_thm.extracted_1._1 : ∀ (x : BitVec 64), ¬33#64 ≥ ↑64 → truncate 32 (x <<< 33#64) = 0#32

theorem setWidth_eq_zext (x : BitVec v) : x.zeroExtend w = x.setWidth w

theorem neg_slt_42_proof : neg_slt_42_before ⊑ neg_slt_42_after

theorem select_add_icmp_proof : select_add_icmp_before ⊑ select_add_icmp_after

theorem testi16i8_proof : testi16i8_before ⊑ testi16i8_after

theorem urem_i1_is_zero_proof : urem_i1_is_zero_before ⊑ urem_i1_is_zero_after

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

@[simp] theorem HVector.vars_nil :
    (HVector.nil : HVector (Var Γ) ([] : List d.Ty)).vars = ∅

@[simp] theorem get_map (xs : HVector A as) (f : (a : α) → A a → B a) :
    (xs.map f).get i = f _ (xs.get i)

theorem sge_swap_or_max_proof : sge_swap_or_max_before ⊑ sge_swap_or_max_after

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

theorem lshr_and_and_proof : lshr_and_and_before ⊑ lshr_and_and_after

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

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

theorem test_proof : test_before ⊑ test_after

theorem test_ult_proof : test_ult_before ⊑ test_ult_after

theorem positive_biggerlshr_proof : positive_biggerlshr_before ⊑ positive_biggerlshr_after

theorem n14_wrong_comparison_constant_proof : n14_wrong_comparison_constant_before ⊑ n14_wrong_comparison_constant_after

theorem test_invert_demorgan_or3_thm (e e_1 : IntW 32) :
  LLVM.xor
      (LLVM.or
        (LLVM.or
          (LLVM.or (icmp IntPred.eq e_1 (const? 32 178206))
            (icmp IntPred.ult (add e (const? 32 (-195102))) (const? 32 1506)))
          (icmp IntPred.ult (add e (const? 32 (-201547))) (const? 32 716213)))
        (icmp IntPred.ult (add e (const? 32 (-918000))) (const? 32 196112)))
      (const? 1 1) ⊑
    LLVM.and
      (LLVM.and
        (LLVM.and (icmp IntPred.ne e_1 (const? 32 178206))
          (icmp IntPred.ult (add e (const? 32 (-196608))) (const? 32 (-1506))))
        (icmp IntPred.ult (add e (const? 32 (-917760))) (const? 32 (-716213))))
      (icmp IntPred.ult (add e (const? 32 (-1114112))) (const? 32 (-196112)))

theorem test_nsw_and_signed_pred_proof : test_nsw_and_signed_pred_before ⊑ test_nsw_and_signed_pred_after

theorem zext_sext_add_icmp_ugt_1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  ofBool (1#8 <ᵤ zeroExtend 8 x_1 + signExtend 8 x) = x &&& (x_1 ^^^ 1#1)

theorem e_1478 :
     - 11 *  ~~~(z &&& t) + 3 * (z ||| t) + 1 *  ~~~(z &&&  ~~~z) + 3 * (z ^^^ t) - 2 *  ~~~(z ^^^ t) + 11 * t - 2 * (z |||  ~~~t) + 5 *  ~~~t + 8 *  ~~~(z ||| t) - 8 *  ~~~(z |||  ~~~t) - 12 * (z &&& t) =  - 1 *  ~~~z - 1 * z

theorem ashrslt_01_14_proof : ashrslt_01_14_before ⊑ ashrslt_01_14_after

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

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

theorem PR75692_1_proof : PR75692_1_before ⊑ PR75692_1_after

theorem mul_constant_partial_nuw_eq_thm (e e_1 : IntW 32) :
  icmp IntPred.eq (mul e_1 (const? 32 44)) (mul e (const? 32 44) { «nsw» := false, «nuw» := true }) ⊑
    icmp IntPred.eq (LLVM.and (LLVM.xor e_1 e) (const? 32 1073741823)) (const? 32 0)

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

theorem same_signbit_wrong_type_signed_proof : same_signbit_wrong_type_signed_before ⊑ same_signbit_wrong_type_signed_after

theorem eq_3210_proof : eq_3210_before ⊑ eq_3210_after

theorem test1_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(1#32 ≥ ↑32 ∨
        True ∧ (x.sshiftRight' 1#32 &&& 1431655765#32 ^^^ -1#32).saddOverflow 1#32 = true ∨
          True ∧ x.saddOverflow ((x.sshiftRight' 1#32 &&& 1431655765#32 ^^^ -1#32) + 1#32) = true) →
    ¬(1#32 ≥ ↑32 ∨ True ∧ x.ssubOverflow (x >>> 1#32 &&& 1431655765#32) = true) →
      x + ((x.sshiftRight' 1#32 &&& 1431655765#32 ^^^ -1#32) + 1#32) = x - (x >>> 1#32 &&& 1431655765#32)

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

theorem lshr_and_add_thm (e e_1 : IntW 8) :
  shl (add (LLVM.srem e_1 (const? 8 42)) (LLVM.and (lshr e (const? 8 3)) (const? 8 12))) (const? 8 3) ⊑
    add (LLVM.and e (const? 8 96)) (shl (LLVM.srem e_1 (const? 8 42)) (const? 8 3))

theorem or_or_logic_and_2_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 ||

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

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

theorem zext_add_proof : zext_add_before ⊑ zext_add_after

theorem bv_AndOrXor_2607 :
    ∀ (e e_1 : LLVM.IntW w),
      LLVM.xor (LLVM.or e (LLVM.xor e_1 (LLVM.const? w (-1)))) (LLVM.or (LLVM.xor e (LLVM.const? w (-1))) e_1) ⊑
        LLVM.xor e e_1

@[grind =, simp]
lemma RawCNFA.same_stateMax (m : RawCNFA A) x y (z : Std.HashMap (State × A) (Std.HashSet State)) :
    (RawCNFA.mk m.stateMax x y z).states = m.states

theorem sgt_and_min_logical_thm (e e_1 : IntW 9) :
  select (icmp IntPred.sgt e_1 e) (icmp IntPred.eq e_1 (const? 9 (-256))) (const? 1 0) ⊑ const? 1 0

theorem absdiff1_proof : absdiff1_before ⊑ absdiff1_after

theorem missed_const_prop_2002h12h05_proof : missed_const_prop_2002h12h05_before ⊑ missed_const_prop_2002h12h05_after

theorem pr89516_thm.extracted_1._5 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 <ₛ 0#8) = 1#1 →
    ¬(True ∧ 1#8 <<< x >>> x ≠ 1#8 ∨ x ≥ ↑8 ∨ (1#8 <<< x == 0 || 8 != 1 && 1#8 == intMin 8 && 1#8 <<< x == -1) = true) →
      ¬(True ∧ ((1#8).srem (1#8 <<< x)).uaddOverflow 0#8 = true) →
        (1#8).srem (1#8 <<< x) = (1#8).srem (1#8 <<< x) + 0#8

theorem mul_sdiv_cancel_of_dvd_of_ne {w : Nat} {x y : BitVec w}
  (h₁ : y.smod x = 0#_)
  (h₂ : y ≠ intMin w ∨ x ≠ -1#w) :
  x * y.sdiv x = y

theorem PR42691_7_logical_proof : PR42691_7_logical_before ⊑ PR42691_7_logical_after

theorem reduce_xor_common_op_commute0_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 4),
  x_2 ^^^ x_1 ^^^ x ||

theorem band_land_left1_proof : band_land_left1_before ⊑ band_land_left1_after

theorem sext_zext_ult_known_nonneg_thm (e e_1 : IntW 8) :
  icmp IntPred.ult (sext 32 e_1) (zext 32 (lshr e (const? 8 6))) ⊑
    icmp IntPred.ult e_1 (lshr e (const? 8 6))

theorem pr51551_proof : pr51551_before ⊑ pr51551_after

theorem test_with_even_proof : test_with_even_before ⊑ test_with_even_after

theorem select_icmp_eq_and_1_0_lshr_tv_thm (e e_1 : IntW 8) :
  select (icmp IntPred.ne (LLVM.and e_1 (const? 8 1)) (const? 8 0)) (lshr e (const? 8 2)) e ⊑
    lshr e (LLVM.and (shl e_1 (const? 8 1)) (const? 8 2))

@[bv_mba_preprocess]
theorem BitVec.ofNat_eq_ofInt (n w : Nat) :
    BitVec.ofNat w n = BitVec.ofInt w n

theorem rem_euclid_1_proof : rem_euclid_1_before ⊑ rem_euclid_1_after

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

theorem narrow_source_matching_signbits_proof : narrow_source_matching_signbits_before ⊑ narrow_source_matching_signbits_after

theorem test_proof : test_before ⊑ test_after

theorem and_zext_eq_even_commuted_thm (e : IntW 32) : LLVM.and (zext 32 (icmp IntPred.eq e (const? 32 2))) e ⊑ const? 32 0

theorem lshrugt_03_06_thm (e : IntW 4) : icmp IntPred.ugt (lshr e (const? 4 3)) (const? 4 6) ⊑ const? 1 0

theorem sext_sext_add_mismatched_types_proof : sext_sext_add_mismatched_types_before ⊑ sext_sext_add_mismatched_types_after

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

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

theorem test46_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬8#32 ≥ ↑32 → 8#32 ≥ ↑32 ∨ True ∧ (truncate 32 x <<< 8#32 &&& 10752#32).msb = true → False

theorem scalar_i32_shl_ult_const_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬11#32 ≥ ↑32 → ofBool (x <<< 11#32 <ᵤ 131072#32) = ofBool (x &&& 2097088#32 == 0#32)

theorem test_and1_logical_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sge e_1 (const? 32 0)) (icmp IntPred.slt e_1 (LLVM.and e (const? 32 2147483647)))
      (const? 1 0) ⊑
    select (icmp IntPred.sgt e_1 (const? 32 (-1))) (icmp IntPred.slt e_1 (LLVM.and e (const? 32 2147483647)))
      (const? 1 0)

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

theorem sgt_and_min_commute_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == BitVec.ofInt 8 (-128)) = 1#1 → ofBool (x <ₛ x_1) = 0#1

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

theorem test28_thm (e : IntW 32) :
  LLVM.xor (add e (const? 32 (-2147483647))) (const? 32 (-2147483648)) ⊑ add e (const? 32 1)

theorem srem_constant_dividend_select_of_constants_divisor_proof : srem_constant_dividend_select_of_constants_divisor_before ⊑ srem_constant_dividend_select_of_constants_divisor_after

theorem lshr_32_add_zext_trunc_proof : lshr_32_add_zext_trunc_before ⊑ lshr_32_add_zext_trunc_after

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

theorem e_1229 :
    1 *  ~~~(z ^^^ t) + 2 *  ~~~(z &&& t) - 2 *  ~~~t + 1 *  ~~~(z &&&  ~~~z) - 11 *  ~~~(z &&&  ~~~t) + 12 *  ~~~(z ||| t) + 8 *  ~~~(z |||  ~~~t) - 9 * (z &&&  ~~~t) + 1 * (z &&& t) =  - 11 * z + 3 * (z |||  ~~~t)

theorem udiv_x_by_const_cmp_x_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬123#32 = 0 → ofBool (x / 123#32 <ₛ x) = ofBool (0#32 <ₛ x)

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

theorem masked_and_notA_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 14#32 != x) &&& ofBool (x &&& 78#32 != x) = ofBool (x &&& BitVec.ofInt 32 (-79) != 0#32)

theorem test36_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ (x + 7#32 &&& 240#32).msb = true) →
    zeroExtend 64 x + 7#64 &&& 240#64 = zeroExtend 64 (x + 7#32 &&& 240#32)

theorem xor_of_icmps_proof : xor_of_icmps_before ⊑ xor_of_icmps_after

theorem test11_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(True ∧ (x &&& BitVec.ofInt 8 (-13) &&& 8#8 != 0) = true) →
    (x ||| 12#8) ^^^ 4#8 = x &&& BitVec.ofInt 8 (-13) ||

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

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

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

theorem cmpeq_xor_cst1_proof : cmpeq_xor_cst1_before ⊑ cmpeq_xor_cst1_after

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

theorem demorgan_nor_proof : demorgan_nor_before ⊑ demorgan_nor_after

theorem icmp_slt_sext_ne_zero_nofold_proof : icmp_slt_sext_ne_zero_nofold_before ⊑ icmp_slt_sext_ne_zero_nofold_after

theorem or_and1_proof : or_and1_before ⊑ or_and1_after

theorem scalar_i16_shl_and_signbit_eq_proof : scalar_i16_shl_and_signbit_eq_before ⊑ scalar_i16_shl_and_signbit_eq_after

theorem xor_or_thm (e : IntW 8) :
  LLVM.or (LLVM.xor e (const? 8 32)) (const? 8 7) ⊑ LLVM.xor (LLVM.and e (const? 8 (-8))) (const? 8 39)

theorem n10_thm (e : IntW 64) :
  sub (const? 64 1) (lshr e (const? 64 63)) ⊑ zext 64 (icmp IntPred.sgt e (const? 64 (-1)))

theorem ne_smin3_proof : ne_smin3_before ⊑ ne_smin3_after

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 7#32 != 1#32) ||

theorem and_xor_common_op_commute2_proof : and_xor_common_op_commute2_before ⊑ and_xor_common_op_commute2_after

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

theorem e_1008 :
    2 * (z ^^^ t) - 11 *  ~~~(z ^^^ t) + 4 * (z ||| t) + 3 *  ~~~(z &&&  ~~~z) + 8 *  ~~~(z ||| t) - 9 *  ~~~(z |||  ~~~t) - 9 * (z &&&  ~~~t) =  - 4 * (z &&& t)

theorem or_or_logic_and_2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), ¬x_1 ||

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

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

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

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

theorem or_xor_tree_0000_proof : or_xor_tree_0000_before ⊑ or_xor_tree_0000_after

theorem ugt_swap_and_not_min_logical_proof : ugt_swap_and_not_min_logical_before ⊑ ugt_swap_and_not_min_logical_after

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

theorem shl_trunc_smaller_lshr_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(3#32 ≥ ↑32 ∨ 5#8 ≥ ↑8) →
    ¬2#8 ≥ ↑8 → truncate 8 (x >>> 3#32) <<< 5#8 = truncate 8 x <<< 2#8 &&& BitVec.ofInt 8 (-32)

theorem test7_thm.extracted_1._1 : ∀ (x : BitVec 77), -1#77 - x = x ^^^ -1#77

theorem select_1_proof : select_1_before ⊑ select_1_after

theorem bv_AddSub_1574 :
    ∀ (e e_1 e_2 : LLVM.IntW w), LLVM.sub e_1 (LLVM.add e e_2) ⊑ LLVM.sub (LLVM.sub e_1 e_2) e

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

theorem t0_proof : t0_before ⊑ t0_after

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

theorem canonicalize_logic_first_or0_nswnuw_proof : canonicalize_logic_first_or0_nswnuw_before ⊑ canonicalize_logic_first_or0_nswnuw_after

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

theorem select_udiv_icmp_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 == 1#32) = 1#1 → ¬x_1 = 0 → x / x_1 = x

theorem xor_decide (p q : Prop) [dp : Decidable p] [Decidable q] :
    (decide p).xor (decide q) = decide (p ≠ q)

theorem test7_proof : test7_before ⊑ test7_after

theorem test3a_proof : test3a_before ⊑ test3a_after

theorem logic_or_logic_and_5_proof : logic_or_logic_and_5_before ⊑ logic_or_logic_and_5_after

theorem or_consts_proof : or_consts_before ⊑ or_consts_after

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

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

theorem and_ne_with_one_bit_diff_constants3_thm (e : IntW 8) :
  LLVM.and (icmp IntPred.ne e (const? 8 65)) (icmp IntPred.ne e (const? 8 (-63))) ⊑
    icmp IntPred.ne (LLVM.and e (const? 8 127)) (const? 8 65)

theorem ashr_mul_times_5_div_4_exact_2_proof : ashr_mul_times_5_div_4_exact_2_before ⊑ ashr_mul_times_5_div_4_exact_2_after

theorem select_icmp_ne_0_and_8_xor_1073741824_proof : select_icmp_ne_0_and_8_xor_1073741824_before ⊑ select_icmp_ne_0_and_8_xor_1073741824_after

theorem narrow_zext_sub_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 16),
  truncate 16 (zeroExtend 32 x_1 - x) = x_1 - truncate 16 x

theorem bitwise_and_logical_and_icmps_comm3_proof : bitwise_and_logical_and_icmps_comm3_before ⊑ bitwise_and_logical_and_icmps_comm3_after

theorem e_2304 :
     - 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 7 * (f ^^^ (d &&& (e ||| f))) + 1 * ((d &&& e) ^^^ (e ||| f)) - 2 * (f &&& (d |||  ~~~e)) + 2 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 2 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 5 * (d ||| (e ^^^ f)) - 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 7 * (e ^^^  ~~~(d ||| (e &&& f))) - 2 * (e ^^^ (d &&& ( ~~~e ||| f))) - 1 * (f ^^^ (d ||| ( ~~~e &&& f))) + 11 * (e &&&  ~~~f) + 3 * (e &&&  ~~~(d &&& f)) - 2 * (e ||| (d &&&  ~~~f)) - 1 *  ~~~(d &&&  ~~~f) - 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 2 * ( ~~~d ||| (e ||| f)) - 11 * (f ^^^ (d &&&  ~~~e)) - 1 * (e |||  ~~~(d |||  ~~~f)) + 4 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 2 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 3 *  ~~~(d ||| (e ^^^ f)) + 11 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 11 * (f ^^^  ~~~(d &&&  ~~~e)) + 5 * ((d |||  ~~~e) &&& (e ^^^ f)) - 6 * (f ^^^  ~~~(d ||| (e &&& f))) + 2 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 7 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 1 * (e ^^^ ( ~~~d ||| (e ||| f))) + 3 *  ~~~( ~~~d ||| (e ^^^ f)) + 3 * ( ~~~d &&& (e ^^^ f)) - 5 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 2 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 3 * (f ^^^  ~~~(d &&& (e &&& f))) + 2 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 5 * (f ^^^ (d ||| (e ||| f))) + 11 *  ~~~(d |||  ~~~e) - 5 * (d &&& e) - 3 *  ~~~(d ||| (e &&& f)) - 3 * ((d &&& e) |||  ~~~(e ||| f)) + 7 * ( ~~~e |||  ~~~(d ^^^ f)) - 1 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 1 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 11 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 6 * (d ^^^ ( ~~~e ||| f)) + 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (e ^^^  ~~~(d &&& (e ||| f))) - 2 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 3 *  ~~~(d ^^^ ( ~~~e ||| f)) - 1 * (e ^^^ f) - 1 * (d &&& ( ~~~e ||| f)) - 1 * (e |||  ~~~(d ||| f)) - 6 * (d &&& (e ||| f)) + 2 * (e ||| (d ^^^ f)) + 26 *  ~~~(d ||| (e ||| f)) - 5 *  ~~~(d ||| ( ~~~e ||| f)) + 20 *  ~~~( ~~~d ||| (e ||| f)) + 15 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 2 * ( ~~~d &&& ( ~~~e &&& f)) + 41 * ( ~~~d &&& (e &&& f)) + 18 * (d &&& ( ~~~e &&& f)) + 35 * (d &&& (e &&& f)) = 2 * (e ^^^  ~~~(d &&& f)) - 11 * (f ^^^  ~~~(d ||| ( ~~~e &&& f)))

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

theorem 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 src_is_mask_and_fail_mixed_proof : src_is_mask_and_fail_mixed_before ⊑ src_is_mask_and_fail_mixed_after

theorem land_bor_left1_proof : land_bor_left1_before ⊑ land_bor_left1_after

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

theorem ashr_1_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 8) (x_3 : BitVec 1),
  ¬x_3 = 1#1 → ¬x ≥ ↑8 → (x_1 ^^^ 123#8).sshiftRight' x ^^^ -1#8 = (x_1 ^^^ BitVec.ofInt 8 (-124)).sshiftRight' x

theorem test6_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬32#128 ≥ ↑128 → 32#64 ≥ ↑64 ∨ True ∧ zeroExtend 64 (truncate 32 (x >>> 32#64)) ≠ x >>> 32#64 → False

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

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

theorem shift_xor_multiuse_or_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (0#32 != x_1 &&& 4096#32) = 1#1 →
    ¬ofBool (x_1 &&& 4096#32 == 0#32) = 1#1 → (x ||| 2048#32) * (x ||| 2048#32) = x * (x ||| 2048#32)

theorem test24_proof : test24_before ⊑ test24_after

theorem udiv_shl_pair_const_proof : udiv_shl_pair_const_before ⊑ udiv_shl_pair_const_after

theorem bools2_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 icmp_eq_sext_ne_otherwise_proof : icmp_eq_sext_ne_otherwise_before ⊑ icmp_eq_sext_ne_otherwise_after

theorem add_const_sub_const_thm.extracted_1._1 : ∀ (x : BitVec 32), x + 8#32 - 2#32 = x + 6#32

theorem p0_proof : p0_before ⊑ p0_after

theorem lshr_mul_times_5_div_4_exact_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 >>> 2#32) = true) →
      (x * 5#32) >>> 2#32 = x + x >>> 2#32

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

theorem slt_or_not_max_proof : slt_or_not_max_before ⊑ slt_or_not_max_after

theorem t6_ugt_sgt_128_proof : t6_ugt_sgt_128_before ⊑ t6_ugt_sgt_128_after

theorem test_sdiv_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.sdiv x) = true →
      False

@[simp]
theorem scanl_succ (init : Bool) (f : Bool → Bool → Bool) (s : BitStream) : scanl init f s (n+1) = f (scanl init f s n) (s (n+1))

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

@[simp] theorem carry_fsmCarry' (initCarry : Bool)
    (x : Bool → BitStream) : ∀ (n : ℕ),
    FSM.carry (fsmCarry' initCarry) x (n + 1) =
      fun () =>
        BitStream.carry initCarry ((x true)) ((x false)) n

theorem test_const_shr_exact_and_1_ne_0_proof : test_const_shr_exact_and_1_ne_0_before ⊑ test_const_shr_exact_and_1_ne_0_after

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

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

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

theorem e_232 :
    5 *  ~~~(x ^^^ y) + 2 *  ~~~(x &&&  ~~~y) + 5 * (x |||  ~~~y) - 2 *  ~~~(x &&&  ~~~x) - 10 *  ~~~(x ||| y) - 14 * (x &&&  ~~~y) - 10 * (x &&& y) =  - 11 * (x ^^^ y) + 11 *  ~~~(x |||  ~~~y)

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

theorem e_2447 :
     - 1 * (e ^^^  ~~~(d &&& (e &&& f))) + 3 * ((d ^^^ e) &&& (d ^^^ f)) - 1 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 6 * (e |||  ~~~(d ||| f)) - 6 * (f ^^^ (d ||| ( ~~~e &&& f))) + 1 *  ~~~(d &&& ( ~~~e &&& f)) + 2 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 3 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 2 * (e ||| (d &&&  ~~~f)) + 4 * (f ^^^ ( ~~~d ||| (e ||| f))) - 2 * (f ^^^ (d ||| (e &&& f))) + 5 * (f ^^^ (d &&& (e ||| f))) + 11 * (f ^^^  ~~~(d ||| e)) + 3 * (f ^^^  ~~~(d &&& e)) - 5 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 11 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 2 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 1 *  ~~~(d ^^^ (e ^^^ f)) + 1 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 1 *  ~~~(d ||| (e ^^^ f)) - 1 * (d ^^^ e) + 2 * (f ^^^ (d &&&  ~~~e)) - 11 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (f &&& (d |||  ~~~e)) - 5 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 2 * ( ~~~d &&& (e ^^^ f)) + 7 * (f ^^^ (d ||| ( ~~~e ||| f))) + 1 *  ~~~(d ^^^ (e &&& f)) - 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 2 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 11 * ((d &&& f) |||  ~~~(e ||| f)) - 5 * (f &&& (d ^^^ e)) + 1 * (e ^^^ (d ||| ( ~~~e &&& f))) - 1 * (e ^^^ ( ~~~d &&& (e ||| f))) + 3 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 3 *  ~~~(e |||  ~~~f) - 2 * ((d &&&  ~~~e) ||| (e ^^^ f)) - 7 * ( ~~~d ||| (e ^^^ f)) - 2 * (f ^^^ (d ||| (e ||| f))) + 4 * ( ~~~d &&& (e ||| f)) + 1 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 6 * (d ||| f) - 2 * (e ^^^ (d ||| f)) + 1 * (f |||  ~~~(d ^^^ e)) + 3 * (e &&&  ~~~(d ^^^ f)) + 2 * (f ^^^  ~~~(d &&& (e ||| f))) - 5 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 4 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 6 * (d ^^^ ( ~~~e &&& f)) - 11 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 1 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 11 * (e ^^^ (d &&& (e ^^^ f))) - 2 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 1 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 5 * (e ||| (d ^^^ f)) + 2 *  ~~~( ~~~d &&& (e ||| f)) + 7 * e - 1 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 11 *  ~~~(d ^^^ (e ||| f)) - 3 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 3 * ( ~~~d &&& ( ~~~e ||| f)) + 3 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 1 *  ~~~(d ||| ( ~~~e &&& f)) + 11 * (d ||| ( ~~~e &&& f)) - 3 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * (d &&& f) + 5 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 19 *  ~~~(d ||| (e ||| f)) - 2 *  ~~~(d ||| ( ~~~e ||| f)) + 4 *  ~~~( ~~~d ||| (e ||| f)) + 8 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 14 * ( ~~~d &&& ( ~~~e &&& f)) + 15 * ( ~~~d &&& (e &&& f)) - 20 * (d &&& ( ~~~e &&& f)) - 30 * (d &&& (e &&& f)) =  - 5 * (e &&&  ~~~(d &&& f))

theorem slt_zero_ult_i1_proof : slt_zero_ult_i1_before ⊑ slt_zero_ult_i1_after

theorem main5f_like_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 &&& x_1 != x_2) ||

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

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

theorem icmp_slt_0_xor_icmp_sgt_neg2_i32_proof : icmp_slt_0_xor_icmp_sgt_neg2_i32_before ⊑ icmp_slt_0_xor_icmp_sgt_neg2_i32_after

theorem main7b_logical_proof : main7b_logical_before ⊑ main7b_logical_after

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

theorem R.trimTensor_append_not_zero (tensor : List Int) (x : Int) (hX : x ≠ 0) :
  trimTensor (tensor ++ [x]) = tensor ++ [x]

theorem or_not_xor_common_op_commute5_proof : or_not_xor_common_op_commute5_before ⊑ or_not_xor_common_op_commute5_after

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 narrow_sext_or_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 16),
  truncate 16 (signExtend 32 x_1 ||| x) = x_1 ||

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

theorem xor_icmp_to_icmp_add_thm (e : IntW 32) :
  LLVM.xor (icmp IntPred.sgt e (const? 32 3)) (icmp IntPred.slt e (const? 32 6)) ⊑
    icmp IntPred.ult (add e (const? 32 (-6))) (const? 32 (-2))

theorem uge_umin3_proof : uge_umin3_before ⊑ uge_umin3_after

theorem test_proof : test_before ⊑ test_after

theorem ite_eq_of_eq_true {cond t f : Circuit α} (h : cond.eval g = true) :
    (ite cond t f).eval g = t.eval g

theorem n3_constmask_samemask_thm (e e_1 : IntW 32) :
  add (LLVM.and e_1 (const? 32 65280)) (LLVM.and e (const? 32 65280)) ⊑
    add (LLVM.and e_1 (const? 32 65280)) (LLVM.and e (const? 32 65280)) { «nsw» := true, «nuw» := true }

theorem sub_shl_same_amount_nuw_proof : sub_shl_same_amount_nuw_before ⊑ sub_shl_same_amount_nuw_after

theorem mul_select_sext_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → 1#64 * signExtend 64 x = 0#64

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

theorem n6_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 1#32 != 0#32) = 1#1 → ¬ofBool (x &&& 1#32 == 0#32) = 1#1 → ¬2#32 ≥ ↑32 → 1#32 = x >>> 2#32 &&& 1#32

theorem neg_of_sub_from_constant_proof : neg_of_sub_from_constant_before ⊑ neg_of_sub_from_constant_after

theorem checkDCEasExpected :
  ex1_post_dce = ex1_post_dce_expected

theorem trunc_shl_31_i32_i64_proof : trunc_shl_31_i32_i64_before ⊑ trunc_shl_31_i32_i64_after

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

@[simp] theorem eval_trueUptoIncluding (n : Nat) (i : Nat) {env : Fin 0 → BitStream} :
    (trueUptoIncluding n).eval env i = decide (i ≤ n)

theorem not_invert_signbit_splat_mask1_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 8),
  ¬7#8 ≥ ↑8 →
    zeroExtend 16 (x_1.sshiftRight' 7#8 ^^^ -1#8) &&& x = x &&& zeroExtend 16 (signExtend 8 (ofBool (-1#8 <ₛ x_1)))

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

theorem and_xor_or4_proof : and_xor_or4_before ⊑ and_xor_or4_after

theorem test5_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ¬(zeroExtend 32 x ≥ ↑32 ∨ 32#32 <<< zeroExtend 32 x = 0) →
    ¬(True ∧ x.msb = true ∨ True ∧ 32#32 <<< zeroExtend 32 x >>> zeroExtend 32 x ≠ 32#32 ∨ zeroExtend 32 x ≥ ↑32) →
      x_1 % 32#32 <<< zeroExtend 32 x = x_1 &&& 32#32 <<< zeroExtend 32 x + -1#32

theorem fold_sext_to_and_wrong3_proof : fold_sext_to_and_wrong3_before ⊑ fold_sext_to_and_wrong3_after

theorem icmp_eq_x_invertable_y2_todo_proof : icmp_eq_x_invertable_y2_todo_before ⊑ icmp_eq_x_invertable_y2_todo_after

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

theorem modulo32_proof : modulo32_before ⊑ modulo32_after

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

theorem lshrult_03_07_thm.extracted_1._1 : ∀ (x : BitVec 4), ¬3#4 ≥ ↑4 → ofBool (x >>> 3#4 <ᵤ 7#4) = 1#1

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

theorem t0_thm (e e_1 e_2 e_3 : IntW 8) (e_4 : IntW 1) :
  select (LLVM.or (LLVM.xor e_4 (const? 1 1)) (icmp IntPred.eq e_3 e_2)) e_1 e ⊑
    select (LLVM.and (icmp IntPred.ne e_3 e_2) e_4) e e_1

theorem e_2417 :
    11 * (d ^^^ e) - 1 *  ~~~(d ^^^ (e ^^^ f)) - 5 * (d ^^^ (e ||| f)) - 1 * (e ^^^ (d ||| (e ^^^ f))) - 2 * (e ^^^  ~~~(d |||  ~~~f)) - 11 * (e ^^^ (d &&& ( ~~~e ||| f))) + 2 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 2 * (d ||| f) + 1 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 3 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 1 * (f &&& (d |||  ~~~e)) - 6 * (f |||  ~~~(d ^^^ e)) + 1 * ((d &&& e) |||  ~~~(e ^^^ f)) + 2 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 6 * (d &&&  ~~~e) - 2 * (d ||| ( ~~~e ||| f)) + 11 * (d ^^^ (e ^^^ f)) - 5 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 5 * ((d &&& f) ||| (e &&&  ~~~f)) + 1 * ((d ||| e) &&& (e ^^^ f)) - 6 *  ~~~(d ^^^ ( ~~~e ||| f)) + 4 * (f |||  ~~~(d ||| e)) + 5 * (e ||| (d &&&  ~~~f)) + 4 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 1 * ( ~~~d ||| (e &&& f)) + 2 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 2 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 4 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 1 *  ~~~d - 3 * ( ~~~d ||| ( ~~~e ||| f)) - 2 * (f ^^^  ~~~(d ||| (e &&& f))) + 7 * (f ^^^ (d &&&  ~~~e)) + 1 *  ~~~( ~~~d &&& (e &&& f)) - 11 * (f ^^^ (d ||| (e &&& f))) + 1 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 2 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 3 * (e &&& (d |||  ~~~f)) + 1 * ( ~~~d &&& (e ^^^ f)) - 1 *  ~~~(d &&& (e ||| f)) - 11 *  ~~~(e ||| f) - 5 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 3 * (f ^^^ (d ||| e)) + 1 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 2 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 11 * (d &&& f) - 2 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 3 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 11 *  ~~~( ~~~d ||| (e ^^^ f)) + 4 * ((d &&& e) ^^^ (e ||| f)) - 6 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 7 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) + 3 * ( ~~~f |||  ~~~(d ^^^ e)) + 2 * (e |||  ~~~(d |||  ~~~f)) + 2 * ( ~~~f &&& (d ^^^ e)) - 5 *  ~~~(d &&&  ~~~d) + 3 *  ~~~(e &&& f) - 5 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 11 * (e ^^^ (d &&& (e ||| f))) - 1 * (f ^^^ (d |||  ~~~e)) + 1 * (f &&& (d ^^^ e)) + 1 * (e ||| f) + 2 * ((d |||  ~~~e) &&& (e ^^^ f)) - 1 * (e &&& (d ^^^ f)) - 7 *  ~~~(d ^^^ (e ||| f)) - 1 * ( ~~~f &&&  ~~~(d ^^^ e)) + 41 *  ~~~(d ||| (e ||| f)) + 8 *  ~~~(d ||| ( ~~~e ||| f)) + 36 *  ~~~( ~~~d ||| (e ||| f)) + 26 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 7 * ( ~~~d &&& ( ~~~e &&& f)) + 27 * ( ~~~d &&& (e &&& f)) + 18 * (d &&& ( ~~~e &&& f)) - 21 * (d &&& (e &&& f)) = 1 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f)))

theorem e_2489 :
    2 * (f ^^^  ~~~(d |||  ~~~e)) - 1 *  ~~~( ~~~d ||| (e ^^^ f)) + 5 *  ~~~(e &&& f) + 7 * ( ~~~d &&& (e ^^^ f)) - 5 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 1 *  ~~~( ~~~d &&& (e &&& f)) - 1 * (e ^^^  ~~~(d &&& f)) + 7 * (e &&&  ~~~(d ^^^ f)) - 7 * (e &&& (d ^^^ f)) - 1 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 * (d ||| e) + 11 * (e ^^^ (d ||| ( ~~~e ||| f))) - 1 *  ~~~(e ^^^ f) - 1 * (e &&& (d |||  ~~~f)) - 7 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 3 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 2 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 4 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 6 * ((d &&& e) |||  ~~~(e ||| f)) - 2 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 1 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 1 * (e ^^^ f) + 1 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 1 * (e ^^^ ( ~~~d ||| (e &&& f))) - 7 *  ~~~(d ^^^ ( ~~~e &&& f)) - 2 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 2 * ( ~~~e &&& (d ^^^ f)) - 6 * (f ^^^ (d ||| ( ~~~e ||| f))) + 5 * (d &&&  ~~~e) + 7 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 2 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 2 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 2 *  ~~~(d |||  ~~~e) + 1 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 *  ~~~(d &&& (e ||| f)) + 1 * ((d &&& f) ||| (e &&&  ~~~f)) + 5 * ( ~~~d ||| ( ~~~e &&& f)) + 4 *  ~~~(d ||| ( ~~~e &&& f)) + 3 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 1 * d - 11 * (d ^^^ (e ||| f)) + 2 * (f ^^^ (d &&& (e ||| f))) + 2 * ((d &&& e) ^^^ (e ||| f)) + 5 * (f ^^^ ( ~~~d ||| (e ||| f))) + 1 * (f ^^^ (d |||  ~~~e)) - 6 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 4 * (f ^^^  ~~~(d &&& e)) - 3 * (f ^^^ (d &&& ( ~~~e ||| f))) - 7 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 3 * (d ||| (e ||| f)) - 7 * (f ^^^ (d &&& e)) + 3 *  ~~~(d ^^^ f) - 2 * ( ~~~f ||| (d ^^^ e)) - 1 *  ~~~(d ||| f) + 11 * ((d ^^^ e) &&& (d ^^^ f)) + 2 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 11 *  ~~~(d ^^^ (e ||| f)) - 2 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 11 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 2 * ((d &&& e) |||  ~~~(e |||  ~~~f)) - 3 * (f ^^^ ( ~~~d &&& (e ||| f))) - 1 *  ~~~(e |||  ~~~f) - 3 * (f &&& (d ||| e)) - 5 *  ~~~d - 7 *  ~~~(d &&&  ~~~e) + 4 * (f ||| (d ^^^ e)) - 11 * f - 3 * (e ^^^ (d |||  ~~~f)) - 5 *  ~~~f - 3 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 1 * (f ^^^ (d ||| (e ||| f))) - 11 * (e ^^^  ~~~(d &&&  ~~~f)) + 1 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 14 *  ~~~(d ||| (e ||| f)) - 22 *  ~~~(d ||| ( ~~~e ||| f)) - 26 *  ~~~( ~~~d ||| (e ||| f)) + 16 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 19 * ( ~~~d &&& ( ~~~e &&& f)) + 11 * ( ~~~d &&& (e &&& f)) - 5 * (d &&& ( ~~~e &&& f)) + 8 * (d &&& (e &&& f)) =  - 2 * ( ~~~d ||| ( ~~~e ||| f))

@[simp]
theorem Factor.denote_width_zero  (f : Factor) (env : Env 0) : f.denote env = 0

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

theorem fold_icmp_shl_nuw_c2_thm (e : IntW 32) :
  icmp IntPred.ult (shl (const? 32 16) e { «nsw» := false, «nuw» := true }) (const? 32 64) ⊑
    icmp IntPred.ult e (const? 32 2)

theorem or_simplify_ugt_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x &&& BitVec.ofInt 8 (-2) <ᵤ x_1 ||| 1#8 ||| x &&& BitVec.ofInt 8 (-2)) =
    ofBool (x &&& BitVec.ofInt 8 (-2) <ᵤ x_1 ||| x ||| 1#8)

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

theorem sext_zext_ne_known_nonneg_thm (e e_1 : IntW 8) :
  icmp IntPred.ne (sext 32 e_1) (zext 32 (LLVM.udiv e (const? 8 6))) ⊑
    icmp IntPred.ne e_1 (LLVM.udiv e (const? 8 6))

theorem src_srem_shl_demand_max_mask_proof : src_srem_shl_demand_max_mask_before ⊑ src_srem_shl_demand_max_mask_after

theorem src_is_notmask_ashr_proof : src_is_notmask_ashr_before ⊑ src_is_notmask_ashr_after

theorem PR24873_proof : PR24873_before ⊑ PR24873_after

theorem sge_or_not_max_commute_proof : sge_or_not_max_commute_before ⊑ sge_or_not_max_commute_after

theorem PR1817_1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x <ₛ 10#32) &&& ofBool (x <ᵤ 10#32) = ofBool (x <ᵤ 10#32)

theorem add_of_selects_thm.extracted_1._3 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → BitVec.ofInt 32 (-2) + 2#32 = 0#32

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

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

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

theorem ult_swap_or_not_max_commute_logical_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x != -1#8) = 1#1 → 1#1 = ofBool (x != -1#8)

@[simp]
lemma BitVecs'.transport_getElem' {bvs' : BitVecs' m} (f : Fin n → Fin m) (i : Nat) (h : i < bvs'.length) :
    (bvs'.transport f)[i]'(by simp_all) = (bvs'[i]'h).transport f

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

theorem test1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 ^^^ 5#32 == 10#32) ||

theorem udiv_i80_thm.extracted_1._2 : ∀ (x : BitVec 80),
  ¬(2#80 ≥ ↑80 ∨ 100#80 = 0) → ¬400#80 = 0 → x >>> 2#80 / 100#80 = x / 400#80

theorem e_1544 :
     - 7 *  ~~~(a ^^^ b) + 7 * ((a ^^^ b) |||  ~~~(a ^^^ c)) - 5 * ((a &&& c) ^^^ (a ^^^ (b &&& c))) + 3 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) - 6 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) - 3 *  ~~~(b ^^^ c) - 8 *  ~~~(a ||| ( ~~~b ||| c)) + 7 *  ~~~( ~~~a ||| (b ||| c)) + 11 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 3 * ( ~~~a &&& ( ~~~b &&& c)) - 9 * ( ~~~a &&& (b &&& c)) - 10 * (a &&& ( ~~~b &&& c)) + 14 * (a &&& (b &&& c)) =  - 7 * ((a &&& c) ^^^ (b ||| c))

theorem lshrugt_02_11_proof : lshrugt_02_11_before ⊑ lshrugt_02_11_after

theorem select_add_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 1), ¬x_1 = 1#1 → x = x + 0#64

theorem no_shift_xor_multiuse_cmp_with_xor_proof : no_shift_xor_multiuse_cmp_with_xor_before ⊑ no_shift_xor_multiuse_cmp_with_xor_after

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

theorem uge_zext_proof : uge_zext_before ⊑ uge_zext_after

theorem bool_zext_thm (e : IntW 1) : lshr (sext 16 e) (const? 16 15) ⊑ zext 16 e

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

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

theorem lor_lor_right2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1), x_1 = 1#1 ∨ x = 1#1 → ¬x_1 = 1#1 → 1#1 = x

theorem xor_sext_sext_proof : xor_sext_sext_before ⊑ xor_sext_sext_after

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

theorem basic_preserve_nsw_thm (e e_1 : IntW 8) :
  LLVM.xor (add (LLVM.xor e_1 (const? 8 (-1))) e { «nsw» := true, «nuw» := false }) (const? 8 (-1)) ⊑
    sub e_1 e { «nsw» := true, «nuw» := false }

theorem no_shift_xor_multiuse_cmp_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.or e_2 (const? 32 4096)))
      (select (icmp IntPred.ne (const? 32 0) (LLVM.and e_3 (const? 32 4096))) e_1 e) ⊑
    mul (LLVM.or e_2 (LLVM.xor (LLVM.and e_3 (const? 32 4096)) (const? 32 4096)))
      (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) e e_1)

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

theorem udiv_x_by_const_cmp_x_proof : udiv_x_by_const_cmp_x_before ⊑ udiv_x_by_const_cmp_x_after

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

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

theorem positive_with_signbit_proof : positive_with_signbit_before ⊑ positive_with_signbit_after

theorem neg_mask_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 32),
  ¬(True ∧ x_1.ssubOverflow (signExtend 32 x) = true ∨
        15#16 ≥ ↑16 ∨ True ∧ (0#32).ssubOverflow (zeroExtend 32 (x >>> 15#16)) = true) →
    ofBool (x <ₛ 0#16) = 1#1 → True ∧ x_1.ssubOverflow (signExtend 32 x) = true → False

theorem bools2_logical_commute1_thm.extracted_1._13 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 → ¬x_1 ^^^ 1#1 = 1#1 → x_1 = 1#1 → 1#1 = x_2

theorem mul_setnzV_unkV_nuw_eq_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ (x_1 ||| 2#8).umulOverflow x = true) → ofBool ((x_1 ||| 2#8) * x == 0#8) = ofBool (x == 0#8)

theorem test_proof : test_before ⊑ test_after

theorem and_ne_with_diff_one_proof : and_ne_with_diff_one_before ⊑ and_ne_with_diff_one_after

theorem ashrslt_01_12_proof : ashrslt_01_12_before ⊑ ashrslt_01_12_after

theorem test9_proof : test9_before ⊑ test9_after

@[simp]
lemma RawCNFA.lift_processTrans_spec {m : CNFA n₁} {f : Fin n₁ → Fin n₂} :
    s' ∈ (lift.processTrans m.m f trs s₀ a).getD (s, b) ∅ ↔
      s' ∈ trs.getD (s, b) ∅ ∨ s = s₀ ∧ a = b ∧ s' ∈ m.m.tr s (b.transport f)

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

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

theorem ashrslt_03_02_proof : ashrslt_03_02_before ⊑ ashrslt_03_02_after

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

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

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

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

theorem and_xor_or7_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 64),
  ¬(x_2 = 0 ∨ x_1 = 0 ∨ x = 0 ∨ x_2 = 0) → x_2 = 0 ∨ x_1 = 0 → False

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

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

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

theorem not_and_and_or_not_or_or_commute1_and_proof : not_and_and_or_not_or_or_commute1_and_before ⊑ not_and_and_or_not_or_or_commute1_and_after

theorem add_or_and_proof : add_or_and_before ⊑ add_or_and_after

theorem sub_eq_add_not_add_one :
    x - y = x + ~~~ y + 1

theorem and_ne_with_diff_one_logical_proof : and_ne_with_diff_one_logical_before ⊑ and_ne_with_diff_one_logical_after

theorem main12_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (truncate 16 x <ₛ 0#16) ||

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 multiuse_lshr_lshr_thm.extracted_1._2 : ∀ (x : BitVec 9),
  ¬(2#9 ≥ ↑9 ∨ 2#9 ≥ ↑9 ∨ 3#9 ≥ ↑9) → ¬(2#9 ≥ ↑9 ∨ 5#9 ≥ ↑9) → x >>> 2#9 * x >>> 2#9 >>> 3#9 = x >>> 2#9 * x >>> 5#9

theorem main3c_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 7#32 != 0#32) ||

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

theorem substitute_constant_or_ne_swap_sle_proof : substitute_constant_or_ne_swap_sle_before ⊑ substitute_constant_or_ne_swap_sle_after

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

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

theorem lshrult_02_13_proof : lshrult_02_13_before ⊑ lshrult_02_13_after

theorem lshr_not_nneg2_proof : lshr_not_nneg2_before ⊑ lshr_not_nneg2_after

theorem AvoidCollision_setWidth_ushiftRight_eq_extractLsb {b : BitVec w} : (b >>> w').setWidth w'' = b.extractLsb' w' w''

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

@[simp]
theorem none_left :
  Refinement none x?

theorem not_lshr_const_proof : not_lshr_const_before ⊑ not_lshr_const_after

theorem absdiff_proof : absdiff_before ⊑ absdiff_after

theorem lshr_add_proof : lshr_add_before ⊑ lshr_add_after

theorem sext_sub_const_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → 42#64 - signExtend 64 x = 43#64

theorem n9_wrong_x2_thm (e e_1 : IntW 8) :
  select (icmp IntPred.eq (LLVM.and e_1 (const? 8 15)) (const? 8 0)) e
      (LLVM.and (add e (const? 8 16)) (const? 8 (-16))) ⊑
    select (icmp IntPred.eq (LLVM.and e_1 (const? 8 15)) (const? 8 0)) e
      (add (LLVM.and e (const? 8 (-16))) (const? 8 16))

theorem ashrsgt_01_06_exact_proof : ashrsgt_01_06_exact_before ⊑ ashrsgt_01_06_exact_after

theorem icmp_slt_sext_ne_otherwise_nofold_proof : icmp_slt_sext_ne_otherwise_nofold_before ⊑ icmp_slt_sext_ne_otherwise_nofold_after

theorem t3_ult_sgt_neg1_proof : t3_ult_sgt_neg1_before ⊑ t3_ult_sgt_neg1_after

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

theorem lsb_mask_sign_zext_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → (x + -1#32 &&& (x ^^^ -1#32)) >>> 31#32 = zeroExtend 32 (ofBool (x == 0#32))

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

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

theorem logical_or_bitwise_or_icmps_comm2_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8),
  ¬ofBool (x_2 &&& 1#8 == 0#8) ||

theorem icmp_ne_sext_ne_allones_thm (e : IntW 32) :
  icmp IntPred.ne (sext 32 (icmp IntPred.ne e (const? 32 (-1)))) e ⊑ const? 1 1

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

theorem t9_c0_c2_thm.extracted_1._1 : ∀ (x : BitVec 8), 42#8 - x - 24#8 = 18#8 - x

@[simp]
theorem eval_repeatN_succ (b : Bool) (n : Nat) (env : Unit → BitStream) :
  (repeatN b (n + 1)).eval env =
  BitStream.concat b ((repeatN b n).eval env)

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

theorem negate_sdiv_thm (e e_1 : IntW 8) :
  sub e_1 (LLVM.sdiv e (const? 8 42)) ⊑ add (LLVM.sdiv e (const? 8 (-42))) e_1

theorem icmp_mul_nsw_sge_proof : icmp_mul_nsw_sge_before ⊑ icmp_mul_nsw_sge_after

theorem in_constant_mone_vary_proof : in_constant_mone_vary_before ⊑ in_constant_mone_vary_after

theorem icmp_power2_and_icmp_shifted_mask_2147483648_805306368_proof : icmp_power2_and_icmp_shifted_mask_2147483648_805306368_before ⊑ icmp_power2_and_icmp_shifted_mask_2147483648_805306368_after

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

theorem test6a_thm.extracted_1._1 : ∀ (x : BitVec 55), ¬1#55 ≥ ↑55 → (x * 3#55) <<< 1#55 = x * 6#55

theorem t0_proof : t0_before ⊑ t0_after

theorem e_1193 :
     - 6 *  ~~~(z &&&  ~~~z) - 7 * z - 3 * (z ^^^ t) - 6 *  ~~~z + 13 *  ~~~(z ||| t) + 15 *  ~~~(z |||  ~~~t) + 17 * (z &&&  ~~~t) + 14 * (z &&& t) = 1 * (z |||  ~~~t)

theorem icmp_shl_ne_2_proof : icmp_shl_ne_2_before ⊑ icmp_shl_ne_2_after

theorem neg_sgt_n1_proof : neg_sgt_n1_before ⊑ neg_sgt_n1_after

theorem select_icmp_ne_0_and_8_xor_1073741824_proof : select_icmp_ne_0_and_8_xor_1073741824_before ⊑ select_icmp_ne_0_and_8_xor_1073741824_after

theorem ashr_exact_proof : ashr_exact_before ⊑ ashr_exact_after

theorem e_1383 :
    11 * (z |||  ~~~t) + 3 * (z ||| t) + 3 *  ~~~(z &&&  ~~~t) + 4 * z - 6 *  ~~~t + 1 * t + 14 *  ~~~(z ||| t) + 15 *  ~~~(z |||  ~~~t) - 1 * (z &&&  ~~~t) - 22 * (z &&& t) = 11 *  ~~~z + 11 *  ~~~(z &&& t)

theorem test20_proof : test20_before ⊑ test20_after

theorem shl_ashr_pow2_const_case1_proof : shl_ashr_pow2_const_case1_before ⊑ shl_ashr_pow2_const_case1_after

theorem icmp_select_implied_cond_ne_proof : icmp_select_implied_cond_ne_before ⊑ icmp_select_implied_cond_ne_after

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

theorem invert_both_cmp_operands_complex_thm (e e_1 e_2 : IntW 32) (e_3 : IntW 1) :
  icmp IntPred.sle (select e_3 (add e_2 (LLVM.xor e_1 (const? 32 (-1)))) (LLVM.xor e (const? 32 (-1))))
      (LLVM.xor e_2 (const? 32 (-1))) ⊑
    icmp IntPred.sge (select e_3 (sub e_1 e_2) e) e_2

theorem trunc_nuw_xor_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ zeroExtend 8 (truncate 1 (x_1 ^^^ x)) ≠ x_1 ^^^ x) → truncate 1 (x_1 ^^^ x) = ofBool (x_1 != x)

@[grind =, simp, aesop 50% unsafe]
lemma states_addManyTrans (m : RawCNFA A) (as : List A) (s1 s2 : State) :
    (m.addManyTrans as s1 s2).states = m.states

theorem ashr_eq_both_equal_proof : ashr_eq_both_equal_before ⊑ ashr_eq_both_equal_after

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

theorem select_replace_one_use_proof : select_replace_one_use_before ⊑ select_replace_one_use_after

theorem lowmask_add_zext_wrong_mask_proof : lowmask_add_zext_wrong_mask_before ⊑ lowmask_add_zext_wrong_mask_after

theorem and_xor_commute2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(x_1 = 0 ∨ x = 0 ∨ x = 0) →
    ¬(x = 0 ∨ x_1 = 0) → 42#32 / x_1 &&& 42#32 / x ^^^ 42#32 / x = 42#32 / x &&& (42#32 / x_1 ^^^ -1#32)

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

theorem sle_swap_or_not_min_commute_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 != BitVec.ofInt 8 (-128)) = 1#1 → ofBool (x_1 ≤ₛ x) = 1#1

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 shl_add_proof : shl_add_before ⊑ shl_add_after

theorem test56_proof : test56_before ⊑ test56_after

theorem not_or_or_and_no_and_commute1_proof : not_or_or_and_no_and_commute1_before ⊑ not_or_or_and_no_and_commute1_after

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

theorem icmp_eq_or_z_or_pow2orz_fail_logic_or_proof : icmp_eq_or_z_or_pow2orz_fail_logic_or_before ⊑ icmp_eq_or_z_or_pow2orz_fail_logic_or_after

theorem ashr_mul_sign_bits_proof : ashr_mul_sign_bits_before ⊑ ashr_mul_sign_bits_after

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

theorem icmp_eq_zext_ne_non_boolean_proof : icmp_eq_zext_ne_non_boolean_before ⊑ icmp_eq_zext_ne_non_boolean_after

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 icmp_shl_nsw_sge0_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ (x <<< 21#32).sshiftRight' 21#32 ≠ x ∨ 21#32 ≥ ↑32) → ofBool (0#32 ≤ₛ x <<< 21#32) = ofBool (-1#32 <ₛ x)

theorem 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 ashrsgt_03_03_exact_thm (e : IntW 4) :
  icmp IntPred.sgt (ashr e (const? 4 3) { «exact» := true }) (const? 4 3) ⊑ const? 1 0

theorem ashr_exact_add_nuw_proof : ashr_exact_add_nuw_before ⊑ ashr_exact_add_nuw_after

theorem test7_proof : test7_before ⊑ test7_after

theorem no_shift_no_xor_multiuse_cmp_with_xor_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.xor e_2 (const? 32 4096)))
      (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) e_1 e) ⊑
    mul (LLVM.xor 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 trunc_shl_15_i16_i32_proof : trunc_shl_15_i16_i32_before ⊑ trunc_shl_15_i16_i32_after

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

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

theorem splat_mul_unknown_lz_proof : splat_mul_unknown_lz_before ⊑ splat_mul_unknown_lz_after

theorem neg_or_ashr_i32_commute_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬((x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true ∨
        (x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true ∨ 31#32 ≥ ↑32) →
    ¬(x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true →
      ((42#32).sdiv x ||| 0#32 - (42#32).sdiv x).sshiftRight' 31#32 = signExtend 32 (ofBool ((42#32).sdiv x != 0#32))

@[simp] theorem carry_succ (initCarry : Bool) (x y : BitStream) :
    (carry initCarry x y (i + 1)) =
  let out

@[simp] theorem hasType_push_of_neq {Γ : Context Ty} (h : w ≠ v) :
    (Γ.push v ty).hasType w ty' ↔ Γ.hasType w ty'

theorem ashr_known_pos_exact_proof : ashr_known_pos_exact_before ⊑ ashr_known_pos_exact_after

theorem test10_thm (e : IntW 16) : trunc 16 (sext 32 e) ⊑ e

theorem and_zext_zext_proof : and_zext_zext_before ⊑ and_zext_zext_after

theorem e_217 :
     - 1 * x - 11 *  ~~~x - 1 * y - 1 *  ~~~(x &&&  ~~~x) + 12 *  ~~~(x ||| y) + 13 *  ~~~(x |||  ~~~y) + 3 * (x &&& y) =  - 2 * (x &&&  ~~~y)

theorem e_2149 :
     - 1 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 2 *  ~~~( ~~~d &&& (e ||| f)) + 2 * (e ^^^  ~~~(d ||| f)) + 1 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 4 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 1 * ((d ^^^ e) &&& (d ^^^ f)) - 1 * ( ~~~d &&& ( ~~~e ||| f)) - 1 * ( ~~~d ||| (e ||| f)) - 1 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 1 * (e &&& (d ||| f)) + 11 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (e ^^^ (d ||| (e ||| f))) + 1 *  ~~~(d |||  ~~~e) + 3 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 3 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 6 *  ~~~(d ^^^ (e ||| f)) - 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 1 *  ~~~e + 7 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 *  ~~~(e ||| f) + 1 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 4 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 4 * (f |||  ~~~(d ||| e)) - 5 * (f &&&  ~~~(d &&& e)) - 11 * (e ^^^ ( ~~~d ||| (e &&& f))) - 1 * (d |||  ~~~e) - 3 *  ~~~(d ||| (e ^^^ f)) + 1 * (f ^^^ (d ||| ( ~~~e &&& f))) - 11 * (e ^^^ (d &&& (e ||| f))) + 2 * (e ^^^  ~~~(d &&& (e &&& f))) - 1 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 6 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 2 * ( ~~~e ||| (d ^^^ f)) + 4 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) + 2 * (d &&& (e ||| f)) + 5 * (f &&& (d ^^^ e)) + 3 *  ~~~(d &&& (e ^^^ f)) - 7 *  ~~~(d &&& f) + 11 *  ~~~( ~~~d &&& (e ^^^ f)) - 3 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 2 * (d &&& ( ~~~e ||| f)) - 5 *  ~~~(e |||  ~~~f) - 18 *  ~~~( ~~~d ||| (e ||| f)) + 1 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 31 * ( ~~~d &&& (e &&& f)) + 5 * (d &&& ( ~~~e &&& f)) - 21 * (d &&& (e &&& f)) =  - 7 *  ~~~(d ||| ( ~~~e ||| f)) - 15 * ( ~~~d &&& ( ~~~e &&& f))

theorem sext_zext_nneg_uge_op0_wide_proof : sext_zext_nneg_uge_op0_wide_before ⊑ sext_zext_nneg_uge_op0_wide_after

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

theorem shl_add_and_fail_mismatch_shift_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(1#8 ≥ ↑8 ∨ 1#8 ≥ ↑8) → 1#8 ≥ ↑8 ∨ 1#8 ≥ ↑8 ∨ True ∧ (x >>> 1#8).uaddOverflow 123#8 = true → False

theorem e_2159 :
     - 2 * (e &&&  ~~~(d ^^^ f)) + 1 * (e ^^^  ~~~(d ||| (e &&& f))) - 7 *  ~~~(d ||| e) - 3 * (f |||  ~~~(d ^^^ e)) - 1 * (f ^^^  ~~~(d &&& (e &&& f))) + 11 * (e ^^^ (d &&& f)) - 11 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 3 * (e ^^^ (d &&& (e ||| f))) - 1 * ((d ^^^ e) &&& (d ^^^ f)) + 2 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 2 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 2 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 1 * ( ~~~f &&& (d ^^^ e)) + 2 * (d |||  ~~~e) + 3 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 6 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 5 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 2 *  ~~~(d ^^^ f) + 4 * (e ^^^ (d ||| (e &&& f))) + 7 * ((d &&& e) ^^^ (e ||| f)) + 5 *  ~~~(d |||  ~~~e) + 1 * (d &&& (e ||| f)) + 5 * ( ~~~d &&& (e ||| f)) + 1 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 6 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 11 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * ((d &&& e) ^^^ (e |||  ~~~f)) + 4 *  ~~~(d ^^^ ( ~~~e ||| f)) - 3 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 1 * (f ^^^ (d ||| ( ~~~e ||| f))) + 5 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 * (d &&& (e ^^^ f)) + 4 * ( ~~~e &&& (d ^^^ f)) + 3 * ((d &&& f) |||  ~~~(e ||| f)) + 5 * ( ~~~d ||| ( ~~~e ||| f)) - 1 * (f ^^^ (d ||| ( ~~~e &&& f))) - 1 *  ~~~(d ^^^ e) + 1 *  ~~~(d &&& f) - 7 *  ~~~f + 1 * (f &&&  ~~~(d &&& e)) + 24 *  ~~~(d ||| (e ||| f)) - 23 *  ~~~(d ||| ( ~~~e ||| f)) - 3 *  ~~~( ~~~d ||| (e ||| f)) + 10 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 12 * ( ~~~d &&& ( ~~~e &&& f)) - 14 * ( ~~~d &&& (e &&& f)) - 8 * (d &&& ( ~~~e &&& f)) - 16 * (d &&& (e &&& f)) =  - 1 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 1 * (f &&& (d |||  ~~~e))

theorem test20_thm (e : IntW 32) :
  zext 32 (icmp IntPred.ne (LLVM.and e (const? 32 1)) (const? 32 0)) ⊑ LLVM.and e (const? 32 1)

theorem select_icmp_eq_and_1_0_xor_2_proof : select_icmp_eq_and_1_0_xor_2_before ⊑ select_icmp_eq_and_1_0_xor_2_after

theorem multiuse_lshr_lshr_proof : multiuse_lshr_lshr_before ⊑ multiuse_lshr_lshr_after

theorem test_shl__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)))
        (LLVM.or e (const? 32 (-83886080))))
      (shl (LLVM.or e (const? 32 (-83886080))) (const? 32 2)) ⊑
    mul
      (mul (shl (LLVM.or e (const? 32 (-83886080))) (const? 32 2) { «nsw» := true, «nuw» := false })
        (LLVM.or e (const? 32 (-83886080))))
      (shl (LLVM.or e (const? 32 (-83886080))) (const? 32 2) { «nsw» := true, «nuw» := false })

theorem or_nosignbit_ashr_thm (e : IntW 32) :
  ashr (LLVM.or e (const? 32 2147418112)) (const? 32 8) ⊑ LLVM.or (ashr e (const? 32 8)) (const? 32 8388352)

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

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

theorem test_sext1_proof : test_sext1_before ⊑ test_sext1_after

@[simp] theorem Valuation.cons_append {V : Γ.Valuation} {W : Δ.Valuation} {x : ⟦t⟧} :
    HAppend.hAppend (α := Valuation no_index _) (γ := Valuation no_index _)
      (x ::ᵥ V) W -- x::ᵥV ++ W
    = x ::ᵥ (V ++ W)

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

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

theorem canonicalize_logic_first_xor_0_nsw_proof : canonicalize_logic_first_xor_0_nsw_before ⊑ canonicalize_logic_first_xor_0_nsw_after

theorem masked_and_notA_proof : masked_and_notA_before ⊑ masked_and_notA_after

theorem test13_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬zeroExtend 128 x &&& 31#128 ≥ ↑128 → True ∧ (x &&& 31#32).msb = true ∨ zeroExtend 64 (x &&& 31#32) ≥ ↑64 → False

theorem test31 (w : Nat) (x : BitVec w) : x &&& x = x

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

theorem positive_sameconst_shlnuw_proof : positive_sameconst_shlnuw_before ⊑ positive_sameconst_shlnuw_after

theorem ashr_ugt_15_proof : ashr_ugt_15_before ⊑ ashr_ugt_15_after

theorem n2_badmask_proof : n2_badmask_before ⊑ n2_badmask_after

theorem t2_proof : t2_before ⊑ t2_after

theorem eq_umax1_proof : eq_umax1_before ⊑ eq_umax1_after

theorem p0_proof : p0_before ⊑ p0_after

@[simp]
lemma neg_accepts (M : NFA' n) :
    M.neg.accepts = M.acceptsᶜ

theorem e_1878 :
     - 1 * (c &&& (a |||  ~~~b)) - 2 * (b ^^^ (a &&&  ~~~c)) + 3 * ( ~~~(a ||| b) ||| (b ^^^ c)) + 3 * (b ||| (a ^^^ c)) + 1 * (c ^^^  ~~~(a |||  ~~~b)) + 1 * (a ^^^ ( ~~~b ||| c)) - 5 * (b ^^^  ~~~(a |||  ~~~c)) + 1 * ( ~~~c &&&  ~~~(a ^^^ b)) - 1 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) - 7 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 7 *  ~~~( ~~~a ||| (b ^^^ c)) + 11 * ( ~~~(a ||| b) |||  ~~~(b ^^^ c)) - 1 * (a &&&  ~~~c) + 11 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) + 2 * (b &&& (a |||  ~~~c)) + 11 * (b ^^^ (a ||| (b &&& c))) - 3 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) - 2 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 4 *  ~~~(a &&& b) + 11 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) + 7 * (a ^^^ (b &&& c)) - 6 *  ~~~(a ^^^ b) + 4 *  ~~~(a ||| b) + 1 * ((a &&& b) ^^^ (b |||  ~~~c)) + 2 *  ~~~(a &&& c) - 5 * (b ^^^  ~~~(a &&& c)) - 3 * (b &&& (a ||| c)) - 1 * (b ^^^  ~~~(a ||| (b &&& c))) + 1 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) - 2 * (c &&&  ~~~(a &&& b)) + 1 *  ~~~(a ||| (b ^^^ c)) - 7 * (a &&& ( ~~~b ||| c)) + 11 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) - 7 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) - 5 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) + 5 * ((a &&& b) ||| (b ^^^ c)) + 4 * ( ~~~a &&& (b ^^^ c)) - 2 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) + 1 *  ~~~(b |||  ~~~c) - 30 *  ~~~(a ||| (b ||| c)) - 19 *  ~~~(a ||| ( ~~~b ||| c)) - 14 *  ~~~( ~~~a ||| (b ||| c)) + 1 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 30 * ( ~~~a &&& ( ~~~b &&& c)) - 28 * ( ~~~a &&& (b &&& c)) - 41 * (a &&& ( ~~~b &&& c)) + 18 * (a &&& (b &&& c)) = 1 * (c ^^^ (a |||  ~~~b))

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

theorem add_or_sub_comb_i128_commuted3_nuw_nsw_thm (e : IntW 128) :
  add (LLVM.or (mul e e) (sub (const? 128 0) (mul e e))) (mul e e) { «nsw» := true, «nuw» := true } ⊑ mul e e

theorem src2_proof : src2_before ⊑ src2_after

theorem ne_21_comm_ne2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(16#32 ≥ ↑32 ∨ 16#32 ≥ ↑32 ∨ 8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32) →
    ¬(8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32) →
      ofBool (truncate 8 (x_1 >>> 16#32) != truncate 8 (x >>> 16#32)) ||

theorem t1_thm.extracted_1._1 : ∀ (x : BitVec 4),
  (x ||| BitVec.ofInt 4 (-4)) ^^^ BitVec.ofInt 4 (-6) = x &&& 3#4 ^^^ 6#4

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_3_proof : masked_icmps_mask_notallzeros_bmask_mixed_swapped_3_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_swapped_3_after

theorem icmp_ne_sext_slt_otherwise_nofold_thm (e : IntW 32) :
  icmp IntPred.ne (sext 32 (icmp IntPred.slt e (const? 32 2))) e ⊑
    icmp IntPred.ne e (sext 32 (icmp IntPred.slt e (const? 32 2)))

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

theorem positive_sameconst_ashrexact_thm (e : IntW 8) : shl (ashr e (const? 8 3) { «exact» := true }) (const? 8 3) ⊑ e

theorem no_masks_with_logical_or2_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 != -1#32) = 1#1 →
    ofBool (x_2 &&& x != -1#32) = 1#1 → ofBool (x_1 != 63#32) ||

theorem bv_AndOrXor_144 :
    ∀ (e e_1 e_2 : LLVM.IntW w), LLVM.and (LLVM.or e e_1) e_2 ⊑ LLVM.and (LLVM.or e (LLVM.and e_1 e_2)) e_2

theorem test_proof : test_before ⊑ test_after

theorem e_1059 :
     - 2 *  ~~~(z ^^^ t) + 1 *  ~~~t - 3 * z - 5 *  ~~~(z &&&  ~~~z) + 6 *  ~~~(z ||| t) + 7 * (z &&&  ~~~t) + 10 * (z &&& t) =  - 5 *  ~~~(z |||  ~~~t)

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

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

theorem not_and_and_or_not_or_or_commute1_proof : not_and_and_or_not_or_or_commute1_before ⊑ not_and_and_or_not_or_or_commute1_after

theorem main2_logical_proof : main2_logical_before ⊑ main2_logical_after

theorem foo_thm (e : IntW 1) : e ⊑ e

theorem test_invert_demorgan_or3_proof : test_invert_demorgan_or3_before ⊑ test_invert_demorgan_or3_after

theorem p_constmask_proof : p_constmask_before ⊑ p_constmask_after

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

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

theorem no_reassoc_add_none_nuw_thm (e : IntW 32) :
  add (add e (const? 32 4) { «nsw» := false, «nuw» := true }) (const? 32 64) ⊑ add e (const? 32 68)

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

theorem and_two_ranges_to_mask_and_range_not_pow2_diff_thm (e : IntW 8) :
  LLVM.and (icmp IntPred.ugt (add e (const? 8 (-97))) (const? 8 25))
      (icmp IntPred.ugt (add e (const? 8 (-64))) (const? 8 25)) ⊑
    LLVM.and (icmp IntPred.ult (add e (const? 8 (-123))) (const? 8 (-26)))
      (icmp IntPred.ult (add e (const? 8 (-90))) (const? 8 (-26)))

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 srem2_ashr_mask_proof : srem2_ashr_mask_before ⊑ srem2_ashr_mask_after

theorem add_nuw_const_const_sub_nuw_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(True ∧ x.uaddOverflow 1#8 = true ∨ True ∧ (BitVec.ofInt 8 (-127)).usubOverflow (x + 1#8) = true) →
    ¬(True ∧ (BitVec.ofInt 8 (-128)).usubOverflow x = true) →
      BitVec.ofInt 8 (-127) - (x + 1#8) = BitVec.ofInt 8 (-128) - x

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

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

theorem test13_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(3#32 ≥ ↑32 ∨ True ∧ (x >>> 3#32 &&& 1#32).saddOverflow (-1#32) = true) →
    signExtend 32 (ofBool (x &&& 8#32 == 0#32)) = (x >>> 3#32 &&& 1#32) + -1#32

theorem PR38021_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬3#8 ≥ ↑8 →
    3#8 ≥ ↑8 ∨
        True ∧ (x >>> 3#8).saddOverflow (BitVec.ofInt 8 (-63)) = true ∨
          True ∧ (x >>> 3#8).uaddOverflow (BitVec.ofInt 8 (-63)) = true →
      False

theorem main4f_like_proof : main4f_like_before ⊑ main4f_like_after

theorem xor_or_xor_proof : xor_or_xor_before ⊑ xor_or_xor_after

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

theorem not_or_or_and_not_and_and_commute2_proof : not_or_or_and_not_and_and_commute2_before ⊑ not_or_or_and_not_and_and_commute2_after

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

theorem fold_sext_to_and3_proof : fold_sext_to_and3_before ⊑ fold_sext_to_and3_after

theorem positive_with_icmp_logical_proof : positive_with_icmp_logical_before ⊑ positive_with_icmp_logical_after

theorem ashr_overshift_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬(15#32 ≥ ↑32 ∨ 17#32 ≥ ↑32) → 31#32 ≥ ↑32 → False

theorem positive_biggerlshr_thm.extracted_1._1 : ∀ (x : BitVec 8), ¬(6#8 ≥ ↑8 ∨ 3#8 ≥ ↑8) → 3#8 ≥ ↑8 → False

theorem shl_trunc_bigger_lshr_thm (e : IntW 32) :
  shl (trunc 8 (lshr e (const? 32 5))) (const? 8 3) ⊑ LLVM.and (trunc 8 (lshr e (const? 32 2))) (const? 8 (-8))

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

theorem lor_lor_left1_thm (e e_1 : IntW 1) :
  select (select e_1 (const? 1 1) e) (const? 1 1) e_1 ⊑ select e_1 (const? 1 1) e

theorem and_ne_with_diff_one_proof : and_ne_with_diff_one_before ⊑ and_ne_with_diff_one_after

theorem one_side_fold_sgt_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32) (x_2 : BitVec 1),
  x_2 = 1#1 → x_2 ^^^ 1#1 = 1#1 → False

theorem lshrugt_03_14_exact_proof : lshrugt_03_14_exact_before ⊑ lshrugt_03_14_exact_after

theorem and_nosignbit_select_lshr_proof : and_nosignbit_select_lshr_before ⊑ and_nosignbit_select_lshr_after

theorem xor_andn_commute2_thm (e e_1 : IntW 33) :
  LLVM.xor (LLVM.and (LLVM.udiv (const? 33 42) e_1) (LLVM.xor e (const? 33 (-1)))) e ⊑
    LLVM.or e (LLVM.udiv (const? 33 42) e_1)

theorem t_0_10_proof : t_0_10_before ⊑ t_0_10_after

theorem or_and_not_not_commute2_proof : or_and_not_not_commute2_before ⊑ or_and_not_not_commute2_after

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

theorem e_1398 :
    7 *  ~~~z - 1 *  ~~~(z &&&  ~~~t) + 2 *  ~~~(z &&& t) + 7 *  ~~~(z &&&  ~~~z) + 3 *  ~~~(z ^^^ t) - 2 * z - 18 *  ~~~(z ||| t) - 21 *  ~~~(z |||  ~~~t) - 13 * (z &&&  ~~~t) - 10 * (z &&& t) =  - 3 * (z ||| t) - 3 * (z ^^^ t)

theorem eq_commuted_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(x == 0 || 8 != 1 && 43#8 == intMin 8 && x == -1) = true →
    ofBool (x_1 == 0#8) ||

theorem add_smax_simplify_thm (e : IntW 8) :
  select (icmp IntPred.sgt (add e (const? 8 126) { «nsw» := true, «nuw» := false }) (const? 8 (-2)))
      (add e (const? 8 126) { «nsw» := true, «nuw» := false }) (const? 8 (-2)) ⊑
    add e (const? 8 126) { «nsw» := true, «nuw» := false }

theorem lshrugt_02_12_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬2#4 ≥ ↑4 → ofBool (BitVec.ofInt 4 (-4) <ᵤ x >>> 2#4) = 0#1

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

theorem select_zext_different_condition_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  x_1 = 1#1 →
    True ∧ (64#64).saddOverflow (zeroExtend 64 x) = true ∨ True ∧ (64#64).uaddOverflow (zeroExtend 64 x) = true →
      False

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

theorem test3_thm (e : IntW 32) : urem e (const? 32 8) ⊑ LLVM.and e (const? 32 7)

theorem lshr_shl_pow2_const_overflow_proof : lshr_shl_pow2_const_overflow_before ⊑ lshr_shl_pow2_const_overflow_after

theorem ashrslt_02_14_proof : ashrslt_02_14_before ⊑ ashrslt_02_14_after

theorem main7c_logical_thm.extracted_1._7 : ∀ (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 (ofBool (x != x &&& x_1))

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

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

theorem bv_AndOrXor_1294_A__B__A__B___A__B :
    ∀ (e e_1 : LLVM.IntW w), LLVM.and (LLVM.or e e_1) (LLVM.xor (LLVM.xor e (LLVM.const? w (-1))) e_1) ⊑ LLVM.and e e_1

theorem and_logic_and_logic_or_7_proof : and_logic_and_logic_or_7_before ⊑ and_logic_and_logic_or_7_after

theorem test71_proof : test71_before ⊑ test71_after

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

theorem in_constant_14_vary_proof : in_constant_14_vary_before ⊑ in_constant_14_vary_after

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

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

theorem and_sel_op0_proof : and_sel_op0_before ⊑ and_sel_op0_after

theorem exact_lshr_ne_opposite_msb_proof : exact_lshr_ne_opposite_msb_before ⊑ exact_lshr_ne_opposite_msb_after

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

theorem bv_290__292 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.mul (LLVM.shl (LLVM.const? w 1) e) e_1 ⊑ LLVM.shl e_1 e

@[simp]
theorem eval_map (fsm : FSM arity) (f : arity → arity')
    (env' : arity' → BitStream):
    (fsm.map f).eval env' = fsm.eval (env' ∘ f)

theorem sge_and_max_proof : sge_and_max_before ⊑ sge_and_max_after

theorem test13_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬zeroExtend 128 x &&& 31#128 ≥ ↑128 → True ∧ (x &&& 31#32).msb = true ∨ zeroExtend 64 (x &&& 31#32) ≥ ↑64 → False

theorem icmp_eq_x_invertable_y_todo_thm.extracted_1._2 : ∀ (x : BitVec 1) (x_1 : BitVec 8),
  ¬x = 1#1 → ofBool (x_1 == x_1 &&& 24#8) = ofBool (x_1 &&& BitVec.ofInt 8 (-25) == 0#8)

theorem fold_sext_to_and_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x &&& BitVec.ofInt 32 (-2147483647) == 1#32) = ofBool (x &&& BitVec.ofInt 8 (-127) == 1#8)

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

theorem icmp_sle6_proof : icmp_sle6_before ⊑ icmp_sle6_after

theorem t2_ult_sgt_128_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.ult (add e_2 (const? 32 16)) (const? 32 144)) e_2
      (select (icmp IntPred.sgt e_2 (const? 32 127)) e_1 e) ⊑
    select (icmp IntPred.sgt e_2 (const? 32 127)) e_1
      (select (icmp IntPred.slt e_2 (const? 32 (-16))) e e_2)

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

theorem e_1916 :
    7 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) - 5 * (b ^^^ (a ||| (b &&& c))) + 1 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 6 * (b &&&  ~~~(a &&& c)) - 7 * (b ^^^ ( ~~~a &&& (b ^^^ c))) - 5 *  ~~~(a ^^^ c) + 1 * (b ^^^ ( ~~~a &&& (b ||| c))) - 3 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) + 1 * (c ^^^  ~~~(a ||| b)) - 6 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 1 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) + 2 *  ~~~( ~~~a &&& (b &&& c)) + 11 * (b ^^^ (a |||  ~~~c)) + 3 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 3 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) + 5 * (c ^^^  ~~~(a &&& b)) - 1 * (c &&& (a ||| b)) + 4 * (a &&& b) + 5 * ( ~~~c |||  ~~~(a ^^^ b)) - 1 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) + 1 * ( ~~~a ||| ( ~~~b ||| c)) + 1 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 1 * (a ||| b) - 2 *  ~~~(a &&& ( ~~~b ||| c)) - 3 * ((a &&&  ~~~b) ||| (b ^^^ c)) + 3 * b + 1 * (a ^^^ (b ||| c)) - 5 *  ~~~(b ^^^ c) - 5 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) + 7 * (b ^^^ (a ||| ( ~~~b &&& c))) + 1 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 2 * (b ^^^  ~~~(a |||  ~~~c)) - 1 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) - 5 *  ~~~a - 2 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 11 * (a |||  ~~~b) - 1 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) + 5 *  ~~~(a &&& c) + 3 *  ~~~(a ||| c) - 11 *  ~~~( ~~~a ||| (b &&& c)) - 1 * (b |||  ~~~c) + 1 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) - 32 *  ~~~(a ||| (b ||| c)) - 13 *  ~~~(a ||| ( ~~~b ||| c)) - 23 *  ~~~( ~~~a ||| (b ||| c)) + 7 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 19 * ( ~~~a &&& ( ~~~b &&& c)) + 1 * ( ~~~a &&& (b &&& c)) - 10 * (a &&& ( ~~~b &&& c)) - 19 * (a &&& (b &&& c)) =  - 4 * (b ^^^ (a &&& (b ^^^ c)))

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

@[simp]
theorem Term.toBV_binRel {wenv : WidthExpr.Env wcard}
    {tctx : Term.Ctx wcard tcard}
    (benv : Term.BoolEnv bcard)
    (tenv : tctx.Env wenv)
    (k : BinaryRelationKind)
    (w : WidthExpr wcard)
    (a b : Term bcard ncard icard pcard tctx (.bv w)) :
  Term.toBV benv nenv ienv penv tenv (.binRel k w a b) =
    match k with

theorem lshrult_01_07_thm (e : IntW 4) :
  icmp IntPred.ult (lshr e (const? 4 1)) (const? 4 7) ⊑ icmp IntPred.ult e (const? 4 (-2))

theorem scalar_i8_lshr_and_negC_eq_not_negatedPowerOf2_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (LLVM.and (lshr e_1 e) (const? 8 (-3))) (const? 8 0) ⊑
    icmp IntPred.eq (LLVM.and e_1 (shl (const? 8 (-3)) e)) (const? 8 0)

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

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

theorem test_shl_nuw_nsw__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» := true, «nuw» := true }))
        (LLVM.or e (const? 32 (-83886080))))
      (shl (LLVM.or e (const? 32 (-83886080))) (const? 32 2) { «nsw» := true, «nuw» := true }) ⊑
    const? 32 0

theorem sdiv_i1_is_op0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  ¬(x == 0 || 1 != 1 && x_1 == intMin 1 && x == -1) = true → x_1.sdiv x = x_1

theorem in_constant_varx_14_proof : in_constant_varx_14_before ⊑ in_constant_varx_14_after

theorem test21_proof : test21_before ⊑ test21_after

theorem mul_constant_eq_nsw_thm (e e_1 : IntW 32) :
  icmp IntPred.eq (mul e_1 (const? 32 6) { «nsw» := true, «nuw» := false })
      (mul e (const? 32 6) { «nsw» := true, «nuw» := false }) ⊑
    icmp IntPred.eq e_1 e

theorem pr89516_proof : pr89516_before ⊑ pr89516_after

theorem ne_21_logical_proof : ne_21_logical_before ⊑ ne_21_logical_after

theorem t1_flags_nuw_first_proof : t1_flags_nuw_first_before ⊑ t1_flags_nuw_first_after

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

theorem add_smax_simplify_proof : add_smax_simplify_before ⊑ add_smax_simplify_after

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

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

@[simp] theorem Valuation.ofHVector_inj (xs ys : HVector toType ts) :
    ofHVector xs = ofHVector ys ↔ xs = ys

theorem e_2003 :
    1 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 2 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 1 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 2 * (d &&& (e ||| f)) - 1 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 11 * (f &&& (d |||  ~~~e)) - 2 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) - 1 * (e ^^^  ~~~(d &&& f)) + 5 * d - 7 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 5 * (e ^^^ (d ||| (e &&& f))) - 6 * (e &&& f) - 2 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 7 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 1 * (f ^^^ (d ||| (e ||| f))) + 1 * (e &&& (d ||| f)) + 1 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 5 * (f &&&  ~~~(d &&&  ~~~e)) - 11 *  ~~~(d ^^^ ( ~~~e ||| f)) - 1 * (e |||  ~~~f) + 7 *  ~~~(d ^^^ ( ~~~e &&& f)) + 7 *  ~~~(d ^^^ (e ||| f)) + 11 * (f ^^^ (d ||| e)) - 2 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 10 *  ~~~(d ||| (e ||| f)) + 5 *  ~~~(d ||| ( ~~~e ||| f)) + 13 *  ~~~( ~~~d ||| (e ||| f)) - 18 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 29 * ( ~~~d &&& ( ~~~e &&& f)) + 12 * ( ~~~d &&& (e &&& f)) - 11 * (d &&& ( ~~~e &&& f)) - 1 * (d &&& (e &&& f)) = 1 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 11 * (f ^^^  ~~~( ~~~d &&& (e &&& f)))

theorem n2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬x_1 ≥ ↑8 →
    ¬(True ∧ ((-1#8) <<< x_1).sshiftRight' x_1 ≠ -1#8 ∨ x_1 ≥ ↑8) →
      ofBool (((-1#8) <<< x_1 ^^^ 1#8) &&& x != x) = ofBool (x &&& ((-1#8) <<< x_1 ^^^ BitVec.ofInt 8 (-2)) != 0#8)

theorem test3_proof : test3_before ⊑ test3_after

theorem negate_select_of_op_vs_negated_op_nsw_proof : negate_select_of_op_vs_negated_op_nsw_before ⊑ negate_select_of_op_vs_negated_op_nsw_after

theorem prop_eq (w : Nat) (x y: BitVec w) :
  let wenv

lemma NFA.correct_spec {M : NFA α σ} {ζ : M.sa} {L : Language α} :
    M.correct ζ L → M.accepts = L

theorem sextbool_add_commute_proof : sextbool_add_commute_before ⊑ sextbool_add_commute_after

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

theorem test48_thm (e : IntW 8) :
  zext 64 (LLVM.or (shl (zext 32 e) (const? 32 8)) (zext 32 e)) ⊑
    zext 64
      (LLVM.or (shl (zext 32 e) (const? 32 8) { «nsw» := true, «nuw» := true }) (zext 32 e) { «disjoint» := true })
      { «nneg» := true }

theorem sle_swap_and_min_proof : sle_swap_and_min_before ⊑ sle_swap_and_min_after

theorem alive_239 : alive_239_src ⊑ alive_239_tgt

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

@[simp]
theorem Expr.regArgs_mk {Γ : Ctxt d.Ty} {ty eff op}
    (ty_eq : ty = DialectSignature.returnTypes op)
    (eff_le : DialectSignature.effectKind op ≤ eff)
    (args : HVector (Var Γ) (DialectSignature.sig op)) (regArgs) :
    (Expr.mk op ty_eq eff_le args regArgs).regArgs = regArgs

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

theorem or_simplify_ule_proof : or_simplify_ule_before ⊑ or_simplify_ule_after

theorem icmp_eq_mul_nsw_nonequal_commuted_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (mul e_1 e { «nsw» := true, «nuw» := false })
      (mul e (add e_1 (const? 8 1)) { «nsw» := true, «nuw» := false }) ⊑
    icmp IntPred.eq e (const? 8 0)

theorem test7_proof : test7_before ⊑ test7_after

theorem n3_constmask_samemask_proof : n3_constmask_samemask_before ⊑ n3_constmask_samemask_after

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

theorem t2_ult_sgt_65536_proof : t2_ult_sgt_65536_before ⊑ t2_ult_sgt_65536_after

theorem test11_proof : test11_before ⊑ test11_after

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

theorem srem_common_divisor_defined_cond_thm.extracted_1._2 : ∀ (x x_1 : BitVec 5) (x_2 : BitVec 1),
  ¬(x_2 = 1#1 ∨ (x_1 == 0 || 5 != 1 && x == intMin 5 && x_1 == -1) = true) →
    ¬x_2 = 1#1 → (x_1 == 0 || 5 != 1 && x == intMin 5 && x_1 == -1) = true → False

theorem modulo4_thm (e : IntW 32) :
  add (select (icmp IntPred.slt (LLVM.srem e (const? 32 4)) (const? 32 0)) (const? 32 4) (const? 32 0))
      (LLVM.srem e (const? 32 4)) { «nsw» := true, «nuw» := false } ⊑
    LLVM.and e (const? 32 3)

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

theorem test10_logical_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 2)) (const? 32 0)) (icmp IntPred.ult e (const? 32 4))
      (const? 1 0) ⊑
    icmp IntPred.ult e (const? 32 2)

theorem demorgan_nor_use2bc_proof : demorgan_nor_use2bc_before ⊑ demorgan_nor_use2bc_after

theorem reassoc_x2_sub_nuw_proof : reassoc_x2_sub_nuw_before ⊑ reassoc_x2_sub_nuw_after

theorem sgt_smax4_proof : sgt_smax4_before ⊑ sgt_smax4_after

theorem absdiff1_thm (e e_1 : IntW 64) :
  sub (LLVM.xor (sub e_1 e) (sext 64 (icmp IntPred.ult e_1 e))) (sext 64 (icmp IntPred.ult e_1 e)) ⊑
    select (icmp IntPred.ult e_1 e) (sub (const? 64 0) (sub e_1 e)) (sub e_1 e)

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

theorem vars_simplifyXor [DecidableEq α] (c₁ c₂ : Circuit α) :
    (vars (simplifyXor c₁ c₂)) ⊆ (vars c₁ ++ vars c₂).dedup

theorem in_constant_mone_vary_invmask_proof : in_constant_mone_vary_invmask_before ⊑ in_constant_mone_vary_invmask_after

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

theorem test_shl_nuw_nsw__none_are_safe_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& BitVec.ofInt 32 (-2) == 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 absdiff1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 64),
  ¬ofBool (x_1 <ᵤ x) = 1#1 →
    (x_1 - x ^^^ signExtend 64 (ofBool (x_1 <ᵤ x))) - signExtend 64 (ofBool (x_1 <ᵤ x)) = x_1 - x

theorem empty_eq : (∅ : Ctxt Ty) = .empty

theorem test5_proof : test5_before ⊑ test5_after

theorem canonicalize_logic_first_and0_nswnuw_proof : canonicalize_logic_first_and0_nswnuw_before ⊑ canonicalize_logic_first_and0_nswnuw_after

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

theorem PR42691_9_logical_proof : PR42691_9_logical_before ⊑ PR42691_9_logical_after

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

theorem test_shl_nsw__none_are_safe_proof : test_shl_nsw__none_are_safe_before ⊑ test_shl_nsw__none_are_safe_after

theorem shl_add_add_fail_proof : shl_add_add_fail_before ⊑ shl_add_add_fail_after

theorem zext_true_val_must_be_one_proof : zext_true_val_must_be_one_before ⊑ zext_true_val_must_be_one_after

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

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

theorem test42_proof : test42_before ⊑ test42_after

@[simp] theorem map_append (f : Ty₁ → Ty₂) (Γ Δ : Ctxt Ty₁) :
    (Γ ++ Δ).map f = Γ.map f ++ Δ.map f

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

theorem n7_wrong_pred2_proof : n7_wrong_pred2_before ⊑ n7_wrong_pred2_after

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

theorem uadd_sat_via_add_swapped_cmp_nonstrict_proof : uadd_sat_via_add_swapped_cmp_nonstrict_before ⊑ uadd_sat_via_add_swapped_cmp_nonstrict_after

theorem squared_nsw_sgt0_thm.extracted_1._1 : ∀ (x : BitVec 5),
  ¬(True ∧ x.smulOverflow x = true) → ofBool (0#5 <ₛ x * x) = ofBool (x != 0#5)

theorem slt_positive_multip_rem_nz_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.smulOverflow 5#8 = true) → ofBool (x * 5#8 <ₛ 21#8) = ofBool (x <ₛ 5#8)

theorem and_or2_proof : and_or2_before ⊑ and_or2_after

@[aesop 50% unsafe]
theorem Std.HashMap.insert_keys_perm_new [BEq K] [LawfulBEq K] [Hashable K] [LawfulHashable K] (m : Std.HashMap K V) (k : K) (v : V) :
    k ∉ m → (m.insert k v).keys.Perm (k :: m.keys)

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 599),
  x = 1#1 → ¬70368744177664#599 = 0 → x_1 % 70368744177664#599 = x_1 &&& 70368744177663#599

theorem test_logical_proof : test_logical_before ⊑ test_logical_after

theorem add_or_and_thm (e e_1 : IntW 32) : add (LLVM.or e_1 e) (LLVM.and e_1 e) ⊑ add e_1 e

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

theorem cond_eq_and_const_thm (e e_1 : IntW 8) :
  select (icmp IntPred.eq e_1 (const? 8 10)) (icmp IntPred.ult e_1 e) (const? 1 0) ⊑
    select (icmp IntPred.eq e_1 (const? 8 10)) (icmp IntPred.ugt e (const? 8 10)) (const? 1 0)

theorem ne_basic_equal_5_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.ne e_1 (const? 8 5)) (icmp IntPred.ule (add e_1 (const? 8 (-5))) e) ⊑
    icmp IntPred.ult (add e_1 (const? 8 (-6))) e

theorem test59_proof : test59_before ⊑ test59_after

theorem xor_common_op_commute3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  x_1 ^^^ 5#8 ||

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

theorem e_8 :
    1 * (x |||  ~~~y) - 1 * (x ||| y) - 2 *  ~~~(x ||| y) - 1 * (x &&& y) =  - 1 *  ~~~(x &&&  ~~~y)

@[simp]
lemma BitVec.cons_ugt_iff {w} {bv1 bv2 : BitVec w} :
    ((BitVec.cons b2 bv2).ult (BitVec.cons b1 bv1)) ↔ (if b1 = b2 then bv2.ult bv1 else b1)

theorem masked_icmps_mask_notallzeros_bmask_mixed_7b_proof : masked_icmps_mask_notallzeros_bmask_mixed_7b_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_7b_after

theorem icmp_sle_x_negy_proof : icmp_sle_x_negy_before ⊑ icmp_sle_x_negy_after

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

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

theorem fold_sext_to_and_wrong6_thm (e : IntW 8) :
  icmp IntPred.ne (LLVM.and (sext 32 e) (const? 32 (-2147483647))) (const? 32 (-1)) ⊑ const? 1 1

theorem outputWith_carryWith_eq_evalWith (p : FSM arity)
  (xs ys : arity → BitStream) (xN : arity → Bool)
  (hysLt : ∀ a i, i < n → ys a i = xs a i)
  (hysN : ∀ a, ys a n = xN a) :
  p.outputWith (p.carryWith p.initCarry xs n) xN = p.evalWith p.initCarry ys n

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 positive_biggershl_shlnuw_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(3#8 ≥ ↑8 ∨ True ∧ x >>> 3#8 <<< 6#8 >>> 6#8 ≠ x >>> 3#8 ∨ 6#8 ≥ ↑8) →
    ¬(True ∧ x <<< 3#8 >>> 3#8 ≠ x ∨ 3#8 ≥ ↑8) → x >>> 3#8 <<< 6#8 = x <<< 3#8 &&& BitVec.ofInt 8 (-64)

theorem alive_InstCombineShift__239  (w : Nat)   : alive_InstCombineShift__239_src w  ⊑ alive_InstCombineShift__239_tgt w

theorem select_icmp_eq_and_4096_0_or_4096_proof : select_icmp_eq_and_4096_0_or_4096_before ⊑ select_icmp_eq_and_4096_0_or_4096_after

theorem and_ranges_signed_pred_proof : and_ranges_signed_pred_before ⊑ and_ranges_signed_pred_after

theorem xor_of_icmps_commute_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ofBool (0#64 <ₛ x) ^^^ ofBool (x == 1#64) = ofBool (1#64 <ₛ x)

theorem eq_smax1_proof : eq_smax1_before ⊑ eq_smax1_after

theorem or_logic_or_logic_and_1_proof : or_logic_or_logic_and_1_before ⊑ or_logic_or_logic_and_1_after

theorem xor_i8_to_i64_shl_save_and_ne_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 8),
  ofBool (x_1 &&& 1#8 != 0#8) = 1#1 → 63#64 ≥ ↑64 → False

theorem e_2428 :
     - 2 * (e ^^^ ( ~~~d ||| (e ^^^ f))) + 7 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 * ((d ^^^ e) |||  ~~~(d ^^^ f)) + 1 * (f ^^^ (d &&& ( ~~~e ||| f))) - 6 * (e |||  ~~~(d |||  ~~~f)) + 2 * e + 7 * (f ^^^  ~~~(d |||  ~~~e)) - 1 * (e ^^^ f) - 3 *  ~~~(d &&&  ~~~e) - 2 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 4 * (f ^^^  ~~~(d ||| e)) + 2 * (f ^^^ (d ||| (e ||| f))) + 3 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 2 * (d ||| ( ~~~e ||| f)) + 7 *  ~~~(e &&& f) + 11 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 3 * (e &&& (d ^^^ f)) - 1 *  ~~~( ~~~d &&& (e ||| f)) + 7 *  ~~~(d ^^^ (e ||| f)) - 1 * (e ^^^  ~~~(d ||| f)) + 5 *  ~~~(d &&&  ~~~d) + 7 * (d &&& ( ~~~e ||| f)) + 1 * ((d &&& f) ^^^ (e ||| f)) + 3 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 2 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 5 * (e ^^^ (d |||  ~~~f)) - 5 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 *  ~~~(d ^^^ f) + 2 * (d ^^^ (e ^^^ f)) + 1 *  ~~~(d ^^^ e) + 5 * (e ^^^ (d &&& ( ~~~e ||| f))) + 1 *  ~~~(d &&& ( ~~~e &&& f)) - 1 * (e ||| (d &&& f)) - 1 * (e ^^^ (d ||| (e ^^^ f))) + 11 *  ~~~(e &&&  ~~~f) + 3 * (f ^^^ (d ||| ( ~~~e &&& f))) + 4 * (e ^^^ (d ||| (e ||| f))) - 1 * (f &&&  ~~~(d ^^^ e)) + 1 *  ~~~( ~~~d &&& (e ^^^ f)) - 5 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 4 * (f ^^^  ~~~(d &&& (e &&& f))) + 3 * (e |||  ~~~(d ^^^ f)) + 1 * ( ~~~f &&& (d ^^^ e)) - 5 * (f ^^^ (d &&&  ~~~e)) + 1 * ((d &&& e) ^^^ (e |||  ~~~f)) - 7 *  ~~~(d &&& (e ^^^ f)) + 1 *  ~~~( ~~~d ||| (e &&& f)) + 7 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 2 * (e ^^^ (d ||| ( ~~~e ||| f))) - 5 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 1 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 2 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 11 * ((d &&& e) ^^^ (e ||| f)) - 2 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 11 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 11 *  ~~~(d &&& f) + 5 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 2 * (d ^^^ ( ~~~e ||| f)) - 7 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 2 * (e ^^^ (d ||| (e &&& f))) + 1 *  ~~~(d ||| (e &&& f)) - 1 * (e ^^^ (d &&& f)) + 11 *  ~~~(d &&& (e ||| f)) - 7 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 3 * (e ^^^  ~~~(d |||  ~~~f)) - 2 * (d &&&  ~~~e) - 1 * (f |||  ~~~(d ||| e)) - 25 *  ~~~(d ||| (e ||| f)) - 16 *  ~~~(d ||| ( ~~~e ||| f)) - 71 *  ~~~( ~~~d ||| (e ||| f)) - 4 * ( ~~~d &&& ( ~~~e &&& f)) - 19 * ( ~~~d &&& (e &&& f)) - 64 * (d &&& ( ~~~e &&& f)) - 36 * (d &&& (e &&& f)) = 13 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 1 * (f ||| (d ^^^ e))

theorem test_shift_and_cmp_changed2_thm (e : IntW 8) :
  icmp IntPred.ult (LLVM.and (shl e (const? 8 5)) (const? 8 (-64))) (const? 8 32) ⊑
    icmp IntPred.eq (LLVM.and e (const? 8 6)) (const? 8 0)

theorem ashr_ule_exact_proof : ashr_ule_exact_before ⊑ ashr_ule_exact_after

lemma TermBinop.alt_lang {t₁ t₂ : Term} (op : TermBinop) :
  (op.subst_arity' ▸ (op.subst t₁ t₂).language) =
    let lop : Set (BitVecs 3) := op.openTerm_arity ▸ op.openTerm.language
    let lop' : Set (BitVecs ((t₁.arity ⊔ t₂.arity) + 3)) := lop.lift (liftLast3 (max t₁.arity t₂.arity))
    let l₁ := t₁.language.lift (liftMaxSuccSucc1 t₁.arity t₂.arity)
    let l₂ := t₂.language.lift (liftMaxSuccSucc2 t₁.arity t₂.arity)
    let l := l₁ ∩ l₂ ∩ lop'
    l.proj (liftOp _)

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 ule_or_not_min_commute_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.ne e_1 (const? 8 0)) (icmp IntPred.ule e_1 e) ⊑ const? 1 1

theorem alive_Select_1087 : forall (w : Nat) (Y X val : Bitvec 1)
, TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec w)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (val) %v0;
  %v2 := op:const (↑true) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:xor 1 %v3;
  %v5 := op:const (X) %v0;
  %v6 := op:const (Y) %v0;
  %v7 := triple:%v4 %v5 %v6;
  %v8 := op:select w %v7
  dsl_ret %v8
  ]  ⊑
  TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec w)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (val) %v0;
  %v2 := op:const (↑true) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:xor 1 %v3;
  %v5 := op:const (Y) %v0;
  %v6 := op:const (X) %v0;
  %v7 := triple:%v1 %v5 %v6;
  %v8 := op:select w %v7
  dsl_ret %v8
  ]

theorem and_logic_and_logic_or_4_proof : and_logic_and_logic_or_4_before ⊑ and_logic_and_logic_or_4_after

theorem udiv_common_divisor_defined_cond_thm.extracted_1._2 : ∀ (x x_1 : BitVec 5) (x_2 : BitVec 1),
  ¬(x_2 = 1#1 ∨ x_1 = 0) → x_2 = 1#1 → ¬x_1 = 0 → False

theorem e_2117 :
     - 5 *  ~~~(d |||  ~~~e) + 1 * (f &&& (d |||  ~~~e)) - 1 * ((d &&& e) |||  ~~~(e ||| f)) - 11 * ( ~~~d ||| (e &&& f)) - 7 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 11 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 1 * (e &&& f) + 11 * (d &&& e) + 2 * (d ||| ( ~~~e ||| f)) + 4 * (e ^^^ (d ||| ( ~~~e &&& f))) + 3 * (e ^^^  ~~~(d &&&  ~~~f)) - 3 *  ~~~(d &&& ( ~~~e &&& f)) - 2 * (d ^^^ e) + 3 * (f &&&  ~~~(d ^^^ e)) - 2 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 3 * d - 5 *  ~~~(d &&& ( ~~~e ||| f)) - 11 * (e ^^^ ( ~~~d ||| (e ||| f))) - 2 * (e &&&  ~~~(d &&& f)) + 2 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 7 * ( ~~~d ||| (e ^^^ f)) + 5 *  ~~~(d ^^^ (e ||| f)) + 2 * (e |||  ~~~f) + 1 * e - 2 * (f ^^^ (d &&&  ~~~e)) + 7 * ((d &&& e) ^^^ (e |||  ~~~f)) + 3 * (f &&& (d ^^^ e)) + 11 *  ~~~(d &&& (e ||| f)) + 4 * (e |||  ~~~(d ^^^ f)) + 5 *  ~~~( ~~~d &&& (e &&& f)) + 1 * (e ^^^  ~~~(d &&& f)) + 5 * (f ^^^ (d |||  ~~~e)) - 1 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 3 * ( ~~~d ||| (e ||| f)) + 3 * (e ^^^ (d ||| (e ||| f))) + 2 * (f ^^^ ( ~~~d ||| (e ||| f))) - 2 *  ~~~(d ||| (e ||| f)) + 5 *  ~~~(d ||| ( ~~~e ||| f)) - 34 *  ~~~( ~~~d ||| (e ||| f)) - 26 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 2 * ( ~~~d &&& ( ~~~e &&& f)) - 14 * ( ~~~d &&& (e &&& f)) - 8 * (d &&& ( ~~~e &&& f)) - 7 * (d &&& (e &&& f)) =  - 2 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f))

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

theorem select_bittest_to_sub_proof : select_bittest_to_sub_before ⊑ select_bittest_to_sub_after

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 or_xor_xor_normal_variant2_proof : or_xor_xor_normal_variant2_before ⊑ or_xor_xor_normal_variant2_after

theorem t0_commutative_proof : t0_commutative_before ⊑ t0_commutative_after

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

theorem scalar_i32_lshr_and_negC_slt_proof : scalar_i32_lshr_and_negC_slt_before ⊑ scalar_i32_lshr_and_negC_slt_after

theorem test_mul_nsw__nsw_is_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x ||| BitVec.ofInt 32 (-83886080) == BitVec.ofInt 32 (-83886079)) = 1#1 →
    ¬(True ∧ (x ||| BitVec.ofInt 32 (-83886080)).smulOverflow 9#32 = true) →
      BitVec.ofInt 32 (-754974711) = (x ||| BitVec.ofInt 32 (-83886080)) * 9#32

theorem ashrsgt_02_10_exact_proof : ashrsgt_02_10_exact_before ⊑ ashrsgt_02_10_exact_after

theorem test5_thm.extracted_1._1 : ∀ (x : BitVec 1), zeroExtend 32 (zeroExtend 8 x) = zeroExtend 32 x

theorem a_proof : a_before ⊑ a_after

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

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 invert_both_cmp_operands_complex_proof : invert_both_cmp_operands_complex_before ⊑ invert_both_cmp_operands_complex_after

theorem main3f_like_thm (e e_1 e_2 : IntW 32) :
  select
      (LLVM.or (icmp IntPred.ne (LLVM.and e_2 e_1) (const? 32 0))
        (icmp IntPred.ne (LLVM.and e_2 e) (const? 32 0)))
      (const? 32 0) (const? 32 1) ⊑
    zext 32 (icmp IntPred.eq (LLVM.and e_2 (LLVM.or e_1 e)) (const? 32 0))

theorem is_ascii_alphabetic_inverted_proof : is_ascii_alphabetic_inverted_before ⊑ is_ascii_alphabetic_inverted_after

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

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

theorem p1_scalar_urem_by_nonconst_proof : p1_scalar_urem_by_nonconst_before ⊑ p1_scalar_urem_by_nonconst_after

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 logical_or_logical_or_icmps_comm1_thm.extracted_1._3 : ∀ (x x_1 x_2 : BitVec 8),
  ¬x_1 ≥ ↑8 →
    ofBool (x_2 &&& 1#8 <<< x_1 == 0#8) = 1#1 ∨ ofBool (x == 42#8) = 1#1 →
      ¬(True ∧ 1#8 <<< x_1 >>> x_1 ≠ 1#8 ∨ x_1 ≥ ↑8) →
        ¬ofBool (x_2 &&& 1#8 <<< x_1 == 0#8) = 1#1 → ¬ofBool (x == 42#8) = 1#1 → 1#1 = ofBool (x_2 &&& 1#8 == 0#8)

theorem e_1606 :
    11 *  ~~~(a ^^^ c) + 7 * (b ^^^  ~~~(a &&& (b ||| c))) - 1 * (b ^^^ (a &&& (b ||| c))) - 11 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) - 11 * ( ~~~b &&&  ~~~(a ^^^ c)) - 6 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) + 1 * ( ~~~b &&& (a ^^^ c)) + 7 * (b &&& (a ||| c)) - 1 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) - 7 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) + 1 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) + 3 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) + 1 * (b ^^^  ~~~(a &&&  ~~~c)) - 8 *  ~~~(a ||| (b ||| c)) - 8 *  ~~~(a ||| ( ~~~b ||| c)) - 2 * ( ~~~a &&& ( ~~~b &&& c)) + 2 * ( ~~~a &&& (b &&& c)) + 23 * (a &&& ( ~~~b &&& c)) - 26 * (a &&& (b &&& c)) =  - 4 *  ~~~( ~~~a ||| (b ||| c)) - 1 * ( ~~~(a ^^^ b) &&& (a ^^^ c))

theorem urem_i32_multiuse_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬zeroExtend 32 x = 0 →
    zeroExtend 32 x = 0 ∨
        True ∧ (zeroExtend 32 x_1).saddOverflow (zeroExtend 32 x) = true ∨
          True ∧ (zeroExtend 32 x_1).uaddOverflow (zeroExtend 32 x) = true ∨
            True ∧ (zeroExtend 32 x_1 % zeroExtend 32 x).smulOverflow (zeroExtend 32 x_1 + zeroExtend 32 x) = true ∨
              True ∧ (zeroExtend 32 x_1 % zeroExtend 32 x).umulOverflow (zeroExtend 32 x_1 + zeroExtend 32 x) = true →
      False

theorem lshrugt_02_04_exact_proof : lshrugt_02_04_exact_before ⊑ lshrugt_02_04_exact_after

theorem test25_proof : test25_before ⊑ test25_after

theorem e_108 :
     - 2 * x + 2 *  ~~~(x ^^^ y) - 11 *  ~~~x + 9 *  ~~~(x ||| y) + 22 *  ~~~(x |||  ~~~y) + 13 * (x &&&  ~~~y) =  - 11 * (x &&& y) + 11 * (x ||| y)

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

theorem main4e_like_logical_thm.extracted_1._5 : ∀ (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 → 0#32 = zeroExtend 32 1#1

theorem PR60818_ne_proof : PR60818_ne_before ⊑ PR60818_ne_after

theorem basic_preserve_nuw_nsw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ (x_1 ^^^ -1#8).saddOverflow x = true ∨ True ∧ (x_1 ^^^ -1#8).uaddOverflow x = true) →
    True ∧ x_1.ssubOverflow x = true ∨ True ∧ x_1.usubOverflow x = true → False

theorem test_thm.extracted_1._1 : ∀ (x : BitVec 31),
  ¬15#32 ≥ ↑32 → True ∧ (zeroExtend 32 x).uaddOverflow 16384#32 = true ∨ 15#32 ≥ ↑32 → False

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

theorem ne_umin3_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 + 3#32 <ᵤ x) = 1#1 → ofBool (x_1 + 3#32 != x) = ofBool (x <ᵤ x_1 + 3#32)

theorem src_is_mask_and_fail_mixed_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8),
  ¬(x_1 ≥ ↑8 ∨ x ≥ ↑8) →
    ofBool (x_2 ^^^ 123#8 == (x_2 ^^^ 123#8) &&& ((BitVec.ofInt 8 (-8)).sshiftRight' x_1 &&& (-1#8) >>> x)) =
      ofBool ((BitVec.ofInt 8 (-8)).sshiftRight' x_1 &&& (-1#8) >>> x ||| x_2 ^^^ BitVec.ofInt 8 (-124) == -1#8)

theorem e_752 :
     - 1 * (z ||| t) + 7 *  ~~~(z ||| t) + 8 *  ~~~(z |||  ~~~t) =  - 1 * z + 7 *  ~~~z

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 not_select_bool_const1_thm (e e_1 : IntW 1) :
  LLVM.xor (select e_1 e (const? 1 1)) (const? 1 1) ⊑ select e_1 (LLVM.xor e (const? 1 1)) (const? 1 0)

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

theorem xor_orn_commute1_proof : xor_orn_commute1_before ⊑ xor_orn_commute1_after

theorem pv_proof : pv_before ⊑ pv_after

theorem sext_shl_mask_thm (e : IntW 32) (e_1 : IntW 16) :
  LLVM.and (shl (sext 32 e_1) e) (const? 32 65535) ⊑ LLVM.and (shl (zext 32 e_1) e) (const? 32 65535)

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

@[simp]
theorem BitStream.ofProp_eq_negOne_iff (p : Prop) :
    (BitStream.ofProp p = .negOne) ↔ p

theorem and_zext_zext_proof : and_zext_zext_before ⊑ and_zext_zext_after

@[simp]
theorem outputCirc_changeInitCarry_eq (p : FSM arity) (c : p.α → Bool) :
    (p.changeInitCarry c).outputCirc = p.outputCirc

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

theorem test6_proof : test6_before ⊑ test6_after

theorem com_Γ : com.1 = (Γn 1)

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

theorem multiuse2_proof : multiuse2_before ⊑ multiuse2_after

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

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

theorem eq_signed_to_small_unsigned_proof : eq_signed_to_small_unsigned_before ⊑ eq_signed_to_small_unsigned_after

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

theorem ashrsgt_02_05_proof : ashrsgt_02_05_before ⊑ ashrsgt_02_05_after

theorem icmp_slt_0_or_icmp_sgt_0_i64_proof : icmp_slt_0_or_icmp_sgt_0_i64_before ⊑ icmp_slt_0_or_icmp_sgt_0_i64_after

omit [Fintype S] [DecidableEq S] in
lemma processOneElem_tr (st : worklist.St A S) (final : S → Bool) (a b : A) (sa : S) (s s' : State) :
    if a = b ∧ s = s' then
      ∃ ssa, (processOneElem A S final s st (a, sa)).map[sa]? = some ssa ∧
        (processOneElem A S final s st (a, sa)).m.tr s' b =
        (st.m.tr s a |>.insert ssa)
    else
      (processOneElem A S final s st (a, sa)).m.tr s' b = st.m.tr s' b

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

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

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

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

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

theorem or_not_and_and_not_and_xor_commute2_proof : or_not_and_and_not_and_xor_commute2_before ⊑ or_not_and_and_not_and_xor_commute2_after

theorem PR42691_1_logical_thm (e : IntW 32) :
  select (icmp IntPred.slt e (const? 32 0)) (const? 1 1) (icmp IntPred.eq e (const? 32 2147483647)) ⊑
    icmp IntPred.ugt e (const? 32 2147483646)

theorem positive_samevar_lshrexact_proof : positive_samevar_lshrexact_before ⊑ positive_samevar_lshrexact_after

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

theorem negative_with_nonuniform_bad_mask_logical_proof : negative_with_nonuniform_bad_mask_logical_before ⊑ negative_with_nonuniform_bad_mask_logical_after

theorem e_2296 :
    1 *  ~~~(e &&& f) + 5 * (e ^^^  ~~~(d |||  ~~~f)) - 7 * (d ||| ( ~~~e &&& f)) + 1 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 7 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 3 * (e ^^^ (d &&& (e ||| f))) - 2 *  ~~~(d &&&  ~~~e) + 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 11 * (e ^^^ ( ~~~d &&& (e ||| f))) - 5 * (d |||  ~~~e) + 11 *  ~~~(d &&&  ~~~f) - 2 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 1 * (e &&&  ~~~(d ^^^ f)) - 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 3 * (f ^^^  ~~~(d &&& e)) - 6 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 1 * (d ||| f) - 1 * ( ~~~e |||  ~~~(d ^^^ f)) + 1 * (e ^^^  ~~~(d ||| f)) + 2 * (e ^^^ (d |||  ~~~f)) - 6 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 1 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 1 * (f ^^^ (d &&& ( ~~~e ||| f))) + 2 * (d ||| (e &&& f)) - 11 * ((d &&& e) |||  ~~~(e ^^^ f)) - 1 * (f &&& (d ^^^ e)) + 1 * ((d &&& f) ||| (e &&&  ~~~f)) - 6 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 2 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 7 * ((d ^^^ e) ||| (d ^^^ f)) - 5 * (e ||| (d &&& f)) + 11 *  ~~~(d ||| (e &&& f)) + 5 * (e ^^^ (d ||| (e ^^^ f))) + 1 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 5 * ((d |||  ~~~e) &&& (e ^^^ f)) + 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 7 * (e ^^^  ~~~(d ||| (e &&& f))) + 2 *  ~~~(d ||| ( ~~~e &&& f)) - 1 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 6 * (e |||  ~~~(d ^^^ f)) + 7 *  ~~~(d &&& (e &&& f)) + 5 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 2 *  ~~~(d |||  ~~~f) + 1 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 11 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 5 *  ~~~(d ||| (e ^^^ f)) + 4 *  ~~~(d &&& ( ~~~e &&& f)) - 7 * (f ^^^ (d ||| e)) - 11 *  ~~~(d ^^^ f) - 11 *  ~~~(d ^^^ (e ||| f)) + 1 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 1 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 23 *  ~~~(d ||| (e ||| f)) - 5 *  ~~~(d ||| ( ~~~e ||| f)) + 11 *  ~~~( ~~~d ||| (e ||| f)) + 49 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 12 * ( ~~~d &&& ( ~~~e &&& f)) - 40 * ( ~~~d &&& (e &&& f)) - 1 * (d &&& ( ~~~e &&& f)) + 35 * (d &&& (e &&& f)) = 6 * ( ~~~(d &&& e) &&& (e ^^^ f))

theorem lshr_sext_i1_to_i128_thm.extracted_1._2 : ∀ (x : BitVec 1),
  ¬42#128 ≥ ↑128 → ¬x = 1#1 → signExtend 128 x >>> 42#128 = 0#128

theorem add_eq_xor_add_mul_and :
    x + y = (x ^^^ y) + 2 * (x &&& y)

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

theorem test6_proof : test6_before ⊑ test6_after

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

theorem bools_logical_thm.extracted_1._4 : ∀ (x x_1 : BitVec 1), x_1 ^^^ 1#1 = 1#1 → x_1 = 1#1 → x = 1#1 → False

theorem ashr_ult_5_thm (e : IntW 4) :
  icmp IntPred.ult (ashr e (const? 4 1)) (const? 4 5) ⊑ icmp IntPred.sgt e (const? 4 (-1))

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 test4c_thm (e : IntW 64) :
  icmp IntPred.slt (trunc 32 (LLVM.or (ashr e (const? 64 63)) (lshr (sub (const? 64 0) e) (const? 64 63))))
      (const? 32 1) ⊑
    icmp IntPred.slt e (const? 64 1)

theorem ashr_mul_thm (e e_1 : IntW 8) :
  trunc 16 (ashr (mul (sext 20 e_1) (sext 20 e)) (const? 20 8)) ⊑
    ashr (mul (sext 16 e_1) (sext 16 e) { «nsw» := true, «nuw» := false }) (const? 16 8)

theorem main4_proof : main4_before ⊑ main4_after

theorem test_ne_11_and_15_add_10_proof : test_ne_11_and_15_add_10_before ⊑ test_ne_11_and_15_add_10_after

theorem lshr_shl_pow2_const_case2_proof : lshr_shl_pow2_const_case2_before ⊑ lshr_shl_pow2_const_case2_after

theorem e_1936 :
     - 1 * (c ^^^ ( ~~~a ||| (b &&& c))) + 2 * ((a &&& b) ^^^ (b |||  ~~~c)) + 5 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) - 1 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) + 2 * (b ^^^ (a &&& ( ~~~b ||| c))) - 5 * ( ~~~b ||| (a ^^^ c)) - 11 * (b ^^^  ~~~(a &&& (b ||| c))) + 5 * (b ^^^ (a &&& (b ||| c))) - 6 *  ~~~(a &&& c) + 4 * (c &&&  ~~~(a ^^^ b)) + 3 * (c ^^^ ( ~~~a &&& (b ||| c))) + 1 * c - 1 * ((a &&& b) |||  ~~~(b |||  ~~~c)) - 11 * (b ^^^  ~~~(a &&&  ~~~c)) + 7 *  ~~~a - 1 * ( ~~~a ||| (b ||| c)) + 11 * (a &&& c) - 7 * (b &&&  ~~~(a ^^^ c)) + 4 *  ~~~(a &&& (b ^^^ c)) - 7 * (c &&& (a ^^^ b)) + 3 * ( ~~~c &&&  ~~~(a ^^^ b)) + 11 * (c ^^^  ~~~(a &&& (b ||| c))) + 5 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) - 3 * (a ^^^ (b ||| c)) + 11 * (c ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 2 * (a ^^^ (b &&& c)) - 1 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 2 * ((a &&& c) ||| (b &&&  ~~~c)) + 5 * (b ^^^  ~~~( ~~~a ||| (b ^^^ c))) + 4 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) + 5 * (b ^^^ (a |||  ~~~c)) - 2 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) + 2 * ((a &&& b) ||| (b ^^^ c)) + 4 * ( ~~~c |||  ~~~(a ^^^ b)) - 6 * ((a ^^^ b) ||| (a ^^^ c)) - 3 * (a ^^^ ( ~~~b ||| c)) + 1 * (c ^^^  ~~~(a &&&  ~~~b)) - 1 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) + 11 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) + 1 *  ~~~(b |||  ~~~c) - 7 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 5 *  ~~~(a ||| ( ~~~b &&& c)) - 11 *  ~~~(a &&&  ~~~a) + 1 *  ~~~(a ^^^ ( ~~~b ||| c)) + 3 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) + 4 * (b &&& (a ||| c)) - 4 *  ~~~(a ||| (b ||| c)) - 22 *  ~~~(a ||| ( ~~~b ||| c)) + 14 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 7 * ( ~~~a &&& ( ~~~b &&& c)) + 1 * (a &&& ( ~~~b &&& c)) - 15 * (a &&& (b &&& c)) = 25 *  ~~~( ~~~a ||| (b ||| c)) + 24 * ( ~~~a &&& (b &&& c))

theorem lshrult_01_01_proof : lshrult_01_01_before ⊑ lshrult_01_01_after

theorem xor_lshr_proof : xor_lshr_before ⊑ xor_lshr_after

theorem e_1904 :
    1 *  ~~~(b &&& c) - 7 * ( ~~~a ||| (b ^^^ c)) + 11 * ((a &&& b) ^^^ (b |||  ~~~c)) + 4 * (a ^^^ ( ~~~b &&& c)) - 2 * (c ^^^ (a &&& b)) - 5 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) + 7 *  ~~~(a &&& (b ^^^ c)) - 1 * (b ^^^ ( ~~~a ||| (b ^^^ c))) - 5 *  ~~~(a ^^^ (b ||| c)) + 2 * (b ^^^ (a ||| (b ||| c))) - 7 *  ~~~(a &&& ( ~~~b &&& c)) + 1 * (c ^^^ (a ||| ( ~~~b &&& c))) - 3 * (b &&&  ~~~(a ^^^ c)) - 2 * ( ~~~b |||  ~~~(a ^^^ c)) - 2 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 7 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 1 * ((a ^^^ b) |||  ~~~(a ^^^ c)) + 3 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) + 3 * ( ~~~a ||| ( ~~~b &&& c)) + 1 *  ~~~( ~~~a ||| (b ^^^ c)) - 7 * (b |||  ~~~c) + 2 * (a |||  ~~~c) - 1 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) - 3 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 11 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) + 3 * (b ^^^  ~~~(a &&& (b &&& c))) - 5 * (b ||| (a &&&  ~~~c)) + 2 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 2 * (b &&&  ~~~(a &&& c)) - 11 * ((a ||| b) &&& (b ^^^ c)) - 6 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 1 * (a ^^^ c) + 7 * ((a &&&  ~~~b) ||| (b ^^^ c)) - 5 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 2 * (c &&&  ~~~(a &&& b)) + 2 * (b ^^^ (a |||  ~~~c)) + 5 * (c ^^^  ~~~(a &&& (b ||| c))) - 5 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 3 * ( ~~~a ||| ( ~~~b ||| c)) + 3 * ((a &&& b) ^^^ (b ||| c)) - 5 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) + 7 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) + 23 *  ~~~(a ||| (b ||| c)) + 19 *  ~~~(a ||| ( ~~~b ||| c)) - 6 *  ~~~( ~~~a ||| (b ||| c)) + 56 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 2 * ( ~~~a &&& ( ~~~b &&& c)) + 23 * ( ~~~a &&& (b &&& c)) + 11 * (a &&& ( ~~~b &&& c)) + 31 * (a &&& (b &&& c)) = 7 * (b &&& (a ||| c))

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

theorem bools2_logical_commute1_and1_thm.extracted_1._4 : ∀ (x x_1 : BitVec 1),
  ¬x_1 &&& x = 1#1 → ¬x ^^^ 1#1 = 1#1 → ¬x = 1#1 → 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 logical_or_bitwise_or_icmps_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8),
  ¬ofBool (x_2 == 42#8) ||

theorem fixed (x : BitVec 4) (y : BitVec 7) : 
    (BitVec.signExtend 32 x < BitVec.signExtend 32 y) ↔ (BitVec.signExtend 7 x < y)

theorem eq_umin4_proof : eq_umin4_before ⊑ eq_umin4_after

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

theorem tryFactorization_xor_lshr_ashr_proof : tryFactorization_xor_lshr_ashr_before ⊑ tryFactorization_xor_lshr_ashr_after

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

theorem ashr_ule_noexact_thm (e : IntW 8) :
  icmp IntPred.ule (ashr e (const? 8 3)) (const? 8 10) ⊑ icmp IntPred.ult e (const? 8 88)

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

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

theorem test43_thm.extracted_1._1 : ∀ (x : BitVec 8), True ∧ (zeroExtend 32 x).saddOverflow (-1#32) = true → False

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

theorem zext_sext_sgt_known_nonneg_proof : zext_sext_sgt_known_nonneg_before ⊑ zext_sext_sgt_known_nonneg_after

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

theorem test_ashr_exact__exact_is_safe_thm (e : IntW 64) (e_1 : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e_1 (const? 32 (-2147483588))) (const? 32 0)) e
      (ashr e (zext 64 (ashr (LLVM.and e_1 (const? 32 (-2147483588))) (const? 32 2) { «exact» := true }))) ⊑
    ashr e (zext 64 (LLVM.and (ashr e_1 (const? 32 2)) (const? 32 (-536870897))) { «nneg» := true })

theorem slt_and_not_max_logical_proof : slt_and_not_max_logical_before ⊑ slt_and_not_max_logical_after

theorem test5_proof : test5_before ⊑ test5_after

theorem xor_or_xor_proof : xor_or_xor_before ⊑ xor_or_xor_after
</all_available_lemmas>

<local_ctx>
import LeanMLIR.Framework

import Mathlib.Tactic.Linarith

import Mathlib.Tactic.DepRewrite

open Ctxt (Var Valuation Hom)

namespace DCE

structure DeleteRange (Γ : Ctxt Ty) where
   
  start : Fin (Γ.length + 1)
   
  num : Fin (Γ.length + 1 - start.val)

open DCE (DeleteRange)

namespace DeleteRange

def appendInl {Γ : Ctxt Ty} {ts : List Ty}
    (r : DeleteRange Γ) : DeleteRange (⟨ts⟩ ++ Γ) where
  start := ⟨r.start + ts.length, by admit /- proof elided -/
  ⟩
  num := ⟨r.num, by admit /- proof elided -/
  ⟩

section Lemmas

end Lemmas

end DeleteRange

end DCE

open DCE (DeleteRange)

def Ctxt.delete (Γ : Ctxt Ty) (vs : DeleteRange Γ) : Ctxt Ty :=
  Ctxt.ofList <| List.ofFn (n := Γ.length - vs.num.val) fun i =>
    have := vs.start.prop
    if hi : i.val < vs.start then
      Γ[i.val]
    else
      Γ[i.val + vs.num]

section Lemmas

variable {Γ : Ctxt Ty}

end Lemmas

def Hom.delete {Γ : Ctxt Ty} (delv : DeleteRange Γ) : Hom (Γ.delete delv) Γ :=
  fun t' v =>
    let idx :=
      if v.val < delv.start then
        v.val
      else
        v.val + delv.num
    ⟨idx, by admit /- proof elided -/
    ⟩

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

def Deleted.toHom (h : Deleted Γ r Γ') : Γ'.Hom Γ :=
  fun _ v => Hom.delete r (v.castCtxt h)
</local_ctx>

<target_theorem>
@[simp] lemma Deleted.toHom_append {Γ Γ' : Ctxt Ty} {vs : DeleteRange Γ}
    (DEL : Deleted (⟨us⟩ ++ Γ) vs.appendInl (⟨us⟩ ++ Γ')) :
    DEL.toHom
    = have DEL' : Deleted Γ vs Γ' :=
</target_theorem>

