author | wenzelm |
Wed, 06 Jan 2016 10:08:09 +0100 | |
changeset 62076 | 1add21f7cabc |
parent 62074 | 5b0bec0583bb |
child 62078 | 76399b8fde4d |
permissions | -rw-r--r-- |
60248
f7e4294216d2
updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents:
60209
diff
changeset
|
1 |
(* Title: HOL/Eisbach/method_closure.ML |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
2 |
Author: Daniel Matichuk, NICTA/UNSW |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
3 |
|
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
4 |
Facilities for treating method syntax as a closure, with abstraction |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
5 |
over terms, facts and other methods. |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
6 |
|
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
7 |
The 'method' command allows to define new proof methods by combining |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
8 |
existing ones with their usual syntax. |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
9 |
*) |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
10 |
|
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
11 |
signature METHOD_CLOSURE = |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
12 |
sig |
61818 | 13 |
val read: Proof.context -> Token.src -> Method.text |
14 |
val read_closure: Proof.context -> Token.src -> Method.text * Token.src |
|
15 |
val read_closure_input: Proof.context -> Input.source -> Method.text * Token.src |
|
16 |
val method_text: Method.text context_parser |
|
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
17 |
val method_evaluate: Method.text -> Proof.context -> Method.method |
62070
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
18 |
val apply_method: Proof.context -> string -> term list -> thm list list -> |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
19 |
(Proof.context -> Method.method) list -> Proof.context -> thm list -> context_tactic |
61910 | 20 |
val method: binding -> (binding * typ option * mixfix) list -> binding list -> |
21 |
binding list -> binding list -> Token.src -> local_theory -> string * local_theory |
|
22 |
val method_cmd: binding -> (binding * string option * mixfix) list -> binding list -> |
|
23 |
binding list -> binding list -> Token.src -> local_theory -> string * local_theory |
|
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
24 |
end; |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
25 |
|
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
26 |
structure Method_Closure: METHOD_CLOSURE = |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
27 |
struct |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
28 |
|
62070
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
29 |
(* auxiliary data for method definition *) |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
30 |
|
62070
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
31 |
structure Method_Definition = Proof_Data |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
32 |
( |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
33 |
type T = |
60287
adde5ce1e0a7
updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents:
60285
diff
changeset
|
34 |
(Proof.context -> Method.method) Symtab.table * (*dynamic methods*) |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
35 |
(term list -> Proof.context -> Method.method) (*recursive method*); |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
36 |
fun init _ : T = (Symtab.empty, fn _ => fn _ => Method.fail); |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
37 |
); |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
38 |
|
60287
adde5ce1e0a7
updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents:
60285
diff
changeset
|
39 |
fun lookup_dynamic_method ctxt full_name = |
62070
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
40 |
(case Symtab.lookup (#1 (Method_Definition.get ctxt)) full_name of |
62074 | 41 |
SOME m => m ctxt |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
42 |
| NONE => error ("Illegal use of internal Eisbach method: " ^ quote full_name)); |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
43 |
|
62070
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
44 |
val update_dynamic_method = Method_Definition.map o apfst o Symtab.update; |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
45 |
|
62073 | 46 |
fun get_recursive_method ts ctxt = #2 (Method_Definition.get ctxt) ts ctxt; |
62070
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
47 |
val put_recursive_method = Method_Definition.map o apsnd o K; |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
48 |
|
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
49 |
|
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
50 |
(* stored method closures *) |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
51 |
|
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
52 |
type closure = {vars: term list, named_thms: string list, methods: string list, body: Method.text}; |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
53 |
|
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
54 |
structure Data = Generic_Data |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
55 |
( |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
56 |
type T = closure Symtab.table; |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
57 |
val empty: T = Symtab.empty; |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
58 |
val extend = I; |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
59 |
fun merge data : T = Symtab.merge (K true) data; |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
60 |
); |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
61 |
|
62070
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
62 |
fun get_closure ctxt name = |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
63 |
(case Symtab.lookup (Data.get (Context.Proof ctxt)) name of |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
64 |
SOME closure => closure |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
65 |
| NONE => error ("Unknown Eisbach method: " ^ quote name)); |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
66 |
|
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
67 |
fun put_closure binding (closure: closure) lthy = |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
68 |
let |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
69 |
val name = Local_Theory.full_name lthy binding; |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
70 |
in |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
71 |
lthy |> Local_Theory.declaration {syntax = false, pervasive = true} (fn phi => |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
72 |
Data.map |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
73 |
(Symtab.update (name, |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
74 |
{vars = map (Morphism.term phi) (#vars closure), |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
75 |
named_thms = #named_thms closure, |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
76 |
methods = #methods closure, |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
77 |
body = (Method.map_source o map) (Token.transform phi) (#body closure)}))) |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
78 |
end; |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
79 |
|
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
80 |
|
61818 | 81 |
(* read method text *) |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
82 |
|
61818 | 83 |
fun read ctxt src = |
61917
35ec3757d3c1
check and report source at most once, notably in body of "match" method;
wenzelm
parents:
61912
diff
changeset
|
84 |
(case Scan.read Token.stopper (Parse.!!! (Method.parser 0 --| Scan.ahead Parse.eof)) src of |
35ec3757d3c1
check and report source at most once, notably in body of "match" method;
wenzelm
parents:
61912
diff
changeset
|
85 |
SOME (text, range) => |
35ec3757d3c1
check and report source at most once, notably in body of "match" method;
wenzelm
parents:
61912
diff
changeset
|
86 |
if Method.checked_text text then text |
35ec3757d3c1
check and report source at most once, notably in body of "match" method;
wenzelm
parents:
61912
diff
changeset
|
87 |
else (Method.report (text, range); Method.check_text ctxt text) |
35ec3757d3c1
check and report source at most once, notably in body of "match" method;
wenzelm
parents:
61912
diff
changeset
|
88 |
| NONE => |
35ec3757d3c1
check and report source at most once, notably in body of "match" method;
wenzelm
parents:
61912
diff
changeset
|
89 |
error ("Failed to parse method" ^ Position.here (Position.set_range (Token.range_of src)))); |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
90 |
|
61818 | 91 |
fun read_closure ctxt src0 = |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
92 |
let |
61814
1ca1142e1711
clarified type Token.src: plain token list, with usual implicit value assignment;
wenzelm
parents:
60553
diff
changeset
|
93 |
val src1 = map Token.init_assignable src0; |
61818 | 94 |
val text = read ctxt src1 |> Method.map_source (Method.method_closure ctxt); |
61814
1ca1142e1711
clarified type Token.src: plain token list, with usual implicit value assignment;
wenzelm
parents:
60553
diff
changeset
|
95 |
val src2 = map Token.closure src1; |
61818 | 96 |
in (text, src2) end; |
60209
022ca2799c73
updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents:
60119
diff
changeset
|
97 |
|
61818 | 98 |
fun read_closure_input ctxt = |
99 |
Input.source_explode #> |
|
100 |
Token.read_no_commands (Thy_Header.get_keywords' ctxt) (Scan.one Token.not_eof) #> |
|
101 |
read_closure ctxt; |
|
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
102 |
|
61818 | 103 |
val method_text = |
61912
ad710de5c576
more standard nesting of sub-language: Parse.text allows atomic entities without quotes;
wenzelm
parents:
61911
diff
changeset
|
104 |
Args.context -- Scan.lift (Parse.token Parse.text) >> (fn (ctxt, tok) => |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
105 |
(case Token.get_value tok of |
61818 | 106 |
SOME (Token.Source src) => read ctxt src |
107 |
| _ => |
|
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
108 |
let |
61818 | 109 |
val (text, src) = read_closure_input ctxt (Token.input_of tok); |
61814
1ca1142e1711
clarified type Token.src: plain token list, with usual implicit value assignment;
wenzelm
parents:
60553
diff
changeset
|
110 |
val _ = Token.assign (SOME (Token.Source src)) tok; |
61818 | 111 |
in text end)); |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
112 |
|
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
113 |
|
61919 | 114 |
(* evaluate method text *) |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
115 |
|
61903
d5ddd4866b7b
tuned -- with subtle change of order of evaluation;
wenzelm
parents:
61902
diff
changeset
|
116 |
fun method_evaluate text ctxt = |
61902 | 117 |
let |
61903
d5ddd4866b7b
tuned -- with subtle change of order of evaluation;
wenzelm
parents:
61902
diff
changeset
|
118 |
val text' = |
d5ddd4866b7b
tuned -- with subtle change of order of evaluation;
wenzelm
parents:
61902
diff
changeset
|
119 |
text |> (Method.map_source o map o Token.map_facts) |
61902 | 120 |
(fn SOME name => |
121 |
(case Proof_Context.lookup_fact ctxt name of |
|
122 |
SOME (false, ths) => K ths |
|
123 |
| _ => I) |
|
124 |
| NONE => I); |
|
125 |
val ctxt' = Config.put Method.closure false ctxt; |
|
61903
d5ddd4866b7b
tuned -- with subtle change of order of evaluation;
wenzelm
parents:
61902
diff
changeset
|
126 |
in fn facts => Method.RUNTIME (fn st => Method.evaluate text' ctxt' facts st) end; |
60287
adde5ce1e0a7
updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents:
60285
diff
changeset
|
127 |
|
62070
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
128 |
fun method_instantiate vars body ts ctxt = |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
129 |
let |
62076
1add21f7cabc
proper Pattern.match and corresponding Envir.subst_term, instead of Envir.norm_term of unify-family;
wenzelm
parents:
62074
diff
changeset
|
130 |
val thy = Proof_Context.theory_of ctxt; |
1add21f7cabc
proper Pattern.match and corresponding Envir.subst_term, instead of Envir.norm_term of unify-family;
wenzelm
parents:
62074
diff
changeset
|
131 |
val subst = fold (Pattern.match thy) (vars ~~ ts) (Vartab.empty, Vartab.empty); |
1add21f7cabc
proper Pattern.match and corresponding Envir.subst_term, instead of Envir.norm_term of unify-family;
wenzelm
parents:
62074
diff
changeset
|
132 |
val morphism = Morphism.term_morphism "method_instantiate" (Envir.subst_term subst); |
62070
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
133 |
val body' = (Method.map_source o map) (Token.transform morphism) body; |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
134 |
in method_evaluate body' ctxt end; |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
135 |
|
62074 | 136 |
|
137 |
||
138 |
(** apply method closure **) |
|
62070
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
139 |
|
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
140 |
fun recursive_method vars body ts = |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
141 |
let val m = method_instantiate vars body |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
142 |
in put_recursive_method m #> m ts end; |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
143 |
|
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
144 |
fun apply_method ctxt method_name terms facts methods = |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
145 |
let |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
146 |
fun declare_facts (name :: names) (fact :: facts) = |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
147 |
fold (Context.proof_map o Named_Theorems.add_thm name) fact |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
148 |
#> declare_facts names facts |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
149 |
| declare_facts _ [] = I |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
150 |
| declare_facts [] (_ :: _) = error ("Excessive facts for method " ^ quote method_name); |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
151 |
val {vars, named_thms, methods = method_args, body} = get_closure ctxt method_name; |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
152 |
in |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
153 |
declare_facts named_thms facts |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
154 |
#> fold update_dynamic_method (method_args ~~ methods) |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
155 |
#> recursive_method vars body terms |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
156 |
end; |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
157 |
|
61919 | 158 |
|
159 |
||
62070
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
160 |
(** define method closure **) |
61919 | 161 |
|
162 |
local |
|
163 |
||
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
164 |
fun setup_local_method binding lthy = |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
165 |
let |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
166 |
val full_name = Local_Theory.full_name lthy binding; |
62074 | 167 |
fun dynamic_method ctxt = lookup_dynamic_method ctxt full_name; |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
168 |
in |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
169 |
lthy |
60287
adde5ce1e0a7
updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents:
60285
diff
changeset
|
170 |
|> update_dynamic_method (full_name, K Method.fail) |
62074 | 171 |
|> Method.local_setup binding (Scan.succeed dynamic_method) "(internal)" |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
172 |
end; |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
173 |
|
62070
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
174 |
fun check_named_thm ctxt binding = |
61919 | 175 |
let |
62070
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
176 |
val bname = Binding.name_of binding; |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
177 |
val pos = Binding.pos_of binding; |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
178 |
val full_name = Named_Theorems.check ctxt (bname, pos); |
61919 | 179 |
val parser: Method.modifier parser = |
62070
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
180 |
Args.$$$ bname -- Args.colon |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
181 |
>> K {init = I, attribute = Named_Theorems.add full_name, pos = pos}; |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
182 |
in (full_name, parser) end; |
61919 | 183 |
|
61900 | 184 |
fun dummy_named_thm named_thm = |
185 |
Context.proof_map |
|
186 |
(Named_Theorems.clear named_thm |
|
187 |
#> Named_Theorems.add_thm named_thm Drule.free_dummy_thm); |
|
60285
b4f1a0a701ae
updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents:
60248
diff
changeset
|
188 |
|
61918 | 189 |
fun parse_term_args args = |
190 |
Args.context :|-- (fn ctxt => |
|
191 |
let |
|
192 |
val ctxt' = Proof_Context.set_mode (Proof_Context.mode_schematic) ctxt; |
|
193 |
||
194 |
fun parse T = |
|
195 |
(if T = propT then Syntax.parse_prop ctxt' else Syntax.parse_term ctxt') |
|
196 |
#> Type.constraint (Type_Infer.paramify_vars T); |
|
197 |
||
198 |
fun do_parse' T = |
|
199 |
Parse_Tools.name_term >> Parse_Tools.parse_val_cases (parse T); |
|
200 |
||
201 |
fun do_parse (Var (_, T)) = do_parse' T |
|
202 |
| do_parse (Free (_, T)) = do_parse' T |
|
203 |
| do_parse t = error ("Unexpected method parameter: " ^ Syntax.string_of_term ctxt' t); |
|
204 |
||
205 |
fun rep [] x = Scan.succeed [] x |
|
206 |
| rep (t :: ts) x = (do_parse t ::: rep ts) x; |
|
207 |
||
208 |
fun check ts = |
|
209 |
let |
|
210 |
val (ts, fs) = split_list ts; |
|
211 |
val ts' = Syntax.check_terms ctxt' ts |> Variable.polymorphic ctxt'; |
|
212 |
val _ = ListPair.app (fn (f, t) => f t) (fs, ts'); |
|
213 |
in ts' end; |
|
214 |
in Scan.lift (rep args) >> check end); |
|
215 |
||
62070
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
216 |
fun parse_method_args method_args = |
61919 | 217 |
let |
218 |
fun bind_method (name, text) ctxt = |
|
219 |
let |
|
220 |
val method = method_evaluate text; |
|
221 |
val inner_update = method o update_dynamic_method (name, K (method ctxt)); |
|
222 |
in update_dynamic_method (name, inner_update) ctxt end; |
|
223 |
||
224 |
fun rep [] x = Scan.succeed [] x |
|
62070
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
225 |
| rep (m :: ms) x = ((method_text >> pair m) ::: rep ms) x; |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
226 |
in rep method_args >> fold bind_method end; |
61919 | 227 |
|
61899 | 228 |
fun gen_method add_fixes name vars uses declares methods source lthy = |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
229 |
let |
61898 | 230 |
val (uses_internal, lthy1) = lthy |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
231 |
|> Proof_Context.concealed |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
232 |
|> Local_Theory.open_target |-> Proof_Context.private_scope |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
233 |
|> Local_Theory.map_background_naming (Name_Space.add_path (Binding.name_of name)) |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
234 |
|> Config.put Method.old_section_parser true |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
235 |
|> fold setup_local_method methods |
61898 | 236 |
|> fold_map (fn b => Named_Theorems.declare b "") uses; |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
237 |
|
60407 | 238 |
val (term_args, lthy2) = lthy1 |
60469 | 239 |
|> add_fixes vars |-> fold_map Proof_Context.inferred_param |>> map Free; |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
240 |
|
62070
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
241 |
val (named_thms, modifiers) = map (check_named_thm lthy2) (declares @ uses) |> split_list; |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
242 |
|
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
243 |
val method_args = map (Local_Theory.full_name lthy2) methods; |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
244 |
|
62073 | 245 |
fun parser args meth = |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
246 |
apfst (Config.put_generic Method.old_section_parser true) #> |
60287
adde5ce1e0a7
updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents:
60285
diff
changeset
|
247 |
(parse_term_args args -- |
62070
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
248 |
parse_method_args method_args --| |
60285
b4f1a0a701ae
updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents:
60248
diff
changeset
|
249 |
(Scan.depend (fn context => |
61900 | 250 |
Scan.succeed (fold Named_Theorems.clear uses_internal context, ())) -- |
62073 | 251 |
Method.sections modifiers)) >> (fn (ts, decl) => meth ts o decl); |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
252 |
|
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
253 |
val lthy3 = lthy2 |
60285
b4f1a0a701ae
updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents:
60248
diff
changeset
|
254 |
|> fold dummy_named_thm named_thms |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
255 |
|> Method.local_setup (Binding.make (Binding.name_of name, Position.none)) |
62073 | 256 |
(parser term_args get_recursive_method) "(internal)"; |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
257 |
|
61818 | 258 |
val (text, src) = read_closure lthy3 source; |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
259 |
|
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
260 |
val morphism = |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
261 |
Variable.export_morphism lthy3 |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
262 |
(lthy |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
263 |
|> Proof_Context.transfer (Proof_Context.theory_of lthy3) |
61814
1ca1142e1711
clarified type Token.src: plain token list, with usual implicit value assignment;
wenzelm
parents:
60553
diff
changeset
|
264 |
|> fold Token.declare_maxidx src |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
265 |
|> Variable.declare_maxidx (Variable.maxidx_of lthy3)); |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
266 |
|
61814
1ca1142e1711
clarified type Token.src: plain token list, with usual implicit value assignment;
wenzelm
parents:
60553
diff
changeset
|
267 |
val text' = (Method.map_source o map) (Token.transform morphism) text; |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
268 |
val term_args' = map (Morphism.term morphism) term_args; |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
269 |
in |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
270 |
lthy3 |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
271 |
|> Local_Theory.close_target |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
272 |
|> Proof_Context.restore_naming lthy |
62070
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
273 |
|> put_closure name |
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
274 |
{vars = term_args', named_thms = named_thms, methods = method_args, body = text'} |
62073 | 275 |
|> Method.local_setup name (parser term_args' (recursive_method term_args' text')) |
62070
b13b98a4d5f8
more realistic Eisbach method invocation from ML;
wenzelm
parents:
62069
diff
changeset
|
276 |
"(defined in Eisbach)" |
61911
fe2b7f4276be
proper full name within the name space of the method definition;
wenzelm
parents:
61910
diff
changeset
|
277 |
|> pair (Local_Theory.full_name lthy name) |
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
278 |
end; |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
279 |
|
61898 | 280 |
in |
281 |
||
61899 | 282 |
val method = gen_method Proof_Context.add_fixes; |
283 |
val method_cmd = gen_method Proof_Context.add_fixes_cmd; |
|
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
284 |
|
61898 | 285 |
end; |
286 |
||
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
287 |
val _ = |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
288 |
Outer_Syntax.local_theory @{command_keyword method} "Eisbach method definition" |
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
289 |
(Parse.binding -- Parse.for_fixes -- |
60287
adde5ce1e0a7
updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents:
60285
diff
changeset
|
290 |
((Scan.optional (@{keyword "methods"} |-- Parse.!!! (Scan.repeat1 Parse.binding)) []) -- |
adde5ce1e0a7
updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents:
60285
diff
changeset
|
291 |
(Scan.optional (@{keyword "uses"} |-- Parse.!!! (Scan.repeat1 Parse.binding)) [])) -- |
adde5ce1e0a7
updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents:
60285
diff
changeset
|
292 |
(Scan.optional (@{keyword "declares"} |-- Parse.!!! (Scan.repeat1 Parse.binding)) []) -- |
61898 | 293 |
Parse.!!! (@{keyword "="} |-- Parse.args1 (K true)) >> |
294 |
(fn ((((name, vars), (methods, uses)), declares), src) => |
|
61910 | 295 |
#2 o method_cmd name vars uses declares methods src)); |
61814
1ca1142e1711
clarified type Token.src: plain token list, with usual implicit value assignment;
wenzelm
parents:
60553
diff
changeset
|
296 |
|
60119
54bea620e54f
added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
297 |
end; |