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