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>
Bool in Init.Prelude
Nat in Init.Prelude
BitVec in Init.Prelude
BitVec.adcb in Init.Data.BitVec.Bitblast
Prod in Init.Prelude
Fin in Init.Prelude
BitVec.iunfoldr in Init.Data.BitVec.Folds
FinEnum in Mathlib.Data.FinEnum
FinEnum.card in Mathlib.Data.FinEnum
Polynomial.X in Mathlib.Algebra.Polynomial.Basic
ZMod in Mathlib.Data.ZMod.Defs
BEq in Init.Prelude
DecidableEq in Init.Prelude
Hashable in Init.Prelude
Repr in Init.Data.Repr
Std.HashMap in Std.Data.HashMap.Basic
Std.HashSet in Std.Data.HashSet.Basic
Array in Init.Prelude
List.map in Init.Prelude
Array.foldl in Init.Data.Array.Basic
Std.HashMap.emptyWithCapacity in Std.Data.HashMap.Basic
Array.size in Init.Prelude
List in Init.Prelude
Vector in Init.Data.Vector.Basic
String in Init.Prelude
Unit in Init.Prelude
Field in Mathlib.Algebra.Field.Defs
Int.xor in Mathlib.Data.Int.Bitwise
Inhabited in Init.Prelude
Lean.ToExpr in Lean.ToExpr
Empty in Init.Prelude
Empty.elim in Init.Core
Sum.inr in Init.Core
Sum.inl in Init.Core
Sum in Init.Core
Sum.elim in Init.Data.Sum.Basic
id in Init.Prelude
Fin.castLE in Init.Data.Fin.Basic
cond in Init.Prelude
Nat.testBit in Init.Data.Nat.Bitwise.Basic
Fin.last in Init.Data.Fin.Basic
Array.emptyWithCapacity in Init.Prelude
Prod.mk in Init.Prelude
Array.empty in Init.Prelude
FinEnum.toList in Mathlib.Data.FinEnum
FinEnum.equiv in Mathlib.Data.FinEnum
NFA in Mathlib.Computability.NFA
NFA.accept in Mathlib.Computability.NFA
NFA.start in Mathlib.Computability.NFA
NFA.step in Mathlib.Computability.NFA
List.Vector in Mathlib.Data.Vector.Defs
Set in Mathlib.Data.Set.Defs
NFA.stepSet in Mathlib.Computability.NFA
Subsingleton in Init.Core
reduceDIte in Lean.Meta.Tactic.Simp.BuiltinSimprocs.Core
BitVec.ofNat in Init.Prelude
BitVec.zero in Init.Data.BitVec.Basic
Language in Mathlib.Computability.Language
BitVec.cons in Init.Data.BitVec.Basic
List.Vector.ofFn in Mathlib.Data.Vector.Defs
List.Vector.replicate in Mathlib.Data.Vector.Defs
List.finRange in Init.Data.List.FinRange
List.reverseRecOn in Mathlib.Data.List.Induction
SetRel in Mathlib.Data.Rel
Array.back? in Init.Data.Array.Basic
Array.isEmpty in Init.Data.Array.Basic
List.next in Mathlib.Data.List.Cycle
L in Archive.Hairer
Fin.mk in Init.Prelude
Fin.cast in Init.Data.Fin.Basic
Fin.castLT in Init.Data.Fin.Basic
Fin.subNat in Init.Data.Fin.Basic
List.Vector.get in Mathlib.Data.Vector.Defs
List.Vector.nil in Mathlib.Data.Vector.Defs
Finset in Mathlib.Data.Finset.Defs
Finset.range in Mathlib.Data.Finset.Range
DFA in Mathlib.Computability.DFA
NFA.toDFA in Mathlib.Computability.NFA
List.range in Init.Data.List.Basic
Vector.ofFn in Init.Data.Vector.Basic

syntax "max" : MLIR.Pretty.uniform_op

syntax "slt" : MLIR.Pretty.uniform_op

syntax "xor" : MLIR.Pretty.uniform_op

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

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

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

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

def carry (initCarry : Bool) (x y : BitStream) : BitStream :=
  fun n => (addAux' initCarry x y n).2

def BitStream : Type := Nat → Bool

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

def BitVec.ofFn {w : Nat} (f : Fin w → Bool) : BitVec w :=
  BitVec.iunfoldr (fun i _ => ((), f i)) () |>.2

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

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 worklistRun' (final : S → Bool) (inits : Array S) (hinits : inits.toList.Nodup) (f : S → Array (A × S)) : RawCNFA A :=
  let st0 := worklist.initState _ _ inits hinits final
  go st0
where go (st0 : worklist.St A S) : RawCNFA A :=
  if hemp : st0.worklist.isEmpty then st0.m else
  let sa? := st0.worklist.back?
  match heq : sa? with
  | some sa =>
    let wl := st0.worklist.pop
    let st1 := { st0 with worklist := wl,
                          worklist_nodup := by admit /- proof elided -/

structure worklist.St where
  m : RawCNFA A
  map : Std.HashMap S State := ∅
  worklist : Array S := ∅
  worklist_nodup : worklist.toList.Nodup
  worklist_incl : ∀ sa ∈ worklist, sa ∈ map

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

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

abbrev State := Nat

def RawCNFA.empty : RawCNFA A := {
  stateMax := 0
  initials := ∅
  finals := ∅
  trans := ∅
}

def processOneElem (final : S → Bool) (s : State) (st : worklist.St A S) : A × S → worklist.St A S :=
  fun (a', sa') =>
    let (s', st') := st.addOrCreateState _ _ (final sa') sa'
    let m := st'.m.addTrans a' s s'
    { st' with m }

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

structure CNFA (n : Nat) where
  m : RawCNFA (BitVec n)
  wf : m.WF

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

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

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

def sub (x y : BitStream) : BitStream :=
  fun n => (subAux x y n).1

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

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

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 termEvalEqFSM : ∀ (t : Term), FSMTermSolution t
  | ofNat n =>
    { toFSM := FSM.ofNat n,
      good := by admit /- proof elided -/

def or : FSM Bool :=
  { α := Empty,
    initCarry := Empty.elim,
    outputCirc := Circuit.var true (inr true) ||| Circuit.var true (inr false),
    nextStateCirc := fun a => a.elim
  }

def shiftLeft (n : Nat) : FSM Unit :=
  match n with
  | 0 => FSM.id
  | n + 1 => composeUnaryAux (FSM.ls false) (shiftLeft n)

def id : FSM Unit := {
 α := Empty,
 initCarry := Empty.elim,
 outputCirc := Circuit.var true (inr ()),
 nextStateCirc := Empty.elim
}

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

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

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

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

def neg : FSM Unit :=
  { α := Unit,
    i := by admit /- proof elided -/

def composeBinary
    (p : FSM Bool)
    {t₁ t₂ : Term}
    (q₁ : FSMTermSolution t₁)
    (q₂ : FSMTermSolution t₂) :
    FSM (Fin (max t₁.arity t₂.arity)) := composeBinaryAux p q₁.toFSM q₂.toFSM

def composeBinaryAux
    (p : FSM Bool)
    (q₁ : FSM (Fin a₁))
    (q₂ : FSM (Fin a₂)) :
    FSM (Fin (max a₁ a₂)) :=
  p.compose (Fin (max a₁ a₂))
    (λ b => Fin (cond b a₁ a₂))
    (λ b i => Fin.castLE (by admit /- proof elided -/
    ) i)
    (λ b => match b with
      | true => q₁
      | false => q₂)

structure FSMTermSolution (t : Term) extends FSM (Fin t.arity) where
  ( good : t.evalFin = toFSM.eval )

@[simp] def Term.evalFin (t : Term) (vars : Fin (arity t) → BitStream) : BitStream :=
  match t with
  | var n => vars (Fin.last n)
  | zero    => BitStream.zero
  | one     => BitStream.one
  | negOne  => BitStream.negOne
  | ofNat n => BitStream.ofNat n
  | and t₁ t₂ =>
      let x₁ := t₁.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      let x₂ := t₂.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      x₁ &&& x₂
  | or t₁ t₂ =>
      let x₁ := t₁.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      let x₂ := t₂.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      x₁ ||| x₂
  | xor t₁ t₂ =>
      let x₁ := t₁.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      let x₂ := t₂.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      x₁ ^^^ x₂
  | not t     => ~~~(t.evalFin vars)
  | add t₁ t₂ =>
      let x₁ := t₁.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      let x₂ := t₂.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      x₁ + x₂
  | sub t₁ t₂ =>
      let x₁ := t₁.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      let x₂ := t₂.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      x₁ - x₂
  | neg t       => -(Term.evalFin t vars)
 
 
  | shiftL t n  => BitStream.shiftLeft (Term.evalFin t vars) n

@[simp] def Predicate.evalFin (p : Predicate) (vars : Fin (arity p) → 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
| .binary .eq t₁ t₂ =>
    let x₁ := t₁.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
    ) i))
    let x₂ := t₂.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
    ) i))
    Predicate.evalEq x₁ x₂
| .binary .neq t₁ t₂  =>
    let x₁ := t₁.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
    ) i))
    let x₂ := t₂.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
    ) i))
    Predicate.evalNeq x₁ x₂
| .land p q =>
  
  
  let x₁ := p.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
  ) i))
  let x₂ := q.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
  ) i))
  Predicate.evalLand x₁ x₂
| .lor p q =>
  
  let x₁ := p.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
  ) i))
  let x₂ := q.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
  ) i))
  Predicate.evalLor x₁ x₂
| .binary .slt p q =>
  let x₁ := p.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
  ) i))
  let x₂ := q.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
  ) i))
  Predicate.evalSlt x₁ x₂
| .binary .sle p q =>
  let x₁ := p.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
  ) i))
  let x₂ := q.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
  ) i))
  Predicate.evalLor (Predicate.evalSlt x₁ x₂) (Predicate.evalEq x₁ x₂)
| .binary .ult p q =>
  let x₁ := p.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
  ) i))
  let x₂ := q.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
  ) i))
  (Predicate.evalUlt x₁ x₂)
| .binary .ule p q =>
  let x₁ := p.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
  ) i))
  let x₂ := q.evalFin (fun i => vars (Fin.castLE (by admit /- proof elided -/
  ) i))
  Predicate.evalLor (Predicate.evalUlt x₁ x₂) (Predicate.evalEq x₁ x₂)

def Predicate.evalUlt (t₁ t₂ : BitStream) : BitStream := (~~~ (t₁.borrow t₂)).concat true

def borrow (x y : BitStream) : BitStream :=
  fun n => (subAux x y n).2

def Predicate.evalLor (t₁ t₂ : BitStream) : BitStream := (t₁ &&& t₂)

def Predicate.evalSlt (t₁ t₂ : BitStream) : BitStream :=
    (((Predicate.evalUlt t₁ t₂)) ^^^ (Predicate.evalMsbEq t₁ t₂))

def Predicate.evalMsbEq (t₁ t₂ : BitStream) : BitStream :=
  (t₁ ^^^ t₂).concat false

def Predicate.evalLand (t₁ t₂ : BitStream) : BitStream := (t₁ ||| t₂)

def Predicate.evalNeq (t₁ t₂ : BitStream) : BitStream := (t₁.nxor t₂).concat true |>.scanAnd

def nxor (a b : BitStream) : BitStream := fun i => a i == b i

def scanAnd (s : BitStream) : BitStream := scanl true Bool.and s

abbrev scanl (init : Bool) (f : Bool → Bool → Bool) (s : BitStream) : BitStream :=
  fun n => match n with
    | 0 => f init (s 0)
    | n+1 => f (scanl init f s n) (s (n + 1))

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

def scanOr (s : BitStream) : BitStream := scanl false Bool.or s

inductive Predicate : Type where
 
| width (wp : WidthPredicate) (n : Nat) : Predicate
| binary (p : BinaryPredicate) (t₁ t₂ : Term)
| land  (p q : Predicate) : Predicate
| lor (p q : Predicate) : Predicate
deriving Repr, Inhabited, Lean.ToExpr

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

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

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

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

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

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

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

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

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

abbrev negOne : BitStream := fun _ => true

def shiftLeft (x : BitStream) (k : Nat) : BitStream :=
  fun i => if i < k then false else x (i - k)

def ofNat (x : Nat) : BitStream :=
  Nat.testBit x

abbrev one    : BitStream := (· == 0)

abbrev zero   : BitStream := fun _ => false

def ofNat (n : Nat)  : FSM (Fin 0) :=
  match hn : n with
  | 0 => FSM.zero

| n' + 1 =>
    let bit := n.testBit 0
    let m := n / 2
    have h : m < n := by admit /- proof elided -/

def zero : FSM (Fin 0) :=
  { α := Empty,
    initCarry := Empty.elim,
    nextStateCirc := Empty.elim,
    outputCirc := Circuit.fals
  }

def composeUnary
    (p : FSM Unit)
    {t : Term}
    (q : FSMTermSolution t) :
    FSM (Fin t.arity) := composeUnaryAux p q.toFSM

def one : FSM (Fin 0) :=
  { α := Unit,
    i := by admit /- proof elided -/

def var (n : ℕ) : FSM (Fin (n+1)) :=
  { α := Empty,
    i := by admit /- proof elided -/

def add : FSM Bool :=
  { α := Unit,
    initCarry := λ _ => false,
    nextStateCirc := fun () =>
      Circuit.var true (inr true) &&& Circuit.var true (inr false) |||
      Circuit.var true (inr true) &&& Circuit.var true (inl ()) |||
      Circuit.var true (inr false) &&& Circuit.var true (inl ()),
    outputCirc := Circuit.var true (inr true) ^^^
                  Circuit.var true (inr false) ^^^
                  Circuit.var true (inl ()),
  }

def negOne : FSM (Fin 0) :=
  { α := Empty,
    i := by admit /- proof elided -/

def sub : FSM Bool :=
  { α := Unit,
    initCarry := fun _ => false,
    outputCirc := Circuit.var true (inr true) ^^^
                  Circuit.var true (inr false) ^^^
                  Circuit.var true (inl ()),
    nextStateCirc := fun _ =>
      (Circuit.var false (inr true) &&& Circuit.var true (inr false)) |||
      (Circuit.var false (inr true) ^^^ Circuit.var true (inr false)) &&&
      (Circuit.var true (inl ()))
  }

def not : FSM Unit :=
  { α := Empty,
    initCarry := Empty.elim,
    nextStateCirc := Empty.elim,
    outputCirc := Circuit.var false (inr ())
  }

def add (x y : BitStream) : BitStream :=
  fun n => (addAux x y n).1

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

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

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

def liftMaxSuccSucc2 (n m : Nat) : Fin (m + 1) → Fin (max n m + 3) :=
  fun k => if _ : k = Fin.last m then max n m + 1 else k.castLE (by admit /- proof elided -/
  )

def liftMaxSuccSucc1 (n m : Nat) : Fin (n + 1) → Fin (max n m + 3) :=
  fun k => if _ : k = Fin.last n then (max n m).cast else k.castLE (by admit /- proof elided -/
  )

def liftLast3 n : Fin 3 → Fin (n + 3)
| 0 => n
| 1 => n + 1
| 2 => Fin.last (n + 2)

def CNFA.inter (m1 m2 : CNFA n) : CNFA n := product (fun b1 b2 => b1 && b2) m1 m2

def product (final? : Bool → Bool → Bool) (m₁ m₂ : CNFA n) : CNFA n :=
  worklistRun (m₁.m.states × m₂.m.states) final (product.inits m₁ m₂)
    (by admit /- proof elided -/
    ) f
where final (ss : m₁.m.states × m₂.m.states) := final? (ss.1 ∈ m₁.m.finals) (ss.2 ∈ m₂.m.finals)
      f (ss : m₁.m.states × m₂.m.states) :=
        let (s1, s2) := ss
        (FinEnum.toList (α := BitVec n)).foldl (init := Array.empty) fun as a =>
          product.prodArray' (λ s₁ s₂ ↦ (a, (s₁, s₂)))
            (fun s' => m₁.wf.trans_tgt_lt (s := s1) (a := a)) (fun s' => m₂.wf.trans_tgt_lt (s := s2) (a := a)) as

@[inline]
def product.prodArray' (a : Array γ) :=
  m₁.attachWith _ hm₁ |>.fold (init := a) fun is s1 =>
    m₂.attachWith _ hm₂ |>.fold (init := is) fun is s2 =>
      is.push (f s1 s2)

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

def product.inits (m₁ m₂ : CNFA n) :=
  product.prodArray Prod.mk @m₁.wf.initials_lt @m₂.wf.initials_lt

@[inline]
def product.prodArray := prodArray' f hm₁ hm₂ (Array.emptyWithCapacity <| m₁.size * m₂.size)

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

def HashSet.inter [BEq A] [Hashable A] (m1 m2 : Std.HashSet A) : Std.HashSet A :=
  m1.fold (init := ∅) fun mi x => if m2.contains x then mi.insert x else mi

structure NFA' (n : Nat) where
  σ : Type
  M : NFA (BitVec n) σ

structure BitVecs (n : Nat) where
  w : Nat
  bvs : List.Vector (BitVec w) n

def eval (x : arity → BitStream) : BitStream :=
  fun n => (p.nextBit (p.carry x n) (fun i => x i n)).2

def nextBit : p.State → (arity → Bool) → p.State × Bool :=
  fun carry inputBits =>
    let input := Sum.elim carry inputBits
    let newState : p.State  := fun (a : p.α) => (p.nextStateCirc a).eval input
    let outBit : Bool       := (p.outputCirc).eval input
    (newState, outBit)

abbrev State : Type := p.α → Bool

def carry (x : arity → BitStream) : ℕ → p.State
  | 0 => p.initCarry
  | n+1 => (p.nextBit (carry x n) (fun i => x i n)).1

def carryBV (x : ar → BitVec w) : p.State :=
  p.carry (fun ar => .ofBitVecSext (x ar)) w

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

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

def Term.language (t : Term) : Set (BitVecs (t.arity + 1)) :=
  { bvs : BitVecs (t.arity + 1) | t.evalFinBV (fun n => bvs.bvs.get n) = bvs.bvs.get t.arity }

@[simp]
def Formula.arity : Formula → Nat
| width _ _ => 0
| atom _ t1 t2 => max t1.arity t2.arity
| msbSet t => t.arity
| unop _ φ => φ.arity
| binop _ φ1 φ2 => max φ1.arity φ2.arity

@[simp] def Term.evalFinBV (t : Term) (vars : Fin (arity t) → BitVec w) : BitVec w :=
  match t with
  | .var n => vars (Fin.last n)
  | .zero    => BitVec.zero w
  | .one     => 1
  | .negOne  => -1
  | .ofNat n => BitVec.ofNat _ n
  | .and t₁ t₂ =>
      let x₁ := t₁.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      let x₂ := t₂.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      x₁ &&& x₂
  | .or t₁ t₂ =>
      let x₁ := t₁.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      let x₂ := t₂.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      x₁ ||| x₂
  | .xor t₁ t₂ =>
      let x₁ := t₁.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      let x₂ := t₂.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      x₁ ^^^ x₂
  | .not t     => ~~~(t.evalFinBV vars)
  
  | .add t₁ t₂ =>
      let x₁ := t₁.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      let x₂ := t₂.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      x₁ + x₂
  | .sub t₁ t₂ =>
      let x₁ := t₁.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      let x₂ := t₂.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      x₁ - x₂
  | .neg t       => -(t.evalFinBV vars)
  | .shiftL a n => (a.evalFinBV vars) <<< n

def enc (bvs : BitVecs n) : BitVecs' n :=
  (List.finRange bvs.w).map (fun i =>
    BitVec.ofFn (fun (k : Fin n) => (bvs.bvs.get k)[i]))

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

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

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

def worklistRun_spec : (worklistRun S final inits hinits f |>.Sim $ nfa' inits final f) :=
  worklistRun'_spec inits final f

def nfa' : NFA' n :=
  { σ := _, M := nfa inits final f }

def nfa : NFA A S where
  start := { sa | sa ∈ inits }
  accept := { sa | final sa }
  step sa a := { sa' | (a, sa') ∈ f sa }

def worklistRun'_spec :
    (worklistRun' A S final inits hinits f |>.Sim $ nfa inits final f) :=

structure StInv (m : RawCNFA A) (map : Std.HashMap S State) where
  wf : m.WF
  map_states : ∀ (sa : S) s, map[sa]? = some s → s ∈ m.states
  map_surj : ∀ s : m.states, ∃ (sa : S), map[sa]? = some s.val
  map_inj : ∀ {s} {sa sa' : S}, map[sa]? = some s → map[sa']? = some s → sa = sa'

def worklist.St.D (st : worklist.St A S) : Set S := st.visited

def worklist.St.visited (st : worklist.St A S) : Set S := { s : S | s ∈ st.map ∧ s ∉ st.worklist }

def worklistGo_spec {st : worklist.St A S} (inv : StInv A S st.m st.map) :
    st.sim inits final f ∅ →
    (worklistRun'.go A S final f st |>.Sim $ nfa inits final f) :=

def worklist.St.rel (st : worklist.St A S) : SetRel State S := {(s, sa) | st.map[sa]? = some s }

def processOneElem_mot (s : State) (sa : S) (n : ℕ) (st : worklist.St A S) : Prop :=
  st.map[sa]? = some s ∧
  sa ∈ st.visited ∧
  StInv A S st.m st.map ∧
  st.sim inits final f  {(sa1, a, sa') | sa1 = sa ∧ ∃ k ≥ n, (f sa)[k]? = some (a, sa') }

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

def RawCNFA.Sim (m : RawCNFA A) (A : NFA A S) := ∃ R, RawCNFA.Simul m A R ⊤ ∅

structure RawCNFA.Simul (m : RawCNFA A) (M : NFA A Q) (R : SetRel State Q) (D : Set Q) (T : Set (Q × A × Q)) where
  accept {s q} : s ~[R] q → (s ∈ m.finals ↔ q ∈ M.accept)
  initial₁ {s} : s ∈ m.initials → ∃ q ∈ M.start, s ~[R] q
  initial₂ {q} : q ∈ M.start → ∃ s ∈ m.initials, s ~[R] q
  trans_match₁ {s s' a q} : s ~[R] q → s' ∈ m.tr s a → ∃ q', q' ∈ M.step q a ∧ s' ~[R] q'
  trans_match₂ {s a q q'} : s ~[R] q → q' ∈ M.step q a → q ∈ D → (q, a, q') ∉ T → ∃ s', s' ∈ m.tr s a ∧ s' ~[R] q'

structure RawCNFA.SimulFun (m : RawCNFA A) (M : NFA A Q) (f : m.states ≃ Q)  where
  accept {q} : ((f.invFun q).val ∈ m.finals ↔ q ∈ M.accept)
  initial {q} : q ∈ M.start ↔ (f.invFun q).val ∈ m.initials
  trans_match {a q q'} : q' ∈ M.step q a ↔ (f.invFun q').val ∈ m.tr (f.invFun q) a

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

abbrev R := (ZMod q)[X] ⧸ (Ideal.span {f q n})

def CNFA.Sim (m : CNFA n) (M : NFA' n) :=
  m.m.Sim M.M

def CNFA.bv_recognizes (m : CNFA n) (L : Set (BitVecs n)) :=
  ∃ L', m.recognizes L' ∧ L = dec '' L'

def RawCNFA.recognizes (m : RawCNFA A) (L : Language A) :=
  ∃ (σ : Type) (M : NFA A σ), m.Sim M ∧ M.accepts = L

def CNFA.recognizes (m : CNFA n) (L : Language (BitVec n)) :=
  ∃ (M : NFA' n), m.Sim M ∧ M.M.accepts = L

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

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

def CNFA.minimize (m : CNFA n) : CNFA n :=
  let mᵣ := m.reverse.determinize
  mᵣ.reverse.determinize

def CNFA.determinize (m : CNFA n) : CNFA n :=
  worklistRun (BitVec m.m.stateMax)
    (fun ss => ss.any fun n b => b == true && n ∈ m.m.finals)
    (determinize.inits m)
    (by admit /- proof elided -/
    )
    f
where
  f := fun (ss : BitVec m.m.stateMax) =>
        (FinEnum.toList (BitVec n)).foldl (init := Array.empty) fun ts a =>
          let ss' := m.m.transSetBV ss a
          ts.push (a, ss')

def CNFA.determinize.inits (m : CNFA n) : Array (BitVec m.m.stateMax) :=
  #[BitVec.ofFn (fun n => n ∈ m.m.initials)]

def CNFA.reverse (m : CNFA n) : CNFA n :=
  ⟨m.m.reverse, RawCNFA.reverse_spec m.wf |>.1⟩

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

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

def CNFA.toNFA (m : CNFA n) : NFA (BitVec n) m.m.states where
  start := { s | s.val ∈ m.m.initials }
  accept := { s | s.val ∈ m.m.finals }
  step s₁ a := { s₂ | s₂.val ∈ m.m.tr s₁.val a }

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

def reverse (M : NFA' n) : NFA' n where
  σ := _
  M := M.M.reverse

def CNFA.determinize_spec (m : CNFA n)
  {M : NFA' n} (hsim : m.Sim M) :
    m.determinize.Sim M.determinize :=

private def bv_to_set (bv : BitVec w) : Set State :=
  { s | bv.getLsbD s }

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

@[inline]
def RawCNFA.lift (m₁: RawCNFA (BitVec n1)) (f : Fin n1 → Fin n2) : RawCNFA (BitVec n2) :=
  let trans := (List.range m₁.stateMax).foldl (init := ∅) fun m2 s => processState m2 s
  { m₁ with trans }
where

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

def BitVecs.transport (f : Fin n → Fin m) (bvs : BitVecs m) : BitVecs n :=
  { w := bvs.w, bvs := bvs.bvs.transport f }

def BitVec.transport (f : Fin n2 → Fin n1) (bv : BitVec n1) : BitVec n2 :=
  BitVec.ofFn fun i => bv.getLsbD (f i)

def List.Vector.transport (v : Vector α m) (f : Fin n → Fin m) : Vector α n :=
  Vector.ofFn fun i => v.get (f i)

def BitVecs'.transport (f : Fin n → Fin m) (bvs' : BitVecs' m): BitVecs' n :=
  bvs'.map fun bv => bv.transport f

@[inline]
def RawCNFA.proj (m1: RawCNFA (BitVec n1)) (f : Fin n2 → Fin n1) : RawCNFA (BitVec n2) :=
  let trans := m1.trans.keysArray.foldl (init := Std.HashMap.emptyWithCapacity) process
  { m1 with trans }
where

def CNFA.proj_spec (m : CNFA n2) (f : Fin n1 → Fin n2) {M : NFA' n2} :
    m.Sim M → (m.proj f |>.Sim (M.proj f)) :=

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

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

def udiv_i80_before := [llvm|
{
^0(%arg2 : i80):
  %0 = llvm.mlir.constant(2 : i80) : i80
  %1 = llvm.mlir.constant(100 : i80) : i80
  %2 = llvm.lshr %arg2, %0 : i80
  %3 = llvm.udiv %2, %1 : i80
  "llvm.return"(%3) : (i80) -> ()
}
]

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

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

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

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

def zext_or_masked_bit_test_before := [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 : 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 factorize2_after := [llvm|
{
^0(%arg8 : i32):
  "llvm.return"(%arg8) : (i32) -> ()
}
]

def bb0IcomConcrete := [llvm()|
{
  ^bb0(%arg0: i32):
    %0 = llvm.mlir.constant(1) : i32
    %1 = llvm.mlir.constant(31) : i32
    %2 = llvm.ashr %arg0, %1 : i32
    %3 = llvm.and %2, %0 : i32
    %4 = llvm.add %3, %2 : i32
    llvm.return %4 : i32
  }]

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

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

def sext_ule_sext_before := [llvm|
{
^0(%arg119 : i1, %arg120 : i8):
  %0 = llvm.mul %arg120, %arg120 : i8
  %1 = llvm.sext %arg119 : i1 to i16
  %2 = llvm.sext %0 : i8 to i16
  %3 = llvm.icmp "ule" %2, %1 : i16
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def NFA.autWidth_correct : (autWidth wp n).correct (autWidthSA n) (autWidthLang wp n) :=

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

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

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

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

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

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 mul_unkV_oddC_sge_after := [llvm|
{
^0(%arg22 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.mul %arg22, %0 : i8
  %3 = llvm.icmp "sgt" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

def lshr_lshr_pow2_const_negative_overflow_after := [llvm|
{
^0(%arg61 : i16):
  %0 = llvm.mlir.constant(0 : i16) : i16
  "llvm.return"(%0) : (i16) -> ()
}
]

def not_cmp_fold_uge : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64, %y: i64):
      %0 = llvm.icmp.uge %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.ult %x, %y : i64
      llvm.return %0 : i1
  }]

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

def sel_false_val_is_a_masked_lshr_of_true_val1_before := [llvm|
{
^0(%arg6 : i32, %arg7 : 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 %arg6, %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 %arg7, %5 : i64
  %8 = "llvm.select"(%6, %arg7, %7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%8) : (i64) -> ()
}
]

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

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

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

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

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

instance : AST.TransformReturn Comb 0 := { mkReturn }

def or_logic_or_logic_and_8_before := [llvm|
{
^0(%arg27 : i1, %arg28 : i1, %arg29 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.or %arg28, %arg27 : i1
  %3 = "llvm.select"(%arg29, %0, %arg27) <{"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 band_lor_left1_after := [llvm|
{
^0(%arg82 : i1, %arg83 : i1):
  "llvm.return"(%arg82) : (i1) -> ()
}
]

List.foldlRecOn in Init.Data.List.Lemmas

def Region.substitute (σ : Substitution) : Region Op T → Region Op T
  | ⟨entry, blocks⟩ => ⟨entry, subBlocks blocks⟩
  where subBlocks : List (BasicBlock Op T) → List (BasicBlock Op T)
    | []    => []
    | b::bs => b.substitute σ :: subBlocks bs

def HVector.replicateToList {α : Type} {f : α → Type} {a : α} :
    {n : Nat} → HVector f (List.replicate n a) → List (f a)
  | 0, _ => []
  | n + 1, HVector.cons x xs => x :: replicateToList xs


example (op : Comb.Op) : DialectSignature.effectKind (d := DCxComb) (.comb op) = .pure := rfl



example (op : Comb.Op) : DialectSignature.regSig (d := DCxComb) (.comb op) = [] := rfl

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

def lowmask_add_zext_before := [llvm|
{
^0(%arg235 : i8, %arg236 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.zext %arg235 : i8 to i32
  %2 = llvm.add %1, %arg236 : i32
  %3 = llvm.and %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

private def mkAxiomLikeMessage (kind : String) (id : Name) (levelParams : List Name) (type : Expr) (safety : DefinitionSafety) : MetaM MessageData := do
  mkHeader kind id levelParams type safety

def testi128i128_before := [llvm|
{
^0(%arg7 : i128):
  %0 = llvm.mlir.constant(127 : i128) : i128
  %1 = llvm.mlir.constant(27 : i128) : i128
  %2 = llvm.ashr %arg7, %0 : i128
  %3 = llvm.xor %2, %1 : i128
  "llvm.return"(%3) : (i128) -> ()
}
]

def no_shift_xor_multiuse_cmp_or_after := [llvm|
{
^0(%arg48 : i32, %arg49 : i32, %arg50 : i32, %arg51 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg48, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  %4 = llvm.or %arg49, %0 : i32
  %5 = "llvm.select"(%3, %4, %arg49) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %6 = "llvm.select"(%3, %arg51, %arg50) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = llvm.mul %5, %6 : i32
  %8 = llvm.mul %7, %4 : i32
  "llvm.return"(%8) : (i32) -> ()
}
]

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

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

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

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

instance : HydrableChangePredWidth FpPredicate where
  changePredWidth := changeFpPredWidth

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

instance : AndOp (Circuit α) := ⟨Circuit.simplifyAnd⟩

def GeneralizerStateM.liftTermElabM
  {parsedExpr : Type}  {genPred : Type}
  [HydrableInstances genPred]
  (m : TermElabM α) : GeneralizerStateM parsedExpr genPred α := do
  let v ← m
  return v

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

def t2_ult_sgt_128_before := [llvm|
{
^0(%arg72 : i32, %arg73 : i32, %arg74 : i32):
  %0 = llvm.mlir.constant(127 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.mlir.constant(144 : i32) : i32
  %3 = llvm.icmp "sgt" %arg72, %0 : i32
  %4 = "llvm.select"(%3, %arg74, %arg73) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %5 = llvm.add %arg72, %1 : i32
  %6 = llvm.icmp "ult" %5, %2 : i32
  %7 = "llvm.select"(%6, %arg72, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def xor_notand_to_or_not4_before := [llvm|
{
^0(%arg9 : i3, %arg10 : i3, %arg11 : i3):
  %0 = llvm.mlir.constant(-1 : i3) : i3
  %1 = llvm.or %arg10, %arg11 : i3
  %2 = llvm.and %arg11, %arg9 : i3
  %3 = llvm.xor %2, %0 : i3
  %4 = llvm.xor %3, %1 : i3
  "llvm.return"(%4) : (i3) -> ()
}
]

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

def llvm_const_lower_riscv_li48 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM48, rhs:= liRiscv48,
   correct := by admit /- proof elided -/

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

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

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

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

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

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

def and_zext_commuted_after := [llvm|
{
^0(%arg38 : i32, %arg39 : i1):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg38, %0 : i32
  %3 = "llvm.select"(%arg39, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def add_negative_high_bound_accept_test: LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := add_negative_high_bound_accept_llvm
  rhs := add_negative_high_bound_accept_riscv

def t8_twoshifts3_before := [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 : i32
  %4 = llvm.and %3, %2 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

PartialOrder in Mathlib.Order.Defs.PartialOrder

instance instPrint : DialectPrint Simple where
  printOpName
  | .add => "add"
  | .const _ => "const"
  printTy
  | .int => "i32"
  printAttributes
  | .const val => s!"\{value = {val} : i32}"
  | _ => ""
  dialectName := "simple"
  printReturn _ := "return"

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

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

def fsmZext (nFsm wnewfsm : FSM (StateSpace wcard tcard bcard ncard icard pcard))
    : FSM (StateSpace wcard tcard bcard ncard icard pcard) :=
  (nFsm) &&& (wnewfsm)

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

def test16_before := [llvm|
{
^0(%arg22 : i84):
  %0 = llvm.mlir.constant(4 : i84) : i84
  %1 = llvm.mlir.constant(1 : i84) : i84
  %2 = llvm.mlir.constant(0 : i84) : i84
  %3 = llvm.ashr %arg22, %0 : i84
  %4 = llvm.and %3, %1 : i84
  %5 = llvm.icmp "ne" %4, %2 : i84
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

def test_sub_nuw__all_are_safe_before := [llvm|
{
^0(%arg30 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.mlir.constant(6 : i32) : i32
  %2 = llvm.mlir.constant(-254 : i32) : i32
  %3 = llvm.mlir.constant(-260 : i32) : i32
  %4 = llvm.and %arg30, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.sub %2, %4 overflow<nuw> : i32
  %7 = "llvm.select"(%5, %3, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

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

def uge_swap_or_max_before := [llvm|
{
^0(%arg166 : i8, %arg167 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.icmp "ule" %arg167, %arg166 : i8
  %2 = llvm.icmp "eq" %arg166, %0 : i8
  %3 = llvm.or %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def test45_after := [llvm|
{
^0(%arg201 : i32, %arg202 : i32):
  %0 = llvm.and %arg201, %arg202 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

Lean.PrettyPrinter.Parenthesizer in Lean.PrettyPrinter.Parenthesizer

@[inline]
def CNFA.autMsbSet : CNFA 1 :=
  ⟨RawCNFA.autMsbSet, RawCNFA.autMsbSet_wf⟩

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

partial def collectTerm (state : CollectState) (e : Expr) :
     SolverM (MultiWidth.Nondep.Term × CollectState) := do
  match_expr e with
  | BitVec.ofBool bExpr =>
      let (b, state) ← collectBoolTerm state bExpr
      return (.bvOfBool b, state)
  | BitVec.ofNat wExpr nExpr =>
    let (w, state) ← collectWidthExpr state wExpr
    if let some n ← getNatValue? nExpr then
      return (.ofNat w n, state)
    else
      mkAtom
  | HAdd.hAdd _bv _bv _bv _inst a b =>
    match_expr _bv with
    | BitVec w =>
      let (w, state) ← collectWidthExpr state w
      let (ta, state) ← collectTerm state a
      let (tb, state) ← collectTerm state b
      return (.add w ta tb, state)
    | _ => mkAtom
  | BitVec.zeroExtend _w v x =>
      let (v, state) ← collectWidthExpr state v
      let (x, state) ← collectTerm state x
      return (.zext x v, state)
  | BitVec.setWidth _w v x =>
      let (v, state) ← collectWidthExpr state v
      let (x, state) ← collectTerm state x
      return (.setWidth x v, state)
  | BitVec.signExtend _w v x =>
      let (v, state) ← collectWidthExpr state v
      let (x, state) ← collectTerm state x
      return (.sext x v, state)
  | HXor.hXor _bv _bv _bv _inst a b =>
    match_expr _bv with
    | BitVec w =>
      let (w, state) ← collectWidthExpr state w
      let (ta, state) ← collectTerm state a
      let (tb, state) ← collectTerm state b
      return (.bxor w ta tb, state)
    | _ => mkAtom
  | HAnd.hAnd _bv _bv _bv _inst a b =>
    match_expr _bv with
    | BitVec w =>
      let (w, state) ← collectWidthExpr state w
      let (ta, state) ← collectTerm state a
      let (tb, state) ← collectTerm state b
      return (.band w ta tb, state)
    | _ => mkAtom
  | HOr.hOr _bv _bv _bv _inst a b =>
    match_expr _bv with
    | BitVec w =>
      let (w, state) ← collectWidthExpr state w
      let (ta, state) ← collectTerm state a
      let (tb, state) ← collectTerm state b
      return (.bor w ta tb, state)
    | _ => mkAtom
  | Complement.complement bv _inst a =>
    match_expr bv with
    | BitVec w =>
      let (w, state) ← collectWidthExpr state w
      let (ta, state) ← collectTerm state a
      return (.bnot w ta, state)
    | _ => mkAtom
  | HShiftLeft.hShiftLeft _bv _nat _bv _inst a n =>
    match_expr _bv with
    | BitVec w =>
      match_expr _nat with
      | Nat =>
        let (w, state) ← collectWidthExpr state w
        let (ta, state) ← collectTerm state a
        if let some nn ← getNatValue? n then
          return (.shiftl w ta nn, state)
        else
          mkAtom
      | _ => mkAtom
    | _ => mkAtom
  | _ => mkAtom
  where
    mkAtom := do
      let (t, state) ← collectBVAtom state e
      return (t, state)

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

instance {cmp} : Fintype (NFA'.autSignedCmp cmp).σ :=

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

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

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

def lshr_or_or_fail_after := [llvm|
{
^0(%arg150 : i8, %arg151 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.mlir.constant(-58 : i8) : i8
  %2 = llvm.or %arg151, %arg150 : i8
  %3 = llvm.lshr %2, %0 : i8
  %4 = llvm.or %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def exampleSndVal := [DCxComb_com| {
  ^entry(%0: !ValueTokenStream_8):
    %src = "DCxComb.sndVal" (%0) : (!ValueTokenStream_8) -> (!TokenStream)
    "return" (%src) : (!TokenStream) -> ()
  }]

def alive_AddSub_1309_src :=
[sllvm| {
^bb0(%a : i64, %b : i64):
  %v1 = llvm.and %a, %b : i64
  %v2 = llvm.or %a, %b : i64
  %v3 = llvm.add %v1, %v2 : i64
  llvm.return %v3 : i64
}]

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

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

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

def test7_before := [llvm|
{
^0(%arg81 : i64):
  %0 = llvm.mlir.constant(32 : i128) : i128
  %1 = llvm.zext %arg81 : i64 to i128
  %2 = llvm.lshr %1, %0 : i128
  %3 = llvm.trunc %2 : i128 to i92
  "llvm.return"(%3) : (i92) -> ()
}
]

def test_srem_canonicalize_op0_after := [llvm|
{
^0(%arg8 : i32, %arg9 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.srem %arg8, %arg9 : i32
  %2 = llvm.sub %0, %1 overflow<nsw> : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def test6_before := [llvm|
{
^0(%arg17 : i57, %arg18 : i57):
  %0 = llvm.and %arg17, %arg18 : i57
  %1 = llvm.sub %arg17, %0 : i57
  "llvm.return"(%1) : (i57) -> ()
}
]

def icmp_sgt_riscv_eq_icmp_slt_llvm_64 : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] :=
  {lhs:= icmp_sgt_llvm_64, rhs:= icmp_sgt_riscv_64}

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

def urem_i32_c_multiuse_after := [llvm|
{
^0(%arg8 : i8):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.zext %arg8 : i8 to i32
  %2 = llvm.urem %1, %0 : i32
  %3 = llvm.add %2, %1 overflow<nsw,nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def main : IO Unit := do
  generateRawSemantics
  generateTestSemantics

def widget_after := [llvm|
{
^0(%arg0 : i32, %arg1 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(20 : i32) : i32
  %2 = llvm.icmp "ne" %arg0, %0 : i32
  %3 = llvm.zext %2 : i1 to i32
  %4 = llvm.shl %1, %3 overflow<nsw,nuw> : i32
  %5 = llvm.zext %2 : i1 to i32
  %6 = llvm.or disjoint %4, %5 : i32
  %7 = llvm.zext %2 : i1 to i32
  %8 = llvm.shl %6, %7 overflow<nsw,nuw> : i32
  "llvm.return"(%8) : (i32) -> ()
}
]

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

structure BVExprWrapper where
  width : Nat
  bvExpr: GenBVExpr width

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

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

RV64.sraw in RISCV.Instructions

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

Lean.PrettyPrinter.Formatter in Lean.PrettyPrinter.Formatter

def eq_21_comm_eq2_before := [llvm|
{
^0(%arg118 : i32, %arg119 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.lshr %arg118, %0 : i32
  %3 = llvm.trunc %2 : i32 to i8
  %4 = llvm.lshr %arg118, %1 : i32
  %5 = llvm.trunc %4 : i32 to i8
  %6 = llvm.lshr %arg119, %0 : i32
  %7 = llvm.trunc %6 : i32 to i8
  %8 = llvm.lshr %arg119, %1 : i32
  %9 = llvm.trunc %8 : i32 to i8
  %10 = llvm.icmp "eq" %7, %3 : i8
  %11 = llvm.icmp "eq" %5, %9 : i8
  %12 = llvm.and %11, %10 : i1
  "llvm.return"(%12) : (i1) -> ()
}
]

def add_mask : Op 0 := [mlir_op|
  "module"() ( {
  "llvm.func"() ( {
  ^bb0(%arg0: i32):
    %0 = llvm.mlir.constant(8) : i32
    %1 = llvm.mlir.constant(31) : i32
    %2 = llvm.ashr %arg0, %1 : i32
    %3 = llvm.and %2, %0 : i32
    %4 = llvm.add %3, %2 : i32
    llvm.return %4 : i32
  })  : () -> ()
  "llvm.func"() ( {
  ^bb0(%arg0: i32):
    %0 = llvm.mlir.constant(8) : i32
    %1 = llvm.mlir.constant(31) : i32
    %2 = llvm.ashr %arg0, %1 : i32
    %3 = llvm.and %2, %0 : i32
    %4 = llvm.add %2, %3 : i32
    llvm.return %4 : i32
  }) : () -> ()
}) : () -> ()
]

def shl_C1_add_A_C2_i32_after := [llvm|
{
^0(%arg78 : i16):
  %0 = llvm.mlir.constant(192 : i32) : i32
  %1 = llvm.zext nneg %arg78 : i16 to i32
  %2 = llvm.shl %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

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

def narrow_zext_sub_before := [llvm|
{
^0(%arg38 : i16, %arg39 : i32):
  %0 = llvm.zext %arg38 : i16 to i32
  %1 = llvm.sub %0, %arg39 : i32
  %2 = llvm.trunc %1 : i32 to i16
  "llvm.return"(%2) : (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 ripple_nsw5_before := [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 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

def test_and_ne_a_b_commuted_before := [llvm|
{
^0(%arg27 : i1, %arg28 : i8, %arg29 : i8):
  %0 = llvm.icmp "ne" %arg28, %arg29 : i8
  %1 = llvm.and %arg27, %0 : i1
  %2 = "llvm.select"(%1, %arg29, %arg28) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

def lt_signed_to_small_signed_before := [llvm|
{
^0(%arg49 : i8):
  %0 = llvm.mlir.constant(17 : i32) : i32
  %1 = llvm.sext %arg49 : i8 to i32
  %2 = llvm.icmp "slt" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

def n2_before := [llvm|
{
^0(%arg39 : i32, %arg40 : i32, %arg41 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "eq" %arg39, %arg40 : i32
  %3 = "llvm.select"(%arg41, %2, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = llvm.xor %3, %1 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

RV64.rol in RISCV.Instructions

instance : CoeOut (Var (Γ.dropUntil v) ty) (Var Γ ty) where
  coe v := dropUntilDiff.toHom v

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

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

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

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

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

def test_lshr__exact_is_unsafe_before := [llvm|
{
^0(%arg56 : i32, %arg57 : i64):
  %0 = llvm.mlir.constant(63 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.and %arg56, %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 %arg57, %5 : i64
  %8 = "llvm.select"(%6, %arg57, %7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%8) : (i64) -> ()
}
]

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

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

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

def alive_AddSub_1043_src  :=
[sllvm| {
^bb0(%C1 : i64, %Z : i64, %RHS : i64):
  %v1 = llvm.and %Z, %C1 : i64
  %v2 = llvm.xor %v1, %C1 : i64
  %v3 = llvm.mlir.constant 1 : i64
  %v4 = llvm.add %v2, %v3 : i64
  %v5 = llvm.add %v4, %RHS : i64
  llvm.return %v5 : 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) -> ()
}
]

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

def or_and_not_not_commute7_after := [llvm|
{
^0(%arg404 : i32, %arg405 : i32, %arg406 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg406, %arg405 : i32
  %2 = llvm.or %1, %arg404 : i32
  %3 = llvm.xor %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

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

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

def xor_andn_commute2_before := [llvm|
{
^0(%arg70 : i33, %arg71 : i33):
  %0 = llvm.mlir.constant(42 : i33) : i33
  %1 = llvm.mlir.constant(-1 : i33) : i33
  %2 = llvm.udiv %0, %arg71 : i33
  %3 = llvm.xor %arg70, %1 : i33
  %4 = llvm.and %2, %3 : i33
  %5 = llvm.xor %4, %arg70 : i33
  "llvm.return"(%5) : (i33) -> ()
}
]

def getAttr? : String → Option (AttrValue φ) :=
  op.attrs.getAttr

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

def test2_gen (x y : BitVec w) : (~~~(x ^^^ y)) = ((x &&& y) + ~~~(x ||| y)) :=

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

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

def or_logic_or_logic_and_1_before := [llvm|
{
^0(%arg48 : i1, %arg49 : i1, %arg50 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.or %arg48, %arg49 : i1
  %3 = "llvm.select"(%arg48, %0, %arg50) <{"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 test19_commutative0_before := [llvm|
{
^0(%arg74 : i32, %arg75 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.shl %0, %arg74 : i32
  %2 = llvm.shl %0, %arg75 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.add %3, %1 : i32
  %5 = llvm.urem %arg75, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def 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 shift_xor_multiuse_and_after := [llvm|
{
^0(%arg124 : i32, %arg125 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(-2049 : i32) : i32
  %3 = llvm.and %arg124, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.and %arg125, %2 : i32
  %6 = "llvm.select"(%4, %5, %arg125) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = llvm.mul %6, %5 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

def not_and_and_or_not_or_or_commute1_or_after := [llvm|
{
^0(%arg250 : i32, %arg251 : i32, %arg252 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg252, %arg251 : i32
  %2 = llvm.or %1, %arg250 : i32
  %3 = llvm.xor %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

def ashr_can_be_lshr_2_before := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(4278190080) : i64
  %1 = llvm.mlir.constant(34) : i64
  %2 = llvm.mlir.constant(32) : i64
  %3 = llvm.zext %arg0 : i32 to i64
  %4 = llvm.or %3, %0 : i64
  %5 = llvm.shl %4, %1 : i64
  %6 = llvm.ashr exact %5, %2 : i64
  %7 = llvm.trunc %6 overflow<nsw> : i64 to i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def liftTy : MLIR2Comb.Ty → MLIR2Handshake.Ty
| .bitvec w => .stream (.bitvec w)

def udiv1_before := [llvm|
{
^0(%arg32 : i32, %arg33 : i32):
  %0 = llvm.udiv exact %arg32, %arg33 : i32
  %1 = llvm.mul %0, %arg33 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

@[simp_denote]
def not {Γ : Ctxt _} (w : ℕ) (l : Nat)
    (lp : (Γ[l]? = some (InstCombine.MTy.bitvec (ConcreteOrMVar.concrete w)))
      := by admit /- proof elided -/
      ):
    Expr InstCombine.LLVM Γ .pure (LLVM.Ty.bitvec w) :=
  Expr.mk
    (op := InstCombine.MOp.not w)
    (eff_le := by admit /- proof elided -/
    )
    (ty_eq := rfl)
    (args := .cons ⟨l, lp⟩ .nil)
    (regArgs := .nil)

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

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

instance : HasUB Option where
  throwUB := none

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

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

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

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

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

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

def dont_narrow_zext_ashr_keep_trunc_after := [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.lshr %3, %0 : i16
  %5 = llvm.trunc %4 : i16 to i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def udiv_illegal_type_after := [llvm|
{
^0(%arg23 : i9, %arg24 : i9):
  %0 = llvm.udiv %arg23, %arg24 : i9
  %1 = llvm.zext %0 : i9 to i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

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

def masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_6_before := [llvm|
{
^0(%arg14 : 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.and %arg14, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.and %arg14, %2 : i32
  %7 = llvm.icmp "ne" %6, %3 : i32
  %8 = llvm.or %7, %5 : i1
  "llvm.return"(%8) : (i1) -> ()
}
]

def rewritePeephole (fuel : ℕ)
    (pr : PeepholeRewrite d Γ t) (target : Com d Γ₂ eff t₂) : (Com d Γ₂ eff t₂) :=
  rewritePeephole_go fuel pr 0 target

def yw : WidthExpr 1 := WidthExpr.var ⟨0, by admit /- proof elided -/
⟩

instance : TyDenote Ty where toType := Ty.toType

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

def zext_masked_bit_zero_to_larger_bitwidth_after := [llvm|
{
^0(%arg39 : i32, %arg40 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.xor %arg39, %0 : i32
  %3 = llvm.lshr %2, %arg40 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.zext nneg %4 : i32 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

def match_selects : List (Σ Γ, LLVMPeepholeRewriteRefine 64  Γ) :=
  [⟨_, select_1_0⟩,
  ⟨_, select_neg1_0⟩,
  ⟨_, select_0_1⟩,
  ⟨_, select_0_neg1⟩,
  ⟨_, select_cond_f⟩,
  ⟨_, select_1_f⟩,
  ⟨_, select_t_cond⟩,
  ⟨_, select_t_0⟩,
  ⟨_, select_t_1⟩,
  ⟨_, select_0_f⟩]

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

abbrev GenM := StateT State TermElabM

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

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

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

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

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

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

def test25_before := [llvm|
{
^0(%arg271 : i32):
  %0 = llvm.mlir.constant(50 : i32) : i32
  %1 = llvm.mlir.constant(100 : i32) : i32
  %2 = llvm.icmp "sge" %arg271, %0 : i32
  %3 = llvm.icmp "slt" %arg271, %1 : i32
  %4 = llvm.and %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

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

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

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

inductive HVector {α : Type*} (f : α → Type*) : List α → Type _
  | nil : HVector f []
  | cons {a : α} : (f a) → HVector f as → HVector f (a :: as)

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

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

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

def or_and_not_not_commute3_after := [llvm|
{
^0(%arg416 : i32, %arg417 : i32, %arg418 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg418, %arg417 : i32
  %2 = llvm.or %1, %arg416 : i32
  %3 = llvm.xor %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

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

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

def src_x_and_nmask_slt_after := [llvm|
{
^0(%arg19 : i8, %arg20 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.shl %0, %arg20 overflow<nsw> : i8
  %2 = llvm.icmp "sgt" %1, %arg19 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

@[simp_denote]
def transformExprLLVM (e : Expr (InstCombine.MetaLLVM 0) (ctxtTransformToLLVM Γ) eff ty) :
  MLIR.AST.ReaderM (LLVMPlusRiscV) (Expr LLVMPlusRiscV Γ eff (.llvm <$> ty)) :=
    match e with
    | Expr.mk op1 ty_eq1 eff_le1 args1 regArgs1 => do
        let args' : HVector (Ctxt.Var Γ) (.llvm <$> DialectSignature.sig op1) ←
          args1.mapM' fun t v => do
            match h : Γ[v.val]? with
            | some ty' => do
              match hty : ty' with
              | .riscv _ =>  
                throw <| .generic s!"INTERNAL ERROR: This case is impossible, LLVM expression is pointing to RISCV variable.
                Should haven been caught by the LLVM parser."
              | .llvm originalLLVMTy =>
                if hty' : originalLLVMTy = t then
                  return ⟨v.val, by admit /- proof elided -/
                  ⟩
                else
                  throw <|.generic s!"INTERNAL ERROR: This case is impossible, LLVM expression is pointing to an incorrect bitwidth LLVM argument."
            | none =>
              
              throw <| .generic s!"INTERNAL ERROR: This case is impossible, as 'ctxtTransformToLLVM' is length-preserving."
        return Expr.mk
          (op := Op.llvm op1)
          (eff_le := eff_le1)
          (ty_eq := by admit /- proof elided -/
          )
          (args := args')
          (regArgs := HVector.nil)

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

def llvm_sext_lower_riscv_i1_to_64 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 1)] :=
  {lhs:= sext_llvm_i1_to_64, rhs:= sext_riscv_i1_to_64}

private def opRgnAttr0 : Op φ := [mlir_op|
 "module"() ({
  ^entry:
   "func"() ({
     ^bb0(%arg0:i32, %arg1:i32):
      %zero = "std.addi"(%arg0 , %arg1) : (i32, i16) -> (i64)
      "std.return"(%zero) : (i32) -> ()
    }){sym_name = "add"} : () -> ()
   "module_terminator"() : () -> ()
 }) : () -> ()
]

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

EquivBEq in Init.Data.BEq

def src_is_mask_lshr_before := [llvm|
{
^0(%arg96 : i8, %arg97 : i8, %arg98 : i8, %arg99 : i1):
  %0 = llvm.mlir.constant(123 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.mlir.constant(15 : i8) : i8
  %3 = llvm.xor %arg96, %0 : i8
  %4 = llvm.add %arg97, %1 : i8
  %5 = llvm.xor %arg97, %4 : i8
  %6 = "llvm.select"(%arg99, %5, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %7 = llvm.lshr %6, %arg98 : i8
  %8 = llvm.and %7, %3 : i8
  %9 = llvm.icmp "ne" %3, %8 : i8
  "llvm.return"(%9) : (i1) -> ()
}
]

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

instance : ToString HydraVariable where
  toString s := s! "Variable[id: {s.id}, name : {s.name}, width : {s.width}]"

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

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

def muxVal (x y c : ValueStream (BitVec 1)): ValueStream (BitVec 1) :=
  Stream.corec (β := ValueStream (BitVec 1) × ValueStream (BitVec 1) × ValueStream (BitVec 1)) (x, y, c)
  fun ⟨x, y, c⟩ =>
    match (c 0) with
    | none => (none, x, y, c.tail) 
    | some 1#1 =>
      match (x 0) with
      | none => (none, x.tail, y, c) 
      | some e => (some e, x.tail, y, c.tail) 
    | some 0#1 =>
      match (y 0) with
      | none => (none, x, y.tail, c) 
      | some e => (some e, x, y.tail, c.tail) 

def sub_ult_zext_before := [llvm|
{
^0(%arg161 : i1, %arg162 : i8, %arg163 : i8):
  %0 = llvm.zext %arg161 : i1 to i8
  %1 = llvm.sub %arg162, %arg163 : i8
  %2 = llvm.icmp "ult" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

def addKUnary (x : BitStream) (k : Nat) : BitStream :=
  fun i => if i < k then true else x (i - k)

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

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

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

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

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 add_mask_ashr28_non_pow2_i32_after := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(28 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.ashr %arg1, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.add %3, %2 overflow<nsw> : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

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

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

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

def HVector.vars {l : List d.Ty} (T : HVector (Var Γ) l) : VarSet Γ :=
  T.foldl (fun _ s a => insert ⟨_, a⟩ s) ∅

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

instance : ToString Ty where
  toString t := repr t |>.pretty

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

instance : HydrableInstances GenBVPred where

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

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

def absdiff1_before := [llvm|
{
^0(%arg2 : i64, %arg3 : i64):
  %0 = llvm.icmp "ult" %arg2, %arg3 : i64
  %1 = llvm.sext %0 : i1 to i64
  %2 = llvm.sub %arg2, %arg3 : i64
  %3 = llvm.xor %2, %1 : i64
  %4 = llvm.sub %3, %1 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

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

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

@[simp_denote]
def ori_riscv :=
  [LV| {
    ^entry (%arg: i16):
    %a =  "builtin.unrealized_conversion_cast" (%arg) : (i16) -> (!i64)
    %0 =ori %a, 5 : !i64
    %1 = "builtin.unrealized_conversion_cast" (%0) : (!i64) -> (i16)
    llvm.return %1 :i16
  }]

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

    |

def Tensor2d'.map (f : α → β) (t : Tensor2d' α) : Tensor2d' β where
  dim₀ := t.dim₀
  dim₁ := t.dim₁
  mat := t.mat.map f

def t2_symmetry_before := [llvm|
{
^0(%arg25 : i8, %arg26 : i8):
  %0 = llvm.add %arg25, %arg26 : i8
  %1 = llvm.icmp "ult" %0, %arg25 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

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

def State.cseArgList
 [TyDenote d.Ty] [DialectSignature d] [DialectDenote d]
  {Γstart Γ : Ctxt d.Ty} {lets : Lets d Γstart .pure Γ} (s : State d lets)
  {ts : List d.Ty}
  (as : HVector (Ctxt.Var Γ) <| ts) :
  { as' : HVector (Ctxt.Var Γ) <| ts // ∀ (V : Γstart.Valuation),
    as.map (lets.denote V).eval = as'.map (lets.denote V).eval  } :=
  match as with
  | .nil => ⟨.nil, by admit /- proof elided -/
    ⟩
  | .cons a as =>
    let ⟨a', ha'⟩ :=  s.var2var a
    let ⟨as', has'⟩ := s.cseArgList as
    ⟨.cons a' as', by admit /- proof elided -/
    ⟩

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

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

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

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

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

def logicalShiftRight (x : BitStream) (k : Nat) : BitStream :=
  fun i => x (k + i)

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

def Γn (n : Nat) : Ctxt (MetaLLVM φ).Ty :=
  Ctxt.ofList <| .replicate n (.bitvec 32)

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 alive_AndOrXor_135_src :=
[sllvm| {
^bb0(%X : i64, %C1 : i64, %C2 : i64):
  %v1 = llvm.xor %X, %C1 : i64
  %v2 = llvm.and %v1, %C2 : i64
  llvm.return %v2 : i64
}]

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

def test12_logical_before := [llvm|
{
^0(%arg290 : i32, %arg291 : i32):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.icmp "ult" %arg290, %arg291 : i32
  %2 = llvm.icmp "ule" %arg290, %arg291 : i32
  %3 = "llvm.select"(%1, %2, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def PR39793_bswap_u32_as_u16_trunc_after := [llvm|
{
^0(%arg24 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.lshr %arg24, %0 : i32
  %2 = llvm.trunc %1 : i32 to i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

def alive_820_tgt  :=
[llvm()| {
^bb0(%X : i9, %Op1 : i9):
  %v1 = llvm.srem %X, %Op1 : i9
  %v2 = llvm.sub %X, %v1 : i9
  %v3 = llvm.sdiv %X, %Op1 : i9
  llvm.return %v3 : i9
}]

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

def test3_after := [llvm|
{
^0(%arg119 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.and %arg119, %0 : i32
  %3 = llvm.or disjoint %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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 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 test3_after := [llvm|
{
^0(%arg4 : i123):
  %0 = llvm.mlir.constant(0 : i123) : i123
  "llvm.return"(%0) : (i123) -> ()
}
]

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

def or_and_xor_not_constant_commute1_before := [llvm|
{
^0(%arg166 : i9, %arg167 : i9):
  %0 = llvm.mlir.constant(42 : i9) : i9
  %1 = llvm.mlir.constant(-43 : i9) : i9
  %2 = llvm.xor %arg167, %arg166 : i9
  %3 = llvm.and %2, %0 : i9
  %4 = llvm.and %arg167, %1 : i9
  %5 = llvm.or %3, %4 : i9
  "llvm.return"(%5) : (i9) -> ()
}
]

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

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

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

def and_sel_op0_after := [llvm|
{
^0(%arg17 : i1):
  %0 = llvm.zext %arg17 : i1 to i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

Matrix in Mathlib.LinearAlgebra.Matrix.Defs

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

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

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

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

@[match_pattern] def or (w : Width φ)
  (DisjointFlag : DisjointFlag := {disjoint := false} ) : MOp φ
    := .binary w (.or DisjointFlag )

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

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

HDiv in Init.Prelude

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

def select_icmp_eq_and_4096_0_or_4096_after := [llvm|
{
^0(%arg225 : i32, %arg226 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.and %arg225, %0 : i32
  %2 = llvm.or %arg226, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def ne_21_comm_ne2_after := [llvm|
{
^0(%arg66 : i32, %arg67 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.lshr %arg66, %0 : i32
  %2 = llvm.trunc %1 : i32 to i16
  %3 = llvm.lshr %arg67, %0 : i32
  %4 = llvm.trunc %3 : i32 to i16
  %5 = llvm.icmp "ne" %2, %4 : i16
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

def add_or_and_before := [llvm|
{
^0(%arg19 : i32, %arg20 : i32):
  %0 = llvm.or %arg19, %arg20 : i32
  %1 = llvm.and %arg19, %arg20 : i32
  %2 = llvm.add %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

instance : LawfulMonad LLVM.m :=

def select_0_neg1 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 1)] where
  lhs := [LV| {
    ^entry (%c: i1):
      %t = llvm.mlir.constant (0) : i64
      %f = llvm.mlir.constant (-1) : i64
      %0 = llvm.select %c, %t, %f : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%c: i1):
      %0 = llvm.not %c : i1
      %1 = llvm.sext %0: i1 to i64
      llvm.return %1 : i64
  }]

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

structure Op where
  (name: String)
  (res: List <| TypedSSAVal φ)
  (args: List <| TypedSSAVal φ)
  (regions: List Region)
  (attrs: AttrDict φ)

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

Sigma.mk in Init.Core

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

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

def mkTy : MLIR.AST.MLIRType φ → MLIR.AST.ExceptM RV64 RV64.Ty
  | MLIR.AST.MLIRType.undefined "i64" => do return .bv
  | MLIR.AST.MLIRType.undefined "riscv.reg" => do return .bv
  | _ => throw .unsupportedType

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

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

def scanOr  : FSM Unit :=
  {
   α := Unit,
   initCarry := fun () => false,
   outputCirc := Circuit.var true (inl ()) ||| Circuit.var true (inr ()),
   nextStateCirc := fun () => Circuit.var true (inl ()) ||| Circuit.var true (inr ())
  }

RV64.sllw in RISCV.Instructions

def test46_after := [llvm|
{
^0(%arg199 : i32, %arg200 : i32):
  %0 = llvm.and %arg200, %arg199 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

def fold_icmp_shl_nuw_c2_before := [llvm|
{
^0(%arg8 : i32):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.mlir.constant(64 : i32) : i32
  %2 = llvm.shl %0, %arg8 overflow<nuw> : i32
  %3 = llvm.icmp "ult" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def t9_c0_c2_after := [llvm|
{
^0(%arg13 : i8, %arg14 : i8):
  %0 = llvm.mlir.constant(18 : i8) : i8
  %1 = llvm.sub %0, %arg13 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def test1_before := [llvm|
{
^0(%arg3 : i16):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(5 : i32) : i32
  %2 = llvm.zext %arg3 : i16 to i32
  %3 = llvm.lshr %2, %0 : i32
  %4 = llvm.mul %2, %1 : i32
  %5 = llvm.or %3, %4 : i32
  %6 = llvm.trunc %5 : i32 to i16
  "llvm.return"(%6) : (i16) -> ()
}
]

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

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

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

def src_is_notmask_x_xor_neg_x_before := [llvm|
{
^0(%arg69 : i8, %arg70 : i8, %arg71 : i1):
  %0 = llvm.mlir.constant(123 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.mlir.constant(-8 : i8) : i8
  %3 = llvm.xor %arg69, %0 : i8
  %4 = llvm.sub %1, %arg70 : i8
  %5 = llvm.xor %arg70, %4 : i8
  %6 = "llvm.select"(%arg71, %5, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %7 = llvm.and %3, %6 : i8
  %8 = llvm.icmp "eq" %7, %1 : i8
  "llvm.return"(%8) : (i1) -> ()
}
]

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

def or_logic_or_logic_and_3_before := [llvm|
{
^0(%arg42 : i1, %arg43 : i1, %arg44 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.or %arg42, %arg43 : i1
  %3 = "llvm.select"(%arg42, %0, %arg44) <{"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_icmps_mask_notallzeros_bmask_mixed_negated_swapped_6_after := [llvm|
{
^0(%arg14 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.and %arg14, %0 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def trunc_sandwich_big_sum_shift1_before := [llvm|
{
^0(%arg64 : i32):
  %0 = llvm.mlir.constant(21 : i32) : i32
  %1 = llvm.mlir.constant(11 : i12) : i12
  %2 = llvm.lshr %arg64, %0 : i32
  %3 = llvm.trunc %2 : i32 to i12
  %4 = llvm.lshr %3, %1 : i12
  "llvm.return"(%4) : (i12) -> ()
}
]

def orn_and_cmp_2_partial_logical_after := [llvm|
{
^0(%arg6 : i16, %arg7 : i16, %arg8 : i1):
  %0 = llvm.icmp "slt" %arg6, %arg7 : i16
  %1 = llvm.or %arg8, %0 : i1
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

instance : ToString (Com d Γ eff t)  where toString com  := s!"{com.print}"

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

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

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

def generateRawSemantics : IO Unit := do
  let filename := "generated-ssa-llvm-semantics.csv"
  let handle : Handle ← IO.FS.Handle.mk filename IO.FS.Mode.write
  let stream : Stream := IO.FS.Stream.ofHandle handle
  let mut rows := #[rowHeader]
  rows := rows.append (selectRows)
  \n".intercalate |> stream.putStr
  return ()

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

def not_cmp_fold_eq : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64, %y: i64):
      %0 = llvm.icmp.eq %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.ne %x, %y : i64
      llvm.return %0 : i1
  }]

inductive ExTy
  | nat
  | bool
  deriving DecidableEq, Repr

def test17_after := [llvm|
{
^0(%arg17 : i8):
  %0 = llvm.mlir.constant(false) : i1
  "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) -> ()
}
]

def Factor.toExpr (f : Factor) : Expr :=
  match f with
  | .var i => mkApp (mkConst ``Factor.var) (mkNatLit i)
  | .xor i j => mkApp2 (mkConst ``Factor.xor) i.toExpr j.toExpr
  | .and i j => mkApp2 (mkConst ``Factor.and) i.toExpr j.toExpr
  | .or i j => mkApp2 (mkConst ``Factor.or) i.toExpr j.toExpr
  | .not x => mkApp (mkConst ``Factor.not) x.toExpr

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

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

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

instance (priority := low) :
    IsTrans α (HRefinement.IsRefinedBy (self := @instHRefinementOfRefinement α .ofEq)) where
  trans _ _ _ := Eq.trans

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

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

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

def reprWithoutFlags (op : MOp.BinaryOp) (prec : Nat) : Format :=
  let op  : String := match op with
    | .and                => "and"
    | .or   ⟨false⟩        => "or"
    | .or   ⟨true⟩         => "or disjoint"
    | .xor                => "xor"
    | .shl  ⟨false, false⟩ => "shl"
    | .shl  ⟨nsw, nuw⟩     => toString f!"shl {nsw} {nuw}"
    | .lshr ⟨false⟩        => "lshr"
    | .lshr ⟨true⟩         => "lshr exact"
    | .ashr ⟨false⟩        => "ashr"
    | .ashr ⟨true⟩         => "ashr exact"
    | .urem               => "urem"
    | .srem               => "srem"
    | .add  ⟨false, false⟩ => "add"
    | .add  ⟨nsw, nuw⟩     => toString f!"add {nsw} {nuw}"
    | .mul  ⟨false, false⟩ => "mul"
    | .mul  ⟨nsw, nuw⟩     => toString f!"mul {nsw} {nuw}"
    | .sub  ⟨false, false⟩ => "sub"
    | .sub  ⟨nsw, nuw⟩     => toString f!"sub {nsw} {nuw}"
    | .sdiv ⟨false⟩        => "sdiv"
    | .sdiv ⟨true⟩         => "sdiv exact"
    | .udiv ⟨false⟩        => "udiv"
    | .udiv ⟨true⟩         => "udiv exact"
  Repr.addAppParen (Format.group (Format.nest
    (if prec >= max_prec then 1 else 2) f!"InstCombine.MOp.BinaryOp.{op}"))
    prec

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

def fsmWidthUle (a b : FSM α) : FSM α :=
  composeUnaryAux FSM.scanAnd (b ||| ~~~ a)

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 llvm_zext_lower_riscv_1_to_16 : LLVMPeepholeRewriteRefine 16 [Ty.llvm (.bitvec 1)] :=
  {lhs:= zext_llvm_1_to_16, rhs:= zext_riscv_1_to_16}

def alive_AddSub_1564_tgt  (w : Nat)  :=
[llvm( w )| {
^bb0(%x : _, %C : _):
  %v1 = llvm.mlir.constant -1
  %v2 = llvm.xor %x, %v1
  %v3 = llvm.mlir.constant 1
  %v4 = llvm.add %C, %v3
  %v5 = llvm.add %x, %v4
  llvm.return %v5
}]

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

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

Stream' in Mathlib.Data.Stream.Defs

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 icmp_eq_mul_nuw_nonequal_before := [llvm|
{
^0(%arg32 : i8, %arg33 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.add %arg32, %0 : i8
  %2 = llvm.mul %arg32, %arg33 overflow<nuw> : i8
  %3 = llvm.mul %1, %arg33 overflow<nuw> : i8
  %4 = llvm.icmp "eq" %2, %3 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

@[simp_denote]
def icmp_uge_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 %lhsr, %rhsr : !i64
    %1 = xori %0, 1 : !i64
    %2 = "builtin.unrealized_conversion_cast"(%1) : (!i64) -> (i1)
    llvm.return %2 : i1
  }]

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

RV64.zexth in RISCV.Instructions

def scalar_i16_shl_and_signbit_eq_after := [llvm|
{
^0(%arg33 : i16, %arg34 : i16):
  %0 = llvm.mlir.constant(-1 : i16) : i16
  %1 = llvm.shl %arg33, %arg34 : i16
  %2 = llvm.icmp "sgt" %1, %0 : i16
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

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

@[simp_denote]
def iterate {Γ : Ctxt _} (k : Nat) (input : Var Γ int) (body : Com SimpleReg ⟨[int]⟩ .impure [int]) :
    Expr SimpleReg Γ .pure [int] :=
  Expr.mk
    (op := Op.iterate k)
    (eff_le := by admit /- proof elided -/
    )
    (ty_eq := rfl)
    (args := .cons input .nil)
    (regArgs := HVector.cons body HVector.nil)

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

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

def assignAllVars [DecidableEq α] (c : Circuit α)
  (f : α → Bool) : Circuit Empty
  := match c with
  | tru => tru
  | fals => fals
  | var b x =>
    let v := f x
    Circuit.ofBool (b = v)
  | and p q => assignAllVars p f &&& assignAllVars q f
  | or p q => assignAllVars p f ||| assignAllVars q f
  | xor p q => assignAllVars p f ^^^ assignAllVars q f

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

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

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

Lean.Parser.sepBy in Lean.Parser.Basic

def test_eq_11_and_15_add_10_before := [llvm|
{
^0(%arg1 : i8):
  %0 = llvm.mlir.constant(10 : i8) : i8
  %1 = llvm.mlir.constant(15 : i8) : i8
  %2 = llvm.mlir.constant(11 : i8) : i8
  %3 = llvm.add %arg1, %0 : i8
  %4 = llvm.and %3, %1 : i8
  %5 = llvm.icmp "eq" %4, %2 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

instance : Zero Term := ⟨zero⟩

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

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

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

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

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

private def mod2 : Op φ := [mlir_op| module { "dummy.dummy"(): () -> () }]

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

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

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

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

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

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

Nat.succ in Init.Prelude

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

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

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

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

@[match_pattern] def copy   (w : Width φ) : MOp φ := .unary w .copy

def join (x y : TokenStream) : TokenStream  :=
  syncMap₂ (xs := x) (ys := y) (f := sendReadySignal)

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

def t1_after := [llvm|
{
^0(%arg241 : i16, %arg242 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.zext %arg241 : i16 to i32
  %2 = llvm.add %arg242, %0 : i32
  %3 = llvm.lshr %1, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def test8_before := [llvm|
{
^0(%arg20 : i32):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.mlir.constant(32767) : i64
  %2 = llvm.ashr %arg20, %0 : i32
  %3 = llvm.sext %2 : i32 to i64
  %4 = llvm.mul %3, %1 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

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

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

def or_i16_test: LLVMPeepholeRewriteRefine 16 [Ty.llvm (.bitvec 16), Ty.llvm (.bitvec 16) ] where
  lhs := or_llvm_i16
  rhs := or_riscv_i16

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

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

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

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

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

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

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

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

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

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

instance [HRefinement α α] [DecidableRel (· ⊑ · : α → α → _)] :
    DecidableRel (· ⊑ · : PoisonOr α → PoisonOr α → _)
  | .poison, _ => .isTrue <| by simp
  | .value _, .poison => .isFalse <| by simp
  | .value a, .value b => decidable_of_decidable_of_iff (p := a ⊑ b) <| by simp

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

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

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

def test_shl_nuw_nsw__nuw_is_safe_before := [llvm|
{
^0(%arg82 : i32, %arg83 : i64):
  %0 = llvm.mlir.constant(1073741822 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.and %arg82, %0 : i32
  %4 = llvm.shl %3, %1 overflow<nsw,nuw> : i32
  %5 = llvm.zext %4 : i32 to i64
  %6 = llvm.icmp "eq" %3, %2 : i32
  %7 = llvm.ashr %arg83, %5 : i64
  %8 = "llvm.select"(%6, %arg83, %7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%8) : (i64) -> ()
}
]

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

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

Option.get! in Init.Data.Option.BasicAux

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

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

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

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

instance [ToMessageData α] : ToMessageData (ReflectResult α) where
  toMessageData result := m!"{result.e} {result.exprToIx}"

def negate_zext_after := [llvm|
{
^0(%arg112 : i8, %arg113 : i1):
  %0 = llvm.sext %arg113 : i1 to i8
  %1 = llvm.add %arg112, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def zext_nneg_redundant_and_before := [llvm|
{
^0(%arg6 : i8):
  %0 = llvm.mlir.constant(127 : i32) : i32
  %1 = llvm.zext nneg %arg6 : i8 to i32
  %2 = llvm.and %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

def add_mask_ashr28_non_pow2_i32_after := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(28 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.ashr %arg1, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.add %3, %2 overflow<nsw> : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def add {w : Nat} (l : List (BitVec w)) : BitVec w :=
  List.foldr BitVec.add (0#w) l

def simplify_neg_minmax : RISCVPeepholeRewrite [Ty.riscv (.bv) ] where
  lhs := [LV| {
    ^entry (%x: !riscv.reg):
      %0 = neg %x : !riscv.reg
      %1 = min %x, %0 : !riscv.reg
      %2 = neg %1 : !riscv.reg
      ret %2 : !riscv.reg
  }]
  rhs := [LV| {
    ^entry (%x: !riscv.reg):
      %0 = neg %x : !riscv.reg
      %1 = max %x, %0 : !riscv.reg
      ret %1 : !riscv.reg
  }]

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

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

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

-/

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

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

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

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

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

def simplify_neg_maxmin : RISCVPeepholeRewrite [Ty.riscv (.bv) ] where
  lhs := [LV| {
    ^entry (%x: !riscv.reg):
      %0 = neg %x : !riscv.reg
      %1 = max %x, %0 : !riscv.reg
      %2 = neg %1 : !riscv.reg
      ret %2 : !riscv.reg
  }]
  rhs := [LV| {
    ^entry (%x: !riscv.reg):
      %0 = neg %x : !riscv.reg
      %1 = min %x, %0 : !riscv.reg
      ret %1 : !riscv.reg
  }]

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

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

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

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

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

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

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

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

def andcond.001.inv.outer.cond_after := [llvm|
{
^0(%arg75 : i1, %arg76 : i1, %arg77 : i1, %arg78 : i1, %arg79 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.xor %arg76, %0 : i1
  %3 = "llvm.select"(%2, %arg77, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = "llvm.select"(%arg75, %3, %arg78) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def llvm_const_lower_riscv_li7 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM7, rhs:= liRiscv7,
   correct := by admit /- proof elided -/

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

abbrev MetaLLVM (φ : Nat) : Dialect where
  Op := MOp φ
  Ty := MTy φ

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

Lean.Elab.Tactic.run in Lean.Elab.Tactic.Basic

ZMod.val in Mathlib.Data.ZMod.Basic

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 neg_sgt_42_before := [llvm|
{
^0(%arg39 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(42 : i32) : i32
  %2 = llvm.sub %0, %arg39 : i32
  %3 = llvm.icmp "sgt" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

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

@[simp_denote]
def add {Γ : Ctxt _} (w : ℕ) (l r : Nat)
    (lp : (Γ[l]? = some (InstCombine.MTy.bitvec (ConcreteOrMVar.concrete w)))
      := by admit /- proof elided -/
      )
    (rp : (Γ[r]? = some (InstCombine.MTy.bitvec (ConcreteOrMVar.concrete w)))
      := by admit /- proof elided -/
      ) :
    Expr InstCombine.LLVM Γ .pure (LLVM.Ty.bitvec w) :=
  Expr.mk
    (op := InstCombine.MOp.add w)
    (eff_le := by admit /- proof elided -/
    )
    (ty_eq := rfl)
    (args := .cons ⟨l, lp⟩ <| .cons ⟨r, rp⟩ .nil)
    (regArgs := .nil)

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

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

inductive FpBinOp
| add
deriving Hashable, DecidableEq, Repr

def test17_before := [llvm|
{
^0(%arg36 : i32, %arg37 : i32):
  %0 = llvm.mlir.constant(-1431655766 : i32) : i32
  %1 = llvm.mlir.constant(-1431655765 : i32) : i32
  %2 = llvm.and %arg36, %0 : i32
  %3 = llvm.xor %2, %1 : i32
  %4 = llvm.add %3, %arg37 overflow<nsw> : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

def or_before := [llvm|
{
^0(%arg678 : i64, %arg679 : i64):
  %0 = llvm.and %arg679, %arg678 : i64
  %1 = llvm.xor %arg679, %arg678 : i64
  %2 = llvm.add %0, %1 : i64
  "llvm.return"(%2) : (i64) -> ()
}
]

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

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

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

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

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

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

RV64.slliuw in RISCV.Instructions

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

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

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

instance [ToMessageData α] : ToMessageData (BoolExpr α) where
  toMessageData := go
  where
    go : BoolExpr α → MessageData
    | .literal a => toMessageData a
    | .const b => toMessageData b
    | .not x => "!" ++ go x
    | .gate g x y => "(" ++ go x ++ " " ++ g.toString ++ " " ++ go y ++ ")"
    | .ite d l r => "(if " ++ go d ++ " " ++ go l ++ " " ++ go r ++ ")"


deriving instance Hashable for BVBinPred
deriving instance BEq for BVBinPred
deriving instance DecidableEq for BVBinPred

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

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

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

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

def bools_logical_after := [llvm|
{
^0(%arg48 : i1, %arg49 : i1, %arg50 : i1):
  %0 = "llvm.select"(%arg50, %arg49, %arg48) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

Or.inl in Init.Prelude

HSub.hSub in Init.Prelude

def univ [DecidableEq ι] [Fintype ι] (n : Nat) :
    { univ : Finset (Inputs ι n) // ∀ x : Inputs ι n, x ∈ univ } :=
  let ixs : Finset (Fin n) := Finset.univ
  let inputs : Finset ι := Finset.univ
  let out := ixs.biUnion
      (fun ix => inputs.map ⟨fun input => Inputs.mk ix input, by admit /- proof elided -/
      ⟩)
  ⟨out, by admit /- proof elided -/
  ⟩

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

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

def scalar_i16_signbit_lshr_and_eq_before := [llvm|
{
^0(%arg33 : i16, %arg34 : i16):
  %0 = llvm.mlir.constant(-32768 : i16) : i16
  %1 = llvm.mlir.constant(0 : i16) : i16
  %2 = llvm.lshr %0, %arg34 : i16
  %3 = llvm.and %2, %arg33 : i16
  %4 = llvm.icmp "eq" %3, %1 : i16
  "llvm.return"(%4) : (i1) -> ()
}
]

def sel_false_val_is_a_masked_shl_of_true_val1_before := [llvm|
{
^0(%arg10 : i32, %arg11 : i64):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.and %arg10, %0 : i32
  %4 = llvm.shl %3, %1 overflow<nsw,nuw> : i32
  %5 = llvm.zext %4 : i32 to i64
  %6 = llvm.icmp "eq" %3, %2 : i32
  %7 = llvm.ashr %arg11, %5 : i64
  %8 = "llvm.select"(%6, %arg11, %7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%8) : (i64) -> ()
}
]

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

def or_nosignbit_select_lshr_after := [llvm|
{
^0(%arg24 : i32, %arg25 : i1):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(8388352 : i32) : i32
  %2 = llvm.lshr %arg24, %0 : i32
  %3 = llvm.or %2, %1 : i32
  %4 = "llvm.select"(%arg25, %3, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def slt_zero_eq_ne_0_fail1_before := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(31 : i32) : i32
  %2 = llvm.icmp "ne" %arg1, %0 : i32
  %3 = llvm.zext %2 : i1 to i32
  %4 = llvm.ashr %arg1, %1 : i32
  %5 = llvm.icmp "eq" %3, %4 : i32
  "llvm.return"(%5) : (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 sge_smin4_after := [llvm|
{
^0(%arg73 : i32, %arg74 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg73, %0 : i32
  %2 = llvm.icmp "sge" %arg74, %1 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

def not_and_and_or_not_or_or_commute4_after := [llvm|
{
^0(%arg229 : i32, %arg230 : i32, %arg231 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg231 : i32
  %3 = llvm.xor %2, %arg230 : i32
  %4 = llvm.or %3, %arg229 : i32
  %5 = llvm.xor %4, %1 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_6_before := [llvm|
{
^0(%arg14 : 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.and %arg14, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.and %arg14, %2 : i32
  %7 = llvm.icmp "ne" %6, %3 : i32
  %8 = llvm.or %7, %5 : i1
  "llvm.return"(%8) : (i1) -> ()
}
]

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

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

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 n9_before := [llvm|
{
^0(%arg1 : i64):
  %0 = llvm.mlir.constant(62) : i64
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.lshr %arg1, %0 : i64
  %3 = llvm.trunc %2 : i64 to i32
  %4 = llvm.sub %1, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

def xor_ashr_not_fail_ashr_lshr_after := [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, %1 : i8
  %4 = llvm.xor %3, %0 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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 mul_splat_fold_too_narrow_before := [llvm|
{
^0(%arg77 : i2):
  %0 = llvm.mlir.constant(-2 : i2) : i2
  %1 = llvm.mlir.constant(1 : i2) : i2
  %2 = llvm.mul %arg77, %0 overflow<nuw> : i2
  %3 = llvm.lshr %2, %1 : i2
  "llvm.return"(%3) : (i2) -> ()
}
]

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

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

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

def simplify_or_common_op_commute1_after := [llvm|
{
^0(%arg42 : i4, %arg43 : i4, %arg44 : i4):
  %0 = llvm.mlir.constant(-1 : i4) : i4
  "llvm.return"(%0) : (i4) -> ()
}
]

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

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

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

instance : Trans (@ExtEq Op) ExtEq ExtEq := ⟨ExtEq.trans⟩

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

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

Lean.ofReduceBool in Init.Core

def argTypes : List (MLIRType φ) :=
  op.args.map Prod.snd

def scalar_i32_signbit_lshr_and_eq_after := [llvm|
{
^0(%arg31 : i32, %arg32 : i32):
  %0 = llvm.mlir.constant(-2147483648 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.lshr exact %0, %arg32 : i32
  %3 = llvm.and %2, %arg31 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def Lets.varsOfVec (lets : Lets d Γ_in eff Γ_out) (vs : HVector Γ_out.Var ts) :
    VarSet Γ_in :=
  (vs.vars).biUnion (fun v => lets.vars v.2)

def demorgan_and_apint4_after := [llvm|
{
^0(%arg52 : i66, %arg53 : i66):
  %0 = llvm.mlir.constant(-1 : i66) : i66
  %1 = llvm.or %arg52, %arg53 : i66
  %2 = llvm.xor %1, %0 : i66
  "llvm.return"(%2) : (i66) -> ()
}
]

def eq_21_after := [llvm|
{
^0(%arg124 : i32, %arg125 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.lshr %arg124, %0 : i32
  %2 = llvm.trunc %1 : i32 to i16
  %3 = llvm.lshr %arg125, %0 : i32
  %4 = llvm.trunc %3 : i32 to i16
  %5 = llvm.icmp "eq" %2, %4 : i16
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

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

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

Array.push in Init.Prelude

instance : LawfulMonad EffectM :=
</all_available_defs>

<all_available_lemmas>
List.nodup_singleton in Mathlib.Data.List.Nodup
NFA.eval_append_singleton in Mathlib.Computability.NFA
NFA.eval_nil in Mathlib.Computability.NFA
Set.mem_setOf_eq in Mathlib.Data.Set.Operations
Nat.add_comm in Init.Data.Nat.Basic
Fin.add_def in Init.Data.Fin.Lemmas
Fin.castLE_castLE in Init.Data.Fin.Lemmas
Nat.le_of_eq in Init.Data.Nat.Basic
Nat.mod_eq_of_lt in Init.Data.Nat.Div.Basic

@[ext]
theorem ext {x y : BitStream} (h : ∀ i, x i = y i) : x = y

lemma bisim_comp (m : RawCNFA A) :
    m.Sim M₁ → M₁.Bisim M₂ → m.Sim M₂

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

lemma CNFA.bv_recognizes_equiv {m : CNFA n} :
    m.bv_recognizes L ↔ ∃ (M : NFA' n), m.Sim M ∧ M.accepts = L

@[simp]
lemma List.Vector.append_get_ge {x : List.Vector α n} {y : List.Vector α m} {i : Fin (n+m)} (hlt: n ≤ i) :
    (x ++ y).get i = y.get ((i.cast (Nat.add_comm n m) |>.subNat n hlt))

@[simp]
lemma List.Vector.append_get_lt {x : List.Vector α n} {y : List.Vector α m} {i : Fin (n+m)} (hlt: i < n) :
    (x ++ y).get i = x.get (i.castLT hlt)

lemma CNFA.minimize_bv_language {m : CNFA n} :
    m.bv_recognizes L → m.minimize.bv_recognizes L

lemma CNFA.minimize_language {m : CNFA n} :
    m.recognizes L → m.minimize.recognizes L

lemma CNFA.reverse_language {m : CNFA n} (hl : m.recognizes L) : m.reverse.recognizes L.reverse

lemma CNFA.reverse_spec {m : CNFA n} : m.reverse.Sim m.toNFA'.reverse

lemma RawCNFA.reverse_spec {m : RawCNFA A} (hwf : m.WF) :
    let m'

lemma RawCNFA.reverse_spec_procesState {m : RawCNFA A} (hwf : m.WF) s₀ a₀ ss' (hs₀ : s₀ ∈ m.states) :
    let motive m' ss'

lemma CNFA.determinize_language {m : CNFA n} :
    m.recognizes L → m.determinize.recognizes L

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

lemma CNFA.lift_spec (m : CNFA n1) (f : Fin n1 → Fin n2) {M : NFA' n1} :
    m.Sim M → (m.lift f |>.Sim (M.lift f))

lemma CNFA.proj_bv_language {m : CNFA n2} {f : Fin n1 → Fin n2} :
    m.bv_recognizes L → (m.proj f |>.bv_recognizes (BitVecs.transport f '' L))

theorem select_replace_udiv_non_speculatable_proof : select_replace_udiv_non_speculatable_before ⊑ select_replace_udiv_non_speculatable_after

theorem select_icmp_eq_and_1_0_or_2_proof : select_icmp_eq_and_1_0_or_2_before ⊑ select_icmp_eq_and_1_0_or_2_after

theorem and_signbit_select_ashr_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 →
    ¬8#32 ≥ ↑32 → (x &&& BitVec.ofInt 32 (-65536)).sshiftRight' 8#32 = x.sshiftRight' 8#32 &&& BitVec.ofInt 32 (-256)

theorem select_constants_and_icmp_eq0_zero_fval_thm.extracted_1._4 : ∀ (x x_1 : BitVec 1),
  ¬x_1 = 1#1 → ¬x = 1#1 → ofBool (0#8 &&& 0#8 == 0#8) = 0#1 ^^^ 1#1

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

theorem test34_proof : test34_before ⊑ test34_after

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

theorem test73_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (-1#8 <ₛ truncate 8 x) = 1#1 → ¬ofBool (x &&& 128#32 == 0#32) = 1#1 → 40#32 = 42#32

theorem or_and3_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32) (x_2 : BitVec 1),
  x_2 ||

@[simp] theorem MatchVarM.liftM_eq_some_iff (x? : Option α) :
    (liftM x? : no_index MatchVarM Δ Γ α) mapIn = some (x, mapOut)
    ↔ x? = some x ∧ mapIn = mapOut

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

theorem and_sext_to_sel_thm (e : IntW 32) (e_1 : IntW 1) : LLVM.and (sext 32 e_1) e ⊑ select e_1 e (const? 32 0)

theorem uge_swap_or_not_max_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.ule e_1 e) (icmp IntPred.ne e (const? 8 (-1))) ⊑ const? 1 1

theorem bool_add_ashr_thm (e e_1 : IntW 1) :
  ashr (add (zext 2 e_1) (zext 2 e)) (const? 2 1) ⊑
    ashr (add (zext 2 e_1) (zext 2 e) { «nsw» := false, «nuw» := true }) (const? 2 1)

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

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

theorem and_or3_commuted_thm.extracted_1._8 : ∀ (x x_1 : BitVec 1) (x_2 x_3 : BitVec 32),
  ¬ofBool (x_3 == x_2) &&& x_1 = 1#1 → ¬x_1 = 1#1 → x_1 = 0#1

theorem lshrult_01_00_exact_proof : lshrult_01_00_exact_before ⊑ lshrult_01_00_exact_after

theorem e_1701 :
    5 *  ~~~( ~~~a ||| (b &&& c)) - 5 * ((a &&& c) ^^^ (b ||| c)) + 2 * (a ^^^ c) + 5 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) - 11 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) - 2 * ( ~~~a ||| ( ~~~b ||| c)) + 1 * (c ^^^  ~~~(a &&& (b &&& c))) - 5 * (b ^^^  ~~~(a ||| (b &&& c))) - 2 * (b ^^^ (a &&& c)) - 1 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) + 1 * (b &&& (a ||| c)) - 2 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) + 4 *  ~~~(a ||| c) - 1 * ( ~~~(a ||| b) |||  ~~~(b ^^^ c)) + 1 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) + 1 *  ~~~(a &&& (b ^^^ c)) + 3 * (b ^^^ (a ||| c)) - 7 * (a ||| c) - 1 *  ~~~(a &&& ( ~~~b ||| c)) + 3 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) - 1 * (b |||  ~~~(a ^^^ c)) + 11 *  ~~~(a ||| (b ||| c)) + 11 *  ~~~(a ||| ( ~~~b ||| c)) + 6 *  ~~~( ~~~a ||| (b ||| c)) + 6 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 8 * ( ~~~a &&& ( ~~~b &&& c)) + 30 * ( ~~~a &&& (b &&& c)) + 6 * (a &&& ( ~~~b &&& c)) + 9 * (a &&& (b &&& c)) =  - 1 * (c ^^^  ~~~(a &&& ( ~~~b ||| c)))

theorem test2_thm (e e_1 : IntW 32) :
  zext 32 (icmp IntPred.eq (LLVM.and e_1 (const? 32 8)) (LLVM.and e (const? 32 8))) ⊑
    LLVM.xor (LLVM.and (lshr (LLVM.xor e_1 e) (const? 32 3)) (const? 32 1)) (const? 32 1)

theorem ashrslt_03_10_exact_proof : ashrslt_03_10_exact_before ⊑ ashrslt_03_10_exact_after

theorem t3_exact_thm (e : IntW 64) :
  sub (const? 64 0) (ashr e (const? 64 63) { «exact» := true }) ⊑ lshr e (const? 64 63) { «exact» := true }

theorem src_is_mask_p2_m1_proof : src_is_mask_p2_m1_before ⊑ src_is_mask_p2_m1_after

theorem lshr_and_add_thm (e e_1 : IntW 8) :
  shl (add (LLVM.srem e_1 (const? 8 42)) (LLVM.and (lshr e (const? 8 3)) (const? 8 12))) (const? 8 3) ⊑
    add (LLVM.and e (const? 8 96)) (shl (LLVM.srem e_1 (const? 8 42)) (const? 8 3))

theorem test1_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(1#32 ≥ ↑32 ∨
        True ∧ (x.sshiftRight' 1#32 &&& 1431655765#32 ^^^ -1#32).saddOverflow 1#32 = true ∨
          True ∧ x.saddOverflow ((x.sshiftRight' 1#32 &&& 1431655765#32 ^^^ -1#32) + 1#32) = true) →
    ¬(1#32 ≥ ↑32 ∨ True ∧ x.ssubOverflow (x >>> 1#32 &&& 1431655765#32) = true) →
      x + ((x.sshiftRight' 1#32 &&& 1431655765#32 ^^^ -1#32) + 1#32) = x - (x >>> 1#32 &&& 1431655765#32)

theorem e_93 :
    4 * y + 3 * x + 1 * (x ||| y) - 4 * (x &&&  ~~~y) - 8 * (x &&& y) = 5 *  ~~~(x |||  ~~~y)

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

theorem PR2844_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x == 0#32) ||

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

theorem positive_trunc_signbit_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (-1#8 <ₛ truncate 8 x) = 1#1 → 0#1 = ofBool (x <ᵤ 128#32)

theorem sgt_smax4_proof : sgt_smax4_before ⊑ sgt_smax4_after

theorem p0_proof : p0_before ⊑ p0_after

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

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

theorem bor_lor_right1_thm (e e_1 : IntW 1) : select e_1 (const? 1 1) (LLVM.or e_1 e) ⊑ select e_1 (const? 1 1) e

theorem different_size_sext_sext_sle_thm.extracted_1._1 : ∀ (x : BitVec 4) (x_1 : BitVec 7),
  ofBool (signExtend 25 x_1 ≤ₛ signExtend 25 x) = ofBool (x_1 ≤ₛ signExtend 7 x)

theorem eq_mul_constants_with_tz_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 * 12#32 != x * 12#32) = ofBool ((x_1 ^^^ x) &&& 1073741823#32 != 0#32)

theorem t3_proof : t3_before ⊑ t3_after

theorem or_to_nxor4_proof : or_to_nxor4_before ⊑ or_to_nxor4_after

theorem shl_add_and_proof : shl_add_and_before ⊑ shl_add_and_after

theorem t0_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8), x_2 - x_1 - x = x_2 - (x_1 + x)

theorem e_1308 :
     - 6 *  ~~~(z &&& t) + 4 * (z |||  ~~~t) + 5 * (z ||| t) + 2 * (z ^^^ t) + 11 *  ~~~(z &&&  ~~~t) - 1 *  ~~~z - 8 *  ~~~(z ||| t) - 5 * (z &&&  ~~~t) - 20 * (z &&& t) = 11 *  ~~~(z |||  ~~~t)

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

theorem icmp_mul_nsw_slt_neg_proof : icmp_mul_nsw_slt_neg_before ⊑ icmp_mul_nsw_slt_neg_after

theorem logical_or_implies_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x == 0#32) = 1#1 → 1#1 = ofBool (x == 0#32) ||

theorem test_shift_and_cmp_changed1_proof : test_shift_and_cmp_changed1_before ⊑ test_shift_and_cmp_changed1_after

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

theorem scalar_i8_lshr_and_negC_eq_proof : scalar_i8_lshr_and_negC_eq_before ⊑ scalar_i8_lshr_and_negC_eq_after

theorem test_proof : test_before ⊑ test_after

theorem p15_commutativity2_thm (e : IntW 32) :
  select (icmp IntPred.ult e (const? 32 65536)) (const? 32 42) (const? 32 65535) ⊑
    select (icmp IntPred.ugt e (const? 32 65535)) (const? 32 65535) (const? 32 42)

theorem test18_proof : test18_before ⊑ test18_after

theorem uge_umin3_proof : uge_umin3_before ⊑ uge_umin3_after

theorem e_2089 :
     - 1 * ( ~~~d &&& (e ^^^ f)) + 1 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 11 * (f ||| (d &&& e)) - 1 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 6 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 7 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 1 *  ~~~(d &&& ( ~~~e ||| f)) - 7 *  ~~~(d |||  ~~~e) + 1 * ((d &&& f) |||  ~~~(e ||| f)) + 5 *  ~~~(d ^^^ ( ~~~e ||| f)) - 7 *  ~~~(e ||| f) + 1 * (d ^^^ (e ^^^ f)) - 1 * (e ^^^ ( ~~~d ||| (e &&& f))) + 5 * (d &&&  ~~~e) - 3 * ((d ^^^ e) ||| (d ^^^ f)) - 1 * (e |||  ~~~(d ||| f)) - 1 *  ~~~( ~~~d ||| (e ^^^ f)) + 11 * (d ||| (e &&& f)) + 1 * (d ^^^ ( ~~~e ||| f)) + 2 * ((d &&& e) ^^^ (e |||  ~~~f)) - 11 * (f ^^^  ~~~(d &&& e)) - 7 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 2 * (e ^^^ (d &&& ( ~~~e ||| f))) + 7 *  ~~~(d &&& f) + 1 * (d ||| e) - 6 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) - 1 * (e ^^^ (d ||| f)) - 5 * (e ||| (d ^^^ f)) - 1 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 1 * f - 7 * (e ||| (d &&& f)) + 39 *  ~~~(d ||| (e ||| f)) + 32 *  ~~~(d ||| ( ~~~e ||| f)) + 15 *  ~~~( ~~~d ||| (e ||| f)) + 16 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 33 * ( ~~~d &&& ( ~~~e &&& f)) + 18 * ( ~~~d &&& (e &&& f)) + 11 * (d &&& ( ~~~e &&& f)) + 23 * (d &&& (e &&& f)) = 1 * (f ^^^  ~~~( ~~~d &&& (e &&& f)))

theorem add_or_and_commutative_proof : add_or_and_commutative_before ⊑ add_or_and_commutative_after

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

theorem t9_ashr_exact_flag_preservation_proof : t9_ashr_exact_flag_preservation_before ⊑ t9_ashr_exact_flag_preservation_after

theorem land_lor_left1_proof : land_lor_left1_before ⊑ land_lor_left1_after

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

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

theorem two_signed_truncation_checks_logical_proof : two_signed_truncation_checks_logical_before ⊑ two_signed_truncation_checks_logical_after

theorem mul_unkV_oddC_eq_proof : mul_unkV_oddC_eq_before ⊑ mul_unkV_oddC_eq_after

theorem bar_thm.extracted_1._2 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ¬ofBool (x_2 <ₛ x_1) = 1#1 →
    x_3 &&& (signExtend 32 (ofBool (x_2 <ₛ x_1)) ^^^ -1#32) ||

theorem n2_badmask_proof : n2_badmask_before ⊑ n2_badmask_after

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

theorem e_706 :
    4 *  ~~~(x &&& y) + 4 * (x ^^^ y) + 4 *  ~~~x + 11 * (x |||  ~~~y) - 7 * y + 4 *  ~~~(x &&&  ~~~y) - 16 *  ~~~(x ||| y) - 9 *  ~~~(x |||  ~~~y) - 12 * (x &&&  ~~~y) - 8 * (x &&& y) = 7 *  ~~~y

theorem e_1734 :
    3 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 6 *  ~~~(a ^^^ (b &&& c)) - 2 * ( ~~~b ||| (a ^^^ c)) + 2 * (a &&& ( ~~~b ||| c)) + 1 *  ~~~c - 1 * (a &&& (b ||| c)) + 1 * (b ^^^ ( ~~~a ||| (b &&& c))) + 5 * (c ^^^ (a ||| ( ~~~b ||| c))) - 6 *  ~~~(a |||  ~~~b) - 2 * (c |||  ~~~(a ^^^ b)) - 3 * ( ~~~b &&& (a ^^^ c)) + 2 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 3 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) - 5 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) - 1 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) - 1 *  ~~~( ~~~a ||| (b &&& c)) - 6 * ( ~~~(a &&& b) &&&  ~~~(b ^^^ c)) - 1 * (b ^^^ ( ~~~a ||| (b ||| c))) + 1 * ( ~~~(a ||| b) ||| (b ^^^ c)) - 2 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) - 7 * ( ~~~a ||| ( ~~~b ||| c)) + 3 * (c ^^^  ~~~(a &&& (b &&& c))) + 1 *  ~~~(a ^^^ ( ~~~b ||| c)) + 11 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) + 18 *  ~~~(a ||| (b ||| c)) + 18 *  ~~~(a ||| ( ~~~b ||| c)) - 6 *  ~~~( ~~~a ||| (b ||| c)) - 7 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 13 * ( ~~~a &&& ( ~~~b &&& c)) + 18 * ( ~~~a &&& (b &&& c)) + 11 * (a &&& ( ~~~b &&& c)) + 11 * (a &&& (b &&& c)) = 2 * ((b &&& c) ||| ( ~~~a &&& (b ||| c)))

theorem tryFactorization_add_nuw_mul_nuw_int_max_proof : tryFactorization_add_nuw_mul_nuw_int_max_before ⊑ tryFactorization_add_nuw_mul_nuw_int_max_after

theorem lshr_add_xor_fail_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(1#8 ≥ ↑8 ∨ 1#8 ≥ ↑8) → 1#8 ≥ ↑8 ∨ 1#8 ≥ ↑8 ∨ True ∧ (x >>> 1#8).uaddOverflow 123#8 = true → False

theorem xor_sub :
    [llvm(w)| {
  ^bb0(%X : _, %Y : _):
    %v1 = llvm.sub %X, %X
    %r = llvm.xor %v1, %Y
    llvm.return %r
  }] ⊑  [llvm(w)| {
  ^bb0(%X : _, %Y : _):
    llvm.return %Y
  }]

theorem ashr_ult_2_proof : ashr_ult_2_before ⊑ ashr_ult_2_after

theorem test3_proof : test3_before ⊑ test3_after

theorem gt_unsigned_to_small_negative_proof : gt_unsigned_to_small_negative_before ⊑ gt_unsigned_to_small_negative_after

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

theorem test55_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ (truncate 16 x &&& 7224#16 &&& BitVec.ofInt 16 (-32574) != 0) = true) →
    signExtend 64 ((truncate 16 x ||| BitVec.ofInt 16 (-32574)) &&& BitVec.ofInt 16 (-25350)) =
      signExtend 64 (truncate 16 x &&& 7224#16 ||| BitVec.ofInt 16 (-32574))

theorem demorgan_nor_use2bc_proof : demorgan_nor_use2bc_before ⊑ demorgan_nor_use2bc_after

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

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

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

theorem not_ashr_const_proof : not_ashr_const_before ⊑ not_ashr_const_after

theorem and_or_not_not_commute6_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬((x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true ∨
        (x_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 → False

theorem R.fromTensorFinsupp_concat_monomial (c : Int) (cs : List Int) :
    (R.fromTensorFinsupp q (cs ++ [c])) =
      (R.fromTensorFinsupp q cs) +
        (Polynomial.monomial cs.length (Int.cast c : (ZMod q)))

theorem not_cond_proof : not_cond_before ⊑ not_cond_after

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

theorem test58_thm (e : IntW 64) :
  zext 64 (LLVM.or (lshr (trunc 32 e) (const? 32 8)) (const? 32 128)) ⊑
    zext 64 (LLVM.or (lshr (trunc 32 e) (const? 32 8)) (const? 32 128)) { «nneg» := true }

theorem ashrslt_03_12_proof : ashrslt_03_12_before ⊑ ashrslt_03_12_after

theorem no_reassoc_add_nuw_none_proof : no_reassoc_add_nuw_none_before ⊑ no_reassoc_add_nuw_none_after

theorem icmp_shl_ule_2_proof : icmp_shl_ule_2_before ⊑ icmp_shl_ule_2_after

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

theorem test_negative_combined_sub_signed_overflow_proof : test_negative_combined_sub_signed_overflow_before ⊑ test_negative_combined_sub_signed_overflow_after

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

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

theorem scalar_i64_signbit_lshr_and_eq_thm.extracted_1._1 : ∀ (x x_1 : BitVec 64),
  ¬x_1 ≥ ↑64 →
    True ∧ BitVec.ofInt 64 (-9223372036854775808) >>> x_1 <<< x_1 ≠ BitVec.ofInt 64 (-9223372036854775808) ∨ x_1 ≥ ↑64 →
      False

theorem eq_210_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(16#32 ≥ ↑32 ∨ 16#32 ≥ ↑32 ∨ 8#32 ≥ ↑32 ∨ 8#32 ≥ ↑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 (truncate 24 x_1 == truncate 24 x)

theorem or_logic_or_logic_and_8_thm.extracted_1._3 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 → ¬True → x ||

theorem lshr_and_proof : lshr_and_before ⊑ lshr_and_after

theorem test3_thm (e e_1 : IntW 32) : LLVM.and e_1 (LLVM.and e e_1) ⊑ LLVM.and e e_1

theorem mul_five (x : BitVec w) : 5 * x = x + x + x + x + x

theorem t1_proof : t1_before ⊑ t1_after

theorem t0_proof : t0_before ⊑ t0_after

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

theorem test13_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32) →
    ¬8#32 ≥ ↑32 → (x_1 - x <<< 8#32 &&& 128#32) * x <<< 8#32 = (x_1 &&& 128#32) * x <<< 8#32

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

theorem bitwise_and_bitwise_and_icmps_comm1_proof : bitwise_and_bitwise_and_icmps_comm1_before ⊑ bitwise_and_bitwise_and_icmps_comm1_after

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

theorem logical_or_bitwise_or_icmps_comm3_proof : logical_or_bitwise_or_icmps_comm3_before ⊑ logical_or_bitwise_or_icmps_comm3_after

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

theorem test_shift_negative_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧
          ((x_1 ||| BitVec.ofInt 32 (-2147483648)) <<< (x &&& 7#32)).sshiftRight' (x &&& 7#32) ≠
            x_1 ||| BitVec.ofInt 32 (-2147483648) ∨
        x &&& 7#32 ≥ ↑32) →
    ofBool ((x_1 ||| BitVec.ofInt 32 (-2147483648)) <<< (x &&& 7#32) <ₛ 0#32) = 1#1

theorem test_mul_nsw__nuw_is_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 268435457)) (const? 32 268435456)) (const? 32 (-1879048192))
      (mul (LLVM.and e (const? 32 268435457)) (const? 32 9) { «nsw» := true, «nuw» := false }) ⊑
    mul (LLVM.and e (const? 32 268435457)) (const? 32 9) { «nsw» := false, «nuw» := true }

theorem or_basic_commuted_proof : or_basic_commuted_before ⊑ or_basic_commuted_after

theorem max_of_min_proof : max_of_min_before ⊑ max_of_min_after

theorem ashrsgt_01_01_exact_proof : ashrsgt_01_01_exact_before ⊑ ashrsgt_01_01_exact_after

theorem sub_ult_zext_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 x_2 : BitVec 8),
  ofBool (x_2 - x_1 <ᵤ zeroExtend 8 x) = ofBool (x_2 == x_1) &&& x

theorem ashrslt_01_06_proof : ashrslt_01_06_before ⊑ ashrslt_01_06_after

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

theorem lshr_pow2_sgt_proof : lshr_pow2_sgt_before ⊑ lshr_pow2_sgt_after

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

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

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

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

theorem shrink_and_proof : shrink_and_before ⊑ shrink_and_after

theorem masked_bit_wrong_pred_proof : masked_bit_wrong_pred_before ⊑ masked_bit_wrong_pred_after

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

@[simp]
theorem mem_mkLowerTriangularPairs₂  {n : Nat} {ij :  Nat × Nat} :
  (ij ∈ mkLowerTriangularPairs n) ↔
  (ij.1 < ij.2 ∧ ij.2 ≤ n)

theorem test6_proof : test6_before ⊑ test6_after

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

theorem shl_nsw_nuw_proof : shl_nsw_nuw_before ⊑ shl_nsw_nuw_after

theorem lshrugt_03_08_proof : lshrugt_03_08_before ⊑ lshrugt_03_08_after

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

theorem test1_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬8#32 ≥ ↑32 →
    ¬8#16 ≥ ↑16 → truncate 16 (zeroExtend 32 x >>> 8#32 ||| zeroExtend 32 x * 5#32) = x >>> 8#16 ||

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

theorem e_1742 :
    1 *  ~~~(a ^^^ (b &&& c)) - 11 * ( ~~~b &&&  ~~~(a ^^^ c)) + 2 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 * (b ^^^ ( ~~~a ||| (b ||| c))) - 1 * (c ^^^ (a &&&  ~~~b)) + 5 * (a ^^^ (b ^^^ c)) - 1 * (c ^^^ (a ||| (b &&& c))) + 7 *  ~~~( ~~~a &&& (b &&& c)) + 1 * (b |||  ~~~(a |||  ~~~c)) - 2 * (b ^^^ (a ||| c)) + 1 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 1 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) - 1 * (b &&& (a ||| c)) - 2 * ((a &&& c) |||  ~~~(b ||| c)) + 3 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) - 7 * ( ~~~b ||| (a ^^^ c)) - 5 *  ~~~(a ^^^ ( ~~~b &&& c)) + 4 * (c &&& (a |||  ~~~b)) - 2 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) - 1 * (b ^^^ (a ||| (b &&& c))) - 3 *  ~~~( ~~~a &&& ( ~~~b &&& c)) - 7 * (a ^^^ c) - 5 * (c ^^^ (a ||| (b ||| c))) + 1 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) - 7 * (b ||| (a &&&  ~~~c)) + 14 *  ~~~(a ||| (b ||| c)) + 3 *  ~~~(a ||| ( ~~~b ||| c)) + 20 *  ~~~( ~~~a ||| (b ||| c)) + 17 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 4 * ( ~~~a &&& ( ~~~b &&& c)) + 28 * ( ~~~a &&& (b &&& c)) + 10 * (a &&& ( ~~~b &&& c)) - 7 * (a &&& (b &&& c)) =  - 2 * (a &&& (b ||| c)) - 1 * (b ^^^  ~~~(a &&& (b ^^^ c)))

theorem zext_add_scalar_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → zeroExtend 32 x + 42#32 = 42#32

theorem fold_sext_to_and1_thm (e : IntW 8) :
  icmp IntPred.ne (LLVM.and (sext 32 e) (const? 32 (-2147483647))) (const? 32 1) ⊑
    icmp IntPred.ne (LLVM.and e (const? 8 (-127))) (const? 8 1)

theorem lshrult_02_11_exact_proof : lshrult_02_11_exact_before ⊑ lshrult_02_11_exact_after

theorem e_298 :
    1 * y - 7 * (x ^^^ y) + 1 *  ~~~(x &&& y) + 11 *  ~~~y - 12 *  ~~~(x ||| y) - 5 * (x &&&  ~~~y) - 1 * (x &&& y) =  - 5 *  ~~~(x |||  ~~~y)

theorem set_to_set_decomposebittest_proof : set_to_set_decomposebittest_before ⊑ set_to_set_decomposebittest_after

theorem ashr_16_add_zext_basic_thm (e e_1 : IntW 16) :
  lshr (add (zext 32 e_1) (zext 32 e)) (const? 32 16) ⊑
    zext 32 (icmp IntPred.ugt e (LLVM.xor e_1 (const? 16 (-1))))

theorem lshrugt_03_10_proof : lshrugt_03_10_before ⊑ lshrugt_03_10_after

theorem test13_proof : test13_before ⊑ test13_after

theorem test_slt_thm (e : IntW 16) (e_1 : IntW 32) :
  icmp IntPred.slt (trunc 8 e_1 { «nsw» := true, «nuw» := false }) (trunc 8 e { «nsw» := true, «nuw» := false }) ⊑
    icmp IntPred.slt e_1 (sext 32 e)

theorem ashr_ugt_5_proof : ashr_ugt_5_before ⊑ ashr_ugt_5_after

theorem test4_logical_proof : test4_logical_before ⊑ test4_logical_after

theorem or_eq_with_one_bit_diff_constants1_logical_proof : or_eq_with_one_bit_diff_constants1_logical_before ⊑ or_eq_with_one_bit_diff_constants1_logical_after

theorem uge_or_not_max_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 != -1#8) ||

theorem shl_or_with_or_disjoint_instead_of_add_thm (e : IntW 8) :
  LLVM.or (shl (const? 8 16) e) (shl (const? 8 3) (LLVM.or e (const? 8 1) { «disjoint» := true })) ⊑
    shl (const? 8 22) e

theorem t0_thm (e e_1 : IntW 32) :
  lshr (lshr e_1 (sub (const? 32 32) e)) (add e (const? 32 (-2))) { «exact» := true } ⊑ lshr e_1 (const? 32 30)

theorem and_not_or_commute9_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 == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true ∨
            (x_1 == 0 || 32 != 1 && 42#32 == intMin 32 && x_1 == -1) = true ∨
              (x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true ∨
                (x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true) →
    ¬((x_1 == 0 || 32 != 1 && 42#32 == intMin 32 && x_1 == -1) = true ∨
          (x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true ∨
            (x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true) →
      ((42#32).sdiv x_2 &&& (42#32).sdiv x_1 ^^^ -1#32 ||| (42#32).sdiv x) &&&
          ((42#32).sdiv x_1 ||| (42#32).sdiv x_2 &&& (42#32).sdiv x ^^^ -1#32) =
        ((42#32).sdiv x_1 ^^^ (42#32).sdiv x) &&& (42#32).sdiv x_2 ^^^ -1#32

theorem append_valid {Γ₁ Γ₂ Γ₃  : Ctxt Ty} {d₁ d₂ : Nat} :
  Diff.Valid Γ₁ Γ₂ d₁ →  Diff.Valid Γ₂ Γ₃ d₂ → Diff.Valid Γ₁ Γ₃ (d₁ + d₂)

theorem e_592 :
     - 1 * (x |||  ~~~y) + 1 * (x ||| y) - 5 *  ~~~(x &&& y) + 1 *  ~~~(x &&&  ~~~y) + 2 *  ~~~y + 7 * (x ^^^ y) + 14 *  ~~~(x ||| y) + 7 *  ~~~(x |||  ~~~y) + 8 * (x &&&  ~~~y) + 11 * (x &&& y) = 1 * x + 11 *  ~~~(x &&&  ~~~x)

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

theorem bv_AddSub_1176 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.add e (LLVM.sub (LLVM.const? w 0) e_1) ⊑ LLVM.sub e e_1

theorem ashrsgt_02_14_proof : ashrsgt_02_14_before ⊑ ashrsgt_02_14_after

theorem eq_nsw_rem_nz_proof : eq_nsw_rem_nz_before ⊑ eq_nsw_rem_nz_after

theorem n2_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬15#32 ≥ ↑32 → zeroExtend 32 x <<< 15#32 &&& BitVec.ofInt 32 (-2147483648) = 0#32

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

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

theorem select_ashr_thm.extracted_1._3 : ∀ (x x_1 : BitVec 128) (x_2 : BitVec 1), ¬x_2 = 1#1 → 0#128 ≥ ↑128 → False

@[simp] lemma swapLastTwoBlock_n {n : Nat} : swapLastTwoBlock (n := n) n = n + 1

@[simp, simp_denote, simp_sllvm]
lemma run_ub : StateT.run (throwUB : EffectM α) s = .poison

theorem slt_positive_multip_rem_zero_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.smulOverflow 7#8 = true) → ofBool (x * 7#8 <ₛ 21#8) = ofBool (x <ₛ 3#8)

theorem alive_AndOrXor_2658 : alive_AndOrXor_2658_src ⊑ alive_AndOrXor_2658_tgt

theorem logical_and_logical_and_icmps_comm3_thm.extracted_1._3 : ∀ (x x_1 x_2 : BitVec 8),
  ¬x_1 ≥ ↑8 →
    ofBool (x_2 &&& 1#8 <<< x_1 != 0#8) = 1#1 ∧ ofBool (x_2 &&& 1#8 != 0#8) = 1#1 →
      ¬(True ∧ 1#8 <<< x_1 >>> x_1 ≠ 1#8 ∨ x_1 ≥ ↑8 ∨ True ∧ 1#8 <<< x_1 >>> x_1 ≠ 1#8 ∨ x_1 ≥ ↑8) →
        ¬ofBool (x_2 &&& (1#8 <<< x_1 ||| 1#8) == 1#8 <<< x_1 ||| 1#8) = 1#1 → ofBool (x == 42#8) = 0#1

theorem not_match_inconsistent_values_proof : not_match_inconsistent_values_before ⊑ not_match_inconsistent_values_after

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

theorem t2_ashr_thm (e : IntW 8) (e_1 : IntW 32) :
  ashr e_1 (sext 32 e) ⊑ ashr e_1 (zext 32 e { «nneg» := true })

theorem Factor.reflect_eq_reflectFin {f : Factor} {xs : List (BitVec w)} {xsFin : EnvFin w f.numVars}
    (h : ∀ (i : Fin f.numVars), xs[i]?.getD 0#w = xsFin i) :
    f.reflect xs = f.reflectFin xsFin

theorem and_zext_eq_odd_thm.extracted_1._1 : ∀ (x : BitVec 32),
  x &&& zeroExtend 32 (ofBool (x == 3#32)) = zeroExtend 32 (ofBool (x == 3#32))

theorem PR60818_eq_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (0#32 - x == x) = ofBool (x &&& 2147483647#32 == 0#32)

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

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

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

theorem slt_and_not_max_logical_proof : slt_and_not_max_logical_before ⊑ slt_and_not_max_logical_after

theorem test_thm.extracted_1._1 : ∀ (x : BitVec 64), zeroExtend 64 (truncate 32 x) = x &&& 4294967295#64

@[simp] lemma composeBinary_eval
    (p : FSM Bool)
    {t₁ t₂ : Term}
    (q₁ : FSMTermSolution t₁)
    (q₂ : FSMTermSolution t₂)
    (x : Fin (max t₁.arity t₂.arity) → BitStream) :
    (composeBinary p q₁ q₂).eval x = p.eval
      (λ b => cond b (t₁.evalFin (fun i => x (Fin.castLE (by simp) i)))
                  (t₂.evalFin (fun i => x (Fin.castLE (by simp) i))))

theorem icmp_uge_x_y_2_thm (e e_1 : IntW 8) :
  icmp IntPred.ule (mul e_1 e_1) (LLVM.and (mul e_1 e_1) e) ⊑
    icmp IntPred.eq (LLVM.and (mul e_1 e_1) e) (mul e_1 e_1)

theorem test6_thm.extracted_1._1 : ∀ (x : BitVec 8), x ^^^ 17#8 ^^^ 17#8 = x

theorem ashrsgt_02_15_exact_proof : ashrsgt_02_15_exact_before ⊑ ashrsgt_02_15_exact_after

theorem add_mask_ashr27_i32_proof : add_mask_ashr27_i32_before ⊑ add_mask_ashr27_i32_after

theorem and_ashr_not_thm (e e_1 e_2 : IntW 8) :
  LLVM.and (ashr e_2 e_1) (LLVM.xor (ashr e e_1) (const? 8 (-1))) ⊑
    ashr (LLVM.and e_2 (LLVM.xor e (const? 8 (-1)))) e_1

theorem Tensor2d'.fill_extract (δ₀ δ₁ sz₀ sz₁ : ℕ) (t : Tensor2d' α) (v : β) :
  (t.fill v).extract δ₀ δ₁ sz₀ sz₁ = (t.extract δ₀ δ₁ sz₀ sz₁).fill v

theorem uge_umin1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 <ᵤ x) = 1#1 → ofBool (x_1 ≤ᵤ x_1) = ofBool (x_1 ≤ᵤ x)

theorem sub_ashr_and_i32_proof : sub_ashr_and_i32_before ⊑ sub_ashr_and_i32_after

theorem test29_thm.extracted_1._1 : ∀ (x : BitVec 8), zeroExtend 32 x &&& 255#32 = zeroExtend 32 x

theorem main13_logical_thm.extracted_1._1 : ∀ (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 → 1#32 = 2#32

theorem main3e_like_proof : main3e_like_before ⊑ main3e_like_after

theorem foo1_and_signbit_lshr_without_shifting_signbit_both_sides_thm (e e_1 e_2 : IntW 32) :
  LLVM.or (icmp IntPred.sgt (shl e_2 e_1) (const? 32 (-1))) (icmp IntPred.sgt (shl e_2 e) (const? 32 (-1))) ⊑
    icmp IntPred.sgt (LLVM.and (shl e_2 e_1) (shl e_2 e)) (const? 32 (-1))

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

theorem test4_thm.extracted_1._2 : ∀ (x : BitVec 1023),
  ofBool (x <ₛ 0#1023) = 1#1 → ¬1022#1023 ≥ ↑1023 → -1#1023 = x.sshiftRight' 1022#1023

theorem invert_both_cmp_operands_sub_proof : invert_both_cmp_operands_sub_before ⊑ invert_both_cmp_operands_sub_after

theorem le_thm (e e_1 : IntW 32) :
  icmp IntPred.sle
      (select (icmp IntPred.slt e_1 e) (const? 32 (-1))
        (select (icmp IntPred.sgt e_1 e) (const? 32 1) (const? 32 0)))
      (const? 32 0) ⊑
    icmp IntPred.sle e_1 e

theorem icmp_shl_uge_2_proof : icmp_shl_uge_2_before ⊑ icmp_shl_uge_2_after

theorem test73_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (-1#8 <ₛ truncate 8 x) = 1#1 → ofBool (x &&& 128#32 == 0#32) = 1#1 → 42#32 = 40#32

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

theorem logical_and_logical_and_icmps_comm1_proof : logical_and_logical_and_icmps_comm1_before ⊑ logical_and_logical_and_icmps_comm1_after

theorem drop_nuw_trunc_proof : drop_nuw_trunc_before ⊑ drop_nuw_trunc_after

theorem shl_add_add_thm (e e_1 : IntW 8) :
  add (shl e_1 (const? 8 2)) (add (shl e (const? 8 2)) (const? 8 48)) ⊑
    add (shl (add e e_1) (const? 8 2)) (const? 8 48)

theorem icmp_equality_test_commute_icmp2_proof : icmp_equality_test_commute_icmp2_before ⊑ icmp_equality_test_commute_icmp2_after

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

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

theorem narrow_zext_mul_proof : narrow_zext_mul_before ⊑ narrow_zext_mul_after

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

theorem multiuse3_proof : multiuse3_before ⊑ multiuse3_after

theorem negate_lshr_proof : negate_lshr_before ⊑ negate_lshr_after

theorem e_1638 :
    2 * (a ^^^ (b &&& c)) + 2 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 6 * (c &&&  ~~~(a ^^^ b)) - 5 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) + 1 * (a ^^^ ( ~~~b &&& c)) - 7 * ((a &&& c) ||| (b &&&  ~~~c)) + 1 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) - 1 * ( ~~~a &&& (b ^^^ c)) + 1 * (a |||  ~~~b) - 5 * (b ^^^ (a ||| (b ^^^ c))) + 2 * ( ~~~b &&& (a ^^^ c)) + 3 * (c |||  ~~~(a ^^^ b)) - 1 *  ~~~(b ||| c) + 2 * ((b &&&  ~~~c) ^^^ (a ||| (b ^^^ c))) - 2 * (b ^^^ (a &&& (b ^^^ c))) - 6 *  ~~~(a ||| (b ||| c)) + 14 *  ~~~(a ||| ( ~~~b ||| c)) - 7 *  ~~~( ~~~a ||| (b ||| c)) - 8 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 6 * ( ~~~a &&& ( ~~~b &&& c)) - 6 * ( ~~~a &&& (b &&& c)) + 8 * (a &&& (b &&& c)) =  - 6 * (a &&& ( ~~~b &&& c)) - 7 * (c ^^^ (a ||| ( ~~~b &&& c)))

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

theorem icmp_ne_sext_ne_otherwise_i128_proof : icmp_ne_sext_ne_otherwise_i128_before ⊑ icmp_ne_sext_ne_otherwise_i128_after

theorem shl_add_add_fail_thm (e e_1 : IntW 8) :
  add (lshr e_1 (const? 8 2)) (add (lshr e (const? 8 2)) (const? 8 48)) ⊑
    add (lshr e_1 (const? 8 2)) (add (lshr e (const? 8 2)) (const? 8 48) { «nsw» := true, «nuw» := true })
      { «nsw» := false, «nuw» := true }

theorem ne_umin1_proof : ne_umin1_before ⊑ ne_umin1_after

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

theorem cv2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ¬x_1 ≥ ↑8 → ofBool ((-1#8) >>> x_1 &&& x ≤ᵤ x) = 1#1

theorem max_sub_ugt_c0_proof : max_sub_ugt_c0_before ⊑ max_sub_ugt_c0_after

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

theorem test1_proof : test1_before ⊑ test1_after

theorem shl_xor_xor_good_mask_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(1#8 ≥ ↑8 ∨ 1#8 ≥ ↑8) → ¬1#8 ≥ ↑8 → x_1 <<< 1#8 ^^^ (x <<< 1#8 ^^^ 88#8) = (x ^^^ x_1) <<< 1#8 ^^^ 88#8

theorem or_xor_tree_1111_proof : or_xor_tree_1111_before ⊑ or_xor_tree_1111_after

theorem and_not_or_commute8_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_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) →
      ((42#32).sdiv x_2 &&& (42#32).sdiv x_1 ^^^ -1#32 ||| x) &&&
          ((42#32).sdiv x_1 ||| x &&& (42#32).sdiv x_2 ^^^ -1#32) =
        ((42#32).sdiv x_1 ^^^ x) &&& (42#32).sdiv x_2 ^^^ -1#32

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

theorem icmp_ugt_32_proof : icmp_ugt_32_before ⊑ icmp_ugt_32_after

theorem test_sub__none_are_safe_proof : test_sub__none_are_safe_before ⊑ test_sub__none_are_safe_after

theorem ashr_eq_noexact_thm (e : IntW 8) :
  icmp IntPred.eq (ashr e (const? 8 3)) (const? 8 10) ⊑
    icmp IntPred.eq (LLVM.and e (const? 8 (-8))) (const? 8 80)

theorem mul_selectp2_x_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 1), x_1 = 1#1 → 1#8 ≥ ↑8 → False

theorem mkPostcondIndHypNoCycleBreaking_eq_false_iff
    {circs : KInductionCircuits fsm n}
    (hCircs : circs.IsLawful)
    (env : Vars fsm.α arity (n + 2) → Bool) :
    ((mkPostcondIndHypNoCycleBreaking circs).eval env = false) ↔
    ((∀ (i : Nat) (hi : i < n + 1), env (Vars.outputs ⟨i, by omega⟩) = false) →
    env (Vars.outputs ⟨n + 1, by omega⟩) = false)

theorem e_1748 :
     - 7 * (c ||| (a ^^^ b)) - 1 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) - 5 * b + 1 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) + 2 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 3 * (b ^^^ (a ||| c)) + 1 * (c ^^^ (a ||| (b ||| c))) + 11 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 1 * (a |||  ~~~b) - 1 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) + 2 * (c |||  ~~~(a ||| b)) - 5 * (b ^^^ (a &&& c)) + 7 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 4 * (a ^^^ (b &&& c)) - 2 *  ~~~(b ^^^ c) + 11 * (a &&& (b ||| c)) + 3 *  ~~~(b &&& c) + 5 * ((a ||| b) &&&  ~~~(b ^^^ c)) - 5 * ( ~~~a ||| ( ~~~b &&& c)) + 11 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) - 7 * (b |||  ~~~c) + 2 * (b &&&  ~~~c) + 2 * (a ||| (b ^^^ c)) - 11 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) + 2 * (b &&& (a ^^^ c)) + 11 * (b ^^^ ( ~~~a ||| (b &&& c))) + 1 * (c &&& (a ^^^ b)) - 1 *  ~~~( ~~~a &&& (b &&& c)) + 16 *  ~~~(a ||| ( ~~~b ||| c)) - 20 *  ~~~( ~~~a ||| (b ||| c)) - 5 * ( ~~~a &&& ( ~~~b &&& c)) + 22 * ( ~~~a &&& (b &&& c)) - 36 * (a &&& ( ~~~b &&& c)) - 3 * (a &&& (b &&& c)) = 39 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 13 *  ~~~(a ||| (b ||| c))

theorem a_false_implies_b_false2_comm_proof : a_false_implies_b_false2_comm_before ⊑ a_false_implies_b_false2_comm_after

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

theorem n0_thm (e : IntW 8) :
  icmp IntPred.ult (LLVM.and e (const? 8 4)) e ⊑
    icmp IntPred.ne (LLVM.and e (const? 8 (-5))) (const? 8 0)

theorem sel_false_val_is_a_masked_lshr_of_true_val1_proof : sel_false_val_is_a_masked_lshr_of_true_val1_before ⊑ sel_false_val_is_a_masked_lshr_of_true_val1_after

theorem p1_scalar_urem_by_nonconst_proof : p1_scalar_urem_by_nonconst_before ⊑ p1_scalar_urem_by_nonconst_after

theorem icmp_ult_x_y_2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 * x_1 &&& x <ᵤ x_1 * x_1) = ofBool (x_1 * x_1 &&& x != x_1 * x_1)

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

theorem cmpne_xor_cst3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 ^^^ 10#32 != x ^^^ 10#32) = ofBool (x_1 != x)

theorem not_neg_eq_sub_one (x : BitVec w) :
    ~~~ (- x) = x - 1

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

theorem shl_or_disjoint_lshr_comm_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ x_1 <<< x >>> x ≠ x_1 ∨ x ≥ ↑32 ∨ True ∧ (x_2 &&& x_1 <<< x != 0) = true ∨ x ≥ ↑32) →
    ¬(x ≥ ↑32 ∨ True ∧ (x_2 >>> x &&& x_1 != 0) = true) → (x_2 ||| x_1 <<< x) >>> x = x_2 >>> x ||

theorem mullo_variant3_proof : mullo_variant3_before ⊑ mullo_variant3_after

theorem is_ascii_alphabetic_inverted_thm (e : IntW 32) :
  select (icmp IntPred.ult (add e (const? 32 (-91)) { «nsw» := true, «nuw» := false }) (const? 32 (-26)))
      (icmp IntPred.ult (add e (const? 32 (-123)) { «nsw» := true, «nuw» := false }) (const? 32 (-26)))
      (const? 1 0) ⊑
    icmp IntPred.ult (add (LLVM.and e (const? 32 (-33))) (const? 32 (-91))) (const? 32 (-26))

theorem lshr_exact_add_nuw_proof : lshr_exact_add_nuw_before ⊑ lshr_exact_add_nuw_after

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

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

theorem decideIfZerosAux_correct {arity : Type _} [DecidableEq arity]
    (p : FSM arity) (c : Circuit p.α)
    (hc : ∀ s, c.eval s = true →
      ∃ m y, (p.changeInitCarry s).eval y m = true)
    (hc₂ : ∀ (x : arity → Bool) (s : p.α → Bool),
      (FSM.nextBit p s x).snd = true → Circuit.eval c s = true) :
    decideIfZerosAux p c = true ↔ ∀ n x, p.eval x n = false

theorem ashrslt_01_01_proof : ashrslt_01_01_before ⊑ ashrslt_01_01_after

theorem test2_proof : test2_before ⊑ test2_after

theorem e_1270 :
     - 7 * (z ||| t) + 2 *  ~~~(z &&&  ~~~z) + 3 *  ~~~(z &&& t) + 1 *  ~~~t + 11 *  ~~~z - 5 *  ~~~(z &&&  ~~~t) - 4 *  ~~~(z |||  ~~~t) - 4 * (z &&&  ~~~t) + 5 * (z &&& t) = 17 *  ~~~(z ||| t) - 5 * (z |||  ~~~t)

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

theorem eq_smax4_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 + 3#32 <ₛ x) = 1#1 → ofBool (x_1 + 3#32 == x) = ofBool (x ≤ₛ x_1 + 3#32)

@[simp] lemma eval_scanAnd (x : Unit → BitStream) : scanAnd.eval x = (x ()).scanAnd

theorem bor_lor_left1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), ¬x_1 ||

theorem masked_or_allones_proof : masked_or_allones_before ⊑ masked_or_allones_after

theorem basic_preserve_nsw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ (x_1 ^^^ -1#8).saddOverflow x = true) → True ∧ x_1.ssubOverflow x = true → False

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

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

theorem land_lor_left2_proof : land_lor_left2_before ⊑ land_lor_left2_after

theorem test1_proof : test1_before ⊑ test1_after

theorem xor_i8_to_i64_shl_save_and_ne_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 8),
  ofBool (x_1 &&& 1#8 != 0#8) = 1#1 →
    ¬63#64 ≥ ↑64 → x ^^^ BitVec.ofInt 64 (-9223372036854775808) = x ^^^ zeroExtend 64 x_1 <<< 63#64

theorem eq_21_comm_and_proof : eq_21_comm_and_before ⊑ eq_21_comm_and_after

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

theorem main2_logical_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 1#32 == 0#32) = 1#1 →
    ofBool (x &&& 2#32 == 0#32) = 1#1 → 0#32 = zeroExtend 32 (ofBool (x &&& 3#32 == 3#32))

theorem e_1841 :
    3 * ((a &&& b) |||  ~~~(b ^^^ c)) - 2 * c - 11 *  ~~~(a &&& b) + 2 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 7 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) + 4 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) + 5 * ((a &&& b) |||  ~~~(b |||  ~~~c)) + 5 * a - 7 * (a &&& (b ||| c)) + 3 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) + 1 * (b &&& (a |||  ~~~c)) + 2 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) - 7 * (c ^^^  ~~~(a &&& ( ~~~b ||| c))) - 6 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) + 11 * (b &&&  ~~~(a ^^^ c)) + 1 * (b &&&  ~~~c) - 6 * (c |||  ~~~(a ^^^ b)) + 2 * (a ||| b) - 1 *  ~~~a - 5 * (b ^^^ ( ~~~a ||| (b &&& c))) + 1 * (b ^^^  ~~~(a ||| c)) + 2 * (c ^^^  ~~~(a &&& b)) - 1 * ((a &&& b) ^^^ (a ^^^ ( ~~~b ||| c))) + 4 * ( ~~~c ||| (a ^^^ b)) - 2 * (c &&& (a ^^^ b)) - 7 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 11 * (c ||| (a ^^^ b)) + 1 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 1 * ( ~~~b &&&  ~~~(a ^^^ c)) - 3 * (a &&& ( ~~~b ||| c)) - 2 * (b ^^^ (a |||  ~~~c)) - 6 * (a ||| (b &&& c)) - 2 * (b |||  ~~~c) - 1 * (b |||  ~~~(a |||  ~~~c)) - 2 * (b ^^^  ~~~(a &&&  ~~~c)) - 1 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 11 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 34 *  ~~~(a ||| (b ||| c)) - 12 *  ~~~(a ||| ( ~~~b ||| c)) + 2 *  ~~~( ~~~a ||| (b ||| c)) + 24 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 11 * ( ~~~a &&& ( ~~~b &&& c)) + 23 * ( ~~~a &&& (b &&& c)) - 18 * (a &&& (b &&& c)) =  - 24 * (a &&& ( ~~~b &&& c))

theorem trunc_shl_15_i16_i64_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬15#64 ≥ ↑64 → ¬15#16 ≥ ↑16 → truncate 16 (x <<< 15#64) = truncate 16 x <<< 15#16

theorem bools_logical_commute1_and2_proof : bools_logical_commute1_and2_before ⊑ bools_logical_commute1_and2_after

theorem or_test2_thm (e : IntW 7) : LLVM.or (shl e (const? 7 6)) (const? 7 (-64)) ⊑ const? 7 (-64)

theorem ule_bignum_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x * -1#8 ≤ᵤ 0#8) = ofBool (x == 0#8)

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

theorem is_ascii_alphabetic_proof : is_ascii_alphabetic_before ⊑ is_ascii_alphabetic_after

@[simp] theorem Hom.appendCodomain_apply (f : Γ.Hom Δ) (v : Γ.Var t) :
    (f.appendCodomain (ts := ts)) v = (f v).appendInr

theorem trunc_sandwich_max_sum_shift_proof : trunc_sandwich_max_sum_shift_before ⊑ trunc_sandwich_max_sum_shift_after

theorem sdiv_mul_shl_nsw_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 5),
  ¬(True ∧ x_2.smulOverflow x_1 = true ∨
        True ∧ (x_2 <<< x).sshiftRight' x ≠ x_2 ∨
          x ≥ ↑5 ∨ (x_2 <<< x == 0 || 5 != 1 && x_2 * x_1 == intMin 5 && x_2 <<< x == -1) = true) →
    True ∧ 1#5 <<< x >>> x ≠ 1#5 ∨ x ≥ ↑5 ∨ (1#5 <<< x == 0 || 5 != 1 && x_1 == intMin 5 && 1#5 <<< x == -1) = true →
      False

theorem lsb_mask_sign_sext_commuted_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 ashrsgt_03_07_exact_thm (e : IntW 4) :
  icmp IntPred.sgt (ashr e (const? 4 3) { «exact» := true }) (const? 4 7) ⊑ const? 1 0

theorem lshrult_01_07_exact_proof : lshrult_01_07_exact_before ⊑ lshrult_01_07_exact_after

theorem isMonotone_matchVarArg_aux (lets : Lets d Γ_in eff Γ_out) :
    (
     ∀  (Δ_out : Ctxt d.Ty)
        (matchLets : Lets d Δ_in EffectKind.pure Δ_out) (l : List d.Ty)
        (argsl : HVector Γ_out.Var l) (argsr : HVector Δ_out.Var l),
        (matchArg lets matchLets argsl argsr).IsMonotone
    )
    ∧ (
      ∀ (Δ_out : Ctxt d.Ty) (t : d.Ty) (v : Γ_out.Var t)
        (matchLets : Lets d Δ_in EffectKind.pure Δ_out)
        (w : Var Δ_out t),
        (matchVar lets v matchLets w).IsMonotone
    )

theorem or_and_not_not_wrong_b_proof : or_and_not_not_wrong_b_before ⊑ or_and_not_not_wrong_b_after

theorem n8_wrong_pred3_proof : n8_wrong_pred3_before ⊑ n8_wrong_pred3_after

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

theorem slt_zero_eq_ne_0_fail2_proof : slt_zero_eq_ne_0_fail2_before ⊑ slt_zero_eq_ne_0_fail2_after

theorem sdiv_common_divisor_defined_cond_thm (e e_1 e_2 : IntW 5) (e_3 : IntW 1) :
  select e_3 (LLVM.sdiv e_2 e_1) (LLVM.sdiv e e_1) ⊑ LLVM.sdiv (select e_3 e_2 e) e_1

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

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

theorem t1_sshr_proof : t1_sshr_before ⊑ t1_sshr_after

theorem test0_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (-1#32 <ₛ x ^^^ BitVec.ofInt 32 (-2147483648)) = ofBool (x <ₛ 0#32)

@[simp]
theorem Std.HashSet.mem_attachWith_mem [BEq α] [Hashable α] [LawfulBEq α] (m : HashSet α) {P H} (x : α) h :
    ⟨x, h⟩ ∈ m.attachWith P H ↔ x ∈ m

theorem e_1410 :
     - 6 * z - 3 *  ~~~z - 11 * (z ^^^ t) - 5 *  ~~~(z &&&  ~~~t) - 1 * t - 1 *  ~~~(z &&& t) + 7 *  ~~~(z ||| t) + 21 *  ~~~(z |||  ~~~t) + 18 * (z &&&  ~~~t) + 10 * (z &&& t) =  - 2 *  ~~~(z ^^^ t)

theorem or_and_or_pat4_proof : or_and_or_pat4_before ⊑ or_and_or_pat4_after

theorem ashrsgt_01_03_proof : ashrsgt_01_03_before ⊑ ashrsgt_01_03_after

theorem lshrugt_02_01_thm (e : IntW 4) :
  icmp IntPred.ugt (lshr e (const? 4 2)) (const? 4 1) ⊑ icmp IntPred.slt e (const? 4 0)

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

theorem eq_umin1_proof : eq_umin1_before ⊑ eq_umin1_after

theorem ashrslt_02_11_exact_proof : ashrslt_02_11_exact_before ⊑ ashrslt_02_11_exact_after

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

theorem main5_like_logical_thm.extracted_1._11 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 7#32 == 7#32) = 1#1 →
    ¬ofBool (x_1 &&& 7#32 != 7#32) = 1#1 → 0#1 = 1#1 → 0#32 = zeroExtend 32 (ofBool (x &&& 7#32 != 7#32))

theorem test5_proof : test5_before ⊑ test5_after

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

theorem select_ashr_icmp_bad_thm.extracted_1._3 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 == 1#32) = 1#1 → ¬x_2 ≥ ↑32 → 1#32 ≥ ↑32 → False

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

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

theorem positive_sameconst_shlnuwnsw_lshrexact_proof : positive_sameconst_shlnuwnsw_lshrexact_before ⊑ positive_sameconst_shlnuwnsw_lshrexact_after

theorem sge_smin3_proof : sge_smin3_before ⊑ sge_smin3_after

theorem ashr_bitwidth_mask_proof : ashr_bitwidth_mask_before ⊑ ashr_bitwidth_mask_after

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

theorem and_ranges_overlap_single_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (5#8 ≤ᵤ x) &&& ofBool (x ≤ᵤ 10#8) &&& (ofBool (10#8 ≤ᵤ x) &&& ofBool (x ≤ᵤ 20#8)) = ofBool (x == 10#8)

theorem t0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬x ≥ ↑8 → (x_1 ^^^ -1#8).sshiftRight' x = x_1.sshiftRight' x ^^^ -1#8

theorem trunc_lshr_trunc_proof : trunc_lshr_trunc_before ⊑ trunc_lshr_trunc_after

theorem xor_ashr_not_fail_lshr_ashr_proof : xor_ashr_not_fail_lshr_ashr_before ⊑ xor_ashr_not_fail_lshr_ashr_after

theorem trunc_sel_smaller_zext_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → zeroExtend 32 42#16 = 42#32

theorem e_464 :
     - 1 *  ~~~y - 5 *  ~~~x - 11 *  ~~~(x ^^^ y) + 7 * (x ||| y) + 1 * y - 11 * (x ^^^ y) + 14 *  ~~~(x |||  ~~~y) + 11 * (x &&&  ~~~y) + 3 * (x &&& y) =  - 23 *  ~~~(x ||| y) + 6 *  ~~~(x &&& y)

theorem icmp_ugt_16_proof : icmp_ugt_16_before ⊑ icmp_ugt_16_after

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

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

theorem test19_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (signExtend 64 x <ₛ 12345#64) = ofBool (x <ₛ 12345#32)

theorem lshrugt_03_11_proof : lshrugt_03_11_before ⊑ lshrugt_03_11_after

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

theorem e_1535 :
     - 3 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) - 2 * (c ^^^ (a &&&  ~~~b)) + 2 *  ~~~(a ||| b) + 1 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) + 2 *  ~~~(a |||  ~~~b) + 3 * (c &&& (a ^^^ b)) - 3 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) - 2 *  ~~~(a ||| (b ||| c)) + 2 *  ~~~(a ||| ( ~~~b ||| c)) + 5 *  ~~~( ~~~a ||| (b ||| c)) + 3 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 4 * (a &&& (b &&& c)) =  - 2 *  ~~~(a ||| c) + 1 * ( ~~~a &&& ( ~~~b &&& c))

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

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

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

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

theorem width_specific_1 (x : BitVec w) : w = 1 →  x + x = x ^^^ x

theorem fold_or_zext_icmp_proof : fold_or_zext_icmp_before ⊑ fold_or_zext_icmp_after

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

theorem zext_sext_add_icmp_ne_minus1_thm (e e_1 : IntW 1) :
  icmp IntPred.ne (add (zext 8 e_1) (sext 8 e)) (const? 8 (-1)) ⊑ LLVM.or e_1 (LLVM.xor e (const? 1 1))

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

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

theorem scalar_i8_shl_ugt_const_proof : scalar_i8_shl_ugt_const_before ⊑ scalar_i8_shl_ugt_const_after

theorem and_ranges_signed_pred_thm (e : IntW 64) :
  LLVM.and (icmp IntPred.slt (add e (const? 64 127)) (const? 64 1024))
      (icmp IntPred.slt (add e (const? 64 128)) (const? 64 256)) ⊑
    icmp IntPred.ult (add e (const? 64 (-9223372036854775681))) (const? 64 (-9223372036854775553))

theorem test9_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x ^^^ 123#8 == 34#8) = ofBool (x == 89#8)

theorem e_2403 :
    1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 1 * (e ^^^ (d &&&  ~~~f)) - 3 *  ~~~e + 11 * (e ^^^  ~~~(d &&& f)) - 6 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 1 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 1 * (e ^^^  ~~~(d &&& (e ||| f))) + 3 *  ~~~(d |||  ~~~e) + 11 * (e &&& (d |||  ~~~f)) - 5 * (f &&&  ~~~(d &&& e)) + 1 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 3 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 4 * (e ^^^ (d &&& (e ||| f))) + 7 * (d ^^^ e) + 1 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 1 * f - 2 *  ~~~(e &&& f) - 7 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 7 * (f ||| (d ^^^ e)) - 3 * (f ||| (d &&&  ~~~e)) + 4 * (f ^^^ (d ||| ( ~~~e &&& f))) - 2 * (f ^^^ (d ||| (e &&& f))) + 11 * (f ^^^  ~~~(d &&& (e &&& f))) + 1 * (e ^^^ ( ~~~d ||| (e &&& f))) + 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 11 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 5 * (d ^^^ (e &&& f)) + 5 * (d ||| (e ^^^ f)) + 2 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 6 * ( ~~~e &&& (d ^^^ f)) - 1 * (f |||  ~~~(d |||  ~~~e)) + 5 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 4 * (d &&&  ~~~f) + 2 *  ~~~( ~~~d ||| (e &&& f)) + 7 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 11 * (d &&& f) + 2 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 *  ~~~(d ^^^ (e ^^^ f)) + 3 * (e ^^^ (d &&& ( ~~~e ||| f))) + 7 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 1 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 1 *  ~~~(d &&& ( ~~~e ||| f)) + 1 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 3 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 1 * (e ||| (d ^^^ f)) + 7 * (e ^^^  ~~~(d ||| (e &&& f))) - 5 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 1 * ( ~~~f &&&  ~~~(d ^^^ e)) - 3 *  ~~~(d ^^^ e) + 3 * ( ~~~f ||| (d ^^^ e)) - 11 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 1 *  ~~~(d ^^^ (e ||| f)) - 2 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 3 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) - 1 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 5 *  ~~~(d |||  ~~~f) + 2 * (e ^^^ f) - 6 * (f ^^^ (d |||  ~~~e)) + 1 * (e &&& (d ||| f)) - 5 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 3 * ( ~~~e &&&  ~~~(d ^^^ f)) + 7 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 11 * (d ||| f) + 1 * (d ^^^ ( ~~~e ||| f)) - 25 *  ~~~(d ||| (e ||| f)) - 23 *  ~~~(d ||| ( ~~~e ||| f)) - 57 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 7 * ( ~~~d &&& ( ~~~e &&& f)) - 13 * ( ~~~d &&& (e &&& f)) + 23 * (d &&& ( ~~~e &&& f)) - 30 * (d &&& (e &&& f)) = 26 *  ~~~( ~~~d ||| (e ||| f)) - 3 * ( ~~~(d ||| e) ||| (e ^^^ f))

theorem a_false_implies_b_true2_thm.extracted_1._5 : ∀ (x x_1 : BitVec 1) (x_2 : BitVec 8),
  ofBool (x_2 <ᵤ 20#8) = 1#1 → ofBool (10#8 <ᵤ x_2) = 1#1 → ofBool (10#8 <ᵤ x_2) ||

theorem e_2243 :
    1 *  ~~~(d ^^^ e) - 2 * (e ^^^ (d ||| (e &&& f))) + 4 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 2 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 11 * (d ^^^ ( ~~~e ||| f)) + 11 * (e ^^^  ~~~(d &&& (e ||| f))) - 3 * (e ^^^ (d ||| (e ^^^ f))) - 7 *  ~~~( ~~~d &&& (e &&& f)) + 1 * (d |||  ~~~e) + 1 * (d ^^^ ( ~~~e &&& f)) - 7 *  ~~~(d &&&  ~~~d) + 1 * (d &&&  ~~~e) - 1 * (d ^^^ (e &&& f)) - 11 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 4 * (f ^^^ (d ||| ( ~~~e &&& f))) + 2 * (e ^^^ (d &&& ( ~~~e ||| f))) + 1 * (f ||| (d ^^^ e)) - 7 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 5 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 1 * (d ^^^ e) - 2 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 7 * (f |||  ~~~(d |||  ~~~e)) + 3 * (d ||| e) - 2 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) - 11 *  ~~~(d |||  ~~~e) + 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 2 *  ~~~(d &&& e) - 2 * (e &&&  ~~~(d &&&  ~~~f)) - 2 * (d &&& ( ~~~e ||| f)) - 1 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 2 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 1 *  ~~~(e |||  ~~~f) - 1 * (e |||  ~~~(d ^^^ f)) - 6 * (e ^^^  ~~~(d ||| f)) - 1 * (f &&&  ~~~(d &&& e)) - 3 * (e ^^^ (d &&& (e ||| f))) - 5 *  ~~~(d &&& (e ||| f)) + 2 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 7 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 2 * (f ^^^ (d |||  ~~~e)) + 7 * ( ~~~d ||| (e ^^^ f)) + 3 * (d &&& (e ^^^ f)) - 5 * (f &&& (d ||| e)) - 1 * (f ^^^ (d ||| (e &&& f))) - 1 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 2 * (d ||| f) + 2 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 3 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 1 *  ~~~(d ^^^ f) + 31 *  ~~~(d ||| ( ~~~e ||| f)) - 3 *  ~~~( ~~~d ||| (e ||| f)) - 11 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 10 * ( ~~~d &&& ( ~~~e &&& f)) + 21 * ( ~~~d &&& (e &&& f)) + 13 * (d &&& ( ~~~e &&& f)) + 3 * (d &&& (e &&& f)) =  - 5 * (d |||  ~~~f) - 1 *  ~~~(d ||| (e ^^^ f))

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

theorem testi64i32_ne_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(31#32 ≥ ↑32 ∨ 32#64 ≥ ↑64) →
    ofBool ((truncate 32 x).sshiftRight' 31#32 != truncate 32 (x >>> 32#64)) =
      ofBool (x + BitVec.ofInt 64 (-2147483648) <ᵤ BitVec.ofInt 64 (-4294967296))

theorem test_or3_proof : test_or3_before ⊑ test_or3_after

theorem e_2106 :
     - 1 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) - 11 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 1 * (e ^^^ (d &&& ( ~~~e ||| f))) - 6 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 1 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 1 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 11 *  ~~~( ~~~d &&& (e ^^^ f)) + 4 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 6 * (e ^^^ (d ||| ( ~~~e ||| f))) + 4 * (f ^^^ ( ~~~d ||| (e ||| f))) - 2 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 3 * (d &&& (e ||| f)) + 5 *  ~~~(d |||  ~~~f) - 1 * (e |||  ~~~f) + 1 * ( ~~~f &&&  ~~~(d ^^^ e)) + 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 1 * ( ~~~d &&& (e ||| f)) + 1 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) + 11 * (d ||| e) + 1 * (d ||| (e ^^^ f)) + 5 * ( ~~~d &&& ( ~~~e ||| f)) + 3 * (e ^^^ ( ~~~d &&& (e ||| f))) + 1 * (f ^^^ (d ||| (e &&& f))) - 1 * (e ^^^ (d &&& f)) - 5 * d + 2 *  ~~~f - 2 *  ~~~(d &&&  ~~~d) + 5 * ((d &&& e) ^^^ (e |||  ~~~f)) + 2 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 6 * ((d &&& e) ||| (e ^^^ f)) + 2 * ( ~~~d ||| (e ^^^ f)) + 2 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 11 * ( ~~~f |||  ~~~(d ^^^ e)) - 2 * (e ^^^  ~~~(d &&&  ~~~f)) - 6 * (d ^^^ (e &&& f)) + 1 * (f &&& (d ||| e)) - 27 *  ~~~(d ||| ( ~~~e ||| f)) + 15 *  ~~~( ~~~d ||| (e ||| f)) - 1 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 10 * ( ~~~d &&& ( ~~~e &&& f)) - 2 * ( ~~~d &&& (e &&& f)) - 5 * (d &&& (e &&& f)) =  - 25 * (d &&& ( ~~~e &&& f))

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

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

theorem negate_add_with_single_negatible_operand_depth2_proof : negate_add_with_single_negatible_operand_depth2_before ⊑ negate_add_with_single_negatible_operand_depth2_after

theorem e_2422 :
     - 6 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 1 * ((d ||| e) &&& (e ^^^ f)) - 5 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 1 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 7 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 4 *  ~~~(d ^^^ (e ^^^ f)) + 11 * ( ~~~f |||  ~~~(d ^^^ e)) - 7 * (e ^^^  ~~~(d ||| (e &&& f))) - 5 * (f ^^^ ( ~~~d &&& (e ||| f))) + 3 * (f &&& (d |||  ~~~e)) + 3 * (e ^^^ (d &&& f)) - 11 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 *  ~~~(d &&&  ~~~e) + 7 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 4 * (f ^^^ (d ||| e)) - 1 * (e ^^^  ~~~(d &&&  ~~~f)) - 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) + 7 *  ~~~(d &&&  ~~~f) - 5 * (e ||| (d ^^^ f)) - 6 *  ~~~(d &&& (e ||| f)) + 3 * (f |||  ~~~(d ||| e)) - 6 * (f ^^^  ~~~(d &&& (e &&& f))) + 4 * (f &&&  ~~~(d &&& e)) + 4 * ((d &&& e) ^^^ (e ||| f)) + 7 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 2 * (f ^^^ (d ||| (e ||| f))) - 2 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 5 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 1 *  ~~~(d &&& (e &&& f)) - 11 * (e ^^^ (d |||  ~~~f)) + 2 * (f |||  ~~~(d ^^^ e)) + 2 *  ~~~( ~~~d ||| (e ^^^ f)) + 5 * ( ~~~e &&& (d ^^^ f)) - 1 * (e ||| (d &&& f)) - 2 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 2 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 2 *  ~~~(d &&& (e ^^^ f)) + 2 * (e ^^^ (d ||| (e &&& f))) - 6 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 3 * (e ^^^ (d &&&  ~~~f)) + 4 * (f ||| (d &&& e)) + 1 * ((d &&& f) ^^^ (e ||| f)) - 11 * (f ||| (d &&&  ~~~e)) - 11 *  ~~~(d &&&  ~~~d) + 1 *  ~~~( ~~~d &&& (e ^^^ f)) - 6 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 5 * (f &&& (d ^^^ e)) + 3 *  ~~~(d &&& f) - 2 * (e &&& (d ||| f)) + 2 * (f ^^^ (d ||| (e &&& f))) + 5 * ( ~~~d ||| (e ^^^ f)) + 3 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 1 *  ~~~( ~~~d ||| ( ~~~e &&& f)) + 11 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 2 *  ~~~(d ^^^ e) - 11 * (d ^^^ ( ~~~e &&& f)) - 7 * ( ~~~d ||| (e ||| f)) - 11 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 2 *  ~~~(e &&&  ~~~f) - 2 *  ~~~(d ^^^ (e &&& f)) - 3 * ((d &&& e) |||  ~~~(e ^^^ f)) + 2 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 1 *  ~~~(e ||| f) + 11 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 7 * (e &&&  ~~~(d &&& f)) + 28 *  ~~~(d ||| (e ||| f)) + 7 *  ~~~(d ||| ( ~~~e ||| f)) + 29 *  ~~~( ~~~d ||| (e ||| f)) + 31 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 30 * ( ~~~d &&& ( ~~~e &&& f)) + 20 * ( ~~~d &&& (e &&& f)) + 4 * (d &&& ( ~~~e &&& f)) + 13 * (d &&& (e &&& f)) = 7 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 7 *  ~~~(d ||| (e &&& f))

theorem uge_zext_proof : uge_zext_before ⊑ uge_zext_after

theorem sext_xor_sub_2_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  x_1 = 1#1 → signExtend 64 x_1 - (x ^^^ signExtend 64 x_1) = x

theorem lt_signed_to_large_signed_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (signExtend 32 x <ₛ 1024#32) = 1#1

theorem e_463 :
    5 *  ~~~x - 1 *  ~~~(x ^^^ y) - 11 *  ~~~(x &&&  ~~~x) - 5 * (x |||  ~~~y) - 11 * x - 1 *  ~~~(x &&& y) + 13 *  ~~~(x ||| y) + 6 *  ~~~(x |||  ~~~y) + 28 * (x &&& y) =  - 1 * (x ^^^ y) - 27 * (x &&&  ~~~y)

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

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

theorem e_2343 :
     - 1 * (f ||| (d &&&  ~~~e)) + 11 * (e |||  ~~~(d |||  ~~~f)) + 2 * (e ^^^ (d ||| f)) + 1 *  ~~~( ~~~d ||| (e ^^^ f)) + 7 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 1 *  ~~~(d &&& ( ~~~e &&& f)) - 7 * (f ^^^ (d ||| (e &&& f))) - 7 * (e ^^^  ~~~(d &&&  ~~~f)) + 3 * (f ^^^ (d &&& (e ||| f))) - 1 * (e &&& (d |||  ~~~f)) - 6 * (d ^^^ e) + 2 *  ~~~( ~~~d &&& (e &&& f)) + 5 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 11 *  ~~~(d &&& e) + 4 * (e |||  ~~~(d ||| f)) + 4 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 2 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 *  ~~~( ~~~d &&& (e ||| f)) - 1 *  ~~~(d &&& (e ||| f)) + 3 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 5 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 3 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 1 *  ~~~( ~~~d ||| (e &&& f)) - 5 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 1 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 11 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 4 * (e &&&  ~~~(d &&& f)) - 7 *  ~~~(d ||| (e ^^^ f)) + 1 * (d &&& (e ^^^ f)) - 1 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 1 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 1 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 2 *  ~~~(d |||  ~~~f) + 2 * (f ^^^  ~~~(d |||  ~~~e)) - 7 *  ~~~e - 2 * (d ||| (e ^^^ f)) + 7 * (e ^^^ (d ||| ( ~~~e &&& f))) - 2 * ((d ^^^ e) ||| (d ^^^ f)) + 1 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 7 * (f ^^^  ~~~(d &&& (e &&& f))) + 5 *  ~~~(d ^^^ (e ^^^ f)) + 11 * ( ~~~d &&& ( ~~~e ||| f)) + 2 * (e &&& (d ^^^ f)) + 1 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 * ( ~~~d &&& (e ||| f)) + 1 * (f |||  ~~~(d |||  ~~~e)) + 1 * (d &&& e) - 5 * (d ^^^ (e &&& f)) + 1 * (e ^^^ f) - 1 *  ~~~(e |||  ~~~f) - 6 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (e ^^^ (d &&& (e ^^^ f))) - 1 * (e ^^^  ~~~(d &&& (e &&& f))) - 5 * ((d &&& f) ^^^ (e ||| f)) + 1 * (e ||| (d &&&  ~~~f)) + 1 *  ~~~(d &&& (e ^^^ f)) - 3 * (f ^^^ (d &&&  ~~~e)) - 5 * (e ^^^ ( ~~~d ||| (e &&& f))) + 2 * ( ~~~d ||| ( ~~~e ||| f)) - 20 *  ~~~(d ||| (e ||| f)) - 39 *  ~~~(d ||| ( ~~~e ||| f)) + 1 * ( ~~~d &&& ( ~~~e &&& f)) - 29 * ( ~~~d &&& (e &&& f)) - 7 * (d &&& ( ~~~e &&& f)) - 16 * (d &&& (e &&& f)) = 5 *  ~~~( ~~~d ||| ( ~~~e ||| f))

theorem corec_eq_corec {a : α} {b : β} {f g}
    (R : α → β → Prop)
    (thing : R a b)
    (h : ∀ a b, R a b →
          let x := f a
          let y := g b
          R x.fst y.fst ∧ x.snd = y.snd) :
    corec f a = corec g b

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

theorem test2_proof : test2_before ⊑ test2_after

theorem test_and1_logical_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sge e_1 (const? 32 0)) (icmp IntPred.slt e_1 (LLVM.and e (const? 32 2147483647)))
      (const? 1 0) ⊑
    select (icmp IntPred.sgt e_1 (const? 32 (-1))) (icmp IntPred.slt e_1 (LLVM.and e (const? 32 2147483647)))
      (const? 1 0)

theorem test_sub_nuw__nsw_is_safe_proof : test_sub_nuw__nsw_is_safe_before ⊑ test_sub_nuw__nsw_is_safe_after

theorem select_sub_icmp_bad_proof : select_sub_icmp_bad_before ⊑ select_sub_icmp_bad_after

theorem main7f_proof : main7f_before ⊑ main7f_after

theorem ashrslt_03_01_exact_proof : ashrslt_03_01_exact_before ⊑ ashrslt_03_01_exact_after

theorem udiv_x_by_const_cmp_x_thm (e : IntW 32) :
  icmp IntPred.slt (LLVM.udiv e (const? 32 123)) e ⊑ icmp IntPred.sgt e (const? 32 0)

theorem positive_and_odd_eq_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(2#32 == 0 || 32 != 1 && x == intMin 32 && 2#32 == -1) = true →
    ofBool (x.srem 2#32 == 1#32) = ofBool (x &&& BitVec.ofInt 32 (-2147483647) == 1#32)

theorem e_623 :
    3 * (x ||| y) + 4 *  ~~~x + 4 *  ~~~(x &&& y) + 2 * (x ^^^ y) - 11 *  ~~~(x ^^^ y) - 2 * y - 5 *  ~~~(x &&&  ~~~y) + 8 *  ~~~(x ||| y) - 6 *  ~~~(x |||  ~~~y) + 15 * (x &&& y) = 9 * (x &&&  ~~~y)

theorem ashr_lshr_cst2_proof : ashr_lshr_cst2_before ⊑ ashr_lshr_cst2_after

theorem uge_swap_and_max_commute_logical_proof : uge_swap_and_max_commute_logical_before ⊑ uge_swap_and_max_commute_logical_after

theorem sgt_3_impliesT_sgt_2_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ofBool (3#8 <ₛ x) = 1#1 → ¬ofBool (x <ₛ 4#8) = 1#1 → ofBool (x <ₛ 2#8) = 0#1

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

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

theorem Eqn.denote_hard_case_aux {eqn : Eqn}
    (h1 : ∀ (env1 : EnvFin 1 eqn.numVars), Eqn.denoteFin eqn env1 = 0) :
    ∀ {w : Nat} (env : EnvFin w eqn.numVars), eqn.denoteFin env = 0

theorem n13_overshift_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 x_2 : BitVec 32),
  ¬(32#32 - x_1 ≥ ↑32 ∨ zeroExtend 64 (x_1 + 32#32) ≥ ↑64) →
    32#32 - x_1 ≥ ↑32 ∨ True ∧ (x_1 + 32#32).msb = true ∨ zeroExtend 64 (x_1 + 32#32) ≥ ↑64 → False

theorem test_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬zeroExtend 32 x ≥ ↑32 → True ∧ x.msb = true ∨ zeroExtend 32 x ≥ ↑32 → False

theorem t2_ashr_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ¬signExtend 32 x ≥ ↑32 → True ∧ x.msb = true ∨ zeroExtend 32 x ≥ ↑32 → False

theorem add_select_not_sext_thm.extracted_1._1 : ∀ (x : BitVec 1),
  x = 1#1 → 64#64 + signExtend 64 (x ^^^ 1#1) = 64#64

theorem select_icmp_eq_and_1_0_lshr_fv_proof : select_icmp_eq_and_1_0_lshr_fv_before ⊑ select_icmp_eq_and_1_0_lshr_fv_after

theorem ugt_swap_or_not_min_commute_logical_thm (e e_1 : IntW 823) :
  select (icmp IntPred.ne e_1 (const? 823 0)) (const? 1 1) (icmp IntPred.ult e e_1) ⊑
    icmp IntPred.ne e_1 (const? 823 0)

theorem ripple_nsw3_thm (e e_1 : IntW 16) :
  add (LLVM.and e_1 (const? 16 (-21845))) (LLVM.and e (const? 16 21843)) ⊑
    add (LLVM.and e_1 (const? 16 (-21845))) (LLVM.and e (const? 16 21843)) { «nsw» := true, «nuw» := true }

theorem PR42691_2_logical_proof : PR42691_2_logical_before ⊑ PR42691_2_logical_after

theorem PR30273_three_bools_thm.extracted_1._11 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 = 1#1 →
    ¬x_1 = 1#1 →
      True ∧ (zeroExtend 32 x).saddOverflow (zeroExtend 32 x_2) = true ∨
          True ∧ (zeroExtend 32 x).uaddOverflow (zeroExtend 32 x_2) = true →
        False

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

theorem lshrult_01_01_exact_proof : lshrult_01_01_exact_before ⊑ lshrult_01_01_exact_after

theorem e_2297 :
     - 3 * (f |||  ~~~(d ^^^ e)) + 3 *  ~~~( ~~~d &&& (e ^^^ f)) + 1 * (e ^^^ ( ~~~d ||| (e ||| f))) - 3 * (f ||| (d &&&  ~~~e)) - 5 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 7 *  ~~~(e &&& f) + 2 * (e ^^^  ~~~(d |||  ~~~f)) - 6 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 5 *  ~~~( ~~~d &&& (e &&& f)) - 3 * (e ^^^ (d ||| (e ^^^ f))) - 2 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 4 * (d ||| (e ^^^ f)) - 5 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 1 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 1 * ( ~~~f &&&  ~~~(d ^^^ e)) + 5 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 1 * ( ~~~d ||| ( ~~~e &&& f)) + 7 *  ~~~(d |||  ~~~e) - 1 * (f ^^^ (d ||| (e ||| f))) + 2 * ( ~~~f &&& (d ^^^ e)) - 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 1 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) - 5 * (e ||| (d &&&  ~~~f)) + 4 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 7 * (e ^^^  ~~~(d &&& f)) - 2 * (f ^^^ ( ~~~d ||| (e &&& f))) - 2 * ( ~~~d ||| (e &&& f)) - 11 * (e &&& (d ||| f)) + 1 * (e ^^^  ~~~(d ||| f)) - 5 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 2 *  ~~~(d ^^^ (e ||| f)) + 7 *  ~~~(d ||| e) + 11 *  ~~~( ~~~d ||| (e &&& f)) + 1 * ((d ^^^ e) ||| (d ^^^ f)) + 7 * (f |||  ~~~(d ||| e)) + 4 *  ~~~(e ^^^ f) + 1 * (d ||| (e ||| f)) + 2 * (f ^^^ (d ||| (e &&& f))) - 1 * (d ^^^ ( ~~~e ||| f)) - 1 * ( ~~~d ||| (e ||| f)) + 2 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 5 * (d ^^^ ( ~~~e &&& f)) - 11 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 2 * (e ^^^ f) - 3 * ((d &&& e) ^^^ (e ||| f)) - 3 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 1 * (d &&& f) + 1 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) + 11 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 6 *  ~~~(d &&& ( ~~~e ||| f)) - 11 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 5 * ( ~~~e &&& (d ^^^ f)) - 11 * (e &&& (d |||  ~~~f)) - 1 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 6 *  ~~~(d &&& ( ~~~e &&& f)) + 6 *  ~~~(d ||| (e ||| f)) + 27 *  ~~~(d ||| ( ~~~e ||| f)) + 2 *  ~~~( ~~~d ||| (e ||| f)) + 46 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 20 * ( ~~~d &&& ( ~~~e &&& f)) + 6 * (d &&& ( ~~~e &&& f)) + 23 * (d &&& (e &&& f)) =  - 25 * ( ~~~d &&& (e &&& f)) - 1 * (f ^^^  ~~~(d &&& (e &&& f)))

theorem xor_signbit_lshr_thm (e : IntW 32) :
  lshr (LLVM.xor e (const? 32 (-65536))) (const? 32 8) ⊑ LLVM.xor (lshr e (const? 32 8)) (const? 32 16776960)

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

theorem or_simplify_ugt_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x &&& BitVec.ofInt 8 (-2) <ᵤ x_1 ||| 1#8 ||| x &&& BitVec.ofInt 8 (-2)) =
    ofBool (x &&& BitVec.ofInt 8 (-2) <ᵤ x_1 ||| x ||| 1#8)

theorem trunc_sel_larger_zext_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → zeroExtend 64 42#16 = 42#64

theorem or_not_and_commute9_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬((x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true ∨
        (x_1 == 0 || 32 != 1 && 42#32 == intMin 32 && x_1 == -1) = true ∨
          (x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true ∨
            (x_1 == 0 || 32 != 1 && 42#32 == intMin 32 && x_1 == -1) = true ∨
              (x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true ∨
                (x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true) →
    (x_1 == 0 || 32 != 1 && 42#32 == intMin 32 && x_1 == -1) = true ∨
        (x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true ∨
          (x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true →
      False

theorem select_constants_and_icmp_ne0_zero_fval_proof : select_constants_and_icmp_ne0_zero_fval_before ⊑ select_constants_and_icmp_ne0_zero_fval_after

theorem negate_sdiv_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true →
    (BitVec.ofInt 8 (-42) == 0 || 8 != 1 && x == intMin 8 && BitVec.ofInt 8 (-42) == -1) = true → False

theorem lshr_shl_eq_amt_multi_use_thm.extracted_1._1 : ∀ (x : BitVec 43),
  ¬(23#43 ≥ ↑43 ∨ 23#43 ≥ ↑43 ∨ 23#43 ≥ ↑43) → 23#43 ≥ ↑43 → False

theorem Valuation.eq_nil (V : Valuation (empty : Ctxt Ty)) : V = Valuation.nil

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 test_shl_nsw__nuw_is_safe_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& 1073741822#32 == 0#32) = 1#1 →
    2#32 ≥ ↑32 ∨
        True ∧ (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)).msb = true ∨
          zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)) ≥ ↑64 →
      False

theorem ne_smax4_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (add e_1 (const? 32 3))
      (select (icmp IntPred.sgt e (add e_1 (const? 32 3))) e (add e_1 (const? 32 3))) ⊑
    icmp IntPred.slt (add e_1 (const? 32 3)) e

theorem test6a_thm (e : IntW 55) : shl (mul e (const? 55 3)) (const? 55 1) ⊑ mul e (const? 55 6)

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 srem_i1_is_zero_thm (e e_1 : IntW 1) : LLVM.srem e_1 e ⊑ const? 1 0

theorem ashr_2_add_zext_basic_proof : ashr_2_add_zext_basic_before ⊑ ashr_2_add_zext_basic_after

theorem ugt_swap_and_not_min_logical_proof : ugt_swap_and_not_min_logical_before ⊑ ugt_swap_and_not_min_logical_after

theorem t0_commutative_thm.extracted_1._5 : ∀ (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 → 0#1 = 1#1 → False

theorem test7_logical_thm (e : IntW 1) (e_1 : IntW 32) :
  select (select (icmp IntPred.slt e_1 (const? 32 1)) e (const? 1 0)) (icmp IntPred.sgt e_1 (const? 32 (-1)))
      (const? 1 0) ⊑
    select (icmp IntPred.eq e_1 (const? 32 0)) e (const? 1 0)

theorem shl_xor_xor_good_mask_proof : shl_xor_xor_good_mask_before ⊑ shl_xor_xor_good_mask_after

theorem ule_swap_or_min_commute_proof : ule_swap_or_min_commute_before ⊑ ule_swap_or_min_commute_after

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

theorem ne_umax1_proof : ne_umax1_before ⊑ ne_umax1_after

theorem zext_sext_add_icmp_i128_thm (e e_1 : IntW 1) :
  icmp IntPred.sgt (add (zext 128 e_1) (sext 128 e)) (const? 128 9223372036854775808) ⊑ const? 1 0

theorem lshrult_03_01_exact_proof : lshrult_03_01_exact_before ⊑ lshrult_03_01_exact_after

theorem trunc_shl_16_i32_i64_thm (e : IntW 64) : trunc 32 (shl e (const? 64 16)) ⊑ shl (trunc 32 e) (const? 32 16)

theorem e_1335 :
     - 1 *  ~~~(z &&&  ~~~z) - 7 * t + 5 *  ~~~(z &&& t) + 11 *  ~~~t + 2 * (z ^^^ t) + 5 *  ~~~(z ^^^ t) - 20 *  ~~~(z ||| t) - 18 * (z &&&  ~~~t) + 2 * (z &&& t) =  - 1 * (z ||| t)

theorem test17_proof : test17_before ⊑ test17_after

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 test8_thm.extracted_1._1 : ∀ (x : BitVec 128),
  ¬(127#128 ≥ ↑128 ∨ 120#128 ≥ ↑128 ∨ 127#128 ≥ ↑128) →
    (x ^^^ (1#128 <<< 127#128).sshiftRight' 120#128) + 1#128 <<< 127#128 =
      x ^^^ 170141183460469231731687303715884105600#128

theorem e_104 :
    5 * y + 2 * (x |||  ~~~y) + 11 *  ~~~x - 13 *  ~~~(x ||| y) - 16 *  ~~~(x |||  ~~~y) - 7 * (x &&& y) = 2 * (x &&&  ~~~y)

theorem test1_thm.extracted_1._1 : ∀ (x : BitVec 61), zeroExtend 61 (truncate 41 x) = x &&& 2199023255551#61

theorem eq_hide {a : α} : a = hide a

theorem test9_logical_proof : test9_logical_before ⊑ test9_logical_after

theorem positive_samevar_proof : positive_samevar_before ⊑ positive_samevar_after

theorem test6_proof : test6_before ⊑ test6_after

theorem bitwise_and_logical_and_masked_icmp_allones_poison1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& x == x) = 1#1 →
    ¬ofBool (x_1 &&& (x ||| 7#32) == x ||| 7#32) = 1#1 → 0#1 &&& ofBool (x_1 &&& 7#32 == 7#32) = 0#1

theorem scalar_i8_shl_uge_const_thm (e : IntW 8) :
  icmp IntPred.uge (shl e (const? 8 5)) (const? 8 64) ⊑
    icmp IntPred.ne (LLVM.and e (const? 8 6)) (const? 8 0)

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

theorem bor_lor_left1_thm (e e_1 : IntW 1) : select (LLVM.or e_1 e) (const? 1 1) e_1 ⊑ LLVM.or e_1 e

theorem zext_zext_sle_op0_narrow_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 8),
  ofBool (zeroExtend 32 x_1 ≤ₛ zeroExtend 32 x) = ofBool (zeroExtend 16 x_1 ≤ᵤ x)

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

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

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

theorem band_lor_left1_proof : band_lor_left1_before ⊑ band_lor_left1_after

@[simp] theorem scanAnd_succ (s : BitStream) : scanAnd s (n+1) = ((s.scanAnd n) && s (n + 1))

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

theorem e_2395 :
    3 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 1 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 7 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 3 * (e ^^^ (d ||| (e ^^^ f))) + 1 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) - 3 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 11 * (d &&&  ~~~f) + 5 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 2 * (e ^^^ f) - 2 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 11 * (f ^^^  ~~~(d |||  ~~~e)) + 1 * ( ~~~f &&& (d ^^^ e)) + 5 * ((d &&& f) |||  ~~~(e ||| f)) + 1 *  ~~~(d ||| f) - 2 * (d ^^^ ( ~~~e &&& f)) - 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 7 * (e ^^^ (d ||| f)) - 5 *  ~~~(d &&& ( ~~~e ||| f)) + 2 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 3 * ( ~~~d &&& (e ^^^ f)) + 2 * (d ||| ( ~~~e &&& f)) - 11 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 1 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 11 * ( ~~~f |||  ~~~(d ^^^ e)) - 2 * (f ^^^ (d ||| e)) - 7 * (e ||| (d ^^^ f)) - 3 * (e ^^^ ( ~~~d ||| (e &&& f))) + 2 * ((d ^^^ e) &&& (d ^^^ f)) + 5 * (e &&& f) + 3 * (f ||| (d &&& e)) + 3 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 7 * (e ^^^ (d &&&  ~~~f)) + 1 * (f ^^^  ~~~(d &&& e)) + 2 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 * (e |||  ~~~f) - 3 *  ~~~(e ||| f) - 5 *  ~~~(d ^^^ f) + 2 * (d ||| f) - 1 *  ~~~(d ||| ( ~~~e &&& f)) + 2 * (f ^^^ ( ~~~d ||| (e &&& f))) + 2 *  ~~~(e &&&  ~~~f) + 4 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 11 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) - 2 *  ~~~(d ^^^ (e &&& f)) + 1 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * (f ||| (d ^^^ e)) + 3 * (e &&&  ~~~(d &&& f)) + 2 *  ~~~(d ||| e) + 5 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 7 *  ~~~(d ||| (e ^^^ f)) - 11 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 2 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 5 * (f ^^^ (d &&& e)) - 2 *  ~~~( ~~~d &&& (e &&& f)) + 4 * (f ^^^ ( ~~~d &&& (e ||| f))) - 11 * (d &&&  ~~~e) + 1 *  ~~~(d &&& ( ~~~e &&& f)) + 1 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 2 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 *  ~~~(e ^^^ f) - 2 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 6 * ( ~~~d &&& (e ||| f)) - 1 * (e &&& (d ||| f)) + 6 *  ~~~(d ||| (e ||| f)) + 50 *  ~~~(d ||| ( ~~~e ||| f)) + 49 *  ~~~( ~~~d ||| (e ||| f)) + 38 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 42 * ( ~~~d &&& ( ~~~e &&& f)) + 8 * ( ~~~d &&& (e &&& f)) + 37 * (d &&& ( ~~~e &&& f)) + 11 * (d &&& (e &&& f)) = 3 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 2 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f))

@[simp] theorem Com.changeVars_var (e : Expr d Γ eff t) (body : Com d _ eff u) :
    (Com.var e body).changeVars
    = fun (map : Γ.Hom Δ) => Com.var (e.changeVars map) (body.changeVars map.append)

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

theorem sub_zext_trunc_lshr_thm (e : IntW 64) :
  sub (const? 32 10) (zext 32 (trunc 1 (lshr e (const? 64 15)))) ⊑
    add (ashr (shl (trunc 32 e) (const? 32 16)) (const? 32 31)) (const? 32 10)
      { «nsw» := true, «nuw» := false }

theorem lshr_pow2_ult_proof : lshr_pow2_ult_before ⊑ lshr_pow2_ult_after

@[simp]
theorem EnvFin.cons_zero (env : EnvFin w n) (b : BitVec w) :
  (env.cons b) 0 = b

theorem test_thm.extracted_1._1 : ∀ (x : BitVec 32), x + 5#32 + BitVec.ofInt 32 (-5) = x

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

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

theorem eq_21_proof : eq_21_before ⊑ eq_21_after

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

theorem ule_swap_and_min_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.uge e_1 e) (icmp IntPred.eq e (const? 8 0)) ⊑
    icmp IntPred.eq e (const? 8 0)

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

theorem test_shift_negative_proof : test_shift_negative_before ⊑ test_shift_negative_after

theorem or_disjoint_with_xor_proof : or_disjoint_with_xor_before ⊑ or_disjoint_with_xor_after

theorem e_646 :
    3 * (x |||  ~~~y) + 3 *  ~~~(x &&&  ~~~y) - 2 * y - 11 *  ~~~x + 1 * (x ||| y) + 2 *  ~~~(x &&& y) - 2 * x - 4 *  ~~~(x |||  ~~~y) - 15 * (x &&&  ~~~y) - 3 * (x &&& y) =  - 11 * (x ^^^ y) - 3 *  ~~~(x ||| y)

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

theorem eq_smin3_proof : eq_smin3_before ⊑ eq_smin3_after

theorem lshrugt_02_00_proof : lshrugt_02_00_before ⊑ lshrugt_02_00_after

theorem scalar_i32_lshr_and_negC_eq_X_is_constant1_proof : scalar_i32_lshr_and_negC_eq_X_is_constant1_before ⊑ scalar_i32_lshr_and_negC_eq_X_is_constant1_after

theorem lor_band_left1_thm (e e_1 : IntW 1) : LLVM.and (select e_1 (const? 1 1) e) e_1 ⊑ e_1

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

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

theorem test1_proof : test1_before ⊑ test1_after

theorem exact_ashr_eq_exactdiv_proof : exact_ashr_eq_exactdiv_before ⊑ exact_ashr_eq_exactdiv_after

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

theorem icmp_eq_zext_ne_zero_proof : icmp_eq_zext_ne_zero_before ⊑ icmp_eq_zext_ne_zero_after

theorem e_1170 :
    2 * (z ^^^ t) - 3 *  ~~~(z &&&  ~~~z) - 6 * z - 7 *  ~~~(z &&&  ~~~t) - 6 *  ~~~t + 16 *  ~~~(z ||| t) + 13 * (z &&&  ~~~t) + 16 * (z &&& t) =  - 8 *  ~~~(z |||  ~~~t)

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

theorem drop_nsw_trunc_proof : drop_nsw_trunc_before ⊑ drop_nsw_trunc_after

theorem test11d_proof : test11d_before ⊑ test11d_after

theorem icmp_eq_and_pow2_shl_pow2_negative3_proof : icmp_eq_and_pow2_shl_pow2_negative3_before ⊑ icmp_eq_and_pow2_shl_pow2_negative3_after

theorem ashr_ule_noexact_thm (e : IntW 8) :
  icmp IntPred.ule (ashr e (const? 8 3)) (const? 8 10) ⊑ icmp IntPred.ult e (const? 8 88)

theorem test_sub__all_are_safe_proof : test_sub__all_are_safe_before ⊑ test_sub__all_are_safe_after

theorem shl_add_add_fail_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(2#8 ≥ ↑8 ∨ 2#8 ≥ ↑8) →
    2#8 ≥ ↑8 ∨
        2#8 ≥ ↑8 ∨
          True ∧ (x >>> 2#8).saddOverflow 48#8 = true ∨
            True ∧ (x >>> 2#8).uaddOverflow 48#8 = true ∨ True ∧ (x_1 >>> 2#8).uaddOverflow (x >>> 2#8 + 48#8) = true →
      False

theorem no_masks_with_logical_or_proof : no_masks_with_logical_or_before ⊑ no_masks_with_logical_or_after

theorem or_xor_tree_0101_proof : or_xor_tree_0101_before ⊑ or_xor_tree_0101_after

theorem lshrugt_03_13_proof : lshrugt_03_13_before ⊑ lshrugt_03_13_after

theorem test5_apint_proof : test5_apint_before ⊑ test5_apint_after

theorem t0_proof : t0_before ⊑ t0_after

theorem ugt_swap_and_min_commute_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.eq e_1 (const? 8 0)) (icmp IntPred.ult e e_1) ⊑ const? 1 0

theorem test3_proof : test3_before ⊑ test3_after

theorem testi32i8_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(7#8 ≥ ↑8 ∨ 8#32 ≥ ↑32) →
    ¬ofBool ((truncate 8 x).sshiftRight' 7#8 == truncate 8 (x >>> 8#32)) = 1#1 →
      ¬15#32 ≥ ↑32 → truncate 8 (x.sshiftRight' 15#32) ^^^ 127#8 = truncate 8 (x >>> 15#32) ^^^ 127#8

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

theorem demorgan_nor_use2a_proof : demorgan_nor_use2a_before ⊑ demorgan_nor_use2a_after

theorem lshrugt_01_03_thm (e : IntW 4) :
  icmp IntPred.ugt (lshr e (const? 4 1)) (const? 4 3) ⊑ icmp IntPred.slt e (const? 4 0)

theorem positive_samevar_shlnuw_thm (e e_1 : IntW 32) : lshr (shl e_1 e { «nsw» := false, «nuw» := true }) e ⊑ e_1

theorem or2_thm (e e_1 : IntW 64) : LLVM.or (LLVM.and e_1 e) (LLVM.xor e_1 e) ⊑ LLVM.or e_1 e

theorem xor_2_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 1) (x_2 : BitVec 8),
  x_1 = 1#1 → x_2 ^^^ (x ^^^ -1#8) ^^^ -1#8 = x_2 ^^^ x

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

theorem trunc_sandwich_min_shift1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(20#32 ≥ ↑32 ∨ 1#12 ≥ ↑12) →
    21#32 ≥ ↑32 ∨
        True ∧ signExtend 32 (truncate 12 (x >>> 21#32)) ≠ x >>> 21#32 ∨
          True ∧ zeroExtend 32 (truncate 12 (x >>> 21#32)) ≠ x >>> 21#32 →
      False

theorem for_return {t : Arith.Ty} (istart istep: Var Γ Arith.Ty.int)
    (niters : Var Γ .nat) (v : Var Γ t) :
    Expr.denoteOp (for_ (t := t) istart istep niters v (RegionRet t ⟨1, by simp⟩)) Γv = [Γv v]ₕ

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_lshr_exact_both_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_1 >>> x = x_1.sshiftRight' x

theorem lshrugt_03_15_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 lshrult_03_07_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 3#4 <<< 3#4 ≠ x ∨ 3#4 ≥ ↑4) → ofBool (x >>> 3#4 <ᵤ 7#4) = 1#1

theorem select_of_symmetric_selects_proof : select_of_symmetric_selects_before ⊑ select_of_symmetric_selects_after

theorem and_two_ranges_to_mask_and_range_proof : and_two_ranges_to_mask_and_range_before ⊑ and_two_ranges_to_mask_and_range_after

theorem ne_umax1_proof : ne_umax1_before ⊑ ne_umax1_after

theorem test24_thm (e : IntW 32) :
  icmp IntPred.ne (urem e (const? 32 (-2147483648))) (const? 32 0) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 2147483647)) (const? 32 0)

theorem uaddo_wrong_pred2_proof : uaddo_wrong_pred2_before ⊑ uaddo_wrong_pred2_after

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

theorem lsb_mask_sign_zext_commuted_proof : lsb_mask_sign_zext_commuted_before ⊑ lsb_mask_sign_zext_commuted_after

theorem ashrsgt_01_08_proof : ashrsgt_01_08_before ⊑ ashrsgt_01_08_after

theorem e_1205 :
    7 *  ~~~z + 2 *  ~~~(z &&&  ~~~z) - 11 *  ~~~(z &&& t) - 6 * (z |||  ~~~t) - 5 * (z ||| t) + 10 *  ~~~(z ||| t) + 7 *  ~~~(z |||  ~~~t) + 20 * (z &&&  ~~~t) + 7 * (z &&& t) = 2 *  ~~~t - 2 * z

theorem sdiv2_proof : sdiv2_before ⊑ sdiv2_after

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

theorem sle_smax4_proof : sle_smax4_before ⊑ sle_smax4_after

theorem t9_proof : t9_before ⊑ t9_after

theorem trunc_sandwich_max_sum_shift_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(20#32 ≥ ↑32 ∨ 11#12 ≥ ↑12) →
    31#32 ≥ ↑32 ∨
        True ∧ signExtend 32 (truncate 12 (x >>> 31#32)) ≠ x >>> 31#32 ∨
          True ∧ zeroExtend 32 (truncate 12 (x >>> 31#32)) ≠ x >>> 31#32 →
      False

theorem test46_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬8#32 ≥ ↑32 → 8#32 ≥ ↑32 ∨ True ∧ (truncate 32 x <<< 8#32 &&& 10752#32).msb = true → False

theorem uge_swap_and_max_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.ule e_1 e) (icmp IntPred.eq e (const? 8 (-1))) ⊑
    icmp IntPred.eq e (const? 8 (-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 test8_proof : test8_before ⊑ test8_after

theorem ashr_lshr_cst_proof : ashr_lshr_cst_before ⊑ ashr_lshr_cst_after

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

theorem src_is_notmask_sext_thm (e : IntW 8) (e_1 : IntW 16) :
  icmp IntPred.ule (LLVM.xor e_1 (const? 16 123))
      (LLVM.and (LLVM.xor (sext 16 (shl (const? 8 (-8)) e)) (const? 16 (-1))) (LLVM.xor e_1 (const? 16 123))) ⊑
    icmp IntPred.uge (LLVM.xor e_1 (const? 16 (-128))) (sext 16 (shl (const? 8 (-8)) e))

theorem ashr_lshr_wrong_cond_proof : ashr_lshr_wrong_cond_before ⊑ ashr_lshr_wrong_cond_after

theorem tail_iterate'' {α} {n} {s : Stream' α} : Stream'.iterate Stream'.tail s n m = s (n + m)

theorem ashrslt_01_03_exact_proof : ashrslt_01_03_exact_before ⊑ ashrslt_01_03_exact_after

theorem test9_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ (0#64).ssubOverflow x = true) → 0#64 - x &&& 1#64 = x &&& 1#64

theorem test1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 447),
  True ∧ (x_1 &&& 70368744177664#447 &&& (x &&& 70368744177663#447) != 0) = true → False

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

theorem xor_or_xor_thm.extracted_1._1 : ∀ (x : BitVec 8),
  (x ^^^ 33#8 ||| 7#8) ^^^ 12#8 = x &&& BitVec.ofInt 8 (-8) ^^^ 43#8

theorem xor_to_xor3_proof : xor_to_xor3_before ⊑ xor_to_xor3_after

theorem EqualUpTo_ofBitVecZextMsb_add (a b : BitVec w) :
    EqualUpTo (w + 1)
    (BitStream.ofBitVecZextMsb a + BitStream.ofBitVecZextMsb b)
    (BitStream.ofBitVecZextMsb (a + b))

theorem add_five (x : BitVec w) : (x + x) + (x + x) + x = x + x + x + x + x

theorem PR44545_thm (e e_1 : IntW 32) :
  add
      (trunc 16
        (select (icmp IntPred.eq e_1 (const? 32 0)) (const? 32 0)
          (add e (const? 32 1) { «nsw» := true, «nuw» := true })))
      (const? 16 (-1)) { «nsw» := true, «nuw» := false } ⊑
    select (icmp IntPred.eq e_1 (const? 32 0)) (const? 16 (-1)) (trunc 16 e)

@[simp]
theorem ctxt_cons {Γ : DerivedCtxt Δ} :
    (Γ.cons ty).ctxt = Γ.ctxt.cons ty

theorem select_ashr_thm.extracted_1._1 : ∀ (x : BitVec 128) (x_1 : BitVec 1), ¬x_1 = 1#1 → 0#128 ≥ ↑128 → False

theorem n11_uge_slt_proof : n11_uge_slt_before ⊑ n11_uge_slt_after

theorem sub_shl_same_amount_partial_nsw2_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 6),
  ¬(x_1 ≥ ↑6 ∨
        True ∧ (x <<< x_1).sshiftRight' x_1 ≠ x ∨ x_1 ≥ ↑6 ∨ True ∧ (x_2 <<< x_1).ssubOverflow (x <<< x_1) = true) →
    ¬x_1 ≥ ↑6 → x_2 <<< x_1 - x <<< x_1 = (x_2 - x) <<< x_1

theorem ashr_not_proof : ashr_not_before ⊑ ashr_not_after

theorem width1 (w : Nat) (a : BitVec w) : (w = 1) → (a = 0#w ∨ a = 1#w)

theorem masked_icmps_mask_notallzeros_bmask_mixed_7_proof : masked_icmps_mask_notallzeros_bmask_mixed_7_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_7_after

theorem and_xor_not_common_op_proof : and_xor_not_common_op_before ⊑ and_xor_not_common_op_after

theorem test12_proof : test12_before ⊑ test12_after

lemma worklistRun'_wf :
    (worklistRun' A S final inits hinits f).WF

 theorem List.dropLast_nodup (l : List X) : l.Nodup → l.dropLast.Nodup

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 bools2_logical_commute0_and1_and2_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 &&& x_1 = 1#1 → ¬x_2 = 1#1 → 1#1 = x

theorem mul_unkV_evenC_ne_proof : mul_unkV_evenC_ne_before ⊑ mul_unkV_evenC_ne_after

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

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

theorem e_236 :
     - 7 * (x ||| y) - 6 * x - 1 *  ~~~(x &&&  ~~~x) - 2 *  ~~~(x ||| y) + 8 *  ~~~(x |||  ~~~y) + 11 * (x &&&  ~~~y) + 11 * (x &&& y) =  - 3 * (x |||  ~~~y)

theorem src_is_notmask_neg_p2_fail_not_invertable_proof : src_is_notmask_neg_p2_fail_not_invertable_before ⊑ src_is_notmask_neg_p2_fail_not_invertable_after

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 logical_and_logical_and_icmps_comm1_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 8),
  ¬x_1 ≥ ↑8 →
    ofBool (x_2 &&& 1#8 <<< x_1 != 0#8) = 1#1 ∧ ofBool (x == 42#8) = 1#1 →
      ¬(True ∧ 1#8 <<< x_1 >>> x_1 ≠ 1#8 ∨ x_1 ≥ ↑8) →
        ofBool (x_2 &&& 1#8 <<< x_1 != 0#8) = 1#1 → ¬ofBool (x == 42#8) = 1#1 → ofBool (x_2 &&& 1#8 != 0#8) = 0#1

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

theorem and1 (w : Nat) (a b : BitVec w) : (a + b = b + a) ∧ (a + a = a <<< 1)

theorem sgt_n1_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (-1#8 <ₛ truncate 8 x) = ofBool (x &&& 128#32 == 0#32)

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

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

theorem ashr_ugt_14_proof : ashr_ugt_14_before ⊑ ashr_ugt_14_after

theorem test_add_nuw_nsw__nsw_is_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x ||| BitVec.ofInt 32 (-2147483648) == -1#32) = 1#1 →
    True ∧ (x ||| BitVec.ofInt 32 (-2147483648)).saddOverflow 1#32 = true → False

theorem trunc_equality_both_sext_proof : trunc_equality_both_sext_before ⊑ trunc_equality_both_sext_after

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

theorem samesign_inverted_different_sign_bittest1_thm (e e_1 : IntW 32) :
  LLVM.and (icmp IntPred.sge (LLVM.and e_1 e) (const? 32 0))
      (icmp IntPred.slt (LLVM.or e_1 e) (const? 32 0)) ⊑
    icmp IntPred.slt (LLVM.xor e_1 e) (const? 32 0)

theorem shl_trunc_smaller_lshr_thm (e : IntW 32) :
  shl (trunc 8 (lshr e (const? 32 3))) (const? 8 5) ⊑ LLVM.and (shl (trunc 8 e) (const? 8 2)) (const? 8 (-32))

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

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

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

theorem t0_basic_proof : t0_basic_before ⊑ t0_basic_after

theorem e_2098 :
     - 1 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 5 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 6 * (e ^^^ ( ~~~d &&& (e ||| f))) + 7 * (e ^^^ (d &&& (e ^^^ f))) - 11 *  ~~~(d ||| f) + 5 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 2 * (e ^^^ (d ||| (e ||| f))) - 1 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 7 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * (f |||  ~~~(d |||  ~~~e)) + 3 *  ~~~(d ||| (e &&& f)) - 5 * (e ^^^ f) - 2 *  ~~~(e |||  ~~~f) - 3 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 7 * (e &&&  ~~~(d &&& f)) + 2 *  ~~~(d &&& e) + 5 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 1 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) - 1 * (f ^^^ ( ~~~d ||| (e &&& f))) + 1 * (e ^^^ ( ~~~d ||| (e &&& f))) - 6 * (e |||  ~~~(d ||| f)) - 1 * (f ^^^ (d &&&  ~~~e)) + 2 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 1 * ( ~~~f &&& (d ^^^ e)) + 1 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) - 3 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 1 *  ~~~f - 1 * ( ~~~d ||| ( ~~~e &&& f)) - 5 * ((d &&& f) ||| (e &&&  ~~~f)) + 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 7 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 6 * ( ~~~d &&& ( ~~~e ||| f)) - 5 *  ~~~(d &&&  ~~~e) + 2 * d + 1 * (d ||| ( ~~~e &&& f)) - 2 *  ~~~(d ||| (e ||| f)) + 1 *  ~~~(d ||| ( ~~~e ||| f)) - 22 *  ~~~( ~~~d ||| (e ||| f)) - 12 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 10 * ( ~~~d &&& ( ~~~e &&& f)) - 19 * ( ~~~d &&& (e &&& f)) - 17 * (d &&& ( ~~~e &&& f)) =  - 7 *  ~~~(e &&& f)

theorem ashrsgt_03_02_exact_proof : ashrsgt_03_02_exact_before ⊑ ashrsgt_03_02_exact_after

theorem sub_inc_proof : sub_inc_before ⊑ sub_inc_after

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

theorem sgt_smax4_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_1 + 3#32 <ₛ x)

theorem or_test1_thm.extracted_1._1 : ∀ (x : BitVec 32), x &&& 1#32 ||

theorem main7f_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 main7f_thm.extracted_1._1 : ∀ (x x_1 x_2 x_3 x_4 : BitVec 32),
  ofBool (x_4 &&& x_3 == x_2 &&& (x_4 &&& x_3)) &&& ofBool (x_1 &&& x == x_2 &&& (x_1 &&& x)) = 1#1 →
    0#32 = zeroExtend 32 (ofBool (x_2 &&& (x_4 &&& x_3 ||| x_1 &&& x) != x_4 &&& x_3 ||| x_1 &&& x))

theorem icmp_slt_0_xor_icmp_sgt_neg2_i32_thm (e : IntW 32) :
  LLVM.xor (lshr e (const? 32 31)) (zext 32 (icmp IntPred.sgt e (const? 32 (-2)))) ⊑
    zext 32 (icmp IntPred.ne e (const? 32 (-1)))

theorem and_or_not_not_commute4_proof : and_or_not_not_commute4_before ⊑ and_or_not_not_commute4_after

theorem eq1 : ∀ (w : Nat) (a : BitVec w), a = a

theorem or_nosignbit_select_shl_proof : or_nosignbit_select_shl_before ⊑ or_nosignbit_select_shl_after

theorem e_1876 :
     - 2 *  ~~~(a &&& b) + 2 * (c ||| (a &&&  ~~~b)) - 6 * ( ~~~a &&& (b ||| c)) - 1 * ( ~~~a ||| (b &&& c)) - 5 * (b ^^^ (a &&& c)) - 5 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) + 2 *  ~~~c + 1 * ((a &&& b) ^^^ (b ||| c)) + 7 * (a ||| (b ||| c)) + 4 * (a ^^^ c) - 3 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) - 7 *  ~~~(a &&&  ~~~c) - 1 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) - 3 *  ~~~(a ||| (b ^^^ c)) - 1 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 1 *  ~~~(a ^^^ ( ~~~b ||| c)) + 1 * (b ^^^ (a ||| (b ^^^ c))) + 1 *  ~~~(a ||| ( ~~~b &&& c)) + 1 *  ~~~( ~~~a &&& ( ~~~b &&& c)) - 7 * (b ^^^  ~~~(a ||| c)) - 1 * (c ||| (a ^^^ b)) - 2 * ( ~~~c ||| (a ^^^ b)) + 1 * (c ^^^ (a ||| ( ~~~b &&& c))) + 1 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) + 4 * (b ^^^ (a &&& ( ~~~b ||| c))) - 7 * ((a &&&  ~~~b) ||| (b ^^^ c)) + 1 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) + 11 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 6 * ((a ^^^ b) ||| (a ^^^ c)) - 6 * ((a ^^^ b) |||  ~~~(a ^^^ c)) - 7 *  ~~~(a |||  ~~~b) - 1 * (b ^^^  ~~~(a &&& (b &&& c))) - 3 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) + 5 *  ~~~(a ^^^ c) - 1 * (c &&& (a ||| b)) + 2 * ((a ^^^ b) &&& (a ^^^ c)) + 2 *  ~~~( ~~~a &&& (b ^^^ c)) + 1 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) - 1 * (c ^^^ (a ||| b)) + 15 *  ~~~(a ||| (b ||| c)) + 40 *  ~~~(a ||| ( ~~~b ||| c)) + 1 *  ~~~( ~~~a ||| (b ||| c)) - 5 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 16 * ( ~~~a &&& ( ~~~b &&& c)) + 20 * ( ~~~a &&& (b &&& c)) + 22 * (a &&& ( ~~~b &&& c)) + 6 * (a &&& (b &&& c)) =  - 1 * ((a &&&  ~~~b) ||| (a ^^^ (b ^^^ c))) - 4 * (b ^^^  ~~~(a &&& (b ||| c)))

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

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

theorem ule_or_not_min_commute_proof : ule_or_not_min_commute_before ⊑ ule_or_not_min_commute_after

theorem sub_ule_sext_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 x_2 : BitVec 8),
  ofBool (x_2 - x_1 ≤ᵤ signExtend 8 x) = ofBool (x_2 == x_1) ||

theorem oppositesign_proof : oppositesign_before ⊑ oppositesign_after

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

theorem a_false_implies_b_true2_thm.extracted_1._8 : ∀ (x x_1 : BitVec 1) (x_2 : BitVec 8),
  ¬ofBool (x_2 <ᵤ 20#8) = 1#1 → ¬ofBool (10#8 <ᵤ x_2) = 1#1 → ofBool (10#8 <ᵤ x_2) ||

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

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

theorem samesign_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 &&& x <ₛ 0#32) ||

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

theorem c_1_1_0_proof : c_1_1_0_before ⊑ c_1_1_0_after

theorem xor_to_xor4_proof : xor_to_xor4_before ⊑ xor_to_xor4_after

theorem test5_proof : test5_before ⊑ test5_after

theorem multiuse_shl_shl_thm.extracted_1._1 : ∀ (x : BitVec 42),
  ¬(8#42 ≥ ↑42 ∨ 8#42 ≥ ↑42 ∨ 9#42 ≥ ↑42) → 8#42 ≥ ↑42 ∨ 17#42 ≥ ↑42 → False

@[simp] theorem msb_signExtend_of_ge {i} (h : i ≥ w) (x : BitVec w) :
    (x.signExtend i).msb = x.msb

theorem do_not_add_annotation_to_existing_instr_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  0#32 + (x_1 + x) = x_1 + x

theorem test1_proof : test1_before ⊑ test1_after

theorem e_354 :
     - 1 *  ~~~(x &&& y) + 11 * x + 7 * y + 5 *  ~~~x - 1 *  ~~~(x ^^^ y) - 5 *  ~~~(x ||| y) - 13 *  ~~~(x |||  ~~~y) - 10 * (x &&&  ~~~y) = 19 * (x &&& y) - 2 *  ~~~(x &&&  ~~~y)

theorem zext_nneg_sext_ule_op0_wide_proof : zext_nneg_sext_ule_op0_wide_before ⊑ zext_nneg_sext_ule_op0_wide_after

theorem exact_lshr_ne_both_equal_proof : exact_lshr_ne_both_equal_before ⊑ exact_lshr_ne_both_equal_after

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

theorem test13_thm.extracted_1._1 : ∀ (x : BitVec 1024),
  ¬1016#1024 ≥ ↑1024 → x.sshiftRight' 1016#1024 &&& 255#1024 = x >>> 1016#1024

theorem slt_smin1_thm (e e_1 : IntW 32) :
  icmp IntPred.slt (select (icmp IntPred.slt e_1 e) e_1 e) e_1 ⊑ icmp IntPred.slt e e_1

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

@[bv_multi_width_normalize↓] theorem not_forall (p : α → Prop) : (¬∀ x, p x) = ∃ x, ¬p x

theorem multiuse_select_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → 64#64 * (64#64 - zeroExtend 64 x) = 4032#64

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

lemma CNFA.autWidth_finals (hn : s < n + 2) : s ∈ (autWidth wp n).m.finals ↔ wp.final? n s

theorem select_constants_and_icmp_ne0_common_bit_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1),
  ¬x_1 = 1#1 → x = 1#1 → ofBool (3#8 &&& 2#8 != 0#8) = 1#1

theorem test_or3_logical_proof : test_or3_logical_before ⊑ test_or3_logical_after

theorem test7_thm (e : IntW 32) :
  sext 64 (sub (const? 32 20000) (LLVM.and e (const? 32 511))) ⊑
    zext 64 (sub (const? 32 20000) (LLVM.and e (const? 32 511)) { «nsw» := true, «nuw» := true })
      { «nneg» := true }

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

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

theorem p14_commutativity1_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x <ᵤ 65536#32) = 1#1 → ¬ofBool (65535#32 <ᵤ x) = 1#1 → 42#32 = 65535#32

theorem test47_thm (e : IntW 8) :
  zext 64 (LLVM.or (sext 32 e) (const? 32 42)) ⊑ zext 64 (sext 32 (LLVM.or e (const? 8 42)))

theorem ashr_can_be_lshr_2_proof : ashr_can_be_lshr_2_before ⊑ ashr_can_be_lshr_2_after

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

theorem e_1148 :
     - 7 * (z ^^^ t) - 6 *  ~~~(z &&&  ~~~z) + 11 * (z |||  ~~~t) - 1 *  ~~~z - 1 *  ~~~(z ^^^ t) + 16 *  ~~~(z |||  ~~~t) + 2 * (z &&&  ~~~t) - 2 * (z &&& t) = 2 *  ~~~(z &&&  ~~~t) + 1 *  ~~~(z ||| t)

theorem allOnes_xor_eq_not (x : BitVec w) : allOnes w ^^^ x = ~~~x

theorem test9_thm (e : IntW 32) : trunc 8 (LLVM.and e (const? 32 42)) ⊑ LLVM.and (trunc 8 e) (const? 8 42)

@[simp]
lemma RawCNFA.reverse_induction_helper {m : RawCNFA A} :
    (∃ ss', m.trans.toPFun (s, a) = some ss' ∧ s' ∈ ss') ↔ s' ∈ m.tr s a

theorem add_select_sext_proof : add_select_sext_before ⊑ add_select_sext_after

theorem xor_sge_proof : xor_sge_before ⊑ xor_sge_after

theorem e_915 :
     - 2 * z - 11 *  ~~~z + 2 * t + 14 *  ~~~(z ||| t) + 12 *  ~~~(z |||  ~~~t) + 5 * (z &&&  ~~~t) = 3 *  ~~~(z &&& t)

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

theorem lshr_shl_pow2_const_overflow_proof : lshr_shl_pow2_const_overflow_before ⊑ lshr_shl_pow2_const_overflow_after

theorem e_474 :
     - 11 *  ~~~x - 6 *  ~~~y - 6 * y - 5 * (x ||| y) - 1 * x + 3 * (x |||  ~~~y) + 14 *  ~~~(x ||| y) + 22 *  ~~~(x |||  ~~~y) + 9 * (x &&& y) =  - 9 * (x &&&  ~~~y)

theorem xor_signbit_select_lshr_thm (e : IntW 32) (e_1 : IntW 1) :
  lshr (select e_1 (LLVM.xor e (const? 32 (-65536))) e) (const? 32 8) ⊑
    select e_1 (LLVM.xor (lshr e (const? 32 8)) (const? 32 16776960)) (lshr e (const? 32 8))

@[simp, bitvec_to_nat]
lemma toNat_shiftLeft' (A B : BitVec w) :
    BitVec.toNat (A <<< B) = (BitVec.toNat A) * 2 ^ BitVec.toNat B % 2 ^w

theorem t7_ugt_sgt_neg1_proof : t7_ugt_sgt_neg1_before ⊑ t7_ugt_sgt_neg1_after

theorem ashr_sle_noexact_proof : ashr_sle_noexact_before ⊑ ashr_sle_noexact_after

theorem main14_logical_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (0#16 ≤ₛ truncate 16 x) = 1#1 → ofBool (x &&& 32896#32 == 0#32) = 1#1 → ¬0#1 = 1#1 → 1#32 = 2#32

theorem scalar_i32_signbit_lshr_and_slt_proof : scalar_i32_signbit_lshr_and_slt_before ⊑ scalar_i32_signbit_lshr_and_slt_after

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

theorem test22_thm.extracted_1._1 : ∀ (x : BitVec 14),
  ¬7#14 ≥ ↑14 → ofBool (x <<< 7#14 == 0#14) = ofBool (x &&& 127#14 == 0#14)

theorem udiv_shl_mul_nuw_proof : udiv_shl_mul_nuw_before ⊑ udiv_shl_mul_nuw_after

theorem basic_preserve_nuw_proof : basic_preserve_nuw_before ⊑ basic_preserve_nuw_after

theorem or_and2_thm (e e_1 e_2 : IntW 1) :
  select (LLVM.or (LLVM.xor e_2 (const? 1 1)) e_1) e_1 e ⊑ select e_1 (const? 1 1) (select e_2 e (const? 1 0))

theorem test_and4_thm (e e_1 : IntW 32) :
  LLVM.and (icmp IntPred.sge (LLVM.and e_1 (const? 32 2147483647)) e) (icmp IntPred.sge e (const? 32 0)) ⊑
    icmp IntPred.ule e (LLVM.and e_1 (const? 32 2147483647))

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

theorem bv_239 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.mul (LLVM.sub (LLVM.const? w 0) e_1) (LLVM.sub (LLVM.const? w 0) e) ⊑ LLVM.mul e_1 e

theorem src_tv_eq_proof : src_tv_eq_before ⊑ src_tv_eq_after

theorem positive_biggerLshr_lshrexact_proof : positive_biggerLshr_lshrexact_before ⊑ positive_biggerLshr_lshrexact_after

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

theorem pr40493_neg3_proof : pr40493_neg3_before ⊑ pr40493_neg3_after

theorem n1_proof : n1_before ⊑ n1_after

theorem t13_x_is_one_proof : t13_x_is_one_before ⊑ t13_x_is_one_after

theorem testi32i8_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(7#8 ≥ ↑8 ∨ 8#32 ≥ ↑32) →
    ¬ofBool ((truncate 8 x).sshiftRight' 7#8 == truncate 8 (x >>> 8#32)) = 1#1 →
      ¬15#32 ≥ ↑32 → truncate 8 (x.sshiftRight' 15#32) ^^^ 127#8 = truncate 8 (x >>> 15#32) ^^^ 127#8

theorem or_or_logic_and_2_proof : or_or_logic_and_2_before ⊑ or_or_logic_and_2_after

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

theorem e_2267 :
    3 * (f &&&  ~~~(d &&& e)) + 4 * ((d &&& f) ^^^ (e ||| f)) + 4 * (d ^^^ e) - 11 *  ~~~( ~~~d &&& (e &&& f)) + 1 *  ~~~(d ||| f) - 2 *  ~~~(d ^^^ e) - 3 * (f ^^^ (d &&& ( ~~~e ||| f))) + 1 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 1 * ( ~~~d &&& (e ||| f)) + 2 *  ~~~(d ||| e) + 1 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 3 *  ~~~( ~~~d &&& (e ^^^ f)) - 1 * (f ^^^  ~~~(d &&& e)) - 5 *  ~~~(d &&& e) + 5 * ( ~~~d &&& ( ~~~e ||| f)) - 1 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 1 * (e ^^^  ~~~(d |||  ~~~f)) + 5 *  ~~~(d ||| ( ~~~e &&& f)) + 1 * (d &&&  ~~~f) + 1 * (f |||  ~~~(d ^^^ e)) + 1 * (f &&& (d |||  ~~~e)) + 1 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 1 * (e &&& (d |||  ~~~f)) - 11 * (f &&&  ~~~(d &&&  ~~~e)) - 11 *  ~~~(d &&& (e ^^^ f)) + 3 *  ~~~(e ||| f) - 5 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 2 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 1 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * ( ~~~e |||  ~~~(d ^^^ f)) + 4 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 11 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 2 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 3 * (e &&&  ~~~(d &&& f)) + 3 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 1 * (e ^^^ (d ||| (e &&& f))) - 2 * (e ^^^ ( ~~~d ||| (e &&& f))) + 3 *  ~~~(d |||  ~~~f) - 1 * (d &&& (e ||| f)) + 2 * (e ^^^  ~~~(d ||| f)) - 7 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 6 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 1 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 3 * (f ^^^ (d &&& e)) + 2 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 7 * (d ||| e) - 11 *  ~~~(d &&& ( ~~~e &&& f)) - 5 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 1 *  ~~~(e &&&  ~~~f) - 6 * (e |||  ~~~f) + 30 *  ~~~(d ||| (e ||| f)) + 16 *  ~~~(d ||| ( ~~~e ||| f)) + 46 *  ~~~( ~~~d ||| (e ||| f)) + 15 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 27 * ( ~~~d &&& ( ~~~e &&& f)) + 21 * ( ~~~d &&& (e &&& f)) - 2 * (d &&& ( ~~~e &&& f)) + 54 * (d &&& (e &&& f)) =  - 7 *  ~~~(d &&& ( ~~~e ||| f))

theorem test1_proof : test1_before ⊑ test1_after

theorem p_proof : p_before ⊑ p_after

theorem and_ne_with_one_bit_diff_constants1_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x != 51#32) = 1#1 → 0#1 = ofBool (x + BitVec.ofInt 32 (-52) <ᵤ BitVec.ofInt 32 (-2))

theorem shl_lshr_and_exact_thm (e e_1 e_2 : IntW 32) :
  lshr (LLVM.and (shl e_2 e_1 { «nsw» := false, «nuw» := true }) e) e_1 { «exact» := true } ⊑
    LLVM.and (lshr e e_1) e_2

theorem ashr_ult_15_proof : ashr_ult_15_before ⊑ ashr_ult_15_after

@[simp, simp_denote]
theorem liftEffect_rfl [Pure m] (hle : eff ≤ eff) :
    liftEffect hle (α := α) (m := m) = id

theorem lshrugt_03_10_proof : lshrugt_03_10_before ⊑ lshrugt_03_10_after

theorem icmp_sgt8_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (x <<< 1#8).sshiftRight' 1#8 ≠ x ∨ 1#8 ≥ ↑8) → ofBool (125#8 <ₛ x <<< 1#8) = ofBool (x == 63#8)

theorem test_mul_nuw__none_are_safe_proof : test_mul_nuw__none_are_safe_before ⊑ test_mul_nuw__none_are_safe_after

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

theorem e_388 :
    11 *  ~~~y + 2 * y + 5 * (x ^^^ y) - 2 *  ~~~x - 6 * (x |||  ~~~y) - 5 *  ~~~(x &&&  ~~~x) + 2 *  ~~~(x ||| y) + 9 * (x &&& y) = 5 * (x &&&  ~~~y)

theorem trunc_signed_nsw_sext_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ¬(True ∧ signExtend 32 (truncate 16 x_1) ≠ x_1) →
    ofBool (truncate 16 x_1 <ₛ signExtend 16 x) = ofBool (x_1 <ₛ signExtend 32 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 test70_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x_1 <ₛ 0#8) = 1#1 → 6#8 ≥ ↑8 → False

theorem icmp_eq_or_z_or_pow2orz_fail_nonzero_const_proof : icmp_eq_or_z_or_pow2orz_fail_nonzero_const_before ⊑ icmp_eq_or_z_or_pow2orz_fail_nonzero_const_after

theorem ult_and_not_max_proof : ult_and_not_max_before ⊑ ult_and_not_max_after

theorem bv_AndOrXor_135 :
    ∀ (e e_1 e_2 : LLVM.IntW w), LLVM.and (LLVM.xor e e_1) e_2 ⊑ LLVM.xor (LLVM.and e e_2) (LLVM.and e_1 e_2)

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

theorem ashrslt_02_11_proof : ashrslt_02_11_before ⊑ ashrslt_02_11_after

@[simp] theorem Valuation.comap_cons_consRight {Γ Δ : Ctxt Ty} (Γv : Valuation Γ) (f : Hom Δ Γ) :
    comap (Γv.cons x) (f.consRight) = comap Γv f

theorem PR30273_three_bools_thm.extracted_1._3 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 →
    x_1 = 1#1 →
      ¬(True ∧ (zeroExtend 32 x).saddOverflow 1#32 = true) →
        ¬x = 1#1 →
          ¬(True ∧ (zeroExtend 32 x + 1#32).saddOverflow 1#32 = true) →
            True ∧ (1#32).saddOverflow (zeroExtend 32 x_2) = true ∨
                True ∧ (1#32).uaddOverflow (zeroExtend 32 x_2) = true →
              False

theorem test56_proof : test56_before ⊑ test56_after
</all_available_lemmas>

<local_ctx>
import Batteries.Data.Fin.Basic

import Batteries.Data.Fin.Lemmas

import Blase.SingleWidth.Defs

import Blase.AutoStructs.Constructions

import Blase.AutoStructs.Defs

import Blase.AutoStructs.FiniteStateMachine

import Mathlib.Tactic.Ring

import Mathlib.Data.Nat.Size -- TODO: remove and get rid of shiftLeft_eq_mul_pow use

import Mathlib.Data.BitVec

import Mathlib.Tactic.FinCases

open Fin.NatCast

open Mathlib

def NFA.sa (_ : NFA α σ) := σ → Language α

structure NFA.correct (M : NFA α σ) (ζ : M.sa) (L : Language α) where
  cond1 : ∀ w, (w ∈ L ↔ ∃ q ∈ M.accept, w ∈ ζ q)
  cond2 : ∀ w q, q ∈ M.eval w ↔ w ∈ ζ q

abbrev BVNRel n := ∀ ⦃w⦄, List.Vector (BitVec w) n → Prop

def NFA'.sa (M : NFA' n) := M.σ → BVNRel n

def langRel (R : BVNRel n) : Set (BitVecs n) :=
  { bvs | R bvs.bvs }

structure NFA'.correct (M : NFA' n) (ζ : M.sa) (L : BVNRel n) where
  cond1 : ∀ ⦃w⦄ (bvn : List.Vector (BitVec w) n), (L bvn ↔ ∃ q ∈ M.M.accept, ζ q bvn)
  cond2 q : q ∈ M.M.start ↔ ζ q (List.Vector.replicate n .nil)
  cond3 q a {w} (bvn : List.Vector (BitVec w) n) : q ∈ M.M.stepSet { q | ζ q bvn } a ↔
              ζ q (List.Vector.ofFn fun k => BitVec.cons (a.getLsbD k) (bvn.get k))

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

section fsm

abbrev Alphabet (arity: Type) [FinEnum arity] := BitVec (FinEnum.card arity + 1)

variable {arity : Type} [FinEnum arity]

def finFunToBitVec [fe : FinEnum carry] (c : carry → Bool) : BitVec (FinEnum.card carry) :=
  BitVec.ofFn fun i => c (fe.equiv.invFun i)

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

def NFA.ofFSM (p : FSM arity) : NFA (Alphabet arity) (p.α → Bool) where
  start := { q | q = p.initCarry }
  accept := ⊤
  step s a := {s' |
    let (s'', b) := p.nextBit s (bitVecToFinFun (a.truncate $ FinEnum.card arity))
    s' = s'' ∧ a.msb = b }

@[simp]
abbrev inFSMRel (p : FSM arity) {w} (bvn : List.Vector (BitVec w) _) :=
  bvn.get (Fin.last (FinEnum.card arity)) = p.evalBV (fun ar => bvn.get (FinEnum.equiv.toFun ar))

def NFA'.ofFSM_sa (p : FSM arity) : (NFA'.ofFSM' p).sa := fun q _ bvn =>
    inFSMRel p bvn ∧ q = p.carryBV (fun ar => bvn.get (FinEnum.equiv.toFun ar))

def NFA'.ofFSM_correct (p : FSM arity) :
    (NFA'.ofFSM' p).correct (ofFSM_sa p) (fun _ bvn => inFSMRel p bvn) :=

open BitStream in

def CNFA.ofFSM (p : FSM arity) : CNFA (FinEnum.card arity + 1) :=
  worklistRun (BitVec (FinEnum.card p.α))
    (fun _ => true)
    #[finFunToBitVec p.initCarry]
    (by admit /- proof elided -/
    )
    f
  where

end fsm

section nfas_relations

inductive NFA.msbState : Type where
| i | f
deriving DecidableEq, Fintype

end nfas_relations

def liftOp n : Fin (n + 1) → Fin (n + 3) :=
  fun k =>
    if k = n then Fin.last (n+2) else k.castLE (by admit /- proof elided -/
    )

@[simp]
def liftOp_unchanged (k : Fin n) : liftOp n k.castSucc = k.castLE (by simp) :=

inductive TermBinop where
| and | or | xor | add | sub

def TermBinop.subst (op : TermBinop) (t₁ t₂ : Term) : Term :=
  match op with
  | .and => .and t₁ t₂
  | .or => .or t₁ t₂
  | .xor => .xor t₁ t₂
  | .add => .add t₁ t₂
  | .sub => .sub t₁ t₂

def TermBinop.openTerm (op : TermBinop) : Term := op.subst (.var 0) (.var 1)

@[simp]
def TermBinop.openTerm_arity (op : TermBinop) : op.openTerm.arity + 1 = 3 :=

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

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

def swapLastTwoBlock (x : Fin (n + 3)) : Fin (n + 3) :=
  if x = Fin.last (n+2) then n
  else if x = n+1 then Fin.last (n + 2)
  else if x = n then n + 1
  else x

inductive TermUnop where
| neg | not | shiftL (k : Nat)

def TermUnop.openTerm (op : TermUnop) : Term :=
  match op with
  | .neg => .neg (.var 0)
  | .not => .not (.var 0)
  | .shiftL k => .shiftL (.var 0) k

def TermUnop.openTerm_arity (op : TermUnop) : op.openTerm.arity = 1 :=

def TermUnop.subst (op : TermUnop) (t : Term) : Term :=
  match op with
  | .neg => .neg t
  | .not => .not t
  | .shiftL k => .shiftL t k
</local_ctx>

<target_theorem>
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)) :=
</target_theorem>

