3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 00:55:31 +00:00

split into parts, add stats

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2021-04-14 04:05:35 -07:00
parent 21baa2a70a
commit 57486f0b3d
7 changed files with 215 additions and 112 deletions

View file

@ -1,6 +1,7 @@
z3_add_component(polysat
SOURCES
polysat.cpp
solver.cpp
constraint.cpp
COMPONENT_DEPENDENCIES
util
dd

View file

@ -0,0 +1,30 @@
/*++
Copyright (c) 2021 Microsoft Corporation
Module Name:
polysat constraints
Author:
Nikolaj Bjorner (nbjorner) 2021-03-19
--*/
#include "math/polysat/constraint.h"
namespace polysat {
std::ostream& constraint::display(std::ostream& out) const {
switch (kind()) {
case ckind_t::eq_t:
return out << p() << " == 0";
case ckind_t::ule_t:
return out << lhs() << " <=u " << rhs();
case ckind_t::sle_t:
return out << lhs() << " <=s " << rhs();
}
return out;
}
}

View file

@ -0,0 +1,61 @@
/*++
Copyright (c) 2021 Microsoft Corporation
Module Name:
polysat constraints
Abstract:
Polynomial constriants
Author:
Nikolaj Bjorner (nbjorner) 2021-03-19
--*/
#pragma once
#include "math/polysat/types.h"
namespace polysat {
enum ckind_t { eq_t, ule_t, sle_t };
class constraint {
unsigned m_level;
ckind_t m_kind;
pdd m_poly;
pdd m_other;
p_dependency_ref m_dep;
unsigned_vector m_vars;
constraint(unsigned lvl, pdd const& p, pdd const& q, p_dependency_ref& dep, ckind_t k):
m_level(lvl), m_kind(k), m_poly(p), m_other(q), m_dep(dep) {
m_vars.append(p.free_vars());
if (q != p)
for (auto v : q.free_vars())
m_vars.insert(v);
}
public:
static constraint* eq(unsigned lvl, pdd const& p, p_dependency_ref& d) {
return alloc(constraint, lvl, p, p, d, ckind_t::eq_t);
}
static constraint* ule(unsigned lvl, pdd const& p, pdd const& q, p_dependency_ref& d) {
return alloc(constraint, lvl, p, q, d, ckind_t::ule_t);
}
bool is_eq() const { return m_kind == ckind_t::eq_t; }
bool is_ule() const { return m_kind == ckind_t::ule_t; }
bool is_sle() const { return m_kind == ckind_t::sle_t; }
ckind_t kind() const { return m_kind; }
pdd const & p() const { return m_poly; }
pdd const & lhs() const { return m_poly; }
pdd const & rhs() const { return m_other; }
std::ostream& display(std::ostream& out) const;
p_dependency* dep() const { return m_dep; }
unsigned_vector& vars() { return m_vars; }
unsigned level() const { return m_level; }
};
inline std::ostream& operator<<(std::ostream& out, constraint const& c) { return c.display(out); }
}

View file

@ -0,0 +1,44 @@
/*++
Copyright (c) 2021 Microsoft Corporation
Module Name:
polysat justification
Author:
Nikolaj Bjorner (nbjorner) 2021-03-19
--*/
#pragma once
#include "math/polysat/types.h"
namespace polysat {
/**
* Justification kind for a variable assignment.
*/
enum justification_k { unassigned, decision, propagation };
class justification {
justification_k m_kind;
unsigned m_level;
justification(justification_k k, unsigned lvl): m_kind(k), m_level(lvl) {}
public:
justification(): m_kind(justification_k::unassigned) {}
static justification unassigned() { return justification(justification_k::unassigned, 0); }
static justification decision(unsigned lvl) { return justification(justification_k::decision, lvl); }
static justification propagation(unsigned lvl) { return justification(justification_k::propagation, lvl); }
bool is_decision() const { return m_kind == justification_k::decision; }
bool is_unassigned() const { return m_kind == justification_k::unassigned; }
bool is_propagation() const { return m_kind == justification_k::propagation; }
justification_k kind() const { return m_kind; }
unsigned level() const { return m_level; }
std::ostream& display(std::ostream& out) const;
};
inline std::ostream& operator<<(std::ostream& out, justification const& j) { return j.display(out); }
}

View file

@ -15,21 +15,10 @@ Author:
--*/
#include "math/polysat/polysat.h"
#include "math/polysat/solver.h"
namespace polysat {
std::ostream& constraint::display(std::ostream& out) const {
switch (kind()) {
case ckind_t::eq_t:
return out << p() << " == 0";
case ckind_t::ule_t:
return out << lhs() << " <=u " << rhs();
case ckind_t::sle_t:
return out << lhs() << " <=s " << rhs();
}
return out;
}
dd::pdd_manager& solver::sz2pdd(unsigned sz) {
m_pdd.reserve(sz + 1);
@ -355,6 +344,10 @@ namespace polysat {
}
void solver::assign_core(pvar v, rational const& val, justification const& j) {
if (j.is_decision())
++m_stats.m_num_decisions;
else
++m_stats.m_num_propagations;
SASSERT(is_viable(v, val));
m_value[v] = val;
m_search.push_back(std::make_pair(v, val));
@ -393,6 +386,7 @@ namespace polysat {
*
*/
void solver::resolve_conflict() {
++m_stats.m_num_conflicts;
SASSERT(!m_conflict.empty());
@ -628,6 +622,12 @@ namespace polysat {
return out;
}
void solver::collect_statistics(statistics& st) const {
st.update("polysat decisions", m_stats.m_num_decisions);
st.update("polysat conflicts", m_stats.m_num_conflicts);
st.update("polysat propagations", m_stats.m_num_propagations);
}
bool solver::invariant() {
invariant(m_constraints);
invariant(m_redundant);

View file

@ -3,7 +3,7 @@ Copyright (c) 2021 Microsoft Corporation
Module Name:
polysat
polysat solver
Abstract:
@ -16,109 +16,21 @@ Author:
--*/
#pragma once
#include "util/dependency.h"
#include "util/trail.h"
#include "util/lbool.h"
#include "util/rlimit.h"
#include "util/scoped_ptr_vector.h"
#include "util/var_queue.h"
#include "util/ref_vector.h"
#include "math/dd/dd_pdd.h"
#include "math/dd/dd_bdd.h"
#include "util/statistics.h"
#include "math/polysat/constraint.h"
#include "math/polysat/justification.h"
namespace polysat {
class solver;
typedef dd::pdd pdd;
typedef dd::bdd bdd;
typedef unsigned pvar;
const unsigned null_dependency = UINT_MAX;
const pvar null_var = UINT_MAX;
struct dep_value_manager {
void inc_ref(unsigned) {}
void dec_ref(unsigned) {}
};
struct dep_config {
typedef dep_value_manager value_manager;
typedef unsigned value;
typedef small_object_allocator allocator;
static const bool ref_count = false;
};
typedef dependency_manager<dep_config> poly_dep_manager;
typedef poly_dep_manager::dependency p_dependency;
typedef obj_ref<p_dependency, poly_dep_manager> p_dependency_ref;
typedef ref_vector<p_dependency, poly_dep_manager> p_dependency_refv;
enum ckind_t { eq_t, ule_t, sle_t };
class constraint {
unsigned m_level;
ckind_t m_kind;
pdd m_poly;
pdd m_other;
p_dependency_ref m_dep;
unsigned_vector m_vars;
constraint(unsigned lvl, pdd const& p, pdd const& q, p_dependency_ref& dep, ckind_t k):
m_level(lvl), m_kind(k), m_poly(p), m_other(q), m_dep(dep) {
m_vars.append(p.free_vars());
if (q != p)
for (auto v : q.free_vars())
m_vars.insert(v);
}
public:
static constraint* eq(unsigned lvl, pdd const& p, p_dependency_ref& d) {
return alloc(constraint, lvl, p, p, d, ckind_t::eq_t);
}
static constraint* ule(unsigned lvl, pdd const& p, pdd const& q, p_dependency_ref& d) {
return alloc(constraint, lvl, p, q, d, ckind_t::ule_t);
}
bool is_eq() const { return m_kind == ckind_t::eq_t; }
bool is_ule() const { return m_kind == ckind_t::ule_t; }
bool is_sle() const { return m_kind == ckind_t::sle_t; }
ckind_t kind() const { return m_kind; }
pdd const & p() const { return m_poly; }
pdd const & lhs() const { return m_poly; }
pdd const & rhs() const { return m_other; }
std::ostream& display(std::ostream& out) const;
p_dependency* dep() const { return m_dep; }
unsigned_vector& vars() { return m_vars; }
unsigned level() const { return m_level; }
};
inline std::ostream& operator<<(std::ostream& out, constraint const& c) { return c.display(out); }
/**
* Justification kind for a variable assignment.
*/
enum justification_k { unassigned, decision, propagation };
class justification {
justification_k m_kind;
unsigned m_level;
justification(justification_k k, unsigned lvl): m_kind(k), m_level(lvl) {}
public:
justification(): m_kind(justification_k::unassigned) {}
static justification unassigned() { return justification(justification_k::unassigned, 0); }
static justification decision(unsigned lvl) { return justification(justification_k::decision, lvl); }
static justification propagation(unsigned lvl) { return justification(justification_k::propagation, lvl); }
bool is_decision() const { return m_kind == justification_k::decision; }
bool is_unassigned() const { return m_kind == justification_k::unassigned; }
bool is_propagation() const { return m_kind == justification_k::propagation; }
justification_k kind() const { return m_kind; }
unsigned level() const { return m_level; }
std::ostream& display(std::ostream& out) const;
};
inline std::ostream& operator<<(std::ostream& out, justification const& j) { return j.display(out); }
class solver {
struct stats {
unsigned m_num_decisions;
unsigned m_num_propagations;
unsigned m_num_conflicts;
void reset() { memset(this, 0, sizeof(*this)); }
};
typedef ptr_vector<constraint> constraints;
trail_stack& m_trail;
@ -131,6 +43,7 @@ namespace polysat {
constraints m_conflict;
constraints m_stash_just;
var_queue m_free_vars;
stats m_stats;
// Per constraint state
scoped_ptr_vector<constraint> m_constraints;
@ -305,6 +218,8 @@ namespace polysat {
std::ostream& display(std::ostream& out) const;
void collect_statistics(statistics& st) const;
};
inline std::ostream& operator<<(std::ostream& out, solver const& s) { return s.display(out); }

52
src/math/polysat/types.h Normal file
View file

@ -0,0 +1,52 @@
/*++
Copyright (c) 2021 Microsoft Corporation
Module Name:
polysat types
Author:
Nikolaj Bjorner (nbjorner) 2021-03-19
--*/
#pragma once
#include "util/dependency.h"
#include "util/trail.h"
#include "util/lbool.h"
#include "util/rlimit.h"
#include "util/scoped_ptr_vector.h"
#include "util/var_queue.h"
#include "util/ref_vector.h"
#include "math/dd/dd_pdd.h"
#include "math/dd/dd_bdd.h"
namespace polysat {
class solver;
typedef dd::pdd pdd;
typedef dd::bdd bdd;
typedef unsigned pvar;
const unsigned null_dependency = UINT_MAX;
const pvar null_var = UINT_MAX;
struct dep_value_manager {
void inc_ref(unsigned) {}
void dec_ref(unsigned) {}
};
struct dep_config {
typedef dep_value_manager value_manager;
typedef unsigned value;
typedef small_object_allocator allocator;
static const bool ref_count = false;
};
typedef dependency_manager<dep_config> poly_dep_manager;
typedef poly_dep_manager::dependency p_dependency;
typedef obj_ref<p_dependency, poly_dep_manager> p_dependency_ref;
typedef ref_vector<p_dependency, poly_dep_manager> p_dependency_refv;
}