src/Pure/Isar/locale.ML
changeset 16169 b59202511b8a
parent 16144 e339119f4261
child 16325 a6431098a929
equal deleted inserted replaced
16168:adb83939177f 16169:b59202511b8a
    16 [1] Clemens Ballarin. Locales and Locale Expressions in Isabelle/Isar.
    16 [1] Clemens Ballarin. Locales and Locale Expressions in Isabelle/Isar.
    17     In Stefano Berardi et al., Types for Proofs and Programs: International
    17     In Stefano Berardi et al., Types for Proofs and Programs: International
    18     Workshop, TYPES 2003, Torino, Italy, LNCS 3085, pages 34-50, 2004.
    18     Workshop, TYPES 2003, Torino, Italy, LNCS 3085, pages 34-50, 2004.
    19 *)
    19 *)
    20 
    20 
       
    21 (* TODO:
       
    22 - beta-eta normalisation of interpretation parameters
       
    23 - no beta reduction of interpretation witnesses
       
    24 - mix of locales with and without open in activate_elems
       
    25 - dangling type frees in locales
       
    26 *)
       
    27 
    21 signature LOCALE =
    28 signature LOCALE =
    22 sig
    29 sig
    23   type context
    30   type context
    24   datatype ('typ, 'term, 'fact) elem =
    31   datatype ('typ, 'term, 'fact) elem =
    25     Fixes of (string * 'typ option * mixfix option) list |
    32     Fixes of (string * 'typ option * mixfix option) list |
       
    33     Constrains of (string * 'typ) list |
    26     Assumes of ((string * Attrib.src list) * ('term * ('term list * 'term list)) list) list |
    34     Assumes of ((string * Attrib.src list) * ('term * ('term list * 'term list)) list) list |
    27     Defines of ((string * Attrib.src list) * ('term * 'term list)) list |
    35     Defines of ((string * Attrib.src list) * ('term * 'term list)) list |
    28     Notes of ((string * Attrib.src list) * ('fact * Attrib.src list) list) list
    36     Notes of ((string * Attrib.src list) * ('fact * Attrib.src list) list) list
    29   datatype expr =
    37   datatype expr =
    30     Locale of string |
    38     Locale of string |
    76     theory -> theory * (bstring * thm list) list
    84     theory -> theory * (bstring * thm list) list
    77   val add_thmss: string -> string -> ((string * thm list) * Attrib.src list) list ->
    85   val add_thmss: string -> string -> ((string * thm list) * Attrib.src list) list ->
    78     theory * context -> (theory * context) * (string * thm list) list
    86     theory * context -> (theory * context) * (string * thm list) list
    79 
    87 
    80   (* Locale interpretation *)
    88   (* Locale interpretation *)
    81   val instantiate: string -> string * context attribute list
       
    82     -> thm list option -> context -> context
       
    83   val prep_global_registration:
    89   val prep_global_registration:
    84     string * Attrib.src list -> expr -> string option list -> theory ->
    90     string * Attrib.src list -> expr -> string option list -> theory ->
    85     theory * ((string * term list) * term list) list * (theory -> theory)
    91     theory * ((string * term list) * term list) list * (theory -> theory)
    86   val prep_local_registration:
    92   val prep_local_registration:
    87     string * Attrib.src list -> expr -> string option list -> context ->
    93     string * Attrib.src list -> expr -> string option list -> context ->
    99 
   105 
   100 type context = ProofContext.context;
   106 type context = ProofContext.context;
   101 
   107 
   102 datatype ('typ, 'term, 'fact) elem =
   108 datatype ('typ, 'term, 'fact) elem =
   103   Fixes of (string * 'typ option * mixfix option) list |
   109   Fixes of (string * 'typ option * mixfix option) list |
       
   110   Constrains of (string * 'typ) list |
   104   Assumes of ((string * Attrib.src list) * ('term * ('term list * 'term list)) list) list |
   111   Assumes of ((string * Attrib.src list) * ('term * ('term list * 'term list)) list) list |
   105   Defines of ((string * Attrib.src list) * ('term * 'term list)) list |
   112   Defines of ((string * Attrib.src list) * ('term * 'term list)) list |
   106   Notes of ((string * Attrib.src list) * ('fact * Attrib.src list) list) list;
   113   Notes of ((string * Attrib.src list) * ('fact * Attrib.src list) list) list;
   107 
   114 
   108 datatype expr =
   115 datatype expr =
   301               in (Termtab.update ((t, (attn, [])), regs), sups') end
   308               in (Termtab.update ((t, (attn, [])), regs), sups') end
   302       | _ => (regs, []))
   309       | _ => (regs, []))
   303     end;
   310     end;
   304 
   311 
   305   (* add witness theorem to registration,
   312   (* add witness theorem to registration,
   306      only if instantiation is exact, otherwise excpetion Option raised *)
   313      only if instantiation is exact, otherwise exception Option raised *)
   307   fun add_witness ts thm regs =
   314   fun add_witness ts thm regs =
   308     let
   315     let
   309       val t = termify ts;
   316       val t = termify ts;
   310       val (x, thms) = valOf (Termtab.lookup (regs, t));
   317       val (x, thms) = valOf (Termtab.lookup (regs, t));
   311     in
   318     in
   561 (* map elements *)
   568 (* map elements *)
   562 
   569 
   563 fun map_elem {name, var, typ, term, fact, attrib} =
   570 fun map_elem {name, var, typ, term, fact, attrib} =
   564   fn Fixes fixes => Fixes (fixes |> map (fn (x, T, mx) =>
   571   fn Fixes fixes => Fixes (fixes |> map (fn (x, T, mx) =>
   565        let val (x', mx') = var (x, mx) in (x', Option.map typ T, mx') end))
   572        let val (x', mx') = var (x, mx) in (x', Option.map typ T, mx') end))
       
   573    | Constrains csts => Constrains (csts |> map (fn (x, T) =>
       
   574        let val (x', _) = var (x, SOME Syntax.NoSyn) in (x', typ T) end))
   566    | Assumes asms => Assumes (asms |> map (fn ((a, atts), propps) =>
   575    | Assumes asms => Assumes (asms |> map (fn ((a, atts), propps) =>
   567       ((name a, map attrib atts), propps |> map (fn (t, (ps, qs)) =>
   576       ((name a, map attrib atts), propps |> map (fn (t, (ps, qs)) =>
   568         (term t, (map term ps, map term qs))))))
   577         (term t, (map term ps, map term qs))))))
   569    | Defines defs => Defines (defs |> map (fn ((a, atts), (t, ps)) =>
   578    | Defines defs => Defines (defs |> map (fn ((a, atts), (t, ps)) =>
   570       ((name a, map attrib atts), (term t, map term ps))))
   579       ((name a, map attrib atts), (term t, map term ps))))
   968      (* CB: turn remaining hyps into assumptions. *)
   977      (* CB: turn remaining hyps into assumptions. *)
   969   |> Seq.single
   978   |> Seq.single
   970 
   979 
   971 fun activate_elem _ ((ctxt, axs), Fixes fixes) =
   980 fun activate_elem _ ((ctxt, axs), Fixes fixes) =
   972       ((ctxt |> ProofContext.add_fixes fixes, axs), [])
   981       ((ctxt |> ProofContext.add_fixes fixes, axs), [])
       
   982   | activate_elem _ ((ctxt, axs), Constrains _) = ((ctxt, axs), [])
   973   | activate_elem _ ((ctxt, axs), Assumes asms) =
   983   | activate_elem _ ((ctxt, axs), Assumes asms) =
   974       let
   984       let
   975         val asms' = map_attrib_specs (Attrib.context_attribute_i ctxt) asms;
   985         val asms' = map_attrib_specs (Attrib.context_attribute_i ctxt) asms;
   976         val ts = List.concat (map (map #1 o #2) asms');
   986         val ts = List.concat (map (map #1 o #2) asms');
   977         val (ps, qs) = splitAt (length ts, axs);
   987         val (ps, qs) = splitAt (length ts, axs);
  1064 
  1074 
  1065 (* parameters *)
  1075 (* parameters *)
  1066 
  1076 
  1067 local
  1077 local
  1068 
  1078 
  1069 fun prep_fixes prep_vars ctxt fixes =
  1079 fun prep_parms prep_vars ctxt parms =
  1070   let val vars = snd (foldl_map prep_vars (ctxt, map (fn (x, T, _) => ([x], T)) fixes))
  1080   let val vars = snd (foldl_map prep_vars (ctxt, map (fn (x, T) => ([x], T)) parms))
  1071   in map (fn (([x'], T'), (_, _, mx)) => (x', T', mx)) (vars ~~ fixes) end;
  1081   in map (fn ([x'], T') => (x', T')) vars end;
  1072 
  1082 
  1073 in
  1083 in
  1074 
  1084 
  1075 fun read_fixes x = prep_fixes ProofContext.read_vars x;
  1085 fun read_parms x = prep_parms ProofContext.read_vars x;
  1076 fun cert_fixes x = prep_fixes ProofContext.cert_vars x;
  1086 fun cert_parms x = prep_parms ProofContext.cert_vars x;
  1077 
  1087 
  1078 end;
  1088 end;
  1079 
  1089 
  1080 
  1090 
  1081 (* propositions and bindings *)
  1091 (* propositions and bindings *)
  1122 fun declare_int_elem (ctxt, Fixes fixes) =
  1132 fun declare_int_elem (ctxt, Fixes fixes) =
  1123       (ctxt |> ProofContext.add_fixes (map (fn (x, T, mx) =>
  1133       (ctxt |> ProofContext.add_fixes (map (fn (x, T, mx) =>
  1124         (x, Option.map (Term.map_type_tfree (TypeInfer.param 0)) T, mx)) fixes), [])
  1134         (x, Option.map (Term.map_type_tfree (TypeInfer.param 0)) T, mx)) fixes), [])
  1125   | declare_int_elem (ctxt, _) = (ctxt, []);
  1135   | declare_int_elem (ctxt, _) = (ctxt, []);
  1126 
  1136 
  1127 fun declare_ext_elem prep_fixes (ctxt, Fixes fixes) =
  1137 fun declare_ext_elem prep_parms (ctxt, Fixes fixes) =
  1128       (ctxt |> ProofContext.add_fixes (prep_fixes ctxt fixes), [])
  1138       let
       
  1139         val parms = map (fn (x, T, _) => (x, T)) fixes;
       
  1140         val parms' = prep_parms ctxt parms;
       
  1141         val fixes' = map (fn ((x, T), (_, _, mx)) => (x, T, mx)) (parms' ~~ fixes);
       
  1142       in (ctxt |> ProofContext.add_fixes fixes', []) end
       
  1143   | declare_ext_elem prep_parms (ctxt, Constrains csts) =
       
  1144       let
       
  1145         val parms = map (fn (x, T) => (x, SOME T)) csts;
       
  1146         val parms' = prep_parms ctxt parms;
       
  1147         val ts = map (fn (x, SOME T) => Free (x, T)) parms';
       
  1148       in (Library.fold ProofContext.declare_term ts ctxt, []) end
  1129   | declare_ext_elem _ (ctxt, Assumes asms) = (ctxt, map #2 asms)
  1149   | declare_ext_elem _ (ctxt, Assumes asms) = (ctxt, map #2 asms)
  1130   | declare_ext_elem _ (ctxt, Defines defs) = (ctxt, map (fn (_, (t, ps)) => [(t, (ps, []))]) defs)
  1150   | declare_ext_elem _ (ctxt, Defines defs) = (ctxt, map (fn (_, (t, ps)) => [(t, (ps, []))]) defs)
  1131   | declare_ext_elem _ (ctxt, Notes facts) = (ctxt, []);
  1151   | declare_ext_elem _ (ctxt, Notes facts) = (ctxt, []);
  1132 
  1152 
  1133 fun declare_elems prep_fixes (ctxt, (((name, ps), _), elems)) =
  1153 fun declare_elems prep_parms (ctxt, (((name, ps), _), elems)) =
  1134   let val (ctxt', propps) =
  1154   let val (ctxt', propps) =
  1135     (case elems of
  1155     (case elems of
  1136       Int es => foldl_map declare_int_elem (ctxt, es)
  1156       Int es => foldl_map declare_int_elem (ctxt, es)
  1137     | Ext e => foldl_map (declare_ext_elem prep_fixes) (ctxt, [e]))
  1157     | Ext e => foldl_map (declare_ext_elem prep_parms) (ctxt, [e]))
  1138     handle ProofContext.CONTEXT (msg, ctxt) => err_in_locale ctxt msg [(name, map fst ps)]
  1158     handle ProofContext.CONTEXT (msg, ctxt) => err_in_locale ctxt msg [(name, map fst ps)]
  1139   in (ctxt', propps) end;
  1159   in (ctxt', propps) end;
  1140 
  1160 
  1141 in
  1161 in
  1142 
  1162 
  1143 (* CB: only called by prep_elemss. *)
  1163 (* CB: only called by prep_elemss. *)
  1144 
  1164 
  1145 fun declare_elemss prep_fixes fixed_params raw_elemss ctxt =
  1165 fun declare_elemss prep_parms fixed_params raw_elemss ctxt =
  1146   let
  1166   let
  1147     (* CB: fix of type bug of goal in target with context elements.
  1167     (* CB: fix of type bug of goal in target with context elements.
  1148        Parameters new in context elements must receive types that are
  1168        Parameters new in context elements must receive types that are
  1149        distinct from types of parameters in target (fixed_params).  *)
  1169        distinct from types of parameters in target (fixed_params).  *)
  1150     val ctxt_with_fixed =
  1170     val ctxt_with_fixed =
  1154       |> List.mapPartial (fn (id, Int es) => SOME (id, es) | _ => NONE)
  1174       |> List.mapPartial (fn (id, Int es) => SOME (id, es) | _ => NONE)
  1155       |> unify_elemss ctxt_with_fixed fixed_params;
  1175       |> unify_elemss ctxt_with_fixed fixed_params;
  1156     val (_, raw_elemss') =
  1176     val (_, raw_elemss') =
  1157       foldl_map (fn ((_, es) :: elemss, (id, Int _)) => (elemss, (id, Int es)) | x => x)
  1177       foldl_map (fn ((_, es) :: elemss, (id, Int _)) => (elemss, (id, Int es)) | x => x)
  1158         (int_elemss, raw_elemss);
  1178         (int_elemss, raw_elemss);
  1159   in foldl_map (declare_elems prep_fixes) (ctxt, raw_elemss') end;
  1179   in foldl_map (declare_elems prep_parms) (ctxt, raw_elemss') end;
  1160 
  1180 
  1161 end;
  1181 end;
  1162 
  1182 
  1163 local
  1183 local
  1164 
  1184 
  1196   end;
  1216   end;
  1197 
  1217 
  1198 (* CB: for finish_elems (Int and Ext) *)
  1218 (* CB: for finish_elems (Int and Ext) *)
  1199 
  1219 
  1200 fun eval_text _ _ _ (text, Fixes _) = text
  1220 fun eval_text _ _ _ (text, Fixes _) = text
       
  1221   | eval_text _ _ _ (text, Constrains _) = text
  1201   | eval_text _ _ is_ext ((((exts, exts'), (ints, ints')), (xs, env, defs)), Assumes asms) =
  1222   | eval_text _ _ is_ext ((((exts, exts'), (ints, ints')), (xs, env, defs)), Assumes asms) =
  1202       let
  1223       let
  1203         val ts = List.concat (map (map #1 o #2) asms);
  1224         val ts = List.concat (map (map #1 o #2) asms);
  1204         val ts' = map (norm_term env) ts;
  1225         val ts' = map (norm_term env) ts;
  1205         val spec' =
  1226         val spec' =
  1233       end;
  1254       end;
  1234 
  1255 
  1235 
  1256 
  1236 fun finish_ext_elem parms _ (Fixes fixes, _) = Fixes (map (fn (x, _, mx) =>
  1257 fun finish_ext_elem parms _ (Fixes fixes, _) = Fixes (map (fn (x, _, mx) =>
  1237       (x, assoc_string (parms, x), mx)) fixes)
  1258       (x, assoc_string (parms, x), mx)) fixes)
       
  1259   | finish_ext_elem parms _ (Constrains csts, _) =
       
  1260       Constrains (map (fn (x, _) => (x, valOf (assoc_string (parms, x)))) csts)
  1238   | finish_ext_elem _ close (Assumes asms, propp) =
  1261   | finish_ext_elem _ close (Assumes asms, propp) =
  1239       close (Assumes (map #1 asms ~~ propp))
  1262       close (Assumes (map #1 asms ~~ propp))
  1240   | finish_ext_elem _ close (Defines defs, propp) =
  1263   | finish_ext_elem _ close (Defines defs, propp) =
  1241       close (Defines (map #1 defs ~~ map (fn [(t, (ps, []))] => (t, ps)) propp))
  1264       close (Defines (map #1 defs ~~ map (fn [(t, (ps, []))] => (t, ps)) propp))
  1242   | finish_ext_elem _ _ (Notes facts, _) = Notes facts;
  1265   | finish_ext_elem _ _ (Notes facts, _) = Notes facts;
  1268 
  1291 
  1269 end;
  1292 end;
  1270 
  1293 
  1271 (* CB: type inference and consistency checks for locales *)
  1294 (* CB: type inference and consistency checks for locales *)
  1272 
  1295 
  1273 fun prep_elemss prep_fixes prepp do_close context fixed_params raw_elemss raw_concl =
  1296 fun prep_elemss prep_parms prepp do_close context fixed_params raw_elemss raw_concl =
  1274   let
  1297   let
  1275     (* CB: contexts computed in the course of this function are discarded.
  1298     (* CB: contexts computed in the course of this function are discarded.
  1276        They are used for type inference and consistency checks only. *)
  1299        They are used for type inference and consistency checks only. *)
  1277     (* CB: fixed_params are the parameters (with types) of the target locale,
  1300     (* CB: fixed_params are the parameters (with types) of the target locale,
  1278        empty list if there is no target. *)
  1301        empty list if there is no target. *)
  1279     (* CB: raw_elemss are list of pairs consisting of identifiers and
  1302     (* CB: raw_elemss are list of pairs consisting of identifiers and
  1280        context elements, the latter marked as internal or external. *)
  1303        context elements, the latter marked as internal or external. *)
  1281     val (raw_ctxt, raw_proppss) = declare_elemss prep_fixes fixed_params raw_elemss context;
  1304     val (raw_ctxt, raw_proppss) = declare_elemss prep_parms fixed_params raw_elemss context;
  1282     (* CB: raw_ctxt is context with additional fixed variables derived from
  1305     (* CB: raw_ctxt is context with additional fixed variables derived from
  1283        the fixes elements in raw_elemss,
  1306        the fixes elements in raw_elemss,
  1284        raw_proppss contains assumptions and definitions from the
  1307        raw_proppss contains assumptions and definitions from the
  1285        external elements in raw_elemss. *)
  1308        external elements in raw_elemss. *)
  1286     val raw_propps = map List.concat raw_proppss;
  1309     val raw_propps = map List.concat raw_proppss;
  1309       (map (ProofContext.default_type ctxt) xs);
  1332       (map (ProofContext.default_type ctxt) xs);
  1310     val parms = param_types (xs ~~ typing);
  1333     val parms = param_types (xs ~~ typing);
  1311     (* CB: parms are the parameters from raw_elemss, with correct typing. *)
  1334     (* CB: parms are the parameters from raw_elemss, with correct typing. *)
  1312 
  1335 
  1313     (* CB: extract information from assumes and defines elements
  1336     (* CB: extract information from assumes and defines elements
  1314        (fixes and notes in raw_elemss don't have an effect on text and elemss),
  1337        (fixes, constrains and notes in raw_elemss don't have an effect on
  1315        compute final form of context elements. *)
  1338        text and elemss), compute final form of context elements. *)
  1316     val (text, elemss) = finish_elemss ctxt parms do_close
  1339     val (text, elemss) = finish_elemss ctxt parms do_close
  1317       (((([], []), ([], [])), ([], [], [])), raw_elemss ~~ proppss);
  1340       (((([], []), ([], [])), ([], [], [])), raw_elemss ~~ proppss);
  1318     (* CB: text has the following structure:
  1341     (* CB: text has the following structure:
  1319            (((exts, exts'), (ints, ints')), (xs, env, defs))
  1342            (((exts, exts'), (ints, ints')), (xs, env, defs))
  1320        where
  1343        where
  1328            is a free variable; substitutions represent defines elements and
  1351            is a free variable; substitutions represent defines elements and
  1329            the rhs is normalised wrt. the previous env
  1352            the rhs is normalised wrt. the previous env
  1330          defs: theorems representing the substitutions from defines elements
  1353          defs: theorems representing the substitutions from defines elements
  1331            (thms are normalised wrt. env).
  1354            (thms are normalised wrt. env).
  1332        elemss is an updated version of raw_elemss:
  1355        elemss is an updated version of raw_elemss:
  1333          - type info added to Fixes
  1356          - type info added to Fixes and modified in Constrains
  1334          - axiom and definition statement replaced by corresponding one
  1357          - axiom and definition statement replaced by corresponding one
  1335            from proppss in Assumes and Defines
  1358            from proppss in Assumes and Defines
  1336          - Facts unchanged
  1359          - Facts unchanged
  1337        *)
  1360        *)
  1338   in ((parms, elemss, concl), text) end;
  1361   in ((parms, elemss, concl), text) end;
  1339 
  1362 
  1340 in
  1363 in
  1341 
  1364 
  1342 fun read_elemss x = prep_elemss read_fixes ProofContext.read_propp_schematic x;
  1365 fun read_elemss x = prep_elemss read_parms ProofContext.read_propp_schematic x;
  1343 fun cert_elemss x = prep_elemss cert_fixes ProofContext.cert_propp_schematic x;
  1366 fun cert_elemss x = prep_elemss cert_parms ProofContext.cert_propp_schematic x;
  1344 
  1367 
  1345 end;
  1368 end;
  1346 
  1369 
  1347 
  1370 
  1348 (* facts and attributes *)
  1371 (* facts and attributes *)
  1440 val cert_context_statement = gen_statement (K I) gen_context_i;
  1463 val cert_context_statement = gen_statement (K I) gen_context_i;
  1441 
  1464 
  1442 end;
  1465 end;
  1443 
  1466 
  1444 
  1467 
  1445 (** CB: experimental instantiation mechanism **)
       
  1446 
       
  1447 fun instantiate loc_name (prfx, attribs) raw_inst ctxt =
       
  1448   let
       
  1449     val thy = ProofContext.theory_of ctxt;
       
  1450     val sign = Theory.sign_of thy;
       
  1451     val tsig = Sign.tsig_of sign;
       
  1452     val cert = cterm_of sign;
       
  1453 
       
  1454     (** process the locale **)
       
  1455 
       
  1456     val {predicate = (_, axioms), params = (ps, _), ...} =
       
  1457       the_locale thy (intern sign loc_name);
       
  1458     val fixed_params = param_types (map #1 ps);
       
  1459     val init = ProofContext.init thy;
       
  1460     val (_, raw_elemss) = flatten (init, intern_expr sign)
       
  1461          (([], Symtab.empty), Expr (Locale loc_name));
       
  1462     val ((parms, all_elemss, concl),
       
  1463          (spec as (_, (ints, _)), (xs, env, defs))) =
       
  1464       read_elemss false (* do_close *) init
       
  1465         fixed_params (* could also put [] here??? *) raw_elemss
       
  1466         [] (* concl *);
       
  1467 
       
  1468     (** analyse the instantiation theorem inst **)
       
  1469 
       
  1470     val inst = case raw_inst of
       
  1471         NONE => if null ints
       
  1472 	  then NONE
       
  1473 	  else error "Locale has assumptions but no chained fact was found"
       
  1474       | SOME [] => if null ints
       
  1475 	  then NONE
       
  1476 	  else error "Locale has assumptions but no chained fact was found"
       
  1477       | SOME [thm] => if null ints
       
  1478 	  then (warning "Locale has no assumptions: fact ignored"; NONE)
       
  1479 	  else SOME thm
       
  1480       | SOME _ => error "Multiple facts are not allowed";
       
  1481 
       
  1482     val args = case inst of
       
  1483             NONE => []
       
  1484           | SOME thm => thm |> prop_of |> ObjectLogic.drop_judgment sign
       
  1485               |> Term.strip_comb
       
  1486               |>> (fn t as (Const (s, _)) => if (intern sign loc_name = s)
       
  1487                         then t
       
  1488                         else error ("Constant " ^ quote loc_name ^
       
  1489                           " expected but constant " ^ quote s ^ " was found")
       
  1490                     | t => error ("Constant " ^ quote loc_name ^ " expected \
       
  1491                           \but term " ^ quote (Sign.string_of_term sign t) ^
       
  1492                           " was found"))
       
  1493               |> snd;
       
  1494     val cargs = map cert args;
       
  1495 
       
  1496     (* process parameters: match their types with those of arguments *)
       
  1497 
       
  1498     val def_names = map (fn (Free (s, _), _) => s) env;
       
  1499     val (defined, assumed) = List.partition
       
  1500           (fn (s, _) => s mem def_names) fixed_params;
       
  1501     val cassumed = map (cert o Free) assumed;
       
  1502     val cdefined = map (cert o Free) defined;
       
  1503 
       
  1504     val param_types = map snd assumed;
       
  1505     val v_param_types = map Type.varifyT param_types;
       
  1506     val arg_types = map Term.fastype_of args;
       
  1507     val Tenv = Library.foldl (Type.typ_match tsig)
       
  1508           (Vartab.empty, v_param_types ~~ arg_types)
       
  1509           handle UnequalLengths => error "Number of parameters does not \
       
  1510             \match number of arguments of chained fact";
       
  1511     (* get their sorts *)
       
  1512     val tfrees = foldr Term.add_typ_tfrees [] param_types
       
  1513     val Tenv' = map
       
  1514           (fn ((a, i), (S, T)) => ((a, S), T))
       
  1515           (Vartab.dest Tenv);
       
  1516 
       
  1517     (* process (internal) elements *)
       
  1518 
       
  1519     fun inst_type [] T = T
       
  1520       | inst_type env T =
       
  1521           Term.map_type_tfree (fn v => getOpt (assoc (env, v), TFree v)) T;
       
  1522 
       
  1523     fun inst_term [] t = t
       
  1524       | inst_term env t = Term.map_term_types (inst_type env) t;
       
  1525 
       
  1526     (* parameters with argument types *)
       
  1527 
       
  1528     val cparams' = map (cterm_of sign o inst_term Tenv' o term_of) cassumed;
       
  1529     val cdefined' = map (cert o inst_term Tenv' o term_of) cdefined;
       
  1530     val cdefining = map (cert o inst_term Tenv' o snd) env;
       
  1531 
       
  1532     fun inst_thm _ [] th = th
       
  1533       | inst_thm ctxt Tenv th =
       
  1534 	  let
       
  1535 	    val sign = ProofContext.sign_of ctxt;
       
  1536 	    val cert = Thm.cterm_of sign;
       
  1537 	    val certT = Thm.ctyp_of sign;
       
  1538 	    val {hyps, prop, maxidx, ...} = Thm.rep_thm th;
       
  1539 	    val tfrees = foldr Term.add_term_tfree_names [] (prop :: hyps);
       
  1540 	    val Tenv' = List.filter (fn ((a, _), _) => a mem_string tfrees) Tenv;
       
  1541 	  in
       
  1542 	    if null Tenv' then th
       
  1543 	    else
       
  1544 	      th
       
  1545 	      |> Drule.implies_intr_list (map cert hyps)
       
  1546 	      |> Drule.tvars_intr_list (map (#1 o #1) Tenv')
       
  1547 	      |> (fn (th', al) => th' |>
       
  1548 		Thm.instantiate ((map (fn ((a, _), T) =>
       
  1549                   (certT (TVar (valOf (assoc (al, a)))), certT T)) Tenv'), []))
       
  1550 	      |> (fn th'' => Drule.implies_elim_list th''
       
  1551 		  (map (Thm.assume o cert o inst_term Tenv') hyps))
       
  1552 	  end;
       
  1553 
       
  1554     val inst_type' = inst_type Tenv';
       
  1555 
       
  1556     val inst_term' = Term.subst_atomic
       
  1557         (map (pairself term_of) ((cparams' @ cdefined') ~~ (cargs @ cdefining)))
       
  1558       o inst_term Tenv';
       
  1559 
       
  1560     fun inst_thm' thm =
       
  1561       let
       
  1562         (* not all axs are normally applicable *)
       
  1563         val hyps = #hyps (rep_thm thm);
       
  1564         val ass = map (fn ax => (prop_of ax, ax)) axioms;
       
  1565         val axs' = Library.foldl (fn (axs, hyp) => 
       
  1566               (case gen_assoc (op aconv) (ass, hyp) of NONE => axs
       
  1567                  | SOME ax => axs @ [ax])) ([], hyps);
       
  1568         val thm' = Drule.satisfy_hyps axs' thm;
       
  1569         (* instantiate types *)
       
  1570         val thm'' = inst_thm ctxt Tenv' thm';
       
  1571         (* substitute arguments and discharge hypotheses *)
       
  1572         val thm''' = case inst of
       
  1573                 NONE => thm''
       
  1574               | SOME inst_thm => let
       
  1575 		    val hyps = #hyps (rep_thm thm'');
       
  1576 		    val th = thm'' |> implies_intr_hyps
       
  1577 		      |> forall_intr_list (cparams' @ cdefined')
       
  1578 		      |> forall_elim_list (cargs @ cdefining)
       
  1579 		    (* th has premises of the form either inst_thm or x==x *)
       
  1580 		    fun mk hyp = if Logic.is_equals hyp
       
  1581 			  then hyp |> Logic.dest_equals |> snd |> cert
       
  1582 				 |> reflexive
       
  1583 			  else inst_thm
       
  1584                   in implies_elim_list th (map mk hyps)
       
  1585                   end;
       
  1586       in thm''' end
       
  1587       handle THM (msg, n, thms) => error ("Exception THM " ^
       
  1588         string_of_int n ^ " raised\n" ^
       
  1589 	  "Note: instantiate does not support old-style locales \
       
  1590           \declared with (open)\n" ^ msg ^ "\n" ^
       
  1591 	cat_lines (map string_of_thm thms));
       
  1592 
       
  1593     fun inst_elem (ctxt, (Ext _)) = ctxt
       
  1594       | inst_elem (ctxt, (Int (Notes facts))) =
       
  1595               (* instantiate fact *)
       
  1596           let
       
  1597               val facts = facts |> map_attrib_facts
       
  1598                 (Attrib.context_attribute_i ctxt o
       
  1599                   Args.map_values I inst_type' inst_term' inst_thm');
       
  1600               val facts' =
       
  1601                 map (apsnd (map (apfst (map inst_thm')))) facts
       
  1602               (* rename fact *)
       
  1603               val facts'' = map (apfst (apfst (NameSpace.qualified prfx))) facts'
       
  1604               (* add attributes *)
       
  1605               val facts''' = map (apfst (apsnd (fn atts => atts @ attribs))) facts''
       
  1606           in fst (ProofContext.note_thmss_i facts''' ctxt)
       
  1607           end
       
  1608       | inst_elem (ctxt, (Int _)) = ctxt;
       
  1609 
       
  1610     (* FIXME fold o fold *)
       
  1611     fun inst_elems (ctxt, (id, elems)) = Library.foldl inst_elem (ctxt, elems);
       
  1612 
       
  1613     fun inst_elemss ctxt elemss = Library.foldl inst_elems (ctxt, elemss);
       
  1614 
       
  1615     (* main part *)
       
  1616 
       
  1617     val ctxt' = ProofContext.qualified_names ctxt;
       
  1618   in ProofContext.restore_naming ctxt (inst_elemss ctxt' all_elemss) end;
       
  1619 
       
  1620 
       
  1621 (** define locales **)
  1468 (** define locales **)
  1622 
  1469 
  1623 (* print locale *)
  1470 (* print locale *)
  1624 
  1471 
  1625 fun print_locale thy import body =
  1472 fun print_locale thy import body =
  1637       let val s = (case syn of NONE => "(structure)" | SOME mx => Syntax.string_of_mixfix mx)
  1484       let val s = (case syn of NONE => "(structure)" | SOME mx => Syntax.string_of_mixfix mx)
  1638       in if s = "" then [] else [Pretty.brk 2, Pretty.str s] end;
  1485       in if s = "" then [] else [Pretty.brk 2, Pretty.str s] end;
  1639     fun prt_fix (x, SOME T, syn) = Pretty.block (Pretty.str (x ^ " ::") :: Pretty.brk 1 ::
  1486     fun prt_fix (x, SOME T, syn) = Pretty.block (Pretty.str (x ^ " ::") :: Pretty.brk 1 ::
  1640           prt_typ T :: Pretty.brk 1 :: prt_syn syn)
  1487           prt_typ T :: Pretty.brk 1 :: prt_syn syn)
  1641       | prt_fix (x, NONE, syn) = Pretty.block (Pretty.str x :: Pretty.brk 1 :: prt_syn syn);
  1488       | prt_fix (x, NONE, syn) = Pretty.block (Pretty.str x :: Pretty.brk 1 :: prt_syn syn);
       
  1489     fun prt_cst (x, T) = Pretty.block [Pretty.str (x ^ " ::"), prt_typ T];
  1642 
  1490 
  1643     fun prt_name name = Pretty.str (ProofContext.extern ctxt name);
  1491     fun prt_name name = Pretty.str (ProofContext.extern ctxt name);
  1644     fun prt_name_atts (name, atts) =
  1492     fun prt_name_atts (name, atts) =
  1645       if name = "" andalso null atts then []
  1493       if name = "" andalso null atts then []
  1646       else [Pretty.block (Pretty.breaks (prt_name name :: prt_atts atts @ [Pretty.str ":"]))];
  1494       else [Pretty.block (Pretty.breaks (prt_name name :: prt_atts atts @ [Pretty.str ":"]))];
  1657       Pretty.block (Pretty.breaks (List.concat (prt_name_atts a :: map prt_fact ths)));
  1505       Pretty.block (Pretty.breaks (List.concat (prt_name_atts a :: map prt_fact ths)));
  1658 
  1506 
  1659     fun items _ [] = []
  1507     fun items _ [] = []
  1660       | items prfx (x :: xs) = Pretty.block [Pretty.str prfx, Pretty.brk 1, x] :: items "  and" xs;
  1508       | items prfx (x :: xs) = Pretty.block [Pretty.str prfx, Pretty.brk 1, x] :: items "  and" xs;
  1661     fun prt_elem (Fixes fixes) = items "fixes" (map prt_fix fixes)
  1509     fun prt_elem (Fixes fixes) = items "fixes" (map prt_fix fixes)
       
  1510       | prt_elem (Constrains csts) = items "constrains" (map prt_cst csts)
  1662       | prt_elem (Assumes asms) = items "assumes" (map prt_asm asms)
  1511       | prt_elem (Assumes asms) = items "assumes" (map prt_asm asms)
  1663       | prt_elem (Defines defs) = items "defines" (map prt_def defs)
  1512       | prt_elem (Defines defs) = items "defines" (map prt_def defs)
  1664       | prt_elem (Notes facts) = items "notes" (map prt_note facts);
  1513       | prt_elem (Notes facts) = items "notes" (map prt_note facts);
  1665   in
  1514   in
  1666     Pretty.big_list "context elements:" (map (Pretty.chunks o prt_elem) all_elems)
  1515     Pretty.big_list "context elements:" (map (Pretty.chunks o prt_elem) all_elems)
  2014 
  1863 
  2015 local
  1864 local
  2016 
  1865 
  2017 (* extract proof obligations (assms and defs) from elements *)
  1866 (* extract proof obligations (assms and defs) from elements *)
  2018 
  1867 
  2019 (* check if defining equation has become t == t, these are dropped
       
  2020    in extract_asms_elem, as they lead to trivial proof obligations *)
       
  2021 (* currently disabled *)
       
  2022 fun check_def (_, (def, _)) = SOME def;
       
  2023 (*
       
  2024 fun check_def (_, (def, _)) =
       
  2025       if def |> Logic.dest_equals |> op aconv
       
  2026       then NONE else SOME def;
       
  2027 *)
       
  2028 
       
  2029 fun extract_asms_elem (ts, Fixes _) = ts
  1868 fun extract_asms_elem (ts, Fixes _) = ts
       
  1869   | extract_asms_elem (ts, Constrains _) = ts
  2030   | extract_asms_elem (ts, Assumes asms) =
  1870   | extract_asms_elem (ts, Assumes asms) =
  2031       ts @ List.concat (map (fn (_, ams) => map (fn (t, _) => t) ams) asms)
  1871       ts @ List.concat (map (fn (_, ams) => map (fn (t, _) => t) ams) asms)
  2032   | extract_asms_elem (ts, Defines defs) =
  1872   | extract_asms_elem (ts, Defines defs) =
  2033       ts @ List.mapPartial check_def defs
  1873       ts @ map (fn (_, (def, _)) => def) defs
  2034   | extract_asms_elem (ts, Notes _) = ts;
  1874   | extract_asms_elem (ts, Notes _) = ts;
  2035 
  1875 
  2036 fun extract_asms_elems (id, elems) =
  1876 fun extract_asms_elems (id, elems) =
  2037       (id, Library.foldl extract_asms_elem ([], elems));
  1877       (id, Library.foldl extract_asms_elem ([], elems));
  2038 
  1878 
  2040       map extract_asms_elems elemss;
  1880       map extract_asms_elems elemss;
  2041 
  1881 
  2042 (* activate instantiated facts in theory or context *)
  1882 (* activate instantiated facts in theory or context *)
  2043 
  1883 
  2044 fun activate_facts_elem _ _ _ _ (thy_ctxt, Fixes _) = thy_ctxt
  1884 fun activate_facts_elem _ _ _ _ (thy_ctxt, Fixes _) = thy_ctxt
       
  1885   | activate_facts_elem _ _ _ _ (thy_ctxt, Constrains _) = thy_ctxt
  2045   | activate_facts_elem _ _ _ _ (thy_ctxt, Assumes _) = thy_ctxt
  1886   | activate_facts_elem _ _ _ _ (thy_ctxt, Assumes _) = thy_ctxt
  2046   | activate_facts_elem _ _ _ _ (thy_ctxt, Defines _) = thy_ctxt
  1887   | activate_facts_elem _ _ _ _ (thy_ctxt, Defines _) = thy_ctxt
  2047   | activate_facts_elem note_thmss attrib
  1888   | activate_facts_elem note_thmss attrib
  2048         disch (prfx, atts) (thy_ctxt, Notes facts) =
  1889         disch (prfx, atts) (thy_ctxt, Notes facts) =
  2049       let
  1890       let