diff --git a/src/api/api_opt.cpp b/src/api/api_opt.cpp index ac11e1a33..0d96a6719 100644 --- a/src/api/api_opt.cpp +++ b/src/api/api_opt.cpp @@ -16,17 +16,19 @@ Revision History: --*/ #include +#include "util/cancel_eh.h" +#include "util/file_path.h" +#include "util/scoped_timer.h" +#include "parsers/smt2/smt2parser.h" +#include "opt/opt_context.h" +#include "opt/opt_cmds.h" +#include "opt/opt_parse.h" #include "api/z3.h" #include "api/api_log_macros.h" #include "api/api_stats.h" #include "api/api_context.h" #include "api/api_util.h" #include "api/api_model.h" -#include "opt/opt_context.h" -#include "opt/opt_cmds.h" -#include "util/cancel_eh.h" -#include "util/scoped_timer.h" -#include "parsers/smt2/smt2parser.h" #include "api/api_ast_vector.h" extern "C" { @@ -281,16 +283,27 @@ extern "C" { static void Z3_optimize_from_stream( Z3_context c, Z3_optimize opt, - std::istream& s) { - ast_manager& m = mk_c(c)->m(); + std::istream& s, + char const* ext) { + ast_manager& m = mk_c(c)->m(); + if (ext && std::string("opb") == ext) { + unsigned_vector h; + parse_opb(*to_optimize_ptr(opt), s, h); + return; + } + if (ext && std::string("wcnf") == ext) { + unsigned_vector h; + parse_wcnf(*to_optimize_ptr(opt), s, h); + return; + } scoped_ptr ctx = alloc(cmd_context, false, &m); install_opt_cmds(*ctx.get(), to_optimize_ptr(opt)); - ctx->set_ignore_check(true); std::stringstream errstrm; ctx->set_regular_stream(errstrm); + ctx->set_ignore_check(true); try { if (!parse_smt2_commands(*ctx.get(), s)) { - mk_c(c)->m_parser_error_buffer = errstrm.str(); + mk_c(c)->m_parser_error_buffer = errstrm.str(); ctx = nullptr; SET_ERROR_CODE(Z3_PARSER_ERROR); return; @@ -303,6 +316,7 @@ extern "C" { SET_ERROR_CODE(Z3_PARSER_ERROR); return; } + ptr_vector::const_iterator it = ctx->begin_assertions(); ptr_vector::const_iterator end = ctx->end_assertions(); for (; it != end; ++it) { @@ -310,6 +324,8 @@ extern "C" { } } + + void Z3_API Z3_optimize_from_string( Z3_context c, Z3_optimize d, @@ -318,7 +334,7 @@ extern "C" { //LOG_Z3_optimize_from_string(c, d, s); std::string str(s); std::istringstream is(str); - Z3_optimize_from_stream(c, d, is); + Z3_optimize_from_stream(c, d, is, nullptr); Z3_CATCH; } @@ -334,7 +350,7 @@ extern "C" { strm << "Could not open file " << s; throw default_exception(strm.str()); } - Z3_optimize_from_stream(c, d, is); + Z3_optimize_from_stream(c, d, is, get_extension(s)); Z3_CATCH; } @@ -347,8 +363,8 @@ extern "C" { mk_c(c)->save_object(v); expr_ref_vector hard(mk_c(c)->m()); to_optimize_ptr(o)->get_hard_constraints(hard); - for (unsigned i = 0; i < hard.size(); i++) { - v->m_ast_vector.push_back(hard[i].get()); + for (expr* h : hard) { + v->m_ast_vector.push_back(h); } RETURN_Z3(of_ast_vector(v)); Z3_CATCH_RETURN(0); diff --git a/src/api/api_solver.cpp b/src/api/api_solver.cpp index 2030c5210..0a0039f4c 100644 --- a/src/api/api_solver.cpp +++ b/src/api/api_solver.cpp @@ -28,11 +28,17 @@ Revision History: #include "solver/tactic2solver.h" #include "util/scoped_ctrl_c.h" #include "util/cancel_eh.h" +#include "util/file_path.h" #include "util/scoped_timer.h" #include "tactic/portfolio/smt_strategic_solver.h" #include "smt/smt_solver.h" #include "smt/smt_implied_equalities.h" #include "solver/smt_logics.h" +#include "cmd_context/cmd_context.h" +#include "parsers/smt2/smt2parser.h" +#include "sat/dimacs.h" +#include "sat/sat_solver.h" +#include "sat/tactic/goal2sat.h" extern "C" { @@ -121,6 +127,63 @@ extern "C" { Z3_CATCH_RETURN(0); } + void solver_from_stream(Z3_context c, Z3_solver s, std::istream& is) { + scoped_ptr ctx = alloc(cmd_context, false, &(mk_c(c)->m())); + ctx->set_ignore_check(true); + + if (!parse_smt2_commands(*ctx.get(), is)) { + ctx = nullptr; + SET_ERROR_CODE(Z3_PARSER_ERROR); + return; + } + + bool initialized = to_solver(s)->m_solver.get() != 0; + if (!initialized) + init_solver(c, s); + ptr_vector::const_iterator it = ctx->begin_assertions(); + ptr_vector::const_iterator end = ctx->end_assertions(); + for (; it != end; ++it) { + to_solver_ref(s)->assert_expr(*it); + } + // to_solver_ref(s)->set_model_converter(ctx->get_model_converter()); + } + + void Z3_API Z3_solver_from_string(Z3_context c, Z3_solver s, Z3_string c_str) { + Z3_TRY; + LOG_Z3_solver_from_string(c, s, c_str); + std::string str(c_str); + std::istringstream is(str); + solver_from_stream(c, s, is); + Z3_CATCH; + } + + void Z3_API Z3_solver_from_file(Z3_context c, Z3_solver s, Z3_string file_name) { + Z3_TRY; + LOG_Z3_solver_from_file(c, s, file_name); + char const* ext = get_extension(file_name); + std::ifstream is(file_name); + if (!is) { + SET_ERROR_CODE(Z3_FILE_ACCESS_ERROR); + } + else if (ext && std::string("dimacs") == ext) { + ast_manager& m = to_solver_ref(s)->get_manager(); + sat::solver solver(to_solver_ref(s)->get_params(), m.limit(), nullptr); + parse_dimacs(is, solver); + sat2goal s2g; + model_converter_ref mc; + atom2bool_var a2b(m); + goal g(m); + s2g(solver, a2b, to_solver_ref(s)->get_params(), g, mc); + for (unsigned i = 0; i < g.size(); ++i) { + to_solver_ref(s)->assert_expr(g.form(i)); + } + } + else { + solver_from_stream(c, s, is); + } + Z3_CATCH; + } + Z3_string Z3_API Z3_solver_get_help(Z3_context c, Z3_solver s) { Z3_TRY; LOG_Z3_solver_get_help(c, s); diff --git a/src/api/c++/z3++.h b/src/api/c++/z3++.h index 236750bdf..d8087c4ee 100644 --- a/src/api/c++/z3++.h +++ b/src/api/c++/z3++.h @@ -1536,6 +1536,35 @@ namespace z3 { m_vector = s.m_vector; return *this; } + bool contains(T const& x) const { + for (auto y : *this) if (eq(x, y)) return true; + return false; + } + + class iterator { + ast_vector_tpl const* m_vector; + unsigned m_index; + public: + iterator(ast_vector_tpl const* v, unsigned i): m_vector(v), m_index(i) {} + iterator(iterator& other): m_vector(other.m_vector), m_index(other.m_index) {} + iterator operator=(iterator const& other) { m_vector = other.m_vector; m_index = other.m_index; return *this; } + + bool operator==(iterator const& other) { + return other.m_index == m_index; + }; + bool operator!=(iterator const& other) { + return other.m_index != m_index; + }; + iterator& operator++() { + ++m_index; + return *this; + } + iterator operator++(int) { iterator tmp = *this; ++m_index; return tmp; } + T * operator->() const { return &(operator*()); } + T operator*() const { return (*m_vector)[m_index]; } + }; + iterator begin() const { return iterator(this, 0); } + iterator end() const { return iterator(this, size()); } friend std::ostream & operator<<(std::ostream & out, ast_vector_tpl const & v) { out << Z3_ast_vector_to_string(v.ctx(), v); return out; } }; @@ -1911,6 +1940,11 @@ namespace z3 { return *this; } void set(params const & p) { Z3_solver_set_params(ctx(), m_solver, p); check_error(); } + void set(char const * k, bool v) { params p(ctx()); p.set(k, v); set(p); } + void set(char const * k, unsigned v) { params p(ctx()); p.set(k, v); set(p); } + void set(char const * k, double v) { params p(ctx()); p.set(k, v); set(p); } + void set(char const * k, symbol const & v) { params p(ctx()); p.set(k, v); set(p); } + void set(char const * k, char const* v) { params p(ctx()); p.set(k, v); set(p); } void push() { Z3_solver_push(ctx(), m_solver); check_error(); } void pop(unsigned n = 1) { Z3_solver_pop(ctx(), m_solver, n); check_error(); } void reset() { Z3_solver_reset(ctx(), m_solver); check_error(); } @@ -1923,6 +1957,10 @@ namespace z3 { void add(expr const & e, char const * p) { add(e, ctx().bool_const(p)); } + void add(expr_vector const& v) { check_context(*this, v); for (expr e : v) add(e); } + void from_file(char const* file) { Z3_solver_from_file(ctx(), m_solver, file); ctx().check_parser_error(); } + void from_string(char const* s) { Z3_solver_from_string(ctx(), m_solver, s); ctx().check_parser_error(); } + check_result check() { Z3_lbool r = Z3_solver_check(ctx(), m_solver); check_error(); return to_check_result(r); } check_result check(unsigned n, expr * const assumptions) { array _assumptions(n); @@ -2003,6 +2041,7 @@ namespace z3 { return *this; } void add(expr const & f) { check_context(*this, f); Z3_goal_assert(ctx(), m_goal, f); check_error(); } + void add(expr_vector const& v) { check_context(*this, v); for (expr e : v) add(e); } unsigned size() const { return Z3_goal_size(ctx(), m_goal); } expr operator[](int i) const { assert(0 <= i); Z3_ast r = Z3_goal_formula(ctx(), m_goal, i); check_error(); return expr(ctx(), r); } Z3_goal_prec precision() const { return Z3_goal_precision(ctx(), m_goal); } diff --git a/src/api/dotnet/Params.cs b/src/api/dotnet/Params.cs index 23b037c78..37d73d5b1 100644 --- a/src/api/dotnet/Params.cs +++ b/src/api/dotnet/Params.cs @@ -31,98 +31,108 @@ namespace Microsoft.Z3 /// /// Adds a parameter setting. /// - public void Add(Symbol name, bool value) + public Params Add(Symbol name, bool value) { Contract.Requires(name != null); Native.Z3_params_set_bool(Context.nCtx, NativeObject, name.NativeObject, (value) ? 1 : 0); + return this; } /// /// Adds a parameter setting. /// - public void Add(Symbol name, uint value) + public Params Add(Symbol name, uint value) { Contract.Requires(name != null); Native.Z3_params_set_uint(Context.nCtx, NativeObject, name.NativeObject, value); + return this; } /// /// Adds a parameter setting. /// - public void Add(Symbol name, double value) + public Params Add(Symbol name, double value) { - Contract.Requires(name != null); - + Contract.Requires(name != null); + Native.Z3_params_set_double(Context.nCtx, NativeObject, name.NativeObject, value); + return this; } /// /// Adds a parameter setting. /// - public void Add(Symbol name, string value) + public Params Add(Symbol name, string value) { Contract.Requires(value != null); Native.Z3_params_set_symbol(Context.nCtx, NativeObject, name.NativeObject, Context.MkSymbol(value).NativeObject); + return this; } /// /// Adds a parameter setting. /// - public void Add(Symbol name, Symbol value) + public Params Add(Symbol name, Symbol value) { Contract.Requires(name != null); Contract.Requires(value != null); Native.Z3_params_set_symbol(Context.nCtx, NativeObject, name.NativeObject, value.NativeObject); + return this; } /// /// Adds a parameter setting. /// - public void Add(string name, bool value) + public Params Add(string name, bool value) { Native.Z3_params_set_bool(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, (value) ? 1 : 0); + return this; } /// /// Adds a parameter setting. /// - public void Add(string name, uint value) + public Params Add(string name, uint value) { Native.Z3_params_set_uint(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, value); + return this; } /// /// Adds a parameter setting. /// - public void Add(string name, double value) + public Params Add(string name, double value) { Native.Z3_params_set_double(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, value); + return this; } /// /// Adds a parameter setting. /// - public void Add(string name, Symbol value) + public Params Add(string name, Symbol value) { Contract.Requires(value != null); Native.Z3_params_set_symbol(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, value.NativeObject); + return this; } /// /// Adds a parameter setting. /// - public void Add(string name, string value) + public Params Add(string name, string value) { Contract.Requires(name != null); Contract.Requires(value != null); Native.Z3_params_set_symbol(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, Context.MkSymbol(value).NativeObject); + return this; } /// diff --git a/src/api/dotnet/Solver.cs b/src/api/dotnet/Solver.cs index dff2677df..a176e790b 100644 --- a/src/api/dotnet/Solver.cs +++ b/src/api/dotnet/Solver.cs @@ -57,6 +57,49 @@ namespace Microsoft.Z3 } } + /// + /// Sets parameter on the solver + /// + public void Set(string name, bool value) { Parameters = Context.MkParams().Add(name, value); } + /// + /// Sets parameter on the solver + /// + public void Set(string name, uint value) { Parameters = Context.MkParams().Add(name, value); } + /// + /// Sets parameter on the solver + /// + public void Set(string name, double value) { Parameters = Context.MkParams().Add(name, value); } + /// + /// Sets parameter on the solver + /// + public void Set(string name, string value) { Parameters = Context.MkParams().Add(name, value); } + /// + /// Sets parameter on the solver + /// + public void Set(string name, Symbol value) { Parameters = Context.MkParams().Add(name, value); } + /// + /// Sets parameter on the solver + /// + public void Set(Symbol name, bool value) { Parameters = Context.MkParams().Add(name, value); } + /// + /// Sets parameter on the solver + /// + public void Set(Symbol name, uint value) { Parameters = Context.MkParams().Add(name, value); } + /// + /// Sets parameter on the solver + /// + public void Set(Symbol name, double value) { Parameters = Context.MkParams().Add(name, value); } + /// + /// Sets parameter on the solver + /// + public void Set(Symbol name, string value) { Parameters = Context.MkParams().Add(name, value); } + /// + /// Sets parameter on the solver + /// + public void Set(Symbol name, Symbol value) { Parameters = Context.MkParams().Add(name, value); } + + + /// /// Retrieves parameter descriptions for solver. /// @@ -140,11 +183,11 @@ namespace Microsoft.Z3 /// using the Boolean constants in ps. /// /// - /// This API is an alternative to with assumptions for extracting unsat cores. + /// This API is an alternative to with assumptions for extracting unsat cores. /// Both APIs can be used in the same solver. The unsat core will contain a combination /// of the Boolean variables provided using /// and the Boolean literals - /// provided using with assumptions. + /// provided using with assumptions. /// public void AssertAndTrack(BoolExpr[] constraints, BoolExpr[] ps) { @@ -165,11 +208,11 @@ namespace Microsoft.Z3 /// using the Boolean constant p. /// /// - /// This API is an alternative to with assumptions for extracting unsat cores. + /// This API is an alternative to with assumptions for extracting unsat cores. /// Both APIs can be used in the same solver. The unsat core will contain a combination /// of the Boolean variables provided using /// and the Boolean literals - /// provided using with assumptions. + /// provided using with assumptions. /// public void AssertAndTrack(BoolExpr constraint, BoolExpr p) { @@ -181,6 +224,22 @@ namespace Microsoft.Z3 Native.Z3_solver_assert_and_track(Context.nCtx, NativeObject, constraint.NativeObject, p.NativeObject); } + /// + /// Load solver assertions from a file. + /// + public void FromFile(string file) + { + Native.Z3_solver_from_file(Context.nCtx, NativeObject, file); + } + + /// + /// Load solver assertions from a string. + /// + public void FromString(string str) + { + Native.Z3_solver_from_string(Context.nCtx, NativeObject, str); + } + /// /// The number of assertions in the solver. /// @@ -225,6 +284,25 @@ namespace Microsoft.Z3 return lboolToStatus(r); } + /// + /// Checks whether the assertions in the solver are consistent or not. + /// + /// + /// + /// + /// + /// + public Status Check(IEnumerable assumptions) + { + Z3_lbool r; + BoolExpr[] asms = assumptions.ToArray(); + if (asms.Length == 0) + r = (Z3_lbool)Native.Z3_solver_check(Context.nCtx, NativeObject); + else + r = (Z3_lbool)Native.Z3_solver_check_assumptions(Context.nCtx, NativeObject, (uint)asms.Length, AST.ArrayToNative(asms)); + return lboolToStatus(r); + } + /// /// Retrieve fixed assignments to the set of variables in the form of consequences. /// Each consequence is an implication of the form diff --git a/src/api/java/Solver.java b/src/api/java/Solver.java index 19f3b01da..5bd4e65ba 100644 --- a/src/api/java/Solver.java +++ b/src/api/java/Solver.java @@ -1,3 +1,4 @@ + /** Copyright (c) 2012-2014 Microsoft Corporation @@ -120,6 +121,23 @@ public class Solver extends Z3Object { } } + /** + * Load solver assertions from a file. + */ + public void fromFile(String file) + { + Native.solverFromFile(getContext().nCtx(), getNativeObject(), file); + } + + /** + * Load solver assertions from a string. + */ + public void fromString(String str) + { + Native.solverFromString(getContext().nCtx(), getNativeObject(), str); + } + + /** * Assert multiple constraints into the solver, and track them (in the * unsat) core diff --git a/src/api/python/z3/z3.py b/src/api/python/z3/z3.py index 2304491c8..237f35433 100644 --- a/src/api/python/z3/z3.py +++ b/src/api/python/z3/z3.py @@ -6324,6 +6324,20 @@ class Solver(Z3PPObject): sz = len(consequences) consequences = [ consequences[i] for i in range(sz) ] return CheckSatResult(r), consequences + + def from_file(self, filename): + """Parse assertions from a file""" + try: + Z3_solver_from_file(self.ctx.ref(), self.solver, filename) + except Z3Exception as e: + _handle_parse_error(e, self.ctx) + + def from_string(self, s): + """Parse assertions from a string""" + try: + Z3_solver_from_string(self.ctx.ref(), self.solver, s) + except Z3Exception as e: + _handle_parse_error(e, self.ctx) def proof(self): """Return a proof for the last `check()`. Proof construction must be enabled.""" diff --git a/src/api/z3_api.h b/src/api/z3_api.h index d620254d1..064476b9b 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -6038,6 +6038,20 @@ extern "C" { */ Z3_ast_vector Z3_API Z3_solver_get_assertions(Z3_context c, Z3_solver s); + /** + \brief load solver assertions from a file. + + def_API('Z3_solver_from_file', VOID, (_in(CONTEXT), _in(SOLVER), _in(STRING))) + */ + void Z3_API Z3_solver_from_file(Z3_context c, Z3_solver s, Z3_string file_name); + + /** + \brief load solver assertions from a string. + + def_API('Z3_solver_from_string', VOID, (_in(CONTEXT), _in(SOLVER), _in(STRING))) + */ + void Z3_API Z3_solver_from_string(Z3_context c, Z3_solver s, Z3_string file_name); + /** \brief Check whether the assertions in a given solver are consistent or not. diff --git a/src/opt/CMakeLists.txt b/src/opt/CMakeLists.txt index 05a62b6c2..28a14be2e 100644 --- a/src/opt/CMakeLists.txt +++ b/src/opt/CMakeLists.txt @@ -6,6 +6,7 @@ z3_add_component(opt opt_cmds.cpp opt_context.cpp opt_pareto.cpp + opt_parse.cpp optsmt.cpp opt_solver.cpp pb_sls.cpp diff --git a/src/shell/main.cpp b/src/shell/main.cpp index 8b719681c..f0e640d66 100644 --- a/src/shell/main.cpp +++ b/src/shell/main.cpp @@ -35,6 +35,7 @@ Revision History: #include "util/error_codes.h" #include "util/gparams.h" #include "util/env_params.h" +#include "util/file_path.h" #include "shell/lp_frontend.h" typedef enum { IN_UNSPECIFIED, IN_SMTLIB_2, IN_DATALOG, IN_DIMACS, IN_WCNF, IN_OPB, IN_Z3_LOG, IN_MPS } input_kind; @@ -286,19 +287,6 @@ void parse_cmd_line_args(int argc, char ** argv) { } } -char const * get_extension(char const * file_name) { - if (file_name == 0) - return 0; - char const * last_dot = 0; - for (;;) { - char const * tmp = strchr(file_name, '.'); - if (tmp == 0) { - return last_dot; - } - last_dot = tmp + 1; - file_name = last_dot; - } -} int STD_CALL main(int argc, char ** argv) { try{ diff --git a/src/shell/opt_frontend.cpp b/src/shell/opt_frontend.cpp index e1aff8669..8154cbde4 100644 --- a/src/shell/opt_frontend.cpp +++ b/src/shell/opt_frontend.cpp @@ -13,6 +13,7 @@ Copyright (c) 2015 Microsoft Corporation #include "util/gparams.h" #include "util/timeout.h" #include "ast/reg_decl_plugins.h" +#include "opt/opt_parse.h" extern bool g_display_statistics; static bool g_first_interrupt = true; @@ -20,262 +21,6 @@ static opt::context* g_opt = 0; static double g_start_time = 0; static unsigned_vector g_handles; -class opt_stream_buffer { - std::istream & m_stream; - int m_val; - unsigned m_line; -public: - opt_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(); } - int ch() const { return m_val; } - void next() { m_val = m_stream.get(); } - bool eof() const { return ch() == EOF; } - unsigned line() const { return m_line; } - void skip_whitespace() { - while ((ch() >= 9 && ch() <= 13) || ch() == 32) { - if (ch() == 10) ++m_line; - next(); - } - } - void skip_space() { - while (ch() != 10 && ((ch() >= 9 && ch() <= 13) || ch() == 32)) { - next(); - } - } - void skip_line() { - while(true) { - if (eof()) { - return; - } - if (ch() == '\n') { - ++m_line; - next(); - return; - } - next(); - } - } - - bool parse_token(char const* token) { - skip_whitespace(); - char const* t = token; - while (ch() == *t) { - next(); - ++t; - } - return 0 == *t; - } - - int parse_int() { - int val = 0; - bool neg = false; - skip_whitespace(); - - if (ch() == '-') { - neg = true; - next(); - } - else if (ch() == '+') { - next(); - } - if (ch() < '0' || ch() > '9') { - std::cerr << "(error line " << line() << " \"unexpected char: " << ((char)ch()) << "\" )\n"; - exit(3); - } - while (ch() >= '0' && ch() <= '9') { - val = val*10 + (ch() - '0'); - next(); - } - return neg ? -val : val; - } - - unsigned parse_unsigned() { - skip_space(); - if (ch() == '\n') { - return UINT_MAX; - } - unsigned val = 0; - while (ch() >= '0' && ch() <= '9') { - val = val*10 + (ch() - '0'); - next(); - } - return val; - } -}; - -class wcnf { - opt::context& opt; - ast_manager& m; - opt_stream_buffer& in; - - app_ref read_clause(unsigned& weight) { - int parsed_lit; - int var; - weight = in.parse_unsigned(); - app_ref result(m), p(m); - expr_ref_vector ors(m); - while (true) { - parsed_lit = in.parse_int(); - if (parsed_lit == 0) - break; - var = abs(parsed_lit); - p = m.mk_const(symbol(var), m.mk_bool_sort()); - if (parsed_lit < 0) p = m.mk_not(p); - ors.push_back(p); - } - result = to_app(mk_or(m, ors.size(), ors.c_ptr())); - return result; - } - - void parse_spec(unsigned& num_vars, unsigned& num_clauses, unsigned& max_weight) { - in.parse_token("wcnf"); - num_vars = in.parse_unsigned(); - num_clauses = in.parse_unsigned(); - max_weight = in.parse_unsigned(); - } - -public: - - wcnf(opt::context& opt, opt_stream_buffer& in): opt(opt), m(opt.get_manager()), in(in) { - opt.set_clausal(true); - } - - void parse() { - unsigned num_vars = 0, num_clauses = 0, max_weight = 0; - while (true) { - in.skip_whitespace(); - if (in.eof()) { - break; - } - else if (*in == 'c') { - in.skip_line(); - } - else if (*in == 'p') { - ++in; - parse_spec(num_vars, num_clauses, max_weight); - } - else { - unsigned weight = 0; - app_ref cls = read_clause(weight); - if (weight >= max_weight) { - opt.add_hard_constraint(cls); - } - else { - unsigned id = opt.add_soft_constraint(cls, rational(weight), symbol::null); - if (g_handles.empty()) { - g_handles.push_back(id); - } - } - } - } - } -}; - - -class opb { - opt::context& opt; - ast_manager& m; - opt_stream_buffer& in; - arith_util arith; - - app_ref parse_id() { - bool negated = in.parse_token("~"); - if (!in.parse_token("x")) { - std::cerr << "(error line " << in.line() << " \"unexpected char: " << ((char)in.ch()) << "\")\n"; - exit(3); - } - app_ref p(m); - int id = in.parse_int(); - p = m.mk_const(symbol(id), m.mk_bool_sort()); - if (negated) p = m.mk_not(p); - in.skip_whitespace(); - return p; - } - - app_ref parse_ids() { - app_ref result = parse_id(); - while (*in == '~' || *in == 'x') { - result = m.mk_and(result, parse_id()); - } - return result; - } - - rational parse_coeff_r() { - in.skip_whitespace(); - svector num; - bool pos = true; - if (*in == '-') pos = false, ++in; - if (*in == '+') ++in; - if (!pos) num.push_back('-'); - in.skip_whitespace(); - while ('0' <= *in && *in <='9') num.push_back(*in), ++in; - num.push_back(0); - return rational(num.c_ptr()); - } - - app_ref parse_coeff() { - return app_ref(arith.mk_numeral(parse_coeff_r(), true), m); - } - - app_ref parse_term() { - app_ref c = parse_coeff(); - app_ref e = parse_ids(); - return app_ref(m.mk_ite(e, c, arith.mk_numeral(rational(0), true)), m); - } - - void parse_objective() { - app_ref t = parse_term(); - while (!in.parse_token(";") && !in.eof()) { - t = arith.mk_add(t, parse_term()); - } - g_handles.push_back(opt.add_objective(t, false)); - } - - void parse_constraint() { - app_ref t = parse_term(); - while (!in.eof()) { - if (in.parse_token(">=")) { - t = arith.mk_ge(t, parse_coeff()); - in.parse_token(";"); - break; - } - if (in.parse_token("=")) { - t = m.mk_eq(t, parse_coeff()); - in.parse_token(";"); - break; - } - t = arith.mk_add(t, parse_term()); - } - opt.add_hard_constraint(t); - } -public: - opb(opt::context& opt, opt_stream_buffer& in): - opt(opt), m(opt.get_manager()), - in(in), arith(m) {} - - void parse() { - while (true) { - in.skip_whitespace(); - if (in.eof()) { - break; - } - else if (*in == '*') { - in.skip_line(); - } - else if (in.parse_token("min:")) { - parse_objective(); - } - else { - parse_constraint(); - } - } - } -}; static void display_results() { @@ -335,14 +80,11 @@ static unsigned parse_opt(std::istream& in, bool is_wcnf) { g_opt = &opt; params_ref p = gparams::get_module("opt"); opt.updt_params(p); - opt_stream_buffer _in(in); if (is_wcnf) { - wcnf wcnf(opt, _in); - wcnf.parse(); + parse_wcnf(opt, in, g_handles); } else { - opb opb(opt, _in); - opb.parse(); + parse_opb(opt, in, g_handles); } try { lbool r = opt.optimize(); diff --git a/src/util/file_path.h b/src/util/file_path.h new file mode 100644 index 000000000..8a2d053d8 --- /dev/null +++ b/src/util/file_path.h @@ -0,0 +1,38 @@ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + file_path.h + +Abstract: + + File path functions. + +Author: + + Nikolaj Bjorner (nbjorner) 2017-11-19 + +Revision History: + +--*/ +#ifndef FILE_PATH_H_ +#define FILE_PATH_H_ + +inline char const * get_extension(char const * file_name) { + if (file_name == 0) + return 0; + char const * last_dot = 0; + for (;;) { + char const * tmp = strchr(file_name, '.'); + if (tmp == 0) { + return last_dot; + } + last_dot = tmp + 1; + file_name = last_dot; + } +} + +#endif /* FILE_PATH_H_ */ + +