data _∈_ {X : Set} (x : X) : (xs : List X) → Set where
here! : {xs : List X} → x ∈ x ∷ xs
there : {xs : List X} {y : X} (pr : x ∈ xs) → x ∈ y ∷ xs
remove : {X : Set} {x : X} (xs : List X) (pr : x ∈ xs) → List X
remove (_ ∷ xs) here! = xs
remove (y ∷ xs) (there pr) = y ∷ remove xs pr
我试图将以上定义从阿格达(Agda)转换为考克(Coq),并且遇到了困难。
Inductive Any {A : Type} (P : A -> Type) : list A -> Prop :=
| here : forall {x : A} {xs : list A}, P x -> Any P (x :: xs)
| there : forall {x : A} {xs : list A}, Any P xs -> Any P (x :: xs).
Definition In' {A : Type} (x : A) xs := Any (fun x' => x = x') xs.
Fixpoint remove {A : Type} {x : A} {l : list A} (pr : In' x l) : list A :=
match l, pr with
| [], _ => []
| _ :: ls, here _ _ => ls
| x :: ls, there _ pr => x :: remove pr
end.
Incorrect elimination of "pr0" in the inductive type "@Any":
the return type has sort "Type" while it should be "Prop".
Elimination of an inductive object of sort Prop
is not allowed on a predicate in sort Type
because proofs can be eliminated only to build proofs.
除了此错误外,如果我不提出[]
案件,Coq会要求我提供它,尽管它很荒谬。
到目前为止,我认为Agda和Coq是相同的语言,但前端不同,但是现在我开始认为它们在幕后是不同的。有没有一种方法可以在Coq中复制删除功能,如果没有,您会推荐哪种选择?
编辑:我还希望将证明保留在In
和In'
之间。最初,我将In'
设为Type
,而不是Prop
,但这使以下证明因类型错误而失败。
Fixpoint In {A : Type} (x : A) (l : list A) : Prop :=
match l with
| [] ⇒ False
| x' :: l' ⇒ x' = x ∨ In x l'
end.
Theorem In_iff_In' :
forall {A : Type} (x : A) (l : list A),
In x l <-> In' x l.
Proof.
intros.
split.
- intros.
induction l.
+ inversion H.
+ simpl in H.
destruct H; subst.
* apply here. reflexivity.
* apply there. apply IHl. assumption.
- intros.
induction H.
+ left. subst. reflexivity.
+ right. assumption.
Qed.
In environment
A : Type
x : A
l : list A
The term "In' x l" has type "Type" while it is expected to have type
"Prop" (universe inconsistency).
此处的In
来自SF的Logic chapter。我在Agda中有鸽子洞原理的解决方案,因此我希望将此双射转换为练习所要求的形式。
Edit2 :
Theorem remove_lemma :
forall {A} {x} {y} {l : list A} (pr : In' x l) (pr' : In' y l),
x = y \/ In' y (remove pr).
即使在定义Type
时使用In'
,我也会在此定义中遇到Universe不一致的情况。
答案 0 :(得分:2)
您需要使用会员资格证明。现在,您的Any
在Prop
中取值,由于其消除的限制(请参阅错误消息),该值与公理forall (P: Prop) (x y: P), x = y
是一致的。这意味着,如果您有某个术语依赖于其类型在Prop
中的术语(remove
就是这种情况),那么它只能使用存在该术语的事实,而不必使用具体来说。通常,您不能在Prop
上使用消除(通常是模式匹配)来产生除Prop
之外的任何东西。
In' 1 [1; 2; 1; 3; 1; 4]
有三种本质上不同的证明,根据所使用的证明,remove p
可以是[2; 1; 4; 1; 4]
,[1; 2; 3; 1; 4]
或[1; 2; 1; 3; 4]
。因此,输出在本质上取决于特定的证明。
要解决此问题,您只需将Prop
中的Inductive Any {A : Type} (P : A -> Type) : list A -> Prop
替换为Type
。 1 现在我们可以消除为非Prop
类型和您对remove
的定义按书面规定进行。
要回答您的编辑,我认为最大的问题是您的某些定理/定义需要In'
成为Prop
(因为它们依赖于非信息量的证明),而另一些则需要信息量的证明。
我认为您最好的选择是将In'
保留为Type
,然后证明定理的非信息性版本。在标准库中,Coq.Init.Logic
中有一个归纳类型inhabited
。
Inductive inhabited (A: Type): Prop :=
| inhabits: A -> inhabited A.
这是一种类型,本质上会忘记任何有关其术语的特定信息,只会记住它是否有人居住。我认为,只要将In' x l
替换为inhabited (In' x l)
,就可以证明您的定理和引理。我能够证明您的定理的一个变体,其结论只是In x l <-> inhabited (In' x l)
。您的证明大部分有效,但是我必须一步一步使用以下简单引理:
Lemma inhabited_there {A: Type} {P: A -> Type} {x: A} {xs: list A}:
inhabited (Any P xs) -> inhabited (Any P (x :: xs)).
注意:尽管inhabited A
基本上只是Prop
的{{1}}版本,并且我们有A
,但由于我们一般无法证明A -> inhabited A
,因为这将涉及选择inhabited A -> A
的任意元素。 2
我之前在这里也建议过A
,但是由于归纳类型取决于Set
中的A
,因此无法使用。
事实上,我相信证明助理Lean会在选择公理中使用与此类似的东西。