没有可判定的相等性或排除中间值的鸽巢证明

2024-04-23

在软件基础中IndProp.v https://softwarefoundations.cis.upenn.edu/lf-current/IndProp.html#lab244一个人被要求证明鸽巢原理,并且可以使用排除中间,但有人提到这并不是绝对必要的。我一直试图在没有电磁场的情况下证明这一点,但我的大脑似乎是经典的。

问:如何证明该定理without使用排除中间?在无法轻易通过案例进行推理的情况下,人们通常应该如何处理没有可判定相等性的类型的证明?

我很乐意看到完整的证明,但请避免“以明确的方式”发布它,以免破坏软件基础课程中的练习。

该定义使用两个归纳谓词,In and repeats.

Require Import Lists.List.
Import ListNotations.

Section Pigeon.

  Variable (X:Type).
  Implicit Type (x:X).

  Fixpoint In x l : Prop :=                        (***    In       ***)
    match l with
    | nil => False
    | (x'::l') => x' = x \/ In x l'
    end.

  Hypothesis in_split : forall x l, In x l ->  exists l1 l2, l = l1 ++ x :: l2.
  Hypothesis in_app:    forall x l1 l2, In x (l1++l2) <-> In x l1 \/ In x l2.

  Inductive repeats : list X -> Prop :=            (***    repeats   ***)
    repeats_hd l x : In x l    -> repeats (x::l)
  | repeats_tl l x : repeats l -> repeats (x::l).

  Theorem pigeonhole_principle_NO_EM:              (***   pigeonhole   ***)
    forall l1  l2,
      length l2 < length l1 ->            (* There are more pigeons than nests *)
      (forall x, In x l1 -> In x l2) ->   (* All pigeons are in some nest *)
      repeats l1.                         (* Thus, some pigeons share nest *)
  Proof.

    (* ??? *)     

我将描述引导我找到解决方案的思维过程,以防有帮助。我们可以应用归纳法,很容易简化到案例l1 = a::l1', l2 = a::l2'. Now l1'是一个子集a::l2'。我受过 EM 训练的直觉是以下之一成立:

  • a is in l1'.
  • a不在l1'.

在后一种情况下,每个元素l1' is in a::l2'但不同于a,因此必须在l2'. Thus l1'是一个子集l2',我们可以应用归纳假设。

