3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-05-14 03:04:44 +00:00
z3/src/math/polysat/assignment.h
2022-11-30 14:50:14 +01:00

118 lines
4 KiB
C++

/*++
Copyright (c) 2021 Microsoft Corporation
Module Name:
polysat substitution and assignment
Author:
Nikolaj Bjorner (nbjorner) 2021-03-19
Jakob Rath 2021-04-06
--*/
#pragma once
#include "math/polysat/types.h"
namespace polysat {
using assignment_item_t = std::pair<pvar, rational>;
class substitution_iterator {
pdd m_current;
substitution_iterator(pdd current) : m_current(std::move(current)) {}
friend class substitution;
public:
using value_type = assignment_item_t;
using difference_type = std::ptrdiff_t;
using pointer = value_type const*;
using reference = value_type const&;
using iterator_category = std::input_iterator_tag;
substitution_iterator& operator++() {
SASSERT(!m_current.is_val());
m_current = m_current.hi();
return *this;
}
value_type operator*() const {
SASSERT(!m_current.is_val());
return { m_current.var(), m_current.lo().val() };
}
bool operator==(substitution_iterator const& other) const { return m_current == other.m_current; }
bool operator!=(substitution_iterator const& other) const { return !operator==(other); }
};
/** Substitution for a single bit width. */
class substitution {
pdd m_subst;
substitution(pdd p);
public:
substitution(dd::pdd_manager& m);
substitution add(pvar var, rational const& value) const;
pdd apply_to(pdd const& p) const;
bool contains(pvar var) const;
bool value(pvar var, rational& out_value) const;
bool empty() const { return m_subst.is_one(); }
pdd const& to_pdd() const { return m_subst; }
unsigned bit_width() const { return to_pdd().power_of_2(); }
bool operator==(substitution const& other) const { return &m_subst.manager() == &other.m_subst.manager() && m_subst == other.m_subst; }
bool operator!=(substitution const& other) const { return !operator==(other); }
std::ostream& display(std::ostream& out) const;
using const_iterator = substitution_iterator;
const_iterator begin() const { return {m_subst}; }
const_iterator end() const { return {m_subst.manager().one()}; }
};
/** Full variable assignment, may include variables of varying bit widths. */
class assignment {
solver* m_solver;
vector<assignment_item_t> m_pairs; // TODO: do we still need this?
mutable scoped_ptr_vector<substitution> m_subst;
vector<substitution> m_subst_trail;
substitution& subst(unsigned sz);
solver& s() const { return *m_solver; }
public:
assignment(solver& s);
// prevent implicit copy, use clone() if you do need a copy
assignment(assignment const&) = delete;
assignment& operator=(assignment const&) = delete;
assignment(assignment&&) = default;
assignment& operator=(assignment&&) = default;
assignment clone() const;
void push(pvar var, rational const& value);
void pop();
pdd apply_to(pdd const& p) const;
bool contains(pvar var) const;
bool value(pvar var, rational& out_value) const;
rational value(pvar var) const { rational val; VERIFY(value(var, val)); return val; }
bool empty() const { return pairs().empty(); }
substitution const& subst(unsigned sz) const;
vector<assignment_item_t> const& pairs() const { return m_pairs; }
using const_iterator = decltype(m_pairs)::const_iterator;
const_iterator begin() const { return pairs().begin(); }
const_iterator end() const { return pairs().end(); }
std::ostream& display(std::ostream& out) const;
};
using assignment_t = assignment;
inline std::ostream& operator<<(std::ostream& out, substitution const& sub) { return sub.display(out); }
inline std::ostream& operator<<(std::ostream& out, assignment const& a) { return a.display(out); }
}