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

SRI-CSL / yices2 / 25367146742

05 May 2026 08:57AM UTC coverage: 66.842% (+0.2%) from 66.687%
25367146742

Pull #607

github

web-flow
Merge branch 'master' into context_delegates
Pull Request #607: QF_BV context delegates (#453): config/param selection, incremental state, assumptions, and delegate regressions

34 of 43 new or added lines in 3 files covered. (79.07%)

1137 existing lines in 6 files now uncovered.

83676 of 125184 relevant lines covered (66.84%)

1645504.39 hits per line

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

51.97
/src/api/context_config.c
1
/*
2
 * This file is part of the Yices SMT Solver.
3
 * Copyright (C) 2017 SRI International.
4
 *
5
 * Yices is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * Yices is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with Yices.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18

19
/*
20
 * OBJECT TO STORE CONTEXT CONFIGURATIONS
21
 */
22

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

26
#include "api/context_config.h"
27
#include "utils/memalloc.h"
28
#include "utils/string_utils.h"
29

30

31
/*
32
 * Mapping from strings to context modes (cf. string_utils.h)
33
 */
34
static const char * const mode_names[NUM_MODES] = {
35
  "interactive",
36
  "multi-checks",
37
  "one-shot",
38
  "push-pop",
39
};
40

41
static const int32_t mode[NUM_MODES] = {
42
  CTX_MODE_INTERACTIVE,
43
  CTX_MODE_MULTICHECKS,
44
  CTX_MODE_ONECHECK,
45
  CTX_MODE_PUSHPOP,
46
};
47

48
static const char * const solver_type_names[NUM_SOLVER_TYPES] = {
49
  "dpllt",
50
  "mcsat"
51
};
52

53
static const int32_t solver_type[NUM_SOLVER_TYPES] = {
54
  CTX_SOLVER_TYPE_DPLLT,
55
  CTX_SOLVER_TYPE_MCSAT
56
};
57

58
/*
59
 * Solver codes
60
 */
61
static const char * const solver_code_names[NUM_SOLVER_CODES] = {
62
  "auto",
63
  "default",
64
  "ifw",
65
  "none",
66
  "rfw",
67
  "simplex",
68
};
69

70
static const int32_t solver_code[NUM_SOLVER_CODES] = {
71
  CTX_CONFIG_AUTO,
72
  CTX_CONFIG_DEFAULT,
73
  CTX_CONFIG_ARITH_IFW,
74
  CTX_CONFIG_NONE,
75
  CTX_CONFIG_ARITH_RFW,
76
  CTX_CONFIG_ARITH_SIMPLEX,
77
};
78

79

80
/*
81
 * Descriptor fields (other than "logic")
82
 */
83
typedef enum ctx_config_key {
84
  CTX_CONFIG_KEY_MODE,
85
  CTX_CONFIG_KEY_SOLVER_TYPE,
86
  CTX_CONFIG_KEY_TRACE_TAGS,
87
  CTX_CONFIG_KEY_ARITH_FRAGMENT,
88
  CTX_CONFIG_KEY_UF_SOLVER,
89
  CTX_CONFIG_KEY_ARRAY_SOLVER,
90
  CTX_CONFIG_KEY_BV_SOLVER,
91
  CTX_CONFIG_KEY_ARITH_SOLVER,
92
  CTX_CONFIG_KEY_MODEL_INTERPOLATION,
93
} ctx_config_key_t;
94

95
#define NUM_CONFIG_KEYS (CTX_CONFIG_KEY_MODEL_INTERPOLATION+1)
96

97

98
static const char *const config_key_names[NUM_CONFIG_KEYS] = {
99
  "arith-fragment",
100
  "arith-solver",
101
  "array-solver",
102
  "bv-solver",
103
  "mode",
104
  "model-interpolation",
105
  "solver-type",
106
  "trace",
107
  "uf-solver",
108
};
109

110
static const int32_t config_key[NUM_CONFIG_KEYS] = {
111
  CTX_CONFIG_KEY_ARITH_FRAGMENT,
112
  CTX_CONFIG_KEY_ARITH_SOLVER,
113
  CTX_CONFIG_KEY_ARRAY_SOLVER,
114
  CTX_CONFIG_KEY_BV_SOLVER,
115
  CTX_CONFIG_KEY_MODE,
116
  CTX_CONFIG_KEY_MODEL_INTERPOLATION,
117
  CTX_CONFIG_KEY_SOLVER_TYPE,
118
  CTX_CONFIG_KEY_TRACE_TAGS,
119
  CTX_CONFIG_KEY_UF_SOLVER,
120
};
121

