haftmann@31723
|
1 |
(* Title: HOL/Import/import.ML
|
skalberg@14620
|
2 |
Author: Sebastian Skalberg (TU Muenchen)
|
skalberg@14620
|
3 |
*)
|
skalberg@14620
|
4 |
|
haftmann@31723
|
5 |
signature IMPORT =
|
skalberg@14516
|
6 |
sig
|
wenzelm@32740
|
7 |
val debug : bool Unsynchronized.ref
|
wenzelm@31265
|
8 |
val import_tac : Proof.context -> string * string -> tactic
|
wenzelm@18708
|
9 |
val setup : theory -> theory
|
skalberg@14516
|
10 |
end
|
skalberg@14516
|
11 |
|
wenzelm@33522
|
12 |
structure ImportData = Theory_Data
|
wenzelm@22846
|
13 |
(
|
wenzelm@33522
|
14 |
type T = ProofKernel.thm option array option (* FIXME mutable array !??!!! *)
|
wenzelm@22846
|
15 |
val empty = NONE
|
wenzelm@22846
|
16 |
val extend = I
|
wenzelm@33522
|
17 |
fun merge _ = NONE
|
wenzelm@22846
|
18 |
)
|
skalberg@14620
|
19 |
|
haftmann@47674
|
20 |
structure Import : IMPORT =
|
skalberg@14516
|
21 |
struct
|
skalberg@14516
|
22 |
|
wenzelm@32740
|
23 |
val debug = Unsynchronized.ref false
|
skalberg@14516
|
24 |
fun message s = if !debug then writeln s else ()
|
skalberg@14516
|
25 |
|
wenzelm@31265
|
26 |
fun import_tac ctxt (thyname, thmname) =
|
wenzelm@17370
|
27 |
if ! quick_and_dirty
|
wenzelm@43232
|
28 |
then Skip_Proof.cheat_tac (Proof_Context.theory_of ctxt)
|
skalberg@14516
|
29 |
else
|
skalberg@14516
|
30 |
fn th =>
|
wenzelm@21590
|
31 |
let
|
wenzelm@43232
|
32 |
val thy = Proof_Context.theory_of ctxt
|
wenzelm@21590
|
33 |
val prem = hd (prems_of th)
|
wenzelm@31265
|
34 |
val _ = message ("Import_tac: thyname=" ^ thyname ^ ", thmname=" ^ thmname)
|
wenzelm@31265
|
35 |
val _ = message ("Import trying to prove " ^ Syntax.string_of_term ctxt prem)
|
wenzelm@21590
|
36 |
val int_thms = case ImportData.get thy of
|
wenzelm@21590
|
37 |
NONE => fst (Replay.setup_int_thms thyname thy)
|
wenzelm@21590
|
38 |
| SOME a => a
|
wenzelm@21590
|
39 |
val proof = snd (ProofKernel.import_proof thyname thmname thy) thy
|
haftmann@47671
|
40 |
val importerthm = snd (Replay.replay_proof int_thms thyname thmname proof thy)
|
haftmann@47671
|
41 |
val thm = snd (ProofKernel.to_isa_thm importerthm)
|
haftmann@47671
|
42 |
val rew = ProofKernel.rewrite_importer_term (concl_of thm) thy
|
wenzelm@36945
|
43 |
val thm = Thm.equal_elim rew thm
|
haftmann@47671
|
44 |
val prew = ProofKernel.rewrite_importer_term prem thy
|
wenzelm@21590
|
45 |
val prem' = #2 (Logic.dest_equals (prop_of prew))
|
wenzelm@32111
|
46 |
val _ = message ("Import proved " ^ Display.string_of_thm ctxt thm)
|
wenzelm@17657
|
47 |
val thm = ProofKernel.disambiguate_frees thm
|
wenzelm@32111
|
48 |
val _ = message ("Disambiguate: " ^ Display.string_of_thm ctxt thm)
|
wenzelm@21590
|
49 |
in
|
wenzelm@21590
|
50 |
case Shuffler.set_prop thy prem' [("",thm)] of
|
wenzelm@21590
|
51 |
SOME (_,thm) =>
|
wenzelm@21590
|
52 |
let
|
wenzelm@21590
|
53 |
val _ = if prem' aconv (prop_of thm)
|
wenzelm@21590
|
54 |
then message "import: Terms match up"
|
wenzelm@21590
|
55 |
else message "import: Terms DO NOT match up"
|
wenzelm@36945
|
56 |
val thm' = Thm.equal_elim (Thm.symmetric prew) thm
|
wenzelm@31945
|
57 |
val res = Thm.bicompose true (false,thm',0) 1 th
|
wenzelm@21590
|
58 |
in
|
wenzelm@21590
|
59 |
res
|
wenzelm@21590
|
60 |
end
|
wenzelm@21590
|
61 |
| NONE => (message "import: set_prop didn't succeed"; no_tac th)
|
wenzelm@21590
|
62 |
end
|
wenzelm@21590
|
63 |
|
wenzelm@31265
|
64 |
val setup = Method.setup @{binding import}
|
wenzelm@31265
|
65 |
(Scan.lift (Args.name -- Args.name) >>
|
wenzelm@31265
|
66 |
(fn arg => fn ctxt => SIMPLE_METHOD (import_tac ctxt arg)))
|
haftmann@47670
|
67 |
"import external theorem"
|
skalberg@14516
|
68 |
|
haftmann@47676
|
69 |
(* Parsers *)
|
haftmann@47676
|
70 |
|
haftmann@47676
|
71 |
val import_segment = Parse.name >> set_import_segment
|
haftmann@47676
|
72 |
|
haftmann@47676
|
73 |
|
haftmann@47676
|
74 |
val import_theory = (Parse.name -- Parse.name) >> (fn (location, thyname) =>
|
haftmann@47676
|
75 |
fn thy =>
|
haftmann@47676
|
76 |
thy |> set_generating_thy thyname
|
haftmann@47676
|
77 |
|> Sign.add_path thyname
|
haftmann@47676
|
78 |
|> add_dump ("setup_theory " ^ quote location ^ " " ^ thyname))
|
haftmann@47676
|
79 |
|
haftmann@47676
|
80 |
fun end_import toks =
|
haftmann@47676
|
81 |
Scan.succeed
|
haftmann@47676
|
82 |
(fn thy =>
|
haftmann@47676
|
83 |
let
|
haftmann@47676
|
84 |
val thyname = get_generating_thy thy
|
haftmann@47676
|
85 |
val segname = get_import_segment thy
|
haftmann@47676
|
86 |
val (int_thms,facts) = Replay.setup_int_thms thyname thy
|
haftmann@47676
|
87 |
val thmnames = filter_out (should_ignore thyname thy) facts
|
haftmann@47676
|
88 |
fun replay thy = Replay.import_thms thyname int_thms thmnames thy
|
haftmann@47676
|
89 |
in
|
haftmann@47676
|
90 |
thy |> clear_import_thy
|
haftmann@47676
|
91 |
|> set_segment thyname segname
|
haftmann@47676
|
92 |
|> set_used_names facts
|
haftmann@47676
|
93 |
|> replay
|
haftmann@47676
|
94 |
|> clear_used_names
|
haftmann@47676
|
95 |
|> export_importer_pending
|
haftmann@47676
|
96 |
|> Sign.parent_path
|
haftmann@47676
|
97 |
|> dump_import_thy thyname
|
haftmann@47676
|
98 |
|> add_dump ";end_setup"
|
haftmann@47676
|
99 |
end) toks
|
haftmann@47676
|
100 |
|
haftmann@47676
|
101 |
val ignore_thms = Scan.repeat1 Parse.name
|
haftmann@47676
|
102 |
>> (fn ignored =>
|
haftmann@47676
|
103 |
fn thy =>
|
haftmann@47676
|
104 |
let
|
haftmann@47676
|
105 |
val thyname = get_import_thy thy
|
haftmann@47676
|
106 |
in
|
haftmann@47676
|
107 |
Library.foldl (fn (thy,thmname) => ignore_importer thyname thmname thy) (thy,ignored)
|
haftmann@47676
|
108 |
end)
|
haftmann@47676
|
109 |
|
haftmann@47676
|
110 |
val thm_maps = Scan.repeat1 (Parse.name --| Parse.$$$ ">" -- Parse.xname)
|
haftmann@47676
|
111 |
>> (fn thmmaps =>
|
haftmann@47676
|
112 |
fn thy =>
|
haftmann@47676
|
113 |
let
|
haftmann@47676
|
114 |
val thyname = get_import_thy thy
|
haftmann@47676
|
115 |
in
|
haftmann@47676
|
116 |
Library.foldl (fn (thy,(hol,isa)) => add_importer_mapping thyname hol isa thy) (thy,thmmaps)
|
haftmann@47676
|
117 |
end)
|
haftmann@47676
|
118 |
|
haftmann@47676
|
119 |
val type_maps = Scan.repeat1 (Parse.name --| Parse.$$$ ">" -- Parse.xname)
|
haftmann@47676
|
120 |
>> (fn typmaps =>
|
haftmann@47676
|
121 |
fn thy =>
|
haftmann@47676
|
122 |
let
|
haftmann@47676
|
123 |
val thyname = get_import_thy thy
|
haftmann@47676
|
124 |
in
|
haftmann@47676
|
125 |
Library.foldl (fn (thy,(hol,isa)) => add_importer_type_mapping thyname hol false isa thy) (thy,typmaps)
|
haftmann@47676
|
126 |
end)
|
haftmann@47676
|
127 |
|
haftmann@47676
|
128 |
val def_maps = Scan.repeat1 (Parse.name --| Parse.$$$ ">" -- Parse.xname)
|
haftmann@47676
|
129 |
>> (fn defmaps =>
|
haftmann@47676
|
130 |
fn thy =>
|
haftmann@47676
|
131 |
let
|
haftmann@47676
|
132 |
val thyname = get_import_thy thy
|
haftmann@47676
|
133 |
in
|
haftmann@47676
|
134 |
Library.foldl (fn (thy,(hol,isa)) => add_defmap thyname hol isa thy) (thy,defmaps)
|
haftmann@47676
|
135 |
end)
|
haftmann@47676
|
136 |
|
haftmann@47676
|
137 |
val const_renames = Scan.repeat1 (Parse.name --| Parse.$$$ ">" -- Parse.name)
|
haftmann@47676
|
138 |
>> (fn renames =>
|
haftmann@47676
|
139 |
fn thy =>
|
haftmann@47676
|
140 |
let
|
haftmann@47676
|
141 |
val thyname = get_import_thy thy
|
haftmann@47676
|
142 |
in
|
haftmann@47676
|
143 |
Library.foldl (fn (thy,(hol,isa)) => add_importer_const_renaming thyname hol isa thy) (thy,renames)
|
haftmann@47676
|
144 |
end)
|
haftmann@47676
|
145 |
|
haftmann@47676
|
146 |
val const_maps = Scan.repeat1 (Parse.name --| Parse.$$$ ">" -- Parse.xname -- Scan.option (Parse.$$$ "::" |-- Parse.typ))
|
haftmann@47676
|
147 |
>> (fn constmaps =>
|
haftmann@47676
|
148 |
fn thy =>
|
haftmann@47676
|
149 |
let
|
haftmann@47676
|
150 |
val thyname = get_import_thy thy
|
haftmann@47676
|
151 |
in
|
haftmann@47676
|
152 |
Library.foldl (fn (thy,((hol,isa),NONE)) => add_importer_const_mapping thyname hol false isa thy
|
haftmann@47676
|
153 |
| (thy,((hol,isa),SOME ty)) => add_importer_const_wt_mapping thyname hol false isa (Syntax.read_typ_global thy ty) thy) (thy,constmaps)
|
haftmann@47676
|
154 |
end)
|
haftmann@47676
|
155 |
|
haftmann@47676
|
156 |
val const_moves = Scan.repeat1 (Parse.name --| Parse.$$$ ">" -- Parse.xname -- Scan.option (Parse.$$$ "::" |-- Parse.typ))
|
haftmann@47676
|
157 |
>> (fn constmaps =>
|
haftmann@47676
|
158 |
fn thy =>
|
haftmann@47676
|
159 |
let
|
haftmann@47676
|
160 |
val thyname = get_import_thy thy
|
haftmann@47676
|
161 |
in
|
haftmann@47676
|
162 |
Library.foldl (fn (thy,((hol,isa),NONE)) => add_importer_const_mapping thyname hol true isa thy
|
haftmann@47676
|
163 |
| (thy,((hol,isa),SOME ty)) => add_importer_const_wt_mapping thyname hol true isa (Syntax.read_typ_global thy ty) thy) (thy,constmaps)
|
haftmann@47676
|
164 |
end)
|
haftmann@47676
|
165 |
|
haftmann@47676
|
166 |
fun import_thy location s =
|
haftmann@47676
|
167 |
let
|
haftmann@47676
|
168 |
val src_location = Path.append (Path.explode location) (Path.basic (s ^ ".imp"))
|
haftmann@47676
|
169 |
val is = TextIO.openIn (File.platform_path src_location)
|
haftmann@47676
|
170 |
val inp = TextIO.inputAll is
|
haftmann@47676
|
171 |
val _ = TextIO.closeIn is
|
haftmann@47676
|
172 |
val orig_source = Source.of_string inp
|
haftmann@47676
|
173 |
val symb_source = Symbol.source orig_source
|
haftmann@47676
|
174 |
val lexes =
|
haftmann@47676
|
175 |
(Scan.make_lexicon
|
haftmann@47676
|
176 |
(map Symbol.explode ["import_segment","ignore_thms","import","end",">","::","const_maps","const_moves","thm_maps","const_renames","type_maps","def_maps"]),
|
haftmann@47676
|
177 |
Scan.empty_lexicon)
|
haftmann@47676
|
178 |
val token_source = Token.source {do_recover = NONE} (K lexes) Position.start symb_source
|
haftmann@47676
|
179 |
val token_list = filter_out (Token.is_kind Token.Space) (Source.exhaust token_source)
|
haftmann@47676
|
180 |
val import_segmentP = Parse.$$$ "import_segment" |-- import_segment
|
haftmann@47676
|
181 |
val type_mapsP = Parse.$$$ "type_maps" |-- type_maps
|
haftmann@47676
|
182 |
val def_mapsP = Parse.$$$ "def_maps" |-- def_maps
|
haftmann@47676
|
183 |
val const_mapsP = Parse.$$$ "const_maps" |-- const_maps
|
haftmann@47676
|
184 |
val const_movesP = Parse.$$$ "const_moves" |-- const_moves
|
haftmann@47676
|
185 |
val const_renamesP = Parse.$$$ "const_renames" |-- const_renames
|
haftmann@47676
|
186 |
val ignore_thmsP = Parse.$$$ "ignore_thms" |-- ignore_thms
|
haftmann@47676
|
187 |
val thm_mapsP = Parse.$$$ "thm_maps" |-- thm_maps
|
haftmann@47676
|
188 |
val parser = type_mapsP || def_mapsP || const_mapsP || const_movesP || const_renamesP || thm_mapsP || ignore_thmsP || import_segmentP
|
haftmann@47676
|
189 |
val importP = Parse.$$$ "import" |-- Scan.repeat parser --| Parse.$$$ "end"
|
haftmann@47676
|
190 |
fun apply [] thy = thy
|
haftmann@47676
|
191 |
| apply (f::fs) thy = apply fs (f thy)
|
haftmann@47676
|
192 |
in
|
haftmann@47676
|
193 |
apply (set_replaying_thy s :: Sign.add_path s :: fst (importP token_list))
|
haftmann@47676
|
194 |
end
|
haftmann@47676
|
195 |
|
haftmann@47676
|
196 |
fun create_int_thms thyname thy =
|
haftmann@47676
|
197 |
if ! quick_and_dirty
|
haftmann@47676
|
198 |
then thy
|
haftmann@47676
|
199 |
else
|
haftmann@47676
|
200 |
case ImportData.get thy of
|
haftmann@47676
|
201 |
NONE => ImportData.put (SOME (fst (Replay.setup_int_thms thyname thy))) thy
|
haftmann@47676
|
202 |
| SOME _ => error "Import data not closed - forgotten an end_setup, mayhap?"
|
haftmann@47676
|
203 |
|
haftmann@47676
|
204 |
fun clear_int_thms thy =
|
haftmann@47676
|
205 |
if ! quick_and_dirty
|
haftmann@47676
|
206 |
then thy
|
haftmann@47676
|
207 |
else
|
haftmann@47676
|
208 |
case ImportData.get thy of
|
haftmann@47676
|
209 |
NONE => error "Import data already cleared - forgotten a setup_theory?"
|
haftmann@47676
|
210 |
| SOME _ => ImportData.put NONE thy
|
haftmann@47676
|
211 |
|
haftmann@47676
|
212 |
val setup_theory = (Parse.name -- Parse.name)
|
haftmann@47676
|
213 |
>>
|
haftmann@47676
|
214 |
(fn (location, thyname) =>
|
haftmann@47676
|
215 |
fn thy =>
|
haftmann@47676
|
216 |
(case Importer_DefThy.get thy of
|
haftmann@47676
|
217 |
NoImport => thy
|
haftmann@47676
|
218 |
| Generating _ => error "Currently generating a theory!"
|
haftmann@47676
|
219 |
| Replaying _ => thy |> clear_import_thy)
|
haftmann@47676
|
220 |
|> import_thy location thyname
|
haftmann@47676
|
221 |
|> create_int_thms thyname)
|
haftmann@47676
|
222 |
|
haftmann@47676
|
223 |
fun end_setup toks =
|
haftmann@47676
|
224 |
Scan.succeed
|
haftmann@47676
|
225 |
(fn thy =>
|
haftmann@47676
|
226 |
let
|
haftmann@47676
|
227 |
val thyname = get_import_thy thy
|
haftmann@47676
|
228 |
val segname = get_import_segment thy
|
haftmann@47676
|
229 |
in
|
haftmann@47676
|
230 |
thy |> set_segment thyname segname
|
haftmann@47676
|
231 |
|> clear_import_thy
|
haftmann@47676
|
232 |
|> clear_int_thms
|
haftmann@47676
|
233 |
|> Sign.parent_path
|
haftmann@47676
|
234 |
end) toks
|
haftmann@47676
|
235 |
|
haftmann@47676
|
236 |
val set_dump = Parse.string -- Parse.string >> setup_dump
|
haftmann@47676
|
237 |
fun fl_dump toks = Scan.succeed flush_dump toks
|
haftmann@47676
|
238 |
val append_dump = (Parse.verbatim || Parse.string) >> add_dump
|
haftmann@47676
|
239 |
|
haftmann@47676
|
240 |
val _ =
|
wenzelm@47821
|
241 |
(Outer_Syntax.command "import_segment"
|
haftmann@47676
|
242 |
"Set import segment name"
|
haftmann@47676
|
243 |
Keyword.thy_decl (import_segment >> Toplevel.theory);
|
haftmann@47676
|
244 |
Outer_Syntax.command "import_theory"
|
haftmann@47676
|
245 |
"Set default external theory name"
|
haftmann@47676
|
246 |
Keyword.thy_decl (import_theory >> Toplevel.theory);
|
haftmann@47676
|
247 |
Outer_Syntax.command "end_import"
|
haftmann@47676
|
248 |
"End external import"
|
haftmann@47676
|
249 |
Keyword.thy_decl (end_import >> Toplevel.theory);
|
haftmann@47676
|
250 |
Outer_Syntax.command "setup_theory"
|
haftmann@47676
|
251 |
"Setup external theory replaying"
|
haftmann@47676
|
252 |
Keyword.thy_decl (setup_theory >> Toplevel.theory);
|
haftmann@47676
|
253 |
Outer_Syntax.command "end_setup"
|
haftmann@47676
|
254 |
"End external setup"
|
haftmann@47676
|
255 |
Keyword.thy_decl (end_setup >> Toplevel.theory);
|
haftmann@47676
|
256 |
Outer_Syntax.command "setup_dump"
|
haftmann@47676
|
257 |
"Setup the dump file name"
|
haftmann@47676
|
258 |
Keyword.thy_decl (set_dump >> Toplevel.theory);
|
haftmann@47676
|
259 |
Outer_Syntax.command "append_dump"
|
haftmann@47676
|
260 |
"Add text to dump file"
|
haftmann@47676
|
261 |
Keyword.thy_decl (append_dump >> Toplevel.theory);
|
haftmann@47676
|
262 |
Outer_Syntax.command "flush_dump"
|
haftmann@47676
|
263 |
"Write the dump to file"
|
haftmann@47676
|
264 |
Keyword.thy_decl (fl_dump >> Toplevel.theory);
|
haftmann@47676
|
265 |
Outer_Syntax.command "ignore_thms"
|
haftmann@47676
|
266 |
"Theorems to ignore in next external theory import"
|
haftmann@47676
|
267 |
Keyword.thy_decl (ignore_thms >> Toplevel.theory);
|
haftmann@47676
|
268 |
Outer_Syntax.command "type_maps"
|
haftmann@47676
|
269 |
"Map external type names to existing Isabelle/HOL type names"
|
haftmann@47676
|
270 |
Keyword.thy_decl (type_maps >> Toplevel.theory);
|
haftmann@47676
|
271 |
Outer_Syntax.command "def_maps"
|
haftmann@47676
|
272 |
"Map external constant names to their primitive definitions"
|
haftmann@47676
|
273 |
Keyword.thy_decl (def_maps >> Toplevel.theory);
|
haftmann@47676
|
274 |
Outer_Syntax.command "thm_maps"
|
haftmann@47676
|
275 |
"Map external theorem names to existing Isabelle/HOL theorem names"
|
haftmann@47676
|
276 |
Keyword.thy_decl (thm_maps >> Toplevel.theory);
|
haftmann@47676
|
277 |
Outer_Syntax.command "const_renames"
|
haftmann@47676
|
278 |
"Rename external const names"
|
haftmann@47676
|
279 |
Keyword.thy_decl (const_renames >> Toplevel.theory);
|
haftmann@47676
|
280 |
Outer_Syntax.command "const_moves"
|
haftmann@47676
|
281 |
"Rename external const names to other external constants"
|
haftmann@47676
|
282 |
Keyword.thy_decl (const_moves >> Toplevel.theory);
|
haftmann@47676
|
283 |
Outer_Syntax.command "const_maps"
|
haftmann@47676
|
284 |
"Map external const names to existing Isabelle/HOL const names"
|
haftmann@47676
|
285 |
Keyword.thy_decl (const_maps >> Toplevel.theory));
|
haftmann@47676
|
286 |
|
skalberg@14516
|
287 |
end
|
wenzelm@15707
|
288 |
|