PPDP 2020, September 8–10
A Computational Understanding
- f Classical (Co)Recursion
Paul Downen and Zena M. Ariola
A Computational Understanding of Classical (Co)Recursion P a ul - - PowerPoint PPT Presentation
A Computational Understanding of Classical (Co)Recursion P a ul Downen a nd Zen a M. Ariol a PPDP 2020, September 8 10 Topic Topic Both programs and proofs with loops Topic Both programs and proofs with loops (Co)Recursion and
PPDP 2020, September 8–10
Paul Downen and Zena M. Ariola
Topic
Topic
Topic
Topic
Topic
Methodology
Methodology
Methodology
Methodology
Methodology
Methodology
Recursion on Natural Numbers
In System T
Recursion on Natural Numbers
λ Nat = Zero ∣ Succ Nat
In System T
Recursion on Natural Numbers
λ Nat = Zero ∣ Succ Nat recA
Nat : Nat → A → (Nat → A → A) → A
In System T
Recursion on Natural Numbers
λ Nat = Zero ∣ Succ Nat recA
Nat : Nat → A → (Nat → A → A) → A
rec M as {Zero → N ∣ Succ x → y . P}
where M, x : Nat; N and P, y : A
In System T
Recursion on Natural Numbers
λ Nat = Zero ∣ Succ Nat recA
Nat : Nat → A → (Nat → A → A) → A
rec M as {Zero → N ∣ Succ x → y . P}
where M, x : Nat; N and P, y : A
case M of Zero → N Succ x → P := rec M of Zero → M Succ x → _ . P
In System T
Recursion on Natural Numbers
λ Nat = Zero ∣ Succ Nat recA
Nat : Nat → A → (Nat → A → A) → A
rec M as {Zero → N ∣ Succ x → y . P}
where M, x : Nat; N and P, y : A
case M of Zero → N Succ x → P := rec M of Zero → M Succ x → _ . P iter M as Zero → N Succ → y . P := rec M as Zero → N Succ _ → y . P
In System T
Examples of Recursion
In System T
Examples of Recursion
plus Zero y = y plus (Succ x′ ) y = Succ (plus x′ y)
In System T
Examples of Recursion
plus Zero y = y plus (Succ x′ ) y = Succ (plus x′ y)
plus = λx . λy . iter x as Zero → y Succ → z . Succ z
In System T
Examples of Recursion
plus Zero y = y plus (Succ x′ ) y = Succ (plus x′ y)
plus = λx . λy . iter x as Zero → y Succ → z . Succ z
In System T
pred Zero = Zero pred (Succ x′ ) = x′
Examples of Recursion
plus Zero y = y plus (Succ x′ ) y = Succ (plus x′ y)
plus = λx . λy . iter x as Zero → y Succ → z . Succ z
In System T
pred Zero = Zero pred (Succ x′ ) = x′ pred = λx . case x of Zero → Zero Succ x′ → x′
Examples of Recursion
plus Zero y = y plus (Succ x′ ) y = Succ (plus x′ y)
plus = λx . λy . iter x as Zero → y Succ → z . Succ z
In System T
pred Zero = Zero pred (Succ x′ ) = x′ pred = λx . case x of Zero → Zero Succ x′ → x′
minus x Zero = x minus x (Succ y′ ) = pred (minus x y′ )
Examples of Recursion
plus Zero y = y plus (Succ x′ ) y = Succ (plus x′ y)
plus = λx . λy . iter x as Zero → y Succ → z . Succ z
In System T
pred Zero = Zero pred (Succ x′ ) = x′ pred = λx . case x of Zero → Zero Succ x′ → x′
minus x Zero = x minus x (Succ y′ ) = pred (minus x y′ )
minus = λx . λy . iter y as Zero → x Succ → z . pred z
Recursion vs Iteration
Expressiveness vs Cost
Recursion vs Iteration
iter M as Zero → N Succ → y . P := rec M as Zero → N Succ _ → y . P
Expressiveness vs Cost
Recursion vs Iteration
iter M as Zero → N Succ → y . P := rec M as Zero → N Succ _ → y . P rec M as Zero → N Succ x → y . P := snd(iter M as Zero → (Zero, N) Succ → (x, y) . (Succ x, P))
Expressiveness vs Cost
Recursion vs Iteration
iter M as Zero → N Succ → y . P := rec M as Zero → N Succ _ → y . P rec M as Zero → N Succ x → y . P := snd(iter M as Zero → (Zero, N) Succ → (x, y) . (Succ x, P))
to time
pred (Succn Zero) O(1) O(n)
Expressiveness vs Cost
Recursion vs Iteration
iter M as Zero → N Succ → y . P := rec M as Zero → N Succ _ → y . P rec M as Zero → N Succ x → y . P := snd(iter M as Zero → (Zero, N) Succ → (x, y) . (Succ x, P))
to time
pred (Succn Zero) O(1) O(n)
to
minus (Succn Zero) (Succm Zero) O(n) O(n2 + nm)
Expressiveness vs Cost
Recursion vs Iteration
iter M as Zero → N Succ → y . P := rec M as Zero → N Succ _ → y . P rec M as Zero → N Succ x → y . P := snd(iter M as Zero → (Zero, N) Succ → (x, y) . (Succ x, P))
to time
pred (Succn Zero) O(1) O(n)
to
minus (Succn Zero) (Succm Zero) O(n) O(n2 + nm)
has the same performance penalty as encoding in CBV
rec
Expressiveness vs Cost
Recursion vs Iteration
iter M as Zero → N Succ → y . P := rec M as Zero → N Succ _ → y . P rec M as Zero → N Succ x → y . P := snd(iter M as Zero → (Zero, N) Succ → (x, y) . (Succ x, P))
to time
pred (Succn Zero) O(1) O(n)
to
minus (Succn Zero) (Succm Zero) O(n) O(n2 + nm)
has the same performance penalty as encoding in CBV
rec
Expressiveness vs Cost
Recursion in an Abstract Machine
Building the Recursive Continuation
Recursion in an Abstract Machine
Building the Recursive Continuation
⟨M| |E⟩
Recursion in an Abstract Machine
Building the Recursive Continuation
⟨M N| |E⟩ ↦ ⟨M| |N ⋅ E⟩ ⟨λx . M| |N ⋅ E⟩ ↦ ⟨M[N/x]| |E⟩ ⟨M| |E⟩
Recursion in an Abstract Machine
Building the Recursive Continuation
⟨M N| |E⟩ ↦ ⟨M| |N ⋅ E⟩ ⟨λx . M| |N ⋅ E⟩ ↦ ⟨M[N/x]| |E⟩
ralt := { Zero → N ∣ Succ x → y . P }
⟨M| |E⟩
Recursion in an Abstract Machine
Building the Recursive Continuation
⟨M N| |E⟩ ↦ ⟨M| |N ⋅ E⟩ ⟨λx . M| |N ⋅ E⟩ ↦ ⟨M[N/x]| |E⟩
⟨rec M as ralt| |E⟩ ↦ ⟨M| |rec ralt with E⟩ ralt := { Zero → N ∣ Succ x → y . P }
⟨M| |E⟩
Recursion in an Abstract Machine
Building the Recursive Continuation
⟨M N| |E⟩ ↦ ⟨M| |N ⋅ E⟩ ⟨λx . M| |N ⋅ E⟩ ↦ ⟨M[N/x]| |E⟩
⟨rec M as ralt| |E⟩ ↦ ⟨M| |rec ralt with E⟩ ⟨Zero| |rec ralt with E⟩ ↦ ⟨N| |E⟩ ralt := { Zero → N ∣ Succ x → y . P }
⟨M| |E⟩
Recursion in an Abstract Machine
Building the Recursive Continuation
⟨M N| |E⟩ ↦ ⟨M| |N ⋅ E⟩ ⟨λx . M| |N ⋅ E⟩ ↦ ⟨M[N/x]| |E⟩
⟨rec M as ralt| |E⟩ ↦ ⟨M| |rec ralt with E⟩ ⟨Zero| |rec ralt with E⟩ ↦ ⟨N| |E⟩ ⟨Succ M| |rec ralt with E⟩ ↦ ⟨P[M/x, rec M as ralt/y]| |E⟩ ralt := { Zero → N ∣ Succ x → y . P }
⟨M| |E⟩
What’s the Dual of Natural Numbers?
Nat⊥
What’s the Dual of Natural Numbers?
Zero : 1 → Nat Run : Nat⊥ → ⊥
Nat⊥
What’s the Dual of Natural Numbers?
Zero : 1 → Nat Run : Nat⊥ → ⊥
Succ : Nat → Nat Tail : Nat⊥ → Nat⊥
Nat⊥
What’s the Dual of Natural Numbers?
Zero : 1 → Nat Run : Nat⊥ → ⊥
Succ : Nat → Nat Tail : Nat⊥ → Nat⊥
Nat⊥
Nat⊥
What’s the Dual of Natural Numbers?
Zero : 1 → Nat Run : Nat⊥ → ⊥
Succ : Nat → Nat Tail : Nat⊥ → Nat⊥
Nat⊥
Nat⊥
What’s the Dual of Natural Numbers?
Zero : 1 → Nat Run : Nat⊥ → ⊥
Succ : Nat → Nat Tail : Nat⊥ → Nat⊥
Nat⊥
Nat Values: Zero Succ V Nat Continuation: rec {Zero → N ∣ Succ x → y . P} with E
Nat⊥
What’s the Dual of Natural Numbers?
Zero : 1 → Nat Run : Nat⊥ → ⊥
Succ : Nat → Nat Tail : Nat⊥ → Nat⊥
Nat⊥
Nat Values: Zero Succ V Nat Continuation: rec {Zero → N ∣ Succ x → y . P} with E Nat⊥ Value: corec {Run → E ∣ Tail α → β . F} with V Nat⊥ Continuations: Run Tail E
Nat⊥
Corecursion on Streams
In an Abstract Machine
Corecursion on Streams
to
Nat⊥ Stream A
In an Abstract Machine
Corecursion on Streams
to
Nat⊥ Stream A
In an Abstract Machine
Corecursion on Streams
to
Nat⊥ Stream A
Head : Stream A → A Tail : Stream A → Stream A
In an Abstract Machine
Corecursion on Streams
to
Nat⊥ Stream A
Head : Stream A → A Tail : Stream A → Stream A
Nat⊥ Value: corec {Run → E ∣ Tail β → γ . F} with V Nat⊥ Conts.: Run Tail E
In an Abstract Machine
Corecursion on Streams
to
Nat⊥ Stream A
Head : Stream A → A Tail : Stream A → Stream A
Nat⊥ Value: corec {Run → E ∣ Tail β → γ . F} with V Nat⊥ Conts.: Run Tail E
Stream A Value: corec {Head α → E ∣ Tail β → γ . F} with V Stream A Conts.: Head E Tail E
In an Abstract Machine
Corecursion on Streams
In the λμ-Calculus
Corecursion on Streams
In the λμ-Calculus
Corecursion on Streams
In the λμ-Calculus
Corecursion on Streams
; invoked by jumps
μα . J ⟨M| |α⟩
In the λμ-Calculus
Corecursion on Streams
; invoked by jumps
μα . J ⟨M| |α⟩
Destructors: when
Head M : A Tail M : Stream A M : Stream A
In the λμ-Calculus
Corecursion on Streams
; invoked by jumps
μα . J ⟨M| |α⟩
Destructors: when
Head M : A Tail M : Stream A M : Stream A
Generator: corec {Head → x . N ∣ Tail β → y . P} with M
In the λμ-Calculus
Corecursion on Streams
; invoked by jumps
μα . J ⟨M| |α⟩
Destructors: when
Head M : A Tail M : Stream A M : Stream A
Generator: corec {Head → x . N ∣ Tail β → y . P} with M
, named and in the branches
M x y
In the λμ-Calculus
Corecursion on Streams
; invoked by jumps
μα . J ⟨M| |α⟩
Destructors: when
Head M : A Tail M : Stream A M : Stream A
Generator: corec {Head → x . N ∣ Tail β → y . P} with M
, named and in the branches
M x y
N x
In the λμ-Calculus
Corecursion on Streams
; invoked by jumps
μα . J ⟨M| |α⟩
Destructors: when
Head M : A Tail M : Stream A M : Stream A
Generator: corec {Head → x . N ∣ Tail β → y . P} with M
, named and in the branches
M x y
N x
P
In the λμ-Calculus
Corecursion on Streams
; invoked by jumps
μα . J ⟨M| |α⟩
Destructors: when
Head M : A Tail M : Stream A M : Stream A
Generator: corec {Head → x . N ∣ Tail β → y . P} with M
, named and in the branches
M x y
N x
P
y
In the λμ-Calculus
Corecursion on Streams
; invoked by jumps
μα . J ⟨M| |α⟩
Destructors: when
Head M : A Tail M : Stream A M : Stream A
Generator: corec {Head → x . N ∣ Tail β → y . P} with M
, named and in the branches
M x y
N x
P
y
β
In the λμ-Calculus
Examples of Corecursion
In an Abstract Machine
Examples of Corecursion
count x = x, x + 1, x + 2, x + 3…
In an Abstract Machine
Examples of Corecursion
count x = x, x + 1, x + 2, x + 3… count = λx . corec {Head → y . y ∣ Tail _ → z . Succ z} with x
In an Abstract Machine
Examples of Corecursion
count x = x, x + 1, x + 2, x + 3… count = λx . corec {Head → y . y ∣ Tail _ → z . Succ z} with x scons x (y0, y1, y2…) = x, y0, y1, y2…
In an Abstract Machine
Examples of Corecursion
count x = x, x + 1, x + 2, x + 3… count = λx . corec {Head → y . y ∣ Tail _ → z . Succ z} with x scons x (y0, y1, y2…) = x, y0, y1, y2… scons = λx . λys . corec {Head → _ . x ∣ Tail α → _ . μδ . ⟨ys| |α⟩} with _
In an Abstract Machine
Examples of Corecursion
count x = x, x + 1, x + 2, x + 3… count = λx . corec {Head → y . y ∣ Tail _ → z . Succ z} with x scons x (y0, y1, y2…) = x, y0, y1, y2… scons = λx . λys . corec {Head → _ . x ∣ Tail α → _ . μδ . ⟨ys| |α⟩} with _ app [x0, x1, …, xn] (y0, y1, y2…) = x0, x1, …, xn, y0, y1, y2…
In an Abstract Machine
Examples of Corecursion
count x = x, x + 1, x + 2, x + 3… count = λx . corec {Head → y . y ∣ Tail _ → z . Succ z} with x scons x (y0, y1, y2…) = x, y0, y1, y2… scons = λx . λys . corec {Head → _ . x ∣ Tail α → _ . μδ . ⟨ys| |α⟩} with _ app [x0, x1, …, xn] (y0, y1, y2…) = x0, x1, …, xn, y0, y1, y2… app = λxs . λys . corec Head → Cons x xs . x Tail _ → Cons x xs . xs Head → Nil . Head ys Tail α → Nil . μδ . ⟨Tail ys| |α⟩ with xs
In an Abstract Machine
Corecursion vs Coiteration
Expressiveness vs Cost; CBV vs CBN
Corecursion vs Coiteration
coiter { Head α → E Tail → γ . F} with V := corec { Head α → E Tail _ → γ . F} with V
Expressiveness vs Cost; CBV vs CBN
Corecursion vs Coiteration
coiter { Head α → E Tail → γ . F} with V := corec { Head α → E Tail _ → γ . F} with V ⟨Left V| |[E, F]⟩ ↦ ⟨V| |E⟩ ⟨Right V| |[E, F]⟩ ↦ ⟨V| |F⟩
Expressiveness vs Cost; CBV vs CBN
Corecursion vs Coiteration
coiter { Head α → E Tail → γ . F} with V := corec { Head α → E Tail _ → γ . F} with V ⟨Left V| |[E, F]⟩ ↦ ⟨V| |E⟩ ⟨Right V| |[E, F]⟩ ↦ ⟨V| |F⟩ corec { Head α → E Tail β → γ . F} with V := coiter { Head α → [Head α, E] Tail → [β, γ] . [Tail β, F]} with Right V
Expressiveness vs Cost; CBV vs CBN
Corecursion vs Coiteration
coiter { Head α → E Tail → γ . F} with V := corec { Head α → E Tail _ → γ . F} with V ⟨Left V| |[E, F]⟩ ↦ ⟨V| |E⟩ ⟨Right V| |[E, F]⟩ ↦ ⟨V| |F⟩ corec { Head α → E Tail β → γ . F} with V := coiter { Head α → [Head α, E] Tail → [β, γ] . [Tail β, F]} with Right V
:
scons x ys
Expressiveness vs Cost; CBV vs CBN
Corecursion vs Coiteration
coiter { Head α → E Tail → γ . F} with V := corec { Head α → E Tail _ → γ . F} with V ⟨Left V| |[E, F]⟩ ↦ ⟨V| |E⟩ ⟨Right V| |[E, F]⟩ ↦ ⟨V| |F⟩ corec { Head α → E Tail β → γ . F} with V := coiter { Head α → [Head α, E] Tail → [β, γ] . [Tail β, F]} with Right V
:
scons x ys
: adds
corec Head(Tailn+1(scons x ys)) O(1) Head(Tailn ys)
Expressiveness vs Cost; CBV vs CBN
Corecursion vs Coiteration
coiter { Head α → E Tail → γ . F} with V := corec { Head α → E Tail _ → γ . F} with V ⟨Left V| |[E, F]⟩ ↦ ⟨V| |E⟩ ⟨Right V| |[E, F]⟩ ↦ ⟨V| |F⟩ corec { Head α → E Tail β → γ . F} with V := coiter { Head α → [Head α, E] Tail → [β, γ] . [Tail β, F]} with Right V
:
scons x ys
: adds
corec Head(Tailn+1(scons x ys)) O(1) Head(Tailn ys)
: adds
corec Head(Tailn+1(scons x ys)) O(n) Head(Tailn ys)
Expressiveness vs Cost; CBV vs CBN
Corecursion vs Coiteration
coiter { Head α → E Tail → γ . F} with V := corec { Head α → E Tail _ → γ . F} with V ⟨Left V| |[E, F]⟩ ↦ ⟨V| |E⟩ ⟨Right V| |[E, F]⟩ ↦ ⟨V| |F⟩ corec { Head α → E Tail β → γ . F} with V := coiter { Head α → [Head α, E] Tail → [β, γ] . [Tail β, F]} with Right V
:
scons x ys
: adds
corec Head(Tailn+1(scons x ys)) O(1) Head(Tailn ys)
: adds
corec Head(Tailn+1(scons x ys)) O(n) Head(Tailn ys)
has same overhead as encoding; Native CBV more efficient
corec corec
Expressiveness vs Cost; CBV vs CBN
Corecursion vs Coiteration
coiter { Head α → E Tail → γ . F} with V := corec { Head α → E Tail _ → γ . F} with V ⟨Left V| |[E, F]⟩ ↦ ⟨V| |E⟩ ⟨Right V| |[E, F]⟩ ↦ ⟨V| |F⟩ corec { Head α → E Tail β → γ . F} with V := coiter { Head α → [Head α, E] Tail → [β, γ] . [Tail β, F]} with Right V
:
scons x ys
: adds
corec Head(Tailn+1(scons x ys)) O(1) Head(Tailn ys)
: adds
corec Head(Tailn+1(scons x ys)) O(n) Head(Tailn ys)
has same overhead as encoding; Native CBV more efficient
corec corec
and
rec iter
Expressiveness vs Cost; CBV vs CBN
Finite Induction
By Inversion on the Input
Finite Induction
By Inversion on the Input
Finite Induction
By Inversion on the Input
Finite Induction
By Inversion on the Input
Finite Induction
By Inversion on the Input
Finite Induction
By Inversion on the Input
Infinite Induction
By Inversion on the Input
Infinite Induction
By Inversion on the Input
Infinite Induction
By Inversion on the Input
Infinite Induction
By Inversion on the Input
Infinite Induction
By Inversion on the Input
Infinite Induction
By Inversion on the Input
Infinite Induction
By Inversion on the Input
Infinite Induction
By Inversion on the Input
An Induction Principle
Based on Information Flow
An Induction Principle
Based on Information Flow
An Induction Principle
Based on Information Flow
An Induction Principle
Based on Information Flow
An Induction Principle
Based on Information Flow
An Induction Principle
Based on Information Flow
Φ(Zero) ⇒ (∀x:Nat . Φ(x) ⇒ Φ(x + 1)) ⇒ (∀x:Nat . Φ(x))
Finite Coinduction
By Inversion on the Output
Finite Coinduction
By Inversion on the Output
Finite Coinduction
By Inversion on the Output
Finite Coinduction
By Inversion on the Output
Finite Coinduction
By Inversion on the Output
λx . μβ . ⟨V| |x ⋅ β⟩ =η V
Finite Coinduction
By Inversion on the Output
λx . μβ . ⟨V| |x ⋅ β⟩ =η V
Finite Coinduction
By Inversion on the Output
λx . μβ . ⟨V| |x ⋅ β⟩ =η V
Finite Coinduction
By Inversion on the Output
λx . μβ . ⟨V| |x ⋅ β⟩ =η V
Infinite Coinduction
By Inversion on the Output
Infinite Coinduction
By Inversion on the Output
Infinite Coinduction
By Inversion on the Output
Infinite Coinduction
By Inversion on the Output
Infinite Coinduction
By Inversion on the Output
Infinite Coinduction
By Inversion on the Output
Infinite Coinduction
By Inversion on the Output
Infinite Coinduction
By Inversion on the Output
A Coinduction Principle
Based on Control Flow
A Coinduction Principle
Based on Control Flow
A Coinduction Principle
Based on Control Flow
A Coinduction Principle
Based on Control Flow
A Coinduction Principle
Based on Control Flow
A Coinduction Principle
Based on Control Flow
Bisimulation = (∀s, s′ : Stream A . Φ(s, s′ ) ⇒ Head s = Head s′ : A) ⇒ (∀s, s′ : Stream A . Φ(s, s′ ) ⇒ Φ(Tail s, Tail s′ )) ⇒ (∀s, s′ : Stream A . Φ(s, s′ ) ⇒ s = s′ : Stream A)
A Coinduction Principle
Based on Control Flow
Bisimulation = (∀s, s′ : Stream A . Φ(s, s′ ) ⇒ Head s = Head s′ : A) ⇒ (∀s, s′ : Stream A . Φ(s, s′ ) ⇒ Φ(Tail s, Tail s′ )) ⇒ (∀s, s′ : Stream A . Φ(s, s′ ) ⇒ s = s′ : Stream A)
Proof by Coinduction
Proof by Coinduction
repeat x = x, x, x… alt = 0,1,0,1… evens (x0, x1, x2…) = x0, x2, x4…
Proof by Coinduction
Theorem: evens alt = repeat 0 : Stream A repeat x = x, x, x… alt = 0,1,0,1… evens (x0, x1, x2…) = x0, x2, x4…
Proof by Coinduction
Theorem: evens alt = repeat 0 : Stream A
|α⟩ = ⟨repeat 0| |α⟩
repeat x = x, x, x… alt = 0,1,0,1… evens (x0, x1, x2…) = x0, x2, x4…
Proof by Coinduction
Proof: By coinduction on …
α ÷ Stream A
Theorem: evens alt = repeat 0 : Stream A
|α⟩ = ⟨repeat 0| |α⟩
repeat x = x, x, x… alt = 0,1,0,1… evens (x0, x1, x2…) = x0, x2, x4…
Proof by Coinduction
Proof: By coinduction on …
α ÷ Stream A
α = Head β ⟨evens alt| |Head β⟩ = ⟨0| |β⟩ = ⟨repeat 0| |Head β⟩
Theorem: evens alt = repeat 0 : Stream A
|α⟩ = ⟨repeat 0| |α⟩
repeat x = x, x, x… alt = 0,1,0,1… evens (x0, x1, x2…) = x0, x2, x4…
Proof by Coinduction
Proof: By coinduction on …
α ÷ Stream A
α = Head β ⟨evens alt| |Head β⟩ = ⟨0| |β⟩ = ⟨repeat 0| |Head β⟩
and show …
α = Tail β ⟨evens alt| |β⟩ = ⟨repeat 0| |β⟩ ⟨evens alt| |Tail β⟩ = ⟨repeat 0| |Tail β⟩
Theorem: evens alt = repeat 0 : Stream A
|α⟩ = ⟨repeat 0| |α⟩
repeat x = x, x, x… alt = 0,1,0,1… evens (x0, x1, x2…) = x0, x2, x4…
Proof by Coinduction
Proof: By coinduction on …
α ÷ Stream A
α = Head β ⟨evens alt| |Head β⟩ = ⟨0| |β⟩ = ⟨repeat 0| |Head β⟩
and show …
α = Tail β ⟨evens alt| |β⟩ = ⟨repeat 0| |β⟩ ⟨evens alt| |Tail β⟩ = ⟨repeat 0| |Tail β⟩ ⟨evens alt| |Tail β⟩ = ⟨evens (Tail(Tail alt))| |β⟩ (def . evens) = ⟨evens alt| |β⟩ (def . alt) = ⟨repeat 0| |β⟩ (CoIH) = ⟨repeat 0| |Tail β⟩ (def . repeat)
Theorem: evens alt = repeat 0 : Stream A
|α⟩ = ⟨repeat 0| |α⟩
repeat x = x, x, x… alt = 0,1,0,1… evens (x0, x1, x2…) = x0, x2, x4…
Weak vs Strong (Co)Induction
And Effectful Computation
Weak vs Strong (Co)Induction
And Effectful Computation
Weak vs Strong (Co)Induction
And Effectful Computation
Weak vs Strong (Co)Induction
And Effectful Computation
Weak vs Strong (Co)Induction
And Effectful Computation
Weak vs Strong (Co)Induction
x x ⟨x| |E⟩ = ⟨x| |E′ ⟩
And Effectful Computation
Weak vs Strong (Co)Induction
x x ⟨x| |E⟩ = ⟨x| |E′ ⟩
α α ⟨V| |α⟩ = ⟨V′ | |α⟩
And Effectful Computation
Weak vs Strong (Co)Induction
x x ⟨x| |E⟩ = ⟨x| |E′ ⟩
α α ⟨V| |α⟩ = ⟨V′ | |α⟩
And Effectful Computation
Lessons Learned
Lessons Learned
Lessons Learned
Lessons Learned