Coq中的非空列表附加定理

时间:2018-11-20 00:48:16

标签: ocaml coq theorem-proving coq-tactic formal-verification

我正在尝试证明Coq中的以下引理:

Require Import Lists.List.
Import ListNotations.
Lemma not_empty : forall (A : Type) (a b : list A),
    (a <> [] \/ b <> []) -> a ++ b <> [].

现在我当前的策略是在a上进行销毁,并且在打破分离之后,我可以理想地声明,如果a <> []则++ b也必须是<> [] ...那就是计划,但即使我的上下文明确指出“ b <> []”,我也似乎无法通过类似于第一个“ a ++ b <> []”的子目标。有什么建议吗?

我还仔细研究了很多先前存在的列表定理,但没有发现任何特别有用的东西(对于某些子目标,减去app_nil_l和app_nil_r)。

3 个答案:

答案 0 :(得分:17)

a开始确实是个好主意。

对于Nil(a <> [] \/ b <> [])的情况,您应该破坏[] <> []的假设。有两种情况:

  • 假设contradiction的右边是b <> []
  • 左边是假设a = []是您的目标(自a起)

对于a :: a0discriminate的情况,您应按照Julien所说的使用<div class="search-block" style="display:inline-block;position:relative;"> <div class="form-input-icon form-input-icon-right"> <i>KVA</i> <input type="text" class="form-control form-control-sm form-control-rounded"> <button type="button" class="search-block-submit"></button> </div>

答案 1 :(得分:7)

您以正确的方式开始使用destruct a

您应该在某个时候以a0::a++b<>0结尾。它具有a++b<>0的外观,但与这里的cons完全不同,因此discriminate知道它与nil不同。

答案 2 :(得分:2)

首先,我不确定您使用的是哪个Coq版本,语法肯定看起来很奇怪。其次,如果您不向我们展示您到目前为止的证据,那么我们将很难提供帮助。我应该说确实您的策略似乎正确,应该销毁两个列表,这样最好先检查或看看哪个列表不为空。

另一个选择是使用计算来显示您的引理,在这种情况下,将计算相等性,因此您将获得比较的结果。在这种情况下,仅由于顺序或参数就足以销毁一个列表:

From mathcomp Require Import all_ssreflect.

Lemma not_empty (A : eqType) (a b : seq A) :
  [|| a != [::] | b != [::]] -> a ++ b != [::].
Proof. by case: a. Qed.