coq - 如何在 Coq 简化过程中应用一次函数?

标签 coq coq-tactic

据我了解,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 为您执行一些计算,您可以使用 simplcomputevm_compute。如果函数的定义是不透明,则上述解决方案将失败,但您可以首先证明重写引理,例如:

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

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

这是一个使用 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 效果更好。

关于coq - 如何在 Coq 简化过程中应用一次函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33060802/

相关文章:

Coq:为什么我需要手动展开一个值,即使它上面有 `Hint Unfold`?

coq - 展开定义而不减少

coq - 在 Coq 中,组合尝试和重复会导致无限循环吗?

coq - 如何在 Coq 中使用自定义归纳原理?

coq - 如何在特定子表达式中应用重写?

haskell - 是否有可能推导出教堂编码的 Nat 的归纳法?

coq - 为什么在 coqide 中使用 _CoqProject 的 `make` 与命令行上的 `coqc` 不同?

coq - Coq 中的析取三段论策略?

Coq:在假设或目标中用 'forall' 重写

coq - 如何在自定义策略中利用汽车的搜索和提示数据库?