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

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

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

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

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

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

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

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

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

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

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

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

open Set
open Mathlib
open SetRel

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

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

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

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

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

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

@[simp]
</local_ctx>

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

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

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

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

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

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

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

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

### Your task:
<all_available_defs>
Nat in Init.Prelude
Vector in Init.Data.Vector.Basic
Fin in Init.Prelude
String in Init.Prelude
Unit in Init.Prelude
List in Init.Prelude
Field in Mathlib.Algebra.Field.Defs
Bool in Init.Prelude
DecidableEq in Init.Prelude
FinEnum in Mathlib.Data.FinEnum
Hashable in Init.Prelude
input in Leanwuzla.Basic
Fintype in Mathlib.Data.Fintype.Defs
FinEnum.toList in Mathlib.Data.FinEnum
List.range in Init.Data.List.Basic
Bool.xor in Init.Data.Bool
Vector.mapM in Init.Data.Vector.Basic
Subtype in Init.Prelude

def Vars.inputN (inp : ι) (k : Nat) {n : Nat} (hkn : k < n := by admit /- proof elided -/
) : Vars σ ι n :=
  .inputs (Inputs.mk ⟨k, by admit /- proof elided -/
  ⟩ inp)

inductive Vars (σ : Type) (ι : Type) (n : Nat)
| state (s : Inputs σ (n + 1))
| inputs (is : Inputs ι n)
| outputs (os : Fin n) 
deriving DecidableEq, Hashable

inductive Circuit (α : Type u) : Type u
  | tru : Circuit α
  | fals : Circuit α
   
  | var : (positive: Bool) → α → Circuit α
  | and : Circuit α → Circuit α → Circuit α
  | or : Circuit α → Circuit α → Circuit α
  | xor : Circuit α → Circuit α → Circuit α
deriving Repr, DecidableEq

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

structure FSM (arity : Type) : Type 1 where
   
  ( α  : Type )
  [ i : FinEnum α ]
  [ h : Hashable α ]
  [ dec_eq : DecidableEq α ]
   
  ( initCarry : α → Bool )
   
  outputCirc : Circuit (α ⊕ arity)
  nextStateCirc : α → Circuit (α ⊕ arity)

def Vars.stateN (s : σ) (i : Nat) {n : Nat} (hin : i ≤ n := by admit /- proof elided -/
) : Vars σ ι n :=
  .state (Inputs.mk ⟨i, by admit /- proof elided -/
  ⟩ s)

structure Inputs (ι : Type) (n : Nat) : Type  where
  ix : Fin n
  input : ι
deriving DecidableEq, Hashable

def Vars.state0 (s : σ) {n : Nat} : Vars σ ι n :=
  .state (Inputs.mk ⟨0, by admit /- proof elided -/
  ⟩ s)

def bigOr {α : Type _}
    (cs : List (Circuit α)) : Circuit α :=
  match cs with
  | [] => Circuit.fals
  | c :: cs =>
    c ||| (Circuit.bigOr cs)

def bigAnd {α : Type _}
    (cs : List (Circuit α)) : Circuit α :=
  match cs with
  | [] => Circuit.tru
  | c :: cs =>
    c &&& (Circuit.bigAnd cs)

@[simp]
def eval : Circuit α → (α → Bool) → Bool
  | tru, _ => true
  | fals, _ => false
  | var b x, f => if b then f x else !(f x)
  | and c₁ c₂, f => (eval c₁ f) && (eval c₂ f)
  | or c₁ c₂, f => (eval c₁ f) || (eval c₂ f)
  | xor c₁ c₂, f => Bool.xor (eval c₁ f) (eval c₂ f)

def map : ∀ (_c : Circuit α) (_f : α → β), Circuit β
  | tru, _ => tru
  | fals, _ => fals
  | var b x, f => var b (f x)
  | and c₁ c₂, f => (map c₁ f) &&& (map c₂ f)
  | or c₁ c₂, f => (map c₁ f) ||| (map c₂ f)
  | xor c₁ c₂, f => (map c₁ f) ^^^ (map c₂ f)

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

