Do not set values for non-linear mult terms in collectModelInfo (#3983)
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Tue, 10 Mar 2020 15:56:58 +0000 (10:56 -0500)
committerGitHub <noreply@github.com>
Tue, 10 Mar 2020 15:56:58 +0000 (08:56 -0700)
Fixes #3803.

When non-linear arithmetic determines there is a model, then it should not send model values for multiplication terms that the linear solver assigned when abstracting (non-linear) multiplication. This avoids conflicts if the non-linear solver changed a value for a variable occurring in a non-linear monomial. This avoids check-model failures.

src/theory/arith/nl_model.cpp
test/regress/CMakeLists.txt
test/regress/regress1/nl/issue3803-nl-check-model.smt2 [new file with mode: 0644]

index 9043000047663890d47ad8dead3284cdea8bb194..abb2a7921a1fd6f8b7b7e53e123e23618684fe5b 100644 (file)
@@ -1277,11 +1277,12 @@ void NlModel::getModelValueRepair(
     std::map<Node, Node>& arithModel,
     std::map<Node, std::pair<Node, Node>>& approximations)
 {
+  Trace("nl-model") << "NlModel::getModelValueRepair:" << std::endl;
+
   // Record the approximations we used. This code calls the
   // recordApproximation method of the model, which overrides the model
   // values for variables that we solved for, using techniques specific to
   // this class.
-  Trace("nl-model") << "NlModel::getModelValueRepair:" << std::endl;
   NodeManager* nm = NodeManager::currentNM();
   for (const std::pair<const Node, std::pair<Node, Node> >& cb :
        d_check_model_bounds)
@@ -1324,6 +1325,21 @@ void NlModel::getModelValueRepair(
     arithModel[v] = s;
     Trace("nl-model") << v << " solved is " << s << std::endl;
   }
+
+  // multiplication terms should not be given values; their values are
+  // implied by the monomials that they consist of
+  std::vector<Node> amErase;
+  for (const std::pair<const Node, Node>& am : arithModel)
+  {
+    if (am.first.getKind() == NONLINEAR_MULT)
+    {
+      amErase.push_back(am.first);
+    }
+  }
+  for (const Node& ae : amErase)
+  {
+    arithModel.erase(ae);
+  }
 }
 
 }  // namespace arith
index d449669a97276b2fa17957d70b904ab353866ce3..35d5c5bd551ced37f3ed44d9ef67d2325c8911d3 100644 (file)
@@ -1330,6 +1330,7 @@ set(regress_1_tests
   regress1/nl/issue3617.smt2
   regress1/nl/issue3647.smt2
   regress1/nl/issue3656.smt2
+  regress1/nl/issue3803-nl-check-model.smt2
   regress1/nl/metitarski-1025.smt2
   regress1/nl/metitarski-3-4.smt2
   regress1/nl/metitarski_3_4_2e.smt2
diff --git a/test/regress/regress1/nl/issue3803-nl-check-model.smt2 b/test/regress/regress1/nl/issue3803-nl-check-model.smt2
new file mode 100644 (file)
index 0000000..7dfda36
--- /dev/null
@@ -0,0 +1,12 @@
+; COMMAND-LINE: --ext-rew-prep
+; EXPECT: sat
+(set-logic ALL)
+(set-info :status sat)
+(declare-fun a () Real)
+(declare-fun b () Real)
+(declare-fun c () Real)
+(declare-fun d () Real)
+(declare-fun e () Real)
+(assert (exists ((f Real)) (and (or (> (+ d (* (/ (* c e) (- (* c e) e)) f)) 0 (/ 0 a))) (> e 6))))
+(assert (distinct a (/ b e)))
+(check-sat)