使用公式在Coq中实现依赖类型查找时遇到的问题
我试图用package在Coq中定义向量上的函数。下面提供了显示我将描述的问题的最少代码 我的想法是编写一个函数,该函数对某个类型适用于向量所有元素的证明进行查找,该证明具有标准定义:使用公式在Coq中实现依赖类型查找时遇到的问题,coq,dependent-type,Coq,Dependent Type,我试图用package在Coq中定义向量上的函数。下面提供了显示我将描述的问题的最少代码 我的想法是编写一个函数,该函数对某个类型适用于向量所有元素的证明进行查找,该证明具有标准定义: Inductive vec (A : Type) : nat -> Type := | VNil : vec A 0 | VCons : forall n, A -> vec A n -> vec A (S n). 使用前一种类型,我使用公式定义了以下标准查找操作: Equ
Inductive vec (A : Type) : nat -> Type :=
| VNil : vec A 0
| VCons : forall n, A -> vec A n -> vec A (S n).
使用前一种类型,我使用公式定义了以下标准查找操作:
Equations vlookup {A}{n}(i : fin n) (v : vec A n) : A :=
vlookup FZero (VCons x _) := x ;
vlookup (FSucc ix) (VCons _ xs) := vlookup ix xs.
现在,麻烦开始了。我想定义一些
属性适用于向量中的所有元素。以下感应类型完成此工作:
Inductive vforall {A : Type}(P : A -> Type) : forall n, vec A n -> Type :=
| VFNil : vforall P _ VNil
| VFCons : forall n x xs,
P x -> vforall P n xs -> vforall P (S n) (VCons x xs).
最后,我要定义的函数是
Equations vforall_lookup
{n}
{A : Type}
{P : A -> Type}
{xs : vec A n}
(idx : fin n) :
vforall P xs -> P (vlookup idx xs) :=
vforall_lookup FZero (VFCons _ _ pf _) := pf ;
vforall_lookup (FSucc ix) (VFCons _ _ _ ps) := vforall_lookup ix ps.
至少对我来说,这个定义是有意义的,应该进行类型检查。但是,方程式显示了以下警告,给我留下了一个证明义务,我不知道如何完成它
在定义上一个函数后显示的消息是:
Warning:
In environment
eos : end_of_section
fix_0 : forall (n : nat) (A : Type) (P : A -> Type) (xs : vec A n)
(idx : fin n) (v : vforall P xs),
vforall_lookup_ind n A P xs idx v (vforall_lookup idx v)
A : Type
P : A -> Type
n0 : nat
x : A
xs0 : vec A n0
idx : fin n0
p : P x
v : vforall P xs0
Unable to unify "VFCons P n0 x xs0 p v" with "v".
剩下的义务是
Obligation 1 of vforall_lookup_ind_fun:
(forall (n : nat) (A : Type) (P : A -> Type) (xs : vec A n)
(idx : fin n) (v : vforall P xs),
vforall_lookup_ind n A P xs idx v (vforall_lookup idx v)).
后来,在查看Agda标准库中的类似定义后,我意识到前面的函数定义缺少空向量的一个案例:
lookup : ∀ {a p} {A : Set a} {P : A → Set p} {k} {xs : Vec A k} →
(i : Fin k) → All P xs → P (Vec.lookup i xs)
lookup () []
lookup zero (px ∷ pxs) = px
lookup (suc i) (px ∷ pxs) = lookup i pxs
我的问题是,对于空向量的情况,我如何指定右手边应该是空的,即矛盾?《方程式手册》给出了一个等式的例子,但我可以将其应用于这种情况。知道我做错了什么吗 我想,通过仔细观察生成的义务,我终于理解了这个示例中发生的事情 该定义是正确的,您可以使用vforall_查找而不必解决义务。未能生成的是与函数相关的归纳原理 更准确地说,方程式通过三个步骤生成正确的归纳原理,这在章节中的消除原理中有详细说明: 它在我的方程式版本中生成函数图,称为vforall_lookup_graph,在以前的版本中称为vforall_lookup_ind。我不确定我是否完全理解它。直观地说,它反映了函数体的结构。在任何情况下,它都是生成归纳原理的关键组成部分 证明了函数在一个称为vforall_lookup_graph_correct或vforall_lookup_ind_fun的引理中尊重这个图 它将最后两个结果结合起来,生成与该引理在所有版本中称为vforall_lookup_elim的函数相关联的归纳原理 在您的例子中,图形是正确生成的,但方程式无法自动证明函数遵守其图形步骤2,因此留给您处理 让我们试一试吧
Next Obligation.
induction v.
- inversion idx.
- dependent elimination idx.
(* a powerful destruct provided by Equations
that correctly working with dependent types
*)
+ constructor.
+ constructor.
Coq拒绝最后一次调用构造函数,错误为
Unable to unify "VFCons P n1 x xs p v" with "v".
这看起来真的像是一开始就得到的错误,所以我认为自动分辨率达到了同样的点并且失败了。这是否意味着我们走错了路?让我们在第二个构造函数之前仔细看看目标
我们必须证明
vforall_lookup_graph (S n1) A P (VCons x xs) (FSucc f) (VFCons P n1 x xs p v) (vforall_lookup (FSucc f) (VFCons P n1 x xs p v))
当vforall_lookup_graph_等式的类型为2时,vforall_lookup_graph_等式的第二个构造函数为
区别在于对vforall_lookup的调用。在第一种情况下,我们有
vforall_lookup (FSucc f) (VFCons P n1 x xs p v)
在第二种情况下
vforall_lookup f v
但根据vforall_查找的定义,这些是相同的!但在默认情况下,统一没有认识到这一点。我们需要帮点忙。我们可以给出某个参数的值,例如
apply (vforall_lookup_graph_equation_2 n0).
或者我们可以使用精确的或精炼的方法来统一,因为它们被赋予了整个术语,而不仅仅是它的头部
refine (vforall_lookup_graph_equation_2 _ _ _ _ _ _ _ _ _).
我们可以很容易地通过归纳假设得出结论。这提供了以下证据
Next Obligation.
induction v.
- inversion idx.
- dependent elimination idx.
+ constructor.
+ (* IHv is the induction hypothesis *)
exact (vforall_lookup_graph_equation_2 _ _ _ _ _ _ _ _ (IHv _)).
Defined.
因为我喜欢用手做依赖类型的证明,所以我不得不给出一个不使用依赖消除的证明
在我看来,您可以尝试将此报告为服务器上的bug。在最好的情况下,这是一个bug。在任何情况下,你都会有一个问题的答案。有点晚了,但你可以有类似foo zero_case的东西:=\u然后你必须证明一些东西,你的矛盾通常会出现在那里。
Next Obligation.
induction v.
- inversion idx.
- dependent elimination idx.
+ constructor.
+ (* IHv is the induction hypothesis *)
exact (vforall_lookup_graph_equation_2 _ _ _ _ _ _ _ _ (IHv _)).
Defined.
Next Obligation.
induction v.
- inversion idx.
- revert dependent xs.
refine (
match idx as id in fin k return
match k return fin k -> Type with
| 0 => fun _ => IDProp
| S n => fun _ => _
end id
with
| FZero => _
| FSucc f => _
end); intros.
+ constructor.
+ exact (vforall_lookup_graph_equation_2 _ _ _ _ _ _ _ _ (IHv _)).
Defined.