haftmann@38533: (* Title: Pure/Isar/theory_target.ML haftmann@38533: Author: Makarius haftmann@38533: Author: Florian Haftmann, TU Muenchen haftmann@38533: haftmann@38533: Common target infrastructure. haftmann@38533: *) haftmann@38533: haftmann@38533: signature GENERIC_TARGET = haftmann@38533: sig haftmann@38537: val define: (((binding * typ) * mixfix) * (binding * term) haftmann@38537: -> term list * term list -> local_theory -> (term * thm) * local_theory) haftmann@38533: -> (binding * mixfix) * (Attrib.binding * term) -> local_theory haftmann@38533: -> (term * (string * thm)) * local_theory haftmann@38533: val notes: (string haftmann@38533: -> (Attrib.binding * (thm list * Args.src list) list) list haftmann@38533: -> (Attrib.binding * (thm list * Args.src list) list) list haftmann@38533: -> local_theory -> local_theory) haftmann@38533: -> string -> (Attrib.binding * (thm list * Args.src list) list) list haftmann@38533: -> local_theory -> (string * thm list) list * local_theory haftmann@38534: val abbrev: (string * bool -> binding * mixfix -> term * term haftmann@38536: -> term list -> local_theory -> local_theory) haftmann@38534: -> string * bool -> (binding * mixfix) * term -> local_theory haftmann@38534: -> (term * term) * local_theory haftmann@38577: haftmann@38577: val theory_declaration: declaration -> local_theory -> local_theory haftmann@38577: val theory_foundation: ((binding * typ) * mixfix) * (binding * term) haftmann@38577: -> term list * term list -> local_theory -> (term * thm) * local_theory haftmann@38577: val theory_notes: string -> (Attrib.binding * (thm list * Args.src list) list) list haftmann@38577: -> local_theory -> local_theory haftmann@38577: val theory_abbrev: Syntax.mode -> (binding * mixfix) * term haftmann@38577: -> local_theory -> local_theory haftmann@38533: end; haftmann@38533: haftmann@38533: structure Generic_Target: GENERIC_TARGET = haftmann@38533: struct haftmann@38533: haftmann@38577: (** lifting primitive to target operations **) haftmann@38577: haftmann@38536: (* mixfix syntax *) haftmann@38536: haftmann@38536: fun check_mixfix ctxt (b, extra_tfrees) mx = haftmann@38536: if null extra_tfrees then mx haftmann@38536: else haftmann@38536: (warning haftmann@38536: ("Additional type variable(s) in specification of " ^ Binding.str_of b ^ ": " ^ haftmann@38536: commas (map (Syntax.string_of_typ ctxt o TFree) (sort_wrt #1 extra_tfrees)) ^ haftmann@38536: (if mx = NoSyn then "" haftmann@38536: else "\nDropping mixfix syntax " ^ Pretty.string_of (Syntax.pretty_mixfix mx))); haftmann@38536: NoSyn); haftmann@38536: haftmann@38536: haftmann@38533: (* define *) haftmann@38533: haftmann@38535: fun define foundation ((b, mx), ((proto_b_def, atts), rhs)) lthy = haftmann@38533: let haftmann@38533: val thy = ProofContext.theory_of lthy; haftmann@38533: val thy_ctxt = ProofContext.init_global thy; haftmann@38533: haftmann@38535: val b_def = Thm.def_binding_optional b proto_b_def; haftmann@38533: haftmann@38533: (*term and type parameters*) haftmann@38533: val crhs = Thm.cterm_of thy rhs; haftmann@38533: val (defs, rhs') = Local_Defs.export_cterm lthy thy_ctxt crhs ||> Thm.term_of; haftmann@38533: val rhs_conv = MetaSimplifier.rewrite true defs crhs; haftmann@38533: haftmann@38533: val xs = Variable.add_fixed (Local_Theory.target_of lthy) rhs' []; haftmann@38533: val T = Term.fastype_of rhs; haftmann@38533: val tfreesT = Term.add_tfreesT T (fold (Term.add_tfreesT o #2) xs []); haftmann@38533: val extra_tfrees = rev (subtract (op =) tfreesT (Term.add_tfrees rhs [])); haftmann@38536: val mx' = check_mixfix lthy (b, extra_tfrees) mx; haftmann@38533: haftmann@38533: val type_params = map (Logic.mk_type o TFree) extra_tfrees; haftmann@38533: val term_params = haftmann@38533: rev (Variable.fixes_of (Local_Theory.target_of lthy)) haftmann@38533: |> map_filter (fn (_, x) => haftmann@38533: (case AList.lookup (op =) xs x of haftmann@38533: SOME T => SOME (Free (x, T)) haftmann@38533: | NONE => NONE)); haftmann@38533: val params = type_params @ term_params; haftmann@38533: haftmann@38533: val U = map Term.fastype_of params ---> T; haftmann@38533: haftmann@38533: (*foundation*) haftmann@38539: val ((lhs', global_def), lthy2) = foundation haftmann@38537: (((b, U), mx'), (b_def, rhs')) (type_params, term_params) lthy; haftmann@38533: haftmann@38533: (*local definition*) haftmann@38539: val ((lhs, local_def), lthy3) = lthy2 haftmann@38533: |> Local_Defs.add_def ((b, NoSyn), lhs'); haftmann@38539: val def = Local_Defs.trans_terms lthy3 haftmann@38533: [(*c == global.c xs*) local_def, haftmann@38533: (*global.c xs == rhs'*) global_def, haftmann@38533: (*rhs' == rhs*) Thm.symmetric rhs_conv]; haftmann@38533: haftmann@38533: (*note*) haftmann@38539: val ([(res_name, [res])], lthy4) = lthy3 haftmann@38535: |> Local_Theory.notes_kind "" [((b_def, atts), [([def], [])])]; haftmann@38539: in ((lhs, (res_name, res)), lthy4) end; haftmann@38533: haftmann@38533: haftmann@38533: (* notes *) haftmann@38533: haftmann@38533: fun import_export_proof ctxt (name, raw_th) = haftmann@38533: let haftmann@38533: val thy = ProofContext.theory_of ctxt; haftmann@38533: val thy_ctxt = ProofContext.init_global thy; haftmann@38533: val certT = Thm.ctyp_of thy; haftmann@38533: val cert = Thm.cterm_of thy; haftmann@38533: haftmann@38533: (*export assumes/defines*) haftmann@38533: val th = Goal.norm_result raw_th; haftmann@38533: val (defs, th') = Local_Defs.export ctxt thy_ctxt th; haftmann@38534: val assms = map (MetaSimplifier.rewrite_rule defs o Thm.assume) haftmann@38534: (Assumption.all_assms_of ctxt); haftmann@38533: val nprems = Thm.nprems_of th' - Thm.nprems_of th; haftmann@38533: haftmann@38533: (*export fixes*) haftmann@38533: val tfrees = map TFree (Thm.fold_terms Term.add_tfrees th' []); haftmann@38533: val frees = map Free (Thm.fold_terms Term.add_frees th' []); haftmann@38533: val (th'' :: vs) = (th' :: map (Drule.mk_term o cert) (map Logic.mk_type tfrees @ frees)) haftmann@38533: |> Variable.export ctxt thy_ctxt haftmann@38533: |> Drule.zero_var_indexes_list; haftmann@38533: haftmann@38533: (*thm definition*) haftmann@38533: val result = PureThy.name_thm true true name th''; haftmann@38533: haftmann@38533: (*import fixes*) haftmann@38533: val (tvars, vars) = haftmann@38533: chop (length tfrees) (map (Thm.term_of o Drule.dest_term) vs) haftmann@38533: |>> map Logic.dest_type; haftmann@38533: haftmann@38533: val instT = map_filter (fn (TVar v, T) => SOME (v, T) | _ => NONE) (tvars ~~ tfrees); haftmann@38533: val inst = filter (is_Var o fst) (vars ~~ frees); haftmann@38533: val cinstT = map (pairself certT o apfst TVar) instT; haftmann@38533: val cinst = map (pairself (cert o Term.map_types (Term_Subst.instantiateT instT))) inst; haftmann@38533: val result' = Thm.instantiate (cinstT, cinst) result; haftmann@38533: haftmann@38533: (*import assumes/defines*) haftmann@38533: val assm_tac = FIRST' (map (fn assm => Tactic.compose_tac (false, assm, 0)) assms); haftmann@38533: val result'' = haftmann@38533: (case SINGLE (Seq.INTERVAL assm_tac 1 nprems) result' of haftmann@38533: NONE => raise THM ("Failed to re-import result", 0, [result']) haftmann@38533: | SOME res => Local_Defs.contract ctxt defs (Thm.cprop_of th) res) haftmann@38533: |> Goal.norm_result haftmann@38533: |> PureThy.name_thm false false name; haftmann@38533: haftmann@38533: in (result'', result) end; haftmann@38533: haftmann@38533: fun notes target_notes kind facts lthy = haftmann@38533: let haftmann@38533: val thy = ProofContext.theory_of lthy; haftmann@38533: val facts' = facts haftmann@38533: |> map (fn (a, bs) => (a, PureThy.burrow_fact (PureThy.name_multi haftmann@38533: (Local_Theory.full_name lthy (fst a))) bs)) haftmann@38533: |> PureThy.map_facts (import_export_proof lthy); haftmann@38533: val local_facts = PureThy.map_facts #1 facts'; haftmann@38533: val global_facts = PureThy.map_facts #2 facts'; haftmann@38533: in haftmann@38533: lthy haftmann@38533: |> target_notes kind global_facts local_facts haftmann@38533: |> ProofContext.note_thmss kind (Attrib.map_facts (Attrib.attribute_i thy) local_facts) haftmann@38533: end; haftmann@38533: haftmann@38533: haftmann@38533: (* abbrev *) haftmann@38533: haftmann@38533: fun abbrev target_abbrev prmode ((b, mx), t) lthy = haftmann@38533: let haftmann@38533: val thy_ctxt = ProofContext.init_global (ProofContext.theory_of lthy); haftmann@38533: val target_ctxt = Local_Theory.target_of lthy; haftmann@38533: haftmann@38533: val t' = Assumption.export_term lthy target_ctxt t; haftmann@38533: val xs = map Free (rev (Variable.add_fixed target_ctxt t' [])); haftmann@38533: val u = fold_rev lambda xs t'; haftmann@38533: haftmann@38533: val extra_tfrees = haftmann@38533: subtract (op =) (Term.add_tfreesT (Term.fastype_of u) []) (Term.add_tfrees u []); haftmann@38536: val mx' = check_mixfix lthy (b, extra_tfrees) mx; haftmann@38533: haftmann@38533: val global_rhs = haftmann@38533: singleton (Variable.export_terms (Variable.declare_term u target_ctxt) thy_ctxt) u; haftmann@38533: in haftmann@38533: lthy haftmann@38536: |> target_abbrev prmode (b, mx') (global_rhs, t') xs haftmann@38533: |> ProofContext.add_abbrev Print_Mode.internal (b, t) |> snd haftmann@38533: |> Local_Defs.fixed_abbrev ((b, NoSyn), t) haftmann@38533: end; haftmann@38533: haftmann@38577: haftmann@38577: (** primitive theory operations **) haftmann@38577: haftmann@38577: fun theory_declaration decl lthy = haftmann@38577: let haftmann@38577: val global_decl = Morphism.form haftmann@38577: (Morphism.transform (Local_Theory.global_morphism lthy) decl); haftmann@38577: in haftmann@38577: lthy wenzelm@39032: |> Local_Theory.background_theory (Context.theory_map global_decl) haftmann@38577: |> Local_Theory.target (Context.proof_map global_decl) haftmann@38577: end; haftmann@38577: haftmann@38577: fun theory_foundation (((b, U), mx), (b_def, rhs)) (type_params, term_params) lthy = haftmann@38577: let wenzelm@39032: val (const, lthy2) = lthy |> Local_Theory.background_theory_result haftmann@38577: (Sign.declare_const ((b, U), mx)); haftmann@38577: val lhs = list_comb (const, type_params @ term_params); wenzelm@39032: val ((_, def), lthy3) = lthy2 |> Local_Theory.background_theory_result haftmann@38577: (Thm.add_def false false (b_def, Logic.mk_equals (lhs, rhs))); haftmann@38577: in ((lhs, def), lthy3) end; haftmann@38577: haftmann@38577: fun theory_notes kind global_facts lthy = haftmann@38577: let haftmann@38577: val thy = ProofContext.theory_of lthy; haftmann@38577: val global_facts' = Attrib.map_facts (Attrib.attribute_i thy) global_facts; haftmann@38577: in haftmann@38577: lthy wenzelm@39032: |> Local_Theory.background_theory (PureThy.note_thmss kind global_facts' #> snd) haftmann@38577: |> Local_Theory.target (ProofContext.note_thmss kind global_facts' #> snd) haftmann@38577: end; haftmann@38577: wenzelm@39032: fun theory_abbrev prmode ((b, mx), t) = wenzelm@39032: Local_Theory.background_theory wenzelm@39032: (Sign.add_abbrev (#1 prmode) (b, t) #-> wenzelm@39032: (fn (lhs, _) => Sign.notation true prmode [(lhs, mx)])); haftmann@38577: haftmann@38533: end;