Built with Alectryon, running Coq+SerAPI v8.19.0+0.19.3. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use ⌘ instead of Ctrl.
(* Lecture 23 demonstrates two key concepts in Coq: 1. Coinductive streams and stream operations 2. The Knaster-Tarski fixed point theorem *)Require Import List.Import ListNotations.(* Section 1: Infinite streams and operations on them *)Sectionstreams.(* A stream is an infinite sequence of values of type T. It has a head (current value) and tail (remaining infinite sequence) *)CoInductivestream (T : Type) : Type := {
hd: T;
tl: stream T
}.(* Create an infinite stream that repeats a single value *)CoFixpointrepeat (x : nat) : stream nat := {|
hd := x;
tl := repeat x
|}.(* Make head and tail functions easier to use by inferring type T *)Arguments hd {T} _.Arguments tl {T} _.(* Get the nth element of a stream *)Fixpointlookup {T} (n : nat) (s : stream T) : T :=
match n with
| 0 => hd s
| S n' => lookup n' (tl s)
end.(* Example computation *)
= 18
: nat
(* Create a stream from a function mapping natural numbers to values *)CoFixpointfrom_function {T} (f : nat -> T) : stream T := {|
hd := f 0;
tl := from_function (funn => f (S n))
|}.(* Looking up the nth element of a stream created from function f gives the same result as applying f to n directly *)
T: Type f: nat -> T n: nat
lookup n (from_function f) = f n
T: Type f: nat -> T n: nat
lookup n (from_function f) = f n
T: Type n: nat
forallf : nat -> T, lookup n (from_function f) = f n
T: Type f: nat -> T
f 0 = f 0
T: Type n: nat IHn: forallf : nat -> T, lookup n (from_function f) = f n f: nat -> T
lookup n (from_function (funn : nat => f (S n))) =
f (S n)
T: Type f: nat -> T
f 0 = f 0
reflexivity.
T: Type n: nat IHn: forallf : nat -> T, lookup n (from_function f) = f n f: nat -> T
lookup n (from_function (funn : nat => f (S n))) =
f (S n)
apply IHn.Qed.(* Pointwise addition of two streams of natural numbers *)CoFixpointadd_stream (s1s2 : stream nat) : stream nat := {|
hd := hd s1 + hd s2;
tl := add_stream (tl s1) (tl s2)
|}.(* Limits of Coq's productivity checker *)(* This definition fails because Coq can't see that the definition is productive due to the add_stream call. *)
The command has indeed failed with message:
Recursive definition of mult_stream is ill-formed.
In environment
mult_stream : stream nat -> stream nat -> stream nat
s1 : stream nat
s2 : stream nat
Unguarded recursive call in"cofix add_stream (s1 s2 : stream nat) : stream nat := {| hd := hd s1 + hd s2; tl := add_stream (tl s1) (tl s2) |}".
Recursive definition is:
"fun s1 s2 : stream nat => {| hd := hd s1 * hd s2; tl := add_stream (mult_stream (tl s1) s2) (mult_stream s1 (tl s2)) |}".
(* Coinductive definition of stream equality - two streams are equal if their heads are equal and their tails are equal *)CoInductivestream_eq {T} (s1s2 : stream T) : Prop := {
head_eq : hd s1 = hd s2;
tail_eq : stream_eq (tl s1) (tl s2)
}.(* Stream equality is reflexive *)
T: Type s: stream T
stream_eq s s
T: Type s: stream T
stream_eq s s
T: Type
foralls : stream T, stream_eq s s
T: Type IH: foralls : stream T, stream_eq s s
foralls : stream T, stream_eq s s
T: Type IH: foralls : stream T, stream_eq s s s: stream T
stream_eq s s
T: Type IH: foralls : stream T, stream_eq s s s: stream T
hd s = hd s
T: Type IH: foralls : stream T, stream_eq s s s: stream T
stream_eq (tl s) (tl s)
T: Type IH: foralls : stream T, stream_eq s s s: stream T
hd s = hd s
reflexivity.
T: Type IH: foralls : stream T, stream_eq s s s: stream T
stream_eq (tl s) (tl s)
apply IH.Qed.(* Adding two constant streams gives a constant stream with the sum *)
apply IH.Qed.Endstreams.(* Section 2: The Knaster-Tarski fixed point theorem and complete lattices *)Sectionknaster_tarski.(* A set is modeled as a predicate - a function from A to Prop *)Definitionset (A : Type) := A -> Prop.(* A lattice consists of: - A partial order relation (le) - A least upper bound operation (cup) *)ClassLattice (L : Type) := {
le : L -> L -> Prop;
cup : set L -> L;
}.(* Convenient notation for le *)Notation"x <= y" := (le x y).(* Laws that a lattice must satisfy *)ClassLatticeLaws (L : Type) `{Lattice L} := {
le_refl : forallx, x <= x; (* Reflexivity *)
le_trans : forallxyz, x <= y -> y <= z -> x <= z; (* Transitivity *)
le_asym : forallxy, x <= y -> y <= x -> x = y; (* Antisymmetry *)
le_cup : forall (X : set L) y, X y -> y <= (cup X); (* cup is an upper bound *)
cup_le : forall (X : set L) y, (forallx, X x -> x <= y) -> cup X <= y (* cup is least *)
}.(* Hints for automation *)LocalHint Resolve le_refl le_asym le_cup cup_le : lat.LocalHint Extern1 (?x <= ?y) => eapply le_trans; [solve [eauto2]|] : lat.LocalHint Extern1 (?x <= ?y) => eapply le_trans; [|solve [eauto2]] : lat.(* Greatest lower bound operation defined in terms of cup *)Definitioncap {L} `{Lattice L} (X : set L) : L :=
cup (funy => forallx, X x -> y <= x).(* cap is a lower bound *)
L: Type H: Lattice L H0: LatticeLaws L X: set L y: L
X y -> cap X <= y
L: Type H: Lattice L H0: LatticeLaws L X: set L y: L
X y -> cap X <= y
L: Type H: Lattice L H0: LatticeLaws L X: set L y: L
X y ->
cup (funy : L => forallx : L, X x -> y <= x) <= y
eauto with lat.Qed.(* cap is the greatest lower bound *)
L: Type H: Lattice L H0: LatticeLaws L X: set L y: L
(forallx : L, X x -> y <= x) -> y <= cap X
L: Type H: Lattice L H0: LatticeLaws L X: set L y: L
(forallx : L, X x -> y <= x) -> y <= cap X
L: Type H: Lattice L H0: LatticeLaws L X: set L y: L
(forallx : L, X x -> y <= x) ->
y <= cup (funy : L => forallx : L, X x -> y <= x)
eauto with lat.Qed.LocalHint Resolve cap_le le_cap : lat.(* The powerset lattice - sets ordered by inclusion *)Global Instanceset_lattice (T : Type) : Lattice (set T) := {
le x y := forallt, x t -> y t;
cup X := funt => existsx, X x /\ x t
}.(* Axioms needed for function and proposition extensionality *)Axiomfunext : forall {TU} (fg : T -> U), (forallx, f x = g x) -> f = g.Axiompropext : forallPQ : Prop, (P <-> Q) -> P = Q.(* Prove that set_lattice satisfies the lattice laws *)
T: Type
LatticeLaws (set T)
T: Type
LatticeLaws (set T)
T: Type
forallxy : set T,
(forallt : T, x t -> y t) ->
(forallt : T, y t -> x t) -> x = y
T: Type
forall (X : set (set T)) (y : set T),
(forallx : set T, X x -> forallt : T, x t -> y t) ->
forallt : T, (existsx : set T, X x /\ x t) -> y t
T: Type
forallxy : set T,
(forallt : T, x t -> y t) ->
(forallt : T, y t -> x t) -> x = y
T: Type x, y: set T H: forallt : T, x t -> y t H0: forallt : T, y t -> x t
x = y
T: Type x, y: set T H: forallt : T, x t -> y t H0: forallt : T, y t -> x t
forallx0 : T, x x0 = y x0
T: Type x, y: set T H: forallt : T, x t -> y t H0: forallt : T, y t -> x t x0: T
x x0 = y x0
T: Type x, y: set T H: forallt : T, x t -> y t H0: forallt : T, y t -> x t x0: T
x x0 <-> y x0
split; eauto.
T: Type
forall (X : set (set T)) (y : set T),
(forallx : set T, X x -> forallt : T, x t -> y t) ->
forallt : T, (existsx : set T, X x /\ x t) -> y t
T: Type X: set (set T) y: set T H: forallx : set T, X x -> forallt : T, x t -> y t t: T H0: existsx : set T, X x /\ x t
y t
T: Type X: set (set T) y: set T H: forallx : set T, X x -> forallt : T, x t -> y t t: T x: set T H0: X x H1: x t
y t
eauto.Qed.(* A function is monotone if it preserves order *)Definitionmono {L} `{Lattice L} (f : L -> L) :=
forallxy, x <= y -> f x <= f y.(* omega contains all the iterates of f - both limits and successors *)Inductiveomega {L} `{Lattice L} (f : L -> L) : set L :=
| omega_lim (X : set L) : (forallx, X x -> omega f x) -> omega f (cup X)
| omega_suc x : omega f x -> omega f (f x).Hint Constructors omega : lat.(* For monotone functions, elements of omega increase under f *)
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L
mono f -> omega f x -> x <= f x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L
mono f -> omega f x -> x <= f x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L Hmono: mono f HO: omega f x
x <= f x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L Hmono: mono f X: set L H1: forallx : L, X x -> omega f x H2: forallx : L, X x -> x <= f x
cup X <= f (cup X)
L: Type H: Lattice L H0: LatticeLaws L f: L -> L Hmono: mono f x: L HO: omega f x IHHO: x <= f x
f x <= f (f x)
L: Type H: Lattice L H0: LatticeLaws L f: L -> L Hmono: mono f X: set L H1: forallx : L, X x -> omega f x H2: forallx : L, X x -> x <= f x
cup X <= f (cup X)
eauto with lat.
L: Type H: Lattice L H0: LatticeLaws L f: L -> L Hmono: mono f x: L HO: omega f x IHHO: x <= f x
f x <= f (f x)
eauto with lat.Qed.LocalHint Resolve omega_incr : lat.(* cup omega is a fixed point *)
L: Type H: Lattice L H0: LatticeLaws L f: L -> L
mono f -> f (cup (omega f)) = cup (omega f)
L: Type H: Lattice L H0: LatticeLaws L f: L -> L
mono f -> f (cup (omega f)) = cup (omega f)
eauto7with lat.Qed.(* cup omega is the least fixed point *)
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L
mono f -> f x <= x -> cup (omega f) <= x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L
mono f -> f x <= x -> cup (omega f) <= x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L Hmono: mono f Hle: f x <= x
cup (omega f) <= x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L Hmono: mono f Hle: f x <= x
forallx0 : L, omega f x0 -> x0 <= x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L Hmono: mono f Hle: f x <= x y: L Hy: omega f y
y <= x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L Hmono: mono f Hle: f x <= x X: set L H1: forallx : L, X x -> omega f x H2: forallx0 : L, X x0 -> x0 <= x
cup X <= x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L Hmono: mono f Hle: f x <= x x0: L Hy: omega f x0 IHHy: x0 <= x
f x0 <= x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L Hmono: mono f Hle: f x <= x X: set L H1: forallx : L, X x -> omega f x H2: forallx0 : L, X x0 -> x0 <= x
cup X <= x
eauto with lat.
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L Hmono: mono f Hle: f x <= x x0: L Hy: omega f x0 IHHy: x0 <= x
f x0 <= x
eauto with lat.Qed.(* Induction principle for omega *)
L: Type H: Lattice L H0: LatticeLaws L f: L -> L
forallP : L -> Prop,
(forallX : set L,
(forallx : L, X x -> omega f x) ->
(forallx : L, X x -> P x) -> P (cup X)) ->
(forallx : L, omega f x -> P x -> P (f x)) ->
P (cup (omega f))
L: Type H: Lattice L H0: LatticeLaws L f: L -> L
forallP : L -> Prop,
(forallX : set L,
(forallx : L, X x -> omega f x) ->
(forallx : L, X x -> P x) -> P (cup X)) ->
(forallx : L, omega f x -> P x -> P (f x)) ->
P (cup (omega f))
L: Type H: Lattice L H0: LatticeLaws L f: L -> L P: L -> Prop Hlim: forallX : set L,
(forallx : L, X x -> omega f x) ->
(forallx : L, X x -> P x) -> P (cup X) Hsuc: forallx : L, omega f x -> P x -> P (f x)
P (cup (omega f))
L: Type H: Lattice L H0: LatticeLaws L f: L -> L P: L -> Prop Hlim: forallX : set L,
(forallx : L, X x -> omega f x) ->
(forallx : L, X x -> P x) -> P (cup X) Hsuc: forallx : L, omega f x -> P x -> P (f x)
forallx : L, omega f x -> omega f x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L P: L -> Prop Hlim: forallX : set L,
(forallx : L, X x -> omega f x) ->
(forallx : L, X x -> P x) -> P (cup X) Hsuc: forallx : L, omega f x -> P x -> P (f x)
forallx : L, omega f x -> P x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L P: L -> Prop Hlim: forallX : set L,
(forallx : L, X x -> omega f x) ->
(forallx : L, X x -> P x) -> P (cup X) Hsuc: forallx : L, omega f x -> P x -> P (f x)
forallx : L, omega f x -> omega f x
eauto.
L: Type H: Lattice L H0: LatticeLaws L f: L -> L P: L -> Prop Hlim: forallX : set L,
(forallx : L, X x -> omega f x) ->
(forallx : L, X x -> P x) -> P (cup X) Hsuc: forallx : L, omega f x -> P x -> P (f x)
forallx : L, omega f x -> P x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L P: L -> Prop Hlim: forallX : set L,
(forallx : L, X x -> omega f x) ->
(forallx : L, X x -> P x) -> P (cup X) Hsuc: forallx : L, omega f x -> P x -> P (f x) x: L Hx: omega f x
P x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L P: L -> Prop Hlim: forallX : set L,
(forallx : L, X x -> omega f x) ->
(forallx : L, X x -> P x) -> P (cup X) Hsuc: forallx : L, omega f x -> P x -> P (f x) X: set L H1: forallx : L, X x -> omega f x H2: forallx : L, X x -> P x
P (cup X)
L: Type H: Lattice L H0: LatticeLaws L f: L -> L P: L -> Prop Hlim: forallX : set L,
(forallx : L, X x -> omega f x) ->
(forallx : L, X x -> P x) -> P (cup X) Hsuc: forallx : L, omega f x -> P x -> P (f x) x: L Hx: omega f x IHHx: P x
P (f x)
L: Type H: Lattice L H0: LatticeLaws L f: L -> L P: L -> Prop Hlim: forallX : set L,
(forallx : L, X x -> omega f x) ->
(forallx : L, X x -> P x) -> P (cup X) Hsuc: forallx : L, omega f x -> P x -> P (f x) X: set L H1: forallx : L, X x -> omega f x H2: forallx : L, X x -> P x
P (cup X)
eauto.
L: Type H: Lattice L H0: LatticeLaws L f: L -> L P: L -> Prop Hlim: forallX : set L,
(forallx : L, X x -> omega f x) ->
(forallx : L, X x -> P x) -> P (cup X) Hsuc: forallx : L, omega f x -> P x -> P (f x) x: L Hx: omega f x IHHx: P x
P (f x)
eauto.Qed.(* Now the same, but for the greatest fixed point *)InductiveOmega {L} `{Lattice L} (f : L -> L) : set L :=
| Omega_lim (X : set L) : (forallx, X x -> Omega f x) -> Omega f (cap X)
| Omega_suc x : Omega f x -> Omega f (f x).Hint Constructors Omega : lat.(* For monotone functions, elements of Omega decrease under f *)
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L
mono f -> Omega f x -> f x <= x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L
mono f -> Omega f x -> f x <= x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L Hmono: mono f HO: Omega f x
f x <= x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L Hmono: mono f X: set L H1: forallx : L, X x -> Omega f x H2: forallx : L, X x -> f x <= x
f (cap X) <= cap X
L: Type H: Lattice L H0: LatticeLaws L f: L -> L Hmono: mono f x: L HO: Omega f x IHHO: f x <= x
f (f x) <= f x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L Hmono: mono f X: set L H1: forallx : L, X x -> Omega f x H2: forallx : L, X x -> f x <= x
f (cap X) <= cap X
eauto with lat.
L: Type H: Lattice L H0: LatticeLaws L f: L -> L Hmono: mono f x: L HO: Omega f x IHHO: f x <= x
f (f x) <= f x
eauto with lat.Qed.LocalHint Resolve Omega_decr : lat.(* cap Omega is a fixed point *)
L: Type H: Lattice L H0: LatticeLaws L f: L -> L
mono f -> f (cap (Omega f)) = cap (Omega f)
L: Type H: Lattice L H0: LatticeLaws L f: L -> L
mono f -> f (cap (Omega f)) = cap (Omega f)
eauto7with lat.Qed.(* cap Omega is the greatest fixed point *)
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L
mono f -> x <= f x -> x <= cap (Omega f)
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L
mono f -> x <= f x -> x <= cap (Omega f)
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L Hmono: mono f Hle: x <= f x
x <= cap (Omega f)
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L Hmono: mono f Hle: x <= f x
forallx0 : L, Omega f x0 -> x <= x0
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L Hmono: mono f Hle: x <= f x y: L Hy: Omega f y
x <= y
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L Hmono: mono f Hle: x <= f x X: set L H1: forallx : L, X x -> Omega f x H2: forallx0 : L, X x0 -> x <= x0
x <= cap X
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L Hmono: mono f Hle: x <= f x x0: L Hy: Omega f x0 IHHy: x <= x0
x <= f x0
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L Hmono: mono f Hle: x <= f x X: set L H1: forallx : L, X x -> Omega f x H2: forallx0 : L, X x0 -> x <= x0
x <= cap X
eauto with lat.
L: Type H: Lattice L H0: LatticeLaws L f: L -> L x: L Hmono: mono f Hle: x <= f x x0: L Hy: Omega f x0 IHHy: x <= x0
x <= f x0
eauto with lat.Qed.LocalHint Resolve Omega_fix Omega_gfp : lat.(* Induction principle for Omega *)
L: Type H: Lattice L H0: LatticeLaws L f: L -> L
forallP : L -> Prop,
(forallX : set L,
(forallx : L, X x -> Omega f x) ->
(forallx : L, X x -> P x) -> P (cap X)) ->
(forallx : L, Omega f x -> P x -> P (f x)) ->
P (cap (Omega f))
L: Type H: Lattice L H0: LatticeLaws L f: L -> L
forallP : L -> Prop,
(forallX : set L,
(forallx : L, X x -> Omega f x) ->
(forallx : L, X x -> P x) -> P (cap X)) ->
(forallx : L, Omega f x -> P x -> P (f x)) ->
P (cap (Omega f))
L: Type H: Lattice L H0: LatticeLaws L f: L -> L P: L -> Prop Hlim: forallX : set L,
(forallx : L, X x -> Omega f x) ->
(forallx : L, X x -> P x) -> P (cap X) Hsuc: forallx : L, Omega f x -> P x -> P (f x)
P (cap (Omega f))
L: Type H: Lattice L H0: LatticeLaws L f: L -> L P: L -> Prop Hlim: forallX : set L,
(forallx : L, X x -> Omega f x) ->
(forallx : L, X x -> P x) -> P (cap X) Hsuc: forallx : L, Omega f x -> P x -> P (f x)
forallx : L, Omega f x -> Omega f x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L P: L -> Prop Hlim: forallX : set L,
(forallx : L, X x -> Omega f x) ->
(forallx : L, X x -> P x) -> P (cap X) Hsuc: forallx : L, Omega f x -> P x -> P (f x)
forallx : L, Omega f x -> P x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L P: L -> Prop Hlim: forallX : set L,
(forallx : L, X x -> Omega f x) ->
(forallx : L, X x -> P x) -> P (cap X) Hsuc: forallx : L, Omega f x -> P x -> P (f x)
forallx : L, Omega f x -> Omega f x
eauto.
L: Type H: Lattice L H0: LatticeLaws L f: L -> L P: L -> Prop Hlim: forallX : set L,
(forallx : L, X x -> Omega f x) ->
(forallx : L, X x -> P x) -> P (cap X) Hsuc: forallx : L, Omega f x -> P x -> P (f x)
forallx : L, Omega f x -> P x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L P: L -> Prop Hlim: forallX : set L,
(forallx : L, X x -> Omega f x) ->
(forallx : L, X x -> P x) -> P (cap X) Hsuc: forallx : L, Omega f x -> P x -> P (f x) x: L Hx: Omega f x
P x
L: Type H: Lattice L H0: LatticeLaws L f: L -> L P: L -> Prop Hlim: forallX : set L,
(forallx : L, X x -> Omega f x) ->
(forallx : L, X x -> P x) -> P (cap X) Hsuc: forallx : L, Omega f x -> P x -> P (f x) X: set L H1: forallx : L, X x -> Omega f x H2: forallx : L, X x -> P x
P (cap X)
L: Type H: Lattice L H0: LatticeLaws L f: L -> L P: L -> Prop Hlim: forallX : set L,
(forallx : L, X x -> Omega f x) ->
(forallx : L, X x -> P x) -> P (cap X) Hsuc: forallx : L, Omega f x -> P x -> P (f x) x: L Hx: Omega f x IHHx: P x
P (f x)
L: Type H: Lattice L H0: LatticeLaws L f: L -> L P: L -> Prop Hlim: forallX : set L,
(forallx : L, X x -> Omega f x) ->
(forallx : L, X x -> P x) -> P (cap X) Hsuc: forallx : L, Omega f x -> P x -> P (f x) X: set L H1: forallx : L, X x -> Omega f x H2: forallx : L, X x -> P x
P (cap X)
eauto.
L: Type H: Lattice L H0: LatticeLaws L f: L -> L P: L -> Prop Hlim: forallX : set L,
(forallx : L, X x -> Omega f x) ->
(forallx : L, X x -> P x) -> P (cap X) Hsuc: forallx : L, Omega f x -> P x -> P (f x) x: L Hx: Omega f x IHHx: P x