237 |
237 |
238 |
238 |
239 |
239 |
240 (** local syntax **) |
240 (** local syntax **) |
241 |
241 |
242 val fixedN = "\\<^fixed>"; |
|
243 val structN = "\\<^struct>"; |
|
244 |
|
245 |
|
246 (* translation functions *) |
242 (* translation functions *) |
247 |
|
248 fun fixed_tr x = (fixedN ^ x, curry Term.list_comb (Syntax.free x)); |
|
249 |
243 |
250 fun context_tr' ctxt = |
244 fun context_tr' ctxt = |
251 let |
245 let |
252 val (_, structs, mixfixed) = syntax_of ctxt; |
246 val (_, structs, mixfixed) = syntax_of ctxt; |
253 |
247 |
254 fun tr' (t $ u) = tr' t $ tr' u |
248 fun tr' (t $ u) = tr' t $ tr' u |
255 | tr' (Abs (x, T, t)) = Abs (x, T, tr' t) |
249 | tr' (Abs (x, T, t)) = Abs (x, T, tr' t) |
256 | tr' (t as Free (x, T)) = |
250 | tr' (t as Free (x, T)) = |
257 let val i = Library.find_index_eq x structs + 1 in |
251 let val i = Library.find_index_eq x structs + 1 in |
258 if i = 0 andalso x mem_string mixfixed then Const (fixedN ^ x, T) |
252 if i = 0 andalso member (op =) mixfixed x then Const (Syntax.fixedN ^ x, T) |
259 else if i = 1 andalso not (! show_structs) then |
253 else if i = 1 andalso not (! show_structs) then |
260 Syntax.const "_struct" $ Syntax.const "_indexdefault" |
254 Syntax.const "_struct" $ Syntax.const "_indexdefault" |
261 else t |
255 else t |
262 end |
256 end |
263 | tr' a = a; |
257 | tr' a = a; |
264 in tr' end; |
258 in tr' end; |
265 |
259 |
266 |
260 |
267 (* add syntax *) |
261 (* add syntax *) |
268 |
262 |
269 fun mixfix_type mx = replicate (Syntax.mixfix_args mx) TypeInfer.logicT ---> TypeInfer.logicT; |
|
270 |
|
271 local |
263 local |
272 |
264 |
273 fun mixfix x NONE mx = (fixedN ^ x, mixfix_type mx, Syntax.fix_mixfix x mx) |
265 fun mixfix x NONE mx = (Syntax.fixedN ^ x, TypeInfer.mixfixT mx, Syntax.fix_mixfix x mx) |
274 | mixfix x (SOME T) mx = (fixedN ^ x, T, Syntax.fix_mixfix x mx); |
266 | mixfix x (SOME T) mx = (Syntax.fixedN ^ x, T, Syntax.fix_mixfix x mx); |
275 |
267 |
276 fun prep_mixfix (_, _, NONE) = NONE |
268 fun prep_mixfix (_, _, NONE) = NONE |
277 | prep_mixfix (x, opt_T, SOME mx) = SOME (mixfix x opt_T mx); |
269 | prep_mixfix (x, opt_T, SOME mx) = SOME (mixfix x opt_T mx); |
278 |
270 |
279 fun prep_mixfix' (_, _, NONE) = NONE |
271 fun prep_mixfix' (_, _, NONE) = NONE |
304 |
296 |
305 val is_logtype = Sign.is_logtype thy; |
297 val is_logtype = Sign.is_logtype thy; |
306 val structs' = structs @ List.mapPartial prep_struct decls; |
298 val structs' = structs @ List.mapPartial prep_struct decls; |
307 val mxs = List.mapPartial prep_mixfix decls; |
299 val mxs = List.mapPartial prep_mixfix decls; |
308 val (fixed, mxs_output) = Library.split_list (List.mapPartial prep_mixfix' decls); |
300 val (fixed, mxs_output) = Library.split_list (List.mapPartial prep_mixfix' decls); |
309 val trs = map fixed_tr fixed; |
|
310 |
301 |
311 val extend = |
302 val extend = |
312 Syntax.extend_const_gram is_logtype ("", false) mxs_output |
303 Syntax.extend_const_gram is_logtype ("", false) mxs_output |
313 #> Syntax.extend_const_gram is_logtype ("", true) mxs |
304 #> Syntax.extend_const_gram is_logtype ("", true) mxs; |
314 #> Syntax.extend_trfuns ([], mk trs, [], []); |
|
315 val syns' = extend_syntax thy extend syns; |
305 val syns' = extend_syntax thy extend syns; |
316 in ((syns', structs', fixed @ mixfixed), asms, binds, thms, cases, defs) end); |
306 in ((syns', structs', fixed @ mixfixed), asms, binds, thms, cases, defs) end); |
317 |
307 |
318 fun syn_of' thy ctxt = |
308 fun syn_of' thy ctxt = |
319 let |
309 let |
638 fun map_defaults f = map_context (fn (syntax, asms, binds, thms, cases, defs) => |
628 fun map_defaults f = map_context (fn (syntax, asms, binds, thms, cases, defs) => |
639 (syntax, asms, binds, thms, cases, f defs)); |
629 (syntax, asms, binds, thms, cases, f defs)); |
640 |
630 |
641 in |
631 in |
642 |
632 |
643 fun declare_term_syntax t ctxt = |
633 fun declare_term_syntax t = |
644 ctxt |
634 map_defaults (fn (types, sorts, used, occ) => (ins_types t types, sorts, used, occ)) |
645 |> map_defaults (fn (types, sorts, used, occ) => (ins_types t types, sorts, used, occ)) |
635 #> map_defaults (fn (types, sorts, used, occ) => (types, ins_sorts t sorts, used, occ)) |
646 |> map_defaults (fn (types, sorts, used, occ) => (types, ins_sorts t sorts, used, occ)) |
636 #> map_defaults (fn (types, sorts, used, occ) => (types, sorts, ins_used t used, occ)); |
647 |> map_defaults (fn (types, sorts, used, occ) => (types, sorts, ins_used t used, occ)); |
|
648 |
637 |
649 fun declare_term t ctxt = |
638 fun declare_term t ctxt = |
650 ctxt |
639 ctxt |
651 |> declare_term_syntax t |
640 |> declare_term_syntax t |
652 |> map_defaults (fn (types, sorts, used, occ) => (types, sorts, used, ins_occs t occ)) |
641 |> map_defaults (fn (types, sorts, used, occ) => (types, sorts, used, ins_occs t occ)) |
658 |
647 |
659 |
648 |
660 (* type and constant names *) |
649 (* type and constant names *) |
661 |
650 |
662 fun read_tyname ctxt c = |
651 fun read_tyname ctxt c = |
663 if c mem_string used_types ctxt then |
652 if member (op =) (used_types ctxt) c then |
664 TFree (c, the_default (Sign.defaultS (theory_of ctxt)) (def_sort ctxt (c, ~1))) |
653 TFree (c, the_default (Sign.defaultS (theory_of ctxt)) (def_sort ctxt (c, ~1))) |
665 else Sign.read_tyname (theory_of ctxt) c; |
654 else Sign.read_tyname (theory_of ctxt) c; |
666 |
655 |
667 fun read_const ctxt c = |
656 fun read_const ctxt c = |
668 (case lookup_skolem ctxt c of |
657 (case lookup_skolem ctxt c of |
702 (* generalize type variables *) |
691 (* generalize type variables *) |
703 |
692 |
704 fun generalize_tfrees inner outer = |
693 fun generalize_tfrees inner outer = |
705 let |
694 let |
706 val extra_fixes = fixed_names_of inner \\ fixed_names_of outer; |
695 val extra_fixes = fixed_names_of inner \\ fixed_names_of outer; |
707 fun still_fixed (Free (x, _)) = not (x mem_string extra_fixes) |
696 fun still_fixed (Free (x, _)) = not (member (op =) extra_fixes x) |
708 | still_fixed _ = false; |
697 | still_fixed _ = false; |
709 val occs_inner = type_occs_of inner; |
698 val occs_inner = type_occs_of inner; |
710 val occs_outer = type_occs_of outer; |
699 val occs_outer = type_occs_of outer; |
711 fun add a gen = |
700 fun add a gen = |
712 if Symtab.defined occs_outer a orelse |
701 if Symtab.defined occs_outer a orelse |
715 in fn tfrees => fold add tfrees [] end; |
704 in fn tfrees => fold add tfrees [] end; |
716 |
705 |
717 fun generalize inner outer ts = |
706 fun generalize inner outer ts = |
718 let |
707 let |
719 val tfrees = generalize_tfrees inner outer (map #1 (fold Term.add_tfrees ts [])); |
708 val tfrees = generalize_tfrees inner outer (map #1 (fold Term.add_tfrees ts [])); |
720 fun gen (x, S) = if x mem_string tfrees then TVar ((x, 0), S) else TFree (x, S); |
709 fun gen (x, S) = if member (op =) tfrees x then TVar ((x, 0), S) else TFree (x, S); |
721 in map (Term.map_term_types (Term.map_type_tfree gen)) ts end; |
710 in map (Term.map_term_types (Term.map_type_tfree gen)) ts end; |
722 |
711 |
723 |
712 |
724 |
713 |
725 (** export theorems **) |
714 (** export theorems **) |
1088 (syntax, (assumes, f fixes), binds, thms, cases, defs)); |
1077 (syntax, (assumes, f fixes), binds, thms, cases, defs)); |
1089 |
1078 |
1090 fun err_dups ctxt xs = raise CONTEXT ("Duplicate variable(s): " ^ commas_quote xs, ctxt); |
1079 fun err_dups ctxt xs = raise CONTEXT ("Duplicate variable(s): " ^ commas_quote xs, ctxt); |
1091 |
1080 |
1092 val declare = |
1081 val declare = |
1093 fold declare_term_syntax o |
1082 List.mapPartial (fn (_, NONE) => NONE | (x, SOME T) => SOME (Free (x, T))) |
1094 List.mapPartial (fn (_, NONE) => NONE | (x, SOME T) => SOME (Free (x, T))); |
1083 #> fold declare_term_syntax; |
1095 |
1084 |
1096 fun add_vars xs Ts ctxt = |
1085 fun add_vars xs Ts ctxt = |
1097 let val xs' = Term.variantlist (map Syntax.skolem xs, map #2 (fixes_of ctxt)) in |
1086 let val xs' = Term.variantlist (map Syntax.skolem xs, map #2 (fixes_of ctxt)) in |
1098 ctxt |
1087 ctxt |
1099 |> declare (xs' ~~ Ts) |
1088 |> declare (xs' ~~ Ts) |
1118 in |
1107 in |
1119 (case Library.duplicates xs of [] => () | dups => err_dups ctxt dups); |
1108 (case Library.duplicates xs of [] => () | dups => err_dups ctxt dups); |
1120 ctxt' |> add xs Ts |
1109 ctxt' |> add xs Ts |
1121 end; |
1110 end; |
1122 |
1111 |
1123 fun prep_type (x, NONE, SOME mx) = ([x], SOME (mixfix_type mx)) |
1112 fun prep_type (x, NONE, SOME mx) = ([x], SOME (TypeInfer.mixfixT mx)) |
1124 | prep_type (x, opt_T, _) = ([x], opt_T); |
1113 | prep_type (x, opt_T, _) = ([x], opt_T); |
1125 |
1114 |
1126 in |
1115 in |
1127 |
1116 |
1128 val fix = gen_fix read_vars add_vars; |
1117 val fix = gen_fix read_vars add_vars; |
1148 (*Note: improper use may result in variable capture / dynamic scoping!*) |
1137 (*Note: improper use may result in variable capture / dynamic scoping!*) |
1149 fun bind_skolem ctxt xs = |
1138 fun bind_skolem ctxt xs = |
1150 let |
1139 let |
1151 val ctxt' = ctxt |> fix_i [(xs, NONE)]; |
1140 val ctxt' = ctxt |> fix_i [(xs, NONE)]; |
1152 fun bind (t as Free (x, T)) = |
1141 fun bind (t as Free (x, T)) = |
1153 if x mem_string xs then |
1142 if member (op =) xs x then |
1154 (case lookup_skolem ctxt' x of SOME x' => Free (x', T) | NONE => t) |
1143 (case lookup_skolem ctxt' x of SOME x' => Free (x', T) | NONE => t) |
1155 else t |
1144 else t |
1156 | bind (t $ u) = bind t $ bind u |
1145 | bind (t $ u) = bind t $ bind u |
1157 | bind (Abs (x, T, t)) = Abs (x, T, bind t) |
1146 | bind (Abs (x, T, t)) = Abs (x, T, bind t) |
1158 | bind a = a; |
1147 | bind a = a; |
1219 let |
1208 let |
1220 fun err msg = raise CONTEXT (msg ^ |
1209 fun err msg = raise CONTEXT (msg ^ |
1221 "\nThe error(s) above occurred in local definition: " ^ string_of_term ctxt eq, ctxt); |
1210 "\nThe error(s) above occurred in local definition: " ^ string_of_term ctxt eq, ctxt); |
1222 val (lhs, rhs) = Logic.dest_equals (Term.strip_all_body eq) |
1211 val (lhs, rhs) = Logic.dest_equals (Term.strip_all_body eq) |
1223 handle TERM _ => err "Not a meta-equality (==)"; |
1212 handle TERM _ => err "Not a meta-equality (==)"; |
1224 val (f, xs) = Term.strip_comb lhs; |
1213 val (f, xs) = Term.strip_comb (Pattern.beta_eta_contract lhs); |
1225 val (c, _) = Term.dest_Free f handle TERM _ => |
1214 val (c, _) = Term.dest_Free f handle TERM _ => |
1226 err "Head of lhs must be a free/fixed variable"; |
1215 err "Head of lhs must be a free/fixed variable"; |
1227 |
1216 |
1228 fun is_free (Free (x, _)) = not (is_fixed ctxt x) |
1217 fun is_free (Free (x, _)) = not (is_fixed ctxt x) |
1229 | is_free _ = false; |
1218 | is_free _ = false; |
1413 |
1402 |
1414 (*fixes*) |
1403 (*fixes*) |
1415 fun prt_fix (x, x') = |
1404 fun prt_fix (x, x') = |
1416 if x = x' then Pretty.str x |
1405 if x = x' then Pretty.str x |
1417 else Pretty.block [Pretty.str x, Pretty.str " =", Pretty.brk 1, prt_term (Syntax.free x')]; |
1406 else Pretty.block [Pretty.str x, Pretty.str " =", Pretty.brk 1, prt_term (Syntax.free x')]; |
1418 val fixes = rev (filter_out |
1407 val fixes = |
1419 ((can Syntax.dest_internal o #1) orf (fn (_, x') => x' mem_string structs)) (fixes_of ctxt)); |
1408 rev (filter_out ((can Syntax.dest_internal orf member (op =) structs) o #1) (fixes_of ctxt)); |
1420 val prt_fixes = if null fixes then [] |
1409 val prt_fixes = if null fixes then [] |
1421 else [Pretty.block (Pretty.str "fixed variables:" :: Pretty.brk 1 :: |
1410 else [Pretty.block (Pretty.str "fixed variables:" :: Pretty.brk 1 :: |
1422 Pretty.commas (map prt_fix fixes))]; |
1411 Pretty.commas (map prt_fix fixes))]; |
1423 |
1412 |
1424 (*prems*) |
1413 (*prems*) |