Built with doc-gen4, running Lean4. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓to navigate, Ctrl+🖱️to focus. On Mac, use Cmdinstead of Ctrl.
/-
Copyright (c) 2017 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Mario Carneiro

Coinductive formalization of unbounded computations.

! This file was ported from Lean 3 source module data.seq.computation
! leanprover-community/mathlib commit 1f0096e6caa61e9c849ec2adbd227e960e9dff58
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathlib.Data.Stream.Init
import Mathlib.Tactic.Common

/-!
# Coinductive formalization of unbounded computations.

This file provides a `Computation` type where `Computation α` is the type of
unbounded computations returning `α`.
-/


open Function

universe u v w

/-
coinductive Computation (α : Type u) : Type u
| pure : α → Computation α
| think : Computation α → Xomputation α
-/
/-- `Computation α` is the type of unbounded computations returning `α`.
  An element of `Computation α` is an infinite sequence of `Option α` such
  that if `f n = some a` for some `n` then it is constantly `some a` after that. -/
def 
Computation: Type u → Type u
Computation
(
α: Type u
α
:
Type u: Type (u+1)
Type u
) :
Type u: Type (u+1)
Type u
:= {
f: Stream' (Option α)
f
:
Stream': Type ?u.9 → Type ?u.9
Stream'
(
Option: Type ?u.10 → Type ?u.10
Option
α: Type u
α
) // ∀ ⦃
n: ?m.13
n
a: ?m.16
a
⦄,
f: Stream' (Option α)
f
n: ?m.13
n
=
some: {α : Type ?u.21} → αOption α
some
a: ?m.16
a
f: Stream' (Option α)
f
(
n: ?m.13
n
+
1: ?m.58
1
) =
some: {α : Type ?u.118} → αOption α
some
a: ?m.16
a
} #align computation
Computation: Type u → Type u
Computation
namespace Computation variable {
α: Type u
α
:
Type u: Type (u+1)
Type u
} {
β: Type v
β
:
Type v: Type (v+1)
Type v
} {
γ: Type w
γ
:
Type w: Type (w+1)
Type w
} -- constructors /-- `pure a` is the computation that immediately terminates with result `a`. -/ -- porting notes: `return` is reserved, so changed to `pure` def
pure: αComputation α
pure
(
a: α
a
:
α: Type u
α
) :
Computation: Type ?u.155 → Type ?u.155
Computation
α: Type u
α
:= ⟨
Stream'.const: {α : Type ?u.174} → αStream' α
Stream'.const
(
some: {α : Type ?u.178} → αOption α
some
a: α
a
), fun
_: ?m.183
_
_: ?m.186
_
=>
id: ∀ {α : Sort ?u.188}, αα
id
#align computation.return
Computation.pure: {α : Type u} → αComputation α
Computation.pure
instance: {α : Type u} → CoeTC α (Computation α)
instance
:
CoeTC: Sort ?u.301 → Sort ?u.300 → Sort (max(max1?u.301)?u.300)
CoeTC
α: Type u
α
(
Computation: Type ?u.302 → Type ?u.302
Computation
α: Type u
α
) := ⟨
pure: {α : Type ?u.313} → αComputation α
pure
⟩ /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/ -- note [use has_coe_t] /-- `think c` is the computation that delays for one "tick" and then performs computation `c`. -/ def
think: {α : Type u} → Computation αComputation α
think
(c :
Computation: Type ?u.387 → Type ?u.387
Computation
α: Type u
α
) :
Computation: Type ?u.390 → Type ?u.390
Computation
α: Type u
α
:= ⟨
Stream'.cons: {α : Type ?u.409} → αStream' αStream' α
Stream'.cons
none: {α : Type ?u.413} → Option α
none
c.
1: {α : Sort ?u.416} → {p : αProp} → Subtype pα
1
, fun
n: ?m.423
n
a: ?m.426
a
h: ?m.429
h
=>

Goals accomplished! 🐙
α: Type u

β: Type v

γ: Type w

c: Computation α

n:

a: α

h: Stream'.cons none (c) n = some a


Stream'.cons none (c) (n + 1) = some a
α: Type u

β: Type v

γ: Type w

c: Computation α

a: α

h: Stream'.cons none (c) Nat.zero = some a


zero
Stream'.cons none (c) (Nat.zero + 1) = some a
α: Type u

β: Type v

γ: Type w

c: Computation α

a: α

n:

h: Stream'.cons none (c) (Nat.succ n) = some a


succ
Stream'.cons none (c) (Nat.succ n + 1) = some a
α: Type u

β: Type v

γ: Type w

c: Computation α

n:

a: α

h: Stream'.cons none (c) n = some a


Stream'.cons none (c) (n + 1) = some a
α: Type u

β: Type v

γ: Type w

c: Computation α

a: α

h: Stream'.cons none (c) Nat.zero = some a


zero
Stream'.cons none (c) (Nat.zero + 1) = some a
α: Type u

β: Type v

γ: Type w

c: Computation α

a: α

h: Stream'.cons none (c) Nat.zero = some a


zero
Stream'.cons none (c) (Nat.zero + 1) = some a
α: Type u

β: Type v

γ: Type w

c: Computation α

a: α

n:

h: Stream'.cons none (c) (Nat.succ n) = some a


succ
Stream'.cons none (c) (Nat.succ n + 1) = some a

Goals accomplished! 🐙
α: Type u

β: Type v

γ: Type w

c: Computation α

n:

a: α

h: Stream'.cons none (c) n = some a


Stream'.cons none (c) (n + 1) = some a
α: Type u

β: Type v

γ: Type w

c: Computation α

a: α

n:

h: Stream'.cons none (c) (Nat.succ n) = some a


succ
Stream'.cons none (c) (Nat.succ n + 1) = some a
α: Type u

β: Type v

γ: Type w

c: Computation α

a: α

n:

h: Stream'.cons none (c) (Nat.succ n) = some a


succ
Stream'.cons none (c) (Nat.succ n + 1) = some a

