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

SRI-CSL / yices2 / 22588689854

02 Mar 2026 05:54PM UTC coverage: 66.415% (+0.001%) from 66.414%
22588689854

Pull #606

github

disteph
tests: stabilize mcsat tuple regression across configs
Pull Request #606: MCSAT: add tuple/function preprocessing + interpolant regression coverage

218 of 549 new or added lines in 2 files covered. (39.71%)

33 existing lines in 4 files now uncovered.

83246 of 125343 relevant lines covered (66.41%)

1689418.64 hits per line

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

67.09
/src/mcsat/preprocessor.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
#if defined(CYGWIN) || defined(MINGW)
20
#ifndef __YICES_DLLSPEC__
21
#define __YICES_DLLSPEC__ __declspec(dllexport)
22
#endif
23
#endif
24

25
#include "mcsat/preprocessor.h"
26
#include "mcsat/tracing.h"
27

28
#include "terms/term_explorer.h"
29
#include "terms/term_substitution.h"
30
#include "terms/bvarith64_buffer_terms.h"
31
#include "terms/bvarith_buffer_terms.h"
32

33
#include "model/models.h"
34
#include "model/model_queries.h"
35
#include "model/concrete_values.h"
36

37
#include "context/context_types.h"
38

39
#include "yices.h"
40
#include "api/yices_api_lock_free.h"
41

42
void preprocessor_construct(preprocessor_t* pre, term_table_t* terms, jmp_buf* handler, const mcsat_options_t* options) {
667✔
43
  pre->terms = terms;
667✔
44
  init_term_manager(&pre->tm, terms);
667✔
45
  init_int_hmap(&pre->preprocess_map, 0);
667✔
46
  init_ivector(&pre->preprocess_map_list, 0);
667✔
47
  init_int_hmap(&pre->tuple_blast_map, 0);
667✔
48
  init_ivector(&pre->tuple_blast_data, 0);
667✔
49
  init_ivector(&pre->tuple_blast_list, 0);
667✔
50
  init_ivector(&pre->tuple_blast_atoms, 0);
667✔
51
  init_int_hmap(&pre->purification_map, 0);
667✔
52
  init_ivector(&pre->purification_map_list, 0);
667✔
53
  init_ivector(&pre->preprocessing_stack, 0);
667✔
54
  init_int_hmap(&pre->equalities, 0);
667✔
55
  init_ivector(&pre->equalities_list, 0);
667✔
56
  pre->tracer = NULL;
667✔
57
  pre->exception = handler;
667✔
58
  pre->options = options;
667✔
59
  scope_holder_construct(&pre->scope);
667✔
60
}
667✔
61

62
void preprocessor_set_tracer(preprocessor_t* pre, tracer_t* tracer) {
283✔
63
  pre->tracer = tracer;
283✔
64
}
283✔
65

66
void preprocessor_destruct(preprocessor_t* pre) {
667✔
67
  delete_int_hmap(&pre->purification_map);
667✔
68
  delete_ivector(&pre->purification_map_list);
667✔
69
  delete_int_hmap(&pre->tuple_blast_map);
667✔
70
  delete_ivector(&pre->tuple_blast_data);
667✔
71
  delete_ivector(&pre->tuple_blast_list);
667✔
72
  delete_ivector(&pre->tuple_blast_atoms);
667✔
73
  delete_int_hmap(&pre->preprocess_map);
667✔
74
  delete_ivector(&pre->preprocess_map_list);
667✔
75
  delete_ivector(&pre->preprocessing_stack);
667✔
76
  delete_int_hmap(&pre->equalities);
667✔
77
  delete_ivector(&pre->equalities_list);
667✔
78
  delete_term_manager(&pre->tm);
667✔
79
  scope_holder_destruct(&pre->scope);
667✔
80
}
667✔
81

82
static
83
term_t preprocessor_get(preprocessor_t* pre, term_t t) {
1,611,897✔
84
  int_hmap_pair_t* find = int_hmap_find(&pre->preprocess_map, t);
1,611,897✔
85
  if (find == NULL) {
1,611,897✔
86
    return NULL_TERM;
875,149✔
87
  } else {
88
    return find->val;
736,748✔
89
  }
90
}
91

92
static
93
void preprocessor_set(preprocessor_t* pre, term_t t, term_t t_pre) {
338,788✔
94
  assert(preprocessor_get(pre, t) == NULL_TERM);
95
  int_hmap_add(&pre->preprocess_map, t, t_pre);
338,788✔
96
  ivector_push(&pre->preprocess_map_list, t);
338,788✔
97
}
338,788✔
98

99
static
100
bool type_is_tuple_free(type_table_t* types, type_t tau) {
10,103✔
101
  type_kind_t kind = type_kind(types, tau);
10,103✔
102
  uint32_t i;
103
  switch (kind) {
10,103✔
104
  case BOOL_TYPE:
9,029✔
105
  case INT_TYPE:
106
  case REAL_TYPE:
107
  case BITVECTOR_TYPE:
108
  case SCALAR_TYPE:
109
  case UNINTERPRETED_TYPE:
110
  case FF_TYPE:
111
    return true;
9,029✔
NEW
112
  case TUPLE_TYPE:
×
NEW
113
    return false;
×
114
  case FUNCTION_TYPE: {
1,074✔
115
    function_type_t* fun = function_type_desc(types, tau);
1,074✔
116
    if (!type_is_tuple_free(types, fun->range)) {
1,074✔
NEW
117
      return false;
×
118
    }
119
    for (i = 0; i < fun->ndom; ++i) {
2,209✔
120
      if (!type_is_tuple_free(types, fun->domain[i])) {
1,135✔
NEW
121
        return false;
×
122
      }
123
    }
124
    return true;
1,074✔
125
  }
NEW
126
  default:
×
NEW
127
    return false;
×
128
  }
129
}
130

131
static
NEW
132
uint32_t type_leaf_count(type_table_t* types, type_t tau) {
×
133
  tuple_type_t* tuple;
134
  uint32_t i, count;
NEW
135
  switch (type_kind(types, tau)) {
×
NEW
136
  case TUPLE_TYPE:
×
NEW
137
    tuple = tuple_type_desc(types, tau);
×
NEW
138
    count = 0;
×
NEW
139
    for (i = 0; i < tuple->nelem; ++i) {
×
NEW
140
      count += type_leaf_count(types, tuple->elem[i]);
×
141
    }
NEW
142
    return count;
×
NEW
143
  case FUNCTION_TYPE:
×
NEW
144
    return type_leaf_count(types, function_type_desc(types, tau)->range);
×
NEW
145
  default:
×
NEW
146
    return 1;
×
147
  }
148
}
149

150
static
NEW
151
void type_collect_flat(type_table_t* types, type_t tau, ivector_t* flat) {
×
152
  tuple_type_t* tuple;
153
  uint32_t i;
NEW
154
  if (type_kind(types, tau) == TUPLE_TYPE) {
×
NEW
155
    tuple = tuple_type_desc(types, tau);
×
NEW
156
    for (i = 0; i < tuple->nelem; ++i) {
×
NEW
157
      type_collect_flat(types, tuple->elem[i], flat);
×
158
    }
159
  } else {
NEW
160
    ivector_push(flat, tau);
×
161
  }
NEW
162
}
×
163

164
static
NEW
165
void function_type_collect_blasted(type_table_t* types, type_t tau, ivector_t* out) {
×
166
  function_type_t* fun;
167
  ivector_t dom_flat;
168
  ivector_t codom_leaf;
169
  uint32_t i;
170

171
  assert(type_kind(types, tau) == FUNCTION_TYPE);
NEW
172
  fun = function_type_desc(types, tau);
×
173

NEW
174
  init_ivector(&dom_flat, 0);
×
NEW
175
  for (i = 0; i < fun->ndom; ++i) {
×
NEW
176
    type_collect_flat(types, fun->domain[i], &dom_flat);
×
177
  }
178

NEW
179
  init_ivector(&codom_leaf, 0);
×
NEW
180
  type_collect_flat(types, fun->range, &codom_leaf);
×
NEW
181
  for (i = 0; i < codom_leaf.size; ++i) {
×
NEW
182
    type_t ft = function_type(types, codom_leaf.data[i], dom_flat.size, (type_t*) dom_flat.data);
×
NEW
183
    ivector_push(out, ft);
×
184
  }
185

NEW
186
  delete_ivector(&codom_leaf);
×
NEW
187
  delete_ivector(&dom_flat);
×
NEW
188
}
×
189

190
static
NEW
191
void type_collect_blasted_atom_types(type_table_t* types, type_t tau, ivector_t* out) {
×
NEW
192
  switch (type_kind(types, tau)) {
×
NEW
193
  case TUPLE_TYPE:
×
NEW
194
    type_collect_flat(types, tau, out);
×
NEW
195
    break;
×
NEW
196
  case FUNCTION_TYPE:
×
NEW
197
    function_type_collect_blasted(types, tau, out);
×
NEW
198
    break;
×
NEW
199
  default:
×
NEW
200
    ivector_push(out, tau);
×
NEW
201
    break;
×
202
  }
NEW
203
}
×
204

205
static
206
int_hmap_pair_t* tuple_blast_find(preprocessor_t* pre, term_t t) {
396,736✔
207
  return int_hmap_find(&pre->tuple_blast_map, t);
396,736✔
208
}
209

210
static
211
bool tuple_blast_done(preprocessor_t* pre, term_t t) {
198,368✔
212
  return tuple_blast_find(pre, t) != NULL;
198,368✔
213
}
214

215
static
216
void tuple_blast_set(preprocessor_t* pre, term_t t, const ivector_t* terms) {
127,170✔
217
  int_hmap_pair_t* rec = int_hmap_get(&pre->tuple_blast_map, t);
127,170✔
218
  assert(rec->val < 0);
219
  rec->val = pre->tuple_blast_data.size;
127,170✔
220
  ivector_push(&pre->tuple_blast_data, terms->size);
127,170✔
221
  ivector_add(&pre->tuple_blast_data, terms->data, terms->size);
127,170✔
222
  ivector_push(&pre->tuple_blast_list, t);
127,170✔
223
}
127,170✔
224

225
static
226
void tuple_blast_get(preprocessor_t* pre, term_t t, ivector_t* out) {
198,368✔
227
  int_hmap_pair_t* rec = tuple_blast_find(pre, t);
198,368✔
228
  assert(rec != NULL);
229
  uint32_t offset = rec->val;
198,368✔
230
  uint32_t n = pre->tuple_blast_data.data[offset];
198,368✔
231
  ivector_reset(out);
198,368✔
232
  ivector_add(out, pre->tuple_blast_data.data + offset + 1, n);
198,368✔
233
}
198,368✔
234

235
static
236
void tuple_blast_term(preprocessor_t* pre, term_t t);
237

238
static
239
void tuple_blast_collect_arg(preprocessor_t* pre, term_t t, ivector_t* out) {
4,071✔
240
  ivector_t arg;
241
  tuple_blast_term(pre, t);
4,071✔
242
  init_ivector(&arg, 0);
4,071✔
243
  tuple_blast_get(pre, t, &arg);
4,071✔
244
  ivector_add(out, arg.data, arg.size);
4,071✔
245
  delete_ivector(&arg);
4,071✔
246
}
4,071✔
247

248
static
249
term_t tuple_blast_eq_vector(term_manager_t* tm, const ivector_t* a, const ivector_t* b) {
8,611✔
250
  assert(a->size == b->size && a->size > 0);
251
  if (a->size == 1) {
8,611✔
252
    return mk_eq(tm, a->data[0], b->data[0]);
8,611✔
253
  } else {
254
    ivector_t eqs;
255
    uint32_t i;
NEW
256
    init_ivector(&eqs, a->size);
×
NEW
257
    for (i = 0; i < a->size; ++i) {
×
NEW
258
      ivector_push(&eqs, mk_eq(tm, a->data[i], b->data[i]));
×
259
    }
NEW
260
    term_t result = mk_and(tm, eqs.size, eqs.data);
×
NEW
261
    delete_ivector(&eqs);
×
NEW
262
    return result;
×
263
  }
264
}
265

