3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-22 16:45:31 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2018-11-17 15:05:02 -08:00
commit ee7781e602
16 changed files with 330 additions and 147 deletions

View file

@ -183,8 +183,12 @@ extern "C" {
}
else if (ext && std::string("dimacs") == ext) {
ast_manager& m = to_solver_ref(s)->get_manager();
std::stringstream err;
sat::solver solver(to_solver_ref(s)->get_params(), m.limit());
parse_dimacs(is, solver);
if (!parse_dimacs(is, err, solver)) {
SET_ERROR_CODE(Z3_PARSER_ERROR, err.str().c_str());
return;
}
sat2goal s2g;
ref<sat2goal::mc> mc;
atom2bool_var a2b(m);

View file

@ -5579,7 +5579,7 @@ extern "C" {
\brief Convert a goal into a DIMACS formatted string.
The goal must be in CNF. You can convert a goal to CNF
by applying the tseitin-cnf tactic. Bit-vectors are not automatically
converted to Booleans either, so the caller intends to
converted to Booleans either, so if the caller intends to
preserve satisfiability, it should apply bit-blasting tactics.
Quantifiers and theory atoms will not be encoded.

View file

@ -561,6 +561,7 @@ br_status seq_rewriter::mk_seq_extract(expr* a, expr* b, expr* c, expr_ref& resu
zstring s;
rational pos, len;
TRACE("seq", tout << mk_pp(a, m()) << " " << mk_pp(b, m()) << " " << mk_pp(c, m()) << "\n";);
bool constantBase = m_util.str.is_string(a, s);
bool constantPos = m_autil.is_numeral(b, pos);
bool constantLen = m_autil.is_numeral(c, len);
@ -599,6 +600,10 @@ br_status seq_rewriter::mk_seq_extract(expr* a, expr* b, expr* c, expr_ref& resu
SASSERT(_len > 0);
expr_ref_vector as(m()), bs(m());
m_util.str.get_concat(a, as);
if (as.empty()) {
result = a;
return BR_DONE;
}
for (unsigned i = 0; i < as.size() && _len > 0; ++i) {
if (m_util.str.is_unit(as[i].get())) {
if (_pos == 0) {
@ -613,7 +618,12 @@ br_status seq_rewriter::mk_seq_extract(expr* a, expr* b, expr* c, expr_ref& resu
return BR_FAILED;
}
}
result = m_util.str.mk_concat(bs);
if (bs.empty()) {
result = m_util.str.mk_empty(m().get_sort(a));
}
else {
result = m_util.str.mk_concat(bs);
}
return BR_DONE;
}

View file

@ -899,7 +899,7 @@ bool seq_decl_plugin::are_distinct(app* a, app* b) const {
}
if (is_app_of(a, m_family_id, OP_SEQ_UNIT) &&
is_app_of(b, m_family_id, OP_SEQ_UNIT)) {
return true;
return m_manager->are_distinct(a->get_arg(0), b->get_arg(0));
}
if (is_app_of(a, m_family_id, OP_SEQ_EMPTY) &&
is_app_of(b, m_family_id, OP_SEQ_UNIT)) {

View file

@ -346,7 +346,8 @@ namespace smt2 {
// consume garbage
// return true if managed to recover from the error...
bool sync_after_error() {
while (true) {
unsigned num_errors = 0;
while (num_errors < 100) {
try {
while (curr_is_rparen())
next();
@ -374,8 +375,10 @@ namespace smt2 {
catch (scanner_exception & ex) {
SASSERT(ex.has_pos());
error(ex.line(), ex.pos(), ex.msg());
++num_errors;
}
}
return false;
}
void check_next(scanner::token t, char const * msg) {
@ -3117,7 +3120,7 @@ namespace smt2 {
bool operator()() {
m_num_bindings = 0;
bool found_errors = false;
unsigned found_errors = 0;
try {
scan_core();
@ -3126,7 +3129,7 @@ namespace smt2 {
error(ex.msg());
if (!sync_after_error())
return false;
found_errors = true;
found_errors++;
}
while (true) {
@ -3138,7 +3141,7 @@ namespace smt2 {
parse_cmd();
break;
case scanner::EOF_TOKEN:
return !found_errors;
return found_errors == 0;
default:
throw parser_exception("invalid command, '(' expected");
break;

View file

@ -21,6 +21,8 @@ Revision History:
#undef min
#include "sat/sat_solver.h"
struct lex_error {};
class stream_buffer {
std::istream & m_stream;
int m_val;
@ -67,7 +69,7 @@ void skip_line(Buffer & in) {
}
template<typename Buffer>
int parse_int(Buffer & in) {
int parse_int(Buffer & in, std::ostream& err) {
int val = 0;
bool neg = false;
skip_whitespace(in);
@ -81,9 +83,8 @@ int parse_int(Buffer & in) {
}
if (*in < '0' || *in > '9') {
std::cerr << "(error, \"unexpected char: " << *in << " line: " << in.line() << "\")\n";
exit(3);
exit(ERR_PARSER);
err << "(error, \"unexpected char: " << *in << " line: " << in.line() << "\")\n";
throw lex_error();
}
while (*in >= '0' && *in <= '9') {
@ -95,14 +96,14 @@ int parse_int(Buffer & in) {
}
template<typename Buffer>
void read_clause(Buffer & in, sat::solver & solver, sat::literal_vector & lits) {
void read_clause(Buffer & in, std::ostream& err, sat::solver & solver, sat::literal_vector & lits) {
int parsed_lit;
int var;
lits.reset();
while (true) {
parsed_lit = parse_int(in);
parsed_lit = parse_int(in, err);
if (parsed_lit == 0)
break;
var = abs(parsed_lit);
@ -114,24 +115,30 @@ void read_clause(Buffer & in, sat::solver & solver, sat::literal_vector & lits)
}
template<typename Buffer>
void parse_dimacs_core(Buffer & in, sat::solver & solver) {
bool parse_dimacs_core(Buffer & in, std::ostream& err, sat::solver & solver) {
sat::literal_vector lits;
while (true) {
skip_whitespace(in);
if (*in == EOF) {
break;
}
else if (*in == 'c' || *in == 'p') {
skip_line(in);
}
else {
read_clause(in, solver, lits);
solver.mk_clause(lits.size(), lits.c_ptr());
try {
while (true) {
skip_whitespace(in);
if (*in == EOF) {
break;
}
else if (*in == 'c' || *in == 'p') {
skip_line(in);
}
else {
read_clause(in, err, solver, lits);
solver.mk_clause(lits.size(), lits.c_ptr());
}
}
}
catch (lex_error) {
return false;
}
return true;
}
void parse_dimacs(std::istream & in, sat::solver & solver) {
bool parse_dimacs(std::istream & in, std::ostream& err, sat::solver & solver) {
stream_buffer _in(in);
parse_dimacs_core(_in, solver);
return parse_dimacs_core(_in, err, solver);
}

View file

@ -21,7 +21,7 @@ Revision History:
#include "sat/sat_types.h"
void parse_dimacs(std::istream & s, sat::solver & solver);
bool parse_dimacs(std::istream & s, std::ostream& err, sat::solver & solver);
#endif /* DIMACS_PARSER_H_ */

View file

@ -136,7 +136,7 @@ void verify_solution(char const * file_name) {
std::cerr << "(error \"failed to open file '" << file_name << "'\")" << std::endl;
exit(ERR_OPEN_FILE);
}
parse_dimacs(in, solver);
parse_dimacs(in, std::cerr, solver);
sat::model const & m = g_solver->get_model();
for (unsigned i = 1; i < m.size(); i++) {
@ -178,10 +178,10 @@ unsigned read_dimacs(char const * file_name) {
std::cerr << "(error \"failed to open file '" << file_name << "'\")" << std::endl;
exit(ERR_OPEN_FILE);
}
parse_dimacs(in, solver);
parse_dimacs(in, std::cerr, solver);
}
else {
parse_dimacs(std::cin, solver);
parse_dimacs(std::cin, std::cerr, solver);
}
IF_VERBOSE(20, solver.display_status(verbose_stream()););

View file

@ -238,10 +238,10 @@ static void cnf_backbones(bool use_chunk, char const* file_name) {
std::cerr << "(error \"failed to open file '" << file_name << "'\")" << std::endl;
exit(ERR_OPEN_FILE);
}
parse_dimacs(in, solver);
if (!parse_dimacs(in, std::cerr, solver)) return;
}
else {
parse_dimacs(std::cin, solver);
if (!parse_dimacs(std::cin, std::cerr, solver)) return;
}
IF_VERBOSE(20, solver.display_status(verbose_stream()););

View file

@ -34,7 +34,8 @@ void tst_sat_lookahead(char ** argv, int argc, int& i) {
std::cerr << "(error \"failed to open file '" << file_name << "'\")" << std::endl;
exit(ERR_OPEN_FILE);
}
parse_dimacs(in, solver);
if (!parse_dimacs(in, std::cerr, solver))
return;
}
sat::lookahead lh(solver);