F5: Kodrzewa [TODO]
Set Implicit Arguments.
Drzewa nieskończone (TODO)
CoInductive InfTree (A : Type) : Type :=
{
root : A;
left : InfTree A;
right : InfTree A;
}.
Arguments root {A}.
Arguments left {A} _.
Arguments right {A} _.
Korekursja i koindukcja na drzewach nieskończonych (TODO)
Record corecursive
{A X : Type} (f : X -> InfTree A)
(rt : X -> A) (l : X -> X) (r : X -> X) : Prop :=
{
root_f : forall x : X, root (f x) = rt x;
left_f : forall x : X, left (f x) = f (l x);
right_r : forall x : X, right (f x) = f (r x);
}.
CoFixpoint corec
{A X : Type} (rt : X -> A) (l : X -> X) (r : X -> X)
(x : X) : InfTree A :=
{|
root := rt x;
left := corec rt l r (l x);
right := corec rt l r (r x);
|}.
Lemma corecursive_corec :
forall {A X : Type} (rt : X -> A) (l : X -> X) (r : X -> X),
corecursive (corec rt l r) rt l r.
Proof.
split; cbn; reflexivity.
Qed.
Definition uniqueness (A : Type) : Prop :=
forall
(X : Type) (f g : X -> InfTree A)
(rt : X -> A) (l : X -> X) (r : X -> X),
corecursive f rt l r -> corecursive g rt l r ->
forall x : X, f x = g x.
CoInductive sim {A : Type} (t1 t2 : InfTree A) : Prop :=
{
roots : root t1 = root t2;
lefts : sim (left t1) (left t2);
rights : sim (right t1) (right t2);
}.
Definition sim_to_eq (A : Type) : Prop :=
forall t1 t2 : InfTree A, sim t1 t2 -> t1 = t2.
Inductive Index : Type :=
| here : Index
| goleft : Index -> Index
| goright : Index -> Index.
Fixpoint subtree
{A : Type} (t : InfTree A) (i : Index) : InfTree A :=
match i with
| here => t
| goleft i' => subtree (left t) i'
| goright i' => subtree (right t) i'
end.
Fixpoint goleft' (i : Index) : Index :=
match i with
| here => goleft here
| goleft i' => goleft (goleft' i')
| goright i' => goright (goleft' i')
end.
Fixpoint goright' (i : Index) : Index :=
match i with
| here => goright here
| goleft i' => goleft (goright' i')
| goright i' => goright (goright' i')
end.
Lemma left_subtree :
forall {A : Type} (i : Index) (t : InfTree A),
left (subtree t i) = subtree t (goleft' i).
Proof.
induction i; cbn; intros.
reflexivity.
rewrite IHi. reflexivity.
rewrite IHi. reflexivity.
Qed.
Lemma right_subtree :
forall {A : Type} (i : Index) (t : InfTree A),
right (subtree t i) = subtree t (goright' i).
Proof.
induction i; cbn; intros.
reflexivity.
rewrite IHi. reflexivity.
rewrite IHi. reflexivity.
Qed.
#[global] Hint Resolve left_subtree right_subtree : core.
Lemma coinduction :
forall {A : Type},
uniqueness A -> sim_to_eq A.
Proof.
unfold uniqueness, sim_to_eq.
intros A uniqueness t1 t2 Hsim.
eapply
(
uniqueness
(Index) (subtree t1) (subtree t2)
(fun i => root (subtree t2 i)) goleft' goright'
_ _
here
).
Unshelve.
all: repeat split; auto.
clear uniqueness. intro i.
revert t1 t2 Hsim.
induction i; cbn; intros t1 t2 [].
assumption.
erewrite IHi.
reflexivity.
assumption.
erewrite IHi.
reflexivity.
assumption.
Qed.
Record tsim (A : Type) : Type :=
{
lt : InfTree A;
rt : InfTree A;
tsim' : sim lt rt;
}.
Arguments lt {A} _.
Arguments rt {A} _.
Arguments tsim' {A} _.
Definition root' {A : Type} (t : tsim A) : A :=
root (rt t).
Definition left' {A : Type} (t : tsim A) : tsim A :=
{|
lt := left (lt t);
rt := left (rt t);
tsim' := lefts (tsim' t);
|}.
Definition right' {A : Type} (t : tsim A) : tsim A :=
{|
lt := right (lt t);
rt := right (rt t);
tsim' := rights (tsim' t);
|}.
Lemma coinduction' :
forall {A : Type},
uniqueness A -> sim_to_eq A.
Proof.
unfold uniqueness, sim_to_eq.
intros A uniqueness t1 t2 Hsim.
eapply
(
uniqueness
(tsim A) lt rt
root' left' right'
_ _
{| lt := t1; rt := t2; tsim' := Hsim |}
).
Unshelve.
all: repeat split.
destruct x, tsim'0. unfold root'; cbn. assumption.
Qed.
Funkcje na drzewach nieskończonych
From Typonomikon Require Import D5.
CoFixpoint mirror {A : Type} (t : InfTree A) : InfTree A :=
{|
root := root t;
left := mirror (right t);
right := mirror (left t);
|}.
Lemma mirror_mirror :
forall {A : Type} (t : InfTree A),
sim (mirror (mirror t)) t.
Proof.
cofix CH.
constructor; cbn.
reflexivity.
apply CH.
apply CH.
Qed.
CoFixpoint tmap {A B : Type} (f : A -> B) (t : InfTree A) : InfTree B :=
{|
root := f (root t);
left := tmap f (left t);
right := tmap f (right t);
|}.
Lemma tmap_id :
forall {A : Type} (t : InfTree A),
sim (tmap (fun x => x) t) t.
Proof.
cofix CH.
constructor; cbn.
reflexivity.
apply CH.
apply CH.
Qed.
Lemma tmap_comp :
forall {A B C : Type} (f : A -> B) (g : B -> C) (t : InfTree A),
sim (tmap g (tmap f t)) (tmap (fun x => g (f x)) t).
Proof.
cofix CH.
constructor; cbn.
reflexivity.
apply CH.
apply CH.
Qed.
CoFixpoint replicate {A : Type} (x : A) : InfTree A :=
{|
root := x;
left := replicate x;
right := replicate x;
|}.
Fixpoint index {A : Type} (i : Index) (t : InfTree A) : A :=
match i with
| here => root t
| goleft i' => index i' (left t)
| goright i' => index i' (right t)
end.
Fixpoint revi (i : Index) : Index :=
match i with
| here => here
| goleft i' => goright (revi i')
| goright i' => goleft (revi i')
end.
Lemma index_mirror :
forall {A : Type} (i : Index) (t : InfTree A),
index i (mirror t) = index (revi i) t.
Proof.
induction i as [| i' | i']; cbn; intros.
reflexivity.
rewrite IHi'. reflexivity.
rewrite IHi'. reflexivity.
Qed.
Definition node {A : Type} (v : A) (l r : InfTree A) : InfTree A :=
{|
root := v;
left := l;
right := r;
|}.
Fixpoint replace
{A : Type} (i : Index) (x : A) (t : InfTree A) : InfTree A :=
match i with
| here => node x (left t) (right t)
| goleft i' => node (root t) (replace i' x (left t)) (right t)
| goright i' => node (root t) (left t) (replace i' x (right t))
end.
Lemma index_replicate :
forall {A : Type} (i : Index) (x : A),
index i (replicate x) = x.
Proof.
induction i as [| i' | i']; cbn; intros.
reflexivity.
apply IHi'.
apply IHi'.
Qed.
Lemma index_replace :
forall {A : Type} (i : Index) (x : A) (t : InfTree A),
index i (replace i x t) = x.
Proof.
induction i as [| i' | i']; cbn; intros.
reflexivity.
apply IHi'.
apply IHi'.
Qed.
CoFixpoint zipW
{A B C : Type} (f : A -> B -> C)
(ta : InfTree A) (tb : InfTree B) : InfTree C :=
{|
root := f (root ta) (root tb);
left := zipW f (left ta) (left tb);
right := zipW f (right ta) (right tb);
|}.
Lemma zipW_mirror :
forall
{A B C : Type} (f : A -> B -> C)
(ta : InfTree A) (tb : InfTree B),
sim (zipW f (mirror ta) (mirror tb)) (mirror (zipW f ta tb)).
Proof.
cofix CH.
constructor; cbn.
reflexivity.
apply CH.
apply CH.
Qed.
Definition unzipW
{A B C : Type} (f : C -> A * B)
(t : InfTree C) : InfTree A * InfTree B :=
(tmap (fun c => fst (f c)) t,
tmap (fun c => snd (f c)) t).
Fixpoint replace'
{A : Type} (i : Index) (t1 t2 : InfTree A) : InfTree A :=
match i with
| here => t2
| goleft i' => node (root t1) (replace' i' (left t1) t2) (right t1)
| goright i' => node (root t1) (left t1) (replace' i' (right t1) t2)
end.
Lemma subtree_replace' :
forall {A : Type} (i : Index) (t1 t2 : InfTree A),
subtree (replace' i t1 t2) i = t2.
Proof.
induction i as [| i' | i']; cbn; intros.
reflexivity.
apply IHi'.
apply IHi'.
Qed.
CoFixpoint iterate'
{A : Type} (f : A -> A) (x : A) (n : nat) : InfTree A :=
{|
root := iter f n x;
left := iterate' f x (1 + 2 * n);
right := iterate' f x (2 + 2 * n);
|}.
Fixpoint index_to_nat' (i : Index) (n : nat) : nat :=
match i with
| here => n
| goleft i' => index_to_nat' i' (1 + 2 * n)
| goright i' => index_to_nat' i' (2 + 2 * n)
end.
Lemma index_iterate' :
forall {A : Type} (f : A -> A) (i : Index) (x : A) (n : nat),
index i (iterate' f x n) = iter f (index_to_nat' i n) x.
Proof.
induction i as [| i' | i']; cbn; intros.
reflexivity.
rewrite IHi'. reflexivity.
rewrite IHi'. reflexivity.
Qed.
Definition iterate
{A : Type} (f : A -> A) (x : A) : InfTree A :=
iterate' f x 0.
Definition index_to_nat (i : Index) : nat :=
index_to_nat' i 0.
Lemma index_iterate :
forall {A : Type} (f : A -> A) (i : Index) (x : A),
index i (iterate f x) = iter f (index_to_nat i) x.
Proof.
intros. apply index_iterate'.
Qed.
Inductive InfTreeNeq {A : Type} : InfTree A -> InfTree A -> Type :=
| ITN_root :
forall t1 t2 : InfTree A,
root t1 <> root t2 -> InfTreeNeq t1 t2
| ITN_left :
forall t1 t2 : InfTree A,
InfTreeNeq (left t1) (left t2) -> InfTreeNeq t1 t2
| ITN_right :
forall t1 t2 : InfTree A,
InfTreeNeq (right t1) (right t2) -> InfTreeNeq t1 t2.
Lemma InfTreeNeq_neq :
forall {A : Type} {t1 t2 : InfTree A},
InfTreeNeq t1 t2 -> t1 <> t2.
Proof.
induction 1; intros Heq.
apply n. f_equal. assumption.
apply IHX. f_equal. assumption.
apply IHX. f_equal. assumption.
Qed.