Eliminowanie cofix w dowodzie Coq

15

Próbując udowodnić pewne podstawowe właściwości przy użyciu typów koindukcyjnych w Coq, ciągle napotykam na następujący problem i nie mogę go obejść. Wydzieliłem problem na prosty skrypt Coq w następujący sposób.

Rodzaj Drzewo definiuje ewentualnie nieskończone drzew z gałęziami oznaczonych elementów typu A . Oddział nie musi być określone dla wszystkich elementów A . Wartość Univ jest nieskończonym drzewem z zawsze zdefiniowanymi wszystkimi gałęziami A. isUniv sprawdza, czy dane drzewo jest równe Univ . Lemat mówi, że Univ rzeczywiście spełnia isUniv .

Parameter A : Set.

CoInductive Tree: Set := Node : (A -> option Tree) -> Tree.

Definition derv (a : A) (t: Tree): option Tree :=
  match t with Node f => f a end.

CoFixpoint Univ : Tree := Node (fun _ => Some Univ).

CoInductive isUniv : Tree -> Prop :=
  isuniv : forall (nf : A -> option Tree) (a : A) (t : Tree), 
    nf a = Some t -> 
    isUniv t -> 
    isUniv (Node nf).

Lemma UnivIsUniv : isUniv Univ.
Proof.
  cofix CH.    (* this application of cofix is fine *)
  unfold Univ. 

Admitted.

W tym momencie rezygnuję z dowodu. Obecny cel to:

CH : isUniv Univ
============================
isUniv (cofix Univ  : Tree := Node (fun _ : A => Some Univ))

Nie wiem, jaką taktykę zastosować, aby wyeliminować kofiks w celu wyprodukowania (Node coś) , abym mógł zastosować isuniv .

Czy ktoś może pomóc udowodnić ten lemat?
Jakie są standardowe sposoby eliminacji kofika w takiej sytuacji?

Dave Clarke
źródło
1
Znacznik „interaktywne proofy” nie jest odpowiedni, ponieważ ogólnie odnosi się do interaktywnych systemów proofów w ich teoretycznym sensie złożoności. Przypuszczam, że poprawnym terminem jest „interaktywne dowodzenie twierdzeń” lub „dowodzenie twierdzeń”.
Iddo Tzameret,
Naprawiono, używając „asystentów-dowódców”
Dave Clarke

Odpowiedzi:

6

Możesz wyeliminować cofix za pomocą funkcji pomocniczej, której wzór pasuje do drzewa.

Definition TT (t:Tree) :=
  match t with
    | Node o => Node o
  end.

Lemma TTid : forall t: Tree, t = TT t.
  intro t.
  destruct t.
  reflexivity.
  Qed.

Lemma UnivIsUniv : isUniv Univ.
Proof.
  cofix.
  rewrite TTid.
  unfold TT.
  unfold Univ.

Osiągniesz ten cel, który jest krokiem odprężenia.

  UnivIsUniv : isUniv Univ
  ============================
   isUniv
     (Node
        (fun _ : A =>
         Some (cofix Univ  : Tree := Node (fun _ : A => Some Univ))))

Dostosowałem tę technikę z http://adam.chlipala.net/cpdt/html/Coinductive.html

yhirai
źródło
Dzięki za to. Patrzyłem na tę stronę mniej więcej w tym samym czasie, gdy nadeszła twoja odpowiedź. Szalony, ale wydaje się, że działa ... i wtedy utknąłem trochę dalej, ale uderzę głową o to trochę dłużej.
Dave Clarke,
9
(* I post my answer as a Coq file. In it I show that supercoooldave's
   definition of a universal tree is not what he intended. His isUniv
   means "the tree has an infinite branch". I provide the correct
   definition, show that the universal tree is universal according to
   the new definition, and I provide counter-examples to
   supercooldave's definition. I also point out that the universal
   tree of branching type A has an infinite path iff A is inhabited.
   *)

Set Implicit Arguments.

CoInductive Tree (A : Set): Set := Node : (A -> option (Tree A)) -> Tree A.

Definition child (A : Set) (t : Tree A) (a : A) :=
  match t with
    Node f => f a
  end.

