mirror of
https://github.com/Z3Prover/z3
synced 2025-06-21 21:33:39 +00:00
extract/concat slicing wip
This commit is contained in:
parent
8bde66420a
commit
a0df8507d9
7 changed files with 531 additions and 1 deletions
|
@ -13,6 +13,7 @@ z3_add_component(polysat
|
||||||
justification.cpp
|
justification.cpp
|
||||||
linear_solver.cpp
|
linear_solver.cpp
|
||||||
log.cpp
|
log.cpp
|
||||||
|
naming.cpp
|
||||||
op_constraint.cpp
|
op_constraint.cpp
|
||||||
polysat_ast.cpp
|
polysat_ast.cpp
|
||||||
restart.cpp
|
restart.cpp
|
||||||
|
@ -20,6 +21,7 @@ z3_add_component(polysat
|
||||||
search_state.cpp
|
search_state.cpp
|
||||||
simplify.cpp
|
simplify.cpp
|
||||||
simplify_clause.cpp
|
simplify_clause.cpp
|
||||||
|
slicing.cpp
|
||||||
smul_fl_constraint.cpp
|
smul_fl_constraint.cpp
|
||||||
solver.cpp
|
solver.cpp
|
||||||
superposition.cpp
|
superposition.cpp
|
||||||
|
|
65
src/math/polysat/naming.cpp
Normal file
65
src/math/polysat/naming.cpp
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2023 Microsoft Corporation
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
polysat definitions
|
||||||
|
|
||||||
|
Author:
|
||||||
|
|
||||||
|
Jakob Rath 2023-06-01
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include "math/polysat/naming.h"
|
||||||
|
#include "math/polysat/solver.h"
|
||||||
|
#include "math/polysat/log.h"
|
||||||
|
|
||||||
|
namespace polysat {
|
||||||
|
|
||||||
|
void name_manager::push_var(pdd pv) {
|
||||||
|
SASSERT(pv.is_var());
|
||||||
|
SASSERT_EQ(pv.var(), m_terms.size());
|
||||||
|
pvar const v = pv.var();
|
||||||
|
m_terms.push_back(std::move(pv));
|
||||||
|
SASSERT(!is_name(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
void name_manager::pop_var() {
|
||||||
|
pvar const v = m_terms.size() - 1;
|
||||||
|
if (is_name(v)) {
|
||||||
|
name_key key{m_terms[v]};
|
||||||
|
m_names.remove(key);
|
||||||
|
}
|
||||||
|
m_terms.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
void name_manager::set_name(pvar v, pdd const& t) {
|
||||||
|
SASSERT(!is_name(v));
|
||||||
|
name_key key{t};
|
||||||
|
SASSERT(!m_names.contains(key));
|
||||||
|
m_names.insert(key, v);
|
||||||
|
m_terms[v] = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
pvar name_manager::get_name(pdd const& t) const {
|
||||||
|
name_key key{t};
|
||||||
|
auto it = m_names.find_iterator(key);
|
||||||
|
if (it == m_names.end())
|
||||||
|
return null_var;
|
||||||
|
return it->m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
pvar name_manager::mk_name(pdd const& t) {
|
||||||
|
if (t.is_var())
|
||||||
|
return t.var();
|
||||||
|
pvar v = get_name(t);
|
||||||
|
if (v != null_var)
|
||||||
|
return v;
|
||||||
|
v = s.add_var(t.power_of_2());
|
||||||
|
s.add_eq(s.var(v), t);
|
||||||
|
set_name(v, t);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
65
src/math/polysat/naming.h
Normal file
65
src/math/polysat/naming.h
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2021 Microsoft Corporation
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
polysat definitions (define variables as names for terms)
|
||||||
|
|
||||||
|
Author:
|
||||||
|
|
||||||
|
Jakob Rath 2023-06-01
|
||||||
|
|
||||||
|
--*/
|
||||||
|
#pragma once
|
||||||
|
#include "math/polysat/types.h"
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
namespace polysat {
|
||||||
|
|
||||||
|
class solver;
|
||||||
|
|
||||||
|
class name_manager final {
|
||||||
|
|
||||||
|
struct name_key {
|
||||||
|
// NOTE: this is only optional because table2map requires a default constructor
|
||||||
|
std::optional<pdd> term;
|
||||||
|
|
||||||
|
name_key() = default;
|
||||||
|
name_key(pdd term): term(std::move(term)) {}
|
||||||
|
|
||||||
|
bool operator==(name_key const& other) const {
|
||||||
|
return term == other.term;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned hash() const {
|
||||||
|
return term ? term->hash() : 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
using name_hash = obj_hash<name_key>;
|
||||||
|
using name_eq = default_eq<name_key>;
|
||||||
|
using name_map = map<name_key, pvar, name_hash, name_eq>;
|
||||||
|
|
||||||
|
solver& s;
|
||||||
|
name_map m_names; // term -> name
|
||||||
|
vector<pdd> m_terms; // name -> term
|
||||||
|
|
||||||
|
void set_name(pvar v, pdd const& term);
|
||||||
|
|
||||||
|
public:
|
||||||
|
name_manager(solver& s): s(s) {}
|
||||||
|
|
||||||
|
void push_var(pdd v);
|
||||||
|
void pop_var();
|
||||||
|
|
||||||
|
/** Whether v is a definition for a term */
|
||||||
|
bool is_name(pvar v) const { return !m_terms[v].is_var() || m_terms[v].var() != v; }
|
||||||
|
|
||||||
|
/** Return name for term, or null_var if none has been created yet */
|
||||||
|
pvar get_name(pdd const& term) const;
|
||||||
|
bool has_name(pdd const& term) const { return get_name(term) != null_var; }
|
||||||
|
|
||||||
|
/** Return name for term, creating one if necessary */
|
||||||
|
pvar mk_name(pdd const& term);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
225
src/math/polysat/slicing.cpp
Normal file
225
src/math/polysat/slicing.cpp
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2023 Microsoft Corporation
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
polysat slicing
|
||||||
|
|
||||||
|
Author:
|
||||||
|
|
||||||
|
Jakob Rath 2023-06-01
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include "math/polysat/slicing.h"
|
||||||
|
#include "math/polysat/solver.h"
|
||||||
|
#include "math/polysat/log.h"
|
||||||
|
|
||||||
|
namespace polysat {
|
||||||
|
|
||||||
|
void slicing::push_var() {
|
||||||
|
m_stack.push_scope(); // TODO: we don't need a scope for each variable
|
||||||
|
#if 0
|
||||||
|
m_src.push_back(null_var);
|
||||||
|
m_hi.push_back(0);
|
||||||
|
m_lo.push_back(0);
|
||||||
|
#endif
|
||||||
|
pvar const v = m_var_slices.size();
|
||||||
|
slice_idx const s = alloc_slice();
|
||||||
|
m_var_slices.push_back(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void slicing::pop_var() {
|
||||||
|
#if 0
|
||||||
|
if (m_src != null_var) {
|
||||||
|
extract_key key{m_src.back(), m_hi.back(), m_lo.back()};
|
||||||
|
m_extracted.remove(key);
|
||||||
|
}
|
||||||
|
m_src.pop_back();
|
||||||
|
m_hi.pop_back();
|
||||||
|
m_lo.pop_back();
|
||||||
|
#endif
|
||||||
|
m_var_slices.pop_back();
|
||||||
|
m_stack.pop_scope(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
slicing::slice_idx slicing::alloc_slice() {
|
||||||
|
slice_idx const s = m_slices_uf.mk_var();
|
||||||
|
SASSERT_EQ(s, m_slices.size());
|
||||||
|
m_slices.push_back({});
|
||||||
|
m_stack.push_ptr(&m_alloc_slice_trail);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void slicing::alloc_slice_trail::undo() {
|
||||||
|
m_owner.m_slices.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
void slicing::set_extract(pvar v, pvar src, unsigned hi, unsigned lo) {
|
||||||
|
#if 0
|
||||||
|
SASSERT(!is_extract(v));
|
||||||
|
SASSERT(lo < hi && hi <= s.size(src));
|
||||||
|
SASSERT_EQ(hi - lo, s.size(v));
|
||||||
|
SASSERT(src < v);
|
||||||
|
SASSERT(!m_extracted.contains(extract_key{src, hi, lo}));
|
||||||
|
#if 0 // try without this first
|
||||||
|
if (is_extract(src)) {
|
||||||
|
// y = (x[k:m])[h:l] = x[h+m:l+m]
|
||||||
|
unsigned const offset = m_lo[src];
|
||||||
|
set_extract(m_src[src], hi + offset, lo + offset);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
m_extracted.insert({src, hi, lo}, v);
|
||||||
|
m_src[v] = src;
|
||||||
|
m_hi[v] = hi;
|
||||||
|
m_lo[v] = lo;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
slicing::slice_info slicing::var2slice(pvar v) const {
|
||||||
|
slice_info si;
|
||||||
|
si.idx = m_var_slices[v];
|
||||||
|
si.hi = s.size(v) - 1;
|
||||||
|
si.lo = 0;
|
||||||
|
return si;
|
||||||
|
}
|
||||||
|
|
||||||
|
slicing::slice_info slicing::sub_hi(slice_info const& parent) const {
|
||||||
|
SASSERT(has_sub(parent));
|
||||||
|
slice const& parent_slice = m_slices[parent.idx];
|
||||||
|
slice_info si;
|
||||||
|
si.idx = parent_slice.sub;
|
||||||
|
si.hi = parent.hi;
|
||||||
|
si.lo = parent_slice.cut + 1;
|
||||||
|
SASSERT(si.hi >= si.lo);
|
||||||
|
return si;
|
||||||
|
}
|
||||||
|
|
||||||
|
slicing::slice_info slicing::sub_lo(slice_info const& parent) const {
|
||||||
|
SASSERT(has_sub(parent));
|
||||||
|
slice const& parent_slice = m_slices[parent.idx];
|
||||||
|
slice_info si;
|
||||||
|
si.idx = parent_slice.sub + 1;
|
||||||
|
si.hi = parent_slice.cut;
|
||||||
|
si.lo = parent.lo;
|
||||||
|
SASSERT(si.hi >= si.lo);
|
||||||
|
return si;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned slicing::get_cut(slice_info const& si) const {
|
||||||
|
SASSERT(has_sub(si));
|
||||||
|
return m_slices[si.idx].cut;
|
||||||
|
}
|
||||||
|
|
||||||
|
void slicing::split(slice_info const& si, unsigned const cut) {
|
||||||
|
SASSERT(!has_sub(si));
|
||||||
|
SASSERT(si.hi > cut); SASSERT(cut >= si.lo);
|
||||||
|
slice_idx const sub1 = alloc_slice();
|
||||||
|
slice_idx const sub2 = alloc_slice();
|
||||||
|
slice& s = m_slices[si.idx];
|
||||||
|
s.cut = cut;
|
||||||
|
s.sub = sub1;
|
||||||
|
SASSERT_EQ(sub2, sub1 + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void slicing::mk_slice(slice_info const& src, unsigned const hi, unsigned const lo, vector<slice_info>& out)
|
||||||
|
{
|
||||||
|
// extracted range must be fully contained inside the src slice
|
||||||
|
SASSERT(src.hi >= hi); SASSERT(hi >= lo); SASSERT(lo >= src.lo);
|
||||||
|
if (src.hi == hi && src.lo == lo) {
|
||||||
|
out.push_back(src);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (has_sub(src)) {
|
||||||
|
// src is split into [src.hi, cut+1] and [cut, src.lo]
|
||||||
|
unsigned const cut = get_cut(src);
|
||||||
|
if (lo >= cut + 1)
|
||||||
|
return mk_slice(sub_hi(src), hi, lo, out);
|
||||||
|
else if (cut >= hi)
|
||||||
|
return mk_slice(sub_lo(src), hi, lo, out);
|
||||||
|
else {
|
||||||
|
SASSERT(hi > cut && cut >= lo);
|
||||||
|
// desired range spans over the cutpoint, so we get multiple slices in the result
|
||||||
|
mk_slice(sub_hi(src), hi, cut + 1, out);
|
||||||
|
mk_slice(sub_lo(src), cut, lo, out);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// [src.hi, src.lo] has no subdivision yet
|
||||||
|
if (src.hi > hi) {
|
||||||
|
split(src, hi);
|
||||||
|
mk_slice(sub_lo(src), hi, lo, out);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SASSERT(src.hi == hi);
|
||||||
|
SASSERT(lo > src.lo);
|
||||||
|
split(src, lo - 1);
|
||||||
|
slice_info si = sub_hi(src);
|
||||||
|
SASSERT_EQ(si.hi, hi); SASSERT_EQ(si.lo, lo);
|
||||||
|
out.push_back(si);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
pvar slicing::mk_extract_var(pvar src, unsigned hi, unsigned lo) {
|
||||||
|
vector<slice_info> slices;
|
||||||
|
mk_slice(var2slice(src), hi, lo, slices);
|
||||||
|
// src[hi:lo] is the concatenation of the returned slices
|
||||||
|
// TODO: for each slice, set_extract
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
extract_key key{src, hi, lo};
|
||||||
|
auto it = m_extracted.find_iterator(key);
|
||||||
|
if (it != m_extracted.end())
|
||||||
|
return it->m_value;
|
||||||
|
pvar v = s.add_var(hi - lo);
|
||||||
|
set_extract(v, src, hi, lo);
|
||||||
|
return v;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
pdd slicing::mk_extract(pvar src, unsigned hi, unsigned lo) {
|
||||||
|
return s.var(mk_extract_var(src, hi, lo));
|
||||||
|
}
|
||||||
|
|
||||||
|
pdd slicing::mk_extract(pdd const& p, unsigned hi, unsigned lo) {
|
||||||
|
if (!lo) {
|
||||||
|
// TODO: we could push the extract down into variables of the term instead of introducing a name.
|
||||||
|
}
|
||||||
|
pvar const v = s.m_names.mk_name(p);
|
||||||
|
return mk_extract(v, hi, lo);
|
||||||
|
}
|
||||||
|
|
||||||
|
pdd slicing::mk_concat(pdd const& p, pdd const& q) {
|
||||||
|
#if 0
|
||||||
|
// v := p ++ q (new variable of size |p| + |q|)
|
||||||
|
// v[:|q|] = p
|
||||||
|
// v[|q|:] = q
|
||||||
|
unsigned const p_sz = p.power_of_2();
|
||||||
|
unsigned const q_sz = q.power_of_2();
|
||||||
|
unsigned const v_sz = p_sz + q_sz;
|
||||||
|
// TODO: lookup to see if we can reuse a variable
|
||||||
|
// either:
|
||||||
|
// - table of concats
|
||||||
|
// - check for variable with v[:|q|] = p and v[|q|:] = q in extract table (probably better)
|
||||||
|
pvar const v = s.add_var(v_sz);
|
||||||
|
|
||||||
|
// TODO: probably wrong to use names for p, q.
|
||||||
|
// we should rather check if there's already an extraction for v[...] and reuse that variable.
|
||||||
|
pvar const p_name = s.m_names.mk_name(p);
|
||||||
|
pvar const q_name = s.m_names.mk_name(q);
|
||||||
|
set_extract(p_name, v, v_sz, q_sz);
|
||||||
|
set_extract(q_name, v, q_sz, 0);
|
||||||
|
#endif
|
||||||
|
NOT_IMPLEMENTED_YET();
|
||||||
|
}
|
||||||
|
|
||||||
|
void slicing::propagate(pvar v) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
154
src/math/polysat/slicing.h
Normal file
154
src/math/polysat/slicing.h
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2023 Microsoft Corporation
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
polysat slicing (relating variables of different bit-widths by extraction)
|
||||||
|
|
||||||
|
Author:
|
||||||
|
|
||||||
|
Jakob Rath 2023-06-01
|
||||||
|
|
||||||
|
Notation:
|
||||||
|
|
||||||
|
Let x be a bit-vector of width w.
|
||||||
|
Let l, h indices such that 0 <= l <= h < w.
|
||||||
|
Then x[h:l] extracts h - l + 1 bits of x.
|
||||||
|
Shorthands:
|
||||||
|
- x[h:] stands for x[h:0], and
|
||||||
|
- x[:l] stands for x[w-1:l].
|
||||||
|
|
||||||
|
Example:
|
||||||
|
0001[0:] = 1
|
||||||
|
0001[2:0] = 001
|
||||||
|
|
||||||
|
--*/
|
||||||
|
#pragma once
|
||||||
|
#include "math/polysat/types.h"
|
||||||
|
#include "util/trail.h"
|
||||||
|
#include "util/union_find.h"
|
||||||
|
|
||||||
|
namespace polysat {
|
||||||
|
|
||||||
|
class solver;
|
||||||
|
|
||||||
|
class slicing final {
|
||||||
|
|
||||||
|
solver& s;
|
||||||
|
|
||||||
|
/// If y := x[h:l], then m_src[y] = x, m_hi[y] = h, m_lo[y] = l.
|
||||||
|
/// Otherwise m_src[y] = null_var.
|
||||||
|
///
|
||||||
|
/// Invariants:
|
||||||
|
/// m_src[y] != null_var ==> m_src[y] < y (at least as long as we always introduce new variables for extract terms.)
|
||||||
|
/// m_lo[y] <= m_hi[y]
|
||||||
|
unsigned_vector m_src;
|
||||||
|
unsigned_vector m_hi;
|
||||||
|
unsigned_vector m_lo;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
struct extract_key {
|
||||||
|
pvar src;
|
||||||
|
unsigned hi;
|
||||||
|
unsigned lo;
|
||||||
|
|
||||||
|
bool operator==(extract_key const& other) const {
|
||||||
|
return src == other.src && hi == other.hi && lo == other.lo;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned hash() const {
|
||||||
|
return mk_mix(src, hi, lo);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
using extract_hash = obj_hash<extract_key>;
|
||||||
|
using extract_eq = default_eq<extract_key>;
|
||||||
|
using extract_map = map<extract_key, pvar, extract_hash, extract_eq>;
|
||||||
|
|
||||||
|
extract_map m_extracted; ///< src, hi, lo -> v
|
||||||
|
// need src -> [v] and v -> [src] for propagation?
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
trail_stack m_stack;
|
||||||
|
|
||||||
|
using slice_idx = unsigned;
|
||||||
|
static constexpr slice_idx null_slice_idx = UINT_MAX;
|
||||||
|
|
||||||
|
struct slice {
|
||||||
|
// If sub != null_slice_idx, the bit-vector x has been sliced into x[|x|-1:cut+1] and x[cut:0]
|
||||||
|
unsigned cut = UINT_MAX;
|
||||||
|
// If sub != null_slice_idx, the sub-slices are at indices sub and sub+1
|
||||||
|
slice_idx sub = null_slice_idx;
|
||||||
|
|
||||||
|
bool has_sub() const { return cut != 0; }
|
||||||
|
slice_idx sub_hi() const { return sub; }
|
||||||
|
slice_idx sub_lo() const { return sub + 1; }
|
||||||
|
};
|
||||||
|
svector<slice> m_slices; // slice_idx -> slice
|
||||||
|
svector<slice_idx> m_var_slices; // pvar -> slice_idx
|
||||||
|
|
||||||
|
// union_find over slices (union_find vars are indices into m_slices, i.e., slice_idx)
|
||||||
|
union_find<slicing> m_slices_uf;
|
||||||
|
|
||||||
|
slice_idx alloc_slice();
|
||||||
|
|
||||||
|
friend class alloc_slice_trail;
|
||||||
|
class alloc_slice_trail : public trail {
|
||||||
|
slicing& m_owner;
|
||||||
|
public:
|
||||||
|
alloc_slice_trail(slicing& o): m_owner(o) {}
|
||||||
|
void undo() override;
|
||||||
|
};
|
||||||
|
alloc_slice_trail m_alloc_slice_trail;
|
||||||
|
|
||||||
|
void set_extract(pvar v, pvar src, unsigned hi_bit, unsigned lo_bit);
|
||||||
|
|
||||||
|
struct slice_info {
|
||||||
|
slice_idx idx;
|
||||||
|
unsigned hi;
|
||||||
|
unsigned lo;
|
||||||
|
};
|
||||||
|
slice_info var2slice(pvar v) const;
|
||||||
|
bool has_sub(slice_info const& si) const { return m_slices[si.idx].has_sub(); }
|
||||||
|
slice_info sub_hi(slice_info const& si) const;
|
||||||
|
slice_info sub_lo(slice_info const& si) const;
|
||||||
|
unsigned get_cut(slice_info const& si) const;
|
||||||
|
void split(slice_info const& si, unsigned cut);
|
||||||
|
void mk_slice(slice_info const& src, unsigned hi, unsigned lo, vector<slice_info>& out);
|
||||||
|
|
||||||
|
public:
|
||||||
|
slicing(solver& s):
|
||||||
|
s(s),
|
||||||
|
m_slices_uf(*this),
|
||||||
|
m_alloc_slice_trail(*this)
|
||||||
|
{}
|
||||||
|
|
||||||
|
trail_stack& get_trail_stack() { return m_stack; }
|
||||||
|
|
||||||
|
void push_var();
|
||||||
|
void pop_var();
|
||||||
|
|
||||||
|
bool is_extract(pvar v) const { return m_src[v] != null_var; }
|
||||||
|
|
||||||
|
/** Get variable representing x[hi:lo] */
|
||||||
|
pvar mk_extract_var(pvar x, unsigned hi, unsigned lo);
|
||||||
|
|
||||||
|
/** Create expression for x[hi:lo] */
|
||||||
|
pdd mk_extract(pvar x, unsigned hi, unsigned lo);
|
||||||
|
|
||||||
|
/** Create expression for p[hi:lo] */
|
||||||
|
pdd mk_extract(pdd const& p, unsigned hi, unsigned lo);
|
||||||
|
|
||||||
|
/** Create expression for p ++ q */
|
||||||
|
pdd mk_concat(pdd const& p, pdd const& q);
|
||||||
|
|
||||||
|
// propagate:
|
||||||
|
// - value assignments
|
||||||
|
// - fixed bits
|
||||||
|
// - intervals ????? -- that will also need changes in the viable algorithm
|
||||||
|
void propagate(pvar v);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -41,6 +41,8 @@ namespace polysat {
|
||||||
m_bvars(*this),
|
m_bvars(*this),
|
||||||
m_free_pvars(m_activity),
|
m_free_pvars(m_activity),
|
||||||
m_constraints(*this),
|
m_constraints(*this),
|
||||||
|
m_names(*this),
|
||||||
|
m_slicing(*this),
|
||||||
m_search(*this) {
|
m_search(*this) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +136,7 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned solver::add_var(unsigned sz) {
|
unsigned solver::add_var(unsigned sz) {
|
||||||
pvar v = m_value.size();
|
pvar const v = m_value.size();
|
||||||
m_value.push_back(rational::zero());
|
m_value.push_back(rational::zero());
|
||||||
m_justification.push_back(justification::unassigned());
|
m_justification.push_back(justification::unassigned());
|
||||||
m_viable.push_var(sz);
|
m_viable.push_var(sz);
|
||||||
|
@ -145,6 +147,7 @@ namespace polysat {
|
||||||
m_size.push_back(sz);
|
m_size.push_back(sz);
|
||||||
m_trail.push_back(trail_instr_t::add_var_i);
|
m_trail.push_back(trail_instr_t::add_var_i);
|
||||||
m_free_pvars.mk_var_eh(v);
|
m_free_pvars.mk_var_eh(v);
|
||||||
|
m_names.push_var(var(v)); // needs m_vars
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,6 +168,7 @@ namespace polysat {
|
||||||
m_vars.pop_back();
|
m_vars.pop_back();
|
||||||
m_size.pop_back();
|
m_size.pop_back();
|
||||||
m_free_pvars.del_var_eh(v);
|
m_free_pvars.del_var_eh(v);
|
||||||
|
m_names.pop_var();
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::assign_eh(signed_constraint c, dependency dep) {
|
void solver::assign_eh(signed_constraint c, dependency dep) {
|
||||||
|
|
|
@ -24,8 +24,10 @@ Author:
|
||||||
#include "math/polysat/constraint.h"
|
#include "math/polysat/constraint.h"
|
||||||
#include "math/polysat/constraint_manager.h"
|
#include "math/polysat/constraint_manager.h"
|
||||||
#include "math/polysat/clause_builder.h"
|
#include "math/polysat/clause_builder.h"
|
||||||
|
#include "math/polysat/naming.h"
|
||||||
#include "math/polysat/simplify_clause.h"
|
#include "math/polysat/simplify_clause.h"
|
||||||
#include "math/polysat/simplify.h"
|
#include "math/polysat/simplify.h"
|
||||||
|
#include "math/polysat/slicing.h"
|
||||||
#include "math/polysat/restart.h"
|
#include "math/polysat/restart.h"
|
||||||
#include "math/polysat/ule_constraint.h"
|
#include "math/polysat/ule_constraint.h"
|
||||||
#include "math/polysat/justification.h"
|
#include "math/polysat/justification.h"
|
||||||
|
@ -118,6 +120,7 @@ namespace polysat {
|
||||||
friend class conflict_explainer;
|
friend class conflict_explainer;
|
||||||
friend class simplify_clause;
|
friend class simplify_clause;
|
||||||
friend class simplify;
|
friend class simplify;
|
||||||
|
friend class slicing;
|
||||||
friend class restart;
|
friend class restart;
|
||||||
friend class explainer;
|
friend class explainer;
|
||||||
friend class inference_engine;
|
friend class inference_engine;
|
||||||
|
@ -136,6 +139,7 @@ namespace polysat {
|
||||||
friend class saturation;
|
friend class saturation;
|
||||||
friend class parity_tracker;
|
friend class parity_tracker;
|
||||||
friend class constraint_manager;
|
friend class constraint_manager;
|
||||||
|
friend class name_manager;
|
||||||
friend class scoped_solverv;
|
friend class scoped_solverv;
|
||||||
friend class test_polysat;
|
friend class test_polysat;
|
||||||
friend class test_fi;
|
friend class test_fi;
|
||||||
|
@ -160,6 +164,8 @@ namespace polysat {
|
||||||
config m_config;
|
config m_config;
|
||||||
// Per constraint state
|
// Per constraint state
|
||||||
constraint_manager m_constraints;
|
constraint_manager m_constraints;
|
||||||
|
name_manager m_names;
|
||||||
|
slicing m_slicing;
|
||||||
|
|
||||||
// Per variable information
|
// Per variable information
|
||||||
vector<rational> m_value; // assigned value
|
vector<rational> m_value; // assigned value
|
||||||
|
@ -313,6 +319,9 @@ namespace polysat {
|
||||||
|
|
||||||
void push_reinit_stack(clause& c);
|
void push_reinit_stack(clause& c);
|
||||||
|
|
||||||
|
/** Get variable representing v[hi:lo] */
|
||||||
|
pvar extract_var(pvar v, unsigned hi, unsigned lo);
|
||||||
|
|
||||||
void add_clause(clause_ref clause);
|
void add_clause(clause_ref clause);
|
||||||
void add_clause(clause& clause);
|
void add_clause(clause& clause);
|
||||||
void add_clause(signed_constraint c1, bool is_redundant);
|
void add_clause(signed_constraint c1, bool is_redundant);
|
||||||
|
@ -405,6 +414,12 @@ namespace polysat {
|
||||||
*/
|
*/
|
||||||
pdd var(pvar v) { return m_vars[v]; }
|
pdd var(pvar v) { return m_vars[v]; }
|
||||||
|
|
||||||
|
/** Create expression for v[hi:lo] */
|
||||||
|
pdd extract(pvar v, unsigned hi, unsigned lo);
|
||||||
|
|
||||||
|
/** Create expression for p[hi:lo] */
|
||||||
|
pdd extract(pdd const& p, unsigned hi, unsigned lo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create terms for unsigned quot-rem
|
* Create terms for unsigned quot-rem
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue