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
BEq in Init.Prelude
DecidableEq in Init.Prelude
FinEnum in Mathlib.Data.FinEnum
Hashable in Init.Prelude
Repr in Init.Data.Repr
Std.HashMap in Std.Data.HashMap.Basic
Std.HashSet in Std.Data.HashSet.Basic
Array in Init.Prelude
List.map in Init.Prelude
SetRel in Mathlib.Data.Rel
Set in Mathlib.Data.Set.Defs
NFA in Mathlib.Computability.NFA
Bool in Init.Prelude
List in Init.Prelude
Finset in Mathlib.Data.Finset.Defs
Option in Init.Prelude
Prod in Init.Prelude
Prod.mk in Init.Prelude
Finset.range in Mathlib.Data.Finset.Range
Fintype in Mathlib.Data.Fintype.Defs
SetRel.inv in Mathlib.Data.Rel
LawfulBEq in Init.Core
List.next in Mathlib.Data.List.Cycle
LawfulHashable in Init.Data.LawfulHashable
Inhabited in Init.Prelude
List.insert in Init.Data.List.Basic

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

abbrev State := Nat

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

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

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

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

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

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 }

instance : Quote Int := ⟨fun n => Syntax.mkNumLit <| n.repr⟩

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

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

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

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

private def toVarFalseLit (lit : Nat) : Nat := lit * 2

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

