* Models' SubstitutionMaps are now attached to the user context
authorMorgan Deters <mdeters@gmail.com>
Mon, 8 Oct 2012 22:51:08 +0000 (22:51 +0000)
committerMorgan Deters <mdeters@gmail.com>
Mon, 8 Oct 2012 22:51:08 +0000 (22:51 +0000)
  (rather than SAT context)
* Enable part of CVC3 system test (resolves bug 375)
* Fix infinite recursion in beta reduction code (resolves bug 417)
* Some model-building assertions have been added
* Other minor changes

(this commit was certified error- and warning-free by the test-and-commit script.)

contrib/cut-release
src/parser/cvc/Cvc.g
src/smt/options
src/theory/arith/kinds
src/theory/arith/type_enumerator.h
src/theory/model.cpp
src/theory/theory_engine.cpp
src/theory/uf/theory_uf_rewriter.h
src/util/hash.h
test/system/cvc3_main.cpp

index 97bc31bb11e1724d0ab31820248f1e77b897a382..0870b6ce06764df66fd71f6ed5ef7a35e7d52ebe 100755 (executable)
@@ -246,5 +246,9 @@ else
   echo "You can still make a branch manually, of course."
 fi
 
+echo
+echo "Done.  Next steps are to upload and advertise these packages and to add"
+echo "a $version release to Bugzilla."
+
 trap '' EXIT
 
index b496aa91cc0c10791e1ac0189ea3cd10453bc7bd..22459037d5c2b561d98dd553efd18e347c189c24 100644 (file)
@@ -619,18 +619,22 @@ mainCommand[CVC4::Command*& cmd]
 
   | QUERY_TOK formula[f] { cmd = new QueryCommand(f); }
   | CHECKSAT_TOK formula[f] { cmd = new CheckSatCommand(f); }
-  | CHECKSAT_TOK { cmd = new CheckSatCommand(MK_CONST(bool(true))); }
+  | CHECKSAT_TOK { cmd = new CheckSatCommand(); }
 
     /* options */
   | OPTION_TOK
     ( str[s] | IDENTIFIER { s = AntlrInput::tokenText($IDENTIFIER); } )
-    symbolicExpr[sexpr]
-    { if(s == "logic") {
-        cmd = new SetBenchmarkLogicCommand(sexpr.getValue());
-      } else {
-        cmd = new SetOptionCommand(s, sexpr);
+    ( symbolicExpr[sexpr]
+      { if(s == "logic") {
+          cmd = new SetBenchmarkLogicCommand(sexpr.getValue());
+        } else {
+          cmd = new SetOptionCommand(s, sexpr);
+        }
       }
-    }
+    | TRUE_TOK { cmd = new SetOptionCommand(s, SExpr("true")); }
+    | FALSE_TOK { cmd = new SetOptionCommand(s, SExpr("false")); }
+    | { cmd = new SetOptionCommand(s, SExpr("true")); }
+    )
 
     /* push / pop */
   | PUSH_TOK ( k=numeral { cmd = REPEAT_COMMAND(k, PushCommand()); }
index 5be462195f7976d6efc58c5c8ecbf3b4aa87b811..ab5f9330a1910d44ee2e09c7059b3a744425a401 100644 (file)
@@ -23,7 +23,7 @@ option expandDefinitions expand-definitions bool :default false
 common-option produceModels produce-models -m --produce-models bool :default false :predicate CVC4::smt::beforeSearch :predicate-include "smt/smt_engine.h"
  support the get-value and get-model commands
 option checkModels check-models --check-models bool :predicate CVC4::smt::beforeSearch :predicate-include "smt/options_handlers.h"
- after SAT/INVALID, double-check that the generated model satisfies all user assertions
+ after SAT/INVALID/UNKNOWN, check that the generated model satisfies user assertions
 option proof produce-proofs --proof bool :default false :predicate CVC4::smt::proofEnabledBuild CVC4::smt::beforeSearch :predicate-include "smt/options_handlers.h"
  turn on proof generation
 # this is just a placeholder for later; it doesn't show up in command-line options listings
index 549e9f19baf09efa3c9104a65398084abe5b9e52..a724124bdf32ed26a24c22da6dd685519b3c9d31 100644 (file)
@@ -61,6 +61,9 @@ enumerator REAL_TYPE \
 enumerator INTEGER_TYPE \
     "::CVC4::theory::arith::IntegerEnumerator" \
     "theory/arith/type_enumerator.h"
+enumerator SUBRANGE_TYPE \
+    "::CVC4::theory::arith::SubrangeEnumerator" \
+    "theory/arith/type_enumerator.h"
 
 operator LT 2 "less than, x < y"
 operator LEQ 2 "less than or equal, x <= y"
index 4dd139be7a88f5d869db264d17f008bff9a37a59..8b30a4ddfe2d36e4bf83d0fb3f78c23174618072 100644 (file)
@@ -110,6 +110,60 @@ public:
 
 };/* class IntegerEnumerator */
 
+class SubrangeEnumerator : public TypeEnumeratorBase<SubrangeEnumerator> {
+  Integer d_int;
+  SubrangeBounds d_bounds;
+  bool d_direction;// true == +, false == -
+
+public:
+
+  SubrangeEnumerator(TypeNode type) throw(AssertionException) :
+    TypeEnumeratorBase<SubrangeEnumerator>(type),
+    d_int(0),
+    d_bounds(type.getConst<SubrangeBounds>()),
+    d_direction(d_bounds.lower.hasBound()) {
+
+    d_int = d_direction ? d_bounds.lower.getBound() : d_bounds.upper.getBound();
+
+    Assert(type.getKind() == kind::SUBRANGE_TYPE);
+
+    // if we're counting down, there's no lower bound
+    Assert(d_direction || !d_bounds.lower.hasBound());
+  }
+
+  Node operator*() throw() {
+    if(isFinished()) {
+      throw NoMoreValuesException(getType());
+    }
+    return NodeManager::currentNM()->mkConst(Rational(d_int));
+  }
+
+  SubrangeEnumerator& operator++() throw() {
+    if(d_direction) {
+      if(!d_bounds.upper.hasBound() || d_int <= d_bounds.upper.getBound()) {
+        d_int += 1;
+      }
+    } else {
+      // if we're counting down, there's no lower bound
+      d_int -= 1;
+    }
+    // sequence is 0, 1, -1, 2, -2, 3, -3, ...
+    if(d_int <= 0) {
+      d_int = -d_int + 1;
+    } else {
+      d_int = -d_int;
+    }
+    return *this;
+  }
+
+  bool isFinished() throw() {
+    // if we're counting down, there's no lower bound
+    return d_direction &&
+      (!d_bounds.upper.hasBound() || d_int <= d_bounds.upper.getBound());
+  }
+
+};/* class SubrangeEnumerator */
+
 }/* CVC4::theory::arith namespace */
 }/* CVC4::theory namespace */
 }/* CVC4 namespace */
index d97781ab7ca72c1cbf9ff841d7081844a32a74d4..82d602017bfcf0766d345b0774bac01af8c966a0 100644 (file)
@@ -514,6 +514,7 @@ void TheoryEngineModelBuilder::buildModel(Model* m, bool fullModel)
     Node n;
     for (i = noRepSet.begin(); i != noRepSet.end(); ++i) {
       n = typeConstSet.nextTypeEnum(t);
+      Assert(!n.isNull(), "out of values for finite type enumeration while building model");
       constantReps[*i] = n;
       Trace("model-builder") << "  New Const: Setting constant rep of " << (*i) << " to " << n << endl;
     }
index 252109a2651327af080cdb7a3646100ae55d6af8..08073c147919476ccf1c8b062ba8b2aa769b525f 100644 (file)
@@ -91,7 +91,7 @@ TheoryEngine::TheoryEngine(context::Context* context,
   d_quantEngine = new QuantifiersEngine(context, this);
 
   // build model information if applicable
-  d_curr_model = new theory::TheoryModel( context, "DefaultModel", true );
+  d_curr_model = new theory::TheoryModel( userContext, "DefaultModel", true );
   d_curr_model_builder = new theory::TheoryEngineModelBuilder( this );
 
   StatisticsRegistry::registerStat(&d_combineTheoriesTime);
index f70d89b3026106cf38d0d3084f030e63368f94d3..50211f1ad59372201f0b098d29c56f6b630df528 100644 (file)
@@ -77,7 +77,23 @@ public:
       for(TNode::iterator formal = lambda[0].begin(), arg = node.begin(); formal != lambda[0].end(); ++formal, ++arg) {
         // typechecking should ensure that the APPLY_UF is well-typed, correct arity, etc.
         Assert(formal != node.end());
-        substitutions.addSubstitution(*formal, *arg);
+        // This rewrite step is important: if we have (f (f 5)) for
+        // some lambda term f, we want to beta-reduce the inside (f 5)
+        // application first.  Otherwise, we can end up in infinite
+        // recursion, because f's formal (say "x") gives the
+        // substitution "x |-> (f 5)".  Fine, the body of the lambda
+        // gets (f 5) in place for x.  But since the same lambda ("f")
+        // now occurs in the body, it's got the same bound var "x", so
+        // substitution continues and we replace that x by (f 5).  And
+        // then again.  :-(
+        //
+        // We need a better solution for distinguishing bound
+        // variables like this, but for now, handle it by going
+        // inside-out.  (Quantifiers shouldn't ever have this problem,
+        // so long as the bound vars in different quantifiers are kept
+        // different.)
+        Node n = Rewriter::rewrite(*arg);
+        substitutions.addSubstitution(*formal, n);
       }
       return RewriteResponse(REWRITE_DONE, substitutions.apply(lambda[1]));
     }
index 2420b7acd29250e65d67b9b1d6acd5cf76319494..1d360783a20ecdff0d2444b0c05cc3ea27bb50e7 100644 (file)
@@ -54,6 +54,13 @@ struct StringHashFunction {
   }
 };/* struct StringHashFunction */
 
+template <class T, class U, class HashT = std::hash<T>, class HashU = std::hash<U> >
+struct PairHashFunction {
+  size_t operator()(const std::pair<T, U>& pr) const {
+    return HashT()(pr.first) ^ HashU()(pr.second);
+  }
+};/* struct PairHashFunction */
+
 }/* CVC4 namespace */
 
 #endif /* __CVC4__HASH_H */
index a428f605d44e2662b32a93d23dd19b31731be40e..13f5e153c60dc8f750a682fef3bdb5fae9e26540 100644 (file)
@@ -2140,10 +2140,10 @@ int main(int argc, char** argv)
     test3();
     cout << "\n}\n\ntest4(): {" << endl;
     test4();
-    //if (regressLevel > 0) {
-    //  cout << "\n}\n\ntest5(): {" << endl;
-    //  test5();
-    //}
+    if (regressLevel > 0) {
+      cout << "\n}\n\ntest5(): {" << endl;
+      test5();
+    }
     //cout << "\n}\n\ntest6(): {" << endl;
     //test6();
     cout << "\n}\n\ntest7(): {" << endl;