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

SRI-CSL / yices2 / 9226448713

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

Pull #513

github

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

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

18 existing lines in 12 files now uncovered.

81769 of 123915 relevant lines covered (65.99%)

1493770.28 hits per line

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

90.3
/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) {
657✔
40
  pre->terms = terms;
657✔
41
  init_term_manager(&pre->tm, terms);
657✔
42
  init_int_hmap(&pre->preprocess_map, 0);
657✔
43
  init_ivector(&pre->preprocess_map_list, 0);
657✔
44
  init_int_hmap(&pre->purification_map, 0);
657✔
45
  init_ivector(&pre->purification_map_list, 0);
657✔
46
  init_ivector(&pre->preprocessing_stack, 0);
657✔
47
  init_int_hmap(&pre->equalities, 0);
657✔
48
  init_ivector(&pre->equalities_list, 0);
657✔
49
  pre->tracer = NULL;
657✔
50
  pre->exception = handler;
657✔
51
  pre->options = options;
657✔
52
  scope_holder_construct(&pre->scope);
657✔
53
}
657✔
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) {
657✔
60
  delete_int_hmap(&pre->purification_map);
657✔
61
  delete_ivector(&pre->purification_map_list);
657✔
62
  delete_int_hmap(&pre->preprocess_map);
657✔
63
  delete_ivector(&pre->preprocess_map_list);
657✔
64
  delete_ivector(&pre->preprocessing_stack);
657✔
65
  delete_int_hmap(&pre->equalities);
657✔
66
  delete_ivector(&pre->equalities_list);
657✔
67
  delete_term_manager(&pre->tm);
657✔
68
  scope_holder_destruct(&pre->scope);
657✔
69
}
657✔
70

71
static
72
term_t preprocessor_get(preprocessor_t* pre, term_t t) {
1,612,798✔
73
  int_hmap_pair_t* find = int_hmap_find(&pre->preprocess_map, t);
1,612,798✔
74
  if (find == NULL) {
1,612,798✔
75
    return NULL_TERM;
875,001✔
76
  } else {
77
    return find->val;
737,797✔
78
  }
79
}
80

81
static
82
void preprocessor_set(preprocessor_t* pre, term_t t, term_t t_pre) {
338,610✔
83
  assert(preprocessor_get(pre, t) == NULL_TERM);
84
  int_hmap_add(&pre->preprocess_map, t, t_pre);
338,610✔
85
  ivector_push(&pre->preprocess_map_list, t);
338,610✔
86
}
338,610✔
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) {
209,901✔
98
  assert(term_is_composite(terms, t));
99
  assert(term_kind(terms, t) == kind);
100
  assert(is_pos_term(t));
101

102
  switch (kind) {
209,901✔
103
  case ITE_TERM:           // if-then-else
20,548✔
104
  case ITE_SPECIAL:        // special if-then-else term (NEW: EXPERIMENTAL)
105
    return ite_term_desc(terms, t);
20,548✔
106
  case EQ_TERM:            // equality
20,644✔
107
    return eq_term_desc(terms, t);
20,644✔
108
  case OR_TERM:            // n-ary OR
63,881✔
109
    return or_term_desc(terms, t);
63,881✔
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,943✔
113
    return arith_bineq_atom_desc(terms, t);
3,943✔
114
  case ARITH_EQ_ATOM: {
3,641✔
115
    composite_for_noncomposite.arity = 1;
3,641✔
116
    composite_for_noncomposite.arg[0] = arith_eq_arg(terms, t);
3,641✔
117
    return (composite_term_t*)&composite_for_noncomposite;
3,641✔
118
  }
119
  case ARITH_GE_ATOM: {
7,972✔
120
    composite_for_noncomposite.arity = 1;
7,972✔
121
    composite_for_noncomposite.arg[0] = arith_ge_arg(terms, t);
7,972✔
122
    return (composite_term_t*)&composite_for_noncomposite;
7,972✔
123
  }
124
  case ARITH_FF_BINEQ_ATOM:
12✔
125
    return arith_ff_bineq_atom_desc(terms, t);
12✔
126
  case ARITH_FF_EQ_ATOM: {
217✔
127
    composite_for_noncomposite.arity = 1;
217✔
128
    composite_for_noncomposite.arg[0] = arith_ff_eq_arg(terms, t);
217✔
129
    return (composite_term_t*)&composite_for_noncomposite;
217✔
130
  }
131
  case APP_TERM:           // application of an uninterpreted function
5,642✔
132
    return app_term_desc(terms, t);
5,642✔
133
  case ARITH_RDIV:          // division: (/ x y)
58✔
134
    return arith_rdiv_term_desc(terms, t);
58✔
135
  case ARITH_IDIV:          // division: (div x y) as defined in SMT-LIB 2
104✔
136
    return arith_idiv_term_desc(terms, t);
104✔
137
  case ARITH_MOD:          // remainder: (mod x y) is y - x * (div x y)
160✔
138
    return arith_mod_term_desc(terms, t);
160✔
139
  case UPDATE_TERM:
2,571✔
140
    return update_term_desc(terms, t);
2,571✔
141
  case DISTINCT_TERM:
23✔
142
    return distinct_term_desc(terms, t);
23✔
143
  case BV_ARRAY:
17,553✔
144
    return bvarray_term_desc(terms, t);
17,553✔
145
  case BV_DIV:
95✔
146
    return bvdiv_term_desc(terms, t);
95✔
147
  case BV_REM:
212✔
148
    return bvrem_term_desc(terms, t);
212✔
149
  case BV_SDIV:
20✔
150
    return bvsdiv_term_desc(terms, t);
20✔
151
  case BV_SREM:
21✔
152
    return bvsrem_term_desc(terms, t);
21✔
153
  case BV_SMOD:
6✔
154
    return bvsmod_term_desc(terms, t);
6✔
155
  case BV_SHL:
143✔
156
    return bvshl_term_desc(terms, t);
143✔
157
  case BV_LSHR:
279✔
158
    return bvlshr_term_desc(terms, t);
279✔
159
  case BV_ASHR:
21✔
160
    return bvashr_term_desc(terms, t);
21✔
161
  case BV_EQ_ATOM:
58,488✔
162
    return bveq_atom_desc(terms, t);
58,488✔
163
  case BV_GE_ATOM:
2,784✔
164
    return bvge_atom_desc(terms, t);
2,784✔
165
  case BV_SGE_ATOM:
833✔
166
    return bvsge_atom_desc(terms, t);
833✔
167
  default:
×
168
    assert(false);
169
    return NULL;
×
170
  }
171
}
172

