如何定义自动展开的定义

时间:2017-12-01 13:41:42

标签: coq

我有时想为现有函数定义一些快捷方式,如下例所示:

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.

有没有办法将定义标记为自动展开?

1 个答案:

答案 0 :(得分:5)

有几种方法可以完成你的要求,这里是我所知道的解释:

  1. 使用缩写。引用the reference manual
      

    缩写是一个名称,可能应用于参数,表示(可能)更复杂的表达。

         

    [...]

         

    缩写与普通定义绑定为绝对名称,并且也可以通过限定名称引用。

         

    缩写词是句法语法,因为它们与缩写词定义时但未使用的表达式绑定在一起。

  2. 在你的情况下,这将是

    Notation g t := (f t one).
    

    这很像Daniel Schepler关于Notation的建议,除了它不会将g保留为全局关键字。

    1. 使用setoid_rewrite。 Coq的setoid_rewrite策略类似于rewrite,除了它寻找以模δ(展开)为模的出现,可以在绑定下重写,以及其他一些小事。
    2. 对于您的示例,这是:

      Require Import Coq.Setoids.Setoid.
      Goal (g zero = None).
      Proof.
        setoid_rewrite f_unit.
        reflexivity.
      Qed.
      
      1. 在某些情况下,您可以使用Set Keyed UnificationDeclare Equivalent Keys,但这不适用于您的情况(我已经打开了问题on GitHub here。这告诉rewrite将一个头部“展开”到另一个头部,虽然它显然不足以处理你的情况。有一些文档on the relevant commit message和一个open issue to add proper documentation
      2. 以下是一个有用的示例:

        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.