def castLe (i : Inputs ι n) (hn : n ≤ m) : Inputs ι m where
  ix := ⟨i.ix, by admit /- proof elided -/
  ⟩
  input := i.input

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 and_xor_common_op_commute1_after := [llvm|
{
^0(%arg693 : i32, %arg694 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(43 : i32) : i32
  %2 = llvm.mlir.constant(-1 : i32) : i32
  %3 = llvm.udiv %0, %arg693 : i32
  %4 = llvm.udiv %1, %arg694 : i32
  %5 = llvm.xor %4, %2 : i32
  %6 = llvm.and %3, %5 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

def eq_optimized_highbits_cmp_before := [llvm|
{
^0(%arg26 : i32, %arg27 : i32):
  %0 = llvm.mlir.constant(33554432 : i32) : i32
  %1 = llvm.xor %arg27, %arg26 : i32
  %2 = llvm.icmp "ult" %1, %0 : i32
  %3 = llvm.trunc %arg26 : i32 to i25
  %4 = llvm.trunc %arg27 : i32 to i25
  %5 = llvm.icmp "eq" %3, %4 : i25
  %6 = llvm.and %2, %5 : i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def select_icmp_eq_and_4096_0_or_4096_after := [llvm|
{
^0(%arg225 : i32, %arg226 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.and %arg225, %0 : i32
  %2 = llvm.or %arg226, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

def absdiff1_before := [llvm|
{
^0(%arg2 : i64, %arg3 : i64):
  %0 = llvm.icmp "ult" %arg2, %arg3 : i64
  %1 = llvm.sext %0 : i1 to i64
  %2 = llvm.sub %arg2, %arg3 : i64
  %3 = llvm.xor %2, %1 : i64
  %4 = llvm.sub %3, %1 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

def badimm1_before := [llvm|
{
^0(%arg28 : i16):
  %0 = llvm.mlir.constant(9 : i16) : i16
  %1 = llvm.mlir.constant(7 : i8) : i8
  %2 = llvm.mlir.constant(15 : i16) : i16
  %3 = llvm.mlir.constant(127 : i8) : i8
  %4 = llvm.lshr %arg28, %0 : i16
  %5 = llvm.trunc %4 : i16 to i8
  %6 = llvm.trunc %arg28 : i16 to i8
  %7 = llvm.ashr %6, %1 : i8
  %8 = llvm.icmp "eq" %7, %5 : i8
  %9 = llvm.ashr %arg28, %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 masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_0_logical_after := [llvm|
{
^0(%arg29 : i32):
  %0 = llvm.mlir.constant(12 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(3 : i32) : i32
  %3 = llvm.mlir.constant(1 : i32) : i32
  %4 = llvm.and %arg29, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.and %arg29, %2 : i32
  %7 = llvm.icmp "ne" %6, %3 : i32
  %8 = llvm.or %7, %5 : i1
  "llvm.return"(%8) : (i1) -> ()
}
]

BitVec.sdiv in Init.Data.BitVec.Basic

def ashr1_after := [llvm|
{
^0(%arg29 : i64):
  %0 = llvm.mlir.constant(8) : i64
  %1 = llvm.mlir.constant(2) : i64
  %2 = llvm.shl %arg29, %0 : i64
  %3 = llvm.ashr exact %2, %1 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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

def main7a_logical_after := [llvm|
{
^0(%arg81 : i32, %arg82 : i32, %arg83 : i32):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.and %arg82, %arg81 : i32
  %2 = llvm.icmp "ne" %1, %arg82 : i32
  %3 = llvm.and %arg83, %arg81 : i32
  %4 = llvm.icmp "ne" %3, %arg83 : 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) -> ()
}
]

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

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

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

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

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

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

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

def different_size_sext_sext_eq_after := [llvm|
{
^0(%arg10 : i7, %arg11 : i4):
  %0 = llvm.sext %arg11 : i4 to i7
  %1 = llvm.icmp "eq" %arg10, %0 : i7
  "llvm.return"(%1) : (i1) -> ()
}
]

def bools2_logical_commute0_before := [llvm|
{
^0(%arg64 : i1, %arg65 : i1, %arg66 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.xor %arg66, %0 : i1
  %3 = "llvm.select"(%arg66, %arg64, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = "llvm.select"(%2, %arg65, %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 trunc {w: Nat} (w': Nat) (x: IntW w) (noWrapFlags : NoWrapFlags := {nsw := false , nuw := false}) : IntW w' := do
  let x' <- x
  if noWrapFlags.nsw ∧ ((x'.truncate w').signExtend w ≠ x') then
    .poison
  else if noWrapFlags.nuw ∧ ((x'.truncate w').zeroExtend w ≠ x') then
    .poison
  else
    trunc? w' x'

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

def n7_wrong_pred2_before := [llvm|
{
^0(%arg10 : i8, %arg11 : i8):
  %0 = llvm.sub %arg10, %arg11 : i8
  %1 = llvm.icmp "eq" %0, %arg10 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

def sdiv_shl_pair2_before := [llvm|
{
^0(%arg40 : i32, %arg41 : i32, %arg42 : i32):
  %0 = llvm.shl %arg40, %arg41 overflow<nsw,nuw> : i32
  %1 = llvm.shl %arg40, %arg42 overflow<nsw> : i32
  %2 = llvm.sdiv %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

@[simp_denote]
def add_lo_negone_riscv_i64 :=
  [LV| {
    ^entry (%arg0: i64):
    %a = "builtin.unrealized_conversion_cast" (%arg0) : (i64) -> (!riscv.reg)
    %0 = li (0) : !riscv.reg
    %1= li (1) : !riscv.reg
    %2 = sub %0, %1 : !riscv.reg  
    %3 = slli %2, 32 : !riscv.reg
    %4 = add %3, %2 : !riscv.reg
    %5 = add %a, %4 : !riscv.reg
    %6 = "builtin.unrealized_conversion_cast" (%5) : (!riscv.reg) -> (i64)
    llvm.return %6 : i64
  }]

def ashr_32_add_zext_basic_before := [llvm|
{
^0(%arg9 : i32, %arg10 : i32):
  %0 = llvm.mlir.constant(32) : i64
  %1 = llvm.zext %arg9 : i32 to i64
  %2 = llvm.zext %arg10 : i32 to i64
  %3 = llvm.add %1, %2 : i64
  %4 = llvm.ashr %3, %0 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

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

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

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

def storePure (m : MemorySSAState) (p : SLLVM.Ptr) (x : LLVM.IntW w) : MemorySSAState := do
  let m ← m
  Prod.snd <$> (store p x).run m

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

elab "[llvm(" mvars:term,* ")| " reg:mlir_region "]" : term => do
  withTraceNode `LeanMLIR.Elab (pure m!"{exceptEmoji ·} elaborate LLVM program") <| do

  let φ : Nat := mvars.getElems.size
  let ⟨_, _, _, mcom⟩ ← SSA.elabIntoComObj reg (MetaLLVM φ)

  let res ← mcom.metaMap <| MetaLLVM.instantiate <| ←do
    let mvars : Vector _ φ := ⟨mvars.getElems, rfl⟩
    mvars.mapM fun (stx : Term) =>
      elabTermEnsuringType stx (mkConst ``Nat)

  trace[LeanMLIR.Elab] "elaborated expression: {res}"
  return res

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 prove_exact_with_high_mask_before := [llvm|
{
^0(%arg8 : i8, %arg9 : i8):
  %0 = llvm.mlir.constant(-32 : i8) : i8
  %1 = llvm.mlir.constant(-4 : i8) : i8
  %2 = llvm.and %arg8, %0 : i8
  %3 = llvm.sdiv %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def test1_before := [llvm|
{
^0(%arg14 : i32, %arg15 : i32):
  %0 = llvm.icmp "slt" %arg14, %arg15 : i32
  %1 = llvm.zext %0 : i1 to i32
  %2 = llvm.icmp "sgt" %arg14, %arg15 : i32
  %3 = llvm.zext %2 : i1 to i32
  %4 = llvm.and %1, %3 : i32
  %5 = llvm.trunc %4 : i32 to i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def test3_after := [llvm|
{
^0(%arg195 : i64):
  %0 = llvm.mlir.constant(255) : i64
  %1 = llvm.and %arg195, %0 : i64
  "llvm.return"(%1) : (i64) -> ()
}
]

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

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

def testi16i8_ne_before := [llvm|
{
^0(%arg10 : i16):
  %0 = llvm.mlir.constant(8 : i16) : i16
  %1 = llvm.mlir.constant(7 : i8) : i8
  %2 = llvm.lshr %arg10, %0 : i16
  %3 = llvm.trunc %2 : i16 to i8
  %4 = llvm.trunc %arg10 : i16 to i8
  %5 = llvm.ashr %4, %1 : i8
  %6 = llvm.icmp "ne" %5, %3 : i8
  "llvm.return"(%6) : (i1) -> ()
}
]

def sltu_i32_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := sltu_llvm_i32
  rhs := sltu_riscv_i32

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

def and_two_ranges_to_mask_and_range_no_add_on_one_range_after := [llvm|
{
^0(%arg249 : i16):
  %0 = llvm.mlir.constant(-20 : i16) : i16
  %1 = llvm.mlir.constant(11 : i16) : i16
  %2 = llvm.and %arg249, %0 : i16
  %3 = llvm.icmp "ugt" %2, %1 : i16
  "llvm.return"(%3) : (i1) -> ()
}
]

def t9_after := [llvm|
{
^0(%arg192 : i8, %arg193 : i8):
  %0 = llvm.sub %arg192, %arg193 : i8
  "llvm.return"(%0) : (i8) -> ()
}
]

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

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

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

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

def test71_after := [llvm|
{
^0(%arg36 : i32):
  %0 = llvm.mlir.constant(128 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(42 : i32) : i32
  %3 = llvm.mlir.constant(40 : i32) : i32
  %4 = llvm.and %arg36, %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 zext_negate_after := [llvm|
{
^0(%arg37 : i1):
  %0 = llvm.sext %arg37 : i1 to i64
  "llvm.return"(%0) : (i64) -> ()
}
]

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

def scalar_i32_shl_and_signbit_ne_after := [llvm|
{
^0(%arg27 : i32, %arg28 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.shl %arg27, %arg28 : i32
  %2 = llvm.icmp "slt" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def test_before := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(12 : i32) : i32
  %1 = llvm.mlir.constant(-6 : i32) : i32
  %2 = llvm.sdiv %arg1, %0 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

Lean.registerSimplePersistentEnvExtension in Lean.EnvExtension

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

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

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

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

instance : TyDenote (Scf d).Ty := inferInstanceAs (TyDenote d.Ty)

def t1_flags_sub_nsw_sub_before := [llvm|
{
^0(%arg42 : i8, %arg43 : i8, %arg44 : i8):
  %0 = llvm.sub %arg42, %arg43 overflow<nsw> : i8
  %1 = llvm.sub %0, %arg44 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

def test11_after := [llvm|
{
^0(%arg69 : i32, %arg70 : i32):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.zext %arg69 : i32 to i64
  %2 = llvm.and %arg70, %0 : i32
  %3 = llvm.zext nneg %2 : i32 to i64
  %4 = llvm.shl %1, %3 overflow<nsw,nuw> : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

def test73_before := [llvm|
{
^0(%arg32 : i32):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(40 : i32) : i32
  %2 = llvm.mlir.constant(42 : i32) : i32
  %3 = llvm.trunc %arg32 : i32 to i8
  %4 = llvm.icmp "sgt" %3, %0 : i8
  %5 = "llvm.select"(%4, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

def or_eq_with_one_bit_diff_constants1_before := [llvm|
{
^0(%arg366 : i32):
  %0 = llvm.mlir.constant(50 : i32) : i32
  %1 = llvm.mlir.constant(51 : i32) : i32
  %2 = llvm.icmp "eq" %arg366, %0 : i32
  %3 = llvm.icmp "eq" %arg366, %1 : i32
  %4 = llvm.or %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

noncomputable def R.representative :
    R q n → (ZMod q)[X] := fun x => R.representative' q n x %ₘ (f q n)

def test37_before := [llvm|
{
^0(%arg156 : i32):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.mlir.constant(512 : i32) : i32
  %2 = llvm.mlir.constant(11 : i8) : i8
  %3 = llvm.lshr %arg156, %0 : i32
  %4 = llvm.or %3, %1 : i32
  %5 = llvm.trunc %4 : i32 to i8
  %6 = llvm.icmp "eq" %5, %2 : i8
  "llvm.return"(%6) : (i1) -> ()
}
]

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

def test_ult_nuw_after := [llvm|
{
^0(%arg2 : i32, %arg3 : i16):
  %0 = llvm.zext %arg3 : i16 to i32
  %1 = llvm.icmp "ult" %arg2, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

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 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 shl_lshr_eq_amt_multi_use_before := [llvm|
{
^0(%arg7 : i44):
  %0 = llvm.mlir.constant(33 : i44) : i44
  %1 = llvm.shl %arg7, %0 : i44
  %2 = llvm.lshr %1, %0 : i44
  %3 = llvm.add %1, %2 : i44
  "llvm.return"(%3) : (i44) -> ()
}
]

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

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

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

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

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

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

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

def test2_after := [llvm|
{
^0(%arg308 : i32):
  "llvm.return"(%arg308) : (i32) -> ()
}
]

BitVec.cast in Init.Data.BitVec.Basic

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

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

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

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

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

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

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

def sext_ule_sext_after := [llvm|
{
^0(%arg119 : i1, %arg120 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mul %arg120, %arg120 : i8
  %2 = llvm.icmp "eq" %1, %0 : i8
  %3 = llvm.or %2, %arg119 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def positive_samevar_lshrexact_after := [llvm|
{
^0(%arg42 : i8, %arg43 : i8):
  "llvm.return"(%arg42) : (i8) -> ()
}
]

instance : Lean.ToExpr TestDialect.Op :=

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

def mul130_low_before := [llvm|
{
^0(%arg12 : i130, %arg13 : i130):
  %0 = llvm.mlir.constant(36893488147419103231 : i130) : i130
  %1 = llvm.mlir.constant(65 : i130) : i130
  %2 = llvm.and %arg12, %0 : i130
  %3 = llvm.lshr %arg12, %1 : i130
  %4 = llvm.and %arg13, %0 : i130
  %5 = llvm.lshr %arg13, %1 : i130
  %6 = llvm.mul %5, %2 : i130
  %7 = llvm.mul %4, %3 : i130
  %8 = llvm.mul %4, %2 : i130
  %9 = llvm.add %6, %7 : i130
  %10 = llvm.shl %9, %1 : i130
  %11 = llvm.add %10, %8 : i130
  "llvm.return"(%11) : (i130) -> ()
}
]

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

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

@[match_pattern] def lshr (w : Width φ)
  (ExactFlag : ExactFlag := {exact := false} ) : MOp φ
    := .binary w (.lshr ExactFlag )

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

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

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

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

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

@[simp]
def pairMapM [Monad m] (f : α → β → γ) (pair : (m α × m β)) : m γ := do
  let fst ← pair.fst
  let snd ← pair.snd
  return f fst snd

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

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

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

def alive_AndOrXor_2263_tgt :=
[sllvm| {
^bb0(%B : i64, %op0 : i64):
  %v1 = llvm.xor %op0, %B : i64
  %v2 = llvm.or %op0, %B : i64
  llvm.return %v2 : i64
}]

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

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

def 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 or_min_31_30_after := [llvm|
{
^0(%arg3 : i8):
  %0 = llvm.mlir.constant(31 : i8) : i8
  %1 = llvm.or %arg3, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def sdiv_pow2_16 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (16) : i64
      %0 = llvm.sdiv %x, %c : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %c0 = llvm.mlir.constant (63) : i64
      %c1 = llvm.mlir.constant (60) : i64
      %c2 = llvm.mlir.constant (4) : i64
      %0 = llvm.ashr %x, %c0 : i64
      %1 = llvm.lshr %0, %c1 : i64
      %2 = llvm.add %x, %1 : i64 
      %3 = llvm.ashr %2, %c2 : i64
      llvm.return %3 : i64
  }]

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

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

def or_lshr_after := [llvm|
{
^0(%arg628 : i8, %arg629 : i8, %arg630 : i8, %arg631 : i8):
  %0 = llvm.or %arg628, %arg629 : i8
  %1 = llvm.lshr %0, %arg631 : i8
  %2 = llvm.or %1, %arg630 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

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

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

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

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

def ashr_xor_before := [llvm|
{
^0(%arg46 : i32, %arg47 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(5 : i32) : i32
  %2 = llvm.mlir.constant(7 : i32) : i32
  %3 = llvm.srem %arg47, %0 : i32
  %4 = llvm.ashr %arg46, %1 : i32
  %5 = llvm.xor %3, %4 : i32
  %6 = llvm.ashr %5, %2 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

instance {Γ : List d.Ty} {t'} {lhs : Com d (.ofList Γ) .pure t'} :
    Decidable (∀ (t : d.Ty) (v : Var (.ofList Γ) t), ⟨t, v⟩ ∈ lhs.vars) :=
  decidable_of_iff
    (∀ (i : Fin Γ.length),
      let v : Var (.ofList Γ) (Γ.get i) := ⟨i, by admit /- proof elided -/
      ⟩
      ⟨_, v⟩ ∈ lhs.vars) <|  by
  constructor
  · intro h t v
    rcases v with ⟨i, hi⟩
    try simp only [Erased.out_mk] at hi
    rcases List.getElem?_eq_some_iff.1 hi with ⟨h', rfl⟩
    simp at h'
    convert h ⟨i, h'⟩
  · intro h i
    apply h

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

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

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

PartialOrder in Mathlib.Order.Defs.PartialOrder

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

def ofList (vals : List (Option α)) : Stream α :=
  fun i => (vals.get? i).join

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

def llvm_add_lower_riscv_noflags_32 : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)]
where
  lhs:= add_llvm_no_flags_32
  rhs:= add_riscv_32

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

def sgt_and_min_before := [llvm|
{
^0(%arg352 : i9, %arg353 : i9):
  %0 = llvm.mlir.constant(-256 : i9) : i9
  %1 = llvm.icmp "sgt" %arg352, %arg353 : i9
  %2 = llvm.icmp "eq" %arg352, %0 : i9
  %3 = llvm.and %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def icmp_ule_riscv_eq_icmp_ule_llvm_32 : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] :=
  {lhs:= icmp_ule_llvm_32, rhs:= icmp_ule_riscv_32}

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

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

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

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

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

@[simp_denote]
def icmp_slt_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 = slt %lhsr, %rhsr : !i64
    %1 = "builtin.unrealized_conversion_cast"(%0) : (!i64) -> (i1)
    llvm.return %1 : i1
  }]

def shl_and_add_before := [llvm|
{
^0(%arg156 : i8, %arg157 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(119 : i8) : i8
  %2 = llvm.shl %arg156, %0 : i8
  %3 = llvm.shl %arg157, %0 : i8
  %4 = llvm.and %3, %1 : i8
  %5 = llvm.add %2, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

BitVec.twoPow in Init.Data.BitVec.Basic

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

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

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

    |

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

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

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

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

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

def p2_scalar_shifted_urem_by_const_after := [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 overflow<nuw> : i32
  %5 = llvm.urem %4, %1 : i32
  %6 = llvm.icmp "eq" %5, %2 : i32
  "llvm.return"(%6) : (i1) -> ()
}
]

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

partial def printBlockArgs (Γ : Ctxt d.Ty) : String :=
  let ts := Γ.toList
  let args := (List.range ts.length).zip ts.reverse |>.map
    (fun (i, t) => s!"%{i} : {printTy t}")
  "(" ++ String.intercalate ", " args ++ ")"

structure FpExprWrapper where
  width : Nat
  bvExpr: FpExpr width

def icmp_sle8_after := [llvm|
{
^0(%arg5 : i8):
  %0 = llvm.mlir.constant(63 : i8) : i8
  %1 = llvm.icmp "ne" %arg5, %0 : i8
  "llvm.return"(%1) : (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) -> ()
}
]

structure Tensor1d (α : Type) [Inhabited α] where
  size : Index
  val :  Index → α
  spec : ∀ (ix: Index), ix >= size -> val ix = default

def test_and_ne_a_b_commuted_before := [llvm|
{
^0(%arg27 : i1, %arg28 : i8, %arg29 : i8):
  %0 = llvm.icmp "ne" %arg28, %arg29 : i8
  %1 = llvm.and %arg27, %0 : i1
  %2 = "llvm.select"(%1, %arg29, %arg28) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def masked_icmps_mask_notallzeros_bmask_mixed_swapped_4_after := [llvm|
{
^0(%arg40 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.and %arg40, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  "llvm.return"(%3) : (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 RawCNFA.autSignedCmp (cmp: RelationOrdering) : RawCNFA (BitVec 2) :=
  let (m, sltfin, sgtfin, seq) := m
  match cmp with
  | .lt => m.addFinal sltfin
  | .le => (m.addFinal sltfin).addFinal seq
  | .gt => m.addFinal sgtfin
  | .ge => (m.addFinal sgtfin).addFinal seq
where

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

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

BitVec.append in Init.Data.BitVec.Basic

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

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

private partial def valuationElements (e : Expr) (elems : Array Expr := #[]) : Array Expr :=
  match_expr e with
  | Valuation.cons _Ty _instTyDenote _Γ _t x V => valuationElements V (elems.push x)
  | _ => elems

def trunc_lshr_before := [llvm|
{
^0(%arg10 : i8):
  %0 = llvm.mlir.constant(2 : i8) : i8
  %1 = llvm.mlir.constant(14 : i6) : i6
  %2 = llvm.lshr %arg10, %0 : i8
  %3 = llvm.trunc %2 : i8 to i6
  %4 = llvm.and %3, %1 : i6
  "llvm.return"(%4) : (i6) -> ()
}
]

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

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

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

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

def not_cmp_fold_ge : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64, %y: i64):
      %0 = llvm.icmp.ne %x, %y : i64
      %c = llvm.mlir.constant (-1) : i1
      %1 = llvm.xor %0, %c : i1
      llvm.return %1 : i1
  }]
  rhs := [LV| {
    ^entry (%x: i64, %y: i64):
      %0 = llvm.icmp.eq %x, %y : i64
      llvm.return %0 : i1
  }]

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

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

def shl_and_and_after := [llvm|
{
^0(%arg172 : i8, %arg173 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.mlir.constant(80 : i8) : i8
  %2 = llvm.and %arg173, %arg172 : i8
  %3 = llvm.shl %2, %0 : i8
  %4 = llvm.and %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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 test12_logical_after := [llvm|
{
^0(%arg290 : i32, %arg291 : i32):
  %0 = llvm.icmp "ult" %arg290, %arg291 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

structure Item where
 name : String
 tac : Syntax

def processOneElem_inv {st : worklist.St A S} (s : State) (sa : S) (k : ℕ) :
    ∀ a sa', (f sa)[k]? = some (a, sa') →
    processOneElem_mot inits final f s sa k st →
    let st' := processOneElem A S final s st (a, sa')
    StInv A S st'.m st'.map :=

def Lets.castPureToEff (eff : EffectKind) : Lets d Γ_in .pure Γ_out → Lets d Γ_in eff Γ_out
  | .nil => .nil
  | .var body e => .var (body.castPureToEff eff) (e.castPureToEff eff)

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

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

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

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

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

def xor_1_before := [llvm|
{
^0(%arg137 : i8, %arg138 : i1, %arg139 : i8, %arg140 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(123 : i8) : i8
  %2 = llvm.xor %arg139, %0 : i8
  %3 = llvm.xor %arg140, %1 : i8
  %4 = "llvm.select"(%arg138, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %5 = llvm.xor %4, %arg137 : i8
  %6 = llvm.xor %5, %0 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

def add (x y : BitStream) : BitStream :=
  fun n => (addAux x y n).1

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

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

def Std.HashMap.toPFun [BEq α] [Hashable α] (m : HashMap α β) (x : α) : Option β := m[x]?

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

def filterCandidatePredicates  (bvLogicalExpr: FpPredicate) (preconditionCandidates visited: Std.HashSet FpPredicate)
                                                    : GeneralizerStateM ParsedFpExpr FpPredicate (List FpPredicate) :=
  return []

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

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

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

def CNFA.union_bv_language (m₁ m₂ : CNFA n) :
    m₁.bv_recognizes L₁ →
    m₂.bv_recognizes L₂ →
    (m₁.union m₂).bv_recognizes (L₁ ∪ L₂) :=

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

@[inline] private def TacticM.runCore' (x : TacticM α) (ctx : Context) (s : State) : TermElabM α :=
  Prod.fst <$> x.runCore ctx s

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 test22_logical_before := [llvm|
{
^0(%arg5 : i32, %arg6 : i32):
  %0 = llvm.mlir.constant(100663295 : i32) : i32
  %1 = llvm.mlir.constant(268435456 : i32) : i32
  %2 = llvm.mlir.constant(7 : i32) : i32
  %3 = llvm.mlir.constant(-1 : i32) : i32
  %4 = llvm.mlir.constant(true) : i1
  %5 = llvm.and %arg5, %0 : i32
  %6 = llvm.icmp "ult" %5, %1 : i32
  %7 = llvm.and %arg6, %2 : i32
  %8 = llvm.icmp "sgt" %7, %3 : i32
  %9 = "llvm.select"(%6, %4, %8) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%9) : (i1) -> ()
}
]

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

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

def llvm_shl_lower_riscv_nuw_16: LLVMPeepholeRewriteRefine 16 [Ty.llvm (.bitvec 16), Ty.llvm (.bitvec 16)] where
  lhs := shl_llvm_nuw_16
  rhs := shl_riscv_16

def t7_twoshifts2_after := [llvm|
{
^0(%arg28 : i32, %arg29 : i32, %arg30 : i32, %arg31 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %0, %arg29 overflow<nuw> : i32
  %3 = llvm.shl %arg30, %arg31 : i32
  %4 = llvm.and %3, %2 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

def testi16i8_ne_before := [llvm|
{
^0(%arg10 : i16):
  %0 = llvm.mlir.constant(8 : i16) : i16
  %1 = llvm.mlir.constant(7 : i8) : i8
  %2 = llvm.lshr %arg10, %0 : i16
  %3 = llvm.trunc %2 : i16 to i8
  %4 = llvm.trunc %arg10 : i16 to i8
  %5 = llvm.ashr %4, %1 : i8
  %6 = llvm.icmp "ne" %5, %3 : i8
  "llvm.return"(%6) : (i1) -> ()
}
]

def test_add_sub_const_lhs_LHS := [mod_arith q, hq| {
  ^bb0(%x : !R):
    %c0 = mod_arith.constant 12 : !R
    %c1 = mod_arith.constant 34 : !R
    %sub = mod_arith.sub %c0, %x : !R
    %add = mod_arith.add %sub, %c1 : !R
    return %add : !R
}]

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

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

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

noncomputable def removeNone (x : Stream α) : Stream α :=
  Stream.corec x fun x =>
    if h : x ≠ stuck α then
      let x := x.dropLeadingNones h
      (x.head, x.tail)
    else
      (none, x)

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

List.foldr in Init.Data.List.Basic

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 not_signbit_alt_xor_before := [llvm|
{
^0(%arg20 : i8):
  %0 = llvm.mlir.constant(-2 : i8) : i8
  %1 = llvm.mlir.constant(7 : i8) : i8
  %2 = llvm.xor %arg20, %0 : i8
  %3 = llvm.lshr %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

List.drop in Init.Data.List.Basic

def trunc_signed_nsw_before := [llvm|
{
^0(%arg50 : i16, %arg51 : i16):
  %0 = llvm.trunc %arg50 overflow<nsw> : i16 to i8
  %1 = llvm.trunc %arg51 overflow<nsw> : i16 to i8
  %2 = llvm.icmp "slt" %0, %1 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

def udiv_i32_multiuse_after := [llvm|
{
^0(%arg25 : i8, %arg26 : i8):
  %0 = llvm.zext %arg25 : i8 to i32
  %1 = llvm.zext %arg26 : i8 to i32
  %2 = llvm.udiv %0, %1 : i32
  %3 = llvm.add %0, %1 overflow<nsw,nuw> : i32
  %4 = llvm.mul %2, %3 overflow<nsw,nuw> : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

def shl_nsw_nuw_ult_Csle0_before := [llvm|
{
^0(%arg14 : i8, %arg15 : i8):
  %0 = llvm.mlir.constant(-19 : i8) : i8
  %1 = llvm.shl %arg14, %arg15 overflow<nsw,nuw> : i8
  %2 = llvm.icmp "ult" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def uadd_sat_canon_y_nuw_after := [llvm|
{
^0(%arg29 : i32, %arg30 : i32):
  %0 = llvm.add %arg29, %arg30 overflow<nuw> : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

inductive MedusaSynthGeneralizeConfig.Output
  | thmStmt
  | sexpr

def masked_icmps_mask_notallzeros_bmask_mixed_negated_6_logical_after := [llvm|
{
^0(%arg57 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.and %arg57, %0 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  "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_ne_msb_low_last_zero_after := [llvm|
{
^0(%arg174 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.icmp "ult" %arg174, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

def llvm_const_lower_riscv_li19 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM19, rhs:= liRiscv19,
   correct := by admit /- proof elided -/

Lean.Expr.eq? in Lean.Util.Recognizers

def AttrDict.find_nat {φ} (attrs : AttrDict φ) (name : String) : Option Nat :=
  match attrs.find name with
  | .some (AttrValue.nat i) =>  .some i
  | _ => .none

Function.LeftInverse in Init.Data.Function

def shift_xor_multiuse_cmp_and_before := [llvm|
{
^0(%arg28 : i32, %arg29 : i32, %arg30 : i32, %arg31 : 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 %arg28, %0 : i32
  %4 = llvm.icmp "ne" %1, %3 : i32
  %5 = llvm.and %arg29, %2 : i32
  %6 = "llvm.select"(%4, %arg29, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg30, %arg31) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %8 = llvm.mul %6, %7 : i32
  %9 = llvm.mul %8, %5 : i32
  "llvm.return"(%9) : (i32) -> ()
}
]

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

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

def bools2_logical_commute0_and2_after := [llvm|
{
^0(%arg58 : i1, %arg59 : i1, %arg60 : i1):
  %0 = "llvm.select"(%arg60, %arg58, %arg59) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

Lean.isProtected in Lean.Modifiers

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

def src_is_notmask_sext_after := [llvm|
{
^0(%arg75 : i16, %arg76 : i8):
  %0 = llvm.mlir.constant(-8 : i8) : i8
  %1 = llvm.mlir.constant(-128 : i16) : i16
  %2 = llvm.shl %0, %arg76 : i8
  %3 = llvm.xor %arg75, %1 : i16
  %4 = llvm.sext %2 : i8 to i16
  %5 = llvm.icmp "uge" %3, %4 : i16
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

def test21_before := [llvm|
{
^0(%arg146 : i32, %arg147 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg147, %0 : i32
  %2 = llvm.xor %arg146, %0 : i32
  %3 = llvm.or %2, %1 : i32
  %4 = llvm.or %arg146, %arg147 : i32
  %5 = llvm.xor %3, %4 : i32
  "llvm.return"(%5) : (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) -> ()
}
]

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

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

@[reducible]
instance : DialectDenote Ex where
  denote
    | .cst n, _, _ => n ::ₕ .nil
    | .add, .cons (a : Nat) (.cons b .nil), _ => a + b ::ₕ .nil
    | .beq, .cons (a : Nat) (.cons b .nil), _ => (a == b) ::ₕ .nil

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

Sum.inl in Init.Core

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

instance : Refinement GlobalState where
  IsRefinedBy s t :=
    s.alloc ⊑ t.alloc ∧ s.mem ⊑ t.mem

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

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

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

BitVec.clz in Init.Data.BitVec.Basic

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

def passriscv64_optimized_const (fileName : String) : IO UInt32 := do
    let icom? ← Com.parseFromFile LLVMPlusRiscV fileName
    match icom? with
    | none => return 1
    | some (Sigma.mk _Γ ⟨eff, ⟨retTy, c⟩⟩) =>
      match eff with
      | EffectKind.pure =>
        match retTy with
        | [Ty.llvm (.bitvec _w)]  =>
           
          let lowered := selectionPipeFuelWithCSEWithOptConst 150 c true
          IO.println <| lowered.printModule
          return 0
        | _ =>
        IO.println s!" debug: WRONG RETURN TYPE : expected Ty.llvm (Ty.bitvec 64) "
        return 1
      | _ =>
      IO.println s!" debug: WRONG EFFECT KIND : expected pure program "
      return 1

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

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

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

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

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

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

instance instHRefinementOfRefinement [Refinement α] : HRefinement α α where
  IsRefinedBy := Refinement.IsRefinedBy

def solve
[H : HydrableSolve parsedExpr genPred genExpr]
  (bvExpr : BoolExpr genPred) : GeneralizerStateM parsedExpr genPred (Option (Std.HashMap Nat BVExpr.PackedBitVec)) := do
    let state ← get
    let allVars := Std.HashMap.union state.parsedLogicalExpr.state.inputVarIdToVariable state.parsedLogicalExpr.state.symVarIdToVariable

    let bitVecType (w : Nat) :=  mkApp (mkConst ``BitVec) (mkNatLit w)

    let nameTypeCombo : List (Name × Expr) := allVars.values.map (λ n => (n.name, bitVecType n.width))

    let res ←
      withLocalDeclsDND nameTypeCombo.toArray fun _ => do
        let mVar ← withTraceNode `Generalize (fun _ => return m!"Converted bvExpr to expr (size : {getGenLogicalExprSize bvExpr})") do
          let mut expr : Expr ←
            genLogicalExprToExpr (state.parsedLogicalExpr : ParsedLogicalExpr parsedExpr genPred) (bvExpr : BoolExpr genPred)
          Lean.Meta.check expr

          expr ← mkEq expr (mkConst ``Bool.false) 
          Lean.Meta.check expr

          mkFreshExprMVar expr

        let cfg: BVDecideConfig := {timeout := 60, embeddedConstraintSubst := false}

        IO.FS.withTempFile fun _ lratFile => do
          let ctx ← (BVDecide.Frontend.TacticContext.new lratFile cfg)
          let res ← BVDecide.Frontend.bvDecide' mVar.mvarId! ctx

          match res with
          | .ok _ => pure none
          | .error counterExample =>
            let nameToId : Std.HashMap Name Nat := Std.HashMap.ofList (allVars.toList.map (λ (id, var) => (var.name, id)))
            let mut assignment : Std.HashMap Nat BVExpr.PackedBitVec := Std.HashMap.emptyWithCapacity
            for (var, val) in counterExample.equations do
              let name := ((← getLCtx).get! var.fvarId!).userName
              assignment := assignment.insert nameToId[name]! val
            pure (some assignment)
    return res

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

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

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

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

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

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

def IntToString (i: Int): String := i.repr

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

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

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

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

def or_not_xor_common_op_commute5_after := [llvm|
{
^0(%arg92 : i8, %arg93 : i8, %arg94 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.and %arg93, %arg92 : i8
  %2 = llvm.xor %1, %0 : i8
  %3 = llvm.or %arg94, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

def or_simplify_ugt_after := [llvm|
{
^0(%arg11 : i8, %arg12 : i8):
  %0 = llvm.mlir.constant(-2 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.and %arg12, %0 : i8
  %3 = llvm.or %arg11, %arg12 : i8
  %4 = llvm.or %3, %1 : i8
  %5 = llvm.icmp "ugt" %4, %2 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

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

def select_constant_cmp : List (Σ Γ, LLVMPeepholeRewriteRefine 64  Γ) :=
  [⟨_, select_constant_cmp_true⟩,
  ⟨_, select_constant_cmp_false⟩]

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

List.Perm in Init.Data.List.Basic

def different_size_sext_sext_ule_before := [llvm|
{
^0(%arg8 : i7, %arg9 : i4):
  %0 = llvm.sext %arg8 : i7 to i25
  %1 = llvm.sext %arg9 : i4 to i25
  %2 = llvm.icmp "ule" %0, %1 : i25
  "llvm.return"(%2) : (i1) -> ()
}
]

def IsTotal (m : Mapping Γ Δ) : Prop :=
  ∀ {t} v, ⟨t, v⟩ ∈ m

def lowmask_add_zext_before := [llvm|
{
^0(%arg235 : i8, %arg236 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.zext %arg235 : i8 to i32
  %2 = llvm.add %1, %arg236 : i32
  %3 = llvm.and %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

def ne_basic_equal_5_before := [llvm|
{
^0(%arg32 : i8, %arg33 : i8):
  %0 = llvm.mlir.constant(-5 : i8) : i8
  %1 = llvm.mlir.constant(5 : i8) : i8
  %2 = llvm.add %arg32, %0 : i8
  %3 = llvm.icmp "ne" %arg32, %1 : i8
  %4 = llvm.icmp "ule" %2, %arg33 : i8
  %5 = llvm.and %3, %4 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

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

def shl_lshr_eq_amt_multi_use_after := [llvm|
{
^0(%arg7 : i44):
  %0 = llvm.mlir.constant(33 : i44) : i44
  %1 = llvm.mlir.constant(2047 : i44) : i44
  %2 = llvm.shl %arg7, %0 : i44
  %3 = llvm.and %arg7, %1 : i44
  %4 = llvm.or disjoint %2, %3 : i44
  "llvm.return"(%4) : (i44) -> ()
}
]

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

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

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

Array in Init.Prelude

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

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

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

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

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

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

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

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

instance finEnumUnit : FinEnum Unit where
  card := 1
  equiv := {
    toFun := fun _ => 0,
    invFun := fun (_ : Fin 1) => (),
    left_inv := by admit /- proof elided -/

def TotalOrder.getIxD {α : Type} [Hashable α] [BEq α]  (ix : Nat) (d : α) (toOrder : TotalOrder α) : α :=
  toOrder.ix2val.getD ix d

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

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

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

instance : Repr (Var Γ t) where
  reprPrec v _ := f!"%{Γ.toList.length - v.val - 1}"

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

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

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

def uaddo_commute4_after := [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 "ugt" %arg22, %1 : i32
  %4 = "llvm.select"(%3, %arg24, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def PR42691_6_before := [llvm|
{
^0(%arg333 : i32):
  %0 = llvm.mlir.constant(-2147483647 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.icmp "ult" %arg333, %0 : i32
  %3 = llvm.icmp "eq" %arg333, %1 : i32
  %4 = llvm.or %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

def types : List d.Ty := args.toList.map Sigma.fst

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

def iso_unary (a : Stream' (BitVec 1)) : Stream' (Vector (BitVec 1) 1) :=
    fun n =>
      {toArray := [a n].toArray, size_toArray := by admit /- proof elided -/

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

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

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

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

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

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

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

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

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

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

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

HPow.hPow in Init.Prelude

def pr89516_before := [llvm|
{
^0(%arg0 : i8, %arg1 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.icmp "slt" %arg1, %0 : i8
  %3 = llvm.shl %1, %arg0 overflow<nuw> : i8
  %4 = llvm.srem %1, %3 : i8
  %5 = llvm.add %4, %3 overflow<nuw> : i8
  %6 = "llvm.select"(%2, %5, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%6) : (i8) -> ()
}
]

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

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

def srem {w : Nat} (x y : IntW w) : IntW w := do
  let x' ← x
  let y' ← y
  srem? x' y'

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

@[simps]
def proj (M: NFA (BitVec n1) σ) (f : Fin n2 → Fin n1) : NFA (BitVec n2) σ where
  start := M.start
  accept := M.accept
  step q a := { q' | ∃ a', a'.transport f = a ∧ q' ∈ M.step q a' }

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

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

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

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

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

def absdiff2_before := [llvm|
{
^0(%arg0 : i64, %arg1 : i64):
  %0 = llvm.icmp "ugt" %arg0, %arg1 : i64
  %1 = llvm.sext %0 : i1 to i64
  %2 = llvm.sub %arg1, %arg0 : i64
  %3 = llvm.xor %2, %1 : i64
  %4 = llvm.sub %3, %1 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

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

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

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

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

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

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

def alive_AndOrXor_2647_src  (w : Nat)   :=
[llvm( w )| {
^bb0(%a : _, %b : _):
  %v1 = llvm.and %a, %b
  %v2 = llvm.xor %a, %b
  %v3 = llvm.xor %v1, %v2
  llvm.return %v3
}]

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

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

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

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

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

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

def select_icmp_ne_0_and_32_xor_4096_after := [llvm|
{
^0(%arg199 : i32, %arg200 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(4096 : i32) : i32
  %2 = llvm.shl %arg199, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.xor %3, %arg200 : i32
  %5 = llvm.xor %4, %1 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

instance : AndOp BitStream := ⟨map₂ Bool.and⟩

Equivalence.mk in Init.Core

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

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

def sdiv_icmp1_before := [llvm|
{
^0(%arg18 : i64):
  %0 = llvm.mlir.constant(5) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.sdiv exact %arg18, %0 : i64
  %3 = llvm.icmp "eq" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def Factor.denoteFin {w : Nat} (f : Factor) (xs : EnvFin w f.numVars) : Nat := f.reflectFin xs |>.toNat

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

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

def test8_after := [llvm|
{
^0(%arg1 : i128):
  %0 = llvm.mlir.constant(170141183460469231731687303715884105600 : i128) : i128
  %1 = llvm.xor %arg1, %0 : i128
  "llvm.return"(%1) : (i128) -> ()
}
]

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

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

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

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

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

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

def and_shl_before := [llvm|
{
^0(%arg644 : i8, %arg645 : i8, %arg646 : i8, %arg647 : i8):
  %0 = llvm.shl %arg644, %arg647 : i8
  %1 = llvm.shl %arg645, %arg647 : i8
  %2 = llvm.and %0, %arg646 : i8
  %3 = llvm.and %1, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

def alive_Select_1100_tgt  (w : Nat)  :=
[llvm( w )| {
^bb0(%Y : _, %X : _):
  %v1 = llvm.copy %X
  llvm.return %v1
}]

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 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 eqToZero (expr: FpExpr w) : FpPredicate :=
  FpPredicate.bin expr FpBinaryPredKind.eq (zero w)

def test9_before := [llvm|
{
^0(%arg200 : i8):
  %0 = llvm.mlir.constant(123 : i8) : i8
  %1 = llvm.mlir.constant(34 : i8) : i8
  %2 = llvm.xor %arg200, %0 : i8
  %3 = llvm.icmp "eq" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

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

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

def Tensor1d.map [Inhabited α] (f : α → α) (t : Tensor1d α) : Tensor1d α where
  size := t.size
  val := fun ix => if ix < t.size then f (t.val ix) else default
  spec := by admit /- proof elided -/

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

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

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

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

@[simp_denote]
def and_llvm_1 := [LV| {
  ^entry (%lhs: i1, %rhs: i1 ):
  %1 = llvm.and %lhs, %rhs : i1
  llvm.return %1 : 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 shl_const_op1_sub_const_op0_after := [llvm|
{
^0(%arg2 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(336 : i32) : i32
  %2 = llvm.shl %arg2, %0 : i32
  %3 = llvm.sub %1, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

instance : DialectSignature LLVM where
  signature op := ⟨op.sig, [], [op.outTy], .pure⟩

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

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

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

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

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

def redundant_binop_in_equality_XXorYNeX : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64, %y: i64):
      %0 = llvm.xor %x, %y : i64
      %1 = llvm.icmp.ne %0, %x : i64
      llvm.return %1 : i1
  }]
  rhs := [LV| {
    ^entry (%x: i64, %y: i64):
      %0 = llvm.mlir.constant (0) : i64
      %1 = llvm.icmp.ne %y, %0 : i64
      llvm.return %1 : i1
  }]

instance : Hashable Empty where
  hash x := x.elim

abbrev WidthToExprMap := Std.HashMap Expr Expr

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

def main14_logical_after := [llvm|
{
^0(%arg15 : i32):
  %0 = llvm.mlir.constant(32896 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(2 : i32) : i32
  %3 = llvm.mlir.constant(1 : i32) : i32
  %4 = llvm.and %arg15, %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 test24_before := [llvm|
{
^0(%arg183 : i32, %arg184 : i32):
  %0 = llvm.xor %arg184, %arg183 : i32
  %1 = llvm.icmp "ne" %0, %arg183 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

def different_size_zext_zext_ugt_after := [llvm|
{
^0(%arg28 : i7, %arg29 : i4):
  %0 = llvm.zext %arg29 : i4 to i7
  %1 = llvm.icmp "ugt" %arg28, %0 : i7
  "llvm.return"(%1) : (i1) -> ()
}
]

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

instance : HydrableParseExprs ParsedBVExpr GenBVPred where
  parseExprs := parseExprs

def ashr_lshr_cst2_before := [llvm|
{
^0(%arg103 : i32, %arg104 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.icmp "sgt" %arg103, %0 : i32
  %3 = llvm.lshr %arg103, %1 : i32
  %4 = llvm.ashr exact %arg103, %1 : i32
  %5 = "llvm.select"(%2, %3, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def Expr.mkPredicateEvalEqFSM (p : Expr) : Expr :=
    mkApp (.const ``predicateEvalEqFSM []) p

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

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

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

Lean.Meta.getFVarLocalDecl in Lean.Meta.Basic

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

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

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

def MetaLLVM.printType : (MetaLLVM φ).Ty → String
  | .bitvec (.concrete w)  => s!"i{w}"
  | .bitvec (.mvar ⟨i, _⟩) => s!"i$\{%{i}}"

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

def foo1_or_signbit_lshr_after := [llvm|
{
^0(%arg127 : i32, %arg128 : i32, %arg129 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(-2147483648 : i32) : i32
  %2 = llvm.shl %0, %arg128 overflow<nuw> : i32
  %3 = llvm.lshr exact %1, %arg129 : i32
  %4 = llvm.or %2, %3 : i32
  %5 = llvm.and %arg127, %4 : i32
  %6 = llvm.icmp "eq" %5, %4 : i32
  "llvm.return"(%6) : (i1) -> ()
}
]

def n11_before := [llvm|
{
^0(%arg5 : i32, %arg6 : i16):
  %0 = llvm.mlir.constant(30 : i16) : i16
  %1 = llvm.mlir.constant(-31 : i16) : i16
  %2 = llvm.sub %0, %arg6 : i16
  %3 = llvm.zext %2 : i16 to i32
  %4 = llvm.shl %arg5, %3 : i32
  %5 = llvm.trunc %4 : i32 to i16
  %6 = llvm.add %arg6, %1 : i16
  %7 = llvm.shl %5, %6 : i16
  "llvm.return"(%7) : (i16) -> ()
}
]

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

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

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

def getWidthRelations : GeneralizerStateM ParsedBVExpr GenBVPred (Option (BoolExpr GenBVPred)) := do
    let state ← get
    let parsedLogicalExprState :=  state.parsedLogicalExpr.state

    let processingWidth := state.processingWidth

    if parsedLogicalExprState.widthIdToVariable.size <= 1 then
      return none

    let relations := findRelationsBetweenWidths parsedLogicalExprState.widthIdToVariable processingWidth
    return some relations

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

def sdiv_mul_shl_nsw_before := [llvm|
{
^0(%arg193 : i5, %arg194 : i5, %arg195 : i5):
  %0 = llvm.mul %arg193, %arg194 overflow<nsw> : i5
  %1 = llvm.shl %arg193, %arg195 overflow<nsw> : i5
  %2 = llvm.sdiv %0, %1 : i5
  "llvm.return"(%2) : (i5) -> ()
}
]

def composeBinary
    (p : FSM Bool)
    {t₁ t₂ : Term}
    (q₁ : FSMTermSolution t₁)
    (q₂ : FSMTermSolution t₂) :
    FSM (Fin (max t₁.arity t₂.arity)) := composeBinaryAux p q₁.toFSM q₂.toFSM

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

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

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

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

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

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

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

@[simp]
def ofNat_eq_concrete (x : Nat) :
    (OfNat.ofNat x) = (ConcreteOrMVar.concrete x : ConcreteOrMVar Nat φ) := rfl

def const (a : α) (_b : β) : α := a

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

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

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

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

def fake_sext_after := [llvm|
{
^0(%arg166 : i3):
  %0 = llvm.mlir.constant(2 : i3) : i3
  %1 = llvm.lshr %arg166, %0 : i3
  %2 = llvm.zext nneg %1 : i3 to i18
  "llvm.return"(%2) : (i18) -> ()
}
]

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

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

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

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

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

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

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

def shl_and_after := [llvm|
{
^0(%arg71 : i8, %arg72 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.shl %arg71, %0 : i8
  %3 = llvm.shl %arg72, %1 : i8
  %4 = llvm.and %2, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

instance : Inhabited (Ty q n) := ⟨Ty.index⟩

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

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

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

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

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

def and_sext_sext_after := [llvm|
{
^0(%arg52 : i8, %arg53 : i4):
  %0 = llvm.sext %arg53 : i4 to i8
  %1 = llvm.and %arg52, %0 : i8
  %2 = llvm.sext %1 : i8 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

def test15_after := [llvm|
{
^0(%arg40 : i32, %arg41 : i32):
  %0 = llvm.mlir.constant(1431655766 : i32) : i32
  %1 = llvm.or %arg40, %0 : i32
  %2 = llvm.sub %arg41, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

def substituteBVExpr (bvExpr: GenBVExpr w) (assignment: Std.HashMap Nat (SubstitutionValue GenBVExpr)) : GenBVExpr w :=
    match bvExpr with
    | .var idx =>
      if assignment.contains idx then
          let value := assignment[idx]!
          match value with
          | .genExpr (w := wbv) bv =>
            let h : w = wbv := sorry
            h ▸ bv
          | .packedBV packedBitVec =>  GenBVExpr.const (BitVec.ofNat w packedBitVec.bv.toNat)
      else GenBVExpr.var idx
    | .bin lhs op rhs =>
        GenBVExpr.bin (substituteBVExpr lhs assignment) op (substituteBVExpr rhs assignment)
    | .un op operand =>
        GenBVExpr.un op (substituteBVExpr operand assignment)
    | .shiftLeft lhs rhs =>
        GenBVExpr.shiftLeft (substituteBVExpr lhs assignment) (substituteBVExpr rhs assignment)
    | .shiftRight lhs rhs =>
        GenBVExpr.shiftRight (substituteBVExpr lhs assignment) (substituteBVExpr rhs assignment)
    | .arithShiftRight lhs rhs =>
        GenBVExpr.arithShiftRight (substituteBVExpr lhs assignment) (substituteBVExpr rhs assignment)
    | .signExtend w expr =>
        GenBVExpr.signExtend w (substituteBVExpr expr assignment)
    | .zeroExtend w expr =>
        GenBVExpr.zeroExtend w (substituteBVExpr expr assignment)
    | .truncate w expr =>
        GenBVExpr.truncate w (substituteBVExpr expr assignment)
    | .extract start len expr =>
        GenBVExpr.extract start len (substituteBVExpr expr assignment)
    | e => e

def test11_before := [llvm|
{
^0(%arg69 : i32, %arg70 : i32):
  %0 = llvm.mlir.constant(31 : i128) : i128
  %1 = llvm.zext %arg69 : i32 to i128
  %2 = llvm.zext %arg70 : i32 to i128
  %3 = llvm.and %2, %0 : i128
  %4 = llvm.shl %1, %3 : i128
  %5 = llvm.trunc %4 : i128 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

def shift_xor_multiuse_cmp_xor_after := [llvm|
{
^0(%arg32 : i32, %arg33 : i32, %arg34 : i32, %arg35 : 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 %arg32, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.xor %arg33, %2 : i32
  %6 = "llvm.select"(%4, %5, %arg33) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg35, %arg34) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %8 = llvm.mul %6, %7 : i32
  %9 = llvm.mul %8, %5 : i32
  "llvm.return"(%9) : (i32) -> ()
}
]

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

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

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

def test2_after := [llvm|
{
^0(%arg4 : i16, %arg5 : i16):
  %0 = llvm.add %arg4, %arg5 : i16
  "llvm.return"(%0) : (i16) -> ()
}
]

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

def t6_shl_before := [llvm|
{
^0(%arg31 : i32, %arg32 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(-2 : i32) : i32
  %2 = llvm.sub %0, %arg32 : i32
  %3 = llvm.shl %arg31, %2 overflow<nuw> : i32
  %4 = llvm.add %arg32, %1 : i32
  %5 = llvm.shl %3, %4 overflow<nsw> : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

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

def alive_AddSub_1152_src   :=
[llvm()| {
^bb0(%y : i1, %x : i1):
  %v1 = llvm.add %x, %y : i1
  llvm.return %v1 : i1
}]

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

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

instance : Inhabited (Op φ) where
  default := Op.empty "INHABITANT"

def mul16_low_miss_shift_amount_before := [llvm|
{
^0(%arg4 : i16, %arg5 : i16):
  %0 = llvm.mlir.constant(127 : i16) : i16
  %1 = llvm.mlir.constant(8 : i16) : i16
  %2 = llvm.and %arg4, %0 : i16
  %3 = llvm.lshr %arg4, %1 : i16
  %4 = llvm.and %arg5, %0 : i16
  %5 = llvm.lshr %arg5, %1 : i16
  %6 = llvm.mul %5, %2 : i16
  %7 = llvm.mul %4, %3 : i16
  %8 = llvm.mul %4, %2 : i16
  %9 = llvm.add %6, %7 : i16
  %10 = llvm.shl %9, %1 : i16
  %11 = llvm.add %10, %8 : i16
  "llvm.return"(%11) : (i16) -> ()
}
]

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

Lean.Name.mkSimple in Init.Prelude

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

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

OptionT.fail in Init.Control.Option

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

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

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

def alive_AndOrXor_1683_1_tgt :=
[sllvm| {
^bb0(%a : i64, %b : i64):
  %v1 = llvm.icmp.ugt %a, %b : i64
  %v2 = llvm.icmp.eq %a, %b : i64
  %v3 = llvm.icmp.uge %a, %b : i64
  llvm.return %v3 : i1
}]

def VarList (Γ : Context Ty) (tys : List Ty) : Type :=
  { vs : List VarName // vs.length = tys.length ∧ ∀ v ∈ vs.zip tys, Γ.hasType v.fst v.snd }

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

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

List.keys in Mathlib.Data.List.Sigma

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

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

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

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

def srl_match : List (Σ Γ, Σ ty, PeepholeRewrite LLVMPlusRiscV Γ ty) := [
  
  
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_srl_lower_riscv_exact_64),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_srl_lower_riscv_64),
]

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

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

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

def fork (a : Γ.Var (.tokenstream)) : Expr (DC) Γ .pure (.tokenstream2) :=
  Expr.mk
    (op := .fork)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .cons a <| .nil)
    (regArgs := .nil)

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

def t2_before := [llvm|
{
^0(%arg202 : i8, %arg203 : i8):
  %0 = llvm.mlir.constant(-42 : i8) : i8
  %1 = llvm.shl %0, %arg203 : i8
  %2 = llvm.sub %arg202, %1 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def not_mul_of_pow2_commute_after := [llvm|
{
^0(%arg75 : i32, %arg76 : i32):
  %0 = llvm.mlir.constant(12 : i32) : i32
  %1 = llvm.mlir.constant(255 : i32) : i32
  %2 = llvm.mlir.constant(3060 : i32) : i32
  %3 = llvm.and %arg75, %0 : i32
  %4 = llvm.and %arg76, %1 : i32
  %5 = llvm.mul %4, %3 overflow<nsw,nuw> : i32
  %6 = llvm.icmp "ugt" %5, %2 : i32
  "llvm.return"(%6) : (i1) -> ()
}
]

def test2_before := [llvm|
{
^0(%arg208 : i1):
  %0 = llvm.xor %arg208, %arg208 : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

def t5_ugt_slt_0_before := [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.select"(%2, %arg52, %arg53) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.icmp "ugt" %arg51, %1 : i32
  %5 = "llvm.select"(%4, %3, %arg51) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

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

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

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

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

def getWidth (expr : Expr) : MetaM (Option Nat) := do
  match_expr expr with
  | BitVec n => getNatValue? n
  | _ => pure none

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 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 IndexInvariant (f : LoopBody t) : Prop :=
  ∀ (i j : Int) (v : t), f i v = f j v

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

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

def test44_before := [llvm|
{
^0(%arg144 : i8):
  %0 = llvm.mlir.constant(1234 : i16) : i16
  %1 = llvm.zext %arg144 : i8 to i16
  %2 = llvm.or %1, %0 : i16
  %3 = llvm.zext %2 : i16 to i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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

def xor_sge_after := [llvm|
{
^0(%arg16 : i8, %arg17 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mul %arg16, %arg16 : i8
  %2 = llvm.or %arg17, %0 : i8
  %3 = llvm.xor %2, %1 : i8
  %4 = llvm.icmp "slt" %3, %1 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

inductive Ty
| tokenstream : Ty
| tokenstream2 : Ty
| valuestream (w : Nat) : Ty 
| valuestream2 (w : Nat) : Ty 
| valuetokenstream (w : Nat) : Ty 
| variadicvaluetokenstream (w : Nat) : Ty 
deriving Inhabited, DecidableEq, Repr, Lean.ToExpr

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

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

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

abbrev DCPlus : Dialect where
  Op := Op
  Ty := Ty

def_signature for DCPlus where
  | .fst => (Ty.tokenstream2) → (Ty.tokenstream)
  | .fstVal t => (Ty.valuetokenstream t) → Ty.valuestream t
  | .fstVal' t => (Ty.variadicvaluetokenstream t) → Ty.valuestream t
  | .fstValPure t => (Ty.valuestream2 t) → Ty.valuestream t
  | .snd => (Ty.tokenstream2) → (Ty.tokenstream)
  | .sndValPure t => (Ty.valuestream2 t) → Ty.valuestream t
  | .pair w => (Ty.valuestream w, Ty.valuestream w) → Ty.valuestream2 w
  | .sndVal t => (Ty.valuetokenstream t) → Ty.tokenstream
  | .sndVal' t => (Ty.variadicvaluetokenstream t) → Ty.valuestream t
  | .tokVal' t => (Ty.variadicvaluetokenstream t) → Ty.tokenstream
  | .merge => (Ty.tokenstream, Ty.tokenstream) → Ty.valuestream 1
  | .branch => (Ty.valuestream 1, Ty.tokenstream) → Ty.tokenstream2
  | .fork => (Ty.tokenstream) → Ty.tokenstream2
  | .forkVal => (Ty.valuestream 1) → Ty.valuestream2 1
  | .join => (Ty.tokenstream, Ty.tokenstream) → Ty.tokenstream
  | .mux => (Ty.tokenstream, Ty.tokenstream, Ty.valuestream 1) → Ty.tokenstream
  | .muxVal => (Ty.valuestream 1, Ty.valuestream 1, Ty.valuestream 1) → Ty.valuestream 1
  | .sink => (Ty.tokenstream) → Ty.tokenstream
  | .source => () → Ty.tokenstream
  | .sourceOnes => () → Ty.valuestream 1
  | .cMerge => (Ty.tokenstream, Ty.tokenstream) → Ty.valuetokenstream 1
  | .supp => (Ty.valuestream 1, Ty.tokenstream) → Ty.tokenstream
  | .not => (Ty.valuestream 1) → Ty.valuestream 1

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

def mul_add_to_mul_3_after := [llvm|
{
^0(%arg30 : i16):
  %0 = llvm.mlir.constant(5 : i16) : i16
  %1 = llvm.mul %arg30, %0 : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

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

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

Mod.mod in Init.Prelude

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

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

def main7c_logical_after := [llvm|
{
^0(%arg69 : i32, %arg70 : i32, %arg71 : i32):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.and %arg70, %arg69 : i32
  %2 = llvm.icmp "ne" %arg70, %1 : i32
  %3 = llvm.and %arg71, %arg69 : i32
  %4 = llvm.icmp "ne" %arg71, %3 : 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) -> ()
}
]

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

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

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

def src_is_notmask_lshr_shl_fail_mismatch_shifts_after := [llvm|
{
^0(%arg58 : i8, %arg59 : i8, %arg60 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(123 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.lshr %0, %arg59 : i8
  %4 = llvm.shl %3, %arg60 : i8
  %5 = llvm.xor %arg58, %1 : i8
  %6 = llvm.and %5, %4 : i8
  %7 = llvm.icmp "eq" %6, %2 : i8
  "llvm.return"(%7) : (i1) -> ()
}
]

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

def shl_and_add_after := [llvm|
{
^0(%arg156 : i8, %arg157 : i8):
  %0 = llvm.mlir.constant(59 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.and %arg157, %0 : i8
  %3 = llvm.add %arg156, %2 : i8
  %4 = llvm.shl %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def smear_set_bit_after := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(24 : i32) : i32
  %1 = llvm.mlir.constant(31 : i32) : i32
  %2 = llvm.shl %arg6, %0 : i32
  %3 = llvm.ashr %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

@[simp_denote]
def riscvArgsFromHybrid_cons_eq.lemma {ty  : RISCV64.RV64.Ty} {tys : List RISCV64.RV64.Ty}
    (x : TyDenote.toType (LLVMRiscV.Ty.riscv ty))
    (xs : HVector TyDenote.toType (tys.map LLVMRiscV.Ty.riscv)) :
  (riscvArgsFromHybrid (tys := ty :: tys) (HVector.cons x xs)) =
  HVector.cons (f := TyDenote.toType) (a := ty) (as := tys) x (riscvArgsFromHybrid xs)
   := rfl

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

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

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

@[simp] def evalv [DecidableEq α] : ∀ (c : Circuit α), (∀ a ∈ vars c, Bool) → Bool
  | tru, _ => true
  | fals, _ => false
  | var b x, f => if b then f x (by admit /- proof elided -/
  ) else !(f x (by admit /- proof elided -/
  ))
  | and c₁ c₂, f => (evalv c₁ (fun i hi => f i (by admit /- proof elided -/
  ))) &&
    (evalv c₂ (fun i hi => f i (by admit /- proof elided -/
    )))
  | or c₁ c₂, f => (evalv c₁ (fun i hi => f i (by admit /- proof elided -/
  ))) ||
    (evalv c₂ (fun i hi => f i (by admit /- proof elided -/
    )))
  | xor c₁ c₂, f => Bool.xor (evalv c₁ (fun i hi => f i (by admit /- proof elided -/
  )))
    (evalv c₂ (fun i hi => f i (by admit /- proof elided -/
    )))

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

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

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

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

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

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

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

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

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

def shl_mask_weird_type_before := [llvm|
{
^0(%arg4 : i37):
  %0 = llvm.mlir.constant(255 : i37) : i37
  %1 = llvm.mlir.constant(8 : i37) : i37
  %2 = llvm.and %arg4, %0 : i37
  %3 = llvm.shl %2, %1 : i37
  %4 = llvm.or %2, %3 : i37
  "llvm.return"(%4) : (i37) -> ()
}
]

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

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

def test14_after := [llvm|
{
^0(%arg42 : i32, %arg43 : i32):
  %0 = llvm.mlir.constant(1431655766 : i32) : i32
  %1 = llvm.and %arg42, %0 : i32
  %2 = llvm.sub %arg43, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

def test15_before := [llvm|
{
^0(%arg24 : i1):
  %0 = llvm.mlir.constant(3 : i45) : i45
  %1 = llvm.mlir.constant(1 : i45) : i45
  %2 = llvm.mlir.constant(2 : i45) : i45
  %3 = "llvm.select"(%arg24, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i45, i45) -> i45
  %4 = llvm.shl %3, %2 : i45
  "llvm.return"(%4) : (i45) -> ()
}
]

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

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

Lean.Meta.State in Lean.Meta.Basic

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

def 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 test2_before := [llvm|
{
^0(%arg12 : i15):
  %0 = llvm.mlir.constant(-1 : i15) : i15
  %1 = llvm.and %arg12, %0 : i15
  "llvm.return"(%1) : (i15) -> ()
}
]

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

@[simp]
def tripleBind [Monad m] (f : α → β → γ → m δ) (triple : (m α × m β × m γ)) : m δ := do
  let (fstM,sndM,trdM) := triple
  let (fst,snd,trd) := (← fstM,← sndM,← trdM)
  f fst snd trd

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 invert_both_cmp_operands_sub_after := [llvm|
{
^0(%arg36 : i32, %arg37 : i32):
  %0 = llvm.mlir.constant(-43 : i32) : i32
  %1 = llvm.add %arg36, %arg37 : i32
  %2 = llvm.icmp "ugt" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

def Expr.mkVerifyCircuit (c cert : Expr) : MetaM Expr :=
  mkAppM ``Circuit.verifyCircuit #[c, cert]

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

def CNFA.autWidth (wp : WidthPredicate) (n : Nat) : CNFA 0 :=
  ⟨RawCNFA.autWidth wp n, RawCNFA.autWidth_wf⟩

IntCast in Init.Data.Int.Basic

List.lookup in Init.Data.List.Basic

Eq in Init.Prelude
</all_available_defs>

<all_available_lemmas>
List.mem_attach in Init.Data.List.Attach
List.mem_map in Init.Data.List.Lemmas
List.mem_range in Init.Data.List.Nat.Range
forall_exists_index in Init.PropLemmas
true_and in Init.SimpLemmas

lemma eval_map {c : Circuit α} {f : α → β} {g : β → Bool} :
    eval (map c f) g = eval c (λ x => g (f x))

@[simp]
theorem eval_bigOr_eq_false_iff
    (cs : List (Circuit α)) (env : α → Bool):
    (Circuit.bigOr cs).eval env = false ↔
    (∀ (c : Circuit α), c ∈ cs → c.eval env = false)

@[simp]
theorem Vars.castLe_inputs_eq_inputs {n i m : Nat} (hi : i < n) (hnm : n ≤ m) :
  (Vars.inputN inp i hi : Vars σ ι n).castLe hnm =
  Vars.inputN inp i (by omega)

@[simp]
theorem Vars.castLe_stateN_eq_stateN  {n i m : Nat} (hi : i ≤ n) (hnm : n ≤ m) :
  (Vars.stateN s i : Vars σ ι n).castLe hnm =
  Vars.stateN s i (hin := by omega)

@[simp]
theorem Vars.castLe_castLe_eq_castLe_self {α : Type _} {p q r : Nat}
  (v : Vars α σ p) (h : p ≤ q) (h' : q ≤ r) :
    (v.castLe h).castLe h' = v.castLe (by omega)

theorem main4f_like_logical_thm.extracted_1._12 : ∀ (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 0#1

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

theorem not_logicalAnd_not_op1_proof : not_logicalAnd_not_op1_before ⊑ not_logicalAnd_not_op1_after

theorem test12_proof : test12_before ⊑ test12_after

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

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

theorem ashr_mul_thm (e e_1 : IntW 8) :
  trunc 16 (ashr (mul (sext 20 e_1) (sext 20 e)) (const? 20 8)) ⊑
    ashr (mul (sext 16 e_1) (sext 16 e) { «nsw» := true, «nuw» := false }) (const? 16 8)

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

theorem slt_swap_and_max_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x <ₛ x_1) &&& ofBool (x == 127#8) = 0#1

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

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

theorem max_of_min_swap_thm (e : IntW 32) :
  select
      (icmp IntPred.sgt
        (select (icmp IntPred.slt e (const? 32 0)) (const? 32 (-1)) (LLVM.xor e (const? 32 (-1))))
        (const? 32 (-1)))
      (select (icmp IntPred.slt e (const? 32 0)) (const? 32 (-1)) (LLVM.xor e (const? 32 (-1)))) (const? 32 (-1)) ⊑
    const? 32 (-1)

theorem ashr_ult_11_proof : ashr_ult_11_before ⊑ ashr_ult_11_after

theorem samesign_proof : samesign_before ⊑ samesign_after

theorem e_2320 :
    4 *  ~~~(d ^^^ (e ||| f)) + 3 * (e ||| (d &&& f)) - 3 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 7 * (f ||| (d &&& e)) + 11 * (d ^^^ (e &&& f)) + 1 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) - 5 *  ~~~(d &&&  ~~~e) - 11 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 7 * (e ^^^ (d ||| f)) - 11 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 7 * (d ^^^ (e ^^^ f)) - 1 * ((d &&& f) ^^^ (e ||| f)) - 1 * (f ^^^  ~~~(d ||| (e &&& f))) - 6 * (d ||| e) + 5 *  ~~~(d &&& ( ~~~e &&& f)) - 1 * (f ^^^ ( ~~~d ||| (e ||| f))) + 2 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 2 *  ~~~(d ||| ( ~~~e &&& f)) + 3 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 1 * (e |||  ~~~(d ^^^ f)) + 11 * ( ~~~d ||| ( ~~~e ||| f)) + 7 * (f ^^^ (d &&& e)) + 11 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 5 *  ~~~(d |||  ~~~e) + 1 * (f |||  ~~~(d ^^^ e)) + 2 *  ~~~(d |||  ~~~f) - 1 * (f ^^^ ( ~~~d &&& (e ||| f))) + 5 * (e ^^^ (d &&& ( ~~~e ||| f))) - 1 * (e ^^^ ( ~~~d &&& (e ||| f))) - 6 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 1 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 2 * (d &&& ( ~~~e ||| f)) + 4 * ((d &&& f) |||  ~~~(e ||| f)) - 5 * ( ~~~e &&&  ~~~(d ^^^ f)) - 2 * (e |||  ~~~(d ||| f)) - 3 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 4 * ( ~~~d &&& ( ~~~e ||| f)) - 2 * (e ^^^  ~~~(d &&& f)) + 5 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * d + 2 * (e ^^^ ( ~~~d ||| (e ^^^ f))) + 4 * ((d &&& e) |||  ~~~(e |||  ~~~f)) - 7 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 11 * (f ^^^ ( ~~~d ||| (e &&& f))) + 11 *  ~~~(e ^^^ f) - 5 * (d ^^^ e) - 1 * (d ||| (e &&& f)) - 11 * (d ^^^ ( ~~~e ||| f)) + 4 *  ~~~d + 4 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 6 *  ~~~(d ^^^ e) + 1 * (f ||| (d ^^^ e)) + 3 * e - 1 *  ~~~(e |||  ~~~f) + 2 * (f ^^^ (d ||| (e &&& f))) + 1 * ( ~~~e &&& (d ^^^ f)) - 14 *  ~~~(d ||| (e ||| f)) - 8 *  ~~~(d ||| ( ~~~e ||| f)) - 32 *  ~~~( ~~~d ||| (e ||| f)) - 9 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 11 * ( ~~~d &&& ( ~~~e &&& f)) - 57 * ( ~~~d &&& (e &&& f)) - 33 * (d &&& ( ~~~e &&& f)) - 16 * (d &&& (e &&& f)) =  - 1 * (d |||  ~~~f)

theorem scalar_i32_shl_and_negC_ne_proof : scalar_i32_shl_and_negC_ne_before ⊑ scalar_i32_shl_and_negC_ne_after

@[grind =, simp] lemma RawCNFA.empty_states : empty (A := A).states = ∅

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

theorem and_ne_with_one_bit_diff_constants1_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x != 51#32) = 1#1 → 0#1 = ofBool (x + BitVec.ofInt 32 (-52) <ᵤ BitVec.ofInt 32 (-2))

theorem shl_add_lshr_proof : shl_add_lshr_before ⊑ shl_add_lshr_after

theorem ashrsgt_03_10_exact_proof : ashrsgt_03_10_exact_before ⊑ ashrsgt_03_10_exact_after

theorem test16_thm (e e_1 : IntW 8) :
  mul (LLVM.and (LLVM.xor (LLVM.xor e_1 (const? 8 33)) e) (LLVM.xor e e_1)) (LLVM.xor (LLVM.xor e_1 (const? 8 33)) e) ⊑
    mul (LLVM.and (LLVM.xor (LLVM.xor e_1 e) (const? 8 33)) (LLVM.xor e e_1))
      (LLVM.xor (LLVM.xor e_1 e) (const? 8 33))

theorem lt_unsigned_to_large_signed_proof : lt_unsigned_to_large_signed_before ⊑ lt_unsigned_to_large_signed_after

theorem evalWith_succ_eq (p : FSM arity) (carryState : p.α → Bool)
      (x : arity → BitStream) :
  p.evalWith carryState x (n + 1) =
  p.evalWith (p.delta' carryState (fun s => x s 0)) (fun s i => x s (i + 1)) n

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

theorem masked_icmps_bmask_notmixed_or_proof : masked_icmps_bmask_notmixed_or_before ⊑ masked_icmps_bmask_notmixed_or_after

theorem trunc_signed_nsw_sext_proof : trunc_signed_nsw_sext_before ⊑ trunc_signed_nsw_sext_after

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

theorem lt_signed_to_small_negative_thm (e : IntW 8) :
  icmp IntPred.slt (sext 32 e) (const? 32 (-17)) ⊑ icmp IntPred.slt e (const? 8 (-17))

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

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

theorem test_sext1_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → 0#32 = signExtend 32 0#1

theorem not_or_or_and_no_and_proof : not_or_or_and_no_and_before ⊑ not_or_or_and_no_and_after

theorem demo2 (x y : BitVec 8) :  (x ^^^ -1#8 ||| 7#8) ^^^ 12#8 = x &&& BitVec.ofInt 8 (-8) ^^^ BitVec.ofInt 8 (-13)

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 test_logical_proof : test_logical_before ⊑ test_logical_after

theorem only_one_masked_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ofBool (x != 0#64) &&& ofBool (x &&& 9223372036854775807#64 == 0#64) =
    ofBool (x == BitVec.ofInt 64 (-9223372036854775808))

theorem ashrslt_03_06_exact_proof : ashrslt_03_06_exact_before ⊑ ashrslt_03_06_exact_after

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

theorem t1_sshr_proof : t1_sshr_before ⊑ t1_sshr_after

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

theorem carryWith_delta_eq_delta_carryWith
  {carryState : p.α → Bool} {x : arity → BitStream} {n : Nat} :
  p.carryWith (p.delta carryState x) (fun a i => x a (i + 1)) n =
  p.delta (p.carryWith carryState x n) (fun a i => x a (n + i))

theorem test25_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (50#32 ≤ₛ x) &&& ofBool (x <ₛ 100#32) = ofBool (x + BitVec.ofInt 32 (-50) <ᵤ 50#32)

theorem positive_samevar_lshrexact_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ x_1 >>> x <<< x ≠ x_1 ∨ x ≥ ↑8 ∨ x ≥ ↑8) → x_1 >>> x <<< x = x_1

theorem not_or_or_and_not_and_and_commute2_proof : not_or_or_and_not_and_and_commute2_before ⊑ not_or_or_and_not_and_and_commute2_after

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

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

theorem zext_nneg_sext_sle_op0_narrow_proof : zext_nneg_sext_sle_op0_narrow_before ⊑ zext_nneg_sext_sle_op0_narrow_after

@[simp]
lemma RawCNFA.autSignedCmp_m_wf : autSignedCmp.m.1 |>.WF

theorem positive_and_odd_eq_proof : positive_and_odd_eq_before ⊑ positive_and_odd_eq_after

theorem src_is_mask_select_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → ofBool (15#8 &&& (x ^^^ 123#8) != x ^^^ 123#8) = ofBool (15#8 <ᵤ x ^^^ 123#8)

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

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

theorem ashr_ugt_14_proof : ashr_ugt_14_before ⊑ ashr_ugt_14_after

theorem shl_nsw_nuw_add_nuw_proof : shl_nsw_nuw_add_nuw_before ⊑ shl_nsw_nuw_add_nuw_after

theorem and_xor_or7_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 64),
  ¬(x_2 = 0 ∨ x_1 = 0 ∨ x = 0 ∨ x_2 = 0) →
    ¬(x_2 = 0 ∨ x_1 = 0) → 42#64 / x_2 ||

theorem e_1864 :
    7 * (c &&&  ~~~(a &&& b)) + 3 * (c ^^^  ~~~(a &&& (b ||| c))) - 2 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) - 1 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 11 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) - 7 * ((a &&& b) |||  ~~~(b ||| c)) + 7 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) + 3 * (a &&&  ~~~c) + 3 *  ~~~(b &&& c) - 3 *  ~~~c + 4 * ( ~~~c &&& (a ^^^ b)) - 6 * (b ^^^ (a &&& (b ||| c))) + 5 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 11 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 2 * (c ^^^ ( ~~~a ||| (b &&& c))) + 1 *  ~~~( ~~~a &&& (b ^^^ c)) + 2 * (b |||  ~~~(a ||| c)) - 7 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) - 1 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) - 1 * (b ||| c) - 6 * (a &&&  ~~~b) - 3 *  ~~~(a ||| ( ~~~b &&& c)) + 1 *  ~~~( ~~~a ||| (b ^^^ c)) - 11 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 1 * (b ^^^ (a ||| ( ~~~b &&& c))) - 11 * (b ^^^ (a &&& (b ^^^ c))) - 5 * ( ~~~a &&& (b ^^^ c)) - 6 * (b ^^^  ~~~(a |||  ~~~c)) + 5 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) + 7 *  ~~~(a &&& (b ||| c)) - 7 * (c &&&  ~~~(a ^^^ b)) - 1 * (c ^^^  ~~~(a &&& b)) + 4 * (b ^^^ (a ||| ( ~~~b ||| c))) + 11 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) - 1 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) + 1 * ( ~~~(a &&& b) &&& (b ^^^ c)) - 1 * ( ~~~(a ||| b) ||| (b ^^^ c)) - 2 *  ~~~(a ||| (b &&& c)) + 5 * ( ~~~b &&&  ~~~(a ^^^ c)) + 1 *  ~~~(a ||| (b ||| c)) + 27 *  ~~~(a ||| ( ~~~b ||| c)) - 1 *  ~~~( ~~~a ||| (b ||| c)) + 20 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 18 * ( ~~~a &&& (b &&& c)) + 10 * (a &&& ( ~~~b &&& c)) + 40 * (a &&& (b &&& c)) = 7 * (b &&& (a |||  ~~~c)) + 2 *  ~~~(a &&& c)

theorem t1_proof : t1_before ⊑ t1_after

theorem select_icmp_ne_0_and_32_or_4096_proof : select_icmp_ne_0_and_32_or_4096_before ⊑ select_icmp_ne_0_and_32_or_4096_after

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

theorem shl_lshr_pow2_const_negative_overflow2_thm (e : IntW 16) :
  LLVM.and (lshr (shl (const? 16 8) e) (const? 16 6)) (const? 16 (-32768)) ⊑ const? 16 0

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

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

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

theorem lshr_pow2_ult_smin_proof : lshr_pow2_ult_smin_before ⊑ lshr_pow2_ult_smin_after

theorem narrow_source_matching_signbits_proof : narrow_source_matching_signbits_before ⊑ narrow_source_matching_signbits_after

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

theorem sdiv_icmp2_thm (e : IntW 64) :
  icmp IntPred.eq (LLVM.sdiv e (const? 64 5) { «exact» := true }) (const? 64 1) ⊑
    icmp IntPred.eq e (const? 64 5)

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

theorem neg_sgt_n1_proof : neg_sgt_n1_before ⊑ neg_sgt_n1_after

theorem or_zext_zext_thm (e : IntW 8) (e_1 : IntW 4) :
  LLVM.or (zext 16 e_1) (zext 16 e) ⊑ zext 16 (LLVM.or e (zext 8 e_1))

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 zext_eq_sext_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  ofBool (zeroExtend 32 x_1 == signExtend 32 x) = (x_1 ||| x) ^^^ 1#1

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

theorem scalar_i32_shl_and_negC_eq_X_is_constant2_proof : scalar_i32_shl_and_negC_eq_X_is_constant2_before ⊑ scalar_i32_shl_and_negC_eq_X_is_constant2_after

theorem test9_thm (e e_1 : IntW 32) : LLVM.xor (LLVM.and e_1 e) (LLVM.xor e_1 e) ⊑ LLVM.or e_1 e

theorem sge_swap_or_max_commute_proof : sge_swap_or_max_commute_before ⊑ sge_swap_or_max_commute_after

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

theorem xor_or_xor_common_op_commute6_proof : xor_or_xor_common_op_commute6_before ⊑ xor_or_xor_common_op_commute6_after

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

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

theorem negtest_near_pow2_cmpval_isnt_close_to_pow2_proof : negtest_near_pow2_cmpval_isnt_close_to_pow2_before ⊑ negtest_near_pow2_cmpval_isnt_close_to_pow2_after

theorem negate_sdiv_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true →
    (BitVec.ofInt 8 (-42) == 0 || 8 != 1 && x == intMin 8 && BitVec.ofInt 8 (-42) == -1) = true → False

theorem test_invert_demorgan_logical_and_thm (e e_1 : IntW 64) :
  LLVM.xor
      (LLVM.or (icmp IntPred.eq e_1 (const? 64 0))
        (select (icmp IntPred.eq e_1 (const? 64 27)) (icmp IntPred.eq e (const? 64 0)) (const? 1 0)))
      (const? 1 1) ⊑
    LLVM.and (icmp IntPred.ne e_1 (const? 64 0))
      (select (icmp IntPred.ne e_1 (const? 64 27)) (const? 1 1) (icmp IntPred.ne e (const? 64 0)))

theorem test_negative_nsw_and_unsigned_pred_proof : test_negative_nsw_and_unsigned_pred_before ⊑ test_negative_nsw_and_unsigned_pred_after

theorem sel_false_val_is_a_masked_lshr_of_true_val2_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬2#32 ≥ ↑32 →
    ofBool ((x_1 &&& 60#32) >>> 2#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 bools_multi_uses2_logical_thm.extracted_1._8 : ∀ (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 + 0#1 = 0#1 ^^^ 0#1

theorem nonexact_ashr_ne_proof : nonexact_ashr_ne_before ⊑ nonexact_ashr_ne_after

theorem bools_logical_commute3_and2_thm.extracted_1._6 : ∀ (x x_1 : BitVec 1), ¬x_1 = 1#1 → 0#1 = 1#1 → False

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

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

theorem nomask_lhs_logical_proof : nomask_lhs_logical_before ⊑ nomask_lhs_logical_after

theorem mul_of_bool_commute_thm (e e_1 : IntW 32) :
  icmp IntPred.ugt (mul (LLVM.and e_1 (const? 32 255)) (LLVM.and e (const? 32 1))) (const? 32 255) ⊑
    const? 1 0

theorem e_2087 :
     - 11 * (e ^^^ (d &&& f)) - 3 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 1 * (d |||  ~~~f) + 5 *  ~~~(d ^^^ ( ~~~e ||| f)) + 7 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 5 * (e ^^^ (d |||  ~~~f)) + 4 * (d ||| (e ||| f)) + 11 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 11 *  ~~~(d &&& (e ||| f)) + 4 * (f ^^^ (d &&& (e ||| f))) - 1 * (e ^^^ ( ~~~d ||| (e ||| f))) + 4 * (e ^^^ (d ||| (e ||| f))) - 7 *  ~~~(d ^^^ (e ||| f)) - 2 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 2 *  ~~~( ~~~d &&& (e ^^^ f)) + 5 * ( ~~~e &&& (d ^^^ f)) - 2 *  ~~~(d ||| (e ^^^ f)) + 1 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 2 * (e |||  ~~~f) + 1 * (f ^^^  ~~~(d &&& (e ||| f))) - 3 * (d ^^^ f) - 2 *  ~~~(d ^^^ ( ~~~e &&& f)) - 11 * (f ^^^  ~~~(d ||| e)) + 1 * (f ^^^ ( ~~~d ||| (e &&& f))) + 4 * (e ^^^  ~~~(d ||| f)) + 2 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 4 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 3 * (f &&&  ~~~(d ^^^ e)) - 5 *  ~~~(d &&&  ~~~d) + 7 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 2 *  ~~~(d &&& f) - 6 * ( ~~~d ||| ( ~~~e &&& f)) - 2 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 5 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 9 *  ~~~(d ||| ( ~~~e ||| f)) - 15 *  ~~~( ~~~d ||| (e ||| f)) + 10 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 5 * ( ~~~d &&& ( ~~~e &&& f)) + 32 * ( ~~~d &&& (e &&& f)) + 18 * (d &&& ( ~~~e &&& f)) + 8 * (d &&& (e &&& f)) =  - 1 * (d &&& (e ||| f)) - 37 *  ~~~(d ||| (e ||| f))

theorem scalar_i16_lshr_and_signbit_eq_proof : scalar_i16_lshr_and_signbit_eq_before ⊑ scalar_i16_lshr_and_signbit_eq_after

theorem test73_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (-1#8 <ₛ truncate 8 x) = 1#1 → ¬ofBool (x &&& 128#32 == 0#32) = 1#1 → 40#32 = 42#32

theorem t0_const_lshr_shl_ne_proof : t0_const_lshr_shl_ne_before ⊑ t0_const_lshr_shl_ne_after

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

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

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

theorem test2_thm.extracted_1._1 : ∀ (x : BitVec 49),
  ¬(11#49 ≥ ↑49 ∨ 4096#49 <<< 11#49 = 0) → x % 4096#49 <<< 11#49 = x &&& 8388607#49

lemma eval_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) :
    (p.compose new_arity q_arity vars q).eval x =
      p.eval (λ a => (q a).eval (fun i => x (vars _ i)))

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

theorem t1_proof : t1_before ⊑ t1_after

theorem t9_nocse_proof : t9_nocse_before ⊑ t9_nocse_after

theorem in_constant_mone_vary_proof : in_constant_mone_vary_before ⊑ in_constant_mone_vary_after

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

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

theorem PR42691_9_logical_proof : PR42691_9_logical_before ⊑ PR42691_9_logical_after

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

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 PR30273_three_bools_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 →
    x_1 = 1#1 →
      ¬(True ∧ (zeroExtend 32 x).saddOverflow 1#32 = true) →
        x = 1#1 →
          ¬(True ∧ (zeroExtend 32 x + 1#32).saddOverflow 1#32 = true) →
            True ∧ (2#32).saddOverflow (zeroExtend 32 x_2) = true ∨
                True ∧ (2#32).uaddOverflow (zeroExtend 32 x_2) = true →
              False

theorem pr51551_demand3bits_proof : pr51551_demand3bits_before ⊑ pr51551_demand3bits_after

theorem test3_proof : test3_before ⊑ test3_after

theorem PR60818_sgt_proof : PR60818_sgt_before ⊑ PR60818_sgt_after

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

theorem e_1992 :
    4 * (c ||| (a &&&  ~~~b)) - 1 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) - 2 * ( ~~~(a &&& b) &&&  ~~~(b ^^^ c)) - 2 * (b ^^^ (a ||| (b ||| c))) + 1 * (b ||| (a &&& c)) - 7 * (b ^^^ (a &&& c)) + 1 * (b ||| (a &&&  ~~~c)) - 1 *  ~~~(a ^^^ (b ^^^ c)) - 2 * (c ^^^  ~~~(a &&& b)) - 2 *  ~~~(a &&& (b ||| c)) + 2 * (b ^^^ c) - 2 *  ~~~(a ||| c) + 4 * (b ^^^ ( ~~~a &&& (b ||| c))) - 1 * ( ~~~a ||| (b ||| c)) - 1 * (c ^^^  ~~~(a &&& (b &&& c))) - 5 * ( ~~~b ||| (a ^^^ c)) + 1 *  ~~~a - 2 * ((a ^^^ b) |||  ~~~(a ^^^ c)) - 1 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 7 * (b ^^^  ~~~(a &&& (b &&& c))) - 3 * ( ~~~a &&& ( ~~~b ||| c)) - 7 * (b ||| (a ^^^ c)) + 1 * ( ~~~a &&& (b ^^^ c)) - 1 * (b ^^^  ~~~(a ||| (b ^^^ c))) + 4 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) + 1 *  ~~~(a ^^^ (b ||| c)) + 7 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) - 11 * ((a &&& b) ^^^ (b ||| c)) + 1 * c + 2 *  ~~~(a &&& b) + 2 * (b ^^^ (a ||| ( ~~~b &&& c))) + 1 *  ~~~(a |||  ~~~b) + 11 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) + 4 * (a ^^^ c) - 11 * (a ||| ( ~~~b ||| c)) + 11 * (c &&&  ~~~(a &&&  ~~~b)) - 3 * ((b &&& c) ||| (a &&& (b ||| c))) - 1 *  ~~~(a ^^^ ( ~~~b ||| c)) - 11 * ((a ||| b) &&& (b ^^^ c)) - 2 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) + 7 *  ~~~(a ^^^ (b &&& c)) - 1 * ( ~~~c ||| (a ^^^ b)) - 5 * (c &&&  ~~~(a &&& b)) - 1 *  ~~~(a &&&  ~~~c) - 11 *  ~~~( ~~~a &&& (b &&& c)) + 1 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 1 * (a &&&  ~~~b) - 5 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) + 1 *  ~~~( ~~~a ||| (b ^^^ c)) - 7 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) + 16 *  ~~~(a ||| (b ||| c)) + 57 *  ~~~(a ||| ( ~~~b ||| c)) + 29 *  ~~~( ~~~a ||| (b ||| c)) + 55 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 11 * ( ~~~a &&& ( ~~~b &&& c)) + 25 * ( ~~~a &&& (b &&& c)) + 58 * (a &&& ( ~~~b &&& c)) - 8 * (a &&& (b &&& c)) =  - 3 * (c ^^^ ( ~~~a &&& (b ||| c))) + 6 * ((a ^^^ b) ||| (a ^^^ c))

theorem lshr_sext_i1_to_i128_thm.extracted_1._1 : ∀ (x : BitVec 1),
  ¬42#128 ≥ ↑128 → x = 1#1 → signExtend 128 x >>> 42#128 = 77371252455336267181195263#128

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

theorem icmp_ugt_proof : icmp_ugt_before ⊑ icmp_ugt_after

theorem udiv_illegal_type_c_proof : udiv_illegal_type_c_before ⊑ udiv_illegal_type_c_after

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

theorem icmp_ne_sext_eq_otherwise_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (x == 2#32)) != x) = ofBool (x != 0#32)

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

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

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 and_signbit_select_lshr_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 → ¬8#32 ≥ ↑32 → (x &&& BitVec.ofInt 32 (-65536)) >>> 8#32 = x >>> 8#32 &&& 16776960#32

theorem p0_proof : p0_before ⊑ p0_after

theorem src_is_mask_shl_lshr_fail_not_allones_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(x ≥ ↑8 ∨ x ≥ ↑8) →
    ¬x ≥ ↑8 →
      ofBool (0#8 != (x_1 ^^^ 123#8) &&& (BitVec.ofInt 8 (-2) <<< x >>> x ^^^ -1#8)) =
        ofBool (x_1 ^^^ BitVec.ofInt 8 (-124) ||| (-1#8) >>> x &&& BitVec.ofInt 8 (-2) != -1#8)

theorem urem_constant_dividend_select_of_constants_divisor_proof : urem_constant_dividend_select_of_constants_divisor_before ⊑ urem_constant_dividend_select_of_constants_divisor_after

theorem 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 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 and_zext_thm.extracted_1._2 : ∀ (x : BitVec 1) (x_1 : BitVec 32), ¬x = 1#1 → x_1 &&& zeroExtend 32 x = 0#32

theorem C0zero_thm.extracted_1._3 : ∀ (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 sub_undemanded_low_bits_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬4#32 ≥ ↑32 → ((x ||| 15#32) - 1616#32) >>> 4#32 = (x + BitVec.ofInt 32 (-1616)) >>> 4#32

theorem main1_proof : main1_before ⊑ main1_after

theorem select_icmp_ne_0_and_8_xor_1073741824_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 8),
  ofBool (0#8 != x_1 &&& 8#8) = 1#1 → ofBool (x_1 &&& 8#8 == 0#8) = 1#1 → x = x ^^^ 1073741824#32

@[bv_multi_width_normalize] theorem BitVec.mul_ofNat_eq_ofNat_mul (x : BitVec w) (n : Nat) :
  x * (BitVec.ofNat w n) = BitVec.ofNat w n * x

theorem ashrslt_03_00_exact_proof : ashrslt_03_00_exact_before ⊑ ashrslt_03_00_exact_after

theorem or_nosignbit_select_shl_proof : or_nosignbit_select_shl_before ⊑ or_nosignbit_select_shl_after

theorem p0_proof : p0_before ⊑ p0_after

theorem not_sext_thm (e : IntW 1) :
  select e (const? 999 0) (const? 999 (-1)) ⊑ sext 999 (LLVM.xor e (const? 1 1))

theorem and_xor_common_op_commute2_proof : and_xor_common_op_commute2_before ⊑ and_xor_common_op_commute2_after

theorem rem_euclid_pow2_false_arm_folded_proof : rem_euclid_pow2_false_arm_folded_before ⊑ rem_euclid_pow2_false_arm_folded_after

theorem lshrugt_02_10_exact_proof : lshrugt_02_10_exact_before ⊑ lshrugt_02_10_exact_after

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

theorem demorgan_nor_use2b_proof : demorgan_nor_use2b_before ⊑ demorgan_nor_use2b_after

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

theorem pr64558_proof : pr64558_before ⊑ pr64558_after

theorem add_select_zext_proof : add_select_zext_before ⊑ add_select_zext_after

theorem and_or_not_not_commute4_proof : and_or_not_not_commute4_before ⊑ and_or_not_not_commute4_after

theorem test17_thm (e e_1 : IntW 8) :
  mul (LLVM.or (LLVM.xor e_1 e) (LLVM.xor (LLVM.xor e (const? 8 33)) e_1)) (LLVM.xor (LLVM.xor e (const? 8 33)) e_1) ⊑
    mul (LLVM.or (LLVM.xor e_1 e) (LLVM.xor (LLVM.xor e e_1) (const? 8 33)))
      (LLVM.xor (LLVM.xor e e_1) (const? 8 33))

theorem p_commutative0_proof : p_commutative0_before ⊑ p_commutative0_after

theorem add_umin_simplify_proof : add_umin_simplify_before ⊑ add_umin_simplify_after

theorem test_sext4_proof : test_sext4_before ⊑ test_sext4_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_7b_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_7b_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_7b_logical_after

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

theorem select_bittest_to_add_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 1#32 == 0#32) = 1#1 →
    True ∧ (x &&& 1#32).saddOverflow 3#32 = true ∨ True ∧ (x &&& 1#32).uaddOverflow 3#32 = true → False

theorem sle_smax1_proof : sle_smax1_before ⊑ sle_smax1_after

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

theorem scalar_i64_shl_and_signbit_eq_thm (e e_1 : IntW 64) :
  icmp IntPred.eq (LLVM.and (shl e_1 e) (const? 64 (-9223372036854775808))) (const? 64 0) ⊑
    icmp IntPred.sgt (shl e_1 e) (const? 64 (-1))

theorem PR42691_2_logical_thm (e : IntW 32) :
  select (icmp IntPred.ult e (const? 32 (-2147483648))) (const? 1 1) (icmp IntPred.eq e (const? 32 (-1))) ⊑
    icmp IntPred.sgt e (const? 32 (-2))

theorem ashr_mul_times_3_div_2_exact_thm (e : IntW 32) :
  ashr (mul e (const? 32 3) { «nsw» := true, «nuw» := false }) (const? 32 1) { «exact» := true } ⊑
    add e (ashr e (const? 32 1) { «exact» := true }) { «nsw» := true, «nuw» := false }

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

theorem or_xor_tree_0100_proof : or_xor_tree_0100_before ⊑ or_xor_tree_0100_after

theorem e_853 :
     - 7 *  ~~~(z &&& t) - 5 *  ~~~t + 13 *  ~~~(z ||| t) + 8 *  ~~~(z |||  ~~~t) + 13 * (z &&&  ~~~t) + 1 * (z &&& t) = 1 *  ~~~(z &&&  ~~~z)

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

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

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

theorem ugt_swap_or_not_min_commute_logical_thm.extracted_1._1 : ∀ (x : BitVec 823),
  ofBool (x != 0#823) = 1#1 → 1#1 = ofBool (x != 0#823)

theorem andn_or_cmp_2_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → ofBool (x ≤ₛ x_1) = 1#1 → ofBool (x_1 <ₛ x) = 0#1

theorem lshr_16_add_not_known_16_leading_zeroes_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬16#32 ≥ ↑32 →
    True ∧ (x_1 &&& 131071#32).saddOverflow (x &&& 65535#32) = true ∨
        True ∧ (x_1 &&& 131071#32).uaddOverflow (x &&& 65535#32) = true ∨ 16#32 ≥ ↑32 →
      False

theorem main7g_proof : main7g_before ⊑ main7g_after

theorem PR1817_2_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x <ₛ 10#32) = 1#1 → ofBool (x <ᵤ 10#32) = ofBool (x <ₛ 10#32)

theorem test65_proof : test65_before ⊑ test65_after

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

theorem and_add_bool_to_select_multi_use_thm.extracted_1._2 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → (-1#32 + zeroExtend 32 x_1 &&& x) + (-1#32 + zeroExtend 32 x_1) = x + -1#32

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

theorem xor_lshr_thm.extracted_1._2 : ∀ (x x_1 x_2 x_3 : BitVec 8),
  ¬(x_2 ≥ ↑8 ∨ x_2 ≥ ↑8) → ¬x_2 ≥ ↑8 → x_3 >>> x_2 ^^^ x_1 ^^^ x >>> x_2 = (x_3 ^^^ x) >>> x_2 ^^^ x_1

theorem xor_or_xor_common_op_commute8_proof : xor_or_xor_common_op_commute8_before ⊑ xor_or_xor_common_op_commute8_after

@[simp]
theorem not_xor_and_self {a b : Bool} : (!(a ^^ b) && b) = (a && b)

theorem ashr1_proof : ashr1_before ⊑ ashr1_after

theorem AndZextAnd_thm.extracted_1._2 : ∀ (x : BitVec 3),
  ¬(True ∧ (x &&& 2#3).msb = true) → zeroExtend 5 (x &&& 3#3) &&& 14#5 = zeroExtend 5 (x &&& 2#3)

theorem sle_and_min_commute_proof : sle_and_min_commute_before ⊑ sle_and_min_commute_after

theorem foo1_or_proof : foo1_or_before ⊑ foo1_or_after

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

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

theorem select_icmp_x_and_8_ne_0_y_xor_8_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& 8#32 == 0#32) = 1#1 → True ∧ (x_1 &&& 8#32 ^^^ 8#32).msb = true → False

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

theorem select_icmp_x_and_8_eq_0_y_xor_8_proof : select_icmp_x_and_8_eq_0_y_xor_8_before ⊑ select_icmp_x_and_8_eq_0_y_xor_8_after

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

theorem logical_and_bitwise_and_icmps_comm3_proof : logical_and_bitwise_and_icmps_comm3_before ⊑ logical_and_bitwise_and_icmps_comm3_after

theorem ashr_sle_noexact_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬3#8 ≥ ↑8 → ofBool (x.sshiftRight' 3#8 ≤ₛ 10#8) = ofBool (x <ₛ 88#8)

theorem or_eq_with_one_bit_diff_constants3_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x == BitVec.ofInt 8 (-2)) ||

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_4_proof : masked_icmps_mask_notallzeros_bmask_mixed_swapped_4_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_swapped_4_after

theorem zext_zext_eq_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (zext 32 e_1) (zext 32 e) ⊑ icmp IntPred.eq e_1 e

theorem shl_add_lshr_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).uaddOverflow x = true ∨ x_1 ≥ ↑32) →
    ¬(x_1 ≥ ↑32 ∨ True ∧ (x >>> x_1).uaddOverflow x_2 = true) → (x_2 <<< x_1 + x) >>> x_1 = x >>> x_1 + x_2

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

theorem ripple_nsw5_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  True ∧ (x_1 ||| BitVec.ofInt 16 (-21845)).saddOverflow (x ||| BitVec.ofInt 16 (-10923)) = true → False

theorem test10_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬4#64 = 0 → truncate 32 (signExtend 64 (zeroExtend 32 x * 4#32) % 4#64) = 0#32

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

theorem udiv_shl_pair_const_proof : udiv_shl_pair_const_before ⊑ udiv_shl_pair_const_after

theorem icmp_slt_sext_ne_zero_nofold_proof : icmp_slt_sext_ne_zero_nofold_before ⊑ icmp_slt_sext_ne_zero_nofold_after

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

theorem n2_proof : n2_before ⊑ n2_after

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

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

theorem icmp_select_implied_cond_proof : icmp_select_implied_cond_before ⊑ icmp_select_implied_cond_after

theorem n10_ugt_slt_proof : n10_ugt_slt_before ⊑ n10_ugt_slt_after

theorem hoist_ashr_ahead_of_sext_1_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬3#32 ≥ ↑32 → ¬3#8 ≥ ↑8 → (signExtend 32 x).sshiftRight' 3#32 = signExtend 32 (x.sshiftRight' 3#8)

theorem e_1365 :
    1 * t - 3 *  ~~~(z &&&  ~~~z) + 7 *  ~~~(z &&&  ~~~t) - 11 *  ~~~(z &&& t) - 1 * (z ||| t) + 7 *  ~~~t + 1 *  ~~~(z ^^^ t) - 1 *  ~~~(z ||| t) + 7 *  ~~~(z |||  ~~~t) - 5 * (z &&& t) =  - 8 * (z &&&  ~~~t)

theorem positive_samevar_shlnsw_lshrexact_proof : positive_samevar_shlnsw_lshrexact_before ⊑ positive_samevar_shlnsw_lshrexact_after

theorem t0_proof : t0_before ⊑ t0_after

theorem PR42691_8_logical_proof : PR42691_8_logical_before ⊑ PR42691_8_logical_after

theorem test1_thm (e : IntW 333) : LLVM.udiv e (const? 333 70368744177664) ⊑ lshr e (const? 333 46)

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

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

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

theorem eval_fsmTermSlt_eq_decide_slt {wcard tcard : Nat}
    (tctx : Term.Ctx wcard tcard)
    {wenv : WidthExpr.Env wcard}
    (tenv : tctx.Env wenv)
    (benv : Term.BoolEnv bcard)
    (nenv : Term.NatEnv ncard)
    (ienv : Term.IntEnv icard)
    (w : WidthExpr wcard)
    (a : Term bcard ncard icard pcard tctx (.bv w))
    (b : Term bcard ncard icard pcard tctx (.bv w))
    (wfsm : NatFSM wcard tcard bcard ncard icard pcard (.ofDep w))
    (hwfsm : HNatFSMToBitstream wfsm)
    (afsm : TermFSM wcard tcard bcard ncard icard pcard (.ofDepTerm a))
    (hafsm : HTermFSMToBitStream afsm)
    (bfsm : TermFSM wcard tcard bcard ncard icard pcard (.ofDepTerm b))
    (hbfsm : HTermFSMToBitStream bfsm)
    (fsmEnv : StateSpace wcard tcard bcard ncard icard pcard → BitStream)
    (henv : HTermEnv fsmEnv tenv benv)
    :
    ((fsmTermSlt
      wfsm
      afsm
      bfsm)).eval fsmEnv i =
       decide (((a.toBV benv nenv ienv penv tenv).signExtend i).slt
          ((b.toBV benv nenv ienv penv tenv).signExtend i))

theorem test19_proof : test19_before ⊑ test19_after

theorem or_test1_thm (e : IntW 231) : LLVM.or (LLVM.and e (const? 231 1)) (const? 231 1) ⊑ const? 231 1

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

theorem test5_thm (e : IntW 32) :
  ashr (shl e (const? 32 16)) (const? 32 16) ⊑ ashr (shl e (const? 32 16)) (const? 32 16) { «exact» := true }

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

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

theorem not_and_and_or_not_or_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 ^^^ -1#32) &&& x) ||

theorem R.trimTensor_getD_0 (tensor: List Int) :
  tensor.getD i 0 = (trimTensor tensor).getD i 0

theorem test15_thm (e : IntW 32) :
  sub (const? 64 8) (sext 64 (ashr e (const? 32 1))) ⊑
    sext 64 (sub (const? 32 8) (ashr e (const? 32 1)) { «nsw» := true, «nuw» := false })

theorem test1_logical_proof : test1_logical_before ⊑ test1_logical_after

theorem test23_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ofBool (x_1 ^^^ x == x) = ofBool (x_1 == 0#32)

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

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

theorem sdiv_mul_shl_nsw_proof : sdiv_mul_shl_nsw_before ⊑ sdiv_mul_shl_nsw_after

theorem e_2386 :
    2 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 5 * (e ||| (d ^^^ f)) - 1 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 1 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 5 * (d ^^^ (e ||| f)) - 3 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 3 * ( ~~~d ||| (e ||| f)) + 7 * (d ^^^ ( ~~~e ||| f)) + 1 * (f ^^^ (d &&& ( ~~~e ||| f))) + 1 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 2 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 11 * (e ^^^ (d ||| (e ||| f))) + 4 * (e ^^^  ~~~(d &&&  ~~~f)) - 7 * (f &&&  ~~~(d &&&  ~~~e)) + 3 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 3 * (e ^^^ ( ~~~d ||| (e ||| f))) + 1 * (d ^^^ ( ~~~e &&& f)) + 1 * (f ^^^ ( ~~~d ||| (e &&& f))) + 11 * ((d &&& e) |||  ~~~(e ||| f)) + 1 * ( ~~~d ||| (e ^^^ f)) - 3 * (f &&&  ~~~(d &&& e)) - 2 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 1 * ( ~~~d &&& (e ||| f)) - 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 11 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 5 *  ~~~(d |||  ~~~f) - 7 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 1 * (e ^^^ (d ||| ( ~~~e ||| f))) + 7 * (d ||| (e ||| f)) - 1 * (e ||| f) - 2 * (d &&& f) + 4 * (e &&&  ~~~(d ^^^ f)) + 1 * (f ^^^ (d ||| e)) - 3 * (f ^^^ (d ||| (e ||| f))) + 1 *  ~~~(e ^^^ f) + 7 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 3 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 1 * ((d &&& e) |||  ~~~(e ^^^ f)) + 2 * (f |||  ~~~(d ^^^ e)) - 2 * ( ~~~d ||| ( ~~~e &&& f)) + 1 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 1 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) - 7 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 11 * (f ^^^ (d &&& e)) - 2 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 5 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 *  ~~~( ~~~d &&& (e ||| f)) + 4 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) - 6 * (f &&& (d ||| e)) + 3 * (f ^^^ (d ||| ( ~~~e ||| f))) - 5 *  ~~~(e &&&  ~~~f) + 2 * (e ^^^ (d ||| ( ~~~e &&& f))) - 11 * ((d ||| e) &&& (e ^^^ f)) + 5 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 11 *  ~~~(e &&& f) - 1 *  ~~~( ~~~d ||| (e &&& f)) + 3 * d + 7 * (f ^^^ (d ||| ( ~~~e &&& f))) + 7 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 11 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 11 * ( ~~~d &&& ( ~~~e ||| f)) - 5 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 57 *  ~~~(d ||| (e ||| f)) - 14 *  ~~~(d ||| ( ~~~e ||| f)) - 13 *  ~~~( ~~~d ||| (e ||| f)) - 57 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 4 * ( ~~~d &&& ( ~~~e &&& f)) - 16 * ( ~~~d &&& (e &&& f)) - 13 * (d &&& ( ~~~e &&& f)) - 3 * (d &&& (e &&& f)) =  - 1 * (d &&&  ~~~e) + 1 * ((d &&& f) ^^^ (e ||| f))

theorem ashrsgt_03_14_exact_proof : ashrsgt_03_14_exact_before ⊑ ashrsgt_03_14_exact_after

theorem sub_shl_same_amount_partial_nuw2_proof : sub_shl_same_amount_partial_nuw2_before ⊑ sub_shl_same_amount_partial_nuw2_after

theorem test11_thm.extracted_1._1 : ∀ (x : BitVec 23),
  ¬(11#23 ≥ ↑23 ∨ 12#23 ≥ ↑23) → (x * 3#23) >>> 11#23 <<< 12#23 = x * 6#23 &&& BitVec.ofInt 23 (-4096)

theorem narrow_zext_ashr_keep_trunc3_thm (e e_1 : IntW 8) :
  trunc 7 (ashr (add (sext 64 e_1) (sext 64 e) { «nsw» := true, «nuw» := false }) (const? 64 1)) ⊑
    trunc 7 (lshr (add (zext 14 e_1) (zext 14 e) { «nsw» := true, «nuw» := true }) (const? 14 1))

theorem xor_of_icmps_commute_thm (e : IntW 64) :
  LLVM.xor (icmp IntPred.sgt e (const? 64 0)) (icmp IntPred.eq e (const? 64 1)) ⊑
    icmp IntPred.sgt e (const? 64 1)

theorem test_sub_nuw_nsw__nsw_is_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x ||| BitVec.ofInt 32 (-2147483648) == BitVec.ofInt 32 (-2147483647)) = 1#1 →
    True ∧ (BitVec.ofInt 32 (-2147483648)).ssubOverflow (x ||| BitVec.ofInt 32 (-2147483648)) = true → False

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

theorem scalar_i8_shl_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 bools_logical_commute1_and2_thm.extracted_1._13 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 = 1#1 → ¬x_1 = 1#1 → 0#1 = 1#1 → 1#1 = x_2

theorem icmp_eq_sext_eq_otherwise_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (x == 2#32)) == x) = ofBool (x == 0#32)

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

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

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

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

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 negtest_near_pow2_cmpval_would_overflow_into_signbit_thm (e : IntW 8) :
  icmp IntPred.ult (ashr e (const? 8 2) { «exact» := true }) (const? 8 33) ⊑
    icmp IntPred.sgt e (const? 8 (-1))

theorem add_eq_or_add_and (x y : BitVec w) :
    x + y = (x ||| y) + (x &&& y)

theorem bv_AndOrXor_2647 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.xor (LLVM.and e e_1) (LLVM.xor e e_1) ⊑ LLVM.or e e_1

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

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

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

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

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 fold_or_zext_icmp_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 64),
  zeroExtend 8 (ofBool (x_1 <ₛ x_2)) ||

theorem e_426 :
     - 1 * (x ||| y) + 1 * (x ^^^ y) - 5 * (x |||  ~~~y) - 5 * x - 5 *  ~~~(x &&&  ~~~y) + 5 *  ~~~(x |||  ~~~y) + 10 * (x &&&  ~~~y) + 16 * (x &&& y) =  - 10 *  ~~~(x ||| y)

theorem exactly_one_set_signbit_signed_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (ashr e_1 (const? 8 7)) (sext 8 (icmp IntPred.sgt e (const? 8 (-1)))) ⊑
    icmp IntPred.slt (LLVM.xor e_1 e) (const? 8 0)

theorem one_side_fold_sgt_thm.extracted_1._9 : ∀ (x x_1 x_2 : BitVec 32) (x_3 : BitVec 1),
  x_3 = 1#1 → ¬x_3 ^^^ 1#1 = 1#1 → ofBool (x_2 <ₛ x_2) = 0#1

theorem t1_proof : t1_before ⊑ t1_after

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

theorem shl_add_nuw_and_nsw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬x &&& 2#8 ≥ ↑8 →
    True ∧ ((x_1 &&& 31#8) <<< (x &&& 2#8)).sshiftRight' (x &&& 2#8) ≠ x_1 &&& 31#8 ∨
        True ∧ (x_1 &&& 31#8) <<< (x &&& 2#8) >>> (x &&& 2#8) ≠ x_1 &&& 31#8 ∨ x &&& 2#8 ≥ ↑8 →
      False

theorem lshrult_02_15_exact_proof : lshrult_02_15_exact_before ⊑ lshrult_02_15_exact_after

theorem ashr_ugt_1_proof : ashr_ugt_1_before ⊑ ashr_ugt_1_after

theorem sge_or_not_max_commute_proof : sge_or_not_max_commute_before ⊑ sge_or_not_max_commute_after

theorem or_and1_thm.extracted_1._8 : ∀ (x x_1 x_2 : BitVec 1),
  ¬(x_2 ^^^ 1#1) &&& x_1 = 1#1 → ¬x_2 = 1#1 → ¬x_1 = 1#1 → x_2 = 0#1

theorem bools_multi_uses2_logical_proof : bools_multi_uses2_logical_before ⊑ bools_multi_uses2_logical_after

theorem multiuse_add_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → 1#64 + zeroExtend 64 x + 1#64 = 2#64

theorem lshr_mul_times_5_div_4_exact_proof : lshr_mul_times_5_div_4_exact_before ⊑ lshr_mul_times_5_div_4_exact_after

theorem xor_1_thm.extracted_1._3 : ∀ (x x_1 x_2 : BitVec 8) (x_3 : BitVec 1),
  x_3 = 1#1 → x_2 ^^^ -1#8 ^^^ x ^^^ -1#8 = x_2 ^^^ x

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

theorem shl_or_proof : shl_or_before ⊑ shl_or_after

@[simp, aesop 50% unsafe]
theorem stepSet_mono (M : NFA α σ) (S₁ S₂ : Set σ) (a : α) (h : S₁ ⊆ S₂) :
    M.stepSet S₁ a ⊆ M.stepSet S₂ a

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

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

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

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

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

theorem or_eq_notY_eq_0_proof : or_eq_notY_eq_0_before ⊑ or_eq_notY_eq_0_after

theorem shift_xor_multiuse_cmp_with_and_proof : shift_xor_multiuse_cmp_with_and_before ⊑ shift_xor_multiuse_cmp_with_and_after

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

theorem ugt_sext_proof : ugt_sext_before ⊑ ugt_sext_after

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

theorem udiv_common_divisor_defined_cond_proof : udiv_common_divisor_defined_cond_before ⊑ udiv_common_divisor_defined_cond_after

theorem sel_sext_proof : sel_sext_before ⊑ sel_sext_after

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

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

theorem e_1149 :
    11 * (z ^^^ t) + 3 *  ~~~(z &&& t) - 3 *  ~~~(z ^^^ t) - 11 * (z |||  ~~~t) + 5 *  ~~~z - 19 *  ~~~(z |||  ~~~t) - 4 * (z &&&  ~~~t) + 14 * (z &&& t) =  - 1 *  ~~~t - 5 *  ~~~(z ||| t)

theorem select_add_icmp_bad_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.eq e_2 (const? 32 1)) (add e_2 e_1) e ⊑
    select (icmp IntPred.eq e_2 (const? 32 1)) (add e_1 (const? 32 1)) e

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

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

theorem lshrugt_01_12_proof : lshrugt_01_12_before ⊑ lshrugt_01_12_after

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

theorem 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 e_1577 :
     - 2 * (c |||  ~~~(a ||| b)) - 2 *  ~~~(b |||  ~~~c) + 7 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) + 5 * ( ~~~b |||  ~~~(a ^^^ c)) + 3 * ( ~~~b ||| (a ^^^ c)) + 4 * (a &&&  ~~~c) + 2 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 2 * ((a ^^^ b) ||| (a ^^^ c)) - 2 * (b ^^^  ~~~(a &&&  ~~~c)) - 18 *  ~~~(a ||| (b ||| c)) - 19 *  ~~~(a ||| ( ~~~b ||| c)) - 19 *  ~~~( ~~~a ||| (b ||| c)) - 3 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 14 * ( ~~~a &&& ( ~~~b &&& c)) - 8 * ( ~~~a &&& (b &&& c)) - 10 * (a &&& (b &&& c)) =  - 7 *  ~~~a

theorem test3_apint_proof : test3_apint_before ⊑ test3_apint_after

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

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

theorem select_icmp_ne_0_and_1073741824_and_not_8_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ofBool (0#32 != x_1 &&& 1073741824#32) = 1#1 →
    ofBool (x_1 &&& 1073741824#32 == 0#32) = 1#1 → x = x &&& BitVec.ofInt 8 (-9)

theorem select_shl_icmp_bad_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 == 1#32) = 1#1 → ¬x_2 ≥ ↑32 → ¬1#32 ≥ ↑32 → x_1 <<< x_2 = x_1 <<< 1#32

theorem allSignBits_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(31#32 ≥ ↑32 ∨ 31#32 ≥ ↑32) →
    ofBool (x_1 <ₛ 0#32) = 1#1 →
      x_2 &&& x_1.sshiftRight' 31#32 ||

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

theorem scalar_i32_lshr_and_signbit_eq_X_is_constant1_thm (e : IntW 32) :
  icmp IntPred.eq (LLVM.and (lshr (const? 32 12345) e) (const? 32 (-2147483648))) (const? 32 0) ⊑
    const? 1 1

@[simp] theorem append_eq : append xs ys = xs ++ ys

theorem test_proof : test_before ⊑ test_after

theorem positive_biggerlshr_shlnsw_proof : positive_biggerlshr_shlnsw_before ⊑ positive_biggerlshr_shlnsw_after

theorem ashrslt_03_06_proof : ashrslt_03_06_before ⊑ ashrslt_03_06_after

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

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

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

theorem t0_ult_slt_65536_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.ult e_2 (const? 32 65536)) e_2
      (select (icmp IntPred.slt e_2 (const? 32 65536)) e_1 e) ⊑
    select (icmp IntPred.sgt e_2 (const? 32 65535)) e
      (select (icmp IntPred.slt e_2 (const? 32 0)) e_1 e_2)

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

theorem t0_proof : t0_before ⊑ t0_after

theorem t0_proof : t0_before ⊑ t0_after

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 not_and_and_or_not_or_or_commute1_proof : not_and_and_or_not_or_or_commute1_before ⊑ not_and_and_or_not_or_or_commute1_after

theorem e_1245 :
     - 1 *  ~~~(z ^^^ t) - 2 * (z ||| t) + 7 * (z ^^^ t) - 11 *  ~~~t - 11 *  ~~~z + 4 * t + 2 *  ~~~(z |||  ~~~t) + 6 * (z &&&  ~~~t) - 1 * (z &&& t) =  - 23 *  ~~~(z ||| t)

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

theorem xor_eq_or_sub_and :
    x ^^^ y = (x ||| y) - (x &&& y)

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

theorem e_569 :
    3 * x - 11 * y + 3 *  ~~~(x &&&  ~~~y) - 11 *  ~~~(x &&&  ~~~x) + 2 *  ~~~y + 7 * (x ||| y) + 6 *  ~~~(x ||| y) + 12 *  ~~~(x |||  ~~~y) + 9 * (x &&& y) = 1 * (x &&&  ~~~y)

theorem logical_or_logical_or_icmps_comm1_thm.extracted_1._6 : ∀ (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 → ¬True → ofBool (x_2 &&& 1#8 == 0#8) = 1#1

theorem reassoc_sub_nuw_proof : reassoc_sub_nuw_before ⊑ reassoc_sub_nuw_after

theorem icmp_ne_sext_slt_allones_nofold_proof : icmp_ne_sext_slt_allones_nofold_before ⊑ icmp_ne_sext_slt_allones_nofold_after

@[simp] theorem HVector.denote_cons
    {t : _ × _} {ts : RegionSignature _}
    (a : Com d t.1 .impure t.2) (as : Regions _ ts) :
    HVector.denote (.cons a as) = .cons (a.denote) (as.denote)

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

theorem e_165 :
    1 * x + 1 *  ~~~(x &&&  ~~~x) - 11 * (x ^^^ y) + 1 *  ~~~(x ||| y) + 10 *  ~~~(x |||  ~~~y) + 11 * (x &&&  ~~~y) = 2 *  ~~~y + 2 * (x &&& y)

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

theorem test_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (-1#32 <ₛ x) &&& ofBool (x == 1#32) = ofBool (x == 1#32)

theorem lshrult_03_01_proof : lshrult_03_01_before ⊑ lshrult_03_01_after

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

theorem differentconsts_thm.extracted_1._6 : ∀ (x : BitVec 32),
  ¬ofBool (x + 16#32 <ᵤ 144#32) = 1#1 →
    ¬ofBool (x <ₛ 128#32) = 1#1 →
      ¬ofBool (127#32 <ₛ x) = 1#1 → ¬ofBool (x <ₛ BitVec.ofInt 32 (-16)) = 1#1 → -1#16 = truncate 16 x

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

theorem trans {α : Type u} : ∀ x y z : Option α, Refinement x y → Refinement y z → Refinement x z

theorem no_shift_xor_multiuse_cmp_thm.extracted_1._6 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ofBool (0#32 != x_3 &&& 4096#32) = 1#1 →
    ¬ofBool (x_3 &&& 4096#32 == 0#32) = 1#1 → x_2 * x_1 = (x_2 ||| x_3 &&& 4096#32 ^^^ 4096#32) * x_1

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 lshr_xor_proof : lshr_xor_before ⊑ lshr_xor_after

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

theorem shift_xor_multiuse_xor_proof : shift_xor_multiuse_xor_before ⊑ shift_xor_multiuse_xor_after

theorem sel_false_val_is_a_masked_ashr_of_true_val2_proof : sel_false_val_is_a_masked_ashr_of_true_val2_before ⊑ sel_false_val_is_a_masked_ashr_of_true_val2_after

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

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

theorem mul16_low_miss_shift_amount_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬(8#16 ≥ ↑16 ∨ 8#16 ≥ ↑16 ∨ 8#16 ≥ ↑16) →
    8#16 ≥ ↑16 ∨
        True ∧ (x_1 >>> 8#16).smulOverflow (x &&& 127#16) = true ∨
          True ∧ (x_1 >>> 8#16).umulOverflow (x &&& 127#16) = true ∨
            8#16 ≥ ↑16 ∨
              True ∧ (x_1 &&& 127#16).smulOverflow (x >>> 8#16) = true ∨
                True ∧ (x_1 &&& 127#16).umulOverflow (x >>> 8#16) = true ∨
                  True ∧ (x_1 >>> 8#16 * (x &&& 127#16)).uaddOverflow ((x_1 &&& 127#16) * x >>> 8#16) = true ∨
                    8#16 ≥ ↑16 ∨
                      True ∧ (x_1 &&& 127#16).smulOverflow (x &&& 127#16) = true ∨
                        True ∧ (x_1 &&& 127#16).umulOverflow (x &&& 127#16) = true →
      False

theorem alive_AndOrXor_2231__A__B__B__C__A___A__B__C : alive_AndOrXor_2231__A__B__B__C__A___A__B__C_src ⊑ alive_AndOrXor_2231__A__B__B__C__A___A__B__C_tgt

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

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

theorem not_and_and_or_not_or_or_commute1_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_2 e_1) e) (const? 32 (-1))) ⊑
    LLVM.xor (LLVM.or (LLVM.xor e e_1) e_2) (const? 32 (-1))

theorem test3_proof : test3_before ⊑ test3_after

lemma eval_eq_evalv [DecidableEq α] : ∀ (c : Circuit α) (f : α → Bool),
    eval c f = evalv c (λ x _ => f x)

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

theorem negate_lshr_thm (e e_1 : IntW 8) : sub e_1 (lshr e (const? 8 7)) ⊑ add (ashr e (const? 8 7)) e_1

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

theorem c_1_1_0_proof : c_1_1_0_before ⊑ c_1_1_0_after

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

theorem ashrsgt_03_01_proof : ashrsgt_03_01_before ⊑ ashrsgt_03_01_after

theorem logical_and_not_proof : logical_and_not_before ⊑ logical_and_not_after

theorem shl1_trunc_sgt4_proof : shl1_trunc_sgt4_before ⊑ shl1_trunc_sgt4_after

theorem sgt_smin1_proof : sgt_smin1_before ⊑ sgt_smin1_after

theorem a_false_implies_b_false_proof : a_false_implies_b_false_before ⊑ a_false_implies_b_false_after

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

theorem rem_euclid_pow2_false_arm_folded_proof : rem_euclid_pow2_false_arm_folded_before ⊑ rem_euclid_pow2_false_arm_folded_after

theorem select_exact_lshr_icmp_const_thm (e : IntW 32) :
  select (icmp IntPred.ugt e (const? 32 31)) (lshr e (const? 32 5) { «exact» := true }) (const? 32 0) ⊑
    lshr e (const? 32 5)

theorem t5_thm.extracted_1._3 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  ¬(x = 1#1 ∨ x_1 ≥ ↑32) → ¬x = 1#1 → ¬1#32 <<< x_1 = 0 → ¬x_1 ≥ ↑32 → x_1 / 1#32 <<< x_1 = x_1 >>> x_1

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

theorem icmp_select_implied_cond_relational_proof : icmp_select_implied_cond_relational_before ⊑ icmp_select_implied_cond_relational_after

theorem test_ult_proof : test_ult_before ⊑ test_ult_after

theorem trunc_shl_1_i32_i64_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬1#64 ≥ ↑64 → ¬1#32 ≥ ↑32 → truncate 32 (x <<< 1#64) = truncate 32 x <<< 1#32

theorem uge_swap_or_max_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.ule e_1 e) (const? 1 1) (icmp IntPred.eq e (const? 8 (-1))) ⊑
    icmp IntPred.ule e_1 e

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

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

theorem select_replace_nested_no_simplify_proof : select_replace_nested_no_simplify_before ⊑ select_replace_nested_no_simplify_after

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

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

theorem eq_umin1_proof : eq_umin1_before ⊑ eq_umin1_after

theorem reassoc_x2_sub_nuw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.usubOverflow 4#32 = true ∨
        True ∧ x.usubOverflow 8#32 = true ∨ True ∧ (x_1 - 4#32).usubOverflow (x - 8#32) = true) →
    x_1 - 4#32 - (x - 8#32) = x_1 - x + 4#32

theorem e_2206 :
     - 11 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 6 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 5 * (f ^^^  ~~~(d &&& (e &&& f))) - 7 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 2 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 7 * (e ^^^  ~~~(d ||| f)) + 2 * ( ~~~f |||  ~~~(d ^^^ e)) - 1 * ((d &&& f) |||  ~~~(e ||| f)) - 2 * ( ~~~e |||  ~~~(d ^^^ f)) + 1 * (e &&&  ~~~(d ^^^ f)) + 11 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 3 * (f &&&  ~~~(d &&&  ~~~e)) - 2 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 1 * (f ||| (d &&& e)) + 2 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 * (e ^^^ (d &&& ( ~~~e ||| f))) - 2 *  ~~~( ~~~d &&& (e &&& f)) + 3 *  ~~~(d ^^^ ( ~~~e ||| f)) + 4 * (d ^^^ f) - 5 * (e ^^^ (d &&& (e ^^^ f))) + 5 * (d ^^^ (e &&& f)) - 2 * ((d &&& e) |||  ~~~(e ||| f)) + 5 * (f ||| (d &&&  ~~~e)) + 1 * ((d &&& e) |||  ~~~(e |||  ~~~f)) - 7 * (d ^^^ ( ~~~e ||| f)) - 11 * ( ~~~d &&& ( ~~~e ||| f)) - 1 * (f ^^^ (d &&&  ~~~e)) - 1 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 2 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 6 * (f ^^^ (d &&& (e ||| f))) - 1 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 5 * (f ||| (d ^^^ e)) - 3 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 4 * f - 1 * ((d &&& e) ^^^ (e |||  ~~~f)) - 2 * (f |||  ~~~(d ||| e)) - 11 *  ~~~(d ||| ( ~~~e &&& f)) - 1 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 7 *  ~~~(d ^^^ e) - 3 * ( ~~~f ||| (d ^^^ e)) - 3 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 11 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 3 * (d ||| (e ||| f)) + 2 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 1 * (d ||| e) + 18 *  ~~~(d ||| (e ||| f)) + 15 *  ~~~(d ||| ( ~~~e ||| f)) - 18 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 38 * ( ~~~d &&& ( ~~~e &&& f)) + 26 * ( ~~~d &&& (e &&& f)) - 10 * (d &&& ( ~~~e &&& f)) - 8 * (d &&& (e &&& f)) = 14 *  ~~~( ~~~d ||| (e ||| f)) - 5 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f))

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

theorem mul_splat_fold_proof : mul_splat_fold_before ⊑ mul_splat_fold_after

theorem test58_proof : test58_before ⊑ test58_after

theorem ashr_C1_add_A_C2_i32_proof : ashr_C1_add_A_C2_i32_before ⊑ ashr_C1_add_A_C2_i32_after

theorem alive_AndOrXor_1733 : alive_AndOrXor_1733_src ⊑ alive_AndOrXor_1733_tgt

theorem icmp_eq_or_z_or_pow2orz_fail_nonzero_const_proof : icmp_eq_or_z_or_pow2orz_fail_nonzero_const_before ⊑ icmp_eq_or_z_or_pow2orz_fail_nonzero_const_after

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

theorem main5f_like_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 → ¬True → 0#32 = zeroExtend 32 0#1

theorem icmp_ne_sext_ne_zero_proof : icmp_ne_sext_ne_zero_before ⊑ icmp_ne_sext_ne_zero_after

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

theorem ule_or_min_commute_proof : ule_or_min_commute_before ⊑ ule_or_min_commute_after

theorem shl_nsw_add_negative_invalid_constant3_proof : shl_nsw_add_negative_invalid_constant3_before ⊑ shl_nsw_add_negative_invalid_constant3_after

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

theorem shift_xor_multiuse_cmp_thm (e e_1 e_2 e_3 : IntW 32) :
  mul (select (icmp IntPred.ne (const? 32 0) (LLVM.and e_3 (const? 32 4096))) e_2 (LLVM.or e_2 (const? 32 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.or 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 exact_ashr_ne_both_equal_thm (e : IntW 8) :
  icmp IntPred.ne (ashr (const? 8 (-128)) e { «exact» := true }) (const? 8 (-128)) ⊑
    icmp IntPred.ne e (const? 8 0)

theorem eq_basic_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.eq e_1 (const? 8 0)) (icmp IntPred.ugt e_1 e) ⊑
    icmp IntPred.uge (add e_1 (const? 8 (-1))) e

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

theorem icmp_eq_mul_nsw_nonequal_proof : icmp_eq_mul_nsw_nonequal_before ⊑ icmp_eq_mul_nsw_nonequal_after

lemma RawCNFA.reverse_spec_procesState {m : RawCNFA A} (hwf : m.WF) s₀ a₀ ss' (hs₀ : s₀ ∈ m.states) :
    let motive m' ss' :=
      (∀ s ∈ ss', s ∈ m.states) →
        m'.WF ∧ m'.stateMax = m.stateMax ∧ m'.initials = m.initials ∧ m'.finals = m.finals ∧
          ∀ s a s', s' ∈ m'.tr s a ↔ (s' ∈ m.tr s a ∨ s' = s₀ ∧ a = a₀ ∧ s ∈ ss')
    motive (RawCNFA.reverse.processState m (s₀, a₀) ss') ss'.toSet

theorem add_smax_simplify_proof : add_smax_simplify_before ⊑ add_smax_simplify_after

@[simp] theorem carry'_zero
    (initCarry : Bool) (x y : BitStream) :
  (carry' initCarry x y 0) = initCarry

theorem land_land_left2_proof : land_land_left2_before ⊑ land_land_left2_after

theorem ule_swap_or_not_min_proof : ule_swap_or_not_min_before ⊑ ule_swap_or_not_min_after

theorem sext_ule_sext_proof : sext_ule_sext_before ⊑ sext_ule_sext_after

theorem icmp_ne_and_pow2_shl_pow2_proof : icmp_ne_and_pow2_shl_pow2_before ⊑ icmp_ne_and_pow2_shl_pow2_after

theorem ashr_sgt_noexact_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬3#8 ≥ ↑8 → ofBool (10#8 <ₛ x.sshiftRight' 3#8) = ofBool (87#8 <ₛ x)

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

theorem e_2491 :
     - 7 * (e ^^^ (d |||  ~~~f)) + 5 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 11 * (f ^^^  ~~~(d &&& (e ||| f))) + 1 * (d &&&  ~~~e) + 2 * (e ^^^  ~~~(d &&& (e &&& f))) + 3 * ((d ||| e) &&& (e ^^^ f)) - 11 *  ~~~( ~~~d &&& (e &&& f)) - 1 * (d ^^^ (e ^^^ f)) + 1 * (e |||  ~~~f) - 2 * ( ~~~f |||  ~~~(d ^^^ e)) - 1 * (f ^^^ (d &&& e)) + 4 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 2 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 6 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 5 * (f |||  ~~~(d ^^^ e)) + 4 *  ~~~( ~~~d &&& (e ||| f)) - 11 * (f ^^^ (d ||| ( ~~~e ||| f))) - 5 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 6 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 6 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 1 * (d ^^^ (e ||| f)) + 2 *  ~~~f + 5 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 1 * (e &&& (d ^^^ f)) + 3 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 2 * (e ||| f) - 11 * (e ^^^  ~~~(d &&& f)) + 1 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 5 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 3 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 1 * (e |||  ~~~(d |||  ~~~f)) + 1 * (f ||| (d ^^^ e)) + 1 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) - 2 * (f |||  ~~~(d |||  ~~~e)) + 5 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 2 * ( ~~~f &&& (d ^^^ e)) + 4 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 11 *  ~~~(d ^^^ (e ||| f)) + 1 *  ~~~( ~~~d ||| ( ~~~e &&& f)) + 7 * ((d ^^^ e) &&& (d ^^^ f)) - 2 * ( ~~~e ||| (d ^^^ f)) - 2 * (d ^^^ (e &&& f)) + 1 * (e &&&  ~~~f) + 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 6 * ((d &&& f) ^^^ (e ||| f)) + 2 * d + 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 7 * f + 2 *  ~~~(d ^^^ (e &&& f)) + 5 * (e &&&  ~~~(d ^^^ f)) + 1 *  ~~~(d &&& (e ||| f)) - 11 *  ~~~e - 7 * (d ||| (e &&& f)) + 1 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 1 * (d &&& ( ~~~e ||| f)) - 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 11 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 1 *  ~~~(d &&&  ~~~f) - 7 * ((d ^^^ e) ||| (d ^^^ f)) - 1 * (d ||| (e ^^^ f)) - 2 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 7 * (e ^^^ (d &&& (e ||| f))) - 2 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 6 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 1 * (f ^^^ (d ||| ( ~~~e &&& f))) + 11 * (e &&& (d |||  ~~~f)) - 2 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 1 * (d |||  ~~~e) + 5 * (e ^^^ (d &&& ( ~~~e ||| f))) + 3 * (f ^^^ (d ||| (e ||| f))) - 2 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * (f ^^^ (d ||| (e &&& f))) - 1 *  ~~~(d &&& (e ^^^ f)) + 47 *  ~~~(d ||| (e ||| f)) - 26 *  ~~~(d ||| ( ~~~e ||| f)) + 58 *  ~~~( ~~~d ||| (e ||| f)) + 28 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 62 * ( ~~~d &&& ( ~~~e &&& f)) + 52 * ( ~~~d &&& (e &&& f)) + 24 * (d &&& ( ~~~e &&& f)) + 24 * (d &&& (e &&& f)) = 11 *  ~~~(d &&&  ~~~e) + 3 * (f ||| (d &&&  ~~~e))

theorem zext_sext_ugt_known_nonneg_proof : zext_sext_ugt_known_nonneg_before ⊑ zext_sext_ugt_known_nonneg_after

theorem test13_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x_1 <ᵤ x) ^^^ ofBool (x <ᵤ x_1) = ofBool (x_1 != x)

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

theorem icmp_sle2_proof : icmp_sle2_before ⊑ icmp_sle2_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 bool_zext_thm (e : IntW 1) : lshr (sext 16 e) (const? 16 15) ⊑ zext 16 e

@[simp] theorem Com.denoteLets_var (e : Expr d Γ eff t) (body : Com d _ eff u) [LawfulMonad d.m] :
    (Com.var e body).denoteLets =
        fun V => e.denote V >>= body.denoteLets

theorem xor_nosignbit_ashr_thm (e : IntW 32) :
  ashr (LLVM.xor e (const? 32 2147418112)) (const? 32 8) ⊑ LLVM.xor (ashr e (const? 32 8)) (const? 32 8388352)

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

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

theorem ashr_known_pos_exact_thm (e e_1 : IntW 8) :
  ashr (LLVM.and e_1 (const? 8 127)) e { «exact» := true } ⊑
    lshr (LLVM.and e_1 (const? 8 127)) e { «exact» := true }

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

theorem e_435 :
     - 11 *  ~~~(x ^^^ y) + 11 *  ~~~(x &&&  ~~~y) + 7 * (x ^^^ y) + 4 *  ~~~y + 2 *  ~~~x - 9 *  ~~~(x |||  ~~~y) - 5 * (x &&&  ~~~y) + 6 * (x &&& y) = 11 *  ~~~(x &&&  ~~~x) - 5 * (x |||  ~~~y)

theorem positive_biggershl_ashrexact_proof : positive_biggershl_ashrexact_before ⊑ positive_biggershl_ashrexact_after

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

theorem masked_and_notA_slightly_optimized_proof : masked_and_notA_slightly_optimized_before ⊑ masked_and_notA_slightly_optimized_after

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

theorem mul_four (x : BitVec w) : 4 * x = x + x + x + x

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

theorem positive_sameconst_shlnsw_proof : positive_sameconst_shlnsw_before ⊑ positive_sameconst_shlnsw_after

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

theorem e_1510 :
     - 11 *  ~~~c + 3 * ( ~~~c &&&  ~~~(a ^^^ b)) + 10 *  ~~~(a ||| (b ||| c)) + 11 *  ~~~(a ||| ( ~~~b ||| c)) + 13 *  ~~~( ~~~a ||| (b ||| c)) + 8 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 2 * ( ~~~a &&& ( ~~~b &&& c)) + 2 * (a &&& ( ~~~b &&& c)) + 2 * (a &&& (b &&& c)) =  - 2 * ( ~~~a &&& (b &&& c)) + 2 *  ~~~(b &&&  ~~~c)

theorem e_960 :
    3 *  ~~~(z ^^^ t) - 6 * (z ^^^ t) - 11 * t - 3 * z + 17 *  ~~~(z |||  ~~~t) + 12 * (z &&&  ~~~t) = 3 *  ~~~t - 11 * (z &&& t)

theorem ule_umax1_proof : ule_umax1_before ⊑ ule_umax1_after

theorem test1_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x ^^^ 5#32 == 10#32) = 1#1 → ¬ofBool (x == 15#32) = 1#1 → False

theorem test_zext3_proof : test_zext3_before ⊑ test_zext3_after

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

theorem sge_to_ugt_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (15#8 ≤ₛ x ^^^ BitVec.ofInt 8 (-128)) = ofBool (BitVec.ofInt 8 (-114) <ᵤ x)

theorem scalar_i32_lshr_and_negC_eq_X_is_constant2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → ofBool (268435456#32 >>> x &&& BitVec.ofInt 32 (-8) == 0#32) = ofBool (25#32 <ᵤ x)

theorem urem_common_divisor_defined_cond_thm.extracted_1._3 : ∀ (x x_1 : BitVec 5) (x_2 : BitVec 1),
  ¬(x_2 = 1#1 ∨ x_1 = 0) → ¬x_2 = 1#1 → x_1 = 0 → False

theorem trunc_lshr_sext_thm (e : IntW 8) : trunc 8 (lshr (sext 32 e) (const? 32 6)) ⊑ ashr e (const? 8 6)

theorem testi8i8_proof : testi8i8_before ⊑ testi8i8_after

theorem gt_signed_to_small_negative_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (BitVec.ofInt 32 (-17) <ₛ signExtend 32 x) = ofBool (BitVec.ofInt 8 (-17) <ₛ x)

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

theorem add_select_sext_proof : add_select_sext_before ⊑ add_select_sext_after

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

lemma eq_zero_of_toNat_mod_eq_zero {x : BitVec w} (hx : x.toNat % 2^w = 0) : x = 0

theorem e_1537 :
     - 3 * (c ^^^  ~~~(a &&& (b ||| c))) - 2 * (b ^^^ ( ~~~a ||| (b &&& c))) + 11 * ( ~~~a ||| ( ~~~b &&& c)) - 1 *  ~~~(a ^^^ ( ~~~b &&& c)) - 1 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) - 4 *  ~~~(a ||| (b ||| c)) - 7 *  ~~~(a ||| ( ~~~b ||| c)) + 4 *  ~~~( ~~~a ||| (b ||| c)) - 8 * ( ~~~a &&& ( ~~~b &&& c)) - 10 * ( ~~~a &&& (b &&& c)) - 6 * (a &&& ( ~~~b &&& c)) + 3 * (a &&& (b &&& c)) =  - 3 *  ~~~( ~~~a ||| ( ~~~b ||| c))

theorem t1_sub_from_falseval_proof : t1_sub_from_falseval_before ⊑ t1_sub_from_falseval_after

theorem e_2344 :
     - 1 *  ~~~d - 5 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 2 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 11 * ((d ^^^ e) ||| (d ^^^ f)) + 1 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 3 * (d ||| e) - 11 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 11 *  ~~~(d ^^^ (e &&& f)) - 3 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 6 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 7 * (f ^^^ (d &&& e)) + 2 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 2 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 1 * (e ||| (d &&& f)) - 1 *  ~~~(d ||| (e ^^^ f)) + 1 * (e |||  ~~~(d ||| f)) - 5 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 7 * (d ^^^ e) + 11 * (f ^^^ (d &&& (e ||| f))) + 1 * (e &&&  ~~~(d ^^^ f)) - 7 * (e ||| (d ^^^ f)) - 1 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 1 *  ~~~(d |||  ~~~e) + 1 * (e ^^^ ( ~~~d &&& (e ||| f))) - 6 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 * (e &&&  ~~~(d &&&  ~~~f)) + 2 *  ~~~( ~~~d ||| (e &&& f)) - 1 * ( ~~~d ||| ( ~~~e &&& f)) - 1 * ( ~~~f ||| (d ^^^ e)) + 1 * (f ^^^  ~~~(d &&& (e &&& f))) + 5 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 4 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 1 *  ~~~(e &&&  ~~~f) - 6 * ( ~~~d &&& (e ||| f)) + 2 *  ~~~( ~~~d &&& (e &&& f)) + 2 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 1 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 11 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 3 * (d |||  ~~~e) - 11 * (f ^^^ (d ||| ( ~~~e ||| f))) + 5 * (e ^^^ ( ~~~d ||| (e &&& f))) + 4 *  ~~~(d &&&  ~~~d) - 1 * (f &&&  ~~~(d &&& e)) + 5 * (f ^^^  ~~~(d &&&  ~~~e)) + 5 * (e &&&  ~~~f) + 1 * ( ~~~e &&& (d ^^^ f)) + 1 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 1 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) - 5 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 2 * ( ~~~e |||  ~~~(d ^^^ f)) + 11 * ( ~~~f &&& (d ^^^ e)) + 1 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 3 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 2 * (f &&&  ~~~(d &&&  ~~~e)) + 2 * (e ^^^ (d &&& ( ~~~e ||| f))) - 3 * (e &&& f) + 2 * (f ^^^ (d &&&  ~~~e)) + 34 *  ~~~(d ||| (e ||| f)) + 7 *  ~~~(d ||| ( ~~~e ||| f)) + 18 *  ~~~( ~~~d ||| (e ||| f)) - 13 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 8 * ( ~~~d &&& ( ~~~e &&& f)) + 3 * ( ~~~d &&& (e &&& f)) + 1 * (d &&& ( ~~~e &&& f)) + 34 * (d &&& (e &&& f)) =  - 1 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 1 * (e ||| (d &&&  ~~~f))

theorem or_xor_xor_normal_variant2_thm (e e_1 : IntW 8) :
  LLVM.or (LLVM.xor (LLVM.and e_1 e) e) (LLVM.xor e_1 (LLVM.and e_1 e)) ⊑ LLVM.xor e_1 e

theorem add_shl_same_amount_nuw_proof : add_shl_same_amount_nuw_before ⊑ add_shl_same_amount_nuw_after

theorem test11c_proof : test11c_before ⊑ test11c_after

theorem icmp_and_ashr_multiuse_logical_thm (e : IntW 32) :
  select (icmp IntPred.ne (LLVM.and (ashr e (const? 32 4)) (const? 32 15)) (const? 32 14))
      (icmp IntPred.ne (LLVM.and (ashr e (const? 32 4)) (const? 32 31)) (const? 32 27)) (const? 1 0) ⊑
    LLVM.and (icmp IntPred.ne (LLVM.and e (const? 32 240)) (const? 32 224))
      (icmp IntPred.ne (LLVM.and e (const? 32 496)) (const? 32 432))

theorem AvoidCollision_toFin_signExtend_of_le {x : BitVec w} (hv : v ≤ w):
    (x.signExtend v).toFin = Fin.ofNat (2 ^ v) x.toNat

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

theorem and_lshr_and_proof : and_lshr_and_before ⊑ and_lshr_and_after

theorem t4_ugt_slt_65536_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬ofBool (65535#32 <ᵤ x) = 1#1 → ofBool (65535#32 <ₛ x) = 1#1 ∨ ofBool (x <ₛ 0#32) = 1#1 → False

theorem is_ascii_alphabetic_inverted_thm (e : IntW 32) :
  select (icmp IntPred.ult (add e (const? 32 (-91)) { «nsw» := true, «nuw» := false }) (const? 32 (-26)))
      (icmp IntPred.ult (add e (const? 32 (-123)) { «nsw» := true, «nuw» := false }) (const? 32 (-26)))
      (const? 1 0) ⊑
    icmp IntPred.ult (add (LLVM.and e (const? 32 (-33))) (const? 32 (-91))) (const? 32 (-26))

@[symm]
theorem equal_up_to_symm (e : a ≈ʷ b) : b ≈ʷ a

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

theorem icmp_slt_0_or_icmp_sge_neg1_i32_proof : icmp_slt_0_or_icmp_sge_neg1_i32_before ⊑ icmp_slt_0_or_icmp_sge_neg1_i32_after

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

theorem ashr_and_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ x + 1#8 ≥ ↑8) →
    ¬x ≥ ↑8 →
      (BitVec.ofInt 8 (-64)).sshiftRight' x &&& (BitVec.ofInt 8 (-128)).sshiftRight' (x + 1#8) =
        (BitVec.ofInt 8 (-64)).sshiftRight' x

theorem shl_sub_i8_proof : shl_sub_i8_before ⊑ shl_sub_i8_after

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

theorem main5e_like_proof : main5e_like_before ⊑ main5e_like_after

theorem test19_proof : test19_before ⊑ test19_after

theorem ashrslt_02_02_exact_proof : ashrslt_02_02_exact_before ⊑ ashrslt_02_02_exact_after

theorem land_land_left1_proof : land_land_left1_before ⊑ land_land_left1_after

@[simp]
theorem Term.toBV_boolVar {wenv : WidthExpr.Env wcard}
    {tctx : Term.Ctx wcard tcard}
    (benv : Term.BoolEnv bcard)
    (tenv : tctx.Env wenv) (v : Fin bcard) :
  Term.toBV benv nenv ienv penv tenv (.boolVar v) = benv v

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

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

theorem positive_with_aggressive_icmp_logical_proof : positive_with_aggressive_icmp_logical_before ⊑ positive_with_aggressive_icmp_logical_after

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

theorem test1_proof : test1_before ⊑ test1_after

theorem shl_trunc_bigger_shl_thm (e : IntW 32) :
  shl (trunc 8 (shl e (const? 32 4))) (const? 8 2) ⊑ shl (trunc 8 e) (const? 8 6)

theorem main2_logical_proof : main2_logical_before ⊑ main2_logical_after

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 e_1362 :
     - 11 *  ~~~(z ^^^ t) + 1 * (z ^^^ t) - 3 * t - 6 *  ~~~(z &&&  ~~~z) + 11 * (z |||  ~~~t) - 2 * z + 9 *  ~~~(z ||| t) + 11 *  ~~~(z |||  ~~~t) - 4 * (z &&&  ~~~t) + 11 * (z &&& t) = 3 *  ~~~z

theorem ashrsgt_01_08_exact_proof : ashrsgt_01_08_exact_before ⊑ ashrsgt_01_08_exact_after

theorem xor_nosignbit_select_lshr_proof : xor_nosignbit_select_lshr_before ⊑ xor_nosignbit_select_lshr_after

theorem gt_signed_to_large_unsigned_proof : gt_signed_to_large_unsigned_before ⊑ gt_signed_to_large_unsigned_after

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

theorem sle_smin1_thm (e e_1 : IntW 32) :
  icmp IntPred.sle (select (icmp IntPred.slt e_1 e) e_1 e) e_1 ⊑ const? 1 1

theorem or_to_nxor_multiuse_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  True ∧ (x_1 &&& x &&& ((x_1 ||| x) ^^^ -1#32) != 0) = true → False

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

theorem eq_commuted_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(x == 0 || 8 != 1 && 43#8 == intMin 8 && x == -1) = true →
    ofBool (x_1 == 0#8) ||

theorem shl_xor_lshr_proof : shl_xor_lshr_before ⊑ shl_xor_lshr_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 scalar_i32_signbit_shl_and_eq_nonzero_proof : scalar_i32_signbit_shl_and_eq_nonzero_before ⊑ scalar_i32_signbit_shl_and_eq_nonzero_after

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

theorem not_ashr_const_proof : not_ashr_const_before ⊑ not_ashr_const_after

theorem test7_thm (e : IntW 32) : LLVM.srem (mul e (const? 32 8)) (const? 32 4) ⊑ const? 32 0

theorem positive_biggershl_shlnsw_lshrexact_proof : positive_biggershl_shlnsw_lshrexact_before ⊑ positive_biggershl_shlnsw_lshrexact_after

theorem ashrslt_03_02_proof : ashrslt_03_02_before ⊑ ashrslt_03_02_after

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

theorem t4_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 8), x = 1#1 → x_1 - BitVec.ofInt 8 (-42) = 42#8 + x_1

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

theorem pr33078_1_proof : pr33078_1_before ⊑ pr33078_1_after

theorem logic_or_logic_and_1_proof : logic_or_logic_and_1_before ⊑ logic_or_logic_and_1_after

theorem test6_proof : test6_before ⊑ test6_after

theorem test47_proof : test47_before ⊑ test47_after

theorem and_ashr_not_commuted_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 8),
  ¬(x_1 ≥ ↑8 ∨ x_1 ≥ ↑8) →
    ¬x_1 ≥ ↑8 → (x_2.sshiftRight' x_1 ^^^ -1#8) &&& x.sshiftRight' x_1 = (x &&& (x_2 ^^^ -1#8)).sshiftRight' x_1

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

theorem lor_band_left1_proof : lor_band_left1_before ⊑ lor_band_left1_after

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

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

theorem testi16i8_ne_proof : testi16i8_ne_before ⊑ testi16i8_ne_after

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

theorem bv_820' :
    ∀ (e e_1 : LLVM.IntW 9), LLVM.udiv (LLVM.sub e (LLVM.urem e e_1)) e_1 ⊑ LLVM.udiv e e_1

theorem foo_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(7#8 ≥ ↑8 ∨ 7#8 ≥ ↑8 ∨ 5#8 ≥ ↑8 ∨ 7#8 ≥ ↑8) →
    7#8 ≥ ↑8 ∨
        2#8 ≥ ↑8 ∨
          True ∧ (40#8).ssubOverflow (x &&& 84#8) = true ∨
            True ∧ (x &&& 33#8 &&& (40#8 - (x &&& 84#8) &&& 84#8) != 0) = true ∨
              7#8 ≥ ↑8 ∨
                True ∧
                  ((x &&& 33#8 ||| 40#8 - (x &&& 84#8) &&& 84#8) &&& (x_1 <<< 7#8 ^^^ x &&& BitVec.ofInt 8 (-118)) !=
                      0) =
                    true →
      False

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

theorem test2_thm (e : IntW 32) :
  icmp IntPred.ugt e (const? 32 0) ⊑ icmp IntPred.ne e (const? 32 0)

theorem not_or_or_and_not_and_and_commute2_and_proof : not_or_or_and_not_and_and_commute2_and_before ⊑ not_or_or_and_not_and_and_commute2_and_after

theorem bitwise_and_logical_and_masked_icmp_allones_poison1_proof : bitwise_and_logical_and_masked_icmp_allones_poison1_before ⊑ bitwise_and_logical_and_masked_icmp_allones_poison1_after

theorem main7f_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 shl_trunc_smaller_shl_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(2#32 ≥ ↑32 ∨ 4#8 ≥ ↑8) → ¬6#8 ≥ ↑8 → truncate 8 (x <<< 2#32) <<< 4#8 = truncate 8 x <<< 6#8

theorem t6_ugt_sgt_128_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 127)) 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 masked_icmps_mask_notallzeros_bmask_mixed_swapped_7_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_swapped_7_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_swapped_7_logical_after

theorem mul_thm (e e_1 : IntW 32) :
  zext 32 (mul (trunc 8 e_1) (trunc 8 e)) ⊑ LLVM.and (mul e_1 e) (const? 32 255)

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

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

theorem icmp_eq_x_invertable_y_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == x_1 &&& (x ^^^ -1#8)) = ofBool (x_1 &&& x == 0#8)

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

theorem e_1653 :
     - 1 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) + 11 * (b ||| (a &&&  ~~~c)) - 1 *  ~~~( ~~~a ||| (b &&& c)) - 11 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) - 11 * ((a &&& b) |||  ~~~(b ||| c)) + 4 * (c &&&  ~~~(a &&&  ~~~b)) + 2 * (c &&&  ~~~(a ^^^ b)) - 7 * (c &&& (a ^^^ b)) + 3 * ((a ^^^ b) |||  ~~~(a ^^^ c)) - 11 * (b ^^^ (a &&& (b ^^^ c))) + 1 * ( ~~~a ||| (b ||| c)) + 5 * (b ^^^  ~~~( ~~~a ||| (b ^^^ c))) - 11 * ( ~~~c ||| (a ^^^ b)) - 2 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) - 2 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) + 7 * ((b &&& c) ||| (a &&& (b ||| c))) + 35 *  ~~~(a ||| (b ||| c)) + 10 *  ~~~(a ||| ( ~~~b ||| c)) - 1 *  ~~~( ~~~a ||| (b ||| c)) - 4 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 6 * ( ~~~a &&& ( ~~~b &&& c)) + 26 * (a &&& ( ~~~b &&& c)) - 1 * (a &&& (b &&& c)) =  - 5 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) + 1 * ((a &&& b) ^^^  ~~~(a ^^^ (b &&& c)))

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 and_umin_proof : and_umin_before ⊑ and_umin_after

theorem c_0_1_0_proof : c_0_1_0_before ⊑ c_0_1_0_after

theorem ashrsgt_02_02_exact_proof : ashrsgt_02_02_exact_before ⊑ ashrsgt_02_02_exact_after

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

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

theorem sext_sext_ult_proof : sext_sext_ult_before ⊑ sext_sext_ult_after

theorem sext_sext_sge_op0_narrow_thm (e : IntW 8) (e_1 : IntW 5) :
  icmp IntPred.sge (sext 32 e_1) (sext 32 e) ⊑ icmp IntPred.sle e (sext 8 e_1)

theorem twoway_clamp_lt_proof : twoway_clamp_lt_before ⊑ twoway_clamp_lt_after

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

theorem or_ranges_single_elem_left_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (5#8 ≤ᵤ x) &&& ofBool (x ≤ᵤ 10#8) ||

theorem e_1419 :
    11 * (z ||| t) - 2 *  ~~~z + 4 * t + 1 *  ~~~(z &&& t) + 1 *  ~~~(z &&&  ~~~t) + 3 *  ~~~(z ^^^ t) + 2 * (z |||  ~~~t) - 3 *  ~~~t - 11 * (z &&&  ~~~t) - 21 * (z &&& t) = 15 *  ~~~(z |||  ~~~t) + 2 *  ~~~(z ||| t)

theorem com_Γ : com.1 = (Γn 1)

theorem e_2007 :
    1 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 * (f ^^^ ( ~~~d &&& (e ||| f))) + 11 *  ~~~(e ^^^ f) + 1 *  ~~~(e &&& f) + 11 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) - 1 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 1 * ( ~~~d &&& ( ~~~e ||| f)) + 1 * (e &&& (d ||| f)) + 5 * (e ^^^ (d &&& (e ||| f))) - 5 * (d ^^^ f) - 2 * (e ||| (d &&&  ~~~f)) + 1 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 11 * (f &&&  ~~~(d ^^^ e)) + 7 * (d ^^^ e) - 3 *  ~~~(d &&& ( ~~~e &&& f)) - 3 * ((d &&& e) ^^^ (e ||| f)) + 4 *  ~~~(d &&& f) + 1 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 5 * (d ^^^ ( ~~~e ||| f)) + 1 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 7 * (f ^^^  ~~~(d ||| e)) + 3 * (f ^^^ ( ~~~d ||| (e ||| f))) - 2 * (e ^^^ (d &&& ( ~~~e ||| f))) - 6 * (d ||| (e ^^^ f)) - 1 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 18 *  ~~~(d ||| (e ||| f)) - 20 *  ~~~( ~~~d ||| (e ||| f)) + 12 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 1 * ( ~~~d &&& ( ~~~e &&& f)) - 13 * ( ~~~d &&& (e &&& f)) - 18 * (d &&& ( ~~~e &&& f)) - 27 * (d &&& (e &&& f)) = 3 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) + 3 *  ~~~(d ||| ( ~~~e ||| f))

theorem add_eq (x : BitVec w) : x = x + 0

theorem e_1943 :
    5 * (b |||  ~~~(a ^^^ c)) - 11 * ((a &&& b) ^^^ (b ||| c)) - 2 * (b ^^^  ~~~( ~~~a ||| (b ^^^ c))) + 4 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) + 1 *  ~~~(b &&&  ~~~c) + 1 *  ~~~(a ^^^ b) - 1 *  ~~~(a ||| (b &&& c)) + 1 * (c ^^^  ~~~(a &&& (b &&& c))) - 2 *  ~~~(a &&&  ~~~b) - 7 *  ~~~(a &&& c) + 7 * (c ^^^ (a ||| b)) + 3 * (b ^^^ (a &&& c)) - 1 * (a |||  ~~~b) - 7 * (b ||| (a &&&  ~~~c)) + 5 * (b ^^^ (a ||| (b ||| c))) - 2 * (c ^^^  ~~~(a ||| (b &&& c))) + 1 * (a ^^^ (b ^^^ c)) + 11 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) + 4 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) - 6 * (c ^^^ ( ~~~a ||| (b ||| c))) + 2 * ((a ^^^ b) |||  ~~~(a ^^^ c)) + 2 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) + 7 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) + 11 * ( ~~~c &&&  ~~~(a ^^^ b)) - 2 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) - 2 * ( ~~~b &&&  ~~~(a ^^^ c)) - 2 * (c ^^^  ~~~(a &&& b)) + 1 *  ~~~a + 3 * (b ^^^ ( ~~~a &&& (b ||| c))) + 4 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 7 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) + 7 *  ~~~(a &&& (b &&& c)) - 1 * (c &&& (a ^^^ b)) - 2 * (c ^^^  ~~~(a |||  ~~~b)) - 3 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 2 * ((a &&& b) |||  ~~~(b ||| c)) - 1 *  ~~~(b &&& c) - 1 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) + 3 * (c ^^^ (a ||| (b &&& c))) + 1 * ( ~~~a ||| (b &&& c)) + 1 * ((a &&& b) |||  ~~~(b |||  ~~~c)) - 2 * (c ^^^ (a &&& b)) + 7 * ((a ^^^ b) ||| (a ^^^ c)) - 1 * ((a &&&  ~~~b) ||| (b ^^^ c)) - 1 * ((a &&& b) ^^^ (b |||  ~~~c)) + 5 * (b ^^^ (a ||| c)) - 25 *  ~~~(a ||| (b ||| c)) - 21 *  ~~~(a ||| ( ~~~b ||| c)) - 23 *  ~~~( ~~~a ||| (b ||| c)) - 38 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 26 * ( ~~~a &&& ( ~~~b &&& c)) - 35 * (a &&& ( ~~~b &&& c)) - 8 * (a &&& (b &&& c)) =  - 4 *  ~~~(a ||| ( ~~~b &&& c)) + 9 * ( ~~~a &&& (b &&& c))

theorem pr40493_neg1_proof : pr40493_neg1_before ⊑ pr40493_neg1_after

theorem eg5 (u w : Nat) (x : BitVec w) :
    (x.signExtend u).zeroExtend u = x.signExtend u

theorem icmp_ne_and_pow2_minus1_shl1_proof : icmp_ne_and_pow2_minus1_shl1_before ⊑ icmp_ne_and_pow2_minus1_shl1_after

theorem nonexact_ashr_eq_proof : nonexact_ashr_eq_before ⊑ nonexact_ashr_eq_after

theorem t1_thm (e : IntW 32) (e_1 : IntW 16) :
  LLVM.sdiv (zext 32 e_1) (shl (const? 32 2) e) ⊑ lshr (zext 32 e_1) (add e (const? 32 1))

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

lemma reduce_eval {M : NFA α σ} {w} (q : σ) : (∃ hq, ⟨q, hq⟩ ∈ M.reduce.eval w) ↔ q ∈ M.eval w

theorem alive_275_2   : alive_275_2_src ⊑ alive_275_2_tgt

theorem select_zext_or_eq_ult_add_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x + BitVec.ofInt 32 (-3) <ᵤ 2#32) = 1#1 →
    zeroExtend 32 (ofBool (x == 5#32)) = zeroExtend 32 (ofBool (x + BitVec.ofInt 32 (-3) <ᵤ 3#32))

@[simp] theorem bvars_var  :
  (var e body : Com d Γ eff t).bvars = e.bvars + body.bvars

theorem exact_lshr_ne_noexactdiv_proof : exact_lshr_ne_noexactdiv_before ⊑ exact_lshr_ne_noexactdiv_after

theorem or_simplify_ult_proof : or_simplify_ult_before ⊑ or_simplify_ult_after

theorem n10_wrong_pred2_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (add e_1 e) e ⊑ icmp IntPred.eq e_1 (const? 8 0)

theorem sge_to_ugt_proof : sge_to_ugt_before ⊑ sge_to_ugt_after

theorem addhshlhsdivhscalar1_thm (e : IntW 8) :
  add (shl (LLVM.sdiv e (const? 8 (-64))) (const? 8 6)) e ⊑ LLVM.srem e (const? 8 64)

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

theorem t6_ugt_sgt_65536_proof : t6_ugt_sgt_65536_before ⊑ t6_ugt_sgt_65536_after

theorem test13_proof : test13_before ⊑ test13_after

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

theorem t0_proof : t0_before ⊑ t0_after

theorem select_ashr_icmp_bad_thm.extracted_1._3 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 == 1#32) = 1#1 → ¬x_2 ≥ ↑32 → 1#32 ≥ ↑32 → False

theorem add_mask_ashr27_i32_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(27#32 ≥ ↑32 ∨ 27#32 ≥ ↑32) →
    27#32 ≥ ↑32 ∨ 27#32 ≥ ↑32 ∨ True ∧ (x.sshiftRight' 27#32 &&& 8#32).saddOverflow (x.sshiftRight' 27#32) = true →
      False

theorem p_commutative2_proof : p_commutative2_before ⊑ p_commutative2_after

theorem test11_logical_thm (e : IntW 32) :
  select (icmp IntPred.ne (LLVM.and e (const? 32 2)) (const? 32 0)) (const? 1 1)
      (icmp IntPred.ugt e (const? 32 3)) ⊑
    icmp IntPred.ugt e (const? 32 1)

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 negative_not_next_power_of_two_logical_thm (e : IntW 32) :
  select (icmp IntPred.sgt e (const? 32 (-1))) (icmp IntPred.ult (add e (const? 32 64)) (const? 32 256))
      (const? 1 0) ⊑
    icmp IntPred.ult e (const? 32 192)

theorem trunc_lshr_big_mask_proof : trunc_lshr_big_mask_before ⊑ trunc_lshr_big_mask_after

theorem shr_umax_proof : shr_umax_before ⊑ shr_umax_after

theorem test_shl__nsw_is_safe_proof : test_shl__nsw_is_safe_before ⊑ test_shl__nsw_is_safe_after

theorem pb_proof : pb_before ⊑ pb_after

theorem trunc_shl_nsw_31_i32_i64_thm (e : IntW 64) :
  trunc 32 (shl e (const? 64 31) { «nsw» := true, «nuw» := false }) ⊑ shl (trunc 32 e) (const? 32 31)

theorem c_1_1_0_proof : c_1_1_0_before ⊑ c_1_1_0_after

theorem in_constant_14_vary_thm (e : IntW 4) :
  LLVM.xor (LLVM.and (LLVM.xor e (const? 4 (-2))) (const? 4 1)) e ⊑ LLVM.and e (const? 4 (-2))

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 absdiff_thm.extracted_1._2 : ∀ (x x_1 : BitVec 64),
  ¬ofBool (x_1 <ᵤ x) = 1#1 →
    (signExtend 64 (ofBool (x_1 <ᵤ x)) ^^^ x_1 - x) - signExtend 64 (ofBool (x_1 <ᵤ x)) = x_1 - x

theorem masked_and_notA_slightly_optimized_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.uge e (const? 32 8)) (icmp IntPred.ne (LLVM.and e (const? 32 39)) e) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 (-40))) (const? 32 0)

theorem bitwise_and_logical_and_masked_icmp_asymmetric_proof : bitwise_and_logical_and_masked_icmp_asymmetric_before ⊑ bitwise_and_logical_and_masked_icmp_asymmetric_after

theorem test3_proof : test3_before ⊑ test3_after

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

theorem ashr_lshr2_i128_thm.extracted_1._1 : ∀ (x x_1 : BitVec 128),
  ofBool (5#128 <ₛ x_1) = 1#1 → ¬x ≥ ↑128 → x_1 >>> x = x_1.sshiftRight' x

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

@[bv_multi_width_normalize]
theorem slt_iff_sle_eq_false {a b : BitVec w} : a.sle b = false ↔ b.slt a

theorem e_1112 :
     - 11 *  ~~~(z &&&  ~~~t) - 1 * (z ||| t) - 7 *  ~~~(z &&& t) - 5 *  ~~~(z &&&  ~~~z) - 7 * z + 23 *  ~~~(z ||| t) + 24 *  ~~~(z |||  ~~~t) + 24 * (z &&& t) =  - 20 * (z &&&  ~~~t)

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

theorem test44_proof : test44_before ⊑ test44_after

theorem positive_sameconst_shlnsw_ashrexact_proof : positive_sameconst_shlnsw_ashrexact_before ⊑ positive_sameconst_shlnsw_ashrexact_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 src5_thm (e e_1 : IntW 32) :
  add (LLVM.xor (LLVM.or e_1 e) (const? 32 (-1))) (LLVM.and e_1 e) ⊑ LLVM.xor (LLVM.xor e_1 e) (const? 32 (-1))

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

theorem AvoidCollision_getElem?_setWidth (m : Nat) (x : BitVec n) (i : Nat) :
    (x.setWidth m)[i]? = if i < m then some (x.getLsbD i) else none

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

theorem test3i_proof : test3i_before ⊑ test3i_after

theorem main7b_logical_thm.extracted_1._2 : ∀ (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 → 1#32 = zeroExtend 32 1#1

theorem positive_biggershl_shlnuw_thm (e : IntW 8) :
  shl (ashr e (const? 8 3)) (const? 8 6) { «nsw» := false, «nuw» := true } ⊑
    LLVM.and (shl e (const? 8 3) { «nsw» := false, «nuw» := true }) (const? 8 (-64))

theorem sgt_and_min_commute_proof : sgt_and_min_commute_before ⊑ sgt_and_min_commute_after

theorem and_or2_wrong_operand_proof : and_or2_wrong_operand_before ⊑ and_or2_wrong_operand_after

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

@[simp]
theorem Std.HashSet.mem_union' [BEq α] [Hashable α] [LawfulBEq α] {m₁ m₂ : HashSet α} :
    x ∈ m₁ ∪ m₂ ↔ x ∈ m₁ ∨ x ∈ m₂

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 sgt_swap_and_min_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 <ₛ x) = 1#1 → ofBool (x == BitVec.ofInt 8 (-128)) = 0#1

theorem add_and_or_thm (e e_1 : IntW 32) : add (LLVM.and e_1 e) (LLVM.or e_1 e) ⊑ add e_1 e

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

theorem sext_zext_nneg_slt_proof : sext_zext_nneg_slt_before ⊑ sext_zext_nneg_slt_after

theorem ne_commuted_equal_minus_1_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.ne e_1 (const? 8 (-1)))
      (icmp IntPred.uge (LLVM.sdiv (const? 8 42) e) (add e_1 (const? 8 1))) ⊑
    icmp IntPred.ult e_1 (LLVM.sdiv (const? 8 42) e)

theorem e_658 :
     - 2 * (x ^^^ y) + 2 * x - 11 *  ~~~(x &&&  ~~~x) + 1 *  ~~~y - 2 * (x ||| y) - 1 * (x |||  ~~~y) + 2 * y + 11 *  ~~~(x ||| y) + 13 *  ~~~(x |||  ~~~y) + 10 * (x &&& y) =  - 13 * (x &&&  ~~~y)

theorem left_shift_add_1 (hu : u >= r) (hs : s >= r) :
  (bw r (shlMax (bw s (addMax (bw p a) (bw q b))) (bw t c)))  =
  (bw r (addMax (bw u (shlMax (bw p a) (bw t c))) (bw u (shlMax (bw q b) (bw t c)))))

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

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

lemma RawCNFA.autSignedCmp_wf {cmp} : autSignedCmp cmp |>.WF

theorem e_1672 :
    7 * (b ^^^ ( ~~~a ||| (b ||| c))) + 11 * (c ^^^ (a ||| ( ~~~b ||| c))) + 5 *  ~~~(a &&& (b ||| c)) - 6 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) - 1 * (b ^^^ (a ||| ( ~~~b &&& c))) + 4 *  ~~~(a &&& b) + 2 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) - 7 * (b ^^^ ( ~~~a &&& (b ^^^ c))) - 5 * (c ^^^  ~~~(a ||| b)) + 3 * (a ^^^ ( ~~~b ||| c)) - 2 * (b ^^^ (a &&& (b ||| c))) - 5 * ( ~~~c &&& (a ^^^ b)) + 2 * (b ^^^ ( ~~~a ||| (b &&& c))) + 4 * (b ^^^ c) - 1 *  ~~~(b ||| c) + 4 * (b ^^^ (a |||  ~~~c)) - 1 * (b ^^^ (a &&& (b ^^^ c))) + 1 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) - 36 *  ~~~(a ||| (b ||| c)) - 15 *  ~~~(a ||| ( ~~~b ||| c)) - 26 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 31 * ( ~~~a &&& ( ~~~b &&& c)) - 12 * ( ~~~a &&& (b &&& c)) - 22 * (a &&& ( ~~~b &&& c)) + 8 * (a &&& (b &&& c)) = 29 *  ~~~( ~~~a ||| (b ||| c)) - 11 *  ~~~(a &&&  ~~~a)

theorem ashrslt_03_07_proof : ashrslt_03_07_before ⊑ ashrslt_03_07_after

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

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

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

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

theorem test15_commuted_proof : test15_commuted_before ⊑ test15_commuted_after

@[simp_denote] theorem toMonad_impure : impure.toMonad m = m

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

theorem pr4917_3_proof : pr4917_3_before ⊑ pr4917_3_after

theorem cv2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ¬x_1 ≥ ↑8 → ofBool (x <ᵤ (-1#8) >>> x_1 &&& x) = 0#1

theorem test82_proof : test82_before ⊑ test82_after

theorem PR42691_9_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.sgt e (const? 32 13)) (icmp IntPred.ne e (const? 32 2147483647)) ⊑
    icmp IntPred.ult (add e (const? 32 (-14))) (const? 32 2147483633)

theorem not_ashr_not_bitwidth_mask_proof : not_ashr_not_bitwidth_mask_before ⊑ not_ashr_not_bitwidth_mask_after

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

theorem ashr_sle_exact_proof : ashr_sle_exact_before ⊑ ashr_sle_exact_after

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

theorem ashr_lshr_exact_ashr_only_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sgt e_1 (const? 32 (-1))) (lshr e_1 e) (ashr e_1 e { «exact» := true }) ⊑
    ashr e_1 e

theorem negate_select_of_op_vs_negated_op_nsw_thm (e : IntW 8) (e_1 : IntW 1) (e_2 : IntW 8) :
  sub e_2 (select e_1 (sub (const? 8 0) e { «nsw» := true, «nuw» := false }) e) ⊑
    add (select e_1 e (sub (const? 8 0) e)) e_2

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

theorem trunc_lshr_big_mask_proof : trunc_lshr_big_mask_before ⊑ trunc_lshr_big_mask_after

theorem test25_proof : test25_before ⊑ test25_after

theorem t9_ashr_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 32),
  ¬(zeroExtend 32 (32#16 - x) ≥ ↑32 ∨ x + BitVec.ofInt 16 (-2) ≥ ↑16) →
    True ∧ (32#16 - x).msb = true ∨ zeroExtend 32 (32#16 - x) ≥ ↑32 ∨ x + BitVec.ofInt 16 (-2) ≥ ↑16 → False

theorem and_zext_eq_odd_commuted_thm (e : IntW 32) :
  LLVM.and (zext 32 (icmp IntPred.eq e (const? 32 3))) e ⊑ zext 32 (icmp IntPred.eq e (const? 32 3))

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

theorem test2_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  (x_1 ||| zeroExtend 32 x) &&& 65536#32 = x_1 &&& 65536#32

theorem test2_proof : test2_before ⊑ test2_after

@[simp] theorem le_refl (e : EffectKind) : e ≤ e

@[simp, grind=] lemma val_start_appendInl (r : DeleteRange Γ) :
    (r.appendInl (ts := ts)).start.val = r.start.val + ts.length

theorem widget_proof : widget_before ⊑ widget_after

theorem ashrsgt_02_14_exact_proof : ashrsgt_02_14_exact_before ⊑ ashrsgt_02_14_exact_after

theorem reassoc_sub_nuw_proof : reassoc_sub_nuw_before ⊑ reassoc_sub_nuw_after

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

theorem select_icmp_eq_and_1_0_lshr_tv_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 &&& 1#8 != 0#8) = 1#1 →
    ¬2#8 ≥ ↑8 → ¬(1#8 ≥ ↑8 ∨ x_1 <<< 1#8 &&& 2#8 ≥ ↑8) → x >>> 2#8 = x >>> (x_1 <<< 1#8 &&& 2#8)

theorem PR2539_A_thm.extracted_1._1 : ∀ (x : BitVec 1), ofBool (zeroExtend 32 x <ₛ 1#32) = x ^^^ 1#1

theorem test_invert_demorgan_or2_proof : test_invert_demorgan_or2_before ⊑ test_invert_demorgan_or2_after

theorem zext_zext_eq_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (zeroExtend 32 x_1 == zeroExtend 32 x) = ofBool (x_1 == x)

theorem t1_lshr_thm (e : IntW 8) (e_1 : IntW 32) :
  lshr e_1 (sext 32 e) ⊑ lshr e_1 (zext 32 e { «nneg» := true })

theorem test5_thm.extracted_1._1 : ∀ (x : BitVec 16), truncate 16 (signExtend 32 x &&& 15#32) = x &&& 15#16

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

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 test_shl__all_are_safe_proof : test_shl__all_are_safe_before ⊑ test_shl__all_are_safe_after

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

theorem urem_i8_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬zeroExtend 32 x = 0 → ¬x = 0 → truncate 8 (zeroExtend 32 x_1 % zeroExtend 32 x) = x_1 % x

theorem ult_umin4_proof : ult_umin4_before ⊑ ult_umin4_after

lemma CNFA.autWidth_tr (hs : s < n + 2) (hs' : s' < n + 2) : s' ∈ (autWidth wp n).m.tr s 0 ↔ if s = n+1 then s = s' else s' = s + 1

theorem e_112 :
     - 11 *  ~~~(x &&&  ~~~x) + 2 *  ~~~(x ^^^ y) - 3 * y + 9 *  ~~~(x ||| y) + 11 * (x &&&  ~~~y) + 12 * (x &&& y) =  - 14 *  ~~~(x |||  ~~~y)

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

theorem lshr_or_proof : lshr_or_before ⊑ lshr_or_after

theorem t0_commutative_thm.extracted_1._9 : ∀ (x : BitVec 8) (x_1 : BitVec 1) (x_2 x_3 : BitVec 8),
  ¬ofBool (x_3 == x_2) = 1#1 → ¬ofBool (x_3 != x_2) = 1#1 → ¬0#1 = 1#1 → ¬x_1 = 1#1 → False

theorem sub_sext_mask1_trunc_lshr_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬15#64 ≥ ↑64 →
    48#64 ≥ ↑64 ∨
        63#64 ≥ ↑64 ∨
          True ∧ signExtend 64 (truncate 8 ((x <<< 48#64).sshiftRight' 63#64)) ≠ (x <<< 48#64).sshiftRight' 63#64 ∨
            True ∧ (truncate 8 ((x <<< 48#64).sshiftRight' 63#64)).saddOverflow 10#8 = true →
      False

theorem icmp_power2_and_icmp_shifted_mask_swapped_2147483648_805306368_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 805306368#32 != 805306368#32) &&& ofBool (x <ᵤ 1073741824#32) = ofBool (x <ᵤ 805306368#32)

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

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

theorem icmp_equality_test_constant_thm.extracted_1._1 : ∀ (x x_1 : BitVec 42),
  ofBool (x_1 == BitVec.ofInt 42 (-42)) = 1#1 → ofBool (x == BitVec.ofInt 42 (-42)) = ofBool (x_1 == x)

theorem t1_lshr_proof : t1_lshr_before ⊑ t1_lshr_after

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

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

theorem test4_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬x = 0 → ofBool (64#32 / x != 0#32) = ofBool (x <ᵤ 65#32)

theorem tryFactorization_xor_ashr_ashr_proof : tryFactorization_xor_ashr_ashr_before ⊑ tryFactorization_xor_ashr_ashr_after

theorem shl_trunc_bigger_ashr_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(12#32 ≥ ↑32 ∨ 3#24 ≥ ↑24) →
    9#32 ≥ ↑32 ∨ True ∧ signExtend 32 (truncate 24 (x.sshiftRight' 9#32)) ≠ x.sshiftRight' 9#32 → False

theorem and_nosignbit_select_shl_proof : and_nosignbit_select_shl_before ⊑ and_nosignbit_select_shl_after

theorem and_zext_zext_thm.extracted_1._2 : ∀ (x : BitVec 4) (x_1 : BitVec 8),
  ¬(True ∧ (x_1 &&& zeroExtend 8 x).msb = true) →
    zeroExtend 16 x_1 &&& zeroExtend 16 x = zeroExtend 16 (x_1 &&& zeroExtend 8 x)

theorem logical_or_not_thm (e e_1 : IntW 1) :
  select e_1 e (const? 1 1) ⊑ select (LLVM.xor e_1 (const? 1 1)) (const? 1 1) e

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

theorem icmp_shl_ne_2_proof : icmp_shl_ne_2_before ⊑ icmp_shl_ne_2_after

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

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

theorem test14_proof : test14_before ⊑ test14_after

theorem lshrult_03_02_proof : lshrult_03_02_before ⊑ lshrult_03_02_after

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

theorem matchVar_nil {lets : Lets d Γ_in eff Γ_out} :
    matchVar lets v (.nil : Lets d Δ .pure Δ) w ma = some ((), ma') →
    ma'.lookup ⟨_, w⟩ = some v

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

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

theorem and_xor_or8_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 64),
  ¬(x_2 = 0 ∨ x_1 = 0 ∨ x_2 = 0 ∨ x = 0) →
    ¬(x_2 = 0 ∨ x_1 = 0) → 42#64 / x_2 ||

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

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

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 sdiv_ult_smin_proof : sdiv_ult_smin_before ⊑ sdiv_ult_smin_after

theorem e_106 :
    3 *  ~~~x - 1 * y + 11 * (x ||| y) - 14 *  ~~~(x |||  ~~~y) - 11 * (x &&&  ~~~y) - 11 * (x &&& y) = 4 *  ~~~(x ||| y) - 1 *  ~~~(x &&&  ~~~y)

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

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

theorem test_shl__none_are_safe_proof : test_shl__none_are_safe_before ⊑ test_shl__none_are_safe_after

theorem no_shift_xor_multiuse_cmp_with_xor_proof : no_shift_xor_multiuse_cmp_with_xor_before ⊑ no_shift_xor_multiuse_cmp_with_xor_after

theorem lshr_pow2_ult_equal_constants_thm (e : IntW 32) :
  icmp IntPred.ult (lshr (const? 32 16) e) (const? 32 16) ⊑ icmp IntPred.ne e (const? 32 0)

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

theorem positive_samevar_shlnsw_lshrexact_proof : positive_samevar_shlnsw_lshrexact_before ⊑ positive_samevar_shlnsw_lshrexact_after

theorem max_sub_ult_c1_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x <ᵤ 1#32) = 1#1 → 0#32 = signExtend 32 (ofBool (x == 0#32))

theorem nonexact_ashr_eq_noexactdiv_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → ofBool ((BitVec.ofInt 8 (-80)).sshiftRight' x == BitVec.ofInt 8 (-31)) = 0#1

theorem e_2300 :
     - 11 * ( ~~~d &&& (e ||| f)) + 3 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 1 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 3 * (e &&&  ~~~(d &&& f)) + 1 *  ~~~(d ^^^ f) - 5 * (f ^^^  ~~~(d |||  ~~~e)) - 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 2 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 11 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 3 * ((d &&& f) ^^^ (e ||| f)) - 7 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 2 *  ~~~( ~~~d ||| (e &&& f)) - 1 * (e &&& f) - 1 * ((d |||  ~~~e) &&& (e ^^^ f)) - 2 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 1 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) + 3 *  ~~~(e &&& f) - 1 * (e ^^^ (d |||  ~~~f)) + 3 *  ~~~(d &&&  ~~~e) - 1 * ((d ^^^ e) ||| (d ^^^ f)) - 3 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 2 * ( ~~~d ||| ( ~~~e ||| f)) - 2 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 1 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 2 *  ~~~(d |||  ~~~e) + 11 * ((d ^^^ e) &&& (d ^^^ f)) + 4 * (e ^^^  ~~~(d ||| (e &&& f))) - 2 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 11 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 1 * (e ^^^  ~~~(d &&&  ~~~f)) + 7 *  ~~~(d |||  ~~~f) - 1 * (e ^^^ (d &&& (e ^^^ f))) - 2 *  ~~~(d &&&  ~~~f) + 4 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 7 * (e ^^^ (d ||| f)) + 4 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 7 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 2 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 1 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 6 *  ~~~(d ^^^ ( ~~~e &&& f)) + 7 * (e ||| (d ^^^ f)) - 2 *  ~~~(e ||| f) - 11 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 1 * (d |||  ~~~e) + 2 * (d ||| ( ~~~e &&& f)) - 2 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 1 * (f ^^^ (d ||| (e ||| f))) + 5 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 1 * (d ^^^ f) - 1 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 1 *  ~~~(d &&& (e &&& f)) - 5 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * (e &&& (d |||  ~~~f)) + 37 *  ~~~(d ||| (e ||| f)) + 29 *  ~~~(d ||| ( ~~~e ||| f)) + 12 *  ~~~( ~~~d ||| (e ||| f)) + 9 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 20 * ( ~~~d &&& ( ~~~e &&& f)) + 36 * ( ~~~d &&& (e &&& f)) + 12 * (d &&& ( ~~~e &&& f)) + 25 * (d &&& (e &&& f)) =  - 1 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 1 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f)))

theorem test14_thm (e e_1 : IntW 1) : icmp IntPred.eq e_1 e ⊑ LLVM.xor (LLVM.xor e_1 e) (const? 1 1)

theorem exact_lshr_eq_opposite_msb_thm (e : IntW 8) :
  icmp IntPred.eq (lshr (const? 8 (-128)) e { «exact» := true }) (const? 8 1) ⊑
    icmp IntPred.eq e (const? 8 7)

theorem ashr_ashr_proof : ashr_ashr_before ⊑ ashr_ashr_after

theorem test10_proof : test10_before ⊑ test10_after

theorem substitute_constant_and_eq_eq_logical_proof : substitute_constant_and_eq_eq_logical_before ⊑ substitute_constant_and_eq_eq_logical_after

theorem ule_umax1_proof : ule_umax1_before ⊑ ule_umax1_after

theorem e_803 :
    4 *  ~~~(z &&& t) + 5 *  ~~~(z ^^^ t) + 4 * z - 9 *  ~~~(z ||| t) - 8 * (z &&&  ~~~t) = 4 *  ~~~(z |||  ~~~t) + 9 * (z &&& t)

theorem ashr_ult_7_thm (e : IntW 4) :
  icmp IntPred.ult (ashr e (const? 4 1)) (const? 4 7) ⊑ icmp IntPred.sgt e (const? 4 (-1))

theorem udiv_i32_multiuse_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬zeroExtend 32 x = 0 →
    zeroExtend 32 x = 0 ∨
        True ∧ (zeroExtend 32 x_1).saddOverflow (zeroExtend 32 x) = true ∨
          True ∧ (zeroExtend 32 x_1).uaddOverflow (zeroExtend 32 x) = true ∨
            True ∧ (zeroExtend 32 x_1 / zeroExtend 32 x).smulOverflow (zeroExtend 32 x_1 + zeroExtend 32 x) = true ∨
              True ∧ (zeroExtend 32 x_1 / zeroExtend 32 x).umulOverflow (zeroExtend 32 x_1 + zeroExtend 32 x) = true →
      False

theorem e_2089 :
     - 1 * ( ~~~d &&& (e ^^^ f)) + 1 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 11 * (f ||| (d &&& e)) - 1 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 6 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 7 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 1 *  ~~~(d &&& ( ~~~e ||| f)) - 7 *  ~~~(d |||  ~~~e) + 1 * ((d &&& f) |||  ~~~(e ||| f)) + 5 *  ~~~(d ^^^ ( ~~~e ||| f)) - 7 *  ~~~(e ||| f) + 1 * (d ^^^ (e ^^^ f)) - 1 * (e ^^^ ( ~~~d ||| (e &&& f))) + 5 * (d &&&  ~~~e) - 3 * ((d ^^^ e) ||| (d ^^^ f)) - 1 * (e |||  ~~~(d ||| f)) - 1 *  ~~~( ~~~d ||| (e ^^^ f)) + 11 * (d ||| (e &&& f)) + 1 * (d ^^^ ( ~~~e ||| f)) + 2 * ((d &&& e) ^^^ (e |||  ~~~f)) - 11 * (f ^^^  ~~~(d &&& e)) - 7 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 2 * (e ^^^ (d &&& ( ~~~e ||| f))) + 7 *  ~~~(d &&& f) + 1 * (d ||| e) - 6 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) - 1 * (e ^^^ (d ||| f)) - 5 * (e ||| (d ^^^ f)) - 1 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 1 * f - 7 * (e ||| (d &&& f)) + 39 *  ~~~(d ||| (e ||| f)) + 32 *  ~~~(d ||| ( ~~~e ||| f)) + 15 *  ~~~( ~~~d ||| (e ||| f)) + 16 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 33 * ( ~~~d &&& ( ~~~e &&& f)) + 18 * ( ~~~d &&& (e &&& f)) + 11 * (d &&& ( ~~~e &&& f)) + 23 * (d &&& (e &&& f)) = 1 * (f ^^^  ~~~( ~~~d &&& (e &&& f)))

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

@[aesop 50% unsafe]
theorem Std.HashMap.mem_of_getElem? [BEq K] [LawfulBEq K] [Hashable K] [LawfulHashable K] {m : Std.HashMap K V} {k : K} :
    m[k]? = some v → k ∈ m

theorem main4e_like_proof : main4e_like_before ⊑ main4e_like_after

theorem not_or_or_and_not_and_and_commute2_or_proof : not_or_or_and_not_and_and_commute2_or_before ⊑ not_or_or_and_not_and_and_commute2_or_after

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

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 canonicalize_logic_first_or0_nswnuw_proof : canonicalize_logic_first_or0_nswnuw_before ⊑ canonicalize_logic_first_or0_nswnuw_after

theorem not_or_or_not_proof : not_or_or_not_before ⊑ not_or_or_not_after

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

theorem sub_from_constant_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 5),
  ¬(True ∧ (10#5).ssubOverflow x = true ∨ True ∧ (x_1 * x_1).saddOverflow (10#5 - x) = true) →
    x_1 * x_1 + (10#5 - x) = x_1 * x_1 - x + 10#5

theorem p0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬x_1 ≥ ↑8 → ofBool (((-1#8) <<< x_1 ^^^ -1#8) &&& x != x) = ofBool (x >>> x_1 != 0#8)

theorem negative5_proof : negative5_before ⊑ negative5_after

theorem multiuse_add_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → 1#64 + zeroExtend 64 x + 1#64 = 2#64

theorem or_disjoint_with_xor_proof : or_disjoint_with_xor_before ⊑ or_disjoint_with_xor_after

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

theorem test11_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬zeroExtend 128 x &&& 31#128 ≥ ↑128 →
    True ∧ (x &&& 31#32).msb = true ∨
        True ∧
            (zeroExtend 64 x_1 <<< zeroExtend 64 (x &&& 31#32)).sshiftRight' (zeroExtend 64 (x &&& 31#32)) ≠
              zeroExtend 64 x_1 ∨
          True ∧ zeroExtend 64 x_1 <<< zeroExtend 64 (x &&& 31#32) >>> zeroExtend 64 (x &&& 31#32) ≠ zeroExtend 64 x_1 ∨
            zeroExtend 64 (x &&& 31#32) ≥ ↑64 →
      False

theorem sext_zext_uge_known_nonneg_op0_wide_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 16),
  ¬(True ∧ (x &&& 12#8).msb = true) →
    ofBool (zeroExtend 32 (x &&& 12#8) ≤ᵤ signExtend 32 x_1) = ofBool (zeroExtend 16 (x &&& 12#8) ≤ᵤ x_1)

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

theorem or_simplify_ugt_fail_proof : or_simplify_ugt_fail_before ⊑ or_simplify_ugt_fail_after

theorem select_icmp_ne_0_and_1073741824_and_not_8_proof : select_icmp_ne_0_and_1073741824_and_not_8_before ⊑ select_icmp_ne_0_and_1073741824_and_not_8_after

theorem test47_thm.extracted_1._1 : ∀ (x : BitVec 8),
  zeroExtend 64 (signExtend 32 x ||| 42#32) = zeroExtend 64 (signExtend 32 (x ||| 42#8))

theorem select_bittest_to_sub_proof : select_bittest_to_sub_before ⊑ select_bittest_to_sub_after

theorem test_mul_nuw__all_are_safe_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 255#32 == 17#32) = 1#1 →
    ¬(True ∧ (x &&& 255#32).umulOverflow 9#32 = true) →
      True ∧ (x &&& 255#32).smulOverflow 9#32 = true ∨ True ∧ (x &&& 255#32).umulOverflow 9#32 = true → False

theorem xor_nosignbit_shl_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬8#32 ≥ ↑32 → (x ^^^ 2147418112#32) <<< 8#32 = x <<< 8#32 ^^^ BitVec.ofInt 32 (-16777216)

theorem trunc_sel_smaller_zext_thm (e : IntW 64) (e_1 : IntW 1) :
  zext 32 (select e_1 (trunc 16 e) (const? 16 42)) ⊑
    select e_1 (LLVM.and (trunc 32 e) (const? 32 65535)) (const? 32 42)

theorem lshr_shl_eq_amt_multi_use_proof : lshr_shl_eq_amt_multi_use_before ⊑ lshr_shl_eq_amt_multi_use_after

theorem test_eq2_proof : test_eq2_before ⊑ test_eq2_after

theorem lshr_pow2_ult_smin_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → ofBool (BitVec.ofInt 8 (-128) >>> x <ᵤ BitVec.ofInt 8 (-128)) = ofBool (x != 0#8)

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

theorem shl_add_nsw_proof : shl_add_nsw_before ⊑ shl_add_nsw_after

theorem select_icmp_ne_not_pow2_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬ofBool (x &&& 5#8 != 0#8) = 1#1 → ¬ofBool (x &&& 5#8 == 0#8) = 1#1 → x = x ^^^ 5#8

theorem positive_biggershl_proof : positive_biggershl_before ⊑ positive_biggershl_after

theorem not_bool_add_lshr_proof : not_bool_add_lshr_before ⊑ not_bool_add_lshr_after

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 trunc_shl_shl_infloop_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬(1#64 ≥ ↑64 ∨ 2#64 ≥ ↑64) → ¬3#32 ≥ ↑32 → truncate 32 (x <<< 1#64 <<< 2#64) = truncate 32 x <<< 3#32

theorem test11_proof : test11_before ⊑ test11_after

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

theorem zext_sext_add_icmp_sgt_minus2_proof : zext_sext_add_icmp_sgt_minus2_before ⊑ zext_sext_add_icmp_sgt_minus2_after

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

theorem c_1_1_0_proof : c_1_1_0_before ⊑ c_1_1_0_after

theorem negate_sext_thm (e : IntW 1) (e_1 : IntW 8) : sub e_1 (sext 8 e) ⊑ add e_1 (zext 8 e)

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

theorem test5_proof : test5_before ⊑ test5_after

theorem add_mask_ashr27_i32_proof : add_mask_ashr27_i32_before ⊑ add_mask_ashr27_i32_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_6_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_6_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_6_after

theorem bar_thm (e e_1 e_2 e_3 : IntW 32) :
  LLVM.or (LLVM.and e_3 (LLVM.xor (sext 32 (icmp IntPred.slt e_2 e_1)) (const? 32 (-1))))
      (LLVM.and e (sext 32 (icmp IntPred.slt e_2 e_1))) ⊑
    select (icmp IntPred.slt e_2 e_1) e e_3

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

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

theorem isMonotone_matchVar
    {lets : Lets d Γ_in eff Γ_out} {v : Var Γ_out t}
    {matchLets : Lets d Δ_in .pure Δ_out}
    {w : Var Δ_out t} :
    (matchVar lets v matchLets w).IsMonotone

theorem p15_commutativity2_thm (e : IntW 32) :
  select (icmp IntPred.ult e (const? 32 65536)) (const? 32 42) (const? 32 65535) ⊑
    select (icmp IntPred.ugt e (const? 32 65535)) (const? 32 65535) (const? 32 42)

theorem negative_not_less_than_proof : negative_not_less_than_before ⊑ negative_not_less_than_after

theorem t8_twoshifts3_proof : t8_twoshifts3_before ⊑ t8_twoshifts3_after
</all_available_lemmas>

<local_ctx>
import Mathlib.Data.Bool.Basic

import Mathlib.Data.Fin.Basic

import Mathlib.Data.Finset.Basic

import Mathlib.Data.Finset.Defs

import Mathlib.Data.Multiset.FinsetOps

import Blase.Fast.BitStream

import Blase.Fast.Defs

import Blase.Fast.FiniteStateMachine

import Blase.Fast.Decide

import Blase.SingleWidth.Syntax

import Lean.Meta.ForEachExpr

import Lean.Meta.Tactic.Simp.BuiltinSimprocs.BitVec

import Blase.Fast.ForLean

import Blase.Vars

import Blase.EnvBitstream

import Lean

open Fin.NatCast

namespace ReflectVerif

open Lean Meta Elab Tactic

namespace BvDecide

open Std Sat AIG

def mkCarryAssignCircuitNAux {arity : Type _}
  [DecidableEq arity]
  [Fintype arity]
  [Hashable arity]
  (p : FSM arity) (s : p.α) (n : Nat) : Circuit (Vars p.α arity (n + 1)) :=
    (p.nextStateCirc s).map fun v =>
      match v with
        | .inl t => Vars.stateN t n
        | .inr i => Vars.inputN i n

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 mkOutputAssignCircuitNAux {arity : Type _}
  [DecidableEq arity]
  [Fintype arity]
  [Hashable arity]
  (p : FSM arity) (n : Nat) : Circuit (Vars p.α arity (n + 1)) :=
    (p.outputCirc).map fun v =>
      match v with
        | .inl s' => Vars.stateN s' n
        | .inr i => Vars.inputN i n

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

def mkStateNeqCircuit
  {arity : Type _} {i : Nat}
  [DecidableEq arity] [Fintype arity] [Hashable arity]
  (p : FSM arity) (s t : p.α → Circuit (Vars p.α arity i)) : Circuit (Vars p.α arity i) :=
  Circuit.bigAnd <| FinEnum.toList p.α |>.map fun a => ~~~ (s a) ^^^ (t a)

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

structure KInductionCircuits {arity : Type _}
  [DecidableEq arity] [Fintype arity] [Hashable arity] (fsm : FSM arity) (n : Nat) where
  
  cInitCarryAssignCirc : Circuit (Vars fsm.α arity 0)
  
  cSuccCarryAssignCirc : Circuit (Vars fsm.α arity (n+2))
  
  cOutAssignCirc : Circuit (Vars fsm.α arity (n + 2))
  
  cStatesUniqueCirc : Circuit (Vars fsm.α arity n)

structure KInductionCircuits.IsLawful {arity : Type _}
    [DecidableEq arity] [Fintype arity] [Hashable arity] {fsm : FSM arity} {n : Nat}
  (circs : KInductionCircuits fsm n) where
  hCInitCarryAssignCirc :
    ∀ {env : Vars fsm.α arity 0 → Bool},
      (circs.cInitCarryAssignCirc.eval env = false)
      ↔ (∀ (s : fsm.α), fsm.initCarry s = env (Vars.state0 s))

  hCSuccCarryAssignCirc :
    ∀ {env : Vars fsm.α arity (n + 2) → Bool},
      (circs.cSuccCarryAssignCirc.eval env = false)
      ↔ (∀ (s : fsm.α) (i : Nat) (hi : i < n + 2),
        env (Vars.stateN s (i + 1)) =
          ((mkCarryAssignCircuitNAux fsm s i).map
            (fun v => v.castLe (by admit /- proof elided -/
            ))).eval env)
  hCOutAssignCirc :
    ∀ {env : Vars fsm.α arity (n + 2) → Bool},
      (circs.cOutAssignCirc.eval env = false)
      ↔ (∀ (i : Nat) (hi : i < n + 2),
        (fsm.outputCirc).eval
          (fun x => match x with
            | .inl s => env (Vars.stateN s i)
            | .inr j => env (Vars.inputN j i)) =
        env (Vars.outputs ⟨i, by admit /- proof elided -/
        ⟩))
  hCStatesUniqueCirc :
    ∀ {env : Vars fsm.α arity (n) → Bool},
      (circs.cStatesUniqueCirc.eval env = false)
      ↔ (∀ (i j : Nat) (hij : i < j ∧ j ≤ n),
        ∃ (s : fsm.α), env (Vars.stateN s i) ≠ env (Vars.stateN s j))

namespace KInductionCircuits

variable {arity : Type _}
  {fsm : FSM arity}

def castCircLe {n m : Nat} (c : Circuit (Vars fsm.α arity n)) (hnm : n ≤ m := by admit /- proof elided -/
) :
    Circuit (Vars fsm.α arity m) :=
  c.map (fun v => v.castLe hnm)

variable [DecidableEq arity] [Fintype arity] [Hashable arity]

def mkSucc
    (prev : KInductionCircuits fsm n) :
    KInductionCircuits fsm (n + 1) :=
  let cInitCarryAssignCirc := prev.cInitCarryAssignCirc
  { cInitCarryAssignCirc := cInitCarryAssignCirc
  , cSuccCarryAssignCirc :=
      (mkCarryAssignCircuitN fsm (n + 2)) |||
      (castCircLe prev.cSuccCarryAssignCirc)
  , cOutAssignCirc :=
      (mkOutputAssignCircuitN fsm (n + 2)) |||
      (castCircLe prev.cOutAssignCirc)
  , cStatesUniqueCirc :=
      mkStateUniqueCircuitN fsm (n + 1) |||
      (castCircLe prev.cStatesUniqueCirc)
  }
</local_ctx>

<target_theorem>
theorem IsLawful_mkSucc_of_IsLawful {arity : Type _}
    [DecidableEq arity] [Fintype arity] [Hashable arity]
    {fsm : FSM arity} {n : Nat}
    (prev : KInductionCircuits fsm n)
    (hPrev : prev.IsLawful) :
    (mkSucc prev).IsLawful :=
</target_theorem>

