emerging Isar command interface
authorhaftmann
Wed, 17 Nov 2010 12:24:58 +0100
changeset 40587 5206d19038c7
parent 40586 fe4f6703c59e
child 40588 5a2b0b817eca
child 40594 fae1da97bb5e
emerging Isar command interface
src/HOL/Tools/functorial_mappers.ML
--- a/src/HOL/Tools/functorial_mappers.ML	Wed Nov 17 11:38:47 2010 +0100
+++ b/src/HOL/Tools/functorial_mappers.ML	Wed Nov 17 12:24:58 2010 +0100
@@ -129,7 +129,7 @@
   in (x, (HOLogic.mk_Trueprop o HOLogic.mk_eq) (lhs, x)) end;
 
 
-(* registering primitive mappers *)
+(* registering mappers *)
 
 fun register tyco mapper variances raw_concatenate raw_identity thy =
   let
@@ -148,14 +148,56 @@
         concatenate = concatenate, identity = identity }))
   end;
 
+fun split_mapper_typ "fun" T =
+      let
+        val (Ts', T') = strip_type T;
+        val (Ts'', T'') = split_last Ts';
+        val (Ts''', T''') = split_last Ts'';
+      in (Ts''', T''', T'' --> T') end
+  | split_mapper_typ tyco T =
+      let
+        val (Ts', T') = strip_type T;
+        val (Ts'', T'') = split_last Ts';
+      in (Ts'', T'', T') end;
+
+fun analyze_variances thy tyco T =
+  let
+    fun bad_typ () = error ("Bad mapper type: " ^ Syntax.string_of_typ_global thy T);
+    val (Ts, T1, T2) = split_mapper_typ tyco T
+      handle List.Empty => bad_typ ();
+    val _ = pairself
+      ((fn tyco' => if tyco' = tyco then () else bad_typ ()) o fst o dest_Type) (T1, T2)
+    val (vs1, vs2) = pairself (map dest_TFree o snd o dest_Type) (T1, T2)
+      handle TYPE _ => bad_typ ();
+    val _ = if has_duplicates (eq_fst (op =)) (vs1 @ vs2)
+      then bad_typ () else ();
+  in [] end;
+
 fun gen_type_mapper prep_term raw_t thy =
   let
-    val t = prep_term thy raw_t;
-    val after_qed = K I;
+    val (mapper, T) = case prep_term thy raw_t
+     of Const cT => cT
+      | t => error ("No constant: " ^ Syntax.string_of_term_global thy t);
+    val _ = Type.no_tvars T;
+    fun add_tycos (Type (tyco, Ts)) = insert (op =) tyco #> fold add_tycos Ts
+      | add_tycos _ = I;
+    val tycos = add_tycos T [];
+    val tyco = if tycos = ["fun"] then "fun"
+      else case remove (op =) "fun" tycos
+       of [tyco] => tyco
+        | _ => error ("Bad number of type constructors: " ^ Syntax.string_of_typ_global thy T);
+    val variances = analyze_variances thy tyco T;
+    val (_, concatenate_prop) = make_concatenate_prop variances (tyco, mapper);
+    val (_, identity_prop) = make_identity_prop variances (tyco, mapper);
+    fun after_qed [[concatenate], [identity]] lthy =
+      lthy
+      |> (Local_Theory.background_theory o Data.map)
+          (Symtab.update (tyco, { mapper = mapper, variances = variances,
+            concatenate = concatenate, identity = identity }));
   in
     thy
     |> Named_Target.theory_init
-    |> Proof.theorem NONE after_qed []
+    |> Proof.theorem NONE after_qed (map (fn t => [(t, [])]) [concatenate_prop, identity_prop])
   end
 
 val type_mapper = gen_type_mapper Sign.cert_term;