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

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

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

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

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

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

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

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

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

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

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

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

open Set
open Mathlib
open SetRel

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

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

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

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

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

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

@[simp]
</local_ctx>

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

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

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

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

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

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

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

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

### Your task:
<all_available_defs>
BitVec in Init.Prelude
NFA in Mathlib.Computability.NFA
DecidableEq in Init.Prelude
Fintype in Mathlib.Data.Fintype.Defs
BitVec.ofNat in Init.Prelude
BitVec.cons in Init.Data.BitVec.Basic
List in Init.Prelude
Repr in Init.Data.Repr
NFA.accept in Mathlib.Computability.NFA
NFA.start in Mathlib.Computability.NFA
NFA.step in Mathlib.Computability.NFA
FinEnum in Mathlib.Data.FinEnum
BitVec.ofFin in Init.Prelude
cmp in Mathlib.Data.Ordering.Basic
NFA.stepSet in Mathlib.Computability.NFA
BitVec.ult in Init.Data.BitVec.Basic
Nat in Init.Prelude
BitVec.sle in Init.Data.BitVec.Basic
BitVec.slt in Init.Data.BitVec.Basic

inductive RelationOrdering
| lt | le | gt | ge
deriving Repr, Fintype

def bv2 : BitVec 4 := BitVec.ofNat 4 1

def bv1 : BitVec 4 := BitVec.ofNat 4 5

