• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SRI-CSL / yices2 / 16032530443

02 Jul 2025 06:08PM UTC coverage: 60.349% (-5.0%) from 65.357%
16032530443

Pull #582

github

web-flow
Merge b7e09d316 into b3af64ab1
Pull Request #582: Update ci

63716 of 105580 relevant lines covered (60.35%)

1127640.75 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

63.41
/src/model/model_eval.c
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
#ifdef HAVE_MCSAT
30
#include "poly/rational.h"
31
#include "poly/algebraic_number.h"
32
#endif
33

34

35
/*
36
 * Wrapper for q_clear to avoid compilation warnings
37
 * (some versions of GCC complain about inlining q_clear)
38
 */
39
static void clear_rational(rational_t *q) {
224,997✔
40
  q_clear(q);
224,997✔
41
}
224,997✔
42

43

44
/*
45
 * Initialize eval for the given model
46
 */
47
void init_evaluator(evaluator_t *eval, model_t *model) {
58,828✔
48
  eval->model = model;
58,828✔
49
  eval->terms = model->terms;
58,828✔
50
  eval->vtbl = &model->vtbl;
58,828✔
51

52
  // give default interpretations for the divide by zero
53
  // functions.
54
  vtbl_set_default_zero_divide(eval->vtbl);
58,828✔
55

56
  init_int_hmap(&eval->cache, 0); // use the default hmap size
58,828✔
57
  init_istack(&eval->stack);
58,828✔
58
  // eval->env is not initialized
59
}
58,828✔
60

61

62
/*
63
 * Delete caches and stack
64
 */
65
void delete_evaluator(evaluator_t *eval) {
58,828✔
66
  eval->model = NULL;
58,828✔
67
  eval->terms = NULL;
58,828✔
68
  eval->vtbl = NULL;
58,828✔
69
  delete_int_hmap(&eval->cache);
58,828✔
70
  delete_istack(&eval->stack);
58,828✔
71
}
58,828✔
72

73

74

75
/*
76
 * Reset: empty the caches
77
 */
78
void reset_evaluator(evaluator_t *eval) {
×
79
  int_hmap_reset(&eval->cache);
×
80
  reset_istack(&eval->stack);
×
81
  value_table_start_tmp(eval->vtbl);
×
82
}
×
83

84

85

86
/*
87
 * Get the value mapped to term t in the internal cache
88
 * - return null_value if nothing is mapped to t
89
 */
90
static value_t eval_cached_value(evaluator_t *eval, term_t t) {
2,524,425✔
91
  int_hmap_pair_t *r;
92

93
  assert(good_term(eval->terms, t));
94

95
  r = int_hmap_find(&eval->cache, t);
2,524,425✔
96
  if (r == NULL) {
2,524,425✔
97
    return null_value;
1,498,691✔
98
  } else {
99
    return r->val;
1,025,734✔
100
  }
101
}
102

103

104
/*
105
 * Add the mapping t := v to the cache
106
 * - t must not be mapped to an object already
107
 */
108
static void eval_cache_map(evaluator_t *eval, term_t t, value_t v) {
1,498,686✔
109
  int_hmap_pair_t *r;
110

111
  assert(good_term(eval->terms, t) && good_object(eval->vtbl, v));
112

113
  r = int_hmap_get(&eval->cache, t);
1,498,686✔
114
  assert(r->val < 0);
115
  r->val = v;
1,498,686✔
116
}
1,498,686✔
117

118

119

120
/*
121
 * EVALUATION:
122
 *
123
 * Compute the value v of term t in the model
124
 * - add the mapping t := v  to the cache
125
 * - raise an exception if t can't be evaluated
126
 */
127
static value_t eval_term(evaluator_t *eval, term_t t);
128

129
/*
130
 * Attempt to get a rational value for v
131
 * - fails with a longjmp if v is an algebraic number
132
 */
133
static rational_t *eval_get_rational(evaluator_t *eval, value_t v) {
×
134
  if (object_is_algebraic(eval->vtbl, v)) {
×
135
    longjmp(eval->env, MDL_EVAL_FAILED);
×
136
  }
137
  return vtbl_rational(eval->vtbl, v);
×
138
}
139

140
/*
141
 * Check whether v is zero
142
 */
143
static bool eval_is_zero(evaluator_t *eval, value_t v) {
2✔
144
  if (object_is_rational(eval->vtbl, v)) {
2✔
145
    return q_is_zero(vtbl_rational(eval->vtbl, v));
2✔
146
  } else {
147
#ifdef HAVE_MCSAT
148
    return lp_algebraic_number_sgn(vtbl_algebraic_number(eval->vtbl, v)) == 0;
149
#else
150
    assert(false);
151
    return false;
×
152
#endif
153
  }
154
}
155

156
/*
157
 * Attempt to get a non-zero rational value for v
158
 * - fails if v is an algebraic number or if it is zero
159
 */
160
static rational_t *eval_get_nz_rational(evaluator_t *eval, value_t v) {
×
161
  rational_t *q;
162

163
  q = eval_get_rational(eval, v);
×
164
  if (q_is_zero(q)) {
×
165
    longjmp(eval->env, MDL_EVAL_FAILED);
×
166
  }
167
  return q;
×
168
}
169

170
#ifdef HAVE_MCSAT
171
static lp_algebraic_number_t *eval_get_nz_algebraic(evaluator_t *eval, value_t v) {
172
  lp_algebraic_number_t *a;
173

174
  a = vtbl_algebraic_number(eval->vtbl, v);
175
  if (lp_algebraic_number_sgn(a) == 0) {
176
    longjmp(eval->env, MDL_EVAL_FAILED);
177
  }
178
  return a;
179
}
180
#endif
181

182

183

184
/*
185
 * Evaluate terms t[0 ... n-1] and store the result in a[0 .. n-1]
186
 */
187
static void eval_term_array(evaluator_t *eval, term_t *t, value_t *a, uint32_t n) {
267,715✔
188
  uint32_t i;
189

190
  for (i=0; i<n; i++) {
760,982✔
191
    a[i] = eval_term(eval, t[i]);
493,267✔
192
  }
193
}
267,715✔
194

195

196
/*
197
 * Bitvector constant: 64bits or less
198
 */
199
static value_t eval_bv64_constant(evaluator_t *eval, bvconst64_term_t *c) {
22,099✔
200
  return vtbl_mk_bv_from_bv64(eval->vtbl, c->bitsize, c->value);
22,099✔
201
}
202

203

204
/*
205
 * Bitvector constant
206
 */
207
static value_t eval_bv_constant(evaluator_t *eval, bvconst_term_t *c) {
67✔
208
  return vtbl_mk_bv_from_bv(eval->vtbl, c->bitsize, c->data);
67✔
209
}
210

211

212
/*
213
 * Arithmetic atom: t == 0
214
 */
215
static value_t eval_arith_eq(evaluator_t *eval, term_t t) {
31,290✔
216
  value_t v;
217

218
  v = eval_term(eval, t);
31,290✔
219

220
  if (object_is_rational(eval->vtbl, v)) {
31,290✔
221
    return vtbl_mk_bool(eval->vtbl, q_is_zero(vtbl_rational(eval->vtbl, v)));
31,290✔
222
  } else {
223
#ifdef HAVE_MCSAT
224
    return vtbl_mk_bool(eval->vtbl, lp_algebraic_number_sgn(vtbl_algebraic_number(eval->vtbl, v)) == 0);
225
#else
226
    assert(false);
227
    return MDL_EVAL_INTERNAL_ERROR;
×
228
#endif
229
  }
230
}
231

232

233
/*
234
 * Arithmetic atom: t >= 0
235
 */
236
static value_t eval_arith_ge(evaluator_t *eval, term_t t) {
91,780✔
237
  value_t v;
238

239
  v = eval_term(eval, t);
91,780✔
240

241
  if (object_is_rational(eval->vtbl, v)) {
91,780✔
242
    return vtbl_mk_bool(eval->vtbl, q_is_nonneg(vtbl_rational(eval->vtbl, v)));
91,780✔
243
  } else {
244
#ifdef HAVE_MCSAT
245
    return vtbl_mk_bool(eval->vtbl, lp_algebraic_number_sgn(vtbl_algebraic_number(eval->vtbl, v)) >= 0);
246
#else
247
    assert(false);
248
    return MDL_EVAL_INTERNAL_ERROR;
×
249
#endif
250
  }
251
}
252

253
/*
254
 * Arithmetic atom: (is_int t)
255
 */
256
static value_t eval_arith_is_int(evaluator_t *eval, term_t t) {
×
257
  value_t v;
258

259
  v = eval_term(eval, t);
×
260

261
  if (object_is_rational(eval->vtbl, v)) {
×
262
    return vtbl_mk_bool(eval->vtbl, q_is_integer(vtbl_rational(eval->vtbl, v)));
×
263
  } else {
264
#ifdef HAVE_MCSAT
265
    return vtbl_mk_bool(eval->vtbl, lp_algebraic_number_is_integer(vtbl_algebraic_number(eval->vtbl, v)));
266
#else
267
    assert(false);
268
    return MDL_EVAL_INTERNAL_ERROR;
×
269
#endif
270
  }
271
}
272

273

274
/*
275
 * Arithmetic term: (floor t)
276
 */
277
static value_t eval_arith_floor(evaluator_t *eval, term_t t) {
×
278
  rational_t q;
279
  value_t v;
280

281
  v = eval_term(eval, t);
×
282

283
  if (object_is_rational(eval->vtbl, v)) {
×
284
    q_init(&q);
×
285
    q_set(&q, vtbl_rational(eval->vtbl, v)); // q := value of t
×
286
    q_floor(&q);
×
287
    q_normalize(&q);
×
288

289
    v = vtbl_mk_rational(eval->vtbl, &q);
×
290
  
291
    clear_rational(&q);
×
292
  } else {
293
#ifdef HAVE_MCSAT
294
    lp_integer_t a_floor;
295
    lp_integer_construct(&a_floor);
296
    lp_algebraic_number_floor(vtbl_algebraic_number(eval->vtbl, v), &a_floor);
297
    q_init(&q);
298
    q_set_mpz(&q, &a_floor);
299

300
    v = vtbl_mk_rational(eval->vtbl, &q);
301

302
    clear_rational(&q);
303
    lp_integer_destruct(&a_floor);
304
#else
305
    assert(false);
306
    return MDL_EVAL_INTERNAL_ERROR;
×
307
#endif
308
  }
309

310
  return v;
×
311
}
312

