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

SRI-CSL / yices2 / 9225134568

24 May 2024 01:57PM UTC coverage: 64.72% (-1.0%) from 65.728%
9225134568

Pull #513

github

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

818 of 3223 new or added lines in 59 files covered. (25.38%)

14 existing lines in 10 files now uncovered.

80132 of 123813 relevant lines covered (64.72%)

1493950.84 hits per line

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

68.4
/src/parser_utils/term_stack2.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
 * Stack-based API for building terms and types
21
 * Intended to support parsing.
22
 */
23

24
#if defined(CYGWIN) || defined(MINGW)
25
#ifndef __YICES_DLLSPEC__
26
#define __YICES_DLLSPEC__ __declspec(dllexport)
27
#endif
28
#endif
29

30
#include <assert.h>
31
#include <string.h>
32

33
#include "parser_utils/term_stack2.h"
34

35
#include "api/yices_extensions.h"
36
#include "api/yices_api_lock_free.h"
37
#include "api/yices_globals.h"
38
#include "parser_utils/tstack_internals.h"
39
#include "terms/bv64_constants.h"
40
#include "terms/bvarith64_buffer_terms.h"
41
#include "terms/bvarith_buffer_terms.h"
42
#include "terms/rba_buffer_terms.h"
43
#include "utils/hash_functions.h"
44

45
#include "yices.h"
46

47
#ifndef NDEBUG
48
#include <stdio.h>
49
#include <inttypes.h>
50

51
#include "io/type_printer.h"
52
#include "io/term_printer.h"
53
#endif
54

55

56
/****************
57
 *  EXCEPTIONS  *
58
 ***************/
59

60
/*
61
 * Exception raised when processing element e
62
 * - stack->error_pos is set to e->pos
63
 * - stack->error_op is set to stack->top_op
64
 * - stack->error_string is set to e's string field if e is a symbol or a string
65
 *   or a binding, or to NULL otherwise.
66
 * code is returned to exception handler by longjmp
67
 */
68
void __attribute__((noreturn)) raise_exception(tstack_t *stack, stack_elem_t *e, int code) {
×
69
  stack->error_loc = e->loc;
×
70
  stack->error_op = stack->top_op;
×
71
  switch (e->tag) {
×
72
  case TAG_SYMBOL:
×
73
  case TAG_STRING:
74
    stack->error_string = e->val.string;
×
75
    break;
×
76
  case TAG_BINDING:
×
77
    stack->error_string = e->val.binding.symbol;
×
78
    break;
×
79
  case TAG_TYPE_BINDING:
×
80
    stack->error_string = e->val.type_binding.symbol;
×
81
    break;
×
82
  default:
×
83
    stack->error_string = NULL;
×
84
    break;
×
85
  }
86
  longjmp(stack->env, code);
×
87
}
88

89
/*
90
 * Exception on a push_op operation
91
 * - loc = corresponding loc
92
 * - code = error code
93
 */
94
#ifndef NDEBUG
95
static void __attribute__((noreturn)) bad_op_exception(tstack_t *stack, loc_t *loc, uint32_t op) {
96
  stack->error_loc = *loc;
97
  stack->error_op = op;
98
  stack->error_string = NULL;
99
  longjmp(stack->env, TSTACK_INVALID_OP);
100
}
101
#endif
102

103

104
/*
105
 * Bad format or other error on a push_rational, push_float, push_bvbin, push_hexbin operation, etc.
106
 */
107
void __attribute__((noreturn)) push_exception(tstack_t *stack, loc_t *loc, char *s, int code) {
2✔
108
  stack->error_loc = *loc;
2✔
109
  stack->error_op = NO_OP;
2✔
110
  stack->error_string = s;
2✔
111
  longjmp(stack->env, code);
2✔
112
}
113

114
/*
115
 * Translate a yices error into an exception.
116
 */
117
void __attribute__((noreturn)) report_yices_error(tstack_t *stack) {
1✔
118
  uint32_t i;
119

120
  i = stack->frame;
1✔
121
  stack->error_loc = stack->elem[i].loc;
1✔
122
  stack->error_op = stack->top_op;
1✔
123
  stack->error_string = NULL;
1✔
124
  longjmp(stack->env, TSTACK_YICES_ERROR);
1✔
125
}
126

127

128
/********************
129
 *  OPERATOR TABLE  *
130
 *******************/
131

132
/*
133
 * Allocate a table of size n
134
 */
135
static void alloc_op_table(op_table_t *table, uint32_t n) {
1,666✔
136
  assert(n <= MAX_OP_TABLE_SIZE);
137
  table->assoc = (uint8_t *) safe_malloc(n * sizeof(uint8_t));
1,666✔
138
  table->eval = (eval_fun_t *) safe_malloc(n * sizeof(eval_fun_t));
1,666✔
139
  table->check = (check_fun_t *) safe_malloc(n * sizeof(check_fun_t));
1,666✔
140
  table->num_ops = 0;
1,666✔
141
  table->size = n;
1,666✔
142
}
1,666✔
143

144
/*
145
 * Delete
146
 */
147
static void delete_op_table(op_table_t *table) {
1,666✔
148
  safe_free(table->assoc);
1,666✔
149
  safe_free(table->eval);
1,666✔
150
  safe_free(table->check);
1,666✔
151
  table->assoc = NULL;
1,666✔
152
  table->eval = NULL;
1,666✔
153
  table->check = NULL;
1,666✔
154
}
1,666✔
155

156

157
/**************************
158
 *  STACK INITIALIZATION  *
159
 *************************/
160

161
/*
162
 * Initialize stack:
163
 * - nops = size of the operator table
164
 */
165
static void alloc_tstack(tstack_t *stack, uint32_t nops) {
1,666✔
166
  uint32_t n;
167
  stack_elem_t *tmp;
168

169
  n = DEFAULT_TERM_STACK_SIZE;
1,666✔
170
  tmp = (stack_elem_t *) safe_malloc(n * sizeof(stack_elem_t));
1,666✔
171

172
  // mark bottom element
173
  tmp->tag = TAG_OP;
1,666✔
174
  tmp->val.opval.opcode = NO_OP;
1,666✔
175
  tmp->val.opval.multiplicity = 0;
1,666✔
176
  tmp->val.opval.prev = 0;
1,666✔
177

178
  stack->elem = tmp;
1,666✔
179
  stack->top = 1;
1,666✔
180
  stack->size = n;
1,666✔
181
  stack->frame = 0;
1,666✔
182
  stack->top_op = NO_OP;
1,666✔
183

184
  alloc_op_table(&stack->op_table, nops);
1,666✔
185

186
  init_arena(&stack->mem);
1,666✔
187

188
  stack->aux_buffer = (int32_t *) safe_malloc(DEFAULT_AUX_SIZE * sizeof(int32_t));
1,666✔
189
  stack->aux_size = DEFAULT_AUX_SIZE;
1,666✔
190

191
  stack->sbuffer = NULL;
1,666✔
192
  stack->sbuffer_size = 0;
1,666✔
193

194
  stack->name_buffer = NULL;
1,666✔
195
  stack->name_buffer_size = 0;
1,666✔
196

197
  init_bvconstant(&stack->bvconst_buffer);
1,666✔
198

199
  stack->abuffer = NULL;
1,666✔
200
  stack->bva64buffer = NULL;
1,666✔
201
  stack->bvabuffer = NULL;
1,666✔
202
  stack->bvlbuffer = NULL;
1,666✔
203

204
  stack->tvar_id = 0;
1,666✔
205

206
  stack->avtbl = NULL;
1,666✔
207

208
  stack->error_op = NO_OP;
1,666✔
209
  stack->error_loc.line = 0;
1,666✔
210
  stack->error_loc.column = 0;
1,666✔
211
  stack->error_string = NULL;
1,666✔
212
}
1,666✔
213

214

215
/*
216
 * Extend: increase size by 50%
217
 */
218
static void tstack_extend(tstack_t *stack) {
953✔
219
  uint32_t n;
220

221
  n = stack->size + 1;
953✔
222
  n += n >> 1;
953✔
223

224
  if (n > MAX_TERM_STACK_SIZE) {
953✔
225
    out_of_memory();
×
226
  }
227

228
  stack->elem = (stack_elem_t *) safe_realloc(stack->elem, n * sizeof(stack_elem_t));
953✔
229
  stack->size = n;
953✔
230
}
953✔
231

232

233
/*
234
 * Return top index and extend the stack if it's full
235
 * also increment top.
236
 */
237
static uint32_t tstack_get_top(tstack_t *stack) {
3,161,076✔
238
  uint32_t i;
239

240
  i = stack->top;
3,161,076✔
241
  stack->top ++;
3,161,076✔
242
  if (i >= stack->size) {
3,161,076✔
243
    tstack_extend(stack);
953✔
244
    assert(i < stack->size);
245
  }
246
  return i;
3,161,076✔
247
}
248

249
/*
250
 * Same thing but return a pointer to element i
251
 */
252
static stack_elem_t *tstack_get_topelem(tstack_t *stack) {
1,755,678✔
253
  uint32_t k;
254
  // The order is important: tstack_get_top has side effects
255
  // (including changing stack->elem)!!
256
  k = tstack_get_top(stack);
1,755,678✔
257
  return stack->elem + k;
1,755,678✔
258
}
259

260

261

262

263

264
/*********************
265
 *  PUSH OPERATIONS  *
266
 ********************/
267

268
/*
269
 * Push op: create a new frame and push the operator.
270
 *
271
 * For special operators (such that assoc[op] == 1) , if the current
272
 * top-operator is identical to op, then we just increment its
273
 * multiplicity index.
274
 *
275
 * If op is BIND, then top-op must be LET.
276
 * If op is DECLARE_VAR, then top-op must be MK_EXISTS or MK_FORALL or MK_LAMBDA
277
 *
278
 * For all operators except BIND, DECLARE_VAR, and DECLARE_TYPE_VAR,
279
 * we also open a new scope in the arena. For BIND the arena scope
280
 * remains the one open by the enclosing LET. For DECLARE_VAR, it's
281
 * the one of the enclosing FORALL, EXISTS, or LAMBDA. For
282
 * DECLARE_TYPE_VAR, it's also the one open by the enclosing operator
283
 * (must be something like SMT LIB 2's define-sort).
284
 *
285
 * NOTE: in SMT-LIB 2, we can have DECLARE_VAR inside a define-fun
286
 * operation.
287
 */
288
void tstack_push_op(tstack_t *stack, int32_t op, loc_t *loc) {
1,455,044✔
289
  uint32_t i;
290
  stack_elem_t *e;
291

292
#ifndef NDEBUG
293
  if (op < 0 ||
294
      op >= stack->op_table.num_ops ||
295
      stack->op_table.check[op] == NULL ||
296
      stack->op_table.eval[op] == NULL) {
297
    bad_op_exception(stack, loc, op);
298
  }
299
#endif
300

301
  if (stack->op_table.assoc[op] && stack->top_op == op) {
1,455,044✔
302
    i = stack->frame;
49,646✔
303
    stack->elem[i].val.opval.multiplicity ++;
49,646✔
304
    return;
49,646✔
305
  }
306

307
  i = tstack_get_top(stack);
1,405,398✔
308
  e = stack->elem + i;
1,405,398✔
309
  e->tag = TAG_OP;
1,405,398✔
310
  e->val.opval.opcode = op;
1,405,398✔
311
  e->val.opval.prev = stack->frame;
1,405,398✔
312
  e->val.opval.multiplicity = 0;
1,405,398✔
313
  e->loc = *loc;
1,405,398✔
314
  stack->top_op = op;
1,405,398✔
315
  stack->frame = i;
1,405,398✔
316

317
  if (op != BIND && op != DECLARE_VAR && op != DECLARE_TYPE_VAR) {
1,405,398✔
318
    // mark start of new scope
319
    arena_push(&stack->mem);
1,232,658✔
320
  }
321
}
322

323

324
/*
325
 * Push opcode on top of the stack. Don't create a new frame.
326
 * Don't open a new scope in the arena.
327
 */
328
void tstack_push_opcode(tstack_t *stack, int32_t op, loc_t *loc) {
×
329
  stack_elem_t *e;
330

331
#ifndef NDEBUG
332
  if (op < 0 || op >= stack->op_table.num_ops) {
333
    bad_op_exception(stack, loc, op);
334
  }
335
#endif
336

337
  e = tstack_get_topelem(stack);
×
338
  e->tag = TAG_OPCODE;
×
339
  e->val.op = op;
×
340
  e->loc = *loc;
×
341
}
×
342

343
/*
344
 * Push a copy of string s, n = length of s
345
 * - tag = type of string (either TAG_STRING or TAG_SYMBOL)
346
 */
347
void tstack_push_str(tstack_t *stack, tag_t tag, char *s, uint32_t n, loc_t *loc) {
408,808✔
348
  char *tmp;
349
  stack_elem_t *e;
350

351
  assert(strlen(s) == n);
352

353
  tmp = (char *) arena_alloc(&stack->mem, n + 1);
408,808✔
354
  strcpy(tmp, s);
408,808✔
355
  e = tstack_get_topelem(stack);
408,808✔
356
  e->tag = tag;
408,808✔
357
  e->val.string = tmp;
408,808✔
358
  e->loc = *loc;
408,808✔
359
}
408,808✔
360

361

362
/*
363
 * For define-type or define term: push a name s on the stack.
364
 *
365
 * These functions are like push_symbol but they raise an exception if
366
 * name is already used (TSTACK_TYPENAME_REDEF, TSTACK_TERMNAME_REDEF,
367
 * or TSTACK_MACRO_REDEF)
368
 */
369
void tstack_push_free_typename(tstack_t *stack, char *s, uint32_t n, loc_t *loc) {
58✔
370
  if (_o_yices_get_type_by_name(s) != NULL_TYPE) {
58✔
371
    push_exception(stack, loc, s, TSTACK_TYPENAME_REDEF);
×
372
  }
373
  tstack_push_str(stack, TAG_SYMBOL, s, n, loc);
58✔
374
}
58✔
375

376
void tstack_push_free_termname(tstack_t *stack, char *s, uint32_t n, loc_t *loc) {
99,093✔
377
  if (_o_yices_get_term_by_name(s) != NULL_TERM) {
99,093✔
378
    push_exception(stack, loc, s, TSTACK_TERMNAME_REDEF);
×
379
  }
380
  tstack_push_str(stack, TAG_SYMBOL, s, n, loc);
99,093✔
381
}
99,093✔
382

383
void tstack_push_free_macroname(tstack_t *stack, char *s, uint32_t n, loc_t *loc) {
×
384
  if (yices_get_macro_by_name(s) >= 0) {
×
385
    push_exception(stack, loc, s, TSTACK_MACRO_REDEF);
×
386
  }
387
  tstack_push_str(stack, TAG_SYMBOL, s, n, loc);
×
388
}
×
389

390
/*
391
 * Variant: raise exception (TSTACK_TYPENAME_REDEF) if s is already
392
 * used either as a type or as a macro name
393
 */
394
void tstack_push_free_type_or_macro_name(tstack_t *stack, char *s, uint32_t n, loc_t *loc) {
360✔
395
  if (_o_yices_get_type_by_name(s) != NULL_TYPE || yices_get_macro_by_name(s) >= 0) {
360✔
396
    push_exception(stack, loc, s, TSTACK_TYPENAME_REDEF);
×
397
  }
398
  tstack_push_str(stack, TAG_SYMBOL, s, n, loc);
360✔
399
}
360✔
400

401

402
/*
403
 * Convert a string to a rational and push that
404
 * - s must be null-terminated and of rational or floating point formats
405
 */
406
void tstack_push_rational(tstack_t *stack, char *s, loc_t *loc) {
305,272✔
407
  stack_elem_t *e;
408
  int code;
409

410
  e = tstack_get_topelem(stack);
305,272✔
411
  e->tag = TAG_RATIONAL;
305,272✔
412
  e->loc = *loc;
305,272✔
413
  q_init(&e->val.rational);
305,272✔
414
  code = q_set_from_string(&e->val.rational, s);
305,272✔
415
  if (code < 0) {
305,272✔
416
    // -1 means that the format is wrong
417
    // -2 means that the denominator is zero
418
    if (code == -1) {
×
419
      push_exception(stack, loc, s, TSTACK_RATIONAL_FORMAT);
×
420
    } else {
421
      assert(code == -2);
422
      push_exception(stack, loc, s, TSTACK_DIVIDE_BY_ZERO);
×
423
    }
424
  }
425
}
305,272✔
426

427
void tstack_push_float(tstack_t *stack, char *s, loc_t *loc) {
10,383✔
428
  stack_elem_t *e;
429
  int code;
430

431
  e = tstack_get_topelem(stack);
10,383✔
432
  e->tag = TAG_RATIONAL;
10,383✔
433
  e->loc = *loc;
10,383✔
434
  q_init(&e->val.rational);
10,383✔
435
  code = q_set_from_float_string(&e->val.rational, s);
10,383✔
436
  if (code < 0) {
10,383✔
437
    push_exception(stack, loc, s, TSTACK_FLOAT_FORMAT);
×
438
  }
439
}
10,383✔
440

441

442
/*
443
 * Push a small bitvector constant:
444
 * - n = bitsize (1 <= n <= 64)
445
 * - c = value
446
 */
447
static void tstack_push_bv64(tstack_t *stack, uint32_t n, uint64_t c, loc_t *loc) {
14,081✔
448
  stack_elem_t *e;
449

450
  assert(1 <= n && n <= 64 && c == norm64(c, n));
451

452
  e = tstack_get_topelem(stack);
14,081✔
453
  e->tag = TAG_BV64;
14,081✔
454
  e->val.bv64.bitsize = n;
14,081✔
455
  e->val.bv64.value = c;
14,081✔
456
  e->loc = *loc;
14,081✔
457
}
14,081✔
458

459

460
/*
461
 * Push a generic bitvector constant
462
 * - n = bitsize (n > 64)
463
 * - c = value as an array of words
464
 */
465
static void tstack_push_bv(tstack_t *stack, uint32_t n, uint32_t *c, loc_t *loc) {
28✔
466
  stack_elem_t *e;
467

468
  assert(n > 64);
469

470
  e = tstack_get_topelem(stack);
28✔
471
  e->tag = TAG_BV;
28✔
472
  e->val.bv.bitsize = n;
28✔
473
  e->val.bv.data = c;
28✔
474
  e->loc = *loc;
28✔
475
}
28✔
476

477

478
/*
479
 * Convert a string to a bitvector constant and push that
480
 * - n = length of the string
481
 * - s must be a string of binary or hexadecimal digits (no prefix)
482
 */
483
void tstack_push_bvbin(tstack_t *stack, char *s, uint32_t n, loc_t *loc) {
14,089✔
484
  uint32_t k;
485
  int code;
486
  uint32_t *tmp;
487
  uint64_t c;
488

489
  if (n > 64) {
14,089✔
490
    // large constant
491
    k = (n + 31) >> 5; // number of words
28✔
492
    tmp = bvconst_alloc(k);
28✔
493
    code = bvconst_set_from_string(tmp, n, s);
28✔
494
    if (code < 0) goto error;
28✔
495

496
    bvconst_normalize(tmp, n);
28✔
497
    tstack_push_bv(stack, n, tmp, loc);
28✔
498

499
  } else {
500
    // small constant
501
    code = bvconst64_set_from_string(&c, n, s);
14,061✔
502
    if (code < 0) goto error;
14,061✔
503
    tstack_push_bv64(stack, n, c, loc);
14,061✔
504
  }
505
  return;
14,089✔
506

507
 error:
×
508
  push_exception(stack, loc, s, TSTACK_BVBIN_FORMAT);
×
509
}
510

511
void tstack_push_bvhex(tstack_t *stack, char *s, uint32_t n, loc_t *loc) {
20✔
512
  uint32_t k;
513
  int code;
514
  uint32_t *tmp;
515
  uint64_t c;
516

517
  if (n > 16) {
20✔
518
    // large constant
519
    k = (n + 7) >> 3; // number of words
×
520
    tmp = bvconst_alloc(k);
×
521
    code = bvconst_set_from_hexa_string(tmp, n, s);
×
522
    if (code < 0) goto error;
×
523

524
    bvconst_normalize(tmp, 4 * n);
×
525
    tstack_push_bv(stack, 4 * n, tmp, loc);
×
526

527
  } else {
528
    // small constant
529
    code = bvconst64_set_from_hexa_string(&c, n, s);
20✔
530
    if (code < 0) goto error;
20✔
531
    tstack_push_bv64(stack, 4 * n, c, loc);
20✔
532
  }
533
  return;
20✔
534

535
 error:
×
536
  push_exception(stack, loc, s, TSTACK_BVHEX_FORMAT);
×
537
}
538

539

540
/*
541
 * Convert a name to a type or a term and push the type or term on the stack
542
 */
543
void tstack_push_type_by_name(tstack_t *stack, char *s, loc_t *loc) {
14,816✔
544
  stack_elem_t *e;
545
  type_t tau;
546

547
  tau = _o_yices_get_type_by_name(s);
14,816✔
548
  if (tau == NULL_TYPE) push_exception(stack, loc, s, TSTACK_UNDEF_TYPE);
14,816✔
549

550
  e = tstack_get_topelem(stack);
14,816✔
551
  e->tag = TAG_TYPE;
14,816✔
552
  e->val.type = tau;
14,816✔
553
  e->loc = *loc;
14,816✔
554
}
14,816✔
555

556
void tstack_push_term_by_name(tstack_t *stack, char *s, loc_t *loc) {
952,586✔
557
  stack_elem_t *e;
558
  term_t t;
559

560
  t = _o_yices_get_term_by_name(s);
952,586✔
561
  if (t == NULL_TERM) push_exception(stack, loc, s, TSTACK_UNDEF_TERM);
952,586✔
562

563
  e = tstack_get_topelem(stack);
952,584✔
564
  e->tag = TAG_TERM;
952,584✔
565
  e->val.term = t;
952,584✔
566
  e->loc = *loc;
952,584✔
567
}
952,584✔
568

569
void tstack_push_macro_by_name(tstack_t *stack, char *s, loc_t *loc) {
×
570
  stack_elem_t *e;
571
  int32_t id;
572

573
  id = yices_get_macro_by_name(s);
×
574
  if (id < 0) push_exception(stack, loc, s, TSTACK_UNDEF_MACRO);
×
575

576
  e = tstack_get_topelem(stack);
×
577
  e->tag = TAG_MACRO;
×
578
  e->val.macro = id;
×
579
  e->loc = *loc;
×
580
}
×
581

582

583
/*
584
 * Push primitive types or terms
585
 */
586
void tstack_push_bool_type(tstack_t *stack, loc_t *loc) {
3,045✔
587
  stack_elem_t *e;
588

589
  e = tstack_get_topelem(stack);
3,045✔
590
  e->tag = TAG_TYPE;
3,045✔
591
  e->val.type = _o_yices_bool_type();
3,045✔
592
  e->loc = *loc;
3,045✔
593
}
3,045✔
594

595
void tstack_push_int_type(tstack_t *stack, loc_t *loc) {
4✔
596
  stack_elem_t *e;
597

598
  e = tstack_get_topelem(stack);
4✔
599
  e->tag = TAG_TYPE;
4✔
600
  e->val.type = _o_yices_int_type();
4✔
601
  e->loc = *loc;
4✔
602
}
4✔
603

604
void tstack_push_real_type(tstack_t *stack, loc_t *loc) {
184✔
605
  stack_elem_t *e;
606

607
  e = tstack_get_topelem(stack);
184✔
608
  e->tag = TAG_TYPE;
184✔
609
  e->val.type = _o_yices_real_type();
184✔
610
  e->loc = *loc;
184✔
611
}
184✔
612

613
void tstack_push_true(tstack_t *stack, loc_t *loc) {
16✔
614
  stack_elem_t *e;
615

616
  e = tstack_get_topelem(stack);
16✔
617
  e->tag = TAG_TERM;
16✔
618
  e->val.term = yices_true();
16✔
619
  e->loc = *loc;
16✔
620
}
16✔
621

622
void tstack_push_false(tstack_t *stack, loc_t *loc) {
23✔
623
  stack_elem_t *e;
624

625
  e = tstack_get_topelem(stack);
23✔
626
  e->tag = TAG_TERM;
23✔
627
  e->val.term = yices_false();
23✔
628
  e->loc = *loc;
23✔
629
}
23✔
630

631

632
/*
633
 * Push an integer constant
634
 */
635
void tstack_push_int32(tstack_t *stack, int32_t x, loc_t *loc) {
×
636
  stack_elem_t *e;
637

638
  e = tstack_get_topelem(stack);
×
639
  e->tag = TAG_RATIONAL;
×
640
  e->loc = *loc;
×
641
  q_init(&e->val.rational);
×
642
  q_set32(&e->val.rational, x);
×
643
}
×
644

645

646
/*
647
 * Terms or types
648
 */
649
void tstack_push_term(tstack_t *stack, term_t t, loc_t *loc) {
2,984✔
650
  stack_elem_t *e;
651

652
  e = tstack_get_topelem(stack);
2,984✔
653
  e->tag = TAG_TERM;
2,984✔
654
  e->val.term = t;
2,984✔
655
  e->loc = *loc;
2,984✔
656
}
2,984✔
657

658
void tstack_push_type(tstack_t *stack, type_t tau, loc_t *loc) {
43,450✔
659
  stack_elem_t *e;
660

661
  e = tstack_get_topelem(stack);
43,450✔
662
  e->tag = TAG_TYPE;
43,450✔
663
  e->val.type = tau;
43,450✔
664
  e->loc = *loc;
43,450✔
665
}
43,450✔
666

667
void tstack_push_macro(tstack_t *stack, int32_t id, loc_t *loc) {
×
668
  stack_elem_t *e;
669

670
  e = tstack_get_topelem(stack);
×
671
  e->tag = TAG_MACRO;
×
672
  e->val.macro = id;
×
673
  e->loc = *loc;
×
674
}
×
675

676

677
/**********************
678
 *  INTERNAL BUFFERS  *
679
 *********************/
680

681
/*
682
 * Invariant we want to maintain:
683
 * - stack->abuffer is either NULL or it's pointing to the last
684
 *   arithmetic_buffer allocated and that buffer does not occur in the stack.
685
 * - if an element in the stack has tag = TAG_ARITH_BUFFER
686
 *   then its value is a pointer to an arithmetic buffer != stack->abuffer.
687
 * Same thing for stack->bvabuffer and stack->bvlbuffer.
688
 */
689

690
/*
691
 * Get the internal buffers (or allocate a new one)
692
 */
693
rba_buffer_t *tstack_get_abuffer(tstack_t *stack) {
70,452✔
694
  rba_buffer_t *tmp;
695

696
  tmp = stack->abuffer;
70,452✔
697
  if (tmp == NULL) {
70,452✔
698
    tmp = yices_new_arith_buffer();
17,448✔
699
    stack->abuffer = tmp;
17,448✔
700
  } else {
701
    reset_rba_buffer(tmp);
53,004✔
702
  }
703
  assert(rba_buffer_is_zero(tmp));
704
  return tmp;
70,452✔
705
}
706

707
bvarith64_buffer_t *tstack_get_bva64buffer(tstack_t *stack, uint32_t bitsize) {
9,208✔
708
  bvarith64_buffer_t *tmp;
709

710
  assert(1 <= bitsize && bitsize <= 64);
711

712
  tmp = stack->bva64buffer;
9,208✔
713
  if (tmp == NULL) {
9,208✔
714
    tmp = yices_new_bvarith64_buffer(bitsize);
2,667✔
715
    stack->bva64buffer = tmp;
2,667✔
716
  } else {
717
    bvarith64_buffer_prepare(tmp, bitsize); // reset to zero and set size to bitsize
6,541✔
718
  }
719

720
  assert(bvarith64_buffer_is_zero(tmp) && bvarith64_buffer_bitsize(tmp) == bitsize);
721

722
  return tmp;
9,208✔
723
}
724

725
bvarith_buffer_t *tstack_get_bvabuffer(tstack_t *stack, uint32_t bitsize) {
902✔
726
  bvarith_buffer_t *tmp;
727

728
  assert(64 < bitsize && bitsize <= YICES_MAX_BVSIZE);
729

730
  tmp = stack->bvabuffer;
902✔
731
  if (tmp == NULL) {
902✔
732
    tmp = yices_new_bvarith_buffer(bitsize);
74✔
733
    stack->bvabuffer = tmp;
74✔
734
  } else {
735
    bvarith_buffer_prepare(tmp, bitsize); // reset to zero and set size
828✔
736
  }
737

738
  assert(bvarith_buffer_is_zero(tmp) && bvarith_buffer_bitsize(tmp) == bitsize);
739

740
  return tmp;
902✔
741
}
742

743
bvlogic_buffer_t *tstack_get_bvlbuffer(tstack_t *stack) {
60,017✔
744
  bvlogic_buffer_t *tmp;
745

746
  tmp = stack->bvlbuffer;
60,017✔
747
  if (tmp == NULL) {
60,017✔
748
    tmp = yices_new_bvlogic_buffer();
20,437✔
749
    stack->bvlbuffer = tmp;
20,437✔
750
  } else {
751
    bvlogic_buffer_clear(tmp);
39,580✔
752
  }
753
  return tmp;
60,017✔
754
}
755

756

757
/*
758
 * Free or recycle a buffer
759
 */
760
static void recycle_abuffer(tstack_t *stack, rba_buffer_t *b) {
30,524✔
761
  if (stack->abuffer == NULL) {
30,524✔
762
    reset_rba_buffer(b);
13,751✔
763
    stack->abuffer = b;
13,751✔
764
  } else if (stack->abuffer != b) {
16,773✔
765
    yices_free_arith_buffer(b);
16,773✔
766
  }
767
}
30,524✔
768

769
static void recycle_bva64buffer(tstack_t *stack, bvarith64_buffer_t *b) {
9,208✔
770
  if (stack->bva64buffer == NULL) {
9,208✔
771
    bvarith64_buffer_prepare(b, 32); // any non-zero value would work
6,930✔
772
    stack->bva64buffer = b;
6,930✔
773
  } else if (stack->bva64buffer != b) {
2,278✔
774
    yices_free_bvarith64_buffer(b);
2,278✔
775
  }
776
}
9,208✔
777

778
static void recycle_bvabuffer(tstack_t *stack, bvarith_buffer_t *b) {
902✔
779
  if (stack->bvabuffer == NULL) {
902✔
780
    bvarith_buffer_prepare(b, 100); // any non-zero value would work
899✔
781
    stack->bvabuffer = b;
899✔
782
  } else if (stack->bvabuffer != b) {
3✔
783
    yices_free_bvarith_buffer(b);
3✔
784
  }
785
}
902✔
786

787
static void recycle_bvlbuffer(tstack_t *stack, bvlogic_buffer_t *b) {
60,017✔
788
  if (stack->bvlbuffer == NULL) {
60,017✔
789
    bvlogic_buffer_clear(b);
40,131✔
790
    stack->bvlbuffer = b;
40,131✔
791
  } else if (stack->bvlbuffer != b) {
19,886✔
792
    yices_free_bvlogic_buffer(b);
19,886✔
793
  }
794
}
60,017✔
795

796

797
/*
798
 * Make the auxiliary buffer large enough for n terms or types
799
 */
800
void extend_aux_buffer(tstack_t *stack, uint32_t n) {
47✔
801
  uint32_t new_size;
802

803
  assert (stack->aux_size < n);
804

805
  new_size = stack->aux_size + 1;
47✔
806
  new_size += new_size;
47✔
807
  if (new_size < n) new_size = n;
47✔
808

809
  if (new_size  >= MAX_AUX_SIZE) {
47✔
810
    out_of_memory();
×
811
  }
812

813
  stack->aux_buffer = (int32_t *) safe_realloc(stack->aux_buffer, new_size * sizeof(int32_t));
47✔
814
  stack->aux_size  = new_size;
47✔
815
}
47✔
816

