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>
Nat in Init.Prelude
Bool in Init.Prelude
Polynomial.X in Mathlib.Algebra.Polynomial.Basic
ZMod in Mathlib.Data.ZMod.Defs
Inhabited in Init.Prelude
Lean.ToExpr in Lean.ToExpr
Repr in Init.Data.Repr
BitVec in Init.Prelude
BitVec.zero in Init.Data.BitVec.Basic
Fin in Init.Prelude
NFA in Mathlib.Computability.NFA
Fin.last in Init.Data.Fin.Basic
NFA.accept in Mathlib.Computability.NFA
NFA.start in Mathlib.Computability.NFA
NFA.step in Mathlib.Computability.NFA
Fin.mk in Init.Prelude
FinEnum in Mathlib.Data.FinEnum
BitVec.ofFin in Init.Prelude
Set in Mathlib.Data.Set.Defs
SetRel in Mathlib.Data.Rel
BEq in Init.Prelude
DecidableEq in Init.Prelude
Hashable in Init.Prelude
Std.HashMap in Std.Data.HashMap.Basic
Std.HashSet in Std.Data.HashSet.Basic
Finset in Mathlib.Data.Finset.Defs
Finset.range in Mathlib.Data.Finset.Range
LawfulBEq in Init.Core

abbrev State := Nat

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

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

instance RawCNFA.statesFinset (m : RawCNFA A) : Fintype m.states := (Finset.range m.stateMax).fintypeCoeSort

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

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

def CNFA.Sim (m : CNFA n) (M : NFA' n) :=
  m.m.Sim M.M

def RawCNFA.Sim (m : RawCNFA A) (A : NFA A S) := ∃ R, RawCNFA.Simul m A R ⊤ ∅

structure RawCNFA.Simul (m : RawCNFA A) (M : NFA A Q) (R : SetRel State Q) (D : Set Q) (T : Set (Q × A × Q)) where
  accept {s q} : s ~[R] q → (s ∈ m.finals ↔ q ∈ M.accept)
  initial₁ {s} : s ∈ m.initials → ∃ q ∈ M.start, s ~[R] q
  initial₂ {q} : q ∈ M.start → ∃ s ∈ m.initials, s ~[R] q
  trans_match₁ {s s' a q} : s ~[R] q → s' ∈ m.tr s a → ∃ q', q' ∈ M.step q a ∧ s' ~[R] q'
  trans_match₂ {s a q q'} : s ~[R] q → q' ∈ M.step q a → q ∈ D → (q, a, q') ∉ T → ∃ s', s' ∈ m.tr s a ∧ s' ~[R] q'

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

@[inline]
def RawCNFA.tr (m : RawCNFA A) s a := m.trans.getD (s, a) ∅

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

structure CNFA (n : Nat) where
  m : RawCNFA (BitVec n)
  wf : m.WF

structure NFA' (n : Nat) where
  σ : Type
  M : NFA (BitVec n) σ

abbrev zero   : BitStream := fun _ => false

def BitStream : Type := Nat → Bool

def RawCNFA.states (m : RawCNFA A) : Finset State := Finset.range m.stateMax

structure RawCNFA.WF (m : RawCNFA A) where
  initials_lt : ∀ {s}, s ∈ m.initials → s ∈ m.states
  finals_lt : ∀ {s}, s ∈ m.finals → s ∈ m.states
  trans_src_lt : ∀ s_a ∈ m.trans, s_a.1 ∈ m.states
  trans_tgt_lt : s' ∈ m.tr s a → s' ∈ m.states

def RawCNFA.addTrans (m : RawCNFA A) (a : A) (s s' : State) : RawCNFA A :=
  let ns := m.trans.getD (s, a) ∅
  let ns := ns.insert s'
  { m with trans :=  m.trans.insert (s, a) ns }

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

def RawCNFA.addInitial (m : RawCNFA A) (s : State) : RawCNFA A :=
  { m with initials := m.initials.insert s }

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

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

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

def sub_sext_mask1_trunc_lshr_after := [llvm|
{
^0(%arg16 : i64):
  %0 = llvm.mlir.constant(48) : i64
  %1 = llvm.mlir.constant(63) : i64
  %2 = llvm.mlir.constant(10 : i8) : i8
  %3 = llvm.shl %arg16, %0 : i64
  %4 = llvm.ashr %3, %1 : i64
  %5 = llvm.trunc %4 overflow<nsw> : i64 to i8
  %6 = llvm.add %5, %2 overflow<nsw> : i8
  %7 = llvm.zext %6 : i8 to i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

def zext_zext_eq_after := [llvm|
{
^0(%arg80 : i8, %arg81 : i8):
  %0 = llvm.icmp "eq" %arg80, %arg81 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

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

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

def mul_add_to_mul_9_after := [llvm|
{
^0(%arg23 : i16):
  %0 = llvm.mlir.constant(15 : i16) : i16
  %1 = llvm.shl %arg23, %0 : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

class HydrableGetNegativeExamples (parsedExpr : Type) (genLogicalExpr : outParam Type) (genExpr : outParam (Nat → Type)) extends
  HydrableSolve parsedExpr genLogicalExpr genExpr,
  HydrableBooleanAlgebra genLogicalExpr genExpr,
  HydrableGenExpr genExpr

def test_mul_nuw_nsw__all_are_safe_before := [llvm|
{
^0(%arg15 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.mlir.constant(17 : i32) : i32
  %2 = llvm.mlir.constant(9 : i32) : i32
  %3 = llvm.mlir.constant(153 : i32) : i32
  %4 = llvm.and %arg15, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.mul %4, %2 overflow<nsw,nuw> : i32
  %7 = "llvm.select"(%5, %3, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

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

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

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

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

Nat.cast in Init.Data.Cast

@[inline]
def CNFA.proj (m: CNFA n2) (f : Fin n1 → Fin n2) : CNFA n1 :=
  ⟨m.m.proj f, m.m.proj_wf m.wf⟩

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

def Eqn.numVars (e : Eqn) : Nat :=
  match e with
  | [] => 0
  | e :: es => max e.numVars (Eqn.numVars es)

Set.union in Mathlib.Data.Set.Defs

def no_reassoc_add_nuw_none_before := [llvm|
{
^0(%arg23 : i32):
  %0 = llvm.mlir.constant(4 : i32) : i32
  %1 = llvm.mlir.constant(64 : i32) : i32
  %2 = llvm.add %arg23, %0 : i32
  %3 = llvm.add %2, %1 overflow<nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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 sel_sext_constants_before := [llvm|
{
^0(%arg97 : i1):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(42 : i8) : i8
  %2 = "llvm.select"(%arg97, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %3 = llvm.sext %2 : i8 to i16
  "llvm.return"(%3) : (i16) -> ()
}
]

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

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

structure GenConfig where
  specialize : Bool := false

declare_config_elab elabGenConfig GenConfig

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

def srai_i32_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := srai_llvm_i64
  rhs := srai_riscv_i64

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

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

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

def llvm_const_lower_riscv_li_25 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_25, rhs:= liRiscv_25,
   correct := by admit /- proof elided -/

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

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

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

def liftMax2 (n m : Nat) : Fin m → Fin (max n m) :=
  fun k => k.castLE (by admit /- proof elided -/
  )

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

instance :  HydrableCheckTimeout GenBVPred where

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

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

def Vector.ofArray {α : Type u} (a : Array α) : List.Vector α a.size :=
 Vector.ofList a.toList

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

def uge_or_max_logical_after := [llvm|
{
^0(%arg172 : i8, %arg173 : i8):
  %0 = llvm.icmp "uge" %arg172, %arg173 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

def rhs : Com ScfArith ⟨[.int]⟩ .impure .int :=
  Com.ret ⟨0, by admit /- proof elided -/
  ⟩

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

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

def rev8_mul_and_lshr_after := [llvm|
{
^0(%arg29 : i8):
  %0 = llvm.mlir.constant(2050) : i64
  %1 = llvm.mlir.constant(139536) : i64
  %2 = llvm.mlir.constant(32800) : i64
  %3 = llvm.mlir.constant(558144) : i64
  %4 = llvm.mlir.constant(65793) : i64
  %5 = llvm.mlir.constant(16) : i64
  %6 = llvm.zext %arg29 : i8 to i64
  %7 = llvm.mul %6, %0 overflow<nsw,nuw> : i64
  %8 = llvm.and %7, %1 : i64
  %9 = llvm.mul %6, %2 overflow<nsw,nuw> : i64
  %10 = llvm.and %9, %3 : i64
  %11 = llvm.or disjoint %8, %10 : i64
  %12 = llvm.mul %11, %4 overflow<nsw,nuw> : i64
  %13 = llvm.lshr %12, %5 : i64
  %14 = llvm.trunc %13 : i64 to i8
  "llvm.return"(%14) : (i8) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

def ValueStream := Stream

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

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

DFA in Mathlib.Computability.DFA

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

def udiv_i80_before := [llvm|
{
^0(%arg2 : i80):
  %0 = llvm.mlir.constant(2 : i80) : i80
  %1 = llvm.mlir.constant(100 : i80) : i80
  %2 = llvm.lshr %arg2, %0 : i80
  %3 = llvm.udiv %2, %1 : i80
  "llvm.return"(%3) : (i80) -> ()
}
]

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

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

def or_or_xor_commute1_before := [llvm|
{
^0(%arg103 : i4, %arg104 : i4, %arg105 : i4):
  %0 = llvm.or %arg103, %arg105 : i4
  %1 = llvm.or %arg105, %arg104 : i4
  %2 = llvm.xor %0, %1 : i4
  "llvm.return"(%2) : (i4) -> ()
}
]

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 test2_after := [llvm|
{
^0(%arg4 : i32, %arg5 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.xor %arg4, %arg5 : i32
  %2 = llvm.icmp "eq" %arg4, %arg5 : i32
  %3 = llvm.icmp "eq" %1, %0 : i32
  %4 = llvm.xor %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

unsafe def elabIntoTermTactic {α : Type} (expectedType : Expr) (stx : Lean.Syntax) :
    Elab.Tactic.TacticM α := do
  let expr ← Lean.Elab.Tactic.elabTerm stx none
  let _ ← Meta.isDefEq (← Meta.inferType expr) expectedType
  Elab.Term.synthesizeSyntheticMVarsNoPostponing
  let expr ← instantiateMVars expr
  Meta.evalExpr α expectedType expr

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

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

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

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

def invert_both_cmp_operands_complex_before := [llvm|
{
^0(%arg32 : i1, %arg33 : i32, %arg34 : i32, %arg35 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg33, %0 : i32
  %2 = llvm.xor %arg34, %0 : i32
  %3 = llvm.xor %arg35, %0 : i32
  %4 = llvm.add %arg35, %1 : i32
  %5 = "llvm.select"(%arg32, %4, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %6 = llvm.icmp "sle" %5, %3 : i32
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

SMul in Init.Prelude

@[simp_llvm_option]
def or {w : Nat} (x y : IntW w)  (flag : DisjointFlag := {disjoint := false}) : IntW w := do
  let x' ← x
  let y' ← y
  if flag.disjoint ∧ x' &&& y' != 0 then
    .poison
  else
    or? x' y'

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

def par_after := [llvm|
{
^0(%arg81 : i32, %arg82 : i32, %arg83 : i32, %arg84 : i32):
  %0 = llvm.icmp "slt" %arg81, %arg82 : i32
  %1 = "llvm.select"(%0, %arg83, %arg84) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%1) : (i32) -> ()
}
]

CommRing in Mathlib.Algebra.Ring.Defs

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

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

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

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

def test5_after := [llvm|
{
^0(%arg31 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(1073741823 : i32) : i32
  %2 = llvm.ashr %arg31, %0 : i32
  %3 = llvm.add %2, %1 overflow<nsw> : i32
  %4 = llvm.sext %3 : i32 to i64
  "llvm.return"(%4) : (i64) -> ()
}
]

def src_is_mask_xor_fail_notmask_after := [llvm|
{
^0(%arg113 : i8, %arg114 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(-124 : i8) : i8
  %2 = llvm.mlir.constant(-1 : i8) : i8
  %3 = llvm.sub %0, %arg114 : i8
  %4 = llvm.xor %arg114, %3 : i8
  %5 = llvm.xor %arg113, %1 : i8
  %6 = llvm.or %4, %5 : i8
  %7 = llvm.icmp "ne" %6, %2 : i8
  "llvm.return"(%7) : (i1) -> ()
}
]

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

def srai_test: LLVMPeepholeRewriteRefine 16 [Ty.llvm (.bitvec 16)] where
  lhs := srai_llvm
  rhs := srai_riscv

List.Mem.tail in Init.Data.List.Basic

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

def shift_xor_multiuse_cmp_after := [llvm|
{
^0(%arg84 : i32, %arg85 : i32, %arg86 : i32, %arg87 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(2048 : i32) : i32
  %3 = llvm.and %arg84, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.or %arg85, %2 : i32
  %6 = "llvm.select"(%4, %5, %arg85) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg87, %arg86) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %8 = llvm.mul %6, %7 : i32
  "llvm.return"(%8) : (i32) -> ()
}
]

def t1_after := [llvm|
{
^0(%arg16 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.ashr %arg16, %0 : i8
  %2 = llvm.sext %1 : i8 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

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

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

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

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

def 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 test6_before := [llvm|
{
^0(%arg21 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.udiv %0, %arg21 : i32
  %3 = llvm.icmp "ugt" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

def main7f_after := [llvm|
{
^0(%arg44 : i32, %arg45 : i32, %arg46 : i32, %arg47 : i32, %arg48 : i32):
  %0 = llvm.and %arg45, %arg47 : i32
  %1 = llvm.and %arg46, %arg48 : i32
  %2 = llvm.or %0, %1 : i32
  %3 = llvm.and %arg44, %2 : i32
  %4 = llvm.icmp "ne" %3, %2 : i32
  %5 = llvm.zext %4 : i1 to i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

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

def ofList {Γ : Ctxt _} ty : (l : List ((ty : Comb.Ty) × Γ.Var ty)) → (h : l.all (·.1 = ty)) → HVector (Γ.Var) (List.replicate l.length ty)
| [], h => .nil
| ⟨ty', var⟩::rest, h =>
  have hty : ty' = ty := by admit /- proof elided -/

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

@[tactic medusaSynthGeneralize]
def evalBvGeneralize : Tactic
  | `(tactic| md_synth_generalize $cfg) => do
      let cfg ← elabMedusaSynthGeneralizeConfig cfg
      withMainContext do
        generalizeTactic (H := bvHydrableParseAndGeneralize) cfg (← getMainTarget)
  | _ => Lean.Elab.throwUnsupportedSyntax

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

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

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

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

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

def llvm_const_lower_riscv_li_22 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_22, rhs:= liRiscv_22,
   correct := by admit /- proof elided -/

def icmp_eq_or_z_or_pow2orz_fail_bad_pred2_after := [llvm|
{
^0(%arg6 : i8, %arg7 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.sub %0, %arg7 : i8
  %3 = llvm.and %arg7, %2 : i8
  %4 = llvm.icmp "slt" %arg6, %1 : i8
  %5 = llvm.icmp "sle" %arg6, %3 : i8
  %6 = llvm.or %4, %5 : i1
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

def lshrult_02_05_exact_after := [llvm|
{
^0(%arg128 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "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 Tensor2d'.fill (v : β) (t : Tensor2d' α) : Tensor2d' β := t.map (const v)

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

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

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

RV64.srl in RISCV.Instructions

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

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

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

@[simp_denote]
def add_llvm_no_flags_16 := [LV| {
  ^entry (%lhs: i16, %rhs: i16):
    %1 = llvm.add %lhs, %rhs : i16
    llvm.return %1 : i16
  }]

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

def t2_after := [llvm|
{
^0(%arg25 : i8, %arg26 : i1, %arg27 : i1):
  %0 = llvm.sext %arg26 : i1 to i8
  %1 = llvm.sext %arg27 : i1 to i8
  %2 = llvm.add %arg25, %0 : i8
  %3 = llvm.xor %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

@[simp_sllvm]
def LLVM.IntW.canBe (x : LLVM.IntW w) (y : BitVec w) : Bool :=
  x = .poison ∨ x = .value y

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

def emptyElim {α : Sort _} {t : Ty} : Ctxt.Var ∅ t → α :=
  fun ⟨_, h⟩ => by admit /- proof elided -/

instance [Semiring α] : Semiring (Holor α ds) :=

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

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

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

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

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

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

def no_masks_with_logical_or2_before := [llvm|
{
^0(%arg7 : i32, %arg8 : i32, %arg9 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(63 : i32) : i32
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.icmp "ne" %arg7, %0 : i32
  %4 = llvm.icmp "ne" %arg8, %1 : i32
  %5 = "llvm.select"(%3, %2, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %6 = llvm.icmp "ne" %arg9, %0 : i32
  %7 = llvm.or %5, %6 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

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

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

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

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

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

@[reducible]
instance : TyDenote ExTy where
  toType
    | .nat => Nat

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

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

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

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

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

def bv2' : BitVec 4 := BitVec.ofNat 4 6

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

def sdiv_exact_eq_9_no_of_before := [llvm|
{
^0(%arg8 : i8, %arg9 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(9 : i8) : i8
  %2 = llvm.and %arg9, %0 : i8
  %3 = llvm.sdiv exact %arg8, %2 : i8
  %4 = llvm.icmp "eq" %3, %1 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

def simplify_or_common_op_commute0_after := [llvm|
{
^0(%arg45 : i4, %arg46 : i4, %arg47 : i4):
  %0 = llvm.mlir.constant(-1 : i4) : i4
  "llvm.return"(%0) : (i4) -> ()
}
]

def llvm_shl_lower_riscv_nuw_8: LLVMPeepholeRewriteRefine 8 [Ty.llvm (.bitvec 8), Ty.llvm (.bitvec 8)] where
  lhs := shl_llvm_nuw_8
  rhs := shl_riscv_8

noncomputable def R.toTensor {q n} (a : R q n) : List Int :=
  List.range a.repLength |>.map fun i =>
        a.coeff i |>.toInt

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

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

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

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

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

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

def getVarWidth {Γ : Ctxt HSxComb.Ty} : (Σ t, Γ.Var t) → Nat
  | ⟨.stream _, _⟩ => 1
  | ⟨.stream2 _, _⟩ => 1
  | ⟨.stream2token (.bitvec w), _⟩ => w

instance : One Term := ⟨one⟩

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

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

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

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

structure Item where
 name : String
 tac : Syntax

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

def urem_common_dividend_defined_cond_after := [llvm|
{
^0(%arg13 : i1, %arg14 : i5, %arg15 : i5, %arg16 : i5):
  %0 = "llvm.select"(%arg13, %arg16, %arg15) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i5, i5) -> i5
  %1 = llvm.urem %arg14, %0 : i5
  "llvm.return"(%1) : (i5) -> ()
}
]

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

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

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

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

def 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

@[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 test9_after := [llvm|
{
^0(%arg198 : i32, %arg199 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg199, %0 : i32
  %2 = llvm.or %arg198, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def or_ashr_not_commuted_after := [llvm|
{
^0(%arg51 : i8, %arg52 : i8, %arg53 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.xor %arg52, %0 : i8
  %2 = llvm.or %arg51, %1 : i8
  %3 = llvm.ashr %2, %arg53 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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

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

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

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

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

def add_nsw_mul_nsw_before := [llvm|
{
^0(%arg33 : i16):
  %0 = llvm.add %arg33, %arg33 overflow<nsw> : i16
  %1 = llvm.add %0, %arg33 overflow<nsw> : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

def test1_before := [llvm|
{
^0(%arg3 : i33):
  %0 = llvm.mlir.constant(4096 : i33) : i33
  %1 = llvm.urem %arg3, %0 : i33
  "llvm.return"(%1) : (i33) -> ()
}
]

def t9_nocse_after := [llvm|
{
^0(%arg9 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.shl %0, %arg9 overflow<nuw> : i8
  %3 = llvm.shl %1, %arg9 overflow<nsw> : i8
  %4 = llvm.xor %3, %1 : i8
  %5 = llvm.or %2, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def  shift_mul:=
  [llvm(64)| {
  ^bb0(%X : _, %Y : _):
    %c1 = llvm.mlir.constant(1)
    %poty = llvm.shl %c1, %Y
    %r = llvm.mul %poty, %X
    llvm.return %r
  }]

@[simp_denote]
def select_riscv_32 := [LV| {
  ^entry (%cond : i1, %arg0: i32, %arg1: i32):
    %0 = "builtin.unrealized_conversion_cast" (%arg0) : (i32) -> (!i64)
    %1 = "builtin.unrealized_conversion_cast" (%arg1) : (i32) -> (!i64)
    %2 = "builtin.unrealized_conversion_cast" (%cond) : (i1) -> (!i64)
    %3 = snez %2 : !i64
    %4 = sub %0, %1 : !i64
    %5 = mul %4, %3 : !i64
    %6 = add %5, %1 : !i64
    %7 = "builtin.unrealized_conversion_cast" (%6) : (!i64) -> (i32)
    llvm.return %7 : i32
  }]

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

def test11_before := [llvm|
{
^0(%arg30 : i23):
  %0 = llvm.mlir.constant(3 : i23) : i23
  %1 = llvm.mlir.constant(11 : i23) : i23
  %2 = llvm.mlir.constant(12 : i23) : i23
  %3 = llvm.mul %arg30, %0 : i23
  %4 = llvm.lshr %3, %1 : i23
  %5 = llvm.shl %4, %2 : i23
  "llvm.return"(%5) : (i23) -> ()
}
]

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

def icmp_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 llvm_const_lower_riscv_li11 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM11, rhs:= liRiscv11,
   correct := by admit /- proof elided -/

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

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

def CollectState.pcard (state : CollectState) : Nat :=
  state.pToIx.size

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

def 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 lshr_xor_or_good_mask_after := [llvm|
{
^0(%arg108 : i8, %arg109 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.mlir.constant(48 : i8) : i8
  %2 = llvm.or %arg109, %arg108 : i8
  %3 = llvm.lshr %2, %0 : i8
  %4 = llvm.or disjoint %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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 mul_of_pow2_commute_before := [llvm|
{
^0(%arg81 : i32, %arg82 : i32):
  %0 = llvm.mlir.constant(4 : i32) : i32
  %1 = llvm.mlir.constant(255 : i32) : i32
  %2 = llvm.mlir.constant(1020 : i32) : i32
  %3 = llvm.and %arg81, %0 : i32
  %4 = llvm.and %arg82, %1 : i32
  %5 = llvm.mul %4, %3 : i32
  %6 = llvm.icmp "ugt" %5, %2 : i32
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

def test40_after := [llvm|
{
^0(%arg153 : i16):
  %0 = llvm.mlir.constant(9 : i16) : i16
  %1 = llvm.mlir.constant(8 : i16) : i16
  %2 = llvm.lshr %arg153, %0 : i16
  %3 = llvm.shl %arg153, %1 : i16
  %4 = llvm.or disjoint %2, %3 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

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 test_with_5_after := [llvm|
{
^0(%arg315 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "eq" %arg315, %0 : i32
  %2 = llvm.zext %1 : i1 to i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

def trunc_sel_equal_zext_after := [llvm|
{
^0(%arg65 : i32, %arg66 : i1):
  %0 = llvm.mlir.constant(65535 : i32) : i32
  %1 = llvm.mlir.constant(42 : i32) : i32
  %2 = llvm.and %arg65, %0 : i32
  %3 = "llvm.select"(%arg66, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def llvm_ashr_lower_riscv_no_flag_64 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := ashr_llvm_no_flag_64
  rhs := ashr_riscv_64

def TypedSSAVal.mkVal' [instTransformTy : TransformTy d φ] (Γ : Ctxt d.Ty) : TypedSSAVal φ →
    ReaderM d (Σ (ty : d.Ty), Ctxt.Var Γ ty)
| (.name valStx, tyStx) => do
    let ty ← instTransformTy.mkTy tyStx
    let var ← getValFromCtxt Γ valStx ty
    return ⟨ty, var⟩

RV64.zexth in RISCV.Instructions

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 or_not_and_commute7_after := [llvm|
{
^0(%arg516 : i32, %arg517 : i32, %arg518 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg517, %arg518 : i32
  %2 = llvm.xor %arg516, %0 : i32
  %3 = llvm.and %1, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

def icmp_then_sub := [LV| {
  ^entry (%a: i64, %b: i64):
    %0= llvm.icmp.eq %a, %b : i64
    %1 = "builtin.unrealized_conversion_cast" (%0) : (i1) -> (!riscv.reg)
    %2= add %1, %1: !riscv.reg
    %3 = "builtin.unrealized_conversion_cast" (%2) : (!riscv.reg) -> (i1)
    llvm.return %3 : i1
  }]

def test_or3_before := [llvm|
{
^0(%arg28 : i32, %arg29 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg29, %0 : i32
  %3 = llvm.icmp "sle" %2, %arg28 : i32
  %4 = llvm.icmp "slt" %arg28, %1 : i32
  %5 = llvm.or %3, %4 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

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

def sle_swap_or_not_min_before := [llvm|
{
^0(%arg280 : i8, %arg281 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.icmp "sge" %arg281, %arg280 : i8
  %2 = llvm.icmp "ne" %arg280, %0 : i8
  %3 = llvm.or %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

def 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 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 test35_with_trunc_after := [llvm|
{
^0(%arg48 : i64):
  %0 = llvm.mlir.constant(2147483648) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.mlir.constant(60 : i32) : i32
  %3 = llvm.mlir.constant(100 : i32) : i32
  %4 = llvm.and %arg48, %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 src_is_mask_select_after := [llvm|
{
^0(%arg110 : i8, %arg111 : i8, %arg112 : 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 %arg111, %0 : i8
  %4 = llvm.xor %arg111, %3 : i8
  %5 = "llvm.select"(%arg112, %4, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %6 = llvm.xor %arg110, %2 : i8
  %7 = llvm.icmp "ugt" %6, %5 : i8
  "llvm.return"(%7) : (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 fold_sext_to_and_wrong8_after := [llvm|
{
^0(%arg2 : i8):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

def BranchEg1 := [handshake_com| {
  ^entry(%0: !Stream_BitVec_1, %1: !Stream_BitVec_1):
    %out = "handshake.branch" (%0, %1) : (!Stream_BitVec_1, !Stream_BitVec_1) -> (!Stream2_BitVec_1)
    %outf = "handshake.fst" (%out) : (!Stream2_BitVec_1) -> (!Stream_BitVec_1)
    %outs = "handshake.snd" (%out) : (!Stream2_BitVec_1) -> (!Stream_BitVec_1)
    %out2 = "handshake.merge" (%outs, %outf) : (!Stream_BitVec_1, !Stream_BitVec_1) -> (!Stream_BitVec_1)
    "return" (%out2) : (!Stream_BitVec_1) -> ()
  }]

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

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

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

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

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

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

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

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

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

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

def shl_and_and_fail_after := [llvm|
{
^0(%arg170 : i8, %arg171 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.mlir.constant(5 : i8) : i8
  %2 = llvm.mlir.constant(64 : i8) : i8
  %3 = llvm.shl %arg170, %0 : i8
  %4 = llvm.shl %arg171, %1 : i8
  %5 = llvm.and %4, %2 : i8
  %6 = llvm.and %3, %5 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

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

def or_sext_to_sel_after := [llvm|
{
^0(%arg25 : i32, %arg26 : i1):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = "llvm.select"(%arg26, %0, %arg25) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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 test17_before := [llvm|
{
^0(%arg80 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.urem %0, %arg80 : i32
  "llvm.return"(%1) : (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 -/

def unmasked_shlop_insufficient_mask_shift_amount_before := [llvm|
{
^0(%arg14 : i16, %arg15 : i16, %arg16 : i16):
  %0 = llvm.mlir.constant(15 : i16) : i16
  %1 = llvm.mlir.constant(255 : i16) : i16
  %2 = llvm.mlir.constant(8 : i16) : i16
  %3 = llvm.and %arg16, %0 : i16
  %4 = llvm.and %arg14, %1 : i16
  %5 = llvm.sub %2, %3 : i16
  %6 = llvm.shl %arg15, %5 : i16
  %7 = llvm.lshr %4, %3 : i16
  %8 = llvm.or %6, %7 : i16
  %9 = llvm.trunc %8 : i16 to i8
  "llvm.return"(%9) : (i8) -> ()
}
]

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

def rewrite00 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs:= [LV| {
  ^entry (%arg: i64, %amount: i64):
    %0 = llvm.shl %arg, %amount : i64
    %1 = llvm.lshr %0, %amount : i64
    llvm.return %1 : i64
  }]

  rhs:= [LV| {
  ^entry (%arg: i64, %amount: i64):
    llvm.return %arg : i64
  }]
  correct := by admit /- proof elided -/

ReaderT.run in Init.Prelude

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

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

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

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

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

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

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

@[simp_denote]
def freeze_llvm_8 := [LV| {
  ^entry (%x: i8):
    %0 = llvm.freeze %x: i8
    llvm.return %0 : i8
  }]

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

@[simp]
def NFA'.autWidth_spec : (autWidth wp n).accepts = { bv | wp.sat bv.w n } :=

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

Int.sub in Init.Data.Int.Basic

def positive_samevar_shlnuwnsw_ashrexact_after := [llvm|
{
^0(%arg27 : i8, %arg28 : i8):
  "llvm.return"(%arg27) : (i8) -> ()
}
]

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 negate_sdiv_after := [llvm|
{
^0(%arg116 : i8, %arg117 : i8):
  %0 = llvm.mlir.constant(-42 : i8) : i8
  %1 = llvm.sdiv %arg117, %0 : i8
  %2 = llvm.add %1, %arg116 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

abbrev MLIRTy (φ := 0) := MLIRType φ

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

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

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

def poo_before := [llvm|
{
^0(%arg101 : i32, %arg102 : i32, %arg103 : i32, %arg104 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.icmp "slt" %arg101, %arg102 : i32
  %3 = "llvm.select"(%2, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.and %3, %arg103 : i32
  %5 = "llvm.select"(%2, %1, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %6 = llvm.and %5, %arg104 : i32
  %7 = llvm.or %4, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

@[simp_denote]
def add_b31_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := add_b31_llvm_i64
  rhs := add_b31_riscv_i64

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

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

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

def cst {Γ : Ctxt _} (n : ℕ) : Expr Ex Γ .pure [.nat] :=
  Expr.mk
    (op := .cst n)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .nil)
    (regArgs := .nil)

def test21_before := [llvm|
{
^0(%arg174 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.trunc %arg174 : i32 to i8
  %2 = llvm.sext %1 : i8 to i32
  %3 = llvm.and %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

@[simp_denote]
def zext_llvm_1_to_32 := [LV| {
  ^entry (%arg: i1):
    %0 = llvm.zext %arg: i1 to i32
    llvm.return %0: i32
  }]

def icmp_uge_x_y_2_before := [llvm|
{
^0(%arg36 : i8, %arg37 : i8):
  %0 = llvm.mul %arg36, %arg36 : i8
  %1 = llvm.and %0, %arg37 : i8
  %2 = llvm.icmp "ule" %0, %1 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

def Expr.KInductionCircuits.mkMkSafetyCircuit (circs : Expr) : MetaM Expr :=
  mkAppM ``ReflectVerif.BvDecide.KInductionCircuits.mkSafetyCircuit #[circs]

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 Var (Γ : Ctxt Ty) (t : Ty) : Type :=
  { i : Nat // Γ[i]? = some t }

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

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

partial def deductiveSearch (expr: FpExpr w) (constants: Std.HashMap Nat FpExprWrapper)
      (target: FpExprWrapper) (depth: Nat) (parent: Nat) : TermElabM (List (FpExpr target.width)) := do
  return []

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

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

Fact in Mathlib.Logic.Basic

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

@[simp]
def casesOn_toCons
    {motive : (Γ : Ctxt Ty) → (t t' : Ty) → Ctxt.Var (Γ.cons t') t → Sort _}
    {Γ : Ctxt Ty} {t t' : Ty} (v : Γ.Var t)
    (base : {t t' : Ty} →
        {Γ : Ctxt Ty} → (v : Γ.Var t) → motive Γ t t' v.toCons)
    (last : {Γ : Ctxt Ty} → {t : Ty} → motive Γ t t (Ctxt.Var.last _ _)) :
      Ctxt.Var.casesOn (motive := motive) (toCons (t' := t') v) base last = base v :=
  rfl

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

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

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

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

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

def and_add_bool_to_select_after := [llvm|
{
^0(%arg5 : i1, %arg6 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = "llvm.select"(%arg5, %0, %arg6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

def Eqn.denoteFin {w : Nat} (e : Eqn) (envFin : EnvFin w e.numVars) : Int :=
  match e with
  | [] => 0
  | t :: ts =>
    t.denoteFin (envFin.castLe (by admit /- proof elided -/
    )) +
    Eqn.denoteFin ts (envFin.castLe (by admit /- proof elided -/
    ))

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

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

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

Fin.elim0 in Init.Data.Fin.Basic

def eq_21_before := [llvm|
{
^0(%arg124 : i32, %arg125 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.lshr %arg124, %0 : i32
  %3 = llvm.trunc %2 : i32 to i8
  %4 = llvm.lshr %arg124, %1 : i32
  %5 = llvm.trunc %4 : i32 to i8
  %6 = llvm.lshr %arg125, %0 : i32
  %7 = llvm.trunc %6 : i32 to i8
  %8 = llvm.lshr %arg125, %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 %11, %10 : i1
  "llvm.return"(%12) : (i1) -> ()
}
]

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

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

instance : Lean.ToExpr TestDialect.Op :=

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

abbrev HasBool (d : Dialect) [TyDenote d.Ty] [DialectSignature d] : Type := HasTy d Bool

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

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

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

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

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

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

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

def or_basic_commuted_after := [llvm|
{
^0(%arg14 : i16):
  %0 = llvm.mlir.constant(32581 : i16) : i16
  %1 = llvm.icmp "ne" %arg14, %0 : i16
  "llvm.return"(%1) : (i1) -> ()
}
]

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

def resNames : List SSAVal :=
  op.res.map Prod.fst

Int.reduceNegSucc in Lean.Meta.Tactic.Simp.BuiltinSimprocs.Int

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

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

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

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

def t20_after := [llvm|
{
^0(%arg145 : i8, %arg146 : i16):
  %0 = llvm.mlir.constant(42 : i16) : i16
  %1 = llvm.shl %0, %arg146 : i16
  %2 = llvm.trunc %1 : i16 to i8
  %3 = llvm.add %arg145, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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

Std.Tactic.BVDecide.BVExpr.PackedBitVec in Std.Tactic.BVDecide.Bitblast.BVExpr.Basic

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

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

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

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 irc_constants_AMinusC1MinusC2_0_1 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (0) : i64
      %c2 = llvm.mlir.constant (1) : i64
      %0 = llvm.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 Env.ofEnvFin (envFin : EnvFin w n) : Env w := (List.finRange n).map envFin

@[reducible]
instance : DialectDenote ExOp ExTy where
  denote
    | .add, .cons (a : Nat) (.cons b .nil), _ => a + b
    | .runK (k : Nat), (.cons (v : Nat) .nil), (.cons rgn _nil) =>
      k.iterate (fun val => rgn (fun _ty _var => val)) v

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

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

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

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 llvm_trunc_riscv_32_to_8_nuw_nsw : LLVMPeepholeRewriteRefine 8 [Ty.llvm (.bitvec 32)] :=
  {lhs:= trunc_llvm_32_to_8_nsw_nuw, rhs:= trunc_riscv_32_to_8_nsw_nuw}

def Region.empty {φ} (name: String): Region φ := Region.mk name [] []

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

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

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

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 Vars.castLe {n m : Nat} (v : Vars σ ι n) (hnm : n ≤ m) : Vars σ ι m :=
  match v with
  | .state ss => .state (ss.castLe (by admit /- proof elided -/
  ))
  | .inputs is => .inputs (is.castLe hnm)
  | .outputs os =>
    .outputs (os.castLE (by admit /- proof elided -/
    ))

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

def 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 t0_after := [llvm|
{
^0(%arg12 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.and %arg12, %0 : i8
  %3 = llvm.sub %1, %2 overflow<nsw> : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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

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

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

@[simp_denote]
def add_llvm_nsw_nuw_flags_1 := [LV| {
   ^entry (%lhs: i1, %rhs: i1):
    %1 = llvm.add %lhs, %rhs overflow<nsw,nuw> : i1
    llvm.return %1 : 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 ne_optimized_highbits_cmp_before := [llvm|
{
^0(%arg20 : i32, %arg21 : i32):
  %0 = llvm.mlir.constant(16777215 : i32) : i32
  %1 = llvm.xor %arg21, %arg20 : i32
  %2 = llvm.icmp "ugt" %1, %0 : i32
  %3 = llvm.trunc %arg20 : i32 to i24
  %4 = llvm.trunc %arg21 : i32 to i24
  %5 = llvm.icmp "ne" %3, %4 : i24
  %6 = llvm.or %2, %5 : i1
  "llvm.return"(%6) : (i1) -> ()
}
]

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

def uge_or_not_max_commute_after := [llvm|
{
^0(%arg300 : i8, %arg301 : i8):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (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_shl_and_negC_eq_before := [llvm|
{
^0(%arg31 : i32, %arg32 : i32):
  %0 = llvm.mlir.constant(-262144 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %arg31, %arg32 : i32
  %3 = llvm.and %2, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

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

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

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

@[simp_denote]
def sra_llvm_i32 := [LV| {
    ^entry (%a: i32, %b: i32):
    %0 = llvm.ashr %a, %b : i32
    llvm.return %0 : i32
  }]

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

instance : Repr (Lets d Γ eff t) where
  reprPrec lets prec := lets.repr prec

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

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

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

instance : HydrableBooleanAlgebra FpPredicate FpExpr where
  eq e1 e2 := BoolExpr.literal (FpPredicate.bin e1 .eq e2)

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

def llvm_const_lower_riscv_li_50 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_50, rhs:= liRiscv_50,
   correct := by admit /- proof elided -/

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

def autWidth_equiv : (CNFA.autWidth wp n).m.states ≃ (NFA'.autWidth wp n).σ where
  toFun := fun ⟨s, hs⟩ =>
    Fin.mk s (by admit /- proof elided -/
    )
  invFun q := ⟨q.val, by admit /- proof elided -/
  ⟩
  left_inv := by admit /- proof elided -/

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

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

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

def llvm_const_lower_riscv_li36 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM36, rhs:= liRiscv36,
   correct := by admit /- proof elided -/

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

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

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

Lean.Meta.getFVarLocalDecl in Lean.Meta.Basic

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

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

def test1_before := [llvm|
{
^0(%arg0 : i8):
  %0 = llvm.mlir.constant(65544 : i32) : i32
  %1 = llvm.zext %arg0 : i8 to i32
  %2 = llvm.and %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def llvm_rem_lower_riscv_32 : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := rem_llvm_32
  rhs := rem_riscv_32
  correct := by admit /- proof elided -/

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

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

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

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

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

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

def bools2_logical_commute1_before := [llvm|
{
^0(%arg52 : i1, %arg53 : i1, %arg54 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.xor %arg54, %0 : i1
  %3 = "llvm.select"(%arg52, %arg54, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = "llvm.select"(%2, %arg53, %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 generalizeMap (g : MVarId) (e : Expr) : MetaM (FVarId × MVarId) :=  do
  let (fvars, g) ← g.generalize #[{ expr := e : GeneralizeArg}]
  
  if h : fvars.size = 1 then
    return (fvars[0], g)
  throwError"expected a single free variable from generalizing map {e}, found multiple..."

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

def udiv_match : List (Σ Γ, Σ ty, PeepholeRewrite LLVMPlusRiscV Γ ty) := [
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_udiv_lower_riscv_flag_32),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_udiv_lower_riscv_no_flag_32),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_udiv_lower_riscv_flag_64),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_udiv_lower_riscv_no_flag_64),
]

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

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

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 bw' (wmask : BitVec o) (x : BitVec o) : BitVec o := x &&& (wmask)

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

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

def signbit_splat_mask_before := [llvm|
{
^0(%arg117 : i8, %arg118 : i16):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.ashr %arg117, %0 : i8
  %2 = llvm.sext %1 : i8 to i16
  %3 = llvm.and %2, %arg118 : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

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 unsigned_sign_bit_extract_with_trunc_before := [llvm|
{
^0(%arg3 : i64):
  %0 = llvm.mlir.constant(63) : i64
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.lshr %arg3, %0 : i64
  %3 = llvm.trunc %2 : i64 to i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def mul_mask_notpow2_ne_before := [llvm|
{
^0(%arg19 : i8):
  %0 = llvm.mlir.constant(60 : i8) : i8
  %1 = llvm.mlir.constant(12 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.mul %arg19, %0 : i8
  %4 = llvm.and %3, %1 : i8
  %5 = llvm.icmp "ne" %4, %2 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

instance : Coe α (ConcreteOrMVar α φ) := ⟨.concrete⟩

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

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

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

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

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

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

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

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

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

abbrev BVRel := ∀ ⦃w⦄, BitVec w → BitVec w → Prop

def same_source_not_matching_signbits_before := [llvm|
{
^0(%arg2 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.and %arg2, %0 : i32
  %3 = llvm.shl %1, %2 overflow<nsw> : i32
  %4 = llvm.trunc %3 : i32 to i8
  %5 = llvm.sext %4 : i8 to i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

instance : TyDenote (Dialect.Ty Comb) where
  toType := fun
  | .bitvec w => BitVec w

def sub_select_sext_op_swapped_non_const_args_after := [llvm|
{
^0(%arg6 : i1, %arg7 : i6, %arg8 : i6):
  %0 = llvm.mlir.constant(-1 : i6) : i6
  %1 = llvm.mlir.constant(0 : i6) : i6
  %2 = llvm.xor %arg7, %0 : i6
  %3 = llvm.sub %1, %arg8 : i6
  %4 = "llvm.select"(%arg6, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i6, i6) -> i6
  "llvm.return"(%4) : (i6) -> ()
}
]

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

RV64.binv in RISCV.Instructions

def fold_ne_rhs_after := [llvm|
{
^0(%arg17 : i8, %arg18 : i8):
  %0 = llvm.mlir.constant(123 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.xor %arg18, %0 : i8
  %3 = llvm.lshr %2, %arg17 : i8
  %4 = llvm.icmp "ne" %3, %1 : i8
  "llvm.return"(%4) : (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 ashrsgt_02_07_after := [llvm|
{
^0(%arg294 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

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

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

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

inductive AttrDefn where
  | mk: (name: String) -> (val: AttrValue φ) -> AttrDefn

def n0_after := [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 overflow<nuw> : i8
  %3 = llvm.xor %2, %1 : i8
  %4 = llvm.icmp "ule" %arg9, %3 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

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

def 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 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 reassoc_mul_nuw_before := [llvm|
{
^0(%arg24 : i32):
  %0 = llvm.mlir.constant(4 : i32) : i32
  %1 = llvm.mlir.constant(65 : i32) : i32
  %2 = llvm.mul %arg24, %0 overflow<nuw> : i32
  %3 = llvm.mul %2, %1 overflow<nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

def t7_ashr_before := [llvm|
{
^0(%arg29 : i32, %arg30 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(-2 : i32) : i32
  %2 = llvm.sub %0, %arg30 : i32
  %3 = llvm.ashr exact %arg29, %2 : i32
  %4 = llvm.add %arg30, %1 : i32
  %5 = llvm.ashr %3, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

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

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

def or_consts_after := [llvm|
{
^0(%arg163 : i32, %arg164 : i32, %arg165 : i32):
  %0 = llvm.mlir.constant(12 : i32) : i32
  %1 = llvm.and %arg163, %0 : i32
  %2 = llvm.icmp "eq" %1, %0 : i32
  "llvm.return"(%2) : (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 test11_after := [llvm|
{
^0(%arg89 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

def getIdentityAndAbsorptionConstraints
    (_pred : FpPredicate)
    (_symVars : Std.HashSet Nat) : List GenFpLogicalExpr :=
 []

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

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

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

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

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

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

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

NFA.eval in Mathlib.Computability.NFA

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

def select_of_anyext_rw : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 1)] where
  lhs := [LV| {
    ^entry (%cond: i1, %true_val: i32, %false_val: i32):
      %0 = llvm.select %cond, %true_val, %false_val : i32
      %1 = llvm.sext %0 : i32 to i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%cond: i1, %true_val: i32, %false_val: i32):
      %0 = llvm.sext %true_val : i32 to i64
      %1 = llvm.sext %false_val : i32 to i64
      %2 = llvm.select %cond, %0, %1 : i64
      llvm.return %2 : i64
  }]

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

def shl_lshr_pow2_const_negative_overflow1_after := [llvm|
{
^0(%arg70 : i16):
  %0 = llvm.mlir.constant(0 : i16) : i16
  "llvm.return"(%0) : (i16) -> ()
}
]

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

def mapValuation (m : Mapping Γ Δ) (V : Δ.Valuation) : Γ.Valuation :=
  fun t' v' =>
    match m.lookup ⟨t', v'⟩ with
    | some mappedVar => V mappedVar
    | none => default

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

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

def test14_after := [llvm|
{
^0(%arg12 : i16):
  %0 = llvm.mlir.constant(4 : i16) : i16
  %1 = llvm.mlir.constant(1 : i16) : i16
  %2 = llvm.mlir.constant(-1 : i16) : i16
  %3 = llvm.lshr %arg12, %0 : i16
  %4 = llvm.and %3, %1 : i16
  %5 = llvm.add %4, %2 overflow<nsw> : i16
  %6 = llvm.sext %5 : i16 to i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

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

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

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

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 test15e_before := [llvm|
{
^0(%arg23 : i32):
  %0 = llvm.mlir.constant(128 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(256 : i32) : i32
  %3 = llvm.and %arg23, %0 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  %5 = "llvm.select"(%4, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

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

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

def test_before := [llvm|
{
^0(%arg0 : i64):
  %0 = llvm.mlir.constant(4294967294) : i64
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.or %arg0, %0 : i64
  %3 = llvm.trunc %2 : i64 to i32
  %4 = llvm.srem %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

structure Config where
   
  circuitSizeThreshold : Nat := 200

   
  stateSpaceSizeThreshold : Nat := 200
   
  fastFixedWidth : Bool := false
   
  backend : CircuitBackend := .circuit_lean

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

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

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

def test_sub_mul_neg_one_rhs_RHS := [mod_arith q, hq| {
  ^bb0(%x : !R, %y : !R):
    %res0 = mod_arith.constant 0 : !R
    %res1 = mod_arith.add %x, %y : !R
    %res2 = mod_arith.sub %res0, %res1 : !R
    return %res2 : !R
}]

def same_signbit_wrong_type_signed_before := [llvm|
{
^0(%arg14 : i8, %arg15 : i32):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.ashr %arg14, %0 : i8
  %3 = llvm.icmp "sgt" %arg15, %1 : i32
  %4 = llvm.sext %3 : i1 to i8
  %5 = llvm.icmp "ne" %2, %4 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

def simplify : ∀ (_c : Circuit α), Circuit α
  | tru => tru
  | fals => fals
  | var b x => var b x
  | and c₁ c₂ => (simplify c₁) &&& (simplify c₂)
  | or c₁ c₂ => (simplify c₁) ||| (simplify c₂)
  | xor c₁ c₂ => (simplify c₁) ^^^ (simplify c₂)

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

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

def test_or_eq_a_b_after := [llvm|
{
^0(%arg36 : i1, %arg37 : i8, %arg38 : i8):
  %0 = "llvm.select"(%arg36, %arg37, %arg38) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%0) : (i8) -> ()
}
]

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

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

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 srl_match : List (Σ Γ, Σ ty, PeepholeRewrite LLVMPlusRiscV Γ ty) := [
  
  
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_srl_lower_riscv_exact_64),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_srl_lower_riscv_64),
]

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

Lean.mkOptionalNode in Init.Meta.Defs

instance : Repr (Expr d Γ eff t) where reprPrec expr _ := expr.print

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

Sigma in Init.Core

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

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

Sum.inl in Init.Core

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

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

instance : DecidableEq BlockLabel :=

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

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

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

def xor_notand_to_or_not4_before := [llvm|
{
^0(%arg9 : i3, %arg10 : i3, %arg11 : i3):
  %0 = llvm.mlir.constant(-1 : i3) : i3
  %1 = llvm.or %arg10, %arg11 : i3
  %2 = llvm.and %arg11, %arg9 : i3
  %3 = llvm.xor %2, %0 : i3
  %4 = llvm.xor %3, %1 : i3
  "llvm.return"(%4) : (i3) -> ()
}
]

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

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

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

def main7d_after := [llvm|
{
^0(%arg64 : i32, %arg65 : i32, %arg66 : i32, %arg67 : i32, %arg68 : i32):
  %0 = llvm.and %arg65, %arg67 : i32
  %1 = llvm.and %arg66, %arg68 : i32
  %2 = llvm.or %0, %1 : i32
  %3 = llvm.and %arg64, %2 : i32
  %4 = llvm.icmp "ne" %3, %2 : i32
  %5 = llvm.zext %4 : i1 to i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

IO.FS.Stream.ofHandle in Init.System.IO

instance : ToString IcmpPredicate where
  toString
  | .eq  => "eq"
  | .ne  => "ne"
  | .slt => "slt"
  | .sle => "sle"
  | .sgt => "sgt"
  | .sge => "sge"
  | .ult => "ult"
  | .ule => "ule"
  | .ugt => "ugt"
  | .uge => "uge"

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

def eq_umax1_before := [llvm|
{
^0(%arg60 : i32, %arg61 : i32):
  %0 = llvm.icmp "ugt" %arg60, %arg61 : i32
  %1 = "llvm.select"(%0, %arg60, %arg61) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %2 = llvm.icmp "eq" %1, %arg60 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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 test9_after := [llvm|
{
^0(%arg0 : i77):
  %0 = llvm.mlir.constant(562949953421310 : i77) : i77
  %1 = llvm.mlir.constant(1 : i77) : i77
  %2 = llvm.and %arg0, %0 : i77
  %3 = llvm.or disjoint %2, %1 : i77
  "llvm.return"(%3) : (i77) -> ()
}
]

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 main7f_after := [llvm|
{
^0(%arg44 : i32, %arg45 : i32, %arg46 : i32, %arg47 : i32, %arg48 : i32):
  %0 = llvm.and %arg45, %arg47 : i32
  %1 = llvm.and %arg46, %arg48 : i32
  %2 = llvm.or %0, %1 : i32
  %3 = llvm.and %arg44, %2 : i32
  %4 = llvm.icmp "ne" %3, %2 : i32
  %5 = llvm.zext %4 : i1 to i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

def carry' (initCarry : Bool) (x y : BitStream) : BitStream :=
  fun n =>
  match n with
  | 0 => initCarry
  | n + 1 => (addAux' initCarry x y n).2

def concat {ls : List Nat} (xs : HVector BitVec ls) : BitVec (List.sum ls) :=
  match (xs) with
  | (.nil) => 0#0
  | (.cons x xs) =>
     let xsSum := concat xs
     x ++ xsSum

def test3_after := [llvm|
{
^0(%arg48 : i32, %arg49 : i32):
  %0 = llvm.or %arg48, %arg49 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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 or_nosignbit_select_lshr_after := [llvm|
{
^0(%arg24 : i32, %arg25 : i1):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(8388352 : i32) : i32
  %2 = llvm.lshr %arg24, %0 : i32
  %3 = llvm.or %2, %1 : i32
  %4 = "llvm.select"(%arg25, %3, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

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

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

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

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

def match_signed_before := [llvm|
{
^0(%arg15 : i64):
  %0 = llvm.mlir.constant(299) : i64
  %1 = llvm.mlir.constant(64) : i64
  %2 = llvm.mlir.constant(19136) : i64
  %3 = llvm.mlir.constant(9) : i64
  %4 = llvm.srem %arg15, %0 : i64
  %5 = llvm.sdiv %arg15, %0 : i64
  %6 = llvm.srem %5, %1 : i64
  %7 = llvm.sdiv %arg15, %2 : i64
  %8 = llvm.srem %7, %3 : i64
  %9 = llvm.mul %6, %0 : i64
  %10 = llvm.add %4, %9 : i64
  %11 = llvm.mul %8, %2 : i64
  %12 = llvm.add %10, %11 : i64
  "llvm.return"(%12) : (i64) -> ()
}
]

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

def mkStateUniqueCircuitN {arity : Type _}
  [DecidableEq arity] [Fintype arity] [Hashable arity]
  (p : FSM arity) (n : Nat) : Circuit (Vars p.α arity n) :=
  let sn : p.α → Circuit (Vars p.α arity n) := fun s =>
    Circuit.var true (Vars.stateN s n)
  let circs := (List.range n).attach |>.map fun ⟨i, hi⟩ =>
    let si : p.α → Circuit (Vars p.α arity n) := fun s =>
      Circuit.var true (Vars.stateN s i (by admit /- proof elided -/
      ))
    (mkStateNeqCircuit p si sn)
  Circuit.bigOr circs

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

def ashr_uge_noexact_before := [llvm|
{
^0(%arg160 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(10 : i8) : i8
  %2 = llvm.ashr %arg160, %0 : i8
  %3 = llvm.icmp "uge" %2, %1 : i8
  "llvm.return"(%3) : (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) -> ()
}
]

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

def test18_before := [llvm|
{
^0(%arg6 : i128):
  %0 = llvm.mlir.constant(2 : i128) : i128
  %1 = llvm.shl %arg6, %0 : i128
  %2 = llvm.shl %arg6, %0 : i128
  %3 = llvm.sub %1, %2 : i128
  "llvm.return"(%3) : (i128) -> ()
}
]

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

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 "ne" %3, %arg6 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

def factorize4_before := [llvm|
{
^0(%arg3 : i32, %arg4 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.shl %arg4, %0 : i32
  %2 = llvm.mul %1, %arg3 : i32
  %3 = llvm.mul %arg3, %arg4 : i32
  %4 = llvm.sub %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def and_to_xor1_after := [llvm|
{
^0(%arg119 : i32, %arg120 : i32):
  %0 = llvm.xor %arg119, %arg120 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

Semiring in Mathlib.Algebra.Ring.Defs

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

instance : Lean.ToExpr SLLVM.Ty :=

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

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

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

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

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

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

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

Lean.Elab.Term.withDeclName in Lean.Elab.Term.TermElabM

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

def exampleAdd := [DCxComb_com| {
  ^entry(%0: !ValueStream_8, %1: !ValueStream_8):
    %src = "DCxComb.add" (%0, %1) : (!ValueStream_8, !ValueStream_8) -> (!ValueStream_8)
    "return" (%src) : (!ValueStream_8) -> ()
  }]

Union.union in Init.Core
</all_available_defs>

<all_available_lemmas>
BitVec.zero_eq in Init.Data.BitVec.Basic
Finset.mem_range in Mathlib.Data.Finset.Range
Function.iterate_add in Mathlib.Logic.Function.Iterate
eq_of_forall_lt_iff in Mathlib.Order.Basic
gt_iff_lt in Init.Core
Fin.add_def in Init.Data.Fin.Lemmas
Fin.val_one in Init.Data.Fin.Lemmas
Nat.mod_eq_of_lt in Init.Data.Nat.Div.Basic
eq_iff_eq_of_cmp_eq_cmp in Mathlib.Order.Compare

@[grind ., simp, aesop 50% unsafe]
lemma wf_addTrans [LawfulBEq A] (m : RawCNFA A) (hwf : m.WF) s a s' (hin : s ∈ m.states) (hin' : s' ∈ m.states) :
    (m.addTrans a s s').WF

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

@[grind =, simp, aesop 50% unsafe]
lemma newState_eq (m : RawCNFA A) :
    m.newState.1 = m.stateMax

@[grind =, simp]
lemma addInitial_stateMax {m : RawCNFA A} : (m.addInitial s).stateMax = m.stateMax

@[grind =, simp]
lemma addTrans_stateMax {m : RawCNFA A} : (m.addTrans a s s').stateMax = m.stateMax

lemma simulFun_sim {m : CNFA n} f :
    m.m.SimulFun M.M f → m.Sim M

lemma simulFun_sim_raw [LawfulBEq A] {m : RawCNFA A} (hwf : m.WF) f :
    m.SimulFun M f → m.Sim M

@[simp]
lemma RawCNFA.Simul.initial {m : RawCNFA A} {M : NFA A Q} (hsim : m.Simul M R ⊤ ∅) :
    R.set_eq m.initials.toSet M.start

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

theorem shiftLeft_eq' {x : BitVec w₁} {y : BitVec w₂} : x <<< y = x <<< y.toNat

theorem and_ne_with_one_bit_diff_constants3_logical_proof : and_ne_with_one_bit_diff_constants3_logical_before ⊑ and_ne_with_one_bit_diff_constants3_logical_after

theorem lshrult_03_07_thm (e : IntW 4) : icmp IntPred.ult (lshr e (const? 4 3)) (const? 4 7) ⊑ const? 1 1

theorem shift_xor_multiuse_cmp_xor_thm (e e_1 e_2 e_3 : IntW 32) :
  mul
      (mul
        (select (icmp IntPred.ne (const? 32 0) (LLVM.and e_3 (const? 32 4096))) e_2
          (LLVM.xor e_2 (const? 32 2048)))
        (select (icmp IntPred.ne (const? 32 0) (LLVM.and e_3 (const? 32 4096))) e_1 e))
      (LLVM.xor e_2 (const? 32 2048)) ⊑
    mul
      (mul
        (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) (LLVM.xor e_2 (const? 32 2048))
          e_2)
        (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) e e_1))
      (LLVM.xor e_2 (const? 32 2048))

theorem select_icmp_x_and_2147483648_ne_0_or_2147483648_proof : select_icmp_x_and_2147483648_ne_0_or_2147483648_before ⊑ select_icmp_x_and_2147483648_ne_0_or_2147483648_after

theorem select_icmp_ne_0_and_8_and_not_1073741824_proof : select_icmp_ne_0_and_8_and_not_1073741824_before ⊑ select_icmp_ne_0_and_8_and_not_1073741824_after

theorem test5_proof : test5_before ⊑ test5_after

theorem scalar_i32_lshr_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 test2_proof : test2_before ⊑ test2_after

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

theorem icmp_eq_sext_ne_zero_proof : icmp_eq_sext_ne_zero_before ⊑ icmp_eq_sext_ne_zero_after

theorem max_sub_ult_c12_thm (e : IntW 32) :
  select (icmp IntPred.ult e (const? 32 1)) (add e (const? 32 (-2))) (const? 32 0) ⊑
    select (icmp IntPred.eq e (const? 32 0)) (const? 32 (-2)) (const? 32 0)

theorem e_1742 :
    1 *  ~~~(a ^^^ (b &&& c)) - 11 * ( ~~~b &&&  ~~~(a ^^^ c)) + 2 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 * (b ^^^ ( ~~~a ||| (b ||| c))) - 1 * (c ^^^ (a &&&  ~~~b)) + 5 * (a ^^^ (b ^^^ c)) - 1 * (c ^^^ (a ||| (b &&& c))) + 7 *  ~~~( ~~~a &&& (b &&& c)) + 1 * (b |||  ~~~(a |||  ~~~c)) - 2 * (b ^^^ (a ||| c)) + 1 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 1 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) - 1 * (b &&& (a ||| c)) - 2 * ((a &&& c) |||  ~~~(b ||| c)) + 3 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) - 7 * ( ~~~b ||| (a ^^^ c)) - 5 *  ~~~(a ^^^ ( ~~~b &&& c)) + 4 * (c &&& (a |||  ~~~b)) - 2 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) - 1 * (b ^^^ (a ||| (b &&& c))) - 3 *  ~~~( ~~~a &&& ( ~~~b &&& c)) - 7 * (a ^^^ c) - 5 * (c ^^^ (a ||| (b ||| c))) + 1 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) - 7 * (b ||| (a &&&  ~~~c)) + 14 *  ~~~(a ||| (b ||| c)) + 3 *  ~~~(a ||| ( ~~~b ||| c)) + 20 *  ~~~( ~~~a ||| (b ||| c)) + 17 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 4 * ( ~~~a &&& ( ~~~b &&& c)) + 28 * ( ~~~a &&& (b &&& c)) + 10 * (a &&& ( ~~~b &&& c)) - 7 * (a &&& (b &&& c)) =  - 2 * (a &&& (b ||| c)) - 1 * (b ^^^  ~~~(a &&& (b ^^^ c)))

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

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

theorem ashr_slt_noexact_proof : ashr_slt_noexact_before ⊑ ashr_slt_noexact_after

theorem e_1301 :
    4 * (z |||  ~~~t) - 1 *  ~~~z + 1 *  ~~~(z &&& t) + 11 *  ~~~t - 3 *  ~~~(z ^^^ t) - 10 *  ~~~(z ||| t) + 2 *  ~~~(z |||  ~~~t) - 14 * (z &&&  ~~~t) + 1 * (z &&& t) = 2 *  ~~~(z &&&  ~~~z)

theorem lt_unsigned_to_small_signed_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (zeroExtend 32 x <ₛ 17#32) = ofBool (x <ᵤ 17#8)

theorem Id.pure_eq' (a : α) : (pure a : Id α) = a

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

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

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 shift_trunc_wrong_shift_thm (e : IntW 32) :
  icmp IntPred.slt (trunc 8 (lshr e (const? 32 23))) (const? 8 0) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 1073741824)) (const? 32 0)

theorem icmp_equality_test_swift_optional_pointers_proof : icmp_equality_test_swift_optional_pointers_before ⊑ icmp_equality_test_swift_optional_pointers_after

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

theorem test_invert_demorgan_logical_and_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬ofBool (x == 27#64) = 1#1 →
    ofBool (x != 27#64) = 1#1 → (ofBool (x == 0#64) ||| 0#1) ^^^ 1#1 = ofBool (x != 0#64) &&& 1#1

theorem in_constant_6_vary_invmask_proof : in_constant_6_vary_invmask_before ⊑ in_constant_6_vary_invmask_after

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

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

theorem uaddo_wrong_pred2_proof : uaddo_wrong_pred2_before ⊑ uaddo_wrong_pred2_after

theorem xor_nosignbit_select_ashr_proof : xor_nosignbit_select_ashr_before ⊑ xor_nosignbit_select_ashr_after

@[simp] theorem carry_borrow (x : Bool → BitStream) : ∀ (n : ℕ), borrow.carry x (n+1) =
    fun _ => (x true).borrow (x false) n

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

theorem e_2269 :
     - 6 * (d ^^^ (e &&& f)) - 1 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 1 *  ~~~(e |||  ~~~f) - 1 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 2 * ((d &&& e) ^^^ (e |||  ~~~f)) - 1 * ((d &&& e) |||  ~~~(e ^^^ f)) + 2 * ((d &&& e) |||  ~~~(e ||| f)) - 2 * (f ^^^ ( ~~~d ||| (e ||| f))) - 6 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 11 * ((d |||  ~~~e) &&& (e ^^^ f)) + 1 * (e ||| f) - 2 *  ~~~( ~~~d ||| (e &&& f)) - 2 * (e ^^^ (d ||| (e &&& f))) + 5 * (e ||| (d &&&  ~~~f)) + 11 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 2 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 3 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 7 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 11 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 3 * (e ||| (d &&& f)) + 1 * (e ^^^ (d &&&  ~~~f)) + 1 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 11 * (e ^^^  ~~~(d ||| (e &&& f))) + 1 *  ~~~(d &&& f) + 11 * (f ^^^  ~~~(d &&&  ~~~e)) + 7 *  ~~~(d ||| (e ^^^ f)) - 1 * (f |||  ~~~(d |||  ~~~e)) + 1 * ( ~~~e &&& (d ^^^ f)) + 3 *  ~~~(d ^^^ e) + 7 * (e &&& f) + 7 * (d &&& e) + 2 * (d &&& (e ||| f)) + 1 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 6 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 1 * (f ^^^  ~~~(d ||| (e &&& f))) - 6 * ( ~~~d &&& (e ||| f)) + 5 * (f ^^^ (d ||| (e &&& f))) - 5 * (d &&& ( ~~~e ||| f)) + 3 *  ~~~d + 5 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 11 *  ~~~(d &&& (e ||| f)) + 2 * (e ^^^ ( ~~~d ||| (e ||| f))) - 7 * (f ||| (d &&&  ~~~e)) - 2 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 5 * ( ~~~d ||| ( ~~~e ||| f)) - 3 * (e ^^^ (d ||| (e ||| f))) + 4 *  ~~~( ~~~d &&& (e ^^^ f)) + 2 *  ~~~(d &&&  ~~~f) + 3 * ( ~~~d ||| (e &&& f)) + 1 * ( ~~~d ||| (e ^^^ f)) - 49 *  ~~~(d ||| (e ||| f)) - 31 *  ~~~(d ||| ( ~~~e ||| f)) + 19 *  ~~~( ~~~d ||| (e ||| f)) - 39 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 8 * ( ~~~d &&& ( ~~~e &&& f)) - 4 * ( ~~~d &&& (e &&& f)) + 13 * (d &&& ( ~~~e &&& f)) - 54 * (d &&& (e &&& f)) = 1 * (e |||  ~~~(d ||| f))

theorem bv_InstCombineShift__497''' :
    ∀ (e e_1 e_2 : LLVM.IntW w), LLVM.shl (LLVM.add e e_2) e_1 ⊑ LLVM.add (LLVM.shl e e_1) (LLVM.shl e_2 e_1)

theorem e_1741 :
    1 * c + 1 * (a &&& ( ~~~b ||| c)) + 2 * b + 3 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) - 1 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) - 1 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) + 3 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) - 11 * (b ^^^  ~~~(a &&&  ~~~c)) - 2 * (a ^^^ (b ||| c)) + 4 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 3 * (c ^^^ (a ||| (b &&& c))) - 3 * (a &&& (b ||| c)) + 1 * (b ^^^  ~~~(a &&& (b ||| c))) + 2 * (c ^^^  ~~~(a &&& b)) - 1 *  ~~~( ~~~a &&& ( ~~~b &&& c)) + 2 * (c ^^^ (a &&& b)) - 1 *  ~~~b - 6 * (c &&& (a ||| b)) + 2 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) + 2 * ( ~~~a ||| ( ~~~b &&& c)) - 5 * (a ||| ( ~~~b &&& c)) + 1 * ( ~~~(a ||| b) ||| (b ^^^ c)) - 5 * (b ||| (a &&&  ~~~c)) - 5 * ((a ^^^ b) |||  ~~~(a ^^^ c)) + 1 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) + 1 * (b &&& (a ||| c)) + 6 *  ~~~(a ||| (b ||| c)) - 4 *  ~~~(a ||| ( ~~~b ||| c)) - 1 *  ~~~( ~~~a ||| (b ||| c)) + 11 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 3 * ( ~~~a &&& (b &&& c)) + 23 * (a &&& ( ~~~b &&& c)) + 9 * (a &&& (b &&& c)) =  - 5 * (c ^^^ (a ||| b)) - 1 * ( ~~~a &&& ( ~~~b &&& c))

theorem add_smin_simplify_proof : add_smin_simplify_before ⊑ add_smin_simplify_after

theorem foo2_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sgt e_1 (const? 32 2)) (add e_1 e { «nsw» := true, «nuw» := false })
      (sub e_1 e { «nsw» := true, «nuw» := false }) ⊑
    add e_1 (select (icmp IntPred.sgt e_1 (const? 32 2)) e (sub (const? 32 0) e))

theorem or_and_shifts2_proof : or_and_shifts2_before ⊑ or_and_shifts2_after

theorem mul16_low_miss_shift_amount_proof : mul16_low_miss_shift_amount_before ⊑ mul16_low_miss_shift_amount_after

theorem lshr_exact_add_negative_shift_positive_proof : lshr_exact_add_negative_shift_positive_before ⊑ lshr_exact_add_negative_shift_positive_after

theorem e_1266 :
    3 *  ~~~z + 1 * z + 11 *  ~~~(z &&&  ~~~z) - 6 * t - 1 *  ~~~(z &&& t) - 13 *  ~~~(z ||| t) - 9 *  ~~~(z |||  ~~~t) - 13 * (z &&&  ~~~t) - 6 * (z &&& t) =  - 2 * (z ^^^ t)

theorem Predicate.evalNeq_denote {w : Nat} (a b : Term) (vars : List (BitVec w)) :
    evalNeq (a.eval (List.map .ofBitVecSext vars)) (b.eval (List.map .ofBitVecSext vars)) w = false ↔
    Term.denote w a vars ≠ Term.denote w b vars

theorem p_constmask2_proof : p_constmask2_before ⊑ p_constmask2_after

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

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

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

theorem mult_same_same'
  (hppot : ppot &&& (ppot - 1) = 0)
  (hqpot : qpot &&& (qpot - 1) = 0)
  (hrpot : rpot &&& (rpot - 1) = 0)
  (hspot : spot &&& (spot - 1) = 0)
  (htpot : tpot &&& (tpot - 1) = 0)
  (hupot : upot &&& (upot - 1) = 0)
  (hpmask : pmask = ppot - 1)
  (hqmask : qmask = qpot - 1)
  (hrmask : rmask = rpot - 1)
  (hsmask : smask = spot - 1)
  (htmask : tmask = tpot - 1)
  (humask : umask = upot - 1)
  (htp : UnaryGt tmask pmask) (ht1 : UnaryGt tmask (1#o)) (hs : UnaryGe smask (unaryAdd pmask qmask)) :
  (bw' rmask 
    (addMax' 
      (bw' smask 
        (mulMax' (bw' pmask a') pmask (bw' qmask b') qmask)) 
      smask 
      (bw' qmask b') 
      qmask)) =
  (bw' rmask 
    (mulMax' 
      (bw' tmask 
        (addMax' (bw' pmask a') pmask (bw' (1#o) (1#o)) (1#o))) 
      tmask 
      (bw' qmask b') 
      qmask))

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

theorem canonicalize_logic_first_or0_nswnuw_thm (e : IntW 32) :
  LLVM.or (add e (const? 32 112) { «nsw» := true, «nuw» := true }) (const? 32 15) ⊑
    add (LLVM.or e (const? 32 15)) (const? 32 112) { «nsw» := true, «nuw» := true }

theorem bools_multi_uses2_logical_proof : bools_multi_uses2_logical_before ⊑ bools_multi_uses2_logical_after

theorem ashrslt_03_07_exact_proof : ashrslt_03_07_exact_before ⊑ ashrslt_03_07_exact_after

theorem lshrult_03_09_exact_proof : lshrult_03_09_exact_before ⊑ lshrult_03_09_exact_after

theorem e_1556 :
     - 1 * (b ^^^ (a ||| c)) + 1 * (b &&& (a |||  ~~~c)) - 2 * ((a |||  ~~~b) &&& (b ^^^ c)) - 1 * ((a &&&  ~~~b) ||| (a ^^^ (b ^^^ c))) + 7 * (b ^^^ ( ~~~a ||| (b &&& c))) + 2 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 8 *  ~~~(a ||| (b ||| c)) - 8 *  ~~~(a ||| ( ~~~b ||| c)) - 6 *  ~~~( ~~~a ||| (b ||| c)) - 13 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 4 * ( ~~~a &&& ( ~~~b &&& c)) - 6 * ( ~~~a &&& (b &&& c)) - 2 * (a &&& ( ~~~b &&& c)) - 8 * (a &&& (b &&& c)) = 1 *  ~~~(b &&&  ~~~c) - 7 * (a ||| b)

theorem test_or2_thm (e e_1 : IntW 32) :
  LLVM.or (icmp IntPred.sle e_1 (const? 32 (-1))) (icmp IntPred.sgt e_1 (LLVM.and e (const? 32 2147483647))) ⊑
    icmp IntPred.ugt e_1 (LLVM.and e (const? 32 2147483647))

theorem ashrslt_02_03_proof : ashrslt_02_03_before ⊑ ashrslt_02_03_after

@[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 toCom_var {lets : Lets d Γ_in eff Γ_mid} :
    toCom ⟨Lets.var lets e, com⟩ = toCom ⟨lets, Com.var e com⟩

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

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

theorem shl_add_and_thm (e e_1 : IntW 8) :
  LLVM.and (shl e_1 (const? 8 1)) (add (shl e (const? 8 1)) (const? 8 123)) ⊑
    shl (LLVM.and e_1 (add e (const? 8 61))) (const? 8 1)

theorem modulo32_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(32#32 == 0 || 32 != 1 && x == intMin 32 && 32#32 == -1) = true →
    ¬ofBool (x.srem 32#32 <ₛ 0#32) = 1#1 →
      ¬((32#32 == 0 || 32 != 1 && x == intMin 32 && 32#32 == -1) = true ∨
            True ∧ (0#32).saddOverflow (x.srem 32#32) = true) →
        0#32 + x.srem 32#32 = x &&& 31#32

theorem test1_thm.extracted_1._1 : ∀ (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 → False

@[simp]
theorem replicate_zero' {w : Nat} : BitVec.replicate w 0#1 = BitVec.cast (by simp) (0#w)

theorem lshrult_02_03_proof : lshrult_02_03_before ⊑ lshrult_02_03_after

theorem lshrult_01_02_proof : lshrult_01_02_before ⊑ lshrult_01_02_after

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

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

theorem test13_proof : test13_before ⊑ test13_after

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 shl_lshr_pow2_not_const_case2_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(x ≥ ↑16 ∨ 3#16 ≥ ↑16) → ¬ofBool (x == 2#16) = 1#1 → 16#16 <<< x >>> 3#16 &&& 8#16 ^^^ 8#16 = 8#16

theorem test4_thm.extracted_1._1 : ∀ (x : BitVec 49), (x &&& BitVec.ofInt 49 (-2)) + 1#49 = x ||

theorem lshr_or_or_no_const_proof : lshr_or_or_no_const_before ⊑ lshr_or_or_no_const_after

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

theorem test18_thm (e : IntW 8) : trunc 16 (sext 32 e) ⊑ sext 16 e

theorem ashr_lshr_exact_ashr_only_proof : ashr_lshr_exact_ashr_only_before ⊑ ashr_lshr_exact_ashr_only_after

omit [Fintype S] [DecidableEq S] [LawfulBEq A] in
lemma processOneElem_preserves_mem (st : worklist.St A S) (final : S → Bool) (a : A) (sa sa' : S) (s : State) :
    let st' := processOneElem _ _  final s st (a, sa')
    sa ∈ st.map →
    sa ∈ st'.map

theorem test69_xor_proof : test69_xor_before ⊑ test69_xor_after

@[simp]
theorem Lets.denote_var_pure [TyDenote d.Ty] [DialectDenote d] [Monad d.m] [LawfulMonad d.m]
  {Γstart Γ : Ctxt d.Ty}
  {lets : Lets d Γstart .pure Γ}
  (e : Expr d Γ .pure α)
  (V : Ctxt.Valuation Γstart) :
  (lets.var e).denote V
  = (e.pdenoteOp (lets.denote V) ++ lets.denotePure V)

theorem xor_sext_sext_proof : xor_sext_sext_before ⊑ xor_sext_sext_after

theorem AvoidCollision_signExtend_eq_setWidth_of_le (x : BitVec w) {v : Nat} (hv : v ≤ w) :
  x.signExtend v = x.setWidth v

theorem or_nosignbit_lshr_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬8#32 ≥ ↑32 → (x ||| 2147418112#32) >>> 8#32 = x >>> 8#32 ||

theorem alive_InstCombineShift__582 : alive_InstCombineShift__582_src ⊑ alive_InstCombineShift__582_tgt

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

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

theorem test4_proof : test4_before ⊑ test4_after

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

theorem n13_overshift_proof : n13_overshift_before ⊑ n13_overshift_after

theorem ashrslt_03_12_proof : ashrslt_03_12_before ⊑ ashrslt_03_12_after

theorem e_49 :
    11 * (x |||  ~~~y) + 2 * x - 12 *  ~~~(x ||| y) - 13 * (x &&&  ~~~y) - 14 * (x &&& y) =  - 1 *  ~~~(x ^^^ y)

theorem andn_or_cmp_4_logical_proof : andn_or_cmp_4_logical_before ⊑ andn_or_cmp_4_logical_after

theorem urem_common_divisor_thm (e e_1 e_2 : IntW 5) (e_3 : IntW 1) :
  select e_3 (urem e_2 e_1) (urem e e_1) ⊑ urem (select e_3 e_2 e) e_1

theorem nonexact_lshr_eq_exactdiv_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → ofBool (80#8 >>> x == 5#8) = ofBool (x == 4#8)

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

theorem zext_sext_add_icmp_eq_1_proof : zext_sext_add_icmp_eq_1_before ⊑ zext_sext_add_icmp_eq_1_after

theorem select_icmp_ne_0_and_4096_xor_32_proof : select_icmp_ne_0_and_4096_xor_32_before ⊑ select_icmp_ne_0_and_4096_xor_32_after

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

theorem icmp_sle7_proof : icmp_sle7_before ⊑ icmp_sle7_after

theorem different_size_sext_sext_sle_thm.extracted_1._1 : ∀ (x : BitVec 4) (x_1 : BitVec 7),
  ofBool (signExtend 25 x_1 ≤ₛ signExtend 25 x) = ofBool (x_1 ≤ₛ signExtend 7 x)

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

theorem rawspeed_signbit_thm (e : IntW 64) (e_1 : IntW 32) :
  icmp IntPred.eq
      (LLVM.and (shl (const? 32 1) (add e_1 (const? 32 (-1)) { «nsw» := true, «nuw» := false }))
        (trunc 32 (lshr e (zext 64 (sub (const? 32 64) e_1 { «nsw» := true, «nuw» := false })))))
      (const? 32 0) ⊑
    icmp IntPred.sgt e (const? 64 (-1))

theorem lshrult_03_04_exact_proof : lshrult_03_04_exact_before ⊑ lshrult_03_04_exact_after

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

theorem bitvec_AddSub_1309 :
  [llvm(w)| {
    ^bb0(%X : _, %Y : _):
      %v1 = llvm.and %X, %Y
      %v2 = llvm.or %X, %Y
      %v3 = llvm.add %v1, %v2
      llvm.return %v3
  }] ⊑ [llvm(w)| {
    ^bb0(%X : _, %Y : _):
      %v3 = llvm.add %X, %Y
      llvm.return %v3
  }]

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

theorem zext_sub_const_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → 42#64 - zeroExtend 64 x = 42#64

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

theorem neg_or_ashr_i32_commute_proof : neg_or_ashr_i32_commute_before ⊑ neg_or_ashr_i32_commute_after

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

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

theorem ashr_mul_proof : ashr_mul_before ⊑ ashr_mul_after

theorem p_constmask_proof : p_constmask_before ⊑ p_constmask_after

theorem t0_proof : t0_before ⊑ t0_after

theorem lshrugt_03_00_proof : lshrugt_03_00_before ⊑ lshrugt_03_00_after

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

theorem test6_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬16#32 ≥ ↑32 → (x ^^^ 1234#32) >>> 16#32 + (x ^^^ 1234#32) = x >>> 16#32 + (x ^^^ 1234#32)

theorem n12_wrong_bias_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬ofBool (x &&& 15#8 == 0#8) = 1#1 → x + 32#8 &&& BitVec.ofInt 8 (-16) = (x &&& BitVec.ofInt 8 (-16)) + 32#8

theorem ashr_lshr_shift_base_mismatch_thm.extracted_1._3 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (0#32 ≤ₛ x_2) = 1#1 → ¬x_1 ≥ ↑32 → ¬ofBool (x_2 <ₛ 0#32) = 1#1 → x.sshiftRight' x_1 = x_2 >>> x_1

theorem e_1851 :
     - 6 * (c ^^^ (a ||| (b &&& c))) - 2 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 1 *  ~~~( ~~~a &&& (b ||| c)) - 3 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) + 2 * (b |||  ~~~(a ||| c)) - 1 * (c ^^^  ~~~(a ||| b)) + 2 * ((a ^^^ b) ||| (a ^^^ c)) - 1 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 7 * (c ^^^ ( ~~~a ||| (b ||| c))) + 11 * (c &&&  ~~~(a ^^^ b)) - 2 * (c |||  ~~~(a |||  ~~~b)) + 1 * (b ^^^ (a ||| (b &&& c))) + 5 * (a &&& c) + 4 * (b ^^^  ~~~(a ||| c)) + 7 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) + 1 * ((a &&& b) |||  ~~~(b ||| c)) + 3 * (b |||  ~~~(a |||  ~~~c)) - 1 * ( ~~~b ||| (a ^^^ c)) - 3 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) - 7 * ((a &&& c) ^^^ (b ||| c)) + 5 *  ~~~( ~~~a ||| ( ~~~b &&& c)) + 3 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) - 1 *  ~~~(b &&& c) + 1 * (c &&& (a |||  ~~~b)) + 11 * ( ~~~c |||  ~~~(a ^^^ b)) + 5 * (b ^^^ (a ||| (b ^^^ c))) - 1 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) - 6 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) + 3 *  ~~~( ~~~a ||| (b &&& c)) + 2 * (b ^^^ (a &&& ( ~~~b ||| c))) - 1 * ((a ||| b) &&& (b ^^^ c)) + 1 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) - 11 * (b ^^^  ~~~(a ||| (b &&& c))) + 11 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) + 7 *  ~~~(a ^^^ b) + 11 * (a ||| ( ~~~b &&& c)) + 1 * ((b &&& c) ||| (a &&& (b ||| c))) - 11 *  ~~~(a ||| (b ||| c)) - 34 *  ~~~(a ||| ( ~~~b ||| c)) - 53 *  ~~~( ~~~a ||| (b ||| c)) - 32 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 28 * ( ~~~a &&& ( ~~~b &&& c)) + 8 * ( ~~~a &&& (b &&& c)) - 17 * (a &&& ( ~~~b &&& c)) - 70 * (a &&& (b &&& c)) = 1 *  ~~~(a &&&  ~~~b) - 5 * ( ~~~a ||| (b &&& c))

theorem test6_proof : test6_before ⊑ test6_after

theorem or_nand_xor_common_op_commute0_proof : or_nand_xor_common_op_commute0_before ⊑ or_nand_xor_common_op_commute0_after

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

theorem ugt_swap_and_min_commute_logical_proof : ugt_swap_and_min_commute_logical_before ⊑ ugt_swap_and_min_commute_logical_after

theorem t3_exact_proof : t3_exact_before ⊑ t3_exact_after

theorem test_thm (e e_1 : IntW 8) :
  icmp IntPred.sgt (zext 32 e_1) (zext 32 e) ⊑ icmp IntPred.ugt e_1 e

theorem test_logical_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (255#32 <ᵤ x) = 1#1 → 1#1 = ofBool (255#32 <ᵤ x)

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

theorem main7a_thm (e e_1 e_2 : IntW 32) :
  select (LLVM.and (icmp IntPred.eq (LLVM.and e_2 e_1) e_2) (icmp IntPred.eq (LLVM.and e e_1) e))
      (const? 32 0) (const? 32 1) ⊑
    zext 32 (icmp IntPred.ne (LLVM.and e_1 (LLVM.or e_2 e)) (LLVM.or e_2 e))

theorem shl_or_thm.extracted_1._2 : ∀ (x x_1 : BitVec 16),
  ¬((42#16 == 0 || 16 != 1 && x_1 == intMin 16 && 42#16 == -1) = true ∨ 5#16 ≥ ↑16 ∨ 7#16 ≥ ↑16) →
    ¬(12#16 ≥ ↑16 ∨
          (42#16 == 0 || 16 != 1 && x_1 == intMin 16 && 42#16 == -1) = true ∨
            True ∧ (x_1.srem 42#16 <<< 7#16).sshiftRight' 7#16 ≠ x_1.srem 42#16 ∨ 7#16 ≥ ↑16) →
      (x_1.srem 42#16 ||| x <<< 5#16) <<< 7#16 = x <<< 12#16 ||

theorem lowmask_or_zext_commute_proof : lowmask_or_zext_commute_before ⊑ lowmask_or_zext_commute_after

theorem pow2_or_zero_is_negative_commute_thm (e : IntW 8) :
  icmp IntPred.slt (LLVM.and (sub (const? 8 0) (mul (const? 8 42) e)) (mul (const? 8 42) e)) (const? 8 0) ⊑
    icmp IntPred.eq (mul e (const? 8 42)) (const? 8 (-128))

theorem pv_proof : pv_before ⊑ pv_after

theorem and_not_or_wrong_c_proof : and_not_or_wrong_c_before ⊑ and_not_or_wrong_c_after

theorem e_1117 :
    2 *  ~~~(z &&& t) - 3 *  ~~~(z &&&  ~~~z) + 1 * t - 5 * (z |||  ~~~t) - 1 *  ~~~(z &&&  ~~~t) + 7 *  ~~~(z ||| t) + 6 * (z &&&  ~~~t) + 8 * (z &&& t) =  - 1 *  ~~~(z |||  ~~~t)

theorem slt_swap_and_max_proof : slt_swap_and_max_before ⊑ slt_swap_and_max_after

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

theorem e_1018 :
     - 1 * t + 7 *  ~~~(z &&& t) + 1 * (z |||  ~~~t) - 2 * (z ||| t) - 8 *  ~~~(z ||| t) - 6 * (z &&&  ~~~t) + 2 * (z &&& t) = 4 *  ~~~(z |||  ~~~t)

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

theorem e_2058 :
     - 2 *  ~~~(d ||| e) + 5 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 1 * (e ^^^  ~~~(d &&& (e ||| f))) + 11 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 7 *  ~~~(e |||  ~~~f) - 11 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 1 * (e ^^^ (d ||| (e ||| f))) - 6 *  ~~~(d &&&  ~~~d) + 1 * (e ^^^ f) - 11 * (e ^^^ (d &&& f)) + 4 * (d |||  ~~~f) - 11 * (e |||  ~~~(d ^^^ f)) - 11 * ((d &&& f) |||  ~~~(e ||| f)) - 1 * ( ~~~f &&&  ~~~(d ^^^ e)) + 2 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 7 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 4 * (e ^^^ (d ||| ( ~~~e &&& f))) - 5 * (e ^^^  ~~~(d &&& f)) + 1 * ((d &&& e) |||  ~~~(e ||| f)) - 1 *  ~~~(d &&& (e ^^^ f)) + 3 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 5 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) + 1 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 3 * (e ||| (d &&&  ~~~f)) - 7 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 1 *  ~~~( ~~~d &&& (e ||| f)) - 11 *  ~~~(e ||| f) + 1 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 1 * (e &&& f) + 34 *  ~~~(d ||| (e ||| f)) + 3 *  ~~~(d ||| ( ~~~e ||| f)) - 2 *  ~~~( ~~~d ||| (e ||| f)) - 2 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 19 * ( ~~~d &&& ( ~~~e &&& f)) + 29 * ( ~~~d &&& (e &&& f)) + 14 * (d &&& ( ~~~e &&& f)) + 14 * (d &&& (e &&& f)) =  - 7 *  ~~~(d ^^^ ( ~~~e ||| f)) + 3 *  ~~~(d |||  ~~~e)

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 ashr_slt_noexact_thm (e : IntW 8) :
  icmp IntPred.slt (ashr e (const? 8 3)) (const? 8 10) ⊑ icmp IntPred.slt e (const? 8 80)

@[simp] theorem AttrDict.find_none :
    AttrDict.find (@AttrDict.mk φ []) n' = none

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

theorem expand_thm (e : IntW 32) :
  LLVM.and (LLVM.or (LLVM.and e (const? 32 1)) (const? 32 2)) (const? 32 1) ⊑ LLVM.and e (const? 32 1)

theorem IsLawful_mkZero {arity : Type _}
    [DecidableEq arity] [Fintype arity] [Hashable arity]
    (fsm : FSM arity) :
    (mkZero (fsm := fsm)).IsLawful

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

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

theorem test3_proof : test3_before ⊑ test3_after

theorem sdiv_exact_eq_9_no_of_proof : sdiv_exact_eq_9_no_of_before ⊑ sdiv_exact_eq_9_no_of_after

theorem t0_commutative_thm.extracted_1._18 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1) (x_3 x_4 : BitVec 8),
  ofBool (x_4 == x_3) = 1#1 → ofBool (x_4 != x_3) = 1#1 → ¬True → x_2 = 1#1 → x_1 = x

theorem lshrult_01_05_exact_proof : lshrult_01_05_exact_before ⊑ lshrult_01_05_exact_after

theorem set_shl_mask_proof : set_shl_mask_before ⊑ set_shl_mask_after

theorem lt_unsigned_to_large_negative_proof : lt_unsigned_to_large_negative_before ⊑ lt_unsigned_to_large_negative_after

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

theorem and_add_bool_to_select_proof : and_add_bool_to_select_before ⊑ and_add_bool_to_select_after

theorem trunc_lshr_sext_proof : trunc_lshr_sext_before ⊑ trunc_lshr_sext_after

theorem fold_icmp_shl_nuw_c2_precondition2_proof : fold_icmp_shl_nuw_c2_precondition2_before ⊑ fold_icmp_shl_nuw_c2_precondition2_after

theorem addhshlhsdivhscalar0_proof : addhshlhsdivhscalar0_before ⊑ addhshlhsdivhscalar0_after

theorem or_xor_commute4_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(x_1 = 0 ∨ x = 0 ∨ x_1 = 0) → x = 0 ∨ x_1 = 0 → False

theorem and_signbit_select_lshr_proof : and_signbit_select_lshr_before ⊑ and_signbit_select_lshr_after

theorem e_2135 :
     - 7 *  ~~~(e ||| f) + 1 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 11 * ((d &&& e) |||  ~~~(e ^^^ f)) - 6 * (e |||  ~~~(d ^^^ f)) + 1 * ( ~~~e &&& (d ^^^ f)) - 7 * (d |||  ~~~e) + 5 * (e ^^^  ~~~(d &&& f)) + 1 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 1 * (e ^^^ ( ~~~d ||| (e &&& f))) - 5 * (f ^^^ ( ~~~d ||| (e &&& f))) + 7 * ( ~~~e ||| (d ^^^ f)) - 2 * (f ^^^  ~~~(d ||| (e &&& f))) + 1 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 5 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 3 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 1 * (f ^^^  ~~~(d &&& (e ||| f))) - 1 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 1 *  ~~~(d &&& f) - 5 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 1 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 2 * f + 2 *  ~~~(e ^^^ f) + 2 * (f &&& (d ^^^ e)) + 5 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 2 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 2 *  ~~~(d &&& e) + 3 *  ~~~(d ||| ( ~~~e &&& f)) + 2 * (f &&&  ~~~(d &&& e)) - 2 *  ~~~(d &&& (e ||| f)) - 3 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 2 * (f ||| (d ^^^ e)) + 1 *  ~~~(d &&&  ~~~d) - 1 * ( ~~~d ||| (e ||| f)) - 3 * ( ~~~f &&& (d ^^^ e)) - 1 * (d ||| e) - 1 * (f |||  ~~~(d ||| e)) + 4 * (d &&& (e ||| f)) - 11 *  ~~~(d ||| (e ||| f)) + 10 *  ~~~(d ||| ( ~~~e ||| f)) - 11 *  ~~~( ~~~d ||| (e ||| f)) - 21 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 1 * ( ~~~d &&& ( ~~~e &&& f)) - 23 * ( ~~~d &&& (e &&& f)) - 3 * (d &&& ( ~~~e &&& f)) - 4 * (d &&& (e &&& f)) =  - 3 * ((d ||| e) &&&  ~~~(e ^^^ f))

theorem test_logical_or_eq_a_b_thm (e e_1 : IntW 8) (e_2 : IntW 1) :
  select (select e_2 (const? 1 1) (icmp IntPred.eq e_1 e)) e_1 e ⊑ select e_2 e_1 e

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

theorem test_ashr__exact_is_safe_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 scf.for.peel_begin (n : Nat) (f : Nat → β → β) (seed : β) :
  scf.for.loop f (n + 1) n (f 0 seed) = scf.for.loop f (n + 1) (n + 1) seed

theorem FSM.or_eq (a b : FSM arity) : (a ||| b) = composeBinaryAux' FSM.or a b

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

theorem sub_to_xor_and_commuted_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  (x_1 &&& x) - (x ||| x_1) = 0#32 - (x_1 ^^^ x)

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

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

theorem select_sub_icmp_bad_2_proof : select_sub_icmp_bad_2_before ⊑ select_sub_icmp_bad_2_after

@[simp] theorem Com.size_castPureToEff {com : Com d Γ .pure ty} :
    (com.castPureToEff eff).size = com.size

theorem test22_proof : test22_before ⊑ test22_after

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

theorem n3_constmask_samemask_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  x_1 &&& 65280#32 ||

@[bv_multi_width_normalize↓] theorem not_forall (p : α → Prop) : (¬∀ x, p x) = ∃ x, ¬p x

theorem e_861 :
     - 11 *  ~~~(z &&&  ~~~z) + 1 *  ~~~t - 2 *  ~~~(z ^^^ t) + 13 *  ~~~(z |||  ~~~t) + 10 * (z &&&  ~~~t) + 13 * (z &&& t) = 2 *  ~~~z - 14 *  ~~~(z ||| t)

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

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 substitute_constant_and_eq_eq_commute_proof : substitute_constant_and_eq_eq_commute_before ⊑ substitute_constant_and_eq_eq_commute_after

theorem test_sub_4_Y_ne_4_proof : test_sub_4_Y_ne_4_before ⊑ test_sub_4_Y_ne_4_after

theorem sext_sext_add_thm (e : IntW 32) :
  add (sext 64 (ashr e (const? 32 7))) (sext 64 (ashr e (const? 32 9))) ⊑
    sext 64 (add (ashr e (const? 32 7)) (ashr e (const? 32 9)) { «nsw» := true, «nuw» := false })

theorem or_xor_tree_0111_proof : or_xor_tree_0111_before ⊑ or_xor_tree_0111_after

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 udiv_mul_shl_nuw_proof : udiv_mul_shl_nuw_before ⊑ udiv_mul_shl_nuw_after

theorem test7_proof : test7_before ⊑ test7_after

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

theorem icmp_shl_eq_1_thm (e : IntW 8) :
  icmp IntPred.eq (shl e (const? 8 1)) e ⊑ icmp IntPred.eq e (const? 8 0)

theorem select_icmp_eq_0_and_1_xor_1_proof : select_icmp_eq_0_and_1_xor_1_before ⊑ select_icmp_eq_0_and_1_xor_1_after

theorem shl_sub_proof : shl_sub_before ⊑ shl_sub_after

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

theorem sdiv_mul_shl_nsw_exact_commute1_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 5),
  ¬(True ∧ x_2.smulOverflow x_1 = true ∨
        True ∧ (x_1 <<< x).sshiftRight' x ≠ x_1 ∨
          x ≥ ↑5 ∨
            True ∧ (x_2 * x_1).smod (x_1 <<< x) ≠ 0 ∨
              (x_1 <<< x == 0 || 5 != 1 && x_2 * x_1 == intMin 5 && x_1 <<< x == -1) = true) →
    True ∧ 1#5 <<< x >>> x ≠ 1#5 ∨
        x ≥ ↑5 ∨
          True ∧ x_2.smod (1#5 <<< x) ≠ 0 ∨ (1#5 <<< x == 0 || 5 != 1 && x_2 == intMin 5 && 1#5 <<< x == -1) = true →
      False

theorem dec_mask_commute_neg_i32_proof : dec_mask_commute_neg_i32_before ⊑ dec_mask_commute_neg_i32_after

theorem samesign_inverted_commute1_proof : samesign_inverted_commute1_before ⊑ samesign_inverted_commute1_after

theorem select_or_disjoint_or_proof : select_or_disjoint_or_before ⊑ select_or_disjoint_or_after

theorem logical_or_not_cond_reuse_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → x ^^^ 1#1 = 1#1 → False

theorem e_545 :
     - 2 * x - 1 *  ~~~(x &&& y) - 1 *  ~~~(x ^^^ y) - 5 * (x ||| y) - 11 * y + 3 * (x |||  ~~~y) + 18 *  ~~~(x |||  ~~~y) + 6 * (x &&&  ~~~y) + 17 * (x &&& y) = 1 *  ~~~(x &&&  ~~~x)

theorem xor_1_proof : xor_1_before ⊑ xor_1_after

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

theorem ne_21_logical_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ¬(16#32 ≥ ↑32 ∨ 16#32 ≥ ↑32) →
    ¬ofBool (truncate 8 (x_1 >>> 16#32) != truncate 8 (x >>> 16#32)) = 1#1 →
      ¬(8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32) →
        ofBool (truncate 8 (x_1 >>> 8#32) != truncate 8 (x >>> 8#32)) =
          ofBool (truncate 16 (x_1 >>> 8#32) != truncate 16 (x >>> 8#32))

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

theorem n10_ugt_slt_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (128#32 <ᵤ x_2) = 1#1 → ofBool (x_2 <ₛ 0#32) = 1#1 → x_1 = x

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

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

theorem ne_umin1_proof : ne_umin1_before ⊑ ne_umin1_after

theorem negate_xor_thm.extracted_1._1 : ∀ (x : BitVec 4), 0#4 - (x ^^^ 5#4) = (x ^^^ BitVec.ofInt 4 (-6)) + 1#4

theorem width_1_char_2 (x : BitVec w) (hw : w = 1) : x + x = 0#w

theorem negative_with_uniform_bad_mask_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& BitVec.ofInt 32 (-16777152) == 0#32) = 1#1 →
    0#1 = ofBool (x &&& BitVec.ofInt 32 (-16777152) == 0#32) &&& ofBool (x + 128#32 <ᵤ 256#32)

theorem test_shl_nuw_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 and_ne_with_one_bit_diff_constants2_proof : and_ne_with_one_bit_diff_constants2_before ⊑ and_ne_with_one_bit_diff_constants2_after

theorem BitVec.eq_iff_sub_zero (x y : BitVec w) : x = y ↔ x - y = 0

theorem or_xor_xor_normal_variant2_proof : or_xor_xor_normal_variant2_before ⊑ or_xor_xor_normal_variant2_after

theorem ule_swap_or_not_min_commute_proof : ule_swap_or_not_min_commute_before ⊑ ule_swap_or_not_min_commute_after

theorem bar_thm (e e_1 : IntW 64) :
  icmp IntPred.eq (LLVM.and e_1 (LLVM.xor (LLVM.and e_1 e) (const? 64 (-1)))) (const? 64 0) ⊑
    icmp IntPred.eq (LLVM.and e_1 (LLVM.xor e (const? 64 (-1)))) (const? 64 0)

theorem band_lor_left2_proof : band_lor_left2_before ⊑ band_lor_left2_after

theorem icmp_eq_select_proof : icmp_eq_select_before ⊑ icmp_eq_select_after

theorem e_1945 :
     - 5 * ( ~~~a ||| ( ~~~b ||| c)) - 11 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) + 1 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) - 11 * ( ~~~c &&& (a ^^^ b)) - 2 * ( ~~~a ||| (b ||| c)) - 7 * ( ~~~a &&& ( ~~~b ||| c)) + 3 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 7 *  ~~~(a &&& (b ^^^ c)) - 2 *  ~~~(a &&& b) - 3 * (c ^^^  ~~~(a &&& (b ||| c))) + 11 * (b ^^^ (a &&& c)) + 5 * (b ^^^ (a &&& (b ||| c))) + 1 * (b ^^^  ~~~( ~~~a ||| (b ^^^ c))) + 4 * (a &&& (b ||| c)) + 1 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) - 2 * (a |||  ~~~b) + 2 * (c ||| (a &&& b)) + 5 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) + 1 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) - 3 * (a ||| b) + 2 *  ~~~(a ||| (b &&& c)) + 11 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) - 1 * (a ||| (b &&& c)) + 1 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) - 5 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) - 1 *  ~~~(a &&& ( ~~~b ||| c)) - 1 * ((a ^^^ b) &&& (a ^^^ c)) + 1 * (b ^^^ ( ~~~a ||| (b &&& c))) + 4 * ( ~~~c ||| (a ^^^ b)) + 5 * (c ^^^ (a &&& b)) + 1 * (c ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 1 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) + 1 * (b &&& c) + 11 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 11 *  ~~~(a |||  ~~~c) + 1 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) + 11 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 4 * ( ~~~a ||| (b &&& c)) - 5 * (b ^^^  ~~~(a &&& (b ||| c))) + 3 * ((b &&&  ~~~c) ^^^ (a ||| (b ^^^ c))) - 2 *  ~~~(a ||| c) - 1 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) - 1 * (b ^^^ ( ~~~a ||| (b ||| c))) + 3 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) - 2 * (c ^^^ (a &&& ( ~~~b ||| c))) + 2 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 14 *  ~~~(a ||| (b ||| c)) - 19 *  ~~~(a ||| ( ~~~b ||| c)) - 14 *  ~~~( ~~~a ||| (b ||| c)) - 20 * ( ~~~a &&& ( ~~~b &&& c)) - 15 * ( ~~~a &&& (b &&& c)) - 45 * (a &&& ( ~~~b &&& c)) - 7 * (a &&& (b &&& c)) = 32 *  ~~~( ~~~a ||| ( ~~~b ||| c))

theorem e_1200 :
     - 3 * (z ||| t) - 1 * t + 7 *  ~~~z - 7 * z - 2 *  ~~~(z &&&  ~~~t) - 5 *  ~~~(z ||| t) - 1 *  ~~~(z |||  ~~~t) + 13 * (z &&& t) =  - 10 * (z &&&  ~~~t)

theorem xor_lshr_multiuse_thm (e e_1 e_2 e_3 : IntW 8) :
  LLVM.sdiv (LLVM.xor (lshr e_3 e_2) e_1) (LLVM.xor (LLVM.xor (lshr e_3 e_2) e_1) (lshr e e_2)) ⊑
    LLVM.sdiv (LLVM.xor (lshr e_3 e_2) e_1) (LLVM.xor (lshr (LLVM.xor e_3 e) e_2) e_1)

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

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

theorem testi16i8_com_proof : testi16i8_com_before ⊑ testi16i8_com_after

theorem foo_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬ofBool (zeroExtend 32 (x &&& 255#16) <ᵤ 255#32) = 1#1 → truncate 16 255#32 &&& 255#16 = x &&& 255#16

theorem and_xor_commute3_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(x_1 = 0 ∨ x = 0 ∨ x_1 = 0) →
    ¬(x_1 = 0 ∨ x = 0) → 42#32 / x_1 &&& 42#32 / x ^^^ 42#32 / x_1 = 42#32 / x_1 &&& (42#32 / x ^^^ -1#32)

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

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

theorem sext_multi_uses_thm (e : IntW 64) (e_1 : IntW 1) (e_2 : IntW 64) :
  add (mul e_2 (sext 64 e_1)) (sub (LLVM.xor e (sext 64 e_1)) (sext 64 e_1)) ⊑
    select e_1 (sub (const? 64 0) (add e_2 e)) e

@[simp, simp_sllvm]
theorem pure_eq (x : α) (s) : (pure x : EffectM _) s = .value (x, s)

theorem test_sext2_proof : test_sext2_before ⊑ test_sext2_after

theorem no_shift_xor_multiuse_cmp_or_proof : no_shift_xor_multiuse_cmp_or_before ⊑ no_shift_xor_multiuse_cmp_or_after

theorem shl_or_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬((42#16 == 0 || 16 != 1 && x_1 == intMin 16 && 42#16 == -1) = true ∨ 5#16 ≥ ↑16 ∨ 7#16 ≥ ↑16) →
    12#16 ≥ ↑16 ∨
        (42#16 == 0 || 16 != 1 && x_1 == intMin 16 && 42#16 == -1) = true ∨
          True ∧ (x_1.srem 42#16 <<< 7#16).sshiftRight' 7#16 ≠ x_1.srem 42#16 ∨ 7#16 ≥ ↑16 →
      False

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

theorem lshr_sub_thm (e e_1 : IntW 8) :
  shl (sub (LLVM.srem e_1 (const? 8 42)) (lshr e (const? 8 3))) (const? 8 3) ⊑
    shl (sub (LLVM.srem e_1 (const? 8 42)) (lshr e (const? 8 3)) { «nsw» := true, «nuw» := false })
      (const? 8 3)

theorem ashr_16_to_64_add_zext_basic_proof : ashr_16_to_64_add_zext_basic_before ⊑ ashr_16_to_64_add_zext_basic_after

theorem trunc_lshr_exact_mask_thm (e : IntW 8) :
  LLVM.and (trunc 6 (lshr e (const? 8 2))) (const? 6 15) ⊑ lshr (trunc 6 e) (const? 6 2)

theorem src_is_notmask_x_xor_neg_x_inv_proof : src_is_notmask_x_xor_neg_x_inv_before ⊑ src_is_notmask_x_xor_neg_x_inv_after

theorem xor_and_or_proof : xor_and_or_before ⊑ xor_and_or_after

theorem alive_Select_641 : forall (w : Nat) (Y C : Bitvec 1)
(X : Bitvec w)
, TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec w)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (X) %v0;
  %v2 := op:const (C) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:icmp ne  w %v3;
  %v5 := op:const (Y) %v0;
  %v6 := triple:%v4 %v5 %v1;
  %v7 := op:select w %v6
  dsl_ret %v7
  ]  ⊑
  TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec w)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (X) %v0;
  %v2 := op:const (C) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:icmp ne  w %v3;
  %v5 := op:const (Y) %v0;
  %v6 := triple:%v4 %v5 %v2;
  %v7 := op:select w %v6
  dsl_ret %v7
  ]

theorem uge_to_slt_proof : uge_to_slt_before ⊑ uge_to_slt_after

theorem e_5 :
     - 1 *  ~~~y + 2 *  ~~~(x &&& y) - 1 *  ~~~(x |||  ~~~y) - 1 * (x &&&  ~~~y) = 1 *  ~~~x

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

theorem t10_shift_by_one_proof : t10_shift_by_one_before ⊑ t10_shift_by_one_after

theorem masked_and_notA_slightly_optimized_logical_proof : masked_and_notA_slightly_optimized_logical_before ⊑ masked_and_notA_slightly_optimized_logical_after

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

theorem e_301 :
     - 3 * y + 1 * (x ||| y) + 1 * (x |||  ~~~y) - 1 *  ~~~(x ||| y) - 9 *  ~~~(x |||  ~~~y) - 13 * (x &&&  ~~~y) + 1 * (x &&& y) =  - 11 * (x ^^^ y)

theorem icmp_slt_0_and_icmp_sge_neg1_i64_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬63#64 ≥ ↑64 → x >>> 63#64 &&& zeroExtend 64 (ofBool (-1#64 ≤ₛ x)) = zeroExtend 64 (ofBool (x == -1#64))

theorem test12_proof : test12_before ⊑ test12_after

theorem n3_constmask_samemask_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  x_1 &&& 65280#32 ^^^ x &&& 65280#32 = (x_1 ^^^ x) &&& 65280#32

theorem and_xor_or4_proof : and_xor_or4_before ⊑ and_xor_or4_after

theorem bools2_logical_commute3_and1_proof : bools2_logical_commute3_and1_before ⊑ bools2_logical_commute3_and1_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_3b_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_3b_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_3b_logical_after

theorem urem_i32_c_proof : urem_i32_c_before ⊑ urem_i32_c_after

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

theorem ugt_and_not_min_commute_proof : ugt_and_not_min_commute_before ⊑ ugt_and_not_min_commute_after

theorem icmp_equality_test_commute_icmp1_proof : icmp_equality_test_commute_icmp1_before ⊑ icmp_equality_test_commute_icmp1_after

theorem positive_sameconst_lshrexact_thm (e : IntW 8) : shl (lshr e (const? 8 3) { «exact» := true }) (const? 8 3) ⊑ e

theorem ne_21_comm_ne_proof : ne_21_comm_ne_before ⊑ ne_21_comm_ne_after

theorem sel_sext_constants_thm (e : IntW 1) :
  sext 16 (select e (const? 8 (-1)) (const? 8 42)) ⊑ select e (const? 16 (-1)) (const? 16 42)

theorem test_mul_nuw__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 icmp_select_var_commuted_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 8),
  ¬x_2 = 0 → ofBool (x_1 == 0#8) = 1#1 → ofBool (42#8 / x_2 == 42#8 / x_2) = 1#1

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

theorem main7b_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 sgt_swap_and_min_proof : sgt_swap_and_min_before ⊑ sgt_swap_and_min_after

theorem substitute_constant_or_ne_uge_commute_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.uge e_1 e) (icmp IntPred.ne e_1 (const? 8 42)) ⊑
    LLVM.or (icmp IntPred.ne e_1 (const? 8 42)) (icmp IntPred.ult e (const? 8 43))

theorem t15_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1 <<< x >>> x ≠ x_1 ∨ x ≥ ↑32 ∨ x_1 = 0) →
    ¬(True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨ x ≥ ↑32) → x_1 <<< x / x_1 = 1#32 <<< x

theorem uge_umin1_proof : uge_umin1_before ⊑ uge_umin1_after

theorem EqIsBisim {α} : @IsBisim α Eq

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

theorem test_shl_nsw__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 test_proof : test_before ⊑ test_after

theorem trunc_shl_33_i32_i64_proof : trunc_shl_33_i32_i64_before ⊑ trunc_shl_33_i32_i64_after

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

theorem tryFactorization_add_nuw_mul_nuw_mul_nuw_var_proof : tryFactorization_add_nuw_mul_nuw_mul_nuw_var_before ⊑ tryFactorization_add_nuw_mul_nuw_mul_nuw_var_after

theorem shl_add_nuw_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ x.uaddOverflow 5#32 = true ∨ x + 5#32 ≥ ↑32) → ¬x ≥ ↑32 → 6#32 <<< (x + 5#32) = 192#32 <<< x

theorem ne_smin4_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (add e_1 (const? 32 3))
      (select (icmp IntPred.slt e (add e_1 (const? 32 3))) e (add e_1 (const? 32 3))) ⊑
    icmp IntPred.sgt (add e_1 (const? 32 3)) e

theorem test_add_nuw__all_are_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 1073741823)) (const? 32 3)) (const? 32 4)
      (add (LLVM.and e (const? 32 1073741823)) (const? 32 1) { «nsw» := false, «nuw» := true }) ⊑
    add (LLVM.and e (const? 32 1073741823)) (const? 32 1) { «nsw» := true, «nuw» := true }

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

theorem PR2844_thm (e : IntW 32) :
  select (LLVM.or (icmp IntPred.eq e (const? 32 0)) (icmp IntPred.slt e (const? 32 (-638208501))))
      (const? 32 0) (const? 32 1) ⊑
    zext 32
      (LLVM.and (icmp IntPred.ne e (const? 32 0)) (icmp IntPred.sgt e (const? 32 (-638208502))))

theorem lshrugt_01_13_proof : lshrugt_01_13_before ⊑ lshrugt_01_13_after

theorem trunc_ashr_trunc_proof : trunc_ashr_trunc_before ⊑ trunc_ashr_trunc_after

@[simp] lemma eval_negOne (x : Fin 0 → BitStream) : negOne.eval x = BitStream.negOne

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

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

theorem test_shl_nsw__none_are_safe_proof : test_shl_nsw__none_are_safe_before ⊑ test_shl_nsw__none_are_safe_after

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

theorem neg_nsw_sgt_n1_proof : neg_nsw_sgt_n1_before ⊑ neg_nsw_sgt_n1_after

theorem trunc_shl_ashr_var_proof : trunc_shl_ashr_var_before ⊑ trunc_shl_ashr_var_after

theorem and_or1_commuted_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  x_1 ||

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

theorem wrongimm_proof : wrongimm_before ⊑ wrongimm_after

theorem test4_apint_thm (e : IntW 61) :
  LLVM.and (LLVM.xor e (const? 61 (-1))) (const? 61 5) ⊑ LLVM.xor (LLVM.and e (const? 61 5)) (const? 61 5)

theorem neg_thm (e : IntW 8) :
  LLVM.xor (sub (const? 8 0) e) (LLVM.udiv e (const? 8 42)) ⊑
    LLVM.xor (LLVM.udiv e (const? 8 42)) (sub (const? 8 0) e)

theorem udiv_shl_pair_const_thm (e : IntW 32) :
  LLVM.udiv (shl e (const? 32 2) { «nsw» := false, «nuw» := true })
      (shl e (const? 32 1) { «nsw» := false, «nuw» := true }) ⊑
    const? 32 2

theorem t4_proof : t4_before ⊑ t4_after

lemma nfaOfTerm_bv_language (t : Term) :
    nfaOfTerm t |>.bv_recognizes t.language

theorem test6_thm.extracted_1._1 : ∀ (x : BitVec 8), x ^^^ 17#8 ^^^ 17#8 = x

theorem logical_and_logical_and_icmps_comm1_proof : logical_and_logical_and_icmps_comm1_before ⊑ logical_and_logical_and_icmps_comm1_after

theorem logical_or_logical_or_icmps_comm3_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_2 &&& 1#8 == 0#8) = 1#1 →
      True ∧ 1#8 <<< x_1 >>> x_1 ≠ 1#8 ∨ x_1 ≥ ↑8 ∨ True ∧ 1#8 <<< x_1 >>> x_1 ≠ 1#8 ∨ x_1 ≥ ↑8 → False

theorem ule_umax4_proof : ule_umax4_before ⊑ ule_umax4_after

theorem logical_and_cond_reuse_proof : logical_and_cond_reuse_before ⊑ logical_and_cond_reuse_after

theorem test_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ofBool (x_1 <ₛ x) ||

theorem sge_or_max_logical_proof : sge_or_max_logical_before ⊑ sge_or_max_logical_after

theorem select_icmp_ne_0_and_4096_or_32_thm.extracted_1._4 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (0#32 != x_1 &&& 4096#32) = 1#1 → ¬7#32 ≥ ↑32 → x ||

private theorem BitVec.setWidth_lt_setWidth_of_lt {x y : BitVec w}
  {N : Nat} (hN : w ≤ N)
    (h : x < y) : x.setWidth N < y.setWidth N

theorem main2_logical_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 1#32 == 0#32) = 1#1 →
    ofBool (x &&& 2#32 == 0#32) = 1#1 → 0#32 = zeroExtend 32 (ofBool (x &&& 3#32 == 3#32))

theorem test4_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬3#32 = 0 → 3#32 = 0 ∨ True ∧ (x / 3#32).msb = true → False

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

theorem factorize4_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ¬1#32 ≥ ↑32 → x_1 <<< 1#32 * x - x * x_1 = x_1 * x

theorem low_bitmask_ult_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x + 31#8 &&& 31#8 <ᵤ x) = ofBool (x != 0#8)

theorem test_sub_0_Y_eq_0_thm (e : IntW 8) :
  icmp IntPred.eq (sub (const? 8 0) e) (const? 8 0) ⊑ icmp IntPred.eq e (const? 8 0)

theorem e_693 :
     - 11 * x + 1 *  ~~~(x &&& y) + 2 *  ~~~(x &&&  ~~~x) + 1 *  ~~~x + 1 * (x |||  ~~~y) + 1 * y + 1 *  ~~~(x ^^^ y) - 6 *  ~~~y + 13 * (x &&&  ~~~y) + 6 * (x &&& y) = 5 *  ~~~(x |||  ~~~y)

theorem sdiv_exact_eq_0_proof : sdiv_exact_eq_0_before ⊑ sdiv_exact_eq_0_after

theorem trunc_shl_31_i32_i64_thm (e : IntW 64) : trunc 32 (shl e (const? 64 31)) ⊑ shl (trunc 32 e) (const? 32 31)

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_5_proof : masked_icmps_mask_notallzeros_bmask_mixed_5_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_5_after

theorem test2_proof : test2_before ⊑ test2_after

theorem test1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 47),
  True ∧ (x_1 &&& BitVec.ofInt 47 (-70368744177664) &&& (x &&& 70368744177661#47) != 0) = true → False

theorem lshr_16_add_zext_basic_multiuse_proof : lshr_16_add_zext_basic_multiuse_before ⊑ lshr_16_add_zext_basic_multiuse_after

theorem positive_biggershl_shlnuw_lshrexact_proof : positive_biggershl_shlnuw_lshrexact_before ⊑ positive_biggershl_shlnuw_lshrexact_after

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

theorem test_shl_nuw__none_are_safe_proof : test_shl_nuw__none_are_safe_before ⊑ test_shl_nuw__none_are_safe_after

theorem fold_icmp_shl_nuw_c2_non_pow2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ 48#32 <<< x >>> x ≠ 48#32 ∨ x ≥ ↑32) → ofBool (48#32 <<< x <ᵤ 192#32) = ofBool (x <ᵤ 2#32)

theorem e_2303 :
    11 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 2 *  ~~~(d ||| e) + 1 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 4 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 7 *  ~~~( ~~~d &&& (e ||| f)) - 7 *  ~~~e + 4 * ( ~~~d &&& (e ||| f)) + 11 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 2 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 6 *  ~~~(d |||  ~~~f) - 5 * (e ^^^ (d &&& (e ||| f))) - 1 *  ~~~(d &&&  ~~~e) + 1 * ( ~~~e &&& (d ^^^ f)) - 3 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 3 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 2 *  ~~~(d ||| ( ~~~e &&& f)) + 7 * (e ^^^ ( ~~~d ||| (e ^^^ f))) + 5 *  ~~~(d ^^^ e) + 5 * (f ^^^  ~~~(d ||| (e &&& f))) - 7 * (f ^^^  ~~~(d &&& (e &&& f))) + 3 * (f |||  ~~~(d |||  ~~~e)) - 11 * (f ^^^ ( ~~~d ||| (e &&& f))) + 5 * ( ~~~f &&&  ~~~(d ^^^ e)) + 3 * (f |||  ~~~(d ^^^ e)) + 2 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 7 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 1 * (d ^^^ ( ~~~e ||| f)) + 4 *  ~~~(d ^^^ (e ||| f)) - 5 * (d &&& e) + 11 * (d ^^^ (e ^^^ f)) - 6 * (e ^^^ (d &&&  ~~~f)) + 2 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 1 *  ~~~(d &&& (e &&& f)) - 1 * (f ^^^ (d ||| ( ~~~e &&& f))) + 1 * (d ||| ( ~~~e &&& f)) - 3 *  ~~~(d &&& (e ||| f)) + 1 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 5 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 1 * (d &&& (e ||| f)) + 2 * ((d &&& e) |||  ~~~(e ||| f)) + 5 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 3 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 5 * ( ~~~d ||| ( ~~~e &&& f)) - 2 * (f ^^^ ( ~~~d ||| (e ||| f))) + 3 * ( ~~~f |||  ~~~(d ^^^ e)) - 2 * ( ~~~d ||| (e ^^^ f)) + 7 * ((d ^^^ e) |||  ~~~(d ^^^ f)) + 1 * (f ^^^  ~~~(d &&& e)) - 2 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) - 1 *  ~~~(d ||| (e ^^^ f)) - 7 * (e &&&  ~~~(d &&&  ~~~f)) + 4 * (d ||| f) + 2 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 25 *  ~~~(d ||| (e ||| f)) - 12 *  ~~~(d ||| ( ~~~e ||| f)) - 11 *  ~~~( ~~~d ||| (e ||| f)) - 9 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 34 * ( ~~~d &&& ( ~~~e &&& f)) - 8 * ( ~~~d &&& (e &&& f)) - 20 * (d &&& ( ~~~e &&& f)) - 43 * (d &&& (e &&& f)) = 11 * (d ^^^ ( ~~~e &&& f))

theorem slt_swap_or_not_max_commute_proof : slt_swap_or_not_max_commute_before ⊑ slt_swap_or_not_max_commute_after

theorem or_signbit_select_lshr_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 → ¬8#32 ≥ ↑32 → (x ||| BitVec.ofInt 32 (-65536)) >>> 8#32 = x >>> 8#32 ||

theorem exactly_one_set_signbit_proof : exactly_one_set_signbit_before ⊑ exactly_one_set_signbit_after

theorem e_1511 :
     - 2 * ((a &&&  ~~~b) ||| (a ^^^ (b ^^^ c))) + 4 * (a &&&  ~~~b) + 5 *  ~~~(a ||| (b ^^^ c)) - 5 *  ~~~(a ||| (b ||| c)) + 2 *  ~~~(a ||| ( ~~~b ||| c)) - 2 *  ~~~( ~~~a ||| (b ||| c)) + 2 * ( ~~~a &&& ( ~~~b &&& c)) - 5 * ( ~~~a &&& (b &&& c)) + 2 * (a &&& (b &&& c)) = 2 * (a &&& ( ~~~b &&& c))

theorem lshrult_03_09_proof : lshrult_03_09_before ⊑ lshrult_03_09_after

theorem trunc_equality_nsw_sext_proof : trunc_equality_nsw_sext_before ⊑ trunc_equality_nsw_sext_after

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 src_is_notmask_ashr_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 8) (x_2 : BitVec 16),
  ¬(x_1 ≥ ↑8 ∨ x ≥ ↑16) →
    ofBool
        (x_2 ^^^ 123#16 ==
          (x_2 ^^^ 123#16) &&& ((signExtend 16 (BitVec.ofInt 8 (-32) <<< x_1)).sshiftRight' x ^^^ -1#16)) =
      ofBool ((signExtend 16 (BitVec.ofInt 8 (-32) <<< x_1)).sshiftRight' x ≤ᵤ x_2 ^^^ BitVec.ofInt 16 (-124))

theorem test4_proof : test4_before ⊑ test4_after

theorem sub_ashr_and_i32_proof : sub_ashr_and_i32_before ⊑ sub_ashr_and_i32_after

theorem slt_zero_proof : slt_zero_before ⊑ slt_zero_after

theorem or_logic_or_logic_and_1_proof : or_logic_or_logic_and_1_before ⊑ or_logic_or_logic_and_1_after

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

theorem 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 prove_exact_with_high_mask_limit_proof : prove_exact_with_high_mask_limit_before ⊑ prove_exact_with_high_mask_limit_after

theorem sub_mask1_lshr_thm (e : IntW 8) :
  sub (const? 8 10) (LLVM.and (lshr e (const? 8 1)) (const? 8 1)) ⊑
    add (ashr (shl e (const? 8 6)) (const? 8 7)) (const? 8 10) { «nsw» := true, «nuw» := false }

theorem main6c_proof : main6c_before ⊑ main6c_after

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

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

theorem scalar_i32_shl_and_signbit_eq_nonzero_thm (e e_1 : IntW 32) :
  icmp IntPred.eq (LLVM.and (shl e_1 e) (const? 32 (-2147483648))) (const? 32 1) ⊑ const? 1 0

theorem add_congr (e1 : a ≈ʷ b) (e2 : c ≈ʷ d) : (a + c) ≈ʷ (b + d)

theorem select_2_thm (e e_1 e_2 : IntW 8) (e_3 e_4 : IntW 1) :
  LLVM.xor
      (select e_4 (select e_3 (LLVM.xor e_2 (const? 8 (-1))) (LLVM.xor e_1 (const? 8 123))) (LLVM.xor e (const? 8 45)))
      (const? 8 (-1)) ⊑
    select e_4 (select e_3 e_2 (LLVM.xor e_1 (const? 8 (-124)))) (LLVM.xor e (const? 8 (-46)))

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

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

theorem t0_proof : t0_before ⊑ t0_after

theorem udiv_c_i32_proof : udiv_c_i32_before ⊑ udiv_c_i32_after

theorem n11_wrong_pred3_proof : n11_wrong_pred3_before ⊑ n11_wrong_pred3_after

theorem e_33 :
     - 1 * (x ||| y) - 1 *  ~~~(x &&& y) + 1 *  ~~~(x ||| y) + 1 * (x &&&  ~~~y) + 1 * (x &&& y) =  - 1 * (x ^^^ y) - 1 *  ~~~(x |||  ~~~y)

theorem and_orn_cmp_1_logical_thm (e : IntW 1) (e_1 e_2 : IntW 32) :
  select (icmp IntPred.sgt e_2 e_1) (select e (const? 1 1) (icmp IntPred.sle e_2 e_1)) (const? 1 0) ⊑
    select (icmp IntPred.sgt e_2 e_1) e (const? 1 0)

theorem fold_sext_to_and_wrong7_proof : fold_sext_to_and_wrong7_before ⊑ fold_sext_to_and_wrong7_after

@[simp]
theorem eval_repeatForever_eq_self' (b : Bool) {i : Nat} : (FSM.repeatForever b).eval env i = b

theorem foo_thm (e : IntW 32) :
  LLVM.and (sub (const? 32 5) e) (const? 32 2) ⊑ LLVM.and (sub (const? 32 1) e) (const? 32 2)

theorem ashrsgt_03_07_proof : ashrsgt_03_07_before ⊑ ashrsgt_03_07_after

theorem e_809 :
     - 6 *  ~~~(z &&& t) - 11 *  ~~~z + 17 *  ~~~(z |||  ~~~t) + 6 * (z &&&  ~~~t) + 2 * (z &&& t) =  - 19 *  ~~~(z ||| t) + 2 *  ~~~(z ^^^ t)

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

theorem e_2437 :
     - 5 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 2 *  ~~~(e ^^^ f) + 1 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * (e &&& f) - 5 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 2 * (d ||| ( ~~~e ||| f)) - 7 * (e ^^^  ~~~(d ||| f)) - 11 *  ~~~(d ^^^ ( ~~~e ||| f)) - 3 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) + 2 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 6 * (d ^^^ f) + 4 * (e ^^^ (d ||| f)) - 1 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 11 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 6 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) - 3 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 2 * (e ^^^ (d ||| ( ~~~e &&& f))) - 5 * ((d &&& e) ^^^ (e |||  ~~~f)) + 1 * (e ^^^ (d ||| (e ^^^ f))) + 4 * ((d ^^^ e) ||| (d ^^^ f)) + 4 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 3 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 3 *  ~~~( ~~~d ||| ( ~~~e &&& f)) + 7 * (f ^^^ (d &&& ( ~~~e ||| f))) + 5 * ( ~~~d &&& (e ||| f)) - 2 * (e |||  ~~~f) + 2 * (e ^^^ (d &&&  ~~~f)) + 1 *  ~~~(d ||| (e ^^^ f)) + 5 * (d &&&  ~~~f) + 7 * (f &&& (d |||  ~~~e)) - 5 * ((d ||| e) &&& (e ^^^ f)) - 2 * (d &&& ( ~~~e ||| f)) - 11 * (e ^^^  ~~~(d |||  ~~~f)) + 7 *  ~~~( ~~~d ||| (e &&& f)) - 6 * (f ^^^ (d &&& e)) + 1 * (e ^^^ ( ~~~d &&& (e ||| f))) - 5 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 4 * (f ||| (d &&&  ~~~e)) + 11 *  ~~~(d ^^^ (e &&& f)) + 2 * (e ||| (d &&&  ~~~f)) + 2 * (e ^^^ (d ||| ( ~~~e ||| f))) - 1 * (e ^^^  ~~~(d ||| (e &&& f))) - 2 *  ~~~(d ^^^ f) + 1 * (e ^^^ ( ~~~d ||| (e &&& f))) - 1 * (d ^^^ (e ||| f)) + 5 * (f &&& (d ||| e)) + 2 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 2 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 2 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 7 * (e &&& (d |||  ~~~f)) - 2 * (e |||  ~~~(d ^^^ f)) + 1 * ((d &&& e) |||  ~~~(e ||| f)) - 7 * (e ||| (d ^^^ f)) + 1 * (d &&& e) + 1 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 1 * (e ^^^ f) + 4 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 7 *  ~~~(d &&&  ~~~e) - 7 * (e ^^^  ~~~(d &&&  ~~~f)) - 11 *  ~~~(d &&& (e ||| f)) - 11 * (e ^^^  ~~~(d &&& (e ||| f))) - 2 * (d ||| ( ~~~e &&& f)) - 3 * (f &&&  ~~~(d &&& e)) + 7 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 1 *  ~~~( ~~~d &&& (e ^^^ f)) + 1 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 1 * (f ^^^  ~~~(d &&&  ~~~e)) + 5 * (f |||  ~~~(d ||| e)) + 19 *  ~~~(d ||| (e ||| f)) + 13 *  ~~~(d ||| ( ~~~e ||| f)) + 24 *  ~~~( ~~~d ||| (e ||| f)) + 7 * ( ~~~d &&& ( ~~~e &&& f)) + 2 * ( ~~~d &&& (e &&& f)) - 16 * (d &&& ( ~~~e &&& f)) + 15 * (d &&& (e &&& f)) =  - 28 *  ~~~( ~~~d ||| ( ~~~e ||| f))

theorem e_1526 :
     - 1 * (b ^^^ (a &&& c)) - 2 * (a &&& c) + 3 * ( ~~~c &&& (a ^^^ b)) + 11 * (a &&&  ~~~c) + 2 * (c &&& (a ^^^ b)) + 5 * (b ^^^  ~~~(a |||  ~~~c)) - 7 *  ~~~(a ||| ( ~~~b ||| c)) - 14 *  ~~~( ~~~a ||| (b ||| c)) - 5 * ( ~~~a &&& ( ~~~b &&& c)) + 1 * (a &&& ( ~~~b &&& c)) - 3 * (a &&& (b &&& c)) = 1 * ( ~~~a &&& (b &&& c)) + 15 *  ~~~( ~~~a ||| ( ~~~b ||| c))

theorem trunc_shl_lshr_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 test15_thm (e : IntW 32) :
  sext 32 (icmp IntPred.ne (LLVM.and e (const? 32 16)) (const? 32 0)) ⊑
    ashr (shl e (const? 32 27)) (const? 32 31)

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

theorem shl_add_log_may_cause_poison_pr62175_with_nsw_proof : shl_add_log_may_cause_poison_pr62175_with_nsw_before ⊑ shl_add_log_may_cause_poison_pr62175_with_nsw_after

theorem xor_signbit_shl_proof : xor_signbit_shl_before ⊑ xor_signbit_shl_after

theorem not_or_or_and_not_and_and_commute2_and_proof : not_or_or_and_not_and_and_commute2_and_before ⊑ not_or_or_and_not_and_and_commute2_and_after

theorem demorgan_and_zext_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  (zeroExtend 32 x_1 ^^^ 1#32) &&& (zeroExtend 32 x ^^^ 1#32) = zeroExtend 32 ((x_1 ||| x) ^^^ 1#1)

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

@[simp]
theorem Factor.numVars_term : (Factor.var n).numVars = n + 1

theorem bv_AndOrXor_698 :
    ∀ (e e_1 e_2 : LLVM.IntW w),
      LLVM.and (LLVM.icmp LLVM.IntPred.eq (LLVM.and e e_1) (LLVM.const? w 0))
          (LLVM.icmp LLVM.IntPred.eq (LLVM.and e e_2) (LLVM.const? w 0)) ⊑
        LLVM.icmp LLVM.IntPred.eq (LLVM.and e (LLVM.or e_1 e_2)) (LLVM.const? w 0)

theorem test2_proof : test2_before ⊑ test2_after

theorem t2_thm (e : IntW 32) (e_1 : IntW 64) :
  LLVM.udiv e_1 (zext 64 (shl (const? 32 1) e)) ⊑ lshr e_1 (zext 64 e { «nneg» := true })

theorem uge_swap_and_max_commute_proof : uge_swap_and_max_commute_before ⊑ uge_swap_and_max_commute_after

theorem and_sequence_20_eq (w : Nat) :
    and_sequence_20_lhs w  ⊑ and_sequence_20_rhs w

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

theorem badimm1_thm.extracted_1._4 : ∀ (x : BitVec 16),
  ¬(7#8 ≥ ↑8 ∨ 9#16 ≥ ↑16) →
    ¬ofBool ((truncate 8 x).sshiftRight' 7#8 == truncate 8 (x >>> 9#16)) = 1#1 →
      ¬15#16 ≥ ↑16 →
        ¬(7#8 ≥ ↑8 ∨
              9#16 ≥ ↑16 ∨
                True ∧ signExtend 16 (truncate 8 (x >>> 9#16)) ≠ x >>> 9#16 ∨
                  True ∧ zeroExtend 16 (truncate 8 (x >>> 9#16)) ≠ x >>> 9#16) →
          ¬ofBool (-1#16 <ₛ x) = 1#1 → truncate 8 (x.sshiftRight' 15#16) ^^^ 127#8 = BitVec.ofInt 8 (-128)

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

theorem main3b_thm (e : IntW 32) :
  select
      (LLVM.and (icmp IntPred.eq (LLVM.and e (const? 32 7)) (const? 32 0))
        (icmp IntPred.ne (LLVM.and e (const? 32 16)) (const? 32 16)))
      (const? 32 0) (const? 32 1) ⊑
    zext 32 (icmp IntPred.ne (LLVM.and e (const? 32 23)) (const? 32 0))

theorem e_1836 :
    2 * ((a &&& b) ^^^  ~~~(a ^^^ (b &&& c))) + 2 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) + 1 * (a &&&  ~~~b) + 2 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) + 5 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) + 11 * ((a |||  ~~~b) &&& (b ^^^ c)) - 6 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 4 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) + 1 * ( ~~~a &&& (b ||| c)) - 5 *  ~~~(a ^^^ c) + 4 * ( ~~~(a ||| b) ||| (b ^^^ c)) - 1 * (a ||| (b &&& c)) + 3 *  ~~~(a &&& ( ~~~b &&& c)) + 7 * (b ^^^ (a ||| (b ||| c))) - 1 * (c ^^^  ~~~(a ||| b)) - 1 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 2 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 1 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 11 *  ~~~(a ||| (b &&& c)) + 1 * (c ^^^ (a &&& ( ~~~b ||| c))) + 4 * (c |||  ~~~(a ||| b)) - 6 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) - 1 * (a &&& c) - 6 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) + 2 * (c ^^^ (a ||| ( ~~~b &&& c))) + 11 * (b ^^^  ~~~(a &&& (b ^^^ c))) - 2 * ((a ^^^ b) &&& (a ^^^ c)) - 1 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 11 * ( ~~~b |||  ~~~(a ^^^ c)) + 11 * ( ~~~a ||| (b ^^^ c)) + 1 * (b ||| c) + 1 * (b &&& (a ^^^ c)) + 1 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) - 2 * (b ^^^ (a ||| (b ^^^ c))) + 3 * (a ^^^ (b ||| c)) - 2 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) - 37 *  ~~~(a ||| ( ~~~b ||| c)) - 29 *  ~~~( ~~~a ||| (b ||| c)) - 38 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 70 * ( ~~~a &&& ( ~~~b &&& c)) - 23 * ( ~~~a &&& (b &&& c)) - 36 * (a &&& ( ~~~b &&& c)) - 9 * (a &&& (b &&& c)) = 50 *  ~~~(a ||| (b ||| c)) - 4 * (b ^^^  ~~~(a &&& ( ~~~b &&& c)))

theorem mul_sel_op0_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1), x_1 = 1#1 → 0#32 * x = 0#32

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

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

theorem ne_smax3_proof : ne_smax3_before ⊑ ne_smax3_after

theorem pr40493_neg2_thm (e : IntW 32) :
  icmp IntPred.eq (LLVM.and (mul e (const? 32 12)) (const? 32 15)) (const? 32 0) ⊑
    icmp IntPred.eq (LLVM.and (mul e (const? 32 12)) (const? 32 12)) (const? 32 0)

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

theorem drop_nsw_trunc_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬(True ∧ signExtend 16 (truncate 8 (x_1 &&& 255#16 &&& x)) ≠ x_1 &&& 255#16 &&& x) →
    truncate 8 (x_1 &&& 255#16 &&& x) = truncate 8 (x_1 &&& x)

theorem or_consts_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (4#32 &&& x != 0#32) = 1#1 → 0#1 = ofBool (x &&& 12#32 == 12#32)

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

theorem test_add_nuw__none_are_safe_proof : test_add_nuw__none_are_safe_before ⊑ test_add_nuw__none_are_safe_after

theorem e_95 :
     - 2 *  ~~~(x ^^^ y) - 1 * (x |||  ~~~y) - 11 *  ~~~(x &&&  ~~~x) + 11 *  ~~~(x |||  ~~~y) + 18 * (x &&&  ~~~y) + 14 * (x &&& y) =  - 20 *  ~~~(x ||| y) + 6 *  ~~~y

theorem ashrslt_02_12_proof : ashrslt_02_12_before ⊑ ashrslt_02_12_after

theorem test_shl_nuw__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 neg_or_lshr_i32_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → (0#32 - x ||| x) >>> 31#32 = zeroExtend 32 (ofBool (x != 0#32))

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

@[simp]
theorem ofBitVec_getLsbD (n : Nat) (h : n < w) : ofBitVecSext x n = x.getLsbD n

theorem sge_swap_or_max_proof : sge_swap_or_max_before ⊑ sge_swap_or_max_after

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

theorem test28 {w : Nat} (x : BitVec w) :
    x &&& x &&& x &&& x &&& x &&& x = x

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

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

theorem e_294 :
     - 2 *  ~~~(x &&& y) + 11 *  ~~~y - 2 *  ~~~(x ^^^ y) + 11 *  ~~~x - 18 *  ~~~(x ||| y) - 4 *  ~~~(x |||  ~~~y) - 9 * (x &&&  ~~~y) =  - 7 * (x &&& y) + 5 * y

theorem e_117 :
     - 11 *  ~~~y - 11 *  ~~~(x &&&  ~~~y) - 2 * (x ||| y) + 21 *  ~~~(x ||| y) + 12 *  ~~~(x |||  ~~~y) + 13 * (x &&& y) =  - 12 * (x &&&  ~~~y) - 1 *  ~~~(x &&& y)

theorem icmp_slt_0_and_icmp_sge_neg2_i64_proof : icmp_slt_0_and_icmp_sge_neg2_i64_before ⊑ icmp_slt_0_and_icmp_sge_neg2_i64_after

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

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 or_signbit_select_lshr_proof : or_signbit_select_lshr_before ⊑ or_signbit_select_lshr_after

theorem no_shift_no_xor_multiuse_cmp_with_xor_proof : no_shift_no_xor_multiuse_cmp_with_xor_before ⊑ no_shift_no_xor_multiuse_cmp_with_xor_after

theorem shl_nsw_add_nuw_thm (e : IntW 32) :
  add (shl (const? 32 1) e { «nsw» := true, «nuw» := false }) (const? 32 (-1)) { «nsw» := false, «nuw» := true } ⊑
    const? 32 (-1)

theorem fold_add_udiv_urem_commuted_thm (e : IntW 32) :
  add (urem e (const? 32 10)) (shl (LLVM.udiv e (const? 32 10)) (const? 32 4)) ⊑
    add (mul (LLVM.udiv e (const? 32 10)) (const? 32 6) { «nsw» := false, «nuw» := true }) e

theorem ugt_3_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (3#8 <ᵤ truncate 8 x) = ofBool (x &&& 252#32 != 0#32)

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

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

theorem ashrslt_03_00_exact_proof : ashrslt_03_00_exact_before ⊑ ashrslt_03_00_exact_after

theorem main13_logical_proof : main13_logical_before ⊑ main13_logical_after

theorem ashrsgt_03_01_exact_proof : ashrsgt_03_01_exact_before ⊑ ashrsgt_03_01_exact_after

theorem land_band_left2_proof : land_band_left2_before ⊑ land_band_left2_after

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

theorem trunc_lshr_sext_exact_proof : trunc_lshr_sext_exact_before ⊑ trunc_lshr_sext_exact_after

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

theorem urem_common_divisor_defined_cond_proof : urem_common_divisor_defined_cond_before ⊑ urem_common_divisor_defined_cond_after

theorem lshr_32_add_zext_basic_proof : lshr_32_add_zext_basic_before ⊑ lshr_32_add_zext_basic_after

theorem icmp_ule_proof : icmp_ule_before ⊑ icmp_ule_after

theorem e_2101 :
     - 6 * (e ^^^ (d ||| ( ~~~e ||| f))) - 1 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 3 * ( ~~~e ||| (d ^^^ f)) + 3 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 11 * (e ^^^ (d ||| f)) - 7 * ( ~~~d &&& (e ^^^ f)) - 1 *  ~~~(d &&& (e ||| f)) - 11 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * (e ^^^ (d ||| ( ~~~e &&& f))) - 2 * (d &&& (e ||| f)) - 6 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 *  ~~~(d ^^^ e) + 4 *  ~~~(d ^^^ ( ~~~e &&& f)) - 3 *  ~~~(d &&& f) + 1 * (f |||  ~~~(d |||  ~~~e)) - 3 *  ~~~(d |||  ~~~e) - 2 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 4 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 1 * (f ^^^  ~~~(d |||  ~~~e)) - 5 * (d ^^^ e) - 1 * (e ^^^ ( ~~~d ||| (e &&& f))) + 7 * ((d &&& f) ^^^ (e ||| f)) + 11 *  ~~~(d ||| ( ~~~e &&& f)) - 1 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 1 * (d &&& ( ~~~e ||| f)) + 2 * (e &&& f) - 2 * d - 2 * ((d &&& e) ^^^ (e |||  ~~~f)) + 1 *  ~~~(d ||| (e &&& f)) + 2 * (e |||  ~~~(d |||  ~~~f)) - 2 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 2 * (f |||  ~~~(d ^^^ e)) + 5 * (f ^^^  ~~~(d &&&  ~~~e)) - 1 * (e ^^^ ( ~~~d &&& (e ||| f))) - 2 *  ~~~(d ||| (e ||| f)) + 6 *  ~~~(d ||| ( ~~~e ||| f)) + 46 *  ~~~( ~~~d ||| (e ||| f)) + 8 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 9 * ( ~~~d &&& ( ~~~e &&& f)) + 7 * ( ~~~d &&& (e &&& f)) + 30 * (d &&& ( ~~~e &&& f)) - 5 * (d &&& (e &&& f)) =  - 3 *  ~~~(d ||| e)

theorem icmp_slt_0_xor_icmp_sge_neg2_i32_fail_proof : icmp_slt_0_xor_icmp_sge_neg2_i32_fail_before ⊑ icmp_slt_0_xor_icmp_sge_neg2_i32_fail_after

theorem different_size_sext_sext_eq_proof : different_size_sext_sext_eq_before ⊑ different_size_sext_sext_eq_after

theorem lshr_shl_eq_amt_multi_use_thm (e : IntW 43) :
  mul (lshr e (const? 43 23)) (shl (lshr e (const? 43 23)) (const? 43 23)) ⊑
    mul (lshr e (const? 43 23)) (LLVM.and e (const? 43 (-8388608)))

theorem test9_proof : test9_before ⊑ test9_after

theorem test3i_proof : test3i_before ⊑ test3i_after

theorem e_2023 :
     - 1 * (f ^^^ ( ~~~d ||| (e ||| f))) + 2 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 3 * (e ^^^ (d &&& ( ~~~e ||| f))) - 11 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 3 * (e &&&  ~~~(d ^^^ f)) - 2 * ((d &&& f) ^^^ (e ||| f)) - 7 * ((d ||| e) &&& (e ^^^ f)) - 6 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 2 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 7 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 1 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) + 11 *  ~~~(d ||| e) + 1 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 6 * (d ||| ( ~~~e ||| f)) + 2 *  ~~~f + 2 * ( ~~~d &&& (e ||| f)) - 1 * ( ~~~d ||| (e &&& f)) + 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 3 * (d ^^^ f) - 7 * (d &&& (e ||| f)) - 1 * (d ||| (e ||| f)) - 1 * (e ^^^ (d ||| (e ||| f))) + 3 * (e ^^^ ( ~~~d &&& (e ||| f))) + 1 * (e ^^^  ~~~(d &&& (e ||| f))) + 4 * (e ^^^ ( ~~~d ||| (e ||| f))) - 9 *  ~~~(d ||| (e ||| f)) + 13 *  ~~~(d ||| ( ~~~e ||| f)) + 15 *  ~~~( ~~~d ||| (e ||| f)) + 36 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 8 * ( ~~~d &&& ( ~~~e &&& f)) + 25 * ( ~~~d &&& (e &&& f)) + 29 * (d &&& ( ~~~e &&& f)) + 18 * (d &&& (e &&& f)) = 1 * ( ~~~d ||| (e ||| f))

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

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

@[simp] theorem val_appendInr {v : Var Δ t} : (v.appendInr (Γ := Γ)).val = v.val + Γ.length

theorem or_sext_sext_proof : or_sext_sext_before ⊑ or_sext_sext_after

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

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

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

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

theorem thisdoesnotloop_proof : thisdoesnotloop_before ⊑ thisdoesnotloop_after

theorem e_2448 :
     - 2 *  ~~~(d ^^^ e) - 1 * (f ^^^  ~~~(d &&& (e &&& f))) + 11 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 7 * (d ^^^ f) + 2 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 *  ~~~(d ||| ( ~~~e &&& f)) - 11 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 5 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 2 * (e &&& (d ^^^ f)) + 5 *  ~~~(d ^^^ ( ~~~e &&& f)) + 2 *  ~~~(d &&& (e ||| f)) + 1 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) + 5 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * (f ^^^  ~~~(d &&& (e ||| f))) - 2 * (e &&& f) - 2 * ((d ^^^ e) &&& (d ^^^ f)) + 1 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 1 *  ~~~(d ^^^ f) - 6 * (f ^^^  ~~~(d ||| e)) - 1 * (d &&&  ~~~e) - 2 *  ~~~(d &&& ( ~~~e &&& f)) - 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 2 * ( ~~~e |||  ~~~(d ^^^ f)) + 7 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 11 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 11 *  ~~~(d ^^^ (e ^^^ f)) - 6 * ( ~~~f &&& (d ^^^ e)) + 5 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 6 * (d ||| ( ~~~e &&& f)) + 7 * (e ^^^ (d ||| ( ~~~e ||| f))) - 2 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 6 * ((d ^^^ e) ||| (d ^^^ f)) + 4 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 3 * (e ^^^  ~~~(d ||| f)) - 3 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 7 * (f ^^^ (d &&& ( ~~~e ||| f))) + 4 * (d |||  ~~~f) - 3 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 1 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 11 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 7 * (f &&&  ~~~(d ^^^ e)) - 1 * ((d &&& f) ^^^ (e ||| f)) + 1 * (f ^^^  ~~~(d &&& e)) + 1 * ( ~~~d ||| (e &&& f)) - 2 *  ~~~( ~~~d &&& (e ||| f)) - 1 * ((d &&& e) ^^^ (e |||  ~~~f)) + 7 * ( ~~~d &&& (e ||| f)) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 1 * (e |||  ~~~(d ^^^ f)) - 1 * ((d |||  ~~~e) &&& (e ^^^ f)) + 3 *  ~~~(d &&&  ~~~d) - 3 *  ~~~( ~~~d ||| (e &&& f)) - 2 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 1 * (f ^^^  ~~~(d &&&  ~~~e)) + 3 * (e |||  ~~~(d ||| f)) - 5 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 2 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 2 * (f |||  ~~~(d ^^^ e)) - 3 * (d ||| (e &&& f)) + 11 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 11 * (e ^^^ (d &&& f)) + 4 * (f ^^^  ~~~(d ||| (e &&& f))) + 7 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 1 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 3 * ((e &&& f) ||| (d &&& (e ||| f))) + 1 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 2 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 1 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 27 *  ~~~(d ||| (e ||| f)) - 68 *  ~~~(d ||| ( ~~~e ||| f)) - 21 *  ~~~( ~~~d ||| (e ||| f)) - 37 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 6 * ( ~~~d &&& ( ~~~e &&& f)) - 33 * ( ~~~d &&& (e &&& f)) - 8 * (d &&& ( ~~~e &&& f)) + 3 * (d &&& (e &&& f)) =  - 1 * (e ^^^ ( ~~~d &&& (e ||| f)))

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

theorem trunc_signed_nsw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬(True ∧ signExtend 16 (truncate 8 x_1) ≠ x_1 ∨ True ∧ signExtend 16 (truncate 8 x) ≠ x) →
    ofBool (truncate 8 x_1 <ₛ truncate 8 x) = ofBool (x_1 <ₛ x)

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

theorem bv_AddSub_1202 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.add (LLVM.xor e (LLVM.const? w (-1))) e_1 ⊑ LLVM.sub (LLVM.sub e_1 (LLVM.const? w 1)) e

@[bv_multi_width_normalize]
theorem BitVec.lt_ult {x y : BitVec w} : (x < y) = (x.ult y)

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

theorem PR60818_ne_proof : PR60818_ne_before ⊑ PR60818_ne_after

theorem or_not_and_and_not_and_xor_commute4_proof : or_not_and_and_not_and_xor_commute4_before ⊑ or_not_and_and_not_and_xor_commute4_after

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

@[simp]
theorem Array.take_ge_size {a : Array α} {n} (h : n ≥ a.size) : a.take n = a

theorem e_1399 :
     - 1 *  ~~~z + 1 *  ~~~(z &&&  ~~~z) + 2 * t - 1 * (z ^^^ t) - 7 *  ~~~t - 3 *  ~~~(z &&& t) + 11 *  ~~~(z ||| t) + 3 *  ~~~(z |||  ~~~t) + 10 * (z &&&  ~~~t) - 2 * (z &&& t) = 1 *  ~~~(z &&&  ~~~t)

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

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

theorem lowmask_add_zext_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 8),
  zeroExtend 32 x_1 + x &&& 255#32 = zeroExtend 32 (x_1 + truncate 8 x)

theorem invert_signbit_splat_mask_thm (e : IntW 16) (e_1 : IntW 8) :
  LLVM.and (sext 16 (LLVM.xor (ashr e_1 (const? 8 7)) (const? 8 (-1)))) e ⊑
    select (icmp IntPred.sgt e_1 (const? 8 (-1))) e (const? 16 0)

theorem pr51551_neg2_proof : pr51551_neg2_before ⊑ pr51551_neg2_after

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

theorem test_zext_nneg_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32) (x_2 : BitVec 64),
  ¬(True ∧ (x_1 ^^^ -1#32).msb = true) →
    x_2 + BitVec.ofInt 64 (-5) - (zeroExtend 64 (x_1 ^^^ -1#32) + x) =
      x_2 + BitVec.ofInt 64 (-4) + (signExtend 64 x_1 - x)

@[simp, grind=] lemma val_start_appendInl (r : DeleteRange Γ) :
    (r.appendInl (ts := ts)).start.val = r.start.val + ts.length

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

theorem e_829 :
    2 *  ~~~(z &&&  ~~~t) - 2 * z - 5 *  ~~~(z &&& t) + 5 *  ~~~(z |||  ~~~t) + 2 * (z &&&  ~~~t) = 2 *  ~~~z - 5 *  ~~~t

theorem test_proof : test_before ⊑ test_after

theorem lshrugt_02_07_proof : lshrugt_02_07_before ⊑ lshrugt_02_07_after

theorem ashrslt_01_01_proof : ashrslt_01_01_before ⊑ ashrslt_01_01_after

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

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

theorem xor_or_xor_common_op_commute2_proof : xor_or_xor_common_op_commute2_before ⊑ xor_or_xor_common_op_commute2_after

theorem alive_AndOrXor_1288_A__B__B__C__A___A__B__C  (w : Nat)   : alive_AndOrXor_1288_A__B__B__C__A___A__B__C_src w  ⊑ alive_AndOrXor_1288_A__B__B__C__A___A__B__C_tgt w

theorem foo_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(-1#32 == 0 || 32 != 1 && x == intMin 32 && -1#32 == -1) = true → ofBool (x.srem (-1#32) == 0#32) = 1#1

theorem sge_to_ugt_proof : sge_to_ugt_before ⊑ sge_to_ugt_after

theorem sge_or_not_max_commute_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.ne e_1 (const? 8 127)) (const? 1 1) (icmp IntPred.sge e_1 e) ⊑ const? 1 1

theorem ne_smax3_proof : ne_smax3_before ⊑ ne_smax3_after

theorem ashr_eq_exact_thm (e : IntW 8) :
  icmp IntPred.eq (ashr e (const? 8 3) { «exact» := true }) (const? 8 10) ⊑
    icmp IntPred.eq e (const? 8 80)

theorem uge_sext_proof : uge_sext_before ⊑ uge_sext_after

theorem ashr_ult_exact_near_pow2_cmpval_thm (e : IntW 8) :
  icmp IntPred.ult (ashr e (const? 8 1) { «exact» := true }) (const? 8 5) ⊑
    icmp IntPred.ult e (const? 8 9)

theorem e_1600 :
    7 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) + 4 * ((a &&& b) ^^^ (a ^^^ ( ~~~b ||| c))) - 1 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) - 1 * ( ~~~(a &&& b) &&& (b ^^^ c)) + 7 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 1 * ( ~~~a &&& (b ^^^ c)) - 3 * (a ||| (b &&& c)) + 1 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) - 3 * (b ||| (a ^^^ c)) - 5 *  ~~~( ~~~a &&& (b &&& c)) + 7 *  ~~~(a &&&  ~~~c) + 4 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) - 17 *  ~~~(a ||| (b ||| c)) - 3 *  ~~~(a ||| ( ~~~b ||| c)) + 3 *  ~~~( ~~~a ||| (b ||| c)) - 11 * ( ~~~a &&& (b &&& c)) - 12 * (a &&& ( ~~~b &&& c)) - 11 * (a &&& (b &&& c)) = 15 * ( ~~~a &&& ( ~~~b &&& c)) - 7 * (c ^^^ (a &&& b))

theorem both_sides_fold_eq_proof : both_sides_fold_eq_before ⊑ both_sides_fold_eq_after

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

theorem fold_and_zext_icmp_thm (e e_1 e_2 : IntW 64) :
  LLVM.and (zext 8 (icmp IntPred.sgt e_2 e_1)) (zext 8 (icmp IntPred.slt e_2 e)) ⊑
    zext 8 (LLVM.and (icmp IntPred.sgt e_2 e_1) (icmp IntPred.slt e_2 e))

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

theorem 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 ite_eq_of_eq_true {cond t f : Circuit α} (h : cond.eval g = true) :
    (ite cond t f).eval g = t.eval g

theorem main5e_like_proof : main5e_like_before ⊑ main5e_like_after

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

theorem PR52261_proof : PR52261_before ⊑ PR52261_after

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

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

theorem test8_logical_thm (e : IntW 32) :
  select (icmp IntPred.ne e (const? 32 0)) (icmp IntPred.ult e (const? 32 14)) (const? 1 0) ⊑
    icmp IntPred.ult (add e (const? 32 (-1))) (const? 32 13)

theorem e_1234 :
     - 2 * t - 11 *  ~~~z - 2 * (z ||| t) + 5 *  ~~~(z &&&  ~~~t) + 2 *  ~~~(z ^^^ t) - 7 *  ~~~(z &&&  ~~~z) + 11 *  ~~~(z ||| t) + 17 *  ~~~(z |||  ~~~t) + 4 * (z &&& t) =  - 9 * (z &&&  ~~~t)

theorem test15e_proof : test15e_before ⊑ test15e_after

theorem lshrugt_03_11_proof : lshrugt_03_11_before ⊑ lshrugt_03_11_after

theorem select_1_thm.extracted_1._19 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1) (x_3 x_4 : BitVec 8) (x_5 : BitVec 1),
  ¬x_5 = 1#1 → x_2 = 1#1 → x_1 ^^^ -1#8 ^^^ -1#8 = x_1

theorem shr_umax_proof : shr_umax_before ⊑ shr_umax_after

theorem select_icmp_eq_and_1_0_or_2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 &&& 1#32 == 0#32) = 1#1 → ¬1#32 ≥ ↑32 → x = x ||

theorem ashrslt_01_05_proof : ashrslt_01_05_before ⊑ ashrslt_01_05_after

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

theorem low_mask_nsw_nuw_thm.extracted_1._1 : ∀ (x : BitVec 32), 63#32 - (x &&& 31#32) = x &&& 31#32 ^^^ 63#32

theorem or_consts_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (4#32 &&& x != 0#32) &&& ofBool (8#32 &&& x != 0#32) = ofBool (x &&& 12#32 == 12#32)

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

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

theorem test_with_5_proof : test_with_5_before ⊑ test_with_5_after

theorem test3_proof : test3_before ⊑ test3_after

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

theorem test12_logical_proof : test12_logical_before ⊑ test12_logical_after

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

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

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

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

theorem logical_or_not_proof : logical_or_not_before ⊑ logical_or_not_after

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

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

theorem logical_and_bitwise_and_icmps_comm2_proof : logical_and_bitwise_and_icmps_comm2_before ⊑ logical_and_bitwise_and_icmps_comm2_after

theorem lshr_shl_pow2_const_xor_proof : lshr_shl_pow2_const_xor_before ⊑ lshr_shl_pow2_const_xor_after

theorem shl_or_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ x + 1#8 ≥ ↑8) → ¬x ≥ ↑8 → 16#8 <<< x ||

theorem ashrsgt_03_08_proof : ashrsgt_03_08_before ⊑ ashrsgt_03_08_after

theorem test37_thm (e : IntW 32) :
  icmp IntPred.eq (trunc 8 (LLVM.or (lshr e (const? 32 31)) (const? 32 512))) (const? 8 11) ⊑ const? 1 0

theorem PR39793_bswap_u32_as_u16_trunc_proof : PR39793_bswap_u32_as_u16_trunc_before ⊑ PR39793_bswap_u32_as_u16_trunc_after

theorem t4_const_after_fold_lshr_shl_ne_proof : t4_const_after_fold_lshr_shl_ne_before ⊑ t4_const_after_fold_lshr_shl_ne_after

theorem shl_fold_or_disjoint_cnt_proof : shl_fold_or_disjoint_cnt_before ⊑ shl_fold_or_disjoint_cnt_after

theorem icmp_eq_x_invertable_y2_todo_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  x_1 = 1#1 → ofBool (7#8 == x &&& 7#8) = ofBool (x ||| BitVec.ofInt 8 (-8) == -1#8)

theorem lshrult_02_12_exact_proof : lshrult_02_12_exact_before ⊑ lshrult_02_12_exact_after

theorem lowmask_add_zext_wrong_mask_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 8),
  zeroExtend 32 x_1 + x &&& 511#32 = x + zeroExtend 32 x_1 &&& 511#32

theorem andn_or_cmp_4_logical_proof : andn_or_cmp_4_logical_before ⊑ andn_or_cmp_4_logical_after

theorem test18a_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x &&& BitVec.ofInt 8 (-2) == 0#8) = ofBool (x <ᵤ 2#8)

theorem ashrslt_02_06_proof : ashrslt_02_06_before ⊑ ashrslt_02_06_after

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

theorem test19_thm.extracted_1._1 : ∀ (x : BitVec 37),
  ¬2#37 ≥ ↑37 → ofBool (x.sshiftRight' 2#37 == 0#37) = ofBool (x <ᵤ 4#37)

theorem test_sub_nuw_nsw__nsw_is_safe_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x ||| BitVec.ofInt 32 (-2147483648) == BitVec.ofInt 32 (-2147483647)) = 1#1 →
    ¬(True ∧ (BitVec.ofInt 32 (-2147483648)).ssubOverflow (x ||| BitVec.ofInt 32 (-2147483648)) = true ∨
          True ∧ (BitVec.ofInt 32 (-2147483648)).usubOverflow (x ||| BitVec.ofInt 32 (-2147483648)) = true) →
      True ∧ (BitVec.ofInt 32 (-2147483648)).ssubOverflow (x ||| BitVec.ofInt 32 (-2147483648)) = true → False

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

theorem or_umin_thm (e : IntW 32) :
  LLVM.or (select (icmp IntPred.ult (const? 32 15) e) (const? 32 15) e) (const? 32 31) ⊑ const? 32 31

theorem mul_of_bool_no_lz_other_op_proof : mul_of_bool_no_lz_other_op_before ⊑ mul_of_bool_no_lz_other_op_after

theorem substitute_constant_and_ne_ugt_swap_logical_proof : substitute_constant_and_ne_ugt_swap_logical_before ⊑ substitute_constant_and_ne_ugt_swap_logical_after

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

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

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

theorem lshr_add_exact_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬x &&& 2#8 ≥ ↑8 →
    True ∧ (x_1 &&& BitVec.ofInt 8 (-4)) >>> (x &&& 2#8) <<< (x &&& 2#8) ≠ x_1 &&& BitVec.ofInt 8 (-4) ∨
        x &&& 2#8 ≥ ↑8 →
      False

theorem sub_const_add_const_proof : sub_const_add_const_before ⊑ sub_const_add_const_after

theorem icmp_slt_0_or_icmp_sgt_0_i64_thm (e : IntW 64) :
  LLVM.or (zext 64 (icmp IntPred.slt e (const? 64 0))) (zext 64 (icmp IntPred.sgt e (const? 64 0))) ⊑
    zext 64 (icmp IntPred.ne e (const? 64 0))

theorem lshrult_03_12_thm (e : IntW 4) : icmp IntPred.ult (lshr e (const? 4 3)) (const? 4 (-4)) ⊑ const? 1 1

theorem lshr_32_add_zext_trunc_proof : lshr_32_add_zext_trunc_before ⊑ lshr_32_add_zext_trunc_after

theorem test1_proof : test1_before ⊑ test1_after

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

theorem same_source_matching_signbits_proof : same_source_matching_signbits_before ⊑ same_source_matching_signbits_after

theorem sext_multiuse_proof : sext_multiuse_before ⊑ sext_multiuse_after

theorem icmp_sgt11_proof : icmp_sgt11_before ⊑ icmp_sgt11_after

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

theorem test21_proof : test21_before ⊑ test21_after

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

theorem test3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ¬x = 0 → ofBool (x_1 / x != 0#32) = ofBool (x ≤ᵤ x_1)

theorem e_661 :
     - 1 *  ~~~y + 5 *  ~~~(x &&& y) + 11 * x + 1 *  ~~~(x &&&  ~~~x) - 5 * y - 2 *  ~~~x + 1 * (x ||| y) - 1 *  ~~~(x ||| y) - 17 * (x &&&  ~~~y) - 6 * (x &&& y) = 2 *  ~~~(x ^^^ y)

theorem n9_proof : n9_before ⊑ n9_after

theorem select_constants_and_icmp_eq0_proof : select_constants_and_icmp_eq0_before ⊑ select_constants_and_icmp_eq0_after

theorem src_x_and_nmask_slt_proof : src_x_and_nmask_slt_before ⊑ src_x_and_nmask_slt_after

theorem shl_lshr_demand6_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(x ≥ ↑16 ∨ 4#16 ≥ ↑16) →
    ¬x ≥ ↑16 → BitVec.ofInt 16 (-32624) <<< x >>> 4#16 &&& 4094#16 = 2057#16 <<< x &&& 4094#16

lemma CNFA.autWidth_bv_language :
    (autWidth wp n).bv_recognizes { bv | wp.sat bv.w n }

theorem or_ranges_single_elem_right_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (5#8 ≤ᵤ x) &&& ofBool (x ≤ᵤ 10#8) ||

theorem ashrsgt_03_00_exact_proof : ashrsgt_03_00_exact_before ⊑ ashrsgt_03_00_exact_after

@[simp]
lemma always_true_iff [DecidableEq α] (c : Circuit α) :
    always_true c ↔ ∀ x, eval c x

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

theorem test3a_proof : test3a_before ⊑ test3a_after

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

theorem scalar_i32_lshr_and_negC_ne_proof : scalar_i32_lshr_and_negC_ne_before ⊑ scalar_i32_lshr_and_negC_ne_after

theorem fold_select_trunc_nsw_true_thm.extracted_1._1 : ∀ (x : BitVec 128),
  ¬(True ∧ signExtend 128 (truncate 1 x) ≠ x) → truncate 1 x = 1#1 → x = -1#128

theorem ne_smax4_proof : ne_smax4_before ⊑ ne_smax4_after

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

theorem different_size_sext_sext_sgt_proof : different_size_sext_sext_sgt_before ⊑ different_size_sext_sext_sgt_after

theorem xor_of_icmps_commute_thm (e : IntW 64) :
  LLVM.xor (icmp IntPred.sgt e (const? 64 0)) (icmp IntPred.eq e (const? 64 1)) ⊑
    icmp IntPred.sgt e (const? 64 1)

theorem e_2284 :
     - 1 *  ~~~(e ^^^ f) + 7 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) - 1 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 1 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 3 * (f |||  ~~~(d ||| e)) - 2 * (d &&& ( ~~~e ||| f)) + 11 * (f ^^^  ~~~(d &&& (e &&& f))) - 5 * (f ^^^ (d ||| ( ~~~e ||| f))) + 7 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 1 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 7 * ((d &&& f) ^^^ (e ||| f)) + 3 * (f ||| (d ^^^ e)) + 1 * (d ||| (e &&& f)) - 1 *  ~~~e + 1 * (d ^^^ (e ^^^ f)) - 3 * (e ^^^ (d &&& f)) - 2 * (f ^^^  ~~~(d |||  ~~~e)) + 5 *  ~~~( ~~~d ||| ( ~~~e &&& f)) + 7 * (d ^^^ ( ~~~e &&& f)) - 3 *  ~~~(d |||  ~~~f) + 4 * (d |||  ~~~e) + 2 *  ~~~(d ||| ( ~~~e &&& f)) + 7 * (f &&& (d ^^^ e)) + 7 *  ~~~(d &&& ( ~~~e ||| f)) + 1 * (e &&&  ~~~f) - 2 *  ~~~(d ^^^ ( ~~~e &&& f)) - 11 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 3 * f - 2 * ((d &&& e) ^^^ (e |||  ~~~f)) - 2 * (e &&&  ~~~(d ^^^ f)) - 1 * (e ||| (d &&& f)) - 1 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 4 * (f ^^^ (d &&&  ~~~e)) - 11 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 3 * ((d ^^^ e) ||| (d ^^^ f)) - 5 * d - 6 *  ~~~(e &&&  ~~~f) - 6 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 1 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) - 2 * ((d &&& f) ||| (e &&&  ~~~f)) + 2 *  ~~~(e ||| f) + 11 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 5 * (d ^^^ (e ||| f)) + 2 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 3 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 1 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 11 * (e ^^^ (d &&& (e ||| f))) - 6 * (f ^^^  ~~~(d &&&  ~~~e)) - 11 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 11 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 3 * ( ~~~e &&& (d ^^^ f)) - 2 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 11 * (e ^^^ ( ~~~d ||| (e ^^^ f))) + 27 *  ~~~(d ||| (e ||| f)) - 27 *  ~~~(d ||| ( ~~~e ||| f)) - 26 *  ~~~( ~~~d ||| (e ||| f)) - 10 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 17 * ( ~~~d &&& ( ~~~e &&& f)) + 4 * ( ~~~d &&& (e &&& f)) + 34 * (d &&& ( ~~~e &&& f)) - 7 * (d &&& (e &&& f)) =  - 1 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f))

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

theorem mul16_low_proof : mul16_low_before ⊑ mul16_low_after

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

theorem lshrult_03_05_exact_proof : lshrult_03_05_exact_before ⊑ lshrult_03_05_exact_after

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

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

theorem slt_zero_ne_ne_0_proof : slt_zero_ne_ne_0_before ⊑ slt_zero_ne_ne_0_after

theorem rem_euclid_pow2_false_arm_folded_thm (e : IntW 32) :
  select (icmp IntPred.sge (LLVM.srem e (const? 32 2)) (const? 32 0)) (LLVM.srem e (const? 32 2)) (const? 32 1) ⊑
    LLVM.and e (const? 32 1)

theorem uadd_sat_flipped_wrong_bounds7_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x ≤ᵤ BitVec.ofInt 32 (-12)) = 1#1 → ofBool (x <ᵤ BitVec.ofInt 32 (-11)) = 1#1 → -1#32 = x + 9#32

theorem test22_proof : test22_before ⊑ test22_after

theorem test_thm (e e_1 : IntW 16) :
  sext 64 (add (sext 32 e_1) (sext 32 e)) ⊑
    sext 64 (add (sext 32 e_1) (sext 32 e) { «nsw» := true, «nuw» := false })

theorem p_proof : p_before ⊑ p_after

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

theorem e_1080 :
     - 6 * (z |||  ~~~t) - 6 *  ~~~t - 6 * t - 1 *  ~~~(z &&&  ~~~z) - 11 * (z ^^^ t) + 18 *  ~~~(z |||  ~~~t) + 24 * (z &&&  ~~~t) + 13 * (z &&& t) =  - 13 *  ~~~(z ||| t)

theorem icmp_slt_0_or_icmp_sgt_0_i64_fail0_proof : icmp_slt_0_or_icmp_sgt_0_i64_fail0_before ⊑ icmp_slt_0_or_icmp_sgt_0_i64_fail0_after

theorem src_srem_shl_demand_eliminate_signbit_proof : src_srem_shl_demand_eliminate_signbit_before ⊑ src_srem_shl_demand_eliminate_signbit_after

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

theorem test5_thm (e e_1 e_2 : IntW 19) : sub e_2 (sub e_1 e) ⊑ add (sub e e_1) e_2

theorem uadd_sat_flipped_wrong_bounds7_thm (e : IntW 32) :
  select (icmp IntPred.ule e (const? 32 (-12))) (add e (const? 32 9)) (const? 32 (-1)) ⊑
    select (icmp IntPred.ult e (const? 32 (-11))) (add e (const? 32 9)) (const? 32 (-1))

theorem test47_proof : test47_before ⊑ test47_after

theorem foo2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (2#32 <ₛ x_1) = 1#1 → ¬(True ∧ x_1.ssubOverflow x = true) → x_1 - x = x_1 + (0#32 - x)

theorem and_umin_proof : and_umin_before ⊑ and_umin_after

theorem lshrult_02_15_thm (e : IntW 4) : icmp IntPred.ult (lshr e (const? 4 2)) (const? 4 (-1)) ⊑ const? 1 1

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

theorem slt_swap_or_not_max_commute_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.ne e_1 (const? 8 127)) (const? 1 1) (icmp IntPred.sgt e e_1) ⊑
    icmp IntPred.ne e_1 (const? 8 127)

theorem n0_proof : n0_before ⊑ n0_after

theorem or_xor_xor_normal_variant1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  x_1 &&& x ^^^ x_1 ||

theorem t3_no_extrause_thm (e e_1 : IntW 8) :
  icmp IntPred.uge (LLVM.xor e_1 (const? 8 (-1))) e ⊑
    icmp IntPred.ule e (LLVM.xor e_1 (const? 8 (-1)))

theorem ashrslt_01_09_proof : ashrslt_01_09_before ⊑ ashrslt_01_09_after

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

theorem test_shl_nuw__all_are_safe_proof : test_shl_nuw__all_are_safe_before ⊑ test_shl_nuw__all_are_safe_after

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

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

theorem bitwise_and_logical_and_masked_icmp_allones_thm.extracted_1._4 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  ofBool (x_1 &&& 8#32 == 8#32) = 1#1 →
    ¬ofBool (x_1 &&& 15#32 == 15#32) = 1#1 → x &&& ofBool (x_1 &&& 7#32 == 7#32) = 0#1

theorem trunc_shl_lshr_var_proof : trunc_shl_lshr_var_before ⊑ trunc_shl_lshr_var_after

@[simp] theorem Expr.denoteOp_eq_denoteOp_of {e₁ : Expr d Γ eff ty} {e₂ : Expr d Δ eff ty}
    {Γv : Valuation Γ} {Δv : Valuation Δ}
    (op_eq : e₁.op = e₂.op)
    (h_args : HVector.map Γv (op_eq ▸ e₁.args)
              = HVector.map Δv e₂.args)
    (h_regArgs : HEq e₁.regArgs.denote e₂.regArgs.denote) :
    e₁.denoteOp Γv = e₂.denoteOp Δv

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

theorem test11_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬zeroExtend 128 x &&& 31#128 ≥ ↑128 →
    ¬(True ∧ (x &&& 31#32).msb = true ∨
          True ∧
              (zeroExtend 64 x_1 <<< zeroExtend 64 (x &&& 31#32)).sshiftRight' (zeroExtend 64 (x &&& 31#32)) ≠
                zeroExtend 64 x_1 ∨
            True ∧
                zeroExtend 64 x_1 <<< zeroExtend 64 (x &&& 31#32) >>> zeroExtend 64 (x &&& 31#32) ≠ zeroExtend 64 x_1 ∨
              zeroExtend 64 (x &&& 31#32) ≥ ↑64) →
      truncate 64 (zeroExtend 128 x_1 <<< (zeroExtend 128 x &&& 31#128)) =
        zeroExtend 64 x_1 <<< zeroExtend 64 (x &&& 31#32)

theorem ashr_lshr_inv2_proof : ashr_lshr_inv2_before ⊑ ashr_lshr_inv2_after

theorem main4_logical_proof : main4_logical_before ⊑ main4_logical_after

theorem wide_source_matching_signbits_proof : wide_source_matching_signbits_before ⊑ wide_source_matching_signbits_after

theorem PR23309_thm (e e_1 : IntW 32) :
  trunc 1 (sub (add e_1 (const? 32 (-4))) e { «nsw» := true, «nuw» := false }) ⊑ trunc 1 (sub e_1 e)

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

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

theorem bitwise_and_logical_and_masked_icmp_allzeros_poison1_proof : bitwise_and_logical_and_masked_icmp_allzeros_poison1_before ⊑ bitwise_and_logical_and_masked_icmp_allzeros_poison1_after

theorem test_thm.extracted_1._1' : ∀ (x : BitVec 64),
  ¬(-1#32 == 0 || 32 != 1 && truncate 32 (x ||| 4294967294#64) == intMin 32 && -1#32 == -1) = true →
    (truncate 32 (x ||| 4294967294#64)).srem (-1#32) = 0#32

theorem not_lshr_const_thm (e : IntW 8) : LLVM.xor (lshr (const? 8 42) e) (const? 8 (-1)) ⊑ ashr (const? 8 (-43)) e

theorem shl_nsw_nuw_add_nsw_nuw_proof : shl_nsw_nuw_add_nsw_nuw_before ⊑ shl_nsw_nuw_add_nsw_nuw_after

theorem n9_wrong_x0_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 &&& 15#8 == 0#8) = 1#1 → x_1 + 16#8 &&& BitVec.ofInt 8 (-16) = (x_1 &&& BitVec.ofInt 8 (-16)) + 16#8

theorem and_orn_cmp_1_logical_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_1 <ₛ x_2) = 1#1 → ofBool (42#32 <ᵤ x) = 1#1 → 1#1 = ofBool (42#32 <ᵤ x)

theorem bitwise_and_bitwise_and_icmps_comm1_proof : bitwise_and_bitwise_and_icmps_comm1_before ⊑ bitwise_and_bitwise_and_icmps_comm1_after

theorem t5_ugt_slt_0_proof : t5_ugt_slt_0_before ⊑ t5_ugt_slt_0_after

theorem sge_swap_or_not_max_proof : sge_swap_or_not_max_before ⊑ sge_swap_or_not_max_after

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

@[simp]
lemma proj_accepts (M : NFA' m) (f : Fin n → Fin m) :
    (M.proj f).accepts = BitVecs.transport f '' M.accepts

theorem test2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 ^^^ x == 0#32) ^^^ ofBool (x_1 ^^^ x == 32#32) = ofBool (x_1 == x) ^^^ ofBool (x_1 ^^^ x == 32#32)

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

theorem test1_proof : test1_before ⊑ test1_after

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

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

theorem e_1625 :
     - 11 * (b ^^^  ~~~(a |||  ~~~c)) - 2 * (c &&& (a |||  ~~~b)) + 11 * (b ^^^  ~~~(a &&& (b &&& c))) + 5 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 5 * ( ~~~c |||  ~~~(a ^^^ b)) - 1 * (a ||| (b ^^^ c)) - 3 * (c ^^^  ~~~(a ||| (b &&& c))) + 2 * ((a &&& b) |||  ~~~(b ||| c)) + 11 * (b ^^^ (a |||  ~~~c)) + 7 *  ~~~(a ||| c) - 2 *  ~~~(a ^^^ (b ||| c)) + 2 * ((a &&& b) ^^^  ~~~(a ^^^ (b &&& c))) - 7 * ((a &&& b) ||| (b ^^^ c)) - 2 * (c |||  ~~~(a ||| b)) - 28 *  ~~~(a ||| (b ||| c)) + 8 *  ~~~(a ||| ( ~~~b ||| c)) - 33 *  ~~~( ~~~a ||| (b ||| c)) + 8 * ( ~~~a &&& ( ~~~b &&& c)) - 8 * ( ~~~a &&& (b &&& c)) - 7 * (a &&& ( ~~~b &&& c)) + 5 * (a &&& (b &&& c)) =  - 12 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 3 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c)))

theorem logical_and_not_cond_reuse_thm (e e_1 : IntW 1) :
  select e_1 e (LLVM.xor e_1 (const? 1 1)) ⊑ select (LLVM.xor e_1 (const? 1 1)) (const? 1 1) e

theorem same_source_matching_signbits_proof : same_source_matching_signbits_before ⊑ same_source_matching_signbits_after

@[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 e_1692 :
     - 1 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 1 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) + 11 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) - 7 * c + 1 * (c ^^^  ~~~(a &&&  ~~~b)) + 2 * (c ^^^  ~~~(a ||| b)) + 2 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) + 1 * (b &&&  ~~~(a &&& c)) - 2 * (c &&& (a ||| b)) - 1 * ((a |||  ~~~b) &&& (b ^^^ c)) + 11 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 11 * (b ^^^ (a &&& (b ||| c))) + 4 * ((a &&& c) ^^^ (a ^^^ (b &&& c))) - 1 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) - 6 *  ~~~(b ||| c) + 5 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 5 * (a ^^^ ( ~~~b &&& c)) - 1 * ((a &&& b) ^^^ (a ^^^ ( ~~~b ||| c))) - 1 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) - 1 * (a ||| (b ^^^ c)) - 23 *  ~~~(a ||| (b ||| c)) - 40 *  ~~~(a ||| ( ~~~b ||| c)) - 22 *  ~~~( ~~~a ||| (b ||| c)) - 15 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 2 * ( ~~~a &&& ( ~~~b &&& c)) - 2 * ( ~~~a &&& (b &&& c)) - 14 * (a &&& ( ~~~b &&& c)) + 15 * (a &&& (b &&& c)) = 5 * ((b &&& c) ||| (a &&& (b ||| c))) - 2 * ( ~~~a ||| ( ~~~b ||| c))

omit [Fintype S] [DecidableEq S] [LawfulBEq A] in
theorem processOneElem_grow (st : worklist.St A S) (final : S → Bool) (a : A) (sa' : S) (s : State) :
      let st' := processOneElem _ _ final s st (a, sa')
      ∃ sas, List.Perm st'.map.keys (sas ++ st.map.keys) ∧ st'.worklist.toList = st.worklist.toList ++ sas

theorem test10_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬16#32 ≥ ↑32 →
    ¬(16#32 ≥ ↑32 ∨ True ∧ (x >>> 16#32).umulOverflow 65535#32 = true) →
      zeroExtend 64 (x >>> 16#32) * 65535#64 = zeroExtend 64 (x >>> 16#32 * 65535#32)

theorem udiv_exact_eq_1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ x_1.umod x ≠ 0 ∨ x = 0) → ofBool (x_1 / x != 1#8) = ofBool (x_1 != x)

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

theorem sel_false_val_is_a_masked_lshr_of_true_val1_proof : sel_false_val_is_a_masked_lshr_of_true_val1_before ⊑ sel_false_val_is_a_masked_lshr_of_true_val1_after

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

theorem test23_logical_thm (e : IntW 32) :
  select (icmp IntPred.sgt e (const? 32 1)) (icmp IntPred.sle e (const? 32 2)) (const? 1 0) ⊑
    icmp IntPred.eq e (const? 32 2)

theorem uge_swap_or_max_proof : uge_swap_or_max_before ⊑ uge_swap_or_max_after

theorem ugt_zext_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  ofBool (x <ᵤ zeroExtend 8 x_1) = ofBool (x == 0#8) &&& x_1

theorem no_shift_xor_multiuse_cmp_and_thm.extracted_1._4 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ¬ofBool (0#32 != x_3 &&& 4096#32) = 1#1 →
    ¬ofBool (x_3 &&& 4096#32 == 0#32) = 1#1 →
      (x_2 &&& BitVec.ofInt 32 (-4097)) * x * (x_2 &&& BitVec.ofInt 32 (-4097)) =
        x_2 * x_1 * (x_2 &&& BitVec.ofInt 32 (-4097))

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

theorem bools_multi_uses2_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 → ((x_2 ^^^ 1#1) &&& x_1 ||| x_2 &&& x) &&& ((x_2 ^^^ 1#1) &&& x_1) + (x_2 &&& x) = x

theorem PR2844_logical_proof : PR2844_logical_before ⊑ PR2844_logical_after

theorem sgt_3_impliesF_eq_2_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (select (icmp IntPred.sgt e_1 (const? 8 3)) (const? 8 2) e) e_1 ⊑
    select (icmp IntPred.slt e_1 (const? 8 4)) (icmp IntPred.eq e e_1) (const? 1 0)

theorem ule_and_min_commute_proof : ule_and_min_commute_before ⊑ ule_and_min_commute_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

@[simp]
lemma reduce_spec (M : NFA α σ) : M.reduce.accepts = M.accepts

theorem test7_thm (e : IntW 32) : icmp IntPred.uge e (const? 32 0) ⊑ const? 1 1

theorem sdiv2_thm (e : IntW 32) :
  LLVM.sdiv e (const? 32 8) { «exact» := true } ⊑ ashr e (const? 32 3) { «exact» := true }

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

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

theorem mul_add_to_mul_7_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(True ∧ x.smulOverflow 32767#16 = true ∨ True ∧ x.saddOverflow (x * 32767#16) = true) → 15#16 ≥ ↑16 → False

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

theorem test13_proof : test13_before ⊑ test13_after

theorem main5f_like_proof : main5f_like_before ⊑ main5f_like_after

theorem t1_exact_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ x >>> 63#64 <<< 63#64 ≠ x ∨ 63#64 ≥ ↑64) →
    True ∧ x >>> 63#64 <<< 63#64 ≠ x ∨
        63#64 ≥ ↑64 ∨ True ∧ signExtend 64 (truncate 32 (x.sshiftRight' 63#64)) ≠ x.sshiftRight' 63#64 →
      False

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

theorem smear_sign_and_widen_proof : smear_sign_and_widen_before ⊑ smear_sign_and_widen_after

theorem e_2494 :
     - 6 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) - 2 * (f ^^^ (d ||| ( ~~~e ||| f))) - 3 * (e ^^^ ( ~~~d &&& (e ||| f))) - 6 *  ~~~(d &&&  ~~~e) + 1 *  ~~~(d ^^^ f) + 7 * (d ^^^ (e ||| f)) - 3 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 1 * (f ^^^ ( ~~~d ||| (e ||| f))) - 5 * (d &&& ( ~~~e ||| f)) - 2 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 4 *  ~~~(d ||| f) + 7 * (f &&&  ~~~(d ^^^ e)) - 7 * (e &&&  ~~~(d ^^^ f)) - 11 * ((d &&& f) ||| (e &&&  ~~~f)) + 1 * ( ~~~e |||  ~~~(d ^^^ f)) - 1 * (e &&&  ~~~(d &&& f)) - 1 * (e ^^^  ~~~(d &&& f)) - 5 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 2 * (e ^^^ (d ||| (e ||| f))) + 2 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 11 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 1 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * (d ^^^ (e &&& f)) - 5 * (f |||  ~~~(d ||| e)) + 11 * (e |||  ~~~(d |||  ~~~f)) + 2 * (e |||  ~~~(d ^^^ f)) + 4 * (f ||| (d &&&  ~~~e)) - 6 * (f ^^^ (d |||  ~~~e)) + 2 * (d ||| (e ^^^ f)) - 7 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 2 *  ~~~(d &&&  ~~~f) + 3 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 4 *  ~~~d - 3 * (f ||| (d ^^^ e)) + 11 * ((d ^^^ e) &&& (d ^^^ f)) + 2 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 7 * (f ^^^ (d ||| (e ||| f))) + 3 * (d ||| f) + 2 *  ~~~(d ||| (e &&& f)) - 2 * ((d &&& f) |||  ~~~(e ||| f)) + 1 * (e &&& f) - 7 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 2 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 4 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 2 * (e ^^^  ~~~(d ||| f)) - 1 *  ~~~(d &&& f) - 1 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 * ( ~~~d ||| (e ||| f)) + 1 *  ~~~(d |||  ~~~f) + 1 * (e ^^^  ~~~(d &&& (e &&& f))) - 2 * (d ^^^ ( ~~~e ||| f)) - 5 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 1 * ( ~~~d ||| ( ~~~e ||| f)) - 5 *  ~~~f + 5 *  ~~~(d ^^^ ( ~~~e &&& f)) + 5 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 2 * (d ^^^ ( ~~~e &&& f)) - 1 *  ~~~(e &&& f) + 3 * (e ^^^ (d &&& f)) - 1 * (d ||| (e &&& f)) - 7 * ((d &&& e) ||| (e ^^^ f)) + 5 * (e ^^^ (d ||| (e &&& f))) - 2 * (f ^^^ (d &&& (e ||| f))) - 6 * ((d ||| e) &&& (e ^^^ f)) + 7 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 7 * (f |||  ~~~(d |||  ~~~e)) - 11 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * (f ^^^  ~~~(d &&& (e ||| f))) + 1 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) - 5 * (f ^^^  ~~~(d ||| (e &&& f))) - 1 * (e ^^^ (d &&&  ~~~f)) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 11 * e + 1 *  ~~~(d ^^^ (e &&& f)) + 3 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 41 *  ~~~(d ||| (e ||| f)) + 32 *  ~~~(d ||| ( ~~~e ||| f)) + 30 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 12 * ( ~~~d &&& ( ~~~e &&& f)) - 7 * ( ~~~d &&& (e &&& f)) + 62 * (d &&& ( ~~~e &&& f)) + 35 * (d &&& (e &&& f)) =  - 1 * (f &&& (d ^^^ e))

theorem eq_smin3_proof : eq_smin3_before ⊑ eq_smin3_after

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

theorem ashr_C1_add_A_C2_i32_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(x &&& 65535#32) + 5#32 ≥ ↑32 → (6#32).sshiftRight' ((x &&& 65535#32) + 5#32) = 0#32

theorem sub_2_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1) (x_3 : BitVec 8),
  x_2 = 1#1 → x_3 - (x_1 ^^^ -1#8) ^^^ -1#8 = BitVec.ofInt 8 (-2) - (x_1 + x_3)

theorem com_Γ : com.1 = (Γn 1)

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

theorem ashr_x_by_const_cmp_sge_x_thm (e : IntW 32) :
  icmp IntPred.sge (ashr e (const? 32 5)) e ⊑ icmp IntPred.slt e (const? 32 1)

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

theorem not_signbit_zext_proof : not_signbit_zext_before ⊑ not_signbit_zext_after

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

theorem 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 e_1180 :
     - 1 * (z ^^^ t) + 5 *  ~~~(z &&& t) + 2 * z - 7 *  ~~~t + 1 * (z ||| t) - 14 *  ~~~(z |||  ~~~t) - 2 * (z &&&  ~~~t) - 12 * (z &&& t) =  - 7 * t - 2 *  ~~~(z &&&  ~~~z)

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

theorem reduce_xor_common_op_commute1_thm (e e_1 e_2 : IntW 4) :
  LLVM.or (LLVM.xor (LLVM.xor e_2 e_1) e) e_1 ⊑ LLVM.or (LLVM.xor e_2 e) e_1

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

theorem logical_and_implies_thm (e : IntW 32) :
  select (icmp IntPred.ne e (const? 32 0)) (icmp IntPred.ne e (const? 32 42)) (const? 1 0) ⊑
    LLVM.and (icmp IntPred.ne e (const? 32 0)) (icmp IntPred.ne e (const? 32 42))

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

theorem add_const_const_sub_nuw_proof : add_const_const_sub_nuw_before ⊑ add_const_const_sub_nuw_after

theorem ult_umin2_proof : ult_umin2_before ⊑ ult_umin2_after

theorem ashr_ult_9_proof : ashr_ult_9_before ⊑ ashr_ult_9_after

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

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

theorem e_358 :
    1 * (x |||  ~~~y) - 3 *  ~~~(x &&& y) - 7 *  ~~~(x ^^^ y) - 2 * y - 7 * x + 9 *  ~~~(x ||| y) + 9 * (x &&&  ~~~y) + 15 * (x &&& y) =  - 5 *  ~~~(x |||  ~~~y)

theorem test24_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.sgt e (const? 32 1)) (icmp IntPred.ne e (const? 32 2)) ⊑
    icmp IntPred.sgt e (const? 32 2)

theorem test24_proof : test24_before ⊑ test24_after

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

theorem no_masks_with_logical_or2_proof : no_masks_with_logical_or2_before ⊑ no_masks_with_logical_or2_after

theorem srem_common_dividend_defined_cond_thm (e e_1 e_2 : IntW 5) (e_3 : IntW 1) :
  select e_3 (LLVM.srem e_2 e_1) (LLVM.srem e_2 e) ⊑ LLVM.srem e_2 (select e_3 e_1 e)

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_6_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_6_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_6_after

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

theorem t0_thm (e e_1 : IntW 32) : add (add (LLVM.xor e_1 (const? 32 (-1))) e) (const? 32 1) ⊑ sub e e_1

theorem trunc_sandwich_max_sum_shift_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(20#32 ≥ ↑32 ∨ 11#12 ≥ ↑12) →
    ¬(31#32 ≥ ↑32 ∨
          True ∧ signExtend 32 (truncate 12 (x >>> 31#32)) ≠ x >>> 31#32 ∨
            True ∧ zeroExtend 32 (truncate 12 (x >>> 31#32)) ≠ x >>> 31#32) →
      truncate 12 (x >>> 20#32) >>> 11#12 = truncate 12 (x >>> 31#32)

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

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

theorem ashr_overshift_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬(15#32 ≥ ↑32 ∨ 17#32 ≥ ↑32) → 31#32 ≥ ↑32 → False

theorem or_xor_common_op_commute7_proof : or_xor_common_op_commute7_before ⊑ or_xor_common_op_commute7_after

theorem or_and_xor_not_constant_commute1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 9),
  (x_1 ^^^ x) &&& 42#9 ||

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

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

theorem e_1360 :
    7 *  ~~~(z ^^^ t) - 5 *  ~~~(z &&&  ~~~z) - 3 * (z ||| t) - 6 *  ~~~(z &&&  ~~~t) - 1 *  ~~~(z &&& t) + 11 *  ~~~t + 2 * (z ^^^ t) - 6 *  ~~~(z ||| t) + 14 *  ~~~(z |||  ~~~t) + 8 * (z &&& t) = 4 * (z &&&  ~~~t) + 1 * t

theorem shl_nuw_add_nuw_proof : shl_nuw_add_nuw_before ⊑ shl_nuw_add_nuw_after

theorem or_xor_tree_0101_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  x_2 * 42#32 ^^^ x_1 * 42#32 ||

theorem foo1_or_proof : foo1_or_before ⊑ foo1_or_after

theorem ult_swap_and_max_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x <ᵤ x_1) &&& ofBool (x == -1#8) = 0#1

theorem ne_3210_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(24#32 ≥ ↑32 ∨ 24#32 ≥ ↑32 ∨ 16#32 ≥ ↑32 ∨ 16#32 ≥ ↑32 ∨ 8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32) →
    ofBool (truncate 8 (x_1 >>> 24#32) != truncate 8 (x >>> 24#32)) ||

theorem lt_signed_to_small_signed_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x <ₛ 17#32) = ofBool (x <ₛ 17#8)

theorem or_ranges_adjacent_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (5#8 ≤ᵤ x) &&& ofBool (x ≤ᵤ 10#8) ||

theorem test22_proof : test22_before ⊑ test22_after

lemma cases_of_lt_mod_add {a b m k : ℕ} (hsum : (a + b) % m < k)  (ha : a < m) (hb : b < m) :
  ((a + b) < m ∧ (a + b) < k) ∨ ((a + b ≥ m) ∧ (a + b) < m + k)

theorem test11f_proof : test11f_before ⊑ test11f_after

theorem test_proof : test_before ⊑ test_after

theorem select_icmp_eq_and_1_0_lshr_fv_thm.extracted_1._4 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 &&& 1#8 == 0#8) = 1#1 →
    ¬2#8 ≥ ↑8 → ¬(1#8 ≥ ↑8 ∨ x_1 <<< 1#8 &&& 2#8 ≥ ↑8) → x >>> 2#8 = x >>> (x_1 <<< 1#8 &&& 2#8)

theorem p0_proof : p0_before ⊑ p0_after

theorem Lets.Γ_out_eq (l : Lets Op Γ_in Γ_out) : Γ_out = (Lets.outContext l.val Γ_in)

theorem icmp_ne_and_pow2_minus1_shl_pow2_thm (e : IntW 32) :
  zext 32 (icmp IntPred.ne (LLVM.and (shl (const? 32 2) e) (const? 32 15)) (const? 32 0)) ⊑
    zext 32 (icmp IntPred.ult e (const? 32 3))

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

theorem foo_proof : foo_before ⊑ foo_after

theorem t1_proof : t1_before ⊑ t1_after

theorem positive_samevar_shlnuw_proof : positive_samevar_shlnuw_before ⊑ positive_samevar_shlnuw_after

theorem logical_or_bitwise_or_icmps_proof : logical_or_bitwise_or_icmps_before ⊑ logical_or_bitwise_or_icmps_after

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

theorem set_to_set_decomposebittest_proof : set_to_set_decomposebittest_before ⊑ set_to_set_decomposebittest_after

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

theorem ugt_rem_nz_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.umulOverflow 5#8 = true) → ofBool (21#8 <ᵤ x * 5#8) = ofBool (4#8 <ᵤ x)

theorem test12_proof : test12_before ⊑ test12_after

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

theorem trunc_shl_lshr_var_thm (e e_1 : IntW 64) :
  trunc 32 (shl (lshr e_1 e) (const? 64 2)) ⊑ shl (trunc 32 (lshr e_1 e)) (const? 32 2)

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_4_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_swapped_4_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_swapped_4_logical_after

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

theorem test_sub_0_Y_eq_0_proof : test_sub_0_Y_eq_0_before ⊑ test_sub_0_Y_eq_0_after

theorem t10_shift_by_one_thm (e : IntW 64) (e_1 e_2 : IntW 32) :
  icmp IntPred.ne
      (LLVM.and (shl e_2 (sub (const? 32 64) e_1)) (trunc 32 (lshr e (zext 64 (add e_1 (const? 32 (-63)))))))
      (const? 32 0) ⊑
    icmp IntPred.ne
      (LLVM.and (shl e_2 (sub (const? 32 64) e_1))
        (trunc 32 (lshr e (zext 64 (add e_1 (const? 32 (-63))) { «nneg» := true }))))
      (const? 32 0)

theorem exact_lshr_eq_both_equal_proof : exact_lshr_eq_both_equal_before ⊑ exact_lshr_eq_both_equal_after

theorem hoist_ashr_ahead_of_sext_2_thm (e : IntW 8) : ashr (sext 32 e) (const? 32 8) ⊑ sext 32 (ashr e (const? 8 7))

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

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

theorem ult_and_max_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x_1 <ᵤ x) &&& ofBool (x_1 == -1#8) = 0#1

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

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

theorem xor_logic_and_or2_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 → ¬x_1 = 1#1 → x_1 ^^^ (x_1 ||| x) = x

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

theorem lshrult_03_01_exact_proof : lshrult_03_01_exact_before ⊑ lshrult_03_01_exact_after

theorem ule_and_min_commute_logical_proof : ule_and_min_commute_logical_before ⊑ ule_and_min_commute_logical_after

theorem e_1587 :
     - 5 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) - 3 * ( ~~~c ||| (a ^^^ b)) + 3 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) - 2 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 11 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) + 11 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 1 * ( ~~~a ||| ( ~~~b ||| c)) + 1 * (b &&&  ~~~(a ^^^ c)) - 2 * (a ||| (b &&& c)) + 7 * (c ||| (a &&& b)) - 8 *  ~~~(a ||| ( ~~~b ||| c)) - 5 *  ~~~( ~~~a ||| (b ||| c)) - 9 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 15 * ( ~~~a &&& ( ~~~b &&& c)) - 13 * ( ~~~a &&& (b &&& c)) - 26 * (a &&& ( ~~~b &&& c)) + 2 * (a &&& (b &&& c)) = 5 * ( ~~~c &&&  ~~~(a ^^^ b)) - 3 *  ~~~(a ||| (b ||| c))

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

theorem e_1424 :
    1 * t + 4 *  ~~~z + 4 *  ~~~t - 1 *  ~~~(z &&&  ~~~z) - 1 *  ~~~(z ^^^ t) - 7 * (z |||  ~~~t) - 1 * (z ^^^ t) - 4 *  ~~~(z |||  ~~~t) + 4 * (z &&&  ~~~t) + 8 * (z &&& t) =  - 1 *  ~~~(z &&& t)

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

theorem lshr_pow2_slt_thm (e : IntW 8) :
  icmp IntPred.slt (lshr (const? 8 (-128)) e) (const? 8 3) ⊑
    icmp IntPred.slt (lshr (const? 8 (-128)) e { «exact» := true }) (const? 8 3)

theorem test7_proof : test7_before ⊑ test7_after
</all_available_lemmas>

<local_ctx>
import Batteries.Data.Fin.Basic

import Batteries.Data.Fin.Lemmas

import Blase.SingleWidth.Defs

import Blase.AutoStructs.Constructions

import Blase.AutoStructs.Defs

import Blase.AutoStructs.FiniteStateMachine

import Mathlib.Tactic.Ring

import Mathlib.Data.Nat.Size -- TODO: remove and get rid of shiftLeft_eq_mul_pow use

import Mathlib.Data.BitVec

import Mathlib.Tactic.FinCases

open Fin.NatCast

open Mathlib

section fsm

variable {arity : Type} [FinEnum arity]

open BitStream in

end fsm

section nfas_relations

def WidthPredicate.final? (wp : WidthPredicate) (n : Nat) (s : State) : Bool :=
  decide (wp.sat s n)

def RawCNFA.autWidth (wp : WidthPredicate) (n : Nat) : RawCNFA (BitVec 0) :=
  let m := (n+2).iterate f empty
  let m := m.addInitial 0
  m.addTrans (BitVec.zero 0) (n + 1) (n + 1)
where
  f m :=
    let (s, m) := m.newState
    let m := if wp.final? n s then m.addFinal s else m
    if s > 0 then m.addTrans (BitVec.zero 0) (s-1) s else m

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

def NFA.autWidth (wp : WidthPredicate) (n : Nat) : NFA (BitVec 0) (Fin (n+2)) where
  start := { 0 }
  accept := { s | wp.final? n s }
  step s₁ _ := { s₂ | if s₁ = Fin.last (n+1) then s₁ = s₂ else s₂ = s₁ + 1 }

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

def autWidth_equiv : (CNFA.autWidth wp n).m.states ≃ (NFA'.autWidth wp n).σ where
  toFun := fun ⟨s, hs⟩ =>
    Fin.mk s (by admit /- proof elided -/
    )
  invFun q := ⟨q.val, by admit /- proof elided -/
  ⟩
  left_inv := by admit /- proof elided -/
</local_ctx>

<target_theorem>
lemma CNFA.autWidth_spec : autWidth wp n |>.Sim (NFA'.autWidth wp n) :=
</target_theorem>

