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  * PRINTER FOR THE IDL FLOYD-WARSHALL SOLVER
21  */
22 
23 #include <inttypes.h>
24 
25 #include "solvers/cdcl/smt_core_printer.h"
26 #include "solvers/floyd_warshall/idl_fw_printer.h"
27 
28 
29 /*
30  * Print vertex x
31  */
print_idl_vertex(FILE * f,int32_t x)32 void print_idl_vertex(FILE *f, int32_t x) {
33   if (x >= 0) {
34     fprintf(f, "n!%"PRId32, x);
35   } else if (x == null_idl_vertex) {
36     fputs("nil", f);
37   } else {
38     fprintf(f, "<IDL-vertex%"PRId32">", x);
39   }
40 }
41 
42 
43 /*
44  * Value of vertex v in the idl solver
45  *
46  * HACK:
47  * - we use distance[0, v] as the value
48  * - if the distance is not defined we print ???
49  */
print_idl_vertex_value(FILE * f,idl_solver_t * idl,int32_t v)50 void print_idl_vertex_value(FILE *f, idl_solver_t *idl, int32_t v) {
51   idl_matrix_t *m;
52   idl_cell_t *cell;
53   int32_t z;
54 
55   m = &idl->graph.matrix;
56   z = idl->zero_vertex;
57   if (z == null_idl_vertex) {
58     z = 0;
59   }
60 
61   if (m != NULL && z < m->dim && v < m->dim) {
62     cell = m->data + z * m->dim + v;
63     if (cell->id >= 0) {
64       // distance [z, x] is defined
65       fprintf(f, "%"PRId32, cell->dist);
66       return;
67     }
68   }
69 
70   fprintf(f, "???");
71 }
72 
73 
74 /*
75  * Print atom
76  */
print_idl_atom(FILE * f,idl_atom_t * atom)77 void print_idl_atom(FILE *f, idl_atom_t *atom) {
78   fputc('[', f);
79   print_bvar(f, atom->boolvar);
80   fputs(" := (", f);
81   print_idl_vertex(f, atom->source);
82   fputs(" - ", f);
83   print_idl_vertex(f, atom->target);
84   fprintf(f, " <= %"PRId32")]", atom->cost);
85 }
86 
87 
88 /*
89  * Print all atoms in idl solver
90  */
print_idl_atoms(FILE * f,idl_solver_t * idl)91 void print_idl_atoms(FILE *f, idl_solver_t *idl) {
92   uint32_t i, n;
93 
94   n = idl->atoms.natoms;
95   for (i=0; i<n; i++) {
96     print_idl_atom(f, idl->atoms.atoms + i);
97     fputc('\n', f);
98   }
99 }
100 
101 
102 
103 /*
104  * Difference logic triple (x - y + d)
105  * - x and y are vertices
106  */
print_idl_triple(FILE * f,dl_triple_t * triple)107 void print_idl_triple(FILE *f, dl_triple_t *triple) {
108   bool space;
109 
110   space = false;
111   if (triple->target >= 0) {
112     print_idl_vertex(f, triple->target); // x
113     space = true;
114   }
115   if (triple->source >= 0) {
116     if (space) fputc(' ', f);
117     fputs("- ", f);
118     print_idl_vertex(f, triple->source); // y
119     space = true;
120   }
121 
122   if (! space) {
123     q_print(f, &triple->constant);
124   } else if (q_is_pos(&triple->constant)) {
125     fprintf(f, " + ");
126     q_print(f, &triple->constant);
127   } else if (q_is_neg(&triple->constant)) {
128     fprintf(f, " - ");
129     q_print_abs(f, &triple->constant);
130   }
131 }
132 
133 
134 
135 /*
136  * Variable name
137  */
print_idl_var_name(FILE * f,thvar_t u)138 void print_idl_var_name(FILE *f, thvar_t u) {
139   if (u >= 0) {
140     fprintf(f, "i!%"PRId32, u);
141   } else if (u == null_thvar) {
142     fputs("nil-var", f);
143   } else {
144     fprintf(f, "<IDL-var%"PRId32">", u);
145   }
146 }
147 
148 
149 /*
150  * Print u + its descriptor
151  */
print_idl_var_def(FILE * f,idl_solver_t * solver,thvar_t u)152 void print_idl_var_def(FILE *f, idl_solver_t *solver, thvar_t u) {
153   dl_vartable_t *vtbl;
154 
155   vtbl = &solver->vtbl;
156   print_idl_var_name(f, u);
157   if (0 <= u && u < vtbl->nvars) {
158     fputs(" := ", f);
159     print_idl_triple(f, dl_var_triple(vtbl, u));
160   } else {
161     fputs(" ???", f);
162   }
163 }
164 
165 
166 /*
167  * Print the full variable table
168  */
print_idl_var_table(FILE * f,idl_solver_t * solver)169 void print_idl_var_table(FILE *f, idl_solver_t *solver) {
170   uint32_t i, n;
171 
172   n = solver->vtbl.nvars;
173   for (i=0; i<n; i++) {
174     print_idl_var_def(f, solver, i);
175     fputc('\n', f);
176   }
177 }
178 
179 
180 
181 /*
182  * Cell x, y
183  */
idl_cell(idl_matrix_t * m,uint32_t x,uint32_t y)184 static inline idl_cell_t *idl_cell(idl_matrix_t *m, uint32_t x, uint32_t y) {
185   assert(0 <= x && x < m->dim && 0 <= y && y < m->dim);
186   return m->data + x * m->dim + y;
187 }
188 
189 /*
190  * Distance from x to y
191  */
idl_dist(idl_matrix_t * m,uint32_t x,uint32_t y)192 static inline int32_t idl_dist(idl_matrix_t *m, uint32_t x, uint32_t y) {
193   return idl_cell(m, x, y)->dist;
194 }
195 
196 
197 
198 /*
199  * Print edge i
200  */
print_idl_edge(FILE * f,idl_solver_t * solver,uint32_t i)201 static void print_idl_edge(FILE *f, idl_solver_t *solver, uint32_t i) {
202   idl_matrix_t *m;
203   idl_edge_t *e;
204   thvar_t x, y;
205   int32_t d;
206 
207   assert(0 < i && i < solver->graph.edges.top);
208   e = solver->graph.edges.data + i;
209   m = &solver->graph.matrix;
210 
211   x = e->source;
212   y = e->target;
213   d = idl_dist(m, x, y);
214 
215   fprintf(f, "edge[%"PRIu32"]: n!%"PRId32" - n!%"PRId32" <= %"PRId32, i, x, y, d);
216 }
217 
218 
219 /*
220  * Print all edges
221  */
print_idl_edges(FILE * f,idl_solver_t * solver)222 void print_idl_edges(FILE *f, idl_solver_t *solver) {
223   uint32_t i, n;
224 
225   n = solver->graph.edges.top;
226   for (i=1; i<n; i++) {
227     print_idl_edge(f, solver, i);
228     fputc('\n', f);
229   }
230 }
231 
232 
233 
234 /*
235  * All axioms: edges labeled with true_literal
236  */
print_idl_axioms(FILE * f,idl_solver_t * solver)237 void print_idl_axioms(FILE *f, idl_solver_t *solver) {
238   uint32_t i, n;
239 
240   n = solver->graph.edges.top;
241   for (i=1; i<n; i++) {
242     if (solver->graph.edges.lit[i] == true_literal) {
243       print_idl_edge(f, solver, i);
244       fputc('\n', f);
245     }
246   }
247 }
248