313

314
/*
315
 * Arithmetic term: (ceil t)
316
 */
317
static value_t eval_arith_ceil(evaluator_t *eval, term_t t) {
×
318
  rational_t q;
319
  value_t v;
320

321
  v = eval_term(eval, t);
×
322
  
323
  if (object_is_rational(eval->vtbl, v)) {
×
324
    q_init(&q);
×
325
    q_set(&q, vtbl_rational(eval->vtbl, v)); // q := value of t
×
326
    q_ceil(&q);
×
327
    q_normalize(&q);
×
328

329
    v = vtbl_mk_rational(eval->vtbl, &q);
×
330

331
    clear_rational(&q);
×
332
  } else {
333
#ifdef HAVE_MCSAT
334
    lp_integer_t a_ceil;
335
    lp_integer_construct(&a_ceil);
336
    lp_algebraic_number_ceiling(vtbl_algebraic_number(eval->vtbl, v), &a_ceil);
337
    q_init(&q);
338
    q_set_mpz(&q, &a_ceil);
339

340
    v = vtbl_mk_rational(eval->vtbl, &q);
341

342
    clear_rational(&q);
343
    lp_integer_destruct(&a_ceil);
344
#else
345
    assert(false);
346
    return MDL_EVAL_INTERNAL_ERROR;
×
347
#endif
348
  }
349

350
  return v;
×
351
}
352

353

354
/*
355
 * Arithmetic term: (abs t)
356
 */
357
static value_t eval_arith_abs(evaluator_t *eval, term_t t) {
×
358
  rational_t q;
359
  value_t v;
360

361
#ifdef HAVE_MCSAT
362
  const lp_algebraic_number_t* a;
363
  lp_algebraic_number_t a_neg;
364
#endif
365

366
  v = eval_term(eval, t);
×
367
  
368
  if (object_is_rational(eval->vtbl, v)) {
×
369
    q_init(&q);
×
370
    q_set_abs(&q, vtbl_rational(eval->vtbl, v)); // q := value of t
×
371
    q_normalize(&q);
×
372

373
    v = vtbl_mk_rational(eval->vtbl, &q);
×
374

375
    clear_rational(&q);
×
376
  } else {
377
#ifdef HAVE_MCSAT
378
    a = vtbl_algebraic_number(eval->vtbl, v);
379
    // If negative, negate, otherwise stays same
380
    if (lp_algebraic_number_sgn(a) < 0) {
381
      lp_algebraic_number_construct_zero(&a_neg);
382
      lp_algebraic_number_neg(&a_neg, a);
383

384
      v = vtbl_mk_algebraic(eval->vtbl, &a_neg);
385

386
      lp_algebraic_number_destruct(&a_neg);
387
    }
388
#else
389
    assert(false);
390
    return MDL_EVAL_INTERNAL_ERROR;
×
391
#endif
392
  }
393

394
  return v;
×
395
}
396

397
#ifdef HAVE_MCSAT
398
static inline
399
void lp_rational_construct_from_rational(lp_rational_t* q_lp, const rational_t* q) {
400
  if (is_ratgmp(q)) {
401
    lp_rational_construct_copy(q_lp, get_gmp(q));
402
  } else {
403
    lp_rational_construct_from_int(q_lp, get_num(q), get_den(q));
404
  }
405
}
406
#endif
407

408
/*
409
 * Arithmetic atom: v1 == v2
410
 */
411
static value_t eval_arith_bineq(evaluator_t *eval, composite_term_t *eq) {
18,360✔
412
  bool result;
413
  value_t v1, v2;
414
  assert(eq->arity == 2);
415

416
  v1 = eval_term(eval, eq->arg[0]);
18,360✔
417
  v2 = eval_term(eval, eq->arg[1]);
18,360✔
418

419
  if (object_is_rational(eval->vtbl, v1) && object_is_rational(eval->vtbl, v2)) {
18,360✔
420
    result = v1 == v2; // because of hash consing
18,360✔
421
  } else {
422
#ifdef HAVE_MCSAT
423
    lp_rational_t q;
424
    bool v1_algebraic = object_is_algebraic(eval->vtbl, v1);
425
    bool v2_algebraic = object_is_algebraic(eval->vtbl, v2);
426
    lp_algebraic_number_t* a1 = v1_algebraic ? vtbl_algebraic_number(eval->vtbl, v1) : NULL;
427
    lp_algebraic_number_t* a2 = v2_algebraic ? vtbl_algebraic_number(eval->vtbl, v2) : NULL;
428
    if (v1_algebraic && v2_algebraic) {
429
      result = lp_algebraic_number_cmp(a1, a2) == 0;
430
    } else if (v1_algebraic) {
431
      lp_rational_construct_from_rational(&q, vtbl_rational(eval->vtbl, v2));
432
      result = lp_algebraic_number_cmp_rational(a1, &q) == 0;
433
      lp_rational_destruct(&q);
434
    } else {
435
      assert(v2_algebraic);
436
      lp_rational_construct_from_rational(&q, vtbl_rational(eval->vtbl, v1));
437
      result = lp_algebraic_number_cmp_rational(a2, &q) == 0;
438
      lp_rational_destruct(&q);
439
    }
440
#else
441
    assert(false);
442
    return MDL_EVAL_INTERNAL_ERROR;
×
443
#endif
444
  }
445

446
  return vtbl_mk_bool(eval->vtbl, result);
18,360✔
447
}
448

449
static value_t eval_finitefield_bineq(evaluator_t *eval, composite_term_t *eq) {
×
450
  value_t v1, v2;
451

452
  assert(eq->arity == 2);
453

454
  v1 = eval_term(eval, eq->arg[0]);
×
455
  v2 = eval_term(eval, eq->arg[1]);
×
456

457
  assert(object_is_finitefield(eval->vtbl, v1));
458
  assert(object_is_finitefield(eval->vtbl, v2));
459

460
  return vtbl_mk_bool(eval->vtbl, v1 == v2);
×
461
}
462

463
/*
464
 * Compute division when one of the arguments is algebraic and return the result.
465
 */
466
#ifdef HAVE_MCSAT
467
static void eval_arith_rdiv_algebraic(evaluator_t *eval, value_t v1, value_t v2, lp_algebraic_number_t* result) {
468
  bool v1_algebraic = object_is_algebraic(eval->vtbl, v1);
469
  bool v2_algebraic = object_is_algebraic(eval->vtbl, v2);
470
  lp_algebraic_number_t* a1 = v1_algebraic ? vtbl_algebraic_number(eval->vtbl, v1) : NULL;
471
  lp_algebraic_number_t* a2 = v2_algebraic ? eval_get_nz_algebraic(eval, v2) : NULL;
472
  if (v1_algebraic && v2_algebraic) {
473
    lp_algebraic_number_div(result, a1, a2);
474
  } else {
475
    lp_rational_t tmp_q;
476
    lp_algebraic_number_t tmp_a;
477
    if (v1_algebraic) {
478
      lp_rational_construct_from_rational(&tmp_q, eval_get_nz_rational(eval, v2));
479
      lp_algebraic_number_construct_from_rational(&tmp_a, &tmp_q);
480
      lp_algebraic_number_div(result, a1, &tmp_a);
481
    } else {
482
      assert(v2_algebraic);
483
      lp_rational_construct_from_rational(&tmp_q, vtbl_rational(eval->vtbl, v1));
484
      lp_algebraic_number_construct_from_rational(&tmp_a, &tmp_q);
485
      lp_algebraic_number_div(result, &tmp_a, a2);
486
    }
487
    lp_algebraic_number_destruct(&tmp_a);
488
    lp_rational_destruct(&tmp_q);
489
  }
490
}
491
#endif
492

493
/*
494
 * Arithmetic term: (/ v1 v2) (division)
495
 */
496
static value_t eval_arith_rdiv(evaluator_t *eval, composite_term_t *d) {
2✔
497
  rational_t q;
498
  value_t v1, v2, o;
499
  
500
  assert(d->arity == 2);
501

502
  v1 = eval_term(eval, d->arg[0]);
2✔
503
  v2 = eval_term(eval, d->arg[1]);
2✔
504

505
  if (eval_is_zero(eval, v2)) {
2✔
506
    o = vtbl_eval_rdiv_by_zero(eval->vtbl, v1);
2✔
507
  } else if (object_is_rational(eval->vtbl, v1) && object_is_rational(eval->vtbl, v2)) {
×
508
    q_init(&q);
×
509
    q_set(&q, vtbl_rational(eval->vtbl, v1));
×
510
    q_div(&q, eval_get_nz_rational(eval, v2));
×
511
    q_normalize(&q);
×
512

513
    o = vtbl_mk_rational(eval->vtbl, &q);
×
514

515
    clear_rational(&q);
×
516
  } else {
517
#ifdef HAVE_MCSAT
518
    lp_algebraic_number_t result;
519
    lp_algebraic_number_construct_zero(&result);
520
    eval_arith_rdiv_algebraic(eval, v1, v2, &result);
521
    o = vtbl_mk_algebraic(eval->vtbl, &result);
522
    lp_algebraic_number_destruct(&result);
523
#else
524
    assert(false);
525
    o = MDL_EVAL_INTERNAL_ERROR;
×
526
#endif
527
  }
528

529
  return o;
2✔
530
}
531

532

533
/*
534
 * Arithmetic term: (div v1 v2) (integer division)
535
 */
