Add options --partial-triggers, --elim-taut-quant, improve robustness of --purify...
authorajreynol <andrew.j.reynolds@gmail.com>
Sun, 5 Jul 2015 17:56:42 +0000 (19:56 +0200)
committerajreynol <andrew.j.reynolds@gmail.com>
Sun, 5 Jul 2015 17:56:42 +0000 (19:56 +0200)
12 files changed:
contrib/run-script-casc25-fof
contrib/run-script-casc25-tfa
src/smt/smt_engine.cpp
src/theory/quantifiers/ce_guided_single_inv.cpp
src/theory/quantifiers/ce_guided_single_inv.h
src/theory/quantifiers/inst_match_generator.cpp
src/theory/quantifiers/inst_strategy_cbqi.cpp
src/theory/quantifiers/inst_strategy_cbqi.h
src/theory/quantifiers/options
src/theory/quantifiers/quantifiers_rewriter.cpp
src/theory/quantifiers/quantifiers_rewriter.h
src/theory/quantifiers/trigger.cpp

index 7717abe473e68b3c713b9e0a06a27d1c721dd76f..26c544062c12f1d09439be96cafb3c9f6c6d6192 100755 (executable)
@@ -15,7 +15,7 @@ echo "------- cvc4-fof casc 25 : $bench at $2..."
 function trywith {
   limit=$1; shift;
   echo "--- Run $@ at $limit...";
-  (ulimit -S -t "$limit";$cvc4 --lang=tptp --no-checking --no-interactive --dump-instantiations --inst-format=szs --force-no-limit-cpu-while-dump --quant-alpha-equiv "$@" $bench) 2>/dev/null |
+  (ulimit -S -t "$limit";$cvc4 --lang=tptp --no-checking --no-interactive --dump-instantiations --inst-format=szs --force-no-limit-cpu-while-dump "$@" $bench) 2>/dev/null |
   (read w1 w2 w3 result w4 w5;
   case "$result" in
   Unsatisfiable) echo "$w1 $w2 $w3 $result $w4 $w5";cat;exit 0;;
@@ -25,7 +25,7 @@ function trywith {
 }
 function finishwith {
   echo "--- Run $@...";
-  $cvc4 --lang=tptp --no-checking --no-interactive --dump-instantiations --inst-format=szs --force-no-limit-cpu-while-dump --quant-alpha-equiv "$@" $bench
+  $cvc4 --lang=tptp --no-checking --no-interactive --dump-instantiations --inst-format=szs --force-no-limit-cpu-while-dump "$@" $bench
 }
 
 # designed for 300 seconds
index 463b5396e9aa22b24217b12e4a077f244dc56ffe..40ed76df5c1aefede4b8a77d1d416d32f201522c 100644 (file)
@@ -29,11 +29,12 @@ function finishwith {
 }
 
 trywith 10 --cbqi2 --decision=internal --full-saturate-quant
-trywith 10 --relevant-triggers --full-saturate-quant
+trywith 10 --relevant-triggers --full-saturate-quant --partial-triggers --purify-triggers
 trywith 10 --cbqi --full-saturate-quant
+trywith 10 --cbqi2 --e-matching  --partial-triggers --purify-triggers
 trywith 30 --qcf-tconstraint --full-saturate-quant
 trywith 60 --cbqi --cbqi-recurse --full-saturate-quant
-trywith 10 --full-saturate-quant
+trywith 10 --full-saturate-quant --partial-triggers --purify-triggers
 trywith 10 --no-e-matching --full-saturate-quant
 trywith 10 --fmf-bound-int
 finishwith --cbqi2 --cbqi-recurse --full-saturate-quant
index 54c97750aacd1628723cb4a1aff626e6a5b5faf4..921583ed2a0bf3b1b5458bac4e9c0b8b2cb12b63 100644 (file)
@@ -771,7 +771,7 @@ void SmtEngine::finishInit() {
     // Dump("benchmark") << SetBenchmarkLogicCommand(logic.getLogicString());
     LogicInfo everything;
     everything.lock();
-    Dump("benchmark") << CommentCommand("CVC4 always dumps the most general, \"all-supported\" logic (below), as some internals might require the use of a logic more general than the input.")
+    Dump("benchmark") << CommentCommand("CVC4 always dumps the most general, all-supported logic (below), as some internals might require the use of a logic more general than the input.")
                       << SetBenchmarkLogicCommand(everything.getLogicString());
   }
 
index 8e7e3d69cce066862921613d5f7723febf7bf826..0a434e4cad4c12c4872ec64761c4332d963fa8eb 100644 (file)
@@ -538,6 +538,7 @@ bool CegInstantiator::addInstantiation( std::vector< Node >& subs, std::vector<
         d_qe->getOutputChannel().lemma( delta_lem );
       }
       subs[i] = NodeManager::currentNM()->mkNode( subs_typ[i]==2 ? PLUS : MINUS, subs[i], d_n_delta );
+      d_used_delta = true;
     }
   }
   //check if we have already added this instantiation
