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