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

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

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

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

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

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

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

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

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

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

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

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

open Set
open Mathlib
open SetRel

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

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

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

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

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

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

@[simp]
</local_ctx>

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

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

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

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

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

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

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

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

### Your task:
<all_available_defs>
DecidableEq in Init.Prelude
Lean.ToExpr in Lean.ToExpr
List in Init.Prelude
Repr in Init.Data.Repr
Nat in Init.Prelude
AList in Mathlib.Data.List.AList
Option in Init.Prelude
StateT in Init.Control.State
Unit in Init.Prelude
AList.insert in Mathlib.Data.List.AList
String in Init.Prelude
BEq in Init.Prelude
ite in Init.Prelude
Vector in Init.Data.Vector.Basic
Bool in Init.Prelude
Int in Init.Data.Int.Basic
bool in Init.Control.Basic
Computation in Mathlib.Data.Seq.Computation
Valuation.map in Mathlib.RingTheory.Valuation.Basic
Sigma in Init.Core
Sigma.mk in Init.Core
liftM in Init.Prelude
Iff in Init.Core
IsEmpty in Mathlib.Logic.IsEmpty

syntax "neg" : MLIR.Pretty.uniform_op

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

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

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

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

abbrev Mapping (Γ Δ : Ctxt Ty) : Type :=
  @AList (Σ t, Var Γ t) (fun x => Var Δ x.1)

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

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

inductive Lets (Γ_in : Ctxt d.Ty) (eff : EffectKind) :
    (Γ_out : Ctxt d.Ty) → Type where
  | nil : Lets Γ_in eff Γ_in
  | var (body : Lets Γ_in eff Γ_out) (e : Expr d Γ_out eff t) : Lets Γ_in eff e.outContext

protected instance Expr.decidableEq [DecidableEq d.Op] [DecidableEq d.Ty] :
    {Γ : Ctxt d.Ty} → {ty : List d.Ty} → DecidableEq (Expr d Γ eff ty)
  | Γ, _, .mk op₁ rfl eff_le₁ arg₁ regArgs₁, .mk op₂ eq eff_le₂ arg₂ regArgs₂ =>
    if ho : op₁ = op₂ then by
      subst ho
      letI := HVector.decidableEq arg₁ arg₂
      letI := HVector.decidableEqReg regArgs₁ regArgs₂
      exact decidable_of_iff (arg₁ = arg₂ ∧ regArgs₁ = regArgs₂) (by admit /- proof elided -/
      )
    else isFalse (by admit /- proof elided -/
    )

