mirror of
https://github.com/Z3Prover/z3
synced 2025-05-08 00:05:46 +00:00
running updates to bv_solver (#4674)
* na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * dbg Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * bv Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * drat and fresh Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * move ackerman functionality Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * debugability Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * towards debugability Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * missing file Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * remove csp Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
4d1a2a2784
commit
d02b0cde7a
63 changed files with 3060 additions and 3095 deletions
|
@ -20,43 +20,21 @@ Revision History:
|
|||
#undef max
|
||||
#undef min
|
||||
#include "sat/sat_solver.h"
|
||||
|
||||
namespace {
|
||||
struct lex_error {};
|
||||
|
||||
class stream_buffer {
|
||||
std::istream & m_stream;
|
||||
int m_val;
|
||||
unsigned m_line;
|
||||
public:
|
||||
|
||||
stream_buffer(std::istream & s):
|
||||
m_stream(s),
|
||||
m_line(0) {
|
||||
m_val = m_stream.get();
|
||||
}
|
||||
|
||||
int operator *() const {
|
||||
return m_val;
|
||||
}
|
||||
|
||||
void operator ++() {
|
||||
m_val = m_stream.get();
|
||||
if (m_val == '\n') ++m_line;
|
||||
}
|
||||
|
||||
unsigned line() const { return m_line; }
|
||||
};
|
||||
#include "sat/sat_drat.h"
|
||||
|
||||
template<typename Buffer>
|
||||
void skip_whitespace(Buffer & in) {
|
||||
while ((*in >= 9 && *in <= 13) || *in == 32) {
|
||||
++in;
|
||||
}
|
||||
static bool is_whitespace(Buffer & in) {
|
||||
return (*in >= 9 && *in <= 13) || *in == 32;
|
||||
}
|
||||
|
||||
template<typename Buffer>
|
||||
void skip_line(Buffer & in) {
|
||||
static void skip_whitespace(Buffer & in) {
|
||||
while (is_whitespace(in))
|
||||
++in;
|
||||
}
|
||||
|
||||
template<typename Buffer>
|
||||
static void skip_line(Buffer & in) {
|
||||
while(true) {
|
||||
if (*in == EOF) {
|
||||
return;
|
||||
|
@ -70,7 +48,7 @@ void skip_line(Buffer & in) {
|
|||
}
|
||||
|
||||
template<typename Buffer>
|
||||
int parse_int(Buffer & in, std::ostream& err) {
|
||||
static int parse_int(Buffer & in, std::ostream& err) {
|
||||
int val = 0;
|
||||
bool neg = false;
|
||||
skip_whitespace(in);
|
||||
|
@ -84,8 +62,11 @@ int parse_int(Buffer & in, std::ostream& err) {
|
|||
}
|
||||
|
||||
if (*in < '0' || *in > '9') {
|
||||
err << "(error, \"unexpected char: " << *in << " line: " << in.line() << "\")\n";
|
||||
throw lex_error();
|
||||
if (20 <= *in && *in < 128)
|
||||
err << "(error, \"unexpected char: " << ((char)*in) << " line: " << in.line() << "\")\n";
|
||||
else
|
||||
err << "(error, \"unexpected char: " << *in << " line: " << in.line() << "\")\n";
|
||||
throw dimacs::lex_error();
|
||||
}
|
||||
|
||||
while (*in >= '0' && *in <= '9') {
|
||||
|
@ -97,7 +78,7 @@ int parse_int(Buffer & in, std::ostream& err) {
|
|||
}
|
||||
|
||||
template<typename Buffer>
|
||||
void read_clause(Buffer & in, std::ostream& err, sat::solver & solver, sat::literal_vector & lits) {
|
||||
static void read_clause(Buffer & in, std::ostream& err, sat::solver & solver, sat::literal_vector & lits) {
|
||||
int parsed_lit;
|
||||
int var;
|
||||
|
||||
|
@ -116,7 +97,24 @@ void read_clause(Buffer & in, std::ostream& err, sat::solver & solver, sat::lite
|
|||
}
|
||||
|
||||
template<typename Buffer>
|
||||
bool parse_dimacs_core(Buffer & in, std::ostream& err, sat::solver & solver) {
|
||||
static void read_clause(Buffer & in, std::ostream& err, sat::literal_vector & lits) {
|
||||
int parsed_lit;
|
||||
int var;
|
||||
|
||||
lits.reset();
|
||||
|
||||
while (true) {
|
||||
parsed_lit = parse_int(in, err);
|
||||
if (parsed_lit == 0)
|
||||
break;
|
||||
var = abs(parsed_lit);
|
||||
SASSERT(var > 0);
|
||||
lits.push_back(sat::literal(var, parsed_lit < 0));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Buffer>
|
||||
static bool parse_dimacs_core(Buffer & in, std::ostream& err, sat::solver & solver) {
|
||||
sat::literal_vector lits;
|
||||
try {
|
||||
while (true) {
|
||||
|
@ -133,15 +131,158 @@ bool parse_dimacs_core(Buffer & in, std::ostream& err, sat::solver & solver) {
|
|||
}
|
||||
}
|
||||
}
|
||||
catch (lex_error) {
|
||||
catch (dimacs::lex_error) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool parse_dimacs(std::istream & in, std::ostream& err, sat::solver & solver) {
|
||||
stream_buffer _in(in);
|
||||
dimacs::stream_buffer _in(in);
|
||||
return parse_dimacs_core(_in, err, solver);
|
||||
}
|
||||
|
||||
|
||||
namespace dimacs {
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, drat_record const& r) {
|
||||
switch (r.m_tag) {
|
||||
case drat_record::tag_t::is_clause:
|
||||
return out << r.m_status << " " << r.m_lits << "\n";
|
||||
case drat_record::tag_t::is_node:
|
||||
return out << "e " << r.m_node_id << " " << r.m_name << " " << r.m_args << "\n";
|
||||
case drat_record::is_bool_def:
|
||||
return out << "b " << r.m_node_id << " " << r.m_args << "\n";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
char const* drat_parser::parse_identifier() {
|
||||
m_buffer.reset();
|
||||
while (!is_whitespace(in)) {
|
||||
m_buffer.push_back(*in);
|
||||
++in;
|
||||
}
|
||||
m_buffer.push_back(0);
|
||||
return m_buffer.c_ptr();
|
||||
}
|
||||
|
||||
char const* drat_parser::parse_sexpr() {
|
||||
m_buffer.reset();
|
||||
unsigned lp = 0;
|
||||
while (!is_whitespace(in) || lp > 0) {
|
||||
m_buffer.push_back(*in);
|
||||
if (*in == '(')
|
||||
++lp;
|
||||
else if (*in == ')') {
|
||||
if (lp == 0) {
|
||||
throw lex_error();
|
||||
}
|
||||
else --lp;
|
||||
}
|
||||
++in;
|
||||
}
|
||||
m_buffer.push_back(0);
|
||||
return m_buffer.c_ptr();
|
||||
}
|
||||
|
||||
int drat_parser::read_theory_id() {
|
||||
skip_whitespace(in);
|
||||
if ('a' <= *in && *in <= 'z') {
|
||||
if (!m_read_theory_id)
|
||||
throw lex_error();
|
||||
return m_read_theory_id(parse_identifier());
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool drat_parser::next() {
|
||||
int n, b, e, theory_id;
|
||||
try {
|
||||
loop:
|
||||
skip_whitespace(in);
|
||||
switch (*in) {
|
||||
case EOF:
|
||||
return false;
|
||||
case 'c':
|
||||
case 'p':
|
||||
skip_line(in);
|
||||
goto loop;
|
||||
case 'i':
|
||||
++in;
|
||||
skip_whitespace(in);
|
||||
read_clause(in, err, m_record.m_lits);
|
||||
m_record.m_tag = drat_record::tag_t::is_clause;
|
||||
m_record.m_status = sat::status::input();
|
||||
break;
|
||||
case 'a':
|
||||
++in;
|
||||
skip_whitespace(in);
|
||||
theory_id = read_theory_id();
|
||||
skip_whitespace(in);
|
||||
read_clause(in, err, m_record.m_lits);
|
||||
m_record.m_tag = drat_record::tag_t::is_clause;
|
||||
m_record.m_status = sat::status::th(false, theory_id);
|
||||
break;
|
||||
case 'e':
|
||||
++in;
|
||||
skip_whitespace(in);
|
||||
n = parse_int(in, err);
|
||||
skip_whitespace(in);
|
||||
m_record.m_name = parse_sexpr();
|
||||
m_record.m_tag = drat_record::tag_t::is_node;
|
||||
m_record.m_node_id = n;
|
||||
m_record.m_args.reset();
|
||||
while (true) {
|
||||
n = parse_int(in, err);
|
||||
if (n == 0)
|
||||
break;
|
||||
if (n < 0)
|
||||
throw lex_error();
|
||||
m_record.m_args.push_back(n);
|
||||
}
|
||||
break;
|
||||
case 'b':
|
||||
++in;
|
||||
skip_whitespace(in);
|
||||
b = parse_int(in, err);
|
||||
n = parse_int(in, err);
|
||||
e = parse_int(in, err);
|
||||
if (e != 0)
|
||||
throw lex_error();
|
||||
m_record.m_tag = drat_record::tag_t::is_bool_def;
|
||||
m_record.m_node_id = b;
|
||||
m_record.m_args.reset();
|
||||
m_record.m_args.push_back(n);
|
||||
break;
|
||||
case 'd':
|
||||
++in;
|
||||
skip_whitespace(in);
|
||||
read_clause(in, err, m_record.m_lits);
|
||||
m_record.m_tag = drat_record::tag_t::is_clause;
|
||||
m_record.m_status = sat::status::deleted();
|
||||
break;
|
||||
case 'r':
|
||||
++in;
|
||||
skip_whitespace(in);
|
||||
theory_id = read_theory_id();
|
||||
read_clause(in, err, m_record.m_lits);
|
||||
m_record.m_tag = drat_record::tag_t::is_clause;
|
||||
m_record.m_status = sat::status::th(true, theory_id);
|
||||
break;
|
||||
default:
|
||||
read_clause(in, err, m_record.m_lits);
|
||||
m_record.m_tag = drat_record::tag_t::is_clause;
|
||||
m_record.m_status = sat::status::redundant();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (lex_error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue