d_data->d_zero,
d_data->d_pi_neg_2,
d_data->d_pi_neg};
- std::vector<Node> mpoints_vals;
-
- // get model values for points
- for (const auto& point : mpoints)
+ // Sound lower (index=0), upper (index=1) bounds for the above points. We
+ // compute this by plugging in the upper and lower bound of pi.
+ std::vector<Node> mpointsBound[2];
+ TNode tpi = d_data->d_pi;
+ for (size_t j = 0; j < 5; j++)
{
- mpoints_vals.emplace_back(d_data->d_model.computeAbstractModelValue(point));
- Assert(mpoints_vals.back().isConst());
+ Node point = mpoints[j];
+ for (size_t i = 0; i < 2; i++)
+ {
+ Node mpointapprox = point;
+ if (j != 2)
+ {
+ // substitute the lower or upper bound of pi
+ TNode tb = d_data->d_pi_bound[i];
+ mpointapprox = point.substitute(tpi, tb);
+ mpointapprox = d_data->d_model.computeConcreteModelValue(mpointapprox);
+ }
+ Assert(mpointapprox.isConst());
+ mpointsBound[i].emplace_back(mpointapprox);
+ }
+ // bounds are flipped for negative pi
+ if (mpointsBound[0].back().getConst<Rational>()
+ > mpointsBound[1].back().getConst<Rational>())
+ {
+ std::swap(mpointsBound[0].back(), mpointsBound[1].back());
+ }
}
unsigned mdir_index = 0;
{
Node sargval = d_data->d_model.computeAbstractModelValue(sarg);
Assert(sargval.isConst());
+ const Rational& sargvalr = sargval.getConst<Rational>();
Node s = tf_arg_to_term[sarg];
Node sval = d_data->d_model.computeAbstractModelValue(s);
Assert(sval.isConst());
while (increment && mdir_index < mpoints.size())
{
increment = false;
- Node pval = mpoints_vals[mdir_index];
- Assert(pval.isConst());
- if (sargval.getConst<Rational>() < pval.getConst<Rational>())
+ // if we are less than the upper bound of the next point
+ Node pvalUpper = mpointsBound[1][mdir_index];
+ Assert(pvalUpper.isConst());
+ if (sargvalr < pvalUpper.getConst<Rational>())
{
increment = true;
Trace("nl-ext-tf-mono")
<< "...increment at " << sarg << " since model value is less than "
- << mpoints[mdir_index] << std::endl;
+ << mpointsBound[1][mdir_index] << std::endl;
}
if (increment)
{
}
}
}
- // store the concavity region
- d_data->d_tf_region[s] = mdir_index;
- Trace("nl-ext-concavity")
- << "Transcendental function " << s << " is in region #" << mdir_index;
+ // must ensure that we are actually less than or equal to the lower bound of
+ // the previous point
+ if (mdir_index > 0
+ && sargvalr > mpointsBound[0][mdir_index - 1].getConst<Rational>())
+ {
+ d_data->d_tf_region[s] = -1;
+ Trace("nl-ext-concavity")
+ << "Cannot determine the region of transcendental function " << s
+ << ", perhaps its value is close to the boundary "
+ << mpointsBound[1][mdir_index - 1];
+ }
+ else
+ {
+ // store the concavity region
+ d_data->d_tf_region[s] = mdir_index;
+ Trace("nl-ext-concavity")
+ << "Transcendental function " << s << " is in region #" << mdir_index;
+ }
Trace("nl-ext-concavity") << ", arg model value = " << sargval << std::endl;
if (!tval.isNull())
TNode e, TNode c, TNode poly_approx, int region, std::uint64_t d)
{
NodeManager* nm = NodeManager::currentNM();
+ Assert(region != -1);
+ Trace("nl-ext-sine") << c << " in region " << region << std::endl;
// compute tangent plane
// Figure 3: T( x )
// We use zero slope tangent planes, since the concavity of the Taylor
unsigned actual_d,
int region)
{
+ Assert(region != -1);
d_data->doSecantLemmas(getSecantBounds(e, c, d, region),
poly_approx,
c,