• 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

64.16
/src/model/concrete_values.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
 * Concrete values = constants of different types.
21
 * This is used to build models: a model is a mapping from terms to concrete values.
22
 */
23

24
#include <inttypes.h>
25

26
#include "model/concrete_values.h"
27
#include "terms/bv64_constants.h"
28
#include "utils/hash_functions.h"
29
#include "utils/int_array_sort.h"
30
#include "utils/memalloc.h"
31

32
#ifdef HAVE_MCSAT
33
#include <poly/algebraic_number.h>
34
#endif
35

36

37

38
/************************
39
 *  AUXILIARY HASH MAP  *
40
 ***********************/
41

42
/*
43
 * Initialize table: empty table of default size
44
 */
45
static void init_map_htbl(map_htbl_t *htbl) {
31,582✔
46
  uint32_t i, n;
47
  map_pair_t *tmp;
48

49
  n = MAP_HTBL_DEFAULT_SIZE;
31,582✔
50
  assert(n < MAP_HTBL_MAX_SIZE);
51

52
  tmp = (map_pair_t *) safe_malloc(n * sizeof(map_pair_t));
31,582✔
53
  for (i=0; i<n; i++) {
2,052,830✔
54
    tmp[i].function = null_value; // mark as empty
2,021,248✔
55
  }
56

57
  htbl->data = tmp;
31,582✔
58
  htbl->size = n;
31,582✔
59
  htbl->nelems = 0;
31,582✔
60
  htbl->resize_threshold = (uint32_t) (MAP_HTBL_RESIZE_RATIO * n);
31,582✔
61
}
31,582✔
62

63

64

65
/*
66
 * Delete the table
67
 */
68
static void delete_map_htbl(map_htbl_t *htbl) {
31,582✔
69
  safe_free(htbl->data);
31,582✔
70
  htbl->data = NULL;
31,582✔
71
}
31,582✔
72

73

74
/*
75
 * Empty the table
76
 */
77
static void reset_map_htbl(map_htbl_t *htbl) {
×
78
  uint32_t i, n;
79

80
  n = htbl->size;
×
81
  for (i=0; i<n; i++) {
×
82
    htbl->data[i].function = null_value; // mark as empty
×
83
  }
84
  htbl->nelems = 0;
×
85
}
×
86

87

88

89

90
/*
91
 * Compute the hash code of (f a[0] ... a[n-1])
92
 * - f and a[0] ... a[n-1] must all be valid objects in vtbl
93
 */
94
static uint32_t hash_fun_app(value_t f, uint32_t n, value_t *a) {
355,042✔
95
  uint32_t h;
96

97
  h = jenkins_hash_intarray2(a, n, 0x83421bca);
355,042✔
98
  return jenkins_hash_pair(f, 0, h);
355,042✔
99
}
100

101

102

103
/*
104
 * Compute the hash code of a pair (f, i)
105
 * - f must be a function object
106
 * - i must be a mapping object of same arity as f
107
 */
108
static uint32_t hash_map_pair(value_table_t *table, value_t f, value_t i) {
104,752✔
109
  value_map_t *map;
110

111
  assert(object_is_map(table, i) && object_is_function(table, f));
112
  map = (value_map_t *) table->desc[i].ptr;
104,752✔
113
  assert(map->arity == ((value_fun_t *) table->desc[f].ptr)->arity);
114
  return hash_fun_app(f, map->arity, map->arg);
104,752✔
115
}
116

117

118

119

120
/*
121
 * Check whether object i matches a[0] ... a[n-1]
122
 * - i must be a mapping object with n arguments
123
 * - i matches if a[0] = arg[0] ... a[n-1] = arg[n-1]
124
 */
125
static bool mapping_matches_array(value_table_t *table, value_t i, uint32_t n, value_t *a) {
133,336✔
126
  value_map_t *map;
127
  uint32_t j;
128

129
  assert(object_is_map(table, i));
130
  map = (value_map_t *) table->desc[i].ptr;
133,336✔
131
  assert(map->arity == n);
132

133
  for (j=0; j<n; j++) {
351,676✔
134
    if (a[j] != map->arg[j]) return false;
231,320✔
135
  }
136

137
  return true;
120,356✔
138
}
139

140

141

142
/*
143
 * Check whether object i and j match each other
144
 * - both must be mapping objects with the same number of arguments
145
 */
146
static bool mappings_match(value_table_t *table, value_t i, value_t j) {
28,910✔
147
  value_map_t *map1, *map2;
148
  uint32_t k, n;
149

150
  assert(object_is_map(table, i) && object_is_map(table, j));
151
  map1 = (value_map_t *) table->desc[i].ptr;
28,910✔
152
  map2 = (value_map_t *) table->desc[j].ptr;
28,910✔
153
  n = map1->arity;
28,910✔
154
  assert(map2->arity == n);
155

156
  for (k=0; k<n; k++) {
29,981✔
157
    if (map1->arg[k] != map2->arg[k]) return false;
28,910✔
158
  }
159

160
  return true;
1,071✔
161
}
162

163

164
/*
165
 * Search for a pair (f, k) in table such that k is of the form
166
 * (a[0] ... a[n-1] |-> v)
167
 * - vtbl = the value table where all objects are defined
168
 * - return v if such a pair is found, null_value otherwise
169
 */
170
static value_t hash_eval_app(value_table_t *table, value_t f, uint32_t n, value_t *a) {
250,290✔
171
  map_pair_t *d;
172
  uint32_t i, mask;
173
  value_t j;
174

175
  assert(table->mtbl.nelems < table->mtbl.size);
176

177
  mask = table->mtbl.size - 1;
250,290✔
178
  d = table->mtbl.data;
250,290✔
179
  i = hash_fun_app(f, n, a) & mask;
250,290✔
180
  for (;;) {
181
    if (d[i].function < 0) return null_value;
291,109✔
182
    if (d[i].function == f) {
147,714✔
183
      j = d[i].map;
111,128✔
184
      if (mapping_matches_array(table, j, n, a)) {
111,128✔
185
        return vtbl_map_result(table, j);
106,895✔
186
      }
187
    }
188
    i ++;
40,819✔
189
    i &= mask;
40,819✔
190
  }
191
}
192

193

194

195
/*
196
 * Copy pair p into a clean data array
197
 * - mask = size of data - 1 (data's size must be a power of 2)
198
 * - p must be a valid pair (i.e., p->function >= 0)
199
 * - there must be an empty slot in data
200
 */
201
static void map_htbl_clean_copy(value_table_t *table, map_pair_t *data,
61,143✔
202
                                map_pair_t *p, uint32_t mask) {
203
  uint32_t i;
204

205
  i = hash_map_pair(table, p->function, p->map) & mask;
61,143✔
206
  while (data[i].function >= 0) {
77,571✔
207
    i ++;
16,428✔
208
    i &= mask;
16,428✔
209
  }
210
  data[i] = *p;
61,143✔
211
}
61,143✔
212

213

214

215
/*
216
 * Make the hash table twice as large
217
 */
218
static void map_htbl_extend(value_table_t *table) {
89✔
219
  uint32_t n, n2;
220
  map_pair_t *tmp, *p;
221
  uint32_t i, mask;
222

223
  n = table->mtbl.size;
89✔
224
  n2 = n << 1;
89✔
225
  if (n2 >= MAP_HTBL_MAX_SIZE) {
89✔
226
    out_of_memory();
×
227
  }
228

229
  tmp = (map_pair_t *) safe_malloc(n2 * sizeof(map_pair_t));
89✔
230
  for (i=0; i<n2; i++) {
174,681✔
231
    tmp[i].function = null_value;
174,592✔
232
  }
233

234
  mask = n2 - 1;
89✔
235
  p = table->mtbl.data;
89✔
236
  for (i=0; i<n; i++) {
87,385✔
237
    if (p->function >= 0) {
87,296✔
238
      map_htbl_clean_copy(table, tmp, p, mask);
61,143✔
239
    }
240
    p ++;
87,296✔
241
  }
242

243
  safe_free(table->mtbl.data);
89✔
244
  table->mtbl.data = tmp;
89✔
245
  table->mtbl.size = n2;
89✔
246
  table->mtbl.resize_threshold = (uint32_t) (MAP_HTBL_RESIZE_RATIO * n2);
89✔
247
}
89✔
248

249

250

251
/*
252
 * Add the pair (f, i) to the hash table
253
 * - there must not be a matching (f, j) in the table already
254
 */
255
static void add_hash_pair(value_table_t *table, value_t f, value_t i) {
43,609✔
256
  map_pair_t *d;
257
  uint32_t j, mask;
258

259
  assert(table->mtbl.nelems < table->mtbl.size);
260

261
  mask = table->mtbl.size - 1;
43,609✔
262
  d = table->mtbl.data;
43,609✔
263
  j = hash_map_pair(table, f, i) & mask;
43,609✔
264
  while (d[j].function >= 0) {
117,348✔
265
    assert(d[j].function != f || !mappings_match(table, i, d[j].map));
266
    j ++;
73,739✔
267
    j &= mask;
73,739✔
268
  }
269

270
  assert(d[j].function == null_value);
271
  d[j].function = f;
43,609✔
272
  d[j].map = i;
43,609✔
273

274
  table->mtbl.nelems ++;
43,609✔
275
  if (table->mtbl.nelems > table->mtbl.resize_threshold) {
43,609✔
276
    map_htbl_extend(table);
89✔
277
  }
278

279
}
43,609✔
280

281

282

283
/********************************
284
 *  QUEUE FOR DELAYED PRINTING  *
285
 *******************************/
286

287
/*
288
 * Initialize: don't allocate the mark vector yet
289
 */
290
static void init_vtbl_queue(vtbl_queue_t *vq) {
31,582✔
291
  init_int_queue(&vq->queue, 0);
31,582✔
292
  vq->mark = NULL;
31,582✔
293
  vq->size = 0;
31,582✔
294
}
31,582✔
295

296
/*
297
 * Reset: empty the queue and delete the mark vector
298
 */
299
static void reset_vtbl_queue(vtbl_queue_t *vq) {
49,537✔
300
  int_queue_reset(&vq->queue);
49,537✔
301
  delete_bitvector(vq->mark);
49,537✔
302
  vq->mark = NULL;
49,537✔
303
  vq->size = 0;
49,537✔
304
}
49,537✔
305

306
/*
307
 * Delete
308
 */
309
static void delete_vtbl_queue(vtbl_queue_t *vq) {
31,582✔
310
  delete_int_queue(&vq->queue);
31,582✔
311
  delete_bitvector(vq->mark);
31,582✔
312
  vq->mark = NULL;
31,582✔
313
}
31,582✔
314

315

316
/*
317
 * Extend the mark vector to at least size n
318
 * - n must be larger than vq->size
319
 */
320
static void resize_vtbl_queue(vtbl_queue_t *vq, uint32_t n) {
1✔
321
  uint32_t new_size;
322

323
  assert(vq->size < n && n <= MAX_VALUE_TABLE_SIZE);
324

325
  n = (n + 63) & ~63u;       // round n up to a multiple of 64
1✔
326
  if (n < DEF_VTBL_QUEUE_SIZE) {
1✔
327
    n = DEF_VTBL_QUEUE_SIZE;
1✔
328
  }
329

330
  new_size = vq->size << 1;  // double the size
1✔
331
  if (new_size < n) new_size = n;
1✔
332

333
  vq->mark = extend_bitvector0(vq->mark, new_size, vq->size);
1✔
334
  vq->size = new_size;
1✔
335

336
  assert((vq->size & 63u) == 0);
337
}
1✔
338

339

340
/*
341
 * Add v to the queue if it's not marked then mark v
342
 */
343
static void vtbl_queue_push(vtbl_queue_t *vq, value_t v) {
3✔
344
  assert(0 <= v && v < (int32_t) MAX_VALUE_TABLE_SIZE);
345

346
  if (v >= vq->size) {
3✔
347
    resize_vtbl_queue(vq, v+1);
1✔
348
    assert(v < vq->size);
349
  }
350
  if (!tst_bit(vq->mark, v)) {
3✔
351
    set_bit(vq->mark, v);
3✔
352
    int_queue_push(&vq->queue, v);
3✔
353
  }
354
}
3✔
355

356

357

358
/****************************************
359
 *  HASH SETS FOR UPDATE NORMALIZATION  *
360
 ***************************************/
361

362
/*
363
 * Initialize hset: use the default size
364
 */
365
static void init_map_hset(map_hset_t *hset) {
119✔
366
  uint32_t i, n;
367
  value_t *tmp;
368

369
  n = MAP_HSET_DEFAULT_SIZE;
119✔
370
  assert(n < MAP_HSET_MAX_SIZE);
371

372
  tmp = (value_t *) safe_malloc(n * sizeof(value_t));
119✔
373
  for (i=0; i<n; i++) {
3,927✔
374
    tmp[i] = null_value;
3,808✔
375
  }
376

377
  hset->data = tmp;
119✔
378
  hset->size = n;
119✔
379
  hset->nelems = 0;
119✔
380
  hset->resize_threshold = (uint32_t) (MAP_HSET_RESIZE_RATIO * n);
119✔
381
}
119✔
382

383

384
/*
385
 * Delete hset
386
 */
387
static void delete_map_hset(map_hset_t *hset) {
119✔
388
  safe_free(hset->data);
119✔
389
  hset->data = NULL;
119✔
390
}
119✔
391

392

393
/*
394
 * Empty hset
395
 */
396
static void reset_map_hset(map_hset_t *hset) {
13,600✔
397
  uint32_t i, n;
398

399
  n = hset->size;
13,600✔
400
  if (n >= MAP_HSET_REDUCE_THRESHOLD) {
13,600✔
401
    // reduce data to an array of default size
402
    safe_free(hset->data);
56✔
403

404
    n = MAP_HSET_DEFAULT_SIZE;
56✔
405
    assert(n < MAP_HSET_MAX_SIZE && n < MAP_HSET_REDUCE_THRESHOLD);
406
    hset->data = (value_t *) safe_malloc(n * sizeof(value_t));
56✔
407
    hset->size = n;
56✔
408
    hset->resize_threshold = (uint32_t) (MAP_HSET_RESIZE_RATIO * n);
56✔
409
  }
410

411
  // empty data
412
  for (i=0; i<n; i++) {
449,280✔
413
    hset->data[i] = null_value;
435,680✔
414
  }
415
  hset->nelems = 0;
13,600✔
416
}
13,600✔
417

418

419
/*
420
 * Hash code for a tuple of objects a[0 ... n]
421
 */
422
static inline uint32_t hash_map_tuple(value_t *a, uint32_t n) {
71,887✔
423
  return jenkins_hash_intarray2(a, n, 0x543f1a83);
71,887✔
424
}
425

426

427
/*
428
 * Hash code for mapping object i
429
 */
430
static uint32_t hash_map_object(value_table_t *table, value_t i) {
56,749✔
431
  value_map_t *map;
432

433
  assert(object_is_map(table, i));
434
  map = (value_map_t *) table->desc[i].ptr;
56,749✔
435
  return hash_map_tuple(map->arg, map->arity);
56,749✔
436
}
437

438

439
/*
440
 * Copy v into clean array d
441
 * - mask = size of d - 1, where size of d is a power of 2
442
 */
443
static void map_hset_clean_copy(value_table_t *table, value_t *d, value_t v, uint32_t mask) {
19,380✔
444
  uint32_t i;
445

446
  i = hash_map_object(table, v) & mask;
19,380✔
447
  while (d[i] >= 0) {
26,754✔
448
    i++;
7,374✔
449
    i &= mask;
7,374✔
450
  }
451
  d[i] = v;
19,380✔
452
}
19,380✔
453

454

455
/*
456
 * Make the hset twice as large. Keep its content.
457
 */
458
static void map_hset_extend(value_table_t *table, map_hset_t *hset) {
232✔
459
  uint32_t n, n2;
460
  value_t *d, *p;
461
  uint32_t i, mask;
462

463
  n = hset->size;
232✔
464
  n2 = n<<1;
232✔
465
  if (n2 >= MAP_HSET_MAX_SIZE) {
232✔
466
    out_of_memory();
×
467
  }
468

469
  d = (value_t *) safe_malloc(n2 * sizeof(value_t));
232✔
470
  for (i=0; i<n2; i++) {
55,272✔
471
    d[i] = null_value;
55,040✔
472
  }
473

474
  mask = n2 - 1;
232✔
475
  p = hset->data;
232✔
476
  for (i=0; i<n; i++) {
27,752✔
477
    if (p[i] >= 0) {
27,520✔
478
      map_hset_clean_copy(table, d, p[i], mask);
19,380✔
479
    }
480
  }
481

482
  safe_free(p);
232✔
483
  hset->data = d;
232✔
484
  hset->size = n2;
232✔
485
  hset->resize_threshold = (uint32_t) (MAP_HSET_RESIZE_RATIO * n2);
232✔
486
}
232✔
487

488

489
/*
490
 * Add mapping object i to hset:
491
 * - no change if i matches an existing element in hset
492
 */
493
static void hset_add_map(value_table_t *table, map_hset_t *hset, value_t i) {
37,369✔
494
  value_t *d;
495
  value_t k;
496
  uint32_t j, mask;
497

498
  assert(hset->nelems < hset->size);
499

500
  mask = hset->size - 1;
37,369✔
501
  d = hset->data;
37,369✔
502
  j = hash_map_object(table, i) & mask;
37,369✔
503
  for (;;) {
504
    k = d[j];
65,208✔
505
    if (k < 0) break;   // add i
65,208✔
506
    if (mappings_match(table, i, k)) return; // k has precedence
28,910✔
507
    j ++;
27,839✔
508
    j &= mask;
27,839✔
509
  }
510

511
  d[j] = i;
36,298✔
512
  hset->nelems ++;
36,298✔
513
  if (hset->nelems > hset->resize_threshold) {
36,298✔
514
    map_hset_extend(table, hset);
232✔
515
  }
516
}
517

518

519
/*
520
 * Return the map_object that matches tuple a[0... n-1]
521
 * - return null_value if there's no such object
522
 */
523
static value_t hset_find_map(value_table_t *table, map_hset_t *hset, value_t *a, uint32_t n) {
15,138✔
524
  value_t *d;
525
  value_t k;
526
  uint32_t j, mask;
527

528
  assert(hset->nelems < hset->size);
529
  mask = hset->size - 1;
15,138✔
530
  d = hset->data;
15,138✔
531
  j = hash_map_tuple(a, n) & mask;
15,138✔
532
  for (;;) {
533
    k = d[j];
23,885✔
534
    if (k < 0) break; // nothing matches
23,885✔
535
    if (mapping_matches_array(table, k, n, a)) return k;
22,208✔
536
    j ++;
8,747✔
537
    j &= mask;
8,747✔
538
  }
539

540
  return null_value;
1,677✔
541
}
542

543
/*
544
 * Normalize: collect all elements of hset into hset->data[0 ... n-1]
545
 * where n = hset->nelems and sort the elements.
546
 *
547
 * No addition is possible after normalization.
548
 */
549
static void hset_normalize(map_hset_t *hset) {
13,527✔
550
  value_t *d;
551
  uint32_t i, j, n;
552

553
  d = hset->data;
13,527✔
554
  n = hset->size;
13,527✔
555
  j = 0;
13,527✔
556
  for (i=0; i<n; i++) {
446,423✔
557
    if (d[i] >= 0) {
432,896✔
558
      d[j] = d[i];
22,837✔
559
      j ++;
22,837✔
560
    }
561
  }
562
  assert(j == hset->nelems);
563
  int_array_sort(d, j);
13,527✔
564
}
13,527✔
565

566

567

568

569

570

571
/*****************************************
572
 *  TABLE INITIALIZATION/DELETION/RESET  *
573
 ****************************************/
574

575
/*
576
 * Initialize a table;
577
 * - n = initial size. If n is zero, the default size is used.
578
 * - ttbl = attached type table.
579
 */
580
void init_value_table(value_table_t *table, uint32_t n, type_table_t *ttbl) {
31,582✔
581
  if (n == 0) {
31,582✔
582
    n = DEF_VALUE_TABLE_SIZE;
31,582✔
583
  }
584
  if (n >= MAX_VALUE_TABLE_SIZE) {
31,582✔
585
    out_of_memory();
×
586
  }
587

588
  table->size = n;
31,582✔
589
  table->nobjects = 0;
31,582✔
590
  table->kind = (uint8_t *) safe_malloc(n * sizeof(uint8_t));
31,582✔
591
  table->desc = (value_desc_t *) safe_malloc(n * sizeof(value_desc_t));
31,582✔
592
  table->canonical = allocate_bitvector0(n);
31,582✔
593

594
  table->type_table = ttbl;
31,582✔
595
  init_int_htbl(&table->htbl, 0);
31,582✔
596
  init_bvconstant(&table->buffer);
31,582✔
597
  init_ivector(&table->aux_vector, 0);
31,582✔
598
  init_map_htbl(&table->mtbl);
31,582✔
599
  init_vtbl_queue(&table->queue);
31,582✔
600

601
  table->hset1 = NULL;
31,582✔
602
  table->hset2 = NULL;
31,582✔
603

604
  table->unknown_value = null_value;
31,582✔
605
  table->true_value = null_value;
31,582✔
606
  table->false_value = null_value;
31,582✔
607

608
  table->zero_rdiv_fun = null_value;
31,582✔
609
  table->zero_idiv_fun = null_value;
31,582✔
610
  table->zero_mod_fun = null_value;
31,582✔
611

612
  table->first_tmp = -1; // no temporary objects
31,582✔
613

614
  table->aux_namer = NULL;
31,582✔
615
  table->unint_namer = NULL;
31,582✔
616
}
31,582✔
617

618

619
/*
620
 * Make the table larger (by 50%)
621
 */
622
static void extend_value_table(value_table_t *table) {
56✔
623
  uint32_t n;
624

625
  n = table->size + 1;
56✔
626
  n += n>>1;
56✔
627
  assert(n > table->size);
628

629
  if (n >= MAX_VALUE_TABLE_SIZE) {
56✔
630
    out_of_memory();
×
631
  }
632

633
  table->size = n;
56✔
634
  table->kind = (uint8_t *) safe_realloc(table->kind, n * sizeof(uint8_t));
56✔
635
  table->desc = (value_desc_t *) safe_realloc(table->desc, n * sizeof(value_desc_t));
56✔
636
  table->canonical = extend_bitvector0(table->canonical, n, table->size);
56✔
637
}
56✔
638

639

640
/*
641
 * Allocate a new object index
642
 * - kind and descriptor are not initialized
643
 */
644
static value_t allocate_object(value_table_t *table) {
121,179✔
645
  value_t i;
646

647
  i = table->nobjects;
121,179✔
648
  if (i == table->size) {
121,179✔
649
    extend_value_table(table);
56✔
650
  }
651
  assert(i < table->size);
652
  table->nobjects = i+1;
121,179✔
653
  return i;
121,179✔
654
}
655

656

657
/*
658
 * Return hset1 or hset2 (allocate and initialize it if needed)
659
 */
660
static map_hset_t *get_hset1(value_table_t *table) {
13,435✔
661
  map_hset_t *set;
662

663
  set = table->hset1;
13,435✔
664
  if (set == NULL) {
13,435✔
665
    set = (map_hset_t *) safe_malloc(sizeof(map_hset_t));
100✔
666
    init_map_hset(set);
100✔
667
    table->hset1 = set;
100✔
668
  }
669
  return set;
13,435✔
670
}
671

672
static map_hset_t *get_hset2(value_table_t *table) {
165✔
673
  map_hset_t *set;
674

675
  set = table->hset2;
165✔
676
  if (set == NULL) {
165✔
677
    set = (map_hset_t *) safe_malloc(sizeof(map_hset_t));
19✔
678
    init_map_hset(set);
19✔
679
    table->hset2 = set;
19✔
680
  }
681
  return set;
165✔
682
}
683

684

685
/*
686
 * Delete hset1 and hset2 if they exist
687
 */
688
static void delete_hsets(value_table_t *table) {
31,582✔
689
  if (table->hset1 != NULL) {
31,582✔
690
    delete_map_hset(table->hset1);
100✔
691
    safe_free(table->hset1);
100✔
692
    table->hset1 = NULL;
100✔
693
  }
694

695
  if (table->hset2 != NULL) {
31,582✔
696
    delete_map_hset(table->hset2);
19✔
697
    safe_free(table->hset2);
19✔
698
    table->hset2 = NULL;
19✔
699
  }
700
}
31,582✔
701

702

703
/*
704
 * Reset hset1 and hset2 if they exist
705
 */
706
static void reset_hsets(value_table_t *table) {
×
707
  if (table->hset1 != NULL) {
×
708
    reset_map_hset(table->hset1);
×
709
  }
710
  if (table->hset2 != NULL) {
×
711
    reset_map_hset(table->hset2);
×
712
  }
713
}
×
714

715

716
/*
717
 * Delete object descriptors
718
 */
719
static inline void delete_value_unint(value_unint_t *d) {
5,143✔
720
  safe_free(d->name);
5,143✔
721
  safe_free(d);
5,143✔
722
}
5,143✔
723

724
static inline void delete_value_fun(value_fun_t *d) {
12,234✔
725
  safe_free(d->name);
12,234✔
726
  safe_free(d);
12,234✔
727
}
12,234✔
728

729
/*
730
 * Delete descriptors for objects k ... nobjects - 1
731
 */
732
static void vtbl_delete_descriptors(value_table_t *table, uint32_t k) {
31,582✔
733
  uint32_t i, n;
734

735
  n = table->nobjects;
31,582✔
736
  table->nobjects = k;
31,582✔
737

738
  assert(k <= n);
739
  for (i=k; i<n; i++) {
152,761✔
740
    switch (table->kind[i]) {
121,179✔
741
    case UNKNOWN_VALUE:
38,646✔
742
    case BOOLEAN_VALUE:
743
      break;
38,646✔
744
    case RATIONAL_VALUE:
15,718✔
745
      q_clear(&table->desc[i].rational);
15,718✔
746
      break;
15,718✔
747
    case ALGEBRAIC_VALUE:
23✔
748
#ifdef HAVE_MCSAT
749
      lp_algebraic_number_destruct(table->desc[i].ptr);
23✔
750
      safe_free(table->desc[i].ptr);
23✔
751
#else
752
      assert(false);
753
#endif
754
      break;
23✔
755
    case UNINTERPRETED_VALUE:
5,143✔
756
      delete_value_unint(table->desc[i].ptr);
5,143✔
757
      break;
5,143✔
758
    case FUNCTION_VALUE:
12,234✔
759
      delete_value_fun(table->desc[i].ptr);
12,234✔
760
      break;
12,234✔
761
    case FINITEFIELD_VALUE:
21✔
762
      q_clear(&((value_ff_t*)table->desc[i].ptr)->value);
21✔
763
      q_clear(&((value_ff_t*)table->desc[i].ptr)->mod);
21✔
764
      /* fall through */
765
    case BITVECTOR_VALUE:
49,415✔
766
    case TUPLE_VALUE:
767
    case MAP_VALUE:
768
    case UPDATE_VALUE:
769
      safe_free(table->desc[i].ptr);
49,415✔
770
      break;
49,415✔
771
    }
772
  }
773
}
31,582✔
774

775

776
/*
777
 * Reset the table:
778
 * - delete all descriptors
779
 * - empty the table.
780
 */
781
void reset_value_table(value_table_t *table) {
×
782
  vtbl_delete_descriptors(table, 0);
×
783
  reset_int_htbl(&table->htbl);
×
784
  reset_map_htbl(&table->mtbl);
×
785
  reset_vtbl_queue(&table->queue);
×
786
  reset_hsets(table);
×
787

788
  ivector_reset(&table->aux_vector);
×
789

790
  table->nobjects = 0;
×
791
  table->unknown_value = null_value;
×
792
  table->true_value = null_value;
×
793
  table->false_value = null_value;
×
794
  table->first_tmp = -1;
×
795
}
×
796

797

798
/*
799
 * Delete the table
800
 */
801
void delete_value_table(value_table_t *table) {
31,582✔
802
  vtbl_delete_descriptors(table, 0);
31,582✔
803
  safe_free(table->kind);
31,582✔
804
  safe_free(table->desc);
31,582✔
805
  delete_bitvector(table->canonical);
31,582✔
806
  delete_int_htbl(&table->htbl);
31,582✔
807
  delete_bvconstant(&table->buffer);
31,582✔
808
  delete_ivector(&table->aux_vector);
31,582✔
809
  delete_map_htbl(&table->mtbl);
31,582✔
810
  delete_vtbl_queue(&table->queue);
31,582✔
811
  delete_hsets(table);
31,582✔
812
  table->kind = NULL;
31,582✔
813
  table->desc = NULL;
31,582✔
814
  table->canonical = NULL;
31,582✔
815
}
31,582✔
816

817

818

819

820

821
/******************************************************
822
 *  CONSTRUCTORS: VALUES THAT DON'T USE HASH CONSING  *
823
 *****************************************************/
824

825
/*
826
 * Unknown value: for undefined stuff
827
 */
828
value_t vtbl_mk_unknown(value_table_t *table) {
49,524✔
829
  value_t i;
830

831
  i = table->unknown_value;
49,524✔
832
  if (i < 0) {
49,524✔
833
    i = allocate_object(table);
187✔
834
    table->kind[i] = UNKNOWN_VALUE;
187✔
835
    table->desc[i].ptr = NULL;
187✔
836
    table->unknown_value = i;
187✔
837
    set_bit(table->canonical, i);
187✔
838
  }
839
  return i;
49,524✔
840
}
841

842

843
/*
844
 * True and false
845
 */
846
value_t vtbl_mk_true(value_table_t *table) {
403,403✔
847
  value_t i;
848

849
  i = table->true_value;
403,403✔
850
  if (i < 0) {
403,403✔
851
    i = allocate_object(table);
24,438✔
852
    table->kind[i] = BOOLEAN_VALUE;
24,438✔
853
    table->desc[i].integer = 1; // non-zero means true
24,438✔
854
    table->true_value = i;
24,438✔
855
    set_bit(table->canonical, i);
24,438✔
856
  }
857
  return i;
403,403✔
858
}
859

860
value_t vtbl_mk_false(value_table_t *table) {
863,847✔
861
  value_t i;
862

863
  i = table->false_value;
863,847✔
864
  if (i < 0) {
863,847✔
865
    i = allocate_object(table);
14,021✔
866
    table->kind[i] = BOOLEAN_VALUE;
14,021✔
867
    table->desc[i].integer = 0; // zero means false
14,021✔
868
    table->false_value = i;
14,021✔
869
    set_bit(table->canonical, i);
14,021✔
870
  }
871
  return i;
863,847✔
872
}
873

874

875
/*
876
 * Booleans: val = 0 means false, val != 0 means true
877
 */
878
value_t vtbl_mk_bool(value_table_t *table, int32_t val) {
559,423✔
879
  if (val) {
559,423✔
880
    return vtbl_mk_true(table);
147,475✔
881
  } else {
882
    return vtbl_mk_false(table);
411,948✔
883
  }
884
}
885

886

887
/*
888
 * Negation of v
889
 */
890
value_t vtbl_mk_not(value_table_t *table, value_t v) {
396,508✔
891
  assert(v >= 0 && (v == table->true_value || v == table->false_value));
892

893
  if (v == table->true_value) {
396,508✔
894
    return vtbl_mk_false(table);
271,237✔
895
  } else {
896
    return vtbl_mk_true(table);
125,271✔
897
  }
898
}
899

900

901

902

903
/********************************************
904
 *  NORMALIZATION OF FUNCTIONS AND UPDATES  *
905
 *******************************************/
906

907
/*
908
 * Normalize an array of mapping objects a[0 ... n-1]
909
 * - sort a and remove duplicates
910
 * - return the number of elements left in a
911
 */
912
static uint32_t normalize_map_array(uint32_t n, value_t *a) {
8,120✔
913
  uint32_t i, j;
914
  value_t v, w;
915

916
  if (n > 1) {
8,120✔
917
    int_array_sort(a, n);
1,443✔
918
    j = 1;
1,443✔
919
    v = a[0];
1,443✔
920
    for (i=1; i<n; i++) {
51,352✔
921
      w = a[i];
49,909✔
922
      if (v != w) {
49,909✔
923
        a[j] = w;
49,909✔
924
        j ++;
49,909✔
925
        v = w;
49,909✔
926
      }
927
    }
928
    n = j;
1,443✔
929
  }
930

931
  return n;
8,120✔
932
}
933

934

935

936
/*
937
 * Remove all elements in array a[0 ... n-1] that give the same
938
 * value as def.
939
 * - return the number of elements left in a
940
 */
941
static uint32_t remove_redundant_mappings(value_table_t *table, uint32_t n, value_t *a, value_t def) {
21,647✔
942
  uint32_t i, j;
943
  value_t v;
944

945
  j = 0;
21,647✔
946
  for (i=0; i<n; i++) {
96,171✔
947
    v = a[i];
74,524✔
948
    if (vtbl_map_result(table, v) != def) {
74,524✔
949
      a[j] = v;
61,208✔
950
      j++;
61,208✔
951
    }
952
  }
953

954
  return j;
21,647✔
955
}
956

957

958

959
/*
960
 * Compute the set of mapping objects for i
961
 * - i must be an update value or a function
962
 * - hset = where the set is stored
963
 * - def = address where default value will be copied
964
 * - tau = address where the function type will be copied
965
 *
966
 * The mapping objects are added to hset then hset is normalized.
967
 * Whatever is in hset when the function is called is kept.
968
 * The default value and type of the function are copied into
969
 * *def and *tau
970
 */
971
static void normalize_update(value_table_t *table, value_t i, map_hset_t *hset, value_t *def, type_t *tau) {
13,527✔
972
  value_update_t *upd;
973
  value_fun_t *fun;
974
  uint32_t j, n;
975

976
  while (object_is_update(table, i)) {
13,715✔
977
    upd = (value_update_t *) table->desc[i].ptr;
188✔
978
    hset_add_map(table, hset, upd->map);
188✔
979
    i = upd->fun;
188✔
980
  }
981

982
  assert(object_is_function(table, i));
983
  fun = (value_fun_t *) table->desc[i].ptr;
13,527✔
984
  *def = fun->def;
13,527✔
985
  *tau = fun->type;
13,527✔
986
  n = fun->map_size;
13,527✔
987
  for (j=0; j<n; j++) {
23,878✔
988
    hset_add_map(table, hset, fun->map[j]);
10,351✔
989
  }
990

991
  hset_normalize(hset);
13,527✔
992

993
  // the mappings are in hset->data[0.. nelems-1]
994
  if (! object_is_unknown(table, *def)) {
13,527✔
995
    n = remove_redundant_mappings(table, hset->nelems, hset->data, *def);
13,527✔
996
    hset->nelems = n;
13,527✔
997
  }
998
}
13,527✔
999

1000

1001

1002
/*
1003
 * Exported version: expand update object i.
1004
 * - store the mappings in table->hset1
1005
 */
1006
void vtbl_expand_update(value_table_t *table, value_t i, value_t *def, type_t *tau) {
66✔
1007
  map_hset_t *hset;
1008

1009
  assert(0 <= i && i < table->nobjects && table->kind[i] == UPDATE_VALUE);
1010

1011
  hset = get_hset1(table);
66✔
1012
  reset_map_hset(hset);
66✔
1013
  normalize_update(table, i, hset, def, tau);
66✔
1014
}
66✔
1015

1016

