Coq 如何定义自动展开的定义

Coq 如何定义自动展开的定义,coq,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. 然而,这个定义似乎是抽象的,因为我不能在不首先展开的情况下,在g的实例上使用关于f的定理: Goal (g zero

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

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.
然而,这个定义似乎是抽象的,因为我不能在不首先展开的情况下,在
g
的实例上使用关于
f
的定理:

Goal (g zero = None).
  unfold g.
  rewrite f_unit.
  reflexivity.
Qed.

有没有一种方法可以将定义标记为自动展开的?

有几种方法可以实现您的要求,下面是我所知道的一些方法的解释:


  • 使用缩写。引述: 缩写是一个名称,可能用于参数,表示(可能)更复杂的表达式

    [……]

    缩略语和普通的定义一样,被绑定到绝对名称上,它们也可以被限定名称引用

    缩略语是句法上的,因为它们与定义缩略语时未键入但使用缩略语时未键入的表达式相关联

  • 在你的情况下,这将是

    Notation g t := (f t one).
    
    这很像Daniel Schepler提出的
    表示法
    ,只是它没有将
    g
    保留为全局关键字


  • 使用
    setoid\u重写
    。Coq的
    setoid_rewrite
    策略类似于
    rewrite
    ,只是它寻找模δ(展开)出现的情况,可以在绑定器下重写,以及其他一些小事情
  • 例如,这是:

    Require Import Coq.Setoids.Setoid.
    Goal (g zero = None).
    Proof.
      setoid_rewrite f_unit.
      reflexivity.
    Qed.
    

  • 在某些情况下,您可以使用
    设置密钥统一
    声明等效密钥
    ,尽管这在您的情况下不起作用(我已经打开了一个问题。这会告诉
    重写
    “展开”一个头和另一个头是常数,虽然这显然不足以处理你的案子。有一些文档,还有一个
  • 以下是一个有用的示例:

    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.
    

    是的,我不想手动
    展开
    。您可以允许
    siml
    通过声明
    Arguments gt/
    来扩展
    g
    的定义,或者将
    g
    定义为“仅解析”简写符号而不是函数。类似于:
    符号“'g't”:=(f t one)(在级别0,仅解析).
    提示展开g.
    然后在证明中使用
    自动展开
    策略。此外,ssreflect可以通过上下文模式来实现:
    需要导入ssreflect。
    然后您的目标可以通过重写[g\u]f\u单元来证明。
    。此
    [g\u]
    pattern使
    rewrite
    展开
    g
    的定义。