#coq #logical-foundations
#coq #логические основы
Вопрос:
Пытаясь решить In_app_iff excersize из главы Logic, я пришел к этому чудовищу:
(* Lemma used later *)
Lemma list_nil_app : forall (A : Type) (l : list A),
l [] = l.
Proof.
intros A l. induction l as [| n l' IHl'].
- simpl. reflexivity.
- simpl. rewrite -> IHl'. reflexivity.
Qed.
(** **** Exercise: 2 stars, standard (In_app_iff) *)
Lemma In_app_iff : forall A l l' (a:A),
In a (l l') <-> In a l / In a l'.
Proof.
intros A l l' a. split.
induction l as [| h t IHl].
(* l = [] *) destruct l' as [| h' t'].
(* l' = [] *) simpl. intros H. exfalso. apply H.
(* l' = h'::t' *) simpl. intros [H1 | H2].
* right. left. apply H1.
* right. right. apply H2.
(* l = h::t *) destruct l' as [| h' t'].
(* l' = [] *) simpl. intros [H1 | H2].
* left. left. apply H1.
* left. right. rewrite list_nil_app in H2. apply H2.
(* l' = h'::t' *) intros H. simpl in H. simpl. destruct H as [H1 | H2].
* left. left. apply H1.
* apply IHl in H2. destruct H2 as [H21 | H22].
** left. right. apply H21.
** simpl in H22. destruct H22 as [H221 | H222].
*** right. left. apply H221.
*** right. right. apply H222.
induction l as [| h t IHl].
(* l = [] *) simpl. intros [H1 | H2].
exfalso. apply H1.
apply H2.
(* l = h::t *) destruct l' as [| h' t'].
simpl. intros [H1 | H2].
rewrite list_nil_app. apply H1.
exfalso. apply H2.
simpl. intros [H1 | H2].
destruct H1 as [H11 | H12].
left. apply H11.
Вот что я получил в конце:
A : Type
h : A
t : list A
h' : A
t' : list A
a : A
IHl : In a t / In a (h' :: t') -> In a (t h' :: t')
H12 : In a t
============================
h = a / In a (t h' :: t')
Как я могу извлечь из H12
и IHl
того факта, что In a (t h' :: t')
?
Потому что H12 находится в дизъюнкции. И этого достаточно, чтобы сделать вывод.
apply H12 in IHl.
не работает.
Пожалуйста, помогите.
Комментарии:
1. Побочные замечания: для завершения этого доказательства не требуется анализ прецедентов на
l'
(вы можете придумать гораздо более простое доказательство), а-
также является допустимым элементом для структурирования ваших доказательств (обычно они используются в следующем порядке:-
,,
*
--
,
**
и т.д.)2. @eponier «Побочные замечания: анализ случая на l ‘ не требуется для завершения этого доказательства (вы можете придумать гораздо более простое доказательство)» — можете ли вы дать подсказку, как это сделать в ответе?
3. Например, вы можете заменить первое
destruct l'
на толькоsimpl
.
Ответ №1:
Для этого есть разные способы.
Здесь вывод IHl
является одним из пунктов цели, поэтому обратное рассуждение будет работать довольно хорошо.
right. (* We will prove the right hand side of the disjunct. *)
apply IHl.
left.
apply H12.
Также возможны прямые рассуждения, хотя и немного более подробные. Используйте assert
, чтобы доказать предположение, действительно необходимое IHl
:
assert (preIHl : In a t / In a (h' :: t')).
- ...
- apply IHl in preIHl.
apply preIHl.
Комментарии:
1. При использовании
assert
тактики я предпочитаю использовать фигурные скобки, например,assert (...). { some_proof. }
вместо маркеров (поскольку это не анализ конкретного случая). Просто вопрос стиля.