Clean up issues related to compiled scc in LFSC. Refactor --partial-trigger, do not...
authorajreynol <andrew.j.reynolds@gmail.com>
Mon, 2 May 2016 14:16:30 +0000 (09:16 -0500)
committerajreynol <andrew.j.reynolds@gmail.com>
Mon, 2 May 2016 14:16:36 +0000 (09:16 -0500)
24 files changed:
proofs/lfsc_checker/scccode.cpp
proofs/lfsc_checker/scccode.h
proofs/lfsc_checker/sccwriter.cpp
proofs/signatures/th_quant.plf
src/theory/quantifiers/ambqi_builder.cpp
src/theory/quantifiers/candidate_generator.cpp
src/theory/quantifiers/candidate_generator.h
src/theory/quantifiers/conjecture_generator.cpp
src/theory/quantifiers/full_model_check.cpp
src/theory/quantifiers/inst_match_generator.cpp
src/theory/quantifiers/inst_match_generator.h
src/theory/quantifiers/inst_strategy_e_matching.cpp
src/theory/quantifiers/inst_strategy_e_matching.h
src/theory/quantifiers/model_builder.cpp
src/theory/quantifiers/model_builder.h
src/theory/quantifiers/quantifiers_rewriter.cpp
src/theory/quantifiers/relevant_domain.cpp
src/theory/quantifiers/rewrite_engine.cpp
src/theory/quantifiers/term_database.cpp
src/theory/quantifiers/term_database.h
src/theory/quantifiers/trigger.cpp
src/theory/quantifiers/trigger.h
test/regress/regress0/quantifiers/Makefile.am
test/regress/regress0/quantifiers/partial-trigger.smt2 [new file with mode: 0644]

index 22f26ec8893c81f058f06062e67756fea62e1ae0..19712579cce9da350ff0dded9a3681e58636deba 100644 (file)
 #include "scccode.h"
 
-Expr* e_pos;
-Expr* e_neg;
-Expr* e_tt;
-Expr* e_ff;
-Expr* e_cln;
-Expr* e_clc;
-Expr* e_concat;
-Expr* e_clr;
-Expr* e_litvar;
-Expr* e_litpol;
-Expr* e_notb;
-Expr* e_iffb;
-Expr* e_clear_mark;
-Expr* e_append;
-Expr* e_simplify_clause_h;
-Expr* e_simplify_clause;
-
 void init_compiled_scc(){
-   e_pos = symbols->get("pos").first;
-   e_neg = symbols->get("neg").first;
-   e_tt = symbols->get("tt").first;
-   e_ff = symbols->get("ff").first;
-   e_cln = symbols->get("cln").first;
-   e_clc = symbols->get("clc").first;
-   e_concat = symbols->get("concat").first;
-   e_clr = symbols->get("clr").first;
-   e_litvar = progs["litvar"];
-   e_litpol = progs["litpol"];
-   e_notb = progs["notb"];
-   e_iffb = progs["iffb"];
-   e_clear_mark = progs["clear_mark"];
-   e_append = progs["append"];
-   e_simplify_clause_h = progs["simplify_clause_h"];
-   e_simplify_clause = progs["simplify_clause"];
-}
-
-Expr* run_compiled_scc( Expr* p, std::vector< Expr* >& args ){
-   if( p==e_litvar ){
-      return f_litvar( args[0] );
-   }else if( p==e_litpol ){
-      return f_litpol( args[0] );
-   }else if( p==e_notb ){
-      return f_notb( args[0] );
-   }else if( p==e_iffb ){
-      return f_iffb( args[0], args[1] );
-   }else if( p==e_clear_mark ){
-      return f_clear_mark( args[0] );
-   }else if( p==e_append ){
-      return f_append( args[0], args[1] );
-   }else if( p==e_simplify_clause_h ){
-      return f_simplify_clause_h( args[0], args[1] );
-   }else if( p==e_simplify_clause ){
-      return f_simplify_clause( args[0] );
-   }else{
-      return NULL;
-   }
-}
-
-Expr* f_litvar( Expr* l ){
-   Expr* e0;
-   l->inc();
-   Expr* e1 = l->followDefs()->get_head();
-   Expr* e2;
-   e2 = e_pos;
-   e2->inc();
-   Expr* e3;
-   e3 = e_neg;
-   e3->inc();
-   if( e1==e2 ){
-      Expr* x = ((CExpr*)l->followDefs())->kids[1];
-      e0 = x;
-      e0->inc();
-   }else if( e1==e3 ){
-      Expr* x = ((CExpr*)l->followDefs())->kids[1];
-      e0 = x;
-      e0->inc();
-   }else{
-      std::cout << "Could not find match for expression in function f_litvar ";
-      e1->print( std::cout );
-      std::cout << std::endl;
-      exit( 1 );
-   }
-   l->dec();
-   e2->dec();
-   e3->dec();
-   return e0;
-}
-
-Expr* f_litpol( Expr* l ){
-   Expr* e0;
-   l->inc();
-   Expr* e1 = l->followDefs()->get_head();
-   Expr* e2;
-   e2 = e_pos;
-   e2->inc();
-   Expr* e3;
-   e3 = e_neg;
-   e3->inc();
-   if( e1==e2 ){
-      // Expr* x = ((CExpr*)l->followDefs())->kids[1];
-      e0 = e_tt;
-      e0->inc();
-   }else if( e1==e3 ){
-      // Expr* x = ((CExpr*)l->followDefs())->kids[1];
-      e0 = e_ff;
-      e0->inc();
-   }else{
-      std::cout << "Could not find match for expression in function f_litpol ";
-      e1->print( std::cout );
-      std::cout << std::endl;
-      exit( 1 );
-   }
-   l->dec();
-   e2->dec();
-   e3->dec();
-   return e0;
-}
 
-Expr* f_notb( Expr* b ){
-   Expr* e0;
-   b->inc();
-   Expr* e1 = b->followDefs()->get_head();
-   Expr* e2;
-   e2 = e_ff;
-   e2->inc();
-   Expr* e3;
-   e3 = e_tt;
-   e3->inc();
-   if( e1==e2 ){
-      e0 = e_tt;
-      e0->inc();
-   }else if( e1==e3 ){
-      e0 = e_ff;
-      e0->inc();
-   }else{
-      std::cout << "Could not find match for expression in function f_notb ";
-      e1->print( std::cout );
-      std::cout << std::endl;
-      exit( 1 );
-   }
-   b->dec();
-   e2->dec();
-   e3->dec();
-   return e0;
 }
 
