94 type 'att element = (string, string, string, 'att) elem_expr; |
95 type 'att element = (string, string, string, 'att) elem_expr; |
95 type 'att element_i = (typ, term, thm list, 'att) elem_expr; |
96 type 'att element_i = (typ, term, thm list, 'att) elem_expr; |
96 |
97 |
97 type locale = |
98 type locale = |
98 {view: cterm list * thm list, |
99 {view: cterm list * thm list, |
99 (* If locale "loc" contains assumptions, either via import or in the |
100 (* CB: If locale "loc" contains assumptions, either via import or in the |
100 locale body, a locale predicate "loc" is defined capturing all the |
101 locale body, a locale predicate "loc" is defined capturing all the |
101 assumptions. If both import and body contain assumptions, additionally |
102 assumptions. If both import and body contain assumptions, additionally |
102 a delta predicate "loc_axioms" is defined that abbreviates the |
103 a delta predicate "loc_axioms" is defined that abbreviates the |
103 assumptions of the body. |
104 assumptions of the body. |
104 The context generated when entering "loc" contains not (necessarily) a |
105 The context generated when entering "loc" contains not (necessarily) a |
105 single assumption "loc", but a list of assumptions of all locale |
106 single assumption "loc", but a list of assumptions of all locale |
106 predicates of locales without import and all delta predicates of |
107 predicates of locales without import and all delta predicates of |
107 locales with import from the import hierarchy (duplicates removed, |
108 locales with import from the import hierarchy (duplicates removed, |
108 cf. [1], normalisation of locale expressions). |
109 cf. [1], normalisation of locale expressions). |
109 |
110 |
110 The first part of view in the above definition (also called statement) |
111 The record entry view is either ([], []) or ([statement], axioms) |
111 represents this list of assumptions. The second part (also called |
112 where statement is the predicate "loc" applied to the parameters, |
112 axioms) contains projections from the predicate "loc" to these |
113 and axioms contains projections from "loc" to the list of assumptions |
113 assumptions. |
114 generated when entering the locale. |
|
115 It appears that an axiom of the form A [A] is never generated. |
114 *) |
116 *) |
115 import: expr, (*dynamic import*) |
117 import: expr, (*dynamic import*) |
116 elems: ((typ, term, thm list, context attribute) elem * stamp) list, (*static content*) |
118 elems: ((typ, term, thm list, context attribute) elem * stamp) list, (*static content*) |
117 params: (string * typ option) list * string list}; (*all/local params*) |
119 params: (string * typ option) list * string list}; (*all/local params*) |
118 |
120 |
843 |
890 |
844 end; |
891 end; |
845 |
892 |
846 fun prep_elemss prep_fixes prepp do_close context fixed_params raw_elemss raw_concl = |
893 fun prep_elemss prep_fixes prepp do_close context fixed_params raw_elemss raw_concl = |
847 let |
894 let |
|
895 (* CB: raw_elemss are list of pairs consisting of identifiers and |
|
896 context elements, the latter marked as internal or external. *) |
848 val (raw_ctxt, raw_proppss) = declare_elemss prep_fixes fixed_params raw_elemss context; |
897 val (raw_ctxt, raw_proppss) = declare_elemss prep_fixes fixed_params raw_elemss context; |
|
898 (* CB: raw_ctxt is context with additional fixed variables derived from |
|
899 the fixes elements in raw_elemss, |
|
900 raw_proppss contains assumptions and definitions from the |
|
901 (external?) elements in raw_elemss. *) |
849 val raw_propps = map flat raw_proppss; |
902 val raw_propps = map flat raw_proppss; |
850 val raw_propp = flat raw_propps; |
903 val raw_propp = flat raw_propps; |
851 val (ctxt, all_propp) = |
904 val (ctxt, all_propp) = |
852 prepp (ProofContext.declare_terms (map Free fixed_params) raw_ctxt, raw_concl @ raw_propp); |
905 prepp (ProofContext.declare_terms (map Free fixed_params) raw_ctxt, raw_concl @ raw_propp); |
|
906 (* CB: read/cert entire proposition (conclusion and premises from |
|
907 the context elements). *) |
853 val ctxt = ProofContext.declare_terms (flat (map (map fst) all_propp)) ctxt; |
908 val ctxt = ProofContext.declare_terms (flat (map (map fst) all_propp)) ctxt; |
|
909 (* CB: it appears that terms declared in the propositions are added |
|
910 to the context here. *) |
854 |
911 |
855 val all_propp' = map2 (op ~~) |
912 val all_propp' = map2 (op ~~) |
856 (#1 (#2 (ProofContext.bind_propp_schematic_i (ctxt, all_propp))), map (map snd) all_propp); |
913 (#1 (#2 (ProofContext.bind_propp_schematic_i (ctxt, all_propp))), map (map snd) all_propp); |
857 val (concl, propp) = splitAt(length raw_concl, all_propp'); |
914 val (concl, propp) = splitAt(length raw_concl, all_propp'); |
858 val propps = unflat raw_propps propp; |
915 val propps = unflat raw_propps propp; |
861 val xs = map #1 (params_of raw_elemss); |
918 val xs = map #1 (params_of raw_elemss); |
862 val typing = unify_frozen ctxt 0 |
919 val typing = unify_frozen ctxt 0 |
863 (map (ProofContext.default_type raw_ctxt) xs) |
920 (map (ProofContext.default_type raw_ctxt) xs) |
864 (map (ProofContext.default_type ctxt) xs); |
921 (map (ProofContext.default_type ctxt) xs); |
865 val parms = param_types (xs ~~ typing); |
922 val parms = param_types (xs ~~ typing); |
866 |
923 (* CB: parms are the parameters from raw_elemss, with correct typing. *) |
|
924 |
|
925 (* CB: extract information from assumes and defines elements |
|
926 (fixes and notes in raw_elemss don't have an effect on text and elemss), |
|
927 compute final form of context elements. *) |
867 val (text, elemss) = finish_elemss ctxt parms do_close |
928 val (text, elemss) = finish_elemss ctxt parms do_close |
868 (((([], []), ([], [])), ([], [], [])), raw_elemss ~~ proppss); |
929 (((([], []), ([], [])), ([], [], [])), raw_elemss ~~ proppss); |
|
930 (* CB: text has the following structure: |
|
931 (((exts, exts'), (ints, ints')), (xs, env, defs)) |
|
932 where |
|
933 exts: external assumptions (terms in external assumes elements) |
|
934 exts': dito, normalised wrt. env |
|
935 ints: internal assumptions (terms in internal assumes elements) |
|
936 ints': dito, normalised wrt. env |
|
937 xs: the free variables in exts' and ints' and rhss of definitions, |
|
938 this includes parameters except defined parameters |
|
939 env: list of term pairs encoding substitutions, where the first term |
|
940 is a free variable; substitutions represent defines elements and |
|
941 the rhs is normalised wrt. the previous env |
|
942 defs: theorems representing the substitutions from defines elements |
|
943 (thms are normalised wrt. env). |
|
944 elemss is an updated version of raw_elemss: |
|
945 - type info added to Fixes |
|
946 - axiom and definition statement replaced by corresponding one |
|
947 from proppss in Assumes and Defines |
|
948 - Facts unchanged |
|
949 *) |
869 in ((parms, elemss, concl), text) end; |
950 in ((parms, elemss, concl), text) end; |
870 |
951 |
871 in |
952 in |
872 |
953 |
873 fun read_elemss x = prep_elemss read_fixes ProofContext.read_propp_schematic x; |
954 fun read_elemss x = prep_elemss read_fixes ProofContext.read_propp_schematic x; |
907 fun prep_context_statement prep_expr prep_elemss prep_facts |
989 fun prep_context_statement prep_expr prep_elemss prep_facts |
908 do_close axioms fixed_params import elements raw_concl context = |
990 do_close axioms fixed_params import elements raw_concl context = |
909 let |
991 let |
910 val sign = ProofContext.sign_of context; |
992 val sign = ProofContext.sign_of context; |
911 |
993 |
912 fun flatten (ids, Elem (Fixes fixes)) = |
994 val (import_ids, raw_import_elemss) = flatten (context, prep_expr sign) ([], Expr import); |
913 (ids, [(("", map (rpair None o #1) fixes), Ext (Fixes fixes))]) |
|
914 | flatten (ids, Elem elem) = (ids, [(("", []), Ext elem)]) |
|
915 | flatten (ids, Expr expr) = |
|
916 apsnd (map (apsnd Int)) (flatten_expr context (ids, prep_expr sign expr)); |
|
917 |
|
918 val (import_ids, raw_import_elemss) = flatten ([], Expr import); |
|
919 (* CB: normalise "includes" among elements *) |
995 (* CB: normalise "includes" among elements *) |
920 val raw_elemss = flat (#2 ((foldl_map flatten (import_ids, elements)))); |
996 val raw_elemss = flat (#2 ((foldl_map (flatten (context, prep_expr sign)) |
|
997 (import_ids, elements)))); |
|
998 (* CB: raw_import_elemss @ raw_elemss is the normalised list of |
|
999 context elements obtained from import and elements. *) |
921 val ((parms, all_elemss, concl), (spec, (_, _, defs))) = prep_elemss do_close |
1000 val ((parms, all_elemss, concl), (spec, (_, _, defs))) = prep_elemss do_close |
922 context fixed_params (raw_import_elemss @ raw_elemss) raw_concl; |
1001 context fixed_params (raw_import_elemss @ raw_elemss) raw_concl; |
923 val (ps,qs) = splitAt(length raw_import_elemss, all_elemss) |
1002 val (ps,qs) = splitAt(length raw_import_elemss, all_elemss) |
924 val ((import_ctxt, axioms'), (import_elemss, _)) = |
1003 val ((import_ctxt, axioms'), (import_elemss, _)) = |
925 activate_facts prep_facts ((context, axioms), ps); |
1004 activate_facts prep_facts ((context, axioms), ps); |
936 fun gen_statement prep_locale prep_ctxt raw_locale elems concl ctxt = |
1015 fun gen_statement prep_locale prep_ctxt raw_locale elems concl ctxt = |
937 let |
1016 let |
938 val thy = ProofContext.theory_of ctxt; |
1017 val thy = ProofContext.theory_of ctxt; |
939 val locale = apsome (prep_locale (Theory.sign_of thy)) raw_locale; |
1018 val locale = apsome (prep_locale (Theory.sign_of thy)) raw_locale; |
940 val ((view_statement, view_axioms), fixed_params, import) = |
1019 val ((view_statement, view_axioms), fixed_params, import) = |
941 (* view_axioms are xxx.axioms of locale xxx *) |
1020 (* CB: view_axioms are xxx.axioms of locale xxx *) |
942 (case locale of None => (([], []), [], empty) |
1021 (case locale of None => (([], []), [], empty) |
943 | Some name => |
1022 | Some name => |
944 let val {view, params = (ps, _), ...} = the_locale thy name |
1023 let val {view, params = (ps, _), ...} = the_locale thy name |
945 in (view, param_types ps, Locale name) end); |
1024 in (view, param_types ps, Locale name) end); |
946 val ((((locale_ctxt, _), (elems_ctxt, _)), _), concl') = |
1025 val ((((locale_ctxt, _), (elems_ctxt, _)), _), concl') = |
947 prep_ctxt false view_axioms fixed_params import elems concl ctxt; |
1026 prep_ctxt false view_axioms fixed_params import elems concl ctxt; |
948 in (locale, view_statement, locale_ctxt, elems_ctxt, concl') end; |
1027 in (locale, view_statement, locale_ctxt, elems_ctxt, concl') end; |
949 |
1028 |
950 in |
1029 in |
951 |
1030 |
952 (* CB: arguments are: x->import, y->body (elements?), z->context *) |
1031 (* CB: arguments are: x->import, y->body (elements), z->context *) |
953 fun read_context x y z = #1 (gen_context true [] [] x y [] z); |
1032 fun read_context x y z = #1 (gen_context true [] [] x y [] z); |
954 fun cert_context x y z = #1 (gen_context_i true [] [] x y [] z); |
1033 fun cert_context x y z = #1 (gen_context_i true [] [] x y [] z); |
955 |
1034 |
956 val read_context_statement = gen_statement intern gen_context; |
1035 val read_context_statement = gen_statement intern gen_context; |
957 val cert_context_statement = gen_statement (K I) gen_context_i; |
1036 val cert_context_statement = gen_statement (K I) gen_context_i; |
958 |
1037 |
959 end; |
1038 end; |
960 |
1039 |
|
1040 |
|
1041 (** CB: experimental instantiation mechanism **) |
|
1042 |
|
1043 fun instantiate loc_name prfx raw_inst ctxt = |
|
1044 let |
|
1045 val thy = ProofContext.theory_of ctxt; |
|
1046 val sign = Theory.sign_of thy; |
|
1047 val tsig = Sign.tsig_of sign; |
|
1048 val cert = cterm_of sign; |
|
1049 |
|
1050 (** process the locale **) |
|
1051 |
|
1052 val {view = (_, axioms), params = (ps, _), ...} = |
|
1053 the_locale thy (intern sign loc_name); |
|
1054 val fixed_params = param_types ps; |
|
1055 val (ids, raw_elemss) = |
|
1056 flatten (ctxt, intern_expr sign) ([], Expr (Locale loc_name)); |
|
1057 val ((parms, all_elemss, concl), |
|
1058 (spec as (_, (ints, _)), (xs, env, defs))) = |
|
1059 read_elemss false (* do_close *) ctxt |
|
1060 fixed_params (* could also put [] here??? *) raw_elemss |
|
1061 [] (* concl *); |
|
1062 |
|
1063 (** analyse the instantiation theorem inst **) |
|
1064 |
|
1065 val inst = case raw_inst of |
|
1066 None => if null ints |
|
1067 then None |
|
1068 else error "Locale has assumptions but no chained fact was found" |
|
1069 | Some [] => if null ints |
|
1070 then None |
|
1071 else error "Locale has assumptions but no chained fact was found" |
|
1072 | Some [thm] => if null ints |
|
1073 then (warning "Locale has no assumptions: fact ignored"; None) |
|
1074 else Some thm |
|
1075 | Some _ => error "Multiple facts are not allowed"; |
|
1076 |
|
1077 val args = case inst of |
|
1078 None => [] |
|
1079 | Some thm => thm |> prop_of |> ObjectLogic.drop_judgment sign |
|
1080 |> Term.strip_comb |> snd; |
|
1081 val cargs = map cert args; |
|
1082 |
|
1083 (* process parameters: match their types with those of arguments *) |
|
1084 |
|
1085 val def_names = map (fn (Free (s, _), _) => s) env; |
|
1086 val (defined, assumed) = partition |
|
1087 (fn (s, _) => s mem def_names) fixed_params; |
|
1088 val cassumed = map (cert o Free) assumed; |
|
1089 val cdefined = map (cert o Free) defined; |
|
1090 |
|
1091 val param_types = map snd assumed; |
|
1092 val v_param_types = map Type.varifyT param_types; |
|
1093 val arg_types = map Term.fastype_of args; |
|
1094 val Tenv = foldl (Type.typ_match tsig) |
|
1095 (Vartab.empty, v_param_types ~~ arg_types) |
|
1096 handle Library.LIST "~~" => error "Number of parameters does not match number of arguments of chained fact"; |
|
1097 (* get their sorts *) |
|
1098 val tfrees = foldr Term.add_typ_tfrees (param_types, []); |
|
1099 val Tenv' = map |
|
1100 (fn ((a, i), T) => ((a, the (assoc_string (tfrees, a))), T)) |
|
1101 (Vartab.dest Tenv); |
|
1102 |
|
1103 (* process (internal) elements *) |
|
1104 |
|
1105 fun inst_type [] T = T |
|
1106 | inst_type env T = |
|
1107 Term.map_type_tfree (fn v => if_none (assoc (env, v)) (TFree v)) T; |
|
1108 |
|
1109 fun inst_term [] t = t |
|
1110 | inst_term env t = Term.map_term_types (inst_type env) t; |
|
1111 |
|
1112 (* parameters with argument types *) |
|
1113 |
|
1114 val cparams' = map (cterm_of sign o inst_term Tenv' o term_of) cassumed; |
|
1115 val cdefined' = map (cert o inst_term Tenv' o term_of) cdefined; |
|
1116 val cdefining = map (cert o inst_term Tenv' o snd) env; |
|
1117 |
|
1118 fun inst_thm _ [] th = th |
|
1119 | inst_thm ctxt Tenv th = |
|
1120 let |
|
1121 val sign = ProofContext.sign_of ctxt; |
|
1122 val cert = Thm.cterm_of sign; |
|
1123 val certT = Thm.ctyp_of sign; |
|
1124 val {hyps, prop, maxidx, ...} = Thm.rep_thm th; |
|
1125 val tfrees = foldr Term.add_term_tfree_names (prop :: hyps, []); |
|
1126 val Tenv' = filter (fn ((a, _), _) => a mem_string tfrees) Tenv; |
|
1127 in |
|
1128 if null Tenv' then th |
|
1129 else |
|
1130 th |
|
1131 |> Drule.implies_intr_list (map cert hyps) |
|
1132 |> Drule.tvars_intr_list (map (#1 o #1) Tenv') |
|
1133 |> (fn (th', al) => th' |> |
|
1134 Thm.instantiate ((map (fn ((a, _), T) => |
|
1135 (the (assoc (al, a)), certT T)) Tenv'), [])) |
|
1136 |> (fn th'' => Drule.implies_elim_list th'' |
|
1137 (map (Thm.assume o cert o inst_term Tenv') hyps)) |
|
1138 end; |
|
1139 |
|
1140 fun inst_thm' thm = |
|
1141 let |
|
1142 (* not all axs are normally applicable *) |
|
1143 val hyps = #hyps (rep_thm thm); |
|
1144 val ass = map (fn ax => (prop_of ax, ax)) axioms; |
|
1145 val axs' = foldl (fn (axs, hyp) => |
|
1146 (case assoc (ass, hyp) of None => axs |
|
1147 | Some ax => axs @ [ax])) ([], hyps); |
|
1148 val thm' = Drule.satisfy_hyps axs' thm; |
|
1149 (* instantiate types *) |
|
1150 val thm'' = inst_thm ctxt Tenv' thm'; |
|
1151 (* substitute arguments and discharge hypotheses *) |
|
1152 val thm''' = case inst of |
|
1153 None => thm'' |
|
1154 | Some inst_thm => let |
|
1155 val hyps = #hyps (rep_thm thm''); |
|
1156 val th = thm'' |> implies_intr_hyps |
|
1157 |> forall_intr_list (cparams' @ cdefined') |
|
1158 |> forall_elim_list (cargs @ cdefining) |
|
1159 (* th has premises of the form either inst_thm or x==x *) |
|
1160 fun mk hyp = if Logic.is_equals hyp |
|
1161 then hyp |> Logic.dest_equals |> snd |> cert |
|
1162 |> reflexive |
|
1163 else inst_thm |
|
1164 in implies_elim_list th (map mk hyps) |
|
1165 end; |
|
1166 in thm''' end; |
|
1167 |
|
1168 fun inst_elem (ctxt, (Ext _)) = ctxt |
|
1169 | inst_elem (ctxt, (Int (Notes facts))) = |
|
1170 (* instantiate fact *) |
|
1171 let val facts' = |
|
1172 map (apsnd (map (apfst (map inst_thm')))) facts |
|
1173 (* rename fact *) |
|
1174 val facts'' = |
|
1175 map (apfst (apfst (fn "" => "" |
|
1176 | s => NameSpace.append prfx s))) |
|
1177 facts' |
|
1178 in fst (ProofContext.have_thmss_i facts'' ctxt) |
|
1179 end |
|
1180 | inst_elem (ctxt, (Int _)) = ctxt; |
|
1181 |
|
1182 fun inst_elems (ctxt, (id, elems)) = foldl inst_elem (ctxt, elems); |
|
1183 |
|
1184 fun inst_elemss ctxt elemss = foldl inst_elems (ctxt, elemss); |
|
1185 |
|
1186 (* main part *) |
|
1187 |
|
1188 val ctxt' = ProofContext.qualified true ctxt; |
|
1189 in ProofContext.restore_qualified ctxt (inst_elemss ctxt' all_elemss) |
|
1190 end; |
961 |
1191 |
962 |
1192 |
963 (** define locales **) |
1193 (** define locales **) |
964 |
1194 |
965 (* print locale *) |
1195 (* print locale *) |
1048 |
1279 |
1049 in |
1280 in |
1050 |
1281 |
1051 val have_thmss = gen_have_thmss intern ProofContext.get_thms; |
1282 val have_thmss = gen_have_thmss intern ProofContext.get_thms; |
1052 val have_thmss_i = gen_have_thmss (K I) (K I); |
1283 val have_thmss_i = gen_have_thmss (K I) (K I); |
|
1284 (* CB: have_thmss(_i) is the base for the Isar commands |
|
1285 "theorems (in loc)" and "declare (in loc)". *) |
1053 |
1286 |
1054 fun add_thmss loc args (thy, ctxt) = |
1287 fun add_thmss loc args (thy, ctxt) = |
1055 let |
1288 let |
1056 val args' = map (fn ((a, ths), atts) => ((a, atts), [(ths, [])])) args; |
1289 val args' = map (fn ((a, ths), atts) => ((a, atts), [(ths, [])])) args; |
1057 val thy' = put_facts loc args' thy; |
1290 val thy' = put_facts loc args' thy; |
1058 val {view = (_, view_axioms), ...} = the_locale thy loc; |
1291 val {view = (_, view_axioms), ...} = the_locale thy loc; |
1059 val ((ctxt', _), (_, facts')) = |
1292 val ((ctxt', _), (_, facts')) = |
1060 activate_facts (K I) ((ctxt, view_axioms), [(("", []), [Notes args'])]); |
1293 activate_facts (K I) ((ctxt, view_axioms), [(("", []), [Notes args'])]); |
1061 in ((thy', ctxt'), facts') end; |
1294 in ((thy', ctxt'), facts') end; |
|
1295 (* CB: only used in Proof.finish_global. *) |
1062 |
1296 |
1063 end; |
1297 end; |
1064 |
1298 |
1065 |
1299 |
1066 (* predicate text *) |
1300 (* predicate text *) |