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

SRI-CSL / yices2 / 4238628909

pending completion
4238628909

push

github

Ahmed Irfan
disable weq-graph sorting heuristic

76406 of 118997 relevant lines covered (64.21%)

1268580.07 hits per line

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

93.13
/src/mcsat/variable_queue.c
1
/*
2
 * This file is part of the Yices SMT Solver.
3
 * Copyright (C) 2017 SRI International.
4
 *
5
 * Yices is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * Yices is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with Yices.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18
 
19
#include "mcsat/variable_queue.h"
20

21
#include "utils/dprng.h"
22

23
#include <float.h>
24

25
#define VAR_DECAY_FACTOR              (0.95)
26
#define VAR_ACTIVITY_THRESHOLD        (1e100)
27
#define INV_VAR_ACTIVITY_THRESHOLD    (1e-100)
28
#define INIT_VAR_ACTIVITY_INCREMENT   (1.0)
29

30
#define VAR_QUEUE_INITIAL_SIZE        (100)
31

32
void var_queue_construct(var_queue_t *queue) {
608✔
33
  uint32_t i;
34
  double *tmp;
35

36
  tmp = (double *) safe_malloc((VAR_QUEUE_INITIAL_SIZE+2) * sizeof(double));
608✔
37
  queue->activity = tmp + 2;
608✔
38
  queue->heap_index = (int32_t *) safe_malloc(VAR_QUEUE_INITIAL_SIZE * sizeof(int32_t));
608✔
39
  queue->heap = (variable_t *) safe_malloc((VAR_QUEUE_INITIAL_SIZE+1) * sizeof(variable_t));
608✔
40

41
  for (i=0; i<VAR_QUEUE_INITIAL_SIZE; i++) {
61,408✔
42
    queue->heap_index[i] = -1;
60,800✔
43
    queue->activity[i] = 0.0;
60,800✔
44
  }
45

46
  queue->activity[-2] = -1.0;
608✔
47
  queue->activity[-1] = DBL_MAX;
608✔
48
  queue->heap[0] = -1;
608✔
49

50
  queue->heap_last = 0;
608✔
51
  queue->size = VAR_QUEUE_INITIAL_SIZE;
608✔
52
  queue->vmax = 0;
608✔
53

54
  queue->act_increment = INIT_VAR_ACTIVITY_INCREMENT;
608✔
55
  queue->inv_act_decay = 1/VAR_DECAY_FACTOR;
608✔
56
}
608✔
57

58
void var_queue_extend(var_queue_t *queue, uint32_t n) {
460✔
59
  uint32_t old_size, i;
60
  double *tmp;
61

62
  old_size = queue->size;
460✔
63
  assert(old_size < n);
64
  tmp = queue->activity - 2;
460✔
65
  tmp = (double *) safe_realloc(tmp, (n+2) * sizeof(double));
460✔
66
  queue->activity = tmp + 2;
460✔
67
  queue->heap_index = (int32_t *) safe_realloc(queue->heap_index, n * sizeof(int32_t));
460✔
68
  queue->heap = (int32_t *) safe_realloc(queue->heap, (n+1) * sizeof(int32_t));
460✔
69
  queue->size = n;
460✔
70

71
  for (i=old_size; i<n; i++) {
188,818✔
72
    queue->heap_index[i] = -1;
188,358✔
73
    queue->activity[i] = 0.0;
188,358✔
74
  }
75
}
460✔
76

77
void var_queue_destruct(var_queue_t *queue) {
608✔
78
  safe_free(queue->activity - 2);
608✔
79
  safe_free(queue->heap_index);
608✔
80
  safe_free(queue->heap);
608✔
81
}
608✔
82

83
static
84
void var_queue_update_up(var_queue_t *queue, variable_t x, uint32_t i) {
11,296,761✔
85
  double ax, *act;
86
  int32_t *index;
87
  variable_t *h, y;
88
  uint32_t j;
89

90
  h = queue->heap;
11,296,761✔
91
  index = queue->heap_index;
11,296,761✔
92
  act = queue->activity;
11,296,761✔
93

94
  ax = act[x];
11,296,761✔
95

96
  for (;;) {
97
    j = i >> 1;    // parent of i
38,446,826✔
98
    y = h[j];      // variable at position j in the heap
38,446,826✔
99

100
    // The loop terminates since act[h[0]] = DBL_MAX
101
    if (act[y] >= ax) break;
38,446,826✔
102

103
    // move y down, into position i
104
    h[i] = y;
27,150,065✔
105
    index[y] = i;
27,150,065✔
106

107
    // move i up
108
    i = j;
27,150,065✔
109
  }
110

111
  // i is the new position for variable x
112
  h[i] = x;
11,296,761✔
113
  index[x] = i;
11,296,761✔
114
}
11,296,761✔
115

116
static
117
void var_queue_update_down(var_queue_t *queue) {
7,189,298✔
118
  double *act;
119
  int32_t *index;
120
  variable_t *h;
121
  variable_t x, y, z;
122
  double ax, ay, az;
123
  uint32_t i, j, last;
124

125
  last = queue->heap_last;
7,189,298✔
126
  queue->heap_last = last - 1;
7,189,298✔
127
  if (last <= 1 ) { // empty heap.
7,189,298✔
128
    assert(queue->heap_last == 0);
129
    return;
1,425✔
130
  }
131

132
  h = queue->heap;
7,187,873✔
133
  index = queue->heap_index;
7,187,873✔
134
  act = queue->activity;
7,187,873✔
135

136
  z = h[last];   // last element
7,187,873✔
137
  h[last] = -2;  // set end marker: act[-2] is negative
7,187,873✔
138
  az = act[z];   // activity of the last element
7,187,873✔
139

140
  i = 1;      // root
7,187,873✔
141
  j = 2;      // left child of i
7,187,873✔
142
  while (j < last) {
53,137,154✔
143
    /*
144
     * find child of i with highest activity.
145
     * Since h[last] = -2, we don't check j+1 < last
146
     */
