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