1 (* Title: Pure/Tools/invoke.ML
5 Schematic invocation of locale expression in proof context.
10 val invoke: string * Attrib.src list -> Locale.expr -> string option list ->
11 (string * string option * mixfix) list -> bool -> Proof.state -> Proof.state
12 val invoke_i: string * attribute list -> Locale.expr -> term option list ->
13 (string * typ option * mixfix) list -> bool -> Proof.state -> Proof.state
16 structure Invoke: INVOKE =
24 fun gen_invoke prep_att prep_expr parse_term add_fixes
25 (prfx, raw_atts) raw_expr raw_insts fixes int state =
27 val thy = Proof.theory_of state;
28 val _ = Proof.assert_forward_or_chain state;
29 val chain_facts = if can Proof.assert_chain state then Proof.the_facts state else [];
31 val more_atts = map (prep_att thy) raw_atts;
32 val (elems, _) = prep_expr raw_expr [] (ProofContext.init thy);
34 val prems = maps Element.prems_of elems;
35 val params = maps Element.params_of elems;
36 val types = rev (fold Term.add_tfrees prems (fold (Term.add_tfreesT o #2) params []));
38 val prems' = map Logic.varify prems;
39 val params' = map (Logic.varify o Free) params;
40 val types' = map (Logic.varifyT o TFree) types;
43 |> Proof.enter_forward
45 |> Proof.map_context (snd o add_fixes fixes);
46 val ctxt' = Proof.context_of state';
48 val raw_insts' = zip_options params' raw_insts
49 handle Library.UnequalLengths => error "Too many instantiations";
51 fun prep_inst (t, u) =
52 TypeInfer.constrain (TypeInfer.paramify_vars (Term.fastype_of t)) (parse_term ctxt' u);
53 val insts = map #1 raw_insts' ~~
54 Variable.polymorphic ctxt' (Syntax.check_terms ctxt' (map prep_inst raw_insts'));
56 replicate (length types') Drule.termI @
58 (case AList.lookup (op =) insts t of
59 SOME u => Drule.mk_term (Thm.cterm_of thy u)
60 | NONE => Drule.termI)) params';
63 [(("", []), map (rpair [] o Logic.mk_term o Logic.mk_type) types'),
64 (("", []), map (rpair [] o Logic.mk_term) params'),
65 (("", []), map (rpair [] o Element.mark_witness) prems')];
66 fun after_qed results =
68 Proof.map_context (fn ctxt =>
70 val ([res_types, res_params, res_prems], ctxt'') =
71 fold_burrow (apfst snd oo Variable.import_thms false) results ctxt';
73 val types'' = map (Logic.dest_type o Thm.term_of o Drule.dest_term) res_types;
74 val params'' = map (Thm.term_of o Drule.dest_term) res_params;
75 val inst = Element.morph_ctxt (Element.inst_morphism thy
76 (Symtab.make (map #1 types ~~ types''), Symtab.make (map #1 params ~~ params'')));
77 val elems' = map inst elems;
78 val prems'' = map2 Element.make_witness (maps Element.prems_of elems') res_prems;
80 maps (Element.facts_of thy) elems'
81 |> Element.satisfy_facts prems''
82 |> Element.generalize_facts ctxt'' ctxt
83 |> Attrib.map_facts (Attrib.attribute_i thy)
84 |> map (fn ((a, atts), bs) => ((a, atts @ more_atts), bs));
87 |> ProofContext.sticky_prefix prfx
88 |> ProofContext.qualified_names
89 |> (snd o ProofContext.note_thmss_i "" notes)
90 |> ProofContext.restore_naming ctxt
92 Proof.put_facts NONE #> Seq.single;
95 |> Proof.chain_facts chain_facts
96 |> Proof.local_goal (K (K ())) (K I) ProofContext.bind_propp_schematic_i
97 "invoke" NONE after_qed propp
98 |> Element.refine_witness
100 |> Proof.refine (Method.Basic (K (Method.METHOD (K (HEADGOAL (RANGE (map rtac inst_rules))))),
108 gen_invoke Attrib.attribute Locale.read_expr Syntax.parse_term ProofContext.add_fixes x;
109 fun invoke_i x = gen_invoke (K I) Locale.cert_expr (K I) ProofContext.add_fixes_i x;
114 (* concrete syntax *)
116 local structure P = OuterParse and K = OuterKeyword in
119 OuterSyntax.command "invoke"
120 "schematic invocation of locale expression in proof context"
121 (K.tag_proof K.prf_goal)
122 (SpecParse.opt_thm_name ":" -- SpecParse.locale_expr -- SpecParse.locale_insts -- P.for_fixes
123 >> (fn (((name, expr), (insts, _)), fixes) =>
124 Toplevel.print o Toplevel.proof' (invoke name expr insts fixes)));