Menghilangkan cofix dalam Coq proof

15

Saat mencoba membuktikan beberapa sifat dasar menggunakan tipe coinductive dalam Coq, saya terus mengalami masalah berikut ini dan saya tidak bisa mengatasinya. Saya telah menyaring masalahnya menjadi skrip Coq sederhana sebagai berikut.

Jenis Pohon mendefinisikan pohon mungkin tak terbatas dengan cabang diberi label dengan elemen tipe A . Sebuah cabang tidak perlu didefinisikan untuk semua elemen dari A . Nilai Univ adalah pohon tanpa batas dengan semua cabang A selalu ditentukan. isUniv menguji apakah pohon yang diberikan sama dengan Univ . Lemma menyatakan bahwa Univ memang memuaskan 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.

Pada titik ini saya menyerahkan buktinya. Tujuan saat ini adalah:

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

Saya tidak tahu taktik mana yang harus diterapkan untuk menghilangkan cofix di tujuan untuk menghasilkan (Node sesuatu) sehingga saya dapat menerapkan isuniv .

Adakah yang bisa membantu membuktikan lemma ini?
Apa cara standar menghilangkan cofix dalam situasi seperti itu?

Dave Clarke
sumber
1
Tag "bukti interaktif" tidak memadai, karena umumnya mengacu pada sistem bukti interaktif dalam pengertian kompleksitas-teoretisnya. Istilah yang benar saya kira adalah "pembuktian teorema interaktif", atau "pembuktian teorema".
Iddo Tzameret
Diperbaiki, menggunakan "proof-assistants"
Dave Clarke

Jawaban:

6

Anda dapat menghilangkan cofix menggunakan fungsi tambahan yang sesuai dengan pola Tree.

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.

Anda akan mendapatkan sasaran ini, yang merupakan langkah santai.

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

Saya mengadaptasi teknik ini dari http://adam.chlipala.net/cpdt/html/Coinductive.html

yhirai
sumber
Terima kasih untuk ini. Saya melihat halaman itu pada waktu yang hampir bersamaan dengan jawaban Anda. Gila, tetapi tampaknya berhasil ... dan kemudian saya terjebak sedikit lebih jauh, tetapi saya akan menundukkan kepala saya terhadap hal itu untuk sedikit lebih lama.
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
sumber
Terima kasih atas tanggapan yang agak memalukan ini. Saya memang mengalami masalah dengan A yang dihuni, tetapi berhasil memperhalus jalan saya. Anehnya, alam semesta tidak terbuka.
Dave Clarke
Yah, saya tidak malu dengan respons saya :-) Saya pikir saya mungkin juga memberikan respons yang komprehensif jika saya memberikannya.
Andrej Bauer
Tanggapan Anda sangat memalukan bagi saya. Namun tentu sangat dihargai.
Dave Clarke
Saya bercanda ... Bagaimanapun, tidak ada yang perlu malu. Saya telah membuat kesalahan yang lebih buruk. Juga, web mengundang orang untuk memposting sebelum mereka berpikir. Saya sendiri memposting perbaikan yang salah dari definisi Anda di sini, tapi untungnya saya menyadarinya sebelum Anda melakukannya.
Andrej Bauer