-Expr* f_iffb( Expr* b1, Expr* b2 ){
-   Expr* e0;
-   b1->inc();
-   Expr* e1 = b1->followDefs()->get_head();
-   Expr* e2;
-   e2 = e_tt;
-   e2->inc();
-   Expr* e3;
-   e3 = e_ff;
-   e3->inc();
-   if( e1==e2 ){
-      e0 = b2;
-      e0->inc();
-   }else if( e1==e3 ){
-      b2->inc();
-      e0 = f_notb( b2 );
-      b2->dec();
-   }else{
-      std::cout << "Could not find match for expression in function f_iffb ";
-      e1->print( std::cout );
-      std::cout << std::endl;
-      exit( 1 );
-   }
-   b1->dec();
-   e2->dec();
-   e3->dec();
-   return e0;
-}
-
-Expr* f_clear_mark( Expr* v ){
-   Expr* e0;
-   v->inc();
-   if ( ((SymExpr*)v->followDefs())->getmark(0)){
-      v->inc();
-      if ( ((SymExpr*)v->followDefs())->getmark(0))
-         ((SymExpr*)v->followDefs())->clearmark(0);
-      else
-         ((SymExpr*)v->followDefs())->setmark(0);
-      e0 = v;
-      e0->inc();
-      v->dec();
-   }else{
-      e0 = v;
-      e0->inc();
-   }
-   v->dec();
-   return e0;
-}
-
-Expr* f_append( Expr* c1, Expr* c2 ){
-   Expr* e0;
-   c1->inc();
-   Expr* e1 = c1->followDefs()->get_head();
-   Expr* e2;
-   e2 = e_cln;
-   e2->inc();
-   Expr* e3;
-   e3 = e_clc;
-   e3->inc();
-   if( e1==e2 ){
-      e0 = c2;
-      e0->inc();
-   }else if( e1==e3 ){
-      Expr* l = ((CExpr*)c1->followDefs())->kids[1];
-      Expr* c1h = ((CExpr*)c1->followDefs())->kids[2];
-      l->inc();
-      Expr* e4;
-      c1h->inc();
-      c2->inc();
-      e4 = f_append( c1h, c2 );
-      c1h->dec();
-      c2->dec();
-      static Expr* e5;
-      e5 = e_clc;
-      e5->inc();
-      e0 = new CExpr( APP, e5, l, e4 );
-   }else{
-      std::cout << "Could not find match for expression in function f_append ";
-      e1->print( std::cout );
-      std::cout << std::endl;
-      exit( 1 );
-   }
-   c1->dec();
-   e2->dec();
-   e3->dec();
-   return e0;
-}
-
-Expr* f_simplify_clause_h( Expr* pol, Expr* c ){
-   Expr* e0;
-   c->inc();
-   Expr* e1 = c->followDefs()->get_head();
-   Expr* e2;
-   e2 = e_cln;
-   e2->inc();
-   Expr* e3;
-   e3 = e_clc;
-   e3->inc();
-   Expr* e4;
-   e4 = e_concat;
-   e4->inc();
-   Expr* e5;
-   e5 = e_clr;
-   e5->inc();
-   if( e1==e2 ){
-      e0 = e_cln;
-      e0->inc();
-   }else if( e1==e3 ){
-      Expr* l = ((CExpr*)c->followDefs())->kids[1];
-      Expr* c1 = ((CExpr*)c->followDefs())->kids[2];
-      Expr* v;
-      l->inc();
-      v = f_litvar( l );
-      l->dec();
-      Expr* e6;
-      Expr* e7;
-      l->inc();
-      e7 = f_litpol( l );
-      l->dec();
-      pol->inc();
-      e6 = f_iffb( e7, pol );
-      e7->dec();
-      pol->dec();
-      Expr* e8 = e6->followDefs()->get_head();
-      Expr* e9;
-      e9 = e_tt;
-      e9->inc();
-      Expr* e10;
-      e10 = e_ff;
-      e10->inc();
-      if( e8==e9 ){
-         Expr* m;
-         v->inc();
-         if ( ((SymExpr*)v->followDefs())->getmark(0)){
-            m = e_tt;
-            m->inc();
-         }else{
-            Expr* e11;
-            v->inc();
-            if ( ((SymExpr*)v->followDefs())->getmark(0))
-               ((SymExpr*)v->followDefs())->clearmark(0);
-            else
-               ((SymExpr*)v->followDefs())->setmark(0);
-            e11 = v;
-            e11->inc();
-            v->dec();
-            e11->dec();
-            m = e_ff;
-            m->inc();
-         }
-         v->dec();
-         Expr* ch;
-         pol->inc();
-         c1->inc();
-         ch = f_simplify_clause_h( pol, c1 );
-         pol->dec();
-         c1->dec();
-         m->inc();
-         Expr* e12 = m->followDefs()->get_head();
-         Expr* e13;
-         e13 = e_tt;
-         e13->inc();
-         Expr* e14;
-         e14 = e_ff;
-         e14->inc();
-         if( e12==e13 ){
-            Expr* e15;
-            v->inc();
-            if ( ((SymExpr*)v->followDefs())->getmark(1)){
-               e15 = v;
-               e15->inc();
-            }else{
-               v->inc();
-               if ( ((SymExpr*)v->followDefs())->getmark(1))
-                  ((SymExpr*)v->followDefs())->clearmark(1);
-               else
-                  ((SymExpr*)v->followDefs())->setmark(1);
-               e15 = v;
-               e15->inc();
-               v->dec();
-            }
-            v->dec();
-            e15->dec();
-            e0 = ch;
-            e0->inc();
-         }else if( e12==e14 ){
-            Expr* e16;
-            Expr* e17;
-            v->inc();
-            if ( ((SymExpr*)v->followDefs())->getmark(1)){
-               v->inc();
-               if ( ((SymExpr*)v->followDefs())->getmark(1))
-                  ((SymExpr*)v->followDefs())->clearmark(1);
-               else
-                  ((SymExpr*)v->followDefs())->setmark(1);
-               e17 = v;
-               e17->inc();
-               v->dec();
-            }else{
-               e17 = v;
-               e17->inc();
-            }
-            v->dec();
-            e17->dec();
-            v->inc();
-            if ( ((SymExpr*)v->followDefs())->getmark(0))
-               ((SymExpr*)v->followDefs())->clearmark(0);
-            else
-               ((SymExpr*)v->followDefs())->setmark(0);
-            e16 = v;
-            e16->inc();
-            v->dec();
-            e16->dec();
-            l->inc();
-            ch->inc();
-            static Expr* e18;
-            e18 = e_clc;
-            e18->inc();
-            e0 = new CExpr( APP, e18, l, ch );
-         }else{
-            std::cout << "Could not find match for expression in function f_simplify_clause_h ";
-            e12->print( std::cout );
-            std::cout << std::endl;
-            exit( 1 );
-         }
-         m->dec();
-         e13->dec();
-         e14->dec();
-         ch->dec();
-         m->dec();
-      }else if( e8==e10 ){
-         l->inc();
-         Expr* e19;
-         pol->inc();
-         c1->inc();
-         e19 = f_simplify_clause_h( pol, c1 );
-         pol->dec();
-         c1->dec();
-         static Expr* e20;
-         e20 = e_clc;
-         e20->inc();
-         e0 = new CExpr( APP, e20, l, e19 );
-      }else{
-         std::cout << "Could not find match for expression in function f_simplify_clause_h ";
-         e8->print( std::cout );
-         std::cout << std::endl;
-         exit( 1 );
-      }
-      e6->dec();
-      e9->dec();
-      e10->dec();
-      v->dec();
-   }else if( e1==e4 ){
-      Expr* c1 = ((CExpr*)c->followDefs())->kids[1];
-      Expr* c2 = ((CExpr*)c->followDefs())->kids[2];
-      pol->inc();
-      Expr* e21 = pol->followDefs()->get_head();
-      Expr* e22;
-      e22 = e_ff;
-      e22->inc();
-      Expr* e23;
-      e23 = e_tt;
-      e23->inc();
-      if( e21==e22 ){
-         Expr* e24;
-         pol->inc();
-         c1->inc();
-         e24 = f_simplify_clause_h( pol, c1 );
-         pol->dec();
-         c1->dec();
-         Expr* e25;
-         pol->inc();
-         c2->inc();
-         e25 = f_simplify_clause_h( pol, c2 );
-         pol->dec();
-         c2->dec();
-         static Expr* e26;
-         e26 = e_concat;
-         e26->inc();
-         e0 = new CExpr( APP, e26, e24, e25 );
-      }else if( e21==e23 ){
-         Expr* e27;
-         pol->inc();
-         c1->inc();
-         e27 = f_simplify_clause_h( pol, c1 );
-         pol->dec();
-         c1->dec();
-         Expr* e28;
-         pol->inc();
-         c2->inc();
-         e28 = f_simplify_clause_h( pol, c2 );
-         pol->dec();
-         c2->dec();
-         e0 = f_append( e27, e28 );
-         e27->dec();
-         e28->dec();
-      }else{
-         std::cout << "Could not find match for expression in function f_simplify_clause_h ";
-         e21->print( std::cout );
-         std::cout << std::endl;
-         exit( 1 );
-      }
-      pol->dec();
-      e22->dec();
-      e23->dec();
-   }else if( e1==e5 ){
-      Expr* l = ((CExpr*)c->followDefs())->kids[1];
-      Expr* c1 = ((CExpr*)c->followDefs())->kids[2];
-      Expr* e29;
-      Expr* e30;
-      l->inc();
-      e30 = f_litpol( l );
-      l->dec();
-      pol->inc();
-      e29 = f_iffb( e30, pol );
-      e30->dec();
-      pol->dec();
-      Expr* e31 = e29->followDefs()->get_head();
-      Expr* e32;
-      e32 = e_ff;
-      e32->inc();
-      Expr* e33;
-      e33 = e_tt;
-      e33->inc();
-      if( e31==e32 ){
-         l->inc();
-         Expr* e34;
-         pol->inc();
-         c1->inc();
-         e34 = f_simplify_clause_h( pol, c1 );
-         pol->dec();
-         c1->dec();
-         static Expr* e35;
-         e35 = e_clr;
-         e35->inc();
-         e0 = new CExpr( APP, e35, l, e34 );
-      }else if( e31==e33 ){
-         Expr* v;
-         l->inc();
-         v = f_litvar( l );
-         l->dec();
-         Expr* m;
-         v->inc();
-         if ( ((SymExpr*)v->followDefs())->getmark(0)){
-            m = e_tt;
-            m->inc();
-         }else{
-            Expr* e36;
-            v->inc();
-            if ( ((SymExpr*)v->followDefs())->getmark(0))
-               ((SymExpr*)v->followDefs())->clearmark(0);
-            else
-               ((SymExpr*)v->followDefs())->setmark(0);
-            e36 = v;
-            e36->inc();
-            v->dec();
-            e36->dec();
-            m = e_ff;
-            m->inc();
-         }
-         v->dec();
-         Expr* ch;
-         pol->inc();
-         c1->inc();
-         ch = f_simplify_clause_h( pol, c1 );
-         pol->dec();
-         c1->dec();
-         v->inc();
-         if ( ((SymExpr*)v->followDefs())->getmark(1)){
-            m->inc();
-            Expr* e37 = m->followDefs()->get_head();
-            Expr* e38;
-            e38 = e_tt;
-            e38->inc();
-            Expr* e39;
-            e39 = e_ff;
-            e39->inc();
-            if( e37==e38 ){
-               e0 = ch;
-               e0->inc();
-            }else if( e37==e39 ){
-               Expr* e40;
-               Expr* e41;
-               v->inc();
-               if ( ((SymExpr*)v->followDefs())->getmark(1))
-                  ((SymExpr*)v->followDefs())->clearmark(1);
-               else
-                  ((SymExpr*)v->followDefs())->setmark(1);
-               e41 = v;
-               e41->inc();
-               v->dec();
-               e41->dec();
-               v->inc();
-               if ( ((SymExpr*)v->followDefs())->getmark(0))
-                  ((SymExpr*)v->followDefs())->clearmark(0);
-               else
-                  ((SymExpr*)v->followDefs())->setmark(0);
-               e40 = v;
-               e40->inc();
-               v->dec();
-               e40->dec();
-               e0 = ch;
-               e0->inc();
-            }else{
-               std::cout << "Could not find match for expression in function f_simplify_clause_h ";
-               e37->print( std::cout );
-               std::cout << std::endl;
-               exit( 1 );
-            }
-            m->dec();
-            e38->dec();
-            e39->dec();
-         }else{
-            e0 = NULL;
-         }
-         v->dec();
-         ch->dec();
-         m->dec();
-         v->dec();
-      }else{
-         std::cout << "Could not find match for expression in function f_simplify_clause_h ";
-         e31->print( std::cout );
-         std::cout << std::endl;
-         exit( 1 );
-      }
-      e29->dec();
-      e32->dec();
-      e33->dec();
-   }else{
-      std::cout << "Could not find match for expression in function f_simplify_clause_h ";
-      e1->print( std::cout );
-      std::cout << std::endl;
-      exit( 1 );
-   }
-   c->dec();
-   e2->dec();
-   e3->dec();
-   e4->dec();
-   e5->dec();
-   return e0;
+Expr* run_compiled_scc( Expr* p, std::vector< Expr* >& args ){
+  return NULL;
 }
 
-Expr* f_simplify_clause( Expr* c ){
-   Expr* e0;
-   static Expr* e1;
-   e1 = e_tt;
-   e1->inc();
-   Expr* e2;
-   static Expr* e3;
-   e3 = e_ff;
-   e3->inc();
-   c->inc();
-   e2 = f_simplify_clause_h( e3, c );
-   e3->dec();
-   c->dec();
-   e0 = f_simplify_clause_h( e1, e2 );
-   e1->dec();
-   e2->dec();
-   return e0;
-}
 
index 6f5efc8b5ab096a380ae71120276b2269c69cc11..2ab549c101b90b65d4f677114ec33f0095ad2272 100644 (file)
@@ -7,21 +7,5 @@ void init_compiled_scc();
 
 Expr* run_compiled_scc( Expr* p, std::vector< Expr* >& args );
 
-inline Expr* f_litvar( Expr* l );
-
-inline Expr* f_litpol( Expr* l );
-
-inline Expr* f_notb( Expr* b );
-
-inline Expr* f_iffb( Expr* b1, Expr* b2 );
-
-inline Expr* f_clear_mark( Expr* v );
-
-inline Expr* f_append( Expr* c1, Expr* c2 );
-
-inline Expr* f_simplify_clause_h( Expr* pol, Expr* c );
-
-inline Expr* f_simplify_clause( Expr* c );
-
 #endif
 
index 5c1da2a3f6e2b4aa05e69250fb2263519ba46bce..d93341ab8c12ec2acb95bc99ab1876e5f5cf02de 100644 (file)
@@ -286,7 +286,7 @@ void sccwriter::write_code( Expr* code, std::ostream& os, int ind, const char* r
     {
       indent( os, ind );
       os << retModString.c_str();
-      os << "new IntExpr( " << mpz_get_si( ((IntExpr*)code)->n ) << " );" << std::endl;
+      os << "new IntExpr( (signed long int)" << mpz_get_si( ((IntExpr*)code)->n ) << " );" << std::endl;
       indent( os, ind );
       os << incString.c_str() << std::endl;
     }
@@ -527,7 +527,7 @@ void sccwriter::write_code( Expr* code, std::ostream& os, int ind, const char* r
         indent( os, ind );
         os << "Expr* ";
         write_variable( ((SymSExpr*)((CExpr*)code)->kids[0])->s, os );
-        os << ";" << std::endl;
+        os << " = NULL;" << std::endl;
         std::ostringstream ss;
         write_variable( ((SymSExpr*)((CExpr*)code)->kids[0])->s, ss );
         write_code( ((CExpr*)code)->kids[1], os, ind, ss.str().c_str() );
@@ -841,7 +841,7 @@ void sccwriter::write_expr( Expr* code, std::ostream& os, int ind, std::string&
     {
       os << "static ";
     }
-    os << "Expr* " << ss.str().c_str() << ";" << std::endl;
+    os << "Expr* " << ss.str().c_str() << " = NULL;" << std::endl;
     //write the expression
     std::ostringstream ss2;
     ss2 << ss.str().c_str();
index d85b2115ca18c9090f7cffb65df8ea4c1d8b6ccf..e212f835dfc421ef5a19f08d0b331aae85a93cb4 100755 (executable)
       (match ti
         ((apply si1 si2 ti1 ti2) (match (is_inst_t ti1 t1 k) (tt (is_inst_t ti2 t2 k)) (ff ff)))
         (default ff)))
-    (default
-      (match ti
-        ((apply si1 si2 ti1 ti2) ff)
-        (default (eqterm ti (ifmarked t k t)))))))
+    (default (eqterm ti (ifmarked t k t)))))
 
 (program is_inst_f ((fi formula) (f formula) (k term)) bool
   (match f
index 5192da7ded8bb631a2ff1d2ad4da45408f0cf454..97116dee4661bcf7f6d848aca118607afe57abc1 100644 (file)
@@ -787,7 +787,7 @@ void AbsMbqiBuilder::processBuildModel(TheoryModel* m, bool fullModel) {
       Trace("ambqi-model-debug") << "Initial terms: " << std::endl;
       for( size_t i=0; i<fm->d_uf_terms[f].size(); i++ ){
         Node n = fm->d_uf_terms[f][i];
-        if( !n.getAttribute(NoMatchAttribute()) ){
+        if( d_qe->getTermDatabase()->isTermActive( n ) ){
           Trace("ambqi-model-debug") << "  " << n << " -> " << fm->getRepresentativeId( n ) << std::endl;
           fapps.push_back( n );
         }
index 43f5ee2fd34f84368306e5cc2ce343c4b055d48a..a0d9bda0fe07445bedb0f4a501aecc7564284be1 100644 (file)
@@ -28,7 +28,7 @@ using namespace CVC4::theory;
 using namespace CVC4::theory::inst;
 
 bool CandidateGenerator::isLegalCandidate( Node n ){
-  return ( !n.getAttribute(NoMatchAttribute()) && ( !options::cbqi() || !quantifiers::TermDb::hasInstConstAttr(n) ) );
+  return d_qe->getTermDatabase()->isTermActive( n ) && ( !options::cbqi() || !quantifiers::TermDb::hasInstConstAttr(n) );
 }
 
 void CandidateGeneratorQueue::addCandidate( Node n ) {
@@ -59,7 +59,7 @@ Node CandidateGeneratorQueue::getNextCandidate(){
 }
 
 CandidateGeneratorQE::CandidateGeneratorQE( QuantifiersEngine* qe, Node pat ) :
-  d_qe( qe ), d_term_iter( -1 ){
+CandidateGenerator( qe ), d_term_iter( -1 ){
   d_op = qe->getTermDatabase()->getMatchOperator( pat );
   Assert( !d_op.isNull() );
   d_op_arity = pat.getNumChildren();
@@ -186,7 +186,7 @@ Node CandidateGeneratorQE::getNextCandidate(){
 }
 
 CandidateGeneratorQELitEq::CandidateGeneratorQELitEq( QuantifiersEngine* qe, Node mpat ) :
-  d_match_pattern( mpat ), d_qe( qe ){
+  CandidateGenerator( qe ), d_match_pattern( mpat ){
   Assert( mpat.getKind()==EQUAL );
   for( unsigned i=0; i<2; i++ ){
     if( !quantifiers::TermDb::hasInstConstAttr(mpat[i]) ){
@@ -225,7 +225,7 @@ Node CandidateGeneratorQELitEq::getNextCandidate(){
 
 
 CandidateGeneratorQELitDeq::CandidateGeneratorQELitDeq( QuantifiersEngine* qe, Node mpat ) :
-  d_match_pattern( mpat ), d_qe( qe ){
+CandidateGenerator( qe ), d_match_pattern( mpat ){
 
   Assert( d_match_pattern.getKind()==EQUAL || d_match_pattern.getKind()==IFF );
   d_match_pattern_type = d_match_pattern[0].getType();
@@ -259,7 +259,7 @@ Node CandidateGeneratorQELitDeq::getNextCandidate(){
 
 
 CandidateGeneratorQEAll::CandidateGeneratorQEAll( QuantifiersEngine* qe, Node mpat ) :
-  d_match_pattern( mpat ), d_qe( qe ){
+  CandidateGenerator( qe ), d_match_pattern( mpat ){
   d_match_pattern_type = mpat.getType();
   Assert( mpat.getKind()==INST_CONSTANT );
   d_f = quantifiers::TermDb::getInstConstAttr( mpat );
index 18ef6a086383431c51ba1891fda5dfe7504c1fe9..4fc6969fc2be4f72b78dfd406174e29af88d2f75 100644 (file)
@@ -33,8 +33,10 @@ namespace inst {
 
 /** base class for generating candidates for matching */
 class CandidateGenerator {
+protected:
+  QuantifiersEngine* d_qe;
 public:
-  CandidateGenerator(){}
+  CandidateGenerator( QuantifiersEngine* qe ) : d_qe( qe ){}
   virtual ~CandidateGenerator(){}
 
   /** Get candidates functions.  These set up a context to get all match candidates.
@@ -54,7 +56,7 @@ public:
   virtual void resetInstantiationRound() = 0;
 public:
   /** legal candidate */
-  static bool isLegalCandidate( Node n );
+  bool isLegalCandidate( Node n );
 };/* class CandidateGenerator */
 
 /** candidate generator queue (for manual candidate generation) */
@@ -63,7 +65,7 @@ private:
   std::vector< Node > d_candidates;
   int d_candidate_index;
 public:
-  CandidateGeneratorQueue() : d_candidate_index( 0 ){}
+  CandidateGeneratorQueue( QuantifiersEngine* qe ) : CandidateGenerator( qe ), d_candidate_index( 0 ){}
   ~CandidateGeneratorQueue() throw() {}
 
   void addCandidate( Node n );
@@ -80,8 +82,6 @@ class CandidateGeneratorQE : public CandidateGenerator
 private:
   //operator you are looking for
   Node d_op;
-  //instantiator pointer
-  QuantifiersEngine* d_qe;
   //the equality class iterator
   unsigned d_op_arity;
   std::vector< quantifiers::TermArgTrie* > d_tindex;
@@ -122,8 +122,6 @@ private:
   Node d_match_pattern;
   Node d_match_gterm;
   bool d_do_mgt;
-  //einstantiator pointer
-  QuantifiersEngine* d_qe;
 public:
   CandidateGeneratorQELitEq( QuantifiersEngine* qe, Node mpat );
   ~CandidateGeneratorQELitEq() throw() {}
@@ -142,8 +140,6 @@ private:
   Node d_match_pattern;
   //type of disequality
   TypeNode d_match_pattern_type;
-  //einstantiator pointer
-  QuantifiersEngine* d_qe;
 public:
   CandidateGeneratorQELitDeq( QuantifiersEngine* qe, Node mpat );
   ~CandidateGeneratorQELitDeq() throw() {}
@@ -161,8 +157,6 @@ private:
   //equality you are trying to match equalities for
   Node d_match_pattern;
   TypeNode d_match_pattern_type;
-  //einstantiator pointer
-  QuantifiersEngine* d_qe;
   // quantifier/index for the variable we are matching
   Node d_f;
   unsigned d_index;
index 2cc49ef5a441358cda01a6ad88e2ccc949f71b01..fa71f0132a13a95af7b7e79a6fa5725fe51a3b7b 100644 (file)
@@ -285,7 +285,7 @@ Node ConjectureGenerator::getFreeVar( TypeNode tn, unsigned i ) {
 }
 
 bool ConjectureGenerator::isHandledTerm( TNode n ){
-  return !n.getAttribute(NoMatchAttribute()) && inst::Trigger::isAtomicTrigger( n ) && ( n.getKind()!=APPLY_UF || n.getOperator().getKind()!=SKOLEM );
+  return d_quantEngine->getTermDatabase()->isTermActive( n ) && inst::Trigger::isAtomicTrigger( n ) && ( n.getKind()!=APPLY_UF || n.getOperator().getKind()!=SKOLEM );
 }
 
 Node ConjectureGenerator::getGroundEqc( TNode r ) {
@@ -425,7 +425,7 @@ void ConjectureGenerator::check( Theory::Effort e, unsigned quant_e ) {
           eq::EqClassIterator eqc_i = eq::EqClassIterator( r, ee );
           while( !eqc_i.isFinished() ){
             TNode n = (*eqc_i);
-            if( getTermDatabase()->hasTermCurrent( n ) && !n.getAttribute(NoMatchAttribute()) && ( n.getKind()!=EQUAL || isFalse ) ){
+            if( getTermDatabase()->hasTermCurrent( n ) && getTermDatabase()->isTermActive( n ) && ( n.getKind()!=EQUAL || isFalse ) ){
               if( firstTime ){
                 Trace("sg-gen-eqc") << "e" << d_em[r] << " : { " << std::endl;
                 firstTime = false;
index 33c8533289e7165c844e797d1b683d30dd289115..8835d00bc9f6cf2be374ff2a8057a0380a4f5ab6 100644 (file)
@@ -405,7 +405,7 @@ void FullModelChecker::processBuildModel(TheoryModel* m, bool fullModel){
       bool needsDefault = true;
       for( size_t i=0; i<fm->d_uf_terms[op].size(); i++ ){
         Node n = fm->d_uf_terms[op][i];
-        if( !n.getAttribute(NoMatchAttribute()) ){
+        if( d_qe->getTermDatabase()->isTermActive( n ) ){
           add_conds.push_back( n );
           add_values.push_back( n );
           Node r = fm->getUsedRepresentative(n);
index bf05de3bb4e2eb1e1f6bb98eb1743a5ea61b8345..bd5100a2e26f86865f577483e1fdc8776c4e18b9 100644 (file)
@@ -150,7 +150,7 @@ void InstMatchGenerator::initialize( Node q, QuantifiersEngine* qe, std::vector<
         d_cg = new inst::CandidateGeneratorQELitDeq( qe, d_match_pattern );
       }
     }else{
-      d_cg = new CandidateGeneratorQueue;
+      d_cg = new CandidateGeneratorQueue( qe );
       Trace("inst-match-gen-warn") << "(?) Unknown matching pattern is " << d_match_pattern << std::endl;
       d_matchPolicy = MATCH_GEN_INTERNAL_ERROR;
     }
@@ -697,7 +697,7 @@ int InstMatchGeneratorMulti::addTerm( Node q, Node t, QuantifiersEngine* qe ){
   return addedLemmas;
 }
 
-InstMatchGeneratorSimple::InstMatchGeneratorSimple( Node q, Node pat ) : d_f( q ), d_match_pattern( pat ) {
+InstMatchGeneratorSimple::InstMatchGeneratorSimple( Node q, Node pat, QuantifiersEngine* qe ) : d_f( q ), d_match_pattern( pat ) {
   if( d_match_pattern.getKind()==NOT ){
     d_match_pattern = d_match_pattern[0];
     d_pol = false;
@@ -720,10 +720,11 @@ InstMatchGeneratorSimple::InstMatchGeneratorSimple( Node q, Node pat ) : d_f( q
     }
     d_match_pattern_arg_types.push_back( d_match_pattern[i].getType() );
   }
+  d_op = qe->getTermDatabase()->getMatchOperator( d_match_pattern );
 }
 
 void InstMatchGeneratorSimple::resetInstantiationRound( QuantifiersEngine* qe ) {
-  d_op = qe->getTermDatabase()->getMatchOperator( d_match_pattern );
+  
 }
 
 int InstMatchGeneratorSimple::addInstantiations( Node q, InstMatch& baseMatch, QuantifiersEngine* qe ){
@@ -751,6 +752,7 @@ int InstMatchGeneratorSimple::addInstantiations( Node q, InstMatch& baseMatch, Q
       tat = NULL;
     }
   }
+  Debug("simple-trigger-debug") << "Adding instantiations based on " << tat << " from " << d_op << " " << d_eqc << std::endl;
   if( tat ){
     InstMatch m( q );
     m.add( baseMatch );
index a1d90700143769c2a5bc8a77039fd85ced021d24..49e3c1ec51d3e61c2572637ec8e569fa98911f95 100644 (file)
@@ -224,7 +224,7 @@ private:
   void addInstantiations( InstMatch& m, QuantifiersEngine* qe, int& addedLemmas, int argIndex, quantifiers::TermArgTrie* tat );
 public:
   /** constructors */
-  InstMatchGeneratorSimple( Node q, Node pat );
+  InstMatchGeneratorSimple( Node q, Node pat, QuantifiersEngine* qe );
   /** destructor */
   ~InstMatchGeneratorSimple() throw() {}
   /** reset instantiation round (call this whenever equivalence classes have changed) */
index 630880690fab4dfc359a2f7cd03225c1457bba59..d58bbcf3a17302550acc2043976d9d6562a7ff4a 100644 (file)
@@ -83,9 +83,8 @@ int InstStrategyUserPatterns::process( Node f, Theory::Effort effort, int e ){
 
       Trace("inst-alg") << "-> User-provided instantiate " << f << "..." << std::endl;
       if( d_quantEngine->getInstUserPatMode()==USER_PAT_MODE_RESORT  ){
-        int matchOption = 0;
         for( unsigned i=0; i<d_user_gen_wait[f].size(); i++ ){
-          Trigger * t = Trigger::mkTrigger( d_quantEngine, f, d_user_gen_wait[f][i], matchOption, true, Trigger::TR_RETURN_NULL );
+          Trigger * t = Trigger::mkTrigger( d_quantEngine, f, d_user_gen_wait[f][i], true, Trigger::TR_RETURN_NULL );
           if( t ){
             d_user_gen[f].push_back( t );
           }
@@ -134,11 +133,10 @@ void InstStrategyUserPatterns::addUserPattern( Node q, Node pat ){
   if( usable ){
     Trace("user-pat") << "Add user pattern: " << pat << " for " << q << std::endl;
     //check match option
-    int matchOption = 0;
     if( d_quantEngine->getInstUserPatMode()==USER_PAT_MODE_RESORT ){
       d_user_gen_wait[q].push_back( nodes );
     }else{
-      Trigger * t = Trigger::mkTrigger( d_quantEngine, q, nodes, matchOption, true, Trigger::TR_MAKE_NEW );
+      Trigger * t = Trigger::mkTrigger( d_quantEngine, q, nodes, true, Trigger::TR_MAKE_NEW );
       if( t ){
         d_user_gen[q].push_back( t );
       }else{
@@ -306,6 +304,23 @@ void InstStrategyAutoGenTriggers::generateTriggers( Node f ){
         last_weight = curr_w;
       }
     }
+    d_num_trigger_vars[f] = vcMap.size();
+    if( d_num_trigger_vars[f]>0 && d_num_trigger_vars[f]<f[0].getNumChildren() ){
+      Trace("auto-gen-trigger-partial") << "Quantified formula : " << f << std::endl;
+      Trace("auto-gen-trigger-partial") << "...does not contain all variables in triggers!!!" << std::endl;
+      if( options::partialTriggers() ){
+        std::vector< Node > vcs[2];
+        for( unsigned i=0; i<f[0].getNumChildren(); i++ ){
+          Node ic = d_quantEngine->getTermDatabase()->getInstantiationConstant( f, i );
+          vcs[ vcMap.find( ic )==vcMap.end() ? 0 : 1 ].push_back( f[0][i] );
+        }
+        for( unsigned i=0; i<2; i++ ){
+          d_vc_partition[i][f] = NodeManager::currentNM()->mkNode( BOUND_VAR_LIST, vcs[i] );
+        }
+      }else{
+        return;
+      }
+    }
     for( unsigned i=0; i<patTermsF.size(); i++ ){
       Node pat = patTermsF[i];
       if( rmPatTermsF.find( pat )==rmPatTermsF.end() ){
@@ -381,10 +396,9 @@ void InstStrategyAutoGenTriggers::generateTriggers( Node f ){
         }
       }
       //now, generate the trigger...
-      int matchOption = 0;
       Trigger* tr = NULL;
       if( d_is_single_trigger[ patTerms[0] ] ){
-        tr = Trigger::mkTrigger( d_quantEngine, f, patTerms[0], matchOption, false, Trigger::TR_RETURN_NULL );
+        tr = Trigger::mkTrigger( d_quantEngine, f, patTerms[0], false, Trigger::TR_RETURN_NULL, d_num_trigger_vars[f] );
         d_single_trigger_gen[ patTerms[0] ] = true;
       }else{
         //only generate multi trigger if option set, or if no single triggers exist
@@ -402,29 +416,14 @@ void InstStrategyAutoGenTriggers::generateTriggers( Node f ){
           d_made_multi_trigger[f] = true;
         }
         //will possibly want to get an old trigger
-        tr = Trigger::mkTrigger( d_quantEngine, f, patTerms, matchOption, false, Trigger::TR_GET_OLD );
+        tr = Trigger::mkTrigger( d_quantEngine, f, patTerms, false, Trigger::TR_GET_OLD, d_num_trigger_vars[f] );
       }
       if( tr ){
-        unsigned tindex;
-        if( tr->isMultiTrigger() ){
-          //disable all other multi triggers
-          for( std::map< Trigger*, bool >::iterator it = d_auto_gen_trigger[1][f].begin(); it != d_auto_gen_trigger[1][f].end(); ++it ){
-            d_auto_gen_trigger[1][f][ it->first ] = false;
-          }
-          tindex = 1;
-        }else{
-          tindex = 0;
-        }
-        //making it during an instantiation round, so must reset
-        if( d_auto_gen_trigger[tindex][f].find( tr )==d_auto_gen_trigger[tindex][f].end() ){
-          tr->resetInstantiationRound();
-          tr->reset( Node::null() );
-        }
-        d_auto_gen_trigger[tindex][f][tr] = true;
+        addTrigger( tr, f );
         //if we are generating additional triggers...
-        if( tindex==0 ){
-          int index = 0;
-          if( index<(int)patTerms.size() ){
+        if( !tr->isMultiTrigger() ){
+          unsigned index = 0;
+          if( index<patTerms.size() ){
             //Notice() << "check add additional" << std::endl;
             //check if similar patterns exist, and if so, add them additionally
             int nqfs_curr = 0;
@@ -433,18 +432,13 @@ void InstStrategyAutoGenTriggers::generateTriggers( Node f ){
             }
             index++;
             bool success = true;
-            while( success && index<(int)patTerms.size() && d_is_single_trigger[ patTerms[index] ] ){
+            while( success && index<patTerms.size() && d_is_single_trigger[ patTerms[index] ] ){
               success = false;
               if( !options::relevantTriggers() ||
                   d_quantEngine->getQuantifierRelevance()->getNumQuantifiersForSymbol( patTerms[index].getOperator() )<=nqfs_curr ){
                 d_single_trigger_gen[ patTerms[index] ] = true;
-                Trigger* tr2 = Trigger::mkTrigger( d_quantEngine, f, patTerms[index], matchOption, false, Trigger::TR_RETURN_NULL );
-                if( tr2 ){
-                  //Notice() << "Add additional trigger " << patTerms[index] << std::endl;
-                  tr2->resetInstantiationRound();
-                  tr2->reset( Node::null() );
-                  d_auto_gen_trigger[0][f][tr2] = true;
-                }
+                Trigger* tr2 = Trigger::mkTrigger( d_quantEngine, f, patTerms[index], false, Trigger::TR_RETURN_NULL, d_num_trigger_vars[f] );
+                addTrigger( tr2, f );
                 success = true;
               }
               index++;
@@ -458,7 +452,8 @@ void InstStrategyAutoGenTriggers::generateTriggers( Node f ){
 }
 
 void InstStrategyAutoGenTriggers::addPatternToPool( Node q, Node pat, unsigned num_fv ) {
-  if( num_fv==q[0].getNumChildren() && ( options::pureThTriggers() || !Trigger::isPureTheoryTrigger( pat ) ) ){
+  unsigned num_vars = options::partialTriggers() ? d_num_trigger_vars[q] : q[0].getNumChildren();
+  if( num_fv==num_vars && ( options::pureThTriggers() || !Trigger::isPureTheoryTrigger( pat ) ) ){
     d_patTerms[0][q].push_back( pat );
     d_is_single_trigger[ pat ] = true;
   }else{
@@ -467,6 +462,38 @@ void InstStrategyAutoGenTriggers::addPatternToPool( Node q, Node pat, unsigned n
   }
 }
 
+
+void InstStrategyAutoGenTriggers::addTrigger( inst::Trigger * tr, Node q ) {
+  if( tr ){
+    if( d_num_trigger_vars[q]<q[0].getNumChildren() ){
+      //partial trigger : generate implication to mark user pattern
+      Node ipl = NodeManager::currentNM()->mkNode( INST_PATTERN_LIST, d_quantEngine->getTermDatabase()->getVariableNode( tr->getInstPattern(), q ) );
+      Node qq = NodeManager::currentNM()->mkNode( FORALL, d_vc_partition[1][q], NodeManager::currentNM()->mkNode( FORALL, d_vc_partition[0][q], q[1] ), ipl );
+      Trace("auto-gen-trigger-partial") << "Make partially specified user pattern: " << std::endl;
+      Trace("auto-gen-trigger-partial") << "  " << qq << std::endl;
+      Node lem = NodeManager::currentNM()->mkNode( OR, q.negate(), qq );
+      d_quantEngine->addLemma( lem );
+    }else{
+      unsigned tindex;
+      if( tr->isMultiTrigger() ){
+        //disable all other multi triggers
+        for( std::map< Trigger*, bool >::iterator it = d_auto_gen_trigger[1][q].begin(); it != d_auto_gen_trigger[1][q].end(); ++it ){
+          d_auto_gen_trigger[1][q][ it->first ] = false;
+        }
+        tindex = 1;
+      }else{
+        tindex = 0;
+      }
+      //making it during an instantiation round, so must reset
+      if( d_auto_gen_trigger[tindex][q].find( tr )==d_auto_gen_trigger[tindex][q].end() ){
+        tr->resetInstantiationRound();
+        tr->reset( Node::null() );
+      }
+      d_auto_gen_trigger[tindex][q][tr] = true;
+    }
+  }
+}
+
 bool InstStrategyAutoGenTriggers::hasUserPatterns( Node q ) {
   if( q.getNumChildren()==3 ){
     std::map< Node, bool >::iterator it = d_hasUserPatterns.find( q );
@@ -519,8 +546,7 @@ bool InstStrategyLocalTheoryExt::isLocalTheoryExt( Node f ) {
         Trace("local-t-ext") << "  " << patTerms[i] << std::endl;
       }
       Trace("local-t-ext") << std::endl;
-      int matchOption = 0;
-      Trigger * tr = Trigger::mkTrigger( d_quantEngine, f, patTerms, matchOption, true, Trigger::TR_GET_OLD );
+      Trigger * tr = Trigger::mkTrigger( d_quantEngine, f, patTerms, true, Trigger::TR_GET_OLD );
       d_lte_trigger[f] = tr;
     }else{
       Trace("local-t-ext") << "No local theory extensions trigger for " << f << "." << std::endl;
index 028f24b277fa11736f39380d867543868097765b..97d97b10a6e2e7fbed711a201270c4c27a7efed3 100644 (file)
@@ -83,6 +83,9 @@ private:
   std::map< Node, std::map< inst::Trigger*, bool > > d_processed_trigger;
   //instantiation no patterns
   std::map< Node, std::vector< Node > > d_user_no_gen;
+  // number of trigger variables per quantifier
+  std::map< Node, unsigned > d_num_trigger_vars;
+  std::map< Node, Node > d_vc_partition[2];
 private:
   /** process functions */
   void processResetInstantiationRound( Theory::Effort effort );
@@ -90,7 +93,7 @@ private:
   /** generate triggers */
   void generateTriggers( Node q );
   void addPatternToPool( Node q, Node pat, unsigned num_fv );
-  //bool addTrigger( inst::Trigger * tr, Node f, unsigned r );
+  void addTrigger( inst::Trigger * tr, Node f );
   /** has user patterns */
   bool hasUserPatterns( Node q );
   /** has user patterns */
index 3ae36b1d485a3fb4fcb50a5200a9c06710e57741..42fd7c35446db86f7b0c6ffee0e6ac0c4f147de7 100644 (file)
@@ -114,7 +114,7 @@ bool TermArgBasisTrie::addTerm2( FirstOrderModel* fm, Node n, int argIndex ){
 
 
 QModelBuilderIG::QModelBuilderIG( context::Context* c, QuantifiersEngine* qe ) :
-QModelBuilder( c, qe ) {
+QModelBuilder( c, qe ), d_basisNoMatch( c ) {
 
 }
 
@@ -302,7 +302,7 @@ void QModelBuilderIG::analyzeModel( FirstOrderModel* fm ){
     for( size_t i=0; i<fmig->d_uf_terms[op].size(); i++ ){
       Node n = fmig->d_uf_terms[op][i];
       //for calculating if op is constant
-      if( !n.getAttribute(NoMatchAttribute()) ){
+      if( d_qe->getTermDatabase()->isTermActive( n ) ){
         Node v = fmig->getRepresentative( n );
         if( i==0 ){
           d_uf_prefs[op].d_const_val = v;
@@ -312,12 +312,11 @@ void QModelBuilderIG::analyzeModel( FirstOrderModel* fm ){
         }
       }
       //for calculating terms that we don't need to consider
-      if( !n.getAttribute(NoMatchAttribute()) || n.getAttribute(ModelBasisArgAttribute())!=0 ){
-        if( !n.getAttribute(BasisNoMatchAttribute()) ){
+      if( d_qe->getTermDatabase()->isTermActive( n ) || n.getAttribute(ModelBasisArgAttribute())!=0 ){
+        if( d_basisNoMatch.find( n )==d_basisNoMatch.end() ){
           //need to consider if it is not congruent modulo model basis
           if( !tabt.addTerm( fmig, n ) ){
-             BasisNoMatchAttribute bnma;
-             n.setAttribute(bnma,true);
+            d_basisNoMatch[n] = true;
           }
         }
       }
@@ -382,8 +381,8 @@ bool QModelBuilderIG::isQuantifierActive( Node f ){
 }
 
 bool QModelBuilderIG::isTermActive( Node n ){
-  return !n.getAttribute(NoMatchAttribute()) || //it is not congruent to another active term
-         ( n.getAttribute(ModelBasisArgAttribute())!=0 && !n.getAttribute(BasisNoMatchAttribute()) ); //or it has model basis arguments
+  return d_qe->getTermDatabase()->isTermActive( n ) || //it is not congruent to another active term
+         ( n.getAttribute(ModelBasisArgAttribute())!=0 && d_basisNoMatch.find( n )==d_basisNoMatch.end() ); //or it has model basis arguments
                                                                                                       //and is not congruent modulo model basis
                                                                                                       //to another active term
 }
@@ -667,7 +666,7 @@ int QModelBuilderDefault::doInstGen( FirstOrderModel* fm, Node f ){
       //if applicable, try to add exceptions here
       if( !tr_terms.empty() ){
         //make a trigger for these terms, add instantiations
-        inst::Trigger* tr = inst::Trigger::mkTrigger( d_qe, f, tr_terms, 0, true, inst::Trigger::TR_MAKE_NEW );
+        inst::Trigger* tr = inst::Trigger::mkTrigger( d_qe, f, tr_terms, true, inst::Trigger::TR_MAKE_NEW );
         //Notice() << "Trigger = " << (*tr) << std::endl;
         tr->resetInstantiationRound();
         tr->reset( Node::null() );
index 90667390342dcf5abf824e252b7390669ade11e8..e4f9529a81ab861d9e49ef38d43f36bd2436ce87 100644 (file)
@@ -57,15 +57,6 @@ public:
 
 
 
-/** Attribute true for nodes that should not be used when considered for inst-gen basis */
-struct BasisNoMatchAttributeId {};
-/** use the special for boolean flag */
-typedef expr::Attribute< BasisNoMatchAttributeId,
-                         bool,
-                         expr::attr::NullCleanupStrategy,
-                         true // context dependent
-                       > BasisNoMatchAttribute;
-
 class TermArgBasisTrie {
 private:
   bool addTerm2( FirstOrderModel* fm, Node n, int argIndex );
@@ -85,7 +76,9 @@ public:
   */
 class QModelBuilderIG : public QModelBuilder
 {
+  typedef context::CDHashMap<Node, bool, NodeHashFunction> BoolMap;
 protected:
+  BoolMap d_basisNoMatch;
   //map from operators to model preference data
   std::map< Node, uf::UfModelPreferenceData > d_uf_prefs;
   //built model uf
index 5aae4d640683b5451690de9b47ed34e965fabe2a..2f7864831b83ee1d3d8ba06de6112ac288465828 100644 (file)
@@ -185,19 +185,11 @@ RewriteResponse QuantifiersRewriter::preRewrite(TNode in) {
   if( in.getKind()==kind::EXISTS || in.getKind()==kind::FORALL ){
     Trace("quantifiers-rewrite-debug") << "pre-rewriting " << in << std::endl;
     std::vector< Node > args;
-    for( int i=0; i<(int)in[0].getNumChildren(); i++ ){
-      args.push_back( in[0][i] );
-    }
-    Node body = in[1];
+    Node body = in;
     bool doRewrite = false;
-    std::vector< Node > ipl;
-    while( body.getNumChildren()>=2 && body.getKind()==in.getKind() ){
-      if( body.getNumChildren()==3 ){
-        for( unsigned i=0; i<body[2].getNumChildren(); i++ ){
-          ipl.push_back( body[2][i] );
-        }
-      }
-      for( int i=0; i<(int)body[0].getNumChildren(); i++ ){
+    bool firstTime = true;
+    while( body.getNumChildren()==2 && body.getKind()==body[1].getKind() ){
+      for( unsigned i=0; i<body[0].getNumChildren(); i++ ){
         args.push_back( body[0][i] );
       }
       body = body[1];
@@ -207,14 +199,6 @@ RewriteResponse QuantifiersRewriter::preRewrite(TNode in) {
       std::vector< Node > children;
       children.push_back( NodeManager::currentNM()->mkNode(kind::BOUND_VAR_LIST,args) );
       children.push_back( body );
-      if( in.getNumChildren()==3 ){
-        for( unsigned i=0; i<in[2].getNumChildren(); i++ ){
-          ipl.push_back( in[2][i] );
-        }
-      }
-      if( !ipl.empty() ){
-        children.push_back( NodeManager::currentNM()->mkNode( INST_PATTERN_LIST, ipl ) );
-      }
       Node n = NodeManager::currentNM()->mkNode( in.getKind(), children );
       if( in!=n ){
         Trace("quantifiers-pre-rewrite") << "*** pre-rewrite " << in << std::endl;
index b353fce2f9ece52d6f85cb4d5b1eb7593419fab3..b4b51fd842b9b88c81fbea92c47a42d1cd5aa750 100644 (file)
@@ -110,7 +110,7 @@ void RelevantDomain::compute(){
       for( unsigned i=0; i<sz; i++ ){
         Node n = it->second[i];
         //if it is a non-redundant term
-        if( !n.getAttribute(NoMatchAttribute()) ){
+        if( db->isTermActive( n ) ){
           for( unsigned j=0; j<n.getNumChildren(); j++ ){
             RDomain * rf = getRDomain( op, j );
             rf->addTerm( n[j] );
index 5365dbcfae593a825868a7785ff6cb8dae6eec72..2c58b8f778af0be92473dd647b92cf2b23ab7c5c 100644 (file)
@@ -175,7 +175,7 @@ int RewriteEngine::checkRewriteRule( Node f, Theory::Effort e ) {
                   for( unsigned j=0; j<to_remove.size(); j++ ){
                     Node ns = d_quantEngine->getSubstitute( to_remove[j], inst );
                     Trace("rewrite-engine-inst-debug") << "Will remove : " << ns << std::endl;
-                    ns.setAttribute(NoMatchAttribute(),true);
+                    d_quantEngine->getTermDatabase()->setTermInactive( ns );
                   }
                   */
                 }else{
index 4dcf0e24814cfa713a4b1e9ae46dcbd7fe5117d1..b143286cc29be94a554143aeeb99269d05a61dc3 100644 (file)
@@ -84,7 +84,7 @@ void TermArgTrie::debugPrint( const char * c, Node n, unsigned depth ) {
   }
 }
 
-TermDb::TermDb( context::Context* c, context::UserContext* u, QuantifiersEngine* qe ) : d_quantEngine( qe ), d_op_id_count( 0 ), d_typ_id_count( 0 ) {
+TermDb::TermDb( context::Context* c, context::UserContext* u, QuantifiersEngine* qe ) : d_quantEngine( qe ), d_inactive_map( c ), d_op_id_count( 0 ), d_typ_id_count( 0 ) {
   d_true = NodeManager::currentNM()->mkConst( true );
   d_false = NodeManager::currentNM()->mkConst( false );
   d_zero = NodeManager::currentNM()->mkConst( Rational( 0 ) );
@@ -178,6 +178,8 @@ void TermDb::addTerm( Node n, std::set< Node >& added, bool withinQuant, bool wi
             }
           }
         }
+      }else{
+        setTermInactive( n );
       }
       rec = true;
     }
@@ -210,7 +212,7 @@ void TermDb::computeUfEqcTerms( TNode f ) {
     for( unsigned i=0; i<d_op_map[f].size(); i++ ){
       TNode n = d_op_map[f][i];
       if( hasTermCurrent( n ) ){
-        if( !n.getAttribute(NoMatchAttribute()) ){
+        if( isTermActive( n ) ){
           computeArgReps( n );
           TNode r = ee->hasTerm( n ) ? ee->getRepresentative( n ) : n;
           d_func_map_eqc_trie[f].d_data[r].addTerm( n, d_arg_reps[n] );
@@ -471,6 +473,18 @@ bool TermDb::isEntailed( TNode n, std::map< TNode, TNode >& subs, bool subsRep,
   return isEntailed2( n, subs, subsRep, true, pol, qy );
 }
 
+bool TermDb::isTermActive( Node n ) {
+  return d_inactive_map.find( n )==d_inactive_map.end(); 
+  //return !n.getAttribute(NoMatchAttribute());
+}
+
+void TermDb::setTermInactive( Node n ) {
+  d_inactive_map[n] = true;
+  //Trace("term-db-debug2") << "set no match attribute" << std::endl;
+  //NoMatchAttribute nma;
+  //n.setAttribute(nma,true);
+}
+
 bool TermDb::hasTermCurrent( Node n, bool useMode ) {
   if( !useMode ){
     return d_has_map.find( n )!=d_has_map.end();
@@ -636,7 +650,7 @@ bool TermDb::reset( Theory::Effort effort ){
       Node n = it->second[i];
       //to be added to term index, term must be relevant, and exist in EE
       if( hasTermCurrent( n ) && ee->hasTerm( n ) ){
-        if( !n.getAttribute(NoMatchAttribute()) ){
+        if( isTermActive( n ) ){
           if( options::finiteModelFind() ){
             computeModelBasisArgAttribute( n );
           }
@@ -651,13 +665,11 @@ bool TermDb::reset( Theory::Effort effort ){
             }
           }
           Trace("term-db-debug") << std::endl;
-          if( ee->hasTerm( n ) ){
-            Trace("term-db-debug") << "  and value : " << ee->getRepresentative( n ) << std::endl;
-          }
+          Trace("term-db-debug") << "  and value : " << ee->getRepresentative( n ) << std::endl;
           Node at = d_func_map_trie[ it->first ].addOrGetTerm( n, d_arg_reps[n] );
+          Trace("term-db-debug2") << "...add term returned " << at << std::endl;
           if( at!=n && ee->areEqual( at, n ) ){
-            NoMatchAttribute nma;
-            n.setAttribute(nma,true);
+            setTermInactive( n );
             Trace("term-db-debug") << n << " is redundant." << std::endl;
             congruentCount++;
           }else{
@@ -846,9 +858,8 @@ void TermDb::makeInstantiationConstantsFor( Node q ){
       ic.setAttribute( ivna, i );
       InstConstantAttribute ica;
       ic.setAttribute( ica, q );
-      //also set the no-match attribute
-      NoMatchAttribute nma;
-      ic.setAttribute(nma,true);
+      //also set the term inactive
+      setTermInactive( ic );
     }
   }
 }
@@ -906,11 +917,6 @@ Node TermDb::getInstConstAttr( Node n ) {
     }
     InstConstantAttribute ica;
     n.setAttribute(ica, q);
-    if( !q.isNull() ){
-      //also set the no-match attribute
-      NoMatchAttribute nma;
-      n.setAttribute(nma,true);
-    }
   }
   return n.getAttribute(InstConstantAttribute());
 }
@@ -1019,9 +1025,12 @@ Node TermDb::getCounterexampleLiteral( Node q ){
 
 Node TermDb::getInstConstantNode( Node n, Node q ){
   makeInstantiationConstantsFor( q );
-  Node n2 = n.substitute( d_vars[q].begin(), d_vars[q].end(),
-                          d_inst_constants[q].begin(), d_inst_constants[q].end() );
-  return n2;
+  return n.substitute( d_vars[q].begin(), d_vars[q].end(), d_inst_constants[q].begin(), d_inst_constants[q].end() );
+}
+
+Node TermDb::getVariableNode( Node n, Node q ) {
+  makeInstantiationConstantsFor( q );
+  return n.substitute( d_inst_constants[q].begin(), d_inst_constants[q].end(), d_vars[q].begin(), d_vars[q].end() );
 }
 
 Node TermDb::getInstantiatedNode( Node n, Node q, std::vector< Node >& terms ) {
index 266d9b8fabab4f642797c48202d2dc15bd522924..004292622c368501d2b7294b5ea7057a265ce168 100644 (file)
@@ -47,15 +47,6 @@ typedef expr::Attribute< SygusAttributeId, bool > SygusAttribute;
 struct SynthesisAttributeId {};
 typedef expr::Attribute< SynthesisAttributeId, bool > SynthesisAttribute;
 
-/** Attribute true for nodes that should not be used for matching */
-struct NoMatchAttributeId {};
-/** use the special for boolean flag */
-typedef expr::Attribute< NoMatchAttributeId,
-                         bool,
-                         expr::attr::NullCleanupStrategy,
-                         true // context dependent
-                       > NoMatchAttribute;
-
 // attribute for "contains instantiation constants from"
 struct InstConstantAttributeId {};
 typedef expr::Attribute<InstConstantAttributeId, Node> InstConstantAttribute;
@@ -179,6 +170,7 @@ class TermDb : public QuantifiersUtil {
   friend class ::CVC4::theory::quantifiers::ConjectureGenerator;
   friend class ::CVC4::theory::quantifiers::TermGenEnv;
   typedef context::CDHashMap<Node, int, NodeHashFunction> NodeIntMap;
+  typedef context::CDHashMap<Node, bool, NodeHashFunction> NodeBoolMap;
 private:
   /** reference to the quantifiers engine */
   QuantifiersEngine* d_quantEngine;
@@ -211,6 +203,8 @@ private:
   std::map< Node, std::vector< Node > > d_op_map;
   /** map from type nodes to terms of that type */
   std::map< TypeNode, std::vector< Node > > d_type_map;
+  /** inactive map */
+  NodeBoolMap d_inactive_map;
 
   /** count number of non-redundant ground terms per operator */
   std::map< Node, int > d_op_nonred_count;
@@ -266,6 +260,9 @@ public:
   /** is entailed (incomplete check) */
   bool isEntailed( TNode n, bool pol, EqualityQuery * qy = NULL );
   bool isEntailed( TNode n, std::map< TNode, TNode >& subs, bool subsRep, bool pol, EqualityQuery * qy = NULL );
+  /** is active */
+  bool isTermActive( Node n );
+  void setTermInactive( Node n );
   /** has term */
   bool hasTermCurrent( Node n, bool useMode = true );
   /** is term eligble for instantiation? */
@@ -327,6 +324,7 @@ public:
       instantiation.
    */
   Node getInstConstantNode( Node n, Node q );
+  Node getVariableNode( Node n, Node q );
   /** get substituted node */
   Node getInstantiatedNode( Node n, Node q, std::vector< Node >& terms );
 
index 38635b37b252d03fb96e81a8b3ad092d56238442..c911942396e546d7615878e1b8aa4ce9a480f0f8 100644 (file)
@@ -43,9 +43,8 @@ void TriggerTermInfo::init( Node q, Node n, int reqPol, Node reqPolEq ){
 }
 
 /** trigger class constructor */
-Trigger::Trigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes, int matchOption )
-    : d_quantEngine( qe ), d_f( f )
-{
+Trigger::Trigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes )
+    : d_quantEngine( qe ), d_f( f ) {
   d_nodes.insert( d_nodes.begin(), nodes.begin(), nodes.end() );
   Trace("trigger") << "Trigger for " << f << ": " << std::endl;
   for( unsigned i=0; i<d_nodes.size(); i++ ){
@@ -53,7 +52,7 @@ Trigger::Trigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes, int
   }
   if( d_nodes.size()==1 ){
     if( isSimpleTrigger( d_nodes[0] ) ){
-      d_mg = new InstMatchGeneratorSimple( f, d_nodes[0] );
+      d_mg = new InstMatchGeneratorSimple( f, d_nodes[0], qe );
     }else{
       d_mg = InstMatchGenerator::mkInstMatchGenerator( f, d_nodes[0], qe );
       d_mg->setActiveAdd(true);
@@ -112,6 +111,10 @@ int Trigger::addTerm( Node t ){
   return d_mg->addTerm( d_f, t, d_quantEngine );
 }
 
+Node Trigger::getInstPattern(){
+  return NodeManager::currentNM()->mkNode( INST_PATTERN, d_nodes );
+}
+
 int Trigger::addInstantiations( InstMatch& baseMatch ){
   int addedLemmas = d_mg->addInstantiations( d_f, baseMatch, d_quantEngine );
   if( addedLemmas>0 ){
@@ -124,77 +127,85 @@ int Trigger::addInstantiations( InstMatch& baseMatch ){
   return addedLemmas;
 }
 
-Trigger* Trigger::mkTrigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes, int matchOption, bool keepAll, int trOption ){
-  std::vector< Node > trNodes;
-  if( !keepAll ){
-    //only take nodes that contribute variables to the trigger when added
-    std::vector< Node > temp;
-    temp.insert( temp.begin(), nodes.begin(), nodes.end() );
-    std::map< Node, bool > vars;
-    std::map< Node, std::vector< Node > > patterns;
-    size_t varCount = 0;
-    std::map< Node, std::vector< Node > > varContains;
-    quantifiers::TermDb::getVarContains( f, temp, varContains );
-    for( unsigned i=0; i<temp.size(); i++ ){
-      bool foundVar = false;
+bool Trigger::mkTriggerTerms( Node q, std::vector< Node >& nodes, unsigned n_vars, std::vector< Node >& trNodes ) {
+  //only take nodes that contribute variables to the trigger when added
+  std::vector< Node > temp;
+  temp.insert( temp.begin(), nodes.begin(), nodes.end() );
+  std::map< Node, bool > vars;
+  std::map< Node, std::vector< Node > > patterns;
+  size_t varCount = 0;
+  std::map< Node, std::vector< Node > > varContains;
+  quantifiers::TermDb::getVarContains( q, temp, varContains );
+  for( unsigned i=0; i<temp.size(); i++ ){
+    bool foundVar = false;
+    for( unsigned j=0; j<varContains[ temp[i] ].size(); j++ ){
+      Node v = varContains[ temp[i] ][j];
+      Assert( quantifiers::TermDb::getInstConstAttr(v)==q );
+      if( vars.find( v )==vars.end() ){
+        varCount++;
+        vars[ v ] = true;
+        foundVar = true;
+      }
+    }
+    if( foundVar ){
+      trNodes.push_back( temp[i] );
       for( unsigned j=0; j<varContains[ temp[i] ].size(); j++ ){
         Node v = varContains[ temp[i] ][j];
-        Assert( quantifiers::TermDb::getInstConstAttr(v)==f );
-        if( vars.find( v )==vars.end() ){
-          varCount++;
-          vars[ v ] = true;
-          foundVar = true;
-        }
-      }
-      if( foundVar ){
-        trNodes.push_back( temp[i] );
-        for( unsigned j=0; j<varContains[ temp[i] ].size(); j++ ){
-          Node v = varContains[ temp[i] ][j];
-          patterns[ v ].push_back( temp[i] );
-        }
-      }
-      if( varCount==f[0].getNumChildren() ){
-        break;
+        patterns[ v ].push_back( temp[i] );
       }
     }
-    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] << " ";
-      }
-      Trace("trigger-debug") << std::endl;
+    if( varCount==n_vars ){
+      break;
+    }
+  }
+  if( varCount<n_vars ){
+    Trace("trigger-debug") << "Don't consider trigger since it does not contain specified number of variables." << std::endl;
+    for( unsigned i=0; i<nodes.size(); i++) {
+      Trace("trigger-debug") << nodes[i] << " ";
+    }
+    Trace("trigger-debug") << std::endl;
 
-      //do not generate multi-trigger if it does not contain all variables
-      return NULL;
-    }else{
-      //now, minimize the trigger
-      for( unsigned i=0; i<trNodes.size(); i++ ){
-        bool keepPattern = false;
-        Node n = trNodes[i];
+    //do not generate multi-trigger if it does not contain all variables
+    return false;
+  }else{
+    //now, minimize the trigger
+    for( unsigned i=0; i<trNodes.size(); i++ ){
+      bool keepPattern = false;
+      Node n = trNodes[i];
+      for( unsigned j=0; j<varContains[ n ].size(); j++ ){
+        Node v = varContains[ n ][j];
+        if( patterns[v].size()==1 ){
+          keepPattern = true;
+          break;
+        }
+      }
+      if( !keepPattern ){
+        //remove from pattern vector
         for( unsigned j=0; j<varContains[ n ].size(); j++ ){
           Node v = varContains[ n ][j];
-          if( patterns[v].size()==1 ){
-            keepPattern = true;
-            break;
-          }
-        }
-        if( !keepPattern ){
-          //remove from pattern vector
-          for( unsigned j=0; j<varContains[ n ].size(); j++ ){
-            Node v = varContains[ n ][j];
-            for( unsigned k=0; k<patterns[v].size(); k++ ){
-              if( patterns[v][k]==n ){
-                patterns[v].erase( patterns[v].begin() + k, patterns[v].begin() + k + 1 );
-                break;
-              }
+          for( unsigned k=0; k<patterns[v].size(); k++ ){
+            if( patterns[v][k]==n ){
+              patterns[v].erase( patterns[v].begin() + k, patterns[v].begin() + k + 1 );
+              break;
             }
           }
-          //remove from trigger nodes
-          trNodes.erase( trNodes.begin() + i, trNodes.begin() + i + 1 );
-          i--;
         }
+        //remove from trigger nodes
+        trNodes.erase( trNodes.begin() + i, trNodes.begin() + i + 1 );
+        i--;
       }
     }
+  }
+  return true;
+}
+
+Trigger* Trigger::mkTrigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes, bool keepAll, int trOption, unsigned use_n_vars ){
+  std::vector< Node > trNodes;
+  if( !keepAll ){
+    unsigned n_vars = use_n_vars==0 ? f[0].getNumChildren() : use_n_vars;
+    if( !mkTriggerTerms( f, nodes, n_vars, trNodes ) ){
+      return NULL;
+    }
   }else{
     trNodes.insert( trNodes.begin(), nodes.begin(), nodes.end() );
   }
@@ -211,15 +222,15 @@ Trigger* Trigger::mkTrigger( QuantifiersEngine* qe, Node f, std::vector< Node >&
       }
     }
   }
-  Trigger* t = new Trigger( qe, f, trNodes, matchOption );
+  Trigger* t = new Trigger( qe, f, trNodes );
   qe->getTriggerDatabase()->addTrigger( trNodes, t );
   return t;
 }
 
-Trigger* Trigger::mkTrigger( QuantifiersEngine* qe, Node f, Node n, int matchOption, bool keepAll, int trOption ){
+Trigger* Trigger::mkTrigger( QuantifiersEngine* qe, Node f, Node n, bool keepAll, int trOption, unsigned use_n_vars ){
   std::vector< Node > nodes;
   nodes.push_back( n );
-  return mkTrigger( qe, f, nodes, matchOption, keepAll, trOption );
+  return mkTrigger( qe, f, nodes, keepAll, trOption, use_n_vars );
 }
 
 bool Trigger::isUsable( Node n, Node q ){
@@ -343,9 +354,7 @@ bool Trigger::isUsableTrigger( Node n, Node q ){
 }
 
 bool Trigger::isAtomicTrigger( Node n ){
-  Kind k = n.getKind();
-  return ( k==APPLY_UF && !n.getOperator().getAttribute(NoMatchAttribute()) ) ||
-         ( k!=APPLY_UF && isAtomicTriggerKind( k ) );
+  return isAtomicTriggerKind( n.getKind() );
 }
 
 bool Trigger::isAtomicTriggerKind( Kind k ) {
index 41f2a1c38c0cbf928339de7eebbe114a9460e936..902f73e75f33a44736e9b0c8e72ad4dc2f476913 100644 (file)
@@ -76,6 +76,8 @@ class Trigger {
   int addTerm( Node t );
   /** return whether this is a multi-trigger */
   bool isMultiTrigger() { return d_nodes.size()>1; }
+  /** get inst pattern list */
+  Node getInstPattern();
 
   /** add all available instantiations exhaustively, in any equivalence class
       if limitInst>0, limitInst is the max # of instantiations to try */
@@ -84,8 +86,6 @@ class Trigger {
      ie     : quantifier engine;
      f      : forall something ....
      nodes  : (multi-)trigger
-     matchOption : which policy to use for creating matches
-                   (one of InstMatchGenerator::MATCH_GEN_* )
      keepAll: don't remove unneeded patterns;
      trOption : policy for dealing with triggers that already existed
                 (see below)
@@ -95,12 +95,12 @@ class Trigger {
     TR_GET_OLD,     //return a previous trigger if it had already been created
     TR_RETURN_NULL  //return null if a duplicate is found
   };
-  static Trigger* mkTrigger( QuantifiersEngine* qe, Node f,
-                             std::vector< Node >& nodes, int matchOption = 0,
-                             bool keepAll = true, int trOption = TR_MAKE_NEW );
-  static Trigger* mkTrigger( QuantifiersEngine* qe, Node f, Node n,
-                             int matchOption = 0, bool keepAll = true,
-                             int trOption = TR_MAKE_NEW );
+  //nodes input, trNodes output
+  static bool mkTriggerTerms( Node q, std::vector< Node >& nodes, unsigned n_vars, std::vector< Node >& trNodes );
+  static Trigger* mkTrigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes,
+                             bool keepAll = true, int trOption = TR_MAKE_NEW, unsigned use_n_vars = 0 );
+  static Trigger* mkTrigger( QuantifiersEngine* qe, Node f, Node n, bool keepAll = true,
+                             int trOption = TR_MAKE_NEW, unsigned use_n_vars = 0 );
   static void collectPatTerms( Node q, Node n, std::vector< Node >& patTerms, quantifiers::TriggerSelMode tstrt,
                                std::vector< Node >& exclude, std::map< Node, TriggerTermInfo >& tinfo,
                                bool filterInst = false );
@@ -135,7 +135,7 @@ class Trigger {
   }
 private:
   /** trigger constructor */
-  Trigger( QuantifiersEngine* ie, Node f, std::vector< Node >& nodes, int matchOption = 0 );
+  Trigger( QuantifiersEngine* ie, Node f, std::vector< Node >& nodes );
 
   /** is subterm of trigger usable */
   static bool isUsable( Node n, Node q );
index 6b5e0d1ed1e075d33405945dc1973613e2314c78..6c89c83361a9e19779c3fc6a0db4354fd82480f0 100644 (file)
@@ -79,7 +79,8 @@ TESTS =       \
        florian-case-ax.smt2 \
        double-pattern.smt2 \
        qcf-rel-dom-opt.smt2 \
-       parametric-lists.smt2
+       parametric-lists.smt2 \
+       partial-trigger.smt2
 
 
 # regression can be solved with --finite-model-find --fmf-inst-engine
diff --git a/test/regress/regress0/quantifiers/partial-trigger.smt2 b/test/regress/regress0/quantifiers/partial-trigger.smt2
new file mode 100644 (file)
index 0000000..beea57b
--- /dev/null
@@ -0,0 +1,10 @@
+; COMMAND-LINE: --partial-triggers
+; EXPECT: unsat
+(set-logic ALL_SUPPORTED)
+(set-info :status unsat)
+(declare-fun P (Int) Bool)
+(assert (forall ((x Int) (y Int)) (=> (> y 6) (or (> x y) (P x)))))
+
+(assert (not (P 5)))
+
+(check-sat)