266
static
267
void tuple_blast_term(preprocessor_t* pre, term_t t) {
198,368✔
268
  term_table_t* terms = pre->terms;
198,368✔
269
  type_table_t* types = terms->types;
198,368✔
270
  term_manager_t* tm = &pre->tm;
198,368✔
271

272
  if (tuple_blast_done(pre, t)) {
198,368✔
273
    return;
105,310✔
274
  }
275

276
  ivector_t result;
277
  init_ivector(&result, 0);
127,170✔
278

279
  if (is_neg_term(t)) {
127,170✔
280
    term_t c = unsigned_term(t);
34,112✔
281
    ivector_t c_blast;
282
    tuple_blast_term(pre, c);
34,112✔
283
    init_ivector(&c_blast, 0);
34,112✔
284
    tuple_blast_get(pre, c, &c_blast);
34,112✔
285
    if (c_blast.size != 1) {
34,112✔
NEW
286
      delete_ivector(&c_blast);
×
NEW
287
      delete_ivector(&result);
×
NEW
288
      longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
×
289
    }
290
    ivector_push(&result, opposite_term(c_blast.data[0]));
34,112✔
291
    delete_ivector(&c_blast);
34,112✔
292
    tuple_blast_set(pre, t, &result);
34,112✔
293
    delete_ivector(&result);
34,112✔
294
    return;
34,112✔
295
  }
296

297
  term_kind_t kind = term_kind(terms, t);
93,058✔
298
  type_t tau = term_type(terms, t);
93,058✔
299

300
  switch (kind) {
93,058✔
301
  case CONSTANT_TERM:
2,389✔
302
  case ARITH_CONSTANT:
303
  case ARITH_FF_CONSTANT:
304
  case BV64_CONSTANT:
305
  case BV_CONSTANT:
306
  case BIT_TERM:
307
    ivector_push(&result, t);
2,389✔
308
    break;
2,389✔
309

310
  case UNINTERPRETED_TERM: {
7,894✔
311
    if (type_is_tuple_free(types, tau)) {
7,894✔
312
      ivector_push(&result, t);
7,894✔
313
    } else {
314
      ivector_t atom_types;
315
      uint32_t i;
NEW
316
      init_ivector(&atom_types, 0);
×
NEW
317
      type_collect_blasted_atom_types(types, tau, &atom_types);
×
NEW
318
      for (i = 0; i < atom_types.size; ++i) {
×
NEW
319
        term_t v = new_uninterpreted_term(terms, atom_types.data[i]);
×
NEW
320
        ivector_push(&result, v);
×
321
      }
NEW
322
      ivector_push(&pre->tuple_blast_atoms, t);
×
NEW
323
      delete_ivector(&atom_types);
×
324
    }
325
    break;
7,894✔
326
  }
327

NEW
328
  case VARIABLE:
×
NEW
329
    if (!type_is_tuple_free(types, tau)) {
×
NEW
330
      delete_ivector(&result);
×
NEW
331
      longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
×
332
    }
NEW
333
    ivector_push(&result, t);
×
NEW
334
    break;
×
335

NEW
336
  case TUPLE_TERM: {
×
NEW
337
    composite_term_t* tuple = tuple_term_desc(terms, t);
×
338
    uint32_t i;
NEW
339
    for (i = 0; i < tuple->arity; ++i) {
×
NEW
340
      tuple_blast_collect_arg(pre, tuple->arg[i], &result);
×
341
    }
NEW
342
    break;
×
343
  }
344

NEW
345
  case SELECT_TERM: {
×
NEW
346
    select_term_t* sel = select_term_desc(terms, t);
×
347
    ivector_t arg_blast;
348
    tuple_type_t* tuple_type;
349
    uint32_t i, start, len;
NEW
350
    type_t arg_type = term_type(terms, sel->arg);
×
NEW
351
    if (type_kind(types, arg_type) != TUPLE_TYPE) {
×
NEW
352
      delete_ivector(&result);
×
NEW
353
      longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
×
354
    }
NEW
355
    tuple_blast_term(pre, sel->arg);
×
NEW
356
    init_ivector(&arg_blast, 0);
×
NEW
357
    tuple_blast_get(pre, sel->arg, &arg_blast);
×
NEW
358
    tuple_type = tuple_type_desc(types, arg_type);
×
NEW
359
    start = 0;
×
NEW
360
    for (i = 0; i < sel->idx; ++i) {
×
NEW
361
      start += type_leaf_count(types, tuple_type->elem[i]);
×
362
    }
NEW
363
    len = type_leaf_count(types, tuple_type->elem[sel->idx]);
×
NEW
364
    ivector_add(&result, arg_blast.data + start, len);
×
NEW
365
    delete_ivector(&arg_blast);
×
NEW
366
    break;
×
367
  }
368

369
  case EQ_TERM: {
8,611✔
370
    composite_term_t* eq = eq_term_desc(terms, t);
8,611✔
371
    ivector_t lhs, rhs;
372
    term_t eq_term;
373
    tuple_blast_term(pre, eq->arg[0]);
8,611✔
374
    tuple_blast_term(pre, eq->arg[1]);
8,611✔
375
    init_ivector(&lhs, 0);
8,611✔
376
    init_ivector(&rhs, 0);
8,611✔
377
    tuple_blast_get(pre, eq->arg[0], &lhs);
8,611✔
378
    tuple_blast_get(pre, eq->arg[1], &rhs);
8,611✔
379
    if (lhs.size != rhs.size || lhs.size == 0) {
8,611✔
NEW
380
      delete_ivector(&lhs);
×
NEW
381
      delete_ivector(&rhs);
×
NEW
382
      delete_ivector(&result);
×
NEW
383
      longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
×
384
    }
385
    eq_term = tuple_blast_eq_vector(tm, &lhs, &rhs);
8,611✔
386
    ivector_push(&result, eq_term);
8,611✔
387
    delete_ivector(&lhs);
8,611✔
388
    delete_ivector(&rhs);
8,611✔
389
    break;
8,611✔
390
  }
391

392
  case DISTINCT_TERM: {
14✔
393
    composite_term_t* d = distinct_term_desc(terms, t);
14✔
394
    ivector_t conjuncts;
395
    uint32_t i, j;
396
    init_ivector(&conjuncts, 0);
14✔
397
    for (i = 0; i < d->arity; ++i) {
70✔
398
      for (j = i + 1; j < d->arity; ++j) {
148✔
399
        ivector_t ti, tj;
400
        ivector_t disj;
401
        uint32_t k;
402
        tuple_blast_term(pre, d->arg[i]);
92✔
403
        tuple_blast_term(pre, d->arg[j]);
92✔
404
        init_ivector(&ti, 0);
92✔
405
        init_ivector(&tj, 0);
92✔
406
        tuple_blast_get(pre, d->arg[i], &ti);
92✔
407
        tuple_blast_get(pre, d->arg[j], &tj);
92✔
408
        if (ti.size != tj.size || ti.size == 0) {
92✔
NEW
409
          delete_ivector(&ti);
×
NEW
410
          delete_ivector(&tj);
×
NEW
411
          delete_ivector(&conjuncts);
×
NEW
412
          delete_ivector(&result);
×
NEW
413
          longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
×
414
        }
415
        init_ivector(&disj, ti.size);
92✔
416
        for (k = 0; k < ti.size; ++k) {
184✔
417
          ivector_push(&disj, opposite_term(mk_eq(tm, ti.data[k], tj.data[k])));
92✔
418
        }
419
        ivector_push(&conjuncts, mk_or(tm, disj.size, disj.data));
92✔
420
        delete_ivector(&disj);
92✔
421
        delete_ivector(&ti);
92✔
422
        delete_ivector(&tj);
92✔
423
      }
424
    }
425
    ivector_push(&result, mk_and(tm, conjuncts.size, conjuncts.data));
14✔
426
    delete_ivector(&conjuncts);
14✔
427
    break;
14✔
428
  }
429

430
  case ITE_TERM:
857✔
431
  case ITE_SPECIAL: {
432
    composite_term_t* ite = ite_term_desc(terms, t);
857✔
433
    ivector_t c_blast, t_blast, e_blast;
434
    uint32_t i;
435
    tuple_blast_term(pre, ite->arg[0]);
857✔
436
    tuple_blast_term(pre, ite->arg[1]);
857✔
437
    tuple_blast_term(pre, ite->arg[2]);
857✔
438
    init_ivector(&c_blast, 0);
857✔
439
    init_ivector(&t_blast, 0);
857✔
440
    init_ivector(&e_blast, 0);
857✔
441
    tuple_blast_get(pre, ite->arg[0], &c_blast);
857✔
442
    tuple_blast_get(pre, ite->arg[1], &t_blast);
857✔
443
    tuple_blast_get(pre, ite->arg[2], &e_blast);
857✔
444
    if (c_blast.size != 1 || t_blast.size != e_blast.size || t_blast.size == 0) {
857✔
NEW
445
      delete_ivector(&c_blast);
×
NEW
446
      delete_ivector(&t_blast);
×
NEW
447
      delete_ivector(&e_blast);
×
NEW
448
      delete_ivector(&result);
×
NEW
449
      longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
×
450
    }
451
    for (i = 0; i < t_blast.size; ++i) {
1,714✔
452
      type_t ty = super_type(types, term_type(terms, t_blast.data[i]), term_type(terms, e_blast.data[i]));
857✔
453
      if (ty == NULL_TYPE) {
857✔
NEW
454
        delete_ivector(&c_blast);
×
NEW
455
        delete_ivector(&t_blast);
×
NEW
456
        delete_ivector(&e_blast);
×
NEW
457
        delete_ivector(&result);
×
NEW
458
        longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
×
459
      }
460
      ivector_push(&result, mk_ite(tm, c_blast.data[0], t_blast.data[i], e_blast.data[i], ty));
857✔
461
    }
462
    delete_ivector(&c_blast);
857✔
463
    delete_ivector(&t_blast);
857✔
464
    delete_ivector(&e_blast);
857✔
465
    break;
857✔
466
  }
467

468
  case APP_TERM: {
2,002✔
469
    composite_term_t* app = app_term_desc(terms, t);
2,002✔
470
    ivector_t f_blast;
471
    ivector_t args_flat;
472
    uint32_t i;
473
    tuple_blast_term(pre, app->arg[0]);
2,002✔
474
    init_ivector(&f_blast, 0);
2,002✔
475
    tuple_blast_get(pre, app->arg[0], &f_blast);
2,002✔
476
    init_ivector(&args_flat, 0);
2,002✔
477
    for (i = 1; i < app->arity; ++i) {
4,834✔
478
      tuple_blast_collect_arg(pre, app->arg[i], &args_flat);
2,832✔
479
    }
480
    for (i = 0; i < f_blast.size; ++i) {
4,004✔
481
      ivector_push(&result, mk_application(tm, f_blast.data[i], args_flat.size, args_flat.data));
2,002✔
482
    }
483
    delete_ivector(&args_flat);
2,002✔
484
    delete_ivector(&f_blast);
2,002✔
485
    break;
2,002✔
486
  }
487

488
  case UPDATE_TERM: {
1,231✔
489
    composite_term_t* upd = update_term_desc(terms, t);
1,231✔
490
    ivector_t f_blast;
491
    ivector_t idx_flat;
492
    ivector_t v_blast;
493
    uint32_t i;
494
    tuple_blast_term(pre, upd->arg[0]);
1,231✔
495
    init_ivector(&f_blast, 0);
1,231✔
496
    tuple_blast_get(pre, upd->arg[0], &f_blast);
1,231✔
497
    init_ivector(&idx_flat, 0);
1,231✔
498
    for (i = 1; i + 1 < upd->arity; ++i) {
2,470✔
499
      tuple_blast_collect_arg(pre, upd->arg[i], &idx_flat);
1,239✔
500
    }
501
    tuple_blast_term(pre, upd->arg[upd->arity - 1]);
1,231✔
502
    init_ivector(&v_blast, 0);
1,231✔
503
    tuple_blast_get(pre, upd->arg[upd->arity - 1], &v_blast);
1,231✔
504
    if (v_blast.size != 1 && v_blast.size != f_blast.size) {
1,231✔
NEW
505
      delete_ivector(&f_blast);
×
NEW
506
      delete_ivector(&idx_flat);
×
NEW
507
      delete_ivector(&v_blast);
×
NEW
508
      delete_ivector(&result);
×
NEW
509
      longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
×
510
    }
511
    for (i = 0; i < f_blast.size; ++i) {
2,462✔
512
      term_t vi = v_blast.size == 1 ? v_blast.data[0] : v_blast.data[i];
1,231✔
513
      ivector_push(&result, mk_update(tm, f_blast.data[i], idx_flat.size, idx_flat.data, vi));
1,231✔
514
    }
515
    delete_ivector(&f_blast);
1,231✔
516
    delete_ivector(&idx_flat);
1,231✔
517
    delete_ivector(&v_blast);
1,231✔
518
    break;
1,231✔
519
  }
520

521
  case OR_TERM:
32,105✔
522
  case XOR_TERM: {
523
    composite_term_t* c = (kind == OR_TERM) ? or_term_desc(terms, t) : xor_term_desc(terms, t);
32,105✔
524
    ivector_t args;
525
    uint32_t i;
526
    init_ivector(&args, c->arity);
32,105✔
527
    for (i = 0; i < c->arity; ++i) {
128,166✔
528
      ivector_t child;
529
      tuple_blast_term(pre, c->arg[i]);
96,061✔
530
      init_ivector(&child, 0);
96,061✔
531
      tuple_blast_get(pre, c->arg[i], &child);
96,061✔
532
      if (child.size != 1) {
96,061✔
NEW
533
        delete_ivector(&child);
×
NEW
534
        delete_ivector(&args);
×
NEW
535
        delete_ivector(&result);
×
NEW
536
        longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
×
537
      }
538
      ivector_push(&args, child.data[0]);
96,061✔
539
      delete_ivector(&child);
96,061✔
540
    }
541
    ivector_push(&result, kind == OR_TERM ? mk_or(tm, args.size, args.data) : mk_xor(tm, args.size, args.data));
32,105✔
542
    delete_ivector(&args);
32,105✔
543
    break;
32,105✔
544
  }
545

546
  default:
37,955✔
547
    ivector_push(&result, t);
37,955✔
548
    break;
37,955✔
549
  }
550

551
  tuple_blast_set(pre, t, &result);
93,058✔
552
  delete_ivector(&result);
93,058✔
553
}
554

555
typedef struct composite_term1_s {
556
  uint32_t arity;  // number of subterms
557
  term_t arg[1];  // real size = arity
558
} composite_term1_t;
559

560
static
561
composite_term1_t composite_for_noncomposite;
562

563
static
564
composite_term_t* get_composite(term_table_t* terms, term_kind_t kind, term_t t) {
209,349✔
565
  assert(term_is_composite(terms, t));
566
  assert(term_kind(terms, t) == kind);
567
  assert(is_pos_term(t));
568

569
  switch (kind) {
209,349✔
570
  case ITE_TERM:           // if-then-else
20,548✔
571
  case ITE_SPECIAL:        // special if-then-else term (NEW: EXPERIMENTAL)
572
    return ite_term_desc(terms, t);
20,548✔
573
  case EQ_TERM:            // equality
20,282✔
574
    return eq_term_desc(terms, t);
20,282✔
575
  case OR_TERM:            // n-ary OR
64,065✔
576
    return or_term_desc(terms, t);
64,065✔
577
  case XOR_TERM:           // n-ary XOR
30✔
578
    return xor_term_desc(terms, t);
30✔
579
  case ARITH_BINEQ_ATOM:   // equality: (t1 == t2)  (between two arithmetic terms)
3,998✔
580
    return arith_bineq_atom_desc(terms, t);
3,998✔
581
  case ARITH_EQ_ATOM: {
3,672✔
582
    composite_for_noncomposite.arity = 1;
3,672✔
583
    composite_for_noncomposite.arg[0] = arith_eq_arg(terms, t);
3,672✔
584
    return (composite_term_t*)&composite_for_noncomposite;
3,672✔
585
  }
586
  case ARITH_GE_ATOM: {
8,142✔
587
    composite_for_noncomposite.arity = 1;
8,142✔
588
    composite_for_noncomposite.arg[0] = arith_ge_arg(terms, t);
8,142✔
589
    return (composite_term_t*)&composite_for_noncomposite;
8,142✔
590
  }
591
  case ARITH_FF_BINEQ_ATOM:
12✔
592
    return arith_ff_bineq_atom_desc(terms, t);
12✔
593
  case ARITH_FF_EQ_ATOM: {
155✔
594
    composite_for_noncomposite.arity = 1;
155✔
595
    composite_for_noncomposite.arg[0] = arith_ff_eq_arg(terms, t);
155✔
596
    return (composite_term_t*)&composite_for_noncomposite;
155✔
597
  }
598
  case APP_TERM:           // application of an uninterpreted function
5,445✔
599
    return app_term_desc(terms, t);
5,445✔
600
  case ARITH_RDIV:          // division: (/ x y)
58✔
601
    return arith_rdiv_term_desc(terms, t);
58✔
602
  case ARITH_IDIV:          // division: (div x y) as defined in SMT-LIB 2
104✔
603
    return arith_idiv_term_desc(terms, t);
104✔
604
  case ARITH_MOD:          // remainder: (mod x y) is y - x * (div x y)
160✔
605
    return arith_mod_term_desc(terms, t);
160✔
606
  case UPDATE_TERM:
2,205✔
607
    return update_term_desc(terms, t);
2,205✔
UNCOV
608
  case DISTINCT_TERM:
×
UNCOV
609
    return distinct_term_desc(terms, t);
×
610
  case BV_ARRAY:
17,561✔
611
    return bvarray_term_desc(terms, t);
17,561✔
612
  case BV_DIV:
95✔
613
    return bvdiv_term_desc(terms, t);
95✔
614
  case BV_REM:
212✔
615
    return bvrem_term_desc(terms, t);
212✔
616
  case BV_SDIV:
20✔
617
    return bvsdiv_term_desc(terms, t);
20✔
618
  case BV_SREM:
21✔
619
    return bvsrem_term_desc(terms, t);
21✔
620
  case BV_SMOD:
6✔
621
    return bvsmod_term_desc(terms, t);
6✔
622
  case BV_SHL:
143✔
623
    return bvshl_term_desc(terms, t);
143✔
624
  case BV_LSHR:
279✔
625
    return bvlshr_term_desc(terms, t);
279✔
626
  case BV_ASHR:
21✔
627
    return bvashr_term_desc(terms, t);
21✔
628
  case BV_EQ_ATOM:
58,498✔
629
    return bveq_atom_desc(terms, t);
58,498✔
630
  case BV_GE_ATOM:
2,784✔
631
    return bvge_atom_desc(terms, t);
2,784✔
632
  case BV_SGE_ATOM:
833✔
633
    return bvsge_atom_desc(terms, t);
833✔
634
  default:
×
635
    assert(false);
636
    return NULL;
×
637
  }
638
}
639

640
static
641
term_t mk_composite(preprocessor_t* pre, term_kind_t kind, uint32_t n, term_t* children) {
46,790✔
642
  term_manager_t* tm = &pre->tm;
46,790✔
643
  term_table_t* terms = pre->terms;
46,790✔
644

645
  switch (kind) {
46,790✔
646
  case ITE_TERM:           // if-then-else
12,777✔
647
  case ITE_SPECIAL:        // special if-then-else term (NEW: EXPERIMENTAL)
648
  {
649
    assert(n == 3);
650
    term_t type = super_type(pre->terms->types, term_type(terms, children[1]), term_type(terms, children[2]));
12,777✔
651
    assert(type != NULL_TYPE);
652
    return mk_ite(tm, children[0], children[1], children[2], type);
12,777✔
653
  }
654
  case EQ_TERM:            // equality
3,537✔
655
    assert(n == 2);
656
    return mk_eq(tm, children[0], children[1]);
3,537✔
657
  case OR_TERM:            // n-ary OR
12,576✔
658
    assert(n > 1);
659
    return mk_or(tm, n, children);
12,576✔
660
  case XOR_TERM:           // n-ary XOR
3✔
661
    return mk_xor(tm, n, children);
3✔
662
  case ARITH_EQ_ATOM:
49✔
663
    assert(n == 1);
664
    return mk_arith_eq(tm, children[0], zero_term);
49✔
665
  case ARITH_GE_ATOM:
374✔
666
    assert(n == 1);
667
    return mk_arith_geq(tm, children[0], zero_term);
374✔
668
  case ARITH_BINEQ_ATOM:   // equality: (t1 == t2)  (between two arithmetic terms)
206✔
669
    assert(n == 2);
670
    return mk_arith_eq(tm, children[0], children[1]);
206✔
671
  case APP_TERM:           // application of an uninterpreted function
776✔
672
    assert(n > 1);
673
    return mk_application(tm, children[0], n-1, children + 1);
776✔
674
  case ARITH_RDIV:
21✔
675
    assert(n == 2);
676
    return mk_arith_rdiv(tm, children[0], children[1]);
21✔
677
  case ARITH_IDIV:          // division: (div x y) as defined in SMT-LIB 2
18✔
678
    assert(n == 2);
679
    return mk_arith_idiv(tm, children[0], children[1]);
18✔
680
  case ARITH_MOD:          // remainder: (mod x y) is y - x * (div x y)
21✔
681
    assert(n == 2);
682
    return mk_arith_mod(tm, children[0], children[1]);
21✔
683
  case UPDATE_TERM:
501✔
684
    assert(n > 2);
685
    return mk_update(tm, children[0], n-2, children + 1, children[n-1]);
501✔
686
  case BV_ARRAY:
6,975✔
687
    assert(n >= 1);
688
    return mk_bvarray(tm, n, children);
6,975✔
689
  case BV_DIV:
63✔
690
    assert(n == 2);
691
    return mk_bvdiv(tm, children[0], children[1]);
63✔
692
  case BV_REM:
18✔
693
    assert(n == 2);
694
    return mk_bvrem(tm, children[0], children[1]);
18✔
695
  case BV_SDIV:
×
696
    assert(n == 2);
697
    return mk_bvsdiv(tm, children[0], children[1]);
×
698
  case BV_SREM:
×
699
    assert(n == 2);
700
    return mk_bvsrem(tm, children[0], children[1]);
×
701
  case BV_SMOD:
2✔
702
    assert(n == 2);
703
    return mk_bvsmod(tm, children[0], children[1]);
2✔
704
  case BV_SHL:
108✔
705
    assert(n == 2);
706
    return mk_bvshl(tm, children[0], children[1]);
108✔
707
  case BV_LSHR:
135✔
708
    assert(n == 2);
709
    return mk_bvlshr(tm, children[0], children[1]);
135✔
710
  case BV_ASHR:
3✔
711
    assert(n == 2);
712
    return mk_bvashr(tm, children[0], children[1]);
3✔
713
  case BV_EQ_ATOM:
6,549✔
714
    assert(n == 2);
715
    return mk_bveq(tm, children[0], children[1]);
6,549✔
716
  case BV_GE_ATOM:
1,797✔
717
    assert(n == 2);
718
    return mk_bvge(tm, children[0], children[1]);
1,797✔
719
  case BV_SGE_ATOM:
281✔
720
    assert(n == 2);
721
    return mk_bvsge(tm, children[0], children[1]);
281✔
722
  default:
×
723
    assert(false);
724
    return NULL_TERM;
×
725
  }
726
}
727

728
/**
729
 * Returns purified version of t if we should purify t as an argument of a function.
730
 * Any new equalities are added to output.
731
 */
732
static inline
733
term_t preprocessor_purify(preprocessor_t* pre, term_t t, ivector_t* out) {
52,299✔
734

735
  term_table_t* terms = pre->terms;
52,299✔
736

737
  // Negated terms must be purified
738
  if (is_pos_term(t)) {
52,299✔
739
    // We don't purify variables
740
    switch (term_kind(terms, t)) {
15,440✔
741
    case UNINTERPRETED_TERM:
9,922✔
742
      // Variables are already pure
743
      return t;
9,922✔
744
    case CONSTANT_TERM:
13✔
745
      return t;
13✔
746
    case ARITH_CONSTANT:
1,621✔
747
    case ARITH_FF_CONSTANT:
748
    case BV64_CONSTANT:
749
    case BV_CONSTANT:
750
      // Constants are also pure (except for false)
751
      return t;
1,621✔
752
    case APP_TERM:
1,595✔
753
      // Uninterpreted functions are also already purified
754
      return t;
1,595✔
755
    case UPDATE_TERM:
1,259✔
756
      return t;
1,259✔
757
    default:
1,030✔
758
      break;
1,030✔
759
    }
760
  }
761

762
  // Everything else gets purified. Check if in the cache
763
  int_hmap_pair_t* find = int_hmap_find(&pre->purification_map, t);
37,889✔
764
  if (find != NULL) {
37,889✔
765
    return find->val;
37,363✔
766
  } else {
767
    // Make the variable
768
    type_t t_type = term_type(terms, t);
526✔
769
    term_t x = new_uninterpreted_term(terms, t_type);
526✔
770
    // Remember for later
771
    int_hmap_add(&pre->purification_map, t, x);
526✔
772
    ivector_push(&pre->purification_map_list, t);
526✔
773
    // Also add the variable to the pre-processor
774
    preprocessor_set(pre, x, x);
526✔
775
    // Add equality to output
776
    term_t eq = mk_eq(&pre->tm, x, t);
526✔
777
    ivector_push(out, eq);
526✔
778

779
    if (trace_enabled(pre->tracer, "mcsat::preprocess")) {
526✔
780
      mcsat_trace_printf(pre->tracer, "adding lemma = ");
×
781
      trace_term_ln(pre->tracer, terms, eq);
×
782
    }
783

784
    // Return the purified version
785
    return x;
526✔
786
  }
787
}
788

