Вот одно из возможных решений.Я не пошел ни на доказательство без леммы, ни на самое короткое доказательство.Вместо этого я попытался разбить все на куски размером с кусочек, которыми (относительно) легко манипулировать.
Во-первых, вот вспомогательная лемма, отсутствующая в стандартной библиотеке.Он просто устанавливает закон противопоставления в классической логике (у нас здесь есть разрешимые предложения, так что это своего рода классика).
From Coq Require Import Arith Bool List.
Lemma contra b1 b2 :
(b2 = false -> b1 = false) <-> (b1 = true -> b2 = true).
Proof. destruct b1, b2; intuition. Qed.
Теперь нам понадобится следующее простое свойство:
Lemma in_subset_listpair {p l1 l2} :
in_listpair p l1 = true ->
subset_listpair l1 l2 = true ->
in_listpair p l2 = true.
Proof.
induction l1 as [| [x1 y1] l1 IH]; simpl; [easy|].
rewrite orb_true_iff, andb_true_iff. intros [->%Nat.eqb_eq|] []; trivial.
now apply IH.
Qed.
Далее мы докажем, что subset
является транзитивным:
Lemma subset_listpair_transitive l2 l1 l3 :
subset_listpair l1 l2 = true ->
subset_listpair l2 l3 = true ->
subset_listpair l1 l3 = true .
Proof.
induction l1 as [| [x1 y1] l1 IH]; simpl; trivial.
intros [I1 S1]%andb_prop S2. rewrite (IH S1 S2), andb_true_r.
now apply (in_subset_listpair I1).
Qed.
А теперь целевая лемма, которая в основном является контрапозитивным утверждением свойства транзитивности:
Lemma subset_listpair_consFalse l1 l2 l3 :
subset_listpair l1 l2 = true ->
subset_listpair l1 l3 = false ->
subset_listpair l2 l3 = false .
Proof.
intros S12; rewrite contra.
now apply subset_listpair_transitive.
Qed.