与类型系列匹配时的Coq类型错误

时间:2016-07-15 12:14:51

标签: coq

我正在尝试从内存中重新实现CPDT的示例。我写道:

Inductive myType : Set := MyNat | MyBool.

Definition typeDenote (t : myType) : Set :=
  match t with
    | MyNat => nat
    | MyBool => bool
  end.

Inductive unaryOp : myType -> myType -> Set :=
| Twice : unaryOp MyNat MyNat.

Definition twice (n:nat) : nat := n + n.

Definition tunaryDenote (a b : myType) (t : unaryOp a b)
    : typeDenote a -> typeDenote b :=
  match t with
  | Twice => twice
  end.

产生的错误是:

Toplevel input, characters 125-130
>   | Twice => twice
>              ^^^^^
Error: In environment
a : myType
b : myType
t : unaryOp a b
The term "twice" has type "nat -> nat" while it is expected to have type
 "forall H : typeDenote ?141, typeDenote ?142"

我不明白这个错误信息。我认为,一旦Twice : unaryOp MyNat MyNat上的匹配成功,Coq就会推断abMyNat,因此typeDenote a -> typeDenote b ≡ nat -> nattwice返回值的完美候选者。我哪里出错?

3 个答案:

答案 0 :(得分:1)

就像@AntonTrunov所说的那样,我的Coq 8.5pl1没有任何问题。但是,如果您需要为您的版本添加一些额外的注释来接受该功能,您需要have a look at this section of the manual来确定要做什么。

我的猜测是你希望有一个match ... in ... return ... with表示返回类型应该精炼通过匹配类型unaryOp a b获得的信息(确实:ab将在Twice分支中采用具体值。

这是您使用该技术获得的定义:

Definition tunaryDenote (a b : myType) (t : unaryOp a b)
    : typeDenote a -> typeDenote b :=
  match t in unaryOp a b return typeDenote a -> typeDenote b with
  | Twice => twice
  end.

答案 1 :(得分:0)

我认为答案是Coq的类型推断是有限的,并没有做你想要的推理。

Coq的类型推断不是任意计算,而是简单统一。它会查看twice,了解它是nat->nat,并得出结论:它不是(语法上)typeDenote a -> TypeDenote b形式。

如果它正在进行计算,它可能是非终止的,因为它的类型系统非常复杂,所以你可以在那里编码非平凡的计算。

答案 2 :(得分:0)

我尝试了更新版本的Coq,和其他人一样说,它在Coq 8.5上没有问题。 :)