122

123

124

125
/*
126
 * CONTEXT SETTING FOR A GIVEN LOGIC CODE
127
 */
128

129
/*
130
 * Conversion of SMT logic code to a default architecture code
131
 * -1 means not supported
132
 *
133
 * We don't use AUTO_IDL, AUTO_RDL, IFW or RFW here since
134
 * the Floyd-Warshall solvers don't support all use modes.
135
 *
136
 * IMPORTANT: this array is used by the API in config_for_logic.
137
 */
138
static const int32_t logic2arch[NUM_SMT_LOGICS] = {
139
  CTX_ARCH_NOSOLVERS,  // NONE
140

141
  -1,                  // AX
142
  -1,                  // BV  (supported by EF)
143
  -1,                  // FFA
144
  -1,                  // IDL (supported by EF)
145
  -1,                  // LIA (supported by EF)
146
  -1,                  // LRA (supported by EF)
147
  -1,                  // LIRA
148
  -1,                  // NIA
149
  -1,                  // NRA
150
  -1,                  // NIRA
151
  -1,                  // RDL
152
  -1,                  // UF
153
  -1,                  // ABV
154
  -1,                  // ALIA
155
  -1,                  // ALRA
156
  -1,                  // ALIRA
157
  -1,                  // ANIA
158
  -1,                  // ANRA
159
  -1,                  // ANIRA
160
  -1,                  // AUF
161
  -1,                  // BVLRA
162
  -1,                  // UFBV
163
  -1,                  // UFBVLIA
164
  -1,                  // UFIDL
165
  -1,                  // UFLIA
166
  -1,                  // UFLRA
167
  -1,                  // UFLIRA
168
  -1,                  // UFNIA
169
  -1,                  // UFNRA
170
  -1,                  // UFNIRA
171
  -1,                  // UFRDL
172
  -1,                  // AUFBV
173
  -1,                  // AUFBVLIA
174
  -1,                  // AUFBVNIA
175
  -1,                  // AUFLIA
176
  -1,                  // AUFLRA
177
  -1,                  // AUFLIRA
178
  -1,                  // AUFNIA
179
  -1,                  // AUFNRA
180
  -1,                  // AUFNIRA
181

182
  CTX_ARCH_EGFUN,      // QF_AX
183
  CTX_ARCH_BV,         // QF_BV
184
  CTX_ARCH_MCSAT,      // QF_FFA
185
  CTX_ARCH_SPLX,       // QF_IDL
186
  CTX_ARCH_SPLX,       // QF_LIA
187
  CTX_ARCH_SPLX,       // QF_LRA
188
  CTX_ARCH_SPLX,       // QF_LIRA
189
  CTX_ARCH_MCSAT,      // QF_NIA
190
  CTX_ARCH_MCSAT,      // QF_NRA
191
  CTX_ARCH_MCSAT,      // QF_NIRA
192
  CTX_ARCH_SPLX,       // QF_RDL
193
  CTX_ARCH_EG,         // QF_UF
194
  CTX_ARCH_EGFUNBV,    // QF_ABV
195
  CTX_ARCH_EGFUNSPLX,  // QF_ALIA
196
  CTX_ARCH_EGFUNSPLX,  // QF_ALRA
197
  CTX_ARCH_EGFUNSPLX,  // QF_ALIRA
198
  CTX_ARCH_MCSAT,      // QF_ANIA
199
  CTX_ARCH_MCSAT,      // QF_ANRA
200
  CTX_ARCH_MCSAT,      // QF_ANIRA
201
  CTX_ARCH_EGFUN,      // QF_AUF
202
  CTX_ARCH_EGSPLXBV,   // QF_BVLRA
203
  CTX_ARCH_EGBV,       // QF_UFBV
204
  CTX_ARCH_EGSPLXBV,   // QF_UFBVLIA
205

206
  CTX_ARCH_EGSPLX,     // QF_UFIDL
207
  CTX_ARCH_EGSPLX,     // QF_UFLIA
208
  CTX_ARCH_EGSPLX,     // QF_UFLRA
209
  CTX_ARCH_EGSPLX,     // QF_UFLIRA
210
  CTX_ARCH_MCSAT,      // QF_UFNIA
211
  CTX_ARCH_MCSAT,      // QF_UFNRA
212
  CTX_ARCH_MCSAT,      // QF_UFNIRA
213
  CTX_ARCH_EGSPLX,     // QF_UFRDL
214
  CTX_ARCH_EGFUNBV,    // QF_AUFBV
215
  CTX_ARCH_EGFUNSPLXBV, // QF_AUFBVLIA
216
  CTX_ARCH_MCSAT,      // QF_AUFBVNIA
217
  CTX_ARCH_EGFUNSPLX,  // QF_AUFLIA
218
  CTX_ARCH_EGFUNSPLX,  // QF_AUFLRA
219
  CTX_ARCH_EGFUNSPLX,  // QF_AUFLIRA
220
  CTX_ARCH_MCSAT,      // QF_AUFNIA
221
  CTX_ARCH_MCSAT,      // QF_AUFNRA
222
  CTX_ARCH_MCSAT,      // QF_AUFNIRA
223

224
  CTX_ARCH_EGFUNSPLXBV,  // ALL interpreted as QF_AUFLIRA + QF_BV
225
};
226