1017
/*
1018
 * Get the type of a function or update object i
1019
 */
1020
type_t vtbl_function_type(value_table_t *table, value_t i) {
×
1021
  value_update_t *upd;
1022
  value_fun_t *fun;
1023

1024
  while (object_is_update(table, i)) {
×
1025
    upd = (value_update_t *) table->desc[i].ptr;
×
1026
    i = upd->fun;
×
1027
  }
1028

1029
  assert(object_is_function(table, i));
1030
  fun = (value_fun_t *) table->desc[i].ptr;
×
1031

1032
  return fun->type;
×
1033
}
1034

1035

1036

1037

1038
/**********************************************************
1039
 *  MORE NORMALIZATION FOR FUNCTIONS WITH FINITE DOMAINS  *
1040
 *********************************************************/
1041

1042
/*
1043
 * A function is defined by a set of mappings + a default value
1044
 * - that may be ambiguous if the domain is finite and the default is not unknown
1045
 * - to ensure a normal representation, we force the default value to be
1046
 *   the most common value for f (ties are breaking by selecting as default
1047
 *   value the one with the smallest id).
1048
 */
1049

1050
/*
1051
 * Return the element x of a that occurs most often
1052
 * - ties are broken by selecting elements with smaller index
1053
 * - a must be nonempty and sorted in increasing order
1054
 * - return the number of occurrences of x in *count
1055
 */
1056
static value_t majority_element(value_t *a, uint32_t n, uint32_t *count) {
146✔
1057
  uint32_t i;
1058
  value_t b, x;
1059
  uint32_t nb, nx;
1060

1061
  assert(n > 0);
1062

1063
  // b =  best so far, nb = best count so far
1064
  b = null_value;
146✔
1065
  nb = 0;
146✔
1066

1067
  x = a[0];
146✔
1068
  nx = 1;
146✔
1069
  for (i=1; i<n; i++) {
25,039✔
1070
    if (x == a[i]) {
24,893✔
1071
      nx ++;
24,097✔
1072
    } else {
1073
      if (nx > nb) {
796✔
1074
        b = x;
490✔
1075
        nb = nx;
490✔
1076
      }
1077
      x = a[i];
796✔
1078
      nx = 1;
796✔
1079
    }
1080
  }
1081

1082
  // last element
1083
  if (nx > nb) {
146✔
1084
    b = x;
3✔
1085
    nb = nx;
3✔
1086
  }
1087

1088
  *count = nb;
146✔
1089
  return b;
146✔
1090
}
1091

1092
/*
1093
 * Get the most frequent value in the range of map[0 ... n-1]
1094
 * - n must be positive
1095
 * - if there are ties, the value with smallest id is returned
1096
 * - store the number of occurrences in *count.
1097
 */
1098
static value_t get_default_for_map(value_table_t *table, uint32_t n, value_t *a, uint32_t *count) {
146✔
1099
  ivector_t *v;
1100
  uint32_t i;
1101
  value_t x;
1102

1103
  assert(n > 0);
1104

1105
  v = &table->aux_vector;
146✔
1106
  resize_ivector(v, n);
146✔
1107
  for (i=0; i<n; i++) {
25,185✔
1108
    v->data[i] = vtbl_map_result(table, a[i]);
25,039✔
1109
  }
1110
  int_array_sort(v->data, n);
146✔
1111

1112
  x = majority_element(v->data, n, count);
146✔
1113
  ivector_reset(v);
146✔
1114

1115
  return x;
146✔
1116
}
1117

1118

1119
/*
1120
 * Change the default value for a function definition
1121
 * - tau = function type
1122
 * - a = function mappings
1123
 * - n = number of elements in a
1124
 * - old_def = current default
1125
 * - new_def = new default
1126
 *
1127
 * This removes mappings from a and creates new ones but a's size
1128
 * does not increase. Return the number of mappings in a after
1129
 * swapping.
1130
 */
1131
static uint32_t swap_default_for_map(value_table_t *table, type_t tau, uint32_t n, value_t *a, value_t old_def, value_t new_def) {
73✔
1132
  value_t buffer[10];
1133
  value_t *aux;
1134
  function_type_t *ft;
1135
  map_hset_t *hset;
1136
  uint32_t i, j, m, dsize;
1137
  value_t k;
1138

1139
  assert(old_def != new_def);
1140

1141
  // add all the current maps of a to hset2
1142
  hset = get_hset2(table);
73✔
1143
  reset_map_hset(hset);
73✔
1144
  for (i=0; i<n; i++) {
13,534✔
1145
    hset_add_map(table, hset, a[i]);
13,461✔
1146
  }
1147

1148
  ft = function_type_desc(table->type_table, tau);
73✔
1149
  m = ft->ndom; // function arity
73✔
1150

1151
  aux = buffer;
73✔
1152
  if (m > 10) {
73✔
1153
    assert(m < UINT32_MAX/sizeof(value_t));
1154
    aux = (value_t *) safe_malloc(m * sizeof(value_t));
×
1155
  }
1156

1157
  dsize = card_of_domain_type(table->type_table, tau);
73✔
1158
  assert(dsize < UINT32_MAX); // i.e., dsize is the exact cardinality
1159

1160
  /*
1161
   * scan all tuples in domain of tau
1162
   * for each tuple: search for a matching map in hset2
1163
   * - if there's none add the map [tuple -> old_def] to a
1164
   * - if the map's value is equal to new_def skip it
1165
   * - otherwise, add it to a
1166
   */
1167
  j = 0;
73✔
1168
  for (i=0; i<dsize; i++) {
15,211✔
1169
    vtbl_gen_object_tuple(table, m, ft->domain, i, aux);
15,138✔
1170
    k = hset_find_map(table, hset, aux, m);
15,138✔
1171
    if (k < 0) {
15,138✔
1172
      k = vtbl_mk_map(table, m, aux, old_def);
1,677✔
1173
      a[j] = k;
1,677✔
1174
      j ++;
1,677✔
1175
    } else if (vtbl_map_result(table, k) != new_def) {
13,461✔
1176
      a[j] = k;
9,207✔
1177
      j ++;
9,207✔
1178
    }
1179
  }
1180

1181
  if (m > 10) {
73✔
1182
    safe_free(aux);
×
1183
  }
1184

1185
  assert(j <= n);
1186
  int_array_sort(a, j);
73✔
1187

1188
  return j;
73✔
1189
}
1190

1191

1192
/*
1193
 * Normalize a function with finite domain
1194
 * - tau = function type
1195
 * - a = mappings for the function
1196
 * - n = number of elements in a
1197
 * - *def = current default value
1198
 *
1199
 * If the representation is changed then a and *def are modified and
1200
 * the function returns the number of elements in a. Otherwise, the function returns n.
1201
 *
1202
 * NOTE: this must be called after the standard normalization procedure:
1203
 * - array a must not contain duplicate maps nor any map that gives the same value as def
1204
 */
1205
static uint32_t normalize_finite_domain_function(value_table_t *table, type_t tau, uint32_t n, value_t *a, value_t *def) {
1,313✔
1206
  uint32_t dsize, def_count, new_count;
1207
  value_t new_def;
1208

1209
  assert(!object_is_unknown(table, *def) && type_has_finite_domain(table->type_table, tau));
1210

1211
  dsize = card_of_domain_type(table->type_table, tau);
1,313✔
1212
  def_count = dsize - n;
1,313✔
1213
  if (n >= def_count) {
1,313✔
1214
    /*
1215
     * Check whether some other v in the range of a[0 ... n] occurs more
1216
     * often than def_count
1217
     */
1218
    new_def = get_default_for_map(table, n, a, &new_count);
146✔
1219
    if (new_count > def_count || (new_count == def_count && new_def < *def)) {
146✔
1220
      n = swap_default_for_map(table, tau, n, a, *def, new_def);
73✔
1221
      *def = new_def;
73✔
1222
    }
1223
  }
1224

1225
  return n;
1,313✔
1226
}
1227

1228

1229
/***************
1230
 *  UTILITIES  *
1231
 **************/
1232

1233
/*
1234
 * Check whether a and b are equal arrays
1235
 * - both must have size n
1236
 */
1237
static bool equal_arrays(value_t *a, value_t *b, uint32_t n) {
77,225✔
1238
  uint32_t i;
1239

1240
  for (i=0; i<n; i++) {
150,443✔
1241
    if (a[i] != b[i]) return false;
73,218✔
1242
  }
1243
  return true;
77,225✔
1244
}
1245

1246

1247
/*
1248
 * Check whether all elements in a are canonical
1249
 */
1250
static bool canonical_array(value_table_t *table, value_t *a, uint32_t n) {
164,292✔
1251
  uint32_t i;
1252

1253
  for (i=0; i<n; i++) {
495,835✔
1254
    if (! object_is_canonical(table, a[i])) {
331,543✔
1255
      return false;
×
1256
    }
1257
  }
1258

1259
  return true;
164,292✔
1260
}
1261

1262

1263

1264

1265
/********************
1266
 *   HASH CONSING   *
1267
 *******************/
1268

1269
/*
1270
 * There's a hobj for rationals, unint, bitvectors, tuples, and map objects.
1271
 * Each hobj structure starts with a function descriptor m
1272
 * with three fields:
1273
 *   m.hash = compute hash code
1274
 *   m.eq = check equality
1275
 *   m.build = build a fresh value
1276
 *
1277
 * For map objects, hash-consing relies only on the function and arguments:
1278
 * - all map objects with the same function must have the same number of arguments.
1279
 * - two maps objects with the same function and arguments must also have the
1280
 *   same result.
1281
 */
1282
typedef struct {
1283
  int_hobj_t m;
1284
  value_table_t *table;
1285
  rational_t *v;
1286
} rational_hobj_t;
1287

1288
typedef struct {
1289
  int_hobj_t m;
1290
  value_table_t *table;
1291
  void *a;
1292
} algebraic_hobj_t;
1293

1294
typedef struct {
1295
  int_hobj_t m;
1296
  value_table_t *table;
1297
  rational_t *v;
1298
  rational_t *mod;
1299
} ff_hobj_t;
1300

1301
typedef struct {
1302
  int_hobj_t m;
1303
  value_table_t *table;
1304
  type_t tau;
1305
  int32_t id;
1306
} const_hobj_t;
1307

1308
typedef struct {
1309
  int_hobj_t m;
1310
  value_table_t *table;
1311
  uint32_t nbits;
1312
  uint32_t *data;  // must be normalized modulo (2^nbits)
1313
} bv_hobj_t;
1314

1315
typedef struct {
1316
  int_hobj_t m;
1317
  value_table_t *table;
1318
  uint32_t nelems;
1319
  value_t *elem;
1320
} tuple_hobj_t;
1321

1322
typedef struct {
1323
  int_hobj_t m;
1324
  value_table_t *table;
1325
  uint32_t arity;
1326
  value_t *arg;
1327
  value_t val;
1328
} map_hobj_t;
1329

1330

1331

1332
/*
1333
 * Function representation:
1334
 * - a default value (can be unknown)
1335
 * - an array map[0... n-1] of mapping objects sorted
1336
 */
1337
typedef struct {
1338
  int_hobj_t m;
1339
  value_table_t *table;
1340
  type_t type;
1341
  uint32_t arity;
1342
  value_t def;
1343
  uint32_t map_size;
1344
  value_t *map;
1345
  bool ambiguous;
1346
} fun_hobj_t;
1347

1348

1349
/*
1350
 * Function update: for hash-consing, the update
1351
 * is converted into a function representation as above
1352
 * - default value + map array
1353
 */
1354
typedef struct {
1355
  int_hobj_t m;
1356
  value_table_t *table;
1357
  type_t type;
1358
  uint32_t arity;
1359
  value_t fun;
1360
  value_t updt;
1361

1362
  value_t def;
1363
  uint32_t map_size;
1364
  value_t *map;
1365
  bool ambiguous;
1366
} update_hobj_t;
1367

1368

1369
/*
1370
 * Hash functions
1371
 */
1372
static uint32_t hash_rational_value(rational_hobj_t *o) {
279,828✔
1373
  uint32_t h_num, h_den;
1374
  q_hash_decompose(o->v, &h_num, &h_den);
279,828✔
1375
  return jenkins_hash_mix2(h_num, h_den);
279,828✔
1376
}
1377

1378
static uint32_t hash_finitefield_value(ff_hobj_t *o) {
107✔
1379
  assert(q_is_integer(o->v));
1380
  return jenkins_hash_mix2(q_hash_numerator(o->v), q_hash_numerator(o->mod));
107✔
1381
}
1382

1383
static uint32_t hash_algebraic_value(algebraic_hobj_t *a) {
26✔
1384
#ifdef HAVE_MCSAT
1385
  return lp_algebraic_number_hash_approx(a->a, 5);
26✔
1386
#else
1387
  assert(false);
1388
  return 0;
1389
#endif
1390
}
1391

1392
static uint32_t hash_const_value(const_hobj_t *o) {
7,919✔
1393
  return jenkins_hash_pair(o->tau, o->id, 0x417a6eca);
7,919✔
1394
}
1395

1396
static uint32_t hash_bv_value(bv_hobj_t *o) {
163,577✔
1397
  return bvconst_hash(o->data, o->nbits);
163,577✔
1398
}
1399

1400
static uint32_t hash_tuple_value(tuple_hobj_t *o) {
×
1401
  return jenkins_hash_intarray2(o->elem, o->nelems, 0x21398aba);
×
1402
}
1403

1404
static uint32_t hash_map_value(map_hobj_t *o) {
66,734✔
1405
  uint32_t h;
1406

1407
  h = jenkins_hash_intarray2(o->arg, o->arity, 0xabde6320);
66,734✔
1408
  return jenkins_hash_pair(o->val, 0, h);
66,734✔
1409
}
1410

1411
static uint32_t hash_fun_value(fun_hobj_t *o) {
18,079✔
1412
  uint32_t h;
1413

1414
  h = jenkins_hash_intarray2(o->map, o->map_size, 0x9765aef5);
18,079✔
1415
  return jenkins_hash_pair(o->def, 0, h);
18,079✔
1416
}
1417

1418
static uint32_t hash_update_value(update_hobj_t *o) {
13,369✔
1419
  uint32_t h;
1420

1421
  h = jenkins_hash_intarray2(o->map, o->map_size, 0x9765aef5);
13,369✔
1422
  return jenkins_hash_pair(o->def, 0, h);
13,369✔
1423
}
1424

1425

1426

1427
/*
1428
 * Equality testing: compare the object being constructed with
1429
 * an existing value of index i in the table.
1430
 */
1431
static bool equal_rational_value(rational_hobj_t *o, value_t i) {
263,821✔
1432
  value_table_t *table;
1433

1434
  table = o->table;
263,821✔
1435
  return table->kind[i] == RATIONAL_VALUE && q_eq(&table->desc[i].rational, o->v);
263,821✔
1436
}
1437

1438
static bool equal_finitefield_value(ff_hobj_t *o, value_t i) {
86✔
1439
  value_table_t *table;
1440
  value_ff_t *v_ff;
1441

1442
  table = o->table;
86✔
1443
  if (table->kind[i] != FINITEFIELD_VALUE) {
86✔
1444
    return false;
×
1445
  }
1446
  v_ff = table->desc[i].ptr;
86✔
1447
  return q_eq(&v_ff->value, o->v) && q_eq(&v_ff->mod, o->mod);
86✔
1448
}
1449

1450
static bool equal_algebraic_value(algebraic_hobj_t *o, value_t i) {
4✔
1451
#ifdef HAVE_MCSAT
1452
  value_table_t *table;
1453

1454
  table = o->table;
4✔
1455
  return table->kind[i] == ALGEBRAIC_VALUE && lp_algebraic_number_cmp(table->desc[i].ptr, o->a) == 0;
4✔
1456
#else
1457
  assert(false);
1458
  return false;
1459
#endif
1460

1461
}
1462

1463
static bool equal_const_value(const_hobj_t *o, value_t i) {
1,270✔
1464
  value_table_t *table;
1465
  value_unint_t *d;
1466

1467
  table = o->table;
1,270✔
1468
  if (table->kind[i] != UNINTERPRETED_VALUE) {
1,270✔
1469
    return false;
×
1470
  }
1471
  d = table->desc[i].ptr;
1,270✔
1472
  return d->type == o->tau && d->index == o->id;
1,270✔
1473
}
1474

1475
static bool equal_bv_value(bv_hobj_t *o, value_t i) {
122,865✔
1476
  value_table_t *table;
1477
  value_bv_t *d;
1478

1479
  table = o->table;
122,865✔
1480
  if (table->kind[i] != BITVECTOR_VALUE) {
122,865✔
1481
    return false;
×
1482
  }
1483
  d = table->desc[i].ptr;
122,865✔
1484
  return d->nbits == o->nbits && bvconst_eq(d->data, o->data, d->width);
122,865✔
1485
}
1486

1487

1488
static bool equal_tuple_value(tuple_hobj_t *o, value_t i) {
×
1489
  value_table_t *table;
1490
  value_tuple_t *d;
1491

1492
  table = o->table;
×
1493
  if (table->kind[i] != TUPLE_VALUE) {
×
1494
    return false;
×
1495
  }
1496
  d = table->desc[i].ptr;
×
1497
  return d->nelems == o->nelems && equal_arrays(o->elem, d->elem, d->nelems);
×
1498
}
1499

1500
static bool equal_map_value(map_hobj_t *o, value_t i) {
58,081✔
1501
  value_table_t *table;
1502
  value_map_t *d;
1503

1504
  table = o->table;
58,081✔
1505
  if (table->kind[i] != MAP_VALUE) {
58,081✔
1506
    return false;
×
1507
  }
1508
  d = table->desc[i].ptr;
58,081✔
1509
  return d->val == o->val && d->arity == o->arity && equal_arrays(o->arg, d->arg, d->arity);
58,081✔
1510
}
1511

1512

