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

SRI-CSL / yices2 / 12367760548

17 Dec 2024 06:41AM UTC coverage: 65.285% (-0.6%) from 65.92%
12367760548

push

github

web-flow
Fixes GitHub coverage issue (#544)

* Update action.yml

* Update action.yml

81020 of 124102 relevant lines covered (65.29%)

1509382.01 hits per line

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

80.68
/src/terms/term_manager.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
 * TERM MANAGER
21
 */
22

23
#include <stdint.h>
24
#include <assert.h>
25

26
#include "terms/bit_term_conversion.h"
27
#include "terms/bv64_constants.h"
28
#include "terms/bv_constants.h"
29
#include "terms/bvarith64_buffer_terms.h"
30
#include "terms/bvarith_buffer_terms.h"
31
#include "terms/rba_buffer_terms.h"
32
#include "terms/term_manager.h"
33
#include "terms/term_utils.h"
34
#include "utils/bit_tricks.h"
35
#include "utils/int_array_sort.h"
36
#include "utils/int_vectors.h"
37
#include "utils/memalloc.h"
38

39

40

41
/************************
42
 *  GENERAL OPERATIONS  *
43
 ***********************/
44

45
/*
46
 * Initialization:
47
 * - terms = attached term table
48
 */
49
void init_term_manager(term_manager_t *manager, term_table_t *terms) {
3,003✔
50
  manager->terms = terms;
3,003✔
51
  manager->types = terms->types;
3,003✔
52
  manager->pprods = terms->pprods;
3,003✔
53

54
  manager->arith_buffer = NULL;
3,003✔
55
  manager->bvarith_buffer = NULL;
3,003✔
56
  manager->bvarith64_buffer = NULL;
3,003✔
57
  //  manager->bvarith64_aux_buffer = NULL;
58
  manager->bvlogic_buffer = NULL;
3,003✔
59
  manager->pp_buffer = NULL;
3,003✔
60

61
  manager->bvarith_store = NULL;
3,003✔
62
  manager->bvarith64_store = NULL;
3,003✔
63
  manager->nodes = NULL;
3,003✔
64

65
  q_init(&manager->r0);
3,003✔
66
  init_bvconstant(&manager->bv0);
3,003✔
67
  init_bvconstant(&manager->bv1);
3,003✔
68
  init_bvconstant(&manager->bv2);
3,003✔
69
  init_ivector(&manager->vector0, 10);
3,003✔
70

71
  manager->simplify_ite = true;
3,003✔
72
  manager->simplify_bveq1 = true;
3,003✔
73
  manager->simplify_bvite_offset = false;
3,003✔
74
}
3,003✔
75

76

77
/*
78
 * Access to the internal stores:
79
 * - the store is allocated and initialized if needed
80
 */
81
node_table_t *term_manager_get_nodes(term_manager_t *manager) {
20,702✔
82
  node_table_t *tmp;
83

84
  tmp = manager->nodes;
20,702✔
85
  if (tmp == NULL) {
20,702✔
86
    tmp = (node_table_t *) safe_malloc(sizeof(node_table_t));
754✔
87
    init_node_table(tmp, 0);
754✔
88
    manager->nodes = tmp;
754✔
89
  }
90

91
  return tmp;
20,702✔
92
}
93

94
object_store_t *term_manager_get_bvarith_store(term_manager_t *manager) {
88✔
95
  object_store_t *tmp;
96

97
  tmp = manager->bvarith_store;
88✔
98
  if (tmp == NULL) {
88✔
99
    tmp = (object_store_t *) safe_malloc(sizeof(object_store_t));
84✔
100
    init_bvmlist_store(tmp);
84✔
101
    manager->bvarith_store = tmp;
84✔
102
  }
103

104
  return tmp;
88✔
105
}
106

107
object_store_t *term_manager_get_bvarith64_store(term_manager_t *manager) {
2,870✔
108
  object_store_t *tmp;
109

110
  tmp = manager->bvarith64_store;
2,870✔
111
  if (tmp == NULL) {
2,870✔
112
    tmp = (object_store_t *) safe_malloc(sizeof(object_store_t));
545✔
113
    init_bvmlist64_store(tmp);
545✔
114
    manager->bvarith64_store = tmp;
545✔
115
  }
116

117
  return tmp;
2,870✔
118
}
119

120

121
/*
122
 * Access to the internal buffers:
123
 * - they are allocated and initialized if needed (and the store they need too)
124
 */
125
rba_buffer_t *term_manager_get_arith_buffer(term_manager_t *manager) {
86,498✔
126
  rba_buffer_t *tmp;
127

128
  tmp = manager->arith_buffer;
86,498✔
129
  if (tmp == NULL) {
86,498✔
130
    tmp = (rba_buffer_t *) safe_malloc(sizeof(rba_buffer_t));
857✔
131
    init_rba_buffer(tmp, manager->pprods);
857✔
132
    manager->arith_buffer = tmp;
857✔
133
  }
134

135
  return tmp;
86,498✔
136
}
137

138
bvarith_buffer_t *term_manager_get_bvarith_buffer(term_manager_t *manager) {
240✔
139
  bvarith_buffer_t *tmp;
140
  object_store_t *mstore;
141

142
  tmp = manager->bvarith_buffer;
240✔
143
  if (tmp == NULL) {
240✔
144
    mstore = term_manager_get_bvarith_store(manager);
14✔
145
    tmp = (bvarith_buffer_t *) safe_malloc(sizeof(bvarith_buffer_t));
14✔
146
    init_bvarith_buffer(tmp, manager->pprods, mstore);
14✔
147
    manager->bvarith_buffer = tmp;
14✔
148
  }
149

150
  return tmp;
240✔
151
}
152

153
bvarith64_buffer_t *term_manager_get_bvarith64_buffer(term_manager_t *manager) {
327,702✔
154
  bvarith64_buffer_t *tmp;
155
  object_store_t *mstore;
156

157
  tmp = manager->bvarith64_buffer;
327,702✔
158
  if (tmp == NULL) {
327,702✔
159
    mstore = term_manager_get_bvarith64_store(manager);
203✔
160
    tmp = (bvarith64_buffer_t *) safe_malloc(sizeof(bvarith64_buffer_t));
203✔
161
    init_bvarith64_buffer(tmp, manager->pprods, mstore);
203✔
162
    manager->bvarith64_buffer = tmp;
203✔
163
  }
164

165
  return tmp;
327,702✔
166
}
167

168
bvlogic_buffer_t *term_manager_get_bvlogic_buffer(term_manager_t *manager) {
294,366✔
169
  bvlogic_buffer_t *tmp;
170
  node_table_t *nodes;
171

172
  tmp = manager->bvlogic_buffer;
294,366✔
173
  if (tmp == NULL) {
294,366✔
174
    nodes = term_manager_get_nodes(manager);
265✔
175
    tmp = (bvlogic_buffer_t *) safe_malloc(sizeof(bvlogic_buffer_t));
265✔
176
    init_bvlogic_buffer(tmp, nodes);
265✔
177
    manager->bvlogic_buffer = tmp;
265✔
178
  }
179

180
  return tmp;
294,366✔
181
}
182

183
pp_buffer_t *term_manager_get_pp_buffer(term_manager_t *manager) {
16✔
184
  pp_buffer_t *tmp;
185

186
  tmp = manager->pp_buffer;
16✔
187
  if (tmp == NULL) {
16✔
188
    tmp = (pp_buffer_t *) safe_malloc(sizeof(pp_buffer_t));
8✔
189
    init_pp_buffer(tmp, 8);
8✔
190
    manager->pp_buffer = tmp;
8✔
191
  }
192

193
  return tmp;
16✔
194
}
195

196

197
#if 0
198
/*
199
 * Auxiliary buffer: reserved for internal use
200
 */
201
static bvarith64_buffer_t *term_manager_get_bvarith64_aux_buffer(term_manager_t *manager) {
202
  bvarith64_buffer_t *tmp;
203
  object_store_t *mstore;
204

205
  tmp = manager->bvarith64_aux_buffer;
206
  if (tmp == NULL) {
207
    mstore = term_manager_get_bvarith64_store(manager);
208
    tmp = (bvarith64_buffer_t *) safe_malloc(sizeof(bvarith64_buffer_t));
209
    init_bvarith64_buffer(tmp, manager->pprods, mstore);
210
    manager->bvarith64_aux_buffer = tmp;
211
  }
212

213
  return tmp;
214
}
215
#endif
216

217
/*
218
 * Delete all: free memory
219
 */
220
static void term_manager_free_nodes(term_manager_t *manager) {
3,003✔
221
  node_table_t *tmp;
222

223
  tmp = manager->nodes;
3,003✔
224
  if (tmp != NULL) {
3,003✔
225
    delete_node_table(tmp);
754✔
226
    safe_free(tmp);
754✔
227
    manager->nodes = NULL;
754✔
228
  }
229
}
3,003✔
230

231
static void term_manager_free_bvarith_store(term_manager_t *manager) {
3,003✔
232
  object_store_t *tmp;
233

234
  tmp = manager->bvarith_store;
3,003✔
235
  if (tmp != NULL) {
3,003✔
236
    delete_bvmlist_store(tmp);
84✔
237
    safe_free(tmp);
84✔
238
    manager->bvarith_store = NULL;
84✔
239
  }
240
}
3,003✔
241

242
static void term_manager_free_bvarith64_store(term_manager_t *manager) {
3,003✔
243
  object_store_t *tmp;
244

245
  tmp = manager->bvarith64_store;
3,003✔
246
  if (tmp != NULL) {
3,003✔
247
    delete_bvmlist64_store(tmp);
545✔
248
    safe_free(tmp);
545✔
249
    manager->bvarith64_store = NULL;
545✔
250
  }
251
}
3,003✔
252

253
static void term_manager_free_arith_buffer(term_manager_t *manager) {
3,003✔
254
  rba_buffer_t *tmp;
255

256
  tmp = manager->arith_buffer;
3,003✔
257
  if (tmp != NULL) {
3,003✔
258
    delete_rba_buffer(tmp);
857✔
259
    safe_free(tmp);
857✔
260
    manager->arith_buffer = NULL;
857✔
261
  }
262
}
3,003✔
263

264
static void term_manager_free_bvarith_buffer(term_manager_t *manager) {
3,003✔
265
  bvarith_buffer_t *tmp;
266

267
  tmp = manager->bvarith_buffer;
3,003✔
268
  if (tmp != NULL) {
3,003✔
269
    delete_bvarith_buffer(tmp);
14✔
270
    safe_free(tmp);
14✔
271
    manager->bvarith_buffer = NULL;
14✔
272
  }
273
}
3,003✔
274

275
static void term_manager_free_bvarith64_buffer(term_manager_t *manager) {
3,003✔
276
  bvarith64_buffer_t *tmp;
277

278
  tmp = manager->bvarith64_buffer;
3,003✔
279
  if (tmp != NULL) {
3,003✔
280
    delete_bvarith64_buffer(tmp);
203✔
281
    safe_free(tmp);
203✔
282
    manager->bvarith64_buffer = NULL;
203✔
283
  }
284
}
3,003✔
285

286
static void term_manager_free_bvlogic_buffer(term_manager_t *manager) {
3,003✔
287
  bvlogic_buffer_t *tmp;
288

289
  tmp = manager->bvlogic_buffer;
3,003✔
290
  if (tmp != NULL) {
3,003✔
291
    delete_bvlogic_buffer(tmp);
265✔
292
    safe_free(tmp);
265✔
293
    manager->bvlogic_buffer = NULL;
265✔
294
  }
295
}
3,003✔
296

297
static void term_manager_free_pp_buffer(term_manager_t *manager) {
3,003✔
298
  pp_buffer_t *tmp;
299

300
  tmp = manager->pp_buffer;
3,003✔
301
  if (tmp != NULL) {
3,003✔
302
    delete_pp_buffer(tmp);
8✔
303
    safe_free(tmp);
8✔
304
    manager->pp_buffer = NULL;
8✔
305
  }
306
}
3,003✔
307

308
#if 0
309
static void term_manager_free_bvarith64_aux_buffer(term_manager_t *manager) {
310
  bvarith64_buffer_t *tmp;
311

312
  tmp = manager->bvarith64_aux_buffer;
313
  if (tmp != NULL) {
314
    delete_bvarith64_buffer(tmp);
315
    safe_free(tmp);
316
    manager->bvarith64_aux_buffer = NULL;
317
  }
318
}
319
#endif
320

321
void delete_term_manager(term_manager_t *manager) {
3,003✔
322
  term_manager_free_arith_buffer(manager);
3,003✔
323
  term_manager_free_bvarith_buffer(manager);
3,003✔
324
  term_manager_free_bvarith64_buffer(manager);
3,003✔
325
  //  term_manager_free_bvarith64_aux_buffer(manager); NEVER USED
326
  term_manager_free_bvlogic_buffer(manager);
3,003✔
327
  term_manager_free_pp_buffer(manager);
3,003✔
328

329
  term_manager_free_bvarith_store(manager);
3,003✔
330
  term_manager_free_bvarith64_store(manager);
3,003✔
331
  term_manager_free_nodes(manager);
3,003✔
332

333
  q_clear(&manager->r0);
3,003✔
334
  delete_bvconstant(&manager->bv0);
3,003✔
335
  delete_bvconstant(&manager->bv1);
3,003✔
336
  delete_bvconstant(&manager->bv2);
3,003✔
337
  delete_ivector(&manager->vector0);
3,003✔
338
}
3,003✔
339

340

341

342
/*
343
 * Reset internal buffers and stores
344
 */
345
void reset_term_manager(term_manager_t *manager) {
24✔
346
  if (manager->arith_buffer != NULL) {
24✔
347
    reset_rba_buffer(manager->arith_buffer);
×
348
  }
349
  if (manager->bvarith_buffer != NULL) {
24✔
350
    reset_bvarith_buffer(manager->bvarith_buffer);
×
351
  }
352
  if (manager->bvarith64_buffer != NULL) {
24✔
353
    reset_bvarith64_buffer(manager->bvarith64_buffer);
×
354
  }
355
  //  if (manager->bvarith64_aux_buffer != NULL) {
356
  //    reset_bvarith64_buffer(manager->bvarith64_aux_buffer);
357
  //  }
358
  if (manager->bvlogic_buffer != NULL) {
24✔
359
    bvlogic_buffer_clear(manager->bvlogic_buffer);
×
360
  }
361
  if (manager->bvarith_store != NULL) {
24✔
362
    reset_objstore(manager->bvarith_store);
×
363
  }
364
  if (manager->bvarith64_store != NULL) {
24✔
365
    reset_objstore(manager->bvarith64_store);
24✔
366
  }
367
  if (manager->nodes != NULL) {
24✔
368
    reset_node_table(manager->nodes);
21✔
369
  }
370

371
  q_clear(&manager->r0);
24✔
372
  ivector_reset(&manager->vector0);
24✔
373
}
24✔
374

375

376

377

378
/************************************************
379
 *  CONVERSION OF ARRAYS OF BOOLEANS TO TERMS   *
380
 ***********************************************/
381

382
/*
383
 * Check whether all elements of a are boolean constants
384
 * - n = size of the array
385
 */
386
static bool bvarray_is_constant(const term_t *a, uint32_t n) {
18,125✔
387
  uint32_t i;
388

389
  for (i=0; i<n; i++) {
18,526✔
390
    if (index_of(a[i]) != bool_const) return false;
18,517✔
391
    assert(a[i] == true_term || a[i] == false_term);
392
  }
393

394
  return true;
9✔
395
}
396

397

398
/*
399
 * Convert a to a 64bit value (padded with 0)
400
 */
401
static uint64_t bvarray_get_constant64(const term_t *a, uint32_t n) {
8✔
402
  uint64_t c;
403

404
  assert(n <= 64);
405
  c = 0;
8✔
406
  while (n > 0) {
25✔
407
    n --;
17✔
408
    assert(a[n] == true_term || a[n] == false_term);
409
    c = (c << 1) | (uint64_t) (1 ^ polarity_of(a[n]));
17✔
410
  }
411

412
  return c;
8✔
413
}
414

415

416
/*
417
 * Copy constant array into c
418
 */
419
static void bvarray_get_constant(const term_t *a, uint32_t n, bvconstant_t *c) {
1✔
420
  uint32_t i, k;
421

422
  assert(n > 64);
423
  k = (n + 31) >> 5;
1✔
424
  bvconstant_set_bitsize(c, n);
1✔
425

426
  bvconst_clear(c->data, k);
1✔
427
  for (i=0; i<n; i++) {
93✔
428
    assert(a[i] == true_term || a[i] == false_term);
429
    if (a[i] == true_term) {
92✔
430
      bvconst_set_bit(c->data, i);
×
431
    }
432
  }
433
}
1✔
434

435

436
/*
437
 * Check whether term b is (bit i x)
438
 */
439
static bool term_is_bit_i(term_table_t *tbl, term_t b, uint32_t i, term_t x) {
2✔
440
  select_term_t *s;
441

442
  if (is_pos_term(b) && term_kind(tbl, b) == BIT_TERM) {
2✔
443
    s = bit_term_desc(tbl, b);
×
444
    return s->idx == i && s->arg == x;
×
445
  }
446

447
  return false;
2✔
448
}
449

450

451
/*
452
 * Check whether b is (bit 0 x) for some x
453
 * if so return x, otherwise return NULL_TERM
454
 */
455
static term_t term_is_bit0(term_table_t *tbl, term_t b) {
18,116✔
456
  select_term_t *s;
457

458
  if (is_pos_term(b) && term_kind(tbl, b) == BIT_TERM) {
18,116✔
459
    s = bit_term_desc(tbl, b);
47✔
460
    if (s->idx == 0) {
47✔
461
      return s->arg;
22✔
462
    }
463
  }
464

465
  return NULL_TERM;
18,094✔
466
}
467

468
/*
469
 * Convert abstraction sign to a term
470
 * - return NULL_TERM is sign is undef
471
 */
472
static term_t abs64sign_to_term(int32_t sign) {
14✔
473
  term_t t;
474

475
  t = NULL_TERM;
14✔
476
  if (sign == sign_zero) {
14✔
477
    t = false_term;
×
478
  } else if (sign == sign_one) {
14✔
479
    t = true_term;
×
480
  } else if (sign != sign_undef) {
14✔
481
    // sign is a Boolean term
482
    t = sign;
×
483
  }
484

485
  return t;
14✔
486
}
487

488
/*
489
 * Check whether a is equal to an existing term x
490
 * - if so return x
491
 * - otherwise return NULL_TERM
492
 *
493
 * This checks whether a[0] ... a[n-1] are of the form
494
 *   (bit 0 x) (bit 1 x) ... (bit n-1 x),
495
 * where x is a term of n bits.
496
 */
497
static term_t bvarray_get_var(term_table_t *tbl, const term_t *a, uint32_t n) {
18,116✔
498
  bv64_abs_t abs;
499
  term_t x, s;
500
  uint32_t i, m;
501

502
  assert(n > 0);
503

504
  x = term_is_bit0(tbl, a[0]);
18,116✔
505
  if (x == NULL_TERM || term_bitsize(tbl, x) != n) {
18,116✔
506
    return NULL_TERM;
18,100✔
507
  }
508

509
  if (n <= 64) {
16✔
510
    // use abstraction to learn sign + number of significant bits
511
    bv64_abstract_term(tbl, x, &abs);
15✔
512
    assert(0 < abs.nbits && abs.nbits <= n);
513
    m = abs.nbits - 1;
15✔
514
    for (i=1; i<m; i++) {
15✔
515
      if (! term_is_bit_i(tbl, a[i], i, x)) {
1✔
516
        return NULL_TERM;
1✔
517
      }
518
    }
519

520
    // check whether the a[i+1, .., n-1] contain the sign bit of x
521
    s = abs64sign_to_term(abs.sign);
14✔
522
    if (s != NULL_TERM) {
14✔
523
      // the sign bit is s
524
      while (i<n) {
×
525
        if (a[i] != s) {
×
526
          return NULL_TERM;
×
527
        }
528
        i ++;
×
529
      }
530
    } else {
531
      // the sign bit is (select x m)
532
      while (i<n) {
14✔
533
        if (! term_is_bit_i(tbl, a[i], m, x)) {
×
534
          return NULL_TERM;
×
535
        }
536
        i ++;
×
537
      }
538
    }
539
  } else {
540
    // Interval abstraction not implemented for n>64
541
    for (i=1; i<n; i++) {
1✔
542
      if (! term_is_bit_i(tbl, a[i], i, x)) {
1✔
543
        return NULL_TERM;
1✔
544
      }
545
    }
546
  }
547

548

549
  return x;
14✔
550
}
551

552
/*
553
 * Convert array a to a term
554
 * - side effect: use bv0
555
< */
556
static term_t bvarray_get_term(term_manager_t *manager, const term_t *a, uint32_t n) {
18,125✔
557
  term_table_t *terms;
558
  bvconstant_t *bv;
559
  term_t t;
560

561
  assert(n > 0);
562

563
  terms = manager->terms;
18,125✔
564

565
  if (bvarray_is_constant(a, n)) {
18,125✔
566
    if (n <= 64) {
9✔
567
      t = bv64_constant(terms, n, bvarray_get_constant64(a, n));
8✔
568
    } else {
569
      bv = &manager->bv0;
1✔
570
      bvarray_get_constant(a, n, bv);
1✔
571
      assert(bv->bitsize == n);
572
      t = bvconst_term(terms, n, bv->data);
1✔
573
    }
574
  } else {
575
    // try to convert to an existing t
576
    t = bvarray_get_var(terms, a, n);
18,116✔
577
    if (t == NULL_TERM) {
18,116✔
578
      t = bvarray_term(terms, n, a);
18,102✔
579
    }
580
  }
581

582
  return t;
18,125✔
583
}
584

585

586

587
/*
588
 * BITVECTORS OF SIZE 1
589
 */
590

591
/*
592
 * Check whether x is equivalent to (bveq a 0b0) or (bveq a 0b1) where a is a term
593
 * of type (bitvector 1).
594
 * - if x is (bveq a 0b0): return a and set polarity to false
595
 * - if x is (bveq a 0b1): return a and set polarity to true
596
 * - if x is (not (bveq a 0b0)): return a and set polarity to true
597
 * - if x is (not (bveq a 0b1)): return a and set polarity to false
598
 * - otherwise, return NULL_TERM (leave polarity unchanged)
599
 */
600
static term_t term_is_bveq1(term_table_t *tbl, term_t x, bool *polarity) {
291,516✔
601
  composite_term_t *eq;
602
  bvconst64_term_t *c;
603
  term_t a, b;
604

605
  if (term_kind(tbl, x) == BV_EQ_ATOM) {
291,516✔
606
    eq = bveq_atom_desc(tbl, x);
11,173✔
607
    a = eq->arg[0];
11,173✔
608
    b = eq->arg[1];
11,173✔
609
    if (term_bitsize(tbl, a) == 1) {
11,173✔
610
      assert(term_bitsize(tbl, b) == 1);
611
      if (term_kind(tbl, a) == BV64_CONSTANT) {
4,414✔
612
        // a is either 0b0 or 0b1
613
        c = bvconst64_term_desc(tbl, a);
6✔
614
        assert(c->value == 0 || c->value == 1);
615
        *polarity = ((bool) c->value) ^ is_neg_term(x);
6✔
616
        return b;
6✔
617
      }
618

619
      if (term_kind(tbl, b) == BV64_CONSTANT) {
4,408✔
620
        // b is either 0b0 or 0b1
621
        c = bvconst64_term_desc(tbl, b);
4,369✔
622
        assert(c->value == 0 || c->value == 1);
623
        *polarity = ((bool) c->value) ^ is_neg_term(x);
4,369✔
624
        return a;
4,369✔
625
      }
626
    }
627
  }
628

629
  return NULL_TERM;
287,141✔
630
}
631

632

633
/*
634
 * Rewrite (bveq [p] [q]) to (eq p q)
635
 * - t1 and t2 are both bv-arrays of one bit
636
 * - this is called after checking for simplification (so
637
 *   we known that (p == q) does not simplify to a single term).
638
 */
639
static term_t mk_bveq_arrays1(term_manager_t *manager, term_t t1, term_t t2) {
372✔
640
  composite_term_t *a;
641
  composite_term_t *b;
642

643
  a = bvarray_term_desc(manager->terms, t1);
372✔
644
  b = bvarray_term_desc(manager->terms, t2);
372✔
645

646
  assert(a->arity == 1 && b->arity == 1);
647
  return mk_iff(manager, a->arg[0], b->arg[0]);
372✔
648
}
649

650

651
/*
652
 * Auxiliary function: build (bveq t1 t2)
653
 * - try to simplify to true or false
654
 * - attempt to simplify the equality if it's between bit-arrays or bit-arrays and constant
655
 * - build an atom if no simplification works
656
 */
657
static term_t mk_bitvector_eq(term_manager_t *manager, term_t t1, term_t t2) {
413,339✔
658
  term_table_t *tbl;
659
  term_t aux;
660

661
  tbl = manager->terms;
413,339✔
662

663
  if (t1 == t2) return true_term;
413,339✔
664
  if (disequal_bitvector_terms(tbl, t1, t2)) {
309,306✔
665
    return false_term;
95,649✔
666
  }
667

668
  /*
669
   * Try simplifications.  We know that t1 and t2 are not both constant
670
   * (because disequal_bitvector_terms returned false).
671
   */
672
  if (manager->simplify_bveq1) {
213,657✔
673
    aux = simplify_bveq(tbl, t1, t2);
162,655✔
674
    if (aux != NULL_TERM) {
162,655✔
675
      // Simplification worked
676
      return aux;
7,458✔
677
    }
678
  }
679
  /*
680
   * Special case: for bit-vector of size 1
681
   * - convert to boolean equality
682
   */
683
  if (manager->simplify_bveq1 && term_bitsize(tbl, t1) == 1 &&
240,622✔
684
      term_kind(tbl, t1) == BV_ARRAY && term_kind(tbl, t2) == BV_ARRAY) {
35,237✔
685
    assert(term_bitsize(tbl, t2) == 1);
686
    return mk_bveq_arrays1(manager, t1, t2);
372✔
687
  }
688

689
  /*
690
   * Default: normalize then build a bveq_atom
691
   */
692
  if (t1 > t2) {
205,827✔
693
    aux = t1; t1 = t2; t2 = aux;
59,208✔
694
  }
695

696
  return bveq_atom(tbl, t1, t2);
205,827✔
697
}
698

699

700

701
/*
702
 * Special constructor for (iff x y) when x or y (or both)
703
 * are equivalent to (bveq a 0b0) or (bveq a 0b1).
704
 *
705
 * Try the following rewrite rules:
706
 *   iff (bveq a 0b0) (bveq b 0b0) ---> (bveq a b)
707
 *   iff (bveq a 0b0) (bveq b 0b1) ---> (not (bveq a b))
708
 *   iff (bveq a 0b1) (bveq b 0b0) ---> (not (bveq a b))
709
 *   iff (bveq a 0b1) (bveq b 0b1) ---> (bveq a b)
710
 *
711
 *   iff (bveq a 0b0) y   ---> (not (bveq a (bvarray y)))
712
 *   iff (bveq a 0b1) y   ---> (bveq a (bvarray y))
713
 *
714
 * return NULL_TERM if none of these rules can be applied
715
 */
716
static term_t try_iff_bveq_simplification(term_manager_t *manager, term_t x, term_t y) {
145,758✔
717
  term_table_t *tbl;
718
  term_t a, b, t;
719
  bool pa, pb;
720

721
  pa = false;
145,758✔
722
  pb = false; // to prevent GCC warning
145,758✔
723

724
  tbl = manager->terms;
145,758✔
725

726
  a = term_is_bveq1(tbl, x, &pa);
145,758✔
727
  b = term_is_bveq1(tbl, y, &pb);
145,758✔
728
  if (a != NULL_TERM || b != NULL_TERM) {
145,758✔
729
    if (a != NULL_TERM && b != NULL_TERM) {
4,363✔
730
      /*
731
       * x is (bveq a <constant>)
732
       * y is (bveq b <constant>)
733
       */
734
      t = mk_bitvector_eq(manager, a, b);
12✔
735
      t = signed_term(t, (pa == pb));
12✔
736
      return t;
12✔
737
    }
738

739
    if (a != NULL_TERM) {
4,351✔
740
      /*
741
       * x is (bveq a <constant>):
742
       * if pa is true:
743
       *   (iff (bveq a 0b1) y) --> (bveq a (bvarray y))
744
       * if pa is false:
745
       *   (iff (bveq a 0b0) y) --> (not (bveq a (bvarray y)))
746
       *
747
       * TODO? We could rewrite to (bveq a (bvarray ~y))??
748
       */
749
      t = bvarray_get_term(manager, &y, 1);
4,327✔
750
      t = mk_bitvector_eq(manager, a, t);
4,327✔
751
      t = signed_term(t, pa);
4,327✔
752
      return t;
4,327✔
753
    }
754

755
    if (b != NULL_TERM) {
24✔
756
      /*
757
       * y is (bveq b <constant>)
758
       */
759
      t = bvarray_get_term(manager, &x, 1);
24✔
760
      t = mk_bitvector_eq(manager, b, t);
24✔
761
      t = signed_term(t, pb);
24✔
762
      return t;
24✔
763
    }
764
  }
765

766
  return NULL_TERM;
141,395✔
767
}
768

769

770

771

772
/**********************
773
 *  ARITHMETIC TERMS  *
774
 *********************/
775

776
// TODO make some rewriting functions finite field compatible
777

778
/*
779
 * Arithmetic constant (rational)
780
 * - r must be normalized
781
 */
782
term_t mk_arith_constant(term_manager_t *manager, rational_t *r) {
691✔
783
  return arith_constant(manager->terms, r);
691✔
784
}
785

786

787
/*
788
 * Convert b to an arithmetic term:
789
 * - b->ptbl must be equal to manager->pprods
790
 * - b may be the same as manager->arith_buffer
791
 * - side effect: b is reset
792
 *
793
 * Simplifications (after normalization)
794
 * - if b is a constant then a constant rational is created
795
 * - if b is of the form 1. t then t is returned
796
 * - if b is of the from 1. t_1^d_1 ... t_n^d_n then a power product is returned
797
 * - otherwise a polynomial term is created
798
 */
799
static term_t arith_buffer_to_term(term_table_t *tbl, rba_buffer_t *b) {
27,427✔
800
  mono_t *m;
801
  pprod_t *r;
802
  uint32_t n;
803
  term_t t;
804

805
  assert(b->ptbl == tbl->pprods);
806

807
  n = b->nterms;
27,427✔
808
  if (n == 0) {
27,427✔
809
    t = zero_term;
928✔
810
  } else if (n == 1) {
26,499✔
811
    m = rba_buffer_root_mono(b); // unique monomial of b
10,637✔
812
    r = m->prod;
10,637✔
813
    if (r == empty_pp) {
10,637✔
814
      // constant polynomial
815
      t = arith_constant(tbl, &m->coeff);
2,107✔
816
    } else if (q_is_one(&m->coeff)) {
8,530✔
817
      // term or power product
818
      t =  pp_is_var(r) ? var_of_pp(r) : pprod_term(tbl, r);
2,842✔
819
    } else {
820
      // can't simplify
821
      t = arith_poly(tbl, b);
5,688✔
822
    }
823
  } else {
824
    t = arith_poly(tbl, b);
15,862✔
825
  }
826

827
  reset_rba_buffer(b);
27,427✔
828

829
  return t;
27,427✔
830
}
831

832
/*
833
 * Arithmetic constant (finite field)
834
 * - r must be normalized wrt. mod
835
 */
836
term_t mk_arith_ff_constant(term_manager_t *manager, rational_t *r, rational_t *mod) {
×
837
  return arith_ff_constant(manager->terms, r, mod);
×
838
}
839

840
static term_t arith_ff_buffer_to_term(term_table_t *tbl, rba_buffer_t *b, const rational_t *mod) {
1,717✔
841
  mono_t *m;
842
  pprod_t *r;
843
  uint32_t n;
844
  term_t t;
845

846
  assert(b->ptbl == tbl->pprods);
847

848
  rba_buffer_mod_const(b, mod);
1,717✔
849

850
  n = b->nterms;
1,717✔
851
  if (n == 0) {
1,717✔
852
    rational_t zero;
853
    q_init(&zero);
27✔
854
    // generate/get a zero term mod mod
855
    t = arith_ff_constant(tbl, &zero, mod);
27✔
856
    q_clear(&zero);
27✔
857
  } else if (n == 1) {
1,690✔
858
    m = rba_buffer_root_mono(b); // unique monomial of b
733✔
859
    r = m->prod;
733✔
860
    if (r == empty_pp) {
733✔
861
      // constant polynomial
862
      t = arith_ff_constant(tbl, &m->coeff, mod);
3✔
863
    } else if (q_is_one(&m->coeff)) {
730✔
864
      // term or power product
865
      t = pp_is_var(r) ? var_of_pp(r) : pprod_term(tbl, r);
413✔
866
    } else {
867
      // can't simplify
868
      t = arith_ff_poly(tbl, b, mod);
317✔
869
    }
870
  } else {
871
    t = arith_ff_poly(tbl, b, mod);
957✔
872
  }
873

874
  reset_rba_buffer(b);
1,717✔
875

876
  // check that mod is type t's ff-size
877
  assert(q_eq(mod, ff_type_size(tbl->types, term_type(tbl, t))));
878

879
  return t;
1,717✔
880
}
881

882

883

884
term_t mk_arith_term(term_manager_t *manager, rba_buffer_t *b) {
19,996✔
885
  return arith_buffer_to_term(manager->terms, b);
19,996✔
886
}
887

888
term_t mk_direct_arith_term(term_table_t *tbl, rba_buffer_t *b) {
5,127✔
889
  return arith_buffer_to_term(tbl, b);
5,127✔
890
}
891

892
term_t mk_arith_ff_term(term_manager_t *manager, rba_buffer_t *b, const rational_t *mod) {
456✔
893
  return arith_ff_buffer_to_term(manager->terms, b, mod);
456✔
894
}
895

896
term_t mk_direct_arith_ff_term(term_table_t *tbl, rba_buffer_t *b, const rational_t *mod) {
1,261✔
897
  return arith_ff_buffer_to_term(tbl, b, mod);
1,261✔
898
}
899

900

901

902
/*********************************
903
 *   BOOLEAN-TERM CONSTRUCTORS   *
904
 ********************************/
905

906
/*
907
 * Simplifications:
908
 *   x or x       --> x
909
 *   x or true    --> true
910
 *   x or false   --> x
911
 *   x or (not x) --> true
912
 *
913
 * Normalization: put smaller index first
914
 */
915
term_t mk_binary_or(term_manager_t *manager, term_t x, term_t y) {
187,856✔
916
  term_t aux[2];
917

918
  if (x == y) return x;
187,856✔
919
  if (x == true_term) return x;
178,511✔
920
  if (y == true_term) return y;
177,421✔
921
  if (x == false_term) return y;
175,965✔
922
  if (y == false_term) return x;
159,133✔
923
  if (opposite_bool_terms(x, y)) return true_term;
157,370✔
924

925
  if (x < y) {
157,035✔
926
    aux[0] = x; aux[1] = y;
119,446✔
927
  } else {
928
    aux[0] = y; aux[1] = x;
37,589✔
929
  }
930

931
  return or_term(manager->terms, 2, aux);
157,035✔
932
}
933

934

935
/*
936
 * Rewrite (and x y)  to  (not (or (not x) (not y)))
937
 */
938
term_t mk_binary_and(term_manager_t *manager, term_t x, term_t y) {
45,914✔
939
  return opposite_term(mk_binary_or(manager, opposite_term(x), opposite_term(y)));
45,914✔
940
}
941

942

943
/*
944
 * Rewrite (implies x y) to (or (not x) y)
945
 */
946
term_t mk_implies(term_manager_t *manager, term_t x, term_t y) {
55,714✔
947
  return mk_binary_or(manager, opposite_term(x), y);
55,714✔
948
}
949

950

951
/*
952
 * Check whether x is uninterpreted or the negation of an uninterpreted boolean term
953
 */
954
static inline bool is_literal(term_manager_t *manager, term_t x) {
7,558✔
955
  return kind_for_idx(manager->terms, index_of(x)) == UNINTERPRETED_TERM;
7,558✔
956
}
957

958

959
/*
960
 * Simplifications:
961
 *    iff x x       --> true
962
 *    iff x true    --> x
963
 *    iff x false   --> not x
964
 *    iff x (not x) --> false
965
 *
966
 *    iff (not x) (not y) --> eq x y
967
 *
968
 * Optional simplification:
969
 *    iff (not x) y       --> not (eq x y)  (NOT USED ANYMORE)
970
 *
971
 * Smaller index is on the left-hand-side of eq
972
 */
973
term_t mk_iff(term_manager_t *manager, term_t x, term_t y) {
225,262✔
974
  term_t aux;
975

976
  if (x == y) return true_term;
225,262✔
977
  if (x == true_term) return y;
223,852✔
978
  if (y == true_term) return x;
211,535✔
979
  if (x == false_term) return opposite_term(y);
187,628✔
980
  if (y == false_term) return opposite_term(x);
173,552✔
981
  if (opposite_bool_terms(x, y)) return false_term;
145,771✔
982

983
  /*
984
   * Try iff/bveq simplifications.
985
   */
986
  aux = try_iff_bveq_simplification(manager, x, y);
145,758✔
987
  if (aux != NULL_TERM) {
145,758✔
988
    return aux;
4,363✔
989
  }
990

991
  /*
992
   * swap if x > y
993
   */
994
  if (x > y) {
141,395✔
995
    aux = x; x = y; y = aux;
14,531✔
996
  }
997

998
  /*
999
   * - rewrite (iff (not x) (not y)) to (eq x y)
1000
   * - rewrite (iff (not x) y)       to (eq x (not y))
1001
   *   unless y is uninterpreted and x is not
1002
   */
1003
  if (is_neg_term(x) &&
147,624✔
1004
      (is_neg_term(y) || is_literal(manager, x) || !is_literal(manager, y))) {
10,260✔
1005
    x = opposite_term(x);
6,209✔
1006
    y = opposite_term(y);
6,209✔
1007
  }
1008

1009
  return eq_term(manager->terms, x, y);
141,395✔
1010
}
1011

1012

1013
/*
1014
 * Rewrite (xor x y) to (not (iff x  y))
1015
 *
1016
 * NOTE: used to be (xor x y) to (iff (not x) y)
1017
 */
1018
term_t mk_binary_xor(term_manager_t *manager, term_t x, term_t y) {
20,035✔
1019
  return opposite_term(mk_iff(manager, x, y));
20,035✔
1020
}
1021

1022

1023

1024

1025
/*
1026
 * N-ARY OR/AND
1027
 */
1028

1029
/*
1030
 * Construct (or a[0] ... a[n-1])
1031
 * - all terms are assumed valid and boolean
1032
 * - array a is modified (sorted)
1033
 * - n must be positive
1034
 */
1035
term_t mk_or(term_manager_t *manager, uint32_t n, term_t *a) {
363,948✔
1036
  uint32_t i, j;
1037
  term_t x, y;
1038

1039
  /*
1040
   * Sorting the terms ensure:
1041
   * - true_term shows up first if it's present in a
1042
   *   then false_term if it's present
1043
   *   then all the other boolean terms.
1044
   * - if x and (not x) are both in a, then they occur
1045
   *   at successive positions in a after sorting.
1046
   */
1047
  assert(n > 0);
1048
  int_array_sort(a, n);
363,948✔
1049

1050
  x = a[0];
363,948✔
1051
  if (x == true_term) {
363,948✔
1052
    return true_term;
1,330✔
1053
  }
1054

1055
  j = 0;
362,618✔
1056
  if (x != false_term) {
362,618✔
1057
    //    a[j] = x; NOT NECESSARY
1058
    j ++;
330,521✔
1059
  }
1060

1061
  // remove duplicates and check for x/not x in succession
1062
  for (i=1; i<n; i++) {
1,487,964✔
1063
    y = a[i];
1,125,891✔
1064
    if (x != y) {
1,125,891✔
1065
      if (y == opposite_term(x)) {
1,107,366✔
1066
        return true_term;
545✔
1067
      }
1068
      assert(y != false_term && y != true_term);
1069
      x = y;
1,106,821✔
1070
      a[j] = x;
1,106,821✔
1071
      j ++;
1,106,821✔
1072
    }
1073
  }
1074

1075
  if (j <= 1) {
362,073✔
1076
    // if j = 0, then x = false_term and all elements of a are false
1077
    // if j = 1, then x is the unique non-false term in a
1078
    return x;
25,228✔
1079
  } else {
1080
    return or_term(manager->terms, j, a);
336,845✔
1081
  }
1082
}
1083

1084

1085
/*
1086
 * Construct (and a[0] ... a[n-1])
1087
 * - n must be positive
1088
 * - a is modified
1089
 */
1090
term_t mk_and(term_manager_t *manager, uint32_t n, term_t *a) {
36,442✔
1091
  uint32_t i;
1092

1093
  for (i=0; i<n; i++) {
434,843✔
1094
    a[i] = opposite_term(a[i]);
398,401✔
1095
  }
1096

1097
  return opposite_term(mk_or(manager, n, a));
36,442✔
1098
}
1099

1100

1101

1102

1103

1104
/*
1105
 * N-ARY XOR
1106
 */
1107

1108
/*
1109
 * Construct (xor a[0] ... a[n-1])
1110
 * - n must be positive
1111
 * - all terms in a must be valid and boolean
1112
 * - a is modified
1113
 */
1114
term_t mk_xor(term_manager_t *manager, uint32_t n, term_t *a) {
146✔
1115
  uint32_t i, j;
1116
  term_t x, y;
1117
  bool negate;
1118

1119

1120
  /*
1121
   * First pass: remove true_term/false_term and
1122
   * replace negative terms by their opposite
1123
   */
1124
  negate = false;
146✔
1125
  j = 0;
146✔
1126
  for (i=0; i<n; i++) {
902✔
1127
    x = a[i];
756✔
1128
    if (index_of(x) == bool_const) {
756✔
1129
      assert(x == true_term || x == false_term);
1130
      negate ^= is_pos_term(x); // flip sign if x is true
172✔
1131
    } else {
1132
      assert(x != true_term && x != false_term);
1133
      // apply rule (xor ... (not x) ...) = (not (xor ... x ...))
1134
      negate ^= is_neg_term(x);    // flip sign for (not x)
584✔
1135
      x = unsigned_term(x);   // turn (not x) into x
584✔
1136
      a[j] = x;
584✔
1137
      j ++;
584✔
1138
    }
1139
  }
1140

1141
  /*
1142
   * Second pass: remove duplicates (i.e., apply the rule (xor x x) --> false
1143
   */
1144
  n = j;
146✔
1145
  int_array_sort(a, n);
146✔
1146
  j = 0;
146✔
1147
  i = 0;
146✔
1148
  while (i+1 < n) {
545✔
1149
    x = a[i];
399✔
1150
    if (x == a[i+1]) {
399✔
1151
      i += 2;
40✔
1152
    } else {
1153
      a[j] = x;
359✔
1154
      j ++;
359✔
1155
      i ++;
359✔
1156
    }
1157
  }
1158
  assert(i == n || i + 1 == n);
1159
  if (i+1 == n) {
146✔
1160
    a[j] = a[i];
145✔
1161
    j ++;
145✔
1162
  }
1163

1164

1165
  /*
1166
   * Build the result: (xor negate (xor a[0] ... a[j-1]))
1167
   */
1168
  if (j == 0) {
146✔
1169
    return bool2term(negate);
×
1170
  }
1171

1172
  if (j == 1) {
146✔
1173
    return negate ^ a[0];
6✔
1174
  }
1175

1176
  if (j == 2) {
140✔
1177
    x = a[0];
65✔
1178
    y = a[1];
65✔
1179
    assert(is_pos_term(x) && is_pos_term(y) && x < y);
1180
    if (negate) {
65✔
1181
      /*
1182
       * to be consistent with mk_iff:
1183
       * not (xor x y) --> (eq (not x) y) if y is uninterpreted and x is not
1184
       * not (xor x y) --> (eq x (not y)) otherwise
1185
       */
1186
      if (is_literal(manager, y) && !is_literal(manager, x)) {
4✔
1187
        x = opposite_term(x);
×
1188
      } else {
1189
        y = opposite_term(y);
4✔
1190
      }
1191
    }
1192
    return opposite_term(eq_term(manager->terms, x, y));
65✔
1193
  }
1194

1195
  // general case: j >= 3
1196
  x = xor_term(manager->terms, j, a);
75✔
1197
  if (negate) {
75✔
1198
    x = opposite_term(x);
14✔
1199
  }
1200

1201
  return x;
75✔
1202
}
1203

1204

1205
/*
1206
 * Safe versions of mk_or, mk_and, mk_xor: make a copy of the argument array
1207
 * into manager->vector0
1208
 */
1209
term_t mk_or_safe(term_manager_t *manager, uint32_t n, const term_t a[]) {
×
1210
  ivector_t *v;
1211

1212
  v = &manager->vector0;
×
1213
  ivector_copy(v, a, n);
×
1214
  assert(v->size == n);
1215
  return mk_or(manager, n, v->data);
×
1216
}
1217

1218
term_t mk_and_safe(term_manager_t *manager, uint32_t n, const term_t a[]) {
×
1219
  ivector_t *v;
1220

1221
  v = &manager->vector0;
×
1222
  ivector_copy(v, a, n);
×
1223
  assert(v->size == n);
1224
  return mk_and(manager, n, v->data);
×
1225
}
1226

1227
term_t mk_xor_safe(term_manager_t *manager, uint32_t n, const term_t a[]) {
8✔
1228
  ivector_t *v;
1229

1230
  v = &manager->vector0;
8✔
1231
  ivector_copy(v, a, n);
8✔
1232
  assert(v->size == n);
1233
  return mk_xor(manager, n, v->data);
8✔
1234
}
1235

1236

1237
/******************
1238
 *  IF-THEN-ELSE  *
1239
 *****************/
1240

1241
/*
1242
 * BIT-VECTOR IF-THEN-ELSE
1243
 */
1244

1245
/*
1246
 * Build (ite c x y) when both x and y are boolean constants.
1247
 */
1248
static term_t const_ite_simplify(term_t c, term_t x, term_t y) {
17,677✔
1249
  assert(x == true_term || x == false_term);
1250
  assert(y == true_term || y == false_term);
1251

1252
  if (x == y) return x;
17,677✔
1253
  if (x == true_term) {
13,665✔
1254
    assert(y == false_term);
1255
    return c;
12,065✔
1256
  }
1257

1258
  assert(x == false_term && y == true_term);
1259
  return opposite_term(c);
1,600✔
1260
}
1261

1262

1263
/*
1264
 * Convert (ite c u v) into a bvarray term:
1265
 * - c is a boolean
1266
 * - u and v are two bv64 constants
1267
 * - n = number of bits in u and v
1268
 */
1269
static term_t mk_bvconst64_ite_core(term_manager_t *manager, term_t c, uint64_t u, uint64_t v, uint32_t n) {
13,559✔
1270
  uint32_t i;
1271
  term_t bu, bv;
1272
  term_t *a;
1273

1274
  resize_ivector(&manager->vector0, n);
13,559✔
1275
  a = manager->vector0.data;
13,559✔
1276

1277
  for (i=0; i<n; i++) {
30,468✔
1278
    bu = bool2term(tst_bit64(u, i)); // bit i of u
16,909✔
1279
    bv = bool2term(tst_bit64(v, i)); // bit i of v
16,909✔
1280

1281
    a[i] = const_ite_simplify(c, bu, bv); // a[i] = (ite c bu bv)
16,909✔
1282
  }
1283

1284
  return bvarray_get_term(manager, a, n);
13,559✔
1285
}
1286

1287
static inline term_t mk_bvconst64_ite(term_manager_t *manager, term_t c, bvconst64_term_t *u, bvconst64_term_t *v) {
13,559✔
1288
  assert(v->bitsize == u->bitsize);
1289
  return mk_bvconst64_ite_core(manager, c, u->value, v->value, u->bitsize);
13,559✔
1290
}
1291

1292

1293
/*
1294
 * Same thing with u and v two generic bv constants
1295
 * - c: boolean term
1296
 * - u = array of words
1297
 * - v = array of words
1298
 * - n = number of bits in u and b
1299
 */
1300
static term_t mk_bvconst_ite_core(term_manager_t *manager, term_t c, uint32_t *u, uint32_t *v, uint32_t n) {
6✔
1301
  uint32_t i;
1302
  term_t bu, bv;
1303
  term_t *a;
1304

1305
  resize_ivector(&manager->vector0, n);
6✔
1306
  a = manager->vector0.data;
6✔
1307

1308
  for (i=0; i<n; i++) {
774✔
1309
    bu = bool2term(bvconst_tst_bit(u, i));
768✔
1310
    bv = bool2term(bvconst_tst_bit(v, i));
768✔
1311

1312
    a[i] = const_ite_simplify(c, bu, bv);
768✔
1313
  }
1314

1315
  return bvarray_get_term(manager, a, n);
6✔
1316
}
1317

1318
static inline term_t mk_bvconst_ite(term_manager_t *manager, term_t c, bvconst_term_t *u, bvconst_term_t *v) {
6✔
1319
  assert(u->bitsize == v->bitsize);
1320
  return mk_bvconst_ite_core(manager, c, u->data, v->data, u->bitsize);
6✔
1321
}
1322

1323

1324

1325
/*
1326
 * Given three boolean terms c, x, and y, check whether (ite c x y)
1327
 * simplifies and if so return the result.
1328
 * - return NULL_TERM if no simplification is found.
1329
 * - the function assumes c is not a boolean constant
1330
 */
1331
static term_t check_ite_simplifies(term_t c, term_t x, term_t y) {
23,590✔
1332
  assert(c != true_term && c != false_term);
1333

1334
  // (ite c x y) --> (ite c true y)  if c == x
1335
  // (ite c x y) --> (ite c false y) if c == not x
1336
  if (c == x) {
23,590✔
1337
    x = true_term;
×
1338
  } else if (opposite_bool_terms(c, x)) {
23,590✔
1339
    x = false_term;
146✔
1340
  }
1341

1342
  // (ite c x y) --> (ite c x false) if c == y
1343
  // (ite c x y) --> (ite c x true)  if c == not y
1344
  if (c == y) {
23,590✔
1345
    y = false_term;
94✔
1346
  } else if (opposite_bool_terms(c, y)) {
23,496✔
1347
    y = true_term;
146✔
1348
  }
1349

1350
  // (ite c x x) --> x
1351
  // (ite c true false) --> c
1352
  // (ite c false true) --> not c
1353
  if (x == y) return x;
23,590✔
1354
  if (x == true_term && y == false_term) return c;
13,756✔
1355
  if (x == false_term && y == true_term) return opposite_term(c);
13,748✔
1356

1357
  return NULL_TERM;
5,328✔
1358
}
1359

1360

1361
/*
1362
 * Attempt to convert (ite c u v) into a bvarray term:
1363
 * - u is a bitvector constant of no more than 64 bits
1364
 * - v is a bvarray term
1365
 * Return NULL_TERM if the simplifications fail.
1366
 */
1367
static term_t check_ite_bvconst64(term_manager_t *manager, term_t c, bvconst64_term_t *u, composite_term_t *v) {
4,191✔
1368
  uint32_t i, n;
1369
  term_t b;
1370
  term_t *a;
1371

1372
  n = u->bitsize;
4,191✔
1373
  assert(n == v->arity);
1374
  resize_ivector(&manager->vector0, n);
4,191✔
1375
  a = manager->vector0.data;
4,191✔
1376

1377
  for (i=0; i<n; i++) {
4,637✔
1378
    b = bool2term(tst_bit64(u->value, i)); // bit i of u
4,636✔
1379
    b = check_ite_simplifies(c, b, v->arg[i]);
4,636✔
1380

1381
    if (b == NULL_TERM) {
4,636✔
1382
      return NULL_TERM;
4,190✔
1383
    }
1384
    a[i] = b;
446✔
1385
  }
1386

1387
  return bvarray_get_term(manager, a, n);
1✔
1388
}
1389

1390

1391
/*
1392
 * Same thing for a generic constant u
1393
 */
1394
static term_t check_ite_bvconst(term_manager_t *manager, term_t c, bvconst_term_t *u, composite_term_t *v) {
358✔
1395
  uint32_t i, n;
1396
  term_t b;
1397
  term_t *a;
1398

1399
  n = u->bitsize;
358✔
1400
  assert(n == v->arity);
1401
  resize_ivector(&manager->vector0, n);
358✔
1402
  a = manager->vector0.data;
358✔
1403

1404
  for (i=0; i<n; i++) {
834✔
1405
    b = bool2term(bvconst_tst_bit(u->data, i)); // bit i of u
830✔
1406
    b = check_ite_simplifies(c, b, v->arg[i]);
830✔
1407

1408
    if (b == NULL_TERM) {
830✔
1409
      return NULL_TERM;
354✔
1410
    }
1411
    a[i] = b;
476✔
1412
  }
1413

1414
  return bvarray_get_term(manager, a, n);
4✔
1415
}
1416

1417

1418
/*
1419
 * Same thing when both u and v are bvarray terms.
1420
 */
1421
static term_t check_ite_bvarray(term_manager_t *manager, term_t c, composite_term_t *u, composite_term_t *v) {
933✔
1422
  uint32_t i, n;
1423
  term_t b;
1424
  term_t *a;
1425

1426
  n = u->arity;
933✔
1427
  assert(n == v->arity);
1428
  resize_ivector(&manager->vector0, n);
933✔
1429
  a = manager->vector0.data;
933✔
1430

1431
  for (i=0; i<n; i++) {
18,273✔
1432
    b = check_ite_simplifies(c, u->arg[i], v->arg[i]);
18,124✔
1433

1434
    if (b == NULL_TERM) {
18,124✔
1435
      return NULL_TERM;
784✔
1436
    }
1437
    a[i] = b;
17,340✔
1438
  }
1439

1440
  return bvarray_get_term(manager, a, n);
149✔
1441
}
1442

1443

1444
/*
1445
 * Construct t + (ite c a b)
1446
 * - n = number of bits in a and b and t
1447
 */
1448
static term_t mk_bvoffset64_ite(term_manager_t *manager, term_t c, term_t t, uint64_t a, uint64_t b, uint32_t n) {
×
1449
  bvarith64_buffer_t *buffer;
1450
  term_table_t *tbl;
1451
  term_t u;
1452

1453
  tbl = manager->terms;
×
1454
  buffer = term_manager_get_bvarith64_buffer(manager);
×
1455

1456
  u = mk_bvconst64_ite_core(manager, c, a, b, n);   // (ite c a b)
×
1457
  bvarith64_buffer_set_term(buffer, tbl, t);
×
1458
  bvarith64_buffer_add_term(buffer, tbl, u);
×
1459
  return mk_bvarith64_term(manager, buffer);
×
1460
}
1461

1462

1463
/*
1464
 * Try to rewrite (ite c x y) to  (ite c a b) + t where a and b are constants.
1465
 * - x and y are both polynomials
1466
 */
1467
static term_t check_ite_bvoffset64(term_manager_t *manager, term_t c, term_t x, term_t y) {
×
1468
  term_table_t *tbl;
1469
  bvpoly64_t *u, *v;
1470
  uint64_t a, b;
1471
  term_t t;
1472
  uint32_t n;
1473

1474
  tbl = manager->terms;
×
1475

1476
  u = bvpoly64_term_desc(tbl, x);
×
1477
  v = bvpoly64_term_desc(tbl, y);
×
1478
  n = u->bitsize;
×
1479

1480
  assert(n == v->bitsize);
1481

1482
  if (bvpoly64_is_offset(u) && bvpoly64_is_offset(v)) {
×
1483
    assert(u->nterms == 2 && v->nterms == 2);
1484
    assert(u->mono[0].var == const_idx && v->mono[0].var == const_idx);
1485

1486
    t = u->mono[1].var;
×
1487
    if (v->mono[1].var == t) {
×
1488
      n = u->bitsize;
×
1489
      a = u->mono[0].coeff;
×
1490
      b = v->mono[0].coeff;
×
1491
      return mk_bvoffset64_ite(manager, c, t, a, b, n);
×
1492
    }
1493

1494
  } else if (delta_bvpoly64_is_constant(u, v)) {
×
1495
    // x - y is a constant
1496
    if (u->nterms + 1 == v->nterms) {
×
1497
      // rewrite (ite c x (b + x)) to x + (ite c 0 b)
1498
      assert(v->mono[0].var == const_idx);
1499
      b =  v->mono[0].coeff;
×
1500
      return mk_bvoffset64_ite(manager, c, x, 0, b, n);
×
1501
    }
1502
    if (u->nterms == v->nterms + 1) {
×
1503
      // rewrite (ite c (a + y) y) to y + (ite c a 0)
1504
      assert(u->mono[0].var == const_idx);
1505
      a = u->mono[0].coeff;
×
1506
      return mk_bvoffset64_ite(manager, c, y, a, 0, n);
×
1507
    }
1508
    // TODO: handle the case u->nterms == v->nterms?
1509
  }
1510

1511
  return NULL_TERM;
×
1512
}
1513

1514
/*
1515
 * Try to rewrite (ite c t u) to (ite c a 0) + t where
1516
 */
1517
static term_t check_ite_bvoffset64_var(term_manager_t *manager, term_t c, term_t t, bvpoly64_t *u) {
×
1518
  uint32_t n;
1519

1520
  if (bvpoly64_is_const_plus_var(u, t)) {
×
1521
    assert(u->nterms == 2 && u->mono[0].var == const_idx &&
1522
           u->mono[1].var == t && u->mono[1].coeff == 1);
1523

1524
    n = u->bitsize;
×
1525
    return mk_bvoffset64_ite(manager, c, t, 0, u->mono[0].coeff, n);
×
1526
  }
1527

1528
  return NULL_TERM;
×
1529
}
1530

1531

1532
/*
1533
 * Construct t + (ite c a b)
1534
 * - n = number of bits in a and b and t
1535
 * - a or b may be NULL, in which case they are interpreted as zero
1536
 */
1537
static term_t mk_bvoffset_ite(term_manager_t *manager, term_t c, term_t t, uint32_t *a, uint32_t *b, uint32_t n) {
×
1538
  uint32_t aux[32];
1539
  bvarith_buffer_t *buffer;
1540
  term_table_t *tbl;
1541
  uint32_t w;
1542
  uint32_t *tmp;
1543
  term_t u;
1544

1545
  tbl = manager->terms;
×
1546
  buffer = term_manager_get_bvarith_buffer(manager);
×
1547

1548
  tmp = NULL;
×
1549
  if (a == NULL || b == NULL) {
×
1550
    assert(a != b); // only one can be NULL
1551
    w = (n + 31) >> 5; // number of words to store the zero constant
×
1552
    tmp = aux;
×
1553
    if (w > 32) tmp = (uint32_t *) safe_malloc(w * sizeof(uint32_t));
×
1554
    bvconst_clear(tmp, w);
×
1555
    if (a == NULL) a = tmp;
×
1556
    if (b == NULL) b = tmp;
×
1557
  }
1558

1559
  u = mk_bvconst_ite_core(manager, c, a, b, n);   // (ite c a b)
×
1560
  bvarith_buffer_set_term(buffer, tbl, t);
×
1561
  bvarith_buffer_add_term(buffer, tbl, u);
×
1562
  u = mk_bvarith_term(manager, buffer);
×
1563

1564
  if (tmp != NULL && w > 32) {
×
1565
    safe_free(tmp);
×
1566
  }
1567

1568
  return u;
×
1569
}
1570

1571

1572
/*
1573
 * Try to rewrite (ite c x y) to  (ite c a b) + t where a and b are constants.
1574
 * - x and y are both polynomials
1575
 */
1576
static term_t check_ite_bvoffset(term_manager_t *manager, term_t c, term_t x, term_t y) {
×
1577
  term_table_t *tbl;
1578
  bvpoly_t *u, *v;
1579
  uint32_t *a, *b;
1580
  term_t t;
1581
  uint32_t n;
1582

1583
  tbl = manager->terms;
×
1584

1585
  u = bvpoly_term_desc(tbl, x);
×
1586
  v = bvpoly_term_desc(tbl, y);
×
1587
  n = u->bitsize;
×
1588

1589
  assert(n == v->bitsize);
1590

1591
  if (bvpoly_is_offset(u) && bvpoly_is_offset(v)) {
×
1592
    assert(u->nterms == 2 && v->nterms == 2);
1593
    assert(u->mono[0].var == const_idx && v->mono[0].var == const_idx);
1594

1595
    t = u->mono[1].var;
×
1596
    if (v->mono[1].var == t) {
×
1597
      n = u->bitsize;
×
1598
      a = u->mono[0].coeff;
×
1599
      b = v->mono[0].coeff;
×
1600
      return mk_bvoffset_ite(manager, c, t, a, b, n);
×
1601
    }
1602
  } else if (delta_bvpoly_is_constant(u, v)) {
×
1603
    // x - y is a constant
1604
    if (u->nterms + 1 == v->nterms) {
×
1605
      // rewrite (ite c x (b + x)) to x + (ite c 0 b)
1606
      assert(v->mono[0].var == const_idx);
1607
      b = v->mono[0].coeff;
×
1608
      return mk_bvoffset_ite(manager, c, x, NULL, b, n);
×
1609
    }
1610
    if (u->nterms == v->nterms + 1) {
×
1611
      // rewrite (ite c (a + y) y) to y + (ite c a 0)
1612
      assert(u->mono[0].var == const_idx);
1613
      a = u->mono[0].coeff;
×
1614
      return mk_bvoffset_ite(manager, c, y, a, NULL, n);
×
1615
    }
1616
  }
1617

1618
  return NULL_TERM;
×
1619
}
1620

1621
/*
1622
 * Try to rewrite (ite c t u) to (ite c a 0) + t where
1623
 */
1624
static term_t check_ite_bvoffset_var(term_manager_t *manager, term_t c, term_t t, bvpoly_t *u) {
×
1625
  uint32_t aux[32];
1626
  uint32_t n, w;
1627
  uint32_t *a;
1628
  term_t result;
1629

1630

1631
  result = NULL_TERM;
×
1632
  if (bvpoly_is_const_plus_var(u, t)) {
×
1633
    assert(u->nterms == 2 && u->mono[0].var == const_idx &&
1634
           u->mono[1].var == t && bvconst_is_one(u->mono[1].coeff, u->width));
1635

1636
    n = u->bitsize;
×
1637
    w = (n + 31) >> 5;
×
1638
    if (w <= 32) {
×
1639
      bvconst_clear(aux, w);
×
1640
      result = mk_bvoffset_ite(manager, c, t, aux, u->mono[0].coeff, n);
×
1641
    } else {
1642
      a = (uint32_t *) safe_malloc(w * sizeof(uint32_t));
×
1643
      bvconst_clear(a, w);
×
1644
      result = mk_bvoffset_ite(manager, c, t, a, u->mono[0].coeff, n);
×
1645
      safe_free(a);
×
1646
    }
1647
  }
1648

1649
  return result;
×
1650
}
1651

1652

1653

1654
/*
1655
 * Build (ite c x y) c is boolean, x and y are bitvector terms
1656
 * Use vector0 as a buffer.
1657
 */
1658
term_t mk_bv_ite(term_manager_t *manager, term_t c, term_t x, term_t y) {
133,362✔
1659
  term_table_t *tbl;
1660
  term_kind_t kind_x, kind_y;
1661
  term_t aux;
1662

1663
  tbl = manager->terms;
133,362✔
1664

1665
  assert(term_type(tbl, x) == term_type(tbl, y) &&
1666
         is_bitvector_term(tbl, x) &&
1667
         is_boolean_term(tbl, c));
1668

1669
  // Try generic simplification first
1670
  if (x == y) return x;
133,362✔
1671
  if (c == true_term) return x;
117,189✔
1672
  if (c == false_term) return y;
117,034✔
1673

1674
  kind_x = term_kind(tbl, x);
116,699✔
1675
  kind_y = term_kind(tbl, y);
116,699✔
1676
  aux = NULL_TERM;
116,699✔
1677

1678
  // Check whether (ite c x y) simplifies to a bv_array term
1679
  switch (kind_x) {
116,699✔
1680
  case BV64_CONSTANT:
50,249✔
1681
    assert(kind_y != BV_CONSTANT);
1682
    if (kind_y == BV64_CONSTANT) {
50,249✔
1683
      return mk_bvconst64_ite(manager, c, bvconst64_term_desc(tbl, x), bvconst64_term_desc(tbl, y));
13,559✔
1684
    }
1685
    if (kind_y == BV_ARRAY) {
36,690✔
1686
      aux = check_ite_bvconst64(manager, c, bvconst64_term_desc(tbl, x), bvarray_term_desc(tbl, y));
2,935✔
1687
    }
1688
    break;
36,690✔
1689

1690
  case BV_CONSTANT:
492✔
1691
    assert(kind_y != BV64_CONSTANT);
1692
    if (kind_y == BV_CONSTANT) {
492✔
1693
      return mk_bvconst_ite(manager, c, bvconst_term_desc(tbl, x), bvconst_term_desc(tbl, y));
6✔
1694
    }
1695
    if (kind_y == BV_ARRAY) {
486✔
1696
      aux = check_ite_bvconst(manager, c, bvconst_term_desc(tbl, x), bvarray_term_desc(tbl, y));
354✔
1697
    }
1698
    break;
486✔
1699

1700
  case BV_ARRAY:
19,401✔
1701
    if (kind_y == BV64_CONSTANT) {
19,401✔
1702
      aux = check_ite_bvconst64(manager, opposite_term(c), bvconst64_term_desc(tbl, y), bvarray_term_desc(tbl, x));
1,256✔
1703
    } else if (kind_y == BV_CONSTANT) {
18,145✔
1704
      aux = check_ite_bvconst(manager, opposite_term(c), bvconst_term_desc(tbl, y), bvarray_term_desc(tbl, x));
4✔
1705
    } else if (kind_y == BV_ARRAY) {
18,141✔
1706
      aux = check_ite_bvarray(manager, opposite_term(c), bvarray_term_desc(tbl, y), bvarray_term_desc(tbl, x));
933✔
1707
    }
1708
    break;
19,401✔
1709

1710
  default:
46,557✔
1711
    break;
46,557✔
1712
  }
1713

1714
  if (manager->simplify_bvite_offset) {
103,134✔
1715
    // More rewrites
1716
    // (ite c (a + t) (b + t)) --> t + (ite c a b) where a and b are constants
1717
    if (kind_x == BV64_POLY && kind_y == BV64_POLY) {
×
1718
      aux = check_ite_bvoffset64(manager, c, x, y);
×
1719
    } else if (kind_y == BV64_POLY) {
×
1720
      aux = check_ite_bvoffset64_var(manager, c, x, bvpoly64_term_desc(tbl, y));
×
1721
    } else if (kind_x == BV64_POLY) {
×
1722
      aux = check_ite_bvoffset64_var(manager, opposite_term(c), y, bvpoly64_term_desc(tbl, x));
×
1723
    } else if (kind_x == BV_POLY && kind_y == BV_POLY) {
×
1724
      aux = check_ite_bvoffset(manager, c, x, y);
×
1725
    } else if (kind_y == BV_POLY) {
×
1726
      aux = check_ite_bvoffset_var(manager, c, x, bvpoly_term_desc(tbl, y));
×
1727
    } else if (kind_x == BV_POLY) {
×
1728
      aux = check_ite_bvoffset_var(manager, opposite_term(c), y, bvpoly_term_desc(tbl, x));
×
1729
    }
1730
  }
1731

1732

1733
  if (aux != NULL_TERM) {
103,134✔
1734
    return aux;
154✔
1735
  }
1736

1737
  /*
1738
   * No simplification found: build a standard ite.
1739
   * Normalize first: (ite (not c) x y) --> (ite c y x)
1740
   */
1741
  if (is_neg_term(c)) {
102,980✔
1742
    c = opposite_term(c);
6,506✔
1743
    aux = x; x = y; y = aux;
6,506✔
1744
  }
1745

1746
  return ite_term(tbl, term_type(tbl, x), c, x, y);
102,980✔
1747
}
1748

1749

1750

1751

1752

1753
/*
1754
 * BOOLEAN IF-THEN-ELSE
1755
 */
1756

1757
/*
1758
 * Build (bv-eq x (ite c y z))
1759
 * - c not true/false
1760
 */
1761
static term_t mk_bveq_ite(term_manager_t *manager, term_t c, term_t x, term_t y, term_t z) {
376✔
1762
  term_t ite, aux;
1763

1764
  assert(term_type(manager->terms, x) == term_type(manager->terms, y) &&
1765
         term_type(manager->terms, x) == term_type(manager->terms, z));
1766

1767
  ite = mk_bv_ite(manager, c, y, z);
376✔
1768

1769
  // normalize (bveq x ite): put smaller index on the left
1770
  if (x > ite) {
376✔
1771
    aux = x; x = ite; ite = aux;
×
1772
  }
1773

1774
  return bveq_atom(manager->terms, x, ite);
376✔
1775
}
1776

1777

1778
/*
1779
 * Special constructor for (ite c (bveq x y) (bveq z u))
1780
 *
1781
 * Apply lift-if rule:
1782
 * (ite c (bveq x y) (bveq x u))  ---> (bveq x (ite c y u))
1783
 */
1784
static term_t mk_lifted_ite_bveq(term_manager_t *manager, term_t c, term_t t, term_t e) {
381✔
1785
  term_table_t *tbl;
1786
  composite_term_t *eq1, *eq2;
1787
  term_t x;
1788

1789
  tbl = manager->terms;
381✔
1790

1791
  assert(is_pos_term(t) && is_pos_term(e) &&
1792
         term_kind(tbl, t) == BV_EQ_ATOM && term_kind(tbl, e) == BV_EQ_ATOM);
1793

1794
  eq1 = composite_for_idx(tbl, index_of(t));
381✔
1795
  eq2 = composite_for_idx(tbl, index_of(e));
381✔
1796

1797
  assert(eq1->arity == 2 && eq2->arity == 2);
1798

1799
  x = eq1->arg[0];
381✔
1800
  if (x == eq2->arg[0]) return mk_bveq_ite(manager, c, x, eq1->arg[1], eq2->arg[1]);
381✔
1801
  if (x == eq2->arg[1]) return mk_bveq_ite(manager, c, x, eq1->arg[1], eq2->arg[0]);
12✔
1802

1803
  x = eq1->arg[1];
10✔
1804
  if (x == eq2->arg[0]) return mk_bveq_ite(manager, c, x, eq1->arg[0], eq2->arg[1]);
10✔
1805
  if (x == eq2->arg[1]) return mk_bveq_ite(manager, c, x, eq1->arg[0], eq2->arg[0]);
7✔
1806

1807
  return ite_term(tbl, bool_type(tbl->types), c, t, e);
5✔
1808
}
1809

1810

1811
/*
1812
 * Simplifications:
1813
 *  ite c x x        --> x
1814
 *  ite true x y     --> x
1815
 *  ite false x y    --> y
1816
 *
1817
 *  ite c x (not x)  --> (c == x)
1818
 *
1819
 *  ite c c y        --> c or y
1820
 *  ite c x c        --> c and x
1821
 *  ite c (not c) y  --> (not c) and y
1822
 *  ite c x (not c)  --> (not c) or x
1823
 *
1824
 *  ite c true y     --> c or y
1825
 *  ite c x false    --> c and x
1826
 *  ite c false y    --> (not c) and y
1827
 *  ite c x true     --> (not c) or x
1828
 *
1829
 * Otherwise:
1830
 *  ite (not c) x y  --> ite c y x
1831
 */
1832
term_t mk_bool_ite(term_manager_t *manager, term_t c, term_t x, term_t y) {
32,670✔
1833
  term_t aux;
1834

1835
  if (x == y) return x;
32,670✔
1836
  if (c == true_term) return x;
32,357✔
1837
  if (c == false_term) return y;
31,970✔
1838

1839
  if (opposite_bool_terms(x, y)) return mk_iff(manager, c, x);
31,642✔
1840

1841
  if (c == x) return mk_binary_or(manager, c, y);
31,179✔
1842
  if (c == y) return mk_binary_and(manager, c, x);
31,012✔
1843
  if (opposite_bool_terms(c, x)) return mk_binary_and(manager, x, y);
30,841✔
1844
  if (opposite_bool_terms(c, y)) return mk_binary_or(manager, x, y);
30,834✔
1845

1846
  if (x == true_term) return mk_binary_or(manager, c, y);
30,830✔
1847
  if (y == false_term) return mk_binary_and(manager, c, x);
27,432✔
1848
  if (x == false_term) return mk_binary_and(manager, opposite_term(c), y);
27,153✔
1849
  if (y == true_term) return mk_binary_or(manager, opposite_term(c), x);
26,874✔
1850

1851

1852
  if (is_neg_term(c)) {
26,629✔
1853
    c = opposite_term(c);
2,387✔
1854
    aux = x; x = y; y = aux;
2,387✔
1855
  }
1856

1857
  if (is_pos_term(x) && is_pos_term(y) &&
42,518✔
1858
      term_kind(manager->terms, x) == BV_EQ_ATOM &&
16,308✔
1859
      term_kind(manager->terms, y) == BV_EQ_ATOM) {
419✔
1860
    return mk_lifted_ite_bveq(manager, c, x, y);
381✔
1861
  }
1862

1863
  return ite_term(manager->terms, bool_type(manager->types), c, x, y);
26,248✔
1864
}
1865

1866

1867

1868

1869
/*
1870
 * ARITHMETIC IF-THEN-ELSE
1871
 */
1872

1873
/*
1874
 * PUSH IF INSIDE INTEGER LINEAR POLYNOMIALS
1875
 *
1876
 * If t and e are polynomials with integer variables, we try to
1877
 * rewrite (ite c t e)  to r + a * (ite c t' e')  where:
1878
 *   r = common part of t and e (cf. polynomials.h)
1879
 *   a = gcd of coefficients of (t - r) and (e - r).
1880
 *   t' = (t - r)/a
1881
 *   e' = (e - r)/a
1882
 *
1883
 * The code assumes that t and e are linear polynomials (i.e.,
1884
 * the monomials are sorted in increasing variable order).
1885
 */
1886

1887
/*
1888
 * Remove every monomial of p whose variable is in a then divide the
1889
 * result by c
1890
 * - a = array of terms sorted in increasing order
1891
 *   a is terminatated by max_idx
1892
 * - every element of a must be a variable of p
1893
 * - c must be non-zero
1894
 * - return the term (p - r)/c
1895
 */
1896
static term_t remove_monomials(term_manager_t *manager, polynomial_t *p, term_t *a, rational_t *c) {
1,312✔
1897
  rba_buffer_t *b;
1898
  monomial_t *mono;
1899
  uint32_t i;
1900
  term_t x;
1901

1902
  assert(q_is_nonzero(c));
1903

1904
  b = term_manager_get_arith_buffer(manager);
1,312✔
1905
  reset_rba_buffer(b);
1,312✔
1906

1907
  i = 0;
1,312✔
1908
  mono = p->mono;
1,312✔
1909
  x = mono->var;
1,312✔
1910

1911
  // deal with the constant if any
1912
  if (x == const_idx) {
1,312✔
1913
    if (x == a[i]) {
365✔
1914
      i ++;
×
1915
    } else {
1916
      assert(x < a[i]);
1917
      rba_buffer_add_const(b, &mono->coeff);
365✔
1918
    }
1919
    mono ++;
365✔
1920
    x = mono->var;
365✔
1921
  }
1922

1923
  // non constant monomials
1924
  while (x < max_idx) {
3,754✔
1925
    if (x == a[i]) {
2,442✔
1926
      // skip t
1927
      i ++;
1,144✔
1928
    } else {
1929
      assert(x < a[i]);
1930
      rba_buffer_add_mono(b, &mono->coeff, pprod_for_term(manager->terms, x));
1,298✔
1931
    }
1932
    mono ++;
2,442✔
1933
    x = mono->var;
2,442✔
1934
  }
1935

1936
  // divide by c
1937
  if (! q_is_one(c)) {
1,312✔
1938
    rba_buffer_div_const(b, c);
248✔
1939
  }
1940

1941
  // build the term from b
1942
  return arith_buffer_to_term(manager->terms, b);
1,312✔
1943
}
1944

1945

1946
/*
1947
 * Remove every monomial of p whose variable is not in a
1948
 * then add c * t to the result.
1949
 * - a must be an array of terms sorted in increasing order and terminated by max_idx
1950
 * - all elements of a must be variables of p
1951
 */
1952
static term_t add_mono_to_common_part(term_manager_t *manager, polynomial_t *p, term_t *a, rational_t *c, term_t t) {
656✔
1953
  term_table_t *tbl;
1954
  rba_buffer_t *b;
1955
  monomial_t *mono;
1956
  uint32_t i;
1957
  term_t x;
1958

1959
  tbl = manager->terms;
656✔
1960
  b = term_manager_get_arith_buffer(manager);
656✔
1961
  reset_rba_buffer(b);
656✔
1962

1963
  i = 0;
656✔
1964
  mono = p->mono;
656✔
1965
  x = mono->var;
656✔
1966

1967
  // constant monomial
1968
  if (x == const_idx) {
656✔
1969
    assert(x <= a[i]);
1970
    if (x == a[i]) {
174✔
1971
      rba_buffer_add_const(b, &mono->coeff);
×
1972
      i ++;
×
1973
    }
1974
    mono ++;
174✔
1975
    x = mono->var;
174✔
1976
  }
1977

1978
  // non constant monomials
1979
  while (x < max_idx) {
1,922✔
1980
    assert(x <= a[i]);
1981
    if (x == a[i]) {
1,266✔
1982
      rba_buffer_add_mono(b, &mono->coeff, pprod_for_term(tbl, x));
572✔
1983
      i ++;
572✔
1984
    }
1985
    mono ++;
1,266✔
1986
    x = mono->var;
1,266✔
1987
  }
1988

1989
  // add c * t
1990
  rba_buffer_add_mono(b, c, pprod_for_term(tbl, t));
656✔
1991

1992
  return arith_buffer_to_term(tbl, b);
656✔
1993
}
1994

1995

1996

1997
/*
1998
 * Build  t := p/c where c is a non-zero rational
1999
 */
2000
static term_t polynomial_div_const(term_manager_t *manager, polynomial_t *p, rational_t *c) {
×
2001
  term_table_t *tbl;
2002
  rba_buffer_t *b;
2003

2004
  tbl = manager->terms;
×
2005
  b = term_manager_get_arith_buffer(manager);
×
2006
  reset_rba_buffer(b);
×
2007

2008
  rba_buffer_add_monarray(b, p->mono, pprods_for_poly(tbl, p));
×
2009
  term_table_reset_pbuffer(tbl);
×
2010
  rba_buffer_div_const(b, c);
×
2011

2012
  return arith_buffer_to_term(tbl, b);
×
2013
}
2014

2015

2016
/*
2017
 * Build t := u * c
2018
 */
2019
static term_t mk_mul_term_const(term_manager_t *manager, term_t t, rational_t *c) {
×
2020
  term_table_t *tbl;
2021
  rba_buffer_t *b;
2022

2023
  tbl = manager->terms;
×
2024
  b = term_manager_get_arith_buffer(manager);
×
2025
  reset_rba_buffer(b);
×
2026
  rba_buffer_add_mono(b, c, pprod_for_term(tbl, t));
×
2027

2028
  return arith_buffer_to_term(tbl, b);
×
2029
}
2030

2031

2032
/*
2033
 * Attempt to rewrite (ite c t e) to (r + a * (ite c t' e'))
2034
 * - t and e must be distinct integer linear polynomials
2035
 * - if r is null and a is one, it builds (ite c t e)
2036
 * - if r is null and a is more than one, it builds a * (ite t' e')
2037
 */
2038
static term_t mk_integer_polynomial_ite(term_manager_t *manager, term_t c, term_t t, term_t e) {
656✔
2039
  term_table_t *tbl;
2040
  polynomial_t *p, *q;
2041
  ivector_t *v;
2042
  rational_t *r0;
2043
  term_t ite;
2044

2045
  tbl = manager->terms;
656✔
2046

2047
  assert(is_integer_term(tbl, t) && is_integer_term(tbl, e));
2048
  assert(is_linear_poly(tbl, t) && is_linear_poly(tbl, e));
2049

2050
  p = poly_term_desc(tbl, t);  // then part
656✔
2051
  q = poly_term_desc(tbl, e);  // else part
656✔
2052
  assert(! equal_polynomials(p, q));
2053

2054
  /*
2055
   * Collect the common part of p and q into v
2056
   * + the common factor into r0
2057
   */
2058
  v = &manager->vector0;
656✔
2059
  ivector_reset(v);
656✔
2060
  monarray_pair_common_part(p->mono, q->mono, v);
656✔
2061
  ivector_push(v, max_idx); // end marker
656✔
2062

2063
  r0 = &manager->r0;
656✔
2064
  monarray_pair_non_common_gcd(p->mono, q->mono, r0);
656✔
2065
  assert(q_is_pos(r0) && q_is_integer(r0));
2066

2067
  if (v->size > 0) {
656✔
2068
    // the common part is non-null
2069
    t = remove_monomials(manager, p, v->data, r0);  // t is (p - common)/r0
656✔
2070
    e = remove_monomials(manager, q, v->data, r0);  // e is (q - common)/r0
656✔
2071
  } else if (! q_is_one(r0)) {
×
2072
    // no common part, common factor > 1
2073
    t = polynomial_div_const(manager, p, r0);   // t is p/r0
×
2074
    e = polynomial_div_const(manager, q, r0);   // e is q/r0
×
2075
  }
2076

2077
  // build (ite c t e): type int
2078
  ite = ite_term(tbl, int_type(tbl->types), c, t, e);
656✔
2079

2080
  if (v->size > 0) {
656✔
2081
    // build common + r0 * ite
2082
    ite = add_mono_to_common_part(manager, p, v->data, r0, ite);
656✔
2083
  } else if (! q_is_one(r0)) {
×
2084
    // common factor > 1: build r0 * ite
2085
    ite = mk_mul_term_const(manager, ite, r0);
×
2086
  }
2087

2088
  // cleanup
2089
  ivector_reset(v);
656✔
2090

2091
  return ite;
656✔
2092
}
2093

2094

2095
/*
2096
 * OFFSET ITE
2097
 */
2098

2099
/*
2100
 * Auxiliary function: builds t + (ite c k1 k2)
2101
 * - if is_int is true then both k1 and k2 are assumed to be integer
2102
 *   so (ite c k1 k2) has type int
2103
 * - otherwise (ite c k1 k2) has type real
2104
 */
2105
static term_t mk_offset_ite(term_manager_t *manager, term_t t, type_t c, term_t k1, term_t k2, bool is_int) {
336✔
2106
  term_table_t *tbl;
2107
  rba_buffer_t *b;
2108
  type_t tau;
2109
  term_t ite;
2110

2111
  tbl = manager->terms;
336✔
2112
  b  = term_manager_get_arith_buffer(manager);
336✔
2113

2114
  tau = is_int ? int_type(tbl->types) : real_type(tbl->types);
336✔
2115
  ite = ite_term(tbl, tau, c, k1, k2); // (ite c k1 k2)
336✔
2116
  reset_rba_buffer(b);
336✔
2117
  rba_buffer_add_term(b, tbl, t);
336✔
2118
  rba_buffer_add_term(b, tbl, ite); // t + (ite c k1 k2)
336✔
2119
  return arith_buffer_to_term(tbl, b);
336✔
2120
}
2121

2122

2123
/*
2124
 * Attempt to apply the offset rule to (ite c t e):
2125
 * 1) If t is of the form (k + e), builds  e + (ite c k 0)
2126
 * 2) If e is of the form (k + t), builds  t + (ite c 0 k)
2127
 * 3) Otherwise returns NULL_TERM
2128
 */
2129
static term_t try_offset_ite(term_manager_t *manager, term_t c, term_t t, term_t e) {
18,491✔
2130
  term_table_t *tbl;
2131
  polynomial_t *p;
2132
  rational_t *k;
2133
  term_t offset;
2134
  bool is_int;
2135

2136
  tbl = manager->terms;
18,491✔
2137
  k = &manager->r0;
18,491✔
2138

2139
  if (term_kind(tbl, t) == ARITH_POLY) {
18,491✔
2140
    p = poly_term_desc(tbl, t);
1,789✔
2141
    if (polynomial_is_const_plus_var(p, e)) {
1,789✔
2142
      // t is e + k for some non-zero constant k
2143
      // (ite c t e) --> e + (ite c k 0)
2144
      monarray_constant(p->mono, k);
274✔
2145
      is_int = q_is_integer(k);
274✔
2146
      offset = arith_constant(tbl, k);
274✔
2147
      return mk_offset_ite(manager, e, c, offset, zero_term, is_int);
274✔
2148
    }
2149
  }
2150

2151
  if (term_kind(tbl, e) == ARITH_POLY) {
18,217✔
2152
    p = poly_term_desc(tbl, e);
1,425✔
2153
    if (polynomial_is_const_plus_var(p, t)) {
1,425✔
2154
      // e is t + k for some non-zero constant k
2155
      // (ite c t e) --> t + (ite c 0 k)
2156
      monarray_constant(p->mono, k);
62✔
2157
      is_int = q_is_integer(k);
62✔
2158
      offset = arith_constant(tbl, k);
62✔
2159
      return mk_offset_ite(manager, t, c, zero_term, offset, is_int);
62✔
2160
    }
2161
  }
2162

2163
  return NULL_TERM;
18,155✔
2164
}
2165

2166

2167

2168

2169
/*
2170
 * PUSH IF INSIDE ARRAY/FUNCTION UPDATES
2171
 *
2172
 * Rewrite rules:
2173
 *  (ite c (update A (i1 ... ik) v) A) --> (update A (i1 ... ik) (ite c v (A i1 ... ik)))
2174
 *  (ite c A (update A (i1 ... ik) v)) --> (update A (i1 ... ik) (ite c (A i1 ... ik) v))
2175
 *  (ite c (update A (i1 ... ik) v) (update A (i1 ... ik) w)) -->
2176
 *      (update A (i1 ... ik) (ite c v w))
2177
 */
2178

2179

2180
/*
2181
 * Auxiliary function: check whether terms a[0...n-1] and b[0 .. n-1] are equal
2182
 */
2183
static bool equal_term_arrays(uint32_t n, const term_t *a, const term_t *b) {
19,470✔
2184
  uint32_t i;
2185

2186
  for (i=0; i<n; i++) {
20,510✔
2187
    if (a[i] != b[i]) return false;
19,497✔
2188
  }
2189
  return true;
1,013✔
2190
}
2191

2192

2193
/*
2194
 * Check whether one of the rewrite rules above is applicable to (ite c t e tau)
2195
 * - t and e have a function type
2196
 * - it it is apply it and return the result
2197
 * - otherwise, return NULL_TERM
2198
 */
2199
static term_t simplify_ite_update(term_manager_t *manager, term_t c, term_t t, term_t e, type_t tau) {
1,503✔
2200
  term_table_t *terms;
2201
  composite_term_t *update1, *update2;
2202
  bool t_is_update, e_is_update;
2203
  uint32_t n;
2204
  term_t aux;
2205
  type_t sigma;
2206

2207
  terms = manager->terms;
1,503✔
2208

2209
  assert(is_function_term(terms, t) && is_function_term(terms, e));
2210

2211
  t_is_update = (term_kind(terms, t) == UPDATE_TERM);
1,503✔
2212
  e_is_update = (term_kind(terms, e) == UPDATE_TERM);
1,503✔
2213
  sigma = function_type_range(manager->types, tau);
1,503✔
2214

2215
  if (t_is_update && e_is_update) {
1,503✔
2216
    update1 = update_term_desc(terms, t);
40✔
2217
    update2 = update_term_desc(terms, e);
40✔
2218

2219
    n = update1->arity;
40✔
2220
    assert(n >= 3 && n == update2->arity);
2221

2222
    if (equal_term_arrays(n-1, update1->arg, update2->arg)) {
40✔
2223
      // t is (update f a[1] ... a[n-2] v)
2224
      // e is (update f a[1] ... a[n-2] w)
2225
      aux = mk_ite(manager, c, update1->arg[n-1], update2->arg[n-1], sigma); // (ite c v w)
22✔
2226
      return mk_update(manager, update1->arg[0], n-2, update1->arg + 1, aux);
22✔
2227
    }
2228

2229
  } else if (t_is_update) {
1,463✔
2230
    update1 = update_term_desc(terms, t);
160✔
2231
    if (update1->arg[0] == e) {
160✔
2232
      // t is (update e a[1] ... a[n-2] v)
2233
      // (ite c t e) --> (update e a[1] ... a[n-2] (ite c v (e a[1] ... a[n-2])))
2234
      n = update1->arity;
64✔
2235
      assert(n >= 3);
2236

2237
      aux = mk_application(manager, e, n-2, update1->arg + 1);   // (e a[1] ... a[n-2])
64✔
2238
      aux = mk_ite(manager, c, update1->arg[n-1], aux, sigma);   // (ite c v (e a[1] ... a[n-2]))
64✔
2239
      return mk_update(manager, e, n-2, update1->arg + 1, aux);
64✔
2240
    }
2241

2242
  } else if (e_is_update) {
1,303✔
2243
    update2 = update_term_desc(terms, e);
150✔
2244
    if (update2->arg[0] == t) {
150✔
2245
      // e is (update t a[1] ... a[n-2] w)
2246
      // (ite c t e) --> (update t a[1] ... a[n-2] (ite c (t (a[1] ... a[n-2]) w)))
2247
      n = update2->arity;
62✔
2248
      assert(n >= 3);
2249

2250
      aux = mk_application(manager, t, n-2, update2->arg + 1);   // (t a[1] ... a[n-2])
62✔
2251
      aux = mk_ite(manager, c, aux, update2->arg[n-1], sigma);   // (ite c (t a[1] ... a[n-2]) w)
62✔
2252
      return mk_update(manager, t, n-2, update2->arg + 1, aux);
62✔
2253
    }
2254
  }
2255

2256
  return NULL_TERM;
1,355✔
2257
}
2258

2259

2260

2261

2262
/*
2263
 * GENERIC IF-THEN-ELSE
2264
 */
2265

2266
/*
2267
 * Simplify t assuming c holds
2268
 * - c must be a boolean term.
2269
 *
2270
 * Rules:
2271
 *   (ite  c x y) --> x
2272
 *   (ite ~c x y) --> y
2273
 */
2274
static term_t simplify_in_context(term_table_t *tbl, term_t c, term_t t) {
49,232✔
2275
  composite_term_t *d;
2276

2277
  assert(is_boolean_term(tbl, c) && good_term(tbl, t));
2278

2279
  while (is_ite_term(tbl, t)) {
50,695✔
2280
    d = ite_term_desc(tbl, t);
22,202✔
2281
    if (d->arg[0] == c) {
22,202✔
2282
      t = d->arg[1];
1,072✔
2283
    } else if (opposite_bool_terms(c, d->arg[0])) {
21,130✔
2284
      t = d->arg[2];
391✔
2285
    } else {
2286
      break;
20,739✔
2287
    }
2288
  }
2289

2290
  return t;
49,232✔
2291
}
2292

2293

2294
/*
2295
 * If-then-else: (if c then t else e)
2296
 * - c must be Boolean
2297
 * - t and e must have compatible types tau1 and tau2
2298
 * - tau must be the least common supertype of tau1 and tau2
2299
 *
2300
 * Simplifications
2301
 *    ite c (ite  c x y) z  --> ite c x z
2302
 *    ite c (ite ~c x y) z  --> ite c y z
2303
 *    ite c x (ite  c y z)  --> ite c x z
2304
 *    ite c x (ite ~c y z)  --> ite c x y
2305
 *
2306
 *    ite true x y   --> x
2307
 *    ite false x y  --> y
2308
 *    ite c x x      --> x
2309
 *
2310
 * Otherwise:
2311
 *    ite (not c) x y --> ite c y x
2312
 *
2313
 * Plus special trick for integer polynomials:
2314
 *    ite c (d * p1) (d * p2) --> d * (ite c p1 p2)
2315
 *
2316
 */
2317
term_t mk_ite(term_manager_t *manager, term_t c, term_t t, term_t e, type_t tau) {
196,747✔
2318
  term_t aux;
2319

2320
  // boolean ite
2321
  if (is_boolean_type(tau)) {
196,747✔
2322
    assert(is_boolean_term(manager->terms, t) &&
2323
           is_boolean_term(manager->terms, e));
2324
    return mk_bool_ite(manager, c, t, e);
32,670✔
2325
  }
2326

2327
  // bit-vector ite
2328
  if (is_bv_type(manager->types, tau)) {
164,077✔
2329
    assert(is_bitvector_term(manager->terms, t) &&
2330
           is_bitvector_term(manager->terms, e));
2331
    return mk_bv_ite(manager, c, t, e);
132,986✔
2332
  }
2333

2334
  // general case
2335
  if (c == true_term) return t;
31,091✔
2336
  if (c == false_term) return e;
29,038✔
2337

2338
  t = simplify_in_context(manager->terms, c, t);
24,616✔
2339
  e = simplify_in_context(manager->terms, opposite_term(c), e);
24,616✔
2340
  if (t == e) return t;
24,616✔
2341

2342
  if (is_neg_term(c)) {
24,033✔
2343
    // ite (not c) x y  --> ite c y x
2344
    c = opposite_term(c);
9,367✔
2345
    aux = t; t = e; e = aux;
9,367✔
2346
  }
2347

2348
  // rewriting of arithmetic if-then-elses
2349
  if (manager->simplify_ite && is_arithmetic_type(tau)) {
24,033✔
2350
    if (is_integer_type(tau) &&
36,415✔
2351
        is_linear_poly(manager->terms, t) &&
19,254✔
2352
        is_linear_poly(manager->terms, e)) {
1,986✔
2353
      return mk_integer_polynomial_ite(manager, c, t, e);
656✔
2354
    }
2355

2356
    aux = try_offset_ite(manager, c, t, e);
18,491✔
2357
    if (aux != NULL_TERM) return aux;
18,491✔
2358
  }
2359

2360
  // check for array updates
2361
  if (is_function_type(manager->types, tau)) {
23,041✔
2362
    aux = simplify_ite_update(manager, c, t, e, tau);
1,503✔
2363
    if (aux != NULL_TERM) return aux;
1,503✔
2364
  }
2365

2366
  return ite_term(manager->terms, tau, c, t, e);
22,893✔
2367
}
2368

2369

2370

2371

2372

2373
/**********************
2374
 *  ARITHMETIC ATOMS  *
2375
 *********************/
2376

2377
/*
2378
 * Auxiliary function: try to simplify (t1 == t2)
2379
 * using the following rules:
2380
 *   (ite c x y) == x -->  c  provided x != y holds
2381
 *   (ite c x y) == y --> ~c  provided x != y holds
2382
 *
2383
 * - return the result if one of these rules apply
2384
 * - return NULL_TERM otherwise.
2385
 */
2386
static term_t check_aritheq_simplifies(term_table_t *tbl, term_t t1, term_t t2) {
41,818✔
2387
  composite_term_t *d;
2388
  term_t x, y;
2389

2390
  assert(is_arithmetic_term(tbl, t1) && is_arithmetic_term(tbl, t2));
2391

2392
  if (is_ite_term(tbl, t1)) {
41,818✔
2393
    // (ite c x y) == t2
2394
    d = ite_term_desc(tbl, t1);
2,064✔
2395
    x = d->arg[1];
2,064✔
2396
    y = d->arg[2];
2,064✔
2397
    if (x == t2 && disequal_arith_terms(tbl, y, t2, true)) {
2,064✔
2398
      return d->arg[0];
×
2399
    }
2400
    if (y == t2 && disequal_arith_terms(tbl, x, t2, true)) {
2,064✔
2401
      return opposite_term(d->arg[0]);
×
2402
    }
2403
  }
2404

2405
  if (is_ite_term(tbl, t2)) {
41,818✔
2406
    // t1 == (ite c x y)
2407
    d = ite_term_desc(tbl, t2);
8,132✔
2408
    x = d->arg[1];
8,132✔
2409
    y = d->arg[2];
8,132✔
2410
    if (x == t1 && disequal_arith_terms(tbl, y, t1, true)) {
8,132✔
2411
      return d->arg[0];
44✔
2412
    }
2413
    if (y == t1 && disequal_arith_terms(tbl, x, t1, true)) {
8,088✔
2414
      return opposite_term(d->arg[0]);
55✔
2415
    }
2416
  }
2417

2418
  return NULL_TERM;
41,719✔
2419
}
2420

2421

2422
/*
2423
 * Auxiliary function: try to simplify (t == 0)
2424
 * Rules:
2425
 *   (ite c 0 y) == 0  -->  c provided y != 0
2426
 *   (ite c x 0) == 0  --> ~c provided x != 0
2427
 */
2428
static term_t check_arith_eq0_simplifies(term_table_t *tbl, term_t t, bool check_ite) {
4,090✔
2429
  composite_term_t *d;
2430
  term_t x, y;
2431

2432
  assert(is_arithmetic_term(tbl, t));
2433

2434
  if (is_ite_term(tbl, t)) {
4,090✔
2435
    // (ite c x y) == 0
2436
    d = ite_term_desc(tbl, t);
728✔
2437
    x = d->arg[1];
728✔
2438
    y = d->arg[2];
728✔
2439
    if (x == zero_term && arith_term_is_nonzero(tbl, y, check_ite)) {
728✔
2440
      return d->arg[0];
15✔
2441
    }
2442
    if (y == zero_term && arith_term_is_nonzero(tbl, x, check_ite)) {
713✔
2443
      return opposite_term(d->arg[0]);
30✔
2444
    }
2445
  }
2446

2447
  return NULL_TERM;
4,045✔
2448
}
2449

2450
/*
2451
 * Auxiliary function: build binary equality (t1 == t2)
2452
 * for two arithmetic terms t1 and t2.
2453
 * - try simplification and normalize first
2454
 */
2455
static term_t mk_arith_bineq_atom(term_table_t *tbl, term_t t1, term_t t2, bool simplify_ite) {
47,489✔
2456
  term_t aux;
2457

2458
  assert(is_arithmetic_term(tbl, t1) && is_arithmetic_term(tbl, t2));
2459

2460
  if (disequal_arith_terms(tbl, t1, t2, simplify_ite)) {
47,489✔
2461
    return false_term;
2,219✔
2462
  }
2463

2464
  if (simplify_ite) {
45,270✔
2465
    aux = check_aritheq_simplifies(tbl, t1, t2);
41,818✔
2466
    if (aux != NULL_TERM) {
41,818✔
2467
      return aux;
99✔
2468
    }
2469
  }
2470

2471
  // normalize: put the smallest term on the left
2472
  if (t1 > t2) {
45,171✔
2473
    aux = t1; t1 = t2; t2 = aux;
5,647✔
2474
  }
2475

2476
  return arith_bineq_atom(tbl, t1, t2);
45,171✔
2477
}
2478

2479

2480
/*
2481
 * Auxiliary function: builds equality (t == 0)
2482
 * - try to simplify and normalize then build (arith-eq0 t)
2483
 */
2484
static term_t mk_arith_eq0_atom(term_table_t *tbl, term_t t, bool simplify_ite) {
4,794✔
2485
  term_t aux;
2486

2487
  assert(is_arithmetic_term(tbl, t));
2488

2489
  if (arith_term_is_nonzero(tbl, t, simplify_ite)) {
4,794✔
2490
    return false_term;
13✔
2491
  }
2492

2493
  if (simplify_ite) {
4,781✔
2494
    aux = check_arith_eq0_simplifies(tbl, t, simplify_ite);
4,090✔
2495
    if (aux != NULL_TERM) {
4,090✔
2496
      return aux;
45✔
2497
    }
2498
  }
2499

2500
  return arith_eq_atom(tbl, t); // (t == 0)
4,736✔
2501
}
2502

2503

2504
/*
2505
 * Construct the atom (b == 0) then reset b.
2506
 *
2507
 * Normalize b first.
2508
 * - simplify to true if b is the zero polynomial
2509
 * - simplify to false if b is constant and non-zero
2510
 * - rewrite to (t1 == t2) if that's possible.
2511
 * - otherwise, create a polynomial term t from b
2512
 *   and return the atom (t == 0).
2513
 */
2514
term_t mk_arith_eq0(term_manager_t *manager, rba_buffer_t *b) {
72,732✔
2515
  return mk_direct_arith_eq0(manager->terms, b, manager->simplify_ite);
72,732✔
2516
}
2517

2518

2519

2520

2521
/*
2522
 * Auxiliary function: try to simplify (t >= 0)
2523
 * using the following rules:
2524
 *   (ite c x y) >= 0 --> c     if x >= 0 and y < 0
2525
 *   (ite c x y) >= 0 --> ~c    if x < 0 and y >= 0
2526
 *
2527
 * return NULL_TERM if these simplifications don't work.
2528
 * return the result otherwise
2529
 */
2530
static term_t check_arithge_simplifies(term_table_t *tbl, term_t t, bool check_ite) {
55,291✔
2531
  composite_term_t *d;
2532
  term_t x, y;
2533

2534
  assert(is_arithmetic_term(tbl, t));
2535

2536
  if (is_ite_term(tbl, t)) {
55,291✔
2537
    d = ite_term_desc(tbl, t);
255✔
2538
    x = d->arg[1];
255✔
2539
    y = d->arg[2];
255✔
2540

2541
    if (arith_term_is_nonneg(tbl, x, true) &&
328✔
2542
        arith_term_is_negative(tbl, y, check_ite)) {
73✔
2543
      return d->arg[0];
22✔
2544
    }
2545

2546
    if (arith_term_is_negative(tbl, x, check_ite) &&
251✔
2547
        arith_term_is_nonneg(tbl, y, true)) {
18✔
2548
      return opposite_term(d->arg[0]);
4✔
2549
    }
2550
  }
2551

2552
  return NULL_TERM;
55,265✔
2553
}
2554

2555

2556
/*
2557
 * Build the atom (t >= 0)
2558
 * - try simplifications first
2559
 */
2560
static term_t mk_arith_geq_atom(term_table_t *tbl, term_t t, bool simplify_ite) {
58,774✔
2561
  term_t aux;
2562

2563
  assert(is_arithmetic_term(tbl, t));
2564

2565
  if (arith_term_is_nonneg(tbl, t, simplify_ite)) {
58,774✔
2566
    return true_term;
23✔
2567
  }
2568

2569
  if (simplify_ite) {
58,751✔
2570
    aux = check_arithge_simplifies(tbl, t, simplify_ite);
55,291✔
2571
    if (aux != NULL_TERM) {
55,291✔
2572
      return aux;
26✔
2573
    }
2574
  }
2575

2576
  return arith_geq_atom(tbl, t);
58,725✔
2577
}
2578

2579

2580
/*
2581
 * Construct the atom (b == 0) then reset b.
2582
 *
2583
 * Normalize b first.
2584
 * - simplify to true if b is the zero polynomial
2585
 * - simplify to false if b is constant and non-zero
2586
 * - rewrite to (t1 == t2) if that's possible.
2587
 * - otherwise, create a polynomial term t from b
2588
 *   and return the atom (t == 0).
2589
 */
2590
term_t mk_direct_arith_eq0(term_table_t *tbl, rba_buffer_t *b, bool simplify_ite) {
72,734✔
2591
  mono_t *m[2], *m1, *m2;
2592
  pprod_t *r1, *r2;
2593
  rational_t r0;
2594
  term_t t1, t2, t;
2595
  uint32_t n;
2596

2597
  assert(b->ptbl == tbl->pprods);
2598

2599
  n = b->nterms;
72,734✔
2600
  if (n == 0) {
72,734✔
2601
    // b is zero
2602
    t = true_term;
8,808✔
2603

2604
  } else if (n == 1) {
63,926✔
2605
    /*
2606
     * b is a1 * r1 with a_1 != 0
2607
     * (a1 * r1 == 0) is false if r1 is the empty product
2608
     * (a1 * r1 == 0) simplifies to (r1 == 0) otherwise
2609
     */
2610
    m1 = rba_buffer_root_mono(b);
6,124✔
2611
    r1 = m1->prod;
6,124✔
2612
    assert(q_is_nonzero(&m1->coeff));
2613
    if (r1 == empty_pp) {
6,124✔
2614
      t = false_term;
1,330✔
2615
    } else {
2616
      t1 = pp_is_var(r1) ? var_of_pp(r1) : pprod_term(tbl, r1);
4,794✔
2617
      t = mk_arith_eq0_atom(tbl, t1, simplify_ite); // atom r1 = 0
4,794✔
2618
    }
2619

2620
  } else if (n == 2) {
57,802✔
2621
    /*
2622
     * b is a1 * r1 + a2 * r2
2623
     * Simplifications:
2624
     * - rewrite (b == 0) to (r2 == -a1/a2) if r1 is the empty product
2625
     * - rewrite (b == 0) to (r1 == r2) if a1 + a2 = 0
2626
     */
2627
    rba_buffer_monomial_pair(b, m);
49,304✔
2628
    m1 = m[0];
49,304✔
2629
    m2 = m[1];
49,304✔
2630
    r1 = m1->prod;
49,304✔
2631
    r2 = m2->prod;
49,304✔
2632
    assert(q_is_nonzero(&m1->coeff) && q_is_nonzero(&m2->coeff));
2633

2634
    q_init(&r0);
49,304✔
2635

2636
    if (r1 == empty_pp) {
49,304✔
2637
      q_set_neg(&r0, &m1->coeff);
14,106✔
2638
      q_div(&r0, &m2->coeff);  // r0 is -a1/a2
14,106✔
2639
      t1 = arith_constant(tbl, &r0);
14,106✔
2640
      t2 = pp_is_var(r2) ? var_of_pp(r2) : pprod_term(tbl, r2);
14,106✔
2641
      t = mk_arith_bineq_atom(tbl, t1, t2, simplify_ite);
14,106✔
2642

2643
    } else {
2644
      q_set(&r0, &m1->coeff);
35,198✔
2645
      q_add(&r0, &m2->coeff);
35,198✔
2646
      if (q_is_zero(&r0)) {
35,198✔
2647
        t1 = pp_is_var(r1) ? var_of_pp(r1) : pprod_term(tbl, r1);
33,383✔
2648
        t2 = pp_is_var(r2) ? var_of_pp(r2) : pprod_term(tbl, r2);
33,383✔
2649
        t = mk_arith_bineq_atom(tbl, t1, t2, simplify_ite);
33,383✔
2650

2651
      } else {
2652
        // no simplification
2653
        t = arith_poly(tbl, b);
1,815✔
2654
        t = arith_eq_atom(tbl, t);
1,815✔
2655
      }
2656
    }
2657

2658
    q_clear(&r0);
49,304✔
2659

2660
  } else {
2661
    /*
2662
     * more than 2 monomials: don't simplify
2663
     */
2664
    t = arith_poly(tbl, b);
8,498✔
2665
    t = arith_eq_atom(tbl, t);
8,498✔
2666
  }
2667

2668

2669
  reset_rba_buffer(b);
72,734✔
2670
  assert(good_term(tbl, t) && is_boolean_term(tbl, t));
2671

2672
  return t;
72,734✔
2673
}
2674

2675

2676
/*
2677
 * Construct the atom (b >= 0) then reset b.
2678
 *
2679
 * Normalize b first then check for simplifications.
2680
 * - simplify to true or false if b is a constant
2681
 * - otherwise build a term t from b and return the atom (t >= 0)
2682
 */
2683
term_t mk_direct_arith_geq0(term_table_t *tbl, rba_buffer_t *b, bool simplify_ite) {
61,731✔
2684
  mono_t *m;
2685
  pprod_t *r;
2686
  term_t t;
2687
  uint32_t n;
2688

2689
  assert(b->ptbl == tbl->pprods);
2690

2691
  n = b->nterms;
61,731✔
2692
  if (n == 0) {
61,731✔
2693
    // b is zero
2694
    t = true_term;
1,628✔
2695
  } else if (n == 1) {
60,103✔
2696
    /*
2697
     * b is a * r with a != 0
2698
     * if r is the empty product, (b >= 0) simplifies to true or false
2699
     * otherwise, (b >= 0) simplifies either to r >= 0 or -r >= 0
2700
     */
2701
    m = rba_buffer_root_mono(b); // unique monomial of b
11,871✔
2702
    r = m->prod;
11,871✔
2703
    if (q_is_pos(&m->coeff)) {
11,871✔
2704
      // a > 0
2705
      if (r == empty_pp) {
7,500✔
2706
        t = true_term;
693✔
2707
      } else {
2708
        t = pp_is_var(r) ? var_of_pp(r) : pprod_term(tbl, r);
6,807✔
2709
        t = mk_arith_geq_atom(tbl, t, simplify_ite); // r >= 0
6,807✔
2710
      }
2711
    } else {
2712
      // a < 0
2713
      if (r == empty_pp) {
4,371✔
2714
        t = false_term;
636✔
2715
      } else {
2716
        q_set_minus_one(&m->coeff); // force a := -1
3,735✔
2717
        t = arith_poly(tbl, b);
3,735✔
2718
        t = mk_arith_geq_atom(tbl, t, simplify_ite);
3,735✔
2719
      }
2720
    }
2721

2722
  } else {
2723
    // no simplification (for now).
2724
    // could try to reduce the coefficients?
2725
    t = arith_poly(tbl, b);
48,232✔
2726
    t = mk_arith_geq_atom(tbl, t, simplify_ite);
48,232✔
2727
  }
2728

2729
  reset_rba_buffer(b);
61,731✔
2730
  assert(good_term(tbl, t) && is_boolean_term(tbl, t));
2731

2732
  return t;
61,731✔
2733
}
2734

2735

2736
/*
2737
 * Same thing: using a manager
2738
 */
2739
term_t mk_arith_geq0(term_manager_t *manager, rba_buffer_t *b) {
49,203✔
2740
  return mk_direct_arith_geq0(manager->terms, b, manager->simplify_ite);
49,203✔
2741
}
2742

2743

2744
/*
2745
 * Cheap lift-if decomposition:
2746
 * - decompose (ite c x y) (ite c z u) ---> [c, x, z, y, u]
2747
 * - decompose (ite c x y) z           ---> [c, x, z, y, z]
2748
 * - decompose x (ite c y z)           ---> [c, x, y, x, z]
2749
 *
2750
 * The result is stored into the lift_result_t object:
2751
 * - for example: [c, x, z, y, u] is stored as
2752
 *    cond = c,  left1 = x, left2 = z,  right1 = y, right2 = u
2753
 * - the function return true if the decomposition succeeds, false otherwise
2754
 *
2755
 * NOTE: we don't want to apply these lift-if rules if one or both terms
2756
 * are special if-then-elses.
2757
 */
2758
typedef struct lift_result_s {
2759
  term_t cond;
2760
  term_t left1, left2;
2761
  term_t right1, right2;
2762
} lift_result_t;
2763

2764

2765
static bool check_for_lift_if(term_table_t *tbl, term_t t1, term_t t2, lift_result_t *d) {
×
2766
  composite_term_t *ite1, *ite2;
2767
  term_t cond;
2768

2769
  assert(is_pos_term(t1) && is_pos_term(t2));
2770

2771
  if (term_kind(tbl, t1) == ITE_TERM) {
×
2772
    if (term_kind(tbl, t2) == ITE_TERM) {
×
2773
      // both are (if-then-else ..)
2774
      ite1 = ite_term_desc(tbl, t1);
×
2775
      ite2 = ite_term_desc(tbl, t2);
×
2776

2777
      cond = ite1->arg[0];
×
2778
      if (cond == ite2->arg[0]) {
×
2779
        d->cond = cond;
×
2780
        d->left1 = ite1->arg[1];
×
2781
        d->left2 = ite2->arg[1];
×
2782
        d->right1 = ite1->arg[2];
×
2783
        d->right2 = ite2->arg[2];
×
2784
        return true;
×
2785
      }
2786

2787
    } else {
2788
      // t1 is (if-then-else ..) t2 is not
2789
      ite1 = ite_term_desc(tbl, t1);
×
2790
      d->cond = ite1->arg[0];
×
2791
      d->left1 = ite1->arg[1];
×
2792
      d->left2 = t2;
×
2793
      d->right1 = ite1->arg[2];
×
2794
      d->right2 = t2;
×
2795
      return true;
×
2796

2797
    }
2798
  } else if (term_kind(tbl, t2) == ITE_TERM) {
×
2799
    // t2 is (if-then-else ..) t1 is not
2800

2801
    ite2 = ite_term_desc(tbl, t2);
×
2802
    d->cond = ite2->arg[0];
×
2803
    d->left1 = t1;
×
2804
    d->left2 = ite2->arg[1];
×
2805
    d->right1 = t1;
×
2806
    d->right2 = ite2->arg[2];
×
2807
    return true;
×
2808
  }
2809

2810
 return false;
×
2811
}
2812

2813

2814

2815
/*
2816
 * Store t1 - t2 in buffer b
2817
 */
2818
static void mk_arith_diff(term_manager_t *manager, rba_buffer_t *b, term_t t1, term_t t2) {
74,839✔
2819
  reset_rba_buffer(b);
74,839✔
2820
  rba_buffer_add_term(b, manager->terms, t1);
74,839✔
2821
  rba_buffer_sub_term(b, manager->terms, t2);
74,839✔
2822
}
74,839✔
2823

2824

2825
/*
2826
 * Build the term (ite c (aritheq t1 t2) (aritheq t3 t4))
2827
 * - c is a boolean term
2828
 * - t1, t2, t3, t4 are all arithmetic terms
2829
 */
2830
static term_t mk_lifted_aritheq(term_manager_t *manager, term_t c, term_t t1, term_t t2, term_t t3, term_t t4) {
×
2831
  rba_buffer_t *b;
2832
  term_t left, right;
2833

2834
  b = term_manager_get_arith_buffer(manager);
×
2835

2836
  mk_arith_diff(manager, b, t1, t2);
×
2837
  left = mk_arith_eq0(manager, b);
×
2838
  mk_arith_diff(manager, b, t3, t4);
×
2839
  right = mk_arith_eq0(manager, b);
×
2840

2841
  return mk_bool_ite(manager, c, left, right);
×
2842
}
2843

2844
// Variant: apply the cheap lift-if rules recursively
2845
static term_t mk_lifted_aritheq_recur(term_manager_t *manager, term_t c, term_t t1, term_t t2, term_t t3, term_t t4) {
×
2846
  term_t left, right;
2847

2848
  left = mk_arith_eq(manager, t1, t2);
×
2849
  right = mk_arith_eq(manager, t3, t4);
×
2850
  return mk_bool_ite(manager, c, left, right);
×
2851
}
2852

2853

2854
/*
2855
 * Build the term (ite c (arithge t1 t2) (arithge t3 t4))
2856
 * - c is a boolean term
2857
 * - t1, t2, t3, t4 are all arithmetic terms
2858
 */
2859
static term_t mk_lifted_arithgeq(term_manager_t *manager, term_t c, term_t t1, term_t t2, term_t t3, term_t t4) {
×
2860
  rba_buffer_t *b;
2861
  term_t left, right;
2862

2863
  b = term_manager_get_arith_buffer(manager);
×
2864

2865
  mk_arith_diff(manager, b, t1, t2);
×
2866
  left = mk_arith_geq0(manager, b);
×
2867
  mk_arith_diff(manager, b, t3, t4);
×
2868
  right = mk_arith_geq0(manager, b);
×
2869

2870
  return mk_bool_ite(manager, c, left, right);
×
2871
}
2872

2873
// Variant: apply the cheap lift-if rules recursively
2874
static term_t mk_lifted_arithgeq_recur(term_manager_t *manager, term_t c, term_t t1, term_t t2, term_t t3, term_t t4) {
×
2875
  term_t left, right;
2876

2877
  left = mk_arith_geq(manager, t1, t2);
×
2878
  right = mk_arith_geq(manager, t3, t4);
×
2879
  return mk_bool_ite(manager, c, left, right);
×
2880
}
2881

2882

2883

2884
/*
2885
 * BINARY ATOMS
2886
 */
2887

2888
/*
2889
 * Equality term (= t1 t2)
2890
 *
2891
 * Apply the cheap lift-if rules
2892
 *  (eq x (ite c y z))  ---> (ite c (eq x y) (eq x z)) provided x is not an if term
2893
 *  (eq (ite c x y) z)) ---> (ite c (eq x z) (eq y z)) provided z is not an if term
2894
 *  (eq (ite c x y) (ite c z u)) --> (ite c (eq x z) (eq y u))
2895
 *
2896
 */
2897
term_t mk_arith_eq(term_manager_t *manager, term_t t1, term_t t2) {
71,333✔
2898
  rba_buffer_t *b;
2899
  lift_result_t tmp;
2900

2901
  assert(is_arithmetic_term(manager->terms, t1) &&
2902
         is_arithmetic_term(manager->terms, t2));
2903

2904
  if (false && manager->simplify_ite && check_for_lift_if(manager->terms, t1, t2, &tmp)) {
2905
    if (true) {
2906
      return mk_lifted_aritheq(manager, tmp.cond, tmp.left1, tmp.left2, tmp.right1, tmp.right2);
2907
    } else {
2908
      return mk_lifted_aritheq_recur(manager, tmp.cond, tmp.left1, tmp.left2, tmp.right1, tmp.right2);
2909
    }
2910
  }
2911

2912
  b = term_manager_get_arith_buffer(manager);
71,333✔
2913
  mk_arith_diff(manager, b, t1, t2);
71,333✔
2914
  return mk_arith_eq0(manager, b);
71,333✔
2915
}
2916

2917

2918
/*
2919
 * Inequality: (>= t1 t2)
2920
 *
2921
 * Try the cheap lift-if rules.
2922
 */
2923
term_t mk_arith_geq(term_manager_t *manager, term_t t1, term_t t2) {
3,413✔
2924
  rba_buffer_t *b;
2925
  lift_result_t tmp;
2926

2927
  assert(is_arithmetic_term(manager->terms, t1) &&
2928
         is_arithmetic_term(manager->terms, t2));
2929

2930
  if (false && check_for_lift_if(manager->terms, t1, t2, &tmp)) {
2931
    if (true) {
2932
      return mk_lifted_arithgeq(manager, tmp.cond, tmp.left1, tmp.left2, tmp.right1, tmp.right2);
2933
    } else {
2934
      return mk_lifted_arithgeq_recur(manager, tmp.cond, tmp.left1, tmp.left2, tmp.right1, tmp.right2);
2935
    }
2936
  }
2937

2938
  b = term_manager_get_arith_buffer(manager);
3,413✔
2939
  mk_arith_diff(manager, b, t1, t2);
3,413✔
2940
  return mk_arith_geq0(manager, b);
3,413✔
2941
}
2942

2943

2944
/*
2945
 * Derived atoms
2946
 */
2947

2948
// t1 != t2  -->  not (t1 == t2)
2949
term_t mk_arith_neq(term_manager_t *manager, term_t t1, term_t t2) {
15,685✔
2950
  return opposite_term(mk_arith_eq(manager, t1, t2));
15,685✔
2951
}
2952

2953
// t1 <= t2  -->  t2 >= t1
2954
term_t mk_arith_leq(term_manager_t *manager, term_t t1, term_t t2) {
337✔
2955
  return mk_arith_geq(manager, t2, t1);
337✔
2956
}
2957

2958
// t1 > t2  -->  not (t2 >= t1)
2959
term_t mk_arith_gt(term_manager_t *manager, term_t t1, term_t t2) {
49✔
2960
  return opposite_term(mk_arith_geq(manager, t2, t1));
49✔
2961
}
2962

2963
// t1 < t2  -->  not (t1 >= t2)
2964
term_t mk_arith_lt(term_manager_t *manager, term_t t1, term_t t2) {
43✔
2965
  return opposite_term(mk_arith_geq(manager, t1, t2));
43✔
2966
}
2967

2968

2969
// b != 0   -->  not (b == 0)
2970
term_t mk_arith_neq0(term_manager_t *manager, rba_buffer_t *b) {
×
2971
  return opposite_term(mk_arith_eq0(manager, b));
×
2972
}
2973

2974
// b <= 0  -->  (- b) >= 0
2975
term_t mk_arith_leq0(term_manager_t *manager, rba_buffer_t *b) {
23,283✔
2976
  rba_buffer_negate(b);
23,283✔
2977
  return mk_arith_geq0(manager, b);
23,283✔
2978
}
2979

2980
// b > 0  -->  not (b <= 0)
2981
term_t mk_arith_gt0(term_manager_t *manager, rba_buffer_t *b) {
7,765✔
2982
  return opposite_term(mk_arith_leq0(manager, b));
7,765✔
2983
}
2984

2985
// b < 0  -->  not (b >= 0)
2986
term_t mk_arith_lt0(term_manager_t *manager, rba_buffer_t *b) {
8,449✔
2987
  return opposite_term(mk_arith_geq0(manager, b));
8,449✔
2988
}
2989

2990

2991
/*
2992
 * Variants: use a term t
2993
 */
2994
// t == 0
2995
term_t mk_arith_term_eq0(term_manager_t *manager, term_t t) {
1,399✔
2996
  rba_buffer_t *b;
2997

2998
  b = term_manager_get_arith_buffer(manager);
1,399✔
2999
  reset_rba_buffer(b);
1,399✔
3000
  rba_buffer_add_term(b, manager->terms, t);
1,399✔
3001

3002
  return mk_arith_eq0(manager, b);
1,399✔
3003
}
3004

3005
// t != 0
3006
term_t mk_arith_term_neq0(term_manager_t *manager, term_t t) {
×
3007
  rba_buffer_t *b;
3008

3009
  b = term_manager_get_arith_buffer(manager);
×
3010
  reset_rba_buffer(b);
×
3011
  rba_buffer_add_term(b, manager->terms, t);
×
3012

3013
  return mk_arith_neq0(manager, b);
×
3014
}
3015

3016
// t >= 0
3017
term_t mk_arith_term_geq0(term_manager_t *manager, term_t t) {
1,364✔
3018
  rba_buffer_t *b;
3019

3020
  b = term_manager_get_arith_buffer(manager);
1,364✔
3021
  reset_rba_buffer(b);
1,364✔
3022
  rba_buffer_add_term(b, manager->terms, t);
1,364✔
3023

3024
  return mk_arith_geq0(manager, b);
1,364✔
3025
}
3026

3027
// t <= 0
3028
term_t mk_arith_term_leq0(term_manager_t *manager, term_t t) {
×
3029
  rba_buffer_t *b;
3030

3031
  b = term_manager_get_arith_buffer(manager);
×
3032
  reset_rba_buffer(b);
×
3033
  rba_buffer_add_term(b, manager->terms, t);
×
3034

3035
  return mk_arith_leq0(manager, b);
×
3036
}
3037

3038
// t > 0
3039
term_t mk_arith_term_gt0(term_manager_t *manager, term_t t) {
1,442✔
3040
  rba_buffer_t *b;
3041

3042
  b = term_manager_get_arith_buffer(manager);
1,442✔
3043
  reset_rba_buffer(b);
1,442✔
3044
  rba_buffer_add_term(b, manager->terms, t);
1,442✔
3045

3046
  return mk_arith_gt0(manager, b);
1,442✔
3047
}
3048

3049
// t < 0
3050
term_t mk_arith_term_lt0(term_manager_t *manager, term_t t) {
1,345✔
3051
  rba_buffer_t *b;
3052

3053
  b = term_manager_get_arith_buffer(manager);
1,345✔
3054
  reset_rba_buffer(b);
1,345✔
3055
  rba_buffer_add_term(b, manager->terms, t);
1,345✔
3056

3057
  return mk_arith_lt0(manager, b);
1,345✔
3058
}
3059

3060

3061
/*
3062
 * Variant: use a term table
3063
 */
3064
// b <= 0  -->  (- b) >= 0
3065
term_t mk_direct_arith_leq0(term_table_t *tbl, rba_buffer_t *b, bool simplify_ite) {
3,099✔
3066
  rba_buffer_negate(b);
3,099✔
3067
  return mk_direct_arith_geq0(tbl, b, simplify_ite);
3,099✔
3068
}
3069

3070
// b > 0  -->  not (b <= 0)
3071
term_t mk_direct_arith_gt0(term_table_t *tbl, rba_buffer_t *b, bool simplify_ite) {
2,573✔
3072
  return opposite_term(mk_direct_arith_leq0(tbl, b, simplify_ite));
2,573✔
3073
}
3074

3075
// b < 0  -->  not (b >= 0)
3076
term_t mk_direct_arith_lt0(term_table_t *tbl, rba_buffer_t *b, bool simplify_ite) {
9,429✔
3077
  return opposite_term(mk_direct_arith_geq0(tbl, b, simplify_ite));
9,429✔
3078
}
3079

3080

3081
/*
3082
 * Make root atom.
3083
 */
3084
static
3085
term_t mk_arith_root_atom_aux(term_table_t* terms, uint32_t k, term_t x, rba_buffer_t *p_b, root_atom_rel_t r, bool simplify_ite) {
579✔
3086
  uint32_t degree = rba_buffer_degree(p_b);
579✔
3087
  uint32_t degree_x = rba_buffer_var_degree(p_b, x);
579✔
3088
  uint32_t n;
3089
  rational_t root;
3090
  term_t p, root_term, result = NULL_TERM;
579✔
3091
  polynomial_t* p_poly;
3092

3093
  (void)degree_x;
3094
  assert(degree > 0);
3095
  assert(k < degree_x);
3096

3097
  if (degree == 1) {
579✔
3098
    // Special case, these are just regular inequalities:
3099
    // p = ax + b, solve p = 0, x = -b/a, resulting in x r -b/a
3100
    n = p_b->nterms;
×
3101
    assert(n > 0);
3102
    if (n == 1) {
×
3103
      // p = ax => root is 0
3104
      // reuse p_b buffer for x
3105
      reset_rba_buffer(p_b);
×
3106
      switch (r) {
×
3107
      case ROOT_ATOM_LT:
×
3108
        rba_buffer_add_term(p_b, terms, x);
×
3109
        result = mk_direct_arith_lt0(terms, p_b, simplify_ite);
×
3110
        break;
×
3111
      case ROOT_ATOM_LEQ:
×
3112
        rba_buffer_add_term(p_b, terms, x);
×
3113
        result = mk_direct_arith_leq0(terms, p_b, simplify_ite);
×
3114
        break;
×
3115
      case ROOT_ATOM_EQ:
×
3116
        result = mk_arith_eq0_atom(terms, x, simplify_ite);
×
3117
        break;
×
3118
      case ROOT_ATOM_NEQ:
×
3119
        result = mk_arith_eq0_atom(terms, x, simplify_ite);
×
3120
        result = opposite_term(result);
×
3121
        break;
×
3122
      case ROOT_ATOM_GEQ:
×
3123
        rba_buffer_add_term(p_b, terms, x);
×
3124
        result = mk_direct_arith_geq0(terms, p_b, simplify_ite);
×
3125
        break;
×
3126
      case ROOT_ATOM_GT:
×
3127
        rba_buffer_add_term(p_b, terms, x);
×
3128
        result = mk_direct_arith_gt0(terms, p_b, simplify_ite);
×
3129
        break;
×
3130
      }
3131
    } else {
3132
      // p = ax + b => root is -b/a
3133
      // we might still be multivariate, so have to check
3134
      // we are degree 1, so we can have:
3135
      // - one term, i.e. a*x
3136
      // - two terms, i.e. a*x + b, but not a*x + b*y
3137
      // - three terms or more is not univariate
3138
      p = mk_direct_arith_term(terms, p_b);
×
3139
      assert(term_kind(terms, p) == ARITH_POLY);
3140
      p_poly = poly_term_desc(terms, p);
×
3141
      if (p_poly->nterms <= 2) {
×
3142
        if (p_poly->nterms == 1 || p_poly->mono[0].var == const_idx || p_poly->mono[1].var == const_idx) {
×
3143

3144
          q_init(&root);
×
3145
          if (p_poly->nterms == 2) {
×
3146
            // ax + b
3147
            if (p_poly->mono[0].var == const_idx) {
×
3148
              q_set(&root, &p_poly->mono[0].coeff);
×
3149
              q_div(&root, &p_poly->mono[1].coeff);
×
3150
            } else {
3151
              assert(p_poly->mono[1].var == const_idx);
3152
              q_set(&root, &p_poly->mono[1].coeff);
×
3153
              q_div(&root, &p_poly->mono[0].coeff);
×
3154
            }
3155
            q_neg(&root);
×
3156
          } else {
3157
            // ax, root = 0
3158
          }
3159

3160
          // reuse p_b buffer for x
3161
          reset_rba_buffer(p_b);
×
3162

3163
          switch (r) {
×
3164
          case ROOT_ATOM_LT:
×
3165
            rba_buffer_add_term(p_b, terms, x);
×
3166
            rba_buffer_sub_const(p_b, &root);
×
3167
            result = mk_direct_arith_lt0(terms, p_b, simplify_ite);
×
3168
            break;
×
3169
          case ROOT_ATOM_LEQ:
×
3170
            rba_buffer_add_term(p_b, terms, x);
×
3171
            rba_buffer_sub_const(p_b, &root);
×
3172
            result = mk_direct_arith_leq0(terms, p_b, simplify_ite);
×
3173
            break;
×
3174
          case ROOT_ATOM_EQ:
×
3175
            root_term = arith_constant(terms, &root);
×
3176
            result = mk_arith_bineq_atom(terms, x, root_term, simplify_ite);
×
3177
            break;
×
3178
          case ROOT_ATOM_NEQ:
×
3179
            root_term = arith_constant(terms, &root);
×
3180
            result = mk_arith_bineq_atom(terms, x, root_term, simplify_ite);
×
3181
            result = opposite_term(result);
×
3182
            break;
×
3183
          case ROOT_ATOM_GEQ:
×
3184
            rba_buffer_add_term(p_b, terms, x);
×
3185
            rba_buffer_sub_const(p_b, &root);
×
3186
            result = mk_direct_arith_geq0(terms, p_b, simplify_ite);
×
3187
            break;
×
3188
          case ROOT_ATOM_GT:
×
3189
            rba_buffer_add_term(p_b, terms, x);
×
3190
            rba_buffer_sub_const(p_b, &root);
×
3191
            result = mk_direct_arith_gt0(terms, p_b, simplify_ite);
×
3192
            break;
×
3193
          }
3194
        } else {
3195
          // not linear univariate
3196
          result = arith_root_atom(terms, k, x, p, r);
×
3197
        }
3198
      } else {
3199
        // not linear univariate
3200
        result = arith_root_atom(terms, k, x, p, r);
×
3201
      }
3202
    }
3203
  } else {
3204
    term_t p = mk_direct_arith_term(terms, p_b);
579✔
3205
    result = arith_root_atom(terms, k, x, p, r);
579✔
3206
  }
3207

3208
  return result;
579✔
3209
}
3210

3211
term_t mk_direct_arith_root_atom(rba_buffer_t* b, term_table_t* terms, uint32_t k, term_t x, term_t p, root_atom_rel_t r, bool simplify_ite) {
579✔
3212
  reset_rba_buffer(b);
579✔
3213
  rba_buffer_add_term(b, terms, p);
579✔
3214
  return mk_arith_root_atom_aux(terms, k, x, b, r, simplify_ite);
579✔
3215
}
3216

3217
term_t mk_arith_root_atom(term_manager_t* manager, uint32_t k, term_t x, term_t p, root_atom_rel_t r) {
579✔
3218
  rba_buffer_t *b;
3219
  b = term_manager_get_arith_buffer(manager);
579✔
3220
  return mk_direct_arith_root_atom(b, manager->terms, k, x, p, r, manager->simplify_ite);
579✔
3221
}
3222

3223
term_t mk_arith_root_atom_lt(term_manager_t *manager, uint32_t k, term_t x, term_t p) {
×
3224
  return mk_arith_root_atom(manager, k, x, p, ROOT_ATOM_LT);
×
3225
}
3226

3227
term_t mk_arith_root_atom_leq(term_manager_t *manager, uint32_t k, term_t x, term_t p) {
×
3228
  return mk_arith_root_atom(manager, k, x, p, ROOT_ATOM_LEQ);
×
3229
}
3230

3231
term_t mk_arith_root_atom_eq(term_manager_t *manager, uint32_t k, term_t x, term_t p) {
×
3232
return mk_arith_root_atom(manager, k, x, p, ROOT_ATOM_EQ);
×
3233
}
3234

3235
term_t mk_arith_root_atom_neq(term_manager_t *manager, uint32_t k, term_t x, term_t p) {
×
3236
  return mk_arith_root_atom(manager, k, x, p, ROOT_ATOM_NEQ);
×
3237
}
3238

3239
term_t mk_arith_root_atom_gt(term_manager_t *manager, uint32_t k, term_t x, term_t p) {
×
3240
  return mk_arith_root_atom(manager, k, x, p, ROOT_ATOM_GT);
×
3241
}
3242

3243
term_t mk_arith_root_atom_geq(term_manager_t *manager, uint32_t k, term_t x, term_t p) {
×
3244
  return mk_arith_root_atom(manager, k, x, p, ROOT_ATOM_GEQ);
×
3245
}
3246

3247
term_t mk_direct_arith_root_atom_lt(rba_buffer_t* b, term_table_t* terms, uint32_t k, term_t x, term_t p, bool simplify_ite) {
×
3248
  return mk_direct_arith_root_atom(b, terms, k, x, p, ROOT_ATOM_LT, simplify_ite);
×
3249
}
3250

3251
term_t mk_direct_arith_root_atom_leq(rba_buffer_t* b, term_table_t* terms, uint32_t k, term_t x, term_t p, bool simplify_ite) {
×
3252
  return mk_direct_arith_root_atom(b, terms, k, x, p, ROOT_ATOM_LEQ, simplify_ite);
×
3253
}
3254

3255
term_t mk_direct_arith_root_atom_eq(rba_buffer_t* b, term_table_t* terms, uint32_t k, term_t x, term_t p, bool simplify_ite) {
×
3256
  return mk_direct_arith_root_atom(b, terms, k, x, p, ROOT_ATOM_EQ, simplify_ite);
×
3257
}
3258

3259

3260
/*
3261
 * ARITHMETIC FUNCTIONS
3262
 */
3263

3264
/*
3265
 * Auxiliary function: compute -t
3266
 */
3267
static term_t mk_arith_opposite(term_manager_t *manager, term_t t) {
×
3268
  rba_buffer_t *b;
3269
  term_table_t *tbl;
3270

3271
  tbl = manager->terms;
×
3272
  b = term_manager_get_arith_buffer(manager);
×
3273
  reset_rba_buffer(b);
×
3274
  rba_buffer_sub_term(b, tbl, t); // b := -t
×
3275
  return arith_buffer_to_term(tbl, b);
×
3276
}
3277

3278
/*
3279
 * Auxiliary function: compute 1/q * t
3280
 */
3281
static term_t mk_arith_div_by_constant(term_manager_t *manager, term_t t, const rational_t *q) {
×
3282
  rba_buffer_t *b;
3283
  term_table_t *tbl;
3284

3285
  assert(q_is_nonzero(q));
3286

3287
  tbl = manager->terms;
×
3288
  b = term_manager_get_arith_buffer(manager);
×
3289
  reset_rba_buffer(b);
×
3290
  rba_buffer_add_term(b, tbl, t); // b := t
×
3291
  rba_buffer_div_const(b, q);
×
3292
  return arith_buffer_to_term(tbl, b);
×
3293
}
3294

3295

3296
/*
3297
 * Rational division: (/ t1 t2)
3298
 *
3299
 * Simplifications:
3300
 *    (/ t1 1)   -->    t1
3301
 *    (/ t1 -1)  -->  - t1
3302
 *    (/ t1 t2)  -->  (1/t2) * t1  if t2 is a non-zero constant
3303
 *
3304
 */
3305
term_t mk_arith_rdiv(term_manager_t *manager, term_t t1, term_t t2) {
2,705✔
3306
  term_table_t *tbl;
3307
  rational_t *q;
3308
  term_t t;
3309

3310
  tbl = manager->terms;
2,705✔
3311
  t = NULL_TERM;
2,705✔
3312

3313
  if (term_kind(tbl, t2) == ARITH_CONSTANT) {
2,705✔
3314
    q = rational_term_desc(tbl, t2);
4✔
3315
    if (q_is_one(q)) {
4✔
3316
      t = t1;
×
3317
    } else if (q_is_minus_one(q)) {
4✔
3318
      t = mk_arith_opposite(manager, t1);
×
3319
    } else if (q_is_nonzero(q)) {
4✔
3320
      t = mk_arith_div_by_constant(manager, t1, q); // q is safe to use here
×
3321
    }
3322
  }
3323

3324
  // default
3325
  if (t == NULL_TERM) {
2,705✔
3326
    t = arith_rdiv(tbl, t1, t2);
2,705✔
3327
  }
3328

3329
  return t;
2,705✔
3330
}
3331

3332

3333
/*
3334
 * (is_int t):
3335
 *
3336
 * Simplifications:
3337
 *  if t has type integer --> true
3338
 *  if t is a non-integer term --> false
3339
 *  (is_int (abs t)) --> (is_int t)
3340
 *
3341
 * Could do more with polynomials
3342
 */
3343
term_t mk_arith_is_int(term_manager_t *manager, term_t t) {
1✔
3344
  term_table_t *tbl;
3345

3346
  tbl = manager->terms;
1✔
3347
  if (is_integer_term(tbl, t)) {
1✔
3348
    return true_term;
×
3349
  }
3350
  if (arith_term_is_not_integer(tbl, t)) {
1✔
3351
    return false_term;
×
3352
  }
3353

3354
  switch (term_kind(tbl, t)) {
1✔
3355
  case ARITH_ABS:
×
3356
    t = arith_abs_arg(tbl, t);
×
3357
    break;
×
3358

3359
    // MORE TO BE DONE
3360
  default:
1✔
3361
    break;
1✔
3362
  }
3363

3364
  return arith_is_int(tbl, t);
1✔
3365
}
3366

3367
/*
3368
 * (abs t):
3369
 *
3370
 * Simplifications:
3371
 * - if t is known to be non-negative --> t
3372
 * - if t is known to be negative --> (- t)
3373
 * - the first rule ensures (abs (abs t)) --> (abs t)
3374
 */
3375
term_t mk_arith_abs(term_manager_t *manager, term_t t) {
27✔
3376
  term_table_t *tbl;
3377

3378
  tbl = manager->terms;
27✔
3379

3380
  if (arith_term_is_nonneg(tbl, t, manager->simplify_ite)) return t;
27✔
3381

3382
  if (arith_term_is_nonpos(tbl, t, manager->simplify_ite)) return mk_arith_opposite(manager, t);
16✔
3383

3384
  return arith_abs(tbl, t);
16✔
3385
}
3386

3387

3388
/*
3389
 * FLOOR AND CEIL
3390
 */
3391

3392
/*
3393
 * Floor/ceil of a rational constant
3394
 */
3395
static term_t arith_constant_floor(term_manager_t *manager, rational_t *q) {
×
3396
  rational_t *aux;
3397

3398
  aux = &manager->r0;
×
3399
  q_set(aux, q);
×
3400
  q_floor(aux);
×
3401
  q_normalize(aux);
×
3402

3403
  return arith_constant(manager->terms, aux);
×
3404
}
3405

3406
static term_t arith_constant_ceil(term_manager_t *manager, rational_t *q) {
×
3407
  rational_t *aux;
3408

3409
  aux = &manager->r0;
×
3410
  q_set(aux, q);
×
3411
  q_ceil(aux);
×
3412
  q_normalize(aux);
×
3413

3414
  return arith_constant(manager->terms, aux);
×
3415
}
3416

3417

3418

3419
/*
3420
 * (floor t) and (ceil t)
3421
 * - if t is an integer --> t
3422
 * - otherwise, build the term.
3423
 *
3424
 * Could do more: rewrite t as <integer> + <rest> then
3425
 *  (floor t) = <integer> + (floor <rest>)
3426
 *  (ceil t) = <integer> + (ceil <rest>)
3427
 * Not clear whether that would help.
3428
 */
3429
term_t mk_arith_floor(term_manager_t *manager, term_t t) {
5✔
3430
  term_table_t *tbl;
3431

3432
  tbl = manager->terms;
5✔
3433
  if (is_integer_term(tbl, t)) return t;
5✔
3434

3435
  if (term_kind(tbl, t) == ARITH_CONSTANT) {
5✔
3436
    return arith_constant_floor(manager, rational_term_desc(tbl, t));
×
3437
  }
3438

3439
  return arith_floor(tbl, t);
5✔
3440
}
3441

3442
term_t mk_arith_ceil(term_manager_t *manager, term_t t) {
×
3443
  term_table_t *tbl;
3444

3445
  tbl = manager->terms;
×
3446
  if (is_integer_term(tbl, t)) return t;
×
3447

3448
  if (term_kind(tbl, t) == ARITH_CONSTANT) {
×
3449
    return arith_constant_ceil(manager, rational_term_desc(tbl, t));
×
3450
  }
3451

3452
  return arith_ceil(manager->terms, t);
×
3453
}
3454

3455

3456
/*
3457
 * DIV and MOD
3458
 *
3459
 * Intended semantics for div and mod:
3460
 * - if y > 0 then div(x, y) is floor(x/y)
3461
 * - if y < 0 then div(x, y) is ceil(x/y)
3462
 * - 0 <= rem(x, y) < y
3463
 * - x = y * div(x, y) + rem(x, y)
3464
 * These operations are defined for any x and non-zero y.
3465
 * The terms x and y are not required to be integers.
3466
 */
3467

3468
/*
3469
 * Division and mod of two rationals
3470
 * - q2 is the divisor
3471
 */
3472
static term_t arith_constant_div(term_manager_t *manager, rational_t *q1, rational_t *q2) {
2✔
3473
  rational_t *aux;
3474

3475
  aux = &manager->r0;
2✔
3476
  q_smt2_div(aux, q1, q2);
2✔
3477
  q_normalize(aux);
2✔
3478

3479
  return arith_constant(manager->terms, aux);
2✔
3480
}
3481

3482
static term_t arith_constant_mod(term_manager_t *manager, rational_t *q1, rational_t *q2) {
64✔
3483
  rational_t *aux;
3484

3485
  aux = &manager->r0;
64✔
3486
  q_smt2_mod(aux, q1, q2);
64✔
3487
  q_normalize(aux);
64✔
3488

3489
  return arith_constant(manager->terms, aux);
64✔
3490
}
3491

3492

3493
/*
3494
 * Integer division and mod
3495
 *
3496
 * Simplifications:
3497
 *    (div x  1) -->   x if x is an integer
3498
 *    (div x -1) --> - x if x is an integer
3499
 *
3500
 *    (mod x  1) -->   0 if x is an integer
3501
 *    (mod x -1) -->   0 if x is an integer
3502
 */
3503
term_t mk_arith_idiv(term_manager_t *manager, term_t t1, term_t t2) {
184✔
3504
  term_table_t *tbl;
3505
  rational_t *q;
3506
  term_t t;
3507

3508
  tbl = manager->terms;
184✔
3509

3510
  t = NULL_TERM;
184✔
3511

3512
  // Special cases
3513
  if (term_kind(tbl, t2) == ARITH_CONSTANT) {
184✔
3514
    q = rational_term_desc(tbl, t2);
174✔
3515
    if (q_is_nonzero(q)) {
174✔
3516
      if (q_is_one(q) && is_integer_term(tbl, t1)) {
168✔
3517
        t = t1;
×
3518
      } else if (q_is_minus_one(q) && is_integer_term(tbl, t1)) {
168✔
3519
        t = mk_arith_opposite(manager, t1); // - t1
×
3520
      } else if (term_kind(tbl, t1) == ARITH_CONSTANT) {
168✔
3521
        t = arith_constant_div(manager, rational_term_desc(tbl, t1), q);
2✔
3522
      }
3523
    }
3524
  }
3525

3526
  // Default case
3527
  if (t == NULL_TERM) {
184✔
3528
    t = arith_idiv(tbl, t1, t2);
182✔
3529
  }
3530

3531
  return t;
184✔
3532
}
3533

3534
term_t mk_arith_mod(term_manager_t *manager, term_t t1, term_t t2) {
667✔
3535
  term_table_t *tbl;
3536
  rational_t *q;
3537
  term_t t;
3538

3539
  tbl = manager->terms;
667✔
3540

3541
  t = NULL_TERM;
667✔
3542

3543
  // Special case
3544
  if (term_kind(tbl, t2) == ARITH_CONSTANT) {
667✔
3545
    q = rational_term_desc(tbl, t2);
505✔
3546
    if (q_is_nonzero(q)) {
505✔
3547
      if ((q_is_one(q) || q_is_minus_one(q)) && is_integer_term(tbl, t1)) {
503✔
3548
        t = zero_term;
×
3549
      } else if (term_kind(tbl, t1) == ARITH_CONSTANT) {
503✔
3550
        t = arith_constant_mod(manager, rational_term_desc(tbl, t1), q);
64✔
3551
      }
3552
    }
3553
  }
3554

3555
  if (t == NULL_TERM) {
667✔
3556
    t = arith_mod(tbl, t1, t2);
603✔
3557
  }
3558

3559
  return t;
667✔
3560
}
3561

3562

3563
/*
3564
 * DIVISIBILITY TEST
3565
 */
3566

3567
/*
3568
 * Force divisor to be positive: build -q
3569
 */
3570
static term_t neg_rational(term_manager_t *manager, rational_t *q) {
×
3571
  rational_t *aux;
3572

3573
  aux = &manager->r0;
×
3574
  q_set_neg(aux, q);
×
3575
  q_normalize(aux);
×
3576

3577
  return arith_constant(manager->terms, aux);
×
3578
}
3579

3580
/*
3581
 * t1 must be a rational constant
3582
 *
3583
 * Simplifications:
3584
 *    (divides 0 t2) ---> (t2 == 0)
3585
 *    (divides 1 t2) ---> (is_int t2)
3586
 *   (divides -1 t2) ---> (is_int t2)
3587
 *
3588
 * If t1 is negative:
3589
 *   (divides t1 t2) ---> (divides (- t1) t2)
3590
 */
3591
term_t mk_arith_divides(term_manager_t *manager, term_t t1, term_t t2) {
14✔
3592
  term_table_t *tbl;
3593
  rational_t *q;
3594
  term_t t;
3595

3596
  tbl = manager->terms;
14✔
3597
  assert(term_kind(tbl, t1) == ARITH_CONSTANT);
3598

3599
  q = rational_term_desc(tbl, t1);
14✔
3600

3601
  if (q_is_zero(q)) {
14✔
3602
    t = mk_arith_eq0_atom(tbl, t2, manager->simplify_ite);
×
3603
  } else if (q_is_one(q) || q_is_minus_one(q)) {
14✔
3604
    t = mk_arith_is_int(manager, t2);
×
3605
  } else {
3606

3607
    switch (term_kind(tbl, t2)) {
14✔
3608
    case ARITH_CONSTANT:
×
3609
      t = false_term;
×
3610
      if (q_divides(q, rational_term_desc(tbl, t2))) {
×
3611
        t = true_term;
×
3612
      }
3613
      break;
×
3614

3615
    default:
14✔
3616
      // force t1 to be positive
3617
      if (q_is_neg(q)) {
14✔
3618
        t1 = neg_rational(manager, q);
×
3619
      }
3620
      t = arith_divides(tbl, t1, t2);
14✔
3621
      break;
14✔
3622
    }
3623
  }
3624

3625
  return t;
14✔
3626
}
3627

3628
term_t mk_direct_arith_root_atom_neq(rba_buffer_t* b, term_table_t* terms, uint32_t k, term_t x, term_t p, bool simplify_ite) {
×
3629
  return mk_direct_arith_root_atom(b, terms, k, x, p, ROOT_ATOM_NEQ, simplify_ite);
×
3630
}
3631

3632
term_t mk_direct_arith_root_atom_gt(rba_buffer_t* b, term_table_t* terms, uint32_t k, term_t x, term_t p, bool simplify_ite) {
×
3633
  return mk_direct_arith_root_atom(b, terms, k, x, p, ROOT_ATOM_GT, simplify_ite);
×
3634
}
3635

3636
term_t mk_direct_arith_root_atom_geq(rba_buffer_t* b, term_table_t* terms, uint32_t k, term_t x, term_t p, bool simplify_ite) {
×
3637
  return mk_direct_arith_root_atom(b, terms, k, x, p, ROOT_ATOM_GEQ, simplify_ite);
×
3638
}
3639

3640

3641
/*
3642
 * Finite field Arithmetic
3643
 */
3644

3645
term_t mk_arith_ff_eq0(term_manager_t *manager, rba_buffer_t *b, const rational_t *mod) {
1,354✔
3646
  return mk_direct_arith_ff_eq0(manager->terms, b, mod, manager->simplify_ite);
1,354✔
3647
}
3648

3649
term_t mk_arith_ff_neq0(term_manager_t *manager, rba_buffer_t *b, const rational_t *mod) {
327✔
3650
  return opposite_term(mk_arith_ff_eq0(manager, b, mod));
327✔
3651
}
3652

3653
term_t mk_arith_ff_term_eq0(term_manager_t *manager, term_t t) {
934✔
3654
  rba_buffer_t *b;
3655

3656
  assert(is_finitefield_term(manager->terms, t));
3657

3658
  b = term_manager_get_arith_buffer(manager);
934✔
3659
  reset_rba_buffer(b);
934✔
3660
  rba_buffer_add_term(b, manager->terms, t);
934✔
3661

3662
  return mk_arith_ff_eq0(manager, b, finitefield_term_order(manager->terms, t));
934✔
3663
}
3664

3665
term_t mk_arith_ff_term_neq0(term_manager_t *manager, term_t t) {
327✔
3666
  rba_buffer_t *b;
3667

3668
  assert(is_finitefield_term(manager->terms, t));
3669

3670
  b = term_manager_get_arith_buffer(manager);
327✔
3671
  reset_rba_buffer(b);
327✔
3672
  rba_buffer_add_term(b, manager->terms, t);
327✔
3673

3674
  return mk_arith_ff_neq0(manager, b, finitefield_term_order(manager->terms, t));
327✔
3675
}
3676

3677
term_t mk_arith_ff_eq(term_manager_t *manager, term_t t1, term_t t2) {
93✔
3678
  rba_buffer_t *b;
3679

3680
  assert(is_finitefield_term(manager->terms, t1) &&
3681
         is_finitefield_term(manager->terms, t2));
3682
  assert(compatible_types(manager->types, term_type(manager->terms, t1), term_type(manager->terms, t2)));
3683

3684
  b = term_manager_get_arith_buffer(manager);
93✔
3685
  mk_arith_diff(manager, b, t1, t2); // use regular arith diff
93✔
3686
  return mk_arith_ff_eq0(manager, b, finitefield_term_order(manager->terms, t1));
93✔
3687
}
3688

3689
term_t mk_arith_ff_neq(term_manager_t *manager, term_t t1, term_t t2) {
×
3690
  return opposite_term(mk_arith_ff_eq(manager, t1, t2));
×
3691
}
3692

3693
static term_t mk_arith_ff_eq0_atom(term_table_t *tbl, term_t t, bool simplify_ite) {
356✔
3694
  assert(is_finitefield_term(tbl, t));
3695

3696
  if (arith_ff_term_is_nonzero(tbl, t, simplify_ite)) {
356✔
3697
    return false_term;
×
3698
  }
3699

3700
  if (simplify_ite) {
3701
    // TODO implement simplification
3702
  }
3703

3704
  return arith_ff_eq_atom(tbl, t);
356✔
3705
}
3706

3707
static term_t mk_arith_ff_bineq_atom(term_table_t *tbl, term_t t1, term_t t2, bool simplify_ite) {
243✔
3708
  term_t aux;
3709

3710
  assert(is_finitefield_term(tbl, t1) && is_finitefield_term(tbl, t2));
3711

3712
  if (disequal_arith_ff_terms(tbl, t1, t2, simplify_ite)) {
243✔
3713
    return false_term;
×
3714
  }
3715

3716
  if (simplify_ite) {
3717
    // TODO implement simplification
3718
  }
3719

3720
  // normalize: put the smallest term on the left
3721
  if (t1 > t2) {
243✔
3722
    aux = t1; t1 = t2; t2 = aux;
115✔
3723
  }
3724

3725
  return arith_ff_bineq_atom(tbl, t1, t2);
243✔
3726
}
3727

3728
/*
3729
 * Construct the atom (b == 0) then reset b.
3730
 *
3731
 * Normalize b first.
3732
 * - simplify to true if b is the zero polynomial
3733
 * - simplify to false if b is constant and non-zero
3734
 * - rewrite to (t1 == t2) if that's possible.
3735
 * - otherwise, create a polynomial term t from b
3736
 *   and return the atom (t == 0).
3737
 */
3738
term_t mk_direct_arith_ff_eq0(term_table_t *tbl, rba_buffer_t *b, const rational_t *mod, bool simplify_ite) {
1,354✔
3739
  mono_t *m[2], *m1, *m2;
3740
  pprod_t *r1, *r2;
3741
  rational_t r0;
3742
  term_t t1, t2, t;
3743
  uint32_t n;
3744

3745
  assert(b->ptbl == tbl->pprods);
3746

3747
  // normalize the tree wrt. to mod
3748
  rba_buffer_mod_const(b, mod);
1,354✔
3749

3750
  n = b->nterms;
1,354✔
3751
  if (n == 0) {
1,354✔
3752
    // b is zero
3753
    t = true_term;
27✔
3754

3755
  } else if (n == 1) {
1,327✔
3756
    /*
3757
     * b is a1 * r1 with a_1 != 0
3758
     * (a1 * r1 == 0) is false if r1 is the empty product
3759
     * (a1 * r1 == 0) simplifies to (r1 == 0) otherwise
3760
     */
3761
    m1 = rba_buffer_root_mono(b);
359✔
3762
    r1 = m1->prod;
359✔
3763
    assert(q_is_nonzero_mod(&m1->coeff, mod));
3764
    if (r1 == empty_pp) {
359✔
3765
      t = false_term;
3✔
3766
    } else {
3767
      t1 = pp_is_var(r1) ? var_of_pp(r1) : pprod_term(tbl, r1);
356✔
3768
      t = mk_arith_ff_eq0_atom(tbl, t1, simplify_ite); // atom r1 = 0
356✔
3769
    }
3770

3771
  } else if (n == 2) {
968✔
3772
    /*
3773
     * b is a1 * r1 + a2 * r2
3774
     * Simplifications:
3775
     * - rewrite (b == 0) to (r2 == -a1/a2) if r1 is the empty product
3776
     * - rewrite (b == 0) to (r1 == r2) if a1 + a2 = 0
3777
     */
3778
    rba_buffer_monomial_pair(b, m);
549✔
3779
    m1 = m[0];
549✔
3780
    m2 = m[1];
549✔
3781
    r1 = m1->prod;
549✔
3782
    r2 = m2->prod;
549✔
3783
    assert(q_is_nonzero_mod(&m1->coeff, mod) && q_is_nonzero_mod(&m2->coeff, mod));
3784

3785
    q_init(&r0);
549✔
3786

3787
    if (r1 == empty_pp) {
549✔
3788
      q_set(&r0, &m2->coeff);  // r0 = a2
243✔
3789
      q_inv_mod(&r0, mod);         // r0 = a2^-1
243✔
3790
      q_mul(&r0, &m1->coeff);  // r0 = a1*a2^-1
243✔
3791
      q_neg(&r0);                  // r0 = -a1*a2^-1
243✔
3792
      q_integer_rem(&r0, mod);
243✔
3793

3794
      t1 = arith_ff_constant(tbl, &r0, mod);
243✔
3795
      t2 = pp_is_var(r2) ? var_of_pp(r2) : pprod_term(tbl, r2);
243✔
3796
      t = mk_arith_ff_bineq_atom(tbl, t1, t2, simplify_ite);
243✔
3797

3798
    } else {
3799
      q_set(&r0, &m1->coeff);
306✔
3800
      q_add(&r0, &m2->coeff);
306✔
3801
      if (q_is_zero(&r0)) {
306✔
3802
        t1 = pp_is_var(r1) ? var_of_pp(r1) : pprod_term(tbl, r1);
×
3803
        t2 = pp_is_var(r2) ? var_of_pp(r2) : pprod_term(tbl, r2);
×
3804
        t = mk_arith_ff_bineq_atom(tbl, t1, t2, simplify_ite);
×
3805

3806
      } else {
3807
        // no simplification
3808
        t = arith_ff_poly(tbl, b, mod);
306✔
3809
        t = arith_ff_eq_atom(tbl, t);
306✔
3810
      }
3811
    }
3812

3813
    q_clear(&r0);
549✔
3814

3815
  } else {
3816
    /*
3817
     * more than 2 monomials: don't simplify
3818
     */
3819
    t = arith_ff_poly(tbl, b, mod);
419✔
3820
    t = arith_ff_eq_atom(tbl, t);
419✔
3821
  }
3822

3823
  reset_rba_buffer(b);
1,354✔
3824
  assert(good_term(tbl, t) && is_boolean_term(tbl, t));
3825

3826
  return t;
1,354✔
3827
}
3828

3829

3830
/****************
3831
 *  EQUALITIES  *
3832
 ***************/
3833

3834
/*
3835
 * Bitvector equality and disequality
3836
 */
3837
term_t mk_bveq(term_manager_t *manager, term_t t1, term_t t2) {
311,785✔
3838
  return mk_bitvector_eq(manager, t1, t2);
311,785✔
3839
}
3840

3841
term_t mk_bvneq(term_manager_t *manager, term_t t1, term_t t2) {
96,467✔
3842
  return opposite_term(mk_bitvector_eq(manager, t1, t2));
96,467✔
3843
}
3844

3845

3846
/*
3847
 * Generic equality: convert to boolean, arithmetic, or bitvector equality
3848
 */
3849
term_t mk_eq(term_manager_t *manager, term_t t1, term_t t2) {
6,476,819✔
3850
  term_table_t *tbl;
3851
  term_t aux;
3852

3853
  tbl = manager->terms;
6,476,819✔
3854

3855
  if (is_boolean_term(tbl, t1)) {
6,476,819✔
3856
    assert(is_boolean_term(tbl, t2));
3857
    return mk_iff(manager, t1, t2);
204,392✔
3858
  }
3859

3860
  if (is_arithmetic_term(tbl, t1)) {
6,272,427✔
3861
    assert(is_arithmetic_term(tbl, t2));
3862
    return mk_arith_eq(manager, t1, t2);
54,782✔
3863
  }
3864

3865
  if (is_finitefield_term(tbl, t1)) {
6,217,645✔
3866
    assert(is_finitefield_term(tbl, t2));
3867
    return mk_arith_ff_eq(manager, t1, t2);
93✔
3868
  }
3869

3870
  if (is_bitvector_term(tbl, t1)) {
6,217,552✔
3871
    assert(is_bitvector_term(tbl, t2));
3872
    return mk_bveq(manager, t1, t2);
192,898✔
3873
  }
3874

3875
  // general case
3876
  if (t1 == t2) return true_term;
6,024,654✔
3877
  if (disequal_terms(tbl, t1, t2, manager->simplify_ite)) {
5,206,895✔
3878
    return false_term;
24✔
3879
  }
3880

3881
  // put smaller index on the left
3882
  if (t1 > t2) {
5,206,871✔
3883
    aux = t1; t1 = t2; t2 = aux;
2,010,781✔
3884
  }
3885

3886
  return eq_term(tbl, t1, t2);
5,206,871✔
3887
}
3888

3889

3890
/*
3891
 * Generic disequality.
3892
 *
3893
 * We don't want to return (not mk_eq(manager, t1, t2)) because
3894
 * that could miss some simplifications if t1 and t2 are Boolean.
3895
 */
3896
term_t mk_neq(term_manager_t *manager, term_t t1, term_t t2) {
403,074✔
3897
  term_table_t *tbl;
3898
  term_t aux;
3899

3900
  tbl = manager->terms;
403,074✔
3901

3902
  if (is_boolean_term(tbl, t1)) {
403,074✔
3903
    assert(is_boolean_term(tbl, t2));
3904
    return mk_binary_xor(manager, t1, t2);
61✔
3905
  }
3906

3907
  if (is_arithmetic_term(tbl, t1)) {
403,013✔
3908
    assert(is_arithmetic_term(tbl, t2));
3909
    return mk_arith_neq(manager, t1, t2);
15,685✔
3910
  }
3911

3912
  if (is_finitefield_term(tbl, t1)) {
387,328✔
3913
    assert(is_finitefield_term(tbl, t2));
3914
    return mk_arith_ff_neq(manager, t1, t2);
×
3915
  }
3916

3917
  if (is_bitvector_term(tbl, t1)) {
387,328✔
3918
    assert(is_bitvector_term(tbl, t2));
3919
    return mk_bvneq(manager, t1, t2);
96,467✔
3920
  }
3921

3922
  // general case
3923
  if (t1 == t2) return false_term;
290,861✔
3924
  if (disequal_terms(tbl, t1, t2, manager->simplify_ite)) {
290,846✔
3925
    return true_term;
26✔
3926
  }
3927

3928
  // put smaller index on the left
3929
  if (t1 > t2) {
290,820✔
3930
    aux = t1; t1 = t2; t2 = aux;
26,644✔
3931
  }
3932

3933
  return opposite_term(eq_term(tbl, t1, t2));
290,820✔
3934
}
3935

3936

3937
/*
3938
 * Array disequality:
3939
 * - given two arrays a and b of n terms, build the term
3940
 *   (or (/= a[0] b[0]) ... (/= a[n-1] b[n-1]))
3941
 */
3942
term_t mk_array_neq(term_manager_t *manager, uint32_t n, const term_t a[], const term_t b[]) {
×
3943
  uint32_t i;
3944
  term_t *aux;
3945

3946
  resize_ivector(&manager->vector0, n);
×
3947
  aux = manager->vector0.data;
×
3948

3949
  for (i=0; i<n; i++) {
×
3950
    aux[i] = mk_neq(manager, a[i], b[i]);
×
3951
  }
3952
  return mk_or(manager, n, aux);
×
3953
}
3954

3955

3956
/*
3957
 * Array equality:
3958
 * - given two arrays a and b of n term, build
3959
 *   (and (= a[0] b[0]) ... (= a[n-1] b[n-1])
3960
 */
3961
term_t mk_array_eq(term_manager_t *manager, uint32_t n, const term_t a[], const term_t b[]) {
×
3962
  return opposite_term(mk_array_neq(manager, n, a, b));
×
3963
}
3964

3965

3966

3967

3968
/*****************************
3969
 *   GENERIC CONSTRUCTORS    *
3970
 ****************************/
3971

3972
/*
3973
 * When constructing a term of singleton type tau, we return the
3974
 * representative for tau (except for variables).
3975
 */
3976

3977
/*
3978
 * Constant of type tau and index i
3979
 * - tau must be uninterpreted or scalar type
3980
 * - i must be non-negative and smaller than the size of tau
3981
 *   (which matters only if tau is scalar)
3982
 */
3983
term_t mk_constant(term_manager_t *manager, type_t tau, int32_t i) {
13✔
3984
  term_t t;
3985

3986
  assert(i >= 0);
3987
  t = constant_term(manager->terms, tau, i);
13✔
3988
  if (is_unit_type(manager->types, tau)) {
13✔
3989
    store_unit_type_rep(manager->terms, tau, t);
5✔
3990
  }
3991

3992
  return t;
13✔
3993
}
3994

3995

3996
/*
3997
 * New uninterpreted term of type tau
3998
 * - i.e., this creates a fresh global variable
3999
 */
4000
term_t mk_uterm(term_manager_t *manager, type_t tau) {
85,233✔
4001
  if (is_unit_type(manager->types, tau)) {
85,233✔
4002
    return get_unit_type_rep(manager->terms, tau);
1✔
4003
  }
4004

4005
  return new_uninterpreted_term(manager->terms, tau);
85,232✔
4006
}
4007

4008

4009
/*
4010
 * New variable of type tau
4011
 * - this creates a fresh variable (for quantifiers)
4012
 */
4013
term_t mk_variable(term_manager_t *manager, type_t tau) {
3,149✔
4014
  return new_variable(manager->terms, tau);
3,149✔
4015
}
4016

4017

4018

4019
/*
4020
 * Function application:
4021
 * - fun must have arity n
4022
 * - arg = array of n arguments
4023
 * - the argument types much match the domain of f
4024
 *
4025
 * Simplifications if fun is an update term:
4026
 *   ((update f (a_1 ... a_n) v) a_1 ... a_n)   -->  v
4027
 *   ((update f (a_1 ... a_n) v) x_1 ... x_n)   -->  (f x_1 ... x_n)
4028
 *         if x_i must disequal a_i
4029
 *
4030
 */
4031
term_t mk_application(term_manager_t *manager, term_t fun, uint32_t n, const term_t arg[]) {
116,685✔
4032
  term_table_t *tbl;
4033
  type_table_t *types;
4034
  composite_term_t *update;
4035
  type_t tau;
4036

4037
  tbl = manager->terms;
116,685✔
4038
  types = manager->types;
116,685✔
4039

4040
  // singleton function type
4041
  tau = term_type(tbl, fun);
116,685✔
4042
  if (is_unit_type(types, tau)) {
116,685✔
4043
    return get_unit_type_rep(tbl, function_type_range(types, tau));
×
4044
  }
4045

4046
  while (term_kind(tbl, fun) == UPDATE_TERM) {
121,639✔
4047
    assert(is_pos_term(fun));
4048
    // fun is (update f (a_1 ... a_n) v)
4049
    update = update_term_desc(tbl, fun);
6,287✔
4050
    assert(update->arity == n+2);
4051

4052
    /*
4053
     * update->arg[0] is f
4054
     * update->arg[1] to update->arg[n] = a_1 to a_n
4055
     * update->arg[n+1] is v
4056
     */
4057
    if (equal_term_arrays(n, update->arg + 1, arg)) {
6,287✔
4058
      return update->arg[n+1];
561✔
4059
    }
4060

4061
    if (disequal_term_arrays(tbl, n, update->arg + 1, arg, manager->simplify_ite)) {
5,726✔
4062
      // ((update f (a_1 ... a_n) v) x_1 ... x_n) ---> (f x_1 ... x_n)
4063
      // repeat simplification if f is an update term again
4064
      fun = update->arg[0];
4,954✔
4065
    } else {
4066
      break;
772✔
4067
    }
4068
  }
4069

4070
  return app_term(tbl, fun, n, arg);
116,124✔
4071
}
4072

4073

4074

4075
/*
4076
 * Attempt to simplify (mk-tuple arg[0] .... arg[n-1]):
4077
 * return x if arg[i] = (select i x) for i=0 ... n-1 and x is a tuple term of arity n
4078
 * return NULL_TERM otherwise
4079
 */
4080
static term_t simplify_mk_tuple(term_table_t *tbl, uint32_t n, const term_t arg[]) {
135✔
4081
  uint32_t i;
4082
  term_t x, a;
4083

4084
  a = arg[0];
135✔
4085
  if (is_neg_term(a) ||
270✔
4086
      term_kind(tbl, a) != SELECT_TERM ||
160✔
4087
      select_term_index(tbl, a) != 0) {
25✔
4088
    return NULL_TERM;
110✔
4089
  }
4090

4091
  // arg[0] is (select 0 x)
4092
  x = select_term_arg(tbl, a);
25✔
4093
  if (tuple_type_arity(tbl->types, term_type(tbl, x)) != n) {
25✔
4094
    // x does not have arity n
4095
    return NULL_TERM;
15✔
4096
  }
4097

4098
  for (i = 1; i<n; i++) {
10✔
4099
    a = arg[i];
10✔
4100
    if (is_neg_term(a) ||
20✔
4101
        term_kind(tbl, a) != SELECT_TERM ||
20✔
4102
        select_term_index(tbl, a) != i ||
10✔
4103
        select_term_arg(tbl, a) != x) {
×
4104
      // arg[i] is not (select i x)
4105
      return NULL_TERM;
10✔
4106
    }
4107
  }
4108

4109
  return x;
×
4110
}
4111

4112

4113
/*
4114
 * Tuple constructor:
4115
 * - arg = array of n terms
4116
 * - n must be positive and no more than YICES_MAX_ARITY
4117
 *
4118
 * Simplification:
4119
 *   (mk_tuple (select 0 x) ... (select n-1 x)) --> x
4120
 * provided x is a tuple of arity n
4121
 */
4122
term_t mk_tuple(term_manager_t *manager, uint32_t n, const term_t arg[]) {
135✔
4123
  term_table_t *tbl;
4124
  term_t x;
4125
  type_t tau;
4126

4127
  tbl = manager->terms;
135✔
4128
  x = simplify_mk_tuple(tbl, n, arg);
135✔
4129
  if (x == NULL_TERM) {
135✔
4130
    // not simplified
4131
    x = tuple_term(tbl, n, arg);
135✔
4132

4133
    // check whether x is unique element of its type
4134
    tau = term_type(tbl, x);
135✔
4135
    if (is_unit_type(manager->types, tau)) {
135✔
4136
      store_unit_type_rep(tbl, tau, x);
×
4137
    }
4138
  }
4139

4140
  return x;
135✔
4141
}
4142

4143

4144
/*
4145
 * Projection: component i of tuple.
4146
 * - tuple must have tuple type
4147
 * - i must be between 0 and the number of components in the tuple
4148
 *   type - 1
4149
 *
4150
 * Simplification: (select i (mk_tuple x_1 ... x_n))  --> x_i
4151
 */
4152
term_t mk_select(term_manager_t *manager, uint32_t index, term_t tuple) {
2,010✔
4153
  term_table_t *tbl;
4154
  type_table_t *types;
4155
  type_t tau;
4156
  term_t x;
4157

4158
  // simplify
4159
  if (term_kind(manager->terms, tuple) == TUPLE_TERM) {
2,010✔
4160
    x = composite_term_arg(manager->terms, tuple, index);
926✔
4161
  } else {
4162
    // check for singleton type
4163
    tbl = manager->terms;
1,084✔
4164
    types = manager->types;
1,084✔
4165
    tau = term_type(tbl, tuple);
1,084✔
4166
    tau = tuple_type_component(types, tau, index);
1,084✔
4167

4168
    if (is_unit_type(types, tau)) {
1,084✔
4169
      x = get_unit_type_rep(tbl, tau);
270✔
4170
    } else {
4171
      x = select_term(tbl, index, tuple);
814✔
4172
    }
4173
  }
4174

4175
  return x;
2,010✔
4176
}
4177

4178

4179
/*
4180
 * Function update: (update f (arg[0] ... arg[n-1]) new_v)
4181
 * - f must have function type and arity n
4182
 * - new_v's type must be a subtype of f's range
4183
 *
4184
 * Simplifications:
4185
 *  (update (update f (a_1 ... a_n) v) (a_1 ... a_n) v') --> (update f (a_1 ... a_n) v')
4186
 *  (update f (a_1 ... a_n) (f a_1 ... a_n)) --> f
4187
 */
4188
term_t mk_update(term_manager_t *manager, term_t fun, uint32_t n, const term_t arg[], term_t new_v) {
16,383✔
4189
  term_table_t *tbl;
4190
  composite_term_t *update, *app;
4191
  type_t tau;
4192

4193
  tbl = manager->terms;
16,383✔
4194

4195
  // singleton function type
4196
  tau = term_type(tbl, fun);
16,383✔
4197
  if (is_unit_type(manager->types, tau)) {
16,383✔
4198
    assert(unit_type_rep(tbl, tau) == fun);
4199
    return fun;
×
4200
  }
4201

4202
  // try simplification
4203
  while (term_kind(tbl, fun) == UPDATE_TERM) {
16,800✔
4204
    // fun is (update f b_1 ... b_n v)
4205
    assert(is_pos_term(fun));
4206
    update = update_term_desc(tbl, fun);
13,103✔
4207
    assert(update->arity == n+2);
4208

4209
    if (equal_term_arrays(n, update->arg + 1, arg)) {
13,103✔
4210
      // b_1 = a_1, ..., b_n = a_n so
4211
      // (update (update fun b_1 ... b_n v0) a_1 ... a_n new_v)) --> (update fun (a_1 ... a_n) new_v)
4212
      fun = update->arg[0];
417✔
4213
    } else {
4214
      break;
12,686✔
4215
    }
4216
  }
4217

4218
  // build (update fun a_1 .. a_n new_v): try second simplification
4219
  if (is_pos_term(new_v) && term_kind(tbl, new_v) == APP_TERM) {
16,383✔
4220
    app = app_term_desc(tbl, new_v);
733✔
4221
    if (app->arity == n+1 && app->arg[0] == fun &&
773✔
4222
        equal_term_arrays(n, app->arg + 1, arg)) {
40✔
4223
      // new_v is (apply fun a_1 ... a_n)
4224
      return fun;
13✔
4225
    }
4226
  }
4227

4228
  return update_term(tbl, fun, n, arg, new_v);
16,370✔
4229
}
4230

4231

4232

4233
/*
4234
 * Distinct: all terms arg[0] ... arg[n-1] must have compatible types
4235
 * - n must be positive and no more than YICES_MAX_ARITY
4236
 *
4237
 * (distinct t1 ... t_n):
4238
 *
4239
 * if n == 1 --> true
4240
 * if n == 2 --> (diseq t1 t2)
4241
 * if t_i and t_j are equal --> false
4242
 * if all are disequal --> true
4243
 *
4244
 * More simplifications uses type information,
4245
 *  (distinct f g h) --> false if f g h are boolean.
4246
 */
4247
term_t mk_distinct(term_manager_t *manager, uint32_t n, term_t arg[]) {
9,227✔
4248
  uint32_t i;
4249
  type_t tau;
4250

4251
  if (n == 1) {
9,227✔
4252
    return true_term;
×
4253
  }
4254

4255
  if (n == 2) {
9,227✔
4256
    return mk_neq(manager, arg[0], arg[1]);
8,691✔
4257
  }
4258

4259
  // check for finite types
4260
  tau = term_type(manager->terms, arg[0]);
536✔
4261
  if (type_card(manager->types, tau) < n && type_card_is_exact(manager->types, tau)) {
536✔
4262
    // card exact implies that tau is finite (and small)
4263
    return false_term;
44✔
4264
  }
4265

4266

4267
  // check if two of the terms are equal
4268
  int_array_sort(arg, n);
492✔
4269
  for (i=1; i<n; i++) {
5,683✔
4270
    if (arg[i] == arg[i-1]) {
5,296✔
4271
      return false_term;
105✔
4272
    }
4273
  }
4274

4275
  // WARNING: THIS CAN BE EXPENSIVE
4276
  if (pairwise_disequal_terms(manager->terms, n, arg, manager->simplify_ite)) {
387✔
4277
    return true_term;
97✔
4278
  }
4279

4280
  return distinct_term(manager->terms, n, arg);
290✔
4281
}
4282

4283

4284
/*
4285
 * (tuple-update tuple index new_v) is (tuple with component i set to new_v)
4286
 *
4287
 * If new_v is (select t i) then
4288
 *  (tuple-update t i v) is t
4289
 *
4290
 * If tuple is (mk-tuple x_0 ... x_i ... x_n-1) then
4291
 *  (tuple-update t i v) is (mk-tuple x_0 ... v ... x_n-1)
4292
 *
4293
 * Otherwise,
4294
 *  (tuple-update t i v) is (mk-tuple (select t 0) ... v  ... (select t n-1))
4295
 *
4296
 */
4297
static term_t mk_tuple_aux(term_manager_t *manager, term_t tuple, uint32_t n, uint32_t i, term_t v) {
553✔
4298
  term_table_t *tbl;
4299
  composite_term_t *desc;
4300
  term_t *a;
4301
  term_t t;
4302
  uint32_t j;
4303

4304
  tbl = manager->terms;
553✔
4305

4306
  if (is_pos_term(v) && term_kind(tbl, v) == SELECT_TERM &&
553✔
4307
      select_term_arg(tbl, v) == tuple && select_term_index(tbl, v) == i) {
×
4308
    return tuple;
×
4309
  }
4310

4311
  // use vector0 as buffer:
4312
  resize_ivector(&manager->vector0, n);
553✔
4313
  a = manager->vector0.data;
553✔
4314

4315
  if (term_kind(tbl, tuple) == TUPLE_TERM) {
553✔
4316
    desc = tuple_term_desc(tbl, tuple);
112✔
4317
    for (j=0; j<n; j++) {
336✔
4318
      if (i == j) {
224✔
4319
        a[j] = v;
112✔
4320
      } else {
4321
        a[j] = desc->arg[j];
112✔
4322
      }
4323
    }
4324
  } else {
4325
    for (j=0; j<n; j++) {
994✔
4326
      if (i == j) {
553✔
4327
        a[j] = v;
441✔
4328
      } else {
4329
        a[j] = select_term(tbl, j, tuple);
112✔
4330
      }
4331
    }
4332
  }
4333

4334
  t = tuple_term(tbl, n, a);
553✔
4335

4336
  // cleanup
4337
  ivector_reset(&manager->vector0);
553✔
4338

4339
  return t;
553✔
4340
}
4341

4342

4343
/*
4344
 * Tuple update: replace component i of tuple by new_v
4345
 */
4346
term_t mk_tuple_update(term_manager_t *manager, term_t tuple, uint32_t index, term_t new_v) {
553✔
4347
  uint32_t n;
4348
  type_t tau;
4349

4350
  // singleton type
4351
  tau = term_type(manager->terms, tuple);
553✔
4352
  if (is_unit_type(manager->types, tau)) {
553✔
4353
    assert(unit_type_rep(manager->terms, tau) == tuple);
4354
    return tuple;
×
4355
  }
4356

4357
  n = tuple_type_arity(manager->types, tau);
553✔
4358
  return mk_tuple_aux(manager, tuple, n, index, new_v);
553✔
4359
}
4360

4361

4362

4363
/*
4364
 * Quantifiers:
4365
 * - n = number of variables (n must be positive and no more than YICES_MAX_VAR)
4366
 * - all variables v[0 ... n-1] must be distinct
4367
 * - body must be a Boolean term
4368
 *
4369
 * Simplification
4370
 *  (forall (x_1::t_1 ... x_n::t_n) true) --> true
4371
 *  (forall (x_1::t_1 ... x_n::t_n) false) --> false (types are nonempty)
4372
 *
4373
 *  (exists (x_1::t_1 ... x_n::t_n) true) --> true
4374
 *  (exists (x_1::t_1 ... x_n::t_n) false) --> false (types are nonempty)
4375
 */
4376
term_t mk_forall(term_manager_t *manager, uint32_t n, const term_t var[], term_t body) {
23,012✔
4377
  if (body == true_term) return body;
23,012✔
4378
  if (body == false_term) return body;
23,010✔
4379

4380
  return forall_term(manager->terms, n, var, body);
23,010✔
4381
}
4382

4383
term_t mk_exists(term_manager_t *manager, uint32_t n, const term_t var[], term_t body) {
526✔
4384
  if (body == true_term) return body;
526✔
4385
  if (body == false_term) return body;
461✔
4386

4387
  // (not (forall ... (not body))
4388
  return opposite_term(forall_term(manager->terms, n, var, opposite_term(body)));
461✔
4389
}
4390

4391

4392

4393
/*
4394
 * Lambda term:
4395
 * - n = number of variables
4396
 * - var[0 .. n-1] = variables (must all be distinct)
4397
 *
4398
 * Simplification:
4399
 *   (lambda (x_1::t_1 ... x_n::t_n) (f x_1 ... x_n)) --> f
4400
 *
4401
 * provided f has type [t_1 ... t_n --> sigma]
4402
 */
4403

4404
// check whether var[0 ... n-1] and arg[0 ... n-1] are equal
4405
static bool equal_arrays(const term_t var[], const term_t arg[], uint32_t n) {
98✔
4406
  uint32_t i;
4407

4408
  for (i=0; i<n; i++) {
191✔
4409
    if (var[i] != arg[i]) {
98✔
4410
      return false;
5✔
4411
    }
4412
  }
4413

4414
  return true;
93✔
4415
}
4416

4417
// check whether the domain of f matches the variable types
4418
static bool same_domain(term_table_t *table, term_t f, const term_t var[], uint32_t n) {
93✔
4419
  function_type_t *desc;
4420
  type_t tau;
4421
  uint32_t i;
4422

4423
  tau = term_type(table, f);
93✔
4424
  desc = function_type_desc(table->types, tau);
93✔
4425
  assert(desc->ndom == n);
4426

4427
  for (i=0; i<n; i++) {
186✔
4428
    if (desc->domain[i] != term_type(table, var[i])) {
93✔
4429
      return false;
×
4430
    }
4431
  }
4432

4433
  return true;
93✔
4434
}
4435

4436
term_t mk_lambda(term_manager_t *manager, uint32_t n, const term_t var[], term_t body) {
2,124✔
4437
  term_table_t *tbl;
4438
  composite_term_t *d;
4439
  term_t f;
4440

4441
  assert(0 < n && n <= YICES_MAX_ARITY);
4442

4443
  tbl = manager->terms;
2,124✔
4444
  if (is_pos_term(body) && term_kind(tbl, body) == APP_TERM) {
2,124✔
4445
    d = app_term_desc(tbl, body);
98✔
4446
    if (d->arity == n+1 && equal_arrays(var, d->arg + 1, n)) {
98✔
4447
      f = d->arg[0];
93✔
4448
      if (same_domain(tbl, f, var, n)) {
93✔
4449
        return f;
93✔
4450
      }
4451
    }
4452
  }
4453

4454
  return lambda_term(manager->terms, n, var, body);
2,031✔
4455
}
4456

4457

4458

4459

4460
/*************************
4461
 *  BITVECTOR CONSTANTS  *
4462
 ************************/
4463

4464
/*
4465
 * Convert b to a bitvector constant
4466
 * - normalize b first
4467
 * - b->bitsize must be positive and no more than YICES_MAX_BVSIZE
4468
 * - depending on b->bitsize, this either builds a bv64 constant
4469
 *   or a wide bvconst term (more than 64 bits)
4470
 */
4471
term_t mk_bv_constant(term_manager_t *manager, bvconstant_t *b) {
78,257✔
4472
  uint32_t n;
4473
  uint64_t x;
4474
  term_t t;
4475

4476
  assert(b->bitsize > 0);
4477

4478
  n = b->bitsize;
78,257✔
4479
  bvconst_normalize(b->data, n); // reduce modulo 2^n
78,257✔
4480

4481
  if (n <= 64) {
78,257✔
4482
    if (n <= 32) {
78,201✔
4483
      x = bvconst_get32(b->data);
48,617✔
4484
    } else {
4485
      x = bvconst_get64(b->data);
29,584✔
4486
    }
4487
    t = bv64_constant(manager->terms, n, x);
78,201✔
4488
  } else {
4489
    t = bvconst_term(manager->terms, n, b->data);
56✔
4490
  }
4491

4492
  return t;
78,257✔
4493
}
4494

4495

4496

4497
/***************************
4498
 *  CONVERT BITS TO TERMS  *
4499
 **************************/
4500

4501
/*
4502
 * A bvlogic buffer stores an array of bits in manager->nodes.
4503
 * Function bvlogic_buffer_get_bvarray requires converting bits
4504
 * back to Boolean terms.
4505
 *
4506
 * The nodes data structure is defined in bit_expr.h
4507
 */
4508

4509
/*
4510
 * Recursive function: return the term mapped to node x
4511
 * - compute it if needed then store the result in manager->nodes->map[x]
4512
 */
4513
static term_t map_node_to_term(term_manager_t *manager, node_t x);
4514

4515
/*
4516
 * Get the term mapped to bit b. If node_of(b) is mapped to t then
4517
 * - if b has positive polarity, map_of(b) = t
4518
 * - if b has negative polarity, map_of(b) = not t
4519
 */
4520
static inline term_t map_bit_to_term(term_manager_t *manager, bit_t b) {
4,255,314✔
4521
  return map_node_to_term(manager, node_of_bit(b)) ^ polarity_of(b);
4,255,314✔
4522
}
4523

4524

4525

4526
/*
4527
 * Given two bits b1 = c[0] and b2 = c[1], convert (or b1 b2) to a term
4528
 */
4529
static term_t make_or2(term_manager_t *manager, bit_t *c) {
48,416✔
4530
  term_t x, y;
4531

4532
  x = map_bit_to_term(manager, c[0]);
48,416✔
4533
  y = map_bit_to_term(manager, c[1]);
48,416✔
4534

4535
  assert(is_boolean_term(manager->terms, x) &&
4536
         is_boolean_term(manager->terms, y));
4537

4538
  return mk_binary_or(manager, x, y);
48,416✔
4539
}
4540

4541

4542
/*
4543
 * Same thing for (xor c[0] c[1])
4544
 */
4545
static term_t make_xor2(term_manager_t *manager, bit_t *c) {
11,614✔
4546
  term_t x, y;
4547

4548
  x = map_bit_to_term(manager, c[0]);
11,614✔
4549
  y = map_bit_to_term(manager, c[1]);
11,614✔
4550

4551
  assert(is_boolean_term(manager->terms, x) &&
4552
         is_boolean_term(manager->terms, y));
4553

4554
  return mk_binary_xor(manager, x, y);
11,614✔
4555
}
4556

4557

4558

4559
/*
4560
 * Recursive function: return the term mapped to node x
4561
 * - compute it if needed then store the result in nodes->map[x]
4562
 */
4563
static term_t map_node_to_term(term_manager_t *manager, node_t x) {
4,255,314✔
4564
  node_table_t *nodes;
4565
  term_t t;
4566

4567
  nodes = manager->nodes;
4,255,314✔
4568
  assert(nodes != NULL);
4569

4570
  t = map_of_node(nodes, x);
4,255,314✔
4571
  if (t < 0) {
4,255,314✔
4572
    assert(t == -1);
4573

4574
    switch (node_kind(nodes, x)) {
1,923,755✔
4575
    case CONSTANT_NODE:
357✔
4576
      // x is true
4577
      t = true_term;
357✔
4578
      break;
357✔
4579

4580
    case VARIABLE_NODE:
×
4581
      // x is (var t) for a boolean term t
4582
      t = var_of_node(nodes, x);
×
4583
      break;
×
4584

4585
    case SELECT_NODE:
1,863,368✔
4586
      // x is (select i u) for a bitvector term u
4587
      t = mk_bitextract(manager, var_of_select_node(nodes, x), index_of_select_node(nodes, x));
1,863,368✔
4588
      break;
1,863,368✔
4589

4590
    case OR_NODE:
48,416✔
4591
      t = make_or2(manager, children_of_node(nodes, x));
48,416✔
4592
      break;
48,416✔
4593

4594
    case XOR_NODE:
11,614✔
4595
      t = make_xor2(manager, children_of_node(nodes, x));
11,614✔
4596
      break;
11,614✔
4597

4598
    default:
×
4599
      assert(false);
4600
      abort();
×
4601
      break;
4602
    }
4603

4604
    assert(is_boolean_term(manager->terms, t));
4605
    set_map_of_node(nodes, x, t);
1,923,755✔
4606
  }
4607

4608
  return t;
4,255,314✔
4609
}
4610

4611

4612

4613

4614

4615
/*******************
4616
 *  BVLOGIC TERMS  *
4617
 ******************/
4618

4619
/*
4620
 * Convert buffer b to a bv_constant term
4621
 * - side effect: use bv0
4622
 */
4623
static term_t bvlogic_buffer_get_bvconst(term_manager_t *manager, bvlogic_buffer_t *b) {
962✔
4624
  bvconstant_t *bv;
4625

4626
  assert(bvlogic_buffer_is_constant(b));
4627

4628
  bv = &manager->bv0;
962✔
4629
  bvlogic_buffer_get_constant(b, bv);
962✔
4630
  return bvconst_term(manager->terms, bv->bitsize, bv->data);
962✔
4631
}
4632

4633

4634
/*
4635
 * Convert buffer b to a bv-array term
4636
 */
4637
static term_t bvlogic_buffer_get_bvarray(term_manager_t *manager, bvlogic_buffer_t *b) {
208,772✔
4638
  uint32_t i, n;
4639

4640
  assert(b->nodes == manager->nodes && manager->nodes != NULL);
4641

4642
  // translate each bit of b into a boolean term
4643
  // we store the translation in b->bit
4644
  n = b->bitsize;
208,772✔
4645
  for (i=0; i<n; i++) {
4,344,026✔
4646
    b->bit[i] = map_bit_to_term(manager, b->bit[i]);
4,135,254✔
4647
  }
4648

4649
  // build the term (bvarray b->bit[0] ... b->bit[n-1])
4650
  return bvarray_term(manager->terms, n, b->bit);
208,772✔
4651
}
4652

4653

4654
/*
4655
 * Convert b to a term then reset b.
4656
 * - b must not be empty.
4657
 * - build a bitvector constant if possible
4658
 * - if b is of the form (select 0 t) ... (select k t) and t has bitsize (k+1)
4659
 *   then return t
4660
 * - otherwise build a bitarray term
4661
 */
4662
term_t mk_bvlogic_term(term_manager_t *manager, bvlogic_buffer_t *b) {
338,860✔
4663
  term_t t;
4664
  uint32_t n;
4665

4666
  n = b->bitsize;
338,860✔
4667
  assert(0 < n && n <= YICES_MAX_BVSIZE);
4668

4669
  if (bvlogic_buffer_is_constant(b)) {
338,860✔
4670
    if (n <= 64) {
126,057✔
4671
      // small constant
4672
      t = bv64_constant(manager->terms, n, bvlogic_buffer_get_constant64(b));
125,095✔
4673
    } else {
4674
      // wide constant
4675
      t = bvlogic_buffer_get_bvconst(manager, b);
962✔
4676
    }
4677

4678
  } else {
4679
    t = bvlogic_buffer_get_var(b);
212,803✔
4680
    if (t < 0 || term_bitsize(manager->terms, t) != n) {
212,803✔
4681
      // not a variable
4682
      t = bvlogic_buffer_get_bvarray(manager, b);
208,772✔
4683
    }
4684
  }
4685

4686
  assert(is_bitvector_term(manager->terms, t) &&
4687
         term_bitsize(manager->terms, t) == n);
4688

4689
  bvlogic_buffer_clear(b);
338,860✔
4690

4691
  return t;
338,860✔
4692
}
4693

4694

4695
#if 1
4696

4697
/*
4698
 * Sign extend term t to n bits
4699
 * - t must be a bitvector of less than n bits
4700
 * - n = number of bits in the result
4701
 */
4702
static term_t mk_sign_extend_term(term_manager_t *manager, term_t t, uint32_t n) {
16✔
4703
  bvlogic_buffer_t *b;
4704

4705
  assert(is_bitvector_term(manager->terms, t) &&
4706
         term_bitsize(manager->terms, t) < n);
4707

4708
  b = term_manager_get_bvlogic_buffer(manager);
16✔
4709
  bvlogic_buffer_set_term(b, manager->terms, t);
16✔
4710
  bvlogic_buffer_sign_extend(b, n);
16✔
4711

4712
  return mk_bvlogic_term(manager, b);
16✔
4713
}
4714

4715
#endif
4716

4717

4718
/***************************
4719
 *  BITVECTOR POLYNOMIALS  *
4720
 **************************/
4721

4722
/*
4723
 * Store array [false_term, ..., false_term] into vector v
4724
 */
4725
static void bvarray_set_zero_bv(ivector_t *v, uint32_t n) {
31,629✔
4726
  uint32_t i;
4727

4728
  assert(0 < n && n <= YICES_MAX_BVSIZE);
4729
  resize_ivector(v, n);
31,629✔
4730
  for (i=0; i<n; i++) {
1,671,700✔
4731
    v->data[i] = false_term;
1,640,071✔
4732
  }
4733
}
31,629✔
4734

4735
/*
4736
 * Store constant c into vector v
4737
 * - n = number of bits in c
4738
 */
4739
static void bvarray_copy_constant(ivector_t *v, uint32_t n, uint32_t *c) {
634✔
4740
  uint32_t i;
4741

4742
  assert(0 < n && n <= YICES_MAX_BVSIZE);
4743
  resize_ivector(v, n);
634✔
4744
  for (i=0; i<n; i++) {
1,826,273✔
4745
    v->data[i] = bool2term(bvconst_tst_bit(c, i));
1,825,639✔
4746
  }
4747
}
634✔
4748

4749
/*
4750
 * Same thing for a small constant c
4751
 */
4752
static void bvarray_copy_constant64(ivector_t *v, uint32_t n, uint64_t c) {
120,998✔
4753
  uint32_t i;
4754

4755
  assert(0 < n && n <= 64);
4756
  resize_ivector(v, n);
120,998✔
4757
  for (i=0; i<n; i++) {
5,194,954✔
4758
    v->data[i] = bool2term(tst_bit64(c, i));
5,073,956✔
4759
  }
4760
}
120,998✔
4761

4762

4763
/*
4764
 * Check whether v + c * a can be converted to (v | (a << k))  for some k
4765
 * - return true if that can be done and update v to (v | (a << k))
4766
 * - otherwise, return false and keep v unchanged
4767
 * - a must be an array of n boolean terms
4768
 * - v must also contain n boolean terms
4769
 */
4770
static bool bvarray_check_addmul(ivector_t *v, uint32_t n, uint32_t *c, term_t *a) {
99✔
4771
  uint32_t i, w;
4772
  int32_t k;
4773

4774
  w = (n + 31) >> 5; // number of words in c
99✔
4775
  if (bvconst_is_zero(c, w)) {
99✔
4776
    return true;
×
4777
  }
4778

4779
  k = bvconst_is_power_of_two(c, w);
99✔
4780
  if (k < 0) {
99✔
4781
    return false;
55✔
4782
  }
4783

4784
  // c is 2^k so (c * a) is equal to (a << k)
4785
  // check whether we can convert the addition into a bitwise or,
4786
  // that is, check whether  (v + (a << k)) is equal to (v | (a << k))
4787
  assert(0 <= k && k < n);
4788
  for (i=k; i<n; i++) {
2,289✔
4789
    if (v->data[i] != false_term && a[i-k] != false_term) {
2,269✔
4790
      return false;
24✔
4791
    }
4792
  }
4793

4794
  // update v here
4795
  for (i=k; i<n; i++) {
2,225✔
4796
    if (a[i-k] != false_term) {
2,205✔
4797
      assert(v->data[i] == false_term);
4798
      v->data[i] = a[i-k];
876✔
4799
    }
4800
  }
4801

4802
  return true;
20✔
4803
}
4804

4805

4806
/*
4807
 * Same thing for c stored as a small constant (64 bits at most)
4808
 */
4809
static bool bvarray_check_addmul64(ivector_t *v, uint32_t n, uint64_t c, term_t *a) {
107,873✔
4810
  uint32_t i, k;
4811

4812
  assert(0 < n && n <= 64 && c == norm64(c, n));
4813

4814
  if (c == 0) {
107,873✔
4815
    return true;
×
4816
  }
4817

4818
  k = ctz64(c); // k = index of the rightmost 1 in c
107,873✔
4819
  assert(0 <= k && k <= 63);
4820
  if (c != (((uint64_t) 1) << k)) {
107,873✔
4821
    // c != 2^k
4822
    return false;
41,220✔
4823
  }
4824

4825
  // c is 2^k check whether v + (a << k) is equal to v | (a << k)
4826
  assert(0 <= k && k < n);
4827
  for (i=k; i<n; i++) {
272,654✔
4828
    if (v->data[i] != false_term && a[i-k] != false_term) {
266,277✔
4829
      return false;
60,276✔
4830
    }
4831
  }
4832

4833
  // update v here
4834
  for (i=k; i<n; i++) {
109,448✔
4835
    if (a[i-k] != false_term) {
103,071✔
4836
      assert(v->data[i] == false_term);
4837
      v->data[i] = a[i-k];
64,488✔
4838
    }
4839
  }
4840

4841
  return true;
6,377✔
4842
}
4843

4844

4845

4846
/*
4847
 * Check whether power product r is equal to a bit-array term t
4848
 * - if so return t's descriptor, otherwise return NULL
4849
 */
4850
static composite_term_t *pprod_get_bvarray(term_table_t *tbl, pprod_t *r) {
158,734✔
4851
  composite_term_t *bv;
4852
  term_t t;
4853

4854
  bv = NULL;
158,734✔
4855
  if (pp_is_var(r)) {
158,734✔
4856
    t = var_of_pp(r);
158,602✔
4857
    if (term_kind(tbl, t) == BV_ARRAY) {
158,602✔
4858
      bv = composite_for_idx(tbl, index_of(t));
107,972✔
4859
    }
4860
  }
4861

4862
  return bv;
158,734✔
4863
}
4864

4865

4866
/*
4867
 * Attempt to convert a bvarith buffer to a bv-array term
4868
 * - b = bvarith buffer (list of monomials)
4869
 * - return NULL_TERM if the conversion fails
4870
 * - return a term t if the conversion succeeds.
4871
 * - side effect: use vector0
4872
 */
4873
static term_t convert_bvarith_to_bvarray(term_manager_t *manager, bvarith_buffer_t *b) {
840✔
4874
  composite_term_t *bv;
4875
  bvmlist_t *m;
4876
  ivector_t *v;
4877
  uint32_t n;
4878

4879
  v = &manager->vector0;
840✔
4880

4881
  n = b->bitsize;
840✔
4882
  m = b->list; // first monomial
840✔
4883
  if (m->prod == empty_pp) {
840✔
4884
    // copy constant into v
4885
    bvarray_copy_constant(v, n, m->coeff);
634✔
4886
    m = m->next;
634✔
4887
  } else {
4888
    // initialize v to 0b0000..0
4889
    bvarray_set_zero_bv(v, n);
206✔
4890
  }
4891

4892
  while (m->next != NULL) {
860✔
4893
    bv = pprod_get_bvarray(manager->terms, m->prod);
852✔
4894
    if (bv == NULL) return NULL_TERM;
852✔
4895

4896
    assert(bv->arity == n);
4897

4898
    // try to convert coeff * bv into shift + bitwise or
4899
    if (! bvarray_check_addmul(v, n, m->coeff, bv->arg)) {
99✔
4900
      return NULL_TERM;  // conversion failed
79✔
4901
    }
4902
    m = m->next;
20✔
4903
  }
4904

4905
  // Success: construct a bit array from v
4906
  return bvarray_term(manager->terms, n, v->data);
8✔
4907
}
4908

4909

4910
/*
4911
 * Attempt to convert a bvarith64 buffer to a bv-array term
4912
 * - b = bvarith buffer (list of monomials)
4913
 * - return NULL_TERM if the conversion fails
4914
 * - return a term t if the conversion succeeds.
4915
 * - side effect: use vector0
4916
 */
4917
static term_t convert_bvarith64_to_bvarray(term_manager_t *manager, bvarith64_buffer_t *b) {
152,421✔
4918
  composite_term_t *bv;
4919
  bvmlist64_t *m;
4920
  ivector_t *v;
4921
  uint32_t n;
4922

4923
  v = &manager->vector0;
152,421✔
4924

4925
  n = b->bitsize;
152,421✔
4926
  m = b->list; // first monomial
152,421✔
4927
  if (m->prod == empty_pp) {
152,421✔
4928
    // copy constant into vector0
4929
    bvarray_copy_constant64(v, n, m->coeff);
120,998✔
4930
    m = m->next;
120,998✔
4931
  } else {
4932
    // initialize vector0 to 0
4933
    bvarray_set_zero_bv(v, n);
31,423✔
4934
  }
4935

4936
  while (m->next != NULL) {
158,798✔
4937
    bv = pprod_get_bvarray(manager->terms, m->prod);
157,882✔
4938
    if (bv == NULL) return NULL_TERM;
157,882✔
4939

4940
    assert(bv->arity == n);
4941

4942
    // try to convert coeff * bv into shift + bitwise or
4943
    if (! bvarray_check_addmul64(v, n, m->coeff, bv->arg)) {
107,873✔
4944
      return NULL_TERM;  // conversion failed
101,496✔
4945
    }
4946
    m = m->next;
6,377✔
4947
  }
4948

4949
  // Success: construct a bit array from v
4950
  return bvarray_term(manager->terms, n, v->data);
916✔
4951
}
4952

4953

4954
/*
4955
 * Constant bitvector with all bits 0
4956
 * - n = bitsize (must satisfy 0 < n && n <= YICES_MAX_BVSIZE)
4957
 * - side effect: modify bv0
4958
 */
4959
static term_t make_zero_bv(term_manager_t *manager, uint32_t n) {
104,841✔
4960
  bvconstant_t *bv;
4961

4962
  assert(0 < n && n <= YICES_MAX_BVSIZE);
4963

4964
  bv = &manager->bv0;
104,841✔
4965

4966
  if (n > 64) {
104,841✔
4967
    bvconstant_set_all_zero(bv, n);
91✔
4968
    return bvconst_term(manager->terms, bv->bitsize, bv->data);
91✔
4969
  } else {
4970
    return bv64_constant(manager->terms, n, 0);
104,750✔
4971
  }
4972
}
4973

4974

4975
/*
4976
 * Convert a polynomial buffer to a bitvector terms:
4977
 * - b must use the same pprod as manager (i.e., b->ptbl = manager->pprods)
4978
 * - b may be equal to manager->bvarith_buffer
4979
 * - side effect: b is reset
4980
 *
4981
 * This normalizes b first then check for the following:
4982
 * 1) b reduced to a single variable x: return x
4983
 * 2) b reduced to a power product pp: return pp
4984
 * 3) b is constant, return a BV64_CONSTANT or BV_CONSTANT term
4985
 * 4) b can be converted to a BV_ARRAY term (by converting + and *
4986
 *    to bitwise or and shift): return the BV_ARRAY
4987
 *
4988
 * Otherwise, build a bit-vector polynomial.
4989
 */
4990
term_t mk_bvarith_term(term_manager_t *manager, bvarith_buffer_t *b) {
1,216✔
4991
  bvmlist_t *m;
4992
  pprod_t *r;
4993
  uint32_t n, p, k;
4994
  term_t t;
4995

4996
  assert(b->bitsize > 0);
4997

4998
  bvarith_buffer_normalize(b);
1,216✔
4999

5000
  n = b->bitsize;
1,216✔
5001
  k = (n + 31) >> 5;
1,216✔
5002
  p = b->nterms;
1,216✔
5003
  if (p == 0) {
1,216✔
5004
    // zero
5005
    t = make_zero_bv(manager, n);
80✔
5006
    goto done;
80✔
5007
  }
5008

5009
  if (p == 1) {
1,136✔
5010
    m = b->list; // unique monomial of b
373✔
5011
    r = m->prod;
373✔
5012
    if (r == empty_pp) {
373✔
5013
      // constant
5014
      t = bvconst_term(manager->terms, n, m->coeff);
174✔
5015
      goto done;
174✔
5016
    }
5017
    if (bvconst_is_one(m->coeff, k)) {
199✔
5018
      // power product
5019
      t = pp_is_var(r) ? var_of_pp(r) : pprod_term(manager->terms, r);
122✔
5020
      goto done;
122✔
5021
    }
5022
  }
5023

5024
  // try to convert to a bvarray term
5025
  t = convert_bvarith_to_bvarray(manager, b);
840✔
5026
  if (t == NULL_TERM) {
840✔
5027
    // conversion failed: build a bvpoly
5028
    t = bv_poly(manager->terms, b);
832✔
5029
  }
5030

5031
 done:
8✔
5032
  reset_bvarith_buffer(b);
1,216✔
5033
  assert(is_bitvector_term(manager->terms, t) &&
5034
         term_bitsize(manager->terms, t) == n);
5035

5036
  return t;
1,216✔
5037
}
5038

5039

5040
#if 0
5041
/*
5042
 * PROVISIONAL FOR TESTING
5043
 */
5044
#include <inttypes.h>
5045
#include <stdio.h>
5046

5047
static void test_width(term_manager_t *manager, term_t t) {
5048
  bv64_abs_t abs;
5049
  uint32_t n;
5050

5051
  bv64_abstract_term(manager->terms, t, &abs);
5052
  n = term_bitsize(manager->terms, t);
5053
  if (bv64_abs_nontrivial(&abs, n)) {
5054
    printf("---> non-trivial abstraction for term t%"PRId32" (%"PRIu32" bits)\n", t, n);
5055
    printf("     [%"PRId64", %"PRId64"] (%"PRIu32" bits)\n", abs.low, abs.high, abs.nbits);
5056
    fflush(stdout);
5057
  }
5058
}
5059
#endif
5060

5061

5062
/*
5063
 * Truncate term t to n bits
5064
 */
5065
static term_t truncate_bv_term(term_manager_t *manager, uint32_t n, term_t t) {
32✔
5066
  bvlogic_buffer_t *b;
5067

5068
  assert(is_bitvector_term(manager->terms, t) && term_bitsize(manager->terms, t) >= n && n>0);
5069

5070
  b = term_manager_get_bvlogic_buffer(manager);
32✔
5071
  bvlogic_buffer_set_slice_term(b, manager->terms, 0, n-1, t);
32✔
5072

5073
  return mk_bvlogic_term(manager, b);
32✔
5074
}
5075

5076
/*
5077
 * Truncate p to n bits
5078
 */
5079
static pprod_t *truncate_pprod(term_manager_t *manager, uint32_t n, pprod_t *p) {
16✔
5080
  pp_buffer_t *buffer;
5081
  pprod_t *r;
5082
  uint32_t i, k;
5083
  term_t t;
5084

5085
  k = p->len;
16✔
5086

5087
  buffer = term_manager_get_pp_buffer(manager);
16✔
5088
  assert(buffer->len == 0);
5089
  for (i=0; i<k; i++) {
48✔
5090
    t = truncate_bv_term(manager, n, p->prod[i].var);
32✔
5091
    pp_buffer_mul_varexp(buffer, t, p->prod[i].exp);
32✔
5092
  }
5093
  pp_buffer_normalize(buffer);
16✔
5094
  r = pprod_from_buffer(manager->pprods, buffer);
16✔
5095
  pp_buffer_reset(buffer);
16✔
5096

5097
  return r;
16✔
5098
}
5099

5100
/*
5101
 * Construct a power-product term:
5102
 * - n = number of bits (must be between 1 and 64)
5103
 * - p = power product
5104
 */
5105
static term_t mk_pprod64_term(term_manager_t *manager, uint32_t n, pprod_t *p) {
403✔
5106
  bv64_abs_t abs;
5107
  pprod_t *r;
5108
  term_t t;
5109

5110
  assert(1 <= n && n <= 64);
5111
  bv64_abs_pprod(manager->terms, p, n, &abs);
403✔
5112

5113
#if 0
5114
  if (bv64_abs_nontrivial(&abs, n)) {
5115
    printf("---> reducible power product: %"PRIu32" bits\n", n);
5116
    printf("     [%"PRId64", %"PRId64"] (%"PRIu32" bits)\n", abs.low, abs.high, abs.nbits);
5117
    fflush(stdout);
5118
  }
5119
#endif
5120

5121
  if (abs.nbits < n) {
403✔
5122
    r = truncate_pprod(manager, abs.nbits, p);
16✔
5123
    t = pprod_term(manager->terms, r);
16✔
5124
    t = mk_sign_extend_term(manager, t, n);
16✔
5125
  } else {
5126
    t = pprod_term(manager->terms, p);
387✔
5127
  }
5128

5129
  return t;
403✔
5130
}
5131

5132
#if 0
5133
// THIS MAKES THINGS WORSE
5134

5135
/*
5136
 * Truncate a polynomial to n bits
5137
 * - b = buffer that stores the polynomial
5138
 * - b must be normalized
5139
 * - return a term
5140
 */
5141
static term_t truncate_bvarith64_buffer(term_manager_t *manager, bvarith64_buffer_t *b, uint32_t n) {
5142
  bvarith64_buffer_t *aux;
5143
  bvmlist64_t *q;
5144
  pprod_t *r;
5145
  uint64_t c;
5146
  uint32_t i, m;
5147
  term_t t;
5148

5149
  assert(1 <= n && n <= 64);
5150

5151
  aux = term_manager_get_bvarith64_aux_buffer(manager);
5152
  bvarith64_buffer_prepare(aux, n);
5153

5154
  m = b->nterms;
5155
  q = b->list;
5156
  assert(m >= 1);
5157
  for (i=0; i<m; i++) {
5158
    r = q->prod;
5159
    c = norm64(q->coeff, n); // coeff truncated to n bits
5160
    if (r == empty_pp) {
5161
      bvarith64_buffer_add_const(aux, c);
5162
    } else if (pp_is_var(r)) {
5163
      t = truncate_bv_term(manager, n, var_of_pp(r));
5164
      bvarith64_buffer_add_varmono(aux, c, t);
5165
    } else {
5166
      r = truncate_pprod(manager, n, r);
5167
      bvarith64_buffer_add_mono(aux, c, r);
5168
    }
5169
    q = q->next;
5170
  }
5171

5172
  bvarith64_buffer_normalize(aux);
5173
  t = bv64_poly(manager->terms, aux);
5174
  reset_bvarith64_buffer(aux);
5175

5176
  return t;
5177
}
5178

5179

5180
/*
5181
 * Check whether we can reduce b's width.
5182
 * - if so return the (sign extend (reduced width term) ...)
5183
 * - otherwise return NULL_TERM
5184
 */
5185
static term_t try_bvarith64_truncation(term_manager_t *manager, bvarith64_buffer_t *b) {
5186
  bv64_abs_t abs;
5187
  uint32_t n;
5188
  term_t t;
5189

5190
  n = b->bitsize;
5191
  assert(1 <= n && n <= 64);
5192
  bv64_abs_buffer(manager->terms, b, n, &abs);
5193

5194
#if 0
5195
  if (bv64_abs_nontrivial(&abs, n)) {
5196
    printf("---> reducible polynomial: %"PRIu32" bits\n", n);
5197
    printf("     [%"PRId64", %"PRId64"] (%"PRIu32" bits)\n", abs.low, abs.high, abs.nbits);
5198
    fflush(stdout);
5199
  }
5200
#endif
5201

5202
  t = NULL_TERM;
5203
  if (abs.nbits < n) {
5204
    t = truncate_bvarith64_buffer(manager, b, abs.nbits);
5205
    t = mk_sign_extend_term(manager, t, n);
5206
  }
5207

5208
  return t;
5209
}
5210
#endif
5211

5212
/*
5213
 * Normalize b then convert it to a term and reset b
5214
 */
5215
term_t mk_bvarith64_term(term_manager_t *manager, bvarith64_buffer_t *b) {
419,289✔
5216
  bvmlist64_t *m;
5217
  pprod_t *r;
5218
  uint32_t n, p;
5219
  term_t t;
5220

5221
  assert(b->bitsize > 0);
5222

5223
  bvarith64_buffer_normalize(b);
419,289✔
5224

5225
  n = b->bitsize;
419,289✔
5226
  p = b->nterms;
419,289✔
5227
  if (p == 0) {
419,289✔
5228
    // zero
5229
    t = make_zero_bv(manager, n);
104,668✔
5230
    goto done;
104,668✔
5231
  }
5232

5233
  if (p == 1) {
314,621✔
5234
    m = b->list; // unique monomial of b
183,413✔
5235
    r = m->prod;
183,413✔
5236
    if (r == empty_pp) {
183,413✔
5237
      // constant
5238
      t = bv64_constant(manager->terms, n, m->coeff);
88,370✔
5239
      goto done;
88,370✔
5240
    }
5241
    if (m->coeff == 1) {
95,043✔
5242
      // power product
5243
      t = pp_is_var(r) ? var_of_pp(r) : mk_pprod64_term(manager, n, r);
73,830✔
5244
      goto done;
73,830✔
5245
    }
5246
  }
5247

5248
  // try to convert to a bvarray term
5249
  t = convert_bvarith64_to_bvarray(manager, b);
152,421✔
5250
  if (t != NULL_TERM) goto done;
152,421✔
5251

5252
#if 0
5253
  // THIS MAKES THINGS WORSE
5254
  // try width reduction
5255
  t = try_bvarith64_truncation(manager, b);
5256
  if (t != NULL_TERM) goto done;
5257
#endif
5258

5259
  // default
5260
  t = bv64_poly(manager->terms, b);
151,505✔
5261

5262

5263
 done:
419,289✔
5264
  reset_bvarith64_buffer(b);
419,289✔
5265
  assert(is_bitvector_term(manager->terms, t) &&
5266
         term_bitsize(manager->terms, t) == n);
5267

5268
  return t;
419,289✔
5269
}
5270

5271

5272

5273
/***************
5274
 *  BIT ARRAY  *
5275
 **************/
5276

5277
/*
5278
 * Bit array
5279
 * - a must be an array of n boolean terms
5280
 * - n must be positive and no more than YICES_MAX_BVSIZE
5281
 */
5282
term_t mk_bvarray(term_manager_t *manager, uint32_t n, const term_t *a) {
203,217✔
5283
  bvlogic_buffer_t *b;
5284

5285
  assert(0 < n && n <= YICES_MAX_BVSIZE);
5286

5287
  b = term_manager_get_bvlogic_buffer(manager);
203,217✔
5288
  bvlogic_buffer_set_term_array(b, manager->terms, n, a);
203,217✔
5289
  return mk_bvlogic_term(manager, b);
203,217✔
5290
}
5291

5292

5293
/**********************
5294
 *  BITVECTOR  SHIFT  *
5295
 *********************/
5296

5297
/*
5298
 * All shift operators takes two bit-vector arguments of the same size.
5299
 * The first argument is shifted. The second argument is the shift amount.
5300
 * - bvshl t1 t2: shift left, padding with 0
5301
 * - bvlshr t1 t2: logical shift right (padding with 0)
5302
 * - bvashr t1 t2: arithmetic shift right (copy the sign bit)
5303
 *
5304
 * We check whether t2 is a bit-vector constant and convert to
5305
 * constant bit-shifts in such cases.
5306
 */
5307

5308

5309
/*
5310
 * SHIFT LEFT
5311
 */
5312

5313
// shift amount given by a small bitvector constant
5314
static term_t mk_bvshl_const64(term_manager_t *manager, term_t t1, bvconst64_term_t *c) {
66✔
5315
  bvlogic_buffer_t *b;
5316

5317
  b = term_manager_get_bvlogic_buffer(manager);
66✔
5318
  bvlogic_buffer_set_term(b, manager->terms, t1);
66✔
5319
  bvlogic_buffer_shl_constant64(b, c->bitsize, c->value);
66✔
5320

5321
  return mk_bvlogic_term(manager, b);
66✔
5322
}
5323

5324
// shift amount given by a large bitvector constant
5325
static term_t mk_bvshl_const(term_manager_t *manager, term_t t1, bvconst_term_t *c) {
16✔
5326
  bvlogic_buffer_t *b;
5327

5328
  b = term_manager_get_bvlogic_buffer(manager);
16✔
5329
  bvlogic_buffer_set_term(b, manager->terms, t1);
16✔
5330
  bvlogic_buffer_shl_constant(b, c->bitsize, c->data);
16✔
5331

5332
  return mk_bvlogic_term(manager, b);
16✔
5333
}
5334

5335

5336
term_t mk_bvshl(term_manager_t *manager, term_t t1, term_t t2) {
341✔
5337
  term_table_t *tbl;
5338

5339
  tbl = manager->terms;
341✔
5340

5341
  assert(is_bitvector_term(tbl, t1) && is_bitvector_term(tbl, t2)
5342
         && term_type(tbl, t1) == term_type(tbl, t2));
5343

5344
  switch (term_kind(tbl, t2)) {
341✔
5345
  case BV64_CONSTANT:
66✔
5346
    return mk_bvshl_const64(manager, t1, bvconst64_term_desc(tbl, t2));
66✔
5347

5348
  case BV_CONSTANT:
16✔
5349
    return mk_bvshl_const(manager, t1, bvconst_term_desc(tbl, t2));
16✔
5350

5351
  default:
259✔
5352
    if (bvterm_is_zero(tbl, t1)) {
259✔
5353
      return t1;
7✔
5354
    } else {
5355
      return bvshl_term(tbl, t1, t2);
252✔
5356
    }
5357
  }
5358
}
5359

5360

5361

5362
/*
5363
 * LOGICAL SHIFT RIGHT
5364
 */
5365

5366
// shift amount given by a small bitvector constant
5367
static term_t mk_bvlshr_const64(term_manager_t *manager, term_t t1, bvconst64_term_t *c) {
1✔
5368
  bvlogic_buffer_t *b;
5369

5370
  b = term_manager_get_bvlogic_buffer(manager);
1✔
5371
  bvlogic_buffer_set_term(b, manager->terms, t1);
1✔
5372
  bvlogic_buffer_lshr_constant64(b, c->bitsize, c->value);
1✔
5373

5374
  return mk_bvlogic_term(manager, b);
1✔
5375
}
5376

5377
// logical shift right: amount given by a large bitvector constant
5378
static term_t mk_bvlshr_const(term_manager_t *manager, term_t t1, bvconst_term_t *c) {
×
5379
  bvlogic_buffer_t *b;
5380

5381
  b = term_manager_get_bvlogic_buffer(manager);
×
5382
  bvlogic_buffer_set_term(b, manager->terms, t1);
×
5383
  bvlogic_buffer_lshr_constant(b, c->bitsize, c->data);
×
5384

5385
  return mk_bvlogic_term(manager, b);
×
5386
}
5387

5388

5389
term_t mk_bvlshr(term_manager_t *manager, term_t t1, term_t t2) {
1,738✔
5390
  term_table_t *tbl;
5391

5392
  tbl = manager->terms;
1,738✔
5393

5394
  assert(is_bitvector_term(tbl, t1) && is_bitvector_term(tbl, t2)
5395
         && term_type(tbl, t1) == term_type(tbl, t2));
5396

5397
  // rewrite: (bvlshr x x) --> 0b000000 ... 0
5398
  if (t1 == t2) return make_zero_bv(manager, term_bitsize(tbl, t1));
1,738✔
5399

5400
  switch (term_kind(tbl, t2)) {
1,734✔
5401
  case BV64_CONSTANT:
1✔
5402
    return mk_bvlshr_const64(manager, t1, bvconst64_term_desc(tbl, t2));
1✔
5403

5404
  case BV_CONSTANT:
×
5405
    return mk_bvlshr_const(manager, t1, bvconst_term_desc(tbl, t2));
×
5406

5407
  default:
1,733✔
5408
    // as above: if t1 is zero, then shifting does not change it
5409
    if (bvterm_is_zero(tbl, t1)) {
1,733✔
5410
      return t1;
14✔
5411
    } else {
5412
      return bvlshr_term(tbl, t1, t2);
1,719✔
5413
    }
5414
  }
5415
}
5416

5417

5418
/*
5419
 * ARITHMETIC SHIFT RIGHT
5420
 */
5421

5422
// shift amount given by a small bitvector constant
5423
static term_t mk_bvashr_const64(term_manager_t *manager, term_t t1, bvconst64_term_t *c) {
1✔
5424
  bvlogic_buffer_t *b;
5425

5426
  b = term_manager_get_bvlogic_buffer(manager);
1✔
5427
  bvlogic_buffer_set_term(b, manager->terms, t1);
1✔
5428
  bvlogic_buffer_ashr_constant64(b, c->bitsize, c->value);
1✔
5429

5430
  return mk_bvlogic_term(manager, b);
1✔
5431
}
5432

5433
// shift amount given by a large bitvector constant
5434
static term_t mk_bvashr_const(term_manager_t *manager, term_t t1, bvconst_term_t *c) {
×
5435
  bvlogic_buffer_t *b;
5436

5437
  b = term_manager_get_bvlogic_buffer(manager);
×
5438
  bvlogic_buffer_set_term(b, manager->terms, t1);
×
5439
  bvlogic_buffer_ashr_constant(b, c->bitsize, c->data);
×
5440

5441
  return mk_bvlogic_term(manager, b);
×
5442
}
5443

5444
// special case: if t1 is 0b00...00 or 0b11...11 then arithmetic shift
5445
// leaves t1 unchanged (whatever t2)
5446
static bool term_is_bvashr_invariant(term_table_t *tbl, term_t t1) {
478✔
5447
  bvconst64_term_t *u;
5448
  bvconst_term_t *v;
5449
  uint32_t k;
5450

5451
  switch (term_kind(tbl, t1)) {
478✔
5452
  case BV64_CONSTANT:
119✔
5453
    u = bvconst64_term_desc(tbl, t1);
119✔
5454
    assert(u->value == norm64(u->value, u->bitsize));
5455
    return u->value == 0 || bvconst64_is_minus_one(u->value, u->bitsize);
119✔
5456

5457
  case BV_CONSTANT:
8✔
5458
    v = bvconst_term_desc(tbl, t1);
8✔
5459
    k = (v->bitsize + 31) >> 5; // number of words in v
8✔
5460
    return bvconst_is_zero(v->data, k) || bvconst_is_minus_one(v->data, v->bitsize);
8✔
5461

5462
  default:
351✔
5463
    return false;
351✔
5464
  }
5465

5466
}
5467

5468
term_t mk_bvashr(term_manager_t *manager, term_t t1, term_t t2) {
479✔
5469
  term_table_t *tbl;
5470

5471
  tbl = manager->terms;
479✔
5472

5473
  assert(is_bitvector_term(tbl, t1) && is_bitvector_term(tbl, t2)
5474
         && term_type(tbl, t1) == term_type(tbl, t2));
5475

5476
  // possible rewrite:
5477
  // (bvashr x x) = if x<0 then 0b11111.. else 0b000...
5478

5479
  switch (term_kind(tbl, t2)) {
479✔
5480
  case BV64_CONSTANT:
1✔
5481
    return mk_bvashr_const64(manager, t1, bvconst64_term_desc(tbl, t2));
1✔
5482

5483
  case BV_CONSTANT:
×
5484
    return mk_bvashr_const(manager, t1, bvconst_term_desc(tbl, t2));
×
5485

5486
  default:
478✔
5487
    if (term_is_bvashr_invariant(tbl, t1)) {
478✔
5488
      return t1;
10✔
5489
    } else {
5490
      return bvashr_term(tbl, t1, t2);
468✔
5491
    }
5492
  }
5493
}
5494

5495

5496

5497
/************************
5498
 *  BITVECTOR DIVISION  *
5499
 ***********************/
5500

5501
/*
5502
 * All division/remainder constructors are binary operators with two
5503
 * bitvector arguments of the same size.
5504
 * - bvdiv: quotient in unsigned division
5505
 * - bvrem: remainder in unsigned division
5506
 * - bvsdiv: quotient in signed division (rounding toward 0)
5507
 * - bvsrem: remainder in signed division
5508
 * - bvsmod: remainder in floor division (signed division, rounding toward -infinity)
5509
 *
5510
 * We simplify if the two arguments are constants.
5511
 *
5512
 * TODO: We could convert division/remainder when t2 is a constant powers of two
5513
 * to shift and bit masking operations?
5514
 */
5515

5516
/*
5517
 * Check whether b is a power of 2.
5518
 * - if so return the k such such b = 2^k
5519
 * - otherwise, return -1
5520
 */
5521
static int32_t bvconst64_term_is_power_of_two(bvconst64_term_t *b) {
76✔
5522
  uint32_t k;
5523

5524
  if (b->value != 0) {
76✔
5525
    k = ctz64(b->value);
72✔
5526
    assert(0 <= k && k < b->bitsize && b->bitsize <= 64);
5527
    if (b->value == ((uint64_t) 1) << k) {
72✔
5528
      return k;
14✔
5529
    }
5530
  }
5531
  return -1;
62✔
5532
}
5533

5534
static int32_t bvconst_term_is_power_of_two(bvconst_term_t *b) {
8✔
5535
  uint32_t w;
5536

5537
  w = (b->bitsize + 31) >> 5; // number of words in b->data
8✔
5538
  return bvconst_is_power_of_two(b->data, w);
8✔
5539
}
5540

5541

5542
/*
5543
 * Unsigned division by zero: the result is 0b11...1.
5544
 * - divide t1 by 0
5545
 * side effect: use bv0
5546
 */
5547
static term_t bvdiv_by_zero(term_manager_t *manager, term_t t1) {
5✔
5548
  bvconstant_t *bv;
5549
  uint32_t n;
5550

5551
  n = term_bitsize(manager->terms, t1);
5✔
5552
  bv = &manager->bv0;
5✔
5553
  bvconstant_set_all_one(bv, n);
5✔
5554
  return mk_bv_constant(manager, bv);
5✔
5555
}
5556

5557
/*
5558
 * Auxiliary function: build (ite c 0b11111 0b00001) = (ite c -1 +1)
5559
 * - n = number of bits
5560
 * - c = boolean term
5561
 * side effect: use vector0
5562
 */
5563
static term_t mk_ite_minus_or_plus_one(term_manager_t *manager, term_t c, uint32_t n) {
55✔
5564
  term_t *a;
5565
  uint32_t i;
5566

5567
  /*
5568
   * build (ite c 0b11111 0b00001) as an array of booleans a
5569
   *  a[0] = true_term (i.e., 1)
5570
   *  a[1] = c
5571
   *  ..
5572
   *  a[n-1] = c
5573
   */
5574
  resize_ivector(&manager->vector0, n);
55✔
5575
  a = manager->vector0.data;
55✔
5576
  a[0] = true_term;
55✔
5577
  for (i=1; i<n; i++) {
1,195✔
5578
    a[i] = c;
1,140✔
5579
  }
5580

5581
  return bvarray_get_term(manager, a, n);
55✔
5582
}
5583

5584
/*
5585
 * Signed or unsigned division of t by itself:
5586
 * - the result is (ite (= t zero) 0b11111 0b00001)
5587
 *
5588
 * This holds because (bvdiv zero zero) = (bvsdiv zero zero) = 0b11111
5589
 */
5590
static term_t bvdiv_by_self(term_manager_t *manager, term_t t) {
54✔
5591
  term_t zero, eq;
5592
  uint32_t n;
5593

5594
  n = term_bitsize(manager->terms, t);
54✔
5595
  zero = make_zero_bv(manager, n);
54✔
5596
  eq = mk_bitvector_eq(manager, t, zero);
54✔
5597

5598
  return mk_ite_minus_or_plus_one(manager, eq, n);
54✔
5599
}
5600

5601

5602
/*
5603
 * Signed division of t1 by zero
5604
 * - the result is (ite (not b[n-1]) 0b111111 0b000001)
5605
 * where b[n-1] is the sign bit of t1
5606
 *
5607
 * I.e., if t1 < 0  then  (bvsrem t1 zero) = 0b000001
5608
 *       if t1 >= 0 then  (bvsrem t1 zero) = 0b111111
5609
 */
5610
static term_t bvsdiv_by_zero(term_manager_t *manager, term_t t1) {
1✔
5611
  uint32_t n;
5612
  term_t sign;
5613

5614
  n = term_bitsize(manager->terms, t1);
1✔
5615
  assert(n > 0);
5616

5617
  sign = mk_bitextract(manager, t1, n-1);
1✔
5618

5619
  return mk_ite_minus_or_plus_one(manager, opposite_term(sign), n);
1✔
5620
}
5621

5622

5623
/*
5624
 * zero term of same size as t
5625
 */
5626
static term_t bvzero_for_term(term_manager_t *manager, term_t t) {
35✔
5627
  uint32_t n;
5628

5629
  n = term_bitsize(manager->terms, t);
35✔
5630
  return make_zero_bv(manager, n);
35✔
5631
}
5632

5633

5634

5635
/*
5636
 * Unsigned division of two constants
5637
 */
5638
static term_t bvdiv_const64(term_manager_t *manager, bvconst64_term_t *a, bvconst64_term_t *b) {
61✔
5639
  uint64_t x;
5640
  uint32_t n;
5641

5642
  n = a->bitsize;
61✔
5643
  assert(n == b->bitsize);
5644
  x = bvconst64_udiv2z(a->value, b->value, n);
61✔
5645
  assert(x == norm64(x, n));
5646

5647
  return bv64_constant(manager->terms, n, x);
61✔
5648
}
5649

5650
static term_t bvdiv_const(term_manager_t *manager, bvconst_term_t *a, bvconst_term_t *b) {
18✔
5651
  bvconstant_t *bv;
5652
  uint32_t n;
5653

5654
  n = a->bitsize;
18✔
5655
  assert(n == b->bitsize && n > 64);
5656

5657
  bv = &manager->bv0;
18✔
5658

5659
  bvconstant_set_bitsize(bv, n);
18✔
5660
  bvconst_udiv2z(bv->data, n, a->data, b->data);
18✔
5661
  bvconst_normalize(bv->data, n);
18✔
5662

5663
  return bvconst_term(manager->terms, n, bv->data);
18✔
5664
}
5665

5666
/*
5667
 * Unsigned remainder: two constants
5668
 */
5669
static term_t bvrem_const64(term_manager_t *manager, bvconst64_term_t *a, bvconst64_term_t *b) {
7✔
5670
  uint64_t x;
5671
  uint32_t n;
5672

5673
  n = a->bitsize;
7✔
5674
  assert(n == b->bitsize);
5675
  x = bvconst64_urem2z(a->value, b->value, n);
7✔
5676
  assert(x == norm64(x, n));
5677

5678
  return bv64_constant(manager->terms, n, x);
7✔
5679
}
5680

5681
static term_t bvrem_const(term_manager_t *manager, bvconst_term_t *a, bvconst_term_t *b) {
5✔
5682
  bvconstant_t *bv;
5683
  uint32_t n;
5684

5685
  n = a->bitsize;
5✔
5686
  assert(n == b->bitsize && n > 64);
5687

5688
  bv = &manager->bv0;
5✔
5689

5690
  bvconstant_set_bitsize(bv, n);
5✔
5691
  bvconst_urem2z(bv->data, n, a->data, b->data);
5✔
5692
  bvconst_normalize(bv->data, n);
5✔
5693

5694
  return bvconst_term(manager->terms, n, bv->data);
5✔
5695
}
5696

5697

5698
/*
5699
 * Quotient in signed division of two constants
5700
 */
5701
static term_t bvsdiv_const64(term_manager_t *manager, bvconst64_term_t *a, bvconst64_term_t *b) {
13✔
5702
  uint64_t x;
5703
  uint32_t n;
5704

5705
  n = a->bitsize;
13✔
5706
  assert(n == b->bitsize);
5707
  x = bvconst64_sdiv2z(a->value, b->value, n);
13✔
5708
  assert(x == norm64(x, n));
5709

5710
  return bv64_constant(manager->terms, n, x);
13✔
5711
}
5712

5713
static term_t bvsdiv_const(term_manager_t *manager, bvconst_term_t *a, bvconst_term_t *b) {
3✔
5714
  bvconstant_t *bv;
5715
  uint32_t n;
5716

5717
  n = a->bitsize;
3✔
5718
  assert(n == b->bitsize && n > 64);
5719

5720
  bv = &manager->bv0;
3✔
5721

5722
  bvconstant_set_bitsize(bv, n);
3✔
5723
  bvconst_sdiv2z(bv->data, n, a->data, b->data);
3✔
5724
  bvconst_normalize(bv->data, n);
3✔
5725

5726
  return bvconst_term(manager->terms, n, bv->data);
3✔
5727
}
5728

5729

5730
/*
5731
 * Remainder in signed division of constants: rounding to zero
5732
 */
5733
static term_t bvsrem_const64(term_manager_t *manager, bvconst64_term_t *a, bvconst64_term_t *b) {
18✔
5734
  uint64_t x;
5735
  uint32_t n;
5736

5737
  n = a->bitsize;
18✔
5738
  assert(n == b->bitsize);
5739
  x = bvconst64_srem2z(a->value, b->value, n);
18✔
5740
  assert(x == norm64(x, n));
5741

5742
  return bv64_constant(manager->terms, n, x);
18✔
5743
}
5744

5745
static term_t bvsrem_const(term_manager_t *manager, bvconst_term_t *a, bvconst_term_t *b) {
3✔
5746
  bvconstant_t *bv;
5747
  uint32_t n;
5748

5749
  n = a->bitsize;
3✔
5750
  assert(n == b->bitsize && n > 64);
5751

5752
  bv = &manager->bv0;
3✔
5753

5754
  bvconstant_set_bitsize(bv, n);
3✔
5755
  bvconst_srem2z(bv->data, n, a->data, b->data);
3✔
5756
  bvconst_normalize(bv->data, n);
3✔
5757

5758
  return bvconst_term(manager->terms, n, bv->data);
3✔
5759
}
5760

5761

5762
/*
5763
 * Remainder in signed division of constants: rounding to minus infinity
5764
 */
5765
static term_t bvsmod_const64(term_manager_t *manager, bvconst64_term_t *a, bvconst64_term_t *b) {
14✔
5766
  uint64_t x;
5767
  uint32_t n;
5768

5769
  n = a->bitsize;
14✔
5770
  assert(n == b->bitsize);
5771
  x = bvconst64_smod2z(a->value, b->value, n);
14✔
5772
  assert(x == norm64(x, n));
5773

5774
  return bv64_constant(manager->terms, n, x);
14✔
5775
}
5776

5777
static term_t bvsmod_const(term_manager_t *manager, bvconst_term_t *a, bvconst_term_t *b) {
2✔
5778
  bvconstant_t *bv;
5779
  uint32_t n;
5780

5781
  n = a->bitsize;
2✔
5782
  assert(n == b->bitsize && n > 64);
5783

5784
  bv = &manager->bv0;
2✔
5785

5786
  bvconstant_set_bitsize(bv, n);
2✔
5787
  bvconst_smod2z(bv->data, n, a->data, b->data);
2✔
5788
  bvconst_normalize(bv->data, n);
2✔
5789

5790
  return bvconst_term(manager->terms, n, bv->data);
2✔
5791
}
5792

5793

5794
/*
5795
 * Unsigned division: t1 by 2^k
5796
 * - convert to a right shift
5797
 */
5798
static term_t bvdiv_power(term_manager_t *manager, term_t t1, uint32_t k) {
5✔
5799
  bvlogic_buffer_t *b;
5800

5801
  if (k == 0) return t1;
5✔
5802

5803
  b = term_manager_get_bvlogic_buffer(manager);
3✔
5804
  bvlogic_buffer_set_term(b, manager->terms, t1);
3✔
5805
  bvlogic_buffer_shift_right0(b, k);
3✔
5806

5807
  return mk_bvlogic_term(manager, b);
3✔
5808
}
5809

5810

5811
/*
5812
 * Unsigned remainder of t1/2^k
5813
 * - convert to a bit-mask
5814
 */
5815
static term_t bvrem_power(term_manager_t *manager, term_t t1, uint32_t k) {
11✔
5816
  bvlogic_buffer_t *b;
5817
  uint32_t n;
5818

5819
  n = term_bitsize(manager->terms, t1);
11✔
5820
  assert(0 <= k && k < n);
5821

5822
  b = term_manager_get_bvlogic_buffer(manager);
11✔
5823
  bvlogic_buffer_set_low_mask(b, k, n);
11✔
5824
  bvlogic_buffer_and_term(b, manager->terms, t1);
11✔
5825

5826
  return mk_bvlogic_term(manager, b);
11✔
5827
}
5828

5829

5830

5831

5832
/*
5833
 * UNSIGNED DIVISION: QUOTIENT
5834
 */
5835
term_t mk_bvdiv(term_manager_t *manager, term_t t1, term_t t2) {
466✔
5836
  term_table_t *tbl;
5837
  bvconst_term_t *bv;
5838
  bvconst64_term_t *bv64;
5839
  int32_t k;
5840

5841
  tbl = manager->terms;
466✔
5842

5843
  assert(is_bitvector_term(tbl, t1) && is_bitvector_term(tbl, t2)
5844
         && term_type(tbl, t1) == term_type(tbl, t2));
5845

5846
  switch (term_kind(tbl, t2)) {
466✔
5847
  case BV64_CONSTANT:
90✔
5848
    bv64 = bvconst64_term_desc(tbl, t2);
90✔
5849
    assert(bv64->value == norm64(bv64->value, bv64->bitsize));
5850
    if (term_kind(tbl, t1) == BV64_CONSTANT) {
90✔
5851
      return bvdiv_const64(manager, bvconst64_term_desc(tbl, t1), bv64);
61✔
5852
    }
5853
    k = bvconst64_term_is_power_of_two(bv64);
29✔
5854
    if (k >= 0) {
29✔
5855
      return bvdiv_power(manager, t1, k);
4✔
5856
    }
5857
    break;
25✔
5858

5859
  case BV_CONSTANT:
22✔
5860
    bv = bvconst_term_desc(tbl, t2);
22✔
5861
    if (term_kind(tbl, t1) == BV_CONSTANT) {
22✔
5862
      return bvdiv_const(manager, bvconst_term_desc(tbl, t1), bv);
18✔
5863
    }
5864
    k = bvconst_term_is_power_of_two(bv);
4✔
5865
    if (k >= 0) {
4✔
5866
      return bvdiv_power(manager, t1, k);
1✔
5867
    }
5868
    break;
3✔
5869

5870
  default:
354✔
5871
    break;
354✔
5872
  }
5873

5874
  if (bvterm_is_zero(manager->terms, t2)) return bvdiv_by_zero(manager, t1);
382✔
5875

5876
  if (t1 == t2) return bvdiv_by_self(manager, t1);
377✔
5877

5878
  return bvdiv_term(tbl, t1, t2);
334✔
5879
}
5880

5881

5882
/*
5883
 * UNSIGNED DIVISION: REMAINDER
5884
 */
5885
term_t mk_bvrem(term_manager_t *manager, term_t t1, term_t t2) {
714✔
5886
  term_table_t *tbl;
5887
  int32_t k;
5888

5889
  tbl = manager->terms;
714✔
5890

5891
  assert(is_bitvector_term(tbl, t1) && is_bitvector_term(tbl, t2)
5892
         && term_type(tbl, t1) == term_type(tbl, t2));
5893

5894
  switch (term_kind(tbl, t2)) {
714✔
5895
  case BV64_CONSTANT:
54✔
5896
    if (term_kind(tbl, t1) == BV64_CONSTANT) {
54✔
5897
      return bvrem_const64(manager, bvconst64_term_desc(tbl, t1), bvconst64_term_desc(tbl, t2));
7✔
5898
    }
5899
    k = bvconst64_term_is_power_of_two(bvconst64_term_desc(tbl, t2));
47✔
5900
    if (k >= 0) {
47✔
5901
      return bvrem_power(manager, t1, k);
10✔
5902
    }
5903
    break;
37✔
5904

5905
  case BV_CONSTANT:
9✔
5906
    if (term_kind(tbl, t1) == BV_CONSTANT) {
9✔
5907
      return bvrem_const(manager, bvconst_term_desc(tbl, t1), bvconst_term_desc(tbl, t2));
5✔
5908
    }
5909
    k = bvconst_term_is_power_of_two(bvconst_term_desc(tbl, t2));
4✔
5910
    if (k >= 0) {
4✔
5911
      return bvrem_power(manager, t1, k);
1✔
5912
    }
5913
    break;
3✔
5914

5915
  default:
651✔
5916
    break;
651✔
5917
  }
5918

5919
  // (bvrem x 0) is x
5920
  if (bvterm_is_zero(manager->terms, t2)) return t1;
691✔
5921

5922
  // (bvrem x x) is 0 (even if x = 0)
5923
  if (t1 == t2) return bvzero_for_term(manager, t1);
691✔
5924

5925
  return bvrem_term(tbl, t1, t2);
673✔
5926
}
5927

5928

5929
/*
5930
 * SIGNED DIVISION: QUOTIENT
5931
 */
5932
term_t mk_bvsdiv(term_manager_t *manager, term_t t1, term_t t2) {
167✔
5933
  term_table_t *tbl;
5934

5935
  tbl = manager->terms;
167✔
5936

5937
  assert(is_bitvector_term(tbl, t1) && is_bitvector_term(tbl, t2)
5938
         && term_type(tbl, t1) == term_type(tbl, t2));
5939

5940
  switch (term_kind(tbl, t2)) {
167✔
5941
  case BV64_CONSTANT:
30✔
5942
    if (term_kind(tbl, t1) == BV64_CONSTANT) {
30✔
5943
      return bvsdiv_const64(manager, bvconst64_term_desc(tbl, t1), bvconst64_term_desc(tbl, t2));
13✔
5944
    }
5945
    break;
17✔
5946

5947
  case BV_CONSTANT:
10✔
5948
    if (term_kind(tbl, t1) == BV_CONSTANT) {
10✔
5949
      return bvsdiv_const(manager, bvconst_term_desc(tbl, t1), bvconst_term_desc(tbl, t2));
3✔
5950
    }
5951
    break;
7✔
5952

5953
  default:
127✔
5954
    break;
127✔
5955
  }
5956

5957
  // (bvsdiv t1 0)
5958
  if (bvterm_is_zero(manager->terms, t2)) return bvsdiv_by_zero(manager, t1);
151✔
5959

5960
  // (bvsdiv t1 1) = t1
5961
  if (bvterm_is_one(manager->terms, t2)) return t1;
150✔
5962

5963
  // (bvsdiv t t) = (bvdiv t t)
5964
  if (t1 == t2) return bvdiv_by_self(manager, t1);
150✔
5965

5966
  return bvsdiv_term(tbl, t1, t2);
139✔
5967
}
5968

5969

5970
/*
5971
 * SIGNED DIVISION: REMAINDER (ROUNDING TO 0)
5972
 */
5973
term_t mk_bvsrem(term_manager_t *manager, term_t t1, term_t t2) {
165✔
5974
  term_table_t *tbl;
5975

5976
  tbl = manager->terms;
165✔
5977

5978
  assert(is_bitvector_term(tbl, t1) && is_bitvector_term(tbl, t2)
5979
         && term_type(tbl, t1) == term_type(tbl, t2));
5980

5981
  switch (term_kind(tbl, t2)) {
165✔
5982
  case BV64_CONSTANT:
35✔
5983
    if (term_kind(tbl, t1) == BV64_CONSTANT) {
35✔
5984
      return bvsrem_const64(manager, bvconst64_term_desc(tbl, t1), bvconst64_term_desc(tbl, t2));
18✔
5985
    }
5986
    break;
17✔
5987

5988
  case BV_CONSTANT:
7✔
5989
    if (term_kind(tbl, t1) == BV_CONSTANT) {
7✔
5990
      return bvsrem_const(manager, bvconst_term_desc(tbl, t1), bvconst_term_desc(tbl, t2));
3✔
5991
    }
5992
    break;
4✔
5993

5994
  default:
123✔
5995
    break;
123✔
5996
  }
5997

5998
  // (bvsrem x 0) is x
5999
  if (bvterm_is_zero(manager->terms, t2)) return t1;
144✔
6000

6001
  // (bvsrem x 1) is 0
6002
  if (bvterm_is_one(manager->terms, t2)) return bvzero_for_term(manager, t1);
141✔
6003

6004
  // (bvsrem x -1) is 0
6005
  if (bvterm_is_minus_one(manager->terms, t2)) return bvzero_for_term(manager, t1);
137✔
6006

6007
  // (bvsrem x x) is 0 (even if x = 0)
6008
  if (t1 == t2) return bvzero_for_term(manager, t1);
136✔
6009

6010
  return bvsrem_term(tbl, t1, t2);
124✔
6011
}
6012

6013

6014
/*
6015
 * FLOOR DIVISION: REMAINDER (ROUNDING TO - INFINITY)
6016
 */
6017
term_t mk_bvsmod(term_manager_t *manager, term_t t1, term_t t2) {
22✔
6018
  term_table_t *tbl;
6019

6020
  tbl = manager->terms;
22✔
6021

6022
  assert(is_bitvector_term(tbl, t1) && is_bitvector_term(tbl, t2)
6023
         && term_type(tbl, t1) == term_type(tbl, t2));
6024

6025
  switch (term_kind(tbl, t2)) {
22✔
6026
  case BV64_CONSTANT:
15✔
6027
    if (term_kind(tbl, t1) == BV64_CONSTANT) {
15✔
6028
      return bvsmod_const64(manager, bvconst64_term_desc(tbl, t1), bvconst64_term_desc(tbl, t2));
14✔
6029
    }
6030
    break;
1✔
6031

6032
  case BV_CONSTANT:
2✔
6033
    if (term_kind(tbl, t1) == BV_CONSTANT) {
2✔
6034
      return bvsmod_const(manager, bvconst_term_desc(tbl, t1), bvconst_term_desc(tbl, t2));
2✔
6035
    }
6036
    break;
×
6037

6038
  default:
5✔
6039
    break;
5✔
6040
  }
6041

6042
  // (bvsmod x 0) is x
6043
  if (bvterm_is_zero(manager->terms, t2)) return t1;
6✔
6044

6045
  // (bvsmod x 1) is 0
6046
  if (bvterm_is_one(manager->terms, t2)) return bvzero_for_term(manager, t1);
6✔
6047

6048
  // (bvsmoe x -1) is 0
6049
  if (bvterm_is_minus_one(manager->terms, t2)) return bvzero_for_term(manager, t1);
6✔
6050

6051
  // (bvsmod x x) is 0 (even if x = 0)
6052
  if (t1 == t2) return bvzero_for_term(manager, t1);
6✔
6053

6054
  return bvsmod_term(tbl, t1, t2);
6✔
6055
}
6056

6057

6058

6059

6060
/*****************
6061
 *  BIT EXTRACT  *
6062
 ****************/
6063

6064
/*
6065
 * Extract bit i of t
6066
 * - t must be a bitvector term
6067
 * - i must be between 0 and n-1, where n = bitsize of t
6068
 *
6069
 * The result is a boolean term
6070
 */
6071
term_t mk_bitextract(term_manager_t *manager, term_t t, uint32_t i) {
3,435,812✔
6072
  term_table_t *tbl;
6073
  bvconst64_term_t *d;
6074
  bvconst_term_t *c;
6075
  composite_term_t *bv;
6076
  term_t u;
6077

6078
  tbl = manager->terms;
3,435,812✔
6079

6080
  assert(is_bitvector_term(tbl, t) && 0 <= i && i < term_bitsize(tbl, t));
6081

6082
  switch (term_kind(tbl, t)) {
3,435,812✔
6083
  case BV64_CONSTANT:
184,258✔
6084
    d = bvconst64_term_desc(tbl, t);
184,258✔
6085
    u = bool2term(tst_bit64(d->value, i));
184,258✔
6086
    break;
184,258✔
6087

6088
  case BV_CONSTANT:
339✔
6089
    c = bvconst_term_desc(tbl, t);
339✔
6090
    u = bool2term(bvconst_tst_bit(c->data, i));
339✔
6091
    break;
339✔
6092

6093
  case BV_ARRAY:
613,501✔
6094
    bv = bvarray_term_desc(tbl, t);
613,501✔
6095
    u = bv->arg[i];
613,501✔
6096
    break;
613,501✔
6097

6098
  default:
2,637,714✔
6099
    u = bit_term(tbl, i, t);
2,637,714✔
6100
    break;
2,637,714✔
6101
  }
6102

6103
  return u;
3,435,812✔
6104
}
6105

6106

6107
/*
6108
 * Convert bit i of buffer b to a term then reset b
6109
 */
6110
term_t bvl_get_bit(term_manager_t *manager, bvlogic_buffer_t *b, uint32_t i) {
×
6111
  term_t t;
6112

6113
  assert(i < b->bitsize);
6114
  t = map_bit_to_term(manager, b->bit[i]);
×
6115
  bvlogic_buffer_clear(b);
×
6116

6117
  return t;
×
6118
}
6119

6120

6121

6122

6123

6124

6125
/**********************
6126
 *  BIT-VECTOR ATOMS  *
6127
 *********************/
6128

6129
/*
6130
 * For debugging: check that t1 and t2 are bitvectors terms of the same size
6131
 */
6132
#ifndef NDEBUG
6133
static bool valid_bvcomp(term_table_t *tbl, term_t t1, term_t t2) {
6134
  return is_bitvector_term(tbl, t1) && is_bitvector_term(tbl, t2)
6135
    && term_type(tbl, t1) == term_type(tbl, t2);
6136
}
6137
#endif
6138

6139

6140
/*
6141
 * Unsigned comparison
6142
 */
6143

6144
// check whether t1 < t2 holds trivially
6145
static bool must_lt(term_manager_t *manager, term_t t1, term_t t2) {
25,748✔
6146
  bvconstant_t *bv1, *bv2;
6147

6148
  bv1 = &manager->bv1;
25,748✔
6149
  bv2 = &manager->bv2;
25,748✔
6150
  upper_bound_unsigned(manager->terms, t1, bv1); // t1 <= bv1
25,748✔
6151
  lower_bound_unsigned(manager->terms, t2, bv2); // bv2 <= t2
25,748✔
6152
  assert(bv1->bitsize == bv2->bitsize);
6153

6154
  return bvconst_lt(bv1->data, bv2->data, bv1->bitsize);
25,748✔
6155
}
6156

6157
// check whether t1 <= t2 holds trivially
6158
static bool must_le(term_manager_t *manager, term_t t1, term_t t2) {
26,958✔
6159
  bvconstant_t *bv1, *bv2;
6160

6161
  bv1 = &manager->bv1;
26,958✔
6162
  bv2 = &manager->bv2;
26,958✔
6163
  upper_bound_unsigned(manager->terms, t1, bv1);
26,958✔
6164
  lower_bound_unsigned(manager->terms, t2, bv2);
26,958✔
6165
  assert(bv1->bitsize == bv2->bitsize);
6166

6167
  return bvconst_le(bv1->data, bv2->data, bv1->bitsize);
26,958✔
6168
}
6169

6170
 // t1 >= t2: unsigned
6171
term_t mk_bvge(term_manager_t *manager, term_t t1, term_t t2) {
27,359✔
6172
  assert(valid_bvcomp(manager->terms, t1, t2));
6173

6174
  if (t1 == t2 || must_le(manager, t2, t1)) {
27,359✔
6175
    return true_term;
1,611✔
6176
  }
6177

6178
  if (must_lt(manager, t1, t2)) {
25,748✔
6179
    return false_term;
6,583✔
6180
  }
6181

6182
  if (bvterm_is_min_unsigned(manager->terms, t1)) {
19,165✔
6183
    // 0b0000..00 >= t2  iff t2 == 0b0000..00
6184
    return mk_bitvector_eq(manager, t1, t2);
441✔
6185
  }
6186

6187
  if (bvterm_is_max_unsigned(manager->terms, t2)) {
18,724✔
6188
    // t1 >= 0b1111..11  iff t1 == 0b1111..11
6189
    return mk_bitvector_eq(manager, t1, t2);
126✔
6190
  }
6191

6192
  return bvge_atom(manager->terms, t1, t2);
18,598✔
6193
}
6194

6195
// t1 > t2: unsigned
6196
term_t mk_bvgt(term_manager_t *manager, term_t t1, term_t t2) {
1,660✔
6197
  return opposite_term(mk_bvge(manager, t2, t1));
1,660✔
6198
}
6199

6200
// t1 <= t2: unsigned
6201
term_t mk_bvle(term_manager_t *manager, term_t t1, term_t t2) {
5,035✔
6202
  return mk_bvge(manager, t2, t1);
5,035✔
6203
}
6204

6205
// t1 < t2: unsigned
6206
term_t mk_bvlt(term_manager_t *manager, term_t t1, term_t t2) {
15,996✔
6207
  return opposite_term(mk_bvge(manager, t1, t2));
15,996✔
6208
}
6209

6210

6211

6212

6213
/*
6214
 * Signed comparisons
6215
 */
6216

6217
// Check whether t1 < t2 holds trivially
6218
static bool must_slt(term_manager_t *manager, term_t t1, term_t t2) {
7,967✔
6219
  bvconstant_t *bv1, *bv2;
6220

6221
  bv1 = &manager->bv1;
7,967✔
6222
  bv2 = &manager->bv2;
7,967✔
6223
  upper_bound_signed(manager->terms, t1, bv1);
7,967✔
6224
  lower_bound_signed(manager->terms, t2, bv2);
7,967✔
6225
  assert(bv1->bitsize == bv2->bitsize);
6226

6227
  return bvconst_slt(bv1->data, bv2->data, bv1->bitsize);
7,967✔
6228
}
6229

6230
// Check whether t1 <= t2 holds
6231
static bool must_sle(term_manager_t *manager, term_t t1, term_t t2) {
8,534✔
6232
  bvconstant_t *bv1, *bv2;
6233

6234
  bv1 = &manager->bv1;
8,534✔
6235
  bv2 = &manager->bv2;
8,534✔
6236
  upper_bound_signed(manager->terms, t1, bv1);
8,534✔
6237
  lower_bound_signed(manager->terms, t2, bv2);
8,534✔
6238
  assert(bv1->bitsize == bv2->bitsize);
6239

6240
  return bvconst_sle(bv1->data, bv2->data, bv1->bitsize);
8,534✔
6241
}
6242

6243
// t1 >= t2: signed
6244
term_t mk_bvsge(term_manager_t *manager, term_t t1, term_t t2) {
8,816✔
6245
  assert(valid_bvcomp(manager->terms, t1, t2));
6246

6247
  if (t1 == t2 || must_sle(manager, t2, t1)) {
8,816✔
6248
    return true_term;
849✔
6249
  }
6250

6251
  if (must_slt(manager, t1, t2)) {
7,967✔
6252
    return false_term;
326✔
6253
  }
6254

6255
  if (bvterm_is_min_signed(manager->terms, t1)) {
7,641✔
6256
    // 0b1000..00 >= t2  iff t2 == 0b1000..00
6257
    return mk_bitvector_eq(manager, t1, t2);
47✔
6258
  }
6259

6260
  if (bvterm_is_max_signed(manager->terms, t2)) {
7,594✔
6261
    // t1 >= 0b0111..11  iff t1 == 0b0111..11
6262
    return mk_bitvector_eq(manager, t1, t2);
56✔
6263
  }
6264

6265
  return bvsge_atom(manager->terms, t1, t2);
7,538✔
6266
}
6267

6268
// t1 > t2: signed
6269
term_t mk_bvsgt(term_manager_t *manager, term_t t1, term_t t2) {
1,607✔
6270
  return opposite_term(mk_bvsge(manager, t2, t1));
1,607✔
6271
}
6272

6273

6274
// t1 <= t2: signed
6275
term_t mk_bvsle(term_manager_t *manager, term_t t1, term_t t2) {
2,197✔
6276
  return mk_bvsge(manager, t2, t1);
2,197✔
6277
}
6278

6279
// t1 < t2: signed
6280
term_t mk_bvslt(term_manager_t *manager, term_t t1, term_t t2) {
2,160✔
6281
  return opposite_term(mk_bvsge(manager, t1, t2));
2,160✔
6282
}
6283

6284

6285

6286

6287
/*************************************
6288
 *  POWER-PRODUCTS AND POLYNOMIALS   *
6289
 ************************************/
6290

6291
/*
6292
 * Arithmetic product:
6293
 * - p is a power product descriptor: t_0^e_0 ... t_{n-1}^e_{n-1}
6294
 * - a is an array of n arithmetic terms
6295
 * - this function constructs the term a[0]^e_0 ... a[n-1]^e_{n-1}
6296
 */
6297
term_t mk_arith_pprod(term_manager_t *mngr, pprod_t *p, uint32_t n, const term_t *a) {
9✔
6298
  rba_buffer_t *b;
6299
  term_table_t *tbl;
6300
  uint32_t i;
6301

6302
  assert(n == p->len);
6303

6304
  tbl = term_manager_get_terms(mngr);
9✔
6305
  b = term_manager_get_arith_buffer(mngr);
9✔
6306

6307
  rba_buffer_set_one(b); // b := 1
9✔
6308
  for (i=0; i<n; i++) {
33✔
6309
    // b := b * a[i]^e[i]
6310
    rba_buffer_mul_term_power(b, tbl, a[i], p->prod[i].exp);
24✔
6311
  }
6312

6313
  return mk_arith_term(mngr, b);
9✔
6314
}
6315

6316
/*
6317
 * Arithmetic product:
6318
 * - p is a power product descriptor: t_0^e_0 ... t_{n-1}^e_{n-1}
6319
 * - a is an array of n arithmetic terms
6320
 * - this function constructs the term a[0]^e_0 ... a[n-1]^e_{n-1}
6321
 */
6322
term_t mk_arith_ff_pprod(term_manager_t *mngr, pprod_t *p, uint32_t n, const term_t *a, const rational_t *mod) {
×
6323
  rba_buffer_t *b;
6324
  term_table_t *tbl;
6325
  uint32_t i;
6326

6327
  assert(n == p->len);
6328

6329
  tbl = term_manager_get_terms(mngr);
×
6330
  b = term_manager_get_arith_buffer(mngr);
×
6331

6332
  rba_buffer_set_one(b); // b := 1
×
6333
  for (i=0; i<n; i++) {
×
6334
    // b := b * a[i]^e[i]
6335
    rba_buffer_mul_term_power(b, tbl, a[i], p->prod[i].exp);
×
6336
  }
6337

6338
  return mk_arith_ff_term(mngr, b, mod);
×
6339
}
6340

6341

6342
/*
6343
 * Bitvector product: 1 to 64 bits vector
6344
 * - p is a power product descriptor: t_0^e_0 ... t_{n-1}^e_{n-1}
6345
 * - a is an array of n bitvector terms
6346
 * - nbits = number of bits in each term of a
6347
 * - this function constructs the term a[0]^e_0 ... a[n-1]^e_{n-1}
6348
 */
6349
term_t mk_bvarith64_pprod(term_manager_t *mngr, pprod_t *p, uint32_t n, const term_t *a, uint32_t nbits) {
94✔
6350
  bvarith64_buffer_t *b;
6351
  term_table_t *tbl;
6352
  uint32_t i;
6353

6354
  assert(n == p->len && 0 < nbits && nbits <= 64);
6355

6356
  tbl = term_manager_get_terms(mngr);
94✔
6357
  b = term_manager_get_bvarith64_buffer(mngr);
94✔
6358

6359
  bvarith64_buffer_prepare(b, nbits);
94✔
6360
  bvarith64_buffer_set_one(b); // b := 1
94✔
6361
  for (i=0; i<n; i++) {
287✔
6362
    // b := b * a[i]^e[i]
6363
    bvarith64_buffer_mul_term_power(b, tbl, a[i], p->prod[i].exp);
193✔
6364
  }
6365

6366
  return mk_bvarith64_term(mngr, b);
94✔
6367
}
6368

6369

6370
/*
6371
 * Bitvector product: more than 64 bits
6372
 * - p is a power product descriptor: t_0^e_0 ... t_{n-1}^e_{n-1}
6373
 * - a is an array of n bitvector terms
6374
 * - nbits = number of bits in each term of a
6375
 * - this function constructs the term a[0]^e_0 ... a[n-1]^e_{n-1}
6376
 */
6377
term_t mk_bvarith_pprod(term_manager_t *mngr, pprod_t *p, uint32_t n, const term_t *a, uint32_t nbits) {
20✔
6378
  bvarith_buffer_t *b;
6379
  term_table_t *tbl;
6380
  uint32_t i;
6381

6382
  assert(n == p->len && 64 < nbits && nbits <= YICES_MAX_BVSIZE);
6383

6384
  tbl = term_manager_get_terms(mngr);
20✔
6385
  b = term_manager_get_bvarith_buffer(mngr);
20✔
6386

6387
  bvarith_buffer_prepare(b, nbits);
20✔
6388
  bvarith_buffer_set_one(b); // b := 1
20✔
6389
  for (i=0; i<n; i++) {
56✔
6390
    // b := b * a[i]^e[i]
6391
    bvarith_buffer_mul_term_power(b, tbl, a[i], p->prod[i].exp);
36✔
6392
  }
6393

6394
  return mk_bvarith_term(mngr, b);
20✔
6395
}
6396

6397

6398
/*
6399
 * Generic version: check the type of a[0]
6400
 */
6401
term_t mk_pprod(term_manager_t *mngr, pprod_t *p, uint32_t n, const term_t *a) {
68✔
6402
  type_t tau;
6403

6404
  assert(n > 0);
6405

6406
  tau = term_type(mngr->terms, a[0]);
68✔
6407
  if (is_arithmetic_type(tau)) {
68✔
6408
    return mk_arith_pprod(mngr, p, n, a);
9✔
6409
  } else if (is_ff_type(mngr->types, tau)) {
59✔
6410
    const rational_t *mod = ff_type_size(mngr->types, tau);
×
6411
    return mk_arith_ff_pprod(mngr, p, n, a, mod);
×
6412
  } else {
6413
    uint32_t nbits = bv_type_size(mngr->types, tau);
59✔
6414
    if (nbits <= 64) {
59✔
6415
      return mk_bvarith64_pprod(mngr, p, n, a, nbits);
43✔
6416
    } else {
6417
      return mk_bvarith_pprod(mngr, p, n, a, nbits);
16✔
6418
    }
6419
  }
6420
}
6421

6422
/*
6423
 * Polynomial:
6424
 * - p is a polynomial c_0 t_0 + c_1 t_1 + ... + c_{n-1} t_{n-1}
6425
 * - a is an array of n terms
6426
 * - construct the term c_0 a[0] + c_1 a[1] + ... + c_{n-1} a[n-1]
6427
 *   except that c_i * a[i] is replaced by c_i if a[i] == const_idx.
6428
 */
6429
term_t mk_arith_poly(term_manager_t *mngr, polynomial_t *p, uint32_t n, const term_t *a) {
1,444✔
6430
  rba_buffer_t *b;
6431
  term_table_t *tbl;
6432
  uint32_t i;
6433

6434
  assert(p->nterms == n);
6435

6436
  tbl = term_manager_get_terms(mngr);
1,444✔
6437
  b = term_manager_get_arith_buffer(mngr);
1,444✔
6438
  reset_rba_buffer(b);
1,444✔
6439

6440
  for (i=0; i<n; i++) {
4,672✔
6441
    if (a[i] == const_idx) {
3,228✔
6442
      rba_buffer_add_const(b, &p->mono[i].coeff);
424✔
6443
    } else {
6444
      rba_buffer_add_const_times_term(b, tbl, &p->mono[i].coeff, a[i]);
2,804✔
6445
    }
6446
  }
6447

6448
  return mk_arith_term(mngr, b);
1,444✔
6449
}
6450

6451
/*
6452
 * Same thing for a finite field polynomial
6453
 */
6454
term_t mk_arith_ff_poly(term_manager_t *mngr, polynomial_t *p, uint32_t n, const term_t *a, const rational_t *mod) {
×
6455
  rba_buffer_t *b;
6456
  term_table_t *tbl;
6457
  uint32_t i;
6458

6459
  assert(p->nterms == n);
6460

6461
  tbl = term_manager_get_terms(mngr);
×
6462
  b = term_manager_get_arith_buffer(mngr);
×
6463
  reset_rba_buffer(b);
×
6464

6465
  for (i=0; i<n; i++) {
×
6466
    if (a[i] == const_idx) {
×
6467
      rba_buffer_add_const(b, &p->mono[i].coeff);
×
6468
    } else {
6469
      rba_buffer_add_const_times_term(b, tbl, &p->mono[i].coeff, a[i]);
×
6470
    }
6471
  }
6472

6473
  return mk_arith_ff_term(mngr, b, mod);
×
6474
}
6475

6476

6477
/*
6478
 * Same thing for a bitvector polynomial (1 to 64bits)
6479
 */
6480
term_t mk_bvarith64_poly(term_manager_t *mngr, bvpoly64_t *p, uint32_t n, const term_t *a) {
28,172✔
6481
  bvarith64_buffer_t *b;
6482
  term_table_t *tbl;
6483
  uint32_t i;
6484

6485
  assert(p->nterms == n && 0 < p->bitsize && p->bitsize <= 64);
6486

6487
  tbl = term_manager_get_terms(mngr);
28,172✔
6488
  b = term_manager_get_bvarith64_buffer(mngr);
28,172✔
6489
  bvarith64_buffer_prepare(b, p->bitsize);
28,172✔
6490

6491
  for (i=0; i<n; i++) {
63,778✔
6492
    if (a[i] == const_idx) {
35,606✔
6493
      bvarith64_buffer_add_const(b, p->mono[i].coeff);
5,921✔
6494
    } else {
6495
      bvarith64_buffer_add_const_times_term(b, tbl, p->mono[i].coeff, a[i]);
29,685✔
6496
    }
6497
  }
6498

6499
  return mk_bvarith64_term(mngr, b);
28,172✔
6500
}
6501

6502

6503
/*
6504
 * Same thing for a bitvector polynomial (more than 64bits)
6505
 */
6506
term_t mk_bvarith_poly(term_manager_t *mngr, bvpoly_t *p, uint32_t n, const term_t *a) {
15✔
6507
  bvarith_buffer_t *b;
6508
  term_table_t *tbl;
6509
  uint32_t i;
6510

6511
  assert(p->nterms == n && 64 < p->bitsize && p->bitsize <= YICES_MAX_BVSIZE);
6512

6513
  tbl = term_manager_get_terms(mngr);
15✔
6514
  b = term_manager_get_bvarith_buffer(mngr);
15✔
6515
  bvarith_buffer_prepare(b, p->bitsize);
15✔
6516

6517
  for (i=0; i<n; i++) {
38✔
6518
    if (a[i] == const_idx) {
23✔
6519
      bvarith_buffer_add_const(b, p->mono[i].coeff);
×
6520
    } else {
6521
      bvarith_buffer_add_const_times_term(b, tbl, p->mono[i].coeff, a[i]);
23✔
6522
    }
6523
  }
6524

6525
  return mk_bvarith_term(mngr, b);
15✔
6526
}
6527

6528

6529

6530
/*
6531
 * Support for eliminating arithmetic variables:
6532
 * - given a polynomial p and a term t that occurs in p
6533
 * - construct the polynomial q such that (t == q) is equivalent to (p == 0)
6534
 *   (i.e., write p as a.t + r and construct  q :=  -r/a).
6535
 *
6536
 * BUG FIX: if t is an integer and q is not, return NULL_TERM
6537
 */
6538
term_t mk_arith_elim_poly(term_manager_t *mngr, polynomial_t *p, term_t t) {
8✔
6539
  rba_buffer_t *b;
6540
  rational_t *a;
6541
  uint32_t i, j, n;
6542

6543
  assert(good_term(mngr->terms, t));
6544

6545
  n = p->nterms;
8✔
6546

6547
  // find j such that p->mono[j].var == t
6548
  j = 0;
8✔
6549
  while (p->mono[j].var != t) {
23✔
6550
    j++;
15✔
6551
    assert(j < n);
6552
  }
6553

6554
  a = &p->mono[j].coeff; // coefficient of t in p
8✔
6555
  assert(q_is_nonzero(a));
6556

6557
  /*
6558
   * p is r + a.t, construct -r/a in buffer b
6559
   */
6560
  b = term_manager_get_arith_buffer(mngr);
8✔
6561
  reset_rba_buffer(b);
8✔
6562
  if (q_is_minus_one(a)) {
8✔
6563
    // special case: a = -1
6564
    i = 0;
×
6565
    if (p->mono[0].var == const_idx) {
×
6566
      assert(j > 0);
6567
      rba_buffer_add_const(b, &p->mono[0].coeff);
×
6568
      i ++;
×
6569
    }
6570
    while (i < n) {
×
6571
      if (i != j) {
×
6572
        assert(p->mono[i].var != t);
6573
        rba_buffer_add_varmono(b, &p->mono[i].coeff, p->mono[i].var);
×
6574
      }
6575
      i++;
×
6576
    }
6577
  } else {
6578
    // first construct -r then divide by a
6579
    i = 0;
8✔
6580
    if (p->mono[0].var == const_idx) {
8✔
6581
      assert(j > 0);
6582
      rba_buffer_sub_const(b, &p->mono[0].coeff);
5✔
6583
      i ++;
5✔
6584
    }
6585
    while (i < n) {
30✔
6586
      if (i != j) {
22✔
6587
        assert(p->mono[i].var != t);
6588
        rba_buffer_sub_varmono(b, &p->mono[i].coeff, p->mono[i].var);
14✔
6589
      }
6590
      i ++;
22✔
6591
    }
6592
    if (! q_is_one(a)) {
8✔
6593
      rba_buffer_div_const(b, a);
5✔
6594
    }
6595
  }
6596

6597
  if (is_integer_term(mngr->terms, t) && !arith_poly_is_integer(mngr->terms, b)) {
8✔
6598
    // t is an integer term, -r/a is not so (p == 0) is not equivalent to t=-r/a
6599
    reset_rba_buffer(b);
2✔
6600
    return NULL_TERM;
2✔
6601
  }
6602

6603
  return mk_arith_term(mngr, b);
6✔
6604
}
6605

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

© 2025 Coveralls, Inc