Goals accomplished! 🐙
#align computation.think
Computation.think: {α : Type u} → Computation αComputation α
Computation.think
/-- `thinkN c n` is the computation that delays for `n` ticks and then performs computation `c`. -/ def
thinkN: {α : Type u} → Computation αComputation α
thinkN
(c :
Computation: Type ?u.643 → Type ?u.643
Computation
α: Type u
α
) :
: Type
Computation: Type ?u.648 → Type ?u.648
Computation
α: Type u
α
|
0:
0
=> c |
n:
n
+ 1 =>
think: {α : Type ?u.749} → Computation αComputation α
think
(
thinkN: Computation αComputation α
thinkN
c
n:
n
) set_option linter.uppercaseLean3 false in #align computation.thinkN
Computation.thinkN: {α : Type u} → Computation αComputation α
Computation.thinkN
-- check for immediate result /-- `head c` is the first step of computation, either `some a` if `c = pure a` or `none` if `c = think c'`. -/ def
head: {α : Type u} → Computation αOption α
head
(c :
Computation: Type ?u.1040 → Type ?u.1040
Computation
α: Type u
α
) :
Option: Type ?u.1043 → Type ?u.1043
Option
α: Type u
α
:= c.
1: {α : Sort ?u.1046} → {p : αProp} → Subtype pα
1
.
head: {α : Type ?u.1058} → Stream' αα
head
#align computation.head
Computation.head: {α : Type u} → Computation αOption α
Computation.head
-- one step of computation /-- `tail c` is the remainder of computation, either `c` if `c = pure a` or `c'` if `c = think c'`. -/ def
tail: {α : Type u} → Computation αComputation α
tail
(c :
Computation: Type ?u.1131 → Type ?u.1131
Computation
α: Type u
α
) :
Computation: Type ?u.1134 → Type ?u.1134
Computation
α: Type u
α
:= ⟨c.
1: {α : Sort ?u.1153} → {p : αProp} → Subtype pα
1
.
tail: {α : Type ?u.1158} → Stream' αStream' α
tail
, fun
_: ?m.1166
_
_: ?m.1169
_
h: ?m.1172
h
=> c.
2: ∀ {α : Sort ?u.1174} {p : αProp} (self : Subtype p), p self
2
h: ?m.1172
h
#align computation.tail
Computation.tail: {α : Type u} → Computation αComputation α
Computation.tail
/-- `empty α` is the computation that never returns, an infinite sequence of `think`s. -/ def
empty: (α : Type ?u.1308) → Computation α
empty
(
α: ?m.1305
α
) :
Computation: Type ?u.1308 → Type ?u.1308
Computation
α: ?m.1305
α
:= ⟨
Stream'.const: {α : Type ?u.1327} → αStream' α
Stream'.const
none: {α : Type ?u.1331} → Option α
none
, fun
_: ?m.1336
_
_: ?m.1339
_
=>
id: ∀ {α : Sort ?u.1341}, αα
id
#align computation.empty
Computation.empty: (α : Type u_1) → Computation α
Computation.empty
instance: {α : Type u} → Inhabited (Computation α)
instance
:
Inhabited: Sort ?u.1435 → Sort (max1?u.1435)
Inhabited
(
Computation: Type ?u.1436 → Type ?u.1436
Computation
α: Type u
α
) := ⟨
empty: (α : Type ?u.1443) → Computation α
empty
_: Type ?u.1443
_
⟩ /-- `run_for c n` evaluates `c` for `n` steps and returns the result, or `none` if it did not terminate after `n` steps. -/ def
runFor: Computation αOption α
runFor
:
Computation: Type ?u.1505 → Type ?u.1505
Computation
α: Type u
α
: Type
Option: Type ?u.1509 → Type ?u.1509
Option
α: Type u
α
:=
Subtype.val: {α : Sort ?u.1511} → {p : αProp} → Subtype pα
Subtype.val
#align computation.run_for
Computation.runFor: {α : Type u} → Computation αOption α
Computation.runFor
/-- `destruct c` is the destructor for `Computation α` as a coinductive type. It returns `inl a` if `c = pure a` and `inr c'` if `c = think c'`. -/ def
destruct: Computation αα Computation α
destruct
(c :
Computation: Type ?u.1596 → Type ?u.1596
Computation
α: Type u
α
) :
Sum: Type ?u.1600 → Type ?u.1599 → Type (max?u.1600?u.1599)
Sum
α: Type u
α
(
Computation: Type ?u.1601 → Type ?u.1601
Computation
α: Type u
α
) := match c.
1: {α : Sort ?u.1604} → {p : αProp} → Subtype pα
1
0: ?m.1616
0
with |
none: {α : Type ?u.1628} → Option α
none
=>
Sum.inr: {α : Type ?u.1638} → {β : Type ?u.1637} → βα β
Sum.inr
(
tail: {α : Type ?u.1643} → Computation αComputation α
tail
c) |
some: {α : Type ?u.1646} → αOption α
some
a: α
a
=>
Sum.inl: {α : Type ?u.1661} → {β : Type ?u.1660} → αα β
Sum.inl
a: α
a
#align computation.destruct
Computation.destruct: {α : Type u} → Computation αα Computation α
Computation.destruct
/-- `run c` is an unsound meta function that runs `c` to completion, possibly resulting in an infinite loop in the VM. -/ unsafe def
run: {α : Type u} → Computation αα
run
:
Computation: Type ?u.1904 → Type ?u.1904
Computation
α: Type u
α
α: Type u
α
|
c: ?m.1911
c
=> match
destruct: {α : Type ?u.1913} → Computation αα Computation α
destruct
c: ?m.1911
c
with |
Sum.inl: {α : Type ?u.1919} → {β : Type ?u.1918} → αα β
Sum.inl
a: α
a
=>
a: α
a
|
Sum.inr: {α : Type ?u.1939} → {β : Type ?u.1938} → βα β
Sum.inr
ca =>
run: Computation αα
run
ca #align computation.run
Computation.run: {α : Type u} → Computation αα
Computation.run
theorem
destruct_eq_pure: ∀ {s : Computation α} {a : α}, destruct s = Sum.inl as = pure a
destruct_eq_pure
{s :
Computation: Type ?u.2155 → Type ?u.2155
Computation
α: Type u
α
} {
a: α
a
:
α: Type u
α
} :
destruct: {α : Type ?u.2162} → Computation αα Computation α
destruct
s =
Sum.inl: {α : Type ?u.2167} → {β : Type ?u.2166} → αα β
Sum.inl
a: α
a
s =
pure: {α : Type ?u.2205} → αComputation α
pure
a: α
a
:=

Goals accomplished! 🐙
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α


destruct s = Sum.inl as = pure a
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α