1513
static bool equal_fun_value(fun_hobj_t *o, value_t i) {
11,253✔
1514
  value_table_t *table;
1515
  value_fun_t *f;
1516
  map_hset_t *hset;
1517
  type_t tau;
1518
  value_t def;
1519

1520
  table = o->table;
11,253✔
1521
  switch (table->kind[i]) {
11,253✔
1522
  case FUNCTION_VALUE:
11,253✔
1523
    f = (value_fun_t *) table->desc[i].ptr;
11,253✔
1524
    return f->type == o->type && f->def == o->def
5,845✔
1525
      && f->map_size == o->map_size
5,845✔
1526
      && equal_arrays(f->map, o->map, o->map_size);
17,098✔
1527

1528
  case UPDATE_VALUE:
×
1529
    hset = get_hset2(table);
×
1530
    reset_map_hset(hset);
×
1531
    normalize_update(table, i, hset, &def, &tau);
×
1532
    return tau == o->type &&  def == o->def
×
1533
      && o->map_size == hset->nelems
×
1534
      && equal_arrays(hset->data, o->map, o->map_size);
×
1535

1536
  default:
×
1537
    return false;
×
1538
  }
1539
}
1540

1541

1542
static bool equal_update_value(update_hobj_t *o, value_t i) {
24,620✔
1543
  value_table_t *table;
1544
  value_fun_t *f;
1545
  map_hset_t *hset;
1546
  type_t tau;
1547
  value_t def;
1548

1549
  table = o->table;
24,620✔
1550
  switch (table->kind[i]) {
24,620✔
1551
  case FUNCTION_VALUE:
24,528✔
1552
    f = (value_fun_t *) table->desc[i].ptr;
24,528✔
1553
    return f->type == o->type && f->def == o->def
13,207✔
1554
      && f->map_size == o->map_size
13,207✔
1555
      && equal_arrays(f->map, o->map, o->map_size);
37,735✔
1556

1557
  case UPDATE_VALUE:
92✔
1558
    hset = get_hset2(table);
92✔
1559
    reset_map_hset(hset);
92✔
1560
    normalize_update(table, i, hset, &def, &tau);
92✔
1561
    return tau == o->type &&  def == o->def
92✔
1562
      && o->map_size == hset->nelems
92✔
1563
      && equal_arrays(hset->data, o->map, o->map_size);
184✔
1564

1565
  default:
×
1566
    return false;
×
1567
  }
1568
}
1569

1570

1571

1572
/*
1573
 * Constructors
1574
 */
1575
static value_t build_rational_value(rational_hobj_t *o) {
15,718✔
1576
  value_table_t *table;
1577
  value_t i;
1578

1579
  table = o->table;
15,718✔
1580
  i = allocate_object(table);
15,718✔
1581
  table->kind[i] = RATIONAL_VALUE;
15,718✔
1582
  q_init(&table->desc[i].rational);
15,718✔
1583
  q_set(&table->desc[i].rational, o->v);
15,718✔
1584
  set_bit(table->canonical, i);
15,718✔
1585

1586
  return i;
15,718✔
1587
}
1588

1589

1590
static value_t build_algebraic_value(algebraic_hobj_t *o) {
23✔
1591
#ifdef HAVE_MCSAT
1592
  value_table_t *table;
1593
  value_t i;
1594

1595
  table = o->table;
23✔
1596
  i = allocate_object(table);
23✔
1597
  table->kind[i] = ALGEBRAIC_VALUE;
23✔
1598
  table->desc[i].ptr = safe_malloc(sizeof(lp_algebraic_number_t));
23✔
1599
  lp_algebraic_number_construct_copy(table->desc[i].ptr, o->a);
23✔
1600
  set_bit(table->canonical, i);
23✔
1601

1602
  return i;
23✔
1603
#else
1604
  return null_value;
1605
#endif
1606
}
1607

1608

1609
static value_t build_const_value(const_hobj_t *o) {
5,143✔
1610
  value_table_t *table;
1611
  value_unint_t *d;
1612
  value_t i;
1613

1614
  d = (value_unint_t *) safe_malloc(sizeof(value_unint_t));
5,143✔
1615
  d->type = o->tau;
5,143✔
1616
  d->index = o->id;
5,143✔
1617
  d->name = NULL;
5,143✔
1618

1619

1620
  table = o->table;
5,143✔
1621
  i = allocate_object(table);
5,143✔
1622
  table->kind[i] = UNINTERPRETED_VALUE;
5,143✔
1623
  table->desc[i].ptr = d;
5,143✔
1624
  set_bit(table->canonical, i);
5,143✔
1625

1626
  return i;
5,143✔
1627
}
1628

1629

1630
static value_t build_finitefield_value(ff_hobj_t *o) {
21✔
1631
  value_table_t *table;
1632
  value_ff_t *v_ff;
1633
  value_t i;
1634

1635
  v_ff = (value_ff_t *) safe_malloc(sizeof(value_bv_t));
21✔
1636
  q_init(&v_ff->value);
21✔
1637
  q_init(&v_ff->mod);
21✔
1638
  q_set(&v_ff->value, o->v);
21✔
1639
  q_set(&v_ff->mod, o->mod);
21✔
1640

1641
  table = o->table;
21✔
1642
  i = allocate_object(table);
21✔
1643
  table->kind[i] = FINITEFIELD_VALUE;
21✔
1644
  table->desc[i].ptr = v_ff;
21✔
1645
  set_bit(table->canonical, i);
21✔
1646

1647
  return i;
21✔
1648
}
1649

1650

1651
static value_t build_bv_value(bv_hobj_t *o) {
40,671✔
1652
  value_table_t *table;
1653
  value_bv_t *d;
1654
  uint32_t w;
1655
  value_t i;
1656

1657
  w = (o->nbits + 31) >> 5; // ceil(nbits/32)
40,671✔
1658
  d = (value_bv_t *) safe_malloc(sizeof(value_bv_t) + w * sizeof(uint32_t));
40,671✔
1659
  d->nbits = o->nbits;
40,671✔
1660
  d->width = w;
40,671✔
1661
  bvconst_set(d->data, w, o->data);
40,671✔
1662

1663
  table = o->table;
40,671✔
1664
  i = allocate_object(table);
40,671✔
1665
  table->kind[i] = BITVECTOR_VALUE;
40,671✔
1666
  table->desc[i].ptr = d;
40,671✔
1667
  set_bit(table->canonical, i);
40,671✔
1668

1669
  return i;
40,671✔
1670
}
1671

1672

1673
static value_t build_tuple_value(tuple_hobj_t *o) {
×
1674
  value_table_t *table;
1675
  value_tuple_t *d;
1676
  uint32_t j, n;
1677
  value_t i;
1678

1679

1680
  n = o->nelems;
×
1681
  if (n >= VTBL_MAX_TUPLE_SIZE) {
×
1682
    out_of_memory();
×
1683
  }
1684
  d = (value_tuple_t *) safe_malloc(sizeof(value_tuple_t) + n * sizeof(value_t));
×
1685
  d->nelems = n;
×
1686
  for (j=0; j<n; j++) {
×
1687
    d->elem[j] = o->elem[j];
×
1688

1689
  }
1690

1691
  table = o->table;
×
1692
  i = allocate_object(table);
×
1693
  table->kind[i] = TUPLE_VALUE;
×
1694
  table->desc[i].ptr = d;
×
1695

1696
  if (canonical_array(table, d->elem, n)) {
×
1697
    set_bit(table->canonical, i);
×
1698
  } else {
1699
    clr_bit(table->canonical, i);
×
1700
  }
1701

1702
  return i;
×
1703
}
1704

1705

1706
static value_t build_map_value(map_hobj_t *o) {
8,653✔
1707
  value_table_t *table;
1708
  value_map_t *d;
1709
  uint32_t j, n;
1710
  value_t i;
1711

1712
  n = o->arity;
8,653✔
1713
  if (n >= VTBL_MAX_MAP_ARITY) {
8,653✔
1714
    out_of_memory();
×
1715
  }
1716
  d = (value_map_t *) safe_malloc(sizeof(value_map_t) + n * sizeof(value_t));
8,653✔
1717
  d->arity = n;
8,653✔
1718
  d->val = o->val;
8,653✔
1719
  for (j=0; j<n; j++) {
24,728✔
1720
    d->arg[j] = o->arg[j];
16,075✔
1721
  }
1722

1723
  table = o->table;
8,653✔
1724
  i = allocate_object(table);
8,653✔
1725
  table->kind[i] = MAP_VALUE;
8,653✔
1726
  table->desc[i].ptr = d;
8,653✔
1727

1728
  if (canonical_array(table, d->arg, n) && object_is_canonical(table, d->val)) {
8,653✔
1729
    set_bit(table->canonical, i);
8,652✔
1730
  } else {
1731
    clr_bit(table->canonical, i);
1✔
1732
  }
1733

1734
  return i;
8,653✔
1735
}
1736

1737

1738
static value_t build_fun_value(fun_hobj_t *o) {
12,234✔
1739
  value_table_t *table;
1740
  value_fun_t *fun;
1741
  value_t f, i;
1742
  uint32_t j, n;
1743

1744
  table = o->table;
12,234✔
1745

1746
  n = o->map_size;
12,234✔
1747
  if (n >= VTBL_MAX_MAP_SIZE) {
12,234✔
1748
    out_of_memory();
×
1749
  }
1750
  fun = (value_fun_t *) safe_malloc(sizeof(value_fun_t) + n * sizeof(value_t));
12,234✔
1751
  fun->name = NULL;
12,234✔
1752
  fun->type = o->type;
12,234✔
1753
  fun->arity = o->arity;
12,234✔
1754
  fun->map_size = n;
12,234✔
1755
  fun->def = o->def;
12,234✔
1756

1757
  f = allocate_object(table);
12,234✔
1758
  table->kind[f] = FUNCTION_VALUE;
12,234✔
1759
  table->desc[f].ptr = fun;
12,234✔
1760

1761
  for (j=0; j<n; j++) {
55,843✔
1762
    i = o->map[j];
43,609✔
1763
    fun->map[j] = i;
43,609✔
1764
    add_hash_pair(table, f, i);
43,609✔
1765
  }
1766

1767
  // set the canonical flag
1768
  if (!o->ambiguous && object_is_canonical(table, fun->def) &&
24,468✔
1769
      canonical_array(table, fun->map, n)) {
12,234✔
1770
    set_bit(table->canonical, f);
12,234✔
1771
  } else {
1772
    clr_bit(table->canonical, f);
×
1773
  }
1774

1775
  return f;
12,234✔
1776
}
1777

1778

1779
static value_t build_update_value(update_hobj_t *o) {
70✔
1780
  value_table_t *table;
1781
  value_update_t *d;
1782
  value_t i;
1783

1784
  d = (value_update_t *) safe_malloc(sizeof(value_update_t));
70✔
1785
  d->arity = o->arity;
70✔
1786
  d->fun = o->fun;
70✔
1787
  d->map = o->updt;
70✔
1788

1789
  table = o->table;
70✔
1790
  i = allocate_object(table);
70✔
1791
  table->kind[i] = UPDATE_VALUE;
70✔
1792
  table->desc[i].ptr = d;
70✔
1793

1794
  // set the canonical flag
1795
  if (!o->ambiguous && object_is_canonical(table, o->def) &&
80✔
1796
      canonical_array(table, o->map, o->map_size)) {
10✔
1797
    set_bit(table->canonical, i);
10✔
1798
  } else {
1799
    clr_bit(table->canonical, i);
60✔
1800
  }
1801

1802
  return i;
70✔
1803
}
1804

1805
/*
1806
 * Return a rational constant = v
1807
 */
1808
value_t vtbl_mk_rational(value_table_t *table, rational_t *v) {
259,925✔
1809
  rational_hobj_t rational_hobj;
1810
  rational_hobj.m.hash = (hobj_hash_t) hash_rational_value;
259,925✔
1811
  rational_hobj.m.eq = (hobj_eq_t) equal_rational_value;
259,925✔
1812
  rational_hobj.m.build = (hobj_build_t) build_rational_value;
259,925✔
1813
  rational_hobj.table = table;
259,925✔
1814
  rational_hobj.v = v;
259,925✔
1815

1816
  return int_htbl_get_obj(&table->htbl, (int_hobj_t *) &rational_hobj);
259,925✔
1817
}
1818

1819
/*
1820
 * Return a rational constant equal to i
1821
 */
1822
value_t vtbl_mk_int32(value_table_t *table, int32_t i) {
19,558✔
1823
  rational_t aux;
1824
  value_t k;
1825
  rational_hobj_t rational_hobj;
1826

1827
  q_init(&aux);
19,558✔
1828
  q_set32(&aux, i);
19,558✔
1829

1830
  rational_hobj.m.hash = (hobj_hash_t) hash_rational_value;
19,558✔
1831
  rational_hobj.m.eq = (hobj_eq_t) equal_rational_value;
19,558✔
1832
  rational_hobj.m.build = (hobj_build_t) build_rational_value;
19,558✔
1833
  rational_hobj.table = table;
19,558✔
1834
  rational_hobj.v = &aux;
19,558✔
1835

1836
  k = int_htbl_get_obj(&table->htbl, (int_hobj_t *) &rational_hobj);
19,558✔
1837
  q_clear(&aux);
19,558✔
1838

1839
  return k;
19,558✔
1840
}
1841

1842
/*
1843
 * Return a finitefield constant = v
1844
 */
1845
value_t vtbl_mk_finitefield(value_table_t *table, rational_t *v, const rational_t *mod) {
60✔
1846
  ff_hobj_t ff_hobj;
1847
  ff_hobj.m.hash = (hobj_hash_t) hash_finitefield_value;
60✔
1848
  ff_hobj.m.eq = (hobj_eq_t) equal_finitefield_value;
60✔
1849
  ff_hobj.m.build = (hobj_build_t) build_finitefield_value;
60✔
1850
  ff_hobj.table = table;
60✔
1851
  ff_hobj.v = v;
60✔
1852
  ff_hobj.mod = (rational_t*)mod;
60✔
1853

1854
  return int_htbl_get_obj(&table->htbl, (int_hobj_t *) &ff_hobj);
60✔
1855
}
1856

1857
/*
1858
 * Return a finitefield constant = v
1859
 * no check for field size is performed
1860
 */
1861
static value_t vtbl_mk_int32_ff(value_table_t *table, int32_t v, const rational_t *mod) {
47✔
1862
  rational_t aux;
1863
  value_t k;
1864

1865
  q_init(&aux);
47✔
1866
  q_set32(&aux, v);
47✔
1867

1868
  ff_hobj_t ff_hobj;
1869
  ff_hobj.m.hash = (hobj_hash_t) hash_finitefield_value;
47✔
1870
  ff_hobj.m.eq = (hobj_eq_t) equal_finitefield_value;
47✔
1871
  ff_hobj.m.build = (hobj_build_t) build_finitefield_value;
47✔
1872
  ff_hobj.table = table;
47✔
1873
  ff_hobj.v = &aux;
47✔
1874
  ff_hobj.mod = (rational_t*)mod;
47✔
1875

1876
  k = int_htbl_get_obj(&table->htbl, (int_hobj_t *) &ff_hobj);
47✔
1877
  q_clear(&aux);
47✔
1878

1879
  return k;
47✔
1880
}
1881

1882

1883
/*
1884
 * Copy of the algebraic number
1885
 */
1886
value_t vtbl_mk_algebraic(value_table_t *table, void* a) {
26✔
1887
#ifdef HAVE_MCSAT
1888
  algebraic_hobj_t algebraic_hobj;
1889

1890
  algebraic_hobj.m.hash = (hobj_hash_t) hash_algebraic_value;
26✔
1891
  algebraic_hobj.m.eq = (hobj_eq_t) equal_algebraic_value;
26✔
1892
  algebraic_hobj.m.build = (hobj_build_t) build_algebraic_value;
26✔
1893
  algebraic_hobj.table = table;
26✔
1894
  algebraic_hobj.a = a;
26✔
1895

1896
  return int_htbl_get_obj(&table->htbl, (int_hobj_t *) &algebraic_hobj);
26✔
1897
#else
1898
  return null_value;
1899
#endif
1900
}
1901

1902

1903
/*
1904
 * Bit vector constant: defined by array a:
1905
 * - a[i] = 0 means bit[i] = 0
1906
 * - a[i] != 0 means bit[i] = 1
1907
 */
1908
value_t vtbl_mk_bv(value_table_t *table, uint32_t n, int32_t *a) {
66,128✔
1909
  bvconstant_t *b;
1910
  bv_hobj_t bv_hobj;
1911

1912
  // copy the constant in table's buffer
1913
  b = &table->buffer;
66,128✔
1914
  bvconstant_set_bitsize(b, n);
66,128✔
1915
  bvconst_set_array(b->data, a, n);
66,128✔
1916
  bvconst_normalize(b->data, n);
66,128✔
1917

1918
  // hash-consing
1919
  bv_hobj.m.hash = (hobj_hash_t) hash_bv_value;
66,128✔
1920
  bv_hobj.m.eq = (hobj_eq_t) equal_bv_value;
66,128✔
1921
  bv_hobj.m.build = (hobj_build_t) build_bv_value;
66,128✔
1922
  bv_hobj.table = table;
66,128✔
1923
  bv_hobj.nbits = n;
66,128✔
1924
  bv_hobj.data = b->data;
66,128✔
1925
  return int_htbl_get_obj(&table->htbl, (int_hobj_t *) &bv_hobj);
66,128✔
1926
}
1927

1928

1929

1930
/*
1931
 * Bit vector constant defined by an array of words
1932
 * - n = number of bits
1933
 * - a = array of w words (w = ceil(n/32)
1934
 */
