0

我正在尝试创建一个相当直接的类型层次结构。这是一个最小的工作示例:

Record R0 : Type := {
  R0_S :> Type
}.

Record R1 : Type := {
  R1_S   : Type;
  op1    : R1_S -> R1_S
}.

Record R2 : Type := {
  R2_S   : Type;
  op2    : R2_S -> R2_S
}.

Record R12: Type := {
  R12_S   : Type;
  R12_op1 : R12_S -> R12_S;
  R12_op2 : R12_S -> R12_S
}.

Definition R1_0 (r1: R1) := (Build_R0 (R1_S r1)).
Coercion   R1_0 : R1 >-> R0.

Definition R2_0 (r2: R2) := (Build_R0 (R2_S r2)).
Coercion   R2_0 : R2 >-> R0.

Definition R12_1 (r12: R12) := (Build_R1 (R12_S r12) (R12_op1 r12)).
Coercion   R12_1 : R12 >-> R1.

Definition R12_2 (r12: R12) := (Build_R2 (R12_S r12) (R12_op2 r12)).
Coercion   R12_2 : R12 >-> R2.  (* Warning *)

最后一次强制生成以下警告:

Ambiguous paths:
[R12_2; R2_0] : R12 >-> R0
[R12_2; R2_0; R0_S] : R12 >-> Sortclass
R12_2 is now a coercion

实际上,从R12to R0(or Sortclass) 的强制转换可以采用两种不同的路径。而且我理解为什么 Coq 在一般情况下会不允许这样做。因为……它们中的哪一个会被使用?

但是,在这种情况下,可以证明两条路径的强制转换R1_0 (R12_1 r12)R2_0 (R12_2 r12)完全相同的。但我仍然无法添加以下看似有效的公理:

Parameter r12 : R12.
Parameter x : r12.
Axiom id1 : (op1 _ x) = x.  (* OK    *)
Axiom id2 : (op2 _ x) = x.  (* Error *)

问题:那么有没有办法让 Coq 相信这是可以的?

4

1 回答 1

1

我相信没有办法让 Coq 相信这是可以的。但是,您可以通过使用其他功能(例如规范结构或类型类)来获得类似的效果。这就是如何使用类型类来翻译您的示例,例如:

Class R1 T :=
{
  op1 : T -> T
}.

Class R2 T :=
{
  op2 : T -> T
}.

Class R12 T `{R1 T} `{R2 T} :=
{}.

Section S.

Context T `{R12 T}.
Variable x : T.

Hypothesis id1 : op1 x = x.
Hypothesis id2 : op2 x = x.

End S.

请注意,类R12没有任何自己的方法,但要求 typeT是 and 的实例R1R2这在道德上会导致相同的结果。该Context声明强制 Coq 依据这些要求自动假设R1实例R2

编辑:

如果你尝试添加一个R0类来完成图表,你可能会因为类型类推断失败而得到一个奇怪的错误。一种解决方案是关闭自动泛化R12(即删除反引号),并强制R1R2基于相同的R0实例:

Class R0 (T : Type) := {}.

Class R1 T `{R0 T} :=
{
  op1 : T -> T
}.

Class R2 T `{R0 T} :=
{
  op2 : T -> T
}.

Class R12 T `{R0 T} {r1:R1 T} {r2:R2 T} :=
{}.

Section S.

Context T `{R12 T}.
Variable x : T.

Hypothesis id1 : op1 x = x.
Hypothesis id2 : op2 x = x.

End S.

不幸的是,我并没有很好地解释为什么会在那里发生错误,因为类型类推断有些复杂。但是,我认为这与您首先遇到的问题无关,因为实际上并没有像以前那样模棱两可的路径。

于 2013-06-03T14:54:01.253 回答