3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-10-09 09:21:56 +00:00

detangle mess

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2025-09-23 12:45:46 +03:00
parent 3c38ee2690
commit 1582e4616e
3 changed files with 145 additions and 71 deletions

84
.clang-format Normal file
View file

@ -0,0 +1,84 @@
# Z3 Theorem Prover clang-format configuration
# Based on analysis of existing codebase style patterns
BasedOnStyle: LLVM
# Indentation
IndentWidth: 4
TabWidth: 4
UseTab: Never
# Column width
ColumnLimit: 120
# Braces
Cpp11BracedListStyle: true
# Classes and structs
BreakConstructorInitializers: BeforeColon
ConstructorInitializerIndentWidth: 4
AccessModifierOffset: -4
# Function definitions
AlwaysBreakAfterReturnType: None
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
# Ensure function-opening brace is attached to the signature
BreakBeforeBraces: Custom
# Explicitly ensure function brace is not placed on a new line
BraceWrapping:
AfterFunction: false
AfterClass: false
AfterControlStatement: false
AfterNamespace: false
AfterStruct: false
# Spacing
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
IndentCaseLabels: false
# Alignment
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignOperands: true
AlignTrailingComments: true
# Line breaks
AllowAllParametersOfDeclarationOnNextLine: true
BinPackArguments: true
BinPackParameters: true
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
# Includes
SortIncludes: false # Z3 has specific include ordering conventions
# Namespaces
NamespaceIndentation: All
# Comments and documentation
ReflowComments: true
SpacesBeforeTrailingComments: 2
# Language standards
Standard: c++20
# Penalties (for line breaking decisions)
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
# Misc
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1

View file

@ -1,5 +0,0 @@
BasedOnStyle: Google
IndentWidth: 4
ColumnLimit: 0
NamespaceIndentation: All
BreakBeforeBraces: Attach

View file

