src/Pure/variable.ML
changeset 42488 4638622bcaa1
parent 42482 42c7ef050bc3
child 42493 01430341fc79
equal deleted inserted replaced
42487:398d7d6bba42 42488:4638622bcaa1
     8 sig
     8 sig
     9   val is_body: Proof.context -> bool
     9   val is_body: Proof.context -> bool
    10   val set_body: bool -> Proof.context -> Proof.context
    10   val set_body: bool -> Proof.context -> Proof.context
    11   val restore_body: Proof.context -> Proof.context -> Proof.context
    11   val restore_body: Proof.context -> Proof.context -> Proof.context
    12   val names_of: Proof.context -> Name.context
    12   val names_of: Proof.context -> Name.context
    13   val fixes_of: Proof.context -> (string * string) list
       
    14   val binds_of: Proof.context -> (typ * term) Vartab.table
    13   val binds_of: Proof.context -> (typ * term) Vartab.table
    15   val maxidx_of: Proof.context -> int
    14   val maxidx_of: Proof.context -> int
    16   val sorts_of: Proof.context -> sort list
    15   val sorts_of: Proof.context -> sort list
    17   val constraints_of: Proof.context -> typ Vartab.table * sort Vartab.table
    16   val constraints_of: Proof.context -> typ Vartab.table * sort Vartab.table
    18   val is_declared: Proof.context -> string -> bool
    17   val is_declared: Proof.context -> string -> bool
    19   val is_fixed: Proof.context -> string -> bool
       
    20   val newly_fixed: Proof.context -> Proof.context -> string -> bool
       
    21   val name: binding -> string
    18   val name: binding -> string
    22   val default_type: Proof.context -> string -> typ option
    19   val default_type: Proof.context -> string -> typ option
    23   val def_type: Proof.context -> bool -> indexname -> typ option
    20   val def_type: Proof.context -> bool -> indexname -> typ option
    24   val def_sort: Proof.context -> indexname -> sort option
    21   val def_sort: Proof.context -> indexname -> sort option
    25   val declare_names: term -> Proof.context -> Proof.context
    22   val declare_names: term -> Proof.context -> Proof.context
    33   val bind_term: indexname * term option -> Proof.context -> Proof.context
    30   val bind_term: indexname * term option -> Proof.context -> Proof.context
    34   val expand_binds: Proof.context -> term -> term
    31   val expand_binds: Proof.context -> term -> term
    35   val lookup_const: Proof.context -> string -> string option
    32   val lookup_const: Proof.context -> string -> string option
    36   val is_const: Proof.context -> string -> bool
    33   val is_const: Proof.context -> string -> bool
    37   val declare_const: string * string -> Proof.context -> Proof.context
    34   val declare_const: string * string -> Proof.context -> Proof.context
       
    35   val fixed_ord: Proof.context -> string * string -> order
       
    36   val is_fixed: Proof.context -> string -> bool
       
    37   val newly_fixed: Proof.context -> Proof.context -> string -> bool
       
    38   val intern_fixed: Proof.context -> string -> string
       
    39   val lookup_fixed: Proof.context -> string -> string option
       
    40   val revert_fixed: Proof.context -> string -> string
    38   val add_fixed_names: Proof.context -> term -> string list -> string list
    41   val add_fixed_names: Proof.context -> term -> string list -> string list
    39   val add_fixed: Proof.context -> term -> (string * typ) list -> (string * typ) list
    42   val add_fixed: Proof.context -> term -> (string * typ) list -> (string * typ) list
    40   val add_free_names: Proof.context -> term -> string list -> string list
    43   val add_free_names: Proof.context -> term -> string list -> string list
    41   val add_frees: Proof.context -> term -> (string * typ) list -> (string * typ) list
    44   val add_frees: Proof.context -> term -> (string * typ) list -> (string * typ) list
       
    45   val add_fixes_binding: binding list -> Proof.context -> string list * Proof.context
    42   val add_fixes: string list -> Proof.context -> string list * Proof.context
    46   val add_fixes: string list -> Proof.context -> string list * Proof.context
    43   val add_fixes_direct: string list -> Proof.context -> Proof.context
    47   val add_fixes_direct: string list -> Proof.context -> Proof.context
    44   val auto_fixes: term -> Proof.context -> Proof.context
    48   val auto_fixes: term -> Proof.context -> Proof.context
    45   val variant_fixes: string list -> Proof.context -> string list * Proof.context
    49   val variant_fixes: string list -> Proof.context -> string list * Proof.context
       
    50   val dest_fixes: Proof.context -> (string * string) list
    46   val invent_types: sort list -> Proof.context -> (string * sort) list * Proof.context
    51   val invent_types: sort list -> Proof.context -> (string * sort) list * Proof.context
    47   val export_terms: Proof.context -> Proof.context -> term list -> term list
    52   val export_terms: Proof.context -> Proof.context -> term list -> term list
    48   val exportT_terms: Proof.context -> Proof.context -> term list -> term list
    53   val exportT_terms: Proof.context -> Proof.context -> term list -> term list
    49   val exportT: Proof.context -> Proof.context -> thm list -> thm list
    54   val exportT: Proof.context -> Proof.context -> thm list -> thm list
    50   val export_prf: Proof.context -> Proof.context -> Proofterm.proof -> Proofterm.proof
    55   val export_prf: Proof.context -> Proof.context -> Proofterm.proof -> Proofterm.proof
    71 structure Variable: VARIABLE =
    76 structure Variable: VARIABLE =
    72 struct
    77 struct
    73 
    78 
    74 (** local context data **)
    79 (** local context data **)
    75 
    80 
       
    81 type fixes = string Name_Space.table;
       
    82 val empty_fixes: fixes = Name_Space.empty_table "fixed variable";
       
    83 
    76 datatype data = Data of
    84 datatype data = Data of
    77  {is_body: bool,                        (*inner body mode*)
    85  {is_body: bool,                        (*inner body mode*)
    78   names: Name.context,                  (*type/term variable names*)
    86   names: Name.context,                  (*type/term variable names*)
    79   consts: string Symtab.table,          (*consts within the local scope*)
    87   consts: string Symtab.table,          (*consts within the local scope*)
    80   fixes: (string * string) list,        (*term fixes -- extern/intern*)
    88   fixes: fixes,                         (*term fixes -- global name space, intern ~> extern*)
    81   binds: (typ * term) Vartab.table,     (*term bindings*)
    89   binds: (typ * term) Vartab.table,     (*term bindings*)
    82   type_occs: string list Symtab.table,  (*type variables -- possibly within term variables*)
    90   type_occs: string list Symtab.table,  (*type variables -- possibly within term variables*)
    83   maxidx: int,                          (*maximum var index*)
    91   maxidx: int,                          (*maximum var index*)
    84   sorts: sort Ord_List.T,               (*declared sort occurrences*)
    92   sorts: sort Ord_List.T,               (*declared sort occurrences*)
    85   constraints:
    93   constraints:
    92 
   100 
    93 structure Data = Proof_Data
   101 structure Data = Proof_Data
    94 (
   102 (
    95   type T = data;
   103   type T = data;
    96   fun init _ =
   104   fun init _ =
    97     make_data (false, Name.context, Symtab.empty, [], Vartab.empty, Symtab.empty,
   105     make_data (false, Name.context, Symtab.empty, empty_fixes, Vartab.empty,
    98       ~1, [], (Vartab.empty, Vartab.empty));
   106       Symtab.empty, ~1, [], (Vartab.empty, Vartab.empty));
    99 );
   107 );
   100 
   108 
   101 fun map_data f =
   109 fun map_data f =
   102   Data.map (fn Data {is_body, names, consts, fixes, binds, type_occs, maxidx, sorts, constraints} =>
   110   Data.map (fn Data {is_body, names, consts, fixes, binds, type_occs, maxidx, sorts, constraints} =>
   103     make_data (f (is_body, names, consts, fixes, binds, type_occs, maxidx, sorts, constraints)));
   111     make_data (f (is_body, names, consts, fixes, binds, type_occs, maxidx, sorts, constraints)));
   151 val maxidx_of = #maxidx o rep_data;
   159 val maxidx_of = #maxidx o rep_data;
   152 val sorts_of = #sorts o rep_data;
   160 val sorts_of = #sorts o rep_data;
   153 val constraints_of = #constraints o rep_data;
   161 val constraints_of = #constraints o rep_data;
   154 
   162 
   155 val is_declared = Name.is_declared o names_of;
   163 val is_declared = Name.is_declared o names_of;
   156 fun is_fixed ctxt x = exists (fn (_, y) => x = y) (fixes_of ctxt);
       
   157 fun newly_fixed inner outer x = is_fixed inner x andalso not (is_fixed outer x);
       
   158 
   164 
   159 (*checked name binding*)
   165 (*checked name binding*)
   160 val name = Long_Name.base_name o Name_Space.full_name Name_Space.default_naming;
   166 val name = Long_Name.base_name o Name_Space.full_name Name_Space.default_naming;
   161 
   167 
   162 
   168 
   279 
   285 
   280 
   286 
   281 
   287 
   282 (** fixes **)
   288 (** fixes **)
   283 
   289 
       
   290 (* specialized name space *)
       
   291 
       
   292 fun fixed_ord ctxt = Name_Space.entry_ord (#1 (fixes_of ctxt));
       
   293 
       
   294 fun is_fixed ctxt x = can (Name_Space.the_entry (#1 (fixes_of ctxt))) x;
       
   295 fun newly_fixed inner outer x = is_fixed inner x andalso not (is_fixed outer x);
       
   296 
       
   297 fun intern_fixed ctxt = Name_Space.intern (#1 (fixes_of ctxt));
       
   298 
       
   299 fun lookup_fixed ctxt x =
       
   300   let val x' = intern_fixed ctxt x
       
   301   in if is_fixed ctxt x' then SOME x' else NONE end;
       
   302 
       
   303 fun revert_fixed ctxt x =
       
   304   (case Symtab.lookup (#2 (fixes_of ctxt)) x of
       
   305     SOME x' => if intern_fixed ctxt x' = x then x' else x
       
   306   | NONE => x);
       
   307 
       
   308 fun dest_fixes ctxt =
       
   309   let val (space, tab) = fixes_of ctxt
       
   310   in sort (Name_Space.entry_ord space o pairself #2) (map swap (Symtab.dest tab)) end;
       
   311 
       
   312 
   284 (* collect variables *)
   313 (* collect variables *)
   285 
   314 
   286 fun add_free_names ctxt =
   315 fun add_free_names ctxt =
   287   fold_aterms (fn Free (x, _) => not (is_fixed ctxt x) ? insert (op =) x | _ => I);
   316   fold_aterms (fn Free (x, _) => not (is_fixed ctxt x) ? insert (op =) x | _ => I);
   288 
   317 
   298 
   327 
   299 (* declarations *)
   328 (* declarations *)
   300 
   329 
   301 local
   330 local
   302 
   331 
   303 fun no_dups [] = ()
   332 fun err_dups dups =
   304   | no_dups dups = error ("Duplicate fixed variable(s): " ^ commas_quote dups);
   333   error ("Duplicate fixed variable(s): " ^ commas (map Binding.print dups));
   305 
   334 
   306 fun new_fixes names' xs xs' =
   335 fun new_fixed ((x, x'), pos) ctxt =
       
   336   if is_some (lookup_fixed ctxt x') then err_dups [Binding.make (x, pos)]
       
   337   else
       
   338     ctxt
       
   339     |> map_fixes
       
   340       (Name_Space.define ctxt true Name_Space.default_naming (Binding.make (x', pos), x) #> snd #>>
       
   341         Name_Space.alias Name_Space.default_naming (Binding.make (x, pos)) x')
       
   342     |> declare_fixed x
       
   343     |> declare_constraints (Syntax.free x');
       
   344 
       
   345 fun new_fixes names' xs xs' ps =
   307   map_names (K names') #>
   346   map_names (K names') #>
   308   fold declare_fixed xs #>
   347   fold new_fixed ((xs ~~ xs') ~~ ps) #>
   309   map_fixes (fn fixes => (rev (xs ~~ xs') @ fixes)) #>
       
   310   fold (declare_constraints o Syntax.free) xs' #>
       
   311   pair xs';
   348   pair xs';
   312 
   349 
   313 in
   350 in
   314 
   351 
   315 fun add_fixes xs ctxt =
   352 fun add_fixes_binding bs ctxt =
   316   let
   353   let
   317     val _ =
   354     val _ =
   318       (case filter (can Name.dest_skolem) xs of [] => ()
   355       (case filter (can Name.dest_skolem o Binding.name_of) bs of
   319       | bads => error ("Illegal internal Skolem constant(s): " ^ commas_quote bads));
   356         [] => ()
   320     val _ = no_dups (duplicates (op =) xs);
   357       | bads => error ("Illegal internal Skolem constant(s): " ^ commas (map Binding.print bads)));
   321     val (ys, zs) = split_list (fixes_of ctxt);
   358     val _ =
       
   359       (case duplicates (op = o pairself Binding.name_of) bs of
       
   360         [] => ()
       
   361       | dups => err_dups dups);
       
   362 
       
   363     val xs = map name bs;
   322     val names = names_of ctxt;
   364     val names = names_of ctxt;
   323     val (xs', names') =
   365     val (xs', names') =
   324       if is_body ctxt then Name.variants xs names |>> map Name.skolem
   366       if is_body ctxt then Name.variants xs names |>> map Name.skolem
   325       else (no_dups (inter (op =) xs ys); no_dups (inter (op =) xs zs);
   367       else (xs, fold Name.declare xs names);
   326         (xs, fold Name.declare xs names));
   368   in ctxt |> new_fixes names' xs xs' (map Binding.pos_of bs) end;
   327   in ctxt |> new_fixes names' xs xs' end;
       
   328 
   369 
   329 fun variant_fixes raw_xs ctxt =
   370 fun variant_fixes raw_xs ctxt =
   330   let
   371   let
   331     val names = names_of ctxt;
   372     val names = names_of ctxt;
   332     val xs = map (fn x => Name.clean x |> can Name.dest_internal x ? Name.internal) raw_xs;
   373     val xs = map (fn x => Name.clean x |> can Name.dest_internal x ? Name.internal) raw_xs;
   333     val (xs', names') = Name.variants xs names |>> (is_body ctxt ? map Name.skolem);
   374     val (xs', names') = Name.variants xs names |>> (is_body ctxt ? map Name.skolem);
   334   in ctxt |> new_fixes names' xs xs' end;
   375   in ctxt |> new_fixes names' xs xs' (replicate (length xs) Position.none) end;
   335 
   376 
   336 end;
   377 end;
   337 
   378 
       
   379 val add_fixes = add_fixes_binding o map Binding.name;
   338 
   380 
   339 fun add_fixes_direct xs ctxt = ctxt
   381 fun add_fixes_direct xs ctxt = ctxt
   340   |> set_body false
   382   |> set_body false
   341   |> (snd o add_fixes xs)
   383   |> (snd o add_fixes xs)
   342   |> restore_body ctxt;
   384   |> restore_body ctxt;
   356 (** export -- generalize type/term variables (beware of closure sizes) **)
   398 (** export -- generalize type/term variables (beware of closure sizes) **)
   357 
   399 
   358 fun export_inst inner outer =
   400 fun export_inst inner outer =
   359   let
   401   let
   360     val declared_outer = is_declared outer;
   402     val declared_outer = is_declared outer;
   361     val fixes_inner = fixes_of inner;
   403 
   362     val fixes_outer = fixes_of outer;
   404     val gen_fixes =
   363 
   405       Symtab.fold (fn (y, _) => not (is_fixed outer y) ? cons y)
   364     val gen_fixes = map #2 (take (length fixes_inner - length fixes_outer) fixes_inner);
   406         (#2 (fixes_of inner)) [];
   365     val still_fixed = not o member (op =) gen_fixes;
   407     val still_fixed = not o member (op =) gen_fixes;
   366 
   408 
   367     val type_occs_inner = type_occs_of inner;
   409     val type_occs_inner = type_occs_of inner;
   368     fun gen_fixesT ts =
   410     fun gen_fixesT ts =
   369       Symtab.fold (fn (a, xs) =>
   411       Symtab.fold (fn (a, xs) =>