Nominal-General/nominal_library.ML
changeset 2311 4da5c5c29009
parent 2304 8a98171ba1fc
child 2313 25d2cdf7d7e4
--- 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