227

228

229
/*
230
 * WHICH ARITHMETIC FRAGMENTS REQUIRE THE DIOPHANTINE SUBSOLVER
231
 */
232
static const bool fragment2iflag[NUM_ARITH_FRAGMENTS+1] = {
233
  false,  // IDL
234
  false,  // RDL
235
  true,   // LIA
236
  false,  // LRA
237
  true,   // LIRA
238
  true,   // NIA
239
  false,  // NRA
240
  true,   // NIRA
241
  false,  // FFA
242
  false,  // no arithmetic
243
};
244

245

246
/*
247
 * Default configuration:
248
 * - enable PUSH/POP
249
 * - solver type = DPLL(T)
250
 * - no logic specified
251
 * - arith fragment = LIRA
252
 * - all solvers set to defaults
253
 */
254
static const ctx_config_t default_config = {
255
  CTX_MODE_PUSHPOP,       // mode
256
  CTX_SOLVER_TYPE_DPLLT,  // DPLLT solver
257
  SMT_UNKNOWN,            // logic
258
  CTX_CONFIG_DEFAULT,     // uf
259
  CTX_CONFIG_DEFAULT,     // array
260
  CTX_CONFIG_DEFAULT,     // bv
261
  CTX_CONFIG_DEFAULT,     // arith
262
  ARITH_LIRA,             // fragment
263
  false,                  // model interpolation
264
  NULL,                   // trace tags
265
};
266

267

268

269

270

271
/*
272
 * DIRECT CONFIGURATION
273
 */
274
int32_t arch_for_logic(smt_logic_t code) {
5,450✔
275
  assert(code != SMT_UNKNOWN);
276
  return logic2arch[code];
5,450✔
277
}
278

279
bool iflag_for_logic(smt_logic_t code) {
2,757✔
280
  assert(code != SMT_UNKNOWN);
281
  return fragment2iflag[arith_fragment(code)];
2,757✔
282
}
283

284

285

286
/*
287
 * CONFIG OBJECT
288
 */
289

290
/*
291
 * Initialize config to the default configuration
292
 */
293
void init_config_to_defaults(ctx_config_t *config) {
55✔
294
  *config = default_config;
55✔
295
}
55✔
296

297

298

299
/*
300
 * Set a default configuration to support the given logic
301
 * - return -1 if the logic name is not recognized
302
 * - return -2 if we don't support the logic yet
303
 * - return 0 otherwise
304
 *
305
 * If the function returns 0, the logic field is updated.
306
 * All other fields are left unchanged.
307
 */
308
int32_t config_set_logic(ctx_config_t *config, const char *logic) {
28✔
309
  smt_logic_t code;
310
  int32_t r;
311

312
  code = smt_logic_code(logic);
28✔
313
  if (code == SMT_UNKNOWN) {
28✔
UNCOV
314
    r = -1;
×
315
  } else if (logic2arch[code] < 0) {
28✔
UNCOV
316
    r = -2;
×
317
  } else {
318
    config->logic = (smt_logic_t) code;
28✔
319
    r = 0;
28✔
320
  }
321

322
  return r;
28✔
323
}
324

