summaryrefslogtreecommitdiff
path: root/src/theory/arith/nonlinear_extension.cpp
diff options
context:
space:
mode:
authorajreynol <andrew.j.reynolds@gmail.com>2017-08-10 06:08:46 -0500
committerajreynol <andrew.j.reynolds@gmail.com>2017-08-11 01:06:50 -0500
commit4b5460a79838e93f8d417462c930806a77c09d31 (patch)
treecc5cff557348caf6310393fe7fb5996b46526b19 /src/theory/arith/nonlinear_extension.cpp
parent0ce756c379c753899c62f88e725bac4a55dea1cd (diff)
Maintain frontier for tangent planes.
Diffstat (limited to 'src/theory/arith/nonlinear_extension.cpp')
-rw-r--r--src/theory/arith/nonlinear_extension.cpp76
1 files changed, 54 insertions, 22 deletions
diff --git a/src/theory/arith/nonlinear_extension.cpp b/src/theory/arith/nonlinear_extension.cpp
index 42f9636dc..3c3301db1 100644
--- a/src/theory/arith/nonlinear_extension.cpp
+++ b/src/theory/arith/nonlinear_extension.cpp
@@ -2034,28 +2034,60 @@ std::vector<Node> NonlinearExtension::checkTangentPlanes() {
dproc[a][b] = true;
Trace("nl-ext-tplanes")
<< " decomposable into : " << a << " * " << b << std::endl;
- Node a_v = computeModelValue(a, 1);
- Node b_v = computeModelValue(b, 1);
- // tangent plane
- Node tplane = NodeManager::currentNM()->mkNode(
- kind::MINUS,
- NodeManager::currentNM()->mkNode(
- kind::PLUS,
- NodeManager::currentNM()->mkNode(kind::MULT, b_v, a),
- NodeManager::currentNM()->mkNode(kind::MULT, a_v, b)),
- NodeManager::currentNM()->mkNode(kind::MULT, a_v, b_v));
- for (unsigned d = 0; d < 4; d++) {
- Node aa = NodeManager::currentNM()->mkNode(
- d == 0 || d == 3 ? kind::GEQ : kind::LEQ, a, a_v);
- Node ab = NodeManager::currentNM()->mkNode(
- d == 1 || d == 3 ? kind::GEQ : kind::LEQ, b, b_v);
- Node conc = NodeManager::currentNM()->mkNode(
- d <= 1 ? kind::LEQ : kind::GEQ, t, tplane);
- Node tlem = NodeManager::currentNM()->mkNode(
- kind::OR, aa.negate(), ab.negate(), conc);
- Trace("nl-ext-tplanes")
- << "Tangent plane lemma : " << tlem << std::endl;
- lemmas.push_back(tlem);
+ Node a_v_c = computeModelValue(a, 1);
+ Node b_v_c = computeModelValue(b, 1);
+ // points we will add tangent planes for
+ std::vector< Node > pts[2];
+ pts[0].push_back( a_v_c );
+ pts[1].push_back( b_v_c );
+ // if previously refined
+ bool prevRefine = d_tangent_val_bound[0][a].find( b )!=d_tangent_val_bound[0][a].end();
+ // a_min, a_max, b_min, b_max
+ for( unsigned p=0; p<4; p++ ){
+ Node curr_v = p<=1 ? a_v_c : b_v_c;
+ if( prevRefine ){
+ Node pt_v = d_tangent_val_bound[p][a][b];
+ Assert( !pt_v.isNull() );
+ if( curr_v!=pt_v ){
+ Node do_extend = NodeManager::currentNM()->mkNode( ( p==1 || p==3 ) ? GT : LT, curr_v, pt_v );
+ do_extend = Rewriter::rewrite( do_extend );
+ if( do_extend==d_true ){
+ for( unsigned q=0; q<2; q++ ){
+ pts[ p<=1 ? 0 : 1 ].push_back( curr_v );
+ pts[ p<=1 ? 1 : 0 ].push_back( d_tangent_val_bound[ p<=1 ? 2+q : q ][a][b] );
+ }
+ }
+ }
+ }else{
+ d_tangent_val_bound[p][a][b] = curr_v;
+ }
+ }
+
+ for( unsigned p=0; p<pts[0].size(); p++ ){
+ Node a_v = pts[0][p];
+ Node b_v = pts[1][p];
+
+ // tangent plane
+ Node tplane = NodeManager::currentNM()->mkNode(
+ kind::MINUS,
+ NodeManager::currentNM()->mkNode(
+ kind::PLUS,
+ NodeManager::currentNM()->mkNode(kind::MULT, b_v, a),
+ NodeManager::currentNM()->mkNode(kind::MULT, a_v, b)),
+ NodeManager::currentNM()->mkNode(kind::MULT, a_v, b_v));
+ for (unsigned d = 0; d < 4; d++) {
+ Node aa = NodeManager::currentNM()->mkNode(
+ d == 0 || d == 3 ? kind::GEQ : kind::LEQ, a, a_v);
+ Node ab = NodeManager::currentNM()->mkNode(
+ d == 1 || d == 3 ? kind::GEQ : kind::LEQ, b, b_v);
+ Node conc = NodeManager::currentNM()->mkNode(
+ d <= 1 ? kind::LEQ : kind::GEQ, t, tplane);
+ Node tlem = NodeManager::currentNM()->mkNode(
+ kind::OR, aa.negate(), ab.negate(), conc);
+ Trace("nl-ext-tplanes")
+ << "Tangent plane lemma : " << tlem << std::endl;
+ lemmas.push_back(tlem);
+ }
}
}
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback