【问题标题】:How to apply a function once during simplification in Coq?如何在 Coq 的简化过程中应用一次函数?
【发布时间】:2015-10-11 01:55:22
【问题描述】:

据我了解,Coq 中的函数调用是不透明的。 有时,我需要使用unfold 来应用它,然后fold 将函数定义/主体转回其名称。这通常很乏味。我的问题是,有没有更简单的方法来应用函数调用的特定实例?

作为一个最小的例子,对于一个列表l,证明右附加[]不会改变l

Theorem nil_right_app: forall {Y} (l: list Y), l ++ [] = l.
Proof.
  induction l. 
    reflexivity. 

这就离开了:

1 subgoals
Y : Type
x : Y
l : list Y
IHl : l ++ [] = l
______________________________________(1/1)
(x :: l) ++ [] = x :: l

现在,我需要应用一次++(即app)的定义(假设目标中有其他++,我不想应用/扩展)。目前,我知道实现这个一次性应用程序的唯一方法是首先展开 ++ 然后折叠它:

    unfold app at 1. fold (app l []).

给予:

______________________________________(1/1)
x :: l ++ [] = x :: l

但这很不方便,因为我必须弄清楚fold 中使用的术语的形式。我做了计算,而不是 Coq。我的问题归结为:

有没有更简单的方法来实现这个一次性功能应用达到同样的效果?

【问题讨论】:

  • 所有 Coq 的定义都不是不透明的,但有一些方法可以防止 Coq 自动展开定义(例如,在使用策略定义函数时使用 Qed. 而不是 Defined)。
  • 不透明是什么意思?

标签: coq coq-tactic


【解决方案1】:

如果你想让 Coq 为你执行一些计算,你可以使用 simplcomputevm_compute。如果函数的定义是Opaque,上面的解决方案会失败,但是你可以先证明一个重写引理,例如:

forall (A:Type) (a:A) (l1 l2: list A), (a :: l1) ++ l2 = a :: (l1 ++ l2).

使用您的技术,然后在必要时使用rewrite

这里是一个使用simpl的例子:

Theorem nil_right_app: forall {Y} (l: list Y), l ++ nil = l.
Proof.
(* solve the first case directly *)
intros Y; induction l as [ | hd tl hi]; [reflexivity | ]. 
simpl app. (* or simply "simpl." *)
rewrite hi.
reflexivity.
Qed.

要回答您的评论,我不知道如何告诉 cbvcompute 只计算某个符号。请注意,在您的情况下,它们似乎过于急切地计算,simpl 效果更好。

【讨论】:

  • 谢谢。您的意思是我可以使用“compute”之类的“compute app at 1”或类似的东西吗?如果是这样,你能举个例子吗?我查看了计算和 cbv 的 coq 文档,但找不到具体示例。
  • 用一个例子和几句话更新
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-28
  • 1970-01-01
相关资源
最近更新 更多