325

326
/*
327
 * Convert value to a solver
328
 */
UNCOV
329
static int32_t set_solver_code(const char *value, solver_code_t *dest) {
×
330
  int32_t v, r;
331

UNCOV
332
  v = parse_as_keyword(value, solver_code_names, solver_code, NUM_SOLVER_CODES);
×
UNCOV
333
  if (v < 0) {
×
UNCOV
334
    r = -2;
×
335
  } else if (v >= CTX_CONFIG_AUTO) {
×
UNCOV
336
    r = -3;
×
337
  } else {
338
    assert(v == CTX_CONFIG_DEFAULT || v == CTX_CONFIG_NONE);
339
    *dest = (solver_code_t) v;
×
340
    r = 0;
×
341
  }
342

UNCOV
343
  return r;
×
344
}
345

346

347
/*
348
 * Set an individual field in config
349
 * - key = field name
350
 * - value = value for that field
351
 *
352
 * Return code:
353
 *   -1 if the key is not recognized
354
 *   -2 if the value is not recognized
355
 *   -3 if the value is not valid for the key
356
 *    0 otherwise
357
 */
358
int32_t config_set_field(ctx_config_t *config, const char *key, const char *value) {
46✔
359
  int32_t k, v, r;
360
  arith_fragment_t arith;
361

362
  r = 0; // return code
46✔
363

364
  k = parse_as_keyword(key, config_key_names, config_key, NUM_CONFIG_KEYS);
46✔
365
  switch (k) {
46✔
366
  case CTX_CONFIG_KEY_MODE:
14✔
367
    v = parse_as_keyword(value, mode_names, mode, NUM_MODES);
14✔
368
    if (v < 0) {
14✔
UNCOV
369
      r = -2;
×
370
    } else {
371
      config->mode = v;
14✔
372
    }
373
    break;
14✔
374

375
  case CTX_CONFIG_KEY_SOLVER_TYPE:
28✔
376
    v = parse_as_keyword(value, solver_type_names, solver_type, NUM_SOLVER_TYPES);
28✔
377
    if (v < 0) {
28✔
UNCOV
378
      r = -2;
×
379
    } else {
380
      config->solver_type = v;
28✔
381
    }
382
    break;
28✔
383

384
  case CTX_CONFIG_KEY_TRACE_TAGS:
2✔
385
    config->trace_tags = safe_strdup(value);
2✔
386
    break;
2✔
387

UNCOV
388
  case CTX_CONFIG_KEY_ARITH_FRAGMENT:
×
UNCOV
389
    arith = arith_fragment_code(value);
×
UNCOV
390
    if (arith == ARITH_NONE) {
×
UNCOV
391
      r = -2;
×
392
    } else {
UNCOV
393
      config->arith_fragment = arith;
×
394
    }
395
    break;
×
396

397
  case CTX_CONFIG_KEY_UF_SOLVER:
×
UNCOV
398
    r = set_solver_code(value, &config->uf_config);
×
399
    break;
×
400

401
  case CTX_CONFIG_KEY_ARRAY_SOLVER:
×
UNCOV
402
    r = set_solver_code(value, &config->array_config);
×
403
    break;
×
404

405
  case CTX_CONFIG_KEY_BV_SOLVER:
×
UNCOV
406
    r = set_solver_code(value, &config->bv_config);
×
407
    break;
×
408

409
  case CTX_CONFIG_KEY_ARITH_SOLVER:
×
UNCOV
410
    v = parse_as_keyword(value, solver_code_names, solver_code, NUM_SOLVER_CODES);
×
411
    if (v < 0) {
×
412
      r = -2;
×
413
    } else {
414
      assert(0 <= v && v <= NUM_SOLVER_CODES);
415
      config->arith_config = v;
×
416
    }
417
    break;
×
418
  case CTX_CONFIG_KEY_MODEL_INTERPOLATION:
2✔
419
    v = parse_as_boolean(value, &config->model_interpolation);
2✔
420
    if (v < 0) {
2✔
421
      r = -2;
×
422
    }
423
    break;
2✔
UNCOV
424
  default:
×
425
    assert(k == -1);
UNCOV
426
    r = -1;
×
427
    break;
×
428
  }
429

430
  return r;
46✔
431
}
432

