src/Pure/Isar/locale.ML
changeset 14528 1457584110ac
parent 14508 859b11514537
child 14564 3667b4616e9a
equal deleted inserted replaced
14527:bc9e5587d05a 14528:1457584110ac
    63     ((bstring * context attribute list) * (thm list * context attribute list) list) list ->
    63     ((bstring * context attribute list) * (thm list * context attribute list) list) list ->
    64     theory -> theory * (bstring * thm list) list
    64     theory -> theory * (bstring * thm list) list
    65   val add_thmss: string -> ((string * thm list) * context attribute list) list ->
    65   val add_thmss: string -> ((string * thm list) * context attribute list) list ->
    66     theory * context -> (theory * context) * (string * thm list) list
    66     theory * context -> (theory * context) * (string * thm list) list
    67   val prune_prems: theory -> thm -> thm
    67   val prune_prems: theory -> thm -> thm
    68   val instantiate: string -> string -> thm list option -> context -> context
    68   val instantiate: string -> string * context attribute list
       
    69     -> thm list option -> context -> context
    69   val setup: (theory -> theory) list
    70   val setup: (theory -> theory) list
    70 end;
    71 end;
    71 
    72 
    72 structure Locale: LOCALE =
    73 structure Locale: LOCALE =
    73 struct
    74 struct
  1038 end;
  1039 end;
  1039 
  1040 
  1040 
  1041 
  1041 (** CB: experimental instantiation mechanism **)
  1042 (** CB: experimental instantiation mechanism **)
  1042 
  1043 
  1043 fun instantiate loc_name prfx raw_inst ctxt =
  1044 fun instantiate loc_name (prfx, attribs) raw_inst ctxt =
  1044   let
  1045   let
  1045     val thy = ProofContext.theory_of ctxt;
  1046     val thy = ProofContext.theory_of ctxt;
  1046     val sign = Theory.sign_of thy;
  1047     val sign = Theory.sign_of thy;
  1047     val tsig = Sign.tsig_of sign;
  1048     val tsig = Sign.tsig_of sign;
  1048     val cert = cterm_of sign;
  1049     val cert = cterm_of sign;
  1050     (** process the locale **)
  1051     (** process the locale **)
  1051 
  1052 
  1052     val {view = (_, axioms), params = (ps, _), ...} =
  1053     val {view = (_, axioms), params = (ps, _), ...} =
  1053       the_locale thy (intern sign loc_name);
  1054       the_locale thy (intern sign loc_name);
  1054     val fixed_params = param_types ps;
  1055     val fixed_params = param_types ps;
       
  1056     val init = ProofContext.init thy;
  1055     val (ids, raw_elemss) =
  1057     val (ids, raw_elemss) =
  1056           flatten (ctxt, intern_expr sign) ([], Expr (Locale loc_name));
  1058           flatten (init, intern_expr sign) ([], Expr (Locale loc_name));
  1057     val ((parms, all_elemss, concl),
  1059     val ((parms, all_elemss, concl),
  1058          (spec as (_, (ints, _)), (xs, env, defs))) =
  1060          (spec as (_, (ints, _)), (xs, env, defs))) =
  1059       read_elemss false (* do_close *) ctxt
  1061       read_elemss false (* do_close *) init
  1060         fixed_params (* could also put [] here??? *) raw_elemss
  1062         fixed_params (* could also put [] here??? *) raw_elemss
  1061         [] (* concl *);
  1063         [] (* concl *);
  1062 
  1064 
  1063     (** analyse the instantiation theorem inst **)
  1065     (** analyse the instantiation theorem inst **)
  1064 
  1066 
  1075       | Some _ => error "Multiple facts are not allowed";
  1077       | Some _ => error "Multiple facts are not allowed";
  1076 
  1078 
  1077     val args = case inst of
  1079     val args = case inst of
  1078             None => []
  1080             None => []
  1079           | Some thm => thm |> prop_of |> ObjectLogic.drop_judgment sign
  1081           | Some thm => thm |> prop_of |> ObjectLogic.drop_judgment sign
  1080               |> Term.strip_comb |> snd;
  1082               |> Term.strip_comb
       
  1083               |>> (fn t as (Const (s, _)) => if (intern sign loc_name = s)
       
  1084                         then t
       
  1085                         else error ("Constant " ^ quote loc_name ^
       
  1086                           " expected but constant " ^ quote s ^ " was found")
       
  1087                     | t => error ("Constant " ^ quote loc_name ^ " expected \
       
  1088                           \but term " ^ quote (Sign.string_of_term sign t) ^
       
  1089                           " was found"))
       
  1090               |> snd;
  1081     val cargs = map cert args;
  1091     val cargs = map cert args;
  1082 
  1092 
  1083     (* process parameters: match their types with those of arguments *)
  1093     (* process parameters: match their types with those of arguments *)
  1084 
  1094 
  1085     val def_names = map (fn (Free (s, _), _) => s) env;
  1095     val def_names = map (fn (Free (s, _), _) => s) env;
  1091     val param_types = map snd assumed;
  1101     val param_types = map snd assumed;
  1092     val v_param_types = map Type.varifyT param_types;
  1102     val v_param_types = map Type.varifyT param_types;
  1093     val arg_types = map Term.fastype_of args;
  1103     val arg_types = map Term.fastype_of args;
  1094     val Tenv = foldl (Type.typ_match tsig)
  1104     val Tenv = foldl (Type.typ_match tsig)
  1095           (Vartab.empty, v_param_types ~~ arg_types)
  1105           (Vartab.empty, v_param_types ~~ arg_types)
  1096           handle Library.LIST "~~" => error "Number of parameters does not match number of arguments of chained fact";
  1106           handle Library.LIST "~~" => error "Number of parameters does not \
       
  1107             \match number of arguments of chained fact";
  1097     (* get their sorts *)
  1108     (* get their sorts *)
  1098     val tfrees = foldr Term.add_typ_tfrees (param_types, []);
  1109     val tfrees = foldr Term.add_typ_tfrees (param_types, []);
  1099     val Tenv' = map
  1110     val Tenv' = map
  1100           (fn ((a, i), T) => ((a, the (assoc_string (tfrees, a))), T))
  1111           (fn ((a, i), T) => ((a, the (assoc_string (tfrees, a))), T))
  1101           (Vartab.dest Tenv);
  1112           (Vartab.dest Tenv);
  1141       let
  1152       let
  1142         (* not all axs are normally applicable *)
  1153         (* not all axs are normally applicable *)
  1143         val hyps = #hyps (rep_thm thm);
  1154         val hyps = #hyps (rep_thm thm);
  1144         val ass = map (fn ax => (prop_of ax, ax)) axioms;
  1155         val ass = map (fn ax => (prop_of ax, ax)) axioms;
  1145         val axs' = foldl (fn (axs, hyp) => 
  1156         val axs' = foldl (fn (axs, hyp) => 
  1146               (case assoc (ass, hyp) of None => axs
  1157               (case gen_assoc (op aconv) (ass, hyp) of None => axs
  1147                  | Some ax => axs @ [ax])) ([], hyps);
  1158                  | Some ax => axs @ [ax])) ([], hyps);
  1148         val thm' = Drule.satisfy_hyps axs' thm;
  1159         val thm' = Drule.satisfy_hyps axs' thm;
  1149         (* instantiate types *)
  1160         (* instantiate types *)
  1150         val thm'' = inst_thm ctxt Tenv' thm';
  1161         val thm'' = inst_thm ctxt Tenv' thm';
  1151         (* substitute arguments and discharge hypotheses *)
  1162         (* substitute arguments and discharge hypotheses *)
  1163 			  else inst_thm
  1174 			  else inst_thm
  1164                   in implies_elim_list th (map mk hyps)
  1175                   in implies_elim_list th (map mk hyps)
  1165                   end;
  1176                   end;
  1166       in thm''' end;
  1177       in thm''' end;
  1167 
  1178 
       
  1179     val prefix_fact =
       
  1180       if prfx = "" then I
       
  1181       else (fn "" => ""
       
  1182              | s => NameSpace.append prfx s);
       
  1183 
  1168     fun inst_elem (ctxt, (Ext _)) = ctxt
  1184     fun inst_elem (ctxt, (Ext _)) = ctxt
  1169       | inst_elem (ctxt, (Int (Notes facts))) =
  1185       | inst_elem (ctxt, (Int (Notes facts))) =
  1170               (* instantiate fact *)
  1186               (* instantiate fact *)
  1171           let val facts' =
  1187           let val facts' =
  1172               map (apsnd (map (apfst (map inst_thm')))) facts
  1188                 map (apsnd (map (apfst (map inst_thm')))) facts
       
  1189 		handle THM (msg, n, thms) => error ("Exception THM " ^
       
  1190 		  string_of_int n ^ " raised\n" ^
       
  1191 		  "Note: instantiate does not support old-style locales \
       
  1192                   \declared with (open)\n" ^ msg ^ "\n" ^
       
  1193 		  cat_lines (map string_of_thm thms))
  1173               (* rename fact *)
  1194               (* rename fact *)
  1174               val facts'' =
  1195               val facts'' = map (apfst (apfst prefix_fact)) facts'
  1175               map (apfst (apfst (fn "" => ""
  1196               (* add attributes *)
  1176                                   | s => NameSpace.append prfx s)))
  1197               val facts''' = map (apfst (apsnd (fn atts => atts @ attribs))) facts''
  1177                   facts'
  1198           in fst (ProofContext.have_thmss_i facts''' ctxt)
  1178           in fst (ProofContext.have_thmss_i facts'' ctxt)
       
  1179           end
  1199           end
  1180       | inst_elem (ctxt, (Int _)) = ctxt;
  1200       | inst_elem (ctxt, (Int _)) = ctxt;
  1181 
  1201 
  1182     fun inst_elems (ctxt, (id, elems)) = foldl inst_elem (ctxt, elems);
  1202     fun inst_elems (ctxt, (id, elems)) = foldl inst_elem (ctxt, elems);
  1183 
  1203 
  1410 (* add_locale(_i) *)
  1430 (* add_locale(_i) *)
  1411 
  1431 
  1412 local
  1432 local
  1413 
  1433 
  1414 fun gen_add_locale prep_ctxt prep_expr do_pred bname raw_import raw_body thy =
  1434 fun gen_add_locale prep_ctxt prep_expr do_pred bname raw_import raw_body thy =
       
  1435   (* CB: do_pred = false means old-style locale, declared with (open).
       
  1436      Old-style locales don't define predicates. *)
  1415   let
  1437   let
  1416     val sign = Theory.sign_of thy;
  1438     val sign = Theory.sign_of thy;
  1417     val name = Sign.full_name sign bname;
  1439     val name = Sign.full_name sign bname;
  1418     val _ = conditional (is_some (get_locale thy name)) (fn () =>
  1440     val _ = conditional (is_some (get_locale thy name)) (fn () =>
  1419       error ("Duplicate definition of locale " ^ quote name));
  1441       error ("Duplicate definition of locale " ^ quote name));