This PR adds proofs for the sine shift lemmas that add equivalent instances of the sine function where the argument is in its "main phase" between minus pi and pi.
case PfRule::INT_TRUST: return "INT_TRUST";
case PfRule::ARITH_MULT_TANGENT: return "ARITH_MULT_TANGENT";
case PfRule::ARITH_OP_ELIM_AXIOM: return "ARITH_OP_ELIM_AXIOM";
+ case PfRule::ARITH_TRANS_SINE_SHIFT: return "ARITH_TRANS_SINE_SHIFT";
//================================================= Unknown rule
case PfRule::UNKNOWN: return "UNKNOWN";
default: return "?";
// or 1. tplane is the tangent plane of x*y at (a,b): b*x + a*y - a*b
ARITH_MULT_TANGENT,
+ //======== Sine arg shifted to -pi..pi
+ // Children: none
+ // Arguments: (x, y, s)
+ // ---------------------
+ // Conclusion: (and
+ // (<= -pi y pi)
+ // (= (sin y) (sin x))
+ // (ite (<= -pi x pi) (= x y) (= x (+ y (* 2 pi s))))
+ // )
+ // Where x is the argument to sine, y is a new real skolem that is x shifted
+ // into -pi..pi and s is a new integer skolem that is the number of phases y
+ // is shifted.
+ ARITH_TRANS_SINE_SHIFT,
+
//================================================= Unknown rule
UNKNOWN,
};
void TranscendentalProofRuleChecker::registerTo(ProofChecker* pc)
{
+ pc->registerChecker(PfRule::ARITH_TRANS_SINE_SHIFT, this);
}
Node TranscendentalProofRuleChecker::checkInternal(
{
Trace("nl-trans-checker") << "\t" << c << std::endl;
}
+ if (id == PfRule::ARITH_TRANS_SINE_SHIFT)
+ {
+ Assert(children.empty());
+ Assert(args.size() == 3);
+ const auto& x = args[0];
+ const auto& y = args[1];
+ const auto& s = args[2];
+ return nm->mkAnd(std::vector<Node>{
+ nm->mkAnd(std::vector<Node>{
+ nm->mkNode(Kind::GEQ, y, nm->mkNode(Kind::MULT, mone, pi)),
+ nm->mkNode(Kind::LEQ, y, pi)}),
+ nm->mkNode(
+ Kind::ITE,
+ nm->mkAnd(std::vector<Node>{
+ nm->mkNode(Kind::GEQ, x, nm->mkNode(Kind::MULT, mone, pi)),
+ nm->mkNode(Kind::LEQ, x, pi),
+ }),
+ x.eqNode(y),
+ x.eqNode(nm->mkNode(
+ Kind::PLUS,
+ y,
+ nm->mkNode(Kind::MULT, nm->mkConst<Rational>(2), s, pi)))),
+ nm->mkNode(Kind::SINE, y).eqNode(nm->mkNode(Kind::SINE, x))});
+ }
return Node::null();
}
shift,
d_data->d_pi)))),
new_a.eqNode(a));
+ CDProof* proof = nullptr;
+ if (d_data->isProofEnabled())
+ {
+ proof = d_data->getProof();
+ proof->addStep(lem, PfRule::ARITH_TRANS_SINE_SHIFT, {}, {a[0], y, shift});
+ }
// note we must do preprocess on this lemma
Trace("nl-ext-lemma") << "NonlinearExtension::Lemma : purify : " << lem
<< std::endl;
NlLemma nlem(
- lem, LemmaProperty::PREPROCESS, nullptr, InferenceId::NL_T_PURIFY_ARG);
+ lem, LemmaProperty::PREPROCESS, proof, InferenceId::NL_T_PURIFY_ARG);
d_data->d_im.addPendingArithLemma(nlem);
}