536
static value_t eval_arith_idiv(evaluator_t *eval, composite_term_t *d) {
×
537
  rational_t q;
538
  value_t v1, v2, o;
539
  
540
  assert(d->arity == 2);
541

542
  v1 = eval_term(eval, d->arg[0]);
×
543
  v2 = eval_term(eval, d->arg[1]);
×
544

545
  if (eval_is_zero(eval, v2)) {
×
546
    o = vtbl_eval_idiv_by_zero(eval->vtbl, v1);
×
547
  } else if (object_is_rational(eval->vtbl, v1) && object_is_rational(eval->vtbl, v2)) {
×
548
    q_init(&q);
×
549
    q_smt2_div(&q, vtbl_rational(eval->vtbl, v1), eval_get_nz_rational(eval, v2));
×
550
    q_normalize(&q);
×
551

552
    o = vtbl_mk_rational(eval->vtbl, &q);
×
553

554
    clear_rational(&q);
×
555
  } else {
556
#ifdef HAVE_MCSAT
557
    // TODO(algebraic): is this necessary should we not assume that arguments are integers?
558
    lp_integer_t div_z;
559
    lp_integer_construct(&div_z);
560
    lp_algebraic_number_t div_a;
561
    lp_algebraic_number_construct_zero(&div_a);
562
    eval_arith_rdiv_algebraic(eval, v1, v2, &div_a);
563
    if (lp_algebraic_number_sgn(&div_a) > 0) {
564
      lp_algebraic_number_floor(&div_a, &div_z); // round down
565
    } else {
566
      lp_algebraic_number_ceiling(&div_a, &div_z); // round up
567
    }
568

569
    q_init(&q);
570
    q_set_mpz(&q, &div_z);
571

572
    o = vtbl_mk_rational(eval->vtbl, &q);
573

574
    clear_rational(&q);
575

576
    lp_algebraic_number_destruct(&div_a);
577
    lp_integer_destruct(&div_z);
578
#else
579
    assert(false);
580
    o = MDL_EVAL_INTERNAL_ERROR;
×
581
#endif
582
  }
583

584
  return o;
×
585
}
586

587

588
/*
589
 * Arithmetic term: (mod v1 v2)
590
 */
591
static value_t eval_arith_mod(evaluator_t *eval, composite_term_t *d) {
×
592
  rational_t q;
593
  value_t v1, v2, o;
594
  
595
  assert(d->arity == 2);
596

597
  v1 = eval_term(eval, d->arg[0]);
×
598
  v2 = eval_term(eval, d->arg[1]);
×
599

600
  if (eval_is_zero(eval, v2)) {
×
601
    o = vtbl_eval_mod_by_zero(eval->vtbl, v1);
×
602
  } else if (object_is_rational(eval->vtbl, v1) && object_is_rational(eval->vtbl, v2)) {
×
603
    q_init(&q);
×
604
    q_smt2_mod(&q, eval_get_rational(eval, v1), eval_get_nz_rational(eval, v2)); 
×
605
    q_normalize(&q);
×
606

607
    o = vtbl_mk_rational(eval->vtbl, &q);
×
608

609
    clear_rational(&q);
×
610
  } else {
611
#ifdef HAVE_MCSAT
612
    // TODO(algebraic): is this necessary should we not assume that arguments are integers?
613
    lp_integer_t div_z;
614
    lp_integer_construct(&div_z);
615
    lp_algebraic_number_t a, div_a;
616
    lp_algebraic_number_construct_zero(&a);
617

618
    // a = x / y
619
    eval_arith_rdiv_algebraic(eval, v1, v2, &a);
620

621
    // div_z := (div x y)
622
    if (lp_algebraic_number_sgn(&a) > 0) {
623
      lp_algebraic_number_floor(&a, &div_z); // round down
624
    } else {
625
      lp_algebraic_number_ceiling(&a, &div_z); // round up
626
    }
627

628
    // div_a := (div x y)
629
    lp_algebraic_number_construct_from_integer(&div_a, &div_z);
630

631
    // q := y * (div x y)
632

633
    // q := - x + y * (div x y)
634

635
    // q := x - y * (div x y) = (mod x y)
636

637
    q_init(&q);
638
    q_set_mpz(&q, &div_z);
639

640
    o = vtbl_mk_rational(eval->vtbl, &q);
641

642
    clear_rational(&q);
643

644
    lp_algebraic_number_destruct(&a);
645
    lp_algebraic_number_destruct(&div_a);
646
    lp_integer_destruct(&div_z);
647

648
#else
649
    assert(false);
650
    o = MDL_EVAL_INTERNAL_ERROR;
×
651
#endif
652
  }
653

654
  return o;
×
655
}
656

657

658
/*
659
 * Arithmetic term: (divides v1 v2)
660
 */
661
static value_t eval_arith_divides(evaluator_t *eval, composite_term_t *d) {
×
662
  value_t v1, v2;
663
  bool divides;
664
  
665
  assert(d->arity == 2);
666

667
  // it's OK for v1 to be zero here.
668
  v1 = eval_term(eval, d->arg[0]);
×
669
  v2 = eval_term(eval, d->arg[1]);
×
670
  divides = q_smt2_divides(eval_get_rational(eval, v1), eval_get_rational(eval, v2));
×
671

672
  return vtbl_mk_bool(eval->vtbl, divides);
×
673
}
674

675
#ifdef HAVE_MCSAT
676
static value_t eval_arith_pprod_algebraic(evaluator_t *eval, pprod_t *p) {
677
  lp_algebraic_number_t prod, tmp;
678
  mpq_t q;
679
  uint32_t i, n;
680
  term_t t;
681
  value_t o;
682

683
  mpq_init(q);
684
  lp_algebraic_number_construct_one(&prod);
685

686
  n = p->len;
687
  for (i=0; i<n && lp_algebraic_number_sgn(&prod) != 0; i++) {
688
    t = p->prod[i].var;
689
    o = eval_term(eval, t);
690
    // prod[i] is v ^ k so q := q * (o ^ k)
691
    if (object_is_rational(eval->vtbl, o)) {
692
      q_get_mpq(vtbl_rational(eval->vtbl, o), q);
693
      lp_algebraic_number_construct_from_rational(&tmp, q);
694
    } else {
695
      lp_algebraic_number_construct_copy(&tmp, vtbl_algebraic_number(eval->vtbl, o));
696
    }
697
    lp_algebraic_number_pow(&tmp,  &tmp, p->prod[i].exp);
698
    lp_algebraic_number_mul(&prod, &prod, &tmp);
699
    lp_algebraic_number_destruct(&tmp);
700
  }
701

702
  o = vtbl_mk_algebraic(eval->vtbl, &prod);
703

704
  mpq_clear(q);
705
  lp_algebraic_number_destruct(&prod);
706

707
  return o;
708
}
709
#endif
710

711
/*
712
 * Finite field atom: t == 0
713
 */
714
static value_t eval_arith_ff_eq(evaluator_t *eval, term_t t) {
×
715
  value_t v;
716

717
  v = eval_term(eval, t);
×
718
  assert(object_is_finitefield(eval->vtbl, v));
719

720
  value_ff_t *v_ff = vtbl_finitefield(eval->vtbl, v);
×
721
  return vtbl_mk_bool(eval->vtbl, q_is_zero(&v_ff->value));
×
722
}
723

724
/*
725
 * Power product: arithmetic
726
 */
727
static value_t eval_arith_pprod(evaluator_t *eval, pprod_t *p) {
×
728
  rational_t prod;
729
  term_t t;
730
  value_t o;
731

732
  q_init(&prod);
×
733
  q_set_one(&prod);
×
734

735
  uint32_t n = p->len;
×
736
  for (uint32_t i=0; i<n; i++) {
×
737
    t = p->prod[i].var;
×
738
    o = eval_term(eval, t);
×
739
    // prod[i] is v ^ k so q := q * (o ^ k)
740
    if (object_is_rational(eval->vtbl, o)) {
×
741
      q_mulexp(&prod, vtbl_rational(eval->vtbl, o), p->prod[i].exp);
×
742
    } else {
743
#ifdef HAVE_MCSAT
744
      // We need algebraic number computation
745
      o = eval_arith_pprod_algebraic(eval, p);
746
      clear_rational(&prod);
747
      return o;
748
#else
749
      assert(false);
750
      return MDL_EVAL_INTERNAL_ERROR;
×
751
#endif
752
    }
753
  }
754

755
  o = vtbl_mk_rational(eval->vtbl, &prod);
×
756

757
  clear_rational(&prod);
×
758

759
  return o;
×
760
}
761

762
/*
763
 * Power product: finite field arithmetic
764
 */
765
static value_t eval_arith_ff_pprod(evaluator_t *eval, pprod_t *p, const rational_t *mod) {
×
766
  rational_t prod;
767
  term_t t;
768
  value_t o;
769

770
  assert(mod && q_is_integer(mod));
771

772
  q_init(&prod);
×
773
  q_set_one(&prod);
×
774

775
  uint32_t n = p->len;
×
776
  for (uint32_t i=0; i<n; i++) {
×
777
    t = p->prod[i].var;
×
778
    o = eval_term(eval, t);
×
779
    assert(object_is_finitefield(eval->vtbl, o));
780
    value_ff_t *v_ff = vtbl_finitefield(eval->vtbl, o);
×
781
    assert(q_eq(&v_ff->mod, mod));
782
    // prod[i] is v ^ k so q := q * (o ^ k)
783
    q_mulexp(&prod, &v_ff->value, p->prod[i].exp);
×
784
  }
785

786
  assert(q_is_integer(&prod));
787
  q_integer_rem(&prod, mod);
×
788
  o = vtbl_mk_finitefield(eval->vtbl, &prod, mod);
×
789
  clear_rational(&prod);
×
790

791
  return o;
×
792
}
793

794
#ifdef HAVE_MCSAT
795
static value_t eval_arith_poly_algebraic(evaluator_t *eval, polynomial_t *p) {
796
  lp_algebraic_number_t sum, tmp_c, tmp_t;
797
  uint32_t i, n;
798
  term_t t;
799
  value_t v;
800
  mpq_t q;
801

802
  mpq_init(q);
803
  lp_algebraic_number_construct_zero(&sum); // sum = 0
804

805
  n = p->nterms;
806
  for (i=0; i<n; i++) {
807
    t = p->mono[i].var;
808
    q_get_mpq(&p->mono[i].coeff, q);
809
    lp_algebraic_number_construct_from_rational(&tmp_c, q);
810
    if (t == const_idx) {
811
      lp_algebraic_number_add(&sum, &sum, &tmp_c);
812
    } else {
813
      v = eval_term(eval, t);
814
      if (object_is_rational(eval->vtbl, v)) {
815
        q_get_mpq(vtbl_rational(eval->vtbl, v), q);
816
        lp_algebraic_number_construct_from_rational(&tmp_t, q);
817
      } else {
818
        lp_algebraic_number_construct_copy(&tmp_t, vtbl_algebraic_number(eval->vtbl, v));
819
      }
820
      lp_algebraic_number_mul(&tmp_t, &tmp_c, &tmp_t);
821
      lp_algebraic_number_add(&sum, &sum, &tmp_t);
822
      lp_algebraic_number_destruct(&tmp_t);
823
    }
824
    lp_algebraic_number_destruct(&tmp_c);
825
  }
826

827
  // convert sum to an object
828
  v = vtbl_mk_algebraic(eval->vtbl, &sum);
829

830
  mpq_clear(q);
831
  lp_algebraic_number_destruct(&sum);
832

833
  return v;
834
}
835
#endif
836