817

818
/*
819
 * Make the symbol buffer large enough for n symbols
820
 */
821
void extend_sbuffer(tstack_t *stack, uint32_t n) {
7✔
822
  uint32_t new_size;
823

824
  assert(stack->sbuffer_size < n);
825

826
  new_size = stack->sbuffer_size + 1;
7✔
827
  new_size += new_size;
7✔
828
  if (new_size < n) new_size = n;
7✔
829

830
  if (new_size > MAX_SBUFFER_SIZE) {
7✔
831
    out_of_memory();
×
832
  }
833

834
  stack->sbuffer = (signed_symbol_t *) safe_realloc(stack->sbuffer, new_size * sizeof(signed_symbol_t));
7✔
835
  stack->sbuffer_size = new_size;
7✔
836
}
7✔
837

838

839
/*
840
 * Make the name buffer large enough for n names
841
 */
842
void extend_name_buffer(tstack_t *stack, uint32_t n) {
1,000✔
843
  uint32_t new_size;
844

845
  assert(stack->name_buffer_size < n);
846

847
  new_size = stack->name_buffer_size + 1;
1,000✔
848
  new_size += new_size;
1,000✔
849
  if (new_size < n) new_size = n;
1,000✔
850

851
  if (new_size > MAX_NAME_BUFFER_SIZE) {
1,000✔
852
    out_of_memory();
×
853
  }
854

855
  stack->name_buffer = (char **) safe_realloc(stack->name_buffer, new_size * sizeof(char *));
1,000✔
856
  stack->name_buffer_size = new_size;
1,000✔
857
}
1,000✔
858

859

860

861

862

863

864
/*********************
865
 *  POP OPERATIONS   *
866
 ********************/
867

868
/*
869
 * Cleanup object e (before it gets removed from the stack)
870
 */
871
static void tstack_free_val(tstack_t *stack, stack_elem_t *e) {
2,949,519✔
872
  uint32_t k;
873

874
  switch (e->tag) {
2,949,519✔
875
  case TAG_BV:
2,945✔
876
    k = (e->val.bv.bitsize + 31) >> 5;
2,945✔
877
    bvconst_free(e->val.bv.data, k);
2,945✔
878
    break;
2,945✔
NEW
879
  case TAG_FINITEFIELD:
×
NEW
880
    q_clear(&e->val.ff.val);
×
NEW
881
    q_clear(&e->val.ff.mod);
×
NEW
882
    break;
×
883
  case TAG_RATIONAL:
316,823✔
884
    q_clear(&e->val.rational);
316,823✔
885
    break;
316,823✔
886
  case TAG_ATTRIBUTE:
1✔
887
    assert(stack->avtbl != NULL);
888
    if (e->val.aval != AVAL_NULL) {
1✔
889
      aval_decref(stack->avtbl, e->val.aval);
1✔
890
    }
891
    break;
1✔
892
  case TAG_ARITH_BUFFER:
30,524✔
893
    recycle_abuffer(stack, e->val.arith_buffer);
30,524✔
894
    break;
30,524✔
NEW
895
  case TAG_ARITH_FF_BUFFER:
×
NEW
896
    recycle_abuffer(stack, e->val.mod_arith_buffer.b);
×
NEW
897
    q_clear(&e->val.mod_arith_buffer.mod);
×
NEW
898
    break;
×
899
  case TAG_BVARITH64_BUFFER:
9,208✔
900
    recycle_bva64buffer(stack, e->val.bvarith64_buffer);
9,208✔
901
    break;
9,208✔
902
  case TAG_BVARITH_BUFFER:
902✔
903
    recycle_bvabuffer(stack, e->val.bvarith_buffer);
902✔
904
    break;
902✔
905
  case TAG_BVLOGIC_BUFFER:
60,007✔
906
    recycle_bvlbuffer(stack, e->val.bvlogic_buffer);
60,007✔
907
    break;
60,007✔
908
  case TAG_BINDING:
172,740✔
909
    _o_yices_remove_term_name(e->val.binding.symbol);
172,740✔
910
    break;
172,740✔
911
  case TAG_TYPE_BINDING:
×
912
    _o_yices_remove_type_name(e->val.type_binding.symbol);
×
913
    break;
×
914
  default:
2,356,369✔
915
    break; // prevent GCC warning
2,356,369✔
916
  }
917
}
2,949,519✔
918

919

920
/*
921
 * Empty the stack and clear error data
922
 */
923
void tstack_reset(tstack_t *stack) {
1,693✔
924
  stack_elem_t *e;
925
  uint32_t i;
926

927
  i = stack->top;
1,693✔
928
  e = stack->elem + i;
1,693✔
929
  while (i > 0) {
3,420✔
930
    i --;
1,727✔
931
    e --;
1,727✔
932
    tstack_free_val(stack, e);
1,727✔
933
  }
934

935
  arena_reset(&stack->mem);
1,693✔
936
  stack->top = 1;
1,693✔
937
  stack->frame = 0;
1,693✔
938
  stack->top_op = NO_OP;
1,693✔
939

940
  stack->tvar_id = 0;
1,693✔
941

942
  stack->error_op = NO_OP;
1,693✔
943
  stack->error_loc.line = 0;
1,693✔
944
  stack->error_loc.column = 0;
1,693✔
945
  stack->error_string = NULL;
1,693✔
946
}
1,693✔
947

948

949
/*
950
 * Remove the elements above the top-frame index
951
 * (i.e. all the parameters in the top frame, but not the operator)
952
 *
953
 * If top-op is not BIND or DECLARE_VAR or DECLARE_TYPE_VAR, also
954
 * close the arena scope.
955
 */
956
void tstack_pop_frame(tstack_t *stack) {
1,222,477✔
957
  uint32_t i, n;
958
  int32_t op;
959

960
  op = stack->top_op;
1,222,477✔
961
  n = stack->frame;
1,222,477✔
962

963
  assert(0 < n && n < stack->top);
964

965
  // restore previous frame and top_op
966
  i = stack->elem[n].val.opval.prev;
1,222,477✔
967
  stack->frame = i;
1,222,477✔
968
  stack->top_op = stack->elem[i].val.opval.opcode;
1,222,477✔
969

970
  // remove elements at indices n+1 to stack->top-1
971
  i = stack->top;
1,222,477✔
972
  n ++;
1,222,477✔
973
  while (i > n) {
3,814,719✔
974
    i --;
2,592,242✔
975
    tstack_free_val(stack, stack->elem + i);
2,592,242✔
976
  }
977
  stack->top = n;
1,222,477✔
978

979
  if (op != BIND && op != DECLARE_VAR && op != DECLARE_TYPE_VAR) {
1,222,477✔
980
    arena_pop(&stack->mem);
1,049,737✔
981
  }
982
}
1,222,477✔
983

984

985
/*
986
 * Copy v as result in place of the current stack->frame
987
 * then remove all elements above the top frame index.
988
 *
989
 * Cannot be used if v is a string/symbol.
990
 */
991
void copy_result_and_pop_frame(tstack_t *stack, stack_elem_t *v) {
182,891✔
992
  uint32_t i, n;
993
  int32_t op;
994

995
  op = stack->top_op;
182,891✔
996
  n = stack->frame;
182,891✔
997

998
  assert(0 < n && n < stack->top);
999
  assert(&stack->elem[n] < v && v < stack->elem + stack->top);
1000
  assert(v->tag != TAG_SYMBOL);
1001

1002
  // restore previous frame and top_op
1003
  i = stack->elem[n].val.opval.prev;
182,891✔
1004
  stack->frame = i;
182,891✔
1005
  stack->top_op = stack->elem[i].val.opval.opcode;
182,891✔
1006

1007

1008
  stack->elem[n] = *v;
182,891✔
1009
  v->tag = TAG_NONE; // prevent deletion of v's value (since it's copied in elem[n])
182,891✔
1010

1011
  // remove elements at indices n+1 to stack->top-1
1012
  i = stack->top;
182,891✔
1013
  n ++;
182,891✔
1014
  while (i > n) {
538,441✔
1015
    i --;
355,550✔
1016
    tstack_free_val(stack, stack->elem + i);
355,550✔
1017
  }
1018
  stack->top = n;
182,891✔
1019

1020
  if (op != BIND && op != DECLARE_VAR && op != DECLARE_TYPE_VAR) {
182,891✔
1021
    arena_pop(&stack->mem);
182,891✔
1022
  }
1023
}
182,891✔
1024

1025

1026
/*
1027
 * Replace the top element by its new value
1028
 * - to be used after tstack_pop_frame to replace the operator
1029
 *   by the result of the operation
1030
 * - keep the loc field unchanged
1031
 */
1032
void set_term_result(tstack_t *stack, term_t t) {
614,893✔
1033
  stack_elem_t *e;
1034

1035
  e = stack->elem + (stack->top - 1);
614,893✔
1036
  e->tag = TAG_TERM;
614,893✔
1037
  e->val.term = t;
614,893✔
1038
}
614,893✔
1039

1040
void set_special_term_result(tstack_t *stack, term_t t) {
2✔
1041
  stack_elem_t *e;
1042

1043
  e = stack->elem + (stack->top - 1);
2✔
1044
  e->tag = TAG_SPECIAL_TERM;
2✔
1045
  e->val.term = t;
2✔
1046
}
2✔
1047

1048
void set_type_result(tstack_t *stack, type_t tau) {
53,892✔
1049
  stack_elem_t *e;
1050

1051
  e = stack->elem + (stack->top - 1);
53,892✔
1052
  e->tag = TAG_TYPE;
53,892✔
1053
  e->val.type = tau;
53,892✔
1054
}
53,892✔
1055

1056
// b must be equal to stack->abuffer. We reset stack->abuffer to NULL
1057
void set_arith_result(tstack_t *stack, rba_buffer_t *b) {
28,611✔
1058
  stack_elem_t *e;
1059

1060
  assert(b == stack->abuffer);
1061
  stack->abuffer = NULL;
28,611✔
1062

1063
  e = stack->elem + (stack->top - 1);
28,611✔
1064
  e->tag = TAG_ARITH_BUFFER;
28,611✔
1065
  e->val.arith_buffer = b;
28,611✔
1066
}
28,611✔
1067

1068
// b must be equal to stack->abuffer. We reset stack->abuffer to NULL
NEW
1069
void set_arith_ff_result(tstack_t *stack, rba_buffer_t *b, rational_t *mod) {
×
1070
  stack_elem_t *e;
1071

1072
  assert(b == stack->abuffer);
NEW
1073
  stack->abuffer = NULL;
×
1074

1075
  assert(q_is_pos(mod));
1076

NEW
1077
  e = stack->elem + (stack->top - 1);
×
NEW
1078
  e->tag = TAG_ARITH_FF_BUFFER;
×
NEW
1079
  e->val.mod_arith_buffer.b = b;
×
NEW
1080
  q_init(&e->val.mod_arith_buffer.mod);
×
NEW
1081
  q_set(&e->val.mod_arith_buffer.mod, mod);
×
NEW
1082
}
×
1083

1084
// b must be stack->bva64buffer
1085
void set_bvarith64_result(tstack_t *stack, bvarith64_buffer_t *b) {
8,917✔
1086
  stack_elem_t *e;
1087

1088
  assert(b == stack->bva64buffer);
1089
  stack->bva64buffer = NULL;
8,917✔
1090

1091
  e = stack->elem + (stack->top - 1);
8,917✔
1092
  e->tag = TAG_BVARITH64_BUFFER;
8,917✔
1093
  e->val.bvarith64_buffer = b;
8,917✔
1094
}
8,917✔
1095

1096
// b must be stack->bvabuffer
1097
void set_bvarith_result(tstack_t *stack, bvarith_buffer_t *b) {
861✔
1098
  stack_elem_t *e;
1099

1100
  assert(b == stack->bvabuffer);
1101
  stack->bvabuffer = NULL;
861✔
1102

1103
  e = stack->elem + (stack->top - 1);
861✔
1104
  e->tag = TAG_BVARITH_BUFFER;
861✔
1105
  e->val.bvarith_buffer = b;
861✔
1106
}
861✔
1107

1108
// b must be stack->bvlbuffer
1109
void set_bvlogic_result(tstack_t *stack, bvlogic_buffer_t *b) {
60,017✔
1110
  stack_elem_t *e;
1111

1112
  assert(b == stack->bvlbuffer);
1113
  stack->bvlbuffer = NULL;
60,017✔
1114

1115
  e = stack->elem + (stack->top - 1);
60,017✔
1116
  e->tag = TAG_BVLOGIC_BUFFER;
60,017✔
1117
  e->val.bvlogic_buffer = b;
60,017✔
1118
}
60,017✔
1119

1120
void set_binding_result(tstack_t *stack, term_t t, char *symbol) {
198,813✔
1121
  stack_elem_t *e;
1122

1123
  e = stack->elem + (stack->top - 1);
198,813✔
1124
  e->tag = TAG_BINDING;
198,813✔
1125
  e->val.binding.term = t;
198,813✔
1126
  e->val.binding.symbol = symbol;
198,813✔
1127
}
198,813✔
1128

1129
void set_bv64_result(tstack_t *stack, uint32_t nbits, uint64_t c) {
66,383✔
1130
  stack_elem_t *e;
1131

1132
  e = stack->elem + (stack->top - 1);
66,383✔
1133
  e->tag = TAG_BV64;
66,383✔
1134
  e->val.bv64.bitsize = nbits;
66,383✔
1135
  e->val.bv64.value = c;
66,383✔
1136
}
66,383✔
1137

1138
void set_bv_result(tstack_t *stack, uint32_t nbits, uint32_t *bv) {
2,910✔
1139
  stack_elem_t *e;
1140

1141
  e = stack->elem + (stack->top - 1);
2,910✔
1142
  e->tag = TAG_BV;
2,910✔
1143
  e->val.bv.bitsize = nbits;
2,910✔
1144
  e->val.bv.data = bv;
2,910✔
1145
}
2,910✔
1146

NEW
1147
void set_ff_result(tstack_t *stack, rational_t *r, rational_t *m) {
×
1148
  stack_elem_t *e;
1149

NEW
1150
  e = stack->elem + (stack->top - 1);
×
NEW
1151
  e->tag = TAG_FINITEFIELD;
×
NEW
1152
  q_init(&e->val.ff.val);
×
NEW
1153
  q_init(&e->val.ff.mod);
×
NEW
1154
  q_set(&e->val.ff.val, r);
×
NEW
1155
  q_set(&e->val.ff.mod, m);
×
NEW
1156
}
×
1157

UNCOV
1158
void set_type_binding_result(tstack_t *stack, type_t tau, char *symbol) {
×
1159
  stack_elem_t *e;
1160

1161
  e = stack->elem + (stack->top - 1);
×
1162
  e->tag = TAG_TYPE_BINDING;
×
1163
  e->val.type_binding.type = tau;
×
1164
  e->val.type_binding.symbol = symbol;
×
1165
}
×
1166

1167

1168
void set_aval_result(tstack_t *stack, aval_t v) {
1✔
1169
  stack_elem_t *e;
1170

1171
  assert(stack->avtbl != NULL);
1172

1173
  e = stack->elem + (stack->top - 1);
1✔
1174
  e->tag = TAG_ATTRIBUTE;
1✔
1175
  e->val.aval = v;
1✔
1176

1177
  if (v != AVAL_NULL) {
1✔
1178
    aval_incref(stack->avtbl, v);
1✔
1179
  }
1180
}
1✔
1181

1182

1183
#ifndef NDEBUG
1184

1185
/*
1186
 * Print element e (for debugging)
1187
 */
1188
void print_elem(tstack_t *stack, stack_elem_t *e) {
1189
  switch (e->tag) {
1190
  case TAG_NONE:
1191
    printf("<none>");
1192
    break;
1193

1194
  case TAG_OP:
1195
    printf("<op: code = %"PRId32", mult = %"PRIu32", prev = %"PRIu32">", e->val.opval.opcode,
1196
           e->val.opval.multiplicity,e->val.opval.prev);
1197
    break;
1198

1199
  case TAG_OPCODE:
1200
    printf("<opcode: %"PRId32">", e->val.op);
1201
    break;
1202

1203
  case TAG_SYMBOL:
1204
    printf("<symbol: %s>", e->val.string);
1205
    break;
1206

1207
  case TAG_NOT_SYMBOL:
1208
    printf("<not symbol: %s>", e->val.string);
1209
    break;
1210

1211
  case TAG_STRING:
1212
    printf("<string: %s>", e->val.string);
1213
    break;
1214

1215
  case TAG_BV64:
1216
    printf("<bitvector: ");
1217
    bvconst64_print(stdout, e->val.bv64.value, e->val.bv64.bitsize);
1218
    printf(">");
1219
    break;
1220

1221
  case TAG_BV:
1222
    printf("<bitvector: ");
1223
    bvconst_print(stdout, e->val.bv.data, e->val.bv.bitsize);
1224
    printf(">");
1225
    break;
1226

1227
  case TAG_RATIONAL:
1228
    printf("<rational: ");
1229
    q_print(stdout, &e->val.rational);
1230
    printf(">");
1231
    break;
1232

1233
  case TAG_FINITEFIELD:
1234
    printf("<finitefield: ");
1235
    q_print(stdout, &e->val.ff.val);
1236
    printf(" mod ");
1237
    q_print(stdout, &e->val.ff.mod);
1238
    printf(">");
1239
    break;
1240

1241
  case TAG_TERM:
1242
    printf("<term: ");
1243
    print_term_id(stdout, e->val.term);
1244
    printf(">");
1245
    break;
1246

1247
  case TAG_SPECIAL_TERM:
1248
    printf("<special-term: ");
1249
    print_term_id(stdout, e->val.term);
1250
    printf(">");
1251
    break;
1252

1253
  case TAG_TYPE:
1254
    printf("<type: ");
1255
    print_type_id(stdout, e->val.term);
1256
    printf(">");
1257
    break;
1258

1259
  case TAG_MACRO:
1260
    printf("<macro: %"PRId32">", e->val.macro);
1261
    break;
1262

1263
  case TAG_ARITH_BUFFER:
1264
    printf("<arith-buffer: ");
1265
    print_arith_buffer(stdout, e->val.arith_buffer);
1266
    printf(">");
1267
    break;
1268

1269
  case TAG_ARITH_FF_BUFFER:
1270
    printf("<arith-ff-buffer: ");
1271
    print_arith_buffer(stdout, e->val.mod_arith_buffer.b);
1272
    printf(" mod ");
1273
    q_print(stdout, &e->val.mod_arith_buffer.mod);
1274
    printf(">");
1275
    break;
1276

1277
  case TAG_BVARITH64_BUFFER:
1278
    printf("<bvarith64-buffer: ");
1279
    print_bvarith64_buffer(stdout, e->val.bvarith64_buffer);
1280
    printf(">");
1281
    break;
1282

1283
  case TAG_BVARITH_BUFFER:
1284
    printf("<bvarith-buffer: ");
1285
    print_bvarith_buffer(stdout, e->val.bvarith_buffer);
1286
    printf(">");
1287
    break;
1288

1289
  case TAG_BVLOGIC_BUFFER:
1290
    printf("<bvlogic-buffer: ");
1291
    print_bvlogic_buffer(stdout, e->val.bvlogic_buffer);
1292
    printf(">");
1293
    break;
1294

1295
  case TAG_BINDING:
1296
    printf("<binding: %s --> ", e->val.binding.symbol);
1297
    print_term_id(stdout, e->val.binding.term);
1298
    printf(">");
1299
    break;
1300

1301
  case TAG_TYPE_BINDING:
1302
    printf("<type-binding: %s --> ", e->val.type_binding.symbol);
1303
    print_type_id(stdout, e->val.type_binding.type);
1304
    printf(">");
1305
    break;
1306

1307
  case TAG_ATTRIBUTE:
1308
    // no attribute printing implemented yet
1309
  default:
1310
    printf("<error>");
1311
    break;
1312
  }
1313
}
1314

1315
#endif
1316

1317

1318
/***************************************
1319
 *  EVALUATION OF INDIVIDUAL COMMANDS  *
1320
 **************************************/
1321

1322
/*
1323
 * Auxiliary functions
1324
 */
1325
static int invalid_tag(tag_t tg) {
×
1326
  int error_code;
1327

1328
  switch (tg) {
×
1329
  case TAG_SYMBOL:
×
1330
    error_code = TSTACK_NOT_A_SYMBOL;
×
1331
    break;
×
1332

1333
  case TAG_RATIONAL:
×
1334
    error_code = TSTACK_NOT_A_RATIONAL;
×
1335
    break;
×
1336

1337
  case TAG_TYPE:
×
1338
    error_code = TSTACK_NOT_A_TYPE;
×
1339
    break;
×
1340

1341
  default:
×
1342
    error_code = TSTACK_INTERNAL_ERROR;
×
1343
  }
1344

1345
  return error_code;
×
1346
}
1347

1348
void check_tag(tstack_t *stack, stack_elem_t *e, tag_t tg) {
840,136✔
1349
  if (e->tag != tg) raise_exception(stack, e, invalid_tag(tg));
840,136✔
1350
}
840,136✔
1351

1352
void check_op(tstack_t *stack, int32_t op) {
1,405,274✔
1353
  if (stack->top_op != op) {
1,405,274✔
1354
    raise_exception(stack, stack->elem + stack->frame, TSTACK_INTERNAL_ERROR);
×
1355
  }
1356
}
1,405,274✔
1357

1358
void check_size(tstack_t *stack, bool cond) {
1,574,856✔
1359
  if (! cond) {
1,574,856✔
1360
    raise_exception(stack, stack->elem + stack->frame, TSTACK_INVALID_FRAME);
×
1361
  }
1362
}
1,574,856✔
1363

1364
void check_all_tags(tstack_t *stack, stack_elem_t *e, stack_elem_t *end, tag_t tg) {
262,601✔
1365
  while (e < end) {
512,461✔
1366
    check_tag(stack, e, tg);
249,860✔
1367
    e ++;
249,860✔
1368
  }
1369
}
262,601✔
1370

1371
static void check_type(tstack_t *stack, type_t tau) {
46,471✔
1372
  if (tau == NULL_TYPE) report_yices_error(stack);
46,471✔
1373
}
46,471✔
1374

1375
static void check_term(tstack_t *stack, term_t t) {
359,084✔
1376
  if (t == NULL_TERM) report_yices_error(stack);
359,084✔
1377
}
359,084✔
1378

1379

1380

1381
/*
1382
 * Check whether n string s1...sn are all distinct (for small n).
1383
 */
1384
// pair: string + hash code
1385
typedef struct tagged_string_s {
1386
  uint32_t hash;
1387
  char *string;
1388
} tagged_string_t;
1389

1390

1391
/*
1392
 * Add string s to array a, (as last element)
1393
 * n = number of elements currently in a
1394
 * return true if s is already in the array, false otherwise
1395
 */
1396
static bool check_duplicate_string(tagged_string_t *a, int32_t n, char *s) {
3,158✔
1397
  uint32_t h;
1398
  int32_t i;
1399

1400
  h = jenkins_hash_string(s);
3,158✔
1401
  for (i=0; i<n; i++) {
14,034✔
1402
    if (a[i].hash == h && strcmp(s, a[i].string) == 0) {
10,876✔
1403
      return true;
×
1404
    }
1405
  }
1406
  a[i].hash = h;
3,158✔
1407
  a[i].string = s;
3,158✔
1408
  return false;
3,158✔
1409
}
1410

1411

1412
/*
1413
 * Check whether all names in a scalar-type definition are distinct
1414
 * - names are in f[0] .. f[n-1]
1415
 * - all are symbols
1416
 * - n is positive
1417
 */
1418
static void check_distinct_scalar_names(tstack_t *stack, stack_elem_t *f, uint32_t n) {
7✔
1419
  uint32_t i;
1420
  tagged_string_t check[n];
7✔
1421

1422
  // check for duplicate strings in the sequence
1423
  for (i=0; i<n; i++) {
16✔
1424
    assert(f[i].tag == TAG_SYMBOL);
1425
    if (check_duplicate_string(check, i, f[i].val.string)) {
9✔
1426
      raise_exception(stack, f+i, TSTACK_DUPLICATE_SCALAR_NAME);
×
1427
    }
1428
  }
1429
}
7✔
1430

1431

1432
/*
1433
 * Check whether all names in a list of variable bindings are distinct
1434
 * - names are in f[0] .. f[n-1]
1435
 * - all are bindings
1436
 *
1437
 * NOTE: the declaration check[n] causes the memory sanitizer to report a
1438
 * runtime error if n is 0.
1439
 */
1440
void check_distinct_binding_names(tstack_t *stack, stack_elem_t *f, uint32_t n) {
18,861✔
1441
  if (n > 0) {
18,861✔
1442
    uint32_t i;
1443
    tagged_string_t check[n];
2,405✔
1444

1445
    // check for duplicate strings in the sequence
1446
    for (i=0; i<n; i++) {
5,554✔
1447
      assert(f[i].tag == TAG_BINDING);
1448
      if (check_duplicate_string(check, i, f[i].val.binding.symbol)) {
3,149✔
1449
        raise_exception(stack, f+i, TSTACK_DUPLICATE_VAR_NAME);
×
1450
      }
1451
    }
1452
  }
1453
}
18,861✔
1454

1455

1456
/*
1457
 * Same thing for type-variable bindings
1458
 *
1459
 * NOTE: the declaration check[n] causes the memory sanitizer to report a
1460
 * runtime error if n is 0.
1461
 */
1462
void check_distinct_type_binding_names(tstack_t *stack, stack_elem_t *f, uint32_t n) {
59✔
1463
  if (n > 0) {
59✔
1464
    uint32_t i;
1465
    tagged_string_t check[n];
×
1466

1467
    // check for duplicate strings in the sequence
1468
    for (i=0; i<n; i++) {
×
1469
      assert(f[i].tag == TAG_TYPE_BINDING);
1470
      if (check_duplicate_string(check, i, f[i].val.type_binding.symbol)) {
×
1471
        raise_exception(stack, f+i, TSTACK_DUPLICATE_TYPE_VAR_NAME);
×
1472
      }
1473
    }
1474
  }
1475
}
59✔
1476

1477

1478
/*
1479
 * CONVERSIONS
1480
 */
1481

1482
/*
1483
 * Convert element e to a term or raise an exception
1484
 */
1485
term_t get_term(tstack_t *stack, stack_elem_t *e) {
1,556,472✔
1486
  uint64_t c;
1487
  term_t t;
1488

1489
  switch (e->tag) {
1,556,472✔
1490
  case TAG_TERM:
1,389,052✔
1491
  case TAG_SPECIAL_TERM:
1492
    t = e->val.term;
1,389,052✔
1493
    break;
1,389,052✔
1494

1495
  case TAG_SYMBOL:
2,162✔
1496
    t = _o_yices_get_term_by_name(e->val.string);
2,162✔
1497
    if (t == NULL_TERM) {
2,162✔
1498
      raise_exception(stack, e, TSTACK_UNDEF_TERM);
×
1499
    }
1500
    break;
2,162✔
1501

1502
  case TAG_STRING:
×
1503
    raise_exception(stack, e, TSTACK_STRINGS_ARE_NOT_TERMS);
×
1504
    break;
1505

1506
  case TAG_BV64:
60,384✔
1507
    c = norm64(e->val.bv64.value, e->val.bv64.bitsize);
60,384✔
1508
    t = yices_bvconst64_term(e->val.bv64.bitsize, c);
60,384✔
1509
    break;
60,384✔
1510

1511
  case TAG_BV:
1,588✔
1512
    bvconst_normalize(e->val.bv.data, e->val.bv.bitsize);
1,588✔
1513
    t = yices_bvconst_term(e->val.bv.bitsize, e->val.bv.data);
1,588✔
1514
    break;
1,588✔
1515

NEW
1516
  case TAG_FINITEFIELD:
×
NEW
1517
    t = yices_ffconst_term(&e->val.ff.val, &e->val.ff.mod);
×
NEW
1518
    break;
×
1519

1520
  case TAG_RATIONAL:
34,179✔
1521
    t = yices_rational_term(&e->val.rational);
34,179✔
1522
    break;
34,179✔
1523

1524
  case TAG_ARITH_BUFFER:
18,015✔
1525
    t = arith_buffer_get_term(e->val.arith_buffer);
18,015✔
1526
    break;
18,015✔
1527

NEW
1528
  case TAG_ARITH_FF_BUFFER:
×
NEW
1529
    t = arith_ff_buffer_get_term(e->val.mod_arith_buffer.b, &e->val.mod_arith_buffer.mod);
×
NEW
1530
    break;
×
1531

1532
  case TAG_BVARITH64_BUFFER:
7,847✔
1533
    t = bvarith64_buffer_get_term(e->val.bvarith64_buffer);
7,847✔
1534
    break;
7,847✔
1535

1536
  case TAG_BVARITH_BUFFER:
879✔
1537
    t = bvarith_buffer_get_term(e->val.bvarith_buffer);
879✔
1538
    break;
879✔
1539

1540
  case TAG_BVLOGIC_BUFFER:
42,366✔
1541
    t = bvlogic_buffer_get_term(e->val.bvlogic_buffer);
42,366✔
1542
    break;
42,366✔
1543

1544
  default:
×
1545
    raise_exception(stack, e, TSTACK_INTERNAL_ERROR);
×
1546
    break;
1547
  }
1548

1549
  return t;
1,556,472✔
1550
}
1551

1552

1553

1554
/*
1555
 * Return integer value of e (e must have rational tag)
1556
 * Raise an exception if e is too large or is not an integer.
1557
 */
1558
int32_t get_integer(tstack_t *stack, stack_elem_t *e) {
177,801✔
1559
  int32_t v;
1560

1561
  assert(e->tag == TAG_RATIONAL);
1562

1563
  if (q_get32(&e->val.rational, &v)) {
177,801✔
1564
    return v;
177,801✔
1565
  }
1566

1567
  if (q_is_integer(&e->val.rational)) {
×
1568
    raise_exception(stack, e, TSTACK_INTEGER_OVERFLOW);
×
1569
  } else {
1570
    raise_exception(stack, e, TSTACK_NOT_AN_INTEGER);
×
1571
  }
1572
}
1573

1574
/*
1575
 * Return integer value of e as mpz integer (e must have rational tag)
1576
 * Raise an exception if e is not an integer.
1577
 */
NEW
1578
void get_integer_mpz(tstack_t *stack, stack_elem_t *e, mpz_t z) {
×
1579
  assert(e->tag == TAG_RATIONAL);
1580

NEW
1581
  if (! q_get_mpz(&e->val.rational, z)) {
×
NEW
1582
    raise_exception(stack, e, TSTACK_NOT_AN_INTEGER);
×
1583
  }
NEW
1584
}
×
1585

1586
/*
1587
 * Support for division: return a rational constant equal to den
1588
 * provided den is constant and non-zero
1589
 */
