Coq 증거에서 cofix 제거


15

Coq에서 coinductive 유형을 사용하여 몇 가지 기본 속성을 증명하려고 시도하는 동안 다음과 같은 문제가 계속 발생하여 해결할 수 없습니다. 다음과 같이 문제를 간단한 Coq 스크립트로 정리했습니다.

유형 트리는 유형 A의 요소로 레이블이 지정된 분기가있는 무한 트리를 정의합니다 . 분기는의 모든 요소에 대해 정의 할 필요가 없다 . Univ 값 은 모든 A 분기가 항상 정의 된 무한 트리입니다 . isUniv 는 주어진 트리가 Univ와 같은지 테스트합니다 . 주체UnivisUniv를 실제로 만족 시킨다고 말합니다 .

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.

이 시점에서 나는 증거를 포기한다. 현재 목표는 다음과 같습니다.

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

나는 isuniv 를 적용 할 수 있도록 (노드 무언가) 생산 목표 에서 cofix 를 제거하기 위해 적용 할 전술을 모른다 .

누구든지이 보조 정리를 증명할 수 있습니까? 그러한 상황에서 cofix
를 제거하는 표준 방법은 무엇입니까 ?


1
"interactive-proofs"태그는 일반적으로 복잡한 이론적 의미에서 대화 형 증명 시스템을 나타내므로 적절하지 않습니다. 내가 생각하는 올바른 용어는 "대화식 정리 증명"또는 "정리 입증"입니다.
Iddo Tzameret

"내성 지원"을 사용하여 수정 됨
Dave Clarke

답변:


6

패턴이 Tree와 일치하는 보조 기능을 사용하여 cofix를 제거 할 수 있습니다.

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.

당신은이 목표를 얻을 것입니다.

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

http://adam.chlipala.net/cpdt/html/Coinductive.html 에서이 기술을 수정했습니다.


고마워 나는 그 페이지가 당신의 대답이 들어 왔을 때쯤에보고있었습니다. 미친, 그러나 그것은 작동하는 것 같습니다 ... 그리고 조금 더 붙 잡히지 만, 나는 그것에 대해 내 머리를 조금 더 때릴 것입니다.
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.

다소 당황스러운 답변에 감사드립니다. 나는 A가 거주하고있는 문제에 부딪 쳤지 만, 그 문제를 해결하는 데 성공했다. 놀랍게도 우주는 펼쳐지지 않았습니다.
Dave Clarke

글쎄, 나는 내 대답에 당황하지 않습니다 :-) 나는 하나를 주면 포괄적 인 답변을 줄 수도 있다고 생각했습니다.
Andrej Bauer

당신의 응답은 나에게 창피했다. 그러나 확실히 높이 평가했습니다.
Dave Clarke

나는 농담했다 ... 어쨌든, 당황스러운 것은 없습니다. 나는 더 나쁜 실수를했다. 또한 웹은 사람들이 생각하기 전에 게시하도록 초대합니다. 나는 당신 자신의 정의를 잘못 여기에 게시했지만 운 좋게도 당신이하기 전에 그것을 알았습니다.
Andrej Bauer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.