Теорема о добавлении непустого списка в Coq

Я пытаюсь доказать следующую лемму в Coq:

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

Прямо сейчас моя текущая стратегия состояла в том, чтобы уничтожить a, и после разрыва дизъюнкции в идеале я мог бы просто заявить, что если a <> [], то a ++ b также должен быть <> []... Это был план, но я не может пройти мимо подзадачи, которая напоминает первый "a ++ b <> []", даже когда мой контекст ясно утверждает, что "b <> []". Любой совет?

Я также просмотрел множество уже существующих теорем о списках и не нашел ничего особенно полезного (за исключением app_nil_l и app_nil_r, для некоторых подцелей).

Ответы

Ответ 1

Начинать с destruct a - это действительно хорошая идея.

В случае, когда a равно Nil, вы должны разрушить гипотезу (a <> [] \/b <> []). Будет два случая:

  • правая гипотеза [] <> [] является contradiction,
  • левая - гипотеза b <> [] - ваша цель (так как a = [])

Для случая, когда a - a :: a0, вы должны использовать discriminate как сказал Жюльен.

Ответ 2

Вы начали правильный путь с вашего destruct a.

В какой-то момент вы должны получить a0::a++b<>0. Он напоминает a++b<>0 но он совершенно другой, так как здесь есть cons, поэтому discriminate знает, что он отличается от nil.

Ответ 3

Во-первых, я не уверен, какую версию 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.