(* We consider two trees, one is the universal tree on A (always
   branches out fully), and the other is a binary tree which always
   branches to one side and not to the other, so it is like an
   infinite path with branches of length 1 shooting off at each node.  *)

CoFixpoint Univ (A : Set) : Tree A := Node (fun _ => Some (Univ A)).

CoFixpoint Thread : Tree (bool) :=
  Node (fun (b : bool) => if b then Some Thread else None).

(* The original definition of supercooldave should be called "has an
   infinite path", so we rename it to "hasInfinitePath". *)
CoInductive hasInfinitePath (A : Set) : Tree A -> Prop :=
  haspath : forall (f : A -> option (Tree A)) (a : A) (t : Tree A),
    f a = Some t ->
    hasInfinitePath t -> 
    hasInfinitePath (Node f).

(* The correct definition of universal tree. *)
CoInductive isUniv (A : Set) : Tree A -> Prop :=
  isuniv : forall (f : A -> option (Tree A)),
    (forall  a, exists t, f a = Some t /\ isUniv t) -> 
    isUniv (Node f).

(* Technicalities that allow us to get coinductive proofs done. *)
Definition TT (A : Set) (t : Tree A) :=
  match t with
    | Node o => Node o
  end.

Lemma TTid (A : Set) : forall t: Tree A, t = TT t.
  intros A t.
  destruct t.
  reflexivity.
  Qed.

(* Thread has an infinite path. *)
Lemma ThreadHasInfinitePath : hasInfinitePath Thread.
Proof.
  cofix H.
  rewrite TTid.
  unfold TT.
  unfold Thread.
  (* there is a path down the "true" branch leading to Thread. *)
  apply haspath with (a := true) (t := Thread).
  auto.
  auto.
Qed.

(* Auxiliary lemma *)
Lemma univChildNotNone (A : Set) (t : Tree A) (a : A):
  isUniv t -> (child t a <> None).
Proof.
  intros A t a [f H].
  destruct (H a) as [u [G _]].
  unfold child.
  rewrite G.
  discriminate.
Qed.

(* Thread is not universal. *)
Lemma ThreadNotUniversal: ~ (isUniv Thread).
Proof.
  unfold not.
  intro H.
  eapply univChildNotNone with (t := Thread) (a := false).
  auto.
  unfold Thread, child.
  auto.
Qed.

(* Now let us show that Univ is universal. *)
Lemma univIsuniv (A : Set): isUniv (Univ A).
Proof.
  intro A.
  cofix H.
  rewrite TTid.
  unfold TT.
  unfold Univ.
  apply isuniv.
  intro a.
  exists (Univ A).
  auto.
Qed.

(* By the way, it need not be the case that a universal tree has
   an infinite path! In fact, the universal tree of branching type
   A has an infinite path iff A is inhabited. *)

Lemma whenUnivHasInfiniteBranch (A : Set):
  hasInfinitePath (Univ A) <-> exists a : A, True.
Proof.
  intro A.
  split.
  intro H.
  destruct H as [f a t _].
  exists a.
  trivial.
  intros [a _].
  cofix H.
  rewrite TTid.
  unfold TT.
  unfold Univ.
  apply haspath with (t := Univ A); auto.
Qed.
Andrej Bauer
źródło
Dzięki za tę nieco zawstydzającą odpowiedź. Wpadłem na problem z zamieszkaniem w A, ale udało mi się to wyrafinować. Co zaskakujące, wszechświat się nie rozwinął.
Dave Clarke,
Cóż, nie jestem zawstydzony moją odpowiedzią :-) Pomyślałem, że równie dobrze mogę udzielić wyczerpującej odpowiedzi, jeśli ją udzielę.
Andrej Bauer,
Twoja odpowiedź była dla mnie zawstydzająca. Ale z pewnością bardzo mile widziane.
Dave Clarke,
Ja żartuję ... Tak czy inaczej, nie ma nic się wstydzić. Popełniłem gorsze błędy. Ponadto sieć zachęca ludzi do publikowania postów, zanim pomyślą. Ja sam opublikowałem tutaj błędną poprawkę twojej definicji, ale na szczęście zauważyłem ją wcześniej.
Andrej Bauer