使用公式在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

我试图用package在Coq中定义向量上的函数。下面提供了显示我将描述的问题的最少代码

我的想法是编写一个函数,该函数对某个类型适用于向量所有元素的证明进行查找,该证明具有标准定义:

  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.