1935
value_t vtbl_mk_bv_from_bv(value_table_t *table, uint32_t n, uint32_t *a) {
93,635✔
1936
  bv_hobj_t bv_hobj;
1937

1938
  bvconst_normalize(a, n);
93,635✔
1939

1940
  bv_hobj.m.hash = (hobj_hash_t) hash_bv_value;
93,635✔
1941
  bv_hobj.m.eq = (hobj_eq_t) equal_bv_value;
93,635✔
1942
  bv_hobj.m.build = (hobj_build_t) build_bv_value;
93,635✔
1943
  bv_hobj.table = table;
93,635✔
1944
  bv_hobj.nbits = n;
93,635✔
1945
  bv_hobj.data = a;
93,635✔
1946
  return int_htbl_get_obj(&table->htbl, (int_hobj_t*) &bv_hobj);
93,635✔
1947
}
1948

1949

1950
/*
1951
 * Bit vector constant defined by a bvconstant_t object
1952
 * - b->bitsize = number of bits
1953
 * - b->data = array of 32bit words
1954
 */
1955
value_t vtbl_mk_bv_from_constant(value_table_t *table, bvconstant_t *b) {
34,348✔
1956
  return vtbl_mk_bv_from_bv(table, b->bitsize, b->data);
34,348✔
1957
}
1958

1959

1960
/*
1961
 * Bit vector constant defined by a 64bit integer c
1962
 * - n = number of bits to use
1963
 */
1964
value_t vtbl_mk_bv_from_bv64(value_table_t *table, uint32_t n, uint64_t c) {
46,463✔
1965
  uint32_t aux[2];
1966

1967
  aux[0] = (uint32_t) c;
46,463✔
1968
  aux[1] = (uint32_t) (c >> 32);
46,463✔
1969
  return vtbl_mk_bv_from_bv(table, n, aux);
46,463✔
1970
}
1971

1972

1973
/*
1974
 * Bitvector constant with all bits 0
1975
 * - n = number of bits
1976
 */
1977
value_t vtbl_mk_bv_zero(value_table_t *table, uint32_t n) {
3,756✔
1978
  bvconstant_t *b;
1979
  bv_hobj_t bv_hobj;
1980

1981
  assert(n > 0);
1982

1983
  // store 0b000...0 in the buffer
1984
  b = &table->buffer;
3,756✔
1985
  bvconstant_set_all_zero(b, n);
3,756✔
1986

1987
  bv_hobj.m.hash = (hobj_hash_t) hash_bv_value;
3,756✔
1988
  bv_hobj.m.eq = (hobj_eq_t) equal_bv_value;
3,756✔
1989
  bv_hobj.m.build = (hobj_build_t) build_bv_value;
3,756✔
1990
  bv_hobj.table = table;
3,756✔
1991
  bv_hobj.nbits = n;
3,756✔
1992
  bv_hobj.data = b->data;
3,756✔
1993

1994
  return int_htbl_get_obj(&table->htbl, (int_hobj_t *) &bv_hobj);
3,756✔
1995
}
1996

1997

1998
/*
1999
 * Bitvector constant with all bits 0, except the low-order bit
2000
 * - n = number of bits
2001
 */
2002
value_t vtbl_mk_bv_one(value_table_t *table, uint32_t n) {
×
2003
  bvconstant_t *b;
2004
  bv_hobj_t bv_hobj;
2005

2006
  assert(n > 0);
2007

2008
  // store 0b000..01 in the buffer
2009
  b = &table->buffer;
×
2010
  bvconstant_set_all_zero(b, n);
×
2011
  bvconst_set_bit(b->data, 0);
×
2012

2013
  bv_hobj.m.hash = (hobj_hash_t) hash_bv_value;
×
2014
  bv_hobj.m.eq = (hobj_eq_t) equal_bv_value;
×
2015
  bv_hobj.m.build = (hobj_build_t) build_bv_value;
×
2016
  bv_hobj.table = table;
×
2017
  bv_hobj.nbits = n;
×
2018
  bv_hobj.data = b->data;
×
2019

2020
  return int_htbl_get_obj(&table->htbl, (int_hobj_t *) &bv_hobj);
×
2021
}
2022

2023

2024
/*
2025
 * Tuple (e[0] ... e[n-1])
2026
 */
2027
value_t vtbl_mk_tuple(value_table_t *table, uint32_t n, value_t *e) {
×
2028
  tuple_hobj_t tuple_hobj;
2029

2030
  tuple_hobj.m.hash = (hobj_hash_t) hash_tuple_value;
×
2031
  tuple_hobj.m.eq = (hobj_eq_t) equal_tuple_value;
×
2032
  tuple_hobj.m.build = (hobj_build_t) build_tuple_value;
×
2033
  tuple_hobj.table = table;
×
2034
  tuple_hobj.nelems = n;
×
2035
  tuple_hobj.elem = e;
×
2036

2037
  return int_htbl_get_obj(&table->htbl, (int_hobj_t *) &tuple_hobj);
×
2038
}
2039

2040

2041
/*
2042
 * Constant of type tau and index id
2043
 * - name = optional name
2044
 */
2045
value_t vtbl_mk_const(value_table_t *table, type_t tau, int32_t id, char *name) {
6,412✔
2046
  value_unint_t *d;
2047
  value_t v;
2048
  const_hobj_t const_hobj;
2049

2050
  assert(type_kind(table->type_table, tau) == SCALAR_TYPE ||
2051
         type_kind(table->type_table, tau) == UNINTERPRETED_TYPE ||
2052
         type_kind(table->type_table, tau) == INSTANCE_TYPE);
2053
  assert(0 <= id);
2054

2055
  const_hobj.m.hash = (hobj_hash_t) hash_const_value;
6,412✔
2056
  const_hobj.m.eq = (hobj_eq_t) equal_const_value;
6,412✔
2057
  const_hobj.m.build = (hobj_build_t) build_const_value;
6,412✔
2058
  const_hobj.table = table;
6,412✔
2059
  const_hobj.tau = tau;
6,412✔
2060
  const_hobj.id = id;
6,412✔
2061
  v = int_htbl_get_obj(&table->htbl, (int_hobj_t *) &const_hobj);
6,412✔
2062

2063
  // set the name if needed
2064
  assert(table->kind[v] == UNINTERPRETED_VALUE);
2065
  d = table->desc[v].ptr;
6,412✔
2066
  if (name != NULL && d->name == NULL) {
6,412✔
2067
    d->name = (char *) safe_malloc(strlen(name) + 1);
2✔
2068
    strcpy(d->name, name);
2✔
2069
  }
2070

2071
  return v;
6,412✔
2072
}
2073

2074

2075
/*
2076
 * Mapping object (a[0] ... a[n-1]  |-> v)
2077
 * - return a mapping object
2078
 */
2079
value_t vtbl_mk_map(value_table_t *table, uint32_t n, value_t *a, value_t v) {
66,734✔
2080
  map_hobj_t map_hobj;
2081

2082
  map_hobj.m.hash = (hobj_hash_t) hash_map_value;
66,734✔
2083
  map_hobj.m.eq = (hobj_eq_t) equal_map_value;
66,734✔
2084
  map_hobj.m.build = (hobj_build_t) build_map_value;
66,734✔
2085
  map_hobj.table = table;
66,734✔
2086
  map_hobj.arity = n;
66,734✔
2087
  map_hobj.arg = a;
66,734✔
2088
  map_hobj.val = v;
66,734✔
2089

2090
  return int_htbl_get_obj(&table->htbl, (int_hobj_t *) &map_hobj);
66,734✔
2091
}
2092

2093

2094
/*
2095
 * Function defined by the array a[0...n-1] and default value def
2096
 * - tau = its type
2097
 * - a = array of n mapping objects.
2098
 *   The array must not contain conflicting mappings and all elements in a
2099
 *   must have the right arity (same as defined by type tau). It's allowed
2100
 *   to have duplicate elements in a.
2101
 * - def = default value (must be unknown if no default is given)
2102
 *
2103
 * NOTE: a is modified by the function.
2104
 */
2105
value_t vtbl_mk_function(value_table_t *table, type_t tau, uint32_t n, value_t *a, value_t def) {
8,120✔
2106
  fun_hobj_t fun_hobj;
2107

2108
  assert(good_object(table, def));
2109

2110
  // normalize a
2111
  n = normalize_map_array(n, a);
8,120✔
2112
  if (! object_is_unknown(table, def)) {
8,120✔
2113
    n = remove_redundant_mappings(table, n, a, def);
8,120✔
2114
  }
2115

2116
  // if the function has finite domain and the default is something other than unknown
2117
  // we may need more normalization
2118
  if (type_has_finite_domain(table->type_table, tau) && !object_is_unknown(table, def)) {
8,120✔
2119
    n = normalize_finite_domain_function(table, tau, n, a, &def);
1,313✔
2120
  }
2121

2122
  fun_hobj.m.hash = (hobj_hash_t) hash_fun_value;
8,120✔
2123
  fun_hobj.m.eq = (hobj_eq_t) equal_fun_value;
8,120✔
2124
  fun_hobj.m.build = (hobj_build_t) build_fun_value;
8,120✔
2125
  fun_hobj.table = table;
8,120✔
2126
  fun_hobj.type = tau;
8,120✔
2127
  fun_hobj.arity = function_type_arity(table->type_table, tau);
8,120✔
2128
  fun_hobj.def = def;
8,120✔
2129
  fun_hobj.map_size = n;
8,120✔
2130
  fun_hobj.map = a;
8,120✔
2131
  fun_hobj.ambiguous = false;
8,120✔
2132

2133
  return int_htbl_get_obj(&table->htbl, (int_hobj_t*) &fun_hobj);
8,120✔
2134
}
2135

2136

2137

2138
/*
2139
 * Create (update f (a[0] ... a[n-1]) v)
2140
 */
2141
value_t vtbl_mk_update(value_table_t *table, value_t f, uint32_t n, value_t *a, value_t v) {
13,369✔
2142
  map_hset_t *hset;
2143
  value_t u;
2144
  value_t def;
2145
  type_t tau;
2146
  update_hobj_t update_hobj;
2147

2148
  // build the mapping [a[0] ... a[n-1] --> v]
2149
  u = vtbl_mk_map(table, n, a, v);
13,369✔
2150

2151
  // normalize: add mapping u + normalization of f
2152
  hset = get_hset1(table);
13,369✔
2153
  reset_map_hset(hset);
13,369✔
2154
  hset_add_map(table, hset, u);
13,369✔
2155
  normalize_update(table, f, hset, &def, &tau);
13,369✔
2156

2157
  // hash consing
2158
  update_hobj.m.hash = (hobj_hash_t) hash_update_value;
13,369✔
2159
  update_hobj.m.eq = (hobj_eq_t) equal_update_value;
13,369✔
2160
  update_hobj.m.build = (hobj_build_t) build_update_value;
13,369✔
2161

2162
  update_hobj.table = table;
13,369✔
2163
  update_hobj.type = tau;
13,369✔
2164
  update_hobj.arity = function_type_arity(table->type_table, tau);
13,369✔
2165
  update_hobj.fun = f;
13,369✔
2166
  update_hobj.updt = u;
13,369✔
2167
  update_hobj.def = def;
13,369✔
2168
  update_hobj.map_size = hset->nelems;
13,369✔
2169
  update_hobj.map = hset->data;
13,369✔
2170
  update_hobj.ambiguous = type_has_finite_domain(table->type_table, tau) &&
14,795✔
2171
    !object_is_unknown(table, def);
1,426✔
2172

2173
  return int_htbl_get_obj(&table->htbl, (int_hobj_t*) &update_hobj);
13,369✔
2174
}
2175

2176

2177
/*
2178
 * Create a constant function of type tau and value def
2179
 * - tau must be a function type (-> .... sigma)
2180
 * - def must be an object of a type compatible with sigma
2181
 * - def must not be unknown
2182
 */
2183
value_t vtbl_mk_constant_function(value_table_t *table, type_t tau, value_t def) {
9,959✔
2184
  fun_hobj_t fun_hobj;
2185

2186
  assert(good_object(table, def) && !object_is_unknown(table, def));
2187

2188
  fun_hobj.m.hash = (hobj_hash_t) hash_fun_value;
9,959✔
2189
  fun_hobj.m.eq = (hobj_eq_t) equal_fun_value;
9,959✔
2190
  fun_hobj.m.build = (hobj_build_t) build_fun_value;
9,959✔
2191
  fun_hobj.table = table;
9,959✔
2192
  fun_hobj.type = tau;
9,959✔
2193
  fun_hobj.arity = function_type_arity(table->type_table, tau);
9,959✔
2194
  fun_hobj.def = def;
9,959✔
2195
  fun_hobj.map_size = 0;
9,959✔
2196
  fun_hobj.map = NULL;
9,959✔
2197
  fun_hobj.ambiguous = false;
9,959✔
2198

2199
  return int_htbl_get_obj(&table->htbl, (int_hobj_t*) &fun_hobj);
9,959✔
2200
}
2201

2202

2203
/***********************************************
2204
 *  LOCAL INTERPRETATION FOR DIVISION BY ZERO   *
2205
 **********************************************/
2206

2207
/*
2208
 * In SMT-LIB 2.x, the division operators have an uninterpreted
2209
 * semantics if the divisor is zero. The value table can store
2210
 * a mapping that gives an interpretation for these operations.
2211
 *
2212
 * Example: if mcsat says (/ 1 0) = 5 then we can build a function f
2213
 * that maps 1 to 5, then assign f to table->zero_rdiv_fun.  We store
2214
 * this information in the value table so that model_eval can use it.
2215
 */
2216

2217
#ifndef NDEBUG
2218
static bool is_arith_map_type(type_table_t *tbl, type_t tau) {
2219
  function_type_t *d;
2220

2221
  if (is_function_type(tbl, tau)) {
2222
    d = function_type_desc(tbl, tau);
2223
    return d->ndom == 1 && is_arithmetic_type(d->range) && is_arithmetic_type(d->domain[0]);
2224
  }
2225

2226
  return false;
2227
}
2228

2229
static bool is_plausible_div_by_zero(value_table_t *table, value_t f) {
2230
  value_fun_t *fun;
2231
  value_update_t *upd;
2232

2233
  while (object_is_update(table, f)) {
2234
    upd = vtbl_update(table, f);
2235
    if (upd->arity != 1) return false;
2236
    f = upd->fun;
2237
  }
2238

2239
  if (object_is_function(table, f)) {
2240
    fun = vtbl_function(table, f);
2241
    return fun->arity == 1 && is_arith_map_type(table->type_table, fun->type);
2242
  }
2243

2244
  return false;
2245
}
2246
#endif
2247

2248
/*
2249
 * Give a meaning to real division by zero
2250
 */
2251
void vtbl_set_zero_rdiv(value_table_t *table, value_t f) {
×
2252
  assert(is_plausible_div_by_zero(table, f));
2253
  assert(table->zero_rdiv_fun == null_value);
2254
  table->zero_rdiv_fun = f;
×
2255
}
×
2256

2257
/*
2258
 * Integer division
2259
 */
2260
void vtbl_set_zero_idiv(value_table_t *table, value_t f) {
×
2261
  assert(is_plausible_div_by_zero(table, f));
2262
  assert(table->zero_idiv_fun == null_value);
2263
  table->zero_idiv_fun = f;
×
2264
}
×
2265

2266
/*
2267
 * Modulo
2268
 */
2269
void vtbl_set_zero_mod(value_table_t *table, value_t f) {
1✔
2270
  assert(is_plausible_div_by_zero(table, f));
2271
  assert(table->zero_mod_fun == null_value);
2272
  table->zero_mod_fun = f;
1✔
2273
}
1✔
2274

2275

2276
/*
2277
 * Set a default interpretation for the divide-by-zero functions.
2278
 * The default is (rdiv x 0) = 0  (idiv x 0) = 0 and (mod x 0) = 0 for all real x.
2279
 * - if any of the zero_div function is already assigned, it is kept.
2280
 */
2281
void vtbl_set_default_zero_divide(value_table_t *table) {
59,512✔
2282
  value_t f, z;
2283
  type_t tau;
2284

2285
  if (table->zero_rdiv_fun == null_value ||
59,512✔
2286
      table->zero_idiv_fun == null_value ||
49,553✔
2287
      table->zero_mod_fun == null_value) {
49,553✔
2288
    tau = real_type(table->type_table);
9,959✔
2289
    tau = function_type(table->type_table, tau, 1, &tau); // [real -> real]
9,959✔
2290

2291
    z = vtbl_mk_int32(table, 0);
9,959✔
2292
    f = vtbl_mk_constant_function(table, tau, z);
9,959✔
2293
    assert(is_plausible_div_by_zero(table, f));
2294

2295
    if (table->zero_rdiv_fun == null_value) {
9,959✔
2296
      table->zero_rdiv_fun = f;
9,959✔
2297
    }
2298
    if (table->zero_idiv_fun == null_value) {
9,959✔
2299
      table->zero_idiv_fun = f;
9,959✔
2300
    }
2301
    if (table->zero_mod_fun == null_value) {
9,959✔
2302
      table->zero_mod_fun = f;
9,958✔
2303
    }
2304
  }
2305
}
59,512✔
2306

2307

2308

2309
/********************
2310
 *  DEFAULT VALUES  *
2311
 *******************/
2312

2313
/*
2314
 * Tuple object for the given type
2315
 */
2316
static value_t vtbl_make_tuple(value_table_t *vtbl, tuple_type_t *d) {
×
2317
  value_t buffer[10];
2318
  value_t *aux;
2319
  uint32_t i, n;
2320
  value_t v;
2321

2322
  n = d->nelem;
×
2323
  aux = buffer;
×
2324
  if (n > 10) {
×
2325
    aux = (value_t *) safe_malloc(n * sizeof(value_t));
×
2326
  }
2327

2328
  for (i=0; i<n; i++) {
×
2329
    aux[i] = vtbl_make_object(vtbl, d->elem[i]);
×
2330
  }
2331
  v = vtbl_mk_tuple(vtbl, n, aux);
×
2332

2333
  if (n > 10) {
×
2334
    safe_free(aux);
×
2335
  }
2336

2337
  return v;
×
2338
}
2339