433

434

435
/*
436
 * Auxiliary functions to build architecture codes incrementally
437
 * - each function takes an integer a: a is either a valid architecture
438
 *   code or -1
439
 * - then the function adds a new solver component to a: this results
440
 *   in either a new valid code or -1 if the new component is not compatible with a.
441
 *
442
 * Important: we assume that the components are added in the following
443
 * order: egraph, array solver, bitvector solver, arithmetic solver
444
 */
445
static inline int32_t arch_add_egraph(int32_t a) {
4✔
446
  if (a == CTX_ARCH_NOSOLVERS) {
4✔
447
    a = CTX_ARCH_EG;
4✔
448
  } else {
UNCOV
449
    a = -1;
×
450
  }
451
  return a;
4✔
452
}
453

454
static int32_t arch_add_array(int32_t a) {
4✔
455
  if (a == CTX_ARCH_EG || a == CTX_ARCH_NOSOLVERS) {
4✔
456
    a = CTX_ARCH_EGFUN; // array requires egraph so we add both implicitly
4✔
457
  } else {
UNCOV
458
    a = -1;
×
459
  }
460
  return a;
4✔
461
}
462

463
static int32_t arch_add_bv(int32_t a) {
4✔
464
  switch (a) {
4✔
UNCOV
465
  case CTX_ARCH_NOSOLVERS:
×
466
    a = CTX_ARCH_BV;
×
UNCOV
467
    break;
×
468

UNCOV
469
  case CTX_ARCH_EG:
×
UNCOV
470
    a = CTX_ARCH_EGBV;
×
UNCOV
471
    break;
×
472

473
  case CTX_ARCH_EGFUN:
4✔
474
    a = CTX_ARCH_EGFUNBV;
4✔
475
    break;
4✔
476

UNCOV
477
  case CTX_ARCH_SPLX:
×
UNCOV
478
    a = CTX_ARCH_EGSPLXBV;
×
UNCOV
479
    break;
×
480

UNCOV
481
  default:
×
482
    a = -1;
×
483
    break;
×
484
  }
485

486
  return a;
4✔
487
}
488

489
// add the simplex solver
490
static int32_t arch_add_simplex(int32_t a) {
4✔
491
  switch (a) {
4✔
UNCOV
492
  case CTX_ARCH_NOSOLVERS:
×
UNCOV
493
    a = CTX_ARCH_SPLX;
×
494
    break;
×
495

496
  case CTX_ARCH_BV:
×
UNCOV
497
    a = CTX_ARCH_EGSPLXBV;
×
498
    break;
×
499

500
  case CTX_ARCH_EG:
×
UNCOV
501
    a = CTX_ARCH_EGSPLX;
×
UNCOV
502
    break;
×
503

UNCOV
504
  case CTX_ARCH_EGFUN:
×
UNCOV
505
    a = CTX_ARCH_EGFUNSPLX;
×
UNCOV
506
    break;
×
507

UNCOV
508
  case CTX_ARCH_EGBV:
×
509
    a = CTX_ARCH_EGSPLXBV;
×
510
    break;
×
511

512
  case CTX_ARCH_EGFUNBV:
4✔
513
    a = CTX_ARCH_EGFUNSPLXBV;
4✔
514
    break;
4✔
515

UNCOV
516
  default:
×
517
    a = -1;
×
518
    break;
×
519
  }
520

521
  return a;
4✔
522
}
523

524
// add a Floyd-Warshall solver
525
static int32_t arch_add_ifw(int32_t a) {
×
526
  if (a == CTX_ARCH_NOSOLVERS) {
×
527
    a = CTX_ARCH_IFW;
×
528
  } else {
UNCOV
529
    a = -1;
×
530
  }
UNCOV
531
  return a;
×
532
}
533

534
static int32_t arch_add_rfw(int32_t a) {
×
535
  if (a == CTX_ARCH_NOSOLVERS) {
×
UNCOV
536
    a = CTX_ARCH_RFW;
×
537
  } else {
UNCOV
538
    a = -1;
×
539
  }
UNCOV
540
  return a;
×
541
}
542

543

