changeset 34124 | c4628a1dcf75 |
parent 34121 | 5e831d805118 |
child 34126 | 8a2c5d7aff51 |
34123:c4988215a691 | 34124:c4628a1dcf75 |
---|---|
17 |
17 |
18 structure NameTable : TABLE |
18 structure NameTable : TABLE |
19 |
19 |
20 val univ_card : |
20 val univ_card : |
21 int -> int -> int -> Kodkod.bound list -> Kodkod.formula -> int |
21 int -> int -> int -> Kodkod.bound list -> Kodkod.formula -> int |
22 val check_bits : int -> Kodkod.formula -> unit |
|
22 val check_arity : int -> int -> unit |
23 val check_arity : int -> int -> unit |
23 val kk_tuple : bool -> int -> int list -> Kodkod.tuple |
24 val kk_tuple : bool -> int -> int list -> Kodkod.tuple |
24 val tuple_set_from_atom_schema : (int * int) list -> Kodkod.tuple_set |
25 val tuple_set_from_atom_schema : (int * int) list -> Kodkod.tuple_set |
25 val sequential_int_bounds : int -> Kodkod.int_bound list |
26 val sequential_int_bounds : int -> Kodkod.int_bound list |
27 val pow_of_two_int_bounds : int -> int -> int -> Kodkod.int_bound list |
|
26 val bounds_for_built_in_rels_in_formula : |
28 val bounds_for_built_in_rels_in_formula : |
27 bool -> int -> int -> int -> int -> Kodkod.formula -> Kodkod.bound list |
29 bool -> int -> int -> int -> int -> Kodkod.formula -> Kodkod.bound list |
28 val bound_for_plain_rel : Proof.context -> bool -> nut -> Kodkod.bound |
30 val bound_for_plain_rel : Proof.context -> bool -> nut -> Kodkod.bound |
29 val bound_for_sel_rel : |
31 val bound_for_sel_rel : |
30 Proof.context -> bool -> dtype_spec list -> nut -> Kodkod.bound |
32 Proof.context -> bool -> dtype_spec list -> nut -> Kodkod.bound |
31 val merge_bounds : Kodkod.bound list -> Kodkod.bound list |
33 val merge_bounds : Kodkod.bound list -> Kodkod.bound list |
32 val declarative_axiom_for_plain_rel : kodkod_constrs -> nut -> Kodkod.formula |
34 val declarative_axiom_for_plain_rel : kodkod_constrs -> nut -> Kodkod.formula |
33 val declarative_axioms_for_datatypes : |
35 val declarative_axioms_for_datatypes : |
34 extended_context -> int Typtab.table -> kodkod_constrs |
36 extended_context -> int -> int Typtab.table -> kodkod_constrs |
35 -> nut NameTable.table -> dtype_spec list -> Kodkod.formula list |
37 -> nut NameTable.table -> dtype_spec list -> Kodkod.formula list |
36 val kodkod_formula_from_nut : |
38 val kodkod_formula_from_nut : |
37 int Typtab.table -> bool -> kodkod_constrs -> nut -> Kodkod.formula |
39 int -> int Typtab.table -> bool -> kodkod_constrs -> nut -> Kodkod.formula |
38 end; |
40 end; |
39 |
41 |
40 structure Nitpick_Kodkod : NITPICK_KODKOD = |
42 structure Nitpick_Kodkod : NITPICK_KODKOD = |
41 struct |
43 struct |
42 |
44 |
78 val tuple_F = {tuple_func = tuple_func, tuple_set_func = tuple_set_func} |
80 val tuple_F = {tuple_func = tuple_func, tuple_set_func = tuple_set_func} |
79 val card = fold (Kodkod.fold_bound expr_F tuple_F) bounds 1 |
81 val card = fold (Kodkod.fold_bound expr_F tuple_F) bounds 1 |
80 |> Kodkod.fold_formula expr_F formula |
82 |> Kodkod.fold_formula expr_F formula |
81 in Int.max (main_j0 + fold Integer.max [2, nat_card, int_card] 0, card) end |
83 in Int.max (main_j0 + fold Integer.max [2, nat_card, int_card] 0, card) end |
82 |
84 |
83 (* Proof.context -> bool -> string -> typ -> rep -> string *) |
85 (* int -> Kodkod.formula -> unit *) |
84 fun bound_comment ctxt debug nick T R = |
86 fun check_bits bits formula = |
85 short_name nick ^ |
87 let |
86 (if debug then " :: " ^ plain_string_from_yxml (Syntax.string_of_typ ctxt T) |
88 (* Kodkod.int_expr -> unit -> unit *) |
87 else "") ^ " : " ^ string_for_rep R |
89 fun int_expr_func (Kodkod.Num k) () = |
90 if is_twos_complement_representable bits k then |
|
91 () |
|
92 else |
|
93 raise TOO_SMALL ("Nitpick_Kodkod.check_bits", |
|
94 "\"bits\" value " ^ string_of_int bits ^ |
|
95 " too small for problem") |
|
96 | int_expr_func _ () = () |
|
97 val expr_F = {formula_func = K I, rel_expr_func = K I, |
|
98 int_expr_func = int_expr_func} |
|
99 in Kodkod.fold_formula expr_F formula () end |
|
88 |
100 |
89 (* int -> int -> unit *) |
101 (* int -> int -> unit *) |
90 fun check_arity univ_card n = |
102 fun check_arity univ_card n = |
91 if n > Kodkod.max_arity univ_card then |
103 if n > Kodkod.max_arity univ_card then |
92 raise LIMIT ("Nitpick_Kodkod.check_arity", |
104 raise TOO_LARGE ("Nitpick_Kodkod.check_arity", |
93 "arity " ^ string_of_int n ^ " too large for universe of \ |
105 "arity " ^ string_of_int n ^ " too large for universe of \ |
94 \cardinality " ^ string_of_int univ_card) |
106 \cardinality " ^ string_of_int univ_card) |
95 else |
107 else |
96 () |
108 () |
97 |
109 |
98 (* bool -> int -> int list -> Kodkod.tuple *) |
110 (* bool -> int -> int list -> Kodkod.tuple *) |
99 fun kk_tuple debug univ_card js = |
111 fun kk_tuple debug univ_card js = |
107 val tuple_set_from_atom_schema = |
119 val tuple_set_from_atom_schema = |
108 foldl1 Kodkod.TupleProduct o map Kodkod.TupleAtomSeq |
120 foldl1 Kodkod.TupleProduct o map Kodkod.TupleAtomSeq |
109 (* rep -> Kodkod.tuple_set *) |
121 (* rep -> Kodkod.tuple_set *) |
110 val upper_bound_for_rep = tuple_set_from_atom_schema o atom_schema_of_rep |
122 val upper_bound_for_rep = tuple_set_from_atom_schema o atom_schema_of_rep |
111 |
123 |
124 (* int -> Kodkod.tuple_set *) |
|
125 val single_atom = Kodkod.TupleSet o single o Kodkod.Tuple o single |
|
112 (* int -> Kodkod.int_bound list *) |
126 (* int -> Kodkod.int_bound list *) |
113 fun sequential_int_bounds n = |
127 fun sequential_int_bounds n = [(NONE, map single_atom (index_seq 0 n))] |
114 [(NONE, map (Kodkod.TupleSet o single o Kodkod.Tuple o single) |
128 (* int -> int -> Kodkod.int_bound list *) |
115 (index_seq 0 n))] |
129 fun pow_of_two_int_bounds bits j0 univ_card = |
130 let |
|
131 (* int -> int -> int -> Kodkod.int_bound list *) |
|
132 fun aux 0 _ _ = [] |
|
133 | aux 1 pow_of_two j = |
|
134 if j < univ_card then [(SOME (~ pow_of_two), [single_atom j])] else [] |
|
135 | aux iter pow_of_two j = |
|
136 (SOME pow_of_two, [single_atom j]) :: |
|
137 aux (iter - 1) (2 * pow_of_two) (j + 1) |
|
138 in aux (bits + 1) 1 j0 end |
|
116 |
139 |
117 (* Kodkod.formula -> Kodkod.n_ary_index list *) |
140 (* Kodkod.formula -> Kodkod.n_ary_index list *) |
118 fun built_in_rels_in_formula formula = |
141 fun built_in_rels_in_formula formula = |
119 let |
142 let |
120 (* Kodkod.rel_expr -> Kodkod.n_ary_index list -> Kodkod.n_ary_index list *) |
143 (* Kodkod.rel_expr -> Kodkod.n_ary_index list -> Kodkod.n_ary_index list *) |
121 fun rel_expr_func (Kodkod.Rel (n, j)) rels = |
144 fun rel_expr_func (r as Kodkod.Rel (x as (n, j))) = |
122 (case AList.lookup (op =) (#rels initial_pool) n of |
145 if x = unsigned_bit_word_sel_rel orelse x = signed_bit_word_sel_rel then |
123 SOME k => (j < k ? insert (op =) (n, j)) rels |
146 I |
124 | NONE => rels) |
147 else |
125 | rel_expr_func _ rels = rels |
148 (case AList.lookup (op =) (#rels initial_pool) n of |
149 SOME k => j < k ? insert (op =) x |
|
150 | NONE => I) |
|
151 | rel_expr_func _ = I |
|
126 val expr_F = {formula_func = K I, rel_expr_func = rel_expr_func, |
152 val expr_F = {formula_func = K I, rel_expr_func = rel_expr_func, |
127 int_expr_func = K I} |
153 int_expr_func = K I} |
128 in Kodkod.fold_formula expr_F formula [] end |
154 in Kodkod.fold_formula expr_F formula [] end |
129 |
155 |
130 val max_table_size = 65536 |
156 val max_table_size = 65536 |
131 |
157 |
132 (* int -> unit *) |
158 (* int -> unit *) |
133 fun check_table_size k = |
159 fun check_table_size k = |
134 if k > max_table_size then |
160 if k > max_table_size then |
135 raise LIMIT ("Nitpick_Kodkod.check_table_size", |
161 raise TOO_LARGE ("Nitpick_Kodkod.check_table_size", |
136 "precomputed table too large (" ^ string_of_int k ^ ")") |
162 "precomputed table too large (" ^ string_of_int k ^ ")") |
137 else |
163 else |
138 () |
164 () |
139 |
165 |
140 (* bool -> int -> int * int -> (int -> int) -> Kodkod.tuple list *) |
166 (* bool -> int -> int * int -> (int -> int) -> Kodkod.tuple list *) |
141 fun tabulate_func1 debug univ_card (k, j0) f = |
167 fun tabulate_func1 debug univ_card (k, j0) f = |
203 |
229 |
204 (* bool -> int -> int -> int -> int -> int * int |
230 (* bool -> int -> int -> int -> int -> int * int |
205 -> string * bool * Kodkod.tuple list *) |
231 -> string * bool * Kodkod.tuple list *) |
206 fun tabulate_built_in_rel debug univ_card nat_card int_card j0 (x as (n, _)) = |
232 fun tabulate_built_in_rel debug univ_card nat_card int_card j0 (x as (n, _)) = |
207 (check_arity univ_card n; |
233 (check_arity univ_card n; |
208 if Kodkod.Rel x = not3_rel then |
234 if x = not3_rel then |
209 ("not3", tabulate_func1 debug univ_card (2, j0) (curry (op -) 1)) |
235 ("not3", tabulate_func1 debug univ_card (2, j0) (curry (op -) 1)) |
210 else if Kodkod.Rel x = suc_rel then |
236 else if x = suc_rel then |
211 ("suc", tabulate_func1 debug univ_card (univ_card - j0 - 1, j0) |
237 ("suc", tabulate_func1 debug univ_card (univ_card - j0 - 1, j0) |
212 (Integer.add 1)) |
238 (Integer.add 1)) |
213 else if Kodkod.Rel x = nat_add_rel then |
239 else if x = nat_add_rel then |
214 ("nat_add", tabulate_nat_op2 debug univ_card (nat_card, j0) (op +)) |
240 ("nat_add", tabulate_nat_op2 debug univ_card (nat_card, j0) (op +)) |
215 else if Kodkod.Rel x = int_add_rel then |
241 else if x = int_add_rel then |
216 ("int_add", tabulate_int_op2 debug univ_card (int_card, j0) (op +)) |
242 ("int_add", tabulate_int_op2 debug univ_card (int_card, j0) (op +)) |
217 else if Kodkod.Rel x = nat_subtract_rel then |
243 else if x = nat_subtract_rel then |
218 ("nat_subtract", |
244 ("nat_subtract", |
219 tabulate_op2 debug univ_card (nat_card, j0) j0 (uncurry nat_minus)) |
245 tabulate_op2 debug univ_card (nat_card, j0) j0 (uncurry nat_minus)) |
220 else if Kodkod.Rel x = int_subtract_rel then |
246 else if x = int_subtract_rel then |
221 ("int_subtract", tabulate_int_op2 debug univ_card (int_card, j0) (op -)) |
247 ("int_subtract", tabulate_int_op2 debug univ_card (int_card, j0) (op -)) |
222 else if Kodkod.Rel x = nat_multiply_rel then |
248 else if x = nat_multiply_rel then |
223 ("nat_multiply", tabulate_nat_op2 debug univ_card (nat_card, j0) (op * )) |
249 ("nat_multiply", tabulate_nat_op2 debug univ_card (nat_card, j0) (op * )) |
224 else if Kodkod.Rel x = int_multiply_rel then |
250 else if x = int_multiply_rel then |
225 ("int_multiply", tabulate_int_op2 debug univ_card (int_card, j0) (op * )) |
251 ("int_multiply", tabulate_int_op2 debug univ_card (int_card, j0) (op * )) |
226 else if Kodkod.Rel x = nat_divide_rel then |
252 else if x = nat_divide_rel then |
227 ("nat_divide", tabulate_nat_op2 debug univ_card (nat_card, j0) isa_div) |
253 ("nat_divide", tabulate_nat_op2 debug univ_card (nat_card, j0) isa_div) |
228 else if Kodkod.Rel x = int_divide_rel then |
254 else if x = int_divide_rel then |
229 ("int_divide", tabulate_int_op2 debug univ_card (int_card, j0) isa_div) |
255 ("int_divide", tabulate_int_op2 debug univ_card (int_card, j0) isa_div) |
230 else if Kodkod.Rel x = nat_modulo_rel then |
256 else if x = nat_less_rel then |
231 ("nat_modulo", tabulate_nat_op2 debug univ_card (nat_card, j0) isa_mod) |
|
232 else if Kodkod.Rel x = int_modulo_rel then |
|
233 ("int_modulo", tabulate_int_op2 debug univ_card (int_card, j0) isa_mod) |
|
234 else if Kodkod.Rel x = nat_less_rel then |
|
235 ("nat_less", tabulate_nat_op2 debug univ_card (nat_card, j0) |
257 ("nat_less", tabulate_nat_op2 debug univ_card (nat_card, j0) |
236 (int_for_bool o op <)) |
258 (int_for_bool o op <)) |
237 else if Kodkod.Rel x = int_less_rel then |
259 else if x = int_less_rel then |
238 ("int_less", tabulate_int_op2 debug univ_card (int_card, j0) |
260 ("int_less", tabulate_int_op2 debug univ_card (int_card, j0) |
239 (int_for_bool o op <)) |
261 (int_for_bool o op <)) |
240 else if Kodkod.Rel x = gcd_rel then |
262 else if x = gcd_rel then |
241 ("gcd", tabulate_nat_op2 debug univ_card (nat_card, j0) isa_gcd) |
263 ("gcd", tabulate_nat_op2 debug univ_card (nat_card, j0) isa_gcd) |
242 else if Kodkod.Rel x = lcm_rel then |
264 else if x = lcm_rel then |
243 ("lcm", tabulate_nat_op2 debug univ_card (nat_card, j0) isa_lcm) |
265 ("lcm", tabulate_nat_op2 debug univ_card (nat_card, j0) isa_lcm) |
244 else if Kodkod.Rel x = norm_frac_rel then |
266 else if x = norm_frac_rel then |
245 ("norm_frac", tabulate_int_op2_2 debug univ_card (int_card, j0) |
267 ("norm_frac", tabulate_int_op2_2 debug univ_card (int_card, j0) |
246 isa_norm_frac) |
268 isa_norm_frac) |
247 else |
269 else |
248 raise ARG ("Nitpick_Kodkod.tabulate_built_in_rel", "unknown relation")) |
270 raise ARG ("Nitpick_Kodkod.tabulate_built_in_rel", "unknown relation")) |
249 |
271 |
258 (* bool -> int -> int -> int -> int -> Kodkod.formula -> Kodkod.bound list *) |
280 (* bool -> int -> int -> int -> int -> Kodkod.formula -> Kodkod.bound list *) |
259 fun bounds_for_built_in_rels_in_formula debug univ_card nat_card int_card j0 = |
281 fun bounds_for_built_in_rels_in_formula debug univ_card nat_card int_card j0 = |
260 map (bound_for_built_in_rel debug univ_card nat_card int_card j0) |
282 map (bound_for_built_in_rel debug univ_card nat_card int_card j0) |
261 o built_in_rels_in_formula |
283 o built_in_rels_in_formula |
262 |
284 |
285 (* Proof.context -> bool -> string -> typ -> rep -> string *) |
|
286 fun bound_comment ctxt debug nick T R = |
|
287 short_name nick ^ |
|
288 (if debug then " :: " ^ plain_string_from_yxml (Syntax.string_of_typ ctxt T) |
|
289 else "") ^ " : " ^ string_for_rep R |
|
290 |
|
263 (* Proof.context -> bool -> nut -> Kodkod.bound *) |
291 (* Proof.context -> bool -> nut -> Kodkod.bound *) |
264 fun bound_for_plain_rel ctxt debug (u as FreeRel (x, T, R, nick)) = |
292 fun bound_for_plain_rel ctxt debug (u as FreeRel (x, T, R, nick)) = |
265 ([(x, bound_comment ctxt debug nick T R)], |
293 ([(x, bound_comment ctxt debug nick T R)], |
266 if nick = @{const_name bisim_iterator_max} then |
294 if nick = @{const_name bisim_iterator_max} then |
267 case R of |
295 case R of |
268 Atom (k, j0) => [Kodkod.TupleSet [Kodkod.Tuple [k - 1 + j0]]] |
296 Atom (k, j0) => [single_atom (k - 1 + j0)] |
269 | _ => raise NUT ("Nitpick_Kodkod.bound_for_plain_rel", [u]) |
297 | _ => raise NUT ("Nitpick_Kodkod.bound_for_plain_rel", [u]) |
270 else |
298 else |
271 [Kodkod.TupleSet [], upper_bound_for_rep R]) |
299 [Kodkod.TupleSet [], upper_bound_for_rep R]) |
272 | bound_for_plain_rel _ _ u = |
300 | bound_for_plain_rel _ _ u = |
273 raise NUT ("Nitpick_Kodkod.bound_for_plain_rel", [u]) |
301 raise NUT ("Nitpick_Kodkod.bound_for_plain_rel", [u]) |
367 in kk_all decls (kk_xone (fold kk_join vars r)) end |
395 in kk_all decls (kk_xone (fold kk_join vars r)) end |
368 end |
396 end |
369 else |
397 else |
370 Kodkod.True |
398 Kodkod.True |
371 end |
399 end |
372 fun kk_n_ary_function kk R (r as Kodkod.Rel _) = |
400 fun kk_n_ary_function kk R (r as Kodkod.Rel x) = |
373 if not (is_opt_rep R) then |
401 if not (is_opt_rep R) then |
374 if r = suc_rel then |
402 if x = suc_rel then |
375 Kodkod.False |
403 Kodkod.False |
376 else if r = nat_add_rel then |
404 else if x = nat_add_rel then |
377 formula_for_bool (card_of_rep (body_rep R) = 1) |
405 formula_for_bool (card_of_rep (body_rep R) = 1) |
378 else if r = nat_multiply_rel then |
406 else if x = nat_multiply_rel then |
379 formula_for_bool (card_of_rep (body_rep R) <= 2) |
407 formula_for_bool (card_of_rep (body_rep R) <= 2) |
380 else |
408 else |
381 d_n_ary_function kk R r |
409 d_n_ary_function kk R r |
382 else if r = nat_subtract_rel then |
410 else if x = nat_subtract_rel then |
383 Kodkod.True |
411 Kodkod.True |
384 else |
412 else |
385 d_n_ary_function kk R r |
413 d_n_ary_function kk R r |
386 | kk_n_ary_function kk R r = d_n_ary_function kk R r |
414 | kk_n_ary_function kk R r = d_n_ary_function kk R r |
387 |
415 |
391 (r :: rs) = |
419 (r :: rs) = |
392 fold (kk_and o kk_no o kk_intersect r) rs (kk_disjoint_sets kk rs) |
420 fold (kk_and o kk_no o kk_intersect r) rs (kk_disjoint_sets kk rs) |
393 |
421 |
394 (* int -> kodkod_constrs -> (Kodkod.rel_expr -> Kodkod.rel_expr) |
422 (* int -> kodkod_constrs -> (Kodkod.rel_expr -> Kodkod.rel_expr) |
395 -> Kodkod.rel_expr -> Kodkod.rel_expr *) |
423 -> Kodkod.rel_expr -> Kodkod.rel_expr *) |
396 fun basic_rel_let j ({kk_rel_let, ...} : kodkod_constrs) f r = |
424 fun basic_rel_rel_let j ({kk_rel_let, ...} : kodkod_constrs) f r = |
397 if inline_rel_expr r then |
425 if inline_rel_expr r then |
398 f r |
426 f r |
399 else |
427 else |
400 let val x = (Kodkod.arity_of_rel_expr r, j) in |
428 let val x = (Kodkod.arity_of_rel_expr r, j) in |
401 kk_rel_let [Kodkod.AssignRelReg (x, r)] (f (Kodkod.RelReg x)) |
429 kk_rel_let [Kodkod.AssignRelReg (x, r)] (f (Kodkod.RelReg x)) |
402 end |
430 end |
403 |
|
404 (* kodkod_constrs -> (Kodkod.rel_expr -> Kodkod.rel_expr) -> Kodkod.rel_expr |
431 (* kodkod_constrs -> (Kodkod.rel_expr -> Kodkod.rel_expr) -> Kodkod.rel_expr |
405 -> Kodkod.rel_expr *) |
432 -> Kodkod.rel_expr *) |
406 val single_rel_let = basic_rel_let 0 |
433 val single_rel_rel_let = basic_rel_rel_let 0 |
407 (* kodkod_constrs -> (Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr) |
434 (* kodkod_constrs -> (Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr) |
408 -> Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr *) |
435 -> Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr *) |
409 fun double_rel_let kk f r1 r2 = |
436 fun double_rel_rel_let kk f r1 r2 = |
410 single_rel_let kk (fn r1 => basic_rel_let 1 kk (f r1) r2) r1 |
437 single_rel_rel_let kk (fn r1 => basic_rel_rel_let 1 kk (f r1) r2) r1 |
411 (* kodkod_constrs |
438 (* kodkod_constrs |
412 -> (Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr) |
439 -> (Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr) |
413 -> Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr |
440 -> Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr |
414 -> Kodkod.rel_expr *) |
441 -> Kodkod.rel_expr *) |
415 fun triple_rel_let kk f r1 r2 r3 = |
442 fun tripl_rel_rel_let kk f r1 r2 r3 = |
416 double_rel_let kk (fn r1 => fn r2 => basic_rel_let 2 kk (f r1 r2) r3) r1 r2 |
443 double_rel_rel_let kk |
444 (fn r1 => fn r2 => basic_rel_rel_let 2 kk (f r1 r2) r3) r1 r2 |
|
417 |
445 |
418 (* kodkod_constrs -> int -> Kodkod.formula -> Kodkod.rel_expr *) |
446 (* kodkod_constrs -> int -> Kodkod.formula -> Kodkod.rel_expr *) |
419 fun atom_from_formula ({kk_rel_if, ...} : kodkod_constrs) j0 f = |
447 fun atom_from_formula ({kk_rel_if, ...} : kodkod_constrs) j0 f = |
420 kk_rel_if f (Kodkod.Atom (j0 + 1)) (Kodkod.Atom j0) |
448 kk_rel_if f (Kodkod.Atom (j0 + 1)) (Kodkod.Atom j0) |
421 (* kodkod_constrs -> rep -> Kodkod.formula -> Kodkod.rel_expr *) |
449 (* kodkod_constrs -> rep -> Kodkod.formula -> Kodkod.rel_expr *) |
467 else |
495 else |
468 let val card = card_of_rep old_R in |
496 let val card = card_of_rep old_R in |
469 if is_lone_rep old_R andalso is_lone_rep new_R |
497 if is_lone_rep old_R andalso is_lone_rep new_R |
470 andalso card = card_of_rep new_R then |
498 andalso card = card_of_rep new_R then |
471 if card >= lone_rep_fallback_max_card then |
499 if card >= lone_rep_fallback_max_card then |
472 raise LIMIT ("Nitpick_Kodkod.lone_rep_fallback", |
500 raise TOO_LARGE ("Nitpick_Kodkod.lone_rep_fallback", |
473 "too high cardinality (" ^ string_of_int card ^ ")") |
501 "too high cardinality (" ^ string_of_int card ^ ")") |
474 else |
502 else |
475 kk_case_switch kk old_R new_R r (all_singletons_for_rep old_R) |
503 kk_case_switch kk old_R new_R r (all_singletons_for_rep old_R) |
476 (all_singletons_for_rep new_R) |
504 (all_singletons_for_rep new_R) |
477 else |
505 else |
478 raise REP ("Nitpick_Kodkod.lone_rep_fallback", [old_R, new_R]) |
506 raise REP ("Nitpick_Kodkod.lone_rep_fallback", [old_R, new_R]) |
670 unopt_old_R r |
698 unopt_old_R r |
671 end |
699 end |
672 (* kodkod_constrs -> rep -> rep -> rep -> Kodkod.rel_expr -> Kodkod.rel_expr *) |
700 (* kodkod_constrs -> rep -> rep -> rep -> Kodkod.rel_expr -> Kodkod.rel_expr *) |
673 and rel_expr_to_func kk R1 R2 = rel_expr_from_rel_expr kk (Func (R1, R2)) |
701 and rel_expr_to_func kk R1 R2 = rel_expr_from_rel_expr kk (Func (R1, R2)) |
674 |
702 |
703 (* kodkod_constrs -> typ -> Kodkod.rel_expr -> Kodkod.rel_expr *) |
|
704 fun bit_set_from_atom ({kk_join, ...} : kodkod_constrs) T r = |
|
705 kk_join r (Kodkod.Rel (if T = @{typ "unsigned_bit word"} then |
|
706 unsigned_bit_word_sel_rel |
|
707 else |
|
708 signed_bit_word_sel_rel)) |
|
709 (* kodkod_constrs -> typ -> Kodkod.rel_expr -> Kodkod.int_expr *) |
|
710 val int_expr_from_atom = Kodkod.SetSum ooo bit_set_from_atom |
|
711 (* kodkod_constrs -> typ -> rep -> Kodkod.int_expr -> Kodkod.rel_expr *) |
|
712 fun atom_from_int_expr (kk as {kk_rel_eq, kk_comprehension, ...} |
|
713 : kodkod_constrs) T R i = |
|
714 kk_comprehension (decls_for_atom_schema ~1 (atom_schema_of_rep R)) |
|
715 (kk_rel_eq (bit_set_from_atom kk T (Kodkod.Var (1, ~1))) |
|
716 (Kodkod.Bits i)) |
|
717 |
|
675 (* kodkod_constrs -> nut -> Kodkod.formula *) |
718 (* kodkod_constrs -> nut -> Kodkod.formula *) |
676 fun declarative_axiom_for_plain_rel kk (FreeRel (x, _, R as Func _, nick)) = |
719 fun declarative_axiom_for_plain_rel kk (FreeRel (x, _, R as Func _, nick)) = |
677 kk_n_ary_function kk (R |> nick = @{const_name List.set} ? unopt_rep) |
720 kk_n_ary_function kk (R |> nick = @{const_name List.set} ? unopt_rep) |
678 (Kodkod.Rel x) |
721 (Kodkod.Rel x) |
679 | declarative_axiom_for_plain_rel ({kk_lone, kk_one, ...} : kodkod_constrs) |
722 | declarative_axiom_for_plain_rel ({kk_lone, kk_one, ...} : kodkod_constrs) |
802 (kk_formula_if (kk_subset (Kodkod.Var (1, 0)) dom_r) |
845 (kk_formula_if (kk_subset (Kodkod.Var (1, 0)) dom_r) |
803 (kk_n_ary_function kk R2 r') |
846 (kk_n_ary_function kk R2 r') |
804 (kk_no r')) |
847 (kk_no r')) |
805 end |
848 end |
806 end |
849 end |
807 (* extended_context -> int -> kodkod_constrs -> nut NameTable.table |
850 (* extended_context -> int -> int -> kodkod_constrs -> nut NameTable.table |
808 -> constr_spec -> Kodkod.formula list *) |
851 -> constr_spec -> Kodkod.formula list *) |
809 fun sel_axioms_for_constr ext_ctxt j0 kk rel_table |
852 fun sel_axioms_for_constr ext_ctxt bits j0 kk rel_table |
810 (constr as {const, delta, epsilon, explicit_max, ...}) = |
853 (constr as {const, delta, epsilon, explicit_max, ...}) = |
811 let |
854 let |
812 val honors_explicit_max = |
855 val honors_explicit_max = |
813 explicit_max < 0 orelse epsilon - delta <= explicit_max |
856 explicit_max < 0 orelse epsilon - delta <= explicit_max |
814 in |
857 in |
816 [formula_for_bool honors_explicit_max] |
859 [formula_for_bool honors_explicit_max] |
817 else |
860 else |
818 let |
861 let |
819 val ran_r = discr_rel_expr rel_table const |
862 val ran_r = discr_rel_expr rel_table const |
820 val max_axiom = |
863 val max_axiom = |
821 if honors_explicit_max then Kodkod.True |
864 if honors_explicit_max then |
822 else Kodkod.LE (Kodkod.Cardinality ran_r, Kodkod.Num explicit_max) |
865 Kodkod.True |
866 else if is_twos_complement_representable bits (epsilon - delta) then |
|
867 Kodkod.LE (Kodkod.Cardinality ran_r, Kodkod.Num explicit_max) |
|
868 else |
|
869 raise TOO_SMALL ("Nitpick_Kodkod.sel_axioms_for_constr", |
|
870 "\"bits\" value " ^ string_of_int bits ^ |
|
871 " too small for \"max\"") |
|
823 in |
872 in |
824 max_axiom :: |
873 max_axiom :: |
825 map (sel_axiom_for_sel ext_ctxt j0 kk rel_table ran_r constr) |
874 map (sel_axiom_for_sel ext_ctxt j0 kk rel_table ran_r constr) |
826 (index_seq 0 (num_sels_for_constr_type (snd const))) |
875 (index_seq 0 (num_sels_for_constr_type (snd const))) |
827 end |
876 end |
828 end |
877 end |
829 (* extended_context -> int -> kodkod_constrs -> nut NameTable.table |
878 (* extended_context -> int -> int -> kodkod_constrs -> nut NameTable.table |
830 -> dtype_spec -> Kodkod.formula list *) |
879 -> dtype_spec -> Kodkod.formula list *) |
831 fun sel_axioms_for_datatype ext_ctxt j0 kk rel_table |
880 fun sel_axioms_for_datatype ext_ctxt bits j0 kk rel_table |
832 ({constrs, ...} : dtype_spec) = |
881 ({constrs, ...} : dtype_spec) = |
833 maps (sel_axioms_for_constr ext_ctxt j0 kk rel_table) constrs |
882 maps (sel_axioms_for_constr ext_ctxt bits j0 kk rel_table) constrs |
834 |
883 |
835 (* extended_context -> kodkod_constrs -> nut NameTable.table -> constr_spec |
884 (* extended_context -> kodkod_constrs -> nut NameTable.table -> constr_spec |
836 -> Kodkod.formula list *) |
885 -> Kodkod.formula list *) |
837 fun uniqueness_axiom_for_constr ext_ctxt |
886 fun uniqueness_axiom_for_constr ext_ctxt |
838 ({kk_all, kk_implies, kk_and, kk_rel_eq, kk_lone, kk_join, ...} |
887 ({kk_all, kk_implies, kk_and, kk_rel_eq, kk_lone, kk_join, ...} |
879 let val rs = map (discr_rel_expr rel_table o #const) constrs in |
928 let val rs = map (discr_rel_expr rel_table o #const) constrs in |
880 [kk_rel_eq (fold1 kk_union rs) (Kodkod.AtomSeq (card, j0)), |
929 [kk_rel_eq (fold1 kk_union rs) (Kodkod.AtomSeq (card, j0)), |
881 kk_disjoint_sets kk rs] |
930 kk_disjoint_sets kk rs] |
882 end |
931 end |
883 |
932 |
884 (* extended_context -> int Typtab.table -> kodkod_constrs -> nut NameTable.table |
933 (* extended_context -> int -> int Typtab.table -> kodkod_constrs |
885 -> dtype_spec -> Kodkod.formula list *) |
934 -> nut NameTable.table -> dtype_spec -> Kodkod.formula list *) |
886 fun other_axioms_for_datatype _ _ _ _ {shallow = true, ...} = [] |
935 fun other_axioms_for_datatype _ _ _ _ _ {shallow = true, ...} = [] |
887 | other_axioms_for_datatype ext_ctxt ofs kk rel_table (dtype as {typ, ...}) = |
936 | other_axioms_for_datatype ext_ctxt bits ofs kk rel_table |
937 (dtype as {typ, ...}) = |
|
888 let val j0 = offset_of_type ofs typ in |
938 let val j0 = offset_of_type ofs typ in |
889 sel_axioms_for_datatype ext_ctxt j0 kk rel_table dtype @ |
939 sel_axioms_for_datatype ext_ctxt bits j0 kk rel_table dtype @ |
890 uniqueness_axioms_for_datatype ext_ctxt kk rel_table dtype @ |
940 uniqueness_axioms_for_datatype ext_ctxt kk rel_table dtype @ |
891 partition_axioms_for_datatype j0 kk rel_table dtype |
941 partition_axioms_for_datatype j0 kk rel_table dtype |
892 end |
942 end |
893 |
943 |
894 (* extended_context -> int Typtab.table -> kodkod_constrs -> nut NameTable.table |
944 (* extended_context -> int -> int Typtab.table -> kodkod_constrs |
895 -> dtype_spec list -> Kodkod.formula list *) |
945 -> nut NameTable.table -> dtype_spec list -> Kodkod.formula list *) |
896 fun declarative_axioms_for_datatypes ext_ctxt ofs kk rel_table dtypes = |
946 fun declarative_axioms_for_datatypes ext_ctxt bits ofs kk rel_table dtypes = |
897 acyclicity_axioms_for_datatypes ext_ctxt kk rel_table dtypes @ |
947 acyclicity_axioms_for_datatypes ext_ctxt kk rel_table dtypes @ |
898 maps (other_axioms_for_datatype ext_ctxt ofs kk rel_table) dtypes |
948 maps (other_axioms_for_datatype ext_ctxt bits ofs kk rel_table) dtypes |
899 |
949 |
900 (* int Typtab.table -> bool -> kodkod_constrs -> nut -> Kodkod.formula *) |
950 (* int -> int Typtab.table -> bool -> kodkod_constrs -> nut -> Kodkod.formula *) |
901 fun kodkod_formula_from_nut ofs liberal |
951 fun kodkod_formula_from_nut bits ofs liberal |
902 (kk as {kk_all, kk_exist, kk_formula_let, kk_formula_if, kk_or, kk_not, |
952 (kk as {kk_all, kk_exist, kk_formula_let, kk_formula_if, kk_or, kk_not, |
903 kk_iff, kk_implies, kk_and, kk_subset, kk_rel_eq, kk_no, kk_one, |
953 kk_iff, kk_implies, kk_and, kk_subset, kk_rel_eq, kk_no, kk_one, |
904 kk_some, kk_rel_let, kk_rel_if, kk_union, kk_difference, |
954 kk_some, kk_rel_let, kk_rel_if, kk_union, kk_difference, |
905 kk_intersect, kk_product, kk_join, kk_closure, kk_comprehension, |
955 kk_intersect, kk_product, kk_join, kk_closure, kk_comprehension, |
906 kk_project, kk_project_seq, kk_not3, kk_nat_less, kk_int_less, |
956 kk_project, kk_project_seq, kk_not3, kk_nat_less, kk_int_less, |
922 |
972 |
923 (* Kodkod.formula -> Kodkod.formula -> Kodkod.formula *) |
973 (* Kodkod.formula -> Kodkod.formula -> Kodkod.formula *) |
924 fun kk_notimplies f1 f2 = kk_and f1 (kk_not f2) |
974 fun kk_notimplies f1 f2 = kk_and f1 (kk_not f2) |
925 (* Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr *) |
975 (* Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr *) |
926 val kk_or3 = |
976 val kk_or3 = |
927 double_rel_let kk |
977 double_rel_rel_let kk |
928 (fn r1 => fn r2 => |
978 (fn r1 => fn r2 => |
929 kk_rel_if (kk_subset true_atom (kk_union r1 r2)) true_atom |
979 kk_rel_if (kk_subset true_atom (kk_union r1 r2)) true_atom |
930 (kk_intersect r1 r2)) |
980 (kk_intersect r1 r2)) |
931 val kk_and3 = |
981 val kk_and3 = |
932 double_rel_let kk |
982 double_rel_rel_let kk |
933 (fn r1 => fn r2 => |
983 (fn r1 => fn r2 => |
934 kk_rel_if (kk_subset false_atom (kk_union r1 r2)) false_atom |
984 kk_rel_if (kk_subset false_atom (kk_union r1 r2)) false_atom |
935 (kk_intersect r1 r2)) |
985 (kk_intersect r1 r2)) |
936 fun kk_notimplies3 r1 r2 = kk_and3 r1 (kk_not3 r2) |
986 fun kk_notimplies3 r1 r2 = kk_and3 r1 (kk_not3 r2) |
937 |
987 |
1151 (rel_expr_from_rel_expr kk min_R R2 r2)) |
1201 (rel_expr_from_rel_expr kk min_R R2 r2)) |
1152 end |
1202 end |
1153 | Cst (Iden, T, Func (Atom (1, j0), Formula Neut)) => Kodkod.Atom j0 |
1203 | Cst (Iden, T, Func (Atom (1, j0), Formula Neut)) => Kodkod.Atom j0 |
1154 | Cst (Iden, T as Type ("fun", [T1, _]), R as Func (R1, _)) => |
1204 | Cst (Iden, T as Type ("fun", [T1, _]), R as Func (R1, _)) => |
1155 to_rep R (Cst (Iden, T, Func (one_rep ofs T1 R1, Formula Neut))) |
1205 to_rep R (Cst (Iden, T, Func (one_rep ofs T1 R1, Formula Neut))) |
1156 | Cst (Num j, @{typ int}, R) => |
1206 | Cst (Num j, T, R) => |
1157 (case atom_for_int (card_of_rep R, offset_of_type ofs int_T) j of |
1207 if is_word_type T then |
1208 atom_from_int_expr kk T R (Kodkod.Num j) |
|
1209 else if T = int_T then |
|
1210 case atom_for_int (card_of_rep R, offset_of_type ofs int_T) j of |
|
1158 ~1 => if is_opt_rep R then Kodkod.None |
1211 ~1 => if is_opt_rep R then Kodkod.None |
1159 else raise NUT ("Nitpick_Kodkod.to_r (Num)", [u]) |
1212 else raise NUT ("Nitpick_Kodkod.to_r (Num)", [u]) |
1160 | j' => Kodkod.Atom j') |
1213 | j' => Kodkod.Atom j' |
1161 | Cst (Num j, T, R) => |
1214 else |
1162 if j < card_of_rep R then Kodkod.Atom (j + offset_of_type ofs T) |
1215 if j < card_of_rep R then Kodkod.Atom (j + offset_of_type ofs T) |
1163 else if is_opt_rep R then Kodkod.None |
1216 else if is_opt_rep R then Kodkod.None |
1164 else raise NUT ("Nitpick_Kodkod.to_r", [u]) |
1217 else raise NUT ("Nitpick_Kodkod.to_r (Num)", [u]) |
1165 | Cst (Unknown, _, R) => empty_rel_for_rep R |
1218 | Cst (Unknown, _, R) => empty_rel_for_rep R |
1166 | Cst (Unrep, _, R) => empty_rel_for_rep R |
1219 | Cst (Unrep, _, R) => empty_rel_for_rep R |
1167 | Cst (Suc, T, Func (Atom x, _)) => |
1220 | Cst (Suc, T, Func (Atom x, _)) => |
1168 if domain_type T <> nat_T then suc_rel |
1221 if domain_type T <> nat_T then |
1169 else kk_intersect suc_rel (kk_product Kodkod.Univ (Kodkod.AtomSeq x)) |
1222 Kodkod.Rel suc_rel |
1170 | Cst (Add, Type ("fun", [@{typ nat}, _]), _) => nat_add_rel |
1223 else |
1171 | Cst (Add, Type ("fun", [@{typ int}, _]), _) => int_add_rel |
1224 kk_intersect (Kodkod.Rel suc_rel) |
1172 | Cst (Subtract, Type ("fun", [@{typ nat}, _]), _) => nat_subtract_rel |
1225 (kk_product Kodkod.Univ (Kodkod.AtomSeq x)) |
1173 | Cst (Subtract, Type ("fun", [@{typ int}, _]), _) => int_subtract_rel |
1226 | Cst (Add, Type ("fun", [@{typ nat}, _]), _) => Kodkod.Rel nat_add_rel |
1174 | Cst (Multiply, Type ("fun", [@{typ nat}, _]), _) => nat_multiply_rel |
1227 | Cst (Add, Type ("fun", [@{typ int}, _]), _) => Kodkod.Rel int_add_rel |
1175 | Cst (Multiply, Type ("fun", [@{typ int}, _]), _) => int_multiply_rel |
1228 | Cst (Add, T as Type ("fun", [@{typ "unsigned_bit word"}, _]), R) => |
1176 | Cst (Divide, Type ("fun", [@{typ nat}, _]), _) => nat_divide_rel |
1229 to_bit_word_binary_op T R NONE (SOME (curry Kodkod.Add)) |
1177 | Cst (Divide, Type ("fun", [@{typ int}, _]), _) => int_divide_rel |
1230 | Cst (Add, T as Type ("fun", [@{typ "signed_bit word"}, _]), R) => |
1178 | Cst (Modulo, Type ("fun", [@{typ nat}, _]), _) => nat_modulo_rel |
1231 to_bit_word_binary_op T R |
1179 | Cst (Modulo, Type ("fun", [@{typ int}, _]), _) => int_modulo_rel |
1232 (SOME (fn i1 => fn i2 => fn i3 => |
1180 | Cst (Gcd, _, _) => gcd_rel |
1233 kk_implies (Kodkod.LE (Kodkod.Num 0, Kodkod.BitXor (i1, i2))) |
1181 | Cst (Lcm, _, _) => lcm_rel |
1234 (Kodkod.LE (Kodkod.Num 0, Kodkod.BitXor (i2, i3))))) |
1235 (SOME (curry Kodkod.Add)) |
|
1236 | Cst (Subtract, Type ("fun", [@{typ nat}, _]), _) => |
|
1237 Kodkod.Rel nat_subtract_rel |
|
1238 | Cst (Subtract, Type ("fun", [@{typ int}, _]), _) => |
|
1239 Kodkod.Rel int_subtract_rel |
|
1240 | Cst (Subtract, T as Type ("fun", [@{typ "unsigned_bit word"}, _]), R) => |
|
1241 to_bit_word_binary_op T R NONE |
|
1242 (SOME (fn i1 => fn i2 => |
|
1243 Kodkod.IntIf (Kodkod.LE (i1, i2), Kodkod.Num 0, |
|
1244 Kodkod.Sub (i1, i2)))) |
|
1245 | Cst (Subtract, T as Type ("fun", [@{typ "signed_bit word"}, _]), R) => |
|
1246 to_bit_word_binary_op T R |
|
1247 (SOME (fn i1 => fn i2 => fn i3 => |
|
1248 kk_implies (Kodkod.LT (Kodkod.BitXor (i1, i2), Kodkod.Num 0)) |
|
1249 (Kodkod.LT (Kodkod.BitXor (i2, i3), Kodkod.Num 0)))) |
|
1250 (SOME (curry Kodkod.Sub)) |
|
1251 | Cst (Multiply, Type ("fun", [@{typ nat}, _]), _) => |
|
1252 Kodkod.Rel nat_multiply_rel |
|
1253 | Cst (Multiply, Type ("fun", [@{typ int}, _]), _) => |
|
1254 Kodkod.Rel int_multiply_rel |
|
1255 | Cst (Multiply, |
|
1256 T as Type ("fun", [Type (@{type_name word}, [bit_T]), _]), R) => |
|
1257 to_bit_word_binary_op T R |
|
1258 (SOME (fn i1 => fn i2 => fn i3 => |
|
1259 kk_or (Kodkod.IntEq (i2, Kodkod.Num 0)) |
|
1260 (Kodkod.IntEq (Kodkod.Div (i3, i2), i1) |
|
1261 |> bit_T = @{typ signed_bit} |
|
1262 ? kk_and (Kodkod.LE (Kodkod.Num 0, |
|
1263 foldl1 Kodkod.BitAnd [i1, i2, i3]))))) |
|
1264 (SOME (curry Kodkod.Mult)) |
|
1265 | Cst (Divide, Type ("fun", [@{typ nat}, _]), _) => |
|
1266 Kodkod.Rel nat_divide_rel |
|
1267 | Cst (Divide, Type ("fun", [@{typ int}, _]), _) => |
|
1268 Kodkod.Rel int_divide_rel |
|
1269 | Cst (Divide, T as Type ("fun", [@{typ "unsigned_bit word"}, _]), R) => |
|
1270 to_bit_word_binary_op T R NONE |
|
1271 (SOME (fn i1 => fn i2 => |
|
1272 Kodkod.IntIf (Kodkod.IntEq (i2, Kodkod.Num 0), |
|
1273 Kodkod.Num 0, Kodkod.Div (i1, i2)))) |
|
1274 | Cst (Divide, T as Type ("fun", [@{typ "signed_bit word"}, _]), R) => |
|
1275 to_bit_word_binary_op T R |
|
1276 (SOME (fn i1 => fn i2 => fn i3 => |
|
1277 Kodkod.LE (Kodkod.Num 0, foldl1 Kodkod.BitAnd [i1, i2, i3]))) |
|
1278 (SOME (fn i1 => fn i2 => |
|
1279 Kodkod.IntIf (kk_and (Kodkod.LT (i1, Kodkod.Num 0)) |
|
1280 (Kodkod.LT (Kodkod.Num 0, i2)), |
|
1281 Kodkod.Sub (Kodkod.Div (Kodkod.Add (i1, Kodkod.Num 1), i2), |
|
1282 Kodkod.Num 1), |
|
1283 Kodkod.IntIf (kk_and (Kodkod.LT (Kodkod.Num 0, i1)) |
|
1284 (Kodkod.LT (i2, Kodkod.Num 0)), |
|
1285 Kodkod.Sub (Kodkod.Div (Kodkod.Sub (i1, Kodkod.Num 1), |
|
1286 i2), Kodkod.Num 1), |
|
1287 Kodkod.IntIf (Kodkod.IntEq (i2, Kodkod.Num 0), |
|
1288 Kodkod.Num 0, Kodkod.Div (i1, i2)))))) |
|
1289 | Cst (Gcd, _, _) => Kodkod.Rel gcd_rel |
|
1290 | Cst (Lcm, _, _) => Kodkod.Rel lcm_rel |
|
1182 | Cst (Fracs, _, Func (Atom (1, _), _)) => Kodkod.None |
1291 | Cst (Fracs, _, Func (Atom (1, _), _)) => Kodkod.None |
1183 | Cst (Fracs, _, Func (Struct _, _)) => |
1292 | Cst (Fracs, _, Func (Struct _, _)) => |
1184 kk_project_seq norm_frac_rel 2 2 |
1293 kk_project_seq (Kodkod.Rel norm_frac_rel) 2 2 |
1185 | Cst (NormFrac, _, _) => norm_frac_rel |
1294 | Cst (NormFrac, _, _) => Kodkod.Rel norm_frac_rel |
1186 | Cst (NatToInt, _, Func (Atom _, Atom _)) => Kodkod.Iden |
1295 | Cst (NatToInt, Type ("fun", [@{typ nat}, _]), Func (Atom _, Atom _)) => |
1187 | Cst (NatToInt, _, |
1296 Kodkod.Iden |
1297 | Cst (NatToInt, Type ("fun", [@{typ nat}, _]), |
|
1188 Func (Atom (nat_k, nat_j0), Opt (Atom (int_k, int_j0)))) => |
1298 Func (Atom (nat_k, nat_j0), Opt (Atom (int_k, int_j0)))) => |
1189 if nat_j0 = int_j0 then |
1299 if nat_j0 = int_j0 then |
1190 kk_intersect Kodkod.Iden |
1300 kk_intersect Kodkod.Iden |
1191 (kk_product (Kodkod.AtomSeq (max_int_for_card int_k + 1, nat_j0)) |
1301 (kk_product (Kodkod.AtomSeq (max_int_for_card int_k + 1, nat_j0)) |
1192 Kodkod.Univ) |
1302 Kodkod.Univ) |
1193 else |
1303 else |
1194 raise BAD ("Nitpick_Kodkod.to_r (NatToInt)", "\"nat_j0 <> int_j0\"") |
1304 raise BAD ("Nitpick_Kodkod.to_r (NatToInt)", "\"nat_j0 <> int_j0\"") |
1195 | Cst (IntToNat, _, Func (Atom (int_k, int_j0), nat_R)) => |
1305 | Cst (NatToInt, T as Type ("fun", [@{typ "unsigned_bit word"}, _]), R) => |
1306 to_bit_word_unary_op T R I |
|
1307 | Cst (IntToNat, Type ("fun", [@{typ int}, _]), |
|
1308 Func (Atom (int_k, int_j0), nat_R)) => |
|
1196 let |
1309 let |
1197 val abs_card = max_int_for_card int_k + 1 |
1310 val abs_card = max_int_for_card int_k + 1 |
1198 val (nat_k, nat_j0) = the_single (atom_schema_of_rep nat_R) |
1311 val (nat_k, nat_j0) = the_single (atom_schema_of_rep nat_R) |
1199 val overlap = Int.min (nat_k, abs_card) |
1312 val overlap = Int.min (nat_k, abs_card) |
1200 in |
1313 in |
1206 (kk_product (Kodkod.AtomSeq (overlap, int_j0)) |
1319 (kk_product (Kodkod.AtomSeq (overlap, int_j0)) |
1207 Kodkod.Univ)) |
1320 Kodkod.Univ)) |
1208 else |
1321 else |
1209 raise BAD ("Nitpick_Kodkod.to_r (IntToNat)", "\"nat_j0 <> int_j0\"") |
1322 raise BAD ("Nitpick_Kodkod.to_r (IntToNat)", "\"nat_j0 <> int_j0\"") |
1210 end |
1323 end |
1324 | Cst (IntToNat, T as Type ("fun", [@{typ "signed_bit word"}, _]), R) => |
|
1325 to_bit_word_unary_op T R |
|
1326 (fn i => Kodkod.IntIf (Kodkod.LE (i, Kodkod.Num 0), |
|
1327 Kodkod.Num 0, i)) |
|
1211 | Op1 (Not, _, R, u1) => kk_not3 (to_rep R u1) |
1328 | Op1 (Not, _, R, u1) => kk_not3 (to_rep R u1) |
1212 | Op1 (Finite, _, Opt (Atom _), _) => Kodkod.None |
1329 | Op1 (Finite, _, Opt (Atom _), _) => Kodkod.None |
1213 | Op1 (Converse, T, R, u1) => |
1330 | Op1 (Converse, T, R, u1) => |
1214 let |
1331 let |
1215 val (b_T, a_T) = HOLogic.dest_prodT (domain_type T) |
1332 val (b_T, a_T) = HOLogic.dest_prodT (domain_type T) |
1239 let |
1356 let |
1240 val T1 = type_of u1 |
1357 val T1 = type_of u1 |
1241 val R' = rep_to_binary_rel_rep ofs T1 (unopt_rep (rep_of u1)) |
1358 val R' = rep_to_binary_rel_rep ofs T1 (unopt_rep (rep_of u1)) |
1242 val R'' = opt_rep ofs T1 R' |
1359 val R'' = opt_rep ofs T1 R' |
1243 in |
1360 in |
1244 single_rel_let kk |
1361 single_rel_rel_let kk |
1245 (fn r => |
1362 (fn r => |
1246 let |
1363 let |
1247 val true_r = kk_closure (kk_join r true_atom) |
1364 val true_r = kk_closure (kk_join r true_atom) |
1248 val full_r = full_rel_for_rep R' |
1365 val full_r = full_rel_for_rep R' |
1249 val false_r = kk_difference full_r |
1366 val false_r = kk_difference full_r |
1264 | Op1 (SingletonSet, _, R, u1) => |
1381 | Op1 (SingletonSet, _, R, u1) => |
1265 (case R of |
1382 (case R of |
1266 Func (R1, Formula Neut) => to_rep R1 u1 |
1383 Func (R1, Formula Neut) => to_rep R1 u1 |
1267 | Func (Unit, Opt R) => to_guard [u1] R true_atom |
1384 | Func (Unit, Opt R) => to_guard [u1] R true_atom |
1268 | Func (R1, R2 as Opt _) => |
1385 | Func (R1, R2 as Opt _) => |
1269 single_rel_let kk |
1386 single_rel_rel_let kk |
1270 (fn r => kk_rel_if (kk_no r) (empty_rel_for_rep R) |
1387 (fn r => kk_rel_if (kk_no r) (empty_rel_for_rep R) |
1271 (rel_expr_to_func kk R1 bool_atom_R |
1388 (rel_expr_to_func kk R1 bool_atom_R |
1272 (Func (R1, Formula Neut)) r)) |
1389 (Func (R1, Formula Neut)) r)) |
1273 (to_opt R1 u1) |
1390 (to_opt R1 u1) |
1274 | _ => raise NUT ("Nitpick_Kodkod.to_r (SingletonSet)", [u])) |
1391 | _ => raise NUT ("Nitpick_Kodkod.to_r (SingletonSet)", [u])) |
1307 else kk_rel_if (to_f u1) true_atom (to_r u2) |
1424 else kk_rel_if (to_f u1) true_atom (to_r u2) |
1308 | Op2 (And, _, _, u1, u2) => |
1425 | Op2 (And, _, _, u1, u2) => |
1309 if is_opt_rep (rep_of u1) then kk_rel_if (to_f u2) (to_r u1) false_atom |
1426 if is_opt_rep (rep_of u1) then kk_rel_if (to_f u2) (to_r u1) false_atom |
1310 else kk_rel_if (to_f u1) (to_r u2) false_atom |
1427 else kk_rel_if (to_f u1) (to_r u2) false_atom |
1311 | Op2 (Less, _, _, u1, u2) => |
1428 | Op2 (Less, _, _, u1, u2) => |
1312 if type_of u1 = nat_T then |
1429 (case type_of u1 of |
1313 if is_Cst Unrep u1 then to_compare_with_unrep u2 false_atom |
1430 @{typ nat} => |
1314 else if is_Cst Unrep u2 then to_compare_with_unrep u1 true_atom |
1431 if is_Cst Unrep u1 then to_compare_with_unrep u2 false_atom |
1315 else kk_nat_less (to_integer u1) (to_integer u2) |
1432 else if is_Cst Unrep u2 then to_compare_with_unrep u1 true_atom |
1316 else |
1433 else kk_nat_less (to_integer u1) (to_integer u2) |
1317 kk_int_less (to_integer u1) (to_integer u2) |
1434 | @{typ int} => kk_int_less (to_integer u1) (to_integer u2) |
1435 | _ => double_rel_rel_let kk |
|
1436 (fn r1 => fn r2 => |
|
1437 kk_rel_if |
|
1438 (fold kk_and (map_filter (fn (u, r) => |
|
1439 if is_opt_rep (rep_of u) then SOME (kk_some r) |
|
1440 else NONE) [(u1, r1), (u2, r2)]) Kodkod.True) |
|
1441 (atom_from_formula kk bool_j0 (Kodkod.LT (pairself |
|
1442 (int_expr_from_atom kk (type_of u1)) (r1, r2)))) |
|
1443 Kodkod.None) |
|
1444 (to_r u1) (to_r u2)) |
|
1318 | Op2 (The, T, R, u1, u2) => |
1445 | Op2 (The, T, R, u1, u2) => |
1319 if is_opt_rep R then |
1446 if is_opt_rep R then |
1320 let val r1 = to_opt (Func (unopt_rep R, bool_atom_R)) u1 in |
1447 let val r1 = to_opt (Func (unopt_rep R, bool_atom_R)) u1 in |
1321 kk_rel_if (kk_one (kk_join r1 true_atom)) (kk_join r1 true_atom) |
1448 kk_rel_if (kk_one (kk_join r1 true_atom)) (kk_join r1 true_atom) |
1322 (kk_rel_if (kk_or (kk_some (kk_join r1 true_atom)) |
1449 (kk_rel_if (kk_or (kk_some (kk_join r1 true_atom)) |
1466 | Op2 (Apply, @{typ nat}, _, |
1593 | Op2 (Apply, @{typ nat}, _, |
1467 Op2 (Apply, _, _, Cst (Subtract, _, _), u1), u2) => |
1594 Op2 (Apply, _, _, Cst (Subtract, _, _), u1), u2) => |
1468 if is_Cst Unrep u2 andalso not (is_opt_rep (rep_of u1)) then |
1595 if is_Cst Unrep u2 andalso not (is_opt_rep (rep_of u1)) then |
1469 Kodkod.Atom (offset_of_type ofs nat_T) |
1596 Kodkod.Atom (offset_of_type ofs nat_T) |
1470 else |
1597 else |
1471 fold kk_join [to_integer u1, to_integer u2] nat_subtract_rel |
1598 fold kk_join (map to_integer [u1, u2]) (Kodkod.Rel nat_subtract_rel) |
1472 | Op2 (Apply, _, R, u1, u2) => |
1599 | Op2 (Apply, _, R, u1, u2) => |
1473 if is_Cst Unrep u2 andalso is_set_type (type_of u1) |
1600 if is_Cst Unrep u2 andalso is_set_type (type_of u1) |
1474 andalso is_FreeName u1 then |
1601 andalso is_FreeName u1 then |
1475 false_atom |
1602 false_atom |
1476 else |
1603 else |
1492 end |
1619 end |
1493 | Op3 (Let, _, R, u1, u2, u3) => |
1620 | Op3 (Let, _, R, u1, u2, u3) => |
1494 kk_rel_let [to_expr_assign u1 u2] (to_rep R u3) |
1621 kk_rel_let [to_expr_assign u1 u2] (to_rep R u3) |
1495 | Op3 (If, _, R, u1, u2, u3) => |
1622 | Op3 (If, _, R, u1, u2, u3) => |
1496 if is_opt_rep (rep_of u1) then |
1623 if is_opt_rep (rep_of u1) then |
1497 triple_rel_let kk |
1624 tripl_rel_rel_let kk |
1498 (fn r1 => fn r2 => fn r3 => |
1625 (fn r1 => fn r2 => fn r3 => |
1499 let val empty_r = empty_rel_for_rep R in |
1626 let val empty_r = empty_rel_for_rep R in |
1500 fold1 kk_union |
1627 fold1 kk_union |
1501 [kk_rel_if (kk_rel_eq r1 true_atom) r2 empty_r, |
1628 [kk_rel_if (kk_rel_eq r1 true_atom) r2 empty_r, |
1502 kk_rel_if (kk_rel_eq r1 false_atom) r3 empty_r, |
1629 kk_rel_if (kk_rel_eq r1 false_atom) r3 empty_r, |
1684 Opt (Vect (k, Atom _)) => kk_vect_set_op connective k r1 r2 |
1811 Opt (Vect (k, Atom _)) => kk_vect_set_op connective k r1 r2 |
1685 | Vect (k, Atom _) => kk_vect_set_op connective k r1 r2 |
1812 | Vect (k, Atom _) => kk_vect_set_op connective k r1 r2 |
1686 | Func (_, Formula Neut) => set_oper r1 r2 |
1813 | Func (_, Formula Neut) => set_oper r1 r2 |
1687 | Func (Unit, _) => connective3 r1 r2 |
1814 | Func (Unit, _) => connective3 r1 r2 |
1688 | Func (R1, _) => |
1815 | Func (R1, _) => |
1689 double_rel_let kk |
1816 double_rel_rel_let kk |
1690 (fn r1 => fn r2 => |
1817 (fn r1 => fn r2 => |
1691 kk_union |
1818 kk_union |
1692 (kk_product |
1819 (kk_product |
1693 (true_set_oper (kk_join r1 true_atom) |
1820 (true_set_oper (kk_join r1 true_atom) |
1694 (kk_join r2 (atom_for_bool bool_j0 |
1821 (kk_join r2 (atom_for_bool bool_j0 |
1699 (kk_join r2 (atom_for_bool bool_j0 |
1826 (kk_join r2 (atom_for_bool bool_j0 |
1700 neg_second))) |
1827 neg_second))) |
1701 false_atom)) |
1828 false_atom)) |
1702 r1 r2 |
1829 r1 r2 |
1703 | _ => raise REP ("Nitpick_Kodkod.to_set_op", [min_R])) |
1830 | _ => raise REP ("Nitpick_Kodkod.to_set_op", [min_R])) |
1831 end |
|
1832 (* typ -> rep -> (Kodkod.int_expr -> Kodkod.int_expr) -> Kodkod.rel_expr *) |
|
1833 and to_bit_word_unary_op T R oper = |
|
1834 let |
|
1835 val Ts = strip_type T ||> single |> op @ |
|
1836 (* int -> Kodkod.int_expr *) |
|
1837 fun int_arg j = int_expr_from_atom kk (nth Ts j) (Kodkod.Var (1, j)) |
|
1838 in |
|
1839 kk_comprehension (decls_for_atom_schema 0 (atom_schema_of_rep R)) |
|
1840 (Kodkod.FormulaLet |
|
1841 (map (fn j => Kodkod.AssignIntReg (j, int_arg j)) (0 upto 1), |
|
1842 Kodkod.IntEq (Kodkod.IntReg 1, oper (Kodkod.IntReg 0)))) |
|
1843 end |
|
1844 (* typ -> rep |
|
1845 -> (Kodkod.int_expr -> Kodkod.int_expr -> Kodkod.int_expr -> bool) option |
|
1846 -> (Kodkod.int_expr -> Kodkod.int_expr -> Kodkod.int_expr) option |
|
1847 -> Kodkod.rel_expr *) |
|
1848 and to_bit_word_binary_op T R opt_guard opt_oper = |
|
1849 let |
|
1850 val Ts = strip_type T ||> single |> op @ |
|
1851 (* int -> Kodkod.int_expr *) |
|
1852 fun int_arg j = int_expr_from_atom kk (nth Ts j) (Kodkod.Var (1, j)) |
|
1853 in |
|
1854 kk_comprehension (decls_for_atom_schema 0 (atom_schema_of_rep R)) |
|
1855 (Kodkod.FormulaLet |
|
1856 (map (fn j => Kodkod.AssignIntReg (j, int_arg j)) (0 upto 2), |
|
1857 fold1 kk_and |
|
1858 ((case opt_guard of |
|
1859 NONE => [] |
|
1860 | SOME guard => |
|
1861 [guard (Kodkod.IntReg 0) (Kodkod.IntReg 1) |
|
1862 (Kodkod.IntReg 2)]) @ |
|
1863 (case opt_oper of |
|
1864 NONE => [] |
|
1865 | SOME oper => |
|
1866 [Kodkod.IntEq (Kodkod.IntReg 2, |
|
1867 oper (Kodkod.IntReg 0) (Kodkod.IntReg 1))])))) |
|
1704 end |
1868 end |
1705 (* rep -> rep -> Kodkod.rel_expr -> nut -> Kodkod.rel_expr *) |
1869 (* rep -> rep -> Kodkod.rel_expr -> nut -> Kodkod.rel_expr *) |
1706 and to_apply res_R func_u arg_u = |
1870 and to_apply res_R func_u arg_u = |
1707 case unopt_rep (rep_of func_u) of |
1871 case unopt_rep (rep_of func_u) of |
1708 Unit => |
1872 Unit => |