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 "btorass.h"
10 
11 #include <assert.h>
12 #include <stdbool.h>
13 
14 /*------------------------------------------------------------------------*/
15 
16 BtorBVAssList *
btor_ass_new_bv_list(BtorMemMgr * mm)17 btor_ass_new_bv_list (BtorMemMgr *mm)
18 {
19   assert (mm);
20 
21   BtorBVAssList *res;
22 
23   BTOR_CNEW (mm, res);
24   res->mm   = mm;
25   res->last = res->first;
26   return res;
27 }
28 
29 BtorBVAssList *
btor_ass_clone_bv_list(BtorMemMgr * mm,BtorBVAssList * list)30 btor_ass_clone_bv_list (BtorMemMgr *mm, BtorBVAssList *list)
31 {
32   assert (mm);
33   assert (list);
34 
35   BtorBVAssList *res;
36   BtorBVAss *bvass;
37 
38   res = btor_ass_new_bv_list (mm);
39   for (bvass = list->first; bvass; bvass = bvass->next)
40     (void) btor_ass_new_bv (res, (char *) btor_ass_get_bv_str (bvass));
41 
42   return res;
43 }
44 
45 void
btor_ass_delete_bv_list(BtorBVAssList * list,bool auto_cleanup)46 btor_ass_delete_bv_list (BtorBVAssList *list, bool auto_cleanup)
47 {
48   assert (list);
49 
50   BtorBVAss *bvass, *tmp;
51 
52   assert (auto_cleanup || list->count == 0);
53 
54   if (auto_cleanup)
55   {
56     bvass = list->first;
57     while (bvass)
58     {
59       tmp   = bvass;
60       bvass = bvass->next;
61       btor_ass_release_bv (list, (char *) btor_ass_get_bv_str (tmp));
62     }
63   }
64   BTOR_DELETE (list->mm, list);
65 }
66 
67 BtorBVAss *
btor_ass_get_bv(const char * ass)68 btor_ass_get_bv (const char *ass)
69 {
70   assert (ass);
71   return (BtorBVAss *) (ass - sizeof (BtorBVAss));
72 }
73 
74 const char *
btor_ass_get_bv_str(BtorBVAss * ass)75 btor_ass_get_bv_str (BtorBVAss *ass)
76 {
77   return (const char *) ((char *) ass + sizeof (BtorBVAss));
78 }
79 
80 BtorBVAss *
btor_ass_new_bv(BtorBVAssList * list,char * ass)81 btor_ass_new_bv (BtorBVAssList *list, char *ass)
82 {
83   assert (list);
84   assert (ass);
85 
86   BtorBVAss *res;
87   uint32_t len;
88 
89   len = strlen (ass) + 1;
90   res = btor_mem_calloc (list->mm, sizeof (BtorBVAss) + len, sizeof (char));
91   strcpy ((char *) res + sizeof (BtorBVAss), ass);
92   res->prev = list->last;
93   if (list->first)
94     list->last->next = res;
95   else
96     list->first = res;
97   list->last = res;
98   list->count += 1;
99 
100   return res;
101 }
102 
103 bool
btor_find_bv_assignment_dbg(BtorBVAssList * list,BtorBVAss * ass)104 btor_find_bv_assignment_dbg (BtorBVAssList *list, BtorBVAss *ass)
105 {
106   assert (list);
107   assert (ass);
108 
109   bool res;
110   BtorBVAss *b;
111 
112   for (res = false, b = list->first; b; b = b->next)
113     if ((res = (b == ass))) break;
114   return res;
115 }
116 
117 void
btor_ass_release_bv(BtorBVAssList * list,const char * ass)118 btor_ass_release_bv (BtorBVAssList *list, const char *ass)
119 {
120   assert (list);
121   assert (ass);
122 
123   BtorBVAss *bvass;
124 
125   assert (list->count);
126   list->count -= 1;
127 
128   bvass = btor_ass_get_bv (ass);
129   assert (btor_find_bv_assignment_dbg (list, bvass));
130 
131   if (bvass->prev)
132     bvass->prev->next = bvass->next;
133   else
134     list->first = bvass->next;
135 
136   if (bvass->next)
137     bvass->next->prev = bvass->prev;
138   else
139     list->last = bvass->prev;
140   btor_mem_free (list->mm, bvass, sizeof (BtorBVAss) + strlen (ass) + 1);
141 }
142 
143 /*------------------------------------------------------------------------*/
144 
145 BtorFunAssList *
btor_ass_new_fun_list(BtorMemMgr * mm)146 btor_ass_new_fun_list (BtorMemMgr *mm)
147 {
148   assert (mm);
149 
150   BtorFunAssList *res;
151 
152   BTOR_CNEW (mm, res);
153   res->mm   = mm;
154   res->last = res->first;
155   return res;
156 }
157 
158 BtorFunAssList *
btor_ass_clone_fun_list(BtorMemMgr * mm,BtorFunAssList * list)159 btor_ass_clone_fun_list (BtorMemMgr *mm, BtorFunAssList *list)
160 {
161   assert (mm);
162   assert (list);
163 
164   BtorFunAssList *res;
165   BtorFunAss *funass;
166   char **ind, **val, **cind, **cval;
167 
168   res = btor_ass_new_fun_list (mm);
169   for (funass = list->first; funass; funass = funass->next)
170   {
171     btor_ass_get_fun_indices_values (funass, &ind, &val, funass->size);
172     btor_ass_get_fun_indices_values (
173         btor_ass_new_fun (res, ind, val, funass->size),
174         &cind,
175         &cval,
176         funass->size);
177     funass->cloned_indices = cind;
178     funass->cloned_values  = cval;
179   }
180 
181   return res;
182 }
183 
184 void
btor_ass_delete_fun_list(BtorFunAssList * list,bool auto_cleanup)185 btor_ass_delete_fun_list (BtorFunAssList *list, bool auto_cleanup)
186 {
187   assert (list);
188 
189   BtorFunAss *funass, *next;
190   char **ind, **val;
191 
192   assert (auto_cleanup || list->count == 0);
193 
194   if (auto_cleanup)
195   {
196     for (funass = list->first, next = 0; funass; funass = next)
197     {
198       next = funass->next;
199       btor_ass_get_fun_indices_values (funass, &ind, &val, funass->size);
200       btor_ass_release_fun (list, ind, val, funass->size);
201     }
202   }
203   BTOR_DELETE (list->mm, list);
204 }
205 
206 BtorFunAss *
btor_ass_get_fun(const char ** indices,const char ** values,uint32_t size)207 btor_ass_get_fun (const char **indices, const char **values, uint32_t size)
208 {
209   assert (indices);
210   assert (values);
211   (void) values;
212   assert (size);
213   (void) size;
214 
215   BtorFunAss *funass;
216 
217   funass = (BtorFunAss *) ((char *) indices - sizeof (BtorFunAss));
218   assert (funass->size == size);
219   return funass;
220 }
221 
222 void
btor_ass_get_fun_indices_values(BtorFunAss * ass,char *** indices,char *** values,uint32_t size)223 btor_ass_get_fun_indices_values (BtorFunAss *ass,
224                                  char ***indices,
225                                  char ***values,
226                                  uint32_t size)
227 {
228   assert (ass);
229   assert (indices);
230   assert (values);
231   assert (size);
232   (void) size;
233 
234   assert (size == ass->size);
235   *indices = (char **) ((char *) ass + sizeof (BtorFunAss));
236   *values  = (char **) ((char *) ass + sizeof (BtorFunAss)
237                        + ass->size * sizeof (char *));
238 }
239 
240 BtorFunAss *
btor_ass_new_fun(BtorFunAssList * list,char ** indices,char ** values,uint32_t size)241 btor_ass_new_fun (BtorFunAssList *list,
242                   char **indices,
243                   char **values,
244                   uint32_t size)
245 {
246   assert (list);
247   assert (indices);
248   assert (values);
249 
250   BtorFunAss *res;
251   char **ind, **val;
252   uint32_t i;
253 
254   res       = btor_mem_calloc (list->mm,
255                          sizeof (BtorFunAss) + 2 * size * sizeof (char *),
256                          sizeof (char));
257   res->size = size;
258   if (list->first)
259     list->last->next = res;
260   else
261     list->first = res;
262   list->last = res;
263 
264   btor_ass_get_fun_indices_values (res, &ind, &val, size);
265   for (i = 0; i < size; i++)
266   {
267     ind[i] = btor_mem_strdup (list->mm, indices[i]);
268     val[i] = btor_mem_strdup (list->mm, values[i]);
269   }
270 
271   list->count += 1;
272 
273   return res;
274 }
275 
276 bool
btor_find_array_assignment_dbg(BtorFunAssList * list,BtorFunAss * ass)277 btor_find_array_assignment_dbg (BtorFunAssList *list, BtorFunAss *ass)
278 {
279   assert (list);
280   assert (ass);
281 
282   bool res;
283   BtorFunAss *a;
284 
285   for (res = 0, a = list->first; a; a = a->next)
286     if ((res = (a == ass))) break;
287   return res;
288 }
289 
290 void
btor_ass_release_fun(BtorFunAssList * list,char ** indices,char ** values,uint32_t size)291 btor_ass_release_fun (BtorFunAssList *list,
292                       char **indices,
293                       char **values,
294                       uint32_t size)
295 
296 {
297   assert (list);
298   assert (indices);
299   assert (values);
300   assert (size);
301 
302   uint32_t i;
303   BtorFunAss *funass;
304 
305   assert (list->count);
306   list->count -= 1;
307 
308   funass =
309       btor_ass_get_fun ((const char **) indices, (const char **) values, size);
310   assert (size == funass->size);
311   assert (btor_find_array_assignment_dbg (list, funass));
312 
313   if (funass->prev)
314     funass->prev->next = funass->next;
315   else
316     list->first = funass->next;
317 
318   if (funass->next)
319     funass->next->prev = funass->prev;
320   else
321     list->last = funass->prev;
322 
323   for (i = 0; i < size; i++)
324   {
325     btor_mem_freestr (list->mm, indices[i]);
326     btor_mem_freestr (list->mm, values[i]);
327   }
328   btor_mem_free (
329       list->mm, funass, sizeof (BtorFunAss) + 2 * size * sizeof (char *));
330 }
331