Skip to content

Commit e5bf7c1

Browse files
author
Joe Hendrix
committed
mcarith push/pop support.
1 parent 80a4c28 commit e5bf7c1

File tree

3 files changed

+87
-32
lines changed

3 files changed

+87
-32
lines changed

src/context/context.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5360,9 +5360,7 @@ static void create_mcarith_solver(context_t *ctx) {
53605360

53615361
// row saving must be enabled unless we're in ONECHECK mode
53625362
if (ctx->mode != CTX_MODE_ONECHECK) {
5363-
longjmp(ctx->env, INTERNAL_ERROR);
5364-
5365-
// simplex_enable_row_saving(solver);
5363+
simplex_enable_row_saving(solver);
53665364
}
53675365

53685366
if (ctx->egraph != NULL) {

src/solvers/mcarith/mcarith.c

Lines changed: 79 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@
3434

3535
#include "yices.h"
3636

37-
extern void simplex_attach_eterm(simplex_solver_t *solver, thvar_t v, eterm_t t);
38-
extern thvar_t simplex_create_const(simplex_solver_t *solver, rational_t *q);
39-
extern eterm_t simplex_eterm_of_var(simplex_solver_t *solver, thvar_t v);
40-
extern void simplex_start_internalization(simplex_solver_t *solver);
37+
void simplex_attach_eterm(simplex_solver_t *solver, thvar_t v, eterm_t t);
38+
thvar_t simplex_create_const(simplex_solver_t *solver, rational_t *q);
39+
eterm_t simplex_eterm_of_var(simplex_solver_t *solver, thvar_t v);
40+
void simplex_start_internalization(simplex_solver_t *solver);
4141
void simplex_assert_clause_vareq_axiom(simplex_solver_t *solver, uint32_t n, literal_t *c, thvar_t x, thvar_t y);
4242
void simplex_assert_cond_vareq_axiom(simplex_solver_t *solver, literal_t c, thvar_t x, thvar_t y);
4343

@@ -182,7 +182,7 @@ static void mcarith_undo_push_record(mcarith_undo_stack_t* stack, uint32_t n_a)
182182
}
183183

184184
/*
185-
* Push an undo record to the stack.
185+
* Pop an undo record to the stack.
186186
*/
187187
static mcarith_undo_record_t* mcarith_undo_pop_record(mcarith_undo_stack_t* stack) {
188188
assert(stack->top > 0);
@@ -273,6 +273,10 @@ struct mcarith_solver_s {
273273
mcarith_undo_stack_t undo_stack;
274274
};
275275

276+
void mcarith_enable_row_saving(mcarith_solver_t *solver) {
277+
simplex_enable_row_saving(&solver->simplex);
278+
}
279+
276280
#ifdef MCSAT_STANDALONE_TERMS
277281
static
278282
pprod_table_t* mcarith_solver_pprods(mcarith_solver_t* s) {
@@ -430,11 +434,12 @@ term_t get_term(mcarith_solver_t* solver, thvar_t v) {
430434
arith_vartable_t* table;
431435
term_table_t* terms;
432436

433-
terms = mcarith_solver_terms(solver);
434437

435438
table = &solver->simplex.vtbl;
436439
assert(0 <= v && v < table->nvars);
437440

441+
terms = mcarith_solver_terms(solver);
442+
438443
term_t t = solver->var_terms[v];
439444
if (t != NULL_TERM) return t;
440445

@@ -763,17 +768,15 @@ thvar_t mcarith_create_rdiv(void *s, thvar_t num, thvar_t den) {
763768
static
764769
mcarith_assertion_t* alloc_top_assertion(mcarith_solver_t* s) {
765770
size_t cnt = s->assertion_count;
766-
if (cnt < s->assertion_capacity) {
767-
++s->assertion_count;
768-
return s->assertions + cnt;
769-
} else {
771+
if (cnt >= s->assertion_capacity) {
770772
assert(cnt == s->assertion_capacity);
771773
s->assertion_capacity = 2 * s->assertion_capacity;
772774
if (s->assertion_capacity == 0)
773775
out_of_memory();
774776
s->assertions = safe_realloc(s->assertions, s->assertion_capacity * sizeof(mcarith_assertion_t));
775-
return s->assertions + cnt;
776777
}
778+
s->assertion_count = cnt + 1;
779+
return s->assertions + cnt;
777780
}
778781

779782
/********************************
@@ -840,27 +843,51 @@ void init_rba_buffer_from_poly(mcarith_solver_t* solver,
840843
* Check for integer feasibility
841844
*/
842845
static
843-
fcheck_code_t mcarith_final_check(mcarith_solver_t *solver) {
846+
fcheck_code_t mcarith_final_check(void* s) {
847+
mcarith_solver_t *solver;
848+
term_table_t* terms;
849+
uint32_t acnt;
850+
851+
852+
solver = s;
853+
terms = mcarith_solver_terms(solver);
854+
855+
yices_pp_t printer;
856+
pp_area_t area;
857+
858+
area.width = 72;
859+
area.height = 8;
860+
area.offset = 2;
861+
area.stretch = false;
862+
area.truncate = true;
863+
864+
init_default_yices_pp(&printer, stdout, &area);
865+
844866
mcarith_free_mcsat(solver);
845867

846868
const bool qflag = false; // Quantifiers not allowed
847-
term_table_t* terms = mcarith_solver_terms(solver);
848869
init_context(&solver->mcsat_ctx, terms, QF_NRA, CTX_MODE_ONECHECK, CTX_ARCH_MCSAT, qflag);
849870
solver->mcsat = mcsat_new(&solver->mcsat_ctx);
850871

851-
term_t* assertions = safe_malloc(sizeof(term_t) * (solver->assertion_count + 1));
852-
literal_t* literals = safe_malloc(sizeof(literal_t) * (solver->assertion_count + 1));
872+
acnt = solver->assertion_count;
873+
term_t* assertions = safe_malloc(sizeof(term_t) * (acnt + 1));
874+
literal_t* literals = safe_malloc(sizeof(literal_t) * acnt);
853875
size_t literal_count = 0;
854876
mcarith_check_var_size(solver);
855-
for (size_t i = 0; i < solver->assertion_count; ++i) {
877+
for (size_t i = 0; i < acnt; ++i) {
856878
mcarith_assertion_t* a = solver->assertions + i;
857879

858880
rba_buffer_t b;
859881
term_t p;
860882
switch (a->type) {
861-
case VAR_EQ:
862-
p = arith_bineq_atom(terms, get_term(solver, a->def.eq.lhs), get_term(solver, a->def.eq.rhs));
883+
case VAR_EQ: {
884+
term_t lhs;
885+
term_t rhs;
886+
lhs = get_term(solver, a->def.eq.lhs);
887+
rhs = get_term(solver, a->def.eq.rhs);
888+
p = arith_bineq_atom(terms, lhs, rhs);
863889
break;
890+
}
864891
case VAR_EQ0:
865892
p = arith_eq_atom(terms, get_term(solver, a->def.var));
866893
break;
@@ -890,10 +917,9 @@ fcheck_code_t mcarith_final_check(mcarith_solver_t *solver) {
890917
}
891918
assertions[i] = a->tt ? p : not_term(terms, p);
892919
}
893-
assertions[solver->assertion_count] = assertions[solver->assertion_count-1];
894920
literals[literal_count] = end_clause;
895921

896-
int32_t r = mcsat_assert_formulas(solver->mcsat, solver->assertion_count+1, assertions);
922+
int32_t r = mcsat_assert_formulas(solver->mcsat, acnt, assertions);
897923
fcheck_code_t result;
898924
if (r == TRIVIALLY_UNSAT) {
899925
record_theory_conflict(solver->simplex.core, literals);
@@ -971,7 +997,6 @@ void mcarith_backtrack(mcarith_solver_t *solver, uint32_t back_level) {
971997
* Start a new base level
972998
*/
973999
static void mcarith_push(mcarith_solver_t *solver) {
974-
assert(0);
9751000
simplex_push(&solver->simplex);
9761001
mcarith_undo_push_record(&solver->undo_stack, solver->assertion_count);
9771002
}
@@ -980,11 +1005,23 @@ static void mcarith_push(mcarith_solver_t *solver) {
9801005
* Return to the previous base level
9811006
*/
9821007
void mcarith_pop(mcarith_solver_t *solver) {
1008+
uint32_t vc;
1009+
uint32_t vc0;
1010+
term_t* t;
1011+
term_t* end;
1012+
mcarith_undo_record_t* r;
9831013
// Reset assertions
984-
mcarith_undo_record_t* r = mcarith_undo_pop_record(&solver->undo_stack);
1014+
r = mcarith_undo_pop_record(&solver->undo_stack);
9851015
mcarith_backtrack_assertions(solver, r->n_assertions);
9861016
// Pop simplex state
1017+
vc = solver->simplex.vtbl.nvars;
9871018
simplex_pop(&solver->simplex);
1019+
vc0 = solver->simplex.vtbl.nvars;
1020+
1021+
end = solver->var_terms + vc;
1022+
for (t = solver->var_terms + vc0; t != end; ++t) {
1023+
*t = NULL_TERM;
1024+
}
9881025
}
9891026

9901027
/*
@@ -1007,7 +1044,7 @@ static th_ctrl_interface_t mcarith_control = {
10071044
.start_internalization = (start_intern_fun_t) mcarith_start_internalization,
10081045
.start_search = (start_fun_t) mcarith_start_search,
10091046
.propagate = (propagate_fun_t) mcarith_propagate,
1010-
.final_check = (final_check_fun_t) mcarith_final_check,
1047+
.final_check = mcarith_final_check,
10111048
.increase_decision_level = (increase_level_fun_t) mcarith_increase_decision_level,
10121049
.backtrack = (backtrack_fun_t) mcarith_backtrack,
10131050
.push = (push_fun_t) mcarith_push,
@@ -1074,6 +1111,16 @@ static th_smt_interface_t mcarith_smt = {
10741111
.end_atom_deletion = NULL,
10751112
};
10761113

1114+
static const uint32_t theory_var_verb = 5;
1115+
1116+
static
1117+
thvar_t mcarith_create_const(void* s, rational_t *q) {
1118+
mcarith_solver_t *solver;
1119+
1120+
solver = s;
1121+
return simplex_create_const(&solver->simplex, q);
1122+
}
1123+
10771124
/*
10781125
* Create a theory variable equal to p
10791126
* - arith_map maps variables of p to corresponding theory variables
@@ -1231,7 +1278,8 @@ static void mcarith_build_model(void* s) {
12311278
assert(solver->mcsat);
12321279
assert(!solver->model);
12331280
// Create model
1234-
model = yices_new_model();
1281+
model = safe_malloc(sizeof(model_t));
1282+
init_model(model, mcarith_solver_terms(solver), true);
12351283
mcsat_build_model(solver->mcsat, model);
12361284
solver->model = model;
12371285

@@ -1242,10 +1290,12 @@ static void mcarith_build_model(void* s) {
12421290
* Free the model
12431291
*/
12441292
static void mcarith_free_model(void* s) {
1245-
mcarith_solver_t* solver = s;
1246-
assert(solver->model);
1293+
mcarith_solver_t* solver;
12471294

1248-
yices_free_model(solver->model);
1295+
solver = s;
1296+
assert(solver->model);
1297+
delete_model(solver->model);
1298+
free(solver->model);
12491299
solver->model = 0;
12501300
}
12511301

@@ -1280,6 +1330,7 @@ bool mcarith_value_in_model(void* s, thvar_t x, arithval_in_model_t* res) {
12801330
vtbl = model_get_vtbl(mdl);
12811331
if (object_is_rational(vtbl, v)) {
12821332
q_set(&res->val.q, vtbl_rational(vtbl, v));
1333+
return true;
12831334
} else if (object_is_algebraic(vtbl, v)) {
12841335
lp_algebraic_number_t* n = vtbl_algebraic_number(vtbl, v);
12851336
q_clear(&res->val.q);
@@ -1300,7 +1351,7 @@ bool mcarith_value_in_model(void* s, thvar_t x, arithval_in_model_t* res) {
13001351

13011352
static arith_interface_t mcarith_context = {
13021353
.create_var = (create_arith_var_fun_t) simplex_create_var,
1303-
.create_const = (create_arith_const_fun_t) simplex_create_const,
1354+
.create_const = mcarith_create_const,
13041355
.create_poly = mcarith_create_poly,
13051356
.create_pprod = mcarith_create_pprod,
13061357
.create_rdiv = mcarith_create_rdiv,

src/solvers/mcarith/mcarith.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,14 @@ typedef struct mcarith_solver_s mcarith_solver_t;
3737
*/
3838
extern void init_mcarith_solver(mcarith_solver_t **solver, context_t* ctx);
3939

40+
/*
41+
* Enable row saving (to support push/pop/multiple checks)
42+
* - must be done before any assertions
43+
*/
44+
void mcarith_enable_row_saving(mcarith_solver_t *solver);
45+
4046
/**
41-
*
47+
*
4248
*/
4349
extern void destroy_mcarith_solver(mcarith_solver_t* solver);
4450

0 commit comments

Comments
 (0)