src/Pure/Isar/proof_context.ML
changeset 18340 3fdff270aa04
parent 18310 b00c9120f6bd
child 18375 99deeed095ae
equal deleted inserted replaced
18339:64cb06a0bb50 18340:3fdff270aa04
   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*)