837
/*
838
 * Arithmetic polynomial
839
 */
840
static value_t eval_arith_poly(evaluator_t *eval, polynomial_t *p) {
224,997✔
841
  rational_t sum;
842
  uint32_t i, n;
843
  term_t t;
844
  value_t v;
845

846
  q_init(&sum); // sum = 0
224,997✔
847

848
  n = p->nterms;
224,997✔
849
  for (i=0; i<n; i++) {
691,572✔
850
    t = p->mono[i].var;
466,575✔
851
    if (t == const_idx) {
466,575✔
852
      q_add(&sum, &p->mono[i].coeff);
15,318✔
853
    } else {
854
      v = eval_term(eval, t);
451,257✔
855
      if (object_is_rational(eval->vtbl, v)) {
451,257✔
856
        q_addmul(&sum, &p->mono[i].coeff, vtbl_rational(eval->vtbl, v)); // sum := sum + coeff * aux
451,257✔
857
      } else {
858
#ifdef HAVE_MCSAT
859
        v = eval_arith_poly_algebraic(eval, p);
860
        clear_rational(&sum);
861
        return v;
862
#else
863
        assert(false);
864
        return MDL_EVAL_INTERNAL_ERROR;
×
865
#endif
866
      }
867
    }
868
  }
869

870
  // convert sum to an object
871
  v = vtbl_mk_rational(eval->vtbl, &sum);
224,997✔
872

873
  clear_rational(&sum);
224,997✔
874

875
  return v;
224,997✔
876
}
877

878
static value_t eval_arith_ff_poly(evaluator_t *eval, polynomial_t *p, const rational_t *mod) {
×
879
  rational_t sum;
880
  uint32_t i, n;
881
  term_t t;
882
  value_t v;
883
  value_ff_t *v_ff;
884

885
  q_init(&sum); // sum = 0
×
886

887
  n = p->nterms;
×
888
  for (i=0; i<n; i++) {
×
889
    t = p->mono[i].var;
×
890
    if (t == const_idx) {
×
891
      q_add(&sum, &p->mono[i].coeff);
×
892
    } else {
893
      v = eval_term(eval, t);
×
894
      assert(object_is_finitefield(eval->vtbl, v));
895
      v_ff = vtbl_finitefield(eval->vtbl, v);
×
896
      assert(q_eq(&v_ff->mod, mod));
897
      q_addmul(&sum, &p->mono[i].coeff, &v_ff->value); // sum := sum + coeff * aux
×
898
    }
899
  }
900

901
  // convert sum to an object
902
  assert(q_is_integer(&sum));
903
  assert(q_is_integer(mod));
904
  q_integer_rem(&sum, mod);
×
905
  v = vtbl_mk_finitefield(eval->vtbl, &sum, mod);
×
906

907
  clear_rational(&sum);
×
908

909
  return v;
×
910
}
911

912

913

914
/*
915
 * Bitvector terms
916
 */
917
static value_t eval_bv_array(evaluator_t *eval, composite_term_t *array) {
65,033✔
918
  uint32_t i, n;
919
  int32_t *a;
920
  value_t v;
921

922
  n = array->arity;
65,033✔
923
  a = alloc_istack_array(&eval->stack, n);
65,033✔
924
  for (i=0; i<n; i++) {
813,350✔
925
    v = eval_term(eval, array->arg[i]);
748,317✔
926
    a[i] = boolobj_value(eval->vtbl, v);
748,317✔
927
  }
928

929
  v = vtbl_mk_bv(eval->vtbl, n, a);
65,033✔
930

931
  free_istack_array(&eval->stack, a);
65,033✔
932

933
  return v;
65,033✔
934
}
935

936
static value_t eval_bit(evaluator_t *eval, select_term_t *select) {
306,850✔
937
  value_t v;
938
  value_bv_t *bv;
939
  bool b;
940

941
  v = eval_term(eval, select->arg);
306,850✔
942
  bv = vtbl_bitvector(eval->vtbl, v);
306,850✔
943
  assert(select->idx < bv->nbits);
944

945
  b = bvconst_tst_bit(bv->data, select->idx);
306,850✔
946

947
  return vtbl_mk_bool(eval->vtbl, b);
306,850✔
948
}
949

950
static term_t eval_bv_div(evaluator_t *eval, composite_term_t *app) {
1,753✔
951
  uint32_t *aux;
952
  uint32_t n, w;
953
  value_t v1, v2, v;
954
  value_bv_t *bv1, *bv2;
955

956
  assert(app->arity == 2);
957

958
  v1 = eval_term(eval, app->arg[0]);
1,753✔
959
  v2 = eval_term(eval, app->arg[1]);
1,753✔
960
  bv1 = vtbl_bitvector(eval->vtbl, v1);
1,753✔
961
  bv2 = vtbl_bitvector(eval->vtbl, v2);
1,753✔
962
  assert(bv1->nbits == bv2->nbits);
963

964
  n = bv1->nbits;
1,753✔
965
  w = bv1->width;
1,753✔
966
  assert(n>0 && w>0);
967

968
  aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
1,753✔
969
  bvconst_udiv2z(aux, n, bv1->data, bv2->data);
1,753✔
970
  v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
1,753✔
971

972
  free_istack_array(&eval->stack, (int32_t *) aux);
1,753✔
973

974
  return v;
1,753✔
975
}
976

977
static term_t eval_bv_rem(evaluator_t *eval, composite_term_t *app) {
1,448✔
978
  uint32_t *aux;
979
  uint32_t n, w;
980
  value_t v1, v2, v;
981
  value_bv_t *bv1, *bv2;
982

983
  assert(app->arity == 2);
984

985
  v1 = eval_term(eval, app->arg[0]);
1,448✔
986
  v2 = eval_term(eval, app->arg[1]);
1,448✔
987
  bv1 = vtbl_bitvector(eval->vtbl, v1);
1,448✔
988
  bv2 = vtbl_bitvector(eval->vtbl, v2);
1,448✔
989
  assert(bv1->nbits == bv2->nbits);
990

991
  n = bv1->nbits;
1,448✔
992
  w = bv1->width;
1,448✔
993
  assert(n>0 && w>0);
994

995
  aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
1,448✔
996
  bvconst_urem2z(aux, n, bv1->data, bv2->data);
1,448✔
997
  v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
1,448✔
998

999
  free_istack_array(&eval->stack, (int32_t *) aux);
1,448✔
1000

1001
  return v;
1,448✔
1002
}
1003

1004
static term_t eval_bv_sdiv(evaluator_t *eval, composite_term_t *app) {
1,437✔
1005
  uint32_t *aux;
1006
  uint32_t n, w;
1007
  value_t v1, v2, v;
1008
  value_bv_t *bv1, *bv2;
1009

1010
  assert(app->arity == 2);
1011

1012
  v1 = eval_term(eval, app->arg[0]);
1,437✔
1013
  v2 = eval_term(eval, app->arg[1]);
1,437✔
1014
  bv1 = vtbl_bitvector(eval->vtbl, v1);
1,437✔
1015
  bv2 = vtbl_bitvector(eval->vtbl, v2);
1,437✔
1016
  assert(bv1->nbits == bv2->nbits);
1017

1018
  n = bv1->nbits;
1,437✔
1019
  w = bv1->width;
1,437✔
1020
  assert(n>0 && w>0);
1021

1022
  aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
1,437✔
1023
  bvconst_sdiv2z(aux, n, bv1->data, bv2->data);
1,437✔
1024
  v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
1,437✔
1025

1026
  free_istack_array(&eval->stack, (int32_t *) aux);
1,437✔
1027

1028
  return v;
1,437✔
1029
}
1030

1031
static term_t eval_bv_srem(evaluator_t *eval, composite_term_t *app) {
1,335✔
1032
  uint32_t *aux;
1033
  uint32_t n, w;
1034
  value_t v1, v2, v;
1035
  value_bv_t *bv1, *bv2;
1036

1037
  assert(app->arity == 2);
1038

1039
  v1 = eval_term(eval, app->arg[0]);
1,335✔
1040
  v2 = eval_term(eval, app->arg[1]);
1,335✔
1041
  bv1 = vtbl_bitvector(eval->vtbl, v1);
1,335✔
1042
  bv2 = vtbl_bitvector(eval->vtbl, v2);
1,335✔
1043
  assert(bv1->nbits == bv2->nbits);
1044

1045
  n = bv1->nbits;
1,335✔
1046
  w = bv1->width;
1,335✔
1047
  assert(n>0 && w>0);
1048

1049
  aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
1,335✔
1050
  bvconst_srem2z(aux, n, bv1->data, bv2->data);
1,335✔
1051
  v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
1,335✔
1052

1053
  free_istack_array(&eval->stack, (int32_t *) aux);
1,335✔
1054

1055
  return v;
1,335✔
1056
}
1057

1058
static term_t eval_bv_smod(evaluator_t *eval, composite_term_t *app) {
×
1059
  uint32_t *aux;
1060
  uint32_t n, w;
1061
  value_t v1, v2, v;
1062
  value_bv_t *bv1, *bv2;
1063

1064
  assert(app->arity == 2);
1065

1066
  v1 = eval_term(eval, app->arg[0]);
×
1067
  v2 = eval_term(eval, app->arg[1]);
×
1068
  bv1 = vtbl_bitvector(eval->vtbl, v1);
×
1069
  bv2 = vtbl_bitvector(eval->vtbl, v2);
×
1070
  assert(bv1->nbits == bv2->nbits);
1071

1072
  n = bv1->nbits;
×
1073
  w = bv1->width;
×
1074
  assert(n>0 && w>0);
1075

1076
  aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
×
1077
  bvconst_smod2z(aux, n, bv1->data, bv2->data);
×
1078
  v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
×
1079

1080
  free_istack_array(&eval->stack, (int32_t *) aux);
×
1081

1082
  return v;
×
1083
}
1084

