我正在尝试处理ssreflect中的规范结构。我从here获取了2段代码。
我将为bool和选项类型带来碎片。
Section BoolFinType.
Lemma bool_enumP : Finite.axiom [:: true; false]. Proof. by case. Qed.
Definition bool_finMixin := Eval hnf in FinMixin bool_enumP.
Canonical bool_finType := Eval hnf in FinType bool bool_finMixin.
Lemma card_bool : #|{: bool}| = 2. Proof. by rewrite cardT enumT unlock. Qed.
End BoolFinType.
Section OptionFinType.
Variable T : finType.
Notation some := (@Some _) (only parsing).
Local Notation enumF T := (Finite.enum T).
Definition option_enum := None :: map some (enumF T).
Lemma option_enumP : Finite.axiom option_enum.
Proof. by case => [x|]; rewrite /= count_map (count_pred0, enumP). Qed.
Definition option_finMixin := Eval hnf in FinMixin option_enumP.
Canonical option_finType := Eval hnf in FinType (option T) option_finMixin.
Lemma card_option : #|{: option T}| = #|T|.+1.
Proof. by rewrite !cardT !enumT {1}unlock /= !size_map. Qed.
End OptionFinType.
现在,假设我有一个从finType到Prop的函数f。
Variable T: finType.
Variable f: finType -> Prop.
Goal f T. (* Ok *)
Goal f bool. (* Not ok *)
Goal f (option T). (* Not ok *)
在最后两种情况下,我收到以下错误:
术语“bool / option T”的类型为“Set / Type”,而它的类型为“finType”。
我做错了什么?
答案 0 :(得分:7)
在这些情况下,规范结构的实例搜索有点反直觉。假设您有以下事项:
S
和类型T
; proj : S -> T
的字段S
; x : T
;和st : S
,以便将proj st
定义为x
。在您的示例中,我们将:
S = finType
T = Type
proj = Finite.sort
x = bool
st = bool_finType
。在以下情况下,典型结构搜索仅触发:当类型检查算法试图找到一个值以有效地填充等式proj _ = x
中的孔时。然后,它将使用st : S
来填补此漏洞。在您的示例中,您希望算法通过将bool
转换为finType
来理解bool_finType
可以用作Variable P : finType -> Prop.
Check ((fun (T : finType) (x : T) => P T) _ true).
,这与上面描述的不完全相同。
要使Coq推断出您想要的内容,您需要使用该表单的统一问题。例如,
Finite.sort
这里发生了什么?请注意,finType
被声明为从Type
到x : T
的强制,因此x : Finite.sort T
实际上意味着fun
。将true : bool
表达式应用于Finite.sort _ = bool
时,Coq必须找到bool_finType
的解决方案。然后它找到bool
,因为它被声明为规范。因此bool
的元素是触发搜索的元素,但不是[finType of ...]
本身。
正如ejgallego所指出的,这种模式非常常见,以至于ssreflect提供了特殊的{{1}}语法。但是了解幕后发生的事情可能仍然有用。