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>
Option in Init.Prelude
Stream' in Mathlib.Data.Stream.Defs
Stream'.const in Mathlib.Data.Stream.Defs
Stream'.head in Mathlib.Data.Stream.Defs
Nat in Init.Prelude
Nat.strongRecOn in Init.WF
Stream'.drop in Mathlib.Data.Stream.Defs
Stream'.get in Mathlib.Data.Stream.Defs
Stream'.tail in Mathlib.Data.Stream.Defs
Stream'.corec in Mathlib.Data.Stream.Defs

syntax "neg" : MLIR.Pretty.uniform_op

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

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

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

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

def Stream (β : Type) := Stream' (Option β)

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

def tail : Stream α → Stream α := Stream'.tail

def corec {α} {β} (s0 : β) (f : β → (Option α × β)) : Stream α :=
  Stream'.corec (f · |>.fst) (f · |>.snd) s0

BitVec.clz in Init.Data.BitVec.Basic

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

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

Lean.MVarId in Lean.Expr

def test_slt_after := [llvm|
{
^0(%arg4 : i32, %arg5 : i16):
  %0 = llvm.sext %arg5 : i16 to i32
  %1 = llvm.icmp "slt" %arg4, %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) -> ()
}
]

def p4 : PeepholeRewrite ExOp [.nat, .nat] .nat:=
  { lhs := r3, rhs := m, correct :=
    by admit /- proof elided -/

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

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

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

structure Term where
  c : Int
  f : Factor
deriving Repr

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

def initialGeneralizerState (startTime timeout widthId targetWidth: Nat) (parsedLogicalExpr : ParsedBVLogicalExpr)
            : BVGeneralizerState := { startTime := startTime
                                    , widthId := widthId
                                    , timeout := timeout
                                    , processingWidth           := targetWidth
                                    , targetWidth               := targetWidth
                                    , parsedLogicalExpr       := parsedLogicalExpr
                                    , needsPreconditionsExprs   := []
                                    , visitedSubstitutions      := Std.HashSet.emptyWithCapacity
                                    }

def State.consOldExpr2Cache [DecidableEq d.Ty] [DecidableEq d.Op]
    {Γ : Ctxt d.Ty} {α}
    {lets : Lets d Γstart .pure Γ}
    (s : State d lets) (enew : Expr d Γ .pure α) (eold : Expr d Γ .pure α) (henew :
        ∀ (V : Γstart.Valuation), enew.denote (lets.denote V) = eold.denote (lets.denote V))
    (vold : HVector Γ.Var α)
    (hv : ∀ (V : Γstart.Valuation), eold.denoteOp (lets.denote V) =
      vold.map (lets.denote V)) :
    State d (Lets.var lets enew) where
  var2var := fun v => by admit /- proof elided -/
    | .none => .none
    | .some ⟨e', he'⟩ => .some ⟨e'.map fun _ v => v.appendInr, by admit /- proof elided -/
      ⟩

def llvm_const_lower_riscv_li_2 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_2, rhs:= liRiscv_2,
   correct := by admit /- proof elided -/

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

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

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

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

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

def select1_before := [llvm|
{
^0(%arg13 : i1, %arg14 : i32, %arg15 : i32, %arg16 : i32):
  %0 = llvm.trunc %arg14 : i32 to i8
  %1 = llvm.trunc %arg15 : i32 to i8
  %2 = llvm.trunc %arg16 : i32 to i8
  %3 = llvm.add %0, %1 : i8
  %4 = "llvm.select"(%arg13, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %5 = llvm.zext %4 : i8 to i32
  "llvm.return"(%5) : (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 test6a_after := [llvm|
{
^0(%arg47 : i55):
  %0 = llvm.mlir.constant(6 : i55) : i55
  %1 = llvm.mul %arg47, %0 : i55
  "llvm.return"(%1) : (i55) -> ()
}
]

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 xor_ashr_not_fail_invalid_xor_constant_before := [llvm|
{
^0(%arg15 : i8, %arg16 : i8, %arg17 : i8):
  %0 = llvm.mlir.constant(-2 : i8) : i8
  %1 = llvm.ashr %arg15, %arg17 : i8
  %2 = llvm.ashr %arg16, %arg17 : i8
  %3 = llvm.xor %2, %0 : i8
  %4 = llvm.xor %1, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

def test9_before := [llvm|
{
^0(%arg111 : i32, %arg112 : i32):
  %0 = llvm.and %arg111, %arg112 : i32
  %1 = llvm.xor %arg111, %arg112 : i32
  %2 = llvm.xor %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

private def tensor1dTest : MLIRTy := [mlir_type| tensor1d]

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

protected instance Com.decidableEq [DecidableEq d.Op] [DecidableEq d.Ty]
    {Γ : Ctxt d.Ty} {eff : EffectKind} {tys : List d.Ty} : DecidableEq (Com d Γ eff tys)
  | .rets v₁, .rets v₂ => decidable_of_iff (v₁ = v₂) (by admit /- proof elided -/
  )
  | .var (ty := ty₁) e₁ body₁, .var (ty := ty₂) e₂ body₂ =>
    if hα : ty₁ = ty₂
    then by
      subst hα
      letI := Expr.decidableEq e₁ e₂
      letI := Com.decidableEq body₁ body₂
      exact decidable_of_iff (e₁ = e₂ ∧ body₁ = body₂) (by admit /- proof elided -/
      )
    else isFalse (by admit /- proof elided -/
    )
  | .rets _, .var _ _ => isFalse (fun h => Com.noConfusion h)
  | .var _ _, .rets _ => isFalse (fun h => Com.noConfusion h)

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

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

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

@[simp_llvm]
def udiv? {w : Nat} (x y : BitVec w) : IntW w :=
  if y = 0 then
    .poison
  else
    .value <| x / y

def lshr_lshr_after := [llvm|
{
^0(%arg47 : i232):
  %0 = llvm.mlir.constant(0 : i232) : i232
  "llvm.return"(%0) : (i232) -> ()
}
]

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

def parseArgs (Γ : Ctxt d.Ty) : ReaderM d (ParsedArgs Γ) :=
  ParsedArgs.ofList <$> op.args.mapM (TypedSSAVal.mkVal Γ)

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_cond : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 1)] where
  lhs := [LV| {
    ^entry (%c: i1, %t: i64):
      %0 = llvm.sext %c: i1 to i64
      %1 = llvm.select %c, %t, %0 : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%c: i1, %t: i64):
      %0 = llvm.sext %c: i1 to i64
      %1 = llvm.freeze %t : i64
      %2 = llvm.and %0, %1 : i64
      llvm.return %2 : i64
  }]

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

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

BitVec.toNat in Init.Prelude

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

def factorize5_before := [llvm|
{
^0(%arg1 : i32, %arg2 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mul %arg2, %0 : i32
  %2 = llvm.mul %1, %arg1 : i32
  %3 = llvm.mul %arg1, %arg2 : i32
  %4 = llvm.sub %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def positive_sameconst_shlnuw_ashrexact_after := [llvm|
{
^0(%arg31 : i8):
  "llvm.return"(%arg31) : (i8) -> ()
}
]

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

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

abbrev worklist.St.sim {st : worklist.St A S} (T : Set (S × A × S)) :=
  st.m.Simul (nfa inits final f) st.rel st.D T

def test11f_before := [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, %0 : i32
  %4 = llvm.xor %1, %3 : i32
  %5 = llvm.and %4, %2 : 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 test4_before := [llvm|
{
^0(%arg0 : i9, %arg1 : i9):
  %0 = llvm.zext %arg0 : i9 to i64
  %1 = llvm.zext %arg1 : i9 to i64
  %2 = llvm.add %0, %1 : i64
  %3 = llvm.trunc %2 : i64 to i9
  "llvm.return"(%3) : (i9) -> ()
}
]

def test7_after := [llvm|
{
^0(%arg7 : i47):
  %0 = llvm.mlir.constant(39 : i47) : i47
  %1 = llvm.lshr %arg7, %0 : i47
  "llvm.return"(%1) : (i47) -> ()
}
]

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

def udiv_exact_ne_30_no_of_before := [llvm|
{
^0(%arg0 : i8, %arg1 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(30 : i8) : i8
  %2 = llvm.and %arg1, %0 : i8
  %3 = llvm.udiv exact %arg0, %2 : i8
  %4 = llvm.icmp "ne" %3, %1 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

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

def mul_select_zext_before := [llvm|
{
^0(%arg18 : i1, %arg19 : i64):
  %0 = llvm.mlir.constant(1) : i64
  %1 = "llvm.select"(%arg18, %arg19, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  %2 = llvm.zext %arg18 : i1 to i64
  %3 = llvm.mul %1, %2 : i64
  "llvm.return"(%3) : (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_mul : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (0) : i64
      %0 = llvm.mul %x, %c: i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (0) : i64
      llvm.return %c : i64
  }]

def Region.WellTyped : UnTyped.Region Op VarName → RegionType Ty → Prop
  | ⟨entry, _⟩ => BasicBlock.WellTyped entry

instance : Lean.ToExpr RegIndex := inherit

List.reverse in Init.Data.List.Basic

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

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

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

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

def 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_trunc :=
  [llvm()|{
  ^bb0(%arg0: i64):
    %0 = llvm.trunc %arg0 : i64 to i32
    %1 = llvm.zext %0 : i32 to i64
    llvm.return %1 : i64
  }]

def not_shl_before := [llvm|
{
^0(%arg86 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(-128 : i8) : i8
  %2 = llvm.shl %arg86, %0 : i8
  %3 = llvm.xor %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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_before := [llvm|
{
^0(%arg90 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(3 : i32) : i32
  %2 = llvm.mlir.constant(48 : i32) : i32
  %3 = llvm.mlir.constant(16 : i32) : i32
  %4 = llvm.mlir.constant(0 : i32) : i32
  %5 = llvm.mlir.constant(1 : i32) : i32
  %6 = llvm.and %arg90, %0 : i32
  %7 = llvm.icmp "ne" %6, %1 : i32
  %8 = llvm.and %arg90, %2 : i32
  %9 = llvm.icmp "ne" %8, %3 : i32
  %10 = llvm.or %7, %9 : i1
  %11 = "llvm.select"(%10, %4, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%11) : (i32) -> ()
}
]

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

def BitVecs0 : Set (BitVecs n) :=
  {⟨0, List.Vector.replicate n (BitVec.zero 0)⟩}

structure DeleteRange (Γ : Ctxt Ty) where
   
  start : Fin (Γ.length + 1)
   
  num : Fin (Γ.length + 1 - start.val)

def lshr_shl_demand3_after := [llvm|
{
^0(%arg7 : i8):
  %0 = llvm.mlir.constant(28 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.lshr %0, %arg7 : i8
  %3 = llvm.shl %2, %1 overflow<nuw> : i8
  %4 = llvm.or disjoint %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def bools_logical_commute3_and2_after := [llvm|
{
^0(%arg69 : i1, %arg70 : i1, %arg71 : i1):
  %0 = "llvm.select"(%arg71, %arg70, %arg69) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def test21_before := [llvm|
{
^0(%arg10 : i12):
  %0 = llvm.mlir.constant(6 : i12) : i12
  %1 = llvm.mlir.constant(-128 : i12) : i12
  %2 = llvm.shl %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_shl_constants_div_after := [llvm|
{
^0(%arg27 : i32, %arg28 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.add %arg28, %0 : i32
  %2 = llvm.lshr %arg27, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

def icmp_slt_sext_ne_allones_nofold_after := [llvm|
{
^0(%arg3 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.icmp "ne" %arg3, %0 : i32
  %2 = llvm.sext %1 : i1 to i32
  %3 = llvm.icmp "sgt" %arg3, %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_eq_X_is_constant2_before := [llvm|
{
^0(%arg8 : i32):
  %0 = llvm.mlir.constant(268435456 : i32) : i32
  %1 = llvm.mlir.constant(-8 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.lshr %0, %arg8 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.icmp "eq" %4, %2 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

def icmp_slt_0_and_icmp_sge_neg1_i64_fail_before := [llvm|
{
^0(%arg59 : i64):
  %0 = llvm.mlir.constant(-1) : i64
  %1 = llvm.mlir.constant(62) : i64
  %2 = llvm.icmp "sge" %arg59, %0 : i64
  %3 = llvm.zext %2 : i1 to i64
  %4 = llvm.lshr %arg59, %1 : i64
  %5 = llvm.and %4, %3 : i64
  "llvm.return"(%5) : (i64) -> ()
}
]

def neg (x : BitStream) : BitStream :=
  fun n => (negAux x n).1

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 allSignBits_after := [llvm|
{
^0(%arg13 : i32, %arg14 : i32, %arg15 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "slt" %arg13, %0 : i32
  %2 = "llvm.select"(%1, %arg14, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %3 = llvm.icmp "slt" %arg13, %0 : i32
  %4 = "llvm.select"(%3, %0, %arg15) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %5 = llvm.or %2, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def slt_zero_sgt_minus1_before := [llvm|
{
^0(%arg22 : i4, %arg23 : i4):
  %0 = llvm.mlir.constant(0 : i4) : i4
  %1 = llvm.mlir.constant(-1 : i4) : i4
  %2 = llvm.icmp "slt" %arg22, %0 : i4
  %3 = llvm.icmp "sgt" %arg23, %1 : i4
  %4 = llvm.xor %2, %3 : i1
  "llvm.return"(%4) : (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 original_sdiv_srem := [LV| {
  ^entry (%a: i64, %b: i64):
    %0= llvm.sdiv exact %a, %b : i64
    %1 = llvm.srem %a, %b : i64
    llvm.return %1 : i64
  }]

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

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

instance: HRefinement (Expr d Γ eff₁ t) (Expr d Γ eff₂ t) where
  IsRefinedBy e₁ e₂ :=
    ∀ V, e₁.denote V ⊑ e₂.denote V

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

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

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

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_eq_sext_ne_allones_before := [llvm|
{
^0(%arg18 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.icmp "ne" %arg18, %0 : i32
  %2 = llvm.sext %1 : i1 to i32
  %3 = llvm.icmp "eq" %2, %arg18 : 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 test10_after := [llvm|
{
^0(%arg90 : i8):
  %0 = llvm.mlir.constant(0 : i32) : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

def shl1_trunc_eq0_before := [llvm|
{
^0(%arg28 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i16) : i16
  %2 = llvm.shl %0, %arg28 : i32
  %3 = llvm.trunc %2 : i32 to i16
  %4 = llvm.icmp "eq" %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_0111_before := [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.xor %3, %2 : i32
  %6 = llvm.xor %1, %5 : i32
  %7 = llvm.or %4, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

def modulo32_before := [llvm|
{
^0(%arg2 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.srem %arg2, %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 sgt_smax1_before := [llvm|
{
^0(%arg39 : i32, %arg40 : i32):
  %0 = llvm.icmp "sgt" %arg39, %arg40 : i32
  %1 = "llvm.select"(%0, %arg39, %arg40) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %2 = llvm.icmp "sgt" %1, %arg39 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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 udiv {w : Nat} (x y : IntW w) (flag : ExactFlag := {exact := false}) : IntW w := do
  let x' ← x
  let y' ← y
  if flag.exact ∧ x'.umod y' ≠ 0 then
    .poison
  else
    udiv? x' y'

structure Item where
 name : String
 tac : Syntax

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

def canonicalize_icmp_ult_neg2 : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant -2 : i64
      %1 = llvm.icmp.ult %c, %x : i64
      llvm.return %1 : i1
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant -2 : i64
      %1 = llvm.icmp.ugt %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_samevar_shlnuwnsw_ashrexact_before := [llvm|
{
^0(%arg27 : i8, %arg28 : i8):
  %0 = llvm.ashr exact %arg27, %arg28 : i8
  %1 = llvm.shl %0, %arg28 overflow<nsw,nuw> : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

@[simp_sllvm]
def srem (x y : LLVM.IntW w) : EffectM (LLVM.IntW w) := do
  if y.canBe 0#w then
    throwUB
  else
    pure <| LLVM.srem x y

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

def PackedFloat.ofBV (bv : BitVec (1 + e + M)) : PackedFloat e M where
  sign := bv[e + M]
  ex := bv.extractLsb' M e
  sig := bv.extractLsb' 0 M

@[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 t10_c1_c2_before := [llvm|
{
^0(%arg11 : i8, %arg12 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(24 : i8) : i8
  %2 = llvm.sub %arg11, %0 : i8
  %3 = llvm.sub %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def lshr_2_add_zext_basic_before := [llvm|
{
^0(%arg37 : i1, %arg38 : i1):
  %0 = llvm.mlir.constant(1 : i2) : i2
  %1 = llvm.zext %arg37 : i1 to i2
  %2 = llvm.zext %arg38 : i1 to i2
  %3 = llvm.add %1, %2 : i2
  %4 = llvm.lshr %3, %0 : i2
  "llvm.return"(%4) : (i2) -> ()
}
]

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

def 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_ashr_slt_noexact_before := [llvm|
{
^0(%arg3 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(5 : i8) : i8
  %2 = llvm.ashr %arg3, %0 : i8
  %3 = llvm.icmp "slt" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def ne_10_after := [llvm|
{
^0(%arg78 : i32, %arg79 : i32):
  %0 = llvm.trunc %arg78 : i32 to i16
  %1 = llvm.trunc %arg79 : i32 to i16
  %2 = llvm.icmp "ne" %0, %1 : i16
  "llvm.return"(%2) : (i1) -> ()
}
]

Lean.instantiateMVars in Lean.MetavarContext

def t20_after := [llvm|
{
^0(%arg145 : i8, %arg146 : i16):
  %0 = llvm.mlir.constant(42 : i16) : i16
  %1 = llvm.shl %0, %arg146 : i16
  %2 = llvm.trunc %1 : i16 to i8
  %3 = llvm.add %arg145, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

@[simp_denote]
def add_llvm_nsw_nuw_flags_8 := [LV| {
   ^entry (%lhs: i8, %rhs: i8):
    %1 = llvm.add %lhs, %rhs overflow<nsw,nuw> : i8
    llvm.return %1 : i8
  }]

def scalar_i8_shl_and_negC_eq_after := [llvm|
{
^0(%arg35 : i8, %arg36 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.shl %arg35, %arg36 : i8
  %2 = llvm.icmp "ult" %1, %0 : i8
  "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 icmp_shl_ne_2_before := [llvm|
{
^0(%arg4 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.sdiv %0, %arg4 : i8
  %3 = llvm.shl %2, %1 : i8
  %4 = llvm.icmp "ne" %2, %3 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

def trunc_shl_shl_infloop_before := [llvm|
{
^0(%arg20 : i64):
  %0 = llvm.mlir.constant(1) : i64
  %1 = llvm.mlir.constant(2) : i64
  %2 = llvm.shl %arg20, %0 : i64
  %3 = llvm.shl %2, %1 : i64
  %4 = llvm.trunc %3 : i64 to i32
  "llvm.return"(%4) : (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 negative2_logical_after := [llvm|
{
^0(%arg14 : i32, %arg15 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.icmp "slt" %arg14, %arg15 : i32
  %2 = llvm.icmp "sgt" %arg14, %0 : i32
  %3 = llvm.and %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

def test_after := [llvm|
{
^0(%arg0 : i16, %arg1 : i16):
  %0 = llvm.sext %arg0 : i16 to i32
  %1 = llvm.sext %arg1 : i16 to i32
  %2 = llvm.add %0, %1 overflow<nsw> : i32
  %3 = llvm.sext %2 : i32 to i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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_before := [llvm|
{
^0(%arg132 : i64):
  %0 = llvm.mlir.constant(-32574 : i16) : i16
  %1 = llvm.mlir.constant(-25350 : i16) : i16
  %2 = llvm.trunc %arg132 : i64 to i16
  %3 = llvm.or %2, %0 : i16
  %4 = llvm.and %3, %1 : i16
  %5 = llvm.zext %4 : i16 to i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

def xor_with_or_disjoint_ba_before := [llvm|
{
^0(%arg24 : i32, %arg25 : i32):
  %0 = llvm.or disjoint %arg25, %arg24 : i32
  %1 = llvm.xor %arg25, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def test_nuw_nsw_and_unsigned_pred_before := [llvm|
{
^0(%arg55 : i64):
  %0 = llvm.mlir.constant(10) : i64
  %1 = llvm.mlir.constant(3) : i64
  %2 = llvm.sub %0, %arg55 overflow<nsw,nuw> : i64
  %3 = llvm.icmp "ule" %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 udiv (op1 : GenBVExpr w) (op2 : GenBVExpr w) : GenBVExpr w :=
  GenBVExpr.bin op1 BVBinOp.udiv op2

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

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

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

def liRiscv_18 := [LV| {
  ^entry ():
    %0 = "li"() {imm = -18 : !i64} : (!i64) -> (!i64)
    %1 = "builtin.unrealized_conversion_cast"(%0) : (!i64) -> (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 ule_umax4_after := [llvm|
{
^0(%arg46 : i32, %arg47 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg46, %0 : i32
  %2 = llvm.icmp "ule" %arg47, %1 : i32
  "llvm.return"(%2) : (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) -> ()
}
]

def scf.for.loop (f : Nat → β → β) (n n_minus_i: Nat) (acc: β) : β :=
  let i := n - n_minus_i
  match n_minus_i with
    | 0 => acc
    | n_minus_i' + 1 =>
      scf.for.loop f n n_minus_i' (f i acc)

instance : Repr (Lets d Γ eff t) where
  reprPrec lets prec := lets.repr prec

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

def toAIG {α : Type}
    [DecidableEq α] [Fintype α] [Hashable α]
    (c : Circuit α) : { entry : Entrypoint α // ∀ (env : α → Bool), AIG.denote env entry = c.eval env } :=
  let aig : AIG α := AIG.empty
  let val := c.toAIGAux aig
  let aig := val.out
  let ref := val.ref
  let outVal := ⟨aig, ref⟩
  ⟨outVal, by admit /- proof elided -/
  ⟩

def sext_shl_trunc_same_size_after := [llvm|
{
^0(%arg13 : i16, %arg14 : i32):
  %0 = llvm.zext %arg13 : i16 to i32
  %1 = llvm.shl %0, %arg14 : i32
  %2 = llvm.trunc %1 : i32 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

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 const (w : Nat) (val : ℤ) : LLVM.Op        := MOp.const (.concrete w) val

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

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

def trunc_ashr_trunc_outofrange_after := [llvm|
{
^0(%arg2 : i64):
  %0 = llvm.mlir.constant(25 : i32) : i32
  %1 = llvm.trunc %arg2 : i64 to i32
  %2 = llvm.ashr %1, %0 : i32
  %3 = llvm.trunc %2 overflow<nsw> : i32 to i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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_before := [llvm|
{
^0(%arg58 : i32):
  %0 = llvm.mlir.constant(512 : i32) : i32
  %1 = llvm.mlir.constant(128 : i32) : i32
  %2 = llvm.mlir.constant(256 : i32) : i32
  %3 = llvm.icmp "ult" %arg58, %0 : i32
  %4 = llvm.add %arg58, %1 : i32
  %5 = llvm.icmp "ult" %4, %2 : i32
  %6 = llvm.and %3, %5 : i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def main4_logical_before := [llvm|
{
^0(%arg133 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(48 : i32) : i32
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.mlir.constant(0 : i32) : i32
  %4 = llvm.mlir.constant(1 : i32) : i32
  %5 = llvm.and %arg133, %0 : i32
  %6 = llvm.icmp "eq" %5, %0 : i32
  %7 = llvm.and %arg133, %1 : i32
  %8 = llvm.icmp "eq" %7, %1 : i32
  %9 = "llvm.select"(%6, %8, %2) <{"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 ashrslt_02_15_exact_after := [llvm|
{
^0(%arg22 : i4):
  %0 = llvm.mlir.constant(-4 : i4) : i4
  %1 = llvm.icmp "slt" %arg22, %0 : i4
  "llvm.return"(%1) : (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 llvm_const_lower_riscv_li_36 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_36, rhs:= liRiscv_36,
   correct := by admit /- proof elided -/

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

List.Perm in Init.Data.List.Basic

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

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

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

def t0_before := [llvm|
{
^0(%arg206 : i8):
  %0 = llvm.mlir.constant(-42 : i8) : i8
  %1 = llvm.sub %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 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 llvm_const_lower_riscv_li25 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM25, rhs:= liRiscv25,
   correct := by admit /- proof elided -/

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

def rewrite_patterns : List (Σ Γ, Σ ty, PeepholeRewrite DCPlus Γ ty) :=[
  mkRewrite rewrite_a_T,
  mkRewrite rewrite_a_F,
  mkRewrite rewrite_c_A,
  mkRewrite rewrite_c_B,
  mkRewrite rewrite_h_A,
  mkRewrite rewrite_h_B,
  mkRewrite rewrite_g,
  mkRewrite rewrite_e,
]

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 pack2 {r} {Γ : Ctxt _} (a : Γ.Var (.variadicvaluetokenstream r)) : Expr (DC) Γ .pure (.valuestream2 r) :=
  Expr.mk
    (op := .pack2 r)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .cons a  <| .nil)
    (regArgs := .nil)

def ne_irregular_bit_widths_before := [llvm|
{
^0(%arg62 : i31, %arg63 : i31):
  %0 = llvm.mlir.constant(7 : i31) : i31
  %1 = llvm.mlir.constant(13 : i31) : i31
  %2 = llvm.lshr %arg62, %0 : i31
  %3 = llvm.trunc %2 : i31 to i6
  %4 = llvm.lshr %arg62, %1 : i31
  %5 = llvm.trunc %4 : i31 to i5
  %6 = llvm.lshr %arg63, %0 : i31
  %7 = llvm.trunc %6 : i31 to i6
  %8 = llvm.lshr %arg63, %1 : i31
  %9 = llvm.trunc %8 : i31 to i5
  %10 = llvm.icmp "ne" %3, %7 : i6
  %11 = llvm.icmp "ne" %5, %9 : i5
  %12 = llvm.or %11, %10 : i1
  "llvm.return"(%12) : (i1) -> ()
}
]

Lean.initSearchPath in Lean.Util.Path

def or_xor_xor_normal_binops_after := [llvm|
{
^0(%arg8 : i32, %arg9 : i32, %arg10 : i32):
  %0 = llvm.xor %arg9, %arg8 : i32
  "llvm.return"(%0) : (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 nonexact_lshr_ne_exactdiv_after := [llvm|
{
^0(%arg149 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.icmp "ne" %arg149, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

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

def 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_wrong7_before := [llvm|
{
^0(%arg3 : i8):
  %0 = llvm.mlir.constant(-2147483647 : i32) : i32
  %1 = llvm.mlir.constant(128 : i32) : i32
  %2 = llvm.sext %arg3 : i8 to i32
  %3 = llvm.and %2, %0 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def t5_c2_after := [llvm|
{
^0(%arg21 : i8, %arg22 : i8):
  %0 = llvm.mlir.constant(-42 : i8) : i8
  %1 = llvm.sub %arg21, %arg22 : i8
  %2 = llvm.add %1, %0 : i8
  "llvm.return"(%2) : (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_after := [llvm|
{
^0(%arg20 : i32):
  %0 = llvm.mlir.constant(32896 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.mlir.constant(2 : i32) : i32
  %4 = llvm.and %arg20, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = "llvm.select"(%5, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

def XorAndAnd : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64, %y: i64, %z: i64):
      %0 = llvm.and %x, %z : i64
      %1 = llvm.and %y, %z : i64
      %2 = llvm.xor %0, %1 : i64
      llvm.return %2 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64, %y: i64, %z: i64):
      %0 = llvm.xor %x, %y : i64
      %1 = llvm.and %0, %z : i64
      llvm.return %1 : i64
  }]

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

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

def select_riscv_select_llvm_32 : LLVMPeepholeRewriteRefine 32
  [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 1)] where
  lhs := select_llvm_32
  rhs := select_riscv_32

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

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

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

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

def n0_before := [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 : i8
  %3 = llvm.xor %2, %1 : i8
  %4 = llvm.icmp "uge" %3, %arg9 : 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) -> ()
}
]

private def staticDimList1 : List Nat := [static_dim_list| 1 × 2]

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

def orn_and_cmp_2_partial_logical_before := [llvm|
{
^0(%arg6 : i16, %arg7 : i16, %arg8 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.icmp "sge" %arg6, %arg7 : i16
  %2 = llvm.icmp "slt" %arg6, %arg7 : i16
  %3 = llvm.and %1, %arg8 : i1
  %4 = "llvm.select"(%3, %0, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

def test15_after := [llvm|
{
^0(%arg172 : i32, %arg173 : i32):
  %0 = llvm.xor %arg172, %arg173 : i32
  "llvm.return"(%0) : (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 select_icmp_and_2147483648_eq_0_xor_2147483648_after := [llvm|
{
^0(%arg169 : i32):
  %0 = llvm.mlir.constant(-2147483648 : i32) : i32
  %1 = llvm.or %arg169, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

Lean.findSysroot in Lean.Util.Path

DFA in Mathlib.Computability.DFA

def one_inst_concrete_macro_proof :
    one_inst_concrete_macro ⊑ one_inst_concrete_macro :=

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_commute5_after := [llvm|
{
^0(%arg92 : i8, %arg93 : i8, %arg94 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.and %arg93, %arg92 : i8
  %2 = llvm.xor %1, %0 : i8
  %3 = llvm.or %arg94, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

def ashr_ule_exact_before := [llvm|
{
^0(%arg168 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(10 : i8) : i8
  %2 = llvm.ashr exact %arg168, %0 : i8
  %3 = llvm.icmp "ule" %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) -> ()
}
]

def ori_i64_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := ori_llvm_i64
  rhs := ori_riscv_i64

def canonicalize_icmp_sgt_0 : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant 0 : i64
      %1 = llvm.icmp.sgt %c, %x : i64
      llvm.return %1 : i1
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant 0 : i64
      %1 = llvm.icmp.slt %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_with_uniform_bad_mask_logical_after := [llvm|
{
^0(%arg12 : i32):
  %0 = llvm.mlir.constant(-16777152 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(128 : i32) : i32
  %3 = llvm.mlir.constant(256 : i32) : i32
  %4 = llvm.and %arg12, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.add %arg12, %2 : i32
  %7 = llvm.icmp "ult" %6, %3 : i32
  %8 = llvm.and %5, %7 : i1
  "llvm.return"(%8) : (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_before := [llvm|
{
^0(%arg9 : i32):
  %0 = llvm.mlir.constant(1073741823 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(2 : i32) : i32
  %3 = llvm.and %arg9, %0 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  %5 = llvm.shl %arg9, %2 : i32
  %6 = "llvm.select"(%4, %5, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%6) : (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_after := [llvm|
{
^0(%arg235 : i8, %arg236 : i32):
  %0 = llvm.trunc %arg236 : i32 to i8
  %1 = llvm.add %arg235, %0 : i8
  %2 = llvm.zext %1 : i8 to i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def t0_before := [llvm|
{
^0(%arg32 : i8, %arg33 : i1):
  %0 = llvm.sext %arg33 : i1 to i8
  %1 = llvm.add %0, %arg32 : i8
  %2 = llvm.xor %1, %0 : i8
  "llvm.return"(%2) : (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 n3_constmask_samemask_after := [llvm|
{
^0(%arg0 : i32, %arg1 : i32):
  %0 = llvm.mlir.constant(65280 : i32) : i32
  %1 = llvm.or %arg0, %arg1 : i32
  %2 = llvm.and %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

def test2_before := [llvm|
{
^0(%arg0 : i23, %arg1 : i23, %arg2 : i23):
  %0 = llvm.and %arg1, %arg0 : i23
  %1 = llvm.or %arg1, %arg0 : i23
  %2 = llvm.xor %0, %1 : i23
  "llvm.return"(%2) : (i23) -> ()
}
]

def n1_after := [llvm|
{
^0(%arg2 : i8, %arg3 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.shl %0, %arg3 overflow<nuw> : i8
  %3 = llvm.and %arg2, %2 : i8
  %4 = llvm.icmp "eq" %3, %1 : i8
  "llvm.return"(%4) : (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 negative4_before := [llvm|
{
^0(%arg6 : i32, %arg7 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg7, %0 : i32
  %3 = llvm.icmp "ne" %arg6, %2 : i32
  %4 = llvm.icmp "sge" %arg6, %1 : i32
  %5 = llvm.and %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 urem_c_i32_before := [llvm|
{
^0(%arg5 : i8):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.zext %arg5 : i8 to i32
  %2 = llvm.urem %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

def and_zext_eq_odd_commuted_after := [llvm|
{
^0(%arg30 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.icmp "eq" %arg30, %0 : i32
  %2 = llvm.zext %1 : i1 to i32
  "llvm.return"(%2) : (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) : Bool :=
  match c with
    | .eq => (x == y)
    | .ne => (x != y)
    | .sgt => (x >ₛ y)
    | .sge => (x ≥ₛ y)
    | .slt => (x <ₛ y)
    | .sle => (x ≤ₛ y)
    | .ugt => (x >ᵤ y)
    | .uge => (x ≥ᵤ y)
    | .ult => (x <ᵤ y)
    | .ule => (x ≤ᵤ y)

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

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

def EnvFin.getLsb {w : Nat} (env : EnvFin (w + 1) n) : EnvFin 1 n := fun n => BitVec.ofBool <| (env n)[0]

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

def add {w : Nat} (x y : IntW w) (flags : NoWrapFlags := {nsw := false , nuw := false}) : IntW w := do
  let x' ← x
  let y' ← y
  if flags.nsw ∧ BitVec.saddOverflow x' y' then
    .poison
  else if flags.nuw ∧ BitVec.uaddOverflow x' y' then
    .poison
  else
    add? 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_i8_shl_ult_const_2_before := [llvm|
{
^0(%arg18 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.mlir.constant(64 : i8) : i8
  %2 = llvm.shl %arg18, %0 : i8
  %3 = llvm.icmp "ult" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def sdiv_exact_eq_9_no_of_after := [llvm|
{
^0(%arg8 : i8, %arg9 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(9 : i8) : i8
  %2 = llvm.and %arg9, %0 : i8
  %3 = llvm.mul %2, %1 overflow<nsw,nuw> : i8
  %4 = llvm.icmp "eq" %3, %arg8 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

def main4e_like_after := [llvm|
{
^0(%arg128 : i32, %arg129 : i32, %arg130 : i32):
  %0 = llvm.or %arg129, %arg130 : i32
  %1 = llvm.and %arg128, %0 : i32
  %2 = llvm.icmp "ne" %1, %0 : i32
  %3 = llvm.zext %2 : i1 to i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def lshrult_03_12_before := [llvm|
{
^0(%arg323 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(-4 : i4) : i4
  %2 = llvm.lshr %arg323, %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_ne_and_pow2_shl_pow2_before := [llvm|
{
^0(%arg63 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.shl %0, %arg63 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.icmp "ne" %4, %2 : i32
  %6 = llvm.zext %5 : i1 to i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

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

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

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

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

def test59_before := [llvm|
{
^0(%arg122 : i8, %arg123 : i8):
  %0 = llvm.mlir.constant(4 : i32) : i32
  %1 = llvm.mlir.constant(48 : i32) : i32
  %2 = llvm.zext %arg122 : i8 to i32
  %3 = llvm.shl %2, %0 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.zext %arg123 : i8 to i32
  %6 = llvm.lshr %5, %0 : i32
  %7 = llvm.or %6, %4 : i32
  %8 = llvm.zext %7 : i32 to i64
  "llvm.return"(%8) : (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_13_exact_after := [llvm|
{
^0(%arg208 : i4):
  %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 not_mul_of_pow2_after := [llvm|
{
^0(%arg77 : i32, %arg78 : i8):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.mlir.constant(1530 : i32) : i32
  %2 = llvm.and %arg77, %0 : i32
  %3 = llvm.zext %arg78 : i8 to i32
  %4 = llvm.mul %2, %3 overflow<nsw,nuw> : i32
  %5 = llvm.icmp "ugt" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

def TermBinop.termGadget (t : TermBinop) : CNFA 3 :=
  match t with
  | .and => FSM.ofTerm (.and (.var 0) (.var 1)) |> CNFA.ofFSM
  | .or => FSM.ofTerm (.or (.var 0) (.var 1)) |> CNFA.ofFSM
  | .xor => FSM.ofTerm (.xor (.var 0) (.var 1)) |> CNFA.ofFSM
  | .add => FSM.ofTerm (.add (.var 0) (.var 1)) |> CNFA.ofFSM
  | .sub => FSM.ofTerm (.sub (.var 0) (.var 1)) |> CNFA.ofFSM

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

structure GlobalState where
  alloc : AllocState
  mem : MemoryState

def visitSUB_Neg1X : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (-1) : i64
      %0 = llvm.sub %c, %x : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (-1) : i64
      %0 = llvm.xor %x, %c : i64
      llvm.return %0 : 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 mkConstBin (atp : Name) : Expr :=
  mkApp (mkConst ``Predicate.binary) (mkConst atp)

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

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

def shl_xor_xor_bad_mask_distribute_before := [llvm|
{
^0(%arg98 : i8, %arg99 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(-68 : i8) : i8
  %2 = llvm.shl %arg98, %0 : i8
  %3 = llvm.shl %arg99, %0 : i8
  %4 = llvm.xor %3, %1 : i8
  %5 = llvm.xor %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 shl (w : Nat) (flags: NoWrapFlags := {}) : LLVM.Op := MOp.shl (.concrete w) flags

instance : MLIR.AST.TransformReturn LLVMPlusRiscV 0 where
  mkReturn := mkReturn

@[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 tryFactorization_add_mul_nuw_after := [llvm|
{
^0(%arg13 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.shl %arg13, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

inductive ExTy
  | nat
  | bool
  deriving DecidableEq, Repr

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

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

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

def positive_with_aggressive_icmp_after := [llvm|
{
^0(%arg56 : i32):
  %0 = llvm.mlir.constant(128 : i32) : i32
  %1 = llvm.icmp "ult" %arg56, %0 : i32
  "llvm.return"(%1) : (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)

instance : MLIR.AST.TransformExpr (FHE q n) 0 where
  mkExpr := mkExpr

def masked_icmps_mask_notallzeros_bmask_mixed_swapped_7b_after := [llvm|
{
^0(%arg32 : i32):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (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_before := [llvm|
{
^0(%arg25 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.shl %0, %arg25 : i32
  %3 = llvm.add %2, %1 overflow<nsw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

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

def parseAndGeneralize
  [H : HydrableParseAndGeneralize parsedExpr genPred genExpr]
  (cfg : MedusaSynthGeneralizeConfig)
  (hExpr : Expr) (context: GeneralizeContext): TermElabM MessageData := do
    let targetWidth := 8
    let timeoutMs := 300000

    match_expr hExpr with
    | Eq w lhsExpr rhsExpr =>

          let some width ← H.getWidth w  | throwError m! "Could not determine the rewrite width from {w}"
          let startTime ← Core.liftIOCore IO.monoMsNow

          \n Input expression: {hExpr} has generalization: {pretty}"
                          | GeneralizeContext.Tactic _name =>
                            match cfg.output with
                            | .thmStmt =>
                              let name := Name.mkSimple "foo"
                              pure m! "{H.prettifyAsTheorem name res allVariables widthVals}"
                            | .sexpr =>
                              throwError (H.prettifyAsSexpr res allVariables) widthVals|> format
            | none => throwError m! "Could not generalize {bvLogicalExpr}"
    | _ => throwError m!"The top level constructor is not an equality predicate in {hExpr}"

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 test12_before := [llvm|
{
^0(%arg61 : i32, %arg62 : i32):
  %0 = llvm.mlir.constant(31 : i128) : i128
  %1 = llvm.zext %arg61 : i32 to i128
  %2 = llvm.zext %arg62 : i32 to i128
  %3 = llvm.and %2, %0 : i128
  %4 = llvm.lshr %1, %3 : i128
  %5 = llvm.trunc %4 : i128 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

inductive FpPredicate where
 
| bin (lhs : FpExpr e) (op : FpBinaryPredKind) (rhs : FpExpr e)
deriving Hashable, DecidableEq, Repr, BEq

GetElem? in Init.GetElem

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

def ExprRemapVar [DecidableEq d.Ty] [DecidableEq d.Op]
    {Γstart Γ Γ' : Ctxt d.Ty} {α}
    (lets : Lets d Γstart .pure Γ)
    (hom : Ctxt.Hom Γ' Γ)
    (vold : HVector Γ.Var α)
    (vnew : HVector Γ'.Var α)
    (VNEW: ∀ (Vstart : Ctxt.Valuation Γstart), vold.map (lets.denote Vstart) =
      vnew.map ((lets.denote Vstart).comap hom))
    (e' : Expr d Γ' .pure β) :
    {e : Expr d Γ .pure β // ∀ (V : Ctxt.Valuation Γstart),
          e.denoteOp (lets.denote V)
          = e'.denoteOp ((lets.denote V).comap hom) } :=
  match e' with
  | ⟨op, ty_eq, eff_le, args, regArgs⟩ =>
    let ⟨args', hargs'⟩ := VarRemapVar lets hom vold vnew VNEW args
    ⟨.mk op ty_eq eff_le args' regArgs, by admit /- proof elided -/
    ⟩

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

def bools_logical_commute0_after := [llvm|
{
^0(%arg108 : i1, %arg109 : i1, %arg110 : i1):
  %0 = "llvm.select"(%arg110, %arg109, %arg108) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

Lean.addAndCompile in Lean.AddDecl

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

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

def add {Γ : Ctxt _} (e₁ e₂ : Ctxt.Var Γ .nat) : Expr Ex Γ .pure [.nat] :=
  Expr.mk
    (op := .add)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .cons e₁ <| .cons e₂ .nil)
    (regArgs := .nil)

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

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

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

Sum.elim in Init.Data.Sum.Basic

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 select_icmp_ne_0_and_4096_and_not_32_after := [llvm|
{
^0(%arg205 : i32, %arg206 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(-33 : i32) : i32
  %3 = llvm.and %arg205, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.and %arg206, %2 : i32
  %6 = "llvm.select"(%4, %5, %arg206) <{"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_3_before := [llvm|
{
^0(%arg316 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.shl %0, %arg316 : i32
  %3 = llvm.and %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

def PR42691_1_before := [llvm|
{
^0(%arg343 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(2147483647 : i32) : i32
  %2 = llvm.icmp "slt" %arg343, %0 : i32
  %3 = llvm.icmp "eq" %arg343, %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) -> ()
}
]

def llvm_sext_lower_riscv_i1_to_32 : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 1)] :=
  {lhs:= sext_llvm_i1_to_32, rhs:= sext_riscv_i1_to_32}

def and_ne_with_one_bit_diff_constants1_before := [llvm|
{
^0(%arg364 : i32):
  %0 = llvm.mlir.constant(51 : i32) : i32
  %1 = llvm.mlir.constant(50 : i32) : i32
  %2 = llvm.icmp "ne" %arg364, %0 : i32
  %3 = llvm.icmp "ne" %arg364, %1 : i32
  %4 = llvm.and %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

RV64.div in RISCV.Instructions

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

@[simp_denote]
def llvm_xor_64: Com  LLVMPlusRiscV ⟨[.llvm (.bitvec 64), .llvm (.bitvec 64)]⟩
  .pure (.llvm (.bitvec 64)) := [LV| {
  ^entry (%x: i64, %y: i64):
    %0 = llvm.xor    %x, %y : i64
    llvm.return %0 : i64
  }]

def select_icmp_eq_and_1_0_lshr_fv_before := [llvm|
{
^0(%arg2 : i8, %arg3 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.mlir.constant(2 : i8) : i8
  %3 = llvm.and %arg2, %0 : i8
  %4 = llvm.icmp "eq" %3, %1 : i8
  %5 = llvm.lshr %arg3, %2 : i8
  %6 = "llvm.select"(%4, %arg3, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%6) : (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_C1Minus2MinusC2_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 %c1, %a : 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.sub %c1, %c2 : i64
      %1 = llvm.sub %0, %a : i64
      llvm.return %1 : i64
  }]

def ashrsgt_02_05_before := [llvm|
{
^0(%arg296 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.mlir.constant(5 : i4) : i4
  %2 = llvm.ashr %arg296, %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_02_14_exact_before := [llvm|
{
^0(%arg71 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.mlir.constant(-2 : i4) : i4
  %2 = llvm.ashr exact %arg71, %0 : i4
  %3 = llvm.icmp "sgt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

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

@[combinator_formatter MLIR.EDSL.balancedBrackets]
def MLIR.EDSL.balancedBrackets.formatter : Formatter := pure ()

def lshrugt_03_05_exact_after := [llvm|
{
^0(%arg184 : 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 test1_after := [llvm|
{
^0(%arg209 : i32):
  "llvm.return"(%arg209) : (i32) -> ()
}
]

def test13_after := [llvm|
{
^0(%arg178 : i32, %arg179 : i32):
  %0 = llvm.and %arg178, %arg179 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def lowmask_or_zext_commute_before := [llvm|
{
^0(%arg217 : i16, %arg218 : i24):
  %0 = llvm.mlir.constant(65535 : i24) : i24
  %1 = llvm.zext %arg217 : i16 to i24
  %2 = llvm.or %arg218, %1 : i24
  %3 = llvm.and %2, %0 : i24
  "llvm.return"(%3) : (i24) -> ()
}
]

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

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

def t1_before := [llvm|
{
^0(%arg17 : i16):
  %0 = llvm.mlir.constant(1 : i16) : i16
  %1 = llvm.mlir.constant(-1 : i16) : i16
  %2 = llvm.shl %0, %arg17 : i16
  %3 = llvm.add %2, %1 : i16
  %4 = llvm.or %3, %2 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

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_samevar_shlnuwnsw_lshrexact_after := [llvm|
{
^0(%arg27 : i8, %arg28 : i8):
  "llvm.return"(%arg27) : (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 xor_and_before := [llvm|
{
^0(%arg146 : i1, %arg147 : i32, %arg148 : i32):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "ult" %arg147, %arg148 : i32
  %3 = "llvm.select"(%arg146, %2, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = llvm.xor %3, %1 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def AttrDict.addType (attrs: AttrDict φ) (k: String) (v: MLIRType φ): AttrDict φ :=
    AttrEntry.mk k (v : AttrValue φ) :: attrs

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

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

def bug : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 1)] where
  lhs:= original
  rhs:= optimized_incorrect
  correct := by admit /- proof elided -/

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

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

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

def lshrugt_01_06_exact_before := [llvm|
{
^0(%arg215 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(6 : i4) : i4
  %2 = llvm.lshr exact %arg215, %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) -> ()
}
]

instance : ToMessageData (ParsedInputState) where
  toMessageData s := printParsedBVExprState s

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

def 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 srem2_ashr_mask_after := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.srem %arg6, %0 : i32
  %2 = llvm.and %1, %0 : i32
  "llvm.return"(%2) : (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 src_before := [llvm|
{
^0(%arg0 : i1):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.zext %arg0 : i1 to i32
  %2 = llvm.shl %0, %1 : i32
  %3 = llvm.xor %2, %0 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.shl %4, %1 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def EnvFin.ofEnv (env : Env w) (n : Nat) : EnvFin w n :=
  fun i => env.getD i 0#w

def getValFromCtxt (Γ : Ctxt d.Ty) (name : String) (expectedType : d.Ty) :
    ReaderM d (Ctxt.Var Γ expectedType) := do
  let index := (←read).lookup name
  let some index := index | throw <| .undeclaredName name
  let n := Γ.length
  if h : index >= n then
     
    throw <| .indexOutOfBounds name index n
  else
    let t := Γ.toList[index]'(Nat.lt_of_not_le h)
    if h : t = expectedType then
      return ⟨index, by admit /- proof elided -/
      ⟩
    else
      throw <| .typeError (toString expectedType) (toString t)

def test_nuw_nsw_and_unsigned_pred_after := [llvm|
{
^0(%arg55 : i64):
  %0 = llvm.mlir.constant(6) : i64
  %1 = llvm.icmp "ugt" %arg55, %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_04_exact_before := [llvm|
{
^0(%arg113 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(4 : i4) : i4
  %2 = llvm.lshr exact %arg113, %0 : i4
  %3 = llvm.icmp "ult" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

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 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 size (α : Type u) : Circuit α → Nat
| tru | fals | var .. => 1
| and l r | or l r | xor l r => 1 + l.size  + r.size

def trunc_lshr_zext_before := [llvm|
{
^0(%arg12 : i8):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.zext %arg12 : i8 to i32
  %2 = llvm.lshr %1, %0 : i32
  %3 = llvm.trunc %2 : i32 to i8
  "llvm.return"(%3) : (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_to_mul_before := [llvm|
{
^0(%arg8 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(21 : i32) : i32
  %2 = llvm.mlir.constant(3 : i32) : i32
  %3 = llvm.udiv %arg8, %0 : i32
  %4 = llvm.mul %3, %1 : i32
  %5 = llvm.urem %arg8, %0 : i32
  %6 = llvm.mul %5, %2 : i32
  %7 = llvm.add %4, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def simplify_and_common_op_commute2_after := [llvm|
{
^0(%arg25 : i4, %arg26 : i4, %arg27 : i4, %arg28 : i4):
  %0 = llvm.mlir.constant(0 : i4) : i4
  "llvm.return"(%0) : (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_01_15_exact_after := [llvm|
{
^0(%arg38 : i4):
  %0 = llvm.mlir.constant(-2 : i4) : i4
  %1 = llvm.icmp "slt" %arg38, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

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 visitAND_Sameop : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %0 = llvm.and %x, %x : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      llvm.return %x : i64
  }]

def n1_before := [llvm|
{
^0(%arg2 : i8, %arg3 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.shl %0, %arg3 : i8
  %3 = llvm.xor %2, %1 : i8
  %4 = llvm.and %3, %arg2 : i8
  %5 = llvm.icmp "eq" %4, %arg2 : i8
  "llvm.return"(%5) : (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_C1Minus2MinusC2_neg2_neg1 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (-2) : i64
      %c2 = llvm.mlir.constant (-1) : i64
      %0 = llvm.sub %c1, %a : i64
      %1 = llvm.sub %0, %c2 : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (-2) : i64
      %c2 = llvm.mlir.constant (-1) : i64
      %0 = llvm.sub %c1, %c2 : i64
      %1 = llvm.sub %0, %a : i64
      llvm.return %1 : i64
  }]

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

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

def sdiv_pow2 : List (Σ Γ, LLVMPeepholeRewriteRefine 64 Γ) :=
  [
    ⟨_, sdiv_pow2_2⟩,
    ⟨_, sdiv_pow2_4⟩,
    ⟨_, sdiv_pow2_8⟩,
    ⟨_, sdiv_pow2_16⟩,
    ⟨_, sdiv_pow2_32⟩,
    ⟨_, sdiv_pow2_64⟩,
    ⟨_, sdiv_pow2_128⟩,
    ⟨_, sdiv_pow2_256⟩,
    ⟨_, sdiv_pow2_512⟩
  ]

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

Lean.mkApp3 in Lean.Expr

def revertBvHyps (g : MVarId) : MetaM MVarId := do
  let (_, g) ← g.revert (← g.getNondepPropHyps)
  return g

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

def srl_i32_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := srl_llvm_i32
  rhs := srl_riscv_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_x_slt_0_and_icmp_y_sgt_neg1_i32_fail_after := [llvm|
{
^0(%arg40 : i32, %arg41 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.icmp "sgt" %arg40, %0 : i32
  %3 = llvm.icmp "slt" %arg41, %1 : i32
  %4 = llvm.and %3, %2 : i1
  %5 = llvm.zext %4 : i1 to i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def Expr.mkToFSM (self : Expr) : MetaM Expr :=
  mkAppM ``FSMPredicateSolution.toFSM #[self]

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

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

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

class DecidableNFA [Fintype σ] [Fintype α] [DecidableEq σ] [DecidableEq α] (m : NFA α σ) where
  decidable_start : Decidable (q ∈ m.start)
  decidable_accept : Decidable (q ∈ m.accept)
  decidable_step : Decidable (s' ∈ m.step s a)

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

def Eqn.denoteFin {w : Nat} (e : Eqn) (envFin : EnvFin w e.numVars) : Int :=
  match e with
  | [] => 0
  | t :: ts =>
    t.denoteFin (envFin.castLe (by admit /- proof elided -/
    )) +
    Eqn.denoteFin ts (envFin.castLe (by admit /- proof elided -/
    ))

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

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

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

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

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

noncomputable def R.monomial {q n : Nat} (c : ZMod q) (i : Nat): R q n :=
  R.fromPoly (Polynomial.monomial i c)

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

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_before := [llvm|
{
^0(%arg18 : i8, %arg19 : i8, %arg20 : i1):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(-2 : i8) : i8
  %2 = llvm.or %arg18, %0 : i8
  %3 = llvm.and %arg19, %1 : i8
  %4 = llvm.or %2, %3 : i8
  %5 = llvm.icmp "ule" %4, %3 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

def p0_before := [llvm|
{
^0(%arg14 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.shl %arg14, %0 : i8
  %2 = llvm.ashr exact %1, %0 : i8
  %3 = llvm.icmp "eq" %2, %arg14 : 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_before := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(223 : i32) : i32
  %1 = llvm.mlir.constant(29 : i32) : i32
  %2 = llvm.mlir.constant(-784568073 : i32) : i32
  %3 = llvm.mlir.constant(1874836915 : i32) : i32
  %4 = llvm.mlir.constant(221 : i32) : i32
  %5 = llvm.mlir.constant(1 : i32) : i32
  %6 = llvm.mlir.constant(1533579450 : i32) : i32
  %7 = llvm.mlir.constant(-2147483648 : i32) : i32
  %8 = llvm.mlir.constant(749011377 : i32) : i32
  %9 = llvm.and %arg0, %0 : i32
  %10 = llvm.xor %9, %1 : i32
  %11 = llvm.add %10, %2 overflow<nuw> : i32
  %12 = llvm.or %10, %3 : i32
  %13 = llvm.and %10, %4 : i32
  %14 = llvm.xor %13, %3 : i32
  %15 = llvm.xor %12, %14 : i32
  %16 = llvm.shl %15, %5 overflow<nsw,nuw> : i32
  %17 = llvm.sub %11, %16 : i32
  %18 = llvm.add %17, %6 overflow<nsw> : i32
  %19 = llvm.or %18, %7 : i32
  %20 = llvm.xor %19, %8 : i32
  "llvm.return"(%20) : (i32) -> ()
}
]

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

def test7_after := [llvm|
{
^0(%arg96 : i64):
  %0 = llvm.mlir.constant(32) : i64
  %1 = llvm.lshr %arg96, %0 : i64
  %2 = llvm.zext nneg %1 : i64 to i92
  "llvm.return"(%2) : (i92) -> ()
}
]

def t0_after := [llvm|
{
^0(%arg14 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "slt" %arg14, %0 : i8
  "llvm.return"(%1) : (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_01_exact_before := [llvm|
{
^0(%arg116 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(1 : i4) : i4
  %2 = llvm.lshr exact %arg116, %0 : i4
  %3 = llvm.icmp "ult" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def masked_icmps_mask_notallzeros_bmask_mixed_negated_7_before := [llvm|
{
^0(%arg56 : i32):
  %0 = llvm.mlir.constant(7 : 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 %arg56, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.and %arg56, %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 t0_after := [llvm|
{
^0(%arg32 : i8):
  %0 = llvm.mlir.constant(15 : i8) : i8
  %1 = llvm.mlir.constant(-16 : i8) : i8
  %2 = llvm.add %arg32, %0 : i8
  %3 = llvm.and %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def ne_umax4_after := [llvm|
{
^0(%arg38 : i32, %arg39 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg38, %0 : i32
  %2 = llvm.icmp "ult" %1, %arg39 : i32
  "llvm.return"(%2) : (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 neg_nsw_sgt_0_before := [llvm|
{
^0(%arg17 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.sub %0, %arg17 overflow<nsw> : i8
  %2 = llvm.icmp "sgt" %1, %0 : i8
  "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_before := [llvm|
{
^0(%arg39 : i9):
  %0 = llvm.mlir.constant(2 : i9) : i9
  %1 = llvm.mlir.constant(3 : i9) : i9
  %2 = llvm.lshr %arg39, %0 : i9
  %3 = llvm.lshr %2, %1 : i9
  %4 = llvm.mul %2, %3 : i9
  "llvm.return"(%4) : (i9) -> ()
}
]

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

Function.uncurry in Init.Data.Function

def sel_zext_constants_after := [llvm|
{
^0(%arg96 : i1):
  %0 = llvm.mlir.constant(255 : i16) : i16
  %1 = llvm.mlir.constant(42 : i16) : i16
  %2 = "llvm.select"(%arg96, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i16, i16) -> i16
  "llvm.return"(%2) : (i16) -> ()
}
]

@[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_sameconst_shlnuwnsw_after := [llvm|
{
^0(%arg46 : i8):
  %0 = llvm.mlir.constant(-8 : i8) : i8
  %1 = llvm.and %arg46, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def urem_illegal_type_before := [llvm|
{
^0(%arg15 : i9, %arg16 : i9):
  %0 = llvm.zext %arg15 : i9 to i32
  %1 = llvm.zext %arg16 : i9 to i32
  %2 = llvm.urem %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

Prod.mk in Init.Prelude

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

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

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

def original_sdiv_srem := [LV| {
  ^entry (%a: i64, %b: i64):
    %0= llvm.sdiv exact %a, %b : i64
    %1 = llvm.srem %a, %b : i64
    llvm.return %1 : 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 no_masks_with_logical_or2_after := [llvm|
{
^0(%arg7 : i32, %arg8 : i32, %arg9 : i32):
  %0 = llvm.mlir.constant(63 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.icmp "ne" %arg8, %0 : i32
  %4 = llvm.and %arg7, %arg9 : i32
  %5 = llvm.icmp "ne" %4, %1 : i32
  %6 = "llvm.select"(%5, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

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

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

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

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

def test_sle_xor_after := [llvm|
{
^0(%arg42 : i32, %arg43 : i32):
  %0 = llvm.xor %arg42, %arg43 : i32
  %1 = llvm.icmp "sge" %0, %arg43 : 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 select_icmp_sgt_allones_smin_flipped_after := [llvm|
{
^0(%arg2 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.or %arg2, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

def negate_ashr_after := [llvm|
{
^0(%arg110 : i8, %arg111 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.lshr %arg111, %0 : i8
  %2 = llvm.add %1, %arg110 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

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

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

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

    return allInputs

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 udiv_i1_is_op0_before := [llvm|
{
^0(%arg4 : i1, %arg5 : i1):
  %0 = llvm.udiv %arg4, %arg5 : 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_y_todo_after := [llvm|
{
^0(%arg10 : i8, %arg11 : i1):
  %0 = llvm.mlir.constant(-8 : i8) : i8
  %1 = llvm.mlir.constant(-25 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = "llvm.select"(%arg11, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = llvm.and %arg10, %3 : i8
  %5 = llvm.icmp "eq" %4, %2 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

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

def test8_after := [llvm|
{
^0(%arg20 : i32):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.mlir.constant(32767 : i32) : i32
  %2 = llvm.ashr %arg20, %0 : i32
  %3 = llvm.mul %2, %1 overflow<nsw> : i32
  %4 = llvm.sext %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 shl1_trunc_sgt4_after := [llvm|
{
^0(%arg15 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(4 : i16) : i16
  %2 = llvm.shl %0, %arg15 overflow<nuw> : i32
  %3 = llvm.trunc %2 : i32 to i16
  %4 = llvm.icmp "sgt" %3, %1 : i16
  "llvm.return"(%4) : (i1) -> ()
}
]

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 runMainCmd (args : Cli.Parsed) : IO UInt32 := do
  let fileName := args.positionalArg! "file" |>.as! String
  if args.hasFlag "verbose" then 
    let code ← verbose_flag fileName
    return code
  if args.hasFlag "riscv" then 
    let code ←  parseAsRiscv fileName
    return code
  if args.hasFlag "passriscv64" then 
    let code ← passriscv64 fileName
    return code
  if args.hasFlag "passriscv64_optimized" then 
    let code ← passriscv64_optimized fileName
    return code
  if args.hasFlag "passriscv64_optimized_const" then 
    let code ← passriscv64_optimized fileName
    return code
  if args.hasFlag "passriscv64_selectiondag" then 
    let code ← passriscv64_selectiondag fileName
    return code
  else
    let code ← wellformed fileName
    return code

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

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

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

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 llvm_freeze_lower_riscv_32 : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := freeze_llvm_32
  rhs := freeze_riscv_32

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

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

RV64.sh2adduw in RISCV.Instructions

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

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

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

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

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

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_ugt_1_after := [llvm|
{
^0(%arg66 : i1, %arg67 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg66, %0 : i1
  %2 = llvm.and %arg67, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

def scalar_i32_lshr_and_negC_eq_X_is_constant1_before := [llvm|
{
^0(%arg9 : i32):
  %0 = llvm.mlir.constant(12345 : i32) : i32
  %1 = llvm.mlir.constant(-8 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.lshr %0, %arg9 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.icmp "eq" %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_signed : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (2) : i64
      %0 = llvm.mul %x, %c overflow<nsw, nuw> : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %0 = llvm.add %x, %x overflow<nsw, nuw> : i64
      llvm.return %0 : i64
  }]

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

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

def icmp_slt_0_and_icmp_sgt_neg1_i64_after := [llvm|
{
^0(%arg60 : i64):
  %0 = llvm.mlir.constant(0) : i64
  "llvm.return"(%0) : (i64) -> ()
}
]

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

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

def ashrsgt_03_09_after := [llvm|
{
^0(%arg276 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (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 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 not_mul_of_bool_commute_before := [llvm|
{
^0(%arg87 : i32, %arg88 : i32):
  %0 = llvm.mlir.constant(30 : i32) : i32
  %1 = llvm.mlir.constant(255 : i32) : i32
  %2 = llvm.lshr %arg87, %0 : i32
  %3 = llvm.and %arg88, %1 : i32
  %4 = llvm.mul %3, %2 : i32
  %5 = llvm.icmp "ugt" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

def icmp_ult_8_after := [llvm|
{
^0(%arg12 : i64):
  %0 = llvm.mlir.constant(16) : i64
  %1 = llvm.icmp "ult" %arg12, %0 : i64
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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 llvm_const_lower_riscv_li12 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM12, rhs:= liRiscv12,
   correct := by admit /- proof elided -/

def ashrslt_03_01_exact_after := [llvm|
{
^0(%arg20 : 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_commute5_after := [llvm|
{
^0(%arg120 : i8, %arg121 : i8, %arg122 : i8):
  %0 = llvm.or %arg121, %arg120 : i8
  %1 = llvm.or %0, %arg122 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

def sub_shl_same_amount_partial_nsw1_before := [llvm|
{
^0(%arg11 : i6, %arg12 : i6, %arg13 : i6):
  %0 = llvm.shl %arg11, %arg13 overflow<nsw> : i6
  %1 = llvm.shl %arg12, %arg13 overflow<nsw> : i6
  %2 = llvm.sub %0, %1 : i6
  "llvm.return"(%2) : (i6) -> ()
}
]

def liftEffect_compose {e1 e2 e3 : EffectKind} {α : Type} [Pure m]
    (h12 : e1 ≤ e2)
    (h23 : e2 ≤ e3)
    (h13 : e1 ≤ e3 := le_trans h12 h23) :
    ((liftEffect (α := α) h23) ∘ (liftEffect h12)) = liftEffect (m := m) h13 :=

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

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

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

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

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

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

def 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_samevar_shlnsw_ashrexact_before := [llvm|
{
^0(%arg37 : i8, %arg38 : i8):
  %0 = llvm.ashr exact %arg37, %arg38 : i8
  %1 = llvm.shl %0, %arg38 overflow<nsw> : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

Function.Injective2 in Mathlib.Logic.Function.Basic

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 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 visitMUL_XShift : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64, %y: i64):
      %c = llvm.mlir.constant (1) : i64
      %1 = llvm.shl %c, %y : i64
      %0 = llvm.mul %x, %1 : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64, %y: i64):
      %0 = llvm.shl %x, %y : i64
      llvm.return %0 : i64
  }]

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_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 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_samevar_lshrexact_before := [llvm|
{
^0(%arg42 : i8, %arg43 : i8):
  %0 = llvm.lshr exact %arg42, %arg43 : i8
  %1 = llvm.shl %0, %arg43 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

def lshrult_03_09_before := [llvm|
{
^0(%arg326 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(-7 : i4) : i4
  %2 = llvm.lshr %arg326, %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 and_zext_demanded_after := [llvm|
{
^0(%arg255 : i16, %arg256 : i32):
  %0 = llvm.mlir.constant(8 : i16) : i16
  %1 = llvm.lshr %arg255, %0 : i16
  %2 = llvm.zext nneg %1 : i16 to i32
  "llvm.return"(%2) : (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 and_lshr_and_before := [llvm|
{
^0(%arg63 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg63, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  %4 = llvm.lshr %arg63, %0 : i32
  %5 = llvm.and %4, %0 : i32
  %6 = "llvm.select"(%3, %5, %0) <{"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 t1_after := [llvm|
{
^0(%arg16 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.ashr %arg16, %0 : i8
  %2 = llvm.sext %1 : i8 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

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

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

def llvm_add_lower_riscv_nuw_nsw_flag_1 : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 1), Ty.llvm (.bitvec 1)] where
  lhs:= add_llvm_nsw_nuw_flags_1
  rhs:= add_riscv_1

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

def a_before := [llvm|
{
^0(%arg48 : i1, %arg49 : i1):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.zext %arg48 : i1 to i32
  %3 = llvm.zext %arg49 : i1 to i32
  %4 = llvm.sub %0, %3 : i32
  %5 = llvm.add %2, %1 : i32
  %6 = llvm.add %5, %4 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def t1_flags_nuw_second_before := [llvm|
{
^0(%arg36 : i8, %arg37 : i8, %arg38 : i8):
  %0 = llvm.sub %arg36, %arg37 : i8
  %1 = llvm.sub %0, %arg38 overflow<nuw> : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def add_nsw_const_const_sub_before := [llvm|
{
^0(%arg59 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(-127 : i8) : i8
  %2 = llvm.add %arg59, %0 overflow<nsw> : i8
  %3 = llvm.sub %1, %2 : i8
  "llvm.return"(%3) : (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_shl1_is_cmp_eq_0_multiuse_before := [llvm|
{
^0(%arg14 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.shl %0, %arg14 : 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 liRiscv_45 := [LV| {
  ^entry ():
    %0 = "li"() {imm = -45 : !i64} : (!i64) -> (!i64)
    %1 = "builtin.unrealized_conversion_cast"(%0) : (!i64) -> (i64)
    llvm.return %1 : i64
  }]

def source : TokenStream :=
  Stream.corec () fun () => (some (), ())

def andcond.010.inv.inner.cond.in.inner.sel_before := [llvm|
{
^0(%arg65 : i1, %arg66 : i1, %arg67 : i1, %arg68 : i1, %arg69 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = "llvm.select"(%arg65, %arg66, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = llvm.xor %arg65, %1 : i1
  %4 = "llvm.select"(%3, %arg68, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %5 = "llvm.select"(%2, %arg69, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%5) : (i1) -> ()
}
]

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

Lean.Meta.check in Lean.Meta.Check

@[simp_denote]
def llvm_shl_lower_riscv_32: LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := shl_llvm_32
  rhs := shl_riscv_32

def shift_xor_multiuse_cmp_after := [llvm|
{
^0(%arg84 : i32, %arg85 : i32, %arg86 : i32, %arg87 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(2048 : i32) : i32
  %3 = llvm.and %arg84, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.or %arg85, %2 : i32
  %6 = "llvm.select"(%4, %5, %arg85) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg87, %arg86) <{"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 srem   (w : Width φ) : MOp φ := .binary w .srem

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 lshr_16_to_64_add_zext_basic_before := [llvm|
{
^0(%arg17 : i16, %arg18 : i16):
  %0 = llvm.mlir.constant(16) : i64
  %1 = llvm.zext %arg17 : i16 to i64
  %2 = llvm.zext %arg18 : i16 to i64
  %3 = llvm.add %1, %2 : i64
  %4 = llvm.lshr %3, %0 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

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

def ashr_mul_sign_bits_after := [llvm|
{
^0(%arg101 : i8, %arg102 : i8):
  %0 = llvm.mlir.constant(3 : i16) : i16
  %1 = llvm.sext %arg101 : i8 to i16
  %2 = llvm.sext %arg102 : i8 to i16
  %3 = llvm.mul %1, %2 overflow<nsw> : i16
  %4 = llvm.ashr %3, %0 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

Membership in Init.Prelude

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

partial def reflectPredicateAux (exprToIx : ReflectMap) (e : Expr) (wExpected : Expr) : MetaM (ReflectResult Predicate) := do
  match_expr e with
  | Eq α a b =>
    match_expr α with
    | Nat =>
       
      
      if wExpected != a then
        throwError m!"Only Nat expressions allowed are '{wExpected} ≠ <concrete value>'. Found {indentD e}."
      let some natVal ← Lean.Meta.getNatValue? b
        | throwError m!"Expected '{wExpected} ≠ <concrete width>', found symbolic width {indentD b}."
      let out := Predicate.width .eq natVal
      return { exprToIx := exprToIx, e := out }

    | BitVec w =>
      let a ←  reflectTermUnchecked exprToIx w a
      let b ← reflectTermUnchecked a.exprToIx w b
      return { exprToIx := b.exprToIx, e := Predicate.binary .eq a.e b.e }
    | Bool =>
      
      
      
      
      let_expr true := b
        | throwError m!"only boolean conditionals allowed are 'bv.\{u,s}l\{t,e} bv = true'. Found {indentD e}."
      match_expr a with
      | BitVec.slt w a b =>
        let a ← reflectTermUnchecked exprToIx w a
        let b ← reflectTermUnchecked a.exprToIx w b
        return { exprToIx := b.exprToIx, e := Predicate.binary .slt a.e b.e }
      | BitVec.sle w a b =>
        let a ← reflectTermUnchecked exprToIx w a
        let b ← reflectTermUnchecked a.exprToIx w b
        return { exprToIx := b.exprToIx, e := Predicate.binary .sle a.e b.e }
      | BitVec.ult w a b =>
        let a ← reflectTermUnchecked exprToIx w a
        let b ← reflectTermUnchecked a.exprToIx w b
        return { exprToIx := b.exprToIx, e := Predicate.binary .ult a.e b.e }
      | BitVec.ule w a b =>
        let a ← reflectTermUnchecked exprToIx w a
        let b ← reflectTermUnchecked a.exprToIx w b
        return { exprToIx := b.exprToIx, e := Predicate.binary .ule a.e b.e }
      | _ =>
        throwError m!"unknown boolean conditional, expected 'bv.slt bv = true' or 'bv.sle bv = true'. Found {indentD e}"
    | _ =>
      throwError m!"unknown equality kind, expected 'bv = bv' or 'bv.slt bv = true' or 'bv.sle bv = true'. Found {indentD e}"
  | Ne α a b =>
     
    match_expr α with
    | Nat => do
      
      if wExpected != a then
        throwError m!"Only Nat expressions allowed are '{wExpected} ≠ <concrete value>'. Found {indentD e}."
      let some natVal ← Lean.Meta.getNatValue? b
        | throwError m!"Expected '{wExpected} ≠ <concrete width>', found symbolic width {indentD b}."
      let out := Predicate.width .neq natVal
      return { exprToIx := exprToIx, e := out }
    | BitVec w =>
      let a ← reflectTermUnchecked exprToIx w a
      let b ← reflectTermUnchecked a.exprToIx w b
      return { exprToIx := b.exprToIx, e := Predicate.binary .neq a.e b.e }
    | _ =>
      throwError m!"Expected typeclass to be 'BitVec w' / 'Nat', found '{indentD α}' in {e} when matching against 'Ne'"
  | LT.lt α _inst a b =>
    let_expr BitVec w := α | throwError m!"Expected typeclass to be BitVec w, found '{indentD α}' in {indentD e} when matching against 'LT.lt'"
    let a ← reflectTermUnchecked exprToIx w a
    let b ← reflectTermUnchecked a.exprToIx w b
    return { exprToIx := b.exprToIx, e := Predicate.binary .ult a.e b.e }
  | LE.le α _inst a b =>
    let_expr BitVec w := α | throwError m!"Expected typeclass to be BitVec w, found '{indentD α}' in {indentD e} when matching against 'LE.le'"
    let a ← reflectTermUnchecked exprToIx w a
    let b ← reflectTermUnchecked a.exprToIx w b
    return { exprToIx := b.exprToIx, e := Predicate.binary .ule a.e b.e }
  | Or p q =>
    let p ← reflectPredicateAux exprToIx p wExpected
    let q ← reflectPredicateAux p.exprToIx q wExpected
    let out := Predicate.lor p.e q.e
    return { q with e := out }
  | And p q =>
    let p ← reflectPredicateAux exprToIx p wExpected
    let q ← reflectPredicateAux p.exprToIx q wExpected
    let out := Predicate.land p.e q.e
    return { q with e := out }
  | _ =>
     throwError m!"expected predicate over bitvectors (no quantification), found:  {indentD e}"

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

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

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

def llvm_const_lower_riscv_li46 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM46, rhs:= liRiscv46,
   correct := by admit /- proof elided -/

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

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

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

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

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

def parseAsRiscv (fileName : String ) : IO UInt32 := do
  let icom? ← Com.parseFromFile RV64 fileName
  match icom? with
  | none => return 1
  | some (Sigma.mk _Γ ⟨_eff, ⟨_retTy, c⟩⟩) => do
    IO.println c.printModule
    return 0

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

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

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

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

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

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

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

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

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

NFA.start in Mathlib.Computability.NFA
</all_available_defs>

<all_available_lemmas>
Nat.not_lt_zero in Init.Prelude
Nat.zero_add in Init.Data.Nat.Basic
false_implies in Init.SimpLemmas
implies_true in Init.SimpLemmas
ne_eq in Init.SimpLemmas
true_and in Init.SimpLemmas

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 e_2318 :
    7 * (e &&&  ~~~(d &&&  ~~~f)) - 2 * ((d &&& f) |||  ~~~(e ||| f)) + 2 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 5 * (d &&&  ~~~e) + 2 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 2 * (d ^^^ e) - 11 *  ~~~(d ^^^ ( ~~~e ||| f)) - 6 * (f ^^^  ~~~(d ||| (e &&& f))) - 2 *  ~~~(d &&& f) - 11 * ((d |||  ~~~e) &&& (e ^^^ f)) - 2 * (d ||| e) - 3 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 2 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (f ^^^ ( ~~~d ||| (e ||| f))) + 11 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 1 * (e ^^^ (d ||| (e ||| f))) + 1 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 7 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 2 * (e ^^^  ~~~(d |||  ~~~f)) - 1 * (d ||| (e ^^^ f)) - 2 * (e ||| (d &&&  ~~~f)) - 3 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 * (f ||| (d ^^^ e)) + 1 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 11 * (e ^^^ (d ||| ( ~~~e &&& f))) - 5 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 5 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 2 * (e ^^^ ( ~~~d ||| (e &&& f))) + 1 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 1 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 1 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 7 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * (f ^^^ ( ~~~d &&& (e ||| f))) - 2 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 1 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 4 *  ~~~(d &&& e) + 5 * (e ^^^ ( ~~~d ||| (e ||| f))) + 2 *  ~~~(e &&&  ~~~f) + 3 * (e ^^^ (d ||| f)) - 11 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 2 * ( ~~~d ||| ( ~~~e ||| f)) - 2 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) + 4 * ( ~~~f ||| (d ^^^ e)) - 2 *  ~~~(d ^^^ e) - 7 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 6 * (f ^^^  ~~~(d &&& (e ||| f))) + 7 * (f ^^^  ~~~(d &&& e)) + 3 * (e ^^^  ~~~(d ||| f)) + 5 *  ~~~(d ||| (e &&& f)) + 1 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 7 *  ~~~( ~~~d &&& (e &&& f)) + 1 *  ~~~(d ^^^ (e ^^^ f)) + 1 *  ~~~(d &&& ( ~~~e ||| f)) - 1 *  ~~~(d ^^^ (e &&& f)) - 1 * (d ^^^ f) - 19 *  ~~~(d ||| (e ||| f)) + 11 *  ~~~(d ||| ( ~~~e ||| f)) + 23 *  ~~~( ~~~d ||| (e ||| f)) + 25 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 49 * ( ~~~d &&& ( ~~~e &&& f)) - 17 * ( ~~~d &&& (e &&& f)) + 42 * (d &&& ( ~~~e &&& f)) + 48 * (d &&& (e &&& f)) = 11 * (e ^^^ ( ~~~d &&& (e ||| f)))

theorem 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 shl_add_and_fail_mismatch_shift_thm (e e_1 : IntW 8) :
  LLVM.and (shl e_1 (const? 8 1)) (add (lshr e (const? 8 1)) (const? 8 123)) ⊑
    LLVM.and (shl e_1 (const? 8 1))
      (add (lshr e (const? 8 1)) (const? 8 123) { «nsw» := false, «nuw» := true })

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

theorem ashrslt_02_09_exact_proof : ashrslt_02_09_exact_before ⊑ ashrslt_02_09_exact_after
</all_available_lemmas>

<local_ctx>
import SSA.Projects.CIRCT.Stream.Stream

import Mathlib.Logic.Function.Iterate

import Mathlib.Data.Stream.Init

namespace CIRCTStream

namespace Stream

namespace Bisim

scoped infix:50 " ~ " => Bisim

end Bisim

open Bisim

def stuck (α : Type) : Stream α := Stream'.const none

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

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

open Classical in

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

open Classical in

open Classical in

open Classical in
</local_ctx>

<target_theorem>
theorem removeNone_equiv (x : Stream α) :
    x.removeNone ~ x :=
</target_theorem>

