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