不幸的是如果In是不可判定的,以上不能直接形式化。特别是,如果给定类型的相等性不可判定,则很难证明元素不相等,因此很难证明像这样的否定陈述~(In a l1')。然而,我们想用这个否定的陈述来证明一个积极的陈述,即

forall x, In x l1' -> In x l2'

以此类推,假设我们想证明

P \/ Q
Q -> R
------
P \/ R

上面直观的论证就像是从P \/ ~P,并使用~P -> Q -> R在第二种情况下。我们可以使用直接证明来避免 EM。

对列表进行量化l1'使这有点复杂,但我们仍然可以使用以下引理构建直接证明,这可以通过归纳法来证明。

Lemma split_or {X} (l : list X) (P Q : X -> Prop) :
  (forall x, In x l -> (P x \/ Q x)) ->
  (exists x, In x l /\ P x) \/ (forall x, In x l -> Q x).

最后注意,直觉鸽巢原理也可以形式化为以下方式,当类型具有不可判定的相等性时无法证明(注意它的结论中有否定陈述):

Definition pigeon2 {X} : Prop := forall (l1 l2 : list X),
  length l2 < length l1 ->
  (exists x, In x l1 /\ ~(In x l2)) \/ repeats l1.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

没有可判定的相等性或排除中间值的鸽巢证明 的相关文章

  • Coq:变量参数列表上的 Ltac 定义?

    在尝试创建循环可变长度参数列表的 Ltac 定义时 我在 Coq 8 4pl2 上遇到了以下意外行为 谁能给我解释一下吗 Ltac ltac loop X match X with 0 gt idtac done gt fun Y gt i
  • 如何在 Coq 中使用归纳类型来处理案例

    我想使用destruct通过案例来证明陈述的策略 我在网上读了几个例子 但我很困惑 有人可以更好地解释一下吗 这是一个小例子 还有其他方法可以解决它 但尝试使用destruct Inductive three zero one two Le
  • Coq 中的 `destruct` 和 `case_eq` 策略有什么区别?

    我明白了destruct因为它将归纳定义分解为其构造函数 我最近看到case eq我不明白它有什么不同 1 subgoals n nat k nat m M t nat H match M find elt nat n m with Som
  • 使用 lambda 参数重写 Coq

    我们有一个函数可以将元素插入到列表的特定索引中 Fixpoint inject into A x A l list A n nat option list A match n l with 0 gt Some x l S k gt None
  • 归纳命题在 Coq 中如何运作?

    我正在阅读软件基础中的 IndProp 和 Adam Chlipala 的第 4 章书 但我在理解归纳命题时遇到了困难 为了运行示例 让我们使用 Inductive ev nat gt Prop ev 0 ev 0 ev SS forall
  • 对术语...进行抽象会导致术语...类型错误

    这是我想证明的 A Type i nat index f nat nat n nat ip n lt i partial index f nat option nat L partial index f index f n Some n V
  • Coq - 在 if ... then ... else 中使用 Prop (True | False)

    我对 Coq 有点陌生 我正在尝试实现插入排序的通用版本 我正在实现一个以比较器作为参数的模块 该 Comparator 实现了比较运算符 如 is eq is le is neq 等 在插入排序中 为了插入 我必须比较输入列表中的两个元素
  • 引入先前证明的定理作为假设

    假设我已经在coq中证明了某个定理 稍后我想将其作为假设引入到另一个定理的证明中 有没有一种简洁的方法来做到这一点 当我想做一些诸如案例证明之类的事情时 我通常会出现这种需要 我发现做到这一点的一种方法是assert陈述定理 然后立即证明它
  • Coq 无法在 Z 上计算有根据的函数,但它可以在 nat 上运行

    我正在 为我自己 写一篇关于如何在 Coq 中进行有根据的递归的解释 参见 Coq Art 书 第 15 2 章 首先我做了一个基于的示例函数nat效果很好 但后来我又做了一次Z 当我使用Compute来评估它 它并没有一直降低到Z价值 为
  • 如何有效地查找 Coq 中定义标识符的位置?

    在大多数 IDE 或文本编辑器中 您可以右键单击某个术语 它会将您带到定义该术语的文件 CoqIDE好像没有这个 所以我一直在做coqdoc myfile v html 然后转到生成的 HTML 文档 但该文件中唯一可点击的术语是针对 Co
  • Coq 中的程序定点和函数有什么区别?

    它们似乎有相似的目的 到目前为止我注意到的一个区别是Program Fixpoint将接受复合措施 例如 measure length l1 length l2 Function似乎拒绝这一点并且只会允许 measure length l1
  • 证明匹配语句

    为了解决一个练习 我有以下代表整数的定义 Inductive bin Type Zero bin Twice bin gt bin TwiceOne bin gt bin 这个想法是 Twice x is 2 x 两次一x is 2 x 1
  • 如何在 Coq 简化过程中应用一次函数?

    据我了解 Coq 中的函数调用是不透明的 有时 我需要使用unfold应用它然后fold将函数定义 主体恢复为其名称 这通常很乏味 我的问题是 是否有更简单的方法来应用函数调用的特定实例 作为一个最小的例子 对于一个列表l 证明右附加 没有
  • 将假设中的 ~exists 转换为 forall

    我陷入了假设的境地 exists k k lt n 1 f k f n 2 并希望将其转换为等效的 我希望如此 假设forall k k lt n 1 gt f k lt gt f n 2 这是一个小例子 Require Import Co
  • Coq 中的“错误:宇宙不一致”是什么意思?

    我正在努力通过软件基础 http www cis upenn edu bcpierce sf current 目前正在做教堂数字的练习 这是自然数的类型签名 Definition nat forall X Type X gt X gt X
  • Coq案例分析和函数返回子集类型的重写

    我正在做一个关于使用子集类型编写经过认证的函数的简单练习 想法是先写一个前驱函数 pred forall n n nat n gt 0 m nat S m n 1 然后使用这个定义给定一个函数 pred2 forall n n nat n
  • 为什么较新的依赖类型语言没有采用 SSReflect 的方法?

    我在 Coq 的 SSReflect 扩展中发现了两个约定 它们似乎特别有用 但我还没有看到它们在较新的依赖类型语言 Lean Agda Idris 中得到广泛采用 首先 可能的谓词被表示为布尔返回函数而不是归纳定义的数据类型 默认情况下
  • 我可以将 Coq 证明提取为 Haskell 函数吗?

    自从学了一点 Coq 以来 我就想学着写一个所谓的除法算法的 Coq 证明 它实际上是一个逻辑命题 forall n m nat exists q nat exists r nat n q m r 我最近利用我学到的知识完成了这项任务软件基
  • 在 Coq 模块系统中导入 与包含

    确切的语义是什么Include M1在另一个模块中 比如 M 这与做有什么不同Import M1在模块 M 内 更准确地说 以下命令的语义是什么 Module Type M M1 lt M2 lt M3 总结这两个白话命令的语义 命令Inc
  • 在 coq 的 then 部分中使用 if expression = true 的证明

    对于所有 1 Require Import ZArith Znumtheory Local Open Scope Z scope Require Coq Program Tactics Require Coq Program Wf Lemm

随机推荐