@ -320,21 +320,22 @@ struct solver::imp {
} }
lbool check_assignment() { lbool check_assignment() {
IF_VERBOSE(1, verbose_stream() << "nra::solver::check_assignment\n";);
setup_solver(); setup_solver();
lbool r = l_undef; lbool r = l_undef;
statistics& st = m_nla_core.lp_settings().stats().m_st; statistics &st = m_nla_core.lp_settings().stats().m_st;
nlsat::literal_vector clause; nlsat::literal_vector clause;
polynomial::manager& pm = m_nlsat->pm(); polynomial::manager &pm = m_nlsat->pm();
try { try {
nlsat::assignment rvalues(m_nlsat->am()); nlsat::assignment rvalues(m_nlsat->am());
for (auto [j, x] : m_lp2nl) { for (auto [j, x] : m_lp2nl) {
scoped_anum a(am()); scoped_anum a(am());
am().set(a, m_nla_core.val(j).to_mpq()); am().set(a, m_nla_core.val(j).to_mpq());
rvalues.set(x, a); rvalues.set(x, a);
} }
r = m_nlsat->check(rvalues, clause); r = m_nlsat->check(rvalues, clause);
} }
catch (z3_exception&) { catch (z3_exception &) {
if (m_limit.is_canceled()) { if (m_limit.is_canceled()) {
r = l_undef; r = l_undef;
} }
@ -344,71 +345,65 @@ struct solver::imp {
} }
} }
m_nlsat->collect_statistics(st); m_nlsat->collect_statistics(st);
TRACE(nra, TRACE(nra, m_nlsat->display(tout << r << "\n"); display(tout); tout << "m_lp2nl:\n";
m_nlsat->display(tout << r << "\n");
display(tout);
tout << "m_lp2nl:\n";
for (auto [j, x] : m_lp2nl) tout << "j" << j << " := x" << x << "\n";); for (auto [j, x] : m_lp2nl) tout << "j" << j << " := x" << x << "\n";);
switch (r) { switch (r) {
case l_true: case l_true:
m_nla_core.set_use_nra_model(true); m_nla_core.set_use_nra_model(true);
lra.init_model(); lra.init_model();
validate_constraints(); validate_constraints();
break; m_nla_core.set_use_nra_model(true);
case l_false: { break;
u_map<lp::lpvar> nl2lp = reverse_lp2nl(); case l_false:
nla::lemma_builder lemma(m_nla_core, __FUNCTION__); return add_lemma(clause);
for (nlsat::literal l : clause) { default:
nlsat::atom* a = m_nlsat->bool_var2atom(l.var()); break;
TRACE(nra, tout << "atom: "; m_nlsat->display(tout, *a); tout << "\n";); }
SASSERT(!a->is_root_atom()); return r;
SASSERT(a->is_ineq_atom()); }
auto& ia = *to_ineq_atom(a);
VERIFY(ia.size() == 1); // deal with factored polynomials later lbool add_lemma(nlsat::literal_vector const &clause) {
// a is an inequality atom, i.e., p > 0, p < 0, or p = 0. u_map<lp::lpvar> nl2lp = reverse_lp2nl();
polynomial::polynomial const* p = ia.p(0); polynomial::manager &pm = m_nlsat->pm();
TRACE(nra, tout << "polynomial: "; pm.display(tout, p); tout << "\n";); nla::lemma_builder lemma(m_nla_core, __FUNCTION__);
unsigned num_mon = pm.size(p); for (nlsat::literal l : clause) {
rational bound(0); nlsat::atom *a = m_nlsat->bool_var2atom(l.var());
lp::lar_term t; TRACE(nra, tout << "atom: "; m_nlsat->display(tout, *a); tout << "\n";);
process_polynomial_check_assignment(num_mon, p, bound, nl2lp, t); SASSERT(!a->is_root_atom());
SASSERT(a->is_ineq_atom());
switch (a->get_kind()) { auto &ia = *to_ineq_atom(a);
{ VERIFY(ia.size() == 1); // deal with factored polynomials later
// Introduce a single ineq variable and assign it per case; common handling after switch. // a is an inequality atom, i.e., p > 0, p < 0, or p = 0.
nla::ineq inq(lp::lconstraint_kind::EQ, t, bound); // initial value overwritten in cases below polynomial::polynomial const *p = ia.p(0);
switch (a->get_kind()) { TRACE(nra, tout << "polynomial: "; pm.display(tout, p); tout << "\n";);
case nlsat::atom::EQ: unsigned num_mon = pm.size(p);
inq = nla::ineq(l.sign() ? lp::lconstraint_kind::NE : lp::lconstraint_kind::EQ, t, bound); rational bound(0);
break; lp::lar_term t;
case nlsat::atom::LT: process_polynomial_check_assignment(num_mon, p, bound, nl2lp, t);
inq = nla::ineq(l.sign() ? lp::lconstraint_kind::GE : lp::lconstraint_kind::LT, t, bound);
break; // Introduce a single ineq variable and assign it per case; common handling after switch.
case nlsat::atom::GT: nla::ineq inq(lp::lconstraint_kind::EQ, t, bound); // initial value overwritten in cases below
inq = nla::ineq(l.sign() ? lp::lconstraint_kind::LE : lp::lconstraint_kind::GT, t, bound); switch (a->get_kind()) {
break; case nlsat::atom::EQ:
default: inq = nla::ineq(l.sign() ? lp::lconstraint_kind::NE : lp::lconstraint_kind::EQ, t, bound);
UNREACHABLE(); break;
return l_undef; case nlsat::atom::LT:
} inq = nla::ineq(l.sign() ? lp::lconstraint_kind::GE : lp::lconstraint_kind::LT, t, bound);
if (m_nla_core.ineq_holds(inq)) break;
return l_undef; case nlsat::atom::GT:
lemma |= inq; inq = nla::ineq(l.sign() ? lp::lconstraint_kind::LE : lp::lconstraint_kind::GT, t, bound);
} break;
break; default:
default: UNREACHABLE();
UNREACHABLE(); return l_undef;
return l_undef; }
} // NSB review: what is this???
} if (m_nla_core.ineq_holds(inq))
IF_VERBOSE(1, verbose_stream() << "linear lemma: " << lemma << "\n"); return l_undef;
m_nla_core.set_use_nra_model(true); lemma |= inq;
break; IF_VERBOSE(1, verbose_stream() << "linear lemma: " << lemma << "\n");
} return l_false;
case l_undef:
break;
} }
return r;
} }
void constraint_core2ex(lp::explanation& ex) { void constraint_core2ex(lp::explanation& ex) {