def Var (Γ : Context Ty) (ty : Ty) : Type := { v : VarName // Γ.hasType v ty }

def Valuation.nil : Ctxt.Valuation (∅ : Ctxt Ty) := fun _ v => v.emptyElim

inductive EffectKind
| pure 
| impure 
deriving Repr, DecidableEq, Lean.ToExpr

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

@[match_pattern]
def last (Γ : Ctxt Ty) (t : Ty) : Ctxt.Var (Ctxt.cons t Γ) t :=
  ⟨0, by admit /- proof elided -/
  ⟩

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

protected instance HVector.decidableEqReg [DecidableEq d.Op] [DecidableEq d.Ty] :
    ∀ {l : RegionSignature d.Ty}, DecidableEq (HVector (fun t => Com d t.1 .impure t.2) l)
  | _, .nil, .nil => isTrue rfl
  | _, .cons x₁ v₁, .cons x₂ v₂ =>
    letI := HVector.decidableEqReg v₁ v₂
    letI := Com.decidableEq x₁ x₂
    decidable_of_iff (x₁ = x₂ ∧ v₁ = v₂) (by admit /- proof elided -/
    )

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

def sig          := Signature.sig ∘ s.signature

structure Signature (Ty : Type) where
  mkEffectful ::
  sig         : List Ty
  regSig      : RegionSignature Ty
  returnTypes : List Ty
  effectKind  : EffectKind := .pure

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

def effectKind   := Signature.effectKind ∘ s.signature

def returnTypes  := Signature.returnTypes ∘ s.signature

def Expr.ty : Expr d Γ eff [t] → d.Ty := fun _ => t

def Expr.op {Γ : Ctxt d.Ty} {eff : EffectKind} {ty} (e : Expr d Γ eff ty) : d.Op :=
  Expr.casesOn e (fun op _ _ _ _ => op)

infixr:50 "::ₕ" => HVector.cons

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

def sext_zext_ult_known_nonneg_before := [llvm|
{
^0(%arg12 : i8, %arg13 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.sext %arg12 : i8 to i32
  %2 = llvm.lshr %arg13, %0 : i8
  %3 = llvm.zext %2 : i8 to i32
  %4 = llvm.icmp "ult" %1, %3 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

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

def negate_sdiv_after := [llvm|
{
^0(%arg132 : i8, %arg133 : i8):
  %0 = llvm.mlir.constant(-42 : i8) : i8
  %1 = llvm.sdiv %arg133, %0 : i8
  %2 = llvm.add %1, %arg132 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def slt_zero_slt_i1_fail_after := [llvm|
{
^0(%arg4 : i32, %arg5 : i1):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "slt" %arg4, %0 : i32
  %3 = llvm.xor %arg5, %1 : i1
  %4 = llvm.and %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def t1_flags_nuw_first_before := [llvm|
{
^0(%arg39 : i8, %arg40 : i8, %arg41 : i8):
  %0 = llvm.sub %arg39, %arg40 overflow<nuw> : i8
  %1 = llvm.sub %0, %arg41 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

instance : Lean.ToExpr TestDialect.Op :=

def or2_after := [llvm|
{
^0(%arg676 : i64, %arg677 : i64):
  %0 = llvm.or %arg677, %arg676 : i64
  "llvm.return"(%0) : (i64) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@[simp_denote]
def add_shl_sext_llvm := [LV| {
    ^entry (%a: i32):
    %0 = llvm.mlir.constant (3) : i32
    %1 = llvm.add %a, %0 : i32
    %2 = llvm.shl %1, %a : i32
    %3 = llvm.sext %2 : i32 to i64
    llvm.return %3 : i64
  }]

def genTable.getGenTable (n : Name) (args : Array Expr) : GenM (Option (Array Bool)) := do
  
  
  if n == ``BitVec then
    if hx : args.size ≠ 1 then
      throwError "BitVec expected 1 argument, got {args.size}"
    else
      
      if let some 1 ← Meta.getNatValue? args[0] then
        return some #[false]
      
      return some #[true]
  
  

  let constInfo ← getConstInfo n
  let ty := constInfo.type
  withTraceNode `WidthGeneralize
    (fun _ => return m!"genTable.getGenTable for {n}") do
      forallTelescope ty fun xs ret => do
        trace[WidthGeneralize] m!"getGenTable for {n} : {xs} → {ret}"
        let mut widths : Std.HashSet Expr := {}
        for x in xs do
          let ty ← inferType x
          
          
          
          
          trace[WidthGeneralize] m!"inspecting arg {x} : {ty}"
          widths ← getBitVecTypeWidths ty widths
        
        
        
        
        widths ← getBitVecTypeWidths ret widths
        trace[WidthGeneralize] m!"found concrete widths: {widths.toArray}"
        let mut out := #[]
        for (x, arg) in xs.zip args do
          
          if let some 1 ← getNatValue? arg then
            trace[WidthGeneralize] m!"arg {arg} is BitVec 1, skipping width generalization"
            out := out.push false
            continue
          let x ← whnf x
          let isWidth := widths.contains x
          trace[WidthGeneralize] m!"inspecting concrete arg {x} isWidth: {isWidth}"
          out := out.push isWidth
        trace[WidthGeneralize] m!"genTable for {n} @ {out}"
        return some out

def select_xor_icmp_bad_6_before := [llvm|
{
^0(%arg169 : i32, %arg170 : i32, %arg171 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.icmp "ne" %arg169, %0 : i32
  %2 = llvm.xor %arg169, %arg171 : i32
  %3 = "llvm.select"(%1, %arg170, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

Lean.levelZero in Lean.Level

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

example : rewritePeepholeAt p3 1 ex2 = (
  Com.var (cst  1) <|
     .var (add ⟨0, by simp⟩ ⟨0, by simp⟩  ) <|
     .var (cst  0) <|
     .var (add ⟨0, by simp⟩ ⟨2, by simp⟩  ) <|
     .var (add ⟨0, by simp⟩ ⟨3, by simp⟩  ) <|
     .var (add ⟨4, by simp⟩ ⟨0, by simp⟩  ) <|
     .var (add ⟨1, by simp⟩ ⟨1, by simp⟩  ) <|
     .var (add ⟨1, by simp⟩ ⟨1, by simp⟩  ) <|
     .ret ⟨0, by simp⟩  ) :=

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 test_shl_nsw__nuw_is_safe_before := [llvm|
{
^0(%arg78 : i32, %arg79 : i64):
  %0 = llvm.mlir.constant(1073741822 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.and %arg78, %0 : i32
  %4 = llvm.shl %3, %1 overflow<nsw> : i32
  %5 = llvm.zext %4 : i32 to i64
  %6 = llvm.icmp "eq" %3, %2 : i32
  %7 = llvm.ashr %arg79, %5 : i64
  %8 = "llvm.select"(%6, %arg79, %7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%8) : (i64) -> ()
}
]

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

Fintype in Mathlib.Data.Fintype.Defs

structure NatFSM (wcard tcard bcard ncard icard pcard : Nat) (v : Nondep.WidthExpr) where
  toFsm : FSM (StateSpace wcard tcard bcard ncard icard pcard)

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

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

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 prove_exact_with_high_mask_limit_before := [llvm|
{
^0(%arg6 : i8, %arg7 : i8):
  %0 = llvm.mlir.constant(-8 : i8) : i8
  %1 = llvm.mlir.constant(8 : i8) : i8
  %2 = llvm.and %arg6, %0 : i8
  %3 = llvm.sdiv %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def test6_before := [llvm|
{
^0(%arg17 : i57, %arg18 : i57):
  %0 = llvm.and %arg17, %arg18 : i57
  %1 = llvm.sub %arg17, %0 : i57
  "llvm.return"(%1) : (i57) -> ()
}
]

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

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

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

def or_simplify_uge_before := [llvm|
{
^0(%arg15 : i8, %arg16 : i8, %arg17 : i1):
  %0 = llvm.mlir.constant(-127 : i8) : i8
  %1 = llvm.mlir.constant(127 : i8) : i8
  %2 = llvm.or %arg15, %0 : i8
  %3 = llvm.and %arg16, %1 : i8
  %4 = llvm.or %2, %3 : i8
  %5 = llvm.icmp "uge" %3, %4 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

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

instance : MLIR.AST.TransformReturn (FHE q n) 0 where
  mkReturn := mkReturn

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

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 or_xor_tree_1111_before := [llvm|
{
^0(%arg0 : i32, %arg1 : i32, %arg2 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mul %arg0, %0 : i32
  %2 = llvm.mul %arg1, %0 : i32
  %3 = llvm.mul %arg2, %0 : i32
  %4 = llvm.xor %2, %1 : i32
  %5 = llvm.xor %3, %2 : i32
  %6 = llvm.xor %1, %5 : i32
  %7 = llvm.or %6, %4 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

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

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

def 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 tryFactorization_xor_ashr_ashr_after := [llvm|
{
^0(%arg36 : i32):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.lshr %0, %arg36 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def binop_same_val : List (Σ Γ, RISCVPeepholeRewrite  Γ) :=
    [⟨_, binop_same_val_and⟩,
    ⟨_, binop_same_val_or⟩]

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

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

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

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

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

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

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

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

LawfulHashable in Init.Data.LawfulHashable

def MetaLLVM.instantiate (vals : Vector Expr φ) : DialectMetaMorphism (MetaLLVM φ) q(LLVM) where
  mapTy := fun
  | .bitvec w =>
    mkApp (mkConst ``Ty.bitvec) <| w.metaInstantiate vals
  mapOp :=
    fun
    | .binary w binOp =>
      let w := w.metaInstantiate vals
      mkApp2 (mkConst ``Op.binary) w (toExpr binOp)
    | .unary w unOp =>
      let w := w.metaInstantiate vals

       
      let mapWidth (w : ConcreteOrMVar Nat φ) : Q(ConcreteOrMVar Nat 0) :=
        let w : Q(Nat) := w.metaInstantiate vals
        q(.concrete $w)

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

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

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

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

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 sub_3_before := [llvm|
{
^0(%arg105 : i128, %arg106 : i1, %arg107 : i128, %arg108 : i128):
  %0 = llvm.mlir.constant(-1 : i128) : i128
  %1 = llvm.mlir.constant(123 : i128) : i128
  %2 = llvm.xor %arg107, %0 : i128
  %3 = llvm.xor %arg108, %1 : i128
  %4 = "llvm.select"(%arg106, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i128, i128) -> i128
  %5 = llvm.sub %arg105, %4 : i128
  %6 = llvm.xor %5, %0 : i128
  "llvm.return"(%6) : (i128) -> ()
}
]

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

instance [SIG : DialectSignature d] [DENOTE : DialectDenote d] {Γ : Ctxt d.Ty} {t}
    (com : Com d Γ .pure t) : Inhabited (DCEType com) where
  default :=
    ⟨Γ, Hom.id, com, by admit /- proof elided -/
    ⟩

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

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

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

def getPreconditionSynthesisComponents (positiveExamples negativeExamples: List (Std.HashMap Nat FpExprWrapper)) (specialConstants : Std.HashMap (FpExpr w) FpExprWrapper) :
                  Std.HashMap (FpExpr w)  PreconditionSynthesisCacheValue := Id.run do
    let groupExamplesBySymVar (examples : List (Std.HashMap Nat FpExprWrapper)) : Std.HashMap (FpExpr w) (List FpExprWrapper) := Id.run do
      let mut res : Std.HashMap (FpExpr w) (List FpExprWrapper) := Std.HashMap.emptyWithCapacity
      for ex in examples do
        for (const, val) in ex.toArray do
          let constVar : FpExpr w := FpExpr.var const
          let existingList := res.getD constVar []
          res := res.insert constVar (val::existingList)
      res

    let positiveExamplesByKey := groupExamplesBySymVar positiveExamples
    let negativeExamplesByKey := groupExamplesBySymVar negativeExamples

    let mut allInputs : Std.HashMap (FpExpr w)  PreconditionSynthesisCacheValue := Std.HashMap.emptyWithCapacity
    for key in positiveExamplesByKey.keys do
      allInputs := allInputs.insert key {positiveExampleValues := positiveExamplesByKey[key]!, negativeExampleValues := negativeExamplesByKey[key]!}

    for (sc, val) in specialConstants.toArray do
      allInputs := allInputs.insert sc {positiveExampleValues := List.replicate positiveExamples.length val, negativeExampleValues := List.replicate negativeExamples.length val}

    return allInputs

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

def add : Diff Γ₁ Γ₂ → Diff Γ₂ Γ₃ → Diff Γ₁ Γ₃
  | ⟨d₁, h₁⟩, ⟨d₂, h₂⟩ => ⟨d₁ + d₂, fun h => by admit /- proof elided -/
    ⟩

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

Matrix.of in Mathlib.LinearAlgebra.Matrix.Defs

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

def ule_swap_or_not_min_before := [llvm|
{
^0(%arg264 : i8, %arg265 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "uge" %arg265, %arg264 : i8
  %2 = llvm.icmp "ne" %arg264, %0 : i8
  %3 = llvm.or %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def sdiv_exact_ne_1_before := [llvm|
{
^0(%arg12 : i8, %arg13 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.sdiv exact %arg12, %arg13 : i8
  %2 = llvm.icmp "eq" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

Lean.Expr.int? in Lean.Expr

def Expr.printResultList (_e : Expr d Γ eff ts) : Format :=
  if ts.length = 0 then
    ""
  else
    let rs :=
      List.range ts.length
      |>.map (f!"%{· + Γ.length}")
      |> f!", ".joinSep
    f!"{rs} = "

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

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

MonadLift in Init.Prelude

NFA.accept in Mathlib.Computability.NFA

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

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

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

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

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

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

def shl_trunc_smaller_ashr_before := [llvm|
{
^0(%arg41 : i32):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.mlir.constant(13 : i24) : i24
  %2 = llvm.ashr %arg41, %0 : i32
  %3 = llvm.trunc %2 : i32 to i24
  %4 = llvm.shl %3, %1 : i24
  "llvm.return"(%4) : (i24) -> ()
}
]

def or_or_and_pat1_before := [llvm|
{
^0(%arg74 : i8, %arg75 : i8, %arg76 : i8, %arg77 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.udiv %0, %arg76 : i8
  %2 = llvm.and %arg74, %arg75 : i8
  %3 = llvm.and %arg74, %arg77 : i8
  %4 = llvm.or %1, %3 : i8
  %5 = llvm.or %4, %2 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def multiuse_lshr_lshr_before := [llvm|
{
^0(%arg39 : i9):
  %0 = llvm.mlir.constant(2 : i9) : i9
  %1 = llvm.mlir.constant(3 : i9) : i9
  %2 = llvm.lshr %arg39, %0 : i9
  %3 = llvm.lshr %2, %1 : i9
  %4 = llvm.mul %2, %3 : i9
  "llvm.return"(%4) : (i9) -> ()
}
]

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

def PR44545_before := [llvm|
{
^0(%arg0 : i32, %arg1 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(-1 : i16) : i16
  %3 = llvm.add %arg0, %0 overflow<nsw,nuw> : i32
  %4 = llvm.icmp "eq" %arg1, %1 : i32
  %5 = "llvm.select"(%4, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %6 = llvm.trunc %5 : i32 to i16
  %7 = llvm.add %6, %2 overflow<nsw> : i16
  "llvm.return"(%7) : (i16) -> ()
}
]

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

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

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

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

@[simp_denote]
def trunc_llvm_32_to_16 := [LV| {
  ^entry (%lhs: i32):
    %0 = llvm.trunc %lhs : i32 to i16
    llvm.return %0 : i16
  }]

def Substitution.removeMappingFor (σ : Substitution) (v : VarName) : Substitution :=
  List.filter (·.fst != v) σ

def reduce (M : NFA α σ) : NFA α M.Reachable where
  start q :=  M.start q.val
  accept q := M.accept q.val
  step q a q' := M.step q.val a q'.val

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

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

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

def xor_ashr_not_after := [llvm|
{
^0(%arg27 : i8, %arg28 : i8, %arg29 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.xor %arg28, %arg27 : i8
  %2 = llvm.ashr %1, %arg29 : i8
  %3 = llvm.xor %2, %0 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def select2_before := [llvm|
{
^0(%arg9 : i1, %arg10 : i8, %arg11 : i8, %arg12 : i8):
  %0 = llvm.zext %arg10 : i8 to i32
  %1 = llvm.zext %arg11 : i8 to i32
  %2 = llvm.zext %arg12 : i8 to i32
  %3 = llvm.add %0, %1 : i32
  %4 = "llvm.select"(%arg9, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %5 = llvm.trunc %4 : i32 to i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

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

decidable_of_decidable_of_iff in Init.Core

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 sgt_smax2_before := [llvm|
{
^0(%arg37 : i32, %arg38 : i32):
  %0 = llvm.icmp "sgt" %arg38, %arg37 : i32
  %1 = "llvm.select"(%0, %arg38, %arg37) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %2 = llvm.icmp "sgt" %1, %arg37 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

def ValueStream := Stream

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

def test_add_fold_RHS := [mod_arith q, hq| {
  ^bb0():
    %res = mod_arith.constant 18 : !R
    return %res : !R
}]

def neg_or_lshr_i32_commute_before := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(31 : i32) : i32
  %3 = llvm.sdiv %0, %arg6 : i32
  %4 = llvm.sub %1, %3 : i32
  %5 = llvm.or %3, %4 : i32
  %6 = llvm.lshr %5, %2 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def ashr_16_add_zext_basic_after := [llvm|
{
^0(%arg11 : i16, %arg12 : i16):
  %0 = llvm.mlir.constant(-1 : i16) : i16
  %1 = llvm.xor %arg11, %0 : i16
  %2 = llvm.icmp "ugt" %arg12, %1 : i16
  %3 = llvm.zext %2 : i1 to i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def test4_before := [llvm|
{
^0(%arg97 : i32, %arg98 : i1):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = "llvm.select"(%arg98, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %3 = llvm.urem %arg97, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def PR30273_three_bools_before := [llvm|
{
^0(%arg41 : i1, %arg42 : i1, %arg43 : i1):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.zext %arg41 : i1 to i32
  %2 = llvm.add %1, %0 overflow<nsw> : i32
  %3 = "llvm.select"(%arg42, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.add %3, %0 overflow<nsw> : i32
  %5 = "llvm.select"(%arg43, %4, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

def test10_before := [llvm|
{
^0(%arg50 : i32, %arg51 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(-1431655766 : i32) : i32
  %2 = llvm.mlir.constant(1431655765 : i32) : i32
  %3 = llvm.mlir.constant(1 : i32) : i32
  %4 = llvm.ashr %arg50, %0 : i32
  %5 = llvm.or %4, %1 : i32
  %6 = llvm.xor %5, %2 : i32
  %7 = llvm.add %arg51, %3 : i32
  %8 = llvm.add %7, %6 : i32
  "llvm.return"(%8) : (i32) -> ()
}
]

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

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

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

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

instance : AST.TransformExpr LLVM 0 := { mkExpr }

def llvm_const_lower_riscv_li9 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM9, rhs:= liRiscv9,
   correct := by admit /- proof elided -/

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

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

instance : Lean.ToExpr RegIndex := inherit

def nonexact_lshr_ne_noexactlog_before := [llvm|
{
^0(%arg135 : i8):
  %0 = llvm.mlir.constant(90 : i8) : i8
  %1 = llvm.mlir.constant(30 : i8) : i8
  %2 = llvm.lshr %0, %arg135 : i8
  %3 = llvm.icmp "ne" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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 test3a_before := [llvm|
{
^0(%arg100 : i32):
  %0 = llvm.mlir.constant(-8 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.srem %arg100, %0 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

@[simp]
def mkOutEqZeroCircuitN {arity : Type _}
  [DecidableEq arity]
  [Fintype arity]
  [Hashable arity]
  (p : FSM arity) (n : Nat) :
  Circuit (Vars p.α arity (n + 1)) :=
    
    
    Circuit.xor
      (Circuit.ofBool false)
      (Circuit.var true <| Vars.outputs ⟨n, by admit /- proof elided -/
      ⟩)

def test9_before := [llvm|
{
^0(%arg52 : i16):
  %0 = llvm.mlir.constant(2 : i16) : i16
  %1 = llvm.mlir.constant(32767 : i16) : i16
  %2 = llvm.mul %arg52, %0 : i16
  %3 = llvm.mul %arg52, %1 : i16
  %4 = llvm.add %2, %3 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

RV64.clz in RISCV.Instructions

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

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

def not_bool_add_lshr_before := [llvm|
{
^0(%arg12 : i2, %arg13 : i2):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.zext %arg12 : i2 to i4
  %2 = llvm.zext %arg13 : i2 to i4
  %3 = llvm.add %1, %2 : i4
  %4 = llvm.lshr %3, %0 : i4
  "llvm.return"(%4) : (i4) -> ()
}
]

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

instance : ToFormat (Width φ) := ⟨repr⟩

def shl_lshr_demand6_after := [llvm|
{
^0(%arg10 : i16):
  %0 = llvm.mlir.constant(2057 : i16) : i16
  %1 = llvm.mlir.constant(4094 : i16) : i16
  %2 = llvm.shl %0, %arg10 : i16
  %3 = llvm.and %2, %1 : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

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

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

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

def negate_zext_before := [llvm|
{
^0(%arg96 : i8, %arg97 : i1):
  %0 = llvm.zext %arg97 : i1 to i8
  %1 = llvm.sub %arg96, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

structure Item where
 name : String
 tac : Syntax

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

def intro_example_rhs := [LV| {
  ^entry (%arg: i64, %amount: i64):
    llvm.return %arg : i64
  }]

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

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

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

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

def xor_or_xor_common_op_commute2_before := [llvm|
{
^0(%arg77 : i32, %arg78 : i32, %arg79 : i32):
  %0 = llvm.xor %arg79, %arg77 : i32
  %1 = llvm.or %arg77, %arg78 : i32
  %2 = llvm.xor %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

Stream'.map in Mathlib.Data.Stream.Defs

def slt_to_ugt_before := [llvm|
{
^0(%arg28 : i8, %arg29 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.xor %arg28, %0 : i8
  %2 = llvm.xor %arg29, %0 : i8
  %3 = llvm.icmp "slt" %1, %2 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def strictlyGTZero  (expr: GenBVExpr w) (widthId : Nat) : BoolExpr (GenBVPred) :=
  BoolExpr.gate Gate.and
    (.literal (GenBVPred.bin (zero w) BVBinPred.ult expr))
    (positive expr widthId)

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

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

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

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

def liRiscv48 := [LV| {
  ^entry ():
    %0 = "li"() {imm = 48 : !i64} : (!i64) -> (!i64)
    %1 = "builtin.unrealized_conversion_cast"(%0) : (!i64) -> (i64)
    llvm.return %1 : 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 uadd_sat_flipped_wrong_bounds6_before := [llvm|
{
^0(%arg91 : 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" %arg91, %0 : i32
  %4 = llvm.add %arg91, %1 : i32
  %5 = "llvm.select"(%3, %4, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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 sink (x : TokenStream) : TokenStream :=
  Stream.corec (β := TokenStream) x fun x => (none, x.tail)

@[simp_llvm_option]
def and {w : Nat} (x y : IntW w) : IntW w := do
  let x' ← x
  let y' ← y
  and? x' y'

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

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

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

    |

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

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

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

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

def src_is_mask_ashr_before := [llvm|
{
^0(%arg92 : i8, %arg93 : i8, %arg94 : i8, %arg95 : i1):
  %0 = llvm.mlir.constant(123 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.mlir.constant(15 : i8) : i8
  %3 = llvm.xor %arg92, %0 : i8
  %4 = llvm.add %arg93, %1 : i8
  %5 = llvm.xor %arg93, %4 : i8
  %6 = "llvm.select"(%arg95, %5, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %7 = llvm.ashr %6, %arg94 : i8
  %8 = llvm.and %3, %7 : i8
  %9 = llvm.icmp "ult" %8, %3 : i8
  "llvm.return"(%9) : (i1) -> ()
}
]

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

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

def reassoc_x2_mul_nuw_after := [llvm|
{
^0(%arg18 : i32, %arg19 : i32):
  %0 = llvm.mlir.constant(45 : i32) : i32
  %1 = llvm.mul %arg18, %arg19 : i32
  %2 = llvm.mul %1, %0 overflow<nuw> : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

def test85_after := [llvm|
{
^0(%arg60 : i32):
  %0 = llvm.mlir.constant(2130706432 : i32) : i32
  %1 = llvm.mlir.constant(23 : i32) : i32
  %2 = llvm.add %arg60, %0 : i32
  %3 = llvm.lshr %2, %1 : i32
  %4 = llvm.trunc %3 : i32 to i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

def alive_AndOrXor_1280_ABA___AB_tgt :=
[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 %A, %B : i64
  llvm.return %v4 : i64
}]

def branch (x : ValueStream (BitVec 1)): TokenStream × TokenStream  :=
  Stream.corec₂ (β := ValueStream (BitVec 1)) x fun x =>
    Id.run <| do
      match x 0 with
        | none => (none, none, (x.tail))
        | some x₀ =>
          if x₀.msb then
            (some (), none, (x.tail))
          else
            (none, some (), (x.tail))

def test7_before := [llvm|
{
^0(%arg93 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(4 : i32) : i32
  %2 = llvm.mul %arg93, %0 : i32
  %3 = llvm.srem %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

def positive_samevar_shlnuw_before := [llvm|
{
^0(%arg57 : i8, %arg58 : i8):
  %0 = llvm.lshr %arg57, %arg58 : i8
  %1 = llvm.shl %0, %arg58 overflow<nuw> : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

def mkExpr (Γ : Ctxt _) (opStx : MLIR.AST.Op 0) :
    MLIR.AST.ReaderM Comb (Σ eff ty, Expr Comb Γ eff ty) := do
  let args ← opStx.parseArgs Γ
  
  let unW := do
    let args ← args.assumeArity 1
    return getVarWidth args[0]
  
  let binW : AST.ReaderM (Comb) (Nat) := do
    let args ← args.assumeArity 2
    return getVarWidth args[0]
  
  let terW : AST.ReaderM (Comb) (Nat) := do
    let args ← args.assumeArity 3
    return getVarWidth args[0]
  
  if h : args.toList.length = 0 then
    throw <| .generic s!" empty list of argument provided for the variadic op {repr opStx.args}"
  else
    
    let nnW : AST.ReaderM (Comb) (Nat) := do
      let args ← args.assumeArity args.toList.length
      return getVarWidth args[0]
    let mkExprOf := opStx.mkExprOf (args? := args) Γ
    match (opStx.name).splitOn "_" with
    
    | ["Comb.parity"] => mkExprOf <| .parity (← unW)
    | ["Comb.extract", ns] =>
      match ns.toNat? with
      | some n =>  mkExprOf <| .extract (← unW) n
      | _ => throw <| .generic s!" an integer attribute should be provided for {repr opStx.args}"
    | ["Comb.replicate", ns] =>
      match ns.toNat? with
      | some n =>  mkExprOf <| .replicate (← unW) n
      | _ => throw <| .generic s!" an integer attribute should be provided for {repr opStx.args}"
    
    | ["Comb.divs"] => mkExprOf <| .divs (← binW)
    | ["Comb.divu"] => mkExprOf <| .divu (← binW)
    | ["Comb.icmp", ps] =>
      match (ofString? ps) with
      
      | some p => mkExprOf <| .icmp ps (← binW)
      | _ => throw <| .generic s!" invalid attribute provided for {repr opStx.args}"
    | ["Comb.mods"] => mkExprOf <| .mods (← binW)
    | ["Comb.modu"] => mkExprOf <| .modu (← binW)
    | ["Comb.shl"] => mkExprOf <| .shl (← binW)
    | ["Comb.shrs"] => mkExprOf <| .shrs (← binW)
    | ["Comb.shru"] => mkExprOf <| .shru (← binW)
    | ["Comb.sub "] => mkExprOf <| .sub (← binW)
    
    | ["Comb.mux"] => mkExprOf <| .mux (← terW)
    
    | ["Comb.add"] => mkExprOf <| .add (← nnW) args.toList.length
    | ["Comb.and"] => mkExprOf <| .and (← nnW) args.toList.length
    | ["Comb.mul"] => mkExprOf <| .mul (← nnW) args.toList.length
    | ["Comb.or"] => mkExprOf <| .or (← nnW) args.toList.length
    | ["Comb.xor"] => mkExprOf <| .xor (← nnW) args.toList.length
    
    | ["Comb.shlPar", n] =>
      match n.toNat? with
      | some n' => mkExprOf <| .shlPar n' (← unW)
      | _  => throw <| .generic s!"type mismatch"
    | _ => throw <| .unsupportedOp s!"{repr opStx}"

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

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

def icmp' {w : Nat} (c : IntPred) (x y : BitVec w) : Bool :=
  match c with
    | .eq => (x == y)
    | .ne => (x != y)
    | .sgt => (x >ₛ y)
    | .sge => (x ≥ₛ y)
    | .slt => (x <ₛ y)
    | .sle => (x ≤ₛ y)
    | .ugt => (x >ᵤ y)
    | .uge => (x ≥ᵤ y)
    | .ult => (x <ᵤ y)
    | .ule => (x ≤ᵤ y)

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

def concreteCliTestRows (test : ConcreteCliTest) : IO <| Array Row := do
  let mut rows := #[]
  let argTys : List test.code.getTy := test.context.reverse 
  let mut args : Array (Array (Option ℤ)) := #[]
  for ty in argTys do
    match ty with
      | .bitvec (.concrete w) => args := args.push <| (BitVec.inputsForWidth w).map (Option.map BitVec.toInt)
  let argvecs := productsArr args
  for arg in argvecs do
    let evalRes ← test.eval? arg
    match evalRes with
      | Except.ok retv =>
        let ty : InstCombine.MTy 0 := test.ty
        match hty : ty with
          | .bitvec (.concrete w) =>
              let h : TyDenote.toType ty = Option (BitVec w) := by admit /- proof elided -/

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

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

def test70_after := [llvm|
{
^0(%arg150 : i8, %arg151 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.lshr %arg150, %0 : i8
  %3 = llvm.and %2, %1 : i8
  %4 = llvm.or %arg151, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

def zext_masked_bit_zero_to_smaller_bitwidth_before := [llvm|
{
^0(%arg49 : i32, %arg50 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %0, %arg50 : i32
  %3 = llvm.and %2, %arg49 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.zext %4 : i1 to i16
  "llvm.return"(%5) : (i16) -> ()
}
]

def rewrite_e : PeepholeRewrite DCPlus [.tokenstream, .valuestream 1] [.tokenstream] :=
  { lhs := [DCPlus_com| {
      ^entry(%c : !ValueStream_1, %d : !TokenStream):
        %forkc = "DCPlus.forkVal" (%c) : (!ValueStream_1) -> (!ValueStream2_1)
        %forkc' = "DCPlus.forkVal" (%c) : (!ValueStream_1) -> (!ValueStream2_1)
        %fstc = "DCPlus.fstValPure" (%forkc) : (!ValueStream2_1) -> (!ValueStream_1)
        %sndc = "DCPlus.sndValPure" (%forkc) : (!ValueStream2_1) -> (!ValueStream_1)
        %trdc = "DCPlus.fstValPure" (%forkc') : (!ValueStream2_1) -> (!ValueStream_1)
        %forkd = "DCPlus.fork" (%d) : (!TokenStream) -> (!TokenStream2)
        %fstd = "DCPlus.fst" (%forkd) : (!TokenStream2) -> (!TokenStream)
        %sndd = "DCPlus.snd" (%forkd) : (!TokenStream2) -> (!TokenStream)
        %supp1 = "DCPlus.supp" (%fstc, %fstd) : (!ValueStream_1, !TokenStream) -> (!TokenStream)
        %not = "DCPlus.not" (%sndc) : (!ValueStream_1) -> (!ValueStream2_1)
        %supp2 = "DCPlus.supp" (%not, %sndd) : (!ValueStream_1, !TokenStream) -> (!TokenStream)
        %mux = "DCPlus.mux" (%supp1, %supp2, %trdc) : (!TokenStream, !TokenStream, !ValueStream_1) -> (!TokenStream)
        "return" (%mux) : (!TokenStream) -> ()
      }],
    rhs := [DCPlus_com| {
      ^entry(%c : !ValueStream_1, %d : !TokenStream):
        "return" (%d) : (!TokenStream) -> ()
      }],
    correct :=
    by admit /- proof elided -/

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

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

structure NonNegFlag where
  nneg : Bool := false
  deriving Repr, DecidableEq, Lean.ToExpr

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 n1_after := [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 overflow<nsw> : i8
  %3 = llvm.xor %2, %1 : i8
  %4 = llvm.icmp "ult" %3, %arg7 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

Lean.Meta.evalExpr in Lean.Meta.Eval

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

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

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

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

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

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

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

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

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

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

def icmp_ult_riscv_eq_icmp_ult_llvm_32 : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] :=
  {lhs:= icmp_ult_llvm_32, rhs:= icmp_ult_riscv_32}

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

def test_invert_demorgan_or2_before := [llvm|
{
^0(%arg15 : i64, %arg16 : i64, %arg17 : i64):
  %0 = llvm.mlir.constant(23) : i64
  %1 = llvm.mlir.constant(59) : i64
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.icmp "ugt" %arg15, %0 : i64
  %4 = llvm.icmp "ugt" %arg16, %1 : i64
  %5 = llvm.or %3, %4 : i1
  %6 = llvm.icmp "ugt" %arg17, %1 : i64
  %7 = llvm.or %5, %6 : i1
  %8 = llvm.xor %7, %2 : i1
  "llvm.return"(%8) : (i1) -> ()
}
]

def foo1_and_commuted_before := [llvm|
{
^0(%arg172 : i32, %arg173 : i32, %arg174 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mul %arg172, %arg172 : i32
  %3 = llvm.shl %0, %arg173 : i32
  %4 = llvm.shl %0, %arg174 : i32
  %5 = llvm.and %2, %3 : i32
  %6 = llvm.icmp "eq" %5, %1 : i32
  %7 = llvm.and %4, %2 : i32
  %8 = llvm.icmp "eq" %7, %1 : i32
  %9 = llvm.or %6, %8 : i1
  "llvm.return"(%9) : (i1) -> ()
}
]

def add_or_sub_comb_i8_negative_y_add_after := [llvm|
{
^0(%arg4 : i8, %arg5 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.sub %0, %arg4 : i8
  %2 = llvm.or %arg4, %1 : i8
  %3 = llvm.add %2, %arg5 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

Vector in Init.Data.Vector.Basic

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

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

def carryBV (x : ar → BitVec w) : p.State :=
  p.carry (fun ar => .ofBitVecSext (x ar)) w

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

private def mkHeader (kind : String) (id : Name) (levelParams : List Name) (type : Expr) (safety : DefinitionSafety) (sig : Bool := true) : MetaM MessageData := do
  let mut attrs := #[]
  match (← getReducibilityStatus id) with
  | ReducibilityStatus.irreducible =>   attrs := attrs.push m!"irreducible"
  | ReducibilityStatus.reducible =>     attrs := attrs.push m!"reducible"
  | ReducibilityStatus.semireducible => pure ()

  if defeqAttr.hasTag (← getEnv) id then
    attrs := attrs.push m!"defeq"

  let mut m : MessageData := m!""
  unless attrs.isEmpty do
    m := m ++ "@[" ++ MessageData.joinSep attrs.toList ", " ++ "] "

  match safety with
  | DefinitionSafety.unsafe  => m := m ++ "unsafe "
  | DefinitionSafety.partial => m := m ++ "partial "
  | DefinitionSafety.safe    => pure ()

  if isProtected (← getEnv) id then
    m := m ++ "protected "

  let id' ← match privateToUserName? id with
    | some id' =>
      m := m ++ "private "
      pure id'
    | none =>
      pure id

  if sig then
    return m!"{m}{kind} {id'}{levelParamsToMessageData levelParams} : {type}"
  else
    return m!"{m}{kind}"

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

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

def lshrult_01_02_exact_before := [llvm|
{
^0(%arg147 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(2 : i4) : i4
  %2 = llvm.lshr exact %arg147, %0 : i4
  %3 = llvm.icmp "ult" %2, %1 : i4
  "llvm.return"(%3) : (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 test1_before := [llvm|
{
^0(%arg8 : i32, %arg9 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.mlir.constant(10 : i32) : i32
  %2 = llvm.xor %arg8, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  %4 = llvm.icmp "eq" %2, %arg9 : i32
  %5 = llvm.or %3, %4 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

def op3 : Op 0 := [mlir_op| %3 = llvm.and %2, %0 : i32]

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

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

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

def test_add_nuw_nsw__all_are_safe_before := [llvm|
{
^0(%arg47 : i32):
  %0 = llvm.mlir.constant(1073741823 : i32) : i32
  %1 = llvm.mlir.constant(3 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.mlir.constant(4 : i32) : i32
  %4 = llvm.and %arg47, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.add %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 shrink_select_after := [llvm|
{
^0(%arg52 : i1, %arg53 : i32):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.trunc %arg53 : i32 to i8
  %2 = "llvm.select"(%arg52, %1, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def printAttributes: RISCV64.Op → String
  | .li imm => s! "\{immediate = { imm.toInt } : i64 }"
  | .addiw (imm : BitVec 12) => s!"\{immediate = { imm.toInt} : si12 }"
  | .lui (imm : BitVec 20) => s!"\{immediate = { imm.toInt} : ui20 } "
  | .auipc (imm : BitVec 20) => s!"\{immediate = { imm.toInt} : si20 }" 
  | .slliw (imm : BitVec 5) => s!"\{immediate = { imm.toNat} : ui5 }"
  | .srliw (imm : BitVec 5) => s!"\{immediate = { imm.toNat} : ui5 }"
  | .sraiw (imm : BitVec 5) => s!"\{immediate = { imm.toNat} : ui5 }"
  | .slli (imm : BitVec 6) => s!"\{immediate = { imm.toNat} : ui6 }"
  | .srli (imm : BitVec 6) => s!"\{immediate = { imm.toNat} : ui6 }"
  | .srai (imm : BitVec 6) => s!"\{immediate = { imm.toNat} : ui6 }"
  | .addi (imm : BitVec 12) => s!"\{immediate = { imm.toInt } : si12 }"
  | .slti (imm : BitVec 12) => s!"\{immediate = { imm.toInt } : si12 }"
  | .sltiu (imm : BitVec 12) => s!"\{immediate = { imm.toInt } : si12 }"
  | .andi (imm : BitVec 12) => s!"\{immediate = { imm.toInt } : si12 }"
  | .ori (imm : BitVec 12) => s!"\{immediate = { imm.toInt } : si12 }"
  | .xori (imm : BitVec 12) => s!"\{immediate = { imm.toInt } : si12 }"
  | .bclri (imm : BitVec 6) => s!"\{immediate = { imm.toInt} : i6 }"
  | .bexti (imm : BitVec 6) =>s!"\{immediate = { imm.toInt} : i6 }"
  | .binvi (imm : BitVec 6) => s!"\{immediate = { imm.toInt} : i6 }"
  | .bseti (imm : BitVec 6) => s!"\{immediate = { imm.toInt} : i6 }"
  | .slliuw (imm : BitVec 6) => s!"\{immediate = { imm.toNat} : ui6 }"
  | .rori (imm : BitVec 6) => s!"\{immediate = { imm.toInt} : i5 }"
  | .roriw (imm : BitVec 5) => s!"\{immediate = { imm.toInt} : i5 }"
  | _ => ""

def select_zext_different_condition_before := [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 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

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

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

def mkCarryAssignCircuitN {arity : Type _}
  [DecidableEq arity]
  [Fintype arity]
  [Hashable arity]
  (p : FSM arity) (n : Nat) :
  Circuit (Vars p.α arity (n + 1)) :=
  let carrys := FinEnum.toList p.α |>.map fun s =>
    
    Circuit.xor
      (mkCarryAssignCircuitNAux p s n)
      (Circuit.var true <| Vars.stateN s (n + 1))
  Circuit.bigOr carrys

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

def uge_sext_before := [llvm|
{
^0(%arg134 : i1, %arg135 : i8):
  %0 = llvm.sext %arg134 : i1 to i8
  %1 = llvm.icmp "uge" %0, %arg135 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

def add_or_and_commutative_after := [llvm|
{
^0(%arg17 : i32, %arg18 : i32):
  %0 = llvm.add %arg17, %arg18 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

@[simp]
def evalBinop' (op : Binop) (b1 b2 : Prop) : Prop :=
  match op with
  | .and => b1 ∧ b2
  | .or => b1 ∨ b2
  | .impl => b1 → b2
  | .equiv => b1 ↔ b2

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

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

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

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

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

def BlockLabel : Type := String

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

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

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

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

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

def test6_before := [llvm|
{
^0(%arg3 : i65):
  %0 = llvm.mlir.constant(1 : i65) : i65
  %1 = llvm.mlir.constant(64 : i65) : i65
  %2 = llvm.shl %0, %1 : i65
  %3 = llvm.xor %arg3, %2 : i65
  %4 = llvm.add %3, %2 : i65
  "llvm.return"(%4) : (i65) -> ()
}
]

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

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

CoeDep in Init.Coe

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

inductive Op
| fst
| snd
| pair (w : Nat)
| fstVal (w : Nat)
| fstValPure (w : Nat)
| sndVal (w : Nat)
| sndValPure (w : Nat)
| fstVal' (w : Nat)
| sndVal' (w : Nat)
| tokVal' (w : Nat)
| fork
| forkVal
| join
| merge
| mux
| muxVal
| cMerge
| branch
| source
| sourceOnes
| sink
| supp
| not
deriving Inhabited, DecidableEq, Repr, Lean.ToExpr

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

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

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

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

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

def test87_before := [llvm|
{
^0(%arg58 : i16):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.sext %arg58 : i16 to i32
  %2 = llvm.mul %1, %0 overflow<nsw> : i32
  %3 = llvm.ashr %2, %0 : i32
  %4 = llvm.trunc %3 : i32 to i16
  "llvm.return"(%4) : (i16) -> ()
}
]

def product (final? : Bool → Bool → Bool) (m₁ m₂ : CNFA n) : CNFA n :=
  worklistRun (m₁.m.states × m₂.m.states) final (product.inits m₁ m₂)
    (by admit /- proof elided -/
    ) f
where final (ss : m₁.m.states × m₂.m.states) := final? (ss.1 ∈ m₁.m.finals) (ss.2 ∈ m₂.m.finals)
      f (ss : m₁.m.states × m₂.m.states) :=
        let (s1, s2) := ss
        (FinEnum.toList (α := BitVec n)).foldl (init := Array.empty) fun as a =>
          product.prodArray' (λ s₁ s₂ ↦ (a, (s₁, s₂)))
            (fun s' => m₁.wf.trans_tgt_lt (s := s1) (a := a)) (fun s' => m₂.wf.trans_tgt_lt (s := s2) (a := a)) as

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

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

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

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 not_mul_of_pow2_before := [llvm|
{
^0(%arg77 : i32, %arg78 : i8):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.mlir.constant(1530 : i32) : i32
  %2 = llvm.and %arg77, %0 : i32
  %3 = llvm.zext %arg78 : i8 to i32
  %4 = llvm.mul %2, %3 : i32
  %5 = llvm.icmp "ugt" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

BitVec.iunfoldr in Init.Data.BitVec.Folds

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

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

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 foo4_before := [llvm|
{
^0(%arg0 : i1, %arg1 : i1):
  %0 = llvm.sdiv %arg0, %arg1 : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

@[reducible]
instance [Monad d.m] : DialectDenote (Scf d) where
  denote
    | .coe o', args', regArgs' =>
        let denote' := DialectDenote.denote o'
        by
         exact denote' args' regArgs'
    | .if t t', (.cons (cond ) (.cons v .nil)),
         (.cons (f : Ctxt.Valuation ⟨[t]⟩ → d.m (HVector toType [t'])) (.cons (g : _ → _) .nil)) =>
         let body := if B.denote_eq ▸ cond then f else g
      body (Ctxt.Valuation.nil.cons v)
    | .run _t, (.cons v .nil), (.cons (f : _ → _) .nil) =>
        f (Ctxt.Valuation.nil.cons v)
    | .for ty, (.cons istart (.cons istep (.cons niter (.cons vstart .nil)))),
        (.cons (f : _  → _) .nil) => do
        let istart : ℤ := Z.denote_eq ▸ istart
        let istep : ℤ := Z.denote_eq ▸ istep
        let niter : ℕ := N.denote_eq ▸ niter
        let f' : LoopBody (d.m ⟦ty⟧) := fun i v => do
          let v ← v
          let i := Z.denote_eq.symm ▸ i
          let xs ← f (Valuation.ofPair i v)
          return xs.get (0 : Fin 1)
        let to_iterate := f'.counterDecorator (α := d.m ⟦ty⟧) (δ := istep)
        let loop_fn := niter.iterate (op := to_iterate)
        let x ← (loop_fn (istart, pure vstart)).2
        return [x]ₕ

    | .iterate k, (.cons (x) .nil), (.cons (f : _ → _) .nil) => do
      let x : ℤ := Z.denote_eq ▸ x
      let coe : ℤ = toType Z.ty := Z.denote_eq.symm
      let f' (v : d.m ℤ) : d.m ℤ := do
        let v ← v
        let xs ← f (Ctxt.Valuation.nil.cons (cast coe v))
        let x := xs.getN 0
        return coe ▸ x
      let y ← (k.iterate f' (pure x))
      return [cast Z.denote_eq.symm y]ₕ

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

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

def getPreconditionSynthesisComponents (positiveExamples negativeExamples: List (Std.HashMap Nat BVExpr.PackedBitVec)) (specialConstants : Std.HashMap (GenBVExpr w) BVExpr.PackedBitVec) :
                  Std.HashMap (GenBVExpr w)  PreconditionSynthesisCacheValue := Id.run do
    let groupExamplesBySymVar (examples : List (Std.HashMap Nat BVExpr.PackedBitVec)) : Std.HashMap (GenBVExpr w) (List BVExpr.PackedBitVec) := Id.run do
      let mut res : Std.HashMap (GenBVExpr w) (List BVExpr.PackedBitVec) := Std.HashMap.emptyWithCapacity
      for ex in examples do
        for (const, val) in ex.toArray do
          let constVar : GenBVExpr w := GenBVExpr.var const
          let existingList := res.getD constVar []
          res := res.insert constVar (val::existingList)
      res

    let positiveExamplesByKey := groupExamplesBySymVar positiveExamples
    let negativeExamplesByKey := groupExamplesBySymVar negativeExamples

    let mut allInputs : Std.HashMap (GenBVExpr w)  PreconditionSynthesisCacheValue := Std.HashMap.emptyWithCapacity
    for key in positiveExamplesByKey.keys do
      allInputs := allInputs.insert key {positiveExampleValues := positiveExamplesByKey[key]!, negativeExampleValues := negativeExamplesByKey[key]!}

    for (sc, val) in specialConstants.toArray do
      allInputs := allInputs.insert sc {positiveExampleValues := List.replicate positiveExamples.length val, negativeExampleValues := List.replicate negativeExamples.length val}

    return allInputs

instance : HasUB PoisonOr where
  throwUB := .poison

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

def TokenStream := Stream Unit

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 not_or_or_and_not_and_and_commute4_after := [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.xor %arg184, %1 : i32
  %4 = llvm.xor %2, %arg185 : i32
  %5 = llvm.or %4, %3 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

BitVec.sub in Init.Data.BitVec.BasicAux

def select_constants_and_icmp_ne0_after := [llvm|
{
^0(%arg26 : i1, %arg27 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg26, %arg27 : i1
  %2 = llvm.xor %1, %0 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

def Predicate.evalNeq (t₁ t₂ : BitStream) : BitStream := (t₁.nxor t₂).concat true |>.scanAnd

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

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

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

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

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

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

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

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

CommRing in Mathlib.Algebra.Ring.Defs

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

def and_or_not_not_commute4_after := [llvm|
{
^0(%arg363 : i32, %arg364 : i32, %arg365 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg365, %arg364 : i32
  %2 = llvm.and %1, %arg363 : i32
  %3 = llvm.xor %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

def ripple_nsw4_before := [llvm|
{
^0(%arg17 : i16, %arg18 : i16):
  %0 = llvm.mlir.constant(-21845 : i16) : i16
  %1 = llvm.mlir.constant(21843 : i16) : i16
  %2 = llvm.and %arg18, %0 : i16
  %3 = llvm.and %arg17, %1 : i16
  %4 = llvm.add %3, %2 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

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

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 shl_or_lshr_comm_after := [llvm|
{
^0(%arg106 : i32, %arg107 : i32, %arg108 : i32):
  %0 = llvm.lshr %arg108, %arg107 : i32
  %1 = llvm.or %0, %arg106 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

def eq_umin3_after := [llvm|
{
^0(%arg56 : i32, %arg57 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg56, %0 : i32
  %2 = llvm.icmp "ule" %1, %arg57 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

UInt32 in Init.Prelude

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

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

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

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

def simplify_and_common_op_commute1_before := [llvm|
{
^0(%arg29 : i4, %arg30 : i4, %arg31 : i4):
  %0 = llvm.mlir.constant(-1 : i4) : i4
  %1 = llvm.or %arg30, %arg29 : i4
  %2 = llvm.or %1, %arg31 : i4
  %3 = llvm.xor %2, %0 : i4
  %4 = llvm.and %3, %arg29 : i4
  "llvm.return"(%4) : (i4) -> ()
}
]

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

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

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

def ashr_and_or_disjoint_before := [llvm|
{
^0(%arg41 : i8, %arg42 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.mlir.constant(13 : i8) : i8
  %3 = llvm.srem %arg41, %0 : i8
  %4 = llvm.ashr %arg42, %1 : i8
  %5 = llvm.and %4, %2 : i8
  %6 = llvm.or disjoint %3, %5 : i8
  %7 = llvm.shl %6, %1 : i8
  "llvm.return"(%7) : (i8) -> ()
}
]

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

def t3_exact_after := [llvm|
{
^0(%arg7 : i64):
  %0 = llvm.mlir.constant(63) : i64
  %1 = llvm.lshr exact %arg7, %0 : i64
  %2 = llvm.trunc %1 overflow<nsw,nuw> : i64 to i32
  "llvm.return"(%2) : (i32) -> ()
}
]

EmptyCollection.emptyCollection in Init.Core

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

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

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

Pi.algebra in Mathlib.Algebra.Algebra.Pi

def t4_commutative_before := [llvm|
{
^0(%arg34 : i8, %arg35 : i8):
  %0 = llvm.add %arg34, %arg35 : i8
  %1 = llvm.icmp "ule" %arg35, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

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

def sub_add_reg : List (Σ Γ, LLVMPeepholeRewriteRefine 64 Γ) :=
  [⟨_, sub_add_reg_x_add_y_sub_y⟩,
  ⟨_, sub_add_reg_x_add_y_sub_x⟩,
  ⟨_, sub_add_reg_x_sub_y_add_x⟩,
  ⟨_, sub_add_reg_x_sub_x_add_y⟩]

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

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

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

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

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

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

def test34_after := [llvm|
{
^0(%arg248 : i32, %arg249 : i32):
  "llvm.return"(%arg249) : (i32) -> ()
}
]

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

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

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

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

def eqvVarLeft  :
    MatchVarResult lets v (.var matchLets matchExpr) w.appendInr ma
    ≃ MatchVarResult lets v matchLets w ma where
  toFun := fun ⟨x, h⟩ => ⟨x, by admit /- proof elided -/
  ⟩
  invFun := fun ⟨x, h⟩ => ⟨x, by admit /- proof elided -/
  ⟩

def printParsedFpExprState (s: ParsedInputState) :=
    s!"ParsedFpExprState:\n" ++
    s!"  maxFreeVarId: {s.maxFreeVarId}\n" ++
    s!"  numSymVars: {s.numSymVars}\n" ++
    s!"  displayNameToVariable: {s.displayNameToVariable}\n" ++
    s!"  BVExprIdToFreeVar: {s.inputVarIdToVariable}\n" ++
    s!"  symVarToVal: {s.symVarToVal}" ++
    s!"  symVarToDisplayName: {s.symVarIdToVariable}"

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

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

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

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 src2_after := [llvm|
{
^0(%arg10 : i32, %arg11 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg11, %arg10 : i32
  %2 = llvm.xor %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

def or_not_and_commute2_before := [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.or %arg531, %2 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.and %4, %arg533 : i32
  %6 = llvm.or %arg531, %arg533 : i32
  %7 = llvm.xor %6, %1 : i32
  %8 = llvm.and %2, %7 : i32
  %9 = llvm.or %8, %5 : i32
  "llvm.return"(%9) : (i32) -> ()
}
]

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

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

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

def test2_before := [llvm|
{
^0(%arg4 : i32, %arg5 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(32 : i32) : i32
  %2 = llvm.xor %arg4, %arg5 : i32
  %3 = llvm.icmp "eq" %2, %0 : i32
  %4 = llvm.icmp "eq" %2, %1 : i32
  %5 = llvm.xor %3, %4 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

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

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

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

@[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 add_nosignbit_select_shl_before := [llvm|
{
^0(%arg32 : i32, %arg33 : i1):
  %0 = llvm.mlir.constant(2147418112 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.add %arg32, %0 : i32
  %3 = "llvm.select"(%arg33, %2, %arg32) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.shl %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

ShiftRight in Init.Prelude

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

def not_match_inconsistent_signs_after := [llvm|
{
^0(%arg13 : i64):
  %0 = llvm.mlir.constant(299) : i64
  %1 = llvm.mlir.constant(63) : i64
  %2 = llvm.urem %arg13, %0 : i64
  %3 = llvm.sdiv %arg13, %0 : i64
  %4 = llvm.and %3, %1 : i64
  %5 = llvm.mul %4, %0 overflow<nsw,nuw> : i64
  %6 = llvm.add %2, %5 overflow<nsw,nuw> : i64
  "llvm.return"(%6) : (i64) -> ()
}
]

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

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

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

@[simp_denote]
def add_multiuse_llvm_i64 := [LV| {
    ^entry (%x: i64):
    %0 = llvm.mlir.constant (-1099511627775) : i64
    %1 = llvm.add %x, %0 : i64
    %2 = llvm.and %1, %0 : i64
    llvm.return %2 : i64
  }]

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

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

instance : HydrableChangePredWidth GenBVPred where
  changePredWidth := changeBVLogicalExprWidth

def lhsSketchEnumeration  (lhsSketch: GenBVExpr w) (inputVars: List Nat) (lhsSymVars rhsSymVars : Std.HashMap Nat BVExpr.PackedBitVec) : ExpressionSynthesisResult := Id.run do
  let zero := wrap (GenBVExpr.const (BitVec.ofNat w 0))
  let one := wrap (GenBVExpr.const (BitVec.ofNat w 1 ))
  let minusOne := wrap (GenBVExpr.const (BitVec.ofInt w (-1)))

  
  let specialConstants := [zero, one, minusOne]
  let inputCombinations := productsList (List.replicate inputVars.length specialConstants)

  let lhsSymVarsAsBVExprs : List (BVExprWrapper):= lhsSymVars.toList.map (λ (id, pbv) => {bvExpr := GenBVExpr.var id, width := pbv.w})
  let lhsSymVarsPermutation := productsList (List.replicate lhsSymVarsAsBVExprs.length lhsSymVarsAsBVExprs)

  let inputsAndSymVars := List.product inputCombinations lhsSymVarsPermutation

  let mut rhsVarByValue : Std.HashMap (BitVec w) Nat := Std.HashMap.emptyWithCapacity
  for (var, value) in rhsSymVars.toArray do
    let h : value.w = w := sorry
    rhsVarByValue := rhsVarByValue.insert (h ▸ value.bv) var

  let mut res : ExpressionSynthesisResult := Std.HashMap.emptyWithCapacity
  for combo in inputsAndSymVars do
    let inputsSubstitutions := bvExprToSubstitutionValue (Std.HashMap.ofList (List.zip inputVars combo.fst))
    let symVarsSubstitutions := bvExprToSubstitutionValue (Std.HashMap.ofList (List.zip lhsSymVars.keys combo.snd))

    let substitutedExpr := substituteBVExpr lhsSketch (Std.HashMap.union inputsSubstitutions symVarsSubstitutions)
    let evalRes : BitVec w := evalBVExpr lhsSymVars substitutedExpr

    if rhsVarByValue.contains evalRes then
      let existingVar := rhsVarByValue[evalRes]!
      let existingVarRes := res.getD existingVar []

      res := res.insert existingVar (wrap substitutedExpr :: existingVarRes)

  pure res

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

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

def and_xor_or7_before := [llvm|
{
^0(%arg655 : i64, %arg656 : i64, %arg657 : i64):
  %0 = llvm.mlir.constant(42) : i64
  %1 = llvm.udiv %0, %arg655 : i64
  %2 = llvm.udiv %0, %arg656 : i64
  %3 = llvm.udiv %0, %arg657 : i64
  %4 = llvm.and %1, %2 : i64
  %5 = llvm.xor %3, %4 : i64
  %6 = llvm.or %2, %5 : i64
  "llvm.return"(%6) : (i64) -> ()
}
]

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

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

def test10_after := [llvm|
{
^0(%arg50 : i32, %arg51 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(1431655765 : i32) : i32
  %2 = llvm.ashr %arg50, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.sub %arg51, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def shl_xor_xor_good_mask_after := [llvm|
{
^0(%arg100 : i8, %arg101 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(88 : i8) : i8
  %2 = llvm.xor %arg101, %arg100 : i8
  %3 = llvm.shl %2, %0 : i8
  %4 = llvm.xor %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def foo1_or_commuted_after := [llvm|
{
^0(%arg145 : i32, %arg146 : i32, %arg147 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mul %arg145, %arg145 : i32
  %2 = llvm.shl %0, %arg146 overflow<nuw> : i32
  %3 = llvm.shl %0, %arg147 overflow<nuw> : i32
  %4 = llvm.or %2, %3 : i32
  %5 = llvm.and %1, %4 : i32
  %6 = llvm.icmp "eq" %5, %4 : i32
  "llvm.return"(%6) : (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 masked_and_notallzeroes_before := [llvm|
{
^0(%arg134 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(39 : i32) : i32
  %3 = llvm.and %arg134, %0 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  %5 = llvm.and %arg134, %2 : i32
  %6 = llvm.icmp "ne" %5, %1 : i32
  %7 = llvm.and %4, %6 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

def instantiate (as : List.Vector α φ) : ConcreteOrMVar α φ → α
  | .concrete w => w
  | .mvar i => as.get i

Lean.Quote in Init.Meta.Defs

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

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

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

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

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

def narrow_sext_sub_after := [llvm|
{
^0(%arg40 : i16, %arg41 : i32):
  %0 = llvm.trunc %arg41 : i32 to i16
  %1 = llvm.sub %arg40, %0 : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

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

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

def llvm_sub_lower_riscv_no_flag_self: LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := llvm_sub_self_ex
  rhs := sub_riscv_self_ex
  correct := by admit /- proof elided -/

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

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

def rem_euclid_non_const_pow2_after := [llvm|
{
^0(%arg4 : i8, %arg5 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.shl %0, %arg4 overflow<nsw> : i8
  %2 = llvm.xor %1, %0 : i8
  %3 = llvm.and %arg5, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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 scalar_i32_shl_and_negC_eq_after := [llvm|
{
^0(%arg31 : i32, %arg32 : i32):
  %0 = llvm.mlir.constant(262144 : i32) : i32
  %1 = llvm.shl %arg31, %arg32 : i32
  %2 = llvm.icmp "ult" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

def Std.HashSet.toSet [BEq α] [Hashable α] (m : HashSet α) : Set α := { x | x ∈ m }

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

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

structure Op where
  (name: String)
  (res: List <| TypedSSAVal φ)
  (args: List <| TypedSSAVal φ)
  (regions: List Region)
  (attrs: AttrDict φ)

def foo1_and_signbit_lshr_without_shifting_signbit_after := [llvm|
{
^0(%arg118 : i32, %arg119 : i32, %arg120 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(-1 : i32) : i32
  %3 = llvm.shl %0, %arg119 overflow<nuw> : i32
  %4 = llvm.and %3, %arg118 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.shl %arg118, %arg120 : i32
  %7 = llvm.icmp "sgt" %6, %2 : i32
  %8 = llvm.or %5, %7 : i1
  "llvm.return"(%8) : (i1) -> ()
}
]

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

def always_false [DecidableEq α] (c : Circuit α) : Bool :=
   nonempty c = false

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

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

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

Lean.Core.State in Lean.CoreM

Flag in Mathlib.Order.Preorder.Chain

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

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

def RISCV_identity_combines: List (Σ Γ, RISCVPeepholeRewrite Γ) :=
  right_identity_zero ++ binop_same_val ++ right_identity_one ++ add_sub_reg_frags

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

List.length in Init.Prelude

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

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

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

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

def testi64i32_ne_before := [llvm|
{
^0(%arg7 : i64):
  %0 = llvm.mlir.constant(32) : i64
  %1 = llvm.mlir.constant(31 : i32) : i32
  %2 = llvm.lshr %arg7, %0 : i64
  %3 = llvm.trunc %2 : i64 to i32
  %4 = llvm.trunc %arg7 : i64 to i32
  %5 = llvm.ashr %4, %1 : i32
  %6 = llvm.icmp "ne" %5, %3 : i32
  "llvm.return"(%6) : (i1) -> ()
}
]

BitVec.ofInt in Init.Data.BitVec.Basic

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

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

def NFA.msbLang : Language (BitVec 1) := { bvs  | bvs.getLast? = some 1 }

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

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

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

def 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 trunc_before := [llvm|
{
^0(%arg15 : i32, %arg16 : i32, %arg17 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.icmp "ult" %arg15, %arg16 : i32
  %2 = "llvm.select"(%1, %0, %arg17) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %3 = llvm.trunc %2 : i32 to i16
  "llvm.return"(%3) : (i16) -> ()
}
]

def test13_after := [llvm|
{
^0(%arg2 : i32, %arg3 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(128 : i32) : i32
  %2 = llvm.shl %arg2, %0 : i32
  %3 = llvm.and %arg3, %1 : i32
  %4 = llvm.mul %3, %2 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def 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 n4_after := [llvm|
{
^0(%arg36 : i32, %arg37 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(-16 : i32) : i32
  %2 = llvm.mlir.constant(262143) : i64
  %3 = llvm.mlir.constant(0 : i32) : i32
  %4 = llvm.sub %0, %arg37 : i32
  %5 = llvm.shl %arg36, %4 : i32
  %6 = llvm.add %arg37, %1 : i32
  %7 = llvm.zext nneg %6 : i32 to i64
  %8 = llvm.lshr %2, %7 : i64
  %9 = llvm.trunc %8 overflow<nsw,nuw> : i64 to i32
  %10 = llvm.and %5, %9 : i32
  %11 = llvm.icmp "ne" %10, %3 : i32
  "llvm.return"(%11) : (i1) -> ()
}
]

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

def test1_after := [llvm|
{
^0(%arg19 : i32, %arg20 : i8):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.zext nneg %arg20 : i8 to i32
  %2 = llvm.lshr %arg19, %1 : i32
  %3 = llvm.and %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

@[simp_denote]
def srai_riscv_i32 :=
  [LV| {
    ^entry (%arg: i32):
    %a = "builtin.unrealized_conversion_cast" (%arg) : (i32) -> (!i64)
    %0 = sraiw %a, 9 : !i64
    %1 = "builtin.unrealized_conversion_cast" (%0) : (!i64) -> (i32)
    llvm.return %1 : i32
  }]

def and_zext_zext_after := [llvm|
{
^0(%arg58 : i8, %arg59 : i4):
  %0 = llvm.zext %arg59 : i4 to i8
  %1 = llvm.and %arg58, %0 : i8
  %2 = llvm.zext nneg %1 : i8 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

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

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

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

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

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

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

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

def 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 test_const_shr_and_1_ne_0_i1_negative_before := [llvm|
{
^0(%arg2 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.lshr %0, %arg2 : i1
  %3 = llvm.and %2, %0 : i1
  %4 = llvm.icmp "ne" %3, %1 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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 sext {w: Nat} (w': Nat) (x: IntW w) : IntW w' := do
  let x' <- x
  sext? w' x'

def no_shift_xor_multiuse_and_before := [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 "ne" %1, %3 : i32
  %5 = llvm.and %arg131, %2 : i32
  %6 = "llvm.select"(%4, %arg131, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = llvm.mul %6, %5 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def Ptr : Type := PoisonOr Pointer

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

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

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

def mkBoolLit (b : Bool) : Expr :=
  match b with
  | true => mkConst ``true
  | false => mkConst ``false

OneHom in Mathlib.Algebra.Group.Hom.Defs

def sub_ult_zext_after := [llvm|
{
^0(%arg161 : i1, %arg162 : i8, %arg163 : i8):
  %0 = llvm.icmp "eq" %arg162, %arg163 : i8
  %1 = llvm.and %0, %arg161 : i1
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

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

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

def icmp_ne_riscv_eq_icmp_ne_llvm_64_pseudo : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] :=
  {lhs:= icmp_neq_llvm_64, rhs:= icmp_ne_riscv_64_pseudo}

abbrev NameExt := SimplePersistentEnvExtension (Name × Name) (NameMap Name)

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 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 sub_from_constant_before := [llvm|
{
^0(%arg6 : i5, %arg7 : i5):
  %0 = llvm.mlir.constant(10 : i5) : i5
  %1 = llvm.sub %0, %arg6 : i5
  %2 = llvm.add %1, %arg7 : i5
  "llvm.return"(%2) : (i5) -> ()
}
]

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

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

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

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

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

def shrink_and_before := [llvm|
{
^0(%arg9 : i64):
  %0 = llvm.mlir.constant(42) : i64
  %1 = llvm.and %arg9, %0 : i64
  %2 = llvm.trunc %1 : i64 to i31
  "llvm.return"(%2) : (i31) -> ()
}
]

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

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

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

instance [ToString w] : ToString (Option w) where
  toString
    | some x => s!"(some {toString x})"
    | none   => "(none)"

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

def test_const_shr_exact_and_1_ne_0_after := [llvm|
{
^0(%arg6 : 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, %arg6 overflow<nuw> : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.icmp "ne" %4, %2 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

def alive_AddSub_1202_src :=
[sllvm| {
^bb0(%x : i64, %C : i64):
  %v1 = llvm.mlir.constant -1 : i64
  %v2 = llvm.xor %x, %v1 : i64
  %v3 = llvm.add %v2, %C : i64
  llvm.return %v3 : i64
}]

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

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

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

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

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

def in_constant_mone_vary_after := [llvm|
{
^0(%arg24 : i4, %arg25 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.or %arg24, %0 : i4
  "llvm.return"(%1) : (i4) -> ()
}
]

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

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

def add_or_and_after := [llvm|
{
^0(%arg19 : i32, %arg20 : i32):
  %0 = llvm.add %arg19, %arg20 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

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

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

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

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

def select_sub_before := [llvm|
{
^0(%arg9 : i1, %arg10 : i17, %arg11 : i17):
  %0 = llvm.sub %arg10, %arg11 : i17
  %1 = "llvm.select"(%arg9, %0, %arg10) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i17, i17) -> i17
  "llvm.return"(%1) : (i17) -> ()
}
]

def canonicalize_icmp_sle_4 : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant 4 : i64
      %1 = llvm.icmp.sle %c, %x : i64
      llvm.return %1 : i1
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant 4 : i64
      %1 = llvm.icmp.sge %x, %c : i64
      llvm.return %1 : 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) -> ()
}
]

BitVec.ofBool in Init.Data.BitVec.Basic

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

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

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

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

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

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

def flipAccept (M : NFA α σ) : NFA α σ where
  start := M.start
  accept := M.accept.compl
  step := M.step

def VariadicDialect : Dialect where
  Op := Op
  Ty := Ty

def_signature for VariadicDialect where
  | .const _  => () -> .int
  | .add n    => ${List.replicate n .int} → .int

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 and_to_xor3_before := [llvm|
{
^0(%arg115 : i32, %arg116 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg115, %arg116 : i32
  %2 = llvm.and %arg116, %arg115 : i32
  %3 = llvm.xor %2, %0 : i32
  %4 = llvm.and %1, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def dec_inj {n : Nat} : Function.Injective (dec (n := n)) :=

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

instance : DialectPrint LLVM :=

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

structure NoWrapFlags where
  nsw : Bool := false
  nuw : Bool := false
  deriving Repr, DecidableEq, Lean.ToExpr

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

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

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

def trunc_sel_equal_sext_after := [llvm|
{
^0(%arg77 : i32, %arg78 : i1):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.mlir.constant(42 : i32) : i32
  %2 = llvm.shl %arg77, %0 : i32
  %3 = llvm.ashr exact %2, %0 : i32
  %4 = "llvm.select"(%arg78, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

inductive ExTy
  | nat
  | bool
  deriving DecidableEq

def join (x y : TokenStream) : TokenStream  :=
  Stream.corec (β := TokenStream × TokenStream) (x, y) fun ⟨x, y⟩ =>
    match x 0, y 0 with
    | some _, some _ => (some (), (x.tail, y.tail))
    | some _, none => (none, (x, y.tail))
    | none, some _ => (none, (x.tail, y))
    | none, none => (none, (x.tail, y.tail))

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

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

def trunc_sandwich_min_shift1_after := [llvm|
{
^0(%arg68 : i32):
  %0 = llvm.mlir.constant(21 : i32) : i32
  %1 = llvm.lshr %arg68, %0 : i32
  %2 = llvm.trunc %1 overflow<nsw,nuw> : i32 to i12
  "llvm.return"(%2) : (i12) -> ()
}
]

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

@[simps]
instance finenum_fin : FinEnum (Fin n) where
  card := n
  equiv := by admit /- proof elided -/

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

def simplify_and_common_op_commute1_after := [llvm|
{
^0(%arg29 : i4, %arg30 : i4, %arg31 : i4):
  %0 = llvm.mlir.constant(0 : i4) : i4
  "llvm.return"(%0) : (i4) -> ()
}
]

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

Sum in Init.Core

Lean.Import in Lean.Setup
</all_available_defs>

<all_available_lemmas>
Bool.false_eq_true in Init.Data.Bool
IsEmpty.exists_iff in Mathlib.Logic.IsEmpty
Option.isSome_none in Init.Data.Option.Basic
iff_false in Init.SimpLemmas
Option.get_some in Init.Data.Option.Basic
Option.isSome_iff_exists in Init.Data.Option.Lemmas
forall_exists_index in Init.PropLemmas

theorem eq.ty_eq {v : Γ.Var t} {w : Γ.Var u} (h : v.eq w) : t = u

@[simp]
theorem Expr.op_mk {Γ : Ctxt d.Ty} {ty} {eff : EffectKind} (op : d.Op)
    (ty_eq : ty = DialectSignature.returnTypes op)
    (eff_le : DialectSignature.effectKind op ≤ eff)
    (args : HVector (Var Γ) (DialectSignature.sig op))
    (regArgs) :
    (Expr.mk op ty_eq eff_le args regArgs).op = op

@[simp]
theorem Expr.regArgs_mk {Γ : Ctxt d.Ty} {ty eff op}
    (ty_eq : ty = DialectSignature.returnTypes op)
    (eff_le : DialectSignature.effectKind op ≤ eff)
    (args : HVector (Var Γ) (DialectSignature.sig op)) (regArgs) :
    (Expr.mk op ty_eq eff_le args regArgs).regArgs = regArgs

@[simp] theorem appendCases_appendInl (v : Γ.Var t) :
    appendCases (motive := motive) left right v.appendInl = (left v)

@[simp]
theorem Expr.args_mk {Γ : Ctxt d.Ty} {ty eff op}
    (ty_eq : ty = DialectSignature.returnTypes op)
    (eff_le : DialectSignature.effectKind op ≤ eff)
    (args : HVector (Var Γ) (DialectSignature.sig op)) (regArgs) :
    (Expr.mk op ty_eq eff_le args regArgs).args = args

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

theorem select_icmp_eq_pow2_flipped_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬ofBool (x &&& 4#8 == 0#8) = 1#1 → x = x ||

theorem a_true_implies_b_false2_comm_proof : a_true_implies_b_false2_comm_before ⊑ a_true_implies_b_false2_comm_after

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

theorem test3i_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(29#32 ≥ ↑32 ∨ 29#32 ≥ ↑32) →
    zeroExtend 32 (ofBool (x_1 >>> 29#32 ||| 35#32 == x >>> 29#32 ||| 35#32)) =
      zeroExtend 32 (ofBool (-1#32 <ₛ x_1 ^^^ x))

@[simp, grind=] theorem length_cons (Γ : Ctxt α) (x : α) : (Γ.cons x).length = Γ.length + 1

theorem sle_smax4_proof : sle_smax4_before ⊑ sle_smax4_after

theorem select_icmp_ne_0_and_32_and_not_4096_proof : select_icmp_ne_0_and_32_and_not_4096_before ⊑ select_icmp_ne_0_and_32_and_not_4096_after

theorem icmp_ne_sext_sgt_zero_nofold_proof : icmp_ne_sext_sgt_zero_nofold_before ⊑ icmp_ne_sext_sgt_zero_nofold_after

@[simp] theorem Com.changeDialect_rets (f : DialectMorphism d d') (vs) :
    Com.changeDialect f (Com.rets vs : Com d Γ eff t)
    = Com.rets (vs.map' f.mapTy (fun _ v => v.toMap))

lemma RawCNFA.lift_wf (m : RawCNFA (BitVec n₁)) {f : Fin n₁ → Fin n₂} (hwf : m.WF) :
    m.lift f |>.WF

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

theorem exact_lshr_ne_proof : exact_lshr_ne_before ⊑ exact_lshr_ne_after

theorem f_var0_commutative_and_proof : f_var0_commutative_and_before ⊑ f_var0_commutative_and_after

theorem uadd_sat_flipped_wrong_bounds_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (BitVec.ofInt 32 (-12) ≤ᵤ x) = 1#1 → ofBool (BitVec.ofInt 32 (-13) <ᵤ x) = 1#1 → x + 9#32 = -1#32

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

theorem neg_not_signbit2_proof : neg_not_signbit2_before ⊑ neg_not_signbit2_after

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

theorem syncMap2_flip {f : α → β → γ} :
  syncMap₂ f xs ys = syncMap₂ (fun y x => f x y) ys xs

theorem and_min_7_8_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬ofBool (x <ᵤ BitVec.ofInt 8 (-8)) = 1#1 → BitVec.ofInt 8 (-8) &&& BitVec.ofInt 8 (-8) = x &&& BitVec.ofInt 8 (-8)

theorem test1_proof : test1_before ⊑ test1_after

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

theorem eq_signed_to_small_unsigned_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x == 17#32) = ofBool (x == 17#8)

@[simp]
lemma BitVec.cons_inj : cons b1 bv1 = cons b2 bv2 ↔ (b1 = b2) ∧ bv1 = bv2

theorem not_or_or_and_not_and_and_proof : not_or_or_and_not_and_and_before ⊑ not_or_or_and_not_and_and_after

@[simp]
lemma TermUnop.subst_arity' {op : TermUnop} : (op.subst t).arity + 1 = t.arity + 1

theorem slt_0_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (truncate 8 x <ₛ 0#8) = ofBool (x &&& 128#32 != 0#32)

theorem negate_sext_proof : negate_sext_before ⊑ negate_sext_after

theorem ashrslt_01_03_exact_proof : ashrslt_01_03_exact_before ⊑ ashrslt_01_03_exact_after

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

theorem and_zext_eq_odd_commuted_proof : and_zext_eq_odd_commuted_before ⊑ and_zext_eq_odd_commuted_after

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

theorem add_select_not_sext_proof : add_select_not_sext_before ⊑ add_select_not_sext_after

theorem negtest_near_pow2_cmpval_ashr_wrong_cmp_pred_thm (e : IntW 8) :
  icmp IntPred.eq (ashr e (const? 8 1) { «exact» := true }) (const? 8 5) ⊑
    icmp IntPred.eq e (const? 8 10)

theorem e_2086 :
    2 * (f &&& (d ^^^ e)) - 1 * (d &&& (e ^^^ f)) - 1 * (d |||  ~~~f) + 1 * (e ||| f) - 1 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 1 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 11 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 2 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 6 * ( ~~~f |||  ~~~(d ^^^ e)) + 11 * (e ^^^  ~~~(d &&& f)) + 3 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 6 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 2 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 11 * (e ||| (d &&& f)) - 1 *  ~~~(e ^^^ f) + 3 *  ~~~(d ||| e) - 2 *  ~~~( ~~~d ||| (e ^^^ f)) + 4 * (d &&& ( ~~~e ||| f)) + 5 * (d ||| e) + 5 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 * (f ^^^ ( ~~~d ||| (e &&& f))) - 5 * (e &&& f) - 11 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 5 * (f ^^^ (d ||| (e ||| f))) + 2 * (d ||| ( ~~~e &&& f)) + 2 * (d ^^^ ( ~~~e &&& f)) + 1 *  ~~~e - 6 *  ~~~(d &&& ( ~~~e &&& f)) - 2 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 7 *  ~~~(d ||| (e ^^^ f)) - 6 * (d ^^^ e) - 1 * (d ^^^ f) + 4 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 8 *  ~~~(d ||| (e ||| f)) + 29 *  ~~~(d ||| ( ~~~e ||| f)) - 8 *  ~~~( ~~~d ||| (e ||| f)) + 33 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 15 * ( ~~~d &&& ( ~~~e &&& f)) + 7 * ( ~~~d &&& (e &&& f)) - 2 * (d &&& ( ~~~e &&& f)) - 9 * (d &&& (e &&& f)) = 2 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f)))

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

theorem mul_add_to_mul_1_proof : mul_add_to_mul_1_before ⊑ mul_add_to_mul_1_after

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

theorem canonicalize_logic_first_or0_nswnuw_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.saddOverflow 112#32 = true ∨ True ∧ x.uaddOverflow 112#32 = true) →
    True ∧ (x ||| 15#32).saddOverflow 112#32 = true ∨ True ∧ (x ||| 15#32).uaddOverflow 112#32 = true → False

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

theorem lsb_mask_sign_sext_wrong_cst2_proof : lsb_mask_sign_sext_wrong_cst2_before ⊑ lsb_mask_sign_sext_wrong_cst2_after

theorem exact_ashr_ne_proof : exact_ashr_ne_before ⊑ exact_ashr_ne_after

@[simp]
lemma bv_to_set_or {m : CNFA n} (x y : BitVec m.m.stateMax) :
    (s ∈ bv_to_set (x ||| y)) ↔ (s ∈ bv_to_set x ∨ s ∈ bv_to_set y)

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

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

theorem bv_Select_859' :
    ∀ (e e_1 : LLVM.IntW 1),
      LLVM.select e e_1 (LLVM.xor e (LLVM.const? 1 (-1))) ⊑ LLVM.or (LLVM.xor e (LLVM.const? 1 (-1))) e_1

theorem test24_logical_proof : test24_logical_before ⊑ test24_logical_after

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

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

theorem lowmask_add_2_thm (e : IntW 8) : LLVM.and (add e (const? 8 (-64))) (const? 8 63) ⊑ LLVM.and e (const? 8 63)

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

theorem and_and_logic_or_2_thm (e e_1 e_2 : IntW 1) :
  select (LLVM.and e_2 e_1) (const? 1 1) (LLVM.and e e_2) ⊑ LLVM.and e_2 (select e_1 (const? 1 1) e)

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

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

theorem ashrslt_01_06_exact_proof : ashrslt_01_06_exact_before ⊑ ashrslt_01_06_exact_after

theorem icmp_shl_nsw_eq_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ (x <<< 5#32).sshiftRight' 5#32 ≠ x ∨ 5#32 ≥ ↑32) → ofBool (x <<< 5#32 == 0#32) = ofBool (x == 0#32)

theorem shl_or_disjoint_lshr_proof : shl_or_disjoint_lshr_before ⊑ shl_or_disjoint_lshr_after

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

theorem a_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1),
  ¬x_1 = 1#1 → True ∧ (1#32).saddOverflow (signExtend 32 x) = true → False

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

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

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

theorem not_and_and_or_no_or_commute1_proof : not_and_and_or_no_or_commute1_before ⊑ not_and_and_or_no_or_commute1_after

theorem 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 e_1301 :
    4 * (z |||  ~~~t) - 1 *  ~~~z + 1 *  ~~~(z &&& t) + 11 *  ~~~t - 3 *  ~~~(z ^^^ t) - 10 *  ~~~(z ||| t) + 2 *  ~~~(z |||  ~~~t) - 14 * (z &&&  ~~~t) + 1 * (z &&& t) = 2 *  ~~~(z &&&  ~~~z)

theorem 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 sge_smin2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 <ₛ x) = 1#1 → ofBool (x ≤ₛ x) = ofBool (x ≤ₛ x_1)

theorem xor_or_xor_common_op_commute3_proof : xor_or_xor_common_op_commute3_before ⊑ xor_or_xor_common_op_commute3_after

theorem pr51551_proof : pr51551_before ⊑ pr51551_after

theorem reassoc_x2_mul_nuw_proof : reassoc_x2_mul_nuw_before ⊑ reassoc_x2_mul_nuw_after

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

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

theorem slt_to_ugt_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 ^^^ 127#8 <ₛ x ^^^ 127#8) = ofBool (x <ᵤ x_1)

theorem test9_logical_proof : test9_logical_before ⊑ test9_logical_after

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

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

theorem test15g_proof : test15g_before ⊑ test15g_after

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

theorem ashr_ult_4_proof : ashr_ult_4_before ⊑ ashr_ult_4_after

theorem test1_proof : test1_before ⊑ test1_after

theorem mkOutEqZeroCircuitLeN_eval_eq_false_iff {arity : Type _}
  [DecidableEq arity] [Fintype arity] [Hashable arity] (p : FSM arity) (n : Nat)
  (env : Vars p.α arity (n + 1) → Bool) :
  ((mkOutEqZeroCircuitLeN p n).eval env = false) ↔
  (∀ (i : Nat) (hi : i < n + 1),
    env (Vars.outputs ⟨i, by omega⟩) = false)

theorem ExtEq.trans {Γ Δ Ξ : Context Ty} : Γ.ExtEq Δ → Δ.ExtEq Ξ → Γ.ExtEq Ξ

theorem lor_bor_left2_proof : lor_bor_left2_before ⊑ lor_bor_left2_after

theorem add_nuw_const_const_sub_proof : add_nuw_const_const_sub_before ⊑ add_nuw_const_const_sub_after

theorem and_two_ranges_to_mask_and_range_not_pow2_diff_proof : and_two_ranges_to_mask_and_range_not_pow2_diff_before ⊑ and_two_ranges_to_mask_and_range_not_pow2_diff_after

theorem ashrslt_02_01_proof : ashrslt_02_01_before ⊑ ashrslt_02_01_after

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

theorem lshrugt_02_07_exact_proof : lshrugt_02_07_exact_before ⊑ lshrugt_02_07_exact_after

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

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

theorem ule_or_min_proof : ule_or_min_before ⊑ ule_or_min_after

theorem test1_thm (e : IntW 177) : mul e (shl (const? 177 1) (const? 177 155)) ⊑ shl e (const? 177 155)

theorem lshrult_02_14_exact_proof : lshrult_02_14_exact_before ⊑ lshrult_02_14_exact_after

theorem test1_proof : test1_before ⊑ test1_after

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

theorem ashrslt_02_04_exact_proof : ashrslt_02_04_exact_before ⊑ ashrslt_02_04_exact_after

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

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

theorem eq_umin4_thm.extracted_1._1 : ∀ (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 positive_with_icmp_logical_thm (e : IntW 32) :
  select (icmp IntPred.ult e (const? 32 512)) (icmp IntPred.ult (add e (const? 32 128)) (const? 32 256))
      (const? 1 0) ⊑
    icmp IntPred.ult e (const? 32 128)

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_6_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_6_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_6_after

theorem add_smin_simplify2_proof : add_smin_simplify2_before ⊑ add_smin_simplify2_after

theorem select_icmp_eq_and_1_0_lshr_tv_proof : select_icmp_eq_and_1_0_lshr_tv_before ⊑ select_icmp_eq_and_1_0_lshr_tv_after

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

theorem a_false_implies_b_false2_comm_proof : a_false_implies_b_false2_comm_before ⊑ a_false_implies_b_false2_comm_after

theorem test2_proof : test2_before ⊑ test2_after

theorem test2_proof : test2_before ⊑ test2_after

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

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

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

theorem ule_umax4_proof : ule_umax4_before ⊑ ule_umax4_after

theorem test18_proof : test18_before ⊑ test18_after

theorem shl_lshr_eq_amt_multi_use_proof : shl_lshr_eq_amt_multi_use_before ⊑ shl_lshr_eq_amt_multi_use_after

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

theorem slt_zero_eq_i1_fail_signed_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  ¬31#32 ≥ ↑32 → ofBool (signExtend 32 x_1 == x >>> 31#32) = ofBool (x >>> 31#32 == signExtend 32 x_1)

theorem main5_like_logical_thm.extracted_1._5 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 &&& 7#32 == 7#32) = 1#1 →
    ofBool (x_1 &&& 7#32 != 7#32) = 1#1 → ofBool (x &&& 7#32 == 7#32) = 1#1 → 0#32 = zeroExtend 32 1#1

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_0_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_0_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_0_logical_after

theorem test4c_proof : test4c_before ⊑ test4c_after

theorem mul_selectp2_x_non_const_proof : mul_selectp2_x_non_const_before ⊑ mul_selectp2_x_non_const_after

theorem lshrult_01_01_exact_proof : lshrult_01_01_exact_before ⊑ lshrult_01_01_exact_after

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

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

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

theorem not_signbit_trunc_proof : not_signbit_trunc_before ⊑ not_signbit_trunc_after

theorem e_834 :
     - 1 *  ~~~(z &&&  ~~~z) + 1 * z + 1 *  ~~~(z |||  ~~~t) + 1 * (z &&&  ~~~t) - 1 * (z &&& t) = 1 * (z ^^^ t) - 1 *  ~~~(z &&&  ~~~t)

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

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

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

theorem ashrsgt_01_09_exact_proof : ashrsgt_01_09_exact_before ⊑ ashrsgt_01_09_exact_after

theorem xor_logic_and_or2_proof : xor_logic_and_or2_before ⊑ xor_logic_and_or2_after

theorem e_1528 :
     - 1 * ((a &&& c) ||| (b &&&  ~~~c)) - 11 *  ~~~(a &&&  ~~~c) - 5 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) + 5 *  ~~~(a ||| (b ||| c)) + 19 *  ~~~(a ||| ( ~~~b ||| c)) - 4 *  ~~~( ~~~a ||| (b ||| c)) - 10 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 5 * ( ~~~a &&& ( ~~~b &&& c)) + 2 * ( ~~~a &&& (b &&& c)) + 12 * (a &&& ( ~~~b &&& c)) + 6 * (a &&& (b &&& c)) =  - 11 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) + 2 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c)))

theorem and_or_not_not_commute2_proof : and_or_not_not_commute2_before ⊑ and_or_not_not_commute2_after

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

theorem trunc_shl_zext_64_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬7#8 ≥ ↑8 → ¬7#64 ≥ ↑64 → zeroExtend 64 (truncate 8 x <<< 7#8) = x <<< 7#64 &&& 128#64

theorem test_logical_proof : test_logical_before ⊑ test_logical_after

theorem demorgan_nor_use2c_thm (e e_1 : IntW 8) :
  LLVM.sdiv (LLVM.xor (LLVM.or (LLVM.xor e_1 (const? 8 (-1))) e) (const? 8 (-1)))
      (mul (LLVM.or (LLVM.xor e_1 (const? 8 (-1))) e) (const? 8 23)) ⊑
    LLVM.sdiv (LLVM.xor (LLVM.or e (LLVM.xor e_1 (const? 8 (-1)))) (const? 8 (-1)))
      (mul (LLVM.or e (LLVM.xor e_1 (const? 8 (-1)))) (const? 8 23))

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

theorem test1_proof : test1_before ⊑ test1_after

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

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

@[simp]
theorem BitVec.zero_concat (b : Bool) : (0#0).concat b = BitVec.ofBool b

theorem mul_splat_fold_proof : mul_splat_fold_before ⊑ mul_splat_fold_after

theorem and_ne_with_one_bit_diff_constants1_logical_proof : and_ne_with_one_bit_diff_constants1_logical_before ⊑ and_ne_with_one_bit_diff_constants1_logical_after

theorem test2_thm.extracted_1._1 : ∀ (x : BitVec 8),
  zeroExtend 64 (zeroExtend 32 (zeroExtend 16 x)) = zeroExtend 64 x

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

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

theorem ult_swap_and_max_proof : ult_swap_and_max_before ⊑ ult_swap_and_max_after

theorem e_2094 :
    1 * (f ^^^ ( ~~~d &&& (e ||| f))) + 2 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 5 *  ~~~( ~~~d ||| (e &&& f)) - 3 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 1 *  ~~~(d &&& f) - 1 * (f ^^^ (d ||| (e ||| f))) + 4 *  ~~~(d |||  ~~~e) - 3 * (d ^^^ e) + 7 * (e ^^^  ~~~(d ||| (e &&& f))) - 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) + 11 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 2 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 3 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 *  ~~~(d &&& (e ^^^ f)) - 5 * (d &&& ( ~~~e ||| f)) - 3 *  ~~~(d &&& (e &&& f)) + 1 * ((d &&& e) ^^^ (e ||| f)) - 7 * (e |||  ~~~(d |||  ~~~f)) - 7 * (f ||| (d ^^^ e)) + 4 * (d ^^^ (e ^^^ f)) - 2 * (d ||| ( ~~~e &&& f)) - 3 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 1 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 3 *  ~~~(e &&& f) + 1 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 1 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 3 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 5 * (e |||  ~~~(d ||| f)) - 3 *  ~~~(d &&&  ~~~e) - 7 * (e ^^^ (d ||| f)) + 1 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 2 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 2 *  ~~~(d ^^^ e) - 1 * (f &&& (d |||  ~~~e)) + 1 * (d &&& (e ^^^ f)) - 1 * (f ^^^  ~~~(d ||| e)) - 6 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 13 *  ~~~(d ||| (e ||| f)) + 18 *  ~~~(d ||| ( ~~~e ||| f)) + 26 * ( ~~~d &&& (e &&& f)) + 16 * (d &&& ( ~~~e &&& f)) + 19 * (d &&& (e &&& f)) = 15 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 12 *  ~~~( ~~~d ||| (e ||| f))

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

theorem EqualUpTo_ofBitVecZextMsb_add (a b : BitVec w) :
    EqualUpTo (w + 1)
    (BitStream.ofBitVecZextMsb a + BitStream.ofBitVecZextMsb b)
    (BitStream.ofBitVecZextMsb (a + b))

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

theorem xor_nosignbit_select_shl_proof : xor_nosignbit_select_shl_before ⊑ xor_nosignbit_select_shl_after

theorem n11_wrong_pred3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x_1 + x != x) = ofBool (x_1 != 0#8)

theorem e_637 :
    1 *  ~~~(x &&&  ~~~y) + 1 * (x ||| y) + 11 * (x |||  ~~~y) - 1 *  ~~~x - 6 * x - 11 * y - 6 *  ~~~(x ||| y) + 17 *  ~~~(x |||  ~~~y) + 1 * (x &&&  ~~~y) + 9 * (x &&& y) = 5 *  ~~~(x ^^^ y) + 7 * (x ^^^ y)

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

theorem mul64_low_proof : mul64_low_before ⊑ mul64_low_after

theorem n10_proof : n10_before ⊑ n10_after

theorem e_934 :
    2 *  ~~~(z &&&  ~~~t) - 1 *  ~~~(z &&& t) + 11 * t - 1 *  ~~~(z ||| t) - 12 *  ~~~(z |||  ~~~t) - 17 * (z &&& t) = 3 * (z &&&  ~~~t) - 4 * z

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

theorem test_sext_zext_thm.extracted_1._1 : ∀ (x : BitVec 16), signExtend 64 (zeroExtend 32 x) = zeroExtend 64 x

theorem main10_logical_thm.extracted_1._4 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 64#32 == 0#32) = 1#1 → ¬ofBool (x &&& 192#32 == 0#32) = 1#1 → 0#1 = 1#1 → 2#32 = 1#32

theorem test_thm (e : IntW 32) :
  icmp IntPred.eq (LLVM.and (shl e (const? 32 8)) (const? 32 (-16777216))) (const? 32 167772160) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 16711680)) (const? 32 655360)

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

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

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

theorem reassoc_mul_nuw_thm (e : IntW 32) :
  mul (mul e (const? 32 4) { «nsw» := false, «nuw» := true }) (const? 32 65) { «nsw» := false, «nuw» := true } ⊑
    mul e (const? 32 260) { «nsw» := false, «nuw» := true }

theorem test5_proof : test5_before ⊑ test5_after

theorem neg_nsw_slt_n1_proof : neg_nsw_slt_n1_before ⊑ neg_nsw_slt_n1_after

theorem lshrult_01_03_proof : lshrult_01_03_before ⊑ lshrult_01_03_after

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

theorem src4_proof : src4_before ⊑ src4_after

theorem PR42691_10_logical_proof : PR42691_10_logical_before ⊑ PR42691_10_logical_after

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

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

theorem neg_not_signbit2_proof : neg_not_signbit2_before ⊑ neg_not_signbit2_after

theorem not_and_and_or_no_or_commute1_proof : not_and_and_or_no_or_commute1_before ⊑ not_and_and_or_no_or_commute1_after

theorem t5_ugt_slt_0_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (65535#32 <ᵤ x_1) = 1#1 → ofBool (65535#32 <ₛ x_1) = 1#1 → False

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

theorem select_bittest_to_add_proof : select_bittest_to_add_before ⊑ select_bittest_to_add_after

theorem lshr_and_add_proof : lshr_and_add_before ⊑ lshr_and_add_after

theorem logical_and_bitwise_and_icmps_comm3_proof : logical_and_bitwise_and_icmps_comm3_before ⊑ logical_and_bitwise_and_icmps_comm3_after

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

theorem n2_proof : n2_before ⊑ n2_after

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

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

theorem ashr_ashr_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(5#32 ≥ ↑32 ∨ 7#32 ≥ ↑32) → ¬12#32 ≥ ↑32 → (x.sshiftRight' 5#32).sshiftRight' 7#32 = x.sshiftRight' 12#32

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

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

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

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

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

theorem lshrugt_02_03_proof : lshrugt_02_03_before ⊑ lshrugt_02_03_after

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

theorem scalar_i16_signbit_lshr_and_eq_thm (e e_1 : IntW 16) :
  icmp IntPred.eq (LLVM.and (lshr (const? 16 (-32768)) e_1) e) (const? 16 0) ⊑
    icmp IntPred.eq (LLVM.and (lshr (const? 16 (-32768)) e_1 { «exact» := true }) e) (const? 16 0)

theorem Term.toBV_of_KInductionCircuits'
    {wcard tcard bcard ncard icard pcard : Nat}
    (P : Prop)
    (tctx : Term.Ctx wcard tcard)
    (p : MultiWidth.Term bcard ncard icard pcard tctx .prop)
    (pNondep : Nondep.Term)
    (_hpNondep : pNondep = (.ofDepTerm p))
    (fsm : TermFSM wcard tcard bcard ncard icard pcard pNondep)
    (_hfsm : fsm = mkTermFsmNondep wcard tcard bcard ncard icard pcard pNondep)
    (n : Nat)
    (circs : KInductionCircuits fsm.toFsmZext n)
    (hCircs : circs.IsLawful)
    (sCert : Lean.Elab.Tactic.BVDecide.Frontend.LratCert)
    (hs : Circuit.verifyCircuit (circs.mkSafetyCircuit) sCert = true)
    (indCert : Lean.Elab.Tactic.BVDecide.Frontend.LratCert)
    (hind : Circuit.verifyCircuit (circs.mkIndHypCycleBreaking) indCert = true)
    (wenv : WidthExpr.Env wcard)
    (tenv : tctx.Env wenv)
    (benv : Term.BoolEnv bcard)
    (nenv : Term.NatEnv ncard)
    (ienv : Term.IntEnv icard)
    (penv : Predicate.Env pcard)
    (hp : p.toBV benv nenv ienv penv tenv = P) :
    P

theorem pr9998_thm (e : IntW 32) :
  icmp IntPred.ugt (sext 64 (ashr (shl e (const? 32 31)) (const? 32 31) { «exact» := true }))
      (const? 64 7297771788697658747) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 1)) (const? 32 0)

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 bools_multi_uses2_logical_thm.extracted_1._17 : ∀ (x x_1 : BitVec 1),
  ¬x_1 ^^^ 1#1 = 1#1 → ¬x_1 = 1#1 → 0#1 = 1#1 → True → False

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

@[simp]
theorem or_sub_xor_eq_and {a b : BitVec w} : (a ||| b) - (a ^^^ b) = a &&& b

theorem different_size_zext_zext_ne_commute_thm (e : IntW 4) (e_1 : IntW 7) :
  icmp IntPred.ne (zext 25 e_1) (zext 25 e) ⊑ icmp IntPred.ne e_1 (zext 7 e)

theorem ashrslt_03_00_proof : ashrslt_03_00_before ⊑ ashrslt_03_00_after

theorem or_or_logic_and_2_proof : or_or_logic_and_2_before ⊑ or_or_logic_and_2_after

theorem e_1080 :
     - 6 * (z |||  ~~~t) - 6 *  ~~~t - 6 * t - 1 *  ~~~(z &&&  ~~~z) - 11 * (z ^^^ t) + 18 *  ~~~(z |||  ~~~t) + 24 * (z &&&  ~~~t) + 13 * (z &&& t) =  - 13 *  ~~~(z ||| t)

theorem commutativity_constant_14_vary_proof : commutativity_constant_14_vary_before ⊑ commutativity_constant_14_vary_after

theorem t0_basic_proof : t0_basic_before ⊑ t0_basic_after

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

theorem test_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 64),
  x = 1#1 →
    4#64 ≥ ↑64 ∨
        3#64 ≥ ↑64 ∨
          True ∧ (x_1 >>> 4#64).saddOverflow (x_1 >>> 3#64) = true ∨
            True ∧ (x_1 >>> 4#64).uaddOverflow (x_1 >>> 3#64) = true →
      ¬(16#64 = 0 ∨ 8#64 = 0) → False

theorem test19_commutative1_thm (e e_1 : IntW 32) :
  urem e_1 (add (shl (const? 32 1) e) (LLVM.and (shl (const? 32 1) e) (shl (const? 32 1) e_1))) ⊑
    LLVM.and e_1
      (add
        (add (shl (const? 32 1) e { «nsw» := false, «nuw» := true })
          (LLVM.and (shl (const? 32 1) e { «nsw» := false, «nuw» := true })
            (shl (const? 32 1) e_1 { «nsw» := false, «nuw» := true })))
        (const? 32 (-1)))

theorem head_isNone_of_bisim_stuck {α : Type} (x : Stream α) : x ~ stuck α → x.head = none

theorem substitute_constant_and_eq_eq_commute_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 == x) = 1#1 → 0#1 = ofBool (x_1 == 42#8) &&& ofBool (x == 42#8)

theorem sub_eq_mul_and_not_sub_xor :
    x - y = 2 * (x &&& ~~~ y) - (x ^^^ y)

theorem or_trunc_lshr_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬1#8 ≥ ↑8 → 1#6 ≥ ↑6 ∨ True ∧ (truncate 6 x >>> 1#6 &&& BitVec.ofInt 6 (-32) != 0) = true → False

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

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

theorem test_ne_11_and_15_add_10_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x + 10#8 &&& 15#8 != 11#8) = ofBool (x &&& 15#8 != 1#8)

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

theorem ule_and_min_commute_proof : ule_and_min_commute_before ⊑ ule_and_min_commute_after

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

theorem ult_and_not_max_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 != -1#8) &&& ofBool (x_1 <ᵤ x) = ofBool (x_1 <ᵤ x)

theorem smear_set_bit_proof : smear_set_bit_before ⊑ smear_set_bit_after

theorem exact_ashr_ne_both_equal_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ BitVec.ofInt 8 (-128) >>> x <<< x ≠ BitVec.ofInt 8 (-128) ∨ x ≥ ↑8) →
    ofBool ((BitVec.ofInt 8 (-128)).sshiftRight' x != BitVec.ofInt 8 (-128)) = ofBool (x != 0#8)

theorem t7_ugt_sgt_neg1_thm.extracted_1._15 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (65535#32 <ᵤ x_2) = 1#1 → ¬ofBool (65535#32 <ₛ x_2) = 1#1 → ofBool (x_2 <ₛ 0#32) = 1#1 → x_2 = x

theorem not_or_or_and_not_and_and_commute1_proof : not_or_or_and_not_and_and_commute1_before ⊑ not_or_or_and_not_and_and_commute1_after

theorem mul_unkV_oddC_sge_thm (e : IntW 8) :
  icmp IntPred.sge (mul e (const? 8 3)) (const? 8 0) ⊑
    icmp IntPred.sgt (mul e (const? 8 3)) (const? 8 (-1))

theorem sle_smax3_proof : sle_smax3_before ⊑ sle_smax3_after

theorem sub_to_and_thm (e e_1 : IntW 32) :
  sub (LLVM.xor e_1 e) (LLVM.or e_1 e) ⊑ sub (const? 32 0) (LLVM.and e_1 e)

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

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

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

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

theorem test2_proof : test2_before ⊑ test2_after

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

theorem shl_trunc_bigger_shl_proof : shl_trunc_bigger_shl_before ⊑ shl_trunc_bigger_shl_after

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

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

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

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 e_838 :
    2 *  ~~~(z ^^^ t) + 1 *  ~~~(z &&&  ~~~z) - 5 * (z ^^^ t) + 4 * (z &&&  ~~~t) - 3 * (z &&& t) = 3 *  ~~~(z ||| t) - 4 *  ~~~(z |||  ~~~t)

theorem test4_thm (e : IntW 1023) :
  select (icmp IntPred.slt e (const? 1023 0)) (const? 1023 (-1)) (const? 1023 0) ⊑
    ashr e (const? 1023 1022)

theorem test_shl_nuw__nuw_is_safe_proof : test_shl_nuw__nuw_is_safe_before ⊑ test_shl_nuw__nuw_is_safe_after

theorem add_constant_equal_with_the_top_bit_of_demandedbits_insertpt_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  (x_1 + 16#32 ||| x) &&& 24#32 = (x_1 ^^^ 16#32 ||| x) &&& 24#32

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

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

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

theorem not_or_or_and_not_and_and_commute2_or_proof : not_or_or_and_not_and_and_commute2_or_before ⊑ not_or_or_and_not_and_and_commute2_or_after

theorem lowmask_sub_zext_commute_thm (e : IntW 5) (e_1 : IntW 17) :
  LLVM.and (sub e_1 (zext 17 e)) (const? 17 31) ⊑ zext 17 (sub (trunc 5 e_1) e)

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

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

theorem main7e_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 ashrsgt_02_14_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬2#4 ≥ ↑4 → ofBool (BitVec.ofInt 4 (-2) <ₛ x.sshiftRight' 2#4) = ofBool (BitVec.ofInt 4 (-5) <ₛ x)

theorem andcond.010.inv.inner.cond.in.inner.sel_proof : andcond.010.inv.inner.cond.in.inner.sel_before ⊑ andcond.010.inv.inner.cond.in.inner.sel_after

theorem test_sub__nuw_is_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 2147483647#32 == 1073741824#32) = 1#1 →
    ¬(True ∧ (BitVec.ofInt 32 (-2147483648)).usubOverflow (x &&& 2147483647#32) = true) →
      1073741824#32 = BitVec.ofInt 32 (-2147483648) - (x &&& 2147483647#32)

theorem mul_select_zext_proof : mul_select_zext_before ⊑ mul_select_zext_after

theorem main6d_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 != 3#32) ||

theorem sgt_smin1_thm (e e_1 : IntW 32) :
  icmp IntPred.sgt (select (icmp IntPred.slt e_1 e) e_1 e) e_1 ⊑ const? 1 0

theorem main12_proof : main12_before ⊑ main12_after

theorem cmpne_xor_cst3_proof : cmpne_xor_cst3_before ⊑ cmpne_xor_cst3_after

theorem trunc_shl_15_i16_i32_thm (e : IntW 32) : trunc 16 (shl e (const? 32 15)) ⊑ shl (trunc 16 e) (const? 16 15)

theorem PR38021_proof : PR38021_before ⊑ PR38021_after

theorem lor_band_left1_proof : lor_band_left1_before ⊑ lor_band_left1_after

theorem ashr_ugt_12_proof : ashr_ugt_12_before ⊑ ashr_ugt_12_after

theorem samesign_inverted_commute3_proof : samesign_inverted_commute3_before ⊑ samesign_inverted_commute3_after

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

theorem test3_proof : test3_before ⊑ test3_after

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

theorem p0_thm (e : IntW 8) :
  icmp IntPred.sge (LLVM.and e (const? 8 3)) e ⊑ icmp IntPred.slt e (const? 8 4)

theorem icmp_eq_zext_ne_zero_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (zeroExtend 32 (ofBool (x != 0#32)) == x) = ofBool (x <ᵤ 2#32)

theorem select_icmp_eq_and_1_0_or_2_proof : select_icmp_eq_and_1_0_or_2_before ⊑ select_icmp_eq_and_1_0_or_2_after

theorem trunc_sandwich_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(28#32 ≥ ↑32 ∨ 2#12 ≥ ↑12) →
    30#32 ≥ ↑32 ∨
        True ∧ signExtend 32 (truncate 12 (x >>> 30#32)) ≠ x >>> 30#32 ∨
          True ∧ zeroExtend 32 (truncate 12 (x >>> 30#32)) ≠ x >>> 30#32 →
      False

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

theorem ne_umax3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x <ᵤ x_1 + 3#32) = 1#1 → ofBool (x_1 + 3#32 != x_1 + 3#32) = ofBool (x_1 + 3#32 <ᵤ x)

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

theorem lor_band_left2_proof : lor_band_left2_before ⊑ lor_band_left2_after

theorem flip_masked_bit_proof : flip_masked_bit_before ⊑ flip_masked_bit_after

theorem or_nosignbit_select_shl_proof : or_nosignbit_select_shl_before ⊑ or_nosignbit_select_shl_after

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 substitute_constant_and_eq_ugt_swap_logical_proof : substitute_constant_and_eq_ugt_swap_logical_before ⊑ substitute_constant_and_eq_ugt_swap_logical_after

theorem neg_sgt_42_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (42#32 <ₛ 0#32 - x) = ofBool (x + -1#32 <ₛ BitVec.ofInt 32 (-43))

theorem negative1_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 <ₛ x &&& 2147483647#32) = 1#1 → 0#1 = ofBool (x_1 <ₛ x &&& 2147483647#32) &&& ofBool (0#32 <ₛ x_1)

theorem sdiv_x_by_const_cmp_x_proof : sdiv_x_by_const_cmp_x_before ⊑ sdiv_x_by_const_cmp_x_after

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

theorem t20_proof : t20_before ⊑ t20_after

theorem trunc_shl_lshr_infloop_proof : trunc_shl_lshr_infloop_before ⊑ trunc_shl_lshr_infloop_after

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

theorem pr51551_2_thm (e e_1 : IntW 32) :
  icmp IntPred.eq
      (LLVM.and (mul (LLVM.or (LLVM.and e_1 (const? 32 (-7))) (const? 32 1)) e { «nsw» := true, «nuw» := false })
        (const? 32 1))
      (const? 32 0) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 1)) (const? 32 0)

theorem ugt_swap_and_min_commute_logical_proof : ugt_swap_and_min_commute_logical_before ⊑ ugt_swap_and_min_commute_logical_after

theorem scalar_i32_shl_and_negC_eq_proof : scalar_i32_shl_and_negC_eq_before ⊑ scalar_i32_shl_and_negC_eq_after

theorem t11_no_shift_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 x_2 : BitVec 32),
  ¬(64#32 - x_1 ≥ ↑32 ∨ zeroExtend 64 (x_1 + BitVec.ofInt 32 (-64)) ≥ ↑64) →
    ofBool (x_2 <<< (64#32 - x_1) &&& truncate 32 (x >>> zeroExtend 64 (x_1 + BitVec.ofInt 32 (-64))) != 0#32) =
      ofBool (x &&& zeroExtend 64 x_2 != 0#64)

theorem icmp_eq_zext_eq_non_boolean_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (zeroExtend 32 (ofBool (x == 2#32)) == x) = ofBool (x == 0#32)

theorem and_ranges_signed_pred_proof : and_ranges_signed_pred_before ⊑ and_ranges_signed_pred_after

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

theorem trunc_ashr_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬8#36 ≥ ↑36 → 8#32 ≥ ↑32 → False

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)

@[simp] lemma fals_and (c : Circuit α) :
  Circuit.fals &&& c = Circuit.fals

theorem PR60818_sgt_proof : PR60818_sgt_before ⊑ PR60818_sgt_after

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

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 e_189 :
    1 *  ~~~(x &&& y) - 5 * (x |||  ~~~y) + 4 *  ~~~(x ||| y) - 1 *  ~~~(x |||  ~~~y) + 9 * (x &&&  ~~~y) + 10 * (x &&& y) = 5 * x

theorem mullo_variant3_proof : mullo_variant3_before ⊑ mullo_variant3_after

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

theorem e_1691 :
     - 2 * (a ||| (b ^^^ c)) + 2 * (a ^^^ b) + 1 * (b ^^^ ( ~~~a &&& (b ^^^ c))) - 2 * (b ^^^ (a |||  ~~~c)) - 11 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 3 * (b ||| (a &&& c)) - 6 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) + 4 * (b &&& (a |||  ~~~c)) - 2 *  ~~~(a &&& b) - 1 * (a &&& (b ||| c)) + 4 * (c &&& (a ^^^ b)) + 1 *  ~~~(a ||| b) - 5 * (b ^^^ (a &&& (b ^^^ c))) - 6 * (a ||| (b &&& c)) - 1 * c + 2 *  ~~~(a |||  ~~~b) - 2 *  ~~~(a ^^^ b) - 7 * (c ^^^  ~~~(a &&& (b ||| c))) + 1 *  ~~~( ~~~a ||| (b ^^^ c)) - 1 * (b &&&  ~~~c) - 6 * (c ^^^ (a ||| ( ~~~b ||| c))) + 1 * ( ~~~a ||| (b ^^^ c)) + 28 *  ~~~(a ||| (b ||| c)) + 32 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 10 * ( ~~~a &&& ( ~~~b &&& c)) + 15 * ( ~~~a &&& (b &&& c)) + 33 * (a &&& ( ~~~b &&& c)) + 27 * (a &&& (b &&& c)) =  - 11 *  ~~~(a ||| ( ~~~b ||| c)) - 39 *  ~~~( ~~~a ||| (b ||| c))

theorem xor_ugt_2_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8), True ∧ (x &&& 63#8 &&& 64#8 != 0) = true → False

theorem test_add_nuw__all_are_safe_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 1073741823#32 == 3#32) = 1#1 →
    ¬(True ∧ (x &&& 1073741823#32).uaddOverflow 1#32 = true) →
      True ∧ (x &&& 1073741823#32).saddOverflow 1#32 = true ∨ True ∧ (x &&& 1073741823#32).uaddOverflow 1#32 = true →
        False

@[simp] theorem sup_impure_eq : max e impure  = impure

theorem e_229 :
     - 7 * (x ^^^ y) + 1 *  ~~~x + 2 *  ~~~(x &&& y) + 11 * y + 1 * x - 4 *  ~~~(x |||  ~~~y) - 9 * (x &&& y) =  - 4 * (x &&&  ~~~y) + 3 *  ~~~(x &&&  ~~~y)

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

theorem test22_thm.extracted_1._1 : ∀ (x : BitVec 14),
  ¬7#14 ≥ ↑14 → ofBool (x <<< 7#14 == 0#14) = ofBool (x &&& 127#14 == 0#14)

theorem test11_thm (e e_1 : IntW 32) :
  trunc 64 (shl (zext 128 e_1) (LLVM.and (zext 128 e) (const? 128 31))) ⊑
    shl (zext 64 e_1) (zext 64 (LLVM.and e (const? 32 31)) { «nneg» := true }) { «nsw» := true, «nuw» := true }

theorem test12_logical_thm (e e_1 : IntW 32) :
  select (icmp IntPred.ult e_1 e) (icmp IntPred.ule e_1 e) (const? 1 0) ⊑ icmp IntPred.ult e_1 e

theorem and_two_ranges_to_mask_and_range_thm (e : IntW 8) :
  LLVM.and (icmp IntPred.ugt (add e (const? 8 (-97))) (const? 8 25))
      (icmp IntPred.ugt (add e (const? 8 (-65))) (const? 8 25)) ⊑
    icmp IntPred.ult (add (LLVM.and e (const? 8 (-33))) (const? 8 (-91))) (const? 8 (-26))

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

theorem shl_add_log_may_cause_poison_pr62175_with_nuw_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ 4#8 <<< x >>> x ≠ 4#8 ∨ x ≥ ↑8) → ¬x + 2#8 ≥ ↑8 → x_1 * 4#8 <<< x = x_1 <<< (x + 2#8)

theorem add_select_not_sext_proof : add_select_not_sext_before ⊑ add_select_not_sext_after

theorem ashrslt_02_15_proof : ashrslt_02_15_before ⊑ ashrslt_02_15_after

theorem ashrslt_02_01_proof : ashrslt_02_01_before ⊑ ashrslt_02_01_after

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

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

theorem and_ne_with_one_bit_diff_constants3_logical_proof : and_ne_with_one_bit_diff_constants3_logical_before ⊑ and_ne_with_one_bit_diff_constants3_logical_after

theorem and_nosignbit_shl_proof : and_nosignbit_shl_before ⊑ and_nosignbit_shl_after

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

theorem orn_and_cmp_2_partial_logical_proof : orn_and_cmp_2_partial_logical_before ⊑ orn_and_cmp_2_partial_logical_after

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

theorem trunc_lshr_sext_wide_input_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬9#32 ≥ ↑32 →
    ¬(9#16 ≥ ↑16 ∨ True ∧ signExtend 16 (truncate 8 (x.sshiftRight' 9#16)) ≠ x.sshiftRight' 9#16) →
      truncate 8 (signExtend 32 x >>> 9#32) = truncate 8 (x.sshiftRight' 9#16)

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

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

theorem intMin_neq_one {w : Nat} (h : w > 1): BitVec.intMin w ≠ 1

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

theorem ashr_ult_exact_near_pow2_cmpval_proof : ashr_ult_exact_near_pow2_cmpval_before ⊑ ashr_ult_exact_near_pow2_cmpval_after

theorem t7_ugt_sgt_neg1_proof : t7_ugt_sgt_neg1_before ⊑ t7_ugt_sgt_neg1_after

theorem test23_thm (e : IntW 8) :
  LLVM.xor (LLVM.or (LLVM.xor (LLVM.or e (const? 8 (-2))) (const? 8 13)) (const? 8 1)) (const? 8 12) ⊑
    const? 8 (-1)

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7b_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7b_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7b_logical_after

theorem sext_multiuse_proof : sext_multiuse_before ⊑ sext_multiuse_after

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

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

theorem eq_3210_proof : eq_3210_before ⊑ eq_3210_after

theorem PR38781_thm (e e_1 : IntW 32) :
  LLVM.and (LLVM.xor (lshr e_1 (const? 32 31)) (const? 32 1)) (LLVM.xor (lshr e (const? 32 31)) (const? 32 1)) ⊑
    zext 32 (icmp IntPred.sgt (LLVM.or e_1 e) (const? 32 (-1)))

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

theorem gt_signed_to_small_unsigned_proof : gt_signed_to_small_unsigned_before ⊑ gt_signed_to_small_unsigned_after

theorem positive_biggerlshr_shlnuwnsw_lshrexact_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x >>> 6#8 <<< 6#8 ≠ x ∨
        6#8 ≥ ↑8 ∨
          True ∧ (x >>> 6#8 <<< 3#8).sshiftRight' 3#8 ≠ x >>> 6#8 ∨
            True ∧ x >>> 6#8 <<< 3#8 >>> 3#8 ≠ x >>> 6#8 ∨ 3#8 ≥ ↑8) →
    True ∧ x >>> 3#8 <<< 3#8 ≠ x ∨ 3#8 ≥ ↑8 → False

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

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

theorem alive_AddSub_1309  (w : Nat)   : alive_AddSub_1309_src w  ⊑ alive_AddSub_1309_tgt w

@[simp] lemma eval_scanAnd (x : Unit → BitStream) : scanAnd.eval x = (x ()).scanAnd

theorem alive_AndOrXor_2475 : alive_AndOrXor_2475_src ⊑ alive_AndOrXor_2475_tgt

theorem src_proof : src_before ⊑ src_after

theorem e_1418 :
     - 7 * z - 11 * (z ||| t) - 6 * (z ^^^ t) + 3 *  ~~~t + 1 * (z |||  ~~~t) - 2 * t - 3 *  ~~~(z ||| t) + 20 *  ~~~(z |||  ~~~t) + 21 * (z &&&  ~~~t) + 19 * (z &&& t) = 1 *  ~~~(z &&& t)

theorem sub_2_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 1) (x_2 : BitVec 8),
  ¬x_1 = 1#1 → x_2 - (x ^^^ 123#8) ^^^ -1#8 = BitVec.ofInt 8 (-2) - ((x ^^^ BitVec.ofInt 8 (-124)) + x_2)

theorem e_2205 :
     - 5 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 1 * (e &&&  ~~~f) - 1 *  ~~~( ~~~d &&& (e ||| f)) + 1 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 4 * ( ~~~d ||| (e ^^^ f)) + 7 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 2 * (d ^^^ (e &&& f)) - 1 * (e ||| (d &&& f)) - 7 * (e ^^^  ~~~(d ||| (e &&& f))) + 1 * (d &&&  ~~~e) + 2 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 5 * (f ^^^  ~~~(d &&&  ~~~e)) + 4 * (f &&&  ~~~(d &&&  ~~~e)) + 1 * e - 6 * (d ||| ( ~~~e &&& f)) - 1 * (f ^^^ (d &&& e)) + 7 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 3 * (e ||| (d ^^^ f)) - 5 * (f ^^^  ~~~(d ||| (e &&& f))) + 7 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 11 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 2 * (d ||| e) + 11 * (e |||  ~~~(d |||  ~~~f)) - 1 * (e ^^^ ( ~~~d ||| (e &&& f))) - 5 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 1 * (f ^^^  ~~~(d &&& e)) + 11 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) + 7 * ((d &&& e) |||  ~~~(e ||| f)) + 1 *  ~~~(d ^^^ ( ~~~e ||| f)) - 11 * (d &&& (e ||| f)) + 2 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 3 *  ~~~(e |||  ~~~f) + 5 * (e ^^^  ~~~(d |||  ~~~f)) + 1 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 1 * ((d &&&  ~~~e) ||| (e ^^^ f)) - 7 * (d &&&  ~~~f) - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 1 *  ~~~f - 11 * (f ^^^ ( ~~~d ||| (e ||| f))) - 5 *  ~~~(d |||  ~~~e) + 4 * (e &&& f) - 2 * (e ^^^ (d ||| f)) - 6 *  ~~~(d &&&  ~~~e) + 2 * (e ^^^ (d &&& (e ||| f))) - 1 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 13 *  ~~~(d ||| ( ~~~e ||| f)) - 4 *  ~~~( ~~~d ||| (e ||| f)) + 37 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 17 * ( ~~~d &&& ( ~~~e &&& f)) - 29 * ( ~~~d &&& (e &&& f)) + 4 * (d &&& ( ~~~e &&& f)) - 23 * (d &&& (e &&& f)) =  - 11 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f)))

theorem test2_proof : test2_before ⊑ test2_after

@[bv_multi_width_normalize] theorem one_eq_ofBool_true :
  1#1 = BitVec.ofBool true

theorem icmp_eq_or_z_or_pow2orz_fail_logic_or_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 == 0#8) = 1#1 → ofBool (x_1 == 0#8 - x &&& x) = ofBool (x_1 == x &&& 0#8 - x)

theorem substitute_constant_and_eq_eq_commute_proof : substitute_constant_and_eq_eq_commute_before ⊑ substitute_constant_and_eq_eq_commute_after

theorem bar_thm (e e_1 e_2 e_3 : IntW 32) :
  LLVM.or (LLVM.and e_3 (LLVM.xor (sext 32 (icmp IntPred.slt e_2 e_1)) (const? 32 (-1))))
      (LLVM.and e (sext 32 (icmp IntPred.slt e_2 e_1))) ⊑
    select (icmp IntPred.slt e_2 e_1) e e_3

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

theorem trunc_ashr_trunc_exact_proof : trunc_ashr_trunc_exact_before ⊑ trunc_ashr_trunc_exact_after

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

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

theorem mul_of_pow2_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ofBool (510#32 <ᵤ (x_1 &&& 2#32) * zeroExtend 32 x) = 0#1

theorem substitute_constant_or_ne_uge_commute_logical_proof : substitute_constant_or_ne_uge_commute_logical_before ⊑ substitute_constant_or_ne_uge_commute_logical_after

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

theorem shl_nsw_add_nuw_proof : shl_nsw_add_nuw_before ⊑ shl_nsw_add_nuw_after

theorem not_add_thm (e : IntW 32) :
  LLVM.xor (add e (const? 32 123)) (const? 32 (-1)) ⊑ sub (const? 32 (-124)) e

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

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

theorem add_assoc_1 (hq : q >= t) (hu : u >= t) :
  (bw t (addMax (bw u (addMax (bw p a) (bw r b))) (bw s c))) =
  (bw t (addMax (bw p a) (bw q (addMax (bw r b) (bw s c)))))

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

theorem lshrult_01_04_exact_proof : lshrult_01_04_exact_before ⊑ lshrult_01_04_exact_after

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

theorem mul_select_zext_proof : mul_select_zext_before ⊑ mul_select_zext_after

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

theorem 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 shift_no_xor_multiuse_cmp_thm.extracted_1._5 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ofBool (x_3 &&& 1#32 == 0#32) = 1#1 →
    True ∧ ((x_3 &&& 1#32) <<< 1#32).sshiftRight' 1#32 ≠ x_3 &&& 1#32 ∨
        True ∧ (x_3 &&& 1#32) <<< 1#32 >>> 1#32 ≠ x_3 &&& 1#32 ∨ 1#32 ≥ ↑32 →
      False

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 main12_logical_thm.extracted_1._4 : ∀ (x : BitVec 32),
  ¬ofBool (truncate 16 x <ₛ 0#16) = 1#1 →
    ¬ofBool (x &&& 32896#32 == 0#32) = 1#1 → ¬ofBool (truncate 8 x <ₛ 0#8) = 1#1 → 1#32 = 2#32

theorem e_1487 :
    11 * (z ^^^ t) + 3 *  ~~~(z ^^^ t) - 11 *  ~~~z - 1 * (z |||  ~~~t) + 3 *  ~~~(z &&&  ~~~t) + 3 * t - 1 *  ~~~(z &&& t) + 5 *  ~~~(z ||| t) - 5 *  ~~~(z |||  ~~~t) - 18 * (z &&&  ~~~t) - 15 * (z &&& t) =  - 7 * z - 2 *  ~~~t

theorem substitute_constant_or_ne_uge_commute_proof : substitute_constant_or_ne_uge_commute_before ⊑ substitute_constant_or_ne_uge_commute_after

theorem trunc_sel_larger_sext_proof : trunc_sel_larger_sext_before ⊑ trunc_sel_larger_sext_after

theorem or_xor_commute1_proof : or_xor_commute1_before ⊑ or_xor_commute1_after

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

theorem test1_proof : test1_before ⊑ test1_after

theorem sge_or_not_max_commute_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 != 127#8) = 1#1 → ofBool (x ≤ₛ x_1) = 1#1

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

theorem eq_smax2_proof : eq_smax2_before ⊑ eq_smax2_after

theorem udiv_i1_is_op0_proof : udiv_i1_is_op0_before ⊑ udiv_i1_is_op0_after

theorem test5_apint_proof : test5_apint_before ⊑ test5_apint_after

theorem scalar_i32_shl_and_negC_ne_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬x ≥ ↑32 → ofBool (x_1 <<< x &&& BitVec.ofInt 32 (-262144) != 0#32) = ofBool (262143#32 <ᵤ x_1 <<< x)

theorem n1_thm (e e_1 : IntW 8) :
  icmp IntPred.uge (LLVM.xor (shl (const? 8 (-1)) e_1) (const? 8 1)) e ⊑
    icmp IntPred.uge (LLVM.xor (shl (const? 8 (-1)) e_1 { «nsw» := true, «nuw» := false }) (const? 8 1)) e

theorem icmp_ne_sext_ne_otherwise_proof : icmp_ne_sext_ne_otherwise_before ⊑ icmp_ne_sext_ne_otherwise_after

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

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

theorem urem_constant_dividend_select_of_constants_divisor_thm (e : IntW 1) :
  urem (const? 32 42) (select e (const? 32 12) (const? 32 (-3))) ⊑ select e (const? 32 6) (const? 32 42)

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

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 sdiv_i1_is_op0_thm (e e_1 : IntW 1) : LLVM.sdiv e_1 e ⊑ e_1

theorem imp1 (w : Nat) (a b : BitVec w) : (a < b) → (a ≠ b)

theorem positive_biggerlshr_shlnuwnsw_lshrexact_proof : positive_biggerlshr_shlnuwnsw_lshrexact_before ⊑ positive_biggerlshr_shlnuwnsw_lshrexact_after

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

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

theorem t_2_4_proof : t_2_4_before ⊑ t_2_4_after

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

theorem test1_proof : test1_before ⊑ test1_after

theorem test28_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(BitVec.ofInt 32 (-2147483648) == 0 || 32 != 1 && x == intMin 32 && BitVec.ofInt 32 (-2147483648) == -1) = true →
    ofBool (x.srem (BitVec.ofInt 32 (-2147483648)) == 0#32) = ofBool (x &&& 2147483647#32 == 0#32)

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

theorem t1_lshr_thm (e : IntW 8) (e_1 : IntW 32) :
  lshr e_1 (sext 32 e) ⊑ lshr e_1 (zext 32 e { «nneg» := true })

theorem alive_AddSub_1176  (w : Nat)   : alive_AddSub_1176_src w  ⊑ alive_AddSub_1176_tgt w

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

theorem test39_thm (e : IntW 32) :
  LLVM.and (LLVM.or (zext 64 e) (const? 64 7)) (const? 64 240) ⊑
    zext 64 (LLVM.and e (const? 32 240)) { «nneg» := true }

theorem sdiv_eq_smin_proof : sdiv_eq_smin_before ⊑ sdiv_eq_smin_after

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

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

theorem lsb_mask_sign_zext_commuted_thm (e : IntW 32) :
  lshr (LLVM.and (LLVM.xor e (const? 32 (-1))) (add e (const? 32 (-1)))) (const? 32 31) ⊑
    zext 32 (icmp IntPred.eq e (const? 32 0))

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

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

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

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

theorem sub_ult_zext_thm (e : IntW 1) (e_1 e_2 : IntW 8) :
  icmp IntPred.ult (sub e_2 e_1) (zext 8 e) ⊑ LLVM.and (icmp IntPred.eq e_2 e_1) e

theorem scalar_i32_shl_and_signbit_slt_proof : scalar_i32_shl_and_signbit_slt_before ⊑ scalar_i32_shl_and_signbit_slt_after

theorem main13_thm.extracted_1._1 : ∀ (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 → 2#32 = 1#32

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 udiv1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ¬(True ∧ x_1.umod x ≠ 0 ∨ x = 0) → x_1 / x * x = x_1

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

theorem or_and_shifts1_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(3#32 ≥ ↑32 ∨ 5#32 ≥ ↑32) →
    ¬(3#32 ≥ ↑32 ∨ 5#32 ≥ ↑32 ∨ True ∧ (x <<< 3#32 &&& 8#32 &&& (x <<< 5#32 &&& 32#32) != 0) = true) →
      x <<< 3#32 &&& 15#32 ||

theorem e_413 :
    11 *  ~~~y - 2 * (x ||| y) + 1 * (x ^^^ y) - 7 * y - 18 *  ~~~(x ||| y) + 1 *  ~~~(x |||  ~~~y) - 10 * (x &&&  ~~~y) + 9 * (x &&& y) =  - 7 *  ~~~x

@[simp]
lemma CNFA.SignedCmp_states cmp : s ∈ (autSignedCmp cmp).m.states ↔  s < 5

theorem sge_swap_or_max_proof : sge_swap_or_max_before ⊑ sge_swap_or_max_after

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

theorem sdiv_ult_smin_proof : sdiv_ult_smin_before ⊑ sdiv_ult_smin_after

theorem test21_proof : test21_before ⊑ test21_after

theorem mkStateUniqueCircuitN_eq_false_iff {arity : Type _}
  [DecidableEq arity] [Fintype arity] [Hashable arity]
  (p : FSM arity) (n : Nat)
  {env : Vars p.α arity n → Bool} :
  ((mkStateUniqueCircuitN p n).eval env = false) ↔
  (∀ (i : Nat) (hi : i < n), ∃ (s : p.α), env (Vars.stateN s i) ≠ env (Vars.stateN s n))

theorem urem_common_divisor_defined_cond_proof : urem_common_divisor_defined_cond_before ⊑ urem_common_divisor_defined_cond_after

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

theorem sgt_and_min_commute_proof : sgt_and_min_commute_before ⊑ sgt_and_min_commute_after

theorem and_sequence_10_eq (w : Nat) :
    and_sequence_10_lhs w  ⊑ and_sequence_10_rhs w

theorem narrow_sext_xor_proof : narrow_sext_xor_before ⊑ narrow_sext_xor_after

theorem incr_congr (h : a ≈ʷ b) : a.incr ≈ʷ b.incr

theorem test15_proof : test15_before ⊑ test15_after

theorem zext_sext_add_icmp_slt_2_proof : zext_sext_add_icmp_slt_2_before ⊑ zext_sext_add_icmp_slt_2_after

theorem zext_add_scalar_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → zeroExtend 32 x + 42#32 = 43#32

theorem no_shift_no_xor_multiuse_or_proof : no_shift_no_xor_multiuse_or_before ⊑ no_shift_no_xor_multiuse_or_after

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

theorem xor_or_thm.extracted_1._7 : ∀ (x x_1 : BitVec 32) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → x_2 ^^^ 1#1 = 1#1 → ofBool (x_1 <ᵤ x) ^^^ 1#1 = ofBool (x ≤ᵤ x_1)

theorem shrink_or_proof : shrink_or_before ⊑ shrink_or_after

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

@[bv_multi_width_normalize]
theorem iff_iff_and_or_not_and_not {P Q : Prop} : (P ↔ Q) ↔ ((P ∧ Q) ∨  (¬ P ∧ ¬ Q))

theorem lshr_2_add_zext_basic_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  ¬1#2 ≥ ↑2 → (zeroExtend 2 x_1 + zeroExtend 2 x) >>> 1#2 = zeroExtend 2 (x_1 &&& x)

theorem ule_swap_or_not_min_commute_proof : ule_swap_or_not_min_commute_before ⊑ ule_swap_or_not_min_commute_after

theorem samesign_different_sign_bittest2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 &&& x <ₛ 0#32) ||

theorem lshrult_01_05_proof : lshrult_01_05_before ⊑ lshrult_01_05_after

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

theorem lshrugt_03_05_exact_proof : lshrugt_03_05_exact_before ⊑ lshrugt_03_05_exact_after

theorem eq_umin4_proof : eq_umin4_before ⊑ eq_umin4_after

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

theorem getElem?_eq_toList_getElem? {i : Nat} : Γ[i]? = Γ.toList[i]?

@[simp] theorem Com.rec'_var (e : Expr d Γ eff u) (body : Com d _ _ t) :
    (Com.var e body).rec' (motive:=motive) rets var
    = var e body (body.rec' (motive:=motive) rets var)

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 a_true_implies_b_false2_comm_thm.extracted_1._8 : ∀ (x x_1 : BitVec 1) (x_2 : BitVec 8),
  ¬ofBool (x_2 == 10#8) = 1#1 → ¬ofBool (20#8 <ᵤ x_2) = 1#1 → x &&& ofBool (20#8 <ᵤ x_2) = 0#1

theorem lt_signed_to_large_negative_thm (e : IntW 8) : icmp IntPred.slt (sext 32 e) (const? 32 (-1024)) ⊑ const? 1 0

theorem ashr_ashr_thm (e : IntW 32) : ashr (ashr e (const? 32 5)) (const? 32 7) ⊑ ashr e (const? 32 12)

theorem test_nuw_dropped_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 1073741823)) (const? 32 0)) (const? 32 0)
      (shl e (const? 32 2) { «nsw» := false, «nuw» := true }) ⊑
    shl e (const? 32 2)

theorem sgt_mulzero_proof : sgt_mulzero_before ⊑ sgt_mulzero_after

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

theorem src_srem_shl_demand_eliminate_signbit_proof : src_srem_shl_demand_eliminate_signbit_before ⊑ src_srem_shl_demand_eliminate_signbit_after

theorem test_zext4_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → x ^^^ 1#1 = 1#1 → 1#32 = zeroExtend 32 1#1

theorem Expr.denote_unfold (e : Expr d Γ eff ty) :
    e.denote = fun V => (· ++ V) <$> (e.denoteOp V)

theorem select_icmp_ne_pow2_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬ofBool (x &&& 4#8 != 0#8) = 1#1 → x = x &&& BitVec.ofInt 8 (-5)

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

theorem neg_not_signbit1_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬7#8 ≥ ↑8 → 1#32 - zeroExtend 32 (x >>> 7#8) = zeroExtend 32 (ofBool (-1#8 <ₛ x))

theorem ashrslt_01_15_proof : ashrslt_01_15_before ⊑ ashrslt_01_15_after

theorem positive_easyinvert_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 8),
  ofBool (x_1 <ₛ 0#8) ^^^ ofBool (x <ₛ 0#16) ^^^ 1#1 = ofBool (x_1 <ₛ 0#8) ^^^ ofBool (-1#16 <ₛ x)

theorem or_xor_commute4_thm (e e_1 : IntW 32) :
  LLVM.xor (LLVM.udiv (const? 32 42) e_1) (LLVM.or (LLVM.udiv (const? 32 42) e) (LLVM.udiv (const? 32 42) e_1)) ⊑
    LLVM.and (LLVM.udiv (const? 32 42) e) (LLVM.xor (LLVM.udiv (const? 32 42) e_1) (const? 32 (-1)))

theorem ashrsgt_01_00_proof : ashrsgt_01_00_before ⊑ ashrsgt_01_00_after

theorem lshr_shl_pow2_const_overflow_proof : lshr_shl_pow2_const_overflow_before ⊑ lshr_shl_pow2_const_overflow_after

theorem e_547 :
    2 *  ~~~(x &&&  ~~~y) - 7 * y - 6 *  ~~~x - 11 * (x ||| y) + 7 *  ~~~(x &&&  ~~~x) + 11 * x + 2 *  ~~~(x ||| y) + 15 *  ~~~(x |||  ~~~y) - 4 * (x &&& y) = 7 *  ~~~y - 2 *  ~~~(x ^^^ y)

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

theorem or_ranges_single_elem_left_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 4)) ⊑
    icmp IntPred.ult (add e (const? 8 (-4))) (const? 8 7)

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

theorem t0_proof : t0_before ⊑ t0_after

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

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

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

theorem zext_masked_bit_zero_to_larger_bitwidth_proof : zext_masked_bit_zero_to_larger_bitwidth_before ⊑ zext_masked_bit_zero_to_larger_bitwidth_after

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

theorem test12_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬zeroExtend 128 x &&& 31#128 ≥ ↑128 → True ∧ (x &&& 31#32).msb = true ∨ zeroExtend 64 (x &&& 31#32) ≥ ↑64 → False

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

theorem main11_thm (e : IntW 32) :
  select
      (LLVM.or (icmp IntPred.eq (LLVM.and e (const? 32 64)) (const? 32 0))
        (icmp IntPred.sge (trunc 8 e) (const? 8 0)))
      (const? 32 2) (const? 32 1) ⊑
    select (icmp IntPred.eq (LLVM.and e (const? 32 192)) (const? 32 192)) (const? 32 1) (const? 32 2)

theorem n3_constmask_samemask_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  (x_1 ||| BitVec.ofInt 32 (-65281)) &&& (x ||| BitVec.ofInt 32 (-65281)) = x_1 &&& x ||

theorem trunc_shl_15_i16_i64_thm.extracted_1._1 : ∀ (x : BitVec 64), ¬15#64 ≥ ↑64 → 15#16 ≥ ↑16 → False

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

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

theorem add_nsw_poison_constant_fold_thm (e : IntW 8) (e_1 : IntW 1) :
  add (select e_1 e (const? 8 65)) (const? 8 64) { «nsw» := true, «nuw» := false } ⊑
    select e_1 (add e (const? 8 64) { «nsw» := true, «nuw» := false }) (const? 8 (-127))

theorem Std.HashSet.toSet_toList[BEq α] [LawfulBEq α] [Hashable α] (m : HashSet α) : m.toSet = { x | x ∈ m.toList }

theorem test44_thm.extracted_1._1 : ∀ (x : BitVec 8), True ∧ (zeroExtend 16 x ||| 1234#16).msb = true → False

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_4_proof : masked_icmps_mask_notallzeros_bmask_mixed_swapped_4_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_swapped_4_after

theorem test13_proof : test13_before ⊑ test13_after

theorem test_mul__none_are_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq e (const? 32 805306368)) (const? 32 (-1342177280)) (mul e (const? 32 9)) ⊑
    mul e (const? 32 9)

theorem Int.natCast_pred_of_pos (x : Nat) (h : 0 < x) :
    (x : Int) - 1 = Nat.cast (x - 1)

theorem test_shr_and_1_ne_0_samesign_proof : test_shr_and_1_ne_0_samesign_before ⊑ test_shr_and_1_ne_0_samesign_after

theorem fold_select_trunc_nsw_true_thm.extracted_1._2 : ∀ (x x_1 : BitVec 128),
  ¬(True ∧ signExtend 128 (truncate 1 x_1) ≠ x_1) → truncate 1 x_1 = 1#1 → x_1 = -1#128

theorem negation_of_increment_via_or_disjoint_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ (x &&& 1#8 != 0) = true) → x_1 - (x ||| 1#8) = x_1 + (x ^^^ -1#8)

theorem slt_zero_eq_i1_fail_proof : slt_zero_eq_i1_fail_before ⊑ slt_zero_eq_i1_fail_after

theorem no_shift_xor_multiuse_cmp_or_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 shift_xor_multiuse_cmp_and_thm.extracted_1._3 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ofBool (0#32 != x_3 &&& 4096#32) = 1#1 →
    ofBool (x_3 &&& 4096#32 == 0#32) = 1#1 →
      x_2 * x_1 * (x_2 &&& 2048#32) = (x_2 &&& 2048#32) * x * (x_2 &&& 2048#32)

theorem test_shr_and_1_ne_0_proof : test_shr_and_1_ne_0_before ⊑ test_shr_and_1_ne_0_after

theorem t7_ugt_sgt_neg1_thm.extracted_1._9 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (65535#32 <ᵤ x_1) = 1#1 → ¬ofBool (65535#32 <ₛ x_1) = 1#1 → ofBool (x_1 <ₛ 0#32) = 1#1 → x_1 = x

theorem shl_add_and_fail_mismatch_shift_proof : shl_add_and_fail_mismatch_shift_before ⊑ shl_add_and_fail_mismatch_shift_after

theorem test7_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ (20000#32).ssubOverflow (x &&& 511#32) = true ∨
        True ∧ (20000#32).usubOverflow (x &&& 511#32) = true ∨ True ∧ (20000#32 - (x &&& 511#32)).msb = true) →
    signExtend 64 (20000#32 - (x &&& 511#32)) = zeroExtend 64 (20000#32 - (x &&& 511#32))

theorem ofBitVec_sub' {w : Nat} {i : Nat} {hi : i < w} (x y : BitVec w) :
    ofBitVecSext (x - y) i = ((ofBitVecSext x) - (ofBitVecSext y)) i

theorem shift_xor_multiuse_cmp_with_xor_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 t1_flags_nuw_second_thm (e e_1 e_2 : IntW 8) :
  sub (sub e_2 e_1) e { «nsw» := false, «nuw» := true } ⊑ sub e_2 (add e_1 e)

theorem zext_ult_zext_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 8),
  ofBool (zeroExtend 16 (x_1 * x_1) <ᵤ zeroExtend 16 x) = ofBool (x_1 * x_1 == 0#8) &&& x

theorem and_min_7_7_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬ofBool (x <ᵤ BitVec.ofInt 8 (-7)) = 1#1 → BitVec.ofInt 8 (-7) &&& BitVec.ofInt 8 (-8) = x &&& BitVec.ofInt 8 (-8)

lemma simul_equiv {m : CNFA n} {M : NFA' n} :
    m.Sim M → m.toNFA'.M.Bisim M.M

theorem main7a_logical_thm.extracted_1._1 : ∀ (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 → 0#32 = zeroExtend 32 1#1

theorem t0_proof : t0_before ⊑ t0_after

theorem or_test1_proof : or_test1_before ⊑ or_test1_after

theorem e_1942 :
     - 2 *  ~~~b + 2 *  ~~~(b ||| c) + 4 * (b ^^^ (a &&&  ~~~c)) + 3 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) - 1 * (b ^^^  ~~~(a ||| (b ^^^ c))) - 7 *  ~~~(a ^^^ ( ~~~b ||| c)) - 2 * (c &&&  ~~~(a &&& b)) - 3 * (a ||| ( ~~~b &&& c)) - 2 * (b ^^^ (a &&& c)) - 2 *  ~~~(b |||  ~~~c) + 1 *  ~~~(a ^^^ (b ^^^ c)) + 4 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) - 11 * (c ^^^ ( ~~~a &&& (b ||| c))) - 11 * (b ^^^  ~~~(a &&&  ~~~c)) + 2 *  ~~~( ~~~a &&& ( ~~~b ||| c)) + 3 * (a &&& ( ~~~b ||| c)) - 1 *  ~~~(a |||  ~~~b) - 3 * ( ~~~b |||  ~~~(a ^^^ c)) + 1 * (c ||| (a &&&  ~~~b)) - 3 *  ~~~(a &&& (b &&& c)) - 1 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 4 * (c ^^^  ~~~(a &&&  ~~~b)) - 1 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 5 * a - 6 * (b ^^^  ~~~(a ||| c)) - 1 * (a ||| ( ~~~b ||| c)) + 2 * (c ^^^ (a &&& (b ||| c))) + 2 * ( ~~~b &&& (a ^^^ c)) + 1 * (b ||| (a &&& c)) + 2 * (c ^^^  ~~~(a &&& (b &&& c))) + 5 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) + 5 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) + 2 * (c ^^^ (a ||| ( ~~~b &&& c))) + 1 * (a &&& (b ^^^ c)) + 1 * (a ^^^ ( ~~~b ||| c)) - 1 * (c ^^^ (a ||| b)) - 3 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) + 1 *  ~~~(a ||| (b &&& c)) + 2 *  ~~~( ~~~a &&& (b ||| c)) + 1 *  ~~~(a ||| ( ~~~b &&& c)) - 7 * b + 11 * (b &&& (a ^^^ c)) - 2 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) + 1 * (a ||| (b ^^^ c)) - 3 *  ~~~(a &&& (b ^^^ c)) + 14 *  ~~~(a ||| (b ||| c)) + 26 *  ~~~(a ||| ( ~~~b ||| c)) + 7 *  ~~~( ~~~a ||| (b ||| c)) + 8 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 18 * ( ~~~a &&& ( ~~~b &&& c)) - 2 * ( ~~~a &&& (b &&& c)) + 37 * (a &&& ( ~~~b &&& c)) + 22 * (a &&& (b &&& c)) = 5 * (c ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 1 * (b ^^^ c)

theorem fold_add_udiv_urem_without_noundef_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(10#32 = 0 ∨ 4#32 ≥ ↑32 ∨ 10#32 = 0) →
    ¬(10#32 = 0 ∨ 4#32 ≥ ↑32 ∨ 10#32 = 0 ∨ True ∧ ((x / 10#32) <<< 4#32 &&& x % 10#32 != 0) = true) →
      (x / 10#32) <<< 4#32 + x % 10#32 = (x / 10#32) <<< 4#32 ||

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

theorem ashr_ult_8_proof : ashr_ult_8_before ⊑ ashr_ult_8_after

theorem xor_ashr_not_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 8),
  ¬(x_1 ≥ ↑8 ∨ x_1 ≥ ↑8) →
    ¬x_1 ≥ ↑8 → x_2.sshiftRight' x_1 ^^^ (x.sshiftRight' x_1 ^^^ -1#8) = (x ^^^ x_2).sshiftRight' x_1 ^^^ -1#8

theorem eq_smax2_thm (e e_1 : IntW 32) :
  icmp IntPred.eq (select (icmp IntPred.sgt e_1 e) e_1 e) e ⊑ icmp IntPred.sge e e_1

theorem shl_add_and_fail_mismatch_shift_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(1#8 ≥ ↑8 ∨ 1#8 ≥ ↑8) → 1#8 ≥ ↑8 ∨ 1#8 ≥ ↑8 ∨ True ∧ (x >>> 1#8).uaddOverflow 123#8 = true → False

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

theorem slt_swap_or_not_max_commute_proof : slt_swap_or_not_max_commute_before ⊑ slt_swap_or_not_max_commute_after

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

theorem test_logical_proof : test_logical_before ⊑ test_logical_after

theorem test1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 33),
  ofBool (x_1 &&& 65280#33 != x &&& 65280#33) = ofBool ((x_1 ^^^ x) &&& 65280#33 != 0#33)

theorem sle_swap_or_min_commute_proof : sle_swap_or_min_commute_before ⊑ sle_swap_or_min_commute_after

theorem test44_proof : test44_before ⊑ test44_after

theorem sub_ashr_and_i64_thm (e e_1 : IntW 64) :
  LLVM.and (ashr (sub e_1 e { «nsw» := true, «nuw» := false }) (const? 64 63)) e ⊑
    select (icmp IntPred.slt e_1 e) e (const? 64 0)

theorem test5_proof : test5_before ⊑ test5_after

theorem test14_proof : test14_before ⊑ test14_after

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

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

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 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 land_lor_right1_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1), x_1 = 1#1 → 1#1 = x_1

theorem scalar_i8_lshr_and_signbit_eq_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬x ≥ ↑8 → ofBool (x_1 >>> x &&& BitVec.ofInt 8 (-128) == 0#8) = ofBool (-1#8 <ₛ x_1 >>> x)

theorem reused_mul_nuw_xy_z_selectnonzero_ugt_proof : reused_mul_nuw_xy_z_selectnonzero_ugt_before ⊑ reused_mul_nuw_xy_z_selectnonzero_ugt_after

theorem icmp_eq_x_invertable_y_todo_proof : icmp_eq_x_invertable_y_todo_before ⊑ icmp_eq_x_invertable_y_todo_after

theorem andn_or_cmp_4_logical_thm.extracted_1._11 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 == x_1) = 1#1 → ¬ofBool (x_2 != x_1) = 1#1 → ofBool (42#32 <ᵤ x) = 1#1 → ofBool (x_2 != x_1) = 0#1

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

theorem udiv_exact_eq_1_proof : udiv_exact_eq_1_before ⊑ udiv_exact_eq_1_after

theorem bar_proof : bar_before ⊑ bar_after

theorem masked_and_notA_proof : masked_and_notA_before ⊑ masked_and_notA_after

theorem hoist_ashr_ahead_of_sext_1_proof : hoist_ashr_ahead_of_sext_1_before ⊑ hoist_ashr_ahead_of_sext_1_after

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

theorem e_956 :
    7 *  ~~~(z &&&  ~~~z) + 2 * t - 7 *  ~~~t - 11 *  ~~~(z |||  ~~~t) + 3 * (z &&&  ~~~t) - 4 * (z &&& t) = 5 * z - 2 * (z ^^^ t)

theorem e_2240 :
     - 1 * (e &&& f) - 7 * (d |||  ~~~e) - 3 * (e |||  ~~~(d ^^^ f)) + 4 * (f ^^^  ~~~(d &&&  ~~~e)) + 1 * (d &&& (e ||| f)) + 2 * (e ||| (d &&& f)) + 4 * (d &&&  ~~~e) + 2 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 11 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 3 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 1 * ( ~~~d &&& (e ||| f)) - 5 * (e &&&  ~~~(d &&& f)) + 2 * (d ^^^ (e ||| f)) + 3 * (e ^^^  ~~~(d &&&  ~~~f)) - 2 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 3 *  ~~~(d ^^^ e) + 7 * (f ^^^ ( ~~~d ||| (e &&& f))) - 2 * ( ~~~e &&& (d ^^^ f)) + 3 * ( ~~~f |||  ~~~(d ^^^ e)) - 6 *  ~~~(d ||| f) - 2 * (f ^^^ (d &&& e)) + 11 * (d ^^^ e) + 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 2 * (e &&&  ~~~f) + 2 * ( ~~~f ||| (d ^^^ e)) - 1 * (f ^^^  ~~~(d &&& (e ||| f))) - 6 * (f ||| (d ^^^ e)) + 1 * ((d ^^^ e) &&& (d ^^^ f)) - 11 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 5 * (d &&& e) + 1 *  ~~~(d &&& e) - 2 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 5 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 11 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 5 * (d ^^^ f) + 1 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 11 * f + 1 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 11 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 7 *  ~~~(e |||  ~~~f) + 5 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 5 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 4 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 7 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * ((d &&& e) ^^^ (e ||| f)) - 1 * ( ~~~d ||| (e ||| f)) - 12 *  ~~~(d ||| (e ||| f)) - 16 *  ~~~(d ||| ( ~~~e ||| f)) - 9 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 37 * ( ~~~d &&& ( ~~~e &&& f)) - 20 * ( ~~~d &&& (e &&& f)) - 6 * (d &&& ( ~~~e &&& f)) + 26 * (d &&& (e &&& f)) = 20 *  ~~~( ~~~d ||| (e ||| f))

theorem sub_shl_same_amount_partial_nsw1_proof : sub_shl_same_amount_partial_nsw1_before ⊑ sub_shl_same_amount_partial_nsw1_after

theorem and_or_not_not_commute1_proof : and_or_not_not_commute1_before ⊑ and_or_not_not_commute1_after

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

theorem ashrsgt_01_00_exact_proof : ashrsgt_01_00_exact_before ⊑ ashrsgt_01_00_exact_after

private theorem sge_eq_sle (A B : BitVec w) : (A ≥ₛ B) = (B ≤ₛ A)

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

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

theorem e_1529 :
    3 * (b |||  ~~~(a |||  ~~~c)) - 2 * ((a &&& b) ^^^ (b |||  ~~~c)) + 1 * (b ^^^ (a &&& ( ~~~b ||| c))) + 7 * (b &&& c) + 2 *  ~~~(a ||| (b ||| c)) - 2 *  ~~~(a ||| ( ~~~b ||| c)) + 4 *  ~~~( ~~~a ||| (b ||| c)) - 4 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 6 * ( ~~~a &&& (b &&& c)) + 2 * (a &&& ( ~~~b &&& c)) - 10 * (a &&& (b &&& c)) = 3 * (b ^^^ (a ||| (b ^^^ c)))

theorem test_eq_0_and_15_add_1_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x + 1#8 &&& 15#8 == 0#8) = ofBool (x &&& 15#8 == 15#8)

theorem or_not_xor_common_op_commute2_thm (e e_1 e_2 : IntW 8) :
  LLVM.or (LLVM.xor e_2 e_1) (LLVM.or (sub (const? 8 0) e) (LLVM.xor e_2 (const? 8 (-1)))) ⊑
    LLVM.or (LLVM.xor (LLVM.and e_2 e_1) (const? 8 (-1))) (sub (const? 8 0) e)

theorem 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 ashr_ult_12_proof : ashr_ult_12_before ⊑ ashr_ult_12_after

theorem main_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(6#8 ≥ ↑8 ∨ 7#8 ≥ ↑8) → 5#8 ≥ ↑8 ∨ True ∧ ((truncate 8 x ^^^ -1#8) <<< 5#8 &&& 64#8).msb = true → False

@[simp] theorem impure_inf_impure_eq : min impure impure = impure

theorem test4_proof : test4_before ⊑ test4_after

theorem sub_mask1_trunc_lshr_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬15#64 ≥ ↑64 →
    ¬(48#64 ≥ ↑64 ∨
          63#64 ≥ ↑64 ∨
            True ∧ signExtend 64 (truncate 8 ((x <<< 48#64).sshiftRight' 63#64)) ≠ (x <<< 48#64).sshiftRight' 63#64 ∨
              True ∧ (truncate 8 ((x <<< 48#64).sshiftRight' 63#64)).saddOverflow 10#8 = true) →
      10#8 - (truncate 8 (x >>> 15#64) &&& 1#8) = truncate 8 ((x <<< 48#64).sshiftRight' 63#64) + 10#8

theorem ule_swap_or_not_min_logical_proof : ule_swap_or_not_min_logical_before ⊑ ule_swap_or_not_min_logical_after

theorem lshrult_01_15_exact_proof : lshrult_01_15_exact_before ⊑ lshrult_01_15_exact_after

theorem select_icmp_eq_and_32_0_xor_8_proof : select_icmp_eq_and_32_0_xor_8_before ⊑ select_icmp_eq_and_32_0_xor_8_after

theorem test2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1), x_1 &&& x &&& x_1 = x_1 &&& x

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

theorem or_to_nxor1_proof : or_to_nxor1_before ⊑ or_to_nxor1_after

theorem lshr_eq_msb_low_last_zero_proof : lshr_eq_msb_low_last_zero_before ⊑ lshr_eq_msb_low_last_zero_after

@[simp] lemma eval_xor : ∀ (c₁ c₂ : Circuit α) (f : α → Bool),
    eval (c₁ ^^^ c₂) f = Bool.xor (eval c₁ f) (eval c₂ f)

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

theorem exact_ashr_eq_both_equal_proof : exact_ashr_eq_both_equal_before ⊑ exact_ashr_eq_both_equal_after

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

theorem ashrslt_03_06_exact_proof : ashrslt_03_06_exact_before ⊑ ashrslt_03_06_exact_after

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 scalar_i8_lshr_and_signbit_eq_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (LLVM.and (lshr e_1 e) (const? 8 (-128))) (const? 8 0) ⊑
    icmp IntPred.sgt (lshr e_1 e) (const? 8 (-1))

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

theorem t5_thm (e : IntW 8) :
  icmp IntPred.uge (sub (const? 8 0) e { «nsw» := true, «nuw» := false }) e ⊑
    icmp IntPred.sgt e (const? 8 (-1))

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

theorem select_icmp_ne_0_and_8_or_1073741824_thm.extracted_1._2 : ∀ (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 ||

theorem lt_unsigned_to_small_unsigned_thm (e : IntW 8) :
  icmp IntPred.ult (zext 32 e) (const? 32 17) ⊑ icmp IntPred.ult e (const? 8 17)

theorem positive_samevar_proof : positive_samevar_before ⊑ positive_samevar_after

theorem not_and_and_or_not_or_or_commute4_proof : not_and_and_or_not_or_or_commute4_before ⊑ not_and_and_or_not_or_or_commute4_after

theorem lshrugt_01_01_proof : lshrugt_01_01_before ⊑ lshrugt_01_01_after

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

@[simp]
theorem instantiate_mvar_zero' :
    (mvar (φ := 1) ⟨0, by simp⟩).instantiate (Subtype.mk [w] (by simp)) = w

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

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

theorem sdiv2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.smod 8#32 ≠ 0 ∨ (8#32 == 0 || 32 != 1 && x == intMin 32 && 8#32 == -1) = true) →
    True ∧ x >>> 3#32 <<< 3#32 ≠ x ∨ 3#32 ≥ ↑32 → False

theorem e_1474 :
     - 11 *  ~~~(z &&&  ~~~t) + 4 *  ~~~z + 11 * (z ^^^ t) + 5 *  ~~~t + 4 * t + 7 * z + 2 *  ~~~(z &&& t) - 1 *  ~~~(z ^^^ t) + 1 *  ~~~(z ||| t) - 9 *  ~~~(z |||  ~~~t) - 24 * (z &&&  ~~~t) = 1 * (z ||| t) - 2 * (z &&& t)

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

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

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

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

theorem or_ashr_not_proof : or_ashr_not_before ⊑ or_ashr_not_after

theorem ashr_pow2_ugt_proof : ashr_pow2_ugt_before ⊑ ashr_pow2_ugt_after

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

theorem test_shift_nonnegative_proof : test_shift_nonnegative_before ⊑ test_shift_nonnegative_after

theorem main4d_logical_thm (e : IntW 32) :
  select
      (select (icmp IntPred.ne (LLVM.and e (const? 32 7)) (const? 32 7)) (const? 1 1)
        (icmp IntPred.eq (LLVM.and e (const? 32 16)) (const? 32 0)))
      (const? 32 0) (const? 32 1) ⊑
    zext 32 (icmp IntPred.eq (LLVM.and e (const? 32 23)) (const? 32 23))

theorem test67_proof : test67_before ⊑ test67_after

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

theorem c_1_1_0_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 or_xor_not_proof : or_xor_not_before ⊑ or_xor_not_after

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

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 ashr_ugt_6_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬1#4 ≥ ↑4 → ofBool (6#4 <ᵤ x.sshiftRight' 1#4) = ofBool (x <ₛ 0#4)

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

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

theorem test_proof : test_before ⊑ test_after

theorem icmp_slt_0_xor_icmp_sgt_neg2_i32_proof : icmp_slt_0_xor_icmp_sgt_neg2_i32_before ⊑ icmp_slt_0_xor_icmp_sgt_neg2_i32_after

theorem unsigned_sign_bit_extract_with_trunc_thm (e : IntW 64) :
  icmp IntPred.ne (trunc 32 (lshr e (const? 64 63))) (const? 32 0) ⊑ icmp IntPred.slt e (const? 64 0)

theorem expand_proof : expand_before ⊑ expand_after

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

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

theorem dec_commute_mask_neg_i32_proof : dec_commute_mask_neg_i32_before ⊑ dec_commute_mask_neg_i32_after

theorem icmp_ne_zext_eq_non_boolean_proof : icmp_ne_zext_eq_non_boolean_before ⊑ icmp_ne_zext_eq_non_boolean_after

theorem mul_constant_eq_proof : mul_constant_eq_before ⊑ mul_constant_eq_after

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

theorem test14_thm (e : IntW 32) (e_1 : IntW 64) :
  urem e_1 (zext 64 (shl (const? 32 1) e)) ⊑
    LLVM.and e_1
      (add (zext 64 (shl (const? 32 1) e { «nsw» := false, «nuw» := true })) (const? 64 (-1))
        { «nsw» := true, «nuw» := false })

theorem t0_exact_proof : t0_exact_before ⊑ t0_exact_after

@[simp] lemma and_tru (c : Circuit α) :
  c &&& Circuit.tru = c

theorem eq_smax1_proof : eq_smax1_before ⊑ eq_smax1_after

theorem icmp_eq_and_pow2_shl_pow2_negative3_thm (e : IntW 32) :
  zext 32 (icmp IntPred.eq (LLVM.and (shl (const? 32 32) e) (const? 32 16)) (const? 32 0)) ⊑ const? 32 1

theorem select_icmp_ne_0_and_32_and_not_4096_proof : select_icmp_ne_0_and_32_and_not_4096_before ⊑ select_icmp_ne_0_and_32_and_not_4096_after

theorem positive_with_signbit_logical_proof : positive_with_signbit_logical_before ⊑ positive_with_signbit_logical_after

theorem test5_proof : test5_before ⊑ test5_after

theorem select_sub_icmp_bad_proof : select_sub_icmp_bad_before ⊑ select_sub_icmp_bad_after

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

theorem ashr_ne_both_equal_thm (e : IntW 8) :
  icmp IntPred.ne (ashr (const? 8 (-128)) e) (const? 8 (-128)) ⊑ icmp IntPred.ne e (const? 8 0)

theorem AvoidCollision_toInt_signExtend_eq_toNat_bmod (x : BitVec w) :
    (x.signExtend v).toInt = Int.bmod x.toNat (2 ^ min v w)

theorem select_constants_and_icmp_ne0_zero_tval_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1),
  ¬x_1 = 1#1 → x = 1#1 → ofBool (12#8 &&& 0#8 != 0#8) = x ^^^ 1#1

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

theorem annihilate_xor_common_op_commute2_thm.extracted_1._1 : ∀ (x x_1 x_2 x_3 : BitVec 4),
  x_3 * x_3 ^^^ (x_2 ^^^ x_1) ^^^ x ^^^ x_2 = x_1 ^^^ x_3 * x_3 ^^^ x

theorem Expr.eff_le {Γ : Ctxt d.Ty} {ty} (e : Expr d Γ eff ty) :
  DialectSignature.effectKind e.op ≤ eff

theorem test4_proof : test4_before ⊑ test4_after

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

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

theorem uge_swap_or_not_max_proof : uge_swap_or_not_max_before ⊑ uge_swap_or_not_max_after

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

theorem select_sub_icmp_bad_2_proof : select_sub_icmp_bad_2_before ⊑ select_sub_icmp_bad_2_after

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_sgt_overflow_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬1#8 ≥ ↑8 → ofBool (63#8 <ₛ x.sshiftRight' 1#8) = 0#1

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_7b_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_swapped_7b_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_swapped_7b_logical_after

theorem t0_basic_proof : t0_basic_before ⊑ t0_basic_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 lt_unsigned_to_small_negative_thm (e : IntW 8) : icmp IntPred.slt (zext 32 e) (const? 32 (-17)) ⊑ const? 1 0

theorem test_simplify_decrement_invalid_ne_thm (e : IntW 8) :
  select (icmp IntPred.ne e (const? 8 0)) (const? 8 0) (sub e (const? 8 1)) ⊑
    sext 8 (icmp IntPred.eq e (const? 8 0))

theorem test24_proof : test24_before ⊑ test24_after

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

theorem test_or_eq_a_b_commuted_proof : test_or_eq_a_b_commuted_before ⊑ test_or_eq_a_b_commuted_after

theorem a_or_b_const2_thm.extracted_1._1 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ofBool (x_3 == x_2) &&& ofBool (x_1 != x) ||

theorem invert_both_cmp_operands_add_thm (e e_1 : IntW 32) :
  icmp IntPred.sgt (add e_1 (LLVM.xor e (const? 32 (-1)))) (const? 32 0) ⊑
    icmp IntPred.slt (sub e e_1) (const? 32 (-1))

theorem c0_proof : c0_before ⊑ c0_after

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

theorem t3_proof : t3_before ⊑ t3_after

@[bv_multi_width_normalize] theorem BitVec.mul_ofNat_eq_ofNat_mul (x : BitVec w) (n : Nat) :
  x * (BitVec.ofNat w n) = BitVec.ofNat w n * x

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

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

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

theorem add_nsw_or_and_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (x_1 ||| x).saddOverflow (x_1 &&& x) = true) →
    ¬(True ∧ x_1.saddOverflow x = true) → (x_1 ||| x) + (x_1 &&& x) = x_1 + x

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 andn_or_cmp_2_logical_proof : andn_or_cmp_2_logical_before ⊑ andn_or_cmp_2_logical_after

theorem test_ne_0_and_15_add_1_proof : test_ne_0_and_15_add_1_before ⊑ test_ne_0_and_15_add_1_after

theorem sge_or_not_max_logical_proof : sge_or_not_max_logical_before ⊑ sge_or_not_max_logical_after

theorem icmp_eq_zext_eq_one_proof : icmp_eq_zext_eq_one_before ⊑ icmp_eq_zext_eq_one_after

theorem basic_com_add_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), x_1 + (x ^^^ -1#8) ^^^ -1#8 = x - x_1

theorem e_1228 :
    1 *  ~~~(z &&&  ~~~t) - 2 *  ~~~z - 3 * (z ||| t) - 5 * (z |||  ~~~t) + 7 *  ~~~(z ^^^ t) - 7 *  ~~~t - 1 *  ~~~(z &&& t) + 7 *  ~~~(z ||| t) + 5 *  ~~~(z |||  ~~~t) =  - 16 * (z &&&  ~~~t)

theorem t0_proof : t0_before ⊑ t0_after

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

theorem exact_lshr_eq_opposite_msb_proof : exact_lshr_eq_opposite_msb_before ⊑ exact_lshr_eq_opposite_msb_after

theorem alive_229 : alive_229_src ⊑ alive_229_tgt

theorem trunc_proof : trunc_before ⊑ trunc_after

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

theorem head_dropLeadingNones_eq_of_bisim {x y} (h : x ~ y) (x_neq_stuck : x ≠ stuck α)
    (y_neq_stuck : y ≠ stuck α := fun h' => x_neq_stuck (eq_stuck_iff_equiv.mp (h' ▸ h))) :
    head (x.dropLeadingNones x_neq_stuck) = head (y.dropLeadingNones y_neq_stuck)

theorem select_icmp_and_8_ne_0_xor_8_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 8)) (const? 32 0)) e (LLVM.xor e (const? 32 8)) ⊑
    LLVM.and e (const? 32 (-9))

theorem toBitVec_eq_toBitVec_iff_EqualUpTo {w : Nat} {x y : BitStream} :
  (EqualUpTo w x y) ↔ x.toBitVec w = y.toBitVec w

theorem matchVar_nil {lets : Lets d Γ_in eff Γ_out} :
    matchVar lets v (.nil : Lets d Δ .pure Δ) w ma = some ((), ma') →
    ma'.lookup ⟨_, w⟩ = some v

theorem lt_unsigned_to_small_negative_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (zeroExtend 32 x <ₛ BitVec.ofInt 32 (-17)) = 0#1

theorem PR42691_3_proof : PR42691_3_before ⊑ PR42691_3_after

theorem lshr_add_xor_fail_proof : lshr_add_xor_fail_before ⊑ lshr_add_xor_fail_after

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

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

theorem positive_biggershl_shlnsw_proof : positive_biggershl_shlnsw_before ⊑ positive_biggershl_shlnsw_after

theorem scalar_i32_shl_and_signbit_ne_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (LLVM.and (shl e_1 e) (const? 32 (-2147483648))) (const? 32 0) ⊑
    icmp IntPred.slt (shl e_1 e) (const? 32 0)

@[simp]
lemma var_map (f : α → β) (b : Bool) (x : α) :
  (Circuit.var b x).map f = Circuit.var b (f x)

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

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

theorem bools2_logical_commute1_thm.extracted_1._9 : ∀ (x x_1 : BitVec 1),
  ¬x_1 = 1#1 → ¬x ^^^ 1#1 = 1#1 → ¬x = 1#1 → 0#1 = 1#1 → False

theorem shl_shl_thm (e : IntW 32) : shl (shl e (const? 32 6)) (const? 32 28) ⊑ const? 32 0

theorem test24_proof : test24_before ⊑ test24_after

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

theorem sel_false_val_is_a_masked_ashr_of_true_val2_thm.extracted_1._4 : ∀ (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) →
          x.sshiftRight' (zeroExtend 64 ((x_1 &&& BitVec.ofInt 32 (-2147483588)).sshiftRight' 2#32)) =
            x.sshiftRight' (zeroExtend 64 (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)))

theorem and_ne_with_one_bit_diff_constants1_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x != 51#32) = 1#1 → 0#1 = ofBool (x + BitVec.ofInt 32 (-52) <ᵤ BitVec.ofInt 32 (-2))

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

@[simp] lemma eval_xor (x : Bool → BitStream) : xor.eval x = (x true) ^^^ (x false)

theorem ashr_ult_6_thm (e : IntW 4) :
  icmp IntPred.ult (ashr e (const? 4 1)) (const? 4 6) ⊑ icmp IntPred.sgt e (const? 4 (-1))

theorem test69_xor_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 &&& 128#32 != 0#32) = 1#1 → 6#32 ≥ ↑32 → False

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

theorem t0_basic_proof : t0_basic_before ⊑ t0_basic_after

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

theorem slt_or_not_max_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 <ₛ x) = 1#1 → 1#1 = ofBool (x_1 != 127#8)

theorem ashrslt_03_01_exact_proof : ashrslt_03_01_exact_before ⊑ ashrslt_03_01_exact_after

theorem not_neg_eq_sub_one :
    ~~~ (-x) = x - 1

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

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

theorem mul_constant_nuw_eq_thm (e e_1 : IntW 32) :
  icmp IntPred.eq (mul e_1 (const? 32 22) { «nsw» := false, «nuw» := true })
      (mul e (const? 32 22) { «nsw» := false, «nuw» := true }) ⊑
    icmp IntPred.eq e_1 e

theorem sle_and_min_proof : sle_and_min_before ⊑ sle_and_min_after

theorem e_325 :
     - 1 *  ~~~(x &&&  ~~~y) - 2 *  ~~~(x &&& y) + 11 * (x ||| y) + 3 *  ~~~(x ||| y) - 8 *  ~~~(x |||  ~~~y) - 16 * (x &&&  ~~~y) - 17 * (x &&& y) =  - 7 * x

theorem n12_thm (e : IntW 8) :
  ashr (shl e (const? 8 6)) (const? 8 6) ⊑ ashr (shl e (const? 8 6)) (const? 8 6) { «exact» := true }

theorem bools_logical_commute0_and2_thm.extracted_1._12 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 ^^^ 1#1 = 1#1 → x_2 = 1#1 → ¬x_1 = 1#1 → x_2 &&& x = x

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

theorem sub_ult_zext_proof : sub_ult_zext_before ⊑ sub_ult_zext_after

theorem test_sub_nuw_nsw__none_are_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x == 1#32) = 1#1 → 2147483647#32 = BitVec.ofInt 32 (-2147483648) - x

theorem zext_sext_add_icmp_ult_minus1_proof : zext_sext_add_icmp_ult_minus1_before ⊑ zext_sext_add_icmp_ult_minus1_after

theorem main6c_proof : main6c_before ⊑ main6c_after

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

theorem main4f_like_logical_proof : main4f_like_logical_before ⊑ main4f_like_logical_after

theorem test31 (w : Nat) (x : BitVec w) : x &&& x = x

theorem xor_of_icmps_proof : xor_of_icmps_before ⊑ xor_of_icmps_after

theorem e_557 :
    2 *  ~~~(x &&&  ~~~y) - 11 * x + 3 * y - 1 *  ~~~(x &&& y) + 2 * (x |||  ~~~y) - 7 *  ~~~(x ||| y) - 8 *  ~~~(x |||  ~~~y) + 10 * (x &&&  ~~~y) + 4 * (x &&& y) =  - 4 *  ~~~x

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

theorem xor_signbit_select_shl_proof : xor_signbit_select_shl_before ⊑ xor_signbit_select_shl_after

theorem basic_proof : basic_before ⊑ basic_after

theorem lowmask_add_zext_commute_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 32),
  x_1 * x_1 + zeroExtend 32 x &&& 65535#32 = zeroExtend 32 (x + truncate 16 (x_1 * x_1))

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

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

lemma reduce_stepSet {M : NFA α σ} {q : σ} (S1 : Set M.Reachable) (S2 : Set σ) :
    (∀ q, (∃ hq, S1 ⟨q, hq⟩) ↔ S2 q) →
    ((∃ hq,  ⟨q, hq⟩ ∈ M.reduce.stepSet S1 a) ↔ q ∈ M.stepSet S2 a)

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

@[simp] theorem bvars_rets  : (rets v : Com d Γ eff t).bvars = 0

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

@[grind ., simp, aesop 50% unsafe]
lemma wf_addInitial (m : RawCNFA A) (hwf : m.WF) (hin : s ∈ m.states) :
    (m.addInitial s).WF

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

theorem ashr_ugt_0_thm (e : IntW 4) :
  icmp IntPred.ugt (ashr e (const? 4 1)) (const? 4 0) ⊑ icmp IntPred.ugt e (const? 4 1)

theorem test_shl_nsw__all_are_safe_proof : test_shl_nsw__all_are_safe_before ⊑ test_shl_nsw__all_are_safe_after

theorem ashr_ugt_2_proof : ashr_ugt_2_before ⊑ ashr_ugt_2_after

theorem test9_proof : test9_before ⊑ test9_after

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

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

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

theorem shl_nsw_nuw_ult_Csle0_proof : shl_nsw_nuw_ult_Csle0_before ⊑ shl_nsw_nuw_ult_Csle0_after

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

theorem PR39793_bswap_u64_as_u16_trunc_proof : PR39793_bswap_u64_as_u16_trunc_before ⊑ PR39793_bswap_u64_as_u16_trunc_after

theorem ashr_16_to_64_add_zext_basic_proof : ashr_16_to_64_add_zext_basic_before ⊑ ashr_16_to_64_add_zext_basic_after

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

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

theorem and_not_or_or_not_or_xor_proof : and_not_or_or_not_or_xor_before ⊑ and_not_or_or_not_or_xor_after

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

theorem icmp_select_var_select_thm.extracted_1._12 : ∀ (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#1

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

theorem xor_of_icmps_to_ne_proof : xor_of_icmps_to_ne_before ⊑ xor_of_icmps_to_ne_after

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

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

theorem ashr_lshr_cst_proof : ashr_lshr_cst_before ⊑ ashr_lshr_cst_after

theorem shl_add_add_no_const_proof : shl_add_add_no_const_before ⊑ shl_add_add_no_const_after

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

theorem bad_add1_thm (e : IntW 32) :
  add (shl (const? 32 1) e) (const? 32 1) ⊑
    add (shl (const? 32 1) e { «nsw» := false, «nuw» := true }) (const? 32 1) { «nsw» := false, «nuw» := true }

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

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 or_and_not_not_wrong_b_thm.extracted_1._1 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ((x_3 ||| x_2) ^^^ -1#32) &&& x_1 ||

theorem p0_proof : p0_before ⊑ p0_after

theorem exact_lshr_eq_opposite_msb_thm (e : IntW 8) :
  icmp IntPred.eq (lshr (const? 8 (-128)) e { «exact» := true }) (const? 8 1) ⊑
    icmp IntPred.eq e (const? 8 7)

theorem test6_proof : test6_before ⊑ test6_after

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 narrow_source_matching_signbits_thm (e : IntW 32) :
  sext 64 (trunc 8 (shl (const? 32 (-1)) (LLVM.and e (const? 32 7)) { «nsw» := true, «nuw» := false })) ⊑
    sext 64 (shl (const? 32 (-1)) (LLVM.and e (const? 32 7)) { «nsw» := true, «nuw» := false })

theorem t22_sign_check2_proof : t22_sign_check2_before ⊑ t22_sign_check2_after

theorem zext_sext_add_icmp_eq_1_proof : zext_sext_add_icmp_eq_1_before ⊑ zext_sext_add_icmp_eq_1_after

theorem positive_with_icmp_proof : positive_with_icmp_before ⊑ positive_with_icmp_after

theorem ult_and_max_proof : ult_and_max_before ⊑ ult_and_max_after

theorem Holor.reindex_functorial
  (ix : HolorIndex ds₂ → HolorIndex ds₁) (iy : HolorIndex ds₃ → HolorIndex ds₂)
  (h : Holor α ds₁) : Holor.reindex iy (Holor.reindex ix h) = Holor.reindex (ix ∘ iy) h

theorem main4_logical_proof : main4_logical_before ⊑ main4_logical_after

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

theorem e_2068 :
    11 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 1 *  ~~~(e ||| f) + 7 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 1 * ((d &&& f) |||  ~~~(e ||| f)) + 2 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 1 * (f ||| (d &&& e)) - 1 * (e &&& (d |||  ~~~f)) - 1 * ( ~~~d &&& (e ||| f)) - 6 *  ~~~(d &&&  ~~~f) - 2 * ( ~~~f &&& (d ^^^ e)) + 4 * f + 5 * ( ~~~f |||  ~~~(d ^^^ e)) + 3 * (f ^^^  ~~~(d ||| (e &&& f))) + 5 * ( ~~~d ||| (e &&& f)) + 3 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) - 1 * (e ^^^ (d ||| (e ^^^ f))) - 2 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 7 *  ~~~(d &&& ( ~~~e ||| f)) + 1 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 * (e &&&  ~~~(d ^^^ f)) - 11 * ( ~~~f &&&  ~~~(d ^^^ e)) + 1 * (e ^^^ (d ||| ( ~~~e ||| f))) - 2 * (f ||| (d ^^^ e)) + 5 * ( ~~~e ||| (d ^^^ f)) + 2 * (f ^^^  ~~~(d |||  ~~~e)) + 7 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 3 * (f ^^^  ~~~(d &&& (e &&& f))) - 3 * ((d &&& e) |||  ~~~(e ||| f)) - 3 * (f ^^^  ~~~(d &&&  ~~~e)) + 5 * (e ^^^ (d &&& (e ||| f))) - 1 * (f ^^^ (d &&&  ~~~e)) - 17 *  ~~~(d ||| (e ||| f)) - 12 *  ~~~(d ||| ( ~~~e ||| f)) - 20 *  ~~~( ~~~d ||| (e ||| f)) - 6 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 12 * ( ~~~d &&& ( ~~~e &&& f)) - 26 * ( ~~~d &&& (e &&& f)) - 18 * (d &&& ( ~~~e &&& f)) - 17 * (d &&& (e &&& f)) = 3 * (e ^^^  ~~~(d &&& (e &&& f)))

theorem ashrslt_01_13_proof : ashrslt_01_13_before ⊑ ashrslt_01_13_after

theorem e_2424 :
    1 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 11 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 2 * (e ^^^  ~~~(d ||| (e &&& f))) + 2 * (e ^^^ (d &&& f)) - 1 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) - 6 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 1 * (e ^^^ (d ||| (e ||| f))) + 3 * ( ~~~d &&& ( ~~~e ||| f)) + 5 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 1 * ( ~~~d ||| ( ~~~e &&& f)) - 7 * (e ^^^ (d ||| f)) + 3 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 5 * (f &&&  ~~~(d &&&  ~~~e)) - 11 * (f |||  ~~~(d ||| e)) + 5 * ((d &&& f) ||| (e &&&  ~~~f)) + 2 * ( ~~~f &&& (d ^^^ e)) + 7 *  ~~~(d ^^^ (e ||| f)) + 11 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 11 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * (e ^^^ ( ~~~d &&& (e ||| f))) + 1 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 3 * (d ||| (e ^^^ f)) + 11 * (e |||  ~~~(d |||  ~~~f)) + 7 * (f ^^^  ~~~(d ||| e)) + 1 * (d ||| ( ~~~e ||| f)) - 6 * (e ^^^  ~~~(d |||  ~~~f)) - 1 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 3 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 1 * (e ||| (d ^^^ f)) + 7 *  ~~~(d &&& e) - 6 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 3 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 6 *  ~~~(d &&& f) - 7 * (d ^^^ e) - 1 * (d ||| f) - 1 *  ~~~(d &&& (e ^^^ f)) - 1 * ( ~~~f &&&  ~~~(d ^^^ e)) + 7 * (d |||  ~~~f) - 2 * (f ||| (d ^^^ e)) - 1 * (f ^^^ (d ||| (e &&& f))) + 4 * ( ~~~e &&&  ~~~(d ^^^ f)) - 2 *  ~~~( ~~~d ||| (e &&& f)) - 1 * (e |||  ~~~(d ^^^ f)) - 5 *  ~~~(d ^^^ (e ^^^ f)) - 5 * (f ^^^ (d |||  ~~~e)) + 1 * (d ||| e) - 2 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 5 * (e ^^^ f) + 1 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 3 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 5 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 4 * (f &&& (d ||| e)) + 1 * ( ~~~f ||| (d ^^^ e)) - 1 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 2 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 1 * ( ~~~d ||| (e ||| f)) + 3 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 4 *  ~~~(d &&& (e ||| f)) + 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 11 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 5 * (d &&& e) + 2 * ( ~~~e ||| (d ^^^ f)) + 4 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 11 * (e ^^^ (d ||| (e ^^^ f))) - 7 *  ~~~(d |||  ~~~f) - 2 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 5 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 7 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 13 *  ~~~(d ||| (e ||| f)) - 25 *  ~~~(d ||| ( ~~~e ||| f)) + 11 *  ~~~( ~~~d ||| (e ||| f)) - 26 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 1 * ( ~~~d &&& ( ~~~e &&& f)) - 2 * (d &&& ( ~~~e &&& f)) - 11 * (d &&& (e &&& f)) =  - 24 * ( ~~~d &&& (e &&& f)) + 7 *  ~~~(d &&& (e &&& f))

@[simp]
theorem Array.take_ge_size {a : Array α} {n} (h : n ≥ a.size) : a.take n = a

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

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

theorem lshr_add_thm (e e_1 : IntW 8) :
  shl (add (lshr e_1 (const? 8 5)) (LLVM.srem e (const? 8 42))) (const? 8 5) ⊑
    LLVM.and (add e_1 (shl (LLVM.srem e (const? 8 42)) (const? 8 5))) (const? 8 (-32))

theorem e_2079 :
     - 2 *  ~~~(d &&& ( ~~~e &&& f)) - 7 * ((d &&& e) |||  ~~~(e ^^^ f)) + 1 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 5 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 1 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 11 * (e ^^^ (d &&& f)) + 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 1 * (f ||| (d &&&  ~~~e)) - 2 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 5 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 1 * (d |||  ~~~f) + 2 * (e ^^^  ~~~(d &&& (e &&& f))) + 2 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 3 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 1 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 4 * (f &&& (d ||| e)) + 7 * (f ^^^ ( ~~~d ||| (e ||| f))) + 4 * (f |||  ~~~(d |||  ~~~e)) + 1 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 4 * (f &&& (d ^^^ e)) - 1 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) + 2 * (e &&& (d ||| f)) + 1 * (f ^^^  ~~~(d ||| e)) - 1 * ( ~~~e &&& (d ^^^ f)) - 1 * (e ^^^ ( ~~~d ||| (e ||| f))) - 1 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 3 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 7 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 1 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 2 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 2 * (d ^^^ e) + 7 * (f ^^^  ~~~(d &&& (e ||| f))) + 11 * ( ~~~d &&& (e ||| f)) + 3 * (e ^^^  ~~~(d &&& f)) + 5 *  ~~~(d ||| (e ||| f)) - 34 *  ~~~(d ||| ( ~~~e ||| f)) + 2 *  ~~~( ~~~d ||| (e ||| f)) - 11 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 27 * ( ~~~d &&& (e &&& f)) - 24 * (d &&& ( ~~~e &&& f)) - 1 * (d &&& (e &&& f)) = 5 * ( ~~~d &&& ( ~~~e &&& f))

theorem lshr_sub_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬((42#8 == 0 || 8 != 1 && x_1 == intMin 8 && 42#8 == -1) = true ∨ 3#8 ≥ ↑8 ∨ 3#8 ≥ ↑8) →
    (42#8 == 0 || 8 != 1 && x_1 == intMin 8 && 42#8 == -1) = true ∨
        3#8 ≥ ↑8 ∨ True ∧ (x_1.srem 42#8).ssubOverflow (x >>> 3#8) = true ∨ 3#8 ≥ ↑8 →
      False

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

theorem logic_or_logic_and_2_proof : logic_or_logic_and_2_before ⊑ logic_or_logic_and_2_after

theorem p_commutative2_proof : p_commutative2_before ⊑ p_commutative2_after

theorem ugt_sext_thm (e : IntW 8) (e_1 : IntW 1) :
  icmp IntPred.ugt (sext 8 e_1) e ⊑ icmp IntPred.ult e (sext 8 e_1)

theorem negate_add_with_single_negatible_operand_depth2_thm (e e_1 : IntW 8) :
  sub (const? 8 0) (mul (add e_1 (const? 8 21)) e) ⊑ mul (sub (const? 8 (-21)) e_1) e

theorem foo_thm.extracted_1._1 : ∀ (x : BitVec 32), 5#32 - x &&& 2#32 = 1#32 - x &&& 2#32

theorem nonexact_ashr_eq_exactdiv_proof : nonexact_ashr_eq_exactdiv_before ⊑ nonexact_ashr_eq_exactdiv_after
</all_available_lemmas>

<local_ctx>
import LeanMLIR.Framework

import LeanMLIR.Transforms.Rewrite.Mapping

open Ctxt (Var VarSet Valuation Hom)

variable {d} [DialectSignature d] [DecidableEq d.Ty]

variable {Γ : Ctxt d.Ty} {ty : d.Ty}

abbrev MatchVarM (Δ Γ : Ctxt d.Ty) := (StateT (Mapping Δ Γ) Option)

abbrev MatchVar (Δ Γ : Ctxt d.Ty)  := MatchVarM Δ Γ Unit

def MatchVarM.unifyVars {Δ Γ : Ctxt d.Ty} (v : Δ.Var t) (w : Γ.Var t) : MatchVar Δ Γ :=
  fun ma =>
    match ma.lookup ⟨_, v⟩ with
    | some v =>
      if v = w then
        some ((), ma)
      else
        none
    | none =>
      some ((), AList.insert ⟨_, v⟩ w ma)

open MatchVarM

variable [DecidableEq d.Op]

def matchArg [DecidableEq d.Op]
    (lets : Lets d Γ_in eff Γ_out) (matchLets : Lets d Δ_in .pure Δ_out) :
    {l : List d.Ty} → HVector (Var Γ_out) l → HVector (Var Δ_out) l →
    MatchVar Δ_in Γ_out
  | _, .nil, .nil => return
  | t::l, .cons vₗ vsₗ, .cons vᵣ vsᵣ => do
      matchVar (t := t) lets vₗ matchLets vᵣ
      matchArg lets matchLets vsₗ vsᵣ
  termination_by l => (sizeOf matchLets, l.length + 1)

def matchVar {Γ_in Γ_out Δ_in Δ_out : Ctxt d.Ty} {t : d.Ty} [DecidableEq d.Op]
    (lets : Lets d Γ_in eff Γ_out) (v : Var Γ_out t) :
    (matchLets : Lets d Δ_in .pure Δ_out) →
    (w : Var Δ_out t) →
    MatchVar Δ_in Γ_out
   
  | @Lets.var _ _ _ _ Δ_out ts matchLets matchExpr, w => by admit /- proof elided -/
      | right w =>
        exact matchVar lets v matchLets w
      | left w => exact do
        let ⟨ts', w', ie⟩ ← lets.getPureExpr v
        if hs : ∃ h : ie.op = matchExpr.op, ie.regArgs = (h ▸ matchExpr.regArgs) then
          have hts : Ctxt.ofList ts' = ts := by admit /- proof elided -/

end

section MatchVar

variable [DecidableEq d.Op] {Γ_in Γ_out Δ_in Δ_out t te}
          {lets : Lets d Γ_in eff Γ_out} {v : Var Γ_out t}
          {matchLets : Lets d Δ_in .pure Δ_out}
          {matchExpr : Expr d Δ_out .pure te}
</local_ctx>

<target_theorem>
theorem matchVar_appendInl {w : Var ⟨te⟩ t} :
    matchVar lets v (.var matchLets matchExpr) w.appendInl ma = some ma' →
    ∃ args,
      lets.getPureExpr v
        = some ⟨_, w, matchExpr.op, matchExpr.ty_eq, matchExpr.eff_le, args, matchExpr.regArgs⟩
      ∧ matchArg lets matchLets args matchExpr.args ma = some ma' :=
</target_theorem>

