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, &param, 1);
2609   app_else = btor_exp_apply_n (btor, e_else, &param, 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