mirror of
https://github.com/Z3Prover/z3
synced 2025-04-12 20:18:18 +00:00
merge with master
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
commit
03ed33ac02
|
@ -2106,6 +2106,7 @@ namespace test_mapi
|
||||||
Console.WriteLine("OK, model: {0}", s.Model.ToString());
|
Console.WriteLine("OK, model: {0}", s.Model.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void TranslationExample()
|
public static void TranslationExample()
|
||||||
{
|
{
|
||||||
Context ctx1 = new Context();
|
Context ctx1 = new Context();
|
||||||
|
|
|
@ -1482,7 +1482,7 @@ class JavaExample
|
||||||
BoolExpr ca = commAxiom(ctx, g);
|
BoolExpr ca = commAxiom(ctx, g);
|
||||||
|
|
||||||
BoolExpr thm = ctx.parseSMTLIB2String(
|
BoolExpr thm = ctx.parseSMTLIB2String(
|
||||||
"(assert (forall ((x Int) (y Int)) (=> (= x y) (= (gg x 0) (gg 0 y)))))",
|
"(declare-fun (Int Int) Int) (assert (forall ((x Int) (y Int)) (=> (= x y) (= (gg x 0) (gg 0 y)))))",
|
||||||
null, null, new Symbol[] { ctx.mkSymbol("gg") },
|
null, null, new Symbol[] { ctx.mkSymbol("gg") },
|
||||||
new FuncDecl[] { g })[0];
|
new FuncDecl[] { g })[0];
|
||||||
System.out.println("formula: " + thm);
|
System.out.println("formula: " + thm);
|
||||||
|
@ -2303,7 +2303,7 @@ class JavaExample
|
||||||
p.simplifierExample(ctx);
|
p.simplifierExample(ctx);
|
||||||
p.finiteDomainExample(ctx);
|
p.finiteDomainExample(ctx);
|
||||||
p.floatingPointExample1(ctx);
|
p.floatingPointExample1(ctx);
|
||||||
p.floatingPointExample2(ctx);
|
// core dumps: p.floatingPointExample2(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // These examples need proof generation turned on.
|
{ // These examples need proof generation turned on.
|
||||||
|
@ -2314,7 +2314,7 @@ class JavaExample
|
||||||
p.proveExample2(ctx);
|
p.proveExample2(ctx);
|
||||||
p.arrayExample2(ctx);
|
p.arrayExample2(ctx);
|
||||||
p.tupleExample(ctx);
|
p.tupleExample(ctx);
|
||||||
p.parserExample3(ctx);
|
// throws p.parserExample3(ctx);
|
||||||
p.enumExample(ctx);
|
p.enumExample(ctx);
|
||||||
p.listExample(ctx);
|
p.listExample(ctx);
|
||||||
p.treeExample(ctx);
|
p.treeExample(ctx);
|
||||||
|
|
|
@ -2777,25 +2777,25 @@ namespace Microsoft.Z3
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create an at-most-k constraint.
|
/// Create an at-most-k constraint.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BoolExpr MkAtMost(BoolExpr[] args, uint k)
|
public BoolExpr MkAtMost(IEnumerable<BoolExpr> args, uint k)
|
||||||
{
|
{
|
||||||
Contract.Requires(args != null);
|
Contract.Requires(args != null);
|
||||||
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
|
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
|
||||||
CheckContextMatch<BoolExpr>(args);
|
CheckContextMatch<BoolExpr>(args);
|
||||||
return new BoolExpr(this, Native.Z3_mk_atmost(nCtx, (uint) args.Length,
|
return new BoolExpr(this, Native.Z3_mk_atmost(nCtx, (uint) args.Count(),
|
||||||
AST.ArrayToNative(args), k));
|
AST.EnumToNative(args), k));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create an at-least-k constraint.
|
/// Create an at-least-k constraint.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BoolExpr MkAtLeast(BoolExpr[] args, uint k)
|
public BoolExpr MkAtLeast(IEnumerable<BoolExpr> args, uint k)
|
||||||
{
|
{
|
||||||
Contract.Requires(args != null);
|
Contract.Requires(args != null);
|
||||||
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
|
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
|
||||||
CheckContextMatch<BoolExpr>(args);
|
CheckContextMatch<BoolExpr>(args);
|
||||||
return new BoolExpr(this, Native.Z3_mk_atleast(nCtx, (uint) args.Length,
|
return new BoolExpr(this, Native.Z3_mk_atleast(nCtx, (uint) args.Count(),
|
||||||
AST.ArrayToNative(args), k));
|
AST.EnumToNative(args), k));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -91,11 +91,11 @@ public class Model extends Z3Object {
|
||||||
return null;
|
return null;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!Native.isAsArray(getContext().nCtx(), n))
|
if (Native.isAsArray(getContext().nCtx(), n)) {
|
||||||
throw new Z3Exception(
|
long fd = Native.getAsArrayFuncDecl(getContext().nCtx(), n);
|
||||||
"Argument was not an array constant");
|
return getFuncInterp(new FuncDecl(getContext(), fd));
|
||||||
long fd = Native.getAsArrayFuncDecl(getContext().nCtx(), n);
|
}
|
||||||
return getFuncInterp(new FuncDecl(getContext(), fd));
|
return null;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
|
|
|
@ -354,6 +354,8 @@ public:
|
||||||
MATCH_BINARY(is_bv_mul);
|
MATCH_BINARY(is_bv_mul);
|
||||||
MATCH_BINARY(is_bv_sle);
|
MATCH_BINARY(is_bv_sle);
|
||||||
MATCH_BINARY(is_bv_ule);
|
MATCH_BINARY(is_bv_ule);
|
||||||
|
MATCH_BINARY(is_bv_ashr);
|
||||||
|
MATCH_BINARY(is_bv_lshr);
|
||||||
MATCH_BINARY(is_bv_shl);
|
MATCH_BINARY(is_bv_shl);
|
||||||
MATCH_BINARY(is_bv_urem);
|
MATCH_BINARY(is_bv_urem);
|
||||||
MATCH_BINARY(is_bv_srem);
|
MATCH_BINARY(is_bv_srem);
|
||||||
|
|
|
@ -92,7 +92,7 @@ func_decl * pb_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, p
|
||||||
}
|
}
|
||||||
|
|
||||||
void pb_decl_plugin::get_op_names(svector<builtin_name> & op_names, symbol const & logic) {
|
void pb_decl_plugin::get_op_names(svector<builtin_name> & op_names, symbol const & logic) {
|
||||||
if (logic == symbol::null || logic == "QF_FD" || logic == "ALL") {
|
if (logic == symbol::null || logic == "QF_FD" || logic == "ALL" || logic == "HORN") {
|
||||||
op_names.push_back(builtin_name(m_at_most_sym.bare_str(), OP_AT_MOST_K));
|
op_names.push_back(builtin_name(m_at_most_sym.bare_str(), OP_AT_MOST_K));
|
||||||
op_names.push_back(builtin_name(m_at_least_sym.bare_str(), OP_AT_LEAST_K));
|
op_names.push_back(builtin_name(m_at_least_sym.bare_str(), OP_AT_LEAST_K));
|
||||||
op_names.push_back(builtin_name(m_pble_sym.bare_str(), OP_PB_LE));
|
op_names.push_back(builtin_name(m_pble_sym.bare_str(), OP_PB_LE));
|
||||||
|
|
|
@ -59,7 +59,7 @@ public:
|
||||||
if (c == nullptr) {
|
if (c == nullptr) {
|
||||||
std::string err_msg("unknown command '");
|
std::string err_msg("unknown command '");
|
||||||
err_msg = err_msg + s.bare_str() + "'";
|
err_msg = err_msg + s.bare_str() + "'";
|
||||||
throw cmd_exception(err_msg);
|
throw cmd_exception(std::move(err_msg));
|
||||||
}
|
}
|
||||||
m_cmds.push_back(s);
|
m_cmds.push_back(s);
|
||||||
}
|
}
|
||||||
|
@ -384,7 +384,7 @@ class set_option_cmd : public set_get_option_cmd {
|
||||||
std::string msg = "error setting '";
|
std::string msg = "error setting '";
|
||||||
msg += opt_name.str();
|
msg += opt_name.str();
|
||||||
msg += "', option value cannot be modified after initialization";
|
msg += "', option value cannot be modified after initialization";
|
||||||
throw cmd_exception(msg);
|
throw cmd_exception(std::move(msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ Revision History:
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
#include "cmd_context/check_logic.h"
|
#include "cmd_context/check_logic.h"
|
||||||
|
#include "solver/smt_logics.h"
|
||||||
#include "ast/arith_decl_plugin.h"
|
#include "ast/arith_decl_plugin.h"
|
||||||
#include "ast/array_decl_plugin.h"
|
#include "ast/array_decl_plugin.h"
|
||||||
#include "ast/bv_decl_plugin.h"
|
#include "ast/bv_decl_plugin.h"
|
||||||
|
@ -453,7 +454,7 @@ struct check_logic::imp {
|
||||||
else if (fid == m_dt_util.get_family_id() && m_dt) {
|
else if (fid == m_dt_util.get_family_id() && m_dt) {
|
||||||
// nothing to check
|
// nothing to check
|
||||||
}
|
}
|
||||||
else if (fid == m_pb_util.get_family_id() && m_logic == "QF_FD") {
|
else if (fid == m_pb_util.get_family_id() && smt_logics::logic_has_pb(m_logic)) {
|
||||||
// nothing to check
|
// nothing to check
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -369,7 +369,7 @@ void stream_ref::set(char const * name) {
|
||||||
std::string msg = "failed to set output stream '";
|
std::string msg = "failed to set output stream '";
|
||||||
msg += name;
|
msg += name;
|
||||||
msg += "'";
|
msg += "'";
|
||||||
throw cmd_exception(msg);
|
throw cmd_exception(std::move(msg));
|
||||||
}
|
}
|
||||||
SASSERT(m_stream);
|
SASSERT(m_stream);
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,7 +211,7 @@ class horn_tactic : public tactic {
|
||||||
default:
|
default:
|
||||||
msg << "formula is not in Horn fragment: " << mk_pp(g->form(i), m) << "\n";
|
msg << "formula is not in Horn fragment: " << mk_pp(g->form(i), m) << "\n";
|
||||||
TRACE("horn", tout << msg.str(););
|
TRACE("horn", tout << msg.str(););
|
||||||
throw tactic_exception(msg.str().c_str());
|
throw tactic_exception(msg.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -909,7 +909,7 @@ namespace smt2 {
|
||||||
std::string err_msg = "invalid datatype declaration, unknown sort '";
|
std::string err_msg = "invalid datatype declaration, unknown sort '";
|
||||||
err_msg += missing.str();
|
err_msg += missing.str();
|
||||||
err_msg += "'";
|
err_msg += "'";
|
||||||
throw parser_exception(err_msg, line, pos);
|
throw parser_exception(std::move(err_msg), line, pos);
|
||||||
}
|
}
|
||||||
dts->commit(pm());
|
dts->commit(pm());
|
||||||
m_ctx.insert_aux_pdecl(dts.get());
|
m_ctx.insert_aux_pdecl(dts.get());
|
||||||
|
@ -989,7 +989,7 @@ namespace smt2 {
|
||||||
std::string err_msg = "invalid datatype declaration, unknown sort '";
|
std::string err_msg = "invalid datatype declaration, unknown sort '";
|
||||||
err_msg += missing.str();
|
err_msg += missing.str();
|
||||||
err_msg += "'";
|
err_msg += "'";
|
||||||
throw parser_exception(err_msg, line, pos);
|
throw parser_exception(std::move(err_msg), line, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -999,7 +999,7 @@ namespace smt2 {
|
||||||
std::string err_msg = "invalid datatype declaration, repeated accessor identifier '";
|
std::string err_msg = "invalid datatype declaration, repeated accessor identifier '";
|
||||||
err_msg += duplicated.str();
|
err_msg += duplicated.str();
|
||||||
err_msg += "'";
|
err_msg += "'";
|
||||||
throw parser_exception(err_msg, line, pos);
|
throw parser_exception(std::move(err_msg), line, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -844,8 +844,7 @@ namespace qe {
|
||||||
break;
|
break;
|
||||||
case l_undef:
|
case l_undef:
|
||||||
result.push_back(in.get());
|
result.push_back(in.get());
|
||||||
std::string s = "search failed";
|
throw tactic_exception("search failed");
|
||||||
throw tactic_exception(s.c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1279,7 +1279,7 @@ namespace qe {
|
||||||
if (s == "ok" || s == "unknown") {
|
if (s == "ok" || s == "unknown") {
|
||||||
s = m_fa.s().reason_unknown();
|
s = m_fa.s().reason_unknown();
|
||||||
}
|
}
|
||||||
throw tactic_exception(s.c_str());
|
throw tactic_exception(std::move(s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1344,7 +1344,7 @@ namespace qe {
|
||||||
s = m_fa.s().reason_unknown();
|
s = m_fa.s().reason_unknown();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw tactic_exception(s.c_str());
|
throw tactic_exception(std::move(s));
|
||||||
}
|
}
|
||||||
return l_true;
|
return l_true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ struct goal2sat::imp {
|
||||||
|
|
||||||
void throw_op_not_handled(std::string const& s) {
|
void throw_op_not_handled(std::string const& s) {
|
||||||
std::string s0 = "operator " + s + " not supported, apply simplifier before invoking translator";
|
std::string s0 = "operator " + s + " not supported, apply simplifier before invoking translator";
|
||||||
throw tactic_exception(s0.c_str());
|
throw tactic_exception(std::move(s0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void mk_clause(sat::literal l) {
|
void mk_clause(sat::literal l) {
|
||||||
|
|
|
@ -39,7 +39,6 @@ class smt_tactic : public tactic {
|
||||||
smt_params m_params;
|
smt_params m_params;
|
||||||
params_ref m_params_ref;
|
params_ref m_params_ref;
|
||||||
statistics m_stats;
|
statistics m_stats;
|
||||||
std::string m_failure;
|
|
||||||
smt::kernel * m_ctx;
|
smt::kernel * m_ctx;
|
||||||
symbol m_logic;
|
symbol m_logic;
|
||||||
progress_callback * m_callback;
|
progress_callback * m_callback;
|
||||||
|
@ -259,7 +258,7 @@ public:
|
||||||
if (m_fail_if_inconclusive && !m_candidate_models) {
|
if (m_fail_if_inconclusive && !m_candidate_models) {
|
||||||
std::stringstream strm;
|
std::stringstream strm;
|
||||||
strm << "smt tactic failed to show goal to be sat/unsat " << m_ctx->last_failure_as_string();
|
strm << "smt tactic failed to show goal to be sat/unsat " << m_ctx->last_failure_as_string();
|
||||||
throw tactic_exception(strm.str().c_str());
|
throw tactic_exception(strm.str());
|
||||||
}
|
}
|
||||||
result.push_back(in.get());
|
result.push_back(in.get());
|
||||||
if (m_candidate_models) {
|
if (m_candidate_models) {
|
||||||
|
@ -281,8 +280,7 @@ public:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_failure = m_ctx->last_failure_as_string();
|
throw tactic_exception(m_ctx->last_failure_as_string());
|
||||||
throw tactic_exception(m_failure.c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (rewriter_exception & ex) {
|
catch (rewriter_exception & ex) {
|
||||||
|
|
|
@ -752,9 +752,10 @@ namespace smt {
|
||||||
class theory_pb::card_justification : public justification {
|
class theory_pb::card_justification : public justification {
|
||||||
card& m_card;
|
card& m_card;
|
||||||
family_id m_fid;
|
family_id m_fid;
|
||||||
|
literal m_lit;
|
||||||
public:
|
public:
|
||||||
card_justification(card& c, family_id fid)
|
card_justification(card& c, literal lit, family_id fid)
|
||||||
: justification(true), m_card(c), m_fid(fid) {}
|
: justification(true), m_card(c), m_fid(fid), m_lit(lit) {}
|
||||||
|
|
||||||
card& get_card() { return m_card; }
|
card& get_card() { return m_card; }
|
||||||
|
|
||||||
|
@ -769,7 +770,28 @@ namespace smt {
|
||||||
return m_fid;
|
return m_fid;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual proof* mk_proof(smt::conflict_resolution& cr) { return 0; }
|
virtual proof* mk_proof(smt::conflict_resolution& cr) {
|
||||||
|
ptr_buffer<proof> prs;
|
||||||
|
ast_manager& m = cr.get_context().get_manager();
|
||||||
|
expr_ref fact(m);
|
||||||
|
cr.get_context().literal2expr(m_lit, fact);
|
||||||
|
bool all_valid = true;
|
||||||
|
proof* pr = nullptr;
|
||||||
|
pr = cr.get_proof(m_card.lit());
|
||||||
|
all_valid &= pr != nullptr;
|
||||||
|
prs.push_back(pr);
|
||||||
|
for (unsigned i = m_card.k(); i < m_card.size(); ++i) {
|
||||||
|
pr = cr.get_proof(~m_card.lit(i));
|
||||||
|
all_valid &= pr != nullptr;
|
||||||
|
prs.push_back(pr);
|
||||||
|
}
|
||||||
|
if (!all_valid) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return m.mk_th_lemma(m_fid, fact, prs.size(), prs.c_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -959,7 +981,7 @@ namespace smt {
|
||||||
m_stats.m_num_propagations++;
|
m_stats.m_num_propagations++;
|
||||||
TRACE("pb", tout << "#prop: " << c.num_propagations() << " - " << c.lit() << " => " << l << "\n";);
|
TRACE("pb", tout << "#prop: " << c.num_propagations() << " - " << c.lit() << " => " << l << "\n";);
|
||||||
SASSERT(validate_unit_propagation(c));
|
SASSERT(validate_unit_propagation(c));
|
||||||
ctx.assign(l, ctx.mk_justification(card_justification(c, get_id())));
|
ctx.assign(l, ctx.mk_justification(card_justification(c, l, get_id())));
|
||||||
}
|
}
|
||||||
|
|
||||||
void theory_pb::clear_watch(card& c) {
|
void theory_pb::clear_watch(card& c) {
|
||||||
|
|
|
@ -5036,7 +5036,7 @@ expr* theory_seq::coalesce_chars(expr* const& e) {
|
||||||
if (bvu.is_bv(s)) {
|
if (bvu.is_bv(s)) {
|
||||||
expr_ref result(m);
|
expr_ref result(m);
|
||||||
expr * args[1] = {s};
|
expr * args[1] = {s};
|
||||||
if (m_seq_rewrite.mk_app_core(to_app(e)->get_decl(), 1, args, result)) {
|
if (BR_FAILED != m_seq_rewrite.mk_app_core(to_app(e)->get_decl(), 1, args, result)) {
|
||||||
if (!ctx.e_internalized(result))
|
if (!ctx.e_internalized(result))
|
||||||
ctx.internalize(result, false);
|
ctx.internalize(result, false);
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -635,7 +635,7 @@ private:
|
||||||
t.join();
|
t.join();
|
||||||
m_manager.limit().reset_cancel();
|
m_manager.limit().reset_cancel();
|
||||||
if (m_exn_code == -1)
|
if (m_exn_code == -1)
|
||||||
throw default_exception(m_exn_msg);
|
throw default_exception(std::move(m_exn_msg));
|
||||||
if (m_exn_code != 0)
|
if (m_exn_code != 0)
|
||||||
throw z3_error(m_exn_code);
|
throw z3_error(m_exn_code);
|
||||||
if (!m_models.empty()) {
|
if (!m_models.empty()) {
|
||||||
|
|
|
@ -150,7 +150,7 @@ bool smt_logics::logic_has_horn(symbol const& s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool smt_logics::logic_has_pb(symbol const& s) {
|
bool smt_logics::logic_has_pb(symbol const& s) {
|
||||||
return s == "QF_FD" || s == "ALL";
|
return s == "QF_FD" || s == "ALL" || logic_has_horn(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool smt_logics::logic_has_datatype(symbol const& s) {
|
bool smt_logics::logic_has_datatype(symbol const& s) {
|
||||||
|
|
|
@ -968,7 +968,7 @@ private:
|
||||||
void throw_tactic(expr* e) {
|
void throw_tactic(expr* e) {
|
||||||
std::stringstream strm;
|
std::stringstream strm;
|
||||||
strm << "goal is in a fragment unsupported by pb2bv. Offending expression: " << mk_pp(e, m);
|
strm << "goal is in a fragment unsupported by pb2bv. Offending expression: " << mk_pp(e, m);
|
||||||
throw tactic_exception(strm.str().c_str());
|
throw tactic_exception(strm.str());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,9 @@ Notes:
|
||||||
#include "tactic/core/reduce_invertible_tactic.h"
|
#include "tactic/core/reduce_invertible_tactic.h"
|
||||||
#include "tactic/core/collect_occs.h"
|
#include "tactic/core/collect_occs.h"
|
||||||
#include "tactic/generic_model_converter.h"
|
#include "tactic/generic_model_converter.h"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace {
|
||||||
class reduce_invertible_tactic : public tactic {
|
class reduce_invertible_tactic : public tactic {
|
||||||
ast_manager& m;
|
ast_manager& m;
|
||||||
bv_util m_bv;
|
bv_util m_bv;
|
||||||
|
@ -60,7 +62,8 @@ public:
|
||||||
generic_model_converter_ref mc;
|
generic_model_converter_ref mc;
|
||||||
occs(*g, vars);
|
occs(*g, vars);
|
||||||
expr_safe_replace sub(m);
|
expr_safe_replace sub(m);
|
||||||
expr_ref p(m), new_v(m);
|
expr_ref new_v(m);
|
||||||
|
expr * p;
|
||||||
for (expr* v : vars) {
|
for (expr* v : vars) {
|
||||||
if (is_invertible(v, p, new_v, &mc)) {
|
if (is_invertible(v, p, new_v, &mc)) {
|
||||||
mark_inverted(p);
|
mark_inverted(p);
|
||||||
|
@ -75,8 +78,8 @@ public:
|
||||||
expr_ref f_new(m);
|
expr_ref f_new(m);
|
||||||
sub(f, f_new);
|
sub(f, f_new);
|
||||||
rw(f_new, f_new);
|
rw(f_new, f_new);
|
||||||
proof_ref new_pr(m);
|
|
||||||
if (f == f_new) continue;
|
if (f == f_new) continue;
|
||||||
|
proof_ref new_pr(m);
|
||||||
if (g->proofs_enabled()) {
|
if (g->proofs_enabled()) {
|
||||||
proof * pr = g->pr(idx);
|
proof * pr = g->pr(idx);
|
||||||
new_pr = m.mk_modus_ponens(pr, new_pr);
|
new_pr = m.mk_modus_ponens(pr, new_pr);
|
||||||
|
@ -120,11 +123,20 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// store up to two parents of expression.
|
// store one parent of expression, or null if multiple
|
||||||
struct parents {
|
struct parents {
|
||||||
parents(): m_p1(nullptr), m_p2(nullptr) {}
|
parents(): m_p(0) {}
|
||||||
expr* m_p1;
|
uintptr_t m_p;
|
||||||
expr* m_p2;
|
|
||||||
|
void set(expr * e) {
|
||||||
|
SASSERT((uintptr_t)e != 1);
|
||||||
|
if (!m_p) m_p = (uintptr_t)e;
|
||||||
|
else m_p = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
expr * get() const {
|
||||||
|
return m_p == 1 ? nullptr : (expr*)m_p;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
svector<parents> m_parents;
|
svector<parents> m_parents;
|
||||||
struct parent_collector {
|
struct parent_collector {
|
||||||
|
@ -132,9 +144,8 @@ private:
|
||||||
parent_collector(reduce_invertible_tactic& c):c(c) {}
|
parent_collector(reduce_invertible_tactic& c):c(c) {}
|
||||||
void operator()(app* n) {
|
void operator()(app* n) {
|
||||||
for (expr* arg : *n) {
|
for (expr* arg : *n) {
|
||||||
c.m_parents.reserve(arg->get_id() + 1, parents());
|
c.m_parents.reserve(arg->get_id() + 1);
|
||||||
parents& p = c.m_parents[arg->get_id()];
|
c.m_parents[arg->get_id()].set(n);
|
||||||
if (!p.m_p1) p.m_p1 = n; else p.m_p2 = n;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void operator()(expr*) {}
|
void operator()(expr*) {}
|
||||||
|
@ -156,11 +167,13 @@ private:
|
||||||
|
|
||||||
// TBD: could be made to be recursive, by walking multiple layers of parents.
|
// TBD: could be made to be recursive, by walking multiple layers of parents.
|
||||||
|
|
||||||
bool is_invertible(expr* v, expr_ref& p, expr_ref& new_v, generic_model_converter_ref* mc) {
|
bool is_invertible(expr* v, expr*& p, expr_ref& new_v, generic_model_converter_ref* mc) {
|
||||||
p = m_parents[v->get_id()].m_p1;
|
p = m_parents[v->get_id()].get();
|
||||||
if (m_parents[v->get_id()].m_p2 || !p) return false;
|
SASSERT(p);
|
||||||
|
|
||||||
if (m_inverted.is_marked(p)) return false;
|
if (m_inverted.is_marked(p)) return false;
|
||||||
if (mc && !is_ground(p)) return false;
|
if (mc && !is_ground(p)) return false;
|
||||||
|
|
||||||
if (m_bv.is_bv_add(p)) {
|
if (m_bv.is_bv_add(p)) {
|
||||||
if (mc) {
|
if (mc) {
|
||||||
ensure_mc(mc);
|
ensure_mc(mc);
|
||||||
|
@ -175,6 +188,24 @@ private:
|
||||||
new_v = v;
|
new_v = v;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr *a, *b;
|
||||||
|
// shift(a, b), where both a,b are single use. Set b = 0 and return a
|
||||||
|
// FIXME: needs to check that both variables are grounded by same quantifier
|
||||||
|
if (m_bv.is_bv_shl(p, a, b) ||
|
||||||
|
m_bv.is_bv_ashr(p, a, b) ||
|
||||||
|
m_bv.is_bv_lshr(p, a, b)) {
|
||||||
|
if (!m_parents[(v == a ? b : a)->get_id()].get())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (mc) {
|
||||||
|
ensure_mc(mc);
|
||||||
|
(*mc)->add(b, m_bv.mk_numeral(rational::zero(), get_sort(b)));
|
||||||
|
}
|
||||||
|
new_v = a;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_bv.is_bv_mul(p)) {
|
if (m_bv.is_bv_mul(p)) {
|
||||||
expr_ref rest(m);
|
expr_ref rest(m);
|
||||||
for (expr* arg : *to_app(p)) {
|
for (expr* arg : *to_app(p)) {
|
||||||
|
@ -365,7 +396,8 @@ private:
|
||||||
expr_safe_replace sub(m);
|
expr_safe_replace sub(m);
|
||||||
t.m_parents.reset();
|
t.m_parents.reset();
|
||||||
t.m_inverted.reset();
|
t.m_inverted.reset();
|
||||||
expr_ref p(m), new_v(m);
|
expr_ref new_v(m);
|
||||||
|
expr * p;
|
||||||
|
|
||||||
{
|
{
|
||||||
parent_collector proc(t);
|
parent_collector proc(t);
|
||||||
|
@ -409,11 +441,9 @@ private:
|
||||||
rewriter_tpl<reduce_q_rw_cfg>(t.m, false, m_cfg),
|
rewriter_tpl<reduce_q_rw_cfg>(t.m, false, m_cfg),
|
||||||
m_cfg(t) {}
|
m_cfg(t) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
tactic * mk_reduce_invertible_tactic(ast_manager & m, params_ref const &) {
|
tactic * mk_reduce_invertible_tactic(ast_manager & m, params_ref const &) {
|
||||||
return alloc(reduce_invertible_tactic, m);
|
return alloc(reduce_invertible_tactic, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -206,7 +206,7 @@ void fail_if_proof_generation(char const * tactic_name, goal_ref const & in) {
|
||||||
if (in->proofs_enabled()) {
|
if (in->proofs_enabled()) {
|
||||||
std::string msg = tactic_name;
|
std::string msg = tactic_name;
|
||||||
msg += " does not support proof production";
|
msg += " does not support proof production";
|
||||||
throw tactic_exception(msg.c_str());
|
throw tactic_exception(std::move(msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ void fail_if_unsat_core_generation(char const * tactic_name, goal_ref const & in
|
||||||
if (in->unsat_core_enabled()) {
|
if (in->unsat_core_enabled()) {
|
||||||
std::string msg = tactic_name;
|
std::string msg = tactic_name;
|
||||||
msg += " does not support unsat core production";
|
msg += " does not support unsat core production";
|
||||||
throw tactic_exception(msg.c_str());
|
throw tactic_exception(std::move(msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,6 +222,6 @@ void fail_if_model_generation(char const * tactic_name, goal_ref const & in) {
|
||||||
if (in->models_enabled()) {
|
if (in->models_enabled()) {
|
||||||
std::string msg = tactic_name;
|
std::string msg = tactic_name;
|
||||||
msg += " does not generate models";
|
msg += " does not generate models";
|
||||||
throw tactic_exception(msg.c_str());
|
throw tactic_exception(std::move(msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ class tactic_exception : public z3_exception {
|
||||||
protected:
|
protected:
|
||||||
std::string m_msg;
|
std::string m_msg;
|
||||||
public:
|
public:
|
||||||
tactic_exception(char const * msg):m_msg(msg) {}
|
tactic_exception(std::string && msg) : m_msg(std::move(msg)) {}
|
||||||
~tactic_exception() override {}
|
~tactic_exception() override {}
|
||||||
char const * msg() const override { return m_msg.c_str(); }
|
char const * msg() const override { return m_msg.c_str(); }
|
||||||
};
|
};
|
||||||
|
|
|
@ -463,9 +463,9 @@ public:
|
||||||
if (finished_id == UINT_MAX) {
|
if (finished_id == UINT_MAX) {
|
||||||
switch (ex_kind) {
|
switch (ex_kind) {
|
||||||
case ERROR_EX: throw z3_error(error_code);
|
case ERROR_EX: throw z3_error(error_code);
|
||||||
case TACTIC_EX: throw tactic_exception(ex_msg.c_str());
|
case TACTIC_EX: throw tactic_exception(std::move(ex_msg));
|
||||||
default:
|
default:
|
||||||
throw default_exception(ex_msg.c_str());
|
throw default_exception(std::move(ex_msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -660,9 +660,9 @@ public:
|
||||||
if (failed) {
|
if (failed) {
|
||||||
switch (ex_kind) {
|
switch (ex_kind) {
|
||||||
case ERROR_EX: throw z3_error(error_code);
|
case ERROR_EX: throw z3_error(error_code);
|
||||||
case TACTIC_EX: throw tactic_exception(ex_msg.c_str());
|
case TACTIC_EX: throw tactic_exception(std::move(ex_msg));
|
||||||
default:
|
default:
|
||||||
throw default_exception(ex_msg.c_str());
|
throw default_exception(std::move(ex_msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,8 +55,8 @@ class cmd_exception : public default_exception {
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
cmd_exception(char const * msg):default_exception(msg), m_line(-1), m_pos(-1) {}
|
cmd_exception(char const * msg):default_exception(msg), m_line(-1), m_pos(-1) {}
|
||||||
cmd_exception(std::string const & msg):default_exception(msg), m_line(-1), m_pos(-1) {}
|
cmd_exception(std::string && msg):default_exception(std::move(msg)), m_line(-1), m_pos(-1) {}
|
||||||
cmd_exception(std::string const & msg, int line, int pos):default_exception(msg), m_line(line), m_pos(pos) {}
|
cmd_exception(std::string && msg, int line, int pos):default_exception(std::move(msg)), m_line(line), m_pos(pos) {}
|
||||||
cmd_exception(char const * msg, symbol const & s):
|
cmd_exception(char const * msg, symbol const & s):
|
||||||
default_exception(compose(msg,s)),m_line(-1),m_pos(-1) {}
|
default_exception(compose(msg,s)),m_line(-1),m_pos(-1) {}
|
||||||
cmd_exception(char const * msg, symbol const & s, int line, int pos):
|
cmd_exception(char const * msg, symbol const & s, int line, int pos):
|
||||||
|
|
|
@ -356,7 +356,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (error)
|
if (error)
|
||||||
throw exception(error_msg);
|
throw exception(std::move(error_msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string get_value(params_ref const & ps, symbol const & p) {
|
std::string get_value(params_ref const & ps, symbol const & p) {
|
||||||
|
@ -417,7 +417,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (error)
|
if (error)
|
||||||
throw exception(error_msg);
|
throw exception(std::move(error_msg));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,7 +509,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (error)
|
if (error)
|
||||||
throw exception(error_msg);
|
throw exception(std::move(error_msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_parameter(std::ostream & out, char const * name) {
|
void display_parameter(std::ostream & out, char const * name) {
|
||||||
|
@ -550,7 +550,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (error)
|
if (error)
|
||||||
throw exception(error_msg);
|
throw exception(std::move(error_msg));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ bool contains(const std::unordered_map<A, B> & map, const A& key) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace lp {
|
namespace lp {
|
||||||
|
|
||||||
inline void throw_exception(const std::string & str) {
|
inline void throw_exception(const std::string & str) {
|
||||||
throw default_exception(str);
|
throw default_exception(str);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,9 +27,10 @@ Revision History:
|
||||||
#include "util/event_handler.h"
|
#include "util/event_handler.h"
|
||||||
#include "util/scoped_timer.h"
|
#include "util/scoped_timer.h"
|
||||||
|
|
||||||
scoped_timer * g_timeout = nullptr;
|
static scoped_timer * g_timeout = nullptr;
|
||||||
void (* g_on_timeout)() = nullptr;
|
static void (* g_on_timeout)() = nullptr;
|
||||||
|
|
||||||
|
namespace {
|
||||||
class g_timeout_eh : public event_handler {
|
class g_timeout_eh : public event_handler {
|
||||||
public:
|
public:
|
||||||
void operator()(event_handler_caller_t caller_id) override {
|
void operator()(event_handler_caller_t caller_id) override {
|
||||||
|
@ -46,6 +47,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void set_timeout(long ms) {
|
void set_timeout(long ms) {
|
||||||
if (g_timeout)
|
if (g_timeout)
|
||||||
|
|
|
@ -67,9 +67,6 @@ default_exception::default_exception(fmt, char const* msg, ...) {
|
||||||
m_msg = out.str();
|
m_msg = out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
default_exception::default_exception(std::string const & msg): m_msg(msg) {
|
|
||||||
}
|
|
||||||
|
|
||||||
char const * default_exception::msg() const {
|
char const * default_exception::msg() const {
|
||||||
return m_msg.c_str();
|
return m_msg.c_str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ class default_exception : public z3_exception {
|
||||||
std::string m_msg;
|
std::string m_msg;
|
||||||
public:
|
public:
|
||||||
struct fmt {};
|
struct fmt {};
|
||||||
default_exception(std::string const& msg);
|
default_exception(std::string && msg) : m_msg(std::move(msg)) {}
|
||||||
default_exception(fmt, char const* msg, ...);
|
default_exception(fmt, char const* msg, ...);
|
||||||
~default_exception() override {}
|
~default_exception() override {}
|
||||||
char const * msg() const override;
|
char const * msg() const override;
|
||||||
|
|
Loading…
Reference in a new issue