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>
DecidableEq in Init.Prelude
Lean.ToExpr in Lean.ToExpr
List in Init.Prelude
Repr in Init.Data.Repr
Nat in Init.Prelude
AList in Mathlib.Data.List.AList
Option in Init.Prelude
StateT in Init.Control.State
Unit in Init.Prelude
String in Init.Prelude
BEq in Init.Prelude
ite in Init.Prelude
Vector in Init.Data.Vector.Basic
Bool in Init.Prelude
Int in Init.Data.Int.Basic
bool in Init.Control.Basic
Computation in Mathlib.Data.Seq.Computation
AList.insert in Mathlib.Data.List.AList
Valuation.map in Mathlib.RingTheory.Valuation.Basic
Exists in Init.Core
Id in Init.Control.Id
List.map in Init.Prelude
Polynomial.X in Mathlib.Algebra.Polynomial.Basic
ZMod in Mathlib.Data.ZMod.Defs
Sigma in Init.Core
Sigma.mk in Init.Core
liftM in Init.Prelude
Iff in Init.Core
IsEmpty in Mathlib.Logic.IsEmpty
id in Init.Prelude
PUnit in Init.Prelude
Pure in Init.Prelude
HEq in Init.Prelude

syntax "neg" : MLIR.Pretty.uniform_op

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

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

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

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

abbrev Mapping (Γ Δ : Ctxt Ty) : Type :=
  @AList (Σ t, Var Γ t) (fun x => Var Δ x.1)

structure Ctxt (Ty : Type) : Type where
  ofList :: toList : List Ty
  
  deriving Repr, Lean.ToExpr, DecidableEq

def Var (Γ : Ctxt Ty) (t : Ty) : Type :=
  { i : Nat // Γ[i]? = some t }

inductive Lets (Γ_in : Ctxt d.Ty) (eff : EffectKind) :
    (Γ_out : Ctxt d.Ty) → Type where
  | nil : Lets Γ_in eff Γ_in
  | var (body : Lets Γ_in eff Γ_out) (e : Expr d Γ_out eff t) : Lets Γ_in eff e.outContext

protected instance Expr.decidableEq [DecidableEq d.Op] [DecidableEq d.Ty] :
    {Γ : Ctxt d.Ty} → {ty : List d.Ty} → DecidableEq (Expr d Γ eff ty)
  | Γ, _, .mk op₁ rfl eff_le₁ arg₁ regArgs₁, .mk op₂ eq eff_le₂ arg₂ regArgs₂ =>
    if ho : op₁ = op₂ then by
      subst ho
      letI := HVector.decidableEq arg₁ arg₂
      letI := HVector.decidableEqReg regArgs₁ regArgs₂
      exact decidable_of_iff (arg₁ = arg₂ ∧ regArgs₁ = regArgs₂) (by admit /- proof elided -/
      )
    else isFalse (by admit /- proof elided -/
    )

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

def Valuation.nil : Ctxt.Valuation (∅ : Ctxt Ty) := fun _ v => v.emptyElim

inductive EffectKind
| pure 
| impure 
deriving Repr, DecidableEq, Lean.ToExpr

def Valuation.cons {Γ : Ctxt Ty} {t : Ty} (x : toType t) (V : Γ.Valuation) :
    (Γ.cons t).Valuation :=

protected instance HVector.decidableEqReg [DecidableEq d.Op] [DecidableEq d.Ty] :
    ∀ {l : RegionSignature d.Ty}, DecidableEq (HVector (fun t => Com d t.1 .impure t.2) l)
  | _, .nil, .nil => isTrue rfl
  | _, .cons x₁ v₁, .cons x₂ v₂ =>
    letI := HVector.decidableEqReg v₁ v₂
    letI := Com.decidableEq x₁ x₂
    decidable_of_iff (x₁ = x₂ ∧ v₁ = v₂) (by admit /- proof elided -/
    )

@[elab_as_elim]
def appendCases
    {motive : (Γ ++ Δ).Var t → Sort u}
    (left : (v : Var Γ t) → motive (appendInl v))
    (right : (v : Var Δ t) → motive (appendInr v)) :
    (v : (Γ ++ Δ).Var t) → motive v
  | ⟨idx, h⟩ =>
    if hv : idx < Γ.length then
      left ⟨idx, by admit /- proof elided -/
      ⟩
    else
      let v' : Var _ _ := ⟨idx - Γ.length, by admit /- proof elided -/
      ⟩
      have eq : v'.appendInr = ⟨idx, h⟩ := by admit /- proof elided -/

@[match_pattern]
def last (Γ : Ctxt Ty) (t : Ty) : Ctxt.Var (Ctxt.cons t Γ) t :=
  ⟨0, by admit /- proof elided -/
  ⟩

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

class TyDenote (β : Type) : Type 1 where
  toType : β → Type

def map (f : ∀ (a : α), A a → B a) :
    ∀ {l : List α}, HVector A l → HVector B l
  | [],   .nil        => .nil
  | t::_, .cons a as  => .cons (f t a) (map f as)

def map (f : Ty₁ → Ty₂) : Ctxt Ty₁ → Ctxt Ty₂ :=
  ofList ∘ (List.map f) ∘ toList

@[match_pattern]
def cons (hd : Ty) : Ctxt Ty → Ctxt Ty
| ⟨tl⟩ => ⟨hd :: tl⟩

noncomputable def f : (ZMod q)[X] := X^(2^n) + 1

def sig          := Signature.sig ∘ s.signature

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

class DialectSignature (d : Dialect) where
  signature : d.Op → Signature d.Ty

def effectKind   := Signature.effectKind ∘ s.signature

def returnTypes  := Signature.returnTypes ∘ s.signature

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

def Expr.op {Γ : Ctxt d.Ty} {eff : EffectKind} {ty} (e : Expr d Γ eff ty) : d.Op :=
  Expr.casesOn e (fun op _ _ _ _ => op)

class DialectDenote (d : Dialect) [TyDenote d.Ty] [DialectSignature d] where
  denote : (op : d.Op) → HVector toType (DialectSignature.sig op) →
    (HVector (fun t : Ctxt d.Ty × List d.Ty =>
      t.1.Valuation
      → EffectKind.impure.toMonad d.m (HVector toType t.2))
            (DialectSignature.regSig op)) →
    ((DialectSignature.effectKind op).toMonad d.m
      (HVector toType <| DialectSignature.returnTypes op))

def Lets.denote [DialectSignature d] [DialectDenote d] {Γ₂}
    (lets : Lets d Γ₁ eff Γ₂) (V : Valuation Γ₁) : (eff.toMonad d.m <| Valuation Γ₂) :=
  match lets with
  | .nil          => return V
  | .var lets' e  => lets'.denote V >>= e.denote

def regSig       := Signature.regSig ∘ s.signature

abbrev RegionSignature Ty := List (Ctxt Ty × List Ty)

inductive Ty (q : Nat) (n : Nat)
  | index : Ty q n
  | integer : Ty q n
  | tensor : Ty q n
  | polynomialLike : Ty q n
  deriving DecidableEq, Repr

structure Dialect where
  (Op : Type)
  (Ty : Type)
  (m : Type → Type := Id)

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

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

def HVector.denote :
    {l : RegionSignature d.Ty} → (T : HVector (fun t => Com d t.1 .impure t.2) l) →
    HVector (fun t => t.1.Valuation → EffectKind.impure.toMonad d.m (HVector toType t.2)) l
  | _, .nil => HVector.nil
  | _, .cons v vs => HVector.cons (v.denote) (HVector.denote vs)

@[simp] abbrev FlatCom.denote [DialectDenote d]
    (flatCom : FlatCom d Γ eff Γ_out ts)
    (V : Γ.Valuation) : eff.toMonad d.m (HVector toType ts) :=
  flatCom.lets.denote V >>= (return flatCom.rets.map ·)

structure FlatCom (d : Dialect) [DialectSignature d]  (Γ_in : Ctxt d.Ty) (eff : EffectKind)
    (Γ_out : Ctxt d.Ty) (ts : List d.Ty) where
  lets : Lets d Γ_in eff Γ_out
  rets : HVector Γ_out.Var ts

def RegionSignature.map (f : Ty → Ty') : RegionSignature Ty → RegionSignature Ty' :=
  List.map fun ⟨Γ, ty⟩ => (Γ.map f, ty.map f)

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

inductive Com : Ctxt d.Ty → EffectKind → List d.Ty → Type where
  | rets {Γ} {tys} {eff : EffectKind} (vs : HVector Γ.Var tys) : Com Γ eff tys
  | var (e : Expr Γ eff ty) (body : Com (ty ++ Γ) eff β) : Com Γ eff β

def Expr.denote {ty} (e : Expr d Γ eff ty) (V : Valuation Γ) :
    eff.toMonad d.m (e.outContext.Valuation) :=
  match e with
  | ⟨op, ty_eq, heff, args, regArgs⟩ => do
      let argsDenote := args.map V
      let val ← EffectKind.liftEffect heff <| DialectDenote.denote op argsDenote regArgs.denote
      return (val ++ V).cast (by admit /- proof elided -/
      )

def Com.outContext {Γ} : Com d Γ eff ts → Ctxt d.Ty :=
  Com.rec' (motive := fun _ => Ctxt d.Ty)
    (@fun Γ _ => Γ) 
    (fun _ _ r => r)

def Com.rec' {Γ} (com : Com d Γ eff t) : motive com :=
   
  Com.rec
    (motive_1 := fun _ _ _ _ => PUnit)
    (motive_2 := fun _ eff' t' c =>
      (h₁ : eff = eff') → (h₂ : t = t') → motive (h₁ ▸ h₂ ▸ c))
    (motive_3 := fun _ _ => PUnit)
    (fun _ _ _ _ _ _ => ⟨⟩) 
    (fun v h₁ h₂ => 
      cast (by admit /- proof elided -/
      ) <| rets (h₂ ▸ v))
    (fun e' body' _ r' h₁ h₂ => 
      let e := h₁ ▸ e'
      let body : Com _ _ eff t := cast (by admit /- proof elided -/
      ) body'
      let r : motive body := cast (by admit /- proof elided -/
      ) (r' h₁ h₂)
      cast (by admit /- proof elided -/
      ) <| var e body r)
    ⟨⟩
    (fun _ _ _ _ => ⟨⟩)
    com
    rfl
    rfl

def Valuation.cast {Γ Δ : Ctxt Ty} (h : Γ = Δ) (V : Valuation Γ) : Valuation Δ :=
  fun _ v => V <| v.castCtxt h.symm

abbrev Expr.outContext (_ : Expr d Γ eff ts) : Ctxt d.Ty :=
  ts ++ Γ

def liftEffect [Pure m] {e1 e2 : EffectKind} {α : Type}
    (hle : e1 ≤ e2) (v1 : e1.toMonad m α) : e2.toMonad m α :=
  match e1, e2, hle with
    | .pure, .pure, _ | .impure, .impure, _ => v1
    | .pure, .impure, _ => Pure.pure v1

def toMonad (e : EffectKind) (m : Type → Type) : Type → Type :=
  match e with
  | pure => Id
  | impure => m

def Com.denote : Com d Γ eff ty → (Γv : Valuation Γ) →
    eff.toMonad d.m (HVector toType ty)
  | .rets vs, Γv     => pure (vs.map Γv)
  | .var e body, V => e.denote V >>= body.denote

def Com.ty : Com d Γ eff [t] → d.Ty := fun _ => t

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

def Expr.regArgs {Γ ts} (e : Expr d Γ eff ts) :
    Regions d (DialectSignature.regSig e.op) :=
  Expr.casesOn e (fun _ _ _ _ regArgs => regArgs)

abbrev Regions (regSig : RegionSignature d.Ty) : Type :=
  HVector (fun t => Com d t.1 .impure t.2) regSig

def Expr.denoteOp (e : Expr d Γ eff ty) (V : Γ.Valuation) :
    eff.toMonad d.m (HVector toType ty) :=
  EffectKind.liftEffect e.eff_le <| cast (by admit /- proof elided -/
  ) <|
    DialectDenote.denote e.op (e.args.map V) e.regArgs.denote

infixr:50 "::ₕ" => HVector.cons

notation "⟦" x "⟧" => TyDenote.toType x

infixr:67 "::ᵥ" => Valuation.cons

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

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

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

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

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

@[simp]
abbrev envOfArray {w} (a : Array (BitVec w)) : Nat → BitVec w := fun n => a.getD n 0

def and_to_xor4_after := [llvm|
{
^0(%arg113 : i32, %arg114 : i32):
  %0 = llvm.xor %arg114, %arg113 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

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

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

def icmp_equality_test_constant_after := [llvm|
{
^0(%arg32 : i42, %arg33 : i42):
  %0 = llvm.icmp "eq" %arg32, %arg33 : i42
  "llvm.return"(%0) : (i1) -> ()
}
]

def t9_ashr_before := [llvm|
{
^0(%arg2 : i32, %arg3 : i16):
  %0 = llvm.mlir.constant(32 : i16) : i16
  %1 = llvm.mlir.constant(-2 : i16) : i16
  %2 = llvm.sub %0, %arg3 : i16
  %3 = llvm.zext %2 : i16 to i32
  %4 = llvm.ashr %arg2, %3 : i32
  %5 = llvm.trunc %4 : i32 to i16
  %6 = llvm.add %arg3, %1 : i16
  %7 = llvm.ashr %5, %6 : i16
  "llvm.return"(%7) : (i16) -> ()
}
]

Lean.ReducibilityStatus.semireducible in Lean.ReducibilityAttrs

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

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

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

partial def finNumeral? (e : Lean.Expr) : Option Nat :=
  match_expr e with
  | Fin.mk _ i _h => Expr.numeral? i
  | Fin.succ _ i => (· + 1) <$> finNumeral? i
  | OfNat.ofNat α i _ => do
      let_expr Fin n := α | none
      let n ← Expr.numeral? n
      let i ← Expr.numeral? i
      some (i % n)
  | _ => none

dsimproc simpHVectorGet (HVector.get _ _) := fun e => do
  let_expr HVector.get _α _A _as xs i := e
    | return .continue
  withTraceNode `LeanMLIR.Elab (fun _ => pure m!"Simplifying: {e}") <| do
    let some i := finNumeral? i
      | trace[LeanMLIR.Elab] "Unable to statically determine the value of `Fin` expression: {i}"
        return .continue

    let rec getElem (xs : Expr) (i : Nat) : MetaM (Option Expr) := do
      let_expr HVector.cons _α _f _as _a x xs := xs
        | trace[LeanMLIR.Elab] "Expected an application of `HVector.cons`, but found: {xs}"
          return none
      match i with
      | 0 => return some x
      | i+1 => getElem xs i

    let some x ← getElem xs i
      | return .continue

    return .visit x

def icmp_mul_nsw_sge_after := [llvm|
{
^0(%arg13 : i8, %arg14 : i8):
  %0 = llvm.icmp "sge" %arg13, %arg14 : i8
  "llvm.return"(%0) : (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 ashr_mul_times_3_div_2_exact_before := [llvm|
{
^0(%arg21 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.mul %arg21, %0 overflow<nsw> : i32
  %3 = llvm.ashr exact %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

@[coe]
def toCons {Γ : Ctxt Ty} {t t' : Ty} (var : Var Γ t) : Var (cons t' Γ) t  :=
  ⟨var.1+1, var.2⟩

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

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

def test6_after := [llvm|
{
^0(%arg88 : i64):
  %0 = llvm.mlir.constant(32) : i64
  %1 = llvm.lshr %arg88, %0 : i64
  %2 = llvm.trunc %1 overflow<nuw> : i64 to i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

def envBitstream_set (x : arity → BitStream) (n : Nat) (v : arity → Bool) :
    arity → BitStream :=
  fun a j => if j = n then v a else x a j

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

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

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

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

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

List.map in Init.Prelude

def zext_or_masked_bit_test_after := [llvm|
{
^0(%arg54 : i32, %arg55 : i32, %arg56 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %0, %arg55 overflow<nuw> : i32
  %3 = llvm.and %2, %arg54 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  %5 = llvm.icmp "eq" %arg56, %arg55 : i32
  %6 = llvm.or %4, %5 : i1
  %7 = llvm.zext %6 : i1 to i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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 }

    |

structure Item where
 name : String
 tac : Syntax

NatCast in Init.Data.Cast

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

def lshr_shl_pow2_const_case2_before := [llvm|
{
^0(%arg58 : i16):
  %0 = llvm.mlir.constant(8192 : i16) : i16
  %1 = llvm.mlir.constant(4 : i16) : i16
  %2 = llvm.mlir.constant(32 : i16) : i16
  %3 = llvm.lshr %0, %arg58 : i16
  %4 = llvm.shl %3, %1 : i16
  %5 = llvm.and %4, %2 : i16
  "llvm.return"(%5) : (i16) -> ()
}
]

def ReflectMap.toExpr (xs : ReflectMap) (w : Expr) : MetaM ReflectedExpr := do
  let mut out := mkApp (mkConst ``Reflect.Map.empty) w
  let exprs := xs.exprs.toArray.qsort (fun ei ej => ei.2 < ej.2)
  for (e, _) in exprs do
    
     
    out := mkAppN (mkConst ``Reflect.Map.append) #[w, e, out]
  return out

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

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

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

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

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

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

def bigOr (constraints : List (BoolExpr α)) : BoolExpr α :=
  foldConstraints (BoolExpr.const false) constraints Gate.or

instance : ToString PreconditionSynthesisCacheValue where
  toString val :=
    s! "⟨positiveExampleValues := {val.positiveExampleValues}, negativeExampleValues := {val.negativeExampleValues}⟩"

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

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

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

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

noncomputable def a_plus_generator_eq_a := [poly q, n, hq| {
^bb0(%a : !R):
  %one_int = arith.const 1 : i16
  %two_to_the_n = arith.const ${2**n} : index
  %x2n = poly.monomial %one_int, %two_to_the_n : (i16, index) -> !R
  %oner = poly.const 1 : !R
  %p = poly.add %x2n, %oner : !R
  %v1 = poly.add %a, %p : !R
  return %v1 : !R
}]

def Com.ret {Γ : Ctxt d.Ty} {ty : d.Ty} {eff : EffectKind} : Γ.Var ty → Com d Γ eff [ty] :=
  (Com.rets [·]ₕ)

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

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

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

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

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

def inputSnd : (CIRCTStream.DCOp.TokenStream × CIRCTStream.DCOp.TokenStream) := (tok1, tok2)

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

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

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

def ori_test: LLVMPeepholeRewriteRefine 16 [Ty.llvm (.bitvec 16)] where
  lhs := ori_llvm
  rhs := ori_riscv

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

MonadLift in Init.Prelude

@[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 positive_biggershl_shlnuwnsw_ashrexact_after := [llvm|
{
^0(%arg24 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.shl %arg24, %0 overflow<nsw,nuw> : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

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

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

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

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 test13_before := [llvm|
{
^0(%arg0 : i1024):
  %0 = llvm.mlir.constant(1016 : i1024) : i1024
  %1 = llvm.mlir.constant(255 : i1024) : i1024
  %2 = llvm.ashr %arg0, %0 : i1024
  %3 = llvm.and %2, %1 : i1024
  "llvm.return"(%3) : (i1024) -> ()
}
]

def t8_twoshifts3_after := [llvm|
{
^0(%arg24 : i32, %arg25 : i32, %arg26 : i32, %arg27 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %arg24, %arg25 : i32
  %3 = llvm.shl %0, %arg27 overflow<nuw> : i32
  %4 = llvm.and %3, %2 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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 multiuse1_before := [llvm|
{
^0(%arg11 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(4 : i32) : i32
  %2 = llvm.mlir.constant(6 : i32) : i32
  %3 = llvm.mlir.constant(1 : i32) : i32
  %4 = llvm.and %arg11, %0 : i32
  %5 = llvm.and %arg11, %1 : i32
  %6 = llvm.shl %4, %2 overflow<nsw,nuw> : i32
  %7 = llvm.lshr exact %4, %3 : i32
  %8 = llvm.shl %5, %2 overflow<nsw,nuw> : i32
  %9 = llvm.lshr exact %5, %3 : i32
  %10 = llvm.or %6, %8 : i32
  %11 = llvm.or %7, %9 : i32
  %12 = llvm.or %11, %10 : i32
  "llvm.return"(%12) : (i32) -> ()
}
]

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

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

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

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

def closed_set (M : NFA α σ) (S : Set σ) := M.start ⊆ S ∧ ∀ a, M.stepSet S a ⊆ S

def trunc {w: Nat} (w': Nat) (x: IntW w) (noWrapFlags : NoWrapFlags := {nsw := false , nuw := false}) : IntW w' := do
  let x' <- x
  if noWrapFlags.nsw ∧ ((x'.truncate w').signExtend w ≠ x') then
    .poison
  else if noWrapFlags.nuw ∧ ((x'.truncate w').zeroExtend w ≠ x') then
    .poison
  else
    trunc? w' x'

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

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

def or_consts_logical_after := [llvm|
{
^0(%arg160 : i32, %arg161 : i32, %arg162 : i32):
  %0 = llvm.mlir.constant(12 : i32) : i32
  %1 = llvm.and %arg160, %0 : i32
  %2 = llvm.icmp "eq" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

def substBvEqualitiesTac : TacticM Unit := do
  liftMetaTactic1 substBvEqualities

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

def p1 : PeepholeRewrite ExOp [.nat, .nat] .nat :=
  { lhs := m, rhs := r, correct :=
    by
      rw [m, r]
      funext Γv
      simp_peephole [add, cst] at Γv
      intros a b
      rw [Nat.add_comm]
    }

example : rewritePeepholeAt p1 1 ex1 = (
  Com.var (cst 1)  <|
     .var (add ⟨0, by simp⟩ ⟨0, by simp⟩)  <|
     .var (add ⟨1, by simp⟩ ⟨1, by simp⟩)  <|
     .ret ⟨0, by simp⟩) :=

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

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

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

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

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

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

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

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

instance (Γ Δ : Ctxt Ty) : HAppend (Valuation Γ) (Valuation Δ) (Valuation <| Γ ++ Δ) where
  hAppend V W := fun t v =>
    v.appendCases (@V t) (@W t)

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

private abbrev ReaderM := MLIR.AST.ReaderM SLLVM

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 one_side_fold_slt_after := [llvm|
{
^0(%arg33 : i32, %arg34 : i32, %arg35 : i32, %arg36 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.icmp "slt" %arg34, %arg33 : i32
  %2 = "llvm.select"(%arg36, %1, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

def shl_or_disjoint_lshr_before := [llvm|
{
^0(%arg109 : i32, %arg110 : i32, %arg111 : i32):
  %0 = llvm.shl %arg109, %arg110 overflow<nuw> : i32
  %1 = llvm.or disjoint %0, %arg111 : i32
  %2 = llvm.lshr %1, %arg110 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

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

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

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

def signed_sign_bit_extract_trunc_before := [llvm|
{
^0(%arg1 : i64):
  %0 = llvm.mlir.constant(63) : i64
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.ashr %arg1, %0 : i64
  %3 = llvm.trunc %2 : i64 to i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

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

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

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

def andi_i64_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := andi_llvm_i64
  rhs := andi_riscv_i64

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

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

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

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

def neg_mask_after := [llvm|
{
^0(%arg1 : i32, %arg2 : i16):
  %0 = llvm.mlir.constant(0 : i16) : i16
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.sext %arg2 : i16 to i32
  %3 = llvm.sub %arg1, %2 overflow<nsw> : i32
  %4 = llvm.icmp "slt" %arg2, %0 : i16
  %5 = "llvm.select"(%4, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

def generalizeTactic
      (H : HydrableParseAndGeneralize parsedExpr genLogicalExpr genExpr)
      (cfg : MedusaSynthGeneralizeConfig)
      (expr : Expr) : TacticM Unit := do
  let name ← mkAuxDeclName `generalized
  let msg ← withoutModifyingEnv <| withoutModifyingState do
    Lean.Elab.Tactic.withMainContext do
      
      
      let res ← parseAndGeneralize (H := H) cfg expr (GeneralizeContext.Tactic name)
      pure m! "{res}"
  logInfo m! "{msg}"

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

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

instance instToStringTy : ToString (Dialect.Ty d) where toString := printTy

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

def or_basic_after := [llvm|
{
^0(%arg15 : i16):
  %0 = llvm.mlir.constant(17791 : i16) : i16
  %1 = llvm.icmp "ne" %arg15, %0 : i16
  "llvm.return"(%1) : (i1) -> ()
}
]

def ripple_no_nsw2_after := [llvm|
{
^0(%arg9 : i16, %arg10 : i16):
  %0 = llvm.mlir.constant(1 : i16) : i16
  %1 = llvm.mlir.constant(32767 : i16) : i16
  %2 = llvm.and %arg10, %0 : i16
  %3 = llvm.and %arg9, %1 : i16
  %4 = llvm.add %2, %3 overflow<nuw> : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

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

def sgt_and_min_logical_before := [llvm|
{
^0(%arg350 : i9, %arg351 : i9):
  %0 = llvm.mlir.constant(-256 : i9) : i9
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "sgt" %arg350, %arg351 : i9
  %3 = llvm.icmp "eq" %arg350, %0 : i9
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def and_signbit_shl_before := [llvm|
{
^0(%arg23 : i32):
  %0 = llvm.mlir.constant(-65536 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.and %arg23, %0 : i32
  %3 = llvm.shl %2, %1 : i32
  "llvm.return"(%3) : (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 ashrslt_01_05_before := [llvm|
{
^0(%arg264 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(5 : i4) : i4
  %2 = llvm.ashr %arg264, %0 : i4
  %3 = llvm.icmp "slt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

private def op2 : Op φ :=
  [mlir_op| %z = "foo"(%x, %y) : (i32, i32) -> (i32)]

Lean.indentD in Lean.Message

def mkReturn (Γ : Ctxt (ModArith q).Ty) (opStx : MLIR.AST.Op 0)
  : MLIR.AST.ReaderM (ModArith q) (Σ eff ty, Com (ModArith q) Γ eff ty) :=
  if opStx.name == "return" then
    match opStx.args with
    | [argStx] => do
      let ⟨tyArg, x⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ argStx
      return ⟨.pure, tyArg, Com.ret x⟩
    | _ =>
      throw <| .generic s!"[mod_arith] return expects exactly 1 argument"
  else
      throw <| .generic s!"[mod_arith] mkReturn called on non-return op {opStx.name}"

instance : DialectToExpr DC where
  toExprM := .const ``Id [0]
  toExprDialect := .const ``DC []

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

def t1_before := [llvm|
{
^0(%arg6 : i8, %arg7 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.xor %arg6, %0 : i8
  %2 = llvm.ashr exact %1, %arg7 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

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

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

def Expr.mk {Γ} {ty}
    (varName : VarName)
    (op : Op) (ty_eq : ty = (signature op).returnType)
    (args : VarList Γ (signature op).arguments)
    (regions : RegionList Op (signature op).regions) :
    Expr Op Γ ty :=
  ⟨⟨varName, op, args.val, regions.val⟩, by admit /- proof elided -/
  ⟩

def AttrDict.find_int {φ} (attrs : AttrDict φ)
  (name : String): Option (Int × MLIRType φ) :=
  match attrs.find name with
  | .some (AttrValue.int i ty) =>  .some (i, ty)
  | _ => .none

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

def not_or_or_and_no_and_after := [llvm|
{
^0(%arg121 : i32, %arg122 : i32, %arg123 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg121, %0 : i32
  %2 = llvm.xor %arg122, %0 : i32
  %3 = llvm.and %arg123, %2 : i32
  %4 = llvm.or %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

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

def select_1_before := [llvm|
{
^0(%arg87 : i1, %arg88 : i8, %arg89 : i8, %arg90 : i1, %arg91 : i8, %arg92 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(123 : i8) : i8
  %2 = llvm.mlir.constant(45 : i8) : i8
  %3 = llvm.xor %arg91, %0 : i8
  %4 = llvm.xor %arg92, %1 : i8
  %5 = "llvm.select"(%arg90, %3, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %6 = llvm.xor %arg88, %2 : i8
  %7 = llvm.xor %arg89, %6 : i8
  %8 = "llvm.select"(%arg87, %7, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %9 = llvm.xor %8, %0 : i8
  "llvm.return"(%9) : (i8) -> ()
}
]

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

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

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

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

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

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

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

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

BitVec.ofInt in Init.Data.BitVec.Basic

def or_or_and_pat5_before := [llvm|
{
^0(%arg58 : i8, %arg59 : i8, %arg60 : i8, %arg61 : i8):
  %0 = llvm.and %arg58, %arg59 : i8
  %1 = llvm.and %arg58, %arg61 : i8
  %2 = llvm.or %1, %arg60 : i8
  %3 = llvm.or %2, %0 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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

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

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

instance : DecidableNFA' (NFA'.autMsbSet) where

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

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

def ashr_ashr_before := [llvm|
{
^0(%arg7 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.mlir.constant(7 : i32) : i32
  %2 = llvm.ashr %arg7, %0 : i32
  %3 = llvm.ashr %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

def ripple_nsw5_after := [llvm|
{
^0(%arg15 : i16, %arg16 : i16):
  %0 = llvm.mlir.constant(-21845 : i16) : i16
  %1 = llvm.mlir.constant(-10923 : i16) : i16
  %2 = llvm.or %arg16, %0 : i16
  %3 = llvm.or %arg15, %1 : i16
  %4 = llvm.add %2, %3 overflow<nsw> : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

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

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

def t2_before := [llvm|
{
^0(%arg8 : i64):
  %0 = llvm.mlir.constant(63) : i64
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.ashr %arg8, %0 : i64
  %3 = llvm.trunc %2 : i64 to i32
  %4 = llvm.sub %1, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

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

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

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

def ugt_swap_and_not_min_commute_after := [llvm|
{
^0(%arg66 : i8, %arg67 : i8):
  %0 = llvm.icmp "ult" %arg67, %arg66 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

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

inductive Term : Type
| var : Nat → Term
 
| zero : Term
 
| negOne : Term
 
| one : Term
 
| ofNat (n : Nat) : Term
 
| and : Term → Term → Term
 
| or : Term → Term → Term
 
| xor : Term → Term → Term
 
| not : Term → Term
 
| add : Term → Term → Term
 
| sub : Term → Term → Term
 
| neg : Term → Term




 
| shiftL : Term → Nat → Term




deriving Repr, Inhabited, Lean.ToExpr

def and_not_or_commute9_after := [llvm|
{
^0(%arg454 : i32, %arg455 : i32, %arg456 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg454 : i32
  %3 = llvm.sdiv %0, %arg455 : i32
  %4 = llvm.sdiv %0, %arg456 : i32
  %5 = llvm.xor %3, %4 : i32
  %6 = llvm.and %5, %2 : i32
  %7 = llvm.xor %6, %1 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

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

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

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

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

          mkFreshExprMVar expr

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

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

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

def test_lshr__exact_is_safe_before := [llvm|
{
^0(%arg60 : i32, %arg61 : i64):
  %0 = llvm.mlir.constant(60 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.and %arg60, %0 : i32
  %4 = llvm.lshr %3, %1 : i32
  %5 = llvm.zext %4 : i32 to i64
  %6 = llvm.icmp "eq" %3, %2 : i32
  %7 = llvm.ashr %arg61, %5 : i64
  %8 = "llvm.select"(%6, %arg61, %7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%8) : (i64) -> ()
}
]

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

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

def and_to_xor2_after := [llvm|
{
^0(%arg117 : i32, %arg118 : i32):
  %0 = llvm.xor %arg117, %arg118 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

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

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

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

@[simp_denote]
def add_shl_rhs_constant_llvm := [LV| {
    ^entry (%a0: i64, %a1: i64):
    %0 = llvm.mlir.constant (1) : i64
    %c3 = llvm.mlir.constant (3) : i64
    %c8 = llvm.mlir.constant (-8) : i64
    %1 = llvm.add %a0, %0 : i64
    %2 = llvm.add %a1, %1 : i64
    %3 = llvm.shl %2, %c3 : i64
    %4 = llvm.add %3, %c8 : i64
    llvm.return %4 : i64
  }]

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

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

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

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

def xor_ashr_not_fail_ashr_lshr_before := [llvm|
{
^0(%arg18 : i8, %arg19 : i8, %arg20 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.ashr %arg18, %arg20 : i8
  %2 = llvm.lshr %arg19, %arg20 : i8
  %3 = llvm.xor %2, %0 : i8
  %4 = llvm.xor %1, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

Lean.Expr.lam in Lean.Expr

def test0_before := [llvm|
{
^0(%arg123 : i32):
  %0 = llvm.mlir.constant(-2147483648 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.xor %arg123, %0 : i32
  %3 = llvm.icmp "sgt" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

instance : TyDenote Ty where
  toType
    | .int => ℤ
    | .bool => Bool
    | .nat => Nat

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

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

def lshr_shl_demand4_before := [llvm|
{
^0(%arg6 : i8):
  %0 = llvm.mlir.constant(60 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.mlir.constant(7 : i8) : i8
  %3 = llvm.lshr %0, %arg6 : i8
  %4 = llvm.shl %3, %1 : i8
  %5 = llvm.or %4, %2 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

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

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

def is_ascii_alphabetic_inverted_after := [llvm|
{
^0(%arg247 : i32):
  %0 = llvm.mlir.constant(-33 : i32) : i32
  %1 = llvm.mlir.constant(-91 : i32) : i32
  %2 = llvm.mlir.constant(-26 : i32) : i32
  %3 = llvm.and %arg247, %0 : i32
  %4 = llvm.add %3, %1 : i32
  %5 = llvm.icmp "ult" %4, %2 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

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

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

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

def test_before := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(17 : i32) : i32
  %1 = llvm.ashr %arg1, %0 : i32
  %2 = llvm.ashr %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def shl_add_add_fail_after := [llvm|
{
^0(%arg166 : i8, %arg167 : i8):
  %0 = llvm.mlir.constant(2 : i8) : i8
  %1 = llvm.mlir.constant(48 : i8) : i8
  %2 = llvm.lshr %arg166, %0 : i8
  %3 = llvm.lshr %arg167, %0 : i8
  %4 = llvm.add %3, %1 overflow<nsw,nuw> : i8
  %5 = llvm.add %2, %4 overflow<nuw> : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def test48_before := [llvm|
{
^0(%arg137 : i8, %arg138 : i8):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.zext %arg138 : i8 to i32
  %2 = llvm.zext %arg137 : i8 to i32
  %3 = llvm.shl %2, %0 : i32
  %4 = llvm.or %3, %2 : i32
  %5 = llvm.zext %4 : i32 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

inductive AttrDefn where
  | mk: (name: String) -> (val: AttrValue φ) -> AttrDefn

def ashr_bitwidth_mask_before := [llvm|
{
^0(%arg127 : i8, %arg128 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.ashr %arg127, %0 : i8
  %2 = llvm.and %1, %arg128 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def ripple_nsw2_before := [llvm|
{
^0(%arg21 : i16, %arg22 : i16):
  %0 = llvm.mlir.constant(1 : i16) : i16
  %1 = llvm.mlir.constant(-16385 : i16) : i16
  %2 = llvm.and %arg22, %0 : i16
  %3 = llvm.and %arg21, %1 : i16
  %4 = llvm.add %3, %2 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

def Valuation.ofHVector {types : List Ty} : HVector toType types → Valuation (Ctxt.ofList types)
  | .nil        => (nil : Ctxt.Valuation ∅)
  | .cons x xs  => cons x (ofHVector xs)

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

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

def t4_commutative_before := [llvm|
{
^0(%arg34 : i8, %arg35 : i8):
  %0 = llvm.add %arg34, %arg35 : i8
  %1 = llvm.icmp "ule" %arg35, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

Lean.Meta.check in Lean.Meta.Check

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

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

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

instance : BEq (FpExpr e) where
  beq := fun a b => toString a == toString b

def icmp_equality_test_commute_icmp1_after := [llvm|
{
^0(%arg23 : i64, %arg24 : i64, %arg25 : i64):
  %0 = llvm.icmp "eq" %arg24, %arg23 : i64
  "llvm.return"(%0) : (i1) -> ()
}
]

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

def samesign_commute1_after := [llvm|
{
^0(%arg125 : i32, %arg126 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg125, %arg126 : i32
  %2 = llvm.icmp "sgt" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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 udiv_shl_mul_nuw_swap_before := [llvm|
{
^0(%arg145 : i5, %arg146 : i5, %arg147 : i5):
  %0 = llvm.shl %arg145, %arg147 overflow<nuw> : i5
  %1 = llvm.mul %arg146, %arg145 overflow<nuw> : i5
  %2 = llvm.udiv %0, %1 : i5
  "llvm.return"(%2) : (i5) -> ()
}
]

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

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

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

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

instance fpHydrableParseAndGeneralize : HydrableParseAndGeneralize ParsedFpExpr FpPredicate FpExpr where

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

def llvm_const_lower_riscv_li_25 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_25, rhs:= liRiscv_25,
   correct := by admit /- proof elided -/

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

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

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

def urem_i32_after := [llvm|
{
^0(%arg21 : i8, %arg22 : i8):
  %0 = llvm.urem %arg21, %arg22 : i8
  %1 = llvm.zext %0 : i8 to i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

@[simp_denote]
def llvm_sub_nuw_16 := [LV| {
  ^entry (%x: i16, %y: i16):
    %1 = llvm.sub %x, %y overflow<nuw> : i16
    llvm.return %1 : i16
  }]

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

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

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

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

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

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 test15_before := [llvm|
{
^0(%arg3 : i32):
  %0 = llvm.mlir.constant(4 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.udiv %0, %arg3 : i32
  %3 = llvm.icmp "ugt" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

abbrev AttrVal (φ := 0) := AttrValue φ

def test_mul_zero_rhs_LHS := [mod_arith q, hq| {
  ^bb0(%x : !R):
    %zero = mod_arith.constant 0 : !R
    %mul = mod_arith.mul %x, %zero : !R
    return %mul : !R
}]

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

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

abbrev instHadd : HAdd ⟦ScfFunctor.Arith.Ty.int⟧ ⟦ScfFunctor.Arith.Ty.int⟧
  ⟦ScfFunctor.Arith.Ty.int⟧ := @instHAdd ℤ Int.instAdd

def Predicate.evalEq (t₁ t₂ : BitStream) : BitStream := (t₁ ^^^ t₂).concat false |>.scanOr

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

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

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

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

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

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

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

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

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

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

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

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

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

def attr0Str : AttrEntry 0 := [mlir_attr_entry| sym_name = "add"]

Std.Tactic.BVDecide.BoolExpr.const in Std.Tactic.BVDecide.Bitblast.BoolExpr.Basic

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

def binop_same_val : List (Σ Γ, RISCVPeepholeRewrite  Γ) :=
    [⟨_, binop_same_val_and⟩,
    ⟨_, binop_same_val_or⟩]

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

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

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

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

def eq_umax4_after := [llvm|
{
^0(%arg54 : i32, %arg55 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg54, %0 : i32
  %2 = llvm.icmp "uge" %1, %arg55 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

def and_sequence_40_rhs (w : Nat)  :=
[llvm( w )| {
^bb0(%C1 : _, %Z : _):
  %v1 = llvm.and %Z,  %C1
  llvm.return %v1
}]

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

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

CoeDep in Init.Coe

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

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

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

Function.Surjective in Init.Data.Function

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

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

def test13_after := [llvm|
{
^0(%arg0 : i1024):
  %0 = llvm.mlir.constant(1016 : i1024) : i1024
  %1 = llvm.lshr %arg0, %0 : i1024
  "llvm.return"(%1) : (i1024) -> ()
}
]

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

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

def test_trunc_before := [llvm|
{
^0(%arg24 : i8):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(31 : i32) : i32
  %2 = llvm.mlir.constant(-1 : i8) : i8
  %3 = llvm.zext %arg24 : i8 to i32
  %4 = llvm.add %3, %0 overflow<nsw> : i32
  %5 = llvm.ashr %4, %1 : i32
  %6 = llvm.trunc %5 : i32 to i8
  %7 = llvm.xor %6, %2 : i8
  "llvm.return"(%7) : (i8) -> ()
}
]

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

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

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

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

def lor_land_right2_after := [llvm|
{
^0(%arg24 : i1, %arg25 : i1):
  "llvm.return"(%arg24) : (i1) -> ()
}
]

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

RV64.sub in RISCV.Instructions

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

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

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

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

def Predicate.eval (p : Predicate) (vars : List BitStream) : BitStream :=
  match p with
  | .width .eq n => BitStream.falseIffEq n
  | .width .neq n => BitStream.falseIffNeq n
  | .width .lt n => BitStream.falseIffLt n
  | .width .le n => BitStream.falseIffLe n
  | .width .gt n => BitStream.falseIffGt n
  | .width .ge n => BitStream.falseIffGe n
  | lor p q => Predicate.evalLor (p.eval vars) (q.eval vars)
  | land p q => Predicate.evalLand (p.eval vars) (q.eval vars)
  | binary .eq t₁ t₂ => Predicate.evalEq (t₁.eval vars) (t₂.eval vars)
   
  | binary .neq t1 t2 => Predicate.evalNeq (t1.eval vars) (t2.eval vars)
  | binary .ult t₁ t₂ => Predicate.evalUlt (t₁.eval vars) (t₂.eval vars)
  | binary .ule t₁ t₂ =>
     Predicate.evalLor
       (Predicate.evalEq (t₁.eval vars) (t₂.eval vars))
       (Predicate.evalUlt (t₁.eval vars) (t₂.eval vars))
  | binary .slt t₁ t₂ => Predicate.evalSlt (t₁.eval vars) (t₂.eval vars)
  | binary .sle t₁ t₂ => Predicate.evalLor
       (Predicate.evalEq (t₁.eval vars) (t₂.eval vars))
       (Predicate.evalSlt (t₁.eval vars) (t₂.eval vars))

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

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

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

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

def rewrite00 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs:= [LV| {
  ^entry (%arg: i64, %amount: i64):
    %0 = llvm.shl %arg, %amount : i64
    %1 = llvm.lshr %0, %amount : i64
    llvm.return %1 : i64
  }]

  rhs:= [LV| {
  ^entry (%arg: i64, %amount: i64):
    llvm.return %arg : i64
  }]
  correct := by admit /- proof elided -/

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

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

def shl? {n} (op1 : BitVec n) (op2 : BitVec n) : IntW n :=
  if op2 >= n
  then .poison
  else .value (op1 <<< op2)

def t0_after := [llvm|
{
^0(%arg8 : i8, %arg9 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.ashr %arg8, %arg9 : i8
  %2 = llvm.xor %1, %0 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

@[simp]
def dec_transport :
    dec (bvs'.transport f) = (dec bvs').transport f :=

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

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

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

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

instance : Lean.ToExpr RegIndex := inherit

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

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

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

def t1_after := [llvm|
{
^0(%arg17 : i16):
  %0 = llvm.mlir.constant(15 : i16) : i16
  %1 = llvm.mlir.constant(-1 : i16) : i16
  %2 = llvm.sub %0, %arg17 : i16
  %3 = llvm.lshr %1, %2 : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

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

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

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

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

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

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

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

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

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

def no_shift_no_xor_multiuse_xor_after := [llvm|
{
^0(%arg138 : i32, %arg139 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.and %arg138, %0 : i32
  %2 = llvm.xor %arg139, %0 : i32
  %3 = llvm.xor %arg139, %1 : i32
  %4 = llvm.mul %3, %2 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

def t15_after := [llvm|
{
^0(%arg198 : i32, %arg199 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.shl %0, %arg199 overflow<nuw> : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def PR30273_three_bools_after := [llvm|
{
^0(%arg41 : i1, %arg42 : i1, %arg43 : i1):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.zext %arg41 : i1 to i32
  %3 = "llvm.select"(%arg41, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = "llvm.select"(%arg42, %3, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %5 = llvm.zext %arg43 : i1 to i32
  %6 = llvm.add %4, %5 overflow<nsw,nuw> : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

def test_mul_nuw__nuw_is_safe_before := [llvm|
{
^0(%arg10 : i32):
  %0 = llvm.mlir.constant(268435457 : i32) : i32
  %1 = llvm.mlir.constant(268435456 : i32) : i32
  %2 = llvm.mlir.constant(9 : i32) : i32
  %3 = llvm.mlir.constant(-1879048192 : i32) : i32
  %4 = llvm.and %arg10, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.mul %4, %2 overflow<nuw> : i32
  %7 = "llvm.select"(%5, %3, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%7) : (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 masked_bit_clear_commute_before := [llvm|
{
^0(%arg77 : i32, %arg78 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.srem %0, %arg77 : i32
  %4 = llvm.shl %1, %arg78 : i32
  %5 = llvm.and %3, %4 : i32
  %6 = llvm.icmp "eq" %5, %2 : i32
  %7 = llvm.zext %6 : i1 to i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

def hoist_logic_op_with_same_opcode_hands_64 : List (Σ Γ, LLVMPeepholeRewriteRefine 64 Γ) :=
  [⟨_, AndSextSext⟩,
  ⟨_, OrSextSext⟩,
  ⟨_, XorSextSext⟩,
  ⟨_, AndZextZext⟩,
  ⟨_, OrZextZext⟩,
  ⟨_, XorZextZext⟩,
  ⟨_, AndShlShl⟩,
  ⟨_, OrShlShl⟩,
  ⟨_, XorShlShl⟩,
  ⟨_, AndLshrLshr⟩,
  ⟨_, OrLshrLshr⟩,
  ⟨_, XorLshrLshr⟩,
  ⟨_, AndAshrAshr⟩,
  ⟨_, OrAshrAshr⟩,
  ⟨_, XorAshrAshr⟩,
  ⟨_, AndAndAnd⟩,
  ⟨_, OrAndAnd⟩,
  ⟨_, XorAndAnd⟩]

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

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

@[simp, grind=] def Expr.bvars (e : Expr d Γ eff Δ) : Nat :=
  (DialectSignature.returnTypes e.op).length

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

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

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

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

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

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

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 ashr_mul_sign_bits_before := [llvm|
{
^0(%arg86 : i8, %arg87 : i8):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.sext %arg86 : i8 to i32
  %2 = llvm.sext %arg87 : i8 to i32
  %3 = llvm.mul %1, %2 : i32
  %4 = llvm.ashr %3, %0 : i32
  %5 = llvm.trunc %4 : i32 to i16
  "llvm.return"(%5) : (i16) -> ()
}
]

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

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

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 masked_and_notallzeroes_before := [llvm|
{
^0(%arg134 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(39 : i32) : i32
  %3 = llvm.and %arg134, %0 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  %5 = llvm.and %arg134, %2 : i32
  %6 = llvm.icmp "ne" %5, %1 : i32
  %7 = llvm.and %4, %6 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

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

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

def test47_after := [llvm|
{
^0(%arg197 : i32, %arg198 : i32):
  %0 = llvm.and %arg198, %arg197 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def mul_constant_eq_nsw_before := [llvm|
{
^0(%arg130 : i32, %arg131 : i32):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.mul %arg130, %0 overflow<nsw> : i32
  %2 = llvm.mul %arg131, %0 overflow<nsw> : i32
  %3 = llvm.icmp "eq" %1, %2 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def ashr_exact_add_nuw_before := [llvm|
{
^0(%arg62 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(-4 : i32) : i32
  %2 = llvm.add %arg62, %0 overflow<nuw> : i32
  %3 = llvm.ashr exact %1, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

instance : HydrableGeneralize ParsedFpExpr FpPredicate FpExpr where

def test14a_before := [llvm|
{
^0(%arg25 : i79):
  %0 = llvm.mlir.constant(4 : i79) : i79
  %1 = llvm.mlir.constant(1234 : i79) : i79
  %2 = llvm.shl %arg25, %0 : i79
  %3 = llvm.and %2, %1 : i79
  %4 = llvm.lshr %3, %0 : i79
  "llvm.return"(%4) : (i79) -> ()
}
]

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

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

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

def t3_exact_before := [llvm|
{
^0(%arg7 : i64):
  %0 = llvm.mlir.constant(63) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.ashr exact %arg7, %0 : i64
  %3 = llvm.sub %1, %2 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

@[simp_denote]
def sdiv_llvm_exact_32 := [LV| {
  ^entry (%x: i32, %y: i32):
    %1 = llvm.sdiv exact %x, %y : i32
    llvm.return %1 : i32
  }]

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

def two_ne_stmt (b a : LLVM.IntW w) :
    (LLVM.icmp LLVM.IntPred.ne b a)
      ⊑ (LLVM.icmp LLVM.IntPred.ne b a) :=

def t9_highest_bit_after := [llvm|
{
^0(%arg25 : i32, %arg26 : i64, %arg27 : i32):
  %0 = llvm.mlir.constant(63) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.zext %arg25 : i32 to i64
  %3 = llvm.lshr %arg26, %0 : i64
  %4 = llvm.and %3, %2 : i64
  %5 = llvm.icmp "ne" %4, %1 : i64
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

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

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

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

def 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 OrZextOr_before := [llvm|
{
^0(%arg4 : i3):
  %0 = llvm.mlir.constant(3 : i3) : i3
  %1 = llvm.mlir.constant(8 : i5) : i5
  %2 = llvm.or %arg4, %0 : i3
  %3 = llvm.zext %2 : i3 to i5
  %4 = llvm.or %3, %1 : i5
  "llvm.return"(%4) : (i5) -> ()
}
]

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

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

def Expr.printType (e : Expr d Γ eff ts) : Format :=
  let argTys := e.args.mapToList (@fun t _ => printTy t)
  let argTys := Format.group <| Format.joinSep argTys ", "
  let retTys := ts.map printTy
  let retTys := Format.group <| Format.joinSep retTys ", "
  f!"({argTys}) -> ({retTys})"

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

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

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

def Sexpr.toFormat : Sexpr → Format
| .atom a => a
| .array as => (as.map Sexpr.toFormat) |>.toList |> fun l => Format.joinSep l " "  |>.paren

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

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

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

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

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

inductive Op : Type
| add (n : Nat) : Op
| const : (val : ℤ) → Op
deriving DecidableEq, Repr

private def tyi32NoGap : MLIRTy := [mlir_type| i32]

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

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

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

def alive_AndOrXor_1288_A__B__B__C__A___A__B__C_src :=
[sllvm| {
^bb0(%A : i64, %C : i64, %B : i64):
  %v1 = llvm.xor %A, %B : i64
  %v2 = llvm.xor %B, %C : i64
  %v3 = llvm.xor %v2, %A : i64
  %v4 = llvm.and %v1, %v3 : i64
  llvm.return %v4 : i64
}]

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

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

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

def and_ashr_not_before := [llvm|
{
^0(%arg81 : i8, %arg82 : i8, %arg83 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.ashr %arg81, %arg83 : i8
  %2 = llvm.ashr %arg82, %arg83 : i8
  %3 = llvm.xor %2, %0 : i8
  %4 = llvm.and %1, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def add_const_const_sub_nsw_before := [llvm|
{
^0(%arg58 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(-127 : i8) : i8
  %2 = llvm.add %arg58, %0 : i8
  %3 = llvm.sub %1, %2 overflow<nsw> : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

@[simp] def Term.arity : Term → Nat
| (var n) => n+1
| zero => 0
| one => 0
| negOne => 0
| ofNat _ => 0
| Term.and t₁ t₂ => max (arity t₁) (arity t₂)
| Term.or t₁ t₂ => max (arity t₁) (arity t₂)
| Term.xor t₁ t₂ => max (arity t₁) (arity t₂)
| Term.not t => arity t
| add t₁ t₂ => max (arity t₁) (arity t₂)
| sub t₁ t₂ => max (arity t₁) (arity t₂)
| neg t => arity t


| shiftL t .. => arity t

def icmp_ugt_before := [llvm|
{
^0(%arg41 : i32, %arg42 : i32):
  %0 = llvm.lshr %arg41, %arg42 : i32
  %1 = llvm.icmp "ugt" %0, %arg41 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

def alive_AndOrXor_1704_tgt :=
[sllvm| {
^bb0(%A : i64, %B : i64):
  %v1 = llvm.mlir.constant -1 : i64
  %v2 = llvm.add %B, %v1 : i64
  %v3 = llvm.mlir.constant 0 : i64
  %v4 = llvm.icmp.eq %B, %v3 : i64
  %v5 = llvm.icmp.ult %A, %B : i64
  %v6 = llvm.icmp.uge %v2, %A : i64
  llvm.return %v6 : i1
}]

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

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

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

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

      
      let g ← revertBvHyps g

      
      
      let .some g ← NNF.runNNFSimpSet g
        | trace[Bits.Frontend] m!"Converting to negation normal form automatically closed goal."
          return ()
      trace[Bits.Frontend] m!"goal after NNF: {indentD g}"

      let .some g ← Simplifications.runPreprocessing g
        | trace[Bits.Frontend] m!"Preprocessing automatically closed goal."
          return ()
      trace[Bits.Frontend] m!"goal after preprocessing: {indentD g}"
      
      let result ← reflectPredicateAux ∅ (← g.getType) w
      let bvToIxMapVal ← result.exprToIx.toExpr w

      let target := (mkAppN (mkConst ``Predicate.denote) #[result.e.quote, w, bvToIxMapVal])
      let g ← g.replaceTargetDefEq target
      trace[Bits.Frontend] m!"goal after reflection: {indentD g}"
      return ()
| _  => throwUnsupportedSyntax

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

def Deleted (Γ: Ctxt Ty) (vs : DeleteRange Γ) (Γ' : Ctxt Ty) : Prop :=
  Γ' = Γ.delete vs

Std.Tactic.BVDecide.BVExpr.PackedBitVec in Std.Tactic.BVDecide.Bitblast.BVExpr.Basic

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

def and_xor_not_common_op_after := [llvm|
{
^0(%arg686 : i32, %arg687 : i32):
  %0 = llvm.and %arg686, %arg687 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

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

def add_or_sub_comb_i128_commuted3_nuw_nsw_before := [llvm|
{
^0(%arg14 : i128):
  %0 = llvm.mlir.constant(0 : i128) : i128
  %1 = llvm.mul %arg14, %arg14 : i128
  %2 = llvm.sub %0, %1 : i128
  %3 = llvm.or %1, %2 : i128
  %4 = llvm.add %3, %1 overflow<nsw,nuw> : i128
  "llvm.return"(%4) : (i128) -> ()
}
]

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

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

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

def t0_after := [llvm|
{
^0(%arg43 : i32, %arg44 : i32):
  %0 = llvm.mlir.constant(30 : i32) : i32
  %1 = llvm.lshr %arg43, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

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

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

@[simp_llvm]
def not? {w : Nat} (x : BitVec w) : IntW w := do
  .value (~~~x)

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

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

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

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

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

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

def foo1_or_commuted_before := [llvm|
{
^0(%arg145 : i32, %arg146 : i32, %arg147 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mul %arg145, %arg145 : i32
  %3 = llvm.shl %0, %arg146 : i32
  %4 = llvm.shl %0, %arg147 : i32
  %5 = llvm.and %2, %3 : i32
  %6 = llvm.icmp "ne" %5, %1 : i32
  %7 = llvm.and %4, %2 : i32
  %8 = llvm.icmp "ne" %7, %1 : i32
  %9 = llvm.and %6, %8 : i1
  "llvm.return"(%9) : (i1) -> ()
}
]

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

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

def xor {w : Nat} (l : List (BitVec w)) : BitVec w :=
  List.foldr BitVec.xor (BitVec.zero w) l

Flag in Mathlib.Order.Preorder.Chain

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

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

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

def addMax (a : BitVec v) (b : BitVec w) : BitVec (max v w + 1) :=
   a.zeroExtend _ + b.zeroExtend _

def add_mask_ashr27_i32_before := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(27 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.ashr %arg0, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.add %3, %2 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

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

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

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

def scalar_i8_shl_ult_const_3_after := [llvm|
{
^0(%arg17 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.and %arg17, %0 : i8
  %3 = llvm.icmp "eq" %2, %1 : i8
  "llvm.return"(%3) : (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⟩

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

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

def fold_nested_logic_zext_icmp_after := [llvm|
{
^0(%arg87 : i64, %arg88 : i64, %arg89 : i64, %arg90 : i64):
  %0 = llvm.icmp "sgt" %arg87, %arg88 : i64
  %1 = llvm.icmp "slt" %arg87, %arg89 : i64
  %2 = llvm.and %0, %1 : i1
  %3 = llvm.icmp "eq" %arg87, %arg90 : i64
  %4 = llvm.or %2, %3 : i1
  %5 = llvm.zext %4 : i1 to i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

def n2_after := [llvm|
{
^0(%arg19 : i1, %arg20 : i8, %arg21 : i8, %arg22 : i8, %arg23 : i8):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.icmp "eq" %arg20, %arg21 : i8
  %2 = llvm.xor %arg19, %0 : i1
  %3 = llvm.and %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def negate_xor_before := [llvm|
{
^0(%arg142 : i4):
  %0 = llvm.mlir.constant(5 : i4) : i4
  %1 = llvm.mlir.constant(0 : i4) : i4
  %2 = llvm.xor %arg142, %0 : i4
  %3 = llvm.sub %1, %2 : i4
  "llvm.return"(%3) : (i4) -> ()
}
]

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

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

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

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

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

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

def 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 Term where
  c : Int
  f : Factor
deriving Repr

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

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

def pb_before := [llvm|
{
^0(%arg13 : i65):
  %0 = llvm.mlir.constant(1 : i65) : i65
  %1 = llvm.shl %arg13, %0 : i65
  %2 = llvm.ashr exact %1, %0 : i65
  %3 = llvm.icmp "eq" %arg13, %2 : i65
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

NFA.stepSet in Mathlib.Computability.NFA

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

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

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 source : Expr (DC) Γ .pure (.tokenstream) :=
  Expr.mk
    (op := .source)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .nil)
    (regArgs := .nil)

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

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 composeQuinaryAux' (p : FSM (Fin 5)) (q₀ q₁ q₂ q₃ q₄: FSM α) : FSM α :=
  p.compose (α)
    (λ _ => α)
    (λ _ i => i)
    (λ v =>
      v.cases q₀ fun v =>
        v.cases q₁ fun v =>
          v.cases q₂ fun v =>
            v.cases q₃ fun v =>
              v.cases q₄ fun v => v.elim0)

def add_and_or_commutative_after := [llvm|
{
^0(%arg13 : i32, %arg14 : i32):
  %0 = llvm.add %arg13, %arg14 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

private def rgn0 : Region φ := ([mlir_region|  { }])

BEq.beq in Init.Prelude

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

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

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

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

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

def positive_samevar_shlnuwnsw_before := [llvm|
{
^0(%arg47 : i8, %arg48 : i8):
  %0 = llvm.ashr %arg47, %arg48 : i8
  %1 = llvm.shl %0, %arg48 overflow<nsw,nuw> : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

instance : HydrablePackedBitvecToSubstitutionValue GenBVPred GenBVExpr where
  packedBitVecToSubstitutionValue := packedBitVecToSubstitutionValue

List.Perm in Init.Data.List.Basic

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

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

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

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

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

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

def mul16_low_after := [llvm|
{
^0(%arg24 : i16, %arg25 : i16):
  %0 = llvm.mul %arg24, %arg25 : i16
  "llvm.return"(%0) : (i16) -> ()
}
]

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

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

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

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

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

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

def and_or_hoist_mask_before := [llvm|
{
^0(%arg91 : i8, %arg92 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.lshr %arg91, %0 : i8
  %3 = llvm.or %2, %arg92 : i8
  %4 = llvm.and %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def different_size_sext_sext_sgt_before := [llvm|
{
^0(%arg14 : i7, %arg15 : i4):
  %0 = llvm.sext %arg14 : i7 to i25
  %1 = llvm.sext %arg15 : i4 to i25
  %2 = llvm.icmp "sgt" %0, %1 : i25
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

noncomputable def to_prop (f : Bool → Bool → Bool) (p1 p2 : Prop) : Prop :=
  f (@Decidable.decide p1 (Classical.propDecidable _)) (@Decidable.decide p2 (Classical.propDecidable _))

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

WithBot.recBotCoe in Mathlib.Order.TypeTags

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

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

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

def and_ne_with_diff_one_signed_before := [llvm|
{
^0(%arg348 : i64):
  %0 = llvm.mlir.constant(-1) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.icmp "ne" %arg348, %0 : i64
  %3 = llvm.icmp "ne" %arg348, %1 : i64
  %4 = llvm.and %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

def three_inst_com_proof (w : Nat) :
    three_inst_com w ⊑ three_inst_com w :=

def add_hi_one_lo_negone_i64_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := add_hi_one_lo_negone_llvm_i64
  rhs := add_hi_one_lo_negone_riscv_i64

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

def negate_sext_after := [llvm|
{
^0(%arg98 : i8, %arg99 : i1):
  %0 = llvm.zext %arg99 : i1 to i8
  %1 = llvm.add %arg98, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

def Predicate.Env.empty : Predicate.Env 0 :=
  fun v => v.elim0

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

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

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

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

def llvm_const_lower_riscv_li_10 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_10, rhs:= liRiscv_10,
   correct := by admit /- proof elided -/

@[simp_denote]
def trunc_llvm_32_to_16 := [LV| {
  ^entry (%lhs: i32):
    %0 = llvm.trunc %lhs : i32 to i16
    llvm.return %0 : i16
  }]

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

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

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

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

def udiv_pow2 : List (Σ Γ, LLVMPeepholeRewriteRefine 64 Γ) :=
  [
    ⟨_, udiv_pow2_1⟩,
    ⟨_, udiv_pow2_2⟩,
    ⟨_, udiv_pow2_4⟩,
    ⟨_, udiv_pow2_8⟩,
    ⟨_, udiv_pow2_16⟩,
    ⟨_, udiv_pow2_32⟩,
    ⟨_, udiv_pow2_64⟩,
    ⟨_, udiv_pow2_128⟩,
    ⟨_, udiv_pow2_256⟩,
    ⟨_, udiv_pow2_512⟩
  ]

Bool.xor in Init.Data.Bool

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

Lean.Meta.whnfD in Lean.Meta.Basic

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

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

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

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

def t1_after := [llvm|
{
^0(%arg46 : i64, %arg47 : i32):
  %0 = llvm.mlir.constant(4294901760) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.and %arg46, %0 : i64
  %3 = llvm.icmp "ne" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

def addi_i64_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := addi_llvm_i64
  rhs := addi_riscv_i64

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

OptionT in Init.Control.Option

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

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

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

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

def test_sub_mul_neg_one_lhs_LHS := [mod_arith q, hq| {
  ^bb0(%x : !R, %y : !R):
    %neg_one = mod_arith.constant 41 : !R
    %mul = mod_arith.mul %neg_one, %x : !R
    %sub = mod_arith.sub %mul, %y : !R
    return %sub : !R
}]

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

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

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

def shl_add_nsw_before := [llvm|
{
^0(%arg10 : i8, %arg11 : i8):
  %0 = llvm.mlir.constant(-32 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.or %arg10, %0 : i8
  %3 = llvm.and %arg11, %1 : i8
  %4 = llvm.shl %2, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

Id in Init.Control.Id
</all_available_defs>

<all_available_lemmas>
Bool.false_eq_true in Init.Data.Bool
IsEmpty.exists_iff in Mathlib.Logic.IsEmpty
Option.isSome_none in Init.Data.Option.Basic
iff_false in Init.SimpLemmas
Option.get_some in Init.Data.Option.Basic
Option.isSome_iff_exists in Init.Data.Option.Lemmas
forall_exists_index in Init.PropLemmas
Exists.choose_spec in Init.Classical

@[simp] theorem map_cons : (Γ.cons a).map f = (Γ.map f).cons (f a)

theorem eq.ty_eq {v : Γ.Var t} {w : Γ.Var u} (h : v.eq w) : t = u

@[simp]
theorem Expr.op_mk {Γ : Ctxt d.Ty} {ty} {eff : EffectKind} (op : d.Op)
    (ty_eq : ty = DialectSignature.returnTypes op)
    (eff_le : DialectSignature.effectKind op ≤ eff)
    (args : HVector (Var Γ) (DialectSignature.sig op))
    (regArgs) :
    (Expr.mk op ty_eq eff_le args regArgs).op = op

@[simp]
theorem Expr.regArgs_mk {Γ : Ctxt d.Ty} {ty eff op}
    (ty_eq : ty = DialectSignature.returnTypes op)
    (eff_le : DialectSignature.effectKind op ≤ eff)
    (args : HVector (Var Γ) (DialectSignature.sig op)) (regArgs) :
    (Expr.mk op ty_eq eff_le args regArgs).regArgs = regArgs

@[simp] theorem appendCases_appendInl (v : Γ.Var t) :
    appendCases (motive := motive) left right v.appendInl = (left v)

@[simp]
theorem Expr.args_mk {Γ : Ctxt d.Ty} {ty eff op}
    (ty_eq : ty = DialectSignature.returnTypes op)
    (eff_le : DialectSignature.effectKind op ≤ eff)
    (args : HVector (Var Γ) (DialectSignature.sig op)) (regArgs) :
    (Expr.mk op ty_eq eff_le args regArgs).args = args

theorem Id.bind_eq' (x : Id α) (f : α → id β) : x >>= f = f x

@[simp] theorem Expr.denoteOp_eq_denoteOp_of {e₁ : Expr d Γ eff ty} {e₂ : Expr d Δ eff ty}
    {Γv : Valuation Γ} {Δv : Valuation Δ}
    (op_eq : e₁.op = e₂.op)
    (h_args : HVector.map Γv (op_eq ▸ e₁.args)
              = HVector.map Δv e₂.args)
    (h_regArgs : HEq e₁.regArgs.denote e₂.regArgs.denote) :
    e₁.denoteOp Γv = e₂.denoteOp Δv

theorem Id.pure_eq' (a : α) : (pure a : Id α) = a

theorem test6_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬3#32 ≥ ↑32 →
    ¬(3#32 ≥ ↑32 ∨
          True ∧ (x >>> 3#32).smulOverflow 3#32 = true ∨
            True ∧ (x >>> 3#32).umulOverflow 3#32 = true ∨ True ∧ (x >>> 3#32 * 3#32).msb = true) →
      signExtend 64 (x >>> 3#32 * 3#32) = zeroExtend 64 (x >>> 3#32 * 3#32)

theorem trunc_shl_7_i8_i64_thm.extracted_1._1 : ∀ (x : BitVec 64), ¬7#64 ≥ ↑64 → 7#8 ≥ ↑8 → False

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

theorem equiv_forkToken (streamT : DCOp.TokenStream) :
  (Handshake.fork streamT).fst ~ (forkToken.denote (Valuation.ofHVector (.cons streamT <| .nil))).fst

theorem src_fv_ne_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → ofBool (0#8 ||| x != 0#8) = ofBool (x != 0#8) ||

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

theorem bv_820' :
    ∀ (e e_1 : LLVM.IntW 9), LLVM.udiv (LLVM.sub e (LLVM.urem e e_1)) e_1 ⊑ LLVM.udiv e e_1

theorem not_and_and_or_no_or_commute1_proof : not_and_and_or_no_or_commute1_before ⊑ not_and_and_or_no_or_commute1_after

theorem and_not_or_commute5_proof : and_not_or_commute5_before ⊑ and_not_or_commute5_after

theorem positive_sameconst_shlnuwnsw_lshrexact_proof : positive_sameconst_shlnuwnsw_lshrexact_before ⊑ positive_sameconst_shlnuwnsw_lshrexact_after

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

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

theorem test9_proof : test9_before ⊑ test9_after

theorem test_sub_0_Y_ne_0_proof : test_sub_0_Y_ne_0_before ⊑ test_sub_0_Y_ne_0_after

theorem or_not_and_and_not_and_xor_proof : or_not_and_and_not_and_xor_before ⊑ or_not_and_and_not_and_xor_after

theorem positive_with_aggressive_icmp_logical_proof : positive_with_aggressive_icmp_logical_before ⊑ positive_with_aggressive_icmp_logical_after

theorem exactly_one_set_signbit_wrong_pred_proof : exactly_one_set_signbit_wrong_pred_before ⊑ exactly_one_set_signbit_wrong_pred_after

@[simp]
theorem concat_eq_sub_of_lt
    {b : Bool} {x : BitStream} {i : Nat} (hi : 0 < i) :
    concat b x i = x (i - 1)

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 lshr_mul_times_5_div_4_exact_thm.extracted_1._1 : ∀ (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 >>> 2#32) = true → False

theorem PR42691_10_proof : PR42691_10_before ⊑ PR42691_10_after

theorem bools_multi_uses1_logical_thm.extracted_1._18 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 ^^^ 1#1 = 1#1 → ¬x_2 = 1#1 → ¬0#1 = 1#1 → 0#1 ^^^ 0#1 = x_1 ^^^ 0#1

lemma helper_dec_enc (bvs : BitVecs n) (h : w' = bvs.w) i (j : Nat) :
    (bvs.bvs.get i)[j]?.getD false = (h ▸ bvs.bvs.get i)[j]?.getD false

theorem test1_thm (e : IntW 33) : urem e (const? 33 4096) ⊑ LLVM.and e (const? 33 4095)

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

@[simp] theorem getElem?_cons_succ (t : Ty) (i : Nat) : (Γ.cons t)[i+1]? = Γ[i]?

theorem e_625 :
     - 11 *  ~~~(x &&& y) - 1 * (x ||| y) + 2 * x + 4 *  ~~~y - 11 * (x ^^^ y) + 7 *  ~~~(x ^^^ y) - 6 *  ~~~(x &&&  ~~~y) + 6 *  ~~~(x ||| y) + 29 *  ~~~(x |||  ~~~y) - 2 * (x &&& y) =  - 17 * (x &&&  ~~~y)

@[simp] theorem eval_falseAfterIncluding (n : Nat) (i : Nat) {env : Fin 0 → BitStream} :
    (falseAfterIncluding n).eval env i = decide (i < n)

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

theorem Expr.denote_unfold (e : Expr d Γ eff ty) :
    e.denote = fun V => (· ++ V) <$> (e.denoteOp V)

theorem e_1780 :
    1 * (a &&& b) + 5 * (a |||  ~~~b) - 1 * a - 2 *  ~~~(a ||| c) + 7 *  ~~~(a &&& (b &&& c)) + 11 * b - 2 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 * ( ~~~b |||  ~~~(a ^^^ c)) - 2 * (c ^^^  ~~~(a |||  ~~~b)) + 1 * ((a &&& b) ^^^ (b |||  ~~~c)) - 3 * (c ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 3 * (a &&& (b ||| c)) + 1 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) - 2 * (c ^^^  ~~~(a &&&  ~~~b)) + 1 * (a ^^^ ( ~~~b ||| c)) - 5 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 2 * (b ^^^  ~~~(a &&&  ~~~c)) - 5 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) + 5 * (a ^^^ ( ~~~b &&& c)) + 5 *  ~~~(a &&&  ~~~a) + 11 * (b ^^^ (a ||| (b ||| c))) + 3 * (c ^^^  ~~~(a ||| (b &&& c))) + 3 * ((a ^^^ b) ||| (a ^^^ c)) + 2 * (b ||| (a &&& c)) - 1 * ( ~~~a ||| ( ~~~b ||| c)) + 11 * c - 5 * ( ~~~a &&& (b ||| c)) + 3 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) + 1 * (a ^^^ c) - 9 *  ~~~(a ||| (b ||| c)) - 13 *  ~~~(a ||| ( ~~~b ||| c)) - 31 *  ~~~( ~~~a ||| (b ||| c)) - 38 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 40 * ( ~~~a &&& ( ~~~b &&& c)) - 33 * ( ~~~a &&& (b &&& c)) - 44 * (a &&& ( ~~~b &&& c)) - 42 * (a &&& (b &&& c)) = 1 * (c &&& (a ||| b))

theorem t0_thm.extracted_1._27 : ∀ (x x_1 x_2 x_3 : BitVec 8) (x_4 : BitVec 1),
  x_4 ^^^ 1#1 = 1#1 → ¬x_4 = 1#1 → True → 0#1 = 1#1 → x_1 = x

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

theorem e_1266 :
    3 *  ~~~z + 1 * z + 11 *  ~~~(z &&&  ~~~z) - 6 * t - 1 *  ~~~(z &&& t) - 13 *  ~~~(z ||| t) - 9 *  ~~~(z |||  ~~~t) - 13 * (z &&&  ~~~t) - 6 * (z &&& t) =  - 2 * (z ^^^ t)

theorem ashrslt_02_09_thm (e : IntW 4) : icmp IntPred.slt (ashr e (const? 4 2)) (const? 4 (-7)) ⊑ const? 1 0

theorem and_not_or_or_not_or_xor_commute4_proof : and_not_or_or_not_or_xor_commute4_before ⊑ and_not_or_or_not_or_xor_commute4_after

theorem positive_biggershl_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(3#8 ≥ ↑8 ∨ 6#8 ≥ ↑8) → ¬3#8 ≥ ↑8 → x >>> 3#8 <<< 6#8 = x <<< 3#8 &&& BitVec.ofInt 8 (-64)

theorem shift_trunc_wrong_shift_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬23#32 ≥ ↑32 → ofBool (truncate 8 (x >>> 23#32) <ₛ 0#8) = ofBool (x &&& 1073741824#32 != 0#32)

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

theorem ofBool_0_iff_false : BitVec.ofBool b = 0#1 ↔ b = false

theorem clear_to_clear_decomposebittest_proof : clear_to_clear_decomposebittest_before ⊑ clear_to_clear_decomposebittest_after

theorem test7_proof : test7_before ⊑ test7_after

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

theorem in_constant_mone_vary_thm (e : IntW 4) :
  LLVM.xor (LLVM.and (LLVM.xor e (const? 4 (-1))) (const? 4 1)) e ⊑ LLVM.or e (const? 4 1)

theorem not_mul_of_bool_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  True ∧ (x_1 &&& 3#32).smulOverflow (zeroExtend 32 x) = true ∨
      True ∧ (x_1 &&& 3#32).umulOverflow (zeroExtend 32 x) = true →
    False

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

theorem test3_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.ssubOverflow x = true) →
    ¬ofBool (x_1 - x == 0#32) = 1#1 → ofBool (x_1 == x) = 1#1 → ofBool (x_1 - x == 31#32) = 1#1

theorem and_xor_or1_thm (e e_1 e_2 : IntW 64) :
  LLVM.or
      (LLVM.xor (LLVM.and (LLVM.udiv (const? 64 42) e_2) (LLVM.udiv (const? 64 42) e_1)) (LLVM.udiv (const? 64 42) e))
      (LLVM.udiv (const? 64 42) e_1) ⊑
    LLVM.or (LLVM.udiv (const? 64 42) e) (LLVM.udiv (const? 64 42) e_1)

theorem ugt_umax3_thm (e e_1 : IntW 32) :
  icmp IntPred.ult (add e_1 (const? 32 3))
      (select (icmp IntPred.ugt (add e_1 (const? 32 3)) e) (add e_1 (const? 32 3)) e) ⊑
    icmp IntPred.ugt e (add e_1 (const? 32 3))

@[simp, grind=] theorem getElem_ofList (i : Nat) (h : _) : (ofList ts)[i]'h = ts[i]'h

theorem logical_and_cond_reuse_proof : logical_and_cond_reuse_before ⊑ logical_and_cond_reuse_after

theorem exact_ashr_eq_proof : exact_ashr_eq_before ⊑ exact_ashr_eq_after

theorem ashrsgt_02_04_proof : ashrsgt_02_04_before ⊑ ashrsgt_02_04_after

theorem test14_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(4#16 ≥ ↑16 ∨ True ∧ (x >>> 4#16 &&& 1#16).saddOverflow (-1#16) = true) →
    signExtend 32 (ofBool (x &&& 16#16 != 16#16)) = signExtend 32 ((x >>> 4#16 &&& 1#16) + -1#16)

theorem select_icmp_eq_and_1_0_lshr_fv_thm (e e_1 : IntW 8) :
  select (icmp IntPred.eq (LLVM.and e_1 (const? 8 1)) (const? 8 0)) e (lshr e (const? 8 2)) ⊑
    lshr e (LLVM.and (shl e_1 (const? 8 1)) (const? 8 2))

theorem ashr_slt_exact_near_pow2_cmpval_proof : ashr_slt_exact_near_pow2_cmpval_before ⊑ ashr_slt_exact_near_pow2_cmpval_after

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

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

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

theorem sgt_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.slt e e_1) ⊑
    icmp IntPred.ne e_1 (const? 8 (-128))

theorem test45_proof : test45_before ⊑ test45_after

theorem p_constmask2_thm (e e_1 : IntW 32) :
  LLVM.or (LLVM.and e_1 (const? 32 61440)) (LLVM.and e (const? 32 (-65281))) ⊑
    LLVM.or (LLVM.and e_1 (const? 32 61440)) (LLVM.and e (const? 32 (-65281))) { «disjoint» := true }

@[simp] theorem cons_getElem_toCons (x : A a) (v : Var Γ u)
    (h : as = Γ.toList := by rfl) (h' : a :: as = (Γ.cons a).toList := by rfl) :
    (HVector.cons x xs)[v.toCons (t' := a)]'h' = xs[v]'h

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

theorem test1_proof : test1_before ⊑ test1_after

theorem trunc_sandwich_big_sum_shift1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(21#32 ≥ ↑32 ∨ 11#12 ≥ ↑12) → truncate 12 (x >>> 21#32) >>> 11#12 = 0#12

theorem src_is_mask_const_sle_proof : src_is_mask_const_sle_before ⊑ src_is_mask_const_sle_after

theorem both_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(x_1 ≥ ↑8 ∨ x ≥ ↑8) →
    ¬(True ∧ 1#8 <<< x >>> x ≠ 1#8 ∨ x ≥ ↑8 ∨ x_1 ≥ ↑8) →
      ofBool (1#8 <<< x_1 ≤ᵤ 1#8 <<< x) = ofBool (1#8 <<< x >>> x_1 != 0#8)

theorem bitwise_and_bitwise_and_icmps_comm2_proof : bitwise_and_bitwise_and_icmps_comm2_before ⊑ bitwise_and_bitwise_and_icmps_comm2_after

theorem p_commutative2_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ (x_1 &&& (x_2 ^^^ -1#32) &&& (x &&& x_2) != 0) = true) →
    (x_2 ^^^ -1#32) &&& x_1 ^^^ x &&& x_2 = x_1 &&& (x_2 ^^^ -1#32) ||

theorem test6_thm.extracted_1._1 : ∀ (x x_1 : BitVec 57), x_1 - (x_1 &&& x) = x_1 &&& (x ^^^ -1#57)

theorem udiv_exact_ne_0_proof : udiv_exact_ne_0_before ⊑ udiv_exact_ne_0_after

theorem different_size_zext_zext_sgt_thm.extracted_1._1 : ∀ (x : BitVec 4) (x_1 : BitVec 7),
  ofBool (zeroExtend 25 x <ₛ zeroExtend 25 x_1) = ofBool (zeroExtend 7 x <ᵤ x_1)

theorem e_96 :
    4 *  ~~~y + 7 *  ~~~x - 7 * (x ||| y) - 2 * (x ^^^ y) - 5 *  ~~~(x |||  ~~~y) - 2 * (x &&&  ~~~y) =  - 7 *  ~~~(x &&&  ~~~x) + 18 *  ~~~(x ||| y)

theorem t_2_192_proof : t_2_192_before ⊑ t_2_192_after

theorem lshrugt_02_10_thm (e : IntW 4) : icmp IntPred.ugt (lshr e (const? 4 2)) (const? 4 (-6)) ⊑ const? 1 0

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

theorem ashrsgt_02_06_proof : ashrsgt_02_06_before ⊑ ashrsgt_02_06_after

theorem test15f_thm (e : IntW 32) :
  select (icmp IntPred.ne (LLVM.and e (const? 32 128)) (const? 32 0)) (const? 32 0) (const? 32 256) ⊑
    LLVM.xor (LLVM.and (shl e (const? 32 1)) (const? 32 256)) (const? 32 256)

theorem select_icmp_eq_pow2_thm (e : IntW 8) :
  select (icmp IntPred.eq (LLVM.and e (const? 8 4)) (const? 8 0)) e (LLVM.xor e (const? 8 4)) ⊑
    LLVM.and e (const? 8 (-5))

theorem t7_ugt_sgt_neg1_thm.extracted_1._6 : ∀ (x x_1 : BitVec 32),
  ofBool (143#32 <ᵤ x_1 + 16#32) = 1#1 →
    ¬ofBool (BitVec.ofInt 32 (-17) <ₛ x_1) = 1#1 → ofBool (127#32 <ₛ x_1) = 1#1 → False

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

theorem test3a_proof : test3a_before ⊑ test3a_after

theorem e_2023 :
     - 1 * (f ^^^ ( ~~~d ||| (e ||| f))) + 2 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 3 * (e ^^^ (d &&& ( ~~~e ||| f))) - 11 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 3 * (e &&&  ~~~(d ^^^ f)) - 2 * ((d &&& f) ^^^ (e ||| f)) - 7 * ((d ||| e) &&& (e ^^^ f)) - 6 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 2 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 7 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 1 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) + 11 *  ~~~(d ||| e) + 1 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 6 * (d ||| ( ~~~e ||| f)) + 2 *  ~~~f + 2 * ( ~~~d &&& (e ||| f)) - 1 * ( ~~~d ||| (e &&& f)) + 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 3 * (d ^^^ f) - 7 * (d &&& (e ||| f)) - 1 * (d ||| (e ||| f)) - 1 * (e ^^^ (d ||| (e ||| f))) + 3 * (e ^^^ ( ~~~d &&& (e ||| f))) + 1 * (e ^^^  ~~~(d &&& (e ||| f))) + 4 * (e ^^^ ( ~~~d ||| (e ||| f))) - 9 *  ~~~(d ||| (e ||| f)) + 13 *  ~~~(d ||| ( ~~~e ||| f)) + 15 *  ~~~( ~~~d ||| (e ||| f)) + 36 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 8 * ( ~~~d &&& ( ~~~e &&& f)) + 25 * ( ~~~d &&& (e &&& f)) + 29 * (d &&& ( ~~~e &&& f)) + 18 * (d &&& (e &&& f)) = 1 * ( ~~~d ||| (e ||| f))

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

theorem lshr_pow2_slt_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → True ∧ BitVec.ofInt 8 (-128) >>> x <<< x ≠ BitVec.ofInt 8 (-128) ∨ x ≥ ↑8 → False

theorem lshr_mul_nuw_nsw_proof : lshr_mul_nuw_nsw_before ⊑ lshr_mul_nuw_nsw_after

theorem e_2013 :
    5 * (e |||  ~~~(d ||| f)) - 3 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 3 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 11 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 2 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 2 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 5 *  ~~~(e ||| f) - 11 * ((d &&& e) |||  ~~~(e ||| f)) - 6 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 2 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 7 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) - 6 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 7 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 2 * (e ^^^ f) + 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 2 * (e ^^^ (d ||| (e &&& f))) + 5 *  ~~~(e |||  ~~~f) - 11 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 5 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 5 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 5 * (f ^^^ (d ||| (e &&& f))) + 4 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 2 * (f ^^^  ~~~(d &&& e)) + 4 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 10 *  ~~~(d ||| (e ||| f)) - 1 *  ~~~(d ||| ( ~~~e ||| f)) + 11 *  ~~~( ~~~d ||| (e ||| f)) + 26 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 14 * ( ~~~d &&& ( ~~~e &&& f)) - 4 * ( ~~~d &&& (e &&& f)) + 13 * (d &&& ( ~~~e &&& f)) + 18 * (d &&& (e &&& f)) = 1 * (e ^^^  ~~~(d ||| (e &&& f))) + 3 * (d &&&  ~~~f)

theorem src_x_and_nmask_slt_fail_maybe_z_proof : src_x_and_nmask_slt_fail_maybe_z_before ⊑ src_x_and_nmask_slt_fail_maybe_z_after

theorem narrow_zext_or_proof : narrow_zext_or_before ⊑ narrow_zext_or_after

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

theorem test51_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  x_1 = 1#1 →
    ¬(True ∧ (truncate 32 x &&& BitVec.ofInt 32 (-2) &&& zeroExtend 32 (x_1 ^^^ 1#1) != 0) = true) →
      signExtend 64 (truncate 32 x &&& BitVec.ofInt 32 (-2)) =
        signExtend 64 (truncate 32 x &&& BitVec.ofInt 32 (-2) ||| zeroExtend 32 (x_1 ^^^ 1#1))

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

theorem ashr_ugt_14_proof : ashr_ugt_14_before ⊑ ashr_ugt_14_after

theorem t0_proof : t0_before ⊑ t0_after

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

theorem t1_proof : t1_before ⊑ t1_after

@[simp]
theorem eval_bigAnd_eq_true_iff
    (cs : List (Circuit α)) (env : α → Bool):
    (Circuit.bigAnd cs).eval env = true ↔
    (∀ (c : Circuit α), c ∈ cs → c.eval env = true)

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

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

theorem lshr_eq_opposite_msb_proof : lshr_eq_opposite_msb_before ⊑ lshr_eq_opposite_msb_after

theorem test6_proof : test6_before ⊑ test6_after

theorem icmp_equality_test_commute_select1_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 64),
  ¬ofBool (x_2 == x_1) = 1#1 → ofBool (x == x_1) = 1#1 → 0#1 = ofBool (x_2 == x)

theorem sgt_or_not_min_commute_logical_proof : sgt_or_not_min_commute_logical_before ⊑ sgt_or_not_min_commute_logical_after

theorem icmp_slt_0_or_icmp_sgt_0_i64_fail3_proof : icmp_slt_0_or_icmp_sgt_0_i64_fail3_before ⊑ icmp_slt_0_or_icmp_sgt_0_i64_fail3_after

theorem sge_swap_and_max_commute_proof : sge_swap_and_max_commute_before ⊑ sge_swap_and_max_commute_after

theorem FSM.and_eq (a b : FSM arity) : (a &&& b) = composeBinaryAux' FSM.and a b

theorem l_proof : l_before ⊑ l_after

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

theorem test_shift_and_cmp_changed4_proof : test_shift_and_cmp_changed4_before ⊑ test_shift_and_cmp_changed4_after

theorem t17_nocse_mismatching_x_proof : t17_nocse_mismatching_x_before ⊑ t17_nocse_mismatching_x_after

theorem ashr_mul_sign_bits_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬3#32 ≥ ↑32 →
    ¬(True ∧ (signExtend 16 x_1).smulOverflow (signExtend 16 x) = true ∨ 3#16 ≥ ↑16) →
      truncate 16 ((signExtend 32 x_1 * signExtend 32 x).sshiftRight' 3#32) =
        (signExtend 16 x_1 * signExtend 16 x).sshiftRight' 3#16

theorem or_and3_commuted_thm.extracted_1._3 : ∀ (x : BitVec 1) (x_1 x_2 : BitVec 32),
  ofBool (x_2 == x_1) ||

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

theorem eq_nuw_rem_nz_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.umulOverflow (BitVec.ofInt 8 (-5)) = true) → ofBool (x * BitVec.ofInt 8 (-5) == 20#8) = 0#1

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

theorem e_281 :
     - 1 *  ~~~(x &&&  ~~~x) - 11 * (x ||| y) - 1 *  ~~~(x &&&  ~~~y) - 7 * (x ^^^ y) + 2 *  ~~~(x ||| y) + 20 * (x &&&  ~~~y) + 14 * (x &&& y) =  - 20 *  ~~~(x |||  ~~~y) + 1 * x

theorem icmp_eq_zext_eq_zero_proof : icmp_eq_zext_eq_zero_before ⊑ icmp_eq_zext_eq_zero_after

theorem and_ashr_not_commuted_proof : and_ashr_not_commuted_before ⊑ and_ashr_not_commuted_after

theorem t3_no_extrause_thm (e e_1 : IntW 8) :
  icmp IntPred.uge (LLVM.xor e_1 (const? 8 (-1))) e ⊑
    icmp IntPred.ule e (LLVM.xor e_1 (const? 8 (-1)))

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

theorem icmp_eq_x_invertable_y2_todo_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → ofBool (x_1 ^^^ -1#8 == x ||| x_1 ^^^ -1#8) = ofBool (x &&& x_1 == 0#8)

theorem ashrsgt_03_07_proof : ashrsgt_03_07_before ⊑ ashrsgt_03_07_after

theorem bools2_logical_commute1_and1_and2_proof : bools2_logical_commute1_and1_and2_before ⊑ bools2_logical_commute1_and1_and2_after

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

theorem scalar_i16_signbit_lshr_and_eq_proof : scalar_i16_signbit_lshr_and_eq_before ⊑ scalar_i16_signbit_lshr_and_eq_after

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

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

theorem no_shift_xor_multiuse_cmp_with_and_proof : no_shift_xor_multiuse_cmp_with_and_before ⊑ no_shift_xor_multiuse_cmp_with_and_after

theorem reassoc_x2_add_nuw_proof : reassoc_x2_add_nuw_before ⊑ reassoc_x2_add_nuw_after

theorem main5_like_proof : main5_like_before ⊑ main5_like_after

theorem addhshlhsdivhnegative1_thm (e : IntW 32) :
  add (shl (LLVM.sdiv e (const? 32 (-1))) (const? 32 1)) e ⊑ sub (const? 32 0) e

theorem sub_zext_trunc_lshr_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬15#64 ≥ ↑64 →
    16#32 ≥ ↑32 ∨ 31#32 ≥ ↑32 ∨ True ∧ ((truncate 32 x <<< 16#32).sshiftRight' 31#32).saddOverflow 10#32 = true →
      False

theorem and_zext_eq_even_thm (e : IntW 32) : LLVM.and e (zext 32 (icmp IntPred.eq e (const? 32 2))) ⊑ const? 32 0

theorem src_is_mask_const_sle_proof : src_is_mask_const_sle_before ⊑ src_is_mask_const_sle_after

theorem or_sext_sext_thm.extracted_1._1 : ∀ (x : BitVec 4) (x_1 : BitVec 8),
  signExtend 16 x_1 ||

theorem main5c_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 → ¬ofBool (x &&& 7#32 != 7#32) = 1#1 → 1#32 = zeroExtend 32 0#1

theorem select_replace_one_use_thm (e e_1 : IntW 32) :
  select (icmp IntPred.eq e_1 (const? 32 0)) (sub e_1 e) e ⊑
    select (icmp IntPred.eq e_1 (const? 32 0)) (sub (const? 32 0) e) e

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

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

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

theorem udiv_illegal_type_c_thm.extracted_1._2 : ∀ (x : BitVec 9),
  ¬10#32 = 0 → ¬(10#9 = 0 ∨ True ∧ (x / 10#9).msb = true) → zeroExtend 32 x / 10#32 = zeroExtend 32 (x / 10#9)

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

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

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

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

theorem n10_ugt_slt_proof : n10_ugt_slt_before ⊑ n10_ugt_slt_after

theorem trunc_shl_1_i32_i64_proof : trunc_shl_1_i32_i64_before ⊑ trunc_shl_1_i32_i64_after

theorem lshr_eq_both_equal_proof : lshr_eq_both_equal_before ⊑ lshr_eq_both_equal_after

theorem test59_thm (e e_1 : IntW 8) :
  zext 64 (LLVM.or (lshr (zext 32 e_1) (const? 32 4)) (LLVM.and (shl (zext 32 e) (const? 32 4)) (const? 32 48))) ⊑
    zext 64
      (LLVM.or (LLVM.and (shl (zext 32 e) (const? 32 4) { «nsw» := true, «nuw» := true }) (const? 32 48))
        (zext 32 (lshr e_1 (const? 8 4)) { «nneg» := true }) { «disjoint» := true })
      { «nneg» := true }

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

theorem p_constmask_commutative_thm (e e_1 : IntW 32) :
  add (LLVM.and e_1 (const? 32 (-65281))) (LLVM.and e (const? 32 65280)) ⊑
    LLVM.or (LLVM.and e_1 (const? 32 (-65281))) (LLVM.and e (const? 32 65280)) { «disjoint» := true }

theorem e_1704 :
    5 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) - 1 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 2 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) + 2 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 5 * (c ^^^  ~~~(a &&& b)) - 3 * (b ||| (a &&& c)) - 2 *  ~~~(a &&& ( ~~~b &&& c)) + 2 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) + 7 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) + 2 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) + 7 * ((a ||| b) &&&  ~~~(b ^^^ c)) - 11 * (c ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 1 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 6 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) + 3 * ( ~~~a ||| ( ~~~b ||| c)) - 3 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) + 1 * (a ^^^ (b &&& c)) + 1 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) - 11 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) - 7 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 1 * ((a &&& b) |||  ~~~(b ^^^ c)) - 16 *  ~~~(a ||| (b ||| c)) + 24 *  ~~~(a ||| ( ~~~b ||| c)) + 13 *  ~~~( ~~~a ||| (b ||| c)) + 15 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 16 * ( ~~~a &&& ( ~~~b &&& c)) + 4 * ( ~~~a &&& (b &&& c)) - 7 * (a &&& ( ~~~b &&& c)) + 3 * (a &&& (b &&& c)) =  - 4 * (c ^^^ ( ~~~a ||| (b ||| c)))

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

theorem n2_proof : n2_before ⊑ n2_after

theorem test_add_nuw_nsw__all_are_safe_proof : test_add_nuw_nsw__all_are_safe_before ⊑ test_add_nuw_nsw__all_are_safe_after

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

theorem test10_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 2#32 == 0#32) = 1#1 → 0#1 = ofBool (x <ᵤ 2#32)

theorem modulo32_proof : modulo32_before ⊑ modulo32_after

theorem bools_logical_commute0_and2_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1),
  x_1 ^^^ 1#1 = 1#1 → x_1 = 1#1 → x = 1#1 → False

theorem uge_swap_and_max_proof : uge_swap_and_max_before ⊑ uge_swap_and_max_after

theorem sdiv_shl_pair2_thm (e e_1 e_2 : IntW 32) :
  LLVM.sdiv (shl e_2 e_1 { «nsw» := true, «nuw» := true }) (shl e_2 e { «nsw» := true, «nuw» := false }) ⊑
    lshr (shl (const? 32 1) e_1 { «nsw» := true, «nuw» := true }) e

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

@[simp]
lemma Set.mem_cast (A : W → Type) (P : A w → Prop) (h : w = w') (x : A w') :
  x ∈ h ▸ setOf P ↔
  P (h ▸ x)

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

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

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

theorem squared_nsw_sgt0_thm.extracted_1._1 : ∀ (x : BitVec 5),
  ¬(True ∧ x.smulOverflow x = true) → ofBool (0#5 <ₛ x * x) = ofBool (x != 0#5)

theorem test29_proof : test29_before ⊑ test29_after

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

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

theorem ashr_2_add_zext_basic_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  ¬1#2 ≥ ↑2 → True ∧ (zeroExtend 2 x_1).uaddOverflow (zeroExtend 2 x) = true ∨ 1#2 ≥ ↑2 → False

theorem test_add_nsw__all_are_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 1073741823#32 == 3#32) = 1#1 →
    True ∧ (x &&& 1073741823#32).saddOverflow 1#32 = true ∨ True ∧ (x &&& 1073741823#32).uaddOverflow 1#32 = true →
      False

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

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

theorem xor_and_logic_or2_proof : xor_and_logic_or2_before ⊑ xor_and_logic_or2_after

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

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

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

theorem no_shift_xor_multiuse_cmp_and_proof : no_shift_xor_multiuse_cmp_and_before ⊑ no_shift_xor_multiuse_cmp_and_after

theorem sext_shl_mask_proof : sext_shl_mask_before ⊑ sext_shl_mask_after

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

@[simp]
lemma complete_cast {M : NFA α σ} (h : σ = ς) : (h ▸ M).Complete ↔ M.Complete

@[simp] theorem dropUntilHom_last : dropUntilHom (v := Var.last Γ ty) = Hom.id.consRight

lemma bisimul_eval_one (hsim : Bisimul R M₁ M₂) :
    R.set_eq Q₁ Q₂ → R.set_eq (M₁.stepSet Q₁ a) (M₂.stepSet Q₂ a)

omit [Fintype S] [DecidableEq S] in
lemma processOneElem_trans_preserve (st : worklist.St A S) (final : S → Bool) (a b : A) (sa : S) (s s1 s2 : State) :
    s2 ∈ st.m.tr s1 b →
    s2 ∈ (processOneElem A S final s st (a, sa)).m.tr s1 b

theorem e_2325 :
    1 * (e ^^^ (d ||| ( ~~~e &&& f))) - 1 *  ~~~(d &&& (e ^^^ f)) + 2 * (e ^^^  ~~~(d ||| f)) + 1 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) - 6 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 3 * (e |||  ~~~(d ||| f)) - 1 *  ~~~(d ^^^ (e &&& f)) + 4 * ( ~~~d ||| (e &&& f)) + 1 * (e ^^^ f) + 11 * ((d &&& f) ^^^ (e ||| f)) - 1 * (e ^^^  ~~~(d &&& (e &&& f))) + 7 * (e ^^^ (d &&& f)) + 2 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 2 * (e |||  ~~~f) - 1 *  ~~~(d &&& e) - 11 * (f &&& (d ^^^ e)) - 7 * ( ~~~f &&&  ~~~(d ^^^ e)) - 2 *  ~~~( ~~~d &&& (e ^^^ f)) - 1 *  ~~~( ~~~d &&& (e ||| f)) + 3 * (d &&& (e ^^^ f)) + 1 * (e ^^^  ~~~(d ||| (e &&& f))) + 7 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 1 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 6 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 1 * (f ^^^ (d ||| (e ||| f))) - 11 *  ~~~(e ||| f) + 2 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 3 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 1 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 2 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 2 * (d ^^^ (e &&& f)) + 3 *  ~~~(d &&& ( ~~~e &&& f)) + 5 *  ~~~(d ^^^ ( ~~~e ||| f)) + 1 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 5 *  ~~~( ~~~d ||| (e ^^^ f)) + 4 * ( ~~~e &&&  ~~~(d ^^^ f)) - 5 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 5 * (d &&&  ~~~e) + 7 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 7 * (f ^^^ ( ~~~d &&& (e ||| f))) - 1 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 6 * ((d ^^^ e) &&& (d ^^^ f)) + 2 * (e |||  ~~~(d ^^^ f)) + 1 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 7 * ((d ||| e) &&& (e ^^^ f)) + 11 * (f ^^^  ~~~(d &&& e)) - 2 * (e ^^^ ( ~~~d ||| (e &&& f))) + 7 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 4 * ( ~~~d &&& (e ||| f)) + 2 *  ~~~(d ^^^ e) + 3 *  ~~~( ~~~d ||| (e &&& f)) + 5 * (f ^^^ ( ~~~d ||| (e ||| f))) - 6 * (f ^^^  ~~~(d ||| e)) - 5 * ((d &&& e) |||  ~~~(e ^^^ f)) + 2 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 2 * (d ||| f) + 6 *  ~~~(d ||| (e ||| f)) - 47 *  ~~~(d ||| ( ~~~e ||| f)) - 10 *  ~~~( ~~~d ||| (e ||| f)) - 27 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 23 * ( ~~~d &&& ( ~~~e &&& f)) - 10 * ( ~~~d &&& (e &&& f)) - 22 * (d &&& ( ~~~e &&& f)) - 26 * (d &&& (e &&& f)) =  - 2 * (f |||  ~~~(d ||| e)) + 3 *  ~~~(d ||| (e &&& f))

theorem udiv2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(x ≥ ↑32 ∨ True ∧ x_1.umod (1#32 <<< x) ≠ 0 ∨ 1#32 <<< x = 0) →
    ¬(True ∧ x_1 >>> x <<< x ≠ x_1 ∨ x ≥ ↑32) → x_1 / 1#32 <<< x = x_1 >>> x

theorem zext_ashr_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬2#16 ≥ ↑16 →
    ¬(2#8 ≥ ↑8 ∨ True ∧ (x >>> 2#8 &&& x).msb = true) →
      (zeroExtend 16 x).sshiftRight' 2#16 &&& zeroExtend 16 x = zeroExtend 16 (x >>> 2#8 &&& x)

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

theorem e_387 :
    5 * x + 2 * (x ||| y) + 7 *  ~~~y - 11 * (x ^^^ y) - 7 *  ~~~(x ||| y) + 12 *  ~~~(x |||  ~~~y) - 3 * (x &&&  ~~~y) - 7 * (x &&& y) =  - 3 * (x |||  ~~~y) + 3 *  ~~~(x &&&  ~~~x)

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

theorem ashr_mul_sign_bits_proof : ashr_mul_sign_bits_before ⊑ ashr_mul_sign_bits_after

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

theorem not_and_and_or_not_or_or_commute1_proof : not_and_and_or_not_or_or_commute1_before ⊑ not_and_and_or_not_or_or_commute1_after

theorem eq_umax1_proof : eq_umax1_before ⊑ eq_umax1_after

theorem sge_swap_or_not_max_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.sle e_1 e) (const? 1 1) (icmp IntPred.ne e (const? 8 127)) ⊑ const? 1 1

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

theorem sge_or_not_max_logical_proof : sge_or_not_max_logical_before ⊑ sge_or_not_max_logical_after

theorem negtest_near_pow2_cmpval_ashr_slt_noexact_proof : negtest_near_pow2_cmpval_ashr_slt_noexact_before ⊑ negtest_near_pow2_cmpval_ashr_slt_noexact_after

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

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

theorem sub_3_proof : sub_3_before ⊑ sub_3_after

theorem t1_flags_nuw_first_proof : t1_flags_nuw_first_before ⊑ t1_flags_nuw_first_after

theorem test_add_nuw_nsw__nsw_is_safe_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x ||| BitVec.ofInt 32 (-2147483648) == -1#32) = 1#1 →
    ¬(True ∧ (x ||| BitVec.ofInt 32 (-2147483648)).saddOverflow 1#32 = true ∨
          True ∧ (x ||| BitVec.ofInt 32 (-2147483648)).uaddOverflow 1#32 = true) →
      True ∧ (x ||| BitVec.ofInt 32 (-2147483648)).saddOverflow 1#32 = true → False

theorem and_or2_wrong_operand_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 1),
  ¬(x_2 ^^^ 1#1) &&& x_1 = 1#1 → x_1 &&& (x_2 ^^^ 1#1) = 1#1 → False

theorem not_sub_eq_not_add :
    ~~~ (x - y) = ~~~x + y

theorem e_290 :
    5 *  ~~~(x ^^^ y) + 2 * x + 2 *  ~~~(x &&&  ~~~y) + 11 *  ~~~(x &&& y) - 18 *  ~~~(x ||| y) - 13 *  ~~~(x |||  ~~~y) - 13 * (x &&&  ~~~y) = 9 * (x &&& y)

theorem add_assoc_1 (hq : q >= t) (hu : u >= t) :
  (bw t (addMax (bw u (addMax (bw p a) (bw r b))) (bw s c))) =
  (bw t (addMax (bw p a) (bw q (addMax (bw r b) (bw s c)))))

theorem test28_proof : test28_before ⊑ test28_after

theorem mul_x_selectp2_thm.extracted_1._2 : ∀ (x : BitVec 1) (x_1 : BitVec 8),
  x = 1#1 → ¬3#8 ≥ ↑8 → x_1 * x_1 * 8#8 = (x_1 * x_1) <<< 3#8

theorem mul_of_sdiv_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(True ∧ x.smod 12#8 ≠ 0 ∨ (12#8 == 0 || 8 != 1 && x == intMin 8 && 12#8 == -1) = true) →
    ¬(True ∧ x >>> 1#8 <<< 1#8 ≠ x ∨ 1#8 ≥ ↑8 ∨ True ∧ (0#8).ssubOverflow (x.sshiftRight' 1#8) = true) →
      x.sdiv 12#8 * BitVec.ofInt 8 (-6) = 0#8 - x.sshiftRight' 1#8

theorem test42_proof : test42_before ⊑ test42_after

theorem orcond_proof : orcond_before ⊑ orcond_after

theorem sub_ashr_and_i32_thm (e e_1 : IntW 32) :
  LLVM.and (ashr (sub e_1 e { «nsw» := true, «nuw» := false }) (const? 32 31)) e ⊑
    select (icmp IntPred.slt e_1 e) e (const? 32 0)

theorem alive_AndOrXor_2118___A__B__A___A__B  (w : Nat)   : alive_AndOrXor_2118___A__B__A___A__B_src w  ⊑ alive_AndOrXor_2118___A__B__A___A__B_tgt w

theorem t4_c1_proof : t4_c1_before ⊑ t4_c1_after

theorem test_add_nuw_nsw__all_are_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 1073741823#32 == 3#32) = 1#1 →
    ¬(True ∧ (x &&& 1073741823#32).saddOverflow 1#32 = true ∨ True ∧ (x &&& 1073741823#32).uaddOverflow 1#32 = true) →
      4#32 = (x &&& 1073741823#32) + 1#32

theorem ule_swap_or_min_commute_proof : ule_swap_or_min_commute_before ⊑ ule_swap_or_min_commute_after

theorem main6c_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 7#32 != 3#32) = 1#1 → ¬True → 0#32 = zeroExtend 32 (ofBool (x &&& 55#32 == 19#32))

theorem sub_from_constant_thm.extracted_1._1 : ∀ (x x_1 : BitVec 5), 10#5 - x_1 + x = x - x_1 + 10#5

theorem lshr_32_add_zext_trunc_proof : lshr_32_add_zext_trunc_before ⊑ lshr_32_add_zext_trunc_after

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

theorem main7f_logical_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 &&& x_1 == x &&& (x_2 &&& x_1)) = 1#1 →
    ¬ofBool (x_2 &&& x_1 != x &&& (x_2 &&& x_1)) = 1#1 → ¬0#1 = 1#1 → False

theorem select_icmp_and_2147483648_ne_0_xor_2147483648_proof : select_icmp_and_2147483648_ne_0_xor_2147483648_before ⊑ select_icmp_and_2147483648_ne_0_xor_2147483648_after

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

theorem ashrslt_01_10_exact_thm (e : IntW 4) :
  icmp IntPred.slt (ashr e (const? 4 1) { «exact» := true }) (const? 4 (-6)) ⊑ const? 1 0

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

theorem select_xor_icmp_bad_5_proof : select_xor_icmp_bad_5_before ⊑ select_xor_icmp_bad_5_after

theorem test_shl_nuw__all_are_safe_thm (e : IntW 64) (e_1 : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e_1 (const? 32 15)) (const? 32 0)) e
      (ashr e (zext 64 (shl (LLVM.and e_1 (const? 32 15)) (const? 32 2) { «nsw» := false, «nuw» := true }))) ⊑
    ashr e (zext 64 (LLVM.and (shl e_1 (const? 32 2)) (const? 32 60)) { «nneg» := true })

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

theorem src_is_mask_const_sle_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool ((x ^^^ 123#8) &&& 31#8 ≤ₛ x ^^^ 123#8) = ofBool (-1#8 <ₛ x)

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

theorem sub_shl_same_amount_partial_nsw2_thm (e e_1 e_2 : IntW 6) :
  sub (shl e_2 e_1) (shl e e_1 { «nsw» := true, «nuw» := false }) { «nsw» := true, «nuw» := false } ⊑
    shl (sub e_2 e) e_1

theorem test_add_nuw__nuw_is_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 2147483647#32 == 2147483647#32) = 1#1 → True ∧ (x &&& 2147483647#32).uaddOverflow 1#32 = true → False

theorem ule_umax4_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_03_05_proof : ashrsgt_03_05_before ⊑ ashrsgt_03_05_after

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

theorem scalar_i32_shl_and_negC_eq_X_is_constant2_proof : scalar_i32_shl_and_negC_eq_X_is_constant2_before ⊑ scalar_i32_shl_and_negC_eq_X_is_constant2_after

theorem exact_lshr_ne_proof : exact_lshr_ne_before ⊑ exact_lshr_ne_after

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

theorem src_x_and_nmask_slt_proof : src_x_and_nmask_slt_before ⊑ src_x_and_nmask_slt_after

theorem test8_thm.extracted_1._1 : ∀ (x : BitVec 8), x &&& 3#8 &&& 4#8 = 0#8

theorem add_2_proof : add_2_before ⊑ add_2_after

theorem scalar_i16_shl_ult_const_proof : scalar_i16_shl_ult_const_before ⊑ scalar_i16_shl_ult_const_after

theorem mul_of_bool_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ofBool (255#32 <ᵤ (x_1 &&& 1#32) * zeroExtend 32 x) = 0#1

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

theorem ashrslt_03_13_proof : ashrslt_03_13_before ⊑ ashrslt_03_13_after

theorem no_shift_xor_multiuse_or_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (0#32 != x_1 &&& 4096#32) = 1#1 →
    (x ||| 4096#32) * (x ||| 4096#32) = (x ||| x_1 &&& 4096#32 ^^^ 4096#32) * (x ||| 4096#32)

theorem ashrslt_03_07_proof : ashrslt_03_07_before ⊑ ashrslt_03_07_after

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

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

theorem multiuse_select_thm (e : IntW 1) :
  mul (select e (const? 64 64) (const? 64 0)) (sub (select e (const? 64 64) (const? 64 0)) (zext 64 e)) ⊑
    select e (const? 64 4032) (const? 64 0)

theorem ne_210_thm (e e_1 : IntW 32) :
  LLVM.or (icmp IntPred.ne (trunc 8 (lshr e_1 (const? 32 16))) (trunc 8 (lshr e (const? 32 16))))
      (LLVM.or (icmp IntPred.ne (trunc 8 e_1) (trunc 8 e))
        (icmp IntPred.ne (trunc 8 (lshr e_1 (const? 32 8))) (trunc 8 (lshr e (const? 32 8))))) ⊑
    icmp IntPred.ne (trunc 24 e_1) (trunc 24 e)

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

theorem test4_proof : test4_before ⊑ test4_after

theorem band_lor_left2_proof : band_lor_left2_before ⊑ band_lor_left2_after

theorem test21_thm (e : IntW 12) :
  icmp IntPred.eq (shl e (const? 12 6)) (const? 12 (-128)) ⊑
    icmp IntPred.eq (LLVM.and e (const? 12 63)) (const? 12 62)

theorem icmp_equality_test_commute_icmp2_proof : icmp_equality_test_commute_icmp2_before ⊑ icmp_equality_test_commute_icmp2_after

theorem test_negative_combined_sub_signed_overflow_proof : test_negative_combined_sub_signed_overflow_before ⊑ test_negative_combined_sub_signed_overflow_after

theorem icmp_and_ashr_multiuse_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬4#32 ≥ ↑32 →
    ofBool (x.sshiftRight' 4#32 &&& 15#32 != 14#32) = 1#1 →
      ofBool (x.sshiftRight' 4#32 &&& 31#32 != 27#32) =
        ofBool (x &&& 240#32 != 224#32) &&& ofBool (x &&& 496#32 != 432#32)

theorem shl_ashr_pow2_const_case1_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(x ≥ ↑16 ∨ 6#16 ≥ ↑16) → ofBool (x == 7#16) = 1#1 → (4#16 <<< x).sshiftRight' 6#16 &&& 8#16 = 8#16

theorem and_or2_thm.extracted_1._7 : ∀ (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 = x

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

theorem masked_bit_wrong_pred_thm (e e_1 : IntW 32) :
  zext 32 (icmp IntPred.sgt (LLVM.and (shl (const? 32 1) e_1) e) (const? 32 0)) ⊑
    zext 32
      (icmp IntPred.sgt (LLVM.and (shl (const? 32 1) e_1 { «nsw» := false, «nuw» := true }) e)
        (const? 32 0))

theorem add_nsw_poison_constant_fold_thm (e : IntW 8) (e_1 : IntW 1) :
  add (select e_1 e (const? 8 65)) (const? 8 64) { «nsw» := true, «nuw» := false } ⊑
    select e_1 (add e (const? 8 64) { «nsw» := true, «nuw» := false }) (const? 8 (-127))

@[grind ., simp, aesop 50% unsafe]
lemma wf_addInitial (m : RawCNFA A) (hwf : m.WF) (hin : s ∈ m.states) :
    (m.addInitial s).WF

theorem e_2383 :
     - 2 * ((d &&& e) ||| (e ^^^ f)) + 2 * ((d &&& e) ^^^ (e ||| f)) - 1 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 5 * ( ~~~e &&&  ~~~(d ^^^ f)) + 4 * (d ||| ( ~~~e &&& f)) + 4 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 2 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 1 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 5 * (e &&& (d |||  ~~~f)) - 6 * ( ~~~d &&& ( ~~~e ||| f)) - 6 * (f ^^^ ( ~~~d &&& (e ||| f))) - 11 * ( ~~~f &&&  ~~~(d ^^^ e)) + 3 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * ( ~~~d ||| ( ~~~e &&& f)) + 5 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 1 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) - 7 * ( ~~~d ||| ( ~~~e ||| f)) - 11 *  ~~~(d ||| (e ^^^ f)) + 2 * (f ^^^  ~~~(d &&& (e ||| f))) + 2 * (e ^^^ (d &&& ( ~~~e ||| f))) + 3 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) - 5 *  ~~~( ~~~d ||| (e &&& f)) + 1 * ((d ||| e) &&& (e ^^^ f)) - 7 *  ~~~(d ^^^ (e &&& f)) + 1 * (d |||  ~~~f) - 7 * (e ^^^  ~~~(d &&& (e ||| f))) - 2 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 2 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 1 * (e &&&  ~~~(d &&& f)) + 5 * (e &&&  ~~~(d &&&  ~~~f)) + 1 * (f ^^^ (d ||| (e &&& f))) + 1 *  ~~~(d &&& e) + 3 * (f ^^^  ~~~(d ||| e)) - 11 * ( ~~~f &&& (d ^^^ e)) - 1 * (e ^^^ (d ||| ( ~~~e &&& f))) + 4 *  ~~~(e |||  ~~~f) + 7 * (f ||| (d &&&  ~~~e)) - 7 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 2 * ( ~~~f |||  ~~~(d ^^^ e)) - 2 *  ~~~(d ||| (e &&& f)) + 5 *  ~~~d - 1 * (d ||| (e ||| f)) + 1 * (d ||| (e &&& f)) - 5 * ((d &&& e) |||  ~~~(e ^^^ f)) + 1 * (e |||  ~~~(d ^^^ f)) + 7 * ((d &&& f) ^^^ (e ||| f)) - 1 * (e &&& (d ^^^ f)) - 6 * (f ^^^ (d ||| e)) + 1 *  ~~~(d |||  ~~~e) - 11 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 4 * (e ^^^ (d &&& f)) + 2 * (d &&&  ~~~e) - 1 * (f ^^^  ~~~(d &&&  ~~~e)) + 7 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 7 * (d &&& (e ^^^ f)) + 11 * (d ^^^ f) + 2 * ( ~~~d &&& (e ||| f)) + 2 * (e ^^^ ( ~~~d ||| (e ^^^ f))) + 1 * (f &&& (d ^^^ e)) - 6 * (e ^^^ ( ~~~d &&& (e ||| f))) + 4 * (d ||| ( ~~~e ||| f)) - 1 * (e &&&  ~~~f) + 4 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) + 38 *  ~~~(d ||| (e ||| f)) + 10 *  ~~~(d ||| ( ~~~e ||| f)) - 4 *  ~~~( ~~~d ||| (e ||| f)) - 27 * ( ~~~d &&& ( ~~~e &&& f)) - 39 * ( ~~~d &&& (e &&& f)) - 30 * (d &&& ( ~~~e &&& f)) + 15 * (d &&& (e &&& f)) =  - 5 * (f &&& (d ||| e))

theorem OrZextOr_thm (e : IntW 3) :
  LLVM.or (zext 5 (LLVM.or e (const? 3 3))) (const? 5 8) ⊑ LLVM.or (zext 5 e) (const? 5 11)

theorem xor_icmp_true_signed_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (5#32 <ₛ x) ^^^ ofBool (x <ₛ 6#32) = 1#1

theorem test_or_eq_different_operands_thm (e e_1 e_2 : IntW 8) :
  select (LLVM.or (icmp IntPred.eq e_2 e_1) (icmp IntPred.eq e e_2)) e_2 e ⊑
    select (icmp IntPred.eq e_2 e_1) e_2 e

theorem test7_proof : test7_before ⊑ test7_after

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

theorem t9_proof : t9_before ⊑ t9_after

theorem rem_euclid_2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(8#32 == 0 || 32 != 1 && x == intMin 32 && 8#32 == -1) = true →
    ofBool (-1#32 <ₛ x.srem 8#32) = 1#1 → x.srem 8#32 = x &&& 7#32

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

theorem trunc_sel_larger_zext_thm.extracted_1._3 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 → ¬(True ∧ (x &&& 65535#32).msb = true) → zeroExtend 64 (truncate 16 x) = zeroExtend 64 (x &&& 65535#32)

theorem alive_AddSub_1176  (w : Nat)   : alive_AddSub_1176_src w  ⊑ alive_AddSub_1176_tgt w

theorem positive_biggerLshr_shlnuw_proof : positive_biggerLshr_shlnuw_before ⊑ positive_biggerLshr_shlnuw_after

theorem sge_or_max_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.sge e_1 e) (const? 1 1) (icmp IntPred.eq e_1 (const? 8 127)) ⊑
    icmp IntPred.sge e_1 e

theorem ashr_lshr_exact_lshr_only_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (-1#32 <ₛ x_1) = 1#1 → ¬(True ∧ x_1 >>> x <<< x ≠ x_1 ∨ x ≥ ↑32) → x ≥ ↑32 → False

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

theorem t3_ult_sgt_neg1_proof : t3_ult_sgt_neg1_before ⊑ t3_ult_sgt_neg1_after

theorem lor_band_left1_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1), ¬x_1 = 1#1 → x &&& x_1 = x_1

theorem ne_smin4_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (add e_1 (const? 32 3))
      (select (icmp IntPred.slt e (add e_1 (const? 32 3))) e (add e_1 (const? 32 3))) ⊑
    icmp IntPred.sgt (add e_1 (const? 32 3)) e

theorem xor_or_thm (e e_1 : IntW 32) (e_2 : IntW 1) :
  LLVM.xor (select e_2 (const? 1 1) (icmp IntPred.ult e_1 e)) (const? 1 1) ⊑
    select (LLVM.xor e_2 (const? 1 1)) (icmp IntPred.uge e_1 e) (const? 1 0)

theorem sub_ashr_and_i8_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ x_1.ssubOverflow x = true ∨ 7#8 ≥ ↑8) → ofBool (x_1 <ₛ x) = 1#1 → (x_1 - x).sshiftRight' 7#8 &&& x = x

theorem exact_lshr_ne_both_equal_thm (e : IntW 8) :
  icmp IntPred.ne (lshr (const? 8 126) e { «exact» := true }) (const? 8 126) ⊑
    icmp IntPred.ne e (const? 8 0)

theorem e_1631 :
    2 * ( ~~~a &&& (b ^^^ c)) + 1 *  ~~~(a &&& (b ||| c)) + 1 * (b ||| c) + 2 * (a ||| (b &&& c)) - 1 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) - 1 * (c |||  ~~~(a ^^^ b)) + 1 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) - 2 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 7 *  ~~~(a &&& (b &&& c)) - 3 * (b ^^^ (a ||| (b ||| c))) - 3 *  ~~~( ~~~a ||| (b &&& c)) + 11 * (a |||  ~~~b) + 4 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 20 *  ~~~(a ||| (b ||| c)) - 21 *  ~~~(a ||| ( ~~~b ||| c)) - 13 *  ~~~( ~~~a ||| (b ||| c)) - 17 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 28 * ( ~~~a &&& ( ~~~b &&& c)) - 12 * ( ~~~a &&& (b &&& c)) - 14 * (a &&& ( ~~~b &&& c)) - 22 * (a &&& (b &&& c)) = 1 * (c ^^^  ~~~(a &&& (b &&& c))) - 11 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c)))

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_1_proof : masked_icmps_mask_notallzeros_bmask_mixed_swapped_1_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_swapped_1_after

theorem test18_thm.extracted_1._1 : ∀ (x : BitVec 8), truncate 16 (signExtend 32 x) = signExtend 16 x

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

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

theorem bv_AndOrXor_2663 :
    ∀ (e e_1 : LLVM.IntW w),
      LLVM.xor (LLVM.icmp LLVM.IntPred.ule e e_1) (LLVM.icmp LLVM.IntPred.ne e e_1) ⊑ LLVM.icmp LLVM.IntPred.uge e e_1

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

theorem scalar_i8_lshr_and_negC_eq_not_negatedPowerOf2_proof : scalar_i8_lshr_and_negC_eq_not_negatedPowerOf2_before ⊑ scalar_i8_lshr_and_negC_eq_not_negatedPowerOf2_after

theorem shl_sub_lshr_reverse_nsw_on_op1_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ (x_1 <<< x).sshiftRight' x ≠ x_1 ∨
        True ∧ x_1 <<< x >>> x ≠ x_1 ∨
          x ≥ ↑32 ∨
            True ∧ x_2.usubOverflow (x_1 <<< x) = true ∨
              True ∧ (x_2 - x_1 <<< x) >>> x <<< x ≠ x_2 - x_1 <<< x ∨ x ≥ ↑32) →
    ¬(True ∧ x_2 >>> x <<< x ≠ x_2 ∨ x ≥ ↑32 ∨ True ∧ (x_2 >>> x).usubOverflow x_1 = true) →
      (x_2 - x_1 <<< x) >>> x = x_2 >>> x - x_1

theorem lshrult_03_04_exact_proof : lshrult_03_04_exact_before ⊑ lshrult_03_04_exact_after

theorem rem_euclid_1_thm (e : IntW 32) :
  select (icmp IntPred.slt (LLVM.srem e (const? 32 8)) (const? 32 0))
      (add (LLVM.srem e (const? 32 8)) (const? 32 8)) (LLVM.srem e (const? 32 8)) ⊑
    LLVM.and e (const? 32 7)

theorem shl_nsw_nuw_ult_Csle0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ (x_1 <<< x).sshiftRight' x ≠ x_1 ∨ True ∧ x_1 <<< x >>> x ≠ x_1 ∨ x ≥ ↑8) →
    ofBool (x_1 <<< x <ᵤ BitVec.ofInt 8 (-19)) = ofBool (x_1 <ᵤ BitVec.ofInt 8 (-19))

theorem PR75692_1_proof : PR75692_1_before ⊑ PR75692_1_after

theorem trunc_shl_zext_32_proof : trunc_shl_zext_32_before ⊑ trunc_shl_zext_32_after

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

@[grind ., simp] lemma RawCNFA.empty_mem_tr {s s' : State} : s' ∉ empty (A := A).tr s a

theorem add_smax_simplify_proof : add_smax_simplify_before ⊑ add_smax_simplify_after

theorem PR42691_2_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x <ᵤ BitVec.ofInt 32 (-2147483648)) = 1#1 → ofBool (x == -1#32) = ofBool (BitVec.ofInt 32 (-2) <ₛ x)

theorem exact_ashr_eq_exactdiv_proof : exact_ashr_eq_exactdiv_before ⊑ exact_ashr_eq_exactdiv_after

theorem eq_21_comm_eq_proof : eq_21_comm_eq_before ⊑ eq_21_comm_eq_after

theorem positive_samevar_shlnsw_proof : positive_samevar_shlnsw_before ⊑ positive_samevar_shlnsw_after

theorem exactly_one_set_signbit_signed_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (ashr e_1 (const? 8 7)) (sext 8 (icmp IntPred.sgt e (const? 8 (-1)))) ⊑
    icmp IntPred.slt (LLVM.xor e_1 e) (const? 8 0)

theorem 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 test15 (x y : BitVec w) : (x - y) = (( x &&& (~~~ y)) - ((~~~ x) &&&  y))

theorem t9_highest_bit_thm (e : IntW 64) (e_1 e_2 : IntW 32) :
  icmp IntPred.ne
      (LLVM.and (shl e_2 (sub (const? 32 64) e_1)) (trunc 32 (lshr e (zext 64 (add e_1 (const? 32 (-1)))))))
      (const? 32 0) ⊑
    icmp IntPred.ne (LLVM.and (lshr e (const? 64 63)) (zext 64 e_2)) (const? 64 0)

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

theorem src_fv_eq_proof : src_fv_eq_before ⊑ src_fv_eq_after

theorem fold_add_udiv_urem_without_noundef_proof : fold_add_udiv_urem_without_noundef_before ⊑ fold_add_udiv_urem_without_noundef_after

theorem AvoidCollision_msb_setWidth (x : BitVec w) : (x.setWidth v).msb = (decide (0 < v) && x.getLsbD (v - 1))

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 lshr_xor_or_good_mask_proof : lshr_xor_or_good_mask_before ⊑ lshr_xor_or_good_mask_after

theorem or_simplify_ult_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 &&& BitVec.ofInt 8 (-5) <ᵤ x ||| 36#8 ||| x_1 &&& BitVec.ofInt 8 (-5)) =
    ofBool (x_1 &&& BitVec.ofInt 8 (-5) <ᵤ x ||| x_1 ||| 36#8)

theorem lowmask_add_zext_commute_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 32),
  x_1 * x_1 + zeroExtend 32 x &&& 65535#32 = zeroExtend 32 (x + truncate 16 (x_1 * x_1))

theorem e_195 :
     - 1 *  ~~~(x ^^^ y) + 2 * (x ||| y) - 1 *  ~~~(x &&&  ~~~x) + 2 *  ~~~(x &&&  ~~~y) - 13 *  ~~~(x |||  ~~~y) - 13 * (x &&& y) =  - 11 * y + 1 * (x ^^^ y)

@[simp] theorem Com.rec'_var (e : Expr d Γ eff u) (body : Com d _ _ t) :
    (Com.var e body).rec' (motive:=motive) rets var
    = var e body (body.rec' (motive:=motive) rets var)

theorem shl1_nsw_proof : shl1_nsw_before ⊑ shl1_nsw_after

theorem icmp_shl_nsw_sge0_thm (e : IntW 32) :
  icmp IntPred.sge (shl e (const? 32 21) { «nsw» := true, «nuw» := false }) (const? 32 0) ⊑
    icmp IntPred.sgt e (const? 32 (-1))

theorem one_side_fold_eq_thm.extracted_1._4 : ∀ (x x_1 : BitVec 32) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → ¬x_2 ^^^ 1#1 = 1#1 → False

theorem main8_logical_thm.extracted_1._4 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 64#32 != 0#32) = 1#1 →
    ¬ofBool (x &&& 192#32 == 0#32) = 1#1 → ¬ofBool (truncate 8 x <ₛ 0#8) = 1#1 → 1#32 = 2#32

theorem rem_euclid_wrong_sign_test_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(8#32 == 0 || 32 != 1 && x == intMin 32 && 8#32 == -1) = true →
    ofBool (0#32 <ₛ x.srem 8#32) = 1#1 →
      (8#32 == 0 || 32 != 1 && x == intMin 32 && 8#32 == -1) = true ∨ True ∧ (x.srem 8#32).saddOverflow 8#32 = true →
        False

theorem sel_zext_constants_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → zeroExtend 16 (-1#8) = 255#16

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

theorem test_sub_nuw_nsw__none_are_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x == 1#32) = 1#1 → 2147483647#32 = BitVec.ofInt 32 (-2147483648) - x

@[simp] theorem getValue_value [Inhabited α] : (value a).getValue = a

theorem test4_proof : test4_before ⊑ test4_after

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

theorem slt_zero_eq_i1_proof : slt_zero_eq_i1_before ⊑ slt_zero_eq_i1_after

theorem positive_sameconst_shlnuwnsw_lshrexact_proof : positive_sameconst_shlnuwnsw_lshrexact_before ⊑ positive_sameconst_shlnuwnsw_lshrexact_after

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

@[simp]
lemma dec_snoc_in_langRel {n} {R : BVNRel n} {w : BitVecs' n} {a : BitVec n} :
    dec (w ++ [a]) ∈ langRel R ↔
      R (List.Vector.ofFn fun k => .cons (a.getLsbD k) ((dec w).bvs.get k))

theorem ashrsgt_03_12_proof : ashrsgt_03_12_before ⊑ ashrsgt_03_12_after

theorem lshrult_02_02_proof : lshrult_02_02_before ⊑ lshrult_02_02_after

theorem ule_or_not_min_commute_proof : ule_or_not_min_commute_before ⊑ ule_or_not_min_commute_after

theorem e_1882 :
    5 * ((a &&& b) ||| (b ^^^ c)) + 5 * (c &&&  ~~~(a &&&  ~~~b)) - 5 *  ~~~( ~~~a &&& ( ~~~b &&& c)) - 1 * (a &&& (b ||| c)) + 4 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) + 11 * (a ^^^ ( ~~~b ||| c)) + 11 * (a ||| c) - 7 * b - 1 *  ~~~(a ^^^ (b ^^^ c)) - 3 * (b &&&  ~~~(a ^^^ c)) - 2 * ( ~~~a &&& (b ||| c)) - 7 * ( ~~~(a &&& b) &&& (b ^^^ c)) - 11 * ( ~~~a ||| (b ||| c)) - 1 * (a &&&  ~~~b) - 1 * (b |||  ~~~(a ||| c)) + 4 * (a ^^^ (b ^^^ c)) + 5 * (b ||| (a &&&  ~~~c)) + 2 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) + 7 *  ~~~( ~~~a &&& (b &&& c)) - 1 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) + 4 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 3 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) + 11 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) + 1 * ((a &&&  ~~~b) ||| (b ^^^ c)) - 3 * (c ^^^ (a ||| ( ~~~b &&& c))) - 2 * (b ^^^  ~~~(a &&&  ~~~c)) + 2 * ( ~~~b |||  ~~~(a ^^^ c)) - 1 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) + 4 * (a &&& c) - 2 * ( ~~~a ||| ( ~~~b &&& c)) - 11 * (a ||| ( ~~~b &&& c)) - 2 * (b &&& (a ^^^ c)) + 4 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) - 1 *  ~~~(a ||| b) - 1 * (c |||  ~~~(a ||| b)) + 4 * (a ^^^ b) + 3 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 1 * (b ^^^ (a &&& (b ||| c))) - 1 *  ~~~(a ^^^ (b &&& c)) + 3 * (b ^^^ (a ||| (b &&& c))) - 1 *  ~~~(a ||| (b ||| c)) + 7 *  ~~~(a ||| ( ~~~b ||| c)) - 29 *  ~~~( ~~~a ||| (b ||| c)) - 11 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 31 * ( ~~~a &&& ( ~~~b &&& c)) - 20 * ( ~~~a &&& (b &&& c)) - 1 * (a &&& ( ~~~b &&& c)) - 14 * (a &&& (b &&& c)) = 2 * (b ^^^  ~~~(a |||  ~~~c)) - 1 * (c ||| (a &&& b))

theorem PR2330_thm (e e_1 : IntW 32) :
  LLVM.and (icmp IntPred.ult e_1 (const? 32 8)) (icmp IntPred.ult e (const? 32 8)) ⊑
    icmp IntPred.ult (LLVM.or e_1 e) (const? 32 8)

theorem dec_sub_proof : dec_sub_before ⊑ dec_sub_after

theorem not_cond_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32) (x_2 : BitVec 1), x_2 ^^^ 1#1 = 1#1 → x_2 = 1#1 → x_1 = x

theorem or_and_not_not_proof : or_and_not_not_before ⊑ or_and_not_not_after

theorem ashrslt_01_07_exact_proof : ashrslt_01_07_exact_before ⊑ ashrslt_01_07_exact_after

theorem t9_ashr_exact_flag_preservation_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1 >>> (32#32 - x) <<< (32#32 - x) ≠ x_1 ∨
        32#32 - x ≥ ↑32 ∨
          True ∧
              x_1.sshiftRight' (32#32 - x) >>> (x + BitVec.ofInt 32 (-2)) <<< (x + BitVec.ofInt 32 (-2)) ≠
                x_1.sshiftRight' (32#32 - x) ∨
            x + BitVec.ofInt 32 (-2) ≥ ↑32) →
    True ∧ x_1 >>> 30#32 <<< 30#32 ≠ x_1 ∨ 30#32 ≥ ↑32 → False

theorem test5_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ¬(zeroExtend 32 x ≥ ↑32 ∨ 32#32 <<< zeroExtend 32 x = 0) →
    True ∧ x.msb = true ∨ True ∧ 32#32 <<< zeroExtend 32 x >>> zeroExtend 32 x ≠ 32#32 ∨ zeroExtend 32 x ≥ ↑32 →
      False

theorem t0_const_after_fold_lshr_shl_ne_thm (e : IntW 64) (e_1 e_2 : IntW 32) :
  icmp IntPred.ne
      (LLVM.and (lshr e_2 (sub (const? 32 32) e_1)) (trunc 32 (shl e (zext 64 (add e_1 (const? 32 (-1)))))))
      (const? 32 0) ⊑
    icmp IntPred.ne (LLVM.and e (zext 64 (lshr e_2 (const? 32 31)) { «nneg» := true })) (const? 64 0)

@[bv_automata_nnf]
theorem slt_iff_sle_eq_false {a b : BitVec w} : a.sle b = false ↔ b.slt a

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

theorem ne_smax4_proof : ne_smax4_before ⊑ ne_smax4_after

theorem bools2_logical_commute0_thm (e e_1 e_2 : IntW 1) :
  select (select e_2 e_1 (const? 1 0)) (const? 1 1) (select (LLVM.xor e_2 (const? 1 1)) e (const? 1 0)) ⊑
    select e_2 e_1 e

theorem lshr_eq_both_equal_thm (e : IntW 8) :
  icmp IntPred.eq (lshr (const? 8 127) e) (const? 8 127) ⊑ icmp IntPred.eq e (const? 8 0)

@[simp]
theorem ofNat_zero : ofNat 0 = FSM.zero

theorem e_1149 :
    11 * (z ^^^ t) + 3 *  ~~~(z &&& t) - 3 *  ~~~(z ^^^ t) - 11 * (z |||  ~~~t) + 5 *  ~~~z - 19 *  ~~~(z |||  ~~~t) - 4 * (z &&&  ~~~t) + 14 * (z &&& t) =  - 1 *  ~~~t - 5 *  ~~~(z ||| t)

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

theorem e_1765 :
    5 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) + 1 * (c ^^^ (a &&& b)) - 1 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) - 7 * ((a ^^^ b) &&& (a ^^^ c)) - 1 * ((a &&& b) |||  ~~~(b ^^^ c)) - 11 * (a &&& ( ~~~b ||| c)) + 7 * ( ~~~a ||| (b ^^^ c)) + 2 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 4 * (b &&&  ~~~(a ^^^ c)) - 2 *  ~~~(b &&& c) - 2 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) + 11 * (c ^^^  ~~~(a &&& b)) - 11 * (b &&& c) + 2 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) + 7 *  ~~~(a &&& (b ||| c)) - 11 *  ~~~( ~~~a ||| (b &&& c)) - 11 * (b ^^^  ~~~(a &&& (b ^^^ c))) + 1 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) - 2 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) + 3 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 1 * (b &&& (a ^^^ c)) - 1 *  ~~~( ~~~a &&& (b ||| c)) - 1 * (b |||  ~~~(a ^^^ c)) - 1 * (b ^^^  ~~~( ~~~a ||| (b ^^^ c))) + 5 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) - 6 * (a ^^^ (b ^^^ c)) - 1 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) - 5 * (c ^^^  ~~~(a |||  ~~~b)) - 8 *  ~~~(a ||| (b ||| c)) - 22 *  ~~~(a ||| ( ~~~b ||| c)) + 24 *  ~~~( ~~~a ||| (b ||| c)) + 16 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 3 * ( ~~~a &&& ( ~~~b &&& c)) - 3 * ( ~~~a &&& (b &&& c)) + 18 * (a &&& ( ~~~b &&& c)) + 6 * (a &&& (b &&& c)) =  - 2 * a

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

theorem and_xor_or5_proof : and_xor_or5_before ⊑ and_xor_or5_after

theorem test3_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.ssubOverflow x = true ∨ True ∧ x_1.ssubOverflow x = true) →
    ¬(True ∧ x_1.ssubOverflow x = true) →
      ofBool (x_1 - x == 0#32) ||

theorem sgt_swap_and_min_logical_proof : sgt_swap_and_min_logical_before ⊑ sgt_swap_and_min_logical_after

@[simp]
lemma RawCNFA.Simul.initial {m : RawCNFA A} {M : NFA A Q} (hsim : m.Simul M R ⊤ ∅) :
    R.set_eq m.initials.toSet M.start

theorem substitute_constant_and_ne_ugt_swap_logical_proof : substitute_constant_and_ne_ugt_swap_logical_before ⊑ substitute_constant_and_ne_ugt_swap_logical_after

theorem substitute_constant_and_eq_eq_logical_proof : substitute_constant_and_eq_eq_logical_before ⊑ substitute_constant_and_eq_eq_logical_after

theorem multiuse_add_proof : multiuse_add_before ⊑ multiuse_add_after

theorem positive_with_aggressive_icmp_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x <ᵤ 128#32) = 1#1 → ofBool (x + 256#32 <ᵤ 512#32) = ofBool (x <ᵤ 128#32)

theorem Factor.denote_eq_toNat_reflect {w : Nat} (xs : Env w) (f : Factor) :
  f.denote xs = (f.reflect xs |>.toNat)

@[simp_denote, simp]
theorem toOption_getNone : (PoisonOr.poison).toOption.getD y = y

theorem e_2498 :
    1 * (e ^^^ ( ~~~d ||| (e &&& f))) - 3 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) - 5 *  ~~~(d |||  ~~~e) - 1 *  ~~~(e &&& f) + 3 *  ~~~( ~~~d ||| ( ~~~e &&& f)) + 2 * (e ^^^ (d ||| ( ~~~e ||| f))) + 1 *  ~~~(d &&&  ~~~d) - 11 * (e ^^^ (d ||| (e &&& f))) - 5 * (e ||| (d &&& f)) + 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 2 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 7 * (f ^^^  ~~~(d ||| (e &&& f))) + 7 * (f ^^^ (d &&& e)) - 5 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) + 11 * (e |||  ~~~(d |||  ~~~f)) - 7 * ( ~~~d &&& (e ||| f)) + 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 1 * d + 11 * ( ~~~f |||  ~~~(d ^^^ e)) - 1 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 1 * (f ^^^ ( ~~~d ||| (e &&& f))) - 3 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 4 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 6 * ((d &&& e) ^^^ (e |||  ~~~f)) - 1 * ( ~~~e &&&  ~~~(d ^^^ f)) + 7 * (e |||  ~~~(d ^^^ f)) + 4 * (e ||| f) + 7 *  ~~~(d &&& f) + 3 *  ~~~(d ^^^ (e ^^^ f)) - 6 * (f ^^^  ~~~(d |||  ~~~e)) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 1 * ( ~~~d &&& (e ^^^ f)) - 2 * ((e &&& f) ||| (d &&& (e ||| f))) - 11 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 2 * ( ~~~d ||| ( ~~~e &&& f)) + 5 * ((d &&& f) ^^^ (e ||| f)) - 6 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 7 * (e ^^^  ~~~(d &&& (e ||| f))) - 11 * ( ~~~e ||| (d ^^^ f)) - 2 * (f ^^^  ~~~(d &&&  ~~~e)) + 1 *  ~~~( ~~~d ||| (e &&& f)) - 2 *  ~~~f + 1 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 2 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 *  ~~~(d &&& ( ~~~e &&& f)) - 5 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 2 * (d ||| (e &&& f)) + 2 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 1 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 4 * ((d ^^^ e) &&& (d ^^^ f)) + 11 *  ~~~( ~~~d &&& (e ^^^ f)) + 2 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 1 * (f ^^^ (d &&& (e ||| f))) + 2 * (d ^^^ (e ^^^ f)) + 5 * ( ~~~e &&& (d ^^^ f)) - 7 * (d |||  ~~~e) + 11 * (f ^^^ (d ||| ( ~~~e ||| f))) - 2 * ((d &&& e) |||  ~~~(e ^^^ f)) + 5 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 4 * ( ~~~d ||| (e ^^^ f)) + 2 * (f &&& (d ^^^ e)) - 1 * (f ||| (d ^^^ e)) - 1 * (d ^^^ e) - 5 * ((d &&& e) ^^^ (e ||| f)) - 2 *  ~~~(d &&& (e ^^^ f)) + 1 *  ~~~( ~~~d ||| (e ^^^ f)) - 6 * (e &&& (d ^^^ f)) - 1 * (e ^^^  ~~~(d &&&  ~~~f)) - 1 *  ~~~(d ^^^ (e ||| f)) - 1 * (f ||| (d &&&  ~~~e)) + 2 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 3 * (e ^^^ (d &&& (e ||| f))) + 3 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 20 *  ~~~(d ||| (e ||| f)) + 9 *  ~~~(d ||| ( ~~~e ||| f)) - 18 *  ~~~( ~~~d ||| (e ||| f)) - 38 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 22 * ( ~~~d &&& ( ~~~e &&& f)) + 13 * ( ~~~d &&& (e &&& f)) + 42 * (d &&& ( ~~~e &&& f)) - 5 * (d &&& (e &&& f)) = 1 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 5 * f

theorem main1_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 1#32 != 0#32) &&& ofBool (x &&& 2#32 != 0#32) = 1#1 →
    ofBool (x &&& 3#32 == 3#32) = 1#1 → 1#32 = 2#32

theorem lsb_mask_sign_sext_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → (x + -1#32 &&& (x ^^^ -1#32)).sshiftRight' 31#32 = signExtend 32 (ofBool (x == 0#32))

theorem lshrugt_02_11_proof : lshrugt_02_11_before ⊑ lshrugt_02_11_after

theorem lshr_and_sub_proof : lshr_and_sub_before ⊑ lshr_and_sub_after

theorem lshrugt_01_10_thm (e : IntW 4) : icmp IntPred.ugt (lshr e (const? 4 1)) (const? 4 (-6)) ⊑ const? 1 0

theorem masked_icmps_bmask_notmixed_and_proof : masked_icmps_bmask_notmixed_and_before ⊑ masked_icmps_bmask_notmixed_and_after

theorem eq_commuted_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(x == 0 || 8 != 1 && 43#8 == intMin 8 && x == -1) = true →
    ofBool (x_1 == 0#8) ||

theorem Array.push_incl {a : Array α} {x : α} (y : α) : x ∈ a → x ∈ a.push y

theorem ult_to_slt_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 ^^^ BitVec.ofInt 8 (-128) <ᵤ x ^^^ BitVec.ofInt 8 (-128)) = ofBool (x_1 <ₛ x)

theorem or_simplify_ule_fail_proof : or_simplify_ule_fail_before ⊑ or_simplify_ule_fail_after

theorem or_trunc_lshr_more_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬4#8 ≥ ↑8 → 4#6 ≥ ↑6 ∨ True ∧ (truncate 6 x >>> 4#6 &&& BitVec.ofInt 6 (-4) != 0) = true → False

lemma RawCNFA.reverse_spec {m : RawCNFA A} (hwf : m.WF) :
    let m' := m.reverse
    m'.WF ∧ m'.stateMax = m.stateMax ∧ m'.initials = m.finals ∧ m'.finals = m.initials ∧
      ∀ s a s', s' ∈ m'.tr s a ↔ s ∈ m.tr s' a

theorem test2_gen (x y : BitVec w) : (~~~(x ^^^ y)) = ((x &&& y) + ~~~(x ||| y))

theorem udiv1_thm (e e_1 : IntW 32) : mul (LLVM.udiv e_1 e { «exact» := true }) e ⊑ e_1

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

theorem not_mul_of_pow2_commute_proof : not_mul_of_pow2_commute_before ⊑ not_mul_of_pow2_commute_after

theorem neg_or_lshr_i32_commute_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬((x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true ∨
        (x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true ∨ 31#32 ≥ ↑32) →
    ¬(x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true →
      ((42#32).sdiv x ||| 0#32 - (42#32).sdiv x) >>> 31#32 = zeroExtend 32 (ofBool ((42#32).sdiv x != 0#32))

theorem n1_thm (e : IntW 8) :
  icmp IntPred.eq (lshr (shl e (const? 8 5)) (const? 8 5) { «exact» := true }) e ⊑
    icmp IntPred.ult e (const? 8 8)

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

theorem bools2_logical_commute0_proof : bools2_logical_commute0_before ⊑ bools2_logical_commute0_after

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 ashrslt_03_07_exact_proof : ashrslt_03_07_exact_before ⊑ ashrslt_03_07_exact_after

theorem lor_lor_right1_thm (e e_1 : IntW 1) :
  select e_1 (const? 1 1) (select e_1 (const? 1 1) e) ⊑ select e_1 (const? 1 1) e

theorem lshrugt_01_15_proof : lshrugt_01_15_before ⊑ lshrugt_01_15_after

theorem ripple_nsw2_proof : ripple_nsw2_before ⊑ ripple_nsw2_after

theorem add_smax_simplify2_proof : add_smax_simplify2_before ⊑ add_smax_simplify2_after

theorem bitwise_and_logical_and_masked_icmp_allones_poison1_proof : bitwise_and_logical_and_masked_icmp_allones_poison1_before ⊑ bitwise_and_logical_and_masked_icmp_allones_poison1_after

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

@[simp]
lemma determinize_complete (M : NFA α σ) :
    M.toDFA.toNFA.Complete

theorem t0_proof : t0_before ⊑ t0_after

theorem test22_proof : test22_before ⊑ test22_after

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

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

theorem test_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 test_shl__nsw_is_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x ||| BitVec.ofInt 32 (-83886080) == BitVec.ofInt 32 (-83886079)) = 1#1 →
    ¬2#32 ≥ ↑32 →
      ¬(True ∧ ((x ||| BitVec.ofInt 32 (-83886080)) <<< 2#32).sshiftRight' 2#32 ≠ x ||| BitVec.ofInt 32 (-83886080) ∨
            2#32 ≥ ↑32 ∨
              True ∧
                  ((x ||| BitVec.ofInt 32 (-83886080)) <<< 2#32).sshiftRight' 2#32 ≠ x ||| BitVec.ofInt 32 (-83886080) ∨
                2#32 ≥ ↑32) →
        BitVec.ofInt 32 (-335544316) * (x ||| BitVec.ofInt 32 (-83886080)) *
            (x ||| BitVec.ofInt 32 (-83886080)) <<< 2#32 =
          (x ||| BitVec.ofInt 32 (-83886080)) <<< 2#32 * (x ||| BitVec.ofInt 32 (-83886080)) *
            (x ||| BitVec.ofInt 32 (-83886080)) <<< 2#32

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

theorem lshr_exact_add_negative_shift_positive_proof : lshr_exact_add_negative_shift_positive_before ⊑ lshr_exact_add_negative_shift_positive_after

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

theorem sub_select_sext_op_swapped_non_const_args_thm.extracted_1._1 : ∀ (x : BitVec 6) (x_1 : BitVec 1),
  x_1 = 1#1 → signExtend 6 x_1 - x = x ^^^ -1#6

theorem band_lor_left2_thm (e e_1 : IntW 1) : select (LLVM.and e_1 e) (const? 1 1) e ⊑ e

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

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

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

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

theorem test11e_proof : test11e_before ⊑ test11e_after

theorem sub_from_constant_commute_proof : sub_from_constant_commute_before ⊑ sub_from_constant_commute_after

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

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

theorem ashrsgt_03_06_exact_proof : ashrsgt_03_06_exact_before ⊑ ashrsgt_03_06_exact_after

theorem ashrslt_01_03_proof : ashrslt_01_03_before ⊑ ashrslt_01_03_after

theorem shift_xor_multiuse_cmp_and_proof : shift_xor_multiuse_cmp_and_before ⊑ shift_xor_multiuse_cmp_and_after

theorem sub_mask1_lshr_proof : sub_mask1_lshr_before ⊑ sub_mask1_lshr_after

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

theorem e_1931 :
    4 * ((b &&&  ~~~c) ^^^ (a ||| (b ^^^ c))) - 6 * (b ^^^  ~~~(a ||| c)) + 2 * (b ^^^ ( ~~~a ||| (b &&& c))) + 2 * (c ^^^ (a ||| ( ~~~b ||| c))) - 3 * (b &&&  ~~~(a &&&  ~~~c)) + 1 *  ~~~(a &&& (b ||| c)) - 1 * (b ^^^  ~~~( ~~~a ||| (b ^^^ c))) + 3 * (b ^^^  ~~~(a &&& (b ^^^ c))) + 4 * ((a ^^^ b) |||  ~~~(a ^^^ c)) - 7 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) - 1 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) - 1 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) - 5 * (a &&& b) - 11 * ( ~~~a ||| ( ~~~b ||| c)) - 2 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) - 1 * (a &&& ( ~~~b ||| c)) + 11 * (c ^^^ (a ||| (b ||| c))) + 7 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 2 * (a ||| c) + 5 * ((a &&& b) ^^^ (b |||  ~~~c)) + 2 * (c ^^^ ( ~~~a ||| (b &&& c))) + 1 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 5 * (b ^^^ (a ||| (b ||| c))) - 6 * ((a &&& c) ^^^ (a ^^^ (b &&& c))) - 5 * (c ^^^  ~~~(a &&& b)) + 1 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) + 1 *  ~~~( ~~~a ||| (b ^^^ c)) + 11 *  ~~~(a &&& b) - 2 * (c ^^^ (a &&& (b ||| c))) + 3 *  ~~~(a ^^^ ( ~~~b &&& c)) - 2 *  ~~~(a ^^^ (b ^^^ c)) - 2 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) - 1 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) - 5 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 1 * (b ||| (a &&&  ~~~c)) + 3 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) + 2 *  ~~~b + 1 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 1 * (b &&&  ~~~(a ^^^ c)) + 2 * ((b &&& c) ||| (a &&& (b ||| c))) - 2 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 2 * ((a ||| b) &&&  ~~~(b ^^^ c)) + 1 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) + 5 * (c ^^^ (a |||  ~~~b)) + 1 *  ~~~( ~~~a &&& (b ||| c)) - 1 * ( ~~~(a &&& b) &&& (b ^^^ c)) - 13 *  ~~~(a ||| ( ~~~b ||| c)) - 31 *  ~~~( ~~~a ||| (b ||| c)) - 15 * ( ~~~a &&& ( ~~~b &&& c)) - 4 * ( ~~~a &&& (b &&& c)) - 16 * (a &&& ( ~~~b &&& c)) + 35 * (a &&& (b &&& c)) = 7 *  ~~~(a ||| (b ||| c))

theorem sub_select_sext_op_swapped_non_const_args_thm.extracted_1._2 : ∀ (x : BitVec 6) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → signExtend 6 x_1 - x = 0#6 - x

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

theorem lshrult_03_05_exact_proof : lshrult_03_05_exact_before ⊑ lshrult_03_05_exact_after

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

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

theorem positive_biggerashr_shlnuw_ashrexact_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x >>> 6#8 <<< 6#8 ≠ x ∨
        6#8 ≥ ↑8 ∨ True ∧ x.sshiftRight' 6#8 <<< 3#8 >>> 3#8 ≠ x.sshiftRight' 6#8 ∨ 3#8 ≥ ↑8) →
    True ∧ x >>> 3#8 <<< 3#8 ≠ x ∨ 3#8 ≥ ↑8 → False

theorem lowmask_add_zext_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 8),
  zeroExtend 32 x_1 + x &&& 255#32 = zeroExtend 32 (x_1 + truncate 8 x)

theorem not_match_inconsistent_signs_proof : not_match_inconsistent_signs_before ⊑ not_match_inconsistent_signs_after

theorem AvoidCollision_setWidth_not {x : BitVec w} (_ : k ≤ w) :
    (~~~x).setWidth k = ~~~(x.setWidth k)

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

theorem test_shl_nsw__nuw_is_safe_proof : test_shl_nsw__nuw_is_safe_before ⊑ test_shl_nsw__nuw_is_safe_after

theorem ashr_mul_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬8#20 ≥ ↑20 →
    ¬(True ∧ (signExtend 16 x_1).smulOverflow (signExtend 16 x) = true ∨ 8#16 ≥ ↑16) →
      truncate 16 ((signExtend 20 x_1 * signExtend 20 x).sshiftRight' 8#20) =
        (signExtend 16 x_1 * signExtend 16 x).sshiftRight' 8#16

theorem icmp_select_var_select_thm.extracted_1._9 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  x_2 = 1#1 → ¬(ofBool (x_1 == 0#8) = 1#1 ∧ x_2 = 1#1) → ofBool (x_1 == 0#8) = 1#1 → True → ofBool (x_1 == x) = 1#1

theorem e_1377 :
     - 3 * (z ||| t) - 1 *  ~~~(z &&&  ~~~z) - 3 *  ~~~z - 1 *  ~~~(z &&& t) - 11 * t + 1 *  ~~~(z &&&  ~~~t) + 3 * (z |||  ~~~t) + 1 *  ~~~(z ||| t) + 18 *  ~~~(z |||  ~~~t) + 1 * (z &&&  ~~~t) =  - 1 * z - 10 * (z &&& t)

theorem neg_eq_negAux (x : BitStream) : (- x) i = (negAux x i).1

theorem lowmask_or_zext_commute_thm (e : IntW 16) (e_1 : IntW 24) :
  LLVM.and (LLVM.or e_1 (zext 24 e)) (const? 24 65535) ⊑ zext 24 (LLVM.or e (trunc 16 e_1))

theorem alive_AndOrXor_2587__BAA___B__A : alive_AndOrXor_2587__BAA___B__A_src ⊑ alive_AndOrXor_2587__BAA___B__A_tgt

theorem sub_shl_same_amount_partial_nsw1_proof : sub_shl_same_amount_partial_nsw1_before ⊑ sub_shl_same_amount_partial_nsw1_after

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

theorem pr51551_neg1_proof : pr51551_neg1_before ⊑ pr51551_neg1_after

theorem or_signbit_select_lshr_proof : or_signbit_select_lshr_before ⊑ or_signbit_select_lshr_after

theorem test1_proof : test1_before ⊑ test1_after

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

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

theorem ult_umin1_proof : ult_umin1_before ⊑ ult_umin1_after

theorem or_not_xor_common_op_commute7_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8),
  0#8 - x_2 ||

theorem t1_exact_proof : t1_exact_before ⊑ t1_exact_after

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

theorem positive_biggerlshr_shlnuw_proof : positive_biggerlshr_shlnuw_before ⊑ positive_biggerlshr_shlnuw_after

theorem e_695 :
     - 11 * (x |||  ~~~y) + 7 *  ~~~(x &&&  ~~~x) - 11 * (x ^^^ y) - 2 * (x ||| y) - 2 *  ~~~x - 11 *  ~~~(x &&&  ~~~y) + 2 *  ~~~(x &&& y) + 12 *  ~~~(x ||| y) + 15 * (x &&&  ~~~y) + 14 * (x &&& y) =  - 17 *  ~~~(x |||  ~~~y) - 3 *  ~~~(x ^^^ y)

theorem negative_not_power_of_two_logical_proof : negative_not_power_of_two_logical_before ⊑ negative_not_power_of_two_logical_after

theorem narrow_sext_and_proof : narrow_sext_and_before ⊑ narrow_sext_and_after

theorem test_sub__nuw_is_safe_proof : test_sub__nuw_is_safe_before ⊑ test_sub__nuw_is_safe_after

theorem List.perm_subset_iff_right {l1 l2 : List α} (hperm : l1.Perm l2) (l : List α) :
  l ⊆ l1 ↔ l ⊆ l2

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

theorem lshr_lshr_pow2_const_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(x ≥ ↑16 ∨ 6#16 ≥ ↑16) → ¬ofBool (x == 3#16) = 1#1 → 2048#16 >>> x >>> 6#16 &&& 4#16 = 0#16

theorem sub_eq_add_neg : a - b = a + (-b)

theorem t3_const_after_fold_lshr_shl_ne_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(32#32 - x_1 ≥ ↑32 ∨ x_1 + -1#32 ≥ ↑32) →
    ¬31#32 ≥ ↑32 →
      ofBool (x_2 >>> (32#32 - x_1) &&& x <<< (x_1 + -1#32) != 0#32) = ofBool (x_2 >>> 31#32 &&& x != 0#32)

theorem e_1905 :
    1 * (a ^^^ c) + 1 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) - 5 * (a ||| ( ~~~b &&& c)) + 2 * ( ~~~b |||  ~~~(a ^^^ c)) + 1 * (a &&&  ~~~c) + 5 * ( ~~~c &&&  ~~~(a ^^^ b)) + 3 * ((a &&&  ~~~b) ||| (b ^^^ c)) - 7 *  ~~~(b ^^^ c) + 2 * (a ||| c) + 7 * ((a &&& c) ||| (b &&&  ~~~c)) - 2 * ( ~~~(a ||| b) ||| (b ^^^ c)) + 1 * (a ^^^ ( ~~~b ||| c)) - 3 *  ~~~(b &&&  ~~~c) - 2 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 4 * (a ||| ( ~~~b ||| c)) - 1 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 1 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) + 1 * (c ^^^ (a ||| (b &&& c))) - 7 * (c ^^^ (a &&&  ~~~b)) + 1 * ( ~~~a ||| ( ~~~b &&& c)) - 11 * (b &&& c) - 2 *  ~~~(a ^^^ ( ~~~b &&& c)) + 5 * (a ||| b) - 1 * (b &&& (a |||  ~~~c)) + 1 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) - 1 *  ~~~(a ||| c) - 5 * a + 11 * (a &&& (b ||| c)) + 2 * (a ^^^ (b ^^^ c)) - 1 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) - 6 * (c &&& (a ^^^ b)) - 3 *  ~~~(a &&& ( ~~~b &&& c)) - 3 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 1 * (a &&& ( ~~~b ||| c)) + 3 * ((a &&&  ~~~b) ||| (a ^^^ (b ^^^ c))) - 1 * (c ^^^  ~~~(a &&& (b ||| c))) + 2 * ((a &&& b) |||  ~~~(b ||| c)) + 4 *  ~~~(a &&& (b ^^^ c)) + 3 * ( ~~~a ||| (b ||| c)) + 2 * (c &&&  ~~~(a &&&  ~~~b)) + 1 * (b |||  ~~~(a ^^^ c)) + 11 * (b ^^^ ( ~~~a &&& (b ^^^ c))) - 2 * (a &&& (b ^^^ c)) - 28 *  ~~~(a ||| ( ~~~b ||| c)) + 6 *  ~~~( ~~~a ||| (b ||| c)) - 42 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 22 * ( ~~~a &&& ( ~~~b &&& c)) + 3 * ( ~~~a &&& (b &&& c)) - 21 * (a &&& ( ~~~b &&& c)) - 18 * (a &&& (b &&& c)) =  - 3 * (b ^^^ (a &&& (b ^^^ c))) - 4 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c))

theorem select_non_const_sides_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → x - zeroExtend 64 x_1 = x

theorem and_ne_with_diff_one_signed_proof : and_ne_with_diff_one_signed_before ⊑ and_ne_with_diff_one_signed_after

theorem icmp_ne_sext_ne_zero_i128_thm (e : IntW 128) :
  icmp IntPred.ne (sext 128 (icmp IntPred.ne e (const? 128 0))) e ⊑
    icmp IntPred.ult (add e (const? 128 (-1))) (const? 128 (-2))

theorem ashrslt_03_13_exact_proof : ashrslt_03_13_exact_before ⊑ ashrslt_03_13_exact_after

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

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

theorem test11_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬zeroExtend 128 x &&& 31#128 ≥ ↑128 →
    ¬(True ∧ (x &&& 31#32).msb = true ∨
          True ∧
              (zeroExtend 64 x_1 <<< zeroExtend 64 (x &&& 31#32)).sshiftRight' (zeroExtend 64 (x &&& 31#32)) ≠
                zeroExtend 64 x_1 ∨
            True ∧
                zeroExtend 64 x_1 <<< zeroExtend 64 (x &&& 31#32) >>> zeroExtend 64 (x &&& 31#32) ≠ zeroExtend 64 x_1 ∨
              zeroExtend 64 (x &&& 31#32) ≥ ↑64) →
      truncate 64 (zeroExtend 128 x_1 <<< (zeroExtend 128 x &&& 31#128)) =
        zeroExtend 64 x_1 <<< zeroExtend 64 (x &&& 31#32)

theorem negative3_logical_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.slt e_2 (LLVM.and e_1 (const? 32 2147483647))) (icmp IntPred.sge e (const? 32 0))
      (const? 1 0) ⊑
    select (icmp IntPred.slt e_2 (LLVM.and e_1 (const? 32 2147483647))) (icmp IntPred.sgt e (const? 32 (-1)))
      (const? 1 0)

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

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

@[bv_automata_nnf] theorem eq_false_eq (p : Prop) : (p = False) = ¬p

theorem test_mul_nuw__nsw_is_safe_proof : test_mul_nuw__nsw_is_safe_before ⊑ test_mul_nuw__nsw_is_safe_after

theorem not_ashr_bitwidth_mask_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬7#8 ≥ ↑8 → ofBool (x_1 <ₛ 0#8) = 1#1 → (x_1.sshiftRight' 7#8 ^^^ -1#8) &&& x = 0#8

theorem trunc_lshr_sext_proof : trunc_lshr_sext_before ⊑ trunc_lshr_sext_after

theorem e_132 :
    11 *  ~~~(x ^^^ y) - 7 * (x |||  ~~~y) + 3 *  ~~~(x &&& y) - 3 *  ~~~(x |||  ~~~y) + 4 * (x &&&  ~~~y) - 4 * (x &&& y) = 7 *  ~~~(x ||| y)

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

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

theorem 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 t0_ult_slt_128_thm.extracted_1._8 : ∀ (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 → False

theorem fake_sext_thm.extracted_1._1 : ∀ (x : BitVec 3),
  ¬17#18 ≥ ↑18 → 2#3 ≥ ↑3 ∨ True ∧ (x >>> 2#3).msb = true → False

theorem addhshlhsdivhnegative1_proof : addhshlhsdivhnegative1_before ⊑ addhshlhsdivhnegative1_after

theorem test_slt_xor_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 ^^^ -1#32 ^^^ x <ₛ x_1 ^^^ -1#32) = ofBool (x_1 <ₛ x ^^^ x_1)

theorem main3c_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 7#32 != 0#32) = 1#1 → ¬True → 0#32 = zeroExtend 32 (ofBool (x &&& 55#32 == 0#32))

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

theorem shift_trunc_signbit_test_proof : shift_trunc_signbit_test_before ⊑ shift_trunc_signbit_test_after

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

theorem main_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(6#8 ≥ ↑8 ∨ 7#8 ≥ ↑8) → 5#8 ≥ ↑8 ∨ True ∧ ((truncate 8 x ^^^ -1#8) <<< 5#8 &&& 64#8).msb = true → False

theorem test15h_thm (e : IntW 32) :
  select (icmp IntPred.ne (LLVM.and e (const? 32 8)) (const? 32 0)) (const? 32 (-9)) (const? 32 (-1)) ⊑
    LLVM.xor (LLVM.and e (const? 32 8)) (const? 32 (-1))

theorem mul_eleven' (x : BitVec w) : 11 * x =
  (x + x + x + x + x +
   x + x + x + x + x +
   x)

theorem sub_not_proof : sub_not_before ⊑ sub_not_after

theorem trunc_sel_equal_sext_thm.extracted_1._3 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 →
    ¬(16#32 ≥ ↑32 ∨ True ∧ x <<< 16#32 >>> 16#32 <<< 16#32 ≠ x <<< 16#32 ∨ 16#32 ≥ ↑32) →
      signExtend 32 (truncate 16 x) = (x <<< 16#32).sshiftRight' 16#32

theorem icmp_ult_8_thm (e : IntW 64) :
  icmp IntPred.ult (shl e (const? 64 8) { «nsw» := false, «nuw» := true }) (const? 64 4095) ⊑
    icmp IntPred.ult e (const? 64 16)

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

@[simp]
theorem unifyVars_eq_some_iff :
    unifyVars w v mapIn = some ((), mapOut)
    ↔ ( mapIn.lookup ⟨t, w⟩ = none ∧ mapIn.insert ⟨t, w⟩ v = mapOut
        ∨ mapIn.lookup ⟨t, w⟩ = v ∧ mapIn = mapOut
      )

theorem lshrult_03_08_thm (e : IntW 4) : icmp IntPred.ult (lshr e (const? 4 3)) (const? 4 (-8)) ⊑ const? 1 1

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

theorem PR39793_bswap_u64_as_u16_trunc_proof : PR39793_bswap_u64_as_u16_trunc_before ⊑ PR39793_bswap_u64_as_u16_trunc_after

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

theorem icmp_ne_sext_ne_allones_thm (e : IntW 32) :
  icmp IntPred.ne (sext 32 (icmp IntPred.ne e (const? 32 (-1)))) e ⊑ const? 1 1

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

theorem icmp_ne_zext_ne_zero_proof : icmp_ne_zext_ne_zero_before ⊑ icmp_ne_zext_ne_zero_after

theorem t0_commutative_thm.extracted_1._23 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1) (x_3 x_4 : BitVec 8),
  ¬ofBool (x_4 == x_3) = 1#1 → ¬ofBool (x_4 != x_3) = 1#1 → x_2 ^^^ 1#1 = 1#1 → 0#1 = 1#1 → x_1 = x

theorem uge_swap_or_max_logical_proof : uge_swap_or_max_logical_before ⊑ uge_swap_or_max_logical_after

theorem test_xor_eq_proof : test_xor_eq_before ⊑ test_xor_eq_after

theorem sdiv_exact_ne_1_proof : sdiv_exact_ne_1_before ⊑ sdiv_exact_ne_1_after

theorem badimm3_thm.extracted_1._4 : ∀ (x : BitVec 16),
  ¬(7#8 ≥ ↑8 ∨ 8#16 ≥ ↑16) →
    ¬ofBool ((truncate 8 x).sshiftRight' 7#8 == truncate 8 (x >>> 8#16)) = 1#1 →
      ¬14#16 ≥ ↑16 →
        ¬ofBool (x + 128#16 <ᵤ 256#16) = 1#1 →
          14#16 ≥ ↑16 ∨ True ∧ signExtend 16 (truncate 8 (x.sshiftRight' 14#16)) ≠ x.sshiftRight' 14#16 → False

theorem icmp_eq_x_invertable_y_todo_thm.extracted_1._2 : ∀ (x : BitVec 1) (x_1 : BitVec 8),
  ¬x = 1#1 → ofBool (x_1 == x_1 &&& 24#8) = ofBool (x_1 &&& BitVec.ofInt 8 (-25) == 0#8)

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 mkSafetyCircuit_eval_eq_false_thm
    {circs : KInductionCircuits fsm n}
    (hCircs : circs.IsLawful)
    (h : ∀ (env : _), (mkSafetyCircuit circs).eval env = false) :
    (∀ (envBitstream : _) (i : Nat), i < n + 1 → fsm.eval envBitstream i = false)

lemma CNFA.canonicalSim (m : CNFA n) : m.m.Sim m.toNFA

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

theorem lshrugt_01_14_exact_proof : lshrugt_01_14_exact_before ⊑ lshrugt_01_14_exact_after

theorem e_124 :
    11 *  ~~~(x &&&  ~~~y) + 2 *  ~~~(x &&&  ~~~x) - 7 * (x ||| y) - 6 * x - 6 *  ~~~(x |||  ~~~y) + 11 * (x &&&  ~~~y) = 13 *  ~~~(x ||| y)

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3_logical_after

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

theorem sext_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → 0#41 = signExtend 41 x

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

theorem sext_non_bool_xor_sub_1_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 8),
  (signExtend 64 x_1 ^^^ x) - signExtend 64 x_1 = (x ^^^ signExtend 64 x_1) - signExtend 64 x_1

theorem shl_nuw_add_proof : shl_nuw_add_before ⊑ shl_nuw_add_after

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

theorem uge_umin3_proof : uge_umin3_before ⊑ uge_umin3_after

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

theorem ashr_icmp2_proof : ashr_icmp2_before ⊑ ashr_icmp2_after

theorem test_ashr_exact__exact_is_safe_proof : test_ashr_exact__exact_is_safe_before ⊑ test_ashr_exact__exact_is_safe_after

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

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

theorem select_icmp_slt_zero_smin_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬ofBool (x <ₛ 0#8) = 1#1 → x ^^^ BitVec.ofInt 8 (-128) = x ||

theorem PR51351_proof : PR51351_before ⊑ PR51351_after

theorem test_invalid_simplify_eq2_proof : test_invalid_simplify_eq2_before ⊑ test_invalid_simplify_eq2_after

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

theorem sdiv_icmp1_proof : sdiv_icmp1_before ⊑ sdiv_icmp1_after

theorem trunc_nuw_xor_thm (e e_1 : IntW 8) :
  trunc 1 (LLVM.xor e_1 e) { «nsw» := false, «nuw» := true } ⊑ icmp IntPred.ne e_1 e

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 trunc_shl_nsw_nuw_31_i32_i64_proof : trunc_shl_nsw_nuw_31_i32_i64_before ⊑ trunc_shl_nsw_nuw_31_i32_i64_after

theorem and_signbit_select_shl_proof : and_signbit_select_shl_before ⊑ and_signbit_select_shl_after

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

lemma RawCNFA.autSignedCmp_wf {cmp} : autSignedCmp cmp |>.WF

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

theorem or_xor_commute3_thm (e e_1 : IntW 32) :
  LLVM.xor (LLVM.or (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) (LLVM.xor (LLVM.udiv (const? 32 42) e_1) (const? 32 (-1)))

theorem add_select_not_sext_thm (e : IntW 1) :
  add (select e (const? 64 64) (const? 64 1)) (sext 64 (LLVM.xor e (const? 1 1))) ⊑
    select e (const? 64 64) (const? 64 0)

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

theorem t0_lshr_proof : t0_lshr_before ⊑ t0_lshr_after

theorem test10_proof : test10_before ⊑ test10_after

omit [LawfulBEq A] [Fintype S] [DecidableEq S] in
lemma worklistRun'_init_wf inits hinits final? :
    let st := worklist.initState A S inits hinits final?
    (StInv A S st.m st.map ∧ worklistRun_init_post A S inits final? st.map st.m)

theorem t10_shift_by_one_proof : t10_shift_by_one_before ⊑ t10_shift_by_one_after

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

theorem test42_thm.extracted_1._1 : ∀ (x : BitVec 32), zeroExtend 32 (truncate 8 x) = x &&& 255#32

theorem e_1662 :
    5 * ((a &&&  ~~~b) ||| (b ^^^ c)) - 1 * ( ~~~c ||| (a ^^^ b)) - 1 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) + 2 * ((a &&& b) |||  ~~~(b |||  ~~~c)) - 6 *  ~~~( ~~~a ||| (b ^^^ c)) + 5 *  ~~~( ~~~a &&& (b &&& c)) + 11 * (b &&&  ~~~(a ^^^ c)) + 11 *  ~~~(a |||  ~~~c) + 4 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 7 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) + 1 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) - 2 * ((a &&& b) ^^^ (b |||  ~~~c)) - 3 * ((a &&& b) ^^^ (b ||| c)) + 3 * (b ^^^ ( ~~~a ||| (b &&& c))) + 7 * (a &&& ( ~~~b ||| c)) - 3 * (c &&& (a |||  ~~~b)) - 18 *  ~~~(a ||| (b ||| c)) - 19 *  ~~~(a ||| ( ~~~b ||| c)) - 22 *  ~~~( ~~~a ||| (b ||| c)) - 19 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 30 * ( ~~~a &&& ( ~~~b &&& c)) - 6 * ( ~~~a &&& (b &&& c)) - 15 * (a &&& ( ~~~b &&& c)) - 19 * (a &&& (b &&& c)) =  - 2 *  ~~~( ~~~a &&& (b ||| c))

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

theorem lsb_mask_sign_zext_proof : lsb_mask_sign_zext_before ⊑ lsb_mask_sign_zext_after

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

theorem test8_thm (e : IntW 128) :
  add (LLVM.xor e (ashr (shl (const? 128 1) (const? 128 127)) (const? 128 120))) (shl (const? 128 1) (const? 128 127)) ⊑
    LLVM.xor e (const? 128 170141183460469231731687303715884105600)

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

theorem e_1085 :
    4 * t + 1 *  ~~~t - 7 *  ~~~(z ^^^ t) + 5 *  ~~~z + 4 * z + 1 *  ~~~(z ||| t) - 9 *  ~~~(z |||  ~~~t) - 1 * (z &&& t) = 5 * (z &&&  ~~~t)

theorem e_266 :
     - 7 *  ~~~(x ^^^ y) - 7 *  ~~~y - 7 * x + 3 *  ~~~(x &&&  ~~~y) - 3 *  ~~~(x |||  ~~~y) + 14 * (x &&&  ~~~y) + 11 * (x &&& y) =  - 11 *  ~~~(x ||| y)

theorem test11_thm (e e_1 : IntW 9) :
  icmp IntPred.ne (sub e_1 e) (const? 9 0) ⊑ icmp IntPred.ne e_1 e

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

theorem neg_nsw_sgt_1_proof : neg_nsw_sgt_1_before ⊑ neg_nsw_sgt_1_after

theorem sext_sext_add_thm (e : IntW 32) :
  add (sext 64 (ashr e (const? 32 7))) (sext 64 (ashr e (const? 32 9))) ⊑
    sext 64 (add (ashr e (const? 32 7)) (ashr e (const? 32 9)) { «nsw» := true, «nuw» := false })

theorem ashrslt_01_04_exact_proof : ashrslt_01_04_exact_before ⊑ ashrslt_01_04_exact_after

theorem lshrult_03_09_exact_proof : lshrult_03_09_exact_before ⊑ lshrult_03_09_exact_after

theorem or_eq_with_diff_one_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x == 13#8) ||

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

lemma cases_of_lt_mod_add {a b m k : ℕ} (hsum : (a + b) % m < k)  (ha : a < m) (hb : b < m) :
  ((a + b) < m ∧ (a + b) < k) ∨ ((a + b ≥ m) ∧ (a + b) < m + k)

theorem lshr_sub_nsw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.ssubOverflow x = true ∨ 31#32 ≥ ↑32) → (x_1 - x) >>> 31#32 = zeroExtend 32 (ofBool (x_1 <ₛ x))

theorem testi16i8_com_thm (e : IntW 16) :
  icmp IntPred.eq (trunc 8 (lshr e (const? 16 8))) (ashr (trunc 8 e) (const? 8 7)) ⊑
    icmp IntPred.ult (add e (const? 16 128)) (const? 16 256)

theorem or_not_and_and_not_and_xor_commute4_proof : or_not_and_and_not_and_xor_commute4_before ⊑ or_not_and_and_not_and_xor_commute4_after

theorem test_mul__nsw_is_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x ||| BitVec.ofInt 32 (-83886080) == BitVec.ofInt 32 (-83886079)) = 1#1 →
    True ∧ (x ||| BitVec.ofInt 32 (-83886080)).smulOverflow 9#32 = true → False

theorem t0_proof : t0_before ⊑ t0_after

theorem positive_trunc_base_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.sgt (trunc 16 e) (const? 16 (-1)))
      (icmp IntPred.ult (add (trunc 16 e) (const? 16 128)) (const? 16 256)) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 65408)) (const? 32 0)

theorem main4f_like_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 &&& x_1 != x_1) ||

theorem main5c_like_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 7#32 != 7#32) ||

theorem uge_swap_and_max_commute_logical_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬ofBool (x == -1#8) = 1#1 → 0#1 = ofBool (x == -1#8)

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

theorem n7_proof : n7_before ⊑ n7_after

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

theorem shl_sub_proof : shl_sub_before ⊑ shl_sub_after

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

theorem test2_proof : test2_before ⊑ test2_after

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

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

theorem add_select_zext_proof : add_select_zext_before ⊑ add_select_zext_after

theorem src_srem_shl_demand_max_mask_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬((2#32 == 0 || 32 != 1 && x == intMin 32 && 2#32 == -1) = true ∨ 1#32 ≥ ↑32) →
    (2#32 == 0 || 32 != 1 && x == intMin 32 && 2#32 == -1) = true → False

theorem in_constant_14_vary_thm.extracted_1._1 : ∀ (x : BitVec 4),
  (x ^^^ BitVec.ofInt 4 (-2)) &&& 1#4 ^^^ x = x &&& BitVec.ofInt 4 (-2)

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

theorem shl_or_proof : shl_or_before ⊑ shl_or_after

theorem or_or_logic_and_1_proof : or_or_logic_and_1_before ⊑ or_or_logic_and_1_after

theorem lshr_or_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬((42#8 == 0 || 8 != 1 && x_1 == intMin 8 && 42#8 == -1) = true ∨ 4#8 ≥ ↑8 ∨ 4#8 ≥ ↑8) →
    ¬((42#8 == 0 || 8 != 1 && x_1 == intMin 8 && 42#8 == -1) = true ∨ 4#8 ≥ ↑8) →
      (x_1.srem 42#8 ||| x >>> 4#8) <<< 4#8 = x &&& BitVec.ofInt 8 (-16) ||

theorem same_source_matching_signbits_proof : same_source_matching_signbits_before ⊑ same_source_matching_signbits_after

@[simp] theorem Valuation.ofHVector_cons :
    ofHVector (Ty:=Ty) (x ::ₕ xs) = x ::ᵥ (ofHVector xs)

@[simp] theorem Lets.outContext_cons (lets : List (UnTyped.Expr Op VarName)) (Γ_in : Context Ty) :
    Lets.outContext ⟨e :: lets⟩ Γ_in
    = (Lets.outContext ⟨lets⟩ (Γ_in.push e.varName (signature e.op).returnType))

@[simp]
lemma FSM.eval_bv (bvn : List.Vector (BitVec w) (t.arity + 1)) :
  ((FSM.ofTerm t).evalBV fun ar => bvn.get ar.castSucc) =
    (t.evalFinBV fun ar => bvn.get ar.castSucc)

theorem ashr_and_thm.extracted_1._1 : ∀ (x : BitVec 8), ¬(x ≥ ↑8 ∨ x + 1#8 ≥ ↑8) → x ≥ ↑8 → False

theorem slt_zero_eq_i1_fail_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  ¬31#32 ≥ ↑32 →
    ofBool (zeroExtend 32 x_1 == x.sshiftRight' 31#32) = ofBool (x.sshiftRight' 31#32 == zeroExtend 32 x_1)

theorem max_sub_ult_c0_proof : max_sub_ult_c0_before ⊑ max_sub_ult_c0_after

theorem ashrslt_03_15_exact_proof : ashrslt_03_15_exact_before ⊑ ashrslt_03_15_exact_after

theorem or_ashr_not_commuted_thm (e e_1 e_2 : IntW 8) :
  LLVM.or (LLVM.xor (ashr e_2 e_1) (const? 8 (-1))) (ashr e e_1) ⊑
    ashr (LLVM.or e (LLVM.xor e_2 (const? 8 (-1)))) e_1

theorem test4_thm.extracted_1._2 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  ¬x = 1#1 → ¬8#32 = 0 → x_1 % 8#32 = x_1 &&& 7#32

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 ashrsgt_01_15_exact_proof : ashrsgt_01_15_exact_before ⊑ ashrsgt_01_15_exact_after

@[aesop safe]
theorem Std.HashMap.mem_keys_insert_new [BEq K] [LawfulBEq K] [Hashable K] [LawfulHashable K] (m : Std.HashMap K V) (k : K) : k ∈ m.insert k v

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)

@[simp] theorem denote_mk {lets : Lets d Γ_in eff Γ_out} {com : Com d Γ_out eff ty} :
    denote ⟨lets, com⟩ = fun V => (lets.denote V) >>= com.denote

theorem test6_proof : test6_before ⊑ test6_after

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

theorem test_eq2_proof : test_eq2_before ⊑ test_eq2_after

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

lemma CNFA.determinize.f_spec {m : CNFA n} {a : BitVec n} {sa sa' : BitVec m.m.stateMax} :
    (a, sa') ∈ f m sa ↔ (∀ {s'}, s' ∈ bv_to_set sa' ↔ ∃ s ∈ bv_to_set sa, s' ∈ m.m.tr s a)

theorem e_1385 :
     - 6 *  ~~~(z &&&  ~~~t) + 1 * t - 7 * (z ||| t) + 2 *  ~~~(z &&&  ~~~z) - 7 *  ~~~t - 1 *  ~~~z - 7 *  ~~~(z ^^^ t) + 11 *  ~~~(z |||  ~~~t) + 12 * (z &&&  ~~~t) + 17 * (z &&& t) =  - 19 *  ~~~(z ||| t)

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

theorem canonicalize_logic_first_and0_nswnuw_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(True ∧ x.saddOverflow 48#8 = true ∨ True ∧ x.uaddOverflow 48#8 = true) →
    ¬(True ∧ (x &&& BitVec.ofInt 8 (-10)).saddOverflow 48#8 = true ∨
          True ∧ (x &&& BitVec.ofInt 8 (-10)).uaddOverflow 48#8 = true) →
      x + 48#8 &&& BitVec.ofInt 8 (-10) = (x &&& BitVec.ofInt 8 (-10)) + 48#8

theorem test85_proof : test85_before ⊑ test85_after

theorem and_xor_commute2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(x_1 = 0 ∨ x = 0 ∨ x = 0) →
    ¬(x = 0 ∨ x_1 = 0) → 42#32 / x_1 &&& 42#32 / x ^^^ 42#32 / x = 42#32 / x &&& (42#32 / x_1 ^^^ -1#32)

theorem or_and_not_not_commute3_proof : or_and_not_not_commute3_before ⊑ or_and_not_not_commute3_after

theorem ashrsgt_01_14_proof : ashrsgt_01_14_before ⊑ ashrsgt_01_14_after

@[simp] theorem appendCases_appendInr (v : Γ.Var t) :
    appendCases (motive := motive) left right v.appendInr = (right v)

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

theorem R.fromPoly_representatitive' (a : R q n) : R.fromPoly (R.representative' q n a) = ↑ a

theorem pr33078_3_proof : pr33078_3_before ⊑ pr33078_3_after

theorem test9a_thm (e : IntW 32) :
  icmp IntPred.ne (LLVM.and e (const? 32 (-2147483648))) (const? 32 0) ⊑
    icmp IntPred.slt e (const? 32 0)

theorem or_eq_with_one_bit_diff_constants3_proof : or_eq_with_one_bit_diff_constants3_before ⊑ or_eq_with_one_bit_diff_constants3_after

theorem select_ashr_thm.extracted_1._3 : ∀ (x x_1 : BitVec 128) (x_2 : BitVec 1), ¬x_2 = 1#1 → 0#128 ≥ ↑128 → False

theorem negative_and_odd_proof : negative_and_odd_before ⊑ negative_and_odd_after

theorem test4_thm.extracted_1._1 : ∀ (x : BitVec 49), (x &&& BitVec.ofInt 49 (-2)) + 1#49 = x ||

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

@[simp]
theorem Term.denoteFin_width_zero  (t : Term) (env : EnvFin 0 t.numVars) :
    t.denoteFin env = 0

theorem test32_proof : test32_before ⊑ test32_after

theorem ashr_bitwidth_mask_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬7#8 ≥ ↑8 → ¬ofBool (x_1 <ₛ 0#8) = 1#1 → x_1.sshiftRight' 7#8 &&& x = 0#8

theorem ashrsgt_01_09_proof : ashrsgt_01_09_before ⊑ ashrsgt_01_09_after

theorem sdiv4_proof : sdiv4_before ⊑ sdiv4_after

theorem icmp_eq_sext_eq_allones_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (x == -1#32)) == x) = ofBool (x + 1#32 <ᵤ 2#32)

@[simp] theorem Com.changeDialect_var (f : DialectMorphism d d')
    (e : Expr d Γ eff t) (body : Com d _ eff u) :
    (Com.var e body).changeDialect f
    = have h

theorem test_logical_proof : test_logical_before ⊑ test_logical_after

theorem alive_AndOrXor_2430 : alive_AndOrXor_2430_src ⊑ alive_AndOrXor_2430_tgt

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

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

theorem or_xor_xor_normal_variant1_proof : or_xor_xor_normal_variant1_before ⊑ or_xor_xor_normal_variant1_after

theorem t7_thm.extracted_1._3 : ∀ (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 e_185 :
    5 *  ~~~(x &&&  ~~~y) - 6 * x - 4 *  ~~~(x ||| y) - 6 *  ~~~(x |||  ~~~y) + 6 * (x &&&  ~~~y) + 1 * (x &&& y) = 1 *  ~~~y - 1 * (x ^^^ y)

theorem and_or_not_not_commute4_proof : and_or_not_not_commute4_before ⊑ and_or_not_not_commute4_after

theorem generic (p q r : Nat)  (hpq : p ≤ q) (hpr : p ≤ r) (hqr : q ≤ r) 
    (x : BitVec p) (y : BitVec q):
   (BitVec.signExtend r x < BitVec.signExtend r y) ↔ BitVec.signExtend q x < y

theorem mul_zero (a : ZMod q) : a * 0 = 0

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

lemma autOfTermBinop_bv_language op {t₁ t₂ : Term} (m₁ : CNFA (t₁.arity + 1)) (m₂ : CNFA (t₂.arity + 1)) :
    m₁.bv_recognizes t₁.language →
    m₂.bv_recognizes t₂.language →
    (autOfTermBinop op m₁ m₂ |>.bv_recognizes (op.subst_arity' ▸ (op.subst t₁ t₂).language))

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

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

theorem cast_test_2002h08h02_thm.extracted_1._1 : ∀ (x : BitVec 64), zeroExtend 64 (truncate 8 x) = x &&& 255#64

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

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

theorem gt_unsigned_to_large_unsigned_proof : gt_unsigned_to_large_unsigned_before ⊑ gt_unsigned_to_large_unsigned_after

theorem test_or1_proof : test_or1_before ⊑ test_or1_after

theorem ashrslt_03_13_exact_proof : ashrslt_03_13_exact_before ⊑ ashrslt_03_13_exact_after

theorem not_not_true_thm (e e_1 : IntW 1) :
  select (LLVM.xor e_1 (const? 1 1)) (LLVM.xor e (const? 1 1)) (const? 1 1) ⊑
    select e_1 (const? 1 1) (LLVM.xor e (const? 1 1))

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

theorem f_thm (e : IntW 32) :
  select (icmp IntPred.slt e (const? 32 0)) (const? 1 1) (icmp IntPred.sgt e (ashr (const? 32 7) e)) ⊑
    select (icmp IntPred.slt e (const? 32 0)) (const? 1 1)
      (icmp IntPred.sgt e (lshr (const? 32 7) e))

theorem add_select_not_sext_proof : add_select_not_sext_before ⊑ add_select_not_sext_after

theorem e_118 :
    1 *  ~~~(x &&&  ~~~x) - 5 * (x |||  ~~~y) - 6 * x - 1 *  ~~~y + 11 * (x &&&  ~~~y) + 10 * (x &&& y) = 1 *  ~~~(x |||  ~~~y) - 5 *  ~~~(x ||| y)

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

theorem test_nuw_and_unsigned_pred_proof : test_nuw_and_unsigned_pred_before ⊑ test_nuw_and_unsigned_pred_after

theorem select_ashr_thm.extracted_1._1 : ∀ (x : BitVec 128) (x_1 : BitVec 1), ¬x_1 = 1#1 → 0#128 ≥ ↑128 → False

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

theorem lshr_lshr_proof : lshr_lshr_before ⊑ lshr_lshr_after

theorem icmp_ne_sext_ne_zero_i128_thm.extracted_1._1 : ∀ (x : BitVec 128),
  ofBool (signExtend 128 (ofBool (x != 0#128)) != x) = ofBool (x + -1#128 <ᵤ BitVec.ofInt 128 (-2))

theorem uge_or_not_max_commute_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.ne e_1 (const? 8 (-1))) (const? 1 1) (icmp IntPred.uge e_1 e) ⊑ const? 1 1

theorem test16_proof : test16_before ⊑ test16_after

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

theorem 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 pr89516_proof : pr89516_before ⊑ pr89516_after

theorem reused_mul_nuw_xy_z_selectnonzero_ugt_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 8),
  ¬ofBool (x_2 != 0#8) = 1#1 →
    ¬ofBool (x_2 == 0#8) = 1#1 → True ∧ x_1.umulOverflow x_2 = true ∨ True ∧ x.umulOverflow x_2 = true → False

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

theorem ult_swap_and_max_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.ugt e_1 e) (icmp IntPred.eq e (const? 8 (-1))) (const? 1 0) ⊑ const? 1 0

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

theorem Tensor2d.transpose_involutive (t: Tensor2d α):
  (t.transpose).transpose = t

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

theorem ult_1_impliesF_eq_1_proof : ult_1_impliesF_eq_1_before ⊑ ult_1_impliesF_eq_1_after

theorem test_ule_xor_proof : test_ule_xor_before ⊑ test_ule_xor_after

theorem FSM.carryWith_congrEnv_envBitstream_set_of_le (fsm : FSM arity)
    (s0 : fsm.α → Bool) (env : arity → BitStream) (n : Nat) (v : arity → Bool)
    (k : Nat) (hk : k ≤ n) :
  fsm.carryWith s0 (envBitstream_set env n v) k =
  fsm.carryWith s0 env k

theorem no_shift_xor_multiuse_cmp_or_thm.extracted_1._4 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ¬ofBool (0#32 != x_3 &&& 4096#32) = 1#1 →
    ¬ofBool (x_3 &&& 4096#32 == 0#32) = 1#1 →
      (x_2 ||| 4096#32) * x * (x_2 ||| 4096#32) = x_2 * x_1 * (x_2 ||| 4096#32)

theorem bools_multi_uses2_logical_proof : bools_multi_uses2_logical_before ⊑ bools_multi_uses2_logical_after

@[simp]
theorem Term.toBV_bxor {wenv : WidthExpr.Env wcard}
    {tctx : Term.Ctx wcard tcard}
    (benv : Term.BoolEnv bcard)
    (tenv : tctx.Env wenv) (a b : Term bcard ncard icard pcard tctx (.bv w)) :
  Term.toBV benv nenv ienv penv tenv (.bxor a b) = a.toBV benv nenv ienv penv tenv ^^^ b.toBV benv nenv ienv penv tenv

theorem fold_icmp_shl_nuw_c2_precondition2_proof : fold_icmp_shl_nuw_c2_precondition2_before ⊑ fold_icmp_shl_nuw_c2_precondition2_after

theorem icmp_select_var_select_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  x_1 = 1#1 → ofBool (x == 0#8) = 1#1 ∧ x_1 = 1#1 → ofBool (x == 0#8) = 1#1 → ¬True → ofBool (x == x) = 1#1

theorem t7_ugt_sgt_neg1_thm.extracted_1._15 : ∀ (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 c_1_0_0_proof : c_1_0_0_before ⊑ c_1_0_0_after

theorem select_of_symmetric_selects_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 x_2 : BitVec 1),
  x_2 = 1#1 → x_1 = 1#1 → x_1 ^^^ x_2 = 1#1 → False

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

theorem c0_thm (e : IntW 8) :
  icmp IntPred.sgt (LLVM.and e (const? 8 3)) e ⊑ icmp IntPred.slt e (const? 8 0)

theorem logic_or_logic_and_6_proof : logic_or_logic_and_6_before ⊑ logic_or_logic_and_6_after

theorem _root_.SetRel.set_eq_symm {R : SetRel α β} (h : R.set_eq A B) : R.inv.set_eq B A

theorem test18_proof : test18_before ⊑ test18_after

theorem test_negative_combined_sub_unsigned_overflow_proof : test_negative_combined_sub_unsigned_overflow_before ⊑ test_negative_combined_sub_unsigned_overflow_after

theorem e_1913 :
    5 * ( ~~~a ||| ( ~~~b ||| c)) - 1 * ( ~~~a &&& ( ~~~b ||| c)) + 1 *  ~~~b - 5 * (b ||| (a &&& c)) + 2 * ((a &&& c) ||| (b &&&  ~~~c)) + 11 *  ~~~a - 1 * (b ^^^ (a |||  ~~~c)) + 5 *  ~~~( ~~~a ||| (b &&& c)) - 1 * (c ||| (a ^^^ b)) + 5 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) - 11 * ( ~~~b &&&  ~~~(a ^^^ c)) - 1 * ((a &&& b) |||  ~~~(b |||  ~~~c)) + 11 * (b |||  ~~~(a ||| c)) - 2 * ( ~~~c &&& (a ^^^ b)) - 5 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 1 * (a ^^^ ( ~~~b ||| c)) - 5 * (b ^^^  ~~~(a &&& (b ||| c))) + 3 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) - 2 * ((a ^^^ b) |||  ~~~(a ^^^ c)) + 7 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) + 4 *  ~~~(a |||  ~~~c) + 1 * (c &&& (a |||  ~~~b)) + 7 * (a &&& (b ^^^ c)) - 6 * (b |||  ~~~(a |||  ~~~c)) + 11 * ((a ^^^ b) ||| (a ^^^ c)) + 2 * ((a &&& b) ^^^ (a ^^^ ( ~~~b ||| c))) - 1 *  ~~~(a |||  ~~~b) - 1 * ((a &&&  ~~~b) ||| (a ^^^ (b ^^^ c))) + 2 *  ~~~( ~~~a &&& (b ^^^ c)) + 3 * ( ~~~b &&& (a ^^^ c)) + 2 * (c ^^^  ~~~(a &&& (b &&& c))) - 3 * (b ^^^ ( ~~~a ||| (b ^^^ c))) + 1 *  ~~~(a ^^^ (b ^^^ c)) + 1 * (c &&&  ~~~(a &&& b)) - 2 * (b |||  ~~~(a ^^^ c)) + 7 * (c ^^^ ( ~~~a &&& (b ||| c))) + 11 * ( ~~~c |||  ~~~(a ^^^ b)) + 3 * (a ^^^ ( ~~~b &&& c)) + 1 * b - 3 * ((a &&& b) |||  ~~~(b ||| c)) + 2 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) - 7 * ((a &&& c) ^^^ (a ^^^ (b &&& c))) - 21 *  ~~~(a ||| (b ||| c)) - 48 *  ~~~(a ||| ( ~~~b ||| c)) - 25 *  ~~~( ~~~a ||| (b ||| c)) - 25 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 45 * ( ~~~a &&& ( ~~~b &&& c)) - 24 * ( ~~~a &&& (b &&& c)) - 13 * (a &&& ( ~~~b &&& c)) - 13 * (a &&& (b &&& c)) = 3 * (a |||  ~~~b)

theorem ule_and_min_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 ≤ᵤ x) = 1#1 → 0#1 = ofBool (x_1 == 0#8)

theorem falseIffNeq_eq_false_iff (n i : Nat) :
    falseIffNeq n i = false ↔ i ≠ n

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

theorem test_mul_nuw__nsw_is_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x ||| BitVec.ofInt 32 (-83886080) == BitVec.ofInt 32 (-83886079)) = 1#1 →
    True ∧ (x ||| BitVec.ofInt 32 (-83886080)).smulOverflow 9#32 = true → False

theorem fold_add_udiv_urem_commuted_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(10#32 = 0 ∨ 10#32 = 0 ∨ 4#32 ≥ ↑32) → 10#32 = 0 ∨ True ∧ (x / 10#32).umulOverflow 6#32 = true → False

@[simp] theorem Com.toFlatCom_ret [LawfulMonad d.m] (com : Com d Γ .pure t) :
    com.toFlatCom.rets = com.returnVars

theorem positive_sameconst_shlnuwnsw_proof : positive_sameconst_shlnuwnsw_before ⊑ positive_sameconst_shlnuwnsw_after

theorem and_or_not_not_commute5_proof : and_or_not_not_commute5_before ⊑ and_or_not_not_commute5_after

theorem e_50 :
    2 *  ~~~y + 1 *  ~~~(x &&&  ~~~x) - 3 * (x ^^^ y) + 8 *  ~~~(x ||| y) + 10 * (x &&& y) = 11 *  ~~~(x &&&  ~~~y) - 13 *  ~~~(x |||  ~~~y)

theorem masked_or_A_slightly_optimized_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x <ᵤ 8#32) = 1#1 → 1#1 = ofBool (x &&& BitVec.ofInt 32 (-40) == 0#32)

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

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

theorem eq_3210_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(24#32 ≥ ↑32 ∨ 24#32 ≥ ↑32 ∨ 16#32 ≥ ↑32 ∨ 16#32 ≥ ↑32 ∨ 8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32) →
    ofBool (truncate 8 (x_1 >>> 24#32) == truncate 8 (x >>> 24#32)) &&&
        (ofBool (truncate 8 (x_1 >>> 16#32) == truncate 8 (x >>> 16#32)) &&&
          (ofBool (truncate 8 x_1 == truncate 8 x) &&& ofBool (truncate 8 (x_1 >>> 8#32) == truncate 8 (x >>> 8#32)))) =
      ofBool (x_1 == x)

theorem e_1427 :
     - 11 *  ~~~(z &&& t) - 11 *  ~~~(z &&&  ~~~t) - 2 * z - 5 * t - 1 *  ~~~(z ^^^ t) + 1 * (z ||| t) + 23 *  ~~~(z ||| t) + 25 *  ~~~(z |||  ~~~t) + 11 * (z &&&  ~~~t) + 18 * (z &&& t) =  - 1 * (z ^^^ t)

theorem substitute_constant_or_ne_swap_sle_proof : substitute_constant_or_ne_swap_sle_before ⊑ substitute_constant_or_ne_swap_sle_after

theorem e_1388 :
     - 3 * (z ||| t) + 2 * (z ^^^ t) + 3 * t - 2 *  ~~~(z ^^^ t) + 4 *  ~~~(z &&&  ~~~z) + 11 *  ~~~t + 1 * z + 1 * (z |||  ~~~t) - 6 *  ~~~(z |||  ~~~t) - 16 * (z &&&  ~~~t) = 4 * (z &&& t) + 14 *  ~~~(z ||| t)

@[simp]
theorem MatchVar.isMonotone_bind_liftM {x? : Option α} {g : α → MatchVar Δ Γ} :
    IsMonotone (liftM x? >>= g) ↔ (∀ x ∈ x?, (g x).IsMonotone)

theorem canonicalize_logic_first_xor_0_proof : canonicalize_logic_first_xor_0_before ⊑ canonicalize_logic_first_xor_0_after

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

theorem sge_or_not_max_commute_logical_proof : sge_or_not_max_commute_logical_before ⊑ sge_or_not_max_commute_logical_after

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

theorem zext_or_masked_bit_test_proof : zext_or_masked_bit_test_before ⊑ zext_or_masked_bit_test_after

theorem alive_InstCombineShift__476  (w : Nat)   : alive_InstCombineShift__476_src w  ⊑ alive_InstCombineShift__476_tgt w

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

theorem sub_select_sext_op_swapped_non_const_args_thm.extracted_1._3 : ∀ (x x_1 : BitVec 6) (x_2 : BitVec 1),
  x_2 = 1#1 → signExtend 6 x_2 - x_1 = x_1 ^^^ -1#6

theorem fold_sext_to_and3_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x &&& 1073741826#32 != 2#32) = ofBool (x &&& BitVec.ofInt 8 (-126) != 2#8)

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

theorem ashr_exact_add_negative_shift_negative_proof : ashr_exact_add_negative_shift_negative_before ⊑ ashr_exact_add_negative_shift_negative_after

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

theorem lshrugt_02_13_exact_proof : lshrugt_02_13_exact_before ⊑ lshrugt_02_13_exact_after

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

theorem t0_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬4#8 ≥ ↑8 → signExtend 16 (truncate 4 (x >>> 4#8)) = signExtend 16 (x.sshiftRight' 4#8)

theorem PR2844_logical_thm.extracted_1._4 : ∀ (x : BitVec 32),
  ¬ofBool (x == 0#32) = 1#1 →
    ¬ofBool (x <ₛ BitVec.ofInt 32 (-638208501)) = 1#1 →
      1#32 = zeroExtend 32 (ofBool (x != 0#32) &&& ofBool (BitVec.ofInt 32 (-638208502) <ₛ x))

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

theorem or_xor_tree_1100_thm (e e_1 e_2 : IntW 32) :
  LLVM.or (LLVM.xor (mul e_2 (const? 32 42)) (LLVM.xor (mul e_1 (const? 32 42)) (mul e (const? 32 42))))
      (LLVM.xor (mul e_2 (const? 32 42)) (mul e_1 (const? 32 42))) ⊑
    LLVM.or (LLVM.xor (mul e_2 (const? 32 42)) (mul e_1 (const? 32 42))) (mul e (const? 32 42))

theorem modulo4_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(4#32 == 0 || 32 != 1 && x == intMin 32 && 4#32 == -1) = true →
    ofBool (x.srem 4#32 <ₛ 0#32) = 1#1 →
      ¬((4#32 == 0 || 32 != 1 && x == intMin 32 && 4#32 == -1) = true ∨
            True ∧ (4#32).saddOverflow (x.srem 4#32) = true) →
        4#32 + x.srem 4#32 = x &&& 3#32

theorem simplify_and_common_op_commute1_proof : simplify_and_common_op_commute1_before ⊑ simplify_and_common_op_commute1_after

theorem ult_umin3_proof : ult_umin3_before ⊑ ult_umin3_after

theorem lshr_mul_times_3_div_2_exact_proof : lshr_mul_times_3_div_2_exact_before ⊑ lshr_mul_times_3_div_2_exact_after

theorem scalar_i32_shl_and_negC_ne_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬x ≥ ↑32 → ofBool (x_1 <<< x &&& BitVec.ofInt 32 (-262144) != 0#32) = ofBool (262143#32 <ᵤ x_1 <<< x)

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

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

theorem ashrslt_02_15_exact_proof : ashrslt_02_15_exact_before ⊑ ashrslt_02_15_exact_after

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

theorem shl_and_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ x + 1#8 ≥ ↑8) → ¬x ≥ ↑8 → 48#8 <<< x &&& 8#8 <<< (x + 1#8) = 16#8 <<< x

theorem no_shift_no_xor_multiuse_cmp_xor_thm.extracted_1._4 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ¬ofBool (x_3 &&& 4096#32 == 0#32) = 1#1 →
    (x_2 ^^^ 4096#32) * x * (x_2 ^^^ 4096#32) = (x_2 ^^^ x_3 &&& 4096#32) * x * (x_2 ^^^ 4096#32)

theorem e_1715 :
    4 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) + 3 * (c ^^^  ~~~(a &&& (b ||| c))) + 7 *  ~~~(a |||  ~~~b) + 4 *  ~~~(b ^^^ c) + 2 * ( ~~~b &&& (a ^^^ c)) - 3 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 1 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) + 7 * (c ^^^ (a ||| (b ||| c))) + 5 *  ~~~(a &&&  ~~~b) + 11 * ( ~~~(a &&& b) &&&  ~~~(b ^^^ c)) + 2 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 5 * (a ||| c) - 5 * ( ~~~a ||| (b ^^^ c)) + 1 *  ~~~(a ||| ( ~~~b &&& c)) - 5 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) + 2 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 1 *  ~~~(a &&& b) - 3 * ((a &&&  ~~~b) ||| (b ^^^ c)) + 2 * (b ^^^  ~~~( ~~~a ||| (b ^^^ c))) - 3 * (b ^^^  ~~~(a &&& c)) - 1 * (b ||| (a &&&  ~~~c)) + 3 * ((a &&& b) |||  ~~~(b |||  ~~~c)) - 16 *  ~~~(a ||| (b ||| c)) - 15 *  ~~~(a ||| ( ~~~b ||| c)) - 24 *  ~~~( ~~~a ||| (b ||| c)) - 9 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 10 * ( ~~~a &&& ( ~~~b &&& c)) - 23 * ( ~~~a &&& (b &&& c)) + 2 * (a &&& ( ~~~b &&& c)) - 13 * (a &&& (b &&& c)) = 6 *  ~~~( ~~~a &&& ( ~~~b ||| c))

theorem PR60818_ne_proof : PR60818_ne_before ⊑ PR60818_ne_after

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

theorem n7_wrong_pred2_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (sub e_1 e) e_1 ⊑ icmp IntPred.eq e (const? 8 0)

theorem bitwise_and_logical_and_masked_icmp_allones_poison2_thm.extracted_1._3 : ∀ (x : BitVec 32) (x_1 : BitVec 1)
  (x_2 : BitVec 32),
  ¬ofBool (x_2 &&& 8#32 == 8#32) = 1#1 →
    ofBool (x_2 &&& 8#32 != 0#32) = 1#1 → 0#1 &&& ofBool (x_2 &&& x == x) = x_1 &&& ofBool (x_2 &&& x == x)

theorem mul_splat_fold_no_nuw_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.smulOverflow 65537#32 = true ∨ 16#32 ≥ ↑32) →
    16#32 ≥ ↑32 ∨ True ∧ x.saddOverflow (x >>> 16#32) = true → False

theorem sext_proof : sext_before ⊑ sext_after

theorem sext_zext_uge_known_nonneg_op0_wide_thm (e : IntW 8) (e_1 : IntW 16) :
  icmp IntPred.uge (sext 32 e_1) (zext 32 (LLVM.and e (const? 8 12))) ⊑
    icmp IntPred.uge e_1 (zext 16 (LLVM.and e (const? 8 12)) { «nneg» := true })

theorem t3_ult_sgt_neg1_proof : t3_ult_sgt_neg1_before ⊑ t3_ult_sgt_neg1_after

theorem alive_AndOrXor_2627  (w : Nat)   : alive_AndOrXor_2627_src w  ⊑ alive_AndOrXor_2627_tgt w

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

theorem positive_biggershl_shlnsw_ashrexact_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x >>> 3#8 <<< 3#8 ≠ x ∨
        3#8 ≥ ↑8 ∨ True ∧ (x.sshiftRight' 3#8 <<< 6#8).sshiftRight' 6#8 ≠ x.sshiftRight' 3#8 ∨ 6#8 ≥ ↑8) →
    True ∧ (x <<< 3#8).sshiftRight' 3#8 ≠ x ∨ 3#8 ≥ ↑8 → False

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

theorem bv_AddSub_1164 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.add (LLVM.sub (LLVM.const? w 0) e) e_1 ⊑ LLVM.sub e_1 e

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

theorem select_icmp_eq_0_and_1_xor_1_proof : select_icmp_eq_0_and_1_xor_1_before ⊑ select_icmp_eq_0_and_1_xor_1_after

theorem ugt_and_not_min_logical_proof : ugt_and_not_min_logical_before ⊑ ugt_and_not_min_logical_after

theorem test_proof : test_before ⊑ test_after
</all_available_lemmas>

<local_ctx>
import LeanMLIR.Framework

import LeanMLIR.Transforms.Rewrite.Mapping

open Ctxt (Var VarSet Valuation Hom)

variable {d} [DialectSignature d] [DecidableEq d.Ty]

variable {Γ : Ctxt d.Ty} {ty : d.Ty}

abbrev MatchVarM (Δ Γ : Ctxt d.Ty) := (StateT (Mapping Δ Γ) Option)

abbrev MatchVar (Δ Γ : Ctxt d.Ty)  := MatchVarM Δ Γ Unit

def MatchVarM.unifyVars {Δ Γ : Ctxt d.Ty} (v : Δ.Var t) (w : Γ.Var t) : MatchVar Δ Γ :=
  fun ma =>
    match ma.lookup ⟨_, v⟩ with
    | some v =>
      if v = w then
        some ((), ma)
      else
        none
    | none =>
      some ((), AList.insert ⟨_, v⟩ w ma)

open MatchVarM

variable [DecidableEq d.Op]

def matchArg [DecidableEq d.Op]
    (lets : Lets d Γ_in eff Γ_out) (matchLets : Lets d Δ_in .pure Δ_out) :
    {l : List d.Ty} → HVector (Var Γ_out) l → HVector (Var Δ_out) l →
    MatchVar Δ_in Γ_out
  | _, .nil, .nil => return
  | t::l, .cons vₗ vsₗ, .cons vᵣ vsᵣ => do
      matchVar (t := t) lets vₗ matchLets vᵣ
      matchArg lets matchLets vsₗ vsᵣ
  termination_by l => (sizeOf matchLets, l.length + 1)

def matchVar {Γ_in Γ_out Δ_in Δ_out : Ctxt d.Ty} {t : d.Ty} [DecidableEq d.Op]
    (lets : Lets d Γ_in eff Γ_out) (v : Var Γ_out t) :
    (matchLets : Lets d Δ_in .pure Δ_out) →
    (w : Var Δ_out t) →
    MatchVar Δ_in Γ_out
   
  | @Lets.var _ _ _ _ Δ_out ts matchLets matchExpr, w => by admit /- proof elided -/
      | right w =>
        exact matchVar lets v matchLets w
      | left w => exact do
        let ⟨ts', w', ie⟩ ← lets.getPureExpr v
        if hs : ∃ h : ie.op = matchExpr.op, ie.regArgs = (h ▸ matchExpr.regArgs) then
          have hts : Ctxt.ofList ts' = ts := by admit /- proof elided -/

end

section MatchVar

variable [DecidableEq d.Op] {Γ_in Γ_out Δ_in Δ_out t te}
          {lets : Lets d Γ_in eff Γ_out} {v : Var Γ_out t}
          {matchLets : Lets d Δ_in .pure Δ_out}
          {matchExpr : Expr d Δ_out .pure te}

variable (lets v matchLets w) (mapIn : Mapping _ _) in

def MatchVarResult := { mapOut : Mapping _ _ //
  ∃ (mapIn' mapOut' : Mapping _ _),
    mapIn.entries ⊆ mapIn'.entries
    ∧ mapOut'.entries ⊆ mapOut.entries
    ∧ matchVar lets v matchLets w mapIn' = some ((), mapOut') }

variable (lets matchLets) {tys} (vs ws : HVector _ tys) (mapIn : Mapping _ _) in

def MatchArgResult := { mapOut : Mapping _ _ //
  ∃ (mapIn' mapOut' : Mapping _ _),
    mapIn.entries ⊆ mapIn'.entries
    ∧ mapOut'.entries ⊆ mapOut.entries
    ∧ matchArg lets matchLets vs ws mapIn' = some ((), mapOut') }

namespace MatchVarResult

variable [TyDenote d.Ty] [∀ (t : d.Ty), Inhabited ⟦t⟧] in

section Left

variable {w : Δ_out.Var t}

def eqvVarLeft  :
    MatchVarResult lets v (.var matchLets matchExpr) w.appendInr ma
    ≃ MatchVarResult lets v matchLets w ma where
  toFun := fun ⟨x, h⟩ => ⟨x, by admit /- proof elided -/
  ⟩
  invFun := fun ⟨x, h⟩ => ⟨x, by admit /- proof elided -/
  ⟩

variable {mapIn} (mapOut : MatchVarResult lets v (.var matchLets matchExpr) w.appendInr mapIn)

end Left

variable {w : Var ⟨te⟩ _} {mapIn}

noncomputable def toArgResult
    (mapOut : MatchVarResult lets v (.var matchLets matchExpr) w.appendInl mapIn) :
    let args := mapOut.getPureExpr_eq_some.choose
    MatchArgResult lets matchLets args matchExpr.args mapIn :=
  ⟨mapOut.1, by admit /- proof elided -/
  ⟩

end MatchVarResult

end MatchVar

section SubsetEntries

open MatchVar

section UnifyVars

variable {Δ Γ : Ctxt d.Ty} {t} (w : Δ.Var t) (v : Γ.Var t)

end UnifyVars

variable [DecidableEq d.Op]

end SubsetEntries

namespace MatchArgResult

variable [DecidableEq d.Op] {Γ_in Γ_out Δ_in Δ_out te}
          {lets : Lets d Γ_in eff Γ_out}
          {matchLets : Lets d Δ_in .pure Δ_out}
          {matchExpr : Expr d Δ_out .pure te}
          {u us}
          {v : Γ_out.Var u} {vs : HVector Γ_out.Var us}
          {w : Δ_out.Var u} {ws : HVector Δ_out.Var us}
          {mapIn : Mapping _ _}
          (mapOut : MatchArgResult lets matchLets (v ::ₕ vs) (w ::ₕ ws) mapIn)

end MatchArgResult

section DenoteLemmas

variable [TyDenote d.Ty] [DecidableEq d.Op]

variable [∀ (t : d.Ty), Inhabited ⟦t⟧]

variable [Monad d.m] [LawfulMonad d.m] [DialectDenote d]

section DenoteIntoSubtype

end DenoteIntoSubtype

variable {Γ_in Γ_out Δ_in Δ_out : Ctxt d.Ty}
    {lets : Lets d Γ_in eff Γ_out}
    {matchLets : Lets d Δ_in .pure Δ_out}
</local_ctx>

<target_theorem>
theorem denote_matchVar
    {v w : Var _ t}
    (mapOut : MatchVarResult lets v matchLets w mapIn)
    (V : lets.ValidDenotation) :
    (matchLets.denote (mapOut.val.mapValuation V.val) w)
    = V.val v :=
</target_theorem>

