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

SRI-CSL / yices2 / 9226448713

24 May 2024 03:34PM UTC coverage: 65.988% (+0.3%) from 65.728%
9226448713

Pull #513

github

web-flow
Merge da66d3d5d into f06761440
Pull Request #513: Finite Field support

2396 of 3347 new or added lines in 66 files covered. (71.59%)

18 existing lines in 12 files now uncovered.

81769 of 123915 relevant lines covered (65.99%)

1493770.28 hits per line

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

82.55
/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) {
226,060✔
40
  q_clear(q);
226,060✔
41
}
226,060✔
42

43

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

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

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

61

62
/*
63
 * Delete caches and stack
64
 */
65
void delete_evaluator(evaluator_t *eval) {
59,521✔
66
  eval->model = NULL;
59,521✔
67
  eval->terms = NULL;
59,521✔
68
  eval->vtbl = NULL;
59,521✔
69
  delete_int_hmap(&eval->cache);
59,521✔
70
  delete_istack(&eval->stack);
59,521✔
71
}
59,521✔
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,709,319✔
91
  int_hmap_pair_t *r;
92

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

95
  r = int_hmap_find(&eval->cache, t);
2,709,319✔
96
  if (r == NULL) {
2,709,319✔
97
    return null_value;
1,591,324✔
98
  } else {
99
    return r->val;
1,117,995✔
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,591,319✔
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,591,319✔
114
  assert(r->val < 0);
115
  r->val = v;
1,591,319✔
116
}
1,591,319✔
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) {
12✔
134
  if (object_is_algebraic(eval->vtbl, v)) {
12✔
135
    longjmp(eval->env, MDL_EVAL_FAILED);
×
136
  }
137
  return vtbl_rational(eval->vtbl, v);
12✔
138
}
139

140
/*
141
 * Check whether v is zero
142
 */
143
static bool eval_is_zero(evaluator_t *eval, value_t v) {
17✔
144
  if (object_is_rational(eval->vtbl, v)) {
17✔
145
    return q_is_zero(vtbl_rational(eval->vtbl, v));
15✔
146
  } else {
147
#ifdef HAVE_MCSAT
148
    return lp_algebraic_number_sgn(vtbl_algebraic_number(eval->vtbl, v)) == 0;
2✔
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) {
7✔
161
  rational_t *q;
162

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

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

174
  a = vtbl_algebraic_number(eval->vtbl, v);
2✔
175
  if (lp_algebraic_number_sgn(a) == 0) {
2✔
176
    longjmp(eval->env, MDL_EVAL_FAILED);
×
177
  }
178
  return a;
2✔
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) {
268,046✔
188
  uint32_t i;
189

190
  for (i=0; i<n; i++) {
761,877✔
191
    a[i] = eval_term(eval, t[i]);
493,831✔
192
  }
193
}
268,046✔
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,459✔
200
  return vtbl_mk_bv_from_bv64(eval->vtbl, c->bitsize, c->value);
22,459✔
201
}
202

203

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

211

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

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

220
  if (object_is_rational(eval->vtbl, v)) {
31,520✔
221
    return vtbl_mk_bool(eval->vtbl, q_is_zero(vtbl_rational(eval->vtbl, v)));
31,520✔
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) {
92,344✔
237
  value_t v;
238

239
  v = eval_term(eval, t);
92,344✔
240

241
  if (object_is_rational(eval->vtbl, v)) {
92,344✔
242
    return vtbl_mk_bool(eval->vtbl, q_is_nonneg(vtbl_rational(eval->vtbl, v)));
92,342✔
243
  } else {
244
#ifdef HAVE_MCSAT
245
    return vtbl_mk_bool(eval->vtbl, lp_algebraic_number_sgn(vtbl_algebraic_number(eval->vtbl, v)) >= 0);
2✔
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) {
1✔
257
  value_t v;
258

259
  v = eval_term(eval, t);
1✔
260

261
  if (object_is_rational(eval->vtbl, v)) {
1✔
262
    return vtbl_mk_bool(eval->vtbl, q_is_integer(vtbl_rational(eval->vtbl, v)));
1✔
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) {
2✔
278
  rational_t q;
279
  value_t v;
280

281
  v = eval_term(eval, t);
2✔
282

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

289
    v = vtbl_mk_rational(eval->vtbl, &q);
2✔
290
  
291
    clear_rational(&q);
2✔
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;
2✔
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) {
1✔
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);
1✔
367
  
368
  if (object_is_rational(eval->vtbl, v)) {
1✔
369
    q_init(&q);
1✔
370
    q_set_abs(&q, vtbl_rational(eval->vtbl, v)); // q := value of t
1✔
371
    q_normalize(&q);
1✔
372

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

375
    clear_rational(&q);
1✔
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;
1✔
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) {
1✔
400
  if (is_ratgmp(q)) {
1✔
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));
1✔
404
  }
405
}
1✔
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,454✔
412
  bool result;
413
  value_t v1, v2;
414
  assert(eq->arity == 2);
415

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

419
  if (object_is_rational(eval->vtbl, v1) && object_is_rational(eval->vtbl, v2)) {
18,454✔
420
    result = v1 == v2; // because of hash consing
18,453✔
421
  } else {
422
#ifdef HAVE_MCSAT
423
    lp_rational_t q;
424
    bool v1_algebraic = object_is_algebraic(eval->vtbl, v1);
1✔
425
    bool v2_algebraic = object_is_algebraic(eval->vtbl, v2);
1✔
426
    lp_algebraic_number_t* a1 = v1_algebraic ? vtbl_algebraic_number(eval->vtbl, v1) : NULL;
1✔
427
    lp_algebraic_number_t* a2 = v2_algebraic ? vtbl_algebraic_number(eval->vtbl, v2) : NULL;
1✔
428
    if (v1_algebraic && v2_algebraic) {
1✔
429
      result = lp_algebraic_number_cmp(a1, a2) == 0;
×
430
    } else if (v1_algebraic) {
1✔
431
      lp_rational_construct_from_rational(&q, vtbl_rational(eval->vtbl, v2));
1✔
432
      result = lp_algebraic_number_cmp_rational(a1, &q) == 0;
1✔
433
      lp_rational_destruct(&q);
1✔
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,454✔
447
}
448

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

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

454
  v1 = eval_term(eval, eq->arg[0]);
4✔
455
  v2 = eval_term(eval, eq->arg[1]);
4✔
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);
4✔
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) {
2✔
468
  bool v1_algebraic = object_is_algebraic(eval->vtbl, v1);
2✔
469
  bool v2_algebraic = object_is_algebraic(eval->vtbl, v2);
2✔
470
  lp_algebraic_number_t* a1 = v1_algebraic ? vtbl_algebraic_number(eval->vtbl, v1) : NULL;
2✔
471
  lp_algebraic_number_t* a2 = v2_algebraic ? eval_get_nz_algebraic(eval, v2) : NULL;
2✔
472
  if (v1_algebraic && v2_algebraic) {
2✔
473
    lp_algebraic_number_div(result, a1, a2);
2✔
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
}
2✔
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) {
6✔
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]);
6✔
503
  v2 = eval_term(eval, d->arg[1]);
6✔
504

505
  if (eval_is_zero(eval, v2)) {
6✔
506
    o = vtbl_eval_rdiv_by_zero(eval->vtbl, v1);
4✔
507
  } else if (object_is_rational(eval->vtbl, v1) && object_is_rational(eval->vtbl, v2)) {
2✔
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);
2✔
520
    eval_arith_rdiv_algebraic(eval, v1, v2, &result);
2✔
521
    o = vtbl_mk_algebraic(eval->vtbl, &result);
2✔
522
    lp_algebraic_number_destruct(&result);
2✔
523
#else
524
    assert(false);
525
    o = MDL_EVAL_INTERNAL_ERROR;
526
#endif
527
  }
528

529
  return o;
6✔
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) {
6✔
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]);
6✔
543
  v2 = eval_term(eval, d->arg[1]);
6✔
544

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

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

554
    clear_rational(&q);
2✔
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;
6✔
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) {
5✔
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]);
5✔
598
  v2 = eval_term(eval, d->arg[1]);
5✔
599