instance instFinEnumBV : FinEnum (BitVec w) where
  card := 2^w
  equiv := {
    toFun := fun x => x.toFin
    invFun := fun x => BitVec.ofFin x
    left_inv := by admit /- proof elided -/

BitVec.clz in Init.Data.BitVec.Basic

def bar_after := [llvm|
{
^0(%arg0 : i64, %arg1 : i64):
  %0 = llvm.mlir.constant(-1) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.xor %arg0, %0 : i64
  %3 = llvm.and %arg1, %2 : i64
  %4 = llvm.icmp "eq" %3, %1 : i64
  "llvm.return"(%4) : (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 trunc_equality_nuw_before := [llvm|
{
^0(%arg44 : i16, %arg45 : i16):
  %0 = llvm.trunc %arg44 overflow<nuw> : i16 to i8
  %1 = llvm.trunc %arg45 overflow<nuw> : i16 to i8
  %2 = llvm.icmp "eq" %0, %1 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

Lean.MVarId in Lean.Expr

def test_slt_nuw_after := [llvm|
{
^0(%arg0 : i32, %arg1 : i16):
  %0 = llvm.zext %arg1 : i16 to i32
  %1 = llvm.icmp "slt" %arg0, %0 : i32
  "llvm.return"(%1) : (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 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) -> ()
}
]

instance : DialectSignature ExOp ExTy where
  signature
  | .add    => ⟨[.nat, .nat], [], .nat, .pure⟩
  | .runK _ => ⟨[.nat], [([.nat], .nat)], .nat, .pure⟩

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

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

def llvm_udiv_lower_riscv_flag_32: LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] :=
  {lhs := udiv_llvm_exact_32, rhs := udiv_riscv_32, correct := sorry }

def Term.reflect {w : Nat}  (t : Term) (xs: Env w) : BitVec w :=
  (BitVec.ofInt w t.c) * t.f.reflect xs

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

elab "#generalize" expr:term : command =>

def State.cseRegionArgList
  {Γstart Γ : Ctxt d.Ty}
  {lets : Lets d Γstart .pure Γ}
  (_ : State d lets)
  {ts : RegionSignature d.Ty}
  (rs : HVector ((fun t => Com d t.1 .impure t.2)) <| ts) :
  {rs' : HVector ((fun t => Com d t.1 .impure t.2)) <| ts //
    HVector.denote rs = HVector.denote rs' } :=
  let _ := HVector.map (fun _Γα com => Com.denote com) rs
  match ts, rs with
  | _, .nil => ⟨.nil, by admit /- proof elided -/
    ⟩
  | ⟨Γ, t⟩::ts, .cons region rs =>
    
    
    
    
    ⟨.cons region rs, by admit /- proof elided -/
    ⟩

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

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

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

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

def toString : GenBVExpr w → String
  | .var idx => s!"var{idx}#{w}"
  | .const val => ToString.toString val
  | .extract start len expr => s!"{expr.toString}[{start}, {len}]"
  | .bin lhs op rhs => s!"({lhs.toString} {op.toString} {rhs.toString})"
  | .un op operand => s!"({op.toString} {toString operand})"
  | .append lhs rhs _ => s!"({toString lhs} ++ {toString rhs})"
  | .replicate n expr _ => s!"(replicate {n} {toString expr})"
  | .shiftLeft lhs rhs => s!"({lhs.toString} << {rhs.toString})"
  | .shiftRight lhs rhs => s!"({lhs.toString} >> {rhs.toString})"
  | .arithShiftRight lhs rhs => s!"({lhs.toString} >>a {rhs.toString})"
  | .signExtend v expr => s!"(signExtend {v} {toString expr}})"
  | .zeroExtend v expr => s!"(zeroExtend {v} {toString expr}})"
  | .truncate v expr => s!"(truncate {v} {toString expr}})"

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

def eval_zext_multi_use_in_one_inst_before := [llvm|
{
^0(%arg7 : i32):
  %0 = llvm.mlir.constant(5 : i16) : i16
  %1 = llvm.trunc %arg7 : i32 to i16
  %2 = llvm.and %1, %0 : i16
  %3 = llvm.mul %2, %2 overflow<nsw,nuw> : i16
  %4 = llvm.zext %3 : i16 to i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

private def attrVal0Str : AttrVal := [mlir_attr_val| "foo"]

BitVec.reduceOfNat in Lean.Meta.Tactic.Simp.BuiltinSimprocs.BitVec

def Expr.args {Γ ts} (e : Expr d Γ eff ts) :
    HVector (Var Γ) (DialectSignature.sig e.op) :=
  Expr.casesOn e (fun _ _ _ args _ => args)

abbrev MLIRType.i1: MLIRType φ := MLIRType.int .Signless 1

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

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

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

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

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

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

def assumeArity (n : Nat) : Except TransformError (ParsedArgs Γ n) :=
  if h : n? = some n then
    return h ▸ args
  else if h : args.toList.length = n then
    return ⟨args.toList, h⟩
  else
    throw <| .generic s!"Expected exactly {n} argument(s), but found {args.toList.length}"

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

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

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

def src_is_mask_zext_fail_not_mask_before := [llvm|
{
^0(%arg129 : i16, %arg130 : i8):
  %0 = llvm.mlir.constant(123 : i16) : i16
  %1 = llvm.mlir.constant(-2 : i8) : i8
  %2 = llvm.xor %arg129, %0 : i16
  %3 = llvm.lshr %1, %arg130 : i8
  %4 = llvm.zext %3 : i8 to i16
  %5 = llvm.and %2, %4 : i16
  %6 = llvm.icmp "eq" %5, %2 : i16
  "llvm.return"(%6) : (i1) -> ()
}
]

BitVec.toNat in Init.Prelude

def test7_before := [llvm|
{
^0(%arg7 : i47):
  %0 = llvm.mlir.constant(39 : i47) : i47
  %1 = llvm.mlir.constant(255 : i47) : i47
  %2 = llvm.ashr %arg7, %0 : i47
  %3 = llvm.and %2, %1 : i47
  "llvm.return"(%3) : (i47) -> ()
}
]

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

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

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

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

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

Min in Init.Prelude

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

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

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

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

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

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

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

def Context (Ty : Type) : Type :=
  List (VarName × Ty)

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

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

def 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 binop_right_to_zero: List (Σ Γ, LLVMPeepholeRewriteRefine 64 Γ) :=
  [⟨_, binop_right_to_zero_mul⟩]

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

instance : Lean.ToExpr RegIndex := inherit

List.reverse in Init.Data.List.Basic

def test14_before := [llvm|
{
^0(%arg36 : i1, %arg37 : i1):
  %0 = llvm.icmp "eq" %arg36, %arg37 : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

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

private def pretty_test_exact :=
  [llvm()|{
  ^bb0(%arg0: i64):
    %0 = llvm.udiv exact %arg0, %arg0 : i64
    %1 = llvm.sdiv exact %arg0, %arg0 : i64
    %2 = llvm.lshr exact %arg0, %arg0 : i64
    %3 = llvm.ashr exact %arg0, %arg0 : i64
    llvm.return %0 : i64
  }]

example : pretty_test = prettier_test_generic 32 :=

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

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

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

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

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

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

@[simp]
def dec_bij {n : Nat} : Function.Bijective (dec (n := n)) :=

def Ctxt.delete (Γ : Ctxt Ty) (vs : DeleteRange Γ) : Ctxt Ty :=
  Ctxt.ofList <| List.ofFn (n := Γ.length - vs.num.val) fun i =>
    have := vs.start.prop
    if hi : i.val < vs.start then
      Γ[i.val]
    else
      Γ[i.val + vs.num]

instance : ToString (CIRCTStream.Stream (BitVec w))where
  toString s := toString (Stream.toList 10 s)

def bools2_logical_commute0_and1_after := [llvm|
{
^0(%arg61 : i1, %arg62 : i1, %arg63 : i1):
  %0 = "llvm.select"(%arg63, %arg61, %arg62) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

def shl_lshr_demand1_after := [llvm|
{
^0(%arg20 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.mlir.constant(-32 : i8) : i8
  %2 = llvm.shl %0, %arg20 : i8
  %3 = llvm.or %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

def t3_after := [llvm|
{
^0(%arg23 : i8, %arg24 : i2):
  %0 = llvm.sext %arg24 : i2 to i8
  %1 = llvm.add %arg23, %0 : i8
  %2 = llvm.xor %1, %0 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

def scalar_i32_lshr_and_negC_slt_before := [llvm|
{
^0(%arg4 : i32, %arg5 : i32):
  %0 = llvm.mlir.constant(-8 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.lshr %arg4, %arg5 : i32
  %3 = llvm.and %2, %0 : i32
  %4 = llvm.icmp "slt" %3, %1 : i32
  "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) -> ()
}
]

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

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

def sub_zext_trunc_lshr_after := [llvm|
{
^0(%arg15 : i64):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.mlir.constant(31 : i32) : i32
  %2 = llvm.mlir.constant(10 : i32) : i32
  %3 = llvm.trunc %arg15 : i64 to i32
  %4 = llvm.shl %3, %0 : i32
  %5 = llvm.ashr %4, %1 : i32
  %6 = llvm.add %5, %2 overflow<nsw> : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def test6a_after := [llvm|
{
^0(%arg47 : i55):
  %0 = llvm.mlir.constant(6 : i55) : i55
  %1 = llvm.mul %arg47, %0 : i55
  "llvm.return"(%1) : (i55) -> ()
}
]

def test14_before := [llvm|
{
^0(%arg14 : i8, %arg15 : i8):
  %0 = llvm.icmp "eq" %arg14, %arg15 : i8
  %1 = llvm.icmp "ne" %arg15, %arg14 : i8
  %2 = llvm.xor %0, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

instance : LawfulGetElem (Ctxt Ty) Nat Ty (fun as i => i < as.length) where
  getElem?_def Γ i _ := by admit /- proof elided -/

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

def inter (M N : NFA' n) : NFA' n := ⟨_, M.M.inter N.M⟩

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

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

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

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 testi128i128_after := [llvm|
{
^0(%arg7 : i128):
  %0 = llvm.mlir.constant(-1 : i128) : i128
  %1 = llvm.mlir.constant(27 : i128) : i128
  %2 = llvm.mlir.constant(-28 : i128) : i128
  %3 = llvm.icmp "sgt" %arg7, %0 : i128
  %4 = "llvm.select"(%3, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i128, i128) -> i128
  "llvm.return"(%4) : (i128) -> ()
}
]

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

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

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

def bar_after := [llvm|
{
^0(%arg109 : i32, %arg110 : i32, %arg111 : i32, %arg112 : i32):
  %0 = llvm.icmp "slt" %arg109, %arg110 : i32
  %1 = "llvm.select"(%0, %arg111, %arg112) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

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

private def pretty_bool :=
  [llvm()| {
    ^bb0():
      %0 = llvm.mlir.constant (1 : i1) : i1
      %1 = llvm.mlir.constant (0 : i1) : i1
      %2 = llvm.mlir.constant (true)
      %3 = llvm.mlir.constant (false)
      %4 = llvm.mlir.constant (true) : i1
      %5 = llvm.mlir.constant (false) : i1
      %10 = llvm.add %0, %1 : i1
      %11 = llvm.add %2, %3 : i1
      %12 = llvm.add %4, %5 : i1
      llvm.return %2 : i1
  }]

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

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

structure Item where
 name : String
 tac : Syntax

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

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

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

Finset.card in Mathlib.Data.Finset.Card

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

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

def shl_and_and_fail_before := [llvm|
{
^0(%arg170 : i8, %arg171 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.mlir.constant(5 : i8) : i8
  %2 = llvm.mlir.constant(88 : i8) : i8
  %3 = llvm.shl %arg170, %0 : i8
  %4 = llvm.shl %arg171, %1 : i8
  %5 = llvm.and %4, %2 : i8
  %6 = llvm.and %3, %5 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

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

def FpBinaryPredKind.toString : FpBinaryPredKind → String
  | FpBinaryPredKind.eq => "="

@[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 foo_before := [llvm|
{
^0(%arg113 : i32, %arg114 : i32, %arg115 : i32, %arg116 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.icmp "slt" %arg113, %arg114 : i32
  %2 = llvm.sext %1 : i1 to i32
  %3 = llvm.and %arg115, %2 : i32
  %4 = llvm.xor %2, %0 : i32
  %5 = llvm.and %arg116, %4 : i32
  %6 = llvm.or %3, %5 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def lshr_16_add_zext_basic_before := [llvm|
{
^0(%arg33 : i16, %arg34 : i16):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.zext %arg33 : i16 to i32
  %2 = llvm.zext %arg34 : i16 to i32
  %3 = llvm.add %1, %2 : i32
  %4 = llvm.lshr %3, %0 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

def shl_xor_lshr_after := [llvm|
{
^0(%arg100 : i32, %arg101 : i32, %arg102 : i32):
  %0 = llvm.lshr %arg102, %arg101 : i32
  %1 = llvm.xor %0, %arg100 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def ne_3210_after := [llvm|
{
^0(%arg74 : i32, %arg75 : i32):
  %0 = llvm.icmp "ne" %arg74, %arg75 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

Lean.instantiateMVars in Lean.MetavarContext

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

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

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

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

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

def add_positive_low_bound_reject_test: LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := add_positive_low_bound_reject_llvm
  rhs := add_positive_low_bound_reject_riscv

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

def ne_umax2_after := [llvm|
{
^0(%arg42 : i32, %arg43 : i32):
  %0 = llvm.icmp "ult" %arg42, %arg43 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

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

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

def sext_shl_mask_after := [llvm|
{
^0(%arg7 : i16, %arg8 : i32):
  %0 = llvm.mlir.constant(65535 : i32) : i32
  %1 = llvm.zext %arg7 : i16 to i32
  %2 = llvm.shl %1, %arg8 : i32
  %3 = llvm.and %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def or_basic_before := [llvm|
{
^0(%arg15 : i16):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.mlir.constant(-256 : i16) : i16
  %2 = llvm.mlir.constant(17664 : i16) : i16
  %3 = llvm.trunc %arg15 : i16 to i8
  %4 = llvm.icmp "ne" %3, %0 : i8
  %5 = llvm.and %arg15, %1 : i16
  %6 = llvm.icmp "ne" %5, %2 : i16
  %7 = llvm.or %4, %6 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

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

def icmp_sge_riscv_eq_icmp_sge_llvm_32 : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] :=
  {lhs:= icmp_sge_llvm_32, rhs:= icmp_sge_riscv_32}

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

class SubstituteableTerminator (T : Type u) where
  substituteTerminator (σ : VarName → VarName) : T → T

List.Perm in Init.Data.List.Basic

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

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

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

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

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

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

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

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

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

def t0_basic_after := [llvm|
{
^0(%arg24 : i8, %arg25 : i8):
  %0 = llvm.icmp "ule" %arg25, %arg24 : i8
  "llvm.return"(%0) : (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 merge {Γ : Ctxt _} (a b : Γ.Var (.tokenstream)) : Expr (DC) Γ .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 ne_shift_in_zeros_before := [llvm|
{
^0(%arg32 : i32, %arg33 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.lshr %arg32, %0 : i32
  %3 = llvm.trunc %2 : i32 to i8
  %4 = llvm.lshr %arg32, %1 : i32
  %5 = llvm.trunc %4 : i32 to i24
  %6 = llvm.lshr %arg33, %0 : i32
  %7 = llvm.trunc %6 : i32 to i8
  %8 = llvm.lshr %arg33, %1 : i32
  %9 = llvm.trunc %8 : i32 to i24
  %10 = llvm.icmp "ne" %3, %7 : i8
  %11 = llvm.icmp "ne" %5, %9 : i24
  %12 = llvm.or %11, %10 : i1
  "llvm.return"(%12) : (i1) -> ()
}
]

Lean.initSearchPath in Lean.Util.Path

def sub_to_and_after := [llvm|
{
^0(%arg14 : i32, %arg15 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.and %arg14, %arg15 : i32
  %2 = llvm.sub %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

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

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

def t10_c1_c2_after := [llvm|
{
^0(%arg11 : i8, %arg12 : i8):
  %0 = llvm.mlir.constant(-66 : i8) : i8
  %1 = llvm.add %arg11, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

def positive_samevar_shlnsw_ashrexact_after := [llvm|
{
^0(%arg37 : i8, %arg38 : i8):
  "llvm.return"(%arg37) : (i8) -> ()
}
]

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

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

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

@[simp_denote]
def select_riscv_64 := [LV| {
  ^entry (%cond : i1, %arg0: i64, %arg1: i64):
    %0 = "builtin.unrealized_conversion_cast" (%arg0) : (i64) -> (!i64)
    %1 = "builtin.unrealized_conversion_cast" (%arg1) : (i64) -> (!i64)
    %2 = "builtin.unrealized_conversion_cast" (%cond) : (i1) -> (!i64)
    %3 = snez %2 : !i64
    %4 = sub %0, %1 : !i64
    %5 = mul %4, %3 : !i64
    %6 = add %5, %1 : !i64
    %7 = "builtin.unrealized_conversion_cast" (%6) : (!i64) -> (i64)
    llvm.return %7 : i64
  }]

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

def irc_constants_AMinusC1PlusC2_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.sub %a, %c1 : i64
      %1 = llvm.add %0, %c2 : 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.add %a, %0 : i64
      llvm.return %1 : i64
  }]

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

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

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

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

def negNumToTerm : TSyntax ``neg_num → MacroM Term
  | `(neg_num| $x:num) => `($x:num)
  | `(neg_num| -$x:num) => `(-$x:num)
  | _ => Macro.throwUnsupported

structure Tensor2d' (α : Type) where
  dim₀ : Index
  dim₁ : Index
  mat : Matrix (Fin dim₀) (Fin dim₁) α

def isOpenBracket(c: Char): Option Bracket :=
match c with
| '(' => some .Round
| '[' => some .Square
| '{' => some .Curly
| '<' => some .Angle
| _ => none

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

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

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

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

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

def test68_after := [llvm|
{
^0(%arg166 : i32, %arg167 : i32):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.lshr %arg166, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.or %arg167, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

Lean.findSysroot in Lean.Util.Path

DFA in Mathlib.Computability.DFA

def two_inst_concrete_com_proof :
    two_inst_concrete_com w ⊑ two_inst_concrete_com w :=

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

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

def test2_before := [llvm|
{
^0(%arg0 : i52, %arg1 : i52):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.icmp "ule" %arg0, %arg1 : i52
  %2 = llvm.xor %1, %0 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

@[simp_denote]
def slli_llvm_i64 := [LV| {
    ^entry (%a: i64):
    %0 = llvm.mlir.constant (7) : i64
    %1 = llvm.shl %a, %0 : i64
    llvm.return %1 : i64
  }]

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

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

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

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

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

Prod in Init.Prelude

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 lowmask_add_zext_wrong_mask_after := [llvm|
{
^0(%arg231 : i8, %arg232 : i32):
  %0 = llvm.mlir.constant(511 : i32) : i32
  %1 = llvm.zext %arg231 : i8 to i32
  %2 = llvm.add %arg232, %1 : i32
  %3 = llvm.and %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def t2_before := [llvm|
{
^0(%arg25 : i8, %arg26 : i1, %arg27 : i1):
  %0 = llvm.sext %arg26 : i1 to i8
  %1 = llvm.sext %arg27 : i1 to i8
  %2 = llvm.add %0, %arg25 : i8
  %3 = llvm.xor %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def 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 hasAttr (attr : String) : Bool :=
  (op.getAttr? attr).isSome

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

def scalar_i8_shl_uge_const_before := [llvm|
{
^0(%arg13 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.mlir.constant(64 : i8) : i8
  %2 = llvm.shl %arg13, %0 : i8
  %3 = llvm.icmp "uge" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

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 negative5_before := [llvm|
{
^0(%arg2 : i32, %arg3 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg3, %0 : i32
  %3 = llvm.icmp "slt" %arg2, %2 : i32
  %4 = llvm.icmp "sge" %arg2, %1 : i32
  %5 = llvm.or %3, %4 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def 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_before := [llvm|
{
^0(%arg0 : i64):
  %0 = llvm.mlir.constant(4294967294) : i64
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.or %arg0, %0 : i64
  %3 = llvm.trunc %2 : i64 to i32
  %4 = llvm.srem %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

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

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

def select_add_before := [llvm|
{
^0(%arg15 : i1, %arg16 : i64, %arg17 : i64):
  %0 = llvm.add %arg16, %arg17 : i64
  %1 = "llvm.select"(%arg15, %0, %arg16) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%1) : (i64) -> ()
}
]

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

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

def EnvFin.comap {w n n' : Nat} (env : EnvFin w n) (f : Fin n' → Fin n) : EnvFin w n' :=
  fun i' => env (f i')

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

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

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

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

def scalar_i16_shl_ult_const_before := [llvm|
{
^0(%arg16 : i16):
  %0 = llvm.mlir.constant(8 : i16) : i16
  %1 = llvm.mlir.constant(1024 : i16) : i16
  %2 = llvm.shl %arg16, %0 : i16
  %3 = llvm.icmp "ult" %2, %1 : i16
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def positive_biggerLshr_after := [llvm|
{
^0(%arg33 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.mlir.constant(4194303 : i32) : i32
  %2 = llvm.lshr %arg33, %0 : i32
  %3 = llvm.and %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

def test13_before := [llvm|
{
^0(%arg44 : i32, %arg45 : i32):
  %0 = llvm.mlir.constant(-1431655767 : i32) : i32
  %1 = llvm.mlir.constant(1431655766 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.or %arg44, %0 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.add %arg45, %2 : i32
  %6 = llvm.add %5, %4 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

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

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

def icmp_eq_and_pow2_shl_pow2_negative2_before := [llvm|
{
^0(%arg60 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(14 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.shl %0, %arg60 : 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 same_source_shifted_signbit_before := [llvm|
{
^0(%arg2 : i32):
  %0 = llvm.mlir.constant(24 : i32) : i32
  %1 = llvm.lshr %arg2, %0 : i32
  %2 = llvm.trunc %1 : i32 to i8
  %3 = llvm.sext %2 : i8 to i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

Fin.instOfNat in Init.Data.Fin.Basic

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

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

def sub_mask1_lshr_after := [llvm|
{
^0(%arg21 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.mlir.constant(7 : i8) : i8
  %2 = llvm.mlir.constant(10 : i8) : i8
  %3 = llvm.shl %arg21, %0 : i8
  %4 = llvm.ashr %3, %1 : i8
  %5 = llvm.add %4, %2 overflow<nsw> : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

def n1_before := [llvm|
{
^0(%arg3 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.shl %arg3, %0 : i8
  %2 = llvm.lshr exact %1, %0 : i8
  %3 = llvm.icmp "ne" %2, %arg3 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

def Pointer.offsetInBits (p : Pointer) : Nat :=
  8 * p.offset.toNat

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

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

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

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

def Reflect.Map.get (ix : ℕ) (_ : BitVec w)  (m : List (BitVec w)) : BitVec w := m[ix]!

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

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

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

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

@[match_pattern] abbrev lshr (w : Nat) (flag : ExactFlag := {} ) : LLVM.Op := MOp.lshr (.concrete w) flag

private def fhe_test_one_rhs := [poly q, n, h | {
  ^bb0(%a : !R):
    return %a : !R
  }]

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

def tryFactorization_add_nuw_mul_nuw_mul_nuw_var_after := [llvm|
{
^0(%arg9 : i32, %arg10 : i32, %arg11 : i32):
  %0 = llvm.add %arg10, %arg11 : i32
  %1 = llvm.mul %arg9, %0 overflow<nuw> : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

instance : DialectSignature Ex where
  signature
    | .add    => ⟨[.nat, .nat], [], [.nat], .pure⟩
    | .beq    => ⟨[.nat, .nat], [], [.bool], .pure⟩
    | .cst _  => ⟨[], [], [.nat], .pure⟩

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

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

def positive_samevar_shlnsw_lshrexact_after := [llvm|
{
^0(%arg37 : i8, %arg38 : i8):
  "llvm.return"(%arg37) : (i8) -> ()
}
]

def sub_ashr_or_i8_before := [llvm|
{
^0(%arg39 : i8, %arg40 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.sub %arg40, %arg39 overflow<nsw> : i8
  %2 = llvm.ashr %1, %0 : i8
  %3 = llvm.or %2, %arg39 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

def rewritePeepholeRecursivelyExpr (fuel : ℕ)
    (pr : PeepholeRewrite d Γ t) {ty}
    (e : Expr d Γ₂ eff ty) : { out : Expr d Γ₂ eff ty // out.denote = e.denote } :=
  match e with
  | Expr.mk op ty eff' args regArgs =>
    let ⟨regArgs', hregArgs'⟩ := rewritePeepholeRecursivelyRegArgs fuel pr regArgs
    ⟨Expr.mk op ty eff' args regArgs', by admit /- proof elided -/
      ⟩
termination_by (fuel + 1, 0)

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

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

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

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

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

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

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

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

RV64.bseti in RISCV.Instructions

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

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

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

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

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

List.Vector.ofFn in Mathlib.Data.Vector.Defs

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

HDiv in Init.Prelude

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

def PR39793_bswap_u32_as_u16_trunc_before := [llvm|
{
^0(%arg24 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(255 : i32) : i32
  %2 = llvm.mlir.constant(65280 : i32) : i32
  %3 = llvm.lshr %arg24, %0 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.shl %arg24, %0 : i32
  %6 = llvm.and %5, %2 : i32
  %7 = llvm.or %4, %6 : i32
  %8 = llvm.trunc %7 : i32 to i8
  "llvm.return"(%8) : (i8) -> ()
}
]

instance : ToMessageData FpPredicate where
  toMessageData p := toString p

GetElem? in Init.GetElem

def eq_commuted_after := [llvm|
{
^0(%arg2 : i8, %arg3 : i8):
  %0 = llvm.mlir.constant(43 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.sdiv %0, %arg3 : i8
  %3 = llvm.add %arg2, %1 : i8
  %4 = llvm.icmp "uge" %3, %2 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

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

def a_false_implies_b_true_before := [llvm|
{
^0(%arg15 : i8, %arg16 : i1, %arg17 : i1):
  %0 = llvm.mlir.constant(10 : i8) : i8
  %1 = llvm.mlir.constant(20 : i8) : i8
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.icmp "ugt" %arg15, %0 : i8
  %4 = llvm.icmp "ult" %arg15, %1 : i8
  %5 = "llvm.select"(%4, %arg16, %arg17) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %6 = "llvm.select"(%3, %2, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def bools_logical_commute0_and2_after := [llvm|
{
^0(%arg102 : i1, %arg103 : i1, %arg104 : i1):
  %0 = "llvm.select"(%arg104, %arg103, %arg102) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

Lean.addAndCompile in Lean.AddDecl

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

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

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

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

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

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

Sum.elim in Init.Data.Sum.Basic

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

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

@[inline]
def CNFA.proj (m: CNFA n2) (f : Fin n1 → Fin n2) : CNFA n1 :=
  ⟨m.m.proj f, m.m.proj_wf m.wf⟩

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

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 scalar_i32_shl_and_negC_slt_before := [llvm|
{
^0(%arg2 : i32, %arg3 : i32):
  %0 = llvm.mlir.constant(-8 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %arg2, %arg3 : i32
  %3 = llvm.and %2, %0 : i32
  %4 = llvm.icmp "slt" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

def or_eq_with_one_bit_diff_constants2_before := [llvm|
{
^0(%arg362 : i32):
  %0 = llvm.mlir.constant(97 : i32) : i32
  %1 = llvm.mlir.constant(65 : i32) : i32
  %2 = llvm.icmp "eq" %arg362, %0 : i32
  %3 = llvm.icmp "eq" %arg362, %1 : i32
  %4 = llvm.or %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

RV64.div in RISCV.Instructions

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

def bw (w : Nat) (x : BitVec v) : BitVec w := x.signExtend w

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

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

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

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

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

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

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

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

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

def udiv_common_divisor_before := [llvm|
{
^0(%arg65 : i1, %arg66 : i5, %arg67 : i5, %arg68 : i5):
  %0 = llvm.udiv %arg67, %arg66 : i5
  %1 = llvm.udiv %arg68, %arg66 : i5
  %2 = "llvm.select"(%arg65, %1, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i5, i5) -> i5
  "llvm.return"(%2) : (i5) -> ()
}
]

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

def test14_commuted_after := [llvm|
{
^0(%arg174 : i32, %arg175 : i32):
  %0 = llvm.xor %arg174, %arg175 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

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

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

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

def slt_or_not_max_commute_after := [llvm|
{
^0(%arg58 : i8, %arg59 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.icmp "ne" %arg58, %0 : i8
  "llvm.return"(%1) : (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 Region.appendOps (bb: Region φ) (ops: List (Op φ)): Region φ :=
  match bb with
  | Region.mk name args bbs => Region.mk name args (bbs ++ ops)

def Tensor2d'.error (α : Type) : Tensor2d' α where
  dim₀ := 0
  dim₁ := 0
  mat := Matrix.of fun x _y => x.elim0

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

instance (priority := low) : Monad (pure.toMonad m) :=

unsafe def elabIntoEIO {α : Type} (env : Lean.Environment) (typeName : Lean.Expr)
    (stx : Lean.Syntax) : EIO ParseError α :=
  fun s =>
    let resE : EIO Exception α :=
        elabIntoCore (α := α) typeName stx |>.run'
        {fileName := "parserHack", fileMap := default, maxHeartbeats := 0} {env := env}
    match resE s with
    | .ok a s => .ok a s
    | .error exception s =>
      let errMsgIO : IO String := exception.toMessageData.toString
      match errMsgIO s with
      | .ok errMsg s => .error s!"failed elaboration {stx}. Error: {errMsg}" s
      | .error e s => .error (s!" Failed elaborating {stx}.\n" ++
        s!"Unable to pretty-print exception at 'elabIntoEIO':\n{e}.") s

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

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

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

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

partial def toBVExpr (expr : Expr) (width: Nat) : ParseExprM (Option (BVExprWrapper)) := do
  go expr
  where

  go (x : Expr) : ParseExprM (Option (BVExprWrapper)) := do
    match_expr x with
    | HAnd.hAnd _ _ resType _ lhsExpr rhsExpr =>
        binaryReflection lhsExpr rhsExpr resType BVBinOp.and
    | HXor.hXor _ _ resType _ lhsExpr rhsExpr =>
        binaryReflection lhsExpr rhsExpr resType BVBinOp.xor
    | HAdd.hAdd _ _ resType _ lhsExpr rhsExpr =>
        binaryReflection lhsExpr rhsExpr resType BVBinOp.add
    | HOr.hOr _ _ resType _ lhsExpr rhsExpr =>
        binaryReflection lhsExpr rhsExpr resType BVBinOp.or
    | HSub.hSub _ _ resType _ lhsExpr rhsExpr =>
        let some lhs ← go lhsExpr | return none
        let some rhs ← go rhsExpr | return none
        let some w ← getWidth? resType | return none
        if h : lhs.width = w ∧ rhs.width = lhs.width then
          let rhs' := h.right ▸ rhs.bvExpr
          return some {bvExpr := subtract lhs.bvExpr rhs', width := lhs.width}
        else
          return none
    | HMul.hMul _ _ resType _ lhsExpr rhsExpr =>
        binaryReflection lhsExpr rhsExpr resType BVBinOp.mul
    | HDiv.hDiv _ _ resType _ lhsExpr rhsExpr =>
        binaryReflection lhsExpr rhsExpr resType BVBinOp.udiv
    | HMod.hMod _ _ resType _ lhsExpr rhsExpr =>
        binaryReflection lhsExpr rhsExpr resType BVBinOp.umod
    | Complement.complement _ _ innerExpr => 
        let some inner ← go innerExpr | return none
        return some {bvExpr := GenBVExpr.un BVUnOp.not inner.bvExpr, width := inner.width}
    | HShiftLeft.hShiftLeft _ _ resType _ innerExpr distanceExpr =>
        shiftReflection innerExpr distanceExpr resType GenBVExpr.shiftLeft
    | HShiftRight.hShiftRight _ _ resType _ innerExpr distanceExpr =>
        shiftReflection innerExpr distanceExpr resType GenBVExpr.shiftRight
    | BitVec.sshiftRight _ resType innerExpr distanceExpr =>
        shiftReflection innerExpr distanceExpr resType GenBVExpr.arithShiftRight
    | BitVec.sshiftRight' _ resType innerExpr distanceExpr =>
        shiftReflection innerExpr distanceExpr resType GenBVExpr.arithShiftRight
    | HAppend.hAppend _ _ _ _ lhsExpr rhsExpr =>
        let some lhs ← go lhsExpr | return none
        let some rhs ← go rhsExpr | return none
        return some {bvExpr := GenBVExpr.append lhs.bvExpr rhs.bvExpr rfl, width := _}
    | BitVec.extractLsb' _ _ _ _ =>
        throwError m! "Does not support BitVec.extractLsb' operations"
    | BitVec.rotateLeft resType innerExpr distanceExpr =>
        rotateReflection innerExpr distanceExpr resType BVUnOp.rotateLeft
    | BitVec.rotateRight resType innerExpr distanceExpr =>
        rotateReflection innerExpr distanceExpr resType BVUnOp.rotateRight
    | BitVec.signExtend _ vExpr xExpr =>
        let some v ← getNatValue? vExpr | return none
        let some x ← go xExpr | return none

        storeWidth v
        return some {bvExpr := GenBVExpr.signExtend v x.bvExpr, width := v}
    | BitVec.zeroExtend _ vExpr xExpr =>
        let some v ← getNatValue? vExpr | return none
        let some x ← go xExpr | return none
        storeWidth v
        return some {bvExpr := GenBVExpr.zeroExtend v x.bvExpr, width := v}
    | BitVec.truncate _ vExpr xExpr =>
      let some v ← getNatValue? vExpr | return none
      let some x ← go xExpr | return none
      storeWidth v
      return some {bvExpr := GenBVExpr.truncate v x.bvExpr, width := _}
    | Neg.neg _ _ a =>
          let some (bvProd) ← getBitVecValue? a| return none
          let pbv := {bv := -bvProd.snd: BVExpr.PackedBitVec}

          return (← processBitVec pbv)

    | _ =>
        let natVal ← getNatValue? x
        let bitVecVal ← getBitVecValue? x

        match (natVal, bitVecVal) with
        | (some v, none) =>
              let currState: ParsedInputState  ← get
              let pbv : BVExpr.PackedBitVec := {bv := BitVec.ofNat currState.originalWidth v}
              let existingVal :=  currState.valToSymVar[pbv]?

              match existingVal with
              | none => let numSymVars := currState.numSymVars
                        let newId := 1001 + numSymVars
                        let newExpr : GenBVExpr width := GenBVExpr.var newId
                        let userFacingName := Lean.Name.mkSimple s!"C{numSymVars + 1}"
                        let var : HydraVariable := {name := userFacingName, id := newId, width := width}

                        let updatedState : ParsedInputState  := { currState with
                                                                numSymVars := numSymVars + 1
                                                                , symVarToVal := currState.symVarToVal.insert newId pbv
                                                                , valToSymVar := currState.valToSymVar.insert pbv newId
                                                                , displayNameToVariable := currState.displayNameToVariable.insert userFacingName var
                                                                , symVarIdToVariable := currState.symVarIdToVariable.insert newId var}
                        set updatedState
                        return some {bvExpr := newExpr, width := width}
              | some var => let newExpr : GenBVExpr width := GenBVExpr.var var
                            return some {bvExpr := newExpr, width := width}

        | (none, some bvProd) =>
              let pbv : BVExpr.PackedBitVec := {bv := bvProd.snd: BVExpr.PackedBitVec}
              return (← processBitVec pbv)
        | _ =>
            let currState: ParsedInputState ← get
            let localDecl ← getFVarLocalDecl x
            let userFacingName := localDecl.userName
            let some w ← getWidth? localDecl.type | return none

            let existingVar? := currState.displayNameToVariable[userFacingName]?
            match existingVar? with
            | some val => return some {bvExpr := GenBVExpr.var val.id, width := val.width}
            | none =>
                let newId := currState.maxFreeVarId + 1
                let newExpr : GenBVExpr w :=  GenBVExpr.var newId

                let var : HydraVariable := {name := userFacingName, id := newId, width := w}
                let updatedState : ParsedInputState :=  { currState with
                                                         maxFreeVarId := newId
                                                         , displayNameToVariable := currState.displayNameToVariable.insert userFacingName var
                                                         , inputVarIdToVariable := currState.inputVarIdToVariable.insert newId var
                                                         }
                set updatedState
                storeWidth w
                return some {bvExpr := newExpr, width := w}

  storeWidth (v: Nat) : ParseExprM Unit := do
    let currState ← get

    if !currState.widthValToVar.contains v then
      let newWidthId := currState.maxWidthId + 1
      let userFacingName := Lean.Name.mkSimple s!"w{currState.widthIdToVariable.size + 1}"
      let var : HydraVariable := {name := userFacingName, id := newWidthId, width := v}
      let updatedState : ParsedInputState := { currState with maxWidthId := newWidthId, widthIdToVariable := currState.widthIdToVariable.insert newWidthId var, widthValToVar := currState.widthValToVar.insert v var}
      set updatedState

  rotateReflection (innerExpr distanceExpr resType: Expr) (rotateOp: Nat → BVUnOp)
          : ParseExprM (Option (BVExprWrapper)) := do
      let some inner ← go innerExpr | return none
      let some distance ← getNatValue? distanceExpr | return none
      let some w ← getWidth? resType | return none

      if w == inner.width then
        return some {bvExpr := GenBVExpr.un (rotateOp distance) inner.bvExpr, width := inner.width}
      else return none

  binaryReflection (lhsExpr rhsExpr resType : Expr) (op : BVBinOp) : ParseExprM (Option (BVExprWrapper)) := do
    let some lhs ← go lhsExpr | return none
    let some rhs ← go rhsExpr | return none
    let some w ← getWidth? resType | return none

    if h : w = lhs.width ∧ lhs.width = rhs.width then
      let rhs' := h.right ▸ rhs.bvExpr
      return some {bvExpr := GenBVExpr.bin lhs.bvExpr op rhs', width := lhs.width}
    else
      return none

  shiftReflection (innerExpr distanceExpr resType: Expr) (shiftOp : {m n : Nat} → GenBVExpr m → GenBVExpr n → GenBVExpr m)
        : ParseExprM (Option (BVExprWrapper)) := do
      let some inner ← go innerExpr | return none
      let some distance ← go distanceExpr | return none
      let some w ← getWidth? resType | return none

      if w == inner.width then
        return some {bvExpr :=  shiftOp inner.bvExpr distance.bvExpr, width := inner.width}
      else return none


  getConstantBVExpr? (nExpr : Expr) (vExpr : Expr) : ParseExprM (Option (BVExprWrapper)) := do
        let some n  ← getNatValue? nExpr | return none
        let some v ← getNatValue? vExpr | return none

        return some {bvExpr := GenBVExpr.const (BitVec.ofNat n v), width := n}

  getBitVecValue? (e : Expr) : MetaM (Option ((n : Nat) × BitVec n)) := OptionT.run do
    match_expr e with
    | BitVec.ofNat nExpr vExpr =>
      let n ← getNatValue? nExpr
      let v ← getNatValue? vExpr
      return ⟨n, BitVec.ofNat n v⟩
    | BitVec.ofNatLT nExpr vExpr _ =>
      let n ← getNatValue? nExpr
      let v ← getNatValue? vExpr
      return ⟨n, BitVec.ofNat n v⟩
    | BitVec.ofInt nExpr vExpr =>
      let n ← getNatValue? nExpr
      let v ← getIntValue? vExpr
      return ⟨n, BitVec.ofInt n v⟩
    
    
    | BitVec.allOnes nExpr =>
      let n ← getNatValue? nExpr
      return ⟨n, BitVec.allOnes n⟩
    | _ =>
      let (v, type) ← getOfNatValue? e ``BitVec
      let n ← getNatValue? (← whnfD type.appArg!)
      return ⟨n, BitVec.ofNat n v⟩

  getWidth? (typeExpr : Expr) : MetaM (Option Nat) := do
    match_expr typeExpr with
    | BitVec n => getNatValue? n
    | _ => getNatValue? typeExpr

  processBitVec (pbv : BVExpr.PackedBitVec) : ParseExprM (Option BVExprWrapper) := do
    let currState: ParsedInputState ← get
    let existingVal :=  currState.valToSymVar[pbv]?
    match existingVal with
    | none =>
      let numSymVars := currState.numSymVars
      let newId := 1001 + numSymVars
      let newExpr : GenBVExpr pbv.w := GenBVExpr.var newId

      let userFacingName := Lean.Name.mkSimple s!"C{numSymVars + 1}"
      let var : HydraVariable := {name := userFacingName, id := newId, width := pbv.w}

      let updatedState : ParsedInputState := { currState with
                                              numSymVars := numSymVars + 1
                                              , symVarToVal := currState.symVarToVal.insert newId pbv
                                              , valToSymVar := currState.valToSymVar.insert pbv newId
                                              , displayNameToVariable := currState.displayNameToVariable.insert userFacingName var
                                              , symVarIdToVariable := currState.symVarIdToVariable.insert newId var}
      set updatedState
      return some {bvExpr := newExpr, width := pbv.w}
    | some var => let newExpr : GenBVExpr pbv.w := GenBVExpr.var var
                  return some {bvExpr := newExpr, width := pbv.w}

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

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

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

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

def bar_before := [llvm|
{
^0(%arg109 : i32, %arg110 : i32, %arg111 : i32, %arg112 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.icmp "slt" %arg109, %arg110 : i32
  %2 = llvm.sext %1 : i1 to i32
  %3 = llvm.and %arg111, %2 : i32
  %4 = llvm.xor %2, %0 : i32
  %5 = llvm.and %arg112, %4 : i32
  %6 = llvm.or %5, %3 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

@[simp]
def Env.getElem_ofEnvFin (envFin : EnvFin w n) (i : Nat) (h : i < n) :
    (Env.ofEnvFin envFin)[i]'(by simp [Env.length_ofEnvFin, h]) = envFin ⟨i, by omega⟩ :=

def TypedSSAVal.mkVal [instTransformTy : TransformTy d φ] (Γ : Ctxt d.Ty) : TypedSSAVal φ →
    ReaderM d (Σ (ty : d.Ty), Ctxt.Var Γ ty)
| (.name valStx, tyStx) => do
    let ty ← instTransformTy.mkTy tyStx
    let var ← getValFromCtxt Γ valStx ty
    return ⟨ty, var⟩

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

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

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

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

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

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

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

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

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

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

def reduce_xor_common_op_commute1_after := [llvm|
{
^0(%arg7 : i4, %arg8 : i4, %arg9 : i4):
  %0 = llvm.xor %arg8, %arg9 : i4
  %1 = llvm.or %0, %arg7 : i4
  "llvm.return"(%1) : (i4) -> ()
}
]

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

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

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

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

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

BitVec.cons in Init.Data.BitVec.Basic

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

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

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 llvm_trunc_riscv_32_to_8_nuw_nsw : LLVMPeepholeRewriteRefine 8 [Ty.llvm (.bitvec 32)] :=
  {lhs:= trunc_llvm_32_to_8_nsw_nuw, rhs:= trunc_riscv_32_to_8_nsw_nuw}

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

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

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

def abs_diff_signed_slt_swap_wrong_pred1_before := [llvm|
{
^0(%arg15 : i32, %arg16 : i32):
  %0 = llvm.icmp "eq" %arg15, %arg16 : i32
  %1 = llvm.sub %arg16, %arg15 overflow<nsw> : i32
  %2 = llvm.sub %arg15, %arg16 overflow<nsw> : i32
  %3 = "llvm.select"(%0, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

Lean.mkApp3 in Lean.Expr

def cadicalTimeoutSec : Nat := 1000

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

@[simp_denote]
def sra_llvm_i32 := [LV| {
    ^entry (%a: i32, %b: i32):
    %0 = llvm.ashr %a, %b : i32
    llvm.return %0 : i32
  }]

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 icmp_slt_0_or_icmp_add_1_sge_100_i32_fail_after := [llvm|
{
^0(%arg38 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(99 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.add %arg38, %0 : i32
  %4 = llvm.icmp "sgt" %3, %1 : i32
  %5 = llvm.icmp "slt" %arg38, %2 : i32
  %6 = llvm.or %5, %4 : i1
  %7 = llvm.zext %6 : i1 to i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

def test19_before := [llvm|
{
^0(%arg192 : i32, %arg193 : i32):
  %0 = llvm.xor %arg192, %arg193 : i32
  %1 = llvm.xor %0, %arg192 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

Lean.Parser.Tactic.tacticSeq in Lean.Parser.Term.Basic

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

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

instance (e : Eqn) : Decidable (∀ env1 : EnvFin 1 e.numVars, Eqn.denoteFin e env1 = 0) :=
  let ⟨allEnvs, hAllEnvs⟩ := EnvFin.getAll1 e.numVars
  let b := allEnvs.all (fun env1 => e.denoteFin env1 = 0)
  match hb : b with
  | true => .isTrue <| by
    simp [b] at hb
    intros env1
    apply hb
    apply hAllEnvs
  | false => .isFalse <| by
    simp
    simp [b] at hb
    obtain ⟨env, henvMem, henvDenote⟩ := hb
    exists env

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

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

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

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

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

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

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

noncomputable def R.fromTensor' (coeffs : List Int) : (ZMod q)[X] :=
  coeffs.zipIdx.foldl (init := 0) fun res (c, i) =>
    res + (Polynomial.monomial i ↑c)

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

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

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

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

Int.lt in Init.Data.Int.Basic

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

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

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

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

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

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

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

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

def test7_before := [llvm|
{
^0(%arg0 : i47):
  %0 = llvm.mlir.constant(70368744177663 : i47) : i47
  %1 = llvm.mlir.constant(703687463 : i47) : i47
  %2 = llvm.or %arg0, %0 : i47
  %3 = llvm.xor %2, %1 : i47
  "llvm.return"(%3) : (i47) -> ()
}
]

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

Fin.castLT in Init.Data.Fin.Basic

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

def ugt_umax2_after := [llvm|
{
^0(%arg34 : i32, %arg35 : i32):
  %0 = llvm.icmp "ugt" %arg35, %arg34 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

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

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

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

Function.uncurry in Init.Data.Function

def sel_zext_after := [llvm|
{
^0(%arg89 : i32, %arg90 : i1):
  %0 = llvm.mlir.constant(42) : i64
  %1 = llvm.zext %arg89 : i32 to i64
  %2 = "llvm.select"(%arg90, %1, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%2) : (i64) -> ()
}
]

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

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

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

def slt_and_shl_one_after := [llvm|
{
^0(%arg25 : i8, %arg26 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.shl %0, %arg26 overflow<nuw> : i8
  %2 = llvm.and %arg25, %1 : i8
  %3 = llvm.icmp "slt" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

Prod.mk in Init.Prelude

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

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

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

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

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

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

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

BitVec.sshiftRight' in Init.Data.BitVec.Basic

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

def test_or_eq_a_b_after := [llvm|
{
^0(%arg36 : i1, %arg37 : i8, %arg38 : i8):
  %0 = "llvm.select"(%arg36, %arg37, %arg38) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%0) : (i8) -> ()
}
]

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

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

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

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

def test_sge_xor_after := [llvm|
{
^0(%arg38 : i32, %arg39 : i32):
  %0 = llvm.xor %arg39, %arg38 : i32
  %1 = llvm.icmp "sle" %0, %arg38 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

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

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

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

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

def List.product (l₁ : List α) (l₂ : List β) : List (α × β) := l₁.flatMap fun a => l₂.map (Prod.mk a)

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

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

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

def test10_after := [llvm|
{
^0(%arg13 : i32):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.mlir.constant(65535 : i32) : i32
  %2 = llvm.lshr %arg13, %0 : i32
  %3 = llvm.mul %2, %1 overflow<nuw> : i32
  %4 = llvm.zext %3 : i32 to i64
  "llvm.return"(%4) : (i64) -> ()
}
]

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

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

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

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

def t0_lshr_after := [llvm|
{
^0(%arg30 : i32, %arg31 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.shl %0, %arg31 overflow<nsw> : i32
  %2 = llvm.and %1, %arg30 : i32
  %3 = llvm.lshr exact %2, %arg31 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

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

def freeze_match : List (Σ Γ, Σ ty, PeepholeRewrite LLVMPlusRiscV Γ ty) := [
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_freeze_lower_riscv_8),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_freeze_lower_riscv_16),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_freeze_lower_riscv_32),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_freeze_lower_riscv_64)
]

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

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

RV64.sh2adduw in RISCV.Instructions

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

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

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

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

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

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

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

BitVec.signExtend in Init.Data.BitVec.Basic

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

Finsupp in Mathlib.Data.Finsupp.Defs

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

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

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

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 foo_after := [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.select"(%3, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %5 = llvm.add %arg54, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

def test24_before := [llvm|
{
^0(%arg53 : i32):
  %0 = llvm.mlir.constant(-2147483648 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.urem %arg53, %0 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

def or_not_and_wrong_b_before := [llvm|
{
^0(%arg484 : i32, %arg485 : i32, %arg486 : i32, %arg487 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg484, %arg485 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.and %2, %arg486 : i32
  %4 = llvm.or %arg484, %arg486 : i32
  %5 = llvm.xor %4, %0 : i32
  %6 = llvm.and %5, %arg487 : i32
  %7 = llvm.or %3, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

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

def sub_shl_same_amount_partial_nuw1_before := [llvm|
{
^0(%arg5 : i6, %arg6 : i6, %arg7 : i6):
  %0 = llvm.shl %arg5, %arg7 overflow<nuw> : i6
  %1 = llvm.shl %arg6, %arg7 overflow<nuw> : i6
  %2 = llvm.sub %0, %1 : i6
  "llvm.return"(%2) : (i6) -> ()
}
]

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

Set.compl in Mathlib.Data.Set.Defs

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 and_logic_and_logic_or_1_before := [llvm|
{
^0(%arg138 : i1, %arg139 : i1, %arg140 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.and %arg138, %arg139 : i1
  %3 = "llvm.select"(%arg138, %arg140, %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 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) -> ()
}
]

propext in Init.Core

def test_mul_nuw_nsw__none_are_safe_after := [llvm|
{
^0(%arg3 : i32):
  %0 = llvm.mlir.constant(9 : i32) : i32
  %1 = llvm.mul %arg3, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def lshr_xor_or_good_mask_after := [llvm|
{
^0(%arg108 : i8, %arg109 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.mlir.constant(48 : i8) : i8
  %2 = llvm.or %arg109, %arg108 : i8
  %3 = llvm.lshr %2, %0 : i8
  %4 = llvm.or disjoint %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

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

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

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

Function.Injective2 in Mathlib.Logic.Function.Basic

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

def llvm_const_lower_riscv_li14 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM14, rhs:= liRiscv14,
   correct := by admit /- proof elided -/

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

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

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

def t1_flags_nuw_nsw_second_before := [llvm|
{
^0(%arg30 : i8, %arg31 : i8, %arg32 : i8):
  %0 = llvm.sub %arg30, %arg31 : i8
  %1 = llvm.sub %0, %arg32 overflow<nsw,nuw> : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

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

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

abbrev DC : Dialect where
  Op := Op
  Ty := Ty

def_signature for DC where
  | .fst => (Ty.tokenstream2) → (Ty.tokenstream)
  | .fstVal t => (Ty.valuetokenstream t) → Ty.valuestream t
  | .fstVal' t => (Ty.variadicvaluetokenstream t) → Ty.valuestream t
  | .snd => (Ty.tokenstream2) → (Ty.tokenstream)
  | .pair w => (Ty.valuestream w, Ty.valuestream w) → Ty.valuestream2 w
  | .sndVal t => (Ty.valuetokenstream t) → Ty.tokenstream
  | .sndVal' t => (Ty.variadicvaluetokenstream t) → Ty.valuestream t
  | .tokVal' t => (Ty.variadicvaluetokenstream t) → Ty.tokenstream
  | .merge => (Ty.tokenstream, Ty.tokenstream) → Ty.valuestream 1
  | .branch => (Ty.valuestream 1) → Ty.tokenstream2
  | .fork => (Ty.tokenstream) → Ty.tokenstream2
  | .join => (Ty.tokenstream, Ty.tokenstream) → Ty.tokenstream
  | .select => (Ty.tokenstream, Ty.tokenstream, Ty.valuestream 1) → Ty.tokenstream
  | .sink => (Ty.tokenstream) → Ty.tokenstream
  | .source => () → Ty.tokenstream
  | .pack t => (Ty.valuestream t, Ty.tokenstream) → Ty.valuestream t
  | .pack2 t => (Ty.variadicvaluetokenstream t) → Ty.valuestream2 t
  | .unpack t => (Ty.valuestream t) → Ty.valuetokenstream t
  | .unpack2 t => (Ty.valuestream t, Ty.valuestream t) → Ty.variadicvaluetokenstream t

def andcond.100.inv.inner.cond.in.outer.cond_before := [llvm|
{
^0(%arg55 : i1, %arg56 : i1, %arg57 : i8, %arg58 : i8, %arg59 : i8):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.xor %arg55, %0 : i1
  %3 = "llvm.select"(%2, %arg56, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = "llvm.select"(%arg55, %arg57, %arg58) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %5 = "llvm.select"(%3, %arg59, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

Lean.Meta.check in Lean.Meta.Check

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

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

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

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

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

def lshr_32_add_not_known_32_leading_zeroes_before := [llvm|
{
^0(%arg13 : i64, %arg14 : i64):
  %0 = llvm.mlir.constant(8589934591) : i64
  %1 = llvm.mlir.constant(4294967295) : i64
  %2 = llvm.mlir.constant(32) : i64
  %3 = llvm.and %arg13, %0 : i64
  %4 = llvm.and %arg14, %1 : i64
  %5 = llvm.add %3, %4 : i64
  %6 = llvm.lshr %5, %2 : i64
  "llvm.return"(%6) : (i64) -> ()
}
]

abbrev ParsedBVLogicalExpr := ParsedLogicalExpr ParsedBVExpr GenBVPred

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

Membership in Init.Prelude

instance : Inhabited (IntW w) :=

def tacName : String := "bv_automata_gen"

instance : MLIR.AST.TransformReturn (Handshake) 0 where
  mkReturn := mkReturn

def sub_select_not_zext_after := [llvm|
{
^0(%arg22 : i1, %arg23 : i64):
  %0 = llvm.mlir.constant(63) : i64
  %1 = "llvm.select"(%arg22, %arg23, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%1) : (i64) -> ()
}
]

def xor_ugt_2_before := [llvm|
{
^0(%arg13 : i8, %arg14 : i8, %arg15 : i8):
  %0 = llvm.mlir.constant(63 : i8) : i8
  %1 = llvm.mlir.constant(64 : i8) : i8
  %2 = llvm.add %arg13, %arg15 : i8
  %3 = llvm.and %arg14, %0 : i8
  %4 = llvm.or %3, %1 : i8
  %5 = llvm.xor %2, %4 : i8
  %6 = llvm.icmp "ugt" %2, %5 : i8
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

Union in Init.Core
</all_available_defs>

<all_available_lemmas>
BitVec.toNat_eq in Init.Data.BitVec.Lemmas
Nat.le_antisymm in Init.Prelude
BitVec.toInt_inj in Init.Data.BitVec.Lemmas
le_iff_lt_or_eq in Mathlib.Order.Defs.PartialOrder

theorem List.getElem_append_left{α : Type u_1} {l₁ l₂ : List α} {i : Nat} (hn : i < l₁.length) :\n(l₁ ++ l₂)[i] = l₁[i]

theorem in_constant_14_vary_proof : in_constant_14_vary_before ⊑ in_constant_14_vary_after

@[simp, simp_denote] theorem nil_isRefinedBy_nil    : (nil : HVector A _) ⊑ (nil : HVector B _)

theorem Tensor2d'.transpose_transpose (t : Tensor2d' α) : t.transpose.transpose = t

theorem udiv_i32_c_thm (e : IntW 8) :
  LLVM.udiv (zext 32 e) (const? 32 10) ⊑ zext 32 (LLVM.udiv e (const? 8 10)) { «nneg» := true }

theorem ashrsgt_02_05_proof : ashrsgt_02_05_before ⊑ ashrsgt_02_05_after

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

theorem shl_add_proof : shl_add_before ⊑ shl_add_after

theorem main3c_proof : main3c_before ⊑ main3c_after

theorem icmp_eq_x_invertable_y2_todo_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  x_2 = 1#1 → ofBool (7#8 == x ||| 7#8) = ofBool (x &&& BitVec.ofInt 8 (-8) == 0#8)

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

theorem e_323 :
    4 *  ~~~(x &&& y) + 11 * x + 3 *  ~~~y - 1 * (x ||| y) - 10 *  ~~~(x |||  ~~~y) - 24 * (x &&&  ~~~y) - 10 * (x &&& y) =  - 7 * (x ^^^ y) + 7 *  ~~~(x ||| y)

theorem sdiv_icmp3_proof : sdiv_icmp3_before ⊑ sdiv_icmp3_after

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 41), ofBool (x <ₛ 0#41) = 1#1 → 40#41 ≥ ↑41 → False

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

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

theorem add_1_proof : add_1_before ⊑ add_1_after

theorem test23_proof : test23_before ⊑ test23_after

theorem and_orn_cmp_1_proof : and_orn_cmp_1_before ⊑ and_orn_cmp_1_after

theorem e_1930 :
     - 1 * (c ^^^ ( ~~~a ||| (b ||| c))) - 7 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) + 1 *  ~~~( ~~~a ||| (b ^^^ c)) - 1 * (b &&& c) + 7 * ((a &&& c) ^^^ (a ^^^ (b &&& c))) + 11 * (c ||| (a ^^^ b)) - 2 * (a ^^^ ( ~~~b ||| c)) - 1 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) - 3 * (c ^^^  ~~~(a &&& b)) - 3 * (b ^^^  ~~~(a &&& c)) + 1 * (c &&&  ~~~(a ^^^ b)) + 7 * ((a &&& c) |||  ~~~(b ||| c)) - 7 * (b ^^^ ( ~~~a ||| (b ||| c))) + 2 * (c ^^^ ( ~~~a &&& ( ~~~b ||| c))) + 5 *  ~~~(a ^^^ (b ^^^ c)) - 1 * (c ^^^ (a ||| (b &&& c))) - 6 * (c ^^^  ~~~(a ||| b)) - 5 * (a ^^^ (b &&& c)) + 2 * ((a ||| b) &&& (b ^^^ c)) + 1 * c + 1 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 1 * (c ^^^  ~~~(a |||  ~~~b)) + 4 * (a ||| (b ^^^ c)) - 6 *  ~~~(a &&& (b ||| c)) - 11 * (c ^^^ ( ~~~a ||| (b &&& c))) - 3 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) - 3 * (b ^^^ (a &&& (b ^^^ c))) + 1 * ((b &&& c) ||| (a &&& (b ||| c))) + 1 * (c ^^^ (a &&& b)) - 7 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) + 4 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 3 * (a ^^^ b) - 7 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) + 1 * (b |||  ~~~(a ^^^ c)) - 2 * (c ^^^  ~~~(a &&& (b ||| c))) - 2 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) + 1 *  ~~~(a ^^^ c) + 2 * (b ||| (a ^^^ c)) + 5 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) - 11 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) + 7 * (a ||| b) + 1 * ( ~~~a &&& (b ^^^ c)) + 4 *  ~~~(a |||  ~~~b) + 5 *  ~~~( ~~~a &&& (b &&& c)) + 38 *  ~~~(a ||| (b ||| c)) + 9 *  ~~~(a ||| ( ~~~b ||| c)) - 10 *  ~~~( ~~~a ||| (b ||| c)) - 21 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 9 * ( ~~~a &&& ( ~~~b &&& c)) + 3 * ( ~~~a &&& (b &&& c)) - 7 * (a &&& ( ~~~b &&& c)) - 5 * (a &&& (b &&& c)) =  - 1 * (b ^^^  ~~~(a &&&  ~~~c))

theorem sub_ashr_or_i32_proof : sub_ashr_or_i32_before ⊑ sub_ashr_or_i32_after

theorem bor_lor_right2_proof : bor_lor_right2_before ⊑ bor_lor_right2_after

theorem getPureExpr_eq_some
    (mapOut : MatchVarResult lets v (.var matchLets matchExpr) w.appendInl mapIn) :
    ∃ args, lets.getPureExpr v = some ⟨te, w, ⟨
        matchExpr.op,
        matchExpr.ty_eq,
        matchExpr.eff_le,
        args,
        matchExpr.regArgs
      ⟩⟩

theorem icmp_shl_uge_2_proof : icmp_shl_uge_2_before ⊑ icmp_shl_uge_2_after

theorem sext_xor_sub_2_thm (e : IntW 64) (e_1 : IntW 1) :
  sub (sext 64 e_1) (LLVM.xor e (sext 64 e_1)) ⊑ select e_1 e (sub (const? 64 0) e)

theorem sext_sext_slt_proof : sext_sext_slt_before ⊑ sext_sext_slt_after

theorem test1_thm (e : IntW 17) :
  trunc 17 (LLVM.or (lshr (zext 37 e) (const? 37 8)) (shl (zext 37 e) (const? 37 8))) ⊑
    LLVM.or (lshr e (const? 17 8)) (shl e (const? 17 8))

theorem e_1099 :
    11 *  ~~~z - 6 *  ~~~(z ^^^ t) - 5 * z + 1 *  ~~~(z &&&  ~~~z) + 7 * t + 4 * (z ^^^ t) - 6 *  ~~~(z ||| t) + 3 * (z &&& t) = 23 *  ~~~(z |||  ~~~t)

theorem and_ne_with_one_bit_diff_constants1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x != 51#32) &&& ofBool (x != 50#32) = ofBool (x + BitVec.ofInt 32 (-52) <ᵤ BitVec.ofInt 32 (-2))

theorem trunc_signed_nsw_sext_proof : trunc_signed_nsw_sext_before ⊑ trunc_signed_nsw_sext_after

theorem udiv_i32_proof : udiv_i32_before ⊑ udiv_i32_after

theorem in_constant_mone_vary_proof : in_constant_mone_vary_before ⊑ in_constant_mone_vary_after

theorem and_or_not_not_commute3_proof : and_or_not_not_commute3_before ⊑ and_or_not_not_commute3_after

theorem positive_biggerLshr_shlnuw_lshrexact_proof : positive_biggerLshr_shlnuw_lshrexact_before ⊑ positive_biggerLshr_shlnuw_lshrexact_after

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

theorem prove_exact_with_high_mask_limit_proof : prove_exact_with_high_mask_limit_before ⊑ prove_exact_with_high_mask_limit_after

theorem no_shift_no_xor_multiuse_cmp_with_xor_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 &&& 4096#32 == 0#32) = 1#1 → x_1 * x = (x_1 ^^^ x_2 &&& 4096#32) * x

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

theorem select_bittest_to_sub_proof : select_bittest_to_sub_before ⊑ select_bittest_to_sub_after

theorem ofBitVec_not_eqTo : ofBitVecSext (~~~ x) ≈ʷ ~~~ ofBitVecSext x

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

theorem lshrult_03_13_proof : lshrult_03_13_before ⊑ lshrult_03_13_after

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

theorem nonexact_lshr_eq_noexactdiv_thm (e : IntW 8) : icmp IntPred.eq (lshr (const? 8 80) e) (const? 8 31) ⊑ const? 1 0

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

theorem t0_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8) (x_3 : BitVec 1),
  x_3 ^^^ 1#1 ||

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

theorem positive_sameconst_lshrexact_thm (e : IntW 8) : shl (lshr e (const? 8 3) { «exact» := true }) (const? 8 3) ⊑ e

theorem test1_proof : test1_before ⊑ test1_after

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

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

theorem test1_proof : test1_before ⊑ test1_after

theorem ashr_icmp2_proof : ashr_icmp2_before ⊑ ashr_icmp2_after

theorem ashrsgt_03_01_proof : ashrsgt_03_01_before ⊑ ashrsgt_03_01_after

theorem mul_select_zext_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → 1#64 * zeroExtend 64 x = 0#64

theorem signbit_splat_mask_proof : signbit_splat_mask_before ⊑ signbit_splat_mask_after

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

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

theorem n10_wrong_low_bit_mask_proof : n10_wrong_low_bit_mask_before ⊑ n10_wrong_low_bit_mask_after

theorem or_xor_tree_0010_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_1 (const? 32 42))) (mul e_2 (const? 32 42))) ⊑
    LLVM.or (LLVM.xor (mul e_2 (const? 32 42)) (mul e_1 (const? 32 42))) (mul e (const? 32 42))

theorem or2 {v w k l : Nat} (a : BitVec k) : v < w ∨ w < v ∨ 
  (a.setWidth v).setWidth l = (a.setWidth w).setWidth l

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

theorem shl_C1_add_A_C2_i32_thm (e : IntW 16) :
  shl (const? 32 6) (add (zext 32 e) (const? 32 5)) ⊑ shl (const? 32 192) (zext 32 e { «nneg» := true })

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

omit [LawfulBEq A] [Fintype S] in
lemma processOneElem_rel {s₁ s₂ : State} :
    s₂ ~[(processOneElem A S final s₁ st (a, sa)).rel] sa' ↔
      (s₂ ~[st.rel] sa' ∨ (s₂ = st.m.stateMax ∧ sa' = sa ∧ st.map[sa']? = none))

@[simp]
theorem ofBitVec_getLsbD (n : Nat) (h : n < w) : ofBitVecSext x n = x.getLsbD n

theorem scalar_i8_shl_and_signbit_eq_proof : scalar_i8_shl_and_signbit_eq_before ⊑ scalar_i8_shl_and_signbit_eq_after

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

theorem test17_proof : test17_before ⊑ test17_after

theorem eq_umax1_proof : eq_umax1_before ⊑ eq_umax1_after

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

theorem ugt_umax1_proof : ugt_umax1_before ⊑ ugt_umax1_after

theorem select_icmp_eq_and_4096_0_xor_4096_proof : select_icmp_eq_and_4096_0_xor_4096_before ⊑ select_icmp_eq_and_4096_0_xor_4096_after

theorem not_cond_proof : not_cond_before ⊑ not_cond_after

theorem n10_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬63#64 ≥ ↑64 → 1#64 - x >>> 63#64 = zeroExtend 64 (ofBool (-1#64 <ₛ x))

theorem AvoidCollision_signExtend_eq_append_of_le {w v : Nat} {x : BitVec w} (h : w ≤ v) :
    x.signExtend v =
    ((if x.msb then allOnes (v - w) else 0#(v - w)) ++ x).cast (by omega)

theorem udiv_exact_ne_0_proof : udiv_exact_ne_0_before ⊑ udiv_exact_ne_0_after

theorem e_651 :
     - 11 * y - 1 *  ~~~x + 1 *  ~~~(x &&&  ~~~x) + 1 *  ~~~y - 1 *  ~~~(x &&& y) - 6 *  ~~~(x ^^^ y) + 11 *  ~~~(x ||| y) + 17 *  ~~~(x |||  ~~~y) - 4 * (x &&&  ~~~y) + 18 * (x &&& y) = 5 *  ~~~(x &&&  ~~~y) - 3 * x

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 src_x_and_nmask_uge_thm.extracted_1._6 : ∀ (x : BitVec 8) (x_1 : BitVec 1) (x_2 : BitVec 8),
  ¬x_1 = 1#1 → x_1 ^^^ 1#1 = 1#1 → ofBool (0#8 ≤ᵤ x_2 &&& 0#8) = 1#1

theorem tryFactorization_xor_ashr_lshr_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(x ≥ ↑32 ∨ x ≥ ↑32) →
    ¬x ≥ ↑32 → (BitVec.ofInt 32 (-3)).sshiftRight' x ^^^ 5#32 >>> x = (BitVec.ofInt 32 (-8)).sshiftRight' 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 test15c_proof : test15c_before ⊑ test15c_after

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

theorem e_975 :
    5 *  ~~~(z ^^^ t) + 1 *  ~~~z + 4 * (z ||| t) - 1 *  ~~~(z &&& t) - 10 *  ~~~(z ||| t) - 4 *  ~~~(z |||  ~~~t) - 9 * (z &&& t) = 8 * (z &&&  ~~~t) - 5 *  ~~~t

theorem test3_proof : test3_before ⊑ test3_after

theorem or_and1_commuted_proof : or_and1_commuted_before ⊑ or_and1_commuted_after

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

theorem same_signbit_wrong_type_proof : same_signbit_wrong_type_before ⊑ same_signbit_wrong_type_after

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

@[simp]
theorem Eqn.reflect_zero_of_denote_zero {w : Nat} (xs : Env w) (e : Eqn) (h : e.denote xs = 0) :
    e.reflect xs = 0

theorem sel_zext_proof : sel_zext_before ⊑ sel_zext_after

theorem test_negative_nuw_and_signed_pred_proof : test_negative_nuw_and_signed_pred_before ⊑ test_negative_nuw_and_signed_pred_after

theorem lt_unsigned_to_large_unsigned_proof : lt_unsigned_to_large_unsigned_before ⊑ lt_unsigned_to_large_unsigned_after

theorem fold_add_udiv_urem_thm (e : IntW 32) :
  add (shl (LLVM.udiv e (const? 32 10)) (const? 32 4)) (urem e (const? 32 10)) ⊑
    add (mul (LLVM.udiv e (const? 32 10)) (const? 32 6) { «nsw» := false, «nuw» := true }) e

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

theorem test_invert_demorgan_logical_and_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬ofBool (x == 27#64) = 1#1 → ¬ofBool (x != 27#64) = 1#1 → False

theorem or_signbit_select_shl_proof : or_signbit_select_shl_before ⊑ or_signbit_select_shl_after

theorem trunc_lshr_trunc_outofrange_proof : trunc_lshr_trunc_outofrange_before ⊑ trunc_lshr_trunc_outofrange_after

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

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

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

theorem ne_smax1_proof : ne_smax1_before ⊑ ne_smax1_after

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

theorem ashrslt_02_05_exact_proof : ashrslt_02_05_exact_before ⊑ ashrslt_02_05_exact_after

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

theorem src_srem_shl_demand_max_signbit_mask_hit_first_demand_proof : src_srem_shl_demand_max_signbit_mask_hit_first_demand_before ⊑ src_srem_shl_demand_max_signbit_mask_hit_first_demand_after

theorem land_bor_left1_proof : land_bor_left1_before ⊑ land_bor_left1_after

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

theorem ashr_slt_exact_thm (e : IntW 8) :
  icmp IntPred.slt (ashr e (const? 8 3) { «exact» := true }) (const? 8 10) ⊑
    icmp IntPred.slt e (const? 8 80)

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

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

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 test5_thm (e : IntW 32) :
  sext 64 (urem e (const? 32 30000)) ⊑ zext 64 (urem e (const? 32 30000)) { «nneg» := true }

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

theorem invert_both_cmp_operands_complex_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 32) (x_3 : BitVec 1),
  ¬x_3 = 1#1 → ofBool (x ^^^ -1#32 ≤ₛ x_2 ^^^ -1#32) = ofBool (x_2 ≤ₛ x)

theorem not_and_and_or_no_or_commute1_proof : not_and_and_or_no_or_commute1_before ⊑ not_and_and_or_no_or_commute1_after

theorem ne_umin4_proof : ne_umin4_before ⊑ ne_umin4_after

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

theorem positive_biggerShl_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(10#32 ≥ ↑32 ∨ 5#32 ≥ ↑32) → ¬5#32 ≥ ↑32 → x <<< 10#32 >>> 5#32 = x <<< 5#32 &&& 134217696#32

theorem eq_commuted_proof : eq_commuted_before ⊑ eq_commuted_after

theorem test1_proof : test1_before ⊑ test1_after

theorem urem_i32_c_multiuse_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬10#32 = 0 →
    10#32 = 0 ∨
        True ∧ (zeroExtend 32 x % 10#32).saddOverflow (zeroExtend 32 x) = true ∨
          True ∧ (zeroExtend 32 x % 10#32).uaddOverflow (zeroExtend 32 x) = true →
      False

theorem ugt_umax1_proof : ugt_umax1_before ⊑ ugt_umax1_after

theorem icmp_power2_and_icmp_shifted_mask_swapped_8_7_proof : icmp_power2_and_icmp_shifted_mask_swapped_8_7_before ⊑ icmp_power2_and_icmp_shifted_mask_swapped_8_7_after

theorem not_true_not_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1), x_1 ^^^ 1#1 = 1#1 → x_1 = 1#1 → 1#1 = x ^^^ 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 lshr_pow2_ult_proof : lshr_pow2_ult_before ⊑ lshr_pow2_ult_after

theorem icmp_eq_and_pow2_minus1_shl1_negative2_thm (e : IntW 32) :
  zext 32 (icmp IntPred.eq (LLVM.and (shl (const? 32 32) e) (const? 32 15)) (const? 32 0)) ⊑ const? 32 1

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

theorem drop_both_trunc_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬(True ∧ signExtend 16 (truncate 8 (x_1 &&& 255#16 &&& x)) ≠ x_1 &&& 255#16 &&& x ∨
        True ∧ zeroExtend 16 (truncate 8 (x_1 &&& 255#16 &&& x)) ≠ x_1 &&& 255#16 &&& x) →
    truncate 8 (x_1 &&& 255#16 &&& x) = truncate 8 (x_1 &&& x)

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

theorem ule_and_min_commute_proof : ule_and_min_commute_before ⊑ ule_and_min_commute_after

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

theorem e_125 :
     - 5 *  ~~~x - 11 *  ~~~(x ^^^ y) + 2 *  ~~~(x &&&  ~~~x) + 14 *  ~~~(x ||| y) - 2 * (x &&&  ~~~y) + 9 * (x &&& y) =  - 3 *  ~~~(x |||  ~~~y)

theorem lshrugt_01_00_exact_proof : lshrugt_01_00_exact_before ⊑ lshrugt_01_00_exact_after

theorem test23_logical_proof : test23_logical_before ⊑ test23_logical_after

theorem test15e_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (x &&& 128#32 != 0#32) = 1#1 → 1#32 ≥ ↑32 → False

theorem or_ugt_proof : or_ugt_before ⊑ or_ugt_after

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

@[simp] theorem append_eq : append xs ys = xs ++ ys

theorem PR44545_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 == 0#32) = 1#1 →
    ¬(True ∧ x.saddOverflow 1#32 = true ∨ True ∧ x.uaddOverflow 1#32 = true) →
      ¬(True ∧ (truncate 16 (x + 1#32)).saddOverflow (-1#16) = true) → truncate 16 (x + 1#32) + -1#16 = truncate 16 x

theorem e_2158 :
    1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 3 * (f ^^^ (d &&& (e ||| f))) - 7 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 6 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 7 * ((d &&& e) ^^^ (e |||  ~~~f)) + 5 * (d |||  ~~~f) + 7 * (f |||  ~~~(d ^^^ e)) - 7 * (e ^^^  ~~~(d |||  ~~~f)) + 2 * (d ^^^ ( ~~~e ||| f)) - 1 * ((d &&& f) |||  ~~~(e ||| f)) + 3 *  ~~~(d ||| (e &&& f)) + 2 *  ~~~( ~~~d ||| (e &&& f)) + 3 * (f |||  ~~~(d |||  ~~~e)) - 2 * (e ^^^ ( ~~~d &&& (e ||| f))) - 1 * (e ^^^ (d &&& (e ^^^ f))) - 7 * ((d ||| e) &&& (e ^^^ f)) + 11 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) + 11 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 1 *  ~~~( ~~~d &&& (e &&& f)) - 5 * ( ~~~e &&& (d ^^^ f)) + 1 * ((d &&& e) |||  ~~~(e ||| f)) + 2 * (f &&& (d ^^^ e)) + 3 *  ~~~(d |||  ~~~e) - 1 * (e ^^^ (d ||| f)) + 11 * (d &&& (e ||| f)) + 5 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 2 * (f ^^^  ~~~(d &&&  ~~~e)) + 1 *  ~~~(d ^^^ e) - 6 * ( ~~~f &&& (d ^^^ e)) - 3 * (e |||  ~~~(d ||| f)) + 5 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 5 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 11 * (e &&& (d ^^^ f)) + 1 * (f ^^^ (d &&& ( ~~~e ||| f))) + 4 *  ~~~(d &&&  ~~~d) - 1 *  ~~~( ~~~d ||| ( ~~~e &&& f)) + 2 * d - 6 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 11 * (f ^^^ ( ~~~d ||| (e &&& f))) - 2 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 48 *  ~~~(d ||| (e ||| f)) - 14 *  ~~~(d ||| ( ~~~e ||| f)) + 1 *  ~~~( ~~~d ||| (e ||| f)) - 24 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 40 * ( ~~~d &&& ( ~~~e &&& f)) - 43 * ( ~~~d &&& (e &&& f)) - 33 * (d &&& ( ~~~e &&& f)) - 21 * (d &&& (e &&& f)) = 1 * (e |||  ~~~(d ^^^ f))

theorem fast_div_201_proof : fast_div_201_before ⊑ fast_div_201_after

theorem exact_lshr_eq_proof : exact_lshr_eq_before ⊑ exact_lshr_eq_after

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

theorem nomask_rhs_logical_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 1)) (const? 32 0)) (const? 1 1)
      (icmp IntPred.eq e (const? 32 0)) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 1)) (const? 32 0)

theorem and_xor_hoist_mask_commute_proof : and_xor_hoist_mask_commute_before ⊑ and_xor_hoist_mask_commute_after

theorem not_mul_of_pow2_proof : not_mul_of_pow2_before ⊑ not_mul_of_pow2_after

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

theorem neg_nsw_slt_n1_proof : neg_nsw_slt_n1_before ⊑ neg_nsw_slt_n1_after

theorem narrow_sext_and_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 16),
  truncate 16 (signExtend 32 x_1 &&& x) = x_1 &&& truncate 16 x

theorem ashrsgt_01_03_proof : ashrsgt_01_03_before ⊑ ashrsgt_01_03_after

theorem not_cond_proof : not_cond_before ⊑ not_cond_after

theorem or_eq_with_one_bit_diff_constants3_logical_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x == BitVec.ofInt 8 (-2)) = 1#1 → 1#1 = ofBool (x &&& 127#8 == 126#8)

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

theorem ult_rem_zero_nsw_thm (e : IntW 8) :
  icmp IntPred.ult (mul e (const? 8 7) { «nsw» := true, «nuw» := true }) (const? 8 21) ⊑
    icmp IntPred.ult e (const? 8 3)

private theorem BitVec.signExtend_slt_signExtend_of_slt {x y : BitVec w}
    {N : Nat} (hN : w ≤ N)
    (h : x.slt y) : (x.signExtend N).slt (y.signExtend N)

theorem fold_icmp_shl_nuw_c3_proof : fold_icmp_shl_nuw_c3_before ⊑ fold_icmp_shl_nuw_c3_after

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

theorem positive_biggershl_proof : positive_biggershl_before ⊑ positive_biggershl_after

theorem and_two_ranges_to_mask_and_range_not_pow2_diff_proof : and_two_ranges_to_mask_and_range_not_pow2_diff_before ⊑ and_two_ranges_to_mask_and_range_not_pow2_diff_after

theorem test1_proof : test1_before ⊑ test1_after

theorem shl_mask_wrong_shl_const_thm (e : IntW 32) :
  LLVM.or (LLVM.and e (const? 32 255)) (shl (LLVM.and e (const? 32 255)) (const? 32 7)) ⊑
    LLVM.or (LLVM.and e (const? 32 255))
      (shl (LLVM.and e (const? 32 255)) (const? 32 7) { «nsw» := true, «nuw» := true })

theorem lshrult_02_05_exact_proof : lshrult_02_05_exact_before ⊑ lshrult_02_05_exact_after

theorem test2_proof : test2_before ⊑ test2_after

theorem ule_swap_or_min_proof : ule_swap_or_min_before ⊑ ule_swap_or_min_after

theorem test_nsw_and_signed_pred_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ (3#64).ssubOverflow x = true) → ofBool (10#64 <ₛ 3#64 - x) = ofBool (x <ₛ BitVec.ofInt 64 (-7))

theorem shl_sub_i8_proof : shl_sub_i8_before ⊑ shl_sub_i8_after

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

theorem nonexact_ashr_ne_noexactdiv_proof : nonexact_ashr_ne_noexactdiv_before ⊑ nonexact_ashr_ne_noexactdiv_after

theorem positive_sameconst_shlnuw_proof : positive_sameconst_shlnuw_before ⊑ positive_sameconst_shlnuw_after

theorem exactly_one_set_signbit_wrong_pred_thm (e e_1 : IntW 8) :
  icmp IntPred.sgt (lshr e_1 (const? 8 7)) (zext 8 (icmp IntPred.sgt e (const? 8 (-1)))) ⊑
    icmp IntPred.slt (LLVM.and e e_1) (const? 8 0)

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

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

theorem urem_constant_dividend_select_of_constants_divisor_0_arm_proof : urem_constant_dividend_select_of_constants_divisor_0_arm_before ⊑ urem_constant_dividend_select_of_constants_divisor_0_arm_after

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 trunc_signed_both_thm (e e_1 : IntW 16) :
  icmp IntPred.slt (trunc 8 e_1 { «nsw» := true, «nuw» := true }) (trunc 8 e { «nsw» := true, «nuw» := true }) ⊑
    icmp IntPred.slt e_1 e

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

theorem alive_1030 : alive_1030_src ⊑ alive_1030_tgt

theorem Eqn.denote_hard_case_of_denote (e : Eqn) (h : ∀ (env1 : EnvFin 1 e.numVars), e.denoteFin env1 = 0) :
    ∀ {w : Nat} (env : List (BitVec w)), e.reflect env = 0

theorem foo4_proof : foo4_before ⊑ foo4_after

theorem or_not_and_and_not_and_xor_commute4_proof : or_not_and_and_not_and_xor_commute4_before ⊑ or_not_and_and_not_and_xor_commute4_after

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

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

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

theorem ashr_overshift_proof : ashr_overshift_before ⊑ ashr_overshift_after

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

theorem e_110 :
    4 *  ~~~y + 7 * y + 2 *  ~~~(x &&&  ~~~x) - 6 *  ~~~(x &&&  ~~~y) - 3 *  ~~~(x |||  ~~~y) - 6 * (x &&&  ~~~y) = 3 * (x &&& y)

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

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

theorem ashr_ne_msb_low_second_zero_proof : ashr_ne_msb_low_second_zero_before ⊑ ashr_ne_msb_low_second_zero_after

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

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

theorem lshrult_02_15_proof : lshrult_02_15_before ⊑ lshrult_02_15_after

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

theorem and_logic_and_logic_or_6_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 → x_1 = 1#1 → 1#1 = x_1 &&& 1#1

theorem unmasked_shlop_insufficient_mask_shift_amount_proof : unmasked_shlop_insufficient_mask_shift_amount_before ⊑ unmasked_shlop_insufficient_mask_shift_amount_after

theorem lshrugt_01_12_proof : lshrugt_01_12_before ⊑ lshrugt_01_12_after

theorem mul_splat_fold_too_narrow_proof : mul_splat_fold_too_narrow_before ⊑ mul_splat_fold_too_narrow_after

theorem p0_proof : p0_before ⊑ p0_after

theorem trunc_sel_smaller_zext_proof : trunc_sel_smaller_zext_before ⊑ trunc_sel_smaller_zext_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_5_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_5_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_5_logical_after

theorem n2_badmask_proof : n2_badmask_before ⊑ n2_badmask_after

theorem trunc_proof : trunc_before ⊑ trunc_after

theorem sel_false_val_is_a_masked_ashr_of_true_val1_proof : sel_false_val_is_a_masked_ashr_of_true_val1_before ⊑ sel_false_val_is_a_masked_ashr_of_true_val1_after

theorem e_1218 :
    1 * t - 2 * (z |||  ~~~t) + 11 *  ~~~z + 1 *  ~~~(z &&&  ~~~t) - 1 *  ~~~t - 2 * z - 9 *  ~~~(z ||| t) - 17 *  ~~~(z |||  ~~~t) + 1 * (z &&&  ~~~t) =  - 2 * (z &&& t) - 4 * (z ^^^ t)

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 shl_add_log_may_cause_poison_pr62175_with_nuw_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ 4#8 <<< x >>> x ≠ 4#8 ∨ x ≥ ↑8) → ¬x + 2#8 ≥ ↑8 → x_1 * 4#8 <<< x = x_1 <<< (x + 2#8)

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

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

@[simp]
lemma CNFA.lift_bv_language {m : CNFA n1} {f : Fin n1 → Fin n2} :
    m.bv_recognizes L → (m.lift f |>.bv_recognizes (BitVecs.transport f ⁻¹' L))

@[simp]
theorem Equiv_refl : ∀ (c : Circuit α), Circuit.Equiv c c

theorem lshr_lshr_pow2_const_thm (e : IntW 16) :
  LLVM.and (lshr (lshr (const? 16 2048) e) (const? 16 6)) (const? 16 4) ⊑
    select (icmp IntPred.eq e (const? 16 3)) (const? 16 4) (const? 16 0)

theorem xor_andn_commute3_proof : xor_andn_commute3_before ⊑ xor_andn_commute3_after

theorem test_nuw_dropped_proof : test_nuw_dropped_before ⊑ test_nuw_dropped_after

theorem t2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ¬x ≥ ↑8 → x_1 - BitVec.ofInt 8 (-42) <<< x = 42#8 <<< x + x_1

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

theorem sub_mask1_trunc_lshr_proof : sub_mask1_trunc_lshr_before ⊑ sub_mask1_trunc_lshr_after

theorem ashr_and_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ x + 1#8 ≥ ↑8) →
    ¬x ≥ ↑8 →
      (BitVec.ofInt 8 (-64)).sshiftRight' x &&& (BitVec.ofInt 8 (-128)).sshiftRight' (x + 1#8) =
        (BitVec.ofInt 8 (-64)).sshiftRight' x

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

theorem AvoidCollision_setWidth_and {x y : BitVec w} :
    (x &&& y).setWidth k = x.setWidth k &&& y.setWidth k

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

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

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

@[simp] theorem zero_eq_last (h) : ⟨0, h⟩ = last Γ t

@[simp]
theorem complete_accepts (M : NFA α σ) : M.complete.accepts = M.accepts

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

theorem and_two_ranges_to_mask_and_range_no_add_on_one_range_thm (e : IntW 16) :
  LLVM.and (icmp IntPred.uge e (const? 16 12))
      (LLVM.or (icmp IntPred.ult e (const? 16 16)) (icmp IntPred.uge e (const? 16 28))) ⊑
    icmp IntPred.ugt (LLVM.and e (const? 16 (-20))) (const? 16 11)

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

theorem slt1 (w : Nat) (a b : BitVec w) : (a.slt b) ∨ (b.sle a)

theorem t5_proof : t5_before ⊑ t5_after

theorem e_1417 :
     - 2 * (z |||  ~~~t) - 5 *  ~~~(z &&&  ~~~t) - 1 * z - 11 *  ~~~t - 5 *  ~~~z - 6 *  ~~~(z &&& t) + 3 * (z ^^^ t) + 29 *  ~~~(z ||| t) + 18 *  ~~~(z |||  ~~~t) + 17 * (z &&&  ~~~t) = 5 * t - 13 * (z &&& t)

theorem foo_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.saddOverflow x = true ∨ True ∧ (x_1 + x).smulOverflow x_1 = true ∨ True ∧ x_1.smulOverflow x_1 = true) →
    (x_1 + x) * x_1 - x_1 * x_1 = x * x_1

theorem must_drop_poison_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ ((x_1 &&& 255#32) <<< x).sshiftRight' x ≠ x_1 &&& 255#32 ∨
        True ∧ (x_1 &&& 255#32) <<< x >>> x ≠ x_1 &&& 255#32 ∨ x ≥ ↑32) →
    ¬x ≥ ↑32 → truncate 8 ((x_1 &&& 255#32) <<< x) = truncate 8 (x_1 <<< x)

theorem and_signbit_select_shl_proof : and_signbit_select_shl_before ⊑ and_signbit_select_shl_after

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

theorem test3_thm (e : IntW 32) : icmp IntPred.slt e e ⊑ const? 1 0

theorem slt_zero_ult_i1_fail2_proof : slt_zero_ult_i1_fail2_before ⊑ slt_zero_ult_i1_fail2_after

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

theorem e_2100 :
    2 *  ~~~(d &&& ( ~~~e &&& f)) + 1 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 2 * (e ^^^  ~~~(d &&& (e ||| f))) - 1 *  ~~~(d |||  ~~~e) - 1 * (d &&& ( ~~~e ||| f)) - 5 *  ~~~(e |||  ~~~f) + 5 * ( ~~~d &&& (e ^^^ f)) + 3 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 2 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 11 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 7 * (e ||| (d &&& f)) - 2 *  ~~~(d ||| (e ^^^ f)) + 11 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 11 *  ~~~(d &&& ( ~~~e ||| f)) + 7 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 2 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 1 * (e &&&  ~~~f) + 1 * (d ||| (e ||| f)) - 3 * (d ^^^ (e ||| f)) - 6 * (e ^^^ (d &&& (e ||| f))) - 6 * (f ^^^  ~~~(d ||| (e &&& f))) - 1 * (f ^^^ (d &&&  ~~~e)) - 1 *  ~~~( ~~~d ||| (e &&& f)) + 1 *  ~~~( ~~~d &&& (e ||| f)) + 1 * ( ~~~d ||| (e ^^^ f)) + 2 * (d |||  ~~~f) + 5 * d - 3 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 3 *  ~~~(d ^^^ f) - 1 * (f &&& (d |||  ~~~e)) + 5 * ( ~~~f &&&  ~~~(d ^^^ e)) - 11 * ( ~~~d ||| ( ~~~e ||| f)) + 2 * (e |||  ~~~(d ||| f)) + 1 * (e &&&  ~~~(d &&& f)) + 11 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 4 * ((d &&& e) ^^^ (e ||| f)) + 5 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 18 *  ~~~(d ||| (e ||| f)) - 7 *  ~~~(d ||| ( ~~~e ||| f)) - 17 *  ~~~( ~~~d ||| (e ||| f)) - 54 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 6 * ( ~~~d &&& (e &&& f)) - 13 * (d &&& ( ~~~e &&& f)) =  - 1 * (d ||| (e ^^^ f)) - 1 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f)))

theorem bv_152 :
    ∀ (e : LLVM.IntW w), LLVM.mul e (LLVM.const? w (-1)) ⊑ LLVM.sub (LLVM.const? w 0) e

theorem pr40493_neg2_proof : pr40493_neg2_before ⊑ pr40493_neg2_after

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

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

theorem not_signbit_zext_proof : not_signbit_zext_before ⊑ not_signbit_zext_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 test10_thm (e : IntW 64) :
  add (sub (const? 64 0) e { «nsw» := true, «nuw» := false })
      (LLVM.and (sub (const? 64 0) e { «nsw» := true, «nuw» := false }) (const? 64 1)) ⊑
    sub (const? 64 0) (LLVM.and e (const? 64 (-2)))

theorem and_or_not_not_commute1_proof : and_or_not_not_commute1_before ⊑ and_or_not_not_commute1_after

theorem lshrult_01_04_exact_proof : lshrult_01_04_exact_before ⊑ lshrult_01_04_exact_after

theorem sel_sext_constants_proof : sel_sext_constants_before ⊑ sel_sext_constants_after

@[simp] theorem getElem_map (xs : HVector A as) (v : Var ⟨as⟩ a) :
    (xs.map f)[v] = f _ xs[v]

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

theorem test7_proof : test7_before ⊑ test7_after

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

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

theorem positive_with_mask_proof : positive_with_mask_before ⊑ positive_with_mask_after

theorem t0_proof : t0_before ⊑ t0_after

theorem not_and_and_not_proof : not_and_and_not_before ⊑ not_and_and_not_after

theorem lshrult_03_11_proof : lshrult_03_11_before ⊑ lshrult_03_11_after

theorem ashr_ne_exact_thm (e : IntW 8) :
  icmp IntPred.ne (ashr e (const? 8 3) { «exact» := true }) (const? 8 10) ⊑
    icmp IntPred.ne e (const? 8 80)

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

lemma CNFA.autWidth_bv_language :
    (autWidth wp n).bv_recognizes { bv | wp.sat bv.w n }

theorem icmp_eq_and_pow2_shl1_proof : icmp_eq_and_pow2_shl1_before ⊑ icmp_eq_and_pow2_shl1_after

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

theorem or_trunc_lshr_small_mask_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬4#8 ≥ ↑8 →
    4#8 ≥ ↑8 ∨
        True ∧ signExtend 8 (truncate 6 (x >>> 4#8)) ≠ x >>> 4#8 ∨
          True ∧ zeroExtend 8 (truncate 6 (x >>> 4#8)) ≠ x >>> 4#8 →
      False

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

theorem test3_proof : test3_before ⊑ test3_after

theorem andn_or_cmp_4_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 == x) = 1#1 → ofBool (x_1 != x) = 1#1 → True → False

theorem t2_proof : t2_before ⊑ t2_after

theorem lshr_shl_pow2_const_overflow_proof : lshr_shl_pow2_const_overflow_before ⊑ lshr_shl_pow2_const_overflow_after

theorem ashrslt_02_06_exact_proof : ashrslt_02_06_exact_before ⊑ ashrslt_02_06_exact_after

theorem test25_proof : test25_before ⊑ test25_after

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

theorem and_xor_or6_proof : and_xor_or6_before ⊑ and_xor_or6_after

theorem shl_xor_lshr_proof : shl_xor_lshr_before ⊑ shl_xor_lshr_after

theorem and_two_ranges_to_mask_and_range_not_pow2_diff_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (25#8 <ᵤ x + BitVec.ofInt 8 (-97)) &&& ofBool (25#8 <ᵤ x + BitVec.ofInt 8 (-64)) =
    ofBool (x + BitVec.ofInt 8 (-123) <ᵤ BitVec.ofInt 8 (-26)) &&&
      ofBool (x + BitVec.ofInt 8 (-90) <ᵤ BitVec.ofInt 8 (-26))

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

theorem foo_proof : foo_before ⊑ foo_after

theorem icmp_eq_or_z_or_pow2orz_fail_logic_or_proof : icmp_eq_or_z_or_pow2orz_fail_logic_or_before ⊑ icmp_eq_or_z_or_pow2orz_fail_logic_or_after

theorem fold_add_udiv_urem_commuted_proof : fold_add_udiv_urem_commuted_before ⊑ fold_add_udiv_urem_commuted_after

theorem ult_192_thm (e : IntW 32) :
  icmp IntPred.ult (trunc 8 e) (const? 8 (-64)) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 192)) (const? 32 192)

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

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

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

theorem PR42691_9_proof : PR42691_9_before ⊑ PR42691_9_after

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

theorem shl_add_and_fail_mismatch_shift_proof : shl_add_and_fail_mismatch_shift_before ⊑ shl_add_and_fail_mismatch_shift_after

theorem ule_umax3_proof : ule_umax3_before ⊑ ule_umax3_after

theorem lshr_shl_pow2_const_case2_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(x ≥ ↑16 ∨ 4#16 ≥ ↑16) → ofBool (x == 12#16) = 1#1 → 8192#16 >>> x <<< 4#16 &&& 32#16 = 32#16

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 multiuse_lshr_lshr_thm.extracted_1._2 : ∀ (x : BitVec 9),
  ¬(2#9 ≥ ↑9 ∨ 2#9 ≥ ↑9 ∨ 3#9 ≥ ↑9) → ¬(2#9 ≥ ↑9 ∨ 5#9 ≥ ↑9) → x >>> 2#9 * x >>> 2#9 >>> 3#9 = x >>> 2#9 * x >>> 5#9

theorem icmp_eq_and_pow2_shl_pow2_negative2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → zeroExtend 32 (ofBool (2#32 <<< x &&& 14#32 == 0#32)) = zeroExtend 32 (ofBool (2#32 <ᵤ x))

theorem mul_may_overflow_thm (e e_1 : IntW 32) :
  zext 32 (icmp IntPred.ule (mul (zext 34 e_1) (zext 34 e)) (const? 34 4294967295)) ⊑
    zext 32 (icmp IntPred.ult (mul (zext 34 e_1) (zext 34 e)) (const? 34 4294967296))

theorem ashr_mul_times_5_div_4_proof : ashr_mul_times_5_div_4_before ⊑ ashr_mul_times_5_div_4_after

theorem e_2355 :
    7 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 11 * ( ~~~d ||| ( ~~~e &&& f)) - 1 * (f ^^^ (d ||| e)) + 1 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) - 3 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 1 * ( ~~~d &&& (e ^^^ f)) - 3 * (f ^^^ (d &&& ( ~~~e ||| f))) + 7 * (e ^^^ ( ~~~d &&& (e ||| f))) + 1 * ( ~~~f ||| (d ^^^ e)) + 7 *  ~~~(d |||  ~~~e) - 7 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 1 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 1 * ( ~~~d ||| (e &&& f)) - 1 * (e ^^^  ~~~(d &&& f)) - 3 * (e ^^^ ( ~~~d ||| (e ||| f))) - 6 * ((d &&& e) |||  ~~~(e ^^^ f)) - 2 * (e ^^^ (d &&& (e ^^^ f))) - 5 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 6 *  ~~~(d |||  ~~~f) - 2 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 3 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 1 * (f ^^^  ~~~(d &&& (e &&& f))) + 1 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 11 * (d ^^^ ( ~~~e ||| f)) - 2 * (e ^^^ (d ||| (e ^^^ f))) + 4 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 2 * (e ^^^ f) - 11 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 4 * (e |||  ~~~(d |||  ~~~f)) + 5 * (d ^^^ (e &&& f)) - 6 *  ~~~(d ^^^ ( ~~~e ||| f)) - 11 * (f ^^^  ~~~(d ||| (e &&& f))) + 2 * (f |||  ~~~(d ||| e)) + 5 * (e ^^^  ~~~(d |||  ~~~f)) - 3 * (e ^^^  ~~~(d &&&  ~~~f)) + 1 * (e ^^^  ~~~(d ||| f)) + 3 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 4 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (e &&& (d ||| f)) + 2 * (d &&& ( ~~~e ||| f)) - 7 * (e ^^^ (d ||| ( ~~~e &&& f))) - 1 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 1 * ( ~~~f &&& (d ^^^ e)) + 7 *  ~~~(d ^^^ e) - 11 * (f &&&  ~~~(d &&&  ~~~e)) - 5 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 11 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) + 5 * (f ^^^  ~~~(d ||| e)) + 1 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 *  ~~~(d &&& (e ||| f)) + 1 * (e ||| (d ^^^ f)) - 1 *  ~~~(d ||| f) + 5 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 5 * (f ^^^  ~~~(d |||  ~~~e)) - 2 * (e &&& f) - 1 * (e |||  ~~~f) - 7 * e + 3 * (d |||  ~~~f) - 6 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 2 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 48 *  ~~~(d ||| (e ||| f)) + 49 *  ~~~(d ||| ( ~~~e ||| f)) + 22 *  ~~~( ~~~d ||| (e ||| f)) + 5 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 54 * ( ~~~d &&& ( ~~~e &&& f)) + 76 * ( ~~~d &&& (e &&& f)) + 40 * (d &&& ( ~~~e &&& f)) + 31 * (d &&& (e &&& f)) = 1 *  ~~~(d &&&  ~~~d)

theorem masked_icmps_mask_notallzeros_bmask_mixed_1_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_1_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_1_logical_after

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

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

theorem test_ult_xor_proof : test_ult_xor_before ⊑ test_ult_xor_after

theorem test24_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.sgt e (const? 32 1)) (icmp IntPred.ne e (const? 32 2)) ⊑
    icmp IntPred.sgt e (const? 32 2)

@[simp]
theorem eval_latchDelayed_zero_eq (initVal : Bool)
    (x : Bool → BitStream) :
    (latchDelayed initVal).eval x 0 = initVal

theorem e_1872 :
     - 11 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) - 1 * (c ^^^ (a ||| b)) - 1 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) + 3 * ( ~~~b &&& (a ^^^ c)) + 1 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 11 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 1 * ( ~~~a &&& ( ~~~b ||| c)) - 7 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) - 1 *  ~~~(a &&& ( ~~~b ||| c)) + 4 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 * (c ^^^ ( ~~~a &&& (b ||| c))) + 7 * (c ||| (a &&&  ~~~b)) - 7 * ((b &&&  ~~~c) ^^^ (a ||| (b ^^^ c))) + 1 * ((a &&&  ~~~b) ||| (a ^^^ (b ^^^ c))) + 7 * (a &&& ( ~~~b ||| c)) + 4 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) - 3 *  ~~~(a ^^^ (b &&& c)) + 1 * ( ~~~a ||| (b &&& c)) - 3 * (a ||| b) - 6 * ( ~~~a ||| (b ||| c)) + 1 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) + 2 * ((a ^^^ b) |||  ~~~(a ^^^ c)) + 7 * (c |||  ~~~(a ||| b)) + 1 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) + 1 * (b ^^^  ~~~( ~~~a ||| (b ^^^ c))) - 6 *  ~~~(a ||| c) + 11 *  ~~~(b |||  ~~~c) - 1 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) - 1 * (c ^^^  ~~~(a &&& b)) + 3 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) + 2 * (c &&& (a ||| b)) - 2 * (c ^^^  ~~~(a &&&  ~~~b)) - 2 * (c ^^^ (a &&& ( ~~~b ||| c))) - 2 * ((a &&& b) ^^^ (b |||  ~~~c)) - 5 * (a ^^^ ( ~~~b ||| c)) - 5 *  ~~~(a &&& c) + 2 * (b ^^^ (a &&& (b ||| c))) - 1 * (a |||  ~~~c) - 2 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) + 41 *  ~~~(a ||| (b ||| c)) + 15 *  ~~~(a ||| ( ~~~b ||| c)) + 16 *  ~~~( ~~~a ||| (b ||| c)) + 36 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 1 * ( ~~~a &&& ( ~~~b &&& c)) + 7 * ( ~~~a &&& (b &&& c)) - 13 * (a &&& ( ~~~b &&& c)) - 18 * (a &&& (b &&& c)) =  - 3 * (c |||  ~~~(a ^^^ b))

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

theorem e_687 :
    2 * (x ^^^ y) - 2 *  ~~~(x ^^^ y) + 5 *  ~~~y - 6 *  ~~~(x &&&  ~~~y) - 7 *  ~~~(x &&&  ~~~x) - 1 * (x |||  ~~~y) - 2 *  ~~~(x &&& y) + 13 *  ~~~(x ||| y) + 15 *  ~~~(x |||  ~~~y) + 3 * (x &&&  ~~~y) =  - 18 * (x &&& y) + 2 * y

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

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

theorem xor_with_or_disjoint_ba_proof : xor_with_or_disjoint_ba_before ⊑ xor_with_or_disjoint_ba_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 smear_set_bit_different_dest_type_wider_dst_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬7#8 ≥ ↑8 → 24#32 ≥ ↑32 ∨ 31#32 ≥ ↑32 → False

theorem trunc_ashr_trunc_exact_thm (e : IntW 64) :
  trunc 8 (ashr (trunc 32 e) (const? 32 8) { «exact» := true }) ⊑
    trunc 8 (lshr e (const? 64 8) { «exact» := true })

theorem main11_logical_thm (e : IntW 32) :
  select
      (select (icmp IntPred.eq (LLVM.and e (const? 32 64)) (const? 32 0)) (const? 1 1)
        (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 e_436 :
    1 *  ~~~(x &&& y) + 11 * (x ||| y) + 1 *  ~~~y + 2 *  ~~~(x &&&  ~~~y) - 4 *  ~~~(x ||| y) - 11 *  ~~~(x |||  ~~~y) - 13 * (x &&&  ~~~y) - 10 * (x &&& y) = 3 * y

theorem t6_shl_proof : t6_shl_before ⊑ t6_shl_after

theorem negate_lshr_proof : negate_lshr_before ⊑ negate_lshr_after

theorem test_xor_ne_proof : test_xor_ne_before ⊑ test_xor_ne_after

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

theorem p0_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(5#8 ≥ ↑8 ∨ True ∧ x <<< 5#8 >>> 5#8 <<< 5#8 ≠ x <<< 5#8 ∨ 5#8 ≥ ↑8) →
    ofBool ((x <<< 5#8).sshiftRight' 5#8 != x) = ofBool (x + BitVec.ofInt 8 (-4) <ᵤ BitVec.ofInt 8 (-8))

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

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

@[simp] lemma eval_incr (x : Unit → BitStream) : incr.eval x = (x ()).incr

theorem test13_proof : test13_before ⊑ test13_after

theorem lshrult_03_15_proof : lshrult_03_15_before ⊑ lshrult_03_15_after

theorem shl_nsw_nuw_add_nsw_proof : shl_nsw_nuw_add_nsw_before ⊑ shl_nsw_nuw_add_nsw_after

theorem or_and_shifts1_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(3#32 ≥ ↑32 ∨ 5#32 ≥ ↑32) →
    ¬(3#32 ≥ ↑32 ∨ 5#32 ≥ ↑32 ∨ True ∧ (x <<< 3#32 &&& 8#32 &&& (x <<< 5#32 &&& 32#32) != 0) = true) →
      x <<< 3#32 &&& 15#32 ||

theorem udiv2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(x ≥ ↑32 ∨ True ∧ x_1.umod (1#32 <<< x) ≠ 0 ∨ 1#32 <<< x = 0) →
    ¬(True ∧ x_1 >>> x <<< x ≠ x_1 ∨ x ≥ ↑32) → x_1 / 1#32 <<< x = x_1 >>> x

theorem udiv_exact_ne_30_no_of_proof : udiv_exact_ne_30_no_of_before ⊑ udiv_exact_ne_30_no_of_after

theorem eq_irregular_bit_widths_proof : eq_irregular_bit_widths_before ⊑ eq_irregular_bit_widths_after

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

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_2_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_2_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_2_logical_after

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

@[simp]
theorem Std.HashSet.mem_attachWith_mem [BEq α] [Hashable α] [LawfulBEq α] (m : HashSet α) {P H} (x : α) h :
    ⟨x, h⟩ ∈ m.attachWith P H ↔ x ∈ m

theorem samesign_commute2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 &&& x <ₛ 0#32) ||

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

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

theorem test_shl__nuw_is_safe_proof : test_shl__nuw_is_safe_before ⊑ test_shl__nuw_is_safe_after

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

theorem test1_thm.extracted_1._1 : ∀ (x : BitVec 32), x &&& 0#32 = 0#32

theorem lowmask_xor_zext_commute_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  (x_1 * x_1 ^^^ zeroExtend 32 x) &&& 255#32 = zeroExtend 32 (x ^^^ truncate 8 (x_1 * x_1))

theorem slt_x_impliesT_ne_smin_todo_thm.extracted_1._3 : ∀ (x x_1 x_2 : BitVec 8),
  ¬ofBool (x_2 <ₛ x_1) = 1#1 → ofBool (x_2 != x) = ofBool (x != x_2)

theorem test3_thm (e : IntW 23) : LLVM.xor e e ⊑ const? 23 0

theorem e_1466 :
    1 *  ~~~(z ^^^ t) + 3 *  ~~~t + 4 *  ~~~(z &&& t) + 2 * (z |||  ~~~t) + 11 * t - 2 * (z ^^^ t) + 7 *  ~~~(z &&&  ~~~t) - 20 *  ~~~(z ||| t) - 23 *  ~~~(z |||  ~~~t) - 1 * (z &&&  ~~~t) - 15 * (z &&& t) = 6 * z - 3 *  ~~~z

theorem positive_biggershl_shlnuw_lshrexact_proof : positive_biggershl_shlnuw_lshrexact_before ⊑ positive_biggershl_shlnuw_lshrexact_after

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

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

@[bv_multi_width_normalize] theorem BitVec.one_mul (x : BitVec w) : 1#w * x = x

theorem test93_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬64#96 ≥ ↑96 → 31#32 ≥ ↑32 → False

@[simp] theorem eval_falseAfterIncluding (n : Nat) (i : Nat) {env : Fin 0 → BitStream} :
    (falseAfterIncluding n).eval env i = decide (i < n)

theorem foo_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ofBool (zeroExtend 32 (x &&& 255#16) <ᵤ 255#32) = 1#1 →
    truncate 16 (zeroExtend 32 (x &&& 255#16)) &&& 255#16 = x &&& 255#16

theorem pr40493_neg3_thm (e : IntW 32) :
  LLVM.and (mul e (const? 32 12)) (const? 32 4) ⊑ LLVM.and (shl e (const? 32 2)) (const? 32 4)

theorem mul32_low_proof : mul32_low_before ⊑ mul32_low_after

theorem test7_proof : test7_before ⊑ test7_after

theorem alive_AndOrXor_2263 : alive_AndOrXor_2263_src ⊑ alive_AndOrXor_2263_tgt

theorem t2_proof : t2_before ⊑ t2_after

theorem allOnes_sub_eq_xor (x :BitVec w) : (allOnes w) - x = x ^^^ (allOnes w)

theorem test_sub_0_Y_ne_0_thm (e : IntW 8) :
  icmp IntPred.ne (sub (const? 8 0) e) (const? 8 0) ⊑ icmp IntPred.ne e (const? 8 0)

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

theorem add_constant_equal_with_the_top_bit_of_demandedbits_insertpt_proof : add_constant_equal_with_the_top_bit_of_demandedbits_insertpt_before ⊑ add_constant_equal_with_the_top_bit_of_demandedbits_insertpt_after

theorem t_0_10_thm (e : IntW 8) :
  LLVM.and (select (icmp IntPred.ugt e (const? 8 0)) e (const? 8 0)) (const? 8 10) ⊑
    LLVM.and e (const? 8 10)

theorem test25_proof : test25_before ⊑ test25_after

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

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

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

theorem select_icmp_ne_0_and_4096_xor_32_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (0#32 != x_1 &&& 4096#32) = 1#1 → 7#32 ≥ ↑32 → False

lemma reduce_stepSet {M : NFA α σ} {q : σ} (S1 : Set M.Reachable) (S2 : Set σ) :
    (∀ q, (∃ hq, S1 ⟨q, hq⟩) ↔ S2 q) →
    ((∃ hq,  ⟨q, hq⟩ ∈ M.reduce.stepSet S1 a) ↔ q ∈ M.stepSet S2 a)

theorem shift_xor_multiuse_cmp_thm.extracted_1._2 : ∀ (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 sgt_swap_and_min_commute_logical_proof : sgt_swap_and_min_commute_logical_before ⊑ sgt_swap_and_min_commute_logical_after

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

theorem test_mul_nsw__nsw_is_safe_proof : test_mul_nsw__nsw_is_safe_before ⊑ test_mul_nsw__nsw_is_safe_after

theorem icmp_mul_nsw_sgt_proof : icmp_mul_nsw_sgt_before ⊑ icmp_mul_nsw_sgt_after

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

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

theorem icmp_ne_zext_eq_zero_proof : icmp_ne_zext_eq_zero_before ⊑ icmp_ne_zext_eq_zero_after

theorem select_constants_and_icmp_ne0_zero_fval_proof : select_constants_and_icmp_ne0_zero_fval_before ⊑ select_constants_and_icmp_ne0_zero_fval_after

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 trunc_shl_31_i32_i64_proof : trunc_shl_31_i32_i64_before ⊑ trunc_shl_31_i32_i64_after

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

theorem sext_sext_slt_proof : sext_sext_slt_before ⊑ sext_sext_slt_after

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

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

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

theorem bools_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 → 1#1 = x

theorem main5e_like_logical_proof : main5e_like_logical_before ⊑ main5e_like_logical_after

theorem pr40493_neg2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x * 12#32 &&& 15#32 == 0#32) = ofBool (x * 12#32 &&& 12#32 == 0#32)

theorem test_nuw_nsw_and_unsigned_pred_proof : test_nuw_nsw_and_unsigned_pred_before ⊑ test_nuw_nsw_and_unsigned_pred_after

theorem zext_zext_sgt_thm (e e_1 : IntW 8) :
  icmp IntPred.sgt (zext 32 e_1) (zext 32 e) ⊑ icmp IntPred.ugt e_1 e

theorem ne_smax1_proof : ne_smax1_before ⊑ ne_smax1_after

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

theorem src_is_mask_sext_proof : src_is_mask_sext_before ⊑ src_is_mask_sext_after

theorem mul_of_pow2_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ofBool (510#32 <ᵤ (x_1 &&& 2#32) * zeroExtend 32 x) = 0#1

theorem icmp_shl_ne_2_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬((x == 0 || 8 != 1 && 42#8 == intMin 8 && x == -1) = true ∨
        (x == 0 || 8 != 1 && 42#8 == intMin 8 && x == -1) = true ∨ 1#8 ≥ ↑8) →
    ¬(x == 0 || 8 != 1 && 42#8 == intMin 8 && x == -1) = true →
      ofBool ((42#8).sdiv x != (42#8).sdiv x <<< 1#8) = ofBool ((42#8).sdiv x != 0#8)

theorem shl_mask_wrong_shl_const_proof : shl_mask_wrong_shl_const_before ⊑ shl_mask_wrong_shl_const_after

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

theorem test17_thm (e : IntW 1) : sub (const? 32 0) (sext 32 e) ⊑ zext 32 e

theorem AvoidCollision_getLsbD_signExtend (x  : BitVec w) {v i : Nat} :
    (x.signExtend v).getLsbD i = (decide (i < v) && if i < w then x.getLsbD i else x.msb)

theorem substitute_constant_and_eq_eq_commute_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.eq e_1 e) (icmp IntPred.eq e_1 (const? 8 42)) ⊑
    LLVM.and (icmp IntPred.eq e_1 (const? 8 42)) (icmp IntPred.eq e (const? 8 42))

theorem low_bitmask_ult_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x + 31#8 &&& 31#8 <ᵤ x) = ofBool (x != 0#8)

theorem e_170 :
     - 2 *  ~~~(x &&& y) - 11 * (x ||| y) + 9 *  ~~~(x ||| y) + 20 *  ~~~(x |||  ~~~y) + 20 * (x &&&  ~~~y) + 18 * (x &&& y) = 7 *  ~~~(x &&&  ~~~x)

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

theorem lshr_sext_i1_to_i16_thm.extracted_1._2 : ∀ (x : BitVec 1),
  ¬4#16 ≥ ↑16 → ¬x = 1#1 → signExtend 16 x >>> 4#16 = 0#16

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

theorem e_2137 :
    11 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 5 * ((d &&& e) ^^^ (e ||| f)) + 2 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 2 * ( ~~~d ||| (e ||| f)) + 4 * (d &&& (e ^^^ f)) + 5 * (f ||| (d &&&  ~~~e)) - 5 * (f ^^^ (d ||| e)) + 7 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) + 1 * ( ~~~d &&& ( ~~~e ||| f)) + 2 * ( ~~~f &&&  ~~~(d ^^^ e)) - 2 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 5 * ( ~~~e &&& (d ^^^ f)) - 1 *  ~~~(d ^^^ (e ^^^ f)) + 11 * (d ||| (e &&& f)) - 1 *  ~~~(e &&& f) - 3 * (e ^^^ (d ||| f)) + 2 * (e ^^^  ~~~(d &&&  ~~~f)) - 5 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 4 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 11 * (f &&& (d |||  ~~~e)) - 1 *  ~~~( ~~~d ||| (e &&& f)) - 5 * (e ^^^ f) - 1 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 1 *  ~~~(d ^^^ (e &&& f)) - 5 * (e ^^^ (d &&&  ~~~f)) - 1 * (d ||| (e ||| f)) + 4 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 11 * (e ^^^ (d &&& ( ~~~e ||| f))) + 2 * ((d &&& e) |||  ~~~(e ||| f)) - 6 * ( ~~~d ||| ( ~~~e &&& f)) - 1 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) - 7 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 6 *  ~~~e - 11 *  ~~~(d &&& (e ^^^ f)) + 3 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 1 * (e ^^^ (d |||  ~~~f)) - 11 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 15 *  ~~~(d ||| (e ||| f)) + 8 *  ~~~( ~~~d ||| (e ||| f)) + 3 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 12 * ( ~~~d &&& ( ~~~e &&& f)) + 21 * ( ~~~d &&& (e &&& f)) + 28 * (d &&& ( ~~~e &&& f)) - 8 * (d &&& (e &&& f)) =  - 36 *  ~~~(d ||| ( ~~~e ||| f))

theorem carry_decr (x : Unit → BitStream) : ∀ (n : ℕ), decr.carry x (n+1) =
    fun _ => (BitStream.decrAux (x ()) n).2

theorem lshr_or_thm (e e_1 : IntW 8) :
  shl (LLVM.or (LLVM.srem e_1 (const? 8 42)) (lshr e (const? 8 4))) (const? 8 4) ⊑
    LLVM.or (LLVM.and e (const? 8 (-16))) (shl (LLVM.srem e_1 (const? 8 42)) (const? 8 4))

theorem or_and3_commuted_thm.extracted_1._3 : ∀ (x : BitVec 1) (x_1 x_2 : BitVec 32),
  ofBool (x_2 == x_1) ||

theorem test36_proof : test36_before ⊑ test36_after

theorem trunc_sel_larger_sext_thm (e : IntW 32) (e_1 : IntW 1) :
  sext 64 (select e_1 (trunc 16 e) (const? 16 42)) ⊑ select e_1 (sext 64 (trunc 16 e)) (const? 64 42)

theorem test1_proof : test1_before ⊑ test1_after

theorem t0_lshr_proof : t0_lshr_before ⊑ t0_lshr_after

theorem test22_proof : test22_before ⊑ test22_after

theorem shl_nsw_add_nuw_proof : shl_nsw_add_nuw_before ⊑ shl_nsw_add_nuw_after

theorem samesign_inverted_different_sign_bittest1_proof : samesign_inverted_different_sign_bittest1_before ⊑ samesign_inverted_different_sign_bittest1_after

theorem absdiff2_proof : absdiff2_before ⊑ absdiff2_after

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

theorem select_ashr_thm.extracted_1._3 : ∀ (x x_1 : BitVec 128) (x_2 : BitVec 1), ¬x_2 = 1#1 → 0#128 ≥ ↑128 → False

theorem orn_and_cmp_2_logical_thm (e e_1 : IntW 16) (e_2 : IntW 1) :
  select (select e_2 (icmp IntPred.sge e_1 e) (const? 1 0)) (const? 1 1) (icmp IntPred.slt e_1 e) ⊑
    select e_2 (const? 1 1) (icmp IntPred.slt e_1 e)

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

theorem t9_ashr_proof : t9_ashr_before ⊑ t9_ashr_after

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

theorem test86_thm (e : IntW 16) : trunc 16 (ashr (sext 32 e) (const? 32 4)) ⊑ ashr e (const? 16 4)

theorem test8_proof : test8_before ⊑ test8_after

theorem test18a_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x &&& BitVec.ofInt 8 (-2) == 0#8) = ofBool (x <ᵤ 2#8)

theorem test_nsw_dropped_proof : test_nsw_dropped_before ⊑ test_nsw_dropped_after

theorem udiv_shl_pair_const_proof : udiv_shl_pair_const_before ⊑ udiv_shl_pair_const_after

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 599),
  x = 1#1 → ¬70368744177664#599 = 0 → x_1 % 70368744177664#599 = x_1 &&& 70368744177663#599

@[simp] theorem Com.returnVars_rets : returnVars (rets vs : Com d Γ eff t) = vs

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_of_symmetric_selects_proof : select_of_symmetric_selects_before ⊑ select_of_symmetric_selects_after

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

theorem udiv_i32_c_proof : udiv_i32_c_before ⊑ udiv_i32_c_after

theorem negate_zext_proof : negate_zext_before ⊑ negate_zext_after

theorem PR42691_9_logical_proof : PR42691_9_logical_before ⊑ PR42691_9_logical_after

theorem and_congr (e1 : a ≈ʷ b) (e2 : c ≈ʷ d) : (a &&& c) ≈ʷ (b &&& d)

theorem ashr_can_be_lshr_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ x >>> 16#32 <<< 16#32 ≠ x ∨
        16#32 ≥ ↑32 ∨ True ∧ signExtend 32 (truncate 16 (x.sshiftRight' 16#32)) ≠ x.sshiftRight' 16#32) →
    ¬(True ∧ x >>> 16#32 <<< 16#32 ≠ x ∨ 16#32 ≥ ↑32 ∨ True ∧ zeroExtend 32 (truncate 16 (x >>> 16#32)) ≠ x >>> 16#32) →
      truncate 16 (x.sshiftRight' 16#32) = truncate 16 (x >>> 16#32)

theorem e_2408 :
     - 1 * (e &&&  ~~~(d &&& f)) - 7 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 11 * (f |||  ~~~(d ^^^ e)) + 5 * (f ^^^ (d ||| ( ~~~e ||| f))) - 6 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 1 * ( ~~~d ||| (e ^^^ f)) + 3 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 5 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 1 * (e ^^^  ~~~(d |||  ~~~f)) - 1 * ( ~~~f |||  ~~~(d ^^^ e)) + 7 *  ~~~(d &&&  ~~~d) - 2 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 5 *  ~~~(d ^^^ (e ^^^ f)) - 3 * (e ||| (d ^^^ f)) + 11 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) - 5 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (e ^^^ (d &&& (e ^^^ f))) - 1 * (d ||| (e &&& f)) + 1 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 7 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 6 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 2 * (d |||  ~~~e) - 6 * (d ^^^ f) - 7 * (e ^^^ f) + 11 * (e &&& (d ^^^ f)) - 1 * (d ||| ( ~~~e ||| f)) - 2 * (f ^^^  ~~~(d ||| e)) + 2 * (e ^^^ (d ||| ( ~~~e ||| f))) + 4 *  ~~~(d ||| ( ~~~e &&& f)) + 7 *  ~~~(e ^^^ f) - 3 * (d &&& f) - 2 * (e |||  ~~~(d ||| f)) - 1 * d - 11 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 1 * (f ^^^ (d &&& e)) + 2 * (e ^^^ ( ~~~d ||| (e &&& f))) + 1 * ((d ^^^ e) &&& (d ^^^ f)) + 1 * (e ^^^ (d ||| (e ^^^ f))) + 5 * (d ^^^ (e ||| f)) + 1 *  ~~~d - 2 *  ~~~( ~~~d ||| (e &&& f)) + 2 * (e &&& (d ||| f)) + 7 * (f &&&  ~~~(d &&&  ~~~e)) - 5 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 1 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 * (d &&& (e ^^^ f)) + 1 * (f ^^^  ~~~(d &&& (e &&& f))) + 4 * (f ^^^ ( ~~~d ||| (e ||| f))) - 11 * ((d &&& e) ^^^ (e ||| f)) + 3 * ( ~~~d &&& (e ||| f)) + 7 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 1 * ( ~~~f &&& (d ^^^ e)) - 2 * (f &&&  ~~~(d &&& e)) + 2 *  ~~~(d ^^^ (e ||| f)) + 1 * (e &&&  ~~~(d ^^^ f)) - 6 * (d ||| f) + 5 * ((d &&& e) |||  ~~~(e |||  ~~~f)) - 7 *  ~~~(d ^^^ e) + 5 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 7 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 2 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 5 * (f ^^^  ~~~(d |||  ~~~e)) + 2 * ( ~~~d &&& (e ^^^ f)) + 20 *  ~~~(d ||| (e ||| f)) + 11 *  ~~~(d ||| ( ~~~e ||| f)) + 5 *  ~~~( ~~~d ||| (e ||| f)) + 30 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 43 * ( ~~~d &&& ( ~~~e &&& f)) - 2 * ( ~~~d &&& (e &&& f)) + 19 * (d &&& ( ~~~e &&& f)) + 24 * (d &&& (e &&& f)) =  - 7 * (d &&& ( ~~~e ||| f)) - 2 * (f |||  ~~~(d |||  ~~~e))

lemma CNFA.canonicalSimul (m : CNFA n) : m.m.Simul m.toNFA {(s, s') | s = s'.val} ⊤ ∅

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

theorem shl_ashr_pow2_const_case1_proof : shl_ashr_pow2_const_case1_before ⊑ shl_ashr_pow2_const_case1_after

theorem com_Γ : com.1 = (Γn 1)

theorem src_srem_shl_demand_max_signbit_mask_hit_first_demand_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬((4#32 == 0 || 32 != 1 && x == intMin 32 && 4#32 == -1) = true ∨ 29#32 ≥ ↑32) →
    (4#32 == 0 || 32 != 1 && x == intMin 32 && 4#32 == -1) = true ∨
        True ∧ (x.srem 4#32 <<< 29#32).sshiftRight' 29#32 ≠ x.srem 4#32 ∨ 29#32 ≥ ↑32 →
      False

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

@[simp] lemma eval_or (x : Bool → BitStream) : or.eval x = (x true) ||

theorem no_shift_xor_multiuse_cmp_thm.extracted_1._7 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ¬ofBool (0#32 != x_3 &&& 4096#32) = 1#1 →
    ofBool (x_3 &&& 4096#32 == 0#32) = 1#1 → (x_2 ||| 4096#32) * x = (x_2 ||| x_3 &&& 4096#32 ^^^ 4096#32) * x

theorem src_is_mask_p2_m1_proof : src_is_mask_p2_m1_before ⊑ src_is_mask_p2_m1_after

theorem sub_sel_op1_proof : sub_sel_op1_before ⊑ sub_sel_op1_after

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

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

theorem const_sub_sub_const_proof : const_sub_sub_const_before ⊑ const_sub_sub_const_after

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

theorem exact_ashr_ne_both_equal_proof : exact_ashr_ne_both_equal_before ⊑ exact_ashr_ne_both_equal_after

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

omit [Fintype S] [DecidableEq S] [LawfulBEq A] in
theorem addOrCreateState_grow (st : worklist.St A S) (b : Bool) (sa : S) :
    let (_, st') := st.addOrCreateState _ _ b sa
    ∃ sas, List.Perm st'.map.keys (sas ++ st.map.keys) ∧ st'.worklist.toList = st.worklist.toList ++ sas

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

theorem test2_thm (e : IntW 1) : LLVM.xor e e ⊑ const? 1 0

theorem t4_thm (e : IntW 1) (e_1 : IntW 8) :
  sub e_1 (select e (const? 8 (-42)) (const? 8 44)) ⊑ add (select e (const? 8 42) (const? 8 (-44))) e_1

@[simp] theorem subAux_eq_BitVec_carry (a b : BitStream) (w i : Nat) (hi : i < w) :
    (a.subAux b i).2 = !(BitVec.carry (i + 1) (a.toBitVec w) ((~~~b).toBitVec w) true)

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

theorem differentconsts_proof : differentconsts_before ⊑ differentconsts_after

theorem xor_2_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 1) (x_2 : BitVec 8),
  ¬x_1 = 1#1 → x_2 ^^^ (x ^^^ 123#8) ^^^ -1#8 = x_2 ^^^ (x ^^^ BitVec.ofInt 8 (-124))

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

theorem ashr_sgt_exact_proof : ashr_sgt_exact_before ⊑ ashr_sgt_exact_after

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

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

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

theorem ashrslt_01_00_proof : ashrslt_01_00_before ⊑ ashrslt_01_00_after

theorem nonexact_lshr_eq_exactdiv_proof : nonexact_lshr_eq_exactdiv_before ⊑ nonexact_lshr_eq_exactdiv_after

theorem sext_sub_proof : sext_sub_before ⊑ sext_sub_after

@[simp] theorem getElem_toBitVec (w : Nat) (x : BitStream) (i : Nat) (hi : i < w) :
    (x.toBitVec w)[i] = ((decide (i < w)) && x i)

theorem e_2102 :
     - 2 * (f ^^^ (d ||| (e ||| f))) - 5 * (f ^^^  ~~~(d &&&  ~~~e)) + 2 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 3 * (e &&& (d ||| f)) + 11 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 1 * (f ^^^ (d ||| ( ~~~e &&& f))) - 1 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 4 * ((e &&& f) ||| (d &&& (e ||| f))) - 1 * (f ^^^  ~~~(d &&& (e ||| f))) - 2 * (e &&&  ~~~f) + 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 1 * (e &&&  ~~~(d &&& f)) - 5 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) - 2 * (e ^^^ f) + 11 * (e ^^^ ( ~~~d ||| (e ||| f))) + 5 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 2 * (d ||| e) + 4 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 5 * (f ^^^  ~~~(d ||| e)) - 5 * (e ^^^ (d &&&  ~~~f)) - 1 * (e ^^^  ~~~(d |||  ~~~f)) - 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 5 * (e ^^^  ~~~(d &&&  ~~~f)) + 2 * (f ^^^ ( ~~~d ||| (e &&& f))) - 2 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 1 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 5 * (f ||| (d &&&  ~~~e)) + 3 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) + 4 * (f |||  ~~~(d |||  ~~~e)) + 1 *  ~~~(e ||| f) + 1 *  ~~~(d &&& (e ||| f)) + 2 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 2 * (f |||  ~~~(d ||| e)) - 11 * (f &&& (d ^^^ e)) + 11 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 4 * (e ^^^  ~~~(d ||| (e &&& f))) - 40 *  ~~~(d ||| (e ||| f)) + 8 *  ~~~(d ||| ( ~~~e ||| f)) + 2 *  ~~~( ~~~d ||| (e ||| f)) - 5 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 41 * ( ~~~d &&& ( ~~~e &&& f)) - 3 * ( ~~~d &&& (e &&& f)) - 30 * (d &&& (e &&& f)) = 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f)))

theorem xor_orn_commute1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ¬(x_1 = 0 ∨ x_1 = 0) → x_1 = 0 → False

theorem mul_selectp2_x_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  x_1 = 1#1 → ¬1#8 ≥ ↑8 → 2#8 * x = x <<< 1#8

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

theorem icmp_ne_mul_nsw_nonequal_proof : icmp_ne_mul_nsw_nonequal_before ⊑ icmp_ne_mul_nsw_nonequal_after

theorem select_icmp_ne_0_and_1073741824_and_not_8_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ¬ofBool (0#32 != x_1 &&& 1073741824#32) = 1#1 →
    ¬ofBool (x_1 &&& 1073741824#32 == 0#32) = 1#1 → x &&& BitVec.ofInt 8 (-9) = x

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

theorem e_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 trunc_sandwich_big_sum_shift2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(31#32 ≥ ↑32 ∨ 1#12 ≥ ↑12) → truncate 12 (x >>> 31#32) >>> 1#12 = 0#12

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

theorem trunc_ashr_trunc_outofrange_proof : trunc_ashr_trunc_outofrange_before ⊑ trunc_ashr_trunc_outofrange_after

theorem lshrult_02_14_exact_proof : lshrult_02_14_exact_before ⊑ lshrult_02_14_exact_after

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

theorem positive_and_odd_eq_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(2#32 == 0 || 32 != 1 && x == intMin 32 && 2#32 == -1) = true →
    ofBool (x.srem 2#32 == 1#32) = ofBool (x &&& BitVec.ofInt 32 (-2147483647) == 1#32)

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

theorem add_nosignbit_select_shl_proof : add_nosignbit_select_shl_before ⊑ add_nosignbit_select_shl_after

theorem sub_ult_zext_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 x_2 : BitVec 8),
  ofBool (x_2 - x_1 <ᵤ zeroExtend 8 x) = ofBool (x_2 == x_1) &&& x

theorem test1_thm (e e_1 : IntW 32) :
  LLVM.or (icmp IntPred.eq (LLVM.xor e_1 (const? 32 5)) (const? 32 10))
      (icmp IntPred.eq (LLVM.xor e_1 (const? 32 5)) e) ⊑
    LLVM.or (icmp IntPred.eq e_1 (const? 32 15)) (icmp IntPred.eq (LLVM.xor e_1 e) (const? 32 5))

theorem pr40493_neg3_proof : pr40493_neg3_before ⊑ pr40493_neg3_after

theorem icmp_eq_zext_ne_one_thm (e : IntW 32) :
  icmp IntPred.eq (zext 32 (icmp IntPred.ne e (const? 32 1))) e ⊑ const? 1 0

theorem PR42691_1_thm (e : IntW 32) :
  LLVM.or (icmp IntPred.slt e (const? 32 0)) (icmp IntPred.eq e (const? 32 2147483647)) ⊑
    icmp IntPred.ugt e (const? 32 2147483646)

theorem t0_proof : t0_before ⊑ t0_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 abs_must_be_positive_proof : abs_must_be_positive_before ⊑ abs_must_be_positive_after

theorem test7_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬1#32 ≥ ↑32 →
    ¬(1#32 ≥ ↑32 ∨ True ∧ (x >>> 1#32).uaddOverflow 2147483647#32 = true) →
      zeroExtend 64 (x >>> 1#32) + 2147483647#64 = zeroExtend 64 (x >>> 1#32 + 2147483647#32)

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

theorem sle_smin1_proof : sle_smin1_before ⊑ sle_smin1_after

theorem test23_proof : test23_before ⊑ test23_after

theorem ofBitVecZextMsb_eq_ofBitVecZext_mul_two_zeroExtend (x : BitVec w)
    (i : Nat) (hi : i ≤ w) :
    (BitStream.ofBitVecZextMsb x i) =
    ((BitStream.ofBitVecSext ((x.zeroExtend (w + 1)) <<< 1)) i)

theorem ashr_or_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ x + 1#8 ≥ ↑8) →
    ¬x ≥ ↑8 →
      (BitVec.ofInt 8 (-64)).sshiftRight' x ||

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

theorem p0_proof : p0_before ⊑ p0_after

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

theorem p0_scalar_urem_by_const_thm (e : IntW 32) :
  icmp IntPred.eq (urem (LLVM.and e (const? 32 128)) (const? 32 6)) (const? 32 0) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 128)) (const? 32 0)

theorem bv_276_2 :
    ∀ (e e_1 : LLVM.IntW 5), LLVM.mul (LLVM.udiv e_1 e) (LLVM.sub (LLVM.const? 5 0) e) ⊑ LLVM.sub (LLVM.urem e_1 e) e_1

theorem test6_thm (e : IntW 16) : ashr (shl (zext 32 e) (const? 32 16)) (const? 32 16) ⊑ sext 32 e

theorem ne_commuted_equal_minus_1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(x == 0 || 8 != 1 && 42#8 == intMin 8 && x == -1) = true →
    ofBool (x_1 != -1#8) &&& ofBool (x_1 + 1#8 ≤ᵤ (42#8).sdiv x) = ofBool (x_1 <ᵤ (42#8).sdiv x)

theorem scalar_i32_lshr_and_negC_slt_thm (e e_1 : IntW 32) :
  icmp IntPred.slt (LLVM.and (lshr e_1 e) (const? 32 (-2147483648))) (const? 32 0) ⊑
    icmp IntPred.slt (lshr e_1 e) (const? 32 0)

theorem PR75692_1_thm.extracted_1._1 : ∀ (x : BitVec 32), x ^^^ 4#32 ||

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

theorem ashrsgt_03_05_proof : ashrsgt_03_05_before ⊑ ashrsgt_03_05_after

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

theorem PR42691_9_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.sgt e (const? 32 13)) (icmp IntPred.ne e (const? 32 2147483647)) ⊑
    icmp IntPred.ult (add e (const? 32 (-14))) (const? 32 2147483633)

theorem alive_AndOrXor_1683_1 : alive_AndOrXor_1683_1_src ⊑ alive_AndOrXor_1683_1_tgt

theorem exact_ashr_eq_exactdiv_proof : exact_ashr_eq_exactdiv_before ⊑ exact_ashr_eq_exactdiv_after

theorem scalar_i32_shl_and_signbit_ne_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (LLVM.and (shl e_1 e) (const? 32 (-2147483648))) (const? 32 0) ⊑
    icmp IntPred.slt (shl e_1 e) (const? 32 0)

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_5_proof : masked_icmps_mask_notallzeros_bmask_mixed_swapped_5_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_swapped_5_after

theorem test_shl_nuw__nuw_is_safe_proof : test_shl_nuw__nuw_is_safe_before ⊑ test_shl_nuw__nuw_is_safe_after

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

theorem main3_proof : main3_before ⊑ main3_after

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

theorem e_1851 :
     - 6 * (c ^^^ (a ||| (b &&& c))) - 2 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 1 *  ~~~( ~~~a &&& (b ||| c)) - 3 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) + 2 * (b |||  ~~~(a ||| c)) - 1 * (c ^^^  ~~~(a ||| b)) + 2 * ((a ^^^ b) ||| (a ^^^ c)) - 1 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 7 * (c ^^^ ( ~~~a ||| (b ||| c))) + 11 * (c &&&  ~~~(a ^^^ b)) - 2 * (c |||  ~~~(a |||  ~~~b)) + 1 * (b ^^^ (a ||| (b &&& c))) + 5 * (a &&& c) + 4 * (b ^^^  ~~~(a ||| c)) + 7 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) + 1 * ((a &&& b) |||  ~~~(b ||| c)) + 3 * (b |||  ~~~(a |||  ~~~c)) - 1 * ( ~~~b ||| (a ^^^ c)) - 3 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) - 7 * ((a &&& c) ^^^ (b ||| c)) + 5 *  ~~~( ~~~a ||| ( ~~~b &&& c)) + 3 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) - 1 *  ~~~(b &&& c) + 1 * (c &&& (a |||  ~~~b)) + 11 * ( ~~~c |||  ~~~(a ^^^ b)) + 5 * (b ^^^ (a ||| (b ^^^ c))) - 1 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) - 6 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) + 3 *  ~~~( ~~~a ||| (b &&& c)) + 2 * (b ^^^ (a &&& ( ~~~b ||| c))) - 1 * ((a ||| b) &&& (b ^^^ c)) + 1 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) - 11 * (b ^^^  ~~~(a ||| (b &&& c))) + 11 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) + 7 *  ~~~(a ^^^ b) + 11 * (a ||| ( ~~~b &&& c)) + 1 * ((b &&& c) ||| (a &&& (b ||| c))) - 11 *  ~~~(a ||| (b ||| c)) - 34 *  ~~~(a ||| ( ~~~b ||| c)) - 53 *  ~~~( ~~~a ||| (b ||| c)) - 32 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 28 * ( ~~~a &&& ( ~~~b &&& c)) + 8 * ( ~~~a &&& (b &&& c)) - 17 * (a &&& ( ~~~b &&& c)) - 70 * (a &&& (b &&& c)) = 1 *  ~~~(a &&&  ~~~b) - 5 * ( ~~~a ||| (b &&& c))

theorem and_not_or_commute5_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬((x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true ∨
        (x_1 == 0 || 32 != 1 && 42#32 == intMin 32 && x_1 == -1) = true ∨
          (x_1 == 0 || 32 != 1 && 42#32 == intMin 32 && x_1 == -1) = true ∨
            (x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true) →
    (x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true ∨
        (x_1 == 0 || 32 != 1 && 42#32 == intMin 32 && x_1 == -1) = true →
      False

theorem add_smax_simplify_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.saddOverflow 126#8 = true) →
    ¬ofBool (BitVec.ofInt 8 (-2) <ₛ x + 126#8) = 1#1 → BitVec.ofInt 8 (-2) = x + 126#8

theorem add_shl_same_amount_partial_nsw1_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 6),
  ¬(True ∧ (x_2 <<< x_1).sshiftRight' x_1 ≠ x_2 ∨ x_1 ≥ ↑6 ∨ True ∧ (x <<< x_1).sshiftRight' x_1 ≠ x ∨ x_1 ≥ ↑6) →
    ¬x_1 ≥ ↑6 → x_2 <<< x_1 + x <<< x_1 = (x_2 + x) <<< x_1

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

theorem and1_shl1_is_cmp_eq_0_multiuse_proof : and1_shl1_is_cmp_eq_0_multiuse_before ⊑ and1_shl1_is_cmp_eq_0_multiuse_after

theorem addsub_combine_constants_proof : addsub_combine_constants_before ⊑ addsub_combine_constants_after

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

theorem ashr_slt_exact_proof : ashr_slt_exact_before ⊑ ashr_slt_exact_after

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

theorem ashrslt_03_03_exact_proof : ashrslt_03_03_exact_before ⊑ ashrslt_03_03_exact_after

theorem icmp_ne_sext_eq_otherwise_proof : icmp_ne_sext_eq_otherwise_before ⊑ icmp_ne_sext_eq_otherwise_after

theorem select_icmp_and_2147483648_eq_0_xor_2147483648_proof : select_icmp_and_2147483648_eq_0_xor_2147483648_before ⊑ select_icmp_and_2147483648_eq_0_xor_2147483648_after

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

theorem test1_proof : test1_before ⊑ test1_after

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

theorem test19_proof : test19_before ⊑ test19_after

theorem logic_and_logic_or_5_proof : logic_and_logic_or_5_before ⊑ logic_and_logic_or_5_after

theorem test_shl_nuw_nsw__none_are_safe_proof : test_shl_nuw_nsw__none_are_safe_before ⊑ test_shl_nuw_nsw__none_are_safe_after

theorem select1_proof : select1_before ⊑ select1_after

theorem xor_logic_and_or2_proof : xor_logic_and_or2_before ⊑ xor_logic_and_or2_after

theorem positive_samevar_shlnsw_ashrexact_proof : positive_samevar_shlnsw_ashrexact_before ⊑ positive_samevar_shlnsw_ashrexact_after

theorem shrink_xor_thm.extracted_1._1 : ∀ (x : BitVec 64), truncate 32 (x ^^^ 1#64) = truncate 32 x ^^^ 1#32

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 and_not_or_commute7_proof : and_not_or_commute7_before ⊑ and_not_or_commute7_after

theorem srem_eq_zero_of_smod {w : Nat} {x y : BitVec w} :
  x.smod y = 0#_ → x.srem y = 0#_

theorem trunc_shl_15_i16_i64_thm.extracted_1._1 : ∀ (x : BitVec 64), ¬15#64 ≥ ↑64 → 15#16 ≥ ↑16 → False

theorem e_1587 :
     - 5 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) - 3 * ( ~~~c ||| (a ^^^ b)) + 3 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) - 2 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 11 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) + 11 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 1 * ( ~~~a ||| ( ~~~b ||| c)) + 1 * (b &&&  ~~~(a ^^^ c)) - 2 * (a ||| (b &&& c)) + 7 * (c ||| (a &&& b)) - 8 *  ~~~(a ||| ( ~~~b ||| c)) - 5 *  ~~~( ~~~a ||| (b ||| c)) - 9 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 15 * ( ~~~a &&& ( ~~~b &&& c)) - 13 * ( ~~~a &&& (b &&& c)) - 26 * (a &&& ( ~~~b &&& c)) + 2 * (a &&& (b &&& c)) = 5 * ( ~~~c &&&  ~~~(a ^^^ b)) - 3 *  ~~~(a ||| (b ||| c))

theorem positive_samevar_shlnsw_proof : positive_samevar_shlnsw_before ⊑ positive_samevar_shlnsw_after

theorem mul_add_to_mul_9_proof : mul_add_to_mul_9_before ⊑ mul_add_to_mul_9_after

theorem and_ne_with_one_bit_diff_constants3_thm (e : IntW 8) :
  LLVM.and (icmp IntPred.ne e (const? 8 65)) (icmp IntPred.ne e (const? 8 (-63))) ⊑
    icmp IntPred.ne (LLVM.and e (const? 8 127)) (const? 8 65)

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

theorem ashr_ugt_14_proof : ashr_ugt_14_before ⊑ ashr_ugt_14_after

theorem sel_zext_constants_thm (e : IntW 1) :
  zext 16 (select e (const? 8 (-1)) (const? 8 42)) ⊑ select e (const? 16 255) (const? 16 42)

theorem bv_AddSub_1619 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.sub (LLVM.sub e_1 e) e_1 ⊑ LLVM.sub (LLVM.const? w 0) e

theorem zext_sext_ugt_known_nonneg_thm (e e_1 : IntW 8) :
  icmp IntPred.ugt (zext 32 (LLVM.and e_1 (const? 8 127))) (sext 32 e) ⊑
    icmp IntPred.ugt (LLVM.and e_1 (const? 8 127)) e

theorem shl_add_nsw_nuw_proof : shl_add_nsw_nuw_before ⊑ shl_add_nsw_nuw_after

lemma CNFA.union_spec (m1 m2 : CNFA n)
  {M1 : NFA' n} {M2 : NFA' n} :
    m1.Sim M1 →
    m2.Sim M2 →
    (m1.union m2).Sim (M1.union M2)

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

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

theorem shl_nsw_add_nsw_nuw_proof : shl_nsw_add_nsw_nuw_before ⊑ shl_nsw_add_nsw_nuw_after

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

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

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

theorem orn_and_cmp_1_logical_thm (e : IntW 1) (e_1 e_2 : IntW 37) :
  select (icmp IntPred.sle e_2 e_1) (const? 1 1) (select e (icmp IntPred.sgt e_2 e_1) (const? 1 0)) ⊑
    select (icmp IntPred.sle e_2 e_1) (const? 1 1) e

theorem sub_1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → (x_1 ^^^ 123#8) - x ^^^ -1#8 = (x_1 ^^^ BitVec.ofInt 8 (-124)) + x

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

theorem isMonotone_matchVarArg_aux (lets : Lets d Γ_in eff Γ_out) :
    (
     ∀  (Δ_out : Ctxt d.Ty)
        (matchLets : Lets d Δ_in EffectKind.pure Δ_out) (l : List d.Ty)
        (argsl : HVector Γ_out.Var l) (argsr : HVector Δ_out.Var l),
        (matchArg lets matchLets argsl argsr).IsMonotone
    )
    ∧ (
      ∀ (Δ_out : Ctxt d.Ty) (t : d.Ty) (v : Γ_out.Var t)
        (matchLets : Lets d Δ_in EffectKind.pure Δ_out)
        (w : Var Δ_out t),
        (matchVar lets v matchLets w).IsMonotone
    )

theorem ashr_ult_4_proof : ashr_ult_4_before ⊑ ashr_ult_4_after

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

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

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

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

theorem bools2_logical_commute1_and2_proof : bools2_logical_commute1_and2_before ⊑ bools2_logical_commute1_and2_after

theorem test83_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 16),
  ¬(True ∧ x.saddOverflow (-1#64) = true ∨ truncate 32 (x + -1#64) ≥ ↑32) → truncate 32 x + -1#32 ≥ ↑32 → False

theorem t7_proof : t7_before ⊑ t7_after

theorem sub_ashr_and_i32_proof : sub_ashr_and_i32_before ⊑ sub_ashr_and_i32_after

theorem fold_sext_to_and_wrong9_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x &&& 128#32 != 1#32) = 1#1

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

theorem test_trunc_proof : test_trunc_before ⊑ test_trunc_after

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

theorem no_shift_xor_multiuse_cmp_thm.extracted_1._5 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ofBool (0#32 != x_3 &&& 4096#32) = 1#1 →
    ofBool (x_3 &&& 4096#32 == 0#32) = 1#1 → x_2 * x_1 = (x_2 ||| x_3 &&& 4096#32 ^^^ 4096#32) * x

theorem select_1_thm.extracted_1._18 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1) (x_3 x_4 : BitVec 8) (x_5 : BitVec 1),
  x_5 = 1#1 → x_4 ^^^ (x_3 ^^^ 45#8) ^^^ -1#8 = x_3 ^^^ x_4 ^^^ BitVec.ofInt 8 (-46)

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

theorem test_nsw_and_signed_pred_thm (e : IntW 64) :
  icmp IntPred.sgt (sub (const? 64 3) e { «nsw» := true, «nuw» := false }) (const? 64 10) ⊑
    icmp IntPred.slt e (const? 64 (-7))

theorem slt_zero_ne_ne_0_thm (e : IntW 32) :
  icmp IntPred.ne (zext 32 (icmp IntPred.ne e (const? 32 0))) (lshr e (const? 32 31)) ⊑
    icmp IntPred.sgt e (const? 32 0)

theorem e_2496 :
    2 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 3 * (f ||| (d &&&  ~~~e)) - 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 5 * ( ~~~d ||| (e ||| f)) + 11 * (e ^^^ (d &&& f)) - 2 * (f ^^^ ( ~~~d &&& (e ||| f))) - 11 * ( ~~~d ||| (e ^^^ f)) - 6 * ( ~~~f &&& (d ^^^ e)) - 2 * (e |||  ~~~f) - 5 * ( ~~~d ||| ( ~~~e &&& f)) + 3 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 1 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 1 *  ~~~(d &&&  ~~~e) - 1 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 2 * (f &&&  ~~~(d ^^^ e)) + 1 * (e &&& (d ||| f)) - 1 * ( ~~~d ||| ( ~~~e ||| f)) - 1 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 1 * (e ^^^ (d |||  ~~~f)) - 6 * (f &&& (d ||| e)) + 7 * (e ^^^ (d &&& ( ~~~e ||| f))) + 1 * (e ^^^ ( ~~~d &&& (e ||| f))) + 4 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 7 * (e ||| (d &&& f)) + 2 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 1 * (e ^^^  ~~~(d &&& (e &&& f))) + 1 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 2 * (f ^^^ (d ||| (e &&& f))) + 5 * (e ^^^  ~~~(d &&& (e ||| f))) + 1 * (f ^^^ ( ~~~d ||| (e ||| f))) + 3 * (d ||| e) + 1 * (e &&&  ~~~f) - 3 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 7 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 1 * ( ~~~d &&& (e ^^^ f)) - 1 * (d &&&  ~~~e) - 1 * (d ^^^ (e ^^^ f)) + 7 * (d ||| (e ||| f)) + 2 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 2 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 3 *  ~~~( ~~~d ||| (e ^^^ f)) + 3 * (f ||| (d &&& e)) - 1 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 7 * (d ^^^ f) - 1 * (e ^^^ ( ~~~d ||| (e &&& f))) - 5 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 1 * (e |||  ~~~(d |||  ~~~f)) + 5 *  ~~~(d ^^^ e) - 6 *  ~~~f + 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) + 1 * (f ^^^  ~~~(d |||  ~~~e)) - 2 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 6 * (d ||| ( ~~~e &&& f)) + 7 * (d ^^^ (e ||| f)) + 2 * (e ^^^ (d ||| ( ~~~e ||| f))) - 5 * ((d &&& e) ||| (e ^^^ f)) + 7 * (e &&& f) + 1 * (f ^^^ (d &&& e)) + 3 * ((d ||| e) &&& (e ^^^ f)) + 4 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 7 *  ~~~(e ^^^ f) + 3 *  ~~~(d ||| (e ^^^ f)) - 6 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) + 7 * ( ~~~d &&& ( ~~~e ||| f)) - 6 * (f ^^^ (d &&&  ~~~e)) - 3 * (f ^^^ ( ~~~d ||| (e &&& f))) + 2 * (d ||| ( ~~~e ||| f)) + 5 *  ~~~(d ||| e) - 2 * (f ^^^ (d ||| ( ~~~e ||| f))) + 1 * ((d &&& f) |||  ~~~(e ||| f)) + 1 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 2 * (d ^^^ ( ~~~e ||| f)) - 11 * ((d |||  ~~~e) &&& (e ^^^ f)) - 2 * ( ~~~d &&& (e ||| f)) + 13 *  ~~~(d ||| (e ||| f)) + 2 *  ~~~(d ||| ( ~~~e ||| f)) + 20 *  ~~~( ~~~d ||| (e ||| f)) - 3 * ( ~~~d &&& ( ~~~e &&& f)) - 9 * ( ~~~d &&& (e &&& f)) + 18 * (d &&& ( ~~~e &&& f)) + 17 * (d &&& (e &&& f)) = 18 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 2 * ((d &&& f) ^^^ (e ||| f))

theorem sle_smax3_proof : sle_smax3_before ⊑ sle_smax3_after

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (x <ₛ x) = 0#1

theorem invert_both_cmp_operands_sub_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool ((x_1 ^^^ -1#32) - x <ᵤ 42#32) = ofBool (BitVec.ofInt 32 (-43) <ᵤ x_1 + x)

theorem icmp_eq_zext_eq_zero_proof : icmp_eq_zext_eq_zero_before ⊑ icmp_eq_zext_eq_zero_after

@[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 select_icmp_ne_0_and_4096_xor_4096_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (0#32 != x_1 &&& 4096#32) = 1#1 → x = x_1 &&& 4096#32 ^^^ x ^^^ 4096#32

theorem splat_mul_known_lz_proof : splat_mul_known_lz_before ⊑ splat_mul_known_lz_after

theorem negate_shl_xor_thm.extracted_1._1 : ∀ (x x_1 : BitVec 4),
  ¬x ≥ ↑4 → 0#4 - (x_1 ^^^ 5#4) <<< x = ((x_1 ^^^ BitVec.ofInt 4 (-6)) + 1#4) <<< x

theorem poison_ne_value (a : α) :
    @Ne (no_index _) poison (value a)

theorem slt_swap_or_not_max_commute_proof : slt_swap_or_not_max_commute_before ⊑ slt_swap_or_not_max_commute_after

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

theorem test_proof : test_before ⊑ test_after

@[simp] theorem isPoison_value : isPoison (value a) = false

theorem shl_sub_i64_proof : shl_sub_i64_before ⊑ shl_sub_i64_after

theorem ult_umin3_proof : ult_umin3_before ⊑ ult_umin3_after

theorem cast_test_2002h08h02_proof : cast_test_2002h08h02_before ⊑ cast_test_2002h08h02_after

theorem t3_proof : t3_before ⊑ t3_after

theorem e_2193 :
     - 5 * (d ||| (e &&& f)) - 6 * ((d &&& f) |||  ~~~(e ||| f)) - 11 *  ~~~(d &&& f) - 7 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 3 * (e &&&  ~~~(d &&&  ~~~f)) - 3 * (f ^^^ (d ||| (e &&& f))) - 3 *  ~~~e + 2 * (d &&& (e ||| f)) + 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 3 * (f &&&  ~~~(d &&& e)) - 1 *  ~~~(d ||| (e &&& f)) + 4 * ( ~~~d &&& (e ||| f)) - 2 * (f |||  ~~~(d ||| e)) - 1 *  ~~~(d ||| ( ~~~e &&& f)) + 7 * (e ^^^  ~~~(d &&&  ~~~f)) + 1 * (e ^^^ (d &&& ( ~~~e ||| f))) + 1 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 4 * (f ^^^ (d |||  ~~~e)) - 3 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 2 *  ~~~f - 7 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 1 * (f ^^^ (d &&&  ~~~e)) + 1 * ( ~~~f |||  ~~~(d ^^^ e)) - 2 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 2 *  ~~~d - 1 * ((d &&& e) ^^^ (e ||| f)) + 4 *  ~~~(d ||| e) + 7 * (f &&& (d ^^^ e)) + 1 * (e |||  ~~~f) - 1 * (d |||  ~~~e) - 2 * ( ~~~f ||| (d ^^^ e)) + 11 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 2 * (e &&&  ~~~(d &&& f)) - 1 * (e ||| f) - 2 * ( ~~~d ||| ( ~~~e &&& f)) - 7 * (d &&& ( ~~~e ||| f)) + 11 *  ~~~(d &&& (e ^^^ f)) - 11 *  ~~~(d &&& (e &&& f)) - 1 * ((d &&& e) ||| (e ^^^ f)) - 5 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 5 *  ~~~(d |||  ~~~e) + 1 * (d ^^^ e) - 11 *  ~~~(d ^^^ e) + 29 *  ~~~(d ||| (e ||| f)) + 22 *  ~~~(d ||| ( ~~~e ||| f)) + 58 *  ~~~( ~~~d ||| (e ||| f)) + 47 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 24 * ( ~~~d &&& ( ~~~e &&& f)) + 29 * ( ~~~d &&& (e &&& f)) + 25 * (d &&& ( ~~~e &&& f)) + 25 * (d &&& (e &&& f)) = 6 * (d ||| ( ~~~e &&& f)) + 3 * (e ^^^ (d ||| (e ^^^ f)))

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

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

@[simp]
theorem HTermEnv.of_mkFsmEnvOfTenv {wcard tcard bcard ncard icard pcard : Nat}
    {wenv : Fin wcard → Nat} {tctx : Term.Ctx wcard tcard}
    (tenv : tctx.Env wenv)
    (benv : Term.BoolEnv bcard)
    (nenv : Term.NatEnv ncard)
    (ienv : Term.IntEnv icard)
    (penv : Predicate.Env pcard) :
    HTermEnv (mkFsmEnvOfTenv tenv benv nenv ienv penv) tenv benv

theorem add_smax_simplify2_thm (e : IntW 8) :
  select (icmp IntPred.sgt (add e (const? 8 127) { «nsw» := true, «nuw» := false }) (const? 8 (-2)))
      (add e (const? 8 127) { «nsw» := true, «nuw» := false }) (const? 8 (-2)) ⊑
    add e (const? 8 127) { «nsw» := true, «nuw» := false }

theorem slt_zero_eq_i1_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  ¬31#32 ≥ ↑32 → ofBool (zeroExtend 32 x_1 == x >>> 31#32) = ofBool (-1#32 <ₛ x) ^^^ x_1

theorem test2_proof : test2_before ⊑ test2_after

theorem test8_thm (e : IntW 8) : LLVM.and (LLVM.and e (const? 8 3)) (const? 8 4) ⊑ const? 8 0

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

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

theorem slt_swap_and_not_max_logical_proof : slt_swap_and_not_max_logical_before ⊑ slt_swap_and_not_max_logical_after

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

theorem zext_ult_zext_proof : zext_ult_zext_before ⊑ zext_ult_zext_after

theorem test19_proof : test19_before ⊑ test19_after

theorem e_1907 :
     - 2 * (a &&& ( ~~~b ||| c)) + 7 * ((a &&& c) |||  ~~~(b ||| c)) - 6 * ( ~~~a ||| (b ||| c)) + 11 * (b ^^^ (a ||| (b ||| c))) - 7 * (a &&& (b ^^^ c)) - 11 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) + 2 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 2 * (b ^^^ (a ||| (b &&& c))) + 1 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 5 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) + 2 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) + 1 * (c &&& (a ||| b)) - 11 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) + 1 *  ~~~(a &&& (b ||| c)) + 11 * ((a &&& c) ||| (b &&&  ~~~c)) - 1 *  ~~~(a ^^^ ( ~~~b ||| c)) - 7 *  ~~~(b ^^^ c) - 5 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) + 2 * (c ^^^ (a ||| ( ~~~b ||| c))) + 2 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 6 *  ~~~( ~~~a &&& ( ~~~b ||| c)) - 2 * (b ^^^ (a &&&  ~~~c)) - 2 * (b ^^^  ~~~(a |||  ~~~c)) + 3 *  ~~~c - 6 *  ~~~(b &&&  ~~~c) - 7 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) + 1 *  ~~~( ~~~a &&& ( ~~~b &&& c)) - 3 *  ~~~(a &&&  ~~~a) + 11 * (b &&&  ~~~c) + 4 *  ~~~( ~~~a ||| (b &&& c)) - 5 * (b &&& c) - 6 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 1 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) + 5 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 7 * (c ^^^  ~~~(a ||| b)) - 2 * (c ^^^  ~~~(a &&& b)) + 3 * (c ^^^ ( ~~~a ||| (b ||| c))) + 4 * (c ^^^  ~~~(a &&& (b &&& c))) + 5 * (a |||  ~~~c) - 2 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) - 2 * ((b &&& c) ||| (a &&& (b ||| c))) + 2 *  ~~~(a ||| (b &&& c)) - 1 * ((a &&&  ~~~b) ||| (b ^^^ c)) + 14 *  ~~~(a ||| (b ||| c)) + 9 *  ~~~(a ||| ( ~~~b ||| c)) + 7 *  ~~~( ~~~a ||| (b ||| c)) + 18 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 39 * ( ~~~a &&& ( ~~~b &&& c)) + 64 * ( ~~~a &&& (b &&& c)) + 25 * (a &&& (b &&& c)) =  - 14 * (a &&& ( ~~~b &&& c))

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

theorem and_zext_demanded_thm (e : IntW 16) (e_1 : IntW 32) :
  LLVM.and (LLVM.or e_1 (const? 32 255)) (zext 32 (lshr e (const? 16 8))) ⊑
    zext 32 (lshr e (const? 16 8)) { «nneg» := true }

theorem lshr_lshr_pow2_const_proof : lshr_lshr_pow2_const_before ⊑ lshr_lshr_pow2_const_after

theorem e_207 :
     - 6 * y + 1 *  ~~~(x &&& y) - 2 * x + 5 *  ~~~(x ||| y) + 5 *  ~~~(x |||  ~~~y) + 8 * (x &&& y) = 6 *  ~~~y - 7 * (x &&&  ~~~y)

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

theorem negate_xor_proof : negate_xor_before ⊑ negate_xor_after

theorem bools2_logical_commute1_thm.extracted_1._17 : ∀ (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 → 1#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 ashr_ult_11_proof : ashr_ult_11_before ⊑ ashr_ult_11_after

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

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

theorem liftEffect_eq_pure_cast_of [Pure m] {e₁ e₂} (heq : e₁ = .pure) (hle : e₁ ≤ e₂) :
    liftEffect hle (α := α) (m := m) = fun x => Pure.pure (cast (by subst heq; rfl) x)

theorem ashr_lowmask_proof : ashr_lowmask_before ⊑ ashr_lowmask_after

theorem test67_proof : test67_before ⊑ test67_after

theorem and_or3_commuted_thm.extracted_1._4 : ∀ (x x_1 : BitVec 1) (x_2 x_3 : BitVec 32),
  ofBool (x_3 == x_2) &&& x_1 = 1#1 → x_1 = 1#1 → ofBool (x_3 != x_2) = 1#1 → x = 1#1

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

theorem wrongimm_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬14#16 ≥ ↑16 →
    14#16 ≥ ↑16 ∨ True ∧ signExtend 16 (truncate 8 (x.sshiftRight' 14#16)) ≠ x.sshiftRight' 14#16 → False

theorem neg_slt_1_proof : neg_slt_1_before ⊑ neg_slt_1_after

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

theorem urem_common_divisor_defined_cond_proof : urem_common_divisor_defined_cond_before ⊑ urem_common_divisor_defined_cond_after

theorem or_and2_commuted_thm (e e_1 e_2 : IntW 1) :
  select (LLVM.or e_2 (LLVM.xor e_1 (const? 1 1))) e_2 e ⊑ select e_2 (const? 1 1) (select e_1 e (const? 1 0))

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

theorem scalar_i32_signbit_lshr_and_eq_X_is_constant1_proof : scalar_i32_signbit_lshr_and_eq_X_is_constant1_before ⊑ scalar_i32_signbit_lshr_and_eq_X_is_constant1_after

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

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

theorem incr_add : a + (@ofBitVecSext w 1) ≈ʷ a.incr

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

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

theorem test11_thm (e : IntW 32) :
  icmp IntPred.ult (LLVM.udiv (const? 32 4) e) (const? 32 1) ⊑ icmp IntPred.ugt e (const? 32 4)

theorem test_eq_0_and_15_add_1_proof : test_eq_0_and_15_add_1_before ⊑ test_eq_0_and_15_add_1_after

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 shl_add_nsw_nuw_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(x ≥ ↑32 ∨ True ∧ (1#32 <<< x).saddOverflow (-1#32) = true ∨ True ∧ (1#32 <<< x).uaddOverflow (-1#32) = true) →
    1#32 <<< x + -1#32 = -1#32

theorem set_bits_thm.extracted_1._3 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → True ∧ (x &&& BitVec.ofInt 8 (-6) &&& 0#8 != 0) = true → False

theorem select_add_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 1), ¬x_1 = 1#1 → x = x + 0#64

@[simp, simp_denote, simp_sllvm]
lemma run_bind (x : EffectM α) :
    StateT.run (x >>= f : EffectM β) s
    = StateT.run x s >>= (fun p => StateT.run (f p.1) p.2)

@[simp] theorem map'_nil : map' f g nil = nil

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

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

theorem e_2043 :
     - 2 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 5 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 5 * ( ~~~f |||  ~~~(d ^^^ e)) + 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 1 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 1 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 1 * ( ~~~d ||| (e ^^^ f)) - 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 3 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) - 1 * (e ^^^  ~~~(d |||  ~~~f)) - 2 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 1 * (e ||| (d &&& f)) - 2 *  ~~~(d ^^^ f) + 2 * (f |||  ~~~(d ^^^ e)) - 7 * (e ||| (d &&&  ~~~f)) - 2 * (e ^^^ (d |||  ~~~f)) - 5 * (e |||  ~~~(d ||| f)) + 2 *  ~~~(d &&& (e ^^^ f)) - 2 * (e ||| f) + 11 * ( ~~~f &&&  ~~~(d ^^^ e)) + 3 *  ~~~(d &&& (e ||| f)) - 1 * (e ^^^ (d ||| (e ^^^ f))) + 5 * (d ||| e) - 2 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 1 * (f ||| (d ^^^ e)) - 1 * d + 2 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 11 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 11 * ( ~~~e &&& (d ^^^ f)) - 10 *  ~~~(d ||| (e ||| f)) + 1 *  ~~~(d ||| ( ~~~e ||| f)) - 13 *  ~~~( ~~~d ||| (e ||| f)) - 1 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 9 * ( ~~~d &&& (e &&& f)) + 2 * (d &&& ( ~~~e &&& f)) + 17 * (d &&& (e &&& f)) = 23 * ( ~~~d &&& ( ~~~e &&& f))

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

theorem t7_proof : t7_before ⊑ t7_after

theorem nonexact_ashr_eq_exactdiv_proof : nonexact_ashr_eq_exactdiv_before ⊑ nonexact_ashr_eq_exactdiv_after

@[simp, grind=] theorem castCtxt_castCtxt (h₁ : Γ = Δ) (h₂ : Δ = Ξ) :
    (v.castCtxt h₁).castCtxt h₂ = v.castCtxt (by simp [*])

theorem ult_umin3_thm (e e_1 : IntW 32) :
  icmp IntPred.ugt (add e_1 (const? 32 3))
      (select (icmp IntPred.ult (add e_1 (const? 32 3)) e) (add e_1 (const? 32 3)) e) ⊑
    icmp IntPred.ult e (add e_1 (const? 32 3))

theorem negtest_near_pow2_cmpval_would_overflow_into_signbit_proof : negtest_near_pow2_cmpval_would_overflow_into_signbit_before ⊑ negtest_near_pow2_cmpval_would_overflow_into_signbit_after

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

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

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

theorem ashrslt_01_02_proof : ashrslt_01_02_before ⊑ ashrslt_01_02_after

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

theorem eq_optimized_highbits_cmp_proof : eq_optimized_highbits_cmp_before ⊑ eq_optimized_highbits_cmp_after

@[simp, grind=] theorem castCtxt_rfl (h : Γ = Γ) : v.castCtxt h = v

theorem canonicalize_logic_first_and0_proof : canonicalize_logic_first_and0_before ⊑ canonicalize_logic_first_and0_after

theorem canonicalize_logic_first_or0_nsw_thm (e : IntW 32) :
  LLVM.or (add e (const? 32 112) { «nsw» := true, «nuw» := false }) (const? 32 15) ⊑
    add (LLVM.or e (const? 32 15)) (const? 32 112) { «nsw» := true, «nuw» := false }

theorem test13_proof : test13_before ⊑ test13_after

theorem test69_and_proof : test69_and_before ⊑ test69_and_after

theorem test10_proof : test10_before ⊑ test10_after

theorem both_proof : both_before ⊑ both_after

theorem select_and_icmp_zero_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 == 0#32) = 1#1 → x_2 &&& x_1 = 0#32

theorem test15g_proof : test15g_before ⊑ test15g_after

theorem e_1664 :
     - 11 *  ~~~(a ||| b) + 5 * ( ~~~a ||| ( ~~~b &&& c)) - 7 * (c &&& (a |||  ~~~b)) - 5 * b + 1 * (b ^^^  ~~~(a &&& c)) - 11 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) - 1 *  ~~~(a ^^^ (b ^^^ c)) + 2 * (a ^^^ ( ~~~b &&& c)) - 1 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 11 * (a ||| (b ^^^ c)) + 5 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) + 2 * ( ~~~b &&&  ~~~(a ^^^ c)) - 3 * ((a &&& b) ^^^ (a ^^^ ( ~~~b ||| c))) + 2 * (b ^^^  ~~~(a &&&  ~~~c)) - 11 *  ~~~(a &&&  ~~~c) + 11 * ((a &&& c) ||| (b &&&  ~~~c)) - 1 * (a &&& c) + 15 *  ~~~(a ||| (b ||| c)) - 20 *  ~~~( ~~~a ||| (b ||| c)) - 14 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 15 * ( ~~~a &&& ( ~~~b &&& c)) + 26 * ( ~~~a &&& (b &&& c)) - 6 * (a &&& ( ~~~b &&& c)) + 2 * (a &&& (b &&& c)) =  - 2 *  ~~~b

theorem t2_thm.extracted_1._2 : ∀ (x : BitVec 32) (x_1 : BitVec 64),
  ¬(x ≥ ↑32 ∨ zeroExtend 64 (1#32 <<< x) = 0) →
    ¬(True ∧ x.msb = true ∨ zeroExtend 64 x ≥ ↑64) → x_1 / zeroExtend 64 (1#32 <<< x) = x_1 >>> zeroExtend 64 x

theorem eq_umax4_proof : eq_umax4_before ⊑ eq_umax4_after

theorem t0_proof : t0_before ⊑ t0_after

theorem ofBitVec_sub_congr (h1 : ofBitVecSext x ≈ʷ a) (h2 : ofBitVecSext y ≈ʷ b) : ofBitVecSext (x - y) ≈ʷ a - b

theorem bool_add_ashr_proof : bool_add_ashr_before ⊑ bool_add_ashr_after

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

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

theorem eq_commuted_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(x == 0 || 8 != 1 && 43#8 == intMin 8 && x == -1) = true →
    ofBool (x_1 == 0#8) ||

theorem cmpne_xor_cst3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 ^^^ 10#32 != x ^^^ 10#32) = ofBool (x_1 != x)

theorem sdiv_common_divisor_defined_cond_proof : sdiv_common_divisor_defined_cond_before ⊑ sdiv_common_divisor_defined_cond_after

theorem udiv_ne_big_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬x = 0 → ofBool (x_1 / x != BitVec.ofInt 8 (-128)) = ofBool (x_1 != BitVec.ofInt 8 (-128)) ||

theorem udiv400_proof : udiv400_before ⊑ udiv400_after

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 or_nosignbit_select_lshr_thm (e : IntW 32) (e_1 : IntW 1) :
  lshr (select e_1 (LLVM.or e (const? 32 2147418112)) e) (const? 32 8) ⊑
    select e_1 (LLVM.or (lshr e (const? 32 8)) (const? 32 8388352)) (lshr e (const? 32 8))

@[simp]
theorem ctxt_cons {Γ : DerivedCtxt Δ} :
    (Γ.cons ty).ctxt = Γ.ctxt.cons ty

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

theorem ashrsgt_03_13_exact_proof : ashrsgt_03_13_exact_before ⊑ ashrsgt_03_13_exact_after

theorem lshrugt_03_12_exact_proof : lshrugt_03_12_exact_before ⊑ lshrugt_03_12_exact_after

theorem shl_lshr_pow2_not_const_case2_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(x ≥ ↑16 ∨ 3#16 ≥ ↑16) → ¬ofBool (x == 2#16) = 1#1 → 16#16 <<< x >>> 3#16 &&& 8#16 ^^^ 8#16 = 8#16

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

@[simp] lemma eval_simplify :
    p.simplify.eval = p.eval

theorem e_114 :
    5 * y - 11 * x + 1 *  ~~~(x &&&  ~~~y) - 1 *  ~~~(x ||| y) - 8 *  ~~~(x |||  ~~~y) + 9 * (x &&&  ~~~y) =  - 2 * (x ||| y) - 3 * (x &&& y)

theorem icmp_select_var_proof : icmp_select_var_before ⊑ icmp_select_var_after

theorem ne_nuw_rem_nz_proof : ne_nuw_rem_nz_before ⊑ ne_nuw_rem_nz_after

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

theorem ne_umin2_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (select (icmp IntPred.ult e_1 e) e_1 e) e ⊑ icmp IntPred.ugt e e_1

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

theorem e_1679 :
    1 * (a ||| (b ||| c)) + 11 * (b &&&  ~~~(a ^^^ c)) - 11 * (a &&&  ~~~b) + 5 * ( ~~~(a &&& b) &&& (b ^^^ c)) + 7 * ( ~~~c &&& (a ^^^ b)) - 1 * (c ^^^  ~~~(a &&&  ~~~b)) - 1 * (a ^^^ (b ^^^ c)) + 1 * (c ^^^  ~~~(a &&& ( ~~~b ||| c))) + 11 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) + 4 * ((a &&& b) ||| (b ^^^ c)) - 1 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 2 * (b ^^^ (a ||| (b ||| c))) - 11 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) + 7 * (b ^^^ ( ~~~a ||| (b ^^^ c))) + 2 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 11 * ((a &&& b) ^^^ (b ||| c)) - 1 * (c |||  ~~~(a |||  ~~~b)) + 1 * (c ^^^ ( ~~~a ||| (b ||| c))) + 1 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 11 *  ~~~(a ||| (b ||| c)) - 26 *  ~~~(a ||| ( ~~~b ||| c)) + 10 *  ~~~( ~~~a ||| (b ||| c)) - 29 * ( ~~~a &&& ( ~~~b &&& c)) - 23 * ( ~~~a &&& (b &&& c)) - 31 * (a &&& ( ~~~b &&& c)) - 11 * (a &&& (b &&& c)) =  - 1 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 7 *  ~~~( ~~~a ||| ( ~~~b ||| c))

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_logical_after

theorem PR42691_7_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (BitVec.ofInt 32 (-2147483647) ≤ᵤ x) ||

theorem icmp_eq_zext_eq_one_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (zeroExtend 32 (ofBool (x == 1#32)) == x) = ofBool (x <ᵤ 2#32)

theorem logical_and_bitwise_and_icmps_comm2_proof : logical_and_bitwise_and_icmps_comm2_before ⊑ logical_and_bitwise_and_icmps_comm2_after

theorem icmp_ne_sext_slt_otherwise_nofold_proof : icmp_ne_sext_slt_otherwise_nofold_before ⊑ icmp_ne_sext_slt_otherwise_nofold_after

@[simp]
lemma lift_accepts (M : NFA' n) (f : Fin n → Fin m) :
    (M.lift f).accepts = BitVecs.transport f ⁻¹' M.accepts

theorem bitwise_and_logical_and_masked_icmp_allzeros_thm.extracted_1._3 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  ofBool (x_1 &&& 8#32 == 0#32) = 1#1 →
    ofBool (x_1 &&& 15#32 == 0#32) = 1#1 → x &&& ofBool (x_1 &&& 7#32 == 0#32) = x

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

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

@[simp]
lemma swapLastTwo_same (x : Fin n) : swapLastTwo (n := n) (x.castLE (by omega)) = x.castLE (by omega)

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

theorem e_776 :
    4 * (z |||  ~~~t) + 7 * (z ^^^ t) - 2 *  ~~~(z ||| t) - 11 * (z &&&  ~~~t) - 2 * (z &&& t) = 2 *  ~~~(z ^^^ t) + 7 *  ~~~(z |||  ~~~t)

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

theorem ashr_2_add_zext_basic_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  ¬1#2 ≥ ↑2 → True ∧ (zeroExtend 2 x_1).uaddOverflow (zeroExtend 2 x) = true ∨ 1#2 ≥ ↑2 → False

theorem basic_preserve_nuw_thm (e e_1 : IntW 8) :
  LLVM.xor (add (LLVM.xor e_1 (const? 8 (-1))) e { «nsw» := false, «nuw» := true }) (const? 8 (-1)) ⊑
    sub e_1 e { «nsw» := false, «nuw» := true }

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

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

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

theorem select_icmp_ne_0_and_4096_xor_32_thm.extracted_1._4 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (0#32 != x_1 &&& 4096#32) = 1#1 → ¬7#32 ≥ ↑32 → x ^^^ 32#32 = x_1 >>> 7#32 &&& 32#32 ^^^ x ^^^ 32#32

theorem or_eq_with_diff_one_proof : or_eq_with_diff_one_before ⊑ or_eq_with_diff_one_after

theorem lshrugt_02_03_proof : lshrugt_02_03_before ⊑ lshrugt_02_03_after

theorem ashr_sub_nsw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 17),
  ¬(True ∧ x_1.ssubOverflow x = true ∨ 16#17 ≥ ↑17) →
    (x_1 - x).sshiftRight' 16#17 = signExtend 17 (ofBool (x_1 <ₛ x))

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

theorem test16_thm.extracted_1._1 : ∀ (x : BitVec 84),
  ¬4#84 ≥ ↑84 → ofBool (x.sshiftRight' 4#84 &&& 1#84 != 0#84) = ofBool (x &&& 16#84 != 0#84)

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

theorem positive_sameconst_proof : positive_sameconst_before ⊑ positive_sameconst_after

theorem e_266 :
     - 7 *  ~~~(x ^^^ y) - 7 *  ~~~y - 7 * x + 3 *  ~~~(x &&&  ~~~y) - 3 *  ~~~(x |||  ~~~y) + 14 * (x &&&  ~~~y) + 11 * (x &&& y) =  - 11 *  ~~~(x ||| y)

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

theorem not_mul_of_pow2_proof : not_mul_of_pow2_before ⊑ not_mul_of_pow2_after
</all_available_lemmas>

<local_ctx>
import Batteries.Data.Fin.Basic

import Batteries.Data.Fin.Lemmas

import Blase.SingleWidth.Defs

import Blase.AutoStructs.Constructions

import Blase.AutoStructs.Defs

import Blase.AutoStructs.FiniteStateMachine

import Mathlib.Tactic.Ring

import Mathlib.Data.Nat.Size -- TODO: remove and get rid of shiftLeft_eq_mul_pow use

import Mathlib.Data.BitVec

import Mathlib.Tactic.FinCases

open Fin.NatCast

open Mathlib

structure NFA.correct (M : NFA α σ) (ζ : M.sa) (L : Language α) where
  cond1 : ∀ w, (w ∈ L ↔ ∃ q ∈ M.accept, w ∈ ζ q)
  cond2 : ∀ w q, q ∈ M.eval w ↔ w ∈ ζ q

abbrev BVRel := ∀ ⦃w⦄, BitVec w → BitVec w → Prop

def NFA'.sa2 (M : NFA' 2) := M.σ → BVRel

structure NFA'.correct2 (M : NFA' 2) (ζ : M.sa2) (L : BVRel) where
  cond1 : ∀ (bv1 bv2 : BitVec w), (L bv1 bv2 ↔ ∃ q ∈ M.M.accept, ζ q bv1 bv2)
  cond2 q : q ∈ M.M.start ↔ ζ q .nil .nil
  cond3 q a w (bv1 bv2 : BitVec w) : q ∈ M.M.stepSet { q | ζ q bv1 bv2 } a ↔
              ζ q (BitVec.cons (a.getLsbD 0) bv1) (BitVec.cons (a.getLsbD 1) bv2)

section fsm

variable {arity : Type} [FinEnum arity]

open BitStream in

end fsm

section nfas_relations

inductive NFA.signedCmpState : Type where
| eq | gt | lt | ltfin | gtfin
deriving DecidableEq, Fintype

def NFA.signedCmpStep (q : NFA.signedCmpState) (a : BitVec 2) : List NFA.signedCmpState :=
  match q, a with
  | .eq, 0 => [ .eq ] | .eq, 3 => [.eq] | .eq, 1 => [.gt, .ltfin] | .eq, 2 => [ .lt, .gtfin ]
  | .gt, 0 => [ .gt, .gtfin ] | .gt, 1 => [ .gt, .ltfin ] | .gt, 3 => [ .gt, .gtfin ] | .gt, 2 => [ .lt, .gtfin ]
  | .lt, 0 => [ .lt, .ltfin ] | .lt, 1 => [ .gt, .ltfin ] | .lt, 2 => [ .lt, .gtfin ] | .lt, 3 => [ .lt, .ltfin ]
  | .gtfin, _ => ∅
  | .ltfin, _ => ∅

def NFA.autSignedCmp (cmp: RelationOrdering) : NFA (BitVec 2) signedCmpState where
  step s a := { s' | s' ∈ signedCmpStep s a }
  start := { s | s = signedCmpState.eq }
  accept := { s | s ∈ match cmp with | .lt => [NFA.signedCmpState.ltfin] | .le => [.ltfin, .eq] | .gt => [.gtfin] | .ge => [.gtfin, .eq] }

def NFA'.autSignedCmp (cmp: RelationOrdering) : NFA' 2 :=
  ⟨_, NFA.autSignedCmp cmp⟩

def RelationOrdering.srel (cmp : RelationOrdering) : BVRel :=
  match cmp with
  | .lt => fun _ bv1 bv2 => bv1.slt bv2
  | .le => fun _ bv1 bv2 => bv1.sle bv2
  | .gt => fun _ bv1 bv2 => bv2.slt bv1
  | .ge => fun _ bv1 bv2 => bv2.sle bv1

def NFA'.autSignedCmpSA (q : NFA.signedCmpState) : BVRel :=
  match q with
  | .eq => fun _ bv1 bv2 => bv1 = bv2
  | .lt => fun _ bv1 bv2 => bv1.ult bv2
  | .gt => fun _ bv1 bv2 => bv2.ult bv1
  | .ltfin => fun _ bv1 bv2 => bv1.slt bv2
  | .gtfin => fun _ bv1 bv2 => bv2.slt bv1
</local_ctx>

<target_theorem>
lemma NFA'.autSignedCmp_correct cmp : autSignedCmp cmp |>.correct2 autSignedCmpSA cmp.srel :=
</target_theorem>

