wenzelm@19899: (* Title: Pure/variable.ML wenzelm@19899: ID: $Id$ wenzelm@19899: Author: Makarius wenzelm@19899: wenzelm@19899: Fixed type/term variables and polymorphic term abbreviations. wenzelm@19899: *) wenzelm@19899: wenzelm@19899: signature VARIABLE = wenzelm@19899: sig wenzelm@20303: val is_body: Proof.context -> bool wenzelm@20303: val set_body: bool -> Proof.context -> Proof.context wenzelm@20303: val restore_body: Proof.context -> Proof.context -> Proof.context wenzelm@20303: val names_of: Proof.context -> Name.context wenzelm@20303: val fixes_of: Proof.context -> (string * string) list wenzelm@20303: val binds_of: Proof.context -> (typ * term) Vartab.table wenzelm@24765: val maxidx_of: Proof.context -> int wenzelm@28625: val sorts_of: Proof.context -> sort list wenzelm@20303: val constraints_of: Proof.context -> typ Vartab.table * sort Vartab.table wenzelm@20303: val is_declared: Proof.context -> string -> bool wenzelm@20303: val is_fixed: Proof.context -> string -> bool wenzelm@20303: val newly_fixed: Proof.context -> Proof.context -> string -> bool wenzelm@21571: val add_fixed: Proof.context -> term -> (string * typ) list -> (string * typ) list wenzelm@20303: val default_type: Proof.context -> string -> typ option wenzelm@20303: val def_type: Proof.context -> bool -> indexname -> typ option wenzelm@20303: val def_sort: Proof.context -> indexname -> sort option wenzelm@27280: val declare_names: term -> Proof.context -> Proof.context wenzelm@20303: val declare_constraints: term -> Proof.context -> Proof.context wenzelm@20303: val declare_term: term -> Proof.context -> Proof.context wenzelm@27280: val declare_typ: typ -> Proof.context -> Proof.context wenzelm@20303: val declare_prf: Proofterm.proof -> Proof.context -> Proof.context wenzelm@20303: val declare_thm: thm -> Proof.context -> Proof.context wenzelm@20303: val thm_context: thm -> Proof.context wenzelm@20303: val variant_frees: Proof.context -> term list -> (string * 'a) list -> (string * 'a) list wenzelm@20303: val add_binds: (indexname * term option) list -> Proof.context -> Proof.context wenzelm@20303: val expand_binds: Proof.context -> term -> term wenzelm@25325: val lookup_const: Proof.context -> string -> string option wenzelm@25316: val is_const: Proof.context -> string -> bool wenzelm@25325: val declare_const: string * string -> Proof.context -> Proof.context wenzelm@20303: val add_fixes: string list -> Proof.context -> string list * Proof.context wenzelm@20303: val add_fixes_direct: string list -> Proof.context -> Proof.context wenzelm@21369: val auto_fixes: term -> Proof.context -> Proof.context wenzelm@20797: val variant_fixes: string list -> Proof.context -> string list * Proof.context wenzelm@20303: val invent_types: sort list -> Proof.context -> (string * sort) list * Proof.context wenzelm@20303: val export_terms: Proof.context -> Proof.context -> term list -> term list wenzelm@20303: val exportT_terms: Proof.context -> Proof.context -> term list -> term list wenzelm@20303: val exportT: Proof.context -> Proof.context -> thm list -> thm list wenzelm@20303: val export_prf: Proof.context -> Proof.context -> Proofterm.proof -> Proofterm.proof wenzelm@20303: val export: Proof.context -> Proof.context -> thm list -> thm list wenzelm@21522: val export_morphism: Proof.context -> Proof.context -> morphism wenzelm@20303: val importT_inst: term list -> Proof.context -> ((indexname * sort) * typ) list * Proof.context wenzelm@20303: val import_inst: bool -> term list -> Proof.context -> wenzelm@20303: (((indexname * sort) * typ) list * ((indexname * typ) * term) list) * Proof.context wenzelm@20303: val importT_terms: term list -> Proof.context -> term list * Proof.context wenzelm@20303: val import_terms: bool -> term list -> Proof.context -> term list * Proof.context wenzelm@22601: val importT_thms: thm list -> Proof.context -> (ctyp list * thm list) * Proof.context wenzelm@20303: val import_prf: bool -> Proofterm.proof -> Proof.context -> Proofterm.proof * Proof.context wenzelm@22568: val import_thms: bool -> thm list -> Proof.context -> wenzelm@20303: ((ctyp list * cterm list) * thm list) * Proof.context wenzelm@21287: val tradeT: (Proof.context -> thm list -> thm list) -> Proof.context -> thm list -> thm list wenzelm@21287: val trade: (Proof.context -> thm list -> thm list) -> Proof.context -> thm list -> thm list wenzelm@20303: val focus: cterm -> Proof.context -> (cterm list * cterm) * Proof.context wenzelm@20303: val focus_subgoal: int -> thm -> Proof.context -> (cterm list * cterm) * Proof.context wenzelm@20303: val warn_extra_tfrees: Proof.context -> Proof.context -> unit wenzelm@24694: val polymorphic_types: Proof.context -> term list -> (indexname * sort) list * term list wenzelm@20303: val polymorphic: Proof.context -> term list -> term list wenzelm@19899: end; wenzelm@19899: wenzelm@19899: structure Variable: VARIABLE = wenzelm@19899: struct wenzelm@19899: wenzelm@19899: (** local context data **) wenzelm@19899: wenzelm@19899: datatype data = Data of wenzelm@20102: {is_body: bool, (*inner body mode*) wenzelm@20162: names: Name.context, (*type/term variable names*) wenzelm@25325: consts: string Symtab.table, (*consts within the local scope*) wenzelm@20162: fixes: (string * string) list, (*term fixes -- extern/intern*) wenzelm@20102: binds: (typ * term) Vartab.table, (*term bindings*) wenzelm@20162: type_occs: string list Symtab.table, (*type variables -- possibly within term variables*) wenzelm@24765: maxidx: int, (*maximum var index*) wenzelm@28625: sorts: sort OrdList.T, (*declared sort occurrences*) wenzelm@20162: constraints: wenzelm@20102: typ Vartab.table * (*type constraints*) wenzelm@20162: sort Vartab.table}; (*default sorts*) wenzelm@19899: wenzelm@28625: fun make_data (is_body, names, consts, fixes, binds, type_occs, maxidx, sorts, constraints) = wenzelm@25325: Data {is_body = is_body, names = names, consts = consts, fixes = fixes, binds = binds, wenzelm@28625: type_occs = type_occs, maxidx = maxidx, sorts = sorts, constraints = constraints}; wenzelm@19899: wenzelm@19899: structure Data = ProofDataFun wenzelm@19899: ( wenzelm@19899: type T = data; wenzelm@19899: fun init thy = wenzelm@25316: make_data (false, Name.context, Symtab.empty, [], Vartab.empty, Symtab.empty, wenzelm@28625: ~1, [], (Vartab.empty, Vartab.empty)); wenzelm@19899: ); wenzelm@19899: wenzelm@19899: fun map_data f = wenzelm@28625: Data.map (fn Data {is_body, names, consts, fixes, binds, type_occs, maxidx, sorts, constraints} => wenzelm@28625: make_data (f (is_body, names, consts, fixes, binds, type_occs, maxidx, sorts, constraints))); wenzelm@25316: wenzelm@25316: fun map_names f = wenzelm@28625: map_data (fn (is_body, names, consts, fixes, binds, type_occs, maxidx, sorts, constraints) => wenzelm@28625: (is_body, f names, consts, fixes, binds, type_occs, maxidx, sorts, constraints)); wenzelm@19899: wenzelm@25325: fun map_consts f = wenzelm@28625: map_data (fn (is_body, names, consts, fixes, binds, type_occs, maxidx, sorts, constraints) => wenzelm@28625: (is_body, names, f consts, fixes, binds, type_occs, maxidx, sorts, constraints)); wenzelm@20162: wenzelm@25316: fun map_fixes f = wenzelm@28625: map_data (fn (is_body, names, consts, fixes, binds, type_occs, maxidx, sorts, constraints) => wenzelm@28625: (is_body, names, consts, f fixes, binds, type_occs, maxidx, sorts, constraints)); wenzelm@19899: wenzelm@25316: fun map_binds f = wenzelm@28625: map_data (fn (is_body, names, consts, fixes, binds, type_occs, maxidx, sorts, constraints) => wenzelm@28625: (is_body, names, consts, fixes, f binds, type_occs, maxidx, sorts, constraints)); wenzelm@24765: wenzelm@25316: fun map_type_occs f = wenzelm@28625: map_data (fn (is_body, names, consts, fixes, binds, type_occs, maxidx, sorts, constraints) => wenzelm@28625: (is_body, names, consts, fixes, binds, f type_occs, maxidx, sorts, constraints)); wenzelm@19899: wenzelm@25316: fun map_maxidx f = wenzelm@28625: map_data (fn (is_body, names, consts, fixes, binds, type_occs, maxidx, sorts, constraints) => wenzelm@28625: (is_body, names, consts, fixes, binds, type_occs, f maxidx, sorts, constraints)); wenzelm@28625: wenzelm@28625: fun map_sorts f = wenzelm@28625: map_data (fn (is_body, names, consts, fixes, binds, type_occs, maxidx, sorts, constraints) => wenzelm@28625: (is_body, names, consts, fixes, binds, type_occs, maxidx, f sorts, constraints)); wenzelm@20102: wenzelm@25316: fun map_constraints f = wenzelm@28625: map_data (fn (is_body, names, consts, fixes, binds, type_occs, maxidx, sorts, constraints) => wenzelm@28625: (is_body, names, consts, fixes, binds, type_occs, maxidx, sorts, f constraints)); wenzelm@19899: wenzelm@19899: fun rep_data ctxt = Data.get ctxt |> (fn Data args => args); wenzelm@19899: wenzelm@19899: val is_body = #is_body o rep_data; wenzelm@24765: wenzelm@28625: fun set_body b = wenzelm@28625: map_data (fn (_, names, consts, fixes, binds, type_occs, maxidx, sorts, constraints) => wenzelm@28625: (b, names, consts, fixes, binds, type_occs, maxidx, sorts, constraints)); wenzelm@24765: wenzelm@19899: fun restore_body ctxt = set_body (is_body ctxt); wenzelm@19899: wenzelm@20102: val names_of = #names o rep_data; wenzelm@20102: val fixes_of = #fixes o rep_data; wenzelm@19899: val binds_of = #binds o rep_data; wenzelm@20162: val type_occs_of = #type_occs o rep_data; wenzelm@24765: val maxidx_of = #maxidx o rep_data; wenzelm@28625: val sorts_of = #sorts o rep_data; wenzelm@20162: val constraints_of = #constraints o rep_data; wenzelm@19899: wenzelm@20162: val is_declared = Name.is_declared o names_of; wenzelm@19899: fun is_fixed ctxt x = exists (fn (_, y) => x = y) (fixes_of ctxt); wenzelm@20149: fun newly_fixed inner outer x = is_fixed inner x andalso not (is_fixed outer x); wenzelm@19899: wenzelm@21571: fun add_fixed ctxt = Term.fold_aterms wenzelm@21571: (fn Free (x, T) => if is_fixed ctxt x then insert (op =) (x, T) else I | _ => I); wenzelm@21571: wenzelm@19899: wenzelm@19899: wenzelm@19899: (** declarations **) wenzelm@19899: wenzelm@19899: (* default sorts and types *) wenzelm@19899: wenzelm@20162: fun default_type ctxt x = Vartab.lookup (#1 (constraints_of ctxt)) (x, ~1); wenzelm@19899: wenzelm@19899: fun def_type ctxt pattern xi = wenzelm@20162: let val {binds, constraints = (types, _), ...} = rep_data ctxt in wenzelm@19899: (case Vartab.lookup types xi of wenzelm@19899: NONE => wenzelm@19899: if pattern then NONE wenzelm@19899: else Vartab.lookup binds xi |> Option.map (TypeInfer.polymorphicT o #1) wenzelm@19899: | some => some) wenzelm@19899: end; wenzelm@19899: wenzelm@20162: val def_sort = Vartab.lookup o #2 o constraints_of; wenzelm@20162: wenzelm@20162: wenzelm@20162: (* names *) wenzelm@20162: wenzelm@24765: fun declare_type_names t = wenzelm@24765: map_names (fold_types (fold_atyps (fn TFree (a, _) => Name.declare a | _ => I)) t) #> wenzelm@24765: map_maxidx (fold_types Term.maxidx_typ t); wenzelm@20162: wenzelm@20162: fun declare_names t = wenzelm@20162: declare_type_names t #> wenzelm@24765: map_names (fold_aterms (fn Free (x, _) => Name.declare x | _ => I) t) #> wenzelm@24765: map_maxidx (Term.maxidx_term t); wenzelm@20162: wenzelm@20162: wenzelm@20162: (* type occurrences *) wenzelm@20162: wenzelm@24719: fun decl_type_occsT T = fold_atyps (fn TFree (a, _) => Symtab.default (a, []) | _ => I) T; wenzelm@24719: wenzelm@22671: val decl_type_occs = fold_term_types wenzelm@20162: (fn Free (x, _) => fold_atyps (fn TFree (a, _) => Symtab.insert_list (op =) (a, x) | _ => I) wenzelm@24719: | _ => decl_type_occsT); wenzelm@19899: wenzelm@24719: val declare_type_occsT = map_type_occs o fold_types decl_type_occsT; wenzelm@22671: val declare_type_occs = map_type_occs o decl_type_occs; wenzelm@22671: wenzelm@19899: wenzelm@20162: (* constraints *) wenzelm@19899: wenzelm@21355: fun constrain_tvar (xi, S) = wenzelm@21355: if S = dummyS then Vartab.delete_safe xi else Vartab.update (xi, S); wenzelm@21355: wenzelm@20162: fun declare_constraints t = map_constraints (fn (types, sorts) => wenzelm@20162: let wenzelm@20162: val types' = fold_aterms wenzelm@20162: (fn Free (x, T) => Vartab.update ((x, ~1), T) wenzelm@20162: | Var v => Vartab.update v wenzelm@20162: | _ => I) t types; wenzelm@20162: val sorts' = fold_types (fold_atyps wenzelm@21355: (fn TFree (x, S) => constrain_tvar ((x, ~1), S) wenzelm@21355: | TVar v => constrain_tvar v wenzelm@20162: | _ => I)) t sorts; wenzelm@20162: in (types', sorts') end) wenzelm@24719: #> declare_type_occsT t wenzelm@22711: #> declare_type_names t; wenzelm@19899: wenzelm@20162: wenzelm@20162: (* common declarations *) wenzelm@20162: wenzelm@20162: fun declare_internal t = wenzelm@20162: declare_names t #> wenzelm@28625: declare_type_occs t #> wenzelm@28625: map_sorts (Sorts.insert_term t); wenzelm@19911: wenzelm@20162: fun declare_term t = wenzelm@20162: declare_internal t #> wenzelm@20162: declare_constraints t; wenzelm@19899: wenzelm@27280: val declare_typ = declare_term o Logic.mk_type; wenzelm@27280: wenzelm@20303: val declare_prf = Proofterm.fold_proof_terms declare_internal (declare_internal o Logic.mk_type); wenzelm@20303: wenzelm@22691: val declare_thm = Thm.fold_terms declare_internal; wenzelm@21522: fun thm_context th = declare_thm th (ProofContext.init (Thm.theory_of_thm th)); wenzelm@19899: wenzelm@19899: wenzelm@19899: (* renaming term/type frees *) wenzelm@19899: wenzelm@20162: fun variant_frees ctxt ts frees = wenzelm@19899: let wenzelm@20162: val names = names_of (fold declare_names ts ctxt); wenzelm@20084: val xs = fst (Name.variants (map #1 frees) names); wenzelm@20084: in xs ~~ map snd frees end; wenzelm@19899: wenzelm@19899: wenzelm@19899: wenzelm@20303: (** term bindings **) wenzelm@20303: wenzelm@20303: fun add_bind (xi, NONE) = map_binds (Vartab.delete_safe xi) wenzelm@20303: | add_bind ((x, i), SOME t) = wenzelm@20303: let wenzelm@25051: val u = Term.close_schematic_term t; wenzelm@25051: val U = Term.fastype_of u; wenzelm@25051: in declare_term u #> map_binds (Vartab.update ((x, i), (U, u))) end; wenzelm@20303: wenzelm@20303: val add_binds = fold add_bind; wenzelm@20303: wenzelm@20303: fun expand_binds ctxt = wenzelm@20303: let wenzelm@20303: val binds = binds_of ctxt; wenzelm@21799: val get = fn Var (xi, _) => Vartab.lookup binds xi | _ => NONE; wenzelm@21799: in Envir.beta_norm o Envir.expand_term get end; wenzelm@20303: wenzelm@20303: wenzelm@20303: wenzelm@25325: (** consts **) wenzelm@25316: wenzelm@25325: val lookup_const = Symtab.lookup o #consts o rep_data; wenzelm@25325: val is_const = is_some oo lookup_const; wenzelm@25316: wenzelm@25325: val declare_fixed = map_consts o Symtab.delete_safe; wenzelm@25325: val declare_const = map_consts o Symtab.update; wenzelm@25316: wenzelm@25316: wenzelm@25316: wenzelm@19911: (** fixes **) wenzelm@19911: wenzelm@20084: local wenzelm@20084: wenzelm@19911: fun no_dups [] = () wenzelm@19911: | no_dups dups = error ("Duplicate fixed variable(s): " ^ commas_quote dups); wenzelm@19911: wenzelm@20102: fun new_fixes names' xs xs' = wenzelm@20102: map_names (K names') #> wenzelm@25316: fold declare_fixed xs #> wenzelm@20102: map_fixes (fn fixes => (rev (xs ~~ xs') @ fixes)) #> wenzelm@20162: fold (declare_constraints o Syntax.free) xs' #> wenzelm@20084: pair xs'; wenzelm@20084: wenzelm@20084: in wenzelm@20084: wenzelm@19911: fun add_fixes xs ctxt = wenzelm@19911: let wenzelm@19911: val _ = wenzelm@20084: (case filter (can Name.dest_skolem) xs of [] => () wenzelm@19911: | bads => error ("Illegal internal Skolem constant(s): " ^ commas_quote bads)); wenzelm@20084: val _ = no_dups (duplicates (op =) xs); wenzelm@20084: val (ys, zs) = split_list (fixes_of ctxt); wenzelm@20102: val names = names_of ctxt; wenzelm@20084: val (xs', names') = wenzelm@20149: if is_body ctxt then Name.variants xs names |>> map Name.skolem wenzelm@20084: else (no_dups (xs inter_string ys); no_dups (xs inter_string zs); wenzelm@20084: (xs, fold Name.declare xs names)); wenzelm@20102: in ctxt |> new_fixes names' xs xs' end; wenzelm@19911: wenzelm@20797: fun variant_fixes raw_xs ctxt = wenzelm@20084: let wenzelm@20102: val names = names_of ctxt; wenzelm@26714: val xs = map (fn x => Name.clean x |> can Name.dest_internal x ? Name.internal) raw_xs; wenzelm@26714: val (xs', names') = Name.variants xs names |>> (is_body ctxt ? map Name.skolem); wenzelm@20102: in ctxt |> new_fixes names' xs xs' end; wenzelm@20084: wenzelm@20084: end; wenzelm@19911: wenzelm@20251: wenzelm@20251: fun add_fixes_direct xs ctxt = ctxt wenzelm@20251: |> set_body false wenzelm@20251: |> (snd o add_fixes xs) wenzelm@20251: |> restore_body ctxt; wenzelm@20251: wenzelm@20251: fun fix_frees t ctxt = ctxt wenzelm@20251: |> add_fixes_direct wenzelm@20251: (rev (fold_aterms (fn Free (x, _) => wenzelm@21369: if is_fixed ctxt x then I else insert (op =) x | _ => I) t [])); wenzelm@21369: wenzelm@21369: fun auto_fixes t ctxt = wenzelm@21369: (if is_body ctxt then ctxt else fix_frees t ctxt) wenzelm@20251: |> declare_term t; wenzelm@20251: wenzelm@19911: fun invent_types Ss ctxt = wenzelm@19911: let wenzelm@24848: val tfrees = Name.invents (names_of ctxt) Name.aT (length Ss) ~~ Ss; wenzelm@20162: val ctxt' = fold (declare_constraints o Logic.mk_type o TFree) tfrees ctxt; wenzelm@19911: in (tfrees, ctxt') end; wenzelm@19911: wenzelm@19911: wenzelm@19911: wenzelm@22671: (** export -- generalize type/term variables (beware of closure sizes) **) wenzelm@19911: wenzelm@19911: fun export_inst inner outer = wenzelm@19911: let wenzelm@20162: val declared_outer = is_declared outer; wenzelm@19911: val fixes_inner = fixes_of inner; wenzelm@19911: val fixes_outer = fixes_of outer; wenzelm@19911: wenzelm@19911: val gen_fixes = map #2 (Library.take (length fixes_inner - length fixes_outer, fixes_inner)); wenzelm@20162: val still_fixed = not o member (op =) gen_fixes; wenzelm@22671: wenzelm@22671: val type_occs_inner = type_occs_of inner; wenzelm@22671: fun gen_fixesT ts = wenzelm@19911: Symtab.fold (fn (a, xs) => wenzelm@20162: if declared_outer a orelse exists still_fixed xs wenzelm@22671: then I else cons a) (fold decl_type_occs ts type_occs_inner) []; wenzelm@19911: in (gen_fixesT, gen_fixes) end; wenzelm@19911: wenzelm@19911: fun exportT_inst inner outer = #1 (export_inst inner outer); wenzelm@19911: wenzelm@22671: fun exportT_terms inner outer = wenzelm@22671: let val mk_tfrees = exportT_inst inner outer in wenzelm@22671: fn ts => ts |> map wenzelm@22671: (TermSubst.generalize (mk_tfrees ts, []) wenzelm@22671: (fold (Term.fold_types Term.maxidx_typ) ts ~1 + 1)) wenzelm@22671: end; wenzelm@19911: wenzelm@22671: fun export_terms inner outer = wenzelm@22671: let val (mk_tfrees, tfrees) = export_inst inner outer in wenzelm@22671: fn ts => ts |> map wenzelm@22671: (TermSubst.generalize (mk_tfrees ts, tfrees) wenzelm@22671: (fold Term.maxidx_term ts ~1 + 1)) wenzelm@22671: end; wenzelm@19911: wenzelm@20303: fun export_prf inner outer prf = wenzelm@20303: let wenzelm@22671: val (mk_tfrees, frees) = export_inst (declare_prf prf inner) outer; wenzelm@22671: val tfrees = mk_tfrees []; wenzelm@20303: val idx = Proofterm.maxidx_proof prf ~1 + 1; wenzelm@22671: val gen_term = TermSubst.generalize_option (tfrees, frees) idx; wenzelm@22671: val gen_typ = TermSubst.generalizeT_option tfrees idx; wenzelm@20303: in Proofterm.map_proof_terms_option gen_term gen_typ prf end; wenzelm@20303: wenzelm@22671: wenzelm@22671: fun gen_export (mk_tfrees, frees) ths = wenzelm@19911: let wenzelm@22671: val tfrees = mk_tfrees (map Thm.full_prop_of ths); wenzelm@22671: val maxidx = fold Thm.maxidx_thm ths ~1; wenzelm@22671: in map (Thm.generalize (tfrees, frees) (maxidx + 1)) ths end; wenzelm@19911: wenzelm@22671: fun exportT inner outer = gen_export (exportT_inst inner outer, []); wenzelm@22671: fun export inner outer = gen_export (export_inst inner outer); wenzelm@19911: wenzelm@21522: fun export_morphism inner outer = wenzelm@21522: let wenzelm@21522: val fact = export inner outer; wenzelm@21522: val term = singleton (export_terms inner outer); wenzelm@21522: val typ = Logic.type_map term; haftmann@28965: in Morphism.morphism {binding = I, var = I, typ = typ, term = term, fact = fact} end; wenzelm@19911: wenzelm@19911: wenzelm@24765: wenzelm@19911: (** import -- fix schematic type/term variables **) wenzelm@19911: wenzelm@19911: fun importT_inst ts ctxt = wenzelm@19911: let wenzelm@19911: val tvars = rev (fold Term.add_tvars ts []); wenzelm@19911: val (tfrees, ctxt') = invent_types (map #2 tvars) ctxt; wenzelm@19911: in (tvars ~~ map TFree tfrees, ctxt') end; wenzelm@19911: wenzelm@19911: fun import_inst is_open ts ctxt = wenzelm@19911: let wenzelm@26714: val ren = Name.clean #> (if is_open then I else Name.internal); wenzelm@19911: val (instT, ctxt') = importT_inst ts ctxt; wenzelm@20509: val vars = map (apsnd (TermSubst.instantiateT instT)) (rev (fold Term.add_vars ts [])); wenzelm@20797: val (xs, ctxt'') = variant_fixes (map (ren o #1 o #1) vars) ctxt'; wenzelm@19911: val inst = vars ~~ map Free (xs ~~ map #2 vars); wenzelm@19911: in ((instT, inst), ctxt'') end; wenzelm@19911: wenzelm@19911: fun importT_terms ts ctxt = wenzelm@19911: let val (instT, ctxt') = importT_inst ts ctxt wenzelm@20509: in (map (TermSubst.instantiate (instT, [])) ts, ctxt') end; wenzelm@19911: wenzelm@19911: fun import_terms is_open ts ctxt = wenzelm@19911: let val (inst, ctxt') = import_inst is_open ts ctxt wenzelm@20509: in (map (TermSubst.instantiate inst) ts, ctxt') end; wenzelm@19911: wenzelm@22601: fun importT_thms ths ctxt = wenzelm@19911: let wenzelm@21522: val thy = ProofContext.theory_of ctxt; wenzelm@19911: val certT = Thm.ctyp_of thy; wenzelm@19911: val (instT, ctxt') = importT_inst (map Thm.full_prop_of ths) ctxt; wenzelm@19911: val instT' = map (fn (v, T) => (certT (TVar v), certT T)) instT; wenzelm@19911: val ths' = map (Thm.instantiate (instT', [])) ths; wenzelm@20220: in ((map #2 instT', ths'), ctxt') end; wenzelm@19911: wenzelm@20303: fun import_prf is_open prf ctxt = wenzelm@20303: let wenzelm@20303: val ts = rev (Proofterm.fold_proof_terms cons (cons o Logic.mk_type) prf []); wenzelm@20303: val (insts, ctxt') = import_inst is_open ts ctxt; wenzelm@20303: in (Proofterm.instantiate insts prf, ctxt') end; wenzelm@20303: wenzelm@22568: fun import_thms is_open ths ctxt = wenzelm@19911: let wenzelm@21522: val thy = ProofContext.theory_of ctxt; wenzelm@19911: val cert = Thm.cterm_of thy; wenzelm@19911: val certT = Thm.ctyp_of thy; wenzelm@19911: val ((instT, inst), ctxt') = import_inst is_open (map Thm.full_prop_of ths) ctxt; wenzelm@19911: val instT' = map (fn (v, T) => (certT (TVar v), certT T)) instT; wenzelm@19911: val inst' = map (fn (v, t) => (cert (Var v), cert t)) inst; wenzelm@19911: val ths' = map (Thm.instantiate (instT', inst')) ths; wenzelm@20220: in (((map #2 instT', map #2 inst'), ths'), ctxt') end; wenzelm@19911: wenzelm@19911: wenzelm@19926: (* import/export *) wenzelm@19926: wenzelm@21287: fun gen_trade imp exp f ctxt ths = wenzelm@20220: let val ((_, ths'), ctxt') = imp ths ctxt wenzelm@21287: in exp ctxt' ctxt (f ctxt' ths') end; wenzelm@19926: wenzelm@22601: val tradeT = gen_trade importT_thms exportT; wenzelm@22568: val trade = gen_trade (import_thms true) export; wenzelm@19926: wenzelm@19926: wenzelm@20162: (* focus on outermost parameters *) wenzelm@20149: wenzelm@20149: fun forall_elim_prop t prop = wenzelm@20579: Thm.beta_conversion false (Thm.capply (Thm.dest_arg prop) t) wenzelm@20579: |> Thm.cprop_of |> Thm.dest_arg; wenzelm@20149: wenzelm@20149: fun focus goal ctxt = wenzelm@20149: let wenzelm@20149: val cert = Thm.cterm_of (Thm.theory_of_cterm goal); wenzelm@20149: val t = Thm.term_of goal; wenzelm@20162: val ps = Term.variant_frees t (Term.strip_all_vars t); (*as they are printed :-*) wenzelm@20149: val (xs, Ts) = split_list ps; wenzelm@20797: val (xs', ctxt') = variant_fixes xs ctxt; wenzelm@20220: val ps' = ListPair.map (cert o Free) (xs', Ts); wenzelm@20220: val goal' = fold forall_elim_prop ps' goal; wenzelm@27119: val ctxt'' = ctxt' |> fold (declare_constraints o Thm.term_of) ps'; wenzelm@27119: in ((ps', goal'), ctxt'') end; wenzelm@20149: wenzelm@20303: fun focus_subgoal i st = wenzelm@20303: let wenzelm@22691: val all_vars = Thm.fold_terms Term.add_vars st []; wenzelm@20303: val no_binds = map (fn (xi, _) => (xi, NONE)) all_vars; wenzelm@20303: in wenzelm@20303: add_binds no_binds #> wenzelm@20303: fold (declare_constraints o Var) all_vars #> wenzelm@20303: focus (Thm.cprem_of st i) wenzelm@20303: end; wenzelm@20303: wenzelm@20303: wenzelm@19911: wenzelm@19911: (** implicit polymorphism **) wenzelm@19899: wenzelm@19899: (* warn_extra_tfrees *) wenzelm@19899: wenzelm@19899: fun warn_extra_tfrees ctxt1 ctxt2 = wenzelm@19899: let wenzelm@19911: fun occs_typ a = Term.exists_subtype (fn TFree (b, _) => a = b | _ => false); wenzelm@20162: fun occs_free a x = wenzelm@20162: (case def_type ctxt1 false (x, ~1) of wenzelm@20162: SOME T => if occs_typ a T then I else cons (a, x) wenzelm@20162: | NONE => cons (a, x)); wenzelm@19899: wenzelm@20162: val occs1 = type_occs_of ctxt1; wenzelm@20162: val occs2 = type_occs_of ctxt2; wenzelm@19911: val extras = Symtab.fold (fn (a, xs) => wenzelm@19911: if Symtab.defined occs1 a then I else fold (occs_free a) xs) occs2 []; wenzelm@19899: val tfrees = map #1 extras |> sort_distinct string_ord; wenzelm@19899: val frees = map #2 extras |> sort_distinct string_ord; wenzelm@19899: in wenzelm@19899: if null extras then () wenzelm@19899: else warning ("Introduced fixed type variable(s): " ^ commas tfrees ^ " in " ^ wenzelm@19899: space_implode " or " (map quote frees)) wenzelm@19899: end; wenzelm@19899: wenzelm@19899: wenzelm@20149: (* polymorphic terms *) wenzelm@19899: wenzelm@24694: fun polymorphic_types ctxt ts = wenzelm@20003: let wenzelm@20003: val ctxt' = fold declare_term ts ctxt; wenzelm@20162: val occs = type_occs_of ctxt; wenzelm@20162: val occs' = type_occs_of ctxt'; wenzelm@20162: val types = Symtab.fold (fn (a, _) => if Symtab.defined occs a then I else cons a) occs' []; wenzelm@24765: val idx = maxidx_of ctxt' + 1; wenzelm@24694: val Ts' = (fold o fold_types o fold_atyps) wenzelm@24694: (fn T as TFree _ => wenzelm@24694: (case TermSubst.generalizeT types idx T of TVar v => insert (op =) v | _ => I) wenzelm@24694: | _ => I) ts []; wenzelm@24694: val ts' = map (TermSubst.generalize (types, []) idx) ts; wenzelm@24694: in (rev Ts', ts') end; wenzelm@24694: wenzelm@24694: fun polymorphic ctxt ts = snd (polymorphic_types ctxt ts); wenzelm@20003: wenzelm@19899: end;