我試圖編寫一個Coq函數,它需要一個Stream
和一個謂詞並返回,作爲list
,該屬性擁有的流的最長前綴。這是我有:Coinduction和從屬類型
Require Import List Streams.
Require Import Lt.
Import ListNotations.
Local Open Scope list_scope.
Section TakeWhile.
Context {A : Type} {P : Stream A -> Prop}.
Hypothesis decide_P : forall s : Stream A, {P s} + {~ P s}.
Program Fixpoint take_while (s : Stream A)
(H : Exists (fun s => ~ P s) s) : list A :=
if decide_P s
then hd s :: take_while (tl s) _
else [].
Next Obligation.
destruct H; tauto.
Defined.
End TakeWhile.
但是,當我試圖使用該功能進行計算,我得到一個非常大的項與所有的定義擴大。我不知道爲什麼,但我猜測Coq不願意展開共同誘惑的說法。這裏有一個例子:
Require Import Program.Equality.
Require Import Compare_dec.
Lemma not_lt_le :
forall n m : nat, ~ n < m -> m <= n.
Proof.
pose le_or_lt.
firstorder.
Qed.
Definition increasing (s : Stream nat) : Prop :=
forall n : nat, Exists (fun s => ~ hd s < n) s.
CoFixpoint nats (n : nat) := Cons n (nats (S n)).
Theorem increasing_nats :
forall n : nat, increasing (nats n).
Proof.
intros n m.
induction m.
- left.
pose lt_n_0.
firstorder.
- dependent induction IHm.
* apply not_lt_le, le_lt_or_eq in H.
destruct H.
+ left.
pose le_not_lt.
firstorder.
+ right.
left.
simpl in *.
rewrite H.
pose lt_irrefl.
firstorder.
* right.
simpl.
apply IHIHm.
reflexivity.
Qed.
鑑於此,命令Eval compute in take_while (fun s => lt_dec (hd s) 5) (nats 0) (increasing_nats 0 5)
導致非常大的名詞,正如我上面提到。
任何人都可以給我一些指導嗎?
感謝您的回答。那麼,Coq中通常不可能進行依賴於證明的編程?因爲我看到它的方式,這打破了沉思Prop類型的整個點。 – nosewings
這取決於你的意思。用道具來製作數據片段可以做很多事情。您可以將其用於終止參數,演員和其他事物,但不多。我不確定你的意思是與類型中的計算有關的impredictivity,但prop是被設計成不會干擾類型中的計算。 –
@nosewings如果你想討論有關命題的數據,你可以使用'sig'類型,它位於'Set'而不是'Prop'。換句話說,如果你可以實際使用它們,那麼盲目性會讓你做壞事:這就是爲什麼你不能區分'Prop'中的任何東西。 (詳情請參閱http://adam.chlipala.net/cpdt/html/Universes.html。) –