173
static
174
term_t mk_composite(preprocessor_t* pre, term_kind_t kind, uint32_t n, term_t* children) {
31,723✔
175
  term_manager_t* tm = &pre->tm;
31,723✔
176
  term_table_t* terms = pre->terms;
31,723✔
177

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

261
/**
262
 * Returns true if we should purify t as an argument of a function.
263
 * Any new equalities are added to output.
264
 */
265
static inline
266
term_t preprocessor_purify(preprocessor_t* pre, term_t t, ivector_t* out) {
16,752✔
267

268
  term_table_t* terms = pre->terms;
16,752✔
269

270
  // Negated terms must be purified
271
  if (is_pos_term(t)) {
16,752✔
272
    // We don't purify variables
273
    switch (term_kind(terms, t)) {
16,730✔
274
    case UNINTERPRETED_TERM:
10,801✔
275
      // Variables are already pure
276
      return t;
10,801✔
277
    case CONSTANT_TERM:
9✔
278
      return t;
9✔
279
    case ARITH_CONSTANT:
1,621✔
280
    case ARITH_FF_CONSTANT:
281
    case BV64_CONSTANT:
282
    case BV_CONSTANT:
283
      // Constants are also pure (except for false)
284
      return t;
1,621✔
285
    case APP_TERM:
1,595✔
286
      // Uninterpreted functions are also already purified
287
      return t;
1,595✔
288
    case UPDATE_TERM:
1,675✔
289
      return t;
1,675✔
290
    default:
1,029✔
291
      break;
1,029✔
292
    }
293
  }
294

295
  // Everything else gets purified. Check if in the cache
296
  int_hmap_pair_t* find = int_hmap_find(&pre->purification_map, t);
1,051✔
297
  if (find != NULL) {
1,051✔
298
    return find->val;
658✔
299
  } else {
300
    // Make the variable
301
    type_t t_type = term_type(terms, t);
393✔
302
    term_t x = new_uninterpreted_term(terms, t_type);
393✔
303
    // Remember for later
304
    int_hmap_add(&pre->purification_map, t, x);
393✔
305
    ivector_push(&pre->purification_map_list, t);
393✔
306
    // Also add the variable to the pre-processor
307
    preprocessor_set(pre, x, x);
393✔
308
    // Add equality to output
309
    term_t eq = mk_eq(&pre->tm, x, t);
393✔
310
    ivector_push(out, eq);
393✔
311

312
    if (trace_enabled(pre->tracer, "mcsat::preprocess")) {
393✔
313
      mcsat_trace_printf(pre->tracer, "adding lemma = ");
×
314
      trace_term_ln(pre->tracer, terms, eq);
×
315
    }
316

317
    // Return the purified version
318
    return x;
393✔
319
  }
320
}
321

322
static inline
323
term_t mk_bvneg(term_manager_t* tm, term_t t) {
92✔
324
  term_table_t* terms = tm->terms;
92✔
325
  if (term_bitsize(terms,t) <= 64) {
92✔
326
    bvarith64_buffer_t *buffer = term_manager_get_bvarith64_buffer(tm);
76✔
327
    bvarith64_buffer_set_term(buffer, terms, t);
76✔
328
    bvarith64_buffer_negate(buffer);
76✔
329
    return mk_bvarith64_term(tm, buffer);
76✔
330
  } else {
331
    bvarith_buffer_t *buffer = term_manager_get_bvarith_buffer(tm);
16✔
332
    bvarith_buffer_set_term(buffer, terms, t);
16✔
333
    bvarith_buffer_negate(buffer);
16✔
334
    return mk_bvarith_term(tm, buffer);
16✔
335
  }
336
}
337

338
// Mark equality eq: (var = t) for solving
339
static
340
void preprocessor_mark_eq(preprocessor_t* pre, term_t eq, term_t var) {
24,851✔
341
  assert(is_pos_term(eq));
342
  assert(is_pos_term(var));
343
  assert(term_kind(pre->terms, var) == UNINTERPRETED_TERM);
344

345
  // Mark the equality
346
  int_hmap_pair_t* find = int_hmap_get(&pre->equalities, eq);
24,851✔
347
  assert(find->val == -1);
348
  find->val = var;
24,851✔
349
  ivector_push(&pre->equalities_list, eq);
24,851✔
350
}
24,851✔
351

352
static
353
term_t preprocessor_get_eq_solved_var(const preprocessor_t* pre, term_t eq) {
47,494✔
354
  assert(is_pos_term(eq));
355
  int_hmap_pair_t* find = int_hmap_find((int_hmap_t*) &pre->equalities, eq);
47,494✔
356
  if (find != NULL) {
47,494✔
357
    return find->val;
19,974✔
358
  } else {
359
    return NULL_TERM;
27,520✔
360
  }
361
}
362

363
term_t preprocessor_apply(preprocessor_t* pre, term_t t, ivector_t* out, bool is_assertion) {
39,399✔
364

365
  term_table_t* terms = pre->terms;
39,399✔
366
  term_manager_t* tm = &pre->tm;
39,399✔
367

368
  uint32_t i, j, n;
369

370
  // Check if already preprocessed;
371
  term_t t_pre = preprocessor_get(pre, t);
39,399✔
372
  if (t_pre != NULL_TERM) {
39,399✔
373
    return t_pre;
1,560✔
374
  }
375

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

394
  // Preprocess
395
  while (pre_stack->size) {
509,889✔
396
    // Current term
397
    term_t current = ivector_last(pre_stack);
472,051✔
398

399
    if (trace_enabled(pre->tracer, "mcsat::preprocess")) {
472,051✔
400
      mcsat_trace_printf(pre->tracer, "current = ");
×
401
      trace_term_ln(pre->tracer, terms, current);
×
402
    }
403

404
    // If preprocessed already, done
405
    term_t current_pre = preprocessor_get(pre, current);
472,051✔
406
    if (current_pre != NULL_TERM) {
472,051✔
407
      ivector_pop(pre_stack);
31,465✔
408
      continue;
31,465✔
409
    }
410

411
    // Negation
412
    if (is_neg_term(current)) {
440,586✔
413
      term_t child = unsigned_term(current);
89,881✔
414
      term_t child_pre = preprocessor_get(pre, child);
89,881✔
415
      if (child_pre == NULL_TERM) {
89,881✔
416
        ivector_push(pre_stack, child);
42,537✔
417
        continue;
42,537✔
418
      } else {
419
        ivector_pop(pre_stack);
47,344✔
420
        current_pre = opposite_term(child_pre);
47,344✔
421
        preprocessor_set(pre, current, current_pre);
47,344✔
422
        continue;
47,344✔
423
      }
424
    }
425

426
    // Check for supported types
427
    type_kind_t type = term_type_kind(terms, current);
350,705✔
428
    switch (type) {
350,705✔
429
    case BOOL_TYPE:
350,705✔
430
    case INT_TYPE:
431
    case REAL_TYPE:
432
    case FF_TYPE:
433
    case UNINTERPRETED_TYPE:
434
    case FUNCTION_TYPE:
435
    case BITVECTOR_TYPE:
436
    case SCALAR_TYPE:
437
      break;
350,705✔
438
    default:
×
439
      longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
×
440
    }
441

442
    // Kind of term
443
    term_kind_t current_kind = term_kind(terms, current);
350,705✔
444

445
    switch(current_kind) {
350,705✔
446
    case CONSTANT_TERM:    // constant of uninterpreted/scalar/boolean types
1,769✔
447
    case BV64_CONSTANT:    // compact bitvector constant (64 bits at most)
448
    case BV_CONSTANT:      // generic bitvector constant (more than 64 bits)
449
    case ARITH_CONSTANT:   // rational constant
450
    case ARITH_FF_CONSTANT:   // finite field constant
451
      current_pre = current;
1,769✔
452
      break;
1,769✔
453

454
    case UNINTERPRETED_TERM:  // (i.e., global variables, can't be bound).
14,670✔
455
      current_pre = current;
14,670✔
456
      // Unless we want special slicing
457
      if (type == BITVECTOR_TYPE) {
14,670✔
458
        if (pre->options->bv_var_size > 0) {
5,014✔
459
          uint32_t size = term_bitsize(terms, current);
×
460
          uint32_t var_size = pre->options->bv_var_size;
×
461
          if (size > var_size) {
×
462
            uint32_t n_vars = (size - 1) / var_size + 1;
×
463
            term_t vars[n_vars];
×
464
            for (i = n_vars - 1; size > 0; i--) {
×
465
              if (size >= var_size) {
×
466
                vars[i] = new_uninterpreted_term(terms, bv_type(terms->types, var_size));
×
467
                size -= var_size;
×
468
              } else {
469
                vars[i] = new_uninterpreted_term(terms, bv_type(terms->types, size));
×
470
                size = 0;
×
471
              }
472
            }
473
            current_pre = _o_yices_bvconcat(n_vars, vars);
×
474
            term_t eq = _o_yices_eq(current, current_pre);
×
475
            preprocessor_mark_eq(pre, eq, current);
×
476
          }
477
        }
478
      }
479
      break;
14,670✔
480

481
    case ITE_TERM:           // if-then-else
183,746✔
482
    case ITE_SPECIAL:        // special if-then-else term (NEW: EXPERIMENTAL)
483
    case EQ_TERM:            // equality
484
    case OR_TERM:            // n-ary OR
485
    case XOR_TERM:           // n-ary XOR
486
    case ARITH_EQ_ATOM:      // equality (t == 0)
487
    case ARITH_BINEQ_ATOM:   // equality (t1 == t2)  (between two arithmetic terms)
488
    case ARITH_GE_ATOM:      // inequality (t >= 0)
489
    case ARITH_FF_EQ_ATOM:   // finite field equality (t == 0)
490
    case ARITH_FF_BINEQ_ATOM: // finite field equality (t1 == t2)  (between two arithmetic terms)
491
    case BV_DIV:
492
    case BV_REM:
493
    case BV_SMOD:
494
    case BV_SHL:
495
    case BV_LSHR:
496
    case BV_ASHR:
497
    case BV_EQ_ATOM:
498
    case BV_GE_ATOM:
499
    case BV_SGE_ATOM:
500
    {
501
      composite_term_t* desc = get_composite(terms, current_kind, current);
183,746✔
502
      bool children_done = true;
183,746✔
503
      bool children_same = true;
183,746✔
504

505
      n = desc->arity;
183,746✔
506

507
      /*
508
      // Arrays not supported yet
509
      if (current_kind == EQ_TERM && term_type_kind(terms, desc->arg[0]) == FUNCTION_TYPE) {
510
        longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
511
      }
512
      */
513
 
514
      // Is this a top-level equality assertion
515
      bool is_equality =
183,746✔
516
          current_kind == EQ_TERM ||
163,102✔
517
          current_kind == BV_EQ_ATOM ||
104,614✔
518
          current_kind == ARITH_EQ_ATOM ||
100,975✔
519
          current_kind == ARITH_BINEQ_ATOM ||
97,033✔
520
          current_kind == ARITH_FF_EQ_ATOM ||
346,848✔
521
          current_kind == ARITH_FF_BINEQ_ATOM;
522
      // don't rewrite if the equality is between Boolean terms
523
      bool is_boolean = is_boolean_type(term_type(pre->terms, desc->arg[0]));
183,746✔
524

525
      term_t eq_solve_var = NULL_TERM;
183,746✔
526
      if (is_assertion && is_equality && !is_boolean) {
183,746✔
527
        bool is_lhs_rhs_mixed = desc->arity > 1 &&
141,902✔
528
          term_type_kind(pre->terms, desc->arg[0]) != term_type_kind(pre->terms, desc->arg[1]);
69,023✔
529
        // don't rewrite if equality is between mixed terms, e.g. between int and real terms
530
        if (!is_lhs_rhs_mixed && current == t) {
72,879✔
531
          eq_solve_var = preprocessor_get_eq_solved_var(pre, t);
47,491✔
532
          if (eq_solve_var == NULL_TERM) {
47,491✔
533
            term_t lhs = desc->arg[0];
27,520✔
534
            term_kind_t lhs_kind = term_kind(terms, lhs);
27,520✔
535
            // If lhs/rhs is a first-time seen variable, we can solve it
536
            bool lhs_is_var = lhs_kind == UNINTERPRETED_TERM && is_pos_term(lhs);
27,520✔
537
            if (lhs_is_var && preprocessor_get(pre, lhs) == NULL_TERM) {
27,520✔
538
              // First time variable, let's solve
539
              preprocessor_mark_eq(pre, t, lhs);
24,596✔
540
              eq_solve_var = lhs;
24,596✔
541
            } else if (desc->arity > 1) {
2,924✔
542
              term_t rhs = desc->arg[1];
2,218✔
543
              term_kind_t rhs_kind = term_kind(terms, rhs);
2,218✔
544
              bool rhs_is_var = rhs_kind == UNINTERPRETED_TERM && is_pos_term(rhs);
2,218✔
545
              if (rhs_is_var && preprocessor_get(pre, rhs) == NULL_TERM) {
2,218✔
546
                // First time variable, let's solve
547
                preprocessor_mark_eq(pre, t, rhs);
255✔
548
                eq_solve_var = rhs;
255✔
549
              }
550
            }
551
          } else {
552
            // Check that we it's not there already
553
            if (preprocessor_get(pre, eq_solve_var) != NULL_TERM) {
19,971✔
554
              eq_solve_var = NULL_TERM;
61✔
555
            }
556
          }
557
        }
558
      }
559

560
      ivector_t children;
561
      init_ivector(&children, n);
183,746✔
562

563
      for (i = 0; i < n; ++ i) {
612,068✔
564
        term_t child = desc->arg[i];
428,322✔
565
        if (child != eq_solve_var) {
428,322✔
566
          term_t child_pre = preprocessor_get(pre, child);
383,561✔
567
          if (child_pre == NULL_TERM) {
383,561✔
568
            children_done = false;
110,461✔
569
            ivector_push(pre_stack, child);
110,461✔
570
          } else if (child_pre != child) {
273,100✔
571
            children_same = false;
76,437✔
572
          }
573
          if (children_done) {
383,561✔
574
            ivector_push(&children, child_pre);
259,162✔
575
          }
576
        }
577
      }
578

579
      if (eq_solve_var != NULL_TERM) {
183,746✔
580
        // Check again to make sure we don't have something like x = x + 1
581
        if (preprocessor_get(pre, eq_solve_var) != NULL_TERM) {
44,761✔
582
          // Do it again
583
          children_done = false;
×
584
        }
585
      }
586

587
      if (children_done) {
183,746✔
588
        if (eq_solve_var != NULL_TERM) {
114,682✔
589
          term_t eq_solve_term = zero_term;
24,790✔
590
          if (children.size > 0) {
24,790✔
591
            eq_solve_term = children.data[0];
24,752✔
592
          }
593
          preprocessor_set(pre, eq_solve_var, eq_solve_term);
24,790✔
594
          current_pre = true_term;
24,790✔
595
        } else {
596
          if (children_same) {
89,892✔
597
            current_pre = current;
64,800✔
598
          } else {
599
            current_pre = mk_composite(pre, current_kind, n, children.data);
25,092✔
600
          }
601
        }
602
      }
603

604
      delete_ivector(&children);
183,746✔
605

606
      break;
183,746✔
607
    }
608

609
    case BV_ARRAY:
17,553✔
610
    {
611
      composite_term_t* desc = get_composite(terms, current_kind, current);
17,553✔
612
      bool children_done = true;
17,553✔
613
      bool children_same = true;
17,553✔
614

615
      n = desc->arity;
17,553✔
616

617
      ivector_t children;
618
      init_ivector(&children, n);
17,553✔
619

620
      for (i = 0; i < n; ++ i) {
355,516✔
621
        term_t child = desc->arg[i];
337,963✔
622
        term_t child_pre = preprocessor_get(pre, child);
337,963✔
623
        if (child_pre == NULL_TERM) {
337,963✔
624
          children_done = false;
143,640✔
625
          ivector_push(pre_stack, child);
143,640✔
626
        } else {
627
          if (is_arithmetic_literal(terms, child_pre)) {
194,323✔
628
            // purify if arithmetic literal, i.e. a = 0 where a is of integer type
629
            child_pre = preprocessor_purify(pre, child_pre, out);
1✔
630
          }
631
          if (child_pre != child) {
194,323✔
632
            children_same = false;
60,366✔
633
          }
634
        }
635
        if (children_done) {
337,963✔
636
          ivector_push(&children, child_pre);
180,701✔
637
        }
638
      }
639

640
      if (children_done) {
17,553✔
641
        if (children_same) {
9,183✔
642
          current_pre = current;
3,874✔
643
        } else {
644
          current_pre = mk_composite(pre, current_kind, n, children.data);
5,309✔
645
        }
646
      }
647

648
      delete_ivector(&children);
17,553✔
649

650
      break;
17,553✔
651
    }
652

653
    case ARITH_ABS:
6✔
654
    {
655
      term_t arg = arith_abs_arg(terms, current);
6✔
656
      term_t arg_pre = preprocessor_get(pre, arg);
6✔
657
      if (arg_pre == NULL_TERM) {
6✔
658
        ivector_push(pre_stack, arg);
2✔
659
      } else {
660
        type_t arg_pre_type = term_type(pre->terms, arg_pre);
4✔
661
        term_t arg_pre_is_positive = mk_arith_term_geq0(&pre->tm, arg_pre);
4✔
662
        term_t arg_negative = _o_yices_neg(arg_pre);
4✔
663
        current_pre = mk_ite(&pre->tm, arg_pre_is_positive, arg_pre, arg_negative, arg_pre_type);
4✔
664
      }
665
      break;
6✔
666
    }
667

668
    case BV_SDIV:
20✔
669
    {
670
      composite_term_t* desc = get_composite(terms, current_kind, current);
20✔
671
      assert(desc->arity == 2);
672
      term_t s = desc->arg[0];
20✔
673
      term_t s_pre = preprocessor_get(pre, s);
20✔
674
      if (s_pre == NULL_TERM) {
20✔
675
        ivector_push(pre_stack, s);
7✔
676
      }
677
      term_t t = desc->arg[1];
20✔
678
      term_t t_pre = preprocessor_get(pre, t);
20✔
679
      if (t_pre == NULL_TERM) {
20✔
680
        ivector_push(pre_stack, t);
5✔
681
      }
682
      if (s_pre != NULL_TERM && t_pre != NULL_TERM) {
20✔
683
        type_t tau = term_type(terms, s_pre);
11✔
684
        uint32_t n = term_bitsize(terms, s_pre);
11✔
685
        term_t msb_s = mk_bitextract(tm, s_pre, n-1);
11✔
686
        term_t msb_t = mk_bitextract(tm, t_pre, n-1);
11✔
687
        // if (msb_s) {
688
        //   if (msb_t) {
689
        //     t1: udiv(-s, -t)
690
        //   } else {
691
        //     t2: -udiv(-s, t)
692
        //   }
693
        // } else {
694
        //   if (msb_t) {
695
        //     t3: -udiv(s, -t)
696
        //   } else {
697
        //     t4: udiv(s, t)
698
        //   }
699
        // }
700
        term_t neg_s = mk_bvneg(tm, s_pre);
11✔
701
        term_t neg_t = mk_bvneg(tm, t_pre);
11✔
702

703
        term_t t1 = mk_bvdiv(tm, neg_s, neg_t);
11✔
704
        term_t t2 = mk_bvdiv(tm, neg_s, t_pre);
11✔
705
        t2 = mk_bvneg(&pre->tm, t2);
11✔
706
        term_t t3 = mk_bvdiv(tm, s_pre, neg_t);
11✔
707
        t3 = mk_bvneg(&pre->tm, t3);
11✔
708
        term_t t4 = mk_bvdiv(tm, s_pre, t_pre);
11✔
709

710
        term_t b1 = mk_ite(tm, msb_t, t1, t2, tau);
11✔
711
        term_t b2 = mk_ite(tm, msb_t, t3, t4, tau);
11✔
712

713
        current_pre = mk_ite(tm, msb_s, b1, b2, tau);
11✔
714
      }
715
      break;
20✔
716
    }
717
    case BV_SREM:
21✔
718
    {
719
      composite_term_t* desc = get_composite(terms, current_kind, current);
21✔
720
      assert(desc->arity == 2);
721
      term_t s = desc->arg[0];
21✔
722
      term_t s_pre = preprocessor_get(pre, s);
21✔
723
      if (s_pre == NULL_TERM) {
21✔
724
        ivector_push(pre_stack, s);
8✔
725
      }
726
      term_t t = desc->arg[1];
21✔
727
      term_t t_pre = preprocessor_get(pre, t);
21✔
728
      if (t_pre == NULL_TERM) {
21✔
729
        ivector_push(pre_stack, t);
3✔
730
      }
731
      if (s_pre != NULL_TERM && t_pre != NULL_TERM) {
21✔
732
        type_t tau = term_type(terms, s_pre);
12✔
733
        uint32_t n = term_bitsize(terms, s_pre);
12✔
734
        term_t msb_s = mk_bitextract(tm, s_pre, n-1);
12✔
735
        term_t msb_t = mk_bitextract(tm, t_pre, n-1);
12✔
736
        // if (msb_s) {
737
        //   if (msb_t) {
738
        //     t1: -urem(-s, -t)
739
        //   } else {
740
        //     t2: -urem(-s, t)
741
        //   }
742
        // } else {
743
        //   if (msb_t) {
744
        //     t3: -urem(s, -t)
745
        //   } else {
746
        //     t4: urem(s, t)
747
        //   }
748
        // }
749
        term_t neg_s = mk_bvneg(tm, s_pre);
12✔
750
        term_t neg_t = mk_bvneg(tm, t_pre);
12✔
751

752
        term_t t1 = mk_bvrem(tm, neg_s, neg_t);
12✔
753
        t1 = mk_bvneg(tm, t1);
12✔
754
        term_t t2 = mk_bvrem(tm, neg_s, t_pre);
12✔
755
        t2 = mk_bvneg(tm, t2);
12✔
756
        term_t t3 = mk_bvrem(tm, s_pre, neg_t);
12✔
757
        term_t t4 = mk_bvrem(tm, s_pre, t_pre);
12✔
758

759
        term_t b1 = mk_ite(tm, msb_t, t1, t2, tau);
12✔
760
        term_t b2 = mk_ite(tm, msb_t, t3, t4, tau);
12✔
761

762
        current_pre = mk_ite(tm, msb_s, b1, b2, tau);
12✔
763
      }
764
      break;
21✔
765
    }
766
    case BIT_TERM: // bit-select current = child[i]
112,994✔
767
    {
768
      uint32_t index = bit_term_index(terms, current);
112,994✔
769
      term_t arg = bit_term_arg(terms, current);
112,994✔
770
      term_t arg_pre = preprocessor_get(pre, arg);
112,994✔
771
      if (arg_pre == NULL_TERM) {
112,994✔
772
        ivector_push(pre_stack, arg);
1,586✔
773
      } else {
774
        if (arg_pre == arg) {
111,408✔
775
          current_pre = current;
80,591✔
776
        } else {
777
          if (trace_enabled(pre->tracer, "mcsat::preprocess")) {
30,817✔
778
            mcsat_trace_printf(pre->tracer, "arg_pre = ");
×
779
            trace_term_ln(pre->tracer, terms, arg_pre);
×
780
          }
781
          // For simplification purposes use API
782
          current_pre = _o_yices_bitextract(arg_pre, index);
30,817✔
783
          assert(current_pre != NULL_TERM);
784
        }
785
      }
786
      break;
112,994✔
787
    }
788
    case BV_POLY:  // polynomial with generic bitvector coefficients
33✔
789
    {
790
      bvpoly_t* p = bvpoly_term_desc(terms, current);
33✔
791

792
      bool children_done = true;
33✔
793
      bool children_same = true;
33✔
794

795
      n = p->nterms;
33✔
796

797
      ivector_t children;
798
      init_ivector(&children, n);
33✔
799

800
      for (i = 0; i < n; ++ i) {
84✔
801
        term_t x = p->mono[i].var;
51✔
802
        term_t x_pre = (x == const_idx ? const_idx : preprocessor_get(pre, x));
51✔
803

804
        if (x_pre != const_idx) {
51✔
805
          if (x_pre == NULL_TERM) {
47✔
806
            children_done = false;
10✔
807
            ivector_push(pre_stack, x);
10✔
808
          } else if (x_pre != x) {
37✔
809
            children_same = false;
23✔
810
          }
811
        }
812

813
        if (children_done) { ivector_push(&children, x_pre); }
51✔
814
      }
815

816
      if (children_done) {
33✔
817
        if (children_same) {
26✔
818
          current_pre = current;
11✔
819
        } else {
820
          current_pre = mk_bvarith_poly(tm, p, n, children.data);
15✔
821
        }
822
      }
823

824
      delete_ivector(&children);
33✔
825

826
      break;
33✔
827
    }
828
    case BV64_POLY: // polynomial with 64bit coefficients
2,802✔
829
    {
830
      bvpoly64_t* p = bvpoly64_term_desc(terms, current);
2,802✔
831

832
      bool children_done = true;
2,802✔
833
      bool children_same = true;
2,802✔
834

835
      n = p->nterms;
2,802✔
836

837
      ivector_t children;
838
      init_ivector(&children, n);
2,802✔
839

840
      for (i = 0; i < n; ++ i) {
10,514✔
841
        term_t x = p->mono[i].var;
7,712✔
842
        term_t x_pre = (x == const_idx ? const_idx : preprocessor_get(pre, x));
7,712✔
843

844
        if (x_pre != const_idx) {
7,712✔
845
          if (x_pre == NULL_TERM) {
5,835✔
846
            children_done = false;
1,393✔
847
            ivector_push(pre_stack, x);
1,393✔
848
          } else if (x_pre != x) {
4,442✔
849
            children_same = false;
665✔
850
          }
851
        }
852

853
        if (children_done) { ivector_push(&children, x_pre); }
7,712✔
854
      }
855

856
      if (children_done) {
2,802✔
857
        if (children_same) {
2,026✔
858
          current_pre = current;
1,426✔
859
        } else {
860
          current_pre = mk_bvarith64_poly(tm, p, n, children.data);
600✔
861
        }
862
      }
863

864
      delete_ivector(&children);
2,802✔
865

866
      break;
2,802✔
867
    }
868

869
    case POWER_PRODUCT:    // power products: (t1^d1 * ... * t_n^d_n)
1,660✔
870
    {
871
      pprod_t* pp = pprod_term_desc(terms, current);
1,660✔
872
      bool children_done = true;
1,660✔
873
      bool children_same = true;
1,660✔
874

875
      n = pp->len;
1,660✔
876

877
      ivector_t children;
878
      init_ivector(&children, n);
1,660✔
879

880
      for (i = 0; i < n; ++ i) {
5,257✔
881
        term_t x = pp->prod[i].var;
3,597✔
882
        term_t x_pre = preprocessor_get(pre, x);
3,597✔
883

884
        if (x_pre == NULL_TERM) {
3,597✔
885
          children_done = false;
438✔
886
          ivector_push(pre_stack, x);
438✔
887
        } else if (x_pre != x) {
3,159✔
888
          children_same = false;
43✔
889
        }
890

891
        if (children_done) { ivector_push(&children, x_pre); }
3,597✔
892
      }
893

894
      if (children_done) {
1,660✔
895
        if (children_same) {
1,335✔
896
          current_pre = current;
1,307✔
897
        } else {
898
          // NOTE: it doens't change pp, it just uses it as a frame
899
          current_pre = mk_pprod(tm, pp, n, children.data);
28✔
900
        }
901
      }
902

903
      delete_ivector(&children);
1,660✔
904

905
      break;
1,660✔
906
    }
907

908
    case ARITH_POLY:       // polynomial with rational coefficients
6,656✔
909
    {
910
      polynomial_t* p = poly_term_desc(terms, current);
6,656✔
911

912
      bool children_done = true;
6,656✔
913
      bool children_same = true;
6,656✔
914

915
      n = p->nterms;
6,656✔
916

917
      ivector_t children;
918
      init_ivector(&children, n);
6,656✔
919

920
      for (i = 0; i < n; ++ i) {
25,874✔
921
        term_t x = p->mono[i].var;
19,218✔
922
        term_t x_pre = (x == const_idx ? const_idx : preprocessor_get(pre, x));
19,218✔
923

924
        if (x_pre != const_idx) {
19,218✔
925
          if (x_pre == NULL_TERM) {
16,260✔
926
            children_done = false;
2,455✔
927
            ivector_push(pre_stack, x);
2,455✔
928
          } else if (x_pre != x) {
13,805✔
929
            children_same = false;
762✔
930
          }
931
        }
932

933
        if (children_done) { ivector_push(&children, x_pre); }
19,218✔
934
      }
935

936
      if (children_done) {
6,656✔
937
        if (children_same) {
5,285✔
938
          current_pre = current;
4,769✔
939
        } else {
940
          current_pre = mk_arith_poly(tm, p, n, children.data);
516✔
941
        }
942
      }
943

944
      delete_ivector(&children);
6,656✔
945

946
      break;
6,656✔
947
    }
948

949
    case ARITH_FF_POLY:    // polynomial with finite field coefficients
210✔
950
    {
951
      polynomial_t* p = finitefield_poly_term_desc(terms, current);
210✔
952
      const rational_t *mod = finitefield_term_order(terms, current);
210✔
953

954
      bool children_done = true;
210✔
955
      bool children_same = true;
210✔
956

957
      n = p->nterms;
210✔
958

959
      ivector_t children;
960
      init_ivector(&children, n);
210✔
961

962
      for (i = 0; i < n; ++ i) {
1,340✔
963
        term_t x = p->mono[i].var;
1,130✔
964
        term_t x_pre = (x == const_idx ? const_idx : preprocessor_get(pre, x));
1,130✔
965

966
        if (x_pre != const_idx) {
1,130✔
967
          if (x_pre == NULL_TERM) {
1,060✔
968
            children_done = false;
436✔
969
            ivector_push(pre_stack, x);
436✔
970
          } else if (x_pre != x) {
624✔
NEW
971
            children_same = false;
×
972
          }
973
        }
974

975
        if (children_done) { ivector_push(&children, x_pre); }
1,130✔
976
      }
977

978
      if (children_done) {
210✔
979
        if (children_same) {
106✔
980
          current_pre = current;
106✔
981
        } else {
NEW
982
          current_pre = mk_arith_ff_poly(tm, p, n, children.data, mod);
×
983
        }
984
      }
985

986
      delete_ivector(&children);
210✔
987

988
      break;
210✔
989
    }
990

991
    // FOLLOWING ARE UNINTEPRETED, SO WE PURIFY THE ARGUMENTS
992

993
    case APP_TERM:           // application of an uninterpreted function
8,535✔
994
    case ARITH_RDIV:         // regular division (/ x y)
995
    case ARITH_IDIV:         // division: (div x y) as defined in SMT-LIB 2
996
    case ARITH_MOD:          // remainder: (mod x y) is y - x * (div x y)
997
    case UPDATE_TERM:        // update array
998
    {
999
      composite_term_t* desc = get_composite(terms, current_kind, current);
8,535✔
1000
      bool children_done = true;
8,535✔
1001
      bool children_same = true;
8,535✔
1002

1003
      n = desc->arity;
8,535✔
1004

1005
      ivector_t children;
1006
      init_ivector(&children, n);
8,535✔
1007

1008
      for (i = 0; i < n; ++ i) {
29,315✔
1009
        term_t child = desc->arg[i];
20,780✔
1010
        term_t child_pre = preprocessor_get(pre, child);
20,780✔
1011

1012
        if (child_pre == NULL_TERM) {
20,780✔
1013
          children_done = false;
4,032✔
1014
          ivector_push(pre_stack, child);
4,032✔
1015
        } else {
1016
          // Purify if needed
1017
          child_pre = preprocessor_purify(pre, child_pre, out);
16,748✔
1018
          // If interpreted terms, we need to purify non-variables
1019
          if (child_pre != child) { children_same = false; }
16,748✔
1020
        }
1021

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

1025
      if (children_done) {
8,535✔
1026
        if (children_same) {
5,549✔
1027
          current_pre = current;
4,227✔
1028
        } else {
1029
          current_pre = mk_composite(pre, current_kind, n, children.data);
1,322✔
1030
        }
1031
      }
1032

1033
      delete_ivector(&children);
8,535✔
1034

1035
      break;
8,535✔
1036
    }
1037

1038
    case ARITH_IS_INT_ATOM:
×
1039
    {
1040
      // replace with t <= floor(t)
1041
      term_t child = arith_is_int_arg(terms, current);
×
1042
      term_t child_pre = preprocessor_get(pre, child);
×
1043
      if (child_pre != NULL_TERM) {
×
1044
        child_pre = preprocessor_purify(pre, child_pre, out);
×
1045
        current_pre = arith_floor(terms, child_pre);
×
1046
        current_pre = mk_arith_leq(tm, child_pre, current_pre);
×
1047
      } else {
1048
        ivector_push(pre_stack, child);
×
1049
      }
1050
      break;
×
1051
    }
1052

1053
    case ARITH_FLOOR:        // floor: purify, but its interpreted
7✔
1054
    {
1055
      term_t child = arith_floor_arg(terms, current);
7✔
1056
      term_t child_pre = preprocessor_get(pre, child);
7✔
1057

1058
      if (child_pre != NULL_TERM) {
7✔
1059
        if (term_kind(terms, child_pre) == ARITH_CONSTANT) {
4✔
1060
          rational_t floor;
1061
          q_init(&floor);
1✔
1062
          q_set(&floor, rational_term_desc(terms, child_pre));
1✔
1063
          q_floor(&floor);
1✔
1064
          current_pre = arith_constant(terms, &floor);
1✔
1065
          q_clear(&floor);
1✔
1066
        } else {
1067
          child_pre = preprocessor_purify(pre, child_pre, out);
3✔
1068
          if (child_pre != child) {
3✔
1069
            current_pre = arith_floor(terms, child_pre);
1✔
1070
          } else {
1071
            current_pre = current;
2✔
1072
          }
1073
        }
1074
      } else {
1075
        ivector_push(pre_stack, child);
3✔
1076
      }
1077

1078
      break;
7✔
1079
    }
1080

1081
    case ARITH_CEIL:        // floor: purify, but its interpreted
×
1082
    {
1083
      term_t child = arith_ceil_arg(terms, current);
×
1084
      term_t child_pre = preprocessor_get(pre, child);
×
1085

1086
      if (child_pre != NULL_TERM) {
×
1087
        child_pre = preprocessor_purify(pre, child_pre, out);
×
1088
        if (child_pre != child) {
×
1089
          current_pre = arith_floor(terms, child_pre);
×
1090
        } else {
1091
          current_pre = current;
×
1092
        }
1093
      } else {
1094
        ivector_push(pre_stack, child);
×
1095
      }
1096

1097
      break;
×
1098
    }
1099

1100
    case DISTINCT_TERM:
23✔
1101
    {
1102
      composite_term_t* desc = get_composite(terms, current_kind, current);
23✔
1103

1104
      // Arrays not supported yet
1105
      if (term_type_kind(terms, desc->arg[0]) == FUNCTION_TYPE) {
23✔
1106
        longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
1✔
1107
      }
1108

1109
      bool children_done = true;
22✔
1110
      n = desc->arity;
22✔
1111

1112
      ivector_t children;
1113
      init_ivector(&children, n);
22✔
1114

1115
      for (i = 0; i < n; ++ i) {
114✔
1116
        term_t child = desc->arg[i];
92✔
1117
        term_t child_pre = preprocessor_get(pre, child);
92✔
1118

1119
        if (child_pre == NULL_TERM) {
92✔
1120
          children_done = false;
38✔
1121
          ivector_push(pre_stack, child);
38✔
1122
        }
1123

1124
        if (children_done) { ivector_push(&children, child_pre); }
92✔
1125
      }
1126

1127
      if (children_done) {
22✔
1128
        ivector_t distinct;
1129
        init_ivector(&distinct, 0);
13✔
1130

1131
        for (i = 0; i < n; ++ i) {
66✔
1132
          for (j = i + 1; j < n; ++ j) {
142✔
1133
            term_t neq = mk_eq(&pre->tm, children.data[i], children.data[j]);
89✔
1134
            neq = opposite_term(neq);
89✔
1135
            ivector_push(&distinct, neq);
89✔
1136
          }
1137
        }
1138
        current_pre = mk_and(&pre->tm, distinct.size, distinct.data);
13✔
1139

1140
        delete_ivector(&distinct);
13✔
1141
      }
1142

1143
      delete_ivector(&children);
22✔
1144

1145
      break;
22✔
1146
    }
1147

1148
    default:
×
1149
      // UNSUPPORTED TERM/THEORY
1150
      longjmp(*pre->exception, MCSAT_EXCEPTION_UNSUPPORTED_THEORY);
×
1151
      break;
1152
    }
1153

1154
    if (current_pre != NULL_TERM) {
350,704✔
1155
      preprocessor_set(pre, current, current_pre);
266,083✔
1156
      ivector_pop(pre_stack);
266,083✔
1157
      if (trace_enabled(pre->tracer, "mcsat::preprocess")) {
266,083✔
1158
        mcsat_trace_printf(pre->tracer, "current_pre = ");
×
1159
        trace_term_ln(pre->tracer, terms, current_pre);
×
1160
      }
1161
    }
1162

1163
  }
1164

1165
  // Return the result
1166
  t_pre = preprocessor_get(pre, t);
37,838✔
1167
  if (trace_enabled(pre->tracer, "mcsat::preprocess")) {
37,838✔
1168
    mcsat_trace_printf(pre->tracer, "t_pre = ");
×
1169
    trace_term_ln(pre->tracer, terms, t_pre);
×
1170
  }
1171

1172
  ivector_reset(pre_stack);
37,838✔
1173

1174
  assert(t_pre != NULL_TERM);
1175
  return t_pre;
37,838✔
1176
}
1177

1178
void preprocessor_set_exception_handler(preprocessor_t* pre, jmp_buf* handler) {
×
1179
  pre->exception = handler;
×
1180
}
×
1181

1182
void preprocessor_push(preprocessor_t* pre) {
526✔
1183
  scope_holder_push(&pre->scope,
526✔
1184
      &pre->preprocess_map_list.size,
1185
      &pre->purification_map_list.size,
1186
      &pre->equalities_list.size,
1187
      NULL);
1188
}
526✔
1189

1190
void preprocessor_pop(preprocessor_t* pre) {
452✔
1191

1192
  uint32_t preprocess_map_list_size = 0;
452✔
1193
  uint32_t purification_map_list_size = 0;
452✔
1194
  uint32_t equalities_list_size = 0;
452✔
1195

1196
  scope_holder_pop(&pre->scope,
452✔
1197
      &preprocess_map_list_size,
1198
      &purification_map_list_size,
1199
      &equalities_list_size,
1200
      NULL);
1201

1202
  while (pre->preprocess_map_list.size > preprocess_map_list_size) {
13,614✔
1203
    term_t t = ivector_last(&pre->preprocess_map_list);
13,162✔
1204
    ivector_pop(&pre->preprocess_map_list);
13,162✔
1205
    int_hmap_pair_t* find = int_hmap_find(&pre->preprocess_map, t);
13,162✔
1206
    assert(find != NULL);
1207
    int_hmap_erase(&pre->preprocess_map, find);
13,162✔
1208
  }
1209

1210
  while (pre->purification_map_list.size > purification_map_list_size) {
587✔
1211
    term_t t = ivector_last(&pre->purification_map_list);
135✔
1212
    ivector_pop(&pre->purification_map_list);
135✔
1213
    int_hmap_pair_t* find = int_hmap_find(&pre->purification_map, t);
135✔
1214
    assert(find != NULL);
1215
    int_hmap_erase(&pre->purification_map, find);
135✔
1216
  }
1217

1218
  while (pre->equalities_list.size > equalities_list_size) {
502✔
1219
    term_t eq = ivector_last(&pre->equalities_list);
50✔
1220
    ivector_pop(&pre->equalities_list);
50✔
1221
    int_hmap_pair_t* find = int_hmap_find(&pre->equalities, eq);
50✔
1222
    assert(find != NULL);
1223
    int_hmap_erase(&pre->equalities, find);
50✔
1224
  }
1225
}
452✔
1226

1227
void preprocessor_build_model(preprocessor_t* pre, model_t* model) {
29✔
1228
  uint32_t i = 0;
29✔
1229
  for (i = 0; i < pre->equalities_list.size; ++ i) {
32✔
1230
    term_t eq = pre->equalities_list.data[i];
3✔
1231
    term_t eq_var = preprocessor_get_eq_solved_var(pre, eq);
3✔
1232
    if (trace_enabled(pre->tracer, "mcsat::preprocess")) {
3✔
1233
      mcsat_trace_printf(pre->tracer, "eq = ");
×
1234
      trace_term_ln(pre->tracer, pre->terms, eq);
×
1235
      mcsat_trace_printf(pre->tracer, "\neq_var = ");
×
1236
      trace_term_ln(pre->tracer, pre->terms, eq_var);
×
1237
      mcsat_trace_printf(pre->tracer, "\n");
×
1238
    }
1239
    // Some equalities are solved, but then reasserted in the solver
1240
    // these already have a model
1241
    if (model_find_term_value(model, eq_var) != null_value) {
3✔
1242
      continue;
×
1243
    }
1244
    // Some equalities are marked, but not solved. These we skip as they
1245
    // are already set in the model
1246
    if (preprocessor_get(pre, eq_var) == eq_var) {
3✔
1247
      continue;
×
1248
    }
1249
    term_kind_t eq_kind = term_kind(pre->terms, eq);
3✔
1250
    composite_term_t* eq_desc = get_composite(pre->terms, eq_kind, eq);
3✔
1251
    if (eq_desc->arity > 1) {
3✔
1252
      term_t eq_subst = eq_desc->arg[0] == eq_var ? eq_desc->arg[1] : eq_desc->arg[0];
1✔
1253
      model_add_substitution(model, eq_var, eq_subst);
1✔
1254
    } else {
1255
      model_add_substitution(model, eq_var, zero_term);
2✔
1256
    }
1257
  }
1258
}
29✔
1259

1260

1261
static inline
1262
void preprocessor_gc_mark_term(preprocessor_t* pre, term_t t) {
1,260✔
1263
  term_table_set_gc_mark(pre->terms, index_of(t));
1,260✔
1264
  type_table_set_gc_mark(pre->terms->types, term_type(pre->terms, t));
1,260✔
1265
}
1,260✔
1266

1267
void preprocessor_gc_mark(preprocessor_t* pre) {
6✔
1268
  uint32_t i;
1269

1270
  for (i = 0; i < pre->preprocess_map_list.size; ++ i) {
612✔
1271
    term_t t = pre->preprocess_map_list.data[i];
606✔
1272
    preprocessor_gc_mark_term(pre, t);
606✔
1273
    term_t t_pre = preprocessor_get(pre, t);
606✔
1274
    preprocessor_gc_mark_term(pre, t_pre);
606✔
1275
  }
1276

1277
  for (i = 0; i < pre->equalities_list.size; ++ i) {
16✔
1278
    term_t t = pre->equalities_list.data[i];
10✔
1279
    preprocessor_gc_mark_term(pre, t);
10✔
1280
  }
1281

1282
  for (i = 0; i < pre->purification_map_list.size; ++ i) {
25✔
1283
    term_t t = pre->purification_map_list.data[i];
19✔
1284
    preprocessor_gc_mark_term(pre, t);
19✔
1285
    term_t t_pure = int_hmap_find(&pre->purification_map, t)->val;
19✔
1286
    preprocessor_gc_mark_term(pre, t_pure);
19✔
1287
  }
1288
}
6✔
1289

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