z3-z3-4.13.0.src.math.dd.pdd_interval.h Maven / Gradle / Ivy
The newest version!
/*++
Copyright (c) 2019 Microsoft Corporation
Module Name:
dd_pdd.cpp
Abstract:
Poly DD package
Author:
Nikolaj Bjorner (nbjorner) 2019-12-24
Lev Nachmanson (levnach) 2019-12-24
Revision History:
--*/
#pragma once
#include "math/dd/dd_pdd.h"
#include "math/interval/dep_intervals.h"
namespace dd {
typedef dep_intervals::interval interval;
typedef dep_intervals::with_deps_t w_dep;
// calculates the interval of a pdd expression based on the given intervals of the variables
class pdd_interval {
dep_intervals& m_dep_intervals;
std::function m_var2interval;
// retrieve intervals after distributing multiplication over addition.
template
void get_interval_distributed(pdd const& p, scoped_dep_interval& i, scoped_dep_interval& ret) {
bool deps = wd == w_dep::with_deps;
if (p.is_val()) {
if (deps)
m_dep_intervals.mul(p.val(), i, ret);
else
m_dep_intervals.mul(p.val(), i, ret);
return;
}
scoped_dep_interval hi(m()), lo(m()), t(m()), a(m());
get_interval_distributed(p.lo(), i, lo);
m_var2interval(p.var(), deps, a);
if (deps) {
m_dep_intervals.mul(a, i, t);
get_interval_distributed(p.hi(), t, hi);
m_dep_intervals.add(hi, lo, ret);
}
else {
m_dep_intervals.mul(a, i, t);
get_interval_distributed(p.hi(), t, hi);
m_dep_intervals.add(hi, lo, ret);
}
}
public:
pdd_interval(dep_intervals& d): m_dep_intervals(d) {}
dep_intervals& m() { return m_dep_intervals; }
std::function& var2interval() { return m_var2interval; } // setter
const std::function& var2interval() const { return m_var2interval; } // getter
template
void get_interval(pdd const& p, scoped_dep_interval& ret) {
if (p.is_val()) {
m_dep_intervals.set_interval_for_scalar(ret, p.val());
return;
}
bool deps = wd == w_dep::with_deps;
scoped_dep_interval hi(m()), lo(m()), t(m()), a(m());
m_var2interval(p.var(), deps, a);
get_interval(p.hi(), hi);
get_interval(p.lo(), lo);
if (deps) {
m_dep_intervals.mul(hi, a, t);
m_dep_intervals.add(t, lo, ret);
} else {
m_dep_intervals.mul(hi, a, t);
m_dep_intervals.add(t, lo, ret);
}
}
template
void get_interval_distributed(pdd const& p, scoped_dep_interval& ret) {
scoped_dep_interval i(m());
m_dep_intervals.set_interval_for_scalar(i, rational::one());
get_interval_distributed(p, i, ret);
}
};
}