789
static inline
790
term_t mk_bvneg(term_manager_t* tm, term_t t) {
92✔
791
  term_table_t* terms = tm->terms;
92✔
792
  if (term_bitsize(terms,t) <= 64) {
92✔
793
    bvarith64_buffer_t *buffer = term_manager_get_bvarith64_buffer(tm);
76✔
794
    bvarith64_buffer_set_term(buffer, terms, t);
76✔
795
    bvarith64_buffer_negate(buffer);
76✔
796
    return mk_bvarith64_term(tm, buffer);
76✔
797
  } else {
798
    bvarith_buffer_t *buffer = term_manager_get_bvarith_buffer(tm);
16✔
799
    bvarith_buffer_set_term(buffer, terms, t);
16✔
800
    bvarith_buffer_negate(buffer);
16✔
801
    return mk_bvarith_term(tm, buffer);
16✔
802
  }
803
}
804

805
// Mark equality eq: (var = t) for solving
806
static
807
void preprocessor_mark_eq(preprocessor_t* pre, term_t eq, term_t var) {
25,036✔
808
  assert(is_pos_term(eq));
809
  assert(is_pos_term(var));
810
  assert(term_kind(pre->terms, var) == UNINTERPRETED_TERM);
811

812
  // Mark the equality
813
  int_hmap_pair_t* find = int_hmap_get(&pre->equalities, eq);
25,036✔
814
  assert(find->val == -1);
815
  find->val = var;
25,036✔
816
  ivector_push(&pre->equalities_list, eq);
25,036✔
817
}
25,036✔
818

819
static
820
term_t preprocessor_get_eq_solved_var(const preprocessor_t* pre, term_t eq) {
47,076✔
821
  assert(is_pos_term(eq));
822
  int_hmap_pair_t* find = int_hmap_find((int_hmap_t*) &pre->equalities, eq);
47,076✔
823
  if (find != NULL) {
47,076✔
824
    return find->val;
20,157✔
825
  } else {
826
    return NULL_TERM;
26,919✔
827
  }
828
}
829