index eb99fc4f66b41c887f2165456ca08d4f59aa6b30..eb33c479ea6ee267de939c322564e4a8284ba63f 100644 (file)
@@ -71,6 +71,7 @@ public:
   std::vector< Node > d_vars;
   //delta
   Node d_n_delta;
+  bool d_used_delta;
   //check : add instantiations based on valuation of d_vars
   bool check();
   // get delta lemmas : on-demand force minimality of d_n_delta
index 941eaf89b4b16e4009e6b4178ad43eccefacb9f5..f7dc709d9fc5b2d456ac7ef87d7ef7720392c149 100644 (file)
@@ -463,13 +463,17 @@ bool VarMatchGeneratorTermSubs::getNextMatch( Node f, InstMatch& m, QuantifiersE
     s = Rewriter::rewrite( s );
     Trace("var-trigger-matching") << "...got " << s << std::endl;
     d_eq_class = Node::null();
-    d_rm_prev = m.get( d_var_num[0] ).isNull();
-    if( !m.set( qe, d_var_num[0], s ) ){
-      return false;
-    }else{
-      if( continueNextMatch( f, m, qe ) ){
-        return true;
+    if( s.getType().isSubtypeOf( d_var.getType() ) ){
+      d_rm_prev = m.get( d_var_num[0] ).isNull();
+      if( !m.set( qe, d_var_num[0], s ) ){
+        return false;
+      }else{
+        if( continueNextMatch( f, m, qe ) ){
+          return true;
+        }
       }
+    }else{
+      Trace("var-trigger-matching") << "Violates type requirement." << std::endl;
     }
   }
   if( d_rm_prev ){
index de80146f9ffbb3a4cc8ce8de9b35ca8866a60e6b..dab32af712cb41b39f43124d2245ac5469b2853d 100644 (file)
@@ -126,9 +126,9 @@ void InstStrategySimplex::addTermToRow( Node i, ArithVar x, Node n, NodeBuilder<
 }
 
 int InstStrategySimplex::process( Node f, Theory::Effort effort, int e ){
-  if( e<2 ){
+  if( e<1 ){
     return STATUS_UNFINISHED;
-  }else if( e==2 ){
+  }else if( e==1 ){
     if( d_quantActive.find( f )!=d_quantActive.end() ){
       //the point instantiation
       InstMatch m_point( f );
@@ -373,9 +373,9 @@ void InstStrategyCegqi::processResetInstantiationRound( Theory::Effort effort )
 }
 
 int InstStrategyCegqi::process( Node f, Theory::Effort effort, int e ) {
-  if( e<2 ){
+  if( e<1 ){
     return STATUS_UNFINISHED;
-  }else if( e==2 ){
+  }else if( e==1 ){
     CegInstantiator * cinst;
     std::map< Node, CegInstantiator * >::iterator it = d_cinst.find( f );
     if( it==d_cinst.end() ){
@@ -417,10 +417,11 @@ int InstStrategyCegqi::process( Node f, Theory::Effort effort, int e ) {
     Trace("inst-alg") << "-> Run cegqi for " << f << std::endl;
     d_curr_quant = f;
     bool addedLemma = cinst->check();
+    d_used_delta = d_used_delta || cinst->d_used_delta;
     d_curr_quant = Node::null();
     return addedLemma ? STATUS_UNKNOWN : STATUS_UNFINISHED;
-  }else if( e==3 ){
-    if( d_check_delta_lemma_lc ){
+  }else if( e==2 ){
+    if( d_check_delta_lemma_lc && d_used_delta ){
       d_check_delta_lemma_lc = false;
       d_n_delta_ub = NodeManager::currentNM()->mkNode( MULT, d_n_delta_ub, d_n_delta_ub );
       d_n_delta_ub = Rewriter::rewrite( d_n_delta_ub );
index 13e8cf54b07f726000a6e394a488a31bc62d5cd5..d59690c843a46c908863a7aa09e159f14f6edb44 100644 (file)
@@ -104,6 +104,7 @@ private:
   Node d_curr_quant;
   bool d_check_delta_lemma;
   bool d_check_delta_lemma_lc;
+  bool d_used_delta;
   /** process functions */
   void processResetInstantiationRound( Theory::Effort effort );
   int process( Node f, Theory::Effort effort, int e );
index 231392a9aa2b26ab01693535d736fd1625bd8d54..ce7f01328e743a64ecf42712a3fb46cc11c1a0c9 100644 (file)
@@ -57,6 +57,9 @@ option aggressiveMiniscopeQuant --ag-miniscope-quant bool :default false
 # Whether to perform quantifier macro expansion
 option macrosQuant --macros-quant bool :default false
  perform quantifiers macro expansions
+# Whether to CNF quantifier bodies
+option elimTautQuant --elim-taut-quant bool :default true
+ eliminate tautological disjuncts of quantified formulas
  
 #### E-matching options
  
@@ -83,6 +86,8 @@ option purifyDtTriggers --purify-dt-triggers bool :default false :read-write
  purify dt triggers, match all constructors of correct form instead of selectors
 option pureThTriggers --pure-th-triggers bool :default false :read-write
  use pure theory terms as single triggers
+option partialTriggers --partial-triggers bool :default false :read-write
+ use triggers that do not contain all free variables
 option multiTriggerWhenSingle --multi-trigger-when-single bool :default false
  select multi triggers when single triggers exist
 option multiTriggerPriority --multi-trigger-priority bool :default false
@@ -250,7 +255,7 @@ option lteRestrictInstClosure --lte-restrict-inst-closure bool :default false
  
 ### reduction options
 
-option quantAlphaEquiv --quant-alpha-equiv bool :default false
+option quantAlphaEquiv --quant-alpha-equiv bool :default true
   infer alpha equivalence between quantified formulas
  
 endmodule
index 07aa89ece9c411d49c9786f8a591ff54b24c2cef..0198e014f9e18f030192b2898e51f3910927f153 100644 (file)
@@ -774,6 +774,30 @@ Node QuantifiersRewriter::computePrenex( Node body, std::vector< Node >& args, b
   }
 }
 
+Node QuantifiersRewriter::computeElimTaut( Node body ) {
+  if( body.getKind()==OR ){
+    std::vector< Node > children;
+    std::map< Node, bool > lit_pol;
+    for( unsigned i=0; i<body.getNumChildren(); i++ ){
+      Node lit = body[i].getKind()==NOT ? body[i][0] : body[i];
+      bool pol = body[i].getKind()!=NOT;
+      std::map< Node, bool >::iterator it = lit_pol.find( lit );
+      if( it==lit_pol.end() ){
+        lit_pol[lit] = pol;
+        children.push_back( body[i] );
+      }else{
+        if( it->second!=pol ){
+          return NodeManager::currentNM()->mkConst( true );
+        }
+      }
+    }
+    if( children.size()!=body.getNumChildren() ){
+      return children.size()==1 ? children[0] : NodeManager::currentNM()->mkNode( OR, children );
+    }
+  }
+  return body;
+}
+  
 Node QuantifiersRewriter::computeSplit( Node f, Node body, std::vector< Node >& vars ) {
   if( body.getKind()==OR ){
     size_t var_found_count = 0;
@@ -1104,6 +1128,8 @@ bool QuantifiersRewriter::doOperation( Node f, bool isNested, int computeOption
     return options::iteDtTesterSplitQuant();
   }else if( computeOption==COMPUTE_PRENEX ){
     return options::prenexQuant()!=PRENEX_NONE && !options::aggressiveMiniscopeQuant();
+  }else if( computeOption==COMPUTE_ELIM_TAUT ){
+    return options::elimTautQuant();
   }else if( computeOption==COMPUTE_VAR_ELIMINATION ){
     return options::varElimQuant() || options::dtVarExpandQuant();
   }else if( computeOption==COMPUTE_CNF ){
@@ -1144,6 +1170,8 @@ Node QuantifiersRewriter::computeOperation( Node f, bool isNested, int computeOp
       n = computeProcessIte2( n );
     }else if( computeOption==COMPUTE_PRENEX ){
       n = computePrenex( n, args, true );
+    }else if( computeOption==COMPUTE_ELIM_TAUT ){
+      n = computeElimTaut( n );
     }else if( computeOption==COMPUTE_VAR_ELIMINATION ){
       Node prev;
       do{
index 201a037370623d36d364d3e557e4dcd0dd499304..d01677171a638f5c1705daa08a1e7ae67c85436c 100644 (file)
@@ -51,6 +51,7 @@ private:
   static Node computeVarElimination( Node body, std::vector< Node >& args, Node& ipl );
   static Node computeCNF( Node body, std::vector< Node >& args, NodeBuilder<>& defs, bool forcePred );
   static Node computePrenex( Node body, std::vector< Node >& args, bool pol );
+  static Node computeElimTaut( Node body );
   static Node computeSplit( Node f, Node body, std::vector< Node >& args );
 private:
   enum{
@@ -61,6 +62,7 @@ private:
     COMPUTE_PROCESS_ITE,
     COMPUTE_PROCESS_ITE_2,
     COMPUTE_PRENEX,
+    COMPUTE_ELIM_TAUT,
     COMPUTE_VAR_ELIMINATION,
     //COMPUTE_FLATTEN_ARGS_UF,
     COMPUTE_CNF,
index c55ed27ead6ce8d4e050afd96e3d7ab570ff3275..e4d9a27309fa82e498f9042b664be4964f261371 100644 (file)
@@ -145,7 +145,7 @@ Trigger* Trigger::mkTrigger( QuantifiersEngine* qe, Node f, std::vector< Node >&
         break;
       }
     }
-    if( varCount<f[0].getNumChildren() ){
+    if( varCount<f[0].getNumChildren() && !options::partialTriggers() ){
       Trace("trigger-debug") << "Don't consider trigger since it does not contain all variables in " << f << std::endl;
       for( unsigned i=0; i<nodes.size(); i++) {
         Trace("trigger-debug") << nodes[i] << " ";
@@ -226,6 +226,12 @@ bool Trigger::isUsable( Node n, Node f ){
       if( isBooleanTermTrigger( n ) ){
         return true;
       }
+      if( options::purifyTriggers() ){
+        Node x = getInversionVariable( n );
+        if( !x.isNull() ){
+          return true;
+        }
+      }
     }
     return false;
   }else{
@@ -247,6 +253,7 @@ bool nodeContainsVar( Node n, Node v ){
 }
 
 Node Trigger::getIsUsableTrigger( Node n, Node f, bool pol, bool hasPol ) {
+  Trace("trigger-debug") << "Is " << n << " a usable trigger?" << std::endl;
   if( options::relationalTriggers() ){
     if( n.getKind()==EQUAL || n.getKind()==IFF || n.getKind()==GEQ ){
       Node rtr;
@@ -287,7 +294,7 @@ Node Trigger::getIsUsableTrigger( Node n, Node f, bool pol, bool hasPol ) {
     }
   }
   bool usable = quantifiers::TermDb::getInstConstAttr(n)==f && isAtomicTrigger( n ) && isUsable( n, f );
-  Trace("usable") << n << " usable : " << (quantifiers::TermDb::getInstConstAttr(n)==f) << " " << isAtomicTrigger( n ) << " " << isUsable( n, f ) << std::endl;
+  Trace("trigger-debug") << n << " usable : " << (quantifiers::TermDb::getInstConstAttr(n)==f) << " " << isAtomicTrigger( n ) << " " << isUsable( n, f ) << std::endl;
   if( usable ){
     return n;
   }else{
@@ -512,13 +519,16 @@ Node Trigger::getInversionVariable( Node n ) {
         if( !n[i].isConst() ){
           Trace("var-trigger-debug") << "No : non-linear coefficient " << n << std::endl;
           return Node::null();
-        }else if( n.getType().isInteger() ){
+        }
+        /*
+        else if( n.getType().isInteger() ){
           Rational r = n[i].getConst<Rational>();
           if( r!=Rational(-1) && r!=Rational(1) ){
             Trace("var-trigger-debug") << "No : not integer coefficient " << n << std::endl;
             return Node::null();
           }
         }
+        */
       }
     }
     return ret;
@@ -539,8 +549,13 @@ Node Trigger::getInversion( Node n, Node x ) {
           x = NodeManager::currentNM()->mkNode( MINUS, x, n[i] );
         }else if( n.getKind()==MULT ){
           Assert( n[i].isConst() );
-          Node coeff = NodeManager::currentNM()->mkConst( Rational(1) / n[i].getConst<Rational>() );
-          x = NodeManager::currentNM()->mkNode( MULT, x, coeff );
+          if( x.getType().isInteger() ){
+            Node coeff = NodeManager::currentNM()->mkConst( n[i].getConst<Rational>() );
+            x = NodeManager::currentNM()->mkNode( INTS_DIVISION, x, coeff );
+          }else{
+            Node coeff = NodeManager::currentNM()->mkConst( Rational(1) / n[i].getConst<Rational>() );
+            x = NodeManager::currentNM()->mkNode( MULT, x, coeff );
+          }
         }
       }else{
         Assert( cindex==-1 );