list - Coq:依赖列表上的类型不匹配可以通过证明来解决

标签 list coq dependent-type theorem-proving

在我最后一次使用 coq 中的列表时,我遇到了一个类型问题。但首先是定义;


休闲 list :

Inductive list (a : Set) : Set :=
| nil : list a
| cons : a -> list a -> list a
.

Fixpoint len {a : Set} (l : list a) : nat :=
  match l with
  | nil _ => 0
  | cons _ _ t => 1 + (len t)
  end.

家属名单:

Inductive dlist (a : Set) : nat -> Set :=
| dnil : dlist a 0
| dcons : a -> forall n, dlist a n -> dlist a (S n)
.

转化:

Fixpoint from_d {a : Set} {n : nat} (l : dlist a n) : list a :=
  match l with
  | dnil _ => nil _
  | dcons _ h _ t => cons _ h (from_d t)
  end.

Fixpoint to_d {a : Set} (l : list a) : dlist a (len l) :=
  match l with
  | nil _ => dnil _
  | cons _ h t => dcons _ h _ (to_d t)
  end.

严格来说,我想证明转换回旋处

Theorem d_round : forall (a : Set) (n : nat) (l : dlist a n),
    to_d (from_d l) = l.

但是我得到以下错误:

The term "l" has type "dlist a n" while it is expected to have type
 "dlist a (len (from_d l))".

这很容易理解,但我完全不知道如何解决它。我可以很容易地证明

forall (a : Set) (n : nat) (l : dlist a n), n = len (from_d l).

但我看不出有什么方法可以使用这个定理让 Coq 相信列表的长度保持不变。怎么做?

最佳答案

你要证明的是异质等式,lto_d(from_d l) 有不同的类型,因此不能与同质等式比较 (=)

如果理论是外延的,那将是另一回事(相同类型可以转换),但是您必须手动处理这种差异。 一种方法是定义一些符合莱布尼茨原理的 transport:从 x = y 推导出 P x -> P y对于任何 P

Definition transport {A} {x y : A} (e : x = y) {P : A -> Type} (t : P x) : P y :=
  match e with
  | eq_refl => t
  end.

在您的情况下,它将是 n = m -> dlist A n -> dlist A m,因此您甚至可以使用专门的版本。

定理可以表述为:

Axiom e : forall (a : Set) (n : nat) (l : dlist a n), n = len (from_d l).

Theorem d_round : 
  forall (A : Set) (n : nat) (l : dlist A n),
    to_d (from_d l) = transport (e _ _ _) l.

现在你必须处理阻碍你前进的相等性,但是自然数上的相等性是可判定的,因此是一个命题(n = m 的任何两个证明总是相等的,特别是任何n = n 的证明等于 eq_refl;与 transport eq_refl t = t 完美结合的事实。

关于list - Coq:依赖列表上的类型不匹配可以通过证明来解决,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59593179/

相关文章:

coq - 关于何时使用 Prop 和何时使用 bool 的一般建议

coq - 在 Coq 中测试类的好方法

dependent-type - Idris 中的“半”函数类型签名

Haskell 嵌套函数顺序

agda -\forall (∀) 在签名中实际上是什么意思?

c++ - 如何根据位置删除列表中的特定项目

SwiftUI 更新导航操作的状态

coq - 如何通过等式证明进行推理?

python - 插入列表时数字发生变化

list - 区 block 链是单链表吗?