1590
rational_t *get_divisor(tstack_t *stack, stack_elem_t *den) {
×
1591
  rational_t *d;
1592
  term_t t;
1593
  rba_buffer_t *c;
1594
  term_table_t *terms;
1595
  mono_t *m;
1596

1597
  switch (den->tag) {
×
1598
  case TAG_RATIONAL:
×
1599
    d = &den->val.rational;
×
1600
    if (q_is_zero(d)) {
×
1601
      raise_exception(stack, den, TSTACK_DIVIDE_BY_ZERO);
×
1602
    }
1603
    break;
×
1604

1605
  case TAG_TERM:
×
1606
  case TAG_SPECIAL_TERM:
1607
    terms = __yices_globals.terms;
×
1608
    t = den->val.term;
×
1609
    if (term_kind(terms, t) == ARITH_CONSTANT) {
×
1610
      d = rational_term_desc(terms, t);
×
1611
      if (q_is_zero(d)) {
×
1612
        raise_exception(stack, den, TSTACK_DIVIDE_BY_ZERO);
×
1613
      }
1614
    } else if (is_arithmetic_term(terms, t)) {
×
1615
      raise_exception(stack, den, TSTACK_NON_CONSTANT_DIVISOR);
×
1616
    } else {
1617
      raise_exception(stack, den, TSTACK_ARITH_ERROR);
×
1618
    }
1619
    break;
×
1620

1621
  case TAG_ARITH_BUFFER:
×
1622
    c = den->val.arith_buffer;
×
1623
    if (rba_buffer_is_constant(c)) {
×
1624
      m = rba_buffer_get_constant_mono(c);
×
1625
      if (m == NULL) {
×
1626
        assert(rba_buffer_is_zero(c));
1627
        raise_exception(stack, den, TSTACK_DIVIDE_BY_ZERO);
×
1628
      }
1629
      d = &m->coeff;
×
1630
    } else {
1631
      raise_exception(stack, den, TSTACK_NON_CONSTANT_DIVISOR);
×
1632
    }
1633
    break;
×
1634

1635
  default:
×
1636
    raise_exception(stack, den, TSTACK_ARITH_ERROR);
×
1637
    break;
1638
  }
1639

1640
  return d;
×
1641
}
1642

1643

1644
/*
1645
 * Variant: Check whether e stores a non-zero rational constant
1646
 * If so, store the value in result.
1647
 */
1648
bool elem_is_nz_constant(stack_elem_t *e, rational_t *result) {
3,751✔
1649
  rational_t *d;
1650
  term_t t;
1651
  bool ok;
1652
  rba_buffer_t *c;
1653
  term_table_t *terms;
1654
  mono_t *m;
1655

1656
  ok = false;
3,751✔
1657

1658
  switch (e->tag) {
3,751✔
1659
  case TAG_RATIONAL:
835✔
1660
    d = &e->val.rational;
835✔
1661
    if (q_is_nonzero(d)) {
835✔
1662
      q_set(result, d);
832✔
1663
      ok = true;
832✔
1664
    }
1665
    break;
835✔
1666

1667
  case TAG_TERM:
2,007✔
1668
  case TAG_SPECIAL_TERM:
1669
    terms = __yices_globals.terms;
2,007✔
1670
    t = e->val.term;
2,007✔
1671
    if (term_kind(terms, t) == ARITH_CONSTANT) {
2,007✔
1672
      d = rational_term_desc(terms, t);
241✔
1673
      if (q_is_nonzero(d)) {
241✔
1674
        q_set(result, d);
241✔
1675
        ok = true;
241✔
1676
      }
1677
    }
1678
    break;
2,007✔
1679

1680
  case TAG_ARITH_BUFFER:
909✔
1681
    c = e->val.arith_buffer;
909✔
1682
    if (rba_buffer_is_constant(c)) {
909✔
1683
      m = rba_buffer_get_constant_mono(c);
1✔
1684
      if (m != NULL) {
1✔
1685
        assert(q_is_nonzero(&m->coeff));
NEW
1686
        q_set(result, &m->coeff);
×
NEW
1687
        ok = true;
×
1688
      }
1689
    }
1690
    break;
909✔
1691

1692
  default:
×
1693
    break;
×
1694
  }
1695

1696
  return ok;
3,751✔
1697
}
1698

1699

1700
/*
1701
 * Convert e to a signed symbol (i.e., pair name/polarity).
1702
 * This does not make a copy of the string.
1703
 * Raise an exception if e has tag other than TAG_SYMBOL and TAG_NOT_SYMBOL.
1704
 */
1705
void get_signed_symbol(tstack_t *stack, stack_elem_t *e, signed_symbol_t *s) {
18✔
1706
  switch (e->tag) {
18✔
1707
  case TAG_SYMBOL:
4✔
1708
    s->name = e->val.string;
4✔
1709
    s->polarity = true;
4✔
1710
    break;
4✔
1711

1712
  case TAG_NOT_SYMBOL:
14✔
1713
    s->name = e->val.string;
14✔
1714
    s->polarity = false;
14✔
1715
    break;
14✔
1716

1717
  default:
×
1718
    raise_exception(stack, e, TSTACK_INTERNAL_ERROR);
×
1719
    break;
1720
  }
1721
}
18✔
1722

1723

1724

1725

1726

1727
/*
1728
 * Bitsize of element e
1729
 * - raise an exception if e is not a bitvector element
1730
 * - also raise an exception if e is an empty bvlogic buffer
1731
 */
1732
static uint32_t elem_bitsize(tstack_t *stack, stack_elem_t *e) {
27,052✔
1733
  term_t t;
1734
  uint32_t n;
1735

1736
  switch (e->tag) {
27,052✔
1737
  case TAG_BV64:
8,216✔
1738
    n = e->val.bv64.bitsize;
8,216✔
1739
    break;
8,216✔
1740

1741
  case TAG_BV:
76✔
1742
    n = e->val.bv.bitsize;
76✔
1743
    break;
76✔
1744

1745
  case TAG_TERM:
15,807✔
1746
  case TAG_SPECIAL_TERM:
1747
    t = e->val.term;
15,807✔
1748
    if (! yices_check_bv_term(t)) {
15,807✔
1749
      report_yices_error(stack);
×
1750
    }
1751
    n = term_bitsize(__yices_globals.terms, t);
15,807✔
1752
    break;
15,807✔
1753

1754
  case TAG_BVARITH64_BUFFER:
450✔
1755
    n = bvarith64_buffer_bitsize(e->val.bvarith64_buffer);
450✔
1756
    break;
450✔
1757

1758
  case TAG_BVARITH_BUFFER:
1✔
1759
    n = bvarith_buffer_bitsize(e->val.bvarith_buffer);
1✔
1760
    break;
1✔
1761

1762
  case TAG_BVLOGIC_BUFFER:
2,502✔
1763
    if (! yices_check_bvlogic_buffer(e->val.bvlogic_buffer)) {
2,502✔
1764
      report_yices_error(stack);
×
1765
    }
1766
    n = bvlogic_buffer_bitsize(e->val.bvlogic_buffer);
2,502✔
1767
    break;
2,502✔
1768

1769
  default:
×
1770
    raise_exception(stack, e, TSTACK_BVARITH_ERROR);
×
1771
    break;
1772
  }
1773

1774
  assert(0 < n && n <= YICES_MAX_BVSIZE);
1775

1776
  return n;
27,052✔
1777
}
1778

1779

1780
/*
1781
 * Get the i-th bit of element e
1782
 * - e must be a bitvector element
1783
 * - i must satisfy 0 <= i < n (where n = bitsize of e)
1784
 */
1785
static term_t elem_bit_select(tstack_t *stack, stack_elem_t *e, uint32_t i) {
48✔
1786
  term_t  t;
1787

1788
  switch (e->tag) {
48✔
1789
  case TAG_BV64:
×
1790
    assert(i < e->val.bv64.bitsize);
1791
    t = bool2term(tst_bit64(e->val.bv64.value, i));
×
1792
    break;
×
1793

1794
  case TAG_BV:
×
1795
    assert(i < e->val.bv.bitsize);
1796
    t = bool2term(bvconst_tst_bit(e->val.bv.data, i));
×
1797
    break;
×
1798

1799
  case TAG_TERM:
24✔
1800
  case TAG_SPECIAL_TERM:
1801
    t = _o_yices_bitextract(e->val.term, i);
24✔
1802
    break;
24✔
1803

1804
  case TAG_BVARITH64_BUFFER:
24✔
1805
    t = bvarith64_buffer_get_term(e->val.bvarith64_buffer);
24✔
1806
    t = _o_yices_bitextract(t, i);
24✔
1807
    break;
24✔
1808

1809
  case TAG_BVARITH_BUFFER:
×
1810
    t = bvarith_buffer_get_term(e->val.bvarith_buffer);
×
1811
    t = _o_yices_bitextract(t, i);
×
1812
    break;
×
1813

1814
  case TAG_BVLOGIC_BUFFER:
×
1815
    t = bvlogic_buffer_get_bit(e->val.bvlogic_buffer, i);
×
1816
    break;
×
1817

1818
  default:
×
1819
    raise_exception(stack, e, TSTACK_INTERNAL_ERROR);
×
1820
    break;
1821
  }
1822

1823
  return t;
48✔
1824
}
1825

1826

1827
/*
1828
 * Verify that element e is a bitvector term of bitsize equal to n
1829
 * - e must have tag = TAG_TERM or TAG_SPECIAL_TERM
1830
 * - raise an exception if t is not
1831
 */
1832
static void check_bv_term(tstack_t *stack, stack_elem_t *e, uint32_t n) {
17,346✔
1833
  term_t t;
1834

1835
  assert(e->tag == TAG_TERM || e->tag == TAG_SPECIAL_TERM);
1836
  t = e->val.term;
17,346✔
1837

1838
  if (! yices_check_bv_term(t)) {
17,346✔
1839
    report_yices_error(stack);
×
1840
  }
1841
  if (term_bitsize(__yices_globals.terms, t) != n) {
17,346✔
1842
    raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
1843
  }
1844
}
17,346✔
1845

1846

1847

1848
/*
1849
 * ARITHMETIC
1850
 */
1851

1852
/*
1853
 * Add arithmetic element e to buffer b. Raise an exception if e is not
1854
 * arithmetic or if the operation fails.
1855
 */
1856
void add_elem(tstack_t *stack, rba_buffer_t *b, stack_elem_t *e) {
86,795✔
1857
  switch (e->tag) {
86,795✔
1858
  case TAG_RATIONAL:
15,438✔
1859
    rba_buffer_add_const(b, &e->val.rational);
15,438✔
1860
    break;
15,438✔
1861

1862
  case TAG_TERM:
60,723✔
1863
  case TAG_SPECIAL_TERM:
1864
    if (! yices_check_arith_term(e->val.term) && ! yices_check_arith_ff_term(e->val.term)) {
60,723✔
1865
      report_yices_error(stack);
×
1866
    }
1867
    rba_buffer_add_term(b, __yices_globals.terms, e->val.term);
60,723✔
1868
    break;
60,723✔
1869

1870
  case TAG_ARITH_BUFFER:
10,634✔
1871
    rba_buffer_add_buffer(b, e->val.arith_buffer);
10,634✔
1872
    break;
10,634✔
1873

1874
  default:
×
1875
    raise_exception(stack, e, TSTACK_ARITH_ERROR);
×
1876
    break;
1877
  }
1878
}
86,795✔
1879

1880

1881
/*
1882
 * Negate element e (in place). Raise an exception if e is not an arithmetic term.
1883
 */
1884
void neg_elem(tstack_t *stack, stack_elem_t *e) {
10,865✔
1885
  rba_buffer_t *b;
1886
  term_table_t *terms;
1887
  term_t t;
1888

1889
  switch (e->tag) {
10,865✔
1890
  case TAG_RATIONAL:
7,652✔
1891
    q_neg(&e->val.rational);
7,652✔
1892
    break;
7,652✔
1893

1894
  case TAG_TERM:
3,081✔
1895
  case TAG_SPECIAL_TERM:
1896
    t = e->val.term;
3,081✔
1897
    terms = __yices_globals.terms;
3,081✔
1898
    if (! yices_check_arith_term(t)) {
3,081✔
1899
      report_yices_error(stack);
×
1900
    }
1901
    if (term_kind(terms, t) == ARITH_CONSTANT) {
3,081✔
1902
      // overwrite e: replace it by -(t's value)
1903
      e->tag = TAG_RATIONAL;
1,168✔
1904
      q_init(&e->val.rational);
1,168✔
1905
      q_set_neg(&e->val.rational, rational_term_desc(terms, t));
1,168✔
1906
    } else {
1907
      // compute -b
1908
      b = tstack_get_abuffer(stack);
1,913✔
1909
      assert(rba_buffer_is_zero(b));
1910
      rba_buffer_sub_term(b, __yices_globals.terms, e->val.term);
1,913✔
1911
      // overwrite e
1912
      e->tag = TAG_ARITH_BUFFER;
1,913✔
1913
      e->val.arith_buffer = b;
1,913✔
1914
      // reset stack->abuffer to NULL (cf. set_arith_result)
1915
      assert(b == stack->abuffer);
1916
      stack->abuffer = NULL;
1,913✔
1917
    }
1918
    break;
3,081✔
1919

1920
  case TAG_ARITH_BUFFER:
132✔
1921
    rba_buffer_negate(e->val.arith_buffer);
132✔
1922
    break;
132✔
1923

1924
  default:
×
1925
    raise_exception(stack, e, TSTACK_ARITH_ERROR);
×
1926
    break;
1927
  }
1928
}
10,865✔
1929

1930

1931
/*
1932
 * Subtract element e from buffer b.
1933
 */
1934
void sub_elem(tstack_t *stack, rba_buffer_t *b, stack_elem_t *e) {
47,556✔
1935
  switch (e->tag) {
47,556✔
1936
  case TAG_RATIONAL:
11,190✔
1937
    rba_buffer_sub_const(b, &e->val.rational);
11,190✔
1938
    break;
11,190✔
1939

1940
  case TAG_TERM:
34,306✔
1941
  case TAG_SPECIAL_TERM:
1942
    if (! yices_check_arith_term(e->val.term)) {
34,306✔
1943
      report_yices_error(stack);
×
1944
    }
1945
    rba_buffer_sub_term(b, __yices_globals.terms, e->val.term);
34,306✔
1946
    break;
34,306✔
1947

1948
  case TAG_ARITH_BUFFER:
2,060✔
1949
    rba_buffer_sub_buffer(b, e->val.arith_buffer);
2,060✔
1950
    break;
2,060✔
1951

1952
  default:
×
1953
    raise_exception(stack, e, TSTACK_ARITH_ERROR);
×
1954
    break;
1955
  }
1956
}
47,556✔
1957

1958

1959
/*
1960
 * Product
1961
 */
1962
void mul_elem(tstack_t *stack, rba_buffer_t *b, stack_elem_t *e) {
24,824✔
1963
  switch (e->tag) {
24,824✔
1964
  case TAG_RATIONAL:
8,234✔
1965
    rba_buffer_mul_const(b, &e->val.rational);
8,234✔
1966
    break;
8,234✔
1967

1968
  case TAG_TERM:
16,399✔
1969
  case TAG_SPECIAL_TERM:
1970
    if (! yices_check_arith_term(e->val.term) || ! yices_check_mul_term(b, e->val.term)) {
16,399✔
1971
      report_yices_error(stack);
1✔
1972
    }
1973
    rba_buffer_mul_term(b, __yices_globals.terms, e->val.term);
16,398✔
1974
    break;
16,398✔
1975

1976
  case TAG_ARITH_BUFFER:
191✔
1977
    if (! yices_check_mul_buffer(b, e->val.arith_buffer)) {
191✔
1978
      // degree overflow
1979
      report_yices_error(stack);
×
1980
    }
1981
    rba_buffer_mul_buffer(b, e->val.arith_buffer);
191✔
1982
    break;
191✔
1983

1984
  default:
×
1985
    raise_exception(stack, e, TSTACK_ARITH_ERROR);
×
1986
    break;
1987
  }
1988
}
24,823✔
1989

1990
/*
1991
 * FINITE FIELD ARITHMETIC
1992
 */
1993

NEW
1994
void ff_add_elem(tstack_t *stack, rba_buffer_t *b, stack_elem_t *e) {
×
1995

NEW
1996
  switch (e->tag) {
×
NEW
1997
  case TAG_FINITEFIELD:
×
NEW
1998
    rba_buffer_add_const(b, &e->val.ff.val);
×
NEW
1999
    break;
×
2000

NEW
2001
  case TAG_TERM:
×
2002
  case TAG_SPECIAL_TERM:
NEW
2003
    if (! yices_check_arith_ff_term(e->val.term)) {
×
NEW
2004
      report_yices_error(stack);
×
2005
    }
NEW
2006
    rba_buffer_add_term(b, __yices_globals.terms, e->val.term);
×
NEW
2007
    break;
×
2008

NEW
2009
  case TAG_ARITH_FF_BUFFER:
×
NEW
2010
    rba_buffer_add_buffer(b, e->val.mod_arith_buffer.b);
×
NEW
2011
    break;
×
2012

NEW
2013
  default:
×
NEW
2014
    raise_exception(stack, e, TSTACK_ARITH_ERROR);
×
2015
    break;
2016
  }
NEW
2017
}
×
2018

NEW
2019
void ff_sub_elem(tstack_t *stack, rba_buffer_t *b, stack_elem_t *e) {
×
2020

NEW
2021
  switch (e->tag) {
×
NEW
2022
  case TAG_FINITEFIELD:
×
NEW
2023
    rba_buffer_sub_const(b, &e->val.ff.val);
×
NEW
2024
    break;
×
2025

NEW
2026
  case TAG_TERM:
×
2027
  case TAG_SPECIAL_TERM:
NEW
2028
    if (! yices_check_arith_ff_term(e->val.term)) {
×
NEW
2029
      report_yices_error(stack);
×
2030
    }
NEW
2031
    rba_buffer_sub_term(b, __yices_globals.terms, e->val.term);
×
NEW
2032
    break;
×
2033

NEW
2034
  case TAG_ARITH_FF_BUFFER:
×
NEW
2035
    rba_buffer_sub_buffer(b, e->val.mod_arith_buffer.b);
×
NEW
2036
    break;
×
2037

NEW
2038
  default:
×
NEW
2039
    raise_exception(stack, e, TSTACK_ARITH_ERROR);
×
2040
    break;
2041
  }
NEW
2042
}
×
2043

NEW
2044
void ff_mul_elem(tstack_t *stack, rba_buffer_t *b, stack_elem_t *e) {
×
2045

NEW
2046
  switch (e->tag) {
×
NEW
2047
  case TAG_FINITEFIELD:
×
NEW
2048
    rba_buffer_mul_const(b, &e->val.ff.val);
×
NEW
2049
    break;
×
2050

NEW
2051
  case TAG_TERM:
×
2052
  case TAG_SPECIAL_TERM:
NEW
2053
    if (! yices_check_arith_ff_term(e->val.term) || ! yices_check_mul_term(b, e->val.term)) {
×
NEW
2054
      report_yices_error(stack);
×
2055
    }
NEW
2056
    rba_buffer_mul_term(b, __yices_globals.terms, e->val.term);
×
NEW
2057
    break;
×
2058

NEW
2059
  case TAG_ARITH_FF_BUFFER:
×
NEW
2060
    if (! yices_check_mul_buffer(b, e->val.mod_arith_buffer.b)) {
×
2061
      // degree overflow
NEW
2062
      report_yices_error(stack);
×
2063
    }
NEW
2064
    rba_buffer_mul_buffer(b, e->val.mod_arith_buffer.b);
×
NEW
2065
    break;
×
2066

NEW
2067
  default:
×
NEW
2068
    raise_exception(stack, e, TSTACK_ARITH_ERROR);
×
2069
    break;
2070
  }
NEW
2071
}
×
2072

2073

2074
/*
2075
 * BIT-VECTOR ARITHMETIC: BITSIZE BETWEEN 1 and 64
2076
 */
2077

2078
/*
2079
 * Add element e to buffer b.
2080
 * - raise an exception if e is not a bitvector of equal size as b
2081
 */
2082
void bva64_add_elem(tstack_t *stack, bvarith64_buffer_t *b, stack_elem_t *e) {
15,577✔
2083
  uint32_t n;
2084
  term_t t;
2085

2086
  n = bvarith64_buffer_bitsize(b);
15,577✔
2087

2088
  assert(1 <= n && n <= 64);
2089

2090
  switch (e->tag) {
15,577✔
2091
  case TAG_BV64:
3,671✔
2092
    if (e->val.bv64.bitsize != n) {
3,671✔
2093
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2094
    }
2095
    bvarith64_buffer_add_const(b, e->val.bv64.value);
3,671✔
2096
    break;
3,671✔
2097

2098
  case TAG_BV:
×
2099
    assert(e->val.bv.bitsize != n);
2100
    raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2101
    break;
2102

2103
  case TAG_TERM:
9,422✔
2104
  case TAG_SPECIAL_TERM:
2105
    check_bv_term(stack, e, n);
9,422✔
2106
    bvarith64_buffer_add_term(b, __yices_globals.terms, e->val.term);
9,422✔
2107
    break;
9,422✔
2108

2109
  case TAG_BVARITH64_BUFFER:
833✔
2110
    if (bvarith64_buffer_bitsize(e->val.bvarith64_buffer) != n) {
833✔
2111
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2112
    }
2113
    bvarith64_buffer_add_buffer(b, e->val.bvarith64_buffer);
833✔
2114
    break;
833✔
2115

2116
  case TAG_BVARITH_BUFFER:
×
2117
    assert(bvarith_buffer_bitsize(e->val.bvarith_buffer) != n);
2118
    raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2119
    break;
2120

2121
  case TAG_BVLOGIC_BUFFER:
1,651✔
2122
    if (bvlogic_buffer_bitsize(e->val.bvlogic_buffer) != n) {
1,651✔
2123
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2124
    }
2125
    // convert e to a term then add to b
2126
    t = bvlogic_buffer_get_term(e->val.bvlogic_buffer);
1,651✔
2127
    bvarith64_buffer_add_term(b, __yices_globals.terms, t);
1,651✔
2128
    break;
1,651✔
2129

2130
  default:
×
2131
    raise_exception(stack, e, TSTACK_BVARITH_ERROR);
×
2132
    break;
2133
  }
2134
}
15,577✔
2135

2136

2137
/*
2138
 * Subtract element e from buffer b.
2139
 * - raise an exception if e is not a bitvector of equal size as b
2140
 */
2141
void bva64_sub_elem(tstack_t *stack, bvarith64_buffer_t *b, stack_elem_t *e) {
2,225✔
2142
  uint32_t n;
2143
  term_t t;
2144

2145
  n = bvarith64_buffer_bitsize(b);
2,225✔
2146

2147
  assert(1 <= n && n <= 64);
2148

2149
  switch (e->tag) {
2,225✔
2150
  case TAG_BV64:
1,348✔
2151
    if (e->val.bv64.bitsize != n) {
1,348✔
2152
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2153
    }
2154
    bvarith64_buffer_sub_const(b, e->val.bv64.value);
1,348✔
2155
    break;
1,348✔
2156

2157
  case TAG_BV:
×
2158
    assert(e->val.bv.bitsize != n);
2159
    raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2160
    break;
2161

2162
  case TAG_TERM:
622✔
2163
  case TAG_SPECIAL_TERM:
2164
    check_bv_term(stack, e, n);
622✔
2165
    bvarith64_buffer_sub_term(b, __yices_globals.terms, e->val.term);
622✔
2166
    break;
622✔
2167

2168
  case TAG_BVARITH64_BUFFER:
26✔
2169
    if (bvarith64_buffer_bitsize(e->val.bvarith64_buffer) != n) {
26✔
2170
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2171
    }
2172
    bvarith64_buffer_sub_buffer(b, e->val.bvarith64_buffer);
26✔
2173
    break;
26✔
2174

2175
  case TAG_BVARITH_BUFFER:
×
2176
    assert(bvarith_buffer_bitsize(e->val.bvarith_buffer) != n);
2177
    raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2178
    break;
2179

2180
  case TAG_BVLOGIC_BUFFER:
229✔
2181
    if (bvlogic_buffer_bitsize(e->val.bvlogic_buffer) != n) {
229✔
2182
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2183
    }
2184
    // convert e to a term then add to b
2185
    t = bvlogic_buffer_get_term(e->val.bvlogic_buffer);
229✔
2186
    bvarith64_buffer_sub_term(b, __yices_globals.terms, t);
229✔
2187
    break;
229✔
2188

2189
  default:
×
2190
    raise_exception(stack, e, TSTACK_BVARITH_ERROR);
×
2191
    break;
2192
  }
2193
}
2,225✔
2194

2195

2196

2197
/*
2198
 * Multiply b by element e
2199
 * - raise an exception if e is not a bitvector of equal size as b
2200
 *   or if there's a degree overflow
2201
 */
2202
void bva64_mul_elem(tstack_t *stack, bvarith64_buffer_t *b, stack_elem_t *e) {
1,059✔
2203
  term_table_t *terms;
2204
  uint32_t n;
2205
  term_t t;
2206

2207
  n = bvarith64_buffer_bitsize(b);
1,059✔
2208

2209
  assert(1 <= n && n <= 64);
2210

2211
  switch (e->tag) {
1,059✔
2212
  case TAG_BV64:
77✔
2213
    if (e->val.bv64.bitsize != n) {
77✔
2214
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2215
    }
2216
    bvarith64_buffer_mul_const(b, e->val.bv64.value);
77✔
2217
    break;
77✔
2218

2219
  case TAG_BV:
×
2220
    assert(e->val.bv.bitsize != n);
2221
    raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2222
    break;
2223

2224
  case TAG_TERM:
865✔
2225
  case TAG_SPECIAL_TERM:
2226
    check_bv_term(stack, e, n);
865✔
2227
    t = e->val.term;
865✔
2228
    terms = __yices_globals.terms;
865✔
2229
    if (! yices_check_bvmul64_term(b, t)) {
865✔
2230
      report_yices_error(stack);
×
2231
    }
2232
    bvarith64_buffer_mul_term(b, terms, t);
865✔
2233
    break;
865✔
2234

2235
  case TAG_BVARITH64_BUFFER:
×
2236
    if (bvarith64_buffer_bitsize(e->val.bvarith64_buffer) != n) {
×
2237
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2238
    }
2239
    if (! yices_check_bvmul64_buffer(b, e->val.bvarith64_buffer)) {
×
2240
      report_yices_error(stack);
×
2241
    }
2242
    bvarith64_buffer_mul_buffer(b, e->val.bvarith64_buffer);
×
2243
    break;
×
2244

2245
  case TAG_BVARITH_BUFFER:
×
2246
    assert(bvarith_buffer_bitsize(e->val.bvarith_buffer) != n);
2247
    raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2248
    break;
2249

2250
  case TAG_BVLOGIC_BUFFER:
117✔
2251
    if (bvlogic_buffer_bitsize(e->val.bvlogic_buffer) != n) {
117✔
2252
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2253
    }
2254
    // convert e to a term then add to b
2255
    t = bvlogic_buffer_get_term(e->val.bvlogic_buffer);
117✔
2256
    if (! yices_check_bvmul64_term(b, t)) {
117✔
2257
      report_yices_error(stack);
×
2258
    }
2259
    bvarith64_buffer_mul_term(b, __yices_globals.terms, t);
117✔
2260
    break;
117✔
2261

2262
  default:
×
2263
    raise_exception(stack, e, TSTACK_BVARITH_ERROR);
×
2264
    break;
2265
  }
2266
}
1,059✔
2267

2268

2269

2270

2271

2272
/*
2273
 * BIT-VECTOR ARITHMETIC: BITSIZE > 64
2274
 */
2275

2276
/*
2277
 * Add element e to buffer b.
2278
 * - raise an exception if e is not a bitvector of equal size as b
2279
 */
2280
void bva_add_elem(tstack_t *stack, bvarith_buffer_t *b, stack_elem_t *e) {
1,526✔
2281
  uint32_t n;
2282
  term_t t;
2283

2284
  n = bvarith_buffer_bitsize(b);
1,526✔
2285

2286
  assert(n > 64);
2287

2288
  switch (e->tag) {
1,526✔
2289
  case TAG_BV64:
×
2290
    assert(e->val.bv64.bitsize != n);
2291
    raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2292
    break;
2293

2294
  case TAG_BV:
658✔
2295
    if (e->val.bv.bitsize != n) {
658✔
2296
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2297
    }
2298
    bvarith_buffer_add_const(b, e->val.bv.data);
658✔
2299
    break;
658✔
2300

2301
  case TAG_TERM:
775✔
2302
  case TAG_SPECIAL_TERM:
2303
    check_bv_term(stack, e, n);
775✔
2304
    bvarith_buffer_add_term(b, __yices_globals.terms, e->val.term);
775✔
2305
    break;
775✔
2306

2307
  case TAG_BVARITH64_BUFFER:
×
2308
    assert(bvarith64_buffer_bitsize(e->val.bvarith64_buffer) != n);
2309
    raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2310
    break;
2311

2312
  case TAG_BVARITH_BUFFER:
×
2313
    if (bvarith_buffer_bitsize(e->val.bvarith_buffer) != n) {
×
2314
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2315
    }
2316
    bvarith_buffer_add_buffer(b, e->val.bvarith_buffer);
×
2317
    break;
×
2318

2319
  case TAG_BVLOGIC_BUFFER:
93✔
2320
    if (bvlogic_buffer_bitsize(e->val.bvlogic_buffer) != n) {
93✔
2321
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2322
    }
2323
    // convert e to a term then add to b
2324
    t = bvlogic_buffer_get_term(e->val.bvlogic_buffer);
93✔
2325
    bvarith_buffer_add_term(b, __yices_globals.terms, t);
93✔
2326
    break;
93✔
2327

2328
  default:
×
2329
    raise_exception(stack, e, TSTACK_BVARITH_ERROR);
×
2330
    break;
2331
  }
2332
}
1,526✔
2333

2334

2335
/*
2336
 * Subtract element e from buffer b.
2337
 * - raise an exception if e is not a bitvector of equal size as b
2338
 */
2339
void bva_sub_elem(tstack_t *stack, bvarith_buffer_t *b, stack_elem_t *e) {
140✔
2340
  uint32_t n;
2341
  term_t t;
2342

2343
  n = bvarith_buffer_bitsize(b);
140✔
2344

2345
  assert(n > 64);
2346

2347
  switch (e->tag) {
140✔
2348
  case TAG_BV64:
×
2349
    assert(e->val.bv64.bitsize != n);
2350
    raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2351
    break;
2352

2353
  case TAG_BV:
18✔
2354
    if (e->val.bv.bitsize != n) {
18✔
2355
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2356
    }
2357
    bvarith_buffer_sub_const(b, e->val.bv.data);
18✔
2358
    break;
18✔
2359

2360
  case TAG_TERM:
115✔
2361
  case TAG_SPECIAL_TERM:
2362
    check_bv_term(stack, e, n);
115✔
2363
    bvarith_buffer_sub_term(b, __yices_globals.terms, e->val.term);
115✔
2364
    break;
115✔
2365

2366
  case TAG_BVARITH64_BUFFER:
×
2367
    assert(bvarith64_buffer_bitsize(e->val.bvarith64_buffer) != n);
2368
    raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2369
    break;
2370

2371
  case TAG_BVARITH_BUFFER:
×
2372
    if (bvarith_buffer_bitsize(e->val.bvarith_buffer) != n) {
×
2373
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2374
    }
2375
    bvarith_buffer_sub_buffer(b, e->val.bvarith_buffer);
×
2376
    break;
×
2377

2378
  case TAG_BVLOGIC_BUFFER:
7✔
2379
    if (bvlogic_buffer_bitsize(e->val.bvlogic_buffer) != n) {
7✔
2380
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2381
    }
2382
    // convert e to a term then add to b
2383
    t = bvlogic_buffer_get_term(e->val.bvlogic_buffer);
7✔
2384
    bvarith_buffer_sub_term(b, __yices_globals.terms, t);
7✔
2385
    break;
7✔
2386

2387
  default:
×
2388
    raise_exception(stack, e, TSTACK_BVARITH_ERROR);
×
2389
    break;
2390
  }
2391
}
140✔
2392

2393

2394
/*
2395
 * Multiply b by element e
2396
 * - raise an exception if e is not a bitvector of equal size as b
2397
 *   or if there's a degree overflow
2398
 */