544
// add solver identified by code c to a
545
static int32_t arch_add_arith(int32_t a, solver_code_t c) {
4✔
546
  switch (c) {
4✔
UNCOV
547
  case CTX_CONFIG_NONE:  // no arithmetic solver
×
548
    break;
×
549

550
  case CTX_CONFIG_DEFAULT:  // simplex is the default
4✔
551
  case CTX_CONFIG_AUTO:     // auto = simplex here too
552
  case CTX_CONFIG_ARITH_SIMPLEX:
553
    a = arch_add_simplex(a);
4✔
554
    break;
4✔
555

UNCOV
556
  case CTX_CONFIG_ARITH_IFW:
×
557
    a = arch_add_ifw(a);
×
UNCOV
558
    break;
×
559

UNCOV
560
  case CTX_CONFIG_ARITH_RFW:
×
UNCOV
561
    a = arch_add_rfw(a);
×
UNCOV
562
    break;
×
563
  }
564
  return a;
4✔
565
}
566

567

568
/*
569
 * Check whether the architecture code a is compatible with mode
570
 * - current restriction: IFW and RFW don't support PUSH/POP or MULTIPLE CHECKS
571
 */
572
static bool arch_supports_mode(context_arch_t a, context_mode_t mode) {
4✔
573
  return (a != CTX_ARCH_IFW && a != CTX_ARCH_RFW) || mode == CTX_MODE_ONECHECK;
4✔
574
}
575

576

577
/*
578
 * Check whether the architecture is supported.
579
 */
580
static bool arch_is_supported(context_arch_t a) {
51✔
581
#if HAVE_MCSAT
582
  return true; // all architectures are supported
51✔
583
#else
584
  return a != CTX_ARCH_MCSAT;
585
#endif
586
}
587

588

589
/*
590
 * Check whether config is valid (and supported by this version of Yices)
591
 * and convert it to a tuple (arch, mode, iflag, qflag)
592
 * - arch = architecture code as defined in context.h
593
 * - mode = one of the context's modes
594
 * - iflag = true if the integer solver (in simplex) is required
595
 * - qflag = true if support for quantifiers is required
596
 *
597
 * Return code:
598
 *   0 if the config is valid and supported
599
 *  -1 if the config is invalid
600
 *  -2 if the config is valid but not currently supported
601
 *  -3 if the solver combination is valid but does not support the specified mode
602
 */