147
    x = h[j];
49,990,636✔
148
    y = h[j+1];
49,990,636✔
149
    ax = act[x];
49,990,636✔
150
    ay = act[y];
49,990,636✔
151
    if (ay > ax) {
49,990,636✔
152
      j++;
23,854,245✔
153
      x = y;
23,854,245✔
154
      ax = ay;
23,854,245✔
155
    }
156

157
    // x = child of node i of highest activity
158
    // j = position of x in the heap (j = 2i or j = 2i+1)
159
    if (az >= ax) break;
49,990,636✔
160

161
    // move x up, into heap[i]
162
    h[i] = x;
45,949,281✔
163
    index[x] = i;
45,949,281✔
164

165
    // go down one step.
166
    i = j;
45,949,281✔
167
    j <<= 1;
45,949,281✔
168
  }
169

170
  h[i] = z;
7,187,873✔
171
  index[z] = i;
7,187,873✔
172
}
173

174
/**
175
 * Insert x into the heap, using its current activity.
176
 * No effect if x is already in the heap.
177
 * - x must be between 0 and nvars - 1
178
 */
179
void var_queue_insert(var_queue_t *queue, variable_t x) {
21,590,005✔
180
  assert(x >= 0);
181
  assert(x < queue->size);
182
  if (queue->heap_index[x] < 0) {
21,590,005✔
183
    // x not in the heap
184
    queue->heap_last ++;
7,211,898✔
185
    var_queue_update_up(queue, x, queue->heap_last);
7,211,898✔
186
  }
187
}
21,590,005✔
188

189

190
/** Check whether the heap is empty. */
191
bool var_queue_is_empty(var_queue_t *queue) {
9,173,554✔
192
  return queue->heap_last == 0;
9,173,554✔
193
}
194

195

196
/** Get and remove top element (the heap must not be empty) */
197
variable_t var_queue_pop(var_queue_t *queue) {
7,189,298✔
198
  variable_t top;
199

200
  assert(queue->heap_last > 0);
201

202
  // remove top element
203
  top = queue->heap[1];
7,189,298✔
204
  queue->heap_index[top] = -1;
7,189,298✔
205

206
  // repair the heap
207
  var_queue_update_down(queue);
7,189,298✔
208

209
  return top;
7,189,298✔
210
}
211

212
/** Get random element (the heap must not be empty) */
213
variable_t var_queue_random(var_queue_t *queue, double* seed) {
×
214
  assert(queue->heap_last > 0);
215
  return queue->heap[irand(seed, queue->heap_last)+1];
×
216
}
217

218
/** Rescale variable activities: divide by VAR_ACTIVITY_THRESHOLD. */
219
void var_queue_rescale_activities(var_queue_t *queue) {
24✔
220
  uint32_t i, n;
221
  double *act;
222

223
  n = queue->size;
24✔
224
  act = queue->activity;
24✔
225
  for (i=0; i<n; i++) {
52,765✔
226
    act[i] *= INV_VAR_ACTIVITY_THRESHOLD;
52,741✔
227
  }
228
  queue->act_increment *= INV_VAR_ACTIVITY_THRESHOLD;
24✔
229
}
24✔
230

231

232
/** Increase activity of variable x (factor times). */
233
void var_queue_bump_variable(var_queue_t *heap, variable_t x, uint32_t factor) {
7,171,437✔
234
  int32_t i;
235

236
  assert(factor > 0);
237
  assert(x < heap->size);
238

239
  if ((heap->activity[x] += factor * heap->act_increment) > VAR_ACTIVITY_THRESHOLD) {
7,171,437✔
240
    var_queue_rescale_activities(heap);
24✔
241
  }
242

243
  // move x up if it's in the heap
244
  i = heap->heap_index[x];
7,171,437✔
245
  if (i >= 0) {
7,171,437✔
246
    var_queue_update_up(heap, x, i);
4,084,863✔
247
  }
248
}
7,171,437✔
249

250
double var_queue_get_activity(const var_queue_t* queue, variable_t x) {
5✔
251
  assert(x < queue->size);
252
  return queue->activity[x];
5✔
253
}
254

255
void var_queue_set_activity(var_queue_t* queue, variable_t x, double a) {
5✔
256
  assert(x < queue->size);
257
  assert(queue->heap_index[x] < 0);
258
  queue->activity[x] = a;
5✔
259
}
5✔
260

261
int var_queue_cmp_variables(var_queue_t *queue, variable_t x, variable_t y) {
×
262
  assert(x < queue->size);
263
  assert(y < queue->size);
264

265
  double diff = queue->activity[x] - queue->activity[y];
×
266

267
  if (diff < 0) {
×
268
    return -1;
×
269
  }
270
  if (diff > 0) {
×
271
    return 1;
×
272
  }
273

274
  return 0;
×
275
}
276

277
/** Decay. */
278
void var_queue_decay_activities(var_queue_t *queue) {
167,188✔
279
  queue->act_increment *= queue->inv_act_decay;
167,188✔
280
}
167,188✔
281

282
/** Sweep the variables */
283
void var_queue_gc_sweep(var_queue_t* queue, const gc_info_t* gc_vars) {
443✔
284

285
  ivector_t vars;
286
  init_ivector(&vars, 0);
443✔
287

288
  assert(gc_vars->is_id);
289

290
  // pop all the variable and put them back in
291
  while (!var_queue_is_empty(queue)) {
218,947✔
292
    variable_t x = var_queue_pop(queue);
218,504✔
293
    if (gc_info_get_reloc(gc_vars, x) != variable_null) {
218,504✔
294
      ivector_push(&vars, x);
192,764✔
295
    }
296
  }
297
  uint32_t var_i;
298
  for (var_i = 0; var_i < vars.size; ++ var_i) {
193,207✔
299
    variable_t x = vars.data[var_i];
192,764✔
300
    var_queue_insert(queue, x);
192,764✔
301
  }
302

303
  delete_ivector(&vars);
443✔
304
}
443✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc