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 #include <stdint.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <inttypes.h>
23
24 #include "solvers/egraph/egraph_types.h"
25 #include "solvers/egraph/theory_explanations.h"
26
27 #ifdef MINGW
28
29 /*
30 * Need some version of random()
31 * rand() exists on mingw
32 */
random(void)33 static inline long int random(void) {
34 return rand();
35 }
36
37 #endif
38
39 /*
40 * Theory explanation object:
41 * - av = atom vector
42 * - eqv = equality vector
43 * - dv = disequality vector (not used here)
44 */
show_atoms(atom_vector_t * av)45 static void show_atoms(atom_vector_t *av) {
46 uint32_t i, n, k;
47
48 n = av->size;
49 k = 0;
50 for (i=0; i<n; i++) {
51 if (k == 30) {
52 k = 0;
53 printf("\n ");
54 }
55 k ++;
56 printf(" %"PRId32, av->data[i]);
57 }
58 }
59
show_eqs(eq_vector_t * eqv)60 static void show_eqs(eq_vector_t *eqv) {
61 uint32_t i, n, k;
62
63 n = eqv->size;
64 k = 0;
65 for (i=0; i<n; i++) {
66 if (k == 8) {
67 k = 0;
68 printf("\n ");
69 }
70 k ++;
71 printf(" (t%"PRId32" = t%"PRId32")", eqv->data[i].lhs, eqv->data[i].rhs);
72 }
73 }
74
75
show_th_explanation(th_explanation_t * e)76 static void show_th_explanation(th_explanation_t *e) {
77 literal_t *atm;
78 th_eq_t *eqs;
79 uint32_t na, ne;
80
81 printf(" atoms:");
82 atm = e->atoms;
83 if (atm == NULL) {
84 na = 0;
85 printf(" none\n");
86 } else {
87 na = get_av_size(atm);
88 show_atoms(av_header(atm));
89 printf("\n");
90 }
91 printf(" eqs:");
92 eqs = e->eqs;
93 if (eqs == NULL) {
94 ne = 0;
95 printf(" none\n");
96 } else {
97 ne = get_eqv_size(eqs);
98 show_eqs(eqv_header(eqs));
99 printf("\n");
100 }
101 printf(" %"PRIu32" atoms, %"PRId32" equalities\n", na, ne);
102 }
103
104
105 /*
106 * Add n random atoms to e
107 */
add_atoms(th_explanation_t * e,uint32_t n)108 static void add_atoms(th_explanation_t *e, uint32_t n) {
109 int32_t x;
110
111 while (n > 0) {
112 n --;
113 x = random() & 0x3f;
114 th_explanation_add_atom(e, x);
115 }
116 }
117
118
119 /*
120 * Add n random equalities
121 */
add_eqs(th_explanation_t * e,uint32_t n)122 static void add_eqs(th_explanation_t *e, uint32_t n) {
123 int32_t x, y;
124
125 while (n > 0) {
126 n --;
127 x = random() & 0x1f;
128 y = random() & 0x1f;
129 th_explanation_add_eq(e, x, y);
130 }
131 }
132
133
134 /*
135 * Force a duplicate (provided e has some equalities)
136 */
duplicate_eq(th_explanation_t * e)137 static void duplicate_eq(th_explanation_t *e) {
138 th_eq_t *eqs;
139 uint32_t i, n;
140 int32_t x, y;
141
142 eqs = e->eqs;
143 if (eqs != NULL) {
144 n = get_eqv_size(eqs);
145 if (n > 0) {
146 i = random() % n;
147 x = eqs[i].lhs;
148 y = eqs[i].rhs;
149 printf(" duplicate: (t%"PRId32" = t%"PRId32")\n", y, x);
150 th_explanation_add_eq(e, y, x);
151 }
152 }
153 }
154
duplicate_eqs(th_explanation_t * e,uint32_t n)155 static void duplicate_eqs(th_explanation_t *e, uint32_t n) {
156 while (n > 0) {
157 n --;
158 duplicate_eq(e);
159 }
160 }
161
162
163 /*
164 * Random test with na = number of atoms, ne = number of equalities
165 */
random_test(th_explanation_t * e,uint32_t na,uint32_t ne)166 static void random_test(th_explanation_t *e, uint32_t na, uint32_t ne) {
167 printf("==== Random test ====\n");
168 add_atoms(e, na);
169 add_eqs(e, ne);
170 duplicate_eqs(e, 4);
171 show_th_explanation(e);
172 cleanup_th_explanation(e);
173 printf("After cleanup:\n");
174 show_th_explanation(e);
175 printf("\n");
176 reset_th_explanation(e);
177 }
178
179
180 /*
181 * Special cases for testing sort eqs
182 */
constant_test(th_explanation_t * e,uint32_t n)183 static void constant_test(th_explanation_t *e, uint32_t n) {
184 int32_t x, y;
185
186 x = random() & 0x1f;
187 y = random() & 0x1f;
188 while (n > 0) {
189 n --;
190 th_explanation_add_eq(e, x, y);
191 }
192 printf("==== Constant test ====\n");
193 show_th_explanation(e);
194 cleanup_th_explanation(e);
195 printf("After cleanup:\n");
196 show_th_explanation(e);
197 printf("\n");
198 reset_th_explanation(e);
199 }
200
decreasing_test(th_explanation_t * e,uint32_t n)201 static void decreasing_test(th_explanation_t *e, uint32_t n) {
202 int32_t x;
203
204 x = n + (((uint32_t) random()) & 0x1f);
205 while (n > 0) {
206 th_explanation_add_eq(e, n, x);
207 n --;
208 }
209
210 printf("==== Decreasing test ====\n");
211 show_th_explanation(e);
212 cleanup_th_explanation(e);
213 printf("After cleanup:\n");
214 show_th_explanation(e);
215 printf("\n");
216 reset_th_explanation(e);
217 }
218
increasing_test(th_explanation_t * e,uint32_t n)219 static void increasing_test(th_explanation_t *e, uint32_t n) {
220 uint32_t i;
221 int32_t x;
222
223 x = n + (((uint32_t) random()) & 0x1f);
224 for (i=1; i<=n; i++) {
225 th_explanation_add_eq(e, i, x);
226 }
227
228 printf("==== Increasing test ====\n");
229 show_th_explanation(e);
230 cleanup_th_explanation(e);
231 printf("After cleanup:\n");
232 show_th_explanation(e);
233 printf("\n");
234 reset_th_explanation(e);
235 }
236
237
238
main(void)239 int main(void) {
240 th_explanation_t test;
241 uint32_t i;
242
243 init_th_explanation(&test);
244 for (i=10; i<50; i++) {
245 constant_test(&test, i);
246 }
247 delete_th_explanation(&test);
248
249 init_th_explanation(&test);
250 for (i=10; i<50; i++) {
251 increasing_test(&test, i);
252 }
253 delete_th_explanation(&test);
254
255 init_th_explanation(&test);
256 for (i=10; i<50; i++) {
257 decreasing_test(&test, i);
258 }
259 delete_th_explanation(&test);
260
261 init_th_explanation(&test);
262 printf("==== Initialized ====\n");
263 show_th_explanation(&test);
264 for (i=0; i<20; i++) {
265 random_test(&test, 20, 0);
266 }
267 delete_th_explanation(&test);
268
269 init_th_explanation(&test);
270 printf("==== Initialized ====\n");
271 show_th_explanation(&test);
272 for (i=0; i<20; i++) {
273 random_test(&test, 0, 20);
274 }
275 delete_th_explanation(&test);
276
277 init_th_explanation(&test);
278 printf("==== Initialized ====\n");
279 show_th_explanation(&test);
280 for (i=0; i<30; i++) {
281 random_test(&test, 30, 30);
282 }
283 delete_th_explanation(&test);
284
285 init_th_explanation(&test);
286 printf("==== Initialized ====\n");
287 show_th_explanation(&test);
288 for (i=0; i<40; i++) {
289 random_test(&test, 40, 40);
290 }
291 delete_th_explanation(&test);
292
293 return 0;
294 }
295