如何使用依赖类型在 Coq 中构建仅包含真实元素的列表?

发布于 2025-01-15 11:45:43 字数 1082 浏览 1 评论 0原文

我正在从数学角度阅读 Coq 书。我试图定义一个依赖类型的函数,它返回一个包含 n 个 true 的长度列表,具体取决于我们想要的 true 数量。 Coq 抱怨事物没有正确的类型,但是当我看到它时,如果它在进行类型比较时展开我的定义,它应该可以工作,但事实并非如此。为什么?

代码:

Module playing_with_types2.
  Inductive Vector {A: Type} : nat -> Type :=
  | vnil: Vector 0
  | vcons: forall n : nat, A -> Vector n -> Vector (S n).

  Definition t {A: Type} (n : nat) : Type :=
    match n with
    | 0 => @Vector A 0
    | S n' => @Vector A (S n')
    end.
  Check t. (* nat -> Type *)
  Check @t. (* Type -> nat -> Type *)

  (* meant to mimic Definition g : forall n: nat, t n. *)
  Fixpoint g (n : nat) : t n :=
    match n with
    | 0 => vnil
    | S n' => vcons n' true (g n')
    end.
End playing_with_types2.

Coq 的错误:

In environment
g : forall n : nat, t n
n : nat
The term "vnil" has type "Vector 0" while it is expected to have type
 "t ?n@{n1:=0}".
Not in proof mode.

t ?n@{n1:=0}Vector 0...不是吗?

I was going through the Coq book from the maths perspective. I was trying to define a dependently typed function that returned a length list with n trues depending on the number trues we want.
Coq complains that things don't have the right type but when I see it if it were to unfold my definitions when doing the type comparison it should have worked but it doesn't. Why?

Code:

Module playing_with_types2.
  Inductive Vector {A: Type} : nat -> Type :=
  | vnil: Vector 0
  | vcons: forall n : nat, A -> Vector n -> Vector (S n).

  Definition t {A: Type} (n : nat) : Type :=
    match n with
    | 0 => @Vector A 0
    | S n' => @Vector A (S n')
    end.
  Check t. (* nat -> Type *)
  Check @t. (* Type -> nat -> Type *)

  (* meant to mimic Definition g : forall n: nat, t n. *)
  Fixpoint g (n : nat) : t n :=
    match n with
    | 0 => vnil
    | S n' => vcons n' true (g n')
    end.
End playing_with_types2.

Coq's error:

In environment
g : forall n : nat, t n
n : nat
The term "vnil" has type "Vector 0" while it is expected to have type
 "t ?n@{n1:=0}".
Not in proof mode.

i.e. t ?n@{n1:=0} is Vector 0...no?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不奢求什么 2025-01-22 11:45:43

在这种情况下,Coq 似乎无法推断 match 表达式的返回类型,因此最好的办法是显式给出它:

Fixpoint g (n : nat) : t n :=
  match n return t n with
  | 0 => vnil
  | S n' => vcons n' true (g n')
  end.

注意添加的 return 条款。

然后出现真正的错误消息:

In environment
g : forall n : nat, t n
n : nat
n' : nat
The term "g n'" has type "t n'" while it is expected to have type "Vector n'".

这次确实是,一般来说 t n'Vector n' 不同,因为 t n' 被卡住(它还不知道 n'0 还是某个 S n'')。

In this case, it looks like Coq does not manage to infer the return type of the match expression, so the best thing to do is to give it explicitly:

Fixpoint g (n : nat) : t n :=
  match n return t n with
  | 0 => vnil
  | S n' => vcons n' true (g n')
  end.

Note the added return clause.

Then the real error message appears:

In environment
g : forall n : nat, t n
n : nat
n' : nat
The term "g n'" has type "t n'" while it is expected to have type "Vector n'".

And this time it is true that in general t n' is not the same as Vector n' because t n' is stuck (it does not know yet whether n' is 0 or some S n'').

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文