830
term_t preprocessor_apply(preprocessor_t* pre, term_t t, ivector_t* out, bool is_assertion) {
39,683✔
831

832
  term_table_t* terms = pre->terms;
39,683✔
833
  term_manager_t* tm = &pre->tm;
39,683✔
834

835
  uint32_t i, j, n;
836
  ivector_t t_blast;
837

838
  tuple_blast_term(pre, t);
39,683✔
839
  init_ivector(&t_blast, 0);
39,683✔
840
  tuple_blast_get(pre, t, &t_blast);
39,683✔
841
  if (t_blast.size != 1) {
39,683✔
NEW
842
    delete_ivector(&t_blast);
×
NEW
843
    longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
×
844
  }
845
  t = t_blast.data[0];
39,683✔
846
  delete_ivector(&t_blast);
39,683✔
847

848
  // Check if already preprocessed;
849
  term_t t_pre = preprocessor_get(pre, t);
39,683✔
850
  if (t_pre != NULL_TERM) {
39,683✔
851
    return t_pre;
1,863✔
852
  }
853

854
// Note: negative affect on general performance due to solved/substituted
855
//       terms being to complex for explainers.
856
//
857
//  // First, if the assertion is a conjunction, just expand
858
//  if (is_assertion && is_neg_term(t) && term_kind(terms, t) == OR_TERM) {
859
//    // !(or t1 ... tn) -> !t1 && ... && !tn
860
//    composite_term_t* t_desc = composite_term_desc(terms, t);
861
//    for (i = 0; i < t_desc->arity; ++ i) {
862
//      ivector_push(out, opposite_term(t_desc->arg[i]));
863
//    }
864
//    return true_term;
865
//  }
866
//
867
  // Start
868
  ivector_t* pre_stack = &pre->preprocessing_stack;
37,820✔
869
  ivector_reset(pre_stack);
37,820✔
870
  ivector_push(pre_stack, t);
37,820✔
871

872
  // Preprocess
873
  while (pre_stack->size) {
509,609✔
874
    // Current term
875
    term_t current = ivector_last(pre_stack);
471,789✔
876

877
    if (trace_enabled(pre->tracer, "mcsat::preprocess")) {
471,789✔
878
      mcsat_trace_printf(pre->tracer, "current = ");
×
879
      trace_term_ln(pre->tracer, terms, current);
×
880
    }
881

882
    // If preprocessed already, done
883
    term_t current_pre = preprocessor_get(pre, current);
471,789✔
884
    if (current_pre != NULL_TERM) {
471,789✔
885
      ivector_pop(pre_stack);
31,239✔
886
      continue;
31,239✔
887
    }
888

889
    // Negation
890
    if (is_neg_term(current)) {
440,550✔
891
      term_t child = unsigned_term(current);
90,238✔
892
      term_t child_pre = preprocessor_get(pre, child);
90,238✔
893
      if (child_pre == NULL_TERM) {
90,238✔
894
        ivector_push(pre_stack, child);
42,645✔
895
        continue;
42,645✔
896
      } else {
897
        ivector_pop(pre_stack);
47,593✔
898
        current_pre = opposite_term(child_pre);
47,593✔
899
        preprocessor_set(pre, current, current_pre);
47,593✔
900
        continue;
47,593✔
901
      }
902
    }
903

904
    // Check for supported types
905
    type_kind_t type = term_type_kind(terms, current);
350,312✔
906
    switch (type) {
350,312✔
907
    case BOOL_TYPE:
350,312✔
908
    case INT_TYPE:
909
    case REAL_TYPE:
910
    case FF_TYPE:
911
    case UNINTERPRETED_TYPE:
912
    case FUNCTION_TYPE:
913
    case BITVECTOR_TYPE:
914
    case SCALAR_TYPE:
915
      break;
350,312✔
916
    default:
×
917
      longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
×
918
    }
919

920
    // Kind of term
921
    term_kind_t current_kind = term_kind(terms, current);
350,312✔
922

923
    switch(current_kind) {
350,312✔
924
    case CONSTANT_TERM:    // constant of uninterpreted/scalar/boolean types
1,748✔
925
    case BV64_CONSTANT:    // compact bitvector constant (64 bits at most)
926
    case BV_CONSTANT:      // generic bitvector constant (more than 64 bits)
927
    case ARITH_CONSTANT:   // rational constant
928
    case ARITH_FF_CONSTANT:   // finite field constant
929
      current_pre = current;
1,748✔
930
      break;
1,748✔
931

932
    case UNINTERPRETED_TERM:  // (i.e., global variables, can't be bound).
14,807✔
933
      current_pre = current;
14,807✔
934
      // Unless we want special slicing
935
      if (type == BITVECTOR_TYPE) {
14,807✔
936
        if (pre->options->bv_var_size > 0) {
5,016✔
937
          uint32_t size = term_bitsize(terms, current);
23✔
938
          uint32_t var_size = pre->options->bv_var_size;
23✔
939
          if (size > var_size) {
23✔
940
            uint32_t n_vars = (size - 1) / var_size + 1;
2✔
941
            term_t vars[n_vars];
2✔
942
            for (i = n_vars - 1; size > 0; i--) {
8✔
943
              if (size >= var_size) {
6✔
944
                vars[i] = new_uninterpreted_term(terms, bv_type(terms->types, var_size));
4✔
945
                size -= var_size;
4✔
946
              } else {
947
                vars[i] = new_uninterpreted_term(terms, bv_type(terms->types, size));
2✔
948
                size = 0;
2✔
949
              }
950
            }
951
            current_pre = _o_yices_bvconcat(n_vars, vars);
2✔
952
            term_t eq = _o_yices_eq(current, current_pre);
2✔
953
            preprocessor_mark_eq(pre, eq, current);
2✔
954
          }
955
        }
956
      }
957
      break;
14,807✔
958

959
    case ITE_TERM:           // if-then-else
183,772✔
960
    case ITE_SPECIAL:        // special if-then-else term (NEW: EXPERIMENTAL)
961
    case EQ_TERM:            // equality
962
    case OR_TERM:            // n-ary OR
963
    case XOR_TERM:           // n-ary XOR
964
    case ARITH_EQ_ATOM:      // equality (t == 0)
965
    case ARITH_BINEQ_ATOM:   // equality (t1 == t2)  (between two arithmetic terms)
966
    case ARITH_GE_ATOM:      // inequality (t >= 0)
967
    case ARITH_FF_EQ_ATOM:   // finite field equality (t == 0)
968
    case ARITH_FF_BINEQ_ATOM: // finite field equality (t1 == t2)  (between two arithmetic terms)
969
    case BV_DIV:
970
    case BV_REM:
971
    case BV_SMOD:
972
    case BV_SHL:
973
    case BV_LSHR:
974
    case BV_ASHR:
975
    case BV_EQ_ATOM:
976
    case BV_GE_ATOM:
977
    case BV_SGE_ATOM:
978
    {
979
      composite_term_t* desc = get_composite(terms, current_kind, current);
183,772✔
980
      bool children_done = true;
183,772✔
981
      bool children_same = true;
183,772✔
982

983
      n = desc->arity;
183,772✔
984

985
      /*
986
      // Arrays not supported yet
987
      if (current_kind == EQ_TERM && term_type_kind(terms, desc->arg[0]) == FUNCTION_TYPE) {
988
        longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
989
      }
990
      */
991
 
992
      // Is this a top-level equality assertion
993
      bool is_equality =
183,772✔
994
          current_kind == EQ_TERM ||
163,490✔
995
          current_kind == BV_EQ_ATOM ||
104,992✔
996
          current_kind == ARITH_EQ_ATOM ||
101,322✔
997
          current_kind == ARITH_BINEQ_ATOM ||
97,325✔
998
          current_kind == ARITH_FF_EQ_ATOM ||
347,262✔
999
          current_kind == ARITH_FF_BINEQ_ATOM;
1000
      // don't rewrite if the equality is between Boolean terms
1001
      bool is_boolean = is_boolean_type(term_type(pre->terms, desc->arg[0]));
183,772✔
1002

1003
      term_t eq_solve_var = NULL_TERM;
183,772✔
1004
      if (is_assertion && is_equality && !is_boolean) {
183,772✔
1005
        bool is_lhs_rhs_mixed = desc->arity > 1 &&
141,277✔
1006
          term_type_kind(pre->terms, desc->arg[0]) != term_type_kind(pre->terms, desc->arg[1]);
68,726✔
1007
        // don't rewrite if equality is between mixed terms, e.g. between int and real terms
1008
        if (!is_lhs_rhs_mixed && current == t) {
72,551✔
1009
          eq_solve_var = preprocessor_get_eq_solved_var(pre, t);
47,073✔
1010
          if (eq_solve_var == NULL_TERM) {
47,073✔
1011
            term_t lhs = desc->arg[0];
26,919✔
1012
            term_kind_t lhs_kind = term_kind(terms, lhs);
26,919✔
1013
            // If lhs/rhs is a first-time seen variable, we can solve it
1014
            bool lhs_is_var = lhs_kind == UNINTERPRETED_TERM && is_pos_term(lhs);
26,919✔
1015
            if (lhs_is_var && preprocessor_get(pre, lhs) == NULL_TERM) {
26,919✔
1016
              // First time variable, let's solve
1017
              preprocessor_mark_eq(pre, t, lhs);
24,779✔
1018
              eq_solve_var = lhs;
24,779✔
1019
            } else if (desc->arity > 1) {
2,140✔
1020
              term_t rhs = desc->arg[1];
1,430✔
1021
              term_kind_t rhs_kind = term_kind(terms, rhs);
1,430✔
1022
              bool rhs_is_var = rhs_kind == UNINTERPRETED_TERM && is_pos_term(rhs);
1,430✔
1023
              if (rhs_is_var && preprocessor_get(pre, rhs) == NULL_TERM) {
1,430✔
1024
                // First time variable, let's solve
1025
                preprocessor_mark_eq(pre, t, rhs);
255✔
1026
                eq_solve_var = rhs;
255✔
1027
              }
1028
            }
1029
          } else {
1030
            // Check that we it's not there already
1031
            if (preprocessor_get(pre, eq_solve_var) != NULL_TERM) {
20,154✔
1032
              eq_solve_var = NULL_TERM;
244✔
1033
            }
1034
          }
1035
        }
1036
      }
1037

1038
      ivector_t children;
1039
      init_ivector(&children, n);
183,772✔
1040

1041
      for (i = 0; i < n; ++ i) {
612,155✔
1042
        term_t child = desc->arg[i];
428,383✔
1043
        if (child != eq_solve_var) {
428,383✔
1044
          term_t child_pre = preprocessor_get(pre, child);
383,439✔
1045
          if (child_pre == NULL_TERM) {
383,439✔
1046
            children_done = false;
110,422✔
1047
            ivector_push(pre_stack, child);
110,422✔
1048
          } else if (child_pre != child) {
273,017✔
1049
            children_same = false;
106,138✔
1050
          }
1051
          if (children_done) {
383,439✔
1052
            ivector_push(&children, child_pre);
259,050✔
1053
          }
1054
        }
1055
      }
1056

1057
      if (eq_solve_var != NULL_TERM) {
183,772✔
1058
        // Check again to make sure we don't have something like x = x + 1
1059
        if (preprocessor_get(pre, eq_solve_var) != NULL_TERM) {
44,944✔
1060
          // Do it again
1061
          children_done = false;
×
1062
        }
1063
      }
1064

1065
      if (children_done) {
183,772✔
1066
        if (eq_solve_var != NULL_TERM) {
114,726✔
1067
          term_t eq_solve_term = zero_term;
24,790✔
1068
          if (children.size > 0) {
24,790✔
1069
            eq_solve_term = children.data[0];
24,752✔
1070
          }
1071
          preprocessor_set(pre, eq_solve_var, eq_solve_term);
24,790✔
1072
          current_pre = true_term;
24,790✔
1073
        } else {
1074
          if (children_same) {
89,936✔
1075
            current_pre = current;
51,458✔
1076
          } else {
1077
            current_pre = mk_composite(pre, current_kind, n, children.data);
38,478✔
1078
          }
1079
        }
1080
      }
1081

1082
      delete_ivector(&children);
183,772✔
1083

1084
      break;
183,772✔
1085
    }
1086

1087
    case BV_ARRAY:
17,561✔
1088
    {
1089
      composite_term_t* desc = get_composite(terms, current_kind, current);
17,561✔
1090
      bool children_done = true;
17,561✔
1091
      bool children_same = true;
17,561✔
1092

1093
      n = desc->arity;
17,561✔
1094

1095
      ivector_t children;
1096
      init_ivector(&children, n);
17,561✔
1097

1098
      for (i = 0; i < n; ++ i) {
355,722✔
1099
        term_t child = desc->arg[i];
338,161✔
1100
        term_t child_pre = preprocessor_get(pre, child);
338,161✔
1101
        if (child_pre == NULL_TERM) {
338,161✔
1102
          children_done = false;
143,656✔
1103
          ivector_push(pre_stack, child);
143,656✔
1104
        } else {
1105
          if (is_arithmetic_literal(terms, child_pre) || child_pre == false_term) {
194,505✔
1106
            // purify if arithmetic literal, i.e. a = 0 where a is of integer type
1107
            child_pre = preprocessor_purify(pre, child_pre, out);
36,819✔
1108
          }
1109
          if (child_pre != child) {
194,505✔
1110
            children_same = false;
111,137✔
1111
          }
1112
        }
1113
        if (children_done) {
338,161✔
1114
          ivector_push(&children, child_pre);
180,883✔
1115
        }
1116
      }
1117

1118
      if (children_done) {
17,561✔
1119
        if (children_same) {
9,189✔
1120
          current_pre = current;
2,214✔
1121
        } else {
1122
          current_pre = mk_composite(pre, current_kind, n, children.data);
6,975✔
1123
        }
1124
      }
1125

1126
      delete_ivector(&children);
17,561✔
1127

1128
      break;
17,561✔
1129
    }
1130

1131
    case ARITH_ABS:
6✔
1132
    {
1133
      term_t arg = arith_abs_arg(terms, current);
6✔
1134
      term_t arg_pre = preprocessor_get(pre, arg);
6✔
1135
      if (arg_pre == NULL_TERM) {
6✔
1136
        ivector_push(pre_stack, arg);
2✔
1137
      } else {
1138
        type_t arg_pre_type = term_type(pre->terms, arg_pre);
4✔
1139
        term_t arg_pre_is_positive = mk_arith_term_geq0(&pre->tm, arg_pre);
4✔
1140
        term_t arg_negative = _o_yices_neg(arg_pre);
4✔
1141
        current_pre = mk_ite(&pre->tm, arg_pre_is_positive, arg_pre, arg_negative, arg_pre_type);
4✔
1142
      }
1143
      break;
6✔
1144
    }
1145

1146
    case BV_SDIV:
20✔
1147
    {
1148
      composite_term_t* desc = get_composite(terms, current_kind, current);
20✔
1149
      assert(desc->arity == 2);
1150
      term_t s = desc->arg[0];
20✔
1151
      term_t s_pre = preprocessor_get(pre, s);
20✔
1152
      if (s_pre == NULL_TERM) {
20✔
1153
        ivector_push(pre_stack, s);
7✔
1154
      }
1155
      term_t t = desc->arg[1];
20✔
1156
      term_t t_pre = preprocessor_get(pre, t);
20✔
1157
      if (t_pre == NULL_TERM) {
20✔
1158
        ivector_push(pre_stack, t);
5✔
1159
      }
1160
      if (s_pre != NULL_TERM && t_pre != NULL_TERM) {
20✔
1161
        type_t tau = term_type(terms, s_pre);
11✔
1162
        uint32_t n = term_bitsize(terms, s_pre);
11✔
1163
        term_t msb_s = mk_bitextract(tm, s_pre, n-1);
11✔
1164
        term_t msb_t = mk_bitextract(tm, t_pre, n-1);
11✔
1165
        // if (msb_s) {
1166
        //   if (msb_t) {
1167
        //     t1: udiv(-s, -t)
1168
        //   } else {
1169
        //     t2: -udiv(-s, t)
1170
        //   }
1171
        // } else {
1172
        //   if (msb_t) {
1173
        //     t3: -udiv(s, -t)
1174
        //   } else {
1175
        //     t4: udiv(s, t)
1176
        //   }
1177
        // }
1178
        term_t neg_s = mk_bvneg(tm, s_pre);
11✔
1179
        term_t neg_t = mk_bvneg(tm, t_pre);
11✔
1180

1181
        term_t t1 = mk_bvdiv(tm, neg_s, neg_t);
11✔
1182
        term_t t2 = mk_bvdiv(tm, neg_s, t_pre);
11✔
1183
        t2 = mk_bvneg(&pre->tm, t2);
11✔
1184
        term_t t3 = mk_bvdiv(tm, s_pre, neg_t);
11✔
1185
        t3 = mk_bvneg(&pre->tm, t3);
11✔
1186
        term_t t4 = mk_bvdiv(tm, s_pre, t_pre);
11✔
1187

1188
        term_t b1 = mk_ite(tm, msb_t, t1, t2, tau);
11✔
1189
        term_t b2 = mk_ite(tm, msb_t, t3, t4, tau);
11✔
1190

1191
        current_pre = mk_ite(tm, msb_s, b1, b2, tau);
11✔
1192
      }
1193
      break;
20✔
1194
    }
1195
    case BV_SREM:
21✔
1196
    {
1197
      composite_term_t* desc = get_composite(terms, current_kind, current);
21✔
1198
      assert(desc->arity == 2);
1199
      term_t s = desc->arg[0];
21✔
1200
      term_t s_pre = preprocessor_get(pre, s);
21✔
1201
      if (s_pre == NULL_TERM) {
21✔
1202
        ivector_push(pre_stack, s);
8✔
1203
      }
1204
      term_t t = desc->arg[1];
21✔
1205
      term_t t_pre = preprocessor_get(pre, t);
21✔
1206
      if (t_pre == NULL_TERM) {
21✔
1207
        ivector_push(pre_stack, t);
3✔
1208
      }
1209
      if (s_pre != NULL_TERM && t_pre != NULL_TERM) {
21✔
1210
        type_t tau = term_type(terms, s_pre);
12✔
1211
        uint32_t n = term_bitsize(terms, s_pre);
12✔
1212
        term_t msb_s = mk_bitextract(tm, s_pre, n-1);
12✔
1213
        term_t msb_t = mk_bitextract(tm, t_pre, n-1);
12✔
1214
        // if (msb_s) {
1215
        //   if (msb_t) {
1216
        //     t1: -urem(-s, -t)
1217
        //   } else {
1218
        //     t2: -urem(-s, t)
1219
        //   }
1220
        // } else {
1221
        //   if (msb_t) {
1222
        //     t3: -urem(s, -t)
1223
        //   } else {
1224
        //     t4: urem(s, t)
1225
        //   }
1226
        // }
1227
        term_t neg_s = mk_bvneg(tm, s_pre);
12✔
1228
        term_t neg_t = mk_bvneg(tm, t_pre);
12✔
1229

1230
        term_t t1 = mk_bvrem(tm, neg_s, neg_t);
12✔
1231
        t1 = mk_bvneg(tm, t1);
12✔
1232
        term_t t2 = mk_bvrem(tm, neg_s, t_pre);
12✔
1233
        t2 = mk_bvneg(tm, t2);
12✔
1234
        term_t t3 = mk_bvrem(tm, s_pre, neg_t);
12✔
1235
        term_t t4 = mk_bvrem(tm, s_pre, t_pre);
12✔
1236

1237
        term_t b1 = mk_ite(tm, msb_t, t1, t2, tau);
12✔
1238
        term_t b2 = mk_ite(tm, msb_t, t3, t4, tau);
12✔
1239

1240
        current_pre = mk_ite(tm, msb_s, b1, b2, tau);
12✔
1241
      }
1242
      break;
21✔
1243
    }
1244
    case BIT_TERM: // bit-select current = child[i]
112,996✔
1245
    {
1246
      uint32_t index = bit_term_index(terms, current);
112,996✔
1247
      term_t arg = bit_term_arg(terms, current);
112,996✔
1248
      term_t arg_pre = preprocessor_get(pre, arg);
112,996✔
1249
      if (arg_pre == NULL_TERM) {
112,996✔
1250
        ivector_push(pre_stack, arg);
1,587✔
1251
      } else {
1252
        if (arg_pre == arg) {
111,409✔
1253
          current_pre = current;
73,367✔
1254
        } else {
1255
          if (trace_enabled(pre->tracer, "mcsat::preprocess")) {
38,042✔
1256
            mcsat_trace_printf(pre->tracer, "arg_pre = ");
×
1257
            trace_term_ln(pre->tracer, terms, arg_pre);
×
1258
          }
1259
          // For simplification purposes use API
1260
          current_pre = _o_yices_bitextract(arg_pre, index);
38,042✔
1261
          assert(current_pre != NULL_TERM);
1262
        }
1263
      }
1264
      break;
112,996✔
1265
    }
1266
    case BV_POLY:  // polynomial with generic bitvector coefficients
33✔
1267
    {
1268
      bvpoly_t* p = bvpoly_term_desc(terms, current);
33✔
1269

1270
      bool children_done = true;
33✔
1271
      bool children_same = true;
33✔
1272

1273
      n = p->nterms;
33✔
1274

1275
      ivector_t children;
1276
      init_ivector(&children, n);
33✔
1277

1278
      for (i = 0; i < n; ++ i) {
84✔
1279
        term_t x = p->mono[i].var;
51✔
1280
        term_t x_pre = (x == const_idx ? const_idx : preprocessor_get(pre, x));
51✔
1281

1282
        if (x_pre != const_idx) {
51✔
1283
          if (x_pre == NULL_TERM) {
47✔
1284
            children_done = false;
10✔
1285
            ivector_push(pre_stack, x);
10✔
1286
          } else if (x_pre != x) {
37✔
1287
            children_same = false;
23✔
1288
          }
1289
        }
1290

1291
        if (children_done) { ivector_push(&children, x_pre); }
51✔
1292
      }
1293

1294
      if (children_done) {
33✔
1295
        if (children_same) {
26✔
1296
          current_pre = current;
11✔
1297
        } else {
1298
          current_pre = mk_bvarith_poly(tm, p, n, children.data);
15✔
1299
        }
1300
      }
1301

1302
      delete_ivector(&children);
33✔
1303

1304
      break;
33✔
1305
    }
1306
    case BV64_POLY: // polynomial with 64bit coefficients
2,804✔
1307
    {
1308
      bvpoly64_t* p = bvpoly64_term_desc(terms, current);
2,804✔
1309

1310
      bool children_done = true;
2,804✔
1311
      bool children_same = true;
2,804✔
1312

1313
      n = p->nterms;
2,804✔
1314

1315
      ivector_t children;
1316
      init_ivector(&children, n);
2,804✔
1317

1318
      for (i = 0; i < n; ++ i) {
10,520✔
1319
        term_t x = p->mono[i].var;
7,716✔
1320
        term_t x_pre = (x == const_idx ? const_idx : preprocessor_get(pre, x));
7,716✔
1321

1322
        if (x_pre != const_idx) {
7,716✔
1323
          if (x_pre == NULL_TERM) {
5,839✔
1324
            children_done = false;
1,394✔
1325
            ivector_push(pre_stack, x);
1,394✔
1326
          } else if (x_pre != x) {
4,445✔
1327
            children_same = false;
3,567✔
1328
          }
1329
        }
1330

1331
        if (children_done) { ivector_push(&children, x_pre); }
7,716✔
1332
      }
1333

1334
      if (children_done) {
2,804✔
1335
        if (children_same) {
2,027✔
1336
          current_pre = current;
435✔
1337
        } else {
1338
          current_pre = mk_bvarith64_poly(tm, p, n, children.data);
1,592✔
1339
        }
1340
      }
1341

1342
      delete_ivector(&children);
2,804✔
1343

1344
      break;
2,804✔
1345
    }
1346

1347
    case POWER_PRODUCT:    // power products: (t1^d1 * ... * t_n^d_n)
1,665✔
1348
    {
1349
      pprod_t* pp = pprod_term_desc(terms, current);
1,665✔
1350
      bool children_done = true;
1,665✔
1351
      bool children_same = true;
1,665✔
1352

1353
      n = pp->len;
1,665✔
1354

1355
      ivector_t children;
1356
      init_ivector(&children, n);
1,665✔
1357

1358
      for (i = 0; i < n; ++ i) {
5,282✔
1359
        term_t x = pp->prod[i].var;
3,617✔
1360
        term_t x_pre = preprocessor_get(pre, x);
3,617✔
1361

1362
        if (x_pre == NULL_TERM) {
3,617✔
1363
          children_done = false;
449✔
1364
          ivector_push(pre_stack, x);
449✔
1365
        } else if (x_pre != x) {
3,168✔
1366
          children_same = false;
89✔
1367
        }
1368

1369
        if (children_done) { ivector_push(&children, x_pre); }
3,617✔
1370
      }
1371

1372
      if (children_done) {
1,665✔
1373
        if (children_same) {
1,331✔
1374
          current_pre = current;
1,278✔
1375
        } else {
1376
          // NOTE: it doens't change pp, it just uses it as a frame
1377
          current_pre = mk_pprod(tm, pp, n, children.data);
53✔
1378
        }
1379
      }
1380

1381
      delete_ivector(&children);
1,665✔
1382

1383
      break;
1,665✔
1384
    }
1385

1386
    case ARITH_POLY:       // polynomial with rational coefficients
6,750✔
1387
    {
1388
      polynomial_t* p = poly_term_desc(terms, current);
6,750✔
1389

1390
      bool children_done = true;
6,750✔
1391
      bool children_same = true;
6,750✔
1392

1393
      n = p->nterms;
6,750✔
1394

1395
      ivector_t children;
1396
      init_ivector(&children, n);
6,750✔
1397

1398
      for (i = 0; i < n; ++ i) {
26,245✔
1399
        term_t x = p->mono[i].var;
19,495✔
1400
        term_t x_pre = (x == const_idx ? const_idx : preprocessor_get(pre, x));
19,495✔
1401

1402
        if (x_pre != const_idx) {
19,495✔
1403
          if (x_pre == NULL_TERM) {
16,478✔
1404
            children_done = false;
2,506✔
1405
            ivector_push(pre_stack, x);
2,506✔
1406
          } else if (x_pre != x) {
13,972✔
1407
            children_same = false;
762✔
1408
          }
1409
        }
1410

1411
        if (children_done) { ivector_push(&children, x_pre); }
19,495✔
1412
      }
1413

1414
      if (children_done) {
6,750✔
1415
        if (children_same) {
5,347✔
1416
          current_pre = current;
4,831✔
1417
        } else {
1418
          current_pre = mk_arith_poly(tm, p, n, children.data);
516✔
1419
        }
1420
      }
1421

1422
      delete_ivector(&children);
6,750✔
1423

1424
      break;
6,750✔
1425
    }
1426

1427
    case ARITH_FF_POLY:    // polynomial with finite field coefficients
150✔
1428
    {
1429
      polynomial_t* p = finitefield_poly_term_desc(terms, current);
150✔
1430
      const rational_t *mod = finitefield_term_order(terms, current);
150✔
1431

1432
      bool children_done = true;
150✔
1433
      bool children_same = true;
150✔
1434

1435
      n = p->nterms;
150✔
1436

1437
      ivector_t children;
1438
      init_ivector(&children, n);
150✔
1439

1440
      for (i = 0; i < n; ++ i) {
1,068✔
1441
        term_t x = p->mono[i].var;
918✔
1442
        term_t x_pre = (x == const_idx ? const_idx : preprocessor_get(pre, x));
918✔
1443

1444
        if (x_pre != const_idx) {
918✔
1445
          if (x_pre == NULL_TERM) {
864✔
1446
            children_done = false;
380✔
1447
            ivector_push(pre_stack, x);
380✔
1448
          } else if (x_pre != x) {
484✔
1449
            children_same = false;
×
1450
          }
1451
        }
1452

1453
        if (children_done) { ivector_push(&children, x_pre); }
918✔
1454
      }
1455

1456
      if (children_done) {
150✔
1457
        if (children_same) {
75✔
1458
          current_pre = current;
75✔
1459
        } else {
1460
          current_pre = mk_arith_ff_poly(tm, p, n, children.data, mod);
×
1461
        }
1462
      }
1463

1464
      delete_ivector(&children);
150✔
1465

1466
      break;
150✔
1467
    }
1468

1469
    // FOLLOWING ARE UNINTEPRETED, SO WE PURIFY THE ARGUMENTS
1470

1471
    case APP_TERM:           // application of an uninterpreted function
7,972✔
1472
    case ARITH_RDIV:         // regular division (/ x y)
1473
    case ARITH_IDIV:         // division: (div x y) as defined in SMT-LIB 2
1474
    case ARITH_MOD:          // remainder: (mod x y) is y - x * (div x y)
1475
    case UPDATE_TERM:        // update array
1476
    {
1477
      composite_term_t* desc = get_composite(terms, current_kind, current);
7,972✔
1478
      bool children_done = true;
7,972✔
1479
      bool children_same = true;
7,972✔
1480

1481
      n = desc->arity;
7,972✔
1482

1483
      ivector_t children;
1484
      init_ivector(&children, n);
7,972✔
1485

1486
      for (i = 0; i < n; ++ i) {
27,263✔
1487
        term_t child = desc->arg[i];
19,291✔
1488
        term_t child_pre = preprocessor_get(pre, child);
19,291✔
1489

1490
        if (child_pre == NULL_TERM) {
19,291✔
1491
          children_done = false;
3,814✔
1492
          ivector_push(pre_stack, child);
3,814✔
1493
        } else {
1494
          // Purify if needed
1495
          child_pre = preprocessor_purify(pre, child_pre, out);
15,477✔
1496
          // If interpreted terms, we need to purify non-variables
1497
          if (child_pre != child) { children_same = false; }
15,477✔
1498
        }
1499

1500
        if (children_done) { ivector_push(&children, child_pre); }
19,291✔
1501
      }
1502

1503
      if (children_done) {
7,972✔
1504
        if (children_same) {
5,163✔
1505
          current_pre = current;
3,826✔
1506
        } else {
1507
          current_pre = mk_composite(pre, current_kind, n, children.data);
1,337✔
1508
        }
1509
      }
1510

1511
      delete_ivector(&children);
7,972✔
1512

1513
      break;
7,972✔
1514
    }
1515

1516
    case ARITH_IS_INT_ATOM:
×
1517
    {
1518
      // replace with t <= floor(t)
1519
      term_t child = arith_is_int_arg(terms, current);
×
1520
      term_t child_pre = preprocessor_get(pre, child);
×
1521
      if (child_pre != NULL_TERM) {
×
1522
        child_pre = preprocessor_purify(pre, child_pre, out);
×
1523
        current_pre = arith_floor(terms, child_pre);
×
1524
        current_pre = mk_arith_leq(tm, child_pre, current_pre);
×
1525
      } else {
1526
        ivector_push(pre_stack, child);
×
1527
      }
1528
      break;
×
1529
    }
1530

1531
    case ARITH_FLOOR:        // floor: purify, but its interpreted
7✔
1532
    {
1533
      term_t child = arith_floor_arg(terms, current);
7✔
1534
      term_t child_pre = preprocessor_get(pre, child);
7✔
1535

1536
      if (child_pre != NULL_TERM) {
7✔
1537
        if (term_kind(terms, child_pre) == ARITH_CONSTANT) {
4✔
1538
          rational_t floor;
1539
          q_init(&floor);
1✔
1540
          q_set(&floor, rational_term_desc(terms, child_pre));
1✔
1541
          q_floor(&floor);
1✔
1542
          current_pre = arith_constant(terms, &floor);
1✔
1543
          q_clear(&floor);
1✔
1544
        } else {
1545
          child_pre = preprocessor_purify(pre, child_pre, out);
3✔
1546
          if (child_pre != child) {
3✔
1547
            current_pre = arith_floor(terms, child_pre);
1✔
1548
          } else {
1549
            current_pre = current;
2✔
1550
          }
1551
        }
1552
      } else {
1553
        ivector_push(pre_stack, child);
3✔
1554
      }
1555

1556
      break;
7✔
1557
    }
1558

1559
    case ARITH_CEIL:        // floor: purify, but its interpreted
×
1560
    {
1561
      term_t child = arith_ceil_arg(terms, current);
×
1562
      term_t child_pre = preprocessor_get(pre, child);
×
1563

1564
      if (child_pre != NULL_TERM) {
×
1565
        child_pre = preprocessor_purify(pre, child_pre, out);
×
1566
        if (child_pre != child) {
×
1567
          current_pre = arith_floor(terms, child_pre);
×
1568
        } else {
1569
          current_pre = current;
×
1570
        }
1571
      } else {
1572
        ivector_push(pre_stack, child);
×
1573
      }
1574

1575
      break;
×
1576
    }
1577

UNCOV
1578
    case DISTINCT_TERM:
×
1579
    {
UNCOV
1580
      composite_term_t* desc = get_composite(terms, current_kind, current);
×
1581

UNCOV
1582
      bool children_done = true;
×
UNCOV
1583
      n = desc->arity;
×
1584

1585
      ivector_t children;
UNCOV
1586
      init_ivector(&children, n);
×
1587

UNCOV
1588
      for (i = 0; i < n; ++ i) {
×
UNCOV
1589
        term_t child = desc->arg[i];
×
UNCOV
1590
        term_t child_pre = preprocessor_get(pre, child);
×
1591

UNCOV
1592
        if (child_pre == NULL_TERM) {
×
UNCOV
1593
          children_done = false;
×
UNCOV
1594
          ivector_push(pre_stack, child);
×
1595
        }
1596

UNCOV
1597
        if (children_done) { ivector_push(&children, child_pre); }
×
1598
      }
1599

UNCOV
1600
      if (children_done) {
×
1601
        ivector_t distinct;
UNCOV
1602
        init_ivector(&distinct, 0);
×
1603

UNCOV
1604
        for (i = 0; i < n; ++ i) {
×
UNCOV
1605
          for (j = i + 1; j < n; ++ j) {
×
UNCOV
1606
            term_t neq = mk_eq(&pre->tm, children.data[i], children.data[j]);
×
UNCOV
1607
            neq = opposite_term(neq);
×
UNCOV
1608
            ivector_push(&distinct, neq);
×
1609
          }
1610
        }
UNCOV
1611
        current_pre = mk_and(&pre->tm, distinct.size, distinct.data);
×
1612

UNCOV
1613
        delete_ivector(&distinct);
×
1614
      }
1615

UNCOV
1616
      delete_ivector(&children);
×
1617

UNCOV
1618
      break;
×
1619
    }
1620

1621
    default:
×
1622
      // UNSUPPORTED TERM/THEORY
1623
      longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
×
1624
      break;
1625
    }
1626

1627
    if (current_pre != NULL_TERM) {
350,312✔
1628
      preprocessor_set(pre, current, current_pre);
265,879✔
1629
      ivector_pop(pre_stack);
265,879✔
1630
      if (trace_enabled(pre->tracer, "mcsat::preprocess")) {
265,879✔
1631
        mcsat_trace_printf(pre->tracer, "current_pre = ");
×
1632
        trace_term_ln(pre->tracer, terms, current_pre);
×
1633
      }
1634
    }
1635

1636
  }
1637

1638
  // Return the result
1639
  t_pre = preprocessor_get(pre, t);
37,820✔
1640
  if (trace_enabled(pre->tracer, "mcsat::preprocess")) {
37,820✔
1641
    mcsat_trace_printf(pre->tracer, "t_pre = ");
×
1642
    trace_term_ln(pre->tracer, terms, t_pre);
×
1643
  }
1644

1645
  ivector_reset(pre_stack);
37,820✔
1646

1647
  assert(t_pre != NULL_TERM);
1648
  return t_pre;
37,820✔
1649
}
1650

