src/Pure/Isar/locale.ML
changeset 12730 fd0f8fa2b6bd
parent 12727 330cb92aaea3
child 12758 f6aceb9d4b8e
equal deleted inserted replaced
12729:46808b5ec985 12730:fd0f8fa2b6bd
    87 
    87 
    88 type locale =
    88 type locale =
    89  {import: expr,                                                         (*dynamic import*)
    89  {import: expr,                                                         (*dynamic import*)
    90   elems: ((typ, term, thm list, context attribute) elem * stamp) list,  (*static content*)
    90   elems: ((typ, term, thm list, context attribute) elem * stamp) list,  (*static content*)
    91   params: (string * typ option) list * string list,                     (*all vs. local params*)
    91   params: (string * typ option) list * string list,                     (*all vs. local params*)
    92   text: (string * typ) list * term list}                                (*logical representation*)
    92   text: ((string * typ) list * term list) * ((string * typ) list * term list)};  (*predicate text*)
    93 
    93 
    94 fun make_locale import elems params text =
    94 fun make_locale import elems params text =
    95  {import = import, elems = elems, params = params, text = text}: locale;
    95  {import = import, elems = elems, params = params, text = text}: locale;
    96 
    96 
    97 
    97 
   273     val (unifier, _) = foldl unify ((Vartab.empty, maxidx''), Ts' ~~ Us');
   273     val (unifier, _) = foldl unify ((Vartab.empty, maxidx''), Ts' ~~ Us');
   274     val Vs = map (apsome (Envir.norm_type unifier)) Us';
   274     val Vs = map (apsome (Envir.norm_type unifier)) Us';
   275     val unifier' = Vartab.extend (unifier, frozen_tvars ctxt (mapfilter I Vs));
   275     val unifier' = Vartab.extend (unifier, frozen_tvars ctxt (mapfilter I Vs));
   276   in map (apsome (Envir.norm_type unifier')) Vs end;
   276   in map (apsome (Envir.norm_type unifier')) Vs end;
   277 
   277 
   278 fun params_of elemss = flat (map (snd o fst) elemss);
   278 fun params_of elemss = gen_distinct eq_fst (flat (map (snd o fst) elemss));
   279 fun param_types ps = mapfilter (fn (_, None) => None | (x, Some T) => Some (x, T)) ps;
   279 fun param_types ps = mapfilter (fn (_, None) => None | (x, Some T) => Some (x, T)) ps;
   280 
   280 
   281 
   281 
   282 (* flatten expressions *)
   282 (* flatten expressions *)
   283 
   283 
   582 fun get_facts_i x = prep_facts (K I) x;
   582 fun get_facts_i x = prep_facts (K I) x;
   583 
   583 
   584 end;
   584 end;
   585 
   585 
   586 
   586 
       
   587 (* predicate_text *)
       
   588 
       
   589 local
       
   590 
       
   591 val norm_term = Envir.beta_norm oo Term.subst_atomic;
       
   592 
       
   593 (*assumes well-formedness according to ProofContext.cert_def*)
       
   594 fun abstract_def eq =
       
   595   let
       
   596     val body = Term.strip_all_body eq;
       
   597     val vars = map Free (Term.rename_wrt_term body (Term.strip_all_vars eq));
       
   598     val (lhs, rhs) = Logic.dest_equals (Term.subst_bounds (vars, body));
       
   599     val (f, xs) = Term.strip_comb lhs;
       
   600   in (Term.dest_Free f, Term.list_abs_free (map Term.dest_Free xs, rhs)) end;
       
   601 
       
   602 fun bind_def ctxt (name, ps) ((xs, ys, env), eq) =
       
   603   let
       
   604     val (y, b) = abstract_def eq;
       
   605     val b' = norm_term env b;
       
   606     fun err msg = err_in_locale ctxt (msg ^ ": " ^ quote (#1 y)) [(name, map fst ps)];
       
   607   in
       
   608     conditional (y mem xs) (fn () => err "Attempt to define previously specified variable");
       
   609     conditional (y mem ys) (fn () => err "Attempt to redefine variable");
       
   610     (Term.add_frees (xs, b'), y :: ys, (Free y, b') :: env)
       
   611   end;
       
   612 
       
   613 fun eval_body _ _ (body, Fixes _) = body
       
   614   | eval_body _ _ (((xs, spec), (ys, env)), Assumes asms) =
       
   615       let val ts = map (norm_term env) (flat (map (map #1 o #2) asms))
       
   616       in ((foldl Term.add_frees (xs, ts), spec @ ts), (ys, env)) end
       
   617   | eval_body ctxt id (((xs, spec), (ys, env)), Defines defs) =
       
   618       let val (xs', ys', env') = foldl (bind_def ctxt id) ((xs, ys, env), map (#1 o #2) defs)
       
   619       in ((xs', spec), (ys', env')) end
       
   620   | eval_body _ _ (body, Notes _) = body;
       
   621 
       
   622 fun eval_bodies ctxt =
       
   623   foldl (fn (body, (id, elems)) => foldl (eval_body ctxt id) (body, elems));
       
   624 
       
   625 in
       
   626 
       
   627 fun predicate_text (ctxt1, elemss1) (ctxt2, elemss2) =
       
   628   let
       
   629     val parms1 = params_of elemss1;
       
   630     val parms2 = params_of elemss2;
       
   631     val all_parms = parms1 @ parms2;
       
   632     fun filter_parms xs = all_parms |> mapfilter (fn (p, _) =>
       
   633       (case assoc_string (xs, p) of None => None | Some T => Some (p, T)));
       
   634     val body as ((xs1, ts1), _) = eval_bodies ctxt1 ((([], []), ([], [])), elemss1);
       
   635     val ((all_xs, all_ts), _) = eval_bodies ctxt2 (body, elemss2);
       
   636     val xs2 = Library.drop (length xs1, all_xs);
       
   637     val ts2 = Library.drop (length ts1, all_ts);
       
   638   in ((all_parms, (filter_parms all_xs, all_ts)), (parms2, (filter_parms xs2, ts2))) end;
       
   639 
       
   640 end;
       
   641 
       
   642 
   587 (* full context statements: import + elements + conclusion *)
   643 (* full context statements: import + elements + conclusion *)
   588 
   644 
   589 local
   645 local
   590 
   646 
   591 fun prep_context_statement prep_expr prep_elemss prep_facts
   647 fun prep_context_statement prep_expr prep_elemss prep_facts
   606       prep_elemss close context fixed_params (raw_import_elemss @ raw_elemss) raw_concl;
   662       prep_elemss close context fixed_params (raw_import_elemss @ raw_elemss) raw_concl;
   607 
   663 
   608     val n = length raw_import_elemss;
   664     val n = length raw_import_elemss;
   609     val (import_ctxt, import_elemss) = foldl_map activate (context, take (n, all_elemss));
   665     val (import_ctxt, import_elemss) = foldl_map activate (context, take (n, all_elemss));
   610     val (ctxt, elemss) = foldl_map activate (import_ctxt, drop (n, all_elemss));
   666     val (ctxt, elemss) = foldl_map activate (import_ctxt, drop (n, all_elemss));
   611   in (((import_ctxt, import_elemss), (ctxt, elemss)), concl) end;
   667     val text = predicate_text (import_ctxt, import_elemss) (ctxt, elemss);
       
   668   in ((((import_ctxt, import_elemss), (ctxt, elemss)), text), concl) end;
   612 
   669 
   613 val gen_context = prep_context_statement intern_expr read_elemss get_facts;
   670 val gen_context = prep_context_statement intern_expr read_elemss get_facts;
   614 val gen_context_i = prep_context_statement (K I) cert_elemss get_facts_i;
   671 val gen_context_i = prep_context_statement (K I) cert_elemss get_facts_i;
   615 
   672 
   616 fun gen_statement prep_locale prep_ctxt raw_locale elems concl ctxt =
   673 fun gen_statement prep_locale prep_ctxt raw_locale elems concl ctxt =
   618     val thy = ProofContext.theory_of ctxt;
   675     val thy = ProofContext.theory_of ctxt;
   619     val locale = apsome (prep_locale (Theory.sign_of thy)) raw_locale;
   676     val locale = apsome (prep_locale (Theory.sign_of thy)) raw_locale;
   620     val (fixed_params, import) =
   677     val (fixed_params, import) =
   621       (case locale of None => ([], empty)
   678       (case locale of None => ([], empty)
   622       | Some name => (param_types (#1 (#params (the_locale thy name))), Locale name));
   679       | Some name => (param_types (#1 (#params (the_locale thy name))), Locale name));
   623     val (((locale_ctxt, _), (elems_ctxt, _)), concl') =
   680     val ((((locale_ctxt, _), (elems_ctxt, _)), _), concl') =
   624       prep_ctxt false fixed_params import elems concl ctxt;
   681       prep_ctxt false fixed_params import elems concl ctxt;
   625   in (locale, locale_ctxt, elems_ctxt, concl') end;
   682   in (locale, locale_ctxt, elems_ctxt, concl') end;
   626 
   683 
   627 in
   684 in
   628 
   685 
   639 
   696 
   640 fun print_locale thy raw_expr =
   697 fun print_locale thy raw_expr =
   641   let
   698   let
   642     val sg = Theory.sign_of thy;
   699     val sg = Theory.sign_of thy;
   643     val thy_ctxt = ProofContext.init thy;
   700     val thy_ctxt = ProofContext.init thy;
   644     val (ctxt, elemss) = #1 (read_context raw_expr [] thy_ctxt);
   701     val (((ctxt, elemss), _), ((_, (pred_xs, pred_ts)), _)) = read_context raw_expr [] thy_ctxt;
   645 
   702 
   646     val prt_typ = Pretty.quote o ProofContext.pretty_typ ctxt;
   703     val prt_typ = Pretty.quote o ProofContext.pretty_typ ctxt;
   647     val prt_term = Pretty.quote o ProofContext.pretty_term ctxt;
   704     val prt_term = Pretty.quote o ProofContext.pretty_term ctxt;
   648     val prt_thm = Pretty.quote o ProofContext.pretty_thm ctxt;
   705     val prt_thm = Pretty.quote o ProofContext.pretty_thm ctxt;
   649 
   706 
   665       | items prfx (x :: xs) = Pretty.block [Pretty.str prfx, Pretty.brk 1, x] :: items "  and" xs;
   722       | items prfx (x :: xs) = Pretty.block [Pretty.str prfx, Pretty.brk 1, x] :: items "  and" xs;
   666     fun prt_elem (Fixes fixes) = items "fixes" (map prt_fix fixes)
   723     fun prt_elem (Fixes fixes) = items "fixes" (map prt_fix fixes)
   667       | prt_elem (Assumes asms) = items "assumes" (map prt_asm asms)
   724       | prt_elem (Assumes asms) = items "assumes" (map prt_asm asms)
   668       | prt_elem (Defines defs) = items "defines" (map prt_def defs)
   725       | prt_elem (Defines defs) = items "defines" (map prt_def defs)
   669       | prt_elem (Notes facts) = items "notes" (map prt_fact facts);
   726       | prt_elem (Notes facts) = items "notes" (map prt_fact facts);
       
   727 
       
   728     val prt_pred =
       
   729       if null pred_ts then Pretty.str ""
       
   730       else
       
   731         Library.foldr1 Logic.mk_conjunction pred_ts
       
   732         |> Thm.cterm_of sg |> ObjectLogic.atomize_cterm |> Thm.term_of
       
   733         |> curry Term.list_abs_free pred_xs
       
   734         |> prt_term;
   670   in
   735   in
   671     Pretty.big_list "context elements:" (map (Pretty.chunks o prt_elem) (flat (map #2 elemss)))
   736     [Pretty.big_list "context elements:" (map (Pretty.chunks o prt_elem) (flat (map #2 elemss))),
   672     |> Pretty.writeln
   737       Pretty.big_list "predicate text:" [prt_pred]] |> Pretty.chunks |> Pretty.writeln
   673   end;
   738   end;
   674 
   739 
   675 
   740 
   676 
   741 
   677 (** define locales **)
   742 (** define locales **)
   686     val name = Sign.full_name sign bname;
   751     val name = Sign.full_name sign bname;
   687     val _ = conditional (is_some (get_locale thy name)) (fn () =>
   752     val _ = conditional (is_some (get_locale thy name)) (fn () =>
   688       error ("Duplicate definition of locale " ^ quote name));
   753       error ("Duplicate definition of locale " ^ quote name));
   689 
   754 
   690     val thy_ctxt = ProofContext.init thy;
   755     val thy_ctxt = ProofContext.init thy;
   691     val ((import_ctxt, import_elemss), (body_ctxt, body_elemss)) =
   756     val (((import_ctxt, import_elemss), (body_ctxt, body_elemss)),
       
   757         ((all_parms, all_text), (body_parms, body_text))) =
   692       prep_context raw_import raw_body thy_ctxt;
   758       prep_context raw_import raw_body thy_ctxt;
   693     val import_parms = params_of import_elemss;
   759     val import = prep_expr sign raw_import;
   694     val import = (prep_expr sign raw_import);
       
   695 
       
   696     val elems = flat (map snd body_elemss);
   760     val elems = flat (map snd body_elemss);
   697     val body_parms = params_of body_elemss;
       
   698     val text = ([], []);  (* FIXME *)
       
   699   in
   761   in
   700     thy
   762     thy
   701     |> declare_locale name
   763     |> declare_locale name
   702     |> put_locale name (make_locale import (map (fn e => (e, stamp ())) elems)
   764     |> put_locale name (make_locale import (map (fn e => (e, stamp ())) elems)
   703       (import_parms @ body_parms, map #1 body_parms) text)
   765       (all_parms, map fst body_parms) (all_text, body_text))
   704   end;
   766   end;
   705 
   767 
   706 in
   768 in
   707 
   769 
   708 val add_locale = gen_add_locale read_context intern_expr;
   770 val add_locale = gen_add_locale read_context intern_expr;
   709 val add_locale_i = gen_add_locale cert_context (K I);
   771 val add_locale_i = gen_add_locale cert_context (K I);
   710 
   772 
   711 end;
   773 end;
   712 
   774 
   713 
   775 
   714 
   776 (* store results *)
   715 (** store results **)
       
   716 
   777 
   717 local
   778 local
   718 
   779 
   719 fun put_facts loc args thy =
   780 fun put_facts loc args thy =
   720   let
   781   let
   743 
   804 
   744 fun gen_have_thmss prep_locale get_thms kind raw_loc raw_args thy =
   805 fun gen_have_thmss prep_locale get_thms kind raw_loc raw_args thy =
   745   let
   806   let
   746     val thy_ctxt = ProofContext.init thy;
   807     val thy_ctxt = ProofContext.init thy;
   747     val loc = prep_locale (Theory.sign_of thy) raw_loc;
   808     val loc = prep_locale (Theory.sign_of thy) raw_loc;
   748     val loc_ctxt = #1 (#1 (cert_context (Locale loc) [] thy_ctxt));
   809     val loc_ctxt = #1 (#1 (#1 (cert_context (Locale loc) [] thy_ctxt)));
   749     val args = map (apsnd (map (apfst (get_thms loc_ctxt)))) raw_args;
   810     val args = map (apsnd (map (apfst (get_thms loc_ctxt)))) raw_args;
   750     val export = Drule.local_standard o ProofContext.export_single loc_ctxt thy_ctxt;
   811     val export = Drule.local_standard o ProofContext.export_single loc_ctxt thy_ctxt;
   751     val results = map (map export o #2) (#2 (ProofContext.have_thmss_i args loc_ctxt));
   812     val results = map (map export o #2) (#2 (ProofContext.have_thmss_i args loc_ctxt));
   752     val args' = map (rpair [] o #1 o #1) args ~~ map (single o Thm.no_attributes) results;
   813     val args' = map (rpair [] o #1 o #1) args ~~ map (single o Thm.no_attributes) results;
   753   in
   814   in
   770      else raise THEORY ("Bad number of locale attributes", [thy]);
   831      else raise THEORY ("Bad number of locale attributes", [thy]);
   771 
   832 
   772 end;
   833 end;
   773 
   834 
   774 
   835 
       
   836 
   775 (** locale theory setup **)
   837 (** locale theory setup **)
   776 
   838 
   777 val setup =
   839 val setup =
   778  [LocalesData.init];
   840  [LocalesData.init];
   779 
   841