证明匹配语句

Prove a match statement

试图解决一个练习,我有以下代表整数的定义:

Inductive bin : Type :=
| Zero : bin
| Twice : bin -> bin
| TwiceOne : bin -> bin.

想法是:

  1. 两次 x2*x
  2. TwiceOne x2*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.

现在,我想证明如果取 bin 类型的 b,我将 b 翻译成 nat,然后返回 bin 我得到了 b 的标准化的 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

使用战术后simpl

但是,我不知道如何处理这个目标中的匹配。我可以从这里做什么?

由于这个练习来自书本,所以我不必使用 Coq 的一些高级东西。我只知道一些策略,例如 reflexivitysimplrewritedestructassert.

第二种可能的规范化只是声明:

Definition normalize_bin (b:bin) : bin :=
  nat_to_bin (bin_to_nat b).

但在这种情况下,这是微不足道的,我认为这不是预期的答案。

由于这是软件基础的练习,我不会给出完整的答案,而是给出一个提示。

这个证明确实比较棘手。当您遇到像这样的复杂证明时,尝试将其分解为更小的引理通常是个好主意。这反过来可能需要重新组织您的定义,以便这些引理的陈述变得更简单。

在你的例子中,你对 normalize_bin 的定义有一个看起来有点过于复杂的内部 match,一旦你进入证明的那个点,它就会变得很明显。您能否将内部 match 分解为一个单独的定义,以便您可以陈述关于该定义的引理并稍后在您的主要证明中使用这些引理?