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 * Test of composite constructors/signature computation
21 * and congruence table
22 */
23
24 #include <stdio.h>
25 #include <stdint.h>
26 #include <stdbool.h>
27 #include <inttypes.h>
28
29 #include "solvers/egraph/composites.h"
30 #include "solvers/egraph/egraph_printer.h"
31 #include "solvers/egraph/egraph_types.h"
32 #include "utils/arena.h"
33
34
35 /*
36 * Test partition: 11 terms, 4 classes
37 * class[0] = { true, a-, b+ }
38 * class[1] = { c+, d- }
39 * class[2] = { e+, f+, g+ }
40 * class[3] = { h+, i+, j+ }
41 *
42 * with classes 2 and 3 distinct
43 */
44
45 #define NC 4
46 #define NT 11
47
48 // fixed label array
49 static elabel_t label[NT];
50
51
52 static eterm_t a = 1;
53 static eterm_t b = 2;
54 static eterm_t c = 3;
55 static eterm_t d = 4;
56 static eterm_t e = 5;
57 static eterm_t f = 6;
58 static eterm_t g = 7;
59 static eterm_t h = 8;
60 static eterm_t i = 9;
61 static eterm_t j = 10;
62
63
64 #define NCMP 50
65
66 static composite_t *composite[NCMP];
67 static signature_t sgn;
68
69
70 static congruence_table_t tbl;
71
72
73 /*
74 * Initialize the labels
75 */
init_labels(void)76 static void init_labels(void) {
77 label[0] = pos_label(0); // true
78 label[a] = neg_label(0);
79 label[b] = pos_label(0);
80
81 label[c] = pos_label(1);
82 label[d] = neg_label(1);
83
84 label[e] = pos_label(2);
85 label[f] = pos_label(2);
86 label[g] = pos_label(2);
87
88 label[h] = pos_label(3);
89 label[i] = pos_label(3);
90 label[j] = pos_label(3);
91 };
92
93 /*
94 * Test constructors
95 */
apply2(eterm_t f,occ_t x,occ_t y)96 static composite_t *apply2(eterm_t f, occ_t x, occ_t y) {
97 occ_t aux[2];
98
99 aux[0] = x;
100 aux[1] = y;
101 return new_apply_composite(pos_occ(f), 2, aux);
102 }
103
update2(eterm_t f,occ_t x,occ_t y,occ_t v)104 static composite_t *update2(eterm_t f, occ_t x, occ_t y, occ_t v) {
105 occ_t aux[2];
106
107 aux[0] = x;
108 aux[1] = y;
109 return new_update_composite(pos_occ(f), 2, aux, v);
110 }
111
pair(occ_t x,occ_t y)112 static composite_t *pair(occ_t x, occ_t y) {
113 occ_t aux[2];
114
115 aux[0] = x;
116 aux[1] = y;
117 return new_tuple_composite(2, aux);
118 }
119
lambda(occ_t x,int32_t tag)120 static composite_t *lambda(occ_t x, int32_t tag) {
121 return new_lambda_composite(x, tag);
122 }
123
build_composites(void)124 static void build_composites(void) {
125 composite[0] = pair(pos_occ(a), neg_occ(a));
126 composite[0]->id = 100;
127 composite[1] = pair(pos_occ(a), pos_occ(a));
128 composite[1]->id = 101;
129 composite[2] = pair(neg_occ(a), pos_occ(a));
130 composite[2]->id = 102;
131 composite[3] = pair(neg_occ(a), neg_occ(a));
132 composite[3]->id = 103;
133
134 composite[4] = pair(pos_occ(a), true_occ);
135 composite[4]->id = 104;
136 composite[5] = pair(pos_occ(a), false_occ);
137 composite[5]->id = 105;
138 composite[6] = pair(neg_occ(a), pos_occ(b));
139 composite[6]->id = 106;
140 composite[7] = pair(neg_occ(a), neg_occ(b));
141 composite[7]->id = 107;
142
143 composite[8] = apply2(f, pos_occ(c), pos_occ(c));
144 composite[8]->id = 108;
145 composite[9] = update2(f, pos_occ(c), neg_occ(d), pos_occ(h));
146 composite[9]->id = 109;
147
148 composite[10] = lambda(pos_occ(a), 0);
149 composite[10]->id = 110;
150 composite[11] = lambda(pos_occ(a), 1);
151 composite[11]->id = 110;
152 }
153
delete_composites(uint32_t n)154 static void delete_composites(uint32_t n) {
155 uint32_t k;
156
157 for (k=0; k<n; k++) {
158 safe_free(composite[k]);
159 }
160 }
161
162
print_composites(uint32_t n)163 static void print_composites(uint32_t n) {
164 uint32_t k;
165
166 printf("==== Terms ====\n");
167 for (k=0; k<n; k++) {
168 printf("cmp[%"PRIu32"] = ", k);
169 print_composite(stdout, composite[k]);
170 printf("\n");
171 }
172 fflush(stdout);
173 }
174
show_label(eterm_t t)175 static void show_label(eterm_t t) {
176 print_eterm_id(stdout, t);
177 printf(" ---> ");
178 print_label(stdout, label[t]);
179 printf("\n");
180 }
181
print_labels(void)182 static void print_labels(void) {
183 eterm_t t;
184
185 printf("==== Labels ====\n");
186 for (t=0; t<NT; t++) {
187 show_label(t);
188 }
189 fflush(stdout);
190 }
191
test_signatures(uint32_t n)192 static void test_signatures(uint32_t n) {
193 uint32_t k;
194
195 for (k=0; k<n; k++) {
196 printf("cmp[%"PRIu32"] = ", k);
197 print_composite(stdout, composite[k]);
198 printf("\n");
199 signature_composite(composite[k], label, &sgn);
200 printf("---> signature = ");
201 print_signature(stdout, &sgn);
202 printf("\n");
203 }
204 }
205
test_eq(arena_t * m,occ_t t1,occ_t t2)206 static void test_eq(arena_t *m, occ_t t1, occ_t t2) {
207 composite_t *tmp;
208
209 tmp = arena_eq_composite(m, t1, t2);
210 signature_composite(tmp, label, &sgn);
211 print_composite(stdout, tmp);
212 printf("\t---> signature = ");
213 print_signature(stdout, &sgn);
214 printf("\n");
215 }
216
test_equalities(uint32_t n)217 static void test_equalities(uint32_t n) {
218 uint32_t k, l;
219 arena_t m;
220
221 init_arena(&m);
222 for (k=0; k<n; k++) {
223 arena_push(&m);
224 for (l=0; l<n; l++) {
225 show_label(k);
226 if (k != l) show_label(l);
227
228 test_eq(&m, pos_occ(k), pos_occ(l));
229 test_eq(&m, pos_occ(k), neg_occ(l));
230 test_eq(&m, neg_occ(k), pos_occ(l));
231 test_eq(&m, neg_occ(k), neg_occ(l));
232 printf("\n");
233 }
234 arena_pop(&m);
235 }
236 delete_arena(&m);
237 }
238
239
test_or3(arena_t * m,occ_t t1,occ_t t2,occ_t t3)240 static void test_or3(arena_t *m, occ_t t1, occ_t t2, occ_t t3) {
241 occ_t aux[3];
242 composite_t *tmp;
243
244 aux[0] = t1;
245 aux[1] = t2;
246 aux[2] = t3;
247
248 tmp = arena_or_composite(m, 3, aux);
249 signature_or(tmp, label, &sgn);
250 print_composite(stdout, tmp);
251 printf("\t---> signature = ");
252 print_signature(stdout, &sgn);
253 printf("\n");
254 }
255
test_disjunctions(uint32_t n)256 static void test_disjunctions(uint32_t n) {
257 uint32_t t1, t2, t3;
258 arena_t m;
259
260 init_arena(&m);
261 for (t1=0; t1<n; t1++) {
262 arena_push(&m);
263
264 for (t2=0; t2<n; t2++) {
265 for (t3=0; t3<n; t3++) {
266 show_label(t1);
267 if (t1 != t2) show_label(t2);
268 if (t1 != t3 && t2 != t3) show_label(t3);
269 test_or3(&m, pos_occ(t1), pos_occ(t2), pos_occ(t3));
270 printf("\n");
271 }
272 }
273
274 arena_pop(&m);
275 }
276 delete_arena(&m);
277 }
278
279
test_congruences(uint32_t n)280 static void test_congruences(uint32_t n) {
281 uint32_t k;
282 composite_t *tmp, *root;
283 uint32_t nroots;
284 composite_t *roots[n];
285
286
287 nroots = 0;
288 for (k=0; k<n; k++) {
289 print_composite(stdout, composite[k]);
290 printf("\n");
291 signature_composite(composite[k], label, &sgn);
292 printf("---> signature = ");
293 print_signature(stdout, &sgn);
294 printf("\n");
295
296 root = congruence_table_find(&tbl, &sgn, label);
297 if (root == NULL) {
298 printf("---> not in congruence table\n");
299 } else {
300 printf("---> congruent to term: ");
301 print_composite(stdout, root);
302 printf("\n");
303 }
304
305 tmp = congruence_table_get(&tbl, composite[k], &sgn, label);
306 printf("---> get returns: ");
307 print_composite(stdout, tmp);
308 printf("\n");
309 if (tmp == composite[k] && root == NULL) {
310 printf("---> added as congruence root\n");
311 roots[nroots] = tmp;
312 nroots ++;
313 } else if (tmp == root && root != NULL) {
314 printf("---> confirmed congruence\n");
315 } else {
316 printf("\n*** BUG: get/find disagree ***\n");
317 }
318
319 printf("\n");
320 fflush(stdout);
321 }
322
323 for (k=0; k<nroots; k++) {
324 tmp = roots[k];
325 printf("---> removing root: ");
326 print_composite(stdout, tmp);
327 printf("\n");
328 congruence_table_remove(&tbl, tmp);
329 }
330
331 printf("\n");
332 fflush(stdout);
333 }
334
main(void)335 int main(void) {
336 init_labels();
337 init_sign_buffer(&sgn);
338 init_congruence_table(&tbl, 1);
339
340 build_composites();
341 print_labels();
342 print_composites(12);
343 printf("\n");
344
345 test_signatures(12);
346 printf("\n");
347
348 test_equalities(12);
349 printf("\n");
350
351 test_disjunctions(12);
352 printf("\n");
353
354 test_congruences(12);
355
356 delete_composites(12);
357 delete_congruence_table(&tbl);
358 delete_sign_buffer(&sgn);
359
360 return 0;
361 }
362