2340

2341
/*
2342
 * Return some value of type tau
2343
 */
2344
value_t vtbl_make_object(value_table_t *vtbl, type_t tau) {
25,486✔
2345
  type_table_t *types;
2346
  value_t v;
2347

2348
  types = vtbl->type_table;
25,486✔
2349

2350
  switch (type_kind(types, tau)) {
25,486✔
2351
  case BOOL_TYPE:
4,890✔
2352
    v = vtbl_mk_false(vtbl);
4,890✔
2353
    break;
4,890✔
2354

2355
  case INT_TYPE:
9,307✔
2356
  case REAL_TYPE:
2357
    v = vtbl_mk_int32(vtbl, 0);
9,307✔
2358
    break;
9,307✔
2359

2360
  case FF_TYPE:
47✔
2361
    v = vtbl_mk_int32_ff(vtbl, 0, ff_type_size(types, tau));
47✔
2362
    break;
47✔
2363

2364
  case BITVECTOR_TYPE:
3,756✔
2365
    v = vtbl_mk_bv_zero(vtbl, bv_type_size(types, tau));
3,756✔
2366
    break;
3,756✔
2367

2368
  case SCALAR_TYPE:
1,402✔
2369
  case UNINTERPRETED_TYPE:
2370
  case INSTANCE_TYPE:
2371
    // we treat an instance type as an uninterpreted tyoe
2372
    v = vtbl_mk_const(vtbl, tau, 0, NULL);
1,402✔
2373
    break;
1,402✔
2374

2375
  case TUPLE_TYPE:
×
2376
    v = vtbl_make_tuple(vtbl, tuple_type_desc(types, tau));
×
2377
    break;
×
2378

2379
  case FUNCTION_TYPE:
6,084✔
2380
    v = vtbl_make_object(vtbl, function_type_range(types, tau));
6,084✔
2381
    v = vtbl_mk_function(vtbl, tau, 0, NULL, v); // constant function
6,084✔
2382
    break;
6,084✔
2383

2384
  case VARIABLE_TYPE:
×
2385
  default:
2386
    // should not happen
2387
    assert(false);
2388
    v = vtbl_mk_unknown(vtbl);
×
2389
    break;
×
2390
  }
2391

2392
  return v;
25,486✔
2393
}
2394

2395

2396

2397
/*
2398
 * Create two distinct tuples of the given type
2399
 */
2400
static bool vtbl_make_two_tuples(value_table_t *vtbl, tuple_type_t *d, value_t a[2]) {
×
2401
  value_t buffer[10];
2402
  value_t *aux;
2403
  uint32_t i, j, n;
2404
  bool done;
2405

2406
  done = false;
×
2407

2408
  n = d->nelem;
×
2409
  aux = buffer;
×
2410
  if (n > 10) {
×
2411
    aux = (value_t *) safe_malloc(n * sizeof(value_t));
×
2412
  }
2413

2414
  for (i=0; i<n; i++) {
×
2415
    if (vtbl_make_two_objects(vtbl, d->elem[i], a)) {
×
2416
      break;
×
2417
    }
2418
  }
2419
  if (i < n) {
×
2420
    // we have two elements for index i in a[0] and a[1]
2421
    // fill in aux[0 ... n-1] except at position i
2422
    for (j=0; j<n; j++) {
×
2423
      if (j != i) {
×
2424
        aux[j] = vtbl_make_object(vtbl, d->elem[j]);
×
2425
      }
2426
    }
2427

2428
    // first tuple: aux[i] = a[0]
2429
    aux[i] = a[0];
×
2430
    a[0] = vtbl_mk_tuple(vtbl, n, aux);
×
2431
    // second tuple: aux[i] = a[1]
2432
    aux[i] = a[1];
×
2433
    a[1] = vtbl_mk_tuple(vtbl, n, aux);
×
2434

2435
    done = true;
×
2436
  }
2437

2438
  if (n > 10) {
×
2439
    safe_free(aux);
×
2440
  }
2441

2442
  return done;
×
2443
}
2444

2445

2446
/*
2447
 * Attempt to construct two distinct objects of type tau.
2448
 * - return true if that succeeds, false if tau is a singleton type
2449
 * - store the two objects in a[0] and a[1]
2450
 */
2451
bool vtbl_make_two_objects(value_table_t *vtbl, type_t tau, value_t a[2]) {
×
2452
  type_table_t *types;
2453

2454
  types = vtbl->type_table;
×
2455

2456
  switch (type_kind(types, tau)) {
×
2457
  case BOOL_TYPE:
×
2458
    a[0] = vtbl_mk_false(vtbl);
×
2459
    a[1] = vtbl_mk_true(vtbl);
×
2460
    break;
×
2461

2462
  case INT_TYPE:
×
2463
  case REAL_TYPE:
2464
    a[0] = vtbl_mk_int32(vtbl, 0);
×
2465
    a[1] = vtbl_mk_int32(vtbl, 1);
×
2466
    break;
×
2467

2468
  case FF_TYPE:
×
2469
    a[0] = vtbl_mk_int32_ff(vtbl, 0, ff_type_size(types, tau));
×
2470
    a[1] = vtbl_mk_int32_ff(vtbl, 1, ff_type_size(types, tau));
×
2471
    break;
×
2472

2473
  case BITVECTOR_TYPE:
×
2474
    a[0] = vtbl_mk_bv_zero(vtbl, bv_type_size(types, tau));
×
2475
    a[1] = vtbl_mk_bv_one(vtbl, bv_type_size(types, tau));
×
2476
    break;
×
2477

2478
  case SCALAR_TYPE:
×
2479
    if (is_unit_type(types, tau)) return false;
×
2480
    assert(type_card(types, tau) >= 2);
2481
    // fall-through intended
2482

2483
  case UNINTERPRETED_TYPE:
2484
  case INSTANCE_TYPE:
2485
    a[0] = vtbl_mk_const(vtbl, tau, 0, NULL);
×
2486
    a[1] = vtbl_mk_const(vtbl, tau, 1, NULL);
×
2487
    break;
×
2488

2489
  case TUPLE_TYPE:
×
2490
    return vtbl_make_two_tuples(vtbl, tuple_type_desc(types, tau), a);
×
2491

2492
  case FUNCTION_TYPE:
×
2493
    // try to create two constant functions
2494
    if (! vtbl_make_two_objects(vtbl, function_type_range(types, tau), a)) {
×
2495
      return false;
×
2496
    }
2497
    // a[0] and a[1] are two objects of type sigma = range of tau
2498
    a[0] = vtbl_mk_function(vtbl, tau, 0, NULL, a[0]);
×
2499
    a[1] = vtbl_mk_function(vtbl, tau, 0, NULL, a[1]);
×
2500
    break;
×
2501

2502
  case VARIABLE_TYPE:
×
2503
  default:
2504
    assert(false);
2505
    return false;
×
2506
  }
2507

2508
  return true;
×
2509
}
2510

2511

2512

2513

2514
/**************************************
2515
 *  TEST WHETHER OBJECTS ARE PRESENT  *
2516
 *************************************/
2517

2518
/*
2519
 * Check whether a rational or integer constant is in the table
2520
 * - return the object if found, -1 (i.e., null_value otherwise)
2521
 */
2522
value_t vtbl_find_rational(value_table_t *table, rational_t *v) {
×
2523
  rational_hobj_t rational_hobj;
2524
  rational_hobj.m.hash = (hobj_hash_t) hash_rational_value;
×
2525
  rational_hobj.m.eq = (hobj_eq_t) equal_rational_value;
×
2526
  rational_hobj.m.build = (hobj_build_t) build_rational_value;
×
2527
  rational_hobj.table = table;
×
2528
  rational_hobj.v = v;
×
2529

2530
  return int_htbl_find_obj(&table->htbl, (int_hobj_t *) &rational_hobj);
×
2531
}
2532

2533
value_t vtbl_find_int32(value_table_t *table, int32_t x) {
345✔
2534
  rational_t aux;
2535
  value_t k;
2536
  rational_hobj_t rational_hobj;
2537

2538
  q_init(&aux);
345✔
2539
  q_set32(&aux, x);
345✔
2540

2541
  rational_hobj.m.hash = (hobj_hash_t) hash_rational_value;
345✔
2542
  rational_hobj.m.eq = (hobj_eq_t) equal_rational_value;
345✔
2543
  rational_hobj.m.build = (hobj_build_t) build_rational_value;
345✔
2544
  rational_hobj.table = table;
345✔
2545
  rational_hobj.v = &aux;
345✔
2546

2547
  k = int_htbl_find_obj(&table->htbl, (int_hobj_t *) &rational_hobj);
345✔
2548
  q_clear(&aux);
345✔
2549

2550
  return k;
345✔
2551
}
2552

2553
/*
2554
 * Check whether the algebraic number is in the table.
2555
 */
2556
value_t vtbl_find_algebraic(value_table_t *table, void* a) {
×
2557
  algebraic_hobj_t algebraic_hobj;
2558

2559
  algebraic_hobj.m.hash = (hobj_hash_t) hash_algebraic_value;
×
2560
  algebraic_hobj.m.eq = (hobj_eq_t) equal_algebraic_value;
×
2561
  algebraic_hobj.m.build = (hobj_build_t) build_algebraic_value;
×
2562
  algebraic_hobj.table = table;
×
2563
  algebraic_hobj.a = a;
×
2564

2565
  return int_htbl_find_obj(&table->htbl, (int_hobj_t *) &algebraic_hobj);
×
2566
}
2567

2568

2569
/*
2570
 * Check presence of a bitvector constant defined by array of n integers:
2571
 * - bit i is 0 if a[i] == 0
2572
 * - bit i is 1 otherwise
2573
 * - n = number of bits (must be positive).
2574
 */
2575
value_t vtbl_find_bv(value_table_t *table, uint32_t n, int32_t *a) {
×
2576
  bvconstant_t *b;
2577
  bv_hobj_t bv_hobj;
2578

2579
  // copy the constant in table's buffer
2580
  b = &table->buffer;
×
2581
  bvconstant_set_bitsize(b, n);
×
2582
  bvconst_set_array(b->data, a, n);
×
2583
  bvconst_normalize(b->data, n);
×
2584

2585
  // hash-consing
2586
  bv_hobj.m.hash = (hobj_hash_t) hash_bv_value;
×
2587
  bv_hobj.m.eq = (hobj_eq_t) equal_bv_value;
×
2588
  bv_hobj.m.build = (hobj_build_t) build_bv_value;
×
2589
  bv_hobj.table = table;
×
2590
  bv_hobj.nbits = n;
×
2591
  bv_hobj.data = b->data;
×
2592

2593
  return int_htbl_find_obj(&table->htbl, (int_hobj_t *) &bv_hobj);
×
2594
}
2595

2596
/*
2597
 * Same thing for the bitvector defined by c:
2598
 * - n = number of bits (must be <= 64)
2599
 */
2600
value_t vtbl_find_bv64(value_table_t *table, uint32_t n, uint64_t c) {
53✔
2601
  uint32_t aux[2];
2602
  bv_hobj_t bv_hobj;
2603

2604
  c = norm64(c, n);
53✔
2605
  aux[0] = (uint32_t) c;
53✔
2606
  aux[1] = (uint32_t) (c >> 32);
53✔
2607

2608
  bv_hobj.m.hash = (hobj_hash_t) hash_bv_value;
53✔
2609
  bv_hobj.m.eq = (hobj_eq_t) equal_bv_value;
53✔
2610
  bv_hobj.m.build = (hobj_build_t) build_bv_value;
53✔
2611
  bv_hobj.table = table;
53✔
2612
  bv_hobj.nbits = n;
53✔
2613
  bv_hobj.data = aux;
53✔
2614
  return int_htbl_find_obj(&table->htbl, (int_hobj_t *) &bv_hobj);
53✔
2615
}
2616

2617
/*
2618
 * Same thing for the bitvector constant defined by b
2619
 */
2620
value_t vtbl_find_bvconstant(value_table_t *table, bvconstant_t *b) {
5✔
2621
  uint32_t n;
2622
  bv_hobj_t bv_hobj;
2623

2624
  n = b->bitsize;
5✔
2625
  bvconst_normalize(b->data, n);
5✔
2626
  bv_hobj.m.hash = (hobj_hash_t) hash_bv_value;
5✔
2627
  bv_hobj.m.eq = (hobj_eq_t) equal_bv_value;
5✔
2628
  bv_hobj.m.build = (hobj_build_t) build_bv_value;
5✔
2629
  bv_hobj.table = table;
5✔
2630
  bv_hobj.nbits = n;
5✔
2631
  bv_hobj.data = b->data;
5✔
2632
  return int_htbl_find_obj(&table->htbl, (int_hobj_t *) &bv_hobj);
5✔
2633
}
2634

2635
/*
2636
 * Check whether the constant of type tau and index i is present
2637
 */
2638
value_t vtbl_find_const(value_table_t *table, type_t tau, int32_t id) {
1,507✔
2639
  const_hobj_t const_hobj;
2640

2641
  assert(type_kind(table->type_table, tau) == SCALAR_TYPE ||
2642
         type_kind(table->type_table, tau) == UNINTERPRETED_TYPE ||
2643
         type_kind(table->type_table, tau) == INSTANCE_TYPE);
2644
  assert(0 <= id);
2645

2646
  const_hobj.m.hash = (hobj_hash_t) hash_const_value;
1,507✔
2647
  const_hobj.m.eq = (hobj_eq_t) equal_const_value;
1,507✔
2648
  const_hobj.m.build = (hobj_build_t) build_const_value;
1,507✔
2649
  const_hobj.table = table;
1,507✔
2650
  const_hobj.tau = tau;
1,507✔
2651
  const_hobj.id = id;
1,507✔
2652

2653
  return int_htbl_find_obj(&table->htbl, (int_hobj_t *) &const_hobj);
1,507✔
2654
}
2655

2656
/*
2657
 * Check whether the tuple e[0] ... e[n-1] is present
2658
 */
2659
value_t vtbl_find_tuple(value_table_t *table, uint32_t n, value_t *e) {
×
2660
  tuple_hobj_t tuple_hobj;
2661

2662
  tuple_hobj.m.hash = (hobj_hash_t) hash_tuple_value;
×
2663
  tuple_hobj.m.eq = (hobj_eq_t) equal_tuple_value;
×
2664
  tuple_hobj.m.build = (hobj_build_t) build_tuple_value;
×
2665
  tuple_hobj.table = table;
×
2666
  tuple_hobj.nelems = n;
×
2667
  tuple_hobj.elem = e;
×
2668

2669
  return int_htbl_find_obj(&table->htbl, (int_hobj_t *) &tuple_hobj);
×
2670
}
2671

2672
/*
2673
 * Mapping object (a[0] ... a[n-1]  |-> v)
2674
 */
2675
value_t vtbl_find_map(value_table_t *table, uint32_t n, value_t *a, value_t v) {
×
2676
  map_hobj_t map_hobj;
2677

2678
  map_hobj.m.hash = (hobj_hash_t) hash_map_value;
×
2679
  map_hobj.m.eq = (hobj_eq_t) equal_map_value;
×
2680
  map_hobj.m.build = (hobj_build_t) build_map_value;
×
2681
  map_hobj.table = table;
×
2682
  map_hobj.arity = n;
×
2683
  map_hobj.arg = a;
×
2684
  map_hobj.val = v;
×
2685

2686
  return int_htbl_find_obj(&table->htbl, (int_hobj_t *) &map_hobj);
×
2687
}
2688

2689
/*
2690
 * Function: defined by a[0 ... n-1] and the default value:
2691
 * - same conventions as for vtbl_mk_function
2692
 * - a is modified
2693
 */
2694
value_t vtbl_find_function(value_table_t *table, type_t tau, uint32_t n, value_t *a, value_t def) {
×
2695
  fun_hobj_t fun_hobj;
2696

2697
  assert(good_object(table, def));
2698

2699
  // normalize a
2700
  n = normalize_map_array(n, a);
×
2701
  if (! object_is_unknown(table, def)) {
×
2702
    n = remove_redundant_mappings(table, n, a, def);
×
2703
  }
2704

2705
  // if the function has finite domain and the default is something other than unknown
2706
  // we may need more normalization
2707
  if (type_has_finite_domain(table->type_table, tau) && !object_is_unknown(table, def)) {
×
2708
    n = normalize_finite_domain_function(table, tau, n, a, &def);
×
2709
  }
2710

2711
  fun_hobj.m.hash = (hobj_hash_t) hash_fun_value;
×
2712
  fun_hobj.m.eq = (hobj_eq_t) equal_fun_value;
×
2713
  fun_hobj.m.build = (hobj_build_t) build_fun_value;
×
2714
  fun_hobj.table = table;
×
2715
  fun_hobj.type = tau;
×
2716
  fun_hobj.arity = function_type_arity(table->type_table, tau);
×
2717
  fun_hobj.def = def;
×
2718
  fun_hobj.map_size = n;
×
2719
  fun_hobj.map = a;
×
2720
  fun_hobj.ambiguous = false;
×
2721

2722
  return int_htbl_find_obj(&table->htbl, (int_hobj_t*) &fun_hobj);
×
2723
}
2724

2725

2726

2727
/**********************************
2728
 *  ENUMERATION OF FINITE TYPES   *
2729
 *********************************/
2730

2731
/*
2732
 * Expand index i into an array of n indices a[0 ... n-1]
2733
 * - where a[k] is an index for type tau[k]
2734
 */
