Multiple inheritance 致命的死亡钻石

Multiple inheritance 致命的死亡钻石,multiple-inheritance,coq,coercion,diamond-problem,Multiple Inheritance,Coq,Coercion,Diamond Problem,我试图创建一个相当直接的类型层次结构。下面是一个简单的工作示例: 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 :

我试图创建一个相当直接的类型层次结构。下面是一个简单的工作示例:

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
实际上,从
R12
R0
(或
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相信这没问题?

我认为没有办法让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.
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.
请注意,类
R12
没有自己的任何方法,但要求类型
t
同时作为
R1
R2
的实例,这在道德上导致了相同的结果。
上下文
声明强制Coq根据这些要求自动假设
R1
R2
的实例

编辑:

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

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.
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.

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

但是您似乎已经移除了菱形的底部(
R0
)。这也适用于
Record
s。如果我尝试将
类R0(T:Type):={}.
添加到您的层次结构中,并相应地“增强”
R1
R2
,您将在
id1
处得到一个错误。一种与以前不同的错误,但我相信,基于相同的问题。嗯。。。似乎只要将
e:T
这样的成员放入
R0
的定义中,就可以再次检查所有类型无论如何,如果你能扩充你的例子并解释这个奇怪的现象,我将不胜感激!:-)在那里,我刚刚找到了如何将
R0
添加到图表中!是的,我后来想出了一个不同的解决方案,但似乎归结为同一件事。谢谢!:-)