mirror of
https://github.com/Z3Prover/z3
synced 2025-04-06 17:44:08 +00:00
109 lines
3 KiB
C++
109 lines
3 KiB
C++
/*++
|
|
Copyright (c) 2014 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
opt_pareto.cpp
|
|
|
|
Abstract:
|
|
|
|
Pareto front utilities
|
|
|
|
Author:
|
|
|
|
Nikolaj Bjorner (nbjorner) 2014-4-24
|
|
|
|
Notes:
|
|
|
|
|
|
--*/
|
|
|
|
#include "opt/opt_pareto.h"
|
|
#include "ast/ast_pp.h"
|
|
#include "ast/ast_util.h"
|
|
#include "model/model_smt2_pp.h"
|
|
|
|
namespace opt {
|
|
|
|
// ---------------------
|
|
// GIA pareto algorithm
|
|
|
|
lbool gia_pareto::operator()() {
|
|
expr_ref fml(m);
|
|
lbool is_sat = m_solver->check_sat(0, nullptr);
|
|
if (is_sat == l_true) {
|
|
{
|
|
solver::scoped_push _s(*m_solver.get());
|
|
while (is_sat == l_true) {
|
|
if (m.canceled()) {
|
|
return l_undef;
|
|
}
|
|
m_solver->get_model(m_model);
|
|
m_solver->get_labels(m_labels);
|
|
IF_VERBOSE(1,
|
|
model_ref mdl(m_model);
|
|
cb.fix_model(mdl);
|
|
model_smt2_pp(verbose_stream() << "new model:\n", m, *mdl, 0););
|
|
// TBD: we can also use local search to tune solution coordinate-wise.
|
|
mk_dominates();
|
|
is_sat = m_solver->check_sat(0, nullptr);
|
|
}
|
|
}
|
|
if (is_sat == l_undef) {
|
|
return l_undef;
|
|
}
|
|
SASSERT(is_sat == l_false);
|
|
is_sat = l_true;
|
|
mk_not_dominated_by();
|
|
}
|
|
return is_sat;
|
|
}
|
|
|
|
void pareto_base::mk_dominates() {
|
|
unsigned sz = cb.num_objectives();
|
|
expr_ref fml(m);
|
|
expr_ref_vector gt(m), fmls(m);
|
|
for (unsigned i = 0; i < sz; ++i) {
|
|
fmls.push_back(cb.mk_ge(i, m_model));
|
|
gt.push_back(cb.mk_gt(i, m_model));
|
|
}
|
|
fmls.push_back(mk_or(gt));
|
|
fml = mk_and(fmls);
|
|
IF_VERBOSE(10, verbose_stream() << "dominates: " << fml << "\n";);
|
|
TRACE("opt", tout << fml << "\n"; model_smt2_pp(tout, m, *m_model, 0););
|
|
m_solver->assert_expr(fml);
|
|
}
|
|
|
|
void pareto_base::mk_not_dominated_by() {
|
|
unsigned sz = cb.num_objectives();
|
|
expr_ref fml(m);
|
|
expr_ref_vector le(m);
|
|
for (unsigned i = 0; i < sz; ++i) {
|
|
le.push_back(cb.mk_le(i, m_model));
|
|
}
|
|
fml = m.mk_not(mk_and(le));
|
|
IF_VERBOSE(10, verbose_stream() << "not dominated by: " << fml << "\n";);
|
|
TRACE("opt", tout << fml << "\n";);
|
|
m_solver->assert_expr(fml);
|
|
}
|
|
|
|
// ---------------------------------
|
|
// OIA algorithm (without filtering)
|
|
|
|
lbool oia_pareto::operator()() {
|
|
solver::scoped_push _s(*m_solver.get());
|
|
lbool is_sat = m_solver->check_sat(0, nullptr);
|
|
if (m.canceled()) {
|
|
is_sat = l_undef;
|
|
}
|
|
if (is_sat == l_true) {
|
|
m_solver->get_model(m_model);
|
|
m_solver->get_labels(m_labels);
|
|
mk_not_dominated_by();
|
|
}
|
|
return is_sat;
|
|
}
|
|
|
|
}
|
|
|