2399
void bva_mul_elem(tstack_t *stack, bvarith_buffer_t *b, stack_elem_t *e) {
74✔
2400
  term_table_t *terms;
2401
  uint32_t n;
2402
  term_t t;
2403

2404
  n = bvarith_buffer_bitsize(b);
74✔
2405

2406
  assert(n > 64);
2407

2408
  switch (e->tag) {
74✔
2409
  case TAG_BV64:
×
2410
    assert(e->val.bv64.bitsize != n);
2411
    raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2412
    break;
2413

2414
  case TAG_BV:
×
2415
    if (e->val.bv.bitsize != n) {
×
2416
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2417
    }
2418
    bvarith_buffer_mul_const(b, e->val.bv.data);
×
2419
    break;
×
2420

2421
  case TAG_TERM:
53✔
2422
  case TAG_SPECIAL_TERM:
2423
    check_bv_term(stack, e, n);
53✔
2424
    t = e->val.term;
53✔
2425
    terms = __yices_globals.terms;
53✔
2426
    if (! yices_check_bvmul_term(b, t)) {
53✔
2427
      report_yices_error(stack);
×
2428
    }
2429
    bvarith_buffer_mul_term(b, terms, t);
53✔
2430
    break;
53✔
2431

2432
  case TAG_BVARITH64_BUFFER:
×
2433
    assert(bvarith64_buffer_bitsize(e->val.bvarith64_buffer) != n);
2434
    raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2435
    break;
2436

2437
  case TAG_BVARITH_BUFFER:
×
2438
    if (bvarith_buffer_bitsize(e->val.bvarith_buffer) != n) {
×
2439
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2440
    }
2441
    if (! yices_check_bvmul_buffer(b, e->val.bvarith_buffer)) {
×
2442
      report_yices_error(stack);
×
2443
    }
2444
    bvarith_buffer_mul_buffer(b, e->val.bvarith_buffer);
×
2445
    break;
×
2446

2447
  case TAG_BVLOGIC_BUFFER:
21✔
2448
    if (bvlogic_buffer_bitsize(e->val.bvlogic_buffer) != n) {
21✔
2449
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2450
    }
2451
    // convert e to a term then add to b
2452
    t = bvlogic_buffer_get_term(e->val.bvlogic_buffer);
21✔
2453
    if (! yices_check_bvmul_term(b, t)) {
21✔
2454
      report_yices_error(stack);
×
2455
    }
2456
    bvarith_buffer_mul_term(b, __yices_globals.terms, t);
21✔
2457
    break;
21✔
2458

2459
  default:
×
2460
    raise_exception(stack, e, TSTACK_BVARITH_ERROR);
×
2461
    break;
2462
  }
2463
}
74✔
2464

2465

2466

2467
/*
2468
 * BV-NEG (for both 64/generic bitsizes)
2469
 */
2470

2471
/*
2472
 * Store the opposite of term t in e:
2473
 * - raise an exception if t is not a bitvector.
2474
 * - overwrite the current value of e.
2475
 */
2476
static void copy_bvneg_term(tstack_t *stack, stack_elem_t *e, term_t t) {
371✔
2477
  bvarith_buffer_t *b;
2478
  bvarith64_buffer_t *b64;
2479
  term_table_t *terms;
2480
  uint32_t *tmp;
2481
  uint32_t n, k;
2482

2483
  terms = __yices_globals.terms;
371✔
2484
  if (! yices_check_bv_term(t)) {
371✔
2485
    report_yices_error(stack);
×
2486
  }
2487

2488
  n = term_bitsize(terms, t);
371✔
2489

2490
  switch (term_kind(terms, t)) {
371✔
2491
  case BV64_CONSTANT:
32✔
2492
    // copy the opposite of t's value into e:
2493
    assert(n == bvconst64_term_desc(terms, t)->bitsize);
2494
    e->tag = TAG_BV64;
32✔
2495
    e->val.bv64.bitsize = n;
32✔
2496
    e->val.bv64.value = - bvconst64_term_desc(terms, t)->value;
32✔
2497
    break;
32✔
2498

2499
  case BV_CONSTANT:
7✔
2500
    assert(n == bvconst_term_desc(terms, t)->bitsize);
2501
    // allocate a buffer for the result
2502
    k = (n + 31) >> 5; // number of words
7✔
2503
    tmp = bvconst_alloc(k);
7✔
2504
    bvconst_negate2(tmp, k, bvconst_term_desc(terms, t)->data); // tmp := - data
7✔
2505
    // store the result as a BV element
2506
    e->tag = TAG_BV;
7✔
2507
    e->val.bv.bitsize = n;
7✔
2508
    e->val.bv.data = tmp;
7✔
2509
    break;
7✔
2510

2511
  default:
332✔
2512
    if (n <= 64) {
332✔
2513
      b64 = tstack_get_bva64buffer(stack, n);
291✔
2514
      assert(bvarith64_buffer_is_zero(b64));
2515
      bvarith64_buffer_sub_term(b64, terms, t);
291✔
2516

2517
      // overwrite e
2518
      e->tag = TAG_BVARITH64_BUFFER;
291✔
2519
      e->val.bvarith64_buffer = b64;
291✔
2520

2521
      // reset stack->bva64buffer to NULL
2522
      assert(b64 == stack->bva64buffer);
2523
      stack->bva64buffer = NULL;
291✔
2524

2525
    } else {
2526
      b = tstack_get_bvabuffer(stack, n);
41✔
2527
      assert(bvarith_buffer_is_zero(b));
2528
      bvarith_buffer_sub_term(b, terms, t);
41✔
2529

2530
      // overwrite e
2531
      e->tag = TAG_BVARITH_BUFFER;
41✔
2532
      e->val.bvarith_buffer = b;
41✔
2533

2534
      // reset stack->bvabuffer to NULL
2535
      assert(b == stack->bvabuffer);
2536
      stack->bvabuffer = NULL;
41✔
2537
    }
2538
    break;
332✔
2539
  }
2540

2541
}
371✔
2542

2543
/*
2544
 * Negate element e in place. Raise an exception if e is not a bitvector element.
2545
 */
2546
void bvneg_elem(tstack_t *stack, stack_elem_t *e) {
688✔
2547
  bvlogic_buffer_t *b;
2548
  uint32_t k;
2549
  term_t t;
2550

2551
  switch (e->tag) {
688✔
2552
  case TAG_BV64:
150✔
2553
    e->val.bv64.value = - e->val.bv64.value;
150✔
2554
    break;
150✔
2555

2556
  case TAG_BV:
35✔
2557
    k = (e->val.bv.bitsize + 31) >> 5; // number of words
35✔
2558
    bvconst_negate(e->val.bv.data, k);
35✔
2559
    break;
35✔
2560

2561
  case TAG_TERM:
361✔
2562
  case TAG_SPECIAL_TERM:
2563
    t = e->val.term;
361✔
2564
    copy_bvneg_term(stack, e, t);
361✔
2565
    break;
361✔
2566

2567
  case TAG_BVARITH64_BUFFER:
130✔
2568
    bvarith64_buffer_negate(e->val.bvarith64_buffer);
130✔
2569
    break;
130✔
2570

2571
  case TAG_BVARITH_BUFFER:
2✔
2572
    bvarith_buffer_negate(e->val.bvarith_buffer);
2✔
2573
    break;
2✔
2574

2575
  case TAG_BVLOGIC_BUFFER:
10✔
2576
    b = e->val.bvlogic_buffer;
10✔
2577
    if (! yices_check_bvlogic_buffer(b)){
10✔
2578
      report_yices_error(stack);
×
2579
    }
2580
    // convert to a term then negate.
2581
    t = bvlogic_buffer_get_term(b);
10✔
2582
    recycle_bvlbuffer(stack, b); // since e is going to be overwritten
10✔
2583
    copy_bvneg_term(stack, e, t);
10✔
2584
    break;
10✔
2585

2586
  default:
×
2587
    raise_exception(stack, e, TSTACK_BVARITH_ERROR);
×
2588
    break;
2589
  }
2590
}
688✔
2591

2592

2593

2594

2595
/*
2596
 * BITVECTOR LOGICAL OPERATIONS
2597
 */
2598

2599
/*
2600
 * Copy element e in bvlogic buffer b
2601
 * Raise an exception if e is not a bitvector
2602
 */
2603
void bvl_set_elem(tstack_t *stack, bvlogic_buffer_t *b, stack_elem_t *e) {
39,713✔
2604
  term_t t;
2605

2606
  switch (e->tag) {
39,713✔
2607
  case TAG_BV64:
2,524✔
2608
    bvlogic_buffer_set_constant64(b, e->val.bv64.bitsize, e->val.bv64.value);
2,524✔
2609
    break;
2,524✔
2610

2611
  case TAG_BV:
566✔
2612
    bvlogic_buffer_set_constant(b, e->val.bv.bitsize, e->val.bv.data);
566✔
2613
    break;
566✔
2614

2615
  case TAG_TERM:
30,938✔
2616
  case TAG_SPECIAL_TERM:
2617
    t = e->val.term;
30,938✔
2618
    if (! yices_check_bv_term(t)) { // not a bitvector
30,938✔
2619
      report_yices_error(stack);
×
2620
    }
2621
    bvlogic_buffer_set_term(b, __yices_globals.terms, t);
30,938✔
2622
    break;
30,938✔
2623

2624
  case TAG_BVARITH64_BUFFER:
230✔
2625
    t = bvarith64_buffer_get_term(e->val.bvarith64_buffer);
230✔
2626
    bvlogic_buffer_set_term(b, __yices_globals.terms, t);
230✔
2627
    break;
230✔
2628

2629
  case TAG_BVARITH_BUFFER:
11✔
2630
    t = bvarith_buffer_get_term(e->val.bvarith_buffer);
11✔
2631
    bvlogic_buffer_set_term(b, __yices_globals.terms, t);
11✔
2632
    break;
11✔
2633

2634
  case TAG_BVLOGIC_BUFFER:
5,444✔
2635
    bvlogic_buffer_set_buffer(b, e->val.bvlogic_buffer);
5,444✔
2636
    break;
5,444✔
2637

2638
  default:
×
2639
    raise_exception(stack, e, TSTACK_BVLOGIC_ERROR);
×
2640
    break;
2641
  }
2642
}
39,713✔
2643

2644

2645

2646
/*
2647
 * Copy element segment [i .. j] of e into bvlogic buffer b
2648
 * Raise an exception if e is not a bitvector.
2649
 * - i and j must be valid (i.e., 0 <= i <= j < e's bitsize)
2650
 */
2651
void bvl_set_slice_elem(tstack_t *stack, bvlogic_buffer_t *b, uint32_t i, uint32_t j, stack_elem_t *e) {
15,902✔
2652
  term_t t;
2653

2654
  assert(i <= j);
2655

2656
  switch (e->tag) {
15,902✔
2657
  case TAG_BV64:
6,412✔
2658
    assert(j < e->val.bv64.bitsize);
2659
    bvlogic_buffer_set_slice_constant64(b, i, j, e->val.bv64.value);
6,412✔
2660
    break;
6,412✔
2661

2662
  case TAG_BV:
2✔
2663
    assert(j < e->val.bv.bitsize);
2664
    bvlogic_buffer_set_slice_constant(b, i, j, e->val.bv.data);
2✔
2665
    break;
2✔
2666

2667
  case TAG_TERM:
7,825✔
2668
  case TAG_SPECIAL_TERM:
2669
    t = e->val.term;
7,825✔
2670
    if (! yices_check_bv_term(t)) { // not a bitvector
7,825✔
2671
      report_yices_error(stack);
×
2672
    }
2673
    bvlogic_buffer_set_slice_term(b, __yices_globals.terms, i, j, t);
7,825✔
2674
    break;
7,825✔
2675

2676
  case TAG_BVARITH64_BUFFER:
122✔
2677
    t = bvarith64_buffer_get_term(e->val.bvarith64_buffer);
122✔
2678
    bvlogic_buffer_set_slice_term(b, __yices_globals.terms, i, j, t);
122✔
2679
    break;
122✔
2680

2681
  case TAG_BVARITH_BUFFER:
1✔
2682
    t = bvarith_buffer_get_term(e->val.bvarith_buffer);
1✔
2683
    bvlogic_buffer_set_slice_term(b, __yices_globals.terms, i, j, t);
1✔
2684
    break;
1✔
2685

2686
  case TAG_BVLOGIC_BUFFER:
1,540✔
2687
    bvlogic_buffer_set_slice_buffer(b, i, j, e->val.bvlogic_buffer);
1,540✔
2688
    break;
1,540✔
2689

2690
  default:
×
2691
    raise_exception(stack, e, TSTACK_BVLOGIC_ERROR);
×
2692
    break;
2693
  }
2694
}
15,902✔
2695

2696

2697

2698
/*
2699
 * Check whether e is a bitvector constant
2700
 */
2701
bool elem_is_bvconst(stack_elem_t *e) {
5,303✔
2702
  term_kind_t k;
2703

2704
  switch (e->tag) {
5,303✔
2705
  case TAG_BV64:
3,114✔
2706
  case TAG_BV:
2707
    return true;
3,114✔
2708

2709
  case TAG_TERM:
1,052✔
2710
  case TAG_SPECIAL_TERM:
2711
    k = term_kind(__yices_globals.terms, e->val.term);
1,052✔
2712
    return k == BV64_CONSTANT || k == BV_CONSTANT;
1,052✔
2713

2714
  case TAG_BVARITH64_BUFFER:
1✔
2715
    bvarith64_buffer_normalize(e->val.bvarith64_buffer);
1✔
2716
    return bvarith64_buffer_is_constant(e->val.bvarith64_buffer);
1✔
2717

2718
  case TAG_BVARITH_BUFFER:
×
2719
    bvarith_buffer_normalize(e->val.bvarith_buffer);
×
2720
    return bvarith_buffer_is_constant(e->val.bvarith_buffer);
×
2721

2722
  case TAG_BVLOGIC_BUFFER:
1,136✔
2723
    return bvlogic_buffer_is_constant(e->val.bvlogic_buffer);
1,136✔
2724

2725
  default:
×
2726
    return false;
×
2727
  }
2728
}
2729

2730

2731
/*
2732
 * Copy term t into c:
2733
 * - t must be a BV_CONSTANT or BV64_CONSTANT
2734
 */
2735
static void bvconstant_copy_term(bvconstant_t *c, term_t t) {
577✔
2736
  term_table_t *terms;
2737
  bvconst_term_t *d;
2738
  bvconst64_term_t *d64;
2739

2740
  terms = __yices_globals.terms;
577✔
2741
  if (term_kind(terms, t) == BV64_CONSTANT) {
577✔
2742
    d64 = bvconst64_term_desc(terms, t);
81✔
2743
    bvconstant_copy64(c, d64->bitsize, d64->value);
81✔
2744
  } else {
2745
    d = bvconst_term_desc(terms, t);
496✔
2746
    bvconstant_copy(c, d->bitsize, d->data);
496✔
2747
  }
2748
}
577✔
2749

2750

2751
/*
2752
 * Copy the constant value of e into c
2753
 * - e must satisfy elem_is_bvconst(e)
2754
 */
2755
void bvconst_set_elem(bvconstant_t *c, stack_elem_t *e) {
4,557✔
2756
  assert(elem_is_bvconst(e));
2757

2758
  switch (e->tag) {
4,557✔
2759
  case TAG_BV64:
3,070✔
2760
    bvconstant_copy64(c, e->val.bv64.bitsize, e->val.bv64.value);
3,070✔
2761
    break;
3,070✔
2762

2763
  case TAG_BV:
44✔
2764
    bvconstant_copy(c, e->val.bv.bitsize, e->val.bv.data);
44✔
2765
    break;
44✔
2766

2767
  case TAG_TERM:
577✔
2768
  case TAG_SPECIAL_TERM:
2769
    bvconstant_copy_term(c, e->val.term);
577✔
2770
    break;
577✔
2771

2772
  case TAG_BVARITH64_BUFFER:
1✔
2773
    bvarith64_buffer_copy_constant(e->val.bvarith64_buffer, c);
1✔
2774
    break;
1✔
2775

2776
  case TAG_BVARITH_BUFFER:
×
2777
    bvarith_buffer_copy_constant(e->val.bvarith_buffer, c);
×
2778
    break;
×
2779

2780
  case TAG_BVLOGIC_BUFFER:
865✔
2781
    bvlogic_buffer_get_constant(e->val.bvlogic_buffer, c);
865✔
2782
    break;
865✔
2783

2784
  default: // should not happen
×
2785
    assert(false);
2786
    break;
×
2787
  }
2788
}
4,557✔
2789

2790

2791
/*
2792
 * Bitwise operations between buffer b and element e
2793
 */
2794
void bvand_elem(tstack_t *stack, bvlogic_buffer_t *b, stack_elem_t *e) {
6,287✔
2795
  uint32_t n;
2796
  term_t t;
2797

2798
  n = bvlogic_buffer_bitsize(b);
6,287✔
2799

2800
  switch (e->tag) {
6,287✔
2801
  case TAG_BV64:
545✔
2802
    if (e->val.bv64.bitsize != n) {
545✔
2803
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2804
    }
2805
    bvlogic_buffer_and_constant64(b, e->val.bv64.bitsize, e->val.bv64.value);
545✔
2806
    break;
545✔
2807

2808
  case TAG_BV:
45✔
2809
    if (e->val.bv.bitsize != n) {
45✔
2810
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2811
    }
2812
    bvlogic_buffer_and_constant(b, e->val.bv.bitsize, e->val.bv.data);
45✔
2813
    break;
45✔
2814

2815
  case TAG_TERM:
3,574✔
2816
  case TAG_SPECIAL_TERM:
2817
    check_bv_term(stack, e, n);
3,574✔
2818
    bvlogic_buffer_and_term(b, __yices_globals.terms, e->val.term);
3,574✔
2819
    break;
3,574✔
2820

2821
  case TAG_BVARITH64_BUFFER:
48✔
2822
    if (bvarith64_buffer_bitsize(e->val.bvarith64_buffer) != n) {
48✔
2823
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2824
    }
2825
    t = bvarith64_buffer_get_term(e->val.bvarith64_buffer);
48✔
2826
    bvlogic_buffer_and_term(b, __yices_globals.terms, t);
48✔
2827
    break;
48✔
2828

2829
  case TAG_BVARITH_BUFFER:
10✔
2830
    if (bvarith_buffer_bitsize(e->val.bvarith_buffer) != n) {
10✔
2831
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2832
    }
2833
    t = bvarith_buffer_get_term(e->val.bvarith_buffer);
10✔
2834
    bvlogic_buffer_and_term(b, __yices_globals.terms, t);
10✔
2835
    break;
10✔
2836

2837
  case TAG_BVLOGIC_BUFFER:
2,065✔
2838
    if (bvlogic_buffer_bitsize(e->val.bvlogic_buffer) != n) {
2,065✔
2839
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2840
    }
2841
    bvlogic_buffer_and_buffer(b, e->val.bvlogic_buffer);
2,065✔
2842
    break;
2,065✔
2843

2844
  default:
×
2845
    raise_exception(stack, e, TSTACK_BVLOGIC_ERROR);
×
2846
  }
2847
}
6,287✔
2848

2849
void bvor_elem(tstack_t *stack, bvlogic_buffer_t *b, stack_elem_t *e) {
3,408✔
2850
  uint32_t n;
2851
  term_t t;
2852

2853
  n = bvlogic_buffer_bitsize(b);
3,408✔
2854

2855
  switch (e->tag) {
3,408✔
2856
  case TAG_BV64:
39✔
2857
    if (e->val.bv64.bitsize != n) {
39✔
2858
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2859
    }
2860
    bvlogic_buffer_or_constant64(b, e->val.bv64.bitsize, e->val.bv64.value);
39✔
2861
    break;
39✔
2862

2863
  case TAG_BV:
2✔
2864
    if (e->val.bv.bitsize != n) {
2✔
2865
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2866
    }
2867
    bvlogic_buffer_or_constant(b, e->val.bv.bitsize, e->val.bv.data);
2✔
2868
    break;
2✔
2869

2870
  case TAG_TERM:
1,191✔
2871
  case TAG_SPECIAL_TERM:
2872
    check_bv_term(stack, e, n);
1,191✔
2873
    bvlogic_buffer_or_term(b, __yices_globals.terms, e->val.term);
1,191✔
2874
    break;
1,191✔
2875

2876
  case TAG_BVARITH64_BUFFER:
1✔
2877
    if (bvarith64_buffer_bitsize(e->val.bvarith64_buffer) != n) {
1✔
2878
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2879
    }
2880
    t = bvarith64_buffer_get_term(e->val.bvarith64_buffer);
1✔
2881
    bvlogic_buffer_or_term(b, __yices_globals.terms, t);
1✔
2882
    break;
1✔
2883

2884
  case TAG_BVARITH_BUFFER:
1✔
2885
    if (bvarith_buffer_bitsize(e->val.bvarith_buffer) != n) {
1✔
2886
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2887
    }
2888
    t = bvarith_buffer_get_term(e->val.bvarith_buffer);
1✔
2889
    bvlogic_buffer_or_term(b, __yices_globals.terms, t);
1✔
2890
    break;
1✔
2891

2892
  case TAG_BVLOGIC_BUFFER:
2,174✔
2893
    if (bvlogic_buffer_bitsize(e->val.bvlogic_buffer) != n) {
2,174✔
2894
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2895
    }
2896
    bvlogic_buffer_or_buffer(b, e->val.bvlogic_buffer);
2,174✔
2897
    break;
2,174✔
2898

2899
  default:
×
2900
    raise_exception(stack, e, TSTACK_BVLOGIC_ERROR);
×
2901
  }
2902
}
3,408✔
2903

2904
void bvxor_elem(tstack_t *stack, bvlogic_buffer_t *b, stack_elem_t *e) {
1,914✔
2905
  uint32_t n;
2906
  term_t t;
2907

2908
  n = bvlogic_buffer_bitsize(b);
1,914✔
2909

2910
  switch (e->tag) {
1,914✔
2911
  case TAG_BV64:
57✔
2912
    if (e->val.bv64.bitsize != n) {
57✔
2913
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2914
    }
2915
    bvlogic_buffer_xor_constant64(b, e->val.bv64.bitsize, e->val.bv64.value);
57✔
2916
    break;
57✔
2917

2918
  case TAG_BV:
×
2919
    if (e->val.bv.bitsize != n) {
×
2920
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2921
    }
2922
    bvlogic_buffer_xor_constant(b, e->val.bv.bitsize, e->val.bv.data);
×
2923
    break;
×
2924

2925
  case TAG_TERM:
621✔
2926
  case TAG_SPECIAL_TERM:
2927
    check_bv_term(stack, e, n);
621✔
2928
    bvlogic_buffer_xor_term(b, __yices_globals.terms, e->val.term);
621✔
2929
    break;
621✔
2930

2931
  case TAG_BVARITH64_BUFFER:
16✔
2932
    if (bvarith64_buffer_bitsize(e->val.bvarith64_buffer) != n) {
16✔
2933
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2934
    }
2935
    t = bvarith64_buffer_get_term(e->val.bvarith64_buffer);
16✔
2936
    bvlogic_buffer_xor_term(b, __yices_globals.terms, t);
16✔
2937
    break;
16✔
2938

2939
  case TAG_BVARITH_BUFFER:
×
2940
    if (bvarith_buffer_bitsize(e->val.bvarith_buffer) != n) {
×
2941
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2942
    }
2943
    t = bvarith_buffer_get_term(e->val.bvarith_buffer);
×
2944
    bvlogic_buffer_xor_term(b, __yices_globals.terms, t);
×
2945
    break;
×
2946

2947
  case TAG_BVLOGIC_BUFFER:
1,220✔
2948
    if (bvlogic_buffer_bitsize(e->val.bvlogic_buffer) != n) {
1,220✔
2949
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2950
    }
2951
    bvlogic_buffer_xor_buffer(b, e->val.bvlogic_buffer);
1,220✔
2952
    break;
1,220✔
2953

2954
  default:
×
2955
    raise_exception(stack, e, TSTACK_BVLOGIC_ERROR);
×
2956
    break;
2957
  }
2958
}
1,914✔
2959

2960
void bvcomp_elem(tstack_t *stack, bvlogic_buffer_t *b, stack_elem_t *e) {
527✔
2961
  uint32_t n;
2962
  term_t t;
2963

2964
  n = bvlogic_buffer_bitsize(b);
527✔
2965

2966
  switch (e->tag) {
527✔
2967
  case TAG_BV64:
375✔
2968
    if (e->val.bv64.bitsize != n) {
375✔
2969
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2970
    }
2971
    bvlogic_buffer_comp_constant64(b, e->val.bv64.bitsize, e->val.bv64.value);
375✔
2972
    break;
375✔
2973

2974
  case TAG_BV:
×
2975
    if (e->val.bv.bitsize != n) {
×
2976
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2977
    }
2978
    bvlogic_buffer_comp_constant(b, e->val.bv.bitsize, e->val.bv.data);
×
2979
    break;
×
2980

2981
  case TAG_TERM:
108✔
2982
  case TAG_SPECIAL_TERM:
2983
    check_bv_term(stack, e, n);
108✔
2984
    bvlogic_buffer_comp_term(b, __yices_globals.terms, e->val.term);
108✔
2985
    break;
108✔
2986

2987
  case TAG_BVARITH64_BUFFER:
×
2988
    if (bvarith64_buffer_bitsize(e->val.bvarith64_buffer) != n) {
×
2989
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2990
    }
2991
    t = bvarith64_buffer_get_term(e->val.bvarith64_buffer);
×
2992
    bvlogic_buffer_comp_term(b, __yices_globals.terms, t);
×
2993
    break;
×
2994

2995
  case TAG_BVARITH_BUFFER:
×
2996
    if (bvarith_buffer_bitsize(e->val.bvarith_buffer) != n) {
×
2997
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
2998
    }
2999
    t = bvarith_buffer_get_term(e->val.bvarith_buffer);
×
3000
    bvlogic_buffer_comp_term(b, __yices_globals.terms, t);
×
3001
    break;
×
3002

3003
  case TAG_BVLOGIC_BUFFER:
44✔
3004
    if (bvlogic_buffer_bitsize(e->val.bvlogic_buffer) != n) {
44✔
3005
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
3006
    }
3007
    bvlogic_buffer_comp_buffer(b, e->val.bvlogic_buffer);
44✔
3008
    break;
44✔
3009

3010
  default:
×
3011
    raise_exception(stack, e, TSTACK_BVLOGIC_ERROR);
×
3012
    break;
3013
  }
3014
}
527✔
3015

3016

3017
// add e to the right of b (i.e., high-order bits are from b, low-order bits from e)
3018
void bvconcat_elem(tstack_t *stack, bvlogic_buffer_t *b, stack_elem_t *e) {
14,423✔
3019
  term_t t;
3020

3021
  switch (e->tag) {
14,423✔
3022
  case TAG_BV64:
2,038✔
3023
    bvlogic_buffer_concat_right_constant64(b, e->val.bv64.bitsize, e->val.bv64.value);
2,038✔
3024
    break;
2,038✔
3025

3026
  case TAG_BV:
22✔
3027
    bvlogic_buffer_concat_right_constant(b, e->val.bv.bitsize, e->val.bv.data);
22✔
3028
    break;
22✔
3029

3030
  case TAG_TERM:
10,132✔
3031
  case TAG_SPECIAL_TERM:
3032
    t = e->val.term;
10,132✔
3033
    if (! yices_check_bv_term(t)) {
10,132✔
3034
      report_yices_error(stack);
×
3035
    }
3036
    bvlogic_buffer_concat_right_term(b, __yices_globals.terms, t);
10,132✔
3037
    break;
10,132✔
3038

3039
  case TAG_BVARITH64_BUFFER:
60✔
3040
    t = bvarith64_buffer_get_term(e->val.bvarith64_buffer);
60✔
3041
    bvlogic_buffer_concat_right_term(b, __yices_globals.terms, t);
60✔
3042
    break;
60✔
3043

3044
  case TAG_BVARITH_BUFFER:
×
3045
    t = bvarith_buffer_get_term(e->val.bvarith_buffer);
×
3046
    bvlogic_buffer_concat_right_term(b, __yices_globals.terms, t);
×
3047
    break;
×
3048

3049
  case TAG_BVLOGIC_BUFFER:
2,171✔
3050
    bvlogic_buffer_concat_right_buffer(b, e->val.bvlogic_buffer);
2,171✔
3051
    break;
2,171✔
3052

3053
  default:
×
3054
    raise_exception(stack, e, TSTACK_BVLOGIC_ERROR);
×
3055
    break;
3056
  }
3057
}
14,423✔
3058

3059

3060

3061

3062

3063
/*
3064
 * Every eval function takes three parameters
3065
 * - the stack
3066
 * - f = an array of stack elements.
3067
 * - n = size of this array
3068
 *
3069
 * f is set to the start of the arguments on the top frame,
3070
 * n = the number of arguments
3071
 *
3072
 * For example, if the stack contains a frame with operator code MK_AND
3073
 * and 4 arguments, then the top frame is [MK_AND <arg1> ... <arg4>]
3074
 *
3075
 * tstack_eval will invoke eval_mk_and(stack, f, n)
3076
 * with f pointing to array [<arg1> .... <arg4>] and n = 4
3077
 *
3078
 * With every eval function, there's a check function that takes the
3079
 * same parameters and raises an exception if the arguments or frame
3080
 * are incorrect.
3081
 */
3082

3083

3084
/*
3085
 * COMMANDS MAPPING NAMES TO TYPES OR TERMS
3086
 */
3087

3088
/*
3089
 * [define-type <symbol> ]
3090
 * [define-type <symbol> <type> ]
3091
 */
3092
static void check_define_type(tstack_t *stack, stack_elem_t *f, uint32_t n) {
58✔
3093
  check_op(stack, DEFINE_TYPE);
58✔
3094
  check_size(stack, (n == 1 || n == 2));
58✔
3095
  check_tag(stack, f, TAG_SYMBOL);
58✔
3096
  if (n == 2) check_tag(stack, f+1, TAG_TYPE);
58✔
3097
}
58✔
3098

3099
static void eval_define_type(tstack_t *stack, stack_elem_t *f, uint32_t n) {
58✔
3100
  type_t tau;
3101

3102
  if (n == 1) {
58✔
3103
    tau = _o_yices_new_uninterpreted_type();
27✔
3104
  } else {
3105
    tau = f[1].val.type;
31✔
3106
  }
3107
  _o_yices_set_type_name(tau, f[0].val.string);
58✔
3108

3109
  tstack_pop_frame(stack);
58✔
3110
  no_result(stack);
58✔
3111
}
58✔
3112

3113
/*
3114
 * [define-term <symbol> <type> ]
3115
 * [define-term <symbol> <type> <term> ]
3116
 */
3117
static void check_define_term(tstack_t *stack, stack_elem_t *f, uint32_t n) {
12,055✔
3118
  check_op(stack, DEFINE_TERM);
12,055✔
3119
  check_size(stack, (n == 2 || n == 3));
12,055✔
3120
  check_tag(stack, f, TAG_SYMBOL);
12,055✔
3121
  check_tag(stack, f+1, TAG_TYPE);
12,055✔
3122
  // no need to check val[f+2]: get_term will raise an exception if
3123
  // it can't be converted to a term.
3124
}
12,055✔
3125

3126
static void eval_define_term(tstack_t *stack, stack_elem_t *f, uint32_t n) {
12,055✔
3127
  type_t tau;
3128
  term_t t;
3129

3130
  tau = f[1].val.type;
12,055✔
3131
  if (n == 2) {
12,055✔
3132
    t = _o_yices_new_uninterpreted_term(tau);
12,030✔
3133
  } else {
3134
    t = get_term(stack, f+2);
25✔
3135
    if (! is_subtype(__yices_globals.types, term_type(__yices_globals.terms, t), tau)) {
25✔
3136
      raise_exception(stack, f+2, TSTACK_TYPE_ERROR_IN_DEFTERM);
×
3137
    }
3138
  }
3139
  _o_yices_set_term_name(t, f[0].val.string);
12,055✔
3140

3141
  tstack_pop_frame(stack);
12,055✔
3142
  no_result(stack);
12,055✔
3143
}
12,055✔
3144

3145

3146
/*
3147
 * [bind <string> <term>  .... <string> <term>]
3148
 */
3149
// bind is parallel: we process a block of pairs <name, term>
3150
// the result of bind is a list of bindings object
3151
// they are pushed on the stack and will be removed when we
3152
// pop out of the enclosing let.
3153

3154
static void check_bind(tstack_t *stack, stack_elem_t *f, uint32_t n) {
169,591✔
3155
  uint32_t i;
3156

3157
  check_op(stack, BIND);
169,591✔
3158
  check_size(stack, n >= 2);
169,591✔
3159
  check_size(stack, (n & 0x1) == 0);
169,591✔
3160
  for (i=0; i<n; i+=2) {
365,255✔
3161
    check_tag(stack, f+i, TAG_SYMBOL);
195,664✔
3162
  }
3163
}
169,591✔
3164

3165
static void eval_bind(tstack_t *stack, stack_elem_t *f, uint32_t n) {
169,591✔
3166
  term_t *values;
3167
  char **names;
3168
  char *name;
3169
  term_t t;
3170
  uint32_t i, j, nb;
3171

3172
  nb = n/2;
169,591✔
3173
  assert(nb > 0);
3174

3175
  values = get_aux_buffer(stack, nb);
169,591✔
3176
  names = get_name_buffer(stack, nb);
169,591✔
3177
  j = 0;
169,591✔
3178
  for (i=0; i<nb; i++) {
365,255✔
3179
    name = f[j].val.string;
195,664✔
3180
    j ++;
195,664✔
3181
    t = get_term(stack, f+j);
195,664✔
3182
    j ++;
195,664✔
3183
    _o_yices_set_term_name(t, name);
195,664✔
3184
    names[i] = name;
195,664✔
3185
    values[i] = t;
195,664✔
3186
  }
3187
  tstack_pop_frame(stack);
169,591✔
3188

3189
  // push back the bindings
3190
  for (i=0; i<nb; i++) {
365,255✔
3191
    set_binding_result(stack, values[i], names[i]);
195,664✔
3192
  }
3193
}
169,591✔
3194

3195

3196
/*
3197
 * [declare-var <string> <type>] --> [<string> <var>]
3198
 */
3199
static void check_declare_var(tstack_t *stack, stack_elem_t *f, uint32_t n) {
3,149✔
3200
  check_op(stack, DECLARE_VAR);
3,149✔
3201
  check_size(stack, n == 2);
3,149✔
3202
  check_tag(stack, f, TAG_SYMBOL);
3,149✔
3203
  check_tag(stack, f+1, TAG_TYPE);
3,149✔
3204
}
3,149✔
3205

3206
static void eval_declare_var(tstack_t *stack, stack_elem_t *f, uint32_t n) {
3,149✔
3207
  type_t tau;
3208
  term_t var;
3209
  char *name;
3210

3211
  name = f[0].val.string;
3,149✔
3212
  tau = f[1].val.type;
3,149✔
3213
  var = _o_yices_new_variable(tau);
3,149✔
3214

3215
  _o_yices_set_term_name(var, name);
3,149✔
3216
  tstack_pop_frame(stack);
3,149✔
3217
  set_binding_result(stack, var, name);
3,149✔
3218
}
3,149✔
3219

3220

3221
/*
3222
 * [declare-type-var <symbol> ] --> [type_binding <symbol> <type-var]
3223
 */
3224
static void check_declare_type_var(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
3225
  check_op(stack, DECLARE_TYPE_VAR);
×
3226
  check_size(stack, n == 1);
×
3227
  check_tag(stack, f, TAG_SYMBOL);
×
3228
}
×
3229

3230
static void eval_declare_type_var(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
3231
  type_t tau;
3232
  char *name;
3233

3234
  name = f[0].val.string;
×
3235
  tau = yices_type_variable(stack->tvar_id);
×
3236
  assert(tau != NULL_TYPE);
3237
  stack->tvar_id ++;
×
3238

3239
  yices_set_type_name(tau, name);
×
3240
  tstack_pop_frame(stack);
×
3241
  set_type_binding_result(stack, tau, name);
×
3242
}
×
3243

3244

3245
/*
3246
 * [let [do-bind <binding> ... <binding> <term>]
3247
 */
3248
static void check_let(tstack_t *stack, stack_elem_t *f, uint32_t n) {
169,591✔
3249
  check_op(stack, LET);
169,591✔
3250
  check_size(stack, n>=2);
169,591✔
3251
  check_all_tags(stack, f, f + (n-1), TAG_BINDING);
169,591✔
3252
}
169,591✔
3253

3254
static void eval_let(tstack_t *stack, stack_elem_t *f, uint32_t n) {
169,591✔
3255
  copy_result_and_pop_frame(stack, f + (n-1));
169,591✔
3256
}
169,591✔
3257

3258

3259
/*
3260
 * TYPE CONSTRUCTORS
3261
 */
3262

3263
/*
3264
 * [mk-bv-type <rational>]
3265
 */
3266
static void check_mk_bv_type(tstack_t *stack, stack_elem_t *f, uint32_t n) {
46,471✔
3267
  check_op(stack, MK_BV_TYPE);
46,471✔
3268
  check_size(stack, n == 1);
46,471✔
3269
  check_tag(stack, f, TAG_RATIONAL);
46,471✔
3270
}
46,471✔
3271

3272
static void eval_mk_bv_type(tstack_t *stack, stack_elem_t *f, uint32_t n) {
46,471✔
3273
  int32_t size;
3274
  type_t tau;
3275

3276
  size = get_integer(stack, f);
46,471✔
3277
  if (size <= 0) {
46,471✔
3278
    raise_exception(stack, f, TSTACK_NONPOSITIVE_BVSIZE);
×
3279
  }
3280
  tau = _o_yices_bv_type(size);
46,471✔
3281
  check_type(stack, tau);
46,471✔
3282

3283
  tstack_pop_frame(stack);
46,471✔
3284
  set_type_result(stack, tau);
46,471✔
3285
}
46,471✔
3286

3287
/*
3288
 * [mk-ff-type <rational>]
3289
 */
NEW
3290
static void check_mk_ff_type(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
NEW
3291
  check_op(stack, MK_FF_TYPE);
×
NEW
3292
  check_size(stack, n == 1);
×
NEW
3293
  check_tag(stack, f, TAG_RATIONAL);
×
NEW
3294
}
×
3295

NEW
3296
static void eval_mk_ff_type(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
3297
  type_t tau;
3298
  mpz_t order;
3299

NEW
3300
  mpz_init(order);
×
NEW
3301
  get_integer_mpz(stack, f, order);
×
3302

NEW
3303
  tau = _o_yices_ff_type(order);
×
NEW
3304
  mpz_clear(order);
×
3305

NEW
3306
  if (tau == NULL_TYPE) {
×
NEW
3307
    raise_exception(stack, f, TSTACK_INVALID_FFSIZE);
×
3308
  }
3309

NEW
3310
  check_type(stack, tau);
×
3311

NEW
3312
  tstack_pop_frame(stack);
×
NEW
3313
  set_type_result(stack, tau);
×
NEW
3314
}
×
3315

3316
/*
3317
 * [mk-scalar-type <string> ... <string>]
3318
 */
3319
static void check_mk_scalar_type(tstack_t *stack, stack_elem_t *f, uint32_t n) {
7✔
3320
  check_op(stack, MK_SCALAR_TYPE);
7✔
3321
  check_size(stack, n >= 1);
7✔
3322
  check_all_tags(stack, f, f+n, TAG_SYMBOL);
7✔
3323
  check_distinct_scalar_names(stack, f, n);
7✔
3324
}
7✔
3325

3326
static void eval_mk_scalar_type(tstack_t *stack, stack_elem_t *f, uint32_t n) {
7✔
3327
  type_t tau;
3328
  int32_t i, card;
3329
  term_t x;
3330

3331
  // build the type
3332
  card = n;
7✔
3333
  tau = _o_yices_new_scalar_type(card);
7✔
3334
  assert(tau != NULL_TYPE);
3335

3336
  for (i=0; i<card; i++) {
16✔
3337
    x = _o_yices_constant(tau, i);
9✔
3338
    assert(x != NULL_TERM);
3339
    _o_yices_set_term_name(x, f[i].val.string);
9✔
3340
  }
3341

3342
  tstack_pop_frame(stack);
7✔
3343
  set_type_result(stack, tau);
7✔
3344
}
7✔
3345

3346
/*
3347
 * [mk-tuple-type <type> ... <type>]
3348
 */
3349
static void check_mk_tuple_type(tstack_t *stack, stack_elem_t *f, uint32_t n) {
10✔
3350
  check_op(stack, MK_TUPLE_TYPE);
10✔
3351
  check_size(stack, n >= 1);
10✔
3352
  check_all_tags(stack, f, f+n, TAG_TYPE);
10✔
3353
}
10✔
3354

3355
static void eval_mk_tuple_type(tstack_t *stack, stack_elem_t *f, uint32_t n) {
10✔
3356
  type_t *tau, sigma;
3357
  uint32_t i;
3358

3359
  tau = get_aux_buffer(stack, n);
10✔
3360

3361
  for (i=0; i<n; i++) {
29✔
3362
    tau[i] = f[i].val.type;
19✔
3363
  }
3364
  sigma = _o_yices_tuple_type(n, tau);
10✔
3365
  assert(sigma != NULL_TYPE);
3366

3367
  tstack_pop_frame(stack);
10✔
3368
  set_type_result(stack, sigma);
10✔
3369
}
10✔
3370

3371
/*
3372
 * [mk-fun-type <type> ... <type> <type> ]
3373
 *
3374
 * To support SMT-LIB, we also allow [mk-fun-type <type>] and
3375
 * just return <type>.
3376
 */
3377
static void check_mk_fun_type(tstack_t *stack, stack_elem_t *f, uint32_t n) {
4,778✔
3378
  check_op(stack, MK_FUN_TYPE);
4,778✔
3379
  check_size(stack, n >= 1);
4,778✔
3380
  check_all_tags(stack, f, f+n, TAG_TYPE);
4,778✔
3381
}
4,778✔
3382

3383
static void eval_mk_fun_type(tstack_t *stack, stack_elem_t *f, uint32_t n) {
4,778✔
3384
  type_t *tau, sigma;
3385
  uint32_t i;
3386

3387
  if (n >= 2) {
4,778✔
3388
    // first n-1 types are the domain, last one is the range
3389
    tau = get_aux_buffer(stack, n);
425✔
3390

3391
    for (i=0; i<n; i++) {
1,281✔
3392
      tau[i] = f[i].val.type;
856✔
3393
    }
3394

3395
    n --;
425✔
3396
    sigma = _o_yices_function_type(n, tau, tau[n]);
425✔
3397
  } else {
3398
    sigma = f[0].val.type;
4,353✔
3399
  }
3400

3401
  assert(sigma != NULL_TYPE);
3402
  tstack_pop_frame(stack);
4,778✔
3403
  set_type_result(stack, sigma);
4,778✔
3404
}
4,778✔
3405

3406

3407
/*
3408
 * [mk-app-type <macro> <type> ... <type> ]
3409
 */
3410
static void check_mk_app_type(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
3411
  check_op(stack, MK_APP_TYPE);
×
3412
  check_size(stack, n >= 2);
×
3413
  check_tag(stack, f, TAG_MACRO);
×
3414
  check_all_tags(stack, f+1, f+n, TAG_TYPE);
×
3415
}
×
3416

3417
static void eval_mk_app_type(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
3418
  type_t *tau, sigma;
3419
  int32_t id;
3420
  uint32_t i;
3421

3422
  assert(n > 0);
3423
  id = f[0].val.macro;
×
3424

3425
  n --;
×
3426
  f ++;
×
3427
  tau = get_aux_buffer(stack, n);
×
3428
  for (i=0; i<n; i++) {
×
3429
    tau[i] = f[i].val.type;
×
3430
  }
3431
  sigma = yices_instance_type(id, n, tau);
×
3432
  check_type(stack, sigma);
×
3433

3434
  tstack_pop_frame(stack);
×
3435
  set_type_result(stack, sigma);
×
3436
}
×
3437

3438

3439
/*
3440
 * TERM CONSTRUCTORS
3441
 */
3442

3443
/*
3444
 * [mk-apply <term> .... <term>]
3445
 */
3446
static void check_mk_apply(tstack_t *stack, stack_elem_t *f, uint32_t n) {
33,278✔
3447
  check_op(stack, MK_APPLY);
33,278✔
3448
  check_size(stack, n >= 2);
33,278✔
3449
}
33,278✔
3450

3451
static void eval_mk_apply(tstack_t *stack, stack_elem_t *f, uint32_t n) {
33,278✔
3452
  term_t arg[n], fun, t;
33,278✔
3453
  uint32_t i;
3454

3455
  fun = get_term(stack, f);
33,278✔
3456
  n --; // number of arguments
33,278✔
3457
  f ++;
33,278✔
3458
  for (i=0; i<n; i++) {
85,257✔
3459
    arg[i] = get_term(stack, f + i);
51,979✔
3460
  }
3461
  t = _o_yices_application(fun, n, arg);
33,278✔
3462
  check_term(stack, t);
33,278✔
3463

3464
  tstack_pop_frame(stack);
33,278✔
3465
  set_term_result(stack, t);
33,278✔
3466
}
33,278✔
3467

3468

3469
/*
3470
 * [mk-ite <term> <term> <term>]
3471
 */
3472
static void check_mk_ite(tstack_t *stack, stack_elem_t *f, uint32_t n) {
70,993✔
3473
  check_op(stack, MK_ITE);
70,993✔
3474
  check_size(stack, n == 3);
70,993✔
3475
}
70,993✔
3476

3477
static void eval_mk_ite(tstack_t *stack, stack_elem_t *f, uint32_t n) {
70,993✔
3478
  term_t cond, left, right, t;
3479

3480
  cond = get_term(stack, f);
70,993✔
3481
  left = get_term(stack, f+1);
70,993✔
3482
  right = get_term(stack, f+2);
70,993✔
3483
  t = _o_yices_ite(cond, left, right);
70,993✔
3484
  check_term(stack, t);
70,993✔
3485

3486
  tstack_pop_frame(stack);
70,993✔
3487
  set_term_result(stack, t);
70,993✔
3488
}
70,993✔
3489

3490

3491
/*
3492
 * [mk-eq <term> <term>]
3493
 */
3494
static void check_mk_eq(tstack_t *stack, stack_elem_t *f, uint32_t n) {
4,462✔
3495
  check_op(stack, MK_EQ);
4,462✔
3496
  check_size(stack, n == 2);
4,462✔
3497
}
4,462✔
3498

3499
static void eval_mk_eq(tstack_t *stack, stack_elem_t *f, uint32_t n) {
4,462✔
3500
  term_t left, right, t;
3501

3502
  left = get_term(stack, f);
4,462✔
3503
  right = get_term(stack, f+1);
4,462✔
3504
  t = _o_yices_eq(left, right);
4,462✔
3505
  check_term(stack, t);
4,462✔
3506

3507
  tstack_pop_frame(stack);
4,462✔
3508
  set_term_result(stack, t);
4,462✔
3509
}
4,462✔
3510

3511

3512
/*
3513
 * [mk-diseq <term> <term>]
3514
 */
3515
static void check_mk_diseq(tstack_t *stack, stack_elem_t *f, uint32_t n) {
56✔
3516
  check_op(stack, MK_DISEQ);
56✔
3517
  check_size(stack, n == 2);
56✔
3518
}
56✔
3519

3520
static void eval_mk_diseq(tstack_t *stack, stack_elem_t *f, uint32_t n) {
56✔
3521
  term_t left, right, t;
3522

3523
  left = get_term(stack, f);
56✔
3524
  right = get_term(stack, f+1);
56✔
3525
  t = _o_yices_neq(left, right);
56✔
3526
  check_term(stack, t);
56✔
3527

3528
  tstack_pop_frame(stack);
56✔
3529
  set_term_result(stack, t);
56✔
3530
}
56✔
3531

3532

3533
/*
3534
 * [mk-distinct <term> ... <term>]
3535
 */
3536
static void check_mk_distinct(tstack_t *stack, stack_elem_t *f, uint32_t n) {
8,846✔
3537
  check_op(stack, MK_DISTINCT);
8,846✔
3538
  check_size(stack, n >= 2);
8,846✔
3539
}
8,846✔
3540

3541
static void eval_mk_distinct(tstack_t *stack, stack_elem_t *f, uint32_t n) {
8,846✔
3542
  term_t *arg, t;
3543
  uint32_t i;
3544

3545
  arg = get_aux_buffer(stack, n);
8,846✔
3546

3547
  for (i=0; i<n; i++) {
28,722✔
3548
    arg[i] = get_term(stack, f+i);
19,876✔
3549
  }
3550
  t = _o_yices_distinct(n, arg);
8,846✔
3551
  check_term(stack, t);
8,846✔
3552

3553
  tstack_pop_frame(stack);
8,846✔
3554
  set_term_result(stack, t);
8,846✔
3555
}
8,846✔
3556

3557

3558

3559

3560
/*
3561
 * [mk-not <term>]
3562
 */
3563
static void check_mk_not(tstack_t *stack, stack_elem_t *f, uint32_t n) {
122,168✔
3564
  check_op(stack, MK_NOT);
122,168✔
3565
  check_size(stack, n == 1);
122,168✔
3566
}
122,168✔
3567

3568
static void eval_mk_not(tstack_t *stack, stack_elem_t *f, uint32_t n) {
122,168✔
3569
  term_t t;
3570

3571
  t = _o_yices_not(get_term(stack, f));
122,168✔
3572
  check_term(stack, t);
122,168✔
3573

3574
  tstack_pop_frame(stack);
122,168✔
3575
  set_term_result(stack, t);
122,168✔
3576
}
122,168✔
3577

3578

3579
/*
3580
 * [mk-or <term> ... <term>]
3581
 */
3582
static void check_mk_or(tstack_t *stack, stack_elem_t *f, uint32_t n) {
40,985✔
3583
  check_op(stack, MK_OR);
40,985✔
3584
  check_size(stack, n >= 1);
40,985✔
3585
}
40,985✔
3586

3587
// use buffer here rather than
3588
static void eval_mk_or(tstack_t *stack, stack_elem_t *f, uint32_t n) {
40,985✔
3589
  term_t *arg, t;
3590
  uint32_t i;
3591

3592
  arg = get_aux_buffer(stack, n);
40,985✔
3593

3594
  for (i=0; i<n; i++) {
154,942✔
3595
    arg[i] = get_term(stack, f+i);
113,957✔
3596
  }
3597
  t = _o_yices_or(n, arg);
40,985✔
3598
  check_term(stack, t);
40,985✔
3599

3600
  tstack_pop_frame(stack);
40,985✔
3601
  set_term_result(stack, t);
40,985✔
3602
}
40,985✔
3603

3604

3605
/*
3606
 * [mk-and <term> ... <term>]
3607
 */
3608
static void check_mk_and(tstack_t *stack, stack_elem_t *f, uint32_t n) {
37,014✔
3609
  check_op(stack, MK_AND);
37,014✔
3610
  check_size(stack, n >= 1);
37,014✔
3611
}
37,014✔
3612

3613
static void eval_mk_and(tstack_t *stack, stack_elem_t *f, uint32_t n) {
37,014✔
3614
  term_t *arg, t;
3615
  uint32_t i;
3616

3617
  arg = get_aux_buffer(stack, n);
37,014✔
3618

3619
  for (i=0; i<n; i++) {
230,922✔
3620
    arg[i] = get_term(stack, f+i);
193,908✔
3621
  }
3622
  t = _o_yices_and(n, arg);
37,014✔
3623
  check_term(stack, t);
37,014✔
3624

3625
  tstack_pop_frame(stack);
37,014✔
3626
  set_term_result(stack, t);
37,014✔
3627
}
37,014✔
3628

3629

3630
/*
3631
 * [mk-xor <term> ... <term>]
3632
 */
3633
static void check_mk_xor(tstack_t *stack, stack_elem_t *f, uint32_t n) {
8,481✔
3634
  check_op(stack, MK_XOR);
8,481✔
3635
  check_size(stack, n >= 1);
8,481✔
3636
}
8,481✔
3637

3638
static void eval_mk_xor(tstack_t *stack, stack_elem_t *f, uint32_t n) {
8,481✔
3639
  term_t *arg, t;
3640
  uint32_t i;
3641

3642
  arg = get_aux_buffer(stack, n);
8,481✔
3643

3644
  for (i=0; i<n; i++) {
25,892✔
3645
    arg[i] = get_term(stack, f+i);
17,411✔
3646
  }
3647
  t = _o_yices_xor(n, arg);
8,481✔
3648
  check_term(stack, t);
8,481✔
3649

3650
  tstack_pop_frame(stack);
8,481✔
3651
  set_term_result(stack, t);
8,481✔
3652
}
8,481✔
3653

3654

3655
/*
3656
 * [mk-iff <term> ... <term>]
3657
 */
3658
static void check_mk_iff(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
3659
  check_op(stack, MK_IFF);
×
3660
  check_size(stack, n >= 1);
×
3661
}
×
3662

3663
static void eval_mk_iff(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
3664
  term_t t;
3665
  uint32_t i;
3666

3667
  t = get_term(stack, f);
×
3668
  for (i=1; i<n; i++) {
×
3669
    t = _o_yices_iff(t, get_term(stack, f+i));
×
3670
    check_term(stack, t);
×
3671
  }
3672
  tstack_pop_frame(stack);
×
3673
  set_term_result(stack, t);
×
3674
}
×
3675

3676

3677
/*
3678
 * [mk-implies <term> <term>]
3679
 */
3680
static void check_mk_implies(tstack_t *stack, stack_elem_t *f, uint32_t n) {
549✔
3681
  check_op(stack, MK_IMPLIES);
549✔
3682
  check_size(stack, n == 2);
549✔
3683
}
549✔
3684

3685
static void eval_mk_implies(tstack_t *stack, stack_elem_t *f, uint32_t n) {
549✔
3686
  term_t left, right, t;
3687

3688
  left = get_term(stack, f);
549✔
3689
  right = get_term(stack, f+1);
549✔
3690
  t = _o_yices_implies(left, right);
549✔
3691
  check_term(stack, t);
549✔
3692

3693
  tstack_pop_frame(stack);
549✔
3694
  set_term_result(stack, t);
549✔
3695
}
549✔
3696

3697

3698
/*
3699
 * [mk-tuple <term> ... <term>]
3700
 */
3701
static void check_mk_tuple(tstack_t *stack, stack_elem_t *f, uint32_t n) {
112✔
3702
  check_op(stack, MK_TUPLE);
112✔
3703
  check_size(stack, n >= 1);
112✔
3704
}
112✔
3705

3706
static void eval_mk_tuple(tstack_t *stack, stack_elem_t *f, uint32_t n) {
112✔
3707
  term_t arg[n], t;
112✔
3708
  uint32_t i;
3709

3710
  for (i=0; i<n; i++) {
336✔
3711
    arg[i] = get_term(stack, f+i);
224✔
3712
  }
3713
  t = _o_yices_tuple(n, arg);
112✔
3714
  check_term(stack, t);
112✔
3715

3716
  tstack_pop_frame(stack);
112✔
3717
  set_term_result(stack, t);
112✔
3718
}
112✔
3719

3720

3721
/*
3722
 * [mk-select <term> <rational>]
3723
 */
3724
static void check_mk_select(tstack_t *stack, stack_elem_t *f, uint32_t n) {
2,010✔
3725
  check_op(stack, MK_SELECT);
2,010✔
3726
  check_size(stack, n == 2);
2,010✔
3727
  check_tag(stack, f+1, TAG_RATIONAL);
2,010✔
3728
}
2,010✔
3729

3730
static void eval_mk_select(tstack_t *stack, stack_elem_t *f, uint32_t n) {
2,010✔
3731
  int32_t idx;
3732
  term_t t;
3733

3734
  idx = get_integer(stack, f+1);
2,010✔
3735
  t = _o_yices_select(idx, get_term(stack, f));
2,010✔
3736
  check_term(stack, t);
2,010✔
3737

3738
  tstack_pop_frame(stack);
2,010✔
3739
  set_term_result(stack, t);
2,010✔
3740
}
2,010✔
3741

3742

3743

3744
/*
3745
 * [mk-tuple-update <tuple> <rational> <newvalue> ]
3746
 */
3747
static void check_mk_tuple_update(tstack_t *stack, stack_elem_t *f, uint32_t n) {
553✔
3748
  check_op(stack, MK_TUPLE_UPDATE);
553✔
3749
  check_size(stack, n == 3);
553✔
3750
  check_tag(stack, f+1, TAG_RATIONAL);
553✔
3751
}
553✔
3752

3753

3754
static void eval_mk_tuple_update(tstack_t *stack, stack_elem_t *f, uint32_t n) {
553✔
3755
  int32_t idx;
3756
  term_t t, new_v;
3757

3758
  idx = get_integer(stack, f+1);
553✔
3759
  new_v = get_term(stack, f+2);
553✔
3760
  t = _o_yices_tuple_update(get_term(stack, f), idx, new_v);
553✔
3761
  check_term(stack, t);
553✔
3762

3763
  tstack_pop_frame(stack);
553✔
3764
  set_term_result(stack, t);
553✔
3765
}
553✔
3766

3767

3768
/*
3769
 * [mk-update <fun> <arg1> ... <argn> <newvalue>]
3770
 */
3771
static void check_mk_update(tstack_t *stack, stack_elem_t *f, uint32_t n) {
8,568✔
3772
  check_op(stack, MK_UPDATE);
8,568✔
3773
  check_size(stack, n >= 3);
8,568✔
3774
}
8,568✔
3775

3776
static void eval_mk_update(tstack_t *stack, stack_elem_t *f, uint32_t n) {
8,568✔
3777
  term_t arg[n], t;
8,568✔
3778
  uint32_t i;
3779

3780
  for (i=0; i<n; i++) {
34,280✔
3781
    arg[i] = get_term(stack, f+i);
25,712✔
3782
  }
3783
  t = _o_yices_update(arg[0], n-2, arg+1, arg[n-1]);
8,568✔
3784
  check_term(stack, t);
8,568✔
3785

3786
  tstack_pop_frame(stack);
8,568✔
3787
  set_term_result(stack, t);
8,568✔
3788
}
8,568✔
3789

3790

3791
/*
3792
 * [mk-forall <binding> ... <binding> <term>]
3793
 */
3794
static void check_mk_forall(tstack_t *stack, stack_elem_t *f, uint32_t n) {
601✔
3795
  check_op(stack, MK_FORALL);
601✔
3796
  check_size(stack, n >= 2);
601✔
3797
  check_all_tags(stack, f, f + (n-1), TAG_BINDING);
601✔
3798
  check_distinct_binding_names(stack, f, n-1);
601✔
3799
}
601✔
3800

3801
static void eval_mk_forall(tstack_t *stack, stack_elem_t *f, uint32_t n) {
601✔
3802
  term_t t, arg[n];
601✔
3803
  uint32_t i;
3804

3805
  for (i=0; i<n-1; i++) {
1,853✔
3806
    arg[i] = f[i].val.binding.term;
1,252✔
3807
  }
3808
  // body = last argument
3809
  arg[i] = get_term(stack, f + (n-1));
601✔
3810
  t = _o_yices_forall(n-1, arg, arg[n-1]);
601✔
3811
  check_term(stack, t);
601✔
3812

3813
  tstack_pop_frame(stack);
601✔
3814
  set_term_result(stack, t);
601✔
3815
}
601✔
3816

3817

3818
/*
3819
 * [mk-exists <binding> ... <binding> <term>]
3820
 */
3821
static void check_mk_exists(tstack_t *stack, stack_elem_t *f, uint32_t n) {
526✔
3822
  check_op(stack, MK_EXISTS);
526✔
3823
  check_size(stack, n >= 2);
526✔
3824
  check_all_tags(stack, f, f + (n-1), TAG_BINDING);
526✔
3825
  check_distinct_binding_names(stack, f, n-1);
526✔
3826
}
526✔
3827

3828
static void eval_mk_exists(tstack_t *stack, stack_elem_t *f, uint32_t n) {
526✔
3829
  term_t t, arg[n];
526✔
3830
  uint32_t i;
3831

3832
  for (i=0; i<n-1; i++) {
1,124✔
3833
    arg[i] = f[i].val.binding.term;
598✔
3834
  }
3835
  // body = last argument
3836
  arg[i] = get_term(stack, f + (n-1));
526✔
3837
  t = _o_yices_exists(n-1, arg, arg[n-1]);
526✔
3838
  check_term(stack, t);
526✔
3839

3840
  tstack_pop_frame(stack);
526✔
3841
  set_term_result(stack, t);
526✔
3842
}
526✔
3843

3844

3845
/*
3846
 * [mk-lambda <binding> ... <binding> <term>]
3847
 */
3848
static void check_mk_lambda(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
3849
  check_op(stack, MK_LAMBDA);
×
3850
  check_size(stack, n >= 2);
×
3851
  check_all_tags(stack, f, f + (n-1), TAG_BINDING);
×
3852
  check_distinct_binding_names(stack, f, n-1);
×
3853
}
×
3854

3855
static void eval_mk_lambda(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
3856
  term_t t, arg[n];
×
3857
  uint32_t i;
3858

3859
  for (i=0; i<n-1; i++) {
×
3860
    arg[i] = f[i].val.binding.term;
×
3861
  }
3862
  // body = last argument
3863
  arg[i] = get_term(stack, f + (n-1));
×
3864
  t = _o_yices_lambda(n-1, arg, arg[n-1]);
×
3865
  check_term(stack, t);
×
3866

3867
  tstack_pop_frame(stack);
×
3868
  set_term_result(stack, t);
×
3869
}
×
3870

3871

3872

3873

3874
/*
3875
 *  ARITHMETIC
3876
 */
3877

3878
/*
3879
 * [mk-add <arith> ... <arith>]
3880
 */
3881
static void check_mk_add(tstack_t *stack, stack_elem_t *f, uint32_t n) {
10,258✔
3882
  check_op(stack, MK_ADD);
10,258✔
3883
  check_size(stack, n>=1);
10,258✔
3884
}
10,258✔
3885

3886
static void eval_mk_add(tstack_t *stack, stack_elem_t *f, uint32_t n) {
10,258✔
3887
  uint32_t i;
3888
  rba_buffer_t *b;
3889

3890
  b = tstack_get_abuffer(stack);
10,258✔
3891
  for (i=0; i<n; i++) {
38,764✔
3892
    add_elem(stack, b, f+i);
28,506✔
3893
  }
3894
  tstack_pop_frame(stack);
10,258✔
3895
  set_arith_result(stack, b);
10,258✔
3896
}
10,258✔
3897

3898

3899
/*
3900
 * [mk-sub <arith> ... <arith>]
3901
 */
3902
static void check_mk_sub(tstack_t *stack, stack_elem_t *f, uint32_t n) {
18,277✔
3903
  check_op(stack, MK_SUB);
18,277✔
3904
  check_size(stack, n>=1);
18,277✔
3905
}
18,277✔
3906

3907
static void eval_mk_sub(tstack_t *stack, stack_elem_t *f, uint32_t n) {
18,277✔
3908
  uint32_t i;
3909
  rba_buffer_t *b;
3910

3911
  // if n == 1, we interpret this a unary minus (unlike yices-1.0.x)
3912
  if (n == 1) {
18,277✔
3913
    // [mk-neg xxx] ---> - xxx
3914
    neg_elem(stack, f);
10,865✔
3915
    copy_result_and_pop_frame(stack, f);
10,865✔
3916
  } else {
3917
    b = tstack_get_abuffer(stack);
7,412✔
3918
    add_elem(stack, b, f);
7,412✔
3919
    for (i=1; i<n; i++) {
15,040✔
3920
      sub_elem(stack, b, f+i);
7,628✔
3921
    }
3922
    tstack_pop_frame(stack);
7,412✔
3923
    set_arith_result(stack, b);
7,412✔
3924
  }
3925

3926
}
18,277✔
3927

3928

3929
/*
3930
 * [mk-neg <arith>]
3931
 */
3932
static void check_mk_neg(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
3933
  check_op(stack, MK_NEG);
×
3934
  check_size(stack, n==1);
×
3935
}
×
3936

3937
static void eval_mk_neg(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
3938
  neg_elem(stack, f);
×
3939
  copy_result_and_pop_frame(stack, f);
×
3940
}
×
3941

3942

3943
/*
3944
 * [mk-mul <arith> ... <arith>]
3945
 */
3946
static void check_mk_mul(tstack_t *stack, stack_elem_t *f, uint32_t n) {
10,287✔
3947
  check_op(stack, MK_MUL);
10,287✔
3948
  check_size(stack, n>=1);
10,287✔
3949
}
10,287✔
3950

3951
static void eval_mk_mul(tstack_t *stack, stack_elem_t *f, uint32_t n) {
10,287✔
3952
  uint32_t i;
3953
  rba_buffer_t *b;
3954

3955
  b = tstack_get_abuffer(stack);
10,287✔
3956
  add_elem(stack, b, f);
10,287✔
3957
  for (i=1; i<n; i++) {
35,098✔
3958
    mul_elem(stack, b, f+i);
24,811✔
3959
  }
3960
  tstack_pop_frame(stack);
10,287✔
3961
  set_arith_result(stack, b);
10,287✔
3962
}
10,287✔
3963

3964

3965
/*
3966
 * [mk-division <arith> <arith>]
3967
 */
3968
static void check_mk_division(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
3969
  check_op(stack, MK_DIVISION);
×
3970
  check_size(stack, n == 2);
×
3971
}
×
3972

3973
// GENERIC VERSION: THE DIVIDER CAN BE ZERO OR NON-CONSTANT
3974
static void eval_mk_division(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
3975
  rba_buffer_t *b;
3976
  rational_t divider;
3977
  term_t t1, t2, t;
3978

3979
  q_init(&divider);
×
3980
  if (elem_is_nz_constant(f + 1, &divider)) {
×
3981
    assert(q_is_nonzero(&divider));
3982
    // Division by a non-zero constant
3983
    if (f->tag == TAG_RATIONAL) {
×
3984
      q_div(&f->val.rational, &divider);
×
3985
      copy_result_and_pop_frame(stack, f);
×
3986
    } else {
3987
      b = tstack_get_abuffer(stack);
×
3988
      add_elem(stack, b, f);
×
3989
      rba_buffer_div_const(b, &divider);
×
3990
      tstack_pop_frame(stack);
×
3991
      set_arith_result(stack, b);
×
3992
    }
3993
  } else {
3994
    // Not a constant
3995
    t1 = get_term(stack, f);
×
3996
    t2 = get_term(stack, f+1);
×
3997
    t = _o_yices_division(t1, t2);
×
3998
    check_term(stack, t);
×
3999
    tstack_pop_frame(stack);
×
4000
    set_term_result(stack, t);
×
4001
  }
4002

4003
  /*
4004
   * It's safe to clear the divider only here.
4005
   * If the code above raises an exception, divider is still 0/1
4006
   * and q_clear would do nothing anyway.
4007
   */
4008
  q_clear(&divider);
×
4009
}
×
4010

4011

4012

4013

4014

4015

4016
/*
4017
 * [mk-pow <arith> <integer>]
4018
 */
4019
static void check_mk_pow(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4020
  check_op(stack, MK_POW);
×
4021
  check_size(stack, n == 2);
×
4022
  check_tag(stack, f+1, TAG_RATIONAL);
×
4023
}
×
4024

4025
static void eval_mk_pow(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4026
  int32_t exponent;
4027
  term_t t;
4028

4029
  exponent = get_integer(stack, f+1);
×
4030
  if (exponent < 0) {
×
4031
    raise_exception(stack, f+1, TSTACK_NEGATIVE_EXPONENT);
×
4032
  }
4033

4034
  /*
4035
   * Note: we could avoid creating the intermediate term t
4036
   * by calling directly the exponentiation functions for
4037
   * arith_buffers, rationals, etc.?
4038
   */
4039
  t = get_term(stack, f);
×
4040
  t = _o_yices_power(t, exponent);
×
4041
  check_term(stack, t);
×
4042

4043
  tstack_pop_frame(stack);
×
4044
  set_term_result(stack, t);
×
4045
}
×
4046

4047
/*
4048
 * [mk-ge <arith> <arith>]
4049
 */
4050
static void check_mk_ge(tstack_t *stack, stack_elem_t *f, uint32_t n) {
455✔
4051
  check_op(stack, MK_GE);
455✔
4052
  check_size(stack, n == 2);
455✔
4053
}
455✔
4054

4055
static void eval_mk_ge(tstack_t *stack, stack_elem_t *f, uint32_t n) {
455✔
4056
  rba_buffer_t *b;
4057
  term_t t;
4058

4059
  b = tstack_get_abuffer(stack);
455✔
4060
  add_elem(stack, b, f);
455✔
4061
  sub_elem(stack, b, f+1);
455✔
4062
  t = arith_buffer_get_geq0_atom(b); // term for [f] - [f+1] >= 0
455✔
4063
  assert(t != NULL_TERM);
4064

4065
  tstack_pop_frame(stack);
455✔
4066
  set_term_result(stack, t);
455✔
4067
}
455✔
4068

4069

4070
/*
4071
 * [mk-gt <arith> <arith>]
4072
 */
4073
static void check_mk_gt(tstack_t *stack, stack_elem_t *f, uint32_t n) {
10✔
4074
  check_op(stack, MK_GT);
10✔
4075
  check_size(stack, n == 2);
10✔
4076
}
10✔
4077

4078
static void eval_mk_gt(tstack_t *stack, stack_elem_t *f, uint32_t n) {
10✔
4079
  rba_buffer_t *b;
4080
  term_t t;
4081

4082
  b = tstack_get_abuffer(stack);
10✔
4083
  add_elem(stack, b, f);
10✔
4084
  sub_elem(stack, b, f+1);
10✔
4085
  t = arith_buffer_get_gt0_atom(b); // term for [f] - [f+1] > 0
10✔
4086
  assert(t != NULL_TERM);
4087

4088
  tstack_pop_frame(stack);
10✔
4089
  set_term_result(stack, t);
10✔
4090
}
10✔
4091

4092

4093
/*
4094
 * [mk-le <arith> <arith>]
4095
 */
4096
static void check_mk_le(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4097
  check_op(stack, MK_LE);
×
4098
  check_size(stack, n == 2);
×
4099
}
×
4100

4101
static void eval_mk_le(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4102
  rba_buffer_t *b;
4103
  term_t t;
4104

4105
  b = tstack_get_abuffer(stack);
×
4106
  add_elem(stack, b, f);
×
4107
  sub_elem(stack, b, f+1);
×
4108
  t = arith_buffer_get_leq0_atom(b); // term for [f] - [f+1] <= 0
×
4109
  assert(t != NULL_TERM);
4110

4111
  tstack_pop_frame(stack);
×
4112
  set_term_result(stack, t);
×
4113
}
×
4114

4115

4116
/*
4117
 * [mk-lt <arith> <arith>]
4118
 */
4119
static void check_mk_lt(tstack_t *stack, stack_elem_t *f, uint32_t n) {
9✔
4120
  check_op(stack, MK_LT);
9✔
4121
  check_size(stack, n == 2);
9✔
4122
}
9✔
4123

4124
static void eval_mk_lt(tstack_t *stack, stack_elem_t *f, uint32_t n) {
9✔
4125
  rba_buffer_t *b;
4126
  term_t t;
4127

4128
  b = tstack_get_abuffer(stack);
9✔
4129
  add_elem(stack, b, f);
9✔
4130
  sub_elem(stack, b, f+1);
9✔
4131
  t = arith_buffer_get_lt0_atom(b); // term for [f] - [f+1] < 0
9✔
4132
  assert(t != NULL_TERM);
4133

4134
  tstack_pop_frame(stack);
9✔
4135
  set_term_result(stack, t);
9✔
4136
}
9✔
4137

4138

4139

4140

4141

4142

4143
/*
4144
 * BITVECTOR ARITHMETIC
4145
 */
4146

4147
/*
4148
 * Build bitvector constant defined by val and size:
4149
 * - size = number of bits
4150
 * - val = value
4151
 * - f = frame index: it's used for error reporting only
4152
 * Raise an exception if size <= 0 or size > MAX_BV_SIZE or val is not a non-negative
4153
 * integer
4154
 *
4155
 * Warning: val is a pointer inside a stack element that is reset by q_clear on pop_frame.
4156
 * So we must make a copy before calling pop_frame
4157
 */
4158
void mk_bv_const_core(tstack_t *stack, stack_elem_t *f, int32_t size, rational_t *val) {
69,293✔
4159
  uint32_t k;
4160
  uint32_t *tmp;
4161
  uint64_t c;
4162

4163
  if (size <= 0) {
69,293✔
4164
    raise_exception(stack, f, TSTACK_NONPOSITIVE_BVSIZE);
×
4165
  }
4166

4167
  if (! yices_check_bvsize((uint32_t) size)) {
69,293✔
4168
    report_yices_error(stack);
×
4169
  }
4170

4171
  if (! q_is_integer(val) || ! q_is_nonneg(val)) {
69,293✔
4172
    raise_exception(stack, f, TSTACK_INVALID_BVCONSTANT);
×
4173
  }
4174

4175
  if (size <= 64) {
69,293✔
4176
    c =  bvconst64_from_q(size, val);
66,383✔
4177
    assert(c == norm64(c, size));
4178

4179
    tstack_pop_frame(stack);
66,383✔
4180
    set_bv64_result(stack, size, c);
66,383✔
4181

4182
  } else {
4183
    k = (size + 31) >> 5;
2,910✔
4184
    tmp = bvconst_alloc(k);
2,910✔
4185
    bvconst_set_q(tmp, k, val);
2,910✔
4186
    bvconst_normalize(tmp, size);
2,910✔
4187

4188
    tstack_pop_frame(stack);
2,910✔
4189
    set_bv_result(stack, size, tmp);
2,910✔
4190
  }
4191
}
69,293✔
4192

4193

4194
/*
4195
 * Sign-extend: bv = bitvector, idx = number of bits to add
4196
 */
4197
void mk_bv_sign_extend_core(tstack_t *stack, stack_elem_t *bv, stack_elem_t *idx) {
9,859✔
4198
  int32_t i;
4199
  bvlogic_buffer_t *b;
4200

4201
  i = get_integer(stack, idx);
9,859✔
4202
  b = tstack_get_bvlbuffer(stack);
9,859✔
4203
  bvl_set_elem(stack, b, bv);
9,859✔
4204
  if (! yices_check_bvextend(b, i)) {
9,859✔
4205
    report_yices_error(stack);
×
4206
  }
4207
  bvlogic_buffer_sign_extend(b, i + bvlogic_buffer_bitsize(b));
9,859✔
4208

4209
  tstack_pop_frame(stack);
9,859✔
4210
  set_bvlogic_result(stack, b);
9,859✔
4211
}
9,859✔
4212

4213

4214
/*
4215
 * Zero-extend: bv, idx as for sign-extend
4216
 */
4217
void mk_bv_zero_extend_core(tstack_t *stack, stack_elem_t *bv, stack_elem_t *idx) {
11,587✔
4218
  int32_t i;
4219
  bvlogic_buffer_t *b;
4220

4221
  i = get_integer(stack, idx);
11,587✔
4222
  b = tstack_get_bvlbuffer(stack);
11,587✔
4223
  bvl_set_elem(stack, b, bv);
11,587✔
4224
  if (! yices_check_bvextend(b, i)) {
11,587✔
4225
    report_yices_error(stack);
×
4226
  }
4227
  bvlogic_buffer_zero_extend(b, i + bvlogic_buffer_bitsize(b));
11,587✔
4228

4229
  tstack_pop_frame(stack);
11,587✔
4230
  set_bvlogic_result(stack, b);
11,587✔
4231
}
11,587✔
4232

4233

4234

4235

4236
/*
4237
 * [mk-bv-const <size> <value>]
4238
 */
4239
static void check_mk_bv_const(tstack_t *stack, stack_elem_t *f, uint32_t n) {
20✔
4240
  check_op(stack, MK_BV_CONST);
20✔
4241
  check_size(stack, n == 2);
20✔
4242
  check_tag(stack, f, TAG_RATIONAL);
20✔
4243
  check_tag(stack, f+1, TAG_RATIONAL);
20✔
4244
}
20✔
4245

4246
static void eval_mk_bv_const(tstack_t *stack, stack_elem_t *f, uint32_t n) {
20✔
4247
  int32_t size;
4248
  rational_t *val;
4249

4250
  size = get_integer(stack, f);
20✔
4251
  val = &f[1].val.rational;
20✔
4252
  mk_bv_const_core(stack, f, size, val);
20✔
4253
}
20✔
4254

4255

4256
/*
4257
 * [mk-bv-add <bv> ... <bv>]
4258
 */
4259
static void check_mk_bv_add(tstack_t *stack, stack_elem_t *f, uint32_t n) {
6,304✔
4260
  check_op(stack, MK_BV_ADD);
6,304✔
4261
  check_size(stack, n >= 1);
6,304✔
4262
}
6,304✔
4263

4264
static void eval_mk_bv_add(tstack_t *stack, stack_elem_t *f, uint32_t n) {
6,304✔
4265
  uint32_t i, bitsize;
4266
  bvarith_buffer_t *b;
4267
  bvarith64_buffer_t *b64;
4268

4269
  bitsize = elem_bitsize(stack, f);
6,304✔
4270
  if (bitsize <= 64) {
6,304✔
4271
    b64 = tstack_get_bva64buffer(stack, bitsize);
5,654✔
4272
    for (i=0; i<n; i++) {
17,968✔
4273
      bva64_add_elem(stack, b64, f+i);
12,314✔
4274
    }
4275
    tstack_pop_frame(stack);
5,654✔
4276
    set_bvarith64_result(stack, b64);
5,654✔
4277

4278
  } else {
4279
    b = tstack_get_bvabuffer(stack, bitsize);
650✔
4280
    for (i=0; i<n; i++) {
1,965✔
4281
      bva_add_elem(stack, b, f+i);
1,315✔
4282
    }
4283
    tstack_pop_frame(stack);
650✔
4284
    set_bvarith_result(stack, b);
650✔
4285
  }
4286
}
6,304✔
4287

4288

4289
/*
4290
 * [mk-bv-sub <bv> ... <bv>]
4291
 */
4292
static void check_mk_bv_sub(tstack_t *stack, stack_elem_t *f, uint32_t n) {
2,365✔
4293
  check_op(stack, MK_BV_SUB);
2,365✔
4294
  check_size(stack, n >= 2);
2,365✔
4295
}
2,365✔
4296

4297
static void eval_mk_bv_sub(tstack_t *stack, stack_elem_t *f, uint32_t n) {
2,365✔
4298
  uint32_t i, bitsize;
4299
  bvarith_buffer_t *b;
4300
  bvarith64_buffer_t *b64;
4301

4302
  bitsize = elem_bitsize(stack, f);
2,365✔
4303
  if (bitsize <= 64) {
2,365✔
4304
    b64 = tstack_get_bva64buffer(stack, bitsize);
2,225✔
4305
    bva64_add_elem(stack, b64, f);
2,225✔
4306
    for (i=1; i<n; i++) {
4,450✔
4307
      bva64_sub_elem(stack, b64, f+i);
2,225✔
4308
    }
4309

4310
    tstack_pop_frame(stack);
2,225✔
4311
    set_bvarith64_result(stack, b64);
2,225✔
4312

4313
  } else {
4314
    b = tstack_get_bvabuffer(stack, bitsize);
140✔
4315
    bva_add_elem(stack, b, f);
140✔
4316
    for (i=1; i<n; i++) {
280✔
4317
      bva_sub_elem(stack, b, f+i);
140✔
4318
    }
4319

4320
    tstack_pop_frame(stack);
140✔
4321
    set_bvarith_result(stack, b);
140✔
4322
  }
4323
}
2,365✔
4324

4325

4326
/*
4327
 * [mk-bv-mul <bv> ... <bv>]
4328
 */
4329
static void check_mk_bv_mul(tstack_t *stack, stack_elem_t *f, uint32_t n) {
1,109✔
4330
  check_op(stack, MK_BV_MUL);
1,109✔
4331
  check_size(stack, n >= 1);
1,109✔
4332
}
1,109✔
4333

4334
static void eval_mk_bv_mul(tstack_t *stack, stack_elem_t *f, uint32_t n) {
1,109✔
4335
  uint32_t i, bitsize;
4336
  bvarith_buffer_t *b;
4337
  bvarith64_buffer_t *b64;
4338

4339
  bitsize = elem_bitsize(stack, f);
1,109✔
4340
  if (bitsize <= 64) {
1,109✔
4341
    b64 = tstack_get_bva64buffer(stack, bitsize);
1,038✔
4342
    bva64_add_elem(stack, b64, f);
1,038✔
4343
    for (i=1; i<n; i++) {
2,097✔
4344
      bva64_mul_elem(stack, b64, f+i);
1,059✔
4345
    }
4346

4347
    tstack_pop_frame(stack);
1,038✔
4348
    set_bvarith64_result(stack, b64);
1,038✔
4349

4350
  } else {
4351
    b = tstack_get_bvabuffer(stack, bitsize);
71✔
4352
    bva_add_elem(stack, b, f);
71✔
4353
    for (i=1; i<n; i++) {
145✔
4354
      bva_mul_elem(stack, b, f+i);
74✔
4355
    }
4356

4357
    tstack_pop_frame(stack);
71✔
4358
    set_bvarith_result(stack, b);
71✔
4359
  }
4360
}
1,109✔
4361

4362

4363
/*
4364
 * [mk-bv-neg <bv>]
4365
 */
4366
static void check_mk_bv_neg(tstack_t *stack, stack_elem_t *f, uint32_t n) {
688✔
4367
  check_op(stack, MK_BV_NEG);
688✔
4368
  check_size(stack, n == 1);
688✔
4369
}
688✔
4370

4371
static void eval_mk_bv_neg(tstack_t *stack, stack_elem_t *f, uint32_t n) {
688✔
4372
  bvneg_elem(stack, f);
688✔
4373
  copy_result_and_pop_frame(stack, f);
688✔
4374
}
688✔
4375

4376

4377
/*
4378
 * [mk-bv-pow <bv> <integer]
4379
 */
4380
static void check_mk_bv_pow(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4381
  check_op(stack, MK_BV_POW);
×
4382
  check_size(stack, n == 2);
×
4383
  check_tag(stack, f+1, TAG_RATIONAL);
×
4384
}
×
4385

4386
static void eval_mk_bv_pow(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4387
  int32_t exponent;
4388
  term_t t;
4389

4390
  exponent = get_integer(stack, f+1);
×
4391
  if (exponent < 0) {
×
4392
    raise_exception(stack, f+1, TSTACK_NEGATIVE_EXPONENT);
×
4393
  }
4394

4395
  /*
4396
   * Note: we could avoid creating the intermediate term t
4397
   * by calling directly the exponentiation functions for
4398
   * arith_buffers, rationals, etc.?
4399
   */
4400
  t = get_term(stack, f);
×
4401
  t = _o_yices_bvpower(t, exponent);
×
4402
  check_term(stack, t);
×
4403

4404
  tstack_pop_frame(stack);
×
4405
  set_term_result(stack, t);
×
4406
}
×
4407

4408

4409
/*
4410
 * BITVECTOR LOGIC
4411
 */
4412

4413
/*
4414
 * [mk-bv-not <bv>]
4415
 */
4416
static void check_mk_bv_not(tstack_t *stack, stack_elem_t *f, uint32_t n) {
3,428✔
4417
  check_op(stack, MK_BV_NOT);
3,428✔
4418
  check_size(stack, n == 1);
3,428✔
4419
}
3,428✔
4420

4421
static void eval_mk_bv_not(tstack_t *stack, stack_elem_t *f, uint32_t n) {
3,428✔
4422
  bvlogic_buffer_t *b;
4423

4424
  b = tstack_get_bvlbuffer(stack);
3,428✔
4425
  bvl_set_elem(stack, b, f);
3,428✔
4426
  bvlogic_buffer_not(b);
3,428✔
4427
  tstack_pop_frame(stack);
3,428✔
4428
  set_bvlogic_result(stack, b);
3,428✔
4429
}
3,428✔
4430

4431

4432

4433
/*
4434
 * [mk-bv-and <bv> ... <bv>]
4435
 */
4436
static void check_mk_bv_and(tstack_t *stack, stack_elem_t *f, uint32_t n) {
4,900✔
4437
  check_op(stack, MK_BV_AND);
4,900✔
4438
  check_size(stack, n >= 1);
4,900✔
4439
}
4,900✔
4440

4441
static void eval_mk_bv_and(tstack_t *stack, stack_elem_t *f, uint32_t n) {
4,900✔
4442
  bvlogic_buffer_t *b;
4443
  uint32_t i;
4444

4445
  b = tstack_get_bvlbuffer(stack);
4,900✔
4446
  bvl_set_elem(stack, b, f);
4,900✔
4447
  for (i=1; i<n; i++) {
11,020✔
4448
    bvand_elem(stack, b, f+i);
6,120✔
4449
  }
4450
  tstack_pop_frame(stack);
4,900✔
4451
  set_bvlogic_result(stack, b);
4,900✔
4452
}
4,900✔
4453

4454

4455
/*
4456
 * [mk-bv-or <bv> ... <bv>]
4457
 */
4458
static void check_mk_bv_or(tstack_t *stack, stack_elem_t *f, uint32_t n) {
2,509✔
4459
  check_op(stack, MK_BV_OR);
2,509✔
4460
  check_size(stack, n >= 1);
2,509✔
4461
}
2,509✔
4462

4463
static void eval_mk_bv_or(tstack_t *stack, stack_elem_t *f, uint32_t n) {
2,509✔
4464
  bvlogic_buffer_t *b;
4465
  uint32_t i;
4466

4467
  b = tstack_get_bvlbuffer(stack);
2,509✔
4468
  bvl_set_elem(stack, b, f);
2,509✔
4469
  for (i=1; i<n; i++) {
5,668✔
4470
    bvor_elem(stack, b, f+i);
3,159✔
4471
  }
4472
  tstack_pop_frame(stack);
2,509✔
4473
  set_bvlogic_result(stack, b);
2,509✔
4474
}
2,509✔
4475

4476

4477
/*
4478
 * [mk-bv-xor <bv> ... <bv>]
4479
 */
4480
static void check_mk_bv_xor(tstack_t *stack, stack_elem_t *f, uint32_t n) {
1,309✔
4481
  check_op(stack, MK_BV_XOR);
1,309✔
4482
  check_size(stack, n >= 1);
1,309✔
4483
}
1,309✔
4484

4485
static void eval_mk_bv_xor(tstack_t *stack, stack_elem_t *f, uint32_t n) {
1,309✔
4486
  bvlogic_buffer_t *b;
4487
  uint32_t i;
4488

4489
  b = tstack_get_bvlbuffer(stack);
1,309✔
4490
  bvl_set_elem(stack, b, f);
1,309✔
4491
  for (i=1; i<n; i++) {
3,071✔
4492
    bvxor_elem(stack, b, f+i);
1,762✔
4493
  }
4494
  tstack_pop_frame(stack);
1,309✔
4495
  set_bvlogic_result(stack, b);
1,309✔
4496
}
1,309✔
4497

4498

4499
/*
4500
 * [mk-bv-nand <bv> ... <bv>]
4501
 */
4502
static void check_mk_bv_nand(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4503
  check_op(stack, MK_BV_NAND);
×
4504
  check_size(stack, n >= 1);
×
4505
}
×
4506

4507
static void eval_mk_bv_nand(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4508
  bvlogic_buffer_t *b;
4509
  uint32_t i;
4510

4511
  b = tstack_get_bvlbuffer(stack);
×
4512
  bvl_set_elem(stack, b, f);
×
4513
  for (i=1; i<n; i++) {
×
4514
    bvand_elem(stack, b, f+i);
×
4515
  }
4516
  bvlogic_buffer_not(b);
×
4517
  tstack_pop_frame(stack);
×
4518
  set_bvlogic_result(stack, b);
×
4519
}
×
4520

4521

4522
/*
4523
 * [mk-bv-nor <bv> ... <bv>]
4524
 */
4525
static void check_mk_bv_nor(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4526
  check_op(stack, MK_BV_NOR);
×
4527
  check_size(stack, n >= 1);
×
4528
}
×
4529

4530
static void eval_mk_bv_nor(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4531
  bvlogic_buffer_t *b;
4532
  uint32_t i;
4533

4534
  b = tstack_get_bvlbuffer(stack);
×
4535
  bvl_set_elem(stack, b, f);
×
4536
  for (i=1; i<n; i++) {
×
4537
    bvor_elem(stack, b, f+i);
×
4538
  }
4539
  bvlogic_buffer_not(b);
×
4540
  tstack_pop_frame(stack);
×
4541
  set_bvlogic_result(stack, b);
×
4542
}
×
4543

4544

4545
/*
4546
 * [mk-bv-xnor <bv> ... <bv>]
4547
 */
4548
static void check_mk_bv_xnor(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4549
  check_op(stack, MK_BV_XNOR);
×
4550
  check_size(stack, n >= 1);
×
4551
}
×
4552

4553
static void eval_mk_bv_xnor(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4554
  bvlogic_buffer_t *b;
4555
  uint32_t i;
4556

4557
  b = tstack_get_bvlbuffer(stack);
×
4558
  bvl_set_elem(stack, b, f);
×
4559
  for (i=1; i<n; i++) {
×
4560
    bvxor_elem(stack, b, f+i);
×
4561
  }
4562
  bvlogic_buffer_not(b);
×
4563
  tstack_pop_frame(stack);
×
4564
  set_bvlogic_result(stack, b);
×
4565
}
×
4566

4567

4568
/*
4569
 * [mk-bv-shift-left0 <bv> <rational>]
4570
 */
4571
static void check_mk_bv_shift_left0(tstack_t *stack, stack_elem_t *f, uint32_t n) {
1✔
4572
  check_op(stack, MK_BV_SHIFT_LEFT0);
1✔
4573
  check_size(stack, n == 2);
1✔
4574
  check_tag(stack, f+1, TAG_RATIONAL);
1✔
4575
}
1✔
4576

4577
static void eval_mk_bv_shift_left0(tstack_t *stack, stack_elem_t *f, uint32_t n) {
1✔
4578
  int32_t index;
4579
  bvlogic_buffer_t *b;
4580

4581
  index = get_integer(stack, f+1);
1✔
4582
  b = tstack_get_bvlbuffer(stack);
1✔
4583
  bvl_set_elem(stack, b, f);
1✔
4584
  if (! yices_check_bitshift(b, index)) {
1✔
4585
    report_yices_error(stack);
×
4586
  }
4587
  bvlogic_buffer_shift_left0(b, index);
1✔
4588
  tstack_pop_frame(stack);
1✔
4589
  set_bvlogic_result(stack, b);
1✔
4590
}
1✔
4591

4592

4593
/*
4594
 * [mk-bv-shift-left1 <bv> <rational>]
4595
 */
4596
static void check_mk_bv_shift_left1(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4597
  check_op(stack, MK_BV_SHIFT_LEFT1);
×
4598
  check_size(stack, n == 2);
×
4599
  check_tag(stack, f+1, TAG_RATIONAL);
×
4600
}
×
4601

4602
static void eval_mk_bv_shift_left1(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4603
  int32_t index;
4604
  bvlogic_buffer_t *b;
4605

4606
  index = get_integer(stack, f+1);
×
4607
  b = tstack_get_bvlbuffer(stack);
×
4608
  bvl_set_elem(stack, b, f);
×
4609
  if (! yices_check_bitshift(b, index)) {
×
4610
    report_yices_error(stack);
×
4611
  }
4612
  bvlogic_buffer_shift_left1(b, index);
×
4613
  tstack_pop_frame(stack);
×
4614
  set_bvlogic_result(stack, b);
×
4615
}
×
4616

4617

4618
/*
4619
 * [mk-bv-shift-right0 <bv> <rational>]
4620
 */
4621
static void check_mk_bv_shift_right0(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4622
  check_op(stack, MK_BV_SHIFT_RIGHT0);
×
4623
  check_size(stack, n == 2);
×
4624
  check_tag(stack, f+1, TAG_RATIONAL);
×
4625
}
×
4626

4627
static void eval_mk_bv_shift_right0(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4628
  int32_t index;
4629
  bvlogic_buffer_t *b;
4630

4631
  index = get_integer(stack, f+1);
×
4632
  b = tstack_get_bvlbuffer(stack);
×
4633
  bvl_set_elem(stack, b, f);
×
4634
  if (! yices_check_bitshift(b, index)) {
×
4635
    report_yices_error(stack);
×
4636
  }
4637
  bvlogic_buffer_shift_right0(b, index);
×
4638
  tstack_pop_frame(stack);
×
4639
  set_bvlogic_result(stack, b);
×
4640
}
×
4641

4642

4643
/*
4644
 * [mk-bv-shift-right1 <bv> <rational>]
4645
 */
4646
static void check_mk_bv_shift_right1(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4647
  check_op(stack, MK_BV_SHIFT_RIGHT1);
×
4648
  check_size(stack, n == 2);
×
4649
  check_tag(stack, f+1, TAG_RATIONAL);
×
4650
}
×
4651

4652
static void eval_mk_bv_shift_right1(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4653
  int32_t index;
4654
  bvlogic_buffer_t *b;
4655

4656
  index = get_integer(stack, f+1);
×
4657
  b = tstack_get_bvlbuffer(stack);
×
4658
  bvl_set_elem(stack, b, f);
×
4659
  if (! yices_check_bitshift(b, index)) {
×
4660
    report_yices_error(stack);
×
4661
  }
4662
  bvlogic_buffer_shift_right1(b, index);
×
4663
  tstack_pop_frame(stack);
×
4664
  set_bvlogic_result(stack, b);
×
4665
}
×
4666

4667

4668
/*
4669
 * [mk-bv-ashift-right <bv> <rational>]
4670
 */
4671
static void check_mk_bv_ashift_right(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4672
  check_op(stack, MK_BV_ASHIFT_RIGHT);
×
4673
  check_size(stack, n == 2);
×
4674
  check_tag(stack, f+1, TAG_RATIONAL);
×
4675
}
×
4676

4677
static void eval_mk_bv_ashift_right(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4678
  int32_t index;
4679
  bvlogic_buffer_t *b;
4680

4681
  index = get_integer(stack, f+1);
×
4682
  b = tstack_get_bvlbuffer(stack);
×
4683
  bvl_set_elem(stack, b, f);
×
4684
  if (! yices_check_bitshift(b, index)) {
×
4685
    report_yices_error(stack);
×
4686
  }
4687
  bvlogic_buffer_ashift_right(b, index);
×
4688
  tstack_pop_frame(stack);
×
4689
  set_bvlogic_result(stack, b);
×
4690
}
×
4691

4692

4693
/*
4694
 * [mk-bv-rotate-left <bv> <rational>]
4695
 */
4696
static void check_mk_bv_rotate_left(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4697
  check_op(stack, MK_BV_ROTATE_LEFT);
×
4698
  check_size(stack, n == 2);
×
4699
  check_tag(stack, f+1, TAG_RATIONAL);
×
4700
}
×
4701

4702
static void eval_mk_bv_rotate_left(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4703
  int32_t index;
4704
  bvlogic_buffer_t *b;
4705

4706
  index = get_integer(stack, f+1);
×
4707
  b = tstack_get_bvlbuffer(stack);
×
4708
  bvl_set_elem(stack, b, f);
×
4709
  if (! yices_check_bitshift(b, index)) {
×
4710
    report_yices_error(stack);
×
4711
  }
4712
  // we known 0 <= index <= bitsize of b
4713
  if (index < bvlogic_buffer_bitsize(b)) {
×
4714
    bvlogic_buffer_rotate_left(b, index);
×
4715
  }
4716
  tstack_pop_frame(stack);
×
4717
  set_bvlogic_result(stack, b);
×
4718
}
×
4719

4720
/*
4721
 * [mk-bv-rotate-right <bv> <rational>]
4722
 */
4723
static void check_mk_bv_rotate_right(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4724
  check_op(stack, MK_BV_ROTATE_RIGHT);
×
4725
  check_size(stack, n == 2);
×
4726
  check_tag(stack, f+1, TAG_RATIONAL);
×
4727
}
×
4728

4729
static void eval_mk_bv_rotate_right(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4730
  int32_t index;
4731
  bvlogic_buffer_t *b;
4732

4733
  index = get_integer(stack, f+1);
×
4734
  b = tstack_get_bvlbuffer(stack);
×
4735
  bvl_set_elem(stack, b, f);
×
4736
  if (! yices_check_bitshift(b, index)) {
×
4737
    report_yices_error(stack);
×
4738
  }
4739
  // we known 0 <= index <= bitsize of b
4740
  if (index < bvlogic_buffer_bitsize(b)) {
×
4741
    bvlogic_buffer_rotate_right(b, index);
×
4742
  }
4743
  tstack_pop_frame(stack);
×
4744
  set_bvlogic_result(stack, b);
×
4745
}
×
4746

4747

4748
/*
4749
 * [mk-bv-extract <rational> <rational> <bv>]
4750
 */
4751
static void check_mk_bv_extract(tstack_t *stack, stack_elem_t *f, uint32_t n) {
17,226✔
4752
  check_op(stack, MK_BV_EXTRACT);
17,226✔
4753
  check_size(stack, n == 3);
17,226✔
4754
  check_tag(stack, f, TAG_RATIONAL);
17,226✔
4755
  check_tag(stack, f+1, TAG_RATIONAL);
17,226✔
4756
}
17,226✔
4757

4758
static void eval_mk_bv_extract(tstack_t *stack, stack_elem_t *f, uint32_t n) {
17,226✔
4759
  bvlogic_buffer_t *b;
4760
  int32_t i, j;
4761
  uint32_t size;
4762

4763
  // the syntax is (bv-extract end begin bv)
4764
  i = get_integer(stack, f);        // end index
17,226✔
4765
  j = get_integer(stack, f+1);      // start index
17,226✔
4766
  size = elem_bitsize(stack, f+2);  // vector
17,226✔
4767
  if (! yices_check_bvextract(size, j, i)) {
17,226✔
4768
    report_yices_error(stack);
×
4769
  }
4770

4771
  if (j == 0 && i == size-1) {
17,226✔
4772
    // (bv-extract 0 size-1 bv) = bv
4773
    copy_result_and_pop_frame(stack, f+2);
1,324✔
4774
  } else {
4775
    // copy slice [i .. j] into b
4776
    b = tstack_get_bvlbuffer(stack);
15,902✔
4777
    bvl_set_slice_elem(stack, b, j, i, f+2);
15,902✔
4778
    tstack_pop_frame(stack);
15,902✔
4779
    set_bvlogic_result(stack, b);
15,902✔
4780
  }
4781
}
17,226✔
4782

4783

4784
/*
4785
 * [mk-bv-concat <bv> ... <bv>]
4786
 */
4787
static void check_mk_bv_concat(tstack_t *stack, stack_elem_t *f, uint32_t n) {
4,401✔
4788
  check_op(stack, MK_BV_CONCAT);
4,401✔
4789
  check_size(stack, n >= 1);
4,401✔
4790
}
4,401✔
4791

4792
static void eval_mk_bv_concat(tstack_t *stack, stack_elem_t *f, uint32_t n) {
4,401✔
4793
  bvlogic_buffer_t *b;
4794
  uint32_t i;
4795

4796
  b = tstack_get_bvlbuffer(stack);
4,401✔
4797
  for (i=0; i<n; i++) {
18,824✔
4798
    bvconcat_elem(stack, b, f+i);
14,423✔
4799
  }
4800
  tstack_pop_frame(stack);
4,401✔
4801
  set_bvlogic_result(stack, b);
4,401✔
4802
}
4,401✔
4803

4804

4805
/*
4806
 * [mk-bv-repeat <bv> <rational>]
4807
 */
4808
static void check_mk_bv_repeat(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4809
  check_op(stack, MK_BV_REPEAT);
×
4810
  check_size(stack, n == 2);
×
4811
  check_tag(stack, f+1, TAG_RATIONAL);
×
4812
}
×
4813

4814
static void eval_mk_bv_repeat(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4815
  bvlogic_buffer_t *b;
4816
  int32_t i;
4817

4818
  i = get_integer(stack, f+1);
×
4819
  b = tstack_get_bvlbuffer(stack);
×
4820
  bvl_set_elem(stack, b, f);
×
4821
  // check for overflow or for i <= 0
4822
  if (! yices_check_bvrepeat(b, i)) {
×
4823
    report_yices_error(stack);
×
4824
  }
4825
  bvlogic_buffer_repeat_concat(b, i);
×
4826
  tstack_pop_frame(stack);
×
4827
  set_bvlogic_result(stack, b);
×
4828
}
×
4829

4830

4831

4832

4833
/*
4834
 * [mk-bv-sign-extend <bv> <rational>]
4835
 * rational n = number of bits to add
4836
 */
4837
static void check_mk_bv_sign_extend(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4838
  check_op(stack, MK_BV_SIGN_EXTEND);
×
4839
  check_size(stack, n == 2);
×
4840
  check_tag(stack, f+1, TAG_RATIONAL);
×
4841
}
×
4842

4843
static void eval_mk_bv_sign_extend(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4844
  mk_bv_sign_extend_core(stack, f, f+1);
×
4845
}
×
4846

4847

4848

4849
/*
4850
 * [mk-bv-zero-extend <bv> <rational>]
4851
 * rational n = number of bits to add
4852
 */
4853
static void check_mk_bv_zero_extend(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4854
  check_op(stack, MK_BV_ZERO_EXTEND);
×
4855
  check_size(stack, n == 2);
×
4856
  check_tag(stack, f+1, TAG_RATIONAL);
×
4857
}
×
4858

4859
static void eval_mk_bv_zero_extend(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
4860
  mk_bv_zero_extend_core(stack, f, f+1);
×
4861
}
×
4862

4863

4864

4865

4866
/*
4867
 * BITVECTOR ATOMS
4868
 */
4869

4870
/*
4871
 * [mk-bv-ge <bv> <bv>]
4872
 */
4873
static void check_mk_bv_ge(tstack_t *stack, stack_elem_t *f, uint32_t n) {
1,640✔
4874
  check_op(stack, MK_BV_GE);
1,640✔
4875
  check_size(stack, n == 2);
1,640✔
4876
}
1,640✔
4877

4878
static void eval_mk_bv_ge(tstack_t *stack, stack_elem_t *f, uint32_t n) {
1,640✔
4879
  term_t t1, t2, t;
4880

4881
  t1 = get_term(stack, f);
1,640✔
4882
  t2 = get_term(stack, f+1);
1,640✔
4883
  t = _o_yices_bvge_atom(t1, t2);
1,640✔
4884
  check_term(stack, t);
1,640✔
4885

4886
  tstack_pop_frame(stack);
1,640✔
4887
  set_term_result(stack, t);
1,640✔
4888
}
1,640✔
4889

4890

4891
/*
4892
 * [mk-bv-gt <bv> <bv>]
4893
 */
4894
static void check_mk_bv_gt(tstack_t *stack, stack_elem_t *f, uint32_t n) {
1,660✔
4895
  check_op(stack, MK_BV_GT);
1,660✔
4896
  check_size(stack, n == 2);
1,660✔
4897
}
1,660✔
4898

4899
static void eval_mk_bv_gt(tstack_t *stack, stack_elem_t *f, uint32_t n) {
1,660✔
4900
  term_t t1, t2, t;
4901

4902
  t1 = get_term(stack, f);
1,660✔
4903
  t2 = get_term(stack, f+1);
1,660✔
4904
  t = _o_yices_bvgt_atom(t1, t2);
1,660✔
4905
  check_term(stack, t);
1,660✔
4906

4907
  tstack_pop_frame(stack);
1,660✔
4908
  set_term_result(stack, t);
1,660✔
4909
}
1,660✔
4910

4911

4912
/*
4913
 * [mk-bv-le <bv> <bv>]
4914
 */
4915
static void check_mk_bv_le(tstack_t *stack, stack_elem_t *f, uint32_t n) {
3,388✔
4916
  check_op(stack, MK_BV_LE);
3,388✔
4917
  check_size(stack, n == 2);
3,388✔
4918
}
3,388✔
4919

4920
static void eval_mk_bv_le(tstack_t *stack, stack_elem_t *f, uint32_t n) {
3,388✔
4921
  term_t t1, t2, t;
4922

4923
  t1 = get_term(stack, f);
3,388✔
4924
  t2 = get_term(stack, f+1);
3,388✔
4925
  t = _o_yices_bvle_atom(t1, t2);
3,388✔
4926
  check_term(stack, t);
3,388✔
4927

4928
  tstack_pop_frame(stack);
3,388✔
4929
  set_term_result(stack, t);
3,388✔
4930
}
3,388✔
4931

4932

4933
/*
4934
 * [mk-bv-lt <bv> <bv>]
4935
 */
4936
static void check_mk_bv_lt(tstack_t *stack, stack_elem_t *f, uint32_t n) {
3,867✔
4937
  check_op(stack, MK_BV_LT);
3,867✔
4938
  check_size(stack, n == 2);
3,867✔
4939
}
3,867✔
4940

4941
static void eval_mk_bv_lt(tstack_t *stack, stack_elem_t *f, uint32_t n) {
3,867✔
4942
  term_t t1, t2, t;
4943

4944
  t1 = get_term(stack, f);
3,867✔
4945
  t2 = get_term(stack, f+1);
3,867✔
4946
  t = _o_yices_bvlt_atom(t1, t2);
3,867✔
4947
  check_term(stack, t);
3,867✔
4948

4949
  tstack_pop_frame(stack);
3,867✔
4950
  set_term_result(stack, t);
3,867✔
4951
}
3,867✔
4952

4953

4954
/*
4955
 * [mk-bv-sge <bv> <bv>]
4956
 */
4957
static void check_mk_bv_sge(tstack_t *stack, stack_elem_t *f, uint32_t n) {
1,618✔
4958
  check_op(stack, MK_BV_SGE);
1,618✔
4959
  check_size(stack, n == 2);
1,618✔
4960
}
1,618✔
4961

4962
static void eval_mk_bv_sge(tstack_t *stack, stack_elem_t *f, uint32_t n) {
1,618✔
4963
  term_t t1, t2, t;
4964

4965
  t1 = get_term(stack, f);
1,618✔
4966
  t2 = get_term(stack, f+1);
1,618✔
4967
  t = _o_yices_bvsge_atom(t1, t2);
1,618✔
4968
  check_term(stack, t);
1,618✔
4969

4970
  tstack_pop_frame(stack);
1,618✔
4971
  set_term_result(stack, t);
1,618✔
4972
}
1,618✔
4973

4974

4975
/*
4976
 * [mk-bv-sgt <bv> <bv>]
4977
 */
4978
static void check_mk_bv_sgt(tstack_t *stack, stack_elem_t *f, uint32_t n) {
1,607✔
4979
  check_op(stack, MK_BV_SGT);
1,607✔
4980
  check_size(stack, n == 2);
1,607✔
4981
}
1,607✔
4982

4983
static void eval_mk_bv_sgt(tstack_t *stack, stack_elem_t *f, uint32_t n) {
1,607✔
4984
  term_t t1, t2, t;
4985

4986
  t1 = get_term(stack, f);
1,607✔
4987
  t2 = get_term(stack, f+1);
1,607✔
4988
  t = _o_yices_bvsgt_atom(t1, t2);
1,607✔
4989
  check_term(stack, t);
1,607✔
4990

4991
  tstack_pop_frame(stack);
1,607✔
4992
  set_term_result(stack, t);
1,607✔
4993
}
1,607✔
4994

4995

4996
/*
4997
 * [mk-bv-sle <bv> <bv>]
4998
 */
4999
static void check_mk_bv_sle(tstack_t *stack, stack_elem_t *f, uint32_t n) {
2,197✔
5000
  check_op(stack, MK_BV_SLE);
2,197✔
5001
  check_size(stack, n == 2);
2,197✔
5002
}
2,197✔
5003

5004
static void eval_mk_bv_sle(tstack_t *stack, stack_elem_t *f, uint32_t n) {
2,197✔
5005
  term_t t1, t2, t;
5006

5007
  t1 = get_term(stack, f);
2,197✔
5008
  t2 = get_term(stack, f+1);
2,197✔
5009
  t = _o_yices_bvsle_atom(t1, t2);
2,197✔
5010
  check_term(stack, t);
2,197✔
5011

5012
  tstack_pop_frame(stack);
2,197✔
5013
  set_term_result(stack, t);
2,197✔
5014
}
2,197✔
5015

5016

5017
/*
5018
 * [mk-bv-slt <bv> <bv>]
5019
 */
5020
static void check_mk_bv_slt(tstack_t *stack, stack_elem_t *f, uint32_t n) {
2,160✔
5021
  check_op(stack, MK_BV_SLT);
2,160✔
5022
  check_size(stack, n == 2);
2,160✔
5023
}
2,160✔
5024

5025
static void eval_mk_bv_slt(tstack_t *stack, stack_elem_t *f, uint32_t n) {
2,160✔
5026
  term_t t1, t2, t;
5027

5028
  t1 = get_term(stack, f);
2,160✔
5029
  t2 = get_term(stack, f+1);
2,160✔
5030
  t = _o_yices_bvslt_atom(t1, t2);
2,160✔
5031
  check_term(stack, t);
2,160✔
5032

5033
  tstack_pop_frame(stack);
2,160✔
5034
  set_term_result(stack, t);
2,160✔
5035
}
2,160✔
5036

5037

5038

5039

5040
/*
5041
 * NEW BITVECTOR OPERATORS IN SMT-LIB
5042
 */
5043

5044
/*
5045
 * Shift operators: [shift <bv1> <bv2>]
5046
 * - bv1 and bv2 must be bitvectors of the same size
5047
 * - shift bv1
5048
 * - the number of bits to shift = value of vv2
5049
 *
5050
 * bv-shl: shift left padding with 0
5051
 * bv-lshr: logical shift right (padding with 0)
5052
 * bv-ashr: arithmetic shift (padding with sign bit)
5053
 */
5054

5055
/*
5056
 * [mk-bv-shl <bv1> <bv2>]
5057
 */
5058
static void check_mk_bv_shl(tstack_t *stack, stack_elem_t *f, uint32_t n) {
2,508✔
5059
  check_op(stack, MK_BV_SHL);
2,508✔
5060
  check_size(stack, n == 2);
2,508✔
5061
}
2,508✔
5062

5063
static void eval_mk_bv_shl(tstack_t *stack, stack_elem_t *f, uint32_t n) {
2,508✔
5064
  bvlogic_buffer_t *b;
5065
  bvconstant_t *c;
5066
  stack_elem_t *e;
5067
  term_t t1, t2, t;
5068

5069
  e = f + 1;
2,508✔
5070
  if (! elem_is_bvconst(e)) {
2,508✔
5071
    // variable shift
5072
    t1 = get_term(stack, f);
232✔
5073
    t2 = get_term(stack, f+1);
232✔
5074
    t = _o_yices_bvshl(t1, t2);
232✔
5075
    check_term(stack, t);
232✔
5076

5077
    tstack_pop_frame(stack);
232✔
5078
    set_term_result(stack, t);
232✔
5079

5080
  } else {
5081
    // constant shift amount
5082

5083
    b = tstack_get_bvlbuffer(stack);
2,276✔
5084
    bvl_set_elem(stack, b, f);
2,276✔
5085
    c = &stack->bvconst_buffer;
2,276✔
5086
    bvconst_set_elem(c, e);
2,276✔
5087

5088
    if (c->bitsize != bvlogic_buffer_bitsize(b)) {
2,276✔
5089
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
5090
    }
5091
    bvlogic_buffer_shl_constant(b, c->bitsize, c->data);
2,276✔
5092
    tstack_pop_frame(stack);
2,276✔
5093
    set_bvlogic_result(stack, b);
2,276✔
5094
  }
5095
}
2,508✔
5096

5097

5098
/*
5099
 * [mk-bv-lshr <bv1> <bv2>]
5100
 */
5101
static void check_mk_bv_lshr(tstack_t *stack, stack_elem_t *f, uint32_t n) {
2,583✔
5102
  check_op(stack, MK_BV_LSHR);
2,583✔
5103
  check_size(stack, n == 2);
2,583✔
5104
}
2,583✔
5105

5106
static void eval_mk_bv_lshr(tstack_t *stack, stack_elem_t *f, uint32_t n) {
2,583✔
5107
  bvlogic_buffer_t *b;
5108
  bvconstant_t *c;
5109
  stack_elem_t *e;
5110
  term_t t1, t2, t;
5111

5112
  e = f + 1;
2,583✔
5113
  if (! elem_is_bvconst(e)) {
2,583✔
5114
    // variable shift
5115
    t1 = get_term(stack, f);
399✔
5116
    t2 = get_term(stack, f+1);
399✔
5117
    t = _o_yices_bvlshr(t1, t2);
399✔
5118
    check_term(stack, t);
399✔
5119

5120
    tstack_pop_frame(stack);
399✔
5121
    set_term_result(stack, t);
399✔
5122

5123
  } else {
5124
    // constant shift amount
5125

5126
    b = tstack_get_bvlbuffer(stack);
2,184✔
5127
    bvl_set_elem(stack, b, f);
2,184✔
5128
    c = &stack->bvconst_buffer;
2,184✔
5129
    bvconst_set_elem(c, e);
2,184✔
5130

5131
    if (c->bitsize != bvlogic_buffer_bitsize(b)) {
2,184✔
5132
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
5133
    }
5134
    bvlogic_buffer_lshr_constant(b, c->bitsize, c->data);
2,184✔
5135
    tstack_pop_frame(stack);
2,184✔
5136
    set_bvlogic_result(stack, b);
2,184✔
5137
  }
5138
}
2,583✔
5139

5140
/*
5141
 * [mk-bv-ashr <bv1> <bv2>]
5142
 */
5143
static void check_mk_bv_ashr(tstack_t *stack, stack_elem_t *f, uint32_t n) {
212✔
5144
  check_op(stack, MK_BV_ASHR);
212✔
5145
  check_size(stack, n == 2);
212✔
5146
}
212✔
5147

5148
static void eval_mk_bv_ashr(tstack_t *stack, stack_elem_t *f, uint32_t n) {
212✔
5149
  bvlogic_buffer_t *b;
5150
  bvconstant_t *c;
5151
  stack_elem_t *e;
5152
  term_t t1, t2, t;
5153

5154
  e = f + 1;
212✔
5155
  if (! elem_is_bvconst(e)) {
212✔
5156
    // variable shift
5157
    t1 = get_term(stack, f);
115✔
5158
    t2 = get_term(stack, f+1);
115✔
5159
    t = _o_yices_bvashr(t1, t2);
115✔
5160
    check_term(stack, t);
115✔
5161

5162
    tstack_pop_frame(stack);
115✔
5163
    set_term_result(stack, t);
115✔
5164

5165
  } else {
5166
    // constant shift amount
5167

5168
    b = tstack_get_bvlbuffer(stack);
97✔
5169
    bvl_set_elem(stack, b, f);
97✔
5170
    c = &stack->bvconst_buffer;
97✔
5171
    bvconst_set_elem(c, e);
97✔
5172

5173
    if (c->bitsize != bvlogic_buffer_bitsize(b)) {
97✔
5174
      raise_exception(stack, e, TSTACK_INCOMPATIBLE_BVSIZES);
×
5175
    }
5176
    bvlogic_buffer_ashr_constant(b, c->bitsize, c->data);
97✔
5177
    tstack_pop_frame(stack);
97✔
5178
    set_bvlogic_result(stack, b);
97✔
5179
  }
5180
}
212✔
5181

5182

5183
/*
5184
 * Unsigned division and remainder
5185
 */
5186

5187
/*
5188
 * [mk-bv-div <bv1> <bv2>]
5189
 */
5190
static void check_mk_bv_div(tstack_t *stack, stack_elem_t *f, uint32_t n) {
315✔
5191
  check_op(stack, MK_BV_DIV);
315✔
5192
  check_size(stack, n == 2);
315✔
5193
}
315✔
5194

5195
static void eval_mk_bv_div(tstack_t *stack, stack_elem_t *f, uint32_t n) {
315✔
5196
  term_t t1, t2, t;
5197

5198
  t1 = get_term(stack, f);
315✔
5199
  t2 = get_term(stack, f+1);
315✔
5200
  t = _o_yices_bvdiv(t1, t2);
315✔
5201
  check_term(stack, t);
315✔
5202

5203
  tstack_pop_frame(stack);
315✔
5204
  set_term_result(stack, t);
315✔
5205
}
315✔
5206

5207
/*
5208
 * [mk-bv-rem <bv1> <bv2>]
5209
 */
5210
static void check_mk_bv_rem(tstack_t *stack, stack_elem_t *f, uint32_t n) {
330✔
5211
  check_op(stack, MK_BV_REM);
330✔
5212
  check_size(stack, n == 2);
330✔
5213
}
330✔
5214

5215
static void eval_mk_bv_rem(tstack_t *stack, stack_elem_t *f, uint32_t n) {
330✔
5216
  term_t t1, t2, t;
5217

5218
  t1 = get_term(stack, f);
330✔
5219
  t2 = get_term(stack, f+1);
330✔
5220
  t = _o_yices_bvrem(t1, t2);
330✔
5221
  check_term(stack, t);
330✔
5222

5223
  tstack_pop_frame(stack);
330✔
5224
  set_term_result(stack, t);
330✔
5225
}
330✔
5226

5227

5228

5229

5230
/*
5231
 * Signed division and remainder
5232
 */
5233

5234
/*
5235
 * [mk-bv-sdiv <bv1> <bv2>]
5236
 */
5237
static void check_mk_bv_sdiv(tstack_t *stack, stack_elem_t *f, uint32_t n) {
167✔
5238
  check_op(stack, MK_BV_SDIV);
167✔
5239
  check_size(stack, n == 2);
167✔
5240
}
167✔
5241

5242
static void eval_mk_bv_sdiv(tstack_t *stack, stack_elem_t *f, uint32_t n) {
167✔
5243
  term_t t1, t2, t;
5244

5245
  t1 = get_term(stack, f);
167✔
5246
  t2 = get_term(stack, f+1);
167✔
5247
  t = _o_yices_bvsdiv(t1, t2);
167✔
5248
  check_term(stack, t);
167✔
5249

5250
  tstack_pop_frame(stack);
167✔
5251
  set_term_result(stack, t);
167✔
5252
}
167✔
5253

5254
/*
5255
 * [mk-bv-srem <bv1> <bv2>]
5256
 */
5257
static void check_mk_bv_srem(tstack_t *stack, stack_elem_t *f, uint32_t n) {
165✔
5258
  check_op(stack, MK_BV_SREM);
165✔
5259
  check_size(stack, n == 2);
165✔
5260
}
165✔
5261

5262
static void eval_mk_bv_srem(tstack_t *stack, stack_elem_t *f, uint32_t n) {
165✔
5263
  term_t t1, t2, t;
5264

5265
  t1 = get_term(stack, f);
165✔
5266
  t2 = get_term(stack, f+1);
165✔
5267
  t = _o_yices_bvsrem(t1, t2);
165✔
5268
  check_term(stack, t);
165✔
5269

5270
  tstack_pop_frame(stack);
165✔
5271
  set_term_result(stack, t);
165✔
5272
}
165✔
5273

5274

5275
/*
5276
 * [mk-bv-smod <bv1> <bv2>]
5277
 */
5278
static void check_mk_bv_smod(tstack_t *stack, stack_elem_t *f, uint32_t n) {
20✔
5279
  check_op(stack, MK_BV_SMOD);
20✔
5280
  check_size(stack, n == 2);
20✔
5281
}
20✔
5282

5283
static void eval_mk_bv_smod(tstack_t *stack, stack_elem_t *f, uint32_t n) {
20✔
5284
  term_t t1, t2, t;
5285

5286
  t1 = get_term(stack, f);
20✔
5287
  t2 = get_term(stack, f+1);
20✔
5288
  t = _o_yices_bvsmod(t1, t2);
20✔
5289
  check_term(stack, t);
20✔
5290

5291
  tstack_pop_frame(stack);
20✔
5292
  set_term_result(stack, t);
20✔
5293
}
20✔
5294

5295

5296

5297
/*
5298
 * Redor/redand/bvcomp
5299
 */
5300

5301
/*
5302
 * [mk-bv-redor <bv1>]
5303
 */
5304
static void check_mk_bv_redor(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5305
  check_op(stack, MK_BV_REDOR);
×
5306
  check_size(stack, n == 1);
×
5307
}
×
5308

5309
static void eval_mk_bv_redor(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5310
  bvlogic_buffer_t *b;
5311

5312
  b = tstack_get_bvlbuffer(stack);
×
5313
  bvl_set_elem(stack, b, f);
×
5314
  if (! yices_check_bvlogic_buffer(b)) {
×
5315
    report_yices_error(stack); // empty buffer
×
5316
  }
5317
  bvlogic_buffer_redor(b);
×
5318
  tstack_pop_frame(stack);
×
5319
  set_bvlogic_result(stack, b);
×
5320
}
×
5321

5322

5323
/*
5324
 * [mk-bv-redand <bv1>]
5325
 */
5326
static void check_mk_bv_redand(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5327
  check_op(stack, MK_BV_REDAND);
×
5328
  check_size(stack, n == 1);
×
5329
}
×
5330

5331
static void eval_mk_bv_redand(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5332
  bvlogic_buffer_t *b;
5333

5334
  b = tstack_get_bvlbuffer(stack);
×
5335
  bvl_set_elem(stack, b, f);
×
5336
  if (! yices_check_bvlogic_buffer(b)) {
×
5337
    report_yices_error(stack); // empty buffer
×
5338
  }
5339
  bvlogic_buffer_redand(b);
×
5340
  tstack_pop_frame(stack);
×
5341
  set_bvlogic_result(stack, b);
×
5342
}
×
5343

5344

5345
/*
5346
 * [mk-bv-comp <bv1> <bv2>]
5347
 */
5348
static void check_mk_bv_comp(tstack_t *stack, stack_elem_t *f, uint32_t n) {
527✔
5349
  check_op(stack, MK_BV_COMP);
527✔
5350
  check_size(stack, n == 2);
527✔
5351
}
527✔
5352

5353
static void eval_mk_bv_comp(tstack_t *stack, stack_elem_t *f, uint32_t n) {
527✔
5354
  bvlogic_buffer_t *b;
5355

5356
  b = tstack_get_bvlbuffer(stack);
527✔
5357
  bvl_set_elem(stack, b, f);
527✔
5358
  bvcomp_elem(stack, b, f+1);
527✔
5359
  tstack_pop_frame(stack);
527✔
5360
  set_bvlogic_result(stack, b);
527✔
5361
}
527✔
5362

5363

5364

5365
/*
5366
 * Conversion from Booleans to bitvectors
5367
 */
5368

5369
/*
5370
 * [mk-bool-to-bv <bool> .... <bool>]
5371
 */
5372
static void check_mk_bool2bv(tstack_t *stack, stack_elem_t *f, uint32_t n) {
1✔
5373
  check_op(stack, MK_BOOL_TO_BV);
1✔
5374
  check_size(stack, n>=1);
1✔
5375
}
1✔
5376

5377
/*
5378
 * Build a bitvector from n boolean terms
5379
 * - we reverse the bit order: in [mk-bool-to-bv u_0 ... u_{n-1}], we want
5380
 *   u_0 to be the high order bit and u_{n-1} to be the low order bit.
5381
 * - the result is stored as a bvlogic_buffer element
5382
 */
5383
static void eval_mk_bool2bv(tstack_t *stack, stack_elem_t *f, uint32_t n) {
1✔
5384
  bvlogic_buffer_t *b;
5385
  term_t *aux;
5386
  term_t t;
5387
  uint32_t i;
5388

5389
  if (! yices_check_bvsize(n)) {
1✔
5390
    report_yices_error(stack);
×
5391
  }
5392

5393
  aux = get_aux_buffer(stack, n);
1✔
5394
  for (i=0; i<n; i++) {
13✔
5395
    t = get_term(stack, f+i);
12✔
5396
    if (! yices_check_boolean_term(t)) {
12✔
5397
      report_yices_error(stack);
×
5398
    }
5399
    aux[(n-1) - i] = t;
12✔
5400
  }
5401

5402
  b = tstack_get_bvlbuffer(stack);
1✔
5403
  bvlogic_buffer_set_term_array(b, __yices_globals.terms, n, aux);
1✔
5404

5405
  tstack_pop_frame(stack);
1✔
5406
  set_bvlogic_result(stack, b);
1✔
5407
}
1✔
5408

5409

5410
/*
5411
 * Extract a bit from a bitvector: [mk-bit <bv> <index> ]
5412
 */
5413
static void check_mk_bit(tstack_t *stack, stack_elem_t *f, uint32_t n) {
48✔
5414
  check_op(stack, MK_BIT);
48✔
5415
  check_size(stack, n == 2);
48✔
5416
  check_tag(stack, f+1, TAG_RATIONAL);
48✔
5417
}
48✔
5418

5419
static void eval_mk_bit(tstack_t *stack, stack_elem_t *f, uint32_t n) {
48✔
5420
  uint32_t nbits;
5421
  int32_t i;
5422
  term_t t;
5423

5424
  nbits = elem_bitsize(stack, f);
48✔
5425
  i = get_integer(stack, f+1);
48✔
5426

5427
  if (! yices_check_bitextract(nbits, i)) {
48✔
5428
    report_yices_error(stack);
×
5429
  }
5430

5431
  t = elem_bit_select(stack, f, i);
48✔
5432

5433
  tstack_pop_frame(stack);
48✔
5434
  set_term_result(stack, t);
48✔
5435
}
48✔
5436

5437

5438
/*
5439
 * MORE ARITHMETIC FUNCTIONS (FROM SMT-LIB2)
5440
 */
5441

5442
/*
5443
 * Floor/ceil/absolute value: all take a single argument
5444
 */
5445
static void check_mk_floor(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5446
  check_op(stack, MK_FLOOR);
×
5447
  check_size(stack, n == 1);
×
5448
}
×
5449

5450
static void eval_mk_floor(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5451
  term_t t;
5452

5453
  t = get_term(stack, f);
×
5454
  t = _o_yices_floor(t);
×
5455
  check_term(stack, t);
×
5456

5457
  tstack_pop_frame(stack);
×
5458
  set_term_result(stack, t);
×
5459
}
×
5460

5461

5462
static void check_mk_ceil(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5463
  check_op(stack, MK_CEIL);
×
5464
  check_size(stack, n == 1);
×
5465
}
×
5466

5467
static void eval_mk_ceil(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5468
  term_t t;
5469

5470
  t = get_term(stack, f);
×
5471
  t = _o_yices_ceil(t);
×
5472
  check_term(stack, t);
×
5473

5474
  tstack_pop_frame(stack);
×
5475
  set_term_result(stack, t);
×
5476
}
×
5477

