z3-z3-4.13.0.src.nlsat.nlsat_assignment.h Maven / Gradle / Ivy
The newest version!
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
nlsat_assignment.h
Abstract:
Assignment: Var -> Algebraic Number
Author:
Leonardo de Moura (leonardo) 2012-01-08.
Revision History:
--*/
#pragma once
#include "nlsat/nlsat_types.h"
#include "math/polynomial/algebraic_numbers.h"
namespace nlsat {
/**
\brief A mapping from variables to values.
This mapping is used to encode the current partial interpretation in nlsat.
*/
class assignment : public polynomial::var2anum {
scoped_anum_vector m_values;
bool_vector m_assigned;
public:
assignment(anum_manager & _m):m_values(_m) {}
anum_manager & am() const { return m_values.m(); }
void swap(assignment & other) noexcept {
m_values.swap(other.m_values);
m_assigned.swap(other.m_assigned);
}
void copy(assignment const& other) {
m_assigned.reset();
m_assigned.append(other.m_assigned);
m_values.reserve(m_assigned.size(), anum());
for (unsigned i = 0; i < m_assigned.size(); ++i) {
if (is_assigned(i)) {
am().set(m_values[i], other.value(i));
}
}
}
void set_core(var x, anum & v) {
m_values.reserve(x+1, anum());
m_assigned.reserve(x+1, false);
m_assigned[x] = true;
am().swap(m_values[x], v);
}
void set(var x, anum const & v) {
m_values.reserve(x+1, anum());
m_assigned.reserve(x+1, false);
m_assigned[x] = true;
am().set(m_values[x], v);
}
void reset(var x) { if (x < m_assigned.size()) m_assigned[x] = false; }
void reset() { m_assigned.reset(); }
bool is_assigned(var x) const { return m_assigned.get(x, false); }
anum const & value(var x) const { return m_values[x]; }
anum_manager & m() const override { return am(); }
bool contains(var x) const override { return is_assigned(x); }
anum const & operator()(var x) const override { SASSERT(is_assigned(x)); return value(x); }
void swap(var x, var y) noexcept {
SASSERT(x < m_values.size() && y < m_values.size());
std::swap(m_assigned[x], m_assigned[y]);
std::swap(m_values[x], m_values[y]);
}
void display(std::ostream& out) const {
for (unsigned i = 0; i < m_assigned.size(); ++i) {
if (m_assigned[i]) {
out << "x" << i << " := ";
m_values.m().display(out, m_values[i]);
out << "\n";
}
}
}
};
/**
\brief Wrapper for temporarily unassigning a given variable y.
That is, given an assignment M, M' = undef_var_assignment(M, y) is identical
to M, but y is unassigned in M'
*/
class undef_var_assignment : public polynomial::var2anum {
assignment const & m_assignment;
var m_y;
public:
undef_var_assignment(assignment const & a, var y):m_assignment(a), m_y(y) {}
anum_manager & m() const override { return m_assignment.am(); }
bool contains(var x) const override { return x != m_y && m_assignment.is_assigned(x); }
anum const & operator()(var x) const override { return m_assignment.value(x); }
};
};