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 * EVALUATION: COMPUTE THE VALUE OF A TERM IN A MODEL
21 */
22
23 #include <assert.h>
24 #include <stdbool.h>
25
26 #include "model/model_eval.h"
27 #include "terms/bv64_constants.h"
28
29
30 /*
31 * Wrapper for q_clear to avoid compilation warnings
32 * (some versions of GCC complain about inlining q_clear)
33 */
clear_rational(rational_t * q)34 static void clear_rational(rational_t *q) {
35 q_clear(q);
36 }
37
38
39 /*
40 * Initialize eval for the given model
41 */
init_evaluator(evaluator_t * eval,model_t * model)42 void init_evaluator(evaluator_t *eval, model_t *model) {
43 eval->model = model;
44 eval->terms = model->terms;
45 eval->vtbl = &model->vtbl;
46
47 init_int_hmap(&eval->cache, 0); // use the default hmap size
48 init_istack(&eval->stack);
49 // eval->env is not initialized
50 }
51
52
53 /*
54 * Delete caches and stack
55 */
delete_evaluator(evaluator_t * eval)56 void delete_evaluator(evaluator_t *eval) {
57 eval->model = NULL;
58 eval->terms = NULL;
59 eval->vtbl = NULL;
60 delete_int_hmap(&eval->cache);
61 delete_istack(&eval->stack);
62 }
63
64
65
66 /*
67 * Reset: empty the caches
68 */
reset_evaluator(evaluator_t * eval)69 void reset_evaluator(evaluator_t *eval) {
70 int_hmap_reset(&eval->cache);
71 reset_istack(&eval->stack);
72 value_table_start_tmp(eval->vtbl);
73 }
74
75
76
77 /*
78 * Get the value mapped to term t in the internal cache
79 * - return null_value if nothing is mapped to t
80 */
eval_cached_value(evaluator_t * eval,term_t t)81 static value_t eval_cached_value(evaluator_t *eval, term_t t) {
82 int_hmap_pair_t *r;
83
84 assert(good_term(eval->terms, t));
85
86 r = int_hmap_find(&eval->cache, t);
87 if (r == NULL) {
88 return null_value;
89 } else {
90 return r->val;
91 }
92 }
93
94
95 /*
96 * Add the mapping t := v to the cache
97 * - t must not be mapped to an object already
98 */
eval_cache_map(evaluator_t * eval,term_t t,value_t v)99 static void eval_cache_map(evaluator_t *eval, term_t t, value_t v) {
100 int_hmap_pair_t *r;
101
102 assert(good_term(eval->terms, t) && good_object(eval->vtbl, v));
103
104 r = int_hmap_get(&eval->cache, t);
105 assert(r->val < 0);
106 r->val = v;
107 }
108
109
110
111 /*
112 * EVALUATION:
113 *
114 * Compute the value v of term t in the model
115 * - add the mapping t := v to the cache
116 * - raise an exception if t can't be evaluated
117 */
118 static value_t eval_term(evaluator_t *eval, term_t t);
119
120 /*
121 * Attempt to get a rational value for v
122 * - fails with a longjmp if v is an algebraic number
123 */
eval_get_rational(evaluator_t * eval,value_t v)124 static rational_t *eval_get_rational(evaluator_t *eval, value_t v) {
125 if (object_is_algebraic(eval->vtbl, v)) {
126 longjmp(eval->env, MDL_EVAL_FAILED);
127 }
128 return vtbl_rational(eval->vtbl, v);
129 }
130
131 /*
132 * Check whether v is zero: returns false if v is algebraic
133 */
eval_is_zero(evaluator_t * eval,value_t v)134 static bool eval_is_zero(evaluator_t *eval, value_t v) {
135 return object_is_rational(eval->vtbl, v) && q_is_zero(vtbl_rational(eval->vtbl, v));
136 }
137
138 /*
139 * Attempt to get a non-zero rational value for v
140 * - fails if v is an algebraic number or if it is zero
141 */
eval_get_nz_rational(evaluator_t * eval,value_t v)142 static rational_t *eval_get_nz_rational(evaluator_t *eval, value_t v) {
143 rational_t *q;
144
145 q = eval_get_rational(eval, v);
146 if (q_is_zero(q)) {
147 longjmp(eval->env, MDL_EVAL_FAILED);
148 }
149 return q;
150 }
151
152
153 /*
154 * Evaluate terms t[0 ... n-1] and store the result in a[0 .. n-1]
155 */
eval_term_array(evaluator_t * eval,term_t * t,value_t * a,uint32_t n)156 static void eval_term_array(evaluator_t *eval, term_t *t, value_t *a, uint32_t n) {
157 uint32_t i;
158
159 for (i=0; i<n; i++) {
160 a[i] = eval_term(eval, t[i]);
161 }
162 }
163
164
165 /*
166 * Bitvector constant: 64bits or less
167 */
eval_bv64_constant(evaluator_t * eval,bvconst64_term_t * c)168 static value_t eval_bv64_constant(evaluator_t *eval, bvconst64_term_t *c) {
169 return vtbl_mk_bv_from_bv64(eval->vtbl, c->bitsize, c->value);
170 }
171
172
173 /*
174 * Bitvector constant
175 */
eval_bv_constant(evaluator_t * eval,bvconst_term_t * c)176 static value_t eval_bv_constant(evaluator_t *eval, bvconst_term_t *c) {
177 return vtbl_mk_bv_from_bv(eval->vtbl, c->bitsize, c->data);
178 }
179
180
181 /*
182 * Arithmetic atom: t == 0
183 */
eval_arith_eq(evaluator_t * eval,term_t t)184 static value_t eval_arith_eq(evaluator_t *eval, term_t t) {
185 value_t v;
186
187 v = eval_term(eval, t);
188 return vtbl_mk_bool(eval->vtbl, q_is_zero(eval_get_rational(eval, v)));
189 }
190
191
192 /*
193 * Arithmetic atom: t >= 0
194 */
eval_arith_ge(evaluator_t * eval,term_t t)195 static value_t eval_arith_ge(evaluator_t *eval, term_t t) {
196 value_t v;
197
198 v = eval_term(eval, t);
199 return vtbl_mk_bool(eval->vtbl, q_is_nonneg(eval_get_rational(eval, v)));
200 }
201
202 /*
203 * Arithmetic atom: (is_int t)
204 */
eval_arith_is_int(evaluator_t * eval,term_t t)205 static value_t eval_arith_is_int(evaluator_t *eval, term_t t) {
206 value_t v;
207
208 v = eval_term(eval, t);
209 return vtbl_mk_bool(eval->vtbl, q_is_integer(eval_get_rational(eval, v)));
210 }
211
212
213 /*
214 * Arithmetic term: (floor t)
215 */
eval_arith_floor(evaluator_t * eval,term_t t)216 static value_t eval_arith_floor(evaluator_t *eval, term_t t) {
217 rational_t q;
218 value_t v;
219
220 v = eval_term(eval, t);
221 assert(object_is_rational(eval->vtbl, v));
222
223 q_init(&q);
224 q_set(&q, eval_get_rational(eval, v)); // q := value of t
225 q_floor(&q);
226 q_normalize(&q);
227
228 v = vtbl_mk_rational(eval->vtbl, &q);
229
230 clear_rational(&q);
231
232 return v;
233 }
234
235
236 /*
237 * Arithmetic term: (ceil t)
238 */
eval_arith_ceil(evaluator_t * eval,term_t t)239 static value_t eval_arith_ceil(evaluator_t *eval, term_t t) {
240 rational_t q;
241 value_t v;
242
243 v = eval_term(eval, t);
244 assert(object_is_rational(eval->vtbl, v));
245
246 q_init(&q);
247 q_set(&q, eval_get_rational(eval, v)); // q := value of t
248 q_ceil(&q);
249 q_normalize(&q);
250
251 v = vtbl_mk_rational(eval->vtbl, &q);
252
253 clear_rational(&q);
254
255 return v;
256 }
257
258
259 /*
260 * Arithmetic term: (abs t)
261 */
eval_arith_abs(evaluator_t * eval,term_t t)262 static value_t eval_arith_abs(evaluator_t *eval, term_t t) {
263 rational_t q;
264 value_t v;
265
266 v = eval_term(eval, t);
267 assert(object_is_rational(eval->vtbl, v));
268
269 q_init(&q);
270 q_set_abs(&q, eval_get_rational(eval, v)); // q := value of t
271 q_normalize(&q);
272
273 v = vtbl_mk_rational(eval->vtbl, &q);
274
275 clear_rational(&q);
276
277 return v;
278 }
279
280
281 /*
282 * Arithmetic atom: v1 == v2
283 */
eval_arith_bineq(evaluator_t * eval,composite_term_t * eq)284 static value_t eval_arith_bineq(evaluator_t *eval, composite_term_t *eq) {
285 value_t v1, v2;
286
287 assert(eq->arity == 2);
288
289 v1 = eval_term(eval, eq->arg[0]);
290 v2 = eval_term(eval, eq->arg[1]);
291 assert(object_is_rational(eval->vtbl, v1) &&
292 object_is_rational(eval->vtbl, v2));
293
294 return vtbl_mk_bool(eval->vtbl, v1 == v2); // because of hash consing
295 }
296
297
298 /*
299 * Arithmetic term: (/ v1 v2) (division)
300 */
eval_arith_rdiv(evaluator_t * eval,composite_term_t * d)301 static value_t eval_arith_rdiv(evaluator_t *eval, composite_term_t *d) {
302 rational_t q;
303 value_t v1, v2, o;
304
305 assert(d->arity == 2);
306
307 v1 = eval_term(eval, d->arg[0]);
308 v2 = eval_term(eval, d->arg[1]);
309
310 if (eval_is_zero(eval, v2)) {
311 o = vtbl_eval_rdiv_by_zero(eval->vtbl, v1);
312 } else {
313 q_init(&q);
314 q_set(&q, eval_get_rational(eval, v1));
315 q_div(&q, eval_get_nz_rational(eval, v2));
316 q_normalize(&q);
317
318 o = vtbl_mk_rational(eval->vtbl, &q);
319
320 clear_rational(&q);
321 }
322
323
324 return o;
325 }
326
327
328 /*
329 * Arithmetic term: (div v1 v2) (integer division)
330 */
eval_arith_idiv(evaluator_t * eval,composite_term_t * d)331 static value_t eval_arith_idiv(evaluator_t *eval, composite_term_t *d) {
332 rational_t q;
333 value_t v1, v2, o;
334
335 assert(d->arity == 2);
336
337 v1 = eval_term(eval, d->arg[0]);
338 v2 = eval_term(eval, d->arg[1]);
339
340 if (eval_is_zero(eval, v2)) {
341 o = vtbl_eval_idiv_by_zero(eval->vtbl, v1);
342 } else {
343 q_init(&q);
344 q_smt2_div(&q, eval_get_rational(eval, v1), eval_get_nz_rational(eval, v2));
345 q_normalize(&q);
346
347 o = vtbl_mk_rational(eval->vtbl, &q);
348
349 clear_rational(&q);
350 }
351
352 return o;
353 }
354
355
356 /*
357 * Arithmetic term: (mod v1 v2)
358 */
eval_arith_mod(evaluator_t * eval,composite_term_t * d)359 static value_t eval_arith_mod(evaluator_t *eval, composite_term_t *d) {
360 rational_t q;
361 value_t v1, v2, o;
362
363 assert(d->arity == 2);
364
365 v1 = eval_term(eval, d->arg[0]);
366 v2 = eval_term(eval, d->arg[1]);
367
368 if (eval_is_zero(eval, v2)) {
369 o = vtbl_eval_mod_by_zero(eval->vtbl, v1);
370 } else {
371 q_init(&q);
372 q_smt2_mod(&q, eval_get_rational(eval, v1), eval_get_nz_rational(eval, v2));
373 q_normalize(&q);
374
375 o = vtbl_mk_rational(eval->vtbl, &q);
376
377 clear_rational(&q);
378 }
379
380 return o;
381 }
382
383
384 /*
385 * Arithmetic term: (divides v1 v2)
386 */
eval_arith_divides(evaluator_t * eval,composite_term_t * d)387 static value_t eval_arith_divides(evaluator_t *eval, composite_term_t *d) {
388 value_t v1, v2;
389 bool divides;
390
391 assert(d->arity == 2);
392
393 // it's OK for v1 to be zero here.
394 v1 = eval_term(eval, d->arg[0]);
395 v2 = eval_term(eval, d->arg[1]);
396 divides = q_smt2_divides(eval_get_rational(eval, v1), eval_get_rational(eval, v2));
397
398 return vtbl_mk_bool(eval->vtbl, divides);
399 }
400
401
402 /*
403 * Power product: arithmetic
404 */
eval_arith_pprod(evaluator_t * eval,pprod_t * p)405 static value_t eval_arith_pprod(evaluator_t *eval, pprod_t *p) {
406 rational_t prod;
407 uint32_t i, n;
408 term_t t;
409 value_t o;
410
411 q_init(&prod);
412 q_set_one(&prod);
413
414 n = p->len;
415 for (i=0; i<n; i++) {
416 t = p->prod[i].var;
417 o = eval_term(eval, t);
418 // prod[i] is v ^ k so q := q * (o ^ k)
419 q_mulexp(&prod, eval_get_rational(eval, o), p->prod[i].exp);
420 }
421
422 o = vtbl_mk_rational(eval->vtbl, &prod);
423
424 clear_rational(&prod);
425
426 return o;
427 }
428
429
430 /*
431 * Arithmetic polynomial
432 */
eval_arith_poly(evaluator_t * eval,polynomial_t * p)433 static value_t eval_arith_poly(evaluator_t *eval, polynomial_t *p) {
434 rational_t sum;
435 uint32_t i, n;
436 term_t t;
437 value_t v;
438
439 q_init(&sum); // sum = 0
440
441 n = p->nterms;
442 for (i=0; i<n; i++) {
443 t = p->mono[i].var;
444 if (t == const_idx) {
445 q_add(&sum, &p->mono[i].coeff);
446 } else {
447 v = eval_term(eval, t);
448 q_addmul(&sum, &p->mono[i].coeff, eval_get_rational(eval, v)); // sum := sum + coeff * aux
449 }
450 }
451
452 // convert sum to an object
453 v = vtbl_mk_rational(eval->vtbl, &sum);
454
455 clear_rational(&sum);
456
457 return v;
458 }
459
460
461
462 /*
463 * Bitvector terms
464 */
eval_bv_array(evaluator_t * eval,composite_term_t * array)465 static value_t eval_bv_array(evaluator_t *eval, composite_term_t *array) {
466 uint32_t i, n;
467 int32_t *a;
468 value_t v;
469
470 n = array->arity;
471 a = alloc_istack_array(&eval->stack, n);
472 for (i=0; i<n; i++) {
473 v = eval_term(eval, array->arg[i]);
474 a[i] = boolobj_value(eval->vtbl, v);
475 }
476
477 v = vtbl_mk_bv(eval->vtbl, n, a);
478
479 free_istack_array(&eval->stack, a);
480
481 return v;
482 }
483
eval_bit(evaluator_t * eval,select_term_t * select)484 static value_t eval_bit(evaluator_t *eval, select_term_t *select) {
485 value_t v;
486 value_bv_t *bv;
487 bool b;
488
489 v = eval_term(eval, select->arg);
490 bv = vtbl_bitvector(eval->vtbl, v);
491 assert(select->idx < bv->nbits);
492
493 b = bvconst_tst_bit(bv->data, select->idx);
494
495 return vtbl_mk_bool(eval->vtbl, b);
496 }
497
eval_bv_div(evaluator_t * eval,composite_term_t * app)498 static term_t eval_bv_div(evaluator_t *eval, composite_term_t *app) {
499 uint32_t *aux;
500 uint32_t n, w;
501 value_t v1, v2, v;
502 value_bv_t *bv1, *bv2;
503
504 assert(app->arity == 2);
505
506 v1 = eval_term(eval, app->arg[0]);
507 v2 = eval_term(eval, app->arg[1]);
508 bv1 = vtbl_bitvector(eval->vtbl, v1);
509 bv2 = vtbl_bitvector(eval->vtbl, v2);
510 assert(bv1->nbits == bv2->nbits);
511
512 n = bv1->nbits;
513 w = bv1->width;
514 assert(n>0 && w>0);
515
516 aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
517 bvconst_udiv2z(aux, n, bv1->data, bv2->data);
518 v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
519
520 free_istack_array(&eval->stack, (int32_t *) aux);
521
522 return v;
523 }
524
eval_bv_rem(evaluator_t * eval,composite_term_t * app)525 static term_t eval_bv_rem(evaluator_t *eval, composite_term_t *app) {
526 uint32_t *aux;
527 uint32_t n, w;
528 value_t v1, v2, v;
529 value_bv_t *bv1, *bv2;
530
531 assert(app->arity == 2);
532
533 v1 = eval_term(eval, app->arg[0]);
534 v2 = eval_term(eval, app->arg[1]);
535 bv1 = vtbl_bitvector(eval->vtbl, v1);
536 bv2 = vtbl_bitvector(eval->vtbl, v2);
537 assert(bv1->nbits == bv2->nbits);
538
539 n = bv1->nbits;
540 w = bv1->width;
541 assert(n>0 && w>0);
542
543 aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
544 bvconst_urem2z(aux, n, bv1->data, bv2->data);
545 v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
546
547 free_istack_array(&eval->stack, (int32_t *) aux);
548
549 return v;
550 }
551
eval_bv_sdiv(evaluator_t * eval,composite_term_t * app)552 static term_t eval_bv_sdiv(evaluator_t *eval, composite_term_t *app) {
553 uint32_t *aux;
554 uint32_t n, w;
555 value_t v1, v2, v;
556 value_bv_t *bv1, *bv2;
557
558 assert(app->arity == 2);
559
560 v1 = eval_term(eval, app->arg[0]);
561 v2 = eval_term(eval, app->arg[1]);
562 bv1 = vtbl_bitvector(eval->vtbl, v1);
563 bv2 = vtbl_bitvector(eval->vtbl, v2);
564 assert(bv1->nbits == bv2->nbits);
565
566 n = bv1->nbits;
567 w = bv1->width;
568 assert(n>0 && w>0);
569
570 aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
571 bvconst_sdiv2z(aux, n, bv1->data, bv2->data);
572 v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
573
574 free_istack_array(&eval->stack, (int32_t *) aux);
575
576 return v;
577 }
578
eval_bv_srem(evaluator_t * eval,composite_term_t * app)579 static term_t eval_bv_srem(evaluator_t *eval, composite_term_t *app) {
580 uint32_t *aux;
581 uint32_t n, w;
582 value_t v1, v2, v;
583 value_bv_t *bv1, *bv2;
584
585 assert(app->arity == 2);
586
587 v1 = eval_term(eval, app->arg[0]);
588 v2 = eval_term(eval, app->arg[1]);
589 bv1 = vtbl_bitvector(eval->vtbl, v1);
590 bv2 = vtbl_bitvector(eval->vtbl, v2);
591 assert(bv1->nbits == bv2->nbits);
592
593 n = bv1->nbits;
594 w = bv1->width;
595 assert(n>0 && w>0);
596
597 aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
598 bvconst_srem2z(aux, n, bv1->data, bv2->data);
599 v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
600
601 free_istack_array(&eval->stack, (int32_t *) aux);
602
603 return v;
604 }
605
eval_bv_smod(evaluator_t * eval,composite_term_t * app)606 static term_t eval_bv_smod(evaluator_t *eval, composite_term_t *app) {
607 uint32_t *aux;
608 uint32_t n, w;
609 value_t v1, v2, v;
610 value_bv_t *bv1, *bv2;
611
612 assert(app->arity == 2);
613
614 v1 = eval_term(eval, app->arg[0]);
615 v2 = eval_term(eval, app->arg[1]);
616 bv1 = vtbl_bitvector(eval->vtbl, v1);
617 bv2 = vtbl_bitvector(eval->vtbl, v2);
618 assert(bv1->nbits == bv2->nbits);
619
620 n = bv1->nbits;
621 w = bv1->width;
622 assert(n>0 && w>0);
623
624 aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
625 bvconst_smod2z(aux, n, bv1->data, bv2->data);
626 v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
627
628 free_istack_array(&eval->stack, (int32_t *) aux);
629
630 return v;
631 }
632
633
634 /*
635 * Convert bv's value (interpreted as a non-negative integer) into a shift amount.
636 * If bv's value is larger than nbits, then returns bv->nbits
637 */
get_shift_amount(value_bv_t * bv)638 static uint32_t get_shift_amount(value_bv_t *bv) {
639 uint32_t n, k, i, s;
640
641 s = bvconst_get32(bv->data); // low-order word = shift amount
642 n = bv->nbits;
643
644 if (s < n) {
645 k = bv->width;
646 // if any of the higher order words is nonzero, return n
647 for (i=1; i<k; i++) {
648 if (bv->data[i] != 0) {
649 return n;
650 }
651 }
652 return s;
653 }
654
655 return n;
656 }
657
658
659 /*
660 * Bitvector shift operators
661 */
eval_bv_shl(evaluator_t * eval,composite_term_t * app)662 static term_t eval_bv_shl(evaluator_t *eval, composite_term_t *app) {
663 uint32_t *aux;
664 uint32_t n, w;
665 value_t v1, v2, v;
666 value_bv_t *bv1, *bv2;
667
668 assert(app->arity == 2);
669
670 v1 = eval_term(eval, app->arg[0]);
671 v2 = eval_term(eval, app->arg[1]);
672 bv1 = vtbl_bitvector(eval->vtbl, v1);
673 bv2 = vtbl_bitvector(eval->vtbl, v2);
674 assert(bv1->nbits == bv2->nbits);
675
676 n = bv1->nbits;
677 w = bv1->width;
678 assert(n>0 && w>0);
679
680 aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
681 bvconst_set(aux, w, bv1->data);
682 w = get_shift_amount(bv2);
683 bvconst_shift_left(aux, n, w, 0); // padding with 0
684
685 v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
686
687 free_istack_array(&eval->stack, (int32_t *) aux);
688
689 return v;
690 }
691
eval_bv_lshr(evaluator_t * eval,composite_term_t * app)692 static term_t eval_bv_lshr(evaluator_t *eval, composite_term_t *app) {
693 uint32_t *aux;
694 uint32_t n, w;
695 value_t v1, v2, v;
696 value_bv_t *bv1, *bv2;
697
698 assert(app->arity == 2);
699
700 v1 = eval_term(eval, app->arg[0]);
701 v2 = eval_term(eval, app->arg[1]);
702 bv1 = vtbl_bitvector(eval->vtbl, v1);
703 bv2 = vtbl_bitvector(eval->vtbl, v2);
704 assert(bv1->nbits == bv2->nbits);
705
706 n = bv1->nbits;
707 w = bv1->width;
708 assert(n>0 && w>0);
709
710 aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
711 bvconst_set(aux, w, bv1->data);
712 w = get_shift_amount(bv2);
713 bvconst_shift_right(aux, n, w, 0); // padding with 0
714
715 v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
716
717 free_istack_array(&eval->stack, (int32_t *) aux);
718
719 return v;
720 }
721
eval_bv_ashr(evaluator_t * eval,composite_term_t * app)722 static term_t eval_bv_ashr(evaluator_t *eval, composite_term_t *app) {
723 uint32_t *aux;
724 uint32_t n, w;
725 value_t v1, v2, v;
726 value_bv_t *bv1, *bv2;
727
728 assert(app->arity == 2);
729
730 v1 = eval_term(eval, app->arg[0]);
731 v2 = eval_term(eval, app->arg[1]);
732 bv1 = vtbl_bitvector(eval->vtbl, v1);
733 bv2 = vtbl_bitvector(eval->vtbl, v2);
734 assert(bv1->nbits == bv2->nbits);
735
736 n = bv1->nbits;
737 w = bv1->width;
738 assert(n>0 && w>0);
739
740 aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
741 bvconst_set(aux, w, bv1->data);
742 w = get_shift_amount(bv2);
743 bvconst_shift_right(aux, n, w, bvconst_tst_bit(aux, n-1)); // padding with sign bit
744
745 v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
746
747 free_istack_array(&eval->stack, (int32_t *) aux);
748
749 return v;
750 }
751
752
753
754 /*
755 * Bitvector atoms
756 */
eval_bveq(evaluator_t * eval,composite_term_t * eq)757 static value_t eval_bveq(evaluator_t *eval, composite_term_t *eq) {
758 value_t v1, v2;
759
760 assert(eq->arity == 2);
761
762 v1 = eval_term(eval, eq->arg[0]);
763 v2 = eval_term(eval, eq->arg[1]);
764 assert(object_is_bitvector(eval->vtbl, v1) &&
765 object_is_bitvector(eval->vtbl, v2));
766
767 return vtbl_mk_bool(eval->vtbl, v1 == v2);
768 }
769
eval_bvge(evaluator_t * eval,composite_term_t * ge)770 static value_t eval_bvge(evaluator_t *eval, composite_term_t *ge) {
771 value_t v1, v2;
772 value_bv_t *bv1, *bv2;
773 bool test;
774
775 assert(ge->arity == 2);
776
777 v1 = eval_term(eval, ge->arg[0]);
778 v2 = eval_term(eval, ge->arg[1]);
779 bv1 = vtbl_bitvector(eval->vtbl, v1);
780 bv2 = vtbl_bitvector(eval->vtbl, v2);
781 assert(bv1->nbits == bv2->nbits);
782 test = bvconst_ge(bv1->data, bv2->data, bv1->nbits);
783
784 return vtbl_mk_bool(eval->vtbl, test);
785 }
786
eval_bvsge(evaluator_t * eval,composite_term_t * sge)787 static value_t eval_bvsge(evaluator_t *eval, composite_term_t *sge) {
788 value_t v1, v2;
789 value_bv_t *bv1, *bv2;
790 bool test;
791
792 assert(sge->arity == 2);
793
794 v1 = eval_term(eval, sge->arg[0]);
795 v2 = eval_term(eval, sge->arg[1]);
796 bv1 = vtbl_bitvector(eval->vtbl, v1);
797 bv2 = vtbl_bitvector(eval->vtbl, v2);
798 assert(bv1->nbits == bv2->nbits);
799 test = bvconst_sge(bv1->data, bv2->data, bv1->nbits);
800
801 return vtbl_mk_bool(eval->vtbl, test);
802 }
803
804
805
806 /*
807 * Power product: bitvector of nbits
808 */
eval_bv_pprod(evaluator_t * eval,pprod_t * p,uint32_t nbits)809 static value_t eval_bv_pprod(evaluator_t *eval, pprod_t *p, uint32_t nbits) {
810 uint32_t *a;
811 uint32_t i, n, w;
812 term_t t;
813 value_t o;
814
815 // get bitsize
816 w = (nbits + 31) >> 5; // width in words
817 a = (uint32_t *) alloc_istack_array(&eval->stack, w);
818 bvconst_set_one(a, w);
819
820 n = p->len;
821 for (i=0; i<n; i++) {
822 t = p->prod[i].var;
823 o = eval_term(eval, t);
824 // prod[i] is v ^ k so q := q * (o ^ k)
825 bvconst_mulpower(a, w, vtbl_bitvector(eval->vtbl, o)->data, p->prod[i].exp);
826 }
827
828 // convert to object
829 bvconst_normalize(a, nbits);
830 o = vtbl_mk_bv_from_bv(eval->vtbl, nbits, a);
831
832 // cleanup
833 free_istack_array(&eval->stack, (int32_t *) a);
834
835 return o;
836 }
837
838
839 /*
840 * Bitvector polynomial: wide coefficients
841 */
eval_bv_poly(evaluator_t * eval,bvpoly_t * p)842 static value_t eval_bv_poly(evaluator_t *eval, bvpoly_t *p) {
843 uint32_t *sum;
844 uint32_t i, n, nbits, w;
845 term_t t;
846 value_t v;
847
848 nbits = p->bitsize;
849 w = p->width;
850
851 sum = (uint32_t *) alloc_istack_array(&eval->stack, w);
852 bvconst_clear(sum, w);
853
854 n = p->nterms;
855 for (i=0; i<n; i++) {
856 t = p->mono[i].var;
857 if (t == const_idx) {
858 bvconst_add(sum, w, p->mono[i].coeff);
859 } else {
860 v = eval_term(eval, t);
861 // sum := sum + coeff * v
862 bvconst_addmul(sum, w, p->mono[i].coeff, vtbl_bitvector(eval->vtbl, v)->data);
863 }
864 }
865
866 // convert sum to an object
867 bvconst_normalize(sum, nbits);
868 v = vtbl_mk_bv_from_bv(eval->vtbl, nbits, sum);
869
870 free_istack_array(&eval->stack, (int32_t *) sum);
871
872 return v;
873 }
874
875
876 /*
877 * Convert bivector object o to a 64bit unsigned integer
878 * - o must have between 1 and 64bits
879 */
bvobj_to_uint64(value_bv_t * o)880 static uint64_t bvobj_to_uint64(value_bv_t *o) {
881 uint64_t c;
882
883 assert(1 <= o->nbits && o->nbits <= 64);
884 c = o->data[0];
885 if (o->nbits > 32) {
886 c += ((uint64_t) o->data[1]) << 32;
887 }
888 return c;
889 }
890
891
892 /*
893 * Bitvector polynomial: 64bit coefficients
894 */
eval_bv64_poly(evaluator_t * eval,bvpoly64_t * p)895 static value_t eval_bv64_poly(evaluator_t *eval, bvpoly64_t *p) {
896 uint64_t sum;
897 uint32_t i, n, nbits;
898 term_t t;
899 value_t v;
900
901 nbits = p->bitsize;
902 assert(0 < nbits && nbits <= 64);
903
904 sum = 0;
905
906 n = p->nterms;
907 for (i=0; i<n; i++) {
908 t = p->mono[i].var;
909 if (t == const_idx) {
910 sum += p->mono[i].coeff;
911 } else {
912 v = eval_term(eval, t);
913 sum += p->mono[i].coeff * bvobj_to_uint64(vtbl_bitvector(eval->vtbl, v));
914 }
915 }
916
917 // convert sum to an object
918 sum = norm64(sum, nbits);
919 v = vtbl_mk_bv_from_bv64(eval->vtbl, nbits, sum);
920
921 return v;
922 }
923
924
925
926 /*
927 * Evaluate basic constructs
928 */
eval_ite(evaluator_t * eval,composite_term_t * ite)929 static value_t eval_ite(evaluator_t *eval, composite_term_t *ite) {
930 value_t c;
931
932 assert(ite->arity == 3);
933
934 c = eval_term(eval, ite->arg[0]);
935 if (is_true(eval->vtbl, c)) {
936 return eval_term(eval, ite->arg[1]);
937 } else {
938 assert(is_false(eval->vtbl, c));
939 return eval_term(eval, ite->arg[2]);
940 }
941 }
942
eval_eq(evaluator_t * eval,composite_term_t * eq)943 static value_t eval_eq(evaluator_t *eval, composite_term_t *eq) {
944 value_t v1, v2;
945
946 assert(eq->arity == 2);
947
948 v1 = eval_term(eval, eq->arg[0]);
949 v2 = eval_term(eval, eq->arg[1]);
950 return vtbl_eval_eq(eval->vtbl, v1, v2);
951 }
952
953
954 /*
955 * app is (fun arg[0] ... arg[n-1])
956 */
eval_app(evaluator_t * eval,composite_term_t * app)957 static value_t eval_app(evaluator_t *eval, composite_term_t *app) {
958 value_t *a;
959 value_t *b;
960 composite_term_t *update;
961 value_t v, f;
962 uint32_t n;
963 term_t fun;
964
965 // eval the arguments first
966 assert(app->arity >= 2);
967 n = app->arity - 1;
968 a = alloc_istack_array(&eval->stack, n);
969 eval_term_array(eval, app->arg+1, a, n); // a[i] = eval(arg[i])
970
971 /*
972 * Try to avoid evaluating fun if it's an update.
973 * TODO: check whether that matters??
974 */
975 fun = app->arg[0];
976 if (term_kind(eval->terms, fun) == UPDATE_TERM) {
977 b = alloc_istack_array(&eval->stack, n);
978 do {
979 // fun is (update f (x_1 ... x_n) v)
980 update = update_term_desc(eval->terms, fun);
981 assert(update->arity == n + 2);
982
983 // evaluate x_1 ... x_n
984 eval_term_array(eval, update->arg+1, b, n); // b[i] = eval(x_{i+1})
985
986 // check equality
987 v = vtbl_eval_array_eq(eval->vtbl, a, b, n);
988 if (is_unknown(eval->vtbl, v)) {
989 // result is unknown too
990 free_istack_array(&eval->stack, b);
991 goto done;
992
993 } else if (is_true(eval->vtbl, v)) {
994 // ((update f (x_1 ... x_n) v) a[0] ... a[n-1]) --> v
995 v = eval_term(eval, update->arg[n+1]);
996 free_istack_array(&eval->stack, b);
997 goto done;
998
999 } else {
1000 // ((update f ... v) a[0] ... a[n-1]) --> (f a[0] ... a[n-1])
1001 fun = update->arg[0];
1002 }
1003
1004 } while (term_kind(eval->terms, fun) == UPDATE_TERM);
1005
1006 free_istack_array(&eval->stack, b);
1007 }
1008
1009
1010 /*
1011 * compute (fun a[0] ... a[n-1])
1012 */
1013 assert(term_kind(eval->terms, fun) != UPDATE_TERM);
1014 f = eval_term(eval, fun);
1015 v = vtbl_eval_application(eval->vtbl, f, n, a);
1016
1017 done:
1018 free_istack_array(&eval->stack, a);
1019 return v;
1020 }
1021
1022
eval_or(evaluator_t * eval,composite_term_t * or)1023 static value_t eval_or(evaluator_t *eval, composite_term_t *or) {
1024 uint32_t i, n;
1025 value_t v;
1026
1027 n = or->arity;
1028 for (i=0; i<n; i++) {
1029 v = eval_term(eval, or->arg[i]);
1030 if (is_true(eval->vtbl, v)) {
1031 return v;
1032 }
1033 assert(is_false(eval->vtbl, v));
1034 }
1035
1036 return vtbl_mk_false(eval->vtbl);
1037 }
1038
1039
eval_xor(evaluator_t * eval,composite_term_t * xor)1040 static value_t eval_xor(evaluator_t *eval, composite_term_t *xor) {
1041 uint32_t i, n;
1042 value_t v, w;
1043
1044 n = xor->arity;
1045 v = vtbl_mk_false(eval->vtbl);
1046 for (i=0; i<n; i++) {
1047 w = eval_term(eval, xor->arg[i]);
1048 // v := v xor w: true if v != w, false if v == w
1049 v = vtbl_mk_bool(eval->vtbl, v != w);
1050 }
1051
1052 return v;
1053 }
1054
1055
eval_tuple(evaluator_t * eval,composite_term_t * tuple)1056 static value_t eval_tuple(evaluator_t *eval, composite_term_t *tuple) {
1057 value_t *a;
1058 value_t v;
1059 uint32_t i, n;
1060
1061 n = tuple->arity;
1062 a = alloc_istack_array(&eval->stack, n);
1063 for (i=0; i<n; i++) {
1064 a[i] = eval_term(eval, tuple->arg[i]);
1065 }
1066 v = vtbl_mk_tuple(eval->vtbl, n, a);
1067 free_istack_array(&eval->stack, a);
1068
1069 return v;
1070 }
1071
1072
eval_select(evaluator_t * eval,select_term_t * select)1073 static value_t eval_select(evaluator_t *eval, select_term_t *select) {
1074 value_t v;
1075 value_tuple_t *t;
1076
1077 v = eval_term(eval, select->arg);
1078 t = vtbl_tuple(eval->vtbl, v);
1079 assert(0 <= select->idx && select->idx < t->nelems);
1080
1081 return t->elem[select->idx];
1082 }
1083
1084
eval_update(evaluator_t * eval,composite_term_t * update)1085 static value_t eval_update(evaluator_t *eval, composite_term_t *update) {
1086 value_t *a;
1087 value_t v, f;
1088 uint32_t i, n;
1089
1090 assert(update->arity >= 3);
1091
1092 n = update->arity - 2;
1093 a = alloc_istack_array(&eval->stack, n);
1094 f = eval_term(eval, update->arg[0]);
1095 for (i=0; i<n; i++) {
1096 a[i] = eval_term(eval, update->arg[i+1]);
1097 }
1098 v = eval_term(eval, update->arg[n+1]);
1099
1100 v = vtbl_mk_update(eval->vtbl, f, n, a, v);
1101 free_istack_array(&eval->stack, a);
1102
1103 return v;
1104 }
1105
1106
eval_distinct(evaluator_t * eval,composite_term_t * distinct)1107 static value_t eval_distinct(evaluator_t *eval, composite_term_t *distinct) {
1108 value_t *a;
1109 value_t v, eq;
1110 uint32_t i, j, n;
1111
1112 n = distinct->arity;
1113 a = alloc_istack_array(&eval->stack, n);
1114 for (i=0; i<n; i++) {
1115 v = eval_term(eval, distinct->arg[i]);
1116
1117 for (j=0; j<i; j++) {
1118 eq = vtbl_eval_eq(eval->vtbl, a[j], v);
1119 if (is_unknown(eval->vtbl, eq)) {
1120 v = eq; // i.e., unknown
1121 goto done;
1122 } else if (is_true(eval->vtbl, eq)) {
1123 // a[j] == v so distinct is false
1124 v = vtbl_mk_false(eval->vtbl);
1125 goto done;
1126 }
1127 }
1128 a[i] = v;
1129 }
1130
1131 v = vtbl_mk_true(eval->vtbl);
1132
1133 done:
1134 free_istack_array(&eval->stack, a);
1135 return v;
1136 }
1137
1138
1139
1140
1141 /*
1142 * Return a default value of type tau
1143 */
make_default_value(evaluator_t * eval,type_t tau)1144 static value_t make_default_value(evaluator_t *eval, type_t tau) {
1145 return vtbl_make_object(eval->vtbl, tau);
1146 }
1147
1148
1149
1150 /*
1151 * Uninterpreted term t
1152 * - t has no concrete value assigned in the model
1153 * - the model keeps term substitution (in alias_map);
1154 */
eval_uninterpreted(evaluator_t * eval,term_t t)1155 static value_t eval_uninterpreted(evaluator_t *eval, term_t t) {
1156 term_t u;
1157 value_t v;
1158
1159 assert(eval->model->has_alias);
1160 // check for a substitution
1161 u = model_find_term_substitution(eval->model, t);
1162 if (u == NULL_TERM) {
1163 // assign a default value based on t's type
1164 v = make_default_value(eval, term_type(eval->terms, t));
1165 } else {
1166 // [t --> u] is a substitution in the alias table
1167 v = eval_term(eval, u);
1168 }
1169
1170 return v;
1171 }
1172
1173
1174
1175 /*
1176 * Compute the value v of term t in the model
1177 * - add the mapping t := v to the cache
1178 * - raise an exception if t can't be evaluated
1179 */
eval_term(evaluator_t * eval,term_t t)1180 static value_t eval_term(evaluator_t *eval, term_t t) {
1181 term_table_t *terms;
1182 bool negative;
1183 value_t v;
1184
1185 negative = is_neg_term(t);
1186 t = unsigned_term(t);
1187
1188 /*
1189 * First check the model itself then check the cache.
1190 * If no value is mapped to t in either of them, compute t's
1191 * value v and add the mapping t := v to the cache.
1192 */
1193 v = model_find_term_value(eval->model, t);
1194 if (v == null_value) {
1195 v = eval_cached_value(eval, t);
1196 if (v == null_value) {
1197 terms = eval->terms;
1198
1199 switch (term_kind(terms, t)) {
1200 case CONSTANT_TERM:
1201 if (t == true_term) {
1202 v = vtbl_mk_true(eval->vtbl);
1203 } else if (t == false_term) {
1204 v = vtbl_mk_false(eval->vtbl);
1205 } else {
1206 v = vtbl_mk_const(eval->vtbl, term_type(terms, t), constant_term_index(terms, t),
1207 term_name(terms, t));
1208 }
1209 break;
1210
1211 case ARITH_CONSTANT:
1212 v = vtbl_mk_rational(eval->vtbl, rational_term_desc(terms, t));
1213 break;
1214
1215 case BV64_CONSTANT:
1216 v = eval_bv64_constant(eval, bvconst64_term_desc(terms, t));
1217 break;
1218
1219 case BV_CONSTANT:
1220 v = eval_bv_constant(eval, bvconst_term_desc(terms, t));
1221 break;
1222
1223 case VARIABLE:
1224 // free variable
1225 longjmp(eval->env, MDL_EVAL_FREEVAR_IN_TERM);
1226 break;
1227
1228 case UNINTERPRETED_TERM:
1229 // t has no value mapped in the model
1230 if (eval->model->has_alias) {
1231 v = eval_uninterpreted(eval, t);
1232 } else {
1233 longjmp(eval->env, MDL_EVAL_UNKNOWN_TERM);
1234 }
1235 break;
1236
1237 case ARITH_EQ_ATOM:
1238 v = eval_arith_eq(eval, arith_eq_arg(terms, t));
1239 break;
1240
1241 case ARITH_GE_ATOM:
1242 v = eval_arith_ge(eval, arith_ge_arg(terms, t));
1243 break;
1244
1245 case ARITH_IS_INT_ATOM:
1246 v = eval_arith_is_int(eval, arith_is_int_arg(terms, t));
1247 break;
1248
1249 case ARITH_FLOOR:
1250 v = eval_arith_floor(eval, arith_floor_arg(terms, t));
1251 break;
1252
1253 case ARITH_CEIL:
1254 v = eval_arith_ceil(eval, arith_ceil_arg(terms, t));
1255 break;
1256
1257 case ARITH_ABS:
1258 v = eval_arith_abs(eval, arith_abs_arg(terms, t));
1259 break;
1260
1261 case ITE_TERM:
1262 case ITE_SPECIAL:
1263 v = eval_ite(eval, ite_term_desc(terms, t));
1264 break;
1265
1266 case APP_TERM:
1267 v = eval_app(eval, app_term_desc(terms, t));
1268 break;
1269
1270 case UPDATE_TERM:
1271 v = eval_update(eval, update_term_desc(terms, t));
1272 break;
1273
1274 case TUPLE_TERM:
1275 v = eval_tuple(eval, tuple_term_desc(terms, t));
1276 break;
1277
1278 case EQ_TERM:
1279 v = eval_eq(eval, eq_term_desc(terms, t));
1280 break;
1281
1282 case DISTINCT_TERM:
1283 v = eval_distinct(eval, distinct_term_desc(terms, t));
1284 break;
1285
1286 case FORALL_TERM:
1287 // don't try to evaluate forall for now
1288 // but we could deal with quantification over finite types
1289 longjmp(eval->env, MDL_EVAL_QUANTIFIER);
1290 break;
1291
1292 case LAMBDA_TERM:
1293 // don't evaluate
1294 longjmp(eval->env, MDL_EVAL_LAMBDA);
1295 break;
1296
1297 case OR_TERM:
1298 v = eval_or(eval, or_term_desc(terms, t));
1299 break;
1300
1301 case XOR_TERM:
1302 v = eval_xor(eval, xor_term_desc(terms, t));
1303 break;
1304
1305 case ARITH_BINEQ_ATOM:
1306 v = eval_arith_bineq(eval, arith_bineq_atom_desc(terms, t));
1307 break;
1308
1309 case ARITH_RDIV:
1310 v = eval_arith_rdiv(eval, arith_rdiv_term_desc(terms, t));
1311 break;
1312
1313 case ARITH_IDIV:
1314 v = eval_arith_idiv(eval, arith_idiv_term_desc(terms, t));
1315 break;
1316
1317 case ARITH_MOD:
1318 v = eval_arith_mod(eval, arith_mod_term_desc(terms, t));
1319 break;
1320
1321 case ARITH_DIVIDES_ATOM:
1322 v = eval_arith_divides(eval, arith_divides_atom_desc(terms, t));
1323 break;
1324
1325 case BV_ARRAY:
1326 v = eval_bv_array(eval, bvarray_term_desc(terms, t));
1327 break;
1328
1329 case BV_DIV:
1330 v = eval_bv_div(eval, bvdiv_term_desc(terms, t));
1331 break;
1332
1333 case BV_REM:
1334 v = eval_bv_rem(eval, bvrem_term_desc(terms, t));
1335 break;
1336
1337 case BV_SDIV:
1338 v = eval_bv_sdiv(eval, bvsdiv_term_desc(terms, t));
1339 break;
1340
1341 case BV_SREM:
1342 v = eval_bv_srem(eval, bvsrem_term_desc(terms, t));
1343 break;
1344
1345 case BV_SMOD:
1346 v = eval_bv_smod(eval, bvsmod_term_desc(terms, t));
1347 break;
1348
1349 case BV_SHL:
1350 v = eval_bv_shl(eval, bvshl_term_desc(terms, t));
1351 break;
1352
1353 case BV_LSHR:
1354 v = eval_bv_lshr(eval, bvlshr_term_desc(terms, t));
1355 break;
1356
1357 case BV_ASHR:
1358 v = eval_bv_ashr(eval, bvashr_term_desc(terms, t));
1359 break;
1360
1361 case BV_EQ_ATOM:
1362 v = eval_bveq(eval, bveq_atom_desc(terms, t));
1363 break;
1364
1365 case BV_GE_ATOM:
1366 v = eval_bvge(eval, bvge_atom_desc(terms, t));
1367 break;
1368
1369 case BV_SGE_ATOM:
1370 v = eval_bvsge(eval, bvsge_atom_desc(terms, t));
1371 break;
1372
1373 case SELECT_TERM:
1374 v = eval_select(eval, select_term_desc(terms, t));
1375 break;
1376
1377 case BIT_TERM:
1378 v = eval_bit(eval, bit_term_desc(terms, t));
1379 break;
1380
1381 case POWER_PRODUCT:
1382 if (is_bitvector_term(terms, t)) {
1383 v = eval_bv_pprod(eval, pprod_term_desc(terms, t), term_bitsize(terms, t));
1384 } else {
1385 assert(is_arithmetic_term(terms, t));
1386 v = eval_arith_pprod(eval, pprod_term_desc(terms, t));
1387 }
1388 break;
1389
1390 case ARITH_POLY:
1391 v = eval_arith_poly(eval, poly_term_desc(terms, t));
1392 break;
1393
1394 case BV64_POLY:
1395 v = eval_bv64_poly(eval, bvpoly64_term_desc(terms, t));
1396 break;
1397
1398 case BV_POLY:
1399 v = eval_bv_poly(eval, bvpoly_term_desc(terms, t));
1400 break;
1401
1402 default:
1403 assert(false);
1404 longjmp(eval->env, MDL_EVAL_INTERNAL_ERROR);
1405 break;
1406 }
1407
1408 // if the result v is unknown we quit now
1409 assert(v >= 0); // Coverity thinks v can be negative.
1410 if (object_is_unknown(eval->vtbl, v)) {
1411 longjmp(eval->env, MDL_EVAL_FAILED);
1412 }
1413
1414 eval_cache_map(eval, t, v);
1415 }
1416 }
1417
1418 if (negative) {
1419 v = vtbl_mk_not(eval->vtbl, v);
1420 }
1421
1422 return v;
1423 }
1424
1425
1426 /*
1427 * Compute the value of t in the model
1428 * - t must be a valid term
1429 * - return a negative code if there's an error
1430 * - otherwise, return the id of a concrete object of eval->model.vtbl
1431 *
1432 * Evaluation may create new objects. All these new objects are
1433 * permananet in eval->vtbl.
1434 */
eval_in_model(evaluator_t * eval,term_t t)1435 value_t eval_in_model(evaluator_t *eval, term_t t) {
1436 value_t v;
1437
1438 v = setjmp(eval->env);
1439 if (v == 0) {
1440 v = eval_term(eval, t);
1441 } else {
1442 assert(v < 0); // error code after longjmp
1443 reset_istack(&eval->stack);
1444 }
1445
1446 return v;
1447 }
1448
1449
1450 /*
1451 * Check whether t is true in the model
1452 * - t must be a valid term
1453 * - return true if t evaluates to true
1454 * - return false if t can't be evaluated or
1455 * if t's value is not boolean or not true.
1456 */
eval_to_true_in_model(evaluator_t * eval,term_t t)1457 bool eval_to_true_in_model(evaluator_t *eval, term_t t) {
1458 value_t v;
1459
1460 v = eval_in_model(eval, t);
1461 return good_object(eval->vtbl, v) && is_true(eval->vtbl, v);
1462 }
1463
1464
1465 /*
1466 * Check whether t is false in the model
1467 * - t must be a valid term
1468 * - return true if t evaluates to true
1469 * - return false if t can't be evaluated or
1470 * if t's value is not boolean or not true.
1471 */
eval_to_false_in_model(evaluator_t * eval,term_t t)1472 bool eval_to_false_in_model(evaluator_t *eval, term_t t) {
1473 value_t v;
1474
1475 v = eval_in_model(eval, t);
1476 return good_object(eval->vtbl, v) && is_false(eval->vtbl, v);
1477 }
1478
1479
1480 /*
1481 * Check whether t is zero in the model
1482 * - t must be a valid term
1483 * - if t is an arithmetic term, this checks whether value(t) == 0
1484 * - if t is a bit-vector term, this checks whether value(t) == 0b0000...
1485 * - return false if t can't be evaluated, or if t is not an arithemtic
1486 * term nor a bitvector term, or if t's value is not zero.
1487 */
eval_to_zero_in_model(evaluator_t * eval,term_t t)1488 bool eval_to_zero_in_model(evaluator_t *eval, term_t t) {
1489 value_t v;
1490
1491 v = eval_in_model(eval, t);
1492 return good_object(eval->vtbl, v) &&
1493 (is_zero(eval->vtbl, v) || is_bvzero(eval->vtbl, v));
1494 }
1495
1496 /*
1497 * Check whether t evaluates to +/-1 in the model
1498 * - t must be a valid term
1499 * - return false if t can't be evaluated or its value is not a rational
1500 * - return true if t's value is either +1 or -1
1501 */
eval_to_unit_in_model(evaluator_t * eval,term_t t)1502 bool eval_to_unit_in_model(evaluator_t *eval, term_t t) {
1503 value_t v;
1504
1505 v = eval_in_model(eval, t);
1506 return good_object(eval->vtbl, v) && is_unit(eval->vtbl, v);
1507 }
1508
1509
1510
1511
1512 /*
1513 * Compute the values of terms a[0 ... n-1]
1514 * - don't return anything
1515 * - the value of a[i] can be queried by using eval_in_model(eval, a[i]) later
1516 * (this reads the value from eval->cache so that's cheap).
1517 */
eval_terms_in_model(evaluator_t * eval,const term_t * a,uint32_t n)1518 void eval_terms_in_model(evaluator_t *eval, const term_t *a, uint32_t n) {
1519 uint32_t i;
1520
1521 for (i=0; i<n; i++) {
1522 (void) eval_in_model(eval, a[i]);
1523 }
1524 }
1525
1526
1527 /*
1528 * Check whether term t is useful:
1529 * - return true if t is unintepreted and has no existing value in eval->model
1530 * and is not mapped to another term u in the alias_map
1531 */
term_is_useful(model_t * model,term_t t)1532 static bool term_is_useful(model_t *model, term_t t) {
1533 value_t v;
1534
1535 if (term_kind(model->terms, t) == UNINTERPRETED_TERM) {
1536 v = model_find_term_value(model, t);
1537 if (v == null_value && model->has_alias) {
1538 return model_find_term_substitution(model, t) == NULL_TERM;
1539 }
1540 }
1541 return false;
1542 }
1543
1544 /*
1545 * Add a mapping t->v in eval->model for every pair (t, v) found in eval->cache
1546 * and such that t is useful.
1547 */
eval_record_useful_terms(evaluator_t * eval)1548 void eval_record_useful_terms(evaluator_t *eval) {
1549 model_t *model;
1550 int_hmap_t *cache;
1551 int_hmap_pair_t *r;
1552
1553 model = eval->model;
1554 cache = &eval->cache;
1555 r = int_hmap_first_record(cache);
1556 while (r != NULL) {
1557 // r->key is the term, r->val is the value
1558 if (term_is_useful(model, r->key) && !is_unknown(eval->vtbl, r->val)) {
1559 model_map_term(model, r->key, r->val);
1560 }
1561 r = int_hmap_next_record(cache, r);
1562 }
1563
1564 }
1565
1566 /*
1567 * Cached-term collector:
1568 * - call f(aux, t) for every t that's stored in eval->cache
1569 * if f(aux, t) returns true, add t to v
1570 * - f must not have side effects
1571 */
evaluator_collect_cached_terms(evaluator_t * eval,void * aux,model_filter_t f,ivector_t * v)1572 void evaluator_collect_cached_terms(evaluator_t *eval, void *aux, model_filter_t f, ivector_t *v) {
1573 int_hmap_t *cache;
1574 int_hmap_pair_t *r;
1575
1576 cache = &eval->cache;
1577 r = int_hmap_first_record(cache);
1578 while (r != NULL) {
1579 if (f(aux, r->key)) {
1580 ivector_push(v, r->key);
1581 }
1582 r = int_hmap_next_record(cache, r);
1583 }
1584 }
1585