5478

5479

5480
static void check_mk_abs(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5481
  check_op(stack, MK_ABS);
×
5482
  check_size(stack, n == 1);
×
5483
}
×
5484

5485
static void eval_mk_abs(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5486
  term_t t;
5487

5488
  t = get_term(stack, f);
×
5489
  t = _o_yices_abs(t);
×
5490
  check_term(stack, t);
×
5491

5492
  tstack_pop_frame(stack);
×
5493
  set_term_result(stack, t);
×
5494
}
×
5495

5496

5497
/*
5498
 * Integer division and modulo: two parameters.
5499
 * NOTE: to support QF_NIA/QF_NRA and variants, we allow arbitrary dividers.
5500
 */
5501
static void check_mk_idiv(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5502
  check_op(stack, MK_IDIV);
×
5503
  check_size(stack, n == 2);
×
5504
}
×
5505

5506
static void eval_mk_idiv(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5507
  term_t t1, t2;
5508

5509
  t1 = get_term(stack, f);
×
5510
  t2 = get_term(stack, f+1); // divider
×
5511
  t1 = _o_yices_idiv(t1, t2);
×
5512
  check_term(stack, t1);
×
5513

5514
  tstack_pop_frame(stack);
×
5515
  set_term_result(stack, t1);
×
5516
}
×
5517

5518

5519
static void check_mk_mod(tstack_t *stack, stack_elem_t *f, uint32_t n) {
2✔
5520
  check_op(stack, MK_MOD);
2✔
5521
  check_size(stack, n == 2);
2✔
5522
}
2✔
5523

5524
static void eval_mk_mod(tstack_t *stack, stack_elem_t *f, uint32_t n) {
2✔
5525
  term_t t1, t2;
5526

5527
  t1 = get_term(stack, f);
2✔
5528
  t2 = get_term(stack, f+1); // divider
2✔
5529
  t1 = _o_yices_imod(t1, t2);
2✔
5530
  check_term(stack, t1);
2✔
5531

5532
  tstack_pop_frame(stack);
2✔
5533
  set_term_result(stack, t1);
2✔
5534
}
2✔
5535

5536

5537
/*
5538
 * [mk-is-int <term>]
5539
 */
5540
static void check_mk_is_int(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5541
  check_op(stack, MK_IS_INT);
×
5542
  check_size(stack, n == 1);
×
5543
}
×
5544

5545
static void eval_mk_is_int(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5546
  term_t t;
5547

5548
  t = get_term(stack, f);
×
5549
  t = _o_yices_is_int_atom(t);
×
5550
  check_term(stack, t);
×
5551

5552
  tstack_pop_frame(stack);
×
5553
  set_term_result(stack, t);
×
5554
}
×
5555

5556

5557
/*
5558
 * [mk-divides <arith> <arith> ]
5559
 * - the first term must be an arithmetic constant
5560
 */
5561
static void check_mk_divides(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5562
  check_op(stack, MK_DIVIDES);
×
5563
  check_size(stack, n == 2);
×
5564
}
×
5565

5566
static void eval_mk_divides(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5567
  term_t t1, t2;
5568

5569
  t1 = get_term(stack, f); // divider
×
5570
  t2 = get_term(stack, f+1);
×
5571
  t1 = _o_yices_divides_atom(t1, t2);
×
5572
  check_term(stack, t1);
×
5573

5574
  tstack_pop_frame(stack);
×
5575
  set_term_result(stack, t1);
×
5576
}
×
5577

5578
/*
5579
 * FINITE FIELD FUNCTIONS
5580
 */
5581

5582
/*
5583
 * [mk-ff-const <numeral> [<numeral>]
5584
 */
NEW
5585
static void check_mk_ff_const(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
NEW
5586
  check_op(stack, MK_FF_CONST);
×
NEW
5587
  check_size(stack, n == 1 || n == 2);
×
NEW
5588
  check_tag(stack, f, TAG_RATIONAL);
×
NEW
5589
  if (n == 2)
×
NEW
5590
    check_tag(stack, f+1, TAG_RATIONAL);
×
NEW
5591
}
×
5592

NEW
5593
static void eval_mk_ff_const(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5594
  rational_t val, mod;
5595

NEW
5596
  q_init(&val);
×
NEW
5597
  q_init(&mod);
×
5598

NEW
5599
  q_set(&val, &f->val.rational);
×
NEW
5600
  if (! q_is_integer(&val)) {
×
NEW
5601
    raise_exception(stack, f, TSTACK_INVALID_FFCONSTANT);
×
5602
  }
5603

NEW
5604
  if (n == 2) {
×
NEW
5605
    q_set(&mod, &(f+1)->val.rational);
×
NEW
5606
    if (! q_is_integer(&mod) || ! q_is_nonneg(&mod) || ! q_lt(&val, &mod)) {
×
NEW
5607
      raise_exception(stack, f, TSTACK_INVALID_FFCONSTANT);
×
5608
    }
5609
  } else {
5610
    // we don't know the field size yet
NEW
5611
    q_set_minus_one(&mod);
×
5612
  }
5613

NEW
5614
  tstack_pop_frame(stack);
×
5615
  // the field order (i.e. type) may be yet unknown (requires an `as` to set it)
NEW
5616
  set_ff_result(stack, &val, &mod);
×
5617

NEW
5618
  q_clear(&val);
×
NEW
5619
  q_clear(&mod);
×
NEW
5620
}
×
5621

NEW
5622
static rational_t* ff_get_mod(tstack_t *stack, stack_elem_t *e) {
×
5623
  term_t t;
5624

NEW
5625
  switch (e->tag) {
×
NEW
5626
  case TAG_FINITEFIELD:
×
NEW
5627
    return &e->val.ff.mod;
×
5628

NEW
5629
  case TAG_TERM:
×
5630
  case TAG_SPECIAL_TERM:
NEW
5631
    t = e->val.term;
×
NEW
5632
    if (! yices_check_arith_ff_term(t)) {
×
NEW
5633
      report_yices_error(stack);
×
5634
    }
NEW
5635
    return finitefield_term_order(__yices_globals.terms, t);
×
5636

NEW
5637
  case TAG_ARITH_FF_BUFFER:
×
NEW
5638
    return &e->val.mod_arith_buffer.mod;
×
5639

NEW
5640
  default:
×
NEW
5641
    raise_exception(stack, e, TSTACK_INCOMPATIBLE_FFSIZES);
×
5642
    break;
5643
  }
5644
}
5645

NEW
5646
static void ff_calc_mod(tstack_t *stack, rational_t *mod, stack_elem_t *f, uint32_t n) {
×
5647
  uint32_t i;
5648
  rational_t *tmp;
5649

NEW
5650
  q_set_minus_one(mod);
×
NEW
5651
  for (i=0; i<n; ++i) {
×
NEW
5652
    tmp = ff_get_mod(stack, f+i);
×
NEW
5653
    if (q_is_minus_one(tmp)) { continue; }
×
NEW
5654
    if (q_is_minus_one(mod)) { q_set(mod, tmp); continue; }
×
NEW
5655
    if (q_neq(tmp, mod)) {
×
NEW
5656
      raise_exception(stack, f+i, TSTACK_INCOMPATIBLE_FFSIZES);
×
5657
    }
5658
  }
NEW
5659
}
×
5660

5661
/*
5662
 * [mk-ff-add <arith> <arith> ]
5663
 */
NEW
5664
static void check_mk_ff_add(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
NEW
5665
  check_op(stack, MK_FF_ADD);
×
NEW
5666
  check_size(stack, n >= 1);
×
NEW
5667
}
×
5668

NEW
5669
static void eval_mk_ff_add(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5670
  uint32_t i;
5671
  rba_buffer_t *b;
5672
  rational_t mod;
5673

NEW
5674
  q_init(&mod);
×
NEW
5675
  ff_calc_mod(stack, &mod, f, n);
×
NEW
5676
  b = tstack_get_abuffer(stack);
×
NEW
5677
  for (i=0; i<n; i++) {
×
NEW
5678
    ff_add_elem(stack, b, f+i);
×
5679
  }
NEW
5680
  tstack_pop_frame(stack);
×
NEW
5681
  set_arith_ff_result(stack, b, &mod);
×
NEW
5682
  q_clear(&mod);
×
NEW
5683
}
×
5684

5685
// TODO add sub command
5686
#if 0
5687
/*
5688
 * [mk-ff-sub <arith> <arith> ]
5689
 */
5690
static void check_mk_ff_sub(tstack_t *stack, stack_elem_t *f, uint32_t n) {
5691
  check_op(stack, MK_FF_SUB);
5692
  check_size(stack, n >= 1);
5693
}
5694

5695
static void eval_mk_ff_sub(tstack_t *stack, stack_elem_t *f, uint32_t n) {
5696
  uint32_t i;
5697
  rba_buffer_t *b;
5698
  rational_t mod;
5699

5700
  q_init(&mod);
5701
  ff_calc_mod(stack, &mod, f, n);
5702
  b = tstack_get_abuffer(stack);
5703
  for (i=0; i<n; i++) {
5704
    ff_sub_elem(stack, b, f+i);
5705
  }
5706
  tstack_pop_frame(stack);
5707
  set_arith_ff_result(stack, b, &mod);
5708
  q_clear(&mod);
5709
}
5710
#endif
5711

5712
/*
5713
 * [mk-ff-mul <arith> <arith> ]
5714
 */
NEW
5715
static void check_mk_ff_mul(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
NEW
5716
  check_op(stack, MK_FF_MUL);
×
NEW
5717
  check_size(stack, n >= 1);
×
NEW
5718
}
×
5719

NEW
5720
static void eval_mk_ff_mul(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5721
  uint32_t i;
5722
  rba_buffer_t *b;
5723
  rational_t mod;
5724

NEW
5725
  q_init(&mod);
×
NEW
5726
  ff_calc_mod(stack, &mod, f, n);
×
NEW
5727
  b = tstack_get_abuffer(stack);
×
NEW
5728
  ff_add_elem(stack, b, f);
×
NEW
5729
  for (i=1; i<n; i++) {
×
NEW
5730
    ff_mul_elem(stack, b, f+i);
×
5731
  }
NEW
5732
  tstack_pop_frame(stack);
×
NEW
5733
  set_arith_ff_result(stack, b, &mod);
×
NEW
5734
  q_clear(&mod);
×
NEW
5735
}
×
5736

5737

5738
/*
5739
 * BUILD RESULT
5740
 */
5741

5742
/*
5743
 * [build-term <term>]
5744
 */
5745
static void check_build_term(tstack_t *stack, stack_elem_t *f, uint32_t n) {
56✔
5746
  check_op(stack, BUILD_TERM);
56✔
5747
  check_size(stack, n == 1);
56✔
5748
}
56✔
5749

5750
static void eval_build_term(tstack_t *stack, stack_elem_t *f, uint32_t n) {
56✔
5751
  term_t t;
5752

5753
  t = get_term(stack, f);
56✔
5754
  stack->result.term = t;
56✔
5755
  tstack_pop_frame(stack);
56✔
5756
  no_result(stack);
56✔
5757
}
56✔
5758

5759
/*
5760
 * [build-type <type>]
5761
 */
5762
static void check_build_type(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5763
  check_op(stack, BUILD_TYPE);
×
5764
  check_size(stack, n == 1);
×
5765
  check_tag(stack, f, TAG_TYPE);
×
5766
}
×
5767

5768
static void eval_build_type(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5769
  stack->result.type = f[0].val.type;;
×
5770
  tstack_pop_frame(stack);
×
5771
  no_result(stack);
×
5772
}
×
5773

5774

5775

5776
/*
5777
 * Not supported or other error
5778
 */
5779
static void eval_error(tstack_t *stack, stack_elem_t *f, uint32_t n) {
×
5780
  raise_exception(stack, f, TSTACK_INVALID_OP);
×
5781
}
5782

5783

5784
/*
5785
 * Eval the top-level operation
5786
 */
5787
void tstack_eval(tstack_t *stack) {
1,455,039✔
5788
  uint32_t n;
5789
  int32_t op;
5790
  stack_elem_t *f;
5791

5792
  n = stack->frame;
1,455,039✔
5793
  f = stack->elem + n;
1,455,039✔
5794

5795
  if (f->val.opval.multiplicity > 0) {
1,455,039✔
5796
    // decrement and do nothing. This is a special associative operator
5797
    f->val.opval.multiplicity --;
49,646✔
5798

5799
  } else {
5800
    // pass start frame and frame size to the check and eval function
5801
    op = stack->top_op;
1,405,393✔
5802
    assert(stack->top > stack->frame);
5803
    n = stack->top - stack->frame - 1;
1,405,393✔
5804
    f ++;
1,405,393✔
5805

5806
    stack->op_table.check[op](stack, f, n);
1,405,393✔
5807
    stack->op_table.eval[op](stack, f, n);
1,405,393✔
5808
  }
5809
}
1,455,038✔
5810

5811

5812

5813
/*
5814
 * Direct calls of check[op] and eval[op]
5815
 */
5816
void call_tstack_check(tstack_t *stack, int32_t op, stack_elem_t *f, uint32_t n) {
7,760✔
5817
  int32_t saved_op;
5818

5819
  assert(0 <= op && op < stack->op_table.num_ops && stack->op_table.check[op] != NULL);
5820

5821
  /*
5822
   * we save top_op and replace it by op to prevent 'bad_opcode exception'
5823
   * raised by 'check[op]
5824
   */
5825
  saved_op = stack->top_op;
7,760✔
5826
  stack->top_op = op;
7,760✔
5827
  stack->op_table.check[op](stack, f, n);
7,760✔
5828
  stack->top_op = saved_op;
7,760✔
5829
}
7,760✔
5830

5831
void call_tstack_eval(tstack_t *stack, int32_t op, stack_elem_t *f, uint32_t n) {
7,760✔
5832
  assert(0 <= op && op < stack->op_table.num_ops && stack->op_table.eval[op] != NULL);
5833
  stack->top_op = op;
7,760✔
5834
  stack->op_table.eval[op](stack, f, n);
7,760✔
5835
}
7,760✔
5836

5837

5838

5839

5840
/*
5841
 * PREDEFINED OPERATION TABLE
5842
 */
5843
static const uint8_t assoc[NUM_BASE_OPCODES] = {
5844
  0, // NO_OP
5845
  0, // DEFINE_TYPE
5846
  0, // DEFINE_TERM
5847
  0, // BIND
5848
  0, // DECLARE_VAR
5849
  0, // DECLARE_TYPE_VAR
5850
  0, // LET
5851
  0, // MK_BV_TYPE
5852
  0, // MK_FF_TYPE
5853
  0, // MK_SCALAR_TYPE
5854
  0, // MK_TUPLE_TYPE
5855
  0, // MK_FUN_TYPE
5856
  0, // MK_APP_TYPE
5857
  0, // MK_APPLY
5858
  0, // MK_ITE
5859
  0, // MK_EQ
5860
  0, // MK_DISEQ
5861
  0, // MK_DISTINCT
5862
  0, // MK_NOT
5863
  1, // MK_OR
5864
  1, // MK_AND
5865
  1, // MK_XOR
5866
  0, // MK_IFF
5867
  0, // MK_IMPLIES
5868
  0, // MK_TUPLE
5869
  0, // MK_SELECT
5870
  0, // MK_TUPLE_UPDATE
5871
  0, // MK_UPDATE
5872
  0, // MK_FORALL
5873
  0, // MK_EXISTS
5874
  0, // MK_LAMBDA
5875
  1, // MK_ADD
5876
  0, // MK_SUB
5877
  0, // MK_NEG
5878
  1, // MK_MUL
5879
  0, // MK_DIVISION
5880
  0, // MK_POW
5881
  0, // MK_GE
5882
  0, // MK_GT
5883
  0, // MK_LE
5884
  0, // MK_LT
5885
  0, // MK_BV_CONST
5886
  1, // MK_BV_ADD
5887
  0, // MK_BV_SUB
5888
  1, // MK_BV_MUL
5889
  0, // MK_BV_NEG
5890
  0, // MK_BV_POW
5891
  0, // MK_BV_DIV
5892
  0, // MK_BV_REM
5893
  0, // MK_BV_SDIV
5894
  0, // MK_BV_SREM
5895
  0, // MK_BV_SMOD
5896
  0, // MK_BV_NOT
5897
  1, // MK_BV_AND
5898
  1, // MK_BV_OR
5899
  1, // MK_BV_XOR
5900
  0, // MK_BV_NAND
5901
  0, // MK_BV_NOR
5902
  0, // MK_BV_XNOR
5903
  0, // MK_BV_SHIFT_LEFT0
5904
  0, // MK_BV_SHIFT_LEFT1
5905
  0, // MK_BV_SHIFT_RIGHT0
5906
  0, // MK_BV_SHIFT_RIGHT1
5907
  0, // MK_BV_ASHIFT_RIGHT
5908
  0, // MK_BV_ROTATE_LEFT
5909
  0, // MK_BV_ROTATE_RIGHT
5910
  0, // MK_BV_SHL
5911
  0, // MK_BV_LSHR
5912
  0, // MK_BV_ASHR
5913
  0, // MK_BV_EXTRACT
5914
  1, // MK_BV_CONCAT
5915
  0, // MK_BV_REPEAT
5916
  0, // MK_BV_SIGN_EXTEND
5917
  0, // MK_BV_ZERO_EXTEND
5918
  0, // MK_BV_REDAND
5919
  0, // MK_BV_REDOR
5920
  0, // MK_BV_COMP
5921
  0, // MK_BV_GE
5922
  0, // MK_BV_GT
5923
  0, // MK_BV_LE
5924
  0, // MK_BV_LT
5925
  0, // MK_BV_SGE
5926
  0, // MK_BV_SGT
5927
  0, // MK_BV_SLE
5928
  0, // MK_BV_SLT
5929
  0, // MK_BOOL_TO_BV
5930
  0, // MK_BIT
5931
  0, // MK_FLOOR
5932
  0, // MK_CEIL
5933
  0, // MK_ABS
5934
  0, // MK_IDIV
5935
  0, // MK_MOD
5936
  0, // MK_DIVIDES
5937
  0, // MK_IS_INT
5938
  0, // MK_FF_CONST
5939
  1, // MK_FF_ADD
5940
  1, // MK_FF_MUL
5941
  0, // BUILD_TERM
5942
  0, // BUILD_TYPE
5943
};
5944

5945
static const check_fun_t check[NUM_BASE_OPCODES] = {
5946
  eval_error, // NO_OP
5947
  check_define_type,
5948
  check_define_term,
5949
  check_bind,
5950
  check_declare_var,
5951
  check_declare_type_var,
5952
  check_let,
5953
  check_mk_bv_type,
5954
  check_mk_ff_type,
5955
  check_mk_scalar_type,
5956
  check_mk_tuple_type,
5957
  check_mk_fun_type,
5958
  check_mk_app_type,
5959
  check_mk_apply,
5960
  check_mk_ite,
5961
  check_mk_eq,
5962
  check_mk_diseq,
5963
  check_mk_distinct,
5964
  check_mk_not,
5965
  check_mk_or,
5966
  check_mk_and,
5967
  check_mk_xor,
5968
  check_mk_iff,
5969
  check_mk_implies,
5970
  check_mk_tuple,
5971
  check_mk_select,
5972
  check_mk_tuple_update,
5973
  check_mk_update,
5974
  check_mk_forall,
5975
  check_mk_exists,
5976
  check_mk_lambda,
5977
  check_mk_add,
5978
  check_mk_sub,
5979
  check_mk_neg,
5980
  check_mk_mul,
5981
  check_mk_division,
5982
  check_mk_pow,
5983
  check_mk_ge,
5984
  check_mk_gt,
5985
  check_mk_le,
5986
  check_mk_lt,
5987
  check_mk_bv_const,
5988
  check_mk_bv_add,
5989
  check_mk_bv_sub,
5990
  check_mk_bv_mul,
5991
  check_mk_bv_neg,
5992
  check_mk_bv_pow,
5993
  check_mk_bv_div,
5994
  check_mk_bv_rem,
5995
  check_mk_bv_sdiv,
5996
  check_mk_bv_srem,
5997
  check_mk_bv_smod,
5998
  check_mk_bv_not,
5999
  check_mk_bv_and,
6000
  check_mk_bv_or,
6001
  check_mk_bv_xor,
6002
  check_mk_bv_nand,
6003
  check_mk_bv_nor,
6004
  check_mk_bv_xnor,
6005
  check_mk_bv_shift_left0,
6006
  check_mk_bv_shift_left1,
6007
  check_mk_bv_shift_right0,
6008
  check_mk_bv_shift_right1,
6009
  check_mk_bv_ashift_right,
6010
  check_mk_bv_rotate_left,
6011
  check_mk_bv_rotate_right,
6012
  check_mk_bv_shl,
6013
  check_mk_bv_lshr,
6014
  check_mk_bv_ashr,
6015
  check_mk_bv_extract,
6016
  check_mk_bv_concat,
6017
  check_mk_bv_repeat,
6018
  check_mk_bv_sign_extend,
6019
  check_mk_bv_zero_extend,
6020
  check_mk_bv_redand,
6021
  check_mk_bv_redor,
6022
  check_mk_bv_comp,
6023
  check_mk_bv_ge,
6024
  check_mk_bv_gt,
6025
  check_mk_bv_le,
6026
  check_mk_bv_lt,
6027
  check_mk_bv_sge,
6028
  check_mk_bv_sgt,
6029
  check_mk_bv_sle,
6030
  check_mk_bv_slt,
6031
  check_mk_bool2bv,
6032
  check_mk_bit,
6033
  check_mk_floor,
6034
  check_mk_ceil,
6035
  check_mk_abs,
6036
  check_mk_idiv,
6037
  check_mk_mod,
6038
  check_mk_divides,
6039
  check_mk_is_int,
6040
  check_mk_ff_const,
6041
  check_mk_ff_add,
6042
  check_mk_ff_mul,
6043
  check_build_term,
6044
  check_build_type,
6045
};
6046

6047
static const eval_fun_t eval[NUM_BASE_OPCODES] = {
6048
  NULL, // NO_OP
6049
  eval_define_type,
6050
  eval_define_term,
6051
  eval_bind,
6052
  eval_declare_var,
6053
  eval_declare_type_var,
6054
  eval_let,
6055
  eval_mk_bv_type,
6056
  eval_mk_ff_type,
6057
  eval_mk_scalar_type,
6058
  eval_mk_tuple_type,
6059
  eval_mk_fun_type,
6060
  eval_mk_app_type,
6061
  eval_mk_apply,
6062
  eval_mk_ite,
6063
  eval_mk_eq,
6064
  eval_mk_diseq,
6065
  eval_mk_distinct,
6066
  eval_mk_not,
6067
  eval_mk_or,
6068
  eval_mk_and,
6069
  eval_mk_xor,
6070
  eval_mk_iff,
6071
  eval_mk_implies,
6072
  eval_mk_tuple,
6073
  eval_mk_select,
6074
  eval_mk_tuple_update,
6075
  eval_mk_update,
6076
  eval_mk_forall,
6077
  eval_mk_exists,
6078
  eval_mk_lambda,
6079
  eval_mk_add,
6080
  eval_mk_sub,
6081
  eval_mk_neg,
6082
  eval_mk_mul,
6083
  eval_mk_division,
6084
  eval_mk_pow,
6085
  eval_mk_ge,
6086
  eval_mk_gt,
6087
  eval_mk_le,
6088
  eval_mk_lt,
6089
  eval_mk_bv_const,
6090
  eval_mk_bv_add,
6091
  eval_mk_bv_sub,
6092
  eval_mk_bv_mul,
6093
  eval_mk_bv_neg,
6094
  eval_mk_bv_pow,
6095
  eval_mk_bv_div,
6096
  eval_mk_bv_rem,
6097
  eval_mk_bv_sdiv,
6098
  eval_mk_bv_srem,
6099
  eval_mk_bv_smod,
6100
  eval_mk_bv_not,
6101
  eval_mk_bv_and,
6102
  eval_mk_bv_or,
6103
  eval_mk_bv_xor,
6104
  eval_mk_bv_nand,
6105
  eval_mk_bv_nor,
6106
  eval_mk_bv_xnor,
6107
  eval_mk_bv_shift_left0,
6108
  eval_mk_bv_shift_left1,
6109
  eval_mk_bv_shift_right0,
6110
  eval_mk_bv_shift_right1,
6111
  eval_mk_bv_ashift_right,
6112
  eval_mk_bv_rotate_left,
6113
  eval_mk_bv_rotate_right,
6114
  eval_mk_bv_shl,
6115
  eval_mk_bv_lshr,
6116
  eval_mk_bv_ashr,
6117
  eval_mk_bv_extract,
6118
  eval_mk_bv_concat,
6119
  eval_mk_bv_repeat,
6120
  eval_mk_bv_sign_extend,
6121
  eval_mk_bv_zero_extend,
6122
  eval_mk_bv_redand,
6123
  eval_mk_bv_redor,
6124
  eval_mk_bv_comp,
6125
  eval_mk_bv_ge,
6126
  eval_mk_bv_gt,
6127
  eval_mk_bv_le,
6128
  eval_mk_bv_lt,
6129
  eval_mk_bv_sge,
6130
  eval_mk_bv_sgt,
6131
  eval_mk_bv_sle,
6132
  eval_mk_bv_slt,
6133
  eval_mk_bool2bv,
6134
  eval_mk_bit,
6135
  eval_mk_floor,
6136
  eval_mk_ceil,
6137
  eval_mk_abs,
6138
  eval_mk_idiv,
6139
  eval_mk_mod,
6140
  eval_mk_divides,
6141
  eval_mk_is_int,
6142
  eval_mk_ff_const,
6143
  eval_mk_ff_add,
6144
  eval_mk_ff_mul,
6145
  eval_build_term,
6146
  eval_build_type,
6147
};
6148

6149

6150
/*
6151
 * Initialize the stack
6152
 * - n = size of the operator table (must be >= NUM_BASE_OPCODES)
6153
 * - the op_table is initialized: all default operators are defined
6154
 */
6155
void init_tstack(tstack_t *stack, uint32_t n) {
1,666✔
6156
  op_table_t *table;
6157
  uint32_t i;
6158

6159
  assert(n >= NUM_BASE_OPCODES);
6160

6161
  alloc_tstack(stack, n);
1,666✔
6162
  table = &stack->op_table;
1,666✔
6163
  for (i=0; i<NUM_BASE_OPCODES; i++) {
166,600✔
6164
    table->assoc[i] = assoc[i];
164,934✔
6165
    table->eval[i] = eval[i];
164,934✔
6166
    table->check[i] = check[i];
164,934✔
6167
  }
6168
  table->num_ops = i;
1,666✔
6169
}
1,666✔
6170

6171

6172
/*
6173
 * Delete the stack
6174
 */
6175
void delete_tstack(tstack_t *stack) {
1,666✔
6176
  tstack_reset(stack);
1,666✔
6177

6178
  safe_free(stack->elem);
1,666✔
6179
  stack->elem = NULL;
1,666✔
6180

6181
  delete_op_table(&stack->op_table);
1,666✔
6182

6183
  delete_arena(&stack->mem);
1,666✔
6184

6185
  safe_free(stack->aux_buffer);
1,666✔
6186
  stack->aux_buffer = NULL;
1,666✔
6187

6188
  if (stack->sbuffer != NULL) {
1,666✔
6189
    safe_free(stack->sbuffer);
7✔
6190
    stack->sbuffer = NULL;
7✔
6191
  }
6192

6193
  if (stack->name_buffer != NULL) {
1,666✔
6194
    safe_free(stack->name_buffer);
846✔
6195
    stack->name_buffer = NULL;
846✔
6196
  }
6197

6198
  delete_bvconstant(&stack->bvconst_buffer);
1,666✔
6199

6200
  if (stack->abuffer != NULL) {
1,666✔
6201
    yices_free_arith_buffer(stack->abuffer);
675✔
6202
    stack->abuffer = NULL;
675✔
6203
  }
6204

6205
  if (stack->bva64buffer != NULL) {
1,666✔
6206
    yices_free_bvarith64_buffer(stack->bva64buffer);
365✔
6207
    stack->bva64buffer = NULL;
365✔
6208
  }
6209

6210
  if (stack->bvabuffer != NULL) {
1,666✔
6211
    yices_free_bvarith_buffer(stack->bvabuffer);
71✔
6212
    stack->bvabuffer = NULL;
71✔
6213
  }
6214

6215
  if (stack->bvlbuffer != NULL) {
1,666✔
6216
    yices_free_bvlogic_buffer(stack->bvlbuffer);
530✔
6217
    stack->bvlbuffer = NULL;
530✔
6218
  }
6219
}
1,666✔
6220

6221

6222
/*
6223
 * Reset all the internal buffers
6224
 */
6225
void tstack_reset_buffers(tstack_t *stack) {
24✔
6226
  if (stack->abuffer != NULL) {
24✔
6227
    yices_free_arith_buffer(stack->abuffer);
×
6228
    stack->abuffer = NULL;
×
6229
  }
6230

6231
  if (stack->bva64buffer != NULL) {
24✔
6232
    yices_free_bvarith64_buffer(stack->bva64buffer);
24✔
6233
    stack->bva64buffer = NULL;
24✔
6234
  }
6235

6236
  if (stack->bvabuffer != NULL) {
24✔
6237
    yices_free_bvarith_buffer(stack->bvabuffer);
×
6238
    stack->bvabuffer = NULL;
×
6239
  }
6240

6241
  if (stack->bvlbuffer != NULL) {
24✔
6242
    yices_free_bvlogic_buffer(stack->bvlbuffer);
21✔
6243
    stack->bvlbuffer = NULL;
21✔
6244
  }
6245
}
24✔
6246

6247

6248

6249
/*
6250
 * Add or replace an operator
6251
 * - op = operator code
6252
 * - asssoc = whether op is associative or not
6253
 * - eval. check = evaluator and checker functions
6254
 * - op must be non-negative and less than the operator's table size
6255
 *   (as set in init_tstack)
6256
 *
6257
 * If op is between 0 and stack->op_table.num_ops then the
6258
 * current values for op are replaced. If op is larger than
6259
 * num_ops, then a new operation is added.
6260
 */
6261
void tstack_add_op(tstack_t *stack, int32_t op, bool assoc, eval_fun_t eval, check_fun_t check) {
101,842✔
6262
  uint32_t i, nops;
6263

6264
  assert(0 <= op && op < stack->op_table.size);
6265

6266
  i = op;
101,842✔
6267
  stack->op_table.assoc[i] = assoc;
101,842✔
6268
  stack->op_table.eval[i] = eval;
101,842✔
6269
  stack->op_table.check[i] = check;
101,842✔
6270

6271
  nops = stack->op_table.num_ops;
101,842✔
6272
  if (i >= nops) {
101,842✔
6273
    stack->op_table.num_ops = i+1;
75,000✔
6274
  }
6275
}
101,842✔
6276

6277

6278
/*
6279
 * Get the operator enclosing the top-frame
6280
 * - if the stack is empty, it will contain just the bottom marker,
6281
 *   which has index 0 and contains
6282
 *     tag = TAG_OP
6283
 *     opval.opcode = NO_OP
6284
 *     opval.prev = 0
6285
 * - so there's no need to test for n == 0 in the code below.
6286
 */
6287
int32_t get_enclosing_op(tstack_t *stack) {
49,522✔
6288
  uint32_t n, i;
6289

6290
  n = stack->frame; // top frame
49,522✔
6291
  assert(stack->elem[n].tag == TAG_OP);
6292
  i = stack->elem[n].val.opval.prev;  // previous frame (unless n = 0)
49,522✔
6293
  assert(stack->elem[i].tag == TAG_OP);
6294

6295
  return stack->elem[i].val.opval.opcode;
49,522✔
6296
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc