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>
BitVec in Init.Prelude
List in Init.Prelude
List.Vector in Mathlib.Data.Vector.Defs
Nat in Init.Prelude
Set in Mathlib.Data.Set.Defs
NFA in Mathlib.Computability.NFA
Language in Mathlib.Computability.Language
BitVec.cons in Init.Data.BitVec.Basic
List.Vector.ofFn in Mathlib.Data.Vector.Defs
List.Vector.replicate in Mathlib.Data.Vector.Defs
Bool in Init.Prelude
Fin in Init.Prelude
BitVec.iunfoldr in Init.Data.BitVec.Folds
List.finRange in Init.Data.List.FinRange
List.reverseRecOn in Mathlib.Data.List.Induction

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

def enc (bvs : BitVecs n) : BitVecs' n :=
  (List.finRange bvs.w).map (fun i =>
    BitVec.ofFn (fun (k : Fin n) => (bvs.bvs.get k)[i]))

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

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

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

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

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

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

def BitStream : Type := Nat → Bool

def icmp_equality_test_swift_optional_pointers_after := [llvm|
{
^0(%arg28 : i64, %arg29 : i64):
  %0 = llvm.icmp "eq" %arg28, %arg29 : i64
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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 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 bools2_logical_commute0_and1_before := [llvm|
{
^0(%arg61 : i1, %arg62 : i1, %arg63 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.xor %arg63, %0 : i1
  %3 = llvm.and %arg63, %arg61 : i1
  %4 = "llvm.select"(%2, %arg62, %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) -> ()
}
]

abbrev Expr (Γ) (ty) := _root_.Expr ExOp Γ .pure ty

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

elab "[test| "  reg:mlir_region "]" : term => do
  SSA.elabIntoCom' reg TestDialect

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

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

def add_nuw_nsw_or_and_after := [llvm|
{
^0(%arg7 : i32, %arg8 : i32):
  %0 = llvm.add %arg7, %arg8 overflow<nsw,nuw> : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

instance : DialectPrint Handshake where
  printOpName := reprStr
  printTy := reprStr
  printAttributes _ := ""
  dialectName := "handshake"
  printReturn _ := "return"

def lshr_exact_add_negative_shift_positive_before := [llvm|
{
^0(%arg56 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.add %arg56, %0 : i32
  %3 = llvm.lshr exact %1, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def State.cseArgList
 [TyDenote d.Ty] [DialectSignature d] [DialectDenote d]
  {Γstart Γ : Ctxt d.Ty} {lets : Lets d Γstart .pure Γ} (s : State d lets)
  {ts : List d.Ty}
  (as : HVector (Ctxt.Var Γ) <| ts) :
  { as' : HVector (Ctxt.Var Γ) <| ts // ∀ (V : Γstart.Valuation),
    as.map (lets.denote V).eval = as'.map (lets.denote V).eval  } :=
  match as with
  | .nil => ⟨.nil, by admit /- proof elided -/
    ⟩
  | .cons a as =>
    let ⟨a', ha'⟩ :=  s.var2var a
    let ⟨as', has'⟩ := s.cseArgList as
    ⟨.cons a' as', by admit /- proof elided -/
    ⟩

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

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

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

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

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

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

def xor_ashr_not_fail_invalid_xor_constant_before := [llvm|
{
^0(%arg15 : i8, %arg16 : i8, %arg17 : i8):
  %0 = llvm.mlir.constant(-2 : i8) : i8
  %1 = llvm.ashr %arg15, %arg17 : i8
  %2 = llvm.ashr %arg16, %arg17 : i8
  %3 = llvm.xor %2, %0 : i8
  %4 = llvm.xor %1, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

def test9_before := [llvm|
{
^0(%arg42 : i17):
  %0 = llvm.mlir.constant(16 : i17) : i17
  %1 = llvm.shl %arg42, %0 : i17
  %2 = llvm.lshr %1, %0 : i17
  "llvm.return"(%2) : (i17) -> ()
}
]

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

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

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

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

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

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

def Factor.numVars : Factor → Nat
| .var n => n+1
| .and x y | .or x y | xor x y => max (x.numVars) (y.numVars)
| .not x => x.numVars

private def tensor2dTest : MLIRTy := [mlir_type| tensor2d]

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

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

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

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

def select_t_0 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 1)] where
  lhs := [LV| {
    ^entry (%c: i1, %t: i64):
      %c0 = llvm.mlir.constant (0) : i64
      %0 = llvm.select %c, %t, %c0 : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%c: i1, %t: i64):
      %cext = llvm.sext %c: i1 to i64
      %tfreeze = llvm.freeze %t : i64
      %0 = llvm.and %cext, %tfreeze : i64
      llvm.return %0 : i64
  }]

def zext_sext_sgt_known_nonneg_after := [llvm|
{
^0(%arg24 : i8, %arg25 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.udiv %0, %arg24 : i8
  %2 = llvm.icmp "sgt" %1, %arg25 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def p1 : PeepholeRewrite ExOp [.nat, .nat] .nat :=
  { lhs := m, rhs := r, correct :=
    by
      rw [m, r]
      funext Γv
      simp_peephole [add, cst] at Γv
      intros a b
      rw [Nat.add_comm]
    }

example : rewritePeepholeAt p1 1 ex1 = (
  Com.var (cst 1)  <|
     .var (add ⟨0, by simp⟩ ⟨0, by simp⟩)  <|
     .var (add ⟨1, by simp⟩ ⟨1, by simp⟩)  <|
     .ret ⟨0, by simp⟩) :=

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

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

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

MonadLiftT in Init.Prelude

def getSimpData (simpsetName : Name) : MetaM (SimpTheorems × Simprocs) := do
  let some ext ← (getSimpExtension? simpsetName)
    | throwError m!"'{simpsetName}' simp attribute not found!"
  let theorems ← ext.getTheorems
  let some ext ← (Simp.getSimprocExtension? simpsetName)
    | throwError m!"'{simpsetName}' simp attribute not found!"
  let simprocs ← ext.getSimprocs
  return (theorems, simprocs)

def processOneElem_mot (s : State) (sa : S) (n : ℕ) (st : worklist.St A S) : Prop :=
  st.map[sa]? = some s ∧
  sa ∈ st.visited ∧
  StInv A S st.m st.map ∧
  st.sim inits final f  {(sa1, a, sa') | sa1 = sa ∧ ∃ k ≥ n, (f sa)[k]? = some (a, sa') }

@[simp_denote]
def llvm_shl_lower_riscv_64: LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := shl_llvm_64
  rhs := shl_riscv_64

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

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 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 test10_before := [llvm|
{
^0(%arg4 : i123):
  %0 = llvm.mlir.constant(127 : i123) : i123
  %1 = llvm.mlir.constant(128 : i123) : i123
  %2 = llvm.and %arg4, %0 : i123
  %3 = llvm.and %2, %1 : i123
  "llvm.return"(%3) : (i123) -> ()
}
]

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

instance {Γ : Context Ty} [DecidableEq Ty] {v ty} :
    Decidable (Γ.hasType v ty) :=

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

def select_zext_different_condition_after := [llvm|
{
^0(%arg15 : i1, %arg16 : i1):
  %0 = llvm.mlir.constant(64) : i64
  %1 = llvm.mlir.constant(1) : i64
  %2 = "llvm.select"(%arg15, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  %3 = llvm.zext %arg16 : i1 to i64
  %4 = llvm.add %2, %3 overflow<nsw,nuw> : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

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

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

BitVec.sgt in Leanwuzla.Aux

def binop_right_to_zero: List (Σ Γ, LLVMPeepholeRewriteRefine 64 Γ) :=
  [⟨_, binop_right_to_zero_mul⟩]

def RegionList.WellTyped : List (UnTyped.Region Op VarName) → List (RegionType Ty) → Prop
  | [], [] => True
  | r :: rgns, rTy :: rgnTys => Region.WellTyped r rTy ∧ RegionList.WellTyped rgns rgnTys
  | _, _ => False

instance : Lean.ToExpr RegIndex := inherit

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

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

def bools_logical_commute0_and1_before := [llvm|
{
^0(%arg105 : i1, %arg106 : i1, %arg107 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.xor %arg107, %0 : i1
  %3 = llvm.and %2, %arg105 : i1
  %4 = "llvm.select"(%arg107, %arg106, %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 ugt_and_min_logical_before := [llvm|
{
^0(%arg334 : i8, %arg335 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "ugt" %arg334, %arg335 : i8
  %3 = llvm.icmp "eq" %arg334, %0 : i8
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

def n4_after := [llvm|
{
^0(%arg8 : i16):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.mlir.constant(-1073741824 : i32) : i32
  %2 = llvm.zext %arg8 : i16 to i32
  %3 = llvm.shl %2, %0 overflow<nuw> : i32
  %4 = llvm.and %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

def test_mul__nsw_is_safe_after := [llvm|
{
^0(%arg4 : i32):
  %0 = llvm.mlir.constant(-83886080 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.or %arg4, %0 : i32
  %3 = llvm.mul %2, %1 overflow<nsw> : i32
  "llvm.return"(%3) : (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 llvm_const_lower_riscv_li_40 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_40, rhs:= liRiscv_40,
   correct := by admit /- proof elided -/

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

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

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

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

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

abbrev Index := ℕ

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

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

def test21_after := [llvm|
{
^0(%arg10 : i12):
  %0 = llvm.mlir.constant(63 : i12) : i12
  %1 = llvm.mlir.constant(62 : i12) : i12
  %2 = llvm.and %arg10, %0 : i12
  %3 = llvm.icmp "eq" %2, %1 : i12
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def t2_before := [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 %0, %arg25 : i8
  %3 = llvm.xor %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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

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

def narrow_zext_and_before := [llvm|
{
^0(%arg54 : i16, %arg55 : i32):
  %0 = llvm.zext %arg54 : i16 to i32
  %1 = llvm.and %0, %arg55 : i32
  %2 = llvm.trunc %1 : i32 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

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

def llvm_const_lower_riscv_li49 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM49, rhs:= liRiscv49,
   correct := by admit /- proof elided -/

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

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 match_unsigned_before := [llvm|
{
^0(%arg18 : i64):
  %0 = llvm.mlir.constant(299) : i64
  %1 = llvm.mlir.constant(64) : i64
  %2 = llvm.urem %arg18, %0 : i64
  %3 = llvm.udiv %arg18, %0 : i64
  %4 = llvm.urem %3, %1 : i64
  %5 = llvm.mul %4, %0 : i64
  %6 = llvm.add %2, %5 : i64
  "llvm.return"(%6) : (i64) -> ()
}
]

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

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

def sub_ult_zext_before := [llvm|
{
^0(%arg161 : i1, %arg162 : i8, %arg163 : i8):
  %0 = llvm.zext %arg161 : i1 to i8
  %1 = llvm.sub %arg162, %arg163 : i8
  %2 = llvm.icmp "ult" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

def 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 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 different_size_zext_zext_sgt_before := [llvm|
{
^0(%arg16 : i7, %arg17 : i4):
  %0 = llvm.zext %arg16 : i7 to i25
  %1 = llvm.zext %arg17 : i4 to i25
  %2 = llvm.icmp "sgt" %0, %1 : i25
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

def trunc_signed_nsw_sext_after := [llvm|
{
^0(%arg28 : i32, %arg29 : i8):
  %0 = llvm.sext %arg29 : i8 to i32
  %1 = llvm.icmp "slt" %arg28, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

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

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

def test1_after := [llvm|
{
^0(%arg3 : i333):
  %0 = llvm.mlir.constant(46 : i333) : i333
  %1 = llvm.lshr %arg3, %0 : i333
  "llvm.return"(%1) : (i333) -> ()
}
]

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 sdiv? {w : Nat} (x y : BitVec w) : IntW w :=
  if y == 0 || (w != 1 && x == (BitVec.intMin w) && y == -1) then
    .poison
  else
    .value (x.sdiv y)

structure Item where
 name : String
 tac : Syntax

@[match_pattern] abbrev or (w : Nat) (flag : DisjointFlag := {disjoint := false} ) : LLVM.Op :=
  MOp.or (.concrete w) flag

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

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

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

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

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

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

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

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

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

def positive_biggershl_shlnuwnsw_before := [llvm|
{
^0(%arg44 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(6 : i8) : i8
  %2 = llvm.lshr %arg44, %0 : i8
  %3 = llvm.shl %2, %1 overflow<nsw,nuw> : i8
  "llvm.return"(%3) : (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 andn_or_cmp_1_before := [llvm|
{
^0(%arg176 : i37, %arg177 : i37, %arg178 : i37):
  %0 = llvm.mlir.constant(42 : i37) : i37
  %1 = llvm.icmp "sgt" %arg176, %arg177 : i37
  %2 = llvm.icmp "sle" %arg176, %arg177 : i37
  %3 = llvm.icmp "ugt" %arg178, %0 : i37
  %4 = llvm.or %3, %1 : i1
  %5 = llvm.and %2, %4 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def shl_and_and_fail_before := [llvm|
{
^0(%arg170 : i8, %arg171 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.mlir.constant(5 : i8) : i8
  %2 = llvm.mlir.constant(88 : 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 lshrugt_02_03_after := [llvm|
{
^0(%arg396 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

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

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

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

def llvm_add_lower_riscv_noflags_8 : LLVMPeepholeRewriteRefine 8 [Ty.llvm (.bitvec 8), Ty.llvm (.bitvec 8)] where
  lhs:= add_llvm_no_flags_8
  rhs:= add_riscv_8

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

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

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

def lshr_32_add_zext_basic_multiuse_before := [llvm|
{
^0(%arg23 : i32, %arg24 : i32):
  %0 = llvm.mlir.constant(32) : i64
  %1 = llvm.zext %arg23 : i32 to i64
  %2 = llvm.zext %arg24 : i32 to i64
  %3 = llvm.add %1, %2 : i64
  %4 = llvm.lshr %3, %0 : i64
  %5 = llvm.or %4, %2 : i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

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

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

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

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

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

def test52_after := [llvm|
{
^0(%arg132 : i64):
  %0 = llvm.mlir.constant(7224 : i16) : i16
  %1 = llvm.mlir.constant(-32574 : i16) : i16
  %2 = llvm.trunc %arg132 : i64 to i16
  %3 = llvm.and %2, %0 : i16
  %4 = llvm.or disjoint %3, %1 : i16
  %5 = llvm.zext %4 : i16 to i32
  "llvm.return"(%5) : (i32) -> ()
}
]

instance : ToString Ty where
  toString
  | Ty.bv => "!riscv.reg"

def or_simplify_ule_fail_before := [llvm|
{
^0(%arg13 : i8, %arg14 : i8):
  %0 = llvm.mlir.constant(64 : i8) : i8
  %1 = llvm.mlir.constant(127 : i8) : i8
  %2 = llvm.or %arg13, %0 : i8
  %3 = llvm.and %arg14, %1 : i8
  %4 = llvm.or %2, %3 : i8
  %5 = llvm.icmp "ule" %4, %3 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

RV64.divu in RISCV.Instructions

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

def test_nuw_nsw_and_unsigned_pred_after := [llvm|
{
^0(%arg55 : i64):
  %0 = llvm.mlir.constant(6) : i64
  %1 = llvm.icmp "ugt" %arg55, %0 : i64
  "llvm.return"(%1) : (i1) -> ()
}
]

RV64.sra in RISCV.Instructions

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

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

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

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

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

def ugt_sext_before := [llvm|
{
^0(%arg130 : i1, %arg131 : i8):
  %0 = llvm.sext %arg130 : i1 to i8
  %1 = llvm.icmp "ugt" %0, %arg131 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

instLEBitVec in Init.Prelude

def test9_after := [llvm|
{
^0(%arg5 : i1005):
  "llvm.return"(%arg5) : (i1005) -> ()
}
]

Lean.Parser.sepBy in Lean.Parser.Basic

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

def verifyAIG {α : Type} [DecidableEq α] [Hashable α] (x : Entrypoint α) (cert : String) : Bool :=
  let y := (Entrypoint.relabelNat x)
  let z := AIG.toCNF y
  Std.Tactic.BVDecide.Reflect.verifyCert z cert

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

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

def p_commutative0_after := [llvm|
{
^0(%arg32 : i32, %arg33 : i32, %arg34 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg34, %arg32 : i32
  %2 = llvm.xor %arg34, %0 : i32
  %3 = llvm.and %arg33, %2 : i32
  %4 = llvm.or disjoint %1, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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 t0_basic_before := [llvm|
{
^0(%arg29 : i8, %arg30 : i8):
  %0 = llvm.add %arg29, %arg30 : i8
  %1 = llvm.icmp "ult" %0, %arg30 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

private def isFile (p: System.FilePath) : IO Bool := do
  return (← p.metadata).type == IO.FS.FileType.file

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

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

def trunc_ashr_trunc_outofrange_after := [llvm|
{
^0(%arg2 : i64):
  %0 = llvm.mlir.constant(25 : i32) : i32
  %1 = llvm.trunc %arg2 : i64 to i32
  %2 = llvm.ashr %1, %0 : i32
  %3 = llvm.trunc %2 overflow<nsw> : i32 to i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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 positive_with_icmp_after := [llvm|
{
^0(%arg58 : i32):
  %0 = llvm.mlir.constant(128 : i32) : i32
  %1 = llvm.icmp "ult" %arg58, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

def 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 wellformed (fileName : String ) : IO UInt32 := do
    let icom? ← parseComFromFile fileName
    match icom? with
    | none => return 1
    | some (Sigma.mk _Γ ⟨_eff, ⟨_retTy, c⟩⟩) => do
      IO.println s!"{Com.printModule c}"
      return 0

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

def ashr_16_to_64_add_zext_basic_before := [llvm|
{
^0(%arg7 : i16, %arg8 : i16):
  %0 = llvm.mlir.constant(16) : i64
  %1 = llvm.zext %arg7 : i16 to i64
  %2 = llvm.zext %arg8 : i16 to i64
  %3 = llvm.add %1, %2 : i64
  %4 = llvm.ashr %3, %0 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

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

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

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

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

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

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

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

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

def apply_patterns {Γl : List DCPlus.Ty} (fuel : Nat)
  (prog : Com DCPlus (Ctxt.ofList Γl) .pure ([.tokenstream])) :=
   multiRewritePeephole fuel rewrite_patterns prog

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

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

def ne_irregular_bit_widths_after := [llvm|
{
^0(%arg62 : i31, %arg63 : i31):
  %0 = llvm.mlir.constant(7 : i31) : i31
  %1 = llvm.lshr %arg62, %0 : i31
  %2 = llvm.trunc %1 : i31 to i11
  %3 = llvm.lshr %arg63, %0 : i31
  %4 = llvm.trunc %3 : i31 to i11
  %5 = llvm.icmp "ne" %2, %4 : i11
  "llvm.return"(%5) : (i1) -> ()
}
]

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

repr in Init.Data.Repr

def foo_before := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(223 : i32) : i32
  %1 = llvm.mlir.constant(29 : i32) : i32
  %2 = llvm.mlir.constant(-784568073 : i32) : i32
  %3 = llvm.mlir.constant(1874836915 : i32) : i32
  %4 = llvm.mlir.constant(221 : i32) : i32
  %5 = llvm.mlir.constant(1 : i32) : i32
  %6 = llvm.mlir.constant(1533579450 : i32) : i32
  %7 = llvm.mlir.constant(-2147483648 : i32) : i32
  %8 = llvm.mlir.constant(749011377 : i32) : i32
  %9 = llvm.and %arg0, %0 : i32
  %10 = llvm.xor %9, %1 : i32
  %11 = llvm.add %10, %2 overflow<nuw> : i32
  %12 = llvm.or %10, %3 : i32
  %13 = llvm.and %10, %4 : i32
  %14 = llvm.xor %13, %3 : i32
  %15 = llvm.xor %12, %14 : i32
  %16 = llvm.shl %15, %5 overflow<nsw,nuw> : i32
  %17 = llvm.sub %11, %16 : i32
  %18 = llvm.add %17, %6 overflow<nsw> : i32
  %19 = llvm.or %18, %7 : i32
  %20 = llvm.xor %19, %8 : i32
  "llvm.return"(%20) : (i32) -> ()
}
]

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

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

def or_eq_notY_eq_0_before := [llvm|
{
^0(%arg45 : i8, %arg46 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.xor %arg46, %0 : i8
  %2 = llvm.or %arg45, %1 : i8
  %3 = llvm.icmp "eq" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def and_or3_before := [llvm|
{
^0(%arg168 : i1, %arg169 : i1, %arg170 : i32, %arg171 : i32):
  %0 = llvm.icmp "eq" %arg170, %arg171 : i32
  %1 = llvm.and %arg169, %0 : i1
  %2 = "llvm.select"(%1, %arg168, %arg169) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

def test3_after := [llvm|
{
^0(%arg24 : i97):
  "llvm.return"(%arg24) : (i97) -> ()
}
]

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

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

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

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

def ne_21_logical_before := [llvm|
{
^0(%arg52 : i32, %arg53 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.lshr %arg52, %0 : i32
  %4 = llvm.trunc %3 : i32 to i8
  %5 = llvm.lshr %arg52, %1 : i32
  %6 = llvm.trunc %5 : i32 to i8
  %7 = llvm.lshr %arg53, %0 : i32
  %8 = llvm.trunc %7 : i32 to i8
  %9 = llvm.lshr %arg53, %1 : i32
  %10 = llvm.trunc %9 : i32 to i8
  %11 = llvm.icmp "ne" %4, %8 : i8
  %12 = llvm.icmp "ne" %6, %10 : i8
  %13 = "llvm.select"(%12, %2, %11) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%13) : (i1) -> ()
}
]

def hoist_logic_op_with_same_opcode_hands_32 : List (Σ Γ, LLVMPeepholeRewriteRefine 32 Γ) :=
  [⟨_, AndTruncTrunc⟩,
  ⟨_, OrTruncTrunc⟩,
  ⟨_, XorTruncTrunc⟩]

def trunc_sel_larger_zext_after := [llvm|
{
^0(%arg73 : i32, %arg74 : i1):
  %0 = llvm.mlir.constant(65535 : i32) : i32
  %1 = llvm.mlir.constant(42) : i64
  %2 = llvm.and %arg73, %0 : i32
  %3 = llvm.zext nneg %2 : i32 to i64
  %4 = "llvm.select"(%arg74, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%4) : (i64) -> ()
}
]

@[simp_denote]
def select_riscv_64 := [LV| {
  ^entry (%cond : i1, %arg0: i64, %arg1: i64):
    %0 = "builtin.unrealized_conversion_cast" (%arg0) : (i64) -> (!i64)
    %1 = "builtin.unrealized_conversion_cast" (%arg1) : (i64) -> (!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) -> (i64)
    llvm.return %7 : i64
  }]

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

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

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

def src_is_mask_shl_lshr_before := [llvm|
{
^0(%arg103 : i8, %arg104 : i8, %arg105 : i1):
  %0 = llvm.mlir.constant(123 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.xor %arg103, %0 : i8
  %4 = llvm.shl %1, %arg104 : i8
  %5 = llvm.lshr %4, %arg104 : i8
  %6 = llvm.xor %5, %1 : i8
  %7 = llvm.and %3, %6 : i8
  %8 = llvm.icmp "ne" %2, %7 : i8
  "llvm.return"(%8) : (i1) -> ()
}
]

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

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

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

instance : ToFormat Sexpr where
  format := Sexpr.toFormat

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

Polynomial.coeffs in Mathlib.Algebra.Polynomial.Basic

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

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

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

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

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

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

def t8_twoshifts3_after := [llvm|
{
^0(%arg24 : i32, %arg25 : i32, %arg26 : i32, %arg27 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %arg24, %arg25 : i32
  %3 = llvm.shl %0, %arg27 overflow<nuw> : i32
  %4 = llvm.and %3, %2 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

Lean.Core.Context in Lean.CoreM

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

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

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

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

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

def add_nuw_nsw_or_and_after := [llvm|
{
^0(%arg7 : i32, %arg8 : i32):
  %0 = llvm.add %arg7, %arg8 overflow<nsw,nuw> : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

def test9_after := [llvm|
{
^0(%arg72 : i32):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.trunc %arg72 : i32 to i8
  %2 = llvm.and %1, %0 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

    |

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

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

def negMax' (a : BitVec o) : BitVec o :=
    (-a) 

def pv_after := [llvm|
{
^0(%arg14 : i8, %arg15 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.lshr %0, %arg15 : i8
  %2 = llvm.icmp "ule" %arg14, %1 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def q : Nat := 42

def test_sext_before := [llvm|
{
^0(%arg30 : i32, %arg31 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.icmp "eq" %arg30, %0 : i32
  %3 = llvm.sext %2 : i1 to i32
  %4 = llvm.add %arg31, %3 : i32
  %5 = llvm.xor %4, %1 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def Hom.consMap {Γ Γ' : Ctxt Ty} (f : Hom Γ Γ') {t : Ty} :
    (Γ.cons t).Hom (Γ'.cons t) :=

def icmp? {w : Nat} (c : IntPred) (x y : BitVec w) : IntW 1 :=
  .value <| .ofBool (icmp' c x y) 

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

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

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

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

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

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

private def attrVal6Symbol : AttrVal := [mlir_attr_val| @func_foo ]

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

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

def t9_c0_c2_after := [llvm|
{
^0(%arg13 : i8, %arg14 : i8):
  %0 = llvm.mlir.constant(18 : i8) : i8
  %1 = llvm.sub %0, %arg13 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

macro "[balanced_brackets|" xs:balancedBrackets "]" : term => do
  match xs.raw[0] with
  | .atom _ val => return (Lean.quote val: TSyntax `str)
  | _  => Macro.throwErrorAt xs "expected balanced bracts to have atom"

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

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

def test59_after := [llvm|
{
^0(%arg122 : i8, %arg123 : i8):
  %0 = llvm.mlir.constant(4 : i32) : i32
  %1 = llvm.mlir.constant(48 : i32) : i32
  %2 = llvm.mlir.constant(4 : i8) : i8
  %3 = llvm.zext %arg122 : i8 to i32
  %4 = llvm.shl %3, %0 overflow<nsw,nuw> : i32
  %5 = llvm.and %4, %1 : i32
  %6 = llvm.lshr %arg123, %2 : i8
  %7 = llvm.zext nneg %6 : i8 to i32
  %8 = llvm.or disjoint %5, %7 : i32
  %9 = llvm.zext nneg %8 : i32 to i64
  "llvm.return"(%9) : (i64) -> ()
}
]

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

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

def or_xor_and_commuted1_before := [llvm|
{
^0(%arg50 : i32, %arg51 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mul %arg51, %arg51 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.xor %2, %arg50 : i32
  %4 = llvm.or %1, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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 autOfTermBinop (op : TermBinop) (m₁ : CNFA (n + 1)) (m₂ : CNFA (m + 1)) : CNFA ((n ⊔ m) + 1 ) :=
  let mop : CNFA 3 := op.termGadget
  let f₁ := liftMaxSuccSucc1 n m
  let m1' := m₁.lift f₁
  let f₂ := liftMaxSuccSucc2 n m
  let m2' := m₂.lift f₂
  let mop := mop.lift $ liftLast3 (max (FinEnum.card (Fin n)) (FinEnum.card (Fin m)))
  let m := CNFA.inter m1' m2' |> CNFA.inter mop
  let mfinal := m.proj (liftOp _)
  mfinal.minimize

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

structure Pointer where
  id : BlockId
   
  offset : BitVec 64
  deriving Inhabited

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

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

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

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

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

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

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

def or_and_xor_not_constant_commute1_after := [llvm|
{
^0(%arg166 : i9, %arg167 : i9):
  %0 = llvm.mlir.constant(42 : i9) : i9
  %1 = llvm.and %arg166, %0 : i9
  %2 = llvm.xor %1, %arg167 : i9
  "llvm.return"(%2) : (i9) -> ()
}
]

def shl_nsw_ule_Csle0_fail_missing_flag_before := [llvm|
{
^0(%arg12 : i8, %arg13 : i8):
  %0 = llvm.mlir.constant(-19 : i8) : i8
  %1 = llvm.shl %arg12, %arg13 overflow<nsw> : i8
  %2 = llvm.icmp "ule" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

def test5_after := [llvm|
{
^0(%arg95 : i32, %arg96 : i8):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.zext nneg %arg96 : i8 to i32
  %3 = llvm.shl %0, %2 overflow<nuw> : i32
  %4 = llvm.add %3, %1 : i32
  %5 = llvm.and %arg95, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

@[match_pattern] def sub (w : Width φ)
  (NoWrapFlags: NoWrapFlags := {nsw := false , nuw := false}) : MOp φ
    := .binary w (.sub NoWrapFlags )

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

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

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

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

def select (x y : TokenStream) (c : ValueStream (BitVec 1)): TokenStream :=
  Stream.corec (β := TokenStream × TokenStream × Stream (BitVec 1)) (x, y, c)
  fun ⟨x, y, c⟩ =>
    match (c 0) with
    | none => (none, x, y, c.tail) 
    | some 1#1 =>
      match (x 0) with
      | none => (none, x.tail, y, c) 
      | some _ => (some (), x.tail, y, c.tail) 
    | some 0#1 =>
      match (y 0) with
      | none => (none, x, y.tail, c) 
      | some _ => (some (), x, y.tail, c.tail) 

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

instance : DecidableNFA (NFA'.autMsbSet).M :=

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

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

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

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

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

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

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

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

def and_xor_or3_after := [llvm|
{
^0(%arg667 : i64, %arg668 : i64, %arg669 : i64):
  %0 = llvm.mlir.constant(42) : i64
  %1 = llvm.udiv %0, %arg668 : i64
  %2 = llvm.udiv %0, %arg669 : i64
  %3 = llvm.or %2, %1 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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

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

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

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

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

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

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

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

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

def generalizeCommand
      (H : HydrableParseAndGeneralize parsedExpr genLogicalExpr genExpr)
      (cfg : MedusaSynthGeneralizeConfig)
      (stx : Syntax) : CommandElabM Unit := do
  withoutModifyingEnv <| runTermElabM fun _ =>
    Term.withDeclName `_reduceWidth do
      let hExpr ← Term.elabTerm stx none
      trace[Generalize] m! "hexpr: {hExpr}"
      let res ← parseAndGeneralize (H := H) cfg hExpr GeneralizeContext.Command
      logInfo m! "{res}"

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 test_shl_nsw__none_are_safe_after := [llvm|
{
^0(%arg66 : i32, %arg67 : i64):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(-8 : i32) : i32
  %2 = llvm.shl %arg66, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.zext nneg %3 : i32 to i64
  %5 = llvm.ashr %arg67, %4 : i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

Function.LeftInverse in Init.Data.Function

def evalBV {w} (x : ar → BitVec w) : BitVec w :=
  BitVec.ofFn fun k => p.eval (fun ar => .ofBitVecSext (x ar)) k

HMul in Init.Prelude

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

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

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

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

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

Subtype in Init.Prelude

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

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

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

def main4f_like_logical_after := [llvm|
{
^0(%arg115 : i32, %arg116 : i32, %arg117 : i32):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.and %arg115, %arg116 : i32
  %2 = llvm.icmp "eq" %1, %arg116 : i32
  %3 = llvm.and %arg115, %arg117 : i32
  %4 = llvm.icmp "eq" %3, %arg117 : i32
  %5 = "llvm.select"(%2, %4, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %6 = llvm.zext %5 : i1 to i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

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

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

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

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

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

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

def fsmWidthEq (a b : FSM α) : FSM α :=
  composeUnaryAux FSM.scanAnd (composeBinaryAux' FSM.nxor a b)

@[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 lshr_by_const_cmp_sge_value_before := [llvm|
{
^0(%arg7 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.lshr %arg7, %0 : i32
  %2 = llvm.icmp "sge" %1, %arg7 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

NatCast.natCast in Init.Data.Cast

def Com.letPure (e : Expr d Γ .pure t) (body : Com d (e.outContext) eff u) : Com d Γ eff u :=
  body.var (e.castPureToEff eff)

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

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

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

def sendReadySignal (_ : Unit) (tok : Unit) : Unit := tok

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

EIO.toIO' in Init.System.IO

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

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

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

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

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

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

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

def lshrugt_03_06_exact_before := [llvm|
{
^0(%arg183 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(6 : i4) : i4
  %2 = llvm.lshr exact %arg183, %0 : i4
  %3 = llvm.icmp "ugt" %2, %1 : i4
  "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 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 in_constant_14_vary_before := [llvm|
{
^0(%arg22 : i4, %arg23 : i4):
  %0 = llvm.mlir.constant(-2 : i4) : i4
  %1 = llvm.mlir.constant(1 : i4) : i4
  %2 = llvm.xor %arg22, %0 : i4
  %3 = llvm.and %2, %1 : i4
  %4 = llvm.xor %3, %arg22 : i4
  "llvm.return"(%4) : (i4) -> ()
}
]

RV64.slliw in RISCV.Instructions

def llvm_udiv_lower_riscv_no_flag_32: LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] :=
  {lhs := udiv_llvm_no_exact_32, rhs := udiv_riscv_32, correct :=
  by admit /- proof elided -/

RV64.srai in RISCV.Instructions

def t1_after := [llvm|
{
^0(%arg17 : i16):
  %0 = llvm.mlir.constant(15 : i16) : i16
  %1 = llvm.mlir.constant(-1 : i16) : i16
  %2 = llvm.sub %0, %arg17 : i16
  %3 = llvm.lshr %1, %2 : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

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

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

instance : DialectPrint TestDialect where
  printOpName
    | .noop   => "noop"
    | .unPair => "unpair"
    | .mkPair => "pair"
  printAttributes _ := ""
  printTy
    | .int => "!int"
    | .int2 => "!int2"
  dialectName := "test"
  printReturn _ := "return"
  printFunc _ := "^entry"

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

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

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

def two_inst_concrete_macro_proof :
    two_inst_concrete_macro ⊑ two_inst_concrete_macro :=

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

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

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

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

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

def Expr.changeEffect {eff₁ eff₂ : EffectKind} (h : eff₁ ≤ eff₂) :
    Expr d Γ eff₁ t → Expr d Γ eff₂ t
  | Expr.mk op ty_eq eff_le args regArgs =>
    have heff : DialectSignature.effectKind op ≤ eff₂ := by admit /- proof elided -/

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

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

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

def logical_and_cond_reuse_before := [llvm|
{
^0(%arg258 : i1, %arg259 : i1):
  %0 = "llvm.select"(%arg258, %arg259, %arg258) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

def srem8_ashr_mask_before := [llvm|
{
^0(%arg5 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(31 : i32) : i32
  %2 = llvm.mlir.constant(2 : i32) : i32
  %3 = llvm.srem %arg5, %0 : i32
  %4 = llvm.ashr %3, %1 : i32
  %5 = llvm.and %4, %2 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

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

def exact_lshr_eq_both_equal_after := [llvm|
{
^0(%arg166 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "eq" %arg166, %0 : i8
  "llvm.return"(%1) : (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 lshrult_03_04_exact_after := [llvm|
{
^0(%arg113 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def test_sext_after := [llvm|
{
^0(%arg30 : i32, %arg31 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "ne" %arg30, %0 : i32
  %2 = llvm.sext %1 : i1 to i32
  %3 = llvm.sub %2, %arg31 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

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

def 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 bad_shl2_sub_i32_after := [llvm|
{
^0(%arg9 : i32):
  %0 = llvm.mlir.constant(-31 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.add %arg9, %0 : i32
  %3 = llvm.shl %1, %2 overflow<nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

def ashrslt_02_00_exact_before := [llvm|
{
^0(%arg37 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.mlir.constant(0 : i4) : i4
  %2 = llvm.ashr exact %arg37, %0 : i4
  %3 = llvm.icmp "slt" %2, %1 : i4
  "llvm.return"(%3) : (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 n0_before := [llvm|
{
^0(%arg9 : i8, %arg10 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.shl %0, %arg10 : i8
  %3 = llvm.xor %2, %1 : i8
  %4 = llvm.icmp "ult" %3, %arg9 : i8
  "llvm.return"(%4) : (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}

instance : DecidableEq (NFA'.autMsbSet).σ :=

Int.cast in Init.Data.Int.Basic

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

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

def select_icmp_ne_0_and_4096_or_32_after := [llvm|
{
^0(%arg209 : i32, %arg210 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(32 : i32) : i32
  %2 = llvm.lshr %arg209, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.or %arg210, %4 : i32
  "llvm.return"(%5) : (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 -/

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

def cadicalTimeoutSec : Nat := 1000

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

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

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

instance : DialectPrint Ex where
  printOpName
  | .add    => "add"
  | .beq    => "beq"
  | .cst _  => "cst"
  printAttributes
  | .cst v => s!"\{value = {v}}"
  | _ => ""
  printTy
  | .nat => "nat"
  | .bool => "bool"
  dialectName := "ex"
  printReturn _ := "return"
  printFunc _ := "^entry"

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

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

def test_shl_nsw__nsw_is_safe_before := [llvm|
{
^0(%arg73 : i32):
  %0 = llvm.mlir.constant(-83886080 : i32) : i32
  %1 = llvm.mlir.constant(-83886079 : i32) : i32
  %2 = llvm.mlir.constant(2 : i32) : i32
  %3 = llvm.mlir.constant(-335544316 : i32) : i32
  %4 = llvm.or %arg73, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.shl %4, %2 overflow<nsw> : i32
  %7 = "llvm.select"(%5, %3, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %8 = llvm.mul %7, %4 : i32
  %9 = llvm.mul %8, %6 : i32
  "llvm.return"(%9) : (i32) -> ()
}
]

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

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

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

def llvm_const_lower_riscv_li12 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM12, rhs:= liRiscv12,
   correct := by admit /- proof elided -/

def shl_xor_lshr_comm_after := [llvm|
{
^0(%arg97 : i32, %arg98 : i32, %arg99 : i32):
  %0 = llvm.lshr %arg99, %arg98 : i32
  %1 = llvm.xor %0, %arg97 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

instance : Max EffectKind where
  max := sup

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

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

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

partial def reflectFactor (e : Expr) : M Factor := do
  match_expr e with
  | HAnd.hAnd _bv _bv _bv _inst a b =>
     return Factor.and (← reflectFactor a) (← reflectFactor b)
  | HOr.hOr _bv _bv _bv _inst a b =>
     return Factor.or (← reflectFactor a) (← reflectFactor b)
  | HXor.hXor _bv _bv _bv _inst a b =>
     return Factor.xor (← reflectFactor a) (← reflectFactor b)
  | Complement.complement _bv _inst a =>
     return Factor.not (← reflectFactor a)
  | _ =>
    let s ← get
    match s.e2ix[e]? with
    | .some ix => return Factor.var ix
    | .none => do
       let ix := s.e2ix.size
       set { s with e2ix := s.e2ix.insert e ix }
       return .var ix

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

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

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

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

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

def runM (x : M α) : MetaM (α × State) := x.run {}

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

def Expr.KInductionCircuits.mkN (fsm : Expr) (n : Expr) : MetaM Expr :=
  mkAppM ``ReflectVerif.BvDecide.KInductionCircuits.mkN #[fsm, n]

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

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

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

def foo_after := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(223 : i32) : i32
  %1 = llvm.mlir.constant(29 : i32) : i32
  %2 = llvm.mlir.constant(1362915575 : i32) : i32
  %3 = llvm.mlir.constant(1 : i32) : i32
  %4 = llvm.mlir.constant(290 : i32) : i32
  %5 = llvm.mlir.constant(1533579450 : i32) : i32
  %6 = llvm.mlir.constant(749011377 : i32) : i32
  %7 = llvm.and %arg0, %0 : i32
  %8 = llvm.xor %7, %1 : i32
  %9 = llvm.add %8, %2 overflow<nsw,nuw> : i32
  %10 = llvm.shl %8, %3 overflow<nsw,nuw> : i32
  %11 = llvm.and %10, %4 : i32
  %12 = llvm.sub %9, %11 overflow<nsw,nuw> : i32
  %13 = llvm.add %12, %5 overflow<nuw> : i32
  %14 = llvm.xor %13, %6 : i32
  "llvm.return"(%14) : (i32) -> ()
}
]

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 test8_before := [llvm|
{
^0(%arg94 : i32, %arg95 : i32):
  %0 = llvm.mlir.constant(32 : i128) : i128
  %1 = llvm.zext %arg94 : i32 to i128
  %2 = llvm.zext %arg95 : i32 to i128
  %3 = llvm.shl %2, %0 : i128
  %4 = llvm.or %3, %1 : i128
  %5 = llvm.trunc %4 : i128 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

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

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

def not_lshr_before := [llvm|
{
^0(%arg82 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.mlir.constant(7 : i8) : i8
  %2 = llvm.lshr %arg82, %0 : i8
  %3 = llvm.xor %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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

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

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

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

def uge_swap_or_not_max_commute_before := [llvm|
{
^0(%arg292 : i8, %arg293 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.icmp "ule" %arg293, %arg292 : i8
  %2 = llvm.icmp "ne" %arg292, %0 : i8
  %3 = llvm.or %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def 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 multiuse_lshr_lshr_after := [llvm|
{
^0(%arg39 : i9):
  %0 = llvm.mlir.constant(2 : i9) : i9
  %1 = llvm.mlir.constant(5 : i9) : i9
  %2 = llvm.lshr %arg39, %0 : i9
  %3 = llvm.lshr %arg39, %1 : i9
  %4 = llvm.mul %2, %3 : i9
  "llvm.return"(%4) : (i9) -> ()
}
]

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

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

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

@[match_pattern] abbrev mul (w : Nat) (flags: NoWrapFlags := {}) : LLVM.Op := MOp.mul (.concrete w) flags

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

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

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

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

def n9_after := [llvm|
{
^0(%arg1 : i64):
  %0 = llvm.mlir.constant(62) : i64
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.lshr %arg1, %0 : i64
  %3 = llvm.trunc %2 overflow<nsw,nuw> : i64 to i32
  %4 = llvm.sub %1, %3 overflow<nsw> : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

inductive Lets
  | mk (lets : List Expr)

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

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

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

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

def shl_and_xor_before := [llvm|
{
^0(%arg158 : i8, %arg159 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(20 : i8) : i8
  %2 = llvm.shl %arg158, %0 : i8
  %3 = llvm.shl %arg159, %0 : i8
  %4 = llvm.and %2, %1 : i8
  %5 = llvm.xor %3, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

def one_side_fold_slt_before := [llvm|
{
^0(%arg33 : i32, %arg34 : i32, %arg35 : i32, %arg36 : i1):
  %0 = "llvm.select"(%arg36, %arg33, %arg35) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %1 = "llvm.select"(%arg36, %arg34, %arg35) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %2 = llvm.icmp "slt" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

HAppend.hAppend in Init.Prelude

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

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

@[simp_denote]
def or_llvm_i16:= [LV| {
    ^entry (%a: i16,%b: i16 ):
    %0 = llvm.or %a, %b : i16
    llvm.return %0 :i16
  }]

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

structure DialectMorphism (d d' : Dialect) [DialectSignature d] [DialectSignature d'] where
  mapOp : d.Op → d'.Op
  mapTy : d.Ty → d'.Ty
  preserves_signature : ∀ op, signature (mapOp op) = mapTy <$> (signature op)

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

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

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

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

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

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

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

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

def 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 uaddo_wrong_pred2_before := [llvm|
{
^0(%arg4 : i32, %arg5 : i32, %arg6 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg5, %0 : i32
  %2 = llvm.add %arg4, %arg5 : i32
  %3 = llvm.icmp "uge" %arg4, %1 : i32
  %4 = "llvm.select"(%3, %arg6, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

def shl_nuw_add_nsw_nuw_after := [llvm|
{
^0(%arg15 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  "llvm.return"(%0) : (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 test8_before := [llvm|
{
^0(%arg15 : i27):
  %0 = llvm.mlir.constant(9 : i27) : i27
  %1 = llvm.mul %0, %arg15 : i27
  %2 = llvm.sub %1, %arg15 : i27
  "llvm.return"(%2) : (i27) -> ()
}
]

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

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

def positive_biggerlshr_shlnuwnsw_lshrexact_after := [llvm|
{
^0(%arg25 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.lshr exact %arg25, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

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

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

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

RV64.sh3adduw in RISCV.Instructions

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

@[simp]
abbrev RV64 : Dialect where
  Op := Op
  Ty := Ty

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

def or_not_and_wrong_c_before := [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 %2, %arg490 : i32
  %4 = llvm.or %arg488, %arg491 : i32
  %5 = llvm.xor %4, %0 : i32
  %6 = llvm.and %5, %arg489 : i32
  %7 = llvm.or %3, %6 : i32
  "llvm.return"(%7) : (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 test3_logical_before := [llvm|
{
^0(%arg306 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = "llvm.select"(%arg306, %0, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

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

def not_signbit_trunc_before := [llvm|
{
^0(%arg16 : i16):
  %0 = llvm.mlir.constant(-1 : i16) : i16
  %1 = llvm.mlir.constant(15 : i16) : i16
  %2 = llvm.xor %arg16, %0 : i16
  %3 = llvm.lshr %2, %1 : i16
  %4 = llvm.trunc %3 : i16 to i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

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

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

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

BitVec.add in Init.Data.BitVec.BasicAux

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

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

def mulo_by_2_unsigned : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (2) : i64
      %0 = llvm.mul %x, %c overflow<nuw> : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %0 = llvm.add %x, %x overflow<nuw> : i64
      llvm.return %0 : i64
  }]

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

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

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

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 sltu_i32_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := sltu_llvm_i32
  rhs := sltu_riscv_i32

def positive_samevar_before := [llvm|
{
^0(%arg62 : i8, %arg63 : i8):
  %0 = llvm.lshr %arg62, %arg63 : i8
  %1 = llvm.shl %0, %arg63 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

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

Prod in Init.Prelude

abbrev HSxComb : Dialect where
  Op := Op
  Ty :=  MLIR2Handshake.Handshake.Ty

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

def fold_icmp_shl_nuw_c2_precondition2_before := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(127 : i32) : i32
  %1 = llvm.mlir.constant(63 : i32) : i32
  %2 = llvm.shl %0, %arg1 overflow<nuw> : i32
  %3 = llvm.icmp "ult" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def test13_before := [llvm|
{
^0(%arg40 : i1, %arg41 : i1):
  %0 = llvm.icmp "uge" %arg40, %arg41 : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def or_xor_common_op_commute6_before := [llvm|
{
^0(%arg117 : i8, %arg118 : i8, %arg119 : i8):
  %0 = llvm.or %arg117, %arg118 : i8
  %1 = llvm.xor %arg119, %arg117 : i8
  %2 = llvm.or %1, %0 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

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

@[simp, simp_denote]
def coe_toMonad [Pure m] {eff : EffectKind} : eff.toMonad m α → m α :=
  liftEffect (le_impure eff)

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

def not_or_or_and_no_and_after := [llvm|
{
^0(%arg121 : i32, %arg122 : i32, %arg123 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg121, %0 : i32
  %2 = llvm.xor %arg122, %0 : i32
  %3 = llvm.and %arg123, %2 : i32
  %4 = llvm.or %3, %1 : i32
  "llvm.return"(%4) : (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 lshrult_03_08_before := [llvm|
{
^0(%arg327 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(-8 : i4) : i4
  %2 = llvm.lshr %arg327, %0 : i4
  %3 = llvm.icmp "ult" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

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

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

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

def tryFactorization_xor_lshr_lshr_before := [llvm|
{
^0(%arg37 : i32):
  %0 = llvm.mlir.constant(-3 : i32) : i32
  %1 = llvm.mlir.constant(5 : i32) : i32
  %2 = llvm.lshr %0, %arg37 : i32
  %3 = llvm.lshr %1, %arg37 : i32
  %4 = llvm.xor %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def llvm_const_lower_riscv_li_29 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_29, rhs:= liRiscv_29,
   correct := by admit /- proof elided -/

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

def src_srem_shl_demand_min_signbit_mask_hit_last_demand_after := [llvm|
{
^0(%arg20 : i32):
  %0 = llvm.mlir.constant(536870912 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.mlir.constant(-1073741822 : i32) : i32
  %3 = llvm.srem %arg20, %0 : i32
  %4 = llvm.shl %3, %1 overflow<nsw> : i32
  %5 = llvm.and %4, %2 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

def 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 mul_add_to_mul_6_after := [llvm|
{
^0(%arg26 : i32, %arg27 : i32):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.mul %arg26, %arg27 overflow<nsw> : i32
  %2 = llvm.mul %1, %0 overflow<nsw> : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

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

@[simp_denote]
def ori_llvm := [LV| {
    ^entry (%a: i16):
    %0 = llvm.mlir.constant (5) : i16
    %1 = llvm.or %a, %0 : i16
    llvm.return %1 :i16
  }]

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 src_x_and_nmask_ult_after := [llvm|
{
^0(%arg24 : i8, %arg25 : i8, %arg26 : i1):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.shl %0, %arg25 overflow<nsw> : i8
  %3 = llvm.icmp "ugt" %2, %arg24 : i8
  %4 = "llvm.select"(%arg26, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def andcond.010.inv.inner.cond.in.inner.sel_after := [llvm|
{
^0(%arg65 : i1, %arg66 : i1, %arg67 : i1, %arg68 : i1, %arg69 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = "llvm.select"(%arg66, %arg69, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %2 = "llvm.select"(%arg65, %1, %arg68) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

def canonicalize_logic_first_or0_nswnuw_after := [llvm|
{
^0(%arg38 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(112 : i32) : i32
  %2 = llvm.or %arg38, %0 : i32
  %3 = llvm.add %2, %1 overflow<nsw,nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

instance LLVMAndRiscvPrint : DialectPrint LLVMPlusRiscV where
  printOpName
    | .llvm llvmOp => printOpName llvmOp
    | .riscv riscvOp => printOpName riscvOp
    | _ => "builtin.unrealized_conversion_cast"
  printTy
    | .llvm llvmTy => printTy llvmTy
    | .riscv riscvTy => printTy riscvTy
  printAttributes
    | .llvm llvmOp => printAttributes llvmOp
    | .riscv riscvOp => printAttributes riscvOp
    | _ => ""
  dialectName := "riscv"
  printReturn := fun
    | [.llvm llvmTy] => printReturn [llvmTy]
    | [.riscv riscvTy] =>  printReturn [riscvTy]
    | _ => s!"<ERROR: mallformed return>"
  printFunc := fun
    | [.llvm llvmTy]   => printFunc [llvmTy]
    | [.riscv riscvTy] => printFunc [riscvTy]
    | _ => s!"<ERROR: mallformed func>"

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

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

def simplify_and_common_op_commute2_before := [llvm|
{
^0(%arg25 : i4, %arg26 : i4, %arg27 : i4, %arg28 : i4):
  %0 = llvm.mlir.constant(-1 : i4) : i4
  %1 = llvm.mul %arg27, %arg27 : i4
  %2 = llvm.or %arg25, %arg26 : i4
  %3 = llvm.or %1, %2 : i4
  %4 = llvm.or %3, %arg28 : i4
  %5 = llvm.xor %4, %0 : i4
  %6 = llvm.and %5, %arg25 : i4
  "llvm.return"(%6) : (i4) -> ()
}
]

def icmp_equality_test_constant_before := [llvm|
{
^0(%arg32 : i42, %arg33 : i42):
  %0 = llvm.mlir.constant(-42 : i42) : i42
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.icmp "eq" %arg32, %0 : i42
  %4 = llvm.icmp "eq" %arg33, %0 : i42
  %5 = llvm.icmp "eq" %arg32, %arg33 : i42
  %6 = llvm.xor %4, %1 : i1
  %7 = "llvm.select"(%6, %5, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %8 = "llvm.select"(%3, %4, %7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%8) : (i1) -> ()
}
]

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

StateT in Init.Control.State

def ashr_mul_before := [llvm|
{
^0(%arg99 : i8, %arg100 : i8):
  %0 = llvm.mlir.constant(8 : i20) : i20
  %1 = llvm.sext %arg99 : i8 to i20
  %2 = llvm.sext %arg100 : i8 to i20
  %3 = llvm.mul %1, %2 : i20
  %4 = llvm.ashr %3, %0 : i20
  %5 = llvm.trunc %4 : i20 to i16
  "llvm.return"(%5) : (i16) -> ()
}
]

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

def tacName : String := "bv_automata_gen"

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

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

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

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

def uadd_sat_flipped_wrong_bounds7_before := [llvm|
{
^0(%arg90 : i32):
  %0 = llvm.mlir.constant(-12 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.mlir.constant(-1 : i32) : i32
  %3 = llvm.icmp "ule" %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) -> ()
}
]

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

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

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

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

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

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

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

def or {w : Nat} (l : List (BitVec w)) : BitVec w :=
  List.foldr BitVec.or (BitVec.zero w) l
</all_available_defs>

<all_available_lemmas>
NFA.eval_append_singleton in Mathlib.Computability.NFA
NFA.eval_nil in Mathlib.Computability.NFA

@[ext]
theorem ext {x y : BitStream} (h : ∀ i, x i = y i) : x = y

theorem ashr_mul_times_3_div_2_exact_2_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ x.smulOverflow 3#32 = true ∨ True ∧ (x * 3#32) >>> 1#32 <<< 1#32 ≠ x * 3#32 ∨ 1#32 ≥ ↑32) →
    ¬(True ∧ x >>> 1#32 <<< 1#32 ≠ x ∨ 1#32 ≥ ↑32 ∨ True ∧ x.saddOverflow (x.sshiftRight' 1#32) = true) →
      (x * 3#32).sshiftRight' 1#32 = x + x.sshiftRight' 1#32

theorem test_ult_nuw_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 32),
  ¬(True ∧ signExtend 32 (truncate 8 x_1) ≠ x_1 ∨
        True ∧ zeroExtend 32 (truncate 8 x_1) ≠ x_1 ∨
          True ∧ signExtend 16 (truncate 8 x) ≠ x ∨ True ∧ zeroExtend 16 (truncate 8 x) ≠ x) →
    ofBool (truncate 8 x_1 <ᵤ truncate 8 x) = ofBool (x_1 <ᵤ zeroExtend 32 x)

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

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

theorem test15a_thm.extracted_1._1 : ∀ (x : BitVec 1),
  x = 1#1 → ¬zeroExtend 53 3#8 ≥ ↑53 → 64#53 <<< zeroExtend 53 3#8 = 512#53

theorem test1_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (LLVM.and e_1 (const? 32 65280)) (LLVM.and e (const? 32 65280)) ⊑
    icmp IntPred.ne (LLVM.and (LLVM.xor e_1 e) (const? 32 65280)) (const? 32 0)

theorem ashrsgt_02_06_proof : ashrsgt_02_06_before ⊑ ashrsgt_02_06_after

theorem shl_nuw_eq_0_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (shl e_1 e { «nsw» := false, «nuw» := true }) (const? 8 0) ⊑
    icmp IntPred.eq e_1 (const? 8 0)

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

theorem test2_thm.extracted_1._1 : ∀ (x : BitVec 1005), x ^^^ 0#1005 = x

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

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

theorem bools_multi_uses2_logical_thm.extracted_1._16 : ∀ (x x_1 : BitVec 1),
  ¬x_1 ^^^ 1#1 = 1#1 → x_1 = 1#1 → ¬0#1 = 1#1 → x = 1#1 → 0#1 + x = 0#1 ^^^ x

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

theorem addhshlhsdivhnegative1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬((-1#32 == 0 || 32 != 1 && x == intMin 32 && -1#32 == -1) = true ∨ 1#32 ≥ ↑32) →
    x.sdiv (-1#32) <<< 1#32 + x = 0#32 - x

theorem ashr_xor_thm (e e_1 : IntW 32) :
  ashr (LLVM.xor (LLVM.srem e_1 (const? 32 42)) (ashr e (const? 32 5))) (const? 32 7) ⊑
    LLVM.xor (ashr e (const? 32 12)) (ashr (LLVM.srem e_1 (const? 32 42)) (const? 32 7))

theorem test24_proof : test24_before ⊑ test24_after

theorem and_orn_cmp_1_logical_proof : and_orn_cmp_1_logical_before ⊑ and_orn_cmp_1_logical_after

theorem or_disjoint_with_xor_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (x_1 &&& x != 0) = true) → (x_1 ||| x) ^^^ x_1 = x

@[simp] theorem val_toArgResult (mapOut : MatchVarResult lets v (.var matchLets matchExpr) w.appendInl mapIn) :
    mapOut.toArgResult.val = mapOut.val

theorem t9_lshr_proof : t9_lshr_before ⊑ t9_lshr_after

theorem sext_sext_ult_proof : sext_sext_ult_before ⊑ sext_sext_ult_after

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

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

theorem fold_icmp_shl_nuw_c2_div_non_pow2_proof : fold_icmp_shl_nuw_c2_div_non_pow2_before ⊑ fold_icmp_shl_nuw_c2_div_non_pow2_after

theorem positive_biggerashr_shlnuw_proof : positive_biggerashr_shlnuw_before ⊑ positive_biggerashr_shlnuw_after

theorem ult_umin1_proof : ult_umin1_before ⊑ ult_umin1_after

theorem p_constmask2_proof : p_constmask2_before ⊑ p_constmask2_after

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

theorem xor_common_op_commute0_proof : xor_common_op_commute0_before ⊑ xor_common_op_commute0_after

theorem ashrsgt_03_09_proof : ashrsgt_03_09_before ⊑ ashrsgt_03_09_after

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

theorem e_2263 :
    3 * (e ^^^ (d |||  ~~~f)) - 1 * (e ||| (d &&& f)) + 1 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 5 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 3 *  ~~~(d &&&  ~~~e) + 2 *  ~~~(d ||| (e &&& f)) - 5 * (d ^^^ (e ^^^ f)) + 7 * (e ||| (d ^^^ f)) + 5 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 7 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 1 * (f ^^^ (d &&& (e ||| f))) - 1 * ((e &&& f) ||| (d &&& (e ||| f))) - 11 * (f ^^^ (d ||| (e ||| f))) - 11 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 2 * (f ^^^ (d &&& ( ~~~e ||| f))) + 5 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 5 * (e ^^^ (d ||| (e &&& f))) + 1 * (f &&& (d ||| e)) - 6 * (f |||  ~~~(d ||| e)) - 1 * (e |||  ~~~(d |||  ~~~f)) + 2 * (d ||| f) + 2 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 7 *  ~~~d + 2 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 11 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 2 * ( ~~~e &&& (d ^^^ f)) + 1 *  ~~~(d ^^^ (e ||| f)) - 7 * (f &&& (d ^^^ e)) - 2 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 7 * (f ^^^ (d ||| ( ~~~e ||| f))) + 1 * (f ^^^ (d &&& e)) - 1 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 1 *  ~~~(d ||| (e ^^^ f)) - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 5 * (f ^^^ (d &&&  ~~~e)) + 11 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 5 * (e ^^^ ( ~~~d ||| (e ||| f))) - 7 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 1 * (e ^^^ (d &&&  ~~~f)) - 1 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 3 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 3 * (f ^^^  ~~~(d ||| (e &&& f))) - 1 * (d ||| ( ~~~e &&& f)) + 1 * ( ~~~d &&& ( ~~~e ||| f)) - 11 *  ~~~(e &&&  ~~~f) + 1 * d + 1 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 5 * (e ^^^ (d &&& (e ^^^ f))) - 7 *  ~~~( ~~~d ||| (e ^^^ f)) + 11 * (e ^^^ (d &&& f)) - 47 *  ~~~(d ||| (e ||| f)) - 21 *  ~~~(d ||| ( ~~~e ||| f)) + 1 *  ~~~( ~~~d ||| (e ||| f)) - 25 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 21 * ( ~~~d &&& ( ~~~e &&& f)) - 50 * ( ~~~d &&& (e &&& f)) - 23 * (d &&& ( ~~~e &&& f)) - 9 * (d &&& (e &&& f)) =  - 1 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 11 * (e ^^^  ~~~( ~~~d &&& (e ||| f)))

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 p0_thm (e : IntW 8) :
  icmp IntPred.ult (LLVM.and e (const? 8 3)) e ⊑ icmp IntPred.ugt e (const? 8 3)

theorem and_ranges_overlap_single_proof : and_ranges_overlap_single_before ⊑ and_ranges_overlap_single_after

theorem drop_nuw_trunc_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬(True ∧ zeroExtend 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 ashrslt_01_00_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 1#4 <<< 1#4 ≠ x ∨ 1#4 ≥ ↑4) → ofBool (x.sshiftRight' 1#4 <ₛ 0#4) = ofBool (x <ₛ 0#4)

theorem invert_icmp_thm (e e_1 : IntW 32) :
  LLVM.xor (icmp IntPred.sle e_1 e) (const? 1 1) ⊑ icmp IntPred.sgt e_1 e

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

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

theorem e_1148 :
     - 7 * (z ^^^ t) - 6 *  ~~~(z &&&  ~~~z) + 11 * (z |||  ~~~t) - 1 *  ~~~z - 1 *  ~~~(z ^^^ t) + 16 *  ~~~(z |||  ~~~t) + 2 * (z &&&  ~~~t) - 2 * (z &&& t) = 2 *  ~~~(z &&&  ~~~t) + 1 *  ~~~(z ||| t)

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

theorem test35_with_trunc_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ofBool (0#32 ≤ₛ truncate 32 x) = 1#1 → ¬ofBool (x &&& 2147483648#64 == 0#64) = 1#1 → 60#32 = 100#32

theorem decision_procedure_is_correct {w} (φ : Formula) (env : Nat → BitVec w) :
    formulaIsUniversal φ → φ.sat' env

theorem sel_sext_proof : sel_sext_before ⊑ sel_sext_after

theorem test3_thm (e e_1 : IntW 32) : LLVM.and e_1 (LLVM.and e e_1) ⊑ LLVM.and e e_1

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

theorem test93_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬64#96 ≥ ↑96 → ¬31#32 ≥ ↑32 → truncate 32 (signExtend 96 x >>> 64#96) = x.sshiftRight' 31#32

@[elab_as_elim]
theorem ind_principle₂  {motive : Nat → Prop} (bound : Nat)
  (hBase : ∀ i ≤ bound, motive i)
  (hInd : ∀ (i : Nat),
    bound < i →
    ((∀ (k : Nat), k < bound → motive (i - k - 1)) → motive i)) :
  ∀ k, motive k

theorem t5_proof : t5_before ⊑ t5_after

theorem zext_zext_ule_op0_wide_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 9),
  ofBool (zeroExtend 32 x_1 ≤ᵤ zeroExtend 32 x) = ofBool (x_1 ≤ᵤ zeroExtend 9 x)

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

theorem masked_and_notA_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 14#32 != x) = 1#1 → 0#1 = ofBool (x &&& BitVec.ofInt 32 (-79) != 0#32)

lemma Predicate.evalFin_eq_eval (p : Predicate)
   (varsList : List BitStream) (varsFin : Fin p.arity → BitStream)
   (hvars : ∀ (i : Fin p.arity), varsList.getD i default = (varsFin i)) :
    Predicate.evalFin p varsFin  = Predicate.eval p varsList

theorem PR30273_three_bools_thm.extracted_1._9 : ∀ (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 ∧ (1#32).saddOverflow (zeroExtend 32 x_2) = true ∨
              True ∧ (1#32).uaddOverflow (zeroExtend 32 x_2) = true →
            False

theorem sub_shl_same_amount_partial_nuw2_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 6),
  ¬(True ∧ x_2 <<< x_1 >>> x_1 ≠ x_2 ∨ x_1 ≥ ↑6 ∨ x_1 ≥ ↑6 ∨ True ∧ (x_2 <<< x_1).usubOverflow (x <<< x_1) = true) →
    ¬x_1 ≥ ↑6 → x_2 <<< x_1 - x <<< x_1 = (x_2 - x) <<< x_1

theorem ashrsgt_03_02_proof : ashrsgt_03_02_before ⊑ ashrsgt_03_02_after

theorem e_2273 :
     - 3 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 4 * ( ~~~e &&&  ~~~(d ^^^ f)) - 3 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 4 * (e ^^^  ~~~(d |||  ~~~f)) + 7 *  ~~~(d &&& (e &&& f)) + 2 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 5 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 2 * (e ^^^ (d ||| f)) - 11 * ((d &&& e) ^^^ (e ||| f)) - 1 *  ~~~(e ||| f) - 7 *  ~~~(d ^^^ e) - 3 * (f &&&  ~~~(d &&&  ~~~e)) - 1 * (f ^^^ (d &&& ( ~~~e ||| f))) - 5 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 2 * (e |||  ~~~(d ||| f)) + 4 * ((d &&& e) ^^^ (e |||  ~~~f)) - 1 *  ~~~(e ^^^ f) + 2 * ( ~~~d ||| ( ~~~e ||| f)) + 2 * (f ^^^ (d &&&  ~~~e)) - 3 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 11 * (e &&&  ~~~(d &&& f)) - 6 *  ~~~(d &&& (e ^^^ f)) - 1 * (e ^^^ (d |||  ~~~f)) + 1 *  ~~~(d ||| (e ^^^ f)) + 1 *  ~~~(d &&& f) + 1 * (e ||| (d &&& f)) - 1 *  ~~~( ~~~d ||| (e ^^^ f)) - 2 * (f ^^^ ( ~~~d ||| (e ||| f))) - 1 * (f |||  ~~~(d |||  ~~~e)) + 1 * (e |||  ~~~f) - 1 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 1 * (d ||| e) - 11 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 6 * (d ||| (e ^^^ f)) - 6 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * (e ^^^ f) + 7 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 2 * (e ^^^  ~~~(d &&& f)) - 1 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 3 * d + 7 *  ~~~(d |||  ~~~f) - 1 * ( ~~~f &&&  ~~~(d ^^^ e)) - 1 * (d |||  ~~~f) - 5 * (e ||| (d ^^^ f)) + 1 * (e ^^^  ~~~(d ||| f)) - 7 * (f |||  ~~~(d ||| e)) - 6 * (d ^^^ f) + 2 * (e ^^^ (d &&& f)) + 1 * (d ^^^ ( ~~~e &&& f)) + 1 * (e ^^^ (d ||| (e ||| f))) + 5 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 1 *  ~~~(d ||| (e ||| f)) + 23 *  ~~~( ~~~d ||| (e ||| f)) + 16 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 23 * ( ~~~d &&& ( ~~~e &&& f)) + 32 * ( ~~~d &&& (e &&& f)) + 27 * (d &&& ( ~~~e &&& f)) + 32 * (d &&& (e &&& f)) = 1 *  ~~~(d ||| ( ~~~e ||| f))

theorem ashr_ult_3_proof : ashr_ult_3_before ⊑ ashr_ult_3_after

theorem lshr_lshr_thm (e : IntW 232) : lshr (lshr e (const? 232 231)) (const? 232 1) ⊑ const? 232 0

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

theorem bv_AndOrXor_887_2 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.and (LLVM.icmp LLVM.IntPred.eq e e_1) (LLVM.icmp LLVM.IntPred.ne e e_1) ⊑ LLVM.const? 1 0

theorem t7_ugt_sgt_neg1_proof : t7_ugt_sgt_neg1_before ⊑ t7_ugt_sgt_neg1_after

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

theorem eq_10_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32) →
    ofBool (truncate 8 x_1 == truncate 8 x) &&& ofBool (truncate 8 (x_1 >>> 8#32) == truncate 8 (x >>> 8#32)) =
      ofBool (truncate 16 x_1 == truncate 16 x)

theorem eq_of_ofBitVec_eq (x y : BitVec w) :
    ofBitVecSext x ={≤w} ofBitVecSext y → x = y

theorem and_xor_or4_proof : and_xor_or4_before ⊑ and_xor_or4_after

theorem e_1450 :
     - 3 *  ~~~t + 5 *  ~~~(z &&&  ~~~z) - 6 *  ~~~(z &&& t) - 7 *  ~~~(z &&&  ~~~t) + 4 *  ~~~(z ^^^ t) - 2 *  ~~~z + 2 * z + 5 * t + 9 *  ~~~(z ||| t) - 9 * (z &&& t) =  - 3 *  ~~~(z |||  ~~~t) - 2 * (z ^^^ t)

theorem 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 e_774 :
     - 5 *  ~~~(z &&&  ~~~z) + 1 * t - 6 * (z ^^^ t) + 10 *  ~~~(z |||  ~~~t) - 1 * (z &&& t) =  - 6 * (z &&&  ~~~t) - 5 * (z |||  ~~~t)

theorem sext_thm.extracted_1._1 : ∀ (x : BitVec 16),
  (zeroExtend 32 x ^^^ 32768#32) + BitVec.ofInt 32 (-32768) = signExtend 32 x

theorem test8_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x != 0#32) = 1#1 → 0#1 = ofBool (x + -1#32 <ᵤ 13#32)

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

theorem trunc_shl_ashr_var_thm (e e_1 : IntW 64) :
  trunc 32 (shl (ashr e_1 e) (const? 64 2)) ⊑ shl (trunc 32 (ashr e_1 e)) (const? 32 2)

theorem eq_umax2_proof : eq_umax2_before ⊑ eq_umax2_after

@[bv_multi_width_normalize] theorem ofBool_and_ofBool (x y : Bool) :
  (BitVec.ofBool x &&& BitVec.ofBool y) = BitVec.ofBool (x && y)

theorem sge_swap_and_max_logical_proof : sge_swap_and_max_logical_before ⊑ sge_swap_and_max_logical_after

theorem demorgan_nor_use2a_proof : demorgan_nor_use2a_before ⊑ demorgan_nor_use2a_after

@[simp] theorem Expr.denote_appendInr (e : Expr d Γ .pure t) (V : Γ.Valuation) (v : Γ.Var u) :
    e.denote V v.appendInr = V v

theorem AvoidCollision_shiftLeftZeroExtend_eq {x : BitVec w} :
    shiftLeftZeroExtend x n = setWidth (w+n) x <<< n

theorem fold_sext_to_and2_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x &&& 1073741826#32 == 2#32) = ofBool (x &&& BitVec.ofInt 8 (-126) == 2#8)

theorem icmp_x_slt_0_and_icmp_y_ne_neg2_i32_fail_proof : icmp_x_slt_0_and_icmp_y_ne_neg2_i32_fail_before ⊑ icmp_x_slt_0_and_icmp_y_ne_neg2_i32_fail_after

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

theorem or_and_shifts1_thm (e : IntW 32) :
  LLVM.or (LLVM.and (shl e (const? 32 3)) (const? 32 15)) (LLVM.and (shl e (const? 32 5)) (const? 32 60)) ⊑
    LLVM.or (LLVM.and (shl e (const? 32 3)) (const? 32 8)) (LLVM.and (shl e (const? 32 5)) (const? 32 32))
      { «disjoint» := true }

theorem shl_or_disjoint_lshr_comm_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ x_1 <<< x >>> x ≠ x_1 ∨ x ≥ ↑32 ∨ True ∧ (x_2 &&& x_1 <<< x != 0) = true ∨ x ≥ ↑32) →
    ¬(x ≥ ↑32 ∨ True ∧ (x_2 >>> x &&& x_1 != 0) = true) → (x_2 ||| x_1 <<< x) >>> x = x_2 >>> x ||

theorem zero_sign_bit_thm (e : IntW 16) :
  add (LLVM.and e (const? 16 32767)) (const? 16 512) ⊑
    add (LLVM.and e (const? 16 32767)) (const? 16 512) { «nsw» := false, «nuw» := true }

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

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

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

theorem lshrugt_02_02_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬2#4 ≥ ↑4 → ofBool (2#4 <ᵤ x >>> 2#4) = ofBool (BitVec.ofInt 4 (-5) <ᵤ x)

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

theorem ashrsgt_03_03_exact_proof : ashrsgt_03_03_exact_before ⊑ ashrsgt_03_03_exact_after

theorem same_signbit_wrong_type_proof : same_signbit_wrong_type_before ⊑ same_signbit_wrong_type_after

theorem test_negative_nsw_and_unsigned_pred_proof : test_negative_nsw_and_unsigned_pred_before ⊑ test_negative_nsw_and_unsigned_pred_after

theorem lt_unsigned_to_large_signed_proof : lt_unsigned_to_large_signed_before ⊑ lt_unsigned_to_large_signed_after

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

theorem icmp_eq_or_z_or_pow2orz_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == 0#8 - x &&& x) ||

theorem sext_true_val_must_be_all_ones_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → signExtend 32 x = -1#32

theorem or_nosignbit_select_shl_proof : or_nosignbit_select_shl_before ⊑ or_nosignbit_select_shl_after

theorem lshr_add_and_shl_thm (e e_1 : IntW 32) :
  shl (add e_1 (LLVM.and (lshr e (const? 32 5)) (const? 32 127))) (const? 32 5) ⊑
    add (LLVM.and e (const? 32 4064)) (shl e_1 (const? 32 5))

theorem icmp_eq_and_pow2_shl_pow2_negative3_proof : icmp_eq_and_pow2_shl_pow2_negative3_before ⊑ icmp_eq_and_pow2_shl_pow2_negative3_after

theorem e_1281 :
    7 * z - 5 *  ~~~(z &&& t) + 1 *  ~~~(z ^^^ t) + 4 * t - 11 *  ~~~(z &&&  ~~~z) + 18 *  ~~~(z ||| t) + 13 *  ~~~(z |||  ~~~t) + 11 * (z &&&  ~~~t) + 2 * (z &&& t) = 2 * (z |||  ~~~t) + 1 *  ~~~(z &&&  ~~~t)

theorem ne_smax2_proof : ne_smax2_before ⊑ ne_smax2_after

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

theorem udiv_x_by_const_cmp_x_proof : udiv_x_by_const_cmp_x_before ⊑ udiv_x_by_const_cmp_x_after

theorem samesign_inverted_commute3_proof : samesign_inverted_commute3_before ⊑ samesign_inverted_commute3_after

theorem test_with_1_proof : test_with_1_before ⊑ test_with_1_after

theorem main11_logical_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 64#32 == 0#32) = 1#1 →
    ofBool (x &&& 192#32 == 192#32) = 1#1 → ofBool (0#8 ≤ₛ truncate 8 x) = 1#1 → 2#32 = 1#32

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

theorem xor_signbit_select_shl_proof : xor_signbit_select_shl_before ⊑ xor_signbit_select_shl_after

theorem modulo2_thm (e : IntW 32) :
  add (select (icmp IntPred.slt (LLVM.srem e (const? 32 2)) (const? 32 0)) (const? 32 2) (const? 32 0))
      (LLVM.srem e (const? 32 2)) { «nsw» := true, «nuw» := false } ⊑
    LLVM.and e (const? 32 1)

theorem test_sext4_thm.extracted_1._5 : ∀ (x x_1 : BitVec 1),
  ¬x_1 = 1#1 → ¬x_1 ^^^ 1#1 = 1#1 → -1#32 = signExtend 32 x

theorem ashr_eq_noexact_thm (e : IntW 8) :
  icmp IntPred.eq (ashr e (const? 8 3)) (const? 8 10) ⊑
    icmp IntPred.eq (LLVM.and e (const? 8 (-8))) (const? 8 80)

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

theorem trunc_shl_15_i16_i32_proof : trunc_shl_15_i16_i32_before ⊑ trunc_shl_15_i16_i32_after

theorem and_signbit_ashr_proof : and_signbit_ashr_before ⊑ and_signbit_ashr_after

theorem main7f_logical_thm.extracted_1._12 : ∀ (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 →
        1#32 = zeroExtend 32 (ofBool (x_1 &&& x != x_2 &&& (x_1 &&& x)))

theorem sle_swap_and_min_logical_proof : sle_swap_and_min_logical_before ⊑ sle_swap_and_min_logical_after

theorem not_and_and_or_no_or_commute1_and_proof : not_and_and_or_no_or_commute1_and_before ⊑ not_and_and_or_no_or_commute1_and_after

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

theorem t0_proof : t0_before ⊑ t0_after

theorem ne_commuted_equal_minus_1_proof : ne_commuted_equal_minus_1_before ⊑ ne_commuted_equal_minus_1_after

theorem test2_proof : test2_before ⊑ test2_after

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

theorem demorgan_and_zext_proof : demorgan_and_zext_before ⊑ demorgan_and_zext_after

theorem ne_basic_equal_5_proof : ne_basic_equal_5_before ⊑ ne_basic_equal_5_after

theorem mul_add_to_mul_9_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(True ∧ x.smulOverflow 16384#16 = true ∨
        True ∧ x.smulOverflow 16384#16 = true ∨ True ∧ (x * 16384#16).saddOverflow (x * 16384#16) = true) →
    ¬15#16 ≥ ↑16 → x * 16384#16 + x * 16384#16 = x <<< 15#16

theorem ashrsgt_01_02_proof : ashrsgt_01_02_before ⊑ ashrsgt_01_02_after

theorem and_logic_and_logic_or_4_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 &&& x_1 = 1#1 → x = 1#1 → x_1 = 1#1 → ¬x_2 = 1#1 → x_1 = x

theorem or_xor_common_op_commute6_thm (e e_1 e_2 : IntW 8) :
  LLVM.or (LLVM.xor e_2 e_1) (LLVM.or e_1 e) ⊑ LLVM.or (LLVM.or e_1 e) e_2

theorem test8_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬32#128 ≥ ↑128 →
    True ∧ zeroExtend 64 x_1 <<< 32#64 >>> 32#64 ≠ zeroExtend 64 x_1 ∨
        32#64 ≥ ↑64 ∨ True ∧ (zeroExtend 64 x_1 <<< 32#64 &&& zeroExtend 64 x != 0) = true →
      False

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

theorem ashrsgt_01_13_exact_proof : ashrsgt_01_13_exact_before ⊑ ashrsgt_01_13_exact_after

theorem sgt_or_not_min_commute_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 != BitVec.ofInt 8 (-128)) = 1#1 → 1#1 = ofBool (x_1 != BitVec.ofInt 8 (-128))

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

theorem lshrult_01_11_proof : lshrult_01_11_before ⊑ lshrult_01_11_after

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

theorem icmp_sgt1_thm (e : IntW 8) :
  icmp IntPred.sgt (shl e (const? 8 1) { «nsw» := true, «nuw» := false }) (const? 8 (-128)) ⊑
    icmp IntPred.ne e (const? 8 (-64))

theorem bools2_logical_commute1_proof : bools2_logical_commute1_before ⊑ bools2_logical_commute1_after

theorem test7_proof : test7_before ⊑ test7_after

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

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

theorem negtest_near_pow2_cmpval_ashr_wrong_cmp_pred_proof : negtest_near_pow2_cmpval_ashr_wrong_cmp_pred_before ⊑ negtest_near_pow2_cmpval_ashr_wrong_cmp_pred_after

theorem lor_lor_right2_thm (e e_1 : IntW 1) :
  select e_1 (const? 1 1) (select e (const? 1 1) e_1) ⊑ select e_1 (const? 1 1) e

@[simp] theorem carry'_succ (initCarry : Bool) (x y : BitStream) :
    (carry' initCarry x y (i + 1)) =
    let out := carry' initCarry x y i
  let a := x i
  let b := y i
  Bool.atLeastTwo a b out

theorem sub_const_const_sub_thm.extracted_1._1 : ∀ (x : BitVec 32), 2#32 - (x - 8#32) = 10#32 - x

@[simp] theorem MatchVarM.liftM_eq_some_iff (x? : Option α) :
    (liftM x? : no_index MatchVarM Δ Γ α) mapIn = some (x, mapOut)
    ↔ x? = some x ∧ mapIn = mapOut

theorem test_mul_nuw__all_are_safe_proof : test_mul_nuw__all_are_safe_before ⊑ test_mul_nuw__all_are_safe_after

theorem not_or_or_and_not_and_and_commute3_proof : not_or_or_and_not_and_and_commute3_before ⊑ not_or_or_and_not_and_and_commute3_after

theorem xor_andn_commute4_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 ^^^ -1#32) = 42#32 / x_1 ||

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

theorem exact_lshr_ne_proof : exact_lshr_ne_before ⊑ exact_lshr_ne_after

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

@[bv_automata_nnf] theorem iff_eq (p q : Prop) : (p ↔ q) = (p = q)

theorem and_or_hoist_mask_proof : and_or_hoist_mask_before ⊑ and_or_hoist_mask_after

theorem neg_nsw_slt_0_proof : neg_nsw_slt_0_before ⊑ neg_nsw_slt_0_after

theorem p0_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x ≤ₛ x &&& 3#8) = ofBool (x <ₛ 4#8)

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

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

theorem positive_with_icmp_proof : positive_with_icmp_before ⊑ positive_with_icmp_after

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

theorem add_const_const_sub_nuw_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (BitVec.ofInt 8 (-127)).usubOverflow (x + 1#8) = true) →
    BitVec.ofInt 8 (-127) - (x + 1#8) = BitVec.ofInt 8 (-128) - x

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

theorem no_shift_xor_multiuse_cmp_with_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 * x_1

theorem lowmask_or_zext_commute_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 24),
  (x_1 ||| zeroExtend 24 x) &&& 65535#24 = zeroExtend 24 (x ||| truncate 16 x_1)

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

theorem positive_samevar_shlnuw_proof : positive_samevar_shlnuw_before ⊑ positive_samevar_shlnuw_after

theorem f_proof : f_before ⊑ f_after

theorem e_203 :
     - 5 *  ~~~(x &&& y) - 2 * (x |||  ~~~y) + 7 *  ~~~x + 7 *  ~~~(x ||| y) - 2 *  ~~~(x |||  ~~~y) + 2 * (x &&& y) = 7 *  ~~~y - 14 * (x &&&  ~~~y)

theorem add_nsw_const_const_sub_nsw_ov_proof : add_nsw_const_const_sub_nsw_ov_before ⊑ add_nsw_const_const_sub_nsw_ov_after

theorem or_signbit_select_ashr_proof : or_signbit_select_ashr_before ⊑ or_signbit_select_ashr_after

theorem narrow_zext_ashr_keep_trunc2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 9),
  ¬(True ∧ (signExtend 64 x_1).saddOverflow (signExtend 64 x) = true ∨ 1#64 ≥ ↑64) →
    ¬(True ∧ (zeroExtend 16 x_1).saddOverflow (zeroExtend 16 x) = true ∨
          True ∧ (zeroExtend 16 x_1).uaddOverflow (zeroExtend 16 x) = true ∨ 1#16 ≥ ↑16) →
      truncate 8 ((signExtend 64 x_1 + signExtend 64 x).sshiftRight' 1#64) =
        truncate 8 ((zeroExtend 16 x_1 + zeroExtend 16 x) >>> 1#16)

theorem ule_swap_or_min_commute_proof : ule_swap_or_min_commute_before ⊑ ule_swap_or_min_commute_after

theorem select_add_icmp_bad_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 == 1#32) = 1#1 → x_2 + x_1 = x_1 + 1#32

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

theorem mul_select_zext_proof : mul_select_zext_before ⊑ mul_select_zext_after

lemma dec_enc_w (bvs : BitVecs n) : (dec (enc bvs)).w = bvs.w

theorem nonexact_ashr_ne_noexactdiv_proof : nonexact_ashr_ne_noexactdiv_before ⊑ nonexact_ashr_ne_noexactdiv_after

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

theorem same_signbit_wrong_type_thm (e : IntW 32) (e_1 : IntW 8) :
  icmp IntPred.ne (lshr e_1 (const? 8 7)) (zext 8 (icmp IntPred.sgt e (const? 32 (-1)))) ⊑
    LLVM.xor (icmp IntPred.slt e_1 (const? 8 0)) (icmp IntPred.sgt e (const? 32 (-1)))

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

theorem src_is_mask_and_fail_mixed_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8),
  ¬(x_1 ≥ ↑8 ∨ x ≥ ↑8) →
    ofBool (x_2 ^^^ 123#8 == (x_2 ^^^ 123#8) &&& ((BitVec.ofInt 8 (-8)).sshiftRight' x_1 &&& (-1#8) >>> x)) =
      ofBool ((BitVec.ofInt 8 (-8)).sshiftRight' x_1 &&& (-1#8) >>> x ||| x_2 ^^^ BitVec.ofInt 8 (-124) == -1#8)

theorem e_1916 :
    7 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) - 5 * (b ^^^ (a ||| (b &&& c))) + 1 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 6 * (b &&&  ~~~(a &&& c)) - 7 * (b ^^^ ( ~~~a &&& (b ^^^ c))) - 5 *  ~~~(a ^^^ c) + 1 * (b ^^^ ( ~~~a &&& (b ||| c))) - 3 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) + 1 * (c ^^^  ~~~(a ||| b)) - 6 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 1 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) + 2 *  ~~~( ~~~a &&& (b &&& c)) + 11 * (b ^^^ (a |||  ~~~c)) + 3 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 3 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) + 5 * (c ^^^  ~~~(a &&& b)) - 1 * (c &&& (a ||| b)) + 4 * (a &&& b) + 5 * ( ~~~c |||  ~~~(a ^^^ b)) - 1 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) + 1 * ( ~~~a ||| ( ~~~b ||| c)) + 1 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 1 * (a ||| b) - 2 *  ~~~(a &&& ( ~~~b ||| c)) - 3 * ((a &&&  ~~~b) ||| (b ^^^ c)) + 3 * b + 1 * (a ^^^ (b ||| c)) - 5 *  ~~~(b ^^^ c) - 5 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) + 7 * (b ^^^ (a ||| ( ~~~b &&& c))) + 1 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 2 * (b ^^^  ~~~(a |||  ~~~c)) - 1 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) - 5 *  ~~~a - 2 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 11 * (a |||  ~~~b) - 1 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) + 5 *  ~~~(a &&& c) + 3 *  ~~~(a ||| c) - 11 *  ~~~( ~~~a ||| (b &&& c)) - 1 * (b |||  ~~~c) + 1 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) - 32 *  ~~~(a ||| (b ||| c)) - 13 *  ~~~(a ||| ( ~~~b ||| c)) - 23 *  ~~~( ~~~a ||| (b ||| c)) + 7 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 19 * ( ~~~a &&& ( ~~~b &&& c)) + 1 * ( ~~~a &&& (b &&& c)) - 10 * (a &&& ( ~~~b &&& c)) - 19 * (a &&& (b &&& c)) =  - 4 * (b ^^^ (a &&& (b ^^^ c)))

theorem land_bor_right1_proof : land_bor_right1_before ⊑ land_bor_right1_after

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

theorem t4_proof : t4_before ⊑ t4_after

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

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

theorem alive_820'   : alive_820'_src ⊑ alive_820'_tgt

theorem lshr_shl_pow2_const_case1_proof : lshr_shl_pow2_const_case1_before ⊑ lshr_shl_pow2_const_case1_after

theorem or_nontrivial_mask1_thm (e : IntW 16) :
  LLVM.or (icmp IntPred.ne (trunc 8 e) (const? 8 127))
      (icmp IntPred.ne (LLVM.and e (const? 16 3840)) (const? 16 1280)) ⊑
    icmp IntPred.ne (LLVM.and e (const? 16 4095)) (const? 16 1407)

theorem neg_or_ashr_i32_proof : neg_or_ashr_i32_before ⊑ neg_or_ashr_i32_after

theorem select_bittest_to_shl_negative_test_proof : select_bittest_to_shl_negative_test_before ⊑ select_bittest_to_shl_negative_test_after

theorem zext_negate_thm.extracted_1._1 : ∀ (x : BitVec 1), 0#64 - zeroExtend 64 x = signExtend 64 x

theorem select_icmp_ne_0_and_32_or_4096_proof : select_icmp_ne_0_and_32_or_4096_before ⊑ select_icmp_ne_0_and_32_or_4096_after

theorem and_shl_thm (e e_1 e_2 e_3 : IntW 8) :
  LLVM.and (shl e_3 e_2) (LLVM.and (shl e_1 e_2) e) ⊑ LLVM.and (shl (LLVM.and e_1 e_3) e_2) e

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

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

theorem or_disjoint_with_xor_proof : or_disjoint_with_xor_before ⊑ or_disjoint_with_xor_after

theorem icmp_equality_test_proof : icmp_equality_test_before ⊑ icmp_equality_test_after

theorem ashr_ne_msb_low_second_zero_proof : ashr_ne_msb_low_second_zero_before ⊑ ashr_ne_msb_low_second_zero_after

theorem test_shl_nuw_nsw__all_are_safe_thm.extracted_1._4 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 15#32 == 0#32) = 1#1 →
    ¬(True ∧ ((x_1 &&& 15#32) <<< 2#32).sshiftRight' 2#32 ≠ x_1 &&& 15#32 ∨
          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 test2_proof : test2_before ⊑ test2_after

theorem lshrult_03_01_proof : lshrult_03_01_before ⊑ lshrult_03_01_after

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

theorem mul_of_bools_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ofBool ((x_1 &&& 1#32) * (x &&& 1#32) <ᵤ 2#32) = 1#1

theorem different_size_sext_sext_ule_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 lshrult_01_05_exact_proof : lshrult_01_05_exact_before ⊑ lshrult_01_05_exact_after

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

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

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

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

theorem uadd_sat_via_add_swapped_cmp_nonstrict_thm (e e_1 : IntW 32) :
  select (icmp IntPred.uge e_1 (add e e_1)) (const? 32 (-1)) (add e e_1) ⊑
    select (icmp IntPred.ult e_1 (add e e_1)) (add e e_1) (const? 32 (-1))

theorem e_1615 :
     - 5 * (b ^^^ ( ~~~a ||| (b ||| c))) - 11 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) + 2 *  ~~~(a ^^^ ( ~~~b ||| c)) + 1 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 1 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) - 1 * (b |||  ~~~(a ||| c)) + 1 * (a ||| ( ~~~b ||| c)) - 2 * (c ^^^  ~~~(a &&& (b ||| c))) - 11 * ( ~~~a ||| (b ||| c)) + 4 *  ~~~(a &&& (b ^^^ c)) - 7 * ((a &&& c) |||  ~~~(b ||| c)) - 1 * (b ^^^ c) + 30 *  ~~~(a ||| (b ||| c)) + 18 *  ~~~(a ||| ( ~~~b ||| c)) + 12 *  ~~~( ~~~a ||| (b ||| c)) + 10 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 21 * ( ~~~a &&& ( ~~~b &&& c)) + 5 * ( ~~~a &&& (b &&& c)) + 33 * (a &&& ( ~~~b &&& c)) + 35 * (a &&& (b &&& c)) =  - 1 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) + 11 * (c ^^^  ~~~(a |||  ~~~b))

theorem e_1219 :
    2 *  ~~~(z ^^^ t) + 1 * (z ^^^ t) + 5 * (z ||| t) + 1 * z + 2 * (z |||  ~~~t) - 15 *  ~~~(z ||| t) - 17 *  ~~~(z |||  ~~~t) - 9 * (z &&&  ~~~t) - 21 * (z &&& t) =  - 11 *  ~~~(z &&&  ~~~t)

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_4_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 255#32 == 0#32) = 1#1 → 1#1 = ofBool (x &&& 15#32 != 8#32)

theorem shrink_and_thm (e : IntW 64) :
  trunc 31 (LLVM.and e (const? 64 42)) ⊑ trunc 31 (LLVM.and e (const? 64 42)) { «nsw» := true, «nuw» := true }

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

lemma CNFA.lift_spec (m : CNFA n1) (f : Fin n1 → Fin n2) {M : NFA' n1} :
    m.Sim M → (m.lift f |>.Sim (M.lift f))

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

theorem logical_and_icmps2_proof : logical_and_icmps2_before ⊑ logical_and_icmps2_after

theorem test_cast_select_proof : test_cast_select_before ⊑ test_cast_select_after

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

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

theorem ashr_16_to_64_add_zext_basic_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬16#64 ≥ ↑64 →
    (zeroExtend 64 x_1 + zeroExtend 64 x).sshiftRight' 16#64 = zeroExtend 64 (ofBool (x_1 ^^^ -1#16 <ᵤ x))

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 _root_.List.length_le_of_subset_of_nodup {l₁ l₂ : List α}
    (hs : l₁ ⊆ l₂) (hnd : l₁.Nodup) : l₁.length ≤ l₂.length

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

theorem bisim_tail_of_head_eq_none {a : Stream α} (h : a.head = none) :
    a ~ a.tail

theorem neg_thm.extracted_1._1 : ∀ (x : BitVec 8), ¬42#8 = 0 → 0#8 - x ^^^ x / 42#8 = x / 42#8 ^^^ 0#8 - x

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

theorem bad_shl2_sub_i32_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x - 31#32 ≥ ↑32 →
    True ∧ 1#32 <<< (x + BitVec.ofInt 32 (-31)) >>> (x + BitVec.ofInt 32 (-31)) ≠ 1#32 ∨
        x + BitVec.ofInt 32 (-31) ≥ ↑32 →
      False

theorem shr_umax_proof : shr_umax_before ⊑ shr_umax_after

theorem negative_not_power_of_two_logical_proof : negative_not_power_of_two_logical_before ⊑ negative_not_power_of_two_logical_after

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

theorem p_commutative0_proof : p_commutative0_before ⊑ p_commutative0_after

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

theorem shl_add_add_proof : shl_add_add_before ⊑ shl_add_add_after

theorem e_1022 :
     - 3 * (z ^^^ t) + 1 *  ~~~(z &&&  ~~~t) + 4 *  ~~~t + 7 *  ~~~z - 5 *  ~~~(z |||  ~~~t) - 1 * (z &&&  ~~~t) - 1 * (z &&& t) = 12 *  ~~~(z ||| t)

theorem test46_thm (e : IntW 64) :
  zext 64 (shl (LLVM.and (trunc 32 e) (const? 32 42)) (const? 32 8)) ⊑
    zext 64 (LLVM.and (shl (trunc 32 e) (const? 32 8)) (const? 32 10752)) { «nneg» := true }

theorem shl_add_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ x + 1#8 ≥ ↑8) → ¬x ≥ ↑8 → 16#8 <<< x + 7#8 <<< (x + 1#8) = 30#8 <<< x

theorem BitVec.ofFn_getElem_fin {w : Nat} (f : Fin w → Bool) (i : Fin w) :
    (BitVec.ofFn f)[i.val] = f i

@[simp]
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) }

theorem t0_proof : t0_before ⊑ t0_after

theorem mullo_thm.extracted_1._2 : ∀ (x x_1 : BitVec 64),
  ¬(True ∧ (x_1 &&& 4294967295#64).umulOverflow (x &&& 4294967295#64) = true ∨
        32#64 ≥ ↑64 ∨
          32#64 ≥ ↑64 ∨
            True ∧ (x_1 &&& 4294967295#64).umulOverflow (x >>> 32#64) = true ∨
              32#64 ≥ ↑64 ∨
                True ∧ (x_1 >>> 32#64).umulOverflow (x &&& 4294967295#64) = true ∨
                  32#64 ≥ ↑64 ∨ True ∧ (x_1 &&& 4294967295#64).umulOverflow (x &&& 4294967295#64) = true) →
    ¬(True ∧ (x_1 &&& 4294967295#64).umulOverflow (x &&& 4294967295#64) = true ∨
          32#64 ≥ ↑64 ∨
            32#64 ≥ ↑64 ∨
              32#64 ≥ ↑64 ∨
                32#64 ≥ ↑64 ∨
                  True ∧ (x_1 &&& 4294967295#64).umulOverflow (x &&& 4294967295#64) = true ∨
                    True ∧
                      ((((x_1 &&& 4294967295#64) * (x &&& 4294967295#64)) >>> 32#64 + x_1 * x >>> 32#64 +
                                x_1 >>> 32#64 * x) <<<
                              32#64 &&&
                            ((x_1 &&& 4294967295#64) * (x &&& 4294967295#64) &&& 4294967295#64) !=
                          0) =
                        true) →
      ((((x_1 &&& 4294967295#64) * (x &&& 4294967295#64)) >>> 32#64 + (x_1 &&& 4294967295#64) * x >>> 32#64 &&&
                4294967295#64) +
              x_1 >>> 32#64 * (x &&& 4294967295#64)) <<<
            32#64 ||

theorem addhshlhsdivhscalar1_proof : addhshlhsdivhscalar1_before ⊑ addhshlhsdivhscalar1_after

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

theorem test13_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ofBool (x_1 <ᵤ x) &&& ofBool (x <ᵤ x_1) = 0#1

theorem e_1804 :
     - 11 *  ~~~( ~~~a &&& (b &&& c)) + 7 * ((a ^^^ b) &&& (a ^^^ c)) + 1 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) - 1 * ( ~~~b &&&  ~~~(a ^^^ c)) - 5 *  ~~~(a ||| c) + 4 * (b ||| c) - 11 * (b ^^^ ( ~~~a ||| (b ^^^ c))) - 1 * (a ^^^ ( ~~~b &&& c)) - 7 * (b &&& c) + 2 * ( ~~~a &&& (b ^^^ c)) + 2 * (a ||| ( ~~~b ||| c)) - 6 * (b ^^^ (a &&& c)) + 1 *  ~~~( ~~~a &&& (b ||| c)) + 4 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) + 1 *  ~~~(a ^^^ ( ~~~b ||| c)) - 3 *  ~~~(a &&& ( ~~~b ||| c)) - 3 *  ~~~( ~~~a ||| (b &&& c)) + 1 * ((b &&&  ~~~c) ^^^ (a ||| (b ^^^ c))) - 2 * (b ||| (a ^^^ c)) + 1 *  ~~~(a ||| ( ~~~b &&& c)) + 2 * ( ~~~(a ||| b) ||| (b ^^^ c)) - 7 * (c ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 6 *  ~~~(a &&&  ~~~b) - 1 *  ~~~( ~~~a &&& ( ~~~b &&& c)) - 5 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 3 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 6 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 1 *  ~~~(a &&&  ~~~c) - 1 * (b ^^^ (a ||| (b ^^^ c))) - 2 * (a |||  ~~~b) - 2 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) + 2 * (b ^^^  ~~~(a &&& (b ^^^ c))) + 44 *  ~~~(a ||| (b ||| c)) + 27 *  ~~~(a ||| ( ~~~b ||| c)) + 10 *  ~~~( ~~~a ||| (b ||| c)) + 31 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 21 * ( ~~~a &&& ( ~~~b &&& c)) + 18 * ( ~~~a &&& (b &&& c)) + 18 * (a &&& ( ~~~b &&& c)) + 21 * (a &&& (b &&& c)) =  - 2 * (c &&& (a |||  ~~~b)) - 11 * (a ||| ( ~~~b &&& c))

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

theorem positive_biggershl_shlnuw_ashrexact_proof : positive_biggershl_shlnuw_ashrexact_before ⊑ positive_biggershl_shlnuw_ashrexact_after

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

theorem ashr_ashr_proof : ashr_ashr_before ⊑ ashr_ashr_after

theorem lshrugt_03_08_exact_proof : lshrugt_03_08_exact_before ⊑ lshrugt_03_08_exact_after

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

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

theorem test7_proof : test7_before ⊑ test7_after

theorem test_sub_0_Y_eq_0_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (0#8 - x == 0#8) = ofBool (x == 0#8)

theorem or_not_xor_common_op_commute5_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8),
  x_2 ^^^ x_1 ||

theorem not_logicalAnd_not_op1_proof : not_logicalAnd_not_op1_before ⊑ not_logicalAnd_not_op1_after

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

theorem xor_lshr_proof : xor_lshr_before ⊑ xor_lshr_after

theorem PR42691_5_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x <ₛ 1#32) = 1#1 →
    ofBool (x == 2147483647#32) = ofBool (x + BitVec.ofInt 32 (-2147483647) <ᵤ BitVec.ofInt 32 (-2147483646))

theorem test70_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x_1 <ₛ 0#8) = 1#1 → 6#8 ≥ ↑8 → False

theorem masked_or_A_thm (e : IntW 32) :
  LLVM.or (icmp IntPred.eq (LLVM.and e (const? 32 14)) e) (icmp IntPred.eq (LLVM.and e (const? 32 78)) e) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 (-79))) (const? 32 0)

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

theorem test22_logical_proof : test22_logical_before ⊑ test22_logical_after

theorem and_ne_with_diff_one_signed_thm (e : IntW 64) :
  LLVM.and (icmp IntPred.ne e (const? 64 (-1))) (icmp IntPred.ne e (const? 64 0)) ⊑
    icmp IntPred.ult (add e (const? 64 (-1))) (const? 64 (-2))

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

theorem icmp_ne_and_pow2_shl1_proof : icmp_ne_and_pow2_shl1_before ⊑ icmp_ne_and_pow2_shl1_after

theorem uaddo_commute8_proof : uaddo_commute8_before ⊑ uaddo_commute8_after

theorem ashrsgt_01_15_exact_proof : ashrsgt_01_15_exact_before ⊑ ashrsgt_01_15_exact_after

theorem shift_xor_multiuse_cmp_proof : shift_xor_multiuse_cmp_before ⊑ shift_xor_multiuse_cmp_after

theorem sub_select_zext_op_swapped_non_const_args_thm.extracted_1._2 : ∀ (x : BitVec 6) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → zeroExtend 6 x_1 - x = 0#6 - x

theorem select_icmp_slt_zero_smin_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x <ₛ 0#8) = 1#1 → x = x ||

theorem t6_ugt_sgt_65536_proof : t6_ugt_sgt_65536_before ⊑ t6_ugt_sgt_65536_after

theorem nonexact_ashr_ne_noexactlog_proof : nonexact_ashr_ne_noexactlog_before ⊑ nonexact_ashr_ne_noexactlog_after

theorem negate_lowbitmask_proof : negate_lowbitmask_before ⊑ negate_lowbitmask_after

theorem test53_thm (e : IntW 32) :
  zext 64 (LLVM.and (LLVM.or (trunc 16 e) (const? 16 (-32574))) (const? 16 (-25350))) ⊑
    zext 64 (LLVM.or (LLVM.and (trunc 16 e) (const? 16 7224)) (const? 16 (-32574)) { «disjoint» := true })

theorem e_2364 :
    2 *  ~~~(d &&& f) + 1 * (e &&&  ~~~(d ^^^ f)) - 7 * ( ~~~e &&& (d ^^^ f)) + 1 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 *  ~~~(d &&& (e &&& f)) - 2 * ((d &&& e) ^^^ (e ||| f)) + 3 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 7 * (e |||  ~~~(d |||  ~~~f)) - 1 * (e ||| (d &&&  ~~~f)) - 11 * (f ^^^ (d |||  ~~~e)) - 1 *  ~~~(d ^^^ (e ||| f)) + 1 *  ~~~e + 4 * (e |||  ~~~(d ||| f)) - 5 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 1 *  ~~~(d ^^^ (e ^^^ f)) - 6 * (d ||| ( ~~~e ||| f)) - 3 * (f &&&  ~~~(d &&&  ~~~e)) + 2 * (e ^^^  ~~~(d &&& (e ||| f))) + 3 *  ~~~( ~~~d &&& (e ^^^ f)) + 4 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 2 * (f ^^^  ~~~(d &&& (e &&& f))) + 2 * ((d &&& e) ||| (e ^^^ f)) - 2 *  ~~~(d &&&  ~~~d) + 1 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 1 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 11 * (e ^^^ (d &&& ( ~~~e ||| f))) + 4 *  ~~~(e &&& f) + 3 * (e &&& (d |||  ~~~f)) - 1 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 2 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 11 * (e |||  ~~~(d ^^^ f)) - 1 * (e ^^^ f) - 5 * ((d ^^^ e) ||| (d ^^^ f)) + 1 * ((d &&& f) ||| (e &&&  ~~~f)) + 5 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 6 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 4 * (d ^^^ ( ~~~e &&& f)) + 2 *  ~~~(d ||| (e &&& f)) + 2 * ((d &&& e) ^^^ (e |||  ~~~f)) - 2 *  ~~~(d ||| ( ~~~e &&& f)) + 2 *  ~~~(e ||| f) - 5 * (e ||| (d &&& f)) + 7 * (e ^^^ (d ||| (e ||| f))) - 3 * (d ^^^ ( ~~~e ||| f)) - 2 * (d &&&  ~~~e) + 4 *  ~~~( ~~~d &&& (e ||| f)) - 6 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 1 * ( ~~~f |||  ~~~(d ^^^ e)) + 1 *  ~~~(e &&&  ~~~f) + 11 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 * (f ^^^  ~~~(d |||  ~~~e)) - 2 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 1 * (f ^^^ (d ||| (e ||| f))) - 1 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 5 * (d ||| ( ~~~e &&& f)) - 3 * ( ~~~e ||| (d ^^^ f)) + 3 * (e &&& (d ||| f)) - 1 * (f |||  ~~~(d ||| e)) - 1 * (e ^^^ (d &&& (e ||| f))) - 2 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 1 * (f ^^^  ~~~(d ||| e)) + 3 *  ~~~(d ||| (e ||| f)) - 15 *  ~~~(d ||| ( ~~~e ||| f)) - 28 *  ~~~( ~~~d ||| (e ||| f)) + 7 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 9 * ( ~~~d &&& ( ~~~e &&& f)) + 44 * ( ~~~d &&& (e &&& f)) + 2 * (d &&& ( ~~~e &&& f)) =  - 1 * ( ~~~e &&&  ~~~(d ^^^ f)) - 2 * (e ^^^ ( ~~~d ||| (e ||| f)))

theorem select_mul_icmp_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32), ofBool (x_2 == 1#32) = 1#1 → x_2 * x_1 = x_1

theorem shl_sub_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(3#8 ≥ ↑8 ∨ 2#8 ≥ ↑8) → ¬(5#8 ≥ ↑8 ∨ 2#8 ≥ ↑8) → (x_1 <<< 3#8 - x) <<< 2#8 = x_1 <<< 5#8 - x <<< 2#8

theorem PR1817_1_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.slt e (const? 32 10)) (icmp IntPred.ult e (const? 32 10)) ⊑
    icmp IntPred.ult e (const? 32 10)

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

theorem positive_with_mask_logical_proof : positive_with_mask_logical_before ⊑ positive_with_mask_logical_after

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

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

 theorem List.dropLast_nodup (l : List X) : l.Nodup → l.dropLast.Nodup

theorem fold_add_udiv_urem_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(10#32 = 0 ∨ 4#32 ≥ ↑32 ∨ 10#32 = 0) → 10#32 = 0 ∨ True ∧ (x / 10#32).umulOverflow 6#32 = true → False

theorem positive_sameconst_shlnuwnsw_lshrexact_proof : positive_sameconst_shlnuwnsw_lshrexact_before ⊑ positive_sameconst_shlnuwnsw_lshrexact_after

theorem uge_sext_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  ofBool (x ≤ᵤ signExtend 8 x_1) = ofBool (x == 0#8) ||

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 icmp_select_var_select_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  x_1 = 1#1 → ofBool (x == 0#8) = 1#1 ∧ x_1 = 1#1 → ofBool (x == 0#8) = 1#1 → ¬True → ofBool (x == x) = 1#1

theorem lshrugt_02_09_proof : lshrugt_02_09_before ⊑ lshrugt_02_09_after

theorem no_shift_no_xor_multiuse_or_proof : no_shift_no_xor_multiuse_or_before ⊑ no_shift_no_xor_multiuse_or_after

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

theorem PR42691_9_logical_proof : PR42691_9_logical_before ⊑ PR42691_9_logical_after

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

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

theorem cmpeq_bitwise_proof : cmpeq_bitwise_before ⊑ cmpeq_bitwise_after

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

theorem add_nsw_const_const_sub_nsw_thm (e : IntW 8) :
  sub (const? 8 (-127)) (add e (const? 8 1) { «nsw» := true, «nuw» := false }) { «nsw» := true, «nuw» := false } ⊑
    sub (const? 8 (-128)) e { «nsw» := true, «nuw» := false }

theorem ugt_or_not_min_proof : ugt_or_not_min_before ⊑ ugt_or_not_min_after

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

theorem test1_thm (e : IntW 33) : LLVM.xor (LLVM.xor e (const? 33 (-1))) (const? 33 (-1)) ⊑ e

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

theorem test_zext3_thm.extracted_1._2 : ∀ (x : BitVec 1), x = 1#1 → ¬x ^^^ 1#1 = 1#1 → 0#32 = zeroExtend 32 0#1

theorem one_side_fold_slt_thm (e e_1 e_2 : IntW 32) (e_3 : IntW 1) :
  icmp IntPred.slt (select e_3 e_2 e_1) (select e_3 e e_1) ⊑
    select e_3 (icmp IntPred.slt e_2 e) (const? 1 0)

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 xor_2_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 1) (x_2 : BitVec 8),
  x_1 = 1#1 → x_2 ^^^ (x ^^^ -1#8) ^^^ -1#8 = x_2 ^^^ x

theorem n0_proof : n0_before ⊑ n0_after

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

theorem lor_band_right2_proof : lor_band_right2_before ⊑ lor_band_right2_after

theorem tctx_at_0 : tctx ⟨0, by omega⟩ = WidthExpr.var ⟨0, by omega⟩

theorem scalar_i16_shl_and_signbit_eq_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬x ≥ ↑16 → ofBool (x_1 <<< x &&& BitVec.ofInt 16 (-32768) == 0#16) = ofBool (-1#16 <ₛ x_1 <<< x)

theorem ult_umin2_thm (e e_1 : IntW 32) :
  icmp IntPred.ult (select (icmp IntPred.ult e_1 e) e_1 e) e ⊑ icmp IntPred.ult e_1 e

theorem sub_const_const_sub_thm (e : IntW 32) : sub (const? 32 2) (sub e (const? 32 8)) ⊑ sub (const? 32 10) e

theorem select_or_disjoint_or_proof : select_or_disjoint_or_before ⊑ select_or_disjoint_or_after

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

theorem trunc_ashr_trunc_outofrange_thm (e : IntW 64) :
  trunc 8 (ashr (trunc 32 e) (const? 32 25)) ⊑
    trunc 8 (ashr (trunc 32 e) (const? 32 25)) { «nsw» := true, «nuw» := false }

theorem icmp_ne_and1_lshr_pow2_proof : icmp_ne_and1_lshr_pow2_before ⊑ icmp_ne_and1_lshr_pow2_after

theorem main12_thm (e : IntW 32) :
  select (LLVM.or (icmp IntPred.slt (trunc 16 e) (const? 16 0)) (icmp IntPred.slt (trunc 8 e) (const? 8 0)))
      (const? 32 2) (const? 32 1) ⊑
    select (icmp IntPred.eq (LLVM.and e (const? 32 32896)) (const? 32 0)) (const? 32 1) (const? 32 2)

theorem BitVec.even_mul_eq_shiftLeft_mul_of_eq_mul_two
    (w : Nat) (x : BitVec w) (n e : Nat) (he : e = n * 2) :
    (BitVec.ofNat w e) * x = (BitVec.ofNat w n) * (x <<< (1 : Nat))

theorem lshr_mul_nuw_nsw_proof : lshr_mul_nuw_nsw_before ⊑ lshr_mul_nuw_nsw_after

theorem ne_10_proof : ne_10_before ⊑ ne_10_after

theorem ashr_ugt_0_proof : ashr_ugt_0_before ⊑ ashr_ugt_0_after

theorem or_nosignbit_select_ashr_thm (e : IntW 32) (e_1 : IntW 1) :
  ashr (select e_1 (LLVM.or e (const? 32 2147418112)) e) (const? 32 8) ⊑
    select e_1 (LLVM.or (ashr e (const? 32 8)) (const? 32 8388352)) (ashr e (const? 32 8))

theorem logical_and_logical_and_icmps_proof : logical_and_logical_and_icmps_before ⊑ logical_and_logical_and_icmps_after

theorem PR23309_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (x_1 + BitVec.ofInt 32 (-4)).ssubOverflow x = true) →
    truncate 1 (x_1 + BitVec.ofInt 32 (-4) - x) = truncate 1 (x_1 - x)

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

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

theorem e_1645 :
     - 1 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 7 *  ~~~(a &&&  ~~~b) + 5 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) + 2 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) + 5 * ( ~~~(a ||| b) |||  ~~~(b ^^^ c)) - 7 * ( ~~~c &&&  ~~~(a ^^^ b)) + 5 * (a ||| ( ~~~b ||| c)) + 1 * (b &&& (a ||| c)) + 11 * (c &&&  ~~~(a &&&  ~~~b)) - 11 * (b ^^^ (a ||| c)) - 5 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 6 * (b |||  ~~~(a ^^^ c)) - 5 * (b &&& c) - 1 * (a ^^^ (b &&& c)) - 7 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) - 3 *  ~~~(a ||| (b ||| c)) + 19 *  ~~~(a ||| ( ~~~b ||| c)) - 3 *  ~~~( ~~~a ||| (b ||| c)) + 8 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 10 * ( ~~~a &&& ( ~~~b &&& c)) - 11 * ( ~~~a &&& (b &&& c)) + 18 * (a &&& ( ~~~b &&& c)) - 19 * (a &&& (b &&& c)) =  - 1 * (b ^^^  ~~~( ~~~a ||| (b &&& c)))

theorem test18_thm.extracted_1._4 : ∀ (x : BitVec 16) (x_1 : BitVec 32),
  ¬ofBool (x &&& 4#16 != 0#16) = 1#1 → ¬ofBool (x &&& 4#16 == 0#16) = 1#1 → ¬64#32 = 0 → x_1 % 64#32 = x_1 &&& 31#32

@[simp] lemma composeBinary_eval
    (p : FSM Bool)
    {t₁ t₂ : Term}
    (q₁ : FSMTermSolution t₁)
    (q₂ : FSMTermSolution t₂)
    (x : Fin (max t₁.arity t₂.arity) → BitStream) :
    (composeBinary p q₁ q₂).eval x = p.eval
      (λ b => cond b (t₁.evalFin (fun i => x (Fin.castLE (by simp) i)))
                  (t₂.evalFin (fun i => x (Fin.castLE (by simp) i))))

theorem uge_or_max_proof : uge_or_max_before ⊑ uge_or_max_after

theorem or_ranges_single_elem_right_thm (e : IntW 8) :
  LLVM.or (LLVM.and (icmp IntPred.uge e (const? 8 5)) (icmp IntPred.ule e (const? 8 10)))
      (icmp IntPred.eq e (const? 8 11)) ⊑
    icmp IntPred.ult (add e (const? 8 (-5))) (const? 8 7)

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

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

theorem sext_multi_uses_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 1) (x_2 : BitVec 64),
  x_1 = 1#1 → x_2 * signExtend 64 x_1 + ((x ^^^ signExtend 64 x_1) - signExtend 64 x_1) = 0#64 - (x_2 + x)

theorem t0_thm (e e_1 e_2 e_3 : IntW 32) :
  LLVM.xor (select (icmp IntPred.eq e_3 e_2) (const? 1 1) (icmp IntPred.eq e_1 e)) (const? 1 1) ⊑
    select (icmp IntPred.ne e_3 e_2) (icmp IntPred.ne e_1 e) (const? 1 0)

theorem and_xor_or3_proof : and_xor_or3_before ⊑ and_xor_or3_after

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

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

theorem e_456 :
     - 6 * (x ||| y) + 4 *  ~~~x + 4 * (x |||  ~~~y) + 7 *  ~~~(x &&& y) - 2 *  ~~~(x &&&  ~~~y) - 7 *  ~~~(x ||| y) + 3 *  ~~~(x |||  ~~~y) + 1 * (x &&&  ~~~y) + 10 * (x &&& y) = 6 *  ~~~(x &&&  ~~~x)

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

theorem p_constmask_commutative_thm (e e_1 : IntW 32) :
  LLVM.xor (LLVM.and e_1 (const? 32 (-65281))) (LLVM.and e (const? 32 65280)) ⊑
    LLVM.or (LLVM.and e_1 (const? 32 (-65281))) (LLVM.and e (const? 32 65280)) { «disjoint» := true }

@[simp]
theorem Std.HashSet.mem_union [BEq α] [Hashable α] [LawfulBEq α] {m₁ m₂ : HashSet α} :
    x ∈ m₁.union m₂ ↔ x ∈ m₁ ∨ x ∈ m₂

theorem e_2399 :
     - 1 * (f &&& (d ^^^ e)) + 1 * ((d ^^^ e) |||  ~~~(d ^^^ f)) + 3 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 5 * (f ^^^ (d &&& e)) - 5 * (e ^^^ ( ~~~d &&& (e ||| f))) + 11 * (d ^^^ e) - 2 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 7 * (f ^^^  ~~~(d &&& (e &&& f))) + 5 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 5 * ((d &&& e) ^^^ (e ||| f)) + 1 * (e |||  ~~~(d ^^^ f)) - 5 * (e ^^^ ( ~~~d ||| (e &&& f))) + 1 * (f ^^^  ~~~(d ||| (e &&& f))) - 3 * (f ^^^ (d ||| ( ~~~e ||| f))) + 3 * (e ||| (d &&&  ~~~f)) + 2 * (f |||  ~~~(d |||  ~~~e)) - 5 * (f &&&  ~~~(d ^^^ e)) + 4 * ( ~~~f |||  ~~~(d ^^^ e)) + 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 7 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 7 * (f ^^^ (d ||| e)) - 3 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 1 * (e |||  ~~~(d ||| f)) - 11 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 3 * (f ^^^ ( ~~~d &&& (e ||| f))) + 11 * (d ^^^ ( ~~~e &&& f)) - 7 * (e &&& (d ^^^ f)) + 1 * (f ^^^ (d |||  ~~~e)) - 11 * ( ~~~f &&&  ~~~(d ^^^ e)) + 2 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 4 *  ~~~( ~~~d &&& (e &&& f)) - 2 * (e &&&  ~~~(d &&& f)) - 11 * (f ^^^  ~~~(d &&&  ~~~e)) - 2 *  ~~~(e &&&  ~~~f) - 2 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 3 *  ~~~(d &&& e) - 11 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 1 * e - 3 * (f |||  ~~~(d ||| e)) + 5 * ( ~~~e ||| (d ^^^ f)) - 1 * (e ^^^  ~~~(d ||| (e &&& f))) + 4 * (d &&& e) - 1 * ((d ^^^ e) ||| (d ^^^ f)) - 5 * (e ^^^  ~~~(d &&&  ~~~f)) + 2 * (e &&&  ~~~(d &&&  ~~~f)) - 1 * (e ^^^ (d ||| (e ||| f))) + 4 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * (f ^^^  ~~~(d ||| e)) + 3 *  ~~~(e ^^^ f) - 11 * (d ||| (e &&& f)) - 7 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 3 * (f ||| (d ^^^ e)) - 2 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 11 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 7 * (f ||| (d &&& e)) + 3 * (f ||| (d &&&  ~~~e)) - 6 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 1 *  ~~~( ~~~d ||| ( ~~~e &&& f)) + 11 *  ~~~(d ^^^ (e ||| f)) - 1 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 4 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 3 * (f &&& (d ||| e)) + 2 * (f ^^^  ~~~(d |||  ~~~e)) + 47 *  ~~~(d ||| (e ||| f)) + 12 *  ~~~(d ||| ( ~~~e ||| f)) + 6 *  ~~~( ~~~d ||| (e ||| f)) + 34 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 48 * ( ~~~d &&& ( ~~~e &&& f)) + 38 * (d &&& ( ~~~e &&& f)) + 6 * (d &&& (e &&& f)) =  - 42 * ( ~~~d &&& (e &&& f))

theorem and_shl_thm.extracted_1._2 : ∀ (x x_1 x_2 x_3 : BitVec 8),
  ¬(x_2 ≥ ↑8 ∨ x_2 ≥ ↑8) → ¬x_2 ≥ ↑8 → x_3 <<< x_2 &&& (x_1 <<< x_2 &&& x) = (x_1 &&& x_3) <<< x_2 &&& x

theorem orcond.010.inv.inner.cond.in.inner.sel_proof : orcond.010.inv.inner.cond.in.inner.sel_before ⊑ orcond.010.inv.inner.cond.in.inner.sel_after

theorem test_shl_nuw_nsw__nsw_is_safe_proof : test_shl_nuw_nsw__nsw_is_safe_before ⊑ test_shl_nuw_nsw__nsw_is_safe_after

theorem e_2255 :
     - 5 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 11 *  ~~~(d ^^^ e) - 2 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 3 * ((d &&& e) |||  ~~~(e ||| f)) - 3 * (e ^^^ f) + 2 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 2 *  ~~~(d &&& f) + 1 * (d ||| (e &&& f)) - 11 * (d ^^^ (e ^^^ f)) - 6 * (f ^^^ ( ~~~d ||| (e ||| f))) - 11 * (e ^^^ (d &&& f)) + 5 * (f ^^^ ( ~~~d ||| (e &&& f))) - 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 1 * (f ^^^ (d &&& (e ||| f))) + 3 * ( ~~~e ||| (d ^^^ f)) + 11 * ( ~~~d ||| (e ||| f)) + 5 * (d ||| f) - 6 *  ~~~(e ||| f) + 7 * ((d &&& f) |||  ~~~(e ||| f)) - 2 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 2 * (d ||| (e ||| f)) - 5 * ((d ^^^ e) |||  ~~~(d ^^^ f)) + 11 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 5 * f - 7 * ( ~~~f |||  ~~~(d ^^^ e)) - 2 * (d &&& (e ^^^ f)) - 2 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 4 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 7 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 4 * (e ^^^ (d ||| f)) - 5 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 1 *  ~~~(d ^^^ (e ||| f)) - 7 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 11 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 2 * (e ^^^ (d ||| ( ~~~e &&& f))) - 1 * (f ||| (d &&&  ~~~e)) + 2 * ((d &&& f) ||| (e &&&  ~~~f)) + 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 1 * ( ~~~f &&&  ~~~(d ^^^ e)) - 2 * (d &&&  ~~~f) - 2 *  ~~~(d &&&  ~~~e) + 1 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 7 * (f ^^^ (d ||| ( ~~~e ||| f))) - 5 * (f &&& (d ^^^ e)) - 1 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * (e |||  ~~~(d ||| f)) - 6 * (d ^^^ (e ||| f)) - 1 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 5 * (e ^^^ (d ||| (e ^^^ f))) - 1 * ((d &&& e) ^^^ (e ||| f)) - 5 *  ~~~(d ||| (e ||| f)) + 29 *  ~~~(d ||| ( ~~~e ||| f)) - 7 *  ~~~( ~~~d ||| (e ||| f)) + 30 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 29 * ( ~~~d &&& ( ~~~e &&& f)) + 18 * ( ~~~d &&& (e &&& f)) + 5 * (d &&& ( ~~~e &&& f)) + 15 * (d &&& (e &&& f)) =  - 1 * ( ~~~d ||| ( ~~~e ||| f))

theorem ashr_lshr_no_ashr_proof : ashr_lshr_no_ashr_before ⊑ ashr_lshr_no_ashr_after

theorem sge_and_max_commute_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.eq e_1 (const? 8 127)) (icmp IntPred.sge e_1 e) ⊑
    icmp IntPred.eq e_1 (const? 8 127)

theorem trunc_sel_smaller_sext_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → signExtend 32 42#16 = 42#32

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

theorem lshrult_03_13_proof : lshrult_03_13_before ⊑ lshrult_03_13_after

theorem e_963 :
     - 2 *  ~~~(z &&&  ~~~t) + 1 *  ~~~(z ^^^ t) - 11 * t - 1 *  ~~~(z ||| t) + 13 *  ~~~(z |||  ~~~t) - 2 * (z &&&  ~~~t) =  - 12 * (z &&& t) - 2 *  ~~~t

theorem lshrult_01_09_exact_proof : lshrult_01_09_exact_before ⊑ lshrult_01_09_exact_after

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

theorem bv_AndOrXor_1683_1 :
    ∀ (e e_1 : LLVM.IntW w),
      LLVM.or (LLVM.icmp LLVM.IntPred.ugt e e_1) (LLVM.icmp LLVM.IntPred.eq e e_1) ⊑ LLVM.icmp LLVM.IntPred.uge e e_1

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

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

theorem add_nsw_const_const_sub_nsw_proof : add_nsw_const_const_sub_nsw_before ⊑ add_nsw_const_const_sub_nsw_after

@[simp] theorem eval_falseAfterIncluding (n : Nat) (i : Nat) {env : Fin 0 → BitStream} :
    (falseAfterIncluding n).eval env i = decide (i < n)

theorem bools_multi_uses1_logical_proof : bools_multi_uses1_logical_before ⊑ bools_multi_uses1_logical_after

theorem ashrsgt_02_08_exact_proof : ashrsgt_02_08_exact_before ⊑ ashrsgt_02_08_exact_after

theorem shl_bad_sub_i8_proof : shl_bad_sub_i8_before ⊑ shl_bad_sub_i8_after

@[simp]
theorem or_sub_xor_eq_and {a b : BitVec w} : (a ||| b) - (a ^^^ b) = a &&& b

theorem narrow_zext_sub_proof : narrow_zext_sub_before ⊑ narrow_zext_sub_after

theorem test_sub_4_Y_ne_4_thm (e : IntW 8) :
  icmp IntPred.ne (sub (const? 8 4) e) (const? 8 4) ⊑ icmp IntPred.ne e (const? 8 0)

theorem p0_thm (e : IntW 8) :
  icmp IntPred.sge (LLVM.and e (const? 8 3)) e ⊑ icmp IntPred.slt e (const? 8 4)

theorem sge_to_ult_proof : sge_to_ult_before ⊑ sge_to_ult_after

theorem and_not_or_commute5_proof : and_not_or_commute5_before ⊑ and_not_or_commute5_after

theorem foo_proof : foo_before ⊑ foo_after

theorem p0_proof : p0_before ⊑ p0_after

theorem e_1044 :
     - 1 * (z ^^^ t) + 1 * t + 7 * (z ||| t) - 2 *  ~~~z + 7 *  ~~~(z &&&  ~~~t) - 12 *  ~~~(z |||  ~~~t) - 15 * (z &&& t) = 6 * (z &&&  ~~~t) + 5 *  ~~~(z ||| t)

theorem t0_basic_proof : t0_basic_before ⊑ t0_basic_after

theorem e_1833 :
    1 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 2 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) - 3 * ( ~~~b |||  ~~~(a ^^^ c)) - 5 *  ~~~( ~~~a ||| (b &&& c)) + 2 * (b ||| (a ^^^ c)) + 4 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) - 2 * ( ~~~c &&& (a ^^^ b)) + 1 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) - 2 * c - 1 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) + 11 * (a &&& c) - 2 * ((a |||  ~~~b) &&& (b ^^^ c)) + 1 * (c ||| (a &&& b)) - 5 * (c ^^^  ~~~(a ||| b)) + 11 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) + 3 * (b ^^^ ( ~~~a ||| (b ^^^ c))) - 2 * (b ^^^ (a ||| (b &&& c))) + 4 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) - 2 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) + 7 * (b ^^^ (a &&& c)) + 2 * ( ~~~(a &&& b) &&& (b ^^^ c)) - 7 * ( ~~~a &&& ( ~~~b ||| c)) - 5 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) + 4 * (c ^^^ (a ||| ( ~~~b &&& c))) - 2 *  ~~~(a ^^^ c) - 6 * (c ^^^ (a ||| ( ~~~b ||| c))) - 1 *  ~~~(a ||| b) + 11 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 11 * (b ^^^  ~~~(a &&&  ~~~c)) + 5 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 1 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) + 7 * (b ^^^  ~~~(a |||  ~~~c)) + 7 * (b ^^^  ~~~(a ||| c)) - 6 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) - 6 *  ~~~(b |||  ~~~c) + 5 * (c ^^^  ~~~(a |||  ~~~b)) - 16 *  ~~~(a ||| (b ||| c)) + 3 *  ~~~( ~~~a ||| (b ||| c)) - 46 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 30 * ( ~~~a &&& ( ~~~b &&& c)) + 3 * ( ~~~a &&& (b &&& c)) - 36 * (a &&& ( ~~~b &&& c)) - 24 * (a &&& (b &&& c)) = 2 * (c &&& (a |||  ~~~b)) + 25 *  ~~~(a ||| ( ~~~b ||| c))

theorem t0_shl_thm (e : IntW 8) (e_1 : IntW 32) : shl e_1 (sext 32 e) ⊑ shl e_1 (zext 32 e { «nneg» := true })

theorem ashr_ult_10_proof : ashr_ult_10_before ⊑ ashr_ult_10_after

theorem sub_ashr_or_i64_proof : sub_ashr_or_i64_before ⊑ sub_ashr_or_i64_after

theorem negtest_near_pow2_cmpval_ashr_slt_noexact_proof : negtest_near_pow2_cmpval_ashr_slt_noexact_before ⊑ negtest_near_pow2_cmpval_ashr_slt_noexact_after

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

theorem fold_sext_to_and2_proof : fold_sext_to_and2_before ⊑ fold_sext_to_and2_after

theorem or_xor_tree_1010_proof : or_xor_tree_1010_before ⊑ or_xor_tree_1010_after

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

theorem sgt_swap_or_not_min_commute_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 != BitVec.ofInt 8 (-128)) = 1#1 → 1#1 = ofBool (x_1 != BitVec.ofInt 8 (-128))

theorem test_or3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 &&& 2147483647#32 ≤ₛ x) ||

theorem e_207 :
     - 6 * y + 1 *  ~~~(x &&& y) - 2 * x + 5 *  ~~~(x ||| y) + 5 *  ~~~(x |||  ~~~y) + 8 * (x &&& y) = 6 *  ~~~y - 7 * (x &&&  ~~~y)

theorem pb_proof : pb_before ⊑ pb_after

theorem t0_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬16#32 ≥ ↑32 →
    zeroExtend 32 x <<< 16#32 &&& BitVec.ofInt 32 (-2147483648) = signExtend 32 x &&& BitVec.ofInt 32 (-2147483648)

theorem ExtEq.trans {Γ Δ Ξ : Context Ty} : Γ.ExtEq Δ → Δ.ExtEq Ξ → Γ.ExtEq Ξ

@[simp]
theorem BitVec.zero_concat (b : Bool) : (0#0).concat b = BitVec.ofBool b

theorem ne_umax3_proof : ne_umax3_before ⊑ ne_umax3_after

theorem eq_basic_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == 0#8) ||

theorem test_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x != 34#32) = 1#1 → ofBool (-1#32 <ₛ x) = ofBool (x != 34#32) &&& ofBool (-1#32 <ₛ x)

theorem positive_samevar_shlnsw_lshrexact_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ x_1 >>> x <<< x ≠ x_1 ∨ x ≥ ↑8 ∨ True ∧ (x_1 >>> x <<< x).sshiftRight' x ≠ x_1 >>> x ∨ x ≥ ↑8) →
    x_1 >>> x <<< x = x_1

theorem select_icmp_eq_and_1_0_xor_2_proof : select_icmp_eq_and_1_0_xor_2_before ⊑ select_icmp_eq_and_1_0_xor_2_after

theorem abs_eq_add_xor {x : BitVec w} :
    have y : BitVec w

theorem zext_zext_eq_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (zext 32 e_1) (zext 32 e) ⊑ icmp IntPred.eq e_1 e

theorem shl_lshr_pow2_const_case2_proof : shl_lshr_pow2_const_case2_before ⊑ shl_lshr_pow2_const_case2_after

theorem ashrslt_03_03_proof : ashrslt_03_03_before ⊑ ashrslt_03_03_after

theorem select_icmp_ne_0_and_8_xor_1073741824_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 8),
  ofBool (0#8 != x_1 &&& 8#8) = 1#1 → ofBool (x_1 &&& 8#8 == 0#8) = 1#1 → x = x ^^^ 1073741824#32

theorem pr51551_neg2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (x_1 &&& BitVec.ofInt 32 (-7)).smulOverflow x = true) →
    ¬truncate 1 x_1 ^^^ 1#1 = 1#1 →
      ofBool ((x_1 &&& BitVec.ofInt 32 (-7)) * x &&& 7#32 == 0#32) = ofBool (x &&& 7#32 == 0#32)

theorem ashr_ugt_4_proof : ashr_ugt_4_before ⊑ ashr_ugt_4_after

theorem or_and1_commuted_thm.extracted_1._7 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 &&& (x_1 ^^^ 1#1) = 1#1 → ¬x_1 = 1#1 → x_2 = 1#1 → x_1 = x

theorem e_1284 :
    1 *  ~~~t - 5 * (z ||| t) - 2 * z - 1 * t - 2 * (z |||  ~~~t) + 6 *  ~~~(z ||| t) + 6 *  ~~~(z |||  ~~~t) + 8 * (z &&&  ~~~t) + 15 * (z &&& t) = 5 *  ~~~(z ^^^ t)

theorem test32_thm (e : IntW 32) :
  LLVM.and (lshr (LLVM.and e (const? 32 16)) (const? 32 2)) (const? 32 1) ⊑ const? 32 0

theorem AvoidCollision_getElem?_setWidth (m : Nat) (x : BitVec n) (i : Nat) :
    (x.setWidth m)[i]? = if i < m then some (x.getLsbD i) else none

theorem substitute_constant_and_eq_eq_commute_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.eq e_1 e) (icmp IntPred.eq e_1 (const? 8 42)) (const? 1 0) ⊑
    LLVM.and (icmp IntPred.eq e_1 (const? 8 42)) (icmp IntPred.eq e (const? 8 42))

theorem test_and3_proof : test_and3_before ⊑ test_and3_after

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

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

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

theorem foo_proof : foo_before ⊑ foo_after

theorem e_256 :
     - 11 * (x |||  ~~~y) - 5 * y + 2 *  ~~~x - 5 * (x ||| y) + 1 * (x ^^^ y) + 7 *  ~~~(x |||  ~~~y) + 15 * (x &&&  ~~~y) =  - 21 * (x &&& y) - 9 *  ~~~(x ||| y)

theorem carry_decr (x : Unit → BitStream) : ∀ (n : ℕ), decr.carry x (n+1) =
    fun _ => (BitStream.decrAux (x ()) n).2

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

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

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

theorem main4c_logical_proof : main4c_logical_before ⊑ main4c_logical_after

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

theorem sle_and_min_proof : sle_and_min_before ⊑ sle_and_min_after

theorem select_icmp_x_and_8_ne_0_y_or_8_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& 8#32 == 0#32) = 1#1 → True ∧ (x_1 &&& 8#32 ^^^ 8#32).msb = true → False

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

theorem scalar1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 4),
  ¬(True ∧ (x_1 &&& BitVec.ofInt 4 (-2) &&& (x &&& 1#4) != 0) = true) →
    (x_1 ^^^ x) &&& BitVec.ofInt 4 (-2) ^^^ x = x_1 &&& BitVec.ofInt 4 (-2) ||

theorem p0_thm (e e_1 e_2 : IntW 8) :
  select (icmp IntPred.eq (LLVM.and e_2 (const? 8 1)) (const? 8 1)) e_1 e ⊑
    select (icmp IntPred.eq (LLVM.and e_2 (const? 8 1)) (const? 8 0)) e e_1

theorem sdiv_icmp5_proof : sdiv_icmp5_before ⊑ sdiv_icmp5_after

theorem n1_proof : n1_before ⊑ n1_after

theorem icmp_sgt6_proof : icmp_sgt6_before ⊑ icmp_sgt6_after

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 select_xor_icmp_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 test1_proof : test1_before ⊑ test1_after

theorem icmp_select_var_pred_ult_proof : icmp_select_var_pred_ult_before ⊑ icmp_select_var_pred_ult_after

theorem test_with_neg_even_proof : test_with_neg_even_before ⊑ test_with_neg_even_after

theorem e_617 :
     - 5 *  ~~~(x &&& y) - 5 * y - 1 *  ~~~y + 2 *  ~~~(x &&&  ~~~x) - 2 * (x ^^^ y) - 5 * x + 2 *  ~~~(x ||| y) + 9 *  ~~~(x |||  ~~~y) + 8 * (x &&&  ~~~y) + 5 * (x &&& y) =  - 1 * (x ||| y) - 2 * (x |||  ~~~y)

theorem select_ashr_proof : select_ashr_before ⊑ select_ashr_after

theorem udiv_shl_pair_const_proof : udiv_shl_pair_const_before ⊑ udiv_shl_pair_const_after

theorem or_lshr_proof : or_lshr_before ⊑ or_lshr_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_1_thm (e : IntW 32) :
  LLVM.or (icmp IntPred.eq (LLVM.and e (const? 32 12)) (const? 32 0))
      (icmp IntPred.ne (LLVM.and e (const? 32 7)) (const? 32 1)) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 15)) (const? 32 9)

theorem e_2336 :
    1 * ( ~~~f |||  ~~~(d ^^^ e)) - 1 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 2 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 2 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 4 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 11 * (d ||| ( ~~~e &&& f)) + 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 1 *  ~~~(d &&& e) + 2 * (d ||| f) - 5 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 3 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 11 * (d ^^^ (e ^^^ f)) - 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) + 3 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) - 6 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 * ((d &&& f) |||  ~~~(e ||| f)) + 1 *  ~~~( ~~~d ||| (e &&& f)) + 2 * (f |||  ~~~(d ||| e)) - 1 * (f ^^^ (d &&& (e ||| f))) + 1 *  ~~~(e |||  ~~~f) + 4 * (f ^^^ (d ||| (e ||| f))) - 1 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 3 * (e ^^^ (d ||| (e &&& f))) - 11 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 11 * ((d &&& f) ^^^ (e ||| f)) - 6 * f + 11 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 2 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 1 * (d |||  ~~~e) - 6 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 7 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 3 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 2 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 2 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 3 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 5 *  ~~~(d |||  ~~~e) - 1 *  ~~~(d ||| (e &&& f)) - 2 *  ~~~(d &&&  ~~~e) - 3 * (f &&& (d ||| e)) + 2 * (e |||  ~~~(d ||| f)) - 7 * (e ^^^ (d ||| f)) - 6 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 1 * (e ^^^  ~~~(d ||| f)) + 7 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) - 5 * (e ||| f) - 1 * ((e &&& f) ||| (d &&& (e ||| f))) - 5 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 2 * (f ||| (d ^^^ e)) - 1 * (d ||| (e ||| f)) - 11 * (e ^^^ (d ||| (e ||| f))) - 1 * (e &&& (d ||| f)) + 11 * e + 7 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 6 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) - 2 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 1 * ((d ||| e) &&& (e ^^^ f)) + 11 * (f ^^^ (d |||  ~~~e)) + 7 *  ~~~(d ||| (e ||| f)) + 18 *  ~~~(d ||| ( ~~~e ||| f)) + 19 *  ~~~( ~~~d ||| (e ||| f)) - 26 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 35 * ( ~~~d &&& ( ~~~e &&& f)) + 55 * (d &&& ( ~~~e &&& f)) + 31 * (d &&& (e &&& f)) = 6 * (e ^^^ (d ||| ( ~~~e &&& f))) - 8 * ( ~~~d &&& (e &&& f))

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

theorem t1_sub_of_falseval_thm (e e_1 : IntW 8) (e_2 : IntW 1) :
  sub (select e_2 e_1 e) e ⊑ select e_2 (sub e_1 e) (const? 8 0)

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

theorem PR42691_10_proof : PR42691_10_before ⊑ PR42691_10_after

theorem positive_biggershl_shlnuwnsw_lshrexact_thm (e : IntW 8) :
  shl (lshr e (const? 8 3) { «exact» := true }) (const? 8 6) { «nsw» := true, «nuw» := true } ⊑
    shl e (const? 8 3) { «nsw» := true, «nuw» := true }

theorem ashr_sub_nsw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 17),
  ¬(True ∧ x_1.ssubOverflow x = true ∨ 16#17 ≥ ↑17) →
    (x_1 - x).sshiftRight' 16#17 = signExtend 17 (ofBool (x_1 <ₛ x))

theorem test4_proof : test4_before ⊑ test4_after

theorem select_icmp_x_and_8_ne_0_y_or_8_proof : select_icmp_x_and_8_ne_0_y_or_8_before ⊑ select_icmp_x_and_8_ne_0_y_or_8_after

theorem com_ty : com.2.2.1 = [.bitvec 32]

theorem negate_sdiv_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true →
    ¬(BitVec.ofInt 8 (-42) == 0 || 8 != 1 && x == intMin 8 && BitVec.ofInt 8 (-42) == -1) = true →
      x_1 - x.sdiv 42#8 = x.sdiv (BitVec.ofInt 8 (-42)) + x_1

theorem test17_proof : test17_before ⊑ test17_after

theorem src_is_notmask_sext_proof : src_is_notmask_sext_before ⊑ src_is_notmask_sext_after

theorem in_constant_varx_mone_invmask_proof : in_constant_varx_mone_invmask_before ⊑ in_constant_varx_mone_invmask_after

theorem bar_proof : bar_before ⊑ bar_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 orn_and_cmp_2_partial_logical_thm (e : IntW 1) (e_1 e_2 : IntW 16) :
  select (LLVM.and (icmp IntPred.sge e_2 e_1) e) (const? 1 1) (icmp IntPred.slt e_2 e_1) ⊑
    LLVM.or e (icmp IntPred.slt e_2 e_1)

theorem sge_or_not_max_proof : sge_or_not_max_before ⊑ sge_or_not_max_after

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

theorem exact_lshr_eq_both_equal_proof : exact_lshr_eq_both_equal_before ⊑ exact_lshr_eq_both_equal_after

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

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 test_sub_nuw__nuw_is_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 2147483647#32 == 1073741824#32) = 1#1 →
    True ∧ (BitVec.ofInt 32 (-2147483648)).usubOverflow (x &&& 2147483647#32) = true → False

theorem shl_add_thm (e e_1 : IntW 8) :
  lshr (add (shl e_1 (const? 8 2)) e) (const? 8 2) ⊑ LLVM.and (add (lshr e (const? 8 2)) e_1) (const? 8 63)

theorem zext_zext_ule_op0_wide_proof : zext_zext_ule_op0_wide_before ⊑ zext_zext_ule_op0_wide_after

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

theorem ashr_thm (e : IntW 32) :
  add (LLVM.xor (lshr e (const? 32 5)) (const? 32 67108864)) (const? 32 (-67108864)) ⊑ ashr e (const? 32 5)

theorem ne_nsw_rem_nz_thm (e : IntW 8) :
  icmp IntPred.ne (mul e (const? 8 5) { «nsw» := true, «nuw» := false }) (const? 8 (-126)) ⊑ const? 1 1

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 mul_one :
  (bw p (mulMax (bw p a) (bw q (1#1))))  =
  (bw p a)

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

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 urem_constant_dividend_select_of_constants_divisor_proof : urem_constant_dividend_select_of_constants_divisor_before ⊑ urem_constant_dividend_select_of_constants_divisor_after

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

theorem test_add__nuw_is_safe_proof : test_add__nuw_is_safe_before ⊑ test_add__nuw_is_safe_after

theorem test2_thm (e e_1 : IntW 32) : LLVM.xor (LLVM.and e_1 e) (LLVM.or e_1 e) ⊑ LLVM.xor e_1 e

theorem sub_to_xor_and_commuted_proof : sub_to_xor_and_commuted_before ⊑ sub_to_xor_and_commuted_after

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

theorem not_or_or_and_not_and_and_commute1_and_proof : not_or_or_and_not_and_and_commute1_and_before ⊑ not_or_or_and_not_and_and_commute1_and_after

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

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

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

theorem scalar_i8_lshr_and_negC_eq_not_negatedPowerOf2_proof : scalar_i8_lshr_and_negC_eq_not_negatedPowerOf2_before ⊑ scalar_i8_lshr_and_negC_eq_not_negatedPowerOf2_after

theorem select_icmp_ne_0_and_1073741824_and_not_8_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ¬ofBool (0#32 != x_1 &&& 1073741824#32) = 1#1 →
    ¬ofBool (x_1 &&& 1073741824#32 == 0#32) = 1#1 → x &&& BitVec.ofInt 8 (-9) = x

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_0_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 3#32 != 1#32) = 1#1 →
    ofBool (x &&& 12#32 == 0#32) = ofBool (x &&& 3#32 != 1#32) ||

theorem p0_ult_65536_proof : p0_ult_65536_before ⊑ p0_ult_65536_after

theorem ult_and_not_max_proof : ult_and_not_max_before ⊑ ult_and_not_max_after

theorem PR60818_sgt_thm (e : IntW 32) :
  icmp IntPred.sgt (sub (const? 32 0) e) e ⊑ icmp IntPred.slt e (sub (const? 32 0) e)

theorem trunc_sandwich_max_sum_shift2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(30#32 ≥ ↑32 ∨ 1#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 →
      False

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

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

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

theorem positive_and_odd_eq_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(2#32 == 0 || 32 != 1 && x == intMin 32 && 2#32 == -1) = true →
    ofBool (x.srem 2#32 == 1#32) = ofBool (x &&& BitVec.ofInt 32 (-2147483647) == 1#32)

theorem e_526 :
    1 *  ~~~(x ^^^ y) - 1 * y + 11 *  ~~~(x &&&  ~~~y) + 11 *  ~~~(x &&& y) + 2 *  ~~~y - 25 *  ~~~(x ||| y) - 23 *  ~~~(x |||  ~~~y) - 8 * (x &&&  ~~~y) - 6 * (x &&& y) =  - 2 * (x ||| y) + 7 * x

theorem lshrugt_03_03_exact_proof : lshrugt_03_03_exact_before ⊑ lshrugt_03_03_exact_after

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

theorem C0zero_thm.extracted_1._5 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 + 10#8 <ᵤ 0#8) = 1#1 → ofBool (x_1 <ₛ BitVec.ofInt 8 (-10)) = 1#1 → False

theorem t0_shl_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ¬signExtend 32 x ≥ ↑32 →
    ¬(True ∧ x.msb = true ∨ zeroExtend 32 x ≥ ↑32) → x_1 <<< signExtend 32 x = x_1 <<< zeroExtend 32 x

theorem mul_selectp2_x_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 1), x_1 = 1#1 → 1#8 ≥ ↑8 → False

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

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

theorem e_425 :
    5 * x - 2 * (x ^^^ y) - 11 *  ~~~(x &&&  ~~~y) - 1 * (x ||| y) - 5 *  ~~~x + 16 *  ~~~(x ||| y) + 19 *  ~~~(x |||  ~~~y) - 2 * (x &&&  ~~~y) = 7 *  ~~~y - 7 * (x |||  ~~~y)

theorem and_not_or_wrong_c_proof : and_not_or_wrong_c_before ⊑ and_not_or_wrong_c_after

theorem test8_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬16#32 ≥ ↑32 → 16#32 ≥ ↑32 ∨ True ∧ (x.sshiftRight' 16#32).smulOverflow 32767#32 = true → False

theorem lshrult_03_14_exact_proof : lshrult_03_14_exact_before ⊑ lshrult_03_14_exact_after

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

theorem thisdoesnotloop_proof : thisdoesnotloop_before ⊑ thisdoesnotloop_after

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

theorem t2_proof : t2_before ⊑ t2_after

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

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

theorem test_sdiv_canonicalize_op0_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (0#32).ssubOverflow x_1 = true ∨ (x == 0 || 32 != 1 && 0#32 - x_1 == intMin 32 && x == -1) = true) →
    ¬((x == 0 || 32 != 1 && x_1 == intMin 32 && x == -1) = true ∨ True ∧ (0#32).ssubOverflow (x_1.sdiv x) = true) →
      (0#32 - x_1).sdiv x = 0#32 - x_1.sdiv x

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

theorem 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 n10_lshr_ashr_thm (e : IntW 16) (e_1 : IntW 32) :
  ashr (trunc 16 (lshr e_1 (zext 32 (sub (const? 16 32) e)))) (add e (const? 16 (-1))) ⊑
    ashr (trunc 16 (lshr e_1 (zext 32 (sub (const? 16 32) e) { «nneg» := true }))) (add e (const? 16 (-1)))

theorem lshrult_01_14_thm (e : IntW 4) : icmp IntPred.ult (lshr e (const? 4 1)) (const? 4 (-2)) ⊑ const? 1 1

theorem PR42691_5_thm (e : IntW 32) :
  LLVM.or (icmp IntPred.slt e (const? 32 1)) (icmp IntPred.eq e (const? 32 2147483647)) ⊑
    icmp IntPred.ult (add e (const? 32 (-2147483647))) (const? 32 (-2147483646))

theorem t2_const_lshr_shl_eq_proof : t2_const_lshr_shl_eq_before ⊑ t2_const_lshr_shl_eq_after

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

theorem sub_shl_same_amount_partial_nsw2_proof : sub_shl_same_amount_partial_nsw2_before ⊑ sub_shl_same_amount_partial_nsw2_after

theorem e_567 :
     - 1 * (x ||| y) - 1 *  ~~~(x &&&  ~~~x) - 1 *  ~~~(x &&& y) - 7 * x - 6 * (x |||  ~~~y) + 8 *  ~~~(x ||| y) + 11 *  ~~~(x |||  ~~~y) + 13 * (x &&&  ~~~y) + 26 * (x &&& y) =  - 3 * (x ^^^ y) + 11 * y

theorem n10_thm (e : IntW 8) :
  icmp IntPred.sgt (sub (const? 8 0) e) e ⊑ icmp IntPred.slt e (sub (const? 8 0) e)

theorem exactly_one_set_signbit_proof : exactly_one_set_signbit_before ⊑ exactly_one_set_signbit_after

theorem urem_i32_c_multiuse_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬10#32 = 0 →
    10#32 = 0 ∨
        True ∧ (zeroExtend 32 x % 10#32).saddOverflow (zeroExtend 32 x) = true ∨
          True ∧ (zeroExtend 32 x % 10#32).uaddOverflow (zeroExtend 32 x) = true →
      False

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

theorem test8_thm (e e_1 : IntW 32) :
  trunc 64 (LLVM.or (shl (zext 128 e_1) (const? 128 32)) (zext 128 e)) ⊑
    LLVM.or (shl (zext 64 e_1) (const? 64 32) { «nsw» := false, «nuw» := true }) (zext 64 e)
      { «disjoint» := true }

theorem test_shl__all_are_safe_proof : test_shl__all_are_safe_before ⊑ test_shl__all_are_safe_after

theorem PR38021_proof : PR38021_before ⊑ PR38021_after

theorem e_1675 :
    1 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) + 2 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) + 11 * (b ^^^ (a &&& ( ~~~b ||| c))) - 1 *  ~~~(b ^^^ c) + 2 *  ~~~(a &&&  ~~~a) + 1 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) - 6 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 6 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) - 11 *  ~~~( ~~~a &&& (b ||| c)) - 2 * b + 1 * (a ||| (b &&& c)) - 7 * (a &&& (b ||| c)) + 1 * (b ^^^ ( ~~~a ||| (b ||| c))) - 11 * (c |||  ~~~(a ^^^ b)) - 1 * ((b &&& c) ||| (a &&& (b ||| c))) - 3 * (c &&&  ~~~(a &&&  ~~~b)) - 1 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) - 2 * (c &&&  ~~~(a ^^^ b)) + 22 *  ~~~(a ||| (b ||| c)) - 8 *  ~~~(a ||| ( ~~~b ||| c)) + 4 *  ~~~( ~~~a ||| (b ||| c)) + 15 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 12 * ( ~~~a &&& ( ~~~b &&& c)) + 17 * ( ~~~a &&& (b &&& c)) + 22 * (a &&& ( ~~~b &&& c)) + 32 * (a &&& (b &&& c)) = 6 * (c &&& (a ^^^ b)) - 2 *  ~~~(a ^^^ ( ~~~b &&& c))

theorem sext_shl_trunc_smaller_proof : sext_shl_trunc_smaller_before ⊑ sext_shl_trunc_smaller_after

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

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

theorem ule_bignum_proof : ule_bignum_before ⊑ ule_bignum_after

theorem t7_ashr_proof : t7_ashr_before ⊑ t7_ashr_after

theorem n14_wrong_comparison_constant_proof : n14_wrong_comparison_constant_before ⊑ n14_wrong_comparison_constant_after

theorem sub_from_constant_proof : sub_from_constant_before ⊑ sub_from_constant_after

theorem or_ne_notY_eq_1s_proof : or_ne_notY_eq_1s_before ⊑ or_ne_notY_eq_1s_after

theorem substitute_constant_and_eq_eq_commute_logical_proof : substitute_constant_and_eq_eq_commute_logical_before ⊑ substitute_constant_and_eq_eq_commute_logical_after

theorem ashrsgt_01_01_proof : ashrsgt_01_01_before ⊑ ashrsgt_01_01_after

theorem n1_proof : n1_before ⊑ n1_after

theorem icmp_eq_sext_ne_allones_proof : icmp_eq_sext_ne_allones_before ⊑ icmp_eq_sext_ne_allones_after

theorem t0_thm (e e_1 e_2 : IntW 8) : sub (sub e_2 e_1) e ⊑ sub e_2 (add e_1 e)

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

theorem test2_proof : test2_before ⊑ test2_after

theorem t0_proof : t0_before ⊑ t0_after

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

theorem test19_proof : test19_before ⊑ test19_after

theorem lshr_32_add_known_32_leading_zeroes_proof : lshr_32_add_known_32_leading_zeroes_before ⊑ lshr_32_add_known_32_leading_zeroes_after

theorem isRefinedBy_ite_iff {x? y? z? : PoisonOr α} :
    x? ⊑ ite c y? z?
    ↔ let c := c
      (c → x? ⊑ y?) ∧ (¬c → x? ⊑ z?)

theorem not_cond_proof : not_cond_before ⊑ not_cond_after

theorem test_shl_nuw__none_are_safe_proof : test_shl_nuw__none_are_safe_before ⊑ test_shl_nuw__none_are_safe_after

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

theorem scalar_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 4),
  (x_2 ^^^ x_1) &&& (x ^^^ -1#4) ^^^ x_1 = (x_2 ^^^ x_1) &&& x ^^^ x_2

theorem xor_and_or_proof : xor_and_or_before ⊑ xor_and_or_after

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

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

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 shl_nsw_sgt_n1_proof : shl_nsw_sgt_n1_before ⊑ shl_nsw_sgt_n1_after

@[simp]
lemma CNFA.SignedCmp_states cmp : s ∈ (autSignedCmp cmp).m.states ↔  s < 5

theorem xor_signbit_select_ashr_proof : xor_signbit_select_ashr_before ⊑ xor_signbit_select_ashr_after

theorem not_and_and_or_not_or_or_proof : not_and_and_or_not_or_or_before ⊑ not_and_and_or_not_or_or_after

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

theorem lshr_ne_opposite_msb_thm (e : IntW 8) :
  icmp IntPred.ne (lshr (const? 8 (-128)) e) (const? 8 1) ⊑ icmp IntPred.ne e (const? 8 7)

private theorem if_else_if_then_poison_eq {α : Type} (c₁ c₂ : Prop) [Decidable c₁] [Decidable c₂]
      (x y : PoisonOr α):
    (if c₁ then x else (if c₂ then poison else y)) =
    (if ¬c₁ ∧ c₂ then poison else (if c₁ then x else y))

@[simp] theorem tail_corec : tail (corec b f) = corec (f b).snd f

theorem lowmask_or_zext_commute_proof : lowmask_or_zext_commute_before ⊑ lowmask_or_zext_commute_after

theorem icmp_select_var_both_fold_proof : icmp_select_var_both_fold_before ⊑ icmp_select_var_both_fold_after

theorem test16_thm (e e_1 : IntW 32) :
  add (add e_1 (const? 32 1) { «nsw» := true, «nuw» := false })
      (LLVM.xor (LLVM.and e (const? 32 (-1431655767))) (const? 32 (-1431655767))) { «nsw» := true, «nuw» := false } ⊑
    sub e_1 (LLVM.or e (const? 32 1431655766))

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

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 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 ashrsgt_02_01_thm.extracted_1._1 : ∀ (x : BitVec 4), ¬2#4 ≥ ↑4 → ofBool (1#4 <ₛ x.sshiftRight' 2#4) = 0#1

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

theorem no_masks_with_logical_or_thm.extracted_1._3 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 != 0#32) = 1#1 → ofBool (x_2 ||| x != 0#32) = 1#1 → 1#1 ||

theorem shl_C1_add_A_C2_i32_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬zeroExtend 32 x + 5#32 ≥ ↑32 → True ∧ x.msb = true ∨ zeroExtend 32 x ≥ ↑32 → False

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

theorem ashr_ult_4_proof : ashr_ult_4_before ⊑ ashr_ult_4_after

theorem n7_wrong_pred2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x_1 - x == x_1) = ofBool (x == 0#8)

theorem e_1398 :
    7 *  ~~~z - 1 *  ~~~(z &&&  ~~~t) + 2 *  ~~~(z &&& t) + 7 *  ~~~(z &&&  ~~~z) + 3 *  ~~~(z ^^^ t) - 2 * z - 18 *  ~~~(z ||| t) - 21 *  ~~~(z |||  ~~~t) - 13 * (z &&&  ~~~t) - 10 * (z &&& t) =  - 3 * (z ||| t) - 3 * (z ^^^ t)

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

@[simp]
lemma determinize_deternistic (M : NFA α σ) :
    M.toDFA.toNFA.Deterministic

lemma mem_varsFinset [DecidableEq α] {c : Circuit α} :
    ∀ {x : α}, x ∈ c.varsFinset ↔ x ∈ c.vars

theorem test0_thm (e : IntW 1) : LLVM.xor e (const? 1 0) ⊑ e

theorem basic_com_add_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), x_1 + (x ^^^ -1#8) ^^^ -1#8 = x - x_1

theorem not_true_not_proof : not_true_not_before ⊑ not_true_not_after

theorem sge_or_max_proof : sge_or_max_before ⊑ sge_or_max_after

theorem fold_sext_to_and_wrong_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x &&& BitVec.ofInt 32 (-2147483647) == -1#32) = 0#1

theorem e_630 :
    1 *  ~~~(x &&&  ~~~x) + 7 *  ~~~(x &&& y) + 7 * (x ^^^ y) - 1 *  ~~~(x ^^^ y) - 5 * y - 7 *  ~~~x - 2 *  ~~~y + 2 *  ~~~(x ||| y) - 8 *  ~~~(x |||  ~~~y) - 18 * (x &&&  ~~~y) =  - 5 * (x ||| y)

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 shl_mask_weird_type_thm.extracted_1._1 : ∀ (x : BitVec 37),
  ¬8#37 ≥ ↑37 →
    True ∧ ((x &&& 255#37) <<< 8#37).sshiftRight' 8#37 ≠ x &&& 255#37 ∨
        True ∧ (x &&& 255#37) <<< 8#37 >>> 8#37 ≠ x &&& 255#37 ∨
          8#37 ≥ ↑37 ∨ True ∧ (x &&& 255#37 &&& (x &&& 255#37) <<< 8#37 != 0) = true →
      False

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

theorem test_sub__all_are_safe_proof : test_sub__all_are_safe_before ⊑ test_sub__all_are_safe_after

@[simp] theorem bind_poison : a? >>= (fun _ => @poison β) = poison

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

@[simp_denote] theorem HVector.cons_inj {α : Type u_1} {f : α → Type u_2}
    {as : List α} {a : α}  (x y : f a) (xs ys : HVector f as) :
    @Eq (no_index _) (x ::ₕ xs) (y ::ₕ ys) ↔ (x = y ∧ xs = ys)

theorem or_simplify_ugt_fail_proof : or_simplify_ugt_fail_before ⊑ or_simplify_ugt_fail_after

theorem Tensor2d'.map_functorial (g : β → γ) (f : α → β) (t : Tensor2d' α) :
  t.map (g ∘ f) = (t.map f).map g

theorem slt_zero_ne_ne_b_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (zext 32 (icmp IntPred.ne e_1 e)) (lshr e_1 (const? 32 31)) ⊑
    LLVM.xor (icmp IntPred.slt e_1 (const? 32 0)) (icmp IntPred.ne e_1 e)

theorem e_597 :
    7 *  ~~~x + 3 *  ~~~y + 5 *  ~~~(x ^^^ y) - 1 * (x ^^^ y) - 5 *  ~~~(x &&&  ~~~y) + 1 *  ~~~(x &&& y) + 2 * (x |||  ~~~y) - 16 *  ~~~(x ||| y) - 5 *  ~~~(x |||  ~~~y) - 8 * (x &&&  ~~~y) = 5 * (x &&& y) - 3 *  ~~~(x &&&  ~~~x)

theorem add_umin_constant_limit_proof : add_umin_constant_limit_before ⊑ add_umin_constant_limit_after

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

theorem lor_land_right1_proof : lor_land_right1_before ⊑ lor_land_right1_after

theorem icmp_eq_zext_eq_zero_proof : icmp_eq_zext_eq_zero_before ⊑ icmp_eq_zext_eq_zero_after

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

theorem e_1549 :
     - 1 * ((a &&& c) ||| (b &&&  ~~~c)) + 1 * (b ^^^  ~~~(a &&& (b ||| c))) + 1 * ((a &&& c) |||  ~~~(b ||| c)) + 3 * ((a ||| b) &&&  ~~~(b ^^^ c)) + 5 * (c ||| (a &&&  ~~~b)) + 11 * (c ^^^ ( ~~~a ||| (b ||| c))) - 10 *  ~~~(a ||| ( ~~~b ||| c)) - 10 *  ~~~( ~~~a ||| (b ||| c)) - 11 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 6 * ( ~~~a &&& ( ~~~b &&& c)) - 8 * ( ~~~a &&& (b &&& c)) - 5 * (a &&& ( ~~~b &&& c)) - 9 * (a &&& (b &&& c)) = 13 *  ~~~(a ||| (b ||| c))

theorem t13_x_is_one_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬(32#32 - x_1 ≥ ↑32 ∨ zeroExtend 64 (x_1 + BitVec.ofInt 32 (-16)) ≥ ↑64) →
    ofBool (1#32 <<< (32#32 - x_1) &&& truncate 32 (x >>> zeroExtend 64 (x_1 + BitVec.ofInt 32 (-16))) != 0#32) =
      ofBool (x &&& 65536#64 != 0#64)

theorem ult_umin3_proof : ult_umin3_before ⊑ ult_umin3_after

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

theorem slt_swap_or_not_max_commute_proof : slt_swap_or_not_max_commute_before ⊑ slt_swap_or_not_max_commute_after

theorem test6_thm (e : IntW 1023) :
  select (icmp IntPred.ne (LLVM.and e (const? 1023 64)) (const? 1023 0)) (const? 1023 64) (const? 1023 0) ⊑
    LLVM.and e (const? 1023 64)

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

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

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

theorem ult_umin3_proof : ult_umin3_before ⊑ ult_umin3_after

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

theorem add_nosignbit_shl_thm (e : IntW 32) :
  shl (add e (const? 32 2147418112)) (const? 32 8) ⊑ add (shl e (const? 32 8)) (const? 32 (-16777216))

theorem andn_or_cmp_2_logical_proof : andn_or_cmp_2_logical_before ⊑ andn_or_cmp_2_logical_after

theorem AvoidCollision_toFin_signExtend_of_le {x : BitVec w} (hv : v ≤ w):
    (x.signExtend v).toFin = Fin.ofNat (2 ^ v) x.toNat

theorem ne_smax1_proof : ne_smax1_before ⊑ ne_smax1_after

theorem not_mul_of_bool_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  True ∧ (x_1 &&& 3#32).smulOverflow (zeroExtend 32 x) = true ∨
      True ∧ (x_1 &&& 3#32).umulOverflow (zeroExtend 32 x) = true →
    False

theorem t0_commutative_proof : t0_commutative_before ⊑ t0_commutative_after

theorem e_2218 :
    4 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 2 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 5 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 1 * ( ~~~d &&& (e ^^^ f)) + 7 * (f ^^^ (d ||| ( ~~~e ||| f))) - 1 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 2 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 2 * (d ||| ( ~~~e ||| f)) + 1 * (d ||| (e ^^^ f)) - 11 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 7 *  ~~~(d &&& ( ~~~e &&& f)) + 5 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 5 * (e ^^^  ~~~(d ||| f)) - 2 * (e |||  ~~~(d ^^^ f)) + 1 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 6 * (d &&& (e ^^^ f)) - 1 * (e ^^^ (d ||| (e ^^^ f))) - 2 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 3 * (e ^^^ ( ~~~d ||| (e &&& f))) - 1 * (f ||| (d &&& e)) + 7 *  ~~~(d |||  ~~~f) + 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 1 * (e ^^^ (d |||  ~~~f)) + 2 * (f ^^^  ~~~(d &&& (e &&& f))) + 1 * ( ~~~d &&& (e ||| f)) + 2 * ( ~~~e &&& (d ^^^ f)) - 7 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 5 *  ~~~(d |||  ~~~e) + 2 * (f ^^^  ~~~(d ||| e)) + 1 * ( ~~~d ||| (e ||| f)) - 6 * (f &&&  ~~~(d &&& e)) + 11 * (f ||| (d &&&  ~~~e)) + 2 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 3 *  ~~~d - 7 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * (f ^^^  ~~~(d &&& (e ||| f))) - 7 * (e ^^^  ~~~(d &&& (e &&& f))) + 2 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 11 *  ~~~(e ^^^ f) - 1 * (d ^^^ (e ||| f)) + 3 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 5 * (f |||  ~~~(d ||| e)) - 2 * (f ^^^ (d &&& e)) - 11 * (e &&& f) + 31 *  ~~~(d ||| (e ||| f)) - 20 *  ~~~( ~~~d ||| (e ||| f)) + 33 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 13 * ( ~~~d &&& ( ~~~e &&& f)) + 18 * ( ~~~d &&& (e &&& f)) + 22 * (d &&& ( ~~~e &&& f)) + 19 * (d &&& (e &&& f)) = 11 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f)))

theorem hoist_ashr_ahead_of_sext_2_proof : hoist_ashr_ahead_of_sext_2_before ⊑ hoist_ashr_ahead_of_sext_2_after

theorem sub_ashr_and_i64_proof : sub_ashr_and_i64_before ⊑ sub_ashr_and_i64_after

theorem uge_swap_or_not_max_commute_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.ne e_1 (const? 8 (-1))) (icmp IntPred.ule e e_1) ⊑ const? 1 1

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

theorem c_0_1_0_proof : c_0_1_0_before ⊑ c_0_1_0_after

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

theorem shl_trunc_bigger_ashr_thm (e : IntW 32) :
  shl (trunc 24 (ashr e (const? 32 12))) (const? 24 3) ⊑
    LLVM.and (trunc 24 (ashr e (const? 32 9)) { «nsw» := true, «nuw» := false }) (const? 24 (-8))

theorem test31_thm (e : IntW 1) :
  LLVM.and (shl (zext 32 e) (const? 32 4)) (const? 32 16) ⊑ select e (const? 32 16) (const? 32 0)

theorem shl_add_nsw_nuw_proof : shl_add_nsw_nuw_before ⊑ shl_add_nsw_nuw_after

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

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

theorem e_1803 :
    3 * (b &&& (a |||  ~~~c)) + 7 * (b &&&  ~~~(a &&& c)) + 1 * (a ||| (b ^^^ c)) - 1 * (a &&& ( ~~~b ||| c)) - 1 * (b |||  ~~~(a |||  ~~~c)) + 11 * ((a &&& b) ^^^  ~~~(a ^^^ (b &&& c))) - 7 * (c ^^^ (a &&& b)) - 3 * (c ^^^ ( ~~~a &&& (b ||| c))) - 7 *  ~~~(b ||| c) - 7 * (b ^^^  ~~~(a ||| c)) + 7 * ((a &&& b) |||  ~~~(b ||| c)) + 1 * (b &&& (a ^^^ c)) - 7 *  ~~~( ~~~a &&& (b &&& c)) + 1 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) - 6 * (c ^^^ (a &&& ( ~~~b ||| c))) + 4 *  ~~~(a ||| (b &&& c)) - 11 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 3 *  ~~~( ~~~a &&& ( ~~~b &&& c)) - 11 * (a &&& b) + 7 * (c ^^^ (a ||| (b ||| c))) - 2 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) - 11 * (c ||| (a ^^^ b)) + 4 * ( ~~~a ||| (b ^^^ c)) - 1 * ( ~~~b &&& (a ^^^ c)) - 1 * (a ||| c) + 1 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 2 * (c ^^^ (a |||  ~~~b)) + 7 *  ~~~(a ||| b) + 4 * (a ^^^ ( ~~~b ||| c)) + 4 * (a ||| (b &&& c)) - 1 * (b ^^^ (a ||| (b &&& c))) - 1 * (c &&&  ~~~(a &&& b)) - 4 *  ~~~(a ||| (b ||| c)) - 12 *  ~~~(a ||| ( ~~~b ||| c)) + 26 *  ~~~( ~~~a ||| (b ||| c)) - 16 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 3 * ( ~~~a &&& ( ~~~b &&& c)) + 12 * ( ~~~a &&& (b &&& c)) + 34 * (a &&& ( ~~~b &&& c)) + 30 * (a &&& (b &&& c)) =  - 1 * (b ||| c)

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

theorem eq_21_comm_eq_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(16#32 ≥ ↑32 ∨ 16#32 ≥ ↑32 ∨ 8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32) →
    ¬(8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32) →
      ofBool (truncate 8 (x_1 >>> 16#32) == truncate 8 (x >>> 16#32)) &&&
          ofBool (truncate 8 (x >>> 8#32) == truncate 8 (x_1 >>> 8#32)) =
        ofBool (truncate 16 (x_1 >>> 8#32) == truncate 16 (x >>> 8#32))

theorem ashr_ult_11_proof : ashr_ult_11_before ⊑ ashr_ult_11_after

theorem or_ranges_single_elem_right_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (5#8 ≤ᵤ x) &&& ofBool (x ≤ᵤ 10#8) ||

theorem main9_logical_proof : main9_logical_before ⊑ main9_logical_after

theorem alive_AndOrXor_135  (w : Nat)   : alive_AndOrXor_135_src w  ⊑ alive_AndOrXor_135_tgt w

theorem sext_zext_apint2_thm.extracted_1._1 : ∀ (x : BitVec 11), signExtend 47 (zeroExtend 39 x) = zeroExtend 47 x

theorem positive_with_aggressive_icmp_proof : positive_with_aggressive_icmp_before ⊑ positive_with_aggressive_icmp_after

theorem test_sext1_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → 0#32 = signExtend 32 0#1

theorem or_not_xor_common_op_commute7_proof : or_not_xor_common_op_commute7_before ⊑ or_not_xor_common_op_commute7_after

theorem zext_sext_add_icmp_slt_minus1_proof : zext_sext_add_icmp_slt_minus1_before ⊑ zext_sext_add_icmp_slt_minus1_after

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 shl_nsw_nuw_uge_Csle0_thm (e e_1 : IntW 8) :
  icmp IntPred.uge (shl e_1 e { «nsw» := true, «nuw» := true }) (const? 8 (-120)) ⊑
    icmp IntPred.ugt e_1 (const? 8 (-121))

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

theorem slt_to_ugt_thm (e e_1 : IntW 8) :
  icmp IntPred.slt (LLVM.xor e_1 (const? 8 127)) (LLVM.xor e (const? 8 127)) ⊑ icmp IntPred.ugt e_1 e

theorem foo1_proof : foo1_before ⊑ foo1_after

theorem icmp_shl_ne_2_thm (e : IntW 8) :
  icmp IntPred.ne (LLVM.sdiv (const? 8 42) e) (shl (LLVM.sdiv (const? 8 42) e) (const? 8 1)) ⊑
    icmp IntPred.ne (LLVM.sdiv (const? 8 42) e) (const? 8 0)

theorem test35_with_trunc_proof : test35_with_trunc_before ⊑ test35_with_trunc_after

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

theorem e_11 :
    7 *  ~~~(x &&& y) - 1 *  ~~~y - 6 *  ~~~x - 1 *  ~~~(x |||  ~~~y) = 6 * (x &&&  ~~~y)

theorem ofBitVec_sub' {w : Nat} {i : Nat} {hi : i < w} (x y : BitVec w) :
    ofBitVecSext (x - y) i = ((ofBitVecSext x) - (ofBitVecSext y)) i

theorem main7e_logical_proof : main7e_logical_before ⊑ main7e_logical_after

theorem src_is_notmask_sext_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 16),
  ¬x ≥ ↑8 →
    ofBool (x_1 ^^^ 123#16 ≤ᵤ (signExtend 16 (BitVec.ofInt 8 (-8) <<< x) ^^^ -1#16) &&& (x_1 ^^^ 123#16)) =
      ofBool (signExtend 16 (BitVec.ofInt 8 (-8) <<< x) ≤ᵤ x_1 ^^^ BitVec.ofInt 16 (-128))

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

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

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

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

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

@[simp, simp_denote, simp_sllvm]
lemma run_map (x : EffectM α) :
    StateT.run (f <$> x : EffectM β) s = (fun p => (f p.1, p.2)) <$> StateT.run x s

@[simp] theorem map'_nil : map' f g nil = nil

theorem test13_proof : test13_before ⊑ test13_after

theorem n1_proof : n1_before ⊑ n1_after

theorem substitute_constant_and_ne_ugt_swap_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x <ᵤ x_1) = 1#1 → 0#1 = ofBool (x <ᵤ x_1) &&& ofBool (x != 42#8)

theorem nonexact_ashr_ne_exactdiv_proof : nonexact_ashr_ne_exactdiv_before ⊑ nonexact_ashr_ne_exactdiv_after

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

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

theorem lshr_shl_demand4_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ 3#8 ≥ ↑8) → x ≥ ↑8 ∨ 3#8 ≥ ↑8 ∨ True ∧ (60#8 >>> x <<< 3#8 &&& 7#8 != 0) = true → False

theorem a_true_implies_b_true2_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 8),
  ofBool (10#8 <ᵤ x_1) = 1#1 → ofBool (20#8 <ᵤ x_1) = 1#1 → ofBool (20#8 <ᵤ x_1) &&& x = x

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

theorem R.trimTensor_toTensor'_eq_trimTensor_toTensor [Fact (q > 1)] (a : R q n) :
  trimTensor a.toTensor' = trimTensor a.toTensor

@[simp] theorem dropUntilHom_last : dropUntilHom (v := Var.last Γ ty) = Hom.id.consRight

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

theorem add_select_sext_proof : add_select_sext_before ⊑ add_select_sext_after

theorem or_ugt_proof : or_ugt_before ⊑ or_ugt_after

theorem positive_with_icmp_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.ult e (const? 32 512)) (icmp IntPred.ult (add e (const? 32 128)) (const? 32 256)) ⊑
    icmp IntPred.ult e (const? 32 128)

theorem fake_sext_thm.extracted_1._2 : ∀ (x : BitVec 3),
  ¬17#18 ≥ ↑18 → ¬(2#3 ≥ ↑3 ∨ True ∧ (x >>> 2#3).msb = true) → signExtend 18 x >>> 17#18 = zeroExtend 18 (x >>> 2#3)

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

theorem e_1592 :
     - 1 * ( ~~~b &&&  ~~~(a ^^^ c)) + 11 * (b ^^^ (a ||| (b &&& c))) - 6 * (b ^^^  ~~~(a |||  ~~~c)) + 1 * (c |||  ~~~(a ^^^ b)) + 11 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) - 11 * (b ^^^ ( ~~~a ||| (b ||| c))) - 6 * (c |||  ~~~(a ||| b)) + 5 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) - 6 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) + 1 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) + 2 * (c ^^^ (a &&& (b ||| c))) + 11 * (b ^^^  ~~~(a &&& (b &&& c))) - 11 * (a &&& b) - 16 *  ~~~(a ||| ( ~~~b ||| c)) - 27 *  ~~~( ~~~a ||| (b ||| c)) + 15 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 3 * ( ~~~a &&& ( ~~~b &&& c)) - 1 * (a &&& (b &&& c)) = 8 * ( ~~~a &&& (b &&& c))

theorem bools2_logical_commute1_and2_thm.extracted_1._7 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 → ¬x_1 = 1#1 → (x_1 ^^^ 1#1) &&& x = x

theorem or_not_xor_common_op_commute2_proof : or_not_xor_common_op_commute2_before ⊑ or_not_xor_common_op_commute2_after

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

theorem ashrsgt_01_03_thm (e : IntW 4) : icmp IntPred.sgt (ashr e (const? 4 1)) (const? 4 3) ⊑ const? 1 0

theorem shl_nsw_nuw_poison_constant_fold_thm (e : IntW 8) (e_1 : IntW 1) :
  shl (const? 8 16) (select e_1 (const? 8 3) e) { «nsw» := true, «nuw» := true } ⊑
    select e_1 (const? 8 (-128)) (shl (const? 8 16) e { «nsw» := true, «nuw» := true })

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

theorem test_and4_logical_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sge (LLVM.and e_1 (const? 32 2147483647)) e) (icmp IntPred.sge e (const? 32 0))
      (const? 1 0) ⊑
    icmp IntPred.ule e (LLVM.and e_1 (const? 32 2147483647))

theorem select_1_thm.extracted_1._13 : ∀ (x x_1 x_2 x_3 : BitVec 8) (x_4 : BitVec 1),
  x_4 = 1#1 → x_3 ^^^ (x_2 ^^^ 45#8) ^^^ -1#8 = x_2 ^^^ x_3 ^^^ BitVec.ofInt 8 (-46)

theorem ule_umax1_proof : ule_umax1_before ⊑ ule_umax1_after

theorem scalar_i16_shl_and_negC_eq_proof : scalar_i16_shl_and_negC_eq_before ⊑ scalar_i16_shl_and_negC_eq_after

theorem test35_with_trunc_thm (e : IntW 64) :
  select (icmp IntPred.sge (trunc 32 e) (const? 32 0)) (const? 32 60) (const? 32 100) ⊑
    select (icmp IntPred.eq (LLVM.and e (const? 64 2147483648)) (const? 64 0)) (const? 32 60)
      (const? 32 100)

theorem prove_exact_with_high_mask_limit_proof : prove_exact_with_high_mask_limit_before ⊑ prove_exact_with_high_mask_limit_after

theorem eq_commuted_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(x == 0 || 8 != 1 && 43#8 == intMin 8 && x == -1) = true →
    ofBool (x_1 == 0#8) ||

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

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

theorem PR42691_9_logical_proof : PR42691_9_logical_before ⊑ PR42691_9_logical_after

theorem select_2_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 x_2 : BitVec 1),
  x_2 = 1#1 ∧ x_1 = 1#1 → x ^^^ -1#8 ^^^ -1#8 = x

theorem or_and_or_pat8_proof : or_and_or_pat8_before ⊑ or_and_or_pat8_after

theorem prove_exact_with_high_mask_limit_thm (e : IntW 8) : LLVM.sdiv (LLVM.and e (const? 8 (-8))) (const? 8 8) ⊑ ashr e (const? 8 3)

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

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

theorem lshrugt_03_13_exact_proof : lshrugt_03_13_exact_before ⊑ lshrugt_03_13_exact_after

theorem and_ranges_signed_pred_proof : and_ranges_signed_pred_before ⊑ and_ranges_signed_pred_after

theorem e_1907 :
     - 2 * (a &&& ( ~~~b ||| c)) + 7 * ((a &&& c) |||  ~~~(b ||| c)) - 6 * ( ~~~a ||| (b ||| c)) + 11 * (b ^^^ (a ||| (b ||| c))) - 7 * (a &&& (b ^^^ c)) - 11 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) + 2 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 2 * (b ^^^ (a ||| (b &&& c))) + 1 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 5 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) + 2 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) + 1 * (c &&& (a ||| b)) - 11 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) + 1 *  ~~~(a &&& (b ||| c)) + 11 * ((a &&& c) ||| (b &&&  ~~~c)) - 1 *  ~~~(a ^^^ ( ~~~b ||| c)) - 7 *  ~~~(b ^^^ c) - 5 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) + 2 * (c ^^^ (a ||| ( ~~~b ||| c))) + 2 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 6 *  ~~~( ~~~a &&& ( ~~~b ||| c)) - 2 * (b ^^^ (a &&&  ~~~c)) - 2 * (b ^^^  ~~~(a |||  ~~~c)) + 3 *  ~~~c - 6 *  ~~~(b &&&  ~~~c) - 7 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) + 1 *  ~~~( ~~~a &&& ( ~~~b &&& c)) - 3 *  ~~~(a &&&  ~~~a) + 11 * (b &&&  ~~~c) + 4 *  ~~~( ~~~a ||| (b &&& c)) - 5 * (b &&& c) - 6 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 1 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) + 5 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 7 * (c ^^^  ~~~(a ||| b)) - 2 * (c ^^^  ~~~(a &&& b)) + 3 * (c ^^^ ( ~~~a ||| (b ||| c))) + 4 * (c ^^^  ~~~(a &&& (b &&& c))) + 5 * (a |||  ~~~c) - 2 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) - 2 * ((b &&& c) ||| (a &&& (b ||| c))) + 2 *  ~~~(a ||| (b &&& c)) - 1 * ((a &&&  ~~~b) ||| (b ^^^ c)) + 14 *  ~~~(a ||| (b ||| c)) + 9 *  ~~~(a ||| ( ~~~b ||| c)) + 7 *  ~~~( ~~~a ||| (b ||| c)) + 18 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 39 * ( ~~~a &&& ( ~~~b &&& c)) + 64 * ( ~~~a &&& (b &&& c)) + 25 * (a &&& (b &&& c)) =  - 14 * (a &&& ( ~~~b &&& c))

@[simp] lemma eval_simplify :
    p.simplify.eval = p.eval

theorem positive_samevar_shlnuwnsw_lshrexact_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ x_1 >>> x <<< x ≠ x_1 ∨
        x ≥ ↑8 ∨
          True ∧ (x_1 >>> x <<< x).sshiftRight' x ≠ x_1 >>> x ∨ True ∧ x_1 >>> x <<< x >>> x ≠ x_1 >>> x ∨ x ≥ ↑8) →
    x_1 >>> x <<< x = x_1

theorem shl1_trunc_eq0_proof : shl1_trunc_eq0_before ⊑ shl1_trunc_eq0_after

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

theorem test4_apint_proof : test4_apint_before ⊑ test4_apint_after

theorem ashrsgt_02_14_exact_thm (e : IntW 4) :
  icmp IntPred.sgt (ashr e (const? 4 2) { «exact» := true }) (const? 4 (-2)) ⊑
    icmp IntPred.ne e (const? 4 (-8))

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

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

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

theorem testtrunclowhigh_thm (e e_1 : IntW 16) (e_2 : IntW 32) :
  select (icmp IntPred.ult (add e_2 (const? 32 128)) (const? 32 256)) (trunc 16 e_2)
      (select (icmp IntPred.sgt e_2 (const? 32 (-1))) e_1 e) ⊑
    select (icmp IntPred.ult (add e_2 (const? 32 128)) (const? 32 256)) (trunc 16 e_2)
      (select (icmp IntPred.slt e_2 (const? 32 0)) e e_1)

theorem or2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 64), x_1 &&& x ||

theorem prove_exact_with_high_mask_proof : prove_exact_with_high_mask_before ⊑ prove_exact_with_high_mask_after

theorem test3_thm (e : IntW 8) :
  icmp IntPred.sge e (const? 8 (-127)) ⊑ icmp IntPred.ne e (const? 8 (-128))

theorem e_268 :
    5 * (x ||| y) + 1 *  ~~~(x &&&  ~~~y) - 1 *  ~~~y + 4 *  ~~~(x &&&  ~~~x) - 4 *  ~~~(x ||| y) - 10 *  ~~~(x |||  ~~~y) - 10 * (x &&& y) = 8 * (x &&&  ~~~y)

@[simp]
lemma proj_accepts (M : NFA' m) (f : Fin n → Fin m) :
    (M.proj f).accepts = BitVecs.transport f '' M.accepts

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

theorem lowmask_xor_zext_commute_proof : lowmask_xor_zext_commute_before ⊑ lowmask_xor_zext_commute_after

theorem icmp_select_var_pred_uge_proof : icmp_select_var_pred_uge_before ⊑ icmp_select_var_pred_uge_after

theorem sle_smax4_proof : sle_smax4_before ⊑ sle_smax4_after

theorem e_1435 :
    2 *  ~~~(z &&&  ~~~z) + 1 * z + 3 *  ~~~(z ^^^ t) + 4 * t - 1 *  ~~~t - 1 *  ~~~(z &&& t) + 3 *  ~~~(z ||| t) - 16 *  ~~~(z |||  ~~~t) - 6 * (z &&&  ~~~t) - 15 * (z &&& t) =  - 11 * (z ||| t) + 6 * (z |||  ~~~t)

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 n14_wrong_comparison_constant_thm (e : IntW 8) :
  select (icmp IntPred.eq (LLVM.and e (const? 8 15)) (const? 8 1)) e
      (LLVM.and (add e (const? 8 16)) (const? 8 (-16))) ⊑
    select (icmp IntPred.eq (LLVM.and e (const? 8 15)) (const? 8 1)) e
      (add (LLVM.and e (const? 8 (-16))) (const? 8 16))

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

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

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

theorem zext_sub_proof : zext_sub_before ⊑ zext_sub_after

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

theorem test18_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 32),
  ofBool (x &&& 4#16 != 0#16) = 1#1 → ofBool (x &&& 4#16 == 0#16) = 1#1 → ¬32#32 = 0 → x_1 % 32#32 = x_1 &&& 63#32

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

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

theorem self_EqualUpTo_ofBitVecZext_toBitVec (x : BitStream) :
  EqualUpTo w x (BitStream.ofBitVecZext (x.toBitVec w))

theorem masked_icmps_mask_notallzeros_bmask_mixed_4_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.ne (LLVM.and e (const? 32 255)) (const? 32 0))
      (icmp IntPred.eq (LLVM.and e (const? 32 15)) (const? 32 8)) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 15)) (const? 32 8)

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

theorem bv_AndOrXor_144 :
    ∀ (e e_1 e_2 : LLVM.IntW w), LLVM.and (LLVM.or e e_1) e_2 ⊑ LLVM.and (LLVM.or e (LLVM.and e_1 e_2)) e_2

theorem 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 or_ranges_single_elem_left_proof : or_ranges_single_elem_left_before ⊑ or_ranges_single_elem_left_after

theorem PR23309_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (x_1 + BitVec.ofInt 32 (-4)).ssubOverflow x = true) →
    truncate 1 (x_1 + BitVec.ofInt 32 (-4) - x) = truncate 1 (x_1 - x)

theorem no_shift_xor_multiuse_cmp_xor_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 ^^^ 4096#32) * x * (x_2 ^^^ 4096#32) = x_2 * x_1 * (x_2 ^^^ 4096#32)

theorem e_2319 :
    11 * (e |||  ~~~f) + 1 *  ~~~(d &&& ( ~~~e &&& f)) + 5 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * ( ~~~d ||| (e ||| f)) - 2 * (f ||| (d &&&  ~~~e)) - 7 * (e ^^^ (d &&&  ~~~f)) + 4 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) + 1 * ( ~~~d ||| ( ~~~e ||| f)) - 1 * (d ||| (e &&& f)) + 2 * ( ~~~d ||| (e &&& f)) - 1 * (e ^^^ (d &&& (e ||| f))) - 1 * (f &&&  ~~~(d ^^^ e)) + 3 *  ~~~(d ^^^ f) - 7 * ((d &&& f) ||| (e &&&  ~~~f)) + 7 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 3 * ( ~~~e ||| (d ^^^ f)) + 2 * ( ~~~e |||  ~~~(d ^^^ f)) - 5 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 2 * (e ^^^  ~~~(d &&& (e &&& f))) - 3 *  ~~~(e &&& f) + 1 * (e ^^^  ~~~(d |||  ~~~f)) + 2 * (e ^^^ (d ||| (e ^^^ f))) + 11 * (f ^^^  ~~~(d &&& (e &&& f))) - 11 * (d &&& ( ~~~e ||| f)) + 1 * (f ^^^ (d ||| (e &&& f))) + 2 * (d &&&  ~~~f) + 7 * (f ^^^  ~~~(d &&&  ~~~e)) - 1 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 2 * (e |||  ~~~(d ^^^ f)) - 6 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 5 * (e ^^^ f) + 5 *  ~~~(d ||| (e ^^^ f)) - 2 * (e ^^^  ~~~(d ||| f)) - 6 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 4 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 1 * (d ||| ( ~~~e &&& f)) + 5 * ( ~~~f ||| (d ^^^ e)) - 3 * (e ^^^  ~~~(d ||| (e &&& f))) + 3 * ( ~~~d &&& (e ||| f)) - 1 * (f ^^^ ( ~~~d &&& (e ||| f))) + 5 * (d ^^^ ( ~~~e ||| f)) - 5 * ((d ^^^ e) |||  ~~~(d ^^^ f)) + 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 1 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 7 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 2 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 4 * (e &&& (d ||| f)) - 6 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 1 * (e ^^^ (d ||| (e &&& f))) - 2 *  ~~~(d ^^^ (e ||| f)) + 11 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 7 * ( ~~~d ||| ( ~~~e &&& f)) + 2 * (d ||| e) + 5 *  ~~~(d ||| f) + 11 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 52 *  ~~~(d ||| (e ||| f)) - 5 *  ~~~(d ||| ( ~~~e ||| f)) - 13 *  ~~~( ~~~d ||| (e ||| f)) - 29 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 9 * ( ~~~d &&& ( ~~~e &&& f)) - 33 * ( ~~~d &&& (e &&& f)) + 5 * (d &&& ( ~~~e &&& f)) - 32 * (d &&& (e &&& f)) = 1 * d - 7 * (f ^^^  ~~~(d ||| e))

theorem select_add_icmp_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.eq e_2 (const? 32 0)) (add e_2 e_1) e ⊑
    select (icmp IntPred.eq e_2 (const? 32 0)) e_1 e

theorem uge_and_max_commute_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.eq e_1 (const? 8 (-1))) (icmp IntPred.uge e_1 e) ⊑
    icmp IntPred.eq e_1 (const? 8 (-1))

theorem sle_or_not_min_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.sle e_1 e) (icmp IntPred.ne e_1 (const? 8 (-128))) ⊑ const? 1 1

theorem foo4_proof : foo4_before ⊑ foo4_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

def NFA.sa (_ : NFA α σ) := σ → Language α

structure NFA.correct (M : NFA α σ) (ζ : M.sa) (L : Language α) where
  cond1 : ∀ w, (w ∈ L ↔ ∃ q ∈ M.accept, w ∈ ζ q)
  cond2 : ∀ w q, q ∈ M.eval w ↔ w ∈ ζ q

abbrev BVNRel n := ∀ ⦃w⦄, List.Vector (BitVec w) n → Prop

def NFA'.sa (M : NFA' n) := M.σ → BVNRel n

def langRel (R : BVNRel n) : Set (BitVecs n) :=
  { bvs | R bvs.bvs }

structure NFA'.correct (M : NFA' n) (ζ : M.sa) (L : BVNRel n) where
  cond1 : ∀ ⦃w⦄ (bvn : List.Vector (BitVec w) n), (L bvn ↔ ∃ q ∈ M.M.accept, ζ q bvn)
  cond2 q : q ∈ M.M.start ↔ ζ q (List.Vector.replicate n .nil)
  cond3 q a {w} (bvn : List.Vector (BitVec w) n) : q ∈ M.M.stepSet { q | ζ q bvn } a ↔
              ζ q (List.Vector.ofFn fun k => BitVec.cons (a.getLsbD k) (bvn.get k))

structure NFA'.correct2 (M : NFA' 2) (ζ : M.sa2) (L : BVRel) where
  cond1 : ∀ (bv1 bv2 : BitVec w), (L bv1 bv2 ↔ ∃ q ∈ M.M.accept, ζ q bv1 bv2)
  cond2 q : q ∈ M.M.start ↔ ζ q .nil .nil
  cond3 q a w (bv1 bv2 : BitVec w) : q ∈ M.M.stepSet { q | ζ q bv1 bv2 } a ↔
              ζ q (BitVec.cons (a.getLsbD 0) bv1) (BitVec.cons (a.getLsbD 1) bv2)
</local_ctx>

<target_theorem>
lemma NFA'.correct_spec {M : NFA' n} {ζ : M.sa} {L : BVNRel n} :
    M.correct ζ L → M.accepts = langRel L :=
</target_theorem>

