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

SRI-CSL / yices2 / 6277412324

22 Sep 2023 05:41PM UTC coverage: 64.973% (-0.01%) from 64.983%
6277412324

push

github

web-flow
MC-SAT Thread Safety (#456)

* Correct debug code.

* Avoid deadlocks in MC-SAT.

---------

Co-authored-by: Mark Mitchell <mark.mitchell@sri.com>

26 of 26 new or added lines in 7 files covered. (100.0%)

78998 of 121585 relevant lines covered (64.97%)

1324987.66 hits per line

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

89.15
/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/bvarith64_buffer_terms.h"
30
#include "terms/bvarith_buffer_terms.h"
31

32
#include "model/models.h"
33

34
#include "context/context_types.h"
35

36
#include "yices.h"
37
#include "api/yices_api_lock_free.h"
38

39
void preprocessor_construct(preprocessor_t* pre, term_table_t* terms, jmp_buf* handler, const mcsat_options_t* options) {
614✔
40
  pre->terms = terms;
614✔
41
  init_term_manager(&pre->tm, terms);
614✔
42
  init_int_hmap(&pre->preprocess_map, 0);
614✔
43
  init_ivector(&pre->preprocess_map_list, 0);
614✔
44
  init_int_hmap(&pre->purification_map, 0);
614✔
45
  init_ivector(&pre->purification_map_list, 0);
614✔
46
  init_ivector(&pre->preprocessing_stack, 0);
614✔
47
  init_int_hmap(&pre->equalities, 0);
614✔
48
  init_ivector(&pre->equalities_list, 0);
614✔
49
  pre->tracer = NULL;
614✔
50
  pre->exception = handler;
614✔
51
  pre->options = options;
614✔
52
  scope_holder_construct(&pre->scope);
614✔
53
}
614✔
54

55
void preprocessor_set_tracer(preprocessor_t* pre, tracer_t* tracer) {
281✔
56
  pre->tracer = tracer;
281✔
57
}
281✔
58

59
void preprocessor_destruct(preprocessor_t* pre) {
614✔
60
  delete_int_hmap(&pre->purification_map);
614✔
61
  delete_ivector(&pre->purification_map_list);
614✔
62
  delete_int_hmap(&pre->preprocess_map);
614✔
63
  delete_ivector(&pre->preprocess_map_list);
614✔
64
  delete_ivector(&pre->preprocessing_stack);
614✔
65
  delete_int_hmap(&pre->equalities);
614✔
66
  delete_ivector(&pre->equalities_list);
614✔
67
  delete_term_manager(&pre->tm);
614✔
68
  scope_holder_destruct(&pre->scope);
614✔
69
}
614✔
70

71
static
72
term_t preprocessor_get(preprocessor_t* pre, term_t t) {
1,558,486✔
73
  int_hmap_pair_t* find = int_hmap_find(&pre->preprocess_map, t);
1,558,486✔
74
  if (find == NULL) {
1,558,486✔
75
    return NULL_TERM;
844,780✔
76
  } else {
77
    return find->val;
713,706✔
78
  }
79
}
80

81
static
82
void preprocessor_set(preprocessor_t* pre, term_t t, term_t t_pre) {
327,234✔
83
  assert(preprocessor_get(pre, t) == NULL_TERM);
84
  int_hmap_add(&pre->preprocess_map, t, t_pre);
327,234✔
85
  ivector_push(&pre->preprocess_map_list, t);
327,234✔
86
}
327,234✔
87

88
typedef struct composite_term1_s {
89
  uint32_t arity;  // number of subterms
90
  term_t arg[1];  // real size = arity
91
} composite_term1_t;
92

93
static
94
composite_term1_t composite_for_noncomposite;
95

96
static
97
composite_term_t* get_composite(term_table_t* terms, term_kind_t kind, term_t t) {
198,843✔
98
  assert(term_is_composite(terms, t));
99
  assert(term_kind(terms, t) == kind);
100
  assert(is_pos_term(t));
101

102
  switch (kind) {
198,843✔
103
  case ITE_TERM:           // if-then-else
20,448✔
104
  case ITE_SPECIAL:        // special if-then-else term (NEW: EXPERIMENTAL)
105
    return ite_term_desc(terms, t);
20,448✔
106
  case EQ_TERM:            // equality
19,853✔
107
    return eq_term_desc(terms, t);
19,853✔
108
  case OR_TERM:            // n-ary OR
61,549✔
109
    return or_term_desc(terms, t);
61,549✔
110
  case XOR_TERM:           // n-ary XOR
30✔
111
    return xor_term_desc(terms, t);
30✔
112
  case ARITH_BINEQ_ATOM:   // equality: (t1 == t2)  (between two arithmetic terms)
3,242✔
113
    return arith_bineq_atom_desc(terms, t);
3,242✔
114
  case ARITH_EQ_ATOM: {
2,783✔
115
    composite_for_noncomposite.arity = 1;
2,783✔
116
    composite_for_noncomposite.arg[0] = arith_eq_arg(terms, t);
2,783✔
117
    return (composite_term_t*)&composite_for_noncomposite;
2,783✔
118
  }
119
  case ARITH_GE_ATOM: {
7,477✔
120
    composite_for_noncomposite.arity = 1;
7,477✔
121
    composite_for_noncomposite.arg[0] = arith_ge_arg(terms, t);
7,477✔
122
    return (composite_term_t*)&composite_for_noncomposite;
7,477✔
123
  }
124
  case APP_TERM:           // application of an uninterpreted function
3,600✔
125
    return app_term_desc(terms, t);
3,600✔
126
  case ARITH_RDIV:          // division: (/ x y)
58✔
127
    return arith_rdiv_term_desc(terms, t);
58✔
128
  case ARITH_IDIV:          // division: (div x y) as defined in SMT-LIB 2
34✔
129
    return arith_idiv_term_desc(terms, t);
34✔
130
  case ARITH_MOD:          // remainder: (mod x y) is y - x * (div x y)
117✔
131
    return arith_mod_term_desc(terms, t);
117✔
132
  case UPDATE_TERM:
873✔
133
    return update_term_desc(terms, t);
873✔
134
  case DISTINCT_TERM:
23✔
135
    return distinct_term_desc(terms, t);
23✔
136
  case BV_ARRAY:
17,508✔
137
    return bvarray_term_desc(terms, t);
17,508✔
138
  case BV_DIV:
93✔
139
    return bvdiv_term_desc(terms, t);
93✔
140
  case BV_REM:
212✔
141
    return bvrem_term_desc(terms, t);
212✔
142
  case BV_SDIV:
20✔
143
    return bvsdiv_term_desc(terms, t);
20✔
144
  case BV_SREM:
21✔
145
    return bvsrem_term_desc(terms, t);
21✔
146
  case BV_SMOD:
6✔
147
    return bvsmod_term_desc(terms, t);
6✔
148
  case BV_SHL:
143✔
149
    return bvshl_term_desc(terms, t);
143✔
150
  case BV_LSHR:
279✔
151
    return bvlshr_term_desc(terms, t);
279✔
152
  case BV_ASHR:
21✔
153
    return bvashr_term_desc(terms, t);
21✔
154
  case BV_EQ_ATOM:
57,036✔
155
    return bveq_atom_desc(terms, t);
57,036✔
156
  case BV_GE_ATOM:
2,775✔
157
    return bvge_atom_desc(terms, t);
2,775✔
158
  case BV_SGE_ATOM:
642✔
159
    return bvsge_atom_desc(terms, t);
642✔
160
  default:
×
161
    assert(false);
162
    return NULL;
×
163
  }
164
}
165

166
static
167
term_t mk_composite(preprocessor_t* pre, term_kind_t kind, uint32_t n, term_t* children) {
30,913✔
168
  term_manager_t* tm = &pre->tm;
30,913✔
169
  term_table_t* terms = pre->terms;
30,913✔
170

171
  switch (kind) {
30,913✔
172
  case ITE_TERM:           // if-then-else
12,687✔
173
  case ITE_SPECIAL:        // special if-then-else term (NEW: EXPERIMENTAL)
174
  {
175
    assert(n == 3);
176
    term_t type = super_type(pre->terms->types, term_type(terms, children[1]), term_type(terms, children[2]));
12,687✔
177
    assert(type != NULL_TYPE);
178
    return mk_ite(tm, children[0], children[1], children[2], type);
12,687✔
179
  }
180
  case EQ_TERM:            // equality
820✔
181
    assert(n == 2);
182
    return mk_eq(tm, children[0], children[1]);
820✔
183
  case OR_TERM:            // n-ary OR
3,062✔
184
    assert(n > 1);
185
    return mk_or(tm, n, children);
3,062✔
186
  case XOR_TERM:           // n-ary XOR
3✔
187
    return mk_xor(tm, n, children);
3✔
188
  case ARITH_EQ_ATOM:
40✔
189
    assert(n == 1);
190
    return mk_arith_eq(tm, children[0], zero_term);
40✔
191
  case ARITH_GE_ATOM:
363✔
192
    assert(n == 1);
193
    return mk_arith_geq(tm, children[0], zero_term);
363✔
194
  case ARITH_BINEQ_ATOM:   // equality: (t1 == t2)  (between two arithmetic terms)
196✔
195
    assert(n == 2);
196
    return mk_arith_eq(tm, children[0], children[1]);
196✔
197
  case APP_TERM:           // application of an uninterpreted function
663✔
198
    assert(n > 1);
199
    return mk_application(tm, children[0], n-1, children + 1);
663✔
200
  case ARITH_RDIV:
21✔
201
    assert(n == 2);
202
    return mk_arith_rdiv(tm, children[0], children[1]);
21✔
203
  case ARITH_IDIV:          // division: (div x y) as defined in SMT-LIB 2
6✔
204
    assert(n == 2);
205
    return mk_arith_idiv(tm, children[0], children[1]);
6✔
206
  case ARITH_MOD:          // remainder: (mod x y) is y - x * (div x y)
21✔
207
    assert(n == 2);
208
    return mk_arith_mod(tm, children[0], children[1]);
21✔
209
  case UPDATE_TERM:
279✔
210
    assert(n > 2);
211
    return mk_update(tm, children[0], n-2, children + 1, children[n-1]);
279✔
212
  case BV_ARRAY:
5,308✔
213
    assert(n >= 1);
214
    return mk_bvarray(tm, n, children);
5,308✔
215
  case BV_DIV:
63✔
216
    assert(n == 2);
217
    return mk_bvdiv(tm, children[0], children[1]);
63✔
218
  case BV_REM:
16✔
219
    assert(n == 2);
220
    return mk_bvrem(tm, children[0], children[1]);
16✔
221
  case BV_SDIV:
×
222
    assert(n == 2);
223
    return mk_bvsdiv(tm, children[0], children[1]);
×
224
  case BV_SREM:
×
225
    assert(n == 2);
226
    return mk_bvsrem(tm, children[0], children[1]);
×
227
  case BV_SMOD:
2✔
228
    assert(n == 2);
229
    return mk_bvsmod(tm, children[0], children[1]);
2✔
230
  case BV_SHL:
83✔
231
    assert(n == 2);
232
    return mk_bvshl(tm, children[0], children[1]);
83✔
233
  case BV_LSHR:
2✔
234
    assert(n == 2);
235
    return mk_bvlshr(tm, children[0], children[1]);
2✔
236
  case BV_ASHR:
3✔
237
    assert(n == 2);
238
    return mk_bvashr(tm, children[0], children[1]);
3✔
239
  case BV_EQ_ATOM:
5,826✔
240
    assert(n == 2);
241
    return mk_bveq(tm, children[0], children[1]);
5,826✔
242
  case BV_GE_ATOM:
1,298✔
243
    assert(n == 2);
244
    return mk_bvge(tm, children[0], children[1]);
1,298✔
245
  case BV_SGE_ATOM:
151✔
246
    assert(n == 2);
247
    return mk_bvsge(tm, children[0], children[1]);
151✔
248
  default:
×
249
    assert(false);
250
    return NULL_TERM;
×
251
  }
252
}
253

254
/**
255
 * Returns true if we should purify t as an argument of a function.
256
 * Any new equalities are added to output.
257
 */
258
static inline
259
term_t preprocessor_purify(preprocessor_t* pre, term_t t, ivector_t* out) {
9,559✔
260

261
  term_table_t* terms = pre->terms;
9,559✔
262

263
  // Negated terms must be purified
264
  if (is_pos_term(t)) {
9,559✔
265
    // We don't purify variables
266
    term_kind_t t_kind = term_kind(terms, t);
9,537✔
267
    switch (t_kind) {
9,537✔
268
    case UNINTERPRETED_TERM:
6,108✔
269
      // Variables are already pure
270
      return t;
6,108✔
271
    case CONSTANT_TERM:
8✔
272
      return t;
8✔
273
    case ARITH_CONSTANT:
1,171✔
274
    case BV64_CONSTANT:
275
    case BV_CONSTANT:
276
      // Constants are also pure (except for false)
277
      return t;
1,171✔
278
    case APP_TERM:
863✔
279
      // Uninterpreted functions are also already purified
280
      return t;
863✔
281
    case UPDATE_TERM:
529✔
282
      return t;
529✔
283
    default:
858✔
284
      break;
858✔
285
    }
286
  }
287

288
  // Everything else gets purified. Check if in the cache
289
  int_hmap_pair_t* find = int_hmap_find(&pre->purification_map, t);
880✔
290
  if (find != NULL) {
880✔
291
    return find->val;
653✔
292
  } else {
293
    // Make the variable
294
    type_t t_type = term_type(terms, t);
227✔
295
    term_t x = new_uninterpreted_term(terms, t_type);
227✔
296
    // Remember for later
297
    int_hmap_add(&pre->purification_map, t, x);
227✔
298
    ivector_push(&pre->purification_map_list, t);
227✔
299
    // Also add the variable to the pre-processor
300
    preprocessor_set(pre, x, x);
227✔
301
    // Add equality to output
302
    term_t eq = mk_eq(&pre->tm, x, t);
227✔
303
    ivector_push(out, eq);
227✔
304

305
    if (trace_enabled(pre->tracer, "mcsat::preprocess")) {
227✔
306
      mcsat_trace_printf(pre->tracer, "adding lemma = ");
×
307
      trace_term_ln(pre->tracer, terms, eq);
×
308
    }
309

310
    // Return the purified version
311
    return x;
227✔
312
  }
313
}
314

315
static inline
316
term_t mk_bvneg(term_manager_t* tm, term_t t) {
92✔
317
  term_table_t* terms = tm->terms;
92✔
318
  if (term_bitsize(terms,t) <= 64) {
92✔
319
    bvarith64_buffer_t *buffer = term_manager_get_bvarith64_buffer(tm);
76✔
320
    bvarith64_buffer_set_term(buffer, terms, t);
76✔
321
    bvarith64_buffer_negate(buffer);
76✔
322
    return mk_bvarith64_term(tm, buffer);
76✔
323
  } else {
324
    bvarith_buffer_t *buffer = term_manager_get_bvarith_buffer(tm);
16✔
325
    bvarith_buffer_set_term(buffer, terms, t);
16✔
326
    bvarith_buffer_negate(buffer);
16✔
327
    return mk_bvarith_term(tm, buffer);
16✔
328
  }
329
}
330

331
// Mark equality eq: (var = t) for solving
332
static
333
void preprocessor_mark_eq(preprocessor_t* pre, term_t eq, term_t var) {
24,807✔
334
  assert(is_pos_term(eq));
335
  assert(is_pos_term(var));
336
  assert(term_kind(pre->terms, var) == UNINTERPRETED_TERM);
337

338
  // Mark the equality
339
  int_hmap_pair_t* find = int_hmap_get(&pre->equalities, eq);
24,807✔
340
  assert(find->val == -1);
341
  find->val = var;
24,807✔
342
  ivector_push(&pre->equalities_list, eq);
24,807✔
343
}
24,807✔
344

345
static
346
term_t preprocessor_get_eq_solved_var(const preprocessor_t* pre, term_t eq) {
46,058✔
347
  assert(is_pos_term(eq));
348
  int_hmap_pair_t* find = int_hmap_find((int_hmap_t*) &pre->equalities, eq);
46,058✔
349
  if (find != NULL) {
46,058✔
350
    return find->val;
19,939✔
351
  } else {
352
    return NULL_TERM;
26,119✔
353
  }
354
}
355

356
term_t preprocessor_apply(preprocessor_t* pre, term_t t, ivector_t* out, bool is_assertion) {
38,188✔
357

358
  term_table_t* terms = pre->terms;
38,188✔
359
  term_manager_t* tm = &pre->tm;
38,188✔
360

361
  uint32_t i, j, n;
362

363
  // Check if already preprocessed;
364
  term_t t_pre = preprocessor_get(pre, t);
38,188✔
365
  if (t_pre != NULL_TERM) {
38,188✔
366
    return t_pre;
1,543✔
367
  }
368

369
// Note: negative affect on general performance due to solved/substituted
370
//       terms being to complex for explainers.
371
//
372
//  // First, if the assertion is a conjunction, just expand
373
//  if (is_assertion && is_neg_term(t) && term_kind(terms, t) == OR_TERM) {
374
//    // !(or t1 ... tn) -> !t1 && ... && !tn
375
//    composite_term_t* t_desc = composite_term_desc(terms, t);
376
//    for (i = 0; i < t_desc->arity; ++ i) {
377
//      ivector_push(out, opposite_term(t_desc->arg[i]));
378
//    }
379
//    return true_term;
380
//  }
381
//
382
  // Start
383
  ivector_t* pre_stack = &pre->preprocessing_stack;
36,645✔
384
  ivector_reset(pre_stack);
36,645✔
385
  ivector_push(pre_stack, t);
36,645✔
386

387
  // Preprocess
388
  while (pre_stack->size) {
489,786✔
389
    // Current term
390
    term_t current = ivector_last(pre_stack);
453,142✔
391

392
    if (trace_enabled(pre->tracer, "mcsat::preprocess")) {
453,142✔
393
      mcsat_trace_printf(pre->tracer, "current = ");
×
394
      trace_term_ln(pre->tracer, terms, current);
×
395
    }
396

397
    // If preprocessed already, done
398
    term_t current_pre = preprocessor_get(pre, current);
453,142✔
399
    if (current_pre != NULL_TERM) {
453,142✔
400
      ivector_pop(pre_stack);
30,863✔
401
      continue;
30,863✔
402
    }
403

404
    // Negation
405
    if (is_neg_term(current)) {
422,279✔
406
      term_t child = unsigned_term(current);
86,791✔
407
      term_t child_pre = preprocessor_get(pre, child);
86,791✔
408
      if (child_pre == NULL_TERM) {
86,791✔
409
        ivector_push(pre_stack, child);
41,007✔
410
        continue;
41,007✔
411
      } else {
412
        ivector_pop(pre_stack);
45,784✔
413
        current_pre = opposite_term(child_pre);
45,784✔
414
        preprocessor_set(pre, current, current_pre);
45,784✔
415
        continue;
45,784✔
416
      }
417
    }
418

419
    // Check for supported types
420
    type_kind_t type = term_type_kind(terms, current);
335,488✔
421
    switch (type) {
335,488✔
422
    case BOOL_TYPE:
335,488✔
423
    case INT_TYPE:
424
    case REAL_TYPE:
425
    case UNINTERPRETED_TYPE:
426
    case FUNCTION_TYPE:
427
    case BITVECTOR_TYPE:
428
    case SCALAR_TYPE:
429
      break;
335,488✔
430
    default:
×
431
      longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
×
432
    }
433

434
    // Kind of term
435
    term_kind_t current_kind = term_kind(terms, current);
335,488✔
436

437
    switch(current_kind) {
335,488✔
438
    case CONSTANT_TERM:    // constant of uninterpreted/scalar/boolean types
1,643✔
439
    case BV64_CONSTANT:    // compact bitvector constant (64 bits at most)
440
    case BV_CONSTANT:      // generic bitvector constant (more than 64 bits)
441
    case ARITH_CONSTANT:   // rational constant
442
      current_pre = current;
1,643✔
443
      break;
1,643✔
444
    case UNINTERPRETED_TERM:  // (i.e., global variables, can't be bound).
12,533✔
445
      current_pre = current;
12,533✔
446
      // Unless we want special slicing
447
      if (type == BITVECTOR_TYPE) {
12,533✔
448
        if (pre->options->bv_var_size > 0) {
4,233✔
449
          uint32_t size = term_bitsize(terms, current);
×
450
          uint32_t var_size = pre->options->bv_var_size;
×
451
          if (size > var_size) {
×
452
            uint32_t n_vars = (size - 1) / var_size + 1;
×
453
            term_t vars[n_vars];
×
454
            for (i = n_vars - 1; size > 0; i--) {
×
455
              if (size >= var_size) {
×
456
                vars[i] = new_uninterpreted_term(terms, bv_type(terms->types, var_size));
×
457
                size -= var_size;
×
458
              } else {
459
                vars[i] = new_uninterpreted_term(terms, bv_type(terms->types, size));
×
460
                size = 0;
×
461
              }
462
            }
463
            current_pre = _o_yices_bvconcat(n_vars, vars);
×
464
            term_t eq = _o_yices_eq(current, current_pre);
×
465
            preprocessor_mark_eq(pre, eq, current);
×
466
          }
467
        }
468
      }
469
      break;
12,533✔
470

471
    case ITE_TERM:           // if-then-else
194,095✔
472
    case ITE_SPECIAL:        // special if-then-else term (NEW: EXPERIMENTAL)
473
    case EQ_TERM:            // equality
474
    case OR_TERM:            // n-ary OR
475
    case XOR_TERM:           // n-ary XOR
476
    case ARITH_EQ_ATOM:      // equality (t == 0)
477
    case ARITH_BINEQ_ATOM:   // equality: (t1 == t2)  (between two arithmetic terms)
478
    case ARITH_GE_ATOM:      // inequality (t >= 0)
479
    case BV_ARRAY:
480
    case BV_DIV:
481
    case BV_REM:
482
    case BV_SMOD:
483
    case BV_SHL:
484
    case BV_LSHR:
485
    case BV_ASHR:
486
    case BV_EQ_ATOM:
487
    case BV_GE_ATOM:
488
    case BV_SGE_ATOM:
489
    {
490
      composite_term_t* desc = get_composite(terms, current_kind, current);
194,095✔
491
      bool children_done = true;
194,095✔
492
      bool children_same = true;
194,095✔
493

494
      n = desc->arity;
194,095✔
495

496
      /*
497
      // Arrays not supported yet
498
      if (current_kind == EQ_TERM && term_type_kind(terms, desc->arg[0]) == FUNCTION_TYPE) {
499
        longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
500
      }
501
      */
502
 
503
      // Is this a top-level equality assertion
504
      bool is_equality =
194,095✔
505
          current_kind == EQ_TERM ||
174,242✔
506
          current_kind == BV_EQ_ATOM ||
117,206✔
507
          current_kind == ARITH_BINEQ_ATOM ||
368,337✔
508
          current_kind == ARITH_EQ_ATOM;
509
      // don't rewrite if the equality is between Boolean terms
510
      bool is_boolean = is_boolean_type(term_type(pre->terms, desc->arg[0]));
194,095✔
511

512
      term_t eq_solve_var = NULL_TERM;
194,095✔
513
      if (is_assertion && is_equality && !is_boolean) {
194,095✔
514
        if (current == t) {
68,854✔
515
          eq_solve_var = preprocessor_get_eq_solved_var(pre, t);
46,056✔
516
          if (eq_solve_var == NULL_TERM) {
46,056✔
517
            term_t lhs = desc->arg[0];
26,119✔
518
            term_kind_t lhs_kind = term_kind(terms, lhs);
26,119✔
519
            // If lhs/rhs is a first-time seen variable, we can solve it
520
            bool lhs_is_var = lhs_kind == UNINTERPRETED_TERM && is_pos_term(lhs);
26,119✔
521
            if (lhs_is_var && preprocessor_get(pre, lhs) == NULL_TERM) {
26,119✔
522
              // First time variable, let's solve
523
              preprocessor_mark_eq(pre, t, lhs);
24,554✔
524
              eq_solve_var = lhs;
24,554✔
525
            } else if (desc->arity > 1) {
1,565✔
526
              term_t rhs = desc->arg[1];
1,211✔
527
              term_kind_t rhs_kind = term_kind(terms, rhs);
1,211✔
528
              bool rhs_is_var = rhs_kind == UNINTERPRETED_TERM && is_pos_term(rhs);
1,211✔
529
              if (rhs_is_var && preprocessor_get(pre, rhs) == NULL_TERM) {
1,211✔
530
                // First time variable, let's solve
531
                preprocessor_mark_eq(pre, t, rhs);
253✔
532
                eq_solve_var = rhs;
253✔
533
              }
534
            }
535
          } else {
536
            // Check that we it's not there already
537
            if (preprocessor_get(pre, eq_solve_var) != NULL_TERM) {
19,937✔
538
              eq_solve_var = NULL_TERM;
51✔
539
            }
540
          }
541
        }
542
      }
543

544
      ivector_t children;
545
      init_ivector(&children, n);
194,095✔
546

547
      for (i = 0; i < n; ++ i) {
944,576✔
548
        term_t child = desc->arg[i];
750,481✔
549
        if (child != eq_solve_var) {
750,481✔
550
          term_t child_pre = preprocessor_get(pre, child);
705,788✔
551
          if (child_pre == NULL_TERM) {
705,788✔
552
            children_done = false;
248,311✔
553
            ivector_push(pre_stack, child);
248,311✔
554
          } else if (child_pre != child) {
457,477✔
555
            children_same = false;
136,215✔
556
          }
557
          if (children_done) {
705,788✔
558
            ivector_push(&children, child_pre);
430,750✔
559
          }
560
        }
561
      }
562

563
      if (eq_solve_var != NULL_TERM) {
194,095✔
564
        // Check again to make sure we don't have something like x = x + 1
565
        if (preprocessor_get(pre, eq_solve_var) != NULL_TERM) {
44,693✔
566
          // Do it again
567
          children_done = false;
×
568
        }
569
      }
570

571
      if (children_done) {
194,095✔
572
        if (eq_solve_var != NULL_TERM) {
120,058✔
573
          term_t eq_solve_term = zero_term;
24,756✔
574
          if (children.size > 0) {
24,756✔
575
            eq_solve_term = children.data[0];
24,726✔
576
          }
577
          preprocessor_set(pre, eq_solve_var, eq_solve_term);
24,756✔
578
          current_pre = true_term;
24,756✔
579
        } else {
580
          if (children_same) {
95,302✔
581
            current_pre = current;
65,379✔
582
          } else {
583
            current_pre = mk_composite(pre, current_kind, n, children.data);
29,923✔
584
          }
585
        }
586
      }
587

588
      delete_ivector(&children);
194,095✔
589

590
      break;
194,095✔
591
    }
592

593
    case ARITH_ABS:
4✔
594
    {
595
      term_t arg = arith_abs_arg(terms, current);
4✔
596
      term_t arg_pre = preprocessor_get(pre, arg);
4✔
597
      if (arg_pre == NULL_TERM) {
4✔
598
        ivector_push(pre_stack, arg);
1✔
599
      } else {
600
        type_t arg_pre_type = term_type(pre->terms, arg_pre);
3✔
601
        term_t arg_pre_is_positive = mk_arith_term_geq0(&pre->tm, arg_pre);
3✔
602
        term_t arg_negative = _o_yices_neg(arg_pre);
3✔
603
        current_pre = mk_ite(&pre->tm, arg_pre_is_positive, arg_pre, arg_negative, arg_pre_type);
3✔
604
      }
605
      break;
4✔
606
    }
607

608
    case BV_SDIV:
20✔
609
    {
610
      composite_term_t* desc = get_composite(terms, current_kind, current);
20✔
611
      assert(desc->arity == 2);
612
      term_t s = desc->arg[0];
20✔
613
      term_t s_pre = preprocessor_get(pre, s);
20✔
614
      if (s_pre == NULL_TERM) {
20✔
615
        ivector_push(pre_stack, s);
7✔
616
      }
617
      term_t t = desc->arg[1];
20✔
618
      term_t t_pre = preprocessor_get(pre, t);
20✔
619
      if (t_pre == NULL_TERM) {
20✔
620
        ivector_push(pre_stack, t);
5✔
621
      }
622
      if (s_pre != NULL_TERM && t_pre != NULL_TERM) {
20✔
623
        type_t tau = term_type(terms, s_pre);
11✔
624
        uint32_t n = term_bitsize(terms, s_pre);
11✔
625
        term_t msb_s = mk_bitextract(tm, s_pre, n-1);
11✔
626
        term_t msb_t = mk_bitextract(tm, t_pre, n-1);
11✔
627
        // if (msb_s) {
628
        //   if (msb_t) {
629
        //     t1: udiv(-s, -t)
630
        //   } else {
631
        //     t2: -udiv(-s, t)
632
        //   }
633
        // } else {
634
        //   if (msb_t) {
635
        //     t3: -udiv(s, -t)
636
        //   } else {
637
        //     t4: udiv(s, t)
638
        //   }
639
        // }
640
        term_t neg_s = mk_bvneg(tm, s_pre);
11✔
641
        term_t neg_t = mk_bvneg(tm, t_pre);
11✔
642

643
        term_t t1 = mk_bvdiv(tm, neg_s, neg_t);
11✔
644
        term_t t2 = mk_bvdiv(tm, neg_s, t_pre);
11✔
645
        t2 = mk_bvneg(&pre->tm, t2);
11✔
646
        term_t t3 = mk_bvdiv(tm, s_pre, neg_t);
11✔
647
        t3 = mk_bvneg(&pre->tm, t3);
11✔
648
        term_t t4 = mk_bvdiv(tm, s_pre, t_pre);
11✔
649

650
        term_t b1 = mk_ite(tm, msb_t, t1, t2, tau);
11✔
651
        term_t b2 = mk_ite(tm, msb_t, t3, t4, tau);
11✔
652

653
        current_pre = mk_ite(tm, msb_s, b1, b2, tau);
11✔
654
      }
655
      break;
20✔
656
    }
657
    case BV_SREM:
21✔
658
    {
659
      composite_term_t* desc = get_composite(terms, current_kind, current);
21✔
660
      assert(desc->arity == 2);
661
      term_t s = desc->arg[0];
21✔
662
      term_t s_pre = preprocessor_get(pre, s);
21✔
663
      if (s_pre == NULL_TERM) {
21✔
664
        ivector_push(pre_stack, s);
8✔
665
      }
666
      term_t t = desc->arg[1];
21✔
667
      term_t t_pre = preprocessor_get(pre, t);
21✔
668
      if (t_pre == NULL_TERM) {
21✔
669
        ivector_push(pre_stack, t);
3✔
670
      }
671
      if (s_pre != NULL_TERM && t_pre != NULL_TERM) {
21✔
672
        type_t tau = term_type(terms, s_pre);
12✔
673
        uint32_t n = term_bitsize(terms, s_pre);
12✔
674
        term_t msb_s = mk_bitextract(tm, s_pre, n-1);
12✔
675
        term_t msb_t = mk_bitextract(tm, t_pre, n-1);
12✔
676
        // if (msb_s) {
677
        //   if (msb_t) {
678
        //     t1: -urem(-s, -t)
679
        //   } else {
680
        //     t2: -urem(-s, t)
681
        //   }
682
        // } else {
683
        //   if (msb_t) {
684
        //     t3: -urem(s, -t)
685
        //   } else {
686
        //     t4: urem(s, t)
687
        //   }
688
        // }
689
        term_t neg_s = mk_bvneg(tm, s_pre);
12✔
690
        term_t neg_t = mk_bvneg(tm, t_pre);
12✔
691

692
        term_t t1 = mk_bvrem(tm, neg_s, neg_t);
12✔
693
        t1 = mk_bvneg(tm, t1);
12✔
694
        term_t t2 = mk_bvrem(tm, neg_s, t_pre);
12✔
695
        t2 = mk_bvneg(tm, t2);
12✔
696
        term_t t3 = mk_bvrem(tm, s_pre, neg_t);
12✔
697
        term_t t4 = mk_bvrem(tm, s_pre, t_pre);
12✔
698

699
        term_t b1 = mk_ite(tm, msb_t, t1, t2, tau);
12✔
700
        term_t b2 = mk_ite(tm, msb_t, t3, t4, tau);
12✔
701

702
        current_pre = mk_ite(tm, msb_s, b1, b2, tau);
12✔
703
      }
704
      break;
21✔
705
    }
706
    case BIT_TERM: // bit-select current = child[i]
112,739✔
707
    {
708
      uint32_t index = bit_term_index(terms, current);
112,739✔
709
      term_t arg = bit_term_arg(terms, current);
112,739✔
710
      term_t arg_pre = preprocessor_get(pre, arg);
112,739✔
711
      if (arg_pre == NULL_TERM) {
112,739✔
712
        ivector_push(pre_stack, arg);
1,583✔
713
      } else {
714
        if (arg_pre == arg) {
111,156✔
715
          current_pre = current;
80,339✔
716
        } else {
717
          if (trace_enabled(pre->tracer, "mcsat::preprocess")) {
30,817✔
718
            mcsat_trace_printf(pre->tracer, "arg_pre = ");
×
719
            trace_term_ln(pre->tracer, terms, arg_pre);
×
720
          }
721
          // For simplification purposes use API
722
          current_pre = _o_yices_bitextract(arg_pre, index);
30,817✔
723
          assert(current_pre != NULL_TERM);
724
        }
725
      }
726
      break;
112,739✔
727
    }
728
    case BV_POLY:  // polynomial with generic bitvector coefficients
33✔
729
    {
730
      bvpoly_t* p = bvpoly_term_desc(terms, current);
33✔
731

732
      bool children_done = true;
33✔
733
      bool children_same = true;
33✔
734

735
      n = p->nterms;
33✔
736

737
      ivector_t children;
738
      init_ivector(&children, n);
33✔
739

740
      for (i = 0; i < n; ++ i) {
84✔
741
        term_t x = p->mono[i].var;
51✔
742
        term_t x_pre = (x == const_idx ? const_idx : preprocessor_get(pre, x));
51✔
743

744
        if (x_pre != const_idx) {
51✔
745
          if (x_pre == NULL_TERM) {
47✔
746
            children_done = false;
10✔
747
            ivector_push(pre_stack, x);
10✔
748
          } else if (x_pre != x) {
37✔
749
            children_same = false;
23✔
750
          }
751
        }
752

753
        if (children_done) { ivector_push(&children, x_pre); }
51✔
754
      }
755

756
      if (children_done) {
33✔
757
        if (children_same) {
26✔
758
          current_pre = current;
11✔
759
        } else {
760
          current_pre = mk_bvarith_poly(tm, p, n, children.data);
15✔
761
        }
762
      }
763

764
      delete_ivector(&children);
33✔
765

766
      break;
33✔
767
    }
768
    case BV64_POLY: // polynomial with 64bit coefficients
2,571✔
769
    {
770
      bvpoly64_t* p = bvpoly64_term_desc(terms, current);
2,571✔
771

772
      bool children_done = true;
2,571✔
773
      bool children_same = true;
2,571✔
774

775
      n = p->nterms;
2,571✔
776

777
      ivector_t children;
778
      init_ivector(&children, n);
2,571✔
779

780
      for (i = 0; i < n; ++ i) {
9,821✔
781
        term_t x = p->mono[i].var;
7,250✔
782
        term_t x_pre = (x == const_idx ? const_idx : preprocessor_get(pre, x));
7,250✔
783

784
        if (x_pre != const_idx) {
7,250✔
785
          if (x_pre == NULL_TERM) {
5,578✔
786
            children_done = false;
1,308✔
787
            ivector_push(pre_stack, x);
1,308✔
788
          } else if (x_pre != x) {
4,270✔
789
            children_same = false;
665✔
790
          }
791
        }
792

793
        if (children_done) { ivector_push(&children, x_pre); }
7,250✔
794
      }
795

796
      if (children_done) {
2,571✔
797
        if (children_same) {
1,870✔
798
          current_pre = current;
1,270✔
799
        } else {
800
          current_pre = mk_bvarith64_poly(tm, p, n, children.data);
600✔
801
        }
802
      }
803

804
      delete_ivector(&children);
2,571✔
805

806
      break;
2,571✔
807
    }
808

809
    case POWER_PRODUCT:    // power products: (t1^d1 * ... * t_n^d_n)
1,161✔
810
    {
811
      pprod_t* pp = pprod_term_desc(terms, current);
1,161✔
812
      bool children_done = true;
1,161✔
813
      bool children_same = true;
1,161✔
814

815
      n = pp->len;
1,161✔
816

817
      ivector_t children;
818
      init_ivector(&children, n);
1,161✔
819

820
      for (i = 0; i < n; ++ i) {
3,766✔
821
        term_t x = pp->prod[i].var;
2,605✔
822
        term_t x_pre = preprocessor_get(pre, x);
2,605✔
823

824
        if (x_pre == NULL_TERM) {
2,605✔
825
          children_done = false;
327✔
826
          ivector_push(pre_stack, x);
327✔
827
        } else if (x_pre != x) {
2,278✔
828
          children_same = false;
40✔
829
        }
830

831
        if (children_done) { ivector_push(&children, x_pre); }
2,605✔
832
      }
833

834
      if (children_done) {
1,161✔
835
        if (children_same) {
919✔
836
          current_pre = current;
894✔
837
        } else {
838
          // NOTE: it doens't change pp, it just uses it as a frame
839
          current_pre = mk_pprod(tm, pp, n, children.data);
25✔
840
        }
841
      }
842

843
      delete_ivector(&children);
1,161✔
844

845
      break;
1,161✔
846
    }
847

848
    case ARITH_POLY:       // polynomial with rational coefficients
5,956✔
849
    {
850
      polynomial_t* p = poly_term_desc(terms, current);
5,956✔
851

852
      bool children_done = true;
5,956✔
853
      bool children_same = true;
5,956✔
854

855
      n = p->nterms;
5,956✔
856

857
      ivector_t children;
858
      init_ivector(&children, n);
5,956✔
859

860
      for (i = 0; i < n; ++ i) {
23,284✔
861
        term_t x = p->mono[i].var;
17,328✔
862
        term_t x_pre = (x == const_idx ? const_idx : preprocessor_get(pre, x));
17,328✔
863

864
        if (x_pre != const_idx) {
17,328✔
865
          if (x_pre == NULL_TERM) {
14,912✔
866
            children_done = false;
2,049✔
867
            ivector_push(pre_stack, x);
2,049✔
868
          } else if (x_pre != x) {
12,863✔
869
            children_same = false;
725✔
870
          }
871
        }
872

873
        if (children_done) { ivector_push(&children, x_pre); }
17,328✔
874
      }
875

876
      if (children_done) {
5,956✔
877
        if (children_same) {
4,876✔
878
          current_pre = current;
4,393✔
879
        } else {
880
          current_pre = mk_arith_poly(tm, p, n, children.data);
483✔
881
        }
882
      }
883

884
      delete_ivector(&children);
5,956✔
885

886
      break;
5,956✔
887
    }
888

889
    // FOLLOWING ARE UNINTEPRETED, SO WE PURIFY THE ARGUMENTS
890

891
    case APP_TERM:           // application of an uninterpreted function
4,682✔
892
    case ARITH_RDIV:         // regular division (/ x y)
893
    case ARITH_IDIV:         // division: (div x y) as defined in SMT-LIB 2
894
    case ARITH_MOD:          // remainder: (mod x y) is y - x * (div x y)
895
    case UPDATE_TERM:        // update array
896
    {
897
      composite_term_t* desc = get_composite(terms, current_kind, current);
4,682✔
898
      bool children_done = true;
4,682✔
899
      bool children_same = true;
4,682✔
900

901
      n = desc->arity;
4,682✔
902

903
      ivector_t children;
904
      init_ivector(&children, n);
4,682✔
905

906
      for (i = 0; i < n; ++ i) {
16,048✔
907
        term_t child = desc->arg[i];
11,366✔
908
        term_t child_pre = preprocessor_get(pre, child);
11,366✔
909

910
        if (child_pre == NULL_TERM) {
11,366✔
911
          children_done = false;
1,810✔
912
          ivector_push(pre_stack, child);
1,810✔
913
        } else {
914
          // Purify if needed
915
          child_pre = preprocessor_purify(pre, child_pre, out);
9,556✔
916
          // If interpreted terms, we need to purify non-variables
917
          if (child_pre != child) { children_same = false; }
9,556✔
918
        }
919

920
        if (children_done) { ivector_push(&children, child_pre); }
11,366✔
921
      }
922

923
      if (children_done) {
4,682✔
924
        if (children_same) {
3,343✔
925
          current_pre = current;
2,353✔
926
        } else {
927
          current_pre = mk_composite(pre, current_kind, n, children.data);
990✔
928
        }
929
      }
930

931
      delete_ivector(&children);
4,682✔
932

933
      break;
4,682✔
934
    }
935

936
    case ARITH_IS_INT_ATOM:
×
937
    {
938
      // replace with t <= floor(t)
939
      term_t child = arith_is_int_arg(terms, current);
×
940
      term_t child_pre = preprocessor_get(pre, child);
×
941
      if (child_pre != NULL_TERM) {
×
942
        child_pre = preprocessor_purify(pre, child_pre, out);
×
943
        current_pre = arith_floor(terms, child_pre);
×
944
        current_pre = mk_arith_leq(tm, child_pre, current_pre);
×
945
      } else {
946
        ivector_push(pre_stack, child);
×
947
      }
948
      break;
×
949
    }
950

951
    case ARITH_FLOOR:        // floor: purify, but its interpreted
7✔
952
    {
953
      term_t child = arith_floor_arg(terms, current);
7✔
954
      term_t child_pre = preprocessor_get(pre, child);
7✔
955

956
      if (child_pre != NULL_TERM) {
7✔
957
        if (term_kind(terms, child_pre) == ARITH_CONSTANT) {
4✔
958
          rational_t floor;
959
          q_init(&floor);
1✔
960
          q_set(&floor, rational_term_desc(terms, child_pre));
1✔
961
          q_floor(&floor);
1✔
962
          current_pre = arith_constant(terms, &floor);
1✔
963
          q_clear(&floor);
1✔
964
        } else {
965
          child_pre = preprocessor_purify(pre, child_pre, out);
3✔
966
          if (child_pre != child) {
3✔
967
            current_pre = arith_floor(terms, child_pre);
1✔
968
          } else {
969
            current_pre = current;
2✔
970
          }
971
        }
972
      } else {
973
        ivector_push(pre_stack, child);
3✔
974
      }
975

976
      break;
7✔
977
    }
978

979
    case ARITH_CEIL:        // floor: purify, but its interpreted
×
980
    {
981
      term_t child = arith_ceil_arg(terms, current);
×
982
      term_t child_pre = preprocessor_get(pre, child);
×
983

984
      if (child_pre != NULL_TERM) {
×
985
        child_pre = preprocessor_purify(pre, child_pre, out);
×
986
        if (child_pre != child) {
×
987
          current_pre = arith_floor(terms, child_pre);
×
988
        } else {
989
          current_pre = current;
×
990
        }
991
      } else {
992
        ivector_push(pre_stack, child);
×
993
      }
994

995
      break;
×
996
    }
997

998
    case DISTINCT_TERM:
23✔
999
    {
1000
      composite_term_t* desc = get_composite(terms, current_kind, current);
23✔
1001

1002
      // Arrays not supported yet
1003
      if (term_type_kind(terms, desc->arg[0]) == FUNCTION_TYPE) {
23✔
1004
        longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
1✔
1005
      }
1006

1007
      bool children_done = true;
22✔
1008
      n = desc->arity;
22✔
1009

1010
      ivector_t children;
1011
      init_ivector(&children, n);
22✔
1012

1013
      for (i = 0; i < n; ++ i) {
114✔
1014
        term_t child = desc->arg[i];
92✔
1015
        term_t child_pre = preprocessor_get(pre, child);
92✔
1016

1017
        if (child_pre == NULL_TERM) {
92✔
1018
          children_done = false;
38✔
1019
          ivector_push(pre_stack, child);
38✔
1020
        }
1021

1022
        if (children_done) { ivector_push(&children, child_pre); }
92✔
1023
      }
1024

1025
      if (children_done) {
22✔
1026
        ivector_t distinct;
1027
        init_ivector(&distinct, 0);
13✔
1028

1029
        for (i = 0; i < n; ++ i) {
66✔
1030
          for (j = i + 1; j < n; ++ j) {
142✔
1031
            term_t neq = mk_eq(&pre->tm, children.data[i], children.data[j]);
89✔
1032
            neq = opposite_term(neq);
89✔
1033
            ivector_push(&distinct, neq);
89✔
1034
          }
1035
        }
1036
        current_pre = mk_and(&pre->tm, distinct.size, distinct.data);
13✔
1037

1038
        delete_ivector(&distinct);
13✔
1039
      }
1040

1041
      delete_ivector(&children);
22✔
1042

1043
      break;
22✔
1044
    }
1045

1046
    default:
×
1047
      // UNSUPPORTED TERM/THEORY
1048
      longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
×
1049
      break;
1050
    }
1051

1052
    if (current_pre != NULL_TERM) {
335,487✔
1053
      preprocessor_set(pre, current, current_pre);
256,467✔
1054
      ivector_pop(pre_stack);
256,467✔
1055
      if (trace_enabled(pre->tracer, "mcsat::preprocess")) {
256,467✔
1056
        mcsat_trace_printf(pre->tracer, "current_pre = ");
×
1057
        trace_term_ln(pre->tracer, terms, current_pre);
×
1058
      }
1059
    }
1060

1061
  }
1062

1063
  // Return the result
1064
  t_pre = preprocessor_get(pre, t);
36,644✔
1065
  if (trace_enabled(pre->tracer, "mcsat::preprocess")) {
36,644✔
1066
    mcsat_trace_printf(pre->tracer, "t_pre = ");
×
1067
    trace_term_ln(pre->tracer, terms, t_pre);
×
1068
  }
1069

1070
  ivector_reset(pre_stack);
36,644✔
1071

1072
  assert(t_pre != NULL_TERM);
1073
  return t_pre;
36,644✔
1074
}
1075

1076
void preprocessor_set_exception_handler(preprocessor_t* pre, jmp_buf* handler) {
×
1077
  pre->exception = handler;
×
1078
}
×
1079

1080
void preprocessor_push(preprocessor_t* pre) {
293✔
1081
  scope_holder_push(&pre->scope,
293✔
1082
      &pre->preprocess_map_list.size,
1083
      &pre->purification_map_list.size,
1084
      &pre->equalities_list.size,
1085
      NULL);
1086
}
293✔
1087

1088
void preprocessor_pop(preprocessor_t* pre) {
235✔
1089

1090
  uint32_t preprocess_map_list_size = 0;
235✔
1091
  uint32_t purification_map_list_size = 0;
235✔
1092
  uint32_t equalities_list_size = 0;
235✔
1093

1094
  scope_holder_pop(&pre->scope,
235✔
1095
      &preprocess_map_list_size,
1096
      &purification_map_list_size,
1097
      &equalities_list_size,
1098
      NULL);
1099

1100
  while (pre->preprocess_map_list.size > preprocess_map_list_size) {
6,678✔
1101
    term_t t = ivector_last(&pre->preprocess_map_list);
6,443✔
1102
    ivector_pop(&pre->preprocess_map_list);
6,443✔
1103
    int_hmap_pair_t* find = int_hmap_find(&pre->preprocess_map, t);
6,443✔
1104
    assert(find != NULL);
1105
    int_hmap_erase(&pre->preprocess_map, find);
6,443✔
1106
  }
1107

1108
  while (pre->purification_map_list.size > purification_map_list_size) {
277✔
1109
    term_t t = ivector_last(&pre->purification_map_list);
42✔
1110
    ivector_pop(&pre->purification_map_list);
42✔
1111
    int_hmap_pair_t* find = int_hmap_find(&pre->purification_map, t);
42✔
1112
    assert(find != NULL);
1113
    int_hmap_erase(&pre->purification_map, find);
42✔
1114
  }
1115

1116
  while (pre->equalities_list.size > equalities_list_size) {
253✔
1117
    term_t eq = ivector_last(&pre->equalities_list);
18✔
1118
    ivector_pop(&pre->equalities_list);
18✔
1119
    int_hmap_pair_t* find = int_hmap_find(&pre->equalities, eq);
18✔
1120
    assert(find != NULL);
1121
    int_hmap_erase(&pre->equalities, find);
18✔
1122
  }
1123
}
235✔
1124

1125
void preprocessor_build_model(preprocessor_t* pre, model_t* model) {
23✔
1126
  uint32_t i = 0;
23✔
1127
  for (i = 0; i < pre->equalities_list.size; ++ i) {
25✔
1128
    term_t eq = pre->equalities_list.data[i];
2✔
1129
    term_t eq_var = preprocessor_get_eq_solved_var(pre, eq);
2✔
1130
    if (trace_enabled(pre->tracer, "mcsat::preprocess")) {
2✔
1131
      mcsat_trace_printf(pre->tracer, "eq = ");
×
1132
      trace_term_ln(pre->tracer, pre->terms, eq);
×
1133
      mcsat_trace_printf(pre->tracer, "\neq_var = ");
×
1134
      trace_term_ln(pre->tracer, pre->terms, eq_var);
×
1135
      mcsat_trace_printf(pre->tracer, "\n");
×
1136
    }
1137
    // Some equalities are solved, but then reasserted in the solver
1138
    // these already have a model
1139
    if (model_find_term_value(model, eq_var) != null_value) {
2✔
1140
      continue;
×
1141
    }
1142
    // Some equalities are marked, but not solved. These we skip as they
1143
    // are already set in the model
1144
    if (preprocessor_get(pre, eq_var) == eq_var) {
2✔
1145
      continue;
×
1146
    }
1147
    term_kind_t eq_kind = term_kind(pre->terms, eq);
2✔
1148
    composite_term_t* eq_desc = get_composite(pre->terms, eq_kind, eq);
2✔
1149
    if (eq_desc->arity > 1) {
2✔
1150
      term_t eq_subst = eq_desc->arg[0] == eq_var ? eq_desc->arg[1] : eq_desc->arg[0];
×
1151
      model_add_substitution(model, eq_var, eq_subst);
×
1152
    } else {
1153
      model_add_substitution(model, eq_var, zero_term);
2✔
1154
    }
1155
  }
1156
}
23✔
1157

1158

1159
static inline
1160
void preprocessor_gc_mark_term(preprocessor_t* pre, term_t t) {
1,000✔
1161
  term_table_set_gc_mark(pre->terms, index_of(t));
1,000✔
1162
  type_table_set_gc_mark(pre->terms->types, term_type(pre->terms, t));
1,000✔
1163
}
1,000✔
1164

1165
void preprocessor_gc_mark(preprocessor_t* pre) {
5✔
1166
  uint32_t i;
1167

1168
  for (i = 0; i < pre->preprocess_map_list.size; ++ i) {
486✔
1169
    term_t t = pre->preprocess_map_list.data[i];
481✔
1170
    preprocessor_gc_mark_term(pre, t);
481✔
1171
    term_t t_pre = preprocessor_get(pre, t);
481✔
1172
    preprocessor_gc_mark_term(pre, t_pre);
481✔
1173
  }
1174

1175
  for (i = 0; i < pre->equalities_list.size; ++ i) {
5✔
1176
    term_t t = pre->equalities_list.data[i];
×
1177
    preprocessor_gc_mark_term(pre, t);
×
1178
  }
1179

1180
  for (i = 0; i < pre->purification_map_list.size; ++ i) {
24✔
1181
    term_t t = pre->purification_map_list.data[i];
19✔
1182
    preprocessor_gc_mark_term(pre, t);
19✔
1183
    term_t t_pure = int_hmap_find(&pre->purification_map, t)->val;
19✔
1184
    preprocessor_gc_mark_term(pre, t_pure);
19✔
1185
  }
1186
}
5✔
1187

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