Simplify fmc model construction, add regression. Improve FMF debug assertions.
authorajreynol <andrew.j.reynolds@gmail.com>
Mon, 1 Feb 2016 17:18:00 +0000 (11:18 -0600)
committerajreynol <andrew.j.reynolds@gmail.com>
Mon, 1 Feb 2016 17:18:06 +0000 (11:18 -0600)
src/theory/quantifiers/first_order_model.cpp
src/theory/quantifiers/term_database.cpp
src/theory/quantifiers/term_database.h
test/regress/regress0/fmf/Makefile.am
test/regress/regress0/fmf/am-bad-model.cvc [new file with mode: 0644]

index 018a0c3e0949ebc82dd127054b4ad3772d0be98c..aa2a43fbf1e3ed458f7474032aaf4abdad7c536a 100644 (file)
@@ -669,6 +669,8 @@ Node FirstOrderModelFmc::getFunctionValue(Node op, const char* argPrefix ) {
   for( int i=(d_models[op]->d_cond.size()-1); i>=0; i--) {
     Node v = d_models[op]->d_value[i];
     Trace("fmc-model-func") << "Value is : " << v << std::endl;
+    Assert( v.isConst() );
+    /*
     if( !hasTerm( v ) ){
       //can happen when the model basis term does not exist in ground assignment
       TypeNode tn = v.getType();
@@ -685,6 +687,7 @@ Node FirstOrderModelFmc::getFunctionValue(Node op, const char* argPrefix ) {
       }
     }
     v = getRepresentative( v );
+    */
     if( curr.isNull() ){
       Trace("fmc-model-func") << "base : " << v << std::endl;
       curr = v;
index 56f966426dc3601d4efc21abdcf2df68789776e5..6dfd4c737c3d2fc78be31a55eb3bebb16a9ff0e8 100644 (file)
@@ -1605,10 +1605,10 @@ bool TermDb::containsTerm2( Node n, Node t, std::map< Node, bool >& visited ) {
 }
 
 bool TermDb::containsTerms2( Node n, std::vector< Node >& t, std::map< Node, bool >& visited ) {
-  if( std::find( t.begin(), t.end(), n )!=t.end() ){
-    return true;
-  }else{
-    if( visited.find( n )==visited.end() ){
+  if( visited.find( n )==visited.end() ){
+    if( std::find( t.begin(), t.end(), n )!=t.end() ){
+      return true;
+    }else{
       visited[n] = true;
       for( unsigned i=0; i<n.getNumChildren(); i++ ){
         if( containsTerms2( n[i], t, visited ) ){
@@ -1616,8 +1616,22 @@ bool TermDb::containsTerms2( Node n, std::vector< Node >& t, std::map< Node, boo
         }
       }
     }
-    return false;
   }
+  return false;
+}
+
+bool TermDb::containsUninterpretedConstant2( Node n, std::map< Node, bool >& visited ) {
+  if( n.getKind()==UNINTERPRETED_CONSTANT ){
+    return true;
+  }else if( visited.find( n )==visited.end() ){
+    visited[n] = true;
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){
+      if( containsUninterpretedConstant2( n[i], visited ) ){
+        return true;
+      }
+    }
+  }
+  return false;
 }
 
 bool TermDb::containsTerm( Node n, Node t ) {
@@ -1634,6 +1648,11 @@ bool TermDb::containsTerms( Node n, std::vector< Node >& t ) {
   }
 }
 
+bool TermDb::containsUninterpretedConstant( Node n ) {
+  std::map< Node, bool > visited;
+  return containsUninterpretedConstant2( n, visited );
+}
+
 Node TermDb::simpleNegate( Node n ){
   if( n.getKind()==OR || n.getKind()==AND ){
     std::vector< Node > children;
index 86b0efbf37441f9473aed8dcac91f7c6567dac14..0c4e945172abc190d563cd97ebe5e9db689967e0 100644 (file)
@@ -397,12 +397,15 @@ private:
   //helper for contains term
   static bool containsTerm2( Node n, Node t, std::map< Node, bool >& visited );
   static bool containsTerms2( Node n, std::vector< Node >& t, std::map< Node, bool >& visited );
+  static bool containsUninterpretedConstant2( Node n, std::map< Node, bool >& visited );
 //general utilities
 public:
   /** simple check for whether n contains t as subterm */
   static bool containsTerm( Node n, Node t );
   /** simple check for contains term, true if contains at least one term in t */
   static bool containsTerms( Node n, std::vector< Node >& t );
+  /** contains uninterpreted constant */
+  static bool containsUninterpretedConstant( Node n );
   /** simple negate */
   static Node simpleNegate( Node n );
   /** is assoc */
index 8b7202906381b7c037f4a65f133574ebef0eab67..370096a1ea145160ff4907eeef9a7a95f28e36b6 100644 (file)
@@ -48,7 +48,8 @@ TESTS =       \
        tail_rec.smt2 \
        jasmin-cdt-crash.smt2 \
        loopy_coda.smt2 \
-       fmc_unsound_model.smt2
+       fmc_unsound_model.smt2 \
+       am-bad-model.cvc
 
 
 EXTRA_DIST = $(TESTS)
diff --git a/test/regress/regress0/fmf/am-bad-model.cvc b/test/regress/regress0/fmf/am-bad-model.cvc
new file mode 100644 (file)
index 0000000..e30b5e0
--- /dev/null
@@ -0,0 +1,22 @@
+% EXPECT: sat
+OPTION "produce-models";
+OPTION "finite-model-find";
+
+f     : (BITVECTOR(2),BITVECTOR(2)) ->ARRAY INT OF INT;
+f0    : BITVECTOR(2) -> ARRAY INT OF INT;
+
+td,td1,td2: ARRAY INT OF INT;
+ASSERT td1 = td WITH[0]:= 1;
+ASSERT td2 = td WITH[0]:= 2;
+ASSERT f(0bin01,0bin00)=td1;
+ASSERT f(0bin10,0bin00)=td2;
+%ASSERT FORALL(i:BITVECTOR(2)) : f0(i)=f(0bin00,i) ;
+%Artificial bypass of quantifier for f0 definition
+ASSERT f0(0bin00) = f(0bin00,0bin00);
+ASSERT f0(0bin01) = f(0bin00,0bin01);
+ASSERT f0(0bin10) = f(0bin00,0bin10);
+ASSERT f0(0bin11) = f(0bin00,0bin11);
+ASSERT FORALL(i:BITVECTOR(2)) : f0(i)=td2 ;
+
+CHECKSAT;
+