M7b: Legalna topologia
Wstęp (TODO)
Najpierw nawiązanie do tego co było o relacjach i jakieś intuicje
o porządkach. Potem trochę porządkologii i może jakieś dziedziny.
Potem topologia.
Typy przeszukiwalne (TODO)
Tutaj o topologii takiej jak robi Martin Escardó, np. w tej pracy:
"Infinite sets that satisfy the principle of omniscience in any
variety of constructive mathematics", czyli odkrywamy, że klasycznie
nat i
conat są izomorficzne, ale
conat jest konstruktywnie
przeszukiwalne, zaś
nat nie. Wszystko dzieje się w legalnym Coqu,
z włączonym guard checkerem i bez żadnych homotopii.
From Typonomikon Require Import F3.
Class Searchable (A : Type) : Type :=
{
search : (A -> bool) -> A;
search_spec :
forall p : A -> bool,
p (search p) = false -> forall x : A, p x = false;
}.
Uwaga TODO: pamiętać o tym, że przeszukiwalność typu to coś jak
paradoks pijoka:
- jeżeli pijok pije, to wszyscy piją
- jeżeli wyszukany element nie spełnia, to żaden nie spełnia
CoFixpoint search_conat (p : conat -> bool) : conat :=
{|
out := if p zero then Z else S (search_conat (fun n => p (succ n)))
|}.
Lemma sc_eq :
forall p : conat -> bool,
sim (search_conat p)
(if p zero then zero else succ (search_conat (fun n => p (succ n)))).
Proof.
constructor; cbn.
destruct (p zero) eqn: Hp; cbn; constructor.
reflexivity.
Qed.
Lemma search_conat_false :
forall p : conat -> bool,
p (search_conat p) = false -> sim (search_conat p) omega.
Proof.
cofix CH.
intros p H.
constructor. destruct (p zero) eqn: Hp.
replace (search_conat p) with zero in H.
congruence.
admit.
cbn. rewrite Hp. constructor.
apply CH.
admit.
Admitted.
Lemma search_conat_true :
forall (p : conat -> bool) (n : conat),
p n = true -> le (search_conat p) n.
Proof.
Admitted.
Definition pred (c : conat) : conat :=
{|
out :=
match out c with
| Z => Z
| S c' => out c'
end
|}.
Lemma sim_omega_le :
forall n m : conat,
sim n omega -> le n m -> sim m omega.
Proof.
Admitted.
#[refine]
#[export]
Instance Searchable_conat : Searchable conat :=
{
search := search_conat;
}.
Proof.
intros p H c.
destruct (p c) eqn: Hpn; try reflexivity.
assert (sim (search_conat p) omega).
apply search_conat_false. assumption.
assert (le (search_conat p) c).
apply search_conat_true. assumption.
assert (sim c omega).
apply sim_omega_le with (search_conat p); assumption.
assert (search_conat p <> c).
intro. subst. congruence.
rewrite <- H, <- Hpn.
f_equal. rewrite <- sim_eq.
rewrite H0. assumption.
Defined.
Ćwiczenie (trudne i niezbadane)
Czy typ
Stream A jest przeszukiwalny? Jeżeli tak, udowodnij.
Jeżeli nie, to znajdź jakiś warunek na
A, przy którym
Stream A
jest przeszukiwalny.
Trochę właściwości, pewnie dość oczywistych.
Definition search_prod
{A B : Type} (SA : Searchable A) (SB : Searchable B)
(p : A * B -> bool) : A * B :=
let a := search (fun a : A => p (a, search (fun b : B => p (a, b)))) in
let b := search (fun b : B => p (a, b)) in
(a, b).
#[refine]
#[export]
Instance Searchable_prod
{A B : Type}
(SA : Searchable A) (SB : Searchable B) : Searchable (A * B) :=
{
search := @search_prod _ _ SA SB
}.
Proof.
intros p H [a b].
unfold search_prod in *.
destruct SA as [sa Ha], SB as [sb Hb]; cbn in *.
specialize (Hb (fun b => p (a, b))); cbn in Hb.
apply Hb.
specialize (Ha (fun a => p (a, sb (fun b => p (a, b))))). cbn in Ha.
apply Ha.
assumption.
Defined.
#[refine]
#[export]
Instance Searchable_sum
{A B : Type}
(SA : Searchable A) (SB : Searchable B) : Searchable (A + B) :=
{
search p :=
let a := search (fun a => p (inl a)) in
let b := search (fun b => p (inr b)) in
if p (inl a) then inl a else inr b
}.
Proof.
intros p H x.
destruct SA as [sa Ha], SB as [sb Hb]; cbn in *.
destruct (p (inl (sa (fun a => p (inl a))))) eqn : Heq.
congruence.
destruct x as [a | b].
apply (Ha (fun a => p (inl a))). assumption.
apply (Hb (fun b => p (inr b))). assumption.
Defined.
Da się zrobić jakieś ciekawe funkcje?
Definition sex
{A : Type} {_ : Searchable A} (p : A -> bool) : bool :=
p (search p).
Definition sall
{A : Type} {_ : Searchable A} (p : A -> bool) : bool :=
let p' := fun a => negb (p a) in
negb (p' (search p')).
Nie każdy conat jest zerem, brawo!
Compute
sall (fun n => match out n with | Z => true | _ => false end).
To samo, tylko bardziej przyjazne sygnatury typów.
Inductive ospec
{A : Type} (N : Prop) (S : A -> Prop) : option A -> Prop :=
| ospec_None : N -> ospec N S None
| ospec_Some : forall a : A, S a -> ospec N S (Some a).
Definition search'
{A : Type} {SA : Searchable A} (p : A -> bool) : option A :=
if p (search p) then Some (search p) else None.
Lemma search'_spec :
forall {A : Type} {SA : Searchable A} (p : A -> bool),
ospec (forall x : A, p x = false)
(fun x : A => p x = true)
(search' p).
Proof.
intros. unfold search'.
destruct (p (search p)) eqn: H; constructor.
assumption.
apply search_spec. assumption.
Qed.