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 "utils/btornodeiter.h"
10 
11 /*------------------------------------------------------------------------*/
12 /* node iterators					                  */
13 /*------------------------------------------------------------------------*/
14 
15 void
btor_iter_apply_parent_init(BtorNodeIterator * it,const BtorNode * exp)16 btor_iter_apply_parent_init (BtorNodeIterator *it, const BtorNode *exp)
17 {
18   assert (it);
19   assert (exp);
20   it->cur = btor_node_real_addr (btor_node_real_addr (exp)->last_parent);
21 }
22 
23 bool
btor_iter_apply_parent_has_next(const BtorNodeIterator * it)24 btor_iter_apply_parent_has_next (const BtorNodeIterator *it)
25 {
26   assert (it);
27   assert (btor_node_is_regular (it->cur));
28   /* function child of apply is at position 0, so cur is not tagged */
29   return it->cur && btor_node_is_apply (it->cur);
30 }
31 
32 BtorNode *
btor_iter_apply_parent_next(BtorNodeIterator * it)33 btor_iter_apply_parent_next (BtorNodeIterator *it)
34 {
35   BtorNode *result;
36   assert (it);
37   result = it->cur;
38   assert (result);
39   it->cur = btor_node_real_addr (BTOR_PREV_PARENT (result));
40   assert (btor_node_is_regular (result));
41   assert (btor_node_is_apply (result));
42   return result;
43 }
44 
45 /*------------------------------------------------------------------------*/
46 
47 void
btor_iter_parent_init(BtorNodeIterator * it,const BtorNode * exp)48 btor_iter_parent_init (BtorNodeIterator *it, const BtorNode *exp)
49 {
50   assert (it);
51   assert (exp);
52   it->cur = btor_node_real_addr (exp)->first_parent;
53 }
54 
55 bool
btor_iter_parent_has_next(const BtorNodeIterator * it)56 btor_iter_parent_has_next (const BtorNodeIterator *it)
57 {
58   assert (it);
59   return it->cur != 0;
60 }
61 
62 BtorNode *
btor_iter_parent_next(BtorNodeIterator * it)63 btor_iter_parent_next (BtorNodeIterator *it)
64 {
65   assert (it);
66 
67   BtorNode *result;
68   result = it->cur;
69   assert (result);
70   it->cur = BTOR_NEXT_PARENT (result);
71 
72   return btor_node_real_addr (result);
73 }
74 
75 /*------------------------------------------------------------------------*/
76 
77 void
btor_iter_args_init(BtorArgsIterator * it,const BtorNode * exp)78 btor_iter_args_init (BtorArgsIterator *it, const BtorNode *exp)
79 {
80   assert (it);
81   assert (exp);
82   assert (btor_node_is_regular (exp));
83   assert (btor_node_is_args (exp));
84 
85   it->pos = 0;
86   it->exp = exp;
87   it->cur = exp->e[0];
88 }
89 
90 bool
btor_iter_args_has_next(const BtorArgsIterator * it)91 btor_iter_args_has_next (const BtorArgsIterator *it)
92 {
93   assert (it);
94   return it->cur != 0;
95 }
96 
97 BtorNode *
btor_iter_args_next(BtorArgsIterator * it)98 btor_iter_args_next (BtorArgsIterator *it)
99 {
100   assert (it);
101   assert (it->cur);
102 
103   BtorNode *result;
104 
105   result = it->cur;
106 
107   /* end of this args node, continue with next */
108   if (btor_node_is_args (result))
109   {
110     assert (it->pos == 2);
111     assert (btor_node_is_regular (result));
112     it->pos = 0;
113     it->exp = result;
114     it->cur = result->e[0];
115     result  = it->cur;
116   }
117 
118   /* prepare next argument */
119   it->pos++;
120   if (it->pos < it->exp->arity)
121     it->cur = it->exp->e[it->pos];
122   else
123     it->cur = 0;
124 
125   assert (!btor_node_is_args (result));
126   return result;
127 }
128 
129 /*------------------------------------------------------------------------*/
130 
131 void
btor_iter_binder_init(BtorNodeIterator * it,BtorNode * exp)132 btor_iter_binder_init (BtorNodeIterator *it, BtorNode *exp)
133 {
134   assert (it);
135   assert (exp);
136   assert (btor_node_is_regular (exp));
137   assert (btor_node_is_binder (exp));
138 
139   it->cur = exp;
140 }
141 
142 BtorNode *
btor_iter_binder_next(BtorNodeIterator * it)143 btor_iter_binder_next (BtorNodeIterator *it)
144 {
145   assert (it);
146   assert (it->cur);
147 
148   BtorNode *result;
149   result  = it->cur;
150   it->cur = result->e[1];
151   return result;
152 }
153 
154 bool
btor_iter_binder_has_next(const BtorNodeIterator * it)155 btor_iter_binder_has_next (const BtorNodeIterator *it)
156 {
157   assert (it);
158   assert (it->cur);
159   return !btor_node_is_inverted (it->cur) && btor_node_is_binder (it->cur);
160 }
161 
162 void
btor_iter_lambda_init(BtorNodeIterator * it,BtorNode * exp)163 btor_iter_lambda_init (BtorNodeIterator *it, BtorNode *exp)
164 {
165   btor_iter_binder_init (it, exp);
166   assert (btor_node_is_lambda (exp));
167 }
168 
169 BtorNode *
btor_iter_lambda_next(BtorNodeIterator * it)170 btor_iter_lambda_next (BtorNodeIterator *it)
171 {
172   return btor_iter_binder_next (it);
173 }
174 
175 bool
btor_iter_lambda_has_next(const BtorNodeIterator * it)176 btor_iter_lambda_has_next (const BtorNodeIterator *it)
177 {
178   assert (it);
179   assert (it->cur);
180   return btor_node_is_lambda (it->cur);
181 }
182 
183 /*------------------------------------------------------------------------*/
184 
185 #if 0
186 void
187 btor_iter_param_init (BtorNodeIterator * it, BtorNode * exp)
188 {
189   btor_iter_binder_init (it, exp);
190 }
191 
192 BtorNode *
193 btor_iter_param_next (BtorNodeIterator * it)
194 {
195   BtorNode *result;
196   result = btor_iter_binder_next (it);
197   assert (btor_node_is_param (result->e[0]));
198   return result->e[0];
199 }
200 
201 bool
202 btor_has_next_param_iterator (BtorNodeIterator * it)
203 {
204   return btor_has_next_binder_iterator (it);
205 }
206 #endif
207 
208 /*------------------------------------------------------------------------*/
209 
210 #if 0
211 static void
212 find_next_unique_node (BtorNodeIterator * it)
213 {
214   while (!it->cur && it->pos < it->btor->nodes_unique_table.size)
215     it->cur = it->btor->nodes_unique_table.chains[it->pos++];
216   assert (it->cur
217 	  || it->num_elements == it->btor->nodes_unique_table.num_elements);
218 }
219 
220 void
221 btor_iter_unique_table_init (BtorNodeIterator * it, const Btor * btor)
222 {
223   assert (btor);
224   assert (it);
225 
226   it->btor = btor;
227   it->pos = 0;
228 #ifndef NDEBUG
229   it->num_elements = 0;
230 #endif
231   it->cur = 0;
232   find_next_unique_node (it);
233 }
234 
235 bool
236 btor_iter_unique_table_has_next (const BtorNodeIterator * it)
237 {
238   assert (it);
239   assert (it->cur || it->pos >= it->btor->nodes_unique_table.size);
240   return it->cur != 0;
241 }
242 
243 BtorNode *
244 btor_iter_unique_table_next (BtorNodeIterator * it)
245 {
246   assert (it);
247   assert (it->cur);
248 
249   BtorNode *result;
250 
251   result = it->cur;
252 #ifndef NDEBUG
253   it->num_elements++;
254   assert (it->num_elements <= it->btor->nodes_unique_table.num_elements);
255   assert (result);
256 #endif
257   it->cur = it->cur->next;
258   if (!it->cur)
259     find_next_unique_node (it);
260   return result;
261 }
262 #endif
263