这是一个递归函数all_zero
,用于检查自然数列表中的所有成员是否为零:
Require Import Lists.List.
Require Import Basics.
Fixpoint all_zero ( l : list nat ) : bool :=
match l with
| nil => true
| n :: l' => andb ( beq_nat n 0 ) ( all_zero l' )
end.
现在,假设我有以下目标
true = all_zero (n :: l')
我想用unfold
策略将其转换为
true = andb ( beq_nat n 0 ) ( all_zero l' )
不幸的是,我无法使用简单的unfold all_zero
来执行此操作,因为该策略会热切地查找并替换all_zero
的所有实例,包括曾经展开形式的实例,以及变成一团糟。有没有办法避免这种情况,只展开一次递归函数?
我知道我可以通过证明与assert (...) as X
的临时等价来获得相同的结果,但效率很低。我想知道是否有一种类似于unfold
的简单方法。
答案 0 :(得分:5)
尝试
unfold all_zero; fold all_zero.
至少在我这里产生:
true = (beq_nat n 0 && all_zero l)%bool
答案 1 :(得分:4)
在我看来simpl
会做你想做的事。如果你有一个更复杂的目标,你想要应用的函数和你希望保持原样的函数,你可能需要使用cbv
策略的各种选项(参见http://coq.inria.fr/distrib/current/refman/Reference-Manual010.html#hevea_tactic127)