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>
Vector in Init.Data.Vector.Basic
Fin in Init.Prelude
String in Init.Prelude
Unit in Init.Prelude
List in Init.Prelude
Field in Mathlib.Algebra.Field.Defs
Bool in Init.Prelude
DecidableEq in Init.Prelude
FinEnum in Mathlib.Data.FinEnum
Hashable in Init.Prelude
Sum in Init.Core
Sum.inl in Init.Core
Sum.inr in Init.Core
Sum.elim in Init.Data.Sum.Basic
Empty in Init.Prelude
Empty.elim in Init.Core
id in Init.Prelude
Nat in Init.Prelude
Repr in Init.Data.Repr
Inhabited in Init.Prelude
Lean.ToExpr in Lean.ToExpr
Nat.max in Init.Data.Nat.Basic
Nat.min in Init.Data.Nat.Basic
BitVec in Init.Prelude
BitVec.ofBool in Init.Data.BitVec.Basic
BitVec.ofNat in Init.Prelude
BitVec.signExtend in Init.Data.BitVec.Basic
BitVec.adcb in Init.Data.BitVec.Bitblast
Prod in Init.Prelude
BitVec.carry in Init.Data.BitVec.Bitblast
Bool.atLeastTwo in Init.Data.BitVec.Bitblast

syntax "min" : 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) )

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

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

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

def composeBinaryAux'
    (p : FSM Bool)
    (qtrue : FSM α)
    (qfalse : FSM α) :
    FSM α :=
  p.compose (α)
    (λ _ => α)
    (λ _ i => i)
    (λ b => match b with
      | true => qtrue
      | false => qfalse)

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 xor : FSM Bool :=
  { α := Empty,
    initCarry := Empty.elim,
    outputCirc := Circuit.var true (inr true) ^^^ Circuit.var true (inr false),
    nextStateCirc := Empty.elim
  }

def composeUnaryAux
    (p : FSM Unit)
    (q : FSM arity) :
    FSM arity :=
  p.compose
    arity
    _
    (λ _ => id)
    (λ _ => q)

def ls (b : Bool) : FSM Unit :=
  { α := Unit,
    initCarry := fun _ => b,
    nextStateCirc := fun () => Circuit.var true (inr ()),
    outputCirc := Circuit.var true (inl ())
  }

def latchImmediate (initVal : Bool) : FSM Bool where
  α := Unit
  initCarry := fun _ => initVal
  outputCirc :=
    let xval := Circuit.var true (inr false)
    let control := Circuit.var true (inr true)
    let state := Circuit.var true (inl ())
    Circuit.ite control xval state
  nextStateCirc := fun () =>
    let xval := Circuit.var true (inr false)
    let control := Circuit.var true (inr true)
    let state := Circuit.var true (inl ())
    Circuit.ite control xval state

def ite (cond t f : Circuit α) : Circuit α :=
  (cond &&& t) ||| (~~~ cond &&& f)

structure TermFSM (wcard tcard bcard ncard icard pcard : Nat) (t : Nondep.Term) where
  toFsmZext : FSM (StateSpace wcard tcard bcard ncard icard pcard)
  width : NatFSM wcard tcard bcard ncard icard pcard t.width

structure NatFSM (wcard tcard bcard ncard icard pcard : Nat) (v : Nondep.WidthExpr) where
  toFsm : FSM (StateSpace wcard tcard bcard ncard icard pcard)

inductive StateSpace (wcard tcard bcard ncard icard pcard : Nat)
| widthVar (v : Fin wcard)
| termVar (v : Fin tcard)
| predVar (v : Fin pcard)
| boolVar (v : Fin bcard)
deriving DecidableEq, Repr, Hashable

inductive Term
| ofNat (w : WidthExpr) (n : Nat) : Term
| var (v : Nat) (w : WidthExpr) : Term
| add (w : WidthExpr) (a b : Term) : Term
| zext (a : Term) (wnew : WidthExpr) : Term
| setWidth (a : Term) (wnew : WidthExpr) : Term
| sext (a : Term) (wnew : WidthExpr) : Term
| bor (w : WidthExpr) (a b : Term) : Term
| band (w : WidthExpr) (a b : Term) : Term
| bxor (w : WidthExpr) (a b : Term) : Term
| bnot (w : WidthExpr)  (a : Term) : Term
| boolVar (v : Nat) : Term
| boolConst (b : Bool) : Term
| shiftl (w : WidthExpr) (a : Term) (k : Nat) : Term
| bvOfBool (b : Term) : Term
| binWidthRel (k : WidthBinaryRelationKind) (wa wb : WidthExpr) : Term
| binRel (k : BinaryRelationKind) (w : WidthExpr)
    (a : Term) (b : Term) : Term
| or (p1 p2 : Term) : Term
| and (p1 p2 : Term) : Term
| pvar (v : Nat) : Term
| boolBinRel (k : BoolBinaryRelationKind)
    (a b : Term) : Term
deriving DecidableEq, Inhabited, Repr, Lean.ToExpr

inductive WidthExpr where
| const : Nat → WidthExpr
| var : Nat → WidthExpr
| max : WidthExpr → WidthExpr → WidthExpr
| min : WidthExpr → WidthExpr → WidthExpr
| addK : WidthExpr → Nat → WidthExpr
| kadd : Nat → WidthExpr → WidthExpr
deriving Inhabited, Repr, Hashable, DecidableEq, Lean.ToExpr

def Term.width (t : Term) : WidthExpr :=
  match t with

| .ofNat w _n => w
  | .var _v w => w
  | .add w _a _b => w
  | .zext _a wnew => wnew
  | .setWidth _a wnew => wnew
  | .sext _a wnew => wnew
  | .bor w _a _b => w
  | .band w _a _b => w
  | .bxor w _a _b => w
  | .bnot w _a => w
  | .boolVar _v => WidthExpr.const 1 
  | .boolConst _b => WidthExpr.const 1
  | .shiftl w _a _k => w
  | .bvOfBool _b => WidthExpr.const 1
  | binWidthRel _k wa wb => WidthExpr.const 0
  | binRel _k w _a _b => w
  | or _p1 _p2 => WidthExpr.const 0
  | and _p1 _p2 => WidthExpr.const 0
  | pvar _v => WidthExpr.const 0
  | boolBinRel _k _a _b => WidthExpr.const 0

inductive WidthExpr where
| const : Nat → WidthExpr
| var : Nat → WidthExpr
| max : WidthExpr → WidthExpr → WidthExpr
| min : WidthExpr → WidthExpr → WidthExpr
| addK : WidthExpr → Nat → WidthExpr
| kadd : (k : Nat) → (v : WidthExpr) → WidthExpr
deriving Inhabited, Repr, Hashable, DecidableEq, Lean.ToExpr

structure HNatFSMToBitstream {wcard : Nat} {v : WidthExpr wcard} {tcard : Nat} {bcard : Nat} {pcard : Nat}
   (fsm : NatFSM wcard tcard bcard ncard icard pcard (.ofDep v)) : Prop where
  heq :
    ∀ (wenv : Fin wcard → Nat)
    (fsmEnv : StateSpace wcard tcard bcard ncard icard pcard → BitStream),
    (henv : HWidthEnv fsmEnv wenv) →
      fsm.toFsm.eval fsmEnv =
      BitStream.ofNatUnary (v.toNat wenv)

def WidthExpr.toNat (e : WidthExpr wcard) (env : WidthExpr.Env wcard) : Nat :=
  match e with
  | .const n => n
  | .var v => env v
  | .min v w => Nat.min (v.toNat env) (w.toNat env)
  | .max v w => Nat.max (v.toNat env) (w.toNat env)
  | .addK v k => v.toNat env + k
  | .kadd k v => k + v.toNat env

inductive WidthExpr (wcard : Nat) : Type
| const (n : Nat) :  WidthExpr wcard
| var : (v : Fin wcard) → WidthExpr wcard
| min : (v w : WidthExpr wcard) → WidthExpr wcard
| max : (v w : WidthExpr wcard) → WidthExpr wcard
| addK : (v : WidthExpr wcard) → (k : Nat) → WidthExpr wcard
| kadd : (k : Nat) → (v : WidthExpr wcard) → WidthExpr wcard

abbrev WidthExpr.Env (wcard : Nat) : Type :=
  Fin wcard → Nat

structure HWidthEnv {wcard tcard : Nat}
    (fsmEnv : StateSpace wcard tcard bcard ncard icard pcard → BitStream)
    (wenv : Fin wcard → Nat) : Prop where
    heq_width : ∀ (v : Fin wcard),
      fsmEnv (StateSpace.widthVar v) = BitStream.ofNatUnary (wenv v)

structure HPredicateEnv {wcard tcard bcard ncard icard pcard : Nat}
    (fsmEnv : StateSpace wcard tcard bcard ncard icard pcard → BitStream)
    (penv : Fin pcard → Prop) : Prop where
    heq_width : ∀ (v : Fin pcard),
      fsmEnv (StateSpace.predVar v) = BitStream.ofProp (penv v)

def BitStream : Type := Nat → Bool

abbrev ofNatUnary (n : Nat) : BitStream :=
  fun i => decide (i < n)

structure HPredFSMToBitStream {pcard : Nat}
  {tctx : Term.Ctx wcard tcard}
  {p : Term bcard ncard icard pcard tctx .prop}
  (fsm : TermFSM wcard tcard bcard ncard icard pcard
    (.ofDepTerm p)) : Prop where
  heq :
    ∀ {wenv : WidthExpr.Env wcard}
      (benv : Term.BoolEnv bcard)
      (nenv : Term.NatEnv ncard)
      (ienv : Term.IntEnv icard)
      (penv : Predicate.Env pcard) (tenv : tctx.Env wenv)
      (fsmEnv : StateSpace wcard tcard bcard ncard icard pcard → BitStream),
      (htenv : HTermEnv fsmEnv tenv benv) →
      (hpenv : HPredicateEnv fsmEnv penv) →
        p.toBV benv nenv ienv penv tenv  ↔ (fsm.toFsmZext.eval fsmEnv = .negOne)

abbrev Term.Ctx (wcard : Nat) (tcard : Nat) : Type :=
  Fin tcard → WidthExpr wcard

def Term.BoolEnv (bcard : Nat) : Type := Fin bcard → Bool

def Term.IntEnv (icard : Nat) : Type := Fin icard → Nat

structure HTermFSMToBitStream {w : WidthExpr wcard}
  {tctx : Term.Ctx wcard tcard}
  {t : Term bcard ncard icard pcard tctx (.bv w)}
  (fsm : TermFSM wcard tcard bcard ncard icard pcard (.ofDepTerm t)) : Prop where
  heq :
    ∀ {wenv : WidthExpr.Env wcard}
      (benv : Term.BoolEnv bcard)
      (nenv : Term.NatEnv ncard)
      (ienv : Term.IntEnv icard)
      (penv : Predicate.Env pcard) (tenv : tctx.Env wenv)
      (fsmEnv : StateSpace wcard tcard bcard ncard icard pcard → BitStream),
      (henv : HTermEnv fsmEnv tenv benv) →
        fsm.toFsmZext.eval fsmEnv =
        BitStream.ofBitVecZext (t.toBV benv nenv ienv penv tenv)

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

inductive TermKind (wcard : Nat) : Type
| bool
| bv (w : WidthExpr wcard)  : TermKind wcard
| prop
| nat
| int

structure HTermEnv {wcard tcard bcard : Nat}
    {wenv : Fin wcard → Nat} {tctx : Term.Ctx wcard tcard}
    (fsmEnv : StateSpace wcard tcard bcard ncard icard pcard → BitStream)
    (tenv : tctx.Env wenv)
    (benv : Term.BoolEnv bcard) : Prop
  extends HWidthEnv fsmEnv wenv where
    heq_term : ∀ (v : Fin tcard),
      fsmEnv (StateSpace.termVar v) = BitStream.ofBitVecZext (tenv v)
    heq_bool : ∀ (v : Fin bcard),
      fsmEnv (StateSpace.boolVar v) = BitStream.ofBool (benv v)

noncomputable def BitStream.ofBool (b : Bool) : BitStream := fun _i => b

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

abbrev ofBitVecZext {w} (x : BitVec w) : BitStream :=
  fun i => x.getLsbD i

def Term.NatEnv (ncard : Nat) : Type := Fin ncard → Nat

def Term.toBV {wenv : WidthExpr.Env wcard}
    {tctx : Term.Ctx wcard tcard}
    (benv : Term.BoolEnv bcard)
    (nenv : Term.NatEnv ncard)
    (ienv : Term.IntEnv icard)
    (penv : Predicate.Env pcard)
    (tenv : tctx.Env wenv)
    (t : Term bcard ncard icard pcard tctx k) : k.denote wenv :=
match t with
| .ofNat w n => BitVec.ofNat (w.toNat wenv) n
| .boolConst b => b
| .var v => tenv.get v.1 v.2
| .add (w := w) a b =>
    let a : BitVec (w.toNat wenv) := (a.toBV benv nenv ienv penv tenv)
    let b : BitVec (w.toNat wenv) := (b.toBV benv nenv ienv penv tenv)
    a + b
| .zext a v => (a.toBV benv nenv ienv penv tenv).zeroExtend (v.toNat wenv)
| .setWidth a v => (a.toBV benv nenv ienv penv tenv).zeroExtend (v.toNat wenv)
| .sext a v => (a.toBV benv nenv ienv penv tenv).signExtend (v.toNat wenv)
| .bor a b (w := w) =>
    let a : BitVec (w.toNat wenv) := (a.toBV benv nenv ienv penv tenv)
    let b : BitVec (w.toNat wenv) := (b.toBV benv nenv ienv penv tenv)
    a ||| b
| .band (w := w) a b =>
    let a : BitVec (w.toNat wenv) := (a.toBV benv nenv ienv penv tenv)
    let b : BitVec (w.toNat wenv) := (b.toBV benv nenv ienv penv tenv)
    a &&& b
| .bxor (w := w) a b =>
    let a : BitVec (w.toNat wenv) := (a.toBV benv nenv ienv penv tenv)
    let b : BitVec (w.toNat wenv) := (b.toBV benv nenv ienv penv tenv)
    a ^^^ b
| .bnot (w := w) a =>
    let a : BitVec (w.toNat wenv) := (a.toBV benv nenv ienv penv tenv)
    ~~~ a
| .boolVar v => benv v
| .shiftl (w := w) a k =>
    let a : BitVec (w.toNat wenv) := (a.toBV benv nenv ienv penv tenv)
    a <<< k
| .bvOfBool b => BitVec.ofBool (b.toBV benv nenv ienv penv tenv)

| .binWidthRel rel wa wb =>
  match rel with
  | .eq => wa.toNat wenv = wb.toNat wenv
  | .le => wa.toNat wenv ≤ wb.toNat wenv
| .binRel rel _w a b =>
  match rel with
  | .eq => a.toBV benv nenv ienv penv tenv = b.toBV benv nenv ienv penv tenv
  | .ne => a.toBV benv nenv ienv penv tenv ≠ b.toBV benv nenv ienv penv tenv
  | .ult => (a.toBV benv nenv ienv penv tenv).ult (b.toBV benv nenv ienv penv tenv) = true
  | .ule => (a.toBV benv nenv ienv penv tenv).ule (b.toBV benv nenv ienv penv tenv) = true
  | .slt => (a.toBV benv nenv ienv penv tenv).slt (b.toBV benv nenv ienv penv tenv) = true
  | .sle => (a.toBV benv nenv ienv penv tenv).sle (b.toBV benv nenv ienv penv tenv) = true
| .and p1 p2 => p1.toBV benv nenv ienv penv tenv  ∧ p2.toBV benv nenv ienv penv tenv
| .or p1 p2 => p1.toBV benv nenv ienv penv tenv ∨ p2.toBV benv nenv ienv penv tenv
| .boolBinRel rel a b =>
  match rel with
  
  | .eq => (a.toBV benv nenv ienv penv tenv) = (b.toBV benv nenv ienv penv tenv)
| .pvar v => penv v

inductive Term {wcard tcard : Nat} (bcard : Nat) (ncard : Nat) (icard : Nat) (pcard : Nat)
  (tctx : Term.Ctx wcard tcard) : TermKind wcard → Type

| ofNat (w : WidthExpr wcard) (n : Nat) : Term bcard ncard icard pcard tctx (.bv w)
 
| var (v : Fin tcard) : Term bcard ncard icard pcard tctx (.bv (tctx v))
 
| add (a : Term bcard ncard icard pcard tctx (.bv w))
  (b : Term bcard ncard icard pcard tctx (.bv w)) : Term bcard ncard icard pcard tctx (.bv w)
 
| shiftl (a : Term bcard ncard icard pcard tctx (.bv w)) (k : Nat) : Term bcard ncard icard pcard tctx (.bv w)
 
| bor (a b : Term bcard ncard icard pcard tctx (.bv w)) : Term bcard ncard icard pcard tctx (.bv w)
 
| band (a b : Term bcard ncard icard pcard tctx (.bv w)) : Term bcard ncard icard pcard tctx (.bv w)
 
| bxor (a b : Term bcard ncard icard pcard tctx (.bv w)) : Term bcard ncard icard pcard tctx (.bv w)
 
| bnot (a : Term bcard ncard icard pcard tctx (.bv w)) : Term bcard ncard icard pcard tctx (.bv w)
 
| zext (a : Term bcard ncard icard pcard tctx (.bv w)) (v : WidthExpr wcard) : Term bcard ncard icard pcard tctx (.bv v)
 
| setWidth (a : Term bcard ncard icard pcard tctx (.bv w)) (v : WidthExpr wcard) : Term bcard ncard icard pcard tctx (.bv v)
 
| sext (a : Term bcard ncard icard pcard tctx (.bv w)) (v : WidthExpr wcard) : Term bcard ncard icard pcard tctx (.bv v)
 
| bvOfBool (b : Term bcard ncard icard pcard tctx .bool) : Term bcard ncard icard pcard tctx (.bv (.const 1))

| boolConst (b : Bool) : Term bcard ncard icard pcard tctx .bool
| boolVar (v : Fin bcard) : Term bcard ncard icard pcard tctx .bool
| binWidthRel (k : WidthBinaryRelationKind) (wa wb : WidthExpr wcard) :
    Term bcard ncard icard pcard tctx .prop
| binRel
    (k : BinaryRelationKind)
    (w : WidthExpr wcard)
    (a : Term bcard ncard icard pcard tctx (.bv w))
    (b : Term bcard ncard icard pcard tctx (.bv w)) :
    Term bcard ncard icard pcard tctx .prop
| and (p1 p2 : Term bcard ncard icard pcard tctx (.prop)) : Term bcard ncard icard pcard tctx (.prop)
| or (p1 p2 : Term bcard ncard icard pcard tctx (.prop)) : Term bcard ncard icard pcard tctx (.prop)
| pvar (v : Fin pcard) : Term bcard ncard icard pcard tctx (.prop)

| boolBinRel
  (k : BoolBinaryRelationKind)
  (a b : Term bcard ncard icard pcard tctx .bool) :
  Term bcard ncard icard pcard tctx (.prop)

def Term.Ctx.Env.get {tcard : Nat}
  {wcard : Nat} {wenv : Fin wcard → Nat}
  {tctx : Term.Ctx wcard tcard}
  (tenv : tctx.Env wenv) (i : Nat) (hi : i < tcard) :
  BitVec ((tctx ⟨i, hi⟩).toNat wenv) :=
  tenv ⟨i, hi⟩

inductive BinaryRelationKind
| eq
| ne
| ule
| slt
| sle
| ult 
deriving DecidableEq, Repr, Inhabited, Lean.ToExpr

inductive WidthBinaryRelationKind
| eq
| le

deriving DecidableEq, Repr, Inhabited, Lean.ToExpr

abbrev ofBitVecSext {w} (x : BitVec w) : BitStream :=
  fun i => if i < w then x.getLsbD i else x.msb

abbrev zero   : BitStream := fun _ => false

def carry' (initCarry : Bool) (x y : BitStream) : BitStream :=
  fun n =>
  match n with
  | 0 => initCarry
  | n + 1 => (addAux' initCarry x y n).2

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

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

def t20_before := [llvm|
{
^0(%arg129 : i8, %arg130 : i16):
  %0 = llvm.mlir.constant(-42 : i16) : i16
  %1 = llvm.shl %0, %arg130 : i16
  %2 = llvm.trunc %1 : i16 to i8
  %3 = llvm.sub %arg129, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

def a_or_b_const_after := [llvm|
{
^0(%arg10 : i32, %arg11 : i32, %arg12 : i32):
  %0 = llvm.icmp "eq" %arg10, %arg12 : i32
  %1 = llvm.icmp "eq" %arg11, %arg12 : i32
  %2 = llvm.xor %0, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

def shl_sub_lshr_reverse_no_nsw_before := [llvm|
{
^0(%arg133 : i32, %arg134 : i32, %arg135 : i32):
  %0 = llvm.shl %arg133, %arg134 overflow<nuw> : i32
  %1 = llvm.sub %arg135, %0 overflow<nuw> : i32
  %2 = llvm.lshr exact %1, %arg134 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def and_xor_or8_before := [llvm|
{
^0(%arg652 : i64, %arg653 : i64, %arg654 : i64):
  %0 = llvm.mlir.constant(42) : i64
  %1 = llvm.udiv %0, %arg652 : i64
  %2 = llvm.udiv %0, %arg653 : i64
  %3 = llvm.udiv %0, %arg654 : i64
  %4 = llvm.and %2, %1 : i64
  %5 = llvm.xor %3, %4 : i64
  %6 = llvm.or %2, %5 : i64
  "llvm.return"(%6) : (i64) -> ()
}
]

def shift_xor_multiuse_cmp_or_before := [llvm|
{
^0(%arg36 : i32, %arg37 : i32, %arg38 : i32, %arg39 : 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 %arg36, %0 : i32
  %4 = llvm.icmp "ne" %1, %3 : i32
  %5 = llvm.or %arg37, %2 : i32
  %6 = "llvm.select"(%4, %arg37, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg38, %arg39) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %8 = llvm.mul %6, %7 : i32
  %9 = llvm.mul %8, %5 : i32
  "llvm.return"(%9) : (i32) -> ()
}
]

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

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

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

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

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

def Body.substitute (σ : Substitution) : Body Op T → Body Op T
  | ⟨lets, terminator⟩ => ⟨lets.substitute σ, substituteTerminator σ.apply terminator⟩

def main7g_before := [llvm|
{
^0(%arg34 : i32, %arg35 : i32, %arg36 : i32, %arg37 : i32, %arg38 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.and %arg35, %arg37 : i32
  %3 = llvm.and %arg36, %arg38 : i32
  %4 = llvm.and %2, %arg34 : i32
  %5 = llvm.icmp "eq" %2, %4 : i32
  %6 = llvm.and %3, %arg34 : i32
  %7 = llvm.icmp "eq" %3, %6 : i32
  %8 = llvm.and %5, %7 : i1
  %9 = "llvm.select"(%8, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%9) : (i32) -> ()
}
]

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

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

def anyext_trunc_fold: List (Σ Γ, LLVMPeepholeRewriteRefine 32 Γ) :=
  [⟨_, anyext_trunc_fold_sext_32⟩,
  ⟨_, anyext_trunc_fold_zext_32⟩]

def test2_before := [llvm|
{
^0(%arg2 : i49):
  %0 = llvm.mlir.constant(4096 : i49) : i49
  %1 = llvm.mlir.constant(17 : i49) : i49
  %2 = llvm.shl %0, %1 : i49
  %3 = llvm.udiv %arg2, %2 : i49
  "llvm.return"(%3) : (i49) -> ()
}
]

def argVector.decEq : DecidableEq (HVector (Ctxt.Var Γ) ts) := inferInstance

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 const_sub_add_const_after := [llvm|
{
^0(%arg30 : i32):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.sub %0, %arg30 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

def Config.default : Config := {}

def udiv2_after := [llvm|
{
^0(%arg30 : i32, %arg31 : i32):
  %0 = llvm.lshr exact %arg30, %arg31 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

@[simp]
def Env.getLsb_eq_of_width_one (env : List (BitVec 1)) : Env.getLsb env = env :=

@[simp_denote]
def zext_llvm_8_to_64 := [LV| {
  ^entry (%arg: i8):
    %0 = llvm.zext %arg: i8 to i64
    llvm.return %0: i64
  }]

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

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

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

def one_inst_macro (w: Nat) :=
  [llvm(w)|{
  ^bb0(%arg0: _):
    %0 = llvm.not %arg0
    llvm.return %0
  }]

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

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

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

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

def test14_after := [llvm|
{
^0(%arg26 : i35):
  %0 = llvm.mlir.constant(-19760 : i35) : i35
  %1 = llvm.mlir.constant(19744 : i35) : i35
  %2 = llvm.and %arg26, %0 : i35
  %3 = llvm.or disjoint %2, %1 : i35
  "llvm.return"(%3) : (i35) -> ()
}
]

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

Lean.Elab.Term.withDeclName in Lean.Elab.Term.TermElabM

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

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

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

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

def demorgan_or_apint1_after := [llvm|
{
^0(%arg62 : i43, %arg63 : i43):
  %0 = llvm.mlir.constant(-1 : i43) : i43
  %1 = llvm.and %arg62, %arg63 : i43
  %2 = llvm.xor %1, %0 : i43
  "llvm.return"(%2) : (i43) -> ()
}
]

BitVec.toInt in Init.Data.BitVec.Basic

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

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

@[simp]
def liftUnop_unchanged' (k : Fin n) : liftUnop n k.castSucc = k.castLE (by simp) :=

def sub_2_after := [llvm|
{
^0(%arg109 : i8, %arg110 : i1, %arg111 : i8, %arg112 : i8):
  %0 = llvm.mlir.constant(-124 : i8) : i8
  %1 = llvm.mlir.constant(-2 : i8) : i8
  %2 = llvm.xor %arg112, %0 : i8
  %3 = "llvm.select"(%arg110, %arg111, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = llvm.add %3, %arg109 : i8
  %5 = llvm.sub %1, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

HXor in Init.Prelude

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

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

abbrev LoopBody (t : Type) : Type := Int → t → t

Lean.Parser.Term.matchAlt in Lean.Parser.Term

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

def test_simplify_decrement_invalid_ne_after := [llvm|
{
^0(%arg209 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "eq" %arg209, %0 : i8
  %2 = llvm.sext %1 : i1 to i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def subtract (op1 : GenBVExpr w) (op2 : GenBVExpr w) : GenBVExpr w :=
  add op1 (negate op2)

RV64.sh2adduw in RISCV.Instructions

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

def worklistRun (final : S → Bool) (inits : Array S)
    (hinits : inits.toList.Nodup) (f : S → Array (BitVec n × S)) : CNFA n :=
  ⟨worklistRun' _ S final inits hinits f, worklistRun'_wf (BitVec n) S⟩

Ideal in Mathlib.RingTheory.Ideal.Defs

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

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

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

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

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

@[simp_denote]
def select_riscv_32 := [LV| {
  ^entry (%cond : i1, %arg0: i32, %arg1: i32):
    %0 = "builtin.unrealized_conversion_cast" (%arg0) : (i32) -> (!i64)
    %1 = "builtin.unrealized_conversion_cast" (%arg1) : (i32) -> (!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) -> (i32)
    llvm.return %7 : i32
  }]

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

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

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

def withSignature (sig : List d.Ty) : Except TransformError (HVector Γ.Var sig) := do
  if h : args.types = sig then
    return h ▸ args.toHVector
  else
    throw <| .generic "Argument types don't match expected signature. Expected:\n\
        \t{sig}\nfound:\n\t{args.types}"

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

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

def t0_after := [llvm|
{
^0(%arg10 : i64):
  %0 = llvm.mlir.constant(63) : i64
  %1 = llvm.ashr %arg10, %0 : i64
  "llvm.return"(%1) : (i64) -> ()
}
]

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

def t4_c1_after := [llvm|
{
^0(%arg23 : i8, %arg24 : i8):
  %0 = llvm.mlir.constant(-42 : i8) : i8
  %1 = llvm.add %arg23, %0 : i8
  %2 = llvm.sub %1, %arg24 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

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

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

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

instance : ToString FpBinaryPredKind := ⟨FpBinaryPredKind.toString⟩

inductive SSAVal : Type where
  | name : String -> SSAVal
deriving DecidableEq, Repr

bool in Init.Control.Basic

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

def CNFA.toNFA' (m : CNFA n) : NFA' n := ⟨_, m.toNFA⟩

Membership in Init.Prelude

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

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

def cadicalTimeoutSec : Nat := 1000

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

def eq_smin4_after := [llvm|
{
^0(%arg81 : i32, %arg82 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg81, %0 : i32
  %2 = llvm.icmp "sle" %1, %arg82 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

def p_constmask2_after := [llvm|
{
^0(%arg41 : i32, %arg42 : i32):
  %0 = llvm.mlir.constant(61440 : i32) : i32
  %1 = llvm.mlir.constant(-65281 : i32) : i32
  %2 = llvm.and %arg41, %0 : i32
  %3 = llvm.and %arg42, %1 : i32
  %4 = llvm.or disjoint %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

def parseExprs (lhsExpr rhsExpr : Expr) (width : Nat): ParseExprM (Option ParsedFpLogicalExpr)  := do
  let some lhsRes ← toBVExpr lhsExpr width | throwError "Could not extract lhs: {lhsExpr}"

  let state ← get
  let lhs: ParsedFpExpr := {bvExpr := lhsRes.bvExpr, width := lhsRes.width, symVars := state.symVarToVal, inputVars := state.inputVarIdToVariable}

  let some rhsRes ← toBVExpr rhsExpr width | throwError "Could not extract rhs: {rhsExpr}"
  let state ← get

  let rhsInputVars := state.inputVarIdToVariable.filter fun k _ => !lhs.inputVars.contains k
  let rhsSymVars := state.symVarToVal.filter fun k _ => !lhs.symVars.contains k

  let rhs: ParsedFpExpr := {bvExpr := rhsRes.bvExpr, width := rhsRes.width, symVars := rhsSymVars, inputVars := rhsInputVars}

  trace[Generalize] m! "lhs width: {lhsRes.width}; rhs width: {rhsRes.width}"
  if h : lhsRes.width = rhsRes.width then
    let rhsExpr := h ▸ rhsRes.bvExpr
    
    
    let bvLogicalExpr := BoolExpr.literal (FpPredicate.bin lhsRes.bvExpr FpBinaryPredKind.eq rhsExpr)
    trace[Generalize] m! "BVLogicalExpr: {bvLogicalExpr}"
    return some {lhs := lhs, rhs := rhs, state := state, logicalExpr := bvLogicalExpr}

  return none

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

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

@[simp]
def liftUnop_unchanged (k : Fin n) : liftUnop n k = k.castLE (by simp) :=

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

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

def ConcreteCliTest.parseableInputs (test : ConcreteCliTest) :
    Cli.ParseableType (List.Vector Int test.context.length)
  := inferInstance

def demorgan_nand_apint1_before := [llvm|
{
^0(%arg36 : i7, %arg37 : i7):
  %0 = llvm.mlir.constant(-1 : i7) : i7
  %1 = llvm.xor %arg36, %0 : i7
  %2 = llvm.and %1, %arg37 : i7
  %3 = llvm.xor %2, %0 : i7
  "llvm.return"(%3) : (i7) -> ()
}
]

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

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

def EnvFin.cons (env : EnvFin w n) (b : BitVec w) : EnvFin w (n + 1) :=
  fun i => i.cases b env

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

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

def zext_sext_ule_known_nonneg_op0_wide_after := [llvm|
{
^0(%arg16 : i9, %arg17 : i8):
  %0 = llvm.mlir.constant(254 : i9) : i9
  %1 = llvm.urem %arg16, %0 : i9
  %2 = llvm.sext %arg17 : i8 to i9
  %3 = llvm.icmp "ule" %1, %2 : i9
  "llvm.return"(%3) : (i1) -> ()
}
]

@[simp_denote]
def add_b31_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := add_b31_llvm_i64
  rhs := add_b31_riscv_i64

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

def test22_after := [llvm|
{
^0(%arg55 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.and %arg55, %0 : i32
  %2 = llvm.urem %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def right_identity_zero : List (Σ Γ, RISCVPeepholeRewrite  Γ) :=
  [⟨_, right_identity_zero_sub⟩,
  ⟨_, right_identity_zero_add⟩,
  ⟨_, right_identity_zero_or⟩,
  ⟨_, right_identity_zero_xor⟩,
  ⟨_, right_identity_zero_shl⟩,
  ⟨_, right_identity_zero_ashr⟩,
  ⟨_, right_identity_zero_lshr⟩,
  ⟨_, right_identity_zero_rol⟩,
  ⟨_, right_identity_zero_ror ⟩]

def test58_before := [llvm|
{
^0(%arg124 : i64):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(128 : i32) : i32
  %2 = llvm.trunc %arg124 : i64 to i32
  %3 = llvm.lshr %2, %0 : i32
  %4 = llvm.or %3, %1 : i32
  %5 = llvm.zext %4 : i32 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

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

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

structure NFA'.correct2 (M : NFA' 2) (ζ : M.sa2) (L : BVRel) where
  cond1 : ∀ (bv1 bv2 : BitVec w), (L bv1 bv2 ↔ ∃ q ∈ M.M.accept, ζ q bv1 bv2)
  cond2 q : q ∈ M.M.start ↔ ζ q .nil .nil
  cond3 q a w (bv1 bv2 : BitVec w) : q ∈ M.M.stepSet { q | ζ q bv1 bv2 } a ↔
              ζ q (BitVec.cons (a.getLsbD 0) bv1) (BitVec.cons (a.getLsbD 1) bv2)

def select2_after := [llvm|
{
^0(%arg9 : i1, %arg10 : i8, %arg11 : i8, %arg12 : i8):
  %0 = llvm.add %arg10, %arg11 : i8
  %1 = "llvm.select"(%arg9, %arg12, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

def main7d_before := [llvm|
{
^0(%arg64 : i32, %arg65 : i32, %arg66 : i32, %arg67 : i32, %arg68 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.and %arg65, %arg67 : i32
  %3 = llvm.and %arg66, %arg68 : i32
  %4 = llvm.and %arg64, %2 : i32
  %5 = llvm.icmp "eq" %4, %2 : i32
  %6 = llvm.and %arg64, %3 : i32
  %7 = llvm.icmp "eq" %6, %3 : i32
  %8 = llvm.and %5, %7 : i1
  %9 = "llvm.select"(%8, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%9) : (i32) -> ()
}
]

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

Lean.mkAuxDeclName in Lean.CoreM

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

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

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

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

def add_i32_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := add_llvm_i32
  rhs := add_riscv_i32

def masked_bit_wrong_pred_after := [llvm|
{
^0(%arg57 : i32, %arg58 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %0, %arg58 overflow<nuw> : i32
  %3 = llvm.and %2, %arg57 : i32
  %4 = llvm.icmp "sgt" %3, %1 : i32
  %5 = llvm.zext %4 : i1 to i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

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

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

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

def test1_after := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(1431655765 : i32) : i32
  %2 = llvm.lshr %arg1, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.sub %arg1, %3 overflow<nsw> : i32
  "llvm.return"(%4) : (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) -> ()
}
]

String.intercalate in Init.Data.String.Defs

def sextbool_add_before := [llvm|
{
^0(%arg12 : i1, %arg13 : i32):
  %0 = llvm.sext %arg12 : i1 to i32
  %1 = llvm.add %0, %arg13 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

def or_eq_notY_eq_0_before := [llvm|
{
^0(%arg45 : i8, %arg46 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.xor %arg46, %0 : i8
  %2 = llvm.or %arg45, %1 : i8
  %3 = llvm.icmp "eq" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

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

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

def alive_229_src  (w : Nat)   :=
[llvm( w )| {
^bb0(%X : _, %C1 : _, %Op1 : _):
  %v1 = llvm.add %X, %C1
  %v2 = llvm.mul %v1, %Op1
  llvm.return %v2
}]

instance : ToFormat Sexpr where
  format := Sexpr.toFormat

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

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

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

def llvm_const_lower_riscv_li_23 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_23, rhs:= liRiscv_23,
   correct := by admit /- proof elided -/

def c_0_1_0_before := [llvm|
{
^0(%arg29 : i4, %arg30 : i4, %arg31 : i4):
  %0 = llvm.mlir.constant(-1 : i4) : i4
  %1 = llvm.xor %arg31, %0 : i4
  %2 = llvm.xor %arg29, %arg30 : i4
  %3 = llvm.and %2, %1 : i4
  %4 = llvm.xor %3, %arg29 : i4
  "llvm.return"(%4) : (i4) -> ()
}
]

def debugLog (msgData : MessageData) : SolverM Unit := do
  if (← read).verbose? then
    log msgData MessageSeverity.information
  else
    return ()

def MatchArgResult.toHom
    (map : MatchArgResult lets matchLets vs ws mapIn)
    (hvars : ∀ t (v : Var Δ_in t), ⟨t, v⟩ ∈ matchLets.varsOfVec ws) :
    Δ_in.Hom Γ_out :=
  map.val.toHom <| map.isTotal_of hvars

variable
  {Γ_in Γ_out Δ_in Δ_out : Ctxt d.Ty}
  {lets : Lets d Γ_in eff Γ_out}
  {matchTy}
  {v : Var Γ_out matchTy}
  {matchLets : Lets d Δ_in .pure Δ_out}
  {w : Var Δ_out matchTy}
in

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

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

abbrev falseIffGe (n : Nat) : BitStream := fun i => decide (i < n)

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

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

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

@[simp]
def casesOn_toCons
    {motive : (Γ : Ctxt Ty) → (t t' : Ty) → Ctxt.Var (Γ.cons t') t → Sort _}
    {Γ : Ctxt Ty} {t t' : Ty} (v : Γ.Var t)
    (base : {t t' : Ty} →
        {Γ : Ctxt Ty} → (v : Γ.Var t) → motive Γ t t' v.toCons)
    (last : {Γ : Ctxt Ty} → {t : Ty} → motive Γ t t (Ctxt.Var.last _ _)) :
      Ctxt.Var.casesOn (motive := motive) (toCons (t' := t') v) base last = base v :=
  rfl

@[simp] abbrev Expr.varName (e : Expr Op Γ ty) : VarName := e.val.varName

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

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

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 ripple_nsw4_before := [llvm|
{
^0(%arg17 : i16, %arg18 : i16):
  %0 = llvm.mlir.constant(-21845 : i16) : i16
  %1 = llvm.mlir.constant(21843 : i16) : i16
  %2 = llvm.and %arg18, %0 : i16
  %3 = llvm.and %arg17, %1 : i16
  %4 = llvm.add %3, %2 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

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

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

def zext_or_eq_ult_add_after := [llvm|
{
^0(%arg15 : i32):
  %0 = llvm.mlir.constant(-3 : i32) : i32
  %1 = llvm.mlir.constant(3 : i32) : i32
  %2 = llvm.add %arg15, %0 : i32
  %3 = llvm.icmp "ult" %2, %1 : i32
  %4 = llvm.zext %3 : i1 to i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

    |

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

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

def and_not_or_commute2_before := [llvm|
{
^0(%arg475 : i32, %arg476 : i32, %arg477 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg476 : i32
  %3 = llvm.and %arg475, %2 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.or %4, %arg477 : i32
  %6 = llvm.and %arg475, %arg477 : i32
  %7 = llvm.xor %6, %1 : i32
  %8 = llvm.or %2, %7 : i32
  %9 = llvm.and %8, %5 : i32
  "llvm.return"(%9) : (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 inputSnd : (CIRCTStream.DCOp.TokenStream × CIRCTStream.DCOp.TokenStream) := (tok1, tok2)

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

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

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

def HVector.toVarSet : {l : List d.Ty} → (T : HVector (Var Γ) l) → VarSet Γ
  | [], .nil => ∅
  | _::_, .cons v vs => insert ⟨_, v⟩ vs.toVarSet

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

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

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

def sgt_or_not_min_before := [llvm|
{
^0(%arg30 : i8, %arg31 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.icmp "sgt" %arg30, %arg31 : i8
  %2 = llvm.icmp "ne" %arg30, %0 : i8
  %3 = llvm.or %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def lshr_exact_add_negative_shift_positive_after := [llvm|
{
^0(%arg56 : i32):
  %0 = llvm.mlir.constant(4 : i32) : i32
  %1 = llvm.lshr exact %0, %arg56 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

Lean.registerSimplePersistentEnvExtension in Lean.EnvExtension

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

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

def and_logic_and_logic_or_5_before := [llvm|
{
^0(%arg126 : i1, %arg127 : i1, %arg128 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.and %arg126, %arg127 : i1
  %3 = "llvm.select"(%arg126, %arg128, %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 exact_ashr_eq_after := [llvm|
{
^0(%arg160 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.icmp "eq" %arg160, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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 llvm_shl_lower_riscv_nsw_nuw_32: LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := shl_llvm_nsw_nuw_32
  rhs := shl_riscv_32

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

def mul_of_sdiv_before := [llvm|
{
^0(%arg5 : i8):
  %0 = llvm.mlir.constant(12 : i8) : i8
  %1 = llvm.mlir.constant(-6 : i8) : i8
  %2 = llvm.sdiv exact %arg5, %0 : i8
  %3 = llvm.mul %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

def test7_after := [llvm|
{
^0(%arg190 : i1):
  %0 = llvm.zext %arg190 : i1 to i64
  "llvm.return"(%0) : (i64) -> ()
}
]

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

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

@[simp_denote]
def ctxtTransformToRiscV (Γ : Ctxt LLVMPlusRiscV.Ty) :=
  Ctxt.map  (fun ty  =>
    match ty with
    | .riscv someRiscVTy => someRiscVTy
    | _  => .bv
  ) Γ

def select_icmp_x_and_8_eq_0_y_xor_8_after := [llvm|
{
^0(%arg179 : i32, %arg180 : i64):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.and %arg179, %0 : i32
  %2 = llvm.zext nneg %1 : i32 to i64
  %3 = llvm.xor %arg180, %2 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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

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

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

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

def urem_common_divisor_defined_cond_before := [llvm|
{
^0(%arg29 : i1, %arg30 : i5, %arg31 : i5, %arg32 : i5):
  %0 = llvm.urem %arg31, %arg30 : i5
  %1 = llvm.urem %arg32, %arg30 : i5
  %2 = "llvm.select"(%arg29, %1, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i5, i5) -> i5
  "llvm.return"(%2) : (i5) -> ()
}
]

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

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

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

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

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

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

def dont_narrow_zext_ashr_keep_trunc_before := [llvm|
{
^0(%arg0 : i8, %arg1 : i8):
  %0 = llvm.mlir.constant(1 : i16) : i16
  %1 = llvm.sext %arg0 : i8 to i16
  %2 = llvm.sext %arg1 : i8 to i16
  %3 = llvm.add %1, %2 overflow<nsw> : i16
  %4 = llvm.ashr %3, %0 : i16
  %5 = llvm.trunc %4 : i16 to i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

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

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

def test_ashr_exact__exact_is_unsafe_after := [llvm|
{
^0(%arg50 : i32, %arg51 : i64):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(-536870897 : i32) : i32
  %2 = llvm.ashr %arg50, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.zext nneg %3 : i32 to i64
  %5 = llvm.ashr %arg51, %4 : i64
  "llvm.return"(%5) : (i64) -> ()
}
]

Lean.Expr.forallE in Lean.Expr

instance : HydrableInitializeGeneralizerState ParsedBVExpr GenBVPred GenBVExpr where
  initializeGeneralizerState := initialGeneralizerState

def replicate (x : BitVec w) (n : Nat) : BitVec (w * n) :=
  BitVec.replicate n x

def CNFA.union_language (m₁ m₂ : CNFA n) :
    m₁.recognizes L₁ →
    m₂.recognizes L₂ →
    (m₁.union m₂).recognizes (L₁ ∪ L₂) :=

def zext_nneg_flag_drop_before := [llvm|
{
^0(%arg7 : i8, %arg8 : i16):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.mlir.constant(128 : i16) : i16
  %2 = llvm.and %arg7, %0 : i8
  %3 = llvm.zext nneg %2 : i8 to i16
  %4 = llvm.or %3, %arg8 : i16
  %5 = llvm.or %4, %1 : i16
  "llvm.return"(%5) : (i16) -> ()
}
]

def zext_nneg_sext_ule_op0_wide_before := [llvm|
{
^0(%arg46 : i9, %arg47 : i8):
  %0 = llvm.zext nneg %arg46 : i9 to i32
  %1 = llvm.sext %arg47 : i8 to i32
  %2 = llvm.icmp "ule" %0, %1 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

structure Item where
 name : String
 tac : Syntax

def shift_xor_multiuse_cmp_with_xor_after := [llvm|
{
^0(%arg80 : i32, %arg81 : i32, %arg82 : i32, %arg83 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(2048 : i32) : i32
  %3 = llvm.and %arg80, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.xor %arg81, %2 : i32
  %6 = "llvm.select"(%4, %5, %arg81) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg83, %arg82) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %8 = llvm.mul %6, %7 : i32
  "llvm.return"(%8) : (i32) -> ()
}
]

def test_mul_nuw__nuw_is_safe_after := [llvm|
{
^0(%arg10 : i32):
  %0 = llvm.mlir.constant(268435457 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.and %arg10, %0 : i32
  %3 = llvm.mul %2, %1 overflow<nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def nfaOfFormula (φ : Formula) : CNFA φ.arity :=
  match φ with
  | .width wp n => CNFA.autWidth wp n
  | .atom rel t1 t2 =>
    let m1 := nfaOfTerm t1
    let m2 := nfaOfTerm t2
    let f1 := liftMaxSucc1 (FinEnum.card $ Fin t1.arity) (FinEnum.card $ Fin t2.arity)
    let m1' := m1.lift f1
    let f2 := liftMaxSucc2 (FinEnum.card $ Fin t1.arity) (FinEnum.card $ Fin t2.arity)
    let m2' := m2.lift f2
    let meq := rel.autOfRelation.lift $ liftLast2 (max (FinEnum.card (Fin t1.arity)) (FinEnum.card (Fin t2.arity)))
    let m := CNFA.inter m1' m2' |> CNFA.inter meq
    let mfinal := m.proj (liftExcept2 _)
    mfinal
  | .msbSet t =>
    let m := (termEvalEqFSM t).toFSM |> CNFA.ofFSM
    let mMsb := CNFA.autMsbSet.lift $ fun _ => Fin.last t.arity
    let res := m.inter mMsb
    res.proj $ fun n => n.castLE (by admit /- proof elided -/
    )
  | .unop op φ => unopNfa op (nfaOfFormula φ)
  | .binop op φ1 φ2 =>
    let m1 := (nfaOfFormula φ1).lift $ liftMax1 φ1.arity φ2.arity
    let m2 := (nfaOfFormula φ2).lift $ liftMax2 φ1.arity φ2.arity
    binopNfa op m1 m2

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

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

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

   
  printTy : d.Ty → String

   
  dialectName : String
  

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

def SourceEg := [DC_com| {
  ^entry():
    %src = "DC.source" () : () -> (!TokenStream)
    "return" (%src) : (!TokenStream) -> ()
  }]

def PR28476_logical_before := [llvm|
{
^0(%arg6 : i32, %arg7 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.icmp "ne" %arg6, %0 : i32
  %4 = llvm.icmp "ne" %arg7, %0 : i32
  %5 = "llvm.select"(%3, %4, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %6 = llvm.zext %5 : i1 to i32
  %7 = llvm.xor %6, %2 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

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

def substBvEqualities (g : MVarId) : MetaM (Option MVarId) := g.withContext do
  let gs ← g.casesRec fun localDecl => do
    let some (ty, _lhs, _rhs) := localDecl.type.eq?
      | return false
    return ty.isConstOf ``BitVec
  ensureAtMostOne gs

def exampleSource := [DCxComb_com| {
  ^entry():
    %src = "DCxComb.source" () : () -> (!TokenStream)
    "return" (%src) : (!TokenStream) -> ()
  }]

def goo_before := [llvm|
{
^0(%arg105 : i32, %arg106 : i32, %arg107 : i32, %arg108 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.icmp "slt" %arg105, %arg106 : i32
  %3 = "llvm.select"(%2, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.and %3, %arg107 : i32
  %5 = llvm.xor %3, %0 : i32
  %6 = llvm.and %5, %arg108 : i32
  %7 = llvm.or %4, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

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

def scalar_i32_lshr_and_negC_slt_after := [llvm|
{
^0(%arg2 : i32, %arg3 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.lshr %arg2, %arg3 : i32
  %2 = llvm.icmp "slt" %1, %0 : 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) -> ()
}
]

structure Signature (Ty : Type) where
  arguments : List Ty
  regions : List (RegionType Ty)
  returnType : Ty

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 lshr_add_exact_after := [llvm|
{
^0(%arg6 : i8, %arg7 : i8):
  %0 = llvm.mlir.constant(-4 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.and %arg6, %0 : i8
  %3 = llvm.and %arg7, %1 : i8
  %4 = llvm.lshr exact %2, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

def main_before := [llvm|
{
^0(%arg2 : i32):
  %0 = llvm.mlir.constant(-17 : i8) : i8
  %1 = llvm.mlir.constant(122 : i8) : i8
  %2 = llvm.mlir.constant(6 : i8) : i8
  %3 = llvm.mlir.constant(7 : i8) : i8
  %4 = llvm.mlir.constant(64 : i8) : i8
  %5 = llvm.trunc %arg2 : i32 to i8
  %6 = llvm.or %5, %0 : i8
  %7 = llvm.and %5, %1 : i8
  %8 = llvm.xor %7, %0 : i8
  %9 = llvm.shl %8, %2 : i8
  %10 = llvm.xor %9, %8 : i8
  %11 = llvm.xor %6, %10 : i8
  %12 = llvm.lshr %11, %3 : i8
  %13 = llvm.mul %12, %4 : i8
  %14 = llvm.zext %13 : i8 to i32
  "llvm.return"(%14) : (i32) -> ()
}
]

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

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

def test18_after := [llvm|
{
^0(%arg179 : i8):
  %0 = llvm.sext %arg179 : i8 to i16
  "llvm.return"(%0) : (i16) -> ()
}
]

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

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

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

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

def src_is_mask_ashr_before := [llvm|
{
^0(%arg92 : i8, %arg93 : i8, %arg94 : i8, %arg95 : i1):
  %0 = llvm.mlir.constant(123 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.mlir.constant(15 : i8) : i8
  %3 = llvm.xor %arg92, %0 : i8
  %4 = llvm.add %arg93, %1 : i8
  %5 = llvm.xor %arg93, %4 : i8
  %6 = "llvm.select"(%arg95, %5, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %7 = llvm.ashr %6, %arg94 : i8
  %8 = llvm.and %3, %7 : i8
  %9 = llvm.icmp "ult" %8, %3 : i8
  "llvm.return"(%9) : (i1) -> ()
}
]

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

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

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

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

List.flatten in Init.Prelude

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

def select_2_after := [llvm|
{
^0(%arg82 : i1, %arg83 : i8, %arg84 : i1, %arg85 : i8, %arg86 : i8):
  %0 = llvm.mlir.constant(-124 : i8) : i8
  %1 = llvm.mlir.constant(-46 : i8) : i8
  %2 = llvm.xor %arg86, %0 : i8
  %3 = "llvm.select"(%arg84, %arg85, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = llvm.xor %arg83, %1 : i8
  %5 = "llvm.select"(%arg82, %3, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

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

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

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

def test14_after := [llvm|
{
^0(%arg26 : i35):
  %0 = llvm.mlir.constant(-19760 : i35) : i35
  %1 = llvm.mlir.constant(19744 : i35) : i35
  %2 = llvm.and %arg26, %0 : i35
  %3 = llvm.or disjoint %2, %1 : i35
  "llvm.return"(%3) : (i35) -> ()
}
]

def test11_before := [llvm|
{
^0(%arg6 : i32, %arg7 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(128 : i32) : i32
  %2 = llvm.shl %arg6, %0 : i32
  %3 = llvm.add %2, %arg7 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.mul %4, %2 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

def reused_mul_nuw_xy_z_selectnonzero_ugt_after := [llvm|
{
^0(%arg39 : i8, %arg40 : i8, %arg41 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "eq" %arg41, %0 : i8
  %3 = llvm.mul %arg39, %arg41 overflow<nuw> : i8
  %4 = llvm.mul %arg40, %arg41 overflow<nuw> : i8
  %5 = llvm.icmp "ugt" %4, %3 : i8
  %6 = "llvm.select"(%2, %1, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def test7_before := [llvm|
{
^0(%arg16 : i77):
  %0 = llvm.mlir.constant(-1 : i77) : i77
  %1 = llvm.sub %0, %arg16 : i77
  "llvm.return"(%1) : (i77) -> ()
}
]

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

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

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

def llvm_const_lower_riscv_li_26 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_26, rhs:= liRiscv_26,
   correct := by admit /- proof elided -/

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

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 trunc_signed_nsw_zext_before := [llvm|
{
^0(%arg26 : i32, %arg27 : i8):
  %0 = llvm.trunc %arg26 overflow<nsw> : i32 to i16
  %1 = llvm.zext %arg27 : i8 to i16
  %2 = llvm.icmp "slt" %0, %1 : i16
  "llvm.return"(%2) : (i1) -> ()
}
]

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

def bvExprToSubstitutionValue (map: Std.HashMap Nat BVExprWrapper) : Std.HashMap Nat (SubstitutionValue GenBVExpr) :=
      Std.HashMap.ofList (List.map (fun item => (item.fst, SubstitutionValue.genExpr item.snd.bvExpr)) map.toList)

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

def not_signbit_trunc_after := [llvm|
{
^0(%arg16 : i16):
  %0 = llvm.mlir.constant(-1 : i16) : i16
  %1 = llvm.icmp "sgt" %arg16, %0 : i16
  %2 = llvm.zext %1 : i1 to i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

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

def generateTestSemantics : IO Unit := do
  let filename := "generated-ssa-llvm-syntax-and-semantics.csv"
  let handle : Handle ← IO.FS.Handle.mk filename IO.FS.Mode.write
  let stream : Stream := IO.FS.Stream.ofHandle handle
  let mut rows := #[rowHeader]
  for test in llvmTests! do
    rows := rows.append (← concreteCliTestRows test)
  rows.toList |>.map toString |> "\n".intercalate |> stream.putStr
  return ()

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

def widget_before := [llvm|
{
^0(%arg0 : i32, %arg1 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.mlir.constant(20 : i32) : i32
  %3 = llvm.mlir.constant(1 : i32) : i32
  %4 = llvm.icmp "eq" %arg0, %0 : i32
  %5 = llvm.zext %4 : i1 to i32
  %6 = llvm.sub %1, %5 : i32
  %7 = llvm.mul %2, %6 : i32
  %8 = llvm.zext %4 : i1 to i32
  %9 = llvm.xor %8, %3 : i32
  %10 = llvm.add %7, %9 : i32
  %11 = llvm.mul %10, %6 : i32
  "llvm.return"(%11) : (i32) -> ()
}
]

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

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

def sub_inc_before := [llvm|
{
^0(%arg10 : i8, %arg11 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.add %arg10, %0 : i8
  %2 = llvm.sub %arg11, %1 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def mkReturn (Γ : Ctxt DCxComb.Ty) (opStx : MLIR.AST.Op 0) :
   MLIR.AST.ReaderM DCxComb (Σ eff ty, Com DCxComb Γ eff ty) := do
  if opStx.name ≠ "return" then
    throw <| .generic s!"Tried to build return out of non-return statement {opStx.name}"
  else
    let args ← (← opStx.parseArgs Γ).assumeArity 1
    let ⟨ty, v⟩ := args[0]
    return ⟨.pure, ty, Com.ret v⟩

def sub_1_after := [llvm|
{
^0(%arg113 : i8, %arg114 : i1, %arg115 : i8, %arg116 : i8):
  %0 = llvm.mlir.constant(-124 : i8) : i8
  %1 = llvm.xor %arg116, %0 : i8
  %2 = "llvm.select"(%arg114, %arg115, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %3 = llvm.add %2, %arg113 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

@[tactic medusaSynthGeneralize]
def evalBvGeneralize : Tactic
  | `(tactic| md_synth_generalize $cfg) => do
      let cfg ← elabMedusaSynthGeneralizeConfig cfg
      withMainContext do
        generalizeTactic (H := bvHydrableParseAndGeneralize) cfg (← getMainTarget)
  | _ => Lean.Elab.throwUnsupportedSyntax

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

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

def nxor : FSM Bool :=
  { α := Empty,
    initCarry := Empty.elim,
    nextStateCirc := Empty.elim,
    outputCirc :=
      
      
      
      
      
      (Circuit.tru ^^^
        ( (Circuit.var true (inr true)) ^^^
        (Circuit.var true (inr false))))
  }

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

def main7c_after := [llvm|
{
^0(%arg72 : i32, %arg73 : i32, %arg74 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mul %arg74, %0 : i32
  %2 = llvm.or %arg73, %1 : i32
  %3 = llvm.and %arg72, %2 : i32
  %4 = llvm.icmp "ne" %3, %2 : i32
  %5 = llvm.zext %4 : i1 to i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

def and_two_ranges_to_mask_and_range_not_pow2_diff_after := [llvm|
{
^0(%arg251 : i8):
  %0 = llvm.mlir.constant(-123 : i8) : i8
  %1 = llvm.mlir.constant(-26 : i8) : i8
  %2 = llvm.mlir.constant(-90 : i8) : i8
  %3 = llvm.add %arg251, %0 : i8
  %4 = llvm.icmp "ult" %3, %1 : i8
  %5 = llvm.add %arg251, %2 : i8
  %6 = llvm.icmp "ult" %5, %1 : i8
  %7 = llvm.and %4, %6 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

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

def WidthExpr.ofDep {wcard : Nat}
    (w : MultiWidth.WidthExpr wcard) : WidthExpr :=
  match w with
  | .const n => .const n
  | .var v => .var v
  | .max a b => .max (.ofDep a) (.ofDep b)
  | .min a b => .min (.ofDep a) (.ofDep b)
  | .addK a k => .addK (.ofDep a) k
  | .kadd k a => .kadd k (.ofDep a)

RV64.srlw in RISCV.Instructions

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 test5_after := [llvm|
{
^0(%arg4 : i32):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.shl %arg4, %0 : i32
  %2 = llvm.ashr exact %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

def bitVecToFinFun [FinEnum ar] (bv : BitVec $ FinEnum.card ar) : ar → Bool :=
  fun c => bv[FinEnum.equiv.toFun c]

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

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

def fold_or_zext_icmp_before := [llvm|
{
^0(%arg94 : i64, %arg95 : i64, %arg96 : i64):
  %0 = llvm.icmp "sgt" %arg94, %arg95 : i64
  %1 = llvm.zext %0 : i1 to i8
  %2 = llvm.icmp "slt" %arg94, %arg96 : i64
  %3 = llvm.zext %2 : i1 to i8
  %4 = llvm.or %1, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

inductive MOp.UnaryOp (φ : Nat) : Type
  | neg
  | not
  | copy
  | freeze
  | trunc (w' : Width φ) (noWrapFlags : NoWrapFlags := {nsw := false, nuw := false} )
  | zext  (w' : Width φ) (nneg : NonNegFlag := {nneg := false} )
  | sext  (w' : Width φ)
deriving Repr, DecidableEq, Inhabited, Lean.ToExpr

def sdiv_ult_smin_after := [llvm|
{
^0(%arg18 : i8, %arg19 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.sdiv %arg18, %arg19 : i8
  %2 = llvm.icmp "sgt" %1, %0 : i8
  "llvm.return"(%2) : (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 liRiscv_18 := [LV| {
  ^entry ():
    %0 = "li"() {imm = -18 : !i64} : (!i64) -> (!i64)
    %1 = "builtin.unrealized_conversion_cast"(%0) : (!i64) -> (i64)
    llvm.return %1 : i64
  }]

def printException : Except Exception α → IO String
  | Except.ok _ => throw <| IO.userError "printException called on Except.ok"
  | Except.error e => e.toMessageData.toString

def select_replace_udiv_non_speculatable_after := [llvm|
{
^0(%arg1 : i32, %arg2 : i32):
  "llvm.return"(%arg2) : (i32) -> ()
}
]

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

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

def sdiv_exact_eq_9_no_of_before := [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.sdiv exact %arg8, %2 : i8
  %4 = llvm.icmp "eq" %3, %1 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

def test_or4_logical_after := [llvm|
{
^0(%arg22 : i32, %arg23 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.and %arg23, %0 : i32
  %2 = llvm.icmp "ugt" %arg22, %1 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def shift_xor_multiuse_cmp_before := [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 "ne" %1, %3 : i32
  %5 = llvm.or %arg85, %2 : i32
  %6 = "llvm.select"(%4, %arg85, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg86, %arg87) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %8 = llvm.mul %6, %7 : i32
  "llvm.return"(%8) : (i32) -> ()
}
]

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

noncomputable def mkSimplePathOfPath (fsm : FSM arity)
    (s0 : fsm.α → Bool) (n : Nat) (inputs : arity → BitStream) :
    SimplePathOfPath fsm s0 n inputs :=

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

def main5e_like_before := [llvm|
{
^0(%arg108 : i32, %arg109 : i32, %arg110 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.and %arg108, %arg109 : i32
  %3 = llvm.icmp "eq" %2, %arg108 : i32
  %4 = llvm.and %arg108, %arg110 : i32
  %5 = llvm.icmp "eq" %4, %arg108 : 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 test1_before := [llvm|
{
^0(%arg26 : i23):
  %0 = llvm.sub %arg26, %arg26 : i23
  "llvm.return"(%0) : (i23) -> ()
}
]

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

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

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

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

Function.comp in Init.Prelude

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

def xor_sext_sext_before := [llvm|
{
^0(%arg48 : i8, %arg49 : i4):
  %0 = llvm.sext %arg48 : i8 to i16
  %1 = llvm.sext %arg49 : i4 to i16
  %2 = llvm.xor %0, %1 : i16
  "llvm.return"(%2) : (i16) -> ()
}
]

def trunc_equality_nsw_sext_after := [llvm|
{
^0(%arg14 : i32, %arg15 : i8):
  %0 = llvm.sext %arg15 : i8 to i32
  %1 = llvm.icmp "ne" %arg14, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

def fsmTermNe {wcard tcard : Nat}
  {a b : Nondep.Term}
  (afsm : TermFSM wcard tcard bcard ncard icard pcard a)
  (bfsm : TermFSM wcard tcard bcard ncard icard pcard b)
  : FSM (StateSpace wcard tcard bcard ncard icard pcard) :=
    composeUnaryAux FSM.scanOr
    (composeBinaryAux' FSM.xor afsm.toFsmZext  bfsm.toFsmZext)

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

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

Lean.instantiateMVars in Lean.MetavarContext

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

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

instance instEffToMonadRefinement :
    HRefinement (eff₁.toMonad m α) (eff₂.toMonad n β) where
  IsRefinedBy x y := coe_toMonad x ⊑ coe_toMonad y

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

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

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

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

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

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

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

def in_constant_6_vary_invmask_before := [llvm|
{
^0(%arg35 : i4, %arg36 : i4):
  %0 = llvm.mlir.constant(-1 : i4) : i4
  %1 = llvm.mlir.constant(6 : i4) : i4
  %2 = llvm.xor %arg36, %0 : i4
  %3 = llvm.xor %arg35, %1 : i4
  %4 = llvm.and %3, %2 : i4
  %5 = llvm.xor %4, %arg35 : i4
  "llvm.return"(%5) : (i4) -> ()
}
]

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

def shl1_nsw_after := [llvm|
{
^0(%arg14 : i8, %arg15 : i8):
  %0 = llvm.ashr exact %arg14, %arg15 : i8
  "llvm.return"(%0) : (i8) -> ()
}
]

def OrZextZext : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := [LV| {
    ^entry (%x: i32, %y: i32):
      %0 = llvm.zext %x : i32 to i64
      %1 = llvm.zext %y : i32 to i64
      %2 = llvm.or %0, %1 : i64
      llvm.return %2 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i32, %y: i32):
      %0 = llvm.or %x, %y : i32
      %1 = llvm.zext %0 : i32 to i64
      llvm.return %1 : i64
  }]

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

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

def t2_ult_sgt_65536_before := [llvm|
{
^0(%arg60 : i32, %arg61 : i32, %arg62 : i32):
  %0 = llvm.mlir.constant(65535 : i32) : i32
  %1 = llvm.mlir.constant(65536 : i32) : i32
  %2 = llvm.icmp "sgt" %arg60, %0 : i32
  %3 = "llvm.select"(%2, %arg62, %arg61) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.icmp "ult" %arg60, %1 : i32
  %5 = "llvm.select"(%4, %arg60, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def body : BasicBlock Op T → Body Op T
  | ⟨_, _, body⟩ => body

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

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

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

def testi64i32_after := [llvm|
{
^0(%arg8 : i64):
  %0 = llvm.mlir.constant(2147483648) : i64
  %1 = llvm.mlir.constant(4294967296) : i64
  %2 = llvm.add %arg8, %0 : i64
  %3 = llvm.icmp "ult" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

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

@[simp_denote]
def srl_riscv_i16 :=
  [LV| {
    ^entry (%arg0: i16, %arg1: i16):
    %a0 = "builtin.unrealized_conversion_cast" (%arg0) : (i16) -> (!i64)
    %a1 = "builtin.unrealized_conversion_cast" (%arg1) : (i16) -> (!i64)
    %0 = slli %a0, 48 : !i64
    %1 = srli %0, 48 : !i64
    %2 = srl %1, %a1 : !i64
    %3 = "builtin.unrealized_conversion_cast" (%2) : (!i64) -> (i16)
    llvm.return %3 :i16
  }]

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

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

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

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

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

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

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 no_shift_xor_multiuse_cmp_with_and_after := [llvm|
{
^0(%arg88 : i32, %arg89 : i32, %arg90 : i32, %arg91 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(-4097 : i32) : i32
  %3 = llvm.and %arg88, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.and %arg89, %2 : i32
  %6 = "llvm.select"(%4, %5, %arg89) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg91, %arg90) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %8 = llvm.mul %6, %7 : i32
  "llvm.return"(%8) : (i32) -> ()
}
]

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

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

def Term.numVars (t : Term) : Nat := t.f.numVars

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

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

def trueOnlyAt (n : Nat) : FSM (Fin 0) := ofNat (1 <<< n)

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

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

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

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 select_replace_nested_no_simplify_after := [llvm|
{
^0(%arg23 : i32, %arg24 : i32, %arg25 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.icmp "eq" %arg23, %0 : i32
  %3 = llvm.add %arg24, %1 : i32
  %4 = llvm.add %3, %arg25 : i32
  %5 = "llvm.select"(%2, %4, %arg24) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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 t0_after := [llvm|
{
^0(%arg18 : i32, %arg19 : i16):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.ashr %arg18, %0 : i32
  %2 = llvm.trunc %1 overflow<nsw> : i32 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

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

@[simp_denote]
def  add_negative_low_bound_accept_riscv := [LV| {
  ^entry (%arg: i32):
  %0 =  "builtin.unrealized_conversion_cast" (%arg) : (i32) -> (!i64)
  %1 = "addi"  (%0) {imm = -2048 : !i64} : (!i64) -> (!i64)
  %2 = "addiw"  (%1) {imm = -2048 : !i64} : (!i64) -> (!i64)
  %3 =  "builtin.unrealized_conversion_cast" (%2) : (!i64) -> (i32)
  llvm.return %3 : i32
}]

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

def t4_ugt_slt_128_after := [llvm|
{
^0(%arg66 : i32, %arg67 : i32, %arg68 : i32):
  %0 = llvm.mlir.constant(-16 : i32) : i32
  %1 = llvm.mlir.constant(127 : i32) : i32
  %2 = llvm.icmp "slt" %arg66, %0 : i32
  %3 = llvm.icmp "sgt" %arg66, %1 : i32
  %4 = "llvm.select"(%2, %arg67, %arg66) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %5 = "llvm.select"(%3, %arg68, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

def not_cmp_fold : List (Σ Γ, LLVMPeepholeRewriteRefine 1 Γ) :=
  [⟨_, not_cmp_fold_eq⟩,
  ⟨_, not_cmp_fold_ne⟩,
  ⟨_, not_cmp_fold_ge⟩,
  ⟨_, not_cmp_fold_ugt⟩,
  ⟨_, not_cmp_fold_uge⟩,
  ⟨_, not_cmp_fold_sgt⟩,
  ⟨_, not_cmp_fold_sge⟩,
  ⟨_, not_cmp_fold_sge⟩]

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

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

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

def PackedFloat.toBV (pf : PackedFloat e M) : BitVec (1 + e + M) :=
  let bvSign := BitVec.ofBool pf.sign
  bvSign ++ pf.ex ++ pf.sig

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

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

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

@[simp_riscv]
def snez_pseudo (rs1_val : BitVec 64) : BitVec 64 :=
  RV64.sltu rs1_val 0

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

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

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

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

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

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

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

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

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

def andn_or_cmp_2_partial_logical_before := [llvm|
{
^0(%arg117 : i16, %arg118 : i16, %arg119 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.icmp "sge" %arg117, %arg118 : i16
  %2 = llvm.icmp "slt" %arg117, %arg118 : i16
  %3 = llvm.or %1, %arg119 : i1
  %4 = "llvm.select"(%3, %2, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

def xor_or_after := [llvm|
{
^0(%arg137 : i1, %arg138 : i32, %arg139 : i32):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "uge" %arg138, %arg139 : i32
  %3 = llvm.xor %arg137, %0 : i1
  %4 = "llvm.select"(%3, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def icmp_ne_and_pow2_minus1_shl1_before := [llvm|
{
^0(%arg56 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(15 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.shl %0, %arg56 : 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 ashrslt_01_09_exact_before := [llvm|
{
^0(%arg44 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(-7 : i4) : i4
  %2 = llvm.ashr exact %arg44, %0 : i4
  %3 = llvm.icmp "slt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

modify in Init.Prelude

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

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

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

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

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

def worklist.initState (inits : Array S) (hinits : inits.toList.Nodup) (final? : S → Bool) : worklist.St A S :=
  let m := RawCNFA.empty (A := A)
  let mapm := inits.foldl (init := (Std.HashMap.emptyWithCapacity, m)) fun (map, m) sa =>
    let (s, m) := m.newState
    let m := m.addInitial s
    let m := if final? sa then m.addFinal s else m
    (map.insert sa s, m)
  let map := mapm.1
  let m := mapm.2
  let worklist_incl : ∀ sa ∈ inits, sa ∈ map :=

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

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

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

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

def llvm_const_lower_riscv_li_45 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_45, rhs:= liRiscv_45,
   correct := by admit /- proof elided -/

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

def not_signbit_splat_mask1_after := [llvm|
{
^0(%arg109 : i8, %arg110 : i16):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.ashr %arg109, %0 : i8
  %2 = llvm.zext %1 : i8 to i16
  %3 = llvm.and %arg110, %2 : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

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

def urem_constant_dividend_select_of_constants_divisor_0_arm_after := [llvm|
{
^0(%arg23 : i1):
  %0 = llvm.mlir.constant(6 : i32) : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

abbrev falseIffLe (n : Nat) : BitStream := fun i => decide (i > n)

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

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

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

instance :  HydrableSynthesizeWithNoPrecondition ParsedBVExpr GenBVPred GenBVExpr where
 synthesizeWithNoPrecondition := synthesizeWithNoPrecondition

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

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

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

inductive Op (q : Nat) (n : Nat)
  | add : Op q n
  | sub : Op q n
  | mul : Op q n
  | mul_constant : Op q n
    
    
  | leading_term : Op q n
  | monomial : Op q n
  | monomial_mul : Op q n
  | from_tensor : Op q n
  | to_tensor : Op q n
  | const (c : R q n) : Op q n
  | const_int (c : Int) : Op q n
  | const_idx (i : Nat) : Op q n

def RawCNFA.reverse (m : RawCNFA A) : RawCNFA A :=
  let m' := { stateMax := m.stateMax, trans := Std.HashMap.emptyWithCapacity m.trans.size, initials := m.finals, finals := m.initials}
  m.trans.fold (init := m') processState
where
  processState := fun m' (s, a) ss' =>
    ss'.fold (init := m') fun m' s' => m'.addTrans a s' s

def canonicalize_logic_first_xor_0_nsw_before := [llvm|
{
^0(%arg16 : i8):
  %0 = llvm.mlir.constant(96 : i8) : i8
  %1 = llvm.mlir.constant(31 : i8) : i8
  %2 = llvm.add %arg16, %0 overflow<nsw> : i8
  %3 = llvm.xor %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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

instance  [Inhabited ι] : Inhabited (Vars σ ι (n + 1)) where
  default := .inputs (Inputs.latest default)

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

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

def sext_xor_sub_2_before := [llvm|
{
^0(%arg24 : i64, %arg25 : i1):
  %0 = llvm.sext %arg25 : i1 to i64
  %1 = llvm.xor %arg24, %0 : i64
  %2 = llvm.sub %0, %1 : i64
  "llvm.return"(%2) : (i64) -> ()
}
]

def genBvPredToSmtLib
    (litPred : GenBVPred) (vars : Std.HashMap Nat HydraVariable) (widthVals : Std.HashMap Nat HydraVariable) : SexprPBV.Predicate :=
  match litPred with
  | .bin (w := w) lhs op rhs =>
      match op with
      | .eq => SexprPBV.Predicate.binRel .eq (.const w)
                (GenBVExpr.toSmtLib lhs vars widthVals)
                (GenBVExpr.toSmtLib rhs vars widthVals)
      | .ult => SexprPBV.Predicate.binRel .ult (.const w)
                (GenBVExpr.toSmtLib lhs vars widthVals)
                (GenBVExpr.toSmtLib rhs vars widthVals)
  | _ => SexprPBV.Predicate.junk litPred.toString

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

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

def narrow_zext_xor_before := [llvm|
{
^0(%arg46 : i16, %arg47 : i32):
  %0 = llvm.zext %arg46 : i16 to i32
  %1 = llvm.xor %0, %arg47 : i32
  %2 = llvm.trunc %1 : i32 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

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

def instantiate (as : List.Vector α φ) : ConcreteOrMVar α φ → α
  | .concrete w => w
  | .mvar i => as.get i

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

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

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

Matrix in Mathlib.LinearAlgebra.Matrix.Defs

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

def p_commutative0_before := [llvm|
{
^0(%arg32 : i32, %arg33 : i32, %arg34 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg34, %arg32 : i32
  %2 = llvm.xor %arg34, %0 : i32
  %3 = llvm.and %2, %arg33 : i32
  %4 = llvm.or %1, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def source : Expr (DC) Γ .pure (.tokenstream) :=
  Expr.mk
    (op := .source)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .nil)
    (regArgs := .nil)

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

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

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

instance : DecidableRel (LE.le (α := EffectKind)) := decLe

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

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

def unaryOne {o : Nat} : BitVec o := 1

instance : DecidableEq BlockLabel :=

instance DecideFixedWidthPredicateEvalFin  (p : Predicate) (n : ℕ) :
    Decidable (∀ (x : Fin p.arity → BitStream) , p.evalFin x n = false) :=
  decidable_of_iff
    (decideIfZerosAtIx (predicateEvalEqFSM p).toFSM n) $ by
  rw [decideIfZeroesAtIx_correct, ← (predicateEvalEqFSM p).good]

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

structure Signature (Ty : Type) where
  mkEffectful ::
  sig         : List Ty
  regSig      : RegionSignature Ty
  returnTypes : List Ty
  effectKind  : EffectKind := .pure

def getBoolValue? (e : Expr) : Option Bool :=
  match_expr e with
  | Bool.true => some true
  | Bool.false => some false
  | _ => none

def mkExpr (Γ : Ctxt _) (opStx : MLIR.AST.Op 0) :
    MLIR.AST.ReaderM (DC) (Σ eff ty, Expr (DC) Γ eff ty) := do
  match opStx.name with
  | op@"DC.source" =>
    if opStx.args.length > 0 then
      throw <| .generic s!"expected one operand for `monomial`, found #'{opStx.args.length}' in '{repr opStx.args}'"
    else
      return ⟨_, [.tokenstream], source⟩
  | op@"DC.sink" | op@"DC.unpack" | op@"DC.fork" | op@"DC.branch" | op@"DC.fst" | op@"DC.snd" | op@"DC.fstVal" | op@"DC.sndVal" =>
    match opStx.args with
    | v₁Stx::[] =>
      let ⟨ty₁, v₁⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₁Stx
      match ty₁, op with
      | .tokenstream2, "DC.fst" => return ⟨_, [.tokenstream], fst v₁⟩
      | .tokenstream2, "DC.snd"  => return ⟨_, [.tokenstream], snd v₁⟩
      | .valuetokenstream r, "DC.fstVal" => return ⟨_, [.valuestream r], fstVal v₁⟩
      | .valuetokenstream _, "DC.sndVal"  => return ⟨_, [.tokenstream], sndVal v₁⟩
      | .tokenstream, "DC.sink" => return ⟨_, [.tokenstream], sink v₁⟩
      | .valuestream r, "DC.unpack"  => return ⟨_, [.valuetokenstream r], unpack v₁⟩
      | .tokenstream, "DC.fork"  => return ⟨_, [.tokenstream2], fork v₁⟩
      | .valuestream 1, "DC.branch"  => return ⟨_, [.tokenstream2], branch v₁⟩
      | _, _ => throw <| .generic s!"type mismatch"
    | _ => throw <| .generic s!"expected one operand for `monomial`, found #'{opStx.args.length}' in '{repr opStx.args}'"
  | op@"DC.merge" | op@"DC.join" | op@"DC.pack" | op@"DC.pair" =>
    match opStx.args with
    | v₁Stx::v₂Stx::[] =>
      let ⟨ty₁, v₁⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₁Stx
      let ⟨ty₂, v₂⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₂Stx
      match ty₁, ty₂, op with
      | .tokenstream, .tokenstream, "DC.merge" => return ⟨_, [.valuestream 1], merge v₁ v₂⟩
      | .tokenstream, .tokenstream, "DC.join"  => return ⟨_, [.tokenstream], join v₁ v₂⟩
      | .valuestream r, .tokenstream, "DC.pack"  => return ⟨_, [.valuestream r], pack v₁ v₂⟩
      | .valuestream r₁, .valuestream r₂, "DC.pair"  =>
        if h : r₁ = r₂ then
          let v₂' : Γ.Var (Ty.valuestream r₁) := Eq.mp (by admit /- proof elided -/
          ) v₂
          return ⟨_, [.valuestream2 r₁], pair v₁ v₂'⟩
        else throw <| .generic s!"type mismatch, expected same width for pair, got {r₁} and {r₂}"
      | _, _, _ => throw <| .generic s!"type mismatch"
    | _ => throw <| .generic s!"expected two operands for `monomial`, found #'{opStx.args.length}' in '{repr opStx.args}'"
  | op@"DC.select" =>
    match opStx.args with
    | v₁Stx::v₂Stx::v₃Stx::[] =>
      let ⟨ty₁, v₁⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₁Stx
      let ⟨ty₂, v₂⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₂Stx
      let ⟨ty₃, v₃⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₃Stx
      match ty₁, ty₂, ty₃, op with
      | .tokenstream, .tokenstream, .valuestream 1, "DC.select" => return ⟨_, [.tokenstream], select v₁ v₂ v₃⟩
      | _, _, _, _=> throw <| .generic s!"type mismatch"
    | _ => throw <| .generic s!"expected three operands for `monomial`, found #'{opStx.args.length}' in '{repr opStx.args}'"
  | _ => throw <| .unsupportedOp s!"unsupported operation {repr opStx}"

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

inductive NFA.unsignedCmpState : Type where
| eq | gt | lt
deriving Fintype, DecidableEq

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

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

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

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

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

def t10_shl_nuw_flag_preservation_after := [llvm|
{
^0(%arg23 : i32, %arg24 : i32):
  %0 = llvm.mlir.constant(30 : i32) : i32
  %1 = llvm.shl %arg23, %0 overflow<nuw> : i32
  "llvm.return"(%1) : (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 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 alive_InstCombineShift__476_tgt  (w : Nat)  :=
[llvm( w )| {
^bb0(%Y : _, %X : _, %C : _, %C2 : _):
  %v1 = llvm.shl %Y, %C
  %v2 = llvm.shl %C2, %C
  %v3 = llvm.and %X, %v2
  %v4 = llvm.lshr %X, %C
  %v5 = llvm.and %v4, %C2
  %v6 = llvm.or %v5, %Y
  %v7 = llvm.or %v3, %v1
  llvm.return %v7
}]

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

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

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

def mul_of_pow2_commute_before := [llvm|
{
^0(%arg81 : i32, %arg82 : i32):
  %0 = llvm.mlir.constant(4 : i32) : i32
  %1 = llvm.mlir.constant(255 : i32) : i32
  %2 = llvm.mlir.constant(1020 : i32) : i32
  %3 = llvm.and %arg81, %0 : i32
  %4 = llvm.and %arg82, %1 : i32
  %5 = llvm.mul %4, %3 : i32
  %6 = llvm.icmp "ugt" %5, %2 : i32
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

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

def test11_after := [llvm|
{
^0(%arg30 : i23):
  %0 = llvm.mlir.constant(6 : i23) : i23
  %1 = llvm.mlir.constant(-4096 : i23) : i23
  %2 = llvm.mul %arg30, %0 : i23
  %3 = llvm.and %2, %1 : i23
  "llvm.return"(%3) : (i23) -> ()
}
]

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

instance : ToString LLVM.Ty :=

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

def test_shift_and_cmp_changed1_before := [llvm|
{
^0(%arg6 : i8, %arg7 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.mlir.constant(8 : i8) : i8
  %2 = llvm.mlir.constant(5 : i8) : i8
  %3 = llvm.mlir.constant(1 : i8) : i8
  %4 = llvm.and %arg6, %0 : i8
  %5 = llvm.and %arg7, %1 : i8
  %6 = llvm.or %5, %4 : i8
  %7 = llvm.shl %6, %2 : i8
  %8 = llvm.ashr %7, %2 : i8
  %9 = llvm.icmp "slt" %8, %3 : i8
  "llvm.return"(%9) : (i1) -> ()
}
]

Lean.ToJson in Lean.Data.Json.FromToJson.Basic

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

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

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

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

def test57_after := [llvm|
{
^0(%arg126 : i64):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.trunc %arg126 : i64 to i32
  %2 = llvm.lshr %1, %0 : i32
  %3 = llvm.zext nneg %2 : i32 to i64
  "llvm.return"(%3) : (i64) -> ()
}
]

Lean.mkNatLit in Lean.Expr

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

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

def mkN (fsm : FSM arity) (n : Nat) : KInductionCircuits fsm n :=
  match n with
  | 0 => mkZero
  | n + 1 => mkSucc (mkN fsm n)

def argNames : List SSAVal :=
  op.args.map Prod.fst

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

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

def sext_diff_i1_xor_sub_after := [llvm|
{
^0(%arg15 : i64, %arg16 : i1, %arg17 : i1):
  %0 = llvm.sext %arg16 : i1 to i64
  %1 = llvm.zext %arg17 : i1 to i64
  %2 = llvm.add %1, %0 overflow<nsw> : i64
  "llvm.return"(%2) : (i64) -> ()
}
]

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

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

def Term.NatEnv.empty : Term.NatEnv 0 :=
  fun x => x.elim0

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

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

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

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

def orn_and_cmp_1_logical_before := [llvm|
{
^0(%arg17 : i37, %arg18 : i37, %arg19 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "sgt" %arg17, %arg18 : i37
  %3 = llvm.icmp "sle" %arg17, %arg18 : i37
  %4 = "llvm.select"(%arg19, %2, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %5 = "llvm.select"(%3, %1, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

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

def sext_sext_add_before := [llvm|
{
^0(%arg42 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.ashr %arg42, %0 : i32
  %3 = llvm.ashr %arg42, %1 : i32
  %4 = llvm.sext %2 : i32 to i64
  %5 = llvm.sext %3 : i32 to i64
  %6 = llvm.add %4, %5 : i64
  "llvm.return"(%6) : (i64) -> ()
}
]

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

@[simp] abbrev Hom.id {Γ : Ctxt Ty} : Γ.Hom Γ :=
  fun _ v => v

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

def icmp_shl_nsw_sge0_before := [llvm|
{
^0(%arg29 : i32):
  %0 = llvm.mlir.constant(21 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %arg29, %0 overflow<nsw> : i32
  %3 = llvm.icmp "sge" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

getThe in Init.Prelude

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

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 ne_shift_in_zeros_after := [llvm|
{
^0(%arg32 : i32, %arg33 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.xor %arg32, %arg33 : i32
  %2 = llvm.icmp "ugt" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def simplify_or_common_op_commute0_after := [llvm|
{
^0(%arg45 : i4, %arg46 : i4, %arg47 : i4):
  %0 = llvm.mlir.constant(-1 : i4) : i4
  "llvm.return"(%0) : (i4) -> ()
}
]

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

private def mkElab (ext : NameExt) (ty : Lean.Expr) : Elab.Term.TermElabM Lean.Expr := do
  let mut stx := #[]
  for (_, n4) in ext.getState (← getEnv) do
    stx := stx.push $ ← `($(mkIdent n4):ident)
  let listStx := (← `([$stx,*]))
  let list ← `($listStx)
  Elab.Term.elabTerm list (some ty)

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

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

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

def ConcreteCliTest.inputToString (test : ConcreteCliTest) : Nat → Array (Option ℤ) → String
  | i, arr =>
    let tys : List (InstCombine.MTy 0) := test.context.reverse 
    match tys[i]? with
    | .none => "<none>"
    | .some (.bitvec (.concrete w)) =>
        BitVec.inputToString <| Option.map (BitVec.ofInt w) arr[i]!

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

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

def CollectState.icard (state : CollectState) : Nat :=
  state.iToIx.size

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

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

def alive_AddSub_1176_src  (w : Nat)   :=
[llvm( w )| {
^bb0(%a : _, %b : _):
  %v1 = llvm.mlir.constant 0
  %v2 = llvm.sub %v1, %b
  %v3 = llvm.add %a, %v2
  llvm.return %v3
}]

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

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

def BranchEg1 := [handshake_com| {
  ^entry(%0: !Stream_BitVec_1, %1: !Stream_BitVec_1):
    %out = "handshake.branch" (%0, %1) : (!Stream_BitVec_1, !Stream_BitVec_1) -> (!Stream2_BitVec_1)
    %outf = "handshake.fst" (%out) : (!Stream2_BitVec_1) -> (!Stream_BitVec_1)
    %outs = "handshake.snd" (%out) : (!Stream2_BitVec_1) -> (!Stream_BitVec_1)
    %out2 = "handshake.merge" (%outs, %outf) : (!Stream_BitVec_1, !Stream_BitVec_1) -> (!Stream_BitVec_1)
    "return" (%out2) : (!Stream_BitVec_1) -> ()
  }]

def llvm_const_lower_riscv_li36 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM36, rhs:= liRiscv36,
   correct := by admit /- proof elided -/

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

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

def alive_InstCombineShift__440_tgt  (w : Nat)  :=
[llvm( w )| {
^bb0(%Y : _, %X : _, %C : _, %C2 : _):
  %v1 = llvm.shl %C2, %C
  %v2 = llvm.and %X, %v1
  %v3 = llvm.shl %Y, %C
  %v4 = llvm.lshr %X, %C
  %v5 = llvm.and %v4, %C2
  %v6 = llvm.xor %Y, %v5
  %v7 = llvm.xor %v2, %v3
  llvm.return %v7
}]

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

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

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

def test17_after := [llvm|
{
^0(%arg36 : i32, %arg37 : i32):
  %0 = llvm.mlir.constant(1431655765 : i32) : i32
  %1 = llvm.or %arg36, %0 : i32
  %2 = llvm.sub %arg37, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def Sexpr.atomOf {α : Type} [ToFormat α] (x : α) : Sexpr :=
  Sexpr.atom (format x)

def sext_negate_after := [llvm|
{
^0(%arg29 : i1):
  %0 = llvm.zext %arg29 : i1 to i64
  "llvm.return"(%0) : (i64) -> ()
}
]

def elabIntoCom (region : TSyntax `mlir_region) (d : Q(Dialect)) {φ : Q(Nat)}
    (_dialectSignature : Q(DialectSignature $d) := by admit /- proof elided -/
    )
    (_transformTy      : Q(TransformTy $d $φ)     := by admit /- proof elided -/
    )
    (_transformExpr    : Q(TransformExpr $d $φ)   := by admit /- proof elided -/
    )
    (_transformReturn  : Q(TransformReturn $d $φ) := by admit /- proof elided -/
    ) :
    TermElabM Expr := do
  let com : Q(ExceptM $d (Σ Γ' eff ty, Com $d Γ' eff ty)) ←
    withTraceNode `LeanMLIR.Elab (return m!"{exceptEmoji ·} building `Com` expression") <| do
    let ast_stx ← `([mlir_region| $region])
    let ast ← elabTermEnsuringTypeQ ast_stx q(Region $φ)
    return q(MLIR.AST.mkCom $ast)
  withTraceNode `LeanMLIR.Elab (return m!"{exceptEmoji ·} synthesizingMVars") <|
    synthesizeSyntheticMVarsNoPostponing

  withTraceNode `LeanMLIR.Elab (return m!"{exceptEmoji ·} unwrapping `Com` expression") <| do
     
    let com : Q(ExceptM $d (Σ Γ' eff ty, Com $d Γ' eff ty)) ← whnf com
    match com.app3? ``Except.ok with
    | .some (_εexpr, _αexpr, expr) =>
        let (expr : Q(Σ Γ eff ty, Com $d Γ eff ty)) ← whnf expr
        match expr.app4? ``Sigma.mk with
        | .some (_αexpr, _βexpr, (_Γ : Q(Ctxt ($d).Ty)), expr) =>
          let (expr : Q(Σ eff ty, Com $d $_Γ eff ty)) ← whnf expr
          match expr.app4? ``Sigma.mk with
          | .some (_αexpr, _βexpr, (_eff : Q(EffectKind)), expr) =>
            match expr.app4? ``Sigma.mk with
            | .some (_αexpr, _βexpr, (_ty : Q(List ($d).Ty)), (com : Q(Com $d $_Γ $_eff $_ty))) =>
                 
                withTraceNode `LeanMLIR.Elab (return m!"{exceptEmoji ·} reducing `Com` expression") <|
                  comNf com
            | .none => throwError "Expected (Sigma.mk _ _), found {expr}"
          | .none => throwError "Expected (Sigma.mk _ _), found {expr}"
        | .none => throwError "Expected (Sigma.mk _ _), found {expr}"
    | .none => throwError "Expected `Except.ok`, found {com}"

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

def test4_apint_after := [llvm|
{
^0(%arg42 : i61):
  %0 = llvm.mlir.constant(5 : i61) : i61
  %1 = llvm.and %arg42, %0 : i61
  %2 = llvm.xor %1, %0 : i61
  "llvm.return"(%2) : (i61) -> ()
}
]

def ashr_x_by_const_cmp_sge_x_before := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.ashr %arg6, %0 : i32
  %2 = llvm.icmp "sge" %1, %arg6 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

def addsub_combine_constants_after := [llvm|
{
^0(%arg14 : i7, %arg15 : i7):
  %0 = llvm.mlir.constant(52 : i7) : i7
  %1 = llvm.sub %arg14, %arg15 : i7
  %2 = llvm.add %1, %0 : i7
  "llvm.return"(%2) : (i7) -> ()
}
]

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

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

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

def negative2_before := [llvm|
{
^0(%arg16 : i32, %arg17 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "slt" %arg16, %arg17 : i32
  %2 = llvm.icmp "sge" %arg16, %0 : i32
  %3 = llvm.and %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

structure _root_.SetRel.set_eq (R : SetRel α β) (A : Set α) (B : Set β) where
  fwd : a ∈ A → ∃ b ∈ B, a ~[R] b
  bwd : b ∈ B → ∃ a ∈ A, a ~[R] b

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

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

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

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

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

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

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

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

Option in Init.Prelude

def add_shl_moreOneUse_sh2add_ZBA_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := add_shl_moreOneUse_sh2add
  rhs := add_shl_moreOneUse_sh2add_riscv_ZBA

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

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

def demorgan_nor_use2ac_before := [llvm|
{
^0(%arg22 : i8, %arg23 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(17 : i8) : i8
  %2 = llvm.mlir.constant(23 : i8) : i8
  %3 = llvm.xor %arg22, %0 : i8
  %4 = llvm.mul %3, %1 : i8
  %5 = llvm.or %3, %arg23 : i8
  %6 = llvm.mul %5, %2 : i8
  %7 = llvm.xor %5, %0 : i8
  %8 = llvm.sdiv %7, %6 : i8
  %9 = llvm.sdiv %8, %4 : i8
  "llvm.return"(%9) : (i8) -> ()
}
]

Lean.Parser.sepBy in Lean.Parser.Basic

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

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

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

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

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

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

def test24_before := [llvm|
{
^0(%arg171 : i1):
  %0 = llvm.mlir.constant(14 : i32) : i32
  %1 = llvm.mlir.constant(1234 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = "llvm.select"(%arg171, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.icmp "ne" %3, %2 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]
</all_available_defs>

<all_available_lemmas>
BitVec.msb_eq_getLsbD_last in Init.Data.BitVec.Lemmas
BitVec.getElem_signExtend in Init.Data.BitVec.Lemmas
BitVec.of_length_zero in Init.Data.BitVec.Lemmas
BitVec.sle_eq_carry in Init.Data.BitVec.Bitblast

protected theorem carry'_eq_carry (x y : BitStream) (c : Bool)
    (x' y' : BitVec w)
    (hx : ∀ i, i < n → x'.getLsbD i = x i)
    (hy : ∀ i,  i < n → y'.getLsbD i = y i) :
    carry' c x y n = (BitVec.carry n x' y' c)

@[simp] theorem carry'_succ (initCarry : Bool) (x y : BitStream) :
    (carry' initCarry x y (i + 1)) =
    let out

theorem icmp_slt_0_and_icmp_sge_neg1_i64_thm (e : IntW 64) :
  LLVM.and (lshr e (const? 64 63)) (zext 64 (icmp IntPred.sge e (const? 64 (-1)))) ⊑
    zext 64 (icmp IntPred.eq e (const? 64 (-1)))

theorem icmp_ne_sext_sgt_zero_nofold_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (0#32 <ₛ x)) != x) = ofBool (x != signExtend 32 (ofBool (0#32 <ₛ x)))

theorem e_313 :
     - 1 * (x |||  ~~~y) + 7 * y + 7 *  ~~~y - 5 *  ~~~(x ||| y) - 6 *  ~~~(x |||  ~~~y) - 5 * (x &&&  ~~~y) - 6 * (x &&& y) = 1 *  ~~~(x &&& y)

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

theorem n10_ashr_lshr_proof : n10_ashr_lshr_before ⊑ n10_ashr_lshr_after

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

theorem e_75 :
    1 *  ~~~(x &&&  ~~~y) + 1 * x - 12 *  ~~~(x ||| y) - 1 *  ~~~(x |||  ~~~y) - 2 * (x &&& y) =  - 11 *  ~~~y + 12 * (x &&&  ~~~y)

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

theorem foo_thm (e : IntW 1) : e ⊑ e

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

theorem positive_biggerShl_shlnuw_proof : positive_biggerShl_shlnuw_before ⊑ positive_biggerShl_shlnuw_after

theorem or_not_xor_common_op_commute3_proof : or_not_xor_common_op_commute3_before ⊑ or_not_xor_common_op_commute3_after

theorem lshr_32_add_not_known_32_leading_zeroes_proof : lshr_32_add_not_known_32_leading_zeroes_before ⊑ lshr_32_add_not_known_32_leading_zeroes_after

theorem ofDep_xvar_eq_xvar' : MultiWidth.Nondep.Term.ofDepTerm xvar = xvar'

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

@[simp]
theorem not_bne' {a b : Bool} : (!bne a b) = (a == b)

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

theorem src_is_mask_select_proof : src_is_mask_select_before ⊑ src_is_mask_select_after

theorem test_negative_nuw_and_signed_pred_thm (e : IntW 64) :
  icmp IntPred.slt (sub (const? 64 10) e { «nsw» := false, «nuw» := true }) (const? 64 3) ⊑
    icmp IntPred.ugt e (const? 64 7)

theorem fold_nested_logic_zext_icmp_thm.extracted_1._1 : ∀ (x x_1 x_2 x_3 : BitVec 64),
  zeroExtend 8 (ofBool (x_2 <ₛ x_3)) &&& zeroExtend 8 (ofBool (x_3 <ₛ x_1)) ||

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

theorem masked_or_A_slightly_optimized_logical_proof : masked_or_A_slightly_optimized_logical_before ⊑ masked_or_A_slightly_optimized_logical_after

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

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

theorem test19_thm.extracted_1._1 : ∀ (x : BitVec 10),
  ¬(2#3 ≥ ↑3 ∨ 2#3 ≥ ↑3) → True ∧ (0#3).ssubOverflow (truncate 3 x &&& 1#3) = true → False

theorem bitwise_and_logical_and_masked_icmp_allones_proof : bitwise_and_logical_and_masked_icmp_allones_before ⊑ bitwise_and_logical_and_masked_icmp_allones_after

theorem logical_or_implies_folds_proof : logical_or_implies_folds_before ⊑ logical_or_implies_folds_after

theorem test20_proof : test20_before ⊑ test20_after

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

theorem xor_icmp_invalid_range_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x == 0#8) ^^^ ofBool (x != 4#8) = ofBool (x &&& BitVec.ofInt 8 (-5) != 0#8)

theorem p_constmask2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  True ∧ (x_1 &&& 61440#32 &&& (x &&& BitVec.ofInt 32 (-65281)) != 0) = true → False

theorem t0_thm (e : IntW 8) (e_1 : IntW 1) :
  LLVM.xor (add (sext 8 e_1) e) (sext 8 e_1) ⊑ select e_1 (sub (const? 8 0) e) e

theorem test8_proof : test8_before ⊑ test8_after

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

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

theorem ashr_ule_exact_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x >>> 3#8 <<< 3#8 ≠ x ∨ 3#8 ≥ ↑8) → ofBool (x.sshiftRight' 3#8 ≤ᵤ 10#8) = ofBool (x <ᵤ 88#8)

theorem main6b_proof : main6b_before ⊑ main6b_after

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

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

theorem test15h_proof : test15h_before ⊑ test15h_after

theorem icmp_select_implied_cond_relational_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ofBool (10#8 <ᵤ x_1) = 1#1 → ofBool (10#8 <ᵤ x_1) = 1#1

theorem substitute_constant_and_eq_ugt_swap_proof : substitute_constant_and_eq_ugt_swap_before ⊑ substitute_constant_and_eq_ugt_swap_after

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

theorem lshrugt_01_15_exact_proof : lshrugt_01_15_exact_before ⊑ lshrugt_01_15_exact_after

theorem shl_nsw_add_nsw_nuw_thm (e : IntW 32) :
  add (shl (const? 32 1) e { «nsw» := true, «nuw» := false }) (const? 32 (-1)) { «nsw» := true, «nuw» := true } ⊑
    const? 32 (-1)

theorem p_commutative2_proof : p_commutative2_before ⊑ p_commutative2_after

theorem udiv_i1_is_op0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1), ¬x = 0 → x_1 / x = x_1

theorem add_2_proof : add_2_before ⊑ add_2_after

theorem lshr_lshr_pow2_const_negative_overflow_proof : lshr_lshr_pow2_const_negative_overflow_before ⊑ lshr_lshr_pow2_const_negative_overflow_after

theorem shl_or_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ x + 1#8 ≥ ↑8) → ¬x ≥ ↑8 → 16#8 <<< x ||

theorem test3_proof : test3_before ⊑ test3_after

theorem test13_proof : test13_before ⊑ test13_after

theorem lshr_or_or_fail_thm (e e_1 : IntW 8) :
  LLVM.or (lshr e_1 (const? 8 5)) (LLVM.or (lshr e (const? 8 5)) (const? 8 (-58))) ⊑
    LLVM.or (lshr (LLVM.or e e_1) (const? 8 5)) (const? 8 (-58))

theorem ashr_ugt_8_proof : ashr_ugt_8_before ⊑ ashr_ugt_8_after

theorem test34_thm (e : IntW 16) : trunc 16 (lshr (zext 32 e) (const? 32 8)) ⊑ lshr e (const? 16 8)

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

theorem select_icmp_ne_0_and_32_xor_4096_thm (e e_1 : IntW 32) :
  select (icmp IntPred.ne (const? 32 0) (LLVM.and e_1 (const? 32 32))) e (LLVM.xor e (const? 32 4096)) ⊑
    LLVM.xor (LLVM.xor (LLVM.and (shl e_1 (const? 32 7)) (const? 32 4096)) e) (const? 32 4096)

theorem logical_and_not_cond_reuse_proof : logical_and_not_cond_reuse_before ⊑ logical_and_not_cond_reuse_after

theorem t5_thm.extracted_1._7 : ∀ (x x_1 : BitVec 1) (x_2 : BitVec 32),
  x_1 = 1#1 → ¬x = 1#1 → ¬64#32 = 0 → ¬6#32 ≥ ↑32 → x_2 / 64#32 = x_2 >>> 6#32

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

theorem e_2271 :
    3 *  ~~~(d ||| ( ~~~e &&& f)) - 1 * ((d ^^^ e) &&& (d ^^^ f)) - 2 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 6 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 1 * (f ^^^ (d &&& e)) - 11 *  ~~~(d ||| e) - 6 * (e ||| (d &&&  ~~~f)) + 7 * (d ^^^ e) + 1 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 7 * (f ^^^ (d ||| (e ||| f))) - 5 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 2 * ( ~~~d ||| (e &&& f)) + 1 * (e ^^^ (d ||| ( ~~~e &&& f))) - 2 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 4 * (f ^^^ (d ||| (e &&& f))) + 5 * (d &&& (e ^^^ f)) - 3 *  ~~~( ~~~d ||| (e &&& f)) - 1 * (e ^^^  ~~~(d ||| f)) - 2 * ((e &&& f) ||| (d &&& (e ||| f))) + 4 * ((d &&& e) ||| (e ^^^ f)) - 5 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 * (f ^^^  ~~~(d &&& (e ||| f))) - 11 *  ~~~(d &&&  ~~~d) + 11 * (f ^^^ (d &&&  ~~~e)) - 1 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 7 * (d ||| (e ||| f)) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 1 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 2 * ( ~~~e ||| (d ^^^ f)) + 2 * (e ^^^ (d ||| f)) - 2 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 1 * (e |||  ~~~f) + 7 *  ~~~( ~~~d ||| (e ^^^ f)) - 6 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 5 * ((d &&& e) ^^^ (e ||| f)) - 7 * (e |||  ~~~(d ^^^ f)) - 3 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 1 * ((d ^^^ e) ||| (d ^^^ f)) + 1 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 7 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) + 1 *  ~~~(d |||  ~~~f) + 5 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 5 * (e &&& f) - 1 *  ~~~( ~~~d &&& (e ^^^ f)) - 6 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 7 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 1 *  ~~~(d ||| (e &&& f)) - 2 * (d &&& e) + 1 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) + 4 * (f &&& (d ||| e)) + 2 * (e |||  ~~~(d |||  ~~~f)) + 28 *  ~~~(d ||| (e ||| f)) + 14 *  ~~~( ~~~d ||| (e ||| f)) + 43 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 35 * ( ~~~d &&& ( ~~~e &&& f)) + 39 * ( ~~~d &&& (e &&& f)) + 43 * (d &&& ( ~~~e &&& f)) + 40 * (d &&& (e &&& f)) =  - 25 *  ~~~(d ||| ( ~~~e ||| f)) + 5 * (d &&& ( ~~~e ||| f))

theorem test_sext_zext_proof : test_sext_zext_before ⊑ test_sext_zext_after

theorem e_1717 :
     - 7 * (a &&& (b ||| c)) - 1 * (b |||  ~~~(a ||| c)) - 7 * (c ^^^ (a |||  ~~~b)) - 5 *  ~~~(a ^^^ (b &&& c)) + 1 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) - 7 * (c ^^^ (a &&& b)) + 7 *  ~~~(a ||| b) + 11 * (c ^^^ (a ||| ( ~~~b ||| c))) - 1 * (c ^^^  ~~~(a &&& (b &&& c))) + 3 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) + 3 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 1 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) - 11 *  ~~~(a ^^^ (b ||| c)) + 7 * ((a &&& c) |||  ~~~(b ||| c)) + 1 *  ~~~(a ||| (b &&& c)) + 11 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) - 11 *  ~~~(a ||| c) - 3 * (b |||  ~~~(a ^^^ c)) + 2 * (b ||| (a &&&  ~~~c)) + 3 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 11 * (b &&&  ~~~c) - 7 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) - 6 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) + 14 *  ~~~(a ||| (b ||| c)) + 8 *  ~~~(a ||| ( ~~~b ||| c)) - 28 *  ~~~( ~~~a ||| (b ||| c)) + 1 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 7 * ( ~~~a &&& ( ~~~b &&& c)) + 16 * ( ~~~a &&& (b &&& c)) + 8 * (a &&& ( ~~~b &&& c)) =  - 1 * (c ^^^ (a &&& ( ~~~b ||| c))) - 29 * (a &&& (b &&& c))

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

theorem icmp_ne_zext_ne_non_boolean_proof : icmp_ne_zext_ne_non_boolean_before ⊑ icmp_ne_zext_ne_non_boolean_after

theorem or_ranges_adjacent_proof : or_ranges_adjacent_before ⊑ or_ranges_adjacent_after

theorem sel_false_val_is_a_masked_shl_of_true_val1_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 lshrugt_01_11_exact_proof : lshrugt_01_11_exact_before ⊑ lshrugt_01_11_exact_after

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

theorem or_and2_commuted_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1),
  x_1 ||

theorem shiftLeft_eq' {x : BitVec w₁} {y : BitVec w₂} : x <<< y = x <<< y.toNat

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

theorem ne_nsw_rem_nz_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.smulOverflow 5#8 = true) → ofBool (x * 5#8 != BitVec.ofInt 8 (-126)) = 1#1

theorem PR60818_eq_commuted_proof : PR60818_eq_commuted_before ⊑ PR60818_eq_commuted_after

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

theorem ne_10_proof : ne_10_before ⊑ ne_10_after

theorem p0_proof : p0_before ⊑ p0_after

theorem test_xor_ne_proof : test_xor_ne_before ⊑ test_xor_ne_after

theorem lshr_add_thm (e e_1 : IntW 8) :
  shl (add (lshr e_1 (const? 8 5)) (LLVM.srem e (const? 8 42))) (const? 8 5) ⊑
    LLVM.and (add e_1 (shl (LLVM.srem e (const? 8 42)) (const? 8 5))) (const? 8 (-32))

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

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 alive_AndOrXor_2284  (w : Nat)   : alive_AndOrXor_2284_src w  ⊑ alive_AndOrXor_2284_tgt w

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

theorem ashrsgt_03_04_exact_proof : ashrsgt_03_04_exact_before ⊑ ashrsgt_03_04_exact_after

theorem bv_275 :
    ∀ (e e_1 : LLVM.IntW 5), LLVM.mul (LLVM.udiv e_1 e) e ⊑ LLVM.sub e_1 (LLVM.urem e_1 e)

theorem positive_biggerlshr_shlnuwnsw_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(6#8 ≥ ↑8 ∨
        True ∧ (x >>> 6#8 <<< 3#8).sshiftRight' 3#8 ≠ x >>> 6#8 ∨
          True ∧ x >>> 6#8 <<< 3#8 >>> 3#8 ≠ x >>> 6#8 ∨ 3#8 ≥ ↑8) →
    ¬3#8 ≥ ↑8 → x >>> 6#8 <<< 3#8 = x >>> 3#8 &&& 24#8

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

theorem main7a_logical_thm.extracted_1._5 : ∀ (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 1#1

theorem sle_swap_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.sge e e_1) ⊑ const? 1 1

theorem andn_or_cmp_4_logical_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 == x_1) = 1#1 → ofBool (x_2 != x_1) = 1#1 → True → ofBool (x_2 != x_1) = ofBool (42#32 <ᵤ x)

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (x <ₛ x) = 0#1

theorem test3_thm.extracted_1._4 : ∀ (x : BitVec 1) (x_1 : BitVec 599),
  ¬x = 1#1 → ¬4096#599 = 0 → ¬12#599 ≥ ↑599 → x_1 / 4096#599 = x_1 >>> 12#599

theorem sdiv6_thm (e : IntW 32) :
  mul (LLVM.sdiv e (const? 32 3) { «exact» := true }) (const? 32 (-3)) ⊑ sub (const? 32 0) e

theorem add_eq_sll (a : Nat) : a + a = a <<< 1

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

theorem tctx_at_0 : tctx ⟨0, by omega⟩ = WidthExpr.var ⟨0, by omega⟩

theorem PR75692_1_proof : PR75692_1_before ⊑ PR75692_1_after

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

@[simp]
lemma transSetBV_spec {m : CNFA n} {ss : BitVec m.m.stateMax} :
    s' ∈ bv_to_set (m.m.transSetBV ss a) ↔
      ∃ s ∈ bv_to_set ss, s' ∈ m.m.tr s a

theorem bool2 (x y : Bool) (h : x = y) : y = x

theorem test7_proof : test7_before ⊑ test7_after

theorem positive_trunc_base_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (-1#16 <ₛ truncate 16 x) = 1#1 → ofBool (truncate 16 x + 128#16 <ᵤ 256#16) = ofBool (x &&& 65408#32 == 0#32)

theorem xor_decide (p q : Prop) [dp : Decidable p] [Decidable q] :
    (decide p).xor (decide q) = decide (p ≠ q)

theorem ashr_sle_noexact_proof : ashr_sle_noexact_before ⊑ ashr_sle_noexact_after

theorem icmp_ugt_16_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ x <<< 16#64 >>> 16#64 ≠ x ∨ 16#64 ≥ ↑64) → ofBool (1048575#64 <ᵤ x <<< 16#64) = ofBool (15#64 <ᵤ x)

theorem ult_or_not_max_commute_logical_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x != -1#8) = 1#1 → 1#1 = ofBool (x != -1#8)

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

theorem lshrult_02_02_exact_proof : lshrult_02_02_exact_before ⊑ lshrult_02_02_exact_after

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

theorem and_umax_muchless_proof : and_umax_muchless_before ⊑ and_umax_muchless_after

theorem add_shl_same_amount_nuw_proof : add_shl_same_amount_nuw_before ⊑ add_shl_same_amount_nuw_after

theorem test6_thm (e : IntW 65) :
  add (LLVM.xor e (shl (const? 65 1) (const? 65 64))) (shl (const? 65 1) (const? 65 64)) ⊑ e

theorem ne_commuted_equal_minus_1_proof : ne_commuted_equal_minus_1_before ⊑ ne_commuted_equal_minus_1_after

theorem or_xor_xor_normal_variant3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  x_1 ^^^ x_1 &&& x ||

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

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

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

theorem not_xor_to_or_not1_proof : not_xor_to_or_not1_before ⊑ not_xor_to_or_not1_after

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

theorem udiv_mul_shl_nuw_exact_commute1_proof : udiv_mul_shl_nuw_exact_commute1_before ⊑ udiv_mul_shl_nuw_exact_commute1_after

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

theorem e_1333 :
    1 *  ~~~z + 4 * t + 7 *  ~~~(z ^^^ t) + 3 * (z ^^^ t) + 7 *  ~~~t - 16 *  ~~~(z ||| t) - 8 *  ~~~(z |||  ~~~t) - 4 * (z &&&  ~~~t) - 5 * (z &&& t) =  - 1 * (z |||  ~~~t) + 7 * z

theorem e_1529 :
    3 * (b |||  ~~~(a |||  ~~~c)) - 2 * ((a &&& b) ^^^ (b |||  ~~~c)) + 1 * (b ^^^ (a &&& ( ~~~b ||| c))) + 7 * (b &&& c) + 2 *  ~~~(a ||| (b ||| c)) - 2 *  ~~~(a ||| ( ~~~b ||| c)) + 4 *  ~~~( ~~~a ||| (b ||| c)) - 4 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 6 * ( ~~~a &&& (b &&& c)) + 2 * (a &&& ( ~~~b &&& c)) - 10 * (a &&& (b &&& c)) = 3 * (b ^^^ (a ||| (b ^^^ c)))

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

theorem test32_proof : test32_before ⊑ test32_after

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

theorem test_ashr_exact__exact_is_safe_proof : test_ashr_exact__exact_is_safe_before ⊑ test_ashr_exact__exact_is_safe_after

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

theorem icmp_power2_and_icmp_shifted_mask_8_6_proof : icmp_power2_and_icmp_shifted_mask_8_6_before ⊑ icmp_power2_and_icmp_shifted_mask_8_6_after

@[simp]
lemma complete_eval {M : NFA α σ} {w} (q : σ) :
    (.inl q ∈ M.complete.eval w) ↔ q ∈ M.eval w

theorem or_and_not_not_wrong_a_proof : or_and_not_not_wrong_a_before ⊑ or_and_not_not_wrong_a_after

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

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

@[simp]
theorem sdiv_allOnes {w : ℕ} {x : BitVec w} :
    x.sdiv (BitVec.allOnes w) = -x

theorem e_668 :
     - 1 *  ~~~x + 4 * y - 2 *  ~~~y + 4 *  ~~~(x &&&  ~~~x) + 1 * (x |||  ~~~y) + 1 *  ~~~(x &&& y) + 4 *  ~~~(x ||| y) - 13 *  ~~~(x |||  ~~~y) - 9 * (x &&&  ~~~y) - 7 * (x &&& y) = 7 *  ~~~(x ^^^ y) - 5 * (x ||| y)

theorem test5_proof : test5_before ⊑ test5_after

theorem t3_exact_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ x >>> 63#64 <<< 63#64 ≠ x ∨ 63#64 ≥ ↑64) → 0#64 - x.sshiftRight' 63#64 = x >>> 63#64

theorem e_117 :
     - 11 *  ~~~y - 11 *  ~~~(x &&&  ~~~y) - 2 * (x ||| y) + 21 *  ~~~(x ||| y) + 12 *  ~~~(x |||  ~~~y) + 13 * (x &&& y) =  - 12 * (x &&&  ~~~y) - 1 *  ~~~(x &&& y)

theorem or_signbit_select_lshr_proof : or_signbit_select_lshr_before ⊑ or_signbit_select_lshr_after

theorem ashrslt_01_09_exact_proof : ashrslt_01_09_exact_before ⊑ ashrslt_01_09_exact_after

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

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

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

theorem test11_proof : test11_before ⊑ test11_after

theorem icmp_equality_test_commute_select2_proof : icmp_equality_test_commute_select2_before ⊑ icmp_equality_test_commute_select2_after

theorem ashr_overshift_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬(15#32 ≥ ↑32 ∨ 17#32 ≥ ↑32) → 31#32 ≥ ↑32 → False

theorem t0_const_lshr_shl_ne_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (LLVM.and (shl e_1 (const? 32 1)) (lshr e (const? 32 1))) (const? 32 0) ⊑
    icmp IntPred.ne (LLVM.and (lshr e (const? 32 2)) e_1) (const? 32 0)

theorem xor_nosignbit_select_lshr_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 → ¬8#32 ≥ ↑32 → (x ^^^ 2147418112#32) >>> 8#32 = x >>> 8#32 ^^^ 8388352#32

theorem t2_ashr_proof : t2_ashr_before ⊑ t2_ashr_after

theorem test_eq_11_and_15_add_10_proof : test_eq_11_and_15_add_10_before ⊑ test_eq_11_and_15_add_10_after

theorem add_or_sub_comb_i32_commuted1_nuw_proof : add_or_sub_comb_i32_commuted1_nuw_before ⊑ add_or_sub_comb_i32_commuted1_nuw_after

theorem lt_two_pow_succ_of_lt (x y : Nat) :
    (x / 2) < 2 ^ y → x < 2 ^ (y + 1)

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

theorem test_logical_or_eq_a_b_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → ofBool (x_1 == x) = 1#1 → x_1 = x

theorem main3c_logical_thm (e : IntW 32) :
  select
      (select (icmp IntPred.ne (LLVM.and e (const? 32 7)) (const? 32 0)) (const? 1 1)
        (icmp IntPred.ne (LLVM.and e (const? 32 48)) (const? 32 0)))
      (const? 32 0) (const? 32 1) ⊑
    zext 32 (icmp IntPred.eq (LLVM.and e (const? 32 55)) (const? 32 0))

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

theorem n13_proof : n13_before ⊑ n13_after

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

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

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

theorem test_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x != 34#32) = 1#1 → ofBool (-1#32 <ₛ x) = ofBool (x != 34#32) &&& ofBool (-1#32 <ₛ x)

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

theorem test2_proof : test2_before ⊑ test2_after

theorem test28_thm.extracted_1._1 : ∀ (x : BitVec 32),
  x + BitVec.ofInt 32 (-2147483647) ^^^ BitVec.ofInt 32 (-2147483648) = x + 1#32

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

theorem urem_common_divisor_thm.extracted_1._2 : ∀ (x x_1 : BitVec 5) (x_2 : BitVec 1),
  ¬(x_2 = 1#1 ∨ x_1 = 0) → x_2 = 1#1 → ¬x_1 = 0 → False

theorem not_and_and_or_no_or_commute2_proof : not_and_and_or_no_or_commute2_before ⊑ not_and_and_or_no_or_commute2_after

theorem test_zext_nneg_thm (e : IntW 64) (e_1 : IntW 32) (e_2 : IntW 64) :
  sub (add e_2 (const? 64 (-5))) (add (zext 64 (LLVM.xor e_1 (const? 32 (-1))) { «nneg» := true }) e) ⊑
    add (add e_2 (const? 64 (-4))) (sub (sext 64 e_1) e)

theorem lshr_2_add_zext_basic_thm (e e_1 : IntW 1) :
  lshr (add (zext 2 e_1) (zext 2 e)) (const? 2 1) ⊑ zext 2 (LLVM.and e_1 e)

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

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

theorem icmp_ult_x_y_2_proof : icmp_ult_x_y_2_before ⊑ icmp_ult_x_y_2_after

theorem urem_i32_multiuse_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬zeroExtend 32 x = 0 →
    zeroExtend 32 x = 0 ∨
        True ∧ (zeroExtend 32 x_1).saddOverflow (zeroExtend 32 x) = true ∨
          True ∧ (zeroExtend 32 x_1).uaddOverflow (zeroExtend 32 x) = true ∨
            True ∧ (zeroExtend 32 x_1 % zeroExtend 32 x).smulOverflow (zeroExtend 32 x_1 + zeroExtend 32 x) = true ∨
              True ∧ (zeroExtend 32 x_1 % zeroExtend 32 x).umulOverflow (zeroExtend 32 x_1 + zeroExtend 32 x) = true →
      False

theorem ugt_or_not_min_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x <ᵤ x_1) ||

theorem sge_smin4_proof : sge_smin4_before ⊑ sge_smin4_after

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

theorem Tensor2d'.map_extract (δ₀ δ₁ sz₀ sz₁ : ℕ) (t : Tensor2d' α) (f : α → β) :
  (t.map f).extract δ₀ δ₁ sz₀ sz₁ = (t.extract δ₀ δ₁ sz₀ sz₁).map f

theorem lshr_16_add_not_known_16_leading_zeroes_proof : lshr_16_add_not_known_16_leading_zeroes_before ⊑ lshr_16_add_not_known_16_leading_zeroes_after

theorem select2_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → truncate 8 (zeroExtend 32 x_1 + zeroExtend 32 x) = x_1 + x

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

theorem lshrugt_03_06_proof : lshrugt_03_06_before ⊑ lshrugt_03_06_after

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

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

@[simp] lemma NFA'.autUnsignedCmp_σ (cmp : RelationOrdering) : (NFA'.autUnsignedCmp cmp).σ = NFA.unsignedCmpState

theorem slt_swap_and_max_commute_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.eq e_1 (const? 8 127)) (icmp IntPred.sgt e e_1) (const? 1 0) ⊑ const? 1 0

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

theorem or_shl_thm.extracted_1._1 : ∀ (x x_1 x_2 x_3 : BitVec 8), ¬(x_2 ≥ ↑8 ∨ x_2 ≥ ↑8) → x_2 ≥ ↑8 → False

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

theorem lsb_mask_sign_sext_thm (e : IntW 32) :
  ashr (LLVM.and (add e (const? 32 (-1))) (LLVM.xor e (const? 32 (-1)))) (const? 32 31) ⊑
    sext 32 (icmp IntPred.eq e (const? 32 0))

theorem add_constant_equal_with_the_top_bit_of_demandedbits_pass_thm (e : IntW 32) :
  LLVM.and (add e (const? 32 16)) (const? 32 24) ⊑ LLVM.xor (LLVM.and e (const? 32 24)) (const? 32 16)

theorem e_1604 :
     - 5 * ((a &&& b) |||  ~~~(b ||| c)) + 2 * (b ^^^ ( ~~~a &&& (b ||| c))) + 1 * (a ^^^ (b ||| c)) - 2 * (b &&&  ~~~(a ^^^ c)) - 1 * (c ^^^ ( ~~~a ||| (b &&& c))) - 1 * ( ~~~b &&&  ~~~(a ^^^ c)) + 2 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) + 1 *  ~~~(a &&& ( ~~~b &&& c)) - 6 *  ~~~( ~~~a &&& (b ||| c)) + 2 *  ~~~(a ^^^ (b &&& c)) + 5 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 3 *  ~~~(a ||| (b ||| c)) - 10 *  ~~~(a ||| ( ~~~b ||| c)) - 3 *  ~~~( ~~~a ||| (b ||| c)) + 3 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 13 * ( ~~~a &&& ( ~~~b &&& c)) - 9 * ( ~~~a &&& (b &&& c)) + 1 * (a &&& ( ~~~b &&& c)) + 6 * (a &&& (b &&& c)) =  - 7 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c)))

theorem test_sub_255_Y_eq_255_proof : test_sub_255_Y_eq_255_before ⊑ test_sub_255_Y_eq_255_after

theorem t5_ugt_slt_0_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬ofBool (143#32 <ᵤ x + 16#32) = 1#1 →
    ofBool (127#32 <ₛ x) = 1#1 ∨ ofBool (x <ₛ BitVec.ofInt 32 (-16)) = 1#1 → False

@[bv_multi_width_normalize] theorem not_eq_iff_ne {α : Sort u} (x y : α) :
  ¬ (x = y) ↔ x ≠ y

theorem ashrsgt_03_14_proof : ashrsgt_03_14_before ⊑ ashrsgt_03_14_after

theorem must_drop_poison_proof : must_drop_poison_before ⊑ must_drop_poison_after

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

theorem p2_slt_65536_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬ofBool (x <ₛ 65536#32) = 1#1 → ¬ofBool (65535#32 <ₛ x) = 1#1 → False

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

theorem e_1444 :
     - 1 *  ~~~t - 6 *  ~~~(z &&&  ~~~z) + 5 *  ~~~(z ^^^ t) - 7 *  ~~~z - 5 *  ~~~(z &&& t) + 7 * (z ^^^ t) - 1 * (z |||  ~~~t) + 15 *  ~~~(z ||| t) + 11 *  ~~~(z |||  ~~~t) + 2 * (z &&& t) =  - 6 * (z &&&  ~~~t)

theorem ashrslt_01_10_thm (e : IntW 4) : icmp IntPred.slt (ashr e (const? 4 1)) (const? 4 (-6)) ⊑ const? 1 0

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

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

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

theorem sgt_or_not_min_commute_logical_proof : sgt_or_not_min_commute_logical_before ⊑ sgt_or_not_min_commute_logical_after

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

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

theorem fold_mask_cmps_to_true_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x != 2147483647#32) ||

theorem or_and_or_pat3_proof : or_and_or_pat3_before ⊑ or_and_or_pat3_after

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

theorem PR51351_proof : PR51351_before ⊑ PR51351_after

theorem ashr_or_proof : ashr_or_before ⊑ ashr_or_after

theorem test18_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.saddOverflow 1#32 = true ∨
        True ∧
          (x_1 + 1#32).saddOverflow (x &&& BitVec.ofInt 32 (-1431655766) ^^^ BitVec.ofInt 32 (-1431655766)) = true) →
    x_1 + 1#32 + (x &&& BitVec.ofInt 32 (-1431655766) ^^^ BitVec.ofInt 32 (-1431655766)) =
      x_1 - (x ||| 1431655765#32)

theorem dialect_add_f_eq (a : R q n) : a + (f q n) = a

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

theorem demorgan_or_zext_thm (e e_1 : IntW 1) :
  LLVM.or (LLVM.xor (zext 32 e_1) (const? 32 1)) (LLVM.xor (zext 32 e) (const? 32 1)) ⊑
    zext 32 (LLVM.xor (LLVM.and e_1 e) (const? 1 1))

theorem test_negative_combined_sub_unsigned_overflow_proof : test_negative_combined_sub_unsigned_overflow_before ⊑ test_negative_combined_sub_unsigned_overflow_after

theorem p_constmask2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (x_1 &&& 61440#32 &&& (x &&& BitVec.ofInt 32 (-65281)) != 0) = true) →
    (x_1 &&& 61440#32) + (x &&& BitVec.ofInt 32 (-65281)) = x_1 &&& 61440#32 ||

theorem same_signbit_wrong_type_signed_proof : same_signbit_wrong_type_signed_before ⊑ same_signbit_wrong_type_signed_after

theorem t0_ult_slt_128_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.ult (add e_2 (const? 32 16)) (const? 32 144)) e_2
      (select (icmp IntPred.slt e_2 (const? 32 128)) e_1 e) ⊑
    select (icmp IntPred.sgt e_2 (const? 32 127)) e
      (select (icmp IntPred.slt e_2 (const? 32 (-16))) e_1 e_2)

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

theorem sle_smin3_proof : sle_smin3_before ⊑ sle_smin3_after

theorem n11_uge_slt_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 <ᵤ 129#32) = 1#1 → ofBool (x_2 <ₛ 0#32) = 1#1 → x_1 = x

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_6_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_6_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_6_after

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

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

theorem icmp_slt_0_or_icmp_add_1_sge_100_i32_fail_proof : icmp_slt_0_or_icmp_add_1_sge_100_i32_fail_before ⊑ icmp_slt_0_or_icmp_add_1_sge_100_i32_fail_after

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

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

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

theorem lshrult_03_10_thm (e : IntW 4) : icmp IntPred.ult (lshr e (const? 4 3)) (const? 4 (-6)) ⊑ const? 1 1

theorem t9_thm (e e_1 : IntW 8) : sub (const? 8 0) (sub e_1 e) ⊑ sub e e_1

theorem udiv_icmp1_thm (e : IntW 64) :
  icmp IntPred.ne (LLVM.udiv e (const? 64 5) { «exact» := true }) (const? 64 0) ⊑
    icmp IntPred.ne e (const? 64 0)

theorem src_fv_ne_proof : src_fv_ne_before ⊑ src_fv_ne_after

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

theorem p_constmask_commutative_proof : p_constmask_commutative_before ⊑ p_constmask_commutative_after

theorem t1_thm (e : IntW 8) :
  icmp IntPred.sge (sub (const? 8 0) e { «nsw» := true, «nuw» := false }) e ⊑
    icmp IntPred.slt e (const? 8 1)

theorem trunc_sandwich_max_sum_shift2_proof : trunc_sandwich_max_sum_shift2_before ⊑ trunc_sandwich_max_sum_shift2_after

theorem e_1257 :
     - 11 * (z ||| t) - 1 *  ~~~t - 3 *  ~~~(z &&&  ~~~z) + 11 * (z ^^^ t) + 5 * t - 2 *  ~~~(z &&& t) + 5 *  ~~~(z ||| t) + 13 * (z &&&  ~~~t) + 15 * (z &&& t) =  - 1 *  ~~~(z ^^^ t) + 7 * z

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

theorem and_xor_common_op_proof : and_xor_common_op_before ⊑ and_xor_common_op_after

theorem main7c_logical_proof : main7c_logical_before ⊑ main7c_logical_after

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

theorem t22_sign_check_proof : t22_sign_check_before ⊑ t22_sign_check_after

theorem test17_proof : test17_before ⊑ test17_after

theorem uge_swap_and_max_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 ≤ᵤ x) = 1#1 → 0#1 = ofBool (x == -1#8)

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

theorem test2_thm (e e_1 e_2 : IntW 49) : LLVM.xor (ashr e_2 e_1) (ashr e e_1) ⊑ ashr (LLVM.xor e_2 e) e_1

theorem or_consts_proof : or_consts_before ⊑ or_consts_after

theorem mul_of_bool_no_lz_other_op_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ¬(True ∧ (x_1 &&& 1#32).smulOverflow (signExtend 32 x) = true ∨
        True ∧ (x_1 &&& 1#32).umulOverflow (signExtend 32 x) = true) →
    ofBool (127#32 <ₛ (x_1 &&& 1#32) * signExtend 32 x) = 0#1

theorem test17_thm (e : IntW 1) : sub (const? 32 0) (sext 32 e) ⊑ zext 32 e

theorem ashrslt_03_02_exact_proof : ashrslt_03_02_exact_before ⊑ ashrslt_03_02_exact_after

theorem sgt_and_min_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == BitVec.ofInt 8 (-128)) &&& ofBool (x <ₛ x_1) = 0#1

theorem fold_add_udiv_urem_proof : fold_add_udiv_urem_before ⊑ fold_add_udiv_urem_after

theorem shift_xor_multiuse_cmp_proof : shift_xor_multiuse_cmp_before ⊑ shift_xor_multiuse_cmp_after

@[simp]
lemma List.Vector.transport_get {v : Vector α m} { f : Fin n → Fin m} :
    (v.transport f).get i = v.get (f i)

theorem icmp_slt_0_xor_icmp_sge_neg2_i32_fail_proof : icmp_slt_0_xor_icmp_sge_neg2_i32_fail_before ⊑ icmp_slt_0_xor_icmp_sge_neg2_i32_fail_after

private theorem BitVec.ForLean.ule_iff_ult_or_eq' (x y : BitVec w) : (x.ule y) = (decide (x = y ∨ x < y))

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 599),
  x = 1#1 → ¬70368744177664#599 = 0 → 46#599 ≥ ↑599 → False

theorem icmp_sle2_proof : icmp_sle2_before ⊑ icmp_sle2_after

theorem trunc_shl_lshr_var_thm (e e_1 : IntW 64) :
  trunc 32 (shl (lshr e_1 e) (const? 64 2)) ⊑ shl (trunc 32 (lshr e_1 e)) (const? 32 2)

theorem lshrult_03_07_exact_proof : lshrult_03_07_exact_before ⊑ lshrult_03_07_exact_after

theorem test15a_thm (e : IntW 1) :
  shl (const? 53 64) (zext 53 (select e (const? 8 3) (const? 8 1))) ⊑ select e (const? 53 512) (const? 53 128)

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

theorem trunc_shl_nuw_31_i32_i64_thm (e : IntW 64) :
  trunc 32 (shl e (const? 64 31) { «nsw» := false, «nuw» := true }) ⊑ shl (trunc 32 e) (const? 32 31)

theorem test_or4_logical_proof : test_or4_logical_before ⊑ test_or4_logical_after

theorem p_constmask_commutative_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (x_1 &&& BitVec.ofInt 32 (-65281) &&& (x &&& 65280#32) != 0) = true) →
    x_1 &&& BitVec.ofInt 32 (-65281) ^^^ x &&& 65280#32 = x_1 &&& BitVec.ofInt 32 (-65281) ||

theorem cv2_proof : cv2_before ⊑ cv2_after

theorem ashr_x_by_const_cmp_sge_x_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬5#32 ≥ ↑32 → ofBool (x ≤ₛ x.sshiftRight' 5#32) = ofBool (x <ₛ 1#32)

theorem icmp_slt_0_and_icmp_sge_neg1_i64_fail_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬62#64 ≥ ↑64 →
    ofBool (BitVec.ofInt 64 (-2) <ₛ x) = 1#1 →
      x >>> 62#64 &&& zeroExtend 64 (ofBool (-1#64 ≤ₛ x)) = x >>> 62#64 &&& 1#64

theorem lshr_shl_pow2_const_overflow_proof : lshr_shl_pow2_const_overflow_before ⊑ lshr_shl_pow2_const_overflow_after

theorem test2_proof : test2_before ⊑ test2_after

theorem and_xor_commute1_proof : and_xor_commute1_before ⊑ and_xor_commute1_after

theorem canonicalize_logic_first_or0_thm (e : IntW 32) :
  LLVM.or (add e (const? 32 112)) (const? 32 15) ⊑ add (LLVM.or e (const? 32 15)) (const? 32 112)

theorem shl_xor_xor_bad_mask_distribute_thm (e e_1 : IntW 8) :
  LLVM.xor (shl e_1 (const? 8 1)) (LLVM.xor (shl e (const? 8 1)) (const? 8 (-68))) ⊑
    LLVM.xor (shl (LLVM.xor e e_1) (const? 8 1)) (const? 8 (-68))

theorem fold_icmp_shl_nuw_c1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(12#32 ≥ ↑32 ∨
        True ∧ 2#32 <<< (x >>> 12#32 &&& 15#32) >>> (x >>> 12#32 &&& 15#32) ≠ 2#32 ∨ x >>> 12#32 &&& 15#32 ≥ ↑32) →
    ofBool (2#32 <<< (x >>> 12#32 &&& 15#32) <ᵤ 4#32) = ofBool (x &&& 61440#32 == 0#32)

theorem mul8_low_A0_B0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(4#8 ≥ ↑8 ∨ 4#8 ≥ ↑8 ∨ 4#8 ≥ ↑8) →
    (x_1 >>> 4#8 * x + x >>> 4#8 * x_1) <<< 4#8 + (x_1 &&& 15#8) * (x &&& 15#8) = x * x_1

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

theorem test24_proof : test24_before ⊑ test24_after

theorem neq_of_min_neq_min {i v w : Nat} (hivw : ¬ min i v = min i w ) :
  (v ≠ w)

theorem udiv_x_by_const_cmp_x_proof : udiv_x_by_const_cmp_x_before ⊑ udiv_x_by_const_cmp_x_after

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

theorem positive_samevar_shlnuw_proof : positive_samevar_shlnuw_before ⊑ positive_samevar_shlnuw_after

theorem or_logic_or_logic_and_2_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 ||

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

theorem test10_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬16#32 ≥ ↑32 →
    ¬(16#32 ≥ ↑32 ∨ True ∧ (x >>> 16#32).umulOverflow 65535#32 = true) →
      zeroExtend 64 (x >>> 16#32) * 65535#64 = zeroExtend 64 (x >>> 16#32 * 65535#32)

theorem negation_of_increment_via_or_with_no_common_bits_set_proof : negation_of_increment_via_or_with_no_common_bits_set_before ⊑ negation_of_increment_via_or_with_no_common_bits_set_after

theorem and_xor_common_op_commute1_proof : and_xor_common_op_commute1_before ⊑ and_xor_common_op_commute1_after

theorem badimm4_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(7#8 ≥ ↑8 ∨ 8#16 ≥ ↑16) →
    ofBool ((truncate 8 x).sshiftRight' 7#8 == truncate 8 (x >>> 8#16)) = 1#1 →
      ¬ofBool (127#16 <ₛ x) = 1#1 → ofBool (x <ₛ BitVec.ofInt 16 (-128)) = 1#1 → truncate 8 x = BitVec.ofInt 8 (-127)

theorem band_lor_right2_proof : band_lor_right2_before ⊑ band_lor_right2_after

theorem ripple_nsw2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  True ∧ (x_1 &&& BitVec.ofInt 16 (-16385)).saddOverflow (x &&& 1#16) = true ∨
      True ∧ (x_1 &&& BitVec.ofInt 16 (-16385)).uaddOverflow (x &&& 1#16) = true →
    False

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

theorem lshr_C1_add_A_C2_i32_thm (e : IntW 32) :
  shl (const? 32 6) (add (LLVM.and e (const? 32 65535)) (const? 32 5)) ⊑
    shl (const? 32 192) (LLVM.and e (const? 32 65535))

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

theorem trunc_lshr_sext_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬6#32 ≥ ↑32 → ¬6#8 ≥ ↑8 → truncate 8 (signExtend 32 x >>> 6#32) = x.sshiftRight' 6#8

theorem scalar_i8_shl_ugt_const_proof : scalar_i8_shl_ugt_const_before ⊑ scalar_i8_shl_ugt_const_after

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

theorem scalar_i8_shl_ult_const_3_proof : scalar_i8_shl_ult_const_3_before ⊑ scalar_i8_shl_ult_const_3_after

theorem ashrslt_01_11_exact_proof : ashrslt_01_11_exact_before ⊑ ashrslt_01_11_exact_after

theorem lshrugt_03_03_proof : lshrugt_03_03_before ⊑ lshrugt_03_03_after

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

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

theorem sub_inc_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), x_1 - (x + 1#8) = x_1 + (x ^^^ -1#8)

theorem logical_and_logical_and_icmps_comm2_proof : logical_and_logical_and_icmps_comm2_before ⊑ logical_and_logical_and_icmps_comm2_after

theorem icmp_slt_0_or_icmp_sgt_0_i64_fail0_proof : icmp_slt_0_or_icmp_sgt_0_i64_fail0_before ⊑ icmp_slt_0_or_icmp_sgt_0_i64_fail0_after

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

theorem sle_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.sle e_1 e) ⊑ const? 1 1

theorem p_constmask_commutative_proof : p_constmask_commutative_before ⊑ p_constmask_commutative_after

theorem tryFactorization_xor_ashr_ashr_proof : tryFactorization_xor_ashr_ashr_before ⊑ tryFactorization_xor_ashr_ashr_after

theorem canonicalize_logic_first_or0_nswnuw_proof : canonicalize_logic_first_or0_nswnuw_before ⊑ canonicalize_logic_first_or0_nswnuw_after

theorem scalar_i32_shl_and_signbit_slt_thm (e e_1 : IntW 32) :
  icmp IntPred.slt (LLVM.and (shl e_1 e) (const? 32 (-2147483648))) (const? 32 0) ⊑
    icmp IntPred.slt (shl e_1 e) (const? 32 0)

theorem t0_thm (e e_1 e_2 : IntW 8) : sub (sub e_2 e_1) e ⊑ sub e_2 (add e_1 e)

theorem main4d_logical_thm (e : IntW 32) :
  select
      (select (icmp IntPred.ne (LLVM.and e (const? 32 7)) (const? 32 7)) (const? 1 1)
        (icmp IntPred.eq (LLVM.and e (const? 32 16)) (const? 32 0)))
      (const? 32 0) (const? 32 1) ⊑
    zext 32 (icmp IntPred.eq (LLVM.and e (const? 32 23)) (const? 32 23))

theorem or_test1_proof : or_test1_before ⊑ or_test1_after

theorem ule_swap_and_min_commute_logical_proof : ule_swap_and_min_commute_logical_before ⊑ ule_swap_and_min_commute_logical_after

theorem masked_and_notallzeroes_logical_proof : masked_and_notallzeroes_logical_before ⊑ masked_and_notallzeroes_logical_after

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

theorem p_commutative0_proof : p_commutative0_before ⊑ p_commutative0_after

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

theorem test2_proof : test2_before ⊑ test2_after

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

theorem urem_i8_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬zeroExtend 32 x = 0 → ¬x = 0 → truncate 8 (zeroExtend 32 x_1 % zeroExtend 32 x) = x_1 % x

theorem sge_or_not_max_logical_proof : sge_or_not_max_logical_before ⊑ sge_or_not_max_logical_after

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

theorem t3_ult_sgt_neg1_thm.extracted_1._6 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 + 16#32 <ᵤ 144#32) = 1#1 → ofBool (127#32 <ₛ x_1) = 1#1 → False

theorem ashr_can_be_lshr_2_proof : ashr_can_be_lshr_2_before ⊑ ashr_can_be_lshr_2_after

theorem and_or2_thm.extracted_1._4 : ∀ (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

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 ashrslt_02_01_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬2#4 ≥ ↑4 → ofBool (x.sshiftRight' 2#4 <ₛ 1#4) = ofBool (x <ₛ 4#4)

theorem e_954 :
     - 6 *  ~~~(z ^^^ t) - 11 *  ~~~(z &&&  ~~~t) - 11 *  ~~~(z &&&  ~~~z) + 28 *  ~~~(z ||| t) + 22 *  ~~~(z |||  ~~~t) + 11 * (z &&&  ~~~t) =  - 28 * (z &&& t)

theorem test16_proof : test16_before ⊑ test16_after

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

theorem add_nsw_poison_constant_fold_proof : add_nsw_poison_constant_fold_before ⊑ add_nsw_poison_constant_fold_after

theorem bitwise_and_logical_and_masked_icmp_allones_thm.extracted_1._4 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  ofBool (x_1 &&& 8#32 == 8#32) = 1#1 →
    ¬ofBool (x_1 &&& 15#32 == 15#32) = 1#1 → x &&& ofBool (x_1 &&& 7#32 == 7#32) = 0#1

lemma CNFA.canonicalSimul (m : CNFA n) : m.m.Simul m.toNFA {(s, s') | s = s'.val} ⊤ ∅

theorem exact_lshr_eq_both_equal_proof : exact_lshr_eq_both_equal_before ⊑ exact_lshr_eq_both_equal_after

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

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

theorem scalar_i64_shl_ult_const_proof : scalar_i64_shl_ult_const_before ⊑ scalar_i64_shl_ult_const_after

theorem ugt_swap_and_not_min_logical_proof : ugt_swap_and_not_min_logical_before ⊑ ugt_swap_and_not_min_logical_after

theorem t1_proof : t1_before ⊑ t1_after

theorem test22_proof : test22_before ⊑ test22_after

theorem eq_umin1_proof : eq_umin1_before ⊑ eq_umin1_after

theorem slt_and_not_max_commute_proof : slt_and_not_max_commute_before ⊑ slt_and_not_max_commute_after

theorem ne_smin3_proof : ne_smin3_before ⊑ ne_smin3_after

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

theorem test15c_proof : test15c_before ⊑ test15c_after

theorem t7_ashr_thm (e e_1 : IntW 32) :
  ashr (ashr e_1 (sub (const? 32 32) e) { «exact» := true }) (add e (const? 32 (-2))) ⊑ ashr e_1 (const? 32 30)

theorem zext_sext_sle_known_nonneg_op0_narrow_proof : zext_sext_sle_known_nonneg_op0_narrow_before ⊑ zext_sext_sle_known_nonneg_op0_narrow_after

theorem t0_basic_thm (e e_1 : IntW 8) :
  icmp IntPred.ult (add e_1 e) e ⊑ icmp IntPred.ugt e_1 (LLVM.xor e (const? 8 (-1)))

theorem ashr_can_be_lshr_thm.extracted_1._1 : ∀ (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 →
      False

@[simp]
theorem flipAccept_eval {M : NFA α σ} : M.flipAccept.eval w = M.eval w

theorem exact_ashr_ne_both_equal_proof : exact_ashr_ne_both_equal_before ⊑ exact_ashr_ne_both_equal_after

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

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

theorem demorgan_nor_proof : demorgan_nor_before ⊑ demorgan_nor_after

theorem n9_proof : n9_before ⊑ n9_after

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

theorem lshr_sub_nsw_proof : lshr_sub_nsw_before ⊑ lshr_sub_nsw_after

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

theorem test1_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ¬zeroExtend 32 x ≥ ↑32 →
    ¬(True ∧ x.msb = true ∨ zeroExtend 32 x ≥ ↑32) →
      x_1.sshiftRight' (zeroExtend 32 x) &&& 1#32 = x_1 >>> zeroExtend 32 x &&& 1#32

theorem e_52 :
    11 *  ~~~(x &&&  ~~~x) - 11 * (x ^^^ y) - 12 *  ~~~(x ||| y) - 1 * (x &&&  ~~~y) - 12 * (x &&& y) =  - 1 * (x |||  ~~~y)

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

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

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

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

theorem xor_sge_proof : xor_sge_before ⊑ xor_sge_after

theorem reassoc_add_nuw_proof : reassoc_add_nuw_before ⊑ reassoc_add_nuw_after

theorem test35_proof : test35_before ⊑ test35_after

theorem negate_zext_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 8),
  x_1 - zeroExtend 8 x = x_1 + signExtend 8 x

@[bv_automata_nnf] theorem ite_true_false {_ : Decidable p} : (ite p True False) = p

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

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

theorem test11_proof : test11_before ⊑ test11_after

theorem test19a_proof : test19a_before ⊑ test19a_after

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

@[simp_llvm_option]
theorem sub?_eq : LLVM.sub? a b  = .value (a - b)

theorem not_signbit_zext_thm (e : IntW 16) :
  zext 32 (lshr (LLVM.xor e (const? 16 (-1))) (const? 16 15)) ⊑
    zext 32 (icmp IntPred.sgt e (const? 16 (-1)))

theorem sel_zext_constants_proof : sel_zext_constants_before ⊑ sel_zext_constants_after

theorem bitwise_and_logical_and_masked_icmp_allones_poison1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& x == x) = 1#1 → ofBool (x_1 &&& (x ||| 7#32) == x ||| 7#32) = 1#1 → False

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 neg_mask_thm.extracted_1._1 : ∀ (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 → False

theorem zext_add_scalar_proof : zext_add_scalar_before ⊑ zext_add_scalar_after

theorem add_nsw_mul_nsw_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(True ∧ x.saddOverflow x = true ∨ True ∧ (x + x).saddOverflow x = true) →
    ¬(True ∧ x.smulOverflow 3#16 = true) → x + x + x = x * 3#16

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

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

theorem test_eq1_proof : test_eq1_before ⊑ test_eq1_after

theorem or_and_shift_shift_and_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(3#32 ≥ ↑32 ∨ 2#32 ≥ ↑32) →
    (x &&& 7#32) <<< 3#32 ||

@[simp]
theorem ofBitVecZext_eq_getLsbD (x : BitVec w) (i : Nat) :
  ofBitVecZext x i = x.getLsbD i

theorem ult_or_not_max_commute_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.ne e_1 (const? 8 (-1))) (icmp IntPred.ult e_1 e) ⊑
    icmp IntPred.ne e_1 (const? 8 (-1))

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

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

theorem sgt_and_min_proof : sgt_and_min_before ⊑ sgt_and_min_after

theorem e_350 :
     - 11 * y - 5 * (x ^^^ y) + 2 * (x ||| y) + 5 *  ~~~(x &&&  ~~~y) + 11 *  ~~~y - 16 *  ~~~(x ||| y) + 9 *  ~~~(x |||  ~~~y) - 8 * (x &&&  ~~~y) =  - 4 * (x &&& y)

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

theorem shl_or_commuted_thm (e : IntW 8) :
  LLVM.or (shl (const? 8 3) (add e (const? 8 1))) (shl (const? 8 16) e) ⊑ shl (const? 8 22) e

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

theorem not_not_true_proof : not_not_true_before ⊑ not_not_true_after

theorem e_1103 :
     - 1 *  ~~~(z &&& t) + 2 * (z ^^^ t) + 11 *  ~~~t + 5 *  ~~~(z &&&  ~~~z) - 1 * (z |||  ~~~t) - 14 *  ~~~(z ||| t) - 6 *  ~~~(z |||  ~~~t) - 16 * (z &&&  ~~~t) = 4 * (z &&& t)

theorem and_or_not_not_commute4_proof : and_or_not_not_commute4_before ⊑ and_or_not_not_commute4_after

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

theorem add_signbit_shl_proof : add_signbit_shl_before ⊑ add_signbit_shl_after

theorem narrow_zext_ashr_keep_trunc3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ (signExtend 64 x_1).saddOverflow (signExtend 64 x) = true ∨ 1#64 ≥ ↑64) →
    True ∧ (zeroExtend 14 x_1).saddOverflow (zeroExtend 14 x) = true ∨
        True ∧ (zeroExtend 14 x_1).uaddOverflow (zeroExtend 14 x) = true ∨ 1#14 ≥ ↑14 →
      False

theorem t0_const_lshr_shl_ne_proof : t0_const_lshr_shl_ne_before ⊑ t0_const_lshr_shl_ne_after

theorem test23_proof : test23_before ⊑ test23_after

theorem test65_proof : test65_before ⊑ test65_after

theorem p0_proof : p0_before ⊑ p0_after

theorem ashr_lshr_exact_ashr_only_proof : ashr_lshr_exact_ashr_only_before ⊑ ashr_lshr_exact_ashr_only_after

theorem main3d_logical_proof : main3d_logical_before ⊑ main3d_logical_after

theorem shl_sub_i8_proof : shl_sub_i8_before ⊑ shl_sub_i8_after

theorem narrow_sext_xor_proof : narrow_sext_xor_before ⊑ narrow_sext_xor_after

theorem sdiv_mul_shl_nsw_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 5),
  ¬(True ∧ x_2.smulOverflow x_1 = true ∨
        True ∧ (x_2 <<< x).sshiftRight' x ≠ x_2 ∨
          x ≥ ↑5 ∨ (x_2 <<< x == 0 || 5 != 1 && x_2 * x_1 == intMin 5 && x_2 <<< x == -1) = true) →
    ¬(True ∧ 1#5 <<< x >>> x ≠ 1#5 ∨ x ≥ ↑5 ∨ (1#5 <<< x == 0 || 5 != 1 && x_1 == intMin 5 && 1#5 <<< x == -1) = true) →
      (x_2 * x_1).sdiv (x_2 <<< x) = x_1.sdiv (1#5 <<< x)

theorem n11_wrong_pred3_proof : n11_wrong_pred3_before ⊑ n11_wrong_pred3_after

theorem masked_or_allones_thm (e : IntW 32) :
  LLVM.or (icmp IntPred.eq (LLVM.and e (const? 32 7)) (const? 32 7))
      (icmp IntPred.eq (LLVM.and e (const? 32 39)) (const? 32 39)) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 7)) (const? 32 7)

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

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

theorem test_shl_nuw_nsw__nuw_is_safe_proof : test_shl_nuw_nsw__nuw_is_safe_before ⊑ test_shl_nuw_nsw__nuw_is_safe_after

theorem shift_trunc_wrong_cmp_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬24#32 ≥ ↑32 → 24#32 ≥ ↑32 ∨ True ∧ zeroExtend 32 (truncate 8 (x >>> 24#32)) ≠ x >>> 24#32 → False

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

theorem icmp_eq_and_pow2_shl_pow2_negative1_proof : icmp_eq_and_pow2_shl_pow2_negative1_before ⊑ icmp_eq_and_pow2_shl_pow2_negative1_after

theorem sext_zext_apint2_proof : sext_zext_apint2_before ⊑ sext_zext_apint2_after

theorem scanAnd_false_iff (s : BitStream) (n : Nat)
    : s.scanAnd n = false ↔ ∃ (i : Nat), (i ≤ n) ∧ s i = false

theorem Factor.denote_eq_toNat_reflect {w : Nat} (xs : Env w) (f : Factor) :
  f.denote xs = (f.reflect xs |>.toNat)

theorem test87_proof : test87_before ⊑ test87_after

theorem ult_umin2_proof : ult_umin2_before ⊑ ult_umin2_after

theorem main5c_like_logical_proof : main5c_like_logical_before ⊑ main5c_like_logical_after

theorem ashr_shl_constants_thm (e : IntW 32) :
  shl (ashr (const? 32 (-33)) e) (const? 32 3) ⊑
    shl (ashr (const? 32 (-33)) e) (const? 32 3) { «nsw» := true, «nuw» := false }

theorem a_or_b_const2_proof : a_or_b_const2_before ⊑ a_or_b_const2_after

theorem shl_lshr_demand6_thm (e : IntW 16) :
  LLVM.and (lshr (shl (const? 16 (-32624)) e) (const? 16 4)) (const? 16 4094) ⊑
    LLVM.and (shl (const? 16 2057) e) (const? 16 4094)

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

theorem n2_proof : n2_before ⊑ n2_after

theorem or_signbit_lshr_proof : or_signbit_lshr_before ⊑ or_signbit_lshr_after

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

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

theorem negAux_eq_addAux (x : BitStream) (i : Nat) :
    (negAux x i).1 =  (addAux (~~~ x) one i).1 ∧
    (negAux x i).2 =  (addAux (~~~ x) one i).2

theorem not_ashr_const_proof : not_ashr_const_before ⊑ not_ashr_const_after

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

theorem shl1_nsw_proof : shl1_nsw_before ⊑ shl1_nsw_after

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

theorem lshrult_03_06_exact_proof : lshrult_03_06_exact_before ⊑ lshrult_03_06_exact_after

@[simp] theorem Com.outContextHom_rets (v : HVector Γ.Var t) :
    (rets v : Com d Γ eff t).outContextHom = Ctxt.Hom.id

theorem masked_icmps_mask_notallzeros_bmask_mixed_1_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 12#32 != 0#32) = 1#1 → 0#1 = ofBool (x &&& 15#32 == 9#32)

theorem not_xor_to_or_not1_proof : not_xor_to_or_not1_before ⊑ not_xor_to_or_not1_after

theorem main9_logical_thm.extracted_1._4 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 64#32 != 0#32) = 1#1 → ¬ofBool (x &&& 192#32 == 192#32) = 1#1 → 0#1 = 1#1 → 2#32 = 1#32

theorem test2_proof : test2_before ⊑ test2_after

theorem testi64i32_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬63#64 ≥ ↑64 → ofBool (-1#64 <ₛ x) = 1#1 → truncate 32 (x.sshiftRight' 63#64) ^^^ 127#32 = 127#32

theorem lshr_pow2_sgt_proof : lshr_pow2_sgt_before ⊑ lshr_pow2_sgt_after

@[simp] theorem Lets.castPureToEff_nil : (nil : Lets d Γ_in _ _).castPureToEff eff = nil

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

theorem ashr_mul_times_5_div_4_exact_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ x.smulOverflow 5#32 = true ∨ True ∧ (x * 5#32) >>> 2#32 <<< 2#32 ≠ x * 5#32 ∨ 2#32 ≥ ↑32) →
    ¬(True ∧ x >>> 2#32 <<< 2#32 ≠ x ∨ 2#32 ≥ ↑32 ∨ True ∧ x.saddOverflow (x.sshiftRight' 2#32) = true) →
      (x * 5#32).sshiftRight' 2#32 = x + x.sshiftRight' 2#32

theorem e_2457 :
     - 1 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 2 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 6 * (d &&& ( ~~~e ||| f)) + 1 * (f &&& (d |||  ~~~e)) + 4 * (e ^^^ f) - 1 * (f &&& (d ||| e)) - 1 *  ~~~(d ^^^ (e ^^^ f)) - 3 *  ~~~(d ||| f) - 2 * (f ^^^ (d &&& (e ||| f))) - 1 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 2 * (e ^^^  ~~~(d |||  ~~~f)) - 1 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 4 * (e ^^^ (d &&& ( ~~~e ||| f))) + 5 * ( ~~~f &&& (d ^^^ e)) - 1 *  ~~~(d ||| ( ~~~e &&& f)) - 2 * f - 5 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 1 * (f &&&  ~~~(d &&&  ~~~e)) + 5 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 7 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 7 *  ~~~(d &&&  ~~~f) - 1 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 7 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 7 * (f ^^^  ~~~(d &&&  ~~~e)) - 11 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 2 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 1 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 5 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 5 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 3 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 11 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 6 *  ~~~(d ||| (e &&& f)) - 7 * ((d ^^^ e) |||  ~~~(d ^^^ f)) + 11 * (e ^^^ (d ||| (e &&& f))) + 5 *  ~~~(e |||  ~~~f) - 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 7 * ((d |||  ~~~e) &&& (e ^^^ f)) + 4 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 2 *  ~~~(d &&& (e &&& f)) - 7 * (d |||  ~~~f) - 6 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 11 * e + 4 *  ~~~(d ^^^ (e ||| f)) + 2 * (e ^^^  ~~~(d &&& (e &&& f))) + 3 * (e |||  ~~~(d ||| f)) + 1 * (f ||| (d &&& e)) - 1 * (e ^^^ ( ~~~d &&& (e ||| f))) + 1 * ( ~~~d &&& (e ^^^ f)) + 3 *  ~~~(e &&&  ~~~f) - 2 * ( ~~~f &&&  ~~~(d ^^^ e)) + 5 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 3 * ((d ^^^ e) ||| (d ^^^ f)) - 5 * (f ^^^  ~~~(d |||  ~~~e)) + 4 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 3 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 1 *  ~~~e - 7 * (d &&& f) + 1 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 * (e ^^^ (d &&& (e ||| f))) + 1 *  ~~~(d ^^^ f) + 1 * (d &&& e) - 2 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) - 2 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 2 * (d ||| e) - 11 * (d &&& (e ||| f)) + 3 * ((e &&& f) ||| (d &&& (e ||| f))) + 11 * ((d ^^^ e) &&& (d ^^^ f)) + 2 * d - 1 *  ~~~(d ^^^ ( ~~~e ||| f)) + 31 *  ~~~(d ||| (e ||| f)) + 15 *  ~~~(d ||| ( ~~~e ||| f)) + 15 *  ~~~( ~~~d ||| (e ||| f)) - 2 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 4 * ( ~~~d &&& ( ~~~e &&& f)) - 3 * ( ~~~d &&& (e &&& f)) + 14 * (d &&& ( ~~~e &&& f)) + 41 * (d &&& (e &&& f)) = 7 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f)))

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

theorem same_source_shifted_signbit_proof : same_source_shifted_signbit_before ⊑ same_source_shifted_signbit_after

theorem t6_shl_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 <<< (32#32 - x) <<< (x + BitVec.ofInt 32 (-2))).sshiftRight' (x + BitVec.ofInt 32 (-2)) ≠
                x_1 <<< (32#32 - x) ∨
            x + BitVec.ofInt 32 (-2) ≥ ↑32) →
    30#32 ≥ ↑32 → False

theorem udiv_illegal_type_c_proof : udiv_illegal_type_c_before ⊑ udiv_illegal_type_c_after

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

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 main11_logical_proof : main11_logical_before ⊑ main11_logical_after

theorem scalar_i8_shl_uge_const_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬5#8 ≥ ↑8 → ofBool (64#8 ≤ᵤ x <<< 5#8) = ofBool (x &&& 6#8 != 0#8)

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

theorem sgt_or_not_min_proof : sgt_or_not_min_before ⊑ sgt_or_not_min_after

theorem mullo_variant3_proof : mullo_variant3_before ⊑ mullo_variant3_after

theorem e_1916 :
    7 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) - 5 * (b ^^^ (a ||| (b &&& c))) + 1 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 6 * (b &&&  ~~~(a &&& c)) - 7 * (b ^^^ ( ~~~a &&& (b ^^^ c))) - 5 *  ~~~(a ^^^ c) + 1 * (b ^^^ ( ~~~a &&& (b ||| c))) - 3 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) + 1 * (c ^^^  ~~~(a ||| b)) - 6 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 1 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) + 2 *  ~~~( ~~~a &&& (b &&& c)) + 11 * (b ^^^ (a |||  ~~~c)) + 3 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 3 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) + 5 * (c ^^^  ~~~(a &&& b)) - 1 * (c &&& (a ||| b)) + 4 * (a &&& b) + 5 * ( ~~~c |||  ~~~(a ^^^ b)) - 1 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) + 1 * ( ~~~a ||| ( ~~~b ||| c)) + 1 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 1 * (a ||| b) - 2 *  ~~~(a &&& ( ~~~b ||| c)) - 3 * ((a &&&  ~~~b) ||| (b ^^^ c)) + 3 * b + 1 * (a ^^^ (b ||| c)) - 5 *  ~~~(b ^^^ c) - 5 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) + 7 * (b ^^^ (a ||| ( ~~~b &&& c))) + 1 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 2 * (b ^^^  ~~~(a |||  ~~~c)) - 1 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) - 5 *  ~~~a - 2 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 11 * (a |||  ~~~b) - 1 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) + 5 *  ~~~(a &&& c) + 3 *  ~~~(a ||| c) - 11 *  ~~~( ~~~a ||| (b &&& c)) - 1 * (b |||  ~~~c) + 1 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) - 32 *  ~~~(a ||| (b ||| c)) - 13 *  ~~~(a ||| ( ~~~b ||| c)) - 23 *  ~~~( ~~~a ||| (b ||| c)) + 7 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 19 * ( ~~~a &&& ( ~~~b &&& c)) + 1 * ( ~~~a &&& (b &&& c)) - 10 * (a &&& ( ~~~b &&& c)) - 19 * (a &&& (b &&& c)) =  - 4 * (b ^^^ (a &&& (b ^^^ c)))

theorem shl_nsw_add_nsw_nuw_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ (1#32 <<< x).sshiftRight' x ≠ 1#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 e_787 :
    4 *  ~~~(z ^^^ t) + 1 *  ~~~t + 6 *  ~~~(z |||  ~~~t) - 1 * (z &&&  ~~~t) - 4 * (z &&& t) = 6 *  ~~~z - 1 *  ~~~(z ||| t)

theorem ult_umin2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 <ᵤ x) = 1#1 → ofBool (x <ᵤ x) = ofBool (x_1 <ᵤ x)

theorem n2_proof : n2_before ⊑ n2_after

theorem select_icmp_sgt_allones_smin_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬ofBool (-1#8 <ₛ x) = 1#1 → x ^^^ BitVec.ofInt 8 (-128) = x &&& 127#8

theorem or_not_and_commute2_proof : or_not_and_commute2_before ⊑ or_not_and_commute2_after

@[simp] theorem val_appendInr {v : Var Δ t} : (v.appendInr (Γ := Γ)).val = v.val + Γ.length

theorem test13_proof : test13_before ⊑ test13_after

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

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

theorem mul_selectp2_x_propegate_nuw_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  x_1 = 1#1 →
    ¬(True ∧ (2#8).smulOverflow x = true ∨ True ∧ (2#8).umulOverflow x = true) →
      ¬(True ∧ x <<< 1#8 >>> 1#8 ≠ x ∨ 1#8 ≥ ↑8) → 2#8 * x = x <<< 1#8

theorem or_signbit_select_shl_thm (e : IntW 32) (e_1 : IntW 1) :
  shl (select e_1 (LLVM.or e (const? 32 (-65536))) e) (const? 32 8) ⊑
    select e_1 (LLVM.or (shl e (const? 32 8)) (const? 32 (-16777216))) (shl e (const? 32 8))

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

theorem ashr_ult_8_proof : ashr_ult_8_before ⊑ ashr_ult_8_after

theorem uge_and_max_commute_logical_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 == -1#8) = 1#1 → 0#1 = ofBool (x_1 == -1#8)

theorem n1_proof : n1_before ⊑ n1_after

theorem negtest_near_pow2_cmpval_ashr_slt_noexact_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬1#8 ≥ ↑8 → ofBool (x.sshiftRight' 1#8 <ₛ 5#8) = ofBool (x <ₛ 10#8)

theorem multiuse_shl_shl_proof : multiuse_shl_shl_before ⊑ multiuse_shl_shl_after

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

theorem src_is_mask_zext_thm (e : IntW 8) (e_1 : IntW 16) :
  icmp IntPred.eq (LLVM.and (LLVM.xor e_1 (const? 16 123)) (zext 16 (lshr (const? 8 (-1)) e)))
      (LLVM.xor e_1 (const? 16 123)) ⊑
    icmp IntPred.ule (LLVM.xor e_1 (const? 16 123)) (zext 16 (lshr (const? 8 (-1)) e))

theorem sgt_or_not_min_commute_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 != BitVec.ofInt 8 (-128)) = 1#1 → 1#1 = ofBool (x_1 != BitVec.ofInt 8 (-128))

theorem sum_same :
  (bw q (addMax (bw p a) (bw p a)))  =
  (bw q (mulMax (bw 2 (2#2)) (bw p a)))

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

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

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

theorem e_1753 :
     - 7 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) - 1 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) - 6 * ( ~~~c ||| (a ^^^ b)) - 1 * (b ^^^  ~~~(a &&&  ~~~c)) + 2 * (b ^^^  ~~~(a &&& c)) + 11 * (b ^^^ c) - 1 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) + 7 * (c ^^^  ~~~(a &&& (b &&& c))) - 11 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) + 3 * (a ^^^ c) - 7 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) - 6 * ((a &&& b) ^^^ (b |||  ~~~c)) + 1 *  ~~~(a &&& ( ~~~b ||| c)) + 1 * (c &&& (a ||| b)) - 5 * ((a |||  ~~~b) &&& (b ^^^ c)) - 2 * ( ~~~c |||  ~~~(a ^^^ b)) - 3 *  ~~~(b |||  ~~~c) + 7 * (a &&& b) + 1 * ( ~~~b |||  ~~~(a ^^^ c)) - 2 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) - 6 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 2 * ( ~~~a ||| ( ~~~b ||| c)) + 1 * a - 2 * (a ^^^ (b ^^^ c)) + 1 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) - 7 * ((a &&& b) |||  ~~~(b |||  ~~~c)) + 7 * ( ~~~a &&& ( ~~~b ||| c)) + 18 *  ~~~(a ||| (b ||| c)) + 15 *  ~~~(a ||| ( ~~~b ||| c)) + 20 *  ~~~( ~~~a ||| (b ||| c)) + 10 * ( ~~~a &&& ( ~~~b &&& c)) + 21 * ( ~~~a &&& (b &&& c)) + 21 * (a &&& ( ~~~b &&& c)) + 19 * (a &&& (b &&& c)) =  - 1 *  ~~~( ~~~a ||| ( ~~~b ||| c))

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

theorem no_shift_no_xor_multiuse_cmp_xor_proof : no_shift_no_xor_multiuse_cmp_xor_before ⊑ no_shift_no_xor_multiuse_cmp_xor_after

theorem nonexact_lshr_eq_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → ofBool (4#8 >>> x == 1#8) = ofBool (x == 2#8)

theorem test10b_proof : test10b_before ⊑ test10b_after

theorem ne_smin2_proof : ne_smin2_before ⊑ ne_smin2_after

theorem or_logic_or_logic_and_3_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 1), ¬x_2 = 1#1 → x_1 = 1#1 → x_2 ||

theorem bools_multi_uses1_logical_proof : bools_multi_uses1_logical_before ⊑ bools_multi_uses1_logical_after

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

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

theorem srem_eq_sub_sdiv (x y : BitVec w) (h1 :  ¬y = 0#_ ) (hf₂ : x ≠ intMin w ∨ y ≠ -1#w) :
   x.srem y = x - y * x.sdiv y

theorem or_eq_and_not_add :
    x ||

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

theorem c0_proof : c0_before ⊑ c0_after

theorem e_1488 :
     - 6 * t - 1 *  ~~~z - 2 *  ~~~(z &&&  ~~~z) - 1 * (z ||| t) + 7 *  ~~~(z ^^^ t) + 1 *  ~~~(z &&& t) - 6 * (z ^^^ t) - 11 * (z |||  ~~~t) + 20 *  ~~~(z |||  ~~~t) + 19 * (z &&&  ~~~t) + 18 * (z &&& t) = 5 *  ~~~(z &&&  ~~~t) - 11 *  ~~~(z ||| t)

theorem scalar_i8_shl_ugt_const_thm (e : IntW 8) :
  icmp IntPred.ugt (shl e (const? 8 5)) (const? 8 63) ⊑
    icmp IntPred.ne (LLVM.and e (const? 8 6)) (const? 8 0)

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

theorem e_2330 :
    7 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 5 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 1 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 2 * (e ^^^ ( ~~~d ||| (e ||| f))) + 1 * (d ||| (e &&& f)) - 1 * ( ~~~d &&& ( ~~~e ||| f)) + 11 * (d |||  ~~~f) + 5 * ( ~~~f |||  ~~~(d ^^^ e)) + 2 * (f |||  ~~~(d ^^^ e)) - 1 * (f &&&  ~~~(d ^^^ e)) - 3 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 7 * d + 11 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 6 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 1 * ( ~~~d ||| (e ^^^ f)) + 1 * (d &&&  ~~~f) + 3 * ((d &&& f) ||| (e &&&  ~~~f)) - 2 * ( ~~~e ||| (d ^^^ f)) + 3 * (d ^^^ (e &&& f)) - 1 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 11 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 11 * (e ^^^  ~~~(d &&& f)) + 3 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 7 * (f ^^^  ~~~(d &&& e)) + 4 * (e &&&  ~~~(d ^^^ f)) + 5 * (e ||| (d &&& f)) + 4 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 *  ~~~(d ||| ( ~~~e &&& f)) + 11 * (e |||  ~~~(d |||  ~~~f)) + 1 * ((e &&& f) ||| (d &&& (e ||| f))) - 2 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 *  ~~~(d &&& ( ~~~e &&& f)) - 6 * ( ~~~e &&& (d ^^^ f)) + 1 * (e &&&  ~~~f) + 1 *  ~~~(d &&& (e ^^^ f)) - 2 * (f ||| (d &&&  ~~~e)) - 7 * (f ^^^  ~~~(d ||| (e &&& f))) - 3 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) + 2 * (e ^^^ (d ||| ( ~~~e &&& f))) - 2 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 4 *  ~~~(d &&& (e &&& f)) - 1 * (e ^^^ (d &&& (e ||| f))) - 3 * (d ^^^ f) + 3 * ((d ^^^ e) &&& (d ^^^ f)) - 5 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 2 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) - 5 * (f ||| (d &&& e)) - 11 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 1 *  ~~~(e ^^^ f) - 11 *  ~~~(d |||  ~~~e) - 3 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 2 * (e &&& (d ^^^ f)) - 11 * (e ^^^ ( ~~~d ||| (e &&& f))) - 2 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 5 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 13 *  ~~~(d ||| (e ||| f)) - 39 *  ~~~(d ||| ( ~~~e ||| f)) + 35 *  ~~~( ~~~d ||| (e ||| f)) - 33 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 29 * ( ~~~d &&& ( ~~~e &&& f)) + 10 * ( ~~~d &&& (e &&& f)) - 15 * (d &&& ( ~~~e &&& f)) + 10 * (d &&& (e &&& f)) =  - 1 * ( ~~~d ||| (e &&& f))

theorem test2_proof : test2_before ⊑ test2_after

theorem n9_wrong_x1_proof : n9_wrong_x1_before ⊑ n9_wrong_x1_after

theorem a_false_implies_b_false2_comm_thm.extracted_1._6 : ∀ (x x_1 : BitVec 1) (x_2 : BitVec 8),
  ofBool (20#8 <ᵤ x_2) = 1#1 → ¬ofBool (10#8 <ᵤ x_2) = 1#1 → x_1 ||

theorem logical_and_implies_folds_proof : logical_and_implies_folds_before ⊑ logical_and_implies_folds_after

theorem same_signbit_wrong_type_signed_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 8),
  ¬7#8 ≥ ↑8 →
    ofBool (x_1.sshiftRight' 7#8 != signExtend 8 (ofBool (-1#32 <ₛ x))) = ofBool (x_1 <ₛ 0#8) ^^^ ofBool (-1#32 <ₛ x)

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

theorem and_or_not_not_wrong_b_proof : and_or_not_not_wrong_b_before ⊑ and_or_not_not_wrong_b_after

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

theorem test24_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (1#32 <ₛ x) &&& ofBool (x != 2#32) = ofBool (2#32 <ₛ x)

theorem test87_proof : test87_before ⊑ test87_after

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

theorem src_is_notmask_x_xor_neg_x_thm.extracted_1._3 : ∀ (x : BitVec 8) (x_1 : BitVec 1) (x_2 : BitVec 8),
  ¬x_1 = 1#1 → ofBool ((x_2 ^^^ 123#8) &&& BitVec.ofInt 8 (-8) == 0#8) = ofBool (x_2 ^^^ 123#8 ≤ᵤ 7#8)

theorem PR60818_sgt_thm (e : IntW 32) :
  icmp IntPred.sgt (sub (const? 32 0) e) e ⊑ icmp IntPred.slt e (sub (const? 32 0) e)

theorem mkCarryAssignCircuitNAux_eval_eq_ {arity : Type _}
    [DecidableEq arity]
    [Fintype arity]
    [Hashable arity]
    (p : FSM arity) (s : p.α) (n : Nat)
    {env : Vars p.α arity (n + 1) → Bool}
    {env' : p.α ⊕ arity → Bool}
    (hEnvState : ∀ (s : p.α), env (Vars.stateN s n) = env' (Sum.inl s))
    (hEnvInput : ∀ (i : arity), env (Vars.inputN i n) = env' (Sum.inr i)) :
    ((mkCarryAssignCircuitNAux p s n).eval env) = ((p.nextStateCirc s).eval env')

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

theorem e_1324 :
     - 1 * z - 1 * t + 7 * (z ^^^ t) - 11 *  ~~~(z &&&  ~~~z) - 11 *  ~~~(z ^^^ t) + 3 *  ~~~(z &&& t) - 3 * (z ||| t) + 19 *  ~~~(z ||| t) + 5 * (z &&&  ~~~t) =  - 5 *  ~~~(z |||  ~~~t) - 27 * (z &&& t)

theorem add_select_sext_proof : add_select_sext_before ⊑ add_select_sext_after

theorem test15_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → ¬2#45 ≥ ↑45 → 3#45 <<< 2#45 = 12#45

theorem PR42691_5_proof : PR42691_5_before ⊑ PR42691_5_after

theorem or_eq_with_diff_one_logical_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬ofBool (x == 13#8) = 1#1 → ofBool (x == 14#8) = ofBool (x + BitVec.ofInt 8 (-13) <ᵤ 2#8)

theorem mul_select_sext_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → 1#64 * signExtend 64 x = 0#64

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

theorem select_icmp_slt_zero_smin_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x <ₛ 0#8) = 1#1 → x = x ||

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

theorem PR42691_7_logical_proof : PR42691_7_logical_before ⊑ PR42691_7_logical_after

theorem ashrslt_01_15_proof : ashrslt_01_15_before ⊑ ashrslt_01_15_after

theorem shl_add_lshr_comm_thm (e e_1 e_2 : IntW 32) :
  lshr (add (mul e_2 e_2) (shl e_1 e { «nsw» := false, «nuw» := true }) { «nsw» := false, «nuw» := true }) e ⊑
    add (lshr (mul e_2 e_2) e) e_1 { «nsw» := false, «nuw» := true }

theorem n11_proof : n11_before ⊑ n11_after

theorem lshrugt_01_02_thm (e : IntW 4) :
  icmp IntPred.ugt (lshr e (const? 4 1)) (const? 4 2) ⊑ icmp IntPred.ugt e (const? 4 5)

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

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

theorem ashrsgt_01_03_proof : ashrsgt_01_03_before ⊑ ashrsgt_01_03_after

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

@[simp]
lemma env_dec_image : enc '' (dec '' S) = S

theorem e_2365 :
    1 * (f ^^^ (d &&& (e ||| f))) + 3 *  ~~~(d ^^^ (e ^^^ f)) + 1 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 2 * ( ~~~f ||| (d ^^^ e)) + 1 * (d ^^^ e) - 2 * (d ||| (e ||| f)) - 1 *  ~~~e + 1 * (e ||| (d ^^^ f)) + 11 *  ~~~(d &&&  ~~~e) - 6 *  ~~~(d &&&  ~~~d) + 1 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 * (e ^^^ (d ||| ( ~~~e &&& f))) + 3 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 7 *  ~~~(e ||| f) + 1 * (e ^^^ (d ||| (e ^^^ f))) + 2 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * (f ^^^ (d &&&  ~~~e)) - 3 * ((d ^^^ e) &&& (d ^^^ f)) + 2 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 7 *  ~~~(d &&& f) - 2 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 5 *  ~~~(d &&& e) - 1 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 2 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 3 *  ~~~(d |||  ~~~e) + 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 7 * (f ^^^ (d &&& ( ~~~e ||| f))) + 3 * (f |||  ~~~(d ||| e)) - 1 * (e ^^^ (d ||| ( ~~~e ||| f))) - 1 * ( ~~~d ||| (e ^^^ f)) + 11 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 * (f ^^^ (d ||| ( ~~~e ||| f))) - 3 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 1 *  ~~~(e ^^^ f) - 11 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 4 * (d ||| (e &&& f)) - 3 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 1 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 5 * (e |||  ~~~(d |||  ~~~f)) - 5 * (e ^^^ (d |||  ~~~f)) + 1 * (f |||  ~~~(d ^^^ e)) - 7 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 1 * (f &&&  ~~~(d &&&  ~~~e)) + 7 * (f ^^^  ~~~(d |||  ~~~e)) + 3 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 6 * ((d ||| e) &&& (e ^^^ f)) - 2 * (e ^^^  ~~~(d |||  ~~~f)) + 1 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 5 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 5 * (d ^^^ ( ~~~e ||| f)) + 4 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 5 * (e &&& (d |||  ~~~f)) - 3 * (e ^^^  ~~~(d &&& (e ||| f))) + 7 * ( ~~~d ||| (e ||| f)) + 2 * ( ~~~d ||| ( ~~~e &&& f)) - 11 * ( ~~~d &&& (e ||| f)) - 3 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 1 * (d ||| e) + 7 * (d ^^^ (e ^^^ f)) + 7 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 7 * (d ||| f) + 10 *  ~~~(d ||| (e ||| f)) - 20 *  ~~~(d ||| ( ~~~e ||| f)) + 40 *  ~~~( ~~~d ||| (e ||| f)) + 7 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 7 * ( ~~~d &&& ( ~~~e &&& f)) - 15 * ( ~~~d &&& (e &&& f)) + 17 * (d &&& ( ~~~e &&& f)) - 34 * (d &&& (e &&& f)) =  - 3 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f)))

theorem sgt_swap_and_not_min_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 <ₛ x) = 1#1 → ofBool (x != BitVec.ofInt 8 (-128)) = ofBool (x_1 <ₛ x)

theorem e_119 :
    7 * y - 11 *  ~~~y + 9 *  ~~~(x ||| y) - 7 *  ~~~(x |||  ~~~y) + 8 * (x &&&  ~~~y) - 12 * (x &&& y) =  - 2 *  ~~~(x ^^^ y) - 3 * x

theorem FSM.or_eq (a b : FSM arity) : (a ||| b) = composeBinaryAux' FSM.or a b

theorem sdiv_mul_shl_nsw_thm (e e_1 e_2 : IntW 5) :
  LLVM.sdiv (mul e_2 e_1 { «nsw» := true, «nuw» := false }) (shl e_2 e { «nsw» := true, «nuw» := false }) ⊑
    LLVM.sdiv e_1 (shl (const? 5 1) e { «nsw» := false, «nuw» := true })

theorem and_zext_demanded_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 32),
  ¬8#16 ≥ ↑16 → 8#16 ≥ ↑16 ∨ True ∧ (x >>> 8#16).msb = true → False

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

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

theorem test2_proof : test2_before ⊑ test2_after

theorem AndZextAnd_proof : AndZextAnd_before ⊑ AndZextAnd_after

theorem e_1142 :
     - 1 *  ~~~(z &&&  ~~~z) + 1 * t - 11 * (z ^^^ t) - 2 *  ~~~(z ^^^ t) + 8 *  ~~~(z ||| t) + 16 *  ~~~(z |||  ~~~t) + 17 * (z &&&  ~~~t) + 2 * (z &&& t) = 5 *  ~~~(z &&& t)

@[simp] theorem Com.changeDialect_rets (f : DialectMorphism d d') (vs) :
    Com.changeDialect f (Com.rets vs : Com d Γ eff t)
    = Com.rets (vs.map' f.mapTy (fun _ v => v.toMap))

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

theorem reused_mul_nuw_xy_z_selectnonzero_ugt_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 != 0#8) = 1#1 → ¬ofBool (x_1 == 0#8) = 1#1 → ¬(True ∧ x.umulOverflow x_1 = true) → False

theorem rem_euclid_non_const_pow2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(x ≥ ↑8 ∨ (1#8 <<< x == 0 || 8 != 1 && x_1 == intMin 8 && 1#8 <<< x == -1) = true) →
    ofBool (x_1.srem (1#8 <<< x) <ₛ 0#8) = 1#1 →
      ¬(x ≥ ↑8 ∨ (1#8 <<< x == 0 || 8 != 1 && x_1 == intMin 8 && 1#8 <<< x == -1) = true ∨ x ≥ ↑8) →
        True ∧ ((-1#8) <<< x).sshiftRight' x ≠ -1#8 ∨ x ≥ ↑8 → False

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

@[bv_multi_width_normalize]
theorem Nat.le_of_not_lt (v w : Nat) : ¬ (v < w) ↔ w ≤ v

theorem e_248 :
     - 5 * (x ^^^ y) - 1 * (x ||| y) - 7 *  ~~~x + 11 *  ~~~y - 4 *  ~~~(x ||| y) + 13 *  ~~~(x |||  ~~~y) + 1 * (x &&& y) = 5 * (x &&&  ~~~y)

theorem positive_samevar_shlnuwnsw_ashrexact_proof : positive_samevar_shlnuwnsw_ashrexact_before ⊑ positive_samevar_shlnuwnsw_ashrexact_after

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

theorem test22_logical_proof : test22_logical_before ⊑ test22_logical_after

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 t0_const_lshr_shl_ne_proof : t0_const_lshr_shl_ne_before ⊑ t0_const_lshr_shl_ne_after

theorem lshrult_03_12_proof : lshrult_03_12_before ⊑ lshrult_03_12_after

theorem icmp_eq_and_pow2_shl1_proof : icmp_eq_and_pow2_shl1_before ⊑ icmp_eq_and_pow2_shl1_after

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

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

theorem no_shift_no_xor_multiuse_xor_proof : no_shift_no_xor_multiuse_xor_before ⊑ no_shift_no_xor_multiuse_xor_after

@[grind =, simp, aesop 50% unsafe]
lemma states_addManyTrans (m : RawCNFA A) (as : List A) (s1 s2 : State) :
    (m.addManyTrans as s1 s2).states = m.states

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

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

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

theorem test42_proof : test42_before ⊑ test42_after

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

theorem trunc_shl_nsw_31_i32_i64_proof : trunc_shl_nsw_31_i32_i64_before ⊑ trunc_shl_nsw_31_i32_i64_after

theorem shl_add_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ x + 1#8 ≥ ↑8) → ¬x ≥ ↑8 → 16#8 <<< x + 7#8 <<< (x + 1#8) = 30#8 <<< x

theorem icmp_ne_zext_ne_zero_proof : icmp_ne_zext_ne_zero_before ⊑ icmp_ne_zext_ne_zero_after

theorem cast_test_2002h08h02_proof : cast_test_2002h08h02_before ⊑ cast_test_2002h08h02_after

theorem test1_proof : test1_before ⊑ test1_after

theorem test_sub_4_Y_ne_4_proof : test_sub_4_Y_ne_4_before ⊑ test_sub_4_Y_ne_4_after

theorem narrow_sext_xor_proof : narrow_sext_xor_before ⊑ narrow_sext_xor_after

theorem no_shift_xor_multiuse_cmp_and_proof : no_shift_xor_multiuse_cmp_and_before ⊑ no_shift_xor_multiuse_cmp_and_after

theorem test15_thm (e : IntW 8) : LLVM.and (lshr e (const? 8 7)) (const? 8 2) ⊑ const? 8 0

theorem test3_proof : test3_before ⊑ test3_after

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

theorem t2_ult_sgt_65536_thm.extracted_1._5 : ∀ (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_1 = x

theorem negative4_proof : negative4_before ⊑ negative4_after

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

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

theorem gt_unsigned_to_large_negative_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (BitVec.ofInt 32 (-1024) <ₛ zeroExtend 32 x) = 1#1

theorem mul_splat_fold_no_nuw_proof : mul_splat_fold_no_nuw_before ⊑ mul_splat_fold_no_nuw_after

theorem mul_of_pow2_commute_proof : mul_of_pow2_commute_before ⊑ mul_of_pow2_commute_after

theorem select_icmp_ne_pow2_flipped_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬ofBool (x &&& 4#8 != 0#8) = 1#1 → x ^^^ 4#8 = x ||

theorem slt_swap_and_max_logical_proof : slt_swap_and_max_logical_before ⊑ slt_swap_and_max_logical_after

theorem icmp_slt_0_or_icmp_add_1_sge_100_i32_fail_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 →
    x >>> 31#32 ||

lemma NFA'.autEq_correct : autEq.correct2 (fun _ => eqRel) eqRel

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

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

theorem addhshlhsdivhscalar2_thm (e : IntW 32) :
  add (shl (LLVM.sdiv e (const? 32 (-1073741824))) (const? 32 30)) e ⊑ LLVM.srem e (const? 32 1073741824)

theorem ne_umax4_proof : ne_umax4_before ⊑ ne_umax4_after

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

theorem foo1_and_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 test69_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 128#32 != 0#32) = 1#1 → 6#32 ≥ ↑32 → False

@[simp]
lemma accepts_cast {M : NFA α σ} (h : σ = ς): (h ▸ M).accepts = M.accepts

theorem test_add__none_are_safe_proof : test_add__none_are_safe_before ⊑ test_add__none_are_safe_after

theorem or_ne_notY_eq_1s_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 ||| x ^^^ -1#8 != x_1) = ofBool (x_1 ||| x != -1#8)

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

theorem select_icmp_ne_0_and_8_and_not_1073741824_thm (e : IntW 32) (e_1 : IntW 8) :
  select (icmp IntPred.ne (const? 8 0) (LLVM.and e_1 (const? 8 8))) e (LLVM.and e (const? 32 (-1073741825))) ⊑
    select (icmp IntPred.eq (LLVM.and e_1 (const? 8 8)) (const? 8 0)) (LLVM.and e (const? 32 (-1073741825)))
      e

theorem n11_wrong_pred3_proof : n11_wrong_pred3_before ⊑ n11_wrong_pred3_after

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

theorem same_source_not_matching_signbits_proof : same_source_not_matching_signbits_before ⊑ same_source_not_matching_signbits_after

theorem eq_21_comm_eq2_proof : eq_21_comm_eq2_before ⊑ eq_21_comm_eq2_after

theorem test3_proof : test3_before ⊑ test3_after

theorem cmpeq_xor_cst1_commuted_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 * x_1 == x ^^^ 10#32) = ofBool (x ^^^ x_1 * x_1 == 10#32)

theorem main3e_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 → ofBool (x_2 &&& x == 0#32) = 1#1 → 0#32 = zeroExtend 32 1#1

theorem foo1_and_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 ∧ 1#32 <<< x >>> x ≠ 1#32 ∨
            x ≥ ↑32 ∨ True ∧ 1#32 <<< x_2 >>> x_2 ≠ 1#32 ∨ x_2 ≥ ↑32 ∨ True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨ x ≥ ↑32 →
      False

theorem scalar_i32_shl_and_signbit_eq_proof : scalar_i32_shl_and_signbit_eq_before ⊑ scalar_i32_shl_and_signbit_eq_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_2_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_2_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_2_logical_after

theorem lor_band_left2_proof : lor_band_left2_before ⊑ lor_band_left2_after

theorem xor_icmp_to_ne_proof : xor_icmp_to_ne_before ⊑ xor_icmp_to_ne_after

theorem ule_and_min_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == 0#8) &&& ofBool (x_1 ≤ᵤ x) = ofBool (x_1 == 0#8)

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

theorem lshr_lshr_pow2_const_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(x ≥ ↑16 ∨ 6#16 ≥ ↑16) → ofBool (x == 3#16) = 1#1 → 2048#16 >>> x >>> 6#16 &&& 4#16 = 4#16

theorem zext_sext_add_icmp_ne_minus1_proof : zext_sext_add_icmp_ne_minus1_before ⊑ zext_sext_add_icmp_ne_minus1_after

theorem trunc_lshr_zext_proof : trunc_lshr_zext_before ⊑ trunc_lshr_zext_after

@[simp]
theorem Factor.reflectFin_width_zero  (f : Factor) (env : EnvFin 0 f.numVars) : f.reflectFin env = 0#0

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

theorem e_1410 :
     - 6 * z - 3 *  ~~~z - 11 * (z ^^^ t) - 5 *  ~~~(z &&&  ~~~t) - 1 * t - 1 *  ~~~(z &&& t) + 7 *  ~~~(z ||| t) + 21 *  ~~~(z |||  ~~~t) + 18 * (z &&&  ~~~t) + 10 * (z &&& t) =  - 2 *  ~~~(z ^^^ t)

theorem demorgan_nor_use2ab_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬((x * 23#8 == 0 || 8 != 1 && (x_1 ^^^ -1#8 ||| x) ^^^ -1#8 == intMin 8 && x * 23#8 == -1) = true ∨
        ((x_1 ^^^ -1#8) * 17#8 == 0 ||
            8 != 1 && ((x_1 ^^^ -1#8 ||| x) ^^^ -1#8).sdiv (x * 23#8) == intMin 8 && (x_1 ^^^ -1#8) * 17#8 == -1) =
          true) →
    ¬((x * 23#8 == 0 || 8 != 1 && x_1 &&& (x ^^^ -1#8) == intMin 8 && x * 23#8 == -1) = true ∨
          ((x_1 ^^^ -1#8) * 17#8 == 0 ||
              8 != 1 && (x_1 &&& (x ^^^ -1#8)).sdiv (x * 23#8) == intMin 8 && (x_1 ^^^ -1#8) * 17#8 == -1) =
            true) →
      (((x_1 ^^^ -1#8 ||| x) ^^^ -1#8).sdiv (x * 23#8)).sdiv ((x_1 ^^^ -1#8) * 17#8) =
        ((x_1 &&& (x ^^^ -1#8)).sdiv (x * 23#8)).sdiv ((x_1 ^^^ -1#8) * 17#8)

@[grind =, simp]
lemma addInitial_stateMax {m : RawCNFA A} : (m.addInitial s).stateMax = m.stateMax

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

theorem negative_with_wrong_mask_logical_proof : negative_with_wrong_mask_logical_before ⊑ negative_with_wrong_mask_logical_after

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

@[simp] theorem Com.returnVars_var :
    returnVars (var (d:=d) (eff:=eff) e body) = body.returnVars

theorem alive_AndOrXor_2595  (w : Nat)   : alive_AndOrXor_2595_src w  ⊑ alive_AndOrXor_2595_tgt w

theorem trunc_lshr_sext_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬6#32 ≥ ↑32 → ¬6#8 ≥ ↑8 → truncate 8 (signExtend 32 x >>> 6#32) = x.sshiftRight' 6#8

theorem negate_add_with_single_negatible_operand_proof : negate_add_with_single_negatible_operand_before ⊑ negate_add_with_single_negatible_operand_after

theorem e_586 :
     - 1 *  ~~~y + 11 * (x ^^^ y) - 5 *  ~~~(x ^^^ y) + 3 *  ~~~(x &&& y) + 1 * y + 1 * (x |||  ~~~y) - 17 *  ~~~(x |||  ~~~y) - 16 * (x &&&  ~~~y) + 1 * (x &&& y) =  - 2 *  ~~~(x &&&  ~~~x)

lemma RawCNFA.autMsbSet_wf : autMsbSet.WF

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

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

theorem sext_zext_apint2_thm.extracted_1._1 : ∀ (x : BitVec 11), signExtend 47 (zeroExtend 39 x) = zeroExtend 47 x

theorem shl2 : ∀ (w : Nat) (x : BitVec w), x <<< (1 : Nat) = x + x

theorem ne_and_lshr_minval_proof : ne_and_lshr_minval_before ⊑ ne_and_lshr_minval_after

@[simp]
theorem toCons_toMap {Γ : Ctxt Ty} {t : Ty} {var : Ctxt.Var Γ t'} {f : Ty → Ty₂} :
    var.toCons.toMap (Γ := Γ.cons t) (f := f) = var.toMap.toCons

theorem substitute_constant_and_eq_ugt_swap_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.ugt e_1 e) (icmp IntPred.eq e (const? 8 42)) ⊑
    LLVM.and (icmp IntPred.eq e (const? 8 42)) (icmp IntPred.ugt e_1 (const? 8 42))

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

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

theorem test4_thm (e e_1 : IntW 32) :
  zext 32 (zext 8 (icmp IntPred.slt e_1 e)) ⊑ zext 32 (icmp IntPred.slt e_1 e)

theorem icmp_sgt8_proof : icmp_sgt8_before ⊑ icmp_sgt8_after

@[grind ., simp, aesop 50% unsafe]
lemma mem_states_newState (m : RawCNFA A) (s : State) (hin : s ∈ m.states) :
    s ∈ m.newState.2.states

theorem icmp_sgt8_thm (e : IntW 8) :
  icmp IntPred.sgt (shl e (const? 8 1) { «nsw» := true, «nuw» := false }) (const? 8 125) ⊑
    icmp IntPred.eq e (const? 8 63)

theorem t1_proof : t1_before ⊑ t1_after

theorem test0_thm (e : IntW 39) : LLVM.and e (const? 39 0) ⊑ const? 39 0

theorem not_true_not_thm (e e_1 : IntW 1) :
  select (LLVM.xor e_1 (const? 1 1)) (const? 1 1) (LLVM.xor e (const? 1 1)) ⊑
    LLVM.xor (select e_1 e (const? 1 0)) (const? 1 1)

theorem exactly_one_set_signbit_signed_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬7#8 ≥ ↑8 → ofBool (x_1.sshiftRight' 7#8 == signExtend 8 (ofBool (-1#8 <ₛ x))) = ofBool (x_1 ^^^ x <ₛ 0#8)

theorem and_ne_with_diff_one_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x != 40#32) &&& ofBool (x != 39#32) = ofBool (x + BitVec.ofInt 32 (-41) <ᵤ BitVec.ofInt 32 (-2))

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

theorem andn_or_cmp_4_logical_proof : andn_or_cmp_4_logical_before ⊑ andn_or_cmp_4_logical_after

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

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

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

theorem bools_multi_uses2_logical_proof : bools_multi_uses2_logical_before ⊑ bools_multi_uses2_logical_after

theorem lshrugt_01_01_proof : lshrugt_01_01_before ⊑ lshrugt_01_01_after

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

theorem e_2327 :
    1 * ((d ^^^ e) ||| (d ^^^ f)) - 1 *  ~~~(d ^^^ ( ~~~e &&& f)) - 5 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 2 * ( ~~~f &&& (d ^^^ e)) + 1 * (e ^^^ f) + 1 *  ~~~d + 11 * (d ||| (e ^^^ f)) + 1 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 7 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 2 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 2 * (e |||  ~~~(d |||  ~~~f)) + 7 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 6 *  ~~~(d ||| (e &&& f)) - 2 * (f ^^^ ( ~~~d &&& (e ||| f))) + 4 * ( ~~~d ||| (e &&& f)) - 11 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 5 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 5 * ( ~~~f ||| (d ^^^ e)) + 7 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 3 *  ~~~(d &&& ( ~~~e &&& f)) + 1 * (e ^^^  ~~~(d ||| (e &&& f))) + 7 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 6 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 1 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 3 * (f ^^^ (d ||| (e ||| f))) + 1 * (f ^^^  ~~~(d &&& (e &&& f))) - 2 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 4 * (d &&& (e ^^^ f)) + 2 *  ~~~(d &&&  ~~~d) - 7 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * (e &&&  ~~~(d &&& f)) + 5 * (f ||| (d &&& e)) + 3 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 4 *  ~~~(d &&&  ~~~e) - 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 2 *  ~~~(d &&& ( ~~~e ||| f)) + 7 * (d ^^^ ( ~~~e ||| f)) - 2 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 2 *  ~~~(d &&& e) + 5 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 5 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 2 *  ~~~(d &&& (e ^^^ f)) + 1 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 1 * (f ^^^  ~~~(d &&& e)) + 1 * (f ^^^ ( ~~~d ||| (e &&& f))) + 2 * (e ^^^ (d ||| (e &&& f))) - 5 * (e ^^^  ~~~(d &&& f)) - 11 * (e ||| (d &&& f)) - 3 * (e ^^^ (d |||  ~~~f)) - 1 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * (e ^^^ (d &&&  ~~~f)) - 11 * (f ||| (d ^^^ e)) - 1 * (d &&& f) + 1 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 2 * (e &&&  ~~~(d ^^^ f)) + 5 * ( ~~~d ||| (e ^^^ f)) + 11 *  ~~~(e &&& f) - 11 *  ~~~(d ||| (e ||| f)) - 21 *  ~~~(d ||| ( ~~~e ||| f)) - 23 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 32 * ( ~~~d &&& ( ~~~e &&& f)) - 4 * ( ~~~d &&& (e &&& f)) - 6 * (d &&& ( ~~~e &&& f)) + 2 * (d &&& (e &&& f)) =  - 4 * (e &&& (d ^^^ f)) + 6 * (f ^^^ (d &&& (e ||| f)))

theorem lshrult_02_00_proof : lshrult_02_00_before ⊑ lshrult_02_00_after

theorem narrow_zext_xor_proof : narrow_zext_xor_before ⊑ narrow_zext_xor_after

theorem test_add__nsw_is_safe_proof : test_add__nsw_is_safe_before ⊑ test_add__nsw_is_safe_after

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 flip_masked_bit_proof : flip_masked_bit_before ⊑ flip_masked_bit_after

theorem eval_congrEnv {p : FSM arity}
    {x y : arity → BitStream} {n : Nat} (h : ∀ a i, i ≤ n → x a i = y a i) :
    p.eval x n = p.eval y n

theorem positive_samevar_shlnuw_proof : positive_samevar_shlnuw_before ⊑ positive_samevar_shlnuw_after

theorem lor_lor_right2_thm (e e_1 : IntW 1) :
  select e_1 (const? 1 1) (select e (const? 1 1) e_1) ⊑ select e_1 (const? 1 1) e

theorem and_signbit_ashr_proof : and_signbit_ashr_before ⊑ and_signbit_ashr_after

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

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

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

theorem or_xor_commute4_thm (e e_1 : IntW 32) :
  LLVM.xor (LLVM.udiv (const? 32 42) e_1) (LLVM.or (LLVM.udiv (const? 32 42) e) (LLVM.udiv (const? 32 42) e_1)) ⊑
    LLVM.and (LLVM.udiv (const? 32 42) e) (LLVM.xor (LLVM.udiv (const? 32 42) e_1) (const? 32 (-1)))

@[simp] theorem map'_nil : map' f g nil = nil

theorem add_zero (a : ZMod q) : a + 0 = a

@[simp]
theorem Term.width_ofDep_eq_ofDep {wcard tcard : Nat} (bcard : Nat)
    {w : MultiWidth.WidthExpr wcard}
    {tctx : Term.Ctx wcard tcard}
    (t : MultiWidth.Term bcard ncard icard pcard tctx (.bv w))
    : (Term.ofDepTerm t).width = (.ofDep w)

theorem or_ranges_single_elem_right_proof : or_ranges_single_elem_right_before ⊑ or_ranges_single_elem_right_after

theorem icmp_eq_mul_nuw_nonequal_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (mul e_1 e { «nsw» := false, «nuw» := true })
      (mul (add e_1 (const? 8 1)) e { «nsw» := false, «nuw» := true }) ⊑
    icmp IntPred.eq e (const? 8 0)

theorem test9_proof : test9_before ⊑ test9_after

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

theorem a_or_b_proof : a_or_b_before ⊑ a_or_b_after

theorem e_483 :
     - 7 *  ~~~(x &&&  ~~~y) + 11 *  ~~~(x ^^^ y) - 1 *  ~~~y + 4 *  ~~~x + 5 * (x |||  ~~~y) - 3 * x - 12 *  ~~~(x ||| y) + 4 *  ~~~(x |||  ~~~y) - 5 * (x &&& y) = 1 * (x ||| y)

theorem a_true_implies_b_true2_comm_thm (e e_1 : IntW 1) (e_2 : IntW 8) :
  LLVM.and (select (icmp IntPred.ugt e_2 (const? 8 10)) e_1 e) (icmp IntPred.ugt e_2 (const? 8 20)) ⊑
    select (icmp IntPred.ugt e_2 (const? 8 20)) e_1 (const? 1 0)

theorem or_xor_tree_0111_proof : or_xor_tree_0111_before ⊑ or_xor_tree_0111_after

theorem zext_sext_add_icmp_slt_2_proof : zext_sext_add_icmp_slt_2_before ⊑ zext_sext_add_icmp_slt_2_after

theorem alive_AddSub_1539_2 : alive_AddSub_1539_2_src ⊑ alive_AddSub_1539_2_tgt

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

theorem mul_of_bool_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (255#32 <ᵤ (x_1 &&& 255#32) * (x &&& 1#32)) = 0#1

theorem e_345 :
    1 *  ~~~y + 1 * y + 11 *  ~~~(x ^^^ y) + 7 *  ~~~(x &&& y) + 2 * (x ^^^ y) - 19 *  ~~~(x ||| y) - 10 *  ~~~(x |||  ~~~y) - 10 * (x &&&  ~~~y) = 12 * (x &&& y)

theorem src_is_mask_and_thm (e e_1 e_2 : IntW 8) :
  icmp IntPred.eq (LLVM.xor e_2 (const? 8 123))
      (LLVM.and (LLVM.xor e_2 (const? 8 123)) (LLVM.and (ashr (const? 8 7) e_1) (lshr (const? 8 (-1)) e))) ⊑
    icmp IntPred.ule (LLVM.xor e_2 (const? 8 123))
      (LLVM.and (lshr (const? 8 7) e_1) (lshr (const? 8 (-1)) e))

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

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

theorem trunc_lshr_sext_wide_input_proof : trunc_lshr_sext_wide_input_before ⊑ trunc_lshr_sext_wide_input_after

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

theorem alive_AddSub_1309  (w : Nat)   : alive_AddSub_1309_src w  ⊑ alive_AddSub_1309_tgt w

theorem samesign_proof : samesign_before ⊑ samesign_after

theorem main5_like_logical_thm.extracted_1._12 : ∀ (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 → 1#32 = zeroExtend 32 (ofBool (x &&& 7#32 != 7#32))

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

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 t3_exact_thm (e : IntW 64) :
  sub (const? 64 0) (ashr e (const? 64 63) { «exact» := true }) ⊑ lshr e (const? 64 63) { «exact» := true }

theorem ashrsgt_02_07_exact_proof : ashrsgt_02_07_exact_before ⊑ ashrsgt_02_07_exact_after

theorem add_smin_simplify_proof : add_smin_simplify_before ⊑ add_smin_simplify_after

@[simp] theorem matchVar_appendInr (w : Δ_out.Var t) :
    matchVar lets v (.var matchLets matchExpr) w.appendInr
    = matchVar lets v matchLets w

theorem c_0_1_0_thm (e e_1 e_2 : IntW 4) :
  LLVM.xor (LLVM.and (LLVM.xor e_2 e_1) (LLVM.xor e (const? 4 (-1)))) e_2 ⊑
    LLVM.xor (LLVM.and (LLVM.xor e_2 e_1) e) e_1

theorem main6c_thm (e : IntW 32) :
  select
      (LLVM.or (icmp IntPred.ne (LLVM.and e (const? 32 7)) (const? 32 3))
        (icmp IntPred.ne (LLVM.and e (const? 32 48)) (const? 32 16)))
      (const? 32 0) (const? 32 1) ⊑
    zext 32 (icmp IntPred.eq (LLVM.and e (const? 32 55)) (const? 32 19))

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

theorem test13commuted_proof : test13commuted_before ⊑ test13commuted_after

theorem p_constmask_proof : p_constmask_before ⊑ p_constmask_after

theorem test3_logical_proof : test3_logical_before ⊑ test3_logical_after

theorem XorZextXor_thm.extracted_1._1 : ∀ (x : BitVec 3), zeroExtend 5 (x ^^^ 3#3) ^^^ 12#5 = zeroExtend 5 x ^^^ 15#5

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

theorem trunc_equality_both_sext_proof : trunc_equality_both_sext_before ⊑ trunc_equality_both_sext_after

theorem slt_and_max_proof : slt_and_max_before ⊑ slt_and_max_after

theorem test67_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  ¬(True ∧ ((x_1 &&& (zeroExtend 32 x ^^^ 1#32)) <<< 24#32).sshiftRight' 24#32 ≠ x_1 &&& (zeroExtend 32 x ^^^ 1#32) ∨
        True ∧ (x_1 &&& (zeroExtend 32 x ^^^ 1#32)) <<< 24#32 >>> 24#32 ≠ x_1 &&& (zeroExtend 32 x ^^^ 1#32) ∨
          24#32 ≥ ↑32 ∨
            True ∧
                ((x_1 &&& (zeroExtend 32 x ^^^ 1#32)) <<< 24#32 ^^^ BitVec.ofInt 32 (-16777216)) >>> 24#32 <<< 24#32 ≠
                  (x_1 &&& (zeroExtend 32 x ^^^ 1#32)) <<< 24#32 ^^^ BitVec.ofInt 32 (-16777216) ∨
              24#32 ≥ ↑32) →
    ofBool
        (truncate 8
            (((x_1 &&& (zeroExtend 32 x ^^^ 1#32)) <<< 24#32 ^^^ BitVec.ofInt 32 (-16777216)).sshiftRight' 24#32) ==
          0#8) =
      0#1

theorem positive_biggershl_shlnuwnsw_proof : positive_biggershl_shlnuwnsw_before ⊑ positive_biggershl_shlnuwnsw_after

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

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

theorem negate_add_with_single_negatible_operand_depth2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  0#8 - (x_1 + 21#8) * x = (BitVec.ofInt 8 (-21) - x_1) * x

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

theorem lt_unsigned_to_large_signed_proof : lt_unsigned_to_large_signed_before ⊑ lt_unsigned_to_large_signed_after

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

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

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

theorem bools_logical_commute1_thm (e e_1 e_2 : IntW 1) :
  select (select e_2 (LLVM.xor e_1 (const? 1 1)) (const? 1 0)) (const? 1 1) (select e_1 e (const? 1 0)) ⊑
    select e_1 e e_2

theorem lshr_sub_thm (e e_1 : IntW 8) :
  shl (sub (LLVM.srem e_1 (const? 8 42)) (lshr e (const? 8 3))) (const? 8 3) ⊑
    shl (sub (LLVM.srem e_1 (const? 8 42)) (lshr e (const? 8 3)) { «nsw» := true, «nuw» := false })
      (const? 8 3)

theorem icmp_eq_and1_lshr_pow2_thm (e : IntW 32) :
  zext 32 (icmp IntPred.eq (LLVM.and (lshr (const? 32 8) e) (const? 32 1)) (const? 32 0)) ⊑
    zext 32 (icmp IntPred.ne e (const? 32 3))

theorem slt_zero_ne_ne_b_proof : slt_zero_ne_ne_b_before ⊑ slt_zero_ne_ne_b_after

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

@[simp] theorem dropUntilHom_toCons {v : Var Γ t} :
  dropUntilHom (v := v.toCons (t' := t')) = (dropUntilHom (v:=v)).consRight

theorem test_ne_0_and_15_add_3_proof : test_ne_0_and_15_add_3_before ⊑ test_ne_0_and_15_add_3_after

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

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

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

theorem denote_matchArg
    {vs ws : HVector (Var _) ts}
    (mapOut : MatchArgResult lets matchLets vs ws mapIn)
    (V : lets.ValidDenotation) :
    HVector.map (matchLets.denote (mapOut.val.mapValuation V.val)) ws = HVector.map (V.val) vs

theorem e_1501 :
    1 * (c &&&  ~~~(a &&& b)) + 1 *  ~~~(a |||  ~~~c) + 7 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) - 7 *  ~~~(a ||| ( ~~~b ||| c)) - 2 * ( ~~~a &&& ( ~~~b &&& c)) - 9 * ( ~~~a &&& (b &&& c)) - 1 * (a &&& ( ~~~b &&& c)) = 7 * (a &&& (b &&& c)) + 7 *  ~~~(a ||| (b ||| c))

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

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

theorem test4_proof : test4_before ⊑ test4_after

theorem test_or4_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 2147483647#32 <ₛ x) = 1#1 → ofBool (x <ₛ 0#32) = ofBool (x_1 &&& 2147483647#32 <ᵤ x)

theorem test3_proof : test3_before ⊑ test3_after

theorem sgt_negative_multip_rem_zero_thm (e : IntW 8) :
  icmp IntPred.sgt (mul e (const? 8 (-7)) { «nsw» := true, «nuw» := false }) (const? 8 21) ⊑
    icmp IntPred.slt e (const? 8 (-3))

theorem shl_nsw_add_nuw_proof : shl_nsw_add_nuw_before ⊑ shl_nsw_add_nuw_after

theorem sdiv_x_by_const_cmp_x_proof : sdiv_x_by_const_cmp_x_before ⊑ sdiv_x_by_const_cmp_x_after

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

theorem foo3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1), ¬x = 0 → x_1 / x = x_1

theorem shift_no_xor_multiuse_or_proof : shift_no_xor_multiuse_or_before ⊑ shift_no_xor_multiuse_or_after

theorem test_proof : test_before ⊑ test_after
</all_available_lemmas>

<local_ctx>
import Blase.Fast.FiniteStateMachine

import Blase.Vars

import Blase.MultiWidth.Defs

import Blase.KInduction.KInduction

import Lean

namespace MultiWidth

def fsmMsb (x w : FSM α) : FSM α :=
  composeBinaryAux'
    (FSM.latchImmediate false)
    (qfalse := x)
    (qtrue := w)

def fsmCarry'' (initialCarryVal : Bool): FSM Bool :=
  let outputCirc :=
    let carry := Circuit.var true (Sum.inl ())
    let a := Circuit.var true (Sum.inr true)
    let b := Circuit.var true (Sum.inr false)
    
    ((a &&& b) ||| (a &&& carry) ||| (b &&& carry))
  { α := Unit,
    
    
    initCarry := fun () => initialCarryVal, 
    outputCirc := Circuit.var true (Sum.inl ()) ,
    nextStateCirc := fun () => outputCirc
  }

def fsmMsbEq (a : FSM α) (b : FSM α) : FSM α :=
  composeUnaryAux (FSM.ls false) <|
    composeBinaryAux' FSM.xor a b

def fsmTermSle
  {wcard tcard : Nat}
  {w : Nondep.WidthExpr}
  {a b : Nondep.Term}
  (wfsm : NatFSM wcard tcard bcard ncard icard pcard w)
  (afsm : TermFSM wcard tcard bcard ncard icard pcard a)
  (bfsm : TermFSM wcard tcard bcard ncard icard pcard b)
  : FSM (StateSpace wcard tcard bcard ncard icard pcard) :=
    let afsm := afsm.toFsmZext
    let bfsm := bfsm.toFsmZext
    let afsm := fsmMsb afsm wfsm.toFsm
    let bfsm := fsmMsb bfsm wfsm.toFsm
    let carryFsm :=
      ((composeBinaryAux' (fsmCarry'' true)  bfsm (~~~ afsm)))
    let xorFsm := fsmMsbEq afsm bfsm
    ~~~ ((~~~ xorFsm) ^^^ carryFsm)
</local_ctx>

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