(match s 0 with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl as = pure a
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α


destruct s = Sum.inl as = pure a
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

f0: s 0 = none


none
(match none with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl as = pure a
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝


some
(match some val✝ with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl as = pure a
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α


(match s 0 with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl as = pure a
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

f0: s 0 = none


none
(match none with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl as = pure a
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝


some
(match some val✝ with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl as = pure a
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α


(match s 0 with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl as = pure a
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

f0: s 0 = none

h: (match none with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl a


none
s = pure a
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α


destruct s = Sum.inl as = pure a
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

f0: s 0 = none

h: (match none with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl a


none
s = pure a
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

f0: s 0 = none

h: (match none with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl a


none
s = pure a
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝

h: (match some val✝ with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl a


some
s = pure a

Goals accomplished! 🐙
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α


destruct s = Sum.inl as = pure a
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝

h: (match some val✝ with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl a


some
s = pure a
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝

h: (match some val✝ with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl a


some
s = pure a
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝

h: (match some val✝ with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl a


some.a
s = ↑(pure a)
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝

h: (match some val✝ with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl a


some
s = pure a
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝

h: (match some val✝ with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl a

n:


some.a.h
s n = ↑(pure a) n
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝

h: (match some val✝ with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl a


some
s = pure a
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝

h: (match some val✝ with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl a


some.a.h.zero
s Nat.zero = ↑(pure a) Nat.zero
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝

h: (match some val✝ with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl a

n:

IH: s n = ↑(pure a) n


some.a.h.succ
s (Nat.succ n) = ↑(pure a) (Nat.succ n)
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝

h: (match some val✝ with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl a


some
s = pure a
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝

h: (match some val✝ with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl a


some.a.h.zero
s Nat.zero = ↑(pure a) Nat.zero
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝

h: (match some val✝ with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl a


some.a.h.zero
s Nat.zero = ↑(pure a) Nat.zero
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝

h: (match some val✝ with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl a

n:

IH: s n = ↑(pure a) n


some.a.h.succ
s (Nat.succ n) = ↑(pure a) (Nat.succ n)
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝

h': val✝ = a


some.a.h.zero
s Nat.zero = ↑(pure a) Nat.zero
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝

h: (match some val✝ with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl a


some.a.h.zero
s Nat.zero = ↑(pure a) Nat.zero
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝

h': val✝ = a


some.a.h.zero
s Nat.zero = ↑(pure a) Nat.zero
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some a

h': val✝ = a


some.a.h.zero
s Nat.zero = ↑(pure a) Nat.zero
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some a

h': val✝ = a


some.a.h.zero
s Nat.zero = ↑(pure a) Nat.zero

Goals accomplished! 🐙
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝

h: (match some val✝ with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl a


some
s = pure a
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝

h: (match some val✝ with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl a

n:

IH: s n = ↑(pure a) n


some.a.h.succ
s (Nat.succ n) = ↑(pure a) (Nat.succ n)
α: Type u

β: Type v

γ: Type w

s: Computation α

a: α

x✝: Option α

f0✝: s 0 = x✝

val✝: α

f0: s 0 = some val✝

h: (match some val✝ with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inl a

n:

IH: s n = ↑(pure a) n


some.a.h.succ
s (Nat.succ n) = ↑(pure a) (Nat.succ n)

Goals accomplished! 🐙
#align computation.destruct_eq_ret
Computation.destruct_eq_pure: ∀ {α : Type u} {s : Computation α} {a : α}, destruct s = Sum.inl as = pure a
Computation.destruct_eq_pure
theorem
destruct_eq_think: ∀ {s s' : Computation α}, destruct s = Sum.inr s's = think s'
destruct_eq_think
{s :
Computation: Type ?u.2491 → Type ?u.2491
Computation
α: Type u
α
} {
s': ?m.2494
s'
} :
destruct: {α : Type ?u.2499} → Computation αα Computation α
destruct
s =
Sum.inr: {α : Type ?u.2504} → {β : Type ?u.2503} → βα β
Sum.inr
s': ?m.2494
s'
s =
think: {α : Type ?u.2542} → Computation αComputation α
think
s': ?m.2494
s'
:=

Goals accomplished! 🐙
α: Type u

β: Type v

γ: Type w

s, s': Computation α


destruct s = Sum.inr s's = think s'
α: Type u

β: Type v

γ: Type w

s, s': Computation α


(match s 0 with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inr s's = think s'
α: Type u

β: Type v

γ: Type w

s, s': Computation α


destruct s = Sum.inr s's = think s'
α: Type u

β: Type v

γ: Type w

s, s': Computation α

x✝: Option α

f0✝: s 0 = x✝

f0: s 0 = none


none
(match none with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inr s's = think s'
α: Type u

β: Type v

γ: Type w

s, s': Computation α

x✝: Option α

f0✝: s 0 = x✝

a': α

f0: s 0 = some a'


some
(match some a' with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inr s's = think s'
α: Type u

β: Type v

γ: Type w

s, s': Computation α


(match s 0 with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inr s's = think s'
α: Type u

β: Type v

γ: Type w

s, s': Computation α

x✝: Option α

f0✝: s 0 = x✝

f0: s 0 = none


none
(match none with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inr s's = think s'
α: Type u

β: Type v

γ: Type w

s, s': Computation α

x✝: Option α

f0✝: s 0 = x✝

a': α

f0: s 0 = some a'


some
(match some a' with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inr s's = think s'
α: Type u

β: Type v

γ: Type w

s, s': Computation α


(match s 0 with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inr s's = think s'
α: Type u

β: Type v

γ: Type w

s, s': Computation α

x✝: Option α

f0✝: s 0 = x✝

f0: s 0 = none

h: (match none with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inr s'


none
s = think s'
α: Type u

β: Type v

γ: Type w

s, s': Computation α


destruct s = Sum.inr s's = think s'
α: Type u

β: Type v

γ: Type w

s, s': Computation α

x✝: Option α

f0✝: s 0 = x✝

f0: s 0 = none

h: (match none with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inr s'


none
s = think s'
α: Type u

β: Type v

γ: Type w

s, s': Computation α

x✝: Option α

f0✝: s 0 = x✝

f0: s 0 = none

h: (match none with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inr s'


none
s = think s'
α: Type u

β: Type v

γ: Type w

s, s': Computation α

x✝: Option α

f0✝: s 0 = x✝

a': α

f0: s 0 = some a'

h: (match some a' with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inr s'


some
s = think s'
α: Type u

β: Type v

γ: Type w

s, s': Computation α

x✝: Option α

f0✝: s 0 = x✝

f0: s 0 = none

h': tail s = s'


none
s = think s'
α: Type u

β: Type v

γ: Type w

s, s': Computation α

x✝: Option α

f0✝: s 0 = x✝

f0: s 0 = none

h: (match none with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inr s'


none
s = think s'
α: Type u

β: Type v

γ: Type w

s, s': Computation α

x✝: Option α

f0✝: s 0 = x✝

f0: s 0 = none

h': tail s = s'


none
s = think s'
α: Type u

β: Type v

γ: Type w

s, s': Computation α

x✝: Option α

f0✝: s 0 = x✝

f0: s 0 = none

h': tail s = s'


none
s = think (tail s)
α: Type u

β: Type v

γ: Type w

s, s': Computation α

x✝: Option α

f0✝: s 0 = x✝

f0: s 0 = none

h': tail s = s'


none
s = think (tail s)
α: Type u

β: Type v

γ: Type w

s, s': Computation α

x✝: Option α

f0✝: s 0 = x✝

f0: s 0 = none

h: (match none with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inr s'


none
s = think s'
α: Type u

β: Type v

γ: Type w

s': Computation α

x✝: Option α

f: Stream' (Option α)

al: ∀ ⦃n : ⦄ ⦃a : α⦄, f n = some af (n + 1) = some a

f0✝: { val := f, property := al } 0 = x✝

f0: { val := f, property := al } 0 = none

h': tail { val := f, property := al } = s'


none.mk
{ val := f, property := al } = think (tail { val := f, property := al })
α: Type u

β: Type v

γ: Type w

s, s': Computation α

x✝: Option α

f0✝: s 0 = x✝

f0: s 0 = none

h: (match none with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inr s'


none
s = think s'
α: Type u

β: Type v

γ: Type w

s': Computation α

x✝: Option α

f: Stream' (Option α)

al: ∀ ⦃n : ⦄ ⦃a : α⦄, f n = some af (n + 1) = some a

f0✝: { val := f, property := al } 0 = x✝

f0: { val := f, property := al } 0 = none

h': tail { val := f, property := al } = s'


none.mk.a
{ val := f, property := al } = ↑(think (tail { val := f, property := al }))
α: Type u

β: Type v

γ: Type w

s, s': Computation α

x✝: Option α

f0✝: s 0 = x✝

f0: s 0 = none

h: (match none with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inr s'


none
s = think s'
α: Type u

β: Type v

γ: Type w

s': Computation α

x✝: Option α

f: Stream' (Option α)

al: ∀ ⦃n : ⦄ ⦃a : α⦄, f n = some af (n + 1) = some a

f0✝: { val := f, property := al } 0 = x✝

f0: { val := f, property := al } 0 = none

h': tail { val := f, property := al } = s'


none.mk.a
α: Type u

β: Type v

γ: Type w

s, s': Computation α

x✝: Option α

f0✝: s 0 = x✝

f0: s 0 = none

h: (match none with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inr s'


none
s = think s'
α: Type u

β: Type v

γ: Type w

s': Computation α

x✝: Option α

f: Stream' (Option α)

al: ∀ ⦃n : ⦄ ⦃a : α⦄, f n = some af (n + 1) = some a

f0✝: { val := f, property := al } 0 = x✝

f0: { val := f, property := al } 0 = none

h': tail { val := f, property := al } = s'


none.mk.a
α: Type u

β: Type v

γ: Type w

s': Computation α

x✝: Option α

f: Stream' (Option α)

al: ∀ ⦃n : ⦄ ⦃a : α⦄, f n = some af (n + 1) = some a

f0✝: { val := f, property := al } 0 = x✝

f0: { val := f, property := al } 0 = none

h': tail { val := f, property := al } = s'


none.mk.a
f = Stream'.cons ({ val := f, property := al } 0) (Stream'.tail f)
α: Type u

β: Type v

γ: Type w

s': Computation α

x✝: Option α

f: Stream' (Option α)

al: ∀ ⦃n : ⦄ ⦃a : α⦄, f n = some af (n + 1) = some a

f0✝: { val := f, property := al } 0 = x✝

f0: { val := f, property := al } 0 = none

h': tail { val := f, property := al } = s'


none.mk.a
f = Stream'.cons ({ val := f, property := al } 0) (Stream'.tail f)
α: Type u

β: Type v

γ: Type w

s, s': Computation α

x✝: Option α

f0✝: s 0 = x✝

f0: s 0 = none

h: (match none with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inr s'


none
s = think s'

Goals accomplished! 🐙
α: Type u

β: Type v

γ: Type w

s, s': Computation α


destruct s = Sum.inr s's = think s'
α: Type u

β: Type v

γ: Type w

s, s': Computation α

x✝: Option α

f0✝: s 0 = x✝

a': α

f0: s 0 = some a'

h: (match some a' with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inr s'


some
s = think s'
α: Type u

β: Type v

γ: Type w

s, s': Computation α

x✝: Option α

f0✝: s 0 = x✝

a': α

f0: s 0 = some a'

h: (match some a' with | none => Sum.inr (tail s) | some a => Sum.inl a) = Sum.inr s'


some
s = think s'

Goals accomplished! 🐙
#align computation.destruct_eq_think
Computation.destruct_eq_think: ∀ {α : Type u} {s s' : Computation α}, destruct s = Sum.inr s's = think s'
Computation.destruct_eq_think
@[simp] theorem
destruct_pure: ∀ {α : Type u} (a : α), destruct (pure a) = Sum.inl a
destruct_pure
(
a: α
a
:
α: Type u
α
) :
destruct: {α : Type ?u.2892} → Computation αα Computation α
destruct
(
pure: {α : Type ?u.2894} → αComputation α
pure
a: α
a
) =
Sum.inl: {α : Type ?u.2899} → {β : Type ?u.2898} → αα β
Sum.inl
a: α
a
:=
rfl: ∀ {α : Sort ?u.2937} {a : α}, a = a
rfl
#align computation.destruct_ret
Computation.destruct_pure: ∀ {α : Type u} (a : α), destruct (pure a) = Sum.inl a
Computation.destruct_pure
@[simp] theorem
destruct_think: ∀ {α : Type u} (s : Computation α), destruct (think s) = Sum.inr s
destruct_think
: ∀ s :
Computation: Type ?u.2970 → Type ?u.2970
Computation
α: Type u
α
,
destruct: {α : Type ?u.2974} → Computation αα Computation α
destruct
(
think: {α : Type ?u.2976} → Computation αComputation α
think
s) =
Sum.inr: {α : Type ?u.2982} → {β : Type ?u.2981} → βα β
Sum.inr
s | ⟨_, _⟩ =>
rfl: ∀ {α : Sort ?u.3078} {a : α}, a = a
rfl
#align computation.destruct_think
Computation.destruct_think: ∀ {α : Type u} (s : Computation α), destruct (think s) = Sum.inr s
Computation.destruct_think
@[simp] theorem
destruct_empty: destruct (empty α) = Sum.inr (empty α)
destruct_empty
:
destruct: {α : Type ?u.3250} → Computation αα Computation α
destruct
(
empty: (α : Type ?u.3252) → Computation α
empty
α: Type u
α
) =
Sum.inr: {α : Type ?u.3256} → {β : Type ?u.3255} → βα β
Sum.inr
(
empty: (α : Type ?u.3259) → Computation α
empty
α: Type u
α
) :=
rfl: ∀ {α : Sort ?u.3294} {a : α}, a = a
rfl
#align computation.destruct_empty
Computation.destruct_empty: ∀ {α : Type u}, destruct (empty α) = Sum.inr (empty α)
Computation.destruct_empty
@[simp] theorem
head_pure: ∀ (a : α), head (pure a) = some a
head_pure
(
a: α
a
:
α: Type u
α
) :
head: {α : Type ?u.3335} → Computation αOption α
head
(
pure: {α : Type ?u.3337} → αComputation α
pure
a: α
a
) =
some: {α : Type ?u.3341} → αOption α
some
a: α
a
:=
rfl: ∀ {α : Sort ?u.3347} {a : α}, a = a
rfl
#align computation.head_ret
Computation.head_pure: ∀ {α : Type u} (a : α), head (pure a) = some a
Computation.head_pure
@[simp] theorem
head_think: ∀ (s : Computation α), head (think s) = none
head_think
(s :
Computation: Type ?u.3370 → Type ?u.3370
Computation
α: Type u
α
) :
head: {α : Type ?u.3374} → Computation αOption α
head
(
think: {α : Type ?u.3376} → Computation αComputation α
think
s) =
none: {α : Type ?u.3381} → Option α
none
:=
rfl: ∀ {α : Sort ?u.3414} {a : α}, a = a
rfl
#align computation.head_think
Computation.head_think: ∀ {α : Type u} (s : Computation α), head (think s) = none
Computation.head_think
@[simp] theorem
head_empty: ∀ {α : Type u}, head (empty α) = none
head_empty
:
head: {α : Type ?u.3446} → Computation αOption α
head
(
empty: (α : Type ?u.3448) → Computation α
empty
α: Type u
α
) =
none: {α : Type ?u.3451} → Option α
none
:=
rfl: ∀ {α : Sort ?u.3483} {a : α}, a = a
rfl
#align computation.head_empty
Computation.head_empty: ∀ {α : Type u}, head (empty α) = none
Computation.head_empty
@[simp] theorem
tail_pure: ∀ (a : α), tail (pure a) = pure a
tail_pure
(
a: α
a
:
α: Type u
α
) :
tail: {α : Type ?u.3505} → Computation αComputation α
tail
(
pure: {α : Type ?u.3507} → αComputation α
pure
a: α
a
) =
pure: {α : Type ?u.3511} → αComputation α
pure
a: α
a
:=
rfl: ∀ {α : Sort ?u.3516} {a : α}, a = a
rfl
#align computation.tail_ret
Computation.tail_pure: ∀ {α : Type u} (a : α), tail (pure a) = pure a
Computation.tail_pure
@[simp] theorem
tail_think: ∀ {α : Type u} (s : Computation α), tail (think s) = s
tail_think
(s :
Computation: Type ?u.3546 → Type ?u.3546
Computation
α: Type u
α
) :
tail: {α : Type ?u.3550} → Computation αComputation α
tail
(
think: {α : Type ?u.3552} → Computation αComputation α
think
s) = s :=

Goals accomplished! 🐙
α: Type u

β: Type v

γ: Type w

s: Computation α


tail (think s) = s
α: Type u

β: Type v

γ: Type w

f: Stream' (Option α)

al: ∀ ⦃n : ⦄ ⦃a : α⦄, f n = some af (n + 1) = some a


mk
tail (think { val := f, property := al }) = { val := f, property := al }
α: Type u

β: Type v

γ: Type w

s: Computation α


tail (think s) = s
α: Type u

β: Type v

γ: Type w

f: Stream' (Option α)

al: ∀ ⦃n : ⦄ ⦃a : α⦄, f n = some af (n + 1) = some a


mk
tail (think { val := f, property := al }) = { val := f, property := al }
α: Type u

β: Type v

γ: Type w

s: Computation α


tail (think s) = s
α: Type u

β: Type v

γ: Type w

f: Stream' (Option α)

al: ∀ ⦃n : ⦄ ⦃a : α⦄, f n = some af (n + 1) = some a


mk.a
↑(tail (think { val := f, property := al })) = { val := f, property := al }
α: Type u

β: Type v

γ: Type w

s: Computation α


tail (think s) = s
α: Type u

β: Type v

γ: Type w

f: Stream' (Option α)

al: ∀ ⦃n : ⦄ ⦃a : α⦄, f n = some af (n + 1) = some a


mk.a
↑(tail (think { val := f, property := al })) = { val := f, property := al }
α: Type u

β: Type v

γ: Type w

s: Computation α


tail (think s) = s

Goals accomplished! 🐙
#align computation.tail_think
Computation.tail_think: ∀ {α : Type u} (s : Computation α), tail (think s) = s
Computation.tail_think
@[simp] theorem
tail_empty: ∀ {α : Type u}, tail (empty α) = empty α
tail_empty
:
tail: {α : Type ?u.3711} → Computation αComputation α
tail
(
empty: (α : Type ?u.3713) → Computation α
empty
α: Type u
α
) =
empty: (α : Type ?u.3716) → Computation α
empty
α: Type u
α
:=
rfl: ∀ {α : Sort ?u.3719} {a : α}, a = a
rfl
#align computation.tail_empty
Computation.tail_empty: ∀ {α : Type u}, tail (empty α) = empty α
Computation.tail_empty
theorem
think_empty: empty α = think (empty α)
think_empty
:
empty: (α : Type ?u.3746) → Computation α
empty
α: Type u
α
=
think: {α : Type ?u.3747} → Computation αComputation α
think
(
empty: (α : Type ?u.3749) → Computation α
empty
α: Type u
α
) :=
destruct_eq_think: ∀ {α : Type ?u.3754} {s s' : Computation α}, destruct s = Sum.inr s's = think s'
destruct_eq_think
destruct_empty: ∀ {α : Type ?u.3764}, destruct (empty α) = Sum.inr (empty α)
destruct_empty
#align computation.think_empty
Computation.think_empty: ∀ {α : Type u}, empty α = think (empty α)
Computation.think_empty
/-- Recursion principle for computations, compare with `List.recOn`. -/ def
recOn: {α : Type u} → {C : Computation αSort v} → (s : Computation α) → ((a : α) → C (pure a)) → ((s : Computation α) → C (think s)) → C s
recOn
{
C: Computation αSort v
C
:
Computation: Type ?u.3783 → Type ?u.3783
Computation
α: Type u
α
Sort v: Type v
Sort
Sort v: Type v
v
} (s :
Computation: Type ?u.3787 → Type ?u.3787
Computation
α: Type u
α
) (
h1: (a : α) → C (pure a)
h1
: ∀
a: ?m.3791
a
,
C: Computation αSort v
C
(
pure: {α : Type ?u.3794} → αComputation α
pure
a: ?m.3791
a
)) (
h2: (s : Computation α) → C (think s)
h2
: ∀
s: ?m.3800
s
,
C: Computation αSort v
C
(
think: {α : Type ?u.3803} → Computation αComputation α
think
s: ?m.3800
s
)) :
C: Computation αSort v
C
s := match H: (
destruct: {α : Type ?u.3812} → Computation αα Computation α
destruct
s) with |
Sum.inl: {α : Type ?u.3817} → {β : Type ?u.3816} → αα β
Sum.inl
v: α
v
=>

Goals accomplished! 🐙
α: Type u

β: Type v

γ: Type w

C: Computation αSort v

s: Computation α

h1: (a : α) → C (pure a)

h2: (s : Computation α) → C (think s)

v: α

H: destruct s = Sum.inl v


C s
α: Type u

β: Type v

γ: Type w

C: Computation αSort v

s: Computation α

h1: (a : α) → C (pure a)

h2: (s : Computation α) → C (think s)

v: α

H: destruct s = Sum.inl v


C s
α: Type u

β: Type v

γ: Type w

C: Computation αSort v

s: Computation α

h1: (a : α) → C (pure a)

h2: (s : Computation α) → C (think s)

v: α

H: destruct s = Sum.inl v


C (pure v)
α: Type u

β: Type v

γ: Type w

C: Computation αSort v

s: Computation α

h1: (a : α) → C (pure a)

h2: (s : Computation α) → C (think s)

v: α

H: destruct s = Sum.inl v


C (pure v)
α: Type u

β: Type v

γ: Type w

C: Computation αSort v

s: Computation α

h1: (a : α) → C (pure a)

h2: (s : Computation α) → C (think s)

v: α

H: destruct s = Sum.inl v


C s

Goals accomplished! 🐙
|
Sum.inr: {α : Type ?u.3840} → {β : Type ?u.3839} → βα β
Sum.inr
v => match v with | ⟨
a: Stream' (Option α)
a
,
s': ∀ ⦃n : ⦄ ⦃a_1 : α⦄, a n = some a_1a (n + 1) = some a_1
s'
⟩ =>

Goals accomplished! 🐙
α: Type u

β: Type v

γ: Type w

C: Computation αSort v

s: Computation α

h1: (a : α) → C (pure a)

h2: (s : Computation α) → C (think s)

v: Computation α

a: Stream' (Option α)

s': ∀ ⦃n : ⦄ ⦃a_1 : α⦄, a n = some a_1a (n + 1) = some a_1

H: destruct s = Sum.inr { val := a, property := s' }


C s
α: Type u

β: Type v

γ: Type w

C: Computation αSort v

s: Computation α

h1: (a : α) → C (pure a)

h2: (s : Computation α) → C (think s)

v: Computation α

a: Stream' (Option α)

s': ∀ ⦃n : ⦄ ⦃a_1 : α⦄, a n = some a_1a (n + 1) = some a_1

H: destruct s = Sum.inr { val := a, property := s' }


C s
α: Type u

β: Type v

γ: Type w

C: Computation αSort v

s: Computation α

h1: (a : α) → C (pure a)

h2: (s : Computation α) → C (think s)

v: Computation α

a: Stream' (Option α)

s': ∀ ⦃n : ⦄ ⦃a_1 : α⦄, a n = some a_1a (n + 1) = some a_1

H: destruct s = Sum.inr { val := a, property := s' }


C (think { val := a, property := s' })
α: Type u

β: Type v

γ: Type w

C: Computation αSort v

s: Computation α

h1: (a : α) → C (pure a)

h2: (s : Computation α) → C (think s)

v: Computation α

a: Stream' (Option α)

s': ∀ ⦃n : ⦄ ⦃a_1 : α⦄, a n = some a_1a (n + 1) = some a_1

H: destruct s = Sum.inr { val := a, property := s' }


C (think { val := a, property := s' })
α: Type u

β: Type v

γ: Type w

C: Computation αSort v

s: Computation α

h1: (a : α) → C (pure a)

h2: (s : Computation α) → C (think s)

v: Computation α

a: Stream' (Option α)

s': ∀ ⦃n : ⦄ ⦃a_1 : α⦄, a n = some a_1a (n + 1) = some a_1

H: destruct s = Sum.inr { val := a, property := s' }


C s

Goals accomplished! 🐙
#align computation.rec_on
Computation.recOn: {α : Type u} → {C : Computation αSort v} → (s : Computation α) → ((a : α) → C (pure a)) → ((s : Computation α) → C (think s)) → C s
Computation.recOn
/-- Corecursor constructor for `corec`-/ def
Corec.f: {α : Type u} → {β : Type v} → (βα β) → α βOption α × (α β)
Corec.f
(
f: βα β
f
:
β: Type v
β
Sum: Type ?u.4622 → Type ?u.4621 → Type (max?u.4622?u.4621)
Sum
α: Type u
α
β: Type v
β
) :
Sum: Type ?u.4627 → Type ?u.4626 → Type (max?u.4627?u.4626)
Sum
α: Type u
α
β: Type v
β
Option: Type ?u.4631 → Type ?u.4631
Option
α: Type u
α
×
Sum: Type ?u.4633 → Type ?u.4632 → Type (max?u.4633?u.4632)
Sum
α: Type u
α
β: Type v
β
|
Sum.inl: {α : Type ?u.4640} → {β : Type ?u.4639} → αα β
Sum.inl
a: α
a
=> (
some: {α : Type ?u.4665} → αOption α
some
a: α
a
,
Sum.inl: {α : Type ?u.4669} → {β : Type ?u.4668} → αα β
Sum.inl
a: α
a
) |
Sum.inr: {α : Type ?u.4675} → {β : Type ?u.4674} → βα β
Sum.inr
b: β
b
=> (match
f: βα β
f
b: β
b
with |
Sum.inl: {α : Type ?u.4698} → {β : Type ?u.4697} → αα β
Sum.inl
a: α
a
=>
some: {α : Type ?u.4715} → αOption α
some
a: α
a
|
Sum.inr: {α : Type ?u.4718} → {β : Type ?u.4717} → βα β
Sum.inr
_ =>
none: {α : Type ?u.4736} → Option α
none
,
f: βα β
f
b: β
b
) set_option linter.uppercaseLean3 false in #align computation.corec.F
Computation.Corec.f: {α : Type u} → {β : Type v} → (βα β) → α βOption α × (α β)
Computation.Corec.f
/-- `corec f b` is the corecursor for `Computation α` as a coinductive type. If `f b = inl a` then `corec f b = pure a`, and if `f b = inl b'` then `corec f b = think (corec f b')`. -/ def
corec: {α : Type u} → {β : Type v} → (βα β) → βComputation α
corec
(
f: βα β
f
:
β: Type v
β
Sum: Type ?u.5089 → Type ?u.5088 → Type (max?u.5089?u.5088)
Sum
α: Type u
α
β: Type v
β
) (
b: β
b
:
β: Type v
β
) :
Computation: Type ?u.5094 → Type ?u.5094
Computation
α: Type u
α
:=

Goals accomplished! 🐙
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


α: Type u

β: Type v

γ: Type w

f: βα β

b: β

n:

a': α

h: Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'


α: Type u

β: Type v

γ: Type w

f: βα β

b: β


α: Type u

β: Type v

γ: Type w

f: βα β

b: β

n:

a': α

h: Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'


α: Type u

β: Type v

γ: Type w

f: βα β

b: β

n:

a': α

h: Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'


Stream'.cons (Corec.f f (Sum.inr b)).fst (Stream'.corec' (Corec.f f) (Corec.f f (Sum.inr b)).snd) (n + 1) = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

n:

a': α

h: Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'


Stream'.cons (Corec.f f (Sum.inr b)).fst (Stream'.corec' (Corec.f f) (Corec.f f (Sum.inr b)).snd) (n + 1) = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


α: Type u

β: Type v

γ: Type w

f: βα β

b: β

n:

a': α

h: Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'


α: Type u

β: Type v

γ: Type w

f: βα β

b: β


α: Type u

β: Type v

γ: Type w

f: βα β

b: β

n:

a': α


α: Type u

β: Type v

γ: Type w

f: βα β

b: β

n:

a': α


α: Type u

β: Type v

γ: Type w

f: βα β

b: β


α: Type u

β: Type v

γ: Type w

f: βα β

b: β

n:

a': α

o: α β


Stream'.corec' (Corec.f f) o n = some a'Stream'.corec' (Corec.f f) (Corec.f f o).snd n = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

n:

a': α

o: α β


Stream'.corec' (Corec.f f) o n = some a'Stream'.corec' (Corec.f f) (Corec.f f o).snd n = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


α: Type u

β: Type v

γ: Type w

f: βα β

b: β

n:

a': α


∀ (o : α β), Stream'.corec' (Corec.f f) o n = some a'Stream'.corec' (Corec.f f) (Corec.f f o).snd n = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α


zero
∀ (o : α β), Stream'.corec' (Corec.f f) o Nat.zero = some a'Stream'.corec' (Corec.f f) (Corec.f f o).snd Nat.zero = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

n:

IH: ∀ (o : α β), Stream'.corec' (Corec.f f) o n = some a'Stream'.corec' (Corec.f f) (Corec.f f o).snd n = some a'


succ
∀ (o : α β), Stream'.corec' (Corec.f f) o (Nat.succ n) = some a'Stream'.corec' (Corec.f f) (Corec.f f o).snd (Nat.succ n) = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

n:

a': α


∀ (o : α β), Stream'.corec' (Corec.f f) o n = some a'Stream'.corec' (Corec.f f) (Corec.f f o).snd n = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α


zero
∀ (o : α β), Stream'.corec' (Corec.f f) o Nat.zero = some a'Stream'.corec' (Corec.f f) (Corec.f f o).snd Nat.zero = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

n:

IH: ∀ (o : α β), Stream'.corec' (Corec.f f) o n = some a'Stream'.corec' (Corec.f f) (Corec.f f o).snd n = some a'


succ
∀ (o : α β), Stream'.corec' (Corec.f f) o (Nat.succ n) = some a'Stream'.corec' (Corec.f f) (Corec.f f o).snd (Nat.succ n) = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

n:

a': α


∀ (o : α β), Stream'.corec' (Corec.f f) o n = some a'Stream'.corec' (Corec.f f) (Corec.f f o).snd n = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

o: α β


zero
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

o: α β


zero
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

o: α β


zero
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

n:

IH: ∀ (o : α β), Stream'.corec' (Corec.f f) o n = some a'Stream'.corec' (Corec.f f) (Corec.f f o).snd n = some a'

o: α β


succ
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

o: α β


zero
(Corec.f f o).fst = some a'(Corec.f f (Corec.f f o).snd).fst = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

o: α β


zero
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a', val✝: α


zero.inl
(Corec.f f (Sum.inl val✝)).fst = some a'(Corec.f f (Corec.f f (Sum.inl val✝)).snd).fst = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b✝: β

a': α

b: β


zero.inr
(Corec.f f (Sum.inr b)).fst = some a'(Corec.f f (Corec.f f (Sum.inr b)).snd).fst = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

o: α β


zero
(Corec.f f o).fst = some a'(Corec.f f (Corec.f f o).snd).fst = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a', val✝: α


zero.inl
(Corec.f f (Sum.inl val✝)).fst = some a'(Corec.f f (Corec.f f (Sum.inl val✝)).snd).fst = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b✝: β

a': α

b: β


zero.inr
(Corec.f f (Sum.inr b)).fst = some a'(Corec.f f (Corec.f f (Sum.inr b)).snd).fst = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

o: α β


zero
(Corec.f f o).fst = some a'(Corec.f f (Corec.f f o).snd).fst = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a', val✝: α

h: (Corec.f f (Sum.inl val✝)).fst = some a'


zero.inl
(Corec.f f (Corec.f f (Sum.inl val✝)).snd).fst = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

o: α β


zero
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a', val✝: α

h: (Corec.f f (Sum.inl val✝)).fst = some a'


zero.inl
(Corec.f f (Corec.f f (Sum.inl val✝)).snd).fst = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a', val✝: α

h: (Corec.f f (Sum.inl val✝)).fst = some a'


zero.inl
(Corec.f f (Corec.f f (Sum.inl val✝)).snd).fst = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b✝: β

a': α

b: β

h: (Corec.f f (Sum.inr b)).fst = some a'


zero.inr
(Corec.f f (Corec.f f (Sum.inr b)).snd).fst = some a'

Goals accomplished! 🐙
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

o: α β


zero
α: Type u

β: Type v

γ: Type w

f: βα β

b✝: β

a': α

b: β

h: (match Sum.inr b with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)).fst = some a'


zero.inr
(match (match Sum.inr b with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)).snd with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)).fst = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b✝: β

a': α

b: β

h: (match Sum.inr b with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)).fst = some a'


zero.inr
(match (match Sum.inr b with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)).snd with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)).fst = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

o: α β


zero
α: Type u

β: Type v

γ: Type w

f: βα β

b✝: β

a': α

b: β

h: (match Sum.inr b with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)).fst = some a'

x✝: α β

a✝: α

heq✝: (match Sum.inr b with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)).snd = Sum.inl a✝


zero.inr.h_1
(some a✝, Sum.inl a✝).fst = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b✝: β

a': α

b: β

h: (match Sum.inr b with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)).fst = some a'

x✝: α β

val✝: β

heq✝: (match Sum.inr b with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)).snd = Sum.inr val✝


zero.inr.h_2
(match f val✝ with | Sum.inl a => some a | Sum.inr val => none, f val✝).fst = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b✝: β

a': α

b: β

h: (match Sum.inr b with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)).fst = some a'


zero.inr
(match (match Sum.inr b with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)).snd with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)).fst = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b✝: β

a': α

b: β

h: (match Sum.inr b with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)).fst = some a'

x✝: α β

a✝: α

heq✝: (match Sum.inr b with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)).snd = Sum.inl a✝


zero.inr.h_1
(some a✝, Sum.inl a✝).fst = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b✝: β

a': α

b: β

h: (match Sum.inr b with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)).fst = some a'

x✝: α β

val✝: β

heq✝: (match Sum.inr b with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)).snd = Sum.inr val✝


zero.inr.h_2
(match f val✝ with | Sum.inl a => some a | Sum.inr val => none, f val✝).fst = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b✝: β

a': α

b: β

h: (match Sum.inr b with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)).fst = some a'


zero.inr
(match (match Sum.inr b with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)).snd with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)).fst = some a'

Goals accomplished! 🐙
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

n:

IH: ∀ (o : α β), Stream'.corec' (Corec.f f) o n = some a'Stream'.corec' (Corec.f f) (Corec.f f o).snd n = some a'

o: α β


succ
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

n:

IH: ∀ (o : α β), Stream'.corec' (Corec.f f) o n = some a'Stream'.corec' (Corec.f f) (Corec.f f o).snd n = some a'

o: α β


succ
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

n:

IH: ∀ (o : α β), Stream'.corec' (Corec.f f) o n = some a'Stream'.corec' (Corec.f f) (Corec.f f o).snd n = some a'

o: α β


succ
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

n:

IH: ∀ (o : α β), Stream'.corec' (Corec.f f) o n = some a'Stream'.corec' (Corec.f f) (Corec.f f o).snd n = some a'

o: α β


succ
Stream'.corec' (Corec.f f) o (Nat.succ n) = some a'Stream'.cons (Corec.f f (Corec.f f o).snd).fst (Stream'.corec' (Corec.f f) (Corec.f f (Corec.f f o).snd).snd) (Nat.succ n) = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

n:

IH: ∀ (o : α β), Stream'.corec' (Corec.f f) o n = some a'Stream'.corec' (Corec.f f) (Corec.f f o).snd n = some a'

o: α β


succ
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

n:

IH: ∀ (o : α β), Stream'.corec' (Corec.f f) o n = some a'Stream'.corec' (Corec.f f) (Corec.f f o).snd n = some a'

o: α β


succ
Stream'.cons (Corec.f f o).fst (Stream'.corec' (Corec.f f) (Corec.f f o).snd) (Nat.succ n) = some a'Stream'.cons (Corec.f f (Corec.f f o).snd).fst (Stream'.corec' (Corec.f f) (Corec.f f (Corec.f f o).snd).snd) (Nat.succ n) = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

n:

IH: ∀ (o : α β), Stream'.corec' (Corec.f f) o n = some a'Stream'.corec' (Corec.f f) (Corec.f f o).snd n = some a'

o: α β


succ
Stream'.cons (Corec.f f o).fst (Stream'.corec' (Corec.f f) (Corec.f f o).snd) (Nat.succ n) = some a'Stream'.cons (Corec.f f (Corec.f f o).snd).fst (Stream'.corec' (Corec.f f) (Corec.f f (Corec.f f o).snd).snd) (Nat.succ n) = some a'
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

a': α

n:

IH: ∀ (o : α β), Stream'.corec' (Corec.f f) o n = some a'Stream'.corec' (Corec.f f) (Corec.f f o).snd n = some a'

o: α β


succ

Goals accomplished! 🐙
#align computation.corec
Computation.corec: {α : Type u} → {β : Type v} → (βα β) → βComputation α
Computation.corec
/-- left map of `⊕` -/ def
lmap: {α : Type u} → {β : Type v} → {γ : Type w} → (αβ) → α γβ γ
lmap
(
f: αβ
f
:
α: Type u
α
β: Type v
β
) :
Sum: Type ?u.7866 → Type ?u.7865 → Type (max?u.7866?u.7865)
Sum
α: Type u
α
γ: Type w
γ
Sum: Type ?u.7869 → Type ?u.7868 → Type (max?u.7869?u.7868)
Sum
β: Type v
β
γ: Type w
γ
|
Sum.inl: {α : Type ?u.7876} → {β : Type ?u.7875} → αα β
Sum.inl
a: α
a
=>
Sum.inl: {α : Type ?u.7896} → {β : Type ?u.7895} → αα β
Sum.inl
(
f: αβ
f
a: α
a
) |
Sum.inr: {α : Type ?u.7902} → {β : Type ?u.7901} → βα β
Sum.inr
b: γ
b
=>
Sum.inr: {α : Type ?u.7920} → {β : Type ?u.7919} → βα β
Sum.inr
b: γ
b
#align computation.lmap
Computation.lmap: {α : Type u} → {β : Type v} → {γ : Type w} → (αβ) → α γβ γ
Computation.lmap
/-- right map of `⊕` -/ def
rmap: (βγ) → α βα γ
rmap
(
f: βγ
f
:
β: Type v
β
γ: Type w
γ
) :
Sum: Type ?u.8106 → Type ?u.8105 → Type (max?u.8106?u.8105)
Sum
α: Type u
α
β: Type v
β
Sum: Type ?u.8109 → Type ?u.8108 → Type (max?u.8109?u.8108)
Sum
α: Type u
α
γ: Type w
γ
|
Sum.inl: {α : Type ?u.8116} → {β : Type ?u.8115} → αα β
Sum.inl
a: α
a
=>
Sum.inl: {α : Type ?u.8136} → {β : Type ?u.8135} → αα β
Sum.inl
a: α
a
|
Sum.inr: {α : Type ?u.8142} → {β : Type ?u.8141} → βα β
Sum.inr
b: β
b
=>
Sum.inr: {α : Type ?u.8160} → {β : Type ?u.8159} → βα β
Sum.inr
(
f: βγ
f
b: β
b
) #align computation.rmap
Computation.rmap: {α : Type u} → {β : Type v} → {γ : Type w} → (βγ) → α βα γ
Computation.rmap
attribute [simp]
lmap: {α : Type u} → {β : Type v} → {γ : Type w} → (αβ) → α γβ γ
lmap
rmap: {α : Type u} → {β : Type v} → {γ : Type w} → (βγ) → α βα γ
rmap
-- porting note: this was far less painful in mathlib3. There seem to be two issues; -- firstly, in mathlib3 we have `corec.F._match_1` and it's the obvious map α ⊕ β → option α. -- In mathlib4 we have `Corec.f.match_1` and it's something completely different. -- Secondly, the proof that `Stream'.corec' (Corec.f f) (Sum.inr b) 0` is this function -- evaluated at `f b`, used to be `rfl` and now is `cases, rfl`. @[simp] theorem
corec_eq: ∀ {α : Type u} {β : Type v} (f : βα β) (b : β), destruct (corec f b) = rmap (corec f) (f b)
corec_eq
(
f: βα β
f
:
β: Type v
β
Sum: Type ?u.8343 → Type ?u.8342 → Type (max?u.8343?u.8342)
Sum
α: Type u
α
β: Type v
β
) (
b: β
b
:
β: Type v
β
) :
destruct: {α : Type ?u.8349} → Computation αα Computation α
destruct
(
corec: {α : Type ?u.8352} → {β : Type ?u.8351} → (βα β) → βComputation α
corec
f: βα β
f
b: β
b
) =
rmap: {α : Type ?u.8366} → {β : Type ?u.8365} → {γ : Type ?u.8364} → (βγ) → α βα γ
rmap
(
corec: {α : Type ?u.8371} → {β : Type ?u.8370} → (βα β) → βComputation α
corec
f: βα β
f
) (
f: βα β
f
b: β
b
) :=

Goals accomplished! 🐙
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


destruct (corec f b) = rmap (corec f) (f b)
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


(match Stream'.corec' (Corec.f f) (Sum.inr b) 0 with | none => Sum.inr (tail { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }) | some a => Sum.inl a) = match f b with | Sum.inl a => Sum.inl a | Sum.inr b => Sum.inr { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


destruct (corec f b) = rmap (corec f) (f b)
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


(match Stream'.corec' (Corec.f f) (Sum.inr b) 0 with | none => Sum.inr (tail { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }) | some a => Sum.inl a) = match f b with | Sum.inl a => Sum.inl a | Sum.inr b => Sum.inr { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


(match Stream'.corec' (Corec.f f) (Sum.inr b) 0 with | none => Sum.inr (tail { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }) | some a => Sum.inl a) = match f b with | Sum.inl a => Sum.inl a | Sum.inr b => Sum.inr { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


(match f b with | Sum.inl a => some a | Sum.inr val => none) = Sum.rec some (fun x => none) (f b)
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


Stream'.corec' (Corec.f f) (Sum.inr b) 0 = Sum.rec some (fun x => none) (f b)
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


(match f b with | Sum.inl a => some a | Sum.inr val => none) = Sum.rec some (fun x => none) (f b)
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

x: α


(match Sum.inl x with | Sum.inl a => some a | Sum.inr val => none) = Sum.rec some (fun x => none) (Sum.inl x)
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


(match f b with | Sum.inl a => some a | Sum.inr val => none) = Sum.rec some (fun x => none) (f b)

Goals accomplished! 🐙
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


(match f b with | Sum.inl a => some a | Sum.inr val => none) = Sum.rec some (fun x => none) (f b)
α: Type u

β: Type v

γ: Type w

f: βα β

b, x: β


(match Sum.inr x with | Sum.inl a => some a | Sum.inr val => none) = Sum.rec some (fun x => none) (Sum.inr x)
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


(match f b with | Sum.inl a => some a | Sum.inr val => none) = Sum.rec some (fun x => none) (f b)

Goals accomplished! 🐙
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


(match Stream'.corec' (Corec.f f) (Sum.inr b) 0 with | none => Sum.inr (tail { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }) | some a => Sum.inl a) = match f b with | Sum.inl a => Sum.inl a | Sum.inr b => Sum.inr { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


(match Sum.rec some (fun x => none) (f b) with | none => Sum.inr (tail { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }) | some a => Sum.inl a) = match f b with | Sum.inl a => Sum.inl a | Sum.inr b => Sum.inr { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


destruct (corec f b) = rmap (corec f) (f b)
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

x✝: α β

h✝: f b = x✝

a: α

h: f b = Sum.inl a


inl
(match Sum.rec some (fun x => none) (Sum.inl a) with | none => Sum.inr (tail { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }) | some a => Sum.inl a) = match Sum.inl a with | Sum.inl a => Sum.inl a | Sum.inr b => Sum.inr { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

x✝: α β

h✝: f b = x✝

b': β

h: f b = Sum.inr b'


inr
(match Sum.rec some (fun x => none) (Sum.inr b') with | none => Sum.inr (tail { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }) | some a => Sum.inl a) = match Sum.inr b' with | Sum.inl a => Sum.inl a | Sum.inr b => Sum.inr { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

x✝: α β

h✝: f b = x✝

a: α

h: f b = Sum.inl a


inl
(match Sum.rec some (fun x => none) (Sum.inl a) with | none => Sum.inr (tail { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }) | some a => Sum.inl a) = match Sum.inl a with | Sum.inl a => Sum.inl a | Sum.inr b => Sum.inr { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

x✝: α β

h✝: f b = x✝

b': β

h: f b = Sum.inr b'


inr
(match Sum.rec some (fun x => none) (Sum.inr b') with | none => Sum.inr (tail { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }) | some a => Sum.inl a) = match Sum.inr b' with | Sum.inl a => Sum.inl a | Sum.inr b => Sum.inr { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


destruct (corec f b) = rmap (corec f) (f b)
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

x✝: α β

h✝: f b = x✝

a: α

h: f b = Sum.inl a


inl
(match Sum.rec some (fun x => none) (Sum.inl a) with | none => Sum.inr (tail { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }) | some a => Sum.inl a) = match Sum.inl a with | Sum.inl a => Sum.inl a | Sum.inr b => Sum.inr { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

x✝: α β

h✝: f b = x✝

a: α

h: f b = Sum.inl a


inl
(match Sum.rec some (fun x => none) (Sum.inl a) with | none => Sum.inr (tail { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }) | some a => Sum.inl a) = match Sum.inl a with | Sum.inl a => Sum.inl a | Sum.inr b => Sum.inr { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

x✝: α β

h✝: f b = x✝

b': β

h: f b = Sum.inr b'


inr
(match Sum.rec some (fun x => none) (Sum.inr b') with | none => Sum.inr (tail { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }) | some a => Sum.inl a) = match Sum.inr b' with | Sum.inl a => Sum.inl a | Sum.inr b => Sum.inr { val := Stream'.corec' (Corec.f f) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }

Goals accomplished! 🐙
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


destruct (corec f b) = rmap (corec f) (f b)
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

x✝: α β

h✝: f b = x✝

b': β

h: f b = Sum.inr b'


inr
Sum.inr (tail { val := Stream'.corec' (fun x => match x with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }) = Sum.inr { val := Stream'.corec' (fun x => match x with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)) (Sum.inr b'), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b') n = some a'Stream'.corec' (Corec.f f) (Sum.inr b') (n + 1) = some a') }
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


destruct (corec f b) = rmap (corec f) (f b)
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

x✝: α β

h✝: f b = x✝

b': β

h: f b = Sum.inr b'


inr.h
tail { val := Stream'.corec' (fun x => match x with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') } = { val := Stream'.corec' (fun x => match x with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)) (Sum.inr b'), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b') n = some a'Stream'.corec' (Corec.f f) (Sum.inr b') (n + 1) = some a') }
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

x✝: α β

h✝: f b = x✝

b': β

h: f b = Sum.inr b'


inr.h
tail { val := Stream'.corec' (fun x => match x with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') } = { val := Stream'.corec' (fun x => match x with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)) (Sum.inr b'), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b') n = some a'Stream'.corec' (Corec.f f) (Sum.inr b') (n + 1) = some a') }
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


destruct (corec f b) = rmap (corec f) (f b)
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

x✝: α β

h✝: f b = x✝

b': β

h: f b = Sum.inr b'


inr.h.a
↑(tail { val := Stream'.corec' (fun x => match x with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)) (Sum.inr b), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b) n = some a'Stream'.corec' (Corec.f f) (Sum.inr b) (n + 1) = some a') }) = { val := Stream'.corec' (fun x => match x with | Sum.inl a => (some a, Sum.inl a) | Sum.inr b => (match f b with | Sum.inl a => some a | Sum.inr val => none, f b)) (Sum.inr b'), property := (_ : ∀ (n : ) (a' : α), Stream'.corec' (Corec.f f) (Sum.inr b') n = some a'Stream'.corec' (Corec.f f) (Sum.inr b') (n + 1) = some a') }
α: Type u

β: Type v

γ: Type w

f: βα β

b: β


destruct (corec f b) = rmap (corec f) (f b)
α: Type u

β: Type v

γ: Type w

f: βα β

b: β

x✝: α β

h✝: f b = x✝

b': β

h: f b = Sum.inr b'