author | wenzelm |
Mon, 11 Feb 2013 14:39:04 +0100 | |
changeset 51085 | d90218288d51 |
parent 50787 | 065c684130ad |
child 51658 | 21c10672633b |
permissions | -rw-r--r-- |
41561 | 1 |
(* Title: HOL/SPARK/Tools/spark_commands.ML |
2 |
Author: Stefan Berghofer |
|
3 |
Copyright: secunet Security Networks AG |
|
4 |
||
5 |
Isar commands for handling SPARK/Ada verification conditions. |
|
6 |
*) |
|
7 |
||
8 |
signature SPARK_COMMANDS = |
|
9 |
sig |
|
10 |
val setup: theory -> theory |
|
11 |
end |
|
12 |
||
13 |
structure SPARK_Commands: SPARK_COMMANDS = |
|
14 |
struct |
|
15 |
||
48908
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
16 |
fun spark_open header (prfx, files) thy = |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
17 |
let |
49444 | 18 |
val ([{src_path, text = vc_text, pos = vc_pos, ...}: Token.file, |
48908
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
19 |
{text = fdl_text, pos = fdl_pos, ...}, |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
20 |
{text = rls_text, pos = rls_pos, ...}], thy') = files thy; |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
21 |
val base = fst (Path.split_ext (File.full_path (Thy_Load.master_directory thy') src_path)); |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
22 |
in |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
23 |
SPARK_VCs.set_vcs |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
24 |
(snd (Fdl_Parser.parse_declarations fdl_pos fdl_text)) |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
25 |
(Fdl_Parser.parse_rules rls_pos rls_text) |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
26 |
(snd (Fdl_Parser.parse_vcs header vc_pos vc_text)) |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
27 |
base prfx thy' |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
28 |
end; |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
29 |
|
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
30 |
(* FIXME *) |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
31 |
fun spark_open_old (vc_name, prfx) thy = |
41561 | 32 |
let |
43702
24fb44c1086a
more abstract Thy_Load.load_file/use_file for external theory resources;
wenzelm
parents:
43547
diff
changeset
|
33 |
val ((vc_path, vc_id), vc_text) = Thy_Load.load_file thy (Path.explode vc_name); |
41887
ececcbd08d35
simplified Thy_Info.check_file -- discontinued load path;
wenzelm
parents:
41592
diff
changeset
|
34 |
val (base, header) = |
ececcbd08d35
simplified Thy_Info.check_file -- discontinued load path;
wenzelm
parents:
41592
diff
changeset
|
35 |
(case Path.split_ext vc_path of |
41561 | 36 |
(base, "vcg") => (base, Fdl_Lexer.vcg_header >> K ()) |
37 |
| (base, "siv") => (base, Fdl_Lexer.siv_header >> K ()) |
|
38 |
| _ => error "File name must end with .vcg or .siv"); |
|
39 |
val fdl_path = Path.ext "fdl" base; |
|
40 |
val rls_path = Path.ext "rls" base; |
|
41 |
in |
|
42 |
SPARK_VCs.set_vcs |
|
41948 | 43 |
(snd (Fdl_Parser.parse_declarations (Path.position fdl_path) (File.read fdl_path))) |
44 |
(Fdl_Parser.parse_rules (Path.position rls_path) (File.read rls_path)) |
|
43702
24fb44c1086a
more abstract Thy_Load.load_file/use_file for external theory resources;
wenzelm
parents:
43547
diff
changeset
|
45 |
(snd (Fdl_Parser.parse_vcs header (Path.position vc_path) vc_text)) |
42396
0869ce2006eb
Package prefix is now taken into account when looking up user-defined
berghofe
parents:
42361
diff
changeset
|
46 |
base prfx thy |
41561 | 47 |
end; |
48 |
||
49 |
fun add_proof_fun_cmd pf thy = |
|
42361 | 50 |
let val ctxt = Proof_Context.init_global thy |
41561 | 51 |
in SPARK_VCs.add_proof_fun |
52 |
(fn optT => Syntax.parse_term ctxt #> |
|
53 |
the_default I (Option.map Type.constraint optT) #> |
|
54 |
Syntax.check_term ctxt) pf thy |
|
55 |
end; |
|
56 |
||
46725
d34ec0512dfb
Added infrastructure for mapping SPARK field / constructor names
berghofe
parents:
43702
diff
changeset
|
57 |
fun add_spark_type_cmd (s, (raw_typ, cmap)) thy = |
d34ec0512dfb
Added infrastructure for mapping SPARK field / constructor names
berghofe
parents:
43702
diff
changeset
|
58 |
SPARK_VCs.add_type (s, (Syntax.read_typ_global thy raw_typ, cmap)) thy; |
42356
e8777e3ea6ef
Added command for associating user-defined types with SPARK types.
berghofe
parents:
42003
diff
changeset
|
59 |
|
41561 | 60 |
fun get_vc thy vc_name = |
48167 | 61 |
(case SPARK_VCs.lookup_vc thy false vc_name of |
41561 | 62 |
SOME (ctxt, (_, proved, ctxt', stmt)) => |
41896
582cccdda0ed
spark_end now joins proofs of VCs before writing *.prv file.
berghofe
parents:
41887
diff
changeset
|
63 |
if is_some proved then |
41561 | 64 |
error ("The verification condition " ^ |
65 |
quote vc_name ^ " has already been proved.") |
|
66 |
else (ctxt @ [ctxt'], stmt) |
|
67 |
| NONE => error ("There is no verification condition " ^ |
|
68 |
quote vc_name ^ ".")); |
|
69 |
||
70 |
fun prove_vc vc_name lthy = |
|
71 |
let |
|
42361 | 72 |
val thy = Proof_Context.theory_of lthy; |
41561 | 73 |
val (ctxt, stmt) = get_vc thy vc_name |
74 |
in |
|
75 |
Specification.theorem Thm.theoremK NONE |
|
41896
582cccdda0ed
spark_end now joins proofs of VCs before writing *.prv file.
berghofe
parents:
41887
diff
changeset
|
76 |
(fn thmss => (Local_Theory.background_theory |
582cccdda0ed
spark_end now joins proofs of VCs before writing *.prv file.
berghofe
parents:
41887
diff
changeset
|
77 |
(SPARK_VCs.mark_proved vc_name (flat thmss)))) |
50787
065c684130ad
disable interactive mode of Specification.theorem with its slow printing of results;
wenzelm
parents:
49444
diff
changeset
|
78 |
(Binding.name vc_name, []) [] ctxt stmt false lthy |
41561 | 79 |
end; |
80 |
||
41896
582cccdda0ed
spark_end now joins proofs of VCs before writing *.prv file.
berghofe
parents:
41887
diff
changeset
|
81 |
fun string_of_status NONE = "(unproved)" |
582cccdda0ed
spark_end now joins proofs of VCs before writing *.prv file.
berghofe
parents:
41887
diff
changeset
|
82 |
| string_of_status (SOME _) = "(proved)"; |
41561 | 83 |
|
84 |
fun show_status (p, f) = Toplevel.no_timing o Toplevel.keep (fn state => |
|
85 |
let |
|
86 |
val thy = Toplevel.theory_of state; |
|
87 |
||
48167 | 88 |
val (context, defs, vcs) = SPARK_VCs.get_vcs thy true; |
41561 | 89 |
|
90 |
val vcs' = AList.coalesce (op =) (map_filter |
|
91 |
(fn (name, (trace, status, ctxt, stmt)) => |
|
92 |
if p status then |
|
93 |
SOME (trace, (name, status, ctxt, stmt)) |
|
94 |
else NONE) vcs); |
|
95 |
||
96 |
val ctxt = state |> |
|
97 |
Toplevel.theory_of |> |
|
42361 | 98 |
Proof_Context.init_global |> |
41561 | 99 |
Context.proof_map (fold Element.init context) |
100 |
in |
|
41592 | 101 |
[Pretty.str "Context:", |
102 |
Pretty.chunks (maps (Element.pretty_ctxt ctxt) context), |
|
41561 | 103 |
|
41592 | 104 |
Pretty.str "Definitions:", |
43547
f3a8476285c6
clarified Binding.pretty/print: no quotes, only markup -- Binding.str_of is rendered obsolete;
wenzelm
parents:
42396
diff
changeset
|
105 |
Pretty.chunks (map (fn (b, th) => Pretty.block |
f3a8476285c6
clarified Binding.pretty/print: no quotes, only markup -- Binding.str_of is rendered obsolete;
wenzelm
parents:
42396
diff
changeset
|
106 |
[Binding.pretty b, Pretty.str ":", |
41561 | 107 |
Pretty.brk 1, |
108 |
Display.pretty_thm ctxt th]) |
|
41592 | 109 |
defs), |
41561 | 110 |
|
41592 | 111 |
Pretty.str "Verification conditions:", |
112 |
Pretty.chunks2 (maps (fn (trace, vcs'') => |
|
41561 | 113 |
Pretty.str trace :: |
114 |
map (fn (name, status, context', stmt) => |
|
115 |
Pretty.big_list (name ^ " " ^ f status) |
|
116 |
(Element.pretty_ctxt ctxt context' @ |
|
41592 | 117 |
Element.pretty_stmt ctxt stmt)) vcs'') vcs')] |> |
118 |
Pretty.chunks2 |> Pretty.writeln |
|
41561 | 119 |
end); |
120 |
||
121 |
val _ = |
|
46961
5c6955f487e5
outer syntax command definitions based on formal command_spec derived from theory header declarations;
wenzelm
parents:
46725
diff
changeset
|
122 |
Outer_Syntax.command @{command_spec "spark_open"} |
41586 | 123 |
"open a new SPARK environment and load a SPARK-generated .vcg or .siv file" |
48908
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
124 |
(Parse.name -- Parse.parname >> (Toplevel.theory o spark_open_old)); |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
125 |
|
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
126 |
val _ = |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
127 |
Outer_Syntax.command @{command_spec "spark_open_vcg"} |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
128 |
"open a new SPARK environment and load a SPARK-generated .vcg file" |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
129 |
(Parse.parname -- Thy_Load.provide_parse_files "spark_open_vcg" |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
130 |
>> (Toplevel.theory o spark_open Fdl_Lexer.vcg_header)); |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
131 |
|
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
132 |
val _ = |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
133 |
Outer_Syntax.command @{command_spec "spark_open_siv"} |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
134 |
"open a new SPARK environment and load a SPARK-generated .siv file" |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
135 |
(Parse.parname -- Thy_Load.provide_parse_files "spark_open_siv" |
713f24d7a40f
added specific 'spark_open_vcg' and 'spark_open_siv' with formal management of corresponding source files;
wenzelm
parents:
48167
diff
changeset
|
136 |
>> (Toplevel.theory o spark_open Fdl_Lexer.siv_header)); |
41561 | 137 |
|
138 |
val pfun_type = Scan.option |
|
139 |
(Args.parens (Parse.list1 Parse.name) --| Args.colon -- Parse.name); |
|
140 |
||
141 |
val _ = |
|
46961
5c6955f487e5
outer syntax command definitions based on formal command_spec derived from theory header declarations;
wenzelm
parents:
46725
diff
changeset
|
142 |
Outer_Syntax.command @{command_spec "spark_proof_functions"} |
41586 | 143 |
"associate SPARK proof functions with terms" |
41561 | 144 |
(Scan.repeat1 (Parse.name -- (pfun_type --| Args.$$$ "=" -- Parse.term)) >> |
46961
5c6955f487e5
outer syntax command definitions based on formal command_spec derived from theory header declarations;
wenzelm
parents:
46725
diff
changeset
|
145 |
(Toplevel.theory o fold add_proof_fun_cmd)); |
41561 | 146 |
|
147 |
val _ = |
|
46961
5c6955f487e5
outer syntax command definitions based on formal command_spec derived from theory header declarations;
wenzelm
parents:
46725
diff
changeset
|
148 |
Outer_Syntax.command @{command_spec "spark_types"} |
42356
e8777e3ea6ef
Added command for associating user-defined types with SPARK types.
berghofe
parents:
42003
diff
changeset
|
149 |
"associate SPARK types with types" |
46725
d34ec0512dfb
Added infrastructure for mapping SPARK field / constructor names
berghofe
parents:
43702
diff
changeset
|
150 |
(Scan.repeat1 (Parse.name -- Parse.!!! (Args.$$$ "=" |-- Parse.typ -- |
d34ec0512dfb
Added infrastructure for mapping SPARK field / constructor names
berghofe
parents:
43702
diff
changeset
|
151 |
Scan.optional (Args.parens (Parse.list1 |
d34ec0512dfb
Added infrastructure for mapping SPARK field / constructor names
berghofe
parents:
43702
diff
changeset
|
152 |
(Parse.name -- Parse.!!! (Args.$$$ "=" |-- Parse.xname)))) [])) >> |
42356
e8777e3ea6ef
Added command for associating user-defined types with SPARK types.
berghofe
parents:
42003
diff
changeset
|
153 |
(Toplevel.theory o fold add_spark_type_cmd)); |
e8777e3ea6ef
Added command for associating user-defined types with SPARK types.
berghofe
parents:
42003
diff
changeset
|
154 |
|
e8777e3ea6ef
Added command for associating user-defined types with SPARK types.
berghofe
parents:
42003
diff
changeset
|
155 |
val _ = |
46961
5c6955f487e5
outer syntax command definitions based on formal command_spec derived from theory header declarations;
wenzelm
parents:
46725
diff
changeset
|
156 |
Outer_Syntax.command @{command_spec "spark_vc"} |
41586 | 157 |
"enter into proof mode for a specific verification condition" |
41561 | 158 |
(Parse.name >> (fn name => |
159 |
(Toplevel.print o Toplevel.local_theory_to_proof NONE (prove_vc name)))); |
|
160 |
||
161 |
val _ = |
|
46961
5c6955f487e5
outer syntax command definitions based on formal command_spec derived from theory header declarations;
wenzelm
parents:
46725
diff
changeset
|
162 |
Outer_Syntax.improper_command @{command_spec "spark_status"} |
41586 | 163 |
"show the name and state of all loaded verification conditions" |
41561 | 164 |
(Scan.optional |
165 |
(Args.parens |
|
41896
582cccdda0ed
spark_end now joins proofs of VCs before writing *.prv file.
berghofe
parents:
41887
diff
changeset
|
166 |
( Args.$$$ "proved" >> K (is_some, K "") |
582cccdda0ed
spark_end now joins proofs of VCs before writing *.prv file.
berghofe
parents:
41887
diff
changeset
|
167 |
|| Args.$$$ "unproved" >> K (is_none, K ""))) |
41561 | 168 |
(K true, string_of_status) >> show_status); |
169 |
||
170 |
val _ = |
|
46961
5c6955f487e5
outer syntax command definitions based on formal command_spec derived from theory header declarations;
wenzelm
parents:
46725
diff
changeset
|
171 |
Outer_Syntax.command @{command_spec "spark_end"} |
41586 | 172 |
"close the current SPARK environment" |
48167 | 173 |
(Scan.optional (@{keyword "("} |-- Parse.!!! |
174 |
(Parse.reserved "incomplete" --| @{keyword ")"}) >> K true) false >> |
|
175 |
(Toplevel.theory o SPARK_VCs.close)); |
|
41561 | 176 |
|
177 |
val setup = Theory.at_end (fn thy => |
|
178 |
let |
|
179 |
val _ = SPARK_VCs.is_closed thy |
|
180 |
orelse error ("Found the end of the theory, " ^ |
|
181 |
"but the last SPARK environment is still open.") |
|
182 |
in NONE end); |
|
183 |
||
184 |
end; |