1 /* Boolector: Satisfiability Modulo Theories (SMT) solver.
2 *
3 * Copyright (C) 2007-2021 by the authors listed in the AUTHORS file.
4 *
5 * This file is part of Boolector.
6 * See COPYING for more information on using this software.
7 */
8
9 #include "btornode.h"
10
11 #include "btorabort.h"
12 #include "btoraig.h"
13 #include "btoraigvec.h"
14 #include "btorbeta.h"
15 #include "btordbg.h"
16 #include "btorexp.h"
17 #include "btorlog.h"
18 #include "btorrewrite.h"
19 #include "utils/btorhashint.h"
20 #include "utils/btorhashptr.h"
21 #include "utils/btornodeiter.h"
22 #include "utils/btorutil.h"
23
24 #include <assert.h>
25 #include <ctype.h>
26 #include <limits.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 /*------------------------------------------------------------------------*/
32
33 #define BTOR_UNIQUE_TABLE_LIMIT 30
34
35 #define BTOR_FULL_UNIQUE_TABLE(table) \
36 ((table).num_elements >= (table).size \
37 && btor_util_log_2 ((table).size) < BTOR_UNIQUE_TABLE_LIMIT)
38
39 /*------------------------------------------------------------------------*/
40
41 const char *const g_btor_op2str[BTOR_NUM_OPS_NODE] = {
42 [BTOR_INVALID_NODE] = "invalid", [BTOR_BV_CONST_NODE] = "bvconst",
43 [BTOR_VAR_NODE] = "var", [BTOR_PARAM_NODE] = "param",
44 [BTOR_BV_SLICE_NODE] = "slice", [BTOR_BV_AND_NODE] = "and",
45 [BTOR_BV_EQ_NODE] = "beq", [BTOR_FUN_EQ_NODE] = "feq",
46 [BTOR_BV_ADD_NODE] = "add", [BTOR_BV_MUL_NODE] = "mul",
47 [BTOR_BV_ULT_NODE] = "ult", [BTOR_BV_SLL_NODE] = "sll",
48 [BTOR_BV_SRL_NODE] = "srl", [BTOR_BV_UDIV_NODE] = "udiv",
49 [BTOR_BV_UREM_NODE] = "urem", [BTOR_BV_CONCAT_NODE] = "concat",
50 [BTOR_APPLY_NODE] = "apply", [BTOR_FORALL_NODE] = "forall",
51 [BTOR_EXISTS_NODE] = "exists", [BTOR_LAMBDA_NODE] = "lambda",
52 [BTOR_COND_NODE] = "cond", [BTOR_ARGS_NODE] = "args",
53 [BTOR_UF_NODE] = "uf", [BTOR_UPDATE_NODE] = "update",
54 [BTOR_PROXY_NODE] = "proxy",
55 };
56
57 /*------------------------------------------------------------------------*/
58
59 static uint32_t hash_primes[] = {333444569u, 76891121u, 456790003u};
60
61 #define NPRIMES ((uint32_t) (sizeof hash_primes / sizeof *hash_primes))
62
63 /*------------------------------------------------------------------------*/
64
65 /* do not move these two functions to the header (circular dependency) */
66
67 bool
btor_node_is_bv_cond(const BtorNode * exp)68 btor_node_is_bv_cond (const BtorNode *exp)
69 {
70 return btor_node_is_cond (exp)
71 && btor_sort_is_bv (btor_node_real_addr (exp)->btor,
72 btor_node_get_sort_id (exp));
73 }
74
75 bool
btor_node_is_fun_cond(const BtorNode * exp)76 btor_node_is_fun_cond (const BtorNode *exp)
77 {
78 return btor_node_is_cond (exp)
79 && btor_sort_is_fun (btor_node_real_addr (exp)->btor,
80 btor_node_get_sort_id (exp));
81 }
82
83 /*------------------------------------------------------------------------*/
84
85 #ifndef NDEBUG
86 static bool
is_valid_kind(BtorNodeKind kind)87 is_valid_kind (BtorNodeKind kind)
88 {
89 return BTOR_INVALID_NODE <= kind && kind < BTOR_NUM_OPS_NODE;
90 }
91 #endif
92
93 static void
set_kind(Btor * btor,BtorNode * exp,BtorNodeKind kind)94 set_kind (Btor *btor, BtorNode *exp, BtorNodeKind kind)
95 {
96 assert (is_valid_kind (kind));
97 assert (is_valid_kind (exp->kind));
98
99 assert (!BTOR_INVALID_NODE);
100
101 if (exp->kind)
102 {
103 assert (btor->ops[exp->kind].cur > 0);
104 btor->ops[exp->kind].cur--;
105 }
106
107 if (kind)
108 {
109 btor->ops[kind].cur++;
110 assert (btor->ops[kind].cur > 0);
111 if (btor->ops[kind].cur > btor->ops[kind].max)
112 btor->ops[kind].max = btor->ops[kind].cur;
113 }
114
115 exp->kind = kind;
116 }
117
118 /*------------------------------------------------------------------------*/
119
120 bool
btor_node_is_bv_const_zero(Btor * btor,BtorNode * exp)121 btor_node_is_bv_const_zero (Btor *btor, BtorNode *exp)
122 {
123 assert (btor);
124 assert (exp);
125
126 bool result;
127 BtorNode *real_exp;
128 BtorBitVector *bits;
129
130 exp = btor_simplify_exp (btor, exp);
131
132 if (!btor_node_is_bv_const (exp)) return false;
133
134 real_exp = btor_node_real_addr (exp);
135 bits = btor_node_bv_const_get_bits (real_exp);
136 if (btor_node_is_inverted (exp)) bits = btor_bv_not (btor->mm, bits);
137 result = btor_bv_is_zero (bits);
138 if (btor_node_is_inverted (exp)) btor_bv_free (btor->mm, bits);
139
140 return result;
141 }
142
143 bool
btor_node_is_bv_const_one(Btor * btor,BtorNode * exp)144 btor_node_is_bv_const_one (Btor *btor, BtorNode *exp)
145 {
146 assert (btor);
147 assert (exp);
148
149 bool result;
150 BtorNode *real_exp;
151 BtorBitVector *bits;
152
153 exp = btor_simplify_exp (btor, exp);
154
155 if (!btor_node_is_bv_const (exp)) return false;
156
157 real_exp = btor_node_real_addr (exp);
158 bits = btor_node_bv_const_get_bits (real_exp);
159 if (btor_node_is_inverted (exp)) bits = btor_bv_not (btor->mm, bits);
160 result = btor_bv_is_one (bits);
161 if (btor_node_is_inverted (exp)) btor_bv_free (btor->mm, bits);
162
163 return result;
164 }
165
166 bool
btor_node_is_bv_const_ones(Btor * btor,BtorNode * exp)167 btor_node_is_bv_const_ones (Btor *btor, BtorNode *exp)
168 {
169 assert (btor);
170 assert (exp);
171
172 bool result;
173 BtorNode *real_exp;
174 BtorBitVector *bits;
175
176 exp = btor_simplify_exp (btor, exp);
177
178 if (!btor_node_is_bv_const (exp)) return false;
179
180 real_exp = btor_node_real_addr (exp);
181 bits = btor_node_bv_const_get_bits (real_exp);
182 if (btor_node_is_inverted (exp)) bits = btor_bv_not (btor->mm, bits);
183 result = btor_bv_is_ones (bits);
184 if (btor_node_is_inverted (exp)) btor_bv_free (btor->mm, bits);
185
186 return result;
187 }
188
189 bool
btor_node_is_bv_const_min_signed(Btor * btor,BtorNode * exp)190 btor_node_is_bv_const_min_signed (Btor *btor, BtorNode *exp)
191 {
192 assert (btor);
193 assert (exp);
194
195 bool result;
196 BtorNode *real_exp;
197 BtorBitVector *bits;
198
199 exp = btor_simplify_exp (btor, exp);
200
201 if (!btor_node_is_bv_const (exp)) return false;
202
203 real_exp = btor_node_real_addr (exp);
204 bits = btor_node_bv_const_get_bits (real_exp);
205 if (btor_node_is_inverted (exp)) bits = btor_bv_not (btor->mm, bits);
206 result = btor_bv_is_min_signed (bits);
207 if (btor_node_is_inverted (exp)) btor_bv_free (btor->mm, bits);
208
209 return result;
210 }
211
212 bool
btor_node_is_bv_const_max_signed(Btor * btor,BtorNode * exp)213 btor_node_is_bv_const_max_signed (Btor *btor, BtorNode *exp)
214 {
215 assert (btor);
216 assert (exp);
217
218 bool result;
219 BtorNode *real_exp;
220 BtorBitVector *bits;
221
222 exp = btor_simplify_exp (btor, exp);
223
224 if (!btor_node_is_bv_const (exp)) return false;
225
226 real_exp = btor_node_real_addr (exp);
227 bits = btor_node_bv_const_get_bits (real_exp);
228 if (btor_node_is_inverted (exp)) bits = btor_bv_not (btor->mm, bits);
229 result = btor_bv_is_max_signed (bits);
230 if (btor_node_is_inverted (exp)) btor_bv_free (btor->mm, bits);
231
232 return result;
233 }
234
235 bool
btor_node_bv_is_neg(Btor * btor,BtorNode * exp,BtorNode ** res)236 btor_node_bv_is_neg (Btor *btor, BtorNode *exp, BtorNode **res)
237 {
238 assert (btor);
239 assert (exp);
240
241 if (btor_node_is_inverted (exp) || !btor_node_is_bv_add (exp)) return false;
242
243 if (btor_node_is_bv_const_one (btor, exp->e[0]))
244 {
245 if (res) *res = btor_node_invert (exp->e[1]);
246 return true;
247 }
248
249 if (btor_node_is_bv_const_one (btor, exp->e[1]))
250 {
251 if (res) *res = btor_node_invert (exp->e[0]);
252 return true;
253 }
254
255 return false;
256 }
257
258 /*------------------------------------------------------------------------*/
259
260 static void
inc_exp_ref_counter(Btor * btor,BtorNode * exp)261 inc_exp_ref_counter (Btor *btor, BtorNode *exp)
262 {
263 assert (btor);
264 assert (exp);
265
266 BtorNode *real_exp;
267
268 (void) btor;
269 real_exp = btor_node_real_addr (exp);
270 BTOR_ABORT (real_exp->refs == INT32_MAX, "Node reference counter overflow");
271 real_exp->refs++;
272 }
273
274 void
btor_node_inc_ext_ref_counter(Btor * btor,BtorNode * exp)275 btor_node_inc_ext_ref_counter (Btor *btor, BtorNode *exp)
276 {
277 assert (btor);
278 assert (exp);
279
280 BtorNode *real_exp = btor_node_real_addr (exp);
281 BTOR_ABORT (real_exp->ext_refs == INT32_MAX, "Node reference counter overflow");
282 real_exp->ext_refs += 1;
283 btor->external_refs += 1;
284 }
285
286 void
btor_node_dec_ext_ref_counter(Btor * btor,BtorNode * exp)287 btor_node_dec_ext_ref_counter (Btor *btor, BtorNode *exp)
288 {
289 assert (btor);
290 assert (exp);
291
292 btor_node_real_addr (exp)->ext_refs -= 1;
293 btor->external_refs -= 1;
294 }
295
296 BtorNode *
btor_node_copy(Btor * btor,BtorNode * exp)297 btor_node_copy (Btor *btor, BtorNode *exp)
298 {
299 assert (btor);
300 assert (exp);
301 assert (btor == btor_node_real_addr (exp)->btor);
302 inc_exp_ref_counter (btor, exp);
303 return exp;
304 }
305
306 /*------------------------------------------------------------------------*/
307
308 static inline uint32_t
hash_slice_exp(BtorNode * e,uint32_t upper,uint32_t lower)309 hash_slice_exp (BtorNode *e, uint32_t upper, uint32_t lower)
310 {
311 uint32_t hash;
312 assert (upper >= lower);
313 hash = hash_primes[0] * (uint32_t) btor_node_real_addr (e)->id;
314 hash += hash_primes[1] * (uint32_t) upper;
315 hash += hash_primes[2] * (uint32_t) lower;
316 return hash;
317 }
318
319 static inline uint32_t
hash_bv_exp(Btor * btor,BtorNodeKind kind,uint32_t arity,BtorNode * e[])320 hash_bv_exp (Btor *btor, BtorNodeKind kind, uint32_t arity, BtorNode *e[])
321 {
322 uint32_t hash = 0;
323 uint32_t i;
324 #ifndef NDEBUG
325 if (btor_opt_get (btor, BTOR_OPT_SORT_EXP) > 0
326 && btor_node_is_binary_commutative_kind (kind))
327 assert (arity == 2), assert (btor_node_real_addr (e[0])->id
328 <= btor_node_real_addr (e[1])->id);
329 #else
330 (void) btor;
331 (void) kind;
332 #endif
333 assert (arity <= NPRIMES);
334 for (i = 0; i < arity; i++)
335 hash += hash_primes[i] * (uint32_t) btor_node_real_addr (e[i])->id;
336 return hash;
337 }
338
339 static uint32_t
hash_binder_exp(Btor * btor,BtorNode * param,BtorNode * body,BtorIntHashTable * params)340 hash_binder_exp (Btor *btor,
341 BtorNode *param,
342 BtorNode *body,
343 BtorIntHashTable *params)
344 {
345 assert (btor);
346 assert (body);
347
348 uint32_t i;
349 uint32_t hash = 0;
350 BtorNode *cur, *real_cur;
351 BtorNodePtrStack visit;
352 BtorIntHashTable *marked, *p;
353 BtorPtrHashBucket *b;
354
355 marked = btor_hashint_table_new (btor->mm);
356 BTOR_INIT_STACK (btor->mm, visit);
357 BTOR_PUSH_STACK (visit, body);
358
359 while (!BTOR_EMPTY_STACK (visit))
360 {
361 cur = BTOR_POP_STACK (visit);
362 real_cur = btor_node_real_addr (cur);
363
364 if (btor_hashint_table_contains (marked, real_cur->id)) continue;
365
366 if (!real_cur->parameterized)
367 {
368 hash += btor_node_get_id (cur);
369 continue;
370 }
371
372 /* paramterized lambda already hashed, we can use already computed hash
373 * value instead of recomputing it */
374 if (btor_node_is_lambda (real_cur))
375 {
376 hash += btor_hashptr_table_get (btor->lambdas, real_cur)->data.as_int;
377 hash += real_cur->kind;
378 hash += real_cur->e[0]->kind;
379 continue;
380 }
381 else if (btor_node_is_quantifier (real_cur))
382 {
383 hash += btor_hashptr_table_get (btor->quantifiers, real_cur)->data.as_int;
384 hash += real_cur->kind;
385 hash += real_cur->e[0]->kind;
386 /* copy parameters of real_cur to params */
387 if (params)
388 {
389 b = btor_hashptr_table_get (btor->parameterized, real_cur);
390 if (b)
391 {
392 assert (b->data.as_ptr);
393 p = b->data.as_ptr;
394 for (i = 0; i < p->size; i++)
395 {
396 if (p->keys[i] && p->keys[i] != param->id
397 && !btor_hashint_table_contains (params, p->keys[i]))
398 btor_hashint_table_add (params, p->keys[i]);
399 }
400 }
401 }
402 continue;
403 }
404 else if (btor_node_is_param (real_cur) && real_cur != param && params)
405 btor_hashint_table_add (params, real_cur->id);
406
407 btor_hashint_table_add (marked, real_cur->id);
408 hash += btor_node_is_inverted (cur) ? -real_cur->kind : real_cur->kind;
409 for (i = 0; i < real_cur->arity; i++)
410 BTOR_PUSH_STACK (visit, real_cur->e[i]);
411 }
412 BTOR_RELEASE_STACK (visit);
413 btor_hashint_table_delete (marked);
414 return hash;
415 }
416
417 /* Computes hash value of expresssion by children ids */
418 static uint32_t
compute_hash_exp(Btor * btor,BtorNode * exp,uint32_t table_size)419 compute_hash_exp (Btor *btor, BtorNode *exp, uint32_t table_size)
420 {
421 assert (exp);
422 assert (table_size > 0);
423 assert (btor_util_is_power_of_2 (table_size));
424 assert (btor_node_is_regular (exp));
425 assert (!btor_node_is_bv_var (exp));
426 assert (!btor_node_is_uf (exp));
427
428 uint32_t hash = 0;
429
430 if (btor_node_is_bv_const (exp))
431 hash = btor_bv_hash (btor_node_bv_const_get_bits (exp));
432 /* hash for lambdas is computed once during creation. afterwards, we always
433 * have to use the saved hash value since hashing of lambdas requires all
434 * parameterized nodes and their inputs (cf. hash_binder_exp), which may
435 * change at some point. */
436 else if (btor_node_is_lambda (exp))
437 hash = btor_hashptr_table_get (exp->btor->lambdas, (BtorNode *) exp)
438 ->data.as_int;
439 else if (btor_node_is_quantifier (exp))
440 hash = btor_hashptr_table_get (exp->btor->quantifiers, exp)->data.as_int;
441 else if (exp->kind == BTOR_BV_SLICE_NODE)
442 hash = hash_slice_exp (exp->e[0],
443 btor_node_bv_slice_get_upper (exp),
444 btor_node_bv_slice_get_lower (exp));
445 else
446 hash = hash_bv_exp (btor, exp->kind, exp->arity, exp->e);
447 hash &= table_size - 1;
448 return hash;
449 }
450
451 /*------------------------------------------------------------------------*/
452
453 static void
setup_node_and_add_to_id_table(Btor * btor,void * ptr)454 setup_node_and_add_to_id_table (Btor *btor, void *ptr)
455 {
456 assert (btor);
457 assert (ptr);
458
459 BtorNode *exp;
460 uint32_t id;
461
462 exp = (BtorNode *) ptr;
463 assert (!btor_node_is_inverted (exp));
464 assert (!exp->id);
465
466 exp->refs = 1;
467 exp->btor = btor;
468 btor->stats.expressions++;
469 id = BTOR_COUNT_STACK (btor->nodes_id_table);
470 BTOR_ABORT (id == INT32_MAX, "expression id overflow");
471 exp->id = id;
472 BTOR_PUSH_STACK (btor->nodes_id_table, exp);
473 assert (BTOR_COUNT_STACK (btor->nodes_id_table) == (size_t) exp->id + 1);
474 assert (BTOR_PEEK_STACK (btor->nodes_id_table, exp->id) == exp);
475 btor->stats.node_bytes_alloc += exp->bytes;
476
477 if (btor_node_is_apply (exp)) exp->apply_below = 1;
478 }
479
480 /* Enlarges unique table and rehashes expressions. */
481 static void
enlarge_nodes_unique_table(Btor * btor)482 enlarge_nodes_unique_table (Btor *btor)
483 {
484 assert (btor);
485
486 BtorMemMgr *mm;
487 uint32_t size, new_size, i;
488 uint32_t hash;
489 BtorNode *cur, *temp, **new_chains;
490
491 mm = btor->mm;
492 size = btor->nodes_unique_table.size;
493 new_size = size ? 2 * size : 1;
494 BTOR_CNEWN (mm, new_chains, new_size);
495 for (i = 0; i < size; i++)
496 {
497 cur = btor->nodes_unique_table.chains[i];
498 while (cur)
499 {
500 assert (btor_node_is_regular (cur));
501 assert (!btor_node_is_bv_var (cur));
502 assert (!btor_node_is_uf (cur));
503 temp = cur->next;
504 hash = compute_hash_exp (btor, cur, new_size);
505 cur->next = new_chains[hash];
506 new_chains[hash] = cur;
507 cur = temp;
508 }
509 }
510 BTOR_DELETEN (mm, btor->nodes_unique_table.chains, size);
511 btor->nodes_unique_table.size = new_size;
512 btor->nodes_unique_table.chains = new_chains;
513 }
514
515 static void
remove_from_nodes_unique_table_exp(Btor * btor,BtorNode * exp)516 remove_from_nodes_unique_table_exp (Btor *btor, BtorNode *exp)
517 {
518 assert (exp);
519 assert (btor_node_is_regular (exp));
520
521 uint32_t hash;
522 BtorNode *cur, *prev;
523
524 if (!exp->unique) return;
525
526 assert (btor);
527 assert (btor->nodes_unique_table.num_elements > 0);
528
529 hash = compute_hash_exp (btor, exp, btor->nodes_unique_table.size);
530 prev = 0;
531 cur = btor->nodes_unique_table.chains[hash];
532
533 while (cur != exp)
534 {
535 assert (cur);
536 assert (btor_node_is_regular (cur));
537 prev = cur;
538 cur = cur->next;
539 }
540 assert (cur);
541 if (!prev)
542 btor->nodes_unique_table.chains[hash] = cur->next;
543 else
544 prev->next = cur->next;
545
546 btor->nodes_unique_table.num_elements--;
547
548 exp->unique = 0; /* NOTE: this is not debugging code ! */
549 exp->next = 0;
550 }
551
552 static void
remove_from_hash_tables(Btor * btor,BtorNode * exp,bool keep_symbol)553 remove_from_hash_tables (Btor *btor, BtorNode *exp, bool keep_symbol)
554 {
555 assert (btor);
556 assert (exp);
557 assert (btor_node_is_regular (exp));
558 assert (!btor_node_is_invalid (exp));
559
560 BtorHashTableData data;
561
562 switch (exp->kind)
563 {
564 case BTOR_VAR_NODE:
565 btor_hashptr_table_remove (btor->bv_vars, exp, 0, 0);
566 break;
567 case BTOR_LAMBDA_NODE:
568 btor_hashptr_table_remove (btor->lambdas, exp, 0, 0);
569 break;
570 case BTOR_FORALL_NODE:
571 case BTOR_EXISTS_NODE:
572 btor_hashptr_table_remove (btor->quantifiers, exp, 0, 0);
573 break;
574 case BTOR_UF_NODE: btor_hashptr_table_remove (btor->ufs, exp, 0, 0); break;
575 case BTOR_FUN_EQ_NODE:
576 btor_hashptr_table_remove (btor->feqs, exp, 0, 0);
577 break;
578 default: break;
579 }
580
581 if (!keep_symbol && btor_hashptr_table_get (btor->node2symbol, exp))
582 {
583 btor_hashptr_table_remove (btor->node2symbol, exp, 0, &data);
584 if (data.as_str[0] != 0)
585 {
586 btor_hashptr_table_remove (btor->symbols, data.as_str, 0, 0);
587 btor_mem_freestr (btor->mm, data.as_str);
588 }
589 }
590
591 if (btor_hashptr_table_get (btor->parameterized, exp))
592 {
593 btor_hashptr_table_remove (btor->parameterized, exp, 0, &data);
594 assert (data.as_ptr);
595 btor_hashint_table_delete (data.as_ptr);
596 }
597 }
598
599 /*------------------------------------------------------------------------*/
600
601 /* Connects child to its parent and updates list of parent pointers.
602 * Expressions are inserted at the beginning of the regular parent list
603 */
604 static void
connect_child_exp(Btor * btor,BtorNode * parent,BtorNode * child,uint32_t pos)605 connect_child_exp (Btor *btor, BtorNode *parent, BtorNode *child, uint32_t pos)
606 {
607 assert (btor);
608 assert (parent);
609 assert (btor_node_is_regular (parent));
610 assert (btor == parent->btor);
611 assert (child);
612 assert (btor == btor_node_real_addr (child)->btor);
613 assert (pos <= 2);
614 assert (btor_simplify_exp (btor, child) == child);
615 assert (!btor_node_is_args (child) || btor_node_is_args (parent)
616 || btor_node_is_apply (parent) || btor_node_is_update (parent));
617
618 (void) btor;
619 uint32_t tag;
620 bool insert_beginning = 1;
621 BtorNode *real_child, *first_parent, *last_parent, *tagged_parent;
622
623 /* set specific flags */
624
625 /* set parent parameterized if child is parameterized */
626 if (!btor_node_is_binder (parent)
627 && btor_node_real_addr (child)->parameterized)
628 parent->parameterized = 1;
629
630 // TODO (ma): why don't we bind params here?
631
632 if (btor_node_is_fun_cond (parent) && btor_node_real_addr (child)->is_array)
633 parent->is_array = 1;
634
635 if (btor_node_real_addr (child)->lambda_below) parent->lambda_below = 1;
636
637 if (btor_node_real_addr (child)->quantifier_below)
638 parent->quantifier_below = 1;
639
640 if (btor_node_real_addr (child)->rebuild) parent->rebuild = 1;
641
642 if (btor_node_real_addr (child)->apply_below) parent->apply_below = 1;
643
644 btor_node_real_addr (child)->parents++;
645 inc_exp_ref_counter (btor, child);
646
647 /* update parent lists */
648
649 if (btor_node_is_apply (parent)) insert_beginning = false;
650
651 real_child = btor_node_real_addr (child);
652 parent->e[pos] = child;
653 tagged_parent = btor_node_set_tag (parent, pos);
654
655 assert (!parent->prev_parent[pos]);
656 assert (!parent->next_parent[pos]);
657
658 /* no parent so far? */
659 if (!real_child->first_parent)
660 {
661 assert (!real_child->last_parent);
662 real_child->first_parent = tagged_parent;
663 real_child->last_parent = tagged_parent;
664 }
665 /* add parent at the beginning of the list */
666 else if (insert_beginning)
667 {
668 first_parent = real_child->first_parent;
669 assert (first_parent);
670 parent->next_parent[pos] = first_parent;
671 tag = btor_node_get_tag (first_parent);
672 btor_node_real_addr (first_parent)->prev_parent[tag] = tagged_parent;
673 real_child->first_parent = tagged_parent;
674 }
675 /* add parent at the end of the list */
676 else
677 {
678 last_parent = real_child->last_parent;
679 assert (last_parent);
680 parent->prev_parent[pos] = last_parent;
681 tag = btor_node_get_tag (last_parent);
682 btor_node_real_addr (last_parent)->next_parent[tag] = tagged_parent;
683 real_child->last_parent = tagged_parent;
684 }
685 }
686
687 /* Disconnects a child from its parent and updates its parent list */
688 static void
disconnect_child_exp(Btor * btor,BtorNode * parent,uint32_t pos)689 disconnect_child_exp (Btor *btor, BtorNode *parent, uint32_t pos)
690 {
691 assert (btor);
692 assert (parent);
693 assert (btor_node_is_regular (parent));
694 assert (btor == parent->btor);
695 assert (!btor_node_is_bv_const (parent));
696 assert (!btor_node_is_bv_var (parent));
697 assert (!btor_node_is_uf (parent));
698 assert (pos <= 2);
699
700 (void) btor;
701 BtorNode *first_parent, *last_parent;
702 BtorNode *real_child, *tagged_parent;
703
704 tagged_parent = btor_node_set_tag (parent, pos);
705 real_child = btor_node_real_addr (parent->e[pos]);
706 real_child->parents--;
707 first_parent = real_child->first_parent;
708 last_parent = real_child->last_parent;
709 assert (first_parent);
710 assert (last_parent);
711
712 /* if a parameter is disconnected from a lambda we have to reset
713 * 'lambda_exp' of the parameter in order to keep a valid state */
714 if (btor_node_is_binder (parent)
715 && pos == 0
716 /* if parent gets rebuilt via substitute_and_rebuild, it might
717 * result in a new binder term, where the param is already reused.
718 * if this is the case param is already bound by a different binder
719 * and we are not allowed to reset param->binder to 0. */
720 && btor_node_param_get_binder (parent->e[0]) == parent)
721 btor_node_param_set_binder (parent->e[0], 0);
722
723 /* only one parent? */
724 if (first_parent == tagged_parent && first_parent == last_parent)
725 {
726 assert (!parent->next_parent[pos]);
727 assert (!parent->prev_parent[pos]);
728 real_child->first_parent = 0;
729 real_child->last_parent = 0;
730 }
731 /* is parent first parent in the list? */
732 else if (first_parent == tagged_parent)
733 {
734 assert (parent->next_parent[pos]);
735 assert (!parent->prev_parent[pos]);
736 real_child->first_parent = parent->next_parent[pos];
737 BTOR_PREV_PARENT (real_child->first_parent) = 0;
738 }
739 /* is parent last parent in the list? */
740 else if (last_parent == tagged_parent)
741 {
742 assert (!parent->next_parent[pos]);
743 assert (parent->prev_parent[pos]);
744 real_child->last_parent = parent->prev_parent[pos];
745 BTOR_NEXT_PARENT (real_child->last_parent) = 0;
746 }
747 /* detach parent from list */
748 else
749 {
750 assert (parent->next_parent[pos]);
751 assert (parent->prev_parent[pos]);
752 BTOR_PREV_PARENT (parent->next_parent[pos]) = parent->prev_parent[pos];
753 BTOR_NEXT_PARENT (parent->prev_parent[pos]) = parent->next_parent[pos];
754 }
755 parent->next_parent[pos] = 0;
756 parent->prev_parent[pos] = 0;
757 parent->e[pos] = 0;
758 }
759
760 /* Disconnect children of expression in parent list and if applicable from
761 * unique table. Do not touch local data, nor any reference counts. The
762 * kind of the expression becomes 'BTOR_DISCONNECTED_NODE' in debugging mode.
763 *
764 * Actually we have the sequence
765 *
766 * UNIQUE -> !UNIQUE -> ERASED -> DISCONNECTED -> INVALID
767 *
768 * after a unique or non uninque expression is allocated until it is
769 * deallocated. We also have loop back from DISCONNECTED to !UNIQUE
770 * if an expression is rewritten and reused as PROXY.
771 */
772 static void
disconnect_children_exp(Btor * btor,BtorNode * exp)773 disconnect_children_exp (Btor *btor, BtorNode *exp)
774 {
775 assert (btor);
776 assert (exp);
777 assert (btor_node_is_regular (exp));
778 assert (!btor_node_is_invalid (exp));
779 assert (!exp->unique);
780 assert (exp->erased);
781 assert (!exp->disconnected);
782
783 uint32_t i;
784
785 for (i = 0; i < exp->arity; i++) disconnect_child_exp (btor, exp, i);
786 exp->disconnected = 1;
787 }
788
789 /*------------------------------------------------------------------------*/
790
791 /* Delete local data of expression.
792 *
793 * Virtual reads and simplified expressions have to be handled by the
794 * calling function, e.g. 'btor_node_release', to avoid recursion.
795 *
796 * We use this function to update operator stats
797 */
798 static void
erase_local_data_exp(Btor * btor,BtorNode * exp)799 erase_local_data_exp (Btor *btor, BtorNode *exp)
800 {
801 assert (btor);
802 assert (exp);
803
804 assert (btor_node_is_regular (exp));
805
806 assert (!exp->unique);
807 assert (!exp->erased);
808 assert (!exp->disconnected);
809 assert (!btor_node_is_invalid (exp));
810
811 BtorMemMgr *mm;
812 BtorPtrHashTable *static_rho;
813 BtorPtrHashTableIterator it;
814
815 mm = btor->mm;
816 // BTORLOG ("%s: %s", __FUNCTION__, btor_util_node2string (exp));
817
818 switch (exp->kind)
819 {
820 case BTOR_BV_CONST_NODE:
821 btor_bv_free (mm, btor_node_bv_const_get_bits (exp));
822 if (btor_node_bv_const_get_invbits (exp))
823 btor_bv_free (mm, btor_node_bv_const_get_invbits (exp));
824 btor_node_bv_const_set_bits (exp, 0);
825 btor_node_bv_const_set_invbits (exp, 0);
826 break;
827 case BTOR_LAMBDA_NODE:
828 case BTOR_UPDATE_NODE:
829 case BTOR_UF_NODE:
830 if (exp->kind == BTOR_LAMBDA_NODE)
831 {
832 static_rho = btor_node_lambda_get_static_rho (exp);
833 if (static_rho)
834 {
835 btor_iter_hashptr_init (&it, static_rho);
836 while (btor_iter_hashptr_has_next (&it))
837 {
838 btor_node_release (btor, it.bucket->data.as_ptr);
839 btor_node_release (btor, btor_iter_hashptr_next (&it));
840 }
841 btor_hashptr_table_delete (static_rho);
842 ((BtorLambdaNode *) exp)->static_rho = 0;
843 }
844 }
845 if (exp->rho)
846 {
847 btor_hashptr_table_delete (exp->rho);
848 exp->rho = 0;
849 }
850 break;
851 case BTOR_COND_NODE:
852 if (btor_node_is_fun_cond (exp) && exp->rho)
853 {
854 btor_hashptr_table_delete (exp->rho);
855 exp->rho = 0;
856 }
857 break;
858 default: break;
859 }
860
861 if (exp->av)
862 {
863 btor_aigvec_release_delete (btor->avmgr, exp->av);
864 exp->av = 0;
865 }
866 exp->erased = 1;
867 }
868
869 static void
really_deallocate_exp(Btor * btor,BtorNode * exp)870 really_deallocate_exp (Btor *btor, BtorNode *exp)
871 {
872 assert (btor);
873 assert (exp);
874 assert (btor_node_is_regular (exp));
875 assert (btor == exp->btor);
876 assert (!exp->unique);
877 assert (exp->disconnected);
878 assert (exp->erased);
879 assert (exp->id);
880 assert (BTOR_PEEK_STACK (btor->nodes_id_table, exp->id) == exp);
881 BTOR_POKE_STACK (btor->nodes_id_table, exp->id, 0);
882
883 BtorMemMgr *mm;
884
885 mm = btor->mm;
886
887 set_kind (btor, exp, BTOR_INVALID_NODE);
888
889 assert (btor_node_get_sort_id (exp));
890 btor_sort_release (btor, btor_node_get_sort_id (exp));
891 btor_node_set_sort_id (exp, 0);
892
893 btor_mem_free (mm, exp, exp->bytes);
894 }
895
896 static void
recursively_release_exp(Btor * btor,BtorNode * root)897 recursively_release_exp (Btor *btor, BtorNode *root)
898 {
899 assert (btor);
900 assert (root);
901 assert (btor_node_is_regular (root));
902 assert (root->refs == 1);
903
904 BtorNodePtrStack stack;
905 BtorMemMgr *mm;
906 BtorNode *cur;
907 uint32_t i;
908
909 mm = btor->mm;
910
911 BTOR_INIT_STACK (mm, stack);
912 cur = root;
913 goto RECURSIVELY_RELEASE_NODE_ENTER_WITHOUT_POP;
914
915 do
916 {
917 cur = btor_node_real_addr (BTOR_POP_STACK (stack));
918
919 if (cur->refs > 1)
920 cur->refs--;
921 else
922 {
923 RECURSIVELY_RELEASE_NODE_ENTER_WITHOUT_POP:
924 assert (cur->refs == 1);
925 assert (!cur->ext_refs || cur->ext_refs == 1);
926 assert (cur->parents == 0);
927
928 for (i = 1; i <= cur->arity; i++)
929 BTOR_PUSH_STACK (stack, cur->e[cur->arity - i]);
930
931 if (cur->simplified)
932 {
933 BTOR_PUSH_STACK (stack, cur->simplified);
934 cur->simplified = 0;
935 }
936
937 remove_from_nodes_unique_table_exp (btor, cur);
938 erase_local_data_exp (btor, cur);
939
940 /* It is safe to access the children here, since they are pushed
941 * on the stack and will be released later if necessary.
942 */
943 remove_from_hash_tables (btor, cur, 0);
944 disconnect_children_exp (btor, cur);
945 really_deallocate_exp (btor, cur);
946 }
947 } while (!BTOR_EMPTY_STACK (stack));
948 BTOR_RELEASE_STACK (stack);
949 }
950
951 void
btor_node_release(Btor * btor,BtorNode * root)952 btor_node_release (Btor *btor, BtorNode *root)
953 {
954 assert (btor);
955 assert (root);
956 assert (btor == btor_node_real_addr (root)->btor);
957
958 root = btor_node_real_addr (root);
959
960 assert (root->refs > 0);
961
962 if (root->refs > 1)
963 root->refs--;
964 else
965 recursively_release_exp (btor, root);
966 }
967
968 /*------------------------------------------------------------------------*/
969
970 void
btor_node_set_to_proxy(Btor * btor,BtorNode * exp)971 btor_node_set_to_proxy (Btor *btor, BtorNode *exp)
972 {
973 assert (btor);
974 assert (exp);
975 assert (btor_node_is_regular (exp));
976 assert (btor == exp->btor);
977 assert (btor_node_is_simplified (exp));
978 assert (!btor_opt_get (btor, BTOR_OPT_NONDESTR_SUBST));
979
980 uint32_t i;
981 BtorNode *e[3];
982
983 remove_from_nodes_unique_table_exp (btor, exp);
984 /* also updates op stats */
985 erase_local_data_exp (btor, exp);
986 assert (exp->arity <= 3);
987 BTOR_CLR (e);
988 for (i = 0; i < exp->arity; i++) e[i] = exp->e[i];
989 remove_from_hash_tables (btor, exp, 1);
990 disconnect_children_exp (btor, exp);
991
992 for (i = 0; i < exp->arity; i++) btor_node_release (btor, e[i]);
993
994 set_kind (btor, exp, BTOR_PROXY_NODE);
995
996 exp->disconnected = 0;
997 exp->erased = 0;
998 exp->arity = 0;
999 exp->parameterized = 0;
1000 }
1001
1002 /*------------------------------------------------------------------------*/
1003
1004 void
btor_node_set_btor_id(Btor * btor,BtorNode * exp,int32_t id)1005 btor_node_set_btor_id (Btor *btor, BtorNode *exp, int32_t id)
1006 {
1007 assert (btor);
1008 assert (exp);
1009 assert (id);
1010 assert (btor == btor_node_real_addr (exp)->btor);
1011 assert (btor_node_is_bv_var (exp) || btor_node_is_uf_array (exp));
1012
1013 (void) btor;
1014 BtorNode *real_exp;
1015 BtorPtrHashBucket *b;
1016
1017 real_exp = btor_node_real_addr (exp);
1018 b = btor_hashptr_table_get (btor->inputs, real_exp);
1019 assert (b);
1020 b->data.as_int = id;
1021 }
1022
1023 int32_t
btor_node_get_btor_id(BtorNode * exp)1024 btor_node_get_btor_id (BtorNode *exp)
1025 {
1026 assert (exp);
1027
1028 int32_t id = 0;
1029 Btor *btor;
1030 BtorNode *real_exp;
1031 BtorPtrHashBucket *b;
1032
1033 real_exp = btor_node_real_addr (exp);
1034 btor = real_exp->btor;
1035
1036 if ((b = btor_hashptr_table_get (btor->inputs, real_exp)))
1037 id = b->data.as_int;
1038 if (btor_node_is_inverted (exp)) return -id;
1039 return id;
1040 }
1041
1042 BtorNode *
btor_node_match_by_id(Btor * btor,int32_t id)1043 btor_node_match_by_id (Btor *btor, int32_t id)
1044 {
1045 assert (btor);
1046 assert (id > 0);
1047 if ((size_t) id >= BTOR_COUNT_STACK (btor->nodes_id_table)) return 0;
1048 BtorNode *exp = BTOR_PEEK_STACK (btor->nodes_id_table, id);
1049 if (!exp) return 0;
1050 return btor_node_copy (btor, exp);
1051 }
1052
1053 BtorNode *
btor_node_get_by_id(Btor * btor,int32_t id)1054 btor_node_get_by_id (Btor *btor, int32_t id)
1055 {
1056 assert (btor);
1057 bool is_inverted = id < 0;
1058 id = abs (id);
1059 if ((size_t) id >= BTOR_COUNT_STACK (btor->nodes_id_table)) return 0;
1060 BtorNode *res = BTOR_PEEK_STACK (btor->nodes_id_table, id);
1061 if (!res) return 0;
1062 return is_inverted ? btor_node_invert (res) : res;
1063 }
1064
1065 /*------------------------------------------------------------------------*/
1066
1067 char *
btor_node_get_symbol(Btor * btor,const BtorNode * exp)1068 btor_node_get_symbol (Btor *btor, const BtorNode *exp)
1069 {
1070 /* do not pointer-chase! */
1071 assert (btor);
1072 assert (exp);
1073 assert (btor == btor_node_real_addr (exp)->btor);
1074 BtorPtrHashBucket *b;
1075
1076 b = btor_hashptr_table_get (btor->node2symbol, btor_node_real_addr (exp));
1077 if (b) return b->data.as_str;
1078 return 0;
1079 }
1080
1081 void
btor_node_set_symbol(Btor * btor,BtorNode * exp,const char * symbol)1082 btor_node_set_symbol (Btor *btor, BtorNode *exp, const char *symbol)
1083 {
1084 /* do not pointer-chase! */
1085 assert (btor);
1086 assert (exp);
1087 assert (btor == btor_node_real_addr (exp)->btor);
1088 assert (symbol);
1089 assert (!btor_hashptr_table_get (btor->symbols, (char *) symbol));
1090
1091 BtorPtrHashBucket *b;
1092 char *sym;
1093
1094 exp = btor_node_real_addr (exp);
1095 sym = btor_mem_strdup (btor->mm, symbol);
1096 btor_hashptr_table_add (btor->symbols, sym)->data.as_ptr = exp;
1097 b = btor_hashptr_table_get (btor->node2symbol, exp);
1098
1099 if (b)
1100 {
1101 btor_hashptr_table_remove (btor->symbols, b->data.as_str, 0, 0);
1102 btor_mem_freestr (btor->mm, b->data.as_str);
1103 }
1104 else
1105 b = btor_hashptr_table_add (btor->node2symbol, exp);
1106
1107 b->data.as_str = sym;
1108 }
1109
1110 BtorNode *
btor_node_get_by_symbol(Btor * btor,const char * sym)1111 btor_node_get_by_symbol (Btor *btor, const char *sym)
1112 {
1113 assert (btor);
1114 assert (sym);
1115 BtorPtrHashBucket *b;
1116 b = btor_hashptr_table_get (btor->symbols, (char *) sym);
1117 if (!b) return 0;
1118 return b->data.as_ptr;
1119 }
1120
1121 BtorNode *
btor_node_match_by_symbol(Btor * btor,const char * sym)1122 btor_node_match_by_symbol (Btor *btor, const char *sym)
1123 {
1124 assert (btor);
1125 assert (sym);
1126 BtorNode *res = btor_node_get_by_symbol (btor, sym);
1127 if (res) btor_node_copy (btor, res);
1128 return res;
1129 }
1130
1131 /*------------------------------------------------------------------------*/
1132
1133 BtorNode *
btor_node_match(Btor * btor,BtorNode * exp)1134 btor_node_match (Btor *btor, BtorNode *exp)
1135 {
1136 assert (btor);
1137 assert (exp);
1138
1139 uint32_t id;
1140 BtorNode *res;
1141
1142 id = btor_node_real_addr (exp)->id;
1143 assert (id > 0);
1144 if (id >= BTOR_COUNT_STACK (btor->nodes_id_table)) return 0;
1145 res = btor_node_copy (btor, BTOR_PEEK_STACK (btor->nodes_id_table, id));
1146 return btor_node_is_inverted (exp) ? btor_node_invert (res) : res;
1147 }
1148
1149 /*------------------------------------------------------------------------*/
1150
1151 /* Compares expressions by id */
1152 int32_t
btor_node_compare_by_id(const BtorNode * exp0,const BtorNode * exp1)1153 btor_node_compare_by_id (const BtorNode *exp0, const BtorNode *exp1)
1154 {
1155 assert (exp0);
1156 assert (exp1);
1157
1158 uint32_t id0, id1;
1159
1160 id0 = btor_node_get_id (exp0);
1161 id1 = btor_node_get_id (exp1);
1162 if (id0 < id1) return -1;
1163 if (id0 > id1) return 1;
1164 return 0;
1165 }
1166
1167 int32_t
btor_node_compare_by_id_qsort_desc(const void * p,const void * q)1168 btor_node_compare_by_id_qsort_desc (const void *p, const void *q)
1169 {
1170 BtorNode *a = btor_node_real_addr (*(BtorNode **) p);
1171 BtorNode *b = btor_node_real_addr (*(BtorNode **) q);
1172 return b->id - a->id;
1173 }
1174
1175 int32_t
btor_node_compare_by_id_qsort_asc(const void * p,const void * q)1176 btor_node_compare_by_id_qsort_asc (const void *p, const void *q)
1177 {
1178 BtorNode *a = btor_node_real_addr (*(BtorNode **) p);
1179 BtorNode *b = btor_node_real_addr (*(BtorNode **) q);
1180 return a->id - b->id;
1181 }
1182
1183 /* Computes hash value of expression by id */
1184 uint32_t
btor_node_hash_by_id(const BtorNode * exp)1185 btor_node_hash_by_id (const BtorNode *exp)
1186 {
1187 assert (exp);
1188 return (uint32_t) btor_node_get_id (exp) * 7334147u;
1189 }
1190
1191 /*------------------------------------------------------------------------*/
1192
1193 uint32_t
btor_node_bv_get_width(Btor * btor,const BtorNode * exp)1194 btor_node_bv_get_width (Btor *btor, const BtorNode *exp)
1195 {
1196 assert (btor);
1197 assert (exp);
1198 assert (!btor_node_is_fun (exp));
1199 assert (!btor_node_is_args (exp));
1200 return btor_sort_bv_get_width (btor, btor_node_get_sort_id (exp));
1201 }
1202
1203 uint32_t
btor_node_fun_get_width(Btor * btor,const BtorNode * exp)1204 btor_node_fun_get_width (Btor *btor, const BtorNode *exp)
1205 {
1206 assert (btor);
1207 assert (exp);
1208 assert (btor_node_is_regular (exp));
1209
1210 assert (btor_sort_is_fun (btor, btor_node_get_sort_id (exp)));
1211 return btor_sort_bv_get_width (
1212 btor, btor_sort_fun_get_codomain (btor, btor_node_get_sort_id (exp)));
1213 }
1214
1215 uint32_t
btor_node_array_get_index_width(Btor * btor,const BtorNode * e_array)1216 btor_node_array_get_index_width (Btor *btor, const BtorNode *e_array)
1217 {
1218 assert (btor);
1219 assert (e_array);
1220 assert (btor == btor_node_real_addr (e_array)->btor);
1221
1222 assert (btor_sort_is_array (btor, btor_node_get_sort_id (e_array))
1223 || btor_sort_is_fun (btor, btor_node_get_sort_id (e_array)));
1224 return btor_sort_bv_get_width (
1225 btor, btor_sort_array_get_index (btor, btor_node_get_sort_id (e_array)));
1226 }
1227
1228 /*------------------------------------------------------------------------*/
1229
1230 BtorBitVector *
btor_node_bv_const_get_bits(BtorNode * exp)1231 btor_node_bv_const_get_bits (BtorNode *exp)
1232 {
1233 assert (exp);
1234 assert (btor_node_is_bv_const (exp));
1235 return ((BtorBVConstNode *) btor_node_real_addr (exp))->bits;
1236 }
1237
1238 BtorBitVector *
btor_node_bv_const_get_invbits(BtorNode * exp)1239 btor_node_bv_const_get_invbits (BtorNode *exp)
1240 {
1241 assert (exp);
1242 assert (btor_node_is_bv_const (exp));
1243 return ((BtorBVConstNode *) btor_node_real_addr (exp))->invbits;
1244 }
1245
1246 void
btor_node_bv_const_set_bits(BtorNode * exp,BtorBitVector * bits)1247 btor_node_bv_const_set_bits (BtorNode *exp, BtorBitVector *bits)
1248 {
1249 assert (exp);
1250 assert (btor_node_is_bv_const (exp));
1251 ((BtorBVConstNode *) btor_node_real_addr (exp))->bits = bits;
1252 }
1253
1254 void
btor_node_bv_const_set_invbits(BtorNode * exp,BtorBitVector * bits)1255 btor_node_bv_const_set_invbits (BtorNode *exp, BtorBitVector *bits)
1256 {
1257 assert (exp);
1258 assert (btor_node_is_bv_const (exp));
1259 ((BtorBVConstNode *) btor_node_real_addr (exp))->invbits = bits;
1260 }
1261
1262 /*------------------------------------------------------------------------*/
1263
1264 uint32_t
btor_node_fun_get_arity(Btor * btor,BtorNode * exp)1265 btor_node_fun_get_arity (Btor *btor, BtorNode *exp)
1266 {
1267 (void) btor;
1268 assert (btor);
1269 assert (exp);
1270 assert (btor == btor_node_real_addr (exp)->btor);
1271 exp = btor_simplify_exp (btor, exp);
1272 assert (btor_node_is_regular (exp));
1273 assert (btor_sort_is_fun (btor, btor_node_get_sort_id (exp)));
1274 return btor_sort_fun_get_arity (btor, btor_node_get_sort_id (exp));
1275 }
1276
1277 uint32_t
btor_node_args_get_arity(Btor * btor,BtorNode * exp)1278 btor_node_args_get_arity (Btor *btor, BtorNode *exp)
1279 {
1280 (void) btor;
1281 assert (btor);
1282 assert (exp);
1283 assert (btor == btor_node_real_addr (exp)->btor);
1284 exp = btor_simplify_exp (btor, exp);
1285 assert (btor_node_is_regular (exp));
1286 assert (btor_node_is_args (exp));
1287 return btor_sort_tuple_get_arity (btor, btor_node_get_sort_id (exp));
1288 }
1289
1290 /*------------------------------------------------------------------------*/
1291
1292 BtorNode *
btor_node_binder_get_body(BtorNode * binder)1293 btor_node_binder_get_body (BtorNode *binder)
1294 {
1295 assert (btor_node_is_regular (binder));
1296 assert (btor_node_is_binder (binder));
1297 return ((BtorBinderNode *) binder)->body;
1298 }
1299
1300 void
btor_node_binder_set_body(BtorNode * binder,BtorNode * body)1301 btor_node_binder_set_body (BtorNode *binder, BtorNode *body)
1302 {
1303 assert (btor_node_is_regular (binder));
1304 assert (btor_node_is_binder (binder));
1305 ((BtorBinderNode *) binder)->body = body;
1306 }
1307
1308 /*------------------------------------------------------------------------*/
1309
1310 BtorPtrHashTable *
btor_node_lambda_get_static_rho(BtorNode * lambda)1311 btor_node_lambda_get_static_rho (BtorNode *lambda)
1312 {
1313 assert (btor_node_is_regular (lambda));
1314 assert (btor_node_is_lambda (lambda));
1315 return ((BtorLambdaNode *) lambda)->static_rho;
1316 }
1317
1318 void
btor_node_lambda_set_static_rho(BtorNode * lambda,BtorPtrHashTable * static_rho)1319 btor_node_lambda_set_static_rho (BtorNode *lambda, BtorPtrHashTable *static_rho)
1320 {
1321 assert (btor_node_is_regular (lambda));
1322 assert (btor_node_is_lambda (lambda));
1323 ((BtorLambdaNode *) lambda)->static_rho = static_rho;
1324 }
1325
1326 BtorPtrHashTable *
btor_node_lambda_copy_static_rho(Btor * btor,BtorNode * lambda)1327 btor_node_lambda_copy_static_rho (Btor *btor, BtorNode *lambda)
1328 {
1329 assert (btor_node_is_regular (lambda));
1330 assert (btor_node_is_lambda (lambda));
1331 assert (btor_node_lambda_get_static_rho (lambda));
1332
1333 BtorNode *data, *key;
1334 BtorPtrHashTableIterator it;
1335 BtorPtrHashTable *static_rho;
1336
1337 btor_iter_hashptr_init (&it, btor_node_lambda_get_static_rho (lambda));
1338 static_rho = btor_hashptr_table_new (btor->mm,
1339 (BtorHashPtr) btor_node_hash_by_id,
1340 (BtorCmpPtr) btor_node_compare_by_id);
1341 while (btor_iter_hashptr_has_next (&it))
1342 {
1343 data = btor_node_copy (btor, it.bucket->data.as_ptr);
1344 key = btor_node_copy (btor, btor_iter_hashptr_next (&it));
1345 btor_hashptr_table_add (static_rho, key)->data.as_ptr = data;
1346 }
1347 return static_rho;
1348 }
1349
1350 void
btor_node_lambda_delete_static_rho(Btor * btor,BtorNode * lambda)1351 btor_node_lambda_delete_static_rho (Btor *btor, BtorNode *lambda)
1352 {
1353 BtorPtrHashTable *static_rho;
1354 BtorPtrHashTableIterator it;
1355
1356 static_rho = btor_node_lambda_get_static_rho (lambda);
1357 if (!static_rho) return;
1358
1359 btor_iter_hashptr_init (&it, static_rho);
1360 while (btor_iter_hashptr_has_next (&it))
1361 {
1362 btor_node_release (btor, it.bucket->data.as_ptr);
1363 btor_node_release (btor, btor_iter_hashptr_next (&it));
1364 }
1365 btor_hashptr_table_delete (static_rho);
1366 btor_node_lambda_set_static_rho (lambda, 0);
1367 }
1368
1369 /*------------------------------------------------------------------------*/
1370
1371 uint32_t
btor_node_bv_slice_get_upper(BtorNode * slice)1372 btor_node_bv_slice_get_upper (BtorNode *slice)
1373 {
1374 assert (btor_node_is_bv_slice (slice));
1375 return ((BtorBVSliceNode *) btor_node_real_addr (slice))->upper;
1376 }
1377
1378 uint32_t
btor_node_bv_slice_get_lower(BtorNode * slice)1379 btor_node_bv_slice_get_lower (BtorNode *slice)
1380 {
1381 assert (btor_node_is_bv_slice (slice));
1382 return ((BtorBVSliceNode *) btor_node_real_addr (slice))->lower;
1383 }
1384
1385 /*------------------------------------------------------------------------*/
1386
1387 BtorNode *
btor_node_param_get_binder(BtorNode * param)1388 btor_node_param_get_binder (BtorNode *param)
1389 {
1390 assert (btor_node_is_param (param));
1391 return ((BtorParamNode *) btor_node_real_addr (param))->binder;
1392 }
1393
1394 void
btor_node_param_set_binder(BtorNode * param,BtorNode * binder)1395 btor_node_param_set_binder (BtorNode *param, BtorNode *binder)
1396 {
1397 assert (btor_node_is_param (param));
1398 assert (!binder || btor_node_is_binder (binder));
1399
1400 BtorNode *q;
1401
1402 /* param is not bound anymore, remove from exists/forall vars tables */
1403 if (!binder)
1404 {
1405 q = btor_node_param_get_binder (param);
1406 if (q)
1407 {
1408 if (btor_node_is_exists (q))
1409 btor_hashptr_table_remove (param->btor->exists_vars, param, 0, 0);
1410 else if (btor_node_is_forall (q))
1411 btor_hashptr_table_remove (param->btor->forall_vars, param, 0, 0);
1412 }
1413 }
1414 /* param is bound, add to exists/forall vars tables */
1415 else
1416 {
1417 if (btor_node_is_exists (binder))
1418 (void) btor_hashptr_table_add (param->btor->exists_vars, param);
1419 else if (btor_node_is_forall (binder))
1420 (void) btor_hashptr_table_add (param->btor->forall_vars, param);
1421 }
1422 ((BtorParamNode *) btor_node_real_addr (param))->binder = binder;
1423 }
1424
1425 bool
btor_node_param_is_bound(BtorNode * param)1426 btor_node_param_is_bound (BtorNode *param)
1427 {
1428 assert (btor_node_is_param (param));
1429 return btor_node_param_get_binder (param) != 0;
1430 }
1431
1432 bool
btor_node_param_is_exists_var(BtorNode * param)1433 btor_node_param_is_exists_var (BtorNode *param)
1434 {
1435 assert (btor_node_is_param (param));
1436 return btor_node_is_exists (btor_node_param_get_binder (param));
1437 }
1438
1439 bool
btor_node_param_is_forall_var(BtorNode * param)1440 btor_node_param_is_forall_var (BtorNode *param)
1441 {
1442 assert (btor_node_is_param (param));
1443 return btor_node_is_forall (btor_node_param_get_binder (param));
1444 }
1445
1446 BtorNode *
btor_node_param_get_assigned_exp(BtorNode * param)1447 btor_node_param_get_assigned_exp (BtorNode *param)
1448 {
1449 assert (btor_node_is_param (param));
1450 return ((BtorParamNode *) btor_node_real_addr (param))->assigned_exp;
1451 }
1452
1453 BtorNode *
btor_node_param_set_assigned_exp(BtorNode * param,BtorNode * exp)1454 btor_node_param_set_assigned_exp (BtorNode *param, BtorNode *exp)
1455 {
1456 assert (btor_node_is_param (param));
1457 assert (!exp || btor_node_get_sort_id (param) == btor_node_get_sort_id (exp));
1458 return ((BtorParamNode *) btor_node_real_addr (param))->assigned_exp = exp;
1459 }
1460
1461 /*------------------------------------------------------------------------*/
1462
1463 static bool
is_sorted_bv_exp(Btor * btor,BtorNodeKind kind,BtorNode * e[])1464 is_sorted_bv_exp (Btor *btor, BtorNodeKind kind, BtorNode *e[])
1465 {
1466 if (!btor_opt_get (btor, BTOR_OPT_SORT_EXP)) return 1;
1467 if (!btor_node_is_binary_commutative_kind (kind)) return 1;
1468 if (e[0] == e[1]) return 1;
1469 if (btor_node_invert (e[0]) == e[1] && btor_node_is_inverted (e[1])) return 1;
1470 return btor_node_real_addr (e[0])->id <= btor_node_real_addr (e[1])->id;
1471 }
1472
1473 static void
sort_bv_exp(Btor * btor,BtorNodeKind kind,BtorNode * e[])1474 sort_bv_exp (Btor *btor, BtorNodeKind kind, BtorNode *e[])
1475 {
1476 if (!is_sorted_bv_exp (btor, kind, e)) BTOR_SWAP (BtorNode *, e[0], e[1]);
1477 }
1478
1479 /*------------------------------------------------------------------------*/
1480
1481 /* Search for constant expression in hash table. Returns 0 if not found. */
1482 static BtorNode **
find_const_exp(Btor * btor,BtorBitVector * bits)1483 find_const_exp (Btor *btor, BtorBitVector *bits)
1484 {
1485 assert (btor);
1486 assert (bits);
1487
1488 BtorNode *cur, **result;
1489 uint32_t hash;
1490
1491 hash = btor_bv_hash (bits);
1492 hash &= btor->nodes_unique_table.size - 1;
1493 result = btor->nodes_unique_table.chains + hash;
1494 cur = *result;
1495 while (cur)
1496 {
1497 assert (btor_node_is_regular (cur));
1498 if (btor_node_is_bv_const (cur)
1499 && btor_node_bv_get_width (btor, cur) == btor_bv_get_width (bits)
1500 && !btor_bv_compare (btor_node_bv_const_get_bits (cur), bits))
1501 break;
1502 else
1503 {
1504 result = &cur->next;
1505 cur = *result;
1506 }
1507 }
1508 return result;
1509 }
1510
1511 /* Search for slice expression in hash table. Returns 0 if not found. */
1512 static BtorNode **
find_slice_exp(Btor * btor,BtorNode * e0,uint32_t upper,uint32_t lower)1513 find_slice_exp (Btor *btor, BtorNode *e0, uint32_t upper, uint32_t lower)
1514 {
1515 assert (btor);
1516 assert (e0);
1517 assert (upper >= lower);
1518
1519 BtorNode *cur, **result;
1520 uint32_t hash;
1521
1522 hash = hash_slice_exp (e0, upper, lower);
1523 hash &= btor->nodes_unique_table.size - 1;
1524 result = btor->nodes_unique_table.chains + hash;
1525 cur = *result;
1526 while (cur)
1527 {
1528 assert (btor_node_is_regular (cur));
1529 if (cur->kind == BTOR_BV_SLICE_NODE && cur->e[0] == e0
1530 && btor_node_bv_slice_get_upper (cur) == upper
1531 && btor_node_bv_slice_get_lower (cur) == lower)
1532 break;
1533 else
1534 {
1535 result = &cur->next;
1536 cur = *result;
1537 }
1538 }
1539 return result;
1540 }
1541
1542 static BtorNode **
find_bv_exp(Btor * btor,BtorNodeKind kind,BtorNode * e[],uint32_t arity)1543 find_bv_exp (Btor *btor, BtorNodeKind kind, BtorNode *e[], uint32_t arity)
1544 {
1545 bool equal;
1546 uint32_t i;
1547 uint32_t hash;
1548 BtorNode *cur, **result;
1549
1550 assert (kind != BTOR_BV_SLICE_NODE);
1551 assert (kind != BTOR_BV_CONST_NODE);
1552
1553 sort_bv_exp (btor, kind, e);
1554 hash = hash_bv_exp (btor, kind, arity, e);
1555 hash &= btor->nodes_unique_table.size - 1;
1556
1557 result = btor->nodes_unique_table.chains + hash;
1558 cur = *result;
1559 while (cur)
1560 {
1561 assert (btor_node_is_regular (cur));
1562 if (cur->kind == kind && cur->arity == arity)
1563 {
1564 equal = true;
1565 /* special case for bv eq; (= (bvnot a) b) == (= a (bvnot b)) */
1566 if (kind == BTOR_BV_EQ_NODE && cur->e[0] == btor_node_invert (e[0])
1567 && cur->e[1] == btor_node_invert (e[1]))
1568 break;
1569 for (i = 0; i < arity && equal; i++)
1570 if (cur->e[i] != e[i]) equal = false;
1571 if (equal) break;
1572 #ifndef NDEBUG
1573 if (btor_opt_get (btor, BTOR_OPT_SORT_EXP) > 0
1574 && btor_node_is_binary_commutative_kind (kind))
1575 assert (arity == 2),
1576 assert (e[0] == e[1] || btor_node_invert (e[0]) == e[1]
1577 || !(cur->e[0] == e[1] && cur->e[1] == e[0]));
1578 #endif
1579 }
1580 result = &(cur->next);
1581 cur = *result;
1582 }
1583 return result;
1584 }
1585
1586 static int32_t compare_binder_exp (Btor *btor,
1587 BtorNode *param,
1588 BtorNode *body,
1589 BtorNode *binder,
1590 BtorPtrHashTable *map);
1591
1592 static BtorNode **
find_binder_exp(Btor * btor,BtorNodeKind kind,BtorNode * param,BtorNode * body,uint32_t * binder_hash,BtorIntHashTable * params,BtorPtrHashTable * map)1593 find_binder_exp (Btor *btor,
1594 BtorNodeKind kind,
1595 BtorNode *param,
1596 BtorNode *body,
1597 uint32_t *binder_hash,
1598 BtorIntHashTable *params,
1599 BtorPtrHashTable *map)
1600 {
1601 assert (btor);
1602 assert (param);
1603 assert (body);
1604 assert (btor_node_is_regular (param));
1605 assert (btor_node_is_param (param));
1606
1607 BtorNode *cur, **result;
1608 uint32_t hash;
1609
1610 hash = hash_binder_exp (btor, param, body, params);
1611
1612 BTORLOG (2,
1613 "find binder %s %s (hash: %u)",
1614 btor_util_node2string (param),
1615 btor_util_node2string (body),
1616 hash);
1617
1618 if (binder_hash) *binder_hash = hash;
1619 hash &= btor->nodes_unique_table.size - 1;
1620 result = btor->nodes_unique_table.chains + hash;
1621 cur = *result;
1622 while (cur)
1623 {
1624 assert (btor_node_is_regular (cur));
1625 if (cur->kind == kind
1626 && ((!map && param == cur->e[0] && body == cur->e[1])
1627 || (((map || !cur->parameterized)
1628 && compare_binder_exp (btor, param, body, cur, map)))))
1629 break;
1630 else
1631 {
1632 result = &cur->next;
1633 cur = *result;
1634 }
1635 }
1636 assert (!*result || btor_node_is_binder (*result));
1637 BTORLOG (2,
1638 "found binder %s %s -> %s",
1639 btor_util_node2string (param),
1640 btor_util_node2string (body),
1641 btor_util_node2string (*result));
1642 return result;
1643 }
1644
1645 static int32_t
compare_binder_exp(Btor * btor,BtorNode * param,BtorNode * body,BtorNode * binder,BtorPtrHashTable * map)1646 compare_binder_exp (Btor *btor,
1647 BtorNode *param,
1648 BtorNode *body,
1649 BtorNode *binder,
1650 BtorPtrHashTable *map)
1651 {
1652 assert (btor);
1653 assert (param);
1654 assert (body);
1655 assert (btor_node_is_regular (param));
1656 assert (btor_node_is_param (param));
1657 assert (btor_node_is_regular (binder));
1658 assert (btor_node_is_binder (binder));
1659 assert (!binder->parameterized || map);
1660
1661 int32_t i, equal = 0;
1662 BtorMemMgr *mm;
1663 BtorNode *cur, *real_cur, *result, *subst_param, **e, *b0, *b1;
1664 BtorPtrHashTable *cache, *param_map;
1665 BtorPtrHashBucket *b, *bb;
1666 BtorNodePtrStack stack, args;
1667 BtorNodeIterator it, iit;
1668 BtorPtrHashTableIterator h_it;
1669
1670 mm = btor->mm;
1671 subst_param = binder->e[0];
1672
1673 if (btor_node_get_sort_id (subst_param) != btor_node_get_sort_id (param)
1674 || btor_node_get_sort_id (body) != btor_node_get_sort_id (binder->e[1]))
1675 return 0;
1676
1677 cache = btor_hashptr_table_new (mm, 0, 0);
1678
1679 /* create param map */
1680 param_map = btor_hashptr_table_new (mm, 0, 0);
1681 btor_hashptr_table_add (param_map, param)->data.as_ptr = subst_param;
1682
1683 if (map)
1684 {
1685 btor_iter_hashptr_init (&h_it, map);
1686 while (btor_iter_hashptr_has_next (&h_it))
1687 {
1688 subst_param = h_it.bucket->data.as_ptr;
1689 cur = btor_iter_hashptr_next (&h_it);
1690 btor_hashptr_table_add (param_map, cur)->data.as_ptr = subst_param;
1691 }
1692 }
1693
1694 if (btor_node_is_binder (body) && btor_node_is_binder (binder->e[1])
1695 && btor_node_is_inverted (body) == btor_node_is_inverted (binder->e[1]))
1696 {
1697 btor_iter_binder_init (&it, btor_node_real_addr (body));
1698 btor_iter_binder_init (&iit, btor_node_real_addr (binder->e[1]));
1699 while (btor_iter_binder_has_next (&it))
1700 {
1701 if (!btor_iter_binder_has_next (&iit)) goto NOT_EQUAL;
1702
1703 b0 = btor_iter_binder_next (&it);
1704 b1 = btor_iter_binder_next (&iit);
1705
1706 if (btor_node_get_sort_id (b0) != btor_node_get_sort_id (b1)
1707 || b0->kind != b1->kind)
1708 goto NOT_EQUAL;
1709
1710 param = b0->e[0];
1711 subst_param = b1->e[0];
1712 assert (btor_node_is_regular (param));
1713 assert (btor_node_is_regular (subst_param));
1714 assert (btor_node_is_param (param));
1715 assert (btor_node_is_param (subst_param));
1716
1717 if (btor_node_get_sort_id (param) != btor_node_get_sort_id (subst_param))
1718 goto NOT_EQUAL;
1719
1720 btor_hashptr_table_add (param_map, param)->data.as_ptr = subst_param;
1721 }
1722 body = btor_node_binder_get_body (btor_node_real_addr (body));
1723 }
1724 else if (btor_node_is_binder (body) || btor_node_is_binder (binder->e[1]))
1725 goto NOT_EQUAL;
1726
1727 BTOR_INIT_STACK (mm, args);
1728 BTOR_INIT_STACK (mm, stack);
1729 BTOR_PUSH_STACK (stack, body);
1730 while (!BTOR_EMPTY_STACK (stack))
1731 {
1732 cur = BTOR_POP_STACK (stack);
1733 real_cur = btor_node_real_addr (cur);
1734
1735 if (!real_cur->parameterized)
1736 {
1737 BTOR_PUSH_STACK (args, cur);
1738 continue;
1739 }
1740
1741 b = btor_hashptr_table_get (cache, real_cur);
1742
1743 if (!b)
1744 {
1745 b = btor_hashptr_table_add (cache, real_cur);
1746
1747 if (btor_node_is_binder (real_cur))
1748 {
1749 result = *find_binder_exp (btor,
1750 real_cur->kind,
1751 real_cur->e[0],
1752 real_cur->e[1],
1753 0,
1754 0,
1755 param_map);
1756 if (result)
1757 {
1758 b->data.as_ptr = result;
1759 BTOR_PUSH_STACK (args, btor_node_cond_invert (cur, result));
1760 continue;
1761 }
1762 else
1763 {
1764 BTOR_RESET_STACK (args);
1765 break;
1766 }
1767 }
1768
1769 BTOR_PUSH_STACK (stack, cur);
1770 for (i = real_cur->arity - 1; i >= 0; i--)
1771 BTOR_PUSH_STACK (stack, real_cur->e[i]);
1772 }
1773 else if (!b->data.as_ptr)
1774 {
1775 assert (!btor_node_is_binder (real_cur));
1776 assert (BTOR_COUNT_STACK (args) >= real_cur->arity);
1777 args.top -= real_cur->arity;
1778 e = args.top;
1779
1780 if (btor_node_is_bv_slice (real_cur))
1781 {
1782 result = *find_slice_exp (btor,
1783 e[0],
1784 btor_node_bv_slice_get_upper (real_cur),
1785 btor_node_bv_slice_get_lower (real_cur));
1786 }
1787 else if (btor_node_is_param (real_cur))
1788 {
1789 if ((bb = btor_hashptr_table_get (param_map, real_cur)))
1790 result = bb->data.as_ptr;
1791 else
1792 result = real_cur;
1793 }
1794 else
1795 {
1796 assert (!btor_node_is_binder (real_cur));
1797 result = *find_bv_exp (btor, real_cur->kind, e, real_cur->arity);
1798 }
1799
1800 if (!result)
1801 {
1802 BTOR_RESET_STACK (args);
1803 break;
1804 }
1805
1806 BTOR_PUSH_STACK (args, btor_node_cond_invert (cur, result));
1807 b->data.as_ptr = result;
1808 }
1809 else
1810 {
1811 assert (b->data.as_ptr);
1812 BTOR_PUSH_STACK (args, btor_node_cond_invert (cur, b->data.as_ptr));
1813 }
1814 }
1815 assert (BTOR_COUNT_STACK (args) <= 1);
1816
1817 if (!BTOR_EMPTY_STACK (args))
1818 equal = BTOR_TOP_STACK (args) == btor_node_binder_get_body (binder);
1819
1820 BTOR_RELEASE_STACK (stack);
1821 BTOR_RELEASE_STACK (args);
1822 NOT_EQUAL:
1823 btor_hashptr_table_delete (cache);
1824 btor_hashptr_table_delete (param_map);
1825 return equal;
1826 }
1827
1828 static BtorNode **
find_exp(Btor * btor,BtorNodeKind kind,BtorNode * e[],uint32_t arity,uint32_t * binder_hash,BtorIntHashTable * params)1829 find_exp (Btor *btor,
1830 BtorNodeKind kind,
1831 BtorNode *e[],
1832 uint32_t arity,
1833 uint32_t *binder_hash,
1834 BtorIntHashTable *params)
1835 {
1836 assert (btor);
1837 assert (arity > 0);
1838 assert (e);
1839
1840 #ifndef NDEBUG
1841 uint32_t i;
1842 for (i = 0; i < arity; i++) assert (e[i]);
1843 #endif
1844
1845 if (kind == BTOR_LAMBDA_NODE || kind == BTOR_FORALL_NODE
1846 || kind == BTOR_EXISTS_NODE)
1847 return find_binder_exp (btor, kind, e[0], e[1], binder_hash, params, 0);
1848 else if (binder_hash)
1849 *binder_hash = 0;
1850
1851 return find_bv_exp (btor, kind, e, arity);
1852 }
1853
1854 /*------------------------------------------------------------------------*/
1855
1856 static BtorNode *
new_const_exp_node(Btor * btor,BtorBitVector * bits)1857 new_const_exp_node (Btor *btor, BtorBitVector *bits)
1858 {
1859 assert (btor);
1860 assert (bits);
1861
1862 BtorBVConstNode *exp;
1863
1864 BTOR_CNEW (btor->mm, exp);
1865 set_kind (btor, (BtorNode *) exp, BTOR_BV_CONST_NODE);
1866 exp->bytes = sizeof *exp;
1867 btor_node_set_sort_id ((BtorNode *) exp,
1868 btor_sort_bv (btor, btor_bv_get_width (bits)));
1869 setup_node_and_add_to_id_table (btor, exp);
1870 btor_node_bv_const_set_bits ((BtorNode *) exp, btor_bv_copy (btor->mm, bits));
1871 btor_node_bv_const_set_invbits ((BtorNode *) exp,
1872 btor_bv_not (btor->mm, bits));
1873 return (BtorNode *) exp;
1874 }
1875
1876 static BtorNode *
new_slice_exp_node(Btor * btor,BtorNode * e0,uint32_t upper,uint32_t lower)1877 new_slice_exp_node (Btor *btor, BtorNode *e0, uint32_t upper, uint32_t lower)
1878 {
1879 assert (btor);
1880 assert (e0);
1881 assert (btor == btor_node_real_addr (e0)->btor);
1882 assert (upper < btor_node_bv_get_width (btor, e0));
1883 assert (upper >= lower);
1884
1885 BtorBVSliceNode *exp = 0;
1886
1887 BTOR_CNEW (btor->mm, exp);
1888 set_kind (btor, (BtorNode *) exp, BTOR_BV_SLICE_NODE);
1889 exp->bytes = sizeof *exp;
1890 exp->arity = 1;
1891 exp->upper = upper;
1892 exp->lower = lower;
1893 btor_node_set_sort_id ((BtorNode *) exp,
1894 btor_sort_bv (btor, upper - lower + 1));
1895 setup_node_and_add_to_id_table (btor, exp);
1896 connect_child_exp (btor, (BtorNode *) exp, e0, 0);
1897 return (BtorNode *) exp;
1898 }
1899
1900 static BtorNode *
new_lambda_exp_node(Btor * btor,BtorNode * e_param,BtorNode * e_exp)1901 new_lambda_exp_node (Btor *btor, BtorNode *e_param, BtorNode *e_exp)
1902 {
1903 assert (btor);
1904 assert (e_param);
1905 assert (btor_node_is_regular (e_param));
1906 assert (btor_node_is_param (e_param));
1907 assert (!btor_node_param_is_bound (e_param));
1908 assert (e_exp);
1909 assert (btor == e_param->btor);
1910 assert (btor == btor_node_real_addr (e_exp)->btor);
1911
1912 BtorSortId s, domain, codomain;
1913 BtorSortIdStack param_sorts;
1914 BtorLambdaNode *lambda_exp;
1915 BtorTupleSortIterator it;
1916 BtorPtrHashBucket *b;
1917 BtorIntHashTable *params;
1918
1919 BTOR_INIT_STACK (btor->mm, param_sorts);
1920
1921 BTOR_CNEW (btor->mm, lambda_exp);
1922 set_kind (btor, (BtorNode *) lambda_exp, BTOR_LAMBDA_NODE);
1923 lambda_exp->bytes = sizeof *lambda_exp;
1924 lambda_exp->arity = 2;
1925 lambda_exp->lambda_below = 1;
1926 setup_node_and_add_to_id_table (btor, (BtorNode *) lambda_exp);
1927 connect_child_exp (btor, (BtorNode *) lambda_exp, e_param, 0);
1928 connect_child_exp (btor, (BtorNode *) lambda_exp, e_exp, 1);
1929
1930 BTOR_PUSH_STACK (param_sorts, btor_node_get_sort_id (e_param));
1931 /* curried lambdas (functions) */
1932 if (btor_node_is_lambda (e_exp))
1933 {
1934 btor_node_binder_set_body (
1935 (BtorNode *) lambda_exp,
1936 btor_simplify_exp (btor, btor_node_binder_get_body (e_exp)));
1937 btor_iter_tuple_sort_init (
1938 &it,
1939 btor,
1940 btor_sort_fun_get_domain (btor, btor_node_get_sort_id (e_exp)));
1941 while (btor_iter_tuple_sort_has_next (&it))
1942 {
1943 s = btor_iter_tuple_sort_next (&it);
1944 BTOR_PUSH_STACK (param_sorts, s);
1945 }
1946
1947 if ((b = btor_hashptr_table_get (btor->parameterized, e_exp)))
1948 {
1949 params = b->data.as_ptr;
1950 btor_hashint_table_remove (params, e_param->id);
1951 btor_hashptr_table_remove (btor->parameterized, e_exp, 0, 0);
1952 if (params->count > 0)
1953 {
1954 btor_hashptr_table_add (btor->parameterized, lambda_exp)->data.as_ptr =
1955 params;
1956 lambda_exp->parameterized = 1;
1957 }
1958 else
1959 btor_hashint_table_delete (params);
1960 }
1961 }
1962 else
1963 btor_node_binder_set_body ((BtorNode *) lambda_exp, e_exp);
1964
1965 domain =
1966 btor_sort_tuple (btor, param_sorts.start, BTOR_COUNT_STACK (param_sorts));
1967 codomain = btor_node_get_sort_id (lambda_exp->body);
1968 btor_node_set_sort_id ((BtorNode *) lambda_exp,
1969 btor_sort_fun (btor, domain, codomain));
1970
1971 btor_sort_release (btor, domain);
1972 BTOR_RELEASE_STACK (param_sorts);
1973
1974 assert (!btor_node_real_addr (lambda_exp->body)->simplified);
1975 assert (!btor_node_is_lambda (lambda_exp->body));
1976 assert (!btor_hashptr_table_get (btor->lambdas, lambda_exp));
1977 (void) btor_hashptr_table_add (btor->lambdas, lambda_exp);
1978 /* set lambda expression of parameter */
1979 btor_node_param_set_binder (e_param, (BtorNode *) lambda_exp);
1980 return (BtorNode *) lambda_exp;
1981 }
1982
1983 static BtorNode *
new_quantifier_exp_node(Btor * btor,BtorNodeKind kind,BtorNode * param,BtorNode * body)1984 new_quantifier_exp_node (Btor *btor,
1985 BtorNodeKind kind,
1986 BtorNode *param,
1987 BtorNode *body)
1988 {
1989 assert (btor);
1990 assert (param);
1991 assert (body);
1992 assert (kind == BTOR_FORALL_NODE || kind == BTOR_EXISTS_NODE);
1993 assert (btor_node_is_regular (param));
1994 assert (btor_node_is_param (param));
1995 assert (!btor_node_param_is_bound (param));
1996 assert (btor_sort_is_bool (btor, btor_node_real_addr (body)->sort_id));
1997 assert (btor == param->btor);
1998 assert (btor == btor_node_real_addr (body)->btor);
1999
2000 BtorBinderNode *res;
2001
2002 BTOR_CNEW (btor->mm, res);
2003 set_kind (btor, (BtorNode *) res, kind);
2004 res->bytes = sizeof *res;
2005 res->arity = 2;
2006 res->quantifier_below = 1;
2007 res->sort_id = btor_sort_copy (btor, btor_node_real_addr (body)->sort_id);
2008 setup_node_and_add_to_id_table (btor, (BtorNode *) res);
2009 connect_child_exp (btor, (BtorNode *) res, param, 0);
2010 connect_child_exp (btor, (BtorNode *) res, body, 1);
2011
2012 /* curried (non-inverted) quantifiers */
2013 if (!btor_node_is_inverted (body) && btor_node_is_quantifier (body))
2014 res->body = btor_simplify_exp (btor, btor_node_binder_get_body (body));
2015 else
2016 res->body = body;
2017
2018 #if 0
2019 /* check if 'res' is parameterized, i.e. if it contains params that are not
2020 * bound by 'res' */
2021 remove_param_parameterized (btor, (BtorNode *) res, param);
2022 if (is_parameterized (btor, (BtorNode *) res))
2023 res->parameterized = 1;
2024 #endif
2025
2026 assert (!btor_node_real_addr (res->body)->simplified);
2027 assert (!btor_node_is_lambda (res->body));
2028 btor_node_param_set_binder (param, (BtorNode *) res);
2029 assert (!btor_hashptr_table_get (btor->quantifiers, res));
2030 (void) btor_hashptr_table_add (btor->quantifiers, res);
2031 return (BtorNode *) res;
2032 }
2033
2034 static BtorNode *
new_args_exp_node(Btor * btor,uint32_t arity,BtorNode * e[])2035 new_args_exp_node (Btor *btor, uint32_t arity, BtorNode *e[])
2036 {
2037 assert (btor);
2038 assert (arity > 0);
2039 assert (arity <= 3);
2040 assert (e);
2041
2042 uint32_t i;
2043 BtorArgsNode *exp;
2044 BtorSortIdStack sorts;
2045 BtorTupleSortIterator it;
2046 #ifndef NDEBUG
2047 for (i = 0; i < arity; i++) assert (e[i]);
2048 #endif
2049
2050 BTOR_CNEW (btor->mm, exp);
2051 set_kind (btor, (BtorNode *) exp, BTOR_ARGS_NODE);
2052 exp->bytes = sizeof (*exp);
2053 exp->arity = arity;
2054 setup_node_and_add_to_id_table (btor, exp);
2055
2056 for (i = 0; i < arity; i++)
2057 connect_child_exp (btor, (BtorNode *) exp, e[i], i);
2058
2059 /* create tuple sort for argument node */
2060 BTOR_INIT_STACK (btor->mm, sorts);
2061 for (i = 0; i < arity; i++)
2062 {
2063 if (btor_node_is_args (e[i]))
2064 {
2065 assert (i == 2);
2066 assert (btor_node_is_regular (e[i]));
2067 btor_iter_tuple_sort_init (&it, btor, btor_node_get_sort_id (e[i]));
2068 while (btor_iter_tuple_sort_has_next (&it))
2069 BTOR_PUSH_STACK (sorts, btor_iter_tuple_sort_next (&it));
2070 }
2071 else
2072 BTOR_PUSH_STACK (sorts, btor_node_get_sort_id (e[i]));
2073 }
2074 btor_node_set_sort_id (
2075 (BtorNode *) exp,
2076 btor_sort_tuple (btor, sorts.start, BTOR_COUNT_STACK (sorts)));
2077 BTOR_RELEASE_STACK (sorts);
2078 return (BtorNode *) exp;
2079 }
2080
2081 static BtorNode *
new_node(Btor * btor,BtorNodeKind kind,uint32_t arity,BtorNode * e[])2082 new_node (Btor *btor, BtorNodeKind kind, uint32_t arity, BtorNode *e[])
2083 {
2084 assert (btor);
2085 assert (arity > 0);
2086 assert (arity <= 3);
2087 assert (btor_node_is_binary_kind (kind) || btor_node_is_ternary_kind (kind));
2088 assert (e);
2089
2090 #ifndef NDEBUG
2091 if (btor_opt_get (btor, BTOR_OPT_SORT_EXP) > 0
2092 && btor_node_is_binary_commutative_kind (kind))
2093 assert (arity == 2), assert (btor_node_real_addr (e[0])->id
2094 <= btor_node_real_addr (e[1])->id);
2095 #endif
2096
2097 uint32_t i;
2098 BtorBVNode *exp;
2099 BtorSortId sort;
2100
2101 #ifdef NDEBUG
2102 for (i = 0; i < arity; i++)
2103 {
2104 assert (e[i]);
2105 assert (btor == btor_node_real_addr (e[i])->btor);
2106 }
2107 #endif
2108
2109 BTOR_CNEW (btor->mm, exp);
2110 set_kind (btor, (BtorNode *) exp, kind);
2111 exp->bytes = sizeof (*exp);
2112 exp->arity = arity;
2113 setup_node_and_add_to_id_table (btor, exp);
2114
2115 switch (kind)
2116 {
2117 case BTOR_COND_NODE:
2118 sort = btor_sort_copy (btor, btor_node_get_sort_id (e[1]));
2119 break;
2120
2121 case BTOR_BV_CONCAT_NODE:
2122 sort = btor_sort_bv (btor,
2123 btor_node_bv_get_width (btor, e[0])
2124 + btor_node_bv_get_width (btor, e[1]));
2125 break;
2126
2127 case BTOR_FUN_EQ_NODE:
2128 case BTOR_BV_EQ_NODE:
2129 case BTOR_BV_ULT_NODE: sort = btor_sort_bool (btor); break;
2130
2131 case BTOR_APPLY_NODE:
2132 sort = btor_sort_copy (
2133 btor,
2134 btor_sort_fun_get_codomain (btor, btor_node_get_sort_id (e[0])));
2135 break;
2136
2137 default:
2138 assert (kind == BTOR_BV_AND_NODE || kind == BTOR_BV_ADD_NODE
2139 || kind == BTOR_BV_MUL_NODE || kind == BTOR_BV_SLL_NODE
2140 || kind == BTOR_BV_SRL_NODE || kind == BTOR_BV_UDIV_NODE
2141 || kind == BTOR_BV_UREM_NODE || kind == BTOR_UPDATE_NODE);
2142 sort = btor_sort_copy (btor, btor_node_get_sort_id (e[0]));
2143 }
2144
2145 btor_node_set_sort_id ((BtorNode *) exp, sort);
2146
2147 for (i = 0; i < arity; i++)
2148 connect_child_exp (btor, (BtorNode *) exp, e[i], i);
2149
2150 if (kind == BTOR_FUN_EQ_NODE)
2151 {
2152 assert (!btor_hashptr_table_get (btor->feqs, exp));
2153 btor_hashptr_table_add (btor->feqs, exp)->data.as_int = 0;
2154 }
2155
2156 return (BtorNode *) exp;
2157 }
2158
2159 /*------------------------------------------------------------------------*/
2160
2161 static BtorNode *
create_exp(Btor * btor,BtorNodeKind kind,uint32_t arity,BtorNode * e[])2162 create_exp (Btor *btor, BtorNodeKind kind, uint32_t arity, BtorNode *e[])
2163 {
2164 assert (btor);
2165 assert (kind);
2166 assert (arity > 0);
2167 assert (arity <= 3);
2168 assert (e);
2169
2170 uint32_t i;
2171 uint32_t binder_hash;
2172 BtorNode **lookup, *simp_e[3], *simp;
2173 BtorIntHashTable *params = 0;
2174
2175 for (i = 0; i < arity; i++)
2176 {
2177 assert (btor_node_real_addr (e[i])->btor == btor);
2178 simp_e[i] = btor_simplify_exp (btor, e[i]);
2179 }
2180
2181 /* collect params only for quantifier/function bodies */
2182 if ((kind == BTOR_LAMBDA_NODE && !btor_node_is_lambda (e[1]))
2183 || kind == BTOR_FORALL_NODE || kind == BTOR_EXISTS_NODE)
2184 params = btor_hashint_table_new (btor->mm);
2185
2186 lookup = find_exp (btor, kind, simp_e, arity, &binder_hash, params);
2187 if (!*lookup)
2188 {
2189 if (BTOR_FULL_UNIQUE_TABLE (btor->nodes_unique_table))
2190 {
2191 enlarge_nodes_unique_table (btor);
2192 lookup = find_exp (btor, kind, simp_e, arity, &binder_hash, 0);
2193 }
2194
2195 switch (kind)
2196 {
2197 case BTOR_LAMBDA_NODE:
2198 assert (arity == 2);
2199 *lookup = new_lambda_exp_node (btor, simp_e[0], simp_e[1]);
2200 btor_hashptr_table_get (btor->lambdas, *lookup)->data.as_int =
2201 binder_hash;
2202 BTORLOG (2,
2203 "new lambda: %s (hash: %u, param: %u)",
2204 btor_util_node2string (*lookup),
2205 binder_hash,
2206 (*lookup)->parameterized);
2207 break;
2208 case BTOR_FORALL_NODE:
2209 case BTOR_EXISTS_NODE:
2210 assert (arity == 2);
2211 *lookup = new_quantifier_exp_node (btor, kind, e[0], e[1]);
2212 btor_hashptr_table_get (btor->quantifiers, *lookup)->data.as_int =
2213 binder_hash;
2214 break;
2215 case BTOR_ARGS_NODE:
2216 *lookup = new_args_exp_node (btor, arity, simp_e);
2217 break;
2218 default: *lookup = new_node (btor, kind, arity, simp_e);
2219 }
2220
2221 if (params)
2222 {
2223 assert (btor_node_is_binder (*lookup));
2224 if (params->count > 0)
2225 {
2226 btor_hashptr_table_add (btor->parameterized, *lookup)->data.as_ptr =
2227 params;
2228 (*lookup)->parameterized = 1;
2229 }
2230 else
2231 btor_hashint_table_delete (params);
2232 }
2233
2234 assert (btor->nodes_unique_table.num_elements < INT32_MAX);
2235 btor->nodes_unique_table.num_elements++;
2236 (*lookup)->unique = 1;
2237 }
2238 else
2239 {
2240 inc_exp_ref_counter (btor, *lookup);
2241 if (params) btor_hashint_table_delete (params);
2242 }
2243 assert (btor_node_is_regular (*lookup));
2244 if (btor_node_is_simplified (*lookup))
2245 {
2246 assert (btor_opt_get (btor, BTOR_OPT_NONDESTR_SUBST));
2247 simp = btor_node_copy (btor, btor_node_get_simplified (btor, *lookup));
2248 btor_node_release (btor, *lookup);
2249 return simp;
2250 }
2251 return *lookup;
2252 }
2253
2254 /*------------------------------------------------------------------------*/
2255
2256 BtorNode *
btor_node_create_bv_const(Btor * btor,const BtorBitVector * bits)2257 btor_node_create_bv_const (Btor *btor, const BtorBitVector *bits)
2258 {
2259 assert (btor);
2260 assert (bits);
2261
2262 bool inv;
2263 BtorBitVector *lookupbits;
2264 BtorNode **lookup;
2265
2266 /* normalize constants, constants are always even */
2267 if (btor_bv_get_bit (bits, 0))
2268 {
2269 lookupbits = btor_bv_not (btor->mm, bits);
2270 inv = true;
2271 }
2272 else
2273 {
2274 lookupbits = btor_bv_copy (btor->mm, bits);
2275 inv = false;
2276 }
2277
2278 lookup = find_const_exp (btor, lookupbits);
2279 if (!*lookup)
2280 {
2281 if (BTOR_FULL_UNIQUE_TABLE (btor->nodes_unique_table))
2282 {
2283 enlarge_nodes_unique_table (btor);
2284 lookup = find_const_exp (btor, lookupbits);
2285 }
2286 *lookup = new_const_exp_node (btor, lookupbits);
2287 assert (btor->nodes_unique_table.num_elements < INT32_MAX);
2288 btor->nodes_unique_table.num_elements += 1;
2289 (*lookup)->unique = 1;
2290 }
2291 else
2292 inc_exp_ref_counter (btor, *lookup);
2293
2294 assert (btor_node_is_regular (*lookup));
2295
2296 btor_bv_free (btor->mm, lookupbits);
2297
2298 if (inv) return btor_node_invert (*lookup);
2299 return *lookup;
2300 }
2301
2302 BtorNode *
btor_node_create_var(Btor * btor,BtorSortId sort,const char * symbol)2303 btor_node_create_var (Btor *btor, BtorSortId sort, const char *symbol)
2304 {
2305 assert (btor);
2306 assert (sort);
2307 assert (btor_sort_is_bv (btor, sort));
2308 assert (!symbol || !btor_hashptr_table_get (btor->symbols, (char *) symbol));
2309
2310 BtorBVVarNode *exp;
2311
2312 BTOR_CNEW (btor->mm, exp);
2313 set_kind (btor, (BtorNode *) exp, BTOR_VAR_NODE);
2314 exp->bytes = sizeof *exp;
2315 setup_node_and_add_to_id_table (btor, exp);
2316 btor_node_set_sort_id ((BtorNode *) exp, btor_sort_copy (btor, sort));
2317 (void) btor_hashptr_table_add (btor->bv_vars, exp);
2318 if (symbol) btor_node_set_symbol (btor, (BtorNode *) exp, symbol);
2319 return (BtorNode *) exp;
2320 }
2321
2322 BtorNode *
btor_node_create_uf(Btor * btor,BtorSortId sort,const char * symbol)2323 btor_node_create_uf (Btor *btor, BtorSortId sort, const char *symbol)
2324 {
2325 assert (btor);
2326 assert (sort);
2327 assert (!symbol || !btor_hashptr_table_get (btor->symbols, (char *) symbol));
2328
2329 BtorUFNode *exp;
2330
2331 assert (btor_sort_is_fun (btor, sort));
2332 assert (btor_sort_is_bv (btor, btor_sort_fun_get_codomain (btor, sort))
2333 || btor_sort_is_bool (btor, btor_sort_fun_get_codomain (btor, sort)));
2334
2335 BTOR_CNEW (btor->mm, exp);
2336 set_kind (btor, (BtorNode *) exp, BTOR_UF_NODE);
2337 exp->bytes = sizeof (*exp);
2338 btor_node_set_sort_id ((BtorNode *) exp, btor_sort_copy (btor, sort));
2339 setup_node_and_add_to_id_table (btor, exp);
2340 (void) btor_hashptr_table_add (btor->ufs, exp);
2341 if (symbol) btor_node_set_symbol (btor, (BtorNode *) exp, symbol);
2342 return (BtorNode *) exp;
2343 }
2344
2345 BtorNode *
btor_node_create_param(Btor * btor,BtorSortId sort,const char * symbol)2346 btor_node_create_param (Btor *btor, BtorSortId sort, const char *symbol)
2347 {
2348 assert (btor);
2349 assert (sort);
2350 assert (btor_sort_is_bv (btor, sort));
2351 assert (!symbol || !btor_hashptr_table_get (btor->symbols, (char *) symbol));
2352
2353 BtorParamNode *exp;
2354
2355 BTOR_CNEW (btor->mm, exp);
2356 set_kind (btor, (BtorNode *) exp, BTOR_PARAM_NODE);
2357 exp->bytes = sizeof *exp;
2358 exp->parameterized = 1;
2359 btor_node_set_sort_id ((BtorNode *) exp, btor_sort_copy (btor, sort));
2360 setup_node_and_add_to_id_table (btor, exp);
2361 if (symbol) btor_node_set_symbol (btor, (BtorNode *) exp, symbol);
2362 return (BtorNode *) exp;
2363 }
2364
2365 static BtorNode *
unary_exp_slice_exp(Btor * btor,BtorNode * exp,uint32_t upper,uint32_t lower)2366 unary_exp_slice_exp (Btor *btor, BtorNode *exp, uint32_t upper, uint32_t lower)
2367 {
2368 assert (btor);
2369 assert (exp);
2370 assert (btor == btor_node_real_addr (exp)->btor);
2371
2372 bool inv;
2373 BtorNode **lookup;
2374
2375 exp = btor_simplify_exp (btor, exp);
2376
2377 assert (!btor_node_is_fun (exp));
2378 assert (upper >= lower);
2379 assert (upper < btor_node_bv_get_width (btor, exp));
2380
2381 if (btor_opt_get (btor, BTOR_OPT_REWRITE_LEVEL) > 0
2382 && btor_node_is_inverted (exp))
2383 {
2384 inv = true;
2385 exp = btor_node_invert (exp);
2386 }
2387 else
2388 inv = false;
2389
2390 lookup = find_slice_exp (btor, exp, upper, lower);
2391 if (!*lookup)
2392 {
2393 if (BTOR_FULL_UNIQUE_TABLE (btor->nodes_unique_table))
2394 {
2395 enlarge_nodes_unique_table (btor);
2396 lookup = find_slice_exp (btor, exp, upper, lower);
2397 }
2398 *lookup = new_slice_exp_node (btor, exp, upper, lower);
2399 assert (btor->nodes_unique_table.num_elements < INT32_MAX);
2400 btor->nodes_unique_table.num_elements++;
2401 (*lookup)->unique = 1;
2402 }
2403 else
2404 inc_exp_ref_counter (btor, *lookup);
2405 assert (btor_node_is_regular (*lookup));
2406 if (inv) return btor_node_invert (*lookup);
2407 return *lookup;
2408 }
2409
2410 BtorNode *
btor_node_create_bv_slice(Btor * btor,BtorNode * exp,uint32_t upper,uint32_t lower)2411 btor_node_create_bv_slice (Btor *btor,
2412 BtorNode *exp,
2413 uint32_t upper,
2414 uint32_t lower)
2415 {
2416 exp = btor_simplify_exp (btor, exp);
2417 assert (btor_dbg_precond_slice_exp (btor, exp, upper, lower));
2418 return unary_exp_slice_exp (btor, exp, upper, lower);
2419 }
2420
2421 BtorNode *
btor_node_create_bv_and(Btor * btor,BtorNode * e0,BtorNode * e1)2422 btor_node_create_bv_and (Btor *btor, BtorNode *e0, BtorNode *e1)
2423 {
2424 BtorNode *e[2];
2425 e[0] = btor_simplify_exp (btor, e0);
2426 e[1] = btor_simplify_exp (btor, e1);
2427 assert (btor_dbg_precond_regular_binary_bv_exp (btor, e[0], e[1]));
2428 return create_exp (btor, BTOR_BV_AND_NODE, 2, e);
2429 }
2430
2431 BtorNode *
btor_node_create_eq(Btor * btor,BtorNode * e0,BtorNode * e1)2432 btor_node_create_eq (Btor *btor, BtorNode *e0, BtorNode *e1)
2433 {
2434 BtorNode *e[2];
2435 BtorNodeKind kind;
2436
2437 e[0] = btor_simplify_exp (btor, e0);
2438 e[1] = btor_simplify_exp (btor, e1);
2439 assert (btor_dbg_precond_eq_exp (btor, e[0], e[1]));
2440 if (btor_node_is_fun (e[0]))
2441 kind = BTOR_FUN_EQ_NODE;
2442 else
2443 kind = BTOR_BV_EQ_NODE;
2444 return create_exp (btor, kind, 2, e);
2445 }
2446
2447 BtorNode *
btor_node_create_bv_add(Btor * btor,BtorNode * e0,BtorNode * e1)2448 btor_node_create_bv_add (Btor *btor, BtorNode *e0, BtorNode *e1)
2449 {
2450 BtorNode *e[2];
2451 e[0] = btor_simplify_exp (btor, e0);
2452 e[1] = btor_simplify_exp (btor, e1);
2453 assert (btor_dbg_precond_regular_binary_bv_exp (btor, e[0], e[1]));
2454 return create_exp (btor, BTOR_BV_ADD_NODE, 2, e);
2455 }
2456
2457 BtorNode *
btor_node_create_bv_mul(Btor * btor,BtorNode * e0,BtorNode * e1)2458 btor_node_create_bv_mul (Btor *btor, BtorNode *e0, BtorNode *e1)
2459 {
2460 BtorNode *e[2];
2461 e[0] = btor_simplify_exp (btor, e0);
2462 e[1] = btor_simplify_exp (btor, e1);
2463 assert (btor_dbg_precond_regular_binary_bv_exp (btor, e[0], e[1]));
2464 return create_exp (btor, BTOR_BV_MUL_NODE, 2, e);
2465 }
2466
2467 BtorNode *
btor_node_create_bv_ult(Btor * btor,BtorNode * e0,BtorNode * e1)2468 btor_node_create_bv_ult (Btor *btor, BtorNode *e0, BtorNode *e1)
2469 {
2470 BtorNode *e[2];
2471 e[0] = btor_simplify_exp (btor, e0);
2472 e[1] = btor_simplify_exp (btor, e1);
2473 assert (btor_dbg_precond_regular_binary_bv_exp (btor, e[0], e[1]));
2474 return create_exp (btor, BTOR_BV_ULT_NODE, 2, e);
2475 }
2476
2477 BtorNode *
btor_node_create_bv_sll(Btor * btor,BtorNode * e0,BtorNode * e1)2478 btor_node_create_bv_sll (Btor *btor, BtorNode *e0, BtorNode *e1)
2479 {
2480 BtorNode *e[2];
2481 e[0] = btor_simplify_exp (btor, e0);
2482 e[1] = btor_simplify_exp (btor, e1);
2483 assert (btor_dbg_precond_shift_exp (btor, e[0], e[1]));
2484 return create_exp (btor, BTOR_BV_SLL_NODE, 2, e);
2485 }
2486
2487 BtorNode *
btor_node_create_bv_srl(Btor * btor,BtorNode * e0,BtorNode * e1)2488 btor_node_create_bv_srl (Btor *btor, BtorNode *e0, BtorNode *e1)
2489 {
2490 BtorNode *e[2];
2491 e[0] = btor_simplify_exp (btor, e0);
2492 e[1] = btor_simplify_exp (btor, e1);
2493 assert (btor_dbg_precond_shift_exp (btor, e[0], e[1]));
2494 return create_exp (btor, BTOR_BV_SRL_NODE, 2, e);
2495 }
2496
2497 BtorNode *
btor_node_create_bv_udiv(Btor * btor,BtorNode * e0,BtorNode * e1)2498 btor_node_create_bv_udiv (Btor *btor, BtorNode *e0, BtorNode *e1)
2499 {
2500 BtorNode *e[2];
2501 e[0] = btor_simplify_exp (btor, e0);
2502 e[1] = btor_simplify_exp (btor, e1);
2503 assert (btor_dbg_precond_regular_binary_bv_exp (btor, e[0], e[1]));
2504 return create_exp (btor, BTOR_BV_UDIV_NODE, 2, e);
2505 }
2506
2507 BtorNode *
btor_node_create_bv_urem(Btor * btor,BtorNode * e0,BtorNode * e1)2508 btor_node_create_bv_urem (Btor *btor, BtorNode *e0, BtorNode *e1)
2509 {
2510 BtorNode *e[2];
2511 e[0] = btor_simplify_exp (btor, e0);
2512 e[1] = btor_simplify_exp (btor, e1);
2513 assert (btor_dbg_precond_regular_binary_bv_exp (btor, e[0], e[1]));
2514 return create_exp (btor, BTOR_BV_UREM_NODE, 2, e);
2515 }
2516
2517 BtorNode *
btor_node_create_bv_concat(Btor * btor,BtorNode * e0,BtorNode * e1)2518 btor_node_create_bv_concat (Btor *btor, BtorNode *e0, BtorNode *e1)
2519 {
2520 BtorNode *e[2];
2521 e[0] = btor_simplify_exp (btor, e0);
2522 e[1] = btor_simplify_exp (btor, e1);
2523 assert (btor_dbg_precond_concat_exp (btor, e[0], e[1]));
2524 return create_exp (btor, BTOR_BV_CONCAT_NODE, 2, e);
2525 }
2526
2527 BtorNode *
btor_node_create_cond(Btor * btor,BtorNode * e_cond,BtorNode * e_if,BtorNode * e_else)2528 btor_node_create_cond (Btor *btor,
2529 BtorNode *e_cond,
2530 BtorNode *e_if,
2531 BtorNode *e_else)
2532 {
2533 uint32_t i, arity;
2534 BtorNode *e[3], *cond, *lambda;
2535 BtorNodePtrStack params;
2536 BtorSort *sort;
2537 e[0] = btor_simplify_exp (btor, e_cond);
2538 e[1] = btor_simplify_exp (btor, e_if);
2539 e[2] = btor_simplify_exp (btor, e_else);
2540 assert (btor_dbg_precond_cond_exp (btor, e[0], e[1], e[2]));
2541
2542 /* represent parameterized function conditionals (with parameterized
2543 * functions) as parameterized function
2544 * -> gets beta reduced in btor_node_create_apply */
2545 if (btor_node_is_fun (e[1]) && (e[1]->parameterized || e[2]->parameterized))
2546 {
2547 BTOR_INIT_STACK (btor->mm, params);
2548 assert (btor_sort_is_fun (btor, btor_node_get_sort_id (e[1])));
2549 arity = btor_node_fun_get_arity (btor, e[1]);
2550 sort = btor_sort_get_by_id (btor, btor_node_get_sort_id (e[1]));
2551 assert (sort->fun.domain->kind == BTOR_TUPLE_SORT);
2552 assert (sort->fun.domain->tuple.num_elements == arity);
2553 for (i = 0; i < arity; i++)
2554 BTOR_PUSH_STACK (
2555 params,
2556 btor_exp_param (btor, sort->fun.domain->tuple.elements[i]->id, 0));
2557 e[1] = btor_exp_apply_n (btor, e[1], params.start, arity);
2558 e[2] = btor_exp_apply_n (btor, e[2], params.start, arity);
2559 cond = create_exp (btor, BTOR_COND_NODE, 3, e);
2560 lambda = btor_exp_fun (btor, params.start, arity, cond);
2561 while (!BTOR_EMPTY_STACK (params))
2562 btor_node_release (btor, BTOR_POP_STACK (params));
2563 btor_node_release (btor, e[1]);
2564 btor_node_release (btor, e[2]);
2565 btor_node_release (btor, cond);
2566 BTOR_RELEASE_STACK (params);
2567 return lambda;
2568 }
2569 return create_exp (btor, BTOR_COND_NODE, 3, e);
2570 }
2571
2572 #if 0
2573 BtorNode *
2574 btor_bv_cond_exp_node (Btor * btor, BtorNode * e_cond, BtorNode * e_if,
2575 BtorNode * e_else)
2576 {
2577 assert (btor == btor_node_real_addr (e_cond)->btor);
2578 assert (btor == btor_node_real_addr (e_if)->btor);
2579 assert (btor == btor_node_real_addr (e_else)->btor);
2580
2581 if (btor_opt_get (btor, BTOR_OPT_REWRITE_LEVEL) > 0)
2582 return btor_rewrite_ternary_exp (btor, BTOR_BCOND_NODE, e_cond, e_if, e_else);
2583
2584 return btor_node_create_cond (btor, e_cond, e_if, e_else);
2585 }
2586
2587 // TODO: arbitrary conditionals on functions
2588 BtorNode *
2589 btor_array_cond_exp_node (Btor * btor, BtorNode * e_cond, BtorNode * e_if,
2590 BtorNode * e_else)
2591 {
2592 assert (btor == btor_node_real_addr (e_cond)->btor);
2593 assert (btor == btor_node_real_addr (e_if)->btor);
2594 assert (btor == btor_node_real_addr (e_else)->btor);
2595
2596 BtorNode *cond, *param, *lambda, *app_if, *app_else;
2597
2598 e_cond = btor_simplify_exp (btor, e_cond);
2599 e_if = btor_simplify_exp (btor, e_if);
2600 e_else = btor_simplify_exp (btor, e_else);
2601
2602 assert (btor_node_is_regular (e_if));
2603 assert (btor_node_is_fun (e_if));
2604 assert (btor_node_is_regular (e_else));
2605 assert (btor_node_is_fun (e_else));
2606
2607 param = btor_exp_param (btor, btor_node_get_sort_id (e_if), 0);
2608 app_if = btor_exp_apply_n (btor, e_if, ¶m, 1);
2609 app_else = btor_exp_apply_n (btor, e_else, ¶m, 1);
2610 cond = btor_bv_cond_exp_node (btor, e_cond, app_if, app_else);
2611 lambda = btor_exp_lambda (btor, param, cond);
2612 lambda->is_array = 1;
2613
2614 btor_node_release (btor, param);
2615 btor_node_release (btor, app_if);
2616 btor_node_release (btor, app_else);
2617 btor_node_release (btor, cond);
2618
2619 return lambda;
2620 }
2621 #endif
2622
2623 /* more than 4 children are not possible as we only have 2 bit for storing
2624 * the position in the parent pointers */
2625 #define ARGS_MAX_NUM_CHILDREN 3
2626
2627 BtorNode *
btor_node_create_args(Btor * btor,BtorNode * args[],uint32_t argc)2628 btor_node_create_args (Btor *btor, BtorNode *args[], uint32_t argc)
2629 {
2630 assert (btor);
2631 assert (argc > 0);
2632 assert (args);
2633
2634 int64_t i, cur_argc, cnt_args, rem_free, num_args;
2635 BtorNode *e[ARGS_MAX_NUM_CHILDREN];
2636 BtorNode *result = 0, *last = 0;
2637
2638 /* arguments fit in one args node */
2639 if (argc <= ARGS_MAX_NUM_CHILDREN)
2640 {
2641 num_args = 1;
2642 rem_free = ARGS_MAX_NUM_CHILDREN - argc;
2643 cur_argc = argc;
2644 }
2645 /* arguments have to be split into several args nodes.
2646 * compute number of required args nodes */
2647 else
2648 {
2649 rem_free = argc % (ARGS_MAX_NUM_CHILDREN - 1);
2650 num_args = argc / (ARGS_MAX_NUM_CHILDREN - 1);
2651 /* we can store at most 1 more element into 'num_args' nodes
2652 * without needing an additional args node */
2653 if (rem_free > 1) num_args += 1;
2654
2655 assert (num_args > 1);
2656 /* compute number of arguments in last args node */
2657 cur_argc = argc - (num_args - 1) * (ARGS_MAX_NUM_CHILDREN - 1);
2658 }
2659 cnt_args = cur_argc - 1;
2660
2661 /* split up args in 'num_args' of args nodes */
2662 for (i = argc - 1; i >= 0; i--)
2663 {
2664 assert (cnt_args >= 0);
2665 assert (cnt_args <= ARGS_MAX_NUM_CHILDREN);
2666 assert (!btor_node_is_fun (args[i]));
2667 assert (btor == btor_node_real_addr (args[i])->btor);
2668 e[cnt_args] = btor_simplify_exp (btor, args[i]);
2669 cnt_args -= 1;
2670
2671 assert (i > 0 || cnt_args < 0);
2672 if (cnt_args < 0)
2673 {
2674 result = create_exp (btor, BTOR_ARGS_NODE, cur_argc, e);
2675
2676 /* init for next iteration */
2677 cur_argc = ARGS_MAX_NUM_CHILDREN;
2678 cnt_args = cur_argc - 1;
2679 e[cnt_args] = result;
2680 cnt_args -= 1;
2681
2682 if (last) btor_node_release (btor, last);
2683
2684 last = result;
2685 }
2686 }
2687
2688 assert (result);
2689 return result;
2690 }
2691
2692 BtorNode *
btor_node_create_apply(Btor * btor,BtorNode * fun,BtorNode * args)2693 btor_node_create_apply (Btor *btor, BtorNode *fun, BtorNode *args)
2694 {
2695 assert (btor);
2696 assert (fun);
2697 assert (args);
2698 assert (btor == btor_node_real_addr (fun)->btor);
2699 assert (btor == btor_node_real_addr (args)->btor);
2700 assert (btor_dbg_precond_apply_exp (btor, fun, args));
2701
2702 BtorNode *e[2];
2703 e[0] = btor_simplify_exp (btor, fun);
2704 e[1] = btor_simplify_exp (btor, args);
2705
2706 assert (btor_node_is_regular (e[0]));
2707 assert (btor_node_is_regular (e[1]));
2708 assert (btor_node_is_fun (e[0]));
2709 assert (btor_node_is_args (e[1]));
2710
2711 /* eliminate nested functions */
2712 if (btor_node_is_lambda (e[0]) && e[0]->parameterized)
2713 {
2714 btor_beta_assign_args (btor, e[0], args);
2715 BtorNode *result = btor_beta_reduce_bounded (btor, e[0], 1);
2716 btor_beta_unassign_params (btor, e[0]);
2717 return result;
2718 }
2719 assert (!btor_node_is_fun_cond (e[0])
2720 || (!e[0]->e[1]->parameterized && !e[0]->e[2]->parameterized));
2721 return create_exp (btor, BTOR_APPLY_NODE, 2, e);
2722 }
2723
2724 BtorNode *
btor_node_create_quantifier(Btor * btor,BtorNodeKind kind,BtorNode * param,BtorNode * body)2725 btor_node_create_quantifier (Btor *btor,
2726 BtorNodeKind kind,
2727 BtorNode *param,
2728 BtorNode *body)
2729 {
2730 assert (btor);
2731 assert (kind == BTOR_FORALL_NODE || kind == BTOR_EXISTS_NODE);
2732 assert (param);
2733
2734 BtorNode *e[2];
2735 e[0] = btor_simplify_exp (btor, param);
2736 e[1] = btor_simplify_exp (btor, body);
2737
2738 assert (btor_node_is_regular (e[0]));
2739 assert (btor_node_is_param (e[0]));
2740 assert (e[1]);
2741 assert (btor_sort_is_bool (btor, btor_node_real_addr (e[1])->sort_id));
2742 return create_exp (btor, kind, 2, e);
2743 }
2744
2745 BtorNode *
btor_node_create_lambda(Btor * btor,BtorNode * e_param,BtorNode * e_exp)2746 btor_node_create_lambda (Btor *btor, BtorNode *e_param, BtorNode *e_exp)
2747 {
2748 BtorNode *e[2];
2749 e[0] = btor_simplify_exp (btor, e_param);
2750 e[1] = btor_simplify_exp (btor, e_exp);
2751 return create_exp (btor, BTOR_LAMBDA_NODE, 2, e);
2752 }
2753
2754 BtorNode *
btor_node_create_forall(Btor * btor,BtorNode * param,BtorNode * body)2755 btor_node_create_forall (Btor *btor, BtorNode *param, BtorNode *body)
2756 {
2757 return btor_node_create_quantifier (btor, BTOR_FORALL_NODE, param, body);
2758 }
2759
2760 BtorNode *
btor_node_create_exists(Btor * btor,BtorNode * param,BtorNode * body)2761 btor_node_create_exists (Btor *btor, BtorNode *param, BtorNode *body)
2762 {
2763 return btor_node_create_quantifier (btor, BTOR_EXISTS_NODE, param, body);
2764 }
2765
2766 BtorNode *
btor_node_create_update(Btor * btor,BtorNode * fun,BtorNode * args,BtorNode * value)2767 btor_node_create_update (Btor *btor,
2768 BtorNode *fun,
2769 BtorNode *args,
2770 BtorNode *value)
2771 {
2772 BtorNode *e[3], *res;
2773 e[0] = btor_simplify_exp (btor, fun);
2774 e[1] = btor_simplify_exp (btor, args);
2775 e[2] = btor_simplify_exp (btor, value);
2776 assert (btor_node_is_fun (e[0]));
2777 assert (btor_node_is_args (e[1]));
2778 assert (!btor_node_is_fun (e[2]));
2779
2780 if (btor_node_real_addr (e[0])->parameterized
2781 || btor_node_real_addr (e[1])->parameterized
2782 || btor_node_real_addr (e[2])->parameterized)
2783 {
2784 assert (btor_node_args_get_arity (btor, args) == 1);
2785 return btor_exp_lambda_write (btor, fun, args->e[0], value);
2786 }
2787
2788 res = create_exp (btor, BTOR_UPDATE_NODE, 3, e);
2789 if (fun->is_array) res->is_array = 1;
2790 return res;
2791 }
2792
2793 /*========================================================================*/
2794
2795 BtorNodePair *
btor_node_pair_new(Btor * btor,BtorNode * exp1,BtorNode * exp2)2796 btor_node_pair_new (Btor *btor, BtorNode *exp1, BtorNode *exp2)
2797 {
2798 assert (btor);
2799 assert (exp1);
2800 assert (exp2);
2801 assert (btor == btor_node_real_addr (exp1)->btor);
2802 assert (btor == btor_node_real_addr (exp2)->btor);
2803
2804 uint32_t id1, id2;
2805 BtorNodePair *result;
2806
2807 BTOR_NEW (btor->mm, result);
2808 id1 = btor_node_get_id (exp1);
2809 id2 = btor_node_get_id (exp2);
2810 if (id2 < id1)
2811 {
2812 result->node1 = btor_node_copy (btor, exp2);
2813 result->node2 = btor_node_copy (btor, exp1);
2814 }
2815 else
2816 {
2817 result->node1 = btor_node_copy (btor, exp1);
2818 result->node2 = btor_node_copy (btor, exp2);
2819 }
2820 return result;
2821 }
2822
2823 void
btor_node_pair_delete(Btor * btor,BtorNodePair * pair)2824 btor_node_pair_delete (Btor *btor, BtorNodePair *pair)
2825 {
2826 assert (btor);
2827 assert (pair);
2828 btor_node_release (btor, pair->node1);
2829 btor_node_release (btor, pair->node2);
2830 BTOR_DELETE (btor->mm, pair);
2831 }
2832
2833 uint32_t
btor_node_pair_hash(const BtorNodePair * pair)2834 btor_node_pair_hash (const BtorNodePair *pair)
2835 {
2836 uint32_t result;
2837 assert (pair);
2838 result = (uint32_t) btor_node_real_addr (pair->node1)->id;
2839 result += (uint32_t) btor_node_real_addr (pair->node2)->id;
2840 result *= 7334147u;
2841 return result;
2842 }
2843
2844 int32_t
btor_node_pair_compare(const BtorNodePair * pair1,const BtorNodePair * pair2)2845 btor_node_pair_compare (const BtorNodePair *pair1, const BtorNodePair *pair2)
2846 {
2847 assert (pair1);
2848 assert (pair2);
2849
2850 int32_t result;
2851
2852 result = btor_node_get_id (pair1->node1);
2853 result -= btor_node_get_id (pair2->node1);
2854 if (result != 0) return result;
2855 result = btor_node_get_id (pair1->node2);
2856 result -= btor_node_get_id (pair2->node2);
2857 return result;
2858 }
2859