1085

1086
/*
1087
 * Convert bv's value (interpreted as a non-negative integer) into a shift amount.
1088
 * If bv's value is larger than nbits, then returns bv->nbits
1089
 */
1090
static uint32_t get_shift_amount(value_bv_t *bv) {
4,408✔
1091
  uint32_t n, k, i, s;
1092

1093
  s = bvconst_get32(bv->data); // low-order word = shift amount
4,408✔
1094
  n = bv->nbits;
4,408✔
1095

1096
  if (s < n) {
4,408✔
1097
    k = bv->width;
2,827✔
1098
    // if any of the higher order words is nonzero, return n
1099
    for (i=1; i<k; i++) {
2,866✔
1100
      if (bv->data[i] != 0) {
39✔
1101
        return n;
×
1102
      }
1103
    }
1104
    return s;
2,827✔
1105
  }
1106

1107
  return n;
1,581✔
1108
}
1109

1110

1111
/*
1112
 * Bitvector shift operators
1113
 */
1114
static term_t eval_bv_shl(evaluator_t *eval, composite_term_t *app) {
1,310✔
1115
  uint32_t *aux;
1116
  uint32_t n, w;
1117
  value_t v1, v2, v;
1118
  value_bv_t *bv1, *bv2;
1119

1120
  assert(app->arity == 2);
1121

1122
  v1 = eval_term(eval, app->arg[0]);
1,310✔
1123
  v2 = eval_term(eval, app->arg[1]);
1,310✔
1124
  bv1 = vtbl_bitvector(eval->vtbl, v1);
1,310✔
1125
  bv2 = vtbl_bitvector(eval->vtbl, v2);
1,310✔
1126
  assert(bv1->nbits == bv2->nbits);
1127

1128
  n = bv1->nbits;
1,310✔
1129
  w = bv1->width;
1,310✔
1130
  assert(n>0 && w>0);
1131

1132
  aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
1,310✔
1133
  bvconst_set(aux, w, bv1->data);
1,310✔
1134
  w = get_shift_amount(bv2);
1,310✔
1135
  bvconst_shift_left(aux, n, w, 0); // padding with 0
1,310✔
1136

1137
  v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
1,310✔
1138

1139
  free_istack_array(&eval->stack, (int32_t *) aux);
1,310✔
1140

1141
  return v;
1,310✔
1142
}
1143

1144
static term_t eval_bv_lshr(evaluator_t *eval, composite_term_t *app) {
1,638✔
1145
  uint32_t *aux;
1146
  uint32_t n, w;
1147
  value_t v1, v2, v;
1148
  value_bv_t *bv1, *bv2;
1149

1150
  assert(app->arity == 2);
1151

1152
  v1 = eval_term(eval, app->arg[0]);
1,638✔
1153
  v2 = eval_term(eval, app->arg[1]);
1,638✔
1154
  bv1 = vtbl_bitvector(eval->vtbl, v1);
1,638✔
1155
  bv2 = vtbl_bitvector(eval->vtbl, v2);
1,638✔
1156
  assert(bv1->nbits == bv2->nbits);
1157

1158
  n = bv1->nbits;
1,638✔
1159
  w = bv1->width;
1,638✔
1160
  assert(n>0 && w>0);
1161

1162
  aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
1,638✔
1163
  bvconst_set(aux, w, bv1->data);
1,638✔
1164
  w = get_shift_amount(bv2);
1,638✔
1165
  bvconst_shift_right(aux, n, w, 0); // padding with 0
1,638✔
1166

1167
  v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
1,638✔
1168

1169
  free_istack_array(&eval->stack, (int32_t *) aux);
1,638✔
1170

1171
  return v;
1,638✔
1172
}
1173

1174
static term_t eval_bv_ashr(evaluator_t *eval, composite_term_t *app) {
1,460✔
1175
  uint32_t *aux;
1176
  uint32_t n, w;
1177
  value_t v1, v2, v;
1178
  value_bv_t *bv1, *bv2;
1179

1180
  assert(app->arity == 2);
1181

1182
  v1 = eval_term(eval, app->arg[0]);
1,460✔
1183
  v2 = eval_term(eval, app->arg[1]);
1,460✔
1184
  bv1 = vtbl_bitvector(eval->vtbl, v1);
1,460✔
1185
  bv2 = vtbl_bitvector(eval->vtbl, v2);
1,460✔
1186
  assert(bv1->nbits == bv2->nbits);
1187

1188
  n = bv1->nbits;
1,460✔
1189
  w = bv1->width;
1,460✔
1190
  assert(n>0 && w>0);
1191

1192
  aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
1,460✔
1193
  bvconst_set(aux, w, bv1->data);
1,460✔
1194
  w = get_shift_amount(bv2);
1,460✔
1195
  bvconst_shift_right(aux, n, w, bvconst_tst_bit(aux, n-1)); // padding with sign bit
1,460✔
1196

1197
  v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
1,460✔
1198

1199
  free_istack_array(&eval->stack, (int32_t *) aux);
1,460✔
1200

1201
  return v;
1,460✔
1202
}
1203

1204

1205

1206
/*
1207
 * Bitvector atoms
1208
 */
1209
static value_t eval_bveq(evaluator_t *eval, composite_term_t *eq) {
17,690✔
1210
  value_t v1, v2;
1211

1212
  assert(eq->arity == 2);
1213

1214
  v1 = eval_term(eval, eq->arg[0]);
17,690✔
1215
  v2 = eval_term(eval, eq->arg[1]);
17,690✔
1216
  assert(object_is_bitvector(eval->vtbl, v1) &&
1217
         object_is_bitvector(eval->vtbl, v2));
1218

1219
  return vtbl_mk_bool(eval->vtbl, v1 == v2);
17,690✔
1220
}
1221

1222
static value_t eval_bvge(evaluator_t *eval, composite_term_t *ge) {
11,689✔
1223
  value_t v1, v2;
1224
  value_bv_t *bv1, *bv2;
1225
  bool test;
1226

1227
  assert(ge->arity == 2);
1228

1229
  v1 = eval_term(eval, ge->arg[0]);
11,689✔
1230
  v2 = eval_term(eval, ge->arg[1]);
11,689✔
1231
  bv1 = vtbl_bitvector(eval->vtbl, v1);
11,689✔
1232
  bv2 = vtbl_bitvector(eval->vtbl, v2);
11,689✔
1233
  assert(bv1->nbits == bv2->nbits);
1234
  test = bvconst_ge(bv1->data, bv2->data, bv1->nbits);
11,689✔
1235

1236
  return vtbl_mk_bool(eval->vtbl, test);
11,689✔
1237
}
1238

1239
static value_t eval_bvsge(evaluator_t *eval, composite_term_t *sge) {
13,030✔
1240
  value_t v1, v2;
1241
  value_bv_t *bv1, *bv2;
1242
  bool test;
1243

1244
  assert(sge->arity == 2);
1245

1246
  v1 = eval_term(eval, sge->arg[0]);
13,030✔
1247
  v2 = eval_term(eval, sge->arg[1]);
13,030✔
1248
  bv1 = vtbl_bitvector(eval->vtbl, v1);
13,030✔
1249
  bv2 = vtbl_bitvector(eval->vtbl, v2);
13,030✔
1250
  assert(bv1->nbits == bv2->nbits);
1251
  test = bvconst_sge(bv1->data, bv2->data, bv1->nbits);
13,030✔
1252

1253
  return vtbl_mk_bool(eval->vtbl, test);
13,030✔
1254
}
1255

1256

1257

1258
/*
1259
 * Power product: bitvector of nbits
1260
 */
1261
static value_t eval_bv_pprod(evaluator_t *eval, pprod_t *p, uint32_t nbits) {
1,871✔
1262
  uint32_t *a;
1263
  uint32_t i, n, w;
1264
  term_t t;
1265
  value_t o;
1266

1267
  // get bitsize
1268
  w = (nbits + 31) >> 5; // width in words
1,871✔
1269
  a = (uint32_t *) alloc_istack_array(&eval->stack, w);
1,871✔
1270
  bvconst_set_one(a, w);
1,871✔
1271

1272
  n = p->len;
1,871✔
1273
  for (i=0; i<n; i++) {
5,279✔
1274
    t = p->prod[i].var;
3,408✔
1275
    o = eval_term(eval, t);
3,408✔
1276
    // prod[i] is v ^ k so q := q * (o ^ k)
1277
    bvconst_mulpower(a, w, vtbl_bitvector(eval->vtbl, o)->data, p->prod[i].exp);
3,408✔
1278
  }
1279

1280
  // convert to object
1281
  bvconst_normalize(a, nbits);
1,871✔
1282
  o = vtbl_mk_bv_from_bv(eval->vtbl, nbits, a);
1,871✔
1283

1284
  // cleanup
1285
  free_istack_array(&eval->stack, (int32_t *) a);
1,871✔
1286

1287
  return o;
1,871✔
1288
}
1289

1290

1291
/*
1292
 * Bitvector polynomial: wide coefficients
1293
 */
1294
static value_t eval_bv_poly(evaluator_t *eval, bvpoly_t *p) {
423✔
1295
  uint32_t *sum;
1296
  uint32_t i, n, nbits, w;
1297
  term_t t;
1298
  value_t v;
1299

1300
  nbits = p->bitsize;
423✔
1301
  w = p->width;
423✔
1302

1303
  sum = (uint32_t *) alloc_istack_array(&eval->stack, w);
423✔
1304
  bvconst_clear(sum, w);
423✔
1305

1306
  n = p->nterms;
423✔
1307
  for (i=0; i<n; i++) {
1,271✔
1308
    t = p->mono[i].var;
848✔
1309
    if (t == const_idx) {
848✔
1310
      bvconst_add(sum, w, p->mono[i].coeff);
394✔
1311
    } else {
1312
      v = eval_term(eval, t);
454✔
1313
      // sum := sum + coeff * v
1314
      bvconst_addmul(sum, w, p->mono[i].coeff, vtbl_bitvector(eval->vtbl, v)->data);
454✔
1315
    }
1316
  }
1317

1318
  // convert sum to an object
1319
  bvconst_normalize(sum, nbits);
423✔
1320
  v = vtbl_mk_bv_from_bv(eval->vtbl, nbits, sum);
423✔
1321

1322
  free_istack_array(&eval->stack, (int32_t *) sum);
423✔
1323

1324
  return v;
423✔
1325
}
1326

