F1: Koindukcja i korekursja [TODO]
Set Primitive Projections.
Require Import List.
Import ListNotations.
Require Import FunctionalExtensionality.
Require Import Setoid.
Require Import FinFun.
Require Import NArith.
Require Import Div2.
Require Import ZArith.
Koindukcja (TODO)
Nanana Batman! (TODO)
Module Record.
#[projections(primitive)]
Record product (A B : Type) : Type := Pair
{
outl : A;
outr : B;
}.
Arguments outl {A B} _.
Arguments outr {A B} _.
Lemma eq_product :
forall {A B : Type} (p1 p2 : product A B),
outl p1 = outl p2 -> outr p1 = outr p2 -> p1 = p2.
Proof.
intros A B [a1 b1] [a2 b2]; cbn.
now intros -> ->.
Qed.
End Record.
Module Inductive.
#[projections(primitive)]
Inductive product (A B : Type) : Type := Pair
{
outl : A;
outr : B;
}.
Arguments outl {A B} _.
Arguments outr {A B} _.
Lemma eq_product :
forall {A B : Type} (p1 p2 : product A B),
outl p1 = outl p2 -> outr p1 = outr p2 -> p1 = p2.
Proof.
Fail intros A B [a1 b1] [a2 b2]; cbn.
Abort.
End Inductive.
Module CoInductive.
#[projections(primitive)]
CoInductive product (A B : Type) : Type := Pair
{
outl : A;
outr : B;
}.
Arguments outl {A B} _.
Arguments outr {A B} _.
Lemma eq_product :
forall {A B : Type} (p1 p2 : product A B),
outl p1 = outl p2 -> outr p1 = outr p2 -> p1 = p2.
Proof.
Fail intros A B [a1 b1] [a2 b2]; cbn.
Abort.
End CoInductive.
CoInductive coBTree (A : Type) : Type :=
{
root : option (coBTree A * A * coBTree A)
}.
Arguments root {A} _.
CoFixpoint fmap {A B : Type} (f : A -> B) (t : coBTree A) : coBTree B :=
{|
root :=
match root t with
| None => None
| Some (l, v, r) => Some (fmap f l, f v, fmap f r)
end
|}.
CoFixpoint ns (n : nat) : coBTree nat :=
{|
root := Some (ns (1 + 2 * n), n, ns (2 + 2 * n))
|}.
Inductive BTree (A : Type) : Type :=
| Empty : BTree A
| Node : A -> BTree A -> BTree A -> BTree A.
Arguments Empty {A}.
Arguments Node {A} _ _ _.
Fixpoint ttake (n : nat) {A : Type} (t : coBTree A) : BTree A :=
match n with
| 0 => Empty
| S n' =>
match root t with
| None => Empty
| Some (l, v, r) => Node v (ttake n' l) (ttake n' r)
end
end.
Compute ttake 5 (ns 0).
CoInductive tsim {A : Type} (t1 t2 : coBTree A) : Prop :=
{
tsim' :
root t1 = None /\ root t2 = None \/
exists (v1 v2 : A) (l1 l2 r1 r2 : coBTree A),
root t1 = Some (l1, v1, r1) /\
root t2 = Some (l2, v2, r2) /\
tsim l1 l2 /\ tsim r1 r2
}.
CoFixpoint mirror {A : Type} (t : coBTree A) : coBTree A :=
{|
root :=
match root t with
| None => None
| Some (l, v, r) => Some (mirror r, v, mirror l)
end
|}.
Lemma tsim_mirror_inv :
forall (A : Type) (t : coBTree A),
tsim (mirror (mirror t)) t.
Proof.
Admitted.
From Typonomikon Require Import F4.
Ćwiczenie
Znajdź taką rodzinę typów koinduktywnych
C, że dla dowolnego
typu
A,
C A jest w bijekcji z typem funkcji
nat -> A. Przez
bijekcję będziemy tu rozumieć funkcję, która ma odwrotność, z którą
w obie strony składa się do identyczności.
Uwaga: nie da się tego udowodnić bez użycia dodatkowych aksjomatów,
które na szczęście są bardzo oczywiste i same się narzucają.
Ćwiczenie
Zdefiniuj pojęcie "nieskończonego łańcucha malejącego" (oczywiście
za pomocą koindukcji) i udowodnij, że jeżeli relacja jest dobrze
ufundowana, to nie ma nieskończonych łańcuchów malejących.