1651
void preprocessor_set_exception_handler(preprocessor_t* pre, jmp_buf* handler) {
×
1652
  pre->exception = handler;
×
1653
}
×
1654

1655
void preprocessor_push(preprocessor_t* pre) {
523✔
1656
  scope_holder_push(&pre->scope,
523✔
1657
      &pre->preprocess_map_list.size,
1658
      &pre->tuple_blast_list.size,
1659
      &pre->tuple_blast_data.size,
1660
      &pre->tuple_blast_atoms.size,
1661
      &pre->purification_map_list.size,
1662
      &pre->equalities_list.size,
1663
      NULL);
1664
}
523✔
1665

1666
void preprocessor_pop(preprocessor_t* pre) {
449✔
1667

1668
  uint32_t preprocess_map_list_size = 0;
449✔
1669
  uint32_t tuple_blast_list_size = 0;
449✔
1670
  uint32_t tuple_blast_data_size = 0;
449✔
1671
  uint32_t tuple_blast_atoms_size = 0;
449✔
1672
  uint32_t purification_map_list_size = 0;
449✔
1673
  uint32_t equalities_list_size = 0;
449✔
1674

1675
  scope_holder_pop(&pre->scope,
449✔
1676
      &preprocess_map_list_size,
1677
      &tuple_blast_list_size,
1678
      &tuple_blast_data_size,
1679
      &tuple_blast_atoms_size,
1680
      &purification_map_list_size,
1681
      &equalities_list_size,
1682
      NULL);
1683

1684
  while (pre->preprocess_map_list.size > preprocess_map_list_size) {
13,753✔
1685
    term_t t = ivector_last(&pre->preprocess_map_list);
13,304✔
1686
    ivector_pop(&pre->preprocess_map_list);
13,304✔
1687
    int_hmap_pair_t* find = int_hmap_find(&pre->preprocess_map, t);
13,304✔
1688
    assert(find != NULL);
1689
    int_hmap_erase(&pre->preprocess_map, find);
13,304✔
1690
  }
1691

1692
  while (pre->tuple_blast_list.size > tuple_blast_list_size) {
10,096✔
1693
    term_t t = ivector_last(&pre->tuple_blast_list);
9,647✔
1694
    ivector_pop(&pre->tuple_blast_list);
9,647✔
1695
    int_hmap_pair_t* find = int_hmap_find(&pre->tuple_blast_map, t);
9,647✔
1696
    assert(find != NULL);
1697
    int_hmap_erase(&pre->tuple_blast_map, find);
9,647✔
1698
  }
1699
  ivector_shrink(&pre->tuple_blast_data, tuple_blast_data_size);
449✔
1700
  ivector_shrink(&pre->tuple_blast_atoms, tuple_blast_atoms_size);
449✔
1701

1702
  while (pre->purification_map_list.size > purification_map_list_size) {
585✔
1703
    term_t t = ivector_last(&pre->purification_map_list);
136✔
1704
    ivector_pop(&pre->purification_map_list);
136✔
1705
    int_hmap_pair_t* find = int_hmap_find(&pre->purification_map, t);
136✔
1706
    assert(find != NULL);
1707
    int_hmap_erase(&pre->purification_map, find);
136✔
1708
  }
1709

1710
  while (pre->equalities_list.size > equalities_list_size) {
622✔
1711
    term_t eq = ivector_last(&pre->equalities_list);
173✔
1712
    ivector_pop(&pre->equalities_list);
173✔
1713
    int_hmap_pair_t* find = int_hmap_find(&pre->equalities, eq);
173✔
1714
    assert(find != NULL);
1715
    int_hmap_erase(&pre->equalities, find);
173✔
1716
  }
1717
}
449✔
1718