603
int32_t decode_config(const ctx_config_t *config, smt_logic_t *logic, context_arch_t *arch, context_mode_t *mode, bool *iflag, bool *qflag) {
55✔
604
  smt_logic_t logic_code;
605
  int32_t a, r;
606

607
  r = 0; // default return code
55✔
608

609
  logic_code = config->logic;
55✔
610
  if (logic_code != SMT_UNKNOWN) {
55✔
611
    /*
612
     * The intended logic is specified
613
     */
614
    assert(0 <= logic_code && logic_code < NUM_SMT_LOGICS);
615

616
    /*
617
     * Special case: difference logic + mode = ONECHECK + arith_config == AUTO
618
     */
619
    if (config->arith_config == CTX_CONFIG_AUTO && config->mode == CTX_MODE_ONECHECK) {
28✔
UNCOV
620
      if (logic_code == QF_IDL) {
×
UNCOV
621
        *logic = QF_IDL;
×
UNCOV
622
        *arch = CTX_ARCH_AUTO_IDL;
×
UNCOV
623
        *mode = CTX_MODE_ONECHECK;
×
UNCOV
624
        *iflag = false;
×
UNCOV
625
        *qflag = false;
×
UNCOV
626
        goto done;
×
627
      }
628

UNCOV
629
      if (logic_code == QF_RDL) {
×
UNCOV
630
        *logic = QF_RDL;
×
UNCOV
631
        *arch = CTX_ARCH_AUTO_RDL;
×
UNCOV
632
        *mode = CTX_MODE_ONECHECK;
×
UNCOV
633
        *iflag = false;
×
UNCOV
634
        *qflag = false;
×
UNCOV
635
        goto done;
×
636
      }
637
    }
638

639
    a = logic2arch[logic_code];
28✔
640
    if (a < 0 || !arch_is_supported(a)) {
28✔
641
      // not supported
642
      r = -2;
×
643
    } else {
644
      // good configuration
645
      *logic = logic_code;
28✔
646
      *arch = (context_arch_t) a;
28✔
647
      *iflag = iflag_for_logic(logic_code);
28✔
648
      *qflag = qflag_for_logic(logic_code);
28✔
649
      *mode = config->mode;
28✔
650
    }
651

652
  } else if (config->solver_type == CTX_SOLVER_TYPE_MCSAT) {
27✔
653
    if (arch_is_supported(CTX_ARCH_MCSAT)) {
23✔
654
      /*
655
       * MCSAT solver/no logic specified
656
       */
657
      *logic = SMT_UNKNOWN;
23✔
658
      *arch = CTX_ARCH_MCSAT;
23✔
659
      *mode = CTX_MODE_PUSHPOP;
23✔
660
      *iflag = false;
23✔
661
      *qflag = false;
23✔
662
    } else {
663
      // not compiled with MCSAT support so this is not supported
UNCOV
664
      r = -2;
×
665
    }
666

667
  } else {
668
    /*
669
     * No logic specified.
670
     */
671

672
    a = CTX_ARCH_NOSOLVERS;
4✔
673
    if (config->uf_config == CTX_CONFIG_DEFAULT) {
4✔
674
      a = arch_add_egraph(a);
4✔
675
    }
676
    if (config->array_config == CTX_CONFIG_DEFAULT) {
4✔
677
      a = arch_add_array(a);
4✔
678
    }
679
    if (config->bv_config == CTX_CONFIG_DEFAULT) {
4✔
680
      a = arch_add_bv(a);
4✔
681
    }
682
    a = arch_add_arith(a, config->arith_config);
4✔
683

684
    // a is either -1 or an architecture code
685
    if (a < 0) {
4✔
UNCOV
686
      r = -1; // invalid combination of solvers
×
687
    } else if (arch_supports_mode(a, config->mode)) {
4✔
688
      // good configuration
689
      *logic = SMT_UNKNOWN;
4✔
690
      *arch = (context_arch_t) a;
4✔
691
      *iflag = fragment2iflag[config->arith_fragment];
4✔
692
      *qflag = false;
4✔
693
      *mode = config->mode;
4✔
694
    } else {
695
      // mode is not supported by the solvers
UNCOV
696
      r = -3;
×
697
    }
698
  }
699

700
 done:
55✔
701
  return r;
55✔
702
}
703

704

705
/*
706
 * Cleanup a configutation descriptor
707
 */
708
void delete_config(ctx_config_t *config) {
54✔
709
  safe_free(config->trace_tags);
54✔
710
}
54✔
711

712

713
/*
714
 * Check whether a logic is supported by the MCSAT solver
715
 */
716
bool logic_is_supported_by_mcsat(smt_logic_t code) {
509✔
717
  return code == SMT_ALL || !logic_has_quantifiers(code);
509✔
718
}
719

720
/*
721
 * Check whether a logic requires the MCSAT solver
722
 */
723
bool logic_requires_mcsat(smt_logic_t code) {
1,631✔
724
  return arch_for_logic(code) == CTX_ARCH_MCSAT;
1,631✔
725
}
726

727
/*
728
 * Check whether a logic is supported by the exists/forall solver
729
 * - logics with quantifiers and BV or linear arithmetic are supported
730
 * - logic "NONE" == purely Boolean is supported too
731
 */
732
bool logic_is_supported_by_ef(smt_logic_t code) {
1,631✔
733
  return code == NONE || code == BV || code == IDL || code == LRA || code == RDL || code == LIA || code == UF;
1,631✔
734
}
735

736

737
/*
738
 * Context architecture for a logic supported by EF
739
 */
740
int32_t ef_arch_for_logic(smt_logic_t code) {
694✔
741
  switch (code) {
694✔
UNCOV
742
  case NONE:
×
UNCOV
743
    return CTX_ARCH_NOSOLVERS;
×
744

745
  case UF:
114✔
746
    return CTX_ARCH_EG;
114✔
747

748
  case BV:
24✔
749
    return CTX_ARCH_BV;
24✔
750

751
  case IDL:
556✔
752
  case LRA:
753
  case RDL:
754
  case LIA:
755
    return CTX_ARCH_SPLX;
556✔
756

UNCOV
757
  default:
×
UNCOV
758
    return -1;
×
759
  }
760
}
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