Coq 如何用不同的bin定义证明二进制交换性?

Coq 如何用不同的bin定义证明二进制交换性?,coq,Coq,我正在翻阅《软件基础》一书,上面的内容让我感到困惑。我在网上四处寻找,发现了一种不同的垃圾桶配方,但我认为这里的解决方案不适用 问题是,在第三个-bullet中,bin_to_nat(incr(zeropx))=S(bin_to_nat(zeropx)不会简化,也不能直接重写。所以在学习了replace之后,我认为这可能会起作用,但后来我陷入了试图证明Zero=zeropzero的困境 我知道问题是,我可以自由地改变bin的公式,以便更容易地证明它的可交换性,但我的直觉是,如果我陷入上述定义,我

我正在翻阅《软件基础》一书,上面的内容让我感到困惑。我在网上四处寻找,发现了一种不同的垃圾桶配方,但我认为这里的解决方案不适用

问题是,在第三个
-
bullet
中,bin_to_nat(incr(zeropx))=S(bin_to_nat(zeropx)
不会简化,也不能直接重写。所以在学习了replace之后,我认为这可能会起作用,但后来我陷入了试图证明
Zero=zeropzero
的困境

我知道问题是,我可以自由地改变bin的公式,以便更容易地证明它的可交换性,但我的直觉是,如果我陷入上述定义,我不会在Coq上走得更远。尽管与过去几次不同,我认为我还没有工具来克服这一点

我在这里遗漏了什么?

用x替换(zeropx)。
不可能成功:这样一个方程要容纳
x
就需要一个无限项,等于
ZeroP(zeropp(zeropp(…))
。你首先要证明的是
incr
在语义上是扩展的


感觉你让我走上了正确的道路。我不知道如何证明
bin_to_nat x=bin_to_nat y->x=y,虽然我觉得这是证明上述的必要步骤。事实上,我已经回头看了前面的例子,颠倒了其中一个,并且意识到我甚至无法证明类似
的东西+n=m+m->n=m
。你永远无法证明
bin_to_nat x=bin_to_nat y->x=y
,因为
bin_to_nat(ZeroP x)=bin_to_nat x
ZeroP x=x
不是真的。在
bin
中有太多相同数字的表示形式,因此您必须证明您定义的函数(如
incr
)在所有这些等效表示形式上表现良好(即,它们输出等效值).好吧,我确实想到了,我有许多(无限)相同数字的表示,因为零可以在数字的后面不停地追加,而不会改变其含义,但我不认为这会使函数无法验证。我现在明白你的意思了。但即使如此,
bin_to_nat x=bin_to_nat y->bin_to_nat(incr x)=bin_to_nat(incr y)
应该是可以证明的。一旦我弄明白如何做,我可能就能弄明白,这需要我更深入地阅读这本书。
// Collacoq link: https://x80.org/collacoq/qezicaroni.coq

Inductive bin : Type :=
| Zero : bin
| One : bin
| ZeroP : bin -> bin
| OneP : bin -> bin.

Inductive bin_carry : Type :=
| ZeroC : bin_carry
| OneC : bin_carry.

(*returns carry, new_state*)
Fixpoint incr' (x : bin) : bin_carry * bin :=
  match x with
  | Zero => (ZeroC, One)
  | One => (OneC, Zero)
  | ZeroP x =>
    match incr' x with
    | (OneC, x') => (ZeroC, OneP x')
    | (ZeroC, x') => (ZeroC, ZeroP x')
    end
  | OneP x =>
    match incr' x with
    | (OneC, x') => (OneC, ZeroP x')
    | (ZeroC, x') => (ZeroC, OneP x')
    end
  end.


Definition incr (x : bin): bin :=
  match incr' x with
  | (ZeroC,x) => x
  | (OneC,x) => OneP x
  end.

(*index_multiplier * result*)
Fixpoint bin_to_nat' (x : bin): nat * nat :=
  match x with
  | Zero => (2,0)
  | One => (2,1)
  | ZeroP x =>
    match bin_to_nat' x with
    | (multiplier,result) => (multiplier * 2,result)
    end
  | OneP x =>
    match bin_to_nat' x with
    | (multiplier,result) => (multiplier * 2,result + multiplier)
    end
  end.


Definition bin_to_nat (x : bin): nat :=
  match bin_to_nat' x with
  | (_,r) => r
  end.

Example bin_test1: bin_to_nat Zero = 0.
Proof. reflexivity. Qed.
Example bin_test2: bin_to_nat (incr Zero) = 1.
Proof. reflexivity. Qed.
Example bin_test3: bin_to_nat (incr (incr Zero)) = 2.
Proof. reflexivity. Qed.
Example bin_test4: bin_to_nat (incr (incr (incr Zero))) = 3.
Proof. reflexivity. Qed.
Example bin_test5: bin_to_nat (incr (incr (incr (incr Zero)))) = 4.
Proof. reflexivity. Qed.

Theorem binary_commute :
  forall (x: bin),
    bin_to_nat(incr x) = S (bin_to_nat x).
Proof. induction x.
       - reflexivity.
       - reflexivity.
       - replace (ZeroP x) with x.
         + rewrite -> IHx. reflexivity.
         + induction x.
           * Abort.
Theorem incr_ext : forall (x y : bin),
  bin_to_nat x = bin_to_nat y -> bin_to_nat (incr x) = bin_to_nat (incr y).