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).