2735
static void vtbl_expand_tuple_code(type_table_t *types, uint32_t n, type_t *tau, uint32_t i, uint32_t *a) {
15,138✔
2736
  uint32_t j, q, c;
2737

2738
  for (j=0; j<n; j++) {
30,276✔
2739
    assert(is_finite_type(types, tau[j]));
2740
    c = type_card(types, tau[j]);
15,138✔
2741
    /*
2742
     * i is c * q + r with 0 <= r < c
2743
     * store r for a[j]
2744
     */
2745
    q = i / c;
15,138✔
2746
    a[j] = i - c * q;
15,138✔
2747

2748
    assert(a[j] < c);
2749
    i = q;
15,138✔
2750
  }
2751
}
15,138✔
2752

2753

2754
/*
2755
 * Convert index i into a tuple of n objects of types tau[0] ... tau[n-1]
2756
 * - store the result into a[0 ... n-1]
2757
 */
2758
void vtbl_gen_object_tuple(value_table_t *table, uint32_t n, type_t *tau, uint32_t i, value_t *a) {
15,138✔
2759
  uint32_t j;
2760

2761
  vtbl_expand_tuple_code(table->type_table, n, tau, i, (uint32_t *) a);
15,138✔
2762
  for (j=0; j<n; j++) {
30,276✔
2763
    a[j] = vtbl_gen_object(table, tau[j], (uint32_t ) a[j]);
15,138✔
2764
  }
2765
}
15,138✔
2766

2767

2768
/*
2769
 * Build object of a tuple type d and index i
2770
 */
2771
static value_t vtbl_gen_tuple(value_table_t *table, tuple_type_t *d, uint32_t i) {
×
2772
  value_t buffer[10];
2773
  value_t *aux;
2774
  uint32_t n;
2775
  value_t v;
2776

2777
  n = d->nelem;
×
2778
  aux = buffer;
×
2779
  if (n > 10) {
×
2780
    assert(n < UINT32_MAX/sizeof(value_t));
2781
    aux = (value_t *) safe_malloc(n * sizeof(value_t));
×
2782
  }
2783

2784
  vtbl_gen_object_tuple(table, n, d->elem, i, aux);
×
2785
  v = vtbl_mk_tuple(table, n, aux);
×
2786

2787
  if (n > 10) {
×
2788
    safe_free(aux);
×
2789
  }
2790

2791
  return v;
×
2792
}
2793

2794

2795
/*
2796
 * Expand index i into an array of n indices a[0 ... n-1]
2797
 * - each a[i] is an index between 0 and card(sigma) - 1
2798
 */
2799
static void vtbl_expand_function_code(type_table_t *types, uint32_t n, type_t sigma, uint32_t i, uint32_t *a) {
×
2800
  uint32_t j, q, c;
2801

2802
  assert(is_finite_type(types, sigma));
2803

2804
  c = type_card(types, sigma);
×
2805
  for (j=0; j<n; j++) {
×
2806
    q = i / c;
×
2807
    a[j] = i - c * q;
×
2808
    assert(a[j] < c);
2809
    i = q;
×
2810
  }
2811
}
×
2812

2813

2814
/*
2815
 * Construct the function of type tau defined by a[0 ... n-1]
2816
 * - f = type descriptor for tau
2817
 * - n = size of tau's domain
2818
 * - every element of a is in tau's range
2819
 */
2820
static value_t vtbl_make_function_from_value_map(value_table_t *table, type_t tau, function_type_t *f, uint32_t n, value_t *a) {
×
2821
  value_t buffer[10];
2822
  value_t buffer2[32];
2823
  value_t *aux;
2824
  value_t *map;
2825
  ivector_t *v;
2826
  uint32_t i, j, m, count;
2827
  value_t k, def;
2828
  fun_hobj_t fun_hobj;
2829

2830
  assert(f == function_type_desc(table->type_table, tau));
2831

2832
  // compute the default value
2833
  v = &table->aux_vector;
×
2834
  resize_ivector(v, n);
×
2835
  for (i=0; i<n; i++) {
×
2836
    v->data[i] = a[i];
×
2837
  }
2838
  int_array_sort(v->data, n);
×
2839
  def = majority_element(v->data, n, &count);
×
2840
  ivector_reset(v);
×
2841

2842
  assert(count <= n);
2843

2844
  if (count == n) {
×
2845
    // special case: constant function
2846
    k = vtbl_mk_function(table, tau, 0, NULL, def);
×
2847
  } else {
2848

2849
    // allocate array map of size (n - count) to store the map objects
2850
    map = buffer2;
×
2851
    if (n - count > 32) {
×
2852
      assert(n - count < UINT32_MAX/sizeof(value_t));
2853
      map = (value_t *) safe_malloc((n - count) * sizeof(value_t));
×
2854
    }
2855

2856
    m = f->ndom; // function arity
×
2857
    aux = buffer;
×
2858
    if (m > 10) {
×
2859
      assert(m < UINT32_MAX/sizeof(value_t));
2860
      aux = (value_t *) safe_malloc(m * sizeof(value_t));
×
2861
    }
2862

2863
    // build the map objects: add them to array map
2864
    // we skip all map objects whose value is def
2865
    j = 0;
×
2866
    for (i=0; i<n; i++) {
×
2867
      if (a[i] != def) {
×
2868
        vtbl_gen_object_tuple(table, m, f->domain, i, aux);
×
2869
        k = vtbl_mk_map(table, m, aux, a[i]);
×
2870
        map[j] = k;
×
2871
        j ++;
×
2872
      }
2873
    }
2874

2875
    assert(j == n - count);
2876

2877
    // no need to remove duplicate etc. so we just sort and
2878
    // call the hash-consing constructor
2879
    int_array_sort(map, j);
×
2880

2881
    fun_hobj.m.hash = (hobj_hash_t) hash_fun_value;
×
2882
    fun_hobj.m.eq = (hobj_eq_t) equal_fun_value;
×
2883
    fun_hobj.m.build = (hobj_build_t) build_fun_value;
×
2884
    fun_hobj.table = table;
×
2885
    fun_hobj.type = tau;
×
2886
    fun_hobj.arity = m;
×
2887
    fun_hobj.def = def;
×
2888
    fun_hobj.map_size = j;
×
2889
    fun_hobj.map = map;
×
2890
    fun_hobj.ambiguous = false;
×
2891

2892
    k = int_htbl_get_obj(&table->htbl, (int_hobj_t*) &fun_hobj);
×
2893

2894
    // cleanup
2895
    if (m > 10) {
×
2896
      safe_free(aux);
×
2897
    }
2898
    if (n - count > 32) {
×
2899
      safe_free(map);
×
2900
    }
2901
  }
2902

2903
  return k;
×
2904
}
2905

2906

2907
/*
2908
 * Function of type tau and index i
2909
 * - tau is finite and i < card(tau)
2910
 */
2911
static value_t vtbl_gen_function(value_table_t *table, type_t tau, uint32_t i) {
×
2912
  uint32_t buffer[32];
2913
  uint32_t *aux;
2914
  type_table_t *types;
2915
  function_type_t *f;
2916
  uint32_t j, n;
2917
  value_t v;
2918

2919
  types = table->type_table;
×
2920
  f = function_type_desc(types, tau);
×
2921

2922
  if (is_unit_type(types, tau)) {
×
2923
    // build the constant function for that type
2924
    assert(i == 0 && is_unit_type(types, f->range));
2925
    v = vtbl_gen_object(table, f->range, 0);
×
2926
    v = vtbl_mk_function(table, tau, 0, NULL, v);
×
2927
  } else {
2928
    n = card_of_domain_type(types, tau);
×
2929
    aux = buffer;
×
2930
    if (n > 32) {
×
2931
      assert(n < UINT32_MAX/sizeof(uint32_t));
2932
      aux = (uint32_t *) safe_malloc(n * sizeof(uint32_t));
×
2933
    }
2934

2935
    vtbl_expand_function_code(types, n, f->range, i, aux);
×
2936
    for (j=0; j<n; j++) {
×
2937
      aux[j] = vtbl_gen_object(table, f->range, aux[j]);
×
2938
    }
2939
    v = vtbl_make_function_from_value_map(table, tau, f, n, (value_t *) aux);
×
2940

2941
    if (n > 32) {
×
2942
      safe_free(aux);
×
2943
    }
2944
  }
2945

2946
  return v;
×
2947
}
2948

2949

2950
/*
2951
 * Bitvector: index i, size n
2952
 */
2953
static value_t vtbl_gen_bitvector(value_table_t *table, uint32_t n, uint32_t i) {
15,136✔
2954
  bvconstant_t *b;
2955

2956
  b = &table->buffer;
15,136✔
2957
  bvconstant_copy64(b, n, (uint64_t) i);
15,136✔
2958
  return vtbl_mk_bv_from_constant(table, b);
15,136✔
2959
}
2960

2961

2962
/*
2963
 * If tau is a finite type, then we can enumerate its elements from
2964
 * 0 to card(tau) - 1. The following function constructs an element
2965
 * of finite type tau given an enumeration index i.
2966
 * - tau must be finite
2967
 * - i must be smaller than card(tau)
2968
 */
2969
value_t vtbl_gen_object(value_table_t *table, type_t tau, uint32_t i) {
15,138✔
2970
  type_table_t *types;
2971
  value_t v;
2972

2973
  types = table->type_table;
15,138✔
2974
  assert(is_finite_type(types, tau) && i < type_card(types, tau));
2975

2976
  switch (type_kind(types, tau)) {
15,138✔
2977
  case BOOL_TYPE:
2✔
2978
    assert(i == 0 || i == 1);
2979
    v = vtbl_mk_bool(table, i);
2✔
2980
    break;
2✔
2981

2982
  case BITVECTOR_TYPE:
15,136✔
2983
    v = vtbl_gen_bitvector(table, bv_type_size(types, tau), i);
15,136✔
2984
    break;
15,136✔
2985

2986
  case SCALAR_TYPE:
×
2987
    v = vtbl_mk_const(table, tau, i, NULL); // anonymous constant
×
2988
    break;
×
2989

2990
  case TUPLE_TYPE:
×
2991
    v = vtbl_gen_tuple(table, tuple_type_desc(types, tau), i);
×
2992
    break;
×
2993

2994
  case FUNCTION_TYPE:
×
2995
    v = vtbl_gen_function(table, tau, i);
×
2996
    break;
×
2997

2998
  default:
×
2999
    assert(false); // can't be a finite type
3000
    v = null_value;
×
3001
    break;
×
3002
  }
3003

3004
  return v;
15,138✔
3005
}
3006

3007

3008
/*
3009
 * Convert function index i for type tau into an array of n objects
3010
 * - n = size of tau's domain
3011
 */
3012
void vtbl_gen_function_map(value_table_t *table, type_t tau, uint32_t i, value_t *a) {
×
3013
  uint32_t buffer[32];
3014
  uint32_t *aux;
3015
  uint32_t j, n;
3016
  type_t sigma;
3017

3018
  assert(type_has_finite_domain(table->type_table, tau));
3019

3020
  n = card_of_domain_type(table->type_table, tau);
×
3021
  aux = buffer;
×
3022
  if (n > 32) {
×
3023
    assert(n < UINT32_MAX/sizeof(uint32_t));
3024
    aux = (uint32_t *) safe_malloc(n * sizeof(uint32_t));
×
3025
  }
3026

3027
  sigma = function_type_range(table->type_table, tau);
×
3028
  vtbl_expand_function_code(table->type_table, n, sigma, i, aux);
×
3029
  for (j=0; j<n; j++) {
×
3030
    a[j] = vtbl_gen_object(table, sigma, aux[j]);
×
3031
  }
3032

3033
  if (n > 32) {
×
3034
    safe_free(aux);
×
3035
  }
3036
}
×
3037

3038

3039
/*
3040
 * TEST EXISTENCE OF OBJECTS USING THEIR INDEX
3041
 */
3042

3043
/*
3044
 * Search for object tuple of index i and type tau[0] x ... x tau[n-1]
3045
 * - return null_value if it's not present
3046
 */
3047
value_t vtbl_find_object_tuple(value_table_t *table, uint32_t n, type_t *tau, uint32_t i) {
×
3048
  uint32_t buffer[10];
3049
  uint32_t *aux;
3050
  uint32_t j;
3051
  value_t v;
3052

3053
  aux = buffer;
×
3054
  if (n > 10) {
×
3055
    assert(n < UINT32_MAX/sizeof(uint32_t));
3056
    aux = (uint32_t *) safe_malloc(n * sizeof(uint32_t));
×
3057
  }
3058

3059
  vtbl_expand_tuple_code(table->type_table, n, tau, i, aux);
×
3060

3061
  for (j=0; j<n; j++) {
×
3062
    v = vtbl_find_object(table, tau[j], aux[j]);
×
3063
    if (v == null_value) goto cleanup;
×
3064
    aux[j] = v;
×
3065
  }
3066

3067
  // all elements aux[0 ... n-1] exist
3068
  v = vtbl_find_tuple(table, n, (value_t *) aux);
×
3069

3070
 cleanup:
×
3071
  if (n > 10) {
×
3072
    safe_free(aux);
×
3073
  }
3074

3075
  return v;
×
3076
}
3077

3078

3079
/*
3080
 * Search for object of index i and tuple type d
3081
 */
3082
static inline value_t vtbl_find_enum_tuple(value_table_t *table, tuple_type_t *d, uint32_t i) {
×
3083
  return vtbl_find_object_tuple(table, d->nelem, d->elem, i);
×
3084
}
3085

3086

3087
/*
3088
 * Search for the map object defined by codes a[0 ... n-1] and value v
3089
 * - a[i] is a code for type tau[i]
3090
 * - v is good value
3091
 * - a is modified
3092
 */
3093
static value_t vtbl_find_enum_map(value_table_t *table, uint32_t n, type_t *tau, uint32_t *a, value_t v) {
×
3094
  uint32_t i;
3095
  value_t k;
3096

3097
  for (i=0; i<n; i++) {
×
3098
    k = vtbl_find_object(table, tau[i], a[i]);
×
3099
    if (k == null_value) goto done;
×
3100
    a[i] = k;
×
3101
  }
3102

3103
  k = vtbl_find_map(table, n, (value_t *) a, v);
×
3104

3105
 done:
×
3106
  return k;
×
3107
}
3108

3109

3110
/*
3111
 * Function of type tau, defined by the array a[0 ... n-1]
3112
 * - f = type descriptor for tau
3113
 * - n = size of tau's domain
3114
 * - every a[i] is in tau's range
3115
 */
3116
static value_t vtbl_find_function_with_value_map(value_table_t *table, type_t tau, function_type_t *f, uint32_t n, value_t *a) {
×
3117
  uint32_t buffer[10];
3118
  value_t buffer2[32];
3119
  uint32_t *aux;
3120
  value_t *map;
3121
  ivector_t *v;
3122
  uint32_t i, j, m, count;
3123
  value_t k, def;
3124
  fun_hobj_t fun_hobj;
3125

3126
  assert(f == function_type_desc(table->type_table, tau));
3127

3128
  // compute the default value
3129
  v = &table->aux_vector;
×
3130
  resize_ivector(v, n);
×
3131
  for (i=0; i<n; i++) {
×
3132
    v->data[i] = a[i];
×
3133
  }
3134
  int_array_sort(v->data, n);
×
3135
  def = majority_element(v->data, n, &count);
×
3136
  ivector_reset(v);
×
3137

3138
  assert(count <= n);
3139

3140
  if (count == 0) {
×
3141
    // special case: constant function
3142
    k = vtbl_find_function(table, tau, 0, NULL, def);
×
3143
  } else {
3144
    // allocate array map of size (n - count) to store the map objects
3145
    map = buffer2;
×
3146
    if (n - count > 32) {
×
3147
      assert(n - count < UINT32_MAX/sizeof(value_t));
3148
      map = (value_t *) safe_malloc((n - count) * sizeof(value_t));
×
3149
    }
3150

3151
    m = f->ndom; // function arity
×
3152
    aux = buffer;
×
3153
    if (m > 10) {
×
3154
      assert(m < UINT32_MAX/sizeof(uint32_t));
3155
      aux = (uint32_t *) safe_malloc(m * sizeof(uint32_t));
×
3156
    }
3157

3158
    // search for the map objects and add them to array map
3159
    j = 0;
×
3160
    for (i=0; i<n; i++) {
×
3161
      if (a[i] != def) {
×
3162
        vtbl_expand_tuple_code(table->type_table, m, f->domain, i, aux);
×
3163
        k = vtbl_find_enum_map(table, m, f->domain, aux, a[i]);
×
3164
        if (k == null_value) {
×
3165
          goto cleanup;
×
3166
        }
3167
        map[j] = k;
×
3168
        j ++;
×
3169
      }
3170
    }
3171

3172
    assert(j == n - count);
3173

3174
    // no need to remove duplicate etc
3175
    int_array_sort(map, j);
×
3176

3177
    fun_hobj.m.hash = (hobj_hash_t) hash_fun_value;
×
3178
    fun_hobj.m.eq = (hobj_eq_t) equal_fun_value;
×
3179
    fun_hobj.m.build = (hobj_build_t) build_fun_value;
×
3180
    fun_hobj.table = table;
×
3181
    fun_hobj.type = tau;
×
3182
    fun_hobj.arity = m;
×
3183
    fun_hobj.def = def;
×
3184
    fun_hobj.map_size = j;
×
3185
    fun_hobj.map = map;
×
3186
    fun_hobj.ambiguous = false;
×
3187

3188
    k = int_htbl_find_obj(&table->htbl, (int_hobj_t*) &fun_hobj);
×
3189

3190
  cleanup:
×
3191
    if (m > 10) {
×
3192
      safe_free(aux);
×
3193
    }
3194
    if (n - count > 32) {
×
3195
      safe_free(map);
×
3196
    }
3197
  }
3198

3199
  return k;
×
3200
}
3201

3202
/*
3203
 * Function of type tau and index i
3204
 * - tau must be finite and i must be smaller than card(tau)
3205
 */
