Se si dispone di A /\ B /\ C
come un presupposto, e il vostro obiettivo è (A /\ B) /\ C
, è possibile utilizzare la tattica tauto
. Questa tattica risolve tutte le tautologie nel calcolo proposizionale. C'è anche una tattica firstorder
che può risolvere alcune formule con quantificatori.
Se si dispone di A /\ B /\ C
e si desidera passare (A /\ B) /\ C
come argomento per un lemma, sarà necessario lavorare un po 'di più.Un metodo è quello di impostare (A /\ B) /\ C
come un obiettivo intermedio e dimostrarlo:
assert ((A /\ B) /\ C). tauto.
Se A
, B
e C
sono grandi espressioni, è possibile utilizzare una tattica composto da abbinare sopra l'ipotesi H : A /\ B /\ C
e applicare la tattica tauto ad esso . Questo è un approccio ambiguo, eccessivo in questo caso, ma utile in situazioni più complesse in cui si desidera automatizzare una dimostrazione con molti casi simili.
match type of H with ?x /\ ?y /\ ?z =>
assert (x /\ (y /\ z)); [tauto | clear H]
end.
C'è un modo più semplice, ovvero applicare un lemma noto che esegue la trasformazione.
apply and_assoc in H.
È possibile trovare il lemma sfogliando la documentazione della libreria. Puoi anche cercarlo. Questo non è il lemma più facile da cercare perché è un'equivalenza e gli strumenti di ricerca sono orientati verso implicazioni e uguaglianze. È possibile utilizzare SearchPattern (_ /\ _ /\ _).
per cercare i lemmi del modulo forall x1 … xn, ?A /\ ?B /\ ?C
(dove ?A
, ?B
e ?C
può essere una qualsiasi espressione). È possibile utilizzare SearchRewrite (_ /\ _ /\ _)
per cercare i lemmi del modulo forall x1 … xn, (?A /\ ?B /\ ?C) = ?D
. Sfortunatamente, questo non trova quello che cerchiamo, che è un lemma del modulo forall x1 … xn, (?A /\ ?B /\ ?C) <-> ?D
. Che cosa funziona è
Coq < SearchPattern (_ <-> (_ /\ _ /\ _))
and_assoc: forall A B C : Prop, (A /\ B) /\ C <-> A /\ B /\ C
Mi viene in mente che dovrei spiegare perché 'A/\ (B/\ C) == (A/\ B)/\ C' non funziona. Quello che stai essenzialmente dicendo (in termini costruttivi, Coq) è che la dimostrazione di 'A/\ (B/\ C)' è * identica * a '(A/\ B)/\ C'. Come puoi vedere dai proving (1) e (2), non lo sono. Nella mia formulazione, stiamo dicendo che posso * trasformare * una prova dell'una nell'altra. –
Solo un dettaglio di programmazione: Si * può * scrivere 'destruct Habc come [Ha [Hb Hc]]' – ReyCharles
Questo lemma esiste come 'and_assoc' dal Coq 8.3. Puoi dimostrarlo molto semplicemente con 'tauto'. – Gilles