622 fun inst ((((name, ps), mode), elems), env) = |
620 fun inst ((((name, ps), mode), elems), env) = |
623 (((name, map (apsnd (Option.map (Element.instT_type env))) ps), |
621 (((name, map (apsnd (Option.map (Element.instT_type env))) ps), |
624 map_mode (map (Element.instT_witness thy env)) mode), |
622 map_mode (map (Element.instT_witness thy env)) mode), |
625 map (Element.instT_ctxt thy env) elems); |
623 map (Element.instT_ctxt thy env) elems); |
626 in map inst (elemss ~~ envs) end; |
624 in map inst (elemss ~~ envs) end; |
627 |
|
628 (* like unify_elemss, but does not touch mode, additional |
|
629 parameter c_parms for enforcing further constraints (eg. syntax) *) |
|
630 (* FIXME avoid code duplication *) |
|
631 |
|
632 fun unify_elemss' _ _ [] [] = [] |
|
633 | unify_elemss' _ [] [elems] [] = [elems] |
|
634 | unify_elemss' ctxt fixed_parms elemss c_parms = |
|
635 let |
|
636 val thy = ProofContext.theory_of ctxt; |
|
637 val envs = |
|
638 unify_parms ctxt fixed_parms (map (snd o fst o fst) elemss @ map single c_parms); |
|
639 fun inst ((((name, ps), (ps', mode)), elems), env) = |
|
640 (((name, map (apsnd (Option.map (Element.instT_type env))) ps), (ps', mode)), |
|
641 map (Element.instT_ctxt thy env) elems); |
|
642 in map inst (elemss ~~ Library.take (length elemss, envs)) end; |
|
643 |
625 |
644 |
626 |
645 fun renaming xs parms = zip_options parms xs |
627 fun renaming xs parms = zip_options parms xs |
646 handle Library.UnequalLengths => |
628 handle Library.UnequalLengths => |
647 error ("Too many arguments in renaming: " ^ |
629 error ("Too many arguments in renaming: " ^ |
800 where name is a locale name, ps a list of parameter names and axs |
782 where name is a locale name, ps a list of parameter names and axs |
801 a list of axioms relating to the identifier, axs is empty unless |
783 a list of axioms relating to the identifier, axs is empty unless |
802 identify at top level (top = true); |
784 identify at top level (top = true); |
803 parms is accumulated list of parameters *) |
785 parms is accumulated list of parameters *) |
804 let |
786 let |
805 val {axiom, import, params, ...} = |
787 val {axiom, import, params, ...} = the_locale thy name; |
806 the_locale thy name; |
|
807 val ps = map (#1 o #1) params; |
788 val ps = map (#1 o #1) params; |
808 val (ids', parms', _) = identify false import; |
789 val (ids', parms') = identify false import; |
809 (* acyclic import dependencies *) |
790 (* acyclic import dependencies *) |
810 |
791 |
811 val ids'' = ids' @ [((name, ps), ([], Assumed []))]; |
792 val ids'' = ids' @ [((name, ps), ([], Assumed []))]; |
812 val (_, ids''') = add_regs (name, map #1 params) ([], ids''); |
793 val (_, ids''') = add_regs (name, map #1 params) ([], ids''); |
813 val (_, ids4) = chop (length ids' + 1) ids'''; |
794 val (_, ids4) = chop (length ids' + 1) ids'''; |
814 val ids5 = ids' @ ids4 @ [((name, ps), ([], Assumed []))]; |
795 val ids5 = ids' @ ids4 @ [((name, ps), ([], Assumed []))]; |
815 val ids_ax = if top then fst (fold_map (axiomify ps) ids5 axiom) else ids5; |
796 val ids_ax = if top then fst (fold_map (axiomify ps) ids5 axiom) else ids5; |
816 val syn = Symtab.make (map (apfst fst) params); |
797 in (ids_ax, merge_lists parms' ps) end |
817 in (ids_ax, merge_lists parms' ps, syn) end |
|
818 | identify top (Rename (e, xs)) = |
798 | identify top (Rename (e, xs)) = |
819 let |
799 let |
820 val (ids', parms', syn') = identify top e; |
800 val (ids', parms') = identify top e; |
821 val ren = renaming xs parms' |
801 val ren = renaming xs parms' |
822 handle ERROR msg => err_in_locale' ctxt msg ids'; |
802 handle ERROR msg => err_in_locale' ctxt msg ids'; |
823 |
803 |
824 val ids'' = distinct (eq_fst (op =)) (map (rename_parms top ren) ids'); |
804 val ids'' = distinct (eq_fst (op =)) (map (rename_parms top ren) ids'); |
825 val parms'' = distinct (op =) (maps (#2 o #1) ids''); |
805 val parms'' = distinct (op =) (maps (#2 o #1) ids''); |
826 val syn'' = fold (Symtab.insert (op =)) |
806 in (ids'', parms'') end |
827 (map (Element.rename_var ren) (Symtab.dest syn')) Symtab.empty; |
|
828 in (ids'', parms'', syn'') end |
|
829 | identify top (Merge es) = |
807 | identify top (Merge es) = |
830 fold (fn e => fn (ids, parms, syn) => |
808 fold (fn e => fn (ids, parms) => |
831 let |
809 let |
832 val (ids', parms', syn') = identify top e |
810 val (ids', parms') = identify top e |
833 in |
811 in |
834 (merge_alists ids ids', |
812 (merge_alists ids ids', merge_lists parms parms') |
835 merge_lists parms parms', |
|
836 merge_syntax ctxt ids' (syn, syn')) |
|
837 end) |
813 end) |
838 es ([], [], Symtab.empty); |
814 es ([], []); |
839 |
815 |
840 |
816 fun inst_wit all_params (t, th) = let |
841 (* CB: enrich identifiers by parameter types and |
|
842 the corresponding elements (with renamed parameters), |
|
843 also takes care of parameter syntax *) |
|
844 |
|
845 fun eval syn ((name, xs), axs) = |
|
846 let |
|
847 val {params = ps, lparams = qs, elems, ...} = the_locale thy name; |
|
848 val ps' = map (apsnd SOME o #1) ps; |
|
849 fun lookup_syn x = (case Symtab.lookup syn x of SOME Structure => NONE | opt => opt); |
|
850 val ren = map #1 ps' ~~ map (fn x => (x, lookup_syn x)) xs; |
|
851 val (params', elems') = |
|
852 if null ren then (ps', map #1 elems) |
|
853 else (map (apfst (Element.rename ren)) ps', |
|
854 map (Element.rename_ctxt ren o #1) elems); |
|
855 val elems'' = elems' |> map (Element.map_ctxt |
|
856 {var = I, typ = I, term = I, fact = I, attrib = I, |
|
857 name = NameSpace.qualified (space_implode "_" xs)}); |
|
858 in (((name, params'), axs), elems'') end; |
|
859 |
|
860 (* type constraint for renamed parameter with syntax *) |
|
861 fun mixfix_type mx = |
|
862 SOME (Type.freeze_type (#1 (TypeInfer.paramify_dummies (TypeInfer.mixfixT mx) 0))); |
|
863 |
|
864 (* compute identifiers and syntax, merge with previous ones *) |
|
865 val (ids, _, syn) = identify true expr; |
|
866 val idents = gen_rems (eq_fst (op =)) (ids, prev_idents); |
|
867 val syntax = merge_syntax ctxt ids (syn, prev_syntax); |
|
868 (* add types to params and unify them *) |
|
869 val raw_elemss = map (eval syntax) idents; |
|
870 val elemss = unify_elemss' ctxt [] raw_elemss (map (apsnd mixfix_type) (Symtab.dest syntax)); |
|
871 (* replace params in ids by params from axioms, |
|
872 adjust types in mode *) |
|
873 val all_params' = params_of' elemss; |
|
874 val all_params = param_types all_params'; |
|
875 val elemss' = map (fn (((name, _), (ps, mode)), elems) => |
|
876 (((name, map (fn p => (p, AList.lookup (op =) all_params p)) ps), mode), elems)) |
|
877 elemss; |
|
878 fun inst_th (t, th) = let |
|
879 val {hyps, prop, ...} = Thm.rep_thm th; |
817 val {hyps, prop, ...} = Thm.rep_thm th; |
880 val ps = map (apsnd SOME) (fold Term.add_frees (prop :: hyps) []); |
818 val ps = map (apsnd SOME) (fold Term.add_frees (prop :: hyps) []); |
881 val [env] = unify_parms ctxt all_params [ps]; |
819 val [env] = unify_parms ctxt all_params [ps]; |
882 val t' = Element.instT_term env t; |
820 val t' = Element.instT_term env t; |
883 val th' = Element.instT_thm thy env th; |
821 val th' = Element.instT_thm thy env th; |
884 in (t', th') end; |
822 in (t', th') end; |
885 val final_elemss = map (fn ((id, mode), elems) => |
823 |
886 ((id, map_mode (map (Element.map_witness inst_th)) mode), elems)) elemss'; |
824 fun eval all_params tenv syn ((name, params), (locale_params, mode)) = |
887 |
825 let |
|
826 val {params = ps_mx, elems = elems_stamped, ...} = the_locale thy name; |
|
827 val elems = map fst elems_stamped; |
|
828 val ps = map fst ps_mx; |
|
829 fun lookup_syn x = (case Symtab.lookup syn x of SOME Structure => NONE | opt => opt); |
|
830 val locale_params' = map (fn p => (p, Symtab.lookup tenv p |> the)) locale_params; |
|
831 val mode' = map_mode (map (Element.map_witness (inst_wit all_params))) mode; |
|
832 val ren = map fst ps ~~ map (fn p => (p, lookup_syn p)) params; |
|
833 val [env] = unify_parms ctxt all_params [map (apfst (Element.rename ren) o apsnd SOME) ps]; |
|
834 val elems' = elems |
|
835 |> map (Element.rename_ctxt ren) |
|
836 |> map (Element.map_ctxt {var = I, typ = I, term = I, fact = I, attrib = I, |
|
837 name = NameSpace.qualified (space_implode "_" params)}) |
|
838 |> map (Element.instT_ctxt thy env) |
|
839 in (((name, map (apsnd SOME) locale_params'), mode'), elems') end; |
|
840 |
|
841 (* parameters, their types and syntax *) |
|
842 val (all_params', tenv, syn) = params_of_expr ctxt [] expr ([], Symtab.empty, Symtab.empty); |
|
843 val all_params = map (fn p => (p, Symtab.lookup tenv p |> the)) all_params'; |
|
844 (* compute identifiers and syntax, merge with previous ones *) |
|
845 val (ids, _) = identify true expr; |
|
846 val idents = gen_rems (eq_fst (op =)) (ids, prev_idents); |
|
847 val syntax = merge_syntax ctxt ids (syn, prev_syntax); |
|
848 (* type-instantiate elements *) |
|
849 val final_elemss = map (eval all_params tenv syntax) idents; |
888 in ((prev_idents @ idents, syntax), final_elemss) end; |
850 in ((prev_idents @ idents, syntax), final_elemss) end; |
889 |
851 |
890 end; |
852 end; |
891 |
853 |
892 |
854 |
1420 context fixed_params |
1382 context fixed_params |
1421 (raw_import_params_elemss @ raw_import_elemss @ raw_incl_params_elemss @ raw_elemss) raw_concl; |
1383 (raw_import_params_elemss @ raw_import_elemss @ raw_incl_params_elemss @ raw_elemss) raw_concl; |
1422 |
1384 |
1423 (* replace extended ids (for axioms) by ids *) |
1385 (* replace extended ids (for axioms) by ids *) |
1424 val (import_ids', incl_ids) = chop (length import_ids) ids; |
1386 val (import_ids', incl_ids) = chop (length import_ids) ids; |
1425 val add_ids = import_params_ids @ import_ids' @ incl_params_ids @ incl_ids; |
1387 val all_ids = import_params_ids @ import_ids' @ incl_params_ids @ incl_ids; |
1426 val all_elemss' = map (fn (((_, ps), _), (((n, ps'), mode), elems)) => |
1388 val all_elemss' = map (fn (((_, ps), _), (((n, ps'), mode), elems)) => |
1427 (((n, map (fn p => (p, (the o AList.lookup (op =) ps') p)) ps), mode), elems)) |
1389 (((n, map (fn p => (p, (the o AList.lookup (op =) ps') p)) ps), mode), elems)) |
1428 (add_ids ~~ all_elemss); |
1390 (all_ids ~~ all_elemss); |
1429 (* CB: all_elemss and parms contain the correct parameter types *) |
1391 (* CB: all_elemss and parms contain the correct parameter types *) |
1430 |
1392 |
1431 val (ps, qs) = chop (length raw_import_params_elemss + length raw_import_elemss) all_elemss'; |
1393 val (ps, qs) = chop (length raw_import_params_elemss + length raw_import_elemss) all_elemss'; |
1432 val (import_ctxt, (import_elemss, _)) = |
1394 val (import_ctxt, (import_elemss, _)) = |
1433 activate_facts false prep_facts (context, ps); |
1395 activate_facts false prep_facts (context, ps); |
1819 val ((((elemss', predicate as (predicate_statement, predicate_axioms), stmt'), intros), |
1781 val ((((elemss', predicate as (predicate_statement, predicate_axioms), stmt'), intros), |
1820 pred_thy), (import, regs)) = |
1782 pred_thy), (import, regs)) = |
1821 if do_predicate then |
1783 if do_predicate then |
1822 let |
1784 let |
1823 val (elemss', defns) = change_defines_elemss thy elemss []; |
1785 val (elemss', defns) = change_defines_elemss thy elemss []; |
1824 val elemss'' = elemss' @ |
1786 val elemss'' = elemss' @ [(("", []), defns)]; |
1825 (* |
|
1826 [(("", []), [Defines (map (fn t => (("", []), (t, []))) defs)])]; |
|
1827 *) |
|
1828 [(("", []), defns)]; |
|
1829 val (((elemss''', predicate as (_, axioms), stmt'), intros), thy') = |
1787 val (((elemss''', predicate as (_, axioms), stmt'), intros), thy') = |
1830 define_preds bname text elemss'' thy; |
1788 define_preds bname text elemss'' thy; |
1831 fun mk_regs elemss wits = |
1789 fun mk_regs elemss wits = |
1832 fold_map (fn (id, elems) => fn wts => let |
1790 fold_map (fn (id, elems) => fn wts => let |
1833 val ts = List.concat (List.mapPartial (fn (Assumes asms) => |
1791 val ts = List.concat (List.mapPartial (fn (Assumes asms) => |