mirror of
https://github.com/Z3Prover/z3
synced 2025-04-28 19:35:50 +00:00
improved dio handler
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
30021dd74f
commit
6f7b749ff9
11 changed files with 885 additions and 544 deletions
|
@ -2509,6 +2509,24 @@ namespace lp {
|
|||
// Otherwise the new asserted lower bound is is greater than the existing upper bound.
|
||||
// dep is the reason for the new bound
|
||||
|
||||
void lar_solver::write_bound_lemma_to_file(unsigned j, bool is_low, const std::string & file_name, const std::string& location) const {
|
||||
std::ofstream file(file_name);
|
||||
if (!file.is_open()) {
|
||||
// Handle file open error
|
||||
std::cerr << "Failed to open file: " << file_name << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
write_bound_lemma(j, is_low, location, file);
|
||||
file.close();
|
||||
|
||||
if (file.fail()) {
|
||||
std::cerr << "Error occurred while writing to file: " << file_name << std::endl;
|
||||
} else {
|
||||
std::cout << "Bound lemma written to " << file_name << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void lar_solver::set_crossed_bounds_column_and_deps(unsigned j, bool lower_bound, u_dependency* dep) {
|
||||
if (m_crossed_bounds_column != null_lpvar) return; // already set
|
||||
SASSERT(m_crossed_bounds_deps == nullptr);
|
||||
|
@ -2518,7 +2536,7 @@ namespace lp {
|
|||
u_dependency* bdep = lower_bound? ul.lower_bound_witness() : ul.upper_bound_witness();
|
||||
SASSERT(bdep != nullptr);
|
||||
m_crossed_bounds_deps = m_dependencies.mk_join(bdep, dep);
|
||||
insert_to_columns_with_changed_bounds(j);
|
||||
TRACE("dio", tout << "crossed_bound_deps:\n"; print_explanation(tout, flatten(m_crossed_bounds_deps)) << "\n";);
|
||||
}
|
||||
|
||||
void lar_solver::collect_more_rows_for_lp_propagation(){
|
||||
|
@ -2539,6 +2557,189 @@ namespace lp {
|
|||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Helper function to format constants in SMT2 format
|
||||
std::string format_smt2_constant(const mpq& val) {
|
||||
if (val.is_neg()) {
|
||||
// Negative constant - use unary minus operator
|
||||
return std::string("(- ") + abs(val).to_string() + ")";
|
||||
} else {
|
||||
// Positive or zero constant - write directly
|
||||
return val.to_string();
|
||||
}
|
||||
}
|
||||
|
||||
void lar_solver::write_bound_lemma(unsigned j, bool is_low, const std::string& location, std::ostream & out) const {
|
||||
// Get the bound value and dependency
|
||||
mpq bound_val;
|
||||
bool is_strict = false;
|
||||
u_dependency* bound_dep = nullptr;
|
||||
|
||||
// Get the appropriate bound info
|
||||
if (is_low) {
|
||||
if (!has_lower_bound(j, bound_dep, bound_val, is_strict)) {
|
||||
out << "; Error: Variable " << j << " has no lower bound\n";
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!has_upper_bound(j, bound_dep, bound_val, is_strict)) {
|
||||
out << "; Error: Variable " << j << " has no upper bound\n";
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Start SMT2 file
|
||||
out << "(set-info : \"generated at " << location;
|
||||
out << " for " << (is_low ? "lower" : "upper") << " bound of variable " << j << ",";
|
||||
out << " bound value: " << bound_val << (is_strict ? (is_low ? " < " : " > ") : (is_low ? " <= " : " >= ")) << "x" << j << "\")\n";
|
||||
|
||||
// Collect all variables used in dependencies
|
||||
std::unordered_set<unsigned> vars_used;
|
||||
vars_used.insert(j);
|
||||
bool is_int = column_is_int(j);
|
||||
|
||||
// Linearize the dependencies
|
||||
svector<constraint_index> deps;
|
||||
m_dependencies.linearize(bound_dep, deps);
|
||||
|
||||
// Collect variables from constraints
|
||||
for (auto ci : deps) {
|
||||
const auto& c = m_constraints[ci];
|
||||
for (const auto& p : c.coeffs()) {
|
||||
vars_used.insert(p.second);
|
||||
if (!column_is_int(p.second))
|
||||
is_int = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Collect variables from terms
|
||||
std::unordered_set<unsigned> term_variables;
|
||||
for (unsigned var : vars_used) {
|
||||
if (column_has_term(var)) {
|
||||
const lar_term& term = get_term(var);
|
||||
for (const auto& p : term) {
|
||||
term_variables.insert(p.j());
|
||||
if (!column_is_int(p.j()))
|
||||
is_int = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add term variables to vars_used
|
||||
vars_used.insert(term_variables.begin(), term_variables.end());
|
||||
|
||||
if (is_int) {
|
||||
out << "(set-logic QF_LIA)\n\n";
|
||||
}
|
||||
|
||||
// Declare variables
|
||||
out << "; Variable declarations\n";
|
||||
for (unsigned var : vars_used) {
|
||||
out << "(declare-const x" << var << " " << (column_is_int(var) ? "Int" : "Real") << ")\n";
|
||||
}
|
||||
out << "\n";
|
||||
|
||||
// Define term relationships
|
||||
out << "; Term definitions\n";
|
||||
for (unsigned var : vars_used) {
|
||||
if (column_has_term(var)) {
|
||||
const lar_term& term = get_term(var);
|
||||
out << "(assert (= x" << var << " ";
|
||||
|
||||
if (term.size() == 0) {
|
||||
out << "0";
|
||||
} else {
|
||||
if (term.size() > 1) out << "(+ ";
|
||||
|
||||
bool first = true;
|
||||
for (const auto& p : term) {
|
||||
if (first) first = false;
|
||||
else out << " ";
|
||||
|
||||
if (p.coeff().is_one()) {
|
||||
out << "x" << p.j();
|
||||
} else {
|
||||
out << "(* " << format_smt2_constant(p.coeff()) << " x" << p.j() << ")";
|
||||
}
|
||||
}
|
||||
|
||||
if (term.size() > 1) out << ")";
|
||||
}
|
||||
|
||||
out << "))\n";
|
||||
}
|
||||
}
|
||||
out << "\n";
|
||||
|
||||
// Add assertions for the dependencies
|
||||
out << "; Bound dependencies\n";
|
||||
|
||||
for (auto ci : deps) {
|
||||
const auto& c = m_constraints[ci];
|
||||
out << "(assert ";
|
||||
|
||||
// Handle the constraint type and expression
|
||||
auto k = c.kind();
|
||||
|
||||
// Normal constraint with variables
|
||||
switch (k) {
|
||||
case LE: out << "(<= "; break;
|
||||
case LT: out << "(< "; break;
|
||||
case GE: out << "(>= "; break;
|
||||
case GT: out << "(> "; break;
|
||||
case EQ: out << "(= "; break;
|
||||
default: out << "(unknown-constraint-type "; break;
|
||||
}
|
||||
|
||||
// Left-hand side (variables)
|
||||
if (c.coeffs().size() == 1) {
|
||||
// Single variable
|
||||
auto p = *c.coeffs().begin();
|
||||
if (p.first.is_one()) {
|
||||
out << "x" << p.second << " ";
|
||||
} else {
|
||||
out << "(* " << format_smt2_constant(p.first) << " x" << p.second << ") ";
|
||||
}
|
||||
} else {
|
||||
// Multiple variables - create a sum
|
||||
out << "(+ ";
|
||||
for (auto const& p : c.coeffs()) {
|
||||
if (p.first.is_one()) {
|
||||
out << "x" << p.second << " ";
|
||||
} else {
|
||||
out << "(* " << format_smt2_constant(p.first) << " x" << p.second << ") ";
|
||||
}
|
||||
}
|
||||
out << ") ";
|
||||
}
|
||||
|
||||
// Right-hand side (constant)
|
||||
out << format_smt2_constant(c.rhs());
|
||||
out << "))\n";
|
||||
}
|
||||
out << "\n";
|
||||
|
||||
// Now add the assertion that contradicts the bound
|
||||
out << "; Negation of the derived bound\n";
|
||||
if (is_low) {
|
||||
if (is_strict) {
|
||||
out << "(assert (<= x" << j << " " << format_smt2_constant(bound_val) << "))\n";
|
||||
} else {
|
||||
out << "(assert (< x" << j << " " << format_smt2_constant(bound_val) << "))\n";
|
||||
}
|
||||
} else {
|
||||
if (is_strict) {
|
||||
out << "(assert (>= x" << j << " " << format_smt2_constant(bound_val) << "))\n";
|
||||
} else {
|
||||
out << "(assert (> x" << j << " " << format_smt2_constant(bound_val) << "))\n";
|
||||
}
|
||||
}
|
||||
out << "\n";
|
||||
|
||||
// Check sat and get model if available
|
||||
out << "(check-sat)\n";
|
||||
out << "(exit)\n";
|
||||
}
|
||||
} // namespace lp
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue