背景:我正在Software Foundations进行练习。
Theorem neg_move : forall x y : bool,
x = negb y -> negb x = y.
Proof. Admitted.
Theorem evenb_n__oddb_Sn : forall n : nat,
evenb n = negb (evenb (S n)).
Proof.
intros n. induction n as [| n'].
Case "n = 0".
simpl. reflexivity.
Case "n = S n'".
rewrite -> neg_move.
在最后一行之前,我的子目标就是:
evenb (S n') = negb (evenb (S (S n')))
我想把它变成这个:
negb (evenb (S n')) = evenb (S (S n'))
但是,当我尝试单步执行rewrite -> neg_move
时,会产生此错误:
错误:无法找到变量y的实例。
我确信这很简单,但我做错了什么? (请不要为解决evenb_n__oddb_Sn
提供任何帮助,除非我这样做完全错了。)
答案 0 :(得分:10)
正如danportin所说,Coq告诉你它不知道如何实例化y
。实际上,当您执行rewrite -> neg_move
时,您要求它用negb x
替换某些y
。现在,Coq应该在这里使用y
?它无法理解。
一种选择是在重写时明确地实例化y
:
rewrite -> neg_move with (y:=some_term)
这将执行重写并要求您证明前提,这里它将添加x = negb some_term
形式的子目标。
另一种选择是在重写时专门化neg_move
:
rewrite -> (neg_move _ _ H)
此处H
必须是some_x = negb some_y
类型的字词。我为x
的{{1}}和y
参数设置了两个通配符,因为Coq能够将neg_move
推断为H
和some_x
} 分别。然后,Coq会尝试使用some_y
重写目标中negb some_x
的出现。
但是你首先需要在你的假设中得到some_y
这个术语,这可能是一些额外的负担......
(请注意,我给你的第一个选项应该等同于H
)
另一个选项是rewrite -> (neg_move _ some_term)
,它将添加看似erewrite -> negb_move
和?x
的未实例化变量,并尝试进行重写。然后你必须证明这个前提,它看起来像?y
,并且希望在解决这个子目标的过程中,Coq会发现(evenb (S (S n'))) = negb ?y
应该从一开始就有什么(有一些限制)但是,可能出现的一些问题是Coq解决了目标而没有弄清楚?y
必须是什么。)
但是,对于您的特定问题,它更容易:
?y
==========
evenb (S n') = negb (evenb (S (S n')))
symmetry.
==========
negb (evenb (S (S n'))) = evenb (S n')
apply neg_move.
这就是你想要的(如果你愿意的话,倒退,做另一个==========
evenb (S (S n')) = negb (evenb (S n'))
。)