| author | wenzelm | 
| Tue, 20 May 2014 14:56:35 +0200 | |
| changeset 57022 | 801c01004a21 | 
| parent 55467 | a5c9002bc54d | 
| child 59058 | a78612c67ec0 | 
| permissions | -rw-r--r-- | 
| 55467 
a5c9002bc54d
renamed 'enriched_type' to more informative 'functor' (following the renaming of enriched type constructors to bounded natural functors)
 blanchet parents: 
51717diff
changeset | 1 | (* Title: HOL/Tools/functor.ML | 
| 40582 | 2 | Author: Florian Haftmann, TU Muenchen | 
| 3 | ||
| 40968 
a6fcd305f7dc
replace `type_mapper` by the more adequate `type_lifting`
 haftmann parents: 
40857diff
changeset | 4 | Functorial structure of types. | 
| 40582 | 5 | *) | 
| 6 | ||
| 55467 
a5c9002bc54d
renamed 'enriched_type' to more informative 'functor' (following the renaming of enriched type constructors to bounded natural functors)
 blanchet parents: 
51717diff
changeset | 7 | signature FUNCTOR = | 
| 40582 | 8 | sig | 
| 41388 | 9 | val find_atomic: Proof.context -> typ -> (typ * (bool * bool)) list | 
| 10 | val construct_mapper: Proof.context -> (string * bool -> term) | |
| 40582 | 11 | -> bool -> typ -> typ -> term | 
| 55467 
a5c9002bc54d
renamed 'enriched_type' to more informative 'functor' (following the renaming of enriched type constructors to bounded natural functors)
 blanchet parents: 
51717diff
changeset | 12 | val functorx: string option -> term -> local_theory -> Proof.state | 
| 
a5c9002bc54d
renamed 'enriched_type' to more informative 'functor' (following the renaming of enriched type constructors to bounded natural functors)
 blanchet parents: 
51717diff
changeset | 13 | val functor_cmd: string option -> string -> Proof.context -> Proof.state | 
| 40582 | 14 | type entry | 
| 41390 
207ee8f8a19c
full localization with possibly multiple entries;
 haftmann parents: 
41389diff
changeset | 15 | val entries: Proof.context -> entry list Symtab.table | 
| 40582 | 16 | end; | 
| 17 | ||
| 55467 
a5c9002bc54d
renamed 'enriched_type' to more informative 'functor' (following the renaming of enriched type constructors to bounded natural functors)
 blanchet parents: 
51717diff
changeset | 18 | structure Functor : FUNCTOR = | 
| 40582 | 19 | struct | 
| 20 | ||
| 41395 | 21 | (* bookkeeping *) | 
| 22 | ||
| 41371 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 23 | val compN = "comp"; | 
| 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 24 | val idN = "id"; | 
| 40611 | 25 | val compositionalityN = "compositionality"; | 
| 40594 
fae1da97bb5e
infer variances of user-given mapper operation; proper thm storing
 haftmann parents: 
40587diff
changeset | 26 | val identityN = "identity"; | 
| 
fae1da97bb5e
infer variances of user-given mapper operation; proper thm storing
 haftmann parents: 
40587diff
changeset | 27 | |
| 41387 | 28 | type entry = { mapper: term, variances: (sort * (bool * bool)) list,
 | 
| 41371 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 29 | comp: thm, id: thm }; | 
| 40582 | 30 | |
| 41472 
f6ab14e61604
misc tuning and comments based on review of Theory_Data, Proof_Data, Generic_Data usage;
 wenzelm parents: 
41395diff
changeset | 31 | structure Data = Generic_Data | 
| 
f6ab14e61604
misc tuning and comments based on review of Theory_Data, Proof_Data, Generic_Data usage;
 wenzelm parents: 
