Lemma remove {A} (x : A) xs (p : In x xs) :
exists xs', (forall x', x' <> x -> In x' xs -> In x' xs') /\ (length xs = S (length xs')).
Proof.
induction xs.
- inversion p.
- destruct p.
+ subst x0.
exists xs.
split.
* intros x' neq pin.
destruct pin.
-- contradict neq. symmetry. assumption.
-- assumption.
* reflexivity.
+ destruct (IHxs H) as [xs' pxs']. clear IHxs.
destruct pxs' as [p1 plen]. rename x0 into x'.
exists (x' :: xs').
split.
* intros x'' neq pin.
destruct pin.
-- subst x'. left. reflexivity.
-- right. apply p1. assumption. assumption.
* simpl.
rewrite -> plen.
reflexivity.
Qed.
Theorem pigeonhole_principle: forall (X:Type) (l1 l2:list X),
excluded_middle ->
AllIn l1 l2 ->
length l2 < length l1 ->
repeats l1.
Proof.
induction l1; simpl; intros l2 ex_mid Hin Hlen.
- inversion Hlen.
- apply repeats_rest.
destruct (remove x l2) as [l2' Hl2].
+ apply Hin. left. reflexivity.
+ destruct Hl2 as [Hmap Hlen'].
rewrite Hlen' in Hlen.
clear Hlen'.
apply (IHl1 l2').
1 : { assumption. }
2 : { revert Hlen. unfold lt. intros. omega. }
clear Hlen IHl1.
revert Hin.
unfold AllIn.
intros.
apply Hmap.
2 : { apply Hin. right. assumption. }
1 subgoal
X : Type
x : X
l1, l2 : list X
ex_mid : excluded_middle
l2' : list X
Hmap : forall x' : X, x' <> x -> In x' l2 -> In x' l2'
Hin : forall u : X, In u (x :: l1) -> In u l2
u : X
H : In u l1
______________________________________(1/1)
u <> x
我发现网上有各种解决鸽洞原理的方法。上面的内容改编自Kovacs,但在他的证明中,他证明了不存在重复项,而是像SF练习中那样重复。
明显的区别是,我无法在此处证明u <> x
的目标,因为以这种形式说明问题时信息较少。
由于这个问题既棘手又是可选的,并且存在现有的解决方案-我已经进行了两天的研究,所以有人可以向我描述我需要做的一个高层计划
我不是在寻找解决方案,但我希望中间被排除的解决方案很优雅,因为Coq证明without the excluded middle只是一堆重写和了解aq的源代码程序远不能理解它的作用。对该原则的大多数解释只是描述了什么,这不足以弥合我的直觉差距。
我从来没有见过经典的法则在起作用-似乎知道某事是可决定的并不会给我带来很多好处,而且我发现很难理解它们的意义。在这种情况下尤其如此,因此我对查看其目的将更感兴趣。
答案 0 :(得分:1)
我在通过SF(软件基金会)工作时寻找答案时遇到了这个问题,但我自己证明了这一点。我将使用exclude_middle提供SF版鸽洞原理的草图。要证明的语句是,如果列表l1
中的所有元素都在l2
中,并且length l2
小于length l1
,则l1
包含重复的元素。>
SF提出的证据始于对l1
的归纳。我将忽略简单的空白案例。在归纳情况下,破坏l2
。 l2
为空的情况很简单;我们考虑另一种情况。
现在,由于对l1
的归纳和对l2
的破坏,您要证明的陈述是关于具有第一个成员的列表的,所以我们将它们称为x1::l1
和x2::l2
。您的成员资格假设现在看起来像:x1::l1
中的所有元素都在x2::l2
中。
但是首先,让我们使用排除的中间语来声明x1
中的l1
或x1
中的l1
。如果x1
中的l1
,那么我们可以证明x1::l1
有重复。因此,我们可以假设x1
不在l1
中。
足以满足归纳情况,即存在与l2'
长度相同的l2
,以使l1
的所有元素都在l2'
中。
现在考虑x1::l1
上的隶属度假设,并将forall变量引入为x
:
根据假设,我们知道x1
中的x2::l2
。现在考虑l2'
,其中l2'
是x2::l2
,其中一个x1
实例被删除(使用in_split
)。现在,由于x1
不在l1
中,我们可以得出结论,l1
的所有成员也都在l2'
中,而不是被删除的元素。然后,这满足归纳中的隶属度假设,并且一些与长度的争吵使我们length l2 = length l2'
,从而满足了长度假设。因此,我们得出结论:l1
包含重复,因此也包含x1::l1
。
编辑:以前,我还对x1
中的x2
= x1
或l2
以及x
是否进行了案例分析= {{1}中的x2
或x
,并以更直接的方式解决了特殊情况。不需要,一般情况下也涵盖了它们。