1 /*
2 * This file is part of the Yices SMT Solver.
3 * Copyright (C) 2017 SRI International.
4 *
5 * Yices is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * Yices is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Yices. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 /*
20 * OUTPUT FUNCTIONS FOR CONCRETE VALUES
21 */
22
23 #include <inttypes.h>
24 #ifdef HAVE_MCSAT
25 #include <poly/algebraic_number.h>
26 #endif
27
28 #include "io/concrete_value_printer.h"
29 #include "io/type_printer.h"
30
31
32 /*
33 * Printing for each object type
34 */
vtbl_print_unknown(FILE * f)35 static inline void vtbl_print_unknown(FILE *f) {
36 fputs("???", f);
37 }
38
vtbl_print_bool(FILE * f,int32_t b)39 static inline void vtbl_print_bool(FILE *f, int32_t b) {
40 if (b) {
41 fputs("true", f);
42 } else {
43 fputs("false", f);
44 }
45 }
46
vtbl_print_rational(FILE * f,rational_t * v)47 static inline void vtbl_print_rational(FILE *f, rational_t *v) {
48 q_print(f, v);
49 }
50
vtbl_print_algebraic(FILE * f,void * v)51 static inline void vtbl_print_algebraic(FILE *f, void *v) {
52 #ifdef HAVE_MCSAT
53 lp_algebraic_number_print(v, f);
54 #endif
55 }
56
vtbl_print_bitvector(FILE * f,value_bv_t * b)57 static inline void vtbl_print_bitvector(FILE *f, value_bv_t *b) {
58 bvconst_print(f, b->data, b->nbits);
59 }
60
61
62 /*
63 * For uninterpreted constants:
64 * -
65 * We print a default name if there's no name given.
66 */
vtbl_print_unint_name(FILE * f,value_table_t * table,value_t c,value_unint_t * v)67 static void vtbl_print_unint_name(FILE *f, value_table_t *table, value_t c, value_unint_t *v) {
68 const char *s;
69
70 s = v->name;
71 if (s == NULL) {
72 // try to get a name from the external 'unint_namer' function
73 if (table->unint_namer != NULL) {
74 s = table->unint_namer(table->aux_namer, v);
75 }
76 }
77
78 if (s == NULL) {
79 fprintf(f, "const!%"PRId32, c);
80 } else {
81 fputs(s, f);
82 }
83 }
84
85
86 /*
87 * Function: use a default name if nothing is given
88 */
vtbl_print_fun_name(FILE * f,value_t c,value_fun_t * fun)89 static void vtbl_print_fun_name(FILE *f, value_t c, value_fun_t *fun) {
90 if (fun->name == NULL) {
91 fprintf(f, "fun!%"PRId32, c);
92 } else {
93 fputs(fun->name, f);
94 }
95 }
96
97
98
99 /*
100 * For tuples, maps, and updates: recursively print elements
101 */
vtbl_print_tuple(FILE * f,value_table_t * table,value_tuple_t * t)102 static void vtbl_print_tuple(FILE *f, value_table_t *table, value_tuple_t *t) {
103 uint32_t i, n;
104
105 n = t->nelems;
106 fputs("(mk-tuple", f);
107 for (i=0; i<n; i++) {
108 fputc(' ', f);
109 vtbl_print_object(f, table, t->elem[i]);
110 }
111 fputc(')', f);
112 }
113
114
vtbl_print_map(FILE * f,value_table_t * table,value_map_t * m)115 static void vtbl_print_map(FILE *f, value_table_t *table, value_map_t *m) {
116 uint32_t i, n;
117
118 fputc('[', f);
119 n = m->arity;
120 for (i=0; i<n; i++) {
121 vtbl_print_object(f, table, m->arg[i]);
122 fputc(' ', f);
123 }
124 fputs("|-> ", f);
125 vtbl_print_object(f, table, m->val);
126 fputc(']', f);
127 }
128
129
vtbl_print_update(FILE * f,value_table_t * table,value_update_t * u)130 static void vtbl_print_update(FILE *f, value_table_t *table, value_update_t *u) {
131 value_map_t *m;
132 uint32_t i, n;
133
134 n = u->arity;
135 assert(n > 0);
136
137 m = vtbl_map(table, u->map);
138 assert(m->arity == n);
139
140 fputs("(update ", f);
141 vtbl_print_object(f, table, u->fun);
142 fputs(" (", f);
143 vtbl_print_object(f, table, m->arg[0]);
144 for (i=1; i<n; i++) {
145 fputc(' ', f);
146 vtbl_print_object(f, table, m->arg[i]);
147 }
148 fputs(") ", f);
149 vtbl_print_object(f, table, m->val);
150 fputc(')', f);
151 }
152
153
154
155 /*
156 * Print object c on stream f
157 * - if c is a function also add it to the internal queue
158 */
vtbl_print_object(FILE * f,value_table_t * table,value_t c)159 void vtbl_print_object(FILE *f, value_table_t *table, value_t c) {
160 assert(0 <= c && c < table->nobjects);
161 switch (table->kind[c]) {
162 case UNKNOWN_VALUE:
163 vtbl_print_unknown(f);
164 break;
165 case BOOLEAN_VALUE:
166 vtbl_print_bool(f, table->desc[c].integer);
167 break;
168 case RATIONAL_VALUE:
169 vtbl_print_rational(f, &table->desc[c].rational);
170 break;
171 case ALGEBRAIC_VALUE:
172 vtbl_print_algebraic(f, table->desc[c].ptr);
173 break;
174 case BITVECTOR_VALUE:
175 vtbl_print_bitvector(f, table->desc[c].ptr);
176 break;
177 case TUPLE_VALUE:
178 vtbl_print_tuple(f, table, table->desc[c].ptr);
179 break;
180 case UNINTERPRETED_VALUE:
181 vtbl_print_unint_name(f, table, c, table->desc[c].ptr);
182 break;
183 case FUNCTION_VALUE:
184 vtbl_print_fun_name(f, c, table->desc[c].ptr);
185 vtbl_push_object(table, c);
186 break;
187 case MAP_VALUE:
188 vtbl_print_map(f, table, table->desc[c].ptr);
189 break;
190 case UPDATE_VALUE:
191 vtbl_print_update(f, table, table->desc[c].ptr);
192 break;
193 default:
194 assert(false);
195 }
196 }
197
198
199
200 /*
201 * Format to display a function:
202 * (function <name>
203 * (type (-> tau_1 ... tau_n sigma))
204 * (= (<name> x_1 ... x_n) y_1)
205 * ...
206 * (default z))
207 */
vtbl_print_function_header(FILE * f,value_table_t * table,value_t c,type_t tau,const char * name)208 static void vtbl_print_function_header(FILE *f, value_table_t *table, value_t c, type_t tau, const char *name) {
209 if (name == NULL) {
210 fprintf(f, "(function fun!%"PRId32"\n", c);
211 } else {
212 fprintf(f, "(function %s\n", name);
213 }
214 fprintf(f, " (type ");
215 print_type(f, table->type_table, tau);
216 fprintf(f, ")");
217 }
218
219
220 /*
221 * Print the function c
222 * - if show_default is true, also print the default value
223 */
vtbl_print_function(FILE * f,value_table_t * table,value_t c,bool show_default)224 void vtbl_print_function(FILE *f, value_table_t *table, value_t c, bool show_default) {
225 value_fun_t *fun;
226 value_map_t *mp;
227 uint32_t i, n;
228 uint32_t j, m;
229
230 assert(0 <= c && c < table->nobjects && table->kind[c] == FUNCTION_VALUE);
231 fun = table->desc[c].ptr;
232
233 vtbl_print_function_header(f, table, c, fun->type, fun->name);
234
235 m = fun->arity;
236 n = fun->map_size;
237 for (i=0; i<n; i++) {
238 fputs("\n (= (", f);
239 vtbl_print_fun_name(f, c, fun);
240
241 mp = vtbl_map(table, fun->map[i]);
242 assert(mp->arity == m);
243 for (j=0; j<m; j++) {
244 fputc(' ', f);
245 vtbl_print_object(f, table, mp->arg[j]);
246 }
247 fputs(") ", f);
248 vtbl_print_object(f, table, mp->val);
249 fputc(')', f);
250 }
251
252 if (show_default && !is_unknown(table, fun->def)) {
253 fputs("\n (default ", f);
254 vtbl_print_object(f, table, fun->def);
255 fputs(")", f);
256 }
257 fputs(")\n", f);
258 }
259
260
261 /*
262 * Expand update c and print it as a function
263 * - name = function name to use
264 * - if show_default is true, also print the default value
265 */
vtbl_normalize_and_print_update(FILE * f,value_table_t * table,const char * name,value_t c,bool show_default)266 void vtbl_normalize_and_print_update(FILE *f, value_table_t *table, const char *name, value_t c, bool show_default) {
267 char fake_name[20];
268 map_hset_t *hset;
269 value_map_t *mp;
270 value_t def;
271 type_t tau;
272 uint32_t i, j, n, m;
273
274 // build the mapping for c in hset1
275 vtbl_expand_update(table, c, &def, &tau);
276 hset = table->hset1;
277 assert(hset != NULL);
278
279 if (name == NULL) {
280 sprintf(fake_name, "fun!%"PRId32, c);
281 name = fake_name;
282 }
283
284 /*
285 * hset->data contains an array of mapping objects
286 * hset->nelems = number of elements in hset->data
287 */
288 vtbl_print_function_header(f, table, c, tau, name);
289
290 m = vtbl_update(table, c)->arity;
291 n = hset->nelems;
292 for (i=0; i<n; i++) {
293 fprintf(f, "\n (= (%s", name);
294
295 mp = vtbl_map(table, hset->data[i]);
296 assert(mp->arity == m);
297 for (j=0; j<m; j++) {
298 fputc(' ', f);
299 vtbl_print_object(f, table, mp->arg[j]);
300 }
301 fputs(") ", f);
302 vtbl_print_object(f, table, mp->val);
303 fputs(")", f);
304 }
305
306 if (show_default && !is_unknown(table, def)) {
307 fputs("\n (default ", f);
308 vtbl_print_object(f, table, def);
309 fputc(')', f);
310 }
311 fputs(")\n", f);
312 }
313
314
315
316 /*
317 * Print the maps defining all the queue'd functions
318 * (this may recursively queue more objects and print them too).
319 * - if show_default is true, print the default value for each map
320 * - once all queued functions are printed, reset the queue.
321 */
vtbl_print_queued_functions(FILE * f,value_table_t * table,bool show_default)322 void vtbl_print_queued_functions(FILE *f, value_table_t *table, bool show_default) {
323 int_queue_t *q;
324 value_t v;
325
326 q = &table->queue.queue;
327 while (! int_queue_is_empty(q)) {
328 v = int_queue_pop(q);
329 vtbl_print_function(f, table, v, show_default);
330 }
331 vtbl_empty_queue(table);
332 }
333
334
335 /*********************
336 * PRETTY PRINTING *
337 ********************/
338
339 /*
340 * Printing for each object type
341 */
vtbl_pp_bitvector(yices_pp_t * printer,value_bv_t * b)342 static inline void vtbl_pp_bitvector(yices_pp_t *printer, value_bv_t *b) {
343 pp_bv(printer, b->data, b->nbits);
344 }
345
346
347 /*
348 * For uninterpreted constants:
349 * -
350 * We print a default name if there's no name given.
351 */
vtbl_pp_unint_name(yices_pp_t * printer,value_table_t * table,value_t c,value_unint_t * v)352 static void vtbl_pp_unint_name(yices_pp_t *printer, value_table_t *table, value_t c, value_unint_t *v) {
353 const char *s;
354
355 s = v->name;
356 if (s == NULL) {
357 // try to get a name from the external 'unint_namer' function
358 if (table->unint_namer != NULL) {
359 s = table->unint_namer(table->aux_namer, v);
360 }
361 }
362
363 if (s == NULL) {
364 pp_id(printer, "const!", c);
365 } else {
366 pp_string(printer, s);
367 }
368 }
369
370
371 /*
372 * Function: use a default name if nothing is given
373 */
vtbl_pp_fun_name(yices_pp_t * printer,value_t c,value_fun_t * fun)374 static void vtbl_pp_fun_name(yices_pp_t *printer, value_t c, value_fun_t *fun) {
375 if (fun->name == NULL) {
376 pp_id(printer, "fun!", c);
377 } else {
378 pp_string(printer, fun->name);
379 }
380 }
381
382
383
384 /*
385 * For tuples, maps, and updates: recursively print elements
386 */
vtbl_pp_tuple(yices_pp_t * printer,value_table_t * table,value_tuple_t * t)387 static void vtbl_pp_tuple(yices_pp_t *printer, value_table_t *table, value_tuple_t *t) {
388 uint32_t i, n;
389
390 n = t->nelems;
391 pp_open_block(printer, PP_OPEN_TUPLE);
392 for (i=0; i<n; i++) {
393 vtbl_pp_object(printer, table, t->elem[i]);
394 }
395 pp_close_block(printer, true);
396 }
397
398
vtbl_pp_map(yices_pp_t * printer,value_table_t * table,value_map_t * m)399 static void vtbl_pp_map(yices_pp_t *printer, value_table_t *table, value_map_t *m) {
400 uint32_t i, n;
401
402 pp_open_block(printer, PP_OPEN_PAR);
403 n = m->arity;
404 pp_open_block(printer, PP_OPEN_PAR);
405 for (i=0; i<n; i++) {
406 vtbl_pp_object(printer, table, m->arg[i]);
407 }
408 pp_close_block(printer, true);
409 pp_string(printer, "|->");
410 vtbl_pp_object(printer, table, m->val);
411 pp_close_block(printer, true);
412 }
413
414
vtbl_pp_update(yices_pp_t * printer,value_table_t * table,value_update_t * u)415 static void vtbl_pp_update(yices_pp_t *printer, value_table_t *table, value_update_t *u) {
416 value_map_t *m;
417 uint32_t i, n;
418
419 n = u->arity;
420 assert(n > 0);
421
422 m = vtbl_map(table, u->map);
423 assert(m->arity == n);
424
425 pp_open_block(printer, PP_OPEN_UPDATE);
426 vtbl_pp_object(printer, table, u->fun);
427 pp_open_block(printer, PP_OPEN_PAR);
428 for (i=0; i<n; i++) {
429 vtbl_pp_object(printer, table, m->arg[i]);
430 }
431 pp_close_block(printer, true);
432 vtbl_pp_object(printer, table, m->val);
433 pp_close_block(printer, true);
434 }
435
436
437
438 /*
439 * Print object c
440 * - if c is a function, add it to the internal queue
441 */
vtbl_pp_object(yices_pp_t * printer,value_table_t * table,value_t c)442 void vtbl_pp_object(yices_pp_t *printer, value_table_t *table, value_t c) {
443 assert(0 <= c && c < table->nobjects);
444
445 switch (table->kind[c]) {
446 case UNKNOWN_VALUE:
447 pp_string(printer, "???");
448 break;
449 case BOOLEAN_VALUE:
450 pp_bool(printer, table->desc[c].integer);
451 break;
452 case RATIONAL_VALUE:
453 pp_rational(printer, &table->desc[c].rational);
454 break;
455 case ALGEBRAIC_VALUE:
456 pp_algebraic(printer, table->desc[c].ptr);
457 break;
458 case BITVECTOR_VALUE:
459 vtbl_pp_bitvector(printer, table->desc[c].ptr);
460 break;
461 case TUPLE_VALUE:
462 vtbl_pp_tuple(printer, table, table->desc[c].ptr);
463 break;
464 case UNINTERPRETED_VALUE:
465 vtbl_pp_unint_name(printer, table, c, table->desc[c].ptr);
466 break;
467 case FUNCTION_VALUE:
468 vtbl_pp_fun_name(printer, c, table->desc[c].ptr);
469 vtbl_push_object(table, c);
470 break;
471 case MAP_VALUE:
472 vtbl_pp_map(printer, table, table->desc[c].ptr);
473 break;
474 case UPDATE_VALUE:
475 vtbl_pp_update(printer, table, table->desc[c].ptr);
476 break;
477 default:
478 assert(false);
479 }
480 }
481
482
483 /*
484 * Format to display a function:
485 * (function <name>
486 * (type (-> tau_1 ... tau_n sigma))
487 * (= (<name> x_1 ... x_n) y_1)
488 * ...
489 * (default z))
490 */
vtbl_pp_function_header(yices_pp_t * printer,value_table_t * table,value_t c,type_t tau,const char * name)491 static void vtbl_pp_function_header(yices_pp_t *printer, value_table_t *table, value_t c, type_t tau, const char *name) {
492 pp_open_block(printer, PP_OPEN_FUNCTION);
493 if (name == NULL) {
494 pp_id(printer, "fun!", c);
495 } else {
496 pp_string(printer, name);
497 }
498 pp_open_block(printer, PP_OPEN_TYPE);
499 pp_type(printer, table->type_table, tau);
500 pp_close_block(printer, true);
501 }
502
503
504 /*
505 * Print the function c
506 * - if show_default is true, also print the default value
507 */
vtbl_pp_function(yices_pp_t * printer,value_table_t * table,value_t c,bool show_default)508 void vtbl_pp_function(yices_pp_t *printer, value_table_t *table, value_t c, bool show_default) {
509 value_fun_t *fun;
510 value_map_t *mp;
511 uint32_t i, n;
512 uint32_t j, m;
513
514 assert(0 <= c && c < table->nobjects && table->kind[c] == FUNCTION_VALUE);
515 fun = table->desc[c].ptr;
516
517 vtbl_pp_function_header(printer, table, c, fun->type, fun->name);
518
519 m = fun->arity;
520 n = fun->map_size;
521 for (i=0; i<n; i++) {
522 pp_open_block(printer, PP_OPEN_EQ); // (=
523 pp_open_block(printer, PP_OPEN_PAR); // (fun
524 vtbl_pp_fun_name(printer, c, fun);
525
526 mp = vtbl_map(table, fun->map[i]);
527 assert(mp->arity == m);
528 for (j=0; j<m; j++) {
529 vtbl_pp_object(printer, table, mp->arg[j]);
530 }
531 pp_close_block(printer, true); // close of (fun ...
532 vtbl_pp_object(printer, table, mp->val);
533 pp_close_block(printer, true); // close (= ..
534 }
535
536 if (show_default && !is_unknown(table, fun->def)) {
537 pp_open_block(printer, PP_OPEN_DEFAULT); // (default
538 vtbl_pp_object(printer, table, fun->def);
539 pp_close_block(printer, true); // close (default ..
540 }
541 pp_close_block(printer, true); // close (function ...
542 }
543
544
545 /*
546 * Expand update c and print it as a function
547 * - name = function name to use
548 * - if name is NULL, it's replaced by "fun!c"
549 * - if show_default is true, also print the default value
550 */
vtbl_normalize_and_pp_update(yices_pp_t * printer,value_table_t * table,const char * name,value_t c,bool show_default)551 void vtbl_normalize_and_pp_update(yices_pp_t *printer, value_table_t *table, const char *name, value_t c, bool show_default) {
552 char fake_name[20];
553 map_hset_t *hset;
554 value_map_t *mp;
555 value_t def;
556 type_t tau;
557 uint32_t i, j, n, m;
558
559 // build the mapping for c in hset1
560 vtbl_expand_update(table, c, &def, &tau);
561 hset = table->hset1;
562 assert(hset != NULL);
563
564 if (name == NULL) {
565 sprintf(fake_name, "fun!%"PRId32, c);
566 name = fake_name;
567 }
568
569 /*
570 * hset->data contains an array of mapping objects
571 * hset->nelems = number of elements in hset->data
572 */
573 vtbl_pp_function_header(printer, table, c, tau, name);
574
575 m = vtbl_update(table, c)->arity;
576 n = hset->nelems;
577 for (i=0; i<n; i++) {
578 pp_open_block(printer, PP_OPEN_EQ);
579 pp_open_block(printer, PP_OPEN_PAR);
580 pp_string(printer, name);
581
582 mp = vtbl_map(table, hset->data[i]);
583 assert(mp->arity == m);
584 for (j=0; j<m; j++) {
585 vtbl_pp_object(printer, table, mp->arg[j]);
586 }
587 pp_close_block(printer, true); // close (name arg[0] ... arg[m-1])
588 vtbl_pp_object(printer, table, mp->val);
589 pp_close_block(printer, true); // close (=
590 }
591
592 if (show_default && !is_unknown(table, def)) {
593 pp_open_block(printer, PP_OPEN_DEFAULT);
594 vtbl_pp_object(printer, table, def);
595 pp_close_block(printer, true);
596 }
597 pp_close_block(printer, true);
598 }
599
600
601
602 /*
603 * Print the maps defining all the queue'd functions
604 * (this may recursively queue more objects and print them too).
605 * - if show_default is true, print the default value for each map
606 * - once all queued functions are printed, reset the queue.
607 */
vtbl_pp_queued_functions(yices_pp_t * printer,value_table_t * table,bool show_default)608 void vtbl_pp_queued_functions(yices_pp_t *printer, value_table_t *table, bool show_default) {
609 int_queue_t *q;
610 value_t v;
611
612 q = &table->queue.queue;
613 while (! int_queue_is_empty(q)) {
614 v = int_queue_pop(q);
615 vtbl_pp_function(printer, table, v, show_default);
616 }
617 vtbl_empty_queue(table);
618 }
619
620