def fold_xor_zext_icmp_after := [llvm|
{
^0(%arg91 : i64, %arg92 : i64, %arg93 : i64):
  %0 = llvm.icmp "sgt" %arg91, %arg92 : i64
  %1 = llvm.icmp "slt" %arg91, %arg93 : i64
  %2 = llvm.xor %0, %1 : i1
  %3 = llvm.zext %2 : i1 to i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

def worklist.St.addOrCreateState (st : worklist.St A S) (final? : Bool) (sa : S) : State × worklist.St A S :=
  match heq : st.map[sa]? with
  | some s => (s, st)
  | none =>
    let (s, m) := st.m.newState
    let m := if final? then m.addFinal s else m
    let map := st.map.insert sa s
    let worklist := st.worklist.push sa
    have worklist_nodup : worklist.toList.Nodup := by admit /- proof elided -/

BitVec.ofBool in Init.Data.BitVec.Basic

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

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

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

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

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

def scalar_i64_shl_ult_const_before := [llvm|
{
^0(%arg14 : i64):
  %0 = llvm.mlir.constant(25) : i64
  %1 = llvm.mlir.constant(8589934592) : i64
  %2 = llvm.shl %arg14, %0 : i64
  %3 = llvm.icmp "ult" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

def llvm_sext_lower_riscv_i16_to_32 : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 16)] :=
  {lhs:= sext_llvm_i16_to_32, rhs:= sext_riscv_i16_to_32}

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

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

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

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

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

def sshr (a : BitVec n) (s : Nat) := BitVec.sshiftRight a s

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

@[tactic bvAutomataFragmentWidthLegal]
def evalBvAutomataFragmentIllegalWidth : Tactic := fun
| `(tactic| bv_automata_fragment_width_legal) => do
  let g ← getMainGoal
  g.withContext do
    let ws ← findExprBitwidths (← g.getType)
    let ws := ws.toArray
    if h0: ws.size = 0 then throwError m!"found no bitvector in the target: {indentD (← g.getType)}"
    else if hgt: ws.size > 1 then
      let (w1, wExample1) := ws[0]
      let (w2, wExample2) := ws[1]
      let mExample := m!"{w1} → {wExample1}; {w2} → {wExample2}"
      throwError m!"found multiple bitvector widths in the target: {indentD mExample}"
    else
      return ()
| _ => throwUnsupportedSyntax

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

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

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

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

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 PostLegalizerCombiner_LLVMIR_32 : List (Σ Γ, LLVMPeepholeRewriteRefine 32  Γ) :=
  LLVMIR_identity_combines_32 ++
  LLVMIR_cast_combines_32 ++
  hoist_logic_op_with_same_opcode_hands_32 ++
  LLVMIR_identity_combines_32

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

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

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

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

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

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

def test8_before := [llvm|
{
^0(%arg1 : i128):
  %0 = llvm.mlir.constant(1 : i128) : i128
  %1 = llvm.mlir.constant(127 : i128) : i128
  %2 = llvm.mlir.constant(120 : i128) : i128
  %3 = llvm.shl %0, %1 : i128
  %4 = llvm.ashr %3, %2 : i128
  %5 = llvm.xor %arg1, %4 : i128
  %6 = llvm.add %5, %3 : i128
  "llvm.return"(%6) : (i128) -> ()
}
]

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

def slt_zero_eq_i1_after := [llvm|
{
^0(%arg9 : i32, %arg10 : i1):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.icmp "sgt" %arg9, %0 : i32
  %2 = llvm.xor %1, %arg10 : i1
  "llvm.return"(%2) : (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 shl_add_after := [llvm|
{
^0(%arg16 : i8):
  %0 = llvm.mlir.constant(30 : i8) : i8
  %1 = llvm.shl %0, %arg16 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

@[simp_denote]
def sltu_llvm_i64 := [LV| {
    ^entry (%a: i64, %b: i64):
    %0 = llvm.icmp.ult %a, %b : i64
    %1 = llvm.zext %0 : i1 to i64
    llvm.return %1 : i64
  }]

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

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

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

def test5_before := [llvm|
{
^0(%arg95 : i32, %arg96 : i8):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.zext %arg96 : i8 to i32
  %2 = llvm.shl %0, %1 : i32
  %3 = llvm.urem %arg95, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def negative_trunc_not_arg_before := [llvm|
{
^0(%arg22 : i32, %arg23 : i32):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(128 : i32) : i32
  %2 = llvm.mlir.constant(256 : i32) : i32
  %3 = llvm.trunc %arg22 : i32 to i8
  %4 = llvm.icmp "sgt" %3, %0 : i8
  %5 = llvm.add %arg23, %1 : i32
  %6 = llvm.icmp "ult" %5, %2 : i32
  %7 = llvm.and %4, %6 : i1
  "llvm.return"(%7) : (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 AttrDict.find_int {φ} (attrs : AttrDict φ)
  (name : String): Option (Int × MLIRType φ) :=
  match attrs.find name with
  | .some (AttrValue.int i ty) =>  .some (i, ty)
  | _ => .none

private def big_test := [RV64_com| {
 ^bb0(%r1 : !i64, %r2 : !i64 ):
 %1 = andi %r1, 42 : !i64
 %2 = sub %r1,  %1 : !i64
 %3 = andi %2, 10 : !i64
 %4 = div %r2, %r1 : !i64
 %5 = add %4, %1 : !i64
 %7 = li (2) : !i64
 %6 = ror %5, %7 : !i64
      ret %6 : !i64
}]

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

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

def BasicBlock.substitute (σ : Substitution) : BasicBlock Op T → BasicBlock Op T
  | ⟨label, args, program⟩ =>
      let σ' := args.foldl Substitution.removeMappingFor σ
      ⟨label, args, program.substitute σ'⟩

StateT.lift in Init.Control.State

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

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

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 and_or2_wrong_operand_before := [llvm|
{
^0(%arg172 : i1, %arg173 : i1, %arg174 : i1, %arg175 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg174, %0 : i1
  %2 = llvm.and %1, %arg173 : i1
  %3 = "llvm.select"(%2, %arg172, %arg175) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

inductive AffineExpr
  | Var: String -> AffineExpr
  deriving DecidableEq, Repr

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

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

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

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

def timeElapsedMs (x : Unit → α) : IO (α × Int) := do
    let tStart ← IO.monoMsNow
    let b := x ()
    let tEnd ← IO.monoMsNow
    return (b, tEnd - tStart)

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

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 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 test_ult_nuw_before := [llvm|
{
^0(%arg2 : i32, %arg3 : i16):
  %0 = llvm.trunc %arg2 overflow<nsw,nuw> : i32 to i8
  %1 = llvm.trunc %arg3 overflow<nsw,nuw> : i16 to i8
  %2 = llvm.icmp "ult" %0, %1 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

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

Trans in Init.Prelude

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

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

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

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

def zero_sign_bit_before := [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 : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

Lean.Meta.getIntValue? in Lean.Meta.LitValues

noncomputable def nonesUntilSome (x : Stream α) (not_stuck : x ≠ stuck α) : Nat :=
  prop.choose
where
  prop : ∃ i, (x.drop i).head.isSome ∧ ∀ j < i, x.get j = none := by admit /- proof elided -/

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

def lshr_and_after := [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.shl %2, %1 : i8
  %4 = llvm.and %arg74, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def Lets.repr (prec : Nat) : Lets d eff Γ t → Format
    | .nil => .align false ++ f!";"
    | .var body e => body.repr prec ++ (.align false ++ f!"{e.print}")

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

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

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

def 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 test42_before := [llvm|
{
^0(%arg146 : i32):
  %0 = llvm.trunc %arg146 : i32 to i8
  %1 = llvm.zext %0 : i8 to i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

def Reflect.Map.append (w : Nat) (s : BitVec w)  (m : List (BitVec w)) : List (BitVec w) := m.append [s]

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

def a_or_b_const_after := [llvm|
{
^0(%arg10 : i32, %arg11 : i32, %arg12 : i32):
  %0 = llvm.icmp "eq" %arg10, %arg12 : i32
  %1 = llvm.icmp "eq" %arg11, %arg12 : i32
  %2 = llvm.xor %0, %1 : i1
  "llvm.return"(%2) : (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 SourceEg := [DC_com| {
  ^entry():
    %src = "DC.source" () : () -> (!TokenStream)
    "return" (%src) : (!TokenStream) -> ()
  }]

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

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

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

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

def icmp_x_slt_0_and_icmp_y_sgt_neg1_i32_fail_after := [llvm|
{
^0(%arg40 : i32, %arg41 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.icmp "sgt" %arg40, %0 : i32
  %3 = llvm.icmp "slt" %arg41, %1 : i32
  %4 = llvm.and %3, %2 : i1
  %5 = llvm.zext %4 : i1 to i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

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

HSub.hSub in Init.Prelude

def and_signbit_select_ashr_after := [llvm|
{
^0(%arg14 : i32, %arg15 : i1):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(-256 : i32) : i32
  %2 = llvm.ashr %arg14, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = "llvm.select"(%arg15, %3, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

instance : Inhabited (Ctxt Ty) := ⟨Ctxt.empty⟩

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

abbrev ParsedFpLogicalExpr :=
  ParsedLogicalExpr ParsedFpExpr FpPredicate

def n11_after := [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 nneg %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 and_signbit_ashr_before := [llvm|
{
^0(%arg7 : i32):
  %0 = llvm.mlir.constant(-65536 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.and %arg7, %0 : i32
  %3 = llvm.ashr %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

def mkOutputAssignCircuitLeN {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⟩ =>
      mkOutputAssignCircuitN p i |>.map (fun v => v.castLe (by admit /- proof elided -/
      ))
    Circuit.bigOr circs

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

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

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

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

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

RV64.srli in RISCV.Instructions

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

Lean.Parser.Term.matchAlts in Lean.Parser.Term

inductive ExOp :  Type
  | add : ExOp
  | beq : ExOp
  | cst : ℕ → ExOp
  deriving DecidableEq

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

def shl_add_lshr_flag_preservation_before := [llvm|
{
^0(%arg157 : i32, %arg158 : i32, %arg159 : i32):
  %0 = llvm.shl %arg157, %arg158 overflow<nuw> : i32
  %1 = llvm.add %0, %arg159 overflow<nsw,nuw> : i32
  %2 = llvm.lshr exact %1, %arg158 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

def t0_before := [llvm|
{
^0(%arg30 : i1, %arg31 : i8, %arg32 : i8, %arg33 : i8, %arg34 : i8):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.icmp "eq" %arg31, %arg32 : i8
  %2 = llvm.xor %arg30, %0 : i1
  %3 = llvm.and %2, %1 : i1
  %4 = "llvm.select"(%3, %arg33, %arg34) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

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

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

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

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

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

unsafe def elabIntoTermElab {α : Type} (expectedType : Expr) (stx : Lean.Syntax) :
    Elab.Term.TermElabM α := do
  elabIntoTermTactic (α := α) expectedType stx  |>.runCore' { elaborator := `ParserHack} default

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

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

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

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

private def tyIndex : MLIRTy := [mlir_type| index]

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

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

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

def not_mul_of_bool_after := [llvm|
{
^0(%arg89 : i32, %arg90 : i8):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(255 : i32) : i32
  %2 = llvm.and %arg89, %0 : i32
  %3 = llvm.zext %arg90 : i8 to i32
  %4 = llvm.mul %2, %3 overflow<nsw,nuw> : i32
  %5 = llvm.icmp "ugt" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

def llvm_shl_lower_riscv_nsw_nuw_64: LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := shl_llvm_nsw_nuw_64
  rhs := shl_riscv_64

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

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

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

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

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

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

instance : Hashable (GenBVExpr w) where
  hash expr := expr.hashCode _

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

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

def and_logic_and_logic_or_3_before := [llvm|
{
^0(%arg132 : i1, %arg133 : i1, %arg134 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.and %arg133, %arg132 : i1
  %3 = "llvm.select"(%arg132, %arg134, %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 icmp_ne_zext_ne_non_boolean_before := [llvm|
{
^0(%arg33 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.icmp "ne" %arg33, %0 : i32
  %2 = llvm.zext %1 : i1 to i32
  %3 = llvm.icmp "ne" %2, %arg33 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

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

structure Item where
 name : String
 tac : Syntax

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

def t0_before := [llvm|
{
^0(%arg30 : i1, %arg31 : i8, %arg32 : i8, %arg33 : i8, %arg34 : i8):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.icmp "eq" %arg31, %arg32 : i8
  %2 = llvm.xor %arg30, %0 : i1
  %3 = llvm.and %2, %1 : i1
  %4 = "llvm.select"(%3, %arg33, %arg34) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

def src_is_mask_and_before := [llvm|
{
^0(%arg122 : i8, %arg123 : i8, %arg124 : i8):
  %0 = llvm.mlir.constant(123 : i8) : i8
  %1 = llvm.mlir.constant(7 : i8) : i8
  %2 = llvm.mlir.constant(-1 : i8) : i8
  %3 = llvm.xor %arg122, %0 : i8
  %4 = llvm.ashr %1, %arg123 : i8
  %5 = llvm.lshr %2, %arg124 : i8
  %6 = llvm.and %4, %5 : i8
  %7 = llvm.and %3, %6 : i8
  %8 = llvm.icmp "eq" %3, %7 : i8
  "llvm.return"(%8) : (i1) -> ()
}
]

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

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

@[nospecialize]
partial def decideIfZerosAuxVerified' {arity : Type _}
    [DecidableEq arity] [Fintype arity] [Hashable arity]
    (iter : Nat) (maxIter : Nat) (startVerifyAtIter : Nat := 0)
    (fsm : FSM arity)
    (circs : KInductionCircuits fsm iter)
    (stats : Array CircuitStats) :
    TermElabM (DecideIfZerosOutput × Array CircuitStats) := do
  withTraceNode `trace.Bits.Fast (fun _ => return s!"K-induction (iter={iter})") do
    if iter ≥ maxIter && maxIter != 0 then
      return (.exhaustedIterations maxIter, stats.push circs.stats)
    let tStart ← IO.monoMsNow
    let cSafety : Circuit (Vars fsm.α arity (iter+2)) := circs.mkSafetyCircuit
    let tEnd ← IO.monoMsNow
    let tElapsedMs := (tEnd - tStart)
    trace[Bits.FastVerif] m!"Built new safety circuit in '{tElapsedMs}ms'"
    trace[Bits.FastVerif] m!"safety circuit size : {cSafety.size}"
    trace[Bits.FastVerif] s!"Building induction circuit..."
    let tStart ← IO.monoMsNow
    let cIndHyp := circs.mkIndHypCycleBreaking
    let tEnd ← IO.monoMsNow
    let tElapsedMs := (tEnd - tStart)
    trace[Bits.FastVerif] m!"Built induction circuit in '{tElapsedMs}ms'"


    if iter < startVerifyAtIter then
      trace[Bits.FastVerif] s!"Skipping inductive invariant check until iteration {startVerifyAtIter}."
      decideIfZerosAuxVerified' (iter + 1) maxIter startVerifyAtIter fsm  circs.mkSucc (stats.push circs.stats)
    else
      trace[Bits.FastVerif] s!"Verifying safety property..."
      let tStart ← IO.monoMsNow
      let safetyCert? ← Circuit.checkCircuitUnsatAux cSafety
      let tEnd ← IO.monoMsNow
      let tElapsedMs := (tEnd - tStart)
      trace[Bits.FastVerif] m!"Established safety property in {tElapsedMs}ms (iter={iter})."
      match safetyCert? with
      | .none =>
        trace[Bits.FastVerif] s!"Safety property failed on initial state."
        return (.safetyFailure iter, stats.push circs.stats)
      | .some safetyCert =>
        trace[Bits.FastVerif] s!"Safety property established (iter={iter})."
        trace[Bits.FastVerif] s!"Establishing Inductive Invariant..."
        let tStart ← IO.monoMsNow
        let indCert? ← Circuit.checkCircuitUnsatAux cIndHyp
        let tEnd ← IO.monoMsNow
        let tElapsedMs := (tEnd - tStart)
        trace[Bits.FastVerif] s!"Checked inductive invariant in '{tElapsedMs}ms'."
        match indCert? with
        | .some indCert =>
          trace[Bits.FastVerif] s!"Inductive invariant established (iter={iter})."
          return (.provenByKIndCycleBreaking iter safetyCert indCert, stats.push circs.stats)
        | .none =>
          trace[Bits.FastVerif] s!"Unable to establish inductive invariant. Trying next iteration ({iter+1})..."
        decideIfZerosAuxVerified' (iter + 1) maxIter startVerifyAtIter fsm  circs.mkSucc (stats.push circs.stats)

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

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

def addhshlhsdivhnegative0_after := [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 overflow<nsw> : i8
  %4 = llvm.add %3, %arg8 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

def main7b_before := [llvm|
{
^0(%arg78 : i32, %arg79 : i32, %arg80 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.mul %arg80, %0 : i32
  %4 = llvm.and %arg78, %arg79 : i32
  %5 = llvm.icmp "eq" %arg79, %4 : i32
  %6 = llvm.and %arg78, %3 : i32
  %7 = llvm.icmp "eq" %3, %6 : i32
  %8 = llvm.and %5, %7 : i1
  %9 = "llvm.select"(%8, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%9) : (i32) -> ()
}
]

List.isEmpty in Init.Data.List.Basic

def elabOp (env : Lean.Environment) (stx : Lean.Syntax) : EIO ParseError (MLIR.AST.Op 0) :=
  unsafe elabIntoEIO (α := MLIR.AST.Op 0) env op0Expr stx

def test10_after := [llvm|
{
^0(%arg41 : i19):
  %0 = llvm.mlir.constant(-262144 : i19) : i19
  %1 = llvm.and %arg41, %0 : i19
  "llvm.return"(%1) : (i19) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

def getGenLogicalExprSize [H : HydrableGetGenPredSize genPred] (logicalExpr : BoolExpr genPred) : Nat :=
  match logicalExpr with
  | .literal _ => 1
  | .const _ => 1
  | .not x => 1 + getGenLogicalExprSize x
  | .gate _ x y => 1 + getGenLogicalExprSize x + getGenLogicalExprSize y
  | .ite d l r => 1 + getGenLogicalExprSize d + getGenLogicalExprSize l + getGenLogicalExprSize r

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

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

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

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

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

def and_or3_commuted_before := [llvm|
{
^0(%arg164 : i1, %arg165 : i1, %arg166 : i32, %arg167 : i32):
  %0 = llvm.icmp "eq" %arg166, %arg167 : i32
  %1 = llvm.and %0, %arg165 : i1
  %2 = "llvm.select"(%1, %arg164, %arg165) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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 anyext_trunc_fold_zext_32 : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := [LV| {
    ^entry (%x: i32):
      %0 = llvm.zext %x: i32 to i64
      %1 = llvm.trunc %0: i64 to i32
      llvm.return %1 : i32
  }]
  rhs := [LV| {
    ^entry (%x: i32):
      llvm.return %x : i32
  }]

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

def select_xor_icmp_bad_3_before := [llvm|
{
^0(%arg179 : i32, %arg180 : i32, %arg181 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.icmp "eq" %arg179, %0 : i32
  %2 = llvm.xor %arg179, %arg181 : i32
  %3 = "llvm.select"(%1, %2, %arg180) <{"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 n2_after := [llvm|
{
^0(%arg19 : i1, %arg20 : i8, %arg21 : i8, %arg22 : i8, %arg23 : i8):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.icmp "eq" %arg20, %arg21 : i8
  %2 = llvm.xor %arg19, %0 : i1
  %3 = llvm.or %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

instance : HydrableReduceWidth ParsedBVExpr GenBVPred GenBVExpr where
  shrink := shrink

def xor_lshr_after := [llvm|
{
^0(%arg624 : i8, %arg625 : i8, %arg626 : i8, %arg627 : i8):
  %0 = llvm.xor %arg624, %arg625 : i8
  %1 = llvm.lshr %0, %arg627 : i8
  %2 = llvm.xor %1, %arg626 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

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

def sdiv_pow2_4 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (4) : 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 (62) : i64
      %c2 = llvm.mlir.constant (2) : 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 shl_and_xor_after := [llvm|
{
^0(%arg158 : i8, %arg159 : i8):
  %0 = llvm.mlir.constant(10 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.and %arg158, %0 : i8
  %3 = llvm.xor %arg159, %2 : i8
  %4 = llvm.shl %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def Signature.map (f : Ty → Ty') : Signature Ty → Signature Ty' :=
  fun sig => {
    sig         := sig.sig.map f
    regSig      := sig.regSig.map f
    returnTypes := sig.returnTypes.map f
  }

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

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

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

def fold_add_udiv_urem_to_mul_before := [llvm|
{
^0(%arg8 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(21 : i32) : i32
  %2 = llvm.mlir.constant(3 : i32) : i32
  %3 = llvm.udiv %arg8, %0 : i32
  %4 = llvm.mul %3, %1 : i32
  %5 = llvm.urem %arg8, %0 : i32
  %6 = llvm.mul %5, %2 : i32
  %7 = llvm.add %4, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

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

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

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

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

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

@[reducible, simp]
def Op.sig : Op → List Ty
  | .add => [.int, .int]
  | .sub => [.int, .int]
  | .constIx _  => []
  | .constTensor _  => []
  | .constInt _  => []
  | .map2d => [.tensor2d]
  | .fill2d => [.int, .tensor2d]
  | .extract2d => [.ix, .ix, .ix, .ix, .tensor2d]

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 shl_add_log_may_cause_poison_pr62175_with_nsw_before := [llvm|
{
^0(%arg0 : i8, %arg1 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.shl %0, %arg0 overflow<nsw> : i8
  %2 = llvm.mul %arg1, %1 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

def test1_before := [llvm|
{
^0(%arg3 : i57, %arg4 : i57, %arg5 : i57):
  %0 = llvm.and %arg5, %arg3 : i57
  %1 = llvm.and %arg5, %arg4 : i57
  %2 = llvm.xor %0, %1 : i57
  "llvm.return"(%2) : (i57) -> ()
}
]

instance : Coe Bool (BitVec 1) := ⟨BitVec.ofBool⟩

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

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

def or_xor_common_op_commute0_after := [llvm|
{
^0(%arg135 : i8, %arg136 : i8, %arg137 : i8):
  %0 = llvm.or %arg135, %arg136 : i8
  %1 = llvm.or %0, %arg137 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

def div_bit_set_before := [llvm|
{
^0(%arg61 : i32, %arg62 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %0, %arg62 : i32
  %3 = llvm.sdiv %2, %arg61 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  %5 = llvm.zext %4 : i1 to i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def bools2_logical_commute0_and1_and2_before := [llvm|
{
^0(%arg55 : i1, %arg56 : i1, %arg57 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg57, %0 : i1
  %2 = llvm.and %arg57, %arg55 : i1
  %3 = llvm.and %1, %arg56 : i1
  %4 = "llvm.select"(%2, %0, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def narrow_sext_or_after := [llvm|
{
^0(%arg52 : i16, %arg53 : i32):
  %0 = llvm.trunc %arg53 : i32 to i16
  %1 = llvm.or %arg52, %0 : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

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

inductive Ty
| int : Ty
| ix : Ty
| tensor2d : Ty
deriving DecidableEq, Inhabited

instance [Std.Refl (· ⊑ · : α → α → _)] : Std.Refl (· ⊑ · : PoisonOr α → PoisonOr α → _) where
  refl a? := by admit /- proof elided -/

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

def Term.bcard (t : Term) : Nat :=
  match t with
  | .ofNat _w _n => 0
  | .var _v _w => 0
  | .add _w a b => max (Term.bcard a) (Term.bcard b)
  | .zext a _wnew => (Term.bcard a)
  | .sext a _wnew => (Term.bcard a)
  | .setWidth a _wnew => (Term.bcard a)
  | .bor _w a b => (max (Term.bcard a) (Term.bcard b))
  | .band _w a b => (max (Term.bcard a) (Term.bcard b))
  | .bxor _w a b => (max (Term.bcard a) (Term.bcard b))
  | .bnot _w a => (Term.bcard a)
  | .boolVar v => v + 1
  | .boolConst _b => 0
  | .shiftl _w a _k => (Term.bcard a)
  | bvOfBool b => b.bcard
  | binWidthRel _k _wa _wb => 0
  | binRel _k _w a b => max (Term.bcard a) (Term.bcard b)
  | or p1 p2 => max (Term.bcard p1) (Term.bcard p2)
  | and p1 p2 => max (Term.bcard p1) (Term.bcard p2)
  | pvar _v => 0
  | boolBinRel _k a b => max (a.bcard) (b.bcard)

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

abbrev ofTerm (t : Term) : FSM (Fin t.arity) := termEvalEqFSM t |>.toFSM

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

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

def udiv_shl_mul_nuw_exact_before := [llvm|
{
^0(%arg142 : i5, %arg143 : i5, %arg144 : i5):
  %0 = llvm.shl %arg142, %arg144 overflow<nuw> : i5
  %1 = llvm.mul %arg142, %arg143 overflow<nuw> : i5
  %2 = llvm.udiv exact %0, %1 : i5
  "llvm.return"(%2) : (i5) -> ()
}
]

instance {d : Dialect} [DialectSignature d] {t} {Γ : Ctxt d.Ty} {Γ' : DerivedCtxt Γ} :
    Coe (Expr d Γ eff t) (Expr d Γ'.ctxt eff t) where
  coe e := e.changeVars Γ'.diff.toHom

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

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

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

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

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

abbrev zero   : BitStream := fun _ => false

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 sextbool_add_commute_after := [llvm|
{
^0(%arg10 : i1, %arg11 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.urem %arg11, %0 : i32
  %2 = llvm.sext %arg10 : i1 to i32
  %3 = llvm.add %1, %2 overflow<nsw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

Std.Format.align in Init.Data.Format.Basic

Lean.mkApp2 in Lean.Expr

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

def select_match : List (Σ Γ, Σ ty, PeepholeRewrite LLVMPlusRiscV Γ ty) :=
  [⟨[Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64),Ty.llvm (.bitvec 1)],
   [Ty.llvm (.bitvec 64)],(LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND select_riscv_select_llvm_64)⟩,
  ⟨[Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32),Ty.llvm (.bitvec 1)],
   [Ty.llvm (.bitvec 32)],(LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND select_riscv_select_llvm_32)⟩,
   ⟨[Ty.llvm (.bitvec 8), Ty.llvm (.bitvec 8),Ty.llvm (.bitvec 1)],
   [Ty.llvm (.bitvec 8)],(LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND select_riscv_select_llvm_8)⟩]

def mul_splat_fold_no_nuw_before := [llvm|
{
^0(%arg79 : i32):
  %0 = llvm.mlir.constant(65537 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.mul %arg79, %0 overflow<nsw> : i32
  %3 = llvm.lshr %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def multiuse_shl_shl_after := [llvm|
{
^0(%arg36 : i42):
  %0 = llvm.mlir.constant(8 : i42) : i42
  %1 = llvm.mlir.constant(17 : i42) : i42
  %2 = llvm.shl %arg36, %0 : i42
  %3 = llvm.shl %arg36, %1 : i42
  %4 = llvm.mul %2, %3 : i42
  "llvm.return"(%4) : (i42) -> ()
}
]

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

def zext_match : List (Σ Γ, Σ ty, PeepholeRewrite LLVMPlusRiscV Γ ty) := [
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_zext_lower_riscv_1_to_8),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_zext_lower_riscv_1_to_16),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_zext_lower_riscv_1_to_32),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_zext_lower_riscv_1_to_64),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_zext_lower_riscv_8_to_64),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_zext_lower_riscv_8_to_16),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_zext_lower_riscv_8_to_32),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_zext_lower_riscv_16_to_32),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_zext_lower_riscv_16_to_64),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_zext_lower_riscv_32_to_64)
]

def src_is_mask_const_sge_after := [llvm|
{
^0(%arg45 : i8):
  %0 = llvm.mlir.constant(123 : i8) : i8
  %1 = llvm.mlir.constant(32 : i8) : i8
  %2 = llvm.xor %arg45, %0 : i8
  %3 = llvm.icmp "slt" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def trimTensor (tensor : List Int) : List Int
  := tensor.reverse.dropWhile (· = 0) |>.reverse

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

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

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

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

inductive AttrEntry where
  | mk: (key: String)
      -> (value: AttrValue)
      -> AttrEntry

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

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

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 urem_i32_before := [llvm|
{
^0(%arg21 : i8, %arg22 : i8):
  %0 = llvm.zext %arg21 : i8 to i32
  %1 = llvm.zext %arg22 : i8 to i32
  %2 = llvm.urem %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

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

Nat.add in Init.Prelude

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

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

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

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

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

def RawCNFA.transSet (m : RawCNFA A) (ss : Std.HashSet State) (a : A) : Std.HashSet State :=
  ss.fold (init := ∅) fun ss' s =>
    ss'.insertMany $ m.trans.getD (s, a) ∅

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

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

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

def or_and_or_pat8_after := [llvm|
{
^0(%arg10 : i8, %arg11 : i8, %arg12 : i8, %arg13 : i8):
  %0 = llvm.or %arg13, %arg10 : i8
  %1 = llvm.and %0, %arg11 : i8
  %2 = llvm.or %1, %arg12 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

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

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

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

def test5_before := [llvm|
{
^0(%arg2 : i700):
  %0 = llvm.mlir.constant(288230376151711743 : i700) : i700
  %1 = llvm.or %arg2, %0 : i700
  %2 = llvm.xor %1, %0 : i700
  "llvm.return"(%2) : (i700) -> ()
}
]

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

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

def test_sub_nuw_nsw__nuw_is_safe_after := [llvm|
{
^0(%arg27 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.mlir.constant(-2147483648 : i32) : i32
  %2 = llvm.and %arg27, %0 : i32
  %3 = llvm.sub %1, %2 overflow<nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

instance : ToString (MetaLLVM φ).Ty := ⟨MetaLLVM.printType⟩

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

def eval_sext_multi_use_in_one_inst_before := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(14 : i16) : i16
  %1 = llvm.mlir.constant(-32768 : i16) : i16
  %2 = llvm.trunc %arg6 : i32 to i16
  %3 = llvm.and %2, %0 : i16
  %4 = llvm.mul %3, %3 overflow<nsw,nuw> : i16
  %5 = llvm.or %4, %1 : i16
  %6 = llvm.sext %5 : i16 to i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

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

def Expr.KInductionCircuits.mkN (fsm : Expr) (n : Expr) : SolverM Expr := do
  let out ← mkAppM ``ReflectVerif.BvDecide.KInductionCircuits.mkN #[fsm, n]
  debugCheck out
  return out

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

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

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

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

def ValueStream := Stream

Lean.PrettyPrinter.Parenthesizer in Lean.PrettyPrinter.Parenthesizer

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

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

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

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

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

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

instance : HydrableGetIdentityAndAbsorptionConstraints GenBVPred where
  getIdentityAndAbsorptionConstraints := getIdentityAndAbsorptionConstraints

def test25_after := [llvm|
{
^0(%arg2 : i37, %arg3 : i37):
  %0 = llvm.mlir.constant(-131072 : i37) : i37
  %1 = llvm.and %arg2, %0 : i37
  %2 = llvm.add %arg3, %1 : i37
  %3 = llvm.and %2, %0 : i37
  "llvm.return"(%3) : (i37) -> ()
}
]

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

RV64.srlw in RISCV.Instructions

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

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

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

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

def pack (x : Stream α) (y : Stream Unit) : Stream α :=
  syncMap₂ (xs := x) (ys := y) (f := wrapReadyValue)

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

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

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

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

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

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

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

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

Std.Tactic.BVDecide.Reflect.verifyCert in Std.Tactic.BVDecide.Reflect

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

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

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

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

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

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

def shl_or_with_or_disjoint_instead_of_add_before := [llvm|
{
^0(%arg1 : i8):
  %0 = llvm.mlir.constant(16 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.mlir.constant(3 : i8) : i8
  %3 = llvm.shl %0, %arg1 : i8
  %4 = llvm.or disjoint %arg1, %1 : i8
  %5 = llvm.shl %2, %4 : i8
  %6 = llvm.or %3, %5 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

def annihilate_xor_common_op_commute2_before := [llvm|
{
^0(%arg3 : i4, %arg4 : i4, %arg5 : i4, %arg6 : i4):
  %0 = llvm.mul %arg5, %arg5 : i4
  %1 = llvm.xor %arg3, %arg4 : i4
  %2 = llvm.xor %0, %1 : i4
  %3 = llvm.xor %2, %arg6 : i4
  %4 = llvm.xor %3, %arg3 : i4
  "llvm.return"(%4) : (i4) -> ()
}
]

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

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

abbrev HasNat (d : Dialect) [TyDenote d.Ty] [DialectSignature d] : Type := HasTy d Nat

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

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

@[simp_denote]
def add_negative_low_bound_reject_riscv := [LV| {
  ^entry (%arg: i32):
  %0 = li (843949575) : !i64 
  %1 = "lui" (%0) {imm = 1048575 : !i64} : (!i64) -> (!i64)
  %2 = "builtin.unrealized_conversion_cast" (%arg) : (i32) -> (!i64)
  %3 = "addi" (%1) {imm = -1 : !i64} : (!i64) -> (!i64)
  %4 = addw %2, %3 : !i64
  %5 =  "builtin.unrealized_conversion_cast" (%4) : (!i64) -> (i32)
  llvm.return %5 : i32
}]

def register_wrapper
    (inputs : Stream' (Vector α m))
    
    (init_regs : Vector α nfeed)
    
    (update_fun : (Vector α m × Vector α nfeed) → (Vector α r × Vector α nfeed))
      : Stream' (Vector α r) :=
   
  let β := Stream' (Vector α m) × (Vector α nfeed) × Option (Vector α nfeed)
   
  let f : β → Vector α r :=
    fun (input_stream, current_regs_opt, init_regs) =>
       
      match init_regs with
      | some iv =>
                   
                  let (output, _) := update_fun (input_stream.head, iv)
                  output
      | _ =>   
              let (output, _) := update_fun (input_stream.head, current_regs_opt)
              output
   
  let g : β → β :=
    fun (input_stream, current_regs_opt, init_regs) =>
 
    match init_regs with
    | some iv =>
                 
                let (_, output_feedback) := update_fun (input_stream.head, iv)
                (input_stream.tail, output_feedback, none)
    | _ =>   
            let (_, output_feedback) := update_fun (input_stream.head, current_regs_opt)
            (input_stream.tail, output_feedback, none)
  Stream'.corec f g (inputs, init_regs, none)

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

@[simp]
instance Valuation.instAppendHVector (Γ : Ctxt Ty) (ts : List Ty) :
    HAppend (HVector toType ts) (Valuation Γ) (Valuation <| ⟨ts⟩ ++ Γ) where
  hAppend vals V :=
    (Valuation.ofHVector vals) ++ V

def test4_after := [llvm|
{
^0(%arg0 : i1023):
  %0 = llvm.mlir.constant(1022 : i1023) : i1023
  %1 = llvm.ashr %arg0, %0 : i1023
  "llvm.return"(%1) : (i1023) -> ()
}
]

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

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

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

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

def and_logic_and_logic_or_3_before := [llvm|
{
^0(%arg132 : i1, %arg133 : i1, %arg134 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.and %arg133, %arg132 : i1
  %3 = "llvm.select"(%arg132, %arg134, %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 or_and_or_pat2_before := [llvm|
{
^0(%arg34 : i8, %arg35 : i8, %arg36 : i8, %arg37 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.udiv %0, %arg36 : i8
  %2 = llvm.and %arg34, %arg35 : i8
  %3 = llvm.and %arg37, %arg34 : i8
  %4 = llvm.or %1, %3 : i8
  %5 = llvm.or %2, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def and_sequence_20_lhs (w : Nat)   :=
[llvm( w )| {
^bb0(%C1 : _, %Z : _):
  %v1 = llvm.and %Z, %C1
  %v2 = llvm.and %v1, %C1
  %v3 = llvm.and %v2, %C1
  %v4 = llvm.and %v3, %C1
  %v5 = llvm.and %v4, %C1
  %v6 = llvm.and %v5, %C1
  %v7 = llvm.and %v6, %C1
  %v8 = llvm.and %v7, %C1
  %v9 = llvm.and %v8, %C1
  %v10 = llvm.and %v9, %C1
  %v11 = llvm.and %v10, %C1
  %v12 = llvm.and %v11, %C1
  %v13 = llvm.and %v12, %C1
  %v14 = llvm.and %v13, %C1
  %v15 = llvm.and %v14, %C1
  %v16 = llvm.and %v15, %C1
  %v17 = llvm.and %v16, %C1
  %v18 = llvm.and %v17, %C1
  %v19 = llvm.and %v18, %C1
  %v20 = llvm.and %v19, %C1
  llvm.return %v20
}]

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 trunc_shl_lshr_var_after := [llvm|
{
^0(%arg33 : i64, %arg34 : i64):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.lshr %arg33, %arg34 : i64
  %2 = llvm.trunc %1 : i64 to i32
  %3 = llvm.shl %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def shl_sub_lshr_after := [llvm|
{
^0(%arg139 : i32, %arg140 : i32, %arg141 : i32):
  %0 = llvm.lshr exact %arg141, %arg140 : i32
  %1 = llvm.sub %arg139, %0 overflow<nsw,nuw> : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

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

def Lets.denoteIntoSubtype (lets : Lets d Γ_in eff Γ_out) (Γv : Valuation Γ_in) :
    eff.toMonad d.m lets.ValidDenotation :=
  match lets with
    | .nil => return ⟨Γv, by admit /- proof elided -/
    ⟩
    | @Lets.var _ _ _ _ Γ_out eTy body e => do
        let ⟨Vout, h⟩ ← body.denoteIntoSubtype Γv
        let Ve ← e.denoteOpIntoSubtype Vout
        return ⟨Ve.val ++ Vout, by admit /- proof elided -/
        ⟩

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

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

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

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

def 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 zext_shl_after := [llvm|
{
^0(%arg10 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.shl %arg10, %0 : i8
  %2 = llvm.and %1, %arg10 : i8
  %3 = llvm.zext %2 : i8 to i16
  "llvm.return"(%3) : (i16) -> ()
}
]

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

def shift_no_xor_multiuse_cmp_after := [llvm|
{
^0(%arg120 : i32, %arg121 : i32, %arg122 : i32, %arg123 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg120, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  %4 = llvm.shl %2, %0 overflow<nsw,nuw> : i32
  %5 = llvm.or %arg121, %4 : i32
  %6 = "llvm.select"(%3, %arg122, %arg123) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = llvm.mul %5, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

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

def not_ashr_not_before := [llvm|
{
^0(%arg139 : i32, %arg140 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg139, %0 : i32
  %2 = llvm.ashr %1, %arg140 : i32
  %3 = llvm.xor %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def commute_int_constant_to_rhs_or : RISCVPeepholeRewrite [Ty.riscv (.bv)] where
  lhs := [LV| {
    ^entry (%x: !riscv.reg):
      %c = li (1) : !riscv.reg
      %0 = or %c, %x : !riscv.reg
      ret %0 : !riscv.reg
  }]
  rhs := [LV| {
    ^entry (%x: !riscv.reg):
      %c = li (1) : !riscv.reg
      %0 = or %x, %c : !riscv.reg
      ret %0 : !riscv.reg
  }]

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

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

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

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

def ashrslt_01_00_exact_before := [llvm|
{
^0(%arg53 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(0 : i4) : i4
  %2 = llvm.ashr exact %arg53, %0 : i4
  %3 = llvm.icmp "slt" %2, %1 : i4
  "llvm.return"(%3) : (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 main6_before := [llvm|
{
^0(%arg94 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(3 : i32) : i32
  %2 = llvm.mlir.constant(48 : i32) : i32
  %3 = llvm.mlir.constant(16 : i32) : i32
  %4 = llvm.mlir.constant(0 : i32) : i32
  %5 = llvm.mlir.constant(1 : i32) : i32
  %6 = llvm.and %arg94, %0 : i32
  %7 = llvm.icmp "eq" %6, %1 : i32
  %8 = llvm.and %arg94, %2 : i32
  %9 = llvm.icmp "eq" %8, %3 : i32
  %10 = llvm.and %7, %9 : i1
  %11 = "llvm.select"(%10, %4, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%11) : (i32) -> ()
}
]

Nat.strongRecOn in Init.WF

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

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

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

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

def zext_eq_sext_before := [llvm|
{
^0(%arg4 : i1, %arg5 : i1):
  %0 = llvm.zext %arg4 : i1 to i32
  %1 = llvm.sext %arg5 : i1 to i32
  %2 = llvm.icmp "eq" %0, %1 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

def example01 := [RV64_com| {
^bb0(%0 : !i64, %1 : !i64):
  
  
 
    %5 = "add"(%0, %0) : (!i64, !i64) -> (!i64)
  
  "ret" (%0) : (!i64) -> ()
 }]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

def src_fv_eq_after := [llvm|
{
^0(%arg32 : i1, %arg33 : i8, %arg34 : i8):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.xor %arg32, %0 : i1
  %3 = llvm.icmp "eq" %arg33, %1 : i8
  %4 = llvm.and %3, %2 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def SimplePathOfPath.hEvalWith (this : SimplePathOfPath fsm s0 (K + 1) env) :
    fsm.evalWith s0 env (K + 1) =
    fsm.evalWith s0
      (envBitstream_set this.simplePath (this.k) (fun a => env a (K + 1))) this.k :=

OptionT.run in Init.Control.Option

def WidthPredicate.final? (wp : WidthPredicate) (n : Nat) (s : State) : Bool :=
  decide (wp.sat s n)

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

Lean.Elab.Command.CommandElabM in Lean.Elab.Command

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

def sdiv? {w : Nat} (x y : BitVec w) : IntW w :=
  if y == 0 || (w != 1 && x == (BitVec.intMin w) && y == -1) then
    .poison
  else
    .value (x.sdiv y)

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

def shl_mask_wrong_shl_const_after := [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 overflow<nsw,nuw> : i32
  %4 = llvm.or %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def add (op1 : FpExpr w) (op2 : FpExpr w) : FpExpr w :=
  FpExpr.bin op1 FpBinOp.add op2

def instantiateOne (a : α) : ConcreteOrMVar α (φ+1) → ConcreteOrMVar α φ
  | .concrete w => .concrete w
  | .mvar i => i.lastCases
      (.concrete a)       
      (fun j => .mvar j)  

def test_eq_before := [llvm|
{
^0(%arg11 : 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 %arg11, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.shl %arg11, %2 : i32
  %6 = "llvm.select"(%4, %1, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

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

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

def llvm_shl_lower_riscv_nuw_32: LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := shl_llvm_nuw_32
  rhs := shl_riscv_32

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

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

def test10_before := [llvm|
{
^0(%arg90 : i8):
  %0 = llvm.mlir.constant(4 : i32) : i32
  %1 = llvm.mlir.constant(4) : i64
  %2 = llvm.zext %arg90 : i8 to i32
  %3 = llvm.mul %2, %0 : i32
  %4 = llvm.sext %3 : i32 to i64
  %5 = llvm.urem %4, %1 : i64
  %6 = llvm.trunc %5 : i64 to i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

def mul8_low_before := [llvm|
{
^0(%arg26 : i8, %arg27 : i8):
  %0 = llvm.mlir.constant(15 : i8) : i8
  %1 = llvm.mlir.constant(4 : i8) : i8
  %2 = llvm.and %arg26, %0 : i8
  %3 = llvm.lshr %arg26, %1 : i8
  %4 = llvm.and %arg27, %0 : i8
  %5 = llvm.lshr %arg27, %1 : i8
  %6 = llvm.mul %5, %2 : i8
  %7 = llvm.mul %4, %3 : i8
  %8 = llvm.mul %4, %2 : i8
  %9 = llvm.add %6, %7 : i8
  %10 = llvm.shl %9, %1 : i8
  %11 = llvm.add %10, %8 : i8
  "llvm.return"(%11) : (i8) -> ()
}
]

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

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

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

def slli_i32_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := slli_llvm_i32
  rhs := slli_riscv_i32

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

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

def 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 or_logic_or_logic_and_2_before := [llvm|
{
^0(%arg45 : i1, %arg46 : i1, %arg47 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.or %arg45, %arg46 : i1
  %3 = "llvm.select"(%arg47, %0, %arg45) <{"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 test25_after := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

instance instAppend : Append (Ctxt Ty) where
  append Γ Δ := ⟨Γ.toList ++ Δ.toList⟩

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

Lean.Parser.mkAntiquot in Lean.Parser.Basic

partial def visit (t : Expr) : GenM Expr := do
  let t ← instantiateMVars t
  match t with
  | .app _ _ =>
    let f := t.getAppFn
    let args := t.getAppArgs
    let table ←
      if let some (f, _) := f.const? then do
        let out ← genTable.getGenTable f args
        pure out
      else
        pure none
    let bv? (n : Nat) :=
      match table with
      | .some xs => xs.getD n false
      | .none => false
    args.zipIdx.foldlM (init := f) fun res (arg, i) => do
      let arg ← if bv? i then State.add? arg else visit arg
      pure <| .app res arg
  | .forallE n e₁ e₂ info =>
    pure <| .forallE n (← visit e₁) (← visit e₂) info
  | e =>
    pure e

def icmp_shl_uge_2_before := [llvm|
{
^0(%arg12 : i5):
  %0 = llvm.mlir.constant(10 : i5) : i5
  %1 = llvm.mlir.constant(1 : i5) : i5
  %2 = llvm.add %0, %arg12 : i5
  %3 = llvm.shl %2, %1 : i5
  %4 = llvm.icmp "uge" %2, %3 : i5
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

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

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

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

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

LawfulBEq in Init.Core

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

def test23_before := [llvm|
{
^0(%arg143 : i8):
  %0 = llvm.mlir.constant(-2 : i8) : i8
  %1 = llvm.mlir.constant(13 : i8) : i8
  %2 = llvm.mlir.constant(1 : i8) : i8
  %3 = llvm.mlir.constant(12 : i8) : i8
  %4 = llvm.or %arg143, %0 : i8
  %5 = llvm.xor %4, %1 : i8
  %6 = llvm.or %5, %2 : i8
  %7 = llvm.xor %6, %3 : i8
  "llvm.return"(%7) : (i8) -> ()
}
]

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

def different_size_zext_zext_eq_after := [llvm|
{
^0(%arg22 : i4, %arg23 : i7):
  %0 = llvm.zext %arg22 : i4 to i7
  %1 = llvm.icmp "eq" %arg23, %0 : i7
  "llvm.return"(%1) : (i1) -> ()
}
]

inductive ExOp :  Type
  | add : ExOp
  | runK : ℕ → ExOp
  deriving DecidableEq, Repr

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

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

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

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

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

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

def udiv_shl_mul_nuw_before := [llvm|
{
^0(%arg148 : i5, %arg149 : i5, %arg150 : i5):
  %0 = llvm.shl %arg148, %arg150 overflow<nuw> : i5
  %1 = llvm.mul %arg148, %arg149 overflow<nuw> : i5
  %2 = llvm.udiv %0, %1 : i5
  "llvm.return"(%2) : (i5) -> ()
}
]

BitVec.ule in Init.Data.BitVec.Basic

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

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

def sub_ashr_and_i16_before := [llvm|
{
^0(%arg29 : i16, %arg30 : i16):
  %0 = llvm.mlir.constant(15 : i16) : i16
  %1 = llvm.sub %arg30, %arg29 overflow<nsw> : i16
  %2 = llvm.ashr %1, %0 : i16
  %3 = llvm.and %2, %arg29 : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

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

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

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 test11_before := [llvm|
{
^0(%arg84 : i32, %arg85 : i32):
  %0 = llvm.mlir.constant(31 : i128) : i128
  %1 = llvm.zext %arg84 : i32 to i128
  %2 = llvm.zext %arg85 : 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 t9_after := [llvm|
{
^0(%arg176 : i8, %arg177 : i8):
  %0 = llvm.sub %arg176, %arg177 : i8
  "llvm.return"(%0) : (i8) -> ()
}
]

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

def llvm_const_lower_riscv_li32 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM32, rhs:= liRiscv32,
   correct := by admit /- proof elided -/

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

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

def test37_after := [llvm|
{
^0(%arg241 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(240 : i32) : i32
  %2 = llvm.mul %arg241, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.zext nneg %3 : i32 to i64
  "llvm.return"(%4) : (i64) -> ()
}
]

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

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

def ptradd (p : SLLVM.Ptr) (x : LLVM.IntW 64) : SLLVM.Ptr := do
  let p ← p
  let x ← x
  return { p with offset := p.offset + x}

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 mul128_low_after := [llvm|
{
^0(%arg18 : i128, %arg19 : i128):
  %0 = llvm.mul %arg18, %arg19 : i128
  "llvm.return"(%0) : (i128) -> ()
}
]

@[simp_denote]
def xor_riscv_32: Com  LLVMPlusRiscV ⟨[.llvm (.bitvec 32), .llvm (.bitvec 32)]⟩
  .pure (.llvm (.bitvec 32)) := [LV| {
  ^entry (%x: i32, %y: i32):
    %x1 = "builtin.unrealized_conversion_cast"(%x) : (i32) -> (!i64)
    %x2 = "builtin.unrealized_conversion_cast"(%y) : (i32) -> (!i64)
    %1 = xor %x1, %x2 : !i64
    %2 = "builtin.unrealized_conversion_cast"(%1) : (!i64) -> (i32)
    llvm.return %2 : i32
  }]

abbrev Width.mvar : Fin φ → Width φ := ConcreteOrMVar.mvar

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

def and_or1_wrong_operand_before := [llvm|
{
^0(%arg176 : i1, %arg177 : i1, %arg178 : i1, %arg179 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg176, %0 : i1
  %2 = llvm.or %1, %arg178 : i1
  %3 = "llvm.select"(%2, %arg179, %arg177) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def add_of_mul_before := [llvm|
{
^0(%arg4 : i8, %arg5 : i8, %arg6 : i8):
  %0 = llvm.mul %arg4, %arg5 overflow<nsw> : i8
  %1 = llvm.mul %arg4, %arg6 overflow<nsw> : i8
  %2 = llvm.add %0, %1 overflow<nsw> : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

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

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

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

@[simp]
def Formula.sat' {w : Nat} (φ : Formula) (ρ : Nat → BitVec w) : Prop :=
  match φ with
  | .width wp n => wp.sat w n
  | .atom rel t1 t2 =>
    let bv1 := t1.evalNat ρ
    let bv2 := t2.evalNat ρ
    evalRelation rel bv1 bv2
  | .unop .neg φ => ¬ φ.sat' ρ
  | .binop op φ1 φ2 =>
    let b1 := φ1.sat' ρ
    let b2 := φ2.sat' ρ
    evalBinop' op b1 b2
  | .msbSet t => (t.evalNat ρ).msb

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

def sub_ashr_and_i64_before := [llvm|
{
^0(%arg25 : i64, %arg26 : i64):
  %0 = llvm.mlir.constant(63) : i64
  %1 = llvm.sub %arg26, %arg25 overflow<nsw> : i64
  %2 = llvm.ashr %1, %0 : i64
  %3 = llvm.and %2, %arg25 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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

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

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

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

def 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 State.get? (e : Expr) : GenM (Option Expr) := do
  let s ← get
  match ← s.mapping.getMatch e with
  | #[x] => return x
  | #[] => return none
  | _ => unreachable!

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

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

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

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

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

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

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

List.map in Init.Prelude

Lean.Meta.mkLambdaFVars in Lean.Meta.Basic
</all_available_defs>

<all_available_lemmas>
Std.HashMap.getElem?_insert in Std.Data.HashMap.Lemmas
getElem?_eq_none_iff in Init.GetElem
Set.mem_setOf_eq in Mathlib.Data.Set.Operations
true_and in Init.SimpLemmas
Array.mem_of_getElem? in Init.Data.Array.Lemmas
Prod.mk.eta in Mathlib.Data.Prod.Basic
Std.HashSet.mem_insert in Std.Data.HashSet.Lemmas
beq_iff_eq in Init.Core
ge_iff_le in Init.Core
not_and in Init.SimpLemmas
not_exists in Init.PropLemmas
or_true in Init.SimpLemmas
true_or in Init.SimpLemmas

@[aesop 50% unsafe]
theorem Std.HashMap.get?_none_not_mem [BEq K] [LawfulBEq K] [Hashable K] [LawfulHashable K] {m : Std.HashMap K V} {k : K} : m.get? k = none → k ∉ m

@[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 Std.HashMap.mem_iff_getElem? [BEq K] [LawfulBEq K] [Hashable K] [LawfulHashable K] [Inhabited V] {m : Std.HashMap K V} {k : K} :
     k ∈ m ↔ ∃ v, m[k]? = some v

@[grind =, simp]
lemma addTrans_tr_eq (m : RawCNFA A) [LawfulBEq A] (a : A) (s₁ s₂ : State) :
    (m.addTrans a s₁ s₂).tr s₁ a = (m.tr s₁ a).insert s₂

@[grind =] -- TODO: should I?
lemma addTrans_tr (m : RawCNFA A) [LawfulBEq A] {a b : A} {s₁ s₁' s₂ : State} :
    (m.addTrans a s₁ s₂).tr s₁' b = if s₁ = s₁' ∧ a = b then (m.tr s₁ a).insert s₂ else m.tr s₁' b

@[grind ., simp, aesop 50% unsafe]
lemma RawCNFA.WF.trans_src_lt'' [LawfulBEq A] {m : RawCNFA A} (hwf : m.WF) :
    ∀ {s a s'}, s' ∈ m.tr s a → s ∈ m.states

@[grind ., simp, aesop 50% unsafe]
lemma RawCNFA.WF.trans_src_lt' {m : RawCNFA A} (hwf : m.WF) :
    ∀ {s a}, (s, a) ∈ m.trans → s ∈ m.states

@[aesop 50% unsafe]
theorem Std.HashMap.getElem?_none_not_mem [BEq K] [LawfulBEq K] [Hashable K] [LawfulHashable K] {m : Std.HashMap K V} {k : K} :
    m[k]? = none → k ∉ m

theorem add_const_const_sub_thm (e : IntW 32) : sub (const? 32 2) (add e (const? 32 8)) ⊑ sub (const? 32 (-6)) e

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

theorem scalar_i32_lshr_and_negC_slt_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬x ≥ ↑32 → ofBool (x_1 >>> x &&& BitVec.ofInt 32 (-8) <ₛ 0#32) = ofBool (x_1 >>> x <ₛ 0#32)

theorem test_lshr_exact__exact_is_safe_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 lshrult_01_11_proof : lshrult_01_11_before ⊑ lshrult_01_11_after

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

theorem both_proof : both_before ⊑ both_after

@[simp] theorem Lets.denote_nil {Γ : Ctxt d.Ty} :
    (Lets.nil : Lets d Γ eff Γ).denote = (return ·)

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

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

theorem alive_AndOrXor_2118___A__B__A___A__B : alive_AndOrXor_2118___A__B__A___A__B_src ⊑ alive_AndOrXor_2118___A__B__A___A__B_tgt

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

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

theorem ule_umax1_thm (e e_1 : IntW 32) :
  icmp IntPred.ule (select (icmp IntPred.ugt e_1 e) e_1 e) e_1 ⊑ icmp IntPred.ule e e_1

theorem bswap_and_mask_1_thm (e : IntW 64) :
  LLVM.or (LLVM.and (lshr e (const? 64 40)) (const? 64 65280)) (lshr e (const? 64 56)) ⊑
    LLVM.or (LLVM.and (lshr e (const? 64 40)) (const? 64 65280)) (lshr e (const? 64 56)) { «disjoint» := true }

theorem src_x_and_nmask_eq_proof : src_x_and_nmask_eq_before ⊑ src_x_and_nmask_eq_after

theorem bools2_logical_commute1_and1_proof : bools2_logical_commute1_and1_before ⊑ bools2_logical_commute1_and1_after

theorem p0_thm (e e_1 : IntW 8) :
  icmp IntPred.ugt (shl (const? 8 1) e_1) e ⊑ icmp IntPred.eq (lshr e e_1) (const? 8 0)

theorem prove_exact_with_high_mask_proof : prove_exact_with_high_mask_before ⊑ prove_exact_with_high_mask_after

theorem main4b_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 == 7#32) &&& ofBool (x &&& 16#32 != 0#32) = 1#1 →
    1#32 = zeroExtend 32 (ofBool (x &&& 23#32 != 23#32))

theorem test_with_3_proof : test_with_3_before ⊑ test_with_3_after

theorem ashrsgt_03_00_thm (e : IntW 4) : icmp IntPred.sgt (ashr e (const? 4 3)) (const? 4 0) ⊑ const? 1 0

theorem sub_ashr_or_i32_nuw_nsw_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.ssubOverflow x = true ∨ True ∧ x_1.usubOverflow x = true ∨ 31#32 ≥ ↑32) →
    ¬ofBool (x_1 <ₛ x) = 1#1 → (x_1 - x).sshiftRight' 31#32 ||

theorem src_is_mask_xor_proof : src_is_mask_xor_before ⊑ src_is_mask_xor_after

theorem t0_thm.extracted_1._10 : ∀ (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 prove_exact_with_high_mask_thm (e : IntW 8) :
  LLVM.sdiv (LLVM.and e (const? 8 (-8))) (const? 8 4) ⊑ LLVM.and (ashr e (const? 8 2)) (const? 8 (-2))

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

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

theorem lshrult_02_12_proof : lshrult_02_12_before ⊑ lshrult_02_12_after

theorem sub_ule_sext_thm (e : IntW 1) (e_1 e_2 : IntW 8) :
  icmp IntPred.ule (sub e_2 e_1) (sext 8 e) ⊑ LLVM.or (icmp IntPred.eq e_2 e_1) e

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

theorem shl_add_proof : shl_add_before ⊑ shl_add_after

theorem ashrslt_03_03_exact_proof : ashrslt_03_03_exact_before ⊑ ashrslt_03_03_exact_after

theorem sextinreg_alt_thm.extracted_1._1 : ∀ (x : BitVec 32),
  16#32 ≥ ↑32 ∨ True ∧ x <<< 16#32 >>> 16#32 <<< 16#32 ≠ x <<< 16#32 ∨ 16#32 ≥ ↑32 → False

theorem exact_lshr_ne_opposite_msb_proof : exact_lshr_ne_opposite_msb_before ⊑ exact_lshr_ne_opposite_msb_after

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

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

theorem e_796 :
    1 * (z ^^^ t) + 1 *  ~~~(z ^^^ t) - 1 *  ~~~(z ||| t) - 1 * (z &&&  ~~~t) + 10 * (z &&& t) =  - 10 *  ~~~(z |||  ~~~t) + 11 * t

theorem sgt_minus1_proof : sgt_minus1_before ⊑ sgt_minus1_after

theorem sgt_negative_multip_rem_zero_proof : sgt_negative_multip_rem_zero_before ⊑ sgt_negative_multip_rem_zero_after

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

theorem test_and2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (-1#32 <ₛ x_1) &&& ofBool (x_1 ≤ₛ x &&& 2147483647#32) = ofBool (x_1 ≤ᵤ x &&& 2147483647#32)

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

theorem shl_mul_mask_proof : shl_mul_mask_before ⊑ shl_mul_mask_after

theorem t3_exact_proof : t3_exact_before ⊑ t3_exact_after

theorem test92_thm (e : IntW 64) : trunc 64 (lshr (sext 96 e) (const? 96 32)) ⊑ ashr e (const? 64 32)

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

theorem test5_proof : test5_before ⊑ test5_after

theorem test11_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 2#32 != 0#32) ||

theorem multiuse1_proof : multiuse1_before ⊑ multiuse1_after

theorem shift_xor_multiuse_cmp_and_thm.extracted_1._3 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ofBool (0#32 != x_3 &&& 4096#32) = 1#1 →
    ofBool (x_3 &&& 4096#32 == 0#32) = 1#1 →
      x_2 * x_1 * (x_2 &&& 2048#32) = (x_2 &&& 2048#32) * x * (x_2 &&& 2048#32)

theorem positive_with_extra_and_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  ofBool (x_1 + 128#32 <ᵤ 256#32) &&& (ofBool (-1#32 <ₛ x_1) &&& x) = ofBool (x_1 <ᵤ 128#32) &&& x

theorem shl_nsw_nuw_ult_Csle0_thm (e e_1 : IntW 8) :
  icmp IntPred.ult (shl e_1 e { «nsw» := true, «nuw» := true }) (const? 8 (-19)) ⊑
    icmp IntPred.ult e_1 (const? 8 (-19))

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

theorem t0_proof : t0_before ⊑ t0_after

theorem icmp_ne_sext_ne_otherwise_i128_thm.extracted_1._1 : ∀ (x : BitVec 128),
  ofBool (signExtend 128 (ofBool (x != 2#128)) != x) = ofBool (x != -1#128)

theorem bor_land_right1_proof : bor_land_right1_before ⊑ bor_land_right1_after

theorem t2_ashr_proof : t2_ashr_before ⊑ t2_ashr_after

theorem positive_biggershl_shlnuwnsw_thm (e : IntW 8) :
  shl (lshr e (const? 8 3)) (const? 8 6) { «nsw» := true, «nuw» := true } ⊑
    LLVM.and (shl e (const? 8 3) { «nsw» := true, «nuw» := true }) (const? 8 64)

theorem narrow_zext_ashr_keep_trunc_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ (signExtend 32 x_1).saddOverflow (signExtend 32 x) = true ∨ 1#32 ≥ ↑32) →
    True ∧ (signExtend 16 x_1).saddOverflow (signExtend 16 x) = true ∨ 1#16 ≥ ↑16 → False

theorem test27_thm (e e_1 e_2 : IntW 32) :
  zext 32 (icmp IntPred.eq (LLVM.xor e_2 e_1) (LLVM.xor e_2 e)) ⊑ zext 32 (icmp IntPred.eq e_1 e)

theorem e_539 :
     - 7 * (x ^^^ y) - 3 * (x ||| y) + 3 *  ~~~x - 3 *  ~~~y - 11 *  ~~~(x &&&  ~~~x) - 2 * x + 11 *  ~~~(x ||| y) + 26 * (x &&&  ~~~y) + 16 * (x &&& y) =  - 18 *  ~~~(x |||  ~~~y)

theorem no_masks_with_logical_or2_proof : no_masks_with_logical_or2_before ⊑ no_masks_with_logical_or2_after

theorem mul_select_sext_thm (e : IntW 1) :
  mul (select e (const? 64 64) (const? 64 1)) (sext 64 e) ⊑ select e (const? 64 (-64)) (const? 64 0)

theorem test11_proof : test11_before ⊑ test11_after

@[simp] theorem Valuation.append_appendInr {v : Var Δ t} :
    (V ++ W) v.appendInr = W v

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

theorem testi128i128_thm.extracted_1._2 : ∀ (x : BitVec 128),
  ¬127#128 ≥ ↑128 → ¬ofBool (-1#128 <ₛ x) = 1#1 → x.sshiftRight' 127#128 ^^^ 27#128 = BitVec.ofInt 128 (-28)

theorem e_1558 :
     - 6 *  ~~~(a ^^^ ( ~~~b ||| c)) + 1 * ( ~~~b |||  ~~~(a ^^^ c)) - 11 * ((a &&& b) |||  ~~~(b ^^^ c)) - 1 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 6 *  ~~~(a ^^^ (b &&& c)) - 11 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 1 *  ~~~(a |||  ~~~c) + 7 * (a &&& b) + 24 *  ~~~(a ||| (b ||| c)) + 23 *  ~~~(a ||| ( ~~~b ||| c)) + 23 *  ~~~( ~~~a ||| (b ||| c)) + 8 * ( ~~~a &&& (b &&& c)) + 5 * (a &&& ( ~~~b &&& c)) + 27 * (a &&& (b &&& c)) =  - 4 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) - 13 * ( ~~~a &&& ( ~~~b &&& c))

theorem test14_commuted_proof : test14_commuted_before ⊑ test14_commuted_after

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

@[simp] theorem Com.rec'_rets (v : HVector Γ.Var t) :
    (Com.rets (d:=d) (eff := eff) v).rec' (motive:=motive) rets var = rets v

theorem ashrsgt_03_03_exact_proof : ashrsgt_03_03_exact_before ⊑ ashrsgt_03_03_exact_after

theorem icmp_sle9_proof : icmp_sle9_before ⊑ icmp_sle9_after

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

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

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

@[simp] theorem getElem?_map (Γ : Ctxt Ty) (f : Ty → Ty') (i : Nat) :
    (Γ.map f)[i]? = Γ[i]?.map f

theorem and_or1_wrong_operand_thm.extracted_1._3 : ∀ (x x_1 x_2 x_3 : BitVec 1),
  x_3 ^^^ 1#1 ||

theorem mul_setnzV_unkV_nuw_eq_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (mul (LLVM.or e_1 (const? 8 2)) e { «nsw» := false, «nuw» := true }) (const? 8 0) ⊑
    icmp IntPred.eq e (const? 8 0)

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

lemma CNFA.autSignedCmp_spec {cmp} : (CNFA.autSignedCmp cmp).Sim (NFA'.autSignedCmp cmp)

theorem main12_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (truncate 16 x <ₛ 0#16) = 1#1 → ofBool (x &&& 32896#32 == 0#32) = 1#1 → True → 2#32 = 1#32

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

theorem and_sgt_to_mask_thm (e : IntW 8) :
  LLVM.and (icmp IntPred.sgt e (const? 8 123)) (icmp IntPred.eq (LLVM.and e (const? 8 2)) (const? 8 0)) ⊑
    icmp IntPred.eq (LLVM.and e (const? 8 (-2))) (const? 8 124)

theorem substitute_constant_and_eq_ugt_swap_logical_proof : substitute_constant_and_eq_ugt_swap_logical_before ⊑ substitute_constant_and_eq_ugt_swap_logical_after

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

theorem add_signbit_select_shl_proof : add_signbit_select_shl_before ⊑ add_signbit_select_shl_after

@[simp]
theorem Term.toBV_var {wenv : WidthExpr.Env wcard}
    {tctx : Term.Ctx wcard tcard}
    (benv : Term.BoolEnv bcard)
    (tenv : tctx.Env wenv) :
  Term.toBV benv nenv ienv penv tenv (.var v) = tenv v

theorem exact_lshr_eq_exactdiv_proof : exact_lshr_eq_exactdiv_before ⊑ exact_lshr_eq_exactdiv_after

theorem test27_thm (e : IntW 8) :
  add (LLVM.and (sub (LLVM.and e (const? 8 4)) (const? 8 16)) (const? 8 (-16))) (const? 8 16) ⊑ const? 8 0

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

theorem or_umin_thm (e : IntW 32) :
  LLVM.or (select (icmp IntPred.ult (const? 32 15) e) (const? 32 15) e) (const? 32 31) ⊑ const? 32 31

theorem 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 test10_proof : test10_before ⊑ test10_after

@[simp]
theorem EnvFin.getLsbD_getLsb {w : Nat} (env : EnvFin (w + 1) n) (bit : Nat) : (env.getLsb i).getLsbD bit =
    if bit = 0 then (env i)[0] else false

theorem c0_proof : c0_before ⊑ c0_after

theorem test4_proof : test4_before ⊑ test4_after

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

theorem test_sext3_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1), x_1 = 1#1 → x_1 ^^^ 1#1 = 1#1 → 0#32 = signExtend 32 x

theorem icmp_eq_zext_eq_non_boolean_proof : icmp_eq_zext_eq_non_boolean_before ⊑ icmp_eq_zext_eq_non_boolean_after

theorem shl_lshr_pow2_const_negative_overflow2_proof : shl_lshr_pow2_const_negative_overflow2_before ⊑ shl_lshr_pow2_const_negative_overflow2_after

theorem positive_with_aggressive_icmp_proof : positive_with_aggressive_icmp_before ⊑ positive_with_aggressive_icmp_after

theorem ult_rem_zero_proof : ult_rem_zero_before ⊑ ult_rem_zero_after

theorem sle_smax4_proof : sle_smax4_before ⊑ sle_smax4_after

theorem squared_nsw_eq0_thm (e : IntW 5) :
  icmp IntPred.eq (mul e e { «nsw» := true, «nuw» := false }) (const? 5 0) ⊑
    icmp IntPred.eq e (const? 5 0)

theorem icmp_equality_test_constant_proof : icmp_equality_test_constant_before ⊑ icmp_equality_test_constant_after

theorem and_min_7_8_thm (e : IntW 8) :
  LLVM.and (select (icmp IntPred.ult e (const? 8 (-8))) e (const? 8 (-8))) (const? 8 (-8)) ⊑
    LLVM.and e (const? 8 (-8))

theorem test_mul_nuw_nsw__nuw_is_safe_proof : test_mul_nuw_nsw__nuw_is_safe_before ⊑ test_mul_nuw_nsw__nuw_is_safe_after

theorem test4_proof : test4_before ⊑ test4_after

omit [LawfulBEq A] [Fintype S] [DecidableEq S] in
lemma processOneElem_finals (st : worklist.St A S) (final : S → Bool) (a : A) (sa : S) (s : State) :
    (processOneElem A S final s st (a, sa)).m.finals =
      if sa ∉ st.map ∧ final sa then st.m.finals.insert st.m.stateMax else st.m.finals

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

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

theorem masked_and_notA_slightly_optimized_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (8#32 ≤ᵤ x) = 1#1 → 0#1 = ofBool (x &&& BitVec.ofInt 32 (-40) != 0#32)

theorem invert_both_cmp_operands_sub_proof : invert_both_cmp_operands_sub_before ⊑ invert_both_cmp_operands_sub_after

theorem neg_or_lshr_i32_commute_proof : neg_or_lshr_i32_commute_before ⊑ neg_or_lshr_i32_commute_after

theorem e_2278 :
     - 7 *  ~~~(e &&& f) + 1 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 11 * (d ^^^ (e ||| f)) + 4 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 3 * ((d ^^^ e) &&& (d ^^^ f)) - 6 * (e ^^^ (d ||| (e &&& f))) + 1 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 11 *  ~~~f + 7 *  ~~~(d ^^^ ( ~~~e &&& f)) - 11 *  ~~~(d &&&  ~~~d) - 1 * (d ||| ( ~~~e ||| f)) - 3 * e + 2 * (d ||| f) + 5 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 1 * (f &&& (d |||  ~~~e)) - 3 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 2 * (e ^^^ (d ||| ( ~~~e &&& f))) + 1 *  ~~~(d &&& ( ~~~e &&& f)) - 7 * (d ||| (e ^^^ f)) + 3 * ((d &&& e) |||  ~~~(e ^^^ f)) + 7 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 1 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 6 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 2 * ( ~~~d ||| ( ~~~e &&& f)) + 3 * (f ^^^ ( ~~~d ||| (e ||| f))) + 4 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 2 *  ~~~( ~~~d ||| (e &&& f)) + 2 *  ~~~( ~~~d ||| (e ^^^ f)) - 7 * (e ^^^  ~~~(d ||| (e &&& f))) - 11 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 5 * (e ^^^  ~~~(d &&& (e ||| f))) + 5 * (f |||  ~~~(d ||| e)) - 1 * (f ^^^ (d |||  ~~~e)) + 1 * ((d &&& e) ||| (e ^^^ f)) - 11 * ( ~~~f ||| (d ^^^ e)) - 1 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 4 * ( ~~~d ||| ( ~~~e ||| f)) + 3 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 5 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 11 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 3 *  ~~~(d ^^^ f) + 4 * ( ~~~d &&& (e ^^^ f)) - 6 * ((d &&& f) ^^^ (e ||| f)) - 1 * (f &&&  ~~~(d ^^^ e)) + 7 * d + 1 * (d &&& f) + 11 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 3 *  ~~~(d ^^^ (e &&& f)) - 3 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 5 * ( ~~~d &&& ( ~~~e ||| f)) + 3 *  ~~~(d ||| (e ||| f)) + 18 *  ~~~(d ||| ( ~~~e ||| f)) + 20 *  ~~~( ~~~d ||| (e ||| f)) - 4 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 41 * ( ~~~d &&& ( ~~~e &&& f)) + 20 * ( ~~~d &&& (e &&& f)) + 2 * (d &&& ( ~~~e &&& f)) - 8 * (d &&& (e &&& f)) = 1 * (e ^^^  ~~~(d &&& (e &&& f)))

theorem test32_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬2#32 ≥ ↑32 → (x &&& 16#32) >>> 2#32 &&& 1#32 = 0#32

@[simp] theorem sup_impure_eq : max e impure  = impure

theorem not_sub_thm (e : IntW 32) :
  LLVM.xor (sub (const? 32 123) e) (const? 32 (-1)) ⊑ add e (const? 32 (-124))

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

theorem or_xor_and_commuted1_thm (e e_1 : IntW 32) :
  LLVM.or (mul e_1 e_1) (LLVM.xor (LLVM.xor (mul e_1 e_1) (const? 32 (-1))) e) ⊑
    LLVM.or (mul e_1 e_1) (LLVM.xor e (const? 32 (-1)))

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

theorem e_1826 :
    5 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) + 4 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) - 6 *  ~~~(a &&& (b ||| c)) + 5 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) + 1 * (b ^^^ ( ~~~a &&& (b ^^^ c))) - 1 * (a ||| c) + 2 * ((a ^^^ b) &&& (a ^^^ c)) - 2 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) - 5 * c + 2 * (b ^^^ (a ||| (b &&& c))) + 1 *  ~~~( ~~~a ||| (b ^^^ c)) + 11 *  ~~~(b |||  ~~~c) - 7 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) + 3 * (c ^^^  ~~~(a |||  ~~~b)) + 11 * ( ~~~b |||  ~~~(a ^^^ c)) + 1 * (b ^^^ (a ||| (b ||| c))) + 11 * (a &&& (b ||| c)) - 7 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 3 *  ~~~b + 1 * (a ||| (b ||| c)) + 1 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) - 2 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 1 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) - 1 * (c ^^^ (a &&& b)) - 2 *  ~~~( ~~~a &&& (b &&& c)) + 1 * (c |||  ~~~(a ^^^ b)) + 1 *  ~~~(a ^^^ (b ||| c)) + 11 *  ~~~(a ||| c) + 3 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 11 * (b ^^^ (a ||| c)) + 1 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) + 1 *  ~~~(b &&&  ~~~c) - 2 * (b &&&  ~~~(a &&&  ~~~c)) + 4 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) - 12 *  ~~~(a ||| (b ||| c)) - 17 *  ~~~(a ||| ( ~~~b ||| c)) - 15 *  ~~~( ~~~a ||| (b ||| c)) - 8 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 8 * ( ~~~a &&& ( ~~~b &&& c)) + 4 * ( ~~~a &&& (b &&& c)) - 32 * (a &&& ( ~~~b &&& c)) - 22 * (a &&& (b &&& c)) =  - 4 * (c ||| (a &&&  ~~~b))

theorem lsb_mask_sign_zext_thm (e : IntW 32) :
  lshr (LLVM.and (add e (const? 32 (-1))) (LLVM.xor e (const? 32 (-1)))) (const? 32 31) ⊑
    zext 32 (icmp IntPred.eq e (const? 32 0))

theorem sextbool_add_thm (e : IntW 32) (e_1 : IntW 1) : add (sext 32 e_1) e ⊑ add e (sext 32 e_1)

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

theorem PR75692_1_thm (e : IntW 32) :
  LLVM.or (LLVM.xor e (const? 32 4)) (LLVM.xor e (const? 32 (-5))) ⊑ const? 32 (-1)

theorem alive_AddSub_1614 : alive_AddSub_1614_src ⊑ alive_AddSub_1614_tgt

theorem ashrsgt_02_07_exact_proof : ashrsgt_02_07_exact_before ⊑ ashrsgt_02_07_exact_after

theorem test_add_nuw_nsw__nsw_is_safe_proof : test_add_nuw_nsw__nsw_is_safe_before ⊑ test_add_nuw_nsw__nsw_is_safe_after

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

theorem ashrsgt_03_08_thm (e : IntW 4) : icmp IntPred.sgt (ashr e (const? 4 3)) (const? 4 (-8)) ⊑ const? 1 1

theorem lshr_32_add_not_known_32_leading_zeroes_proof : lshr_32_add_not_known_32_leading_zeroes_before ⊑ lshr_32_add_not_known_32_leading_zeroes_after

theorem ugt_swap_and_not_min_logical_proof : ugt_swap_and_not_min_logical_before ⊑ ugt_swap_and_not_min_logical_after

theorem allSignBits_thm.extracted_1._2 : ∀ (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 shl_add_log_may_cause_poison_pr62175_with_nuw_proof : shl_add_log_may_cause_poison_pr62175_with_nuw_before ⊑ shl_add_log_may_cause_poison_pr62175_with_nuw_after

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

theorem sge_swap_or_not_max_logical_proof : sge_swap_or_not_max_logical_before ⊑ sge_swap_or_not_max_logical_after

theorem or_simplify_ugt_proof : or_simplify_ugt_before ⊑ or_simplify_ugt_after

theorem e_2016 :
     - 1 * ((e &&& f) ||| (d &&& (e ||| f))) + 7 * (f ||| (d ^^^ e)) + 1 * ((d &&& e) ||| (e ^^^ f)) + 1 * (e ^^^  ~~~(d |||  ~~~f)) + 2 * ( ~~~e &&&  ~~~(d ^^^ f)) - 1 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 2 * (d ^^^ ( ~~~e &&& f)) - 1 * (d ||| (e &&& f)) - 2 * (e ^^^ (d &&& f)) + 2 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 3 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 5 * (e |||  ~~~f) + 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 3 * (e ^^^ ( ~~~d ||| (e &&& f))) - 2 * (e ^^^  ~~~(d &&& (e &&& f))) - 7 * (d ||| f) + 2 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 1 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 1 * ( ~~~f &&&  ~~~(d ^^^ e)) + 1 * (d &&&  ~~~f) - 1 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 1 * (f &&&  ~~~(d &&& e)) - 6 * (e ^^^  ~~~(d &&& f)) - 6 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 2 * d + 24 *  ~~~(d ||| (e ||| f)) + 3 *  ~~~(d ||| ( ~~~e ||| f)) + 22 *  ~~~( ~~~d ||| (e ||| f)) + 18 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 14 * ( ~~~d &&& ( ~~~e &&& f)) + 9 * (d &&& ( ~~~e &&& f)) + 15 * (d &&& (e &&& f)) = 2 * (f ^^^  ~~~(d ||| (e &&& f))) - 14 * ( ~~~d &&& (e &&& f))

theorem icmp_slt_0_or_icmp_sgt_0_i32_thm.extracted_1._1 : ∀ (x : BitVec 32),
  zeroExtend 32 (ofBool (x <ₛ 0#32)) ||

theorem select1_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 32) (x_3 : BitVec 1),
  x_3 = 1#1 → zeroExtend 32 (truncate 8 x_2) = x_2 &&& 255#32

theorem test8_thm (e : IntW 27) : sub (mul (const? 27 9) e) e ⊑ shl e (const? 27 3)

theorem ashr_lshr_exact_lshr_only_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sgt e_1 (const? 32 (-1))) (lshr e_1 e { «exact» := true }) (ashr e_1 e) ⊑
    ashr e_1 e

theorem src_is_mask_zext_fail_not_mask_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 16),
  ¬x ≥ ↑8 →
    ofBool ((x_1 ^^^ 123#16) &&& zeroExtend 16 (BitVec.ofInt 8 (-2) >>> x) == x_1 ^^^ 123#16) =
      ofBool (x_1 ^^^ BitVec.ofInt 16 (-124) ||| zeroExtend 16 (BitVec.ofInt 8 (-2) >>> x) == -1#16)

theorem alive_AddSub_1556   : alive_AddSub_1556_src ⊑ alive_AddSub_1556_tgt

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

theorem test_invert_demorgan_or2_proof : test_invert_demorgan_or2_before ⊑ test_invert_demorgan_or2_after

theorem nonexact_lshr_ne_exactdiv_thm (e : IntW 8) :
  icmp IntPred.ne (lshr (const? 8 80) e) (const? 8 5) ⊑ icmp IntPred.ne e (const? 8 4)

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

theorem e_2421 :
    4 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 1 * (f ^^^ (d &&& ( ~~~e ||| f))) + 1 * ((d ||| e) &&& (e ^^^ f)) + 1 * (d &&& (e ^^^ f)) - 1 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 7 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 * (d &&&  ~~~e) + 2 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 6 *  ~~~(d &&& ( ~~~e ||| f)) - 1 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 2 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 2 * d - 6 * (f &&& (d ^^^ e)) + 4 * ((d &&& e) ^^^ (e |||  ~~~f)) - 1 * (d &&& e) + 3 * (e ^^^ (d |||  ~~~f)) - 7 *  ~~~(e ^^^ f) - 11 * (e &&&  ~~~(d ^^^ f)) + 1 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) - 2 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) + 5 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 4 * (d ||| (e ^^^ f)) - 7 * (e &&&  ~~~(d &&& f)) + 7 * (f |||  ~~~(d ||| e)) + 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 7 * (d ^^^ ( ~~~e ||| f)) - 1 *  ~~~(d ^^^ ( ~~~e &&& f)) + 2 * ( ~~~d ||| ( ~~~e ||| f)) - 2 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 1 * (d ^^^ f) - 11 * ((d ^^^ e) ||| (d ^^^ f)) + 2 *  ~~~(d ^^^ ( ~~~e ||| f)) + 1 *  ~~~(d |||  ~~~f) + 1 * (e ^^^  ~~~(d &&&  ~~~f)) - 3 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 4 * (d ^^^ e) - 7 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 7 * (f &&& (d ||| e)) - 3 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 11 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 5 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 2 * ( ~~~d &&& (e ^^^ f)) - 2 * (f ^^^  ~~~(d &&& (e &&& f))) + 2 * (d ||| (e ||| f)) + 3 *  ~~~(e &&&  ~~~f) - 1 * (f ^^^ (d ||| ( ~~~e &&& f))) - 2 *  ~~~(d ^^^ (e ^^^ f)) - 11 * (e ^^^ (d &&& (e ||| f))) - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 5 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) + 1 * (e ||| (d ^^^ f)) - 1 * (f ^^^ (d |||  ~~~e)) - 1 * (e &&& (d ||| f)) - 5 * (e |||  ~~~(d ^^^ f)) - 2 * (e ^^^ (d ||| (e ^^^ f))) - 2 * (f ^^^ ( ~~~d &&& (e ||| f))) - 11 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 2 * (f ||| (d &&& e)) - 3 * ((d &&& e) |||  ~~~(e ||| f)) + 4 * ( ~~~f ||| (d ^^^ e)) + 3 * (e &&&  ~~~f) + 3 * (f ^^^  ~~~(d |||  ~~~e)) - 7 * (e &&& f) - 2 * (e ^^^  ~~~(d &&& (e ||| f))) + 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 5 * f + 16 *  ~~~(d ||| (e ||| f)) + 7 *  ~~~(d ||| ( ~~~e ||| f)) + 9 *  ~~~( ~~~d ||| (e ||| f)) + 27 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 7 * ( ~~~d &&& ( ~~~e &&& f)) + 64 * ( ~~~d &&& (e &&& f)) - 19 * (d &&& ( ~~~e &&& f)) + 25 * (d &&& (e &&& f)) = 5 * (d ^^^ (e &&& f))

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

theorem test11_proof : test11_before ⊑ test11_after

theorem trunc_shl_nsw_nuw_31_i32_i64_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬(True ∧ (x <<< 31#64).sshiftRight' 31#64 ≠ x ∨ True ∧ x <<< 31#64 >>> 31#64 ≠ x ∨ 31#64 ≥ ↑64) →
    ¬31#32 ≥ ↑32 → truncate 32 (x <<< 31#64) = truncate 32 x <<< 31#32

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 e_1284 :
    1 *  ~~~t - 5 * (z ||| t) - 2 * z - 1 * t - 2 * (z |||  ~~~t) + 6 *  ~~~(z ||| t) + 6 *  ~~~(z |||  ~~~t) + 8 * (z &&&  ~~~t) + 15 * (z &&& t) = 5 *  ~~~(z ^^^ t)

theorem exact_ashr_eq_both_equal_thm (e : IntW 8) :
  icmp IntPred.eq (ashr (const? 8 (-128)) e { «exact» := true }) (const? 8 (-128)) ⊑
    icmp IntPred.eq e (const? 8 0)

theorem lshrugt_03_13_exact_proof : lshrugt_03_13_exact_before ⊑ lshrugt_03_13_exact_after

theorem xor_signbit_select_shl_proof : xor_signbit_select_shl_before ⊑ xor_signbit_select_shl_after

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

theorem mullo_proof : mullo_before ⊑ mullo_after

theorem add_or_sub_comb_i8_commuted2_nsw_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(True ∧ (x * x).saddOverflow (0#8 - x * x ||| x * x) = true) →
    ¬(True ∧ (x * x).saddOverflow (-1#8) = true) → x * x + (0#8 - x * x ||| x * x) = x * x + -1#8 &&& x * x

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

theorem test16_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(11#32 ≥ ↑32 ∨ (x >>> 11#32 &&& 4#32) + 4#32 = 0) →
    ¬(11#32 ≥ ↑32 ∨ True ∧ (x >>> 11#32 &&& 4#32 &&& 3#32 != 0) = true) →
      x_1 % ((x >>> 11#32 &&& 4#32) + 4#32) = x_1 &&& (x >>> 11#32 &&& 4#32 ||| 3#32)

theorem test15a_thm.extracted_1._2 : ∀ (x : BitVec 32), ¬ofBool (x &&& 16#32 == 0#32) = 1#1 → 16#32 = x &&& 16#32

theorem test_or_eq_a_b_proof : test_or_eq_a_b_before ⊑ test_or_eq_a_b_after

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

theorem ashr_eq_both_equal_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → ofBool ((BitVec.ofInt 8 (-128)).sshiftRight' x == BitVec.ofInt 8 (-128)) = ofBool (x == 0#8)

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

theorem e_2438 :
    11 * (f |||  ~~~(d ^^^ e)) + 3 *  ~~~(e &&&  ~~~f) + 4 * (f ^^^  ~~~(d ||| (e &&& f))) - 3 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 11 * (d ||| f) - 2 * (e ^^^ (d |||  ~~~f)) - 1 * ( ~~~f |||  ~~~(d ^^^ e)) + 1 * (f &&&  ~~~(d ^^^ e)) + 4 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 2 * ((d |||  ~~~e) &&& (e ^^^ f)) - 11 * ((d ||| e) &&& (e ^^^ f)) - 1 * (d |||  ~~~f) - 1 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 6 * (f ^^^ (d &&& e)) - 5 * (e ^^^ (d &&& ( ~~~e ||| f))) + 5 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 6 *  ~~~( ~~~d ||| (e &&& f)) - 6 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 2 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 1 *  ~~~(d ^^^ ( ~~~e ||| f)) + 4 * (d &&& (e ||| f)) - 1 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 2 *  ~~~(d ^^^ f) + 5 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 5 *  ~~~(e ||| f) + 1 * (d |||  ~~~e) + 5 * ( ~~~d ||| (e ||| f)) + 1 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) + 1 * (e ^^^ (d &&& f)) + 2 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 1 * (e ^^^ (d ||| (e ||| f))) + 3 * ( ~~~d ||| (e &&& f)) - 1 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 6 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 1 * (d &&&  ~~~f) - 7 * ( ~~~e &&& (d ^^^ f)) + 2 * (f ^^^  ~~~(d |||  ~~~e)) + 11 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 11 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 2 * (d &&& f) + 7 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 5 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) + 11 * f - 11 * (d &&& e) - 5 * (f ^^^ ( ~~~d ||| (e ||| f))) + 4 * (e |||  ~~~f) + 1 * (e ^^^  ~~~(d ||| (e &&& f))) - 7 * ( ~~~d &&& (e ||| f)) - 7 * ( ~~~e ||| (d ^^^ f)) + 3 * (e ^^^  ~~~(d &&&  ~~~f)) - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 4 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 7 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 2 * (f ^^^  ~~~(d &&& (e ||| f))) - 5 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 1 * ( ~~~d ||| (e ^^^ f)) + 11 * ((d &&& f) ||| (e &&&  ~~~f)) - 6 * (d ||| e) - 1 * (e &&& (d ^^^ f)) - 5 * (f ^^^ (d &&&  ~~~e)) + 7 *  ~~~(d ^^^ (e ||| f)) + 1 * (d ||| ( ~~~e ||| f)) - 3 * (f ^^^ (d ||| ( ~~~e ||| f))) - 1 * (d ||| (e ^^^ f)) - 3 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 1 * (f ^^^  ~~~(d &&& (e &&& f))) - 26 *  ~~~(d ||| (e ||| f)) - 6 *  ~~~(d ||| ( ~~~e ||| f)) + 40 *  ~~~( ~~~d ||| (e ||| f)) + 48 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 16 * ( ~~~d &&& ( ~~~e &&& f)) - 6 * ( ~~~d &&& (e &&& f)) + 4 * (d &&& ( ~~~e &&& f)) - 55 * (d &&& (e &&& f)) = 2 * (f ^^^  ~~~(d &&&  ~~~e)) - 1 * (e ^^^ ( ~~~d ||| (e ||| f)))

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

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

theorem PR52261_proof : PR52261_before ⊑ PR52261_after

theorem ashr_ult_exact_near_pow2_cmpval_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x >>> 1#8 <<< 1#8 ≠ x ∨ 1#8 ≥ ↑8) → ofBool (x.sshiftRight' 1#8 <ᵤ 5#8) = ofBool (x <ᵤ 9#8)

theorem add_or_sub_comb_i8_negative_y_add_proof : add_or_sub_comb_i8_negative_y_add_before ⊑ add_or_sub_comb_i8_negative_y_add_after

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

theorem main4d_proof : main4d_before ⊑ main4d_after

theorem shrink_select_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → truncate 8 42#32 = 42#8

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 e_1725 :
     - 1 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) + 2 * (b &&& (a |||  ~~~c)) + 3 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 2 * (b ||| c) - 3 *  ~~~(a ||| ( ~~~b &&& c)) - 2 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) - 11 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) - 2 *  ~~~(a &&& ( ~~~b &&& c)) - 1 * (c ||| (a ^^^ b)) + 1 * (a &&& b) - 11 * (b |||  ~~~c) - 2 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 1 *  ~~~b + 11 * (a ^^^ ( ~~~b &&& c)) + 5 * ( ~~~(a ||| b) |||  ~~~(b ^^^ c)) + 7 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) + 7 * (b ^^^ (a ||| ( ~~~b &&& c))) + 4 * ((a &&& c) ^^^ (a ^^^ (b &&& c))) - 2 * (b ^^^  ~~~( ~~~a ||| (b ^^^ c))) + 2 * (c &&& (a ^^^ b)) + 1 *  ~~~(a |||  ~~~c) + 2 * (a ||| ( ~~~b &&& c)) - 1 *  ~~~( ~~~a &&& ( ~~~b &&& c)) + 4 * (c ^^^  ~~~(a &&& b)) + 15 *  ~~~(a ||| (b ||| c)) - 2 *  ~~~( ~~~a ||| (b ||| c)) - 14 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 31 * ( ~~~a &&& ( ~~~b &&& c)) + 1 * ( ~~~a &&& (b &&& c)) - 18 * (a &&& ( ~~~b &&& c)) - 2 * (a &&& (b &&& c)) =  - 14 *  ~~~(a ||| ( ~~~b ||| c))

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

theorem or_xor_tree_0111_proof : or_xor_tree_0111_before ⊑ or_xor_tree_0111_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_7b_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_swapped_7b_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_swapped_7b_logical_after

theorem ult_1_impliesF_eq_1_proof : ult_1_impliesF_eq_1_before ⊑ ult_1_impliesF_eq_1_after

theorem lshr_and_thm (e e_1 : IntW 64) :
  lshr (LLVM.and (LLVM.srem e_1 (const? 64 42)) (lshr e (const? 64 5))) (const? 64 7) ⊑
    LLVM.and (lshr e (const? 64 12)) (lshr (LLVM.srem e_1 (const? 64 42)) (const? 64 7))

theorem select_lshr_icmp_bad_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 == 1#32) = 1#1 → ¬x_1 ≥ ↑32 → ¬1#32 ≥ ↑32 → x >>> x_1 = x >>> 1#32

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

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

theorem udiv_shl_mul_nuw_proof : udiv_shl_mul_nuw_before ⊑ udiv_shl_mul_nuw_after

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

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

theorem e_1323 :
     - 11 * (z ^^^ t) - 1 * (z |||  ~~~t) - 5 *  ~~~(z &&&  ~~~t) + 2 * (z ||| t) - 11 *  ~~~(z &&& t) + 24 *  ~~~(z ||| t) + 25 *  ~~~(z |||  ~~~t) + 20 * (z &&&  ~~~t) + 10 * (z &&& t) = 7 *  ~~~(z ^^^ t) - 1 * z

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

theorem test_with_neg_even_proof : test_with_neg_even_before ⊑ test_with_neg_even_after

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

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

theorem ashr_lshr_shift_amt_mismatch_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (0#32 ≤ₛ x_2) = 1#1 → ¬x ≥ ↑32 → ¬ofBool (x_2 <ₛ 0#32) = 1#1 → x_1 ≥ ↑32 → False

theorem e_2337 :
    4 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 6 *  ~~~(d ^^^ (e &&& f)) - 11 * (e ^^^  ~~~(d &&& (e ||| f))) + 2 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 7 * (f ^^^ (d ||| (e &&& f))) - 1 * (d &&& ( ~~~e ||| f)) + 7 * ( ~~~f |||  ~~~(d ^^^ e)) + 7 * ((d &&& e) |||  ~~~(e ||| f)) + 1 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 5 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 4 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 1 * ( ~~~e ||| (d ^^^ f)) - 1 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 11 * ((d ^^^ e) |||  ~~~(d ^^^ f)) + 7 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 11 * (d &&& f) + 11 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 1 * (f |||  ~~~(d |||  ~~~e)) + 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 3 * ( ~~~f &&&  ~~~(d ^^^ e)) + 5 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 11 * (d ^^^ (e ||| f)) - 1 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 1 * ( ~~~f ||| (d ^^^ e)) - 2 *  ~~~(d ^^^ ( ~~~e &&& f)) + 5 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 2 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 1 * ( ~~~d ||| (e &&& f)) + 2 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 5 * (e ^^^  ~~~(d ||| f)) + 2 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 3 *  ~~~( ~~~d ||| (e ^^^ f)) - 3 * (e ^^^ ( ~~~d ||| (e &&& f))) - 7 * (e ^^^ ( ~~~d &&& (e ||| f))) - 5 * (e ^^^ (d &&& (e ||| f))) - 6 *  ~~~(d ^^^ ( ~~~e ||| f)) + 2 * ((e &&& f) ||| (d &&& (e ||| f))) + 4 * (d ^^^ (e &&& f)) + 2 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 2 * ((d |||  ~~~e) &&& (e ^^^ f)) - 6 * (f ^^^  ~~~(d ||| (e &&& f))) + 1 * (d ||| f) + 1 * (e ^^^ (d |||  ~~~f)) + 2 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 1 * (f ^^^ (d ||| ( ~~~e &&& f))) + 2 * (f ^^^ (d &&& ( ~~~e ||| f))) - 7 * (d &&&  ~~~e) + 1 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 * (e ^^^  ~~~(d &&&  ~~~f)) + 4 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 1 *  ~~~(d ||| e) - 5 * (d ^^^ ( ~~~e &&& f)) + 1 * (f ^^^  ~~~(d &&& (e &&& f))) + 1 *  ~~~( ~~~d ||| (e &&& f)) - 2 * (d &&& (e ^^^ f)) + 3 * ( ~~~d &&& ( ~~~e ||| f)) - 38 *  ~~~(d ||| (e ||| f)) - 9 *  ~~~(d ||| ( ~~~e ||| f)) - 16 *  ~~~( ~~~d ||| (e ||| f)) - 50 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 15 * ( ~~~d &&& ( ~~~e &&& f)) - 14 * ( ~~~d &&& (e &&& f)) - 18 * (d &&& ( ~~~e &&& f)) - 41 * (d &&& (e &&& f)) =  - 11 *  ~~~(d ^^^ e) + 2 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f)))

theorem ashrsgt_01_12_thm (e : IntW 4) :
  icmp IntPred.sgt (ashr e (const? 4 1)) (const? 4 (-4)) ⊑ icmp IntPred.sgt e (const? 4 (-7))

theorem logical_and_not_proof : logical_and_not_before ⊑ logical_and_not_after

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

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

theorem nonexact_ashr_ne_noexactlog_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → ofBool ((BitVec.ofInt 8 (-90)).sshiftRight' x != BitVec.ofInt 8 (-30)) = 1#1

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

theorem udiv_shl_pair3_proof : udiv_shl_pair3_before ⊑ udiv_shl_pair3_after

theorem lshrult_01_09_proof : lshrult_01_09_before ⊑ lshrult_01_09_after

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

theorem test_or3_logical_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sle (LLVM.and e_1 (const? 32 2147483647)) e) (const? 1 1)
      (icmp IntPred.slt e (const? 32 0)) ⊑
    icmp IntPred.uge e (LLVM.and e_1 (const? 32 2147483647))

theorem sgt_3_impliesT_sgt_2_proof : sgt_3_impliesT_sgt_2_before ⊑ sgt_3_impliesT_sgt_2_after

theorem test21_proof : test21_before ⊑ test21_after

theorem src_proof : src_before ⊑ src_after

theorem sgt_swap_or_not_min_commute_proof : sgt_swap_or_not_min_commute_before ⊑ sgt_swap_or_not_min_commute_after

lemma bisimul_comp {m : RawCNFA A} :
    m.Simul M₁ R₁ ⊤ ∅ → M₁.Bisimul R₂ M₂ →
    m.Simul M₂ (R₁.comp R₂) ⊤ ∅

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

theorem test1_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 57), ¬(x_1 ≥ ↑57 ∨ x_1 ≥ ↑57) → x_1 ≥ ↑57 → False

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

theorem fold_icmp_shl_nuw_c2_precondition2_thm (e : IntW 32) :
  icmp IntPred.ult (shl (const? 32 127) e { «nsw» := false, «nuw» := true }) (const? 32 63) ⊑ const? 1 0

theorem select_and_icmp_proof : select_and_icmp_before ⊑ select_and_icmp_after

theorem fold_mask_cmps_to_true_logical_thm (e : IntW 32) :
  select (icmp IntPred.ne e (const? 32 2147483647)) (const? 1 1)
      (icmp IntPred.ne (LLVM.and e (const? 32 2147483647)) (const? 32 0)) ⊑
    const? 1 1

@[simp, simp_llvm]
theorem isRefinedBy_iff (x y : LLVM.IntW w) :
    x ⊑ y ↔ @HRefinement.IsRefinedBy (PoisonOr _) (PoisonOr _) _ x y

theorem or_logic_or_logic_and_6_thm.extracted_1._9 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 ||

theorem test_mul_nuw__nuw_is_safe_proof : test_mul_nuw__nuw_is_safe_before ⊑ test_mul_nuw__nuw_is_safe_after

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

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

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

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

theorem test15a_proof : test15a_before ⊑ test15a_after

theorem lshrult_03_08_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 (-8)) = 1#1

lemma eval_eq_of_eq_on_vars [DecidableEq α] : ∀ {c : Circuit α} {f g : α → Bool}
    (_h : ∀ x ∈ c.vars, f x = g x), eval c f = eval c g

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

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

theorem urem_i1_is_zero_thm (e e_1 : IntW 1) : urem e_1 e ⊑ const? 1 0

theorem no_shift_xor_multiuse_xor_proof : no_shift_xor_multiuse_xor_before ⊑ no_shift_xor_multiuse_xor_after

theorem mul_constant_eq_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 * 5#32 == x * 5#32) = ofBool (x_1 == x)

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

theorem icmp_slt_0_and_icmp_ne_neg2_i32_fail_proof : icmp_slt_0_and_icmp_ne_neg2_i32_fail_before ⊑ icmp_slt_0_and_icmp_ne_neg2_i32_fail_after

theorem t7_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 8), x = 1#1 → x_1 - 0#8 = 0#8 + x_1

theorem fork_hs_dc_equiv_fst (x : DCOp.TokenStream):
    (DCOp.fork (x)).fst ~ (HandshakeOp.fork (x)).fst

theorem alive_AndOrXor_1247_AB__AB__AB  (w : Nat)   : alive_AndOrXor_1247_AB__AB__AB_src w  ⊑ alive_AndOrXor_1247_AB__AB__AB_tgt w

theorem test_sub_0_Y_eq_0_proof : test_sub_0_Y_eq_0_before ⊑ test_sub_0_Y_eq_0_after

theorem scalar_i16_shl_and_negC_eq_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬x ≥ ↑16 → ofBool (x_1 <<< x &&& BitVec.ofInt 16 (-128) == 0#16) = ofBool (x_1 <<< x <ᵤ 128#16)

theorem udiv_shl_mul_nuw_swap_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 5),
  ¬(True ∧ x_2 <<< x_1 >>> x_1 ≠ x_2 ∨ x_1 ≥ ↑5 ∨ True ∧ x.umulOverflow x_2 = true ∨ x * x_2 = 0) →
    ¬(True ∧ 1#5 <<< x_1 >>> x_1 ≠ 1#5 ∨ x_1 ≥ ↑5 ∨ x = 0) → x_2 <<< x_1 / (x * x_2) = 1#5 <<< x_1 / x

@[simp] theorem Com.denote_changeVars
    (varsMap : Γ.Hom Γ') (c : Com d Γ eff ty) :
    (c.changeVars varsMap).denote =
    fun V => c.denote (V.comap varsMap)

theorem and_not_or_or_not_or_xor_commute2_proof : and_not_or_or_not_or_xor_commute2_before ⊑ and_not_or_or_not_or_xor_commute2_after

theorem sgt_x_impliesF_eq_smin_todo_thm.extracted_1._3 : ∀ (x x_1 x_2 : BitVec 8),
  ofBool (x_1 <ₛ x_2) = 1#1 → ofBool (x_2 ≤ₛ x_1) = 1#1 → ofBool (BitVec.ofInt 8 (-128) == x_2) = ofBool (x == x_2)

theorem ult_rem_nz_nsw_proof : ult_rem_nz_nsw_before ⊑ ult_rem_nz_nsw_after

theorem alive_AndOrXor_2581__BAB___A__B  (w : Nat)   : alive_AndOrXor_2581__BAB___A__B_src w  ⊑ alive_AndOrXor_2581__BAB___A__B_tgt w

theorem test11c_proof : test11c_before ⊑ test11c_after

theorem sel_false_val_is_a_masked_ashr_of_true_val1_thm.extracted_1._4 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& BitVec.ofInt 32 (-2147483588) == 0#32) = 1#1 →
    ¬(2#32 ≥ ↑32 ∨ zeroExtend 64 ((x_1 &&& BitVec.ofInt 32 (-2147483588)).sshiftRight' 2#32) ≥ ↑64) →
      ¬(2#32 ≥ ↑32 ∨
            True ∧ (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)).msb = true ∨
              zeroExtend 64 (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)) ≥ ↑64) →
        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 shl_add_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ¬(2#8 ≥ ↑8 ∨ 2#8 ≥ ↑8) → 2#8 ≥ ↑8 → False

theorem test25_logical_thm (e : IntW 32) :
  select (icmp IntPred.sge e (const? 32 50)) (icmp IntPred.slt e (const? 32 100)) (const? 1 0) ⊑
    icmp IntPred.ult (add e (const? 32 (-50))) (const? 32 50)

theorem test_and_xor_freely_invertable_thm (e : IntW 1) (e_1 e_2 : IntW 32) :
  LLVM.and (LLVM.xor (icmp IntPred.sgt e_2 e_1) e) e ⊑ LLVM.and (icmp IntPred.sle e_2 e_1) e

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

theorem main7c_logical_thm.extracted_1._2 : ∀ (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 → 1#32 = zeroExtend 32 1#1

theorem c_0_1_0_thm.extracted_1._2 : ∀ (x x_1 : BitVec 4),
  ¬(True ∧ (x &&& BitVec.ofInt 4 (-2) &&& (x_1 &&& 1#4) != 0) = true) →
    (x_1 ^^^ x) &&& BitVec.ofInt 4 (-2) ^^^ x_1 = x &&& BitVec.ofInt 4 (-2) ||

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

theorem fold_sext_to_and_wrong8_proof : fold_sext_to_and_wrong8_before ⊑ fold_sext_to_and_wrong8_after

@[bv_automata_nnf] theorem Int.lt_eq (a b : Int) : (a < b) = (a + 1 ≤ b)

theorem bv_283 :
    ∀ (e e_1 : LLVM.IntW 1), LLVM.mul e_1 e ⊑ LLVM.and e_1 e

theorem test_shl_nuw_nsw__nuw_is_safe_proof : test_shl_nuw_nsw__nuw_is_safe_before ⊑ test_shl_nuw_nsw__nuw_is_safe_after

theorem n15_variable_shamts_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32) (x_2 x_3 : BitVec 64),
  ¬(x_2 ≥ ↑64 ∨ x ≥ ↑32) →
    ¬(x ≥ ↑32 ∨ x_2 ≥ ↑64) →
      ofBool (truncate 32 (x_3 <<< x_2) &&& x_1 >>> x != 0#32) =
        ofBool (x_1 >>> x &&& truncate 32 (x_3 <<< x_2) != 0#32)

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

theorem e_2353 :
     - 5 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 11 * ( ~~~f &&& (d ^^^ e)) + 7 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 6 *  ~~~(d ^^^ e) - 2 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) + 1 * (e ^^^  ~~~(d |||  ~~~f)) + 3 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 4 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 2 * ( ~~~f &&&  ~~~(d ^^^ e)) - 2 * (d ^^^ ( ~~~e &&& f)) - 1 * (e ^^^ f) - 2 *  ~~~( ~~~d &&& (e ||| f)) + 11 * (e |||  ~~~(d |||  ~~~f)) + 1 * (e ^^^ (d ||| (e ||| f))) - 2 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 1 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 3 * (e |||  ~~~f) + 11 *  ~~~d + 5 *  ~~~( ~~~d &&& (e ^^^ f)) + 5 * (e ^^^ ( ~~~d &&& (e ||| f))) + 5 * (d &&& e) + 1 * ((d &&& f) ^^^ (e ||| f)) - 1 * (e ^^^  ~~~(d ||| (e &&& f))) + 4 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 3 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 7 * ( ~~~e ||| (d ^^^ f)) - 5 * (e ^^^ ( ~~~d ||| (e ^^^ f))) + 7 *  ~~~(d ^^^ ( ~~~e ||| f)) - 2 * (e ^^^ (d ||| ( ~~~e &&& f))) - 2 *  ~~~(d &&& (e ||| f)) - 3 *  ~~~(d &&& ( ~~~e &&& f)) + 2 * (f &&& (d |||  ~~~e)) - 6 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 5 * (f ^^^  ~~~(d &&& (e ||| f))) - 11 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 7 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 1 * (e ^^^ (d &&&  ~~~f)) - 1 * ((d |||  ~~~e) &&& (e ^^^ f)) - 1 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 7 * (f ||| (d &&& e)) + 11 * ( ~~~d &&& (e ^^^ f)) + 5 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 11 * (d &&& f) - 6 * ( ~~~e &&&  ~~~(d ^^^ f)) + 2 * (f ^^^  ~~~(d &&&  ~~~e)) + 1 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 2 *  ~~~(e ^^^ f) + 2 * (f ^^^ (d ||| e)) - 6 *  ~~~(d &&& (e ^^^ f)) - 1 * e - 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 *  ~~~(d &&& f) + 7 * (f |||  ~~~(d ||| e)) - 7 *  ~~~(d ||| f) - 3 * (f ^^^ (d |||  ~~~e)) + 4 * (f ^^^ (d &&& ( ~~~e ||| f))) - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 6 * ((d &&& f) ||| (e &&&  ~~~f)) + 2 * (d &&&  ~~~e) - 10 *  ~~~(d ||| (e ||| f)) - 6 *  ~~~(d ||| ( ~~~e ||| f)) - 11 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 28 * ( ~~~d &&& ( ~~~e &&& f)) - 44 * ( ~~~d &&& (e &&& f)) - 20 * (d &&& ( ~~~e &&& f)) - 8 * (d &&& (e &&& f)) =  - 2 * (f ^^^ (d ||| (e ||| f))) + 14 *  ~~~( ~~~d ||| (e ||| f))

theorem ashrslt_01_06_exact_proof : ashrslt_01_06_exact_before ⊑ ashrslt_01_06_exact_after

theorem select_of_symmetric_selects_thm.extracted_1._7 : ∀ (x x_1 : BitVec 32) (x_2 x_3 : BitVec 1),
  ¬x_3 = 1#1 → x_2 = 1#1 → ¬x_2 ^^^ x_3 = 1#1 → x = x_1

@[bv_multi_width_normalize]
theorem iff_iff_and_or_not_and_not {P Q : Prop} : (P ↔ Q) ↔ ((P ∧ Q) ∨  (¬ P ∧ ¬ Q))

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

theorem lshr_16_add_not_known_16_leading_zeroes_proof : lshr_16_add_not_known_16_leading_zeroes_before ⊑ lshr_16_add_not_known_16_leading_zeroes_after

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

theorem udiv_i32_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ¬zeroExtend 32 x = 0 → x = 0 → False

theorem ashrslt_02_05_exact_proof : ashrslt_02_05_exact_before ⊑ ashrslt_02_05_exact_after

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

lemma gt_one_of_neq_0_neq_1 (a : BitVec w) (ha0 : a ≠ 0) (ha1 : a ≠ 1) : a > 1

theorem t2_proof : t2_before ⊑ t2_after

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 test5_thm (e : IntW 8) (e_1 : IntW 32) :
  urem e_1 (shl (const? 32 32) (zext 32 e)) ⊑
    LLVM.and e_1
      (add (shl (const? 32 32) (zext 32 e { «nneg» := true }) { «nsw» := false, «nuw» := true })
        (const? 32 (-1)))

theorem absdiff2_proof : absdiff2_before ⊑ absdiff2_after

theorem rotateleft_9_neg_mask_wide_amount_commute_thm.extracted_1._1 : ∀ (x : BitVec 33) (x_1 : BitVec 9),
  ¬(x &&& 8#33 ≥ ↑33 ∨ 0#33 - x &&& 8#33 ≥ ↑33) →
    True ∧ (zeroExtend 33 x_1 <<< (x &&& 8#33)).sshiftRight' (x &&& 8#33) ≠ zeroExtend 33 x_1 ∨
        True ∧ zeroExtend 33 x_1 <<< (x &&& 8#33) >>> (x &&& 8#33) ≠ zeroExtend 33 x_1 ∨
          x &&& 8#33 ≥ ↑33 ∨ 0#33 - x &&& 8#33 ≥ ↑33 →
      False

theorem ashr_sle_exact_proof : ashr_sle_exact_before ⊑ ashr_sle_exact_after

theorem ashr_xor_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬((42#32 == 0 || 32 != 1 && x_1 == intMin 32 && 42#32 == -1) = true ∨ 5#32 ≥ ↑32 ∨ 7#32 ≥ ↑32) →
    ¬(12#32 ≥ ↑32 ∨ (42#32 == 0 || 32 != 1 && x_1 == intMin 32 && 42#32 == -1) = true ∨ 7#32 ≥ ↑32) →
      (x_1.srem 42#32 ^^^ x.sshiftRight' 5#32).sshiftRight' 7#32 =
        x.sshiftRight' 12#32 ^^^ (x_1.srem 42#32).sshiftRight' 7#32

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

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

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

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

theorem trunc_sel_equal_sext_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → signExtend 32 42#16 = 42#32

theorem reassoc_x2_add_nuw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.uaddOverflow 4#32 = true ∨
        True ∧ x.uaddOverflow 8#32 = true ∨ True ∧ (x_1 + 4#32).uaddOverflow (x + 8#32) = true) →
    True ∧ x_1.uaddOverflow x = true ∨ True ∧ (x_1 + x).uaddOverflow 12#32 = true → False

theorem negate_sext_proof : negate_sext_before ⊑ negate_sext_after

theorem test_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (255#32 <ᵤ x) ||

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

theorem lshr_not_nneg2_proof : lshr_not_nneg2_before ⊑ lshr_not_nneg2_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 lshr_16_to_64_add_zext_basic_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬16#64 ≥ ↑64 → (zeroExtend 64 x_1 + zeroExtend 64 x) >>> 16#64 = zeroExtend 64 (ofBool (x_1 ^^^ -1#16 <ᵤ x))

theorem lowbitmask_casted_shift_proof : lowbitmask_casted_shift_before ⊑ lowbitmask_casted_shift_after

theorem trunc_lshr_sext_narrow_input_proof : trunc_lshr_sext_narrow_input_before ⊑ trunc_lshr_sext_narrow_input_after

theorem add_smax_simplify_proof : add_smax_simplify_before ⊑ add_smax_simplify_after

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

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

theorem e_98 :
     - 2 * (x ||| y) - 5 * (x |||  ~~~y) - 3 *  ~~~(x ^^^ y) + 8 *  ~~~(x ||| y) + 2 *  ~~~(x |||  ~~~y) + 10 * (x &&& y) =  - 7 * (x &&&  ~~~y)

theorem lshr_add_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(5#8 ≥ ↑8 ∨ (42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true ∨ 5#8 ≥ ↑8) →
    (42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true ∨ 5#8 ≥ ↑8 → False

@[simp] theorem Lets.denote_var_appendInl_pure (lets : Lets d Γ_in .pure Γ_out)
    (e : Expr d Γ_out .pure tys) (V_in : Valuation Γ_in) (v : Var _ u) :
    Lets.denote (var lets e) V_in v.appendInl
    = let xs : HVector .. := e.denoteOp (lets.denote V_in)
      xs[v]

theorem positive_biggershl_shlnuwnsw_proof : positive_biggershl_shlnuwnsw_before ⊑ positive_biggershl_shlnuwnsw_after

theorem e_2314 :
     - 2 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 7 * (f &&& (d ||| e)) + 1 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 7 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 7 *  ~~~(d &&&  ~~~f) + 2 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 1 * ((d ^^^ e) ||| (d ^^^ f)) - 6 * (f ^^^ (d ||| ( ~~~e ||| f))) + 11 *  ~~~(d &&& ( ~~~e &&& f)) - 2 * (e ^^^ (d &&& ( ~~~e ||| f))) - 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 5 * (e |||  ~~~f) - 6 * (e ^^^ (d |||  ~~~f)) - 5 * (e ^^^ ( ~~~d ||| (e ^^^ f))) + 5 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 1 * (f &&&  ~~~(d &&&  ~~~e)) - 6 * (d ^^^ (e ^^^ f)) - 1 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) + 1 * ( ~~~d &&& ( ~~~e ||| f)) + 1 * (d ||| (e &&& f)) - 11 * (d &&& e) - 3 * (e &&&  ~~~(d &&&  ~~~f)) + 2 * (f ^^^ (d &&& e)) + 11 * (d ||| f) - 1 * (f ^^^ (d |||  ~~~e)) - 3 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 3 * ((e &&& f) ||| (d &&& (e ||| f))) + 11 * (e ^^^ (d &&&  ~~~f)) - 2 * ((d &&& e) ||| (e ^^^ f)) + 1 * (e ^^^ (d ||| f)) + 5 * ((d &&& e) ^^^ (e ||| f)) - 2 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 6 * (d &&& (e ||| f)) + 11 * ((d &&& f) ^^^ (e ||| f)) + 7 * (d ||| (e ||| f)) + 4 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 1 * ( ~~~d &&& (e ||| f)) + 3 * (e &&&  ~~~(d ^^^ f)) - 11 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 5 * (e ||| (d &&& f)) + 1 *  ~~~(e &&& f) + 1 *  ~~~f - 1 * (f ^^^  ~~~(d &&&  ~~~e)) - 11 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 2 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 7 * ((d &&& e) ^^^ (e |||  ~~~f)) + 2 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 1 *  ~~~(d ||| (e ^^^ f)) + 1 *  ~~~(d ^^^ (e ^^^ f)) - 1 * (e ^^^ (d ||| (e ^^^ f))) + 4 *  ~~~(e ||| f) + 3 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 4 * (d ^^^ (e &&& f)) + 5 * (f ^^^  ~~~(d ||| e)) + 15 *  ~~~(d ||| (e ||| f)) - 24 *  ~~~(d ||| ( ~~~e ||| f)) - 12 *  ~~~( ~~~d ||| (e ||| f)) - 25 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 52 * ( ~~~d &&& ( ~~~e &&& f)) + 11 * (d &&& ( ~~~e &&& f)) + 5 * (d &&& (e &&& f)) = 30 * ( ~~~d &&& (e &&& f))

theorem shl1_nsw_proof : shl1_nsw_before ⊑ shl1_nsw_after

theorem p0_proof : p0_before ⊑ p0_after

@[simp] theorem borrow_zero (x y : BitStream) : (x.borrow y 0) = (!(x 0) && y 0)

theorem t15_proof : t15_before ⊑ t15_after

theorem or_wrong_const1_thm (e : IntW 16) :
  LLVM.or (icmp IntPred.ne (trunc 8 e) (const? 8 127))
      (icmp IntPred.ne (LLVM.and e (const? 16 (-256))) (const? 16 17665)) ⊑
    const? 1 1

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

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

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

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

theorem logical_or_logical_or_icmps_comm3_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_2 &&& 1#8 == 0#8) = 1#1) →
      ¬(True ∧ 1#8 <<< x_1 >>> x_1 ≠ 1#8 ∨ x_1 ≥ ↑8 ∨ True ∧ 1#8 <<< x_1 >>> x_1 ≠ 1#8 ∨ x_1 ≥ ↑8) →
        ofBool (x_2 &&& (1#8 <<< x_1 ||| 1#8) != 1#8 <<< x_1 ||| 1#8) = 1#1 → ofBool (x == 42#8) = 1#1

theorem slt_or_not_max_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 != 127#8) ||

theorem alive_Select_1105 : alive_Select_1105_src ⊑ alive_Select_1105_tgt

theorem add_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 sge_to_ugt_proof : sge_to_ugt_before ⊑ sge_to_ugt_after

theorem lshrugt_01_09_exact_proof : lshrugt_01_09_exact_before ⊑ lshrugt_01_09_exact_after

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

theorem bitwise_and_logical_and_masked_icmp_asymmetric_thm.extracted_1._6 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 255#32 != 0#32) = 1#1 →
    ¬ofBool (x_1 &&& 11#32 == 11#32) = 1#1 → 0#1 &&& ofBool (x_1 &&& 11#32 == 11#32) = 0#1

theorem substitute_constant_or_ne_swap_sle_logical_proof : substitute_constant_or_ne_swap_sle_logical_before ⊑ substitute_constant_or_ne_swap_sle_logical_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_7b_proof : masked_icmps_mask_notallzeros_bmask_mixed_7b_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_7b_after

theorem positive_samevar_shlnuwnsw_proof : positive_samevar_shlnuwnsw_before ⊑ positive_samevar_shlnuwnsw_after

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

theorem alive_InstCombineShift__440  (w : Nat)   : alive_InstCombineShift__440_src w  ⊑ alive_InstCombineShift__440_tgt w

@[simp] theorem Expr.op_mk {varName} {op : Op} {args} {regions : List (Region Op T)} :
    Expr.op ⟨varName, op, args, regions⟩ = op

theorem add_select_sext_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → 1#64 + signExtend 64 x = 1#64

theorem add_nosignbit_select_shl_thm (e : IntW 32) (e_1 : IntW 1) :
  shl (select e_1 (add e (const? 32 2147418112)) e) (const? 32 8) ⊑
    select e_1 (add (shl e (const? 32 8)) (const? 32 (-16777216))) (shl e (const? 32 8))

theorem test11e_proof : test11e_before ⊑ test11e_after

theorem mul_four (x : BitVec w) : 4 * x = x + x + x + x

theorem lshrugt_02_12_proof : lshrugt_02_12_before ⊑ lshrugt_02_12_after

private theorem if_else_if_then_poison_eq {α : Type} (c₁ c₂ : Prop) [Decidable c₁] [Decidable c₂]
      (x y : PoisonOr α):
    (if c₁ then x else (if c₂ then poison else y)) =
    (if ¬c₁ ∧ c₂ then poison else (if c₁ then x else y))

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

theorem test2_proof : test2_before ⊑ test2_after

theorem test21_thm.extracted_1._1 : ∀ (x x_1 : BitVec 256), ofBool (x_1 - x != x_1) = ofBool (x != 0#256)

theorem lshrugt_03_07_proof : lshrugt_03_07_before ⊑ lshrugt_03_07_after

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

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

theorem select_1_thm.extracted_1._17 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1) (x_3 : BitVec 8) (x_4 : BitVec 1),
  ¬x_4 = 1#1 → ¬x_2 = 1#1 → x ^^^ 123#8 ^^^ -1#8 = x ^^^ BitVec.ofInt 8 (-124)

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

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 width1 (w : Nat) (a : BitVec w) : (w = 1) → (a = 0#w ∨ a = 1#w)

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

theorem alive_Select_705 : forall (w : Nat) (A B : Bitvec 1)
, TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 1)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (A) %v0;
  %v2 := op:const (B) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:icmp sge  w %v3;
  %v5 := triple:%v4 %v1 %v2;
  %v6 := op:select 1 %v5;
  %v7 := pair:%v6 %v1;
  %v8 := op:icmp slt  w %v7;
  %v9 := triple:%v8 %v6 %v1;
  %v10 := op:select 1 %v9
  dsl_ret %v10
  ]  ⊑
  TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 1)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (A) %v0;
  %v2 := op:const (B) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:icmp sge  1 %v3;
  %v5 := triple:%v4 %v1 %v2;
  %v6 := op:select 1 %v5;
  %v7 := pair:%v6 %v1;
  %v8 := op:icmp slt  1 %v7;
  %v9 := op:copy 1 %v1
  dsl_ret %v9
  ]

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

theorem sub_ashr_and_i32_commute_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x.ssubOverflow x_1 = true ∨ 31#32 ≥ ↑32) →
    ¬ofBool (x <ₛ x_1) = 1#1 → x_1 &&& (x - x_1).sshiftRight' 31#32 = 0#32

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

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

theorem not_mul_of_pow2_proof : not_mul_of_pow2_before ⊑ not_mul_of_pow2_after

theorem and_ne_with_diff_one_signed_proof : and_ne_with_diff_one_signed_before ⊑ and_ne_with_diff_one_signed_after

theorem logic_and_logic_or_5_proof : logic_and_logic_or_5_before ⊑ logic_and_logic_or_5_after

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

theorem canonicalize_logic_first_and0_nsw_proof : canonicalize_logic_first_and0_nsw_before ⊑ canonicalize_logic_first_and0_nsw_after

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

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

@[bv_automata_nnf] theorem not_eq_prop (p q : Prop) : (¬(p = q)) = (p = ¬q)

theorem xor_signbit_select_ashr_proof : xor_signbit_select_ashr_before ⊑ xor_signbit_select_ashr_after

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

theorem test_sext2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), x_1 = 1#1 → -1#32 = signExtend 32 1#1

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

theorem test4_thm (e e_1 : IntW 67) :
  LLVM.and (LLVM.or e_1 (lshr e (const? 67 66))) (const? 67 2) ⊑ LLVM.and e_1 (const? 67 2)

theorem match_signed_proof : match_signed_before ⊑ match_signed_after

theorem negative5_proof : negative5_before ⊑ negative5_after

theorem p_commutative2_proof : p_commutative2_before ⊑ p_commutative2_after

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

theorem trunc_sandwich_proof : trunc_sandwich_before ⊑ trunc_sandwich_after

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

theorem carry_eq_carryWith_initCarry (p : FSM arity) (x : arity → BitStream) (n : Nat) :
    p.carry x n = p.carryWith p.initCarry x n

@[simp]
lemma BitVec.transport_getElem (f : Fin n2 → Fin n1) (bv : BitVec n1) (i : Nat) (hlt : i < n2) :
    (bv.transport f)[i] = bv.getLsbD (f ⟨i, hlt⟩)

theorem par_proof : par_before ⊑ par_after

theorem alive_Select_1105  (w : Nat)   : alive_Select_1105_src w  ⊑ alive_Select_1105_tgt w

theorem ult_to_sgt_thm (e e_1 : IntW 8) :
  icmp IntPred.ult (LLVM.xor e_1 (const? 8 127)) (LLVM.xor e (const? 8 127)) ⊑ icmp IntPred.sgt e_1 e

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

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

theorem ult_or_not_max_commute_logical_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 != -1#8) = 1#1 → ofBool (x_1 <ᵤ x) = ofBool (x_1 != -1#8)

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

theorem n1_proof : n1_before ⊑ n1_after

theorem shift_no_xor_multiuse_or_thm (e e_1 : IntW 32) :
  mul (select (icmp IntPred.eq (LLVM.and e_1 (const? 32 1)) (const? 32 0)) e (LLVM.or e (const? 32 2)))
      (LLVM.or e (const? 32 2)) ⊑
    mul (LLVM.or e (LLVM.and (shl e_1 (const? 32 1)) (const? 32 2))) (LLVM.or e (const? 32 2))

theorem shl_shl_thm (e : IntW 32) : shl (shl e (const? 32 6)) (const? 32 28) ⊑ const? 32 0

theorem alive_AddSub_1574 : alive_AddSub_1574_src ⊑ alive_AddSub_1574_tgt

theorem select_icmp_ne_0_and_4096_and_not_4096_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (0#32 != x_1 &&& 4096#32) = 1#1 →
    ¬ofBool (x_1 &&& 4096#32 == 0#32) = 1#1 → x &&& BitVec.ofInt 32 (-4097) = x

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

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

theorem sub_from_constant_of_add_with_constant_thm (e : IntW 8) : sub (const? 8 11) (add e (const? 8 42)) ⊑ sub (const? 8 (-31)) e

theorem no_shift_xor_multiuse_cmp_with_and_proof : no_shift_xor_multiuse_cmp_with_and_before ⊑ no_shift_xor_multiuse_cmp_with_and_after

theorem andn_or_cmp_1_proof : andn_or_cmp_1_before ⊑ andn_or_cmp_1_after

@[simp]
theorem toBitVec_neg (a : BitStream) :
    (- a).toBitVec w = - (a.toBitVec w)

theorem sext_zext_nneg_uge_op0_wide_proof : sext_zext_nneg_uge_op0_wide_before ⊑ sext_zext_nneg_uge_op0_wide_after

theorem test_imply_not2_thm.extracted_1._5 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  ¬ofBool (x_1 == 0#32) = 1#1 → ofBool (x_1 != 0#32) = 1#1 → 0#1 ||

@[simp]
theorem FSM.eval_ite_eq_decide {α : Type}
    (cond t e : FSM α)
    (env : α → BitStream) (i : Nat) :
    (FSM.ite cond t e).eval env i =
    if (cond.eval env i) then t.eval env i else e.eval env i

theorem lshr_pow2_ult_smin_thm (e : IntW 8) :
  icmp IntPred.ult (lshr (const? 8 (-128)) e) (const? 8 (-128)) ⊑ icmp IntPred.ne e (const? 8 0)

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

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

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

theorem scalar_i8_lshr_and_negC_eq_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (LLVM.and (lshr e_1 e) (const? 8 (-4))) (const? 8 0) ⊑
    icmp IntPred.ult (lshr e_1 e) (const? 8 4)

theorem sle_or_not_min_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.sle e_1 e) (const? 1 1) (icmp IntPred.ne e_1 (const? 8 (-128))) ⊑ const? 1 1

theorem select_icmp_and_8_ne_0_xor_8_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 8#32 == 0#32) = 1#1 → x = x &&& BitVec.ofInt 32 (-9)

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

theorem src_is_mask_xor_fail_notmask_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool ((x_1 ^^^ 123#8) &&& (x ^^^ x + -1#8 ^^^ -1#8) != x_1 ^^^ 123#8) =
    ofBool (x ^^^ 0#8 - x ||| x_1 ^^^ BitVec.ofInt 8 (-124) != -1#8)

theorem neg_mask2_lshr_thm (e : IntW 8) :
  sub (const? 8 0) (LLVM.and (lshr e (const? 8 3)) (const? 8 2)) ⊑
    sub (const? 8 0) (LLVM.and (lshr e (const? 8 3)) (const? 8 2)) { «nsw» := true, «nuw» := false }

theorem n2_thm (e e_1 : IntW 8) (e_2 : IntW 1) :
  LLVM.and (LLVM.xor e_2 (const? 1 1)) (icmp IntPred.eq e_1 e) ⊑
    LLVM.and (icmp IntPred.eq e_1 e) (LLVM.xor e_2 (const? 1 1))

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_thm (e : IntW 32) :
  LLVM.or (icmp IntPred.ne (LLVM.and e (const? 32 7)) (const? 32 1))
      (icmp IntPred.eq (LLVM.and e (const? 32 12)) (const? 32 0)) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 15)) (const? 32 9)

theorem test14_proof : test14_before ⊑ test14_after

theorem neg_or_ashr_i32_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → (0#32 - x ||| x).sshiftRight' 31#32 = signExtend 32 (ofBool (x != 0#32))

theorem e_1648 :
    11 * (b ^^^ ( ~~~a ||| (b ^^^ c))) - 7 * (a ^^^ b) + 1 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) - 1 * ( ~~~a ||| (b ||| c)) - 2 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) + 1 * ( ~~~c |||  ~~~(a ^^^ b)) + 1 * (b ^^^  ~~~(a &&& (b ^^^ c))) + 3 *  ~~~(a &&& (b ||| c)) - 2 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) - 5 *  ~~~( ~~~a &&& ( ~~~b ||| c)) + 1 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) + 7 * (a |||  ~~~b) + 5 * (b ^^^  ~~~(a &&&  ~~~c)) - 3 * ( ~~~(a ||| b) ||| (b ^^^ c)) + 11 * ( ~~~c ||| (a ^^^ b)) - 1 * ((a &&&  ~~~b) ||| (b ^^^ c)) - 11 *  ~~~(a &&& (b &&& c)) + 14 *  ~~~(a ||| ( ~~~b ||| c)) - 5 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 12 * ( ~~~a &&& ( ~~~b &&& c)) + 6 * ( ~~~a &&& (b &&& c)) - 5 * (a &&& ( ~~~b &&& c)) - 11 * (a &&& (b &&& c)) = 24 *  ~~~(a ||| (b ||| c))

theorem ult_swap_and_max_commute_proof : ult_swap_and_max_commute_before ⊑ ult_swap_and_max_commute_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_0_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_0_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_0_logical_after

theorem t5_thm.extracted_1._8 : ∀ (x x_1 : BitVec 1) (x_2 : BitVec 32),
  ¬x_1 = 1#1 → ¬x_2 ≥ ↑32 → ¬1#32 <<< x_2 = 0 → x_2 / 1#32 <<< x_2 = x_2 >>> x_2

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

theorem basic_preserve_nuw_nsw_thm (e e_1 : IntW 8) :
  LLVM.xor (add (LLVM.xor e_1 (const? 8 (-1))) e { «nsw» := true, «nuw» := true }) (const? 8 (-1)) ⊑
    sub e_1 e { «nsw» := true, «nuw» := true }

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

theorem neg_or_ashr_i32_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → (0#32 - x ||| x).sshiftRight' 31#32 = signExtend 32 (ofBool (x != 0#32))

theorem lshr_ne_opposite_msb_thm (e : IntW 8) :
  icmp IntPred.ne (lshr (const? 8 (-128)) e) (const? 8 1) ⊑ icmp IntPred.ne e (const? 8 7)

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

theorem lshrugt_02_14_proof : lshrugt_02_14_before ⊑ lshrugt_02_14_after

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

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

theorem e_2420 :
     - 2 *  ~~~(d ^^^ e) + 3 * (e ^^^  ~~~(d &&&  ~~~f)) - 1 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 7 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 3 * (f |||  ~~~(d ^^^ e)) + 4 * (f ^^^ (d &&& ( ~~~e ||| f))) + 1 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 2 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 2 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 6 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 3 * (d &&& (e ||| f)) - 7 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 3 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 7 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 1 * ( ~~~d &&& (e ||| f)) - 11 *  ~~~f + 1 * ( ~~~f &&& (d ^^^ e)) + 5 * ((d |||  ~~~e) &&& (e ^^^ f)) - 3 *  ~~~(d &&& ( ~~~e &&& f)) - 7 * ((d &&& f) ^^^ (e ||| f)) - 2 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 6 * (e ^^^ (d &&& ( ~~~e ||| f))) + 7 * (d ||| e) - 11 *  ~~~(e &&& f) + 4 * ((d ^^^ e) &&& (d ^^^ f)) + 11 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 2 * ((d &&& e) |||  ~~~(e ^^^ f)) + 2 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 2 * ( ~~~e ||| (d ^^^ f)) - 5 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 1 * (f |||  ~~~(d |||  ~~~e)) - 2 *  ~~~(d ||| (e ^^^ f)) + 1 * (f ^^^ (d ||| ( ~~~e &&& f))) + 1 * (d &&&  ~~~e) - 1 * (e ||| (d &&&  ~~~f)) + 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 * (e ||| (d &&& f)) + 2 * (e ||| f) + 1 * (e ^^^ (d ||| f)) - 5 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 11 * ( ~~~d ||| (e ^^^ f)) + 1 *  ~~~(d |||  ~~~f) - 1 * (d ^^^ (e ||| f)) - 5 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 5 * (f &&& (d ^^^ e)) + 1 * (e &&& (d ||| f)) + 11 * ( ~~~f ||| (d ^^^ e)) + 4 * ( ~~~d ||| ( ~~~e &&& f)) + 3 * (d ^^^ e) - 3 * (f ^^^ (d ||| ( ~~~e ||| f))) - 1 * (e ^^^ (d ||| (e ^^^ f))) - 1 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 11 * (e ^^^  ~~~(d |||  ~~~f)) - 6 * (f |||  ~~~(d ||| e)) - 1 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 11 * (e &&&  ~~~(d &&&  ~~~f)) - 3 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 2 *  ~~~( ~~~d ||| (e ^^^ f)) + 11 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 1 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) - 1 * (e ^^^ ( ~~~d ||| (e ^^^ f))) + 1 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 *  ~~~( ~~~d ||| (e &&& f)) + 5 * (e ^^^ (d &&&  ~~~f)) + 1 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 2 *  ~~~d + 30 *  ~~~(d ||| (e ||| f)) + 19 *  ~~~(d ||| ( ~~~e ||| f)) + 17 *  ~~~( ~~~d ||| (e ||| f)) + 3 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 4 * ( ~~~d &&& ( ~~~e &&& f)) + 20 * ( ~~~d &&& (e &&& f)) + 10 * (d &&& ( ~~~e &&& f)) + 5 * (d &&& (e &&& f)) =  - 3 * e

theorem e_16 :
    1 * (x ||| y) + 7 * x - 1 *  ~~~x - 8 * (x &&& y) =  - 1 *  ~~~(x ||| y) + 8 * (x &&&  ~~~y)

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

@[simp] theorem get_ofFn : (ofFn A as f).get i = f i

theorem t0_commutative_thm.extracted_1._8 : ∀ (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 → ¬x_1 ^^^ 1#1 = 1#1 → ¬x_1 = 1#1 → False

theorem ashrsgt_02_13_exact_proof : ashrsgt_02_13_exact_before ⊑ ashrsgt_02_13_exact_after

theorem pr64558_thm (e e_1 : IntW 1) : select (LLVM.and (LLVM.xor e_1 (const? 1 1)) e) e e_1 ⊑ LLVM.or e_1 e

theorem demo2 (x : BitVec 64) : BitVec.zeroExtend 64 (BitVec.truncate 32 x) = x &&& 4294967295#64

theorem two_signed_truncation_checks_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x + 512#32 <ᵤ 1024#32) &&& ofBool (x + 128#32 <ᵤ 256#32) = ofBool (x + 128#32 <ᵤ 256#32)

theorem not_zext_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → 1#999 = zeroExtend 999 (x ^^^ 1#1)

theorem e_1029 :
     - 1 *  ~~~t - 7 * z - 7 *  ~~~(z &&& t) + 8 *  ~~~(z ||| t) + 10 *  ~~~(z |||  ~~~t) + 18 * (z &&&  ~~~t) + 7 * (z &&& t) = 3 * (z ^^^ t)

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

theorem e_2173 :
    2 * (e |||  ~~~f) + 3 * (f &&& (d ^^^ e)) + 1 *  ~~~f - 1 * (f ^^^ (d ||| e)) + 5 *  ~~~( ~~~d ||| (e &&& f)) + 7 * (d ||| (e ||| f)) + 2 * (e ^^^ f) + 1 * ((e &&& f) ||| (d &&& (e ||| f))) + 5 * (e ^^^ (d |||  ~~~f)) + 2 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 7 * ((d ^^^ e) ||| (d ^^^ f)) + 1 * (e ^^^ (d ||| ( ~~~e &&& f))) + 1 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 11 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 3 * (f |||  ~~~(d ||| e)) - 1 * ( ~~~e ||| (d ^^^ f)) + 11 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 11 * ((d &&& e) |||  ~~~(e ^^^ f)) + 2 * (d ||| f) - 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) + 5 * (e |||  ~~~(d ||| f)) - 6 * (e ^^^  ~~~(d &&& (e ||| f))) + 4 *  ~~~(d &&& ( ~~~e &&& f)) + 5 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 6 * (f ^^^  ~~~(d |||  ~~~e)) + 7 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 11 *  ~~~(d |||  ~~~e) + 4 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 5 * (d ^^^ (e ^^^ f)) - 5 * (f ^^^ (d ||| ( ~~~e ||| f))) + 2 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 2 * ( ~~~f ||| (d ^^^ e)) + 1 * (f ^^^  ~~~(d &&& (e ||| f))) - 1 * (e &&&  ~~~(d &&& f)) + 3 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 3 * (f ^^^ (d ||| ( ~~~e &&& f))) - 2 * (e ^^^ ( ~~~d ||| (e &&& f))) - 3 *  ~~~(d &&&  ~~~d) - 6 * (e ^^^ (d &&& f)) - 1 * (f ^^^ ( ~~~d &&& (e ||| f))) - 2 * (f &&&  ~~~(d &&& e)) - 5 * (f &&& (d ||| e)) - 18 *  ~~~(d ||| (e ||| f)) - 7 *  ~~~(d ||| ( ~~~e ||| f)) - 28 *  ~~~( ~~~d ||| (e ||| f)) - 26 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 13 * ( ~~~d &&& ( ~~~e &&& f)) - 34 * (d &&& ( ~~~e &&& f)) + 11 * (d &&& (e &&& f)) =  - 4 * (e ^^^  ~~~(d &&&  ~~~f)) + 11 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f)))

theorem shl_lshr_pow2_not_const_case2_thm (e : IntW 16) :
  LLVM.xor (LLVM.and (lshr (shl (const? 16 16) e) (const? 16 3)) (const? 16 8)) (const? 16 8) ⊑
    select (icmp IntPred.eq e (const? 16 2)) (const? 16 0) (const? 16 8)

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

theorem or_sext_sext_thm.extracted_1._1 : ∀ (x : BitVec 4) (x_1 : BitVec 8),
  signExtend 16 x_1 ||

theorem test3_proof : test3_before ⊑ test3_after

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

theorem ult_swap_and_max_proof : ult_swap_and_max_before ⊑ ult_swap_and_max_after

theorem scalar_i8_signbit_lshr_and_eq_proof : scalar_i8_signbit_lshr_and_eq_before ⊑ scalar_i8_signbit_lshr_and_eq_after

theorem prove_exact_with_high_mask_limit_proof : prove_exact_with_high_mask_limit_before ⊑ prove_exact_with_high_mask_limit_after

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

theorem select_of_symmetric_selects_negative1_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  ¬(x_1 = 1#1 ∨ x_1 = 1#1) → x_1 = 1#1 → False

theorem demorgan_nand_apint2_proof : demorgan_nand_apint2_before ⊑ demorgan_nand_apint2_after

theorem select_constants_and_icmp_ne0_zero_tval_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1),
  ¬x_1 = 1#1 → x = 1#1 → ofBool (12#8 &&& 0#8 != 0#8) = x ^^^ 1#1

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

theorem dec_mask_neg_i32_proof : dec_mask_neg_i32_before ⊑ dec_mask_neg_i32_after

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

theorem icmp_select_implied_cond_swapped_select_proof : icmp_select_implied_cond_swapped_select_before ⊑ icmp_select_implied_cond_swapped_select_after

theorem OrZextOr_thm.extracted_1._1 : ∀ (x : BitVec 3), zeroExtend 5 (x ||| 3#3) ||

theorem e_1378 :
     - 3 * (z ^^^ t) + 11 *  ~~~(z ^^^ t) + 11 * t - 7 *  ~~~(z &&& t) - 6 *  ~~~(z &&&  ~~~z) - 1 *  ~~~t + 5 * (z |||  ~~~t) - 7 *  ~~~(z ||| t) + 12 * (z &&&  ~~~t) - 19 * (z &&& t) = 2 *  ~~~(z &&&  ~~~t) - 7 *  ~~~z

theorem bitwise_or_logical_or_icmps_comm1_proof : bitwise_or_logical_or_icmps_comm1_before ⊑ bitwise_or_logical_or_icmps_comm1_after

theorem lshr_mul_times_3_div_2_proof : lshr_mul_times_3_div_2_before ⊑ lshr_mul_times_3_div_2_after

theorem sge_swap_or_not_max_commute_proof : sge_swap_or_not_max_commute_before ⊑ sge_swap_or_not_max_commute_after

theorem test4_proof : test4_before ⊑ test4_after

theorem and_not_or_commute4_proof : and_not_or_commute4_before ⊑ and_not_or_commute4_after

theorem orcond.100.inv.inner.cond.in.outer.cond_proof : orcond.100.inv.inner.cond.in.outer.cond_before ⊑ orcond.100.inv.inner.cond.in.outer.cond_after

@[simp]
lemma product_eval {M : NFA α σ} {N : NFA α ς} {w} :
  (M.product accept? N).eval w = M.eval w ×ˢ N.eval w

theorem lshr_add_and_shl_proof : lshr_add_and_shl_before ⊑ lshr_add_and_shl_after

private theorem sge_of_sgt (A B : BitVec w) : (A >ₛ B) → (A ≥ₛ B)

theorem trunc_shl_16_i32_i64_proof : trunc_shl_16_i32_i64_before ⊑ trunc_shl_16_i32_i64_after

theorem neg_nsw_sgt_0_proof : neg_nsw_sgt_0_before ⊑ neg_nsw_sgt_0_after

theorem slt_swap_or_not_max_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 != 127#8) ||

theorem mul_mask_fakepow2_ne0_proof : mul_mask_fakepow2_ne0_before ⊑ mul_mask_fakepow2_ne0_after

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

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

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 lshrugt_02_10_proof : lshrugt_02_10_before ⊑ lshrugt_02_10_after

theorem substitute_constant_and_eq_eq_proof : substitute_constant_and_eq_eq_before ⊑ substitute_constant_and_eq_eq_after

theorem ofBitVecZext_add_EqualUpTo :
    ofBitVecZext (x + y) ≈ʷ (ofBitVecZext x) + (ofBitVecZext y)

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

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

theorem or_xor_tree_0011_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 (const? 32 42)) (mul e_2 (const? 32 42))) (mul e_1 (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 max_sub_ult_c12_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x <ᵤ 1#32) = 1#1 → ofBool (x == 0#32) = 1#1 → 0#32 = BitVec.ofInt 32 (-2)

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

theorem main11_thm (e : IntW 32) :
  select
      (LLVM.or (icmp IntPred.eq (LLVM.and e (const? 32 64)) (const? 32 0))
        (icmp IntPred.sge (trunc 8 e) (const? 8 0)))
      (const? 32 2) (const? 32 1) ⊑
    select (icmp IntPred.eq (LLVM.and e (const? 32 192)) (const? 32 192)) (const? 32 1) (const? 32 2)

theorem and_or1_proof : and_or1_before ⊑ and_or1_after

theorem test_lshr__exact_is_unsafe_proof : test_lshr__exact_is_unsafe_before ⊑ test_lshr__exact_is_unsafe_after

theorem sge_or_not_max_logical_proof : sge_or_not_max_logical_before ⊑ sge_or_not_max_logical_after

theorem PR42691_6_proof : PR42691_6_before ⊑ PR42691_6_after

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

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

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

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

theorem alive_229  (w : Nat)   : alive_229_src w  ⊑ alive_229_tgt w

theorem n2_badmask_proof : n2_badmask_before ⊑ n2_badmask_after

theorem test_logical_or_eq_a_b_proof : test_logical_or_eq_a_b_before ⊑ test_logical_or_eq_a_b_after

theorem or_trunc_lshr_proof : or_trunc_lshr_before ⊑ or_trunc_lshr_after

theorem xor_signbit_lshr_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬8#32 ≥ ↑32 → (x ^^^ BitVec.ofInt 32 (-65536)) >>> 8#32 = x >>> 8#32 ^^^ 16776960#32

theorem or_or_and_pat7_proof : or_or_and_pat7_before ⊑ or_or_and_pat7_after

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 n6_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 1#32 != 0#32) = 1#1 → ¬2#32 ≥ ↑32 → ofBool (x &&& 1#32 == 0#32) = 1#1 → x >>> 2#32 &&& 1#32 = 1#32

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

theorem xor_logic_and_logic_or4_proof : xor_logic_and_logic_or4_before ⊑ xor_logic_and_logic_or4_after

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

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

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

theorem e_1519 :
    2 * ((a ^^^ b) ||| (a ^^^ c)) - 6 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) - 2 *  ~~~(a ||| (b ||| c)) - 4 *  ~~~(a ||| ( ~~~b ||| c)) + 4 *  ~~~( ~~~a ||| (b ||| c)) + 3 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 2 * ( ~~~a &&& ( ~~~b &&& c)) - 2 * ( ~~~a &&& (b &&& c)) + 2 * (a &&& ( ~~~b &&& c)) - 2 * (a &&& (b &&& c)) =  - 1 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) - 1 * (c ^^^  ~~~(a ||| ( ~~~b &&& c)))

theorem signbit_splat_mask_thm.extracted_1._2 : ∀ (x : BitVec 16) (x_1 : BitVec 8),
  ¬7#8 ≥ ↑8 → ¬ofBool (x_1 <ₛ 0#8) = 1#1 → signExtend 16 (x_1.sshiftRight' 7#8) &&& x = 0#16

theorem test_mul_nsw__none_are_safe_proof : test_mul_nsw__none_are_safe_before ⊑ test_mul_nsw__none_are_safe_after

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

theorem src_srem_shl_demand_min_signbit_mask_hit_last_demand_proof : src_srem_shl_demand_min_signbit_mask_hit_last_demand_before ⊑ src_srem_shl_demand_min_signbit_mask_hit_last_demand_after

theorem test_cast_select_proof : test_cast_select_before ⊑ test_cast_select_after

theorem multiuse2_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ ((x &&& 96#32) <<< 8#32).sshiftRight' 8#32 ≠ x &&& 96#32 ∨
        True ∧ (x &&& 96#32) <<< 8#32 >>> 8#32 ≠ x &&& 96#32 ∨
          8#32 ≥ ↑32 ∨
            True ∧ ((x &&& 6#32) <<< 8#32).sshiftRight' 8#32 ≠ x &&& 6#32 ∨
              True ∧ (x &&& 6#32) <<< 8#32 >>> 8#32 ≠ x &&& 6#32 ∨
                8#32 ≥ ↑32 ∨
                  True ∧ ((x &&& 24#32) <<< 8#32).sshiftRight' 8#32 ≠ x &&& 24#32 ∨
                    True ∧ (x &&& 24#32) <<< 8#32 >>> 8#32 ≠ x &&& 24#32 ∨
                      8#32 ≥ ↑32 ∨
                        True ∧ ((x &&& 6#32) <<< 1#32).sshiftRight' 1#32 ≠ x &&& 6#32 ∨
                          True ∧ (x &&& 6#32) <<< 1#32 >>> 1#32 ≠ x &&& 6#32 ∨
                            1#32 ≥ ↑32 ∨
                              True ∧ ((x &&& 96#32) <<< 1#32).sshiftRight' 1#32 ≠ x &&& 96#32 ∨
                                True ∧ (x &&& 96#32) <<< 1#32 >>> 1#32 ≠ x &&& 96#32 ∨
                                  1#32 ≥ ↑32 ∨
                                    True ∧ ((x &&& 24#32) <<< 1#32).sshiftRight' 1#32 ≠ x &&& 24#32 ∨
                                      True ∧ (x &&& 24#32) <<< 1#32 >>> 1#32 ≠ x &&& 24#32 ∨ 1#32 ≥ ↑32) →
    ¬(8#32 ≥ ↑32 ∨
          1#32 ≥ ↑32 ∨
            1#32 ≥ ↑32 ∨
              1#32 ≥ ↑32 ∨
                True ∧ (x <<< 1#32 &&& 192#32 &&& (x <<< 1#32 &&& 48#32) != 0) = true ∨
                  True ∧ (x <<< 1#32 &&& 12#32 &&& (x <<< 1#32 &&& 192#32 ||| x <<< 1#32 &&& 48#32) != 0) = true ∨
                    True ∧
                      (x <<< 8#32 &&& 32256#32 &&&
                            (x <<< 1#32 &&& 12#32 ||| (x <<< 1#32 &&& 192#32 ||| x <<< 1#32 &&& 48#32)) !=
                          0) =
                        true) →
      (x &&& 96#32) <<< 8#32 ||

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

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

theorem ashrslt_03_15_exact_proof : ashrslt_03_15_exact_before ⊑ ashrslt_03_15_exact_after

theorem e_792 :
    4 *  ~~~(z &&&  ~~~z) + 11 *  ~~~t - 15 *  ~~~(z ||| t) - 11 * (z &&&  ~~~t) - 2 * (z &&& t) = 2 * (z ||| t) + 2 * (z ^^^ t)

@[bv_multi_width_normalize]
theorem sle_iff_slt_eq_false {a b : BitVec w} : a.slt b = false ↔ b.sle a

theorem test3_logical_thm (e e_1 : IntW 32) :
  select (icmp IntPred.eq (sub e_1 e { «nsw» := true, «nuw» := false }) (const? 32 0)) (const? 1 1)
      (icmp IntPred.eq (sub e_1 e { «nsw» := true, «nuw» := false }) (const? 32 31)) ⊑
    select (icmp IntPred.eq e_1 e) (const? 1 1)
      (icmp IntPred.eq (sub e_1 e { «nsw» := true, «nuw» := false }) (const? 32 31))

theorem e_2354 :
    1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 2 *  ~~~(d ^^^ (e ^^^ f)) - 3 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 1 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 2 * (e ||| (d ^^^ f)) + 11 * (e &&&  ~~~(d ^^^ f)) - 7 * (f ^^^  ~~~(d ||| (e &&& f))) + 11 * ((d &&& f) ||| (e &&&  ~~~f)) + 1 * (f ^^^ (d &&& ( ~~~e ||| f))) + 2 * ((d &&& e) |||  ~~~(e ^^^ f)) + 2 * (e &&&  ~~~(d &&&  ~~~f)) - 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 1 * (f ^^^  ~~~(d |||  ~~~e)) - 1 * d + 7 * (f ^^^ (d &&& (e ||| f))) + 1 * (e ^^^  ~~~(d &&& (e ||| f))) - 1 * (e ^^^ (d ||| (e ^^^ f))) - 1 * ( ~~~d ||| (e ^^^ f)) + 7 * ( ~~~d ||| ( ~~~e ||| f)) - 7 * (f |||  ~~~(d |||  ~~~e)) + 5 *  ~~~(d &&&  ~~~f) + 2 * (e &&&  ~~~(d &&& f)) + 5 * (d ^^^ e) - 3 * (e ||| (d &&&  ~~~f)) - 1 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 5 * (f ^^^ ( ~~~d &&& (e ||| f))) - 5 * (d ^^^ ( ~~~e &&& f)) + 7 * (d |||  ~~~f) + 1 * ( ~~~e &&& (d ^^^ f)) - 1 * (f ||| (d &&& e)) - 11 * (e |||  ~~~f) - 11 * (e ^^^ (d ||| ( ~~~e &&& f))) - 1 * (d &&& ( ~~~e ||| f)) - 2 *  ~~~(d &&&  ~~~d) - 1 * ( ~~~f &&& (d ^^^ e)) - 5 * (f ^^^ (d ||| (e &&& f))) - 2 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 2 * (d ||| (e ^^^ f)) - 3 * (d ^^^ (e &&& f)) + 5 * (f ^^^ ( ~~~d ||| (e ||| f))) + 7 *  ~~~(e |||  ~~~f) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 5 * ((d &&& e) ^^^ (e |||  ~~~f)) + 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 11 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 3 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 2 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 *  ~~~(d ^^^ e) - 1 * (e ^^^ (d ||| f)) - 2 * ( ~~~d ||| (e ||| f)) - 6 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 1 * (e ^^^ ( ~~~d ||| (e ^^^ f))) + 5 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 2 * (e ^^^ ( ~~~d ||| (e ||| f))) - 1 * ((d ||| e) &&& (e ^^^ f)) + 11 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 1 *  ~~~(e &&&  ~~~f) - 6 * (e ^^^ ( ~~~d &&& (e ||| f))) + 7 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 3 *  ~~~f + 1 * (f ||| (d &&&  ~~~e)) - 17 *  ~~~(d ||| (e ||| f)) - 7 *  ~~~(d ||| ( ~~~e ||| f)) + 5 *  ~~~( ~~~d ||| (e ||| f)) - 19 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 5 * ( ~~~d &&& ( ~~~e &&& f)) - 6 * (d &&& ( ~~~e &&& f)) - 22 * (d &&& (e &&& f)) =  - 23 * ( ~~~d &&& (e &&& f)) - 2 * (f ^^^ (d ||| ( ~~~e ||| f)))

theorem test16_thm (e : IntW 8) : LLVM.and (shl e (const? 8 2)) (const? 8 3) ⊑ const? 8 0

theorem test9_proof : test9_before ⊑ test9_after

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

theorem icmp_slt_0_and_icmp_sge_neg1_i64_fail_proof : icmp_slt_0_and_icmp_sge_neg1_i64_fail_before ⊑ icmp_slt_0_and_icmp_sge_neg1_i64_fail_after

theorem ashr_ult_2_proof : ashr_ult_2_before ⊑ ashr_ult_2_after

theorem smear_set_bit_thm (e : IntW 32) :
  sext 32 (ashr (trunc 8 e) (const? 8 7)) ⊑ ashr (shl e (const? 32 24)) (const? 32 31)

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

@[grind =, simp, aesop 50% unsafe]
lemma newState_finals (m : RawCNFA A) :
    m.newState.2.finals = m.finals

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

theorem t0_proof : t0_before ⊑ t0_after

theorem PR2539_A_thm (e : IntW 1) : icmp IntPred.slt (zext 32 e) (const? 32 1) ⊑ LLVM.xor e (const? 1 1)

@[symm]
theorem equal_up_to_symm (e : a ≈ʷ b) : b ≈ʷ a

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

theorem alive_AndOrXor_2627 : alive_AndOrXor_2627_src ⊑ alive_AndOrXor_2627_tgt

theorem fold_sext_to_and_wrong2_proof : fold_sext_to_and_wrong2_before ⊑ fold_sext_to_and_wrong2_after

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

theorem eq_10_proof : eq_10_before ⊑ eq_10_after

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

theorem ofDep_xvar_eq_xvar' : MultiWidth.Nondep.Term.ofDepTerm xvar = xvar'

theorem positive_biggerlshr_shlnsw_lshrexact_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(True ∧ x >>> 6#8 <<< 6#8 ≠ x ∨ 6#8 ≥ ↑8 ∨ True ∧ (x >>> 6#8 <<< 3#8).sshiftRight' 3#8 ≠ x >>> 6#8 ∨ 3#8 ≥ ↑8) →
    ¬(True ∧ x >>> 3#8 <<< 3#8 ≠ x ∨ 3#8 ≥ ↑8) → x >>> 6#8 <<< 3#8 = x >>> 3#8

theorem exactly_one_set_signbit_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬7#8 ≥ ↑8 → ofBool (x_1 >>> 7#8 == zeroExtend 8 (ofBool (-1#8 <ₛ x))) = ofBool (x_1 ^^^ x <ₛ 0#8)

theorem test16_thm.extracted_1._1 : ∀ (x : BitVec 51),
  ¬(1123#51 == 0 || 51 != 1 && x == intMin 51 && 1123#51 == -1) = true →
    (BitVec.ofInt 51 (-1123) == 0 || 51 != 1 && x == intMin 51 && BitVec.ofInt 51 (-1123) == -1) = true → False

theorem lshrult_01_06_exact_proof : lshrult_01_06_exact_before ⊑ lshrult_01_06_exact_after

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

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

theorem fold_icmp_shl_nuw_c2_precondition3_thm (e : IntW 32) :
  icmp IntPred.ult (shl (const? 32 1) e { «nsw» := false, «nuw» := true }) (const? 32 1) ⊑ const? 1 0

theorem icmp_power2_and_icmp_shifted_mask_swapped_2147483648_1610612736_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 1610612736#32 != 1610612736#32) &&& ofBool (x <ᵤ BitVec.ofInt 32 (-2147483648)) =
    ofBool (x <ᵤ 1610612736#32)

theorem ule_umax4_proof : ule_umax4_before ⊑ ule_umax4_after

theorem ashrsgt_02_08_exact_proof : ashrsgt_02_08_exact_before ⊑ ashrsgt_02_08_exact_after

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

theorem and_two_ranges_to_mask_and_range_no_add_on_one_range_proof : and_two_ranges_to_mask_and_range_no_add_on_one_range_before ⊑ and_two_ranges_to_mask_and_range_no_add_on_one_range_after

theorem test5_proof : test5_before ⊑ test5_after

theorem sub_2_proof : sub_2_before ⊑ sub_2_after

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

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

theorem t3_exact_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ x >>> 63#64 <<< 63#64 ≠ x ∨ 63#64 ≥ ↑64) → 0#64 - x.sshiftRight' 63#64 = x >>> 63#64

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

theorem sgt_zero_eq_not_neg_sgt_zero (A : BitVec w) (h_ne_intMin : A ≠ intMin w)
    (h_ne_zero : A ≠ 0) : (A >ₛ 0#w) ↔ ¬ ((-A) >ₛ 0#w)

theorem alive_Select_962 : forall (w : Nat) (y c z : Bitvec 1)
(x : Bitvec w)
, TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec w)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (x) %v0;
  %v2 := op:const (y) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:add w %v3;
  %v5 := op:const (z) %v0;
  %v6 := pair:%v1 %v5;
  %v7 := op:add w %v6;
  %v8 := op:const (c) %v0;
  %v9 := triple:%v8 %v4 %v7;
  %v10 := op:select w %v9
  dsl_ret %v10
  ]  ⊑
  TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec w)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (c) %v0;
  %v2 := op:const (y) %v0;
  %v3 := op:const (z) %v0;
  %v4 := triple:%v1 %v2 %v3;
  %v5 := op:select w %v4;
  %v6 := op:const (x) %v0;
  %v7 := pair:%v6 %v2;
  %v8 := op:add w %v7;
  %v9 := pair:%v6 %v3;
  %v10 := op:add w %v9;
  %v11 := pair:%v6 %v5;
  %v12 := op:add w %v11
  dsl_ret %v12
  ]

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

theorem uge_umin2_proof : uge_umin2_before ⊑ uge_umin2_after

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

theorem hoist_ashr_ahead_of_sext_1_proof : hoist_ashr_ahead_of_sext_1_before ⊑ hoist_ashr_ahead_of_sext_1_after

@[simp] theorem getElem_map (xs : HVector A as) (v : Var ⟨as⟩ a) :
    (xs.map f)[v] = f _ xs[v]

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

theorem test15_proof : test15_before ⊑ test15_after

theorem test9_proof : test9_before ⊑ test9_after

theorem trunc_equality_nsw_zext_proof : trunc_equality_nsw_zext_before ⊑ trunc_equality_nsw_zext_after

theorem lshrugt_02_05_thm (e : IntW 4) : icmp IntPred.ugt (lshr e (const? 4 2)) (const? 4 5) ⊑ const? 1 0

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

theorem trunc_ashr_trunc_outofrange_proof : trunc_ashr_trunc_outofrange_before ⊑ trunc_ashr_trunc_outofrange_after

theorem logical_and_logical_and_icmps_comm3_proof : logical_and_logical_and_icmps_comm3_before ⊑ logical_and_logical_and_icmps_comm3_after

theorem icmp_eq_and_pow2_lshr_pow2_case2_proof : icmp_eq_and_pow2_lshr_pow2_case2_before ⊑ icmp_eq_and_pow2_lshr_pow2_case2_after

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

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

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

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

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

theorem not_mul_of_bool_commute_thm (e e_1 : IntW 32) :
  icmp IntPred.ugt (mul (LLVM.and e_1 (const? 32 255)) (lshr e (const? 32 30))) (const? 32 255) ⊑
    icmp IntPred.ugt (mul (LLVM.and e_1 (const? 32 255)) (lshr e (const? 32 30)) { «nsw» := true, «nuw» := true })
      (const? 32 255)

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

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

@[simp]
lemma BitVec.cons_sgt_iff {w} {bv1 bv2 : BitVec w} :
    ((BitVec.cons b2 bv2).slt (BitVec.cons b1 bv1)) ↔
      (if b1 = b2 then bv2.ult bv1 else b2)

theorem lshr_exact_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(2#8 ≥ ↑8 ∨ 2#8 ≥ ↑8) → (x <<< 2#8 + 4#8) >>> 2#8 = x + 1#8 &&& 63#8

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

theorem test10_proof : test10_before ⊑ test10_after

theorem lshr_sext_i1_to_i128_thm (e : IntW 1) :
  lshr (sext 128 e) (const? 128 42) ⊑ select e (const? 128 77371252455336267181195263) (const? 128 0)

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

theorem test8_thm (e : IntW 32) :
  mul (sext 64 (ashr e (const? 32 16))) (const? 64 32767) ⊑
    sext 64 (mul (ashr e (const? 32 16)) (const? 32 32767) { «nsw» := true, «nuw» := false })

theorem not_or_or_and_not_and_and_commute1_proof : not_or_or_and_not_and_and_commute1_before ⊑ not_or_or_and_not_and_and_commute1_after

theorem test_invert_demorgan_or2_proof : test_invert_demorgan_or2_before ⊑ test_invert_demorgan_or2_after

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

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

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

theorem t11_no_shift_proof : t11_no_shift_before ⊑ t11_no_shift_after

theorem ugt_swap_or_not_min_commute_logical_thm.extracted_1._3 : ∀ (x x_1 : BitVec 823),
  ¬ofBool (x_1 != 0#823) = 1#1 → ofBool (x <ᵤ x_1) = ofBool (x_1 != 0#823)

theorem not_cmp_constant_thm (e : IntW 32) :
  icmp IntPred.ugt (LLVM.xor e (const? 32 (-1))) (const? 32 42) ⊑
    icmp IntPred.ult e (const? 32 (-43))

theorem shl_trunc_smaller_ashr_proof : shl_trunc_smaller_ashr_before ⊑ shl_trunc_smaller_ashr_after

theorem test11_proof : test11_before ⊑ test11_after

theorem test12_proof : test12_before ⊑ test12_after

theorem sgt_smin1_proof : sgt_smin1_before ⊑ sgt_smin1_after

theorem test_mul_nsw__nsw_is_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x ||| BitVec.ofInt 32 (-83886080) == BitVec.ofInt 32 (-83886079)) = 1#1 →
    ¬(True ∧ (x ||| BitVec.ofInt 32 (-83886080)).smulOverflow 9#32 = true) →
      BitVec.ofInt 32 (-754974711) = (x ||| BitVec.ofInt 32 (-83886080)) * 9#32

theorem select_icmp_ne_0_and_4096_and_not_32_proof : select_icmp_ne_0_and_4096_and_not_32_before ⊑ select_icmp_ne_0_and_4096_and_not_32_after

theorem t20_thm (e : IntW 16) (e_1 : IntW 8) :
  sub e_1 (trunc 8 (shl (const? 16 (-42)) e)) ⊑ add e_1 (trunc 8 (shl (const? 16 42) e))

theorem select_lshr_icmp_const_reordered_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x <ᵤ 32#32) = 1#1 → ¬5#32 ≥ ↑32 → 0#32 = x >>> 5#32

theorem n11_uge_slt_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.ult e_2 (const? 32 129)) (select (icmp IntPred.slt e_2 (const? 32 0)) e_1 e) e_2 ⊑
    select (icmp IntPred.ult e_2 (const? 32 129)) e e_2

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

theorem lshrult_01_07_proof : lshrult_01_07_before ⊑ lshrult_01_07_after

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

theorem add_select_sext_thm (e : IntW 1) :
  add (select e (const? 64 64) (const? 64 1)) (sext 64 e) ⊑ select e (const? 64 63) (const? 64 1)

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

theorem positive_with_icmp_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x <ᵤ 512#32) = 1#1 → ofBool (x + 128#32 <ᵤ 256#32) = ofBool (x <ᵤ 128#32)

@[simp]
theorem Factor.denote_width_zero  (f : Factor) (env : Env 0) : f.denote env = 0

theorem e_2393 :
     - 2 * (e &&&  ~~~f) + 11 *  ~~~f - 6 * (d ^^^ (e &&& f)) - 6 * ((d &&& e) ^^^ (e |||  ~~~f)) + 3 * (d ^^^ (e ^^^ f)) + 2 * (f ^^^  ~~~(d |||  ~~~e)) + 5 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 3 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 4 * (e ^^^ (d |||  ~~~f)) - 2 * (d ^^^ e) - 1 * (f ^^^  ~~~(d ||| (e &&& f))) - 1 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 2 * (e ^^^ (d ||| (e ^^^ f))) - 2 * ( ~~~e |||  ~~~(d ^^^ f)) - 7 * (f ^^^  ~~~(d &&&  ~~~e)) - 2 *  ~~~(d &&& (e ||| f)) + 11 * (e ||| f) + 1 *  ~~~(e ||| f) - 5 *  ~~~(d ||| ( ~~~e &&& f)) + 7 * (d ^^^ ( ~~~e ||| f)) - 2 *  ~~~(d |||  ~~~e) + 11 *  ~~~(d &&&  ~~~e) + 2 * (e ||| (d ^^^ f)) - 3 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * ((d &&& f) ||| (e &&&  ~~~f)) + 7 * (d ||| (e ||| f)) + 2 * (e &&& (d |||  ~~~f)) - 11 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) - 1 * (e |||  ~~~f) - 6 * (e ^^^ (d &&& f)) - 2 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 4 * (d ||| ( ~~~e ||| f)) + 1 * (d &&& e) + 5 * ( ~~~f ||| (d ^^^ e)) - 1 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 1 * ( ~~~f &&&  ~~~(d ^^^ e)) + 1 * (e &&&  ~~~(d &&& f)) - 7 *  ~~~e + 11 * ((d |||  ~~~e) &&& (e ^^^ f)) - 6 * ( ~~~f |||  ~~~(d ^^^ e)) + 4 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 1 * ( ~~~e &&& (d ^^^ f)) + 5 * (f &&&  ~~~(d &&&  ~~~e)) + 5 * d + 5 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 2 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) + 3 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 3 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) + 11 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 1 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 2 * (e ^^^ ( ~~~d &&& (e ||| f))) - 3 * (f &&& (d |||  ~~~e)) + 3 * (e ^^^ (d ||| ( ~~~e ||| f))) - 11 * ((d &&& e) |||  ~~~(e ||| f)) + 1 * ( ~~~e ||| (d ^^^ f)) + 2 *  ~~~(e |||  ~~~f) - 11 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 7 *  ~~~(d |||  ~~~f) - 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 3 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 1 * (f |||  ~~~(d |||  ~~~e)) + 2 * ( ~~~e &&&  ~~~(d ^^^ f)) - 7 * ( ~~~d ||| ( ~~~e &&& f)) - 1 *  ~~~(d ||| (e ||| f)) - 9 *  ~~~(d ||| ( ~~~e ||| f)) - 4 *  ~~~( ~~~d ||| (e ||| f)) - 22 * ( ~~~d &&& ( ~~~e &&& f)) - 26 * ( ~~~d &&& (e &&& f)) - 22 * (d &&& ( ~~~e &&& f)) - 44 * (d &&& (e &&& f)) = 56 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 3 * (f ^^^ (d ||| e))

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

@[simp]
theorem Std.HashSet.isEmpty_union_iff_isEmpty [BEq α] [Hashable α] [LawfulBEq α] {m₁ m₂ : HashSet α} :
    (m₁.union m₂).isEmpty ↔ m₁.isEmpty ∧ m₂.isEmpty

theorem test_sub__nuw_is_safe_proof : test_sub__nuw_is_safe_before ⊑ test_sub__nuw_is_safe_after

theorem nonexact_lshr_eq_exactdiv_proof : nonexact_lshr_eq_exactdiv_before ⊑ nonexact_lshr_eq_exactdiv_after

theorem le_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 <ₛ x) = 1#1 → ¬ofBool (x <ₛ x_1) = 1#1 → ofBool (0#32 ≤ₛ 0#32) = ofBool (x_1 ≤ₛ x)

theorem negate_add_with_single_negatible_operand_depth2_thm (e e_1 : IntW 8) :
  sub (const? 8 0) (mul (add e_1 (const? 8 21)) e) ⊑ mul (sub (const? 8 (-21)) e_1) e

theorem test6_proof : test6_before ⊑ test6_after

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

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

theorem appendInl_toCons {v : Var Γ t} :
    v.toCons (t':=t').appendInl (Δ := Δ) = v.appendInl.toCons

theorem shl_add_add_fail_thm (e e_1 : IntW 8) :
  add (lshr e_1 (const? 8 2)) (add (lshr e (const? 8 2)) (const? 8 48)) ⊑
    add (lshr e_1 (const? 8 2)) (add (lshr e (const? 8 2)) (const? 8 48) { «nsw» := true, «nuw» := true })
      { «nsw» := false, «nuw» := true }

theorem uadd_sat_canon_nuw_thm (e e_1 : IntW 32) :
  select (icmp IntPred.ult (add e_1 e { «nsw» := false, «nuw» := true }) e_1) (const? 32 (-1))
      (add e_1 e { «nsw» := false, «nuw» := true }) ⊑
    add e_1 e { «nsw» := false, «nuw» := true }

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

theorem positive_and_odd_ne_proof : positive_and_odd_ne_before ⊑ positive_and_odd_ne_after

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

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

theorem negative5_proof : negative5_before ⊑ negative5_after

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

theorem main6d_logical_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 != 3#32) = 1#1 →
    ofBool (x &&& 16#32 == 0#32) = 1#1 → 0#32 = zeroExtend 32 (ofBool (x &&& 23#32 == 19#32))

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

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

theorem lshrult_02_13_exact_proof : lshrult_02_13_exact_before ⊑ lshrult_02_13_exact_after

theorem lshrult_01_11_exact_proof : lshrult_01_11_exact_before ⊑ lshrult_01_11_exact_after

theorem xor_or_proof : xor_or_before ⊑ xor_or_after

theorem shl_nuw_add_nuw_thm (e : IntW 32) :
  shl (const? 32 1) (add e (const? 32 1) { «nsw» := false, «nuw» := true }) { «nsw» := false, «nuw» := true } ⊑
    shl (const? 32 2) e { «nsw» := false, «nuw» := true }

theorem not_invert_signbit_splat_mask2_thm (e : IntW 16) (e_1 : IntW 8) :
  LLVM.and (sext 16 (LLVM.xor (ashr e_1 (const? 8 6)) (const? 8 (-1)))) e ⊑
    LLVM.and e (sext 16 (LLVM.xor (ashr e_1 (const? 8 6)) (const? 8 (-1))))

theorem eval_sext_multi_use_in_one_inst_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ (truncate 16 x &&& 14#16).smulOverflow (truncate 16 x &&& 14#16) = true ∨
        True ∧ (truncate 16 x &&& 14#16).umulOverflow (truncate 16 x &&& 14#16) = true) →
    True ∧ (truncate 16 x &&& 14#16).smulOverflow (truncate 16 x &&& 14#16) = true ∨
        True ∧ (truncate 16 x &&& 14#16).umulOverflow (truncate 16 x &&& 14#16) = true ∨
          True ∧ ((truncate 16 x &&& 14#16) * (truncate 16 x &&& 14#16) &&& BitVec.ofInt 16 (-32768) != 0) = true →
      False

theorem lshrult_03_11_exact_proof : lshrult_03_11_exact_before ⊑ lshrult_03_11_exact_after

theorem ule_swap_or_not_min_commute_logical_proof : ule_swap_or_not_min_commute_logical_before ⊑ ule_swap_or_not_min_commute_logical_after

theorem test5_proof : test5_before ⊑ test5_after

theorem and_xor_or5_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 = 0) → 42#64 / x_2 ||

theorem icmp_select_implied_cond_proof : icmp_select_implied_cond_before ⊑ icmp_select_implied_cond_after

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

@[simp] theorem liftEffect_impure [Pure m] {e} (hle : e ≤ impure) :
    liftEffect hle (α := α) (m := m) = match e with

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_1_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.eq (LLVM.and e (const? 32 7)) (const? 32 1))
      (icmp IntPred.ne (LLVM.and e (const? 32 12)) (const? 32 0)) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 15)) (const? 32 9)

theorem e_1549 :
     - 1 * ((a &&& c) ||| (b &&&  ~~~c)) + 1 * (b ^^^  ~~~(a &&& (b ||| c))) + 1 * ((a &&& c) |||  ~~~(b ||| c)) + 3 * ((a ||| b) &&&  ~~~(b ^^^ c)) + 5 * (c ||| (a &&&  ~~~b)) + 11 * (c ^^^ ( ~~~a ||| (b ||| c))) - 10 *  ~~~(a ||| ( ~~~b ||| c)) - 10 *  ~~~( ~~~a ||| (b ||| c)) - 11 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 6 * ( ~~~a &&& ( ~~~b &&& c)) - 8 * ( ~~~a &&& (b &&& c)) - 5 * (a &&& ( ~~~b &&& c)) - 9 * (a &&& (b &&& c)) = 13 *  ~~~(a ||| (b ||| c))

theorem test15f_thm (e : IntW 32) :
  select (icmp IntPred.ne (LLVM.and e (const? 32 128)) (const? 32 0)) (const? 32 0) (const? 32 256) ⊑
    LLVM.xor (LLVM.and (shl e (const? 32 1)) (const? 32 256)) (const? 32 256)

theorem add_right_shift (hq : q >= t) (hs : s >= p + (2 ^ u - 1)) (hv_s : v > s) (hv_t : v > t) :
  (bw r (addMax (bw p a) (bw q (shrMax (bw t b) (bw u c)))))  =
  (bw r (shrMax (bw v (addMax (bw s (shlMax (bw p a) (bw u c))) (bw t b))) (bw u c)))

theorem or_and3_thm.extracted_1._6 : ∀ (x : BitVec 1) (x_1 x_2 : BitVec 32) (x_3 : BitVec 1),
  x_3 ||

theorem src_srem_shl_demand_max_signbit_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬((2#32 == 0 || 32 != 1 && x == intMin 32 && 2#32 == -1) = true ∨ 30#32 ≥ ↑32) →
    ¬(2#32 == 0 || 32 != 1 && x == intMin 32 && 2#32 == -1) = true →
      x.srem 2#32 <<< 30#32 &&& BitVec.ofInt 32 (-2147483648) = x.srem 2#32 &&& BitVec.ofInt 32 (-2147483648)

theorem zext_add_scalar_proof : zext_add_scalar_before ⊑ zext_add_scalar_after

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

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

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 shl_lshr_demand6_proof : shl_lshr_demand6_before ⊑ shl_lshr_demand6_after

theorem udiv_i80_thm (e : IntW 80) :
  LLVM.udiv (lshr e (const? 80 2)) (const? 80 100) ⊑ LLVM.udiv e (const? 80 400)

theorem shl_trunc_smaller_ashr_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(10#32 ≥ ↑32 ∨ 13#24 ≥ ↑24) →
    ¬3#24 ≥ ↑24 → truncate 24 (x.sshiftRight' 10#32) <<< 13#24 = truncate 24 x <<< 3#24 &&& BitVec.ofInt 24 (-8192)

@[simp] theorem map_append (f : Ty₁ → Ty₂) (Γ Δ : Ctxt Ty₁) :
    (Γ ++ Δ).map f = Γ.map f ++ Δ.map f

theorem alive_Select_858 : forall (w : Nat) (a b : Bitvec 1)
, TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 1)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (a) %v0;
  %v2 := op:const (-1) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:xor w %v3;
  %v5 := op:const (b) %v0;
  %v6 := triple:%v1 %v4 %v5;
  %v7 := op:select w %v6
  dsl_ret %v7
  ]  ⊑
  TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 1)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (a) %v0;
  %v2 := op:const (-1) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:xor 1 %v3;
  %v5 := op:const (b) %v0;
  %v6 := pair:%v4 %v5;
  %v7 := op:and 1 %v6
  dsl_ret %v7
  ]

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

theorem t10_constants_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬(12#32 ≥ ↑32 ∨ 14#64 ≥ ↑64) → 26#32 ≥ ↑32 → False

theorem e_1095 :
    5 *  ~~~z + 2 *  ~~~(z &&& t) + 4 * z + 2 *  ~~~(z &&&  ~~~t) - 9 *  ~~~(z ||| t) - 10 *  ~~~(z |||  ~~~t) - 7 * (z &&&  ~~~t) - 7 * (z &&& t) =  - 1 * (z ||| t)

theorem icmp_select_var_select_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  x_1 = 1#1 → ofBool (x == 0#8) = 1#1 ∧ x_1 = 1#1 → ofBool (x == 0#8) = 1#1 → ¬True → ofBool (x == x) = 1#1

theorem e_2231 :
     - 1 * (d ^^^ ( ~~~e ||| f)) - 5 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) + 5 * (d ||| ( ~~~e &&& f)) - 2 * (e ^^^ (d ||| (e &&& f))) + 2 * (d ||| (e &&& f)) - 3 * (f ^^^  ~~~(d &&&  ~~~e)) + 1 * (d ^^^ (e ^^^ f)) - 7 * (e &&&  ~~~(d ^^^ f)) - 7 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 3 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 3 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 * ((d &&& e) |||  ~~~(e ^^^ f)) + 5 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 11 *  ~~~(d &&& e) - 11 * (e ^^^  ~~~(d &&& (e ||| f))) + 1 * ( ~~~f |||  ~~~(d ^^^ e)) - 1 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 6 * ( ~~~d &&& (e ^^^ f)) + 2 * (e &&&  ~~~(d &&& f)) + 3 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * (e &&&  ~~~f) + 11 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 3 * (e |||  ~~~f) - 6 * (f ^^^ ( ~~~d ||| (e &&& f))) - 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 2 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 11 * ((d &&& e) |||  ~~~(e |||  ~~~f)) - 5 * ( ~~~d ||| (e ^^^ f)) - 7 * (f ^^^  ~~~(d |||  ~~~e)) + 1 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 7 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 *  ~~~( ~~~d &&& (e ^^^ f)) + 7 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 11 * (f ^^^ (d |||  ~~~e)) + 1 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 2 * (f ^^^ (d ||| ( ~~~e ||| f))) + 7 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 3 * (e ||| (d &&& f)) - 2 * (e ^^^  ~~~(d |||  ~~~f)) - 1 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 11 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 3 *  ~~~(e &&& f) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 1 * (f |||  ~~~(d |||  ~~~e)) - 2 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 5 * (e ^^^ (d ||| ( ~~~e &&& f))) + 38 *  ~~~(d ||| (e ||| f)) + 49 *  ~~~(d ||| ( ~~~e ||| f)) - 6 *  ~~~( ~~~d ||| (e ||| f)) - 15 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 6 * ( ~~~d &&& ( ~~~e &&& f)) - 14 * ( ~~~d &&& (e &&& f)) + 4 * (d &&& ( ~~~e &&& f)) + 5 * (d &&& (e &&& f)) =  - 4 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 3 * (f ^^^ (d ||| ( ~~~e &&& f)))

theorem p_constmask2_thm (e e_1 : IntW 32) :
  add (LLVM.and e_1 (const? 32 61440)) (LLVM.and e (const? 32 (-65281))) ⊑
    LLVM.or (LLVM.and e_1 (const? 32 61440)) (LLVM.and e (const? 32 (-65281))) { «disjoint» := true }

theorem positive_sameconst_shlnsw_thm (e : IntW 8) :
  shl (ashr e (const? 8 3)) (const? 8 3) { «nsw» := true, «nuw» := false } ⊑ LLVM.and e (const? 8 (-8))

theorem sub_sext_mask1_trunc_lshr_proof : sub_sext_mask1_trunc_lshr_before ⊑ sub_sext_mask1_trunc_lshr_after

theorem positive_sameconst_proof : positive_sameconst_before ⊑ positive_sameconst_after

theorem unsigned_sign_bit_extract_with_trunc_proof : unsigned_sign_bit_extract_with_trunc_before ⊑ unsigned_sign_bit_extract_with_trunc_after

theorem trunc_equality_both_proof : trunc_equality_both_before ⊑ trunc_equality_both_after

theorem select_of_symmetric_selects_thm.extracted_1._6 : ∀ (x x_1 : BitVec 32) (x_2 x_3 : BitVec 1),
  x_3 = 1#1 → ¬x_2 = 1#1 → ¬x_2 ^^^ x_3 = 1#1 → x = x_1

theorem p_proof : p_before ⊑ p_after

theorem test_sext1_thm (e e_1 : IntW 1) :
  select e_1 (sext 32 e) (const? 32 0) ⊑ sext 32 (select e_1 e (const? 1 0))

theorem urem_i32_c_proof : urem_i32_c_before ⊑ urem_i32_c_after

theorem n1_proof : n1_before ⊑ n1_after

theorem xor_or_xor_thm (e : IntW 8) :
  LLVM.xor (LLVM.or (LLVM.xor e (const? 8 33)) (const? 8 7)) (const? 8 12) ⊑
    LLVM.xor (LLVM.and e (const? 8 (-8))) (const? 8 43)

theorem test1_thm.extracted_1._1 : ∀ (x : BitVec 61), zeroExtend 61 (truncate 41 x) = x &&& 2199023255551#61

theorem lshrult_01_02_proof : lshrult_01_02_before ⊑ lshrult_01_02_after

theorem main_proof : main_before ⊑ main_after

theorem eq_smax1_thm (e e_1 : IntW 32) :
  icmp IntPred.eq (select (icmp IntPred.sgt e_1 e) e_1 e) e_1 ⊑ icmp IntPred.sge e_1 e

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

theorem test2_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 49), ¬(x_1 ≥ ↑49 ∨ x_1 ≥ ↑49) → x_1 ≥ ↑49 → False

theorem rev8_mul_and_lshr_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (zeroExtend 64 x).smulOverflow 2050#64 = true ∨
        True ∧ (zeroExtend 64 x).umulOverflow 2050#64 = true ∨
          True ∧ (zeroExtend 64 x).smulOverflow 32800#64 = true ∨
            True ∧ (zeroExtend 64 x).umulOverflow 32800#64 = true ∨
              True ∧
                  (zeroExtend 64 x * 2050#64 &&& 139536#64 ||| zeroExtend 64 x * 32800#64 &&& 558144#64).smulOverflow
                      65793#64 =
                    true ∨
                True ∧
                    (zeroExtend 64 x * 2050#64 &&& 139536#64 ||| zeroExtend 64 x * 32800#64 &&& 558144#64).umulOverflow
                        65793#64 =
                      true ∨
                  16#64 ≥ ↑64) →
    True ∧ (zeroExtend 64 x).smulOverflow 2050#64 = true ∨
        True ∧ (zeroExtend 64 x).umulOverflow 2050#64 = true ∨
          True ∧ (zeroExtend 64 x).smulOverflow 32800#64 = true ∨
            True ∧ (zeroExtend 64 x).umulOverflow 32800#64 = true ∨
              True ∧
                  (zeroExtend 64 x * 2050#64 &&& 139536#64 &&& (zeroExtend 64 x * 32800#64 &&& 558144#64) != 0) = true ∨
                True ∧
                    (zeroExtend 64 x * 2050#64 &&& 139536#64 ||| zeroExtend 64 x * 32800#64 &&& 558144#64).smulOverflow
                        65793#64 =
                      true ∨
                  True ∧
                      (zeroExtend 64 x * 2050#64 &&& 139536#64 |||
                              zeroExtend 64 x * 32800#64 &&& 558144#64).umulOverflow
                          65793#64 =
                        true ∨
                    16#64 ≥ ↑64 →
      False

theorem udiv_eq_big_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (LLVM.udiv e_1 e) (const? 8 (-128)) ⊑
    LLVM.and (icmp IntPred.eq e_1 (const? 8 (-128))) (icmp IntPred.eq e (const? 8 1))

theorem logical_or_logical_or_icmps_comm1_thm.extracted_1._5 : ∀ (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 ashrsgt_03_11_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 3#4 <<< 3#4 ≠ x ∨ 3#4 ≥ ↑4) → ofBool (BitVec.ofInt 4 (-5) <ₛ x.sshiftRight' 3#4) = 1#1

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

theorem ashr_lshr2_proof : ashr_lshr2_before ⊑ ashr_lshr2_after

theorem e_1882 :
    5 * ((a &&& b) ||| (b ^^^ c)) + 5 * (c &&&  ~~~(a &&&  ~~~b)) - 5 *  ~~~( ~~~a &&& ( ~~~b &&& c)) - 1 * (a &&& (b ||| c)) + 4 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) + 11 * (a ^^^ ( ~~~b ||| c)) + 11 * (a ||| c) - 7 * b - 1 *  ~~~(a ^^^ (b ^^^ c)) - 3 * (b &&&  ~~~(a ^^^ c)) - 2 * ( ~~~a &&& (b ||| c)) - 7 * ( ~~~(a &&& b) &&& (b ^^^ c)) - 11 * ( ~~~a ||| (b ||| c)) - 1 * (a &&&  ~~~b) - 1 * (b |||  ~~~(a ||| c)) + 4 * (a ^^^ (b ^^^ c)) + 5 * (b ||| (a &&&  ~~~c)) + 2 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) + 7 *  ~~~( ~~~a &&& (b &&& c)) - 1 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) + 4 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 3 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) + 11 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) + 1 * ((a &&&  ~~~b) ||| (b ^^^ c)) - 3 * (c ^^^ (a ||| ( ~~~b &&& c))) - 2 * (b ^^^  ~~~(a &&&  ~~~c)) + 2 * ( ~~~b |||  ~~~(a ^^^ c)) - 1 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) + 4 * (a &&& c) - 2 * ( ~~~a ||| ( ~~~b &&& c)) - 11 * (a ||| ( ~~~b &&& c)) - 2 * (b &&& (a ^^^ c)) + 4 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) - 1 *  ~~~(a ||| b) - 1 * (c |||  ~~~(a ||| b)) + 4 * (a ^^^ b) + 3 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 1 * (b ^^^ (a &&& (b ||| c))) - 1 *  ~~~(a ^^^ (b &&& c)) + 3 * (b ^^^ (a ||| (b &&& c))) - 1 *  ~~~(a ||| (b ||| c)) + 7 *  ~~~(a ||| ( ~~~b ||| c)) - 29 *  ~~~( ~~~a ||| (b ||| c)) - 11 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 31 * ( ~~~a &&& ( ~~~b &&& c)) - 20 * ( ~~~a &&& (b &&& c)) - 1 * (a &&& ( ~~~b &&& c)) - 14 * (a &&& (b &&& c)) = 2 * (b ^^^  ~~~(a |||  ~~~c)) - 1 * (c ||| (a &&& b))

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_6_proof : masked_icmps_mask_notallzeros_bmask_mixed_swapped_6_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_swapped_6_after

theorem n7_thm (e : IntW 32) :
  select (icmp IntPred.ne (LLVM.and e (const? 32 2)) (const? 32 0)) (LLVM.and e (const? 32 1)) (const? 32 1) ⊑
    select (icmp IntPred.eq (LLVM.and e (const? 32 2)) (const? 32 0)) (const? 32 1)
      (LLVM.and e (const? 32 1))

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

theorem tryFactorization_add_nuw_mul_nuw_int_max_proof : tryFactorization_add_nuw_mul_nuw_int_max_before ⊑ tryFactorization_add_nuw_mul_nuw_int_max_after

theorem bools2_logical_commute1_and2_thm.extracted_1._11 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 = 1#1 → ¬x_1 = 1#1 → ¬0#1 = 1#1 → (x_1 ^^^ 1#1) &&& x = x

theorem mul_constant_eq_proof : mul_constant_eq_before ⊑ mul_constant_eq_after

theorem or_xor_commute4_thm (e e_1 : IntW 32) :
  LLVM.xor (LLVM.udiv (const? 32 42) e_1) (LLVM.or (LLVM.udiv (const? 32 42) e) (LLVM.udiv (const? 32 42) e_1)) ⊑
    LLVM.and (LLVM.udiv (const? 32 42) e) (LLVM.xor (LLVM.udiv (const? 32 42) e_1) (const? 32 (-1)))

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

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

theorem testi16i8_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬15#16 ≥ ↑16 → ofBool (-1#16 <ₛ x) = 1#1 → truncate 8 (x.sshiftRight' 15#16) ^^^ 27#8 = 27#8

theorem logical_and_logical_and_icmps_comm3_proof : logical_and_logical_and_icmps_comm3_before ⊑ logical_and_logical_and_icmps_comm3_after

theorem test7_thm (e : IntW 64) :
  trunc 92 (lshr (zext 128 e) (const? 128 32)) ⊑ zext 92 (lshr e (const? 64 32)) { «nneg» := true }

@[simp]
theorem Factor.reflect_zero_of_denote_zero {w : Nat} {f : Factor} {xs : Env w} (h : f.denote xs = 0) :
    f.reflect xs = 0#w

theorem or_xor_tree_1110_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  x_2 * 42#32 ^^^ (x_1 * 42#32 ^^^ x * 42#32) ||

theorem and_signbit_ashr_proof : and_signbit_ashr_before ⊑ and_signbit_ashr_after

theorem test5_proof : test5_before ⊑ test5_after

theorem e_1553 :
     - 6 *  ~~~(a ^^^ c) - 1 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 5 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 1 * (b ||| (a ^^^ c)) - 1 *  ~~~( ~~~a &&& ( ~~~b ||| c)) + 5 * ( ~~~a &&& (b ||| c)) - 5 * ((a &&& c) ||| (b &&&  ~~~c)) + 12 *  ~~~(a ||| (b ||| c)) + 8 *  ~~~(a ||| ( ~~~b ||| c)) + 8 *  ~~~( ~~~a ||| (b ||| c)) + 8 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 3 * ( ~~~a &&& (b &&& c)) + 13 * (a &&& ( ~~~b &&& c)) + 14 * (a &&& (b &&& c)) =  - 2 * ( ~~~a &&& ( ~~~b &&& c)) + 1 *  ~~~(a ^^^ b)

@[simp]
theorem concat_false_add_concat_false_zero_eq (x y : BitStream) :
 ((BitStream.concat false x) + (BitStream.concat false y)) 0 =
  (BitStream.concat false (x + y)) 0

theorem positive_biggershl_shlnsw_proof : positive_biggershl_shlnsw_before ⊑ positive_biggershl_shlnsw_after

theorem e_2318 :
    7 * (e &&&  ~~~(d &&&  ~~~f)) - 2 * ((d &&& f) |||  ~~~(e ||| f)) + 2 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 5 * (d &&&  ~~~e) + 2 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 2 * (d ^^^ e) - 11 *  ~~~(d ^^^ ( ~~~e ||| f)) - 6 * (f ^^^  ~~~(d ||| (e &&& f))) - 2 *  ~~~(d &&& f) - 11 * ((d |||  ~~~e) &&& (e ^^^ f)) - 2 * (d ||| e) - 3 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 2 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (f ^^^ ( ~~~d ||| (e ||| f))) + 11 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 1 * (e ^^^ (d ||| (e ||| f))) + 1 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 7 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 2 * (e ^^^  ~~~(d |||  ~~~f)) - 1 * (d ||| (e ^^^ f)) - 2 * (e ||| (d &&&  ~~~f)) - 3 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 * (f ||| (d ^^^ e)) + 1 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 11 * (e ^^^ (d ||| ( ~~~e &&& f))) - 5 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 5 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 2 * (e ^^^ ( ~~~d ||| (e &&& f))) + 1 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 1 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 1 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 7 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * (f ^^^ ( ~~~d &&& (e ||| f))) - 2 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 1 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 4 *  ~~~(d &&& e) + 5 * (e ^^^ ( ~~~d ||| (e ||| f))) + 2 *  ~~~(e &&&  ~~~f) + 3 * (e ^^^ (d ||| f)) - 11 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 2 * ( ~~~d ||| ( ~~~e ||| f)) - 2 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) + 4 * ( ~~~f ||| (d ^^^ e)) - 2 *  ~~~(d ^^^ e) - 7 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 6 * (f ^^^  ~~~(d &&& (e ||| f))) + 7 * (f ^^^  ~~~(d &&& e)) + 3 * (e ^^^  ~~~(d ||| f)) + 5 *  ~~~(d ||| (e &&& f)) + 1 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 7 *  ~~~( ~~~d &&& (e &&& f)) + 1 *  ~~~(d ^^^ (e ^^^ f)) + 1 *  ~~~(d &&& ( ~~~e ||| f)) - 1 *  ~~~(d ^^^ (e &&& f)) - 1 * (d ^^^ f) - 19 *  ~~~(d ||| (e ||| f)) + 11 *  ~~~(d ||| ( ~~~e ||| f)) + 23 *  ~~~( ~~~d ||| (e ||| f)) + 25 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 49 * ( ~~~d &&& ( ~~~e &&& f)) - 17 * ( ~~~d &&& (e &&& f)) + 42 * (d &&& ( ~~~e &&& f)) + 48 * (d &&& (e &&& f)) = 11 * (e ^^^ ( ~~~d &&& (e ||| f)))

theorem xor_sext_sext_thm.extracted_1._1 : ∀ (x : BitVec 4) (x_1 : BitVec 8),
  signExtend 16 x_1 ^^^ signExtend 16 x = signExtend 16 (x_1 ^^^ signExtend 8 x)

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

theorem select2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  x_2 = 1#1 → truncate 8 (zeroExtend 32 x_1) = x_1

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

theorem t7_proof : t7_before ⊑ t7_after
</all_available_lemmas>

<local_ctx>
import Blase.AutoStructs.Basic

open SetRel

section nfa

variable {A : Type} [BEq A] [LawfulBEq A] [Hashable A] [DecidableEq A] [FinEnum A]

variable {S : Type} [Fintype S] [BEq S] [LawfulBEq S] [Hashable S] [DecidableEq S]

variable (inits : Array S) (final : S → Bool) (f : S → Array (A × S))

def nfa : NFA A S where
  start := { sa | sa ∈ inits }
  accept := { sa | final sa }
  step sa a := { sa' | (a, sa') ∈ f sa }

end nfa

section nfa'

variable {S : Type} [Fintype S] [BEq S] [LawfulBEq S] [Hashable S] [DecidableEq S]

variable (inits : Array S) (final : S → Bool) (f : S → Array (BitVec n × S))

end nfa'

section worklist

variable (A : Type) [BEq A] [LawfulBEq A] [Hashable A] [DecidableEq A] [FinEnum A]

variable (S : Type) [Fintype S] [BEq S] [LawfulBEq S] [Hashable S] [DecidableEq S]

structure worklist.St where
  m : RawCNFA A
  map : Std.HashMap S State := ∅
  worklist : Array S := ∅
  worklist_nodup : worklist.toList.Nodup
  worklist_incl : ∀ sa ∈ worklist, sa ∈ map

open List in

def worklist.St.addOrCreateState (st : worklist.St A S) (final? : Bool) (sa : S) : State × worklist.St A S :=
  match heq : st.map[sa]? with
  | some s => (s, st)
  | none =>
    let (s, m) := st.m.newState
    let m := if final? then m.addFinal s else m
    let map := st.map.insert sa s
    let worklist := st.worklist.push sa
    have worklist_nodup : worklist.toList.Nodup := by admit /- proof elided -/

def processOneElem (final : S → Bool) (s : State) (st : worklist.St A S) : A × S → worklist.St A S :=
  fun (a', sa') =>
    let (s', st') := st.addOrCreateState _ _ (final sa') sa'
    let m := st'.m.addTrans a' s s'
    { st' with m }

      open List in
      have hgrow : ∃ sas, st2.map.keys ~ (sas ++ st1.map.keys) ∧ st2.worklist.toList = st1.worklist.toList ++ sas := by
        rcases a with ⟨al⟩
        unfold st2
        generalize hst1 : st1 = x; clear hst1; revert x
        induction al with
        | nil => simp
        | cons asa al ih =>
          simp; simp at ih; intros st
          let wl' := processOneElem A S final s st asa
          rcases ih wl' with ⟨sas', h1', h2'⟩; clear ih
          rcases processOneElem_grow _ _ st final asa.1 asa.2 s with ⟨sas, h1, h2⟩
          use (sas ++ sas')
          constructor
          { simp [wl'] at h1'; apply list_perm_trick; exact h1'; exact h1 }
          { simp [wl', h2] at h2'; aesop }
      have hincl : ∀ k, k ∈ st1.map → k ∈ st2.map := by
        intros k; rcases hgrow with ⟨sas, hkeys, -⟩;
        have := @(List.perm_subset_iff_right hkeys st1.map.keys).mpr (by aesop) k; aesop
      have : st1.meas < st0.meas := by
        rcases heq' : sa? with ⟨⟩ | ⟨sa⟩
        { simp_all }
        apply Finset.card_lt_card
        simp [Finset.ssubset_iff, Finset.subset_iff]
        use sa
        simp [sa?] at heq'
        constructor
        { constructor
          { apply Array.mem_of_back? at heq'; apply st0.worklist_incl; assumption }
          { apply Array.not_elem_back_pop at heq' <;> simp_all +zetaDelta [Array.pop] } }
        constructor
        { right; apply Array.mem_of_back? at heq'; assumption }
        rintro sa hh; rcases hh with hnin | hin
        { simp +zetaDelta [hnin] }
        right
        exact Array.mem_of_mem_pop st0.worklist sa hin
      have : st2.meas ≤ st1.meas := by
        apply Finset.card_le_card
        simp +zetaDelta [Finset.subset_iff]
        intros sa' h
        rcases h with hnin | hin
        { left; simp [st1] at hincl; intros hc; apply hnin; apply hincl; assumption }
        by_cases hnew : sa' ∈ st0.map
        all_goals try (left; trivial)
        right
        simp [st1] at hgrow
        rcases hgrow with ⟨sas, hkeys2, hwl2⟩
        have hnin : sa'∉ sas := by
          intros hc
          have hdisj : st0.map.keys.Disjoint sas := by
            have : (sas ++ st0.map.keys).Nodup := by
              apply List.Perm.nodup
              assumption
              apply st2.map.keys_nodup
            simp [List.nodup_append_comm, List.disjoint_of_nodup_append, this]
          apply hdisj
          { simp_all [Std.HashMap.mem_keys]; apply hnew }
          { apply hc }
        rcases hin with ⟨hin⟩; simp_all +zetaDelta
      have : st2.meas < st0.meas := by omega
      go st2
    else
      st0.m -- never happens
  | none => st0.m -- never happens
  termination_by st0.meas

def worklist.St.visited (st : worklist.St A S) : Set S := { s : S | s ∈ st.map ∧ s ∉ st.worklist }

structure StInv (m : RawCNFA A) (map : Std.HashMap S State) where
  wf : m.WF
  map_states : ∀ (sa : S) s, map[sa]? = some s → s ∈ m.states
  map_surj : ∀ s : m.states, ∃ (sa : S), map[sa]? = some s.val
  map_inj : ∀ {s} {sa sa' : S}, map[sa]? = some s → map[sa']? = some s → sa = sa'

end worklist

section worklist_correct

variable {A : Type} [BEq A] [LawfulBEq A] [Hashable A] [DecidableEq A] [FinEnum A]

variable {S : Type} [Fintype S] [BEq S] [LawfulBEq S] [Hashable S] [DecidableEq S]

variable (inits : Array S) (final : S → Bool) (f : S → Array (A × S))

def worklist.St.rel (st : worklist.St A S) : SetRel State S := {(s, sa) | st.map[sa]? = some s }

def worklist.St.D (st : worklist.St A S) : Set S := st.visited

abbrev worklist.St.sim {st : worklist.St A S} (T : Set (S × A × S)) :=
  st.m.Simul (nfa inits final f) st.rel st.D T

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

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 :=
</local_ctx>

<target_theorem>
omit [Fintype S] in
lemma processOneElem_spec {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 →
    processOneElem_mot inits final f s sa (k+1) (processOneElem A S final s st (a, sa')) :=
</target_theorem>

