1 (* Title: Pure/Isar/proof_context.ML |
1 (* Title: Pure/Isar/proof_context.ML |
2 ID: $Id$ |
2 ID: $Id$ |
3 Author: Markus Wenzel, TU Muenchen |
3 Author: Markus Wenzel, TU Muenchen |
4 contributions by Rafal Kolanski, NICTA |
|
5 |
4 |
6 The key concept of Isar proof contexts. |
5 The key concept of Isar proof contexts. |
7 *) |
6 *) |
8 |
7 |
9 val show_structs = ref false; |
8 val show_structs = ref false; |
222 |
221 |
223 fun fixes_of (Context {asms = (_, fixes), ...}) = fixes; |
222 fun fixes_of (Context {asms = (_, fixes), ...}) = fixes; |
224 val fixed_names_of = map #2 o fixes_of; |
223 val fixed_names_of = map #2 o fixes_of; |
225 fun is_fixed ctxt x = exists (equal x o #2) (fixes_of ctxt); |
224 fun is_fixed ctxt x = exists (equal x o #2) (fixes_of ctxt); |
226 fun is_known (ctxt as Context {defs = (types, _, _, _), ...}) x = |
225 fun is_known (ctxt as Context {defs = (types, _, _, _), ...}) x = |
227 isSome (Vartab.lookup (types, (x, ~1))) orelse is_fixed ctxt x; |
226 is_some (Vartab.lookup (types, (x, ~1))) orelse is_fixed ctxt x; |
228 fun type_occs (Context {defs = (_, _, _, tab), ...}) = tab; |
227 fun type_occs (Context {defs = (_, _, _, tab), ...}) = tab; |
229 |
228 |
230 fun assumptions_of (Context {asms = ((asms, _), _), ...}) = asms; |
229 fun assumptions_of (Context {asms = ((asms, _), _), ...}) = asms; |
231 fun prems_of (Context {asms = ((_, prems), _), ...}) = List.concat (map #2 prems); |
230 fun prems_of (Context {asms = ((_, prems), _), ...}) = List.concat (map #2 prems); |
232 |
231 |
469 |
468 |
470 |
469 |
471 (* internalize Skolem constants *) |
470 (* internalize Skolem constants *) |
472 |
471 |
473 fun lookup_skolem ctxt x = assoc (fixes_of ctxt, x); |
472 fun lookup_skolem ctxt x = assoc (fixes_of ctxt, x); |
474 fun get_skolem ctxt x = getOpt (lookup_skolem ctxt x, x); |
473 fun get_skolem ctxt x = if_none (lookup_skolem ctxt x) x; |
475 |
474 |
476 fun no_skolem internal ctxt x = |
475 fun no_skolem internal ctxt x = |
477 if can Syntax.dest_skolem x then |
476 if can Syntax.dest_skolem x then |
478 raise CONTEXT ("Illegal reference to internal Skolem constant: " ^ quote x, ctxt) |
477 raise CONTEXT ("Illegal reference to internal Skolem constant: " ^ quote x, ctxt) |
479 else if not internal andalso can Syntax.dest_internal x then |
478 else if not internal andalso can Syntax.dest_internal x then |
711 |
710 |
712 (* type and constant names *) |
711 (* type and constant names *) |
713 |
712 |
714 fun read_tyname ctxt c = |
713 fun read_tyname ctxt c = |
715 if c mem_string used_types ctxt then |
714 if c mem_string used_types ctxt then |
716 TFree (c, getOpt (def_sort ctxt (c, ~1), Sign.defaultS (sign_of ctxt))) |
715 TFree (c, if_none (def_sort ctxt (c, ~1)) (Sign.defaultS (sign_of ctxt))) |
717 else Sign.read_tyname (sign_of ctxt) c; |
716 else Sign.read_tyname (sign_of ctxt) c; |
718 |
717 |
719 fun read_const ctxt c = |
718 fun read_const ctxt c = |
720 (case lookup_skolem ctxt c of |
719 (case lookup_skolem ctxt c of |
721 SOME c' => Free (c', dummyT) |
720 SOME c' => Free (c', dummyT) |
759 fun still_fixed (Free (x, _)) = not (x mem_string extra_fixes) |
758 fun still_fixed (Free (x, _)) = not (x mem_string extra_fixes) |
760 | still_fixed _ = false; |
759 | still_fixed _ = false; |
761 val occs_inner = type_occs inner; |
760 val occs_inner = type_occs inner; |
762 val occs_outer = type_occs outer; |
761 val occs_outer = type_occs outer; |
763 fun add (gen, a) = |
762 fun add (gen, a) = |
764 if isSome (Symtab.lookup (occs_outer, a)) orelse |
763 if is_some (Symtab.lookup (occs_outer, a)) orelse |
765 exists still_fixed (Symtab.lookup_multi (occs_inner, a)) |
764 exists still_fixed (Symtab.lookup_multi (occs_inner, a)) |
766 then gen else a :: gen; |
765 then gen else a :: gen; |
767 in fn tfrees => Library.foldl add ([], tfrees) end; |
766 in fn tfrees => Library.foldl add ([], tfrees) end; |
768 |
767 |
769 fun generalize inner outer ts = |
768 fun generalize inner outer ts = |
1182 val _ = if liberal then () else |
1181 val _ = if liberal then () else |
1183 (case List.filter (not o Syntax.is_identifier) (map (no_skolem internal ctxt) xs) of |
1182 (case List.filter (not o Syntax.is_identifier) (map (no_skolem internal ctxt) xs) of |
1184 [] => () | bads => raise CONTEXT ("Bad variable name(s): " ^ commas_quote bads, ctxt)); |
1183 [] => () | bads => raise CONTEXT ("Bad variable name(s): " ^ commas_quote bads, ctxt)); |
1185 |
1184 |
1186 val opt_T = Option.map (cond_tvars o prep_typ ctxt) raw_T; |
1185 val opt_T = Option.map (cond_tvars o prep_typ ctxt) raw_T; |
1187 val T = getOpt (opt_T, TypeInfer.logicT); |
1186 val T = if_none opt_T TypeInfer.logicT; |
1188 val ctxt' = ctxt |> declare_terms_syntax (map (fn x => Free (x, T)) xs); |
1187 val ctxt' = ctxt |> declare_terms_syntax (map (fn x => Free (x, T)) xs); |
1189 in (ctxt', (xs, opt_T)) end; |
1188 in (ctxt', (xs, opt_T)) end; |
1190 |
1189 |
1191 in |
1190 in |
1192 |
1191 |
1278 |
1277 |
1279 (** cases **) |
1278 (** cases **) |
1280 |
1279 |
1281 fun prep_case ctxt name xs {fixes, assumes, binds} = |
1280 fun prep_case ctxt name xs {fixes, assumes, binds} = |
1282 let |
1281 let |
1283 fun replace (opt_x :: xs) ((y, T) :: ys) = (getOpt (opt_x,y), T) :: replace xs ys |
1282 fun replace (opt_x :: xs) ((y, T) :: ys) = (if_none opt_x y, T) :: replace xs ys |
1284 | replace [] ys = ys |
1283 | replace [] ys = ys |
1285 | replace (_ :: _) [] = raise CONTEXT ("Too many parameters for case " ^ quote name, ctxt); |
1284 | replace (_ :: _) [] = raise CONTEXT ("Too many parameters for case " ^ quote name, ctxt); |
1286 in |
1285 in |
1287 if null (foldr Term.add_typ_tvars [] (map snd fixes)) andalso |
1286 if null (foldr Term.add_typ_tvars [] (map snd fixes)) andalso |
1288 null (foldr Term.add_term_vars [] (List.concat (map snd assumes))) then |
1287 null (foldr Term.add_term_vars [] (List.concat (map snd assumes))) then |
1617 val matches2 = PureThy.find_theorems facts2 filters2; |
1616 val matches2 = PureThy.find_theorems facts2 filters2; |
1618 |
1617 |
1619 (* combine them, use a limit, then print *) |
1618 (* combine them, use a limit, then print *) |
1620 val matches = matches1 @ matches2; |
1619 val matches = matches1 @ matches2; |
1621 val len = length matches; |
1620 val len = length matches; |
1622 val limit = getOpt (opt_limit, ! thms_containing_limit); |
1621 val limit = if_none opt_limit (! thms_containing_limit); |
1623 val count = Int.min (limit, len); |
1622 val count = Int.min (limit, len); |
1624 |
1623 |
1625 val header = Pretty.blk (0, [Pretty.str "Searched for:", Pretty.fbrk, |
1624 val header = Pretty.blk (0, [Pretty.str "Searched for:", Pretty.fbrk, |
1626 Pretty.indent 4 ( |
1625 Pretty.indent 4 ( |
1627 Pretty.blk (0, separate Pretty.fbrk (map Pretty.str ss))), |
1626 Pretty.blk (0, separate Pretty.fbrk (map Pretty.str ss))), |