我试图编写一个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。) –