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  * VARIABLE TABLE FOR BITVECTOR SOLVER
21  */
22 
23 #include "solvers/bv/bv_vartable.h"
24 #include "terms/bv64_constants.h"
25 #include "terms/bv_constants.h"
26 #include "utils/hash_functions.h"
27 #include "utils/memalloc.h"
28 
29 
30 /*
31  * Initialize table
32  * - use the default size
33  * - the eterm array is not allocated here, but on the first
34  *   call to attach_eterm
35  * - variable 0 is reserved to prevent confusion with const_idx
36  */
init_bv_vartable(bv_vartable_t * table)37 void init_bv_vartable(bv_vartable_t *table) {
38   uint32_t n;
39 
40   n = DEF_BVVARTABLE_SIZE;
41   assert(1 <= n && n < MAX_BVVARTABLE_SIZE);
42 
43   table->nvars = 1;
44   table->size = n;
45   table->bit_size = (uint32_t *) safe_malloc(n * sizeof(uint32_t));
46   table->kind = (uint8_t *) safe_malloc(n * sizeof(uint8_t));
47   table->def = (bvvar_desc_t *) safe_malloc(n * sizeof(bvvar_desc_t));
48   table->eterm = NULL;
49   table->map = (literal_t **) safe_malloc(n * sizeof(literal_t *));
50 
51   // fake descriptor for variable 0
52   table->map[0] = NULL;
53   table->def[0].ptr = NULL;
54   table->kind[0] = BVTAG_VAR;
55   table->bit_size[0] = 0;
56 
57   init_int_htbl(&table->htbl, 0);
58 }
59 
60 
61 /*
62  * Make the table 50% larger
63  */
extend_bv_vartable(bv_vartable_t * table)64 static void extend_bv_vartable(bv_vartable_t *table) {
65   uint32_t n;
66 
67   n = table->size + 1;
68   n += n>>1;
69 
70   if (n >= MAX_BVVARTABLE_SIZE) {
71     out_of_memory();
72   }
73 
74   table->bit_size = (uint32_t *) safe_realloc(table->bit_size, n * sizeof(uint32_t));
75   table->kind = (uint8_t *) safe_realloc(table->kind, n * sizeof(uint8_t));
76   table->def = (bvvar_desc_t *) safe_realloc(table->def, n * sizeof(bvvar_desc_t));
77   if (table->eterm != NULL) {
78     table->eterm = (eterm_t *) safe_realloc(table->eterm, n * sizeof(eterm_t));
79   }
80   table->map = (literal_t **) safe_realloc(table->map, n * sizeof(literal_t *));
81 
82   table->size = n;
83 }
84 
85 
86 /*
87  * Delete the table
88  */
delete_bv_vartable(bv_vartable_t * table)89 void delete_bv_vartable(bv_vartable_t *table) {
90   uint32_t i, n;
91 
92   n = table->nvars;
93   for (i=1; i<n; i++) {
94     int_array_decref(table->map[i]);
95     switch (bvvar_tag(table, i)) {
96     case BVTAG_CONST:
97     case BVTAG_POLY64:
98     case BVTAG_PPROD:
99     case BVTAG_BIT_ARRAY:
100     case BVTAG_ITE:
101       safe_free(table->def[i].ptr);
102       break;
103 
104     case BVTAG_POLY:
105       free_bvpoly(table->def[i].ptr);
106       break;
107 
108     default:
109       break;
110     }
111   }
112 
113   safe_free(table->bit_size);
114   safe_free(table->kind);
115   safe_free(table->def);
116   safe_free(table->eterm);
117   safe_free(table->map);
118 
119   table->bit_size = NULL;
120   table->kind = NULL;
121   table->def = NULL;
122   table->eterm = NULL;
123   table->map = NULL;
124 
125   delete_int_htbl(&table->htbl);
126 }
127 
128 
129 /*
130  * Reset: empty the table
131  */
reset_bv_vartable(bv_vartable_t * table)132 void reset_bv_vartable(bv_vartable_t *table) {
133   uint32_t i, n;
134 
135   n = table->nvars;
136   for (i=1; i<n; i++) {
137     int_array_decref(table->map[i]);
138     switch (bvvar_tag(table, i)) {
139     case BVTAG_CONST:
140     case BVTAG_POLY64:
141     case BVTAG_PPROD:
142     case BVTAG_BIT_ARRAY:
143     case BVTAG_ITE:
144       safe_free(table->def[i].ptr);
145       break;
146 
147     case BVTAG_POLY:
148       free_bvpoly(table->def[i].ptr);
149       break;
150 
151     default:
152       break;
153     }
154   }
155 
156   table->nvars = 1;
157 
158   reset_int_htbl(&table->htbl);
159 }
160 
161 
162 /*
163  * Attach egraph term t to variable x
164  * - x must be not have an eterm attached already
165  */
attach_eterm_to_bvvar(bv_vartable_t * table,thvar_t x,eterm_t t)166 void attach_eterm_to_bvvar(bv_vartable_t *table, thvar_t x, eterm_t t) {
167   eterm_t *tmp;
168   uint32_t i, n;
169 
170   assert(1 <= x && x < table->nvars && t != null_eterm);
171 
172   tmp = table->eterm;
173   if (tmp == NULL) {
174     n = table->size;
175     tmp = (eterm_t *) safe_malloc(n * sizeof(eterm_t));
176     n = table->nvars;
177     for (i=0; i<n; i++) {
178       tmp[i] = null_eterm;
179     }
180     table->eterm = tmp;
181   }
182   assert(tmp[x] == null_eterm);
183   tmp[x] = t;
184 }
185 
186 
187 
188 
189 /*
190  * Remove all eterms of id >= nterms
191  */
bv_vartable_remove_eterms(bv_vartable_t * table,uint32_t nterms)192 void bv_vartable_remove_eterms(bv_vartable_t *table, uint32_t nterms) {
193   eterm_t *tmp;
194   uint32_t i, n;
195   eterm_t t;
196 
197   tmp = table->eterm;
198 
199   if (tmp != NULL) {
200     n = table->nvars;
201     for (i=1; i<n; i++) {
202       t = tmp[i];
203       if (t != null_eterm && t >= nterms) {
204         tmp[i] = null_eterm;
205       }
206     }
207   }
208 }
209 
210 
211 
212 /*
213  * Hash codes of a variable descriptor
214  *
215  * For bvpoly and bvpoly64 we use
216  * hash_bvpoly   (in bv_polynomials)
217  * hash_bvpoly64 (in bv64_polynomials)
218  *
219  */
220 // n = number of bits
hash_bvconst64(uint64_t c,uint32_t n)221 static inline uint32_t hash_bvconst64(uint64_t c, uint32_t n) {
222   uint32_t a, b;
223   a = jenkins_hash_uint64(c);
224   b = jenkins_hash_uint32(n);
225   return jenkins_hash_mix2(a, b);
226 }
227 
hash_bvconst(uint32_t * c,uint32_t n)228 static inline uint32_t hash_bvconst(uint32_t *c, uint32_t n) {
229   return bvconst_hash(c, n);
230 }
231 
232 // array of k pairs (variable, exponent)
hash_bvpprod_array(varexp_t * a,uint32_t k)233 static inline uint32_t hash_bvpprod_array(varexp_t *a, uint32_t k) {
234   assert(k <= UINT32_MAX/2);
235   return jenkins_hash_intarray((int32_t *) a, 2 * k);
236 }
237 
hash_bvpprod(pprod_t * p)238 static inline uint32_t hash_bvpprod(pprod_t *p) {
239   return hash_bvpprod_array(p->prod, p->len);
240 }
241 
hash_bvarray(literal_t * b,uint32_t n)242 static inline uint32_t hash_bvarray(literal_t *b, uint32_t n) {
243   return jenkins_hash_intarray2(b, n, 0xaed32b8);
244 }
245 
hash_bvite(literal_t c,thvar_t x,thvar_t y)246 static inline uint32_t hash_bvite(literal_t c, thvar_t x, thvar_t y) {
247   return jenkins_hash_triple(c, x, y, 0xfe2efd45);
248 }
249 
hash_bvite_ptr(bv_ite_t * d)250 static inline uint32_t hash_bvite_ptr(bv_ite_t *d) {
251   return hash_bvite(d->cond, d->left, d->right);
252 }
253 
hash_bvdiv(thvar_t x,thvar_t y)254 static inline uint32_t hash_bvdiv(thvar_t x, thvar_t y) {
255   return jenkins_hash_pair(x, y, 0x2389a23f);
256 }
257 
hash_bvrem(thvar_t x,thvar_t y)258 static inline uint32_t hash_bvrem(thvar_t x, thvar_t y) {
259   return jenkins_hash_pair(x, y, 0x237bc32f);
260 }
261 
hash_bvsdiv(thvar_t x,thvar_t y)262 static inline uint32_t hash_bvsdiv(thvar_t x, thvar_t y) {
263   return jenkins_hash_pair(x, y, 0x9afe2ab2);
264 }
265 
hash_bvsrem(thvar_t x,thvar_t y)266 static inline uint32_t hash_bvsrem(thvar_t x, thvar_t y) {
267   return jenkins_hash_pair(x, y, 0xbe7bca36);
268 }
269 
hash_bvsmod(thvar_t x,thvar_t y)270 static inline uint32_t hash_bvsmod(thvar_t x, thvar_t y) {
271   return jenkins_hash_pair(x, y, 0xeab2d457);
272 }
273 
hash_bvshl(thvar_t x,thvar_t y)274 static inline uint32_t hash_bvshl(thvar_t x, thvar_t y) {
275   return jenkins_hash_pair(x, y, 0xc2ad173f);
276 }
277 
hash_bvlshr(thvar_t x,thvar_t y)278 static inline uint32_t hash_bvlshr(thvar_t x, thvar_t y) {
279   return jenkins_hash_pair(x, y, 0x81023ae5);
280 }
281 
hash_bvashr(thvar_t x,thvar_t y)282 static inline uint32_t hash_bvashr(thvar_t x, thvar_t y) {
283   return jenkins_hash_pair(x, y, 0xc3e4fed1);
284 }
285 
hash_bvadd(thvar_t x,thvar_t y)286 static inline uint32_t hash_bvadd(thvar_t x, thvar_t y) {
287   return jenkins_hash_pair(x, y, 0x198cea23);
288 }
289 
hash_bvsub(thvar_t x,thvar_t y)290 static inline uint32_t hash_bvsub(thvar_t x, thvar_t y) {
291   return jenkins_hash_pair(x, y, 0xb8b423c6);
292 }
293 
hash_bvmul(thvar_t x,thvar_t y)294 static inline uint32_t hash_bvmul(thvar_t x, thvar_t y) {
295   return jenkins_hash_pair(x, y, 0x43c94873);
296 }
297 
hash_bvneg(thvar_t x)298 static inline uint32_t hash_bvneg(thvar_t x) {
299   return jenkins_hash_pair(x, x, 0x4b0d5cff);
300 }
301 
302 
303 
304 /*
305  * Remove all variables of index >= nv
306  */
bv_vartable_remove_vars(bv_vartable_t * table,uint32_t nv)307 void bv_vartable_remove_vars(bv_vartable_t *table, uint32_t nv) {
308   uint32_t i, n, h;
309 
310   assert(1 <= nv && nv <= table->nvars);
311 
312   h = 0; // stop GCC warning
313 
314   n = table->nvars;
315   for (i=nv; i<n; i++) {
316     switch (bvvar_tag(table, i)) {
317     case BVTAG_VAR:
318       // no hash consing, no descriptor
319       int_array_decref(table->map[i]);
320       continue;
321 
322     case BVTAG_CONST64:
323       h = hash_bvconst64(table->def[i].val, table->bit_size[i]);
324       break;
325 
326     case BVTAG_CONST:
327       h = hash_bvconst(table->def[i].ptr, table->bit_size[i]);
328       safe_free(table->def[i].ptr);
329       break;
330 
331     case BVTAG_POLY64:
332       h = hash_bvpoly64(table->def[i].ptr);
333       safe_free(table->def[i].ptr);
334       break;
335 
336     case BVTAG_POLY:
337       h = hash_bvpoly(table->def[i].ptr);
338       free_bvpoly(table->def[i].ptr);
339       break;
340 
341     case BVTAG_PPROD:
342       h = hash_bvpprod(table->def[i].ptr);
343       safe_free(table->def[i].ptr);
344       break;
345 
346     case BVTAG_BIT_ARRAY:
347       h = hash_bvarray(table->def[i].ptr, table->bit_size[i]);
348       safe_free(table->def[i].ptr);
349       break;
350 
351     case BVTAG_ITE:
352       h = hash_bvite_ptr(table->def[i].ptr);
353       safe_free(table->def[i].ptr);
354       break;
355 
356     case BVTAG_UDIV:
357       h = hash_bvdiv(table->def[i].op[0], table->def[i].op[1]);
358       break;
359 
360     case BVTAG_UREM:
361       h = hash_bvrem(table->def[i].op[0], table->def[i].op[1]);
362       break;
363 
364     case BVTAG_SDIV:
365       h = hash_bvsdiv(table->def[i].op[0], table->def[i].op[1]);
366       break;
367 
368     case BVTAG_SREM:
369       h = hash_bvsrem(table->def[i].op[0], table->def[i].op[1]);
370       break;
371 
372     case BVTAG_SMOD:
373       h = hash_bvsmod(table->def[i].op[0], table->def[i].op[1]);
374       break;
375 
376     case BVTAG_SHL:
377       h = hash_bvshl(table->def[i].op[0], table->def[i].op[1]);
378       break;
379 
380     case BVTAG_LSHR:
381       h = hash_bvlshr(table->def[i].op[0], table->def[i].op[1]);
382       break;
383 
384     case BVTAG_ASHR:
385       h = hash_bvashr(table->def[i].op[0], table->def[i].op[1]);
386       break;
387 
388     case BVTAG_ADD:
389       h = hash_bvadd(table->def[i].op[0], table->def[i].op[1]);
390       break;
391 
392     case BVTAG_SUB:
393       h = hash_bvsub(table->def[i].op[0], table->def[i].op[1]);
394       break;
395 
396     case BVTAG_MUL:
397       h = hash_bvmul(table->def[i].op[0], table->def[i].op[1]);
398       break;
399 
400     case BVTAG_NEG:
401       h = hash_bvneg(table->def[i].op[0]);
402       break;
403     }
404 
405     int_htbl_erase_record(&table->htbl, h, i);
406     int_array_decref(table->map[i]);
407   }
408 
409   table->nvars = nv;
410 }
411 
412 
413 
414 /*
415  * Allocate a new variable id of n bits
416  * - the descriptors are partially initialized:
417  *   bit_size = n
418  *   eterm = null_eterm if table->eterm exists
419  *   map = NULL
420  * - def and kind are not set
421  */
bv_vartable_alloc_id(bv_vartable_t * table,uint32_t n)422 static thvar_t bv_vartable_alloc_id(bv_vartable_t *table, uint32_t n) {
423   uint32_t x;
424 
425   x = table->nvars;
426   if (x == table->size) {
427     extend_bv_vartable(table);
428   }
429   assert(x < table->size);
430   table->bit_size[x] = n;
431   table->map[x] = NULL;
432   if (table->eterm != NULL) {
433     table->eterm[x] = null_eterm;
434   }
435 
436   table->nvars = x + 1;
437 
438   return x;
439 }
440 
441 
442 
443 /*
444  * Constructors:
445  * - all constructors create a new theory variable with the given definition
446  * - when present n = bitsize of the new variable
447  */
make_bvvar(bv_vartable_t * table,uint32_t n)448 thvar_t make_bvvar(bv_vartable_t *table, uint32_t n) {
449   thvar_t x;
450 
451   x = bv_vartable_alloc_id(table, n);
452   table->kind[x] = BVTAG_VAR;
453 
454   return x;
455 }
456 
make_bvconst64(bv_vartable_t * table,uint32_t n,uint64_t val)457 static thvar_t make_bvconst64(bv_vartable_t *table, uint32_t n, uint64_t val) {
458   thvar_t x;
459 
460   assert(norm64(val, n) == val);
461   x = bv_vartable_alloc_id(table, n);
462   table->kind[x] = BVTAG_CONST64;
463   table->def[x].val = val;
464 
465   return x;
466 }
467 
make_bvconst(bv_vartable_t * table,uint32_t n,uint32_t * val)468 static thvar_t make_bvconst(bv_vartable_t *table, uint32_t n, uint32_t *val) {
469   uint32_t *tmp;
470   thvar_t x;
471   uint32_t w;
472 
473   // make a copy of val
474   w = (n + 31) >> 5;
475   tmp = (uint32_t *) safe_malloc(w * sizeof(uint32_t));
476   bvconst_set(tmp, w, val);
477   bvconst_normalize(tmp, n);
478 
479   x = bv_vartable_alloc_id(table, n);
480   table->kind[x] = BVTAG_CONST;
481   table->def[x].ptr = tmp;
482 
483   return x;
484 }
485 
make_bvpoly64(bv_vartable_t * table,bvpoly_buffer_t * b)486 static thvar_t make_bvpoly64(bv_vartable_t *table, bvpoly_buffer_t *b) {
487   thvar_t x;
488 
489   x = bv_vartable_alloc_id(table, b->bitsize);
490   table->kind[x] = BVTAG_POLY64;
491   table->def[x].ptr = bvpoly_buffer_getpoly64(b);
492 
493   return x;
494 }
495 
make_bvpoly(bv_vartable_t * table,bvpoly_buffer_t * b)496 static thvar_t make_bvpoly(bv_vartable_t *table, bvpoly_buffer_t *b) {
497   thvar_t x;
498 
499   x = bv_vartable_alloc_id(table, b->bitsize);
500   table->kind[x] = BVTAG_POLY;
501   table->def[x].ptr = bvpoly_buffer_getpoly(b);
502 
503   return x;
504 }
505 
make_bvpprod(bv_vartable_t * table,uint32_t n,pp_buffer_t * b)506 static thvar_t make_bvpprod(bv_vartable_t *table, uint32_t n, pp_buffer_t *b) {
507   thvar_t x;
508 
509   x = bv_vartable_alloc_id(table, n);
510   table->kind[x] = BVTAG_PPROD;
511   table->def[x].ptr = pp_buffer_getprod(b);
512 
513   return x;
514 }
515 
make_bvarray(bv_vartable_t * table,uint32_t n,literal_t * a)516 static thvar_t make_bvarray(bv_vartable_t *table, uint32_t n, literal_t *a) {
517   literal_t *b;
518   uint32_t i;
519   thvar_t x;
520 
521   // make a copy of a
522   b = (literal_t *) safe_malloc(n * sizeof(literal_t));
523   for (i=0; i<n; i++) {
524     b[i] = a[i];
525   }
526 
527   x = bv_vartable_alloc_id(table, n);
528   table->kind[x] = BVTAG_BIT_ARRAY;
529   table->def[x].ptr = b;
530 
531   return x;
532 }
533 
make_bvite(bv_vartable_t * table,uint32_t n,literal_t c,thvar_t left,thvar_t right)534 static thvar_t make_bvite(bv_vartable_t *table, uint32_t n, literal_t c, thvar_t left, thvar_t right) {
535   bv_ite_t *b;
536   thvar_t x;
537 
538   b = (bv_ite_t *) safe_malloc(sizeof(bv_ite_t));
539   b->cond = c;
540   b->left = left;
541   b->right = right;
542 
543   x = bv_vartable_alloc_id(table, n);
544   table->kind[x] = BVTAG_ITE;
545   table->def[x].ptr = b;
546 
547   return x;
548 }
549 
550 
551 // binary operator: tag must be in BVTAG_UDIV ... BVTAG_ASHR
make_bvbinop(bv_vartable_t * table,bvvar_tag_t tag,uint32_t n,thvar_t x,thvar_t y)552 static thvar_t make_bvbinop(bv_vartable_t *table, bvvar_tag_t tag, uint32_t n, thvar_t x, thvar_t y) {
553   thvar_t z;
554 
555   z = bv_vartable_alloc_id(table, n);
556   table->kind[z] = tag;
557   table->def[z].op[0] = x;
558   table->def[z].op[1] = y;
559 
560   return z;
561 }
562 
563 
564 
565 /*
566  * HASH CONSING OBJECTS (cf. int_hash_tables)
567  */
568 typedef struct bvconst64_hobj_s {
569   int_hobj_t m;
570   bv_vartable_t *tbl;
571   uint64_t val;
572   uint32_t nbits;
573 } bvconst64_hobj_t;
574 
575 typedef struct bvconst_hobj_s {
576   int_hobj_t m;
577   bv_vartable_t *tbl;
578   uint32_t *val;
579   uint32_t nbits;
580 } bvconst_hobj_t;
581 
582 typedef struct bvpoly_hobj_s {
583   int_hobj_t m;
584   bv_vartable_t *tbl;
585   bvpoly_buffer_t *buffer;
586 } bvpoly_hobj_t;
587 
588 typedef struct bvpprod_hobj_s {
589   int_hobj_t m;
590   bv_vartable_t *tbl;
591   pp_buffer_t *buffer;
592   uint32_t nbits;
593 } bvpprod_hobj_t;
594 
595 typedef struct bvarray_hobj_s {
596   int_hobj_t m;
597   bv_vartable_t *tbl;
598   literal_t *val;
599   uint32_t nbits;
600 } bvarray_hobj_t;
601 
602 typedef struct bvite_hobj_s {
603   int_hobj_t m;
604   bv_vartable_t *tbl;
605   literal_t cond;
606   thvar_t left;
607   thvar_t right;
608   uint32_t nbits;
609 } bvite_hobj_t;
610 
611 // for all binary constructors
612 typedef struct bvop_hobj_s {
613   int_hobj_t m;
614   bv_vartable_t *tbl;
615   thvar_t left;
616   thvar_t right;
617   uint32_t nbits;
618 }  bvop_hobj_t;
619 
620 
621 /*
622  * Hash functions
623  */
hash_bvconst64_hobj(bvconst64_hobj_t * p)624 static uint32_t hash_bvconst64_hobj(bvconst64_hobj_t *p) {
625   return hash_bvconst64(p->val, p->nbits);
626 }
627 
hash_bvconst_hobj(bvconst_hobj_t * p)628 static uint32_t hash_bvconst_hobj(bvconst_hobj_t *p) {
629   return hash_bvconst(p->val, p->nbits);
630 }
631 
hash_bvpoly64_hobj(bvpoly_hobj_t * p)632 static uint32_t hash_bvpoly64_hobj(bvpoly_hobj_t *p) {
633   return bvpoly_buffer_hash64(p->buffer);
634 }
635 
hash_bvpoly_hobj(bvpoly_hobj_t * p)636 static uint32_t hash_bvpoly_hobj(bvpoly_hobj_t *p) {
637   return bvpoly_buffer_hash(p->buffer);
638 }
639 
hash_bvpprod_hobj(bvpprod_hobj_t * p)640 static uint32_t hash_bvpprod_hobj(bvpprod_hobj_t *p) {
641   pp_buffer_t *b;
642 
643   b = p->buffer;
644   return hash_bvpprod_array(b->prod, b->len);
645 }
646 
hash_bvarray_hobj(bvarray_hobj_t * p)647 static uint32_t hash_bvarray_hobj(bvarray_hobj_t *p) {
648   return hash_bvarray(p->val, p->nbits);
649 }
650 
hash_bvite_hobj(bvite_hobj_t * p)651 static uint32_t hash_bvite_hobj(bvite_hobj_t *p) {
652   return hash_bvite(p->cond, p->left, p->right);
653 }
654 
hash_bvdiv_hobj(bvop_hobj_t * p)655 static uint32_t hash_bvdiv_hobj(bvop_hobj_t *p) {
656   return hash_bvdiv(p->left, p->right);
657 }
658 
hash_bvrem_hobj(bvop_hobj_t * p)659 static uint32_t hash_bvrem_hobj(bvop_hobj_t *p) {
660   return hash_bvrem(p->left, p->right);
661 }
662 
hash_bvsdiv_hobj(bvop_hobj_t * p)663 static uint32_t hash_bvsdiv_hobj(bvop_hobj_t *p) {
664   return hash_bvsdiv(p->left, p->right);
665 }
666 
hash_bvsrem_hobj(bvop_hobj_t * p)667 static uint32_t hash_bvsrem_hobj(bvop_hobj_t *p) {
668   return hash_bvsrem(p->left, p->right);
669 }
670 
hash_bvsmod_hobj(bvop_hobj_t * p)671 static uint32_t hash_bvsmod_hobj(bvop_hobj_t *p) {
672   return hash_bvsmod(p->left, p->right);
673 }
674 
hash_bvshl_hobj(bvop_hobj_t * p)675 static uint32_t hash_bvshl_hobj(bvop_hobj_t *p) {
676   return hash_bvshl(p->left, p->right);
677 }
678 
hash_bvlshr_hobj(bvop_hobj_t * p)679 static uint32_t hash_bvlshr_hobj(bvop_hobj_t *p) {
680   return hash_bvlshr(p->left, p->right);
681 }
682 
hash_bvashr_hobj(bvop_hobj_t * p)683 static uint32_t hash_bvashr_hobj(bvop_hobj_t *p) {
684   return hash_bvashr(p->left, p->right);
685 }
686 
hash_bvadd_hobj(bvop_hobj_t * p)687 static uint32_t hash_bvadd_hobj(bvop_hobj_t *p) {
688   return hash_bvadd(p->left, p->right);
689 }
690 
hash_bvsub_hobj(bvop_hobj_t * p)691 static uint32_t hash_bvsub_hobj(bvop_hobj_t *p) {
692   return hash_bvsub(p->left, p->right);
693 }
694 
hash_bvmul_hobj(bvop_hobj_t * p)695 static uint32_t hash_bvmul_hobj(bvop_hobj_t *p) {
696   return hash_bvmul(p->left, p->right);
697 }
698 
hash_bvneg_hobj(bvop_hobj_t * p)699 static uint32_t hash_bvneg_hobj(bvop_hobj_t *p) {
700   return hash_bvneg(p->left);
701 }
702 
703 
704 
705 /*
706  * Equality tests
707  */
eq_bvconst64_hobj(bvconst64_hobj_t * p,thvar_t i)708 static bool eq_bvconst64_hobj(bvconst64_hobj_t *p, thvar_t i) {
709   bv_vartable_t *table;
710 
711   table = p->tbl;
712   return bvvar_tag(table, i) == BVTAG_CONST64 &&
713     table->bit_size[i] == p->nbits && table->def[i].val == p->val;
714 }
715 
eq_bvconst_hobj(bvconst_hobj_t * p,thvar_t i)716 static bool eq_bvconst_hobj(bvconst_hobj_t *p, thvar_t i) {
717   bv_vartable_t *table;
718   uint32_t w;
719 
720   table = p->tbl;
721   if (bvvar_tag(table, i) != BVTAG_CONST || table->bit_size[i] != p->nbits) {
722     return false;
723  }
724   w = (p->nbits + 31) >> 5;
725   return bvconst_eq(p->val, table->def[i].ptr, w);
726 }
727 
eq_bvpoly64_hobj(bvpoly_hobj_t * p,thvar_t i)728 static bool eq_bvpoly64_hobj(bvpoly_hobj_t *p, thvar_t i) {
729   bv_vartable_t *table;
730 
731   table = p->tbl;
732   return bvvar_tag(table, i) == BVTAG_POLY64 &&
733     bvpoly_buffer_equal_poly64(p->buffer, table->def[i].ptr);
734 }
735 
eq_bvpoly_hobj(bvpoly_hobj_t * p,thvar_t i)736 static bool eq_bvpoly_hobj(bvpoly_hobj_t *p, thvar_t i) {
737   bv_vartable_t *table;
738 
739   table = p->tbl;
740   return bvvar_tag(table, i) == BVTAG_POLY &&
741     bvpoly_buffer_equal_poly(p->buffer, table->def[i].ptr);
742 }
743 
744 
745 // helper function
pp_buffer_eq_pprod(pp_buffer_t * buffer,pprod_t * p)746 static bool pp_buffer_eq_pprod(pp_buffer_t *buffer, pprod_t *p) {
747   uint32_t n;
748 
749   n = buffer->len;
750   return p->len == n && varexp_array_equal(buffer->prod, p->prod, n);
751 }
752 
eq_bvpprod_hobj(bvpprod_hobj_t * p,thvar_t i)753 static bool eq_bvpprod_hobj(bvpprod_hobj_t *p, thvar_t i) {
754   bv_vartable_t *table;
755 
756   table = p->tbl;
757   return bvvar_tag(table, i) == BVTAG_PPROD &&
758     pp_buffer_eq_pprod(p->buffer, table->def[i].ptr);
759 }
760 
761 
eq_bvarray_hobj(bvarray_hobj_t * p,thvar_t i)762 static bool eq_bvarray_hobj(bvarray_hobj_t *p, thvar_t i) {
763   bv_vartable_t *table;
764   literal_t *a;
765   uint32_t j, n;
766 
767   table = p->tbl;
768   n = p->nbits;
769   if (bvvar_tag(table, i) != BVTAG_BIT_ARRAY || table->bit_size[i] != n) {
770     return false;
771   }
772 
773   a = table->def[i].ptr;
774   for (j=0; j<n; j++) {
775     if (a[j] != p->val[j]) return false;
776   }
777 
778   return true;
779 }
780 
eq_bvite_hobj(bvite_hobj_t * p,thvar_t i)781 static bool eq_bvite_hobj(bvite_hobj_t *p, thvar_t i) {
782   bv_vartable_t *table;
783   bv_ite_t *d;
784 
785   table = p->tbl;
786   if (bvvar_tag(table, i) == BVTAG_ITE) {
787     d = table->def[i].ptr;
788     return d->cond == p->cond && d->left == p->left && d->right == p->right;
789   } else {
790     return false;
791   }
792 }
793 
eq_bvdiv_hobj(bvop_hobj_t * p,thvar_t i)794 static bool eq_bvdiv_hobj(bvop_hobj_t *p, thvar_t i) {
795   bv_vartable_t *table;
796 
797   table = p->tbl;
798   return bvvar_tag(table, i) == BVTAG_UDIV && table->def[i].op[0] == p->left &&
799     table->def[i].op[1] == p->right;
800 }
801 
eq_bvrem_hobj(bvop_hobj_t * p,thvar_t i)802 static bool eq_bvrem_hobj(bvop_hobj_t *p, thvar_t i) {
803   bv_vartable_t *table;
804 
805   table = p->tbl;
806   return bvvar_tag(table, i) == BVTAG_UREM && table->def[i].op[0] == p->left &&
807     table->def[i].op[1] == p->right;
808 }
809 
eq_bvsdiv_hobj(bvop_hobj_t * p,thvar_t i)810 static bool eq_bvsdiv_hobj(bvop_hobj_t *p, thvar_t i) {
811   bv_vartable_t *table;
812 
813   table = p->tbl;
814   return bvvar_tag(table, i) == BVTAG_SDIV && table->def[i].op[0] == p->left &&
815     table->def[i].op[1] == p->right;
816 }
817 
eq_bvsrem_hobj(bvop_hobj_t * p,thvar_t i)818 static bool eq_bvsrem_hobj(bvop_hobj_t *p, thvar_t i) {
819   bv_vartable_t *table;
820 
821   table = p->tbl;
822   return bvvar_tag(table, i) == BVTAG_SREM && table->def[i].op[0] == p->left &&
823     table->def[i].op[1] == p->right;
824 }
825 
eq_bvsmod_hobj(bvop_hobj_t * p,thvar_t i)826 static bool eq_bvsmod_hobj(bvop_hobj_t *p, thvar_t i) {
827   bv_vartable_t *table;
828 
829   table = p->tbl;
830   return bvvar_tag(table, i) == BVTAG_SMOD && table->def[i].op[0] == p->left &&
831     table->def[i].op[1] == p->right;
832 }
833 
eq_bvshl_hobj(bvop_hobj_t * p,thvar_t i)834 static bool eq_bvshl_hobj(bvop_hobj_t *p, thvar_t i) {
835   bv_vartable_t *table;
836 
837   table = p->tbl;
838   return bvvar_tag(table, i) == BVTAG_SHL && table->def[i].op[0] == p->left &&
839     table->def[i].op[1] == p->right;
840 }
841 
eq_bvlshr_hobj(bvop_hobj_t * p,thvar_t i)842 static bool eq_bvlshr_hobj(bvop_hobj_t *p, thvar_t i) {
843   bv_vartable_t *table;
844 
845   table = p->tbl;
846   return bvvar_tag(table, i) == BVTAG_LSHR && table->def[i].op[0] == p->left &&
847     table->def[i].op[1] == p->right;
848 }
849 
eq_bvashr_hobj(bvop_hobj_t * p,thvar_t i)850 static bool eq_bvashr_hobj(bvop_hobj_t *p, thvar_t i) {
851   bv_vartable_t *table;
852 
853   table = p->tbl;
854   return bvvar_tag(table, i) == BVTAG_ASHR && table->def[i].op[0] == p->left &&
855     table->def[i].op[1] == p->right;
856 }
857 
858 
eq_bvadd_hobj(bvop_hobj_t * p,thvar_t i)859 static bool eq_bvadd_hobj(bvop_hobj_t *p, thvar_t i) {
860   bv_vartable_t *table;
861 
862   table = p->tbl;
863   return bvvar_tag(table, i) == BVTAG_ADD && table->def[i].op[0] == p->left &&
864     table->def[i].op[1] == p->right;
865 }
866 
eq_bvsub_hobj(bvop_hobj_t * p,thvar_t i)867 static bool eq_bvsub_hobj(bvop_hobj_t *p, thvar_t i) {
868   bv_vartable_t *table;
869 
870   table = p->tbl;
871   return bvvar_tag(table, i) == BVTAG_SUB && table->def[i].op[0] == p->left &&
872     table->def[i].op[1] == p->right;
873 }
874 
eq_bvmul_hobj(bvop_hobj_t * p,thvar_t i)875 static bool eq_bvmul_hobj(bvop_hobj_t *p, thvar_t i) {
876   bv_vartable_t *table;
877 
878   table = p->tbl;
879   return bvvar_tag(table, i) == BVTAG_MUL && table->def[i].op[0] == p->left &&
880     table->def[i].op[1] == p->right;
881 }
882 
eq_bvneg_hobj(bvop_hobj_t * p,thvar_t i)883 static bool eq_bvneg_hobj(bvop_hobj_t *p, thvar_t i) {
884   bv_vartable_t *table;
885 
886   table = p->tbl;
887   return bvvar_tag(table, i) == BVTAG_NEG && table->def[i].op[0] == p->left;
888 }
889 
890 
891 
892 
893 
894 /*
895  * Build
896  */
build_bvconst64_hobj(bvconst64_hobj_t * p)897 static thvar_t build_bvconst64_hobj(bvconst64_hobj_t *p) {
898   return make_bvconst64(p->tbl, p->nbits, p->val);
899 }
900 
build_bvconst_hobj(bvconst_hobj_t * p)901 static thvar_t build_bvconst_hobj(bvconst_hobj_t *p) {
902   return make_bvconst(p->tbl, p->nbits, p->val);
903 }
904 
build_bvpoly64_hobj(bvpoly_hobj_t * p)905 static thvar_t build_bvpoly64_hobj(bvpoly_hobj_t *p) {
906   return make_bvpoly64(p->tbl, p->buffer);
907 }
908 
build_bvpoly_hobj(bvpoly_hobj_t * p)909 static thvar_t build_bvpoly_hobj(bvpoly_hobj_t *p) {
910   return make_bvpoly(p->tbl, p->buffer);
911 }
912 
build_bvpprod_hobj(bvpprod_hobj_t * p)913 static thvar_t build_bvpprod_hobj(bvpprod_hobj_t *p) {
914   return make_bvpprod(p->tbl, p->nbits, p->buffer);
915 }
916 
build_bvarray_hobj(bvarray_hobj_t * p)917 static thvar_t build_bvarray_hobj(bvarray_hobj_t *p) {
918   return make_bvarray(p->tbl, p->nbits, p->val);
919 }
920 
build_bvite_hobj(bvite_hobj_t * p)921 static thvar_t build_bvite_hobj(bvite_hobj_t *p) {
922   return make_bvite(p->tbl, p->nbits, p->cond, p->left, p->right);
923 }
924 
build_bvdiv_hobj(bvop_hobj_t * p)925 static thvar_t build_bvdiv_hobj(bvop_hobj_t *p) {
926   return make_bvbinop(p->tbl, BVTAG_UDIV, p->nbits, p->left, p->right);
927 }
928 
build_bvrem_hobj(bvop_hobj_t * p)929 static thvar_t build_bvrem_hobj(bvop_hobj_t *p) {
930   return make_bvbinop(p->tbl, BVTAG_UREM, p->nbits, p->left, p->right);
931 }
932 
build_bvsdiv_hobj(bvop_hobj_t * p)933 static thvar_t build_bvsdiv_hobj(bvop_hobj_t *p) {
934   return make_bvbinop(p->tbl, BVTAG_SDIV, p->nbits, p->left, p->right);
935 }
936 
build_bvsrem_hobj(bvop_hobj_t * p)937 static thvar_t build_bvsrem_hobj(bvop_hobj_t *p) {
938   return make_bvbinop(p->tbl, BVTAG_SREM, p->nbits, p->left, p->right);
939 }
940 
build_bvsmod_hobj(bvop_hobj_t * p)941 static thvar_t build_bvsmod_hobj(bvop_hobj_t *p) {
942   return make_bvbinop(p->tbl, BVTAG_SMOD, p->nbits, p->left, p->right);
943 }
944 
build_bvshl_hobj(bvop_hobj_t * p)945 static thvar_t build_bvshl_hobj(bvop_hobj_t *p) {
946   return make_bvbinop(p->tbl, BVTAG_SHL, p->nbits, p->left, p->right);
947 }
948 
build_bvlshr_hobj(bvop_hobj_t * p)949 static thvar_t build_bvlshr_hobj(bvop_hobj_t *p) {
950   return make_bvbinop(p->tbl, BVTAG_LSHR, p->nbits, p->left, p->right);
951 }
952 
build_bvashr_hobj(bvop_hobj_t * p)953 static thvar_t build_bvashr_hobj(bvop_hobj_t *p) {
954   return make_bvbinop(p->tbl, BVTAG_ASHR, p->nbits, p->left, p->right);
955 }
956 
build_bvadd_hobj(bvop_hobj_t * p)957 static thvar_t build_bvadd_hobj(bvop_hobj_t *p) {
958   return make_bvbinop(p->tbl, BVTAG_ADD, p->nbits, p->left, p->right);
959 }
960 
build_bvsub_hobj(bvop_hobj_t * p)961 static thvar_t build_bvsub_hobj(bvop_hobj_t *p) {
962   return make_bvbinop(p->tbl, BVTAG_SUB, p->nbits, p->left, p->right);
963 }
964 
build_bvmul_hobj(bvop_hobj_t * p)965 static thvar_t build_bvmul_hobj(bvop_hobj_t *p) {
966   return make_bvbinop(p->tbl, BVTAG_MUL, p->nbits, p->left, p->right);
967 }
968 
build_bvneg_hobj(bvop_hobj_t * p)969 static thvar_t build_bvneg_hobj(bvop_hobj_t *p) {
970   return make_bvbinop(p->tbl, BVTAG_NEG, p->nbits, p->left, null_thvar);
971 }
972 
973 
974 /*
975  * Hash-consing constructors
976  */
get_bvconst64(bv_vartable_t * table,uint32_t n,uint64_t val)977 thvar_t get_bvconst64(bv_vartable_t *table, uint32_t n, uint64_t val) {
978   bvconst64_hobj_t bvconst64_hobj;
979 
980   bvconst64_hobj.m.hash = (hobj_hash_t) hash_bvconst64_hobj;
981   bvconst64_hobj.m.eq = (hobj_eq_t) eq_bvconst64_hobj;
982   bvconst64_hobj.m.build = (hobj_build_t) build_bvconst64_hobj;
983   bvconst64_hobj.tbl = table;
984   bvconst64_hobj.val = val;
985   bvconst64_hobj.nbits = n;
986   return int_htbl_get_obj(&table->htbl, &bvconst64_hobj.m);
987 }
988 
get_bvconst(bv_vartable_t * table,uint32_t n,uint32_t * val)989 thvar_t get_bvconst(bv_vartable_t *table, uint32_t n, uint32_t *val) {
990   bvconst_hobj_t bvconst_hobj;
991 
992   bvconst_hobj.m.hash = (hobj_hash_t) hash_bvconst_hobj;
993   bvconst_hobj.m.eq = (hobj_eq_t) eq_bvconst_hobj;
994   bvconst_hobj.m.build = (hobj_build_t) build_bvconst_hobj;
995   bvconst_hobj.tbl = table;
996   bvconst_hobj.val = val;
997   bvconst_hobj.nbits = n;
998   return int_htbl_get_obj(&table->htbl, &bvconst_hobj.m);
999 }
1000 
get_bvpoly64(bv_vartable_t * table,bvpoly_buffer_t * buffer)1001 thvar_t get_bvpoly64(bv_vartable_t *table, bvpoly_buffer_t *buffer) {
1002   bvpoly_hobj_t bvpoly64_hobj;
1003 
1004   bvpoly64_hobj.m.hash = (hobj_hash_t) hash_bvpoly64_hobj;
1005   bvpoly64_hobj.m.eq = (hobj_eq_t) eq_bvpoly64_hobj;
1006   bvpoly64_hobj.m.build = (hobj_build_t) build_bvpoly64_hobj;
1007   bvpoly64_hobj.tbl = table;
1008   bvpoly64_hobj.buffer = buffer;
1009   return int_htbl_get_obj(&table->htbl, &bvpoly64_hobj.m);
1010 }
1011 
get_bvpoly(bv_vartable_t * table,bvpoly_buffer_t * buffer)1012 thvar_t get_bvpoly(bv_vartable_t *table, bvpoly_buffer_t *buffer) {
1013   bvpoly_hobj_t bvpoly_hobj;
1014 
1015   bvpoly_hobj.m.hash = (hobj_hash_t) hash_bvpoly_hobj;
1016   bvpoly_hobj.m.eq = (hobj_eq_t) eq_bvpoly_hobj;
1017   bvpoly_hobj.m.build = (hobj_build_t) build_bvpoly_hobj;
1018   bvpoly_hobj.tbl = table;
1019   bvpoly_hobj.buffer = buffer;
1020   return int_htbl_get_obj(&table->htbl, &bvpoly_hobj.m);
1021 }
1022 
get_bvpprod(bv_vartable_t * table,uint32_t n,pp_buffer_t * buffer)1023 thvar_t get_bvpprod(bv_vartable_t *table, uint32_t n, pp_buffer_t *buffer) {
1024   bvpprod_hobj_t bvpprod_hobj;
1025 
1026   bvpprod_hobj.m.hash = (hobj_hash_t) hash_bvpprod_hobj;
1027   bvpprod_hobj.m.eq = (hobj_eq_t) eq_bvpprod_hobj;
1028   bvpprod_hobj.m.build = (hobj_build_t) build_bvpprod_hobj;
1029   bvpprod_hobj.tbl = table;
1030   bvpprod_hobj.buffer = buffer;
1031   bvpprod_hobj.nbits = n;
1032   return int_htbl_get_obj(&table->htbl, &bvpprod_hobj.m);
1033 }
1034 
get_bvarray(bv_vartable_t * table,uint32_t n,literal_t * a)1035 thvar_t get_bvarray(bv_vartable_t *table, uint32_t n, literal_t *a) {
1036   bvarray_hobj_t bvarray_hobj;
1037 
1038   bvarray_hobj.m.hash = (hobj_hash_t) hash_bvarray_hobj;
1039   bvarray_hobj.m.eq = (hobj_eq_t) eq_bvarray_hobj;
1040   bvarray_hobj.m.build = (hobj_build_t) build_bvarray_hobj;
1041   bvarray_hobj.tbl = table;
1042   bvarray_hobj.val = a;
1043   bvarray_hobj.nbits = n;
1044   return int_htbl_get_obj(&table->htbl, &bvarray_hobj.m);
1045 }
1046 
get_bvite(bv_vartable_t * table,uint32_t n,literal_t l,thvar_t x,thvar_t y)1047 thvar_t get_bvite(bv_vartable_t *table, uint32_t n, literal_t l, thvar_t x, thvar_t y) {
1048   bvite_hobj_t bvite_hobj;
1049 
1050   bvite_hobj.m.hash = (hobj_hash_t) hash_bvite_hobj;
1051   bvite_hobj.m.eq = (hobj_eq_t) eq_bvite_hobj;
1052   bvite_hobj.m.build = (hobj_build_t) build_bvite_hobj;
1053   bvite_hobj.tbl = table;
1054   bvite_hobj.cond = l;
1055   bvite_hobj.left = x;
1056   bvite_hobj.right = y;
1057   bvite_hobj.nbits = n;
1058   return int_htbl_get_obj(&table->htbl, &bvite_hobj.m);
1059 }
1060 
get_bvdiv(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y)1061 thvar_t get_bvdiv(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y) {
1062   bvop_hobj_t bvdiv_hobj;
1063 
1064   bvdiv_hobj.m.hash = (hobj_hash_t) hash_bvdiv_hobj;
1065   bvdiv_hobj.m.eq = (hobj_eq_t) eq_bvdiv_hobj;
1066   bvdiv_hobj.m.build = (hobj_build_t) build_bvdiv_hobj;
1067   bvdiv_hobj.tbl = table;
1068   bvdiv_hobj.left = x;
1069   bvdiv_hobj.right = y;
1070   bvdiv_hobj.nbits = n;
1071   return int_htbl_get_obj(&table->htbl, &bvdiv_hobj.m);
1072 }
1073 
get_bvrem(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y)1074 thvar_t get_bvrem(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y) {
1075   bvop_hobj_t bvrem_hobj;
1076 
1077   bvrem_hobj.m.hash = (hobj_hash_t) hash_bvrem_hobj;
1078   bvrem_hobj.m.eq = (hobj_eq_t) eq_bvrem_hobj;
1079   bvrem_hobj.m.build = (hobj_build_t) build_bvrem_hobj;
1080   bvrem_hobj.tbl = table;
1081   bvrem_hobj.left = x;
1082   bvrem_hobj.right = y;
1083   bvrem_hobj.nbits = n;
1084   return int_htbl_get_obj(&table->htbl, &bvrem_hobj.m);
1085 }
1086 
get_bvsdiv(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y)1087 thvar_t get_bvsdiv(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y) {
1088   bvop_hobj_t bvsdiv_hobj;
1089 
1090   bvsdiv_hobj.m.hash = (hobj_hash_t) hash_bvsdiv_hobj;
1091   bvsdiv_hobj.m.eq = (hobj_eq_t) eq_bvsdiv_hobj;
1092   bvsdiv_hobj.m.build = (hobj_build_t) build_bvsdiv_hobj;
1093   bvsdiv_hobj.tbl = table;
1094   bvsdiv_hobj.left = x;
1095   bvsdiv_hobj.right = y;
1096   bvsdiv_hobj.nbits = n;
1097   return int_htbl_get_obj(&table->htbl, &bvsdiv_hobj.m);
1098 }
1099 
get_bvsrem(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y)1100 thvar_t get_bvsrem(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y) {
1101   bvop_hobj_t bvsrem_hobj;
1102 
1103   bvsrem_hobj.m.hash = (hobj_hash_t) hash_bvsrem_hobj;
1104   bvsrem_hobj.m.eq = (hobj_eq_t) eq_bvsrem_hobj;
1105   bvsrem_hobj.m.build = (hobj_build_t) build_bvsrem_hobj;
1106   bvsrem_hobj.tbl = table;
1107   bvsrem_hobj.left = x;
1108   bvsrem_hobj.right = y;
1109   bvsrem_hobj.nbits = n;
1110   return int_htbl_get_obj(&table->htbl, &bvsrem_hobj.m);
1111 }
1112 
get_bvsmod(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y)1113 thvar_t get_bvsmod(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y) {
1114   bvop_hobj_t bvsmod_hobj;
1115 
1116   bvsmod_hobj.m.hash = (hobj_hash_t) hash_bvsmod_hobj;
1117   bvsmod_hobj.m.eq = (hobj_eq_t) eq_bvsmod_hobj;
1118   bvsmod_hobj.m.build = (hobj_build_t) build_bvsmod_hobj;
1119   bvsmod_hobj.tbl = table;
1120   bvsmod_hobj.left = x;
1121   bvsmod_hobj.right = y;
1122   bvsmod_hobj.nbits = n;
1123   return int_htbl_get_obj(&table->htbl, &bvsmod_hobj.m);
1124 }
1125 
get_bvshl(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y)1126 thvar_t get_bvshl(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y) {
1127   bvop_hobj_t bvshl_hobj;
1128 
1129   bvshl_hobj.m.hash = (hobj_hash_t) hash_bvshl_hobj;
1130   bvshl_hobj.m.eq = (hobj_eq_t) eq_bvshl_hobj;
1131   bvshl_hobj.m.build = (hobj_build_t) build_bvshl_hobj;
1132   bvshl_hobj.tbl = table;
1133   bvshl_hobj.left = x;
1134   bvshl_hobj.right = y;
1135   bvshl_hobj.nbits = n;
1136   return int_htbl_get_obj(&table->htbl, &bvshl_hobj.m);
1137 }
1138 
get_bvlshr(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y)1139 thvar_t get_bvlshr(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y) {
1140   bvop_hobj_t bvlshr_hobj;
1141 
1142   bvlshr_hobj.m.hash = (hobj_hash_t) hash_bvlshr_hobj;
1143   bvlshr_hobj.m.eq = (hobj_eq_t) eq_bvlshr_hobj;
1144   bvlshr_hobj.m.build = (hobj_build_t) build_bvlshr_hobj;
1145   bvlshr_hobj.tbl = table;
1146   bvlshr_hobj.left = x;
1147   bvlshr_hobj.right = y;
1148   bvlshr_hobj.nbits = n;
1149   return int_htbl_get_obj(&table->htbl, &bvlshr_hobj.m);
1150 }
1151 
get_bvashr(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y)1152 thvar_t get_bvashr(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y) {
1153   bvop_hobj_t bvashr_hobj;
1154 
1155   bvashr_hobj.m.hash = (hobj_hash_t) hash_bvashr_hobj;
1156   bvashr_hobj.m.eq = (hobj_eq_t) eq_bvashr_hobj;
1157   bvashr_hobj.m.build = (hobj_build_t) build_bvashr_hobj;
1158   bvashr_hobj.tbl = table;
1159   bvashr_hobj.left = x;
1160   bvashr_hobj.right = y;
1161   bvashr_hobj.nbits = n;
1162   return int_htbl_get_obj(&table->htbl, &bvashr_hobj.m);
1163 }
1164 
1165 
get_bvadd(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y,bool * new_var)1166 thvar_t get_bvadd(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y, bool *new_var) {
1167   uint32_t nvars;
1168   thvar_t i;
1169   bvop_hobj_t bvadd_hobj;
1170 
1171   bvadd_hobj.m.hash = (hobj_hash_t) hash_bvadd_hobj;
1172   bvadd_hobj.m.eq = (hobj_eq_t) eq_bvadd_hobj;
1173   bvadd_hobj.m.build = (hobj_build_t) build_bvadd_hobj;
1174   bvadd_hobj.tbl = table;
1175   bvadd_hobj.left = x;
1176   bvadd_hobj.right = y;
1177   bvadd_hobj.nbits = n;
1178 
1179   nvars = table->nvars;
1180   i = int_htbl_get_obj(&table->htbl, &bvadd_hobj.m);
1181   *new_var = table->nvars > nvars;
1182 
1183   return i;
1184 }
1185 
get_bvsub(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y,bool * new_var)1186 thvar_t get_bvsub(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y, bool *new_var) {
1187   uint32_t nvars;
1188   thvar_t i;
1189   bvop_hobj_t bvsub_hobj;
1190 
1191   bvsub_hobj.m.hash = (hobj_hash_t) hash_bvsub_hobj;
1192   bvsub_hobj.m.eq = (hobj_eq_t) eq_bvsub_hobj;
1193   bvsub_hobj.m.build = (hobj_build_t) build_bvsub_hobj;
1194   bvsub_hobj.tbl = table;
1195   bvsub_hobj.left = x;
1196   bvsub_hobj.right = y;
1197   bvsub_hobj.nbits = n;
1198 
1199   nvars = table->nvars;
1200   i = int_htbl_get_obj(&table->htbl, &bvsub_hobj.m);
1201   *new_var = table->nvars > nvars;
1202 
1203   return i;
1204 }
1205 
get_bvmul(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y,bool * new_var)1206 thvar_t get_bvmul(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y, bool *new_var) {
1207   uint32_t nvars;
1208   thvar_t i;
1209   bvop_hobj_t bvmul_hobj;
1210 
1211   bvmul_hobj.m.hash = (hobj_hash_t) hash_bvmul_hobj;
1212   bvmul_hobj.m.eq = (hobj_eq_t) eq_bvmul_hobj;
1213   bvmul_hobj.m.build = (hobj_build_t) build_bvmul_hobj;
1214   bvmul_hobj.tbl = table;
1215   bvmul_hobj.left = x;
1216   bvmul_hobj.right = y;
1217   bvmul_hobj.nbits = n;
1218 
1219   nvars = table->nvars;
1220   i = int_htbl_get_obj(&table->htbl, &bvmul_hobj.m);
1221   *new_var = table->nvars > nvars;
1222 
1223   return i;
1224 }
1225 
get_bvneg(bv_vartable_t * table,uint32_t n,thvar_t x,bool * new_var)1226 thvar_t get_bvneg(bv_vartable_t *table, uint32_t n, thvar_t x, bool *new_var) {
1227   uint32_t nvars;
1228   thvar_t i;
1229   bvop_hobj_t bvneg_hobj;
1230 
1231   bvneg_hobj.m.hash = (hobj_hash_t) hash_bvneg_hobj;
1232   bvneg_hobj.m.eq = (hobj_eq_t) eq_bvneg_hobj;
1233   bvneg_hobj.m.build = (hobj_build_t) build_bvneg_hobj;
1234   bvneg_hobj.tbl = table;
1235   bvneg_hobj.left = x;
1236   bvneg_hobj.right = null_thvar;
1237   bvneg_hobj.nbits = n;
1238 
1239   nvars = table->nvars;
1240   i = int_htbl_get_obj(&table->htbl, &bvneg_hobj.m);
1241   *new_var = table->nvars > nvars;
1242 
1243   return i;
1244 }
1245 
1246 
1247 
1248 
1249 /*
1250  * Search for (div x y), (rem x y), etc.
1251  * - return -1 if the term is not in the table
1252  */
find_div(bv_vartable_t * table,thvar_t x,thvar_t y)1253 thvar_t find_div(bv_vartable_t *table, thvar_t x, thvar_t y) {
1254   uint32_t n;
1255   bvop_hobj_t bvdiv_hobj;
1256 
1257   assert(valid_bvvar(table, x) && valid_bvvar(table, y) &&
1258          table->bit_size[x] == table->bit_size[y]);
1259 
1260   n = table->bit_size[x];
1261 
1262 
1263   bvdiv_hobj.m.hash = (hobj_hash_t) hash_bvdiv_hobj;
1264   bvdiv_hobj.m.eq = (hobj_eq_t) eq_bvdiv_hobj;
1265   bvdiv_hobj.m.build = (hobj_build_t) build_bvdiv_hobj;
1266   bvdiv_hobj.tbl = table;
1267   bvdiv_hobj.left = x;
1268   bvdiv_hobj.right = y;
1269   bvdiv_hobj.nbits = n;
1270 
1271   return int_htbl_find_obj(&table->htbl, &bvdiv_hobj.m);
1272 }
1273 
find_rem(bv_vartable_t * table,thvar_t x,thvar_t y)1274 thvar_t find_rem(bv_vartable_t *table, thvar_t x, thvar_t y) {
1275   uint32_t n;
1276   bvop_hobj_t bvrem_hobj;
1277 
1278   assert(valid_bvvar(table, x) && valid_bvvar(table, y) &&
1279          table->bit_size[x] == table->bit_size[y]);
1280 
1281   n = table->bit_size[x];
1282 
1283   bvrem_hobj.m.hash = (hobj_hash_t) hash_bvrem_hobj;
1284   bvrem_hobj.m.eq = (hobj_eq_t) eq_bvrem_hobj;
1285   bvrem_hobj.m.build = (hobj_build_t) build_bvrem_hobj;
1286   bvrem_hobj.tbl = table;
1287   bvrem_hobj.left = x;
1288   bvrem_hobj.right = y;
1289   bvrem_hobj.nbits = n;
1290 
1291   return int_htbl_find_obj(&table->htbl, &bvrem_hobj.m);
1292 }
1293 
find_sdiv(bv_vartable_t * table,thvar_t x,thvar_t y)1294 thvar_t find_sdiv(bv_vartable_t *table, thvar_t x, thvar_t y) {
1295   uint32_t n;
1296   bvop_hobj_t bvsdiv_hobj;
1297 
1298   assert(valid_bvvar(table, x) && valid_bvvar(table, y) &&
1299          table->bit_size[x] == table->bit_size[y]);
1300 
1301   n = table->bit_size[x];
1302 
1303   bvsdiv_hobj.m.hash = (hobj_hash_t) hash_bvsdiv_hobj;
1304   bvsdiv_hobj.m.eq = (hobj_eq_t) eq_bvsdiv_hobj;
1305   bvsdiv_hobj.m.build = (hobj_build_t) build_bvsdiv_hobj;
1306   bvsdiv_hobj.tbl = table;
1307   bvsdiv_hobj.left = x;
1308   bvsdiv_hobj.right = y;
1309   bvsdiv_hobj.nbits = n;
1310 
1311   return int_htbl_find_obj(&table->htbl, &bvsdiv_hobj.m);
1312 }
1313 
find_srem(bv_vartable_t * table,thvar_t x,thvar_t y)1314 thvar_t find_srem(bv_vartable_t *table, thvar_t x, thvar_t y) {
1315   uint32_t n;
1316   bvop_hobj_t bvsrem_hobj;
1317 
1318   assert(valid_bvvar(table, x) && valid_bvvar(table, y) &&
1319          table->bit_size[x] == table->bit_size[y]);
1320 
1321   n = table->bit_size[x];
1322 
1323   bvsrem_hobj.m.hash = (hobj_hash_t) hash_bvsrem_hobj;
1324   bvsrem_hobj.m.eq = (hobj_eq_t) eq_bvsrem_hobj;
1325   bvsrem_hobj.m.build = (hobj_build_t) build_bvsrem_hobj;
1326   bvsrem_hobj.tbl = table;
1327   bvsrem_hobj.left = x;
1328   bvsrem_hobj.right = y;
1329   bvsrem_hobj.nbits = n;
1330 
1331   return int_htbl_find_obj(&table->htbl, &bvsrem_hobj.m);
1332 }
1333 
1334 
find_bvadd(bv_vartable_t * table,thvar_t x,thvar_t y)1335 thvar_t find_bvadd(bv_vartable_t *table, thvar_t x, thvar_t y) {
1336   uint32_t n;
1337   bvop_hobj_t bvadd_hobj;
1338 
1339   assert(valid_bvvar(table, x) && valid_bvvar(table, y) &&
1340          table->bit_size[x] == table->bit_size[y]);
1341 
1342   n = table->bit_size[x];
1343 
1344   bvadd_hobj.m.hash = (hobj_hash_t) hash_bvadd_hobj;
1345   bvadd_hobj.m.eq = (hobj_eq_t) eq_bvadd_hobj;
1346   bvadd_hobj.m.build = (hobj_build_t) build_bvadd_hobj;
1347   bvadd_hobj.tbl = table;
1348   bvadd_hobj.left = x;
1349   bvadd_hobj.right = y;
1350   bvadd_hobj.nbits = n;
1351   return int_htbl_find_obj(&table->htbl, &bvadd_hobj.m);
1352 }
1353 
find_bvsub(bv_vartable_t * table,thvar_t x,thvar_t y)1354 thvar_t find_bvsub(bv_vartable_t *table, thvar_t x, thvar_t y) {
1355   uint32_t n;
1356   bvop_hobj_t bvsub_hobj;
1357 
1358   assert(valid_bvvar(table, x) && valid_bvvar(table, y) &&
1359          table->bit_size[x] == table->bit_size[y]);
1360 
1361   n = table->bit_size[x];
1362 
1363   bvsub_hobj.m.hash = (hobj_hash_t) hash_bvsub_hobj;
1364   bvsub_hobj.m.eq = (hobj_eq_t) eq_bvsub_hobj;
1365   bvsub_hobj.m.build = (hobj_build_t) build_bvsub_hobj;
1366   bvsub_hobj.tbl = table;
1367   bvsub_hobj.left = x;
1368   bvsub_hobj.right = y;
1369   bvsub_hobj.nbits = n;
1370   return int_htbl_find_obj(&table->htbl, &bvsub_hobj.m);
1371 }
1372 
find_bvmul(bv_vartable_t * table,thvar_t x,thvar_t y)1373 thvar_t find_bvmul(bv_vartable_t *table, thvar_t x, thvar_t y) {
1374   uint32_t n;
1375   bvop_hobj_t bvmul_hobj;
1376 
1377   assert(valid_bvvar(table, x) && valid_bvvar(table, y) &&
1378          table->bit_size[x] == table->bit_size[y]);
1379 
1380   n = table->bit_size[x];
1381 
1382   bvmul_hobj.m.hash = (hobj_hash_t) hash_bvmul_hobj;
1383   bvmul_hobj.m.eq = (hobj_eq_t) eq_bvmul_hobj;
1384   bvmul_hobj.m.build = (hobj_build_t) build_bvmul_hobj;
1385   bvmul_hobj.tbl = table;
1386   bvmul_hobj.left = x;
1387   bvmul_hobj.right = y;
1388   bvmul_hobj.nbits = n;
1389   return int_htbl_find_obj(&table->htbl, &bvmul_hobj.m);
1390 }
1391 
find_bvneg(bv_vartable_t * table,thvar_t x)1392 thvar_t find_bvneg(bv_vartable_t *table, thvar_t x) {
1393   uint32_t n;
1394   bvop_hobj_t bvneg_hobj;
1395 
1396   assert(valid_bvvar(table, x));
1397 
1398   n = table->bit_size[x];
1399 
1400   bvneg_hobj.m.hash = (hobj_hash_t) hash_bvneg_hobj;
1401   bvneg_hobj.m.eq = (hobj_eq_t) eq_bvneg_hobj;
1402   bvneg_hobj.m.build = (hobj_build_t) build_bvneg_hobj;
1403   bvneg_hobj.tbl = table;
1404   bvneg_hobj.left = x;
1405   bvneg_hobj.right = null_thvar;
1406   bvneg_hobj.nbits = n;
1407   return int_htbl_find_obj(&table->htbl, &bvneg_hobj.m);
1408 }
1409