1327

1328
/*
1329
 * Convert bivector object o to a 64bit unsigned integer
1330
 * - o must have between 1 and 64bits
1331
 */
1332
static uint64_t bvobj_to_uint64(value_bv_t *o) {
18,351✔
1333
  uint64_t c;
1334

1335
  assert(1 <= o->nbits && o->nbits <= 64);
1336
  c = o->data[0];
18,351✔
1337
  if (o->nbits > 32) {
18,351✔
1338
    c += ((uint64_t) o->data[1]) << 32;
29✔
1339
  }
1340
  return c;
18,351✔
1341
}
1342

1343

1344
/*
1345
 * Bitvector polynomial: 64bit coefficients
1346
 */
1347
static value_t eval_bv64_poly(evaluator_t *eval, bvpoly64_t *p) {
15,336✔
1348
  uint64_t sum;
1349
  uint32_t i, n, nbits;
1350
  term_t t;
1351
  value_t v;
1352

1353
  nbits = p->bitsize;
15,336✔
1354
  assert(0 < nbits && nbits <= 64);
1355

1356
  sum = 0;
15,336✔
1357

1358
  n = p->nterms;
15,336✔
1359
  for (i=0; i<n; i++) {
35,863✔
1360
    t = p->mono[i].var;
20,527✔
1361
    if (t == const_idx) {
20,527✔
1362
      sum += p->mono[i].coeff;
2,176✔
1363
    } else {
1364
      v = eval_term(eval, t);
18,351✔
1365
      sum += p->mono[i].coeff * bvobj_to_uint64(vtbl_bitvector(eval->vtbl, v));
18,351✔
1366
    }
1367
  }
1368

1369
  // convert sum to an object
1370
  sum = norm64(sum, nbits);
15,336✔
1371
  v = vtbl_mk_bv_from_bv64(eval->vtbl, nbits, sum);
15,336✔
1372

1373
  return v;
15,336✔
1374
}
1375

1376

1377

1378
/*
1379
 * Evaluate basic constructs
1380
 */
1381
static value_t eval_ite(evaluator_t *eval, composite_term_t *ite) {
215,729✔
1382
  value_t c;
1383

1384
  assert(ite->arity == 3);
1385

1386
  c = eval_term(eval, ite->arg[0]);
215,729✔
1387
  if (is_true(eval->vtbl, c)) {
215,729✔
1388
    return eval_term(eval, ite->arg[1]);
94,297✔
1389
  } else {
1390
    assert(is_false(eval->vtbl, c));
1391
    return eval_term(eval, ite->arg[2]);
121,432✔
1392
  }
1393
}
1394

1395
static value_t eval_eq(evaluator_t *eval, composite_term_t *eq) {
47,206✔
1396
  value_t v1, v2;
1397

1398
  assert(eq->arity == 2);
1399

1400
  v1 = eval_term(eval, eq->arg[0]);
47,206✔
1401
  v2 = eval_term(eval, eq->arg[1]);
47,206✔
1402
  return vtbl_eval_eq(eval->vtbl, v1, v2);
47,205✔
1403
}
1404

1405

1406
/*
1407
 * app is (fun arg[0] ... arg[n-1])
1408
 */
1409
static value_t eval_app(evaluator_t *eval, composite_term_t *app) {
251,763✔
1410
  value_t *a;
1411
  value_t *b;
1412
  composite_term_t *update;
1413
  value_t v, f;
1414
  uint32_t n;
1415
  term_t fun;
1416

1417
  // eval the arguments first
1418
  assert(app->arity >= 2);
1419
  n = app->arity - 1;
251,763✔
1420
  a = alloc_istack_array(&eval->stack, n);
251,763✔
1421
  eval_term_array(eval, app->arg+1, a, n); // a[i] = eval(arg[i])
251,763✔
1422

1423
  /*
1424
   * Try to avoid evaluating fun if it's an update.
1425
   * TODO: check whether that matters??
1426
   */
1427
  fun = app->arg[0];
251,763✔
1428
  if (term_kind(eval->terms, fun) == UPDATE_TERM) {
251,763✔
1429
    b = alloc_istack_array(&eval->stack, n);
3,733✔
1430
    do {
1431
      // fun is (update f (x_1 ... x_n) v)
1432
      update = update_term_desc(eval->terms, fun);
15,952✔
1433
      assert(update->arity == n + 2);
1434

1435
      // evaluate x_1 ... x_n
1436
      eval_term_array(eval, update->arg+1, b, n); // b[i] = eval(x_{i+1})
15,952✔
1437

1438
      // check equality
1439
      v = vtbl_eval_array_eq(eval->vtbl, a, b, n);
15,952✔
1440
      if (is_unknown(eval->vtbl, v)) {
15,952✔
1441
        // result is unknown too
1442
        free_istack_array(&eval->stack, b);
×
1443
        goto done;
×
1444

1445
      } else if (is_true(eval->vtbl, v)) {
15,952✔
1446
        // ((update f (x_1 ... x_n) v) a[0] ... a[n-1]) --> v
1447
        v = eval_term(eval, update->arg[n+1]);
1,803✔
1448
        free_istack_array(&eval->stack, b);
1,803✔
1449
        goto done;
1,803✔
1450

1451
      } else {
1452
        // ((update f  ... v) a[0] ... a[n-1]) --> (f a[0] ... a[n-1])
1453
        fun = update->arg[0];
14,149✔
1454
      }
1455

1456
    } while (term_kind(eval->terms, fun) == UPDATE_TERM);
14,149✔
1457

1458
    free_istack_array(&eval->stack, b);
1,930✔
1459
  }
1460

1461

1462
  /*
1463
   * compute (fun a[0] ... a[n-1])
1464
   */
1465
  assert(term_kind(eval->terms, fun) != UPDATE_TERM);
1466
  f = eval_term(eval, fun);
249,960✔
1467
  v = vtbl_eval_application(eval->vtbl, f, n, a);
249,960✔
1468

1469
 done:
251,763✔
1470
  free_istack_array(&eval->stack, a);
251,763✔
1471
  return v;
251,763✔
1472
}
1473

1474

1475
static value_t eval_or(evaluator_t *eval, composite_term_t *or) {
83,066✔
1476
  uint32_t i, n;
1477
  value_t v;
1478

1479
  n = or->arity;
83,066✔
1480
  for (i=0; i<n; i++) {
156,663✔
1481
    v = eval_term(eval, or->arg[i]);
128,472✔
1482
    if (is_true(eval->vtbl, v)) {
128,471✔
1483
      return v;
54,874✔
1484
    }
1485
    assert(is_false(eval->vtbl, v));
1486
  }
1487

1488
  return vtbl_mk_false(eval->vtbl);
28,191✔
1489
}
1490

1491

1492
static value_t eval_xor(evaluator_t *eval, composite_term_t *xor) {
×
1493
  uint32_t i, n;
1494
  value_t v, w;
1495

1496
  n = xor->arity;
×
1497
  v = vtbl_mk_false(eval->vtbl);
×
1498
  for (i=0; i<n; i++) {
×
1499
    w = eval_term(eval, xor->arg[i]);
×
1500
    // v := v xor w: true if v != w, false if v == w
1501
    v = vtbl_mk_bool(eval->vtbl, v != w);
×
1502
  }
1503

1504
  return v;
×
1505
}
1506

1507

1508
static value_t eval_tuple(evaluator_t *eval, composite_term_t *tuple) {
×
1509
  value_t *a;
1510
  value_t v;
1511
  uint32_t i, n;
1512

1513
  n = tuple->arity;
×
1514
  a = alloc_istack_array(&eval->stack, n);
×
1515
  for (i=0; i<n; i++) {
×
1516
    a[i] = eval_term(eval, tuple->arg[i]);
×
1517
  }
1518
  v = vtbl_mk_tuple(eval->vtbl, n, a);
×
1519
  free_istack_array(&eval->stack, a);
×
1520

1521
  return v;
×
1522
}
1523

1524

1525
static value_t eval_select(evaluator_t *eval, select_term_t *select) {
×
1526
  value_t v;
1527
  value_tuple_t *t;
1528

1529
  v = eval_term(eval, select->arg);
×
1530
  t = vtbl_tuple(eval->vtbl, v);
×
1531
  assert(0 <= select->idx && select->idx < t->nelems);
1532

1533
  return t->elem[select->idx];
×
1534
}
1535

1536

1537
static value_t eval_update(evaluator_t *eval, composite_term_t *update) {
13,216✔
1538
  value_t *a;
1539
  value_t v, f;
1540
  uint32_t i, n;
1541

1542
  assert(update->arity >= 3);
1543

1544
  n = update->arity - 2;
13,216✔
1545
  a = alloc_istack_array(&eval->stack, n);
13,216✔
1546
  f = eval_term(eval, update->arg[0]);
13,216✔
1547
  for (i=0; i<n; i++) {
26,432✔
1548
    a[i] = eval_term(eval, update->arg[i+1]);
13,216✔
1549
  }
1550
  v = eval_term(eval, update->arg[n+1]);
13,216✔
1551

1552
  v = vtbl_mk_update(eval->vtbl, f, n, a, v);
13,216✔
1553
  free_istack_array(&eval->stack, a);
13,216✔
1554

1555
  return v;
13,216✔
1556
}
1557

1558

1559
static value_t eval_distinct(evaluator_t *eval, composite_term_t *distinct) {
12✔
1560
  value_t *a;
1561
  value_t v, eq;
1562
  uint32_t i, j, n;
1563

1564
  n = distinct->arity;
12✔
1565
  a = alloc_istack_array(&eval->stack, n);
12✔
1566
  for (i=0; i<n; i++) {
30✔
1567
    v = eval_term(eval, distinct->arg[i]);
30✔
1568

1569
    for (j=0; j<i; j++) {
44✔
1570
      eq = vtbl_eval_eq(eval->vtbl, a[j], v);
26✔
1571
      if (is_unknown(eval->vtbl, eq)) {
26✔
1572
        v = eq; // i.e., unknown
2✔
1573
        goto done;
2✔
1574
      } else if (is_true(eval->vtbl, eq)) {
24✔
1575
        // a[j] == v so distinct is false
1576
        v = vtbl_mk_false(eval->vtbl);
10✔
1577
        goto done;
10✔
1578
      }
1579
    }
1580
    a[i] = v;
18✔
1581
  }
1582

1583
  v = vtbl_mk_true(eval->vtbl);
×
1584

1585
 done:
12✔
1586
  free_istack_array(&eval->stack, a);
12✔
1587
  return v;
12✔
1588
}
1589

