かなり単純な型階層を作成しようとしています。最小限の作業例を次に示します。
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
to R0
(またはSortclass
) からの型強制は 2 つの異なるパスを取ることができます。そして、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 に納得させる方法はありますか?