3206
static value_t vtbl_find_enum_function(value_table_t *table, type_t tau, uint32_t i) {
×
3207
  uint32_t buffer[32];
3208
  uint32_t *aux;
3209
  type_table_t *types;
3210
  function_type_t *f;
3211
  uint32_t j, n;
3212
  value_t v;
3213

3214
  types = table->type_table;
×
3215
  f = function_type_desc(types, tau);
×
3216

3217
  if (is_unit_type(types, tau)) {
×
3218
    // only element is the constant function of type tau
3219
    assert(i == 0 && is_unit_type(types, f->range));
3220
    v = vtbl_find_object(table, f->range, 0);
×
3221
    if (v != null_value) {
×
3222
      v = vtbl_find_function(table, tau, 0, NULL, v);
×
3223
    }
3224
  } else {
3225
    n = card_of_domain_type(types, tau);
×
3226
    aux = buffer;
×
3227
    if (n > 32) {
×
3228
      assert(n < UINT32_MAX/sizeof(uint32_t));
3229
      aux = (uint32_t *) safe_malloc(n * sizeof(uint32_t));
×
3230
    }
3231

3232
    vtbl_expand_function_code(types, n, f->range, i, aux);
×
3233
    for (j=0; j<n; j++) {
×
3234
      v = vtbl_find_object(table, f->range, aux[j]);
×
3235
      if (v == null_value) {
×
3236
        goto cleanup;
×
3237
      }
3238
      aux[j] = v;
×
3239
    }
3240

3241
    // n good elements are in aux[0 ... n-1]
3242
    v = vtbl_find_function_with_value_map(table, tau, f, n, (value_t *) aux);
×
3243

3244
  cleanup:
×
3245
    if (n > 32) {
×
3246
      safe_free(aux);
×
3247
    }
3248
  }
3249

3250
  return v;
×
3251
}
3252

3253
/*
3254
 * Check whether object of type tau and index i is present in table.
3255
 * - tau must be finite
3256
 * - i must be smaller than card(tau)
3257
 * - return the object of index i if present, null_value otherwise
3258
 */
3259
value_t vtbl_find_object(value_table_t *table, type_t tau, uint32_t i) {
×
3260
  type_table_t *types;
3261

3262
  types = table->type_table;
×
3263
  assert(is_finite_type(types, tau) && i < type_card(types, tau));
3264

3265
  switch (type_kind(types, tau)) {
×
3266
  case BOOL_TYPE:
×
3267
    assert(i == 0 || i == 1);
3268
    return vtbl_mk_bool(table, i);
×
3269

3270
  case BITVECTOR_TYPE:
×
3271
    return vtbl_find_bv64(table, bv_type_size(types, tau), (uint64_t) i);
×
3272

3273
  case SCALAR_TYPE:
×
3274
    return vtbl_find_const(table, tau, i);
×
3275

3276
  case TUPLE_TYPE:
×
3277
    return vtbl_find_enum_tuple(table, tuple_type_desc(types, tau), i);
×
3278

3279
  case FUNCTION_TYPE:
×
3280
    return vtbl_find_enum_function(table, tau, i);
×
3281

3282
  default:
×
3283
    // tau can't be a finite type
3284
    assert(false);
3285
    return null_value;
×
3286
  }
3287
}
3288

3289

3290

3291

3292
/*****************************
3293
 *  FUNCTION/CONSTANT NAMES  *
3294
 ****************************/
3295

3296
/*
3297
 * Set the name of a function f (make a copy and overwrite the current name)
3298
 */
3299
void vtbl_set_function_name(value_table_t *table, value_t f, char *name) {
941✔
3300
  value_fun_t *fun;
3301

3302
  assert(table->kind[f] == FUNCTION_VALUE);
3303
  fun = table->desc[f].ptr;
941✔
3304
  if (fun->name != NULL) {
941✔
3305
    safe_free(fun->name);
×
3306
    fun->name = NULL;
×
3307
  }
3308
  if (name != NULL) {
941✔
3309
    fun->name = (char *) safe_malloc(strlen(name) + 1);
941✔
3310
    strcpy(fun->name, name);
941✔
3311
  }
3312
}
941✔
3313

3314

3315
/*
3316
 * Set the name of an uninterpreted constant c
3317
 */
3318
void vtbl_set_constant_name(value_table_t *table, value_t c, char *name) {
×
3319
  value_unint_t *d;
3320

3321
  assert(table->kind[c] == UNINTERPRETED_VALUE);
3322
  d = table->desc[c].ptr;
×
3323
  if (d->name != NULL) {
×
3324
    safe_free(d->name);
×
3325
    d->name = NULL;
×
3326
  }
3327
  if (name != NULL) {
×
3328
    d->name = (char *) safe_malloc(strlen(name) + 1);
×
3329
    strcpy(d->name, name);
×
3330
  }
3331
}
×
3332

3333

3334

3335

3336

3337
/***********************
3338
 *  TEMPORARY OBJECTS  *
3339
 **********************/
3340

3341
/*
3342
 * Mark all current objects as permanent.
3343
 * All objects created after this function is called are temporary
3344
 * and can be deleted by calling 'value_table_delete_tmp'.
3345
 */
3346
void value_table_start_tmp(value_table_t *table) {
×
3347
  assert(table->first_tmp == -1);
3348
  // make sure unknown, true, and false are constructed
3349
  (void) vtbl_mk_unknown(table);
×
3350
  (void) vtbl_mk_true(table);
×
3351
  (void) vtbl_mk_false(table);
×
3352

3353
  // set the tmp mark
3354
  table->first_tmp = table->nobjects;
×
3355
}
×
3356

3357

3358

3359
/*
3360
 * Delete all temporary objects.
3361
 * They are stored at indices [first_tmp ... nobjects-1].
3362
 * Do nothing if first_tmp is -1.
3363
 * Reset first_tmp to -1.
3364
 */
3365
void value_table_end_tmp(value_table_t *table) {
×
3366
  if (table->first_tmp >= 0) {
×
3367
    vtbl_delete_descriptors(table, table->first_tmp);
×
3368
    table->first_tmp = -1;
×
3369
  }
3370
}
×
3371

3372

3373

3374
/********************
3375
 *  SPECIAL VALUES  *
3376
 *******************/
3377

3378
/*
3379
 * Check whether v is zero:
3380
 * - v must be a good object
3381
 * - return true if v is a rational equal to zero
3382
 */
3383
bool is_zero(value_table_t *table, value_t v) {
×
3384
  assert(good_object(table, v));
3385
  return object_is_rational(table, v) && q_is_zero(vtbl_rational(table, v));
×
3386
}
3387

3388
/*
3389
 * Check whether v is one
3390
 * - v must be a good object
3391
 * - return true if v is a rational equal to 1
3392
 */
3393
bool is_one(value_table_t *table, value_t v) {
×
3394
  assert(good_object(table, v));
3395
  return object_is_rational(table, v) && q_is_one(vtbl_rational(table, v));
×
3396
}
3397

3398

3399
/*
3400
 * Check whether v is +1 or -1
3401
 * - v must be a good object
3402
 */
3403
bool is_unit(value_table_t *table, value_t v) {
×
3404
  rational_t *r;
3405

3406
  assert(good_object(table, v));
3407
  if (object_is_rational(table, v)) {
×
3408
    r = vtbl_rational(table, v);
×
3409
    return q_is_one(r) || q_is_minus_one(r);
×
3410
  }
3411

3412
  return false;
×
3413
}
3414

3415

3416
/*
3417
 * Check whether v is 0b00000...
3418
 * - v must be a good object
3419
 * - return true if v is a bitvector constant of the form 0b0....0
3420
 */
3421
bool is_bvzero(value_table_t *table, value_t v) {
×
3422
  value_bv_t *b;
3423

3424
  assert(good_object(table, v));
3425
  if (object_is_bitvector(table, v)) {
×
3426
    b = vtbl_bitvector(table, v);
×
3427
    assert(bvconst_is_normalized(b->data, b->nbits));
3428
    return bvconst_is_zero(b->data, b->width);
×
3429
  }
3430

3431
  return false;
×
3432
}
3433

3434

3435

3436

3437

3438

3439
/****************
3440
 *  EVALUATION  *
3441
 ***************/
3442

3443
/*
3444
 * Check whether every element in the domain and range of f
3445
 * is canonical.
3446
 * - f must be a function
3447
 */
3448
static bool semi_canonical(value_table_t *table, value_t f) {
×
3449
  value_fun_t *fun;
3450

3451
  fun = vtbl_function(table, f);
×
3452
  return object_is_canonical(table, fun->def) && canonical_array(table, fun->map, fun->map_size);
×
3453
}
3454

3455

3456
/*
3457
 * Check whether the functions f1 and f2 are equal
3458
 * - the maps and default values for both must be canonical
3459
 */
3460
static value_t vtbl_eval_eq_functions(value_table_t *table, value_t f1, value_t f2) {
×
3461
  value_fun_t *d1, *d2;
3462
  value_map_t *m;
3463
  value_t v;
3464
  uint32_t arity, n, i, k;
3465

3466
  assert(semi_canonical(table, f1) && semi_canonical(table, f2) && f1 != f2);
3467

3468
  d1 = vtbl_function(table, f1);
×
3469
  d2 = vtbl_function(table, f2);
×
3470
  if (d1->def == d2->def) goto not_equal; // f1 and f2 have the same default but different maps
×
3471

3472
  arity = d1->arity;
×
3473
  assert(d2->arity == arity);
3474

3475
  n = d1->map_size;
×
3476
  for (i=0; i<n; i++) {
×
3477
    m = vtbl_map(table, d1->map[i]);
×
3478
    v = hash_eval_app(table, f2, arity, m->arg);
×
3479
    if (v == null_value) v = d2->def;
×
3480
    /*
3481
     * f1 maps m->arg[0 ... arity-1] to m->val
3482
     * f2 maps m->arg[0 ... arity-1] to v
3483
     * both m->value and v are canonical
3484
     */
3485
    assert(object_is_canonical(table, v) &&
3486
           object_is_canonical(table, m->val));
3487
    if (v != m->val) goto not_equal;
×
3488
  }
3489

3490
  /*
3491
   * k = number of elements in the domain
3492
   * where f1 and f2 agree.
3493
   */
3494
  k = n;
×
3495
  n = d2->map_size;
×
3496
  for (i=0; i<n; i++) {
×
3497
    m = vtbl_map(table, d2->map[i]);
×
3498
    v = hash_eval_app(table, f1, arity, m->arg);
×
3499
    if (v == null_value) {
×
3500
      k ++; // element in f2's map that's not in f1's map
×
3501
      v = d1->def;
×
3502
    }
3503
    assert(object_is_canonical(table, v) &&
3504
           object_is_canonical(table, m->val));
3505
    if (v != m->val) goto not_equal;
×
3506
  }
3507

3508
  /*
3509
   * The maps of f1 and f2 are equal, the default values are
3510
   * distinct. If we can find a tuple in the domain of f1 and f2
3511
   * that's not in map of f1 nor in map of f2, then f1 and f2 are
3512
   * distinct.
3513
   */
3514
  if (type_has_finite_domain(table->type_table, d1->type) &&
×
3515
      k == card_of_domain_type(table->type_table, d1->type)) {
×
3516
    // f1 and f2 agree on all elements in their domain
3517
    return vtbl_mk_true(table);
×
3518
  }
3519

3520
 not_equal:
×
3521
  return vtbl_mk_false(table);
×
3522
}
3523

3524

3525
/*
3526
 * Evaluate (eq a b)
3527
 *
3528
 * TODO: improve this. We could do much more when checking equality
3529
 * between two functions.
3530
 */
3531
value_t vtbl_eval_eq(value_table_t *table, value_t a, value_t b) {
66,360✔
3532
  value_t v;
3533

3534
  assert(good_object(table, a) && good_object(table, b));
3535

3536
  if (a == b) {
66,360✔
3537
    v = vtbl_mk_true(table);
32,100✔
3538
  } else if (object_is_canonical(table, a) || object_is_canonical(table, b)) {
34,260✔
3539
    v = vtbl_mk_false(table);
34,258✔
3540
  } else {
3541
    /*
3542
     * a and b are non canonical
3543
     */
3544
    if (object_is_function(table, a) && object_is_function(table, b) &&
2✔
3545
        semi_canonical(table, a) && semi_canonical(table, b)) {
×
3546
      v = vtbl_eval_eq_functions(table, a, b);
×
3547
    } else {
3548
      v = vtbl_mk_unknown(table);
2✔
3549
    }
3550
  }
3551

3552
  return v;
66,360✔
3553
}
3554

3555

3556
/*
3557
 * Check whether arrays a[0 ... n-1] and b[0 ... n-1] are equal
3558
 * - return unknown if we can't tell
3559
 */
3560
value_t vtbl_eval_array_eq(value_table_t *table, value_t *a, value_t *b, uint32_t n) {
15,957✔
3561
  uint32_t i;
3562
  value_t v;
3563

3564
  for (i=0; i<n; i++) {
17,764✔
3565
    assert(good_object(table, a[i]) && good_object(table, b[i]));
3566

3567
    if (a[i] != b[i]) {
15,957✔
3568
      v = vtbl_eval_eq(table, a[i], b[i]);
14,150✔
3569
      if (v == vtbl_mk_false(table) || v == vtbl_mk_unknown(table)) {
14,150✔
3570
        return v;
14,150✔
3571
      }
3572
      assert(v == vtbl_mk_true(table));
3573
    }
3574
  }
3575

3576
  return vtbl_mk_true(table);
1,807✔
3577
}
3578

3579

3580

3581
/*
3582
 * Evaluate (f a[0] ... a[n-1])
3583
 * - f must be a function or update object of arity n
3584
 * - a[0] ... a[n-1] must be non-null values
3585
 * Return unknown if the map is not defined for a[0 ... n-1]
3586
 *
3587
 * TODO(algebraic): algebraic numbers are not canonical!
3588
 */
3589
value_t vtbl_eval_application(value_table_t *table, value_t f, uint32_t n, value_t *a) {
250,290✔
3590
  value_update_t *u;
3591
  value_t j;
3592

3593
  // unroll all updates
3594
  while (object_is_update(table, f)) {
250,290✔
3595
    u = table->desc[f].ptr;
×
3596
    assert(u->arity == n);
3597
    j = u->map;
×
3598
    if (mapping_matches_array(table, j, n, a)) {
×
3599
      return vtbl_map_result(table, j);
×
3600
    }
3601
    f = u->fun;
×
3602
  }
3603

3604
  assert(object_is_function(table, f) && vtbl_function(table, f)->arity == n);
3605

3606
  // search for (f a[0] ... a[n-1]) in the mtbl
3607
  j = hash_eval_app(table, f, n, a);
250,290✔
3608
  if (j == null_value) {
250,290✔
3609
    if (canonical_array(table, a, n)) {
143,395✔
3610
      // use the default value for f
3611
      j = vtbl_function(table, f)->def;
143,395✔
3612
    } else {
3613
      // can't tell for sure so we return unknown
3614
      j = vtbl_mk_unknown(table);
×
3615
    }
3616
  }
3617

3618
  return j;
250,290✔
3619
}
3620

3621

3622
/*
3623
 * Evaluate (/ v 0) by a lookup in table->zero_rdiv_dun
3624
 * - v should be an arithmetic object (but we don't check)
3625
 * - return unknown if either zero_rdiv_fun is null or if the mapping of v is not defined.
3626
 */
3627
value_t vtbl_eval_rdiv_by_zero(value_table_t *table, value_t v) {
4✔
3628
  value_t f, r;
3629

3630
  f = table->zero_rdiv_fun;
4✔
3631
  if (f != null_value) {
4✔
3632
    r = vtbl_eval_application(table, f, 1, &v);
4✔
3633
  } else {
3634
    r = vtbl_mk_unknown(table);
×
3635
  }
3636
  return r;
4✔
3637
}
3638

3639

3640
/*
3641
 * Same thing for integer division: use table->zero_idiv_fun
3642
 */
3643
value_t vtbl_eval_idiv_by_zero(value_table_t *table, value_t v) {
4✔
3644
  value_t f, r;
3645

3646
  f = table->zero_idiv_fun;
4✔
3647
  if (f != null_value) {
4✔
3648
    r = vtbl_eval_application(table, f, 1, &v);
4✔
3649
  } else {
3650
    r = vtbl_mk_unknown(table);
×
3651
  }
3652
  return r;
4✔
3653
}
3654

3655
/*
3656
 * Same thing for modulo: use table->zero_mod_fun
3657
 */
3658
value_t vtbl_eval_mod_by_zero(value_table_t *table, value_t v) {
×
3659
  value_t f, r;
3660

3661
  f = table->zero_mod_fun;
×
3662
  if (f != null_value) {
×
3663
    r = vtbl_eval_application(table, f, 1, &v);
×
3664
  } else {
3665
    r = vtbl_mk_unknown(table);
×
3666
  }
3667
  return r;
×
3668
}
3669

3670

3671

3672

3673

3674
/*
3675
 * ACCESS TO THE QUEUE
3676
 */
3677

3678
/*
3679
 * Push v into the internal queue
3680
 * - v must be a valid object
3681
 * - do nothing if v is already in the queue
3682
 */
3683
void vtbl_push_object(value_table_t *table, value_t v) {
3✔
3684
  assert(good_object(table, v));
3685
  vtbl_queue_push(&table->queue, v);
3✔
3686
}
3✔
3687

3688
/*
3689
 * Empty the internal queue
3690
 */
3691
void vtbl_empty_queue(value_table_t *table) {
49,537✔
3692
  reset_vtbl_queue(&table->queue);
49,537✔
3693
}
49,537✔
3694

3695
/*
3696
 * Check emptiness
3697
 */
3698
bool vtbl_queue_is_empty(value_table_t *table) {
×
3699
  return int_queue_is_empty(&table->queue.queue);
×
3700
}
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