1590

1591

1592

1593
/*
1594
 * Return a default value of type tau
1595
 */
1596
static value_t make_default_value(evaluator_t *eval, type_t tau) {
15,962✔
1597
  return vtbl_make_object(eval->vtbl, tau);
15,962✔
1598
}
1599

1600

1601

1602
/*
1603
 * Uninterpreted term t
1604
 * - t has no concrete value assigned in the model
1605
 * - the model keeps term substitution (in alias_map);
1606
 */
1607
static value_t eval_uninterpreted(evaluator_t *eval, term_t t) {
16,687✔
1608
  term_t u;
1609
  value_t v;
1610

1611
  assert(eval->model->has_alias);
1612
  // check for a substitution
1613
  u = model_find_term_substitution(eval->model, t);
16,687✔
1614
  if (u == NULL_TERM) {
16,687✔
1615
    // assign a default value based on t's type
1616
    v = make_default_value(eval, term_type(eval->terms, t));
15,962✔
1617
  } else {
1618
    // [t --> u] is a substitution in the alias table
1619
    v = eval_term(eval, u);
725✔
1620
  }
1621

1622
  return v;
16,687✔
1623
}
1624

1625
static inline const rational_t* arith_get_mod(term_table_t *table, term_t t) {
×
1626
  type_t tau = term_type(table, t);
×
1627
  return is_finite_type(table->types, tau) ? ff_type_size(table->types, tau) : NULL;
×
1628
}
1629

1630

1631
/*
1632
 * Compute the value v of term t in the model
1633
 * - add the mapping t := v  to the cache
1634
 * - raise an exception if t can't be evaluated
1635
 */
1636
static value_t eval_term(evaluator_t *eval, term_t t) {
3,401,260✔
1637
  term_table_t *terms;
1638
  bool negative;
1639
  value_t v;
1640
  term_kind_t t_kind;
1641

1642
  negative = is_neg_term(t);
3,401,260✔
1643
  t = unsigned_term(t);
3,401,260✔
1644

1645
  /*
1646
   * First check the model itself then check the cache.
1647
   * If no value is mapped to t in either of them, compute t's
1648
   * value v and add the mapping t := v to the cache.
1649
   */
1650
  v = model_find_term_value(eval->model, t);
3,401,260✔
1651
  if (v == null_value) {
3,401,260✔
1652
    v = eval_cached_value(eval, t);
2,524,425✔
1653
    if (v == null_value) {
2,524,425✔
1654
      terms = eval->terms;
1,498,691✔
1655

1656
      t_kind = term_kind(terms, t);
1,498,691✔
1657
      switch (t_kind) {
1,498,691✔
1658
      case CONSTANT_TERM:
11,365✔
1659
        if (t == true_term) {
11,365✔
1660
          v = vtbl_mk_true(eval->vtbl);
11,365✔
1661
        } else if (t == false_term) {
×
1662
          v = vtbl_mk_false(eval->vtbl);
×
1663
        } else {
1664
          v = vtbl_mk_const(eval->vtbl, term_type(terms, t), constant_term_index(terms, t),
×
1665
                            term_name(terms, t));
1666
        }
1667
        break;
11,365✔
1668

1669
      case ARITH_CONSTANT:
28,748✔
1670
        v = vtbl_mk_rational(eval->vtbl, rational_term_desc(terms, t));
28,748✔
1671
        break;
28,748✔
1672

1673
      case ARITH_FF_CONSTANT:
×
1674
        assert(arith_get_mod(terms, t) && q_is_pos(arith_get_mod(terms, t)));
1675
        assert(q_lt(finitefield_term_desc(terms, t), arith_get_mod(terms, t)));
1676
        v = vtbl_mk_finitefield(eval->vtbl, finitefield_term_desc(terms, t), arith_get_mod(terms, t));
×
1677
        break;
×
1678

1679
      case BV64_CONSTANT:
22,099✔
1680
        v = eval_bv64_constant(eval, bvconst64_term_desc(terms, t));
22,099✔
1681
        break;
22,099✔
1682

1683
      case BV_CONSTANT:
67✔
1684
        v = eval_bv_constant(eval, bvconst_term_desc(terms, t));
67✔
1685
        break;
67✔
1686

1687
      case VARIABLE:
×
1688
        // free variable
1689
        longjmp(eval->env, MDL_EVAL_FREEVAR_IN_TERM);
×
1690
        break;
1691

1692
      case UNINTERPRETED_TERM:
16,687✔
1693
        // t has no value mapped in the model
1694
        if (eval->model->has_alias) {
16,687✔
1695
          v = eval_uninterpreted(eval, t);
16,687✔
1696
        } else {
1697
          longjmp(eval->env, MDL_EVAL_UNKNOWN_TERM);
×
1698
        }
1699
        break;
16,687✔
1700

1701
      case ARITH_EQ_ATOM:
31,290✔
1702
        v = eval_arith_eq(eval, arith_eq_arg(terms, t));
31,290✔
1703
        break;
31,290✔
1704

1705
      case ARITH_GE_ATOM:
91,780✔
1706
        v = eval_arith_ge(eval, arith_ge_arg(terms, t));
91,780✔
1707
        break;
91,780✔
1708

1709
      case ARITH_IS_INT_ATOM:
×
1710
        v = eval_arith_is_int(eval, arith_is_int_arg(terms, t));
×
1711
        break;
×
1712

1713
      case ARITH_FLOOR:
×
1714
        v = eval_arith_floor(eval, arith_floor_arg(terms, t));
×
1715
        break;
×
1716

1717
      case ARITH_CEIL:
×
1718
        v = eval_arith_ceil(eval, arith_ceil_arg(terms, t));
×
1719
        break;
×
1720

1721
      case ARITH_ABS:
×
1722
        v = eval_arith_abs(eval, arith_abs_arg(terms, t));
×
1723
        break;
×
1724

1725
      case ARITH_ROOT_ATOM:
×
1726
        // not supported (but don't crash if we see them)
1727
        v = vtbl_mk_unknown(eval->vtbl);
×
1728
        break;
×
1729

1730
      case ARITH_FF_EQ_ATOM:
×
1731
        v = eval_arith_ff_eq(eval, arith_ff_eq_arg(terms, t));
×
1732
        break;
×
1733

1734
      case ITE_TERM:
215,729✔
1735
      case ITE_SPECIAL:
1736
        v = eval_ite(eval, ite_term_desc(terms, t));
215,729✔
1737
        break;
215,729✔
1738

1739
      case APP_TERM:
251,763✔
1740
        v = eval_app(eval, app_term_desc(terms, t));
251,763✔
1741
        break;
251,763✔
1742

1743
      case UPDATE_TERM:
13,216✔
1744
        v = eval_update(eval, update_term_desc(terms, t));
13,216✔
1745
        break;
13,216✔
1746

1747
      case TUPLE_TERM:
×
1748
        v = eval_tuple(eval, tuple_term_desc(terms, t));
×
1749
        break;
×
1750

1751
      case EQ_TERM:
47,206✔
1752
        v = eval_eq(eval, eq_term_desc(terms, t));
47,206✔
1753
        break;
47,205✔
1754

1755
      case DISTINCT_TERM:
12✔
1756
        v = eval_distinct(eval, distinct_term_desc(terms, t));
12✔
1757
        break;
12✔
1758

1759
      case FORALL_TERM:
×
1760
        // don't try to evaluate forall for now
1761
        // but we could deal with quantification over finite types
1762
        longjmp(eval->env, MDL_EVAL_QUANTIFIER);
×
1763
        break;
1764

1765
      case LAMBDA_TERM:
1✔
1766
        // don't evaluate
1767
        longjmp(eval->env, MDL_EVAL_LAMBDA);
1✔
1768
        break;
1769

1770
      case OR_TERM:
83,066✔
1771
        v = eval_or(eval, or_term_desc(terms, t));
83,066✔
1772
        break;
83,065✔
1773

1774
      case XOR_TERM:
×
1775
        v = eval_xor(eval, xor_term_desc(terms, t));
×
1776
        break;
×
1777

1778
      case ARITH_BINEQ_ATOM:
18,360✔
1779
        v = eval_arith_bineq(eval, arith_bineq_atom_desc(terms, t));
18,360✔
1780
        break;
18,360✔
1781

1782
      case ARITH_RDIV:
2✔
1783
        v = eval_arith_rdiv(eval, arith_rdiv_term_desc(terms, t));
2✔
1784
        break;
2✔
1785

1786
      case ARITH_IDIV:
×
1787
        v = eval_arith_idiv(eval, arith_idiv_term_desc(terms, t));
×
1788
        break;
×
1789

1790
      case ARITH_MOD:
×
1791
        v = eval_arith_mod(eval, arith_mod_term_desc(terms, t));
×
1792
        break;
×
1793

1794
      case ARITH_DIVIDES_ATOM:
×
1795
        v = eval_arith_divides(eval, arith_divides_atom_desc(terms, t));
×
1796
        break;
×
1797

1798
      case ARITH_FF_BINEQ_ATOM:
×
1799
        v = eval_finitefield_bineq(eval, arith_ff_bineq_atom_desc(terms, t));
×
1800
        break;
×
1801

1802
      case BV_ARRAY:
65,033✔
1803
        v = eval_bv_array(eval, bvarray_term_desc(terms, t));
65,033✔
1804
        break;
65,033✔
1805

1806
      case BV_DIV:
1,753✔
1807
        v = eval_bv_div(eval, bvdiv_term_desc(terms, t));
1,753✔
1808
        break;
1,753✔
1809

1810
      case BV_REM:
1,448✔
1811
        v = eval_bv_rem(eval, bvrem_term_desc(terms, t));
1,448✔
1812
        break;
1,448✔
1813

1814
      case BV_SDIV:
1,437✔
1815
        v = eval_bv_sdiv(eval, bvsdiv_term_desc(terms, t));
1,437✔
1816
        break;
1,437✔
1817

1818
      case BV_SREM:
1,335✔
1819
        v = eval_bv_srem(eval, bvsrem_term_desc(terms, t));
1,335✔
1820
        break;
1,335✔
1821

1822
      case BV_SMOD:
×
1823
        v = eval_bv_smod(eval, bvsmod_term_desc(terms, t));
×
1824
        break;
×
1825

1826
      case BV_SHL:
1,310✔
1827
        v = eval_bv_shl(eval, bvshl_term_desc(terms, t));
1,310✔
1828
        break;
1,310✔
1829

1830
      case BV_LSHR:
1,638✔
1831
        v = eval_bv_lshr(eval, bvlshr_term_desc(terms, t));
1,638✔
1832
        break;
1,638✔
1833

1834
      case BV_ASHR:
1,460✔
1835
        v = eval_bv_ashr(eval, bvashr_term_desc(terms, t));
1,460✔
1836
        break;
1,460✔
1837

1838
      case BV_EQ_ATOM:
17,690✔
1839
        v = eval_bveq(eval, bveq_atom_desc(terms, t));
17,690✔
1840
        break;
17,690✔
1841

1842
      case BV_GE_ATOM:
11,689✔
1843
        v = eval_bvge(eval, bvge_atom_desc(terms, t));
11,689✔
1844
        break;
11,689✔
1845

1846
      case BV_SGE_ATOM:
13,030✔
1847
        v = eval_bvsge(eval, bvsge_atom_desc(terms, t));
13,030✔
1848
        break;
13,030✔
1849

1850
      case SELECT_TERM:
×
1851
        v = eval_select(eval, select_term_desc(terms, t));
×
1852
        break;
×
1853

1854
      case BIT_TERM:
306,850✔
1855
        v = eval_bit(eval, bit_term_desc(terms, t));
306,850✔
1856
        break;
306,850✔
1857

1858
      case POWER_PRODUCT:
1,871✔
1859
        if (is_bitvector_term(terms, t)) {
1,871✔
1860
          v = eval_bv_pprod(eval, pprod_term_desc(terms, t), term_bitsize(terms, t));
1,871✔
1861
        } else if (is_arithmetic_term(terms, t)) {
×
1862
          v = eval_arith_pprod(eval, pprod_term_desc(terms, t));
×
1863
        } else if (is_finitefield_term(terms, t)) {
×
1864
          v = eval_arith_ff_pprod(eval, pprod_term_desc(terms, t), arith_get_mod(terms, t));
×
1865
        } else {
1866
          assert(false);
1867
          v = vtbl_mk_unknown(eval->vtbl);
×
1868
        }
1869
        break;
1,871✔
1870

1871
      case ARITH_POLY:
224,997✔
1872
        v = eval_arith_poly(eval, poly_term_desc(terms, t));
224,997✔
1873
        break;
224,997✔
1874

1875
      case ARITH_FF_POLY:
×
1876
        v = eval_arith_ff_poly(eval, finitefield_poly_term_desc(terms, t), arith_get_mod(terms, t));
×
1877
        break;
×
1878

1879
      case BV64_POLY:
15,336✔
1880
        v = eval_bv64_poly(eval, bvpoly64_term_desc(terms, t));
15,336✔
1881
        break;
15,336✔
1882

1883
      case BV_POLY:
423✔
1884
        v = eval_bv_poly(eval, bvpoly_term_desc(terms, t));
423✔
1885
        break;
423✔
1886

1887
      default:
×
1888
        assert(false);
1889
        longjmp(eval->env, MDL_EVAL_INTERNAL_ERROR);
×
1890
        break;
1891
      }
1892

1893
      // if the result v is unknown we quit now
1894
      assert(v >= 0); // Coverity thinks v can be negative.
1895
      if (object_is_unknown(eval->vtbl, v)) {
1,498,688✔
1896
        longjmp(eval->env, MDL_EVAL_FAILED);
2✔
1897
      }
1898

1899
      eval_cache_map(eval, t, v);
1,498,686✔
1900
    }
1901
  }
1902

1903
  if (negative) {
3,401,255✔
1904
    v = vtbl_mk_not(eval->vtbl, v);
375,336✔
1905
  }
1906

1907
  return v;
3,401,255✔
1908
}
1909

