mirror of
https://github.com/Z3Prover/z3
synced 2025-08-24 12:07:52 +00:00
eq explain
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
8c9835bca6
commit
dc3b921712
2 changed files with 101 additions and 0 deletions
71
src/math/polysat/eq_explain.cpp
Normal file
71
src/math/polysat/eq_explain.cpp
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2021 Microsoft Corporation
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
Conflict explanation
|
||||||
|
|
||||||
|
Author:
|
||||||
|
|
||||||
|
Nikolaj Bjorner (nbjorner) 2021-03-19
|
||||||
|
Jakob Rath 2021-04-6
|
||||||
|
|
||||||
|
--*/
|
||||||
|
#include "math/polysat/eq_explain.h"
|
||||||
|
#include "math/polysat/solver.h"
|
||||||
|
|
||||||
|
namespace polysat {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a*v = 0 => a*2^j = 0 or v*2^k = 0
|
||||||
|
* for j + k < K
|
||||||
|
*
|
||||||
|
* az = trailing_zeros(a)
|
||||||
|
* a << (K - az - 1) = 0 or v << az = 0
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool eq_explain::explain_zero(pvar v, pdd & a, pdd & b, signed_constraint c, conflict& core) {
|
||||||
|
pdd bv = s.subst(b);
|
||||||
|
if (!bv.is_zero())
|
||||||
|
return false;
|
||||||
|
rational av = s.subst(a).val();
|
||||||
|
SASSERT(!av.is_zero());
|
||||||
|
unsigned K = a.power_of_2();
|
||||||
|
unsigned az = av.trailing_zeros();
|
||||||
|
SASSERT(az < K);
|
||||||
|
core.reset();
|
||||||
|
core.insert(c);
|
||||||
|
core.propagate(s.eq(b));
|
||||||
|
core.propagate(~s.eq(a.shl(K - az - 1)));
|
||||||
|
core.propagate(~s.eq(b.shl(az)));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool eq_explain::try_explain1(pvar v, signed_constraint c, conflict& core) {
|
||||||
|
if (!c.is_eq())
|
||||||
|
return false;
|
||||||
|
if (!c.is_currently_false(s))
|
||||||
|
return false;
|
||||||
|
auto p = c->to_ule().lhs();
|
||||||
|
unsigned deg = p.degree(v);
|
||||||
|
if (deg != 1)
|
||||||
|
return false;
|
||||||
|
auto& m = p.manager();
|
||||||
|
pdd a = m.zero(), b = m.zero();
|
||||||
|
p.factor(v, 1, a, b);
|
||||||
|
if (explain_zero(v, a, b, c, core))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool eq_explain::try_explain(pvar v, conflict& core) {
|
||||||
|
for (auto c : core)
|
||||||
|
if (try_explain1(v, c, core))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
30
src/math/polysat/eq_explain.h
Normal file
30
src/math/polysat/eq_explain.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2021 Microsoft Corporation
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
Conflict explanation
|
||||||
|
|
||||||
|
Author:
|
||||||
|
|
||||||
|
Nikolaj Bjorner (nbjorner) 2021-03-19
|
||||||
|
Jakob Rath 2021-04-6
|
||||||
|
|
||||||
|
--*/
|
||||||
|
#pragma once
|
||||||
|
#include "math/polysat/explain.h"
|
||||||
|
|
||||||
|
namespace polysat {
|
||||||
|
|
||||||
|
class solver;
|
||||||
|
|
||||||
|
class eq_explain : public explainer {
|
||||||
|
private:
|
||||||
|
bool try_explain1(pvar v, signed_constraint c, conflict& core);
|
||||||
|
bool explain_zero(pvar v, pdd& a, pdd& b, signed_constraint c, conflict& core);
|
||||||
|
public:
|
||||||
|
eq_explain(solver& s) : explainer(s) {}
|
||||||
|
bool try_explain(pvar v, conflict& core) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue