author | bulwahn |
Mon, 22 Mar 2010 08:30:13 +0100 | |
changeset 35890 | 14a0993fe64b |
parent 35856 | f81557a124d5 |
child 35862 | c2039b00ff0d |
permissions | -rw-r--r-- |
33419 | 1 |
(* Title: HOL/Boogie/Tools/boogie_loader.ML |
2 |
Author: Sascha Boehme, TU Muenchen |
|
3 |
||
4 |
Loading and interpreting Boogie-generated files. |
|
5 |
*) |
|
6 |
||
7 |
signature BOOGIE_LOADER = |
|
8 |
sig |
|
35125
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
9 |
val load_b2i: bool -> (string * int) list -> Path.T -> theory -> theory |
33419 | 10 |
end |
11 |
||
12 |
structure Boogie_Loader: BOOGIE_LOADER = |
|
13 |
struct |
|
14 |
||
34011
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
15 |
fun log verbose text args x = |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
16 |
if verbose andalso not (null args) |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
17 |
then (Pretty.writeln (Pretty.big_list text (map Pretty.str args)); x) |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
18 |
else x |
33419 | 19 |
|
20 |
val isabelle_name = |
|
21 |
let |
|
33445
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
22 |
fun purge s = if Symbol.is_letter s orelse Symbol.is_digit s then s else |
33419 | 23 |
(case s of |
24 |
"." => "_o_" |
|
25 |
| "_" => "_n_" |
|
26 |
| "$" => "_S_" |
|
27 |
| "@" => "_G_" |
|
28 |
| "#" => "_H_" |
|
29 |
| "^" => "_T_" |
|
30 |
| _ => ("_" ^ string_of_int (ord s) ^ "_")) |
|
31 |
in prefix "b_" o translate_string purge end |
|
32 |
||
34959
cd7c98fdab80
drop underscores at end of names coming from Boogie
boehmes
parents:
34181
diff
changeset
|
33 |
fun drop_underscore s = |
cd7c98fdab80
drop underscores at end of names coming from Boogie
boehmes
parents:
34181
diff
changeset
|
34 |
try (unsuffix "_") s |
cd7c98fdab80
drop underscores at end of names coming from Boogie
boehmes
parents:
34181
diff
changeset
|
35 |
|> Option.map drop_underscore |
cd7c98fdab80
drop underscores at end of names coming from Boogie
boehmes
parents:
34181
diff
changeset
|
36 |
|> the_default s |
cd7c98fdab80
drop underscores at end of names coming from Boogie
boehmes
parents:
34181
diff
changeset
|
37 |
|
33445
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
38 |
val short_name = |
34959
cd7c98fdab80
drop underscores at end of names coming from Boogie
boehmes
parents:
34181
diff
changeset
|
39 |
translate_string (fn s => if Symbol.is_letdig s then s else "") #> |
cd7c98fdab80
drop underscores at end of names coming from Boogie
boehmes
parents:
34181
diff
changeset
|
40 |
drop_underscore |
33445
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
41 |
|
34068
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
42 |
(* these prefixes must be distinct: *) |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
43 |
val var_prefix = "V_" |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
44 |
val label_prefix = "L_" |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
45 |
val position_prefix = "P_" |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
46 |
|
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
47 |
val no_label_name = label_prefix ^ "unknown" |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
48 |
fun label_name line col = |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
49 |
if line = 0 orelse col = 0 then no_label_name |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
50 |
else label_prefix ^ string_of_int line ^ "_" ^ string_of_int col |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
51 |
|
35358 | 52 |
fun mk_syntax name i = |
53 |
let |
|
35390 | 54 |
val syn = Syntax.escape name |
35391 | 55 |
val args = space_implode ",/ " (replicate i "_") |
35358 | 56 |
in |
57 |
if i = 0 then Mixfix (syn, [], 1000) |
|
58 |
else Mixfix (syn ^ "()'(/" ^ args ^ "')", replicate i 0, 1000) |
|
59 |
end |
|
60 |
||
33445
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
61 |
|
34011
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
62 |
datatype attribute_value = StringValue of string | TermValue of term |
33419 | 63 |
|
64 |
||
65 |
||
66 |
local |
|
67 |
fun lookup_type_name thy name arity = |
|
68 |
let val intern = Sign.intern_type thy name |
|
69 |
in |
|
70 |
if Sign.declared_tyname thy intern |
|
71 |
then |
|
72 |
if Sign.arity_number thy intern = arity then SOME intern |
|
73 |
else error ("Boogie: type already declared with different arity: " ^ |
|
74 |
quote name) |
|
75 |
else NONE |
|
76 |
end |
|
77 |
||
34011
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
78 |
fun log_new bname name = bname ^ " (as " ^ name ^ ")" |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
79 |
fun log_ex bname name = "[" ^ bname ^ " has already been declared as " ^ |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
80 |
name ^ "]" |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
81 |
|
33419 | 82 |
fun declare (name, arity) thy = |
83 |
let val isa_name = isabelle_name name |
|
84 |
in |
|
85 |
(case lookup_type_name thy isa_name arity of |
|
34011
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
86 |
SOME type_name => (((name, type_name), log_ex name type_name), thy) |
33419 | 87 |
| NONE => |
88 |
let |
|
35837 | 89 |
val args = map (rpair dummyS) (Name.invents Name.context "'a" arity) |
35625 | 90 |
val (T, thy') = |
35682 | 91 |
Typedecl.typedecl_global (Binding.name isa_name, args, mk_syntax name arity) thy |
33419 | 92 |
val type_name = fst (Term.dest_Type T) |
34011
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
93 |
in (((name, type_name), log_new name type_name), thy') end) |
33419 | 94 |
end |
95 |
in |
|
96 |
fun declare_types verbose tys = |
|
34011
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
97 |
fold_map declare tys #>> split_list #-> (fn (tds, logs) => |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
98 |
log verbose "Declared types:" logs #> |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
99 |
rpair (Symtab.make tds)) |
33419 | 100 |
end |
101 |
||
102 |
||
103 |
||
104 |
local |
|
33893
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
105 |
fun maybe_builtin T = |
33419 | 106 |
let |
107 |
fun const name = SOME (Const (name, T)) |
|
34068
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
108 |
fun const2_abs name = |
34181
003333ffa543
merged verification condition structure and term representation in one datatype,
boehmes
parents:
34068
diff
changeset
|
109 |
let val U = Term.domain_type T |
34068
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
110 |
in |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
111 |
SOME (Abs (Name.uu, U, Abs (Name.uu, U, |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
112 |
Const (name, T) $ Bound 0 $ Bound 1))) |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
113 |
end |
33419 | 114 |
|
115 |
fun choose builtin = |
|
116 |
(case builtin of |
|
34068
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
117 |
"bvnot" => const @{const_name bitNOT} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
118 |
| "bvand" => const @{const_name bitAND} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
119 |
| "bvor" => const @{const_name bitOR} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
120 |
| "bvxor" => const @{const_name bitXOR} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
121 |
| "bvadd" => const @{const_name plus} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
122 |
| "bvneg" => const @{const_name uminus} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
123 |
| "bvsub" => const @{const_name minus} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
124 |
| "bvmul" => const @{const_name times} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
125 |
| "bvudiv" => const @{const_name div} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
126 |
| "bvurem" => const @{const_name mod} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
127 |
| "bvsdiv" => const @{const_name sdiv} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
128 |
| "bvsrem" => const @{const_name srem} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
129 |
| "bvshl" => const @{const_name bv_shl} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
130 |
| "bvlshr" => const @{const_name bv_lshr} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
131 |
| "bvashr" => const @{const_name bv_ashr} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
132 |
| "bvult" => const @{const_name less} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
133 |
| "bvule" => const @{const_name less_eq} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
134 |
| "bvugt" => const2_abs @{const_name less} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
135 |
| "bvuge" => const2_abs @{const_name less_eq} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
136 |
| "bvslt" => const @{const_name word_sless} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
137 |
| "bvsle" => const @{const_name word_sle} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
138 |
| "bvsgt" => const2_abs @{const_name word_sless} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
139 |
| "bvsge" => const2_abs @{const_name word_sle} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
140 |
| "zero_extend" => const @{const_name ucast} |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
141 |
| "sign_extend" => const @{const_name scast} |
33419 | 142 |
| _ => NONE) |
143 |
||
144 |
fun is_builtin att = |
|
145 |
(case att of |
|
146 |
("bvbuiltin", [StringValue builtin]) => choose builtin |
|
147 |
| ("bvint", [StringValue "ITE"]) => const @{const_name If} |
|
148 |
| _ => NONE) |
|
149 |
in get_first is_builtin end |
|
150 |
||
151 |
fun lookup_const thy name T = |
|
33465 | 152 |
let val intern = Sign.intern_const thy name |
33419 | 153 |
in |
154 |
if Sign.declared_const thy intern |
|
155 |
then |
|
33465 | 156 |
if Sign.typ_instance thy (T, Sign.the_const_type thy intern) |
33419 | 157 |
then SOME (Const (intern, T)) |
158 |
else error ("Boogie: function already declared with different type: " ^ |
|
159 |
quote name) |
|
160 |
else NONE |
|
161 |
end |
|
162 |
||
34011
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
163 |
fun log_term thy t = Syntax.string_of_term_global thy t |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
164 |
fun log_new thy name t = name ^ " (as " ^ log_term thy t ^ ")" |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
165 |
fun log_ex thy name t = "[" ^ name ^ " has already been declared as " ^ |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
166 |
log_term thy t ^ "]" |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
167 |
fun log_builtin thy name t = "[" ^ name ^ " has been identified as " ^ |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
168 |
log_term thy t ^ "]" |
33419 | 169 |
|
34011
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
170 |
fun declare' name isa_name T arity atts thy = |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
171 |
(case lookup_const thy isa_name T of |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
172 |
SOME t => (((name, t), log_ex thy name t), thy) |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
173 |
| NONE => |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
174 |
(case maybe_builtin T atts of |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
175 |
SOME t => (((name, t), log_builtin thy name t), thy) |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
176 |
| NONE => |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
177 |
thy |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
178 |
|> Sign.declare_const ((Binding.name isa_name, T), |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
179 |
mk_syntax name arity) |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
180 |
|> (fn (t, thy') => (((name, t), log_new thy' name t), thy')))) |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
181 |
fun declare (name, ((Ts, T), atts)) = |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
182 |
declare' name (isabelle_name name) (Ts ---> T) (length Ts) atts |
33893
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
183 |
|
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
184 |
fun uniques fns fds = |
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
185 |
let |
34068
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
186 |
fun is_unique (name, (([], _), atts)) = |
33893
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
187 |
(case AList.lookup (op =) atts "unique" of |
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
188 |
SOME _ => Symtab.lookup fds name |
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
189 |
| NONE => NONE) |
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
190 |
| is_unique _ = NONE |
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
191 |
fun mk_unique_axiom T ts = |
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
192 |
Const (@{const_name distinct}, HOLogic.listT T --> @{typ bool}) $ |
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
193 |
HOLogic.mk_list T ts |
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
194 |
in |
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
195 |
map_filter is_unique fns |
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
196 |
|> map (swap o Term.dest_Const) |
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
197 |
|> AList.group (op =) |
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
198 |
|> map (fn (T, ns) => mk_unique_axiom T (map (Const o rpair T) ns)) |
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
199 |
end |
33419 | 200 |
in |
201 |
fun declare_functions verbose fns = |
|
34011
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
202 |
fold_map declare fns #>> split_list #-> (fn (fds, logs) => |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
203 |
log verbose "Loaded constants:" logs #> |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
204 |
rpair (` (uniques fns) (Symtab.make fds))) |
33419 | 205 |
end |
206 |
||
207 |
||
208 |
||
209 |
local |
|
210 |
fun name_axioms axs = |
|
211 |
let fun mk_name idx = "axiom_" ^ string_of_int (idx + 1) |
|
212 |
in map_index (fn (idx, t) => (mk_name idx, HOLogic.mk_Trueprop t)) axs end |
|
213 |
||
34011
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
214 |
datatype kind = Unused of thm | Used of thm | New of string |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
215 |
|
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
216 |
fun mark (name, t) axs = |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
217 |
(case Termtab.lookup axs t of |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
218 |
SOME (Unused thm) => Termtab.update (t, Used thm) axs |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
219 |
| NONE => Termtab.update (t, New name) axs |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
220 |
| SOME _ => axs) |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
221 |
|
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
222 |
val sort_fst_str = sort (prod_ord fast_string_ord (K EQUAL)) |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
223 |
fun split_list_kind thy axs = |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
224 |
let |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
225 |
fun split (_, Used thm) (used, new) = (thm :: used, new) |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
226 |
| split (t, New name) (used, new) = (used, (name, t) :: new) |
34068
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
227 |
| split (_, Unused thm) (used, new) = |
34011
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
228 |
(warning (Pretty.str_of |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
229 |
(Pretty.big_list "This background axiom has not been loaded:" |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
230 |
[Display.pretty_thm_global thy thm])); |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
231 |
(used, new)) |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
232 |
in apsnd sort_fst_str (fold split axs ([], [])) end |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
233 |
|
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
234 |
fun mark_axioms thy axs = |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
235 |
Boogie_Axioms.get (ProofContext.init thy) |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
236 |
|> Termtab.make o map (fn thm => (Thm.prop_of thm, Unused thm)) |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
237 |
|> fold mark axs |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
238 |
|> split_list_kind thy o Termtab.dest |
33419 | 239 |
in |
240 |
fun add_axioms verbose axs thy = |
|
34011
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
241 |
let val (used, new) = mark_axioms thy (name_axioms axs) |
33419 | 242 |
in |
243 |
thy |
|
35856
f81557a124d5
replaced PureThy.add_axioms by more basic Drule.add_axiom, which is old-style nonetheless;
wenzelm
parents:
35837
diff
changeset
|
244 |
|> fold_map (Drule.add_axiom o apfst Binding.name) new |
33419 | 245 |
|-> Context.theory_map o fold Boogie_Axioms.add_thm |
34011
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
246 |
|> log verbose "The following axioms were added:" (map fst new) |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
247 |
|> (fn thy' => log verbose "The following axioms already existed:" |
2b3f4fcbc066
verbose output of loaded data makes a clear distinction between new and already existing data (types, constants, axioms)
boehmes
parents:
33893
diff
changeset
|
248 |
(map (Display.string_of_thm_global thy') used) thy') |
33419 | 249 |
end |
250 |
end |
|
251 |
||
252 |
||
253 |
||
33445
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
254 |
local |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
255 |
fun burrow_distinct eq f xs = |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
256 |
let |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
257 |
val ys = distinct eq xs |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
258 |
val tab = ys ~~ f ys |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
259 |
in map (the o AList.lookup eq tab) xs end |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
260 |
|
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
261 |
fun indexed names = |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
262 |
let |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
263 |
val dup = member (op =) (duplicates (op =) (map fst names)) |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
264 |
fun make_name (n, i) = n ^ (if dup n then "_" ^ string_of_int i else "") |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
265 |
in map make_name names end |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
266 |
|
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
267 |
fun rename idx_names = |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
268 |
idx_names |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
269 |
|> burrow_fst (burrow_distinct (op =) |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
270 |
(map short_name #> ` (duplicates (op =)) #-> Name.variant_list)) |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
271 |
|> indexed |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
272 |
in |
33419 | 273 |
fun add_vcs verbose vcs thy = |
34068
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
274 |
let val vcs' = burrow_fst rename vcs |
33419 | 275 |
in |
276 |
thy |
|
277 |
|> Boogie_VCs.set vcs' |
|
278 |
|> log verbose "The following verification conditions were loaded:" |
|
279 |
(map fst vcs') |
|
280 |
end |
|
33445
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
281 |
end |
33419 | 282 |
|
283 |
||
284 |
||
285 |
local |
|
286 |
fun mk_bitT i T = |
|
287 |
if i = 0 |
|
288 |
then Type (@{type_name "Numeral_Type.bit0"}, [T]) |
|
289 |
else Type (@{type_name "Numeral_Type.bit1"}, [T]) |
|
290 |
||
291 |
fun mk_binT size = |
|
292 |
if size = 0 then @{typ "Numeral_Type.num0"} |
|
293 |
else if size = 1 then @{typ "Numeral_Type.num1"} |
|
294 |
else let val (q, r) = Integer.div_mod size 2 in mk_bitT r (mk_binT q) end |
|
295 |
in |
|
296 |
fun mk_wordT size = |
|
297 |
if size >= 0 then Type (@{type_name "word"}, [mk_binT size]) |
|
298 |
else raise TYPE ("mk_wordT: " ^ quote (string_of_int size), [], []) |
|
299 |
end |
|
300 |
||
301 |
local |
|
302 |
fun dest_binT T = |
|
303 |
(case T of |
|
304 |
Type (@{type_name "Numeral_Type.num0"}, _) => 0 |
|
305 |
| Type (@{type_name "Numeral_Type.num1"}, _) => 1 |
|
306 |
| Type (@{type_name "Numeral_Type.bit0"}, [T]) => 2 * dest_binT T |
|
307 |
| Type (@{type_name "Numeral_Type.bit1"}, [T]) => 1 + 2 * dest_binT T |
|
308 |
| _ => raise TYPE ("dest_binT", [T], [])) |
|
309 |
in |
|
310 |
val dest_wordT = (fn |
|
311 |
Type (@{type_name "word"}, [T]) => dest_binT T |
|
312 |
| T => raise TYPE ("dest_wordT", [T], [])) |
|
313 |
end |
|
314 |
||
315 |
fun mk_arrayT (Ts, T) = Type (@{type_name "fun"}, [HOLogic.mk_tupleT Ts, T]) |
|
316 |
||
317 |
||
318 |
||
319 |
datatype token = Token of string | Newline | EOF |
|
320 |
||
321 |
fun tokenize path = |
|
322 |
let |
|
323 |
fun blank c = (c = #" " orelse c = #"\t" orelse c = #"\n" orelse c = #"\r") |
|
324 |
fun split line (i, tss) = (i + 1, |
|
325 |
map (pair i) (map Token (String.tokens blank line) @ [Newline]) :: tss) |
|
326 |
in apsnd (flat o rev) (File.fold_lines split path (1, [])) end |
|
327 |
||
328 |
fun stopper i = Scan.stopper (K (i, EOF)) (fn (_, EOF) => true | _ => false) |
|
329 |
||
330 |
fun scan_err msg [] = "Boogie (at end of input): " ^ msg |
|
331 |
| scan_err msg ((i, _) :: _) = "Boogie (at line " ^ string_of_int i ^ "): " ^ |
|
332 |
msg |
|
333 |
||
334 |
fun scan_fail msg = Scan.fail_with (scan_err msg) |
|
335 |
||
336 |
fun finite scan path = |
|
337 |
let val (i, ts) = tokenize path |
|
338 |
in |
|
339 |
(case Scan.error (Scan.finite (stopper i) scan) ts of |
|
340 |
(x, []) => x |
|
341 |
| (_, ts) => error (scan_err "unparsed input" ts)) |
|
342 |
end |
|
343 |
||
344 |
fun read_int' s = (case read_int (explode s) of (i, []) => SOME i | _ => NONE) |
|
345 |
||
346 |
fun $$$ s = Scan.one (fn (_, Token s') => s = s' | _ => false) |
|
33497 | 347 |
fun str st = Scan.some (fn (_, Token s) => SOME s | _ => NONE) st |
348 |
fun num st = Scan.some (fn (_, Token s) => read_int' s | _ => NONE) st |
|
33419 | 349 |
|
350 |
fun scan_line key scan = |
|
351 |
$$$ key |-- scan --| Scan.one (fn (_, Newline) => true | _ => false) |
|
352 |
fun scan_line' key = scan_line key (Scan.succeed ()) |
|
353 |
||
354 |
fun scan_count scan i = |
|
355 |
if i > 0 then scan ::: scan_count scan (i - 1) else Scan.succeed [] |
|
356 |
||
357 |
fun scan_lookup kind tab key = |
|
358 |
(case Symtab.lookup tab key of |
|
359 |
SOME value => Scan.succeed value |
|
360 |
| NONE => scan_fail ("undefined " ^ kind ^ ": " ^ quote key)) |
|
361 |
||
362 |
fun typ tds = |
|
363 |
let |
|
364 |
fun tp st = |
|
365 |
(scan_line' "bool" >> K @{typ bool} || |
|
366 |
scan_line' "int" >> K @{typ int} || |
|
367 |
scan_line "bv" num >> mk_wordT || |
|
368 |
scan_line "type-con" (str -- num) :|-- (fn (name, arity) => |
|
369 |
scan_lookup "type constructor" tds name -- scan_count tp arity >> |
|
370 |
Type) || |
|
371 |
scan_line "array" num :|-- (fn arity => |
|
372 |
scan_count tp (arity - 1) -- tp >> mk_arrayT) || |
|
373 |
scan_fail "illegal type") st |
|
374 |
in tp end |
|
375 |
||
376 |
local |
|
377 |
fun mk_nary _ t [] = t |
|
33661 | 378 |
| mk_nary f _ ts = uncurry (fold_rev f) (split_last ts) |
33419 | 379 |
|
380 |
fun mk_distinct T ts = |
|
381 |
Const (@{const_name distinct}, HOLogic.listT T --> @{typ bool}) $ |
|
382 |
HOLogic.mk_list T ts |
|
383 |
||
384 |
fun quant name f = scan_line name (num -- num -- num) >> pair f |
|
385 |
val quants = |
|
386 |
quant "forall" HOLogic.all_const || |
|
387 |
quant "exists" HOLogic.exists_const || |
|
388 |
scan_fail "illegal quantifier kind" |
|
33445
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
389 |
fun mk_quant q (n, T) t = q T $ Term.absfree (n, T, t) |
33419 | 390 |
|
391 |
val patternT = @{typ pattern} |
|
392 |
fun mk_pattern _ [] = raise TERM ("mk_pattern", []) |
|
393 |
| mk_pattern n [t] = Const (n, Term.fastype_of t --> patternT) $ t |
|
394 |
| mk_pattern n (t :: ts) = |
|
395 |
let val T = patternT --> Term.fastype_of t --> patternT |
|
396 |
in Const (@{const_name andpat}, T) $ mk_pattern n ts $ t end |
|
397 |
fun patt n c scan = |
|
398 |
scan_line n num :|-- scan_count scan >> (mk_pattern c) |
|
399 |
fun pattern scan = |
|
400 |
patt "pat" @{const_name pat} scan || |
|
401 |
patt "nopat" @{const_name nopat} scan || |
|
402 |
scan_fail "illegal pattern kind" |
|
403 |
fun mk_trigger [] t = t |
|
404 |
| mk_trigger ps t = @{term trigger} $ HOLogic.mk_list patternT ps $ t |
|
405 |
||
34068
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
406 |
fun make_label (line, col) = Free (label_name line col, @{typ bool}) |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
407 |
fun labelled_by kind pos t = kind $ make_label pos $ t |
35125
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
408 |
fun label offset = |
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
409 |
$$$ "pos" |-- num -- num >> (fn (line, col) => |
34068
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
410 |
if label_name line col = no_label_name then I |
35125
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
411 |
else labelled_by @{term block_at} (line - offset, col)) || |
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
412 |
$$$ "neg" |-- num -- num >> (fn (line, col) => |
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
413 |
labelled_by @{term assert_at} (line - offset, col)) || |
33419 | 414 |
scan_fail "illegal label kind" |
415 |
||
416 |
fun mk_store ((m, k), v) = |
|
417 |
let |
|
418 |
val mT = Term.fastype_of m and kT = Term.fastype_of k |
|
419 |
val vT = Term.fastype_of v |
|
34068
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
420 |
in Const (@{const_name fun_upd}, mT --> kT --> vT --> mT) $ m $ k $ v end |
33419 | 421 |
|
422 |
fun mk_extract ((msb, lsb), t) = |
|
423 |
let |
|
424 |
val dT = Term.fastype_of t and rT = mk_wordT (msb - lsb) |
|
425 |
val nT = @{typ nat} |
|
426 |
val mk_nat_num = HOLogic.mk_number @{typ nat} |
|
34068
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
427 |
in Const (@{const_name slice}, [nT, dT] ---> rT) $ mk_nat_num lsb $ t end |
33419 | 428 |
|
429 |
fun mk_concat (t1, t2) = |
|
430 |
let |
|
431 |
val T1 = Term.fastype_of t1 and T2 = Term.fastype_of t2 |
|
432 |
val U = mk_wordT (dest_wordT T1 + dest_wordT T2) |
|
34068
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
433 |
in Const (@{const_name word_cat}, [T1, T2] ---> U) $ t1 $ t2 end |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
434 |
|
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
435 |
fun unique_labels t = |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
436 |
let |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
437 |
fun names_of (@{term assert_at} $ Free (n, _) $ t) = cons n #> names_of t |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
438 |
| names_of (t $ u) = names_of t #> names_of u |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
439 |
| names_of (Abs (_, _, t)) = names_of t |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
440 |
| names_of _ = I |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
441 |
val nctxt = Name.make_context (duplicates (op =) (names_of t [])) |
33445
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
442 |
|
34068
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
443 |
fun fresh (i, nctxt) = (position_prefix ^ string_of_int i, (i+1, nctxt)) |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
444 |
fun renamed n (i, nctxt) = |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
445 |
yield_singleton Name.variants n nctxt ||> pair i |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
446 |
fun mk_label (name, t) = @{term assert_at} $ Free (name, @{typ bool}) $ t |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
447 |
|
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
448 |
fun unique t = |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
449 |
(case t of |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
450 |
@{term assert_at} $ Free (n, _) $ u => |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
451 |
if n = no_label_name |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
452 |
then fresh ##>> unique u #>> mk_label |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
453 |
else renamed n ##>> unique u #>> mk_label |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
454 |
| u1 $ u2 => unique u1 ##>> unique u2 #>> (op $) |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
455 |
| Abs (n, T, u) => unique u #>> (fn u' => Abs (n, T, u')) |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
456 |
| _ => pair t) |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
457 |
in fst (unique t (1, nctxt)) end |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
458 |
|
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
459 |
val var_name = str >> prefix var_prefix |
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
460 |
val dest_var_name = unprefix var_prefix |
33445
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
461 |
fun rename_variables t = |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
462 |
let |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
463 |
fun short_var_name n = short_name (dest_var_name n) |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
464 |
|
34068
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
465 |
val all_names = Term.add_free_names t [] |
33445
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
466 |
val (names, nctxt) = |
34068
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
467 |
all_names |
33445
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
468 |
|> map_filter (try (fn n => (n, short_var_name n))) |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
469 |
|> split_list |
34068
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
470 |
||>> (fn names => Name.variants names (Name.make_context all_names)) |
33445
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
471 |
|>> Symtab.make o (op ~~) |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
472 |
|
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
473 |
fun rename_free n = the_default n (Symtab.lookup names n) |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
474 |
fun rename_abs n = yield_singleton Name.variants (short_var_name n) |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
475 |
|
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
476 |
fun rename _ (Free (n, T)) = Free (rename_free n, T) |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
477 |
| rename nctxt (Abs (n, T, t)) = |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
478 |
let val (n', nctxt') = rename_abs n nctxt |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
479 |
in Abs (n', T, rename nctxt' t) end |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
480 |
| rename nctxt (t $ u) = rename nctxt t $ rename nctxt u |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
481 |
| rename _ t = t |
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
482 |
in rename nctxt t end |
33419 | 483 |
in |
35125
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
484 |
fun expr offset tds fds = |
33419 | 485 |
let |
486 |
fun binop t (u1, u2) = t $ u1 $ u2 |
|
487 |
fun binexp s f = scan_line' s |-- exp -- exp >> f |
|
488 |
||
489 |
and exp st = |
|
490 |
(scan_line' "true" >> K @{term True} || |
|
491 |
scan_line' "false" >> K @{term False} || |
|
492 |
scan_line' "not" |-- exp >> HOLogic.mk_not || |
|
493 |
scan_line "and" num :|-- scan_count exp >> |
|
494 |
mk_nary (curry HOLogic.mk_conj) @{term True} || |
|
495 |
scan_line "or" num :|-- scan_count exp >> |
|
496 |
mk_nary (curry HOLogic.mk_disj) @{term False} || |
|
497 |
binexp "implies" (binop @{term "op -->"}) || |
|
498 |
scan_line "distinct" num :|-- scan_count exp >> |
|
499 |
(fn [] => @{term True} |
|
500 |
| ts as (t :: _) => mk_distinct (Term.fastype_of t) ts) || |
|
501 |
binexp "=" HOLogic.mk_eq || |
|
33445
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
502 |
scan_line "var" var_name -- typ tds >> Free || |
33419 | 503 |
scan_line "fun" (str -- num) :|-- (fn (name, arity) => |
504 |
scan_lookup "constant" fds name -- scan_count exp arity >> |
|
505 |
Term.list_comb) || |
|
506 |
quants :|-- (fn (q, ((n, k), i)) => |
|
33445
f0c78a28e18e
shorter names for variables and verification conditions,
boehmes
parents:
33424
diff
changeset
|
507 |
scan_count (scan_line "var" var_name -- typ tds) n -- |
33419 | 508 |
scan_count (pattern exp) k -- |
35125
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
509 |
scan_count (attribute offset tds fds) i -- |
33419 | 510 |
exp >> (fn (((vs, ps), _), t) => |
511 |
fold_rev (mk_quant q) vs (mk_trigger ps t))) || |
|
35125
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
512 |
scan_line "label" (label offset) -- exp >> (fn (mk, t) => mk t) || |
33419 | 513 |
scan_line "int-num" num >> HOLogic.mk_number @{typ int} || |
514 |
binexp "<" (binop @{term "op < :: int => _"}) || |
|
515 |
binexp "<=" (binop @{term "op <= :: int => _"}) || |
|
516 |
binexp ">" (binop @{term "op < :: int => _"} o swap) || |
|
517 |
binexp ">=" (binop @{term "op <= :: int => _"} o swap) || |
|
518 |
binexp "+" (binop @{term "op + :: int => _"}) || |
|
33661 | 519 |
binexp "-" (binop @{term "op - :: int => _"}) || |
520 |
binexp "*" (binop @{term "op * :: int => _"}) || |
|
33419 | 521 |
binexp "/" (binop @{term boogie_div}) || |
522 |
binexp "%" (binop @{term boogie_mod}) || |
|
523 |
scan_line "select" num :|-- (fn arity => |
|
34068
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
524 |
exp -- (scan_count exp (arity - 1) >> HOLogic.mk_tuple) >> (op $)) || |
33419 | 525 |
scan_line "store" num :|-- (fn arity => |
526 |
exp -- (scan_count exp (arity - 2) >> HOLogic.mk_tuple) -- exp >> |
|
527 |
mk_store) || |
|
528 |
scan_line "bv-num" (num -- num) >> (fn (size, i) => |
|
529 |
HOLogic.mk_number (mk_wordT size) i) || |
|
530 |
scan_line "bv-extract" (num -- num) -- exp >> mk_extract || |
|
531 |
binexp "bv-concat" mk_concat || |
|
532 |
scan_fail "illegal expression") st |
|
34068
a78307d72e58
make assertion labels unique already when loading a verification condition,
boehmes
parents:
34011
diff
changeset
|
533 |
in exp >> (rename_variables o unique_labels) end |
33419 | 534 |
|
35125
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
535 |
and attribute offset tds fds = |
33419 | 536 |
let |
537 |
val attr_val = |
|
35125
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
538 |
scan_line' "expr-attr" |-- expr offset tds fds >> TermValue || |
33419 | 539 |
scan_line "string-attr" (Scan.repeat1 str) >> |
540 |
(StringValue o space_implode " ") || |
|
541 |
scan_fail "illegal attribute value" |
|
542 |
in |
|
543 |
scan_line "attribute" (str -- num) :|-- (fn (name, i) => |
|
544 |
scan_count attr_val i >> pair name) || |
|
545 |
scan_fail "illegal attribute" |
|
546 |
end |
|
547 |
end |
|
548 |
||
549 |
fun type_decls verbose = Scan.depend (fn thy => |
|
550 |
Scan.repeat (scan_line "type-decl" (str -- num -- num) :|-- (fn (ty, i) => |
|
35125
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
551 |
scan_count (attribute 0 Symtab.empty Symtab.empty) i >> K ty)) >> |
33419 | 552 |
(fn tys => declare_types verbose tys thy)) |
553 |
||
554 |
fun fun_decls verbose tds = Scan.depend (fn thy => |
|
555 |
Scan.repeat (scan_line "fun-decl" (str -- num -- num) :|-- |
|
556 |
(fn ((name, arity), i) => |
|
557 |
scan_count (typ tds) (arity - 1) -- typ tds -- |
|
35125
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
558 |
scan_count (attribute 0 tds Symtab.empty) i >> pair name)) >> |
33419 | 559 |
(fn fns => declare_functions verbose fns thy)) |
560 |
||
33893
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
561 |
fun axioms verbose tds fds unique_axs = Scan.depend (fn thy => |
33419 | 562 |
Scan.repeat (scan_line "axiom" num :|-- (fn i => |
35125
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
563 |
expr 0 tds fds --| scan_count (attribute 0 tds fds) i)) >> |
33893
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
564 |
(fn axs => (add_axioms verbose (unique_axs @ axs) thy, ()))) |
33419 | 565 |
|
566 |
fun var_decls tds fds = Scan.depend (fn thy => |
|
567 |
Scan.repeat (scan_line "var-decl" (str -- num) :|-- (fn (_, i) => |
|
35125
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
568 |
typ tds -- scan_count (attribute 0 tds fds) i >> K ())) >> K (thy, ())) |
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
569 |
|
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
570 |
fun local_vc_offset offsets vc_name = |
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
571 |
Integer.add ~1 (the_default 1 (AList.lookup (op =) offsets vc_name)) |
33419 | 572 |
|
35125
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
573 |
fun vcs verbose offsets tds fds = Scan.depend (fn thy => |
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
574 |
Scan.repeat (scan_line "vc" (str -- num) :-- (fn (name, _) => |
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
575 |
(expr (local_vc_offset offsets name) tds fds))) >> |
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
576 |
(fn vcs => ((), add_vcs verbose vcs thy))) |
33419 | 577 |
|
35125
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
578 |
fun parse verbose offsets thy = Scan.pass thy |
33419 | 579 |
(type_decls verbose :|-- (fn tds => |
33893
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
580 |
fun_decls verbose tds :|-- (fn (unique_axs, fds) => |
24b648ea4834
respect "unique" attribute: generate distinctness axioms
boehmes
parents:
33661
diff
changeset
|
581 |
axioms verbose tds fds unique_axs |-- |
33419 | 582 |
var_decls tds fds |-- |
35125
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
583 |
vcs verbose offsets tds fds))) |
33419 | 584 |
|
35125
acace7e30357
optionally localize assertion labels (based on user-defined offsets) to reduce the effort of label adaptions after changes to the source program
boehmes
parents:
34959
diff
changeset
|
585 |
fun load_b2i verbose offsets path thy = finite (parse verbose offsets thy) path |
33419 | 586 |
|
587 |
end |