1910

1911
/*
1912
 * Compute the value of t in the model
1913
 * - t must be a valid term
1914
 * - return a negative code if there's an error
1915
 * - otherwise, return the id of a concrete object of eval->model.vtbl
1916
 *
1917
 * Evaluation may create new objects. All these new objects are
1918
 * permananet in eval->vtbl.
1919
 */
1920
value_t eval_in_model(evaluator_t *eval, term_t t) {
167,474✔
1921
  value_t v;
1922

1923
  v = setjmp(eval->env);
167,474✔
1924
  if (v == 0) {
167,477✔
1925
    v = eval_term(eval, t);
167,474✔
1926
  } else {
1927
    assert(v < 0); // error code after longjmp
1928
    reset_istack(&eval->stack);
3✔
1929
  }
1930

1931
  return v;
167,474✔
1932
}
1933

1934

1935
/*
1936
 * Check whether t is true in the model
1937
 * - t must be a valid term
1938
 * - return true if t evaluates to true
1939
 * - return false if t can't be evaluated or
1940
 *   if t's value is not boolean or not true.
1941
 */
1942
bool eval_to_true_in_model(evaluator_t *eval, term_t t) {
1,832✔
1943
  value_t v;
1944

1945
  v = eval_in_model(eval, t);
1,832✔
1946
  return good_object(eval->vtbl, v) && is_true(eval->vtbl, v);
1,832✔
1947
}
1948

1949

1950
/*
1951
 * Check whether t is false in the model
1952
 * - t must be a valid term
1953
 * - return true if t evaluates to true
1954
 * - return false if t can't be evaluated or
1955
 *   if t's value is not boolean or not true.
1956
 */
1957
bool eval_to_false_in_model(evaluator_t *eval, term_t t) {
×
1958
  value_t v;
1959

1960
  v = eval_in_model(eval, t);
×
1961
  return good_object(eval->vtbl, v) && is_false(eval->vtbl, v);
×
1962
}
1963

1964

1965
/*
1966
 * Check whether t is zero in the model
1967
 * - t must be a valid term
1968
 * - if t is an arithmetic term, this checks whether value(t) == 0
1969
 * - if t is a bit-vector term, this checks whether value(t) == 0b0000...
1970
 * - return false if t can't be evaluated, or if t is not an arithemtic
1971
 *   term nor a bitvector term, or if t's value is not zero.
1972
 */
1973
bool eval_to_zero_in_model(evaluator_t *eval, term_t t) {
×
1974
  value_t v;
1975

1976
  v = eval_in_model(eval, t);
×
1977
  return good_object(eval->vtbl, v) &&
×
1978
    (is_zero(eval->vtbl, v) || is_bvzero(eval->vtbl, v));
×
1979
}
1980

1981
/*
1982
 * Check whether t evaluates to +/-1 in the model
1983
 * - t must be a valid  term
1984
 * - return false if t can't be evaluated or its value is not a rational
1985
 * - return true if t's value is either +1 or -1
1986
 */
1987
bool eval_to_unit_in_model(evaluator_t *eval, term_t t) {
×
1988
  value_t v;
1989

1990
  v = eval_in_model(eval, t);
×
1991
  return good_object(eval->vtbl, v) && is_unit(eval->vtbl, v);
×
1992
}
1993

1994

1995

1996

1997
/*
1998
 * Compute the values of terms a[0 ... n-1]
1999
 * - don't return anything
2000
 * - the value of a[i] can be queried by using eval_in_model(eval, a[i]) later
2001
 *   (this reads the value from eval->cache so that's cheap).
2002
 */
2003
void eval_terms_in_model(evaluator_t *eval, const term_t *a, uint32_t n) {
×
2004
  uint32_t i;
2005

2006
  for (i=0; i<n; i++) {
×
2007
    (void) eval_in_model(eval, a[i]);
×
2008
  }
2009
}
×
2010

2011

2012
/*
2013
 * Check whether term t is useful:
2014
 * - return true if t is unintepreted and has no existing value in eval->model
2015
 *   and is not mapped to another term u in the alias_map
2016
 */
2017
static bool term_is_useful(model_t *model, term_t t) {
7,511✔
2018
  value_t v;
2019

2020
  if (term_kind(model->terms, t) == UNINTERPRETED_TERM) {
7,511✔
2021
    v = model_find_term_value(model, t);
317✔
2022
    if (v == null_value && model->has_alias) {
317✔
2023
      return model_find_term_substitution(model, t) == NULL_TERM;
317✔
2024
    }
2025
  }
2026
  return false;
7,194✔
2027
}
2028

2029
/*
2030
 * Add a mapping t->v in eval->model for every pair (t, v) found in eval->cache
2031
 * and such that t is useful.
2032
 */
2033
void eval_record_useful_terms(evaluator_t *eval) {
67✔
2034
  model_t *model;
2035
  int_hmap_t *cache;
2036
  int_hmap_pair_t *r;
2037

2038
  model = eval->model;
67✔
2039
  cache = &eval->cache;
67✔
2040
  r = int_hmap_first_record(cache);
67✔
2041
  while (r != NULL) {
7,578✔
2042
    // r->key is the term, r->val is the value
2043
    if (term_is_useful(model, r->key) && !is_unknown(eval->vtbl, r->val)) {
7,511✔
2044
      model_map_term(model, r->key, r->val);
317✔
2045
    }
2046
    r = int_hmap_next_record(cache, r);
7,511✔
2047
  }
2048

2049
}
67✔
2050

2051
/*
2052
 * Cached-term collector:
2053
 * - call f(aux, t) for every t that's stored in eval->cache
2054
 *   if f(aux, t) returns true, add t to v
2055
 * - f must not have side effects
2056
 */
2057
void evaluator_collect_cached_terms(evaluator_t *eval, void *aux, model_filter_t f, ivector_t *v) {
×
2058
  int_hmap_t *cache;
2059
  int_hmap_pair_t *r;
2060

2061
  cache = &eval->cache;
×
2062
  r = int_hmap_first_record(cache);
×
2063
  while (r != NULL) {
×
2064
    if (f(aux, r->key)) {
×
2065
      ivector_push(v, r->key);
×
2066
    }
2067
    r = int_hmap_next_record(cache, r);
×
2068
  }
2069
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc