为什么这个 Coq 定义失败了?归纳类型的 Coq 命名空间错误
Why does this Coq Definition fail? Coq Namespace error for Inductive Type
我有以下感应类型和测试功能:
Inductive parameter : Type :=
| Nop
| OneP : forall A, A -> parameter
| TwoP : forall (A : Type) (r : nat) (b : A), parameter
.
Check (TwoP nat 1 5).
Definition test (p : parameter) : option (nat * nat) :=
match p with
| TwoP nat x y => Some (x, y)
| _ => None
end.
测试函数失败并出现错误:
术语“Some (x, y)”的类型为“option (Datatypes.nat * nat)”
虽然它应该具有类型“选项(Datatypes.nat * Datatypes.nat)”。
我不明白为什么我的定义不起作用。 nat 和 Datataypes.nat 有区别吗?
如有任何帮助,我们将不胜感激。谢谢!
在 Coq 中,无法测试类型是什么。考虑以下程序:
Definition is_nat (A : Type) : bool :=
match A with
| nat => true
| _ => false
end.
如果您尝试 运行 这个,Coq 会告诉您最后一个分支是多余的,并拒绝该定义。问题是 nat
被当作变量名,而不是标准库中的 nat
数据类型。因此,第一个分支匹配每个类型 A
,最后一个分支是多余的。在您的示例中,模式 nat
最终屏蔽了数据类型 nat
,这就是您最终看到限定名称 Datatypes.nat
.
的原因
解决此问题的一种方法是使用一种 代码 而不是 Type
。例如:
Inductive type : Type :=
| Bool
| Nat.
Definition type_denote t : Type :=
match t with
| Bool => bool
| Nat => nat
end.
Coercion type_denote : type >-> Sortclass.
Inductive parameter : Type :=
| Nop
| OneP : forall (A : type), A -> parameter
| TwoP : forall (A : type) (r : nat) (b : A), parameter
.
Check (TwoP Nat 1 5).
Definition test (p : parameter) : option (nat * nat) :=
match p with
| TwoP Nat x y => Some (x, y)
| _ => None
end.
这个解决方案有两个问题。首先,它要求您预测 parameter
中需要的所有类型,并将它们添加到 type
的定义中。其次,它迫使您使用难以操作的依赖类型进行编程。尽管没有 one-size-fits-all 解决方案 -- 这取决于您的应用程序,但可以重构您的定义来完全避免类型匹配问题。
我有以下感应类型和测试功能:
Inductive parameter : Type :=
| Nop
| OneP : forall A, A -> parameter
| TwoP : forall (A : Type) (r : nat) (b : A), parameter
.
Check (TwoP nat 1 5).
Definition test (p : parameter) : option (nat * nat) :=
match p with
| TwoP nat x y => Some (x, y)
| _ => None
end.
测试函数失败并出现错误:
术语“Some (x, y)”的类型为“option (Datatypes.nat * nat)” 虽然它应该具有类型“选项(Datatypes.nat * Datatypes.nat)”。
我不明白为什么我的定义不起作用。 nat 和 Datataypes.nat 有区别吗?
如有任何帮助,我们将不胜感激。谢谢!
在 Coq 中,无法测试类型是什么。考虑以下程序:
Definition is_nat (A : Type) : bool :=
match A with
| nat => true
| _ => false
end.
如果您尝试 运行 这个,Coq 会告诉您最后一个分支是多余的,并拒绝该定义。问题是 nat
被当作变量名,而不是标准库中的 nat
数据类型。因此,第一个分支匹配每个类型 A
,最后一个分支是多余的。在您的示例中,模式 nat
最终屏蔽了数据类型 nat
,这就是您最终看到限定名称 Datatypes.nat
.
解决此问题的一种方法是使用一种 代码 而不是 Type
。例如:
Inductive type : Type :=
| Bool
| Nat.
Definition type_denote t : Type :=
match t with
| Bool => bool
| Nat => nat
end.
Coercion type_denote : type >-> Sortclass.
Inductive parameter : Type :=
| Nop
| OneP : forall (A : type), A -> parameter
| TwoP : forall (A : type) (r : nat) (b : A), parameter
.
Check (TwoP Nat 1 5).
Definition test (p : parameter) : option (nat * nat) :=
match p with
| TwoP Nat x y => Some (x, y)
| _ => None
end.
这个解决方案有两个问题。首先,它要求您预测 parameter
中需要的所有类型,并将它们添加到 type
的定义中。其次,它迫使您使用难以操作的依赖类型进行编程。尽管没有 one-size-fits-all 解决方案 -- 这取决于您的应用程序,但可以重构您的定义来完全避免类型匹配问题。