import Do.For -- import `runCatch`
import Lean
import Aesop
Formalization of Extended do
Translation
An intrinsically typed representation of the paper's syntax of do
statements as well
of their translation functions and an equivalence proof thereof to a simple denotational semantics.
Contexts
We represent contexts as lists of types and assignments of them as heterogeneous lists over these types. As is common with lists, contexts grow to the left in our presentation. The following encoding of heterogeneous lists avoids the universe bump of the usual inductive definition (https://lists.chalmers.se/pipermail/agda/2010/001826.html).
def HList: List (Type u) → Type u
HList : List: Type (u + 1) → Type (u + 1)
List (Type u: Type (u + 1)
Type u) → Type u: Type (u + 1)
Type u
| [] => PUnit: Type u
PUnit
| α: Type u
α :: αs: List (Type u)
αs => α: Type u
α × HList: List (Type u) → Type u
HList αs: List (Type u)
αs
@[matchPattern] abbrev HList.nil: HList []
HList.nil : HList: List (Type u_1) → Type u_1
HList []: List (Type u_1)
[] := ⟨⟩: PUnit
⟨⟩
@[matchPattern] abbrev HList.cons: {α : Type u_1} → {αs : List (Type u_1)} → α → HList αs → HList (α :: αs)
HList.cons (a: α
a : α: Type u_1
α) (as: HList αs
as : HList: List (Type u_1) → Type u_1
HList αs: List (Type u_1)
αs) : HList: List (Type u_1) → Type u_1
HList (α: Type u_1
α :: αs: List (Type u_1)
αs) := (a: α
a, as: HList αs
as)
We overload the common list notations ::
and [e, ...]
for HList
.
infixr:67 " :: " => HList.cons
syntax (name := hlistCons) "[" term,* "]" : term
macro_rules (kind := hlistCons)
| `([]) => `(HList.nil): Lean.MacroM Lean.Syntax
`(HList.nil)
| `([$x: Lean.TSyntax `term
x]) => `(HList.cons $x: Lean.TSyntax `term
x [])
| `([$x: Lean.TSyntax `term
x, $xs: Lean.Syntax.TSepArray `term ","
xs,*]) => `(HList.cons $x: Lean.TSyntax `term
x [$xs: Lean.Syntax.TSepArray `term ","
xs,*])
Lean's very general, heterogeneous definition of ++
causes some issues with our overloading above in terms
such as a ++ [b]
, so we restrict it to the List
interpretation in the following, which is sufficient for our purposes.
local macro_rules
| `($a: Lean.TSyntax `term
a ++ $b: Lean.TSyntax `term
b) => `(List.append $a: Lean.TSyntax `term
a $b: Lean.TSyntax `term
b)
abbrev Assg: List (Type u_1) → Type u_1
Assg Γ: List (Type u_1)
Γ := HList: List (Type u_1) → Type u_1
HList Γ: List (Type u_1)
Γ
Updating a heterogeneous list at a given, guaranteed in-bounds index.
def HList.set: {αs : List (Type u)} → HList αs → (i : Fin (List.length αs)) → List.get αs i → HList αs
HList.set : {αs: List (Type u)
αs : List: Type (u + 1) → Type (u + 1)
List (Type u: Type (u + 1)
Type u)} → HList: List (Type u) → Type u
HList αs: List (Type u)
αs → (i: Fin (List.length αs)
i : Fin: Nat → Type
Fin αs: List (Type u)
αs.length: {α : Type (u + 1)} → List α → Nat
length) → αs: List (Type u)
αs.get: {α : Type (u + 1)} → (as : List α) → Fin (List.length as) → α
get i: Fin (List.length αs)
i → HList: List (Type u) → Type u
HList αs: List (Type u)
αs
| _ :: _, _ :: as: HList a✝
as, ⟨0: Nat
0, _⟩, b: List.get (α✝ :: a✝) { val := 0, isLt := isLt✝ }
b => b: List.get (α✝ :: a✝) { val := 0, isLt := isLt✝ }
b :: as: HList a✝
as
| _ :: _, a: α✝
a :: as: HList a✝
as, ⟨Nat.succ: Nat → Nat
Nat.succ n: Nat
n, h: Nat.succ n < List.length (α✝ :: a✝)
h⟩, b: List.get (α✝ :: a✝) { val := Nat.succ n, isLt := h }
b => a: α✝
a :: set: {αs : List (Type u)} → HList αs → (i : Fin (List.length αs)) → List.get αs i → HList αs
set as: HList a✝
as ⟨n: Nat
n, Nat.le_of_succ_le_succ: ∀ {n m : Nat}, Nat.succ n ≤ Nat.succ m → n ≤ m
Nat.le_of_succ_le_succ h: Nat.succ n < List.length (α✝ :: a✝)
h⟩ b: List.get (α✝ :: a✝) { val := Nat.succ n, isLt := h }
b
| [], [], _, _ => []: HList []
[]
We write ∅
for empty contexts and assignments and Γ ⊢ α
for the type of values of type α
under the context Γ
- that is, the function type from an assignment to
α
.
instance: EmptyCollection (Assg ∅)
instance : EmptyCollection: Type u_1 → Type u_1
EmptyCollection (Assg: List (Type u_1) → Type u_1
Assg ∅: List (Type u_1)
∅) where
emptyCollection := []: HList []
[]
instance: CoeSort (List (Type u)) (Type u)
instance : CoeSort: Type (u + 1) → outParam (Type (u + 1)) → Type (u + 1)
CoeSort (List: Type (u + 1) → Type (u + 1)
List (Type u: Type (u + 1)
Type u)) (Type u: Type (u + 1)
Type u) := ⟨Assg: List (Type u) → Type u
Assg⟩
notation:30 Γ: Lean.TSyntax `term
Γ " ⊢ " α: Lean.TSyntax `term
α => Assg Γ: Lean.TSyntax `term
Γ → α: Lean.TSyntax `term
α
def Assg.drop: {α : Type u_1} → {Γ : List (Type u_1)} → Assg (α :: Γ) → Assg Γ
Assg.drop : Assg: List (Type u_1) → Type u_1
Assg (α: Type u_1
α :: Γ: List (Type u_1)
Γ) → Assg: List (Type u_1) → Type u_1
Assg Γ: List (Type u_1)
Γ
| _ :: as: HList Γ
as => as: HList Γ
as
In one special case, we will need to manipulate contexts from the right, i.e. the outermost scope.
def Assg.extendBot: {α : Type u_1} → α → {Γ : List (Type u_1)} → Assg Γ → Assg (List.append Γ [α])
Assg.extendBot (x: α
x : α: Type u_1
α) : {Γ: List (Type u_1)
Γ : _: Type (u_1 + 1)
_} → Assg: List (Type u_1) → Type u_1
Assg Γ: List (Type u_1)
Γ → Assg: List (Type u_1) → Type u_1
Assg (Γ: List (Type u_1)
Γ ++ [α: Type u_1
α])
| [], [] => [x: α
x]
| _ :: _, a: α✝
a :: as: HList a✝
as => a: α✝
a :: extendBot: {α : Type u_1} → α → {Γ : List (Type u_1)} → Assg Γ → Assg (List.append Γ [α])
extendBot x: α
x as: HList a✝
as
def Assg.dropBot: {α : Type u_1} → {Γ : List (Type u_1)} → Assg (List.append Γ [α]) → Assg Γ
Assg.dropBot : {Γ: List (Type u_1)
Γ : _: Type (u_1 + 1)
_} → Assg: List (Type u_1) → Type u_1
Assg (Γ: List (Type u_1)
Γ ++ [α: Type u_1
α]) → Assg: List (Type u_1) → Type u_1
Assg Γ: List (Type u_1)
Γ
| [], _ => []: HList []
[]
| _ :: _: List (Type u_1)
_, a: α✝
a :: as: HList (List.append tail✝ [α])
as => a: α✝
a :: dropBot: {α : Type u_1} → {Γ : List (Type u_1)} → Assg (List.append Γ [α]) → Assg Γ
dropBot as: HList (List.append tail✝ [α])
as
Intrinsically Typed Representation of do
Statements
where
- m: base monad
- ω:
return
type,m ω
is the type of the entiredo
block - Γ:
do
-local immutable context - Δ:
do
-local mutable context - b:
break
allowed - c:
continue
allowed - α: local result type,
m α
is the type of the statement
The constructor signatures are best understood by comparing them with the corresponding typing rules in the paper.
Note that the choice of de Bruijn indices changes/simplifies some parts, such as obviating freshness checks (x ∉ Δ
).
inductive Stmt: (Type → Type u) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u)
Stmt (m: Type → Type u
m : Type: Type 1
Type → Type u: Type (u + 1)
Type u) (ω: Type
ω : Type: Type 1
Type) : (Γ: List Type
Γ Δ: List Type
Δ : List: Type 1 → Type 1
List Type: Type 1
Type) → (b: Bool
b c: Bool
c : Bool: Type
Bool) → (α: Type
α : Type: Type 1
Type) → Type _: Type ((max 1 u) + 1)
Type _ where
| expr: {m : Type → Type u} →
{ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α
expr (e: Assg Γ → Assg Δ → m α
e : Γ: List Type
Γ ⊢ Δ: List Type
Δ ⊢ m: Type → Type u
m α: Type
α) : Stmt: (Type → Type u) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u)
Stmt m: Type → Type u
m ω: Type
ω Γ: List Type
Γ Δ: List Type
Δ b: Bool
b c: Bool
c α: Type
α
| bind: {m : Type → Type u} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c β
bind (s: Stmt m ω Γ Δ b c α
s : Stmt: (Type → Type u) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u)
Stmt m: Type → Type u
m ω: Type
ω Γ: List Type
Γ Δ: List Type
Δ b: Bool
b c: Bool
c α: Type
α) (s': Stmt m ω (α :: Γ) Δ b c β
s' : Stmt: (Type → Type u) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u)
Stmt m: Type → Type u
m ω: Type
ω (α: Type
α :: Γ: List Type
Γ) Δ: List Type
Δ b: Bool
b c: Bool
c β: Type
β) : Stmt: (Type → Type u) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u)
Stmt m: Type → Type u
m ω: Type
ω Γ: List Type
Γ Δ: List Type
Δ b: Bool
b c: Bool
c β: Type
β -- let _ ← s; s'
| letmut: {m : Type → Type u} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} → {b c : Bool} → {β : Type} → (Assg Γ → Assg Δ → α) → Stmt m ω Γ (α :: Δ) b c β → Stmt m ω Γ Δ b c β
letmut (e: Assg Γ → Assg Δ → α
e : Γ: List Type
Γ ⊢ Δ: List Type
Δ ⊢ α: Type
α) (s: Stmt m ω Γ (α :: Δ) b c β
s : Stmt: (Type → Type u) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u)
Stmt m: Type → Type u
m ω: Type
ω Γ: List Type
Γ (α: Type
α :: Δ: List Type
Δ) b: Bool
b c: Bool
c β: Type
β) : Stmt: (Type → Type u) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u)
Stmt m: Type → Type u
m ω: Type
ω Γ: List Type
Γ Δ: List Type
Δ b: Bool
b c: Bool
c β: Type
β -- let mut _ := e; s
| assg: {m : Type → Type u} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → (x : Fin (List.length Δ)) → (Assg Γ → Assg Δ → List.get Δ x) → Stmt m ω Γ Δ b c Unit
assg (x: failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)
x : Fin: Nat → Type
Fin Δ: List Type
ΔΔ.length: Nat
.length: {α : Type 1} → List α → Nat
length) (e: failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)
e : Γ: List Type
Γ ⊢ Δ: List Type
Δ ⊢ Δ: List Type
Δ.get: {α : Type 1} → (as : List α) → Fin (List.length as) → α
get x: failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)
x) : Stmt: (Type → Type u) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u)
Stmt m: Type → Type u
m ω: Type
ω Γ: List Type
Γ Δ: List Type
Δ b: Bool
b c: Bool
c Unit: Type
Unit -- x := e
| ite: {m : Type → Type u} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} →
{α : Type} → (Assg Γ → Assg Δ → Bool) → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α
ite (e: Assg Γ → Assg Δ → Bool
e : Γ: List Type
Γ ⊢ Δ: List Type
Δ ⊢ Bool: Type
Bool) (s₁: Stmt m ω Γ Δ b c α
s₁ s₂: Stmt m ω Γ Δ b c α
s₂ : Stmt: (Type → Type u) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u)
Stmt m: Type → Type u
m ω: Type
ω Γ: List Type
Γ Δ: List Type
Δ b: Bool
b c: Bool
c α: Type
α) : Stmt: (Type → Type u) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u)
Stmt m: Type → Type u
m ω: Type
ω Γ: List Type
Γ Δ: List Type
Δ b: Bool
b c: Bool
c α: Type
α -- if e then s₁ else s₂
| ret: {m : Type → Type u} →
{ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → ω) → Stmt m ω Γ Δ b c α
ret (e: Assg Γ → Assg Δ → ω
e : Γ: List Type
Γ ⊢ Δ: List Type
Δ ⊢ ω: Type
ω) : Stmt: (Type → Type u) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u)
Stmt m: Type → Type u
m ω: Type
ω Γ: List Type
Γ Δ: List Type
Δ b: Bool
b c: Bool
c α: Type
α -- return e
| sfor: {m : Type → Type u} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} → (Assg Γ → Assg Δ → List α) → Stmt m ω (α :: Γ) Δ true true Unit → Stmt m ω Γ Δ b c Unit
sfor (e: Assg Γ → Assg Δ → List α
e : Γ: List Type
Γ ⊢ Δ: List Type
Δ ⊢ List: Type → Type
List α: Type
α) (s: Stmt m ω (α :: Γ) Δ true true Unit
s : Stmt: (Type → Type u) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u)
Stmt m: Type → Type u
m ω: Type
ω (α: Type
α :: Γ: List Type
Γ) Δ: List Type
Δ true: Bool
true true: Bool
true Unit: Type
Unit) : Stmt: (Type → Type u) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u)
Stmt m: Type → Type u
m ω: Type
ω Γ: List Type
Γ Δ: List Type
Δ b: Bool
b c: Bool
c Unit: Type
Unit -- for _ in e do s
| sbreak: {m : Type → Type u} → {ω : Type} → {Γ Δ : List Type} → {c : Bool} → {α : Type} → Stmt m ω Γ Δ true c α
sbreak : Stmt: (Type → Type u) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u)
Stmt m: Type → Type u
m ω: Type
ω Γ: List Type
Γ Δ: List Type
Δ true: Bool
true c: Bool
c α: Type
α -- break
| scont: {m : Type → Type u} → {ω : Type} → {Γ Δ : List Type} → {b : Bool} → {α : Type} → Stmt m ω Γ Δ b true α
scont : Stmt: (Type → Type u) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u)
Stmt m: Type → Type u
m ω: Type
ω Γ: List Type
Γ Δ: List Type
Δ b: Bool
b true: Bool
true α: Type
α -- continue
Neutral statements are a restriction of the above type.
inductive Neut: Type → Type → Bool → Bool → Type
Neut (ω: Type
ω α: Type
α : Type: Type 1
Type) : (b: Bool
b c: Bool
c : Bool: Type
Bool) → Type _: Type 1
Type _ where
| val: {ω α : Type} → {b c : Bool} → α → Neut ω α b c
val (a: α
a : α: Type
α) : Neut: Type → Type → Bool → Bool → Type
Neut ω: Type
ω α: Type
α b: Bool
b c: Bool
c
| ret: {ω α : Type} → {b c : Bool} → ω → Neut ω α b c
ret (o: ω
o : ω: Type
ω) : Neut: Type → Type → Bool → Bool → Type
Neut ω: Type
ω α: Type
α b: Bool
b c: Bool
c
| rbreak: {ω α : Type} → {c : Bool} → Neut ω α true c
rbreak : Neut: Type → Type → Bool → Bool → Type
Neut ω: Type
ω α: Type
α true: Bool
true c: Bool
c
| rcont: {ω α : Type} → {b : Bool} → Neut ω α b true
rcont : Neut: Type → Type → Bool → Bool → Type
Neut ω: Type
ω α: Type
α b: Bool
b true: Bool
true
We elide Neut.val
where unambiguous.
instance: {α ω : Type} → {b c : Bool} → Coe α (Neut ω α b c)
instance : Coe: Type → Type → Type
Coe α: Type
α (Neut: Type → Type → Bool → Bool → Type
Neut ω: Type
ω α: Type
α b: Bool
b c: Bool
c) := ⟨Neut.val: {ω α : Type} → {b c : Bool} → α → Neut ω α b c
Neut.val⟩
instance: {α ω : Type} → {b c : Bool} → Coe (Id α) (Neut ω α b c)
instance : Coe: Type → Type → Type
Coe (Id: Type → Type
Id α: Type
α) (Neut: Type → Type → Bool → Bool → Type
Neut ω: Type
ω α: Type
α b: Bool
b c: Bool
c) := ⟨Neut.val: {ω α : Type} → {b c : Bool} → α → Neut ω α b c
Neut.val⟩
We write e[ρ][σ]
for the substitution of both contexts in e
, a simple application in this encoding.
σ[x ↦ v]
updates σ
at v
(a de Bruijn index).
macro:max (priority := high) e: Lean.TSyntax `term
e:term:max noWs "[" ρ: Lean.TSyntax `term
ρ:term "]" "[" σ: Lean.TSyntax `term
σ:term "]" : term => `($e: Lean.TSyntax `term
e $ρ: Lean.TSyntax `term
ρ $σ: Lean.TSyntax `term
σ)
macro:max (priority := high) σ: Lean.TSyntax `term
σ:term:max noWs "[" x: Lean.TSyntax `term
x:term " ↦ " v: Lean.TSyntax `term
v:term "]" : term => `(HList.set $σ: Lean.TSyntax `term
σ $x: Lean.TSyntax `term
x $v: Lean.TSyntax `term
v)
Dynamic Evaluation Function
A direct encoding of the paper's operational semantics as a denotational function,
generalized over an arbitrary monad.
Note that the immutable context ρ
is accumulated (v :: ρ
) and passed explicitly instead of immutable
bindings being substituted immediately as that is a better match for the above definition of Stmt
.
Iteration over the values of the given list in the for
case introduces a nested, mutually recursive helper
function, with termination of the mutual bundle following from a size argument over the statement primarily
and the length of the list in the for
case secondarily.
@[simp] def Stmt.eval: {m : Type → Type u_1} →
{Γ : List Type} →
{ω : Type} →
{Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)
Stmt.eval [Monad: (Type ?u.21808 → Type ?u.21807) → Type (max (?u.21808 + 1) ?u.21807)
Monad m: Type → Type u_1
m] (ρ: Assg Γ
ρ : Assg: List Type → Type
Assg Γ: List Type
Γ) : Stmt: (Type → Type u_1) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u_1)
Stmt m: Type → Type u_1
m ω: Type
ω Γ: List Type
Γ Δ: List Type
Δ b: Bool
b c: Bool
c α: Type
α → Assg: List Type → Type
Assg Δ: List Type
Δ → m: Type → Type u_1
m (Neut: Type → Type → Bool → Bool → Type
Neut ω: Type
ω α: Type
α b: Bool
b c: Bool
c × Assg: List Type → Type
Assg Δ: List Type
Δ)
| expr: {m : Type → Type ?u.32858} →
{ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α
expr e: Assg Γ → Assg Δ → m α
e, σ: Assg Δ
σ => e: Assg Γ → Assg Δ → m α
e[ρ: Assg Γ
ρ][σ: Assg Δ
σ] >>= fun v: α
v => pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f α
pure ⟨v: α
v, σ: Assg Δ
σ⟩
| bind: {m : Type → Type ?u.33084} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c β
bind s: Stmt m ω Γ Δ b c α✝
s s': Stmt m ω (α✝ :: Γ) Δ b c α
s', σ: Assg Δ
σ =>
-- defining this part as a separate definition helps Lean with the termination proof
let rec @[simp] cont: (α✝ → Assg Δ → m (Neut ω α b c × Assg Δ)) → Neut ω α✝ b c × Assg Δ → m (Neut ω α b c × Assg Δ)
cont val: α✝ → Assg Δ → m (Neut ω α b c × Assg Δ)
val
| ⟨Neut.val: {ω α : Type} → {b c : Bool} → α → Neut ω α b c
Neut.val v: α✝
v, σ': Assg Δ
σ'⟩ => val: α✝ → Assg Δ → m (Neut ω α b c × Assg Δ)
val v: α✝
v σ': Assg Δ
σ'
-- the `Neut` type family forces us to repeat these cases as the LHS/RHS indices are not identical
| ⟨Neut.ret: {ω α : Type} → {b c : Bool} → ω → Neut ω α b c
Neut.ret o: ω
o, σ': Assg Δ
σ'⟩ => pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f α
pure ⟨Neut.ret: {ω α : Type} → {b c : Bool} → ω → Neut ω α b c
Neut.ret o: ω
o, σ': Assg Δ
σ'⟩
| ⟨Neut.rbreak: {ω α : Type} → {c : Bool} → Neut ω α true c
Neut.rbreak, σ': Assg Δ
σ'⟩ => pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f α
pure ⟨Neut.rbreak: {ω α : Type} → {c : Bool} → Neut ω α true c
Neut.rbreak, σ': Assg Δ
σ'⟩
| ⟨Neut.rcont: {ω α : Type} → {b : Bool} → Neut ω α b true
Neut.rcont, σ': Assg Δ
σ'⟩ => pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f α
pure ⟨Neut.rcont: {ω α : Type} → {b : Bool} → Neut ω α b true
Neut.rcont, σ': Assg Δ
σ'⟩
s: Stmt m ω Γ Δ b c α✝
s.eval: {m : Type → Type u_1} →
{Γ : List Type} →
{ω : Type} →
{Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)
eval ρ: Assg Γ
ρ σ: Assg Δ
σ >>= cont: (α✝ → Assg Δ → m (Neut ω α b c × Assg Δ)) → Neut ω α✝ b c × Assg Δ → m (Neut ω α b c × Assg Δ)
cont (fun v: α✝
v σ': Assg Δ
σ' => s': Stmt m ω (α✝ :: Γ) Δ b c α
s'.eval: {m : Type → Type u_1} →
{Γ : List Type} →
{ω : Type} →
{Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)
eval (v: α✝
v :: ρ: Assg Γ
ρ) σ': Assg Δ
σ')
| letmut: {m : Type → Type ?u.33463} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} → {b c : Bool} → {β : Type} → (Assg Γ → Assg Δ → α) → Stmt m ω Γ (α :: Δ) b c β → Stmt m ω Γ Δ b c β
letmut e: Assg Γ → Assg Δ → α✝
e s: Stmt m ω Γ (α✝ :: Δ) b c α
s, σ: Assg Δ
σ =>
s: Stmt m ω Γ (α✝ :: Δ) b c α
s.eval: {m : Type → Type u_1} →
{Γ : List Type} →
{ω : Type} →
{Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)
eval ρ: Assg Γ
ρ (e: Assg Γ → Assg Δ → α✝
e[ρ: Assg Γ
ρ][σ: Assg Δ
σ], σ: Assg Δ
σ) >>= fun ⟨r: Neut ω α b c
r, σ': Assg (α✝ :: Δ)
σ'⟩ => pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f α
pure ⟨r: Neut ω α b c
r, σ': Assg (α✝ :: Δ)
σ'.drop: {α : Type} → {Γ : List Type} → Assg (α :: Γ) → Assg Γ
drop⟩
-- `x` is a valid de Bruijn index into `σ` by definition of `assg`
| assg: {m : Type → Type ?u.35837} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → (x : Fin (List.length Δ)) → (Assg Γ → Assg Δ → List.get Δ x) → Stmt m ω Γ Δ b c Unit
assg x: Fin (List.length Δ)
x e: Assg Γ → Assg Δ → List.get Δ x
e, σ: Assg Δ
σ => pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f α
pure ⟨(): Unit
(), σ: Assg Δ
σ[x: Fin (List.length Δ)
x ↦ e: Assg Γ → Assg Δ → List.get Δ x
e[ρ: Assg Γ
ρ][σ: Assg Δ
σ]]⟩
| ite: {m : Type → Type ?u.36112} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} →
{α : Type} → (Assg Γ → Assg Δ → Bool) → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α
ite e: Assg Γ → Assg Δ → Bool
e s₁: Stmt m ω Γ Δ b c α
s₁ s₂: Stmt m ω Γ Δ b c α
s₂, σ: Assg Δ
σ => if e: Assg Γ → Assg Δ → Bool
e[ρ: Assg Γ
ρ][σ: Assg Δ
σ] then s₁: Stmt m ω Γ Δ b c α
s₁.eval: {m : Type → Type u_1} →
{Γ : List Type} →
{ω : Type} →
{Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)
eval ρ: Assg Γ
ρ σ: Assg Δ
σ else s₂: Stmt m ω Γ Δ b c α
s₂.eval: {m : Type → Type u_1} →
{Γ : List Type} →
{ω : Type} →
{Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)
eval ρ: Assg Γ
ρ σ: Assg Δ
σ
| ret: {m : Type → Type ?u.36353} →
{ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → ω) → Stmt m ω Γ Δ b c α
ret e: Assg Γ → Assg Δ → ω
e, σ: Assg Δ
σ => pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f α
pure ⟨Neut.ret: {ω α : Type} → {b c : Bool} → ω → Neut ω α b c
Neut.ret e: Assg Γ → Assg Δ → ω
e[ρ: Assg Γ
ρ][σ: Assg Δ
σ], σ: Assg Δ
σ⟩
| sfor: {m : Type → Type ?u.36472} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} → (Assg Γ → Assg Δ → List α) → Stmt m ω (α :: Γ) Δ true true Unit → Stmt m ω Γ Δ b c Unit
sfor e: Assg Γ → Assg Δ → List α✝
e s: Stmt m ω (α✝ :: Γ) Δ true true Unit
s, σ: Assg Δ
σ =>
let rec @[simp] go: Assg Δ → List α✝ → m (Neut ω Unit b c × Assg Δ)
go σ: Assg Δ
σ
| [] => pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f α
pure ⟨(): Unit
(), σ: Assg Δ
σ⟩
| a: α✝
a::as: List α✝
as =>
s: Stmt m ω (α✝ :: Γ) Δ true true Unit
s.eval: {m : Type → Type u_1} →
{Γ : List Type} →
{ω : Type} →
{Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)
eval (a: α✝
a :: ρ: Assg Γ
ρ) σ: Assg Δ
σ >>= fun
| ⟨(), σ': Assg Δ
σ'⟩ => go: Assg Δ → List α✝ → m (Neut ω Unit b c × Assg Δ)
go σ': Assg Δ
σ' as: List α✝
as
| ⟨Neut.rcont: {ω α : Type} → {b : Bool} → Neut ω α b true
Neut.rcont, σ': Assg Δ
σ'⟩ => go: Assg Δ → List α✝ → m (Neut ω Unit b c × Assg Δ)
go σ': Assg Δ
σ' as: List α✝
as
| ⟨Neut.rbreak: {ω α : Type} → {c : Bool} → Neut ω α true c
Neut.rbreak, σ': Assg Δ
σ'⟩ => pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f α
pure ⟨(): Unit
(), σ': Assg Δ
σ'⟩
| ⟨Neut.ret: {ω α : Type} → {b c : Bool} → ω → Neut ω α b c
Neut.ret o: ω
o, σ': Assg Δ
σ'⟩ => pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f α
pure ⟨Neut.ret: {ω α : Type} → {b c : Bool} → ω → Neut ω α b c
Neut.ret o: ω
o, σ': Assg Δ
σ'⟩
go: Assg Δ → List α✝ → m (Neut ω Unit b c × Assg Δ)
go σ: Assg Δ
σ e: Assg Γ → Assg Δ → List α✝
e[ρ: Assg Γ
ρ][σ: Assg Δ
σ]
| sbreak: {m : Type → Type ?u.36610} → {ω : Type} → {Γ Δ : List Type} → {c : Bool} → {α : Type} → Stmt m ω Γ Δ true c α
sbreak, σ: Assg Δ
σ => pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f α
pure ⟨Neut.rbreak: {ω α : Type} → {c : Bool} → Neut ω α true c
Neut.rbreak, σ: Assg Δ
σ⟩
| scont: {m : Type → Type ?u.36721} → {ω : Type} → {Γ Δ : List Type} → {b : Bool} → {α : Type} → Stmt m ω Γ Δ b true α
scont, σ: Assg Δ
σ => pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f α
pure ⟨Neut.rcont: {ω α : Type} → {b : Bool} → Neut ω α b true
Neut.rcont, σ: Assg Δ
σ⟩
termination_by
eval s _ => (sizeOf: {α : Type (max 1 u_1)} → [self : SizeOf α] → α → Nat
sizeOf s: Stmt m ω Γ Δ b c α
s, 0: Nat
0)
eval.go as => (sizeOf: {α : Type (max 1 u_1)} → [self : SizeOf α] → α → Nat
sizeOf s: Stmt m ω (α✝ :: Γ) Δ true true Unit
s, as: List α✝
as.length: {α : Type} → List α → Nat
length)
At the top-level statement, the contexts are empty, no loop control flow statements are allowed, and the return and result type are identical.
abbrev Do: (Type → Type u_1) → Type → Type (max 1 u_1)
Do m: Type → Type u_1
m α: Type
α := Stmt: (Type → Type u_1) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u_1)
Stmt m: Type → Type u_1
m α: Type
α ∅: List Type
∅ ∅: List Type
∅ false: Bool
false false: Bool
false α: Type
α
def Do.eval: {m : Type → Type u_1} → {α : Type} → [inst : Monad m] → Do m α → m α
Do.eval [Monad: (Type → Type u_1) → Type (max 1 u_1)
Monad m: Type → Type u_1
m] (s: Do m α
s : Do: (Type → Type u_1) → Type → Type (max 1 u_1)
Do m: Type → Type u_1
m α: Type
α) : m: Type → Type u_1
m α: Type
α := -- corresponds to the reduction rule `do s ⇒ v` in the paper
Stmt.eval: {m : Type → Type u_1} →
{Γ : List Type} →
{ω : Type} →
{Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)
Stmt.eval ∅: Assg ∅
∅ s: Do m α
s ∅: Assg ∅
∅ >>= fun
| ⟨Neut.val: {ω α : Type} → {b c : Bool} → α → Neut ω α b c
Neut.val a: α
a, _⟩ => pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f α
pure a: α
a
| ⟨Neut.ret: {ω α : Type} → {b c : Bool} → ω → Neut ω α b c
Neut.ret o: α
o, _⟩ => pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f α
pure o: α
o
notation "⟦" s: Lean.TSyntax `term
s "⟧" => Do.eval s: Lean.TSyntax `term
s
Translation Functions
We adjust the immutable context where necessary. The mutable context does not have to be adjusted.
@[simp] def Stmt.mapAssg: (_x :
(Γ' : List Type) ×'
(Γ : List Type) ×'
(m : Type → Type u_1) ×'
(ω : Type) ×'
(Δ : List Type) ×' (b : Bool) ×' (c : Bool) ×' (β : Type) ×' (_ : Assg Γ' → Assg Γ) ×' Stmt m ω Γ Δ b c β) →
Stmt _x.2.2.1 _x.2.2.2.1 _x.1 _x.2.2.2.2.1 _x.2.2.2.2.2.1 _x.2.2.2.2.2.2.1 _x.2.2.2.2.2.2.2.1
Stmt.mapAssg (f: Assg Γ' → Assg Γ
f : Assg: List Type → Type
Assg Γ': List Type
Γ' → Assg: List (Type ?u.111841) → Type ?u.111841
Assg Γ: List Type
Γ) : Stmt: (Type → Type u_1) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u_1)
Stmt m: Type → Type u_1
m ω: Type
ω Γ: List Type
Γ Δ: List Type
Δ b: Bool
b c: Bool
c β: Type
β → Stmt: (Type → Type u_1) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u_1)
Stmt m: Type → Type u_1
m ω: Type
ω Γ': List Type
Γ' Δ: List Type
Δ b: Bool
b c: Bool
c β: Type
β
| expr: {m : Type → Type ?u.116778} →
{ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α
expr e: Assg Γ → Assg Δ → m β
e => expr: {m : Type → Type u_1} →
{ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α
expr (e: Assg Γ → Assg Δ → m β
e ∘ f: Assg Γ' → Assg Γ
f)
| bind: {m : Type → Type ?u.116872} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c β
bind s₁: Stmt m ω Γ Δ b c α✝
s₁ s₂: Stmt m ω (α✝ :: Γ) Δ b c β
s₂ => bind: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c β
bind (s₁: Stmt m ω Γ Δ b c α✝
s₁.mapAssg: {Γ' Γ : List Type} →
{m : Type → Type u_1} →
{ω : Type} →
{Δ : List Type} → {b c : Bool} → {β : Type} → (Assg Γ' → Assg Γ) → Stmt m ω Γ Δ b c β → Stmt m ω Γ' Δ b c β
mapAssg f: Assg Γ' → Assg Γ
f) (s₂: Stmt m ω (α✝ :: Γ) Δ b c β
s₂.mapAssg: {Γ' Γ : List Type} →
{m : Type → Type u_1} →
{ω : Type} →
{Δ : List Type} → {b c : Bool} → {β : Type} → (Assg Γ' → Assg Γ) → Stmt m ω Γ Δ b c β → Stmt m ω Γ' Δ b c β
mapAssg (fun (a: α✝
a :: as: HList Γ'
as) => (a: α✝
a :: f: Assg Γ' → Assg Γ
f as: HList Γ'
as)))
| letmut: {m : Type → Type ?u.117466} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} → {b c : Bool} → {β : Type} → (Assg Γ → Assg Δ → α) → Stmt m ω Γ (α :: Δ) b c β → Stmt m ω Γ Δ b c β
letmut e: Assg Γ → Assg Δ → α✝
e s: Stmt m ω Γ (α✝ :: Δ) b c β
s => letmut: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} → {b c : Bool} → {β : Type} → (Assg Γ → Assg Δ → α) → Stmt m ω Γ (α :: Δ) b c β → Stmt m ω Γ Δ b c β
letmut (e: Assg Γ → Assg Δ → α✝
e ∘ f: Assg Γ' → Assg Γ
f) (s: Stmt m ω Γ (α✝ :: Δ) b c β
s.mapAssg: {Γ' Γ : List Type} →
{m : Type → Type u_1} →
{ω : Type} →
{Δ : List Type} → {b c : Bool} → {β : Type} → (Assg Γ' → Assg Γ) → Stmt m ω Γ Δ b c β → Stmt m ω Γ' Δ b c β
mapAssg f: Assg Γ' → Assg Γ
f)
| assg: {m : Type → Type ?u.117619} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → (x : Fin (List.length Δ)) → (Assg Γ → Assg Δ → List.get Δ x) → Stmt m ω Γ Δ b c Unit
assg x: Fin (List.length Δ)
x e: Assg Γ → Assg Δ → List.get Δ x
e => assg: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → (x : Fin (List.length Δ)) → (Assg Γ → Assg Δ → List.get Δ x) → Stmt m ω Γ Δ b c Unit
assg x: Fin (List.length Δ)
x (e: Assg Γ → Assg Δ → List.get Δ x
e ∘ f: Assg Γ' → Assg Γ
f)
| ite: {m : Type → Type ?u.117739} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} →
{α : Type} → (Assg Γ → Assg Δ → Bool) → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α
ite e: Assg Γ → Assg Δ → Bool
e s₁: Stmt m ω Γ Δ b c β
s₁ s₂: Stmt m ω Γ Δ b c β
s₂ => ite: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} →
{α : Type} → (Assg Γ → Assg Δ → Bool) → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α
ite (e: Assg Γ → Assg Δ → Bool
e ∘ f: Assg Γ' → Assg Γ
f) (s₁: Stmt m ω Γ Δ b c β
s₁.mapAssg: {Γ' Γ : List Type} →
{m : Type → Type u_1} →
{ω : Type} →
{Δ : List Type} → {b c : Bool} → {β : Type} → (Assg Γ' → Assg Γ) → Stmt m ω Γ Δ b c β → Stmt m ω Γ' Δ b c β
mapAssg f: Assg Γ' → Assg Γ
f) (s₂: Stmt m ω Γ Δ b c β
s₂.mapAssg: {Γ' Γ : List Type} →
{m : Type → Type u_1} →
{ω : Type} →
{Δ : List Type} → {b c : Bool} → {β : Type} → (Assg Γ' → Assg Γ) → Stmt m ω Γ Δ b c β → Stmt m ω Γ' Δ b c β
mapAssg f: Assg Γ' → Assg Γ
f)
| ret: {m : Type → Type ?u.117891} →
{ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → ω) → Stmt m ω Γ Δ b c α
ret e: Assg Γ → Assg Δ → ω
e => ret: {m : Type → Type u_1} →
{ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → ω) → Stmt m ω Γ Δ b c α
ret (e: Assg Γ → Assg Δ → ω
e ∘ f: Assg Γ' → Assg Γ
f)
| sfor: {m : Type → Type ?u.117980} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} → (Assg Γ → Assg Δ → List α) → Stmt m ω (α :: Γ) Δ true true Unit → Stmt m ω Γ Δ b c Unit
sfor e: Assg Γ → Assg Δ → List α✝
e s: Stmt m ω (α✝ :: Γ) Δ true true Unit
s => sfor: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} → (Assg Γ → Assg Δ → List α) → Stmt m ω (α :: Γ) Δ true true Unit → Stmt m ω Γ Δ b c Unit
sfor (e: Assg Γ → Assg Δ → List α✝
e ∘ f: Assg Γ' → Assg Γ
f) (s: Stmt m ω (α✝ :: Γ) Δ true true Unit
s.mapAssg: {Γ' Γ : List Type} →
{m : Type → Type u_1} →
{ω : Type} →
{Δ : List Type} → {b c : Bool} → {β : Type} → (Assg Γ' → Assg Γ) → Stmt m ω Γ Δ b c β → Stmt m ω Γ' Δ b c β
mapAssg (fun (a: α✝
a :: as: HList Γ'
as) => (a: α✝
a :: f: Assg Γ' → Assg Γ
f as: HList Γ'
as)))
| sbreak: {m : Type → Type ?u.118585} → {ω : Type} → {Γ Δ : List Type} → {c : Bool} → {α : Type} → Stmt m ω Γ Δ true c α
sbreak => sbreak: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {c : Bool} → {α : Type} → Stmt m ω Γ Δ true c α
sbreak
| scont: {m : Type → Type ?u.118632} → {ω : Type} → {Γ Δ : List Type} → {b : Bool} → {α : Type} → Stmt m ω Γ Δ b true α
scont => scont: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b : Bool} → {α : Type} → Stmt m ω Γ Δ b true α
scont
Let us write f ∘ₑ e
for the composition of f : α → β
with e : Γ ⊢ Δ ⊢ α
, which we will use to rewrite embedded terms.
infixr:90 " ∘ₑ " => fun f e => fun ρ σ => f e[ρ][σ]
The formalization of S
creates some technical hurdles. Because it operates on the outer-most mutable binding,
we have to operate on that context from the right, from which we lose some helpful definitional equalities and
have to rewrite types using nested proofs instead.
The helper function shadowSnd
is particularly interesting because it shows how the shadowing in
translation rules (S2) and (S9) is expressed in our de Bruijn encoding: The context α :: β :: α :: Γ
corresponds, in this order, to the y
that has just been bound to the value of get
, then x
from the
respective rule, followed by the y
of the outer scope. We encode the shadowing of y
by dropping the
third element from the context as well as the assignment. We are in fact forced to do so because the corresponding
branches of S
would not otherwise typecheck. The only mistake we could still make is to drop the wrong α
value
from the assignment, which (speaking from experience) would eventually be caught by the correctness proof.
@[simp] def S: {m : Type → Type} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} →
{β : Type} → [inst : Monad m] → Stmt m ω Γ (List.append Δ [α]) b c β → Stmt (StateT α m) ω (α :: Γ) Δ b c β
S [Monad: (Type ?u.178851 → Type ?u.178850) → Type (max (?u.178851 + 1) ?u.178850)
Monad m: Type → Type
m] : Stmt: (Type → Type) → Type → List Type → List Type → Bool → Bool → Type → Type 1
Stmt m: Type → Type
m ω: Type
ω Γ: List Type
Γ (Δ: List Type
Δ ++ [α: Type
α]) b: Bool
b c: Bool
c β: Type
β → Stmt: (Type → Type) → Type → List Type → List Type → Bool → Bool → Type → Type 1
Stmt (StateT: Type → (Type → Type) → Type → Type
StateT α: Type
α m: Type → Type
m) ω: Type
ω (α: Type
α :: Γ: List Type
Γ) Δ: List Type
Δ b: Bool
b c: Bool
c β: Type
β
/-(S1)-/ | Stmt.expr: {m : Type → Type ?u.189083} →
{ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α
Stmt.expr e: Assg Γ → Assg (List.append Δ [α]) → m β
e => Stmt.expr: {m : Type → Type} →
{ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α
Stmt.expr (StateT.lift: {σ : Type} → {m : Type → Type} → [inst : Monad m] → {α : Type} → m α → StateT σ m α
StateT.lift ∘ₑ unmut: {β : Type} → (Assg Γ → Assg (List.append Δ [α]) → β) → Assg (α :: Γ) → Assg Δ → β
unmut e: Assg Γ → Assg (List.append Δ [α]) → m β
e)
/-(S2)-/ | Stmt.bind: {m : Type → Type ?u.189320} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c β
Stmt.bind s₁: Stmt m ω Γ (List.append Δ [α]) b c α✝
s₁ s₂: Stmt m ω (α✝ :: Γ) (List.append Δ [α]) b c β
s₂ => Stmt.bind: {m : Type → Type} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c β
Stmt.bind (S: {m : Type → Type} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} →
{β : Type} → [inst : Monad m] → Stmt m ω Γ (List.append Δ [α]) b c β → Stmt (StateT α m) ω (α :: Γ) Δ b c β
S s₁: Stmt m ω Γ (List.append Δ [α]) b c α✝
s₁) (Stmt.bind: {m : Type → Type} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c β
Stmt.bind (Stmt.expr: {m : Type → Type} →
{ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α
Stmt.expr (fun _ _ => get: {σ : Type} → {m : Type → Type} → [self : MonadState σ m] → m σ
get)) (Stmt.mapAssg: {Γ' Γ : List Type} →
{m : Type → Type} →
{ω : Type} →
{Δ : List Type} → {b c : Bool} → {β : Type} → (Assg Γ' → Assg Γ) → Stmt m ω Γ Δ b c β → Stmt m ω Γ' Δ b c β
Stmt.mapAssg shadowSnd: {β : Type} → Assg (α :: β :: α :: Γ) → Assg (α :: β :: Γ)
shadowSnd (S: {m : Type → Type} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} →
{β : Type} → [inst : Monad m] → Stmt m ω Γ (List.append Δ [α]) b c β → Stmt (StateT α m) ω (α :: Γ) Δ b c β
S s₂: Stmt m ω (α✝ :: Γ) (List.append Δ [α]) b c β
s₂)))
/-(S3)-/ | Stmt.letmut: {m : Type → Type ?u.189575} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} → {b c : Bool} → {β : Type} → (Assg Γ → Assg Δ → α) → Stmt m ω Γ (α :: Δ) b c β → Stmt m ω Γ Δ b c β
Stmt.letmut e: Assg Γ → Assg (List.append Δ [α]) → α✝
e s: Stmt m ω Γ (α✝ :: List.append Δ [α]) b c β
s => Stmt.letmut: {m : Type → Type} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} → {b c : Bool} → {β : Type} → (Assg Γ → Assg Δ → α) → Stmt m ω Γ (α :: Δ) b c β → Stmt m ω Γ Δ b c β
Stmt.letmut (unmut: {β : Type} → (Assg Γ → Assg (List.append Δ [α]) → β) → Assg (α :: Γ) → Assg Δ → β
unmut e: Assg Γ → Assg (List.append Δ [α]) → α✝
e) (S: {m : Type → Type} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} →
{β : Type} → [inst : Monad m] → Stmt m ω Γ (List.append Δ [α]) b c β → Stmt (StateT α m) ω (α :: Γ) Δ b c β
S s: Stmt m ω Γ (α✝ :: List.append Δ [α]) b c β
s)
| Stmt.assg: {m : Type → Type ?u.189691} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → (x : Fin (List.length Δ)) → (Assg Γ → Assg Δ → List.get Δ x) → Stmt m ω Γ Δ b c Unit
Stmt.assg x: Fin (List.length (List.append Δ [α]))
x e: Assg Γ → Assg (List.append Δ [α]) → List.get (List.append Δ [α]) x
e =>
if h: ¬x.val < List.length Δ
h : x: Fin (List.length (List.append Δ [α]))
x < Δ: List Type
Δ.length: {α : Type 1} → List α → Nat
length then
/-(S4)-/ Stmt.assg: {m : Type → Type} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → (x : Fin (List.length Δ)) → (Assg Γ → Assg Δ → List.get Δ x) → Stmt m ω Γ Δ b c Unit
Stmt.assg ⟨x: Fin (List.length (List.append Δ [α]))
x, h: x.val < List.length Δ
h⟩ (fun (y: α
y :: ρ: HList Γ
ρ) σ: Assg Δ
σ => List.get_append_left: ∀ {α : Type 1} {i : Nat} (as bs : List α) (h : i < List.length as) {h' : i < List.length (as ++ bs)},
List.get (as ++ bs) { val := i, isLt := h' } = List.get as { val := i, isLt := h }
List.get_append_left .. ▸ e: Assg Γ → Assg (List.append Δ [α]) → List.get (List.append Δ [α]) x
e ρ: HList Γ
ρ (Assg.extendBot: {α : Type} → α → {Γ : List Type} → Assg Γ → Assg (List.append Γ [α])
Assg.extendBot y: α
y σ: Assg Δ
σ))
else
/-(S5)-/ Stmt.expr: {m : Type → Type} →
{ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α
Stmt.expr (set: {σ : Type} → {m : Type → Type} → [self : MonadStateOf σ m] → σ → m PUnit
set (σ := α: Type
α) ∘ₑ cast: {α β : Type} → α = β → α → β
cast (List.get_last: ∀ {α : Type 1} {a : α} {as : List α} {i : Fin (List.length (as ++ [a]))},
¬i.val < List.length as → List.get (as ++ [a]) i = a
List.get_last h: ¬x.val < List.length Δ
h) ∘ₑ unmut: {β : Type} → (Assg Γ → Assg (List.append Δ [α]) → β) → Assg (α :: Γ) → Assg Δ → β
unmut e: Assg Γ → Assg (List.append Δ [α]) → List.get (List.append Δ [α]) x
e)
/-(S6)-/ | Stmt.ite: {m : Type → Type ?u.190593} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} →
{α : Type} → (Assg Γ → Assg Δ → Bool) → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α
Stmt.ite e: Assg Γ → Assg (List.append Δ [α]) → Bool
e s₁: Stmt m ω Γ (List.append Δ [α]) b c β
s₁ s₂: Stmt m ω Γ (List.append Δ [α]) b c β
s₂ => Stmt.ite: {m : Type → Type} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} →
{α : Type} → (Assg Γ → Assg Δ → Bool) → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α
Stmt.ite (unmut: {β : Type} → (Assg Γ → Assg (List.append Δ [α]) → β) → Assg (α :: Γ) → Assg Δ → β
unmut e: Assg Γ → Assg (List.append Δ [α]) → Bool
e) (S: {m : Type → Type} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} →
{β : Type} → [inst : Monad m] → Stmt m ω Γ (List.append Δ [α]) b c β → Stmt (StateT α m) ω (α :: Γ) Δ b c β
S s₁: Stmt m ω Γ (List.append Δ [α]) b c β
s₁) (S: {m : Type → Type} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} →
{β : Type} → [inst : Monad m] → Stmt m ω Γ (List.append Δ [α]) b c β → Stmt (StateT α m) ω (α :: Γ) Δ b c β
S s₂: Stmt m ω Γ (List.append Δ [α]) b c β
s₂)
-- unreachable case; could be eliminated by a more precise specification of `ω`, but the benefit would be minimal
| Stmt.ret: {m : Type → Type ?u.190711} →
{ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → ω) → Stmt m ω Γ Δ b c α
Stmt.ret e: Assg Γ → Assg (List.append Δ [α]) → ω
e => Stmt.ret: {m : Type → Type} →
{ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → ω) → Stmt m ω Γ Δ b c α
Stmt.ret (unmut: {β : Type} → (Assg Γ → Assg (List.append Δ [α]) → β) → Assg (α :: Γ) → Assg Δ → β
unmut e: Assg Γ → Assg (List.append Δ [α]) → ω
e)
/-(S7)-/ | Stmt.sbreak: {m : Type → Type ?u.190795} → {ω : Type} → {Γ Δ : List Type} → {c : Bool} → {α : Type} → Stmt m ω Γ Δ true c α
Stmt.sbreak => Stmt.sbreak: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {c : Bool} → {α : Type} → Stmt m ω Γ Δ true c α
Stmt.sbreak
/-(S8)-/ | Stmt.scont: {m : Type → Type ?u.190845} → {ω : Type} → {Γ Δ : List Type} → {b : Bool} → {α : Type} → Stmt m ω Γ Δ b true α
Stmt.scont => Stmt.scont: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {b : Bool} → {α : Type} → Stmt m ω Γ Δ b true α
Stmt.scont
/-(S9)-/ | Stmt.sfor: {m : Type → Type ?u.190894} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} → (Assg Γ → Assg Δ → List α) → Stmt m ω (α :: Γ) Δ true true Unit → Stmt m ω Γ Δ b c Unit
Stmt.sfor e: Assg Γ → Assg (List.append Δ [α]) → List α✝
e s: Stmt m ω (α✝ :: Γ) (List.append Δ [α]) true true Unit
s => Stmt.sfor: {m : Type → Type} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} → (Assg Γ → Assg Δ → List α) → Stmt m ω (α :: Γ) Δ true true Unit → Stmt m ω Γ Δ b c Unit
Stmt.sfor (unmut: {β : Type} → (Assg Γ → Assg (List.append Δ [α]) → β) → Assg (α :: Γ) → Assg Δ → β
unmut e: Assg Γ → Assg (List.append Δ [α]) → List α✝
e) (Stmt.bind: {m : Type → Type} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c β
Stmt.bind (Stmt.expr: {m : Type → Type} →
{ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α
Stmt.expr (fun _ _ => get: {σ : Type} → {m : Type → Type} → [self : MonadState σ m] → m σ
get)) (Stmt.mapAssg: {Γ' Γ : List Type} →
{m : Type → Type} →
{ω : Type} →
{Δ : List Type} → {b c : Bool} → {β : Type} → (Assg Γ' → Assg Γ) → Stmt m ω Γ Δ b c β → Stmt m ω Γ' Δ b c β
Stmt.mapAssg shadowSnd: {β : Type} → Assg (α :: β :: α :: Γ) → Assg (α :: β :: Γ)
shadowSnd (S: {m : Type → Type} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} →
{β : Type} → [inst : Monad m] → Stmt m ω Γ (List.append Δ [α]) b c β → Stmt (StateT α m) ω (α :: Γ) Δ b c β
S s: Stmt m ω (α✝ :: Γ) (List.append Δ [α]) true true Unit
s)))
where
@[simp] unmut: {β : Type} → (Assg Γ → Assg (List.append Δ [α]) → β) → Assg (α :: Γ) → Assg Δ → β
unmut {β: Type
β} (e: Assg Γ → Assg (List.append Δ [α]) → β
e : Γ: List Type
Γ ⊢ Δ: List Type
Δ ++ [α: Type
α] ⊢ β: Type
β) : α: Type
α :: Γ: List Type
Γ ⊢ Δ: List Type
Δ ⊢ β: Type
β
| y: α
y :: ρ: HList Γ
ρ, σ: Assg Δ
σ => e: Assg Γ → Assg (List.append Δ [α]) → β
e ρ: HList Γ
ρ (Assg.extendBot: {α : Type} → α → {Γ : List Type} → Assg Γ → Assg (List.append Γ [α])
Assg.extendBot y: α
y σ: Assg Δ
σ)
@[simp] shadowSnd: {Γ : List Type} → {α β : Type} → Assg (α :: β :: α :: Γ) → Assg (α :: β :: Γ)
shadowSnd {β: Type
β} : Assg: List Type → Type
Assg (α: Type
α :: β: Type
β :: α: Type
α :: Γ: List Type
Γ) → Assg: List Type → Type
Assg (α: Type
α :: β: Type
β :: Γ: List Type
Γ)
| a': α
a' :: b: β
b :: _ :: ρ: HList Γ
ρ => a': α
a' :: b: β
b :: ρ: HList Γ
ρ
@[simp] def R: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT ω m) Empty Γ Δ b c α
R [Monad: (Type ?u.239464 → Type ?u.239463) → Type (max (?u.239464 + 1) ?u.239463)
Monad m: Type → Type u_1
m] : Stmt: (Type → Type u_1) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u_1)
Stmt m: Type → Type u_1
m ω: Type
ω Γ: List Type
Γ Δ: List Type
Δ b: Bool
b c: Bool
c α: Type
α → Stmt: (Type → Type u_1) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u_1)
Stmt (ExceptT: Type → (Type → Type u_1) → Type → Type u_1
ExceptT ω: Type
ω m: Type → Type u_1
m) Empty: Type
Empty Γ: List Type
Γ Δ: List Type
Δ b: Bool
b c: Bool
c α: Type
α
/-(R1)-/ | Stmt.ret: {m : Type → Type ?u.242023} →
{ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → ω) → Stmt m ω Γ Δ b c α
Stmt.ret e: Assg Γ → Assg Δ → ω
e => Stmt.expr: {m : Type → Type u_1} →
{ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α
Stmt.expr (throw: {ε : Type} → {m : Type → Type u_1} → [self : MonadExcept ε m] → {α : Type} → ε → m α
throw ∘ₑ e: Assg Γ → Assg Δ → ω
e)
/-(R2)-/ | Stmt.expr: {m : Type → Type ?u.242193} →
{ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α
Stmt.expr e: Assg Γ → Assg Δ → m α
e => Stmt.expr: {m : Type → Type u_1} →
{ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α
Stmt.expr (ExceptT.lift: {ε : Type} → {m : Type → Type u_1} → [inst : Monad m] → {α : Type} → m α → ExceptT ε m α
ExceptT.lift ∘ₑ e: Assg Γ → Assg Δ → m α
e)
/-(R3)-/ | Stmt.bind: {m : Type → Type ?u.242398} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c β
Stmt.bind s: Stmt m ω Γ Δ b c α✝
s s': Stmt m ω (α✝ :: Γ) Δ b c α
s' => Stmt.bind: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c β
Stmt.bind (R: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT ω m) Empty Γ Δ b c α
R s: Stmt m ω Γ Δ b c α✝
s) (R: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT ω m) Empty Γ Δ b c α
R s': Stmt m ω (α✝ :: Γ) Δ b c α
s')
/-(R4)-/ | Stmt.letmut: {m : Type → Type ?u.242495} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} → {b c : Bool} → {β : Type} → (Assg Γ → Assg Δ → α) → Stmt m ω Γ (α :: Δ) b c β → Stmt m ω Γ Δ b c β
Stmt.letmut e: Assg Γ → Assg Δ → α✝
e s: Stmt m ω Γ (α✝ :: Δ) b c α
s => Stmt.letmut: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} → {b c : Bool} → {β : Type} → (Assg Γ → Assg Δ → α) → Stmt m ω Γ (α :: Δ) b c β → Stmt m ω Γ Δ b c β
Stmt.letmut e: Assg Γ → Assg Δ → α✝
e (R: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT ω m) Empty Γ Δ b c α
R s: Stmt m ω Γ (α✝ :: Δ) b c α
s)
/-(R5)-/ | Stmt.assg: {m : Type → Type ?u.242597} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → (x : Fin (List.length Δ)) → (Assg Γ → Assg Δ → List.get Δ x) → Stmt m ω Γ Δ b c Unit
Stmt.assg x: Fin (List.length Δ)
x e: Assg Γ → Assg Δ → List.get Δ x
e => Stmt.assg: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → (x : Fin (List.length Δ)) → (Assg Γ → Assg Δ → List.get Δ x) → Stmt m ω Γ Δ b c Unit
Stmt.assg x: Fin (List.length Δ)
x e: Assg Γ → Assg Δ → List.get Δ x
e
/-(R6)-/ | Stmt.ite: {m : Type → Type ?u.242681} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} →
{α : Type} → (Assg Γ → Assg Δ → Bool) → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α
Stmt.ite e: Assg Γ → Assg Δ → Bool
e s₁: Stmt m ω Γ Δ b c α
s₁ s₂: Stmt m ω Γ Δ b c α
s₂ => Stmt.ite: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} →
{α : Type} → (Assg Γ → Assg Δ → Bool) → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α
Stmt.ite e: Assg Γ → Assg Δ → Bool
e (R: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT ω m) Empty Γ Δ b c α
R s₁: Stmt m ω Γ Δ b c α
s₁) (R: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT ω m) Empty Γ Δ b c α
R s₂: Stmt m ω Γ Δ b c α
s₂)
/-(R7)-/ | Stmt.sbreak: {m : Type → Type ?u.242784} → {ω : Type} → {Γ Δ : List Type} → {c : Bool} → {α : Type} → Stmt m ω Γ Δ true c α
Stmt.sbreak => Stmt.sbreak: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {c : Bool} → {α : Type} → Stmt m ω Γ Δ true c α
Stmt.sbreak
/-(R8)-/ | Stmt.scont: {m : Type → Type ?u.242831} → {ω : Type} → {Γ Δ : List Type} → {b : Bool} → {α : Type} → Stmt m ω Γ Δ b true α
Stmt.scont => Stmt.scont: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b : Bool} → {α : Type} → Stmt m ω Γ Δ b true α
Stmt.scont
/-(R9)-/ | Stmt.sfor: {m : Type → Type ?u.242877} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} → (Assg Γ → Assg Δ → List α) → Stmt m ω (α :: Γ) Δ true true Unit → Stmt m ω Γ Δ b c Unit
Stmt.sfor e: Assg Γ → Assg Δ → List α✝
e s: Stmt m ω (α✝ :: Γ) Δ true true Unit
s => Stmt.sfor: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} → (Assg Γ → Assg Δ → List α) → Stmt m ω (α :: Γ) Δ true true Unit → Stmt m ω Γ Δ b c Unit
Stmt.sfor e: Assg Γ → Assg Δ → List α✝
e (R: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT ω m) Empty Γ Δ b c α
R s: Stmt m ω (α✝ :: Γ) Δ true true Unit
s)
@[simp] def L: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ b c α
L [Monad: (Type ?u.255179 → Type ?u.255178) → Type (max (?u.255179 + 1) ?u.255178)
Monad m: Type → Type u_1
m] : Stmt: (Type → Type u_1) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u_1)
Stmt m: Type → Type u_1
m ω: Type
ω Γ: List Type
Γ Δ: List Type
Δ b: Bool
b c: Bool
c α: Type
α → Stmt: (Type → Type u_1) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u_1)
Stmt (ExceptT: Type → (Type → Type u_1) → Type → Type u_1
ExceptT Unit: Type
Unit m: Type → Type u_1
m) ω: Type
ω Γ: List Type
Γ Δ: List Type
Δ b: Bool
b c: Bool
c α: Type
α
/-(L1)-/ | Stmt.sbreak: {m : Type → Type ?u.256306} → {ω : Type} → {Γ Δ : List Type} → {c : Bool} → {α : Type} → Stmt m ω Γ Δ true c α
Stmt.sbreak => Stmt.sbreak: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {c : Bool} → {α : Type} → Stmt m ω Γ Δ true c α
Stmt.sbreak
/-(L2)-/ | Stmt.scont: {m : Type → Type ?u.256353} → {ω : Type} → {Γ Δ : List Type} → {b : Bool} → {α : Type} → Stmt m ω Γ Δ b true α
Stmt.scont => Stmt.scont: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b : Bool} → {α : Type} → Stmt m ω Γ Δ b true α
Stmt.scont
/-(L3)-/ | Stmt.expr: {m : Type → Type ?u.256399} →
{ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α
Stmt.expr e: Assg Γ → Assg Δ → m α
e => Stmt.expr: {m : Type → Type u_1} →
{ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α
Stmt.expr (ExceptT.lift: {ε : Type} → {m : Type → Type u_1} → [inst : Monad m] → {α : Type} → m α → ExceptT ε m α
ExceptT.lift ∘ₑ e: Assg Γ → Assg Δ → m α
e)
/-(L4)-/ | Stmt.bind: {m : Type → Type ?u.256604} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c β
Stmt.bind s: Stmt m ω Γ Δ b c α✝
s s': Stmt m ω (α✝ :: Γ) Δ b c α
s' => Stmt.bind: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c β
Stmt.bind (L: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ b c α
L s: Stmt m ω Γ Δ b c α✝
s) (L: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ b c α
L s': Stmt m ω (α✝ :: Γ) Δ b c α
s')
/-(L5)-/ | Stmt.letmut: {m : Type → Type ?u.256701} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} → {b c : Bool} → {β : Type} → (Assg Γ → Assg Δ → α) → Stmt m ω Γ (α :: Δ) b c β → Stmt m ω Γ Δ b c β
Stmt.letmut e: Assg Γ → Assg Δ → α✝
e s: Stmt m ω Γ (α✝ :: Δ) b c α
s => Stmt.letmut: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} → {b c : Bool} → {β : Type} → (Assg Γ → Assg Δ → α) → Stmt m ω Γ (α :: Δ) b c β → Stmt m ω Γ Δ b c β
Stmt.letmut e: Assg Γ → Assg Δ → α✝
e (L: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ b c α
L s: Stmt m ω Γ (α✝ :: Δ) b c α
s)
/-(L6)-/ | Stmt.assg: {m : Type → Type ?u.256803} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → (x : Fin (List.length Δ)) → (Assg Γ → Assg Δ → List.get Δ x) → Stmt m ω Γ Δ b c Unit
Stmt.assg x: Fin (List.length Δ)
x e: Assg Γ → Assg Δ → List.get Δ x
e => Stmt.assg: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → (x : Fin (List.length Δ)) → (Assg Γ → Assg Δ → List.get Δ x) → Stmt m ω Γ Δ b c Unit
Stmt.assg x: Fin (List.length Δ)
x e: Assg Γ → Assg Δ → List.get Δ x
e
/-(L7)-/ | Stmt.ite: {m : Type → Type ?u.256899} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} →
{α : Type} → (Assg Γ → Assg Δ → Bool) → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α
Stmt.ite e: Assg Γ → Assg Δ → Bool
e s₁: Stmt m ω Γ Δ b c α
s₁ s₂: Stmt m ω Γ Δ b c α
s₂ => Stmt.ite: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} →
{α : Type} → (Assg Γ → Assg Δ → Bool) → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α
Stmt.ite e: Assg Γ → Assg Δ → Bool
e (L: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ b c α
L s₁: Stmt m ω Γ Δ b c α
s₁) (L: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ b c α
L s₂: Stmt m ω Γ Δ b c α
s₂)
| Stmt.ret: {m : Type → Type ?u.257003} →
{ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → ω) → Stmt m ω Γ Δ b c α
Stmt.ret e: Assg Γ → Assg Δ → ω
e => Stmt.ret: {m : Type → Type u_1} →
{ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → ω) → Stmt m ω Γ Δ b c α
Stmt.ret e: Assg Γ → Assg Δ → ω
e
/-(L8)-/ | Stmt.sfor: {m : Type → Type ?u.257074} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} → (Assg Γ → Assg Δ → List α) → Stmt m ω (α :: Γ) Δ true true Unit → Stmt m ω Γ Δ b c Unit
Stmt.sfor e: Assg Γ → Assg Δ → List α✝
e s: Stmt m ω (α✝ :: Γ) Δ true true Unit
s => Stmt.sfor: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} → (Assg Γ → Assg Δ → List α) → Stmt m ω (α :: Γ) Δ true true Unit → Stmt m ω Γ Δ b c Unit
Stmt.sfor e: Assg Γ → Assg Δ → List α✝
e (L: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ b c α
L s: Stmt m ω (α✝ :: Γ) Δ true true Unit
s)
@[simp] def B: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ false c α
B [Monad: (Type ?u.268935 → Type ?u.268934) → Type (max (?u.268935 + 1) ?u.268934)
Monad m: Type → Type u_1
m] : Stmt: (Type → Type u_1) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u_1)
Stmt m: Type → Type u_1
m ω: Type
ω Γ: List Type
Γ Δ: List Type
Δ b: Bool
b c: Bool
c α: Type
α → Stmt: (Type → Type u_1) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u_1)
Stmt (ExceptT: Type → (Type → Type u_1) → Type → Type u_1
ExceptT Unit: Type
Unit m: Type → Type u_1
m) ω: Type
ω Γ: List Type
Γ Δ: List Type
Δ false: Bool
false c: Bool
c α: Type
α
/-(B1)-/ | Stmt.sbreak: {m : Type → Type ?u.270257} → {ω : Type} → {Γ Δ : List Type} → {c : Bool} → {α : Type} → Stmt m ω Γ Δ true c α
Stmt.sbreak => Stmt.expr: {m : Type → Type u_1} →
{ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α
Stmt.expr (fun _ _ => throw: {ε : Type} → {m : Type → Type u_1} → [self : MonadExcept ε m] → {α : Type} → ε → m α
throw (): Unit
())
/-(B2)-/ | Stmt.scont: {m : Type → Type ?u.270390} → {ω : Type} → {Γ Δ : List Type} → {b : Bool} → {α : Type} → Stmt m ω Γ Δ b true α
Stmt.scont => Stmt.scont: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b : Bool} → {α : Type} → Stmt m ω Γ Δ b true α
Stmt.scont
/-(B3)-/ | Stmt.expr: {m : Type → Type ?u.270436} →
{ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α
Stmt.expr e: Assg Γ → Assg Δ → m α
e => Stmt.expr: {m : Type → Type u_1} →
{ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α
Stmt.expr (ExceptT.lift: {ε : Type} → {m : Type → Type u_1} → [inst : Monad m] → {α : Type} → m α → ExceptT ε m α
ExceptT.lift ∘ₑ e: Assg Γ → Assg Δ → m α
e)
/-(B4)-/ | Stmt.bind: {m : Type → Type ?u.270641} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c β
Stmt.bind s: Stmt m ω Γ Δ b c α✝
s s': Stmt m ω (α✝ :: Γ) Δ b c α
s' => Stmt.bind: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c β
Stmt.bind (B: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ false c α
B s: Stmt m ω Γ Δ b c α✝
s) (B: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ false c α
B s': Stmt m ω (α✝ :: Γ) Δ b c α
s')
/-(B5)-/ | Stmt.letmut: {m : Type → Type ?u.270738} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} → {b c : Bool} → {β : Type} → (Assg Γ → Assg Δ → α) → Stmt m ω Γ (α :: Δ) b c β → Stmt m ω Γ Δ b c β
Stmt.letmut e: Assg Γ → Assg Δ → α✝
e s: Stmt m ω Γ (α✝ :: Δ) b c α
s => Stmt.letmut: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} → {b c : Bool} → {β : Type} → (Assg Γ → Assg Δ → α) → Stmt m ω Γ (α :: Δ) b c β → Stmt m ω Γ Δ b c β
Stmt.letmut e: Assg Γ → Assg Δ → α✝
e (B: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ false c α
B s: Stmt m ω Γ (α✝ :: Δ) b c α
s)
/-(B6)-/ | Stmt.assg: {m : Type → Type ?u.270840} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → (x : Fin (List.length Δ)) → (Assg Γ → Assg Δ → List.get Δ x) → Stmt m ω Γ Δ b c Unit
Stmt.assg x: Fin (List.length Δ)
x e: Assg Γ → Assg Δ → List.get Δ x
e => Stmt.assg: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → (x : Fin (List.length Δ)) → (Assg Γ → Assg Δ → List.get Δ x) → Stmt m ω Γ Δ b c Unit
Stmt.assg x: Fin (List.length Δ)
x e: Assg Γ → Assg Δ → List.get Δ x
e
/-(B7)-/ | Stmt.ite: {m : Type → Type ?u.270936} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} →
{α : Type} → (Assg Γ → Assg Δ → Bool) → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α
Stmt.ite e: Assg Γ → Assg Δ → Bool
e s₁: Stmt m ω Γ Δ b c α
s₁ s₂: Stmt m ω Γ Δ b c α
s₂ => Stmt.ite: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} →
{α : Type} → (Assg Γ → Assg Δ → Bool) → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α
Stmt.ite e: Assg Γ → Assg Δ → Bool
e (B: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ false c α
B s₁: Stmt m ω Γ Δ b c α
s₁) (B: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ false c α
B s₂: Stmt m ω Γ Δ b c α
s₂)
| Stmt.ret: {m : Type → Type ?u.271040} →
{ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → ω) → Stmt m ω Γ Δ b c α
Stmt.ret e: Assg Γ → Assg Δ → ω
e => Stmt.ret: {m : Type → Type u_1} →
{ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → ω) → Stmt m ω Γ Δ b c α
Stmt.ret e: Assg Γ → Assg Δ → ω
e
/-(B8)-/ | Stmt.sfor: {m : Type → Type ?u.271111} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} → (Assg Γ → Assg Δ → List α) → Stmt m ω (α :: Γ) Δ true true Unit → Stmt m ω Γ Δ b c Unit
Stmt.sfor e: Assg Γ → Assg Δ → List α✝
e s: Stmt m ω (α✝ :: Γ) Δ true true Unit
s => Stmt.sfor: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} → (Assg Γ → Assg Δ → List α) → Stmt m ω (α :: Γ) Δ true true Unit → Stmt m ω Γ Δ b c Unit
Stmt.sfor e: Assg Γ → Assg Δ → List α✝
e (L: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ b c α
L s: Stmt m ω (α✝ :: Γ) Δ true true Unit
s)
-- (elided in the paper)
@[simp] def C: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ false c α → Stmt (ExceptT Unit m) ω Γ Δ false false α
C [Monad: (Type ?u.277926 → Type ?u.277925) → Type (max (?u.277926 + 1) ?u.277925)
Monad m: Type → Type u_1
m] : Stmt: (Type → Type u_1) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u_1)
Stmt m: Type → Type u_1
m ω: Type
ω Γ: List Type
Γ Δ: List Type
Δ false: Bool
false c: Bool
c α: Type
α → Stmt: (Type → Type u_1) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u_1)
Stmt (ExceptT: Type → (Type → Type u_1) → Type → Type u_1
ExceptT Unit: Type
Unit m: Type → Type u_1
m) ω: Type
ω Γ: List Type
Γ Δ: List Type
Δ false: Bool
false false: Bool
false α: Type
α
| Stmt.scont: {m : Type → Type ?u.278871} → {ω : Type} → {Γ Δ : List Type} → {b : Bool} → {α : Type} → Stmt m ω Γ Δ b true α
Stmt.scont => Stmt.expr: {m : Type → Type u_1} →
{ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α
Stmt.expr (fun _ _ => throw: {ε : Type} → {m : Type → Type u_1} → [self : MonadExcept ε m] → {α : Type} → ε → m α
throw (): Unit
())
| Stmt.expr: {m : Type → Type ?u.278996} →
{ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α
Stmt.expr e: Assg Γ → Assg Δ → m α
e => Stmt.expr: {m : Type → Type u_1} →
{ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α
Stmt.expr (ExceptT.lift: {ε : Type} → {m : Type → Type u_1} → [inst : Monad m] → {α : Type} → m α → ExceptT ε m α
ExceptT.lift ∘ₑ e: Assg Γ → Assg Δ → m α
e)
| Stmt.bind: {m : Type → Type ?u.279194} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c β
Stmt.bind s: Stmt m ω Γ Δ false c α✝
s s': Stmt m ω (α✝ :: Γ) Δ false c α
s' => Stmt.bind: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c β
Stmt.bind (C: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ false c α → Stmt (ExceptT Unit m) ω Γ Δ false false α
C s: Stmt m ω Γ Δ false c α✝
s) (C: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ false c α → Stmt (ExceptT Unit m) ω Γ Δ false false α
C s': Stmt m ω (α✝ :: Γ) Δ false c α
s')
| Stmt.letmut: {m : Type → Type ?u.279281} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} → {b c : Bool} → {β : Type} → (Assg Γ → Assg Δ → α) → Stmt m ω Γ (α :: Δ) b c β → Stmt m ω Γ Δ b c β
Stmt.letmut e: Assg Γ → Assg Δ → α✝
e s: Stmt m ω Γ (α✝ :: Δ) false c α
s => Stmt.letmut: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} → {b c : Bool} → {β : Type} → (Assg Γ → Assg Δ → α) → Stmt m ω Γ (α :: Δ) b c β → Stmt m ω Γ Δ b c β
Stmt.letmut e: Assg Γ → Assg Δ → α✝
e (C: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ false c α → Stmt (ExceptT Unit m) ω Γ Δ false false α
C s: Stmt m ω Γ (α✝ :: Δ) false c α
s)
| Stmt.assg: {m : Type → Type ?u.279374} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → (x : Fin (List.length Δ)) → (Assg Γ → Assg Δ → List.get Δ x) → Stmt m ω Γ Δ b c Unit
Stmt.assg x: Fin (List.length Δ)
x e: Assg Γ → Assg Δ → List.get Δ x
e => Stmt.assg: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → (x : Fin (List.length Δ)) → (Assg Γ → Assg Δ → List.get Δ x) → Stmt m ω Γ Δ b c Unit
Stmt.assg x: Fin (List.length Δ)
x e: Assg Γ → Assg Δ → List.get Δ x
e
| Stmt.ite: {m : Type → Type ?u.279463} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} →
{α : Type} → (Assg Γ → Assg Δ → Bool) → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α
Stmt.ite e: Assg Γ → Assg Δ → Bool
e s₁: Stmt m ω Γ Δ false c α
s₁ s₂: Stmt m ω Γ Δ false c α
s₂ => Stmt.ite: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} →
{α : Type} → (Assg Γ → Assg Δ → Bool) → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α
Stmt.ite e: Assg Γ → Assg Δ → Bool
e (C: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ false c α → Stmt (ExceptT Unit m) ω Γ Δ false false α
C s₁: Stmt m ω Γ Δ false c α
s₁) (C: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ false c α → Stmt (ExceptT Unit m) ω Γ Δ false false α
C s₂: Stmt m ω Γ Δ false c α
s₂)
| Stmt.ret: {m : Type → Type ?u.279557} →
{ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → ω) → Stmt m ω Γ Δ b c α
Stmt.ret e: Assg Γ → Assg Δ → ω
e => Stmt.ret: {m : Type → Type u_1} →
{ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → ω) → Stmt m ω Γ Δ b c α
Stmt.ret e: Assg Γ → Assg Δ → ω
e
| Stmt.sfor: {m : Type → Type ?u.279621} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} → (Assg Γ → Assg Δ → List α) → Stmt m ω (α :: Γ) Δ true true Unit → Stmt m ω Γ Δ b c Unit
Stmt.sfor e: Assg Γ → Assg Δ → List α✝
e s: Stmt m ω (α✝ :: Γ) Δ true true Unit
s => Stmt.sfor: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{α : Type} →
{b c : Bool} → (Assg Γ → Assg Δ → List α) → Stmt m ω (α :: Γ) Δ true true Unit → Stmt m ω Γ Δ b c Unit
Stmt.sfor e: Assg Γ → Assg Δ → List α✝
e (L: {m : Type → Type u_1} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ b c α
L s: Stmt m ω (α✝ :: Γ) Δ true true Unit
s)
The remaining function to be translated is D
, which is straightforward as well except for its termination proof,
as it recurses on the results of S
(D3) and C ∘ B
(D5). Because of rules (S2, S9) that introduce new bindings,
S
may in fact increase the size of the input, and the same is true for C
and B
for the sizeOf
function
automatically generated by Lean. Thus we introduce a new measure numExts
that counts the number of special statements
on top of basic do
notation and prove that all three functions do not increase the size according to that measure.
Because the rules (D3) and (D5) each eliminate such a special statement, it follows that D
terminates because either
the number of special statements decreases in each case, or it remains the same and the total number of statements decreases.
@[simp] defStmt.numExts :Stmt.numExts: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → Stmt m ω Γ Δ b c α → NatStmtStmt: (Type → Type u_1) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u_1)mm: Type → Type u_1ωω: TypeΓΓ: List TypeΔΔ: List Typebb: Boolcc: Boolα →α: TypeNat |Nat: Typeexpr _ =>expr: {m : Type → Type ?u.314493} → {ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c α0 |0: Natbindbind: {m : Type → Type ?u.314556} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c βs₁s₁: Stmt m ω Γ Δ b c α✝s₂ =>s₂: Stmt m ω (α✝ :: Γ) Δ b c αs₁.s₁: Stmt m ω Γ Δ b c α✝numExts +numExts: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → Stmt m ω Γ Δ b c α → Nats₂.s₂: Stmt m ω (α✝ :: Γ) Δ b c αnumExts |numExts: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → Stmt m ω Γ Δ b c α → Natletmut _letmut: {m : Type → Type ?u.314678} → {ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → {β : Type} → (Assg Γ → Assg Δ → α) → Stmt m ω Γ (α :: Δ) b c β → Stmt m ω Γ Δ b c βs =>s: Stmt m ω Γ (α✝ :: Δ) b c αs.s: Stmt m ω Γ (α✝ :: Δ) b c αnumExts +numExts: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → Stmt m ω Γ Δ b c α → Nat1 |1: Natassg _ _ =>assg: {m : Type → Type ?u.314809} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → (x : Fin (List.length Δ)) → (Assg Γ → Assg Δ → List.get Δ x) → Stmt m ω Γ Δ b c Unit1 |1: Natite _ite: {m : Type → Type ?u.314889} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → Bool) → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c αs₁s₁: Stmt m ω Γ Δ b c αs₂ =>s₂: Stmt m ω Γ Δ b c αs₁.s₁: Stmt m ω Γ Δ b c αnumExts +numExts: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → Stmt m ω Γ Δ b c α → Nats₂.s₂: Stmt m ω Γ Δ b c αnumExts |numExts: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → Stmt m ω Γ Δ b c α → Natret _ =>ret: {m : Type → Type ?u.315027} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → ω) → Stmt m ω Γ Δ b c α1 |1: Natsfor _sfor: {m : Type → Type ?u.315088} → {ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → List α) → Stmt m ω (α :: Γ) Δ true true Unit → Stmt m ω Γ Δ b c Units =>s: Stmt m ω (α✝ :: Γ) Δ true true Units.s: Stmt m ω (α✝ :: Γ) Δ true true UnitnumExts +numExts: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → Stmt m ω Γ Δ b c α → Nat1 |1: Natsbreak =>sbreak: {m : Type → Type ?u.315212} → {ω : Type} → {Γ Δ : List Type} → {c : Bool} → {α : Type} → Stmt m ω Γ Δ true c α1 |1: Natscont =>scont: {m : Type → Type ?u.315254} → {ω : Type} → {Γ Δ : List Type} → {b : Bool} → {α : Type} → Stmt m ω Γ Δ b true α1 @[simp] theorem1: NatStmt.numExts_mapAssg (Stmt.numExts_mapAssg: ∀ {Γ' Γ : List Type} {m : Type → Type u_1} {ω : Type} {Δ : List Type} {b c : Bool} {β : Type} (f : Assg Γ' → Assg Γ) (s : Stmt m ω Γ Δ b c β), numExts (mapAssg f s) = numExts sf :f: Assg Γ' → Assg ΓAssgAssg: List Type → TypeΓ' →Γ': List TypeAssgAssg: List Type → TypeΓ) (Γ: List Types :s: Stmt m ω Γ Δ b c βStmtStmt: (Type → Type u_1) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u_1)mm: Type → Type u_1ωω: TypeΓΓ: List TypeΔΔ: List Typebb: Boolcc: Boolβ) :β: TypenumExts (numExts: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → Stmt m ω Γ Δ b c α → NatmapAssgmapAssg: {Γ' Γ : List Type} → {m : Type → Type u_1} → {ω : Type} → {Δ : List Type} → {b c : Bool} → {β : Type} → (Assg Γ' → Assg Γ) → Stmt m ω Γ Δ b c β → Stmt m ω Γ' Δ b c βff: Assg Γ' → Assg Γs) =s: Stmt m ω Γ Δ b c βnumExtsnumExts: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → Stmt m ω Γ Δ b c α → Nats :=s: Stmt m ω Γ Δ b c βΓ', Γ: List Type
m: Type → Type u_1
ω: Type
Δ: List Type
b, c: Bool
β: Type
f: Assg Γ' → Assg Γ
s: Stmt m ω Γ Δ b c βnumExts (mapAssg f s) = numExts sΓ: List Type
m: Type → Type u_1
ω: Type
Δ: List Type
b, c: Bool
β: Type
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e✝: Assg Γ✝ → Assg Δ✝ → m α✝
Γ': List Type
f: Assg Γ' → Assg Γ✝
exprnumExts (mapAssg f (expr e✝)) = numExts (expr e✝)Γ: List Type
m: Type → Type u_1
ω: Type
Δ: List Type
b, c: Bool
β: Type
Γ✝, Δ✝: List Type
b✝, c✝: Bool
α✝, β✝: Type
s✝: Stmt m ω Γ✝ Δ✝ b✝ c✝ α✝
s'✝: Stmt m ω (α✝ :: Γ✝) Δ✝ b✝ c✝ β✝
Γ': List Type
f: Assg Γ' → Assg Γ✝numExts (mapAssg f (bind s✝ s'✝)) = numExts (bind s✝ s'✝)Γ: List Type
m: Type → Type u_1
ω: Type
Δ: List Type
b, c: Bool
β: Type
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
β✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → α✝
s✝: Stmt m ω Γ✝ (α✝ :: Δ✝) b✝ c✝ β✝
Γ': List Type
f: Assg Γ' → Assg Γ✝numExts (mapAssg f (letmut e✝ s✝)) = numExts (letmut e✝ s✝)Γ: List Type
m: Type → Type u_1
ω: Type
Δ: List Type
b, c: Bool
β: Type
Γ✝, Δ✝: List Type
b✝, c✝: Bool
x✝: Fin (List.length Δ✝)
e✝: Assg Γ✝ → Assg Δ✝ → List.get Δ✝ x✝
Γ': List Type
f: Assg Γ' → Assg Γ✝numExts (mapAssg f (assg x✝ e✝)) = numExts (assg x✝ e✝)Γ: List Type
m: Type → Type u_1
ω: Type
Δ: List Type
b, c: Bool
β: Type
Γ✝, Δ✝: List Type
b✝, c✝: Bool
α✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → Bool
s₁✝, s₂✝: Stmt m ω Γ✝ Δ✝ b✝ c✝ α✝
Γ': List Type
f: Assg Γ' → Assg Γ✝numExts (mapAssg f (ite e✝ s₁✝ s₂✝)) = numExts (ite e✝ s₁✝ s₂✝)Γ: List Type
m: Type → Type u_1
ω: Type
Δ: List Type
b, c: Bool
β: Type
Γ✝, Δ✝: List Type
b✝, c✝: Bool
α✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → ω
Γ': List Type
f: Assg Γ' → Assg Γ✝numExts (mapAssg f (ret e✝)) = numExts (ret e✝)Γ: List Type
m: Type → Type u_1
ω: Type
Δ: List Type
b, c: Bool
β: Type
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e✝: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
Γ': List Type
f: Assg Γ' → Assg Γ✝numExts (mapAssg f (sfor e✝ s✝)) = numExts (sfor e✝ s✝)Γ: List Type
m: Type → Type u_1
ω: Type
Δ: List Type
b, c: Bool
β: Type
Γ✝, Δ✝: List Type
c✝: Bool
α✝: Type
Γ': List Type
f: Assg Γ' → Assg Γ✝numExts (mapAssg f sbreak) = numExts sbreakΓ: List Type
m: Type → Type u_1
ω: Type
Δ: List Type
b, c: Bool
β: Type
Γ✝, Δ✝: List Type
b✝: Bool
α✝: Type
Γ': List Type
f: Assg Γ' → Assg Γ✝numExts (mapAssg f scont) = numExts scontΓ: List Type
m: Type → Type u_1
ω: Type
Δ: List Type
b, c: Bool
β: Type
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e✝: Assg Γ✝ → Assg Δ✝ → m α✝
Γ': List Type
f: Assg Γ' → Assg Γ✝
exprnumExts (mapAssg f (expr e✝)) = numExts (expr e✝)Γ: List Type
m: Type → Type u_1
ω: Type
Δ: List Type
b, c: Bool
β: Type
Γ✝, Δ✝: List Type
b✝, c✝: Bool
α✝, β✝: Type
s✝: Stmt m ω Γ✝ Δ✝ b✝ c✝ α✝
s'✝: Stmt m ω (α✝ :: Γ✝) Δ✝ b✝ c✝ β✝
Γ': List Type
f: Assg Γ' → Assg Γ✝numExts (mapAssg f (bind s✝ s'✝)) = numExts (bind s✝ s'✝)Γ: List Type
m: Type → Type u_1
ω: Type
Δ: List Type
b, c: Bool
β: Type
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
β✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → α✝
s✝: Stmt m ω Γ✝ (α✝ :: Δ✝) b✝ c✝ β✝
Γ': List Type
f: Assg Γ' → Assg Γ✝numExts (mapAssg f (letmut e✝ s✝)) = numExts (letmut e✝ s✝)Γ: List Type
m: Type → Type u_1
ω: Type
Δ: List Type
b, c: Bool
β: Type
Γ✝, Δ✝: List Type
b✝, c✝: Bool
x✝: Fin (List.length Δ✝)
e✝: Assg Γ✝ → Assg Δ✝ → List.get Δ✝ x✝
Γ': List Type
f: Assg Γ' → Assg Γ✝numExts (mapAssg f (assg x✝ e✝)) = numExts (assg x✝ e✝)Γ: List Type
m: Type → Type u_1
ω: Type
Δ: List Type
b, c: Bool
β: Type
Γ✝, Δ✝: List Type
b✝, c✝: Bool
α✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → Bool
s₁✝, s₂✝: Stmt m ω Γ✝ Δ✝ b✝ c✝ α✝
Γ': List Type
f: Assg Γ' → Assg Γ✝numExts (mapAssg f (ite e✝ s₁✝ s₂✝)) = numExts (ite e✝ s₁✝ s₂✝)Γ: List Type
m: Type → Type u_1
ω: Type
Δ: List Type
b, c: Bool
β: Type
Γ✝, Δ✝: List Type
b✝, c✝: Bool
α✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → ω
Γ': List Type
f: Assg Γ' → Assg Γ✝numExts (mapAssg f (ret e✝)) = numExts (ret e✝)Γ: List Type
m: Type → Type u_1
ω: Type
Δ: List Type
b, c: Bool
β: Type
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e✝: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
Γ': List Type
f: Assg Γ' → Assg Γ✝numExts (mapAssg f (sfor e✝ s✝)) = numExts (sfor e✝ s✝)Γ: List Type
m: Type → Type u_1
ω: Type
Δ: List Type
b, c: Bool
β: Type
Γ✝, Δ✝: List Type
c✝: Bool
α✝: Type
Γ': List Type
f: Assg Γ' → Assg Γ✝numExts (mapAssg f sbreak) = numExts sbreakΓ: List Type
m: Type → Type u_1
ω: Type
Δ: List Type
b, c: Bool
β: Type
Γ✝, Δ✝: List Type
b✝: Bool
α✝: Type
Γ': List Type
f: Assg Γ' → Assg Γ✝numExts (mapAssg f scont) = numExts sconttheoremGoals accomplished! 🐙Stmt.numExts_S [Stmt.numExts_S: ∀ {m : Type → Type} {ω : Type} {Γ Δ : List Type} {α : Type} {b c : Bool} {β : Type} [inst : Monad m] (s : Stmt m ω Γ (List.append Δ [α]) b c β), numExts (S s) ≤ numExts sMonadMonad: (Type ?u.330075 → Type ?u.330074) → Type (max (?u.330075 + 1) ?u.330074)m] (m: Type → Types :s: Stmt m ω Γ (List.append Δ [α]) b c βStmtStmt: (Type → Type) → Type → List Type → List Type → Bool → Bool → Type → Type 1mm: Type → Typeωω: TypeΓ (Γ: List TypeΔ ++ [Δ: List Typeα])α: Typebb: Boolcc: Boolβ) :β: TypenumExts (numExts: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → Stmt m ω Γ Δ b c α → NatSS: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → {β : Type} → [inst : Monad m] → Stmt m ω Γ (List.append Δ [α]) b c β → Stmt (StateT α m) ω (α :: Γ) Δ b c βs) ≤s: Stmt m ω Γ (List.append Δ [α]) b c βnumExtsnumExts: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → Stmt m ω Γ Δ b c α → Nats :=s: Stmt m ω Γ (List.append Δ [α]) b c βm: Type → Type
ω: Type
Γ, Δ: List Type
α: Type
b, c: Bool
β: Type
inst✝: Monad m
s: Stmt m ω Γ (List.append Δ [α]) b c βnumExts (S s) ≤ numExts sm: Type → Type
ω: Type
Γ, Δ: List Type
α: Type
b, c: Bool
β: Type
inst✝: Monad m∀ (s : Stmt m ω Γ (List.append Δ [α]) b c β), numExts (S s) ≤ numExts sm: Type → Type
ω: Type
Γ, Δ: List Type
α: Type
b, c: Bool
β: Type
inst✝: Monad m∀ {Δ' : List Type} (s : Stmt m ω Γ Δ' b c β) (h : Δ' = List.append Δ [α]), numExts (S (h ▸ s)) ≤ numExts sm: Type → Type
ω: Type
Γ, Δ: List Type
α: Type
b, c: Bool
β: Type
inst✝: Monad m
Δ': List Type
s: Stmt m ω Γ Δ' b c β
h: Δ' = List.append Δ [α]numExts (S (h ▸ s)) ≤ numExts sm: Type → Type
ω: Type
Γ, Δ: List Type
α: Type
b, c: Bool
β: Type
inst✝: Monad m
Δ': List Type
s: Stmt m ω Γ Δ' b c β
h: Δ' = List.append Δ [α]numExts (S (h ▸ s)) ≤ numExts sm: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝: Monad m
Δ', Γ✝: List Type
α✝: Type
b✝, c✝: Bool
β✝: Type
Δ: List Type
e✝: Assg Γ✝ → Assg (List.append Δ [α]) → α✝
s✝: Stmt m ω Γ✝ (α✝ :: List.append Δ [α]) b✝ c✝ β✝
ih: ∀ {Δ_1 : List Type} (h : α✝ :: List.append Δ [α] = List.append Δ_1 [α]), numExts (S (h ▸ s✝)) ≤ numExts s✝
letmutnumExts (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ letmut e✝ s✝)) ≤ numExts (letmut e✝ s✝)m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝: Monad m
Δ', Γ✝: List Type
b✝, c✝: Bool
α✝, β✝: Type
Δ: List Type
s✝: Stmt m ω Γ✝ (List.append Δ [α]) b✝ c✝ α✝
s'✝: Stmt m ω (α✝ :: Γ✝) (List.append Δ [α]) b✝ c✝ β✝
ih₁: ∀ {Δ_1 : List Type} (h : List.append Δ [α] = List.append Δ_1 [α]), numExts (S (h ▸ s✝)) ≤ numExts s✝
ih₂: ∀ {Δ_1 : List Type} (h : List.append Δ [α] = List.append Δ_1 [α]), numExts (S (h ▸ s'✝)) ≤ numExts s'✝
bindnumExts (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ bind s✝ s'✝)) ≤ numExts (bind s✝ s'✝)Goals accomplished! 🐙m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝: Monad m
Δ', Γ✝: List Type
α✝: Type
b✝, c✝: Bool
β✝: Type
Δ: List Type
e✝: Assg Γ✝ → Assg (List.append Δ [α]) → α✝
s✝: Stmt m ω Γ✝ (α✝ :: List.append Δ [α]) b✝ c✝ β✝
ih: ∀ {Δ_1 : List Type} (h : α✝ :: List.append Δ [α] = List.append Δ_1 [α]), numExts (S (h ▸ s✝)) ≤ numExts s✝
letmutnumExts (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ letmut e✝ s✝)) ≤ numExts (letmut e✝ s✝)Goals accomplished! 🐙m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝: Monad m
Δ', Γ✝: List Type
b✝, c✝: Bool
Δ: List Type
x✝: Fin (List.length (List.append Δ [α]))
e✝: Assg Γ✝ → Assg (List.append Δ [α]) → List.get (List.append Δ [α]) x✝
assgnumExts (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ assg x✝ e✝)) ≤ numExts (assg x✝ e✝)Goals accomplished! 🐙m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝: Monad m
Δ', Γ✝: List Type
b✝, c✝: Bool
α✝: Type
Δ: List Type
e✝: Assg Γ✝ → Assg (List.append Δ [α]) → Bool
s₁✝, s₂✝: Stmt m ω Γ✝ (List.append Δ [α]) b✝ c✝ α✝
ih₁: ∀ {Δ_1 : List Type} (h : List.append Δ [α] = List.append Δ_1 [α]), numExts (S (h ▸ s₁✝)) ≤ numExts s₁✝
ih₂: ∀ {Δ_1 : List Type} (h : List.append Δ [α] = List.append Δ_1 [α]), numExts (S (h ▸ s₂✝)) ≤ numExts s₂✝
itenumExts (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ ite e✝ s₁✝ s₂✝)) ≤ numExts (ite e✝ s₁✝ s₂✝)Goals accomplished! 🐙m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝: Monad m
Δ', Γ✝: List Type
α✝: Type
b✝, c✝: Bool
Δ: List Type
e✝: Assg Γ✝ → Assg (List.append Δ [α]) → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) (List.append Δ [α]) true true Unit
ih: ∀ {Δ_1 : List Type} (h : List.append Δ [α] = List.append Δ_1 [α]), numExts (S (h ▸ s✝)) ≤ numExts s✝
sfornumExts (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ sfor e✝ s✝)) ≤ numExts (sfor e✝ s✝)Goals accomplished! 🐙m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝: Monad m
Δ', Γ✝: List Type
b✝, c✝: Bool
α✝: Type
Δ: List Type
e✝: Assg Γ✝ → Assg (List.append Δ [α]) → ω
retnumExts (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ ret e✝)) ≤ numExts (ret e✝)theoremGoals accomplished! 🐙Stmt.numExts_L_L [Stmt.numExts_L_L: ∀ {m : Type → Type u_1} {ω : Type} {Γ Δ : List Type} {b c : Bool} {β : Type} [inst : Monad m] (s : Stmt m ω Γ Δ b c β), numExts (L (L s)) ≤ numExts sMonadMonad: (Type ?u.339386 → Type ?u.339385) → Type (max (?u.339386 + 1) ?u.339385)m] (m: Type → Type u_1s :s: Stmt m ω Γ Δ b c βStmtStmt: (Type → Type u_1) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u_1)mm: Type → Type u_1ωω: TypeΓΓ: List TypeΔΔ: List Typebb: Boolcc: Boolβ) :β: TypenumExts (numExts: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → Stmt m ω Γ Δ b c α → NatL (L: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ b c αLL: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ b c αs)) ≤s: Stmt m ω Γ Δ b c βnumExtsnumExts: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → Stmt m ω Γ Δ b c α → Nats :=s: Stmt m ω Γ Δ b c βm: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
s: Stmt m ω Γ Δ b c βnumExts (L (L s)) ≤ numExts sm: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e✝: Assg Γ✝ → Assg Δ✝ → m α✝
exprnumExts (L (L (expr e✝))) ≤ numExts (expr e✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
b✝, c✝: Bool
α✝, β✝: Type
s✝: Stmt m ω Γ✝ Δ✝ b✝ c✝ α✝
s'✝: Stmt m ω (α✝ :: Γ✝) Δ✝ b✝ c✝ β✝numExts (L (L (bind s✝ s'✝))) ≤ numExts (bind s✝ s'✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
β✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → α✝
s✝: Stmt m ω Γ✝ (α✝ :: Δ✝) b✝ c✝ β✝numExts (L (L (letmut e✝ s✝))) ≤ numExts (letmut e✝ s✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
b✝, c✝: Bool
x✝: Fin (List.length Δ✝)
e✝: Assg Γ✝ → Assg Δ✝ → List.get Δ✝ x✝numExts (L (L (assg x✝ e✝))) ≤ numExts (assg x✝ e✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
b✝, c✝: Bool
α✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → Bool
s₁✝, s₂✝: Stmt m ω Γ✝ Δ✝ b✝ c✝ α✝numExts (L (L (ite e✝ s₁✝ s₂✝))) ≤ numExts (ite e✝ s₁✝ s₂✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
b✝, c✝: Bool
α✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → ωnumExts (L (L (ret e✝))) ≤ numExts (ret e✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e✝: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true UnitnumExts (L (L (sfor e✝ s✝))) ≤ numExts (sfor e✝ s✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
c✝: Bool
α✝: TypenumExts (L (L sbreak)) ≤ numExts sbreakm: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
b✝: Bool
α✝: TypenumExts (L (L scont)) ≤ numExts scontm: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e✝: Assg Γ✝ → Assg Δ✝ → m α✝
exprnumExts (L (L (expr e✝))) ≤ numExts (expr e✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
b✝, c✝: Bool
α✝, β✝: Type
s✝: Stmt m ω Γ✝ Δ✝ b✝ c✝ α✝
s'✝: Stmt m ω (α✝ :: Γ✝) Δ✝ b✝ c✝ β✝numExts (L (L (bind s✝ s'✝))) ≤ numExts (bind s✝ s'✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
β✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → α✝
s✝: Stmt m ω Γ✝ (α✝ :: Δ✝) b✝ c✝ β✝numExts (L (L (letmut e✝ s✝))) ≤ numExts (letmut e✝ s✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
b✝, c✝: Bool
x✝: Fin (List.length Δ✝)
e✝: Assg Γ✝ → Assg Δ✝ → List.get Δ✝ x✝numExts (L (L (assg x✝ e✝))) ≤ numExts (assg x✝ e✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
b✝, c✝: Bool
α✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → Bool
s₁✝, s₂✝: Stmt m ω Γ✝ Δ✝ b✝ c✝ α✝numExts (L (L (ite e✝ s₁✝ s₂✝))) ≤ numExts (ite e✝ s₁✝ s₂✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
b✝, c✝: Bool
α✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → ωnumExts (L (L (ret e✝))) ≤ numExts (ret e✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e✝: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true UnitnumExts (L (L (sfor e✝ s✝))) ≤ numExts (sfor e✝ s✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
c✝: Bool
α✝: TypenumExts (L (L sbreak)) ≤ numExts sbreakm: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
b✝: Bool
α✝: TypenumExts (L (L scont)) ≤ numExts sconttheoremGoals accomplished! 🐙Stmt.numExts_C_B [Stmt.numExts_C_B: ∀ {m : Type → Type u_1} {ω : Type} {Γ Δ : List Type} {b c : Bool} {β : Type} [inst : Monad m] (s : Stmt m ω Γ Δ b c β), numExts (C (B s)) ≤ numExts sMonadMonad: (Type ?u.342450 → Type ?u.342449) → Type (max (?u.342450 + 1) ?u.342449)m] (m: Type → Type u_1s :s: Stmt m ω Γ Δ b c βStmtStmt: (Type → Type u_1) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u_1)mm: Type → Type u_1ωω: TypeΓΓ: List TypeΔΔ: List Typebb: Boolcc: Boolβ) :β: TypenumExts (numExts: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → Stmt m ω Γ Δ b c α → NatC (C: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ false c α → Stmt (ExceptT Unit m) ω Γ Δ false false αBB: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ false c αs)) ≤s: Stmt m ω Γ Δ b c βnumExtsnumExts: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → Stmt m ω Γ Δ b c α → Nats :=s: Stmt m ω Γ Δ b c βm: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
s: Stmt m ω Γ Δ b c βnumExts (C (B s)) ≤ numExts sm: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e✝: Assg Γ✝ → Assg Δ✝ → m α✝
exprnumExts (C (B (expr e✝))) ≤ numExts (expr e✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
b✝, c✝: Bool
α✝, β✝: Type
s✝: Stmt m ω Γ✝ Δ✝ b✝ c✝ α✝
s'✝: Stmt m ω (α✝ :: Γ✝) Δ✝ b✝ c✝ β✝numExts (C (B (bind s✝ s'✝))) ≤ numExts (bind s✝ s'✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
β✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → α✝
s✝: Stmt m ω Γ✝ (α✝ :: Δ✝) b✝ c✝ β✝numExts (C (B (letmut e✝ s✝))) ≤ numExts (letmut e✝ s✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
b✝, c✝: Bool
x✝: Fin (List.length Δ✝)
e✝: Assg Γ✝ → Assg Δ✝ → List.get Δ✝ x✝numExts (C (B (assg x✝ e✝))) ≤ numExts (assg x✝ e✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
b✝, c✝: Bool
α✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → Bool
s₁✝, s₂✝: Stmt m ω Γ✝ Δ✝ b✝ c✝ α✝numExts (C (B (ite e✝ s₁✝ s₂✝))) ≤ numExts (ite e✝ s₁✝ s₂✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
b✝, c✝: Bool
α✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → ωnumExts (C (B (ret e✝))) ≤ numExts (ret e✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e✝: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true UnitnumExts (C (B (sfor e✝ s✝))) ≤ numExts (sfor e✝ s✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
c✝: Bool
α✝: TypenumExts (C (B sbreak)) ≤ numExts sbreakm: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
b✝: Bool
α✝: TypenumExts (C (B scont)) ≤ numExts scontm: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e✝: Assg Γ✝ → Assg Δ✝ → m α✝
exprnumExts (C (B (expr e✝))) ≤ numExts (expr e✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
b✝, c✝: Bool
α✝, β✝: Type
s✝: Stmt m ω Γ✝ Δ✝ b✝ c✝ α✝
s'✝: Stmt m ω (α✝ :: Γ✝) Δ✝ b✝ c✝ β✝numExts (C (B (bind s✝ s'✝))) ≤ numExts (bind s✝ s'✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
β✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → α✝
s✝: Stmt m ω Γ✝ (α✝ :: Δ✝) b✝ c✝ β✝numExts (C (B (letmut e✝ s✝))) ≤ numExts (letmut e✝ s✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
b✝, c✝: Bool
x✝: Fin (List.length Δ✝)
e✝: Assg Γ✝ → Assg Δ✝ → List.get Δ✝ x✝numExts (C (B (assg x✝ e✝))) ≤ numExts (assg x✝ e✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
b✝, c✝: Bool
α✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → Bool
s₁✝, s₂✝: Stmt m ω Γ✝ Δ✝ b✝ c✝ α✝numExts (C (B (ite e✝ s₁✝ s₂✝))) ≤ numExts (ite e✝ s₁✝ s₂✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
b✝, c✝: Bool
α✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → ωnumExts (C (B (ret e✝))) ≤ numExts (ret e✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e✝: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true UnitnumExts (C (B (sfor e✝ s✝))) ≤ numExts (sfor e✝ s✝)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
c✝: Bool
α✝: TypenumExts (C (B sbreak)) ≤ numExts sbreakm: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
β: Type
inst✝: Monad m
Γ✝, Δ✝: List Type
b✝: Bool
α✝: TypenumExts (C (B scont)) ≤ numExts scont-- Auxiliary tactic for showing that `D` terminates macro "D_tac" : tactic => `({simp_wf solve | apply Prod.Lex.left; assumption | apply Prod.Lex.right' <;> simp_arith }) @[simp] defGoals accomplished! 🐙D [D: {m : Type → Type} → {Γ : List Type} → {α : Type} → [inst : Monad m] → Stmt m Empty Γ ∅ false false α → Assg Γ → m αMonadMonad: (Type ?u.348150 → Type ?u.348149) → Type (max (?u.348150 + 1) ?u.348149)m] :m: Type → TypeStmtStmt: (Type → Type) → Type → List Type → List Type → Bool → Bool → Type → Type 1mm: Type → TypeEmptyEmpty: TypeΓΓ: List Type∅∅: List Typefalsefalse: Boolfalsefalse: Boolα → (α: TypeΓ ⊢Γ: List Typemm: Type → Typeα) |α: TypeStmt.exprStmt.expr: {m : Type → Type ?u.349536} → {ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c αe => (e: Assg Γ → Assg ∅ → m αe[·][e: Assg Γ → Assg ∅ → m α∅]) |∅: Assg ∅Stmt.bindStmt.bind: {m : Type → Type ?u.349597} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c βss: Stmt m Empty Γ ∅ false false α✝s' => (funs': Stmt m Empty (α✝ :: Γ) ∅ false false αρ =>ρ: Assg ΓDD: {m : Type → Type} → {Γ : List Type} → {α : Type} → [inst : Monad m] → Stmt m Empty Γ ∅ false false α → Assg Γ → m αss: Stmt m Empty Γ ∅ false false α✝ρ >>= funρ: Assg Γx =>x: α✝DD: {m : Type → Type} → {Γ : List Type} → {α : Type} → [inst : Monad m] → Stmt m Empty Γ ∅ false false α → Assg Γ → m αs' (s': Stmt m Empty (α✝ :: Γ) ∅ false false αx ::x: α✝ρ)) |ρ: Assg ΓStmt.letmutStmt.letmut: {m : Type → Type ?u.349872} → {ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → {β : Type} → (Assg Γ → Assg Δ → α) → Stmt m ω Γ (α :: Δ) b c β → Stmt m ω Γ Δ b c βee: Assg Γ → Assg ∅ → α✝s => have :=s: Stmt m Empty Γ (α✝ :: ∅) false false αNat.lt_succ_of_le <|Nat.lt_succ_of_le: ∀ {n m : Nat}, n ≤ m → n < Nat.succ mStmt.numExts_S (Δ :=Stmt.numExts_S: ∀ {m : Type → Type} {ω : Type} {Γ Δ : List Type} {α : Type} {b c : Bool} {β : Type} [inst : Monad m] (s : Stmt m ω Γ (List.append Δ [α]) b c β), Stmt.numExts (S s) ≤ Stmt.numExts s[])[]: List Types -- for termination funs: Stmt m Empty Γ (α✝ :: ∅) false false αρ => letρ: Assg Γx :=x: α✝e[e: Assg Γ → Assg ∅ → α✝ρ][ρ: Assg Γ∅]∅: Assg ∅StateT.run' (StateT.run': {σ : Type} → {m : Type → Type} → [inst : Functor m] → {α : Type} → StateT σ m α → σ → m αD (D: {m : Type → Type} → {Γ : List Type} → {α : Type} → [inst : Monad m] → Stmt m Empty Γ ∅ false false α → Assg Γ → m αSS: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → {β : Type} → [inst : Monad m] → Stmt m ω Γ (List.append Δ [α]) b c β → Stmt (StateT α m) ω (α :: Γ) Δ b c βs) (s: Stmt m Empty Γ (α✝ :: ∅) false false αx ::x: α✝ρ))ρ: Assg Γx |x: α✝Stmt.iteStmt.ite: {m : Type → Type ?u.350351} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → Bool) → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c αee: Assg Γ → Assg ∅ → Bools₁s₁: Stmt m Empty Γ ∅ false false αs₂ => (funs₂: Stmt m Empty Γ ∅ false false αρ => ifρ: Assg Γe[e: Assg Γ → Assg ∅ → Boolρ][ρ: Assg Γ∅] then∅: Assg ∅DD: {m : Type → Type} → {Γ : List Type} → {α : Type} → [inst : Monad m] → Stmt m Empty Γ ∅ false false α → Assg Γ → m αs₁s₁: Stmt m Empty Γ ∅ false false αρ elseρ: Assg ΓDD: {m : Type → Type} → {Γ : List Type} → {α : Type} → [inst : Monad m] → Stmt m Empty Γ ∅ false false α → Assg Γ → m αs₂s₂: Stmt m Empty Γ ∅ false false αρ) |ρ: Assg ΓStmt.sforStmt.sfor: {m : Type → Type ?u.350515} → {ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → List α) → Stmt m ω (α :: Γ) Δ true true Unit → Stmt m ω Γ Δ b c Unitee: Assg Γ → Assg ∅ → List α✝s => have :=s: Stmt m Empty (α✝ :: Γ) ∅ true true UnitNat.lt_succ_of_le <|Nat.lt_succ_of_le: ∀ {n m : Nat}, n ≤ m → n < Nat.succ mStmt.numExts_C_B (Δ :=Stmt.numExts_C_B: ∀ {m : Type → Type} {ω : Type} {Γ Δ : List Type} {b c : Bool} {β : Type} [inst : Monad m] (s : Stmt m ω Γ Δ b c β), Stmt.numExts (C (B s)) ≤ Stmt.numExts s[])[]: List Types -- for termination funs: Stmt m Empty (α✝ :: Γ) ∅ true true Unitρ =>ρ: Assg ΓrunCatch (runCatch: {m : Type → Type} → {α : Type} → [inst : Monad m] → ExceptT α m α → m αforMforM: {m : Type → Type} → {γ α : Type} → [self : ForM m γ α] → [inst : Monad m] → γ → (α → m PUnit) → m PUnite[e: Assg Γ → Assg ∅ → List α✝ρ][ρ: Assg Γ∅] (fun∅: Assg ∅x =>x: α✝runCatch (runCatch: {m : Type → Type} → {α : Type} → [inst : Monad m] → ExceptT α m α → m αD (D: {m : Type → Type} → {Γ : List Type} → {α : Type} → [inst : Monad m] → Stmt m Empty Γ ∅ false false α → Assg Γ → m αC (C: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ false c α → Stmt (ExceptT Unit m) ω Γ Δ false false αBB: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ false c αs)) (s: Stmt m Empty (α✝ :: Γ) ∅ true true Unitx ::x: α✝ρ)))) |ρ: Assg ΓStmt.retStmt.ret: {m : Type → Type ?u.351104} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → ω) → Stmt m ω Γ Δ b c αe => (nomatche: Assg Γ → Assg ∅ → Emptye[·][e: Assg Γ → Assg ∅ → Empty∅]) termination_by _ s => (∅: Assg ∅s.s: Stmt m Empty Γ ∅ false false αnumExts,numExts: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → Stmt m ω Γ Δ b c α → NatsizeOfsizeOf: {α : Type 1} → [self : SizeOf α] → α → Nats) decreasing_bys: Stmt m Empty Γ ∅ false false αGoals accomplished! 🐙
Finally we compose D
and R
into the translation rule for a top-level statement (1').
def Do.trans: {m : Type → Type} → {α : Type} → [inst : Monad m] → Do m α → m α
Do.trans [Monad: (Type → Type) → Type 1
Monad m: Type → Type
m] (s: Do m α
s : Do: (Type → Type) → Type → Type 1
Do m: Type → Type
m α: Type
α) : m: Type → Type
m α: Type
α := runCatch: {m : Type → Type} → {α : Type} → [inst : Monad m] → ExceptT α m α → m α
runCatch (D: {m : Type → Type} → {Γ : List Type} → {α : Type} → [inst : Monad m] → Stmt m Empty Γ ∅ false false α → Assg Γ → m α
D (R: {m : Type → Type} →
{ω : Type} →
{Γ Δ : List Type} →
{b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT ω m) Empty Γ Δ b c α
R s: Do m α
s) ∅: Assg ∅
∅)
Equivalence Proof
Using the monadic dynamic semantics, we can modularly prove for each individual translation function that evaluating its output is equivalent to directly evaluating the input, modulo some lifting and adjustment of resulting values. After induction on the statement, the proofs are mostly concerned with case splitting, application of congruence theorems, and simplification. We can mostly offload these tasks onto Aesop.
attribute [local simp]map_eq_pure_bindmap_eq_pure_bind: ∀ {m : Type u_1 → Type u_2} {α β : Type u_1} [inst : Monad m] [inst_1 : LawfulMonad m] (f : α → β) (x : m α), f <$> x = do let a ← x pure (f a)ExceptT.run_bind attribute [aesop safe apply]ExceptT.run_bind: ∀ {m : Type u_1 → Type u_2} {ε α β : Type u_1} {f : α → ExceptT ε m β} [inst : Monad m] (x : ExceptT ε m α), ExceptT.run (x >>= f) = do let x ← ExceptT.run x match x with | Except.ok x => ExceptT.run (f x) | Except.error e => pure (Except.error e)bind_congr theorembind_congr: ∀ {m : Type u_1 → Type u_2} {α β : Type u_1} [inst : Bind m] {x : m α} {f g : α → m β}, (∀ (a : α), f a = g a) → x >>= f = x >>= geval_R [eval_R: ∀ {m : Type → Type u_1} {ω : Type} {Γ Δ : List Type} {b c : Bool} {α : Type} {ρ : Assg Γ} {σ : Assg Δ} [inst : Monad m] [inst_1 : LawfulMonad m] (s : Stmt m ω Γ Δ b c α), Stmt.eval ρ (R s) σ = do let x ← ExceptT.lift (Stmt.eval ρ s σ) match b, c, x with | b, c, (Neut.ret o, snd) => throw o | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, σ) => pure (Neut.rbreak, σ)MonadMonad: (Type ?u.373143 → Type ?u.373142) → Type (max (?u.373143 + 1) ?u.373142)m] [m: Type → Type u_1LawfulMonadLawfulMonad: (m : Type ?u.373172 → Type ?u.373171) → [inst : Monad m] → Propm] (m: Type → Type u_1s :s: Stmt m ω Γ Δ b c αStmtStmt: (Type → Type ?u.373206) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 ?u.373206)mm: Type → Type u_1ωω: TypeΓΓ: List TypeΔΔ: List Typebb: Boolcc: Boolα) : (α: TypeRR: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT ω m) Empty Γ Δ b c αs).s: Stmt m ω Γ Δ b c αevaleval: {m : Type → Type u_1} → {Γ : List Type} → {ω : Type} → {Δ : List Type} → {b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)ρρ: Assg Γσ = (σ: Assg ΔExceptT.lift (ExceptT.lift: {ε : Type} → {m : Type → Type u_1} → [inst : Monad m] → {α : Type} → m α → ExceptT ε m αs.s: Stmt m ω Γ Δ b c αevaleval: {m : Type → Type u_1} → {Γ : List Type} → {ω : Type} → {Δ : List Type} → {b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)ρρ: Assg Γσ) >>= funσ: Assg Δx => match (generalizing := false)x: Neut ω α b c × Assg Δx with | (x: Neut ω α b c × Assg ΔNeut.retNeut.ret: {ω α : Type} → {b c : Bool} → ω → Neut ω α b co, _) =>o: ωthrowthrow: {ε : Type} → {m : Type → Type u_1} → [self : MonadExcept ε m] → {α : Type} → ε → m αo | (o: ωNeut.valNeut.val: {ω α : Type} → {b c : Bool} → α → Neut ω α b ca,a: ασ) =>σ: Assg Δpure (pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f αNeut.valNeut.val: {ω α : Type} → {b c : Bool} → α → Neut ω α b ca,a: ασ) | (σ: Assg ΔNeut.rcont,Neut.rcont: {ω α : Type} → {b : Bool} → Neut ω α b trueσ) =>σ: Assg Δpure (pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f αNeut.rcont,Neut.rcont: {ω α : Type} → {b : Bool} → Neut ω α b trueσ) | (σ: Assg ΔNeut.rbreak,Neut.rbreak: {ω α : Type} → {c : Bool} → Neut ω α true cσ) =>σ: Assg Δpure (pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f αNeut.rbreak,Neut.rbreak: {ω α : Type} → {c : Bool} → Neut ω α true cσ) :σ: Assg ΔExceptTExceptT: Type → (Type → Type u_1) → Type → Type u_1ωω: Typem (m: Type → Type u_1NeutNeut: Type → Type → Bool → Bool → TypeEmptyEmpty: Typeαα: Typebb: Boolc ×c: BoolAssgAssg: List Type → TypeΔ)) :=Δ: List Typem: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
ρ: Assg Γ
σ: Assg Δ
inst✝¹: Monad m
s: Stmt m ω Γ Δ b c αStmt.eval ρ (R s) σ = do let x ← ExceptT.lift (Stmt.eval ρ s σ) match b, c, x with | b, c, (Neut.ret o, snd) => throw o | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, σ) => pure (Neut.rbreak, σ)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
ρ: Assg Γ
σ: Assg Δ
inst✝¹: Monad m
s: Stmt m ω Γ Δ b c α
hExceptT.run (Stmt.eval ρ (R s) σ) = ExceptT.run do let x ← ExceptT.lift (Stmt.eval ρ s σ) match b, c, x with | b, c, (Neut.ret o, snd) => throw o | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, σ) => pure (Neut.rbreak, σ)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
ρ: Assg Γ
σ: Assg Δ
inst✝¹: Monad m
s: Stmt m ω Γ Δ b c α
hExceptT.run (Stmt.eval ρ (R s) σ) = ExceptT.run do let x ← ExceptT.lift (Stmt.eval ρ s σ) match b, c, x with | b, c, (Neut.ret o, snd) => throw o | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, σ) => pure (Neut.rbreak, σ)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
σ: Assg Δ✝
h.sforExceptT.run (Stmt.eval ρ (R (Stmt.sfor e s✝)) σ) = ExceptT.run do let x ← ExceptT.lift (Stmt.eval ρ (Stmt.sfor e s✝) σ) match b✝, c✝, x with | b, c, (Neut.ret o, snd) => throw o | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, σ) => pure (Neut.rbreak, σ)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
σ: Assg Δ✝
h.sforExceptT.run (Stmt.eval.go ρ c✝ b✝ α✝ (R s✝) σ (e ρ σ)) = ExceptT.run do let x ← ExceptT.lift (Stmt.eval.go ρ c✝ b✝ α✝ s✝ σ (e ρ σ)) match b✝, c✝, x with | b, c, (Neut.ret o, snd) => throw o | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, σ) => pure (Neut.rbreak, σ)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
σ: Assg Δ✝
h.sfor.nilExceptT.run (Stmt.eval.go ρ c✝ b✝ α✝ (R s✝) σ []) = ExceptT.run do let x ← ExceptT.lift (Stmt.eval.go ρ c✝ b✝ α✝ s✝ σ []) match b✝, c✝, x with | b, c, (Neut.ret o, snd) => throw o | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, σ) => pure (Neut.rbreak, σ)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
head✝: α✝
tail✝: List α✝
σ: Assg Δ✝ExceptT.run (Stmt.eval.go ρ c✝ b✝ α✝ (R s✝) σ (head✝ :: tail✝)) = ExceptT.run do let x ← ExceptT.lift (Stmt.eval.go ρ c✝ b✝ α✝ s✝ σ (head✝ :: tail✝)) match b✝, c✝, x with | b, c, (Neut.ret o, snd) => throw o | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, σ) => pure (Neut.rbreak, σ)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
σ: Assg Δ✝
h.sfor.nilExceptT.run (Stmt.eval.go ρ c✝ b✝ α✝ (R s✝) σ []) = ExceptT.run do let x ← ExceptT.lift (Stmt.eval.go ρ c✝ b✝ α✝ s✝ σ []) match b✝, c✝, x with | b, c, (Neut.ret o, snd) => throw o | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, σ) => pure (Neut.rbreak, σ)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
head✝: α✝
tail✝: List α✝
σ: Assg Δ✝ExceptT.run (Stmt.eval.go ρ c✝ b✝ α✝ (R s✝) σ (head✝ :: tail✝)) = ExceptT.run do let x ← ExceptT.lift (Stmt.eval.go ρ c✝ b✝ α✝ s✝ σ (head✝ :: tail✝)) match b✝, c✝, x with | b, c, (Neut.ret o, snd) => throw o | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, σ) => pure (Neut.rbreak, σ)Goals accomplished! 🐙m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
β✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → α✝
s✝: Stmt m ω Γ✝ (α✝ :: Δ✝) b✝ c✝ β✝
ρ: Assg Γ✝
σ: Assg Δ✝
h.letmutExceptT.run (Stmt.eval ρ (R (Stmt.letmut e✝ s✝)) σ) = ExceptT.run do let x ← ExceptT.lift (Stmt.eval ρ (Stmt.letmut e✝ s✝) σ) match b✝, c✝, x with | b, c, (Neut.ret o, snd) => throw o | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, σ) => pure (Neut.rbreak, σ)@[simp] theoremGoals accomplished! 🐙eval_mapAssg [eval_mapAssg: ∀ {m : Type → Type u_1} {Γ' Γ : List Type} {ω : Type} {Δ : List Type} {b c : Bool} {β : Type} {ρ : Assg Γ'} {σ : Assg Δ} [inst : Monad m] [inst_1 : LawfulMonad m] (f : Assg Γ' → Assg Γ) (s : Stmt m ω Γ Δ b c β), Stmt.eval ρ (Stmt.mapAssg f s) σ = Stmt.eval (f ρ) s σMonadMonad: (Type ?u.513583 → Type ?u.513582) → Type (max (?u.513583 + 1) ?u.513582)m] [m: Type → Type u_1LawfulMonadLawfulMonad: (m : Type → Type u_1) → [inst : Monad m] → Propm] (m: Type → Type u_1f :f: Assg Γ' → Assg ΓAssgAssg: List (Type ?u.513856) → Type ?u.513856Γ' →Γ': List TypeAssgAssg: List (Type ?u.513712) → Type ?u.513712Γ) : ∀ (Γ: List Types :s: Stmt m ω Γ Δ b c βStmtStmt: (Type → Type u_1) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u_1)mm: Type → Type u_1ωω: TypeΓΓ: List TypeΔΔ: List Typebb: Boolcc: Boolβ),β: TypeStmt.evalStmt.eval: {m : Type → Type u_1} → {Γ : List Type} → {ω : Type} → {Δ : List Type} → {b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)ρ (ρ: Assg Γ'Stmt.mapAssgStmt.mapAssg: {Γ' Γ : List Type} → {m : Type → Type u_1} → {ω : Type} → {Δ : List Type} → {b c : Bool} → {β : Type} → (Assg Γ' → Assg Γ) → Stmt m ω Γ Δ b c β → Stmt m ω Γ' Δ b c βff: Assg Γ' → Assg Γs)s: Stmt m ω Γ Δ b c βσ =σ: Assg ΔStmt.eval (Stmt.eval: {m : Type → Type u_1} → {Γ : List Type} → {ω : Type} → {Δ : List Type} → {b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)ff: Assg Γ' → Assg Γρ)ρ: Assg Γ'ss: Stmt m ω Γ Δ b c βσ :=σ: Assg Δm: Type → Type u_1
Γ', Γ: List Type
ω: Type
Δ: List Type
b, c: Bool
β: Type
ρ: Assg Γ'
σ: Assg Δ
inst✝¹: Monad m
f: Assg Γ' → Assg Γ∀ (s : Stmt m ω Γ Δ b c β), Stmt.eval ρ (Stmt.mapAssg f s) σ = Stmt.eval (f ρ) s σm: Type → Type u_1
Γ', Γ: List Type
ω: Type
Δ: List Type
b, c: Bool
β: Type
ρ: Assg Γ'
σ: Assg Δ
inst✝¹: Monad m
f: Assg Γ' → Assg Γ
s: Stmt m ω Γ Δ b c βStmt.eval ρ (Stmt.mapAssg f s) σ = Stmt.eval (f ρ) s σm: Type → Type u_1
Γ', Γ: List Type
ω: Type
Δ: List Type
b, c: Bool
β: Type
ρ: Assg Γ'
σ: Assg Δ
inst✝¹: Monad m
f: Assg Γ' → Assg Γ
s: Stmt m ω Γ Δ b c βStmt.eval ρ (Stmt.mapAssg f s) σ = Stmt.eval (f ρ) s σm: Type → Type u_1
Γ: List Type
ω: Type
Δ: List Type
b, c: Bool
β: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ih: ∀ {Γ' : List Type} {ρ : Assg Γ'} {σ : Assg Δ✝} (f : Assg Γ' → Assg (α✝ :: Γ✝)), Stmt.eval ρ (Stmt.mapAssg f s) σ = Stmt.eval (f ρ) s σ
Γ': List Type
ρ: Assg Γ'
σ: Assg Δ✝
f: Assg Γ' → Assg Γ✝
sforStmt.eval ρ (Stmt.mapAssg f (Stmt.sfor e s)) σ = Stmt.eval (f ρ) (Stmt.sfor e s) σm: Type → Type u_1
Γ: List Type
ω: Type
Δ: List Type
b, c: Bool
β: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ih: ∀ {Γ' : List Type} {ρ : Assg Γ'} {σ : Assg Δ✝} (f : Assg Γ' → Assg (α✝ :: Γ✝)), Stmt.eval ρ (Stmt.mapAssg f s) σ = Stmt.eval (f ρ) s σ
Γ': List Type
ρ: Assg Γ'
σ: Assg Δ✝
f: Assg Γ' → Assg Γ✝
sforStmt.eval.go ρ c✝ b✝ α✝ (Stmt.mapAssg (fun x => match x with | (a, as) => a :: f as) s) σ (e (f ρ) σ) = Stmt.eval.go (f ρ) c✝ b✝ α✝ s σ (e (f ρ) σ)m: Type → Type u_1
Γ: List Type
ω: Type
Δ: List Type
b, c: Bool
β: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ih: ∀ {Γ' : List Type} {ρ : Assg Γ'} {σ : Assg Δ✝} (f : Assg Γ' → Assg (α✝ :: Γ✝)), Stmt.eval ρ (Stmt.mapAssg f s) σ = Stmt.eval (f ρ) s σ
Γ': List Type
ρ: Assg Γ'
f: Assg Γ' → Assg Γ✝
σ: Assg Δ✝
sfor.nilStmt.eval.go ρ c✝ b✝ α✝ (Stmt.mapAssg (fun x => match x with | (a, as) => a :: f as) s) σ [] = Stmt.eval.go (f ρ) c✝ b✝ α✝ s σ []m: Type → Type u_1
Γ: List Type
ω: Type
Δ: List Type
b, c: Bool
β: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ih: ∀ {Γ' : List Type} {ρ : Assg Γ'} {σ : Assg Δ✝} (f : Assg Γ' → Assg (α✝ :: Γ✝)), Stmt.eval ρ (Stmt.mapAssg f s) σ = Stmt.eval (f ρ) s σ
Γ': List Type
ρ: Assg Γ'
f: Assg Γ' → Assg Γ✝
head✝: α✝
tail✝: List α✝
σ: Assg Δ✝Stmt.eval.go ρ c✝ b✝ α✝ (Stmt.mapAssg (fun x => match x with | (a, as) => a :: f as) s) σ (head✝ :: tail✝) = Stmt.eval.go (f ρ) c✝ b✝ α✝ s σ (head✝ :: tail✝)m: Type → Type u_1
Γ: List Type
ω: Type
Δ: List Type
b, c: Bool
β: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ih: ∀ {Γ' : List Type} {ρ : Assg Γ'} {σ : Assg Δ✝} (f : Assg Γ' → Assg (α✝ :: Γ✝)), Stmt.eval ρ (Stmt.mapAssg f s) σ = Stmt.eval (f ρ) s σ
Γ': List Type
ρ: Assg Γ'
f: Assg Γ' → Assg Γ✝
σ: Assg Δ✝
sfor.nilStmt.eval.go ρ c✝ b✝ α✝ (Stmt.mapAssg (fun x => match x with | (a, as) => a :: f as) s) σ [] = Stmt.eval.go (f ρ) c✝ b✝ α✝ s σ []m: Type → Type u_1
Γ: List Type
ω: Type
Δ: List Type
b, c: Bool
β: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ih: ∀ {Γ' : List Type} {ρ : Assg Γ'} {σ : Assg Δ✝} (f : Assg Γ' → Assg (α✝ :: Γ✝)), Stmt.eval ρ (Stmt.mapAssg f s) σ = Stmt.eval (f ρ) s σ
Γ': List Type
ρ: Assg Γ'
f: Assg Γ' → Assg Γ✝
head✝: α✝
tail✝: List α✝
σ: Assg Δ✝Stmt.eval.go ρ c✝ b✝ α✝ (Stmt.mapAssg (fun x => match x with | (a, as) => a :: f as) s) σ (head✝ :: tail✝) = Stmt.eval.go (f ρ) c✝ b✝ α✝ s σ (head✝ :: tail✝)Goals accomplished! 🐙m: Type → Type u_1
Γ: List Type
ω: Type
Δ: List Type
b, c: Bool
β: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
β✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → α✝
s✝: Stmt m ω Γ✝ (α✝ :: Δ✝) b✝ c✝ β✝
Γ': List Type
ρ: Assg Γ'
σ: Assg Δ✝
f: Assg Γ' → Assg Γ✝
letmutStmt.eval ρ (Stmt.mapAssg f (Stmt.letmut e✝ s✝)) σ = Stmt.eval (f ρ) (Stmt.letmut e✝ s✝) σGoals accomplished! 🐙
We need one last helper function on context bottoms to be able to state the invariant of S
, and then
prove various lemmas about their interactions.
defAssg.bot : {Assg.bot: {α : Type u_1} → {Γ : List (Type u_1)} → Assg (List.append Γ [α]) → αΓ :Γ: List (Type u_1)_} →_: Type (u_1 + 1)Assg (Assg: List (Type u_1) → Type u_1Γ ++ [Γ: List (Type u_1)α]) →α: Type u_1α | [], [α: Type u_1a] =>a: αa | _ ::a: α_, _ ::_: List (Type u_1)as =>as: HList (List.append tail✝ [α])botbot: {α : Type u_1} → {Γ : List (Type u_1)} → Assg (List.append Γ [α]) → αas @[simp] theoremas: HList (List.append tail✝ [α])Assg.dropBot_extendBot (Assg.dropBot_extendBot: ∀ {α : Type u_1} {Γ : List (Type u_1)} (a : α) (σ : Assg Γ), dropBot (extendBot a σ) = σa :a: αα) (α: Type u_1σ :σ: Assg ΓAssgAssg: List (Type u_1) → Type u_1Γ) :Γ: List (Type u_1)Assg.dropBot (Assg.dropBot: {α : Type u_1} → {Γ : List (Type u_1)} → Assg (List.append Γ [α]) → Assg ΓAssg.extendBotAssg.extendBot: {α : Type u_1} → α → {Γ : List (Type u_1)} → Assg Γ → Assg (List.append Γ [α])aa: ασ) =σ: Assg Γσ :=σ: Assg Γα: Type u_1
Γ: List (Type u_1)
a: α
σ: Assg ΓdropBot (extendBot a σ) = σα: Type u_1
a: α
σ: Assg []
nildropBot (extendBot a σ) = σα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
σ: Assg (head✝ :: tail✝)dropBot (extendBot a σ) = σα: Type u_1
a: α
σ: Assg []
nildropBot (extendBot a σ) = σα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
σ: Assg (head✝ :: tail✝)dropBot (extendBot a σ) = σα: Type u_1
a: α
nil.unitdropBot (extendBot a PUnit.unit) = PUnit.unitα: Type u_1
a: α
nil.unitdropBot (extendBot a PUnit.unit) = PUnit.unit@[simp] theoremGoals accomplished! 🐙Assg.bot_extendBot (Assg.bot_extendBot: ∀ {α : Type u_1} {Γ : List (Type u_1)} (a : α) (σ : Assg Γ), bot (extendBot a σ) = aa :a: αα) (α: Type u_1σ :σ: Assg ΓAssgAssg: List (Type u_1) → Type u_1Γ) :Γ: List (Type u_1)Assg.bot (Assg.bot: {α : Type u_1} → {Γ : List (Type u_1)} → Assg (List.append Γ [α]) → αAssg.extendBotAssg.extendBot: {α : Type u_1} → α → {Γ : List (Type u_1)} → Assg Γ → Assg (List.append Γ [α])aa: ασ) =σ: Assg Γa :=a: αα: Type u_1
Γ: List (Type u_1)
a: α
σ: Assg Γbot (extendBot a σ) = aα: Type u_1
a: α
σ: Assg []
nilbot (extendBot a σ) = aα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
σ: Assg (head✝ :: tail✝)bot (extendBot a σ) = aα: Type u_1
a: α
σ: Assg []
nilbot (extendBot a σ) = aα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
σ: Assg (head✝ :: tail✝)bot (extendBot a σ) = aα: Type u_1
a: α
nil.unitbot (extendBot a PUnit.unit) = aα: Type u_1
a: α
nil.unitbot (extendBot a PUnit.unit) = a@[simp] theoremGoals accomplished! 🐙Assg.extendBot_bot_dropBot (Assg.extendBot_bot_dropBot: ∀ {Γ : List (Type u_1)} {α : Type u_1} (σ : Assg (List.append Γ [α])), extendBot (bot σ) (dropBot σ) = σσ :σ: Assg (List.append Γ [α])Assg (Assg: List (Type u_1) → Type u_1Γ ++ [Γ: List (Type u_1)α])) :α: Type u_1Assg.extendBot (Assg.extendBot: {α : Type u_1} → α → {Γ : List (Type u_1)} → Assg Γ → Assg (List.append Γ [α])Assg.botAssg.bot: {α : Type u_1} → {Γ : List (Type u_1)} → Assg (List.append Γ [α]) → ασ) (σ: Assg (List.append Γ [α])Assg.dropBotAssg.dropBot: {α : Type u_1} → {Γ : List (Type u_1)} → Assg (List.append Γ [α]) → Assg Γσ) =σ: Assg (List.append Γ [α])σ :=σ: Assg (List.append Γ [α])Γ: List (Type u_1)
α: Type u_1
σ: Assg (List.append Γ [α])extendBot (bot σ) (dropBot σ) = σα: Type u_1
σ: Assg (List.append [] [α])
nilextendBot (bot σ) (dropBot σ) = σα, head✝: Type u_1
tail✝: List (Type u_1)
σ: Assg (List.append (head✝ :: tail✝) [α])extendBot (bot σ) (dropBot σ) = σα: Type u_1
σ: Assg (List.append [] [α])
nilextendBot (bot σ) (dropBot σ) = σα, head✝: Type u_1
tail✝: List (Type u_1)
σ: Assg (List.append (head✝ :: tail✝) [α])extendBot (bot σ) (dropBot σ) = σα: Type u_1
fst✝: α
snd✝: HList []
nil.mkextendBot (bot (fst✝, snd✝)) (dropBot (fst✝, snd✝)) = (fst✝, snd✝)α: Type u_1
fst✝: α
snd✝: HList []
nil.mkextendBot (bot (fst✝, snd✝)) (dropBot (fst✝, snd✝)) = (fst✝, snd✝)Goals accomplished! 🐙Goals accomplished! 🐙@[simp] theoremGoals accomplished! 🐙Assg.dropBot_set_extendBot_init (Assg.dropBot_set_extendBot_init: ∀ {α : Type u_1} {Γ : List (Type u_1)} {i : Fin (List.length (List.append Γ [α]))} (a : α) (σ : Assg Γ) (h : i.val < List.length Γ) {b : List.get (List.append Γ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = HList.set σ { val := i.val, isLt := h } ((_ : List.get (Γ ++ [α]) { val := i.val, isLt := (_ : i.val < List.length (Γ ++ [α])) } = List.get Γ { val := i.val, isLt := h }) ▸ b)a :a: αα) (α: Type u_1σ :σ: Assg ΓAssgAssg: List (Type u_1) → Type u_1Γ) (Γ: List (Type u_1)h :h: i.val < List.length Γi.i: Fin (List.length (List.append Γ [α]))1 <1: {n : Nat} → Fin n → NatΓ.Γ: List (Type u_1)length) {length: {α : Type (u_1 + 1)} → List α → Natb} :b: List.get (List.append Γ [α]) iAssg.dropBot ((Assg.dropBot: {α : Type u_1} → {Γ : List (Type u_1)} → Assg (List.append Γ [α]) → Assg ΓAssg.extendBotAssg.extendBot: {α : Type u_1} → α → {Γ : List (Type u_1)} → Assg Γ → Assg (List.append Γ [α])aa: ασ).σ: Assg Γsetset: {αs : List (Type u_1)} → HList αs → (i : Fin (List.length αs)) → List.get αs i → HList αsii: Fin (List.length (List.append Γ [α]))b) =b: List.get (List.append Γ [α]) iσ.σ: Assg Γset ⟨set: {αs : List (Type u_1)} → HList αs → (i : Fin (List.length αs)) → List.get αs i → HList αsi.i: Fin (List.length (List.append Γ [α]))1,1: {n : Nat} → Fin n → Nath⟩ (h: i.val < List.length ΓList.get_append_left .. ▸List.get_append_left: ∀ {α : Type (u_1 + 1)} {i : Nat} (as bs : List α) (h : i < List.length as) {h' : i < List.length (as ++ bs)}, List.get (as ++ bs) { val := i, isLt := h' } = List.get as { val := i, isLt := h }b) :=b: List.get (List.append Γ [α]) iα: Type u_1
Γ: List (Type u_1)
i: Fin (List.length (List.append Γ [α]))
a: α
σ: Assg Γ
h: i.val < List.length Γ
b: List.get (List.append Γ [α]) idropBot (HList.set (extendBot a σ) i b) = HList.set σ { val := i.val, isLt := h } ((_ : List.get (Γ ++ [α]) { val := i.val, isLt := (_ : i.val < List.length (Γ ++ [α])) } = List.get Γ { val := i.val, isLt := h }) ▸ b)α: Type u_1
Γ: List (Type u_1)
i: Fin (List.length (List.append Γ [α]))
a: α
σ: Assg Γ
h: i.val < List.length Γ
b: List.get (List.append Γ [α]) idropBot (HList.set (extendBot a σ) i b) = HList.set σ { val := i.val, isLt := h } ((_ : List.get (Γ ++ [α]) { val := i.val, isLt := (_ : i.val < List.length (Γ ++ [α])) } = List.get Γ { val := i.val, isLt := h }) ▸ b)α: Type u_1
a: α
i: Fin (List.length (List.append [] [α]))
σ: Assg []
h: i.val < List.length []
b: List.get (List.append [] [α]) i
nildropBot (HList.set (extendBot a σ) i b) = HList.set σ { val := i.val, isLt := h } ((_ : List.get ([] ++ [α]) { val := i.val, isLt := (_ : i.val < List.length ([] ++ [α])) } = List.get [] { val := i.val, isLt := h }) ▸ b)Goals accomplished! 🐙α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝) (h : i.val < List.length tail✝) {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = HList.set σ { val := i.val, isLt := h } ((_ : List.get (tail✝ ++ [α]) { val := i.val, isLt := (_ : i.val < List.length (tail✝ ++ [α])) } = List.get tail✝ { val := i.val, isLt := h }) ▸ b)
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
σ: Assg (head✝ :: tail✝)
h: i.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) i
consdropBot (HList.set (extendBot a σ) i b) = HList.set σ { val := i.val, isLt := h } ((_ : List.get (head✝ :: tail✝ ++ [α]) { val := i.val, isLt := (_ : i.val < List.length (head✝ :: tail✝ ++ [α])) } = List.get (head✝ :: tail✝) { val := i.val, isLt := h }) ▸ b)α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝) (h : i.val < List.length tail✝) {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = HList.set σ { val := i.val, isLt := h } ((_ : List.get (tail✝ ++ [α]) { val := i.val, isLt := (_ : i.val < List.length (tail✝ ++ [α])) } = List.get tail✝ { val := i.val, isLt := h }) ▸ b)
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
h: i.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) i
fst✝: head✝
snd✝: HList tail✝
cons.mkdropBot (HList.set (extendBot a (fst✝, snd✝)) i b) = HList.set (fst✝, snd✝) { val := i.val, isLt := h } ((_ : List.get (head✝ :: tail✝ ++ [α]) { val := i.val, isLt := (_ : i.val < List.length (head✝ :: tail✝ ++ [α])) } = List.get (head✝ :: tail✝) { val := i.val, isLt := h }) ▸ b)α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝) (h : i.val < List.length tail✝) {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = HList.set σ { val := i.val, isLt := h } ((_ : List.get (tail✝ ++ [α]) { val := i.val, isLt := (_ : i.val < List.length (tail✝ ++ [α])) } = List.get tail✝ { val := i.val, isLt := h }) ▸ b)
i✝: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
i: Nat
h': i < List.length (List.append (head✝ :: tail✝) [α])
h: { val := i, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := i, isLt := h' }
cons.mkdropBot (HList.set (extendBot a (fst✝, snd✝)) { val := i, isLt := h' } b) = HList.set (fst✝, snd✝) { val := { val := i, isLt := h' }.val, isLt := h } ((_ : List.get (head✝ :: tail✝ ++ [α]) { val := { val := i, isLt := h' }.val, isLt := (_ : { val := i, isLt := h' }.val < List.length (head✝ :: tail✝ ++ [α])) } = List.get (head✝ :: tail✝) { val := { val := i, isLt := h' }.val, isLt := h }) ▸ b)α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝) (h : i.val < List.length tail✝) {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = HList.set σ { val := i.val, isLt := h } ((_ : List.get (tail✝ ++ [α]) { val := i.val, isLt := (_ : i.val < List.length (tail✝ ++ [α])) } = List.get tail✝ { val := i.val, isLt := h }) ▸ b)
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
h': Nat.zero < List.length (List.append (head✝ :: tail✝) [α])
h: { val := Nat.zero, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.zero, isLt := h' }
cons.mk.zerodropBot (HList.set (extendBot a (fst✝, snd✝)) { val := Nat.zero, isLt := h' } b) = HList.set (fst✝, snd✝) { val := { val := Nat.zero, isLt := h' }.val, isLt := h } ((_ : List.get (head✝ :: tail✝ ++ [α]) { val := { val := Nat.zero, isLt := h' }.val, isLt := (_ : { val := Nat.zero, isLt := h' }.val < List.length (head✝ :: tail✝ ++ [α])) } = List.get (head✝ :: tail✝) { val := { val := Nat.zero, isLt := h' }.val, isLt := h }) ▸ b)α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝) (h : i.val < List.length tail✝) {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = HList.set σ { val := i.val, isLt := h } ((_ : List.get (tail✝ ++ [α]) { val := i.val, isLt := (_ : i.val < List.length (tail✝ ++ [α])) } = List.get tail✝ { val := i.val, isLt := h }) ▸ b)
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: { val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }dropBot (HList.set (extendBot a (fst✝, snd✝)) { val := Nat.succ n✝, isLt := h' } b) = HList.set (fst✝, snd✝) { val := { val := Nat.succ n✝, isLt := h' }.val, isLt := h } ((_ : List.get (head✝ :: tail✝ ++ [α]) { val := { val := Nat.succ n✝, isLt := h' }.val, isLt := (_ : { val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝ ++ [α])) } = List.get (head✝ :: tail✝) { val := { val := Nat.succ n✝, isLt := h' }.val, isLt := h }) ▸ b)α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝) (h : i.val < List.length tail✝) {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = HList.set σ { val := i.val, isLt := h } ((_ : List.get (tail✝ ++ [α]) { val := i.val, isLt := (_ : i.val < List.length (tail✝ ++ [α])) } = List.get tail✝ { val := i.val, isLt := h }) ▸ b)
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
h': Nat.zero < List.length (List.append (head✝ :: tail✝) [α])
h: { val := Nat.zero, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.zero, isLt := h' }
cons.mk.zerodropBot (HList.set (extendBot a (fst✝, snd✝)) { val := Nat.zero, isLt := h' } b) = HList.set (fst✝, snd✝) { val := { val := Nat.zero, isLt := h' }.val, isLt := h } ((_ : List.get (head✝ :: tail✝ ++ [α]) { val := { val := Nat.zero, isLt := h' }.val, isLt := (_ : { val := Nat.zero, isLt := h' }.val < List.length (head✝ :: tail✝ ++ [α])) } = List.get (head✝ :: tail✝) { val := { val := Nat.zero, isLt := h' }.val, isLt := h }) ▸ b)α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝) (h : i.val < List.length tail✝) {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = HList.set σ { val := i.val, isLt := h } ((_ : List.get (tail✝ ++ [α]) { val := i.val, isLt := (_ : i.val < List.length (tail✝ ++ [α])) } = List.get tail✝ { val := i.val, isLt := h }) ▸ b)
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: { val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }dropBot (HList.set (extendBot a (fst✝, snd✝)) { val := Nat.succ n✝, isLt := h' } b) = HList.set (fst✝, snd✝) { val := { val := Nat.succ n✝, isLt := h' }.val, isLt := h } ((_ : List.get (head✝ :: tail✝ ++ [α]) { val := { val := Nat.succ n✝, isLt := h' }.val, isLt := (_ : { val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝ ++ [α])) } = List.get (head✝ :: tail✝) { val := { val := Nat.succ n✝, isLt := h' }.val, isLt := h }) ▸ b)α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝) (h : i.val < List.length tail✝) {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = HList.set σ { val := i.val, isLt := h } ((_ : List.get (tail✝ ++ [α]) { val := i.val, isLt := (_ : i.val < List.length (tail✝ ++ [α])) } = List.get tail✝ { val := i.val, isLt := h }) ▸ b)
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: { val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }
cons.mk.succfst✝ :: dropBot (HList.set (extendBot a snd✝) { val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) } b) = fst✝ :: HList.set snd✝ { val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length tail✝) } ((_ : List.get (head✝ :: tail✝ ++ [α]) { val := { val := Nat.succ n✝, isLt := h' }.val, isLt := (_ : { val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝ ++ [α])) } = List.get (head✝ :: tail✝) { val := { val := Nat.succ n✝, isLt := h' }.val, isLt := h }) ▸ b)α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝) (h : i.val < List.length tail✝) {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = HList.set σ { val := i.val, isLt := h } ((_ : List.get (tail✝ ++ [α]) { val := i.val, isLt := (_ : i.val < List.length (tail✝ ++ [α])) } = List.get tail✝ { val := i.val, isLt := h }) ▸ b)
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: { val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }
cons.mk.succfst✝ :: dropBot (HList.set (extendBot a snd✝) { val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) } b) = fst✝ :: HList.set snd✝ { val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length tail✝) } ((_ : List.get (head✝ :: tail✝ ++ [α]) { val := { val := Nat.succ n✝, isLt := h' }.val, isLt := (_ : { val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝ ++ [α])) } = List.get (head✝ :: tail✝) { val := { val := Nat.succ n✝, isLt := h' }.val, isLt := h }) ▸ b)α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝) (h : i.val < List.length tail✝) {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = HList.set σ { val := i.val, isLt := h } ((_ : List.get (tail✝ ++ [α]) { val := i.val, isLt := (_ : i.val < List.length (tail✝ ++ [α])) } = List.get tail✝ { val := i.val, isLt := h }) ▸ b)
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: { val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }
cons.mk.succfst✝ :: HList.set snd✝ { val := { val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) }.val, isLt := ?cons.mk.succ.h } ((_ : List.get (tail✝ ++ [α]) { val := { val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) }.val, isLt := (_ : { val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) }.val < List.length (tail✝ ++ [α])) } = List.get tail✝ { val := { val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) }.val, isLt := ?cons.mk.succ.h }) ▸ b) = fst✝ :: HList.set snd✝ { val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length tail✝) } ((_ : List.get (head✝ :: tail✝ ++ [α]) { val := { val := Nat.succ n✝, isLt := h' }.val, isLt := (_ : { val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝ ++ [α])) } = List.get (head✝ :: tail✝) { val := { val := Nat.succ n✝, isLt := h' }.val, isLt := h }) ▸ b)α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝) (h : i.val < List.length tail✝) {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = HList.set σ { val := i.val, isLt := h } ((_ : List.get (tail✝ ++ [α]) { val := i.val, isLt := (_ : i.val < List.length (tail✝ ++ [α])) } = List.get tail✝ { val := i.val, isLt := h }) ▸ b)
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: { val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }{ val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) }.val < List.length tail✝@[simp] theoremGoals accomplished! 🐙Assg.bot_set_extendBot_init (Assg.bot_set_extendBot_init: ∀ {α : Type u_1} {Γ : List (Type u_1)} {i : Fin (List.length (List.append Γ [α]))} (a : α) (σ : Assg Γ), i.val < List.length Γ → ∀ {b : List.get (List.append Γ [α]) i}, bot (HList.set (extendBot a σ) i b) = aa :a: αα) (α: Type u_1σ :σ: Assg ΓAssgAssg: List (Type u_1) → Type u_1Γ) (Γ: List (Type u_1)h :h: i.val < List.length Γi.i: Fin (List.length (List.append Γ [α]))1 <1: {n : Nat} → Fin n → NatΓ.Γ: List (Type u_1)length) {length: {α : Type (u_1 + 1)} → List α → Natb} :b: List.get (List.append Γ [α]) iAssg.bot ((Assg.bot: {α : Type u_1} → {Γ : List (Type u_1)} → Assg (List.append Γ [α]) → αAssg.extendBotAssg.extendBot: {α : Type u_1} → α → {Γ : List (Type u_1)} → Assg Γ → Assg (List.append Γ [α])aa: ασ).σ: Assg Γsetset: {αs : List (Type u_1)} → HList αs → (i : Fin (List.length αs)) → List.get αs i → HList αsii: Fin (List.length (List.append Γ [α]))b) =b: List.get (List.append Γ [α]) ia :=a: αα: Type u_1
Γ: List (Type u_1)
i: Fin (List.length (List.append Γ [α]))
a: α
σ: Assg Γ
h: i.val < List.length Γ
b: List.get (List.append Γ [α]) ibot (HList.set (extendBot a σ) i b) = aα: Type u_1
Γ: List (Type u_1)
i: Fin (List.length (List.append Γ [α]))
a: α
σ: Assg Γ
h: i.val < List.length Γ
b: List.get (List.append Γ [α]) ibot (HList.set (extendBot a σ) i b) = aα: Type u_1
a: α
i: Fin (List.length (List.append [] [α]))
σ: Assg []
h: i.val < List.length []
b: List.get (List.append [] [α]) i
nilbot (HList.set (extendBot a σ) i b) = aGoals accomplished! 🐙α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = a
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
σ: Assg (head✝ :: tail✝)
h: i.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) i
consbot (HList.set (extendBot a σ) i b) = aα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = a
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
h: i.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) i
fst✝: head✝
snd✝: HList tail✝
cons.mkbot (HList.set (extendBot a (fst✝, snd✝)) i b) = aα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = a
i✝: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
i: Nat
h': i < List.length (List.append (head✝ :: tail✝) [α])
h: { val := i, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := i, isLt := h' }
cons.mkbot (HList.set (extendBot a (fst✝, snd✝)) { val := i, isLt := h' } b) = aα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = a
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
h': Nat.zero < List.length (List.append (head✝ :: tail✝) [α])
h: { val := Nat.zero, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.zero, isLt := h' }
cons.mk.zerobot (HList.set (extendBot a (fst✝, snd✝)) { val := Nat.zero, isLt := h' } b) = aα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = a
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: { val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }bot (HList.set (extendBot a (fst✝, snd✝)) { val := Nat.succ n✝, isLt := h' } b) = aα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = a
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
h': Nat.zero < List.length (List.append (head✝ :: tail✝) [α])
h: { val := Nat.zero, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.zero, isLt := h' }
cons.mk.zerobot (HList.set (extendBot a (fst✝, snd✝)) { val := Nat.zero, isLt := h' } b) = aα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = a
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: { val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }bot (HList.set (extendBot a (fst✝, snd✝)) { val := Nat.succ n✝, isLt := h' } b) = aα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = a
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: { val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }
cons.mk.succbot (HList.set (extendBot a snd✝) { val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) } b) = aα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = a
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: { val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }
cons.mk.succbot (HList.set (extendBot a snd✝) { val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) } b) = aα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = a
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: { val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }
cons.mk.succa = aα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = a
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: { val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }{ val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) }.val < List.length tail✝;α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = a
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: { val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }
cons.mk.succ.h{ val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) }.val < List.length tail✝@[simp] theoremGoals accomplished! 🐙Assg.dropBot_set_extendBot_bottom (Assg.dropBot_set_extendBot_bottom: ∀ {α : Type u_1} {Γ : List (Type u_1)} {i : Fin (List.length (List.append Γ [α]))} (a : α) (σ : Assg Γ), ¬i.val < List.length Γ → ∀ {b : List.get (List.append Γ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = σa :a: αα) (α: Type u_1σ :σ: Assg ΓAssgAssg: List (Type ?u.548037) → Type ?u.548037Γ) (Γ: List (Type u_1)h : ¬h: ¬i.val < List.length Γi.i: Fin (List.length (List.append Γ [α]))1 <1: {n : Nat} → Fin n → NatΓ.Γ: List (Type u_1)length) {length: {α : Type (u_1 + 1)} → List α → Natb} :b: List.get (List.append Γ [α]) iAssg.dropBot ((Assg.dropBot: {α : Type u_1} → {Γ : List (Type u_1)} → Assg (List.append Γ [α]) → Assg ΓAssg.extendBotAssg.extendBot: {α : Type u_1} → α → {Γ : List (Type u_1)} → Assg Γ → Assg (List.append Γ [α])aa: ασ).σ: Assg Γsetset: {αs : List (Type u_1)} → HList αs → (i : Fin (List.length αs)) → List.get αs i → HList αsii: Fin (List.length (List.append Γ [α]))b) =b: List.get (List.append Γ [α]) iσ :=σ: Assg Γα: Type u_1
Γ: List (Type u_1)
i: Fin (List.length (List.append Γ [α]))
a: α
σ: Assg Γ
h: ¬i.val < List.length Γ
b: List.get (List.append Γ [α]) idropBot (HList.set (extendBot a σ) i b) = σα: Type u_1
Γ: List (Type u_1)
i: Fin (List.length (List.append Γ [α]))
a: α
σ: Assg Γ
h: ¬i.val < List.length Γ
b: List.get (List.append Γ [α]) idropBot (HList.set (extendBot a σ) i b) = σα: Type u_1
a: α
i: Fin (List.length (List.append [] [α]))
σ: Assg []
h: ¬i.val < List.length []
b: List.get (List.append [] [α]) i
nildropBot (HList.set (extendBot a σ) i b) = σGoals accomplished! 🐙α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = σ
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
σ: Assg (head✝ :: tail✝)
h: ¬i.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) i
consdropBot (HList.set (extendBot a σ) i b) = σα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = σ
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
h: ¬i.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) i
fst✝: head✝
snd✝: HList tail✝
cons.mkdropBot (HList.set (extendBot a (fst✝, snd✝)) i b) = (fst✝, snd✝)α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = σ
i✝: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
i: Nat
h': i < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := i, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := i, isLt := h' }
cons.mkdropBot (HList.set (extendBot a (fst✝, snd✝)) { val := i, isLt := h' } b) = (fst✝, snd✝)α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = σ
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
h': Nat.zero < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := Nat.zero, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.zero, isLt := h' }
cons.mk.zerodropBot (HList.set (extendBot a (fst✝, snd✝)) { val := Nat.zero, isLt := h' } b) = (fst✝, snd✝)α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = σ
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }dropBot (HList.set (extendBot a (fst✝, snd✝)) { val := Nat.succ n✝, isLt := h' } b) = (fst✝, snd✝)α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = σ
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
h': Nat.zero < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := Nat.zero, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.zero, isLt := h' }
cons.mk.zerodropBot (HList.set (extendBot a (fst✝, snd✝)) { val := Nat.zero, isLt := h' } b) = (fst✝, snd✝)Goals accomplished! 🐙α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = σ
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }
cons.mk.succdropBot (HList.set (extendBot a (fst✝, snd✝)) { val := Nat.succ n✝, isLt := h' } b) = (fst✝, snd✝)α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = σ
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }
cons.mk.succfst✝ :: dropBot (HList.set (extendBot a snd✝) { val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) } b) = (fst✝, snd✝)α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = σ
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }
cons.mk.succfst✝ :: dropBot (HList.set (extendBot a snd✝) { val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) } b) = (fst✝, snd✝)α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = σ
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }
cons.mk.succfst✝ :: snd✝ = (fst✝, snd✝)α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = σ
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }¬{ val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) }.val < List.length tail✝α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = σ
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }
cons.mk.succ.h¬{ val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) }.val < List.length tail✝α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, dropBot (HList.set (extendBot a σ) i b) = σ
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }
h'': { val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) }.val < List.length tail✝
cons.mk.succ.hFalse@[simp] theoremGoals accomplished! 🐙Assg.bot_set_extendBot_bottom (Assg.bot_set_extendBot_bottom: ∀ {α : Type u_1} {Γ : List (Type u_1)} {i : Fin (List.length (List.append Γ [α]))} (a : α) (σ : Assg Γ), ¬i.val < List.length Γ → ∀ {b : List.get (List.append Γ [α]) i}, bot (HList.set (extendBot a σ) i b) = cast (_ : List.get (Γ ++ [α]) i = α) ba :a: αα) (α: Type u_1σ :σ: Assg ΓAssgAssg: List (Type u_1) → Type u_1Γ) (Γ: List (Type u_1)h : ¬h: ¬i.val < List.length Γi.i: Fin (List.length (List.append Γ [α]))1 <1: {n : Nat} → Fin n → NatΓ.Γ: List (Type u_1)length) {length: {α : Type (u_1 + 1)} → List α → Natb} :b: List.get (List.append Γ [α]) iAssg.bot ((Assg.bot: {α : Type u_1} → {Γ : List (Type u_1)} → Assg (List.append Γ [α]) → αAssg.extendBotAssg.extendBot: {α : Type u_1} → α → {Γ : List (Type u_1)} → Assg Γ → Assg (List.append Γ [α])aa: ασ).σ: Assg Γsetset: {αs : List (Type u_1)} → HList αs → (i : Fin (List.length αs)) → List.get αs i → HList αsii: Fin (List.length (List.append Γ [α]))b) =b: List.get (List.append Γ [α]) icast (cast: {α β : Type u_1} → α = β → α → βList.get_lastList.get_last: ∀ {α : Type (u_1 + 1)} {a : α} {as : List α} {i : Fin (List.length (as ++ [a]))}, ¬i.val < List.length as → List.get (as ++ [a]) i = ah)h: ¬i.val < List.length Γb :=b: List.get (List.append Γ [α]) iα: Type u_1
Γ: List (Type u_1)
i: Fin (List.length (List.append Γ [α]))
a: α
σ: Assg Γ
h: ¬i.val < List.length Γ
b: List.get (List.append Γ [α]) ibot (HList.set (extendBot a σ) i b) = cast (_ : List.get (Γ ++ [α]) i = α) bα: Type u_1
Γ: List (Type u_1)
i: Fin (List.length (List.append Γ [α]))
a: α
σ: Assg Γ
h: ¬i.val < List.length Γ
b: List.get (List.append Γ [α]) ibot (HList.set (extendBot a σ) i b) = cast (_ : List.get (Γ ++ [α]) i = α) bα: Type u_1
a: α
i: Fin (List.length (List.append [] [α]))
σ: Assg []
h: ¬i.val < List.length []
b: List.get (List.append [] [α]) i
nilbot (HList.set (extendBot a σ) i b) = cast (_ : List.get ([] ++ [α]) i = α) bα: Type u_1
a: α
i✝: Fin (List.length (List.append [] [α]))
σ: Assg []
i: Nat
h': i < List.length (List.append [] [α])
h: ¬{ val := i, isLt := h' }.val < List.length []
b: List.get (List.append [] [α]) { val := i, isLt := h' }
nilbot (HList.set (extendBot a σ) { val := i, isLt := h' } b) = cast (_ : List.get ([] ++ [α]) { val := i, isLt := h' } = α) bα: Type u_1
a: α
i: Fin (List.length (List.append [] [α]))
σ: Assg []
h': Nat.zero < List.length (List.append [] [α])
h: ¬{ val := Nat.zero, isLt := h' }.val < List.length []
b: List.get (List.append [] [α]) { val := Nat.zero, isLt := h' }
nil.zerobot (HList.set (extendBot a σ) { val := Nat.zero, isLt := h' } b) = cast (_ : List.get ([] ++ [α]) { val := Nat.zero, isLt := h' } = α) bα: Type u_1
a: α
i: Fin (List.length (List.append [] [α]))
σ: Assg []
n✝: Nat
h': Nat.succ n✝ < List.length (List.append [] [α])
h: ¬{ val := Nat.succ n✝, isLt := h' }.val < List.length []
b: List.get (List.append [] [α]) { val := Nat.succ n✝, isLt := h' }bot (HList.set (extendBot a σ) { val := Nat.succ n✝, isLt := h' } b) = cast (_ : List.get ([] ++ [α]) { val := Nat.succ n✝, isLt := h' } = α) bα: Type u_1
a: α
i: Fin (List.length (List.append [] [α]))
σ: Assg []
h': Nat.zero < List.length (List.append [] [α])
h: ¬{ val := Nat.zero, isLt := h' }.val < List.length []
b: List.get (List.append [] [α]) { val := Nat.zero, isLt := h' }
nil.zerobot (HList.set (extendBot a σ) { val := Nat.zero, isLt := h' } b) = cast (_ : List.get ([] ++ [α]) { val := Nat.zero, isLt := h' } = α) b;α: Type u_1
a: α
i: Fin (List.length (List.append [] [α]))
σ: Assg []
h': Nat.zero < List.length (List.append [] [α])
h: ¬{ val := Nat.zero, isLt := h' }.val < List.length []
b: List.get (List.append [] [α]) { val := Nat.zero, isLt := h' }
nil.zerob = cast (_ : List.get ([] ++ [α]) { val := Nat.zero, isLt := h' } = α) bGoals accomplished! 🐙α: Type u_1
a: α
i: Fin (List.length (List.append [] [α]))
σ: Assg []
n✝: Nat
h': Nat.succ n✝ < List.length (List.append [] [α])
h: ¬{ val := Nat.succ n✝, isLt := h' }.val < List.length []
b: List.get (List.append [] [α]) { val := Nat.succ n✝, isLt := h' }
nil.succbot (HList.set (extendBot a σ) { val := Nat.succ n✝, isLt := h' } b) = cast (_ : List.get ([] ++ [α]) { val := Nat.succ n✝, isLt := h' } = α) bGoals accomplished! 🐙α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = cast (_ : List.get (tail✝ ++ [α]) i = α) b
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
σ: Assg (head✝ :: tail✝)
h: ¬i.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) i
consbot (HList.set (extendBot a σ) i b) = cast (_ : List.get (head✝ :: tail✝ ++ [α]) i = α) bα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = cast (_ : List.get (tail✝ ++ [α]) i = α) b
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
h: ¬i.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) i
fst✝: head✝
snd✝: HList tail✝
cons.mkbot (HList.set (extendBot a (fst✝, snd✝)) i b) = cast (_ : List.get (head✝ :: tail✝ ++ [α]) i = α) bα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = cast (_ : List.get (tail✝ ++ [α]) i = α) b
i✝: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
i: Nat
h': i < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := i, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := i, isLt := h' }
cons.mkbot (HList.set (extendBot a (fst✝, snd✝)) { val := i, isLt := h' } b) = cast (_ : List.get (head✝ :: tail✝ ++ [α]) { val := i, isLt := h' } = α) bα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = cast (_ : List.get (tail✝ ++ [α]) i = α) b
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
h': Nat.zero < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := Nat.zero, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.zero, isLt := h' }
cons.mk.zerobot (HList.set (extendBot a (fst✝, snd✝)) { val := Nat.zero, isLt := h' } b) = cast (_ : List.get (head✝ :: tail✝ ++ [α]) { val := Nat.zero, isLt := h' } = α) bα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = cast (_ : List.get (tail✝ ++ [α]) i = α) b
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }bot (HList.set (extendBot a (fst✝, snd✝)) { val := Nat.succ n✝, isLt := h' } b) = cast (_ : List.get (head✝ :: tail✝ ++ [α]) { val := Nat.succ n✝, isLt := h' } = α) bα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = cast (_ : List.get (tail✝ ++ [α]) i = α) b
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
h': Nat.zero < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := Nat.zero, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.zero, isLt := h' }
cons.mk.zerobot (HList.set (extendBot a (fst✝, snd✝)) { val := Nat.zero, isLt := h' } b) = cast (_ : List.get (head✝ :: tail✝ ++ [α]) { val := Nat.zero, isLt := h' } = α) bGoals accomplished! 🐙α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = cast (_ : List.get (tail✝ ++ [α]) i = α) b
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }
cons.mk.succbot (HList.set (extendBot a (fst✝, snd✝)) { val := Nat.succ n✝, isLt := h' } b) = cast (_ : List.get (head✝ :: tail✝ ++ [α]) { val := Nat.succ n✝, isLt := h' } = α) bα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = cast (_ : List.get (tail✝ ++ [α]) i = α) b
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }
cons.mk.succbot (HList.set (extendBot a snd✝) { val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) } b) = cast (_ : List.get (head✝ :: tail✝ ++ [α]) { val := Nat.succ n✝, isLt := h' } = α) bα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = cast (_ : List.get (tail✝ ++ [α]) i = α) b
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }
cons.mk.succbot (HList.set (extendBot a snd✝) { val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) } b) = cast (_ : List.get (head✝ :: tail✝ ++ [α]) { val := Nat.succ n✝, isLt := h' } = α) bα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = cast (_ : List.get (tail✝ ++ [α]) i = α) b
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }
cons.mk.succcast (_ : List.get (tail✝ ++ [α]) { val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) } = α) b = cast (_ : List.get (head✝ :: tail✝ ++ [α]) { val := Nat.succ n✝, isLt := h' } = α) bα: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = cast (_ : List.get (tail✝ ++ [α]) i = α) b
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }¬{ val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) }.val < List.length tail✝α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = cast (_ : List.get (tail✝ ++ [α]) i = α) b
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }
cons.mk.succ.h¬{ val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) }.val < List.length tail✝α: Type u_1
a: α
head✝: Type u_1
tail✝: List (Type u_1)
ih: ∀ {i : Fin (List.length (List.append tail✝ [α]))} (σ : Assg tail✝), ¬i.val < List.length tail✝ → ∀ {b : List.get (List.append tail✝ [α]) i}, bot (HList.set (extendBot a σ) i b) = cast (_ : List.get (tail✝ ++ [α]) i = α) b
i: Fin (List.length (List.append (head✝ :: tail✝) [α]))
fst✝: head✝
snd✝: HList tail✝
n✝: Nat
h': Nat.succ n✝ < List.length (List.append (head✝ :: tail✝) [α])
h: ¬{ val := Nat.succ n✝, isLt := h' }.val < List.length (head✝ :: tail✝)
b: List.get (List.append (head✝ :: tail✝) [α]) { val := Nat.succ n✝, isLt := h' }
h'': { val := n✝, isLt := (_ : Nat.succ n✝ ≤ List.length (tail✝ ++ [α])) }.val < List.length tail✝
cons.mk.succ.hFalsetheoremGoals accomplished! 🐙eval_S [eval_S: ∀ {m : Type → Type} {ω : Type} {Γ Δ : List Type} {α : Type} {b c : Bool} {β : Type} {a : α} {ρ : HList Γ} {σ : Assg Δ} [inst : Monad m] [inst_1 : LawfulMonad m] (s : Stmt m ω Γ (List.append Δ [α]) b c β), StateT.run (Stmt.eval (a :: ρ) (S s) σ) a = do let x ← Stmt.eval ρ s (Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot σ, Assg.bot σ)MonadMonad: (Type ?u.552273 → Type ?u.552272) → Type (max (?u.552273 + 1) ?u.552272)m] [m: Type → TypeLawfulMonadLawfulMonad: (m : Type → Type) → [inst : Monad m] → Propm] : ∀ (m: Type → Types :s: Stmt m ω Γ (List.append Δ [α]) b c βStmtStmt: (Type → Type) → Type → List Type → List Type → Bool → Bool → Type → Type 1mm: Type → Typeωω: TypeΓ (Γ: List TypeΔ ++ [Δ: List Typeα])α: Typebb: Boolcc: Boolβ),β: TypeStateT.run ((StateT.run: {σ : Type} → {m : Type → Type} → {α : Type} → StateT σ m α → σ → m (α × σ)SS: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → {β : Type} → [inst : Monad m] → Stmt m ω Γ (List.append Δ [α]) b c β → Stmt (StateT α m) ω (α :: Γ) Δ b c βs).s: Stmt m ω Γ (List.append Δ [α]) b c βeval (eval: {m : Type → Type} → {Γ : List Type} → {ω : Type} → {Δ : List Type} → {b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)a ::a: αρ)ρ: HList Γσ)σ: Assg Δa =a: αs.s: Stmt m ω Γ (List.append Δ [α]) b c βevaleval: {m : Type → Type} → {Γ : List Type} → {ω : Type} → {Δ : List Type} → {b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)ρ (ρ: HList ΓAssg.extendBotAssg.extendBot: {α : Type} → α → {Γ : List Type} → Assg Γ → Assg (List.append Γ [α])aa: ασ) >>= fun |σ: Assg Δr ::r: Neut ω β b cσ =>σ: HList (List.append Δ [α])pure ((pure: {f : Type → Type} → [self : Pure f] → {α : Type} → α → f αr ::r: Neut ω β b cAssg.dropBotAssg.dropBot: {α : Type} → {Γ : List Type} → Assg (List.append Γ [α]) → Assg Γσ),σ: HList (List.append Δ [α])Assg.botAssg.bot: {α : Type} → {Γ : List Type} → Assg (List.append Γ [α]) → ασ) :=σ: HList (List.append Δ [α])m: Type → Type
ω: Type
Γ, Δ: List Type
α: Type
b, c: Bool
β: Type
a: α
ρ: HList Γ
σ: Assg Δ
inst✝¹: Monad m∀ (s : Stmt m ω Γ (List.append Δ [α]) b c β), StateT.run (Stmt.eval (a :: ρ) (S s) σ) a = do let x ← Stmt.eval ρ s (Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot σ, Assg.bot σ)m: Type → Type
ω: Type
Γ, Δ: List Type
α: Type
b, c: Bool
β: Type
a: α
ρ: HList Γ
σ: Assg Δ
inst✝¹: Monad m∀ {Δ' : List Type} (s : Stmt m ω Γ Δ' b c β) (h : Δ' = List.append Δ [α]), StateT.run (Stmt.eval (a :: ρ) (S (h ▸ s)) σ) a = do let x ← Stmt.eval ρ s ((_ : List.append Δ [α] = Δ') ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot (h ▸ σ), Assg.bot (h ▸ σ))m: Type → Type
ω: Type
Γ, Δ: List Type
α: Type
b, c: Bool
β: Type
a: α
ρ: HList Γ
σ: Assg Δ
inst✝¹: Monad m
Δ': List Type
s: Stmt m ω Γ Δ' b c β
h: Δ' = List.append Δ [α]StateT.run (Stmt.eval (a :: ρ) (S (h ▸ s)) σ) a = do let x ← Stmt.eval ρ s ((_ : List.append Δ [α] = Δ') ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot (h ▸ σ), Assg.bot (h ▸ σ))m: Type → Type
ω: Type
Γ, Δ: List Type
α: Type
b, c: Bool
β: Type
a: α
ρ: HList Γ
σ: Assg Δ
inst✝¹: Monad m
Δ': List Type
s: Stmt m ω Γ Δ' b c β
h: Δ' = List.append Δ [α]StateT.run (Stmt.eval (a :: ρ) (S (h ▸ s)) σ) a = do let x ← Stmt.eval ρ s ((_ : List.append Δ [α] = Δ') ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot (h ▸ σ), Assg.bot (h ▸ σ))m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
b✝, c✝: Bool
α✝: Type
Δ: List Type
a: α
ρ: HList Γ✝
σ: Assg Δ
e✝: Assg Γ✝ → Assg (List.append Δ [α]) → Bool
s₁✝, s₂✝: Stmt m ω Γ✝ (List.append Δ [α]) b✝ c✝ α✝
iteStateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Stmt.ite e✝ s₁✝ s₂✝)) σ) a = do let x ← Stmt.eval ρ (Stmt.ite e✝ s₁✝ s₂✝) ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
b✝, c✝: Bool
α✝, β✝: Type
Δ: List Type
a: α
ρ: HList Γ✝
σ: Assg Δ
s₁: Stmt m ω Γ✝ (List.append Δ [α]) b✝ c✝ α✝
s₂: Stmt m ω (α✝ :: Γ✝) (List.append Δ [α]) b✝ c✝ β✝
ih₁: ∀ {Δ_1 : List Type} {a : α} {ρ : HList Γ✝} {σ : Assg Δ_1} (h : List.append Δ [α] = List.append Δ_1 [α]), StateT.run (Stmt.eval (a :: ρ) (S (h ▸ s₁)) σ) a = do let x ← Stmt.eval ρ s₁ ((_ : List.append Δ_1 [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot (h ▸ σ), Assg.bot (h ▸ σ))
ih₂: ∀ {Δ_1 : List Type} {a : α} {ρ : HList (α✝ :: Γ✝)} {σ : Assg Δ_1} (h : List.append Δ [α] = List.append Δ_1 [α]), StateT.run (Stmt.eval (a :: ρ) (S (h ▸ s₂)) σ) a = do let x ← Stmt.eval ρ s₂ ((_ : List.append Δ_1 [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot (h ▸ σ), Assg.bot (h ▸ σ))
bindStateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Stmt.bind s₁ s₂)) σ) a = do let x ← Stmt.eval ρ (Stmt.bind s₁ s₂) ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
b✝, c✝: Bool
α✝, β✝: Type
Δ: List Type
a: α
ρ: HList Γ✝
σ: Assg Δ
s₁: Stmt m ω Γ✝ (List.append Δ [α]) b✝ c✝ α✝
s₂: Stmt m ω (α✝ :: Γ✝) (List.append Δ [α]) b✝ c✝ β✝
ih₂: ∀ {Δ_1 : List Type} {a : α} {ρ : HList (α✝ :: Γ✝)} {σ : Assg Δ_1} (h : List.append Δ [α] = List.append Δ_1 [α]), StateT.run (Stmt.eval (a :: ρ) (S (h ▸ s₂)) σ) a = do let x ← Stmt.eval ρ s₂ ((_ : List.append Δ_1 [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot (h ▸ σ), Assg.bot (h ▸ σ))
ih₁: ∀ (a : α) (ρ : HList Γ✝) (σ : Assg Δ), StateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ s₁)) σ) a = do let x ← Stmt.eval ρ s₁ ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))
bindStateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Stmt.bind s₁ s₂)) σ) a = do let x ← Stmt.eval ρ (Stmt.bind s₁ s₂) ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
b✝, c✝: Bool
α✝, β✝: Type
Δ: List Type
a: α
ρ: HList Γ✝
σ: Assg Δ
s₁: Stmt m ω Γ✝ (List.append Δ [α]) b✝ c✝ α✝
s₂: Stmt m ω (α✝ :: Γ✝) (List.append Δ [α]) b✝ c✝ β✝
ih₁: ∀ (a : α) (ρ : HList Γ✝) (σ : Assg Δ), StateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ s₁)) σ) a = do let x ← Stmt.eval ρ s₁ ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))
ih₂: ∀ (a : α) (ρ : HList (α✝ :: Γ✝)) (σ : Assg Δ), StateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ s₂)) σ) a = do let x ← Stmt.eval ρ s₂ ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))
bindStateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Stmt.bind s₁ s₂)) σ) a = do let x ← Stmt.eval ρ (Stmt.bind s₁ s₂) ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))Goals accomplished! 🐙m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
α✝: Type
b✝, c✝: Bool
β✝: Type
Δ: List Type
a: α
ρ: HList Γ✝
σ: Assg Δ
e: Assg Γ✝ → Assg (List.append Δ [α]) → α✝
s: Stmt m ω Γ✝ (α✝ :: List.append Δ [α]) b✝ c✝ β✝
ih: ∀ {Δ_1 : List Type} {a : α} {ρ : HList Γ✝} {σ : Assg Δ_1} (h : α✝ :: List.append Δ [α] = List.append Δ_1 [α]), StateT.run (Stmt.eval (a :: ρ) (S (h ▸ s)) σ) a = do let x ← Stmt.eval ρ s ((_ : List.append Δ_1 [α] = α✝ :: List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot (h ▸ σ), Assg.bot (h ▸ σ))
letmutStateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Stmt.letmut e s)) σ) a = do let x ← Stmt.eval ρ (Stmt.letmut e s) ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
α✝: Type
b✝, c✝: Bool
β✝: Type
Δ: List Type
a: α
ρ: HList Γ✝
σ: Assg Δ
e: Assg Γ✝ → Assg (List.append Δ [α]) → α✝
s: Stmt m ω Γ✝ (α✝ :: List.append Δ [α]) b✝ c✝ β✝
ih: ∀ (a : α) (ρ : HList Γ✝) (σ : Assg (α✝ :: Δ)), StateT.run (Stmt.eval (a :: ρ) (S ((_ : α✝ :: List.append Δ [α] = α✝ :: List.append Δ [α]) ▸ s)) σ) a = do let x ← Stmt.eval ρ s ((_ : List.append (α✝ :: Δ) [α] = α✝ :: List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : α✝ :: List.append Δ [α] = α✝ :: List.append Δ [α]) ▸ σ), Assg.bot ((_ : α✝ :: List.append Δ [α] = α✝ :: List.append Δ [α]) ▸ σ))
letmutStateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Stmt.letmut e s)) σ) a = do let x ← Stmt.eval ρ (Stmt.letmut e s) ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))Goals accomplished! 🐙m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
α✝: Type
b✝, c✝: Bool
Δ: List Type
a: α
ρ: HList Γ✝
σ: Assg Δ
e: Assg Γ✝ → Assg (List.append Δ [α]) → List α✝
s: Stmt m ω (α✝ :: Γ✝) (List.append Δ [α]) true true Unit
ih: ∀ {Δ_1 : List Type} {a : α} {ρ : HList (α✝ :: Γ✝)} {σ : Assg Δ_1} (h : List.append Δ [α] = List.append Δ_1 [α]), StateT.run (Stmt.eval (a :: ρ) (S (h ▸ s)) σ) a = do let x ← Stmt.eval ρ s ((_ : List.append Δ_1 [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot (h ▸ σ), Assg.bot (h ▸ σ))
sforStateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Stmt.sfor e s)) σ) a = do let x ← Stmt.eval ρ (Stmt.sfor e s) ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
α✝: Type
b✝, c✝: Bool
Δ: List Type
a: α
ρ: HList Γ✝
σ: Assg Δ
e: Assg Γ✝ → Assg (List.append Δ [α]) → List α✝
s: Stmt m ω (α✝ :: Γ✝) (List.append Δ [α]) true true Unit
ih: ∀ (a : α) (ρ : HList (α✝ :: Γ✝)) (σ : Assg Δ), StateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ s)) σ) a = do let x ← Stmt.eval ρ s ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))
sforStateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Stmt.sfor e s)) σ) a = do let x ← Stmt.eval ρ (Stmt.sfor e s) ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
α✝: Type
b✝, c✝: Bool
Δ: List Type
a: α
ρ: HList Γ✝
σ: Assg Δ
e: Assg Γ✝ → Assg (List.append Δ [α]) → List α✝
s: Stmt m ω (α✝ :: Γ✝) (List.append Δ [α]) true true Unit
ih: ∀ (a : α) (ρ : HList (α✝ :: Γ✝)) (σ : Assg Δ), StateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ s)) σ) a = do let x ← Stmt.eval ρ s ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))
sforStateT.run (Stmt.eval.go (a :: ρ) c✝ b✝ α✝ (Stmt.bind (Stmt.expr fun x x => get) (Stmt.mapAssg S.shadowSnd (S s))) σ (e ρ (Assg.extendBot a σ))) a = do let x ← Stmt.eval.go ρ c✝ b✝ α✝ s (Assg.extendBot a σ) (e ρ (Assg.extendBot a σ)) pure (x.fst :: Assg.dropBot x.snd, Assg.bot x.snd)m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
α✝: Type
b✝, c✝: Bool
Δ: List Type
a: α
ρ: HList Γ✝
σ: Assg Δ
e: Assg Γ✝ → Assg (List.append Δ [α]) → List α✝
s: Stmt m ω (α✝ :: Γ✝) (List.append Δ [α]) true true Unit
ih: ∀ {Δ_1 : List Type} {a : α} {ρ : HList (α✝ :: Γ✝)} {σ : Assg Δ_1} (h : List.append Δ [α] = List.append Δ_1 [α]), StateT.run (Stmt.eval (a :: ρ) (S (h ▸ s)) σ) a = do let x ← Stmt.eval ρ s ((_ : List.append Δ_1 [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot (h ▸ σ), Assg.bot (h ▸ σ))
sforStateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Stmt.sfor e s)) σ) a = do let x ← Stmt.eval ρ (Stmt.sfor e s) ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
α✝: Type
b✝, c✝: Bool
Δ: List Type
a: α
ρ: HList Γ✝
σ: Assg Δ
e: Assg Γ✝ → Assg (List.append Δ [α]) → List α✝
s: Stmt m ω (α✝ :: Γ✝) (List.append Δ [α]) true true Unit
ih: ∀ (a : α) (ρ : HList (α✝ :: Γ✝)) (σ : Assg Δ), StateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ s)) σ) a = do let x ← Stmt.eval ρ s ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))
a': α
h: a = a'
sforStateT.run (Stmt.eval.go (a' :: ρ) c✝ b✝ α✝ (Stmt.bind (Stmt.expr fun x x => get) (Stmt.mapAssg S.shadowSnd (S s))) σ (e ρ (Assg.extendBot a' σ))) a' = do let x ← Stmt.eval.go ρ c✝ b✝ α✝ s (Assg.extendBot a' σ) (e ρ (Assg.extendBot a' σ)) pure (x.fst :: Assg.dropBot x.snd, Assg.bot x.snd)m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
α✝: Type
b✝, c✝: Bool
Δ: List Type
a: α
ρ: HList Γ✝
σ: Assg Δ
e: Assg Γ✝ → Assg (List.append Δ [α]) → List α✝
s: Stmt m ω (α✝ :: Γ✝) (List.append Δ [α]) true true Unit
ih: ∀ (a : α) (ρ : HList (α✝ :: Γ✝)) (σ : Assg Δ), StateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ s)) σ) a = do let x ← Stmt.eval ρ s ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))
a': α
h: a = a'a :: ρm: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
α✝: Type
b✝, c✝: Bool
Δ: List Type
a: α
ρ: HList Γ✝
σ: Assg Δ
e: Assg Γ✝ → Assg (List.append Δ [α]) → List α✝
s: Stmt m ω (α✝ :: Γ✝) (List.append Δ [α]) true true Unit
ih: ∀ (a : α) (ρ : HList (α✝ :: Γ✝)) (σ : Assg Δ), StateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ s)) σ) a = do let x ← Stmt.eval ρ s ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))
a': α
h: a = a'a' :: ρm: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
α✝: Type
b✝, c✝: Bool
Δ: List Type
a: α
ρ: HList Γ✝
σ: Assg Δ
e: Assg Γ✝ → Assg (List.append Δ [α]) → List α✝
s: Stmt m ω (α✝ :: Γ✝) (List.append Δ [α]) true true Unit
ih: ∀ (a : α) (ρ : HList (α✝ :: Γ✝)) (σ : Assg Δ), StateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ s)) σ) a = do let x ← Stmt.eval ρ s ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))
a': α
h: a = a'a' :: ρm: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
α✝: Type
b✝, c✝: Bool
Δ: List Type
a: α
ρ: HList Γ✝
σ: Assg Δ
e: Assg Γ✝ → Assg (List.append Δ [α]) → List α✝
s: Stmt m ω (α✝ :: Γ✝) (List.append Δ [α]) true true Unit
ih: ∀ (a : α) (ρ : HList (α✝ :: Γ✝)) (σ : Assg Δ), StateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ s)) σ) a = do let x ← Stmt.eval ρ s ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))
a': α
h: a = a'a :: ρm: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
α✝: Type
b✝, c✝: Bool
Δ: List Type
a: α
ρ: HList Γ✝
σ: Assg Δ
e: Assg Γ✝ → Assg (List.append Δ [α]) → List α✝
s: Stmt m ω (α✝ :: Γ✝) (List.append Δ [α]) true true Unit
ih: ∀ (a : α) (ρ : HList (α✝ :: Γ✝)) (σ : Assg Δ), StateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ s)) σ) a = do let x ← Stmt.eval ρ s ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))
a': α
h: a = a'a :: ρm: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
α✝: Type
b✝, c✝: Bool
Δ: List Type
a: α
ρ: HList Γ✝
σ: Assg Δ
e: Assg Γ✝ → Assg (List.append Δ [α]) → List α✝
s: Stmt m ω (α✝ :: Γ✝) (List.append Δ [α]) true true Unit
ih: ∀ (a : α) (ρ : HList (α✝ :: Γ✝)) (σ : Assg Δ), StateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ s)) σ) a = do let x ← Stmt.eval ρ s ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))
a': α
sforStateT.run (Stmt.eval.go (a :: ρ) c✝ b✝ α✝ (Stmt.bind (Stmt.expr fun x x => get) (Stmt.mapAssg S.shadowSnd (S s))) σ (e ρ (Assg.extendBot a' σ))) a' = do let x ← Stmt.eval.go ρ c✝ b✝ α✝ s (Assg.extendBot a' σ) (e ρ (Assg.extendBot a' σ)) pure (x.fst :: Assg.dropBot x.snd, Assg.bot x.snd)m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
α✝: Type
b✝, c✝: Bool
Δ: List Type
a: α
ρ: HList Γ✝
e: Assg Γ✝ → Assg (List.append Δ [α]) → List α✝
s: Stmt m ω (α✝ :: Γ✝) (List.append Δ [α]) true true Unit
ih: ∀ (a : α) (ρ : HList (α✝ :: Γ✝)) (σ : Assg Δ), StateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ s)) σ) a = do let x ← Stmt.eval ρ s ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))
σ: Assg Δ
a': α
sfor.nilStateT.run (Stmt.eval.go (a :: ρ) c✝ b✝ α✝ (Stmt.bind (Stmt.expr fun x x => get) (Stmt.mapAssg S.shadowSnd (S s))) σ []) a' = do let x ← Stmt.eval.go ρ c✝ b✝ α✝ s (Assg.extendBot a' σ) [] pure (x.fst :: Assg.dropBot x.snd, Assg.bot x.snd)m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
α✝: Type
b✝, c✝: Bool
Δ: List Type
a: α
ρ: HList Γ✝
e: Assg Γ✝ → Assg (List.append Δ [α]) → List α✝
s: Stmt m ω (α✝ :: Γ✝) (List.append Δ [α]) true true Unit
ih: ∀ (a : α) (ρ : HList (α✝ :: Γ✝)) (σ : Assg Δ), StateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ s)) σ) a = do let x ← Stmt.eval ρ s ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))
head✝: α✝
tail✝: List α✝
σ: Assg Δ
a': αStateT.run (Stmt.eval.go (a :: ρ) c✝ b✝ α✝ (Stmt.bind (Stmt.expr fun x x => get) (Stmt.mapAssg S.shadowSnd (S s))) σ (head✝ :: tail✝)) a' = do let x ← Stmt.eval.go ρ c✝ b✝ α✝ s (Assg.extendBot a' σ) (head✝ :: tail✝) pure (x.fst :: Assg.dropBot x.snd, Assg.bot x.snd)m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
α✝: Type
b✝, c✝: Bool
Δ: List Type
a: α
ρ: HList Γ✝
e: Assg Γ✝ → Assg (List.append Δ [α]) → List α✝
s: Stmt m ω (α✝ :: Γ✝) (List.append Δ [α]) true true Unit
ih: ∀ (a : α) (ρ : HList (α✝ :: Γ✝)) (σ : Assg Δ), StateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ s)) σ) a = do let x ← Stmt.eval ρ s ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))
σ: Assg Δ
a': α
sfor.nilStateT.run (Stmt.eval.go (a :: ρ) c✝ b✝ α✝ (Stmt.bind (Stmt.expr fun x x => get) (Stmt.mapAssg S.shadowSnd (S s))) σ []) a' = do let x ← Stmt.eval.go ρ c✝ b✝ α✝ s (Assg.extendBot a' σ) [] pure (x.fst :: Assg.dropBot x.snd, Assg.bot x.snd)m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
α✝: Type
b✝, c✝: Bool
Δ: List Type
a: α
ρ: HList Γ✝
e: Assg Γ✝ → Assg (List.append Δ [α]) → List α✝
s: Stmt m ω (α✝ :: Γ✝) (List.append Δ [α]) true true Unit
ih: ∀ (a : α) (ρ : HList (α✝ :: Γ✝)) (σ : Assg Δ), StateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ s)) σ) a = do let x ← Stmt.eval ρ s ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))
head✝: α✝
tail✝: List α✝
σ: Assg Δ
a': αStateT.run (Stmt.eval.go (a :: ρ) c✝ b✝ α✝ (Stmt.bind (Stmt.expr fun x x => get) (Stmt.mapAssg S.shadowSnd (S s))) σ (head✝ :: tail✝)) a' = do let x ← Stmt.eval.go ρ c✝ b✝ α✝ s (Assg.extendBot a' σ) (head✝ :: tail✝) pure (x.fst :: Assg.dropBot x.snd, Assg.bot x.snd)Goals accomplished! 🐙m: Type → Type
ω: Type
Γ: List Type
α: Type
b, c: Bool
β: Type
inst✝¹: Monad m
Δ', Γ✝: List Type
b✝, c✝: Bool
α✝: Type
Δ: List Type
a: α
ρ: HList Γ✝
σ: Assg Δ
e✝: Assg Γ✝ → Assg (List.append Δ [α]) → Bool
s₁✝, s₂✝: Stmt m ω Γ✝ (List.append Δ [α]) b✝ c✝ α✝
iteStateT.run (Stmt.eval (a :: ρ) (S ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Stmt.ite e✝ s₁✝ s₂✝)) σ) a = do let x ← Stmt.eval ρ (Stmt.ite e✝ s₁✝ s₂✝) ((_ : List.append Δ [α] = List.append Δ [α]) ▸ Assg.extendBot a σ) match x with | (r, σ) => pure (r :: Assg.dropBot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ), Assg.bot ((_ : List.append Δ [α] = List.append Δ [α]) ▸ σ))theoremGoals accomplished! 🐙HList.eq_nil (HList.eq_nil: ∀ (as : HList ∅), as = ∅as :as: HList ∅HListHList: List (Type u_1) → Type u_1∅) :∅: List (Type u_1)as = ∅ :=as: HList ∅rfl attribute [local simp]rfl: ∀ {α : Type u_1} {a : α}, a = aExceptT.run_bind theoremExceptT.run_bind: ∀ {m : Type u_1 → Type u_2} {ε α β : Type u_1} {f : α → ExceptT ε m β} [inst : Monad m] (x : ExceptT ε m α), ExceptT.run (x >>= f) = do let x ← ExceptT.run x match x with | Except.ok x => ExceptT.run (f x) | Except.error e => pure (Except.error e)eval_L [eval_L: ∀ {m : Type → Type u_1} {ω : Type} {Γ Δ : List Type} {b c : Bool} {α : Type} {ρ : Assg Γ} {σ : Assg Δ} [inst : Monad m] [inst_1 : LawfulMonad m] (s : Stmt m ω Γ Δ b c α), Stmt.eval ρ (L s) σ = ExceptT.lift (Stmt.eval ρ s σ)MonadMonad: (Type ?u.632180 → Type ?u.632179) → Type (max (?u.632180 + 1) ?u.632179)m] [m: Type → Type u_1LawfulMonadLawfulMonad: (m : Type → Type u_1) → [inst : Monad m] → Propm] (m: Type → Type u_1s :s: Stmt m ω Γ Δ b c αStmtStmt: (Type → Type u_1) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 u_1)mm: Type → Type u_1ωω: TypeΓΓ: List TypeΔΔ: List Typebb: Boolcc: Boolα) : (α: TypeLL: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ b c αs).s: Stmt m ω Γ Δ b c αevaleval: {m : Type → Type u_1} → {Γ : List Type} → {ω : Type} → {Δ : List Type} → {b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)ρρ: Assg Γσ =σ: Assg ΔExceptT.lift (ExceptT.lift: {ε : Type} → {m : Type → Type u_1} → [inst : Monad m] → {α : Type} → m α → ExceptT ε m αs.s: Stmt m ω Γ Δ b c αevaleval: {m : Type → Type u_1} → {Γ : List Type} → {ω : Type} → {Δ : List Type} → {b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)ρρ: Assg Γσ) :=σ: Assg Δm: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
ρ: Assg Γ
σ: Assg Δ
inst✝¹: Monad m
s: Stmt m ω Γ Δ b c αStmt.eval ρ (L s) σ = ExceptT.lift (Stmt.eval ρ s σ)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
ρ: Assg Γ
σ: Assg Δ
inst✝¹: Monad m
s: Stmt m ω Γ Δ b c α
hExceptT.run (Stmt.eval ρ (L s) σ) = ExceptT.run (ExceptT.lift (Stmt.eval ρ s σ))m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
ρ: Assg Γ
σ: Assg Δ
inst✝¹: Monad m
s: Stmt m ω Γ Δ b c α
hExceptT.run (Stmt.eval ρ (L s) σ) = ExceptT.run (ExceptT.lift (Stmt.eval ρ s σ))m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
σ: Assg Δ✝
h.sforExceptT.run (Stmt.eval ρ (L (Stmt.sfor e s✝)) σ) = ExceptT.run (ExceptT.lift (Stmt.eval ρ (Stmt.sfor e s✝) σ))m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
σ: Assg Δ✝
h.sforExceptT.run (Stmt.eval.go ρ c✝ b✝ α✝ (L s✝) σ (e ρ σ)) = ExceptT.run (ExceptT.lift (Stmt.eval.go ρ c✝ b✝ α✝ s✝ σ (e ρ σ)))m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
σ: Assg Δ✝
h.sfor.nilExceptT.run (Stmt.eval.go ρ c✝ b✝ α✝ (L s✝) σ []) = ExceptT.run (ExceptT.lift (Stmt.eval.go ρ c✝ b✝ α✝ s✝ σ []))m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
head✝: α✝
tail✝: List α✝
σ: Assg Δ✝ExceptT.run (Stmt.eval.go ρ c✝ b✝ α✝ (L s✝) σ (head✝ :: tail✝)) = ExceptT.run (ExceptT.lift (Stmt.eval.go ρ c✝ b✝ α✝ s✝ σ (head✝ :: tail✝)))m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
σ: Assg Δ✝
h.sfor.nilExceptT.run (Stmt.eval.go ρ c✝ b✝ α✝ (L s✝) σ []) = ExceptT.run (ExceptT.lift (Stmt.eval.go ρ c✝ b✝ α✝ s✝ σ []))m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
head✝: α✝
tail✝: List α✝
σ: Assg Δ✝ExceptT.run (Stmt.eval.go ρ c✝ b✝ α✝ (L s✝) σ (head✝ :: tail✝)) = ExceptT.run (ExceptT.lift (Stmt.eval.go ρ c✝ b✝ α✝ s✝ σ (head✝ :: tail✝)))Goals accomplished! 🐙m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
b✝, c✝: Bool
x✝: Fin (List.length Δ✝)
e✝: Assg Γ✝ → Assg Δ✝ → List.get Δ✝ x✝
ρ: Assg Γ✝
σ: Assg Δ✝
h.assgExceptT.run (Stmt.eval ρ (L (Stmt.assg x✝ e✝)) σ) = ExceptT.run (ExceptT.lift (Stmt.eval ρ (Stmt.assg x✝ e✝) σ))theoremGoals accomplished! 🐙eval_B [eval_B: ∀ {m : Type → Type u_1} {ω : Type} {Γ Δ : List Type} {b c : Bool} {α : Type} {ρ : Assg Γ} {σ : Assg Δ} [inst : Monad m] [inst_1 : LawfulMonad m] (s : Stmt m ω Γ Δ b c α), Stmt.eval ρ (B s) σ = do let x ← ExceptT.lift (Stmt.eval ρ s σ) match b, c, x with | b, c, (Neut.ret o, σ) => pure (Neut.ret o, σ) | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, snd) => throw ()MonadMonad: (Type ?u.666038 → Type ?u.666037) → Type (max (?u.666038 + 1) ?u.666037)m] [m: Type → Type u_1LawfulMonadLawfulMonad: (m : Type ?u.665935 → Type ?u.665934) → [inst : Monad m] → Propm] (m: Type → Type u_1s :s: Stmt m ω Γ Δ b c αStmtStmt: (Type → Type ?u.665969) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 ?u.665969)mm: Type → Type u_1ωω: TypeΓΓ: List TypeΔΔ: List Typebb: Boolcc: Boolα) : (α: TypeBB: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ b c α → Stmt (ExceptT Unit m) ω Γ Δ false c αs).s: Stmt m ω Γ Δ b c αevaleval: {m : Type → Type u_1} → {Γ : List Type} → {ω : Type} → {Δ : List Type} → {b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)ρρ: Assg Γσ = (σ: Assg ΔExceptT.lift (ExceptT.lift: {ε : Type} → {m : Type → Type u_1} → [inst : Monad m] → {α : Type} → m α → ExceptT ε m αs.s: Stmt m ω Γ Δ b c αevaleval: {m : Type → Type u_1} → {Γ : List Type} → {ω : Type} → {Δ : List Type} → {b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)ρρ: Assg Γσ) >>= funσ: Assg Δx => match (generalizing := false)x: Neut ω α b c × Assg Δx with | (x: Neut ω α b c × Assg ΔNeut.retNeut.ret: {ω α : Type} → {b c : Bool} → ω → Neut ω α b co,o: ωσ) =>σ: Assg Δpure (pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f αNeut.retNeut.ret: {ω α : Type} → {b c : Bool} → ω → Neut ω α b co,o: ωσ) | (σ: Assg ΔNeut.valNeut.val: {ω α : Type} → {b c : Bool} → α → Neut ω α b ca,a: ασ) =>σ: Assg Δpure (pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f αNeut.valNeut.val: {ω α : Type} → {b c : Bool} → α → Neut ω α b ca,a: ασ) | (σ: Assg ΔNeut.rcont,Neut.rcont: {ω α : Type} → {b : Bool} → Neut ω α b trueσ) =>σ: Assg Δpure (pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f αNeut.rcont,Neut.rcont: {ω α : Type} → {b : Bool} → Neut ω α b trueσ) | (σ: Assg ΔNeut.rbreak, _) =>Neut.rbreak: {ω α : Type} → {c : Bool} → Neut ω α true cthrow () :throw: {ε : Type} → {m : Type → Type u_1} → [self : MonadExcept ε m] → {α : Type} → ε → m αExceptTExceptT: Type → (Type → Type u_1) → Type → Type u_1UnitUnit: Typem (m: Type → Type u_1NeutNeut: Type → Type → Bool → Bool → Typeωω: Typeαα: Typefalsefalse: Boolc ×c: BoolAssgAssg: List Type → TypeΔ)) :=Δ: List Typem: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
ρ: Assg Γ
σ: Assg Δ
inst✝¹: Monad m
s: Stmt m ω Γ Δ b c αStmt.eval ρ (B s) σ = do let x ← ExceptT.lift (Stmt.eval ρ s σ) match b, c, x with | b, c, (Neut.ret o, σ) => pure (Neut.ret o, σ) | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, snd) => throw ()m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
ρ: Assg Γ
σ: Assg Δ
inst✝¹: Monad m
s: Stmt m ω Γ Δ b c α
hExceptT.run (Stmt.eval ρ (B s) σ) = ExceptT.run do let x ← ExceptT.lift (Stmt.eval ρ s σ) match b, c, x with | b, c, (Neut.ret o, σ) => pure (Neut.ret o, σ) | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, snd) => throw ()m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
ρ: Assg Γ
σ: Assg Δ
inst✝¹: Monad m
s: Stmt m ω Γ Δ b c α
hExceptT.run (Stmt.eval ρ (B s) σ) = ExceptT.run do let x ← ExceptT.lift (Stmt.eval ρ s σ) match b, c, x with | b, c, (Neut.ret o, σ) => pure (Neut.ret o, σ) | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, snd) => throw ()m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
σ: Assg Δ✝
h.sforExceptT.run (Stmt.eval ρ (B (Stmt.sfor e s✝)) σ) = ExceptT.run do let x ← ExceptT.lift (Stmt.eval ρ (Stmt.sfor e s✝) σ) match b✝, c✝, x with | b, c, (Neut.ret o, σ) => pure (Neut.ret o, σ) | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, snd) => throw ()m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
σ: Assg Δ✝
h.sforExceptT.run (Stmt.eval.go ρ c✝ false α✝ (L s✝) σ (e ρ σ)) = ExceptT.run do let x ← ExceptT.lift (Stmt.eval.go ρ c✝ b✝ α✝ s✝ σ (e ρ σ)) match b✝, c✝, x with | b, c, (Neut.ret o, σ) => pure (Neut.ret o, σ) | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, snd) => throw ()m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
σ: Assg Δ✝
h.sfor.nilExceptT.run (Stmt.eval.go ρ c✝ false α✝ (L s✝) σ []) = ExceptT.run do let x ← ExceptT.lift (Stmt.eval.go ρ c✝ b✝ α✝ s✝ σ []) match b✝, c✝, x with | b, c, (Neut.ret o, σ) => pure (Neut.ret o, σ) | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, snd) => throw ()m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
head✝: α✝
tail✝: List α✝
σ: Assg Δ✝ExceptT.run (Stmt.eval.go ρ c✝ false α✝ (L s✝) σ (head✝ :: tail✝)) = ExceptT.run do let x ← ExceptT.lift (Stmt.eval.go ρ c✝ b✝ α✝ s✝ σ (head✝ :: tail✝)) match b✝, c✝, x with | b, c, (Neut.ret o, σ) => pure (Neut.ret o, σ) | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, snd) => throw ()m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
σ: Assg Δ✝
h.sfor.nilExceptT.run (Stmt.eval.go ρ c✝ false α✝ (L s✝) σ []) = ExceptT.run do let x ← ExceptT.lift (Stmt.eval.go ρ c✝ b✝ α✝ s✝ σ []) match b✝, c✝, x with | b, c, (Neut.ret o, σ) => pure (Neut.ret o, σ) | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, snd) => throw ()m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
head✝: α✝
tail✝: List α✝
σ: Assg Δ✝ExceptT.run (Stmt.eval.go ρ c✝ false α✝ (L s✝) σ (head✝ :: tail✝)) = ExceptT.run do let x ← ExceptT.lift (Stmt.eval.go ρ c✝ b✝ α✝ s✝ σ (head✝ :: tail✝)) match b✝, c✝, x with | b, c, (Neut.ret o, σ) => pure (Neut.ret o, σ) | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, snd) => throw ()Goals accomplished! 🐙m: Type → Type u_1
ω: Type
Γ, Δ: List Type
b, c: Bool
α: Type
inst✝¹: Monad m
Γ✝, Δ✝: List Type
b✝, c✝: Bool
x✝: Fin (List.length Δ✝)
e✝: Assg Γ✝ → Assg Δ✝ → List.get Δ✝ x✝
ρ: Assg Γ✝
σ: Assg Δ✝
h.assgExceptT.run (Stmt.eval ρ (B (Stmt.assg x✝ e✝)) σ) = ExceptT.run do let x ← ExceptT.lift (Stmt.eval ρ (Stmt.assg x✝ e✝) σ) match b✝, c✝, x with | b, c, (Neut.ret o, σ) => pure (Neut.ret o, σ) | b, c, (Neut.val a, σ) => pure (Neut.val a, σ) | b, .(true), (Neut.rcont, σ) => pure (Neut.rcont, σ) | .(true), c, (Neut.rbreak, snd) => throw ()@[simp] defGoals accomplished! 🐙throwOnContinue [throwOnContinue: {m : Type → Type u_1} → {ω α : Type} → {c : Bool} → {Δ : List Type} → [inst : Monad m] → Neut ω α false c × Assg Δ → ExceptT Unit m (Neut ω α false false × Assg Δ)MonadMonad: (Type ?u.788677 → Type ?u.788676) → Type (max (?u.788677 + 1) ?u.788676)m] : (m: Type → Type u_1NeutNeut: Type → Type → Bool → Bool → Typeωω: Typeαα: Typefalsefalse: Boolc ×c: BoolAssgAssg: List Type → TypeΔ) →Δ: List TypeExceptTExceptT: Type → (Type → Type u_1) → Type → Type u_1UnitUnit: Typem (m: Type → Type u_1NeutNeut: Type → Type → Bool → Bool → Typeωω: Typeαα: Typefalsefalse: Boolfalse ×false: BoolAssgAssg: List Type → TypeΔ) | (Δ: List TypeNeut.retNeut.ret: {ω α : Type} → {b c : Bool} → ω → Neut ω α b co,o: ωσ) =>σ: Assg Δpure (pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f αNeut.retNeut.ret: {ω α : Type} → {b c : Bool} → ω → Neut ω α b co,o: ωσ) | (σ: Assg ΔNeut.valNeut.val: {ω α : Type} → {b c : Bool} → α → Neut ω α b ca,a: ασ) =>σ: Assg Δpure (pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f αNeut.valNeut.val: {ω α : Type} → {b c : Bool} → α → Neut ω α b ca,a: ασ) | (σ: Assg ΔNeut.rcont, _) =>Neut.rcont: {ω α : Type} → {b : Bool} → Neut ω α b truethrowthrow: {ε : Type} → {m : Type → Type u_1} → [self : MonadExcept ε m] → {α : Type} → ε → m α() theorem(): Uniteval_C [eval_C: ∀ {m : Type → Type u_1} {ω : Type} {Γ Δ : List Type} {c : Bool} {α : Type} {ρ : Assg Γ} {σ : Assg Δ} [inst : Monad m] [inst_1 : LawfulMonad m] (s : Stmt m ω Γ Δ false c α), Stmt.eval ρ (C s) σ = ExceptT.lift (Stmt.eval ρ s σ) >>= throwOnContinueMonadMonad: (Type ?u.790186 → Type ?u.790185) → Type (max (?u.790186 + 1) ?u.790185)m] [m: Type → Type u_1LawfulMonadLawfulMonad: (m : Type ?u.790060 → Type ?u.790059) → [inst : Monad m] → Propm] (m: Type → Type u_1s :s: Stmt m ω Γ Δ false c αStmtStmt: (Type → Type ?u.790118) → Type → List Type → List Type → Bool → Bool → Type → Type (max 1 ?u.790118)mm: Type → Type u_1ωω: TypeΓΓ: List TypeΔΔ: List Typefalsefalse: Boolcc: Boolα) : (α: TypeCC: {m : Type → Type u_1} → {ω : Type} → {Γ Δ : List Type} → {c : Bool} → {α : Type} → [inst : Monad m] → Stmt m ω Γ Δ false c α → Stmt (ExceptT Unit m) ω Γ Δ false false αs).s: Stmt m ω Γ Δ false c αevaleval: {m : Type → Type u_1} → {Γ : List Type} → {ω : Type} → {Δ : List Type} → {b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)ρρ: Assg Γσ =σ: Assg ΔExceptT.lift (ExceptT.lift: {ε : Type} → {m : Type → Type u_1} → [inst : Monad m] → {α : Type} → m α → ExceptT ε m αs.s: Stmt m ω Γ Δ false c αevaleval: {m : Type → Type u_1} → {Γ : List Type} → {ω : Type} → {Δ : List Type} → {b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)ρρ: Assg Γσ) >>=σ: Assg ΔthrowOnContinue :=throwOnContinue: {m : Type → Type u_1} → {ω α : Type} → {c : Bool} → {Δ : List Type} → [inst : Monad m] → Neut ω α false c × Assg Δ → ExceptT Unit m (Neut ω α false false × Assg Δ)m: Type → Type u_1
ω: Type
Γ, Δ: List Type
c: Bool
α: Type
ρ: Assg Γ
σ: Assg Δ
inst✝¹: Monad m
s: Stmt m ω Γ Δ false c αStmt.eval ρ (C s) σ = ExceptT.lift (Stmt.eval ρ s σ) >>= throwOnContinuem: Type → Type u_1
ω: Type
Γ, Δ: List Type
c: Bool
α: Type
ρ: Assg Γ
σ: Assg Δ
inst✝¹: Monad m∀ (s : Stmt m ω Γ Δ false c α), Stmt.eval ρ (C s) σ = ExceptT.lift (Stmt.eval ρ s σ) >>= throwOnContinuem: Type → Type u_1
ω: Type
Γ, Δ: List Type
c: Bool
α: Type
ρ: Assg Γ
σ: Assg Δ
inst✝¹: Monad m∀ {b : Bool} (s' : Stmt m ω Γ Δ b c α) (h : b = false), let s := h ▸ s'; Stmt.eval ρ (C s) σ = ExceptT.lift (Stmt.eval ρ s σ) >>= throwOnContinuem: Type → Type u_1
ω: Type
Γ, Δ: List Type
c: Bool
α: Type
ρ: Assg Γ
σ: Assg Δ
inst✝¹: Monad m
b': Bool
s: Stmt m ω Γ Δ b' c α
h: b' = falselet s := h ▸ s; Stmt.eval ρ (C s) σ = ExceptT.lift (Stmt.eval ρ s σ) >>= throwOnContinuem: Type → Type u_1
ω: Type
Γ, Δ: List Type
c: Bool
α: Type
ρ: Assg Γ
σ: Assg Δ
inst✝¹: Monad m
b': Bool
s: Stmt m ω Γ Δ b' c α
h: b' = falselet s := h ▸ s; Stmt.eval ρ (C s) σ = ExceptT.lift (Stmt.eval ρ s σ) >>= throwOnContinuem: Type → Type u_1
ω: Type
Γ, Δ: List Type
c: Bool
α: Type
inst✝¹: Monad m
b': Bool
Γ✝, Δ✝: List Type
α✝: Type
b✝, c✝: Bool
β✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → α✝
s✝: Stmt m ω Γ✝ (α✝ :: Δ✝) b✝ c✝ β✝
ρ: Assg Γ✝
σ: Assg Δ✝
h: b✝ = false
letmutlet s := h ▸ Stmt.letmut e✝ s✝; Stmt.eval ρ (C s) σ = ExceptT.lift (Stmt.eval ρ s σ) >>= throwOnContinuem: Type → Type u_1
ω: Type
Γ, Δ: List Type
c: Bool
α: Type
inst✝¹: Monad m
b': Bool
Γ✝, Δ✝: List Type
b✝, c✝: Bool
α✝, β✝: Type
s✝: Stmt m ω Γ✝ Δ✝ b✝ c✝ α✝
s'✝: Stmt m ω (α✝ :: Γ✝) Δ✝ b✝ c✝ β✝
ρ: Assg Γ✝
σ: Assg Δ✝
h: b✝ = false
bindlet s := h ▸ Stmt.bind s✝ s'✝; Stmt.eval ρ (C s) σ = ExceptT.lift (Stmt.eval ρ s σ) >>= throwOnContinuem: Type → Type u_1
ω: Type
Γ, Δ: List Type
c: Bool
α: Type
inst✝¹: Monad m
b': Bool
Γ✝, Δ✝: List Type
c✝: Bool
α✝, β✝: Type
ρ: Assg Γ✝
σ: Assg Δ✝
s✝: Stmt m ω Γ✝ Δ✝ false c✝ α✝
s'✝: Stmt m ω (α✝ :: Γ✝) Δ✝ false c✝ β✝
bindlet s := (_ : false = false) ▸ Stmt.bind s✝ s'✝; Stmt.eval ρ (C s) σ = ExceptT.lift (Stmt.eval ρ s σ) >>= throwOnContinuem: Type → Type u_1
ω: Type
Γ, Δ: List Type
c: Bool
α: Type
inst✝¹: Monad m
b': Bool
Γ✝, Δ✝: List Type
b✝, c✝: Bool
α✝, β✝: Type
s✝: Stmt m ω Γ✝ Δ✝ b✝ c✝ α✝
s'✝: Stmt m ω (α✝ :: Γ✝) Δ✝ b✝ c✝ β✝
ρ: Assg Γ✝
σ: Assg Δ✝
h: b✝ = false
bindlet s := h ▸ Stmt.bind s✝ s'✝; Stmt.eval ρ (C s) σ = ExceptT.lift (Stmt.eval ρ s σ) >>= throwOnContinuem: Type → Type u_1
ω: Type
Γ, Δ: List Type
c: Bool
α: Type
inst✝¹: Monad m
b': Bool
Γ✝, Δ✝: List Type
c✝: Bool
α✝: Type
ρ: Assg Γ✝
σ: Assg Δ✝
h: true = false
sbreaklet s := h ▸ Stmt.sbreak; Stmt.eval ρ (C s) σ = ExceptT.lift (Stmt.eval ρ s σ) >>= throwOnContinuem: Type → Type u_1
ω: Type
Γ, Δ: List Type
c: Bool
α: Type
inst✝¹: Monad m
b': Bool
Γ✝, Δ✝: List Type
α✝: Type
c✝: Bool
β✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → α✝
ρ: Assg Γ✝
σ: Assg Δ✝
s✝: Stmt m ω Γ✝ (α✝ :: Δ✝) false c✝ β✝
letmutlet s := (_ : false = false) ▸ Stmt.letmut e✝ s✝; Stmt.eval ρ (C s) σ = ExceptT.lift (Stmt.eval ρ s σ) >>= throwOnContinuem: Type → Type u_1
ω: Type
Γ, Δ: List Type
c: Bool
α: Type
inst✝¹: Monad m
b': Bool
Γ✝, Δ✝: List Type
α✝: Type
c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
σ: Assg Δ✝
sforlet s := (_ : false = false) ▸ Stmt.sfor e s✝; Stmt.eval ρ (C s) σ = ExceptT.lift (Stmt.eval ρ s σ) >>= throwOnContinuem: Type → Type u_1
ω: Type
Γ, Δ: List Type
c: Bool
α: Type
inst✝¹: Monad m
b': Bool
Γ✝, Δ✝: List Type
α✝: Type
c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
σ: Assg Δ✝
sforStmt.eval.go ρ false false α✝ (L s✝) σ (e ρ σ) = ExceptT.lift (Stmt.eval.go ρ c✝ false α✝ s✝ σ (e ρ σ)) >>= throwOnContinuem: Type → Type u_1
ω: Type
Γ, Δ: List Type
c: Bool
α: Type
inst✝¹: Monad m
b': Bool
Γ✝, Δ✝: List Type
α✝: Type
c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
σ: Assg Δ✝
sfor.nilStmt.eval.go ρ false false α✝ (L s✝) σ [] = ExceptT.lift (Stmt.eval.go ρ c✝ false α✝ s✝ σ []) >>= throwOnContinuem: Type → Type u_1
ω: Type
Γ, Δ: List Type
c: Bool
α: Type
inst✝¹: Monad m
b': Bool
Γ✝, Δ✝: List Type
α✝: Type
c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
head✝: α✝
tail✝: List α✝
σ: Assg Δ✝Stmt.eval.go ρ false false α✝ (L s✝) σ (head✝ :: tail✝) = ExceptT.lift (Stmt.eval.go ρ c✝ false α✝ s✝ σ (head✝ :: tail✝)) >>= throwOnContinuem: Type → Type u_1
ω: Type
Γ, Δ: List Type
c: Bool
α: Type
inst✝¹: Monad m
b': Bool
Γ✝, Δ✝: List Type
α✝: Type
c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
σ: Assg Δ✝
sfor.nilStmt.eval.go ρ false false α✝ (L s✝) σ [] = ExceptT.lift (Stmt.eval.go ρ c✝ false α✝ s✝ σ []) >>= throwOnContinuem: Type → Type u_1
ω: Type
Γ, Δ: List Type
c: Bool
α: Type
inst✝¹: Monad m
b': Bool
Γ✝, Δ✝: List Type
α✝: Type
c✝: Bool
e: Assg Γ✝ → Assg Δ✝ → List α✝
s✝: Stmt m ω (α✝ :: Γ✝) Δ✝ true true Unit
ρ: Assg Γ✝
head✝: α✝
tail✝: List α✝
σ: Assg Δ✝Stmt.eval.go ρ false false α✝ (L s✝) σ (head✝ :: tail✝) = ExceptT.lift (Stmt.eval.go ρ c✝ false α✝ s✝ σ (head✝ :: tail✝)) >>= throwOnContinueGoals accomplished! 🐙m: Type → Type u_1
ω: Type
Γ, Δ: List Type
c: Bool
α: Type
inst✝¹: Monad m
b': Bool
Γ✝, Δ✝: List Type
α✝: Type
c✝: Bool
β✝: Type
e✝: Assg Γ✝ → Assg Δ✝ → α✝
ρ: Assg Γ✝
σ: Assg Δ✝
s✝: Stmt m ω Γ✝ (α✝ :: Δ✝) false c✝ β✝
letmutlet s := (_ : false = false) ▸ Stmt.letmut e✝ s✝; Stmt.eval ρ (C s) σ = ExceptT.lift (Stmt.eval ρ s σ) >>= throwOnContinuetheoremGoals accomplished! 🐙D_eq [D_eq: ∀ (_x : (m : Type → Type) ×' (Γ : List Type) ×' (α : Type) ×' (_ : Assg Γ) ×' (inst : Monad m) ×' (_ : LawfulMonad m) ×' Stmt m Empty Γ ∅ false false α), D _x.2.2.2.2.2.2 _x.2.2.2.1 = do let x ← Stmt.eval _x.2.2.2.1 _x.2.2.2.2.2.2 ∅ match x with | (Neut.val a, snd) => pure aMonadMonad: (Type ?u.924916 → Type ?u.924915) → Type (max (?u.924916 + 1) ?u.924915)m] [m: Type → TypeLawfulMonadLawfulMonad: (m : Type ?u.924921 → Type ?u.924920) → [inst : Monad m] → Propm] : (m: Type → Types :s: Stmt m Empty Γ ∅ false false αStmtStmt: (Type → Type) → Type → List Type → List Type → Bool → Bool → Type → Type 1mm: Type → TypeEmptyEmpty: TypeΓΓ: List Type∅∅: List Typefalsefalse: Boolfalsefalse: Boolα) →α: TypeDD: {m : Type → Type} → {Γ : List Type} → {α : Type} → [inst : Monad m] → Stmt m Empty Γ ∅ false false α → Assg Γ → m αss: Stmt m Empty Γ ∅ false false αρ =ρ: Assg Γs.s: Stmt m Empty Γ ∅ false false αevaleval: {m : Type → Type} → {Γ : List Type} → {ω : Type} → {Δ : List Type} → {b c : Bool} → {α : Type} → [inst : Monad m] → Assg Γ → Stmt m ω Γ Δ b c α → Assg Δ → m (Neut ω α b c × Assg Δ)ρ ∅ >>= fun (ρ: Assg ΓNeut.valNeut.val: {ω α : Type} → {b c : Bool} → α → Neut ω α b ca, _) =>a: αpurepure: {f : Type → Type} → [self : Pure f] → {α : Type} → α → f αa |a: αStmt.exprStmt.expr: {m : Type → Type ?u.926133} → {ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c αe =>e: Assg Γ → Assg ∅ → m αm: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α: Type
e: Assg Γ → Assg ∅ → m αD (Stmt.expr e) ρ = do let x ← Stmt.eval ρ (Stmt.expr e) ∅ match x with | (Neut.val a, snd) => pure a|Goals accomplished! 🐙Stmt.bindStmt.bind: {m : Type → Type ?u.926201} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c βs₁s₁: Stmt m Empty Γ ∅ false false α✝s₂ =>s₂: Stmt m Empty (α✝ :: Γ) ∅ false false αm: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α, α✝: Type
s₁: Stmt m Empty Γ ∅ false false α✝
s₂: Stmt m Empty (α✝ :: Γ) ∅ false false αD (Stmt.bind s₁ s₂) ρ = do let x ← Stmt.eval ρ (Stmt.bind s₁ s₂) ∅ match x with | (Neut.val a, snd) => pure am: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α, α✝: Type
s₁: Stmt m Empty Γ ∅ false false α✝
s₂: Stmt m Empty (α✝ :: Γ) ∅ false false α
ih₁: ∀ (ρ : Assg Γ), Monad m → LawfulMonad m → D s₁ ρ = do let x ← Stmt.eval ρ s₁ ∅ match x with | (Neut.val a, snd) => pure aD (Stmt.bind s₁ s₂) ρ = do let x ← Stmt.eval ρ (Stmt.bind s₁ s₂) ∅ match x with | (Neut.val a, snd) => pure am: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α, α✝: Type
s₁: Stmt m Empty Γ ∅ false false α✝
s₂: Stmt m Empty (α✝ :: Γ) ∅ false false α
ih₁: ∀ (ρ : Assg Γ), Monad m → LawfulMonad m → D s₁ ρ = do let x ← Stmt.eval ρ s₁ ∅ match x with | (Neut.val a, snd) => pure a
ih₂: ∀ (ρ : Assg (α✝ :: Γ)), Monad m → LawfulMonad m → D s₂ ρ = do let x ← Stmt.eval ρ s₂ ∅ match x with | (Neut.val a, snd) => pure aD (Stmt.bind s₁ s₂) ρ = do let x ← Stmt.eval ρ (Stmt.bind s₁ s₂) ∅ match x with | (Neut.val a, snd) => pure a|Goals accomplished! 🐙Stmt.letmutStmt.letmut: {m : Type → Type ?u.926267} → {ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → {β : Type} → (Assg Γ → Assg Δ → α) → Stmt m ω Γ (α :: Δ) b c β → Stmt m ω Γ Δ b c βee: Assg Γ → Assg ∅ → α✝s =>s: Stmt m Empty Γ (α✝ :: ∅) false false αm: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α, α✝: Type
e: Assg Γ → Assg ∅ → α✝
s: Stmt m Empty Γ (α✝ :: ∅) false false αD (Stmt.letmut e s) ρ = do let x ← Stmt.eval ρ (Stmt.letmut e s) ∅ match x with | (Neut.val a, snd) => pure am: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α, α✝: Type
e: Assg Γ → Assg ∅ → α✝
s: Stmt m Empty Γ (α✝ :: ∅) false false α
this: Stmt.numExts (S s) < Nat.succ (Stmt.numExts s)D (Stmt.letmut e s) ρ = do let x ← Stmt.eval ρ (Stmt.letmut e s) ∅ match x with | (Neut.val a, snd) => pure am: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α, α✝: Type
e: Assg Γ → Assg ∅ → α✝
s: Stmt m Empty Γ (α✝ :: ∅) false false αD (Stmt.letmut e s) ρ = do let x ← Stmt.eval ρ (Stmt.letmut e s) ∅ match x with | (Neut.val a, snd) => pure am: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α, α✝: Type
e: Assg Γ → Assg ∅ → α✝
s: Stmt m Empty Γ (α✝ :: ∅) false false α
this: Stmt.numExts (S s) < Nat.succ (Stmt.numExts s)
ih: ∀ (a : Assg (α✝ :: Γ)), D (S s) a = do let x ← Stmt.eval a (S s) ∅ match x with | (Neut.val a, snd) => pure aD (Stmt.letmut e s) ρ = do let x ← Stmt.eval ρ (Stmt.letmut e s) ∅ match x with | (Neut.val a, snd) => pure a|Goals accomplished! 🐙Stmt.iteStmt.ite: {m : Type → Type ?u.926338} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → Bool) → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c αee: Assg Γ → Assg ∅ → Bools₁s₁: Stmt m Empty Γ ∅ false false αs₂ =>s₂: Stmt m Empty Γ ∅ false false αm: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α: Type
e: Assg Γ → Assg ∅ → Bool
s₁, s₂: Stmt m Empty Γ ∅ false false αD (Stmt.ite e s₁ s₂) ρ = do let x ← Stmt.eval ρ (Stmt.ite e s₁ s₂) ∅ match x with | (Neut.val a, snd) => pure a;m: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α: Type
e: Assg Γ → Assg ∅ → Bool
s₁, s₂: Stmt m Empty Γ ∅ false false α(if e ρ ∅ = true then D s₁ ρ else D s₂ ρ) = do let x ← if e ρ ∅ = true then Stmt.eval ρ s₁ ∅ else Stmt.eval ρ s₂ ∅ match x with | (Neut.val a, snd) => pure am: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α: Type
e: Assg Γ → Assg ∅ → Bool
s₁, s₂: Stmt m Empty Γ ∅ false false α
inlD s₁ ρ = do let x ← Stmt.eval ρ s₁ ∅ match x with | (Neut.val a, snd) => pure am: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α: Type
e: Assg Γ → Assg ∅ → Bool
s₁, s₂: Stmt m Empty Γ ∅ false false αD s₂ ρ = do let x ← Stmt.eval ρ s₂ ∅ match x with | (Neut.val a, snd) => pure am: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α: Type
e: Assg Γ → Assg ∅ → Bool
s₁, s₂: Stmt m Empty Γ ∅ false false α
inlD s₁ ρ = do let x ← Stmt.eval ρ s₁ ∅ match x with | (Neut.val a, snd) => pure am: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α: Type
e: Assg Γ → Assg ∅ → Bool
s₁, s₂: Stmt m Empty Γ ∅ false false αD s₂ ρ = do let x ← Stmt.eval ρ s₂ ∅ match x with | (Neut.val a, snd) => pure a|Goals accomplished! 🐙Stmt.retStmt.ret: {m : Type → Type ?u.926403} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → ω) → Stmt m ω Γ Δ b c αe => nomatche: Assg Γ → Assg ∅ → Emptyee: Assg Γ → Assg ∅ → Emptyρρ: Assg Γ∅ |∅: Assg ∅Stmt.sforStmt.sfor: {m : Type → Type ?u.926500} → {ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → List α) → Stmt m ω (α :: Γ) Δ true true Unit → Stmt m ω Γ Δ b c Unitee: Assg Γ → Assg ∅ → List α✝s =>s: Stmt m Empty (α✝ :: Γ) ∅ true true Unitm: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α✝: Type
e: Assg Γ → Assg ∅ → List α✝
s: Stmt m Empty (α✝ :: Γ) ∅ true true UnitD (Stmt.sfor e s) ρ = do let x ← Stmt.eval ρ (Stmt.sfor e s) ∅ match x with | (Neut.val a, snd) => pure am: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α✝: Type
e: Assg Γ → Assg ∅ → List α✝
s: Stmt m Empty (α✝ :: Γ) ∅ true true Unit
this: Stmt.numExts (C (B s)) < Nat.succ (Stmt.numExts s)D (Stmt.sfor e s) ρ = do let x ← Stmt.eval ρ (Stmt.sfor e s) ∅ match x with | (Neut.val a, snd) => pure am: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α✝: Type
e: Assg Γ → Assg ∅ → List α✝
s: Stmt m Empty (α✝ :: Γ) ∅ true true UnitD (Stmt.sfor e s) ρ = do let x ← Stmt.eval ρ (Stmt.sfor e s) ∅ match x with | (Neut.val a, snd) => pure am: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α✝: Type
e: Assg Γ → Assg ∅ → List α✝
s: Stmt m Empty (α✝ :: Γ) ∅ true true Unit
this: Stmt.numExts (C (B s)) < Nat.succ (Stmt.numExts s)
ih: ∀ (a : Assg (α✝ :: Γ)), D (C (B s)) a = do let x ← Stmt.eval a (C (B s)) ∅ match x with | (Neut.val a, snd) => pure aD (Stmt.sfor e s) ρ = do let x ← Stmt.eval ρ (Stmt.sfor e s) ∅ match x with | (Neut.val a, snd) => pure am: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α✝: Type
e: Assg Γ → Assg ∅ → List α✝
s: Stmt m Empty (α✝ :: Γ) ∅ true true Unit
this: Stmt.numExts (C (B s)) < Nat.succ (Stmt.numExts s)
ih: ∀ (a : Assg (α✝ :: Γ)), D (C (B s)) a = do let x ← Stmt.eval a (C (B s)) ∅ match x with | (Neut.val a, snd) => pure arunCatch (forM (e ρ ∅) fun x => runCatch (D (C (B s)) (x :: ρ))) = do let x ← Stmt.eval.go ρ false false α✝ s ∅ (e ρ ∅) match x with | (Neut.val a, snd) => pure am: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α✝: Type
e: Assg Γ → Assg ∅ → List α✝
s: Stmt m Empty (α✝ :: Γ) ∅ true true Unit
this: Stmt.numExts (C (B s)) < Nat.succ (Stmt.numExts s)
ih: ∀ (a : Assg (α✝ :: Γ)), D (C (B s)) a = do let x ← Stmt.eval a (C (B s)) ∅ match x with | (Neut.val a, snd) => pure a
nilrunCatch (forM [] fun x => runCatch (D (C (B s)) (x :: ρ))) = do let x ← Stmt.eval.go ρ false false α✝ s ∅ [] match x with | (Neut.val a, snd) => pure am: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α✝: Type
e: Assg Γ → Assg ∅ → List α✝
s: Stmt m Empty (α✝ :: Γ) ∅ true true Unit
this: Stmt.numExts (C (B s)) < Nat.succ (Stmt.numExts s)
ih: ∀ (a : Assg (α✝ :: Γ)), D (C (B s)) a = do let x ← Stmt.eval a (C (B s)) ∅ match x with | (Neut.val a, snd) => pure a
head✝: α✝
tail✝: List α✝runCatch (forM (head✝ :: tail✝) fun x => runCatch (D (C (B s)) (x :: ρ))) = do let x ← Stmt.eval.go ρ false false α✝ s ∅ (head✝ :: tail✝) match x with | (Neut.val a, snd) => pure am: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α✝: Type
e: Assg Γ → Assg ∅ → List α✝
s: Stmt m Empty (α✝ :: Γ) ∅ true true Unit
this: Stmt.numExts (C (B s)) < Nat.succ (Stmt.numExts s)
ih: ∀ (a : Assg (α✝ :: Γ)), D (C (B s)) a = do let x ← Stmt.eval a (C (B s)) ∅ match x with | (Neut.val a, snd) => pure a
nilrunCatch (forM [] fun x => runCatch (D (C (B s)) (x :: ρ))) = do let x ← Stmt.eval.go ρ false false α✝ s ∅ [] match x with | (Neut.val a, snd) => pure am: Type → Type
Γ: List Type
ρ: Assg Γ
inst✝¹: Monad m
α✝: Type
e: Assg Γ → Assg ∅ → List α✝
s: Stmt m Empty (α✝ :: Γ) ∅ true true Unit
this: Stmt.numExts (C (B s)) < Nat.succ (Stmt.numExts s)
ih: ∀ (a : Assg (α✝ :: Γ)), D (C (B s)) a = do let x ← Stmt.eval a (C (B s)) ∅ match x with | (Neut.val a, snd) => pure a
head✝: α✝
tail✝: List α✝runCatch (forM (head✝ :: tail✝) fun x => runCatch (D (C (B s)) (x :: ρ))) = do let x ← Stmt.eval.go ρ false false α✝ s ∅ (head✝ :: tail✝) match x with | (Neut.val a, snd) => pure atermination_by _ s => (Goals accomplished! 🐙s.s: Stmt m Empty Γ ∅ false false αnumExts,numExts: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → Stmt m ω Γ Δ b c α → NatsizeOfsizeOf: {α : Type 1} → [self : SizeOf α] → α → Nats) decreasing_bys: Stmt m Empty Γ ∅ false false αGoals accomplished! 🐙
The equivalence proof cited in the paper follows from the invariants of D
and R
.
theoremDo.trans_eq_eval [Do.trans_eq_eval: ∀ {m : Type → Type} {α : Type} [inst : Monad m] [inst_1 : LawfulMonad m] (s : Do m α), trans s = ⟦s⟧MonadMonad: (Type → Type) → Type 1m] [m: Type → TypeLawfulMonadLawfulMonad: (m : Type ?u.1069260 → Type ?u.1069259) → [inst : Monad m] → Propm] : ∀m: Type → Types :s: Do m αDoDo: (Type → Type) → Type → Type 1mm: Type → Typeα,α: TypeDo.transDo.trans: {m : Type → Type} → {α : Type} → [inst : Monad m] → Do m α → m αs = ⟦s: Do m αs⟧ :=s: Do m αm: Type → Type
α: Type
inst✝¹: Monad m∀ (s : Do m α), trans s = ⟦s⟧Goals accomplished! 🐙
Partial Evaluation
We define a new term notation simp [...] in e
that rewrites the term e using the given
simplification theorems.
open Lean in
open Lean.Parser.Tactic in
open Lean.Meta in
open Lean.Elab in
elab "simp" "[" simps: Syntax.TSepArray `Lean.Parser.Tactic.simpLemma ","
simps:simpLemma: ParserDescr
simpLemma,* "]" "in" e: TSyntax `term
e:term : term => do
-- construct goal `⊢ e = ?x` with fresh metavariable `?x`, simplify, solve by reflexivity,
-- and return assigned value of `?x`
let e: Expr
e ← Term.elabTermAndSynthesize: Syntax → Option Expr → TermElabM Expr
Term.elabTermAndSynthesize e: TSyntax `term
e none: {α : Type} → Option α
none
let x: Expr
x ← mkFreshExprMVar: Option Expr → optParam MetavarKind MetavarKind.natural → optParam Name Name.anonymous → MetaM Expr
mkFreshExprMVar (← inferType e): Expr
(← inferType: Expr → MetaM Expr
inferType(← inferType e): Expr
e: Expr
e(← inferType e): Expr
)
let goal: Expr
goal ← mkFreshExprMVar: Option Expr → optParam MetavarKind MetavarKind.natural → optParam Name Name.anonymous → MetaM Expr
mkFreshExprMVar (← mkEq e x): Expr
(← mkEq: Expr → Expr → MetaM Expr
mkEq(← mkEq e x): Expr
e: Expr
e(← mkEq e x): Expr
x: Expr
x(← mkEq e x): Expr
)
-- disable ζ-reduction to preserve `let`s
Term.runTactic: MVarId → Syntax → TermElabM Unit
Term.runTactic goal: Expr
goal.mvarId!: Expr → MVarId
mvarId! (← `(tactic| (simp (config := { zeta := false }) [$simps:simpLemma,*]; rfl))): TSyntax `tactic
(← `(tactic| ((← `(tactic| (simp (config := { zeta := false }) [$simps:simpLemma,*]; rfl))): TSyntax `tactic
simp(← `(tactic| (simp (config := { zeta := false }) [$simps:simpLemma,*]; rfl))): TSyntax `tactic
((← `(tactic| (simp (config := { zeta := false }) [$simps:simpLemma,*]; rfl))): TSyntax `tactic
config(← `(tactic| (simp (config := { zeta := false }) [$simps:simpLemma,*]; rfl))): TSyntax `tactic
:= { zeta := false }) [$simps: Syntax.TSepArray `Lean.Parser.Tactic.simpLemma ","
simps(← `(tactic| (simp (config := { zeta := false }) [$simps:simpLemma,*]; rfl))): TSyntax `tactic
:simpLemma,*]; (← `(tactic| (simp (config := { zeta := false }) [$simps:simpLemma,*]; rfl))): TSyntax `tactic
rfl(← `(tactic| (simp (config := { zeta := false }) [$simps:simpLemma,*]; rfl))): TSyntax `tactic
)))
instantiateMVars: {m : Type → Type} → [inst : Monad m] → [inst : MonadMCtx m] → Expr → m Expr
instantiateMVars x: Expr
x
-- further clean up generated programs
attribute [local simp] Assg.extendBot: {α : Type u_1} → α → {Γ : List (Type u_1)} → Assg Γ → Assg (List.append Γ [α])
Assg.extendBot cast: {α β : Sort u} → α = β → α → β
cast
attribute [-simp] StateT.run'_eq: ∀ {m : Type u_1 → Type u_2} {σ α : Type u_1} [inst : Monad m] (x : StateT σ m α) (s : σ),
StateT.run' x s = (fun a => a.fst) <$> StateT.run x s
StateT.run'_eq
We can now use this new notation to completely erase the translation functions
from an invocation on the example ex2
from For.lean
(manually translated to Stmt
).
/- let mut y := init; for x in xs do' { y ← f y x }; return y -/ defex2' [ex2': {m : Type → Type} → {β α : Type} → [inst : Monad m] → (β → α → m β) → β → List α → m βMonadMonad: (Type ?u.1085514 → Type ?u.1085513) → Type (max (?u.1085514 + 1) ?u.1085513)m] (m: Type → Typef :f: β → α → m ββ →β: Typeα →α: Typemm: Type → Typeβ) (β: Typeinit :init: ββ) (β: Typexs :xs: List αListList: Type → Typeα) :α: Typemm: Type → Typeβ := simp [Do.trans] inβ: TypeDo.trans (Do.trans: {m : Type → Type} → {α : Type} → [inst : Monad m] → Do m α → m αStmt.letmut (fun _ _ =>Stmt.letmut: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → {β : Type} → (Assg Γ → Assg Δ → α) → Stmt m ω Γ (α :: Δ) b c β → Stmt m ω Γ Δ b c βinit) <|init: βStmt.bind (Stmt.bind: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c βStmt.sfor (fun _ _ =>Stmt.sfor: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → List α) → Stmt m ω (α :: Γ) Δ true true Unit → Stmt m ω Γ Δ b c Unitxs) <| -- `y ← f y x` unfolded to `let z ← f y x; y := z` (A4)xs: List αStmt.bind (Stmt.bind: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c βStmt.expr (fun ([Stmt.expr: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c αx]) ([x: αy]) =>y: βff: β → α → m βyy: βx)) (x: αStmt.assg ⟨Stmt.assg: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → (x : Fin (List.length Δ)) → (Assg Γ → Assg Δ → List.get Δ x) → Stmt m ω Γ Δ b c Unit0,0: Natm: Type → Type
β, α: Type
inst✝: Monad m
f: β → α → m β
init: β
xs: List α0 < List.length (β :: ∅)⟩ (fun ([Goals accomplished! 🐙z,z: β]) _ =>z))) <|z: βStmt.ret (fun _ ([Stmt.ret: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → ω) → Stmt m ω Γ Δ b c αy]) =>y: βy))y: β
Compare the output of the two versions - the structure is identical except for unused monadic layers in the formal translation, which would be harder to avoid in this typed approach.
ex2ex2: {m : Type → Type u_1} → {α : Type} → [inst : Monad m] → {β : Type} → (β → α → m β) → β → List α → m βex2'ex2': {m : Type → Type} → {β α : Type} → [inst : Monad m] → (β → α → m β) → β → List α → m β
We can evaluate the generated program like any other Lean program, and prove that both versions are equivalent.
ex2' (m :=ex2': {m : Type → Type} → {β α : Type} → [inst : Monad m] → (β → α → m β) → β → List α → m βId) (funId: Type → Typeaa: Natb =>b: Natpure (pure: {f : Type → Type} → [self : Pure f] → {α : Type} → α → f αa +a: Natb))b: Nat0 [0: Nat1,1: Nat2]2: Natexample [example: ∀ {m : Type → Type} {β α : Type} {init : β} {xs : List α} [inst : Monad m] [inst_1 : LawfulMonad m] (f : β → α → m β), ex2' f init xs = ex2 f init xsMonadMonad: (Type → Type) → Type 1m] [m: Type → TypeLawfulMonadLawfulMonad: (m : Type → Type) → [inst : Monad m] → Propm] (m: Type → Typef :f: β → α → m ββ →β: Typeα →α: Typemm: Type → Typeβ) :β: Typeex2'ex2': {m : Type → Type} → {β α : Type} → [inst : Monad m] → (β → α → m β) → β → List α → m βff: β → α → m βinitinit: βxs =xs: List αex2ex2: {m : Type → Type} → {α : Type} → [inst : Monad m] → {β : Type} → (β → α → m β) → β → List α → m βff: β → α → m βinitinit: βxs :=xs: List αm: Type → Type
β, α: Type
init: β
xs: List α
inst✝¹: Monad m
f: β → α → m βex2' f init xs = ex2 f init xsm: Type → Type
β, α: Type
init: β
xs: List α
inst✝¹: Monad m
f: β → α → m βex2' f init xs = ex2 f init xsm: Type → Type
β, α: Type
init: β
xs: List α
inst✝¹: Monad m
f: β → α → m βex2' f init xs = ExceptCpsT.runCatch (let y := init; StateT.run' (do forM xs fun x => do let y ← get let y ← StateT.lift (ExceptCpsT.lift (f y x)) let _ ← get set y let y ← get StateT.lift (throw y)) y)m: Type → Type
β, α: Type
init: β
xs: List α
inst✝¹: Monad m
f: β → α → m βrunCatch (let x := init; StateT.run' (do runCatch (forM xs fun x => runCatch do let x_1 ← ExceptT.lift (ExceptT.lift get) let x ← ExceptT.lift (ExceptT.lift (StateT.lift (ExceptT.lift (f x_1 x)))) let _ ← ExceptT.lift (ExceptT.lift get) ExceptT.lift (ExceptT.lift (set x))) let x ← get StateT.lift (throw x)) x) = ExceptCpsT.runCatch (let y := init; StateT.run' (do forM xs fun x => do let y ← get let y ← StateT.lift (ExceptCpsT.lift (f y x)) let _ ← get set y let y ← get StateT.lift (throw y)) y);m: Type → Type
β, α: Type
init: β
xs: List α
inst✝¹: Monad m
f: β → α → m βrunCatch (let x := init; StateT.run' (do runCatch (forM xs fun x => runCatch do let x_1 ← ExceptT.lift (ExceptT.lift get) let x ← ExceptT.lift (ExceptT.lift (StateT.lift (ExceptT.lift (f x_1 x)))) let _ ← ExceptT.lift (ExceptT.lift get) ExceptT.lift (ExceptT.lift (set x))) let x ← get StateT.lift (throw x)) x) = ExceptCpsT.runCatch (let y := init; StateT.run' (do forM xs fun x => do let y ← get let y ← StateT.lift (ExceptCpsT.lift (f y x)) let _ ← get set y let y ← get StateT.lift (throw y)) y);m: Type → Type
β, α: Type
init: β
xs: List α
inst✝¹: Monad m
f: β → α → m β(do let x ← ExceptT.run (let x := init; StateT.run' (do do let x ← ExceptT.run (forM xs fun x => do let x ← ExceptT.run do let x_1 ← ExceptT.lift (ExceptT.lift get) let x ← ExceptT.lift (ExceptT.lift (StateT.lift (ExceptT.lift (f x_1 x)))) let _ ← ExceptT.lift (ExceptT.lift get) ExceptT.lift (ExceptT.lift (set x)) match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e let x ← get StateT.lift (throw x)) x) match x with | Except.ok x => pure x | Except.error e => pure e) = ExceptCpsT.runCatch (let y := init; StateT.run' (do forM xs fun x => do let y ← get let y ← StateT.lift (ExceptCpsT.lift (f y x)) let _ ← get set y let y ← get StateT.lift (throw y)) y)m: Type → Type
β, α: Type
inst✝¹: Monad m
f: β → α → m β
init: β
nil(do let x ← ExceptT.run (let x := init; StateT.run' (do do let x ← ExceptT.run (forM [] fun x => do let x ← ExceptT.run do let x_1 ← ExceptT.lift (ExceptT.lift get) let x ← ExceptT.lift (ExceptT.lift (StateT.lift (ExceptT.lift (f x_1 x)))) let _ ← ExceptT.lift (ExceptT.lift get) ExceptT.lift (ExceptT.lift (set x)) match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e let x ← get StateT.lift (throw x)) x) match x with | Except.ok x => pure x | Except.error e => pure e) = ExceptCpsT.runCatch (let y := init; StateT.run' (do forM [] fun x => do let y ← get let y ← StateT.lift (ExceptCpsT.lift (f y x)) let _ ← get set y let y ← get StateT.lift (throw y)) y)m: Type → Type
β, α: Type
inst✝¹: Monad m
f: β → α → m β
head✝: α
tail✝: List α
init: β(do let x ← ExceptT.run (let x := init; StateT.run' (do do let x ← ExceptT.run (forM (head✝ :: tail✝) fun x => do let x ← ExceptT.run do let x_1 ← ExceptT.lift (ExceptT.lift get) let x ← ExceptT.lift (ExceptT.lift (StateT.lift (ExceptT.lift (f x_1 x)))) let _ ← ExceptT.lift (ExceptT.lift get) ExceptT.lift (ExceptT.lift (set x)) match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e let x ← get StateT.lift (throw x)) x) match x with | Except.ok x => pure x | Except.error e => pure e) = ExceptCpsT.runCatch (let y := init; StateT.run' (do forM (head✝ :: tail✝) fun x => do let y ← get let y ← StateT.lift (ExceptCpsT.lift (f y x)) let _ ← get set y let y ← get StateT.lift (throw y)) y)m: Type → Type
β, α: Type
inst✝¹: Monad m
f: β → α → m β
init: β
nil(do let x ← ExceptT.run (let x := init; StateT.run' (do do let x ← ExceptT.run (forM [] fun x => do let x ← ExceptT.run do let x_1 ← ExceptT.lift (ExceptT.lift get) let x ← ExceptT.lift (ExceptT.lift (StateT.lift (ExceptT.lift (f x_1 x)))) let _ ← ExceptT.lift (ExceptT.lift get) ExceptT.lift (ExceptT.lift (set x)) match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e let x ← get StateT.lift (throw x)) x) match x with | Except.ok x => pure x | Except.error e => pure e) = ExceptCpsT.runCatch (let y := init; StateT.run' (do forM [] fun x => do let y ← get let y ← StateT.lift (ExceptCpsT.lift (f y x)) let _ ← get set y let y ← get StateT.lift (throw y)) y)m: Type → Type
β, α: Type
inst✝¹: Monad m
f: β → α → m β
head✝: α
tail✝: List α
init: β(do let x ← ExceptT.run (let x := init; StateT.run' (do do let x ← ExceptT.run (forM (head✝ :: tail✝) fun x => do let x ← ExceptT.run do let x_1 ← ExceptT.lift (ExceptT.lift get) let x ← ExceptT.lift (ExceptT.lift (StateT.lift (ExceptT.lift (f x_1 x)))) let _ ← ExceptT.lift (ExceptT.lift get) ExceptT.lift (ExceptT.lift (set x)) match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e let x ← get StateT.lift (throw x)) x) match x with | Except.ok x => pure x | Except.error e => pure e) = ExceptCpsT.runCatch (let y := init; StateT.run' (do forM (head✝ :: tail✝) fun x => do let y ← get let y ← StateT.lift (ExceptCpsT.lift (f y x)) let _ ← get set y let y ← get StateT.lift (throw y)) y)Goals accomplished! 🐙
For one more example, consider ex3
from For.lean
.
/- for xs in xss do' { for x in xs do' { let b ← p x; if b then { return some x } } }; pure none -/ defex3' [ex3': {m : Type → Type} → {α : Type} → [inst : Monad m] → (α → m Bool) → List (List α) → m (Option α)MonadMonad: (Type → Type) → Type 1m] (m: Type → Typep :p: α → m Boolα →α: Typemm: Type → TypeBool) (Bool: Typexss :xss: List (List α)List (List: Type → TypeListList: Type → Typeα)) :α: Typem (m: Type → TypeOptionOption: Type → Typeα) := simp [Do.trans] inα: TypeDo.trans (Do.trans: {m : Type → Type} → {α : Type} → [inst : Monad m] → Do m α → m αStmt.bind (Stmt.bind: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c βStmt.sfor (fun _ _ =>Stmt.sfor: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → List α) → Stmt m ω (α :: Γ) Δ true true Unit → Stmt m ω Γ Δ b c Unitxss) <|xss: List (List α)Stmt.sfor (fun ([Stmt.sfor: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → List α) → Stmt m ω (α :: Γ) Δ true true Unit → Stmt m ω Γ Δ b c Unitxs]) _ =>xs: List αxs) <|xs: List αStmt.bind (Stmt.bind: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α β : Type} → Stmt m ω Γ Δ b c α → Stmt m ω (α :: Γ) Δ b c β → Stmt m ω Γ Δ b c βStmt.expr (fun ([Stmt.expr: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c αx,x: α]) _ =>pp: α → m Boolx)) (x: αStmt.ite (fun ([Stmt.ite: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → Bool) → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c α → Stmt m ω Γ Δ b c αb,b: Bool,]) _ =>b) (b: BoolStmt.ret (fun ([Stmt.ret: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {b c : Bool} → {α : Type} → (Assg Γ → Assg Δ → ω) → Stmt m ω Γ Δ b c α,x,x: α]) _ =>somesome: {α : Type} → α → Option αx)) (x: αStmt.expr (fun _ _ =>Stmt.expr: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c αpurepure: {f : Type → Type} → [self : Pure f] → {α : Type} → α → f α())))) ((): UnitStmt.expr (fun _ _ =>Stmt.expr: {m : Type → Type} → {ω : Type} → {Γ Δ : List Type} → {α : Type} → {b c : Bool} → (Assg Γ → Assg Δ → m α) → Stmt m ω Γ Δ b c αpurepure: {f : Type → Type} → [self : Pure f] → {α : Type} → α → f αnone)))none: {α : Type} → Option αex3ex3: {m : Type → Type u_1} → {α : Type} → [inst : Monad m] → (α → m Bool) → List (List α) → m (Option α)ex3'ex3': {m : Type → Type} → {α : Type} → [inst : Monad m] → (α → m Bool) → List (List α) → m (Option α)ex3' (m :=ex3': {m : Type → Type} → {α : Type} → [inst : Monad m] → (α → m Bool) → List (List α) → m (Option α)Id) (funId: Type → Typen =>n: Natn %n: Nat2 ==2: Nat0) [[0: Nat1,1: Nat3], [3: Nat2,2: Nat4]]4: Natexample [example: ∀ {m : Type → Type} {α : Type} [inst : Monad m] [inst_1 : LawfulMonad m] (p : α → m Bool) (xss : List (List α)), ex3' p xss = ex3 p xssMonadMonad: (Type → Type) → Type 1m] [m: Type → TypeLawfulMonadLawfulMonad: (m : Type ?u.1130706 → Type ?u.1130705) → [inst : Monad m] → Propm] (m: Type → Typep :p: α → m Boolα →α: Typemm: Type → TypeBool) (Bool: Typexss :xss: List (List α)List (List: Type → TypeListList: Type → Typeα)) :α: Typeex3'ex3': {m : Type → Type} → {α : Type} → [inst : Monad m] → (α → m Bool) → List (List α) → m (Option α)pp: α → m Boolxss =xss: List (List α)ex3ex3: {m : Type → Type} → {α : Type} → [inst : Monad m] → (α → m Bool) → List (List α) → m (Option α)pp: α → m Boolxss :=xss: List (List α)m: Type → Type
α: Type
inst✝¹: Monad m
p: α → m Bool
xss: List (List α)ex3' p xss = ex3 p xssm: Type → Type
α: Type
inst✝¹: Monad m
p: α → m Bool
xss: List (List α)ex3' p xss = ex3 p xssm: Type → Type
α: Type
inst✝¹: Monad m
p: α → m Bool
xss: List (List α)ex3' p xss = ExceptCpsT.runCatch do forM xss fun xs => forM xs fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) ExceptCpsT.lift (pure none)m: Type → Type
α: Type
inst✝¹: Monad m
p: α → m Bool
xss: List (List α)(runCatch do runCatch (forM xss fun x => runCatch (runCatch (forM x fun x => runCatch do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x))))) if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (pure ())))))))) ExceptT.lift (pure none)) = ExceptCpsT.runCatch do forM xss fun xs => forM xs fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) ExceptCpsT.lift (pure none)m: Type → Type
α: Type
inst✝¹: Monad m
p: α → m Bool
xss: List (List α)(runCatch do runCatch (forM xss fun x => runCatch (runCatch (forM x fun x => runCatch do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x))))) if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (pure ())))))))) ExceptT.lift (pure none)) = ExceptCpsT.runCatch do forM xss fun xs => forM xs fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) ExceptCpsT.lift (pure none)m: Type → Type
α: Type
inst✝¹: Monad m
p: α → m Bool
xss: List (List α)(do let x ← ExceptT.run do do let x ← ExceptT.run (forM xss fun x => do let x ← ExceptT.run do let x ← ExceptT.run (forM x fun x => do let x ← ExceptT.run do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x))))) if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (pure ()))))) match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e ExceptT.lift (pure none) match x with | Except.ok x => pure x | Except.error e => pure e) = ExceptCpsT.runCatch do forM xss fun xs => forM xs fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) ExceptCpsT.lift (pure none)m: Type → Type
α: Type
inst✝¹: Monad m
p: α → m Bool
xss: List (List α)(do let x ← ExceptT.run do do let x ← ExceptT.run (forM xss fun x => do let x ← ExceptT.run do let x ← ExceptT.run (forM x fun x => do let x ← ExceptT.run do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x))))) if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (pure ()))))) match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e ExceptT.lift (pure none) match x with | Except.ok x => pure x | Except.error e => pure e) = ExceptCpsT.runCatch do forM xss fun xs => forM xs fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) ExceptCpsT.lift (pure none)m: Type → Type
α: Type
inst✝¹: Monad m
p: α → m Bool
nil(do let x ← ExceptT.run do do let x ← ExceptT.run (forM [] fun x => do let x ← ExceptT.run do let x ← ExceptT.run (forM x fun x => do let x ← ExceptT.run do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x))))) if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (pure ()))))) match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e ExceptT.lift (pure none) match x with | Except.ok x => pure x | Except.error e => pure e) = ExceptCpsT.runCatch do forM [] fun xs => forM xs fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) ExceptCpsT.lift (pure none)Goals accomplished! 🐙m: Type → Type
α: Type
inst✝¹: Monad m
p: α → m Bool
xs: List α
xss: List (List α)
ih: (do let x ← ExceptT.run do do let x ← ExceptT.run (forM xss fun x => do let x ← ExceptT.run do let x ← ExceptT.run (forM x fun x => do let x ← ExceptT.run do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x))))) if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (pure ()))))) match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e ExceptT.lift (pure none) match x with | Except.ok x => pure x | Except.error e => pure e) = ExceptCpsT.runCatch do forM xss fun xs => forM xs fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) ExceptCpsT.lift (pure none)
cons(do let x ← ExceptT.run do do let x ← ExceptT.run (forM (xs :: xss) fun x => do let x ← ExceptT.run do let x ← ExceptT.run (forM x fun x => do let x ← ExceptT.run do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x))))) if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (pure ()))))) match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e ExceptT.lift (pure none) match x with | Except.ok x => pure x | Except.error e => pure e) = ExceptCpsT.runCatch do forM (xs :: xss) fun xs => forM xs fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) ExceptCpsT.lift (pure none)m: Type → Type
α: Type
inst✝¹: Monad m
p: α → m Bool
xs: List α
xss: List (List α)
ih: (do let x ← ExceptT.run do do let x ← ExceptT.run (forM xss fun x => do let x ← ExceptT.run do let x ← ExceptT.run (forM x fun x => do let x ← ExceptT.run do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x))))) if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (pure ()))))) match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e ExceptT.lift (pure none) match x with | Except.ok x => pure x | Except.error e => pure e) = ExceptCpsT.runCatch do forM xss fun xs => forM xs fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) ExceptCpsT.lift (pure none)
cons(do let x ← ExceptT.run (ExceptT.run (ExceptT.run (ExceptT.run (forM xs fun x => do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x)))) let x ← ExceptT.run (if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else pure ()) match x with | Except.ok x => pure x | Except.error x => pure x)))) let x ← match x with | Except.ok x => do let x ← ExceptT.run (match x with | Except.ok x => do let x ← ExceptT.run (match x with | Except.ok x => ExceptT.run (match x with | Except.ok x => pure x | Except.error x => pure x) | Except.error e => pure (Except.error e)) match x with | Except.ok x => do let x ← ExceptT.run (match x with | Except.ok x => pure x | Except.error x => pure x) match x with | Except.ok x => ExceptT.run (forM xss fun x => do let x ← ExceptT.run (ExceptT.run (forM x fun x => do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x)))) let x ← ExceptT.run (if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else pure ()) match x with | Except.ok x => pure x | Except.error x => pure x)) let x ← match x with | Except.ok x => ExceptT.run (match x with | Except.ok x => pure x | Except.error x => pure x) | Except.error e => pure (Except.error e) match x with | Except.ok x => pure x | Except.error x => pure x) | Except.error e => pure (Except.error e) | Except.error e => pure (Except.error e) | Except.error e => pure (Except.error e)) match x with | Except.ok x => do let x ← ExceptT.run (match x with | Except.ok x => pure x | Except.error x => pure x) match x with | Except.ok x => pure (Except.ok none) | Except.error e => pure (Except.error e) | Except.error e => pure (Except.error e) | Except.error e => pure (Except.error e) match x with | Except.ok x => pure x | Except.error x => pure x) = ExceptCpsT.runCatch do forM xs fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) forM xss fun xs => forM xs fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) ExceptCpsT.lift (pure none)m: Type → Type
α: Type
inst✝¹: Monad m
p: α → m Bool
xss: List (List α)
ih: (do let x ← ExceptT.run do do let x ← ExceptT.run (forM xss fun x => do let x ← ExceptT.run do let x ← ExceptT.run (forM x fun x => do let x ← ExceptT.run do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x))))) if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (pure ()))))) match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e ExceptT.lift (pure none) match x with | Except.ok x => pure x | Except.error e => pure e) = ExceptCpsT.runCatch do forM xss fun xs => forM xs fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) ExceptCpsT.lift (pure none)
cons.nil(do let x ← ExceptT.run (ExceptT.run (ExceptT.run (ExceptT.run (forM [] fun x => do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x)))) let x ← ExceptT.run (if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else pure ()) match x with | Except.ok x => pure x | Except.error x => pure x)))) let x ← match x with | Except.ok x => do let x ← ExceptT.run (match x with | Except.ok x => do let x ← ExceptT.run (match x with | Except.ok x => ExceptT.run (match x with | Except.ok x => pure x | Except.error x => pure x) | Except.error e => pure (Except.error e)) match x with | Except.ok x => do let x ← ExceptT.run (match x with | Except.ok x => pure x | Except.error x => pure x) match x with | Except.ok x => ExceptT.run (forM xss fun x => do let x ← ExceptT.run (ExceptT.run (forM x fun x => do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x)))) let x ← ExceptT.run (if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else pure ()) match x with | Except.ok x => pure x | Except.error x => pure x)) let x ← match x with | Except.ok x => ExceptT.run (match x with | Except.ok x => pure x | Except.error x => pure x) | Except.error e => pure (Except.error e) match x with | Except.ok x => pure x | Except.error x => pure x) | Except.error e => pure (Except.error e) | Except.error e => pure (Except.error e) | Except.error e => pure (Except.error e)) match x with | Except.ok x => do let x ← ExceptT.run (match x with | Except.ok x => pure x | Except.error x => pure x) match x with | Except.ok x => pure (Except.ok none) | Except.error e => pure (Except.error e) | Except.error e => pure (Except.error e) | Except.error e => pure (Except.error e) match x with | Except.ok x => pure x | Except.error x => pure x) = ExceptCpsT.runCatch do forM [] fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) forM xss fun xs => forM xs fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) ExceptCpsT.lift (pure none)m: Type → Type
α: Type
inst✝¹: Monad m
p: α → m Bool
xss: List (List α)
ih: (do let x ← ExceptT.run do do let x ← ExceptT.run (forM xss fun x => do let x ← ExceptT.run do let x ← ExceptT.run (forM x fun x => do let x ← ExceptT.run do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x))))) if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (pure ()))))) match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e ExceptT.lift (pure none) match x with | Except.ok x => pure x | Except.error e => pure e) = ExceptCpsT.runCatch do forM xss fun xs => forM xs fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) ExceptCpsT.lift (pure none)
head✝: α
tail✝: List α(do let x ← ExceptT.run (ExceptT.run (ExceptT.run (ExceptT.run (forM (head✝ :: tail✝) fun x => do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x)))) let x ← ExceptT.run (if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else pure ()) match x with | Except.ok x => pure x | Except.error x => pure x)))) let x ← match x with | Except.ok x => do let x ← ExceptT.run (match x with | Except.ok x => do let x ← ExceptT.run (match x with | Except.ok x => ExceptT.run (match x with | Except.ok x => pure x | Except.error x => pure x) | Except.error e => pure (Except.error e)) match x with | Except.ok x => do let x ← ExceptT.run (match x with | Except.ok x => pure x | Except.error x => pure x) match x with | Except.ok x => ExceptT.run (forM xss fun x => do let x ← ExceptT.run (ExceptT.run (forM x fun x => do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x)))) let x ← ExceptT.run (if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else pure ()) match x with | Except.ok x => pure x | Except.error x => pure x)) let x ← match x with | Except.ok x => ExceptT.run (match x with | Except.ok x => pure x | Except.error x => pure x) | Except.error e => pure (Except.error e) match x with | Except.ok x => pure x | Except.error x => pure x) | Except.error e => pure (Except.error e) | Except.error e => pure (Except.error e) | Except.error e => pure (Except.error e)) match x with | Except.ok x => do let x ← ExceptT.run (match x with | Except.ok x => pure x | Except.error x => pure x) match x with | Except.ok x => pure (Except.ok none) | Except.error e => pure (Except.error e) | Except.error e => pure (Except.error e) | Except.error e => pure (Except.error e) match x with | Except.ok x => pure x | Except.error x => pure x) = ExceptCpsT.runCatch do forM (head✝ :: tail✝) fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) forM xss fun xs => forM xs fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) ExceptCpsT.lift (pure none)m: Type → Type
α: Type
inst✝¹: Monad m
p: α → m Bool
xss: List (List α)
ih: (do let x ← ExceptT.run do do let x ← ExceptT.run (forM xss fun x => do let x ← ExceptT.run do let x ← ExceptT.run (forM x fun x => do let x ← ExceptT.run do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x))))) if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (pure ()))))) match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e ExceptT.lift (pure none) match x with | Except.ok x => pure x | Except.error e => pure e) = ExceptCpsT.runCatch do forM xss fun xs => forM xs fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) ExceptCpsT.lift (pure none)
cons.nil(do let x ← ExceptT.run (ExceptT.run (ExceptT.run (ExceptT.run (forM [] fun x => do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x)))) let x ← ExceptT.run (if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else pure ()) match x with | Except.ok x => pure x | Except.error x => pure x)))) let x ← match x with | Except.ok x => do let x ← ExceptT.run (match x with | Except.ok x => do let x ← ExceptT.run (match x with | Except.ok x => ExceptT.run (match x with | Except.ok x => pure x | Except.error x => pure x) | Except.error e => pure (Except.error e)) match x with | Except.ok x => do let x ← ExceptT.run (match x with | Except.ok x => pure x | Except.error x => pure x) match x with | Except.ok x => ExceptT.run (forM xss fun x => do let x ← ExceptT.run (ExceptT.run (forM x fun x => do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x)))) let x ← ExceptT.run (if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else pure ()) match x with | Except.ok x => pure x | Except.error x => pure x)) let x ← match x with | Except.ok x => ExceptT.run (match x with | Except.ok x => pure x | Except.error x => pure x) | Except.error e => pure (Except.error e) match x with | Except.ok x => pure x | Except.error x => pure x) | Except.error e => pure (Except.error e) | Except.error e => pure (Except.error e) | Except.error e => pure (Except.error e)) match x with | Except.ok x => do let x ← ExceptT.run (match x with | Except.ok x => pure x | Except.error x => pure x) match x with | Except.ok x => pure (Except.ok none) | Except.error e => pure (Except.error e) | Except.error e => pure (Except.error e) | Except.error e => pure (Except.error e) match x with | Except.ok x => pure x | Except.error x => pure x) = ExceptCpsT.runCatch do forM [] fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) forM xss fun xs => forM xs fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) ExceptCpsT.lift (pure none)m: Type → Type
α: Type
inst✝¹: Monad m
p: α → m Bool
xss: List (List α)
ih: (do let x ← ExceptT.run do do let x ← ExceptT.run (forM xss fun x => do let x ← ExceptT.run do let x ← ExceptT.run (forM x fun x => do let x ← ExceptT.run do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x))))) if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (pure ()))))) match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e match x with | Except.ok x => pure x | Except.error e => pure e) match x with | Except.ok x => pure x | Except.error e => pure e ExceptT.lift (pure none) match x with | Except.ok x => pure x | Except.error e => pure e) = ExceptCpsT.runCatch do forM xss fun xs => forM xs fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) ExceptCpsT.lift (pure none)
head✝: α
tail✝: List α(do let x ← ExceptT.run (ExceptT.run (ExceptT.run (ExceptT.run (forM (head✝ :: tail✝) fun x => do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x)))) let x ← ExceptT.run (if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else pure ()) match x with | Except.ok x => pure x | Except.error x => pure x)))) let x ← match x with | Except.ok x => do let x ← ExceptT.run (match x with | Except.ok x => do let x ← ExceptT.run (match x with | Except.ok x => ExceptT.run (match x with | Except.ok x => pure x | Except.error x => pure x) | Except.error e => pure (Except.error e)) match x with | Except.ok x => do let x ← ExceptT.run (match x with | Except.ok x => pure x | Except.error x => pure x) match x with | Except.ok x => ExceptT.run (forM xss fun x => do let x ← ExceptT.run (ExceptT.run (forM x fun x => do let x_1 ← ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (p x)))) let x ← ExceptT.run (if x_1 = true then ExceptT.lift (ExceptT.lift (ExceptT.lift (ExceptT.lift (throw (some x))))) else pure ()) match x with | Except.ok x => pure x | Except.error x => pure x)) let x ← match x with | Except.ok x => ExceptT.run (match x with | Except.ok x => pure x | Except.error x => pure x) | Except.error e => pure (Except.error e) match x with | Except.ok x => pure x | Except.error x => pure x) | Except.error e => pure (Except.error e) | Except.error e => pure (Except.error e) | Except.error e => pure (Except.error e)) match x with | Except.ok x => do let x ← ExceptT.run (match x with | Except.ok x => pure x | Except.error x => pure x) match x with | Except.ok x => pure (Except.ok none) | Except.error e => pure (Except.error e) | Except.error e => pure (Except.error e) | Except.error e => pure (Except.error e) match x with | Except.ok x => pure x | Except.error x => pure x) = ExceptCpsT.runCatch do forM (head✝ :: tail✝) fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) forM xss fun xs => forM xs fun x => do let b ← ExceptCpsT.lift (p x) if b = true then throw (some x) else ExceptCpsT.lift (pure ()) ExceptCpsT.lift (pure none)Goals accomplished! 🐙
While it would be possible to override our do'
notation such that its named syntax
is first translated to nameless Stmt
constructors and then applied to simp [Do.trans] in
,
for demonstration purposes we decided to encode these examples manually. In practice, the
macro implementation remains more desirable as mentioned in the paper.