41395diff
changeset | 32 | ( | 
| 41390 
207ee8f8a19c
full localization with possibly multiple entries;
 haftmann parents: 
41389diff
changeset | 33 | type T = entry list Symtab.table | 
| 40582 | 34 | val empty = Symtab.empty | 
| 35 | val extend = I | |
| 41472 
f6ab14e61604
misc tuning and comments based on review of Theory_Data, Proof_Data, Generic_Data usage;
 wenzelm parents: 
41395diff
changeset | 36 | fun merge data = Symtab.merge (K true) data | 
| 40582 | 37 | ); | 
| 38 | ||
| 41388 | 39 | val entries = Data.get o Context.Proof; | 
| 40582 | 40 | |
| 41 | ||
| 42 | (* type analysis *) | |
| 43 | ||
| 41389 | 44 | fun term_with_typ ctxt T t = Envir.subst_term_types | 
| 42361 | 45 | (Type.typ_match (Proof_Context.tsig_of ctxt) (fastype_of t, T) Vartab.empty) t; | 
| 41389 | 46 | |
| 41388 | 47 | fun find_atomic ctxt T = | 
| 40582 | 48 | let | 
| 41390 
207ee8f8a19c
full localization with possibly multiple entries;
 haftmann parents: 
41389diff
changeset | 49 | val variances_of = Option.map #variances o try hd o Symtab.lookup_list (entries ctxt); | 
| 40582 | 50 | fun add_variance is_contra T = | 
| 51 | AList.map_default (op =) (T, (false, false)) | |
| 52 | ((if is_contra then apsnd else apfst) (K true)); | |
| 53 | fun analyze' is_contra (_, (co, contra)) T = | |
| 54 | (if co then analyze is_contra T else I) | |
| 55 | #> (if contra then analyze (not is_contra) T else I) | |
| 56 | and analyze is_contra (T as Type (tyco, Ts)) = (case variances_of tyco | |
| 57 | of NONE => add_variance is_contra T | |
| 58 | | SOME variances => fold2 (analyze' is_contra) variances Ts) | |
| 59 | | analyze is_contra T = add_variance is_contra T; | |
| 60 | in analyze false T [] end; | |
| 61 | ||
| 41388 | 62 | fun construct_mapper ctxt atomic = | 
| 40582 | 63 | let | 
| 41390 
207ee8f8a19c
full localization with possibly multiple entries;
 haftmann parents: 
41389diff
changeset | 64 | val lookup = hd o Symtab.lookup_list (entries ctxt); | 
| 40582 | 65 | fun constructs is_contra (_, (co, contra)) T T' = | 
| 66 | (if co then [construct is_contra T T'] else []) | |
| 67 | @ (if contra then [construct (not is_contra) T T'] else []) | |
| 68 | and construct is_contra (T as Type (tyco, Ts)) (T' as Type (_, Ts')) = | |
| 69 | let | |
| 41388 | 70 |             val { mapper = raw_mapper, variances, ... } = lookup tyco;
 | 
| 40582 | 71 | val args = maps (fn (arg_pattern, (T, T')) => | 
| 72 | constructs is_contra arg_pattern T T') | |
| 73 | (variances ~~ (Ts ~~ Ts')); | |
| 74 | val (U, U') = if is_contra then (T', T) else (T, T'); | |
| 41388 | 75 | val mapper = term_with_typ ctxt (map fastype_of args ---> U --> U') raw_mapper; | 
| 76 | in list_comb (mapper, args) end | |
| 40582 | 77 | | construct is_contra (TFree (v, _)) (TFree _) = atomic (v, is_contra); | 
| 78 | in construct end; | |
| 79 | ||
| 80 | ||
| 81 | (* mapper properties *) | |
| 82 | ||
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51551diff
changeset | 83 | val compositionality_ss = | 
| 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51551diff
changeset | 84 |   simpset_of (put_simpset HOL_basic_ss @{context} addsimps [Simpdata.mk_eq @{thm comp_def}]);
 | 
| 41387 | 85 | |
| 41371 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 86 | fun make_comp_prop ctxt variances (tyco, mapper) = | 
| 40582 | 87 | let | 
| 41371 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 88 | val sorts = map fst variances | 
| 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 89 | val (((vs3, vs2), vs1), _) = ctxt | 
| 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 90 | |> Variable.invent_types sorts | 
| 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 91 | ||>> Variable.invent_types sorts | 
| 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 92 | ||>> Variable.invent_types sorts | 
| 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 93 | val (Ts1, Ts2, Ts3) = (map TFree vs1, map TFree vs2, map TFree vs3); | 
| 40582 | 94 | fun mk_argT ((T, T'), (_, (co, contra))) = | 
| 95 | (if co then [(T --> T')] else []) | |
| 96 | @ (if contra then [(T' --> T)] else []); | |
| 97 | val contras = maps (fn (_, (co, contra)) => | |
| 98 | (if co then [false] else []) @ (if contra then [true] else [])) variances; | |
| 99 | val Ts21 = maps mk_argT ((Ts2 ~~ Ts1) ~~ variances); | |
| 100 | val Ts32 = maps mk_argT ((Ts3 ~~ Ts2) ~~ variances); | |
| 41371 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 101 | fun invents n k nctxt = | 
| 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 102 | let | 
| 43329 
84472e198515
tuned signature: Name.invent and Name.invent_names;
 wenzelm parents: 
42388diff
changeset | 103 | val names = Name.invent nctxt n k; | 
| 41371 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 104 | in (names, fold Name.declare names nctxt) end; | 
| 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 105 | val ((names21, names32), nctxt) = Variable.names_of ctxt | 
| 40582 | 106 | |> invents "f" (length Ts21) | 
| 107 | ||>> invents "f" (length Ts32); | |
| 108 | val T1 = Type (tyco, Ts1); | |
| 109 | val T2 = Type (tyco, Ts2); | |
| 110 | val T3 = Type (tyco, Ts3); | |
| 111 | val (args21, args32) = (names21 ~~ Ts21, names32 ~~ Ts32); | |
| 112 | val args31 = map2 (fn is_contra => fn ((f21, T21), (f32, T32)) => | |
| 113 | if not is_contra then | |
| 41371 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 114 | HOLogic.mk_comp (Free (f21, T21), Free (f32, T32)) | 
| 40582 | 115 | else | 
| 41371 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 116 | HOLogic.mk_comp (Free (f32, T32), Free (f21, T21)) | 
| 40582 | 117 | ) contras (args21 ~~ args32) | 
| 41395 | 118 | fun mk_mapper T T' args = list_comb | 
| 119 | (term_with_typ ctxt (map fastype_of args ---> T --> T') mapper, args); | |
| 41387 | 120 | val mapper21 = mk_mapper T2 T1 (map Free args21); | 
| 121 | val mapper32 = mk_mapper T3 T2 (map Free args32); | |
| 122 | val mapper31 = mk_mapper T3 T1 args31; | |
| 41395 | 123 | val eq1 = (HOLogic.mk_Trueprop o HOLogic.mk_eq) | 
| 124 | (HOLogic.mk_comp (mapper21, mapper32), mapper31); | |
| 43329 
84472e198515
tuned signature: Name.invent and Name.invent_names;
 wenzelm parents: 
42388diff
changeset | 125 | val x = Free (the_single (Name.invent nctxt (Long_Name.base_name tyco) 1), T3) | 
| 41395 | 126 | val eq2 = (HOLogic.mk_Trueprop o HOLogic.mk_eq) | 
| 127 | (mapper21 $ (mapper32 $ x), mapper31 $ x); | |
| 41387 | 128 | val comp_prop = fold_rev Logic.all (map Free (args21 @ args32)) eq1; | 
| 129 | val compositionality_prop = fold_rev Logic.all (map Free (args21 @ args32) @ [x]) eq2; | |
| 51551 | 130 | fun prove_compositionality ctxt comp_thm = Goal.prove_sorry ctxt [] [] compositionality_prop | 
| 41387 | 131 |       (K (ALLGOALS (Method.insert_tac [@{thm fun_cong} OF [comp_thm]]
 | 
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51551diff
changeset | 132 | THEN' Simplifier.asm_lr_simp_tac (put_simpset compositionality_ss ctxt) | 
| 41387 | 133 | THEN_ALL_NEW (Goal.assume_rule_tac ctxt)))); | 
| 134 | in (comp_prop, prove_compositionality) end; | |
| 135 | ||
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51551diff
changeset | 136 | val identity_ss = | 
| 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51551diff
changeset | 137 |   simpset_of (put_simpset HOL_basic_ss @{context} addsimps [Simpdata.mk_eq @{thm id_def}]);
 | 
| 40582 | 138 | |
| 41371 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 139 | fun make_id_prop ctxt variances (tyco, mapper) = | 
| 40582 | 140 | let | 
| 46810 | 141 | val (vs, _) = Variable.invent_types (map fst variances) ctxt; | 
| 41371 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 142 | val Ts = map TFree vs; | 
| 40582 | 143 | fun bool_num b = if b then 1 else 0; | 
| 144 | fun mk_argT (T, (_, (co, contra))) = | |
| 41387 | 145 | replicate (bool_num co + bool_num contra) T | 
| 146 | val arg_Ts = maps mk_argT (Ts ~~ variances) | |
| 40582 | 147 | val T = Type (tyco, Ts); | 
| 41387 | 148 | val head = term_with_typ ctxt (map (fn T => T --> T) arg_Ts ---> T --> T) mapper; | 
| 149 | val lhs1 = list_comb (head, map (HOLogic.id_const) arg_Ts); | |
| 150 |     val lhs2 = list_comb (head, map (fn arg_T => Abs ("x", arg_T, Bound 0)) arg_Ts);
 | |
| 151 | val rhs = HOLogic.id_const T; | |
| 41395 | 152 | val (id_prop, identity_prop) = pairself | 
| 153 | (HOLogic.mk_Trueprop o HOLogic.mk_eq o rpair rhs) (lhs1, lhs2); | |
| 51551 | 154 | fun prove_identity ctxt id_thm = Goal.prove_sorry ctxt [] [] identity_prop | 
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51551diff
changeset | 155 | (K (ALLGOALS (Method.insert_tac [id_thm] THEN' | 
| 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51551diff
changeset | 156 | Simplifier.asm_lr_simp_tac (put_simpset identity_ss ctxt)))); | 
| 41387 | 157 | in (id_prop, prove_identity) end; | 
| 40582 | 158 | |
| 159 | ||
| 40597 | 160 | (* analyzing and registering mappers *) | 
| 40582 | 161 | |
| 55467 
a5c9002bc54d
renamed 'enriched_type' to more informative 'functor' (following the renaming of enriched type constructors to bounded natural functors)
 blanchet parents: 
51717diff
changeset | 162 | fun consume _ _ [] = (false, []) | 
| 40594 
fae1da97bb5e
infer variances of user-given mapper operation; proper thm storing
 haftmann parents: 
40587diff
changeset | 163 | | consume eq x (ys as z :: zs) = if eq (x, z) then (true, zs) else (false, ys); | 
| 
fae1da97bb5e
infer variances of user-given mapper operation; proper thm storing
 haftmann parents: 
40587diff
changeset | 164 | |
| 40587 | 165 | fun split_mapper_typ "fun" T = | 
| 166 | let | |
| 167 | val (Ts', T') = strip_type T; | |
| 168 | val (Ts'', T'') = split_last Ts'; | |
| 169 | val (Ts''', T''') = split_last Ts''; | |
| 170 | in (Ts''', T''', T'' --> T') end | |
| 46810 | 171 | | split_mapper_typ _ T = | 
| 40587 | 172 | let | 
| 173 | val (Ts', T') = strip_type T; | |
| 174 | val (Ts'', T'') = split_last Ts'; | |
| 175 | in (Ts'', T'', T') end; | |
| 176 | ||
| 46852 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 177 | fun analyze_mapper ctxt input_mapper = | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 178 | let | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 179 | val T = fastype_of input_mapper; | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 180 | val _ = Type.no_tvars T; | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 181 | val _ = | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 182 | if null (subtract (op =) (Term.add_tfreesT T []) (Term.add_tfrees input_mapper [])) | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 183 | then () | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 184 |       else error ("Illegal additional type variable(s) in term: " ^ Syntax.string_of_term ctxt input_mapper);
 | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 185 | val _ = | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 186 | if null (Term.add_vars (singleton | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 187 | (Variable.export_terms (Variable.auto_fixes input_mapper ctxt) ctxt) input_mapper) []) | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 188 | then () | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 189 |       else error ("Illegal locally free variable(s) in term: "
 | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 190 | ^ Syntax.string_of_term ctxt input_mapper);; | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 191 | val mapper = singleton (Variable.polymorphic ctxt) input_mapper; | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 192 | val _ = | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 193 | if null (Term.add_tfreesT (fastype_of mapper) []) then () | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 194 |       else error ("Illegal locally fixed type variable(s) in type: " ^ Syntax.string_of_typ ctxt T);
 | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 195 | fun add_tycos (Type (tyco, Ts)) = insert (op =) tyco #> fold add_tycos Ts | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 196 | | add_tycos _ = I; | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 197 | val tycos = add_tycos T []; | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 198 | val tyco = if tycos = ["fun"] then "fun" | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 199 | else case remove (op =) "fun" tycos | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 200 | of [tyco] => tyco | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 201 |         | _ => error ("Bad number of type constructors: " ^ Syntax.string_of_typ ctxt T);
 | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 202 | in (mapper, T, tyco) end; | 
| 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 203 | |
| 41390 
207ee8f8a19c
full localization with possibly multiple entries;
 haftmann parents: 
41389diff
changeset | 204 | fun analyze_variances ctxt tyco T = | 
| 40587 | 205 | let | 
| 41390 
207ee8f8a19c
full localization with possibly multiple entries;
 haftmann parents: 
41389diff
changeset | 206 |     fun bad_typ () = error ("Bad mapper type: " ^ Syntax.string_of_typ ctxt T);
 | 
| 40587 | 207 | val (Ts, T1, T2) = split_mapper_typ tyco T | 
| 208 | handle List.Empty => bad_typ (); | |
| 209 | val _ = pairself | |
| 210 | ((fn tyco' => if tyco' = tyco then () else bad_typ ()) o fst o dest_Type) (T1, T2) | |
| 41387 | 211 | handle TYPE _ => bad_typ (); | 
| 40587 | 212 | val (vs1, vs2) = pairself (map dest_TFree o snd o dest_Type) (T1, T2) | 
| 213 | handle TYPE _ => bad_typ (); | |
| 214 | val _ = if has_duplicates (eq_fst (op =)) (vs1 @ vs2) | |
| 215 | then bad_typ () else (); | |
| 46810 | 216 | fun check_variance_pair (var1 as (_, sort1), var2 as (_, sort2)) = | 
| 40594 
fae1da97bb5e
infer variances of user-given mapper operation; proper thm storing
 haftmann parents: 
40587diff
changeset | 217 | let | 
| 
fae1da97bb5e
infer variances of user-given mapper operation; proper thm storing
 haftmann parents: 
40587diff
changeset | 218 | val coT = TFree var1 --> TFree var2; | 
| 
fae1da97bb5e
infer variances of user-given mapper operation; proper thm storing
 haftmann parents: 
40587diff
changeset | 219 | val contraT = TFree var2 --> TFree var1; | 
| 42361 | 220 | val sort = Sign.inter_sort (Proof_Context.theory_of ctxt) (sort1, sort2); | 
| 40594 
fae1da97bb5e
infer variances of user-given mapper operation; proper thm storing
 haftmann parents: 
40587diff
changeset | 221 | in | 
| 
fae1da97bb5e
infer variances of user-given mapper operation; proper thm storing
 haftmann parents: 
40587diff
changeset | 222 | consume (op =) coT | 
| 
fae1da97bb5e
infer variances of user-given mapper operation; proper thm storing
 haftmann parents: 
40587diff
changeset | 223 | ##>> consume (op =) contraT | 
| 
fae1da97bb5e
infer variances of user-given mapper operation; proper thm storing
 haftmann parents: 
40587diff
changeset | 224 | #>> pair sort | 
| 
fae1da97bb5e
infer variances of user-given mapper operation; proper thm storing
 haftmann parents: 
40587diff
changeset | 225 | end; | 
| 
fae1da97bb5e
infer variances of user-given mapper operation; proper thm storing
 haftmann parents: 
40587diff
changeset | 226 | val (variances, left_variances) = fold_map check_variance_pair (vs1 ~~ vs2) Ts; | 
| 
fae1da97bb5e
infer variances of user-given mapper operation; proper thm storing
 haftmann parents: 
40587diff
changeset | 227 | val _ = if null left_variances then () else bad_typ (); | 
| 
fae1da97bb5e
infer variances of user-given mapper operation; proper thm storing
 haftmann parents: 
40587diff
changeset | 228 | in variances end; | 
| 40587 | 229 | |
| 55467 
a5c9002bc54d
renamed 'enriched_type' to more informative 'functor' (following the renaming of enriched type constructors to bounded natural functors)
 blanchet parents: 
51717diff
changeset | 230 | fun gen_functor prep_term some_prfx raw_mapper lthy = | 
| 40583 | 231 | let | 
| 46852 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 232 | val (mapper, T, tyco) = analyze_mapper lthy (prep_term lthy raw_mapper); | 
| 41371 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 233 | val prfx = the_default (Long_Name.base_name tyco) some_prfx; | 
| 41390 
207ee8f8a19c
full localization with possibly multiple entries;
 haftmann parents: 
41389diff
changeset | 234 | val variances = analyze_variances lthy tyco T; | 
| 
207ee8f8a19c
full localization with possibly multiple entries;
 haftmann parents: 
41389diff
changeset | 235 | val (comp_prop, prove_compositionality) = make_comp_prop lthy variances (tyco, mapper); | 
| 
207ee8f8a19c
full localization with possibly multiple entries;
 haftmann parents: 
41389diff
changeset | 236 | val (id_prop, prove_identity) = make_id_prop lthy variances (tyco, mapper); | 
| 40856 
3ad8a5925ba4
optional explicit prefix for type mapper theorems
 haftmann parents: 
40855diff
changeset | 237 | val qualify = Binding.qualify true prfx o Binding.name; | 
| 41389 | 238 | fun mapper_declaration comp_thm id_thm phi context = | 
| 239 | let | |
| 42388 | 240 | val typ_instance = Sign.typ_instance (Context.theory_of context); | 
| 41389 | 241 | val mapper' = Morphism.term phi mapper; | 
| 242 | val T_T' = pairself fastype_of (mapper, mapper'); | |
| 46852 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 243 | val vars = Term.add_vars mapper' []; | 
| 42388 | 244 | in | 
| 46852 
0b8dd4c8c79a
more precise checking for wellformedness of mapper, before and after morphism application
 haftmann parents: 
46851diff
changeset | 245 | if null vars andalso typ_instance T_T' andalso typ_instance (swap T_T') | 
| 41390 
207ee8f8a19c
full localization with possibly multiple entries;
 haftmann parents: 
41389diff
changeset | 246 | then (Data.map o Symtab.cons_list) (tyco, | 
| 41389 | 247 |           { mapper = mapper', variances = variances,
 | 
| 41390 
207ee8f8a19c
full localization with possibly multiple entries;
 haftmann parents: 
41389diff
changeset | 248 | comp = Morphism.thm phi comp_thm, id = Morphism.thm phi id_thm }) context | 
| 41389 | 249 | else context | 
| 250 | end; | |
| 41387 | 251 | fun after_qed [single_comp_thm, single_id_thm] lthy = | 
| 40587 | 252 | lthy | 
| 41387 | 253 | |> Local_Theory.note ((qualify compN, []), single_comp_thm) | 
| 254 | ||>> Local_Theory.note ((qualify idN, []), single_id_thm) | |
| 255 | |-> (fn ((_, [comp_thm]), (_, [id_thm])) => fn lthy => | |
| 41371 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 256 | lthy | 
| 41388 | 257 | |> Local_Theory.note ((qualify compositionalityN, []), | 
| 258 | [prove_compositionality lthy comp_thm]) | |
| 41371 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 259 | |> snd | 
| 41388 | 260 | |> Local_Theory.note ((qualify identityN, []), | 
| 261 | [prove_identity lthy id_thm]) | |
| 262 | |> snd | |
| 45291 
57cd50f98fdc
uniform Local_Theory.declaration with explicit params;
 wenzelm parents: 
43329diff
changeset | 263 |         |> Local_Theory.declaration {syntax = false, pervasive = false}
 | 
| 
57cd50f98fdc
uniform Local_Theory.declaration with explicit params;
 wenzelm parents: 
43329diff
changeset | 264 | (mapper_declaration comp_thm id_thm)) | 
| 40583 | 265 | in | 
| 41390 
207ee8f8a19c
full localization with possibly multiple entries;
 haftmann parents: 
41389diff
changeset | 266 | lthy | 
| 41371 
35d2241c169c
prove more algebraic version of functorial properties; retain old properties for convenience
 haftmann parents: 
41298diff
changeset | 267 | |> Proof.theorem NONE after_qed (map (fn t => [(t, [])]) [comp_prop, id_prop]) | 
| 40583 | 268 | end | 
| 269 | ||
| 55467 
a5c9002bc54d
renamed 'enriched_type' to more informative 'functor' (following the renaming of enriched type constructors to bounded natural functors)
 blanchet parents: 
51717diff
changeset | 270 | val functorx = gen_functor Syntax.check_term; | 
| 
a5c9002bc54d
renamed 'enriched_type' to more informative 'functor' (following the renaming of enriched type constructors to bounded natural functors)
 blanchet parents: 
51717diff
changeset | 271 | val functor_cmd = gen_functor Syntax.read_term; | 
| 40583 | 272 | |
| 46961 
5c6955f487e5
outer syntax command definitions based on formal command_spec derived from theory header declarations;
 wenzelm parents: 
46949diff
changeset | 273 | val _ = | 
| 55467 
a5c9002bc54d
renamed 'enriched_type' to more informative 'functor' (following the renaming of enriched type constructors to bounded natural functors)
 blanchet parents: 
51717diff
changeset | 274 |   Outer_Syntax.local_theory_to_proof @{command_spec "functor"}
 | 
| 46961 
5c6955f487e5
outer syntax command definitions based on formal command_spec derived from theory header declarations;
 wenzelm parents: 
46949diff
changeset | 275 | "register operations managing the functorial structure of a type" | 
| 
5c6955f487e5
outer syntax command definitions based on formal command_spec derived from theory header declarations;
 wenzelm parents: 
46949diff
changeset | 276 |     (Scan.option (Parse.name --| @{keyword ":"}) -- Parse.term
 | 
| 55467 
a5c9002bc54d
renamed 'enriched_type' to more informative 'functor' (following the renaming of enriched type constructors to bounded natural functors)
 blanchet parents: 
51717diff
changeset | 277 | >> (fn (prfx, t) => functor_cmd prfx t)); | 
| 40583 | 278 | |
| 40582 | 279 | end; |