我有时想为现有函数定义一些快捷方式,如下例所示:
Parameter T : Set.
Parameter zero one: T.
Parameter f : T -> T -> option T.
Hypothesis f_unit : forall t, f zero t = None.
Definition g (t : T) := f t one.
然而,这个定义似乎是抽象的,因为在没有首先展开的情况下我不能在f
的实例上使用关于g
的定理:
Goal (g zero = None).
unfold g.
rewrite f_unit.
reflexivity.
Qed.
有没有办法将定义标记为自动展开?
答案 0 :(得分:5)
有几种方法可以完成你的要求,这里是我所知道的解释:
缩写是一个名称,可能应用于参数,表示(可能)更复杂的表达。
[...]
缩写与普通定义绑定为绝对名称,并且也可以通过限定名称引用。
缩写词是句法语法,因为它们与缩写词定义时但未使用的表达式绑定在一起。
在你的情况下,这将是
Notation g t := (f t one).
这很像Daniel Schepler关于Notation
的建议,除了它不会将g
保留为全局关键字。
setoid_rewrite
。 Coq的setoid_rewrite
策略类似于rewrite
,除了它寻找以模δ(展开)为模的出现,可以在绑定下重写,以及其他一些小事。对于您的示例,这是:
Require Import Coq.Setoids.Setoid.
Goal (g zero = None).
Proof.
setoid_rewrite f_unit.
reflexivity.
Qed.
Set Keyed Unification
和Declare Equivalent Keys
,但这不适用于您的情况(我已经打开了问题on GitHub here。这告诉rewrite
将一个头部“展开”到另一个头部,虽然它显然不足以处理你的情况。有一些文档on the relevant commit message和一个open issue to add proper documentation。以下是一个有用的示例:
Parameter T : Set.
Parameter zero one: T.
Parameter f : T -> T -> option T.
Hypothesis f_unit : forall t, f zero t = None.
Definition g := f zero zero.
Set Keyed Unification.
Goal (g = None).
Proof.
Fail rewrite f_unit.
Declare Equivalent Keys g f.
rewrite f_unit.
reflexivity.
Qed.