600
  if (eval_is_zero(eval, v2)) {
5✔
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)) {
5✔
603
    q_init(&q);
5✔
604
    q_smt2_mod(&q, eval_get_rational(eval, v1), eval_get_nz_rational(eval, v2)); 
5✔
605
    q_normalize(&q);
5✔
606

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

609
    clear_rational(&q);
5✔
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;
5✔
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) {
5✔
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);
5✔
684
  lp_algebraic_number_construct_one(&prod);
5✔
685

686
  n = p->len;
5✔
687
  for (i=0; i<n && lp_algebraic_number_sgn(&prod) != 0; i++) {
20✔
688
    t = p->prod[i].var;
15✔
689
    o = eval_term(eval, t);
15✔
690
    // prod[i] is v ^ k so q := q * (o ^ k)
691
    if (object_is_rational(eval->vtbl, o)) {
15✔
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));
15✔
696
    }
697
    lp_algebraic_number_pow(&tmp,  &tmp, p->prod[i].exp);
15✔
698
    lp_algebraic_number_mul(&prod, &prod, &tmp);
15✔
699
    lp_algebraic_number_destruct(&tmp);
15✔
700
  }
701

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

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

707
  return o;
5✔
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) {
21✔
715
  value_t v;
716

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

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

724
/*
725
 * Power product: arithmetic
726
 */
727
static value_t eval_arith_pprod(evaluator_t *eval, pprod_t *p, const rational_t *mod) {
385✔
728
  rational_t prod;
729
  uint32_t i, n;
730
  term_t t;
731
  value_t o;
732

733
  q_init(&prod);
385✔
734
  q_set_one(&prod);
385✔
735

736
  n = p->len;
385✔
737
  for (i=0; i<n; i++) {
1,052✔
738
    t = p->prod[i].var;
672✔
739
    o = eval_term(eval, t);
672✔
740
    // prod[i] is v ^ k so q := q * (o ^ k)
741
    if (object_is_rational(eval->vtbl, o)) {
672✔
742
      q_mulexp(&prod, vtbl_rational(eval->vtbl, o), p->prod[i].exp);
581✔
743
    } else if (object_is_finitefield(eval->vtbl, o)) {
91✔
744
      value_ff_t *v_ff = vtbl_finitefield(eval->vtbl, o);
86✔
745
      assert(mod && q_eq(&v_ff->mod, mod));
746
      q_mulexp(&prod, &v_ff->value, p->prod[i].exp);
86✔
747
    } else {
748
#ifdef HAVE_MCSAT
749
      // We need algebraic number computation
750
      o = eval_arith_pprod_algebraic(eval, p);
5✔
751
      clear_rational(&prod);
5✔
752
      return o;
5✔
753
#else
754
      assert(false);
755
      return MDL_EVAL_INTERNAL_ERROR;
756
#endif
757
    }
758
  }
759

760
  if (mod) {
380✔
761
    assert(q_is_integer(&prod));
762
    q_integer_rem(&prod, mod);
41✔
763
    o = vtbl_mk_finitefield(eval->vtbl, &prod, mod);
41✔
764
  } else {
765
    o = vtbl_mk_rational(eval->vtbl, &prod);
339✔
766
  }
767

768
  clear_rational(&prod);
380✔
769

770
  return o;
380✔
771
}
772

773
#ifdef HAVE_MCSAT
774
static value_t eval_arith_poly_algebraic(evaluator_t *eval, polynomial_t *p) {
7✔
775
  lp_algebraic_number_t sum, tmp_c, tmp_t;
776
  uint32_t i, n;
777
  term_t t;
778
  value_t v;
779
  mpq_t q;
780

781
  mpq_init(q);
7✔
782
  lp_algebraic_number_construct_zero(&sum); // sum = 0
7✔
783

784
  n = p->nterms;
7✔
785
  for (i=0; i<n; i++) {
24✔
786
    t = p->mono[i].var;
17✔
787
    q_get_mpq(&p->mono[i].coeff, q);
17✔
788
    lp_algebraic_number_construct_from_rational(&tmp_c, q);
17✔
789
    if (t == const_idx) {
17✔
790
      lp_algebraic_number_add(&sum, &sum, &tmp_c);
4✔
791
    } else {
792
      v = eval_term(eval, t);
13✔
793
      if (object_is_rational(eval->vtbl, v)) {
13✔
794
        q_get_mpq(vtbl_rational(eval->vtbl, v), q);
×
795
        lp_algebraic_number_construct_from_rational(&tmp_t, q);
×
796
      } else {
797
        lp_algebraic_number_construct_copy(&tmp_t, vtbl_algebraic_number(eval->vtbl, v));
13✔
798
      }
799
      lp_algebraic_number_mul(&tmp_t, &tmp_c, &tmp_t);
13✔
800
      lp_algebraic_number_add(&sum, &sum, &tmp_t);
13✔
801
      lp_algebraic_number_destruct(&tmp_t);
13✔
802
    }
803
    lp_algebraic_number_destruct(&tmp_c);
17✔
804
  }
805

806
  // convert sum to an object
807
  v = vtbl_mk_algebraic(eval->vtbl, &sum);
7✔
808

809
  mpq_clear(q);
7✔
810
  lp_algebraic_number_destruct(&sum);
7✔
811

812
  return v;
7✔
813
}
814
#endif
815

816
/*
817
 * Arithmetic polynomial
818
 */
819
static value_t eval_arith_poly(evaluator_t *eval, polynomial_t *p) {
225,646✔
820
  rational_t sum;
821
  uint32_t i, n;
822
  term_t t;
823
  value_t v;
824

825
  q_init(&sum); // sum = 0
225,646✔
826

827
  n = p->nterms;
225,646✔
828
  for (i=0; i<n; i++) {
694,474✔
829
    t = p->mono[i].var;
468,835✔
830
    if (t == const_idx) {
468,835✔
831
      q_add(&sum, &p->mono[i].coeff);
15,617✔
832
    } else {
833
      v = eval_term(eval, t);
453,218✔
834
      if (object_is_rational(eval->vtbl, v)) {
453,218✔
835
        q_addmul(&sum, &p->mono[i].coeff, vtbl_rational(eval->vtbl, v)); // sum := sum + coeff * aux
453,211✔
836
      } else {
837
#ifdef HAVE_MCSAT
838
        v = eval_arith_poly_algebraic(eval, p);
7✔
839
        clear_rational(&sum);
7✔
840
        return v;
7✔
841
#else
842
        assert(false);
843
        return MDL_EVAL_INTERNAL_ERROR;
844
#endif
845
      }
846
    }
847
  }
848

849
  // convert sum to an object
850
  v = vtbl_mk_rational(eval->vtbl, &sum);
225,639✔
851

852
  clear_rational(&sum);
225,639✔
853

854
  return v;
225,639✔
855
}
856

857
static value_t eval_arith_ff_poly(evaluator_t *eval, polynomial_t *p, const rational_t *mod) {
19✔
858
  rational_t sum;
859
  uint32_t i, n;
860
  term_t t;
861
  value_t v;
862
  value_ff_t *v_ff;
863

864
  q_init(&sum); // sum = 0
19✔
865

866
  n = p->nterms;
19✔
867
  for (i=0; i<n; i++) {
87✔
868
    t = p->mono[i].var;
68✔
869
    if (t == const_idx) {
68✔
870
      q_add(&sum, &p->mono[i].coeff);
7✔
871
    } else {
872
      v = eval_term(eval, t);
61✔
873
      assert(object_is_finitefield(eval->vtbl, v));
874
      v_ff = vtbl_finitefield(eval->vtbl, v);
61✔
875
      assert(q_eq(&v_ff->mod, mod));
876
      q_addmul(&sum, &p->mono[i].coeff, &v_ff->value); // sum := sum + coeff * aux
61✔
877
    }
878
  }
879

880
  // convert sum to an object
881
  assert(q_is_integer(&sum));
882
  assert(q_is_integer(mod));
883
  q_integer_rem(&sum, mod);
19✔
884
  v = vtbl_mk_finitefield(eval->vtbl, &sum, mod);
19✔
885

886
  clear_rational(&sum);
19✔
887

888
  return v;
19✔
889
}
890

891

892

893
/*
894
 * Bitvector terms
895
 */
896
static value_t eval_bv_array(evaluator_t *eval, composite_term_t *array) {
66,128✔
897
  uint32_t i, n;
898
  int32_t *a;
899
  value_t v;
900

901
  n = array->arity;
66,128✔
902
  a = alloc_istack_array(&eval->stack, n);
66,128✔
903
  for (i=0; i<n; i++) {
892,216✔
904
    v = eval_term(eval, array->arg[i]);
826,088✔
905
    a[i] = boolobj_value(eval->vtbl, v);
826,088✔
906
  }
907

908
  v = vtbl_mk_bv(eval->vtbl, n, a);
66,128✔
909

910
  free_istack_array(&eval->stack, a);
66,128✔
911

912
  return v;
66,128✔
913
}
914

915
static value_t eval_bit(evaluator_t *eval, select_term_t *select) {
373,762✔
916
  value_t v;
917
  value_bv_t *bv;
918
  bool b;
919

920
  v = eval_term(eval, select->arg);
373,762✔
921
  bv = vtbl_bitvector(eval->vtbl, v);
373,762✔
922
  assert(select->idx < bv->nbits);
923

924
  b = bvconst_tst_bit(bv->data, select->idx);
373,762✔
925

926
  return vtbl_mk_bool(eval->vtbl, b);
373,762✔
927
}
928

929
static term_t eval_bv_div(evaluator_t *eval, composite_term_t *app) {
1,762✔
930
  uint32_t *aux;
931
  uint32_t n, w;
932
  value_t v1, v2, v;
933
  value_bv_t *bv1, *bv2;
934

935
  assert(app->arity == 2);
936

937
  v1 = eval_term(eval, app->arg[0]);
1,762✔
938
  v2 = eval_term(eval, app->arg[1]);
1,762✔
939
  bv1 = vtbl_bitvector(eval->vtbl, v1);
1,762✔
940
  bv2 = vtbl_bitvector(eval->vtbl, v2);
1,762✔
941
  assert(bv1->nbits == bv2->nbits);
942

943
  n = bv1->nbits;
1,762✔
944
  w = bv1->width;
1,762✔
945
  assert(n>0 && w>0);
946

947
  aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
1,762✔
948
  bvconst_udiv2z(aux, n, bv1->data, bv2->data);
1,762✔
949
  v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
1,762✔
950

951
  free_istack_array(&eval->stack, (int32_t *) aux);
1,762✔
952

953
  return v;
1,762✔
954
}
955

956
static term_t eval_bv_rem(evaluator_t *eval, composite_term_t *app) {
1,457✔
957
  uint32_t *aux;
958
  uint32_t n, w;
959
  value_t v1, v2, v;
960
  value_bv_t *bv1, *bv2;
961

962
  assert(app->arity == 2);
963

964
  v1 = eval_term(eval, app->arg[0]);
1,457✔
965
  v2 = eval_term(eval, app->arg[1]);
1,457✔
966
  bv1 = vtbl_bitvector(eval->vtbl, v1);
1,457✔
967
  bv2 = vtbl_bitvector(eval->vtbl, v2);
1,457✔
968
  assert(bv1->nbits == bv2->nbits);
969

970
  n = bv1->nbits;
1,457✔
971
  w = bv1->width;
1,457✔
972
  assert(n>0 && w>0);
973

974
  aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
1,457✔
975
  bvconst_urem2z(aux, n, bv1->data, bv2->data);
1,457✔
976
  v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
1,457✔
977

978
  free_istack_array(&eval->stack, (int32_t *) aux);
1,457✔
979

980
  return v;
1,457✔
981
}
982

983
static term_t eval_bv_sdiv(evaluator_t *eval, composite_term_t *app) {
1,439✔
984
  uint32_t *aux;
985
  uint32_t n, w;
986
  value_t v1, v2, v;
987
  value_bv_t *bv1, *bv2;
988

989
  assert(app->arity == 2);
990

991
  v1 = eval_term(eval, app->arg[0]);
1,439✔
992
  v2 = eval_term(eval, app->arg[1]);
1,439✔
993
  bv1 = vtbl_bitvector(eval->vtbl, v1);
1,439✔
994
  bv2 = vtbl_bitvector(eval->vtbl, v2);
1,439✔
995
  assert(bv1->nbits == bv2->nbits);
996

997
  n = bv1->nbits;
1,439✔
998
  w = bv1->width;
1,439✔
999
  assert(n>0 && w>0);
1000

1001
  aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
1,439✔
1002
  bvconst_sdiv2z(aux, n, bv1->data, bv2->data);
1,439✔
1003
  v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
1,439✔
1004

1005
  free_istack_array(&eval->stack, (int32_t *) aux);
1,439✔
1006

1007
  return v;
1,439✔
1008
}
1009

1010
static term_t eval_bv_srem(evaluator_t *eval, composite_term_t *app) {
1,340✔
1011
  uint32_t *aux;
1012
  uint32_t n, w;
1013
  value_t v1, v2, v;
1014
  value_bv_t *bv1, *bv2;
1015

1016
  assert(app->arity == 2);
1017

1018
  v1 = eval_term(eval, app->arg[0]);
1,340✔
1019
  v2 = eval_term(eval, app->arg[1]);
1,340✔
1020
  bv1 = vtbl_bitvector(eval->vtbl, v1);
1,340✔
1021
  bv2 = vtbl_bitvector(eval->vtbl, v2);
1,340✔
1022
  assert(bv1->nbits == bv2->nbits);
1023

1024
  n = bv1->nbits;
1,340✔
1025
  w = bv1->width;
1,340✔
1026
  assert(n>0 && w>0);
1027

1028
  aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
1,340✔
1029
  bvconst_srem2z(aux, n, bv1->data, bv2->data);
1,340✔
1030
  v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
1,340✔
1031

1032
  free_istack_array(&eval->stack, (int32_t *) aux);
1,340✔
1033

1034
  return v;
1,340✔
1035
}
1036

1037
static term_t eval_bv_smod(evaluator_t *eval, composite_term_t *app) {
1✔
1038
  uint32_t *aux;
1039
  uint32_t n, w;
1040
  value_t v1, v2, v;
1041
  value_bv_t *bv1, *bv2;
1042

1043
  assert(app->arity == 2);
1044

1045
  v1 = eval_term(eval, app->arg[0]);
1✔
1046
  v2 = eval_term(eval, app->arg[1]);
1✔
1047
  bv1 = vtbl_bitvector(eval->vtbl, v1);
1✔
1048
  bv2 = vtbl_bitvector(eval->vtbl, v2);
1✔
1049
  assert(bv1->nbits == bv2->nbits);
1050

1051
  n = bv1->nbits;
1✔
1052
  w = bv1->width;
1✔
1053
  assert(n>0 && w>0);
1054

1055
  aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
1✔
1056
  bvconst_smod2z(aux, n, bv1->data, bv2->data);
1✔
1057
  v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
1✔
1058

1059
  free_istack_array(&eval->stack, (int32_t *) aux);
1✔
1060

1061
  return v;
1✔
1062
}
1063

1064

1065
/*
1066
 * Convert bv's value (interpreted as a non-negative integer) into a shift amount.
1067
 * If bv's value is larger than nbits, then returns bv->nbits
1068
 */
1069
static uint32_t get_shift_amount(value_bv_t *bv) {
4,423✔
1070
  uint32_t n, k, i, s;
1071

1072
  s = bvconst_get32(bv->data); // low-order word = shift amount
4,423✔
1073
  n = bv->nbits;
4,423✔
1074

1075
  if (s < n) {
4,423✔
1076
    k = bv->width;
2,841✔
1077
    // if any of the higher order words is nonzero, return n
1078
    for (i=1; i<k; i++) {
2,880✔
1079
      if (bv->data[i] != 0) {
39✔
1080
        return n;
×
1081
      }
1082
    }
1083
    return s;
2,841✔
1084
  }
1085

1086
  return n;
1,582✔
1087
}
1088

1089

1090
/*
1091
 * Bitvector shift operators
1092
 */
1093
static term_t eval_bv_shl(evaluator_t *eval, composite_term_t *app) {
1,314✔
1094
  uint32_t *aux;
1095
  uint32_t n, w;
1096
  value_t v1, v2, v;
1097
  value_bv_t *bv1, *bv2;
1098

1099
  assert(app->arity == 2);
1100

1101
  v1 = eval_term(eval, app->arg[0]);
1,314✔
1102
  v2 = eval_term(eval, app->arg[1]);
1,314✔
1103
  bv1 = vtbl_bitvector(eval->vtbl, v1);
1,314✔
1104
  bv2 = vtbl_bitvector(eval->vtbl, v2);
1,314✔
1105
  assert(bv1->nbits == bv2->nbits);
1106

1107
  n = bv1->nbits;
1,314✔
1108
  w = bv1->width;
1,314✔
1109
  assert(n>0 && w>0);
1110

1111
  aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
1,314✔
1112
  bvconst_set(aux, w, bv1->data);
1,314✔
1113
  w = get_shift_amount(bv2);
1,314✔
1114
  bvconst_shift_left(aux, n, w, 0); // padding with 0
1,314✔
1115

1116
  v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
1,314✔
1117

1118
  free_istack_array(&eval->stack, (int32_t *) aux);
1,314✔
1119

1120
  return v;
1,314✔
1121
}
1122

1123
static term_t eval_bv_lshr(evaluator_t *eval, composite_term_t *app) {
1,642✔
1124
  uint32_t *aux;
1125
  uint32_t n, w;
1126
  value_t v1, v2, v;
1127
  value_bv_t *bv1, *bv2;
1128

1129
  assert(app->arity == 2);
1130

1131
  v1 = eval_term(eval, app->arg[0]);
1,642✔
1132
  v2 = eval_term(eval, app->arg[1]);
1,642✔
1133
  bv1 = vtbl_bitvector(eval->vtbl, v1);
1,642✔
1134
  bv2 = vtbl_bitvector(eval->vtbl, v2);
1,642✔
1135
  assert(bv1->nbits == bv2->nbits);
1136

1137
  n = bv1->nbits;
1,642✔
1138
  w = bv1->width;
1,642✔
1139
  assert(n>0 && w>0);
1140

1141
  aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
1,642✔
1142
  bvconst_set(aux, w, bv1->data);
1,642✔
1143
  w = get_shift_amount(bv2);
1,642✔
1144
  bvconst_shift_right(aux, n, w, 0); // padding with 0
1,642✔
1145

1146
  v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
1,642✔
1147

1148
  free_istack_array(&eval->stack, (int32_t *) aux);
1,642✔
1149

1150
  return v;
1,642✔
1151
}
1152

1153
static term_t eval_bv_ashr(evaluator_t *eval, composite_term_t *app) {
1,467✔
1154
  uint32_t *aux;
1155
  uint32_t n, w;
1156
  value_t v1, v2, v;
1157
  value_bv_t *bv1, *bv2;
1158

1159
  assert(app->arity == 2);
1160

1161
  v1 = eval_term(eval, app->arg[0]);
1,467✔
1162
  v2 = eval_term(eval, app->arg[1]);
1,467✔
1163
  bv1 = vtbl_bitvector(eval->vtbl, v1);
1,467✔
1164
  bv2 = vtbl_bitvector(eval->vtbl, v2);
1,467✔
1165
  assert(bv1->nbits == bv2->nbits);
1166

1167
  n = bv1->nbits;
1,467✔
1168
  w = bv1->width;
1,467✔
1169
  assert(n>0 && w>0);
1170

1171
  aux = (uint32_t *) alloc_istack_array(&eval->stack, w);
1,467✔
1172
  bvconst_set(aux, w, bv1->data);
1,467✔
1173
  w = get_shift_amount(bv2);
1,467✔
1174
  bvconst_shift_right(aux, n, w, bvconst_tst_bit(aux, n-1)); // padding with sign bit
1,467✔
1175

1176
  v = vtbl_mk_bv_from_bv(eval->vtbl, n, aux);
1,467✔
1177

1178
  free_istack_array(&eval->stack, (int32_t *) aux);
1,467✔
1179

1180
  return v;
1,467✔
1181
}
1182

1183

1184

1185
/*
1186
 * Bitvector atoms
1187
 */
1188
static value_t eval_bveq(evaluator_t *eval, composite_term_t *eq) {
18,411✔
1189
  value_t v1, v2;
1190

1191
  assert(eq->arity == 2);
1192

1193
  v1 = eval_term(eval, eq->arg[0]);
18,411✔
1194
  v2 = eval_term(eval, eq->arg[1]);
18,411✔
1195
  assert(object_is_bitvector(eval->vtbl, v1) &&
1196
         object_is_bitvector(eval->vtbl, v2));
1197

1198
  return vtbl_mk_bool(eval->vtbl, v1 == v2);
18,411✔
1199
}
1200

1201
static value_t eval_bvge(evaluator_t *eval, composite_term_t *ge) {
11,756✔
1202
  value_t v1, v2;
1203
  value_bv_t *bv1, *bv2;
1204
  bool test;
1205

1206
  assert(ge->arity == 2);
1207

1208
  v1 = eval_term(eval, ge->arg[0]);
11,756✔
1209
  v2 = eval_term(eval, ge->arg[1]);
11,756✔
1210
  bv1 = vtbl_bitvector(eval->vtbl, v1);
11,756✔
1211
  bv2 = vtbl_bitvector(eval->vtbl, v2);
11,756✔
1212
  assert(bv1->nbits == bv2->nbits);
1213
  test = bvconst_ge(bv1->data, bv2->data, bv1->nbits);
11,756✔
1214

1215
  return vtbl_mk_bool(eval->vtbl, test);
11,756✔
1216
}
1217

1218
static value_t eval_bvsge(evaluator_t *eval, composite_term_t *sge) {
13,105✔
1219
  value_t v1, v2;
1220
  value_bv_t *bv1, *bv2;
1221
  bool test;
1222

1223
  assert(sge->arity == 2);
1224

1225
  v1 = eval_term(eval, sge->arg[0]);
13,105✔
1226
  v2 = eval_term(eval, sge->arg[1]);
13,105✔
1227
  bv1 = vtbl_bitvector(eval->vtbl, v1);
13,105✔
1228
  bv2 = vtbl_bitvector(eval->vtbl, v2);
13,105✔
1229
  assert(bv1->nbits == bv2->nbits);
1230
  test = bvconst_sge(bv1->data, bv2->data, bv1->nbits);
13,105✔
1231

1232
  return vtbl_mk_bool(eval->vtbl, test);
13,105✔
1233
}
1234

1235

1236

1237
/*
1238
 * Power product: bitvector of nbits
1239
 */
1240
static value_t eval_bv_pprod(evaluator_t *eval, pprod_t *p, uint32_t nbits) {
1,884✔
1241
  uint32_t *a;
1242
  uint32_t i, n, w;
1243
  term_t t;
1244
  value_t o;
1245

1246
  // get bitsize
1247
  w = (nbits + 31) >> 5; // width in words
1,884✔
1248
  a = (uint32_t *) alloc_istack_array(&eval->stack, w);
1,884✔
1249
  bvconst_set_one(a, w);
1,884✔
1250

1251
  n = p->len;
1,884✔
1252
  for (i=0; i<n; i++) {
5,322✔
1253
    t = p->prod[i].var;
3,438✔
1254
    o = eval_term(eval, t);
3,438✔
1255
    // prod[i] is v ^ k so q := q * (o ^ k)
1256
    bvconst_mulpower(a, w, vtbl_bitvector(eval->vtbl, o)->data, p->prod[i].exp);
3,438✔
1257
  }
1258

1259
  // convert to object
1260
  bvconst_normalize(a, nbits);
1,884✔
1261
  o = vtbl_mk_bv_from_bv(eval->vtbl, nbits, a);
1,884✔
1262

1263
  // cleanup
1264
  free_istack_array(&eval->stack, (int32_t *) a);
1,884✔
1265

1266
  return o;
1,884✔
1267
}
1268

1269

1270
/*
1271
 * Bitvector polynomial: wide coefficients
1272
 */
1273
static value_t eval_bv_poly(evaluator_t *eval, bvpoly_t *p) {
430✔
1274
  uint32_t *sum;
1275
  uint32_t i, n, nbits, w;
1276
  term_t t;
1277
  value_t v;
1278

1279
  nbits = p->bitsize;
430✔
1280
  w = p->width;
430✔
1281

1282
  sum = (uint32_t *) alloc_istack_array(&eval->stack, w);
430✔
1283
  bvconst_clear(sum, w);
430✔
1284

1285
  n = p->nterms;
430✔
1286
  for (i=0; i<n; i++) {
1,291✔
1287
    t = p->mono[i].var;
861✔
1288
    if (t == const_idx) {
861✔
1289
      bvconst_add(sum, w, p->mono[i].coeff);
395✔
1290
    } else {
1291
      v = eval_term(eval, t);
466✔
1292
      // sum := sum + coeff * v
1293
      bvconst_addmul(sum, w, p->mono[i].coeff, vtbl_bitvector(eval->vtbl, v)->data);
466✔
1294
    }
1295
  }
1296

1297
  // convert sum to an object
1298
  bvconst_normalize(sum, nbits);
430✔
1299
  v = vtbl_mk_bv_from_bv(eval->vtbl, nbits, sum);
430✔
1300

1301
  free_istack_array(&eval->stack, (int32_t *) sum);
430✔
1302

1303
  return v;
430✔
1304
}
1305

1306

1307
/*
1308
 * Convert bivector object o to a 64bit unsigned integer
1309
 * - o must have between 1 and 64bits
1310
 */
1311
static uint64_t bvobj_to_uint64(value_bv_t *o) {
19,327✔
1312
  uint64_t c;
1313

1314
  assert(1 <= o->nbits && o->nbits <= 64);
1315
  c = o->data[0];
19,327✔
1316
  if (o->nbits > 32) {
19,327✔
1317
    c += ((uint64_t) o->data[1]) << 32;
34✔
1318
  }
1319
  return c;
19,327✔
1320
}
1321

1322

1323
/*
1324
 * Bitvector polynomial: 64bit coefficients
1325
 */
1326
static value_t eval_bv64_poly(evaluator_t *eval, bvpoly64_t *p) {
15,769✔
1327
  uint64_t sum;
1328
  uint32_t i, n, nbits;
1329
  term_t t;
1330
  value_t v;
1331

1332
  nbits = p->bitsize;
15,769✔
1333
  assert(0 < nbits && nbits <= 64);
1334

1335
  sum = 0;
15,769✔
1336

1337
  n = p->nterms;
15,769✔
1338
  for (i=0; i<n; i++) {
37,456✔
1339
    t = p->mono[i].var;
21,687✔
1340
    if (t == const_idx) {
21,687✔
1341
      sum += p->mono[i].coeff;
2,360✔
1342
    } else {
1343
      v = eval_term(eval, t);
19,327✔
1344
      sum += p->mono[i].coeff * bvobj_to_uint64(vtbl_bitvector(eval->vtbl, v));
19,327✔
1345
    }
1346
  }
1347

1348
  // convert sum to an object
1349
  sum = norm64(sum, nbits);
15,769✔
1350
  v = vtbl_mk_bv_from_bv64(eval->vtbl, nbits, sum);
15,769✔
1351

1352
  return v;
15,769✔
1353
}
1354

1355

1356

1357
/*
1358
 * Evaluate basic constructs
1359
 */
1360
static value_t eval_ite(evaluator_t *eval, composite_term_t *ite) {
215,997✔
1361
  value_t c;
1362

1363
  assert(ite->arity == 3);
1364

1365
  c = eval_term(eval, ite->arg[0]);
215,997✔
1366
  if (is_true(eval->vtbl, c)) {
215,997✔
1367
    return eval_term(eval, ite->arg[1]);
94,416✔
1368
  } else {
1369
    assert(is_false(eval->vtbl, c));
1370
    return eval_term(eval, ite->arg[2]);
121,581✔
1371
  }
1372
}
1373

1374
static value_t eval_eq(evaluator_t *eval, composite_term_t *eq) {
52,180✔
1375
  value_t v1, v2;
1376

1377
  assert(eq->arity == 2);
1378

1379
  v1 = eval_term(eval, eq->arg[0]);
52,180✔
1380
  v2 = eval_term(eval, eq->arg[1]);
52,180✔
1381
  return vtbl_eval_eq(eval->vtbl, v1, v2);
52,179✔
1382
}
1383

1384

1385
/*
1386
 * app is (fun arg[0] ... arg[n-1])
1387
 */
1388
static value_t eval_app(evaluator_t *eval, composite_term_t *app) {
252,089✔
1389
  value_t *a;
1390
  value_t *b;
1391
  composite_term_t *update;
1392
  value_t v, f;
1393
  uint32_t n;
1394
  term_t fun;
1395

1396
  // eval the arguments first
1397
  assert(app->arity >= 2);
1398
  n = app->arity - 1;
252,089✔
1399
  a = alloc_istack_array(&eval->stack, n);
252,089✔
1400
  eval_term_array(eval, app->arg+1, a, n); // a[i] = eval(arg[i])
252,089✔
1401

1402
  /*
1403
   * Try to avoid evaluating fun if it's an update.
1404
   * TODO: check whether that matters??
1405
   */
1406
  fun = app->arg[0];
252,089✔
1407
  if (term_kind(eval->terms, fun) == UPDATE_TERM) {
252,089✔
1408
    b = alloc_istack_array(&eval->stack, n);
3,738✔
1409
    do {
1410
      // fun is (update f (x_1 ... x_n) v)
1411
      update = update_term_desc(eval->terms, fun);
15,957✔
1412
      assert(update->arity == n + 2);
1413

1414
      // evaluate x_1 ... x_n
1415
      eval_term_array(eval, update->arg+1, b, n); // b[i] = eval(x_{i+1})
15,957✔
1416

1417
      // check equality
1418
      v = vtbl_eval_array_eq(eval->vtbl, a, b, n);
15,957✔
1419
      if (is_unknown(eval->vtbl, v)) {
15,957✔
1420
        // result is unknown too
1421
        free_istack_array(&eval->stack, b);
×
1422
        goto done;
×
1423

1424
      } else if (is_true(eval->vtbl, v)) {
15,957✔
1425
        // ((update f (x_1 ... x_n) v) a[0] ... a[n-1]) --> v
1426
        v = eval_term(eval, update->arg[n+1]);
1,807✔
1427
        free_istack_array(&eval->stack, b);
1,807✔
1428
        goto done;
1,807✔
1429

1430
      } else {
1431
        // ((update f  ... v) a[0] ... a[n-1]) --> (f a[0] ... a[n-1])
1432
        fun = update->arg[0];
14,150✔
1433
      }
1434

1435
    } while (term_kind(eval->terms, fun) == UPDATE_TERM);
14,150✔
1436

1437
    free_istack_array(&eval->stack, b);
1,931✔
1438
  }
1439

1440

1441
  /*
1442
   * compute (fun a[0] ... a[n-1])
1443
   */
1444
  assert(term_kind(eval->terms, fun) != UPDATE_TERM);
1445
  f = eval_term(eval, fun);
250,282✔
1446
  v = vtbl_eval_application(eval->vtbl, f, n, a);
250,282✔
1447

1448
 done:
252,089✔
1449
  free_istack_array(&eval->stack, a);
252,089✔
1450
  return v;
252,089✔
1451
}
1452

1453

1454
static value_t eval_or(evaluator_t *eval, composite_term_t *or) {
94,200✔
1455
  uint32_t i, n;
1456
  value_t v;
1457

1458
  n = or->arity;
94,200✔
1459
  for (i=0; i<n; i++) {
173,705✔
1460
    v = eval_term(eval, or->arg[i]);
143,539✔
1461
    if (is_true(eval->vtbl, v)) {
143,538✔
1462
      return v;
64,033✔
1463
    }
1464
    assert(is_false(eval->vtbl, v));
1465
  }
1466

1467
  return vtbl_mk_false(eval->vtbl);
30,166✔
1468
}
1469

1470

1471
static value_t eval_xor(evaluator_t *eval, composite_term_t *xor) {
4✔
1472
  uint32_t i, n;
1473
  value_t v, w;
1474

1475
  n = xor->arity;
4✔
1476
  v = vtbl_mk_false(eval->vtbl);
4✔
1477
  for (i=0; i<n; i++) {
16✔
1478
    w = eval_term(eval, xor->arg[i]);
12✔
1479
    // v := v xor w: true if v != w, false if v == w
1480
    v = vtbl_mk_bool(eval->vtbl, v != w);
12✔
1481
  }
1482

1483
  return v;
4✔
1484
}
1485

1486

1487
static value_t eval_tuple(evaluator_t *eval, composite_term_t *tuple) {
×
1488
  value_t *a;
1489
  value_t v;
1490
  uint32_t i, n;
1491

1492
  n = tuple->arity;
×
1493
  a = alloc_istack_array(&eval->stack, n);
×
1494
  for (i=0; i<n; i++) {
×
1495
    a[i] = eval_term(eval, tuple->arg[i]);
×
1496
  }
1497
  v = vtbl_mk_tuple(eval->vtbl, n, a);
×
1498
  free_istack_array(&eval->stack, a);
×
1499

1500
  return v;
×
1501
}
1502

1503

1504
static value_t eval_select(evaluator_t *eval, select_term_t *select) {
×
1505
  value_t v;
1506
  value_tuple_t *t;
1507

1508
  v = eval_term(eval, select->arg);
×
1509
  t = vtbl_tuple(eval->vtbl, v);
×
1510
  assert(0 <= select->idx && select->idx < t->nelems);
1511

1512
  return t->elem[select->idx];
×
1513
}
1514

1515

1516
static value_t eval_update(evaluator_t *eval, composite_term_t *update) {
13,369✔
1517
  value_t *a;
1518
  value_t v, f;
1519
  uint32_t i, n;
1520

1521
  assert(update->arity >= 3);
1522

1523
  n = update->arity - 2;
13,369✔
1524
  a = alloc_istack_array(&eval->stack, n);
13,369✔
1525
  f = eval_term(eval, update->arg[0]);
13,369✔
1526
  for (i=0; i<n; i++) {
26,738✔
1527
    a[i] = eval_term(eval, update->arg[i+1]);
13,369✔
1528
  }
1529
  v = eval_term(eval, update->arg[n+1]);
13,369✔
1530

1531
  v = vtbl_mk_update(eval->vtbl, f, n, a, v);
13,369✔
1532
  free_istack_array(&eval->stack, a);
13,369✔
1533

1534
  return v;
13,369✔
1535
}
1536

1537

1538
static value_t eval_distinct(evaluator_t *eval, composite_term_t *distinct) {
16✔
1539
  value_t *a;
1540
  value_t v, eq;
1541
  uint32_t i, j, n;
1542

1543
  n = distinct->arity;
16✔
1544
  a = alloc_istack_array(&eval->stack, n);
16✔
1545
  for (i=0; i<n; i++) {
38✔
1546
    v = eval_term(eval, distinct->arg[i]);
38✔
1547

1548
    for (j=0; j<i; j++) {
52✔
1549
      eq = vtbl_eval_eq(eval->vtbl, a[j], v);
30✔
1550
      if (is_unknown(eval->vtbl, eq)) {
30✔
1551
        v = eq; // i.e., unknown
2✔
1552
        goto done;
2✔
1553
      } else if (is_true(eval->vtbl, eq)) {
28✔
1554
        // a[j] == v so distinct is false
1555
        v = vtbl_mk_false(eval->vtbl);
14✔
1556
        goto done;
14✔
1557
      }
1558
    }
1559
    a[i] = v;
22✔
1560
  }
1561

1562
  v = vtbl_mk_true(eval->vtbl);
×
1563

1564
 done:
16✔
1565
  free_istack_array(&eval->stack, a);
16✔
1566
  return v;
16✔
1567
}
1568

1569

1570

1571

1572
/*
1573
 * Return a default value of type tau
1574
 */
1575
static value_t make_default_value(evaluator_t *eval, type_t tau) {
18,853✔
1576
  return vtbl_make_object(eval->vtbl, tau);
18,853✔
1577
}
1578

1579

1580

1581
/*
1582
 * Uninterpreted term t
1583
 * - t has no concrete value assigned in the model
1584
 * - the model keeps term substitution (in alias_map);
1585
 */
1586
static value_t eval_uninterpreted(evaluator_t *eval, term_t t) {
19,581✔
1587
  term_t u;
1588
  value_t v;
1589

1590
  assert(eval->model->has_alias);
1591
  // check for a substitution
1592
  u = model_find_term_substitution(eval->model, t);
19,581✔
1593
  if (u == NULL_TERM) {
19,581✔
1594
    // assign a default value based on t's type
1595
    v = make_default_value(eval, term_type(eval->terms, t));
18,853✔
1596
  } else {
1597
    // [t --> u] is a substitution in the alias table
1598
    v = eval_term(eval, u);
728✔
1599
  }
1600

1601
  return v;
19,581✔
1602
}
1603

1604
static inline const rational_t* arith_get_mod(term_table_t *table, term_t t) {
64✔
1605
  type_t tau = term_type(table, t);
64✔
1606
  return is_finite_type(table->types, tau) ? ff_type_size(table->types, tau) : NULL;
64✔
1607
}
1608

1609

1610
/*
1611
 * Compute the value v of term t in the model
1612
 * - add the mapping t := v  to the cache
1613
 * - raise an exception if t can't be evaluated
1614
 */
1615
static value_t eval_term(evaluator_t *eval, term_t t) {
3,586,213✔
1616
  term_table_t *terms;
1617
  bool negative;
1618
  value_t v;
1619
  term_kind_t t_kind;
1620

1621
  negative = is_neg_term(t);
3,586,213✔
1622
  t = unsigned_term(t);
3,586,213✔
1623

1624
  /*
1625
   * First check the model itself then check the cache.
1626
   * If no value is mapped to t in either of them, compute t's
1627
   * value v and add the mapping t := v to the cache.
1628
   */
1629
  v = model_find_term_value(eval->model, t);
3,586,213✔
1630
  if (v == null_value) {
3,586,213✔
1631
    v = eval_cached_value(eval, t);
2,709,319✔
1632
    if (v == null_value) {
2,709,319✔
1633
      terms = eval->terms;
1,591,324✔
1634

1635
      t_kind = term_kind(terms, t);
1,591,324✔
1636
      switch (t_kind) {
1,591,324✔
1637
      case CONSTANT_TERM:
11,443✔
1638
        if (t == true_term) {
11,443✔
1639
          v = vtbl_mk_true(eval->vtbl);
11,443✔
1640
        } else if (t == false_term) {
×
1641
          v = vtbl_mk_false(eval->vtbl);
×
1642
        } else {
1643
          v = vtbl_mk_const(eval->vtbl, term_type(terms, t), constant_term_index(terms, t),
×
1644
                            term_name(terms, t));
1645
        }
1646
        break;
11,443✔
1647

1648
      case ARITH_CONSTANT:
29,815✔
1649
        v = vtbl_mk_rational(eval->vtbl, rational_term_desc(terms, t));
29,815✔
1650
        break;
29,815✔
1651

1652
      case ARITH_FF_CONSTANT:
4✔
1653
        assert(arith_get_mod(terms, t) && q_is_pos(arith_get_mod(terms, t)));
1654
        assert(q_lt(finitefield_term_desc(terms, t), arith_get_mod(terms, t)));
1655
        v = vtbl_mk_finitefield(eval->vtbl, finitefield_term_desc(terms, t), arith_get_mod(terms, t));
4✔
1656
        break;
4✔
1657

1658
      case BV64_CONSTANT:
22,459✔
1659
        v = eval_bv64_constant(eval, bvconst64_term_desc(terms, t));
22,459✔
1660
        break;
22,459✔
1661

1662
      case BV_CONSTANT:
85✔
1663
        v = eval_bv_constant(eval, bvconst_term_desc(terms, t));
85✔
1664
        break;
85✔
1665

1666
      case VARIABLE:
×
1667
        // free variable
1668
        longjmp(eval->env, MDL_EVAL_FREEVAR_IN_TERM);
×
1669
        break;
1670

1671
      case UNINTERPRETED_TERM:
19,581✔
1672
        // t has no value mapped in the model
1673
        if (eval->model->has_alias) {
19,581✔
1674
          v = eval_uninterpreted(eval, t);
19,581✔
1675
        } else {
1676
          longjmp(eval->env, MDL_EVAL_UNKNOWN_TERM);
×
1677
        }
1678
        break;
19,581✔
1679

1680
      case ARITH_EQ_ATOM:
31,520✔
1681
        v = eval_arith_eq(eval, arith_eq_arg(terms, t));
31,520✔
1682
        break;
31,520✔
1683

1684
      case ARITH_GE_ATOM:
92,344✔
1685
        v = eval_arith_ge(eval, arith_ge_arg(terms, t));
92,344✔
1686
        break;
92,344✔
1687

1688
      case ARITH_IS_INT_ATOM:
1✔
1689
        v = eval_arith_is_int(eval, arith_is_int_arg(terms, t));
1✔
1690
        break;
1✔
1691

1692
      case ARITH_FLOOR:
2✔
1693
        v = eval_arith_floor(eval, arith_floor_arg(terms, t));
2✔
1694
        break;
2✔
1695

1696
      case ARITH_CEIL:
×
1697
        v = eval_arith_ceil(eval, arith_ceil_arg(terms, t));
×
1698
        break;
×
1699

1700
      case ARITH_ABS:
1✔
1701
        v = eval_arith_abs(eval, arith_abs_arg(terms, t));
1✔
1702
        break;
1✔
1703

1704
      case ARITH_ROOT_ATOM:
×
1705
        // not supported (but don't crash if we see them)
NEW
1706
        v = vtbl_mk_unknown(eval->vtbl);
×
NEW
1707
        break;
×
1708

1709
      case ARITH_FF_EQ_ATOM:
21✔
1710
        v = eval_arith_ff_eq(eval, arith_ff_eq_arg(terms, t));
21✔
1711
        break;
21✔
1712

1713
      case ITE_TERM:
215,997✔
1714
      case ITE_SPECIAL:
1715
        v = eval_ite(eval, ite_term_desc(terms, t));
215,997✔
1716
        break;
215,997✔
1717

1718
      case APP_TERM:
252,089✔
1719
        v = eval_app(eval, app_term_desc(terms, t));
252,089✔
1720
        break;
252,089✔
1721

1722
      case UPDATE_TERM:
13,369✔
1723
        v = eval_update(eval, update_term_desc(terms, t));
13,369✔
1724
        break;
13,369✔
1725

1726
      case TUPLE_TERM:
×
1727
        v = eval_tuple(eval, tuple_term_desc(terms, t));
×
1728
        break;
×
1729

1730
      case EQ_TERM:
52,180✔
1731
        v = eval_eq(eval, eq_term_desc(terms, t));
52,180✔
1732
        break;
52,179✔
1733

1734
      case DISTINCT_TERM:
16✔
1735
        v = eval_distinct(eval, distinct_term_desc(terms, t));
16✔
1736
        break;
16✔
1737

1738
      case FORALL_TERM:
×
1739
        // don't try to evaluate forall for now
1740
        // but we could deal with quantification over finite types
1741
        longjmp(eval->env, MDL_EVAL_QUANTIFIER);
×
1742
        break;
1743

1744
      case LAMBDA_TERM:
1✔
1745
        // don't evaluate
1746
        longjmp(eval->env, MDL_EVAL_LAMBDA);
1✔
1747
        break;
1748

1749
      case OR_TERM:
94,200✔
1750
        v = eval_or(eval, or_term_desc(terms, t));
94,200✔
1751
        break;
94,199✔
1752

1753
      case XOR_TERM:
4✔
1754
        v = eval_xor(eval, xor_term_desc(terms, t));
4✔
1755
        break;
4✔
1756

1757
      case ARITH_BINEQ_ATOM:
18,454✔
1758
        v = eval_arith_bineq(eval, arith_bineq_atom_desc(terms, t));
18,454✔
1759
        break;
18,454✔
1760

1761
      case ARITH_RDIV:
6✔
1762
        v = eval_arith_rdiv(eval, arith_rdiv_term_desc(terms, t));
6✔
1763
        break;
6✔
1764

1765
      case ARITH_IDIV:
6✔
1766
        v = eval_arith_idiv(eval, arith_idiv_term_desc(terms, t));
6✔
1767
        break;
6✔
1768

1769
      case ARITH_MOD:
5✔
1770
        v = eval_arith_mod(eval, arith_mod_term_desc(terms, t));
5✔
1771
        break;
5✔
1772

1773
      case ARITH_DIVIDES_ATOM:
×
1774
        v = eval_arith_divides(eval, arith_divides_atom_desc(terms, t));
×
1775
        break;
×
1776

1777
      case ARITH_FF_BINEQ_ATOM:
4✔
1778
        v = eval_finitefield_bineq(eval, arith_ff_bineq_atom_desc(terms, t));
4✔
1779
        break;
4✔
1780

1781
      case BV_ARRAY:
66,128✔
1782
        v = eval_bv_array(eval, bvarray_term_desc(terms, t));
66,128✔
1783
        break;
66,128✔
1784

1785
      case BV_DIV:
1,762✔
1786
        v = eval_bv_div(eval, bvdiv_term_desc(terms, t));
1,762✔
1787
        break;
1,762✔
1788

1789
      case BV_REM:
1,457✔
1790
        v = eval_bv_rem(eval, bvrem_term_desc(terms, t));
1,457✔
1791
        break;
1,457✔
1792

1793
      case BV_SDIV:
1,439✔
1794
        v = eval_bv_sdiv(eval, bvsdiv_term_desc(terms, t));
1,439✔
1795
        break;
1,439✔
1796

1797
      case BV_SREM:
1,340✔
1798
        v = eval_bv_srem(eval, bvsrem_term_desc(terms, t));
1,340✔
1799
        break;
1,340✔
1800

1801
      case BV_SMOD:
1✔
1802
        v = eval_bv_smod(eval, bvsmod_term_desc(terms, t));
1✔
1803
        break;
1✔
1804

1805
      case BV_SHL:
1,314✔
1806
        v = eval_bv_shl(eval, bvshl_term_desc(terms, t));
1,314✔
1807
        break;
1,314✔
1808

1809
      case BV_LSHR:
1,642✔
1810
        v = eval_bv_lshr(eval, bvlshr_term_desc(terms, t));
1,642✔
1811
        break;
1,642✔
1812

1813
      case BV_ASHR:
1,467✔
1814
        v = eval_bv_ashr(eval, bvashr_term_desc(terms, t));
1,467✔
1815
        break;
1,467✔
1816

1817
      case BV_EQ_ATOM:
18,411✔
1818
        v = eval_bveq(eval, bveq_atom_desc(terms, t));
18,411✔
1819
        break;
18,411✔
1820

1821
      case BV_GE_ATOM:
11,756✔
1822
        v = eval_bvge(eval, bvge_atom_desc(terms, t));
11,756✔
1823
        break;
11,756✔
1824

1825
      case BV_SGE_ATOM:
13,105✔
1826
        v = eval_bvsge(eval, bvsge_atom_desc(terms, t));
13,105✔
1827
        break;
13,105✔
1828

1829
      case SELECT_TERM:
×
1830
        v = eval_select(eval, select_term_desc(terms, t));
×
1831
        break;
×
1832

1833
      case BIT_TERM:
373,762✔
1834
        v = eval_bit(eval, bit_term_desc(terms, t));
373,762✔
1835
        break;
373,762✔
1836

1837
      case POWER_PRODUCT:
2,269✔
1838
        if (is_bitvector_term(terms, t)) {
2,269✔
1839
          v = eval_bv_pprod(eval, pprod_term_desc(terms, t), term_bitsize(terms, t));
1,884✔
1840
        } else if (is_arithmetic_term(terms, t)) {
385✔
1841
          v = eval_arith_pprod(eval, pprod_term_desc(terms, t), NULL);
344✔
1842
        } else if (is_finitefield_term(terms, t)) {
41✔
1843
          v = eval_arith_pprod(eval, pprod_term_desc(terms, t), arith_get_mod(terms, t));
41✔
1844
        } else {
1845
          assert(false);
NEW
1846
          v = vtbl_mk_unknown(eval->vtbl);
×
1847
        }
1848
        break;
2,269✔
1849

1850
      case ARITH_POLY:
225,646✔
1851
        v = eval_arith_poly(eval, poly_term_desc(terms, t));
225,646✔
1852
        break;
225,646✔
1853

1854
      case ARITH_FF_POLY:
19✔
1855
        v = eval_arith_ff_poly(eval, finitefield_poly_term_desc(terms, t), arith_get_mod(terms, t));
19✔
1856
        break;
19✔
1857

1858
      case BV64_POLY:
15,769✔
1859
        v = eval_bv64_poly(eval, bvpoly64_term_desc(terms, t));
15,769✔
1860
        break;
15,769✔
1861

1862
      case BV_POLY:
430✔
1863
        v = eval_bv_poly(eval, bvpoly_term_desc(terms, t));
430✔
1864
        break;
430✔
1865

1866
      default:
×
1867
        assert(false);
1868
        longjmp(eval->env, MDL_EVAL_INTERNAL_ERROR);
×
1869
        break;
1870
      }
1871

1872
      // if the result v is unknown we quit now
1873
      assert(v >= 0); // Coverity thinks v can be negative.
1874
      if (object_is_unknown(eval->vtbl, v)) {
1,591,321✔
1875
        longjmp(eval->env, MDL_EVAL_FAILED);
2✔
1876
      }
1877

1878
      eval_cache_map(eval, t, v);
1,591,319✔
1879
    }
1880
  }
1881

1882
  if (negative) {
3,586,208✔
1883
    v = vtbl_mk_not(eval->vtbl, v);
396,486✔
1884
  }
1885

1886
  return v;
3,586,208✔
1887
}
1888

1889

1890
/*
1891
 * Compute the value of t in the model
1892
 * - t must be a valid term
1893
 * - return a negative code if there's an error
1894
 * - otherwise, return the id of a concrete object of eval->model.vtbl
1895
 *
1896
 * Evaluation may create new objects. All these new objects are
1897
 * permananet in eval->vtbl.
1898
 */
1899
value_t eval_in_model(evaluator_t *eval, term_t t) {
174,228✔
1900
  value_t v;
1901

1902
  v = setjmp(eval->env);
174,228✔
1903
  if (v == 0) {
174,231✔
1904
    v = eval_term(eval, t);
174,228✔
1905
  } else {
1906
    assert(v < 0); // error code after longjmp
1907
    reset_istack(&eval->stack);
3✔
1908
  }
1909

1910
  return v;
174,228✔
1911
}
1912

1913

1914
/*
1915
 * Check whether t is true in the model
1916
 * - t must be a valid term
1917
 * - return true if t evaluates to true
1918
 * - return false if t can't be evaluated or
1919
 *   if t's value is not boolean or not true.
1920
 */
1921
bool eval_to_true_in_model(evaluator_t *eval, term_t t) {
7,464✔
1922
  value_t v;
1923

1924
  v = eval_in_model(eval, t);
7,464✔
1925
  return good_object(eval->vtbl, v) && is_true(eval->vtbl, v);
7,464✔
1926
}
1927

1928

1929
/*
1930
 * Check whether t is false in the model
1931
 * - t must be a valid term
1932
 * - return true if t evaluates to true
1933
 * - return false if t can't be evaluated or
1934
 *   if t's value is not boolean or not true.
1935
 */
1936
bool eval_to_false_in_model(evaluator_t *eval, term_t t) {
×
1937
  value_t v;
1938

1939
  v = eval_in_model(eval, t);
×
1940
  return good_object(eval->vtbl, v) && is_false(eval->vtbl, v);
×
1941
}
1942

1943

1944
/*
1945
 * Check whether t is zero in the model
1946
 * - t must be a valid term
1947
 * - if t is an arithmetic term, this checks whether value(t) == 0
1948
 * - if t is a bit-vector term, this checks whether value(t) == 0b0000...
1949
 * - return false if t can't be evaluated, or if t is not an arithemtic
1950
 *   term nor a bitvector term, or if t's value is not zero.
1951
 */
1952
bool eval_to_zero_in_model(evaluator_t *eval, term_t t) {
×
1953
  value_t v;
1954

1955
  v = eval_in_model(eval, t);
×
1956
  return good_object(eval->vtbl, v) &&
×
1957
    (is_zero(eval->vtbl, v) || is_bvzero(eval->vtbl, v));
×
1958
}
1959

1960
/*
1961
 * Check whether t evaluates to +/-1 in the model
1962
 * - t must be a valid  term
1963
 * - return false if t can't be evaluated or its value is not a rational
1964
 * - return true if t's value is either +1 or -1
1965
 */
1966
bool eval_to_unit_in_model(evaluator_t *eval, term_t t) {
×
1967
  value_t v;
1968

1969
  v = eval_in_model(eval, t);
×
1970
  return good_object(eval->vtbl, v) && is_unit(eval->vtbl, v);
×
1971
}
1972

1973

1974

1975

1976
/*
1977
 * Compute the values of terms a[0 ... n-1]
1978
 * - don't return anything
1979
 * - the value of a[i] can be queried by using eval_in_model(eval, a[i]) later
1980
 *   (this reads the value from eval->cache so that's cheap).
1981
 */
1982
void eval_terms_in_model(evaluator_t *eval, const term_t *a, uint32_t n) {
2✔
1983
  uint32_t i;
1984

1985
  for (i=0; i<n; i++) {
4✔
1986
    (void) eval_in_model(eval, a[i]);
2✔
1987
  }
1988
}
2✔
1989

1990

1991
/*
1992
 * Check whether term t is useful:
1993
 * - return true if t is unintepreted and has no existing value in eval->model
1994
 *   and is not mapped to another term u in the alias_map
1995
 */
1996
static bool term_is_useful(model_t *model, term_t t) {
8,103✔
1997
  value_t v;
1998

1999
  if (term_kind(model->terms, t) == UNINTERPRETED_TERM) {
8,103✔
2000
    v = model_find_term_value(model, t);
510✔
2001
    if (v == null_value && model->has_alias) {
510✔
2002
      return model_find_term_substitution(model, t) == NULL_TERM;
510✔
2003
    }
2004
  }
2005
  return false;
7,593✔
2006
}
2007

2008
/*
2009
 * Add a mapping t->v in eval->model for every pair (t, v) found in eval->cache
2010
 * and such that t is useful.
2011
 */
2012
void eval_record_useful_terms(evaluator_t *eval) {
95✔
2013
  model_t *model;
2014
  int_hmap_t *cache;
2015
  int_hmap_pair_t *r;
2016

2017
  model = eval->model;
95✔
2018
  cache = &eval->cache;
95✔
2019
  r = int_hmap_first_record(cache);
95✔
2020
  while (r != NULL) {
8,198✔
2021
    // r->key is the term, r->val is the value
2022
    if (term_is_useful(model, r->key) && !is_unknown(eval->vtbl, r->val)) {
8,103✔
2023
      model_map_term(model, r->key, r->val);
510✔
2024
    }
2025
    r = int_hmap_next_record(cache, r);
8,103✔
2026
  }
2027

2028
}
95✔
2029

2030
/*
2031
 * Cached-term collector:
2032
 * - call f(aux, t) for every t that's stored in eval->cache
2033
 *   if f(aux, t) returns true, add t to v
2034
 * - f must not have side effects
2035
 */
2036
void evaluator_collect_cached_terms(evaluator_t *eval, void *aux, model_filter_t f, ivector_t *v) {
2✔
2037
  int_hmap_t *cache;
2038
  int_hmap_pair_t *r;
2039

2040
  cache = &eval->cache;
2✔
2041
  r = int_hmap_first_record(cache);
2✔
2042
  while (r != NULL) {
6✔
2043
    if (f(aux, r->key)) {
4✔
2044
      ivector_push(v, r->key);
2✔
2045
    }
2046
    r = int_hmap_next_record(cache, r);
4✔
2047
  }
2048
}
2✔
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