src/FOLP/IFOLP.thy
changeset 58963 26bf09b95dda
parent 58889 5b7a9633cfa8
child 59498 50b60f501b05
equal deleted inserted replaced
58960:4bee6d8c1500 58963:26bf09b95dda
   250 
   250 
   251 ML {*
   251 ML {*
   252 local
   252 local
   253   fun discard_proof (Const (@{const_name Proof}, _) $ P $ _) = P;
   253   fun discard_proof (Const (@{const_name Proof}, _) $ P $ _) = P;
   254 in
   254 in
   255 val uniq_assume_tac =
   255 fun uniq_assume_tac ctxt =
   256   SUBGOAL
   256   SUBGOAL
   257     (fn (prem,i) =>
   257     (fn (prem,i) =>
   258       let val hyps = map discard_proof (Logic.strip_assums_hyp prem)
   258       let val hyps = map discard_proof (Logic.strip_assums_hyp prem)
   259           and concl = discard_proof (Logic.strip_assums_concl prem)
   259           and concl = discard_proof (Logic.strip_assums_concl prem)
   260       in
   260       in
   261           if exists (fn hyp => hyp aconv concl) hyps
   261           if exists (fn hyp => hyp aconv concl) hyps
   262           then case distinct (op =) (filter (fn hyp => Term.could_unify (hyp, concl)) hyps) of
   262           then case distinct (op =) (filter (fn hyp => Term.could_unify (hyp, concl)) hyps) of
   263                    [_] => assume_tac i
   263                    [_] => assume_tac ctxt i
   264                  |  _  => no_tac
   264                  |  _  => no_tac
   265           else no_tac
   265           else no_tac
   266       end);
   266       end);
   267 end;
   267 end;
   268 *}
   268 *}
   270 
   270 
   271 (*** Modus Ponens Tactics ***)
   271 (*** Modus Ponens Tactics ***)
   272 
   272 
   273 (*Finds P-->Q and P in the assumptions, replaces implication by Q *)
   273 (*Finds P-->Q and P in the assumptions, replaces implication by Q *)
   274 ML {*
   274 ML {*
   275   fun mp_tac i = eresolve_tac [@{thm notE}, make_elim @{thm mp}] i  THEN  assume_tac i
   275   fun mp_tac ctxt i =
       
   276     eresolve_tac [@{thm notE}, make_elim @{thm mp}] i  THEN  assume_tac ctxt i
   276 *}
   277 *}
   277 
   278 
   278 (*Like mp_tac but instantiates no variables*)
   279 (*Like mp_tac but instantiates no variables*)
   279 ML {*
   280 ML {*
   280   fun int_uniq_mp_tac i = eresolve_tac [@{thm notE}, @{thm impE}] i  THEN  uniq_assume_tac i
   281   fun int_uniq_mp_tac ctxt i =
       
   282     eresolve_tac [@{thm notE}, @{thm impE}] i  THEN  uniq_assume_tac ctxt i
   281 *}
   283 *}
   282 
   284 
   283 
   285 
   284 (*** If-and-only-if ***)
   286 (*** If-and-only-if ***)
   285 
   287 
   372     erule iffE conjE mp | tactic {* iff_tac @{thms assms} 1 *})+
   374     erule iffE conjE mp | tactic {* iff_tac @{thms assms} 1 *})+
   373   done
   375   done
   374 
   376 
   375 schematic_lemma disj_cong:
   377 schematic_lemma disj_cong:
   376   "[| p:P <-> P'; q:Q <-> Q' |] ==> ?p:(P|Q) <-> (P'|Q')"
   378   "[| p:P <-> P'; q:Q <-> Q' |] ==> ?p:(P|Q) <-> (P'|Q')"
   377   apply (erule iffE disjE disjI1 disjI2 | assumption | rule iffI | tactic {* mp_tac 1 *})+
   379   apply (erule iffE disjE disjI1 disjI2 | assumption | rule iffI | tactic {* mp_tac @{context} 1 *})+
   378   done
   380   done
   379 
   381 
   380 schematic_lemma imp_cong:
   382 schematic_lemma imp_cong:
   381   assumes "p:P <-> P'"
   383   assumes "p:P <-> P'"
   382     and "!!x. x:P' ==> q(x):Q <-> Q'"
   384     and "!!x. x:P' ==> q(x):Q <-> Q'"
   383   shows "?p:(P-->Q) <-> (P'-->Q')"
   385   shows "?p:(P-->Q) <-> (P'-->Q')"
   384   apply (insert assms(1))
   386   apply (insert assms(1))
   385   apply (assumption | rule iffI impI | erule iffE | tactic {* mp_tac 1 *} |
   387   apply (assumption | rule iffI impI | erule iffE | tactic {* mp_tac @{context} 1 *} |
   386     tactic {* iff_tac @{thms assms} 1 *})+
   388     tactic {* iff_tac @{thms assms} 1 *})+
   387   done
   389   done
   388 
   390 
   389 schematic_lemma iff_cong:
   391 schematic_lemma iff_cong:
   390   "[| p:P <-> P'; q:Q <-> Q' |] ==> ?p:(P<->Q) <-> (P'<->Q')"
   392   "[| p:P <-> P'; q:Q <-> Q' |] ==> ?p:(P<->Q) <-> (P'<->Q')"
   391   apply (erule iffE | assumption | rule iffI | tactic {* mp_tac 1 *})+
   393   apply (erule iffE | assumption | rule iffI | tactic {* mp_tac @{context} 1 *})+
   392   done
   394   done
   393 
   395 
   394 schematic_lemma not_cong:
   396 schematic_lemma not_cong:
   395   "p:P <-> P' ==> ?p:~P <-> ~P'"
   397   "p:P <-> P' ==> ?p:~P <-> ~P'"
   396   apply (assumption | rule iffI notI | tactic {* mp_tac 1 *} | erule iffE notE)+
   398   apply (assumption | rule iffI notI | tactic {* mp_tac @{context} 1 *} | erule iffE notE)+
   397   done
   399   done
   398 
   400 
   399 schematic_lemma all_cong:
   401 schematic_lemma all_cong:
   400   assumes "!!x. f(x):P(x) <-> Q(x)"
   402   assumes "!!x. f(x):P(x) <-> Q(x)"
   401   shows "?p:(ALL x. P(x)) <-> (ALL x. Q(x))"
   403   shows "?p:(ALL x. P(x)) <-> (ALL x. Q(x))"
   402   apply (assumption | rule iffI allI | tactic {* mp_tac 1 *} | erule allE |
   404   apply (assumption | rule iffI allI | tactic {* mp_tac @{context} 1 *} | erule allE |
   403     tactic {* iff_tac @{thms assms} 1 *})+
   405     tactic {* iff_tac @{thms assms} 1 *})+
   404   done
   406   done
   405 
   407 
   406 schematic_lemma ex_cong:
   408 schematic_lemma ex_cong:
   407   assumes "!!x. f(x):P(x) <-> Q(x)"
   409   assumes "!!x. f(x):P(x) <-> Q(x)"
   408   shows "?p:(EX x. P(x)) <-> (EX x. Q(x))"
   410   shows "?p:(EX x. P(x)) <-> (EX x. Q(x))"
   409   apply (erule exE | assumption | rule iffI exI | tactic {* mp_tac 1 *} |
   411   apply (erule exE | assumption | rule iffI exI | tactic {* mp_tac @{context} 1 *} |
   410     tactic {* iff_tac @{thms assms} 1 *})+
   412     tactic {* iff_tac @{thms assms} 1 *})+
   411   done
   413   done
   412 
   414 
   413 (*NOT PROVED
   415 (*NOT PROVED
   414 ML_Thms.bind_thm ("ex1_cong", prove_goal (the_context ())
   416 ML_Thms.bind_thm ("ex1_cong", prove_goal (the_context ())
   634   "?p4 : False & P <-> False"
   636   "?p4 : False & P <-> False"
   635   "?p5 : P & P <-> P"
   637   "?p5 : P & P <-> P"
   636   "?p6 : P & ~P <-> False"
   638   "?p6 : P & ~P <-> False"
   637   "?p7 : ~P & P <-> False"
   639   "?p7 : ~P & P <-> False"
   638   "?p8 : (P & Q) & R <-> P & (Q & R)"
   640   "?p8 : (P & Q) & R <-> P & (Q & R)"
   639   apply (tactic {* fn st => IntPr.fast_tac 1 st *})+
   641   apply (tactic {* fn st => IntPr.fast_tac @{context} 1 st *})+
   640   done
   642   done
   641 
   643 
   642 schematic_lemma disj_rews:
   644 schematic_lemma disj_rews:
   643   "?p1 : P | True <-> True"
   645   "?p1 : P | True <-> True"
   644   "?p2 : True | P <-> True"
   646   "?p2 : True | P <-> True"
   645   "?p3 : P | False <-> P"
   647   "?p3 : P | False <-> P"
   646   "?p4 : False | P <-> P"
   648   "?p4 : False | P <-> P"
   647   "?p5 : P | P <-> P"
   649   "?p5 : P | P <-> P"
   648   "?p6 : (P | Q) | R <-> P | (Q | R)"
   650   "?p6 : (P | Q) | R <-> P | (Q | R)"
   649   apply (tactic {* IntPr.fast_tac 1 *})+
   651   apply (tactic {* IntPr.fast_tac @{context} 1 *})+
   650   done
   652   done
   651 
   653 
   652 schematic_lemma not_rews:
   654 schematic_lemma not_rews:
   653   "?p1 : ~ False <-> True"
   655   "?p1 : ~ False <-> True"
   654   "?p2 : ~ True <-> False"
   656   "?p2 : ~ True <-> False"
   655   apply (tactic {* IntPr.fast_tac 1 *})+
   657   apply (tactic {* IntPr.fast_tac @{context} 1 *})+
   656   done
   658   done
   657 
   659 
   658 schematic_lemma imp_rews:
   660 schematic_lemma imp_rews:
   659   "?p1 : (P --> False) <-> ~P"
   661   "?p1 : (P --> False) <-> ~P"
   660   "?p2 : (P --> True) <-> True"
   662   "?p2 : (P --> True) <-> True"
   661   "?p3 : (False --> P) <-> True"
   663   "?p3 : (False --> P) <-> True"
   662   "?p4 : (True --> P) <-> P"
   664   "?p4 : (True --> P) <-> P"
   663   "?p5 : (P --> P) <-> True"
   665   "?p5 : (P --> P) <-> True"
   664   "?p6 : (P --> ~P) <-> ~P"
   666   "?p6 : (P --> ~P) <-> ~P"
   665   apply (tactic {* IntPr.fast_tac 1 *})+
   667   apply (tactic {* IntPr.fast_tac @{context} 1 *})+
   666   done
   668   done
   667 
   669 
   668 schematic_lemma iff_rews:
   670 schematic_lemma iff_rews:
   669   "?p1 : (True <-> P) <-> P"
   671   "?p1 : (True <-> P) <-> P"
   670   "?p2 : (P <-> True) <-> P"
   672   "?p2 : (P <-> True) <-> P"
   671   "?p3 : (P <-> P) <-> True"
   673   "?p3 : (P <-> P) <-> True"
   672   "?p4 : (False <-> P) <-> ~P"
   674   "?p4 : (False <-> P) <-> ~P"
   673   "?p5 : (P <-> False) <-> ~P"
   675   "?p5 : (P <-> False) <-> ~P"
   674   apply (tactic {* IntPr.fast_tac 1 *})+
   676   apply (tactic {* IntPr.fast_tac @{context} 1 *})+
   675   done
   677   done
   676 
   678 
   677 schematic_lemma quant_rews:
   679 schematic_lemma quant_rews:
   678   "?p1 : (ALL x. P) <-> P"
   680   "?p1 : (ALL x. P) <-> P"
   679   "?p2 : (EX x. P) <-> P"
   681   "?p2 : (EX x. P) <-> P"
   680   apply (tactic {* IntPr.fast_tac 1 *})+
   682   apply (tactic {* IntPr.fast_tac @{context} 1 *})+
   681   done
   683   done
   682 
   684 
   683 (*These are NOT supplied by default!*)
   685 (*These are NOT supplied by default!*)
   684 schematic_lemma distrib_rews1:
   686 schematic_lemma distrib_rews1:
   685   "?p1 : ~(P|Q) <-> ~P & ~Q"
   687   "?p1 : ~(P|Q) <-> ~P & ~Q"
   686   "?p2 : P & (Q | R) <-> P&Q | P&R"
   688   "?p2 : P & (Q | R) <-> P&Q | P&R"
   687   "?p3 : (Q | R) & P <-> Q&P | R&P"
   689   "?p3 : (Q | R) & P <-> Q&P | R&P"
   688   "?p4 : (P | Q --> R) <-> (P --> R) & (Q --> R)"
   690   "?p4 : (P | Q --> R) <-> (P --> R) & (Q --> R)"
   689   apply (tactic {* IntPr.fast_tac 1 *})+
   691   apply (tactic {* IntPr.fast_tac @{context} 1 *})+
   690   done
   692   done
   691 
   693 
   692 schematic_lemma distrib_rews2:
   694 schematic_lemma distrib_rews2:
   693   "?p1 : ~(EX x. NORM(P(x))) <-> (ALL x. ~NORM(P(x)))"
   695   "?p1 : ~(EX x. NORM(P(x))) <-> (ALL x. ~NORM(P(x)))"
   694   "?p2 : ((EX x. NORM(P(x))) --> Q) <-> (ALL x. NORM(P(x)) --> Q)"
   696   "?p2 : ((EX x. NORM(P(x))) --> Q) <-> (ALL x. NORM(P(x)) --> Q)"
   695   "?p3 : (EX x. NORM(P(x))) & NORM(Q) <-> (EX x. NORM(P(x)) & NORM(Q))"
   697   "?p3 : (EX x. NORM(P(x))) & NORM(Q) <-> (EX x. NORM(P(x)) & NORM(Q))"
   696   "?p4 : NORM(Q) & (EX x. NORM(P(x))) <-> (EX x. NORM(Q) & NORM(P(x)))"
   698   "?p4 : NORM(Q) & (EX x. NORM(P(x))) <-> (EX x. NORM(Q) & NORM(P(x)))"
   697   apply (tactic {* IntPr.fast_tac 1 *})+
   699   apply (tactic {* IntPr.fast_tac @{context} 1 *})+
   698   done
   700   done
   699 
   701 
   700 lemmas distrib_rews = distrib_rews1 distrib_rews2
   702 lemmas distrib_rews = distrib_rews1 distrib_rews2
   701 
   703 
   702 schematic_lemma P_Imp_P_iff_T: "p:P ==> ?p:(P <-> True)"
   704 schematic_lemma P_Imp_P_iff_T: "p:P ==> ?p:(P <-> True)"
   703   apply (tactic {* IntPr.fast_tac 1 *})
   705   apply (tactic {* IntPr.fast_tac @{context} 1 *})
   704   done
   706   done
   705 
   707 
   706 schematic_lemma not_P_imp_P_iff_F: "p:~P ==> ?p:(P <-> False)"
   708 schematic_lemma not_P_imp_P_iff_F: "p:~P ==> ?p:(P <-> False)"
   707   apply (tactic {* IntPr.fast_tac 1 *})
   709   apply (tactic {* IntPr.fast_tac @{context} 1 *})
   708   done
   710   done
   709 
   711 
   710 end
   712 end