尝试解决练习,我有以下定义表示整数:
Inductive bin : Type :=
| Zero : bin
| Twice : bin -> bin
| TwiceOne : bin -> bin.
这个想法是:
x
为2*x
。x
为2*x +1
。但是,此表示存在一个问题:数字0
有几种表示形式。
因此,我需要实现一个函数来规范化bin
中的数字。
为此,我宣布了以下功能:
Fixpoint normalize_bin (b:bin) : bin :=
match b with
| Zero => Zero
| TwiceOne x => TwiceOne (normalize_bin x)
| Twice x => match normalize_bin x with
| Zero => Zero
| x => Twice x
end
end.
现在,我想表明,如果b
类型为bin
,我会在b
中翻译nat
,然后我会回到{{1}我得到了b'这是bin
的标准化。这是以下定理:
b
为了证明这个定理,我在Theorem bin_to_nat_to_bin : forall (b:bin),
nat_to_bin (bin_to_nat b) = normalize_bin2 b.
进行归纳。但我陷入了影响
b
使用战术 nat_to_bin (bin_to_nat Tb + bin_to_nat Tb) =
match normalize_bin2 Tb with
| Zero => Zero
| Twice b => Twice (Twice b)
| TwiceOne b => Twice (TwiceOne b)
end
之后。
但是,我不知道如何在目标中处理这场比赛。我能从这里做些什么?
由于这个练习来自一本书,我不必使用一些高级的Coq。我只知道一些策略,例如simpl
,reflexivity
,simpl
,rewrite
,destruct
。
可能的第二个标准化只是声明:
assert
但在这种情况下,这是微不足道的,我不认为这是预期的答案。
答案 0 :(得分:4)
由于这是来自Software Foundations的练习,我不会给出完整的答案,但是提示。
这个证据确实非常棘手。当你进入像这样复杂的证据时,尝试将其分解为较小的引理通常是一个好主意。这反过来可能需要重新组织您的定义,以便这些引理的语句变得更简单。
在您的情况下,您对normalize_bin
的定义有一个内部match
看起来有点过于复杂,一旦您进入证明的那一点就会变得明显。你能否在一个单独的定义中考虑内部match
,以便你可以陈述关于该定义的引理并在你的主要证明中使用这些引理?