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
Set in Mathlib.Data.Set.Defs
Set.Subset in Mathlib.Data.Set.Defs
List.Subset in Init.Data.List.Basic
StateT.bind in Init.Control.State
liftM in Init.Prelude
Iff in Init.Core
IsEmpty in Mathlib.Logic.IsEmpty
reduceCtorEq in Lean.Meta.Tactic.Simp.BuiltinSimprocs.Core

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

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

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

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

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

def testExampleSource : DCOp.TokenStream :=
  exampleSink.denote (Ctxt.Valuation.ofHVector (.cons inputSource <| .nil))

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

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

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

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

def 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 factorize4_after := [llvm|
{
^0(%arg3 : i32, %arg4 : i32):
  %0 = llvm.mul %arg4, %arg3 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

def bb0 : Region 0 := [mlir_region|
{
  ^bb0(%arg0: i32):
    %0 = llvm.mlir.constant(8) : i32
    %1 = llvm.mlir.constant(31) : i32
    %2 = llvm.ashr %arg0, %1 : i32
    %3 = llvm.and %2, %0 : i32
    %4 = llvm.add %3, %2 : i32
    llvm.return %4 : i32
  }]

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

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

Equivalence in Init.Core

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

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

def bools_multi_uses2_after := [llvm|
{
^0(%arg39 : i1, %arg40 : i1, %arg41 : i1):
  %0 = "llvm.select"(%arg41, %arg40, %arg39) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

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

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

def scalar_i8_shl_ult_const_3_before := [llvm|
{
^0(%arg17 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(64 : i8) : i8
  %2 = llvm.shl %arg17, %0 : i8
  %3 = llvm.icmp "ult" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def n2_before := [llvm|
{
^0(%arg19 : i1, %arg20 : i8, %arg21 : i8, %arg22 : i8, %arg23 : i8):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.icmp "eq" %arg20, %arg21 : i8
  %2 = llvm.xor %arg19, %0 : i1
  %3 = llvm.and %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def shl_xor_xor_no_const_before := [llvm|
{
^0(%arg134 : i8, %arg135 : i8, %arg136 : i8, %arg137 : i8):
  %0 = llvm.shl %arg134, %arg136 : i8
  %1 = llvm.shl %arg135, %arg136 : i8
  %2 = llvm.xor %1, %arg137 : i8
  %3 = llvm.xor %0, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

elab "[mod_arith " qi:term "," hq:term " | " reg:mlir_region "]" : term => do
  
  let q_   : Q(Nat)             ← elabTermEnsuringTypeQ qi   q(Nat)
  
  let hq_  : Q(Fact ($q_ > 1))  ← elabTermEnsuringTypeQ hq   q(Fact ($q_ > 1))
  
  SSA.elabIntoCom reg q(ModArith $q_)

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

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

def 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 in_constant_varx_mone_invmask_after := [llvm|
{
^0(%arg41 : i4, %arg42 : i4):
  %0 = llvm.or %arg41, %arg42 : i4
  "llvm.return"(%0) : (i4) -> ()
}
]

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

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

def Lets.substitute (σ : Substitution) : Lets Op T → Lets Op T
  | ⟨ls⟩    => ⟨go ls⟩
  where go : List (Expr Op T) → List (Expr Op T)
    | [] => []
    | l::ls => l.substitute σ :: go ls

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

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

HShiftRight.hShiftRight in Init.Prelude

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 neg_slt_42_before := [llvm|
{
^0(%arg30 : i128):
  %0 = llvm.mlir.constant(0 : i128) : i128
  %1 = llvm.mlir.constant(42 : i128) : i128
  %2 = llvm.sub %0, %arg30 : i128
  %3 = llvm.icmp "slt" %2, %1 : i128
  "llvm.return"(%3) : (i1) -> ()
}
]

def sltu_test: LLVMPeepholeRewriteRefine 16 [Ty.llvm (.bitvec 16), Ty.llvm (.bitvec 16) ] where
  lhs := sltu_llvm
  rhs := sltu_riscv

def bools_logical_commute1_after := [llvm|
{
^0(%arg96 : i1, %arg97 : i1, %arg98 : i1):
  %0 = "llvm.select"(%arg98, %arg97, %arg96) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

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

def logic_or_logic_and_8_before := [llvm|
{
^0(%arg66 : i1, %arg67 : i1, %arg68 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = "llvm.select"(%arg66, %0, %arg67) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = "llvm.select"(%arg68, %0, %arg66) <{"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 t20_before := [llvm|
{
^0(%arg145 : i8, %arg146 : i16):
  %0 = llvm.mlir.constant(-42 : i16) : i16
  %1 = llvm.shl %0, %arg146 : i16
  %2 = llvm.trunc %1 : i16 to i8
  %3 = llvm.sub %arg145, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

def lshrugt_03_05_exact_before := [llvm|
{
^0(%arg184 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(5 : i4) : i4
  %2 = llvm.lshr exact %arg184, %0 : i4
  %3 = llvm.icmp "ugt" %2, %1 : i4
  "llvm.return"(%3) : (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 pr40493_neg3_after := [llvm|
{
^0(%arg15 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(4 : i32) : i32
  %2 = llvm.shl %arg15, %0 : i32
  %3 = llvm.and %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def XorZextXor_after := [llvm|
{
^0(%arg6 : i3):
  %0 = llvm.mlir.constant(15 : i5) : i5
  %1 = llvm.zext %arg6 : i3 to i5
  %2 = llvm.xor %1, %0 : i5
  "llvm.return"(%2) : (i5) -> ()
}
]

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

def mbaTac (g : MVarId) : TermElabM (List MVarId) := do
  g.withContext do
    let [g] ← g.apply (mkConst ``BitVec.eq_of_sub_zero)
      | throwError m!"unable to apply `BitVec.eq_of_sub_zero`."
    let .some g ← runBvMbaPreprocess  g
      | do
         trace[Bits.MBA] "goal closed by Mba normalizer."
         return []
    trace[Bits.MBA] m!"Normalized goal state to {indentD g}"
    let ((widthExpr, eqn), reflectState) ← g.withContext do runM <| reflectEqn (← g.getType)
    trace[Bits.MBA] m!"found expression of width: '{indentD widthExpr}'"
    let env ← State.envToExpr widthExpr reflectState
    trace[Bits.MBA] m!"replacing goal with reflected version. Equation: {indentD <| repr eqn}"
    trace[Bits.MBA] m!"Environment: {indentD (toMessageData reflectState.e2ix.toList)}"
    
    
    
    
    

    let gs ← g.withContext do g.apply (mkAppN (mkConst ``Eqn.forall_width_reflect_zero_of_width_one_denote_zero []) #[Eqn.toExpr eqn, widthExpr, env])
    let [g] := gs
      | throwError m!"expected single goal after applying reflection theorem, found {gs}"
    let dec ← mkDecideProof <| ← g.getType
    if ← isDefEq (mkMVar g) dec then
      trace[Bits.MBA] "successfully decided!"
      return []
    else
      logWarning "failed to prove theorem using decision procedure, statement is false."
      return [g]

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

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

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

def icmp_eq_and_pow2_minus1_shl1_after := [llvm|
{
^0(%arg58 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.icmp "ugt" %arg58, %0 : i32
  %2 = llvm.zext %1 : i1 to i32
  "llvm.return"(%2) : (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 test_and2_before := [llvm|
{
^0(%arg48 : i32, %arg49 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.and %arg49, %0 : i32
  %3 = llvm.icmp "sgt" %arg48, %1 : i32
  %4 = llvm.icmp "sle" %arg48, %2 : i32
  %5 = llvm.and %3, %4 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

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

def zext_sext_ugt_known_nonneg_after := [llvm|
{
^0(%arg22 : i8, %arg23 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.and %arg22, %0 : i8
  %2 = llvm.icmp "ugt" %1, %arg23 : i8
  "llvm.return"(%2) : (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 lshrugt_03_09_after := [llvm|
{
^0(%arg374 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

    |

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

def lshr_and_or_disjoint_before := [llvm|
{
^0(%arg43 : i8, %arg44 : 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 %arg43, %0 : i8
  %4 = llvm.lshr %arg44, %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 test_nuw_and_unsigned_pred_after := [llvm|
{
^0(%arg57 : i64):
  %0 = llvm.mlir.constant(7) : i64
  %1 = llvm.icmp "ugt" %arg57, %0 : i64
  "llvm.return"(%1) : (i1) -> ()
}
]

def udiv1_before := [llvm|
{
^0(%arg32 : i32, %arg33 : i32):
  %0 = llvm.udiv exact %arg32, %arg33 : i32
  %1 = llvm.mul %0, %arg33 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def sext_zext_apint2_before := [llvm|
{
^0(%arg85 : i11):
  %0 = llvm.zext %arg85 : i11 to i39
  %1 = llvm.sext %0 : i39 to i47
  "llvm.return"(%1) : (i47) -> ()
}
]

Lean.Parser.Term.leading_parser in Lean.Parser.Term

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

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

def 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 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 addAux' (carryIn : Bool) (x y : BitStream) (i : Nat) :  Bool × Bool :=
  let carryIn : Bool := match i with
    | 0 => carryIn
    | i + 1 => (addAux' carryIn x y i).2
  Prod.swap (BitVec.adcb (x i) (y i) carryIn)

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

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

def shift_xor_multiuse_cmp_with_xor_before := [llvm|
{
^0(%arg80 : i32, %arg81 : i32, %arg82 : i32, %arg83 : 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 %arg80, %0 : i32
  %4 = llvm.icmp "ne" %1, %3 : i32
  %5 = llvm.xor %arg81, %2 : i32
  %6 = "llvm.select"(%4, %arg81, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg82, %arg83) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %8 = llvm.mul %6, %7 : i32
  "llvm.return"(%8) : (i32) -> ()
}
]

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 sub_shl_same_amount_partial_nsw1_after := [llvm|
{
^0(%arg11 : i6, %arg12 : i6, %arg13 : i6):
  %0 = llvm.sub %arg11, %arg12 : i6
  %1 = llvm.shl %0, %arg13 : i6
  "llvm.return"(%1) : (i6) -> ()
}
]

noncomputable def dropLeadingNones (x : Stream α) (not_stuck : x ≠ stuck α) : Stream α:=
  x.drop (nonesUntilSome x not_stuck)

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 lowmask_add_2_before := [llvm|
{
^0(%arg144 : i8):
  %0 = llvm.mlir.constant(-64 : i8) : i8
  %1 = llvm.mlir.constant(63 : i8) : i8
  %2 = llvm.add %arg144, %0 : i8
  %3 = llvm.and %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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 test11_before := [llvm|
{
^0(%arg43 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.icmp "ule" %arg43, %0 : i1
  "llvm.return"(%1) : (i1) -> ()
}
]

def tryFactorization_add_nuw_mul_nuw_mul_var_after := [llvm|
{
^0(%arg3 : i32, %arg4 : i32, %arg5 : i32):
  %0 = llvm.add %arg4, %arg5 : i32
  %1 = llvm.mul %arg3, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

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

def 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 foo1_or_signbit_lshr_without_shifting_signbit_both_sides_before := [llvm|
{
^0(%arg100 : i32, %arg101 : i32, %arg102 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.shl %arg100, %arg101 : i32
  %2 = llvm.icmp "slt" %1, %0 : i32
  %3 = llvm.shl %arg100, %arg102 : i32
  %4 = llvm.icmp "slt" %3, %0 : i32
  %5 = llvm.and %2, %4 : i1
  "llvm.return"(%5) : (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 testi8i8_before := [llvm|
{
^0(%arg10 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(127 : i8) : i8
  %2 = llvm.ashr %arg10, %0 : i8
  %3 = llvm.xor %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

@[match_pattern]
def cons (hd : Ty) : Ctxt Ty → Ctxt Ty
| ⟨tl⟩ => ⟨hd :: tl⟩

BitVec.instHShiftLeft in Init.Data.BitVec.Basic

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

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

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

def buggy_ISEL_pattern : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs:= original_sdiv_srem
  rhs:= combined_sdiv_srem
  correct := by admit /- proof elided -/

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

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

def shl_xor_after := [llvm|
{
^0(%arg22 : i8):
  %0 = llvm.mlir.constant(22 : i8) : i8
  %1 = llvm.shl %0, %arg22 : i8
  "llvm.return"(%1) : (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 exampleSink := [DCxComb_com| {
  ^entry(%0: !TokenStream):
    %src = "DCxComb.sink" (%0) : (!TokenStream) -> (!TokenStream)
    "return" (%src) : (!TokenStream) -> ()
  }]

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

Polynomial.ofFinsupp in Mathlib.Algebra.Polynomial.Basic

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

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

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

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

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

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

def lhs : Com ScfArith ⟨[  t]⟩ .impure t :=
    Com.letPure (cst_nat niters1) <|
    Com.letPure (cst start1) <|
    Com.letPure (cst 1) <|
  
  Com.var (for_ (t := t) ⟨1, by admit /- proof elided -/
  ⟩ ⟨0, by admit /- proof elided -/
  ⟩ ⟨2, by admit /- proof elided -/
  ⟩ ⟨3, by admit /- proof elided -/
  ⟩ rgn) <|
    Com.letPure (cst_nat niters2) <|
    Com.letPure (cst <| niters1 + start1) <|
    Com.letPure (cst 1) <|
  Com.var (for_ (t := t) ⟨1, by admit /- proof elided -/
  ⟩ ⟨0, by admit /- proof elided -/
  ⟩ ⟨2, by admit /- proof elided -/
  ⟩ ⟨3, by admit /- proof elided -/
  ⟩ rgn) <|
  Com.ret ⟨0, rfl⟩

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

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 mul_splat_fold_before := [llvm|
{
^0(%arg161 : i32):
  %0 = llvm.mlir.constant(65537 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.mul %arg161, %0 overflow<nuw> : i32
  %3 = llvm.lshr %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def test_zext_nneg_after := [llvm|
{
^0(%arg25 : i32, %arg26 : i64, %arg27 : i64):
  %0 = llvm.mlir.constant(-4) : i64
  %1 = llvm.add %arg26, %0 : i64
  %2 = llvm.sext %arg25 : i32 to i64
  %3 = llvm.sub %2, %arg27 : i64
  %4 = llvm.add %1, %3 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

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

Polynomial in Mathlib.Algebra.Polynomial.Basic

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

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

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

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

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

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

def two_inst_com_proof (w : Nat) :
    two_inst_com w ⊑ two_inst_com w :=

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

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

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

def and_not_xor_common_op_after := [llvm|
{
^0(%arg681 : i32, %arg682 : i32):
  %0 = llvm.and %arg681, %arg682 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

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

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

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

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

inductive ExpTy where
  | isl : ISL.Ty → ExpTy
  | regFile

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

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

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

def size : FpPredicate → Nat
| .bin lhs _ rhs => 1 + lhs.size + rhs.size

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

structure Item where
 name : String
 tac : Syntax

def alive_InstCombineShift__279_tgt :=
[sllvm| {
^bb0(%X : i64, %C : i64):
  %v1 = llvm.lshr %X, %C : i64
  %v2 = llvm.mlir.constant -1 : i64
  %v3 = llvm.shl %v2, %C : i64
  %v4 = llvm.and %X, %v3 : i64
  llvm.return %v4 : i64
}]

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

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

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

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

def PostLegalizerCombiner_RISCV: List (Σ Γ,RISCVPeepholeRewrite  Γ) :=
    RISCV_identity_combines ++
    commute_int_constant_to_rhs ++
    simplify_neg ++
    mulh_to_lshr

def vec_to_streams {α : Type u} {n : Nat} (xv : Stream' (Vector α n)) : Vector (Stream' α) n :=
   
  Vector.ofFn (fun (k : Fin n) => fun (i : Nat) => (xv i).get k)

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 or_xor_commute3_before := [llvm|
{
^0(%arg162 : i32, %arg163 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.udiv %0, %arg162 : i32
  %2 = llvm.udiv %0, %arg163 : i32
  %3 = llvm.or %2, %1 : i32
  %4 = llvm.xor %3, %2 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def test2_after := [llvm|
{
^0(%arg18 : i8):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(3 : i32) : i32
  %2 = llvm.zext %arg18 : i8 to i32
  %3 = llvm.add %2, %0 overflow<nsw,nuw> : i32
  %4 = llvm.lshr %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

def a : Stream (BitVec 32) := ofList [1#32, none, 2#32, 5#32, none]

class HydrableParseAndGeneralize (parsedExpr : Type) (genPred : Type) (genExpr : Nat → Type) extends
  HydrableGeneralize parsedExpr genPred genExpr,
  HydrableParseExprs parsedExpr genPred,
  HydrableInitializeGeneralizerState parsedExpr genPred genExpr,
  HydrablePrettify genPred,
  HydrablePrettifyAsTheorem genPred,
  HydrableGetInputWidth
  where

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

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

instance : HydrableSubstitute FpPredicate FpExpr where
  substitute := substitute

RV64.srai in RISCV.Instructions

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

def factorize3_after := [llvm|
{
^0(%arg5 : i32, %arg6 : i32, %arg7 : i32):
  %0 = llvm.or %arg5, %arg7 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

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

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

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 and_orn_cmp_1_logical_after := [llvm|
{
^0(%arg128 : i32, %arg129 : i32, %arg130 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.icmp "sgt" %arg128, %arg129 : i32
  %2 = "llvm.select"(%1, %arg130, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 select_2_before := [llvm|
{
^0(%arg82 : i1, %arg83 : i8, %arg84 : i1, %arg85 : i8, %arg86 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(123 : i8) : i8
  %2 = llvm.mlir.constant(45 : i8) : i8
  %3 = llvm.xor %arg85, %0 : i8
  %4 = llvm.xor %arg86, %1 : i8
  %5 = "llvm.select"(%arg84, %3, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %6 = llvm.xor %arg83, %2 : i8
  %7 = "llvm.select"(%arg82, %5, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %8 = llvm.xor %7, %0 : i8
  "llvm.return"(%8) : (i8) -> ()
}
]

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

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

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

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

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

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

def llvm_const_lower_riscv_li_21 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_21, rhs:= liRiscv_21,
   correct := by admit /- proof elided -/

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

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

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

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

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

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

def attrDict2 : AttrDict 0 := [mlir_attr_dict| {foo = "bar", baz = "quux" }]

def or_not_and_commute9_before := [llvm|
{
^0(%arg510 : i32, %arg511 : i32, %arg512 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg510 : i32
  %3 = llvm.sdiv %0, %arg511 : i32
  %4 = llvm.sdiv %0, %arg512 : i32
  %5 = llvm.or %2, %3 : i32
  %6 = llvm.xor %5, %1 : i32
  %7 = llvm.and %6, %4 : i32
  %8 = llvm.or %2, %4 : i32
  %9 = llvm.xor %8, %1 : i32
  %10 = llvm.and %3, %9 : i32
  %11 = llvm.or %7, %10 : i32
  "llvm.return"(%11) : (i32) -> ()
}
]

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

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

def sdiv_exact_ne_1_after := [llvm|
{
^0(%arg12 : i8, %arg13 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "eq" %arg12, %0 : i8
  "llvm.return"(%1) : (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 select_or_disjoint_or_before := [llvm|
{
^0(%arg14 : i32, %arg15 : i1):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(4 : i32) : i32
  %2 = "llvm.select"(%arg15, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %3 = llvm.shl %arg14, %1 : i32
  %4 = llvm.or disjoint %2, %3 : i32
  %5 = llvm.add %4, %1 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def test_sub_nuw__all_are_safe_before := [llvm|
{
^0(%arg30 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.mlir.constant(6 : i32) : i32
  %2 = llvm.mlir.constant(-254 : i32) : i32
  %3 = llvm.mlir.constant(-260 : i32) : i32
  %4 = llvm.and %arg30, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.sub %2, %4 overflow<nuw> : i32
  %7 = "llvm.select"(%5, %3, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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 CollectState.icard (state : CollectState) : Nat :=
  state.iToIx.size

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

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

def select_riscv_select_llvm_16 : LLVMPeepholeRewriteRefine 16
  [Ty.llvm (.bitvec 16), Ty.llvm (.bitvec 16), Ty.llvm (.bitvec 1)] where
  lhs := select_llvm_16
  rhs := select_riscv_16

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

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

def shl1_trunc_sgt0_before := [llvm|
{
^0(%arg20 : i9):
  %0 = llvm.mlir.constant(1 : i9) : i9
  %1 = llvm.mlir.constant(0 : i6) : i6
  %2 = llvm.shl %0, %arg20 : i9
  %3 = llvm.trunc %2 : i9 to i6
  %4 = llvm.icmp "sgt" %3, %1 : i6
  "llvm.return"(%4) : (i1) -> ()
}
]

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

def or_test2_before := [llvm|
{
^0(%arg0 : i7, %arg1 : i7):
  %0 = llvm.mlir.constant(6 : i7) : i7
  %1 = llvm.mlir.constant(-64 : i7) : i7
  %2 = llvm.shl %arg0, %0 : i7
  %3 = llvm.or %2, %1 : i7
  "llvm.return"(%3) : (i7) -> ()
}
]

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

def n13_after := [llvm|
{
^0(%arg4 : i32, %arg5 : i32, %arg6 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.shl %0, %arg5 overflow<nsw> : i32
  %2 = llvm.and %1, %arg4 : i32
  %3 = llvm.lshr %2, %arg6 : i32
  "llvm.return"(%3) : (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) -> ()
}
]

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

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

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

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

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 land_lor_right1_after := [llvm|
{
^0(%arg46 : i1, %arg47 : i1):
  "llvm.return"(%arg46) : (i1) -> ()
}
]

def or_test2_after := [llvm|
{
^0(%arg0 : i7, %arg1 : i7):
  %0 = llvm.mlir.constant(-64 : i7) : i7
  "llvm.return"(%0) : (i7) -> ()
}
]

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

def test1_after := [llvm|
{
^0(%arg3 : i16):
  %0 = llvm.mlir.constant(8 : i16) : i16
  %1 = llvm.mlir.constant(5 : i16) : i16
  %2 = llvm.lshr %arg3, %0 : i16
  %3 = llvm.mul %arg3, %1 : i16
  %4 = llvm.or %2, %3 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

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

def sub_shl_same_amount_partial_nuw2_before := [llvm|
{
^0(%arg2 : i6, %arg3 : i6, %arg4 : i6):
  %0 = llvm.shl %arg2, %arg4 overflow<nuw> : i6
  %1 = llvm.shl %arg3, %arg4 : i6
  %2 = llvm.sub %0, %1 overflow<nuw> : i6
  "llvm.return"(%2) : (i6) -> ()
}
]

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

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

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

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

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

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

partial def Expr.print (e : Expr d Γ eff t) : Format :=
  let regions :=
    match h : e.regArgs.length with
    | 0 => f!""
    | 1 =>
      let reg := e.regArgs.getN 0 (by admit /- proof elided -/
      )
      f!" ({reg.print})"
    | _ =>
      let regs :=
        e.regArgs.mapToList (Format.align true ++ Com.print ·)
        |> f!", ".joinSep
        |> Format.nest 2
      f!" ({regs})"
  Format.align true ++ f!"{e.printResultList}\"{printOpName e.op}\"{e.printArgs}{printAttributes e.op}{regions} : {e.printType}"

Lean.pp.explicit in Lean.PrettyPrinter.Delaborator.Options

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

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

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

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

Lean.Syntax.mkNumLit in Init.Meta.Defs

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

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

def different_size_sext_sext_sle_before := [llvm|
{
^0(%arg12 : i7, %arg13 : i4):
  %0 = llvm.sext %arg12 : i7 to i25
  %1 = llvm.sext %arg13 : i4 to i25
  %2 = llvm.icmp "sle" %0, %1 : i25
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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 test9_before := [llvm|
{
^0(%arg87 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.and %arg87, %0 : i32
  %2 = llvm.trunc %1 : i32 to i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

def getIntAttr (attr : String) (coeBool : Bool := true) : Except TransformError (Int × MLIRType φ) := do
  let attrVal ← op.getAttr attr
  if coeBool then if let .bool b := attrVal then
    return (if b then 1 else 0, .int .Signless (.concrete 1))

  let .int val ty := attrVal
    | .error <| .generic s!"Expected attribute `{attr}` to be of type Int, but found:\n\
        \t{attr}"
  return (val, ty)

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

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

abbrev Width φ := ConcreteOrMVar Nat φ

def three_inst_concrete_macro :=
  [llvm()|{
  ^bb0(%arg0: i1):
    %0 = llvm.not %arg0 : i1
    %1 = llvm.not %0 : i1
    %2 = llvm.not %1 : i1
    llvm.return %2 : i1
  }]

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

@[simp_denote]
def udiv_llvm_no_exact_32 : Com  LLVMPlusRiscV ⟨[.llvm (.bitvec 32), .llvm (.bitvec 32)]⟩
  .pure (.llvm (.bitvec 32)) := [LV| {
  ^entry (%x: i32, %y: i32 ):
    %1 = llvm.udiv    %x, %y : i32
    llvm.return %1 : i32
  }]

def pruneEquivalentFpExprs (expressions: List (FpExpr w)) : GeneralizerStateM ParsedFpExpr FpPredicate  (List (FpExpr w)) := do
  withTraceNode `Generalize (fun _ => return "Pruned equivalent bvExprs") do
    let mut pruned : List (FpExpr w) := []

    for expr in expressions do
      if pruned.isEmpty then
        pruned := expr :: pruned
        continue

      let newConstraints := pruned.map (fun f =>  BoolExpr.not (BoolExpr.literal (FpPredicate.bin f .eq expr)))
      let subsumeCheckExpr :=  bigAnd newConstraints

      if let some _ ← solve subsumeCheckExpr then
        pruned := expr :: pruned

    trace[Generalize] m! "Removed {expressions.length - pruned.length} expressions after pruning {expressions.length} expressions"

    pure pruned

@[simp_denote]
def trunc_riscv_to_32_nuw := [LV| {
  ^entry (%lhs: i64 ):
    %lhsr = "builtin.unrealized_conversion_cast"(%lhs) : (i64) -> (!i64)
    %2= "builtin.unrealized_conversion_cast"(%lhsr) : (!i64) -> (i32)
    llvm.return %2 : i32
  }]

def t0_before := [llvm|
{
^0(%arg15 : i8):
  %0 = llvm.mlir.constant(-32 : i8) : i8
  %1 = llvm.sdiv exact %arg15, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

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

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

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

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

abbrev WidthExpr := Expr

@[simp]
def Formula.sat {w : Nat} (φ : Formula) (ρ : Fin φ.arity → BitVec w) : Prop :=
  match φ with
  | .width wp n => wp.sat w n
  | .atom rel t1 t2 =>
    let bv1 := t1.evalFinBV (fun n => ρ $ Fin.castLE (by admit /- proof elided -/
    ) n)
    let bv2 := t2.evalFinBV (fun n => ρ $ Fin.castLE (by admit /- proof elided -/
    ) n)
    evalRelation rel bv1 bv2
  | .unop .neg φ => ¬ φ.sat ρ
  | .binop op φ1 φ2 =>
    let b1 := φ1.sat (fun n => ρ $ Fin.castLE (by admit /- proof elided -/
    ) n)
    let b2 := φ2.sat (fun n => ρ $ Fin.castLE (by admit /- proof elided -/
    ) n)
    evalBinop op b1 b2
  | .msbSet t => (t.evalFinBV ρ).msb

@[simp_denote]
def sub_riscv_16 := [LV| {
  ^entry (%x: i16, %y: i16):
    %0 = "builtin.unrealized_conversion_cast"(%x) : (i16) -> (!i64)
    %1 = "builtin.unrealized_conversion_cast"(%y) : (i16) -> (!i64)
    %2 = sub %0, %1 : !i64
    %3 = "builtin.unrealized_conversion_cast"(%2) : (!i64) -> (i16)
    llvm.return %3 : i16
  }]

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

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 test48_before := [llvm|
{
^0(%arg137 : i8, %arg138 : i8):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.zext %arg138 : i8 to i32
  %2 = llvm.zext %arg137 : i8 to i32
  %3 = llvm.shl %2, %0 : i32
  %4 = llvm.or %3, %2 : i32
  %5 = llvm.zext %4 : i32 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

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

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

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

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

def negative5_before := [llvm|
{
^0(%arg2 : i32, %arg3 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg3, %0 : i32
  %3 = llvm.icmp "slt" %arg2, %2 : i32
  %4 = llvm.icmp "sge" %arg2, %1 : i32
  %5 = llvm.or %3, %4 : i1
  "llvm.return"(%5) : (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_commute9_before := [llvm|
{
^0(%arg454 : i32, %arg455 : i32, %arg456 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg454 : i32
  %3 = llvm.sdiv %0, %arg455 : i32
  %4 = llvm.sdiv %0, %arg456 : i32
  %5 = llvm.and %2, %3 : i32
  %6 = llvm.xor %5, %1 : i32
  %7 = llvm.or %6, %4 : i32
  %8 = llvm.and %2, %4 : i32
  %9 = llvm.xor %8, %1 : i32
  %10 = llvm.or %3, %9 : i32
  %11 = llvm.and %7, %10 : i32
  "llvm.return"(%11) : (i32) -> ()
}
]

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

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

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

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

def DCFork := [DC_com| {
  ^entry(%0 : !ValueStream_8):
    %unpack12 = "DC.unpack" (%0) : (!ValueStream_8) -> (!ValueTokenStream_8)
    %unpack1 = "DC.fstVal" (%unpack12) : (!ValueTokenStream_8) -> (!ValueStream_8)
    %unpack2 = "DC.sndVal" (%unpack12) : (!ValueTokenStream_8) -> (!TokenStream)
    %fork12 = "DC.fork" (%unpack2) : (!TokenStream) -> (!TokenStream2)
    %fork1 = "DC.fst" (%fork12) : (!TokenStream2) -> (!TokenStream)
    %fork2 = "DC.snd" (%fork12) : (!TokenStream2) -> (!TokenStream)
    %pack1 = "DC.pack" (%unpack1, %fork1) : (!ValueStream_8, !TokenStream) -> (!ValueStream_8)
    %pack2 = "DC.pack" (%unpack1, %fork2) : (!ValueStream_8, !TokenStream) -> (!ValueStream_8)
    %pack12 = "DC.pair" (%pack1, %pack2) : (!ValueStream_8, !ValueStream_8) -> (!ValueStream2_8)
    "return" (%pack12) : (!ValueStream2_8) -> ()
  }]

instance : DecidableEq VarName :=

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

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

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

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

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

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 lshrugt_01_03_exact_before := [llvm|
{
^0(%arg218 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(3 : i4) : i4
  %2 = llvm.lshr exact %arg218, %0 : i4
  %3 = llvm.icmp "ugt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def altMerge (x y : Stream α) : Stream α :=
  Stream.corec (β := Stream α × Stream α × ConsumeFrom) (x, y, .left) fun ⟨x, y, consume⟩ =>
    match consume with
      | .left  =>
        let x0 := x.head
        let x := x.tail
        let nextConsume := match x0 with
          | some _ => .right
          | none   => .left
        (x0, x, y, nextConsume)
      | .right =>
        let y0 := y.head
        let y := y.tail
        let nextConsume := match y0 with
          | some _ => .left
          | none   => .right
        (y0, x, y, nextConsume)

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

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

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

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

def toMap : Var Γ t → Var (Γ.map f) (f t)
  | ⟨i, h⟩ => ⟨i, by admit /- proof elided -/
  ⟩

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

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

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

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

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

PartialOrder in Mathlib.Order.Defs.PartialOrder

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

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

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 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 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 trunc_lshr_sext_wide_input_after := [llvm|
{
^0(%arg33 : i16):
  %0 = llvm.mlir.constant(9 : i16) : i16
  %1 = llvm.ashr %arg33, %0 : i16
  %2 = llvm.trunc %1 overflow<nsw> : i16 to i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

def mul32_low_before := [llvm|
{
^0(%arg22 : i32, %arg23 : i32):
  %0 = llvm.mlir.constant(65535 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.and %arg22, %0 : i32
  %3 = llvm.lshr %arg22, %1 : i32
  %4 = llvm.and %arg23, %0 : i32
  %5 = llvm.lshr %arg23, %1 : i32
  %6 = llvm.mul %5, %2 : i32
  %7 = llvm.mul %4, %3 : i32
  %8 = llvm.mul %4, %2 : i32
  %9 = llvm.add %6, %7 : i32
  %10 = llvm.shl %9, %1 : i32
  %11 = llvm.add %10, %8 : i32
  "llvm.return"(%11) : (i32) -> ()
}
]

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

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

NatCast in Init.Data.Cast

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

def test2_before := [llvm|
{
^0(%arg5 : i1005):
  %0 = llvm.mlir.constant(0 : i1005) : i1005
  %1 = llvm.xor %arg5, %0 : i1005
  "llvm.return"(%1) : (i1005) -> ()
}
]

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

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

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

def test13_before := [llvm|
{
^0(%arg16 : i8, %arg17 : i8):
  %0 = llvm.icmp "ult" %arg16, %arg17 : i8
  %1 = llvm.icmp "ugt" %arg16, %arg17 : i8
  %2 = llvm.xor %0, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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 sgt_and_min_logical_after := [llvm|
{
^0(%arg350 : i9, %arg351 : i9):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def CNFA.toNFA (m : CNFA n) : NFA (BitVec n) m.m.states where
  start := { s | s.val ∈ m.m.initials }
  accept := { s | s.val ∈ m.m.finals }
  step s₁ a := { s₂ | s₂.val ∈ m.m.tr s₁.val a }

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

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

instance subtypeBEq [BEq α]  (P : α → Prop) : BEq { x // P x } := { beq := fun x y => x.val == y.val }

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

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

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

def and_two_ranges_to_mask_and_range_before := [llvm|
{
^0(%arg252 : i8):
  %0 = llvm.mlir.constant(-97 : i8) : i8
  %1 = llvm.mlir.constant(25 : i8) : i8
  %2 = llvm.mlir.constant(-65 : i8) : i8
  %3 = llvm.add %arg252, %0 : i8
  %4 = llvm.icmp "ugt" %3, %1 : i8
  %5 = llvm.add %arg252, %2 : i8
  %6 = llvm.icmp "ugt" %5, %1 : i8
  %7 = llvm.and %4, %6 : i1
  "llvm.return"(%7) : (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) -> ()
}
]

@[simp]
def EnvFin.get_castLe {w n n' : Nat} (env : EnvFin w n) (h : n' ≤ n) (i : Fin n') :
  (env.castLe h) i = env ⟨i, by admit /- proof elided -/
  ⟩ := rfl

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

@[simp_denote]
def add_shl_rhs_constant_llvm := [LV| {
    ^entry (%a0: i64, %a1: i64):
    %0 = llvm.mlir.constant (1) : i64
    %c3 = llvm.mlir.constant (3) : i64
    %c8 = llvm.mlir.constant (-8) : i64
    %1 = llvm.add %a0, %0 : i64
    %2 = llvm.add %a1, %1 : i64
    %3 = llvm.shl %2, %c3 : i64
    %4 = llvm.add %3, %c8 : i64
    llvm.return %4 : i64
  }]

Lean.mkAppN in Lean.Expr

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

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

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

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

@[simp_denote]
def llvmArgsFromHybrid_nil_eq :
  (llvmArgsFromHybrid HVector.nil) = HVector.nil := rfl

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

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

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 test5_before := [llvm|
{
^0(%arg0 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.icmp "slt" %arg0, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

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

def masked_icmps_mask_notallzeros_bmask_mixed_7b_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 shl_add_and_after := [llvm|
{
^0(%arg96 : i8, %arg97 : i8):
  %0 = llvm.mlir.constant(61 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.add %arg97, %0 : i8
  %3 = llvm.and %arg96, %2 : i8
  %4 = llvm.shl %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

private def bbop1 : SSAVal × MLIRTy φ := [mlir_bb_operand| %x : i32 ]

def test6_before := [llvm|
{
^0(%arg1 : i7):
  %0 = llvm.mlir.constant(23 : i7) : i7
  %1 = llvm.xor %arg1, %0 : i7
  %2 = llvm.xor %1, %0 : i7
  "llvm.return"(%2) : (i7) -> ()
}
]

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

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

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

def VarName : Type := String

def Env.ofEnvFin (envFin : EnvFin w n) : Env w := (List.finRange n).map envFin

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

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

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

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

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

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

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

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

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 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 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 shr_umax_before := [llvm|
{
^0(%arg16 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(4 : i32) : i32
  %2 = llvm.icmp "ugt" %0, %arg16 : i32
  %3 = "llvm.select"(%2, %0, %arg16) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.lshr %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

CommRing in Mathlib.Algebra.Ring.Defs

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

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

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

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

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

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

LE in Init.Prelude

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

instance : Coe (String × MLIRType φ) (AttrEntry φ) where
  coe v := AttrEntry.mk v.fst (AttrValue.type v.snd)

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 shl_xor_lshr_comm_before := [llvm|
{
^0(%arg97 : i32, %arg98 : i32, %arg99 : i32):
  %0 = llvm.shl %arg97, %arg98 overflow<nuw> : i32
  %1 = llvm.xor %arg99, %0 : i32
  %2 = llvm.lshr %1, %arg98 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

def hasType (Γ : Context Ty) (v : VarName) (ty : Ty) : Prop :=
  Γ.lookup v = some ty

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

def NatPredicate.toProp (env : Fin wcard → Nat) : NatPredicate wcard → Prop
| .eq e1 e2 => WidthExpr.toNat e1 env = WidthExpr.toNat e2 env

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 sel_sext_before := [llvm|
{
^0(%arg93 : i32, %arg94 : i1):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = "llvm.select"(%arg94, %arg93, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %2 = llvm.sext %1 : i32 to i64
  "llvm.return"(%2) : (i64) -> ()
}
]

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

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

def pr4917_3_before := [llvm|
{
^0(%arg25 : i32, %arg26 : i32):
  %0 = llvm.mlir.constant(4294967295) : i64
  %1 = llvm.mlir.constant(111) : i64
  %2 = llvm.zext %arg25 : i32 to i64
  %3 = llvm.zext %arg26 : i32 to i64
  %4 = llvm.mul %2, %3 : i64
  %5 = llvm.icmp "ugt" %4, %0 : i64
  %6 = "llvm.select"(%5, %4, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%6) : (i64) -> ()
}
]

instance : Repr Eqn := inferInstanceAs (Repr (List Term))

def Predicate.Env (pcard : Nat) : Type :=
  Fin pcard → Prop

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

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

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

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 ult_swap_and_max_after := [llvm|
{
^0(%arg360 : i8, %arg361 : i8):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

def lor_land_right2_before := [llvm|
{
^0(%arg24 : i1, %arg25 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = "llvm.select"(%arg25, %0, %arg24) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = "llvm.select"(%arg24, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (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 icmp_mul_nsw_sgt_after := [llvm|
{
^0(%arg15 : i8, %arg16 : i8):
  %0 = llvm.icmp "sgt" %arg15, %arg16 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

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

def or_xor_tree_0010_after := [llvm|
{
^0(%arg39 : i32, %arg40 : i32, %arg41 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mul %arg39, %0 : i32
  %2 = llvm.mul %arg40, %0 : i32
  %3 = llvm.mul %arg41, %0 : i32
  %4 = llvm.xor %1, %2 : i32
  %5 = llvm.or %4, %3 : i32
  "llvm.return"(%5) : (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 icmp_eq_x_invertable_y2_todo_after := [llvm|
{
^0(%arg3 : i8, %arg4 : i1, %arg5 : i8):
  %0 = llvm.mlir.constant(-8 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = "llvm.select"(%arg4, %0, %arg5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %3 = llvm.and %arg3, %2 : i8
  %4 = llvm.icmp "eq" %3, %1 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

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 add_and_or_commutative_after := [llvm|
{
^0(%arg13 : i32, %arg14 : i32):
  %0 = llvm.add %arg13, %arg14 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

@[match_pattern] abbrev unary  (w : Nat) (op : MOp.UnaryOp 0) : LLVM.Op :=
  MOp.unary (.concrete w) op

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

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

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

def ne_3210_before := [llvm|
{
^0(%arg74 : i32, %arg75 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.mlir.constant(24 : i32) : i32
  %3 = llvm.trunc %arg74 : i32 to i8
  %4 = llvm.lshr %arg74, %0 : i32
  %5 = llvm.trunc %4 : i32 to i8
  %6 = llvm.lshr %arg74, %1 : i32
  %7 = llvm.trunc %6 : i32 to i8
  %8 = llvm.lshr %arg74, %2 : i32
  %9 = llvm.trunc %8 : i32 to i8
  %10 = llvm.trunc %arg75 : i32 to i8
  %11 = llvm.lshr %arg75, %0 : i32
  %12 = llvm.trunc %11 : i32 to i8
  %13 = llvm.lshr %arg75, %1 : i32
  %14 = llvm.trunc %13 : i32 to i8
  %15 = llvm.lshr %arg75, %2 : i32
  %16 = llvm.trunc %15 : i32 to i8
  %17 = llvm.icmp "ne" %3, %10 : i8
  %18 = llvm.icmp "ne" %5, %12 : i8
  %19 = llvm.icmp "ne" %7, %14 : i8
  %20 = llvm.icmp "ne" %9, %16 : i8
  %21 = llvm.or %17, %18 : i1
  %22 = llvm.or %19, %21 : i1
  %23 = llvm.or %20, %22 : i1
  "llvm.return"(%23) : (i1) -> ()
}
]

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

MonadLift in Init.Prelude

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

class HydrableSolve (parsedExpr : Type) (genPred : outParam Type) (genExpr : outParam (Nat → Type)) extends
  HydrableInstances genPred,
  HydrableGetGenPredSize genPred,
  HydrableGenPredToExpr parsedExpr genPred where

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

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

def debugCheck (e : Expr) : SolverM Unit := do
    if ← check?
    then
      check e
    else return ()

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

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

def test2_before := [llvm|
{
^0(%arg11 : i47):
  %0 = llvm.mlir.constant(-70368744177664 : i47) : i47
  %1 = llvm.xor %arg11, %0 : i47
  %2 = llvm.add %1, %0 : i47
  "llvm.return"(%2) : (i47) -> ()
}
]

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

def andn_or_cmp_2_before := [llvm|
{
^0(%arg170 : i16, %arg171 : i16, %arg172 : i16):
  %0 = llvm.mlir.constant(42 : i16) : i16
  %1 = llvm.icmp "sge" %arg170, %arg171 : i16
  %2 = llvm.icmp "slt" %arg170, %arg171 : i16
  %3 = llvm.icmp "ugt" %arg172, %0 : i16
  %4 = llvm.or %3, %1 : i1
  %5 = llvm.and %4, %2 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

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

def llvm_const_lower_riscv_li24 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM24, rhs:= liRiscv24,
   correct := by admit /- proof elided -/

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

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

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

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

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

def rhs : Com Simple (Ctxt.ofList [.int]) .pure [.int] :=
  [simple_com| {
    ^bb0(%x : i32):
      "return" (%x) : (i32) -> ()
  }]

def set_to_set_decomposebittest_after := [llvm|
{
^0(%arg11 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.and %arg11, %0 : i8
  %3 = llvm.or disjoint %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

@[simp_denote]
def sub_0xffffffffff_llvm_i64 := [LV| {
    ^entry (%x: i64):
    %0 = llvm.mlir.constant (1099511627775) : i64
    %1 = llvm.sub %x, %0 : i64
    llvm.return %1 : i64
  }]

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

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

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

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

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

def test5_apint_after := [llvm|
{
^0(%arg40 : i71, %arg41 : i71):
  %0 = llvm.and %arg40, %arg41 : i71
  "llvm.return"(%0) : (i71) -> ()
}
]

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

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

def squared_nsw_sgt0_before := [llvm|
{
^0(%arg178 : i5):
  %0 = llvm.mlir.constant(0 : i5) : i5
  %1 = llvm.mul %arg178, %arg178 overflow<nsw> : i5
  %2 = llvm.icmp "sgt" %1, %0 : i5
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

def testi32i8_after := [llvm|
{
^0(%arg32 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(7 : i8) : i8
  %2 = llvm.mlir.constant(15 : i32) : i32
  %3 = llvm.mlir.constant(127 : i8) : i8
  %4 = llvm.lshr %arg32, %0 : i32
  %5 = llvm.trunc %4 : i32 to i8
  %6 = llvm.trunc %arg32 : i32 to i8
  %7 = llvm.ashr %6, %1 : i8
  %8 = llvm.icmp "eq" %7, %5 : i8
  %9 = llvm.lshr %arg32, %2 : i32
  %10 = llvm.trunc %9 : i32 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 xor_signbit_shl_before := [llvm|
{
^0(%arg19 : i32):
  %0 = llvm.mlir.constant(-65536 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.xor %arg19, %0 : i32
  %3 = llvm.shl %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

@[simp_denote]
def or_llvm_disjoint_64 := [LV| {
  ^entry (%x: i64, %y: i64 ):
    %1 = llvm.or disjoint %x, %y : i64
    llvm.return %1 : i64
  }]

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

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

def t10_almost_highest_bit_after := [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 nneg %5 : i32 to i64
  %7 = llvm.lshr %arg23, %6 : i64
  %8 = llvm.trunc %7 : i64 to i32
  %9 = llvm.and %4, %8 : i32
  %10 = llvm.icmp "ne" %9, %2 : i32
  "llvm.return"(%10) : (i1) -> ()
}
]

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

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

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

class DialectPrint (d : Dialect) where
   
  printOpName : d.Op → String
   
  printAttributes : d.Op → String

   
  printTy : d.Ty → String

   
  dialectName : String
  

   
  printReturn : List d.Ty → String
   
  printFunc : List d.Ty → String := fun _ => "^entry"

@[simp_denote]
def srli_demandedbits_llvm_i32 := [LV| {
    ^entry (%a: i32):
    %0 = llvm.mlir.constant (3) : i32
    %1 = llvm.lshr %a, %0 : i32
    %2 = llvm.mlir.constant (1) : i32
    %3 = llvm.or %1, %2 : i32
    llvm.return %3 : 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 or_and_not_constant_commute3_after := [llvm|
{
^0(%arg106 : i32, %arg107 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.and %arg106, %0 : i32
  %2 = llvm.or %1, %arg107 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def t8_lshr_exact_flag_preservation_after := [llvm|
{
^0(%arg27 : i32, %arg28 : i32):
  %0 = llvm.mlir.constant(30 : i32) : i32
  %1 = llvm.lshr exact %arg27, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

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

def llvm_const_lower_riscv_li38 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM38, rhs:= liRiscv38,
   correct := by admit /- proof elided -/

instance : Inhabited (
  {lets : Lets d Γstart .pure Γ} →
  State d lets →
  (com: Com d Γ .pure α) →
  { com' : Com d Γ .pure α // ∀ (V: Ctxt.Valuation Γ), com.denote V = com'.denote V }) where
  default := fun _s com => ⟨com, by admit /- proof elided -/
  ⟩

def zext_sext_add_icmp_slt_0_after := [llvm|
{
^0(%arg74 : i1, %arg75 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg74, %0 : i1
  %2 = llvm.and %arg75, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

instance : DecidableEq BlockLabel :=

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

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

def and_logic_and_logic_or_8_before := [llvm|
{
^0(%arg117 : i1, %arg118 : i1, %arg119 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.and %arg118, %arg117 : i1
  %3 = "llvm.select"(%arg119, %arg117, %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 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 icmp_eq_mul_nsw_nonequal_commuted_after := [llvm|
{
^0(%arg30 : i8, %arg31 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "eq" %arg31, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def Term.Ctx.Env.empty
  {wcard : Nat} (wenv : WidthExpr.Env wcard) (ctx : Term.Ctx wcard 0) :
  Term.Ctx.Env ctx wenv :=
  fun v => v.elim0

def lshr_lshr_pow2_const_negative_overflow_before := [llvm|
{
^0(%arg61 : i16):
  %0 = llvm.mlir.constant(-32768 : i16) : i16
  %1 = llvm.mlir.constant(15 : i16) : i16
  %2 = llvm.mlir.constant(4 : i16) : i16
  %3 = llvm.lshr %0, %arg61 : i16
  %4 = llvm.lshr %3, %1 : i16
  %5 = llvm.and %4, %2 : i16
  "llvm.return"(%5) : (i16) -> ()
}
]

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

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

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

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

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

def select_icmp_eq_and_32_0_xor_8_after := [llvm|
{
^0(%arg237 : i32, %arg238 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.lshr %arg237, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.xor %arg238, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def buggy_ISEL_pattern : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs:= original_sdiv_srem
  rhs:= combined_sdiv_srem
  correct := by admit /- proof elided -/

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

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

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

@[simp_denote]
def and_llvm_i64 := [LV| {
    ^entry (%a: i64, %b: i64):
    %0 = llvm.and %a, %b : i64
    llvm.return %0 : i64
  }]

def or_min_31_30_before := [llvm|
{
^0(%arg3 : i8):
  %0 = llvm.mlir.constant(-30 : i8) : i8
  %1 = llvm.mlir.constant(31 : i8) : i8
  %2 = llvm.icmp "ult" %arg3, %0 : i8
  %3 = "llvm.select"(%2, %arg3, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = llvm.or %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

Lean.Meta.Simp.Step in Lean.Meta.Tactic.Simp.Types

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

Array.isEmpty in Init.Data.Array.Basic

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

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

Iff in Init.Core

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

def State.add? (e : Expr) : GenM Expr := do
  match ← get? e with
  | some x => pure x
  | none =>
    if e.isFVar || e.isBVar then pure e else
    let x ← mkFreshExprMVar (some (.const ``Nat [])) (userName := `w)
    setMapping e x
    modify fun s => { s with invMapping := s.invMapping.insert x e }
    pure x

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 RawCNFA.createSink (m : RawCNFA A) : State × RawCNFA A :=
  let (s, m) := m.newState
  let m := m.addInitial s
  let m := FinEnum.toList (α := A).foldl (init := m) fun m a =>
    m.addTrans a s s
  (s, m)

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

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

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

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

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

def Expr.mk {Γ} {ty}
    (varName : VarName)
    (op : Op) (ty_eq : ty = (signature op).returnType)
    (args : VarList Γ (signature op).arguments)
    (regions : RegionList Op (signature op).regions) :
    Expr Op Γ ty :=
  ⟨⟨varName, op, args.val, regions.val⟩, by admit /- proof elided -/
  ⟩

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

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

def rewritePeepholeRecursively (fuel : ℕ)
    (pr : PeepholeRewrite d Γ t) (target : Com d Γ₂ eff t₂) :
    { out : Com d Γ₂ eff t₂ // out.denote = target.denote } :=
  match fuel with
  | 0 => ⟨target, rfl⟩
  | fuel + 1 =>
    let target' := rewritePeephole fuel pr target
    have htarget'_denote_eq_htarget : target'.denote = target.denote := by admit /- proof elided -/

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

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

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

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

def 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 sdiv_icmp5_before := [llvm|
{
^0(%arg10 : i64):
  %0 = llvm.mlir.constant(-5) : i64
  %1 = llvm.mlir.constant(1) : i64
  %2 = llvm.sdiv exact %arg10, %0 : i64
  %3 = llvm.icmp "eq" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

def test_lshr_exact__exact_is_safe_after := [llvm|
{
^0(%arg62 : i32, %arg63 : i64):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(15 : i32) : i32
  %2 = llvm.lshr %arg62, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.zext nneg %3 : i32 to i64
  %5 = llvm.ashr %arg63, %4 : i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

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

instance : DecidableEq SLLVM.Ty :=

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

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

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

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

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

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

def t7_before := [llvm|
{
^0(%arg197 : i8, %arg198 : i1, %arg199 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.shl %0, %arg199 : i8
  %3 = "llvm.select"(%arg198, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = llvm.sub %arg197, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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 ofFin (i : Fin Γ.length) : Γ.Var (Γ[i]) :=
  ⟨i.val, by admit /- proof elided -/
  ⟩

def arithShiftRight (op1 : GenBVExpr w) (op2: GenBVExpr w) : GenBVExpr w :=
  GenBVExpr.arithShiftRight op1 op2

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

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

@[simp_denote]
def add_b31_riscv_i64 :=
  [LV| {
    ^entry (%x: i64):
    %random = li (574385585755) : !i64
    %0 = "lui" (%random) {imm = 524288 : !i64} : (!i64) -> (!i64)
    %a0 = "builtin.unrealized_conversion_cast" (%x) : (i64) -> (!i64)
    %1 = sub %a0, %0 : !i64
    %2 = "builtin.unrealized_conversion_cast" (%1) : (!i64) -> (i64)
    llvm.return %2 : i64
  }]

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

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 zext_nneg_flag_drop_after := [llvm|
{
^0(%arg7 : i8, %arg8 : i16):
  %0 = llvm.mlir.constant(128 : i16) : i16
  %1 = llvm.zext %arg7 : i8 to i16
  %2 = llvm.or %arg8, %1 : i16
  %3 = llvm.or %2, %0 : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

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

def select_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 lshr_and_add_fail_before := [llvm|
{
^0(%arg94 : i8, %arg95 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(123 : i8) : i8
  %2 = llvm.lshr %arg94, %0 : i8
  %3 = llvm.lshr %arg95, %0 : i8
  %4 = llvm.and %3, %1 : i8
  %5 = llvm.add %2, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

def PR39793_bswap_u64_as_u16_trunc_after := [llvm|
{
^0(%arg27 : i64):
  %0 = llvm.mlir.constant(8) : i64
  %1 = llvm.lshr %arg27, %0 : i64
  %2 = llvm.trunc %1 : i64 to i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

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

def HVector.denote :
    {l : RegionSignature d.Ty} → (T : HVector (fun t => Com d t.1 .impure t.2) l) →
    HVector (fun t => t.1.Valuation → EffectKind.impure.toMonad d.m (HVector toType t.2)) l
  | _, .nil => HVector.nil
  | _, .cons v vs => HVector.cons (v.denote) (HVector.denote vs)

def head : Stream α → Option α := Stream'.head

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

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

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

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

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

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

def bool_zext_after := [llvm|
{
^0(%arg172 : i1):
  %0 = llvm.zext %arg172 : i1 to i16
  "llvm.return"(%0) : (i16) -> ()
}
]

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

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

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

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

Lean.Level in Lean.Level
</all_available_defs>

<all_available_lemmas>
Option.bind_eq_some_iff in Init.Data.Option.Lemmas
AList.entries_insert_of_notMem in Mathlib.Data.List.AList
AList.lookup_eq_none in Mathlib.Data.List.AList
List.subset_cons_of_subset in Init.Data.List.Sublist
Option.mem_def in Init.Data.Option.Instances
IsEmpty.forall_iff in Mathlib.Logic.IsEmpty
forall_eq' in Init.PropLemmas
iff_true in Init.SimpLemmas
implies_true in Init.SimpLemmas

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

theorem logic_or_logic_and_4_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 1), x_2 = 1#1 → ¬x = 1#1 → ¬True → x_2 = 1#1

theorem urem_i8_proof : urem_i8_before ⊑ urem_i8_after

theorem icmp_ne_mul_nsw_nonequal_proof : icmp_ne_mul_nsw_nonequal_before ⊑ icmp_ne_mul_nsw_nonequal_after

theorem shift_no_xor_multiuse_cmp_with_xor_thm (e e_1 e_2 e_3 : IntW 32) :
  mul (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 1)) (const? 32 0)) e_2 (LLVM.xor e_2 (const? 32 2)))
      (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 1)) (const? 32 0)) e_1 e) ⊑
    mul (LLVM.xor e_2 (shl (LLVM.and e_3 (const? 32 1)) (const? 32 1) { «nsw» := true, «nuw» := true }))
      (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 1)) (const? 32 0)) e_1 e)

theorem test1_proof : test1_before ⊑ test1_after

theorem n11_proof : n11_before ⊑ n11_after

theorem p0_proof : p0_before ⊑ p0_after

theorem e_334 :
     - 3 *  ~~~(x &&&  ~~~y) + 1 * x + 3 *  ~~~(x &&&  ~~~x) + 1 *  ~~~(x &&& y) + 5 * (x |||  ~~~y) + 1 *  ~~~(x |||  ~~~y) - 10 * (x &&&  ~~~y) - 4 * (x &&& y) = 2 * y + 6 *  ~~~(x ||| y)

theorem icmp_select_implied_cond_ne_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x == 0#8) = 1#1 → ofBool (x != 0#8) = 1#1 → False

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

theorem trunc_lshr_sext_exact_proof : trunc_lshr_sext_exact_before ⊑ trunc_lshr_sext_exact_after

theorem t3_no_extrause_proof : t3_no_extrause_before ⊑ t3_no_extrause_after

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

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

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

theorem slt_or_not_max_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.slt e_1 e) (const? 1 1) (icmp IntPred.ne e_1 (const? 8 127)) ⊑
    icmp IntPred.ne e_1 (const? 8 127)

theorem test31_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ofBool (truncate 32 x &&& 42#32 == 10#32) = ofBool (x &&& 42#64 == 10#64)

theorem ashrslt_03_11_exact_proof : ashrslt_03_11_exact_before ⊑ ashrslt_03_11_exact_after

theorem div_bit_set_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(x_1 ≥ ↑32 ∨ (x == 0 || 32 != 1 && 1#32 <<< x_1 == intMin 32 && x == -1) = true) →
    True ∧ 1#32 <<< x_1 >>> x_1 ≠ 1#32 ∨
        x_1 ≥ ↑32 ∨ (x == 0 || 32 != 1 && 1#32 <<< x_1 == intMin 32 && x == -1) = true →
      False

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

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

theorem trunc_shl_33_i32_i64_thm (e : IntW 64) : trunc 32 (shl e (const? 64 33)) ⊑ const? 32 0

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

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

theorem splat_mul_known_lz_proof : splat_mul_known_lz_before ⊑ splat_mul_known_lz_after

@[simp]
theorem toBitVec_concat_zero (a : BitStream) :
    (a.concat b).toBitVec 0 = 0#0

theorem card_varsFinset_assignVars_lt [DecidableEq α] [DecidableEq β]
    (c : Circuit α) (f : ∀ (a : α) (_ha : a ∈ c.vars), β ⊕ Bool)
      (a : α) (ha : a ∈ c.vars) (b : Bool) (hfa : f a ha = Sum.inr b) :
      (c.assignVars f).varsFinset.card < c.varsFinset.card

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 canonicalize_logic_first_or0_nsw_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.saddOverflow 112#32 = true) → True ∧ (x ||| 15#32).saddOverflow 112#32 = true → False

theorem test9_proof : test9_before ⊑ test9_after

theorem e_2264 :
    2 * (e ^^^ f) + 2 * (e ^^^ (d ||| ( ~~~e &&& f))) - 11 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 1 * (f ^^^ (d &&&  ~~~e)) - 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 4 *  ~~~(e ^^^ f) + 7 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) - 7 * ( ~~~f &&& (d ^^^ e)) - 1 * (f ^^^ (d ||| ( ~~~e &&& f))) + 1 * (e ^^^ (d ||| (e ||| f))) - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 5 *  ~~~(d &&& ( ~~~e &&& f)) + 2 *  ~~~(d ^^^ f) + 1 *  ~~~(e &&& f) + 11 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 1 * (f &&& (d ^^^ e)) - 1 * (e |||  ~~~f) + 11 * (e ^^^  ~~~(d &&& (e ||| f))) + 1 * (e ^^^  ~~~(d &&&  ~~~f)) - 2 * (f &&& (d ||| e)) + 2 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 5 * ( ~~~e &&&  ~~~(d ^^^ f)) + 1 * (e ^^^ (d ||| (e ^^^ f))) - 6 * (e &&& (d ||| f)) - 11 * ( ~~~e &&& (d ^^^ f)) + 2 * (e &&& (d |||  ~~~f)) - 2 * f - 1 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 1 *  ~~~(d ^^^ ( ~~~e ||| f)) + 2 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 4 * ((d ^^^ e) &&& (d ^^^ f)) + 11 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 5 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 1 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * (e ^^^  ~~~(d &&& f)) - 7 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 6 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 *  ~~~(d &&& f) - 11 * (e |||  ~~~(d |||  ~~~f)) - 11 * (e |||  ~~~(d ^^^ f)) - 2 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 3 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 7 *  ~~~( ~~~d ||| (e &&& f)) + 11 * (f |||  ~~~(d ^^^ e)) - 11 * (e |||  ~~~(d ||| f)) + 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 11 * ( ~~~d &&& (e ||| f)) - 5 * (e ||| (d ^^^ f)) + 2 * (e ^^^ (d ||| f)) - 11 *  ~~~(d ||| (e ||| f)) + 23 *  ~~~(d ||| ( ~~~e ||| f)) + 8 *  ~~~( ~~~d ||| (e ||| f)) + 1 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 8 * ( ~~~d &&& ( ~~~e &&& f)) + 9 * ( ~~~d &&& (e &&& f)) - 23 * (d &&& ( ~~~e &&& f)) + 24 * (d &&& (e &&& f)) = 1 * (e ^^^  ~~~(d |||  ~~~f)) - 4 *  ~~~(d ||| f)

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

theorem main7d_proof : main7d_before ⊑ main7d_after

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

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

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

theorem add_select_not_zext_thm.extracted_1._1 : ∀ (x : BitVec 1),
  x = 1#1 → 64#64 + zeroExtend 64 (x ^^^ 1#1) = 64#64

theorem different_size_sext_sext_ule_proof : different_size_sext_sext_ule_before ⊑ different_size_sext_sext_ule_after

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

theorem test_and_ne_a_b_commuted_proof : test_and_ne_a_b_commuted_before ⊑ test_and_ne_a_b_commuted_after

theorem or_test2_proof : or_test2_before ⊑ or_test2_after

theorem ne_commuted_equal_minus_1_proof : ne_commuted_equal_minus_1_before ⊑ ne_commuted_equal_minus_1_after

theorem main5c_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 → ¬True → 0#32 = zeroExtend 32 (ofBool (x &&& 7#32 == 7#32))

theorem test_proof : test_before ⊑ test_after

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

theorem e_2252 :
    2 * ( ~~~e ||| (d ^^^ f)) + 2 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 3 * (e ^^^  ~~~(d &&& f)) - 1 * (e |||  ~~~(d ||| f)) + 1 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 6 *  ~~~e + 5 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 6 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 6 * (d ^^^ ( ~~~e ||| f)) + 7 * (e |||  ~~~(d ^^^ f)) - 5 * (f &&& (d ||| e)) - 3 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 5 *  ~~~(d &&& (e ||| f)) + 7 * ( ~~~e &&& (d ^^^ f)) + 2 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 11 * (e ^^^  ~~~(d &&&  ~~~f)) + 4 *  ~~~(e &&& f) + 7 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 2 * (e ^^^ (d &&& (e ^^^ f))) + 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 2 * ((d ^^^ e) &&& (d ^^^ f)) - 1 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 2 * ( ~~~d ||| (e ^^^ f)) + 2 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 11 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * (f ^^^ (d &&& ( ~~~e ||| f))) - 3 * (f ||| (d &&&  ~~~e)) - 1 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 2 * ( ~~~d ||| (e ||| f)) + 7 * (d &&& f) + 3 * (e &&& (d ||| f)) - 2 * (e ^^^ (d ||| (e ^^^ f))) + 4 * (f ^^^  ~~~(d &&&  ~~~e)) - 1 *  ~~~(e ||| f) + 11 * (f ^^^ (d &&&  ~~~e)) - 3 *  ~~~(d |||  ~~~f) + 1 * (d &&& (e ||| f)) + 1 * ((d &&& e) |||  ~~~(e ^^^ f)) + 2 * (f &&&  ~~~(d &&&  ~~~e)) - 5 *  ~~~(d &&& ( ~~~e ||| f)) + 11 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 2 * ( ~~~f &&& (d ^^^ e)) - 7 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 11 * (e ^^^  ~~~(d ||| f)) - 1 *  ~~~( ~~~d ||| (e &&& f)) + 7 * (e ^^^ (d |||  ~~~f)) + 1 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 3 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 2 *  ~~~(d ||| e) - 34 *  ~~~(d ||| (e ||| f)) - 11 *  ~~~(d ||| ( ~~~e ||| f)) - 30 *  ~~~( ~~~d ||| (e ||| f)) - 54 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 61 * ( ~~~d &&& ( ~~~e &&& f)) - 13 * ( ~~~d &&& (e &&& f)) - 47 * (d &&& ( ~~~e &&& f)) - 29 * (d &&& (e &&& f)) =  - 2 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f))

theorem ashr_ugt_8_proof : ashr_ugt_8_before ⊑ ashr_ugt_8_after

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

theorem or_not_xor_common_op_commute3_proof : or_not_xor_common_op_commute3_before ⊑ or_not_xor_common_op_commute3_after

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

theorem f_t15_t01_t09_thm.extracted_1._1 : ∀ (x : BitVec 40),
  ¬(31#40 ≥ ↑40 ∨ 16#32 ≥ ↑32) →
    15#40 ≥ ↑40 ∨ True ∧ signExtend 40 (truncate 32 (x.sshiftRight' 15#40)) ≠ x.sshiftRight' 15#40 → False

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

theorem icmp_select_implied_cond_swapped_select_proof : icmp_select_implied_cond_swapped_select_before ⊑ icmp_select_implied_cond_swapped_select_after

theorem demorgan_and_zext_proof : demorgan_and_zext_before ⊑ demorgan_and_zext_after

theorem src2_proof : src2_before ⊑ src2_after

theorem fold_add_udiv_urem_without_noundef_proof : fold_add_udiv_urem_without_noundef_before ⊑ fold_add_udiv_urem_without_noundef_after

theorem icmp_eq_sext_eq_zero_proof : icmp_eq_sext_eq_zero_before ⊑ icmp_eq_sext_eq_zero_after

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

theorem udiv_i1_is_op0_proof : udiv_i1_is_op0_before ⊑ udiv_i1_is_op0_after

theorem smear_set_bit_different_dest_type_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬7#8 ≥ ↑8 →
    ¬(24#32 ≥ ↑32 ∨
          31#32 ≥ ↑32 ∨
            True ∧ signExtend 32 (truncate 16 ((x <<< 24#32).sshiftRight' 31#32)) ≠ (x <<< 24#32).sshiftRight' 31#32) →
      signExtend 16 ((truncate 8 x).sshiftRight' 7#8) = truncate 16 ((x <<< 24#32).sshiftRight' 31#32)

theorem e_2119 :
    2 * (e ^^^ (d &&& f)) - 2 *  ~~~( ~~~d &&& (e ||| f)) + 1 * (f ^^^  ~~~(d &&& (e ||| f))) + 1 * (e ^^^ f) + 7 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 1 * (e ^^^  ~~~(d &&&  ~~~f)) + 11 * ( ~~~f &&& (d ^^^ e)) - 11 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 7 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 11 * (e ^^^ ( ~~~d ||| (e ^^^ f))) + 5 * (d ||| ( ~~~e &&& f)) + 1 * ( ~~~d ||| ( ~~~e ||| f)) - 2 * (f ^^^ (d ||| ( ~~~e ||| f))) + 11 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 3 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 1 * (f &&&  ~~~(d &&&  ~~~e)) - 3 * (f ^^^  ~~~(d ||| (e &&& f))) + 1 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 4 * ( ~~~e |||  ~~~(d ^^^ f)) - 1 *  ~~~(d ||| ( ~~~e &&& f)) - 2 * (e ^^^ ( ~~~d &&& (e ||| f))) + 2 *  ~~~(d &&&  ~~~f) + 4 * (e |||  ~~~(d |||  ~~~f)) + 1 * (f &&&  ~~~(d &&& e)) - 2 * (f ||| (d ^^^ e)) - 5 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * d - 1 * (f ^^^  ~~~(d ||| e)) - 2 * (d ||| e) - 1 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 3 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 2 *  ~~~(d &&& f) - 1 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) - 7 * (f ^^^ (d &&& e)) - 1 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 4 *  ~~~( ~~~d &&& (e ^^^ f)) + 1 * (e ^^^ (d |||  ~~~f)) + 8 *  ~~~(d ||| (e ||| f)) - 28 *  ~~~(d ||| ( ~~~e ||| f)) + 1 *  ~~~( ~~~d ||| (e ||| f)) + 4 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 8 * ( ~~~d &&& ( ~~~e &&& f)) + 19 * ( ~~~d &&& (e &&& f)) + 20 * (d &&& ( ~~~e &&& f)) =  - 3 * (d ^^^ (e ^^^ f))

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

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 select_icmp_ne_0_and_1073741824_or_8_thm (e : IntW 8) (e_1 : IntW 32) :
  select (icmp IntPred.ne (const? 32 0) (LLVM.and e_1 (const? 32 1073741824))) e (LLVM.or e (const? 8 8)) ⊑
    select (icmp IntPred.eq (LLVM.and e_1 (const? 32 1073741824)) (const? 32 0)) (LLVM.or e (const? 8 8))
      e

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

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 scalar_i32_lshr_and_negC_eq_X_is_constant1_proof : scalar_i32_lshr_and_negC_eq_X_is_constant1_before ⊑ scalar_i32_lshr_and_negC_eq_X_is_constant1_after

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

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

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

theorem main7a_logical_thm.extracted_1._8 : ∀ (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 (ofBool (x &&& x_1 != x))

@[simp]
theorem eval_castCircLe_eq {n m : Nat} (c : Circuit (Vars fsm.α arity n))
    (hnm : n ≤ m)
    {env : Vars fsm.α arity m → Bool} :
    (castCircLe c hnm).eval env = c.eval
      (fun x => env (x.castLe hnm))

theorem exact_lshr_ne_proof : exact_lshr_ne_before ⊑ exact_lshr_ne_after

theorem test_slt_xor_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 ^^^ -1#32 ^^^ x <ₛ x_1 ^^^ -1#32) = ofBool (x_1 <ₛ x ^^^ x_1)

theorem test_sge_xor_thm (e e_1 : IntW 32) :
  icmp IntPred.sge (LLVM.xor (LLVM.xor e_1 (const? 32 (-1))) e) (LLVM.xor e_1 (const? 32 (-1))) ⊑
    icmp IntPred.sle (LLVM.xor e e_1) e_1

theorem masked_icmps_mask_notallzeros_bmask_mixed_4_proof : masked_icmps_mask_notallzeros_bmask_mixed_4_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_4_after

theorem sext_sext_ne_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (signExtend 32 x_1 != signExtend 32 x) = ofBool (x_1 != x)

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

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

theorem gt_signed_to_large_signed_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (1024#32 <ₛ signExtend 32 x) = 0#1

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

theorem add_or_sub_comb_i8_negative_y_or_proof : add_or_sub_comb_i8_negative_y_or_before ⊑ add_or_sub_comb_i8_negative_y_or_after

theorem srem_i1_is_zero_thm (e e_1 : IntW 1) : LLVM.srem e_1 e ⊑ const? 1 0

theorem not_or_xor_thm.extracted_1._1 : ∀ (x : BitVec 8),
  (x ^^^ -1#8 ||| 7#8) ^^^ 12#8 = x &&& BitVec.ofInt 8 (-8) ^^^ BitVec.ofInt 8 (-13)

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3b_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3b_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3b_logical_after

theorem xor_signbit_select_shl_proof : xor_signbit_select_shl_before ⊑ xor_signbit_select_shl_after

theorem n1_proof : n1_before ⊑ n1_after

theorem and_sext_to_sel_proof : and_sext_to_sel_before ⊑ and_sext_to_sel_after

theorem shl_lshr_eq_amt_multi_use_proof : shl_lshr_eq_amt_multi_use_before ⊑ shl_lshr_eq_amt_multi_use_after

theorem C0zero_thm.extracted_1._6 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 + 10#8 <ᵤ 0#8) = 1#1 → ¬ofBool (x_1 <ₛ BitVec.ofInt 8 (-10)) = 1#1 → x_1 = x

theorem e_1398 :
    7 *  ~~~z - 1 *  ~~~(z &&&  ~~~t) + 2 *  ~~~(z &&& t) + 7 *  ~~~(z &&&  ~~~z) + 3 *  ~~~(z ^^^ t) - 2 * z - 18 *  ~~~(z ||| t) - 21 *  ~~~(z |||  ~~~t) - 13 * (z &&&  ~~~t) - 10 * (z &&& t) =  - 3 * (z ||| t) - 3 * (z ^^^ t)

theorem xor_of_icmps_proof : xor_of_icmps_before ⊑ xor_of_icmps_after

theorem test3_proof : test3_before ⊑ test3_after

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

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

theorem from_poly_zero : R.fromPoly (0 : (ZMod q)[X]) (n := n) = (0 : R q n)

theorem fold_ne_rhs_fail_shift_not_1s_thm (e e_1 : IntW 8) :
  icmp IntPred.ne (LLVM.and (LLVM.xor e_1 (const? 8 123)) (shl (const? 8 (-2)) e)) (const? 8 0) ⊑
    icmp IntPred.ne (LLVM.and (LLVM.xor e_1 (const? 8 122)) (shl (const? 8 (-2)) e)) (const? 8 0)

theorem mul_splat_fold_thm (e : IntW 32) :
  lshr (mul e (const? 32 65537) { «nsw» := false, «nuw» := true }) (const? 32 16) ⊑ e

lemma CNFA.autUnsignedCmp_spec {cmp} : (CNFA.autUnsignedCmp cmp).Sim (NFA'.autUnsignedCmp cmp)

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 modulo4_thm (e : IntW 32) :
  add (select (icmp IntPred.slt (LLVM.srem e (const? 32 4)) (const? 32 0)) (const? 32 4) (const? 32 0))
      (LLVM.srem e (const? 32 4)) { «nsw» := true, «nuw» := false } ⊑
    LLVM.and e (const? 32 3)

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

theorem icmp_ne_and_z_and_onefail_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x != 0#8) &&& ofBool (x != 1#8) &&& ofBool (x != 2#8) = ofBool (2#8 <ᵤ x)

theorem uadd_sat_flipped_wrong_bounds4_proof : uadd_sat_flipped_wrong_bounds4_before ⊑ uadd_sat_flipped_wrong_bounds4_after

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

@[simp]
theorem Term.toBV_ofBool {wenv : WidthExpr.Env wcard}
    {tctx : Term.Ctx wcard tcard}
    (benv : Term.BoolEnv bcard)
    (tenv : tctx.Env wenv) (b : Term bcard ncard icard pcard tctx .bool) :
  Term.toBV benv nenv ienv penv tenv (.bvOfBool b) = BitVec.ofBool (b.toBV benv nenv ienv penv tenv)

theorem uaddo_wrong_pred2_proof : uaddo_wrong_pred2_before ⊑ uaddo_wrong_pred2_after

theorem PR42691_8_logical_proof : PR42691_8_logical_before ⊑ PR42691_8_logical_after

theorem src_is_notmask_lshr_shl_proof : src_is_notmask_lshr_shl_before ⊑ src_is_notmask_lshr_shl_after

theorem test3_proof : test3_before ⊑ test3_after

@[simp]
lemma Fin.castSucc_neq_last (x : Fin n) : x.castSucc ≠ Fin.last n

theorem zext_sext_add_icmp_eq_1_proof : zext_sext_add_icmp_eq_1_before ⊑ zext_sext_add_icmp_eq_1_after

theorem e_344 :
     - 11 * (x ^^^ y) - 2 *  ~~~x - 2 * (x ||| y) - 3 * (x |||  ~~~y) + 2 *  ~~~(x ||| y) + 12 *  ~~~(x |||  ~~~y) + 16 * (x &&&  ~~~y) + 2 * (x &&& y) =  - 3 *  ~~~(x &&&  ~~~y)

theorem test82_proof : test82_before ⊑ test82_after

theorem icmp_slt_0_or_icmp_sgt_0_i64_fail3_proof : icmp_slt_0_or_icmp_sgt_0_i64_fail3_before ⊑ icmp_slt_0_or_icmp_sgt_0_i64_fail3_after

theorem 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 e_250 :
    5 * (x ^^^ y) - 1 *  ~~~(x &&&  ~~~x) - 11 * (x |||  ~~~y) + 8 *  ~~~(x ||| y) - 8 *  ~~~(x |||  ~~~y) + 3 * (x &&&  ~~~y) + 12 * (x &&& y) =  - 4 *  ~~~(x &&& y)

theorem or_nontrivial_mask2_proof : or_nontrivial_mask2_before ⊑ or_nontrivial_mask2_after

theorem e_973 :
     - 2 *  ~~~(z &&&  ~~~t) + 2 *  ~~~(z &&&  ~~~z) + 2 *  ~~~t + 7 * t - 13 *  ~~~(z ||| t) - 7 *  ~~~(z |||  ~~~t) - 18 * (z &&& t) = 15 * (z &&&  ~~~t) - 11 * (z |||  ~~~t)

theorem merge_left_shift (hu : u >= r) (hts : t > s) (htq : t > q) :
  (bw r (shlMax (bw u (shlMax (bw p a) (bw q b))) (bw s c)))  =
  (bw r (shlMax (bw p a) (bw t (addMax (bw q b) (bw s c)))))

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

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

theorem test_mul_nsw__nsw_is_safe_proof : test_mul_nsw__nsw_is_safe_before ⊑ test_mul_nsw__nsw_is_safe_after

theorem ashr_ult_8_proof : ashr_ult_8_before ⊑ ashr_ult_8_after

theorem ashr_exact_eq_0_proof : ashr_exact_eq_0_before ⊑ ashr_exact_eq_0_after

theorem fold_inverted_icmp_preds_reverse_thm.extracted_1._4 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ofBool (x_3 <ₛ x_2) = 1#1 → ofBool (x_2 ≤ₛ x_3) = 1#1 → 0#32 ||

theorem test1_proof : test1_before ⊑ test1_after

private lemma BitVec.sle_iff_slt_or_eq {w : ℕ} (bv1 bv2 : BitVec w):
    (bv1.sle bv2) = true ↔ (bv1.slt bv2) = true ∨ bv1 = bv2

theorem ule_swap_or_not_min_commute_logical_proof : ule_swap_or_not_min_commute_logical_before ⊑ ule_swap_or_not_min_commute_logical_after

theorem sub_select_sext_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → x - signExtend 64 x_1 = x

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

@[simp]
theorem toBitVec_xor (a b : BitStream) :
    (a ^^^ b).toBitVec w = a.toBitVec w ^^^ b.toBitVec w

theorem scalar_i32_signbit_lshr_and_eq_proof : scalar_i32_signbit_lshr_and_eq_before ⊑ scalar_i32_signbit_lshr_and_eq_after

theorem lshr_mul_times_5_div_4_proof : lshr_mul_times_5_div_4_before ⊑ lshr_mul_times_5_div_4_after

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

theorem zext_nneg_signbit_extract_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.msb = true ∨ 31#64 ≥ ↑64) → zeroExtend 64 x >>> 31#64 = 0#64

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 shl_or_lshr_comm_thm (e e_1 e_2 : IntW 32) :
  lshr (LLVM.or e_2 (shl e_1 e { «nsw» := false, «nuw» := true })) e ⊑ LLVM.or (lshr e_2 e) e_1

theorem test_mul__nuw_is_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 268435457#32 == 268435456#32) = 1#1 →
    ¬(True ∧ (x &&& 268435457#32).umulOverflow 9#32 = true) →
      BitVec.ofInt 32 (-1879048192) = (x &&& 268435457#32) * 9#32

theorem xor_logic_and_logic_or1_proof : xor_logic_and_logic_or1_before ⊑ xor_logic_and_logic_or1_after

theorem test52_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬(True ∧ (truncate 16 x &&& 7224#16 &&& BitVec.ofInt 16 (-32574) != 0) = true) →
    zeroExtend 32 ((truncate 16 x ||| BitVec.ofInt 16 (-32574)) &&& BitVec.ofInt 16 (-25350)) =
      zeroExtend 32 (truncate 16 x &&& 7224#16 ||| BitVec.ofInt 16 (-32574))

theorem extractslice_insertslice [Inhabited α]
  (t: Tensor1d α)
  (sliceix: Nat)
  (slice: Tensor1d α)
  (CORRECT: ((t.insertslice sliceix slice).extract sliceix slice.size).size ≠ 0)
  : (t.insertslice sliceix slice).extract sliceix slice.size = slice

theorem exact_ashr_eq_noexactdiv_proof : exact_ashr_eq_noexactdiv_before ⊑ exact_ashr_eq_noexactdiv_after

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

theorem different_size_zext_zext_eq_proof : different_size_zext_zext_eq_before ⊑ different_size_zext_zext_eq_after

theorem udiv_icmp2_proof : udiv_icmp2_before ⊑ udiv_icmp2_after

theorem shl_and_proof : shl_and_before ⊑ shl_and_after

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

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

theorem and_sequence_15_eq (w : Nat) :
    and_sequence_15_lhs w  ⊑ and_sequence_15_rhs w

theorem test6_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬3#32 ≥ ↑32 →
    3#32 ≥ ↑32 ∨
        True ∧ (x >>> 3#32).smulOverflow 3#32 = true ∨
          True ∧ (x >>> 3#32).umulOverflow 3#32 = true ∨ True ∧ (x >>> 3#32 * 3#32).msb = true →
      False

lemma carry_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))
    (x : new_arity → BitStream) : ∀ (n : ℕ),
    (p.compose new_arity q_arity vars q).carry x n =
      let z := p.carry (λ a => (q a).eval (fun i => x (vars _ i))) n
      Sum.elim z (fun a => (q a.1).carry (fun t => x (vars _ t)) n a.2)

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

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

theorem test10_logical_proof : test10_logical_before ⊑ test10_logical_after

theorem negative_not_power_of_two_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (-1#32 <ₛ x) = 1#1 → ofBool (x + 255#32 <ᵤ 256#32) = ofBool (x == 0#32)

theorem or_signbit_select_shl_proof : or_signbit_select_shl_before ⊑ or_signbit_select_shl_after

theorem test_shl__nuw_is_safe_thm.extracted_1._4 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 1073741822#32 == 0#32) = 1#1 →
    ¬(2#32 ≥ ↑32 ∨ zeroExtend 64 ((x_1 &&& 1073741822#32) <<< 2#32) ≥ ↑64) →
      ¬(2#32 ≥ ↑32 ∨
            True ∧ (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)).msb = true ∨
              zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)) ≥ ↑64) →
        x.sshiftRight' (zeroExtend 64 ((x_1 &&& 1073741822#32) <<< 2#32)) =
          x.sshiftRight' (zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-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 e_1769 :
     - 1 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 5 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) + 2 * (c ||| (a &&&  ~~~b)) - 2 * (c ^^^  ~~~(a ||| (b &&& c))) - 11 * ( ~~~a ||| ( ~~~b &&& c)) - 6 * (a &&& b) + 1 * (b &&& (a ^^^ c)) + 1 * (c ^^^ (a ||| (b &&& c))) - 1 * (c ^^^ (a &&& (b ||| c))) + 1 * (a &&&  ~~~b) + 5 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) + 11 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) + 3 *  ~~~b + 11 * (b ^^^ ( ~~~a ||| (b ||| c))) - 11 * (a &&& (b ||| c)) - 11 * ( ~~~c |||  ~~~(a ^^^ b)) - 1 * (b |||  ~~~(a |||  ~~~c)) - 1 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) + 4 * (b ^^^ (a ||| ( ~~~b &&& c))) + 2 *  ~~~(a ^^^ (b ||| c)) + 2 * ( ~~~c ||| (a ^^^ b)) + 7 *  ~~~(b ||| c) + 5 * (b |||  ~~~(a ||| c)) + 7 * ( ~~~(a ||| b) ||| (b ^^^ c)) - 5 *  ~~~(a ||| c) - 11 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) - 3 *  ~~~(a ||| (b &&& c)) - 6 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) - 1 * (c ^^^ (a ||| ( ~~~b &&& c))) + 14 *  ~~~(a ||| (b ||| c)) + 11 *  ~~~(a ||| ( ~~~b ||| c)) - 6 *  ~~~( ~~~a ||| (b ||| c)) + 19 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 5 * ( ~~~a &&& ( ~~~b &&& c)) + 14 * ( ~~~a &&& (b &&& c)) + 9 * (a &&& ( ~~~b &&& c)) =  - 6 * (a &&& (b &&& c))

theorem reused_mul_nuw_xy_z_selectnonzero_ugt_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 8),
  ofBool (x_2 != 0#8) = 1#1 →
    ¬(True ∧ x_1.umulOverflow x_2 = true ∨ True ∧ x.umulOverflow x_2 = true) →
      ofBool (x_2 == 0#8) = 1#1 → ofBool (x * x_2 <ᵤ x_1 * x_2) = 1#1

theorem e_182 :
    4 *  ~~~(x ^^^ y) - 11 *  ~~~y - 1 *  ~~~(x ||| y) - 8 *  ~~~(x |||  ~~~y) + 4 * (x &&&  ~~~y) - 11 * (x &&& y) =  - 1 *  ~~~x - 7 *  ~~~(x &&&  ~~~x)

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

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

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

theorem nonexact_lshr_ne_noexactdiv_proof : nonexact_lshr_ne_noexactdiv_before ⊑ nonexact_lshr_ne_noexactdiv_after

theorem tryFactorization_xor_lshr_ashr_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬(x ≥ ↑32 ∨ x ≥ ↑32) → x ≥ ↑32 → False

theorem t0_scalar_proof : t0_scalar_before ⊑ t0_scalar_after

theorem addhshlhsdivhscalar0_proof : addhshlhsdivhscalar0_before ⊑ addhshlhsdivhscalar0_after

theorem icmp_eq_zext_eq_non_boolean_proof : icmp_eq_zext_eq_non_boolean_before ⊑ icmp_eq_zext_eq_non_boolean_after

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

theorem band_lor_right1_proof : band_lor_right1_before ⊑ band_lor_right1_after

theorem slt_and_not_max_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 <ₛ x) = 1#1 → ofBool (x_1 != 127#8) = ofBool (x_1 <ₛ x)

theorem lshr_exact_ne_0_proof : lshr_exact_ne_0_before ⊑ lshr_exact_ne_0_after

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

theorem sext_zext_apint2_thm (e : IntW 11) : sext 47 (zext 39 e) ⊑ zext 47 e

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

theorem test68_proof : test68_before ⊑ test68_after

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

theorem reassoc_mul_nuw_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ x.umulOverflow 4#32 = true ∨ True ∧ (x * 4#32).umulOverflow 65#32 = true) →
    ¬(True ∧ x.umulOverflow 260#32 = true) → x * 4#32 * 65#32 = x * 260#32

theorem ashrsgt_02_10_exact_proof : ashrsgt_02_10_exact_before ⊑ ashrsgt_02_10_exact_after

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

theorem zext_ult_zext_thm (e : IntW 1) (e_1 : IntW 8) :
  icmp IntPred.ult (zext 16 (mul e_1 e_1)) (zext 16 e) ⊑
    LLVM.and (icmp IntPred.eq (mul e_1 e_1) (const? 8 0)) e

theorem e_2250 :
    11 * (f ^^^ (d &&& ( ~~~e ||| f))) - 2 * ( ~~~e ||| (d ^^^ f)) - 6 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 3 * (f &&& (d |||  ~~~e)) - 11 * (e ^^^ (d |||  ~~~f)) - 2 * (e |||  ~~~(d ||| f)) + 2 * (f ^^^ (d &&& e)) - 1 * (f ^^^ (d ||| ( ~~~e ||| f))) - 5 * ( ~~~d &&& ( ~~~e ||| f)) - 5 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 7 * (d ^^^ ( ~~~e &&& f)) + 1 *  ~~~(e ||| f) + 3 * (e &&&  ~~~(d &&& f)) + 1 *  ~~~(d &&&  ~~~d) - 2 * (d ^^^ f) + 1 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 7 *  ~~~(d &&& (e &&& f)) + 7 * (e ^^^ (d ||| (e ||| f))) + 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 1 *  ~~~(d |||  ~~~f) - 6 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 1 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) - 1 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 7 *  ~~~(d &&& e) + 3 * (f &&&  ~~~(d &&& e)) - 5 * (f ^^^ (d ||| ( ~~~e &&& f))) - 2 * (e &&& (d ||| f)) + 1 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 6 * (e |||  ~~~(d ^^^ f)) + 5 * (d &&& (e ^^^ f)) + 3 * (e ^^^ (d ||| ( ~~~e &&& f))) - 1 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 5 * (f ^^^ (d |||  ~~~e)) + 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 5 *  ~~~(d &&& (e ||| f)) + 2 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 6 * (d ^^^ (e &&& f)) - 1 * ( ~~~e &&& (d ^^^ f)) + 1 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 *  ~~~(d ^^^ ( ~~~e &&& f)) - 1 * ((d ||| e) &&& (e ^^^ f)) - 3 * (f ^^^  ~~~(d &&& (e &&& f))) - 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 1 * (f &&& (d ||| e)) - 5 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 1 *  ~~~(d ^^^ e) + 2 *  ~~~(e |||  ~~~f) + 7 * e - 1 *  ~~~(d ||| f) - 3 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 37 *  ~~~(d ||| (e ||| f)) + 10 *  ~~~(d ||| ( ~~~e ||| f)) + 19 *  ~~~( ~~~d ||| (e ||| f)) + 33 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 2 * ( ~~~d &&& ( ~~~e &&& f)) + 20 * ( ~~~d &&& (e &&& f)) + 10 * (d &&& ( ~~~e &&& f)) =  - 28 * (d &&& (e &&& f))

theorem Expr.eff_le {Γ : Ctxt d.Ty} {ty} (e : Expr d Γ eff ty) :
  DialectSignature.effectKind e.op ≤ eff

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

theorem e_164 :
    7 *  ~~~x - 2 *  ~~~(x &&& y) + 1 * y - 6 *  ~~~(x |||  ~~~y) - 3 * (x &&&  ~~~y) - 1 * (x &&& y) =  - 5 *  ~~~y + 10 *  ~~~(x ||| y)

theorem trunc_lshr_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬2#8 ≥ ↑8 → ¬2#6 ≥ ↑6 → truncate 6 (x >>> 2#8) &&& 14#6 = truncate 6 x >>> 2#6 &&& 14#6

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_3b_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 15#32 == 0#32) = 1#1 →
    ofBool (x &&& 3#32 != 0#32) = ofBool (x &&& 15#32 == 0#32) ||

theorem substitute_constant_and_eq_eq_logical_proof : substitute_constant_and_eq_eq_logical_before ⊑ substitute_constant_and_eq_eq_logical_after

theorem select_icmp_eq_and_1_0_xor_2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 &&& 1#32 == 0#32) = 1#1 → ¬1#32 ≥ ↑32 → x = x ^^^ x_1 <<< 1#32 &&& 2#32

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

theorem uaddo_wrong_pred2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x ^^^ -1#32 ≤ᵤ x_1) = 1#1 → ¬ofBool (x_1 <ᵤ x ^^^ -1#32) = 1#1 → False

theorem main7b_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 test12_proof : test12_before ⊑ test12_after

theorem e_1223 :
    1 * (z ||| t) + 5 *  ~~~z - 1 * (z |||  ~~~t) + 2 * z + 11 *  ~~~t - 1 *  ~~~(z &&& t) - 14 *  ~~~(z ||| t) - 5 *  ~~~(z |||  ~~~t) - 2 * (z &&& t) = 12 * (z &&&  ~~~t)

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

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

theorem fold_add_udiv_urem_commuted_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(10#32 = 0 ∨ 10#32 = 0 ∨ 4#32 ≥ ↑32) →
    ¬(10#32 = 0 ∨ True ∧ (x / 10#32).umulOverflow 6#32 = true) →
      x % 10#32 + (x / 10#32) <<< 4#32 = x / 10#32 * 6#32 + x

theorem icmp_ne_sext_slt_allones_nofold_proof : icmp_ne_sext_slt_allones_nofold_before ⊑ icmp_ne_sext_slt_allones_nofold_after

theorem e_768 :
     - 7 *  ~~~(z &&&  ~~~t) + 5 * z + 7 *  ~~~(z ||| t) + 7 * (z &&& t) =  - 12 *  ~~~(z |||  ~~~t) + 5 * (z ||| t)

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

theorem test25_proof : test25_before ⊑ test25_after

theorem bool_add_lshr_proof : bool_add_lshr_before ⊑ bool_add_lshr_after

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

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

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

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

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

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

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

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

theorem gt_signed_to_small_signed_proof : gt_signed_to_small_signed_before ⊑ gt_signed_to_small_signed_after

theorem splat_mul_unknown_lz_proof : splat_mul_unknown_lz_before ⊑ splat_mul_unknown_lz_after

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 ashr_ult_7_proof : ashr_ult_7_before ⊑ ashr_ult_7_after

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

theorem t2_thm (e : IntW 1) (e_1 : IntW 8) (e_2 : IntW 1) :
  LLVM.xor (add (sext 8 e_2) e_1) (sext 8 e) ⊑ LLVM.xor (add e_1 (sext 8 e_2)) (sext 8 e)

theorem icmp_mul_nsw_sge_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ x_1.smulOverflow 7#8 = true ∨ True ∧ x.smulOverflow 7#8 = true) →
    ofBool (x * 7#8 ≤ₛ x_1 * 7#8) = ofBool (x ≤ₛ x_1)

theorem t0_thm.extracted_1._3 : ∀ (x x_1 x_2 x_3 : BitVec 8) (x_4 : BitVec 1),
  (x_4 ^^^ 1#1) &&& ofBool (x_3 == x_2) = 1#1 → ofBool (x_3 != x_2) ||

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

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

theorem n5_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x_1 &&& 1#8 == 2#8) = 1#1 → False

theorem negation_of_increment_via_or_with_no_common_bits_set_proof : negation_of_increment_via_or_with_no_common_bits_set_before ⊑ negation_of_increment_via_or_with_no_common_bits_set_after

theorem scalar_i64_shl_and_negC_eq_thm (e e_1 : IntW 64) :
  icmp IntPred.eq (LLVM.and (shl e_1 e) (const? 64 (-8589934592))) (const? 64 0) ⊑
    icmp IntPred.ult (shl e_1 e) (const? 64 8589934592)

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

theorem ashr_sge_exact_proof : ashr_sge_exact_before ⊑ ashr_sge_exact_after

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

theorem t0_sub_from_trueval_thm (e : IntW 8) (e_1 : IntW 1) (e_2 : IntW 8) :
  sub e_2 (select e_1 e_2 e) ⊑ select e_1 (const? 8 0) (sub e_2 e)

theorem trunc_nsw_xor_proof : trunc_nsw_xor_before ⊑ trunc_nsw_xor_after

@[simp]
theorem eval_shiftLeft (k : Nat) (env : Unit → BitStream) (i : Nat) :
    (shiftLeft k).eval env i = ((decide (k ≤ i)) && ((env ()) (i - k)))

theorem n14_trunc_of_lshr_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32) (x_2 : BitVec 64),
  ¬(zeroExtend 64 (32#32 - x_1) ≥ ↑64 ∨ x_1 + -1#32 ≥ ↑32) →
    x_1 + -1#32 ≥ ↑32 ∨ True ∧ (32#32 - x_1).msb = true ∨ zeroExtend 64 (32#32 - x_1) ≥ ↑64 → False

theorem test_eq_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 1073741823#32 == 0#32) = 1#1 → 2#32 ≥ ↑32 → False

@[bv_multi_width_normalize] theorem BitVec.zero_mul (x : BitVec w) : 0#w * x = 0#w

theorem cmp_x_and_negp2_with_eq_proof : cmp_x_and_negp2_with_eq_before ⊑ cmp_x_and_negp2_with_eq_after

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

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

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

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

theorem negate_add_with_single_negatible_operand_depth2_proof : negate_add_with_single_negatible_operand_depth2_before ⊑ negate_add_with_single_negatible_operand_depth2_after

theorem test_negative_combined_sub_unsigned_overflow_proof : test_negative_combined_sub_unsigned_overflow_before ⊑ test_negative_combined_sub_unsigned_overflow_after

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

theorem src_is_mask_const_sgt_thm (e : IntW 8) :
  icmp IntPred.sgt (LLVM.xor e (const? 8 123)) (LLVM.and (LLVM.xor e (const? 8 123)) (const? 8 7)) ⊑
    icmp IntPred.sgt (LLVM.xor e (const? 8 123)) (const? 8 7)

theorem negate_add_with_single_negatible_operand_proof : negate_add_with_single_negatible_operand_before ⊑ negate_add_with_single_negatible_operand_after

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

theorem or_test2_thm (e : IntW 7) : LLVM.or (shl e (const? 7 6)) (const? 7 (-64)) ⊑ const? 7 (-64)

theorem and_zext_proof : and_zext_before ⊑ and_zext_after

theorem e_649 :
     - 7 *  ~~~x + 1 * (x ^^^ y) + 1 *  ~~~(x &&&  ~~~y) + 3 *  ~~~(x ^^^ y) + 5 *  ~~~y + 7 * (x |||  ~~~y) - 8 *  ~~~(x ||| y) + 6 *  ~~~(x |||  ~~~y) - 12 * (x &&&  ~~~y) - 10 * (x &&& y) = 1 *  ~~~(x &&&  ~~~x)

theorem t1_otherbitwidth_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(15#16 ≥ ↑16 ∨ 15#16 ≥ ↑16) → True ∧ (0#16).ssubOverflow (x &&& 1#16) = true → False

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

theorem e_897 :
     - 1 *  ~~~z + 2 *  ~~~(z &&& t) + 1 *  ~~~(z &&&  ~~~t) + 7 * t - 2 * (z &&&  ~~~t) - 8 * (z &&& t) = 2 *  ~~~(z ||| t) + 9 *  ~~~(z |||  ~~~t)

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

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

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

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

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

theorem e_1833 :
    1 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 2 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) - 3 * ( ~~~b |||  ~~~(a ^^^ c)) - 5 *  ~~~( ~~~a ||| (b &&& c)) + 2 * (b ||| (a ^^^ c)) + 4 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) - 2 * ( ~~~c &&& (a ^^^ b)) + 1 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) - 2 * c - 1 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) + 11 * (a &&& c) - 2 * ((a |||  ~~~b) &&& (b ^^^ c)) + 1 * (c ||| (a &&& b)) - 5 * (c ^^^  ~~~(a ||| b)) + 11 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) + 3 * (b ^^^ ( ~~~a ||| (b ^^^ c))) - 2 * (b ^^^ (a ||| (b &&& c))) + 4 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) - 2 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) + 7 * (b ^^^ (a &&& c)) + 2 * ( ~~~(a &&& b) &&& (b ^^^ c)) - 7 * ( ~~~a &&& ( ~~~b ||| c)) - 5 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) + 4 * (c ^^^ (a ||| ( ~~~b &&& c))) - 2 *  ~~~(a ^^^ c) - 6 * (c ^^^ (a ||| ( ~~~b ||| c))) - 1 *  ~~~(a ||| b) + 11 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 11 * (b ^^^  ~~~(a &&&  ~~~c)) + 5 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 1 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) + 7 * (b ^^^  ~~~(a |||  ~~~c)) + 7 * (b ^^^  ~~~(a ||| c)) - 6 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) - 6 *  ~~~(b |||  ~~~c) + 5 * (c ^^^  ~~~(a |||  ~~~b)) - 16 *  ~~~(a ||| (b ||| c)) + 3 *  ~~~( ~~~a ||| (b ||| c)) - 46 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 30 * ( ~~~a &&& ( ~~~b &&& c)) + 3 * ( ~~~a &&& (b &&& c)) - 36 * (a &&& ( ~~~b &&& c)) - 24 * (a &&& (b &&& c)) = 2 * (c &&& (a |||  ~~~b)) + 25 *  ~~~(a ||| ( ~~~b ||| c))

theorem lshrult_02_03_exact_thm (e : IntW 4) :
  icmp IntPred.ult (lshr e (const? 4 2) { «exact» := true }) (const? 4 3) ⊑
    icmp IntPred.ne e (const? 4 (-4))

theorem one_side_fold_slt_proof : one_side_fold_slt_before ⊑ one_side_fold_slt_after

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

theorem t3_singlebit_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(32#32 - x ≥ ↑32 ∨ zeroExtend 64 (x + BitVec.ofInt 32 (-16)) ≥ ↑64) →
    ofBool (x_1 <<< (32#32 - x) &&& truncate 32 (65536#64 >>> zeroExtend 64 (x + BitVec.ofInt 32 (-16))) != 0#32) =
      ofBool (x_1 &&& 1#32 != 0#32)

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

theorem 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 e_1796 :
     - 11 * (b ^^^  ~~~(a ||| (b &&& c))) + 5 *  ~~~(a &&& (b ||| c)) - 7 * (c ^^^ ( ~~~a ||| (b ||| c))) + 3 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) - 2 * (b ^^^ ( ~~~a ||| (b &&& c))) - 2 *  ~~~( ~~~a &&& (b &&& c)) + 11 *  ~~~(a &&& c) - 1 * (b &&&  ~~~(a ^^^ c)) - 11 * (b ^^^ (a |||  ~~~c)) - 7 * (b ||| (a ^^^ c)) - 2 * (c ^^^ (a &&&  ~~~b)) + 3 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) + 2 * (c ^^^  ~~~(a |||  ~~~b)) - 5 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) - 11 * (c &&& (a ||| b)) - 11 * (b &&&  ~~~c) - 7 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 11 * (b ^^^ ( ~~~a ||| (b ^^^ c))) - 2 * ((a ||| b) &&& (b ^^^ c)) - 6 *  ~~~b - 6 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) + 3 *  ~~~( ~~~a ||| (b ^^^ c)) + 2 * ( ~~~(a ||| b) |||  ~~~(b ^^^ c)) - 11 * ((a ^^^ b) |||  ~~~(a ^^^ c)) + 7 *  ~~~(a &&& (b &&& c)) + 7 * (c ^^^ (a ||| (b &&& c))) + 5 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 5 *  ~~~(a &&& b) - 2 * (b ^^^ (a ||| (b ^^^ c))) - 1 * (b &&&  ~~~(a &&& c)) - 2 * (c ^^^  ~~~(a &&& (b &&& c))) + 26 *  ~~~(a ||| (b ||| c)) + 30 *  ~~~(a ||| ( ~~~b ||| c)) + 16 *  ~~~( ~~~a ||| (b ||| c)) + 31 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 13 * ( ~~~a &&& ( ~~~b &&& c)) + 42 * ( ~~~a &&& (b &&& c)) + 38 * (a &&& ( ~~~b &&& c)) + 27 * (a &&& (b &&& c)) = 1 *  ~~~(a &&&  ~~~b)

theorem test_eq_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 positive_biggerashr_shlnuwnsw_thm (e : IntW 8) :
  shl (ashr e (const? 8 6)) (const? 8 3) { «nsw» := true, «nuw» := true } ⊑
    LLVM.and (ashr e (const? 8 3)) (const? 8 (-8))

theorem and_shl_proof : and_shl_before ⊑ and_shl_after

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

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

theorem test6_thm (e : IntW 64) :
  trunc 32 (lshr (zext 128 e) (const? 128 32)) ⊑
    trunc 32 (lshr e (const? 64 32)) { «nsw» := false, «nuw» := true }

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

@[simp]
theorem EnvFin.apply_getLsb_eq (env : EnvFin (w + 1) n) (i : Fin n) : env.getLsb i =
  BitVec.ofBool (env i)[0]

theorem a_true_implies_b_false2_thm.extracted_1._5 : ∀ (x x_1 : BitVec 1) (x_2 : BitVec 8),
  ofBool (x_2 == 10#8) = 1#1 → ofBool (20#8 <ᵤ x_2) = 1#1 → ofBool (20#8 <ᵤ x_2) &&& x_1 = x

theorem sgt_smax4_proof : sgt_smax4_before ⊑ sgt_smax4_after

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

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

theorem bools2_logical_commute1_and1_thm.extracted_1._7 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 &&& x_1 = 1#1 → x_1 ^^^ 1#1 = 1#1 → x_1 = 1#1 → x = x_2

theorem bitwise_and_bitwise_and_icmps_comm2_thm (e e_1 e_2 : IntW 8) :
  LLVM.and
      (LLVM.and (icmp IntPred.ne (LLVM.and e_2 (const? 8 1)) (const? 8 0))
        (icmp IntPred.eq e_1 (const? 8 42)))
      (icmp IntPred.ne (LLVM.and e_2 (shl (const? 8 1) e)) (const? 8 0)) ⊑
    LLVM.and
      (icmp IntPred.eq (LLVM.and e_2 (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)))
      (icmp IntPred.eq e_1 (const? 8 42))

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1b_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1b_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1b_logical_after

theorem ashrslt_02_07_proof : ashrslt_02_07_before ⊑ ashrslt_02_07_after

theorem reassoc_x2_mul_nuw_proof : reassoc_x2_mul_nuw_before ⊑ reassoc_x2_mul_nuw_after

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

theorem main5e_like_proof : main5e_like_before ⊑ main5e_like_after

theorem bitwise_and_logical_and_masked_icmp_allzeros_poison1_thm.extracted_1._5 : ∀ (x : BitVec 1)
  (x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 &&& x_1 == 0#32) = 1#1 →
    ofBool (x_2 &&& (x_1 ||| 7#32) == 0#32) = 1#1 → 0#1 &&& ofBool (x_2 &&& 7#32 == 0#32) = x

theorem xor_nosignbit_ashr_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬8#32 ≥ ↑32 → (x ^^^ 2147418112#32).sshiftRight' 8#32 = x.sshiftRight' 8#32 ^^^ 8388352#32

theorem n2_thm (e e_1 : IntW 8) :
  icmp IntPred.ne (LLVM.and (LLVM.xor (shl (const? 8 (-1)) e_1) (const? 8 1)) e) e ⊑
    icmp IntPred.ne
      (LLVM.and e (LLVM.xor (shl (const? 8 (-1)) e_1 { «nsw» := true, «nuw» := false }) (const? 8 (-2))))
      (const? 8 0)

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

theorem e_1915 :
     - 2 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) - 2 *  ~~~(a &&& (b ^^^ c)) + 4 * (a ^^^ ( ~~~b ||| c)) + 3 *  ~~~(b &&& c) + 1 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) - 5 * (a ||| (b ||| c)) + 2 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) - 1 *  ~~~a - 7 *  ~~~(a ^^^ b) + 4 * (b ^^^ (a ||| ( ~~~b ||| c))) - 6 * (b ^^^ ( ~~~a &&& (b ^^^ c))) - 1 * (a ||| b) - 1 * ( ~~~(a &&& b) &&& (b ^^^ c)) - 3 * (c ^^^ ( ~~~a &&& (b ||| c))) - 1 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) - 5 * (c ^^^  ~~~(a &&& ( ~~~b ||| c))) + 4 *  ~~~( ~~~a &&& ( ~~~b ||| c)) - 6 * a - 1 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 5 * (b |||  ~~~c) + 2 * (c ||| (a &&& b)) - 1 *  ~~~(a ^^^ c) - 11 * (a &&& c) - 2 * (c ^^^ ( ~~~a &&& ( ~~~b ||| c))) - 1 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) - 6 * (b &&& (a |||  ~~~c)) - 3 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) - 7 *  ~~~(a ||| ( ~~~b &&& c)) + 11 *  ~~~(a |||  ~~~c) + 4 * (b &&&  ~~~(a ^^^ c)) + 1 * (c |||  ~~~(a |||  ~~~b)) - 1 *  ~~~( ~~~a &&& (b ^^^ c)) + 1 * (c &&& (a |||  ~~~b)) - 3 * (a |||  ~~~c) - 1 * (c &&&  ~~~(a ^^^ b)) + 11 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) + 2 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 1 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) + 4 * ( ~~~c &&&  ~~~(a ^^^ b)) + 2 *  ~~~(a &&& (b &&& c)) + 7 * (c ^^^ ( ~~~a ||| (b ||| c))) - 5 * (c ^^^ (a ||| (b &&& c))) - 7 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) - 11 * ( ~~~b ||| (a ^^^ c)) + 18 *  ~~~(a ||| (b ||| c)) + 23 *  ~~~( ~~~a ||| (b ||| c)) + 27 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 3 * ( ~~~a &&& ( ~~~b &&& c)) + 8 * ( ~~~a &&& (b &&& c)) + 39 * (a &&& (b &&& c)) =  - 35 * (a &&& ( ~~~b &&& c))

theorem e_1685 :
     - 1 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) + 3 * ( ~~~c ||| (a ^^^ b)) - 1 * ( ~~~b ||| (a ^^^ c)) + 3 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) - 1 *  ~~~( ~~~a ||| (b &&& c)) - 3 *  ~~~c - 1 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) - 2 * (c ^^^  ~~~(a |||  ~~~b)) + 5 *  ~~~( ~~~a &&& (b ^^^ c)) - 7 * (b ^^^ (a &&& (b ||| c))) + 2 * (a ||| c) - 1 *  ~~~( ~~~a &&& (b ||| c)) - 7 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) + 2 * (b ^^^  ~~~(a &&& (b &&& c))) - 2 * (c ^^^  ~~~(a &&& ( ~~~b ||| c))) + 2 * ((a &&& b) ^^^ (b |||  ~~~c)) - 5 *  ~~~(a &&&  ~~~a) - 11 * ( ~~~b &&&  ~~~(a ^^^ c)) + 4 *  ~~~(a &&&  ~~~b) + 1 * ( ~~~a ||| (b &&& c)) + 5 *  ~~~( ~~~a &&& ( ~~~b ||| c)) + 5 *  ~~~(a ||| (b ||| c)) + 3 *  ~~~(a ||| ( ~~~b ||| c)) + 5 * ( ~~~a &&& ( ~~~b &&& c)) - 3 * ( ~~~a &&& (b &&& c)) + 20 * (a &&& ( ~~~b &&& c)) - 12 * (a &&& (b &&& c)) = 2 * ((a |||  ~~~b) &&& (b ^^^ c)) - 2 *  ~~~( ~~~a ||| ( ~~~b ||| c))

theorem t2_ashr_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ¬signExtend 32 x ≥ ↑32 → True ∧ x.msb = true ∨ zeroExtend 32 x ≥ ↑32 → False

theorem or_trunc_lshr_small_mask_proof : or_trunc_lshr_small_mask_before ⊑ or_trunc_lshr_small_mask_after

theorem not_not_cmp_thm (e e_1 : IntW 32) :
  icmp IntPred.slt (LLVM.xor e_1 (const? 32 (-1))) (LLVM.xor e (const? 32 (-1))) ⊑
    icmp IntPred.sgt e_1 e

theorem shift_no_xor_multiuse_cmp_thm.extracted_1._8 : ∀ (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) →
      (x_2 ||| 2#32) * x = (x_2 ||| (x_3 &&& 1#32) <<< 1#32) * x

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

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

theorem sgt_smin4_thm (e e_1 : IntW 32) :
  icmp IntPred.slt (add e_1 (const? 32 3))
      (select (icmp IntPred.slt e (add e_1 (const? 32 3))) e (add e_1 (const? 32 3))) ⊑
    const? 1 0

theorem same_source_not_matching_signbits_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ ((-1#32) <<< (x &&& 8#32)).sshiftRight' (x &&& 8#32) ≠ -1#32 ∨ x &&& 8#32 ≥ ↑32) →
    x &&& 8#32 ≥ ↑32 ∨
        True ∧
            BitVec.ofInt 32 (-16777216) <<< (x &&& 8#32) >>> 24#32 <<< 24#32 ≠
              BitVec.ofInt 32 (-16777216) <<< (x &&& 8#32) ∨
          24#32 ≥ ↑32 →
      False

theorem test_sle_xor_thm (e e_1 : IntW 32) :
  icmp IntPred.sle (LLVM.xor (LLVM.xor e_1 (const? 32 (-1))) e) (LLVM.xor e_1 (const? 32 (-1))) ⊑
    icmp IntPred.sge (LLVM.xor e e_1) e_1

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

theorem e_2163 :
     - 5 * ((d ^^^ e) &&& (d ^^^ f)) + 3 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 1 * (e ^^^  ~~~(d |||  ~~~f)) + 5 * ( ~~~f &&&  ~~~(d ^^^ e)) + 1 * ((d &&& e) |||  ~~~(e ^^^ f)) - 7 * (e ^^^ f) - 1 * ((e &&& f) ||| (d &&& (e ||| f))) + 11 * (f ^^^  ~~~(d |||  ~~~e)) - 6 * (f ^^^ (d ||| (e &&& f))) + 2 * ( ~~~d ||| (e ^^^ f)) - 6 * ( ~~~e &&& (d ^^^ f)) + 7 * (e &&&  ~~~f) - 11 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 3 *  ~~~(d ||| (e ^^^ f)) + 11 * (d ^^^ (e &&& f)) + 3 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 2 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 1 * (e &&& (d |||  ~~~f)) + 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) + 1 * (e ^^^  ~~~(d ||| (e &&& f))) - 1 * ((d &&& e) |||  ~~~(e |||  ~~~f)) - 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 2 * (e ^^^ (d &&& f)) - 7 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 2 * ( ~~~d &&& (e ^^^ f)) + 1 * (e ^^^ ( ~~~d ||| (e &&& f))) + 7 *  ~~~(d ^^^ (e ^^^ f)) + 5 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 6 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 2 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 1 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) - 2 * ( ~~~e &&&  ~~~(d ^^^ f)) - 2 *  ~~~(d ^^^ (e ||| f)) + 5 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 1 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 1 * (f ^^^  ~~~(d &&& (e &&& f))) - 7 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 2 * (e |||  ~~~f) - 5 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 3 * (e |||  ~~~(d |||  ~~~f)) - 1 * (f &&&  ~~~(d ^^^ e)) - 5 *  ~~~(d ||| (e ||| f)) - 2 *  ~~~(d ||| ( ~~~e ||| f)) + 13 *  ~~~( ~~~d ||| (e ||| f)) - 12 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 9 * ( ~~~d &&& ( ~~~e &&& f)) + 2 * ( ~~~d &&& (e &&& f)) - 25 * (d &&& ( ~~~e &&& f)) + 4 * (d &&& (e &&& f)) =  - 7 *  ~~~( ~~~d &&& (e &&& f))

theorem test_sdiv_canonicalize_op0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (0#32).ssubOverflow x_1 = true ∨ (x == 0 || 32 != 1 && 0#32 - x_1 == intMin 32 && x == -1) = true) →
    (x == 0 || 32 != 1 && x_1 == intMin 32 && x == -1) = true ∨ True ∧ (0#32).ssubOverflow (x_1.sdiv x) = true →
      False

theorem factorize3_proof : factorize3_before ⊑ factorize3_after

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

theorem set_shl_mask_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬x ≥ ↑32 → (x_1 ||| 196609#32) <<< x &&& 65536#32 = (x_1 ||| 65537#32) <<< x &&& 65536#32

theorem neg_or_ashr_i32_proof : neg_or_ashr_i32_before ⊑ neg_or_ashr_i32_after

theorem ashrsgt_01_06_exact_proof : ashrsgt_01_06_exact_before ⊑ ashrsgt_01_06_exact_after

theorem not_bool_add_lshr_thm (e e_1 : IntW 2) :
  lshr (add (zext 4 e_1) (zext 4 e)) (const? 4 2) ⊑
    zext 4 (icmp IntPred.ugt e (LLVM.xor e_1 (const? 2 (-1))))

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

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

theorem test37_thm (e : IntW 32) :
  LLVM.and (mul (zext 64 e) (const? 64 7)) (const? 64 240) ⊑
    zext 64 (LLVM.and (mul e (const? 32 7)) (const? 32 240)) { «nneg» := true }

theorem e_729 :
    2 * (x ||| y) + 2 *  ~~~(x &&&  ~~~x) - 6 *  ~~~(x &&& y) + 1 *  ~~~(x &&&  ~~~y) + 1 * x + 7 * y - 1 *  ~~~y + 3 *  ~~~x + 1 *  ~~~(x ||| y) + 2 * (x &&&  ~~~y) - 13 * (x &&& y) = 9 *  ~~~(x |||  ~~~y)

theorem n6_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x_1 &&& 1#8 == 3#8) = 1#1 → False

theorem positive_samevar_shlnsw_thm.extracted_1._2 : ∀ (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) → x_1 >>> x <<< x = (-1#8) <<< x &&& x_1

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

theorem lshr_C1_add_A_C2_i32_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(x &&& 65535#32) + 5#32 ≥ ↑32 →
    ¬x &&& 65535#32 ≥ ↑32 → 6#32 <<< ((x &&& 65535#32) + 5#32) = 192#32 <<< (x &&& 65535#32)

theorem xor_icmp_true_unsigned_thm (e : IntW 32) :
  LLVM.xor (icmp IntPred.ugt e (const? 32 5)) (icmp IntPred.ult e (const? 32 6)) ⊑ const? 1 1

theorem srem_common_divisor_defined_cond_proof : srem_common_divisor_defined_cond_before ⊑ srem_common_divisor_defined_cond_after

theorem or_ranges_adjacent_proof : or_ranges_adjacent_before ⊑ or_ranges_adjacent_after

theorem zext_sext_add_icmp_sgt_minus2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  ofBool (BitVec.ofInt 8 (-2) <ₛ zeroExtend 8 x_1 + signExtend 8 x) = 1#1

theorem test_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.ugt e (const? 32 13)) (icmp IntPred.eq e (const? 32 15)) ⊑
    icmp IntPred.eq e (const? 32 15)

theorem and_sext_multiuse_thm.extracted_1._2 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ¬ofBool (x_2 <ₛ x_3) = 1#1 →
    (signExtend 32 (ofBool (x_2 <ₛ x_3)) &&& x_1) + (signExtend 32 (ofBool (x_2 <ₛ x_3)) &&& x) = 0#32

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

theorem fold_xor_zext_icmp_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 64),
  zeroExtend 8 (ofBool (x_1 <ₛ x_2)) ^^^ zeroExtend 8 (ofBool (x_2 <ₛ x)) =
    zeroExtend 8 (ofBool (x_1 <ₛ x_2) ^^^ ofBool (x_2 <ₛ x))

theorem test48_proof : test48_before ⊑ test48_after

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

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

theorem in_constant_varx_mone_invmask_proof : in_constant_varx_mone_invmask_before ⊑ in_constant_varx_mone_invmask_after

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

theorem a_or_b_const_proof : a_or_b_const_before ⊑ a_or_b_const_after

theorem t3_exact_thm (e : IntW 64) :
  sub (const? 64 0) (ashr e (const? 64 63) { «exact» := true }) ⊑ lshr e (const? 64 63) { «exact» := true }

theorem icmp_power2_and_icmp_shifted_mask_swapped_8_7_proof : icmp_power2_and_icmp_shifted_mask_swapped_8_7_before ⊑ icmp_power2_and_icmp_shifted_mask_swapped_8_7_after

theorem icmp_ne_zext_eq_zero_proof : icmp_ne_zext_eq_zero_before ⊑ icmp_ne_zext_eq_zero_after

theorem shl_trunc_smaller_lshr_thm (e : IntW 32) :
  shl (trunc 8 (lshr e (const? 32 3))) (const? 8 5) ⊑ LLVM.and (shl (trunc 8 e) (const? 8 2)) (const? 8 (-32))

theorem e_1940 :
     - 7 *  ~~~(a &&& (b &&& c)) - 11 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) + 1 * (c ^^^  ~~~(a &&& (b &&& c))) + 5 * (c ^^^  ~~~(a &&&  ~~~b)) - 3 * (b ^^^ ( ~~~a ||| (b &&& c))) - 1 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 2 * (c ^^^ (a &&&  ~~~b)) - 1 * (a ||| ( ~~~b &&& c)) - 2 * ( ~~~c |||  ~~~(a ^^^ b)) + 7 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) - 1 * (c &&&  ~~~(a &&& b)) + 11 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) - 1 *  ~~~(a ^^^ (b ^^^ c)) - 7 * (a &&& ( ~~~b ||| c)) - 5 * ((a &&& b) |||  ~~~(b ^^^ c)) - 1 * ((a |||  ~~~b) &&& (b ^^^ c)) - 7 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) + 1 * ((a ||| b) &&& (b ^^^ c)) - 2 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) - 1 * (a |||  ~~~b) + 1 * (a ^^^ ( ~~~b &&& c)) - 2 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) - 2 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 4 * (b |||  ~~~c) - 2 * (a ||| c) - 1 * ((a &&& b) ^^^  ~~~(a ^^^ (b &&& c))) - 2 * ((a &&& b) ||| (b ^^^ c)) - 7 *  ~~~( ~~~a ||| (b &&& c)) + 5 *  ~~~(a ||| c) - 6 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) - 11 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) + 1 *  ~~~(a ||| b) + 2 * (b ^^^  ~~~(a &&& (b &&& c))) + 2 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) - 6 *  ~~~( ~~~a &&& (b ||| c)) - 2 * ( ~~~a ||| (b &&& c)) + 2 * (b ^^^  ~~~(a ||| (b &&& c))) + 4 *  ~~~(a ^^^ ( ~~~b &&& c)) - 1 * (c ||| (a &&&  ~~~b)) - 2 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) + 3 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 5 * (b ^^^  ~~~(a ||| (b ^^^ c))) - 1 * (b ||| (a ^^^ c)) - 5 * (b ^^^ c) + 3 * (c ||| (a &&& b)) + 5 *  ~~~(a ||| (b ||| c)) + 16 *  ~~~(a ||| ( ~~~b ||| c)) + 32 *  ~~~( ~~~a ||| (b ||| c)) + 35 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 19 * ( ~~~a &&& ( ~~~b &&& c)) + 9 * ( ~~~a &&& (b &&& c)) + 36 * (a &&& ( ~~~b &&& c)) + 37 * (a &&& (b &&& c)) =  - 5 * (b &&& (a ||| c)) - 2 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c)))

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_2_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_2_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_2_logical_after

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

theorem test_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(17#32 ≥ ↑32 ∨ 17#32 ≥ ↑32) → ¬31#32 ≥ ↑32 → (x.sshiftRight' 17#32).sshiftRight' 17#32 = x.sshiftRight' 31#32

theorem bv_AddSub_1202 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.add (LLVM.xor e (LLVM.const? w (-1))) e_1 ⊑ LLVM.sub (LLVM.sub e_1 (LLVM.const? w 1)) e

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

theorem test44_proof : test44_before ⊑ test44_after

theorem e_1831 :
     - 11 *  ~~~( ~~~a ||| ( ~~~b &&& c)) - 2 *  ~~~(a ^^^ (b ^^^ c)) + 2 * (a ^^^ (b &&& c)) - 5 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 1 * ( ~~~a &&& (b ^^^ c)) - 11 * (a ||| (b ^^^ c)) + 1 * ( ~~~b |||  ~~~(a ^^^ c)) - 7 *  ~~~(a ^^^ c) + 2 * (b &&&  ~~~c) - 2 *  ~~~(a ^^^ ( ~~~b &&& c)) + 2 * (c ^^^ (a &&& ( ~~~b ||| c))) - 5 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) - 2 * (a &&& (b ||| c)) - 6 * (b &&&  ~~~(a ^^^ c)) + 5 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) + 2 * (b ^^^ ( ~~~a ||| (b &&& c))) + 1 * (c |||  ~~~(a |||  ~~~b)) + 1 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) + 4 * (c &&&  ~~~(a &&&  ~~~b)) - 3 * ((a ||| b) &&& (b ^^^ c)) - 1 * (c ||| (a &&& b)) + 11 * (a ^^^ (b ^^^ c)) + 7 * (a ^^^ b) - 1 * (a &&& (b ^^^ c)) - 3 *  ~~~(a ^^^ (b &&& c)) + 2 *  ~~~(a &&& b) + 3 * (b ^^^ (a ||| (b ^^^ c))) + 4 * ( ~~~a &&& ( ~~~b ||| c)) + 2 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) + 5 * b + 4 * (a ^^^ (b ||| c)) + 3 * ((a ||| b) &&&  ~~~(b ^^^ c)) - 7 * ((a &&& b) ^^^  ~~~(a ^^^ (b &&& c))) - 1 * ( ~~~b ||| (a ^^^ c)) + 1 * ( ~~~a ||| ( ~~~b ||| c)) + 20 *  ~~~(a ||| (b ||| c)) + 16 *  ~~~(a ||| ( ~~~b ||| c)) - 10 *  ~~~( ~~~a ||| (b ||| c)) + 26 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 17 * ( ~~~a &&& ( ~~~b &&& c)) - 33 * ( ~~~a &&& (b &&& c)) + 18 * (a &&& ( ~~~b &&& c)) + 15 * (a &&& (b &&& c)) = 1 * (b ^^^  ~~~(a ||| (b &&& c)))

theorem shl_and_and_fail_thm (e e_1 : IntW 8) :
  LLVM.and (shl e_1 (const? 8 4)) (LLVM.and (shl e (const? 8 5)) (const? 8 88)) ⊑
    LLVM.and (shl e_1 (const? 8 4)) (LLVM.and (shl e (const? 8 5)) (const? 8 64))

theorem xor_sub :
    [llvm(w)| {
  ^bb0(%X : _, %Y : _):
    %v1 = llvm.sub %X, %X
    %r = llvm.xor %v1, %Y
    llvm.return %r
  }] ⊑  [llvm(w)| {
  ^bb0(%X : _, %Y : _):
    llvm.return %Y
  }]

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

theorem ugt_swap_and_min_commute_logical_proof : ugt_swap_and_min_commute_logical_before ⊑ ugt_swap_and_min_commute_logical_after

theorem test1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  truncate 1 (zeroExtend 32 (ofBool (x_1 <ₛ x)) &&& zeroExtend 32 (ofBool (x <ₛ x_1))) = 0#1

theorem shl1_nsw_not_exact_proof : shl1_nsw_not_exact_before ⊑ shl1_nsw_not_exact_after

theorem test15_proof : test15_before ⊑ test15_after

theorem icmp_sle6_proof : icmp_sle6_before ⊑ icmp_sle6_after

@[simp] theorem lt_length (v : Γ.Var t) : v.1 < Γ.length

theorem land_lor_left1_proof : land_lor_left1_before ⊑ land_lor_left1_after

theorem test_ne_0_and_15_add_3_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x + 3#8 &&& 15#8 != 0#8) = ofBool (x &&& 15#8 != 13#8)

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

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

theorem a_true_implies_b_true_proof : a_true_implies_b_true_before ⊑ a_true_implies_b_true_after

theorem test2_proof : test2_before ⊑ test2_after

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

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

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

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

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

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

theorem test15_proof : test15_before ⊑ test15_after

theorem sub_ule_sext_proof : sub_ule_sext_before ⊑ sub_ule_sext_after

theorem fold_inverted_icmp_preds_proof : fold_inverted_icmp_preds_before ⊑ fold_inverted_icmp_preds_after

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

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

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

theorem main3c_proof : main3c_before ⊑ main3c_after

theorem icmp_ne_and_pow2_lshr_pow2_case2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → zeroExtend 32 (ofBool (4#32 >>> x &&& 8#32 == 0#32)) = 1#32

theorem xor_add_proof : xor_add_before ⊑ xor_add_after

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

theorem main4f_like_proof : main4f_like_before ⊑ main4f_like_after

theorem bv_AndOrXor_2453 :
    ∀ (e e_1 : LLVM.IntW w),
      LLVM.xor (LLVM.icmp LLVM.IntPred.slt e_1 e) (LLVM.const? 1 (-1)) ⊑ LLVM.icmp LLVM.IntPred.sge e_1 e

theorem alive_AddSub_1614  (w : Nat)   : alive_AddSub_1614_src w  ⊑ alive_AddSub_1614_tgt w

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

theorem sgt_swap_and_min_commute_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.eq e_1 (const? 8 (-128))) (icmp IntPred.slt e e_1) (const? 1 0) ⊑ const? 1 0

theorem t1_flags_nuw_nsw_second_proof : t1_flags_nuw_nsw_second_before ⊑ t1_flags_nuw_nsw_second_after

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

theorem udiv_shl_mul_nuw_proof : udiv_shl_mul_nuw_before ⊑ udiv_shl_mul_nuw_after

theorem test16_proof : test16_before ⊑ test16_after

theorem lshrugt_01_06_proof : lshrugt_01_06_before ⊑ lshrugt_01_06_after

theorem select_exact_lshr_icmp_const_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (31#32 <ᵤ x) = 1#1 → 5#32 ≥ ↑32 → False

@[simp] theorem Valuation.append_inj_right {V : Γ.Valuation} {W W' : Δ.Valuation} :
    (V ++ W) = (V ++ W') ↔ W = W'

theorem AvoidCollision_and_setWidth_allOnes (w' w : Nat) (b : BitVec (w' + w)) :
    b &&& (BitVec.allOnes w).setWidth (w' + w) = 0#w' ++ b.setWidth w

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

theorem e_2081 :
     - 11 * (d ^^^ ( ~~~e &&& f)) - 2 * (d |||  ~~~e) - 2 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 4 * ( ~~~d &&& ( ~~~e ||| f)) + 5 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 1 * (e ||| f) - 7 * (f ^^^ ( ~~~d ||| (e &&& f))) - 2 *  ~~~(d ^^^ e) - 5 *  ~~~(d &&& ( ~~~e &&& f)) + 2 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 7 *  ~~~(d ||| f) - 2 * (f ^^^  ~~~(d ||| e)) + 1 * (d &&&  ~~~e) + 2 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 2 * (f &&&  ~~~(d ^^^ e)) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 1 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 3 * (e ^^^ (d ||| (e &&& f))) + 11 * ((d &&& f) |||  ~~~(e ||| f)) + 7 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 2 * ((d ^^^ e) &&& (d ^^^ f)) + 5 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 3 * ((d &&& e) ^^^ (e ||| f)) - 7 * (e ^^^ (d &&& f)) - 2 * ( ~~~e &&& (d ^^^ f)) - 11 * ((e &&& f) ||| (d &&& (e ||| f))) + 1 * (e ^^^  ~~~(d &&& (e &&& f))) - 1 * (e ^^^  ~~~(d ||| f)) - 5 *  ~~~(d &&& (e ||| f)) - 6 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 7 *  ~~~(d ^^^ (e ^^^ f)) - 1 * (e ^^^ (d ||| ( ~~~e &&& f))) - 1 * (f ^^^ (d &&&  ~~~e)) - 8 *  ~~~(d ||| (e ||| f)) + 16 *  ~~~(d ||| ( ~~~e ||| f)) + 5 *  ~~~( ~~~d ||| (e ||| f)) + 35 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 17 * ( ~~~d &&& ( ~~~e &&& f)) + 21 * ( ~~~d &&& (e &&& f)) + 9 * (d &&& ( ~~~e &&& f)) + 26 * (d &&& (e &&& f)) = 6 *  ~~~( ~~~d &&& (e &&& f))

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

theorem t0_proof : t0_before ⊑ t0_after

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

theorem negate_select_of_op_vs_negated_op_nsw_xyyx_proof : negate_select_of_op_vs_negated_op_nsw_xyyx_before ⊑ negate_select_of_op_vs_negated_op_nsw_xyyx_after

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

theorem slt_smin2_proof : slt_smin2_before ⊑ slt_smin2_after

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

theorem shl_mul_mask_wrong_mul_const_proof : shl_mul_mask_wrong_mul_const_before ⊑ shl_mul_mask_wrong_mul_const_after

theorem sle_swap_or_not_min_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 != BitVec.ofInt 8 (-128)) ||

theorem ashrsgt_01_14_exact_proof : ashrsgt_01_14_exact_before ⊑ ashrsgt_01_14_exact_after

theorem or_xor_xor_normal_variant1_proof : or_xor_xor_normal_variant1_before ⊑ or_xor_xor_normal_variant1_after

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 1), x &&& 0#1 = 0#1

theorem t1_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬24#32 ≥ ↑32 →
    zeroExtend 32 x <<< 24#32 &&& BitVec.ofInt 32 (-2147483648) = signExtend 32 x &&& BitVec.ofInt 32 (-2147483648)

theorem e_1320 :
     - 2 * (z ^^^ t) - 7 * (z ||| t) - 6 * t + 2 *  ~~~t + 1 *  ~~~(z ^^^ t) + 7 * (z |||  ~~~t) - 5 *  ~~~(z ||| t) + 20 *  ~~~(z |||  ~~~t) + 10 * (z &&& t) = 5 *  ~~~(z &&&  ~~~t)

theorem e_670 :
    1 * y - 1 *  ~~~(x &&&  ~~~x) - 6 * (x ||| y) - 1 *  ~~~(x &&& y) - 2 *  ~~~(x &&&  ~~~y) + 4 *  ~~~y - 7 *  ~~~(x ||| y) + 9 *  ~~~(x |||  ~~~y) + 4 * (x &&&  ~~~y) + 1 * (x &&& y) =  - 7 *  ~~~(x ^^^ y)

theorem lshr_mul_times_5_div_4_exact_2_proof : lshr_mul_times_5_div_4_exact_2_before ⊑ lshr_mul_times_5_div_4_exact_2_after

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

theorem ashrslt_02_15_proof : ashrslt_02_15_before ⊑ ashrslt_02_15_after

theorem t9_nocse_proof : t9_nocse_before ⊑ t9_nocse_after

theorem sge_swap_or_max_proof : sge_swap_or_max_before ⊑ sge_swap_or_max_after

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

theorem e_445 :
     - 2 * (x ^^^ y) + 2 *  ~~~x + 11 * (x ||| y) + 2 *  ~~~(x &&&  ~~~x) + 3 *  ~~~(x ||| y) - 13 *  ~~~(x |||  ~~~y) - 11 * (x &&&  ~~~y) - 6 * (x &&& y) = 7 *  ~~~(x ^^^ y)

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

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

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

theorem e_100 :
     - 11 * (x |||  ~~~y) + 3 *  ~~~(x &&& y) - 5 *  ~~~y + 13 *  ~~~(x ||| y) - 4 *  ~~~(x |||  ~~~y) + 12 * (x &&&  ~~~y) =  - 1 * (x ^^^ y) - 11 * (x &&& y)

theorem t3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(32#32 - x ≥ ↑32 ∨ zeroExtend 64 (x + BitVec.ofInt 32 (-16)) ≥ ↑64) →
    ofBool (x_1 <<< (32#32 - x) &&& truncate 32 (131071#64 >>> zeroExtend 64 (x + BitVec.ofInt 32 (-16))) != 0#32) =
      ofBool (x_1 &&& 1#32 != 0#32)

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

theorem test_shl_nuw__nsw_is_safe_proof : test_shl_nuw__nsw_is_safe_before ⊑ test_shl_nuw__nsw_is_safe_after

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

theorem neg_slt_1_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (0#8 - x <ₛ 1#8) = ofBool (x <ᵤ BitVec.ofInt 8 (-127))

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

theorem com_ty : com.2.2.1 = [.bitvec 32]

theorem lshrult_01_13_proof : lshrult_01_13_before ⊑ lshrult_01_13_after

theorem test14_proof : test14_before ⊑ test14_after

theorem test13_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(x == 0 || 32 != 1 && x == intMin 32 && x == -1) = true → x.srem x = 0#32

theorem alive_AddSub_1309  (w : Nat)   : alive_AddSub_1309_src w  ⊑ alive_AddSub_1309_tgt w

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

theorem test1_proof : test1_before ⊑ test1_after

theorem srem_constant_dividend_select_of_constants_divisor_0_arm_proof : srem_constant_dividend_select_of_constants_divisor_0_arm_before ⊑ srem_constant_dividend_select_of_constants_divisor_0_arm_after

theorem test_sext4_proof : test_sext4_before ⊑ test_sext4_after

@[simp] theorem Com.outContextHom_var :
    (var e body : Com d Γ eff t).outContextHom
    = e.contextHom.comp body.outContextHom

theorem sel_false_val_is_a_masked_ashr_of_true_val1_thm.extracted_1._2 : ∀ (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) →
      x = x.sshiftRight' (zeroExtend 64 (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)))

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

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

theorem select_ashr_thm.extracted_1._2 : ∀ (x : BitVec 128) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → ¬0#128 ≥ ↑128 → x = x.sshiftRight' 0#128

theorem e_577 :
    2 *  ~~~(x &&& y) + 5 * x - 5 *  ~~~x - 5 *  ~~~y - 2 * y - 5 *  ~~~(x &&&  ~~~x) + 11 *  ~~~(x ||| y) + 8 *  ~~~(x |||  ~~~y) + 3 * (x &&&  ~~~y) =  - 2 *  ~~~(x &&&  ~~~y)

theorem shl_C1_add_A_C2_i32_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬zeroExtend 32 x + 5#32 ≥ ↑32 → True ∧ x.msb = true ∨ zeroExtend 32 x ≥ ↑32 → False

theorem Bisim.rfl {a : Stream α} : a ~ a

theorem icmp_sle2_proof : icmp_sle2_before ⊑ icmp_sle2_after

theorem eq_gen (w : Nat) (a b : BitVec w) : (a &&& b = 0#w) → ((a + b) = (a ||| b))

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

theorem select_replace_nested_proof : select_replace_nested_before ⊑ select_replace_nested_after

theorem sext_sext_slt_proof : sext_sext_slt_before ⊑ sext_sext_slt_after

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

theorem test18a_thm (e : IntW 8) :
  icmp IntPred.eq (LLVM.and e (const? 8 (-2))) (const? 8 0) ⊑ icmp IntPred.ult e (const? 8 2)

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

theorem prove_exact_with_high_mask_limit_proof : prove_exact_with_high_mask_limit_before ⊑ prove_exact_with_high_mask_limit_after

theorem shl_add_lshr_proof : shl_add_lshr_before ⊑ shl_add_lshr_after

theorem e_1959 :
     - 3 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 2 *  ~~~(a &&& (b ^^^ c)) + 1 * (a ^^^ (b ||| c)) - 3 * (b ^^^  ~~~(a ||| c)) + 5 * (b ^^^  ~~~(a &&&  ~~~c)) + 2 * (b &&&  ~~~c) - 5 *  ~~~(a ^^^ ( ~~~b ||| c)) - 3 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) - 7 * ( ~~~c |||  ~~~(a ^^^ b)) + 3 *  ~~~( ~~~a &&& ( ~~~b ||| c)) - 1 *  ~~~(a &&& ( ~~~b &&& c)) - 7 * b - 7 * (b ^^^ (a ||| ( ~~~b &&& c))) + 2 * ((a &&& b) ^^^ (b |||  ~~~c)) - 2 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) - 5 * (b ^^^ (a &&&  ~~~c)) - 1 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) + 1 * ( ~~~b &&&  ~~~(a ^^^ c)) - 6 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) + 3 *  ~~~(a ^^^ c) + 5 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 2 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 5 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 1 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) + 2 * (b ^^^ (a ||| (b ^^^ c))) - 3 * (a ^^^ b) - 2 * (b |||  ~~~c) - 1 * ((a |||  ~~~b) &&& (b ^^^ c)) - 2 * (c &&&  ~~~(a &&& b)) + 1 * (b ^^^  ~~~(a &&& c)) + 1 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) + 3 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 2 *  ~~~(b ^^^ c) - 1 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) - 1 * (a ^^^ c) + 1 * (a ||| ( ~~~b ||| c)) - 1 * (c ^^^ (a &&& b)) + 5 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) - 11 * (b &&& c) - 6 * (c ^^^ (a &&& (b ||| c))) + 11 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) + 5 * (a ^^^ (b ^^^ c)) - 7 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 5 * (b ^^^  ~~~(a &&& (b ^^^ c))) + 1 * ((a ^^^ b) |||  ~~~(a ^^^ c)) + 2 *  ~~~(a &&& c) - 11 * ((a &&& c) |||  ~~~(b ||| c)) - 3 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 7 *  ~~~(a ||| ( ~~~b ||| c)) + 35 *  ~~~( ~~~a ||| (b ||| c)) + 32 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 28 * ( ~~~a &&& ( ~~~b &&& c)) + 42 * ( ~~~a &&& (b &&& c)) + 2 * (a &&& ( ~~~b &&& c)) + 50 * (a &&& (b &&& c)) = 2 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) + 6 * (a ||| ( ~~~b &&& c))

theorem and_min_7_8_proof : and_min_7_8_before ⊑ and_min_7_8_after

theorem test14_thm (e e_1 : IntW 32) :
  mul (LLVM.and (sub (shl e_1 (const? 32 8)) e) (const? 32 128)) (shl e_1 (const? 32 8)) ⊑
    mul (LLVM.and (sub (const? 32 0) e) (const? 32 128)) (shl e_1 (const? 32 8))

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

theorem neg_nsw_slt_1_proof : neg_nsw_slt_1_before ⊑ neg_nsw_slt_1_after

theorem masked_and_notA_slightly_optimized_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (8#32 ≤ᵤ x) = 1#1 → 0#1 = ofBool (x &&& BitVec.ofInt 32 (-40) != 0#32)

theorem sel_false_val_is_a_masked_ashr_of_true_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 denote_insertCom {zip : Zipper d Γ_in eff t₁} [LawfulMonad d.m]
    {newCom : Com d zip.Γ_mid eff newTys} {vs : HVector zip.Γ_mid.Var newTys} :
    (zip.insertCom vs newCom).denote = (fun (V_in : Valuation Γ_in) => do
      let V_mid ← zip.top.denote V_in
      let V_newMid ← newCom.denoteLets V_mid
      zip.bot.denote
        (V_newMid.comap <| newCom.outContextHom.with vs newCom.returnVars)
      )

theorem dont_narrow_zext_ashr_keep_trunc_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ (signExtend 16 x_1).saddOverflow (signExtend 16 x) = true ∨ 1#16 ≥ ↑16) →
    truncate 8 ((signExtend 16 x_1 + signExtend 16 x).sshiftRight' 1#16) =
      truncate 8 ((signExtend 16 x_1 + signExtend 16 x) >>> 1#16)

theorem icmp_ne_and_pow2_shl1_thm (e : IntW 32) :
  zext 32 (icmp IntPred.ne (LLVM.and (shl (const? 32 1) e) (const? 32 16)) (const? 32 0)) ⊑
    zext 32 (icmp IntPred.eq e (const? 32 4))

theorem select_of_symmetric_selects_commuted_proof : select_of_symmetric_selects_commuted_before ⊑ select_of_symmetric_selects_commuted_after

theorem PR42691_10_proof : PR42691_10_before ⊑ PR42691_10_after

theorem test2_thm (e e_1 : IntW 1) : LLVM.and (LLVM.and e_1 e) e_1 ⊑ LLVM.and e_1 e

theorem and_consts_logical_proof : and_consts_logical_before ⊑ and_consts_logical_after

theorem sext_sext_add_mismatched_types_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 16),
  ¬(7#16 ≥ ↑16 ∨ 9#32 ≥ ↑32) →
    7#16 ≥ ↑16 ∨
        9#32 ≥ ↑32 ∨
          True ∧ (signExtend 64 (x_1.sshiftRight' 7#16)).saddOverflow (signExtend 64 (x.sshiftRight' 9#32)) = true →
      False

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

theorem scalar_i32_lshr_and_negC_ne_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (LLVM.and (lshr e_1 e) (const? 32 (-262144))) (const? 32 0) ⊑
    icmp IntPred.ugt (lshr e_1 e) (const? 32 262143)

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

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

theorem ashrslt_03_06_exact_proof : ashrslt_03_06_exact_before ⊑ ashrslt_03_06_exact_after

theorem demorganize_constant2_proof : demorganize_constant2_before ⊑ demorganize_constant2_after

theorem eq_signed_to_small_unsigned_thm (e : IntW 8) :
  icmp IntPred.eq (sext 32 e) (const? 32 17) ⊑ icmp IntPred.eq e (const? 8 17)

@[simp, simp_denote]
theorem returnTypes_map_signature_eq {s : Signature α} {f : α → β} :
  Signature.returnTypes (f <$> s) = f <$> s.returnTypes

theorem sge_or_not_max_logical_proof : sge_or_not_max_logical_before ⊑ sge_or_not_max_logical_after

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

theorem alive_InstCombineShift__497'''  (w : Nat)   : alive_InstCombineShift__497'''_src w  ⊑ alive_InstCombineShift__497'''_tgt w

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

theorem select_icmp_ne_not_pow2_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x &&& 5#8 != 0#8) = 1#1 → ofBool (x &&& 5#8 == 0#8) = 1#1 → x ^^^ 5#8 = x

theorem or_and_or_pat5_proof : or_and_or_pat5_before ⊑ or_and_or_pat5_after

theorem test_add_nuw_nsw__all_are_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 1073741823#32 == 3#32) = 1#1 →
    True ∧ (x &&& 1073741823#32).saddOverflow 1#32 = true ∨ True ∧ (x &&& 1073741823#32).uaddOverflow 1#32 = true →
      False

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 t1_ult_slt_0_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 + 16#32 <ᵤ 144#32) = 1#1 →
    ¬ofBool (127#32 <ₛ x_1) = 1#1 → ofBool (x_1 <ₛ BitVec.ofInt 32 (-16)) = 1#1 → x_1 = x

theorem R.toTensor_getD' [hqgt1 : Fact (q > 1)] (a : R q n) (i : Nat) :
    ↑(a.toTensor.getD i 0) = a.coeff i

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 test3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ¬x = 0 → ofBool (x_1 / x != 0#32) = ofBool (x ≤ᵤ x_1)

theorem mul_of_pow2_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (1020#32 <ᵤ (x_1 &&& 255#32) * (x &&& 4#32)) = 0#1

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

theorem uge_to_slt_proof : uge_to_slt_before ⊑ uge_to_slt_after

theorem uge_and_max_commute_proof : uge_and_max_commute_before ⊑ uge_and_max_commute_after

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

theorem e_1521 :
    1 * (b &&& c) + 1 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) + 7 *  ~~~(a &&& (b &&& c)) + 7 * ((a &&& b) |||  ~~~(b ^^^ c)) - 14 *  ~~~(a ||| (b ||| c)) - 7 *  ~~~(a ||| ( ~~~b ||| c)) - 15 *  ~~~( ~~~a ||| (b ||| c)) - 8 * ( ~~~a &&& ( ~~~b &&& c)) - 15 * ( ~~~a &&& (b &&& c)) - 8 * (a &&& (b &&& c)) = 15 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 8 * (a &&& ( ~~~b &&& c))

theorem ugt_swap_and_min_proof : ugt_swap_and_min_before ⊑ ugt_swap_and_min_after

theorem icmp_slt_0_or_icmp_sgt_0_i64_fail0_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬63#64 ≥ ↑64 → x >>> 63#64 ||

theorem badimm4_thm.extracted_1._4 : ∀ (x : BitVec 16),
  ¬(7#8 ≥ ↑8 ∨ 8#16 ≥ ↑16) →
    ¬ofBool ((truncate 8 x).sshiftRight' 7#8 == truncate 8 (x >>> 8#16)) = 1#1 →
      ¬15#16 ≥ ↑16 →
        ¬ofBool (127#16 <ₛ x) = 1#1 →
          ofBool (x <ₛ BitVec.ofInt 16 (-128)) = 1#1 →
            truncate 8 (x.sshiftRight' 15#16) ^^^ 126#8 = BitVec.ofInt 8 (-127)

theorem negate_shl_xor_proof : negate_shl_xor_before ⊑ negate_shl_xor_after

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

theorem ashrslt_03_06_proof : ashrslt_03_06_before ⊑ ashrslt_03_06_after

theorem eq_21_comm_eq_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))))
      (icmp IntPred.eq (trunc 8 (lshr e (const? 32 8))) (trunc 8 (lshr e_1 (const? 32 8)))) ⊑
    icmp IntPred.eq (trunc 16 (lshr e_1 (const? 32 8))) (trunc 16 (lshr e (const? 32 8)))

theorem test8_proof : test8_before ⊑ test8_after

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

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

theorem test_logical_or_eq_a_b_proof : test_logical_or_eq_a_b_before ⊑ test_logical_or_eq_a_b_after

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)

theorem e_907 :
    11 *  ~~~(z &&&  ~~~z) + 1 * (z ||| t) - 5 *  ~~~t + 2 *  ~~~z - 8 *  ~~~(z ||| t) - 7 * (z &&&  ~~~t) = 14 *  ~~~(z |||  ~~~t) + 12 * (z &&& t)

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 uge_swap_or_max_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == -1#8) ||

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

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

theorem sext_diff_i1_xor_sub_proof : sext_diff_i1_xor_sub_before ⊑ sext_diff_i1_xor_sub_after

theorem R.representative_fromTensor_eq_fromTensor' (tensor : List Int) :
    R.representative q n (R.fromTensor tensor) =
      R.representative' q n (R.fromTensor' (q:=q) tensor)  %ₘ (f q n)

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 ashr_lshr_wrong_cond_proof : ashr_lshr_wrong_cond_before ⊑ ashr_lshr_wrong_cond_after

theorem ashr_exact_add_negative_shift_negative_thm (e : IntW 32) :
  ashr (const? 32 (-2)) (add e (const? 32 (-1))) { «exact» := true } ⊑
    ashr (const? 32 (-4)) e { «exact» := true }

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

theorem test_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (255#32 <ᵤ x) ||

theorem shl_add_nsw_proof : shl_add_nsw_before ⊑ shl_add_nsw_after

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

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

theorem ashr_lowmask_thm (e : IntW 32) : LLVM.and (ashr e (const? 32 24)) (const? 32 255) ⊑ lshr e (const? 32 24)

theorem e_76 :
     - 1 * y - 1 * (x ||| y) - 7 *  ~~~(x ||| y) - 5 *  ~~~(x |||  ~~~y) + 1 * (x &&&  ~~~y) =  - 7 *  ~~~(x &&&  ~~~y) + 5 * (x &&& y)

@[simp]
lemma enc_dec' : enc (dec bvs') = bvs'

theorem lshr_mul_times_3_div_2_proof : lshr_mul_times_3_div_2_before ⊑ lshr_mul_times_3_div_2_after

theorem ashrsgt_02_10_exact_proof : ashrsgt_02_10_exact_before ⊑ ashrsgt_02_10_exact_after

theorem test73_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (-1#8 <ₛ truncate 8 x) = 1#1 → ofBool (x &&& 128#32 == 0#32) = 1#1 → 42#32 = 40#32

theorem shift_no_xor_multiuse_xor_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 &&& 1#32 == 0#32) = 1#1 → 1#32 ≥ ↑32 → False

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

theorem zext_zext_eq_proof : zext_zext_eq_before ⊑ zext_zext_eq_after

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

theorem select_icmp_eq_0_and_1_or_1_proof : select_icmp_eq_0_and_1_or_1_before ⊑ select_icmp_eq_0_and_1_or_1_after

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

theorem slt_and_not_max_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 <ₛ x) = 1#1 → 0#1 = ofBool (x_1 <ₛ x)

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

theorem pr51551_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 3))
      (const? 32 0) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 3)) (const? 32 0)

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

theorem sel_sext_constants_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → signExtend 16 (-1#8) = -1#16

theorem test7_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(4#32 == 0 || 32 != 1 && x * 8#32 == intMin 32 && 4#32 == -1) = true → (x * 8#32).srem 4#32 = 0#32

theorem t2_proof : t2_before ⊑ t2_after

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

theorem not_or_or_and_no_and_proof : not_or_or_and_no_and_before ⊑ not_or_or_and_no_and_after

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

theorem and_not_or_commute7_proof : and_not_or_commute7_before ⊑ and_not_or_commute7_after

theorem test_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬8#32 ≥ ↑32 → ¬7#8 ≥ ↑8 → (signExtend 32 x).sshiftRight' 8#32 = signExtend 32 (x.sshiftRight' 7#8)

theorem or_xor_tree_0110_proof : or_xor_tree_0110_before ⊑ or_xor_tree_0110_after

theorem e_669 :
     - 7 * x + 11 *  ~~~x + 1 * y + 7 * (x ||| y) + 1 *  ~~~(x &&&  ~~~y) - 1 *  ~~~(x &&&  ~~~x) - 9 *  ~~~(x ||| y) - 19 *  ~~~(x |||  ~~~y) + 3 * (x &&&  ~~~y) + 1 * (x &&& y) = 2 * (x |||  ~~~y)

theorem test_shl_nuw_nsw__none_are_safe_thm (e : IntW 64) (e_1 : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e_1 (const? 32 (-2))) (const? 32 0)) e
      (ashr e (zext 64 (shl (LLVM.and e_1 (const? 32 (-2))) (const? 32 2) { «nsw» := true, «nuw» := true }))) ⊑
    ashr e (zext 64 (LLVM.and (shl e_1 (const? 32 2)) (const? 32 (-8))) { «nneg» := true })

theorem ashrslt_02_15_exact_proof : ashrslt_02_15_exact_before ⊑ ashrslt_02_15_exact_after

theorem ne_umin4_proof : ne_umin4_before ⊑ ne_umin4_after

theorem neg_sgt_n1_proof : neg_sgt_n1_before ⊑ neg_sgt_n1_after

theorem t11_shl_nsw_flag_preservation_proof : t11_shl_nsw_flag_preservation_before ⊑ t11_shl_nsw_flag_preservation_after

theorem negative_not_power_of_two_proof : negative_not_power_of_two_before ⊑ negative_not_power_of_two_after

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

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

theorem t6_thm (e : IntW 8) :
  icmp IntPred.ult (sub (const? 8 0) e { «nsw» := true, «nuw» := false }) e ⊑
    icmp IntPred.slt e (const? 8 0)

theorem lshrugt_02_11_thm (e : IntW 4) : icmp IntPred.ugt (lshr e (const? 4 2)) (const? 4 (-5)) ⊑ const? 1 0

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

theorem both_thm (e e_1 : IntW 8) :
  icmp IntPred.ult (LLVM.xor (shl (const? 8 (-1)) e_1) (const? 8 (-1)))
      (LLVM.xor (shl (const? 8 (-1)) e) (const? 8 (-1))) ⊑
    icmp IntPred.ugt (shl (const? 8 (-1)) e_1 { «nsw» := true, «nuw» := false })
      (shl (const? 8 (-1)) e { «nsw» := true, «nuw» := false })

theorem udiv_exact_ne_0_thm (e e_1 : IntW 8) :
  icmp IntPred.ne (LLVM.udiv e_1 e { «exact» := true }) (const? 8 0) ⊑
    icmp IntPred.ne e_1 (const? 8 0)

theorem R.fromTensorFinsupp_concat_monomial (c : Int) (cs : List Int) :
    (R.fromTensorFinsupp q (cs ++ [c])) =
      (R.fromTensorFinsupp q cs) +
        (Polynomial.monomial cs.length (Int.cast c : (ZMod q)))

theorem test3_proof : test3_before ⊑ test3_after

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

theorem e_1051 :
    3 * t - 5 *  ~~~(z &&& t) + 5 * (z ||| t) + 1 *  ~~~t - 3 *  ~~~(z |||  ~~~t) - 1 * (z &&&  ~~~t) - 8 * (z &&& t) =  - 4 *  ~~~(z ||| t)

theorem e_571 :
    5 * (x |||  ~~~y) - 1 *  ~~~(x &&& y) - 6 * y - 2 *  ~~~(x ^^^ y) + 1 *  ~~~(x &&&  ~~~y) - 11 * (x ^^^ y) + 20 *  ~~~(x |||  ~~~y) + 15 * (x &&&  ~~~y) + 10 * (x &&& y) = 3 *  ~~~(x &&&  ~~~x) + 5 * x

theorem e_1261 :
     - 11 *  ~~~(z &&&  ~~~t) - 3 * z - 2 * (z |||  ~~~t) + 2 *  ~~~t - 1 * (z ^^^ t) - 1 *  ~~~(z ^^^ t) + 5 *  ~~~(z &&&  ~~~z) + 7 *  ~~~(z ||| t) - 1 * (z &&&  ~~~t) =  - 5 * (z &&& t) - 7 * t

@[simp] theorem last_appendInl :
    (Var.last Γ t |>.appendInl (Δ := Δ)) = Var.last (Γ ++ Δ) t

theorem PR23309v2_proof : PR23309v2_before ⊑ PR23309v2_after

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

theorem test16_proof : test16_before ⊑ test16_after

theorem band_land_right1_proof : band_land_right1_before ⊑ band_land_right1_after

theorem lshrugt_01_09_thm (e : IntW 4) : icmp IntPred.ugt (lshr e (const? 4 1)) (const? 4 (-7)) ⊑ const? 1 0

theorem test83_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 16),
  ¬(True ∧ x.saddOverflow (-1#64) = true ∨ truncate 32 (x + -1#64) ≥ ↑32) → truncate 32 x + -1#32 ≥ ↑32 → False

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

theorem t10_constants_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬(12#32 ≥ ↑32 ∨ 14#64 ≥ ↑64) → 26#32 ≥ ↑32 → False

theorem slt_x_impliesT_ne_smin_todo_thm.extracted_1._3 : ∀ (x x_1 x_2 : BitVec 8),
  ¬ofBool (x_2 <ₛ x_1) = 1#1 → ofBool (x_2 != x) = ofBool (x != x_2)

theorem PR2330_thm (e : IntW 32) :
  icmp IntPred.eq (LLVM.and (shl (const? 32 1) e) (const? 32 1)) (const? 32 0) ⊑
    icmp IntPred.ne e (const? 32 0)

theorem e_1079 :
    3 *  ~~~z - 5 * (z ^^^ t) + 5 *  ~~~t - 6 * (z ||| t) - 3 *  ~~~(z &&&  ~~~t) - 8 *  ~~~(z ||| t) + 11 *  ~~~(z |||  ~~~t) + 6 * (z &&& t) =  - 3 * (z &&&  ~~~t) - 3 * (z |||  ~~~t)

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

theorem lshrugt_01_00_exact_proof : lshrugt_01_00_exact_before ⊑ lshrugt_01_00_exact_after

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

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

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

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

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

theorem test_invalid_simplify_other_proof : test_invalid_simplify_other_before ⊑ test_invalid_simplify_other_after

theorem addhshlhsdivhscalar1_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬((BitVec.ofInt 8 (-64) == 0 || 8 != 1 && x == intMin 8 && BitVec.ofInt 8 (-64) == -1) = true ∨ 6#8 ≥ ↑8) →
    ¬(64#8 == 0 || 8 != 1 && x == intMin 8 && 64#8 == -1) = true →
      x.sdiv (BitVec.ofInt 8 (-64)) <<< 6#8 + x = x.srem 64#8

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

theorem test14_proof : test14_before ⊑ test14_after

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

theorem select_icmp_ne_0_and_32_xor_4096_proof : select_icmp_ne_0_and_32_xor_4096_before ⊑ select_icmp_ne_0_and_32_xor_4096_after

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

theorem t7_ugt_sgt_neg1_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.ugt (add e_2 (const? 32 16)) (const? 32 143))
      (select (icmp IntPred.sgt e_2 (const? 32 (-17))) e_1 e) e_2 ⊑
    select (icmp IntPred.sgt e_2 (const? 32 127)) e_1
      (select (icmp IntPred.slt e_2 (const? 32 (-16))) e e_2)

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

theorem PR42691_7_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (BitVec.ofInt 32 (-2147483647) ≤ᵤ x) ||

theorem negate_zext_proof : negate_zext_before ⊑ negate_zext_after

theorem select_icmp_ne_0_and_4096_xor_4096_proof : select_icmp_ne_0_and_4096_xor_4096_before ⊑ select_icmp_ne_0_and_4096_xor_4096_after

theorem testi16i8_com_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(8#16 ≥ ↑16 ∨ 7#8 ≥ ↑8) →
    ofBool (truncate 8 (x >>> 8#16) == (truncate 8 x).sshiftRight' 7#8) = ofBool (x + 128#16 <ᵤ 256#16)

theorem pr4917_3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (4294967295#64 <ᵤ zeroExtend 64 x_1 * zeroExtend 64 x) = 1#1 →
    True ∧ (zeroExtend 64 x_1).umulOverflow (zeroExtend 64 x) = true → False

theorem test12_thm (e : IntW 32) : LLVM.srem (LLVM.and e (const? 32 (-4))) (const? 32 2) ⊑ const? 32 0

theorem or_simplify_ugt_fail_proof : or_simplify_ugt_fail_before ⊑ or_simplify_ugt_fail_after

theorem demorganize_constant2_thm (e : IntW 32) :
  LLVM.xor (LLVM.or e (const? 32 15)) (const? 32 (-1)) ⊑
    LLVM.xor (LLVM.and e (const? 32 (-16))) (const? 32 (-16))

theorem e_717 :
     - 2 *  ~~~(x &&&  ~~~y) + 1 * y + 11 * (x ^^^ y) + 2 * (x ||| y) - 7 *  ~~~(x ^^^ y) + 2 *  ~~~y + 5 * x - 5 *  ~~~x + 11 *  ~~~(x ||| y) - 8 *  ~~~(x |||  ~~~y) - 21 * (x &&&  ~~~y) =  - 1 *  ~~~(x &&&  ~~~x)

theorem test20_proof : test20_before ⊑ test20_after

theorem slt_zero_ne_ne_0_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → ofBool (zeroExtend 32 (ofBool (x != 0#32)) != x >>> 31#32) = ofBool (0#32 <ₛ x)

theorem test1_thm (e e_1 : IntW 447) :
  LLVM.xor (LLVM.and e_1 (const? 447 70368744177664)) (LLVM.and e (const? 447 70368744177663)) ⊑
    LLVM.or (LLVM.and e_1 (const? 447 70368744177664)) (LLVM.and e (const? 447 70368744177663))
      { «disjoint» := true }

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

theorem PR42691_4_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (BitVec.ofInt 32 (-2147483648) ≤ᵤ x) ||

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

theorem t0_ult_slt_65536_thm.extracted_1._15 : ∀ (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_2

theorem select_or_icmp_bad_proof : select_or_icmp_bad_before ⊑ select_or_icmp_bad_after

theorem samesign_different_sign_bittest2_thm (e e_1 : IntW 32) :
  LLVM.or (icmp IntPred.slt (LLVM.and e_1 e) (const? 32 0)) (icmp IntPred.sge (LLVM.or e_1 e) (const? 32 0)) ⊑
    icmp IntPred.sgt (LLVM.xor e_1 e) (const? 32 (-1))

theorem and_not_or_commute2_proof : and_not_or_commute2_before ⊑ and_not_or_commute2_after

theorem not_false_not_proof : not_false_not_before ⊑ not_false_not_after

theorem main6c_logical_thm.extracted_1._4 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 != 3#32) = 1#1 →
    ¬ofBool (x &&& 48#32 != 16#32) = 1#1 → 1#32 = zeroExtend 32 (ofBool (x &&& 55#32 == 19#32))

theorem ashr_2_add_zext_basic_proof : ashr_2_add_zext_basic_before ⊑ ashr_2_add_zext_basic_after

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 lshrult_02_15_exact_proof : lshrult_02_15_exact_before ⊑ lshrult_02_15_exact_after

theorem ule_swap_or_min_proof : ule_swap_or_min_before ⊑ ule_swap_or_min_after

theorem icmp_slt_0_or_icmp_add_1_sge_100_i32_fail_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 →
    x >>> 31#32 ||

theorem select_ashr_icmp_bad_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 == 1#32) = 1#1 → ¬x_1 ≥ ↑32 → 1#32 ≥ ↑32 → False

theorem or_not_and_commute5_proof : or_not_and_commute5_before ⊑ or_not_and_commute5_after

theorem e_2356 :
    2 *  ~~~(d &&&  ~~~f) - 1 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 1 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 3 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 1 * ((d &&& f) ^^^ (e ||| f)) - 3 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 6 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (d &&& ( ~~~e ||| f)) - 1 * (e ||| (d ^^^ f)) - 2 *  ~~~(d &&& ( ~~~e &&& f)) + 11 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 1 * (f ^^^ (d ||| (e &&& f))) + 7 * ( ~~~e ||| (d ^^^ f)) - 3 *  ~~~(e |||  ~~~f) - 2 * (e ^^^ ( ~~~d &&& (e ||| f))) - 6 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 2 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 2 * (e ^^^ (d &&&  ~~~f)) - 2 * (e |||  ~~~(d |||  ~~~f)) + 7 * (e ^^^ (d ||| (e ||| f))) + 1 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 3 * ( ~~~d ||| (e ^^^ f)) + 7 * (e ^^^  ~~~(d &&& f)) - 7 * (f ^^^  ~~~(d &&& e)) + 1 * (d &&& (e ||| f)) - 1 * ( ~~~d &&& ( ~~~e ||| f)) + 1 * (d ^^^ (e ||| f)) - 2 * ((d ^^^ e) &&& (d ^^^ f)) + 1 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 4 * ((d |||  ~~~e) &&& (e ^^^ f)) + 1 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 11 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 7 * (f ^^^ ( ~~~d &&& (e ||| f))) + 2 * (d ||| (e ||| f)) + 4 * (e |||  ~~~f) + 2 * ( ~~~d &&& (e ||| f)) - 1 * ( ~~~d &&& (e ^^^ f)) + 3 * (d ||| ( ~~~e ||| f)) + 5 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) + 2 * ( ~~~d ||| (e ||| f)) + 2 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 5 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 1 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 3 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 5 * (d &&&  ~~~f) - 6 * ( ~~~e &&&  ~~~(d ^^^ f)) + 3 * ((d &&&  ~~~e) ||| (e ^^^ f)) - 11 *  ~~~(d ^^^ f) + 1 * (f ^^^ (d &&& (e ||| f))) + 11 * ((d ^^^ e) ||| (d ^^^ f)) + 5 * (d ||| ( ~~~e &&& f)) + 3 * (f ^^^ (d &&& e)) + 1 * (e ||| (d &&& f)) - 2 * (f ^^^ (d &&&  ~~~e)) - 3 * (e ^^^ (d ||| (e ^^^ f))) + 1 * (d ^^^ (e &&& f)) - 1 * ((d &&& e) ^^^ (e |||  ~~~f)) - 5 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 6 *  ~~~(d &&& f) - 1 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 7 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 10 *  ~~~(d ||| (e ||| f)) - 14 *  ~~~(d ||| ( ~~~e ||| f)) - 27 *  ~~~( ~~~d ||| (e ||| f)) - 23 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 41 * ( ~~~d &&& ( ~~~e &&& f)) - 51 * (d &&& ( ~~~e &&& f)) = 13 * ( ~~~d &&& (e &&& f))

theorem shl_sub_i64_thm (e : IntW 64) :
  shl (const? 64 1) (sub (const? 64 63) e) ⊑ lshr (const? 64 (-9223372036854775808)) e { «exact» := true }

theorem sub_select_sext_op_swapped_non_const_args_thm.extracted_1._1 : ∀ (x : BitVec 6) (x_1 : BitVec 1),
  x_1 = 1#1 → signExtend 6 x_1 - x = x ^^^ -1#6

theorem cmpeq_xor_cst3_proof : cmpeq_xor_cst3_before ⊑ cmpeq_xor_cst3_after

theorem eq_umax3_proof : eq_umax3_before ⊑ eq_umax3_after

theorem add_or_sub_comb_i128_commuted3_nuw_nsw_proof : add_or_sub_comb_i128_commuted3_nuw_nsw_before ⊑ add_or_sub_comb_i128_commuted3_nuw_nsw_after

omit [LawfulBEq A] [Fintype S] in
lemma processOneElem_rel_preserve :
    s₂ ~[st.rel] sa' →
    s₂ ~[(processOneElem A S final s₁ st (a, sa)).rel] sa'

theorem icmp_slt_0_and_icmp_sge_neg1_i64_fail_proof : icmp_slt_0_and_icmp_sge_neg1_i64_fail_before ⊑ icmp_slt_0_and_icmp_sge_neg1_i64_fail_after

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

theorem toBitVec_concat(a : BitStream) :
    (a.concat b).toBitVec w =
      match w with

theorem fold_sext_to_and_wrong6_proof : fold_sext_to_and_wrong6_before ⊑ fold_sext_to_and_wrong6_after

theorem bools2_logical_commute3_and1_thm.extracted_1._7 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 &&& x_1 = 1#1 → ¬x = 1#1 → x_1 = 1#1 → 0#1 = x_2

theorem scanOr_true_iff (s : BitStream) (n : Nat)
    : s.scanOr n = true ↔ ∃ (i : Nat), (i ≤ n) ∧ s i = true

theorem test3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ¬1#32 ≥ ↑32 → (x_1 ||| x <<< 1#32) &&& 1#32 = x_1 &&& 1#32

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 shl_C1_add_A_C2_i32_thm (e : IntW 16) :
  shl (const? 32 6) (add (zext 32 e) (const? 32 5)) ⊑ shl (const? 32 192) (zext 32 e { «nneg» := true })

theorem test11_proof : test11_before ⊑ test11_after

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

theorem eq_basic_equal_minus_1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == -1#8) ||

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

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

theorem ashrslt_03_11_exact_proof : ashrslt_03_11_exact_before ⊑ ashrslt_03_11_exact_after

theorem e_1997 :
    1 *  ~~~( ~~~a ||| (b ^^^ c)) + 3 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 3 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) - 2 * ((b &&&  ~~~c) ^^^ (a ||| (b ^^^ c))) + 11 *  ~~~c - 2 * ( ~~~b ||| (a ^^^ c)) - 1 * (b &&&  ~~~(a ^^^ c)) + 2 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 5 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) + 1 * (b &&& (a ^^^ c)) - 7 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) + 7 * (c ^^^ ( ~~~a &&& ( ~~~b ||| c))) + 2 * c - 3 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) - 6 * (c ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 4 * (a &&& b) + 3 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) + 11 * (c ^^^ ( ~~~a ||| (b &&& c))) + 11 * ( ~~~a &&& ( ~~~b ||| c)) - 2 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) - 1 * (c ^^^ (a ||| b)) + 1 *  ~~~(a ||| ( ~~~b &&& c)) + 1 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) - 2 *  ~~~(a ||| (b &&& c)) - 2 * (b ^^^ ( ~~~a ||| (b ||| c))) + 1 * ( ~~~a ||| (b &&& c)) + 5 * (a |||  ~~~b) - 1 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) + 2 * ( ~~~(a &&& b) &&&  ~~~(b ^^^ c)) - 1 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) + 1 * ( ~~~b |||  ~~~(a ^^^ c)) + 1 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 5 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 2 * (c ^^^  ~~~(a &&&  ~~~b)) + 4 * (c ^^^ (a ||| ( ~~~b ||| c))) - 3 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) + 1 * (c ^^^ (a &&& (b ||| c))) + 3 * ((a &&&  ~~~b) ||| (a ^^^ (b ^^^ c))) + 4 * (a ||| ( ~~~b &&& c)) - 3 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 1 * (a &&& (b ^^^ c)) - 6 * ((a &&& b) |||  ~~~(b |||  ~~~c)) + 2 * (c ^^^ (a ||| (b &&& c))) + 2 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) - 3 * (b ||| (a &&& c)) - 11 * ( ~~~a &&& (b ||| c)) - 5 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) - 1 * (b ^^^ (a ||| ( ~~~b ||| c))) - 11 * ((a &&& b) ^^^  ~~~(a ^^^ (b &&& c))) - 7 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) - 11 * (c ^^^  ~~~(a &&& b)) + 4 * (c &&&  ~~~(a ^^^ b)) - 22 *  ~~~(a ||| (b ||| c)) + 36 *  ~~~(a ||| ( ~~~b ||| c)) - 16 *  ~~~( ~~~a ||| (b ||| c)) + 5 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 28 * ( ~~~a &&& ( ~~~b &&& c)) + 12 * ( ~~~a &&& (b &&& c)) - 21 * (a &&& ( ~~~b &&& c)) =  - 12 * (a &&& (b &&& c))

theorem test27_thm (e : IntW 8) :
  add (LLVM.and (sub (LLVM.and e (const? 8 4)) (const? 8 16)) (const? 8 (-16))) (const? 8 16) ⊑ const? 8 0

theorem add_nsw_thm.extracted_1._1 : ∀ (x : BitVec 1),
  ¬x = 1#1 → ¬(True ∧ (7#8).saddOverflow 64#8 = true) → 7#8 + 64#8 = 71#8

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

@[simp] theorem Valuation.nil_append {V : Γ.Valuation} :
    HAppend.hAppend (α := Valuation no_index _) (γ := Valuation no_index _)
      (nil (Ty:=Ty)) V -- nil ++ V
    = V

theorem test36_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → ofBool (truncate 8 (x >>> 31#32) == 0#8) = ofBool (-1#32 <ₛ x)

theorem widget_proof : widget_before ⊑ widget_after

theorem nonexact_ashr_eq_exactdiv_proof : nonexact_ashr_eq_exactdiv_before ⊑ nonexact_ashr_eq_exactdiv_after

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

theorem main1_proof : main1_before ⊑ main1_after

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

theorem xor_with_or_disjoint_ba_proof : xor_with_or_disjoint_ba_before ⊑ xor_with_or_disjoint_ba_after

theorem test_proof : test_before ⊑ test_after

theorem test11_proof : test11_before ⊑ test11_after

theorem test30_proof : test30_before ⊑ test30_after

theorem test19_proof : test19_before ⊑ test19_after

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

theorem lshrugt_03_00_exact_proof : lshrugt_03_00_exact_before ⊑ lshrugt_03_00_exact_after

theorem dec_sub_proof : dec_sub_before ⊑ dec_sub_after

theorem or_nosignbit_ashr_proof : or_nosignbit_ashr_before ⊑ or_nosignbit_ashr_after

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

theorem unmasked_shlop_insufficient_mask_shift_amount_thm (e e_1 e_2 : IntW 16) :
  trunc 8
      (LLVM.or (shl e_2 (sub (const? 16 8) (LLVM.and e_1 (const? 16 15))))
        (lshr (LLVM.and e (const? 16 255)) (LLVM.and e_1 (const? 16 15)))) ⊑
    trunc 8
      (LLVM.or (shl e_2 (sub (const? 16 8) (LLVM.and e_1 (const? 16 15)) { «nsw» := true, «nuw» := false }))
        (lshr (LLVM.and e (const? 16 255)) (LLVM.and e_1 (const? 16 15))))

theorem xor_signbit_select_ashr_proof : xor_signbit_select_ashr_before ⊑ xor_signbit_select_ashr_after

theorem e_63 :
     - 2 *  ~~~x + 11 *  ~~~(x &&&  ~~~x) - 5 * x - 9 *  ~~~(x |||  ~~~y) - 6 * (x &&& y) = 6 * (x &&&  ~~~y) + 9 *  ~~~(x ||| y)

theorem eq_iff_coeff_eq [hqgt1 : Fact (q > 1)] (a b : R q n) :
    a = b ↔ Polynomial.coeff a.representative = Polynomial.coeff b.representative

theorem test19_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (signExtend 64 x <ₛ 12345#64) = ofBool (x <ₛ 12345#32)

theorem lshr_neg_sgt_minus_1_proof : lshr_neg_sgt_minus_1_before ⊑ lshr_neg_sgt_minus_1_after

theorem icmp_slt_0_and_icmp_sge_neg1_i32_proof : icmp_slt_0_and_icmp_sge_neg1_i32_before ⊑ icmp_slt_0_and_icmp_sge_neg1_i32_after

theorem e_1748 :
     - 7 * (c ||| (a ^^^ b)) - 1 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) - 5 * b + 1 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) + 2 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 3 * (b ^^^ (a ||| c)) + 1 * (c ^^^ (a ||| (b ||| c))) + 11 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 1 * (a |||  ~~~b) - 1 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) + 2 * (c |||  ~~~(a ||| b)) - 5 * (b ^^^ (a &&& c)) + 7 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 4 * (a ^^^ (b &&& c)) - 2 *  ~~~(b ^^^ c) + 11 * (a &&& (b ||| c)) + 3 *  ~~~(b &&& c) + 5 * ((a ||| b) &&&  ~~~(b ^^^ c)) - 5 * ( ~~~a ||| ( ~~~b &&& c)) + 11 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) - 7 * (b |||  ~~~c) + 2 * (b &&&  ~~~c) + 2 * (a ||| (b ^^^ c)) - 11 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) + 2 * (b &&& (a ^^^ c)) + 11 * (b ^^^ ( ~~~a ||| (b &&& c))) + 1 * (c &&& (a ^^^ b)) - 1 *  ~~~( ~~~a &&& (b &&& c)) + 16 *  ~~~(a ||| ( ~~~b ||| c)) - 20 *  ~~~( ~~~a ||| (b ||| c)) - 5 * ( ~~~a &&& ( ~~~b &&& c)) + 22 * ( ~~~a &&& (b &&& c)) - 36 * (a &&& ( ~~~b &&& c)) - 3 * (a &&& (b &&& c)) = 39 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 13 *  ~~~(a ||| (b ||| c))

theorem xor_nosignbit_select_shl_proof : xor_nosignbit_select_shl_before ⊑ xor_nosignbit_select_shl_after

theorem test_and4_thm (e e_1 : IntW 32) :
  LLVM.and (icmp IntPred.sge (LLVM.and e_1 (const? 32 2147483647)) e) (icmp IntPred.sge e (const? 32 0)) ⊑
    icmp IntPred.ule e (LLVM.and e_1 (const? 32 2147483647))

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

theorem test12_thm (e e_1 : IntW 32) :
  trunc 64 (lshr (zext 128 e_1) (LLVM.and (zext 128 e) (const? 128 31))) ⊑
    lshr (zext 64 e_1) (zext 64 (LLVM.and e (const? 32 31)) { «nneg» := true })

theorem main10_proof : main10_before ⊑ main10_after

theorem andn_or_cmp_2_thm (e e_1 e_2 : IntW 16) :
  LLVM.and (LLVM.or (icmp IntPred.ugt e_2 (const? 16 42)) (icmp IntPred.sge e_1 e))
      (icmp IntPred.slt e_1 e) ⊑
    LLVM.and (icmp IntPred.ugt e_2 (const? 16 42)) (icmp IntPred.slt e_1 e)

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

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

theorem multiuse_select_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → 64#64 * (64#64 - zeroExtend 64 x) = 4032#64

theorem smear_set_bit_different_dest_type_wider_dst_proof : smear_set_bit_different_dest_type_wider_dst_before ⊑ smear_set_bit_different_dest_type_wider_dst_after

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

theorem arbitrary_mask_sub_i8_proof : arbitrary_mask_sub_i8_before ⊑ arbitrary_mask_sub_i8_after

theorem ashr_lshr_exact_ashr_only_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (-1#32 <ₛ x_1) = 1#1 → ¬x ≥ ↑32 → x_1 >>> x = x_1.sshiftRight' x

theorem scalar_i32_lshr_and_negC_slt_proof : scalar_i32_lshr_and_negC_slt_before ⊑ scalar_i32_lshr_and_negC_slt_after

theorem test_sext2_proof : test_sext2_before ⊑ test_sext2_after

theorem neg_mask1_lshr_proof : neg_mask1_lshr_before ⊑ neg_mask1_lshr_after

theorem n0_proof : n0_before ⊑ n0_after

theorem ashrslt_01_02_proof : ashrslt_01_02_before ⊑ ashrslt_01_02_after

theorem lshrugt_01_13_exact_proof : lshrugt_01_13_exact_before ⊑ lshrugt_01_13_exact_after

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

theorem positive_biggerShl_shlnuw_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x <<< 10#32 >>> 10#32 ≠ x ∨ 10#32 ≥ ↑32 ∨ 5#32 ≥ ↑32) →
    True ∧ (x <<< 5#32).sshiftRight' 5#32 ≠ x ∨ True ∧ x <<< 5#32 >>> 5#32 ≠ x ∨ 5#32 ≥ ↑32 → False

theorem lshr_or_or_fail_proof : lshr_or_or_fail_before ⊑ lshr_or_or_fail_after

theorem PR2844_logical_thm.extracted_1._4 : ∀ (x : BitVec 32),
  ¬ofBool (x == 0#32) = 1#1 →
    ¬ofBool (x <ₛ BitVec.ofInt 32 (-638208501)) = 1#1 →
      1#32 = zeroExtend 32 (ofBool (x != 0#32) &&& ofBool (BitVec.ofInt 32 (-638208502) <ₛ x))

theorem bv_AndOrXor_1733 :
    ∀ (e e_1 : LLVM.IntW w),
      LLVM.or (LLVM.icmp LLVM.IntPred.ne e (LLVM.const? w 0)) (LLVM.icmp LLVM.IntPred.ne e_1 (LLVM.const? w 0)) ⊑
        LLVM.icmp LLVM.IntPred.ne (LLVM.or e e_1) (LLVM.const? w 0)

theorem R.exists_representative_fromPoly_eq_mul_add (a : (ZMod q)[X]) :
    ∃ (k : (ZMod q)[X]), (R.fromPoly (n:=n) a).representative' = k * (f q n) + a

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

theorem or_ranges_separated_thm (e : IntW 8) :
  LLVM.or (LLVM.and (icmp IntPred.uge e (const? 8 5)) (icmp IntPred.ule e (const? 8 10)))
      (LLVM.and (icmp IntPred.uge e (const? 8 12)) (icmp IntPred.ule e (const? 8 20))) ⊑
    LLVM.or (icmp IntPred.ult (add e (const? 8 (-5))) (const? 8 6))
      (icmp IntPred.ult (add e (const? 8 (-12))) (const? 8 9))

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 lshr_and_and_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(2#8 ≥ ↑8 ∨ (42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true ∨ 2#8 ≥ ↑8) →
    ¬((42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true ∨ 2#8 ≥ ↑8) →
      (x_1 >>> 2#8 &&& 13#8 &&& x.srem 42#8) <<< 2#8 = x_1 &&& 52#8 &&& x.srem 42#8 <<< 2#8

theorem icmp_select_var_proof : icmp_select_var_before ⊑ icmp_select_var_after

theorem AvoidCollision_signExtend_xor {x y : BitVec w} :
    (x ^^^ y).signExtend v = (x.signExtend v) ^^^ (y.signExtend v)

theorem foo_proof : foo_before ⊑ foo_after

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

theorem bools_multi_uses2_thm (e e_1 e_2 : IntW 1) :
  LLVM.and (LLVM.or (LLVM.and (LLVM.xor e_2 (const? 1 1)) e_1) (LLVM.and e_2 e))
      (add (LLVM.and (LLVM.xor e_2 (const? 1 1)) e_1) (LLVM.and e_2 e)) ⊑
    select e_2 e e_1

theorem ashrslt_01_01_proof : ashrslt_01_01_before ⊑ ashrslt_01_01_after

theorem icmp_mul_nsw_sgt_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ x_1.smulOverflow 7#8 = true ∨ True ∧ x.smulOverflow 7#8 = true) →
    ofBool (x * 7#8 <ₛ x_1 * 7#8) = ofBool (x <ₛ x_1)

theorem demorgan_and_apint1_proof : demorgan_and_apint1_before ⊑ demorgan_and_apint1_after

theorem lshrugt_02_10_thm (e : IntW 4) : icmp IntPred.ugt (lshr e (const? 4 2)) (const? 4 (-6)) ⊑ const? 1 0

theorem neg_or_ashr_i32_proof : neg_or_ashr_i32_before ⊑ neg_or_ashr_i32_after

theorem ofDep_xvar_eq_xvar' : MultiWidth.Nondep.Term.ofDepTerm xvar = xvar'

theorem absdiff_thm.extracted_1._1 : ∀ (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)) = 0#64 - (x_1 - x)

theorem shift_no_xor_multiuse_or_proof : shift_no_xor_multiuse_or_before ⊑ shift_no_xor_multiuse_or_after

theorem positive_sameconst_lshrexact_proof : positive_sameconst_lshrexact_before ⊑ positive_sameconst_lshrexact_after

theorem zext (b : BitVec 8) : (b.zeroExtend 10 |>.zeroExtend 8) = b

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

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

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

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

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

theorem select_icmp_ne_0_and_32_or_4096_proof : select_icmp_ne_0_and_32_or_4096_before ⊑ select_icmp_ne_0_and_32_or_4096_after

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

theorem ashrsgt_03_14_exact_proof : ashrsgt_03_14_exact_before ⊑ ashrsgt_03_14_exact_after

lemma language_stable_sim {m : CNFA n} {M₁ M₂ : NFA' n} :
    m.Sim M₁ → m.Sim M₂ → M₁.M.accepts = M₂.M.accepts

@[simp] theorem dropUntilHom_toCons {v : Var Γ t} :
  dropUntilHom (v := v.toCons (t' := t')) = (dropUntilHom (v:=v)).consRight

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

theorem andn_or_cmp_4_proof : andn_or_cmp_4_before ⊑ andn_or_cmp_4_after

theorem icmp_sle11_thm (e : IntW 8) :
  icmp IntPred.sle (shl e (const? 8 7) { «nsw» := true, «nuw» := false }) (const? 8 (-2)) ⊑
    icmp IntPred.slt e (const? 8 0)

theorem tryFactorization_add_nuw_mul_nuw_proof : tryFactorization_add_nuw_mul_nuw_before ⊑ tryFactorization_add_nuw_mul_nuw_after

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 lshrugt_03_09_proof : lshrugt_03_09_before ⊑ lshrugt_03_09_after

theorem test_shl_nsw__nuw_is_safe_proof : test_shl_nsw__nuw_is_safe_before ⊑ test_shl_nsw__nuw_is_safe_after

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

lemma CNFA.proj_bv_language {m : CNFA n2} {f : Fin n1 → Fin n2} :
    m.bv_recognizes L → (m.proj f |>.bv_recognizes (BitVecs.transport f '' L))

theorem positive_biggerlshr_shlnuwnsw_lshrexact_proof : positive_biggerlshr_shlnuwnsw_lshrexact_before ⊑ positive_biggerlshr_shlnuwnsw_lshrexact_after

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

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

theorem test_mul_nsw__nsw_is_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.or e (const? 32 (-83886080))) (const? 32 (-83886079))) (const? 32 (-754974711))
      (mul (LLVM.or e (const? 32 (-83886080))) (const? 32 9) { «nsw» := true, «nuw» := false }) ⊑
    mul (LLVM.or e (const? 32 (-83886080))) (const? 32 9) { «nsw» := true, «nuw» := false }

theorem test_logical_proof : test_logical_before ⊑ test_logical_after

theorem and_zext_zext_proof : and_zext_zext_before ⊑ and_zext_zext_after

theorem lshrugt_01_00_proof : lshrugt_01_00_before ⊑ lshrugt_01_00_after

theorem ashrslt_02_10_proof : ashrslt_02_10_before ⊑ ashrslt_02_10_after

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

theorem substitute_constant_and_eq_ugt_swap_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x <ᵤ x_1) &&& ofBool (x == 42#8) = ofBool (x == 42#8) &&& ofBool (42#8 <ᵤ x_1)

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

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

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

theorem sgt_or_not_min_proof : sgt_or_not_min_before ⊑ sgt_or_not_min_after

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

theorem invert_both_cmp_operands_add_proof : invert_both_cmp_operands_add_before ⊑ invert_both_cmp_operands_add_after

theorem test19_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), x_1 ^^^ x ^^^ x_1 = x

theorem shl_nuw_add_nuw_proof : shl_nuw_add_nuw_before ⊑ shl_nuw_add_nuw_after

theorem and_signbit_select_ashr_proof : and_signbit_select_ashr_before ⊑ and_signbit_select_ashr_after

theorem icmp_eq_sext_ne_otherwise_proof : icmp_eq_sext_ne_otherwise_before ⊑ icmp_eq_sext_ne_otherwise_after

theorem trunc_shl_shl_var_proof : trunc_shl_shl_var_before ⊑ trunc_shl_shl_var_after

theorem ne_umin2_proof : ne_umin2_before ⊑ ne_umin2_after

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

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

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

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

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

theorem alive_283   : alive_283_src ⊑ alive_283_tgt

theorem mul_of_udiv_fail_bad_remainder_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.umod 11#8 ≠ 0 ∨ 11#8 = 0) →
    True ∧ x.umod 11#8 ≠ 0 ∨ 11#8 = 0 ∨ True ∧ (x / 11#8).umulOverflow 6#8 = true → False

theorem icmp_lshr_and_overshift_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬5#8 ≥ ↑8 → ofBool (x >>> 5#8 &&& 15#8 != 0#8) = ofBool (31#8 <ᵤ x)

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

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

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

theorem zext_sext_add_icmp_slt_1_type_not_i1_proof : zext_sext_add_icmp_slt_1_type_not_i1_before ⊑ zext_sext_add_icmp_slt_1_type_not_i1_after

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

theorem t2_ult_sgt_65536_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x <ᵤ 65536#32) = 1#1 → ofBool (65535#32 <ₛ x) = 1#1 ∨ ofBool (x <ₛ 0#32) = 1#1 → False

theorem abs_must_be_positive_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (0#32 ≤ₛ x) = 1#1 → ¬(True ∧ (0#32).ssubOverflow x = true) → ofBool (0#32 ≤ₛ 0#32 - x) = 1#1

theorem fold_sext_to_and_wrong_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x &&& BitVec.ofInt 32 (-2147483647) == -1#32) = 0#1

theorem icmp_sle1_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (x <<< 1#8).sshiftRight' 1#8 ≠ x ∨ 1#8 ≥ ↑8) →
    ofBool (x <<< 1#8 ≤ₛ BitVec.ofInt 8 (-128)) = ofBool (x == BitVec.ofInt 8 (-64))
</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}

variable (lets v matchLets w) (mapIn : Mapping _ _) in

variable (lets matchLets) {tys} (vs ws : HVector _ tys) (mapIn : Mapping _ _) in

namespace MatchVarResult

variable [TyDenote d.Ty] [∀ (t : d.Ty), Inhabited ⟦t⟧] in

section Left

variable {w : Δ_out.Var t}

variable {mapIn} (mapOut : MatchVarResult lets v (.var matchLets matchExpr) w.appendInr mapIn)

end Left

variable {w : Var ⟨te⟩ _} {mapIn}

end MatchVarResult

end MatchVar

section SubsetEntries

def MatchVar.IsMonotone (f : MatchVar Δ Γ) : Prop :=
    ∀ mapIn, ∀ mapOut ∈ f mapIn,
      mapIn.entries ⊆ mapOut.2.entries

open MatchVar

section UnifyVars

variable {Δ Γ : Ctxt d.Ty} {t} (w : Δ.Var t) (v : Γ.Var t)

end UnifyVars

variable [DecidableEq d.Op]
</local_ctx>

<target_theorem>
theorem isMonotone_matchVarArg_aux (lets : Lets d Γ_in eff Γ_out) :
    (
     ∀  (Δ_out : Ctxt d.Ty)
        (matchLets : Lets d Δ_in EffectKind.pure Δ_out) (l : List d.Ty)
        (argsl : HVector Γ_out.Var l) (argsr : HVector Δ_out.Var l),
        (matchArg lets matchLets argsl argsr).IsMonotone
    )
    ∧ (
      ∀ (Δ_out : Ctxt d.Ty) (t : d.Ty) (v : Γ_out.Var t)
        (matchLets : Lets d Δ_in EffectKind.pure Δ_out)
        (w : Var Δ_out t),
        (matchVar lets v matchLets w).IsMonotone
    ) :=
</target_theorem>