1719
static
NEW
1720
value_t build_value_from_flat(type_table_t* types, value_table_t* vtbl, type_t tau, const value_t* flat, uint32_t* idx) {
×
NEW
1721
  if (type_kind(types, tau) == TUPLE_TYPE) {
×
NEW
1722
    tuple_type_t* tuple = tuple_type_desc(types, tau);
×
NEW
1723
    uint32_t i, n = tuple->nelem;
×
NEW
1724
    value_t elem[n];
×
NEW
1725
    for (i = 0; i < n; ++i) {
×
NEW
1726
      elem[i] = build_value_from_flat(types, vtbl, tuple->elem[i], flat, idx);
×
1727
    }
NEW
1728
    return vtbl_mk_tuple(vtbl, n, elem);
×
1729
  } else {
NEW
1730
    value_t v = flat[*idx];
×
NEW
1731
    (*idx)++;
×
NEW
1732
    return v;
×
1733
  }
1734
}
1735

1736
static
NEW
1737
bool map_args_match(value_table_t* vtbl, value_t map, const value_t* args, uint32_t n) {
×
NEW
1738
  value_map_t* m = vtbl_map(vtbl, map);
×
1739
  uint32_t i;
NEW
1740
  if (m->arity != n) {
×
NEW
1741
    return false;
×
1742
  }
NEW
1743
  for (i = 0; i < n; ++i) {
×
NEW
1744
    if (m->arg[i] != args[i]) {
×
NEW
1745
      return false;
×
1746
    }
1747
  }
NEW
1748
  return true;
×
1749
}
1750

1751
static
NEW
1752
value_t find_map_result(value_table_t* vtbl, const ivector_t* maps, const value_t* args, uint32_t n, value_t def) {
×
1753
  uint32_t i;
NEW
1754
  for (i = 0; i < maps->size; ++i) {
×
NEW
1755
    value_t map = maps->data[i];
×
NEW
1756
    if (map_args_match(vtbl, map, args, n)) {
×
NEW
1757
      return vtbl_map(vtbl, map)->val;
×
1758
    }
1759
  }
NEW
1760
  return def;
×
1761
}
1762

1763
static
NEW
1764
void add_unique_flat_args(ivector_t* offsets, ivector_t* data, const value_t* args, uint32_t n) {
×
1765
  uint32_t i, j;
NEW
1766
  for (i = 0; i < offsets->size; ++i) {
×
NEW
1767
    uint32_t off = offsets->data[i];
×
NEW
1768
    bool same = true;
×
NEW
1769
    for (j = 0; j < n; ++j) {
×
NEW
1770
      if (data->data[off + j] != args[j]) {
×
NEW
1771
        same = false;
×
NEW
1772
        break;
×
1773
      }
1774
    }
NEW
1775
    if (same) {
×
NEW
1776
      return;
×
1777
    }
1778
  }
NEW
1779
  ivector_push(offsets, data->size);
×
NEW
1780
  ivector_add(data, args, n);
×
1781
}
1782

1783
static
NEW
1784
value_t merge_blasted_function_value(preprocessor_t* pre, value_table_t* vtbl, type_t tau, const value_t* leaves, uint32_t nleaves) {
×
NEW
1785
  type_table_t* types = pre->terms->types;
×
NEW
1786
  function_type_t* fun = function_type_desc(types, tau);
×
NEW
1787
  type_t codom = fun->range;
×
1788
  uint32_t i, j;
1789
  ivector_t flat_dom;
1790
  ivector_t unique_offsets;
1791
  ivector_t unique_args;
1792
  ivector_t orig_maps;
NEW
1793
  value_t result = null_value;
×
NEW
1794
  value_t leaf_defaults[nleaves];
×
NEW
1795
  ivector_t leaf_maps[nleaves];
×
1796
  uint32_t flat_n;
NEW
1797
  uint32_t maps_init = 0;
×
1798

NEW
1799
  init_ivector(&flat_dom, 0);
×
NEW
1800
  for (i = 0; i < fun->ndom; ++i) {
×
NEW
1801
    type_collect_flat(types, fun->domain[i], &flat_dom);
×
1802
  }
NEW
1803
  flat_n = flat_dom.size;
×
1804

NEW
1805
  init_ivector(&unique_offsets, 0);
×
NEW
1806
  init_ivector(&unique_args, 0);
×
1807

NEW
1808
  for (i = 0; i < nleaves; ++i) {
×
NEW
1809
    value_t def = null_value;
×
NEW
1810
    type_t leaf_tau = NULL_TYPE;
×
NEW
1811
    init_ivector(&leaf_maps[i], 0);
×
NEW
1812
    maps_init = i + 1;
×
NEW
1813
    if (!object_is_function(vtbl, leaves[i]) && !object_is_update(vtbl, leaves[i])) {
×
NEW
1814
      goto done;
×
1815
    }
NEW
1816
    vtbl_expand_update(vtbl, leaves[i], &def, &leaf_tau);
×
NEW
1817
    leaf_defaults[i] = def;
×
NEW
1818
    if (vtbl->hset1 != NULL) {
×
NEW
1819
      ivector_add(&leaf_maps[i], (int32_t*) vtbl->hset1->data, vtbl->hset1->nelems);
×
NEW
1820
      for (j = 0; j < vtbl->hset1->nelems; ++j) {
×
NEW
1821
        value_map_t* map = vtbl_map(vtbl, vtbl->hset1->data[j]);
×
NEW
1822
        if (map->arity != flat_n) {
×
NEW
1823
          goto done;
×
1824
        }
NEW
1825
        add_unique_flat_args(&unique_offsets, &unique_args, map->arg, flat_n);
×
1826
      }
1827
    }
1828
  }
1829

NEW
1830
  init_ivector(&orig_maps, 0);
×
NEW
1831
  for (i = 0; i < unique_offsets.size; ++i) {
×
NEW
1832
    uint32_t flat_idx = unique_offsets.data[i];
×
NEW
1833
    const value_t* flat_args = (value_t*) (unique_args.data + flat_idx);
×
NEW
1834
    value_t leaf_values[nleaves];
×
1835
    uint32_t idx;
1836
    value_t mapv;
1837

NEW
1838
    for (j = 0; j < nleaves; ++j) {
×
NEW
1839
      leaf_values[j] = find_map_result(vtbl, &leaf_maps[j], flat_args, flat_n, leaf_defaults[j]);
×
1840
    }
1841

NEW
1842
    idx = 0;
×
NEW
1843
    value_t out_val = build_value_from_flat(types, vtbl, codom, leaf_values, &idx);
×
1844

NEW
1845
    value_t args_orig[fun->ndom];
×
NEW
1846
    idx = 0;
×
NEW
1847
    for (j = 0; j < fun->ndom; ++j) {
×
NEW
1848
      args_orig[j] = build_value_from_flat(types, vtbl, fun->domain[j], flat_args, &idx);
×
1849
    }
NEW
1850
    mapv = vtbl_mk_map(vtbl, fun->ndom, args_orig, out_val);
×
NEW
1851
    ivector_push(&orig_maps, mapv);
×
1852
  }
1853

1854
  {
NEW
1855
    uint32_t idx = 0;
×
NEW
1856
    value_t def_val = build_value_from_flat(types, vtbl, codom, leaf_defaults, &idx);
×
NEW
1857
    result = vtbl_mk_function(vtbl, tau, orig_maps.size, (value_t*) orig_maps.data, def_val);
×
1858
  }
1859

NEW
1860
  delete_ivector(&orig_maps);
×
1861

NEW
1862
 done:
×
NEW
1863
  for (i = 0; i < maps_init; ++i) {
×
NEW
1864
    delete_ivector(&leaf_maps[i]);
×
1865
  }
NEW
1866
  delete_ivector(&unique_offsets);
×
NEW
1867
  delete_ivector(&unique_args);
×
NEW
1868
  delete_ivector(&flat_dom);
×
NEW
1869
  return result;
×
1870
}
1871

1872
static
1873
void preprocessor_build_tuple_model(preprocessor_t* pre, model_t* model) {
30✔
1874
  value_table_t* vtbl = model_get_vtbl(model);
30✔
1875
  type_table_t* types = pre->terms->types;
30✔
1876
  uint32_t i;
1877

1878
  for (i = 0; i < pre->tuple_blast_atoms.size; ++i) {
30✔
NEW
1879
    term_t atom = pre->tuple_blast_atoms.data[i];
×
1880
    ivector_t leaves;
NEW
1881
    type_t tau = term_type(pre->terms, atom);
×
1882
    uint32_t n, j;
1883

NEW
1884
    if (model_find_term_value(model, atom) != null_value) {
×
NEW
1885
      continue;
×
1886
    }
1887

NEW
1888
    init_ivector(&leaves, 0);
×
NEW
1889
    tuple_blast_get(pre, atom, &leaves);
×
NEW
1890
    n = leaves.size;
×
NEW
1891
    if (n == 0) {
×
NEW
1892
      delete_ivector(&leaves);
×
NEW
1893
      continue;
×
1894
    }
1895

NEW
1896
    value_t leaf_vals[n];
×
NEW
1897
    bool ok = true;
×
NEW
1898
    for (j = 0; j < n; ++j) {
×
NEW
1899
      value_t v = model_get_term_value(model, leaves.data[j]);
×
NEW
1900
      if (v < 0) {
×
NEW
1901
        ok = false;
×
NEW
1902
        break;
×
1903
      }
NEW
1904
      leaf_vals[j] = v;
×
1905
    }
NEW
1906
    if (!ok) {
×
NEW
1907
      delete_ivector(&leaves);
×
NEW
1908
      continue;
×
1909
    }
1910

NEW
1911
    if (type_kind(types, tau) == FUNCTION_TYPE) {
×
NEW
1912
      value_t f = merge_blasted_function_value(pre, vtbl, tau, leaf_vals, n);
×
NEW
1913
      if (f >= 0) {
×
NEW
1914
        model_map_term(model, atom, f);
×
1915
      }
1916
    } else {
NEW
1917
      uint32_t idx = 0;
×
NEW
1918
      value_t v = build_value_from_flat(types, vtbl, tau, leaf_vals, &idx);
×
NEW
1919
      model_map_term(model, atom, v);
×
1920
    }
1921

NEW
1922
    delete_ivector(&leaves);
×
1923
  }
1924
}
30✔
1925

