588 | intern_attrib_elem_expr _ (Expr expr) = Expr expr; |
589 | intern_attrib_elem_expr _ (Expr expr) = Expr expr; |
589 |
590 |
590 |
591 |
591 (* renaming *) |
592 (* renaming *) |
592 |
593 |
593 fun rename ren x = getOpt (assoc_string (ren, x), x); |
594 (* ren maps names to (new) names and syntax; represented as association list *) |
594 |
595 |
595 fun rename_var ren (x, mx) = |
596 fun rename_var ren (x, mx) = |
596 let val x' = rename ren x in |
597 case assoc_string (ren, x) of |
597 if x = x' then (x, mx) |
598 NONE => (x, mx) |
598 else (x', if mx = NONE then mx else SOME Syntax.NoSyn) (*drop syntax*) |
599 | SOME (x', NONE) => |
599 end; |
600 (x', if mx = NONE then mx else SOME Syntax.NoSyn) (*drop syntax*) |
|
601 | SOME (x', SOME mx') => |
|
602 if mx = NONE then raise ERROR_MESSAGE |
|
603 ("Attempt to change syntax of structure parameter " ^ quote x) |
|
604 else (x', SOME mx'); (*change syntax*) |
|
605 |
|
606 fun rename ren x = |
|
607 case assoc_string (ren, x) of |
|
608 NONE => x |
|
609 | SOME (x', _) => x'; (*ignore syntax*) |
600 |
610 |
601 fun rename_term ren (Free (x, T)) = Free (rename ren x, T) |
611 fun rename_term ren (Free (x, T)) = Free (rename ren x, T) |
602 | rename_term ren (t $ u) = rename_term ren t $ rename_term ren u |
612 | rename_term ren (t $ u) = rename_term ren t $ rename_term ren u |
603 | rename_term ren (Abs (x, T, t)) = Abs (x, T, rename_term ren t) |
613 | rename_term ren (Abs (x, T, t)) = Abs (x, T, rename_term ren t) |
604 | rename_term _ a = a; |
614 | rename_term _ a = a; |
786 fun inst_parms (i, ps) = |
800 fun inst_parms (i, ps) = |
787 foldr Term.add_typ_tfrees [] (List.mapPartial snd ps) |
801 foldr Term.add_typ_tfrees [] (List.mapPartial snd ps) |
788 |> List.mapPartial (fn (a, S) => |
802 |> List.mapPartial (fn (a, S) => |
789 let val T = Envir.norm_type unifier' (TVar ((a, i), S)) |
803 let val T = Envir.norm_type unifier' (TVar ((a, i), S)) |
790 in if T = TFree (a, S) then NONE else SOME ((a, S), T) end) |
804 in if T = TFree (a, S) then NONE else SOME ((a, S), T) end) |
791 in map inst_parms idx_parmss end; |
805 in map inst_parms idx_parmss end : ((string * Term.sort) * Term.typ) list list; |
792 |
806 |
793 in |
807 in |
794 |
|
795 (* like unify_elemss, but does not touch axioms *) |
|
796 |
|
797 fun unify_elemss' _ _ [] = [] |
|
798 | unify_elemss' _ [] [elems] = [elems] |
|
799 | unify_elemss' ctxt fixed_parms elemss = |
|
800 let |
|
801 val envs = unify_parms ctxt fixed_parms (map (#2 o #1 o #1) elemss); |
|
802 fun inst ((((name, ps), axs), elems), env) = |
|
803 (((name, map (apsnd (Option.map (inst_type env))) ps), axs), |
|
804 map (inst_elem ctxt env) elems); |
|
805 in map inst (elemss ~~ envs) end; |
|
806 |
808 |
807 fun unify_elemss _ _ [] = [] |
809 fun unify_elemss _ _ [] = [] |
808 | unify_elemss _ [] [elems] = [elems] |
810 | unify_elemss _ [] [elems] = [elems] |
809 | unify_elemss ctxt fixed_parms elemss = |
811 | unify_elemss ctxt fixed_parms elemss = |
810 let |
812 let |
812 fun inst ((((name, ps), axs), elems), env) = |
814 fun inst ((((name, ps), axs), elems), env) = |
813 (((name, map (apsnd (Option.map (inst_type env))) ps), |
815 (((name, map (apsnd (Option.map (inst_type env))) ps), |
814 map (inst_thm ctxt env) axs), map (inst_elem ctxt env) elems); |
816 map (inst_thm ctxt env) axs), map (inst_elem ctxt env) elems); |
815 in map inst (elemss ~~ envs) end; |
817 in map inst (elemss ~~ envs) end; |
816 |
818 |
|
819 (* like unify_elemss, but does not touch axioms, |
|
820 additional parameter for enforcing further constraints (eg. syntax) *) |
|
821 |
|
822 fun unify_elemss' _ _ [] [] = [] |
|
823 | unify_elemss' _ [] [elems] [] = [elems] |
|
824 | unify_elemss' ctxt fixed_parms elemss c_parms = |
|
825 let |
|
826 val envs = unify_parms ctxt fixed_parms (map (#2 o #1 o #1) elemss @ map single c_parms); |
|
827 fun inst ((((name, ps), axs), elems), env) = |
|
828 (((name, map (apsnd (Option.map (inst_type env))) ps), axs), |
|
829 map (inst_elem ctxt env) elems); |
|
830 in map inst (elemss ~~ (Library.take (length elemss, envs))) end; |
|
831 |
817 (* flatten_expr: |
832 (* flatten_expr: |
818 Extend list of identifiers by those new in locale expression expr. |
833 Extend list of identifiers by those new in locale expression expr. |
819 Compute corresponding list of lists of locale elements (one entry per |
834 Compute corresponding list of lists of locale elements (one entry per |
820 identifier). |
835 identifier). |
821 |
836 |
864 identify at top level (top = true); |
879 identify at top level (top = true); |
865 parms is accumulated list of parameters *) |
880 parms is accumulated list of parameters *) |
866 let |
881 let |
867 val {predicate = (_, axioms), import, params, ...} = |
882 val {predicate = (_, axioms), import, params, ...} = |
868 the_locale thy name; |
883 the_locale thy name; |
869 val ps = map #1 (#1 params); |
884 val ps = map (#1 o #1) (#1 params); |
870 val (ids', parms') = identify false import; |
885 val (ids', parms', _) = identify false import; |
871 (* acyclic import dependencies *) |
886 (* acyclic import dependencies *) |
872 val ids'' = ids' @ [((name, ps), ([], []))]; |
887 val ids'' = ids' @ [((name, ps), ([], []))]; |
873 val ids_ax = if top then snd |
888 val ids_ax = if top then snd |
|
889 (* get the right axioms, only if at top level *) |
874 (foldl_map (fn (axs, ((name, parms), _)) => let |
890 (foldl_map (fn (axs, ((name, parms), _)) => let |
875 val {elems, ...} = the_locale thy name; |
891 val {elems, ...} = the_locale thy name; |
876 val ts = List.concat (List.mapPartial (fn (Assumes asms, _) => |
892 val ts = List.concat (List.mapPartial (fn (Assumes asms, _) => |
877 SOME (List.concat (map (map #1 o #2) asms)) | _ => NONE) elems); |
893 SOME (List.concat (map (map #1 o #2) asms)) | _ => NONE) elems); |
878 val (axs1, axs2) = splitAt (length ts, axs); |
894 val (axs1, axs2) = splitAt (length ts, axs); |
879 in (axs2, ((name, parms), (ps, axs1))) end) (axioms, ids'')) |
895 in (axs2, ((name, parms), (ps, axs1))) end) (axioms, ids'')) |
880 else ids''; |
896 else ids''; |
881 in (ids_ax, merge_lists parms' ps) end |
897 val syn = Symtab.make (map (apfst fst) (#1 params)); |
|
898 in (ids_ax, merge_lists parms' ps, syn) end |
882 | identify top (Rename (e, xs)) = |
899 | identify top (Rename (e, xs)) = |
883 let |
900 let |
884 val (ids', parms') = identify top e; |
901 val (ids', parms', syn') = identify top e; |
885 val ren = renaming xs parms' |
902 val ren = renaming xs parms' |
886 handle ERROR_MESSAGE msg => err_in_locale' ctxt msg ids'; |
903 handle ERROR_MESSAGE msg => err_in_locale' ctxt msg ids'; |
887 val ids'' = gen_distinct eq_fst (map (rename_parms top ren) ids'); |
904 val ids'' = gen_distinct eq_fst (map (rename_parms top ren) ids'); |
888 val parms'' = distinct (List.concat (map (#2 o #1) ids'')); |
905 val parms'' = distinct (List.concat (map (#2 o #1) ids'')); |
889 in (ids'', parms'') end |
906 val syn'' = syn' |> Symtab.dest |> map (rename_var ren) |> |
|
907 Symtab.make; |
|
908 (* check for conflicting syntax? *) |
|
909 in (ids'', parms'', syn'') end |
890 | identify top (Merge es) = |
910 | identify top (Merge es) = |
891 Library.foldl (fn ((ids, parms), e) => let |
911 Library.foldl (fn ((ids, parms, syn), e) => let |
892 val (ids', parms') = identify top e |
912 val (ids', parms', syn') = identify top e |
893 in (gen_merge_lists eq_fst ids ids', |
913 in (gen_merge_lists eq_fst ids ids', |
894 merge_lists parms parms') end) |
914 merge_lists parms parms', |
895 (([], []), es); |
915 merge_syntax ctxt ids' (syn, syn')) end) |
|
916 (([], [], Symtab.empty), es); |
896 |
917 |
897 (* CB: enrich identifiers by parameter types and |
918 (* CB: enrich identifiers by parameter types and |
898 the corresponding elements (with renamed parameters) *) |
919 the corresponding elements (with renamed parameters), |
899 |
920 also takes care of parameter syntax *) |
900 fun eval ((name, xs), axs) = |
921 |
|
922 fun eval syn ((name, xs), axs) = |
901 let |
923 let |
902 val {params = (ps, qs), elems, ...} = the_locale thy name; |
924 val {params = (ps, qs), elems, ...} = the_locale thy name; |
903 val ren = filter_out (op =) (map #1 ps ~~ xs); |
925 val ps' = map #1 ps; |
|
926 val ren = map #1 ps' ~~ |
|
927 map (fn x => (x, valOf (Symtab.lookup (syn, x)))) xs; |
904 val (params', elems') = |
928 val (params', elems') = |
905 if null ren then ((ps, qs), map #1 elems) |
929 if null ren then ((ps', qs), map #1 elems) |
906 else ((map (apfst (rename ren)) ps, map (rename ren) qs), |
930 else ((map (apfst (rename ren)) ps', map (rename ren) qs), |
907 map (rename_elem ren o #1) elems); |
931 map (rename_elem ren o #1) elems); |
908 val elems'' = map (rename_facts (space_implode "_" xs)) elems'; |
932 val elems'' = map (rename_facts (space_implode "_" xs)) elems'; |
909 in (((name, params'), axs), elems'') end; |
933 in (((name, params'), axs), elems'') end; |
910 |
934 |
911 (* compute identifiers, merge with previous ones *) |
935 (* type constraint for renamed parameter with syntax *) |
912 val idents = gen_rems eq_fst (#1 (identify true expr), prev_idents); |
936 fun type_syntax NONE = NONE |
|
937 | type_syntax (SOME mx) = let |
|
938 val Ts = map (fn x => TFree (x, [])) (Term.invent_names [] "'mxa" |
|
939 (Syntax.mixfix_args mx + 1)) |
|
940 in Ts |> Library.split_last |> op ---> |> SOME end; |
|
941 |
|
942 (* compute identifiers and syntax, merge with previous ones *) |
|
943 val (ids, _, syn) = identify true expr; |
|
944 val idents = gen_rems eq_fst (ids, prev_idents); |
|
945 val syntax = merge_syntax ctxt ids (syn, prev_syntax); |
913 (* add types to params, check for unique params and unify them *) |
946 (* add types to params, check for unique params and unify them *) |
914 val raw_elemss = unique_parms ctxt (map eval idents); |
947 val raw_elemss = unique_parms ctxt (map (eval syntax) idents); |
915 val elemss = unify_elemss' ctxt [] raw_elemss; |
948 val elemss = unify_elemss' ctxt [] raw_elemss |
|
949 (map (apsnd type_syntax) (Symtab.dest syntax)); |
916 (* replace params in ids by params from axioms, |
950 (* replace params in ids by params from axioms, |
917 adjust types in axioms *) |
951 adjust types in axioms *) |
918 val all_params' = params_of' elemss; |
952 val all_params' = params_of' elemss; |
919 val all_params = param_types all_params'; |
953 val all_params = param_types all_params'; |
920 val elemss' = map (fn (((name, _), (ps, axs)), elems) => |
954 val elemss' = map (fn (((name, _), (ps, axs)), elems) => |
1054 end; |
1088 end; |
1055 |
1089 |
1056 |
1090 |
1057 (* propositions and bindings *) |
1091 (* propositions and bindings *) |
1058 |
1092 |
1059 (* flatten (ids, expr) normalises expr (which is either a locale |
1093 (* flatten ((ids, syn), expr) normalises expr (which is either a locale |
1060 expression or a single context element) wrt. |
1094 expression or a single context element) wrt. |
1061 to the list ids of already accumulated identifiers. |
1095 to the list ids of already accumulated identifiers. |
1062 It returns (ids', elemss) where ids' is an extension of ids |
1096 It returns (ids', syn', elemss) where ids' is an extension of ids |
1063 with identifiers generated for expr, and elemss is the list of |
1097 with identifiers generated for expr, and elemss is the list of |
1064 context elements generated from expr. For details, see flatten_expr. |
1098 context elements generated from expr. |
|
1099 syn and syn' are symtabs mapping parameter names to their syntax. syn' |
|
1100 is an extension of syn. |
|
1101 For details, see flatten_expr. |
|
1102 |
1065 Additionally, for a locale expression, the elems are grouped into a single |
1103 Additionally, for a locale expression, the elems are grouped into a single |
1066 Int; individual context elements are marked Ext. In this case, the |
1104 Int; individual context elements are marked Ext. In this case, the |
1067 identifier-like information of the element is as follows: |
1105 identifier-like information of the element is as follows: |
1068 - for Fixes: (("", ps), []) where the ps have type info NONE |
1106 - for Fixes: (("", ps), []) where the ps have type info NONE |
1069 - for other elements: (("", []), []). |
1107 - for other elements: (("", []), []). |
1070 The implementation of activate_facts relies on identifier names being |
1108 The implementation of activate_facts relies on identifier names being |
1071 empty strings for external elements. |
1109 empty strings for external elements. |
1072 *) |
1110 *) |
1073 |
1111 |
1074 fun flatten _ (ids, Elem (Fixes fixes)) = |
1112 fun flatten (ctxt, _) ((ids, syn), Elem (Fixes fixes)) = let |
1075 (ids @ [(("", map #1 fixes), ([], []))], [((("", map (rpair NONE o #1) fixes), []), Ext (Fixes fixes))]) |
1113 val ids' = ids @ [(("", map #1 fixes), ([], []))] |
1076 | flatten _ (ids, Elem elem) = (ids @ [(("", []), ([], []))], [((("", []), []), Ext elem)]) |
1114 in |
1077 | flatten (ctxt, prep_expr) (ids, Expr expr) = |
1115 ((ids', |
1078 apsnd (map (apsnd Int)) (flatten_expr ctxt (ids, prep_expr expr)); |
1116 merge_syntax ctxt ids' |
|
1117 (syn, Symtab.make (map (fn fx => (#1 fx, #3 fx)) fixes)) |
|
1118 handle Symtab.DUPS xs => err_in_locale ctxt |
|
1119 ("Conflicting syntax for parameters: " ^ commas_quote xs) |
|
1120 (map #1 ids')), |
|
1121 [((("", map (rpair NONE o #1) fixes), []), Ext (Fixes fixes))]) |
|
1122 end |
|
1123 | flatten _ ((ids, syn), Elem elem) = |
|
1124 ((ids @ [(("", []), ([], []))], syn), [((("", []), []), Ext elem)]) |
|
1125 | flatten (ctxt, prep_expr) ((ids, syn), Expr expr) = |
|
1126 apsnd (map (apsnd Int)) (flatten_expr ctxt ((ids, syn), prep_expr expr)); |
1079 |
1127 |
1080 local |
1128 local |
1081 |
1129 |
1082 local |
1130 local |
|
1131 |
|
1132 (* paramify type, process mixfix constraint of renamed syntax *) |
|
1133 |
|
1134 fun mx_type _ (x, NONE, mx) = (x, NONE, mx) |
|
1135 | mx_type _ (x, SOME T, NONE) = |
|
1136 (x, SOME (Term.map_type_tfree (TypeInfer.param 0) T), NONE) |
|
1137 | mx_type ctxt (x, SOME T, SOME mx) = |
|
1138 let |
|
1139 val _ = warning "mx_type: mx"; |
|
1140 val _ = PolyML.print mx; |
|
1141 val tsig = Sign.tsig_of (ProofContext.sign_of ctxt); |
|
1142 val T' = Type.varifyT T; |
|
1143 val mxTs = map (fn n => TVar ((n, 0), [])) |
|
1144 (Term.invent_names (Term.add_typ_tfree_names (T, [])) "'a" |
|
1145 (Syntax.mixfix_args mx + 1)); |
|
1146 (* avoid name clashes in unification *) |
|
1147 val mxT = mxTs |> Library.split_last |> op --->; |
|
1148 val (tenv, _) = Type.unify tsig (Vartab.empty, 0) (T', mxT) |
|
1149 handle Type.TUNIFY => |
|
1150 raise TYPE ("failed to satisfy mixfix-constraint for parameter " ^ |
|
1151 quote x ^ "\nunable to unify", [T', mxT], []); |
|
1152 val U = Envir.norm_type tenv T'; |
|
1153 val ixns = Term.add_typ_ixns ([], U); |
|
1154 val ren = Vartab.make (ixns ~~ Term.invent_names [] "'a" (length ixns)); |
|
1155 val U' = Term.map_type_tvar (fn ((x, i), s) => |
|
1156 (TypeInfer.param 0 (x, s))) U; |
|
1157 (* val U' = Term.map_type_tvar (fn (xi, s) => |
|
1158 (TypeInfer.param 0 (valOf (Vartab.lookup (ren, xi)), s))) U; |
|
1159 *)val _ = warning "mx_type (U, U')"; |
|
1160 val _ = PolyML.print (U, U'); |
|
1161 in (x, SOME U', SOME mx) end; |
1083 |
1162 |
1084 fun declare_int_elem (ctxt, Fixes fixes) = |
1163 fun declare_int_elem (ctxt, Fixes fixes) = |
1085 (ctxt |> ProofContext.add_fixes (map (fn (x, T, mx) => |
1164 (ctxt |> ProofContext.add_fixes (map (fn (x, T, mx) => |
1086 (x, Option.map (Term.map_type_tfree (TypeInfer.param 0)) T, mx)) fixes), []) |
1165 (x, Option.map (Term.map_type_tfree (TypeInfer.param 0)) T, mx)) fixes), []) |
1087 | declare_int_elem (ctxt, _) = (ctxt, []); |
1166 | declare_int_elem (ctxt, _) = (ctxt, []); |
1340 fun prep_context_statement prep_expr prep_elemss prep_facts |
1419 fun prep_context_statement prep_expr prep_elemss prep_facts |
1341 do_close fixed_params import elements raw_concl context = |
1420 do_close fixed_params import elements raw_concl context = |
1342 let |
1421 let |
1343 val sign = ProofContext.sign_of context; |
1422 val sign = ProofContext.sign_of context; |
1344 |
1423 |
1345 val (import_ids, raw_import_elemss) = flatten (context, prep_expr sign) ([], Expr import); |
1424 val ((import_ids, import_syn), raw_import_elemss) = flatten (context, prep_expr sign) (([], Symtab.empty), Expr import); |
1346 (* CB: normalise "includes" among elements *) |
1425 (* CB: normalise "includes" among elements *) |
1347 val (ids, raw_elemsss) = foldl_map (flatten (context, prep_expr sign)) |
1426 val ((ids, syn), raw_elemsss) = foldl_map (flatten (context, prep_expr sign)) |
1348 (import_ids, elements); |
1427 ((import_ids, import_syn), elements); |
1349 |
1428 |
1350 val raw_elemss = List.concat raw_elemsss; |
1429 val raw_elemss = List.concat raw_elemsss; |
1351 (* CB: raw_import_elemss @ raw_elemss is the normalised list of |
1430 (* CB: raw_import_elemss @ raw_elemss is the normalised list of |
1352 context elements obtained from import and elements. *) |
1431 context elements obtained from import and elements. *) |
1353 val ((parms, all_elemss, concl), (spec, (_, _, defs))) = prep_elemss do_close |
1432 val ((parms, all_elemss, concl), (spec, (_, _, defs))) = prep_elemss do_close |
1415 |
1494 |
1416 (** process the locale **) |
1495 (** process the locale **) |
1417 |
1496 |
1418 val {predicate = (_, axioms), params = (ps, _), ...} = |
1497 val {predicate = (_, axioms), params = (ps, _), ...} = |
1419 the_locale thy (intern sign loc_name); |
1498 the_locale thy (intern sign loc_name); |
1420 val fixed_params = param_types ps; |
1499 val fixed_params = param_types (map #1 ps); |
1421 val init = ProofContext.init thy; |
1500 val init = ProofContext.init thy; |
1422 val (_, raw_elemss) = |
1501 val (_, raw_elemss) = flatten (init, intern_expr sign) |
1423 flatten (init, intern_expr sign) ([], Expr (Locale loc_name)); |
1502 (([], Symtab.empty), Expr (Locale loc_name)); |
1424 val ((parms, all_elemss, concl), |
1503 val ((parms, all_elemss, concl), |
1425 (spec as (_, (ints, _)), (xs, env, defs))) = |
1504 (spec as (_, (ints, _)), (xs, env, defs))) = |
1426 read_elemss false (* do_close *) init |
1505 read_elemss false (* do_close *) init |
1427 fixed_params (* could also put [] here??? *) raw_elemss |
1506 fixed_params (* could also put [] here??? *) raw_elemss |
1428 [] (* concl *); |
1507 [] (* concl *); |