diff -r dd3b9c046c7d -r 4da5c5c29009 Nominal-General/nominal_library.ML --- a/Nominal-General/nominal_library.ML Thu Jun 03 15:02:52 2010 +0200 +++ b/Nominal-General/nominal_library.ML Mon Jun 07 11:43:01 2010 +0200 @@ -48,7 +48,9 @@ val pat_completeness_simp: thm list -> Proof.context -> tactic val prove_termination: Proof.context -> Function.info * local_theory - + (* transformations of premises in inductions *) + val transform_prem1: Proof.context -> string list -> thm -> thm + val transform_prem2: Proof.context -> string list -> thm -> thm end @@ -156,7 +158,9 @@ end -(** function package **) + +(** function package tactics **) + fun pat_completeness_auto lthy = Pat_Completeness.pat_completeness_tac lthy 1 THEN auto_tac (clasimpset_of lthy) @@ -173,6 +177,77 @@ Function.prove_termination NONE (Lexicographic_Order.lexicographic_order_tac true lthy) lthy + +(** transformations of premises (in inductive proofs) **) + +(* + given the theorem F[t]; proves the theorem F[f t] + + - F needs to be monotone + - f returns either SOME for a term it fires on + and NONE elsewhere +*) +fun map_term f t = + (case f t of + NONE => map_term' f t + | x => x) +and map_term' f (t $ u) = + (case (map_term f t, map_term f u) of + (NONE, NONE) => NONE + | (SOME t'', NONE) => SOME (t'' $ u) + | (NONE, SOME u'') => SOME (t $ u'') + | (SOME t'', SOME u'') => SOME (t'' $ u'')) + | map_term' f (Abs (s, T, t)) = + (case map_term f t of + NONE => NONE + | SOME t'' => SOME (Abs (s, T, t''))) + | map_term' _ _ = NONE; + +fun map_thm_tac ctxt tac thm = +let + val monos = Inductive.get_monos ctxt + val simps = HOL_basic_ss addsimps @{thms split_def} +in + EVERY [cut_facts_tac [thm] 1, etac rev_mp 1, + REPEAT_DETERM (FIRSTGOAL (simp_tac simps THEN' resolve_tac monos)), + REPEAT_DETERM (rtac impI 1 THEN (atac 1 ORELSE tac))] +end + +fun map_thm ctxt f tac thm = +let + val opt_goal_trm = map_term f (prop_of thm) +in + case opt_goal_trm of + NONE => thm + | SOME goal => + Goal.prove ctxt [] [] goal (fn _ => map_thm_tac ctxt tac thm) +end + +(* + inductive premises can be of the form + R ... /\ P ...; split_conj_i picks out + the part R or P part +*) +fun split_conj1 names (Const ("op &", _) $ f1 $ f2) = + (case head_of f1 of + Const (name, _) => if member (op =) names name then SOME f1 else NONE + | _ => NONE) +| split_conj1 _ _ = NONE; + +fun split_conj2 names (Const ("op &", _) $ f1 $ f2) = + (case head_of f1 of + Const (name, _) => if member (op =) names name then SOME f2 else NONE + | _ => NONE) +| split_conj2 _ _ = NONE; + +fun transform_prem1 ctxt names thm = + map_thm ctxt (split_conj1 names) (etac conjunct1 1) thm + +fun transform_prem2 ctxt names thm = + map_thm ctxt (split_conj2 names) (etac conjunct2 1) thm + + + end (* structure *) open Nominal_Library; \ No newline at end of file