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  * INTERNAL TERM REPRESENTATION AND HASH CONSING
21  */
22 
23 /*
24  * The internal terms include:
25  * 1) constants:
26  *    - constants of uninterpreted/scalar
27  *    - global uninterpreted constants
28  * 2) generic terms
29  *    - ite c t1 t2
30  *    - eq t1 t2
31  *    - apply f t1 ... t_n
32  *    - mk-tuple t1 ... t_n
33  *    - select i tuple
34  *    - update f t1 ... t_n v
35  *    - distinct t1 ... t_n
36  * 3) variables and quantifiers
37  *    - variables are identified by their type and an integer index.
38  *    - quantified formulas are of the form (forall v_1 ... v_n term)
39  *      where each v_i is a variable
40  *    - lambda terms: same thing
41  * 4) boolean operators
42  *    - or t1 ... t_n
43  *    - xor t1 ... t_n
44  *    - bit i u (extract bit i of a bitvector term u)
45  * 6) arithmetic terms and atoms
46  *    - terms are either rational constants, power products, or
47  *      polynomials with rational coefficients
48  *    - atoms are either of the form (t == 0) or (t >= 0)
49  *      where t is a term.
50  *    - atoms a x - a y == 0 are rewritten to (x = y)
51  * 7) bitvector terms and atoms
52  *    - bitvector constants
53  *    - power products
54  *    - polynomials
55  *    - bit arrays
56  *    - other operations: divisions/shift
57  *    - atoms: three binary predicates
58  *      bv_eq t1 t2
59  *      bv_ge t1 t2 (unsigned comparison: t1 >= t2)
60  *      bv_sge t1 t2 (signed comparison: t1 >= t2)
61  *
62  * 8) more arithmetic operators (defined in SMTLIB2)
63  *    - floor x
64  *    - ceil x
65  *    - abs x
66  *    - div x y
67  *    - mod x y
68  *    - divides x y: y is a multiple of y
69  *    - is_int x: true if x is an integer
70  *    - rdiv x y: (/ x y)
71  *
72  * Every term is an index t in a global term table,
73  * where 0 <= t <= 2^30. The two term occurrences
74  * t+ and t- are encoded on 32bits (signed integer) with
75  * - bit[31] = sign bit = 0
76  * - bits[30 ... 1] = t
77  * - bit[0] = polarity bit: 0 means t+, 1 means t-
78  *
79  * For a boolean term t, the occurrence t+ means p
80  * and t- means (not p). All occurrences of a
81  * non-boolean term t are positive.
82  *
83  * For every term, we keep:
84  * - type[t] (index in the type table)
85  * - kind[t] (what kind of term it is)
86  * - desc[t] = descriptor that depends on the kind
87  *
88  * It is possible to attach names to term occurrences (but not directly
89  * to terms). This is required to deal properly with booleans. For example,
90  * we want to allow the user to give different names to t and (not t).
91  */
92 
93 #include "terms/bv64_constants.h"
94 #include "terms/terms.h"
95 #include "utils/hash_functions.h"
96 #include "utils/memalloc.h"
97 #include "utils/refcount_strings.h"
98 
99 
100 /*
101  * Finalizer for term names in the symbol table.
102  * All symbols must be generated by the clone function, and have
103  * a reference counter (cf. refcount_strings.h).
104  */
term_name_finalizer(stbl_rec_t * r)105 static void term_name_finalizer(stbl_rec_t *r) {
106   string_decref(r->string);
107 }
108 
109 
110 /*
111  * Default finalizer for special terms
112  */
default_special_finalizer(special_term_t * s,term_kind_t tag)113 static void default_special_finalizer(special_term_t *s, term_kind_t tag) {
114   safe_free(s->extra);
115 }
116 
117 
118 /*
119  * Initialize table, with initial size n.
120  * - ttbl = attached type table.
121  * - ptbl = attached power-product table.
122  */
term_table_init(term_table_t * table,uint32_t n,type_table_t * ttbl,pprod_table_t * ptbl)123 static void term_table_init(term_table_t *table, uint32_t n, type_table_t *ttbl, pprod_table_t *ptbl) {
124   // abort if n is too large
125   if (n > YICES_MAX_TERMS) {
126     out_of_memory();
127   }
128 
129   table->kind = (unsigned char *) safe_malloc(n * sizeof(unsigned char));
130   table->type = (type_t *) safe_malloc(n * sizeof(type_t));
131   table->desc = (term_desc_t *) safe_malloc(n * sizeof(term_desc_t));
132   table->mark = allocate_bitvector(n);
133 
134   table->size = n;
135   table->nelems = 0;
136   table->free_idx = -1; // empty free list
137   table->live_terms = 0;
138 
139   table->types = ttbl;
140   table->pprods = ptbl;
141   table->finalize = default_special_finalizer;
142 
143   // initialize tables with default initial size
144   init_int_htbl(&table->htbl, 0);
145   init_stbl(&table->stbl, 0);
146   init_ptr_hmap(&table->ntbl, 0);
147   init_int_hmap(&table->utbl, 0);
148 
149   // attach the name finalizer to stbl
150   stbl_set_finalizer(&table->stbl, term_name_finalizer);
151 
152   // buffers
153   init_ivector(&table->ibuffer, 20);
154   init_pvector(&table->pbuffer, 20);
155 
156 }
157 
158 
159 /*
160  * Extend the table: make it 50% larger
161  */
term_table_extend(term_table_t * table)162 static void term_table_extend(term_table_t *table) {
163   uint32_t n;
164 
165   n = table->size + 1;
166   n += n >> 1;
167 
168   // force abort if n is too large
169   if (n > YICES_MAX_TERMS) {
170     out_of_memory();
171   }
172 
173   table->kind = (unsigned char *) safe_realloc(table->kind, n * sizeof(unsigned char));
174   table->type = (type_t *) safe_realloc(table->type, n * sizeof(type_t));
175   table->desc = (term_desc_t *) safe_realloc(table->desc, n * sizeof(term_desc_t));
176   table->mark = extend_bitvector(table->mark, n);
177   table->size = n;
178 }
179 
180 
181 
182 /*
183  * TERM ALLOCATION
184  */
185 
186 /*
187  * Allocate a new term id
188  * - clear its mark. Nothing else is initialized.
189  */
allocate_term_id(term_table_t * table)190 static int32_t allocate_term_id(term_table_t *table) {
191   int32_t i;
192 
193   i = table->free_idx;
194   if (i >= 0) {
195     table->free_idx = table->desc[i].integer;
196   } else {
197     i = table->nelems;
198     table->nelems ++;
199     if (i == table->size) {
200       term_table_extend(table);
201     }
202     assert(i < table->size);
203   }
204   clr_bit(table->mark, i);
205   table->live_terms ++;
206 
207   return i;
208 }
209 
210 
211 
212 /*
213  * Terms with integer descriptor
214  * - tag = kind
215  * - tau = type
216  * - id = index
217  */
new_integer_term(term_table_t * table,term_kind_t tag,type_t tau,int32_t id)218 static int32_t new_integer_term(term_table_t *table, term_kind_t tag, type_t tau, int32_t id) {
219   int32_t i;
220 
221   i = allocate_term_id(table);
222   table->kind[i] = tag;
223   table->type[i] = tau;
224   table->desc[i].integer = id;
225 
226   return i;
227 }
228 
229 
230 /*
231  * Terms with pointer descriptor
232  * - tag = kind
233  * - tau = type
234  * - d = descriptor
235  */
new_ptr_term(term_table_t * table,term_kind_t tag,type_t tau,void * d)236 static int32_t new_ptr_term(term_table_t *table, term_kind_t tag, type_t tau, void *d) {
237   int32_t i;
238 
239   i = allocate_term_id(table);
240   table->kind[i] = tag;
241   table->type[i] = tau;
242   table->desc[i].ptr = d;
243 
244   return i;
245 }
246 
247 
248 /*
249  * Rational descriptors
250  * - tag = kind
251  * - tau = type
252  * - a = value
253  */
new_rational_term(term_table_t * table,term_kind_t tag,type_t tau,rational_t * a)254 static int32_t new_rational_term(term_table_t *table, term_kind_t tag, type_t tau, rational_t *a) {
255   int32_t i;
256 
257   i = allocate_term_id(table);
258   table->kind[i] = tag;
259   table->type[i] = tau;
260   q_init(&table->desc[i].rational);
261   q_set(&table->desc[i].rational, a);
262 
263   return i;
264 }
265 
266 
267 /*
268  * Select k t: for tuple projection or bitvector selection.
269  * - tag = kind
270  * - tau = type
271  * - k = select index
272  * - t = select argument
273  */
new_select_term(term_table_t * table,term_kind_t tag,type_t tau,uint32_t k,term_t t)274 static int32_t new_select_term(term_table_t *table, term_kind_t tag, type_t tau, uint32_t k, term_t t) {
275   int32_t i;
276 
277   i = allocate_term_id(table);
278   table->kind[i] = tag;
279   table->type[i] = tau;
280   table->desc[i].select.idx = k;
281   table->desc[i].select.arg = t;
282 
283   return i;
284 }
285 
286 
287 /*
288  * Root object:
289  * - k = root index
290  * - x = variable
291  * - p = polynomial in x
292  * - r = relation
293  */
new_root_atom(term_table_t * table,uint32_t k,term_t x,term_t p,root_atom_rel_t r)294 static root_atom_t* new_root_atom(term_table_t *table, uint32_t k, term_t x, term_t p, root_atom_rel_t r) {
295   root_atom_t *atom;
296 
297   atom = (root_atom_t *) safe_malloc(sizeof(root_atom_t));
298   atom->k = k;
299   atom->x = x;
300   atom->p = p;
301   atom->r = r;
302 
303   return atom;
304 }
305 
306 
307 
308 
309 /*
310  * TERM DESCRIPTORS
311  */
312 
313 /*
314  * Limit on n when allocating a composite term descriptor of arity n.
315  * If n <= MAX_COMPOSITE_TERM_ARITY then we can compute the descriptor
316  * size without overflow (on 32bit).
317  */
318 #define MAX_COMPOSITE_TERM_ARITY ((UINT32_MAX-sizeof(composite_term_t))/sizeof(term_t))
319 
320 
321 /*
322  * Generic n-ary term:
323  * - n = arity
324  * - a[0 ... n-1] = components
325  */
new_composite_term(uint32_t n,const term_t * a)326 static composite_term_t *new_composite_term(uint32_t n, const term_t *a) {
327   composite_term_t *d;
328   uint32_t j;
329 
330   assert(n <= MAX_COMPOSITE_TERM_ARITY);
331 
332   d = (composite_term_t *) safe_malloc(sizeof(composite_term_t) + n * sizeof(term_t));
333   d->arity = n;
334   for (j=0; j<n; j++) {
335     d->arg[j] = a[j];
336   }
337 
338   return d;
339 }
340 
341 
342 /*
343  * Function application
344  * - f = function (as a term)
345  * - n = arity
346  * - a[0 ... n-1] = arguments to f
347  */
new_app_term(term_t f,uint32_t n,const term_t * a)348 static composite_term_t *new_app_term(term_t f, uint32_t n, const term_t *a) {
349   composite_term_t *d;
350   uint32_t j;
351 
352   assert(n <= MAX_COMPOSITE_TERM_ARITY - 1);
353 
354   d = (composite_term_t *) safe_malloc(sizeof(composite_term_t) + (n+1) * sizeof(term_t));
355   d->arity = n+1;
356   d->arg[0] = f;
357   for (j=0; j<n; j++) {
358     d->arg[j + 1] = a[j];
359   }
360 
361   return d;
362 }
363 
364 
365 /*
366  * Function update: (update f a[0] ... a[n-1] v)
367  */
new_update_term(term_t f,uint32_t n,const term_t * a,term_t v)368 static composite_term_t *new_update_term(term_t f, uint32_t n, const term_t *a, term_t v) {
369   composite_term_t *d;
370   uint32_t j;
371 
372   assert(n <= MAX_COMPOSITE_TERM_ARITY - 2);
373 
374   d = (composite_term_t *) safe_malloc(sizeof(composite_term_t) + (n+2) * sizeof(term_t));
375   d->arity = n+2;
376   d->arg[0] = f;
377   for (j=0; j<n; j++) {
378     d->arg[j + 1] = a[j];
379   }
380   d->arg[j + 1] = v;
381 
382   return d;
383 }
384 
385 
386 /*
387  * Quantified term: (forall v[0] ... v[n-1] p)
388  */
new_forall_term(uint32_t n,const term_t * v,term_t p)389 static composite_term_t *new_forall_term(uint32_t n, const term_t *v, term_t p) {
390   composite_term_t *d;
391   uint32_t j;
392 
393   assert(n <= MAX_COMPOSITE_TERM_ARITY - 1);
394 
395   d = (composite_term_t *) safe_malloc(sizeof(composite_term_t) + (n+1) * sizeof(term_t));
396   d->arity = n+1;
397   for (j=0; j<n; j++) {
398     d->arg[j] = v[j];
399   }
400   d->arg[j] = p;
401 
402   return d;
403 }
404 
405 
406 /*
407  * Lambda term: (lambda v[0] ... v[n-1] t)
408  */
new_lambda_term(uint32_t n,const term_t * v,term_t t)409 static composite_term_t *new_lambda_term(uint32_t n, const term_t *v, term_t t) {
410   composite_term_t *d;
411   uint32_t j;
412 
413   assert(n <= MAX_COMPOSITE_TERM_ARITY - 1);
414 
415   d = (composite_term_t *) safe_malloc(sizeof(composite_term_t) + (n+1) * sizeof(term_t));
416   d->arity = n+1;
417   for (j=0; j<n; j++) {
418     d->arg[j] = v[j];
419   }
420   d->arg[j] = t;
421 
422   return d;
423 }
424 
425 
426 /*
427  * Bit-vector constant:
428  * - v = array of k words where k = ceil(bitsize/32).
429  */
new_bvconst_term(uint32_t bitsize,const uint32_t * v)430 static bvconst_term_t *new_bvconst_term(uint32_t bitsize, const uint32_t *v) {
431   bvconst_term_t *d;
432   uint32_t k;
433 
434   assert(bitsize > 64);
435 
436   k = (bitsize + 31) >> 5;
437   d = (bvconst_term_t *) safe_malloc(sizeof(bvconst_term_t) + k * sizeof(uint32_t));
438   d->bitsize = bitsize;
439   bvconst_set(d->data, k, v);
440 
441   return d;
442 }
443 
444 
445 /*
446  * Small bitvector constant
447  */
new_bvconst64_term(uint32_t bitsize,uint64_t v)448 static bvconst64_term_t *new_bvconst64_term(uint32_t bitsize, uint64_t v) {
449   bvconst64_term_t *d;
450 
451   assert(1 <= bitsize && bitsize <= 64 && v == norm64(v, bitsize));
452 
453   d = (bvconst64_term_t *) safe_malloc(sizeof(bvconst64_term_t));
454   d->bitsize = bitsize;
455   d->value = v;
456 
457   return d;
458 }
459 
460 
461 
462 /*
463  * Special term:
464  * - allocate a special_term_descriptor
465  * - set the extra field to NULL
466  * - fill in the rest as a composite of arity n
467  * - a[0 ... n-1] = components
468  */
new_special_term(uint32_t n,const term_t * a)469 static composite_term_t *new_special_term(uint32_t n, const term_t *a) {
470   special_term_t *d;
471   uint32_t j;
472 
473   assert(n <= MAX_COMPOSITE_TERM_ARITY);
474   d = (special_term_t *) safe_malloc(sizeof(special_term_t) + n * sizeof(term_t));
475   d->extra = NULL;
476   d->body.arity = n;
477   for (j=0; j<n; j++) {
478     d->body.arg[j] = a[j];
479   }
480 
481   return &d->body;
482 }
483 
484 
485 
486 /*
487  * HASH CODES
488  */
489 
490 /*
491  * Hash functions for polynomials, bv_polynomials, and bv64_polynomials are
492  * defined in polynomials.c, bv_polynomials.c, and bv64_polynomials.c.
493  * The following functions deal with the other term descriptors.
494  */
495 
496 /*
497  * Indexed term defined by (tag, tau, id)
498  */
hash_integer_term(term_kind_t tag,type_t tau,int32_t id)499 static inline uint32_t hash_integer_term(term_kind_t tag, type_t tau, int32_t id) {
500   return jenkins_hash_triple(tag, tau, id, 0x2839adee);
501 }
502 
503 /*
504  * Rational term defined by (tag, tau, value)
505  */
hash_rational_term(term_kind_t tag,type_t tau,rational_t * a)506 static uint32_t hash_rational_term(term_kind_t tag, type_t tau, rational_t *a) {
507   uint32_t num, den;
508 
509   q_hash_decompose(a, &num, &den);
510   return jenkins_hash_quad(tag, tau, num, den, 0xf9e34ab9);
511 }
512 
513 /*
514  * Generic composite term: (tag, arity, arg[0] ... arg[n-1])
515  */
hash_composite_term(term_kind_t tag,uint32_t n,const term_t * a)516 static uint32_t hash_composite_term(term_kind_t tag, uint32_t n, const term_t *a) {
517   return jenkins_hash_array((uint32_t *) a, n, (uint32_t) (0x8ede2341 + tag));
518 }
519 
520 
521 /*
522  * Function application: (f, n, a[0] ... a[n-1])
523  */
hash_app_term(term_t f,uint32_t n,const term_t * a)524 static uint32_t hash_app_term(term_t f, uint32_t n, const term_t *a) {
525   uint32_t h;
526 
527   h = jenkins_hash_intarray(a, n);
528   return jenkins_hash_pair(f, h, 0x2a3efb23);
529 }
530 
531 
532 /*
533  * Function update: (update f a[0] ... a[n-1] v)
534  */
hash_update_term(term_t f,uint32_t n,const term_t * a,term_t v)535 static uint32_t hash_update_term(term_t f, uint32_t n, const term_t *a, term_t v) {
536   uint32_t h;
537 
538   h = jenkins_hash_intarray(a, n);
539   return jenkins_hash_triple(f, v, h, 0x18abe185);
540 }
541 
542 
543 /*
544  * Quantified term: (forall v[0] ... v[n-1] p)
545  */
hash_forall_term(uint32_t n,const term_t * v,term_t p)546 static uint32_t hash_forall_term(uint32_t n, const term_t *v, term_t p) {
547   uint32_t h;
548 
549   h = jenkins_hash_intarray(v, n);
550   return jenkins_hash_pair(p, h, 0xfe3a2788);
551 }
552 
553 
554 /*
555  * Lambda term: (lambda v[0] ... v[n-1] t)
556  */
hash_lambda_term(uint32_t n,const term_t * v,term_t t)557 static uint32_t hash_lambda_term(uint32_t n, const term_t *v, term_t t) {
558   uint32_t h;
559 
560   h = jenkins_hash_intarray(v, n);
561   return jenkins_hash_pair(t, h, 0xabdaabda);
562 }
563 
564 
565 /*
566  * Projection/bit selection: (tag, k, t)
567  */
hash_select_term(term_kind_t tag,uint32_t k,term_t t)568 static inline uint32_t hash_select_term(term_kind_t tag, uint32_t k, term_t t) {
569   return jenkins_hash_triple(tag, k, t, 0x98ab3342);
570 }
571 
572 
573 /*
574  * Root atoms: (k, x, p, r)
575  */
hash_root_atom(uint32_t k,term_t x,term_t p,root_atom_rel_t r)576 static inline uint32_t hash_root_atom(uint32_t k, term_t x, term_t p, root_atom_rel_t r) {
577   return jenkins_hash_quad(k, x, p, r, 0xdededede);
578 }
579 
580 
581 /*
582  * Power product: since the pprod-table already does hash consing,
583  * a power product r is uniquely identified by its address.
584  */
hash_power_product(const pprod_t * r)585 static inline uint32_t hash_power_product(const pprod_t *r) {
586   return jenkins_hash_ptr(r);
587 }
588 
589 
590 /*
591  * For bitvector constant, we can use bvconst_hash defined in bv_constants.c
592  */
hash_bvconst_term(uint32_t bitsize,const uint32_t * bv)593 static inline uint32_t hash_bvconst_term(uint32_t bitsize, const uint32_t *bv) {
594   return bvconst_hash(bv, bitsize);
595 }
596 
597 
598 /*
599  * 64bit constants
600  */
hash_bvconst64_term(uint32_t bitsize,uint64_t v)601 static inline uint32_t hash_bvconst64_term(uint32_t bitsize, uint64_t v) {
602   assert(v == norm64(v, bitsize));
603   return jenkins_hash_mix3((uint32_t)(v >> 32), (uint32_t) v, 0xdeadbeef + bitsize);
604 }
605 
606 
607 
608 /*
609  * HASH CONSING
610  */
611 
612 /*
613  * Objects for interfacing with int_hash_table
614  * - each object type corresponds to a term kind
615  * - it starts with a method descriptor m
616  *   with three fields:
617  *     m.hash: hash function
618  *     m.eq: check for equality
619  *     m.build: construct fresh term
620  * - other fields are a term table, and all the
621  *   subcomponents for the term kind.
622  * - for an object o,
623  *    o->m.hash(o) = hash code for o
624  *    o->m.eq(o, i): check whether o equals term i
625  *    o->m.build(o): add o to the term table and return its index
626  */
627 
628 /*
629  * Terms with integer id
630  * - tag = term kind
631  * - tau = type
632  * - id
633  */
634 typedef struct {
635   int_hobj_t m;
636   term_table_t *tbl;
637   term_kind_t tag;
638   type_t tau;
639   int32_t id;
640 } integer_term_hobj_t;
641 
642 /*
643  * Rational terms
644  * - tag = term kind
645  * - tau = type
646  * - a = value
647  */
648 typedef struct {
649   int_hobj_t m;
650   term_table_t *tbl;
651   term_kind_t tag;
652   type_t tau;
653   rational_t *a;
654 } rational_term_hobj_t;
655 
656 
657 /*
658  * Generic composite
659  * - tag = term kind
660  * - tau = type
661  * - arity = n
662  * - arg = array of n term occurrences
663  */
664 typedef struct {
665   int_hobj_t m;
666   term_table_t *tbl;
667   term_kind_t tag;
668   type_t tau;
669   uint32_t arity;
670   const term_t *arg;
671 } composite_term_hobj_t;
672 
673 
674 /*
675  * Function application
676  * - tau = type of (f arg[0] ... arg[n-1])
677  * - f = function
678  * - n = number of arguments
679  * - arg = array of n arguments
680  */
681 typedef struct {
682   int_hobj_t m;
683   term_table_t *tbl;
684   type_t tau;
685   term_t f;
686   uint32_t n;
687   const term_t *arg;
688 } app_term_hobj_t;
689 
690 
691 /*
692  * Function update
693  * - tau = result type
694  * - f = function
695  * - n = number of arguments
696  * - arg = array of n arguments
697  * - v = new value
698  */
699 typedef struct {
700   int_hobj_t m;
701   term_table_t *tbl;
702   type_t tau;
703   term_t f;
704   term_t v;
705   uint32_t n;
706   const term_t *arg;
707 } update_term_hobj_t;
708 
709 /*
710  * Quantified formula: (forall v[0] ... v[n-1] p)
711  * - p = body
712  * - n = number of variables
713  * - v = array of n variables
714  */
715 typedef struct {
716   int_hobj_t m;
717   term_table_t *tbl;
718   term_t p;
719   uint32_t n;
720   const term_t *v;
721 } forall_term_hobj_t;
722 
723 /*
724  * Lambda term: (lambda v[0] ... v[n-1] t)
725  * - tau = type
726  * - t = body
727  * - n = number of variables
728  * - v = array of n variables
729  */
730 typedef struct {
731   int_hobj_t m;
732   term_table_t *tbl;
733   type_t tau;
734   term_t t;
735   uint32_t n;
736   const term_t *v;
737 } lambda_term_hobj_t;
738 
739 
740 /*
741  * Select term
742  * - tag = term kind
743  * - tau = type
744  * - k = index in projection/bitselect
745  * - arg = term
746  */
747 typedef struct {
748   int_hobj_t m;
749   term_table_t *tbl;
750   term_kind_t tag;
751   type_t tau;
752   uint32_t k;
753   term_t arg;
754 } select_term_hobj_t;
755 
756 
757 /*
758  * Root atom
759  * - k = root index
760  * - x = main variable
761  * - p = the polynomial (in x) whose root is being compared
762  * - r = the relation
763  */
764 typedef struct {
765   int_hobj_t m;
766   term_table_t *tbl;
767   uint32_t k;
768   term_t x;
769   term_t p;
770   root_atom_rel_t r;
771 } root_atom_hobj_t;
772 
773 
774 /*
775  * Power product
776  * - tau = type (can be int, real, or bitvector)
777  * - r = power product
778  */
779 typedef struct {
780   int_hobj_t m;
781   term_table_t *tbl;
782   type_t tau;
783   pprod_t *r;
784 } pprod_term_hobj_t;
785 
786 
787 
788 /*
789  * Polynomial
790  * - a polynomial is constructed from a buffer b
791  *   and an array of term indices v
792  * - tau can be int or real
793  */
794 typedef struct {
795   int_hobj_t m;
796   term_table_t *tbl;
797   type_t tau;
798   rba_buffer_t *b;
799   int32_t *v;
800 } poly_term_hobj_t;
801 
802 
803 /*
804  * Bit-vector polynomials
805  * - tau = bitvector type
806  */
807 typedef struct {
808   int_hobj_t m;
809   term_table_t *tbl;
810   type_t tau;
811   bvarith_buffer_t *b;
812   int32_t *v;
813 } bvpoly_term_hobj_t;
814 
815 
816 /*
817  * Bit vector polynomials with small coefficients.
818  * - tau = bitvector type
819  */
820 typedef struct {
821   int_hobj_t m;
822   term_table_t *tbl;
823   type_t tau;
824   bvarith64_buffer_t *b;
825   int32_t *v;
826 } bvpoly64_term_hobj_t;
827 
828 
829 /*
830  * Bit vector polynomial constructed from a bvpoly_buffer
831  * - this handles both small and large coefficients.
832  * - tau = bitvector type
833  */
834 typedef struct {
835   int_hobj_t m;
836   term_table_t *tbl;
837   type_t tau;
838   bvpoly_buffer_t *b;
839 } bvpoly_buffer_hobj_t;
840 
841 
842 /*
843  * Bit vector constants
844  * - v = value stored as an array of words
845  */
846 typedef struct {
847   int_hobj_t m;
848   term_table_t *tbl;
849   type_t tau;
850   uint32_t bitsize;
851   const uint32_t *v;
852 } bvconst_term_hobj_t;
853 
854 
855 /*
856  * Small bit vector constants
857  */
858 typedef struct {
859   int_hobj_t m;
860   term_table_t *tbl;
861   type_t tau;
862   uint32_t bitsize;
863   uint64_t v;
864 } bvconst64_term_hobj_t;
865 
866 
867 
868 /*
869  * Hash functions for these objects
870  */
hash_integer_hobj(integer_term_hobj_t * o)871 static uint32_t hash_integer_hobj(integer_term_hobj_t *o) {
872   return hash_integer_term(o->tag, o->tau, o->id);
873 }
874 
hash_rational_hobj(rational_term_hobj_t * o)875 static uint32_t hash_rational_hobj(rational_term_hobj_t *o) {
876   return hash_rational_term(o->tag, o->tau, o->a);
877 }
878 
hash_composite_hobj(composite_term_hobj_t * o)879 static uint32_t hash_composite_hobj(composite_term_hobj_t *o) {
880   return hash_composite_term(o->tag, o->arity, o->arg);
881 }
882 
hash_app_hobj(app_term_hobj_t * o)883 static uint32_t hash_app_hobj(app_term_hobj_t *o) {
884   return hash_app_term(o->f, o->n, o->arg);
885 }
886 
hash_update_hobj(update_term_hobj_t * o)887 static uint32_t hash_update_hobj(update_term_hobj_t *o) {
888   return hash_update_term(o->f, o->n, o->arg, o->v);
889 }
890 
hash_forall_hobj(forall_term_hobj_t * o)891 static uint32_t hash_forall_hobj(forall_term_hobj_t *o) {
892   return hash_forall_term(o->n, o->v, o->p);
893 }
894 
hash_lambda_hobj(lambda_term_hobj_t * o)895 static uint32_t hash_lambda_hobj(lambda_term_hobj_t *o) {
896   return hash_lambda_term(o->n, o->v, o->t);
897 }
898 
hash_select_hobj(select_term_hobj_t * o)899 static uint32_t hash_select_hobj(select_term_hobj_t *o) {
900   return hash_select_term(o->tag, o->k, o->arg);
901 }
902 
hash_root_atom_hobj(root_atom_hobj_t * o)903 static uint32_t hash_root_atom_hobj(root_atom_hobj_t *o) {
904   return hash_root_atom(o->k, o->x, o->p, o->r);
905 }
906 
hash_pprod_hobj(pprod_term_hobj_t * o)907 static uint32_t hash_pprod_hobj(pprod_term_hobj_t *o) {
908   return hash_power_product(o->r);
909 }
910 
hash_poly_hobj(poly_term_hobj_t * o)911 static uint32_t hash_poly_hobj(poly_term_hobj_t *o) {
912   return hash_rba_buffer(o->b, o->v);
913 }
914 
hash_bvpoly_hobj(bvpoly_term_hobj_t * o)915 static uint32_t hash_bvpoly_hobj(bvpoly_term_hobj_t *o) {
916   return hash_bvarith_buffer(o->b, o->v);
917 }
918 
hash_bvpoly64_hobj(bvpoly64_term_hobj_t * o)919 static uint32_t hash_bvpoly64_hobj(bvpoly64_term_hobj_t *o) {
920   return hash_bvarith64_buffer(o->b, o->v);
921 }
922 
hash_bvpoly_buffer_hobj(bvpoly_buffer_hobj_t * o)923 static uint32_t hash_bvpoly_buffer_hobj(bvpoly_buffer_hobj_t *o) {
924   if (o->b->bitsize <= 64) {
925     return bvpoly_buffer_hash64(o->b);
926   } else {
927     return bvpoly_buffer_hash(o->b);
928   }
929 }
930 
hash_bvconst_hobj(bvconst_term_hobj_t * o)931 static uint32_t hash_bvconst_hobj(bvconst_term_hobj_t *o) {
932   return hash_bvconst_term(o->bitsize, o->v);
933 }
934 
hash_bvconst64_hobj(bvconst64_term_hobj_t * o)935 static uint32_t hash_bvconst64_hobj(bvconst64_term_hobj_t *o) {
936   return hash_bvconst64_term(o->bitsize, o->v);
937 }
938 
939 
940 /*
941  * Equality test: o = hash object, i = index of a term in o->tbl
942  */
eq_integer_hobj(integer_term_hobj_t * o,int32_t i)943 static bool eq_integer_hobj(integer_term_hobj_t *o, int32_t i) {
944   term_table_t *table;
945 
946   table = o->tbl;
947   assert(good_term_idx(table, i));
948 
949   return table->kind[i] == o->tag && table->type[i] == o->tau
950     && table->desc[i].integer == o->id;
951 }
952 
eq_rational_hobj(rational_term_hobj_t * o,int32_t i)953 static bool eq_rational_hobj(rational_term_hobj_t *o, int32_t i) {
954   term_table_t *table;
955 
956   table = o->tbl;
957   assert(good_term_idx(table, i));
958 
959   return table->kind[i] == o->tag && q_eq(&table->desc[i].rational, o->a);
960 }
961 
962 
963 // test whether arrays a and b of size n are equal
eq_term_arrays(const term_t * a,const term_t * b,uint32_t n)964 static bool eq_term_arrays(const term_t *a, const term_t *b, uint32_t n) {
965   uint32_t i;
966 
967   for (i=0; i<n; i++) {
968     if (a[i] != b[i]) return false;
969   }
970   return true;
971 }
972 
eq_composite_hobj(composite_term_hobj_t * o,int32_t i)973 static bool eq_composite_hobj(composite_term_hobj_t *o, int32_t i) {
974   term_table_t *table;
975   composite_term_t *d;
976   uint32_t n;
977 
978   table = o->tbl;
979   assert(good_term_idx(table, i));
980 
981   if (table->kind[i] != o->tag) return false;
982 
983   d = table->desc[i].ptr;
984   n = d->arity;
985   return n == o->arity && eq_term_arrays(o->arg, d->arg, n);
986 }
987 
eq_app_hobj(app_term_hobj_t * o,int32_t i)988 static bool eq_app_hobj(app_term_hobj_t *o, int32_t i) {
989   term_table_t *table;
990   composite_term_t *d;
991   uint32_t n;
992 
993   table = o->tbl;
994   assert(good_term_idx(table, i));
995 
996   if (table->kind[i] != APP_TERM) return false;
997 
998   d = table->desc[i].ptr;
999   n = o->n;
1000   return d->arity == n+1 && d->arg[0] == o->f &&
1001     eq_term_arrays(o->arg, d->arg + 1, n);
1002 }
1003 
eq_update_hobj(update_term_hobj_t * o,int32_t i)1004 static bool eq_update_hobj(update_term_hobj_t *o, int32_t i) {
1005   term_table_t *table;
1006   composite_term_t *d;
1007   uint32_t n;
1008 
1009   table = o->tbl;
1010   assert(good_term_idx(table, i));
1011 
1012   if (table->kind[i] != UPDATE_TERM) return false;
1013 
1014   d = table->desc[i].ptr;
1015   n = o->n;
1016   return d->arity == n+2 && d->arg[0] == o->f &&
1017     d->arg[n + 1] == o->v &&
1018     eq_term_arrays(o->arg, d->arg + 1, n);
1019 }
1020 
eq_forall_hobj(forall_term_hobj_t * o,int32_t i)1021 static bool eq_forall_hobj(forall_term_hobj_t *o, int32_t i) {
1022   term_table_t *table;
1023   composite_term_t *d;
1024   uint32_t n;
1025 
1026   table = o->tbl;
1027   assert(good_term_idx(table, i));
1028 
1029   if (table->kind[i] != FORALL_TERM) return false;
1030 
1031   d = table->desc[i].ptr;
1032   n = o->n;
1033   return d->arity == n+1 && d->arg[n] == o->p &&
1034     eq_term_arrays(o->v, d->arg, n);
1035 }
1036 
eq_lambda_hobj(lambda_term_hobj_t * o,int32_t i)1037 static bool eq_lambda_hobj(lambda_term_hobj_t *o, int32_t i) {
1038   term_table_t *table;
1039   composite_term_t *d;
1040   uint32_t n;
1041 
1042   table = o->tbl;
1043   assert(good_term_idx(table, i));
1044 
1045   if (table->kind[i] != LAMBDA_TERM) return false;
1046 
1047   d = table->desc[i].ptr;
1048   n = o->n;
1049   return d->arity == n+1 && d->arg[n] == o->t && eq_term_arrays(o->v, d->arg, n);
1050 }
1051 
eq_select_hobj(select_term_hobj_t * o,int32_t i)1052 static bool eq_select_hobj(select_term_hobj_t *o, int32_t i) {
1053   term_table_t *table;
1054   select_term_t *d;
1055 
1056   table = o->tbl;
1057   assert(good_term_idx(table, i));
1058 
1059   if (table->kind[i] != o->tag) return false;
1060 
1061   d = &table->desc[i].select;
1062   return d->idx == o->k && d->arg == o->arg;
1063 }
1064 
eq_root_atom_hobj(root_atom_hobj_t * o,int32_t i)1065 static bool eq_root_atom_hobj(root_atom_hobj_t *o, int32_t i) {
1066   term_table_t *table;
1067   root_atom_t *r;
1068 
1069   table = o->tbl;
1070   assert(good_term_idx(table, i));
1071 
1072   if (table->kind[i] != ARITH_ROOT_ATOM) return false;
1073 
1074   r = table->desc[i].ptr;
1075   return r->k == o->k && r->p == o->p && r->r == o->r && r->x == o->x;
1076 }
1077 
1078 
eq_pprod_hobj(pprod_term_hobj_t * o,int32_t i)1079 static bool eq_pprod_hobj(pprod_term_hobj_t *o, int32_t i) {
1080   term_table_t *table;
1081 
1082   table = o->tbl;
1083   assert(good_term_idx(table, i));
1084   return table->kind[i] == POWER_PRODUCT && table->desc[i].ptr == o->r;
1085 }
1086 
eq_poly_hobj(poly_term_hobj_t * o,int32_t i)1087 static bool eq_poly_hobj(poly_term_hobj_t *o, int32_t i) {
1088   term_table_t *table;
1089 
1090   table = o->tbl;
1091   assert(good_term_idx(table, i));
1092 
1093   return table->kind[i] == ARITH_POLY &&
1094     rba_buffer_equal_poly(o->b, o->v, table->desc[i].ptr);
1095 }
1096 
eq_bvpoly_hobj(bvpoly_term_hobj_t * o,int32_t i)1097 static bool eq_bvpoly_hobj(bvpoly_term_hobj_t *o, int32_t i) {
1098   term_table_t *table;
1099 
1100   table = o->tbl;
1101   assert(good_term_idx(table, i));
1102 
1103   return table->kind[i] == BV_POLY &&
1104     bvarith_buffer_equal_bvpoly(o->b, o->v, table->desc[i].ptr);
1105 }
1106 
eq_bvpoly64_hobj(bvpoly64_term_hobj_t * o,int32_t i)1107 static bool eq_bvpoly64_hobj(bvpoly64_term_hobj_t *o, int32_t i) {
1108   term_table_t *table;
1109 
1110   table = o->tbl;
1111   assert(good_term_idx(table, i));
1112 
1113   return table->kind[i] == BV64_POLY &&
1114     bvarith64_buffer_equal_bvpoly(o->b, o->v, table->desc[i].ptr);
1115 }
1116 
eq_bvpoly_buffer_hobj(bvpoly_buffer_hobj_t * o,int32_t i)1117 static bool eq_bvpoly_buffer_hobj(bvpoly_buffer_hobj_t *o, int32_t i) {
1118   term_table_t *table;
1119 
1120   table = o->tbl;
1121   assert(good_term_idx(table, i));
1122 
1123   switch (table->kind[i]) {
1124   case BV64_POLY:
1125     return bvpoly_buffer_equal_poly64(o->b, table->desc[i].ptr);
1126 
1127   case BV_POLY:
1128     return bvpoly_buffer_equal_poly(o->b, table->desc[i].ptr);
1129 
1130   default:
1131     return false;
1132   }
1133 }
1134 
eq_bvconst_hobj(bvconst_term_hobj_t * o,int32_t i)1135 static bool eq_bvconst_hobj(bvconst_term_hobj_t *o, int32_t i) {
1136   term_table_t *table;
1137   bvconst_term_t *d;
1138   uint32_t n;
1139 
1140   table = o->tbl;
1141   assert(good_term_idx(table, i));
1142 
1143   if (table->kind[i] != BV_CONSTANT) return false;
1144 
1145   d = table->desc[i].ptr;
1146   n = d->bitsize;
1147   return n == o->bitsize && bvconst_eq(d->data, o->v, (n + 31) >> 5);
1148 }
1149 
eq_bvconst64_hobj(bvconst64_term_hobj_t * o,int32_t i)1150 static bool eq_bvconst64_hobj(bvconst64_term_hobj_t *o, int32_t i) {
1151   term_table_t *table;
1152   bvconst64_term_t *d;
1153 
1154   table = o->tbl;
1155   assert(good_term_idx(table, i));
1156 
1157   if (table->kind[i] != BV64_CONSTANT) return false;
1158 
1159   d = table->desc[i].ptr;
1160   return d->bitsize == o->bitsize && d->value == o->v;
1161 }
1162 
1163 
1164 /*
1165  * Build functions: add a new term to o->tbl and return its index
1166  */
build_integer_hobj(integer_term_hobj_t * o)1167 static int32_t build_integer_hobj(integer_term_hobj_t *o) {
1168   return new_integer_term(o->tbl, o->tag, o->tau, o->id);
1169 }
1170 
build_rational_hobj(rational_term_hobj_t * o)1171 static int32_t build_rational_hobj(rational_term_hobj_t *o) {
1172   return new_rational_term(o->tbl, o->tag, o->tau, o->a);
1173 }
1174 
build_composite_hobj(composite_term_hobj_t * o)1175 static int32_t build_composite_hobj(composite_term_hobj_t *o) {
1176   composite_term_t *d;
1177 
1178   d = new_composite_term(o->arity, o->arg);
1179   return new_ptr_term(o->tbl, o->tag, o->tau, d);
1180 }
1181 
build_special_hobj(composite_term_hobj_t * o)1182 static int32_t build_special_hobj(composite_term_hobj_t *o) {
1183   composite_term_t *d;
1184 
1185   d = new_special_term(o->arity, o->arg);
1186   return new_ptr_term(o->tbl, o->tag, o->tau, d);
1187 }
1188 
build_app_hobj(app_term_hobj_t * o)1189 static int32_t build_app_hobj(app_term_hobj_t *o) {
1190   composite_term_t *d;
1191 
1192   d = new_app_term(o->f, o->n, o->arg);
1193   return new_ptr_term(o->tbl, APP_TERM, o->tau, d);
1194 }
1195 
build_update_hobj(update_term_hobj_t * o)1196 static int32_t build_update_hobj(update_term_hobj_t *o) {
1197   composite_term_t *d;
1198 
1199   d = new_update_term(o->f, o->n, o->arg, o->v);
1200   return new_ptr_term(o->tbl, UPDATE_TERM, o->tau, d);
1201 }
1202 
build_forall_hobj(forall_term_hobj_t * o)1203 static int32_t build_forall_hobj(forall_term_hobj_t *o) {
1204   composite_term_t *d;
1205 
1206   d = new_forall_term(o->n, o->v, o->p);
1207   return new_ptr_term(o->tbl, FORALL_TERM, bool_id, d);
1208 }
1209 
build_lambda_hobj(lambda_term_hobj_t * o)1210 static int32_t build_lambda_hobj(lambda_term_hobj_t *o) {
1211   composite_term_t *d;
1212 
1213   d = new_lambda_term(o->n, o->v, o->t);
1214   return new_ptr_term(o->tbl, LAMBDA_TERM, o->tau, d);
1215 }
1216 
build_select_hobj(select_term_hobj_t * o)1217 static int32_t build_select_hobj(select_term_hobj_t *o) {
1218   return new_select_term(o->tbl, o->tag, o->tau, o->k, o->arg);
1219 }
1220 
build_root_atom_hobj(root_atom_hobj_t * o)1221 static int32_t build_root_atom_hobj(root_atom_hobj_t *o) {
1222   root_atom_t* r;
1223 
1224   r = new_root_atom(o->tbl, o->k, o->x, o->p, o->r);
1225   return new_ptr_term(o->tbl, ARITH_ROOT_ATOM, bool_type(o->tbl->types), r);
1226 }
1227 
build_pprod_hobj(pprod_term_hobj_t * o)1228 static int32_t build_pprod_hobj(pprod_term_hobj_t *o) {
1229   return new_ptr_term(o->tbl, POWER_PRODUCT, o->tau, o->r);
1230 }
1231 
build_poly_hobj(poly_term_hobj_t * o)1232 static int32_t build_poly_hobj(poly_term_hobj_t *o) {
1233   polynomial_t *p;
1234 
1235   p = rba_buffer_get_poly(o->b, o->v);
1236   return new_ptr_term(o->tbl, ARITH_POLY, o->tau, p);
1237 }
1238 
build_bvpoly_hobj(bvpoly_term_hobj_t * o)1239 static int32_t build_bvpoly_hobj(bvpoly_term_hobj_t *o) {
1240   bvpoly_t *p;
1241 
1242   p = bvarith_buffer_get_bvpoly(o->b, o->v);
1243   return new_ptr_term(o->tbl, BV_POLY, o->tau, p);
1244 }
1245 
build_bvpoly64_hobj(bvpoly64_term_hobj_t * o)1246 static int32_t build_bvpoly64_hobj(bvpoly64_term_hobj_t *o) {
1247   bvpoly64_t *p;
1248 
1249   p = bvarith64_buffer_get_bvpoly(o->b, o->v);
1250   return new_ptr_term(o->tbl, BV64_POLY, o->tau, p);
1251 }
1252 
build_bvpoly_buffer_hobj(bvpoly_buffer_hobj_t * o)1253 static int32_t build_bvpoly_buffer_hobj(bvpoly_buffer_hobj_t *o) {
1254   bvpoly_buffer_t *b;
1255   term_kind_t tag;
1256   void *p;
1257 
1258   b = o->b;
1259   if (b->bitsize <= 64) {
1260     p = bvpoly_buffer_getpoly64(b);
1261     tag = BV64_POLY;
1262   } else {
1263     p = bvpoly_buffer_getpoly(b);
1264     tag = BV_POLY;
1265   }
1266 
1267   return new_ptr_term(o->tbl, tag, o->tau, p);
1268 }
1269 
build_bvconst_hobj(bvconst_term_hobj_t * o)1270 static int32_t build_bvconst_hobj(bvconst_term_hobj_t *o) {
1271   bvconst_term_t *c;
1272 
1273   c = new_bvconst_term(o->bitsize, o->v);
1274   return new_ptr_term(o->tbl, BV_CONSTANT, o->tau, c);
1275 }
1276 
build_bvconst64_hobj(bvconst64_term_hobj_t * o)1277 static int32_t build_bvconst64_hobj(bvconst64_term_hobj_t *o) {
1278   bvconst64_term_t *c;
1279 
1280   c = new_bvconst64_term(o->bitsize, o->v);
1281   return new_ptr_term(o->tbl, BV64_CONSTANT, o->tau, c);
1282 }
1283 
1284 
1285 /*
1286  * UNIT TABLE
1287  */
1288 
1289 /*
1290  * Get the representative of type tau in the unit table
1291  * - tau must be a unit type
1292  * - return NULL_TERM (-1) if there's no representative
1293  */
unit_type_rep(term_table_t * table,type_t tau)1294 term_t unit_type_rep(term_table_t *table, type_t tau) {
1295   int_hmap_pair_t *p;
1296 
1297   assert(is_unit_type(table->types, tau));
1298   p = int_hmap_find(&table->utbl, tau);
1299   if (p == NULL) {
1300     return NULL_TERM;
1301   }
1302   assert(good_term(table, p->val) && term_type(table, p->val) == tau);
1303 
1304   return p->val;
1305 }
1306 
1307 
1308 /*
1309  * Store t as the unique term of type tau:
1310  * - tau must be a singleton type
1311  * - t must be a valid term occurrence of type tau
1312  * - there mustn't be a representative for tau already
1313  */
add_unit_type_rep(term_table_t * table,type_t tau,term_t t)1314 void add_unit_type_rep(term_table_t *table, type_t tau, term_t t) {
1315   int_hmap_pair_t *p;
1316 
1317   assert(is_unit_type(table->types, tau) && good_term(table, t) &&
1318          term_type(table, t) == tau);
1319 
1320   p = int_hmap_get(&table->utbl, tau);
1321   assert(p->val == EMPTY_KEY); // i.e., -1
1322   p->val = t;
1323 }
1324 
1325 
1326 /*
1327  * Store t as the unique term of type tau:
1328  * - tau must be a singleton type
1329  * - t must be a valid term occurrence of type tau
1330  * - there mustn't be a representative for tau already or
1331  *   the representative must be equal to t
1332  */
store_unit_type_rep(term_table_t * table,type_t tau,term_t t)1333 void store_unit_type_rep(term_table_t *table, type_t tau, term_t t) {
1334   int_hmap_pair_t *p;
1335 
1336   assert(is_unit_type(table->types, tau) && good_term(table, t) &&
1337          term_type(table, t) == tau);
1338 
1339   p = int_hmap_get(&table->utbl, tau);
1340   if (p->val == EMPTY_KEY) {
1341     p->val = t;
1342   }
1343   assert(p->val == t);
1344 }
1345 
1346 
1347 /*
1348  * Remove the representative of type tau from the table.
1349  * - tau must be a singleton type
1350  * - no effect if tau has no representative
1351  */
remove_unit_type_rep(term_table_t * table,type_t tau)1352 static void remove_unit_type_rep(term_table_t *table, type_t tau) {
1353   int_hmap_pair_t *p;
1354 
1355   assert(is_unit_type(table->types, tau));
1356   p = int_hmap_find(&table->utbl, tau);
1357   if (p != NULL) {
1358     int_hmap_erase(&table->utbl, p);
1359   }
1360 }
1361 
1362 
1363 /*
1364  * For debugging, check that the representative for type
1365  * tau is equal to t.
1366  */
1367 #ifndef NDEBUG
is_unit_type_rep(term_table_t * table,type_t tau,term_t t)1368 static bool is_unit_type_rep(term_table_t *table, type_t tau, term_t t) {
1369   term_t rep;
1370 
1371   rep = unit_type_rep(table, tau);
1372   return rep == NULL_TERM || rep == t;
1373 }
1374 #endif
1375 
1376 
1377 
1378 
1379 
1380 
1381 
1382 /*
1383  * TERM NAMES
1384  */
1385 
1386 /*
1387  * Get the base name of term occurrence t
1388  * - return NULL if t has no base name
1389  */
term_name(term_table_t * table,term_t t)1390 char *term_name(term_table_t *table, term_t t) {
1391   ptr_hmap_pair_t *p;
1392 
1393   assert(live_term(table, t));
1394   p = ptr_hmap_find(&table->ntbl, t);
1395   if (p == NULL) {
1396     return NULL;
1397   }
1398 
1399   assert(p->val != NULL);
1400   return p->val;
1401 
1402 }
1403 
1404 
1405 /*
1406  * Assign name to term occurrence t.
1407  *
1408  * If name is already mapped to another term t' then the previous mapping
1409  * is hidden. The next calls to get_term_by_name will return t. After a
1410  * call to remove_term_name, the mapping [name --> t] is removed and
1411  * the previous mapping [name --> t'] is revealed.
1412  *
1413  * If t does not have a base name already, then 'name' is stored as the
1414  * base name for t. That's what's printed for t by the pretty printer.
1415  *
1416  * Warning: name is stored as a pointer, no copy is made; name must be
1417  * created via the clone_string function.
1418  */
set_term_name(term_table_t * table,term_t t,char * name)1419 void set_term_name(term_table_t *table, term_t t, char *name) {
1420   ptr_hmap_pair_t *p;
1421 
1422   assert(good_term(table, t) && name != NULL);
1423 
1424   // if t doesn't have a base name then
1425   // add mapping t --> name in ntbl
1426   p = ptr_hmap_get(&table->ntbl, t);
1427   assert(p != NULL);
1428   if (p->val == NULL) {
1429     p->val = name;
1430     string_incref(name);
1431   }
1432 
1433   // add mapping name --> t in the symbol table
1434   stbl_add(&table->stbl, name, t);
1435   string_incref(name);
1436 }
1437 
1438 
1439 /*
1440  * Assign name as the base name for term t
1441  * - if t already has a base name, then it's replaced by 'name'
1442  *   and the previous name's reference counter is decremented
1443  */
set_term_base_name(term_table_t * table,term_t t,char * name)1444 void set_term_base_name(term_table_t *table, term_t t, char *name) {
1445   ptr_hmap_pair_t *p;
1446 
1447   assert(good_term(table, t) && name != NULL);
1448 
1449   p = ptr_hmap_get(&table->ntbl, t);
1450   assert(p != NULL);
1451   if (p->val != NULL) {
1452     string_decref(p->val);
1453   }
1454   p->val = name;
1455   string_incref(name);
1456 }
1457 
1458 
1459 /*
1460  * Get term occurrence with the given name (or NULL_TERM)
1461  */
get_term_by_name(term_table_t * table,const char * name)1462 term_t get_term_by_name(term_table_t *table, const char *name) {
1463   // NULL_TERM = -1 and stbl_find returns -1 if name is absent
1464   return stbl_find(&table->stbl, name);
1465 }
1466 
1467 
1468 /*
1469  * Remove a name from the symbol table
1470  * - if name is not in the symbol table, nothing is done
1471  * - if name is mapped to a term t, then the mapping [name -> t]
1472  *   is removed. If name was mapped to a previous term t' then
1473  *   that mapping is restored.
1474  *
1475  * If name is the base name of a term t, then that remains unchanged.
1476  */
remove_term_name(term_table_t * table,const char * name)1477 void remove_term_name(term_table_t *table, const char *name) {
1478   stbl_remove(&table->stbl, name);
1479 }
1480 
1481 
1482 /*
1483  * Clear name: remove t's base name if any.
1484  * - If t has name 'xxx' then 'xxx' is first removed from the symbol
1485  *   table (using remove_term_name) then t's base name is erased.
1486  * - If t doesn't have a base name, nothing is done.
1487  */
clear_term_name(term_table_t * table,term_t t)1488 void clear_term_name(term_table_t *table, term_t t) {
1489   ptr_hmap_pair_t *p;
1490   char *name;
1491 
1492   assert(good_term(table, t));
1493   p = ptr_hmap_find(&table->ntbl, t);
1494   if (p != NULL) {
1495     name = p->val;
1496     assert(name != NULL);
1497 
1498     // remove the mapping t --> name from ntbl
1499     ptr_hmap_erase(&table->ntbl, p);
1500 
1501     // check whether the mapping name --> t still exists
1502     // in the symbol table.
1503     if (stbl_find(&table->stbl, name) == t) {
1504       stbl_remove(&table->stbl, name);
1505     }
1506     string_decref(name);
1507   }
1508 }
1509 
1510 
1511 
1512 
1513 
1514 /*
1515  * TERM DELETION
1516  */
1517 
1518 /*
1519  * Delete term i:
1520  * - remove pos_term(i) from the unit table
1521  * - remove pos_term(i) and neg_term(i) from the name table
1522  * - free the descriptor if needed
1523  * - remove i from the hash table
1524  * - then add i to the free list
1525  *
1526  * IMPORTANT: i must not be accessible via the symbol table.
1527  * No name in the symbol table must refer to pos_term(i)
1528  * or neg_term(i).
1529  */
delete_term(term_table_t * table,int32_t i)1530 static void delete_term(term_table_t *table, int32_t i) {
1531   composite_term_t *d;
1532   select_term_t *s;
1533   root_atom_t* r;
1534   bvconst_term_t *c;
1535   bvconst64_term_t *c64;
1536   uint32_t h, n;
1537   type_t tau;
1538 
1539   assert(good_term_idx(table, i));
1540 
1541   // make sure the reserved and primitive terms are
1542   // never deleted
1543   if (i <= zero_const) return;
1544 
1545   // deal with unit types
1546   tau = table->type[i];
1547   if (is_unit_type(table->types, tau)) {
1548     assert(is_unit_type_rep(table, tau, pos_term(i)));
1549     remove_unit_type_rep(table, tau);
1550   }
1551 
1552   // remove the default name for pos_term(i)
1553   // and for neg_term(i) if i has boolean type
1554   clear_term_name(table, pos_term(i));
1555   if (is_boolean_type(tau)) {
1556     clear_term_name(table, neg_term(i));
1557   }
1558 
1559   h = 0;   // stops GCC warning
1560 
1561   // compute hash and free descriptor
1562   switch (table->kind[i]) {
1563   case UNINTERPRETED_TERM:
1564     // No descriptor, no hash consing
1565     goto recycle;
1566 
1567   case CONSTANT_TERM:
1568   case VARIABLE:
1569   case ARITH_EQ_ATOM:
1570   case ARITH_GE_ATOM:
1571   case ARITH_IS_INT_ATOM:
1572   case ARITH_FLOOR:
1573   case ARITH_CEIL:
1574   case ARITH_ABS:
1575     // The descriptor is an integer nothing to delete.
1576     h = hash_integer_term(table->kind[i], table->type[i], table->desc[i].integer);
1577     break;
1578 
1579   case ITE_TERM:
1580   case TUPLE_TERM:
1581   case EQ_TERM:
1582   case DISTINCT_TERM:
1583   case OR_TERM:
1584   case XOR_TERM:
1585   case ARITH_BINEQ_ATOM:
1586   case ARITH_RDIV:
1587   case ARITH_IDIV:
1588   case ARITH_MOD:
1589   case ARITH_DIVIDES_ATOM:
1590   case BV_ARRAY:
1591   case BV_DIV:
1592   case BV_REM:
1593   case BV_SDIV:
1594   case BV_SREM:
1595   case BV_SMOD:
1596   case BV_SHL:
1597   case BV_LSHR:
1598   case BV_ASHR:
1599   case BV_EQ_ATOM:
1600   case BV_GE_ATOM:
1601   case BV_SGE_ATOM:
1602     // Generic composite
1603     d = table->desc[i].ptr;
1604     h = hash_composite_term(table->kind[i], d->arity, d->arg);
1605     safe_free(d);
1606     break;
1607 
1608   case ITE_SPECIAL:
1609     // Special composite:
1610     // call the finalizer before deleting the descriptor
1611     d = table->desc[i].ptr;
1612     h = hash_composite_term(table->kind[i], d->arity, d->arg);
1613     table->finalize(special_desc(d), ITE_SPECIAL);
1614     safe_free(special_desc(d));
1615     break;
1616 
1617   case APP_TERM:
1618     d = table->desc[i].ptr;
1619     n = d->arity;
1620     assert(n >= 2);
1621     h = hash_app_term(d->arg[0], n-1, d->arg + 1);
1622     safe_free(d);
1623     break;
1624 
1625   case UPDATE_TERM:
1626     d = table->desc[i].ptr;
1627     n = d->arity;
1628     assert(n >= 3);
1629     h = hash_update_term(d->arg[0], n-2, d->arg + 1, d->arg[n-1]);
1630     safe_free(d);
1631     break;
1632 
1633   case FORALL_TERM:
1634     d = table->desc[i].ptr;
1635     n = d->arity;
1636     assert(n >= 2);
1637     h = hash_forall_term(n-1, d->arg, d->arg[n-1]);
1638     safe_free(d);
1639     break;
1640 
1641   case LAMBDA_TERM:
1642     d = table->desc[i].ptr;
1643     n = d->arity;
1644     assert(n >= 2);
1645     h = hash_lambda_term(n-1, d->arg, d->arg[n-1]);
1646     safe_free(d);
1647     break;
1648 
1649   case SELECT_TERM:
1650   case BIT_TERM:
1651     // Select terms: nothing to delete.
1652     s = &table->desc[i].select;
1653     h = hash_select_term(table->kind[i], s->idx, s->arg);
1654     break;
1655 
1656   case ARITH_ROOT_ATOM:
1657     // Root atoms
1658     r = table->desc[i].ptr;
1659     h = hash_root_atom(r->k, r->x, r->p, r->r);
1660     safe_free(r);
1661     break;
1662 
1663   case POWER_PRODUCT:
1664     // Power products are deleted in garbage collection of pprod.
1665     h = hash_power_product(table->desc[i].ptr);
1666     break;
1667 
1668   case ARITH_CONSTANT:
1669     // Free the rational
1670     h = hash_rational_term(ARITH_CONSTANT, table->type[i], &table->desc[i].rational);
1671     q_clear(&table->desc[i].rational);
1672     break;
1673 
1674   case ARITH_POLY:
1675     h = hash_polynomial(table->desc[i].ptr);
1676     free_polynomial(table->desc[i].ptr);
1677     break;
1678 
1679   case BV64_CONSTANT:
1680     c64 = table->desc[i].ptr;
1681     h = hash_bvconst64_term(c64->bitsize, c64->value);
1682     safe_free(c64);
1683     break;
1684 
1685   case BV_CONSTANT:
1686     c = table->desc[i].ptr;
1687     h = hash_bvconst_term(c->bitsize, c->data);
1688     safe_free(c);
1689     break;
1690 
1691   case BV64_POLY:
1692     h = hash_bvpoly64(table->desc[i].ptr);
1693     free_bvpoly64(table->desc[i].ptr);
1694     break;
1695 
1696   case BV_POLY:
1697     h = hash_bvpoly(table->desc[i].ptr);
1698     free_bvpoly(table->desc[i].ptr);
1699     break;
1700 
1701   case UNUSED_TERM:
1702   case RESERVED_TERM:
1703   default:
1704     assert(false);
1705     break;
1706   }
1707 
1708   // Remove the record [h, i] from the hash-consing table
1709   int_htbl_erase_record(&table->htbl, h, i);
1710 
1711   // Put i in the free list
1712  recycle:
1713   table->desc[i].integer = table->free_idx;
1714   table->free_idx = i;
1715   table->kind[i] = UNUSED_TERM;
1716 
1717   assert(table->live_terms > 0);
1718   table->live_terms --;
1719 }
1720 
1721 
1722 
1723 
1724 
1725 
1726 
1727 /*
1728  * TABLE INITIALIZATION
1729  */
1730 
1731 /*
1732  * Build a dummy term at index 0 (to make sure nothing collides
1733  * with the const_idx used in rationals and bitvector polynomials).
1734  *
1735  * Add the boolean constant and the zero constant
1736  */
add_primitive_terms(term_table_t * table)1737 static void add_primitive_terms(term_table_t *table) {
1738   rational_t q;
1739   int32_t i;
1740 
1741   i = allocate_term_id(table);
1742   assert(i == const_idx);
1743   table->kind[i] = RESERVED_TERM;
1744   table->type[i] = NULL_TYPE;
1745   table->desc[i].ptr = NULL;
1746 
1747   i = constant_term(table, bool_type(table->types), 0);
1748   assert(i == true_term);
1749 
1750   q_init(&q);
1751   i = arith_constant(table, &q);
1752   assert(i == zero_term && term_type(table, i) == int_type(table->types));
1753   q_clear(&q);
1754 }
1755 
1756 
1757 /*
1758  * Initialize table with initial size = n.
1759  * Create the built-in constants and reserved term
1760  */
init_term_table(term_table_t * table,uint32_t n,type_table_t * ttbl,pprod_table_t * ptbl)1761 void init_term_table(term_table_t *table, uint32_t n, type_table_t *ttbl, pprod_table_t *ptbl) {
1762   term_table_init(table, n, ttbl, ptbl);
1763   add_primitive_terms(table);
1764 }
1765 
1766 
1767 
1768 
1769 
1770 /*
1771  * TABLE DELETION
1772  */
1773 
1774 /*
1775  * Delete the name table: call decref on all strings.
1776  */
delete_name_table(ptr_hmap_t * table)1777 static void delete_name_table(ptr_hmap_t *table) {
1778   ptr_hmap_pair_t *p;
1779 
1780   p = ptr_hmap_first_record(table);
1781   while (p != NULL) {
1782     assert(p->val != NULL);
1783     string_decref(p->val);
1784     p = ptr_hmap_next_record(table, p);
1785   }
1786 
1787   delete_ptr_hmap(table);
1788 }
1789 
1790 
1791 /*
1792  * Delete all the term descriptors
1793  */
delete_term_descriptors(term_table_t * table)1794 static void delete_term_descriptors(term_table_t *table) {
1795   uint32_t i, n;
1796 
1797   n = table->nelems;
1798   for (i=0; i<n; i++) {
1799     switch (table->kind[i]) {
1800     case UNUSED_TERM:
1801     case RESERVED_TERM:
1802     case CONSTANT_TERM:
1803     case UNINTERPRETED_TERM:
1804     case VARIABLE:
1805     case POWER_PRODUCT:
1806     case ARITH_EQ_ATOM:
1807     case ARITH_GE_ATOM:
1808     case ARITH_IS_INT_ATOM:
1809     case ARITH_FLOOR:
1810     case ARITH_CEIL:
1811     case ARITH_ABS:
1812     case SELECT_TERM:
1813     case BIT_TERM:
1814       break;
1815 
1816     case ITE_TERM:
1817     case APP_TERM:
1818     case UPDATE_TERM:
1819     case TUPLE_TERM:
1820     case EQ_TERM:
1821     case DISTINCT_TERM:
1822     case FORALL_TERM:
1823     case LAMBDA_TERM:
1824     case OR_TERM:
1825     case XOR_TERM:
1826     case ARITH_BINEQ_ATOM:
1827     case ARITH_RDIV:
1828     case ARITH_IDIV:
1829     case ARITH_MOD:
1830     case ARITH_DIVIDES_ATOM:
1831     case ARITH_ROOT_ATOM:
1832     case BV64_CONSTANT:
1833     case BV_CONSTANT:
1834     case BV_ARRAY:
1835     case BV_DIV:
1836     case BV_REM:
1837     case BV_SDIV:
1838     case BV_SREM:
1839     case BV_SMOD:
1840     case BV_SHL:
1841     case BV_LSHR:
1842     case BV_ASHR:
1843     case BV_EQ_ATOM:
1844     case BV_GE_ATOM:
1845     case BV_SGE_ATOM:
1846       safe_free(table->desc[i].ptr);
1847       break;
1848 
1849     case ITE_SPECIAL:
1850       table->finalize(special_desc(table->desc[i].ptr), ITE_SPECIAL);
1851       safe_free(special_desc(table->desc[i].ptr));
1852       break;
1853 
1854     case ARITH_CONSTANT:
1855       // Free the rational
1856       q_clear(&table->desc[i].rational);
1857       break;
1858 
1859     case ARITH_POLY:
1860       free_polynomial(table->desc[i].ptr);
1861       break;
1862 
1863     case BV64_POLY:
1864       free_bvpoly64(table->desc[i].ptr);
1865       break;
1866 
1867     case BV_POLY:
1868       free_bvpoly(table->desc[i].ptr);
1869       break;
1870 
1871     default:
1872       assert(false);
1873       break;
1874     }
1875   }
1876 }
1877 
1878 
1879 
1880 /*
1881  * Delete table
1882  */
delete_term_table(term_table_t * table)1883 void delete_term_table(term_table_t *table) {
1884   delete_name_table(&table->ntbl);
1885   delete_term_descriptors(table);
1886   delete_int_hmap(&table->utbl);
1887   delete_int_htbl(&table->htbl);
1888   delete_stbl(&table->stbl);
1889 
1890   delete_ivector(&table->ibuffer);
1891   delete_pvector(&table->pbuffer);
1892 
1893   safe_free(table->kind);
1894   safe_free(table->type);
1895   safe_free(table->desc);
1896   delete_bitvector(table->mark);
1897 
1898   table->kind = NULL;
1899   table->type = NULL;
1900   table->desc = NULL;
1901   table->mark = NULL;
1902 
1903 
1904 }
1905 
1906 
1907 /*
1908  * RESET
1909  */
1910 
1911 /*
1912  * Reset the name table: first call decref on all strings
1913  */
reset_name_table(ptr_hmap_t * table)1914 static void reset_name_table(ptr_hmap_t *table) {
1915   ptr_hmap_pair_t *p;
1916 
1917   p = ptr_hmap_first_record(table);
1918   while (p != NULL) {
1919     assert(p->val != NULL);
1920     string_decref(p->val);
1921     p = ptr_hmap_next_record(table, p);
1922   }
1923   ptr_hmap_reset(table);
1924 }
1925 
1926 
1927 /*
1928  * Full reset: delete all terms, reset the symbol table,
1929  * and all internal structures.
1930  */
reset_term_table(term_table_t * table)1931 void reset_term_table(term_table_t *table) {
1932   reset_name_table(&table->ntbl);
1933   delete_term_descriptors(table);
1934   int_hmap_reset(&table->utbl);
1935   reset_int_htbl(&table->htbl);
1936   reset_stbl(&table->stbl);
1937 
1938   ivector_reset(&table->ibuffer);
1939   pvector_reset(&table->pbuffer);
1940 
1941   table->nelems = 0;
1942   table->free_idx = -1;
1943   table->live_terms = 0;
1944 
1945   add_primitive_terms(table);
1946 }
1947 
1948 
1949 /*
1950  * TYPE COMPUTATIONS
1951  */
1952 
1953 /*
1954  * Type of (tuple arg[0] ... arg[n-1])
1955  */
type_of_tuple(term_table_t * table,uint32_t n,const term_t arg[])1956 static type_t type_of_tuple(term_table_t *table, uint32_t n, const term_t arg[]) {
1957   int32_t *v;
1958   type_t tau;
1959   uint32_t j;
1960 
1961   // build the type using ibuffer
1962   assert(table->ibuffer.size == 0);
1963   resize_ivector(&table->ibuffer, n);
1964   v = table->ibuffer.data;
1965   for (j=0; j<n; j++) {
1966     v[j] = term_type(table, arg[j]);
1967   }
1968   tau = tuple_type(table->types, n, v);
1969 
1970   ivector_reset(&table->ibuffer);
1971 
1972   return tau;
1973 }
1974 
1975 /*
1976  * Type of (lambda v[0] ... v[n-1] t)
1977  */
type_of_lambda(term_table_t * table,uint32_t n,const term_t * v,term_t t)1978 static type_t type_of_lambda(term_table_t *table, uint32_t n, const term_t *v, term_t t) {
1979   int32_t *dom;
1980   type_t tau;
1981   uint32_t j;
1982 
1983   // use ibuffer;
1984   assert(table->ibuffer.size == 0);
1985   resize_ivector(&table->ibuffer, n);
1986   dom = table->ibuffer.data;
1987   for (j=0; j<n; j++) {
1988     dom[j] = term_type(table, v[j]);
1989   }
1990   tau = term_type(table, t); // range type
1991   tau = function_type(table->types, tau, n, dom);
1992 
1993   ivector_reset(&table->ibuffer);
1994 
1995   return tau;
1996 }
1997 
1998 
1999 /*
2000  * Power product r
2001  * - r must not be a tagged variable or empty_pp or end_pp
2002  * - we assume r is well formed:
2003  *   either all variables of r are bitvectors of the same type
2004  *   or all variables of r are integer or real.
2005  * - type of r = int if all variables are integer
2006  *             = real if one variable is real
2007  *             = type of the first variable otherwise
2008  */
type_of_pprod(term_table_t * table,pprod_t * r)2009 static type_t type_of_pprod(term_table_t *table, pprod_t *r) {
2010   uint32_t i, n;
2011   type_t tau;
2012 
2013   n = r->len;
2014   tau = term_type(table, r->prod[0].var);
2015 
2016   if (is_integer_type(tau)) {
2017     // check whether all variables of r are integer
2018     for (i=1; i<n; i++) {
2019       tau = term_type(table, r->prod[i].var);
2020       if (! is_integer_type(tau)) break;
2021     }
2022   }
2023 
2024   return tau;
2025 }
2026 
2027 
2028 
2029 
2030 /*
2031  * TERM CONSTRUCTORS
2032  */
2033 
2034 /*
2035  * Constant of the given type and index.
2036  * - tau must be uninterpreted or scalar
2037  * - if tau is scalar of cardinality n, then index must be between 0 and n-1
2038  */
constant_term(term_table_t * table,type_t tau,int32_t index)2039 term_t constant_term(term_table_t *table, type_t tau, int32_t index) {
2040   int32_t i;
2041   integer_term_hobj_t integer_hobj;
2042 
2043   integer_hobj.m.hash = (hobj_hash_t) hash_integer_hobj;
2044   integer_hobj.m.eq = (hobj_eq_t) eq_integer_hobj;
2045   integer_hobj.m.build = (hobj_build_t) build_integer_hobj;
2046   integer_hobj.tbl = table;
2047   integer_hobj.tag = CONSTANT_TERM;
2048   integer_hobj.tau = tau;
2049   integer_hobj.id = index;
2050 
2051   i = int_htbl_get_obj(&table->htbl, &integer_hobj.m);
2052 
2053   return pos_term(i);
2054 }
2055 
2056 
2057 /*
2058  * Declare a new uninterpreted constant of type tau.
2059  * - this always creates a fresh term
2060  */
new_uninterpreted_term(term_table_t * table,type_t tau)2061 term_t new_uninterpreted_term(term_table_t *table, type_t tau) {
2062   int32_t i;
2063 
2064   i = allocate_term_id(table);
2065   table->kind[i] = UNINTERPRETED_TERM;
2066   table->type[i] = tau;
2067   table->desc[i].ptr = NULL;
2068 
2069   return pos_term(i);
2070 }
2071 
2072 
2073 /*
2074  * New variable of type tau.
2075  * - create a fresh term
2076  */
new_variable(term_table_t * table,type_t tau)2077 term_t new_variable(term_table_t *table, type_t tau) {
2078   int32_t i;
2079 
2080   i = allocate_term_id(table);
2081   table->kind[i] = VARIABLE;
2082   table->type[i] = tau;
2083   table->desc[i].integer = i;
2084 
2085   return pos_term(i);
2086 }
2087 
2088 
2089 
2090 /*
2091  * Negation: just flip the polarity bit
2092  * - p must be boolean
2093  */
not_term(term_table_t * table,term_t p)2094 term_t not_term(term_table_t *table, term_t p) {
2095   assert(is_boolean_term(table, p));
2096   return opposite_term(p);
2097 }
2098 
2099 
2100 /*
2101  * Check whether (ite ? left right) should be a special if-then-else:
2102  * - i.e., left and right are both constant or special.
2103  */
special_or_constant(term_kind_t tag)2104 static bool special_or_constant(term_kind_t tag) {
2105   return tag == ITE_SPECIAL || is_const_kind(tag);
2106 }
2107 
make_special_ite(term_table_t * table,term_t left,term_t right)2108 static bool make_special_ite(term_table_t *table, term_t left, term_t right) {
2109   return special_or_constant(term_kind(table, left)) && special_or_constant(term_kind(table, right));
2110 }
2111 
2112 
2113 /*
2114  * If-then-else term (if cond then left else right)
2115  * - tau must be the super type of left/right.
2116  * - if left and right are both constant or special if-then-else
2117  *   we build a special if-then-else term.
2118  */
ite_term(term_table_t * table,type_t tau,term_t cond,term_t left,term_t right)2119 term_t ite_term(term_table_t *table, type_t tau, term_t cond, term_t left, term_t right) {
2120   term_t aux[3];
2121   int32_t i;
2122 
2123   aux[0] = cond;
2124   aux[1] = left;
2125   aux[2] = right;
2126 
2127   if (make_special_ite(table, left, right)) {
2128     composite_term_hobj_t special_hobj;
2129 
2130     special_hobj.m.hash = (hobj_hash_t) hash_composite_hobj;
2131     special_hobj.m.eq = (hobj_eq_t) eq_composite_hobj;
2132     special_hobj.m.build = (hobj_build_t) build_special_hobj;
2133     special_hobj.tbl = table;
2134     special_hobj.tag = ITE_SPECIAL;
2135     special_hobj.tau = tau;
2136     special_hobj.arity = 3;
2137     special_hobj.arg = aux;
2138 
2139     i = int_htbl_get_obj(&table->htbl, &special_hobj.m);
2140 
2141   } else {
2142     composite_term_hobj_t composite_hobj;
2143 
2144     composite_hobj.m.hash = (hobj_hash_t) hash_composite_hobj;
2145     composite_hobj.m.eq = (hobj_eq_t) eq_composite_hobj;
2146     composite_hobj.m.build = (hobj_build_t) build_composite_hobj;
2147     composite_hobj.tbl = table;
2148     composite_hobj.tag = ITE_TERM;
2149     composite_hobj.tau = tau;
2150     composite_hobj.arity = 3;
2151     composite_hobj.arg = aux;
2152 
2153     i = int_htbl_get_obj(&table->htbl, &composite_hobj.m);
2154   }
2155 
2156   return pos_term(i);
2157 }
2158 
2159 
2160 /*
2161  * Function application: (fun arg[0] ... arg[n-1])
2162  */
app_term(term_table_t * table,term_t fun,uint32_t n,const term_t arg[])2163 term_t app_term(term_table_t *table, term_t fun, uint32_t n, const term_t arg[]) {
2164   type_t tau;
2165   int32_t i;
2166   app_term_hobj_t app_hobj;
2167 
2168   tau = term_type(table, fun);
2169 
2170   app_hobj.m.hash = (hobj_hash_t) hash_app_hobj;
2171   app_hobj.m.eq = (hobj_eq_t) eq_app_hobj;
2172   app_hobj.m.build = (hobj_build_t) build_app_hobj;
2173   app_hobj.tbl = table;
2174   app_hobj.tau = function_type_range(table->types, tau); // range of fun
2175   app_hobj.f = fun;
2176   app_hobj.n = n;
2177   app_hobj.arg = arg;
2178 
2179   i = int_htbl_get_obj(&table->htbl, &app_hobj.m);
2180 
2181   return pos_term(i);
2182 }
2183 
2184 
2185 /*
2186  * Function update: (update fun arg[0] ... arg[n-1] new_v)
2187  * - new_v must be in the range of fun (not in a supertype)
2188  * - the result has the same type as fun
2189  */
update_term(term_table_t * table,term_t fun,uint32_t n,const term_t arg[],term_t new_v)2190 term_t update_term(term_table_t *table, term_t fun, uint32_t n, const term_t arg[], term_t new_v) {
2191   type_t tau;
2192   int32_t i;
2193   update_term_hobj_t update_hobj;
2194 
2195   tau = term_type(table, fun);
2196 
2197   update_hobj.m.hash = (hobj_hash_t) hash_update_hobj;
2198   update_hobj.m.eq = (hobj_eq_t) eq_update_hobj;
2199   update_hobj.m.build = (hobj_build_t) build_update_hobj;
2200   update_hobj.tbl = table;
2201   update_hobj.tau = tau;
2202   update_hobj.f = fun;
2203   update_hobj.v = new_v;
2204   update_hobj.n = n;
2205   update_hobj.arg = arg;
2206 
2207   i = int_htbl_get_obj(&table->htbl, &update_hobj.m);
2208 
2209   return pos_term(i);
2210 }
2211 
2212 
2213 /*
2214  * (tuple arg[0] .. arg[n-1])
2215  */
tuple_term(term_table_t * table,uint32_t n,const term_t arg[])2216 term_t tuple_term(term_table_t *table, uint32_t n, const term_t arg[]) {
2217   int32_t i;
2218   composite_term_hobj_t composite_hobj;
2219 
2220   composite_hobj.m.hash = (hobj_hash_t) hash_composite_hobj;
2221   composite_hobj.m.eq = (hobj_eq_t) eq_composite_hobj;
2222   composite_hobj.m.build = (hobj_build_t) build_composite_hobj;
2223   composite_hobj.tbl = table;
2224   composite_hobj.tag = TUPLE_TERM;
2225   composite_hobj.tau = type_of_tuple(table, n, arg);
2226   composite_hobj.arity = n;
2227   composite_hobj.arg = arg;
2228 
2229   i = int_htbl_get_obj(&table->htbl, &composite_hobj.m);
2230 
2231   return pos_term(i);
2232 }
2233 
2234 
2235 /*
2236  * Tuple projection (select index tuple)
2237  */
select_term(term_table_t * table,uint32_t index,term_t tuple)2238 term_t select_term(term_table_t *table, uint32_t index, term_t tuple) {
2239   type_t tau;
2240   int32_t i;
2241   select_term_hobj_t select_hobj;
2242 
2243   tau = term_type(table, tuple);
2244 
2245   select_hobj.m.hash = (hobj_hash_t) hash_select_hobj;
2246   select_hobj.m.eq = (hobj_eq_t) eq_select_hobj;
2247   select_hobj.m.build = (hobj_build_t) build_select_hobj;
2248   select_hobj.tbl = table;
2249   select_hobj.tag = SELECT_TERM;
2250   select_hobj.tau = tuple_type_component(table->types, tau, index);;
2251   select_hobj.k = index;
2252   select_hobj.arg = tuple;
2253 
2254   i = int_htbl_get_obj(&table->htbl, &select_hobj.m);
2255 
2256   return pos_term(i);
2257 }
2258 
2259 
2260 /*
2261  * Binary term defined by (tag, tau, left, right)
2262  */
binary_term(term_table_t * table,term_kind_t tag,type_t tau,term_t left,term_t right)2263 static term_t binary_term(term_table_t *table, term_kind_t tag, type_t tau, term_t left, term_t right) {
2264   term_t aux[2];
2265   int32_t i;
2266   composite_term_hobj_t composite_hobj;
2267 
2268   aux[0] = left;
2269   aux[1] = right;
2270 
2271   composite_hobj.m.hash = (hobj_hash_t) hash_composite_hobj;
2272   composite_hobj.m.eq = (hobj_eq_t) eq_composite_hobj;
2273   composite_hobj.m.build = (hobj_build_t) build_composite_hobj;
2274   composite_hobj.tbl = table;
2275   composite_hobj.tag = tag;
2276   composite_hobj.tau = tau;
2277   composite_hobj.arity = 2;
2278   composite_hobj.arg = aux;
2279 
2280   i = int_htbl_get_obj(&table->htbl, &composite_hobj.m);
2281 
2282   return pos_term(i);
2283 }
2284 
2285 
2286 /*
2287  * One-argument term: defined by (tag, tau, t)
2288  */
unary_term(term_table_t * table,term_kind_t tag,type_t tau,term_t t)2289 static term_t unary_term(term_table_t *table, term_kind_t tag, type_t tau, term_t t) {
2290   int32_t i;
2291   integer_term_hobj_t integer_hobj;
2292 
2293   integer_hobj.m.hash = (hobj_hash_t) hash_integer_hobj;
2294   integer_hobj.m.eq = (hobj_eq_t) eq_integer_hobj;
2295   integer_hobj.m.build = (hobj_build_t) build_integer_hobj;
2296   integer_hobj.tbl = table;
2297   integer_hobj.tag = tag;
2298   integer_hobj.tau = tau;
2299   integer_hobj.id = t;
2300 
2301   i = int_htbl_get_obj(&table->htbl, &integer_hobj.m);
2302 
2303   return pos_term(i);
2304 }
2305 
2306 
2307 /*
2308  * Equality (eq left right)
2309  */
eq_term(term_table_t * table,term_t left,term_t right)2310 term_t eq_term(term_table_t *table, term_t left, term_t right) {
2311   return binary_term(table, EQ_TERM, bool_type(table->types), left, right);
2312 }
2313 
2314 
2315 /*
2316  * (distinct arg[0] ... arg[n-1])
2317  */
distinct_term(term_table_t * table,uint32_t n,const term_t arg[])2318 term_t distinct_term(term_table_t *table, uint32_t n, const term_t arg[]) {
2319   int32_t i;
2320   composite_term_hobj_t composite_hobj;
2321 
2322   composite_hobj.m.hash = (hobj_hash_t) hash_composite_hobj;
2323   composite_hobj.m.eq = (hobj_eq_t) eq_composite_hobj;
2324   composite_hobj.m.build = (hobj_build_t) build_composite_hobj;
2325   composite_hobj.tbl = table;
2326   composite_hobj.tag = DISTINCT_TERM;
2327   composite_hobj.tau = bool_type(table->types);
2328   composite_hobj.arity = n;
2329   composite_hobj.arg = arg;
2330 
2331   i = int_htbl_get_obj(&table->htbl, &composite_hobj.m);
2332 
2333   return pos_term(i);
2334 }
2335 
2336 
2337 /*
2338  * (forall var[0] ... var[n-1] body)
2339  */
forall_term(term_table_t * table,uint32_t n,const term_t var[],term_t body)2340 term_t forall_term(term_table_t *table, uint32_t n, const term_t var[], term_t body) {
2341   int32_t i;
2342   forall_term_hobj_t forall_hobj;
2343 
2344   forall_hobj.m.hash = (hobj_hash_t) hash_forall_hobj;
2345   forall_hobj.m.eq = (hobj_eq_t) eq_forall_hobj;
2346   forall_hobj.m.build = (hobj_build_t) build_forall_hobj;
2347   forall_hobj.tbl = table;
2348   forall_hobj.p = body;
2349   forall_hobj.n = n;
2350   forall_hobj.v = var;
2351 
2352   i = int_htbl_get_obj(&table->htbl, &forall_hobj.m);
2353 
2354   return pos_term(i);
2355 }
2356 
2357 
2358 /*
2359  * (lambda var[0] ... var[n-1] body)
2360  */
lambda_term(term_table_t * table,uint32_t n,const term_t var[],term_t body)2361 term_t lambda_term(term_table_t *table, uint32_t n, const term_t var[], term_t body) {
2362   int32_t i;
2363   lambda_term_hobj_t lambda_hobj;
2364 
2365   lambda_hobj.m.hash = (hobj_hash_t) hash_lambda_hobj;
2366   lambda_hobj.m.eq = (hobj_eq_t) eq_lambda_hobj;
2367   lambda_hobj.m.build = (hobj_build_t) build_lambda_hobj;
2368   lambda_hobj.tbl = table;
2369   lambda_hobj.tau = type_of_lambda(table, n, var, body);
2370   lambda_hobj.t = body;
2371   lambda_hobj.n = n;
2372   lambda_hobj.v = var;
2373 
2374   i = int_htbl_get_obj(&table->htbl, &lambda_hobj.m);
2375 
2376   return pos_term(i);
2377 }
2378 
2379 
2380 /*
2381  * (or arg[0] ... arg[n-1])
2382  */
or_term(term_table_t * table,uint32_t n,const term_t arg[])2383 term_t or_term(term_table_t *table, uint32_t n, const term_t arg[]) {
2384   int32_t i;
2385   composite_term_hobj_t composite_hobj;
2386 
2387   composite_hobj.m.hash = (hobj_hash_t) hash_composite_hobj;
2388   composite_hobj.m.eq = (hobj_eq_t) eq_composite_hobj;
2389   composite_hobj.m.build = (hobj_build_t) build_composite_hobj;
2390   composite_hobj.tbl = table;
2391   composite_hobj.tag = OR_TERM;
2392   composite_hobj.tau = bool_type(table->types);
2393   composite_hobj.arity = n;
2394   composite_hobj.arg = arg;
2395 
2396   i = int_htbl_get_obj(&table->htbl, &composite_hobj.m);
2397 
2398   return pos_term(i);
2399 }
2400 
2401 
2402 /*
2403  * (xor arg[0] ... arg[n-1])
2404  */
xor_term(term_table_t * table,uint32_t n,const term_t arg[])2405 term_t xor_term(term_table_t *table, uint32_t n, const term_t arg[]) {
2406   int32_t i;
2407   composite_term_hobj_t composite_hobj;
2408 
2409   composite_hobj.m.hash = (hobj_hash_t) hash_composite_hobj;
2410   composite_hobj.m.eq = (hobj_eq_t) eq_composite_hobj;
2411   composite_hobj.m.build = (hobj_build_t) build_composite_hobj;
2412   composite_hobj.tbl = table;
2413   composite_hobj.tag = XOR_TERM;
2414   composite_hobj.tau = bool_type(table->types);
2415   composite_hobj.arity = n;
2416   composite_hobj.arg = arg;
2417 
2418   i = int_htbl_get_obj(&table->htbl, &composite_hobj.m);
2419 
2420   return pos_term(i);
2421 }
2422 
2423 
2424 /*
2425  * Bit-select: get bit k of bit-vector bv
2426  */
bit_term(term_table_t * table,uint32_t k,term_t bv)2427 term_t bit_term(term_table_t *table, uint32_t k, term_t bv) {
2428   int32_t i;
2429   select_term_hobj_t select_hobj;
2430 
2431   select_hobj.m.hash = (hobj_hash_t) hash_select_hobj;
2432   select_hobj.m.eq = (hobj_eq_t) eq_select_hobj;
2433   select_hobj.m.build = (hobj_build_t) build_select_hobj;
2434   select_hobj.tbl = table;
2435   select_hobj.tag = BIT_TERM;
2436   select_hobj.tau = bool_type(table->types);
2437   select_hobj.k = k;
2438   select_hobj.arg = bv;
2439 
2440   i = int_htbl_get_obj(&table->htbl, &select_hobj.m);
2441 
2442   return pos_term(i);
2443 }
2444 
2445 
2446 /*
2447  * Power product: r must be valid in table->ptbl, and must not be a tagged
2448  * variable or empty_pp.
2449  * - each variable index x_i in r must be a term defined in table
2450  * - the x_i's must have compatible types: either they are all arithmetic
2451  *   terms (type int or real) or they are all bit-vector terms of the
2452  *   same type.
2453  * The type of the result is determined from the x_i's types:
2454  * - if all x_i's are int, the result is int
2455  * - if some x_i's are int, some are real, the result is real
2456  * - if all x_i's have type (bitvector k), the result has type (bitvector k)
2457  */
pprod_term(term_table_t * table,pprod_t * r)2458 term_t pprod_term(term_table_t *table, pprod_t *r) {
2459   int32_t i;
2460   pprod_term_hobj_t pprod_hobj;
2461 
2462   pprod_hobj.m.hash = (hobj_hash_t) hash_pprod_hobj;
2463   pprod_hobj.m.eq = (hobj_eq_t) eq_pprod_hobj;
2464   pprod_hobj.m.build = (hobj_build_t) build_pprod_hobj;
2465   pprod_hobj.tbl = table;
2466   pprod_hobj.tau = type_of_pprod(table, r);
2467   pprod_hobj.r = r;
2468 
2469   i = int_htbl_get_obj(&table->htbl, &pprod_hobj.m);
2470 
2471   return pos_term(i);
2472 }
2473 
2474 
2475 /*
2476  * Rational constant: the result has type int if a is an integer or real otherwise
2477  */
arith_constant(term_table_t * table,rational_t * a)2478 term_t arith_constant(term_table_t *table, rational_t *a) {
2479   type_t tau;
2480   int32_t i;
2481   rational_term_hobj_t rational_hobj;
2482 
2483   tau = real_type(table->types);
2484   if (q_is_integer(a)) {
2485     tau = int_type(table->types);
2486   }
2487 
2488   rational_hobj.m.hash = (hobj_hash_t) hash_rational_hobj;
2489   rational_hobj.m.eq = (hobj_eq_t) eq_rational_hobj;
2490   rational_hobj.m.build = (hobj_build_t) build_rational_hobj;
2491   rational_hobj.tbl = table;
2492   rational_hobj.tag = ARITH_CONSTANT;
2493   rational_hobj.tau = tau;
2494   rational_hobj.a = a;
2495 
2496   i = int_htbl_get_obj(&table->htbl, &rational_hobj.m);
2497 
2498   return pos_term(i);
2499 }
2500 
2501 
2502 /*
2503  * Atom t == 0 for an arithmetic term t
2504  */
arith_eq_atom(term_table_t * table,term_t t)2505 term_t arith_eq_atom(term_table_t *table, term_t t) {
2506   return unary_term(table, ARITH_EQ_ATOM, bool_type(table->types), t);
2507 }
2508 
2509 
2510 /*
2511  * Atom (t >= 0) for an arithmetic term t
2512  */
arith_geq_atom(term_table_t * table,term_t t)2513 term_t arith_geq_atom(term_table_t *table, term_t t) {
2514   return unary_term(table, ARITH_GE_ATOM, bool_type(table->types), t);
2515 }
2516 
2517 
2518 /*
2519  * Equality between two arithmetic terms (left == right)
2520  */
arith_bineq_atom(term_table_t * table,term_t left,term_t right)2521 term_t arith_bineq_atom(term_table_t *table, term_t left, term_t right) {
2522   return binary_term(table, ARITH_BINEQ_ATOM, bool_type(table->types), left, right);
2523 }
2524 
2525 
2526 /*
2527  * Test for integrality: (is_int x)
2528  */
arith_is_int(term_table_t * table,term_t x)2529 term_t arith_is_int(term_table_t *table, term_t x) {
2530   return unary_term(table, ARITH_IS_INT_ATOM, bool_type(table->types), x);
2531 }
2532 
2533 /*
2534  * Floor and ceiling: the result has type int
2535  */
arith_floor(term_table_t * table,term_t x)2536 term_t arith_floor(term_table_t *table, term_t x) {
2537   return unary_term(table, ARITH_FLOOR, int_type(table->types), x);
2538 }
2539 
arith_ceil(term_table_t * table,term_t x)2540 term_t arith_ceil(term_table_t *table, term_t x) {
2541   return unary_term(table, ARITH_CEIL, int_type(table->types), x);
2542 }
2543 
2544 /*
2545  * Absolute value: the result has the same type as x
2546  */
arith_abs(term_table_t * table,term_t x)2547 term_t arith_abs(term_table_t *table, term_t x) {
2548   type_t tau;
2549 
2550   tau = term_type(table, x);
2551   return unary_term(table, ARITH_ABS, tau, x);
2552 }
2553 
2554 /*
2555  * (div x y): the result has type int
2556  */
arith_idiv(term_table_t * table,term_t x,term_t y)2557 term_t arith_idiv(term_table_t *table, term_t x, term_t y) {
2558   return binary_term(table, ARITH_IDIV, int_type(table->types), x, y);
2559 }
2560 
2561 /*
2562  * (mod x y) = x - y * (div x y)
2563  * So the result has type int if both x and y are integers
2564  */
arith_mod(term_table_t * table,term_t x,term_t y)2565 term_t arith_mod(term_table_t *table, term_t x, term_t y) {
2566   type_t tau;
2567 
2568   tau = is_integer_term(table, x) ? term_type(table, y) : real_type(table->types);
2569   return binary_term(table, ARITH_MOD, tau, x, y);
2570 }
2571 
2572 /*
2573  * Test whether x divides y
2574  */
arith_divides(term_table_t * table,term_t x,term_t y)2575 term_t arith_divides(term_table_t *table, term_t x, term_t y) {
2576   return binary_term(table, ARITH_DIVIDES_ATOM, bool_type(table->types), x, y);
2577 }
2578 
2579 
2580 
2581 /*
2582  * Root constraint x r root_k(p).
2583  */
arith_root_atom(term_table_t * table,uint32_t k,term_t x,term_t p,root_atom_rel_t r)2584 term_t arith_root_atom(term_table_t *table, uint32_t k, term_t x, term_t p, root_atom_rel_t r) {
2585   int32_t i;
2586   root_atom_hobj_t root_atom_hobj;
2587 
2588   root_atom_hobj.m.hash = (hobj_hash_t) hash_root_atom_hobj;
2589   root_atom_hobj.m.eq = (hobj_eq_t) eq_root_atom_hobj;
2590   root_atom_hobj.m.build = (hobj_build_t) build_root_atom_hobj;
2591   root_atom_hobj.tbl = table;
2592   root_atom_hobj.k = k;
2593   root_atom_hobj.x = x;
2594   root_atom_hobj.p = p;
2595   root_atom_hobj.r = r;
2596 
2597   i = int_htbl_get_obj(&table->htbl, &root_atom_hobj.m);
2598 
2599   return pos_term(i);
2600 }
2601 
2602 
2603 /*
2604  * Real division: the result (/ x y) has type real
2605  */
arith_rdiv(term_table_t * table,term_t x,term_t y)2606 term_t arith_rdiv(term_table_t *table, term_t x, term_t y) {
2607   return binary_term(table, ARITH_RDIV, real_type(table->types), x, y);
2608 }
2609 
2610 
2611 /*
2612  * Small bitvector constant
2613  * - n = bitsize (must be between 1 and 64)
2614  * - bv = value (must be normalized modulo 2^n)
2615  */
bv64_constant(term_table_t * table,uint32_t n,uint64_t bv)2616 term_t bv64_constant(term_table_t *table, uint32_t n, uint64_t bv) {
2617   int32_t i;
2618   bvconst64_term_hobj_t bvconst64_hobj;
2619 
2620   bvconst64_hobj.m.hash = (hobj_hash_t) hash_bvconst64_hobj;
2621   bvconst64_hobj.m.eq = (hobj_eq_t) eq_bvconst64_hobj;
2622   bvconst64_hobj.m.build = (hobj_build_t) build_bvconst64_hobj;
2623   bvconst64_hobj.tbl = table;
2624   bvconst64_hobj.tau = bv_type(table->types, n);
2625   bvconst64_hobj.bitsize = n;
2626   bvconst64_hobj.v = bv;
2627 
2628   i = int_htbl_get_obj(&table->htbl, &bvconst64_hobj.m);
2629 
2630   return pos_term(i);
2631 }
2632 
2633 
2634 /*
2635  * Bitvector constant:
2636  * - n = bitsize
2637  * - bv = array of k words (where k = ceil(n/32))
2638  * The constant must be normalized (modulo 2^n)
2639  * This constructor should be used only for n > 64.
2640  */
bvconst_term(term_table_t * table,uint32_t n,const uint32_t * bv)2641 term_t bvconst_term(term_table_t *table, uint32_t n, const uint32_t *bv) {
2642   int32_t i;
2643   bvconst_term_hobj_t bvconst_hobj;
2644 
2645   bvconst_hobj.m.hash = (hobj_hash_t) hash_bvconst_hobj;
2646   bvconst_hobj.m.eq = (hobj_eq_t) eq_bvconst_hobj;
2647   bvconst_hobj.m.build = (hobj_build_t) build_bvconst_hobj;
2648   bvconst_hobj.tbl = table;
2649   bvconst_hobj.tau = bv_type(table->types, n);
2650   bvconst_hobj.bitsize = n;
2651   bvconst_hobj.v = bv;
2652 
2653   i = int_htbl_get_obj(&table->htbl, &bvconst_hobj.m);
2654 
2655   return pos_term(i);
2656 }
2657 
2658 
2659 /*
2660  * Bitvector formed of arg[0] ... arg[n-1]
2661  * - n must be positive and no more than YICES_MAX_BVSIZE
2662  * - arg[0] ... arg[n-1] must be boolean terms
2663  */
bvarray_term(term_table_t * table,uint32_t n,const term_t arg[])2664 term_t bvarray_term(term_table_t *table, uint32_t n, const term_t arg[]) {
2665   int32_t i;
2666   composite_term_hobj_t composite_hobj;
2667 
2668   composite_hobj.m.hash = (hobj_hash_t) hash_composite_hobj;
2669   composite_hobj.m.eq = (hobj_eq_t) eq_composite_hobj;
2670   composite_hobj.m.build = (hobj_build_t) build_composite_hobj;
2671   composite_hobj.tbl = table;
2672   composite_hobj.tag = BV_ARRAY;
2673   composite_hobj.tau = bv_type(table->types, n);
2674   composite_hobj.arity = n;
2675   composite_hobj.arg = arg;
2676 
2677   i = int_htbl_get_obj(&table->htbl, &composite_hobj.m);
2678 
2679   return pos_term(i);
2680 }
2681 
2682 
2683 
2684 /*
2685  * Division and shift operators
2686  * - the two arguments must be bitvector terms of the same type
2687  * - in the division/remainder operators, b is the divisor
2688  * - in the shift operator: a is the bitvector to be shifted
2689  *   and b is the shift amount
2690  * - in all cases, the result has the same type as a and b
2691  */
bvdiv_term(term_table_t * table,term_t a,term_t b)2692 term_t bvdiv_term(term_table_t *table, term_t a, term_t b) {
2693   return binary_term(table, BV_DIV, term_type(table, a), a, b);
2694 }
2695 
bvrem_term(term_table_t * table,term_t a,term_t b)2696 term_t bvrem_term(term_table_t *table, term_t a, term_t b) {
2697   return binary_term(table, BV_REM, term_type(table, a), a, b);
2698 }
2699 
bvsdiv_term(term_table_t * table,term_t a,term_t b)2700 term_t bvsdiv_term(term_table_t *table, term_t a, term_t b) {
2701   return binary_term(table, BV_SDIV, term_type(table, a), a, b);
2702 }
2703 
bvsrem_term(term_table_t * table,term_t a,term_t b)2704 term_t bvsrem_term(term_table_t *table, term_t a, term_t b) {
2705   return binary_term(table, BV_SREM, term_type(table, a), a, b);
2706 }
2707 
bvsmod_term(term_table_t * table,term_t a,term_t b)2708 term_t bvsmod_term(term_table_t *table, term_t a, term_t b) {
2709   return binary_term(table, BV_SMOD, term_type(table, a), a, b);
2710 }
2711 
bvshl_term(term_table_t * table,term_t a,term_t b)2712 term_t bvshl_term(term_table_t *table, term_t a, term_t b) {
2713   return binary_term(table, BV_SHL, term_type(table, a), a, b);
2714 }
2715 
bvlshr_term(term_table_t * table,term_t a,term_t b)2716 term_t bvlshr_term(term_table_t *table, term_t a, term_t b) {
2717   return binary_term(table, BV_LSHR, term_type(table, a), a, b);
2718 }
2719 
bvashr_term(term_table_t * table,term_t a,term_t b)2720 term_t bvashr_term(term_table_t *table, term_t a, term_t b) {
2721   return binary_term(table, BV_ASHR, term_type(table, a), a, b);
2722 }
2723 
2724 
2725 /*
2726  * Bitvector atoms: l and r must be bitvector terms of the same type
2727  *  (bveq l r): l == r
2728  *  (bvge l r): l >= r unsigned
2729  *  (bvsge l r): l >= r signed
2730  */
bveq_atom(term_table_t * table,term_t l,term_t r)2731 term_t bveq_atom(term_table_t *table, term_t l, term_t r) {
2732   return binary_term(table, BV_EQ_ATOM, bool_type(table->types), l, r);
2733 }
2734 
bvge_atom(term_table_t * table,term_t l,term_t r)2735 term_t bvge_atom(term_table_t *table, term_t l, term_t r) {
2736   return binary_term(table, BV_GE_ATOM, bool_type(table->types), l, r);
2737 }
2738 
bvsge_atom(term_table_t * table,term_t l,term_t r)2739 term_t bvsge_atom(term_table_t *table, term_t l, term_t r) {
2740   return binary_term(table, BV_SGE_ATOM, bool_type(table->types), l, r);
2741 }
2742 
2743 
2744 
2745 
2746 /*
2747  * POWER PRODUCT
2748  */
2749 
2750 /*
2751  * Power product built from a buffer b
2752  * - b must not be empty
2753  */
pprod_term_from_buffer(term_table_t * table,pp_buffer_t * b)2754 term_t pprod_term_from_buffer(term_table_t *table, pp_buffer_t *b) {
2755   pprod_t *r;
2756 
2757   r = pprod_from_buffer(table->pprods, b);
2758   assert(!pp_is_empty(r));
2759 
2760   if (pp_is_var(r)) {
2761     return var_of_pp(r);
2762   } else {
2763     return pprod_term(table, r);
2764   }
2765 }
2766 
2767 
2768 
2769 /*
2770  * POLYNOMIAL TERM CONSTRUCTORS
2771  */
2772 
2773 /*
2774  * Convert power product r to an equivalent integer index
2775  * - empty_pp --> const_idx
2776  * - tagged variable x --> x (x must be a term)
2777  * - otherwise, build a power product term t for r and return t
2778  */
poly_index_for_pprod(term_table_t * table,pprod_t * r)2779 static int32_t poly_index_for_pprod(term_table_t *table, pprod_t *r) {
2780   int32_t i;
2781 
2782   assert(r != end_pp);
2783 
2784   if (pp_is_empty(r)) {
2785     i = const_idx;
2786   } else if (pp_is_var(r)) {
2787     i = var_of_pp(r);
2788   } else {
2789     i = pprod_term(table, r);
2790   }
2791 
2792   return i;
2793 }
2794 
2795 
2796 /*
2797  * Check whether all terms in array v are integers
2798  * - skip const_idx if it's in v (it should be first)
2799  */
all_integer_terms(term_table_t * table,const term_t * v,uint32_t n)2800 static bool all_integer_terms(term_table_t *table, const term_t *v, uint32_t n) {
2801   uint32_t i;
2802 
2803   if (n > 0) {
2804     if (v[0] == const_idx) {
2805       v ++;
2806       n --;
2807     }
2808 
2809     for (i=0; i<n; i++) {
2810       assert(is_arithmetic_term(table, v[i]));
2811       if (is_real_term(table, v[i])) return false;
2812     }
2813   }
2814 
2815   return true;
2816 }
2817 
2818 
2819 /*
2820  * Auxiliary function: convert power products of subtree rooted at x
2821  * to term indices and check whether all coefficients are integer
2822  * - input: x = node in the buffer b
2823  *          i = number of nodes in the subtree at the left of x
2824  *          v = array to store conversion
2825  * - output: return i + number of nodes in the subtree rooted at x
2826  *   update *all_int so that it's true if all nodes in x have
2827  *   integer coefficients and *all_int was true on entry to the function
2828  *
2829  * So v[i] will store the conversion of the left-most monomial in x's subtree
2830  */
convert_rba_tree(term_table_t * table,rba_buffer_t * b,int32_t * v,bool * all_int,uint32_t i,uint32_t x)2831 static uint32_t convert_rba_tree(term_table_t *table, rba_buffer_t *b, int32_t *v, bool *all_int,
2832                                  uint32_t i, uint32_t x) {
2833   assert(x < b->num_nodes);
2834 
2835   if (x != rba_null) {
2836     i = convert_rba_tree(table, b, v, all_int, i, b->child[x][0]);
2837     assert(i < b->nterms);
2838     v[i] = poly_index_for_pprod(table, b->mono[x].prod);
2839     *all_int = *all_int && q_is_integer(&b->mono[x].coeff);
2840     i = convert_rba_tree(table, b, v, all_int, i+1, b->child[x][1]);
2841   }
2842 
2843   return i;
2844 }
2845 
2846 
2847 /*
2848  * Arithmetic term
2849  * - all variables of b must be real or integer terms defined in table
2850  * - b must be normalized and b->ptbl must be the same as table->ptbl
2851  * - if b contains a non-linear polynomial then the power products that
2852  *   occur in p are converted to terms (using pprod_term)
2853  * - then b is turned into a polynomial object a_1 x_1 + ... + a_n x_n,
2854  *   where x_i is a term.
2855  *
2856  * SIDE EFFECT: b is reset to zero
2857  */
arith_poly(term_table_t * table,rba_buffer_t * b)2858 term_t arith_poly(term_table_t *table, rba_buffer_t *b) {
2859   int32_t *v;
2860   type_t tau;
2861   int32_t i;
2862   bool all_int;
2863   uint32_t j, n;
2864   poly_term_hobj_t poly_hobj;
2865 
2866   assert(b->ptbl == table->pprods);
2867 
2868   n = b->nterms;
2869 
2870   /*
2871    * convert the power products to indices
2872    * store the result in ibuffer.
2873    * also check whether all coefficients are integer.
2874    */
2875   assert(table->ibuffer.size == 0);
2876 
2877   resize_ivector(&table->ibuffer, n + 1);
2878   v = table->ibuffer.data;
2879   all_int = true;
2880   j = convert_rba_tree(table, b, v, &all_int, 0, b->root);
2881   assert(j == n);
2882   v[j] = max_idx;
2883 
2884   // type of b: either int or real
2885   tau = real_type(table->types);
2886   if (all_int && all_integer_terms(table, v, n)) {
2887     tau = int_type(table->types);
2888   }
2889 
2890   // hash consing
2891   poly_hobj.m.hash = (hobj_hash_t) hash_poly_hobj;
2892   poly_hobj.m.eq = (hobj_eq_t) eq_poly_hobj;
2893   poly_hobj.m.build = (hobj_build_t) build_poly_hobj;
2894   poly_hobj.tbl = table;
2895   poly_hobj.tau = tau;
2896   poly_hobj.b = b;
2897   poly_hobj.v = v;
2898 
2899   i = int_htbl_get_obj(&table->htbl, &poly_hobj.m);
2900 
2901   // cleanup ibuffer
2902   ivector_reset(&table->ibuffer);
2903 
2904   return pos_term(i);
2905 }
2906 
2907 
2908 /*
2909  * Bitvector polynomials are constructed from a buffer b
2910  * - all variables of b must be bitvector terms defined in table
2911  * - b must be normalized and b->ptbl must be the same as table->ptbl
2912  * - if b contains non-linear terms, then the power products that
2913  *   occur in b are converted to terms (using pprod_term) then
2914  *   a polynomial object is created.
2915  *
2916  * SIDE EFFECT: b is reset to zero.
2917  */
bv64_poly(term_table_t * table,bvarith64_buffer_t * b)2918 term_t bv64_poly(term_table_t *table, bvarith64_buffer_t *b) {
2919   bvmlist64_t *q;
2920   int32_t *v;
2921   int32_t i;
2922   uint32_t j, n;
2923   bvpoly64_term_hobj_t bvpoly64_hobj;
2924 
2925   assert(b->ptbl == table->pprods);
2926 
2927   n = b->nterms;
2928 
2929   /*
2930    * Convert the power products.
2931    * Store the results in ibuffer.
2932    */
2933   assert(table->ibuffer.size == 0);
2934   resize_ivector(&table->ibuffer, n + 1);
2935   v = table->ibuffer.data;
2936   q = b->list;
2937   for (j=0; j<n; j++) {
2938     assert(q->next != NULL);
2939     v[j] = poly_index_for_pprod(table, q->prod);
2940     q = q->next;
2941   }
2942 
2943   assert(q->next == NULL && q->prod == end_pp);
2944   v[j] = max_idx;
2945 
2946   // hash consing
2947   bvpoly64_hobj.m.hash = (hobj_hash_t) hash_bvpoly64_hobj;
2948   bvpoly64_hobj.m.eq = (hobj_eq_t) eq_bvpoly64_hobj;
2949   bvpoly64_hobj.m.build = (hobj_build_t) build_bvpoly64_hobj ;
2950   bvpoly64_hobj.tbl = table;
2951   bvpoly64_hobj.tau = bv_type(table->types, b->bitsize);
2952   bvpoly64_hobj.b = b;
2953   bvpoly64_hobj.v = v;
2954 
2955   i = int_htbl_get_obj(&table->htbl, &bvpoly64_hobj.m);
2956 
2957   // cleanup ibuffer
2958   ivector_reset(&table->ibuffer);
2959 
2960   return pos_term(i);
2961 }
2962 
2963 
bv_poly(term_table_t * table,bvarith_buffer_t * b)2964 term_t bv_poly(term_table_t *table, bvarith_buffer_t *b) {
2965   bvmlist_t *q;
2966   int32_t *v;
2967   int32_t i;
2968   uint32_t j, n;
2969   bvpoly_term_hobj_t bvpoly_hobj;
2970 
2971   assert(b->ptbl == table->pprods);
2972 
2973   n = b->nterms;
2974 
2975   /*
2976    * Convert the power products.
2977    * Store the results in ibuffer.
2978    */
2979   assert(table->ibuffer.size == 0);
2980   resize_ivector(&table->ibuffer, n+1);
2981   v = table->ibuffer.data;
2982   q = b->list;
2983   for (j=0; j<n; j++) {
2984     assert(q->next != NULL);
2985     v[j] = poly_index_for_pprod(table, q->prod);
2986     q = q->next;
2987   }
2988 
2989   assert(q->next == NULL && q->prod == end_pp);
2990   v[j] = max_idx;
2991 
2992   // hash consing
2993   bvpoly_hobj.m.hash = (hobj_hash_t) hash_bvpoly_hobj;
2994   bvpoly_hobj.m.eq = (hobj_eq_t) eq_bvpoly_hobj;
2995   bvpoly_hobj.m.build = (hobj_build_t) build_bvpoly_hobj;
2996   bvpoly_hobj.tbl = table;
2997   bvpoly_hobj.tau = bv_type(table->types, b->bitsize);
2998   bvpoly_hobj.b = b;
2999   bvpoly_hobj.v = v;
3000 
3001   i = int_htbl_get_obj(&table->htbl, &bvpoly_hobj.m);
3002 
3003   // cleanup ibuffer
3004   ivector_reset(&table->ibuffer);
3005 
3006   return pos_term(i);
3007 }
3008 
3009 
3010 /*
3011  * Build/return a term equal to bvpoly_buffer b
3012  * - this works only for linear polynomials
3013  * - all variables of b must be terms defined in table
3014  * - b must be normalized
3015  * - b is not modified
3016  */
bv_poly_from_buffer(term_table_t * table,bvpoly_buffer_t * b)3017 term_t bv_poly_from_buffer(term_table_t *table, bvpoly_buffer_t *b) {
3018   int32_t i;
3019   bvpoly_buffer_hobj_t bvbuffer_hobj;
3020 
3021   bvbuffer_hobj.m.hash = (hobj_hash_t) hash_bvpoly_buffer_hobj;
3022   bvbuffer_hobj.m.eq = (hobj_eq_t) eq_bvpoly_buffer_hobj;
3023   bvbuffer_hobj.m.build = (hobj_build_t) build_bvpoly_buffer_hobj;
3024   bvbuffer_hobj.tbl = table;
3025   bvbuffer_hobj.tau = bv_type(table->types, b->bitsize);
3026   bvbuffer_hobj.b = b;
3027 
3028   i = int_htbl_get_obj(&table->htbl, &bvbuffer_hobj.m);
3029 
3030   return pos_term(i);
3031 }
3032 
3033 
3034 
3035 
3036 /**********************************
3037  *  CONVERSION TO POWER PRODUCTS  *
3038  *********************************/
3039 
3040 /*
3041  * Convert term t to a power product:
3042  * - t must be a term (not a term index) present in the table
3043  */
pprod_for_term(const term_table_t * table,term_t t)3044 pprod_t *pprod_for_term(const term_table_t *table, term_t t) {
3045   pprod_t *r;
3046   int32_t i;
3047 
3048   assert(is_pos_term(t) && good_term(table, t));
3049   assert(is_arithmetic_term(table, t) || is_bitvector_term(table, t));
3050 
3051   r = var_pp(t);
3052   i = index_of(t);
3053   if (table->kind[i] == POWER_PRODUCT) {
3054     r = table->desc[i].ptr;
3055   }
3056   return r;
3057 }
3058 
3059 
3060 /*
3061  * Degree of x where x = main variable of a polynomial
3062  */
main_var_degree(const term_table_t * table,int32_t x)3063 static uint32_t main_var_degree(const term_table_t *table, int32_t x) {
3064   uint32_t d;
3065 
3066   d = 1;
3067   if (x == const_idx) {
3068     d = 0;
3069   } else {
3070     assert(is_pos_term(x) && good_term(table, x));
3071     x = index_of(x);
3072     if (table->kind[x] == POWER_PRODUCT) {
3073       d = pprod_degree(table->desc[x].ptr);
3074     }
3075   }
3076 
3077   return d;
3078 }
3079 
3080 
3081 /*
3082  * Degree of term t
3083  * - t must be a good term of arithmetic or bitvector type
3084  */
term_degree(const term_table_t * table,term_t t)3085 uint32_t term_degree(const term_table_t *table, term_t t) {
3086   uint32_t d;
3087   int32_t i;
3088 
3089   assert(is_pos_term(t) && good_term(table, t));
3090   assert(is_arithmetic_term(table, t) || is_bitvector_term(table, t));
3091 
3092   d = 1;
3093   i = index_of(t);
3094   switch (table->kind[i]) {
3095   case POWER_PRODUCT:
3096     d = pprod_degree(table->desc[i].ptr);
3097     break;
3098 
3099   case ARITH_CONSTANT:
3100   case BV64_CONSTANT:
3101   case BV_CONSTANT:
3102     d = 0;
3103     break;
3104 
3105   case ARITH_POLY:
3106     d = main_var_degree(table, polynomial_main_var(table->desc[i].ptr));
3107     break;
3108 
3109   case BV64_POLY:
3110     d = main_var_degree(table, bvpoly64_main_var(table->desc[i].ptr));
3111     break;
3112 
3113   case BV_POLY:
3114     d = main_var_degree(table, bvpoly_main_var(table->desc[i].ptr));
3115     break;
3116   }
3117 
3118   return d;
3119 }
3120 
3121 
3122 /*
3123  * Check whether x has degree 0 or 1 (i.e., x is not a power product)
3124  */
not_pprod(const term_table_t * table,int32_t x)3125 static bool not_pprod(const term_table_t *table, int32_t x) {
3126   assert(is_pos_term(x) && good_term(table, x));
3127   return table->kind[index_of(x)] != POWER_PRODUCT;
3128 }
3129 
3130 /*
3131  * Check whether t is a linear polynomial:
3132  * - t must be a good term of arithmetic or bitvector type.
3133  * - returns true if t has tag ARITH_POLY/BV64_POLY or BV_POLY
3134  *   and if no monomial of t is a power product.
3135  * - this implies that t has degree 1.
3136  */
is_linear_poly(const term_table_t * table,term_t t)3137 bool is_linear_poly(const term_table_t *table, term_t t) {
3138   int32_t i;
3139   bool result;
3140 
3141   assert(is_pos_term(t) && good_term(table, t));
3142   assert(is_arithmetic_term(table, t) || is_bitvector_term(table, t));
3143 
3144   result = false;
3145   i = index_of(t);
3146   switch (table->kind[i]) {
3147   case ARITH_POLY:
3148     result = not_pprod(table, polynomial_main_var(table->desc[i].ptr));
3149     break;
3150 
3151   case BV64_POLY:
3152     result = not_pprod(table, bvpoly64_main_var(table->desc[i].ptr));
3153     break;
3154 
3155   case BV_POLY:
3156     result = not_pprod(table, bvpoly_main_var(table->desc[i].ptr));
3157     break;
3158 
3159   default:
3160     break;
3161   }
3162 
3163   return result;
3164 }
3165 
3166 
3167 /*
3168  * Convert all variables of p to power products
3169  * - store the result in table->pbuffer
3170  * - return the array of power products
3171  */
pprods_for_bvpoly64(term_table_t * table,const bvpoly64_t * p)3172 pprod_t **pprods_for_bvpoly64(term_table_t *table, const bvpoly64_t *p) {
3173   uint32_t i, n;
3174   void **v;
3175 
3176   n = p->nterms;
3177   resize_pvector(&table->pbuffer, n+1);
3178   v = table->pbuffer.data;
3179   i = 0;
3180 
3181   // the constant is first in p
3182   if (p->mono[0].var == const_idx) {
3183     v[0] = empty_pp;
3184     i = 1;
3185   }
3186 
3187   // rest of p
3188   while (i < n) {
3189     v[i] = pprod_for_term(table, p->mono[i].var);
3190     i ++;
3191   }
3192   // end marker
3193   assert(p->mono[i].var == max_idx);
3194   v[i] = end_pp;
3195 
3196   return (pprod_t **) v;
3197 }
3198 
3199 
3200 /*
3201  * Convert all variables of p to power products
3202  * - store the result in table->pbuffer
3203  * - return the array of power products
3204  */
pprods_for_bvpoly(term_table_t * table,const bvpoly_t * p)3205 pprod_t **pprods_for_bvpoly(term_table_t *table, const bvpoly_t *p) {
3206   uint32_t i, n;
3207   void **v;
3208 
3209   n = p->nterms;
3210   resize_pvector(&table->pbuffer, n+1);
3211   v = table->pbuffer.data;
3212   i = 0;
3213 
3214   // the constant is first in p
3215   if (p->mono[0].var == const_idx) {
3216     v[0] = empty_pp;
3217     i = 1;
3218   }
3219 
3220   // rest of p
3221   while (i < n) {
3222     v[i] = pprod_for_term(table, p->mono[i].var);
3223     i ++;
3224   }
3225   // end marker
3226   assert(p->mono[i].var == max_idx);
3227   v[i] = end_pp;
3228 
3229   return (pprod_t **) v;
3230 }
3231 
3232 
3233 /*
3234  * CHECKS ON TERMS
3235  */
3236 
3237 /*
3238  * Good term: valid descriptor + polarity = 0 unless
3239  * t is a Boolean term.
3240  */
good_term(const term_table_t * table,term_t t)3241 bool good_term(const term_table_t *table, term_t t) {
3242   return good_term_idx(table, index_of(t)) &&
3243     (is_pos_term(t) || type_for_idx(table, index_of(t)) == bool_id);
3244 }
3245 
3246 /*
3247  * Convert all variables of p to power products
3248  * - store the result in table->pbuffer
3249  * - return the array of power products
3250  */
pprods_for_poly(term_table_t * table,const polynomial_t * p)3251 pprod_t **pprods_for_poly(term_table_t *table, const polynomial_t *p) {
3252   uint32_t i, n;
3253   void **v;
3254 
3255   n = p->nterms;
3256   resize_pvector(&table->pbuffer, n+1);
3257   v = table->pbuffer.data;
3258   i = 0;
3259 
3260   // the constant is first in p
3261   if (p->mono[0].var == const_idx) {
3262     v[0] = empty_pp;
3263     i = 1;
3264   }
3265 
3266   // rest of p
3267   while (i < n) {
3268     v[i] = pprod_for_term(table, p->mono[i].var);
3269     i ++;
3270   }
3271   // end marker
3272   assert(p->mono[i].var == max_idx);
3273   v[i] = end_pp;
3274 
3275   return (pprod_t **) v;
3276 }
3277 
3278 
3279 /***************************
3280  *  TYPE CHECKING SUPPORT  *
3281  **************************/
3282 
3283 /*
3284  * Wrapper function: check whether x has integer type
3285  */
var_is_int(void * aux,int32_t x)3286 static bool var_is_int(void *aux, int32_t x) {
3287   term_table_t *table;
3288 
3289   table = aux;
3290   return is_integer_type(term_type(table, x));
3291 }
3292 
3293 /*
3294  * Check whether b stores an integer polynomial
3295  */
arith_poly_is_integer(const term_table_t * table,rba_buffer_t * b)3296 bool arith_poly_is_integer(const term_table_t *table, rba_buffer_t *b) {
3297   return rba_buffer_is_int(b, (void*) table, var_is_int);
3298 }
3299 
3300 
3301 
3302 /*******************************
3303  *  CHECKS ON ATOMS/LITERALS   *
3304  ******************************/
3305 
3306 /*
3307  * Check whether t is an arithmetic literal (i.e., arithmetic atom
3308  * or the negation of an arithmetic atom).
3309  */
is_arithmetic_literal(const term_table_t * table,term_t t)3310 bool is_arithmetic_literal(const term_table_t *table, term_t t) {
3311   switch (term_kind(table, t)) {
3312   case ARITH_EQ_ATOM:
3313   case ARITH_GE_ATOM:
3314   case ARITH_BINEQ_ATOM:
3315     return true;
3316 
3317   default:
3318     return false;
3319   }
3320 }
3321 
3322 /*
3323  * Test whether t is a bitvector literal
3324  */
is_bitvector_literal(const term_table_t * table,term_t t)3325 bool is_bitvector_literal(const term_table_t *table, term_t t) {
3326   switch (term_kind(table, t)) {
3327   case BV_EQ_ATOM:
3328   case BV_GE_ATOM:
3329   case BV_SGE_ATOM:
3330     return true;
3331 
3332   default:
3333     return false;
3334   }
3335 }
3336 
3337 
3338 /********************
3339  *  CONSTANT TERMS  *
3340  *******************/
3341 
3342 /*
3343  * Check whether t is a constant tuple.
3344  *
3345  * This uses a naive recursion without marking so subterms of t may be
3346  * visited many times (there's a risk of exponential cost). That
3347  * should not be a problem in practice unless people use deeply nested
3348  * tuples of tuples of tuples ...
3349  */
is_constant_tuple(const term_table_t * table,term_t t)3350 bool is_constant_tuple(const term_table_t *table, term_t t) {
3351   composite_term_t *tup;
3352   term_kind_t tag;
3353   uint32_t i, n;
3354 
3355   tup = tuple_term_desc(table, t);
3356   n = tup->arity;
3357 
3358   // first pass: avoid recursive calls
3359   for (i=0; i<n; i++) {
3360     tag = term_kind(table, tup->arg[i]);
3361     if (! is_const_kind(tag) && tag != TUPLE_TERM) {
3362       return false;
3363     }
3364   }
3365 
3366   // second pass: recursively check all subterms
3367   for (i=0; i<n; i++) {
3368     if (! is_const_term(table, tup->arg[i]) &&
3369         ! is_constant_tuple(table, tup->arg[i])) {
3370       return false;
3371     }
3372   }
3373 
3374   return true;
3375 }
3376 
3377 
3378 
3379 /*
3380  * Generic version: return true if t is an atomic constant
3381  * or a constant tuple.
3382  */
is_constant_term(const term_table_t * table,term_t t)3383 bool is_constant_term(const term_table_t *table, term_t t) {
3384   return is_const_term(table, t) ||
3385     (term_kind(table, t) == TUPLE_TERM && is_constant_tuple(table, t));
3386 }
3387 
3388 
3389 
3390 
3391 /*
3392  * Check whether the table contains a constant term of type tau and the given index
3393  * - tau must be uninterpreted or scalar
3394  * - if tau is scalar, then index must be between 0 and cardinality of tau - 1
3395  * - return NULL_TERM if there's no such term in table
3396  */
find_constant_term(term_table_t * table,type_t tau,int32_t index)3397 term_t find_constant_term(term_table_t *table, type_t tau, int32_t index) {
3398   int32_t i;
3399   integer_term_hobj_t integer_hobj;
3400 
3401   integer_hobj.m.hash = (hobj_hash_t) hash_integer_hobj;
3402   integer_hobj.m.eq = (hobj_eq_t) eq_integer_hobj;
3403   integer_hobj.m.build = (hobj_build_t) build_integer_hobj;
3404   integer_hobj.tbl = table;
3405   integer_hobj.tag = CONSTANT_TERM;
3406   integer_hobj.tau = tau;
3407   integer_hobj.id = index;
3408 
3409   i = int_htbl_find_obj(&table->htbl, &integer_hobj.m);
3410   if (i >= 0) {
3411     i = pos_term(i);
3412   }
3413 
3414   assert(i == NULL_TERM ||
3415          (term_kind(table, i) == CONSTANT_TERM && term_type(table, i) == tau
3416           && constant_term_index(table, i) == index));
3417 
3418   return i;
3419 }
3420 
3421 
3422 
3423 
3424 
3425 /***********************
3426  * GARBAGE COLLECTION  *
3427  **********************/
3428 
3429 /*
3430  * MARKING
3431  */
3432 
3433 /*
3434  * Mark all descendants of i whose ids are less than ptr
3435  * - i must be a marked term index and not already deleted.
3436  *
3437  * NOTE: check for risks for stack overflow here.
3438  */
3439 static void mark_reachable_terms(term_table_t *table, int32_t ptr, int32_t i);
3440 
3441 // mark i if it's not already marked then explore its children if i < ptr where i = index_of(t)
mark_and_explore_term(term_table_t * table,int32_t ptr,term_t t)3442 static void mark_and_explore_term(term_table_t *table, int32_t ptr, term_t t) {
3443   int32_t i;
3444 
3445   i = index_of(t);
3446   if (! term_idx_is_marked(table, i)) {
3447     term_table_set_gc_mark(table, i);
3448     if (i < ptr) {
3449       mark_reachable_terms(table, ptr, i);
3450     }
3451   }
3452 }
3453 
3454 // mark all terms in composite term d
mark_composite_term(term_table_t * table,int32_t ptr,composite_term_t * d)3455 static void mark_composite_term(term_table_t *table, int32_t ptr, composite_term_t *d) {
3456   uint32_t i, n;
3457 
3458   n = d->arity;
3459   for (i=0; i<n; i++) {
3460     mark_and_explore_term(table, ptr, d->arg[i]);
3461   }
3462 }
3463 
3464 // subterm of d
mark_select_term(term_table_t * table,int32_t ptr,select_term_t * d)3465 static inline void mark_select_term(term_table_t *table, int32_t ptr, select_term_t *d) {
3466   mark_and_explore_term(table, ptr, d->arg);
3467 }
3468 
3469 // root atoms
mark_root_atom(term_table_t * table,int32_t ptr,root_atom_t * r)3470 static inline void mark_root_atom(term_table_t *table, int32_t ptr, root_atom_t *r) {
3471   // x should be in p, so no need to explore
3472   mark_and_explore_term(table, ptr, r->p);
3473 }
3474 
3475 // variables in polynomials
mark_polynomial(term_table_t * table,int32_t ptr,polynomial_t * p)3476 static void mark_polynomial(term_table_t *table, int32_t ptr, polynomial_t *p) {
3477   monomial_t *q;
3478 
3479   q = p->mono;
3480   // skip constant monomial if any
3481   if (q->var == const_idx) q ++;
3482 
3483   while (q->var != max_idx) {
3484     mark_and_explore_term(table, ptr, q->var);
3485     q ++;
3486   }
3487 }
3488 
mark_bvpoly(term_table_t * table,int32_t ptr,bvpoly_t * p)3489 static void mark_bvpoly(term_table_t *table, int32_t ptr, bvpoly_t *p) {
3490   bvmono_t *q;
3491 
3492   q = p->mono;
3493   // skip constant monomial if any
3494   if (q->var == const_idx) q ++;
3495 
3496   while (q->var != max_idx) {
3497     mark_and_explore_term(table, ptr, q->var);
3498     q ++;
3499   }
3500 }
3501 
mark_bvpoly64(term_table_t * table,int32_t ptr,bvpoly64_t * p)3502 static void mark_bvpoly64(term_table_t *table, int32_t ptr, bvpoly64_t *p) {
3503   bvmono64_t *q;
3504 
3505   q = p->mono;
3506   // skip constant monomial if any
3507   if (q->var == const_idx) q ++;
3508 
3509   while (q->var != max_idx) {
3510     mark_and_explore_term(table, ptr, q->var);
3511     q ++;
3512   }
3513 }
3514 
3515 
3516 // power product r: we mark it in table->pprods, then we explore all variables of r
mark_power_product(term_table_t * table,int32_t ptr,pprod_t * r)3517 static void mark_power_product(term_table_t *table, int32_t ptr, pprod_t *r) {
3518   uint32_t i, n;
3519 
3520   assert(r != empty_pp && r != end_pp && !pp_is_var(r));
3521   pprod_table_set_gc_mark(table->pprods, r);
3522 
3523   n = r->len;
3524   for (i=0; i<n; i++) {
3525     mark_and_explore_term(table, ptr, r->prod[i].var);
3526   }
3527 }
3528 
3529 
mark_reachable_terms(term_table_t * table,int32_t ptr,int32_t i)3530 static void mark_reachable_terms(term_table_t *table, int32_t ptr, int32_t i) {
3531   assert(term_idx_is_marked(table, i));
3532 
3533   switch (table->kind[i]) {
3534   case UNUSED_TERM:
3535   case RESERVED_TERM:
3536   case CONSTANT_TERM:
3537   case ARITH_CONSTANT:
3538   case BV64_CONSTANT:
3539   case BV_CONSTANT:
3540   case VARIABLE:
3541   case UNINTERPRETED_TERM:
3542     // leaf terms
3543     break;
3544 
3545   case ARITH_EQ_ATOM:
3546   case ARITH_GE_ATOM:
3547   case ARITH_IS_INT_ATOM:
3548   case ARITH_FLOOR:
3549   case ARITH_CEIL:
3550   case ARITH_ABS:
3551     // i has a single subterm stored in desc[i].integer
3552     mark_and_explore_term(table, ptr, table->desc[i].integer);
3553     break;
3554 
3555   case ARITH_ROOT_ATOM:
3556     // i is a root atom
3557     mark_root_atom(table, ptr, table->desc[i].ptr);
3558     break;
3559 
3560   case ITE_TERM:
3561   case APP_TERM:
3562   case UPDATE_TERM:
3563   case TUPLE_TERM:
3564   case EQ_TERM:
3565   case DISTINCT_TERM:
3566   case FORALL_TERM:
3567   case LAMBDA_TERM:
3568   case OR_TERM:
3569   case XOR_TERM:
3570   case ARITH_BINEQ_ATOM:
3571   case ARITH_RDIV:
3572   case ARITH_IDIV:
3573   case ARITH_MOD:
3574   case ARITH_DIVIDES_ATOM:
3575   case BV_ARRAY:
3576   case BV_DIV:
3577   case BV_REM:
3578   case BV_SDIV:
3579   case BV_SREM:
3580   case BV_SMOD:
3581   case BV_SHL:
3582   case BV_LSHR:
3583   case BV_ASHR:
3584   case BV_EQ_ATOM:
3585   case BV_GE_ATOM:
3586   case BV_SGE_ATOM:
3587     // i's descriptor is a composite term
3588     mark_composite_term(table, ptr, table->desc[i].ptr);
3589     break;
3590 
3591   case ITE_SPECIAL:
3592     // TODO: do we need a callback here for scanning the extra component?
3593     mark_composite_term(table, ptr, table->desc[i].ptr);
3594     break;
3595 
3596   case SELECT_TERM:
3597   case BIT_TERM:
3598     // i's descriptor is a select term
3599     mark_select_term(table, ptr, &table->desc[i].select);
3600     break;
3601 
3602   case POWER_PRODUCT:
3603     mark_power_product(table, ptr, table->desc[i].ptr);
3604     break;
3605 
3606   case ARITH_POLY:
3607     mark_polynomial(table, ptr, table->desc[i].ptr);
3608     break;
3609 
3610   case BV64_POLY:
3611     mark_bvpoly64(table, ptr, table->desc[i].ptr);
3612     break;
3613 
3614   case BV_POLY:
3615     mark_bvpoly(table, ptr, table->desc[i].ptr);
3616     break;
3617 
3618   default:
3619     assert(false);
3620     break;
3621   }
3622 
3623 }
3624 
3625 
3626 /*
3627  * Mark all live terms:
3628  * - on entry: the root terms must be marked
3629  * - on exit:
3630  *   every term reachable from a root term is marked
3631  *   every power product that's live is marked in table->ptbl.
3632  *   every type that's attached to a live term is marked in table->types
3633  */
mark_live_terms(term_table_t * table)3634 static void mark_live_terms(term_table_t *table) {
3635   type_table_t *types;
3636   uint32_t i, n;
3637 
3638   n = table->nelems;
3639   for (i=0; i<n; i++) {
3640     if (term_idx_is_marked(table, i)) {
3641       mark_reachable_terms(table, i, i);
3642     }
3643   }
3644 
3645   // propagate the marks to live types
3646   // skip the reserved term
3647   types = table->types;
3648   for (i=1; i<n; i++) {
3649     if (term_idx_is_marked(table, i) ) {
3650       type_table_set_gc_mark(types, table->type[i]);
3651     }
3652   }
3653 }
3654 
3655 
3656 /*
3657  * Iterator to mark the terms accessible from the symbol table
3658  * - aux must be a pointer to the term table
3659  * - r is a record in the symbol table: r->value is a term to mark
3660  */
mark_symbol(void * aux,const stbl_rec_t * r)3661 static void mark_symbol(void *aux, const stbl_rec_t *r) {
3662   term_table_set_gc_mark(aux, index_of(r->value));
3663 }
3664 
3665 
3666 /*
3667  * Filter to remove references to dead terms from the symbol table
3668  * - aux must be a pointer to the term table
3669  * - r is a record in the symbol table: if the function returns true,
3670  *   then r is finalized then removed from the symbol table.
3671  */
dead_term_symbol(void * aux,const stbl_rec_t * r)3672 static bool dead_term_symbol(void *aux, const stbl_rec_t *r) {
3673   return !term_idx_is_marked(aux, index_of(r->value));
3674 }
3675 
3676 
3677 /*
3678  * Garbage collector
3679  * - the roots are all the marked terms + if keep_named is true,
3680  *   all the terms accessible from the symbol table (i.e., mapped to some name).
3681  * - every term, type, and power product reachable from these roots
3682  *   is preserved
3683  * - delete everything else
3684  * - clear all the marks
3685  */
term_table_gc(term_table_t * table,bool keep_named)3686 void term_table_gc(term_table_t *table, bool keep_named) {
3687   uint32_t i, n;
3688 
3689   // mark the terms present in the symbol table
3690   if (keep_named) {
3691     stbl_iterate(&table->stbl, table, mark_symbol);
3692   }
3693 
3694   // mark the primitive terms
3695   set_bit(table->mark, const_idx);
3696   set_bit(table->mark, bool_const);
3697   set_bit(table->mark, zero_const);
3698 
3699   // propagate the marks
3700   mark_live_terms(table);
3701 
3702   // remove the unmarked terms from the symbol table
3703   if (!keep_named) {
3704     stbl_remove_records(&table->stbl, table, dead_term_symbol);
3705   }
3706 
3707   // force garbage collection in the type and power-product tables
3708   type_table_gc(table->types, keep_named);
3709   pprod_table_gc(table->pprods);
3710 
3711   // delete the unmarked terms
3712   n = table->nelems;
3713   for (i=0; i<n; i++) {
3714     if (! term_idx_is_marked(table, i) && table->kind[i] != UNUSED_TERM) {
3715       delete_term(table, i);
3716     }
3717   }
3718 
3719   // clear the marks
3720   clear_bitvector(table->mark, table->size);
3721 }
3722