Loại bỏ cofix trong bằng chứng Coq


15

Trong khi cố gắng chứng minh một số thuộc tính cơ bản bằng cách sử dụng các loại cưỡng chế trong Coq, tôi tiếp tục gặp vấn đề sau và tôi không thể khắc phục được. Tôi đã chắt lọc vấn đề vào một kịch bản Coq đơn giản như sau.

Các loại cây xác định cây có thể vô hạn với các ngành, dán nhãn với các yếu tố của loại Một . Chi nhánh không cần phải được định nghĩa cho tất cả các yếu tố của một . Giá trị Univ là cây vô hạn với tất cả các nhánh A luôn được xác định. isUniv kiểm tra xem một cây đã cho có bằng Univ không . Bổ đề nói rằng Univ thực sự thỏa mãn là Univ .

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.

Lúc này tôi từ bỏ bằng chứng. Mục tiêu hiện tại là:

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

Tôi không biết nên áp dụng chiến thuật nào để loại bỏ cofix trong mục tiêu cần sản xuất (Node gì đó) để tôi có thể áp dụng isuniv .

Bất cứ ai có thể giúp chứng minh bổ đề này?
Các cách tiêu chuẩn để loại bỏ cofix trong tình huống như vậy là gì?


1
Thẻ "bằng chứng tương tác" là không đầy đủ, vì nó thường đề cập đến các hệ thống bằng chứng tương tác theo nghĩa lý thuyết phức tạp của chúng. Thuật ngữ chính xác tôi cho là "chứng minh định lý tương tác" hay "chứng minh định lý".
Iddo Tzameret

Đã sửa lỗi, sử dụng "trợ lý bằng chứng"
Dave Clarke

Câu trả lời:


6

Bạn có thể loại bỏ cofix bằng cách sử dụng chức năng phụ trợ phù hợp với 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.

Bạn sẽ có được mục tiêu này, đó là một bước thư giãn.

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

Tôi đã điều chỉnh kỹ thuật này từ http://adam.chlipala.net/cpdt/html/Coindulation.html


Cảm ơn vì điều đó. Tôi đang nhìn vào trang đó cùng lúc câu trả lời của bạn xuất hiện. Thật điên rồ, nhưng nó dường như hoạt động ... và rồi tôi bị kẹt thêm một chút nữa, nhưng tôi sẽ đập đầu mình lâu hơn một chút.
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.

Cảm ơn vì phản ứng có phần xấu hổ này. Tôi đã gặp phải vấn đề với A là người ở, nhưng đã tìm cách giải quyết theo cách của tôi xung quanh đó. Đáng ngạc nhiên, vũ trụ đã không mở ra.
Dave Clarke

Chà, tôi không xấu hổ vì câu trả lời của mình :-) Tôi nghĩ tôi cũng có thể đưa ra một phản hồi toàn diện nếu tôi đưa ra.
Andrej Bauer

Phản ứng của bạn đã gây bối rối cho tôi. Nhưng chắc chắn đánh giá cao.
Dave Clarke

Tôi đã nói đùa ... Dù sao đi nữa, không có gì phải xấu hổ cả. Tôi đã phạm sai lầm tồi tệ hơn. Ngoài ra, web mời mọi người đăng bài trước khi họ nghĩ. Bản thân tôi đã đăng một bản sửa lỗi sai của định nghĩa của bạn ở đây, nhưng may mắn là tôi đã nhận thấy nó trước khi bạn làm.
Andrej Bauer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.