1926
static
NEW
1927
void collect_tuple_leaf_terms(preprocessor_t* pre, term_t base, type_t tau, ivector_t* out) {
×
NEW
1928
  type_table_t* types = pre->terms->types;
×
NEW
1929
  if (type_kind(types, tau) == TUPLE_TYPE) {
×
NEW
1930
    tuple_type_t* tuple = tuple_type_desc(types, tau);
×
1931
    uint32_t i;
NEW
1932
    for (i = 0; i < tuple->nelem; ++i) {
×
NEW
1933
      term_t child = mk_select(&pre->tm, i, base);
×
NEW
1934
      collect_tuple_leaf_terms(pre, child, tuple->elem[i], out);
×
1935
    }
1936
  } else {
NEW
1937
    ivector_push(out, base);
×
1938
  }
NEW
1939
}
×
1940

1941
static
NEW
1942
term_t build_term_from_flat(preprocessor_t* pre, type_t tau, const term_t* flat, uint32_t* idx) {
×
NEW
1943
  type_table_t* types = pre->terms->types;
×
NEW
1944
  if (type_kind(types, tau) == TUPLE_TYPE) {
×
NEW
1945
    tuple_type_t* tuple = tuple_type_desc(types, tau);
×
NEW
1946
    uint32_t i, n = tuple->nelem;
×
NEW
1947
    term_t elem[n];
×
NEW
1948
    for (i = 0; i < n; ++i) {
×
NEW
1949
      elem[i] = build_term_from_flat(pre, tuple->elem[i], flat, idx);
×
1950
    }
NEW
1951
    return mk_tuple(&pre->tm, n, elem);
×
1952
  } else {
NEW
1953
    term_t t = flat[*idx];
×
NEW
1954
    (*idx)++;
×
NEW
1955
    return t;
×
1956
  }
1957
}
1958

1959
static
NEW
1960
bool substitution_has_var(const ivector_t* vars, term_t x) {
×
1961
  uint32_t i;
NEW
1962
  for (i = 0; i < vars->size; ++i) {
×
NEW
1963
    if (vars->data[i] == x) {
×
NEW
1964
      return true;
×
1965
    }
1966
  }
NEW
1967
  return false;
×
1968
}
1969

1970
static
NEW
1971
term_t mk_unblasted_function_leaf_lambda(preprocessor_t* pre, term_t atom, uint32_t leaf_i, term_t leaf_var) {
×
NEW
1972
  term_table_t* terms = pre->terms;
×
NEW
1973
  type_table_t* types = terms->types;
×
NEW
1974
  function_type_t* atom_fun = function_type_desc(types, term_type(terms, atom));
×
NEW
1975
  function_type_t* leaf_fun = function_type_desc(types, term_type(terms, leaf_var));
×
NEW
1976
  uint32_t flat_n = leaf_fun->ndom;
×
1977
  uint32_t i, idx;
NEW
1978
  term_t flat_vars[flat_n];
×
NEW
1979
  term_t orig_args[atom_fun->ndom];
×
1980
  term_t app;
1981
  ivector_t codom_leaves;
1982

NEW
1983
  for (i = 0; i < flat_n; ++i) {
×
NEW
1984
    flat_vars[i] = new_variable(terms, leaf_fun->domain[i]);
×
1985
  }
1986

NEW
1987
  idx = 0;
×
NEW
1988
  for (i = 0; i < atom_fun->ndom; ++i) {
×
NEW
1989
    orig_args[i] = build_term_from_flat(pre, atom_fun->domain[i], flat_vars, &idx);
×
1990
  }
1991
  assert(idx == flat_n);
1992

NEW
1993
  app = mk_application(&pre->tm, atom, atom_fun->ndom, orig_args);
×
NEW
1994
  init_ivector(&codom_leaves, 0);
×
NEW
1995
  collect_tuple_leaf_terms(pre, app, atom_fun->range, &codom_leaves);
×
1996
  assert(leaf_i < codom_leaves.size);
NEW
1997
  term_t body = codom_leaves.data[leaf_i];
×
NEW
1998
  delete_ivector(&codom_leaves);
×
1999

NEW
2000
  return mk_lambda(&pre->tm, flat_n, flat_vars, body);
×
2001
}
2002

2003
term_t preprocessor_unblast_term(preprocessor_t* pre, term_t t) {
54✔
2004
  term_table_t* terms = pre->terms;
54✔
2005
  type_table_t* types = terms->types;
54✔
2006
  ivector_t vars, maps;
2007
  ivector_t leaves, accessors;
2008
  uint32_t i, j;
2009
  term_t out;
2010

2011
  if (pre->tuple_blast_atoms.size == 0) {
54✔
2012
    return t;
54✔
2013
  }
2014

NEW
2015
  init_ivector(&vars, 0);
×
NEW
2016
  init_ivector(&maps, 0);
×
NEW
2017
  init_ivector(&leaves, 0);
×
NEW
2018
  init_ivector(&accessors, 0);
×
2019

NEW
2020
  for (i = 0; i < pre->tuple_blast_atoms.size; ++i) {
×
NEW
2021
    term_t atom = pre->tuple_blast_atoms.data[i];
×
NEW
2022
    type_t atom_type = term_type(terms, atom);
×
NEW
2023
    tuple_blast_get(pre, atom, &leaves);
×
NEW
2024
    if (type_kind(types, atom_type) == TUPLE_TYPE) {
×
NEW
2025
      ivector_reset(&accessors);
×
NEW
2026
      collect_tuple_leaf_terms(pre, atom, atom_type, &accessors);
×
NEW
2027
      if (leaves.size != accessors.size) {
×
NEW
2028
        continue;
×
2029
      }
NEW
2030
      for (j = 0; j < leaves.size; ++j) {
×
NEW
2031
        term_t x = leaves.data[j];
×
NEW
2032
        term_t u = accessors.data[j];
×
NEW
2033
        term_kind_t k = term_kind(terms, x);
×
NEW
2034
        bool is_var = (k == UNINTERPRETED_TERM || k == VARIABLE);
×
NEW
2035
        if (x != u && is_var && !substitution_has_var(&vars, x)) {
×
NEW
2036
          ivector_push(&vars, x);
×
NEW
2037
          ivector_push(&maps, u);
×
2038
        }
2039
      }
NEW
2040
    } else if (type_kind(types, atom_type) == FUNCTION_TYPE) {
×
NEW
2041
      for (j = 0; j < leaves.size; ++j) {
×
NEW
2042
        term_t x = leaves.data[j];
×
NEW
2043
        term_kind_t k = term_kind(terms, x);
×
NEW
2044
        bool is_var = (k == UNINTERPRETED_TERM || k == VARIABLE);
×
NEW
2045
        if (is_var && !substitution_has_var(&vars, x)) {
×
NEW
2046
          term_t u = mk_unblasted_function_leaf_lambda(pre, atom, j, x);
×
NEW
2047
          ivector_push(&vars, x);
×
NEW
2048
          ivector_push(&maps, u);
×
2049
        }
2050
      }
2051
    }
2052
  }
2053

NEW
2054
  if (vars.size == 0) {
×
NEW
2055
    out = t;
×
2056
  } else {
2057
    term_subst_t subst;
NEW
2058
    init_term_subst(&subst, &pre->tm, vars.size, (term_t*) vars.data, (term_t*) maps.data);
×
NEW
2059
    out = apply_term_subst(&subst, t);
×
NEW
2060
    delete_term_subst(&subst);
×
2061
  }
2062

NEW
2063
  delete_ivector(&accessors);
×
NEW
2064
  delete_ivector(&leaves);
×
NEW
2065
  delete_ivector(&maps);
×
NEW
2066
  delete_ivector(&vars);
×
2067

NEW
2068
  return out;
×
2069
}
2070

2071
void preprocessor_build_model(preprocessor_t* pre, model_t* model) {
30✔
2072
  preprocessor_build_tuple_model(pre, model);
30✔
2073

2074
  uint32_t i = 0;
30✔
2075
  for (i = 0; i < pre->equalities_list.size; ++ i) {
33✔
2076
    term_t eq = pre->equalities_list.data[i];
3✔
2077
    term_t eq_var = preprocessor_get_eq_solved_var(pre, eq);
3✔
2078
    if (trace_enabled(pre->tracer, "mcsat::preprocess")) {
3✔
2079
      mcsat_trace_printf(pre->tracer, "eq = ");
×
2080
      trace_term_ln(pre->tracer, pre->terms, eq);
×
2081
      mcsat_trace_printf(pre->tracer, "\neq_var = ");
×
2082
      trace_term_ln(pre->tracer, pre->terms, eq_var);
×
2083
      mcsat_trace_printf(pre->tracer, "\n");
×
2084
    }
2085
    // Some equalities are solved, but then reasserted in the solver
2086
    // these already have a model
2087
    if (model_find_term_value(model, eq_var) != null_value) {
3✔
2088
      continue;
×
2089
    }
2090
    // Some equalities are marked, but not solved. These we skip as they
2091
    // are already set in the model
2092
    if (preprocessor_get(pre, eq_var) == eq_var) {
3✔
2093
      continue;
×
2094
    }
2095
    term_kind_t eq_kind = term_kind(pre->terms, eq);
3✔
2096
    composite_term_t* eq_desc = get_composite(pre->terms, eq_kind, eq);
3✔
2097
    if (eq_desc->arity > 1) {
3✔
2098
      term_t eq_subst = eq_desc->arg[0] == eq_var ? eq_desc->arg[1] : eq_desc->arg[0];
1✔
2099
      model_add_substitution(model, eq_var, eq_subst);
1✔
2100
    } else {
2101
      model_add_substitution(model, eq_var, zero_term);
2✔
2102
    }
2103
  }
2104
}
30✔
2105

2106

2107
static inline
2108
void preprocessor_gc_mark_term(preprocessor_t* pre, term_t t) {
2,152✔
2109
  term_table_set_gc_mark(pre->terms, index_of(t));
2,152✔
2110
  type_table_set_gc_mark(pre->terms->types, term_type(pre->terms, t));
2,152✔
2111
}
2,152✔
2112

2113
void preprocessor_gc_mark(preprocessor_t* pre) {
6✔
2114
  uint32_t i;
2115

2116
  for (i = 0; i < pre->preprocess_map_list.size; ++ i) {
620✔
2117
    term_t t = pre->preprocess_map_list.data[i];
614✔
2118
    preprocessor_gc_mark_term(pre, t);
614✔
2119
    term_t t_pre = preprocessor_get(pre, t);
614✔
2120
    preprocessor_gc_mark_term(pre, t_pre);
614✔
2121
  }
2122

2123
  for (i = 0; i < pre->equalities_list.size; ++ i) {
16✔
2124
    term_t t = pre->equalities_list.data[i];
10✔
2125
    preprocessor_gc_mark_term(pre, t);
10✔
2126
  }
2127

2128
  for (i = 0; i < pre->tuple_blast_list.size; ++i) {
444✔
2129
    term_t t = pre->tuple_blast_list.data[i];
438✔
2130
    int_hmap_pair_t* rec = int_hmap_find(&pre->tuple_blast_map, t);
438✔
2131
    uint32_t j, n, offset;
2132
    assert(rec != NULL);
2133
    preprocessor_gc_mark_term(pre, t);
438✔
2134
    offset = rec->val;
438✔
2135
    n = pre->tuple_blast_data.data[offset];
438✔
2136
    for (j = 0; j < n; ++j) {
876✔
2137
      preprocessor_gc_mark_term(pre, pre->tuple_blast_data.data[offset + 1 + j]);
438✔
2138
    }
2139
  }
2140

2141
  for (i = 0; i < pre->purification_map_list.size; ++ i) {
25✔
2142
    term_t t = pre->purification_map_list.data[i];
19✔
2143
    preprocessor_gc_mark_term(pre, t);
19✔
2144
    term_t t_pure = int_hmap_find(&pre->purification_map, t)->val;
19✔
2145
    preprocessor_gc_mark_term(pre, t_pure);
19✔
2146
  }
2147
}
6✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc