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

SRI-CSL / yices2 / 12367760548

17 Dec 2024 06:41AM UTC coverage: 65.285% (-0.6%) from 65.92%
12367760548

push

github

web-flow
Fixes GitHub coverage issue (#544)

* Update action.yml

* Update action.yml

81020 of 124102 relevant lines covered (65.29%)

1509382.01 hits per line

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

89.33
/src/solvers/simplex/arith_vartable.h
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
/*
20
 * TABLE OF VARIABLES FOR ARITHMETIC SOLVERS
21
 */
22

23
/*
24
 * This table maps theory variables within an arithmetic
25
 * solver to their definition, and to the attached eterm if any.
26
 * It provides hash-consing and it supports removal of variables for pop.
27
 * The table is intended primarily for the Simplex solver,
28
 * but it should be usable by future variants.
29
 *
30
 * The table also maintains a variable assignment (i.e., a mapping from
31
 * variables to extended_rationals), and it keeps track of the current
32
 * lower and upper bound on all variables. These bounds are identified
33
 * by an integer index (i.e., an index into a global queue where asserted
34
 * and derived bounds are pushed).
35
 *
36
 * More precisely, for each arithmetic variable v, the table stores
37
 * - the definition of v, which can be
38
 *     either NULL
39
 *     or a pointer to a polynomial_t object
40
 *     or a pointer to a pprod_t object (for non-linear arithmetic)
41
 *     or a pointer to a rational_t object
42
 * - whether v is an integer or a real variable
43
 * - the egraph term attached to v (or null_eterm if there's none)
44
 * - a vector of atoms indices (all the atoms whose variable is v)
45
 * - the value of v in the current assignment
46
 * - the index of lower/upper bounds on v
47
 */
48

49
#ifndef __ARITH_VARTABLE_H
50
#define __ARITH_VARTABLE_H
51

52
#include <stdint.h>
53
#include <stdbool.h>
54
#include <assert.h>
55

56
#include "solvers/egraph/egraph_base_types.h"
57
#include "terms/extended_rationals.h"
58
#include "terms/polynomials.h"
59
#include "terms/power_products.h"
60
#include "utils/bitvectors.h"
61
#include "utils/index_vectors.h"
62
#include "utils/int_hash_tables.h"
63

64

65
/********************
66
 *  VARIABLE FLAGS  *
67
 *******************/
68

69
/*
70
 * For each variable x we keep data used during assignment updates,
71
 * and other simplex operations.
72
 * - whether value[x] is equal to the lower bound on x
73
 * - whether value[x] is equal to the upper bound on x
74
 * - a generic 1bit mark
75
 *
76
 * This data is stored into an 8bit variable tag
77
 * - bit 0: mark
78
 * - bit 1: x == lower bound
79
 * - bit 2: x == upper bound
80
 *
81
 * The mark bit is currently used only in simplex make_feasible
82
 * - variable x is marked if it was the leaving variable in a pivoting step
83
 * - this is used to switch to Blend's rule after too many variables
84
 *   leave the basis
85
 *
86
 * Other bits in this tag store information about x's type and
87
 * definition:
88
 * - bit 3 is 1 is x is an integer variable, 0 otherwise
89
 * - bit 4 and 5 specify how to interpret def[x]:
90
 *    00 --> x is a variable (def[x] = NULL)
91
 *    01 --> def[x] is a polynomial
92
 *    10 --> def[x] is a power product
93
 *    11 --> def[x] is a rational constant
94
 */
95

96
#define AVARTAG_MARK_MASK  ((uint8_t) 0x1)
97
#define AVARTAG_ATLB_MASK  ((uint8_t) 0x2)
98
#define AVARTAG_ATUB_MASK  ((uint8_t) 0x4)
99
#define AVARTAG_INT_MASK    ((uint8_t) 0x8)
100

101
#define AVARTAG_KIND_MASK   ((uint8_t) 0x30)
102

103

104
/*
105
 * Variable kinds: 00 to 11
106
 */
107
typedef enum {
108
  AVAR_FREE = 0,  // 0b00
109
  AVAR_POLY = 1,  // 0b01
110
  AVAR_PPROD = 2, // 0b10
111
  AVAR_CONST = 3, // 0b11
112
} avar_kind_t;
113

114

115
/*
116
 * Two bits stored in the kind field (bits 4 and 5)
117
 */
118
#define AVARTAG_KIND_FREE  ((uint8_t) 0x00)
119
#define AVARTAG_KIND_POLY  ((uint8_t) 0x10)
120
#define AVARTAG_KIND_PPROD ((uint8_t) 0x20)
121
#define AVARTAG_KIND_CONST ((uint8_t) 0x30)
122

123

124

125

126

127
/********************
128
 *  VARIABLE TABLE  *
129
 *******************/
130

131
/*
132
 * - nvars = number of variables
133
 * - ivars = number of integer variables
134
 * - size = size of all variable-indexed arrays
135
 * - def = array of tagged pointers = variable definition
136
 * - atoms = atom vector for each variable
137
 * - eterm = array of egraph terms
138
 *
139
 * - value = current assignment
140
 * - upper_index, lower_index = indices in the bound queue (-1) means no bound
141
 * - tag = variable tag
142
 */
143
typedef struct arith_vartable_s {
144
  uint32_t nvars;
145
  uint32_t ivars;
146
  uint32_t size;
147

148
  // variable definition and related data
149
  void **def;
150
  int32_t **atoms;
151
  eterm_t *eterm;
152
  uint8_t *tag;
153

154
  // assignment and bounds
155
  xrational_t *value;
156
  int32_t *lower_index;
157
  int32_t *upper_index;
158

159
  int_htbl_t htbl;   // for hash consing
160
} arith_vartable_t;
161

162

163
/*
164
 * Default and maximal size
165
 */
166
#define DEF_AVARTABLE_SIZE 100
167
#define MAX_AVARTABLE_SIZE (UINT32_MAX/sizeof(xrational_t))
168

169

170

171

172
/**********************
173
 *  TABLE OPERATIONS  *
174
 *********************/
175

176
/*
177
 * Initialization:
178
 * - the table is initialized with its default size
179
 * - the eterm array is not allocated here, but on the first
180
 *   call to attach_eterm.
181
 */
182
extern void init_arith_vartable(arith_vartable_t *table);
183

184

185
/*
186
 * Deletion: delete all internal tables and all polynomials/varprod objects
187
 */
188
extern void delete_arith_vartable(arith_vartable_t *table);
189

190

191
/*
192
 * Reset: empty the table, delete all polynomials and varprod objects
193
 */
194
extern void reset_arith_vartable(arith_vartable_t *table);
195

196

197
/*
198
 * Support for pop: delete all variables of index >= nvars
199
 */
200
extern void arith_vartable_remove_vars(arith_vartable_t *table, uint32_t nvars);
201

202

203
/*
204
 * Support for pop: remove all references to egraph terms of indices >= nterms.
205
 * - go through all variables x in the table.
206
 *   if eterm[x] is defined and >= nterms, then it's reset to null_eterm
207
 */
208
extern void arith_vartable_remove_eterms(arith_vartable_t *table, uint32_t nterms);
209

210

211
/*
212
 * Read the number of variables
213
 */
214
static inline uint32_t num_arith_vars(arith_vartable_t *table) {
2,665✔
215
  return table->nvars;
2,665✔
216
}
217

218

219
/*
220
 * Get the number of integer variables
221
 */
222
static inline uint32_t num_integer_vars(arith_vartable_t *table) {
30,675✔
223
  return table->ivars;
30,675✔
224
}
225

226

227
/*
228
 * Number of variables not marked as integer
229
 */
230
static inline uint32_t num_real_vars(arith_vartable_t *table) {
231
  return table->nvars - num_integer_vars(table);
232
}
233

234

235
/*
236
 * Collect the set of integer variables as a bit vector
237
 * - i.e., return a bitvector V of size n = table->nvars
238
 * - bit i of V is 1 if variable i has integer type.
239
 * - V must be deleted when no longer used by calling delete_bitvector(V)
240
 *   (cf. bitvectors.h)
241
 */
242
extern byte_t *get_integer_vars_vector(arith_vartable_t *table);
243

244

245

246
/*
247
 * VARIABLE CREATION
248
 */
249

250
/*
251
 * All new variables are created with the following default initialization:
252
 * - no eterm attached
253
 * - empty atom vector
254
 * - value = 0
255
 * - lower bound and upper bound indices = -1
256
 * - all flags are 0 (not marked, not at lower/upper bound)
257
 *
258
 * The kind and the integer bit set according to the definition
259
 */
260

261
/*
262
 * Create a new variable
263
 * - if is_int is true, the variable has integer type, otherwise it's a real variable
264
 * - the definition is NULL
265
 */
266
extern thvar_t create_arith_var(arith_vartable_t *table, bool is_int);
267

268

269
/*
270
 * Return a variable equal to rational q
271
 * - return null_thvar if there's no such variable in table
272
 */
273
extern thvar_t find_var_for_constant(arith_vartable_t *table, rational_t *q);
274

275

276
/*
277
 * Get a variable equal to rational q
278
 * - create a fresh variable if needed, and set new_var to true
279
 * - otherwise, set new_var to false
280
 */
281
extern thvar_t get_var_for_constant(arith_vartable_t *table, rational_t *q, bool *new_var);
282

283

284
/*
285
 * Find a variable whose definition is equal to polynomial p
286
 * - if there's no such variable, return null_thvar = -1
287
 * - p must be normalized and all its variables must exist in table
288
 * (i.e., p must have its variables sorted and it must be terminated by the end-marker max_idx)
289
 * - n must be the length of p, excluding the end marker
290
 */
291
extern thvar_t find_var_for_poly(arith_vartable_t *table, monomial_t *p, uint32_t n);
292

293

294
/*
295
 * Get a variable whose definition is equal to p
296
 * - create a fresh variable if there's no such variable in the table
297
 * - if a new variable is created, the flag *new_var is set to true,
298
 * - if an existing variable is returned, then *new_var is set false
299
 * - if p is an integer polynomial (all variables and coefficients are integer) then
300
 *   the fresh variable is an integer variable, otherwise it's a real variable.
301
 */
302
extern thvar_t get_var_for_poly(arith_vartable_t *table, monomial_t *p, uint32_t n, bool *new_var);
303

304

305
/*
306
 * Find a variable whose definition is equal to the non-constant part of p
307
 * - i.e., write p as k + q where k is the constant term, then find a variable for q
308
 */
309
extern thvar_t find_var_for_poly_offset(arith_vartable_t *table, monomial_t *p, uint32_t n);
310

311

312
/*
313
 * Get a variable whose definition is equal to the non-constant part of p
314
 * - i.e., write p as k + q where k is the constant term, then get a variable for q
315
 *
316
 * NOTE: this is used to construct atoms: for example, atom (a + q >= 0)
317
 * can be internalized to (x >= -a) with x = var_for_poly_offset(a + q) = var for q
318
 */
319
extern thvar_t get_var_for_poly_offset(arith_vartable_t *table, monomial_t *p, uint32_t n, bool *new_var);
320

321

322
/*
323
 * Find a variable whose definition is equal to the product p
324
 * - if there's no such variable, return null_thvar = -1
325
 * - p = array of pairs (variable, exponents)
326
 * - n = number of pairs in p
327
 * - p must normalized (cf. power_products.h)
328
 *
329
 * IMPORTANT: p must have degree at least 2.
330
 * (i.e., p must not be the empty product, or the end marker,
331
 *        or reducible to a single variable).
332
 */
333
extern thvar_t find_var_for_product(arith_vartable_t *table, varexp_t *p, uint32_t n);
334

335

336
/*
337
 * Return a variable equal to product p. Create a new variable if needed.
338
 * - set *new_flag to true if a new variable is created
339
 *
340
 * IMPORTANT: As above, p must have degree at least 2.
341
 * (i.e., p must not be the empty product, or the end marker,
342
 *        or reducible to a single variable).
343
 */
344
extern thvar_t get_var_for_product(arith_vartable_t *table, varexp_t *p, uint32_t n, bool *new_var);
345

346

347

348

349
/*
350
 * ACCESS TO VARIABLE DATA
351
 */
352

353
/*
354
 * Check whether x is a valid variable index
355
 */
356
static inline bool valid_arith_var(arith_vartable_t *table, thvar_t x) {
357
  return 0 <= x && x < table->nvars;
358
}
359

360

361
/*
362
 * Check type: integer or not
363
 */
364
static inline bool arith_var_is_int(arith_vartable_t *table, thvar_t x) {
3,269,468✔
365
  assert(valid_arith_var(table, x));
366
  return (table->tag[x] & AVARTAG_INT_MASK) != 0;
3,269,468✔
367
}
368

369

370
/*
371
 * Get/check the kind
372
 */
373
static inline avar_kind_t arith_var_kind(arith_vartable_t *table, thvar_t x) {
52,554✔
374
  assert(valid_arith_var(table, x));
375
  return (avar_kind_t)((table->tag[x] >> 4) & 3);
52,554✔
376
}
377

378
static inline bool arith_var_is_free(arith_vartable_t *table, thvar_t x) {
379
  assert(valid_arith_var(table, x));
380
  return (table->tag[x] & AVARTAG_KIND_MASK) == AVARTAG_KIND_FREE;
381
}
382

383
static inline bool arith_var_def_is_poly(arith_vartable_t *table, thvar_t x) {
106,584✔
384
  assert(valid_arith_var(table, x));
385
  return (table->tag[x] & AVARTAG_KIND_MASK) == AVARTAG_KIND_POLY;
106,584✔
386
}
387

388
static inline bool arith_var_def_is_product(arith_vartable_t *table, thvar_t x) {
×
389
  assert(valid_arith_var(table, x));
390
  return (table->tag[x] & AVARTAG_KIND_MASK) == AVARTAG_KIND_PPROD;
×
391
}
392

393
static inline bool arith_var_def_is_rational(arith_vartable_t *table, thvar_t x) {
×
394
  assert(valid_arith_var(table, x));
395
  return (table->tag[x] & AVARTAG_KIND_MASK) == AVARTAG_KIND_CONST;
×
396
}
397

398

399
/*
400
 * Definition of x
401
 */
402
static inline void* arith_var_def(arith_vartable_t *table, thvar_t x) {
1,309,203✔
403
  assert(valid_arith_var(table, x));
404
  return table->def[x];
1,309,203✔
405
}
406

407
static inline polynomial_t *arith_var_poly_def(arith_vartable_t *table, thvar_t x) {
93,265✔
408
  assert(arith_var_def_is_poly(table, x));
409
  return table->def[x];
93,265✔
410
}
411

412
static inline pprod_t *arith_var_product_def(arith_vartable_t *table, thvar_t x) {
×
413
  assert(arith_var_def_is_product(table, x));
414
  return table->def[x];
×
415
}
416

417
static inline rational_t *arith_var_rational_def(arith_vartable_t *table, thvar_t x) {
×
418
  assert(arith_var_def_is_rational(table, x));
419
  return table->def[x];
×
420
}
421

422

423
/*
424
 * Atoms involving x
425
 */
426
static inline int32_t *arith_var_atom_vector(arith_vartable_t *table, thvar_t x) {
11,257,757✔
427
  assert(valid_arith_var(table, x));
428
  return table->atoms[x];
11,257,757✔
429
}
430

431
static inline bool arith_var_has_atoms(arith_vartable_t *table, thvar_t x) {
432
  return arith_var_atom_vector(table, x) != NULL;
433
}
434

435
// number of atoms with variable x
436
static inline uint32_t arith_var_num_atoms(arith_vartable_t *table, thvar_t x) {
27,303✔
437
  int32_t *tmp;
438
  tmp = arith_var_atom_vector(table, x);
27,303✔
439
  return tmp == NULL ? 0 : iv_size(tmp);
27,303✔
440
}
441

442

443
/*
444
 * Value of x in the current assignment
445
 */
446
static inline xrational_t *arith_var_value(arith_vartable_t *table, thvar_t x) {
15,799,037✔
447
  assert(valid_arith_var(table, x));
448
  return table->value + x;
15,799,037✔
449
}
450

451

452
/*
453
 * Lower and upper bound indices
454
 */
455
static inline int32_t arith_var_lower_index(arith_vartable_t *table, thvar_t x) {
87,443,358✔
456
  assert(valid_arith_var(table, x));
457
  return table->lower_index[x];
87,443,358✔
458
}
459

460
static inline int32_t arith_var_upper_index(arith_vartable_t *table, thvar_t x) {
77,571,448✔
461
  assert(valid_arith_var(table, x));
462
  return table->upper_index[x];
77,571,448✔
463
}
464

465

466
/*
467
 * Check the flags of x
468
 */
469
static inline bool arith_var_is_marked(arith_vartable_t *table, thvar_t x) {
292,466✔
470
  assert(valid_arith_var(table, x));
471
  return (table->tag[x] & AVARTAG_MARK_MASK) != 0;
292,466✔
472
}
473

474
static inline bool arith_var_at_lower_bound(arith_vartable_t *table, thvar_t x) {
475
  assert(valid_arith_var(table, x));
476
  return (table->tag[x] & AVARTAG_ATLB_MASK) != 0;
477
}
478

479
static inline bool arith_var_at_upper_bound(arith_vartable_t *table, thvar_t x) {
480
  assert(valid_arith_var(table, x));
481
  return (table->tag[x] & AVARTAG_ATUB_MASK) != 0;
482
}
483

484
// check whether x is at its lower or upper bound
485
static inline bool arith_var_at_bound(arith_vartable_t *table, thvar_t x) {
486
  assert(valid_arith_var(table, x));
487
  return (table->tag[x] & (AVARTAG_ATLB_MASK|AVARTAG_ATUB_MASK)) != 0;
488
}
489

490
// check whether x is a fixed variable (both flags are set)
491
static inline bool arith_var_is_fixed(arith_vartable_t *table, thvar_t x) {
492
  assert(valid_arith_var(table, x));
493
  return (table->tag[x] & (AVARTAG_ATLB_MASK|AVARTAG_ATUB_MASK)) ==
494
    (AVARTAG_ATLB_MASK|AVARTAG_ATUB_MASK);
495
}
496

497
// get the full 8-bit tag
498
static inline uint8_t arith_var_tag(arith_vartable_t *table, thvar_t x) {
10,059,116✔
499
  assert(valid_arith_var(table, x));
500
  return table->tag[x];
10,059,116✔
501
}
502

503

504

505
/*
506
 * Set or clear the flags for x
507
 */
508
static inline void set_arith_var_mark(arith_vartable_t *table, thvar_t x) {
285,608✔
509
  assert(valid_arith_var(table, x));
510
  table->tag[x] |= AVARTAG_MARK_MASK;
285,608✔
511
}
285,608✔
512

513
static inline void clear_arith_var_mark(arith_vartable_t *table, thvar_t x) {
285,608✔
514
  assert(valid_arith_var(table, x));
515
  table->tag[x] &= ~AVARTAG_MARK_MASK;
285,608✔
516
}
285,608✔
517

518
static inline void set_arith_var_lb(arith_vartable_t *table, thvar_t x) {
807,938✔
519
  assert(valid_arith_var(table, x));
520
  table->tag[x] |= AVARTAG_ATLB_MASK;
807,938✔
521
}
807,938✔
522

523
static inline void clear_arith_var_lb(arith_vartable_t *table, thvar_t x) {
1,081,350✔
524
  assert(valid_arith_var(table, x));
525
  table->tag[x] &= ~AVARTAG_ATLB_MASK;
1,081,350✔
526
}
1,081,350✔
527

528
static inline void set_arith_var_ub(arith_vartable_t *table, thvar_t x) {
680,637✔
529
  assert(valid_arith_var(table, x));
530
  table->tag[x] |= AVARTAG_ATUB_MASK;
680,637✔
531
}
680,637✔
532

533
static inline void clear_arith_var_ub(arith_vartable_t *table, thvar_t x) {
1,284,588✔
534
  assert(valid_arith_var(table, x));
535
  table->tag[x] &= ~AVARTAG_ATUB_MASK;
1,284,588✔
536
}
1,284,588✔
537

538

539
// set the full tag
540
static inline void set_arith_var_tag(arith_vartable_t *table, thvar_t x, uint8_t tg) {
24,403✔
541
  assert(valid_arith_var(table, x));
542
  table->tag[x] = tg;
24,403✔
543
}
24,403✔
544

545

546

547

548

549

550
/*
551
 * ETERM AND ATOMS
552
 */
553

554
/*
555
 * Attach eterm t to variable x
556
 * - x must not have an existing eterm attached
557
 */
558
extern void attach_eterm_to_arith_var(arith_vartable_t *table, thvar_t x, eterm_t t);
559

560

561
/*
562
 * Check whether there's at least one variable with an attached eterm in table
563
 */
564
extern bool arith_vartable_has_eterms(arith_vartable_t *table);
565

566

567
/*
568
 * Check whether x has an eterm attached
569
 */
570
static inline bool arith_var_has_eterm(arith_vartable_t *table, thvar_t x) {
868,792✔
571
  assert(valid_arith_var(table, x));
572
  return table->eterm != NULL && table->eterm[x] != null_eterm;
868,792✔
573
}
574

575
/*
576
 * Get the eterm attached to x
577
 * - x must have an eterm attached
578
 */
579
static inline eterm_t arith_var_eterm(arith_vartable_t *table, thvar_t x) {
42,302✔
580
  assert(arith_var_has_eterm(table, x));
581
  return table->eterm[x];
42,302✔
582
}
583

584

585
/*
586
 * Variant: get the eterm attached to x or null_eterm if x has no eterm attached
587
 */
588
static inline eterm_t arith_var_get_eterm(arith_vartable_t *table, thvar_t x) {
2,013,620✔
589
  eterm_t t;
590

591
  assert(valid_arith_var(table, x));
592
  t = null_eterm;
2,013,620✔
593
  if (table->eterm != NULL) {
2,013,620✔
594
    t = table->eterm[x];
2,000,915✔
595
  }
596

597
  return t;
2,013,620✔
598
}
599

600

601
/*
602
 * Add atom index i to the vector atoms[x]
603
 * - x must be the variable of atom i
604
 * - i must not be already present in atoms[x]
605
 */
606
extern void attach_atom_to_arith_var(arith_vartable_t *table, thvar_t x, int32_t i);
607

608

609
/*
610
 * Remove i from the vector atoms[x]
611
 * - x must be the variable of atom i
612
 * - i must be present in atoms[x]
613
 */
614
extern void detach_atom_from_arith_var(arith_vartable_t *table, thvar_t x, int32_t i);
615

616

617

618

619
/*
620
 * ASSIGNMENT AND BOUNDS
621
 */
622

623
/*
624
 * Set value[x] to d
625
 */
626
static inline void set_arith_var_value(arith_vartable_t *table, thvar_t x, xrational_t *d) {
627
  assert(valid_arith_var(table, x));
628
  xq_set(table->value + x, d);
629
}
630

631

632
/*
633
 * Check whether value[x] is an integer
634
 */
635
static inline bool arith_var_value_is_int(arith_vartable_t *table, thvar_t x) {
608,616✔
636
  assert(valid_arith_var(table, x));
637
  return xq_is_integer(table->value + x);
608,616✔
638
}
639

640

641
/*
642
 * Round value[x] up to the nearest integer
643
 */
644
static inline void set_arith_var_value_to_ceil(arith_vartable_t *table, thvar_t x) {
645
  assert(valid_arith_var(table, x));
646
  xq_ceil(table->value + x);
647
}
648

649

650
/*
651
 * Round value[x] down to the nearest integer
652
 */
653
static inline void set_arith_var_value_to_floor(arith_vartable_t *table, thvar_t x) {
654
  assert(valid_arith_var(table, x));
655
  xq_floor(table->value + x);
656
}
657

658

659

660

661
/*
662
 * Set upper_index/lower_index indices for x
663
 */
664
static inline void set_arith_var_lower_index(arith_vartable_t *table, thvar_t x, int32_t i) {
2,084,412✔
665
  assert(valid_arith_var(table, x));
666
  table->lower_index[x] = i;
2,084,412✔
667
}
2,084,412✔
668

669
static inline void set_arith_var_upper_index(arith_vartable_t *table, thvar_t x, int32_t i) {
2,172,954✔
670
  assert(valid_arith_var(table, x));
671
  table->upper_index[x] = i;
2,172,954✔
672
}
2,172,954✔
673

674

675
#endif /* __ARITH_VARTABLE_H */
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

© 2025 Coveralls, Inc