dos2unix-convert some sources.
authorMorgan Deters <mdeters@cs.nyu.edu>
Mon, 16 Jun 2014 19:19:39 +0000 (15:19 -0400)
committerMorgan Deters <mdeters@cs.nyu.edu>
Mon, 16 Jun 2014 19:19:39 +0000 (15:19 -0400)
src/theory/quantifiers/ambqi_builder.cpp
src/theory/quantifiers/ambqi_builder.h
src/theory/quantifiers/qinterval_builder.cpp
src/theory/quantifiers/qinterval_builder.h
src/theory/quantifiers/quant_conflict_find.cpp
src/theory/quantifiers/quant_conflict_find.h
src/theory/strings/regexp_operation.cpp
src/theory/strings/regexp_operation.h
src/util/regexp.cpp

index e86a96a8f85d3591f4d1df6ec6d5a638c339eab1..374d161e9b334c5a2826a3842b7477ea0133697b 100755 (executable)
-/*********************                                                        */\r
-/*! \file ambqi_builder.cpp\r
- ** \verbatim\r
- ** Original author: Andrew Reynolds\r
- ** Major contributors: none\r
- ** Minor contributors (to current version): none\r
- ** This file is part of the CVC4 project.\r
- ** Copyright (c) 2009-2013  New York University and The University of Iowa\r
- ** See the file COPYING in the top-level source directory for licensing\r
- ** information.\endverbatim\r
- **\r
- ** \brief Implementation of abstract MBQI builder\r
- **/\r
-\r
-\r
-#include "theory/quantifiers/ambqi_builder.h"\r
-#include "theory/quantifiers/term_database.h"\r
-#include "theory/quantifiers/options.h"\r
-\r
-using namespace std;\r
-using namespace CVC4;\r
-using namespace CVC4::kind;\r
-using namespace CVC4::context;\r
-using namespace CVC4::theory;\r
-using namespace CVC4::theory::quantifiers;\r
-\r
-void AbsDef::construct_func( FirstOrderModelAbs * m, std::vector< TNode >& fapps, unsigned depth ) {\r
-  d_def.clear();\r
-  Assert( !fapps.empty() );\r
-  if( depth==fapps[0].getNumChildren() ){\r
-    //if( fapps.size()>1 ){\r
-    //  for( unsigned i=0; i<fapps.size(); i++ ){\r
-    //    std::cout << "...." << fapps[i] << " -> " << m->getRepresentativeId( fapps[i] ) << std::endl;\r
-    //  }\r
-    //}\r
-    //get representative in model for this term\r
-    d_value = m->getRepresentativeId( fapps[0] );\r
-    Assert( d_value!=val_none );\r
-  }else{\r
-    TypeNode tn = fapps[0][depth].getType();\r
-    std::map< unsigned, std::vector< TNode > > fapp_child;\r
-\r
-    //partition based on evaluations of fapps[1][depth]....fapps[n][depth]\r
-    for( unsigned i=0; i<fapps.size(); i++ ){\r
-      unsigned r = m->getRepresentativeId( fapps[i][depth] );\r
-      Assert( r < 32 );\r
-      fapp_child[r].push_back( fapps[i] );\r
-    }\r
-\r
-    //do completion\r
-    std::map< unsigned, unsigned > fapp_child_index;\r
-    unsigned def = m->d_domain[ tn ];\r
-    unsigned minSize = fapp_child.begin()->second.size();\r
-    unsigned minSizeIndex = fapp_child.begin()->first;\r
-    for( std::map< unsigned, std::vector< TNode > >::iterator it = fapp_child.begin(); it != fapp_child.end(); ++it ){\r
-      fapp_child_index[it->first] = ( 1 << it->first );\r
-      def = def & ~( 1 << it->first );\r
-      if( it->second.size()<minSize ){\r
-        minSize = it->second.size();\r
-        minSizeIndex = it->first;\r
-      }\r
-    }\r
-    fapp_child_index[minSizeIndex] |= def;\r
-    d_default = fapp_child_index[minSizeIndex];\r
-\r
-    //construct children\r
-    for( std::map< unsigned, std::vector< TNode > >::iterator it = fapp_child.begin(); it != fapp_child.end(); ++it ){\r
-      Trace("abs-model-debug") << "Construct " << it->first << " : " << fapp_child_index[it->first] << " : ";\r
-      debugPrintUInt( "abs-model-debug", m->d_rep_set.d_type_reps[tn].size(), fapp_child_index[it->first] );\r
-      Trace("abs-model-debug") << " : " << it->second.size() << " terms." << std::endl;\r
-      d_def[fapp_child_index[it->first]].construct_func( m, it->second, depth+1 );\r
-    }\r
-  }\r
-}\r
-\r
-void AbsDef::simplify( FirstOrderModelAbs * m, TNode q, TNode n, unsigned depth ) {\r
-  if( d_value==val_none && !d_def.empty() ){\r
-    //process the default\r
-    std::map< unsigned, AbsDef >::iterator defd = d_def.find( d_default );\r
-    Assert( defd!=d_def.end() );\r
-    unsigned newDef = d_default;\r
-    std::vector< unsigned > to_erase;\r
-    defd->second.simplify( m, q, n, depth+1 );\r
-    int defVal = defd->second.d_value;\r
-    bool isConstant = ( defVal!=val_none );\r
-    //process each child\r
-    for( std::map< unsigned, AbsDef >::iterator it = d_def.begin(); it != d_def.end(); ++it ){\r
-      if( it->first!=d_default ){\r
-        it->second.simplify( m, q, n, depth+1 );\r
-        if( it->second.d_value==defVal && it->second.d_value!=val_none ){\r
-          newDef = newDef | it->first;\r
-          to_erase.push_back( it->first );\r
-        }else{\r
-          isConstant = false;\r
-        }\r
-      }\r
-    }\r
-    if( !to_erase.empty() ){\r
-      //erase old default\r
-      int defVal = defd->second.d_value;\r
-      d_def.erase( d_default );\r
-      //set new default\r
-      d_default = newDef;\r
-      d_def[d_default].construct_def_entry( m, q, n, defVal, depth+1 );\r
-      //erase redundant entries\r
-      for( unsigned i=0; i<to_erase.size(); i++ ){\r
-        d_def.erase( to_erase[i] );\r
-      }\r
-    }\r
-    //if constant, propagate the value upwards\r
-    if( isConstant ){\r
-      d_value = defVal;\r
-    }else{\r
-      d_value = val_none;\r
-    }\r
-  }\r
-}\r
-\r
-void AbsDef::debugPrintUInt( const char * c, unsigned dSize, unsigned u ) const{\r
-  for( unsigned i=0; i<dSize; i++ ){\r
-    Trace(c) << ( ( u & ( 1 << i ) )!=0 ? "1" : "0");\r
-  }\r
-  //Trace(c) << "(";\r
-  //for( unsigned i=0; i<32; i++ ){\r
-  //  Trace(c) << ( ( u & ( 1 << i ) )!=0 ? "1" : "0");\r
-  //}\r
-  //Trace(c) << ")";\r
-}\r
-\r
-void AbsDef::debugPrint( const char * c, FirstOrderModelAbs * m, TNode f, unsigned depth ) const{\r
-  if( Trace.isOn(c) ){\r
-    if( depth==f.getNumChildren() ){\r
-      for( unsigned i=0; i<depth; i++ ){ Trace(c) << "  ";}\r
-      Trace(c) << "V[" << d_value << "]" << std::endl;\r
-    }else{\r
-      TypeNode tn = f[depth].getType();\r
-      unsigned dSize = m->d_rep_set.getNumRepresentatives( tn );\r
-      Assert( dSize<32 );\r
-      for( std::map< unsigned, AbsDef >::const_iterator it = d_def.begin(); it != d_def.end(); ++it ){\r
-        for( unsigned i=0; i<depth; i++ ){ Trace(c) << "  ";}\r
-        debugPrintUInt( c, dSize, it->first );\r
-        if( it->first==d_default ){\r
-          Trace(c) << "*";\r
-        }\r
-        if( it->second.d_value!=val_none ){\r
-          Trace(c) << " -> V[" << it->second.d_value << "]";\r
-        }\r
-        Trace(c) << std::endl;\r
-        it->second.debugPrint( c, m, f, depth+1 );\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-bool AbsDef::addInstantiations( FirstOrderModelAbs * m, QuantifiersEngine * qe, TNode q, std::vector< Node >& terms, int& inst, unsigned depth ) {\r
-  if( inst==0 || !options::fmfOneInstPerRound() ){\r
-    if( d_value==1 ){\r
-      //instantiations are all true : ignore this\r
-      return true;\r
-    }else{\r
-      if( depth==q[0].getNumChildren() ){\r
-        if( qe->addInstantiation( q, terms ) ){\r
-          Trace("ambqi-inst-debug") << "-> Added instantiation." << std::endl;\r
-          inst++;\r
-          return true;\r
-        }else{\r
-          Trace("ambqi-inst-debug") << "-> Failed to add instantiation." << std::endl;\r
-          //we are incomplete\r
-          return false;\r
-        }\r
-      }else{\r
-        bool osuccess = true;\r
-        TypeNode tn = m->getVariable( q, depth ).getType();\r
-        for( std::map< unsigned, AbsDef >::iterator it = d_def.begin(); it != d_def.end(); ++it ){\r
-          //get witness term\r
-          unsigned index = 0;\r
-          bool success;\r
-          do {\r
-            success = false;\r
-            index = getId( it->first, index );\r
-            if( index<32 ){\r
-              Assert( index<m->d_rep_set.d_type_reps[tn].size() );\r
-              terms[m->d_var_order[q][depth]] = m->d_rep_set.d_type_reps[tn][index];\r
-              //terms[depth] = m->d_rep_set.d_type_reps[tn][index];\r
-              if( !it->second.addInstantiations( m, qe, q, terms, inst, depth+1 ) && inst==0 ){\r
-                //if we are incomplete, and have not yet added an instantiation, keep trying\r
-                index++;\r
-                Trace("ambqi-inst-debug") << "At depth " << depth << ", failed branch, no instantiations and incomplete, increment index : " << index << std::endl;\r
-              }else{\r
-                success = true;\r
-              }\r
-            }\r
-          }while( !success && index<32 );\r
-          //mark if we are incomplete\r
-          osuccess = osuccess && success;\r
-        }\r
-        return osuccess;\r
-      }\r
-    }\r
-  }else{\r
-    return true;\r
-  }\r
-}\r
-\r
-void AbsDef::construct_entry( std::vector< unsigned >& entry, std::vector< bool >& entry_def, int v, unsigned depth ) {\r
-  if( depth==entry.size() ){\r
-    d_value = v;\r
-  }else{\r
-    d_def[entry[depth]].construct_entry( entry, entry_def, v, depth+1 );\r
-    if( entry_def[depth] ){\r
-      d_default = entry[depth];\r
-    }\r
-  }\r
-}\r
-\r
-void AbsDef::get_defs( unsigned u, std::vector< AbsDef * >& defs ) {\r
-  for( std::map< unsigned, AbsDef >::iterator it = d_def.begin(); it != d_def.end(); ++it ){\r
-    if( ( u & it->first )!=0 ){\r
-      Assert( (u & it->first)==u );\r
-      defs.push_back( &it->second );\r
-    }\r
-  }\r
-}\r
-\r
-void AbsDef::construct_normalize( FirstOrderModelAbs * m, TNode q, std::vector< AbsDef * >& defs, unsigned depth ) {\r
-  if( depth==q[0].getNumChildren() ){\r
-    Assert( defs.size()==1 );\r
-    d_value = defs[0]->d_value;\r
-  }else{\r
-    TypeNode tn = m->getVariable( q, depth ).getType();\r
-    unsigned def = m->d_domain[tn];\r
-    for( unsigned i=0; i<defs.size(); i++ ){\r
-      //process each simple child\r
-      for( std::map< unsigned, AbsDef >::iterator itd = defs[i]->d_def.begin(); itd != defs[i]->d_def.end(); ++itd ){\r
-        if( isSimple( itd->first ) && ( def & itd->first )!=0 ){\r
-          def &= ~( itd->first );\r
-          //process this value\r
-          std::vector< AbsDef * > cdefs;\r
-          for( unsigned j=0; j<defs.size(); j++ ){\r
-            defs[j]->get_defs( itd->first, cdefs );\r
-          }\r
-          d_def[itd->first].construct_normalize( m, q, cdefs, depth+1 );\r
-          if( def==0 ){\r
-            d_default = itd->first;\r
-            break;\r
-          }\r
-        }\r
-      }\r
-      if( def==0 ){\r
-        break;\r
-      }\r
-    }\r
-    if( def!=0 ){\r
-      d_default = def;\r
-      //process the default\r
-      std::vector< AbsDef * > cdefs;\r
-      for( unsigned j=0; j<defs.size(); j++ ){\r
-        defs[j]->get_defs( d_default, cdefs );\r
-      }\r
-      d_def[d_default].construct_normalize( m, q, cdefs, depth+1 );\r
-    }\r
-  }\r
-}\r
-\r
-void AbsDef::construct_def_entry( FirstOrderModelAbs * m, TNode q, TNode n, int v, unsigned depth ) {\r
-  d_value = v;\r
-  if( depth<n.getNumChildren() ){\r
-    TypeNode tn = q.isNull() ? n[depth].getType() : m->getVariable( q, depth ).getType();\r
-    unsigned dom = m->d_domain[tn] ;\r
-    d_def[dom].construct_def_entry( m, q, n, v, depth+1 );\r
-    d_default = dom;\r
-  }\r
-}\r
-\r
-void AbsDef::apply_ucompose( FirstOrderModelAbs * m, TNode q,\r
-                             std::vector< unsigned >& entry, std::vector< bool >& entry_def,\r
-                             std::vector< int >& terms, std::map< unsigned, int >& vchildren,\r
-                             AbsDef * a, unsigned depth ) {\r
-  if( depth==terms.size() ){\r
-    if( Trace.isOn("ambqi-check-debug2") ){\r
-      Trace("ambqi-check-debug2") << "Add entry ( ";\r
-      for( unsigned i=0; i<entry.size(); i++ ){\r
-        unsigned dSize = m->d_rep_set.d_type_reps[m->getVariable( q, i ).getType()].size();\r
-        debugPrintUInt( "ambqi-check-debug2", dSize, entry[i] );\r
-        Trace("ambqi-check-debug2") << " ";\r
-      }\r
-      Trace("ambqi-check-debug2") << ")" << std::endl;\r
-    }\r
-    a->construct_entry( entry, entry_def, d_value );\r
-  }else{\r
-    unsigned id;\r
-    if( terms[depth]==val_none ){\r
-      //a variable\r
-      std::map< unsigned, int >::iterator itv = vchildren.find( depth );\r
-      Assert( itv!=vchildren.end() );\r
-      unsigned prev_v = entry[itv->second];\r
-      bool prev_vd = entry_def[itv->second];\r
-      for( std::map< unsigned, AbsDef >::iterator it = d_def.begin(); it != d_def.end(); ++it ){\r
-        entry[itv->second] = it->first & prev_v;\r
-        entry_def[itv->second] = ( it->first==d_default ) && prev_vd;\r
-        if( entry[itv->second]!=0 ){\r
-          it->second.apply_ucompose( m, q, entry, entry_def, terms, vchildren, a, depth+1 );\r
-        }\r
-      }\r
-      entry[itv->second] = prev_v;\r
-      entry_def[itv->second] = prev_vd;\r
-    }else{\r
-      id = (unsigned)terms[depth];\r
-      Assert( id<32 );\r
-      unsigned fid = 1 << id;\r
-      std::map< unsigned, AbsDef >::iterator it = d_def.find( fid );\r
-      if( it!=d_def.end() ){\r
-        it->second.apply_ucompose( m, q, entry, entry_def, terms, vchildren, a, depth+1 );\r
-      }else{\r
-        d_def[d_default].apply_ucompose( m, q, entry, entry_def, terms, vchildren, a, depth+1 );\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-void AbsDef::construct_var_eq( FirstOrderModelAbs * m, TNode q, unsigned v1, unsigned v2, int curr, int currv, unsigned depth ) {\r
-  if( depth==q[0].getNumChildren() ){\r
-    Assert( currv!=val_none );\r
-    d_value = currv;\r
-  }else{\r
-    TypeNode tn = m->getVariable( q, depth ).getType();\r
-    unsigned dom = m->d_domain[tn];\r
-    int vindex = depth==v1 ? 0 : ( depth==v2 ? 1 : val_none );\r
-    if( vindex==val_none ){\r
-      d_def[dom].construct_var_eq( m, q, v1, v2, curr, currv, depth+1 );\r
-      d_default = dom;\r
-    }else{\r
-      Assert( currv==val_none );\r
-      if( curr==val_none ){\r
-        unsigned numReps = m->d_rep_set.getNumRepresentatives( tn );\r
-        Assert( numReps < 32 );\r
-        for( unsigned i=0; i<numReps; i++ ){\r
-          curr = 1 << i;\r
-          d_def[curr].construct_var_eq( m, q, v1, v2, curr, currv, depth+1 );\r
-        }\r
-        d_default = curr;\r
-      }else{\r
-        d_def[curr].construct_var_eq( m, q, v1, v2, curr, 1, depth+1 );\r
-        dom = dom & ~curr;\r
-        d_def[dom].construct_var_eq( m, q, v1, v2, curr, 0, depth+1 );\r
-        d_default = dom;\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-void AbsDef::construct_var( FirstOrderModelAbs * m, TNode q, unsigned v, int currv, unsigned depth ) {\r
-  if( depth==q[0].getNumChildren() ){\r
-    Assert( currv!=val_none );\r
-    d_value = currv;\r
-  }else{\r
-    TypeNode tn = m->getVariable( q, depth ).getType();\r
-    if( v==depth ){\r
-      unsigned numReps = m->d_rep_set.d_type_reps[tn].size();\r
-      Assert( numReps>0 && numReps < 32 );\r
-      for( unsigned i=0; i<numReps; i++ ){\r
-        d_def[ 1 << i ].construct_var( m, q, v, i, depth+1 );\r
-      }\r
-      d_default = 1 << (numReps - 1);\r
-    }else{\r
-      unsigned dom = m->d_domain[tn];\r
-      d_def[dom].construct_var( m, q, v, currv, depth+1 );\r
-      d_default = dom;\r
-    }\r
-  }\r
-}\r
-\r
-void AbsDef::construct_compose( FirstOrderModelAbs * m, TNode q, TNode n, AbsDef * f,\r
-                                std::map< unsigned, AbsDef * >& children,\r
-                                std::map< unsigned, int >& bchildren, std::map< unsigned, int >& vchildren,\r
-                                std::vector< unsigned >& entry, std::vector< bool >& entry_def ) {\r
-  if( n.getKind()==OR || n.getKind()==AND ){\r
-    // short circuiting\r
-    for( std::map< unsigned, AbsDef * >::iterator it = children.begin(); it != children.end(); ++it ){\r
-      if( ( it->second->d_value==0 && n.getKind()==AND ) ||\r
-          ( it->second->d_value==1 && n.getKind()==OR ) ){\r
-        //std::cout << "Short circuit " << it->second->d_value << " " << entry.size() << "/" << q[0].getNumChildren() << std::endl;\r
-        unsigned count = q[0].getNumChildren() - entry.size();\r
-        for( unsigned i=0; i<count; i++ ){\r
-          entry.push_back( m->d_domain[m->getVariable( q, entry.size() ).getType()] );\r
-          entry_def.push_back( true );\r
-        }\r
-        construct_entry( entry, entry_def, it->second->d_value );\r
-        for( unsigned i=0; i<count; i++ ){\r
-          entry.pop_back();\r
-          entry_def.pop_back();\r
-        }\r
-        return;\r
-      }\r
-    }\r
-  }\r
-  if( entry.size()==q[0].getNumChildren() ){\r
-    if( f ){\r
-      if( Trace.isOn("ambqi-check-debug2") ){\r
-        for( unsigned i=0; i<entry.size(); i++ ){ Trace("ambqi-check-debug2") << "  "; }\r
-        Trace("ambqi-check-debug2") << "Evaluate uninterpreted function entry..." << std::endl;\r
-      }\r
-      //we are composing with an uninterpreted function\r
-      std::vector< int > values;\r
-      values.resize( n.getNumChildren(), val_none );\r
-      for( std::map< unsigned, AbsDef * >::iterator it = children.begin(); it != children.end(); ++it ){\r
-        values[it->first] = it->second->d_value;\r
-      }\r
-      for( std::map< unsigned, int >::iterator it = bchildren.begin(); it != bchildren.end(); ++it ){\r
-        values[it->first] = it->second;\r
-      }\r
-      //look up value(s)\r
-      f->apply_ucompose( m, q, entry, entry_def, values, vchildren, this );\r
-    }else{\r
-      bool incomplete = false;\r
-      //we are composing with an interpreted function\r
-      std::vector< TNode > values;\r
-      values.resize( n.getNumChildren(), TNode::null() );\r
-      for( std::map< unsigned, AbsDef * >::iterator it = children.begin(); it != children.end(); ++it ){\r
-        Trace("ambqi-check-debug2") << "composite : " << it->first << " : " << it->second->d_value;\r
-        if( it->second->d_value>=0 ){\r
-          if( it->second->d_value>=(int)m->d_rep_set.d_type_reps[n[it->first].getType()].size() ){\r
-            std::cout << it->second->d_value << " " << n[it->first] << " " << n[it->first].getType() << " " << m->d_rep_set.d_type_reps[n[it->first].getType()].size() << std::endl;\r
-          }\r
-          Assert( it->second->d_value<(int)m->d_rep_set.d_type_reps[n[it->first].getType()].size() );\r
-          values[it->first] = m->d_rep_set.d_type_reps[n[it->first].getType()][it->second->d_value];\r
-        }else{\r
-          incomplete = true;\r
-        }\r
-        Trace("ambqi-check-debug2") << " ->> " << values[it->first] << std::endl;\r
-      }\r
-      for( std::map< unsigned, int >::iterator it = bchildren.begin(); it != bchildren.end(); ++it ){\r
-        Trace("ambqi-check-debug2") << "   basic :  " << it->first << " : " << it->second;\r
-        if( it->second>=0 ){\r
-          Assert( it->second<(int)m->d_rep_set.d_type_reps[n[it->first].getType()].size() );\r
-          values[it->first] = m->d_rep_set.d_type_reps[n[it->first].getType()][it->second];\r
-        }else{\r
-          incomplete = true;\r
-        }\r
-        Trace("ambqi-check-debug2") << " ->> " << values[it->first] << std::endl;\r
-      }\r
-      Assert( vchildren.empty() );\r
-      if( incomplete ){\r
-        Trace("ajr-temp") << "Construct incomplete entry." << std::endl;\r
-\r
-        //if a child is unknown, we must return unknown\r
-        construct_entry( entry, entry_def, val_unk );\r
-      }else{\r
-        if( Trace.isOn("ambqi-check-debug2") ){\r
-          for( unsigned i=0; i<entry.size(); i++ ){ Trace("ambqi-check-debug2") << "  "; }\r
-          Trace("ambqi-check-debug2") << "Evaluate interpreted function entry ( ";\r
-          for( unsigned i=0; i<values.size(); i++ ){\r
-            Assert( !values[i].isNull() );\r
-            Trace("ambqi-check-debug2") << values[i] << " ";\r
-          }\r
-          Trace("ambqi-check-debug2") << ")..." << std::endl;\r
-        }\r
-        //evaluate\r
-        Node vv = NodeManager::currentNM()->mkNode( n.getKind(), values );\r
-        vv = Rewriter::rewrite( vv );\r
-        int v = m->getRepresentativeId( vv );\r
-        construct_entry( entry, entry_def, v );\r
-      }\r
-    }\r
-  }else{\r
-    //take product of arguments\r
-    TypeNode tn = m->getVariable( q, entry.size() ).getType();\r
-    Assert( m->isValidType( tn ) );\r
-    unsigned def = m->d_domain[tn];\r
-    if( Trace.isOn("ambqi-check-debug2") ){\r
-      for( unsigned i=0; i<entry.size(); i++ ){ Trace("ambqi-check-debug2") << "  "; }\r
-      Trace("ambqi-check-debug2") << "Take product of arguments" << std::endl;\r
-    }\r
-    for( std::map< unsigned, AbsDef * >::iterator it = children.begin(); it != children.end(); ++it ){\r
-      Assert( it->second!=NULL );\r
-      //process each child\r
-      for( std::map< unsigned, AbsDef >::iterator itd = it->second->d_def.begin(); itd != it->second->d_def.end(); ++itd ){\r
-        if( itd->first!=it->second->d_default && ( def & itd->first )!=0 ){\r
-          def &= ~( itd->first );\r
-          //process this value\r
-          std::map< unsigned, AbsDef * > cchildren;\r
-          for( std::map< unsigned, AbsDef * >::iterator it2 = children.begin(); it2 != children.end(); ++it2 ){\r
-            Assert( it2->second!=NULL );\r
-            std::map< unsigned, AbsDef >::iterator itdf = it2->second->d_def.find( itd->first );\r
-            if( itdf!=it2->second->d_def.end() ){\r
-              cchildren[it2->first] = &itdf->second;\r
-            }else{\r
-              Assert( it2->second->getDefault()!=NULL );\r
-              cchildren[it2->first] = it2->second->getDefault();\r
-            }\r
-          }\r
-          if( Trace.isOn("ambqi-check-debug2") ){\r
-            for( unsigned i=0; i<entry.size(); i++ ){ Trace("ambqi-check-debug2") << "  "; }\r
-            Trace("ambqi-check-debug2") << "...process : ";\r
-            debugPrintUInt("ambqi-check-debug2", m->d_rep_set.d_type_reps[tn].size(), itd->first );\r
-            Trace("ambqi-check-debug2") << " " << children.size() << " " << cchildren.size() << std::endl;\r
-          }\r
-          entry.push_back( itd->first );\r
-          entry_def.push_back( def==0 );\r
-          construct_compose( m, q, n, f, cchildren, bchildren, vchildren, entry, entry_def );\r
-          entry_def.pop_back();\r
-          entry.pop_back();\r
-          if( def==0 ){\r
-            break;\r
-          }\r
-        }\r
-      }\r
-      if( def==0 ){\r
-        break;\r
-      }\r
-    }\r
-    if( def!=0 ){\r
-      if( Trace.isOn("ambqi-check-debug2") ){\r
-        for( unsigned i=0; i<entry.size(); i++ ){ Trace("ambqi-check-debug2") << "  "; }\r
-        Trace("ambqi-check-debug2") << "Make default argument" << std::endl;\r
-      }\r
-      std::map< unsigned, AbsDef * > cdchildren;\r
-      for( std::map< unsigned, AbsDef * >::iterator it = children.begin(); it != children.end(); ++it ){\r
-        Assert( it->second->getDefault()!=NULL );\r
-        cdchildren[it->first] = it->second->getDefault();\r
-      }\r
-      if( Trace.isOn("ambqi-check-debug2") ){\r
-        for( unsigned i=0; i<entry.size(); i++ ){ Trace("ambqi-check-debug2") << "  "; }\r
-        Trace("ambqi-check-debug2") << "...process default : ";\r
-        debugPrintUInt("ambqi-check-debug2", m->d_rep_set.getNumRepresentatives( tn ), def );\r
-        Trace("ambqi-check-debug2") << " " << children.size() << " " << cdchildren.size() << std::endl;\r
-      }\r
-      entry.push_back( def );\r
-      entry_def.push_back( true );\r
-      construct_compose( m, q, n, f, cdchildren, bchildren, vchildren, entry, entry_def );\r
-      entry_def.pop_back();\r
-      entry.pop_back();\r
-    }\r
-  }\r
-}\r
-\r
-bool AbsDef::construct( FirstOrderModelAbs * m, TNode q, TNode n, AbsDef * f,\r
-                        std::map< unsigned, AbsDef * >& children,\r
-                        std::map< unsigned, int >& bchildren, std::map< unsigned, int >& vchildren,\r
-                        int varChCount ) {\r
-  if( Trace.isOn("ambqi-check-debug3") ){\r
-    for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-      Trace("ambqi-check-debug3") << i << " : ";\r
-      Trace("ambqi-check-debug3") << ((children.find( i )!=children.end()) ? "X" : ".");\r
-      if( bchildren.find( i )!=bchildren.end() ){\r
-        Trace("ambqi-check-debug3") << bchildren[i];\r
-      }else{\r
-        Trace("ambqi-check-debug3") << ".";\r
-      }\r
-      if( vchildren.find( i )!=vchildren.end() ){\r
-        Trace("ambqi-check-debug3") << vchildren[i];\r
-      }else{\r
-        Trace("ambqi-check-debug3") << ".";\r
-      }\r
-      Trace("ambqi-check-debug3") << std::endl;\r
-    }\r
-    Trace("ambqi-check-debug3") << "varChCount : " << varChCount << std::endl;\r
-  }\r
-  if( varChCount==0 || f ){\r
-    //short-circuit\r
-    if( n.getKind()==AND || n.getKind()==OR ){\r
-      for( std::map< unsigned, int >::iterator it = bchildren.begin(); it !=bchildren.end(); ++it ){\r
-        if( ( it->second==0 && n.getKind()==AND ) ||\r
-            ( it->second==1 && n.getKind()==OR ) ){\r
-          construct_def_entry( m, q, q[0], it->second );\r
-          return true;\r
-        }\r
-      }\r
-    }\r
-    Trace("ambqi-check-debug2") << "Construct compose..." << std::endl;\r
-    std::vector< unsigned > entry;\r
-    std::vector< bool > entry_def;\r
-    if( f && varChCount>0 ){\r
-      AbsDef unorm;\r
-      unorm.construct_compose( m, q, n, f, children, bchildren, vchildren, entry, entry_def );\r
-      //normalize\r
-      std::vector< AbsDef* > defs;\r
-      defs.push_back( &unorm );\r
-      construct_normalize( m, q, defs );\r
-    }else{\r
-      construct_compose( m, q, n, f, children, bchildren, vchildren, entry, entry_def );\r
-    }\r
-    Assert( is_normalized() );\r
-    //if( !is_normalized() ){\r
-    //  std::cout << "NON NORMALIZED DEFINITION" << std::endl;\r
-    //  exit( 10 );\r
-    //}\r
-    return true;\r
-  }else if( varChCount==1 && n.getKind()==EQUAL ){\r
-    Trace("ambqi-check-debug2") << "Expand variable child..." << std::endl;\r
-    //expand the variable based on its finite domain\r
-    AbsDef a;\r
-    a.construct_var( m, q, vchildren.begin()->second, val_none );\r
-    children[vchildren.begin()->first] = &a;\r
-    vchildren.clear();\r
-    std::vector< unsigned > entry;\r
-    std::vector< bool > entry_def;\r
-    Trace("ambqi-check-debug2") << "Construct compose with variable..." << std::endl;\r
-    construct_compose( m, q, n, f, children, bchildren, vchildren, entry, entry_def );\r
-    return true;\r
-  }else if( varChCount==2 && n.getKind()==EQUAL ){\r
-    Trace("ambqi-check-debug2") << "Construct variable equality..." << std::endl;\r
-    //efficient expansion of the equality\r
-    construct_var_eq( m, q, vchildren[0], vchildren[1], val_none, val_none );\r
-    return true;\r
-  }else{\r
-    return false;\r
-  }\r
-}\r
-\r
-void AbsDef::negate() {\r
-  for( std::map< unsigned, AbsDef >::iterator it = d_def.begin(); it != d_def.end(); ++it ){\r
-    it->second.negate();\r
-  }\r
-  if( d_value==0 ){\r
-    d_value = 1;\r
-  }else if( d_value==1 ){\r
-    d_value = 0;\r
-  }\r
-}\r
-\r
-Node AbsDef::getFunctionValue( FirstOrderModelAbs * m, TNode op, std::vector< Node >& vars, unsigned depth ) {\r
-  if( depth==vars.size() ){\r
-    TypeNode tn = op.getType();\r
-    if( tn.getNumChildren()>0 ){\r
-      tn = tn[tn.getNumChildren() - 1];\r
-    }\r
-    if( d_value>=0 ){\r
-      Assert( d_value<(int)m->d_rep_set.d_type_reps[tn].size() );\r
-      if( tn.isBoolean() ){\r
-        return NodeManager::currentNM()->mkConst( d_value==1 );\r
-      }else{\r
-        return m->d_rep_set.d_type_reps[tn][d_value];\r
-      }\r
-    }else{\r
-      return Node::null();\r
-    }\r
-  }else{\r
-    TypeNode tn = vars[depth].getType();\r
-    Node curr;\r
-    curr = d_def[d_default].getFunctionValue( m, op, vars, depth+1 );\r
-    for( std::map< unsigned, AbsDef >::iterator it = d_def.begin(); it != d_def.end(); ++it ){\r
-      if( it->first!=d_default ){\r
-        unsigned id = getId( it->first );\r
-        Assert( id<m->d_rep_set.d_type_reps[tn].size() );\r
-        TNode n = m->d_rep_set.d_type_reps[tn][id];\r
-        Node fv = it->second.getFunctionValue( m, op, vars, depth+1 );\r
-        if( !curr.isNull() && !fv.isNull() ){\r
-          curr = NodeManager::currentNM()->mkNode( ITE, vars[depth].eqNode( n ), fv, curr );\r
-        }else{\r
-          curr = Node::null();\r
-        }\r
-      }\r
-    }\r
-    return curr;\r
-  }\r
-}\r
-\r
-bool AbsDef::isSimple( unsigned n ) {\r
-  return (n & (n - 1))==0;\r
-}\r
-\r
-unsigned AbsDef::getId( unsigned n, unsigned start, unsigned end ) {\r
-  Assert( n!=0 );\r
-  while( (n & ( 1 << start )) == 0 ){\r
-    start++;\r
-    if( start==end ){\r
-      return start;\r
-    }\r
-  }\r
-  return start;\r
-}\r
-\r
-Node AbsDef::evaluate( FirstOrderModelAbs * m, TypeNode retTyp, std::vector< Node >& args ) {\r
-  std::vector< unsigned > iargs;\r
-  for( unsigned i=0; i<args.size(); i++ ){\r
-    unsigned v = 1 << m->getRepresentativeId( args[i] );\r
-    iargs.push_back( v );\r
-  }\r
-  return evaluate( m, retTyp, iargs, 0 );\r
-}\r
-\r
-Node AbsDef::evaluate( FirstOrderModelAbs * m, TypeNode retTyp, std::vector< unsigned >& iargs, unsigned depth ) {\r
-  if( d_value!=val_none ){\r
-    if( d_value==val_unk ){\r
-      return Node::null();\r
-    }else{\r
-      Assert( d_value>=0 && d_value<(int)m->d_rep_set.d_type_reps[retTyp].size() );\r
-      return m->d_rep_set.d_type_reps[retTyp][d_value];\r
-    }\r
-  }else{\r
-    std::map< unsigned, AbsDef >::iterator it = d_def.find( iargs[depth] );\r
-    if( it==d_def.end() ){\r
-      return d_def[d_default].evaluate( m, retTyp, iargs, depth+1 );\r
-    }else{\r
-      return it->second.evaluate( m, retTyp, iargs, depth+1 );\r
-    }\r
-  }\r
-}\r
-\r
-bool AbsDef::is_normalized() {\r
-  for( std::map< unsigned, AbsDef >::iterator it1 = d_def.begin(); it1 != d_def.end(); ++it1 ){\r
-    if( !it1->second.is_normalized() ){\r
-      return false;\r
-    }\r
-    for( std::map< unsigned, AbsDef >::iterator it2 = d_def.begin(); it2 != d_def.end(); ++it2 ){\r
-      if( it1->first!=it2->first && (( it1->first & it2->first )!=0) ){\r
-        return false;\r
-      }\r
-    }\r
-  }\r
-  return true;\r
-}\r
-\r
-AbsMbqiBuilder::AbsMbqiBuilder( context::Context* c, QuantifiersEngine* qe ) :\r
-QModelBuilder( c, qe ){\r
-  d_true = NodeManager::currentNM()->mkConst( true );\r
-  d_false = NodeManager::currentNM()->mkConst( false );\r
-}\r
-\r
-\r
-//------------------------model construction----------------------------\r
-\r
-void AbsMbqiBuilder::processBuildModel(TheoryModel* m, bool fullModel) {\r
-  Trace("ambqi-debug") << "process build model " << fullModel << std::endl;\r
-  FirstOrderModel* f = (FirstOrderModel*)m;\r
-  FirstOrderModelAbs* fm = f->asFirstOrderModelAbs();\r
-  if( fullModel ){\r
-    Trace("ambqi-model") << "Construct model representation..." << std::endl;\r
-    //make function values\r
-    for( std::map<Node, AbsDef * >::iterator it = fm->d_models.begin(); it != fm->d_models.end(); ++it ) {\r
-      if( it->first.getType().getNumChildren()>1 ){\r
-        Trace("ambqi-model") << "Construct for " << it->first << "..." << std::endl;\r
-        m->d_uf_models[ it->first ] = fm->getFunctionValue( it->first, "$x" );\r
-      }\r
-    }\r
-    TheoryEngineModelBuilder::processBuildModel( m, fullModel );\r
-    //mark that the model has been set\r
-    fm->markModelSet();\r
-    //debug the model\r
-    debugModel( fm );\r
-  }else{\r
-    fm->initialize( d_considerAxioms );\r
-    //process representatives\r
-    fm->d_rep_id.clear();\r
-    fm->d_domain.clear();\r
-\r
-    //initialize boolean sort\r
-    TypeNode b = d_true.getType();\r
-    fm->d_rep_set.d_type_reps[b].clear();\r
-    fm->d_rep_set.d_type_reps[b].push_back( d_false );\r
-    fm->d_rep_set.d_type_reps[b].push_back( d_true );\r
-    fm->d_rep_id[d_false] = 0;\r
-    fm->d_rep_id[d_true] = 1;\r
-\r
-    //initialize unintpreted sorts\r
-    Trace("ambqi-model") << std::endl << "Making representatives..." << std::endl;\r
-    for( std::map< TypeNode, std::vector< Node > >::iterator it = fm->d_rep_set.d_type_reps.begin();\r
-         it != fm->d_rep_set.d_type_reps.end(); ++it ){\r
-      if( it->first.isSort() ){\r
-        Assert( !it->second.empty() );\r
-        //set the domain\r
-        fm->d_domain[it->first] = 0;\r
-        Trace("ambqi-model") << "Representatives for " << it->first << " : " << std::endl;\r
-        for( unsigned i=0; i<it->second.size(); i++ ){\r
-          if( i<32 ){\r
-            fm->d_domain[it->first] |= ( 1 << i );\r
-          }\r
-          Trace("ambqi-model") << i << " : " << it->second[i] << std::endl;\r
-          fm->d_rep_id[it->second[i]] = i;\r
-        }\r
-        if( it->second.size()>=32 ){\r
-          fm->d_domain.erase( it->first );\r
-        }\r
-      }\r
-    }\r
-\r
-    Trace("ambqi-model") << std::endl << "Making function definitions..." << std::endl;\r
-    //construct the models for functions\r
-    for( std::map<Node, AbsDef * >::iterator it = fm->d_models.begin(); it != fm->d_models.end(); ++it ) {\r
-      Node f = it->first;\r
-      Trace("ambqi-model-debug") << "Building Model for " << f << std::endl;\r
-      //reset the model\r
-      it->second->clear();\r
-      //get all (non-redundant) f-applications\r
-      std::vector< TNode > fapps;\r
-      Trace("ambqi-model-debug") << "Initial terms: " << std::endl;\r
-      for( size_t i=0; i<fm->d_uf_terms[f].size(); i++ ){\r
-        Node n = fm->d_uf_terms[f][i];\r
-        if( !n.getAttribute(NoMatchAttribute()) ){\r
-          Trace("ambqi-model-debug") << "  " << n << " -> " << fm->getRepresentativeId( n ) << std::endl;\r
-          fapps.push_back( n );\r
-        }\r
-      }\r
-      if( fapps.empty() ){\r
-        //choose arbitrary value\r
-        Node mbt = d_qe->getTermDatabase()->getModelBasisOpTerm(f);\r
-        Trace("ambqi-model-debug") << "Initial terms empty, add " << mbt << std::endl;\r
-        fapps.push_back( mbt );\r
-      }\r
-      bool fValid = true;\r
-      for( unsigned i=0; i<fapps[0].getNumChildren(); i++ ){\r
-        if( fm->d_domain.find( fapps[0][i].getType() )==fm->d_domain.end() ){\r
-          Trace("ambqi-model") << "Interpretation of " << f << " is not valid.";\r
-          Trace("ambqi-model") << " (domain for " << fapps[0][i].getType() << " is too large)." << std::endl;\r
-          fValid = false;\r
-          break;\r
-        }\r
-      }\r
-      fm->d_models_valid[f] = fValid;\r
-      if( fValid ){\r
-        //construct the ambqi model\r
-        it->second->construct_func( fm, fapps );\r
-        Trace("ambqi-model-debug") << "Interpretation of " << f << " : " << std::endl;\r
-        it->second->debugPrint("ambqi-model-debug", fm, fapps[0] );\r
-        Trace("ambqi-model-debug") << "Simplifying " << f << "..." << std::endl;\r
-        it->second->simplify( fm, TNode::null(), fapps[0] );\r
-        Trace("ambqi-model") << "(Simplified) interpretation of " << f << " : " << std::endl;\r
-        it->second->debugPrint("ambqi-model", fm, fapps[0] );\r
-\r
-/*\r
-        if( Debug.isOn("ambqi-model-debug") ){\r
-          for( size_t i=0; i<fm->d_uf_terms[f].size(); i++ ){\r
-            Node e = it->second->evaluate_n( fm, fm->d_uf_terms[f][i] );\r
-            Debug("ambqi-model-debug") << fm->d_uf_terms[f][i] << " evaluates to " << e << std::endl;\r
-            Assert( fm->areEqual( e, fm->d_uf_terms[f][i] ) );\r
-          }\r
-        }\r
-*/\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-\r
-//--------------------model checking---------------------------------------\r
-\r
-//do exhaustive instantiation\r
-bool AbsMbqiBuilder::doExhaustiveInstantiation( FirstOrderModel * fm, Node q, int effort ) {\r
-  Trace("ambqi-check") << "Exhaustive instantiation " << q << " " << effort << std::endl;\r
-  if (effort==0) {\r
-    FirstOrderModelAbs * fma = fm->asFirstOrderModelAbs();\r
-    bool quantValid = true;\r
-    for( unsigned i=0; i<q[0].getNumChildren(); i++ ){\r
-      if( !fma->isValidType( q[0][i].getType() ) ){\r
-        quantValid = false;\r
-        Trace("ambqi-inst") << "Interpretation of " << q << " is not valid because of type " << q[0][i].getType() << std::endl;\r
-        break;\r
-      }\r
-    }\r
-    if( quantValid ){\r
-      Trace("ambqi-check") << "Compute interpretation..." << std::endl;\r
-      AbsDef ad;\r
-      doCheck( fma, q, ad, q[1] );\r
-      //now process entries\r
-      Trace("ambqi-inst-debug") << "...Current : " << d_addedLemmas << std::endl;\r
-      Trace("ambqi-inst") << "Interpretation of " << q << " is : " << std::endl;\r
-      ad.debugPrint( "ambqi-inst", fma, q[0] );\r
-      Trace("ambqi-inst") << std::endl;\r
-      Trace("ambqi-check") << "Add instantiations..." << std::endl;\r
-      int lem = 0;\r
-      quantValid = ad.addInstantiations( fma, d_qe, q, lem );\r
-      Trace("ambqi-inst") << "...Added " << lem << " lemmas." << std::endl;\r
-      if( lem>0 ){\r
-        //if we were incomplete but added at least one lemma, we are ok\r
-        quantValid = true;\r
-      }\r
-      d_addedLemmas += lem;\r
-      Trace("ambqi-inst-debug") << "...Total : " << d_addedLemmas << std::endl;\r
-    }\r
-    return quantValid;\r
-  }\r
-  return true;\r
-}\r
-\r
-bool AbsMbqiBuilder::doCheck( FirstOrderModelAbs * m, TNode q, AbsDef & ad, TNode n ) {\r
-  Assert( n.getKind()!=FORALL );\r
-  if( n.getKind()==NOT && n[0].getKind()!=FORALL ){\r
-    doCheck( m, q, ad, n[0] );\r
-    ad.negate();\r
-    return true;\r
-  }else{\r
-    std::map< unsigned, AbsDef > children;\r
-    std::map< unsigned, int > bchildren;\r
-    std::map< unsigned, int > vchildren;\r
-    int varChCount = 0;\r
-    for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-      if( n[i].getKind()==FORALL ){\r
-        bchildren[i] = AbsDef::val_unk;\r
-      }else if( n[i].getKind() == BOUND_VARIABLE ){\r
-        varChCount++;\r
-        vchildren[i] = m->d_var_index[q][ m->getVariableId( q, n[i] ) ];\r
-        //vchildren[i] = m->getVariableId( q, n[i] );\r
-      }else if( m->hasTerm( n[i] ) ){\r
-        bchildren[i] = m->getRepresentativeId( n[i] );\r
-      }else{\r
-        if( !doCheck( m, q, children[i], n[i] ) ){\r
-          bchildren[i] = AbsDef::val_unk;\r
-          children.erase( i );\r
-        }\r
-      }\r
-    }\r
-    //convert to pointers\r
-    std::map< unsigned, AbsDef * > pchildren;\r
-    for( std::map< unsigned, AbsDef >::iterator it = children.begin(); it != children.end(); ++it ){\r
-      pchildren[it->first] = &it->second;\r
-    }\r
-    //construct the interpretation\r
-    Trace("ambqi-check-debug") << "Compute Interpretation of " << n << " " << n.getKind() << std::endl;\r
-    if( n.getKind() == APPLY_UF || n.getKind() == VARIABLE || n.getKind() == SKOLEM ){\r
-      Node op;\r
-      if( n.getKind() == APPLY_UF ){\r
-        op = n.getOperator();\r
-      }else{\r
-        op = n;\r
-      }\r
-      //uninterpreted compose\r
-      if( m->d_models_valid[op] ){\r
-        ad.construct( m, q, n, m->d_models[op], pchildren, bchildren, vchildren, varChCount );\r
-      }else{\r
-        Trace("ambqi-check-debug") << "** Cannot produce interpretation for " << n << " (no function model)" << std::endl;\r
-        return false;\r
-      }\r
-    }else if( !ad.construct( m, q, n, NULL, pchildren, bchildren, vchildren, varChCount ) ){\r
-      Trace("ambqi-check-debug") << "** Cannot produce interpretation for " << n << " (variables are children of interpreted symbol)" << std::endl;\r
-      return false;\r
-    }\r
-    Trace("ambqi-check-try") << "Interpretation for " << n << " is : " << std::endl;\r
-    ad.debugPrint("ambqi-check-try", m, q[0] );\r
-    ad.simplify( m, q, q[0] );\r
-    Trace("ambqi-check-debug") << "(Simplified) Interpretation for " << n << " is : " << std::endl;\r
-    ad.debugPrint("ambqi-check-debug", m, q[0] );\r
-    Trace("ambqi-check-debug") << std::endl;\r
-    return true;\r
-  }\r
-}\r
+/*********************                                                        */
+/*! \file ambqi_builder.cpp
+ ** \verbatim
+ ** Original author: Andrew Reynolds
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2013  New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Implementation of abstract MBQI builder
+ **/
+
+
+#include "theory/quantifiers/ambqi_builder.h"
+#include "theory/quantifiers/term_database.h"
+#include "theory/quantifiers/options.h"
+
+using namespace std;
+using namespace CVC4;
+using namespace CVC4::kind;
+using namespace CVC4::context;
+using namespace CVC4::theory;
+using namespace CVC4::theory::quantifiers;
+
+void AbsDef::construct_func( FirstOrderModelAbs * m, std::vector< TNode >& fapps, unsigned depth ) {
+  d_def.clear();
+  Assert( !fapps.empty() );
+  if( depth==fapps[0].getNumChildren() ){
+    //if( fapps.size()>1 ){
+    //  for( unsigned i=0; i<fapps.size(); i++ ){
+    //    std::cout << "...." << fapps[i] << " -> " << m->getRepresentativeId( fapps[i] ) << std::endl;
+    //  }
+    //}
+    //get representative in model for this term
+    d_value = m->getRepresentativeId( fapps[0] );
+    Assert( d_value!=val_none );
+  }else{
+    TypeNode tn = fapps[0][depth].getType();
+    std::map< unsigned, std::vector< TNode > > fapp_child;
+
+    //partition based on evaluations of fapps[1][depth]....fapps[n][depth]
+    for( unsigned i=0; i<fapps.size(); i++ ){
+      unsigned r = m->getRepresentativeId( fapps[i][depth] );
+      Assert( r < 32 );
+      fapp_child[r].push_back( fapps[i] );
+    }
+
+    //do completion
+    std::map< unsigned, unsigned > fapp_child_index;
+    unsigned def = m->d_domain[ tn ];
+    unsigned minSize = fapp_child.begin()->second.size();
+    unsigned minSizeIndex = fapp_child.begin()->first;
+    for( std::map< unsigned, std::vector< TNode > >::iterator it = fapp_child.begin(); it != fapp_child.end(); ++it ){
+      fapp_child_index[it->first] = ( 1 << it->first );
+      def = def & ~( 1 << it->first );
+      if( it->second.size()<minSize ){
+        minSize = it->second.size();
+        minSizeIndex = it->first;
+      }
+    }
+    fapp_child_index[minSizeIndex] |= def;
+    d_default = fapp_child_index[minSizeIndex];
+
+    //construct children
+    for( std::map< unsigned, std::vector< TNode > >::iterator it = fapp_child.begin(); it != fapp_child.end(); ++it ){
+      Trace("abs-model-debug") << "Construct " << it->first << " : " << fapp_child_index[it->first] << " : ";
+      debugPrintUInt( "abs-model-debug", m->d_rep_set.d_type_reps[tn].size(), fapp_child_index[it->first] );
+      Trace("abs-model-debug") << " : " << it->second.size() << " terms." << std::endl;
+      d_def[fapp_child_index[it->first]].construct_func( m, it->second, depth+1 );
+    }
+  }
+}
+
+void AbsDef::simplify( FirstOrderModelAbs * m, TNode q, TNode n, unsigned depth ) {
+  if( d_value==val_none && !d_def.empty() ){
+    //process the default
+    std::map< unsigned, AbsDef >::iterator defd = d_def.find( d_default );
+    Assert( defd!=d_def.end() );
+    unsigned newDef = d_default;
+    std::vector< unsigned > to_erase;
+    defd->second.simplify( m, q, n, depth+1 );
+    int defVal = defd->second.d_value;
+    bool isConstant = ( defVal!=val_none );
+    //process each child
+    for( std::map< unsigned, AbsDef >::iterator it = d_def.begin(); it != d_def.end(); ++it ){
+      if( it->first!=d_default ){
+        it->second.simplify( m, q, n, depth+1 );
+        if( it->second.d_value==defVal && it->second.d_value!=val_none ){
+          newDef = newDef | it->first;
+          to_erase.push_back( it->first );
+        }else{
+          isConstant = false;
+        }
+      }
+    }
+    if( !to_erase.empty() ){
+      //erase old default
+      int defVal = defd->second.d_value;
+      d_def.erase( d_default );
+      //set new default
+      d_default = newDef;
+      d_def[d_default].construct_def_entry( m, q, n, defVal, depth+1 );
+      //erase redundant entries
+      for( unsigned i=0; i<to_erase.size(); i++ ){
+        d_def.erase( to_erase[i] );
+      }
+    }
+    //if constant, propagate the value upwards
+    if( isConstant ){
+      d_value = defVal;
+    }else{
+      d_value = val_none;
+    }
+  }
+}
+
+void AbsDef::debugPrintUInt( const char * c, unsigned dSize, unsigned u ) const{
+  for( unsigned i=0; i<dSize; i++ ){
+    Trace(c) << ( ( u & ( 1 << i ) )!=0 ? "1" : "0");
+  }
+  //Trace(c) << "(";
+  //for( unsigned i=0; i<32; i++ ){
+  //  Trace(c) << ( ( u & ( 1 << i ) )!=0 ? "1" : "0");
+  //}
+  //Trace(c) << ")";
+}
+
+void AbsDef::debugPrint( const char * c, FirstOrderModelAbs * m, TNode f, unsigned depth ) const{
+  if( Trace.isOn(c) ){
+    if( depth==f.getNumChildren() ){
+      for( unsigned i=0; i<depth; i++ ){ Trace(c) << "  ";}
+      Trace(c) << "V[" << d_value << "]" << std::endl;
+    }else{
+      TypeNode tn = f[depth].getType();
+      unsigned dSize = m->d_rep_set.getNumRepresentatives( tn );
+      Assert( dSize<32 );
+      for( std::map< unsigned, AbsDef >::const_iterator it = d_def.begin(); it != d_def.end(); ++it ){
+        for( unsigned i=0; i<depth; i++ ){ Trace(c) << "  ";}
+        debugPrintUInt( c, dSize, it->first );
+        if( it->first==d_default ){
+          Trace(c) << "*";
+        }
+        if( it->second.d_value!=val_none ){
+          Trace(c) << " -> V[" << it->second.d_value << "]";
+        }
+        Trace(c) << std::endl;
+        it->second.debugPrint( c, m, f, depth+1 );
+      }
+    }
+  }
+}
+
+bool AbsDef::addInstantiations( FirstOrderModelAbs * m, QuantifiersEngine * qe, TNode q, std::vector< Node >& terms, int& inst, unsigned depth ) {
+  if( inst==0 || !options::fmfOneInstPerRound() ){
+    if( d_value==1 ){
+      //instantiations are all true : ignore this
+      return true;
+    }else{
+      if( depth==q[0].getNumChildren() ){
+        if( qe->addInstantiation( q, terms ) ){
+          Trace("ambqi-inst-debug") << "-> Added instantiation." << std::endl;
+          inst++;
+          return true;
+        }else{
+          Trace("ambqi-inst-debug") << "-> Failed to add instantiation." << std::endl;
+          //we are incomplete
+          return false;
+        }
+      }else{
+        bool osuccess = true;
+        TypeNode tn = m->getVariable( q, depth ).getType();
+        for( std::map< unsigned, AbsDef >::iterator it = d_def.begin(); it != d_def.end(); ++it ){
+          //get witness term
+          unsigned index = 0;
+          bool success;
+          do {
+            success = false;
+            index = getId( it->first, index );
+            if( index<32 ){
+              Assert( index<m->d_rep_set.d_type_reps[tn].size() );
+              terms[m->d_var_order[q][depth]] = m->d_rep_set.d_type_reps[tn][index];
+              //terms[depth] = m->d_rep_set.d_type_reps[tn][index];
+              if( !it->second.addInstantiations( m, qe, q, terms, inst, depth+1 ) && inst==0 ){
+                //if we are incomplete, and have not yet added an instantiation, keep trying
+                index++;
+                Trace("ambqi-inst-debug") << "At depth " << depth << ", failed branch, no instantiations and incomplete, increment index : " << index << std::endl;
+              }else{
+                success = true;
+              }
+            }
+          }while( !success && index<32 );
+          //mark if we are incomplete
+          osuccess = osuccess && success;
+        }
+        return osuccess;
+      }
+    }
+  }else{
+    return true;
+  }
+}
+
+void AbsDef::construct_entry( std::vector< unsigned >& entry, std::vector< bool >& entry_def, int v, unsigned depth ) {
+  if( depth==entry.size() ){
+    d_value = v;
+  }else{
+    d_def[entry[depth]].construct_entry( entry, entry_def, v, depth+1 );
+    if( entry_def[depth] ){
+      d_default = entry[depth];
+    }
+  }
+}
+
+void AbsDef::get_defs( unsigned u, std::vector< AbsDef * >& defs ) {
+  for( std::map< unsigned, AbsDef >::iterator it = d_def.begin(); it != d_def.end(); ++it ){
+    if( ( u & it->first )!=0 ){
+      Assert( (u & it->first)==u );
+      defs.push_back( &it->second );
+    }
+  }
+}
+
+void AbsDef::construct_normalize( FirstOrderModelAbs * m, TNode q, std::vector< AbsDef * >& defs, unsigned depth ) {
+  if( depth==q[0].getNumChildren() ){
+    Assert( defs.size()==1 );
+    d_value = defs[0]->d_value;
+  }else{
+    TypeNode tn = m->getVariable( q, depth ).getType();
+    unsigned def = m->d_domain[tn];
+    for( unsigned i=0; i<defs.size(); i++ ){
+      //process each simple child
+      for( std::map< unsigned, AbsDef >::iterator itd = defs[i]->d_def.begin(); itd != defs[i]->d_def.end(); ++itd ){
+        if( isSimple( itd->first ) && ( def & itd->first )!=0 ){
+          def &= ~( itd->first );
+          //process this value
+          std::vector< AbsDef * > cdefs;
+          for( unsigned j=0; j<defs.size(); j++ ){
+            defs[j]->get_defs( itd->first, cdefs );
+          }
+          d_def[itd->first].construct_normalize( m, q, cdefs, depth+1 );
+          if( def==0 ){
+            d_default = itd->first;
+            break;
+          }
+        }
+      }
+      if( def==0 ){
+        break;
+      }
+    }
+    if( def!=0 ){
+      d_default = def;
+      //process the default
+      std::vector< AbsDef * > cdefs;
+      for( unsigned j=0; j<defs.size(); j++ ){
+        defs[j]->get_defs( d_default, cdefs );
+      }
+      d_def[d_default].construct_normalize( m, q, cdefs, depth+1 );
+    }
+  }
+}
+
+void AbsDef::construct_def_entry( FirstOrderModelAbs * m, TNode q, TNode n, int v, unsigned depth ) {
+  d_value = v;
+  if( depth<n.getNumChildren() ){
+    TypeNode tn = q.isNull() ? n[depth].getType() : m->getVariable( q, depth ).getType();
+    unsigned dom = m->d_domain[tn] ;
+    d_def[dom].construct_def_entry( m, q, n, v, depth+1 );
+    d_default = dom;
+  }
+}
+
+void AbsDef::apply_ucompose( FirstOrderModelAbs * m, TNode q,
+                             std::vector< unsigned >& entry, std::vector< bool >& entry_def,
+                             std::vector< int >& terms, std::map< unsigned, int >& vchildren,
+                             AbsDef * a, unsigned depth ) {
+  if( depth==terms.size() ){
+    if( Trace.isOn("ambqi-check-debug2") ){
+      Trace("ambqi-check-debug2") << "Add entry ( ";
+      for( unsigned i=0; i<entry.size(); i++ ){
+        unsigned dSize = m->d_rep_set.d_type_reps[m->getVariable( q, i ).getType()].size();
+        debugPrintUInt( "ambqi-check-debug2", dSize, entry[i] );
+        Trace("ambqi-check-debug2") << " ";
+      }
+      Trace("ambqi-check-debug2") << ")" << std::endl;
+    }
+    a->construct_entry( entry, entry_def, d_value );
+  }else{
+    unsigned id;
+    if( terms[depth]==val_none ){
+      //a variable
+      std::map< unsigned, int >::iterator itv = vchildren.find( depth );
+      Assert( itv!=vchildren.end() );
+      unsigned prev_v = entry[itv->second];
+      bool prev_vd = entry_def[itv->second];
+      for( std::map< unsigned, AbsDef >::iterator it = d_def.begin(); it != d_def.end(); ++it ){
+        entry[itv->second] = it->first & prev_v;
+        entry_def[itv->second] = ( it->first==d_default ) && prev_vd;
+        if( entry[itv->second]!=0 ){
+          it->second.apply_ucompose( m, q, entry, entry_def, terms, vchildren, a, depth+1 );
+        }
+      }
+      entry[itv->second] = prev_v;
+      entry_def[itv->second] = prev_vd;
+    }else{
+      id = (unsigned)terms[depth];
+      Assert( id<32 );
+      unsigned fid = 1 << id;
+      std::map< unsigned, AbsDef >::iterator it = d_def.find( fid );
+      if( it!=d_def.end() ){
+        it->second.apply_ucompose( m, q, entry, entry_def, terms, vchildren, a, depth+1 );
+      }else{
+        d_def[d_default].apply_ucompose( m, q, entry, entry_def, terms, vchildren, a, depth+1 );
+      }
+    }
+  }
+}
+
+void AbsDef::construct_var_eq( FirstOrderModelAbs * m, TNode q, unsigned v1, unsigned v2, int curr, int currv, unsigned depth ) {
+  if( depth==q[0].getNumChildren() ){
+    Assert( currv!=val_none );
+    d_value = currv;
+  }else{
+    TypeNode tn = m->getVariable( q, depth ).getType();
+    unsigned dom = m->d_domain[tn];
+    int vindex = depth==v1 ? 0 : ( depth==v2 ? 1 : val_none );
+    if( vindex==val_none ){
+      d_def[dom].construct_var_eq( m, q, v1, v2, curr, currv, depth+1 );
+      d_default = dom;
+    }else{
+      Assert( currv==val_none );
+      if( curr==val_none ){
+        unsigned numReps = m->d_rep_set.getNumRepresentatives( tn );
+        Assert( numReps < 32 );
+        for( unsigned i=0; i<numReps; i++ ){
+          curr = 1 << i;
+          d_def[curr].construct_var_eq( m, q, v1, v2, curr, currv, depth+1 );
+        }
+        d_default = curr;
+      }else{
+        d_def[curr].construct_var_eq( m, q, v1, v2, curr, 1, depth+1 );
+        dom = dom & ~curr;
+        d_def[dom].construct_var_eq( m, q, v1, v2, curr, 0, depth+1 );
+        d_default = dom;
+      }
+    }
+  }
+}
+
+void AbsDef::construct_var( FirstOrderModelAbs * m, TNode q, unsigned v, int currv, unsigned depth ) {
+  if( depth==q[0].getNumChildren() ){
+    Assert( currv!=val_none );
+    d_value = currv;
+  }else{
+    TypeNode tn = m->getVariable( q, depth ).getType();
+    if( v==depth ){
+      unsigned numReps = m->d_rep_set.d_type_reps[tn].size();
+      Assert( numReps>0 && numReps < 32 );
+      for( unsigned i=0; i<numReps; i++ ){
+        d_def[ 1 << i ].construct_var( m, q, v, i, depth+1 );
+      }
+      d_default = 1 << (numReps - 1);
+    }else{
+      unsigned dom = m->d_domain[tn];
+      d_def[dom].construct_var( m, q, v, currv, depth+1 );
+      d_default = dom;
+    }
+  }
+}
+
+void AbsDef::construct_compose( FirstOrderModelAbs * m, TNode q, TNode n, AbsDef * f,
+                                std::map< unsigned, AbsDef * >& children,
+                                std::map< unsigned, int >& bchildren, std::map< unsigned, int >& vchildren,
+                                std::vector< unsigned >& entry, std::vector< bool >& entry_def ) {
+  if( n.getKind()==OR || n.getKind()==AND ){
+    // short circuiting
+    for( std::map< unsigned, AbsDef * >::iterator it = children.begin(); it != children.end(); ++it ){
+      if( ( it->second->d_value==0 && n.getKind()==AND ) ||
+          ( it->second->d_value==1 && n.getKind()==OR ) ){
+        //std::cout << "Short circuit " << it->second->d_value << " " << entry.size() << "/" << q[0].getNumChildren() << std::endl;
+        unsigned count = q[0].getNumChildren() - entry.size();
+        for( unsigned i=0; i<count; i++ ){
+          entry.push_back( m->d_domain[m->getVariable( q, entry.size() ).getType()] );
+          entry_def.push_back( true );
+        }
+        construct_entry( entry, entry_def, it->second->d_value );
+        for( unsigned i=0; i<count; i++ ){
+          entry.pop_back();
+          entry_def.pop_back();
+        }
+        return;
+      }
+    }
+  }
+  if( entry.size()==q[0].getNumChildren() ){
+    if( f ){
+      if( Trace.isOn("ambqi-check-debug2") ){
+        for( unsigned i=0; i<entry.size(); i++ ){ Trace("ambqi-check-debug2") << "  "; }
+        Trace("ambqi-check-debug2") << "Evaluate uninterpreted function entry..." << std::endl;
+      }
+      //we are composing with an uninterpreted function
+      std::vector< int > values;
+      values.resize( n.getNumChildren(), val_none );
+      for( std::map< unsigned, AbsDef * >::iterator it = children.begin(); it != children.end(); ++it ){
+        values[it->first] = it->second->d_value;
+      }
+      for( std::map< unsigned, int >::iterator it = bchildren.begin(); it != bchildren.end(); ++it ){
+        values[it->first] = it->second;
+      }
+      //look up value(s)
+      f->apply_ucompose( m, q, entry, entry_def, values, vchildren, this );
+    }else{
+      bool incomplete = false;
+      //we are composing with an interpreted function
+      std::vector< TNode > values;
+      values.resize( n.getNumChildren(), TNode::null() );
+      for( std::map< unsigned, AbsDef * >::iterator it = children.begin(); it != children.end(); ++it ){
+        Trace("ambqi-check-debug2") << "composite : " << it->first << " : " << it->second->d_value;
+        if( it->second->d_value>=0 ){
+          if( it->second->d_value>=(int)m->d_rep_set.d_type_reps[n[it->first].getType()].size() ){
+            std::cout << it->second->d_value << " " << n[it->first] << " " << n[it->first].getType() << " " << m->d_rep_set.d_type_reps[n[it->first].getType()].size() << std::endl;
+          }
+          Assert( it->second->d_value<(int)m->d_rep_set.d_type_reps[n[it->first].getType()].size() );
+          values[it->first] = m->d_rep_set.d_type_reps[n[it->first].getType()][it->second->d_value];
+        }else{
+          incomplete = true;
+        }
+        Trace("ambqi-check-debug2") << " ->> " << values[it->first] << std::endl;
+      }
+      for( std::map< unsigned, int >::iterator it = bchildren.begin(); it != bchildren.end(); ++it ){
+        Trace("ambqi-check-debug2") << "   basic :  " << it->first << " : " << it->second;
+        if( it->second>=0 ){
+          Assert( it->second<(int)m->d_rep_set.d_type_reps[n[it->first].getType()].size() );
+          values[it->first] = m->d_rep_set.d_type_reps[n[it->first].getType()][it->second];
+        }else{
+          incomplete = true;
+        }
+        Trace("ambqi-check-debug2") << " ->> " << values[it->first] << std::endl;
+      }
+      Assert( vchildren.empty() );
+      if( incomplete ){
+        Trace("ajr-temp") << "Construct incomplete entry." << std::endl;
+
+        //if a child is unknown, we must return unknown
+        construct_entry( entry, entry_def, val_unk );
+      }else{
+        if( Trace.isOn("ambqi-check-debug2") ){
+          for( unsigned i=0; i<entry.size(); i++ ){ Trace("ambqi-check-debug2") << "  "; }
+          Trace("ambqi-check-debug2") << "Evaluate interpreted function entry ( ";
+          for( unsigned i=0; i<values.size(); i++ ){
+            Assert( !values[i].isNull() );
+            Trace("ambqi-check-debug2") << values[i] << " ";
+          }
+          Trace("ambqi-check-debug2") << ")..." << std::endl;
+        }
+        //evaluate
+        Node vv = NodeManager::currentNM()->mkNode( n.getKind(), values );
+        vv = Rewriter::rewrite( vv );
+        int v = m->getRepresentativeId( vv );
+        construct_entry( entry, entry_def, v );
+      }
+    }
+  }else{
+    //take product of arguments
+    TypeNode tn = m->getVariable( q, entry.size() ).getType();
+    Assert( m->isValidType( tn ) );
+    unsigned def = m->d_domain[tn];
+    if( Trace.isOn("ambqi-check-debug2") ){
+      for( unsigned i=0; i<entry.size(); i++ ){ Trace("ambqi-check-debug2") << "  "; }
+      Trace("ambqi-check-debug2") << "Take product of arguments" << std::endl;
+    }
+    for( std::map< unsigned, AbsDef * >::iterator it = children.begin(); it != children.end(); ++it ){
+      Assert( it->second!=NULL );
+      //process each child
+      for( std::map< unsigned, AbsDef >::iterator itd = it->second->d_def.begin(); itd != it->second->d_def.end(); ++itd ){
+        if( itd->first!=it->second->d_default && ( def & itd->first )!=0 ){
+          def &= ~( itd->first );
+          //process this value
+          std::map< unsigned, AbsDef * > cchildren;
+          for( std::map< unsigned, AbsDef * >::iterator it2 = children.begin(); it2 != children.end(); ++it2 ){
+            Assert( it2->second!=NULL );
+            std::map< unsigned, AbsDef >::iterator itdf = it2->second->d_def.find( itd->first );
+            if( itdf!=it2->second->d_def.end() ){
+              cchildren[it2->first] = &itdf->second;
+            }else{
+              Assert( it2->second->getDefault()!=NULL );
+              cchildren[it2->first] = it2->second->getDefault();
+            }
+          }
+          if( Trace.isOn("ambqi-check-debug2") ){
+            for( unsigned i=0; i<entry.size(); i++ ){ Trace("ambqi-check-debug2") << "  "; }
+            Trace("ambqi-check-debug2") << "...process : ";
+            debugPrintUInt("ambqi-check-debug2", m->d_rep_set.d_type_reps[tn].size(), itd->first );
+            Trace("ambqi-check-debug2") << " " << children.size() << " " << cchildren.size() << std::endl;
+          }
+          entry.push_back( itd->first );
+          entry_def.push_back( def==0 );
+          construct_compose( m, q, n, f, cchildren, bchildren, vchildren, entry, entry_def );
+          entry_def.pop_back();
+          entry.pop_back();
+          if( def==0 ){
+            break;
+          }
+        }
+      }
+      if( def==0 ){
+        break;
+      }
+    }
+    if( def!=0 ){
+      if( Trace.isOn("ambqi-check-debug2") ){
+        for( unsigned i=0; i<entry.size(); i++ ){ Trace("ambqi-check-debug2") << "  "; }
+        Trace("ambqi-check-debug2") << "Make default argument" << std::endl;
+      }
+      std::map< unsigned, AbsDef * > cdchildren;
+      for( std::map< unsigned, AbsDef * >::iterator it = children.begin(); it != children.end(); ++it ){
+        Assert( it->second->getDefault()!=NULL );
+        cdchildren[it->first] = it->second->getDefault();
+      }
+      if( Trace.isOn("ambqi-check-debug2") ){
+        for( unsigned i=0; i<entry.size(); i++ ){ Trace("ambqi-check-debug2") << "  "; }
+        Trace("ambqi-check-debug2") << "...process default : ";
+        debugPrintUInt("ambqi-check-debug2", m->d_rep_set.getNumRepresentatives( tn ), def );
+        Trace("ambqi-check-debug2") << " " << children.size() << " " << cdchildren.size() << std::endl;
+      }
+      entry.push_back( def );
+      entry_def.push_back( true );
+      construct_compose( m, q, n, f, cdchildren, bchildren, vchildren, entry, entry_def );
+      entry_def.pop_back();
+      entry.pop_back();
+    }
+  }
+}
+
+bool AbsDef::construct( FirstOrderModelAbs * m, TNode q, TNode n, AbsDef * f,
+                        std::map< unsigned, AbsDef * >& children,
+                        std::map< unsigned, int >& bchildren, std::map< unsigned, int >& vchildren,
+                        int varChCount ) {
+  if( Trace.isOn("ambqi-check-debug3") ){
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){
+      Trace("ambqi-check-debug3") << i << " : ";
+      Trace("ambqi-check-debug3") << ((children.find( i )!=children.end()) ? "X" : ".");
+      if( bchildren.find( i )!=bchildren.end() ){
+        Trace("ambqi-check-debug3") << bchildren[i];
+      }else{
+        Trace("ambqi-check-debug3") << ".";
+      }
+      if( vchildren.find( i )!=vchildren.end() ){
+        Trace("ambqi-check-debug3") << vchildren[i];
+      }else{
+        Trace("ambqi-check-debug3") << ".";
+      }
+      Trace("ambqi-check-debug3") << std::endl;
+    }
+    Trace("ambqi-check-debug3") << "varChCount : " << varChCount << std::endl;
+  }
+  if( varChCount==0 || f ){
+    //short-circuit
+    if( n.getKind()==AND || n.getKind()==OR ){
+      for( std::map< unsigned, int >::iterator it = bchildren.begin(); it !=bchildren.end(); ++it ){
+        if( ( it->second==0 && n.getKind()==AND ) ||
+            ( it->second==1 && n.getKind()==OR ) ){
+          construct_def_entry( m, q, q[0], it->second );
+          return true;
+        }
+      }
+    }
+    Trace("ambqi-check-debug2") << "Construct compose..." << std::endl;
+    std::vector< unsigned > entry;
+    std::vector< bool > entry_def;
+    if( f && varChCount>0 ){
+      AbsDef unorm;
+      unorm.construct_compose( m, q, n, f, children, bchildren, vchildren, entry, entry_def );
+      //normalize
+      std::vector< AbsDef* > defs;
+      defs.push_back( &unorm );
+      construct_normalize( m, q, defs );
+    }else{
+      construct_compose( m, q, n, f, children, bchildren, vchildren, entry, entry_def );
+    }
+    Assert( is_normalized() );
+    //if( !is_normalized() ){
+    //  std::cout << "NON NORMALIZED DEFINITION" << std::endl;
+    //  exit( 10 );
+    //}
+    return true;
+  }else if( varChCount==1 && n.getKind()==EQUAL ){
+    Trace("ambqi-check-debug2") << "Expand variable child..." << std::endl;
+    //expand the variable based on its finite domain
+    AbsDef a;
+    a.construct_var( m, q, vchildren.begin()->second, val_none );
+    children[vchildren.begin()->first] = &a;
+    vchildren.clear();
+    std::vector< unsigned > entry;
+    std::vector< bool > entry_def;
+    Trace("ambqi-check-debug2") << "Construct compose with variable..." << std::endl;
+    construct_compose( m, q, n, f, children, bchildren, vchildren, entry, entry_def );
+    return true;
+  }else if( varChCount==2 && n.getKind()==EQUAL ){
+    Trace("ambqi-check-debug2") << "Construct variable equality..." << std::endl;
+    //efficient expansion of the equality
+    construct_var_eq( m, q, vchildren[0], vchildren[1], val_none, val_none );
+    return true;
+  }else{
+    return false;
+  }
+}
+
+void AbsDef::negate() {
+  for( std::map< unsigned, AbsDef >::iterator it = d_def.begin(); it != d_def.end(); ++it ){
+    it->second.negate();
+  }
+  if( d_value==0 ){
+    d_value = 1;
+  }else if( d_value==1 ){
+    d_value = 0;
+  }
+}
+
+Node AbsDef::getFunctionValue( FirstOrderModelAbs * m, TNode op, std::vector< Node >& vars, unsigned depth ) {
+  if( depth==vars.size() ){
+    TypeNode tn = op.getType();
+    if( tn.getNumChildren()>0 ){
+      tn = tn[tn.getNumChildren() - 1];
+    }
+    if( d_value>=0 ){
+      Assert( d_value<(int)m->d_rep_set.d_type_reps[tn].size() );
+      if( tn.isBoolean() ){
+        return NodeManager::currentNM()->mkConst( d_value==1 );
+      }else{
+        return m->d_rep_set.d_type_reps[tn][d_value];
+      }
+    }else{
+      return Node::null();
+    }
+  }else{
+    TypeNode tn = vars[depth].getType();
+    Node curr;
+    curr = d_def[d_default].getFunctionValue( m, op, vars, depth+1 );
+    for( std::map< unsigned, AbsDef >::iterator it = d_def.begin(); it != d_def.end(); ++it ){
+      if( it->first!=d_default ){
+        unsigned id = getId( it->first );
+        Assert( id<m->d_rep_set.d_type_reps[tn].size() );
+        TNode n = m->d_rep_set.d_type_reps[tn][id];
+        Node fv = it->second.getFunctionValue( m, op, vars, depth+1 );
+        if( !curr.isNull() && !fv.isNull() ){
+          curr = NodeManager::currentNM()->mkNode( ITE, vars[depth].eqNode( n ), fv, curr );
+        }else{
+          curr = Node::null();
+        }
+      }
+    }
+    return curr;
+  }
+}
+
+bool AbsDef::isSimple( unsigned n ) {
+  return (n & (n - 1))==0;
+}
+
+unsigned AbsDef::getId( unsigned n, unsigned start, unsigned end ) {
+  Assert( n!=0 );
+  while( (n & ( 1 << start )) == 0 ){
+    start++;
+    if( start==end ){
+      return start;
+    }
+  }
+  return start;
+}
+
+Node AbsDef::evaluate( FirstOrderModelAbs * m, TypeNode retTyp, std::vector< Node >& args ) {
+  std::vector< unsigned > iargs;
+  for( unsigned i=0; i<args.size(); i++ ){
+    unsigned v = 1 << m->getRepresentativeId( args[i] );
+    iargs.push_back( v );
+  }
+  return evaluate( m, retTyp, iargs, 0 );
+}
+
+Node AbsDef::evaluate( FirstOrderModelAbs * m, TypeNode retTyp, std::vector< unsigned >& iargs, unsigned depth ) {
+  if( d_value!=val_none ){
+    if( d_value==val_unk ){
+      return Node::null();
+    }else{
+      Assert( d_value>=0 && d_value<(int)m->d_rep_set.d_type_reps[retTyp].size() );
+      return m->d_rep_set.d_type_reps[retTyp][d_value];
+    }
+  }else{
+    std::map< unsigned, AbsDef >::iterator it = d_def.find( iargs[depth] );
+    if( it==d_def.end() ){
+      return d_def[d_default].evaluate( m, retTyp, iargs, depth+1 );
+    }else{
+      return it->second.evaluate( m, retTyp, iargs, depth+1 );
+    }
+  }
+}
+
+bool AbsDef::is_normalized() {
+  for( std::map< unsigned, AbsDef >::iterator it1 = d_def.begin(); it1 != d_def.end(); ++it1 ){
+    if( !it1->second.is_normalized() ){
+      return false;
+    }
+    for( std::map< unsigned, AbsDef >::iterator it2 = d_def.begin(); it2 != d_def.end(); ++it2 ){
+      if( it1->first!=it2->first && (( it1->first & it2->first )!=0) ){
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+AbsMbqiBuilder::AbsMbqiBuilder( context::Context* c, QuantifiersEngine* qe ) :
+QModelBuilder( c, qe ){
+  d_true = NodeManager::currentNM()->mkConst( true );
+  d_false = NodeManager::currentNM()->mkConst( false );
+}
+
+
+//------------------------model construction----------------------------
+
+void AbsMbqiBuilder::processBuildModel(TheoryModel* m, bool fullModel) {
+  Trace("ambqi-debug") << "process build model " << fullModel << std::endl;
+  FirstOrderModel* f = (FirstOrderModel*)m;
+  FirstOrderModelAbs* fm = f->asFirstOrderModelAbs();
+  if( fullModel ){
+    Trace("ambqi-model") << "Construct model representation..." << std::endl;
+    //make function values
+    for( std::map<Node, AbsDef * >::iterator it = fm->d_models.begin(); it != fm->d_models.end(); ++it ) {
+      if( it->first.getType().getNumChildren()>1 ){
+        Trace("ambqi-model") << "Construct for " << it->first << "..." << std::endl;
+        m->d_uf_models[ it->first ] = fm->getFunctionValue( it->first, "$x" );
+      }
+    }
+    TheoryEngineModelBuilder::processBuildModel( m, fullModel );
+    //mark that the model has been set
+    fm->markModelSet();
+    //debug the model
+    debugModel( fm );
+  }else{
+    fm->initialize( d_considerAxioms );
+    //process representatives
+    fm->d_rep_id.clear();
+    fm->d_domain.clear();
+
+    //initialize boolean sort
+    TypeNode b = d_true.getType();
+    fm->d_rep_set.d_type_reps[b].clear();
+    fm->d_rep_set.d_type_reps[b].push_back( d_false );
+    fm->d_rep_set.d_type_reps[b].push_back( d_true );
+    fm->d_rep_id[d_false] = 0;
+    fm->d_rep_id[d_true] = 1;
+
+    //initialize unintpreted sorts
+    Trace("ambqi-model") << std::endl << "Making representatives..." << std::endl;
+    for( std::map< TypeNode, std::vector< Node > >::iterator it = fm->d_rep_set.d_type_reps.begin();
+         it != fm->d_rep_set.d_type_reps.end(); ++it ){
+      if( it->first.isSort() ){
+        Assert( !it->second.empty() );
+        //set the domain
+        fm->d_domain[it->first] = 0;
+        Trace("ambqi-model") << "Representatives for " << it->first << " : " << std::endl;
+        for( unsigned i=0; i<it->second.size(); i++ ){
+          if( i<32 ){
+            fm->d_domain[it->first] |= ( 1 << i );
+          }
+          Trace("ambqi-model") << i << " : " << it->second[i] << std::endl;
+          fm->d_rep_id[it->second[i]] = i;
+        }
+        if( it->second.size()>=32 ){
+          fm->d_domain.erase( it->first );
+        }
+      }
+    }
+
+    Trace("ambqi-model") << std::endl << "Making function definitions..." << std::endl;
+    //construct the models for functions
+    for( std::map<Node, AbsDef * >::iterator it = fm->d_models.begin(); it != fm->d_models.end(); ++it ) {
+      Node f = it->first;
+      Trace("ambqi-model-debug") << "Building Model for " << f << std::endl;
+      //reset the model
+      it->second->clear();
+      //get all (non-redundant) f-applications
+      std::vector< TNode > fapps;
+      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()) ){
+          Trace("ambqi-model-debug") << "  " << n << " -> " << fm->getRepresentativeId( n ) << std::endl;
+          fapps.push_back( n );
+        }
+      }
+      if( fapps.empty() ){
+        //choose arbitrary value
+        Node mbt = d_qe->getTermDatabase()->getModelBasisOpTerm(f);
+        Trace("ambqi-model-debug") << "Initial terms empty, add " << mbt << std::endl;
+        fapps.push_back( mbt );
+      }
+      bool fValid = true;
+      for( unsigned i=0; i<fapps[0].getNumChildren(); i++ ){
+        if( fm->d_domain.find( fapps[0][i].getType() )==fm->d_domain.end() ){
+          Trace("ambqi-model") << "Interpretation of " << f << " is not valid.";
+          Trace("ambqi-model") << " (domain for " << fapps[0][i].getType() << " is too large)." << std::endl;
+          fValid = false;
+          break;
+        }
+      }
+      fm->d_models_valid[f] = fValid;
+      if( fValid ){
+        //construct the ambqi model
+        it->second->construct_func( fm, fapps );
+        Trace("ambqi-model-debug") << "Interpretation of " << f << " : " << std::endl;
+        it->second->debugPrint("ambqi-model-debug", fm, fapps[0] );
+        Trace("ambqi-model-debug") << "Simplifying " << f << "..." << std::endl;
+        it->second->simplify( fm, TNode::null(), fapps[0] );
+        Trace("ambqi-model") << "(Simplified) interpretation of " << f << " : " << std::endl;
+        it->second->debugPrint("ambqi-model", fm, fapps[0] );
+
+/*
+        if( Debug.isOn("ambqi-model-debug") ){
+          for( size_t i=0; i<fm->d_uf_terms[f].size(); i++ ){
+            Node e = it->second->evaluate_n( fm, fm->d_uf_terms[f][i] );
+            Debug("ambqi-model-debug") << fm->d_uf_terms[f][i] << " evaluates to " << e << std::endl;
+            Assert( fm->areEqual( e, fm->d_uf_terms[f][i] ) );
+          }
+        }
+*/
+      }
+    }
+  }
+}
+
+
+//--------------------model checking---------------------------------------
+
+//do exhaustive instantiation
+bool AbsMbqiBuilder::doExhaustiveInstantiation( FirstOrderModel * fm, Node q, int effort ) {
+  Trace("ambqi-check") << "Exhaustive instantiation " << q << " " << effort << std::endl;
+  if (effort==0) {
+    FirstOrderModelAbs * fma = fm->asFirstOrderModelAbs();
+    bool quantValid = true;
+    for( unsigned i=0; i<q[0].getNumChildren(); i++ ){
+      if( !fma->isValidType( q[0][i].getType() ) ){
+        quantValid = false;
+        Trace("ambqi-inst") << "Interpretation of " << q << " is not valid because of type " << q[0][i].getType() << std::endl;
+        break;
+      }
+    }
+    if( quantValid ){
+      Trace("ambqi-check") << "Compute interpretation..." << std::endl;
+      AbsDef ad;
+      doCheck( fma, q, ad, q[1] );
+      //now process entries
+      Trace("ambqi-inst-debug") << "...Current : " << d_addedLemmas << std::endl;
+      Trace("ambqi-inst") << "Interpretation of " << q << " is : " << std::endl;
+      ad.debugPrint( "ambqi-inst", fma, q[0] );
+      Trace("ambqi-inst") << std::endl;
+      Trace("ambqi-check") << "Add instantiations..." << std::endl;
+      int lem = 0;
+      quantValid = ad.addInstantiations( fma, d_qe, q, lem );
+      Trace("ambqi-inst") << "...Added " << lem << " lemmas." << std::endl;
+      if( lem>0 ){
+        //if we were incomplete but added at least one lemma, we are ok
+        quantValid = true;
+      }
+      d_addedLemmas += lem;
+      Trace("ambqi-inst-debug") << "...Total : " << d_addedLemmas << std::endl;
+    }
+    return quantValid;
+  }
+  return true;
+}
+
+bool AbsMbqiBuilder::doCheck( FirstOrderModelAbs * m, TNode q, AbsDef & ad, TNode n ) {
+  Assert( n.getKind()!=FORALL );
+  if( n.getKind()==NOT && n[0].getKind()!=FORALL ){
+    doCheck( m, q, ad, n[0] );
+    ad.negate();
+    return true;
+  }else{
+    std::map< unsigned, AbsDef > children;
+    std::map< unsigned, int > bchildren;
+    std::map< unsigned, int > vchildren;
+    int varChCount = 0;
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){
+      if( n[i].getKind()==FORALL ){
+        bchildren[i] = AbsDef::val_unk;
+      }else if( n[i].getKind() == BOUND_VARIABLE ){
+        varChCount++;
+        vchildren[i] = m->d_var_index[q][ m->getVariableId( q, n[i] ) ];
+        //vchildren[i] = m->getVariableId( q, n[i] );
+      }else if( m->hasTerm( n[i] ) ){
+        bchildren[i] = m->getRepresentativeId( n[i] );
+      }else{
+        if( !doCheck( m, q, children[i], n[i] ) ){
+          bchildren[i] = AbsDef::val_unk;
+          children.erase( i );
+        }
+      }
+    }
+    //convert to pointers
+    std::map< unsigned, AbsDef * > pchildren;
+    for( std::map< unsigned, AbsDef >::iterator it = children.begin(); it != children.end(); ++it ){
+      pchildren[it->first] = &it->second;
+    }
+    //construct the interpretation
+    Trace("ambqi-check-debug") << "Compute Interpretation of " << n << " " << n.getKind() << std::endl;
+    if( n.getKind() == APPLY_UF || n.getKind() == VARIABLE || n.getKind() == SKOLEM ){
+      Node op;
+      if( n.getKind() == APPLY_UF ){
+        op = n.getOperator();
+      }else{
+        op = n;
+      }
+      //uninterpreted compose
+      if( m->d_models_valid[op] ){
+        ad.construct( m, q, n, m->d_models[op], pchildren, bchildren, vchildren, varChCount );
+      }else{
+        Trace("ambqi-check-debug") << "** Cannot produce interpretation for " << n << " (no function model)" << std::endl;
+        return false;
+      }
+    }else if( !ad.construct( m, q, n, NULL, pchildren, bchildren, vchildren, varChCount ) ){
+      Trace("ambqi-check-debug") << "** Cannot produce interpretation for " << n << " (variables are children of interpreted symbol)" << std::endl;
+      return false;
+    }
+    Trace("ambqi-check-try") << "Interpretation for " << n << " is : " << std::endl;
+    ad.debugPrint("ambqi-check-try", m, q[0] );
+    ad.simplify( m, q, q[0] );
+    Trace("ambqi-check-debug") << "(Simplified) Interpretation for " << n << " is : " << std::endl;
+    ad.debugPrint("ambqi-check-debug", m, q[0] );
+    Trace("ambqi-check-debug") << std::endl;
+    return true;
+  }
+}
index 349073cb43749b8ba4e8705a6088e17d2a4927cf..d586d9c8f67dfdc6a0046e718d050de7ff30b419 100755 (executable)
-/*********************                                                        */\r
-/*! \file ambqi_builder.h\r
- ** \verbatim\r
- ** Original author: Andrew Reynolds\r
- ** Major contributors: none\r
- ** Minor contributors (to current version): none\r
- ** This file is part of the CVC4 project.\r
- ** Copyright (c) 2009-2013  New York University and The University of Iowa\r
- ** See the file COPYING in the top-level source directory for licensing\r
- ** information.\endverbatim\r
- **\r
- ** \brief Abstract MBQI model builder class\r
- **/\r
-\r
-#include "cvc4_private.h"\r
-\r
-#ifndef ABSTRACT_MBQI_BUILDER\r
-#define ABSTRACT_MBQI_BUILDER\r
-\r
-#include "theory/quantifiers/model_builder.h"\r
-#include "theory/quantifiers/first_order_model.h"\r
-\r
-namespace CVC4 {\r
-namespace theory {\r
-namespace quantifiers {\r
-\r
-class FirstOrderModelAbs;\r
-\r
-//representiation of function and term interpretations\r
-class AbsDef\r
-{\r
-private:\r
-  bool addInstantiations( FirstOrderModelAbs * m, QuantifiersEngine * qe, TNode q, std::vector< Node >& terms, int& inst, unsigned depth );\r
-  void construct_compose( FirstOrderModelAbs * m, TNode q, TNode n, AbsDef * f,\r
-                          std::map< unsigned, AbsDef * >& children,\r
-                          std::map< unsigned, int >& bchildren, std::map< unsigned, int >& vchildren,\r
-                          std::vector< unsigned >& entry, std::vector< bool >& entry_def );\r
-  void construct_entry( std::vector< unsigned >& entry, std::vector< bool >& entry_def, int v, unsigned depth = 0 );\r
-  void construct_def_entry( FirstOrderModelAbs * m, TNode q, TNode n, int v, unsigned depth = 0 );\r
-  void apply_ucompose( FirstOrderModelAbs * m, TNode q,\r
-                       std::vector< unsigned >& entry, std::vector< bool >& entry_def, std::vector< int >& terms,\r
-                       std::map< unsigned, int >& vchildren, AbsDef * a, unsigned depth = 0 );\r
-  void construct_var_eq( FirstOrderModelAbs * m, TNode q, unsigned v1, unsigned v2, int curr, int currv, unsigned depth = 0 );\r
-  void construct_var( FirstOrderModelAbs * m, TNode q, unsigned v, int currv, unsigned depth = 0 );\r
-  void get_defs( unsigned u, std::vector< AbsDef * >& defs );\r
-  void construct_normalize( FirstOrderModelAbs * m, TNode q, std::vector< AbsDef * >& defs, unsigned depth = 0 );\r
-public:\r
-  enum {\r
-    val_none = -1,\r
-    val_unk = -2,\r
-  };\r
-  AbsDef() : d_default( 0 ), d_value( -1 ){}\r
-  std::map< unsigned, AbsDef > d_def;\r
-  unsigned d_default;\r
-  int d_value;\r
-\r
-  void clear() { d_def.clear(); d_default = 0; d_value = -1; }\r
-  AbsDef * getDefault() { return &d_def[d_default]; }\r
-  void construct_func( FirstOrderModelAbs * m, std::vector< TNode >& fapps, unsigned depth = 0 );\r
-  void debugPrintUInt( const char * c, unsigned dSize, unsigned u ) const;\r
-  void debugPrint( const char * c, FirstOrderModelAbs * m, TNode f, unsigned depth = 0 ) const;\r
-  void simplify( FirstOrderModelAbs * m, TNode q, TNode n, unsigned depth = 0 );\r
-  int addInstantiations( FirstOrderModelAbs * m, QuantifiersEngine * qe, Node q, int& inst ){\r
-    std::vector< Node > terms;\r
-    terms.resize( q[0].getNumChildren() );\r
-    return addInstantiations( m, qe, q, terms, inst, 0 );\r
-  }\r
-  bool construct( FirstOrderModelAbs * m, TNode q, TNode n, AbsDef * f,\r
-                  std::map< unsigned, AbsDef * >& children,\r
-                  std::map< unsigned, int >& bchildren,\r
-                  std::map< unsigned, int >& vchildren,\r
-                  int varChCount );\r
-  void negate();\r
-  Node getFunctionValue( FirstOrderModelAbs * m, TNode op, std::vector< Node >& vars, unsigned depth = 0 );\r
-  static bool isSimple( unsigned n );\r
-  static unsigned getId( unsigned n, unsigned start=0, unsigned end=32 );\r
-  Node evaluate( FirstOrderModelAbs * m, TypeNode retType, std::vector< Node >& args );\r
-  Node evaluate( FirstOrderModelAbs * m, TypeNode retType, std::vector< unsigned >& iargs, unsigned depth = 0 );\r
-  //for debugging\r
-  bool is_normalized();\r
-};\r
-\r
-class AbsMbqiBuilder : public QModelBuilder\r
-{\r
-  friend class AbsDef;\r
-private:\r
-  Node d_true;\r
-  Node d_false;\r
-  bool doCheck( FirstOrderModelAbs * m, TNode q, AbsDef & ad, TNode n );\r
-public:\r
-  AbsMbqiBuilder( context::Context* c, QuantifiersEngine* qe );\r
-  //process build model\r
-  void processBuildModel(TheoryModel* m, bool fullModel);\r
-  //do exhaustive instantiation\r
-  bool doExhaustiveInstantiation( FirstOrderModel * fm, Node q, int effort );\r
-};\r
-\r
-}\r
-}\r
-}\r
-\r
-#endif\r
+/*********************                                                        */
+/*! \file ambqi_builder.h
+ ** \verbatim
+ ** Original author: Andrew Reynolds
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2013  New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Abstract MBQI model builder class
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef ABSTRACT_MBQI_BUILDER
+#define ABSTRACT_MBQI_BUILDER
+
+#include "theory/quantifiers/model_builder.h"
+#include "theory/quantifiers/first_order_model.h"
+
+namespace CVC4 {
+namespace theory {
+namespace quantifiers {
+
+class FirstOrderModelAbs;
+
+//representiation of function and term interpretations
+class AbsDef
+{
+private:
+  bool addInstantiations( FirstOrderModelAbs * m, QuantifiersEngine * qe, TNode q, std::vector< Node >& terms, int& inst, unsigned depth );
+  void construct_compose( FirstOrderModelAbs * m, TNode q, TNode n, AbsDef * f,
+                          std::map< unsigned, AbsDef * >& children,
+                          std::map< unsigned, int >& bchildren, std::map< unsigned, int >& vchildren,
+                          std::vector< unsigned >& entry, std::vector< bool >& entry_def );
+  void construct_entry( std::vector< unsigned >& entry, std::vector< bool >& entry_def, int v, unsigned depth = 0 );
+  void construct_def_entry( FirstOrderModelAbs * m, TNode q, TNode n, int v, unsigned depth = 0 );
+  void apply_ucompose( FirstOrderModelAbs * m, TNode q,
+                       std::vector< unsigned >& entry, std::vector< bool >& entry_def, std::vector< int >& terms,
+                       std::map< unsigned, int >& vchildren, AbsDef * a, unsigned depth = 0 );
+  void construct_var_eq( FirstOrderModelAbs * m, TNode q, unsigned v1, unsigned v2, int curr, int currv, unsigned depth = 0 );
+  void construct_var( FirstOrderModelAbs * m, TNode q, unsigned v, int currv, unsigned depth = 0 );
+  void get_defs( unsigned u, std::vector< AbsDef * >& defs );
+  void construct_normalize( FirstOrderModelAbs * m, TNode q, std::vector< AbsDef * >& defs, unsigned depth = 0 );
+public:
+  enum {
+    val_none = -1,
+    val_unk = -2,
+  };
+  AbsDef() : d_default( 0 ), d_value( -1 ){}
+  std::map< unsigned, AbsDef > d_def;
+  unsigned d_default;
+  int d_value;
+
+  void clear() { d_def.clear(); d_default = 0; d_value = -1; }
+  AbsDef * getDefault() { return &d_def[d_default]; }
+  void construct_func( FirstOrderModelAbs * m, std::vector< TNode >& fapps, unsigned depth = 0 );
+  void debugPrintUInt( const char * c, unsigned dSize, unsigned u ) const;
+  void debugPrint( const char * c, FirstOrderModelAbs * m, TNode f, unsigned depth = 0 ) const;
+  void simplify( FirstOrderModelAbs * m, TNode q, TNode n, unsigned depth = 0 );
+  int addInstantiations( FirstOrderModelAbs * m, QuantifiersEngine * qe, Node q, int& inst ){
+    std::vector< Node > terms;
+    terms.resize( q[0].getNumChildren() );
+    return addInstantiations( m, qe, q, terms, inst, 0 );
+  }
+  bool construct( FirstOrderModelAbs * m, TNode q, TNode n, AbsDef * f,
+                  std::map< unsigned, AbsDef * >& children,
+                  std::map< unsigned, int >& bchildren,
+                  std::map< unsigned, int >& vchildren,
+                  int varChCount );
+  void negate();
+  Node getFunctionValue( FirstOrderModelAbs * m, TNode op, std::vector< Node >& vars, unsigned depth = 0 );
+  static bool isSimple( unsigned n );
+  static unsigned getId( unsigned n, unsigned start=0, unsigned end=32 );
+  Node evaluate( FirstOrderModelAbs * m, TypeNode retType, std::vector< Node >& args );
+  Node evaluate( FirstOrderModelAbs * m, TypeNode retType, std::vector< unsigned >& iargs, unsigned depth = 0 );
+  //for debugging
+  bool is_normalized();
+};
+
+class AbsMbqiBuilder : public QModelBuilder
+{
+  friend class AbsDef;
+private:
+  Node d_true;
+  Node d_false;
+  bool doCheck( FirstOrderModelAbs * m, TNode q, AbsDef & ad, TNode n );
+public:
+  AbsMbqiBuilder( context::Context* c, QuantifiersEngine* qe );
+  //process build model
+  void processBuildModel(TheoryModel* m, bool fullModel);
+  //do exhaustive instantiation
+  bool doExhaustiveInstantiation( FirstOrderModel * fm, Node q, int effort );
+};
+
+}
+}
+}
+
+#endif
index 285834e96e3bc05ce680d6abb758e46a1dc5b39f..bd8f23db6880d036e8f612deb258c3c355e3c71c 100755 (executable)
-/*********************                                                        */\r
-/*! \file qinterval_builder.cpp\r
- ** \verbatim\r
- ** Original author: Andrew Reynolds\r
- ** Major contributors: none\r
- ** Minor contributors (to current version): none\r
- ** This file is part of the CVC4 project.\r
- ** Copyright (c) 2009-2013  New York University and The University of Iowa\r
- ** See the file COPYING in the top-level source directory for licensing\r
- ** information.\endverbatim\r
- **\r
- ** \brief Implementation of qinterval builder\r
- **/\r
-\r
-\r
-#include "theory/quantifiers/qinterval_builder.h"\r
-#include "theory/quantifiers/term_database.h"\r
-\r
-\r
-using namespace std;\r
-using namespace CVC4;\r
-using namespace CVC4::kind;\r
-using namespace CVC4::context;\r
-using namespace CVC4::theory;\r
-using namespace CVC4::theory::quantifiers;\r
-\r
-//lower bound is exclusive\r
-//upper bound is inclusive\r
-\r
-struct QIntSort\r
-{\r
-  FirstOrderModelQInt * m;\r
-  bool operator() (Node i, Node j) {\r
-    return m->isLessThan( i, j );\r
-  }\r
-};\r
-\r
-void QIntDef::init_vec( FirstOrderModelQInt * m, Node q, std::vector< Node >& l, std::vector< Node >& u ) {\r
-  for( unsigned i=0; i<m->getOrderedNumVars( q ); i++ ){\r
-    l.push_back( Node::null() );\r
-    u.push_back( m->getMaximum( m->getOrderedVarType( q, i ) ) );\r
-  }\r
-}\r
-\r
-void QIntDef::debugPrint( const char * c, FirstOrderModelQInt * m, Node q, std::vector< Node >& l, std::vector< Node >& u )\r
-{\r
-  Trace(c) << "( ";\r
-  for( unsigned i=0; i<l.size(); i++ ){\r
-    if( i>0 ) Trace(c) << ", ";\r
-    //Trace(c) << l[i] << "..." << u[i];\r
-    int lindex = l[i].isNull() ? 0 : m->getRepId( l[i] ) + 1;\r
-    int uindex = m->getRepId( u[i] );\r
-    Trace(c) << lindex << "..." << uindex;\r
-  }\r
-  Trace(c) << " )";\r
-}\r
-\r
-\r
-int QIntDef::getEvIndex( FirstOrderModelQInt * m, Node n, bool exc ) {\r
-  if( n.isNull() ){\r
-    Assert( exc );\r
-    return 0;\r
-  }else{\r
-    int min = 0;\r
-    int max = (int)(d_def_order.size()-1);\r
-    while( min!=max ){\r
-      int index = (min+max)/2;\r
-      Assert( index>=0 && index<(int)d_def_order.size() );\r
-      if( n==d_def_order[index] ){\r
-        max = index;\r
-        min = index;\r
-      }else if( m->isLessThan( n, d_def_order[index] ) ){\r
-        max = index;\r
-      }else{\r
-        min = index+1;\r
-      }\r
-    }\r
-    if( n==d_def_order[min] && exc ){\r
-      min++;\r
-    }\r
-    Assert( min>=0 && min<(int)d_def_order.size() );\r
-    if( ( min!=0 && !m->isLessThan( d_def_order[min-1], n ) && ( !exc || d_def_order[min-1]!=n ) ) ||\r
-        ( ( exc || d_def_order[min]!=n ) && !m->isLessThan( n, d_def_order[min] ) ) ){\r
-      Debug("qint-error") << "ERR size : " << d_def_order.size() << ", exc : " << exc << std::endl;\r
-      for( unsigned i=0; i<d_def_order.size(); i++ ){\r
-        Debug("qint-error") << "ERR ch #" << i << " : " << d_def_order[i];\r
-        Debug("qint-error") << " " << m->getRepId( d_def_order[i] ) << std::endl;\r
-      }\r
-      Debug("qint-error") << " : " << n << " " << min << " " << m->getRepId( n ) << std::endl;\r
-    }\r
-\r
-    Assert( min==0 || m->isLessThan( d_def_order[min-1], n ) || ( exc && d_def_order[min-1]==n ) );\r
-    Assert( ( !exc && n==d_def_order[min] ) || m->isLessThan( n, d_def_order[min] ) );\r
-    return min;\r
-  }\r
-}\r
-\r
-void QIntDef::addEntry( FirstOrderModelQInt * m, Node q, std::vector< Node >& l, std::vector< Node >& u,\r
-                        Node v, unsigned depth ) {\r
-  if( depth==0 ){\r
-    Trace("qint-compose-debug") << "Add entry ";\r
-    debugPrint( "qint-compose-debug", m, q, l, u );\r
-    Trace("qint-compose-debug") << " -> " << v << "..." << std::endl;\r
-  }\r
-  //Assert( false );\r
-  if( depth==u.size() ){\r
-    Assert( d_def_order.empty() );\r
-    Assert( v.isNull() || v.isConst() || ( v.getType().isSort() && m->getRepId( v )!=-1 ) );\r
-    d_def_order.push_back( v );\r
-  }else{\r
-    /*\r
-    if( !d_def_order.empty() &&\r
-        ( l[depth].isNull() || m->isLessThan( l[depth], d_def_order[d_def_order.size()-1] ) ) ){\r
-      int startEvIndex = getEvIndex( m, l[depth], true );\r
-      int endEvIndex;\r
-      if( m->isLessThan( u[depth], d_def_order[d_def_order.size()-1] ) ){\r
-        endEvIndex = getEvIndex( m, u[depth] );\r
-      }else{\r
-        endEvIndex = d_def_order.size()-1;\r
-      }\r
-      Trace("qint-compose-debug2") << this << " adding for bounds " << l[depth] << "..." << u[depth] << std::endl;\r
-      for( int i=startEvIndex; i<=endEvIndex; i++ ){\r
-        Trace("qint-compose-debug2") << this << " add entry " << d_def_order[i] << std::endl;\r
-        d_def[d_def_order[i]].addEntry( m, q, l, u, v, depth+1 );\r
-      }\r
-    }\r
-    if( !d_def_order.empty() &&\r
-         d_def.find(u[depth])==d_def.end() &&\r
-         !m->isLessThan( d_def_order[d_def_order.size()-1], u[depth] ) ){\r
-      Trace("qint-compose-debug2") << "Bad : depth : " << depth << std::endl;\r
-    }\r
-    Assert( d_def_order.empty() ||\r
-            d_def.find(u[depth])!=d_def.end() ||\r
-            m->isLessThan( d_def_order[d_def_order.size()-1], u[depth] ) );\r
-\r
-    if( d_def_order.empty() || m->isLessThan( d_def_order[d_def_order.size()-1], u[depth] ) ){\r
-      Trace("qint-compose-debug2") << this << " add entry new : " << u[depth] << std::endl;\r
-      d_def_order.push_back( u[depth] );\r
-      d_def[u[depth]].addEntry( m, q, l, u, v, depth+1 );\r
-    }\r
-    */\r
-    //%%%%%%\r
-    bool success = true;\r
-    int nnum = m->getVarOrder( q )->getNextNum( depth );\r
-    Node pl;\r
-    Node pu;\r
-    if( nnum!=-1 ){\r
-      Trace("qint-compose-debug2") << "...adding entry #" << depth << " is #" << nnum << std::endl;\r
-      //Assert( l[nnum].isNull() || l[nnum]==l[depth] || m->isLessThan( l[nnum], l[depth] ) );\r
-      //Assert( u[nnum]==u[depth] || m->isLessThan( u[depth], u[nnum] ) );\r
-      pl = l[nnum];\r
-      pu = u[nnum];\r
-      if( !m->doMeet( l[nnum], u[nnum], l[depth], u[depth], l[nnum], u[nnum] ) ){\r
-        success = false;\r
-      }\r
-    }\r
-    //%%%%%%\r
-    if( success ){\r
-      Node r = u[depth];\r
-      if( d_def.find( r )!=d_def.end() ){\r
-        d_def[r].addEntry( m, q, l, u, v, depth+1 );\r
-      }else{\r
-        if( !d_def_order.empty() &&\r
-            !m->isLessThan( d_def_order[d_def_order.size()-1], u[depth] ) ){\r
-          Trace("qint-compose-debug2") << "Bad : depth : " << depth << " ";\r
-          Trace("qint-compose-debug2") << d_def_order[d_def_order.size()-1] << " " << u[depth] << std::endl;\r
-        }\r
-        Assert( d_def_order.empty() || m->isLessThan( d_def_order[d_def_order.size()-1], r ) );\r
-        d_def_order.push_back( r );\r
-        d_def[r].addEntry( m, q, l, u, v, depth+1 );\r
-      }\r
-    }\r
-    if( nnum!=-1 ){\r
-      l[nnum] = pl;\r
-      u[nnum] = pu;\r
-    }\r
-  }\r
-}\r
-\r
-Node QIntDef::simplify_r( FirstOrderModelQInt * m, Node q, std::vector< Node >& il, std::vector< Node >& iu,\r
-                          unsigned depth ) {\r
-  if( d_def.empty() ){\r
-    if( d_def_order.size()!=0 ){\r
-      Debug("qint-error") << "Simplify, size = " << d_def_order.size() << std::endl;\r
-    }\r
-    Assert( d_def_order.size()==1 );\r
-    return d_def_order[0];\r
-  }else{\r
-    Assert( !d_def_order.empty() );\r
-    std::vector< Node > newDefs;\r
-    Node curr;\r
-    for( unsigned i=0; i<d_def_order.size(); i++ ){\r
-      Node n = d_def[d_def_order[i]].simplify_r( m, q, il, iu, depth+1 );\r
-      if( i>0 ){\r
-        if( n==curr && !n.isNull() ){\r
-          d_def.erase( d_def_order[i-1] );\r
-        }else{\r
-          newDefs.push_back( d_def_order[i-1] );\r
-        }\r
-      }\r
-      curr = n;\r
-    }\r
-    newDefs.push_back( d_def_order[d_def_order.size()-1] );\r
-    d_def_order.clear();\r
-    d_def_order.insert( d_def_order.end(), newDefs.begin(), newDefs.end() );\r
-    return d_def_order.size()==1 ? curr : Node::null();\r
-  }\r
-}\r
-\r
-Node QIntDef::simplify( FirstOrderModelQInt * m, Node q ) {\r
-  std::vector< Node > l;\r
-  std::vector< Node > u;\r
-  if( !q.isNull() ){\r
-    //init_vec( m, q, l, u );\r
-  }\r
-  return simplify_r( m, q, l, u, 0 );\r
-}\r
-\r
-bool QIntDef::isTotal_r( FirstOrderModelQInt * m, Node q, std::vector< Node >& l, std::vector< Node >& u,\r
-                         unsigned depth ) {\r
-  if( d_def_order.empty() ){\r
-    return false;\r
-  }else if( d_def.empty() ){\r
-    return true;\r
-  }else{\r
-    //get the current maximum\r
-    Node mx;\r
-    if( !q.isNull() ){\r
-      int pnum = m->getVarOrder( q )->getPrevNum( depth );\r
-      if( pnum!=-1 ){\r
-        mx = u[pnum];\r
-      }\r
-    }\r
-    if( mx.isNull() ){\r
-      mx = m->getMaximum( d_def_order[d_def_order.size()-1].getType() );\r
-    }\r
-    //if not current maximum\r
-    if( d_def_order[d_def_order.size()-1]!=mx ){\r
-      return false;\r
-    }else{\r
-      Node pu = u[depth];\r
-      for( unsigned i=0; i<d_def_order.size(); i++ ){\r
-        u[depth] = d_def_order[i];\r
-        if( !d_def[d_def_order[i]].isTotal_r( m, q, l, u, depth+1 ) ){\r
-          return false;\r
-        }\r
-      }\r
-      u[depth] = pu;\r
-      return true;\r
-    }\r
-  }\r
-}\r
-\r
-bool QIntDef::isTotal( FirstOrderModelQInt * m, Node q ) {\r
-  std::vector< Node > l;\r
-  std::vector< Node > u;\r
-  if( !q.isNull() ){\r
-    init_vec( m, q, l, u );\r
-  }\r
-  return isTotal_r( m, q, l, u, 0 );\r
-}\r
-\r
-void QIntDef::construct_compose_r( FirstOrderModelQInt * m, Node q,\r
-                                    std::vector< Node >& l, std::vector< Node >& u,\r
-                                    Node n, QIntDef * f,\r
-                                    std::vector< Node >& args,\r
-                                    std::map< unsigned, QIntDef >& children,\r
-                                    std::map< unsigned, Node >& bchildren,\r
-                                    QIntVarNumIndex& vindex, unsigned depth ) {\r
-  //check for short circuit\r
-  if( !f ){\r
-    if( !args.empty() ){\r
-      if( ( n.getKind()==OR && args[args.size()-1]==m->d_true ) ||\r
-          ( n.getKind()==AND && args[args.size()-1]==m->d_false ) ){\r
-        addEntry( m, q, l, u, args[args.size()-1] );\r
-        return;\r
-      }\r
-    }\r
-  }\r
-\r
-  for( unsigned i=0; i<depth; i++ ) { Trace("qint-compose") << "  "; }\r
-  Trace("qint-compose") << (f ? "U" : "I" ) << "C( ";\r
-  for( unsigned i=0; i<l.size(); i++ ){\r
-    if( i>0 ) Trace("qint-compose") << ", ";\r
-    //Trace("qint-compose") << l[i] << "..." << u[i];\r
-    int lindex = l[i].isNull() ? 0 : m->getRepId( l[i] ) + 1;\r
-    int uindex = m->getRepId( u[i] );\r
-    Trace( "qint-compose" ) << lindex << "..." << uindex;\r
-  }\r
-  Trace("qint-compose") << " )...";\r
-\r
-  //finished?\r
-  if( ( f && f->d_def.empty() ) || args.size()==n.getNumChildren() ){\r
-    if( f ){\r
-      Assert( f->d_def_order.size()==1 );\r
-      Trace("qint-compose") << "UVALUE(" << f->d_def_order[0] << ")" << std::endl;\r
-      addEntry( m, q, l, u, f->d_def_order[0] );\r
-    }else{\r
-      Node nn;\r
-      bool nnSet = false;\r
-      for( unsigned i=0; i<args.size(); i++ ){\r
-        if( args[i].isNull() ){\r
-          nnSet = true;\r
-          break;\r
-        }\r
-      }\r
-      if( !nnSet ){\r
-        if( n.getKind()==EQUAL ){\r
-          nn = NodeManager::currentNM()->mkConst( args[0]==args[1] );\r
-        }else{\r
-          //apply the operator to args\r
-          nn = NodeManager::currentNM()->mkNode( n.getKind(), args );\r
-          nn = Rewriter::rewrite( nn );\r
-        }\r
-      }\r
-      Trace("qint-compose") << "IVALUE(" << nn << ")" << std::endl;\r
-      addEntry( m, q, l, u, nn );\r
-      Trace("qint-compose-debug2") << "...added entry." << std::endl;\r
-    }\r
-  }else{\r
-    //if a non-simple child\r
-    if( children.find( depth )!=children.end() ){\r
-      //***************************\r
-      Trace("qint-compose") << "compound child, recurse" << std::endl;\r
-      std::vector< int > currIndex;\r
-      std::vector< int > endIndex;\r
-      std::vector< Node > prevL;\r
-      std::vector< Node > prevU;\r
-      std::vector< QIntDef * > visited;\r
-      do{\r
-        Assert( currIndex.size()==visited.size() );\r
-\r
-        //populate the vectors\r
-        while( visited.size()<m->getOrderedNumVars( q ) ){\r
-          unsigned i = visited.size();\r
-          QIntDef * qq = visited.empty() ? &children[depth] : visited[i-1]->getChild( currIndex[i-1] );\r
-          visited.push_back( qq );\r
-          Node qq_mx = qq->getMaximum();\r
-          Trace("qint-compose-debug2") << "...Get ev indices " << i << " " << l[i] << " " << u[i] << std::endl;\r
-          currIndex.push_back( qq->getEvIndex( m, l[i], true ) );\r
-          Trace("qint-compose-debug2") << "...Done get curr index " << currIndex[currIndex.size()-1] << std::endl;\r
-          if( m->isLessThan( qq_mx, u[i] ) ){\r
-            endIndex.push_back( qq->getNumChildren()-1 );\r
-          }else{\r
-            endIndex.push_back( qq->getEvIndex( m, u[i] ) );\r
-          }\r
-          Trace("qint-compose-debug2") << "...Done get end index " << endIndex[endIndex.size()-1] << std::endl;\r
-          prevL.push_back( l[i] );\r
-          prevU.push_back( u[i] );\r
-          if( !m->doMeet( prevL[i], prevU[i],\r
-                          qq->getLower( currIndex[i] ), qq->getUpper( currIndex[i] ), l[i], u[i] ) ){\r
-            Assert( false );\r
-          }\r
-        }\r
-        for( unsigned i=0; i<depth; i++ ) { Trace("qint-compose") << "  "; }\r
-        for( unsigned i=0; i<currIndex.size(); i++ ){\r
-          Trace("qint-compose") << "[" << currIndex[i] << "/" << endIndex[i] << "]";\r
-        }\r
-        Trace("qint-compose") << std::endl;\r
-        //consider the current\r
-        int activeIndex = visited.size()-1;\r
-        QIntDef * qa = visited.empty() ? &children[depth] : visited[activeIndex]->getChild( currIndex[activeIndex] );\r
-        if( f ){\r
-          int fIndex = f->getEvIndex( m, qa->getValue() );\r
-          construct_compose_r( m, q, l, u, n, f->getChild( fIndex ), args, children, bchildren, vindex, depth+1 );\r
-        }else{\r
-          args.push_back( qa->getValue() );\r
-          construct_compose_r( m, q, l, u, n, f, args, children, bchildren, vindex, depth+1 );\r
-          args.pop_back();\r
-        }\r
-\r
-        //increment the index (if possible)\r
-        while( activeIndex>=0 && currIndex[activeIndex]==endIndex[activeIndex] ){\r
-          currIndex.pop_back();\r
-          endIndex.pop_back();\r
-          l[activeIndex] = prevL[activeIndex];\r
-          u[activeIndex] = prevU[activeIndex];\r
-          prevL.pop_back();\r
-          prevU.pop_back();\r
-          visited.pop_back();\r
-          activeIndex--;\r
-        }\r
-        if( activeIndex>=0 ){\r
-          for( unsigned i=0; i<depth; i++ ) { Trace("qint-compose") << "  "; }\r
-          Trace("qint-compose-debug") << "Increment at " << activeIndex << std::endl;\r
-          currIndex[activeIndex]++;\r
-          if( !m->doMeet( prevL[activeIndex], prevU[activeIndex],\r
-                          visited[activeIndex]->getLower( currIndex[activeIndex] ),\r
-                          visited[activeIndex]->getUpper( currIndex[activeIndex] ),\r
-                          l[activeIndex], u[activeIndex] ) ){\r
-            Assert( false );\r
-          }\r
-        }\r
-      }while( !visited.empty() );\r
-      //***************************\r
-    }else{\r
-      Assert( bchildren.find( depth )!=bchildren.end() );\r
-      Node v = bchildren[depth];\r
-      if( f ){\r
-        if( v.getKind()==BOUND_VARIABLE ){\r
-          int vn = vindex.d_var_num[depth];\r
-          Trace("qint-compose") << "variable #" << vn << ", recurse" << std::endl;\r
-          //int vn = m->getOrderedVarOccurId( q, n, depth );\r
-          Trace("qint-compose-debug") << "-process " << v << ", which is var #" << vn << std::endl;\r
-          Node lprev = l[vn];\r
-          Node uprev = u[vn];\r
-          //restrict to last variable in order\r
-          int pnum = m->getVarOrder( q )->getPrevNum( vn );\r
-          if( pnum!=-1 ){\r
-            Trace("qint-compose-debug") << "-restrict to var #" << pnum << " " << l[pnum] << " " << u[pnum] << std::endl;\r
-            l[vn] = l[pnum];\r
-            u[vn] = u[pnum];\r
-          }\r
-          int startIndex = f->getEvIndex( m, l[vn], true );\r
-          int endIndex = f->getEvIndex( m, u[vn] );\r
-          Trace("qint-compose-debug") << "--will process " << startIndex << " " << endIndex << std::endl;\r
-          for( int i=startIndex; i<=endIndex; i++ ){\r
-            if( m->doMeet( lprev, uprev, f->getLower( i ), f->getUpper( i ), l[vn], u[vn] ) ){\r
-              construct_compose_r( m, q, l, u, n, f->getChild( i ), args, children, bchildren, vindex, depth+1 );\r
-            }else{\r
-              Assert( false );\r
-            }\r
-          }\r
-          l[vn] = lprev;\r
-          u[vn] = uprev;\r
-        }else{\r
-          Trace("qint-compose") << "value, recurse" << std::endl;\r
-          //simple\r
-          int ei = f->getEvIndex( m, v );\r
-          construct_compose_r( m, q, l, u, n, f->getChild( ei ), args, children, bchildren, vindex, depth+1 );\r
-        }\r
-      }else{\r
-        Trace("qint-compose") << "value, recurse" << std::endl;\r
-        args.push_back( v );\r
-        construct_compose_r( m, q, l, u, n, f, args, children, bchildren, vindex, depth+1 );\r
-        args.pop_back();\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-\r
-void QIntDef::construct_enum_r( FirstOrderModelQInt * m, Node q, unsigned vn, unsigned depth, Node v ) {\r
-  if( depth==m->getOrderedNumVars( q ) ){\r
-    Assert( !v.isNull() );\r
-    d_def_order.push_back( v );\r
-  }else{\r
-    TypeNode tn = m->getOrderedVarType( q, depth );\r
-    //int vnum = m->getVarOrder( q )->getVar( depth )==\r
-    if( depth==vn ){\r
-      for( unsigned i=0; i<m->d_rep_set.d_type_reps[tn].size(); i++ ){\r
-        Node vv = m->d_rep_set.d_type_reps[tn][i];\r
-        d_def_order.push_back( vv );\r
-        d_def[vv].construct_enum_r( m, q, vn, depth+1, vv );\r
-      }\r
-    }else if( m->getVarOrder( q )->getVar( depth )==m->getVarOrder( q )->getVar( vn ) && depth>vn ){\r
-      d_def_order.push_back( v );\r
-      d_def[v].construct_enum_r( m, q, vn, depth+1, v );\r
-    }else{\r
-      Node mx = m->getMaximum( tn );\r
-      d_def_order.push_back( mx );\r
-      d_def[mx].construct_enum_r( m, q, vn, depth+1, v );\r
-    }\r
-  }\r
-}\r
-\r
-bool QIntDef::construct_enum( FirstOrderModelQInt * m, Node q, unsigned vn ) {\r
-  TypeNode tn = m->getOrderedVarType( q, vn );\r
-  if( tn.isSort() ){\r
-    construct_enum_r( m, q, vn, 0, Node::null() );\r
-    return true;\r
-  }else{\r
-    return false;\r
-  }\r
-}\r
-\r
-bool QIntDef::construct_compose( FirstOrderModelQInt * m, Node q, Node n, QIntDef * f,\r
-                                 std::map< unsigned, QIntDef >& children,\r
-                                 std::map< unsigned, Node >& bchildren, int varChCount,\r
-                                 QIntVarNumIndex& vindex ) {\r
- Trace("qint-compose") << "Do " << (f ? "uninterpreted" : "interpreted");\r
- Trace("qint-compose") << " compose, var count = " << varChCount << "..." << std::endl;\r
-  std::vector< Node > l;\r
-  std::vector< Node > u;\r
-  init_vec( m, q, l, u );\r
-  if( varChCount==0 || f ){\r
-    //standard (no variable child) interpreted compose, or uninterpreted compose\r
-    std::vector< Node > args;\r
-    construct_compose_r( m, q, l, u, n, f, args, children, bchildren, vindex, 0 );\r
-  }else{\r
-    //special cases\r
-    bool success = false;\r
-    int varIndex = ( bchildren.find( 0 )!=bchildren.end() && bchildren[0].getKind()==BOUND_VARIABLE ) ? 0 : 1;\r
-    if( varChCount>1 ){\r
-      if( n.getKind()==EQUAL ){\r
-        //make it an enumeration\r
-        unsigned vn = vindex.d_var_num[0];\r
-        if( children[0].construct_enum( m, q, vn ) ){\r
-          bchildren.erase( 0 );\r
-          varIndex = 1;\r
-          success = true;\r
-        }\r
-      }\r
-    }else{\r
-      success = n.getKind()==EQUAL;\r
-    }\r
-    if( success ){\r
-      int oIndex = varIndex==0 ? 1 : 0;\r
-      Node v = bchildren[varIndex];\r
-      unsigned vn = vindex.d_var_num[varIndex];\r
-      if( children.find( oIndex )==children.end() ){\r
-        Assert( bchildren.find( oIndex )!=bchildren.end() );\r
-        Node at = bchildren[oIndex];\r
-        Trace("qint-icompose") << "Basic child, " << at << " with var " << v << std::endl;\r
-        Node prev = m->getPrev( bchildren[oIndex].getType(), bchildren[oIndex] );\r
-        Node above = u[vn];\r
-        if( !prev.isNull() ){\r
-          u[vn] = prev;\r
-          addEntry( m, q, l, u, NodeManager::currentNM()->mkConst( false ) );\r
-        }\r
-        l[vn] = prev;\r
-        u[vn] = at;\r
-        addEntry( m, q, l, u, NodeManager::currentNM()->mkConst( true ) );\r
-        if( at!=above ){\r
-          l[vn] = at;\r
-          u[vn] = above;\r
-          addEntry( m, q, l, u, NodeManager::currentNM()->mkConst( false ) );\r
-        }\r
-      }else{\r
-        QIntDef * qid = &children[oIndex];\r
-        qid->debugPrint("qint-icompose", m, q );\r
-        Trace("qint-icompose") << " against variable..." << v << ", which is var #" << vn << std::endl;\r
-\r
-        TypeNode tn = v.getType();\r
-        QIntDefIter qdi( m, q, qid );\r
-        while( !qdi.isFinished() ){\r
-          std::vector< Node > us;\r
-          qdi.getUppers( us );\r
-          std::vector< Node > ls;\r
-          qdi.getLowers( ls );\r
-          qdi.debugPrint( "qint-icompose" );\r
-\r
-          Node n_below = ls[vn];\r
-          Node n_prev = m->getPrev( tn, qdi.getValue() );\r
-          Node n_at = qdi.getValue();\r
-          Node n_above = us[vn];\r
-          Trace("qint-icompose") << n_below << " < " << n_prev << " < " << n_at << " < " << n_above << std::endl;\r
-          if( n.getKind()==EQUAL ){\r
-            bool atLtAbove = m->isLessThan( n_at, n_above );\r
-            Node currL = n_below;\r
-            if( n_at==n_above || atLtAbove ){\r
-              //add for value (at-1)\r
-              if( !n_prev.isNull() && ( n_below.isNull() || m->isLessThan( n_below, n_prev ) ) ){\r
-                ls[vn] = currL;\r
-                us[vn] = n_prev;\r
-                currL = n_prev;\r
-                Trace("qint-icompose") << "-add entry(-) at " << ls[vn] << "..." << us[vn] << std::endl;\r
-                addEntry( m, q, ls, us, NodeManager::currentNM()->mkConst( false ) );\r
-              }\r
-              //add for value (at)\r
-              if( ( n_below.isNull() || m->isLessThan( n_below, n_at ) ) && atLtAbove ){\r
-                ls[vn] = currL;\r
-                us[vn] = n_at;\r
-                currL = n_at;\r
-                Trace("qint-icompose") << "-add entry(=) at " << ls[vn] << "..." << us[vn] << std::endl;\r
-                addEntry( m, q, ls, us, NodeManager::currentNM()->mkConst( true ) );\r
-              }\r
-            }\r
-            ls[vn] = currL;\r
-            us[vn] = n_above;\r
-            Trace("qint-icompose") << "-add entry(+) at " << ls[vn] << "..." << us[vn] << std::endl;\r
-            addEntry( m, q, ls, us, NodeManager::currentNM()->mkConst( n_at==n_above ) );\r
-          }else{\r
-            return false;\r
-          }\r
-          qdi.increment();\r
-\r
-          Trace("qint-icompose-debug") << "Now : " << std::endl;\r
-          debugPrint("qint-icompose-debug", m, q );\r
-          Trace("qint-icompose-debug") << std::endl;\r
-        }\r
-      }\r
-\r
-      Trace("qint-icompose") << "Result : " << std::endl;\r
-      debugPrint("qint-icompose", m, q );\r
-      Trace("qint-icompose") << std::endl;\r
-\r
-    }else{\r
-      return false;\r
-    }\r
-  }\r
-  Trace("qint-compose") << "Done i-compose" << std::endl;\r
-  return true;\r
-}\r
-\r
-\r
-void QIntDef::construct( FirstOrderModelQInt * m, std::vector< Node >& fapps, unsigned depth ) {\r
-  d_def.clear();\r
-  d_def_order.clear();\r
-  Assert( !fapps.empty() );\r
-  if( depth==fapps[0].getNumChildren() ){\r
-    //get representative in model for this term\r
-    Assert( fapps.size()>=1 );\r
-    Node r = m->getUsedRepresentative( fapps[0] );\r
-    d_def_order.push_back( r );\r
-  }else{\r
-    std::map< Node, std::vector< Node > > fapp_child;\r
-    //partition based on evaluations of fapps[1][depth]....fapps[n][depth]\r
-    for( unsigned i=0; i<fapps.size(); i++ ){\r
-      Node r = m->getUsedRepresentative( fapps[i][depth] );\r
-      fapp_child[r].push_back( fapps[i] );\r
-    }\r
-    //sort by QIntSort\r
-    for( std::map< Node, std::vector< Node > >::iterator it = fapp_child.begin(); it != fapp_child.end(); ++it ){\r
-      d_def_order.push_back( it->first );\r
-    }\r
-    QIntSort qis;\r
-    qis.m = m;\r
-    std::sort( d_def_order.begin(), d_def_order.end(), qis );\r
-    //construct children\r
-    for( unsigned i=0; i<d_def_order.size(); i++ ){\r
-      Node n = d_def_order[i];\r
-      if( i==d_def_order.size()-1 ){\r
-        d_def_order[i] = m->getMaximum( d_def_order[i].getType() );\r
-      }\r
-      Debug("qint-model-debug2") << "Construct for " << n << ", terms = " << fapp_child[n].size() << std::endl;\r
-      d_def[d_def_order[i]].construct( m, fapp_child[n], depth+1 );\r
-    }\r
-  }\r
-}\r
-\r
-Node QIntDef::getFunctionValue( FirstOrderModelQInt * m, std::vector< Node >& vars, unsigned depth ) {\r
-  if( d_def.empty() ){\r
-    Assert( d_def_order.size()==1 );\r
-    //must convert to actual domain constant\r
-    if( d_def_order[0].getType().isSort() ){\r
-      return m->d_rep_set.d_type_reps[ d_def_order[0].getType() ][ m->getRepId( d_def_order[0] ) ];\r
-    }else{\r
-      return m->getUsedRepresentative( d_def_order[0] );\r
-    }\r
-  }else{\r
-    TypeNode tn = vars[depth].getType();\r
-    Node curr;\r
-    int rep_id = m->d_rep_set.getNumRepresentatives( tn );\r
-    for( int i=(int)(d_def_order.size()-1); i>=0; i-- ){\r
-      int curr_rep_id = i==0 ? 0 : m->getRepId( d_def_order[i-1] )+1;\r
-      Node ccurr = d_def[d_def_order[i]].getFunctionValue( m, vars, depth+1 );\r
-      if( curr.isNull() ){\r
-        curr = ccurr;\r
-      }else{\r
-        std::vector< Node > c;\r
-        Assert( curr_rep_id<rep_id );\r
-        for( int j=curr_rep_id; j<rep_id; j++ ){\r
-          c.push_back( vars[depth].eqNode( m->d_rep_set.d_type_reps[tn][j] ) );\r
-        }\r
-        Node cond = c.size()==1 ? c[0] : NodeManager::currentNM()->mkNode( OR, c );\r
-        curr = NodeManager::currentNM()->mkNode( ITE, cond, ccurr, curr );\r
-      }\r
-      rep_id = curr_rep_id;\r
-    }\r
-    return curr;\r
-  }\r
-}\r
-\r
-Node QIntDef::evaluate_r( FirstOrderModelQInt * m, std::vector< Node >& reps, unsigned depth ) {\r
-  if( depth==reps.size() ){\r
-    Assert( d_def_order.size()==1 );\r
-    return d_def_order[0];\r
-  }else{\r
-    if( d_def.find( reps[depth] )!=d_def.end() ){\r
-      return d_def[reps[depth]].evaluate_r( m, reps, depth+1 );\r
-    }else{\r
-      int ei = getEvIndex( m, reps[depth] );\r
-      return d_def[d_def_order[ei]].evaluate_r( m, reps, depth+1 );\r
-    }\r
-  }\r
-}\r
-Node QIntDef::evaluate_n_r( FirstOrderModelQInt * m, Node n, unsigned depth ) {\r
-  if( depth==n.getNumChildren() ){\r
-    Assert( d_def_order.size()==1 );\r
-    return d_def_order[0];\r
-  }else{\r
-    Node r = m->getUsedRepresentative( n[depth] );\r
-    if( d_def.find( r )!=d_def.end() ){\r
-      return d_def[r].evaluate_n_r( m, n, depth+1 );\r
-    }else{\r
-      int ei = getEvIndex( m, r );\r
-      return d_def[d_def_order[ei]].evaluate_n_r( m, n, depth+1 );\r
-    }\r
-  }\r
-}\r
-\r
-\r
-\r
-QIntDef * QIntDef::getChild( unsigned i ) {\r
-  Assert( i<d_def_order.size() );\r
-  Assert( d_def.find( d_def_order[i] )!=d_def.end() );\r
-  return &d_def[ d_def_order[i] ];\r
-}\r
-\r
-void QIntDef::debugPrint( const char * c, FirstOrderModelQInt * m, Node q, int t ) {\r
-  /*\r
-  for( unsigned i=0; i<d_def_order.size(); i++ ){\r
-    for( int j=0; j<t; j++ ) { Trace(c) << " "; }\r
-    //Trace(c) << this << " ";\r
-    Trace(c) << d_def_order[i] << " : " << std::endl;\r
-    if( d_def.find( d_def_order[i] )!=d_def.end() ){\r
-      d_def[d_def_order[i]].debugPrint( c, m, t+1 );\r
-    }\r
-  }\r
-  */\r
-  //if( t==0 ){\r
-  QIntDefIter qdi( m, q, this );\r
-  while( !qdi.isFinished() ){\r
-    qdi.debugPrint( c, t );\r
-    qdi.increment();\r
-  }\r
-  //}\r
-}\r
-\r
-\r
-QIntDefIter::QIntDefIter( FirstOrderModelQInt * m, Node q, QIntDef * qid ) : d_fm( m ), d_q( q ){\r
-  resetIndex( qid );\r
-}\r
-\r
-void QIntDefIter::debugPrint( const char * c, int t ) {\r
-  //Trace( c ) << getSize() << " " << d_index_visited.size() << " ";\r
-  for( int j=0; j<t; j++ ) { Trace(c) << " "; }\r
-  std::vector< Node > l;\r
-  std::vector< Node > u;\r
-  getLowers( l );\r
-  getUppers( u );\r
-  QIntDef::debugPrint( c, d_fm, d_q, l, u );\r
-  Trace( c ) << " -> " << getValue() << std::endl;\r
-}\r
-\r
-void QIntDefIter::resetIndex( QIntDef * qid ){\r
-  //std::cout << "check : " << qid << " " << qid->d_def_order.size() << " " << qid->d_def.size() << std::endl;\r
-  if( !qid->d_def.empty() ){\r
-    //std::cout << "add to visited " <<  qid << std::endl;\r
-    d_index.push_back( 0 );\r
-    d_index_visited.push_back( qid );\r
-    resetIndex( qid->getChild( 0 ) );\r
-  }\r
-}\r
-\r
-bool QIntDefIter::increment( int index ) {\r
-  if( !isFinished() ){\r
-    index = index==-1 ? (int)(d_index.size()-1) : index;\r
-    while( (int)(d_index.size()-1)>index ){\r
-      //std::cout << "remove from visit 1 " << std::endl;\r
-      d_index.pop_back();\r
-      d_index_visited.pop_back();\r
-    }\r
-    while( index>=0 && d_index[index]>=(int)(d_index_visited[index]->d_def_order.size()-1) ){\r
-      //std::cout << "remove from visit " << d_index_visited[ d_index_visited.size()-1 ] << std::endl;\r
-      d_index.pop_back();\r
-      d_index_visited.pop_back();\r
-      index--;\r
-    }\r
-    if( index>=0 ){\r
-      //std::cout << "increment at index = " << index << std::endl;\r
-      d_index[index]++;\r
-      resetIndex( d_index_visited[index]->getChild( d_index[index] ) );\r
-      return true;\r
-    }else{\r
-      d_index.clear();\r
-      return false;\r
-    }\r
-  }else{\r
-    return false;\r
-  }\r
-}\r
-\r
-Node QIntDefIter::getLower( int index ) {\r
-  if( d_index[index]==0 && !d_q.isNull() ){\r
-    int pnum = d_fm->getVarOrder( d_q )->getPrevNum( index );\r
-    if( pnum!=-1 ){\r
-      return getLower( pnum );\r
-    }\r
-  }\r
-  return d_index_visited[index]->getLower( d_index[index] );\r
-}\r
-\r
-Node QIntDefIter::getUpper( int index ) {\r
-  return d_index_visited[index]->getUpper( d_index[index] );\r
-}\r
-\r
-void QIntDefIter::getLowers( std::vector< Node >& reps ) {\r
-  for( unsigned i=0; i<getSize(); i++ ){\r
-    bool added = false;\r
-    if( d_index[i]==0 && !d_q.isNull() ){\r
-      int pnum = d_fm->getVarOrder( d_q )->getPrevNum( i );\r
-      if( pnum!=-1 ){\r
-        added = true;\r
-        reps.push_back( reps[pnum] );\r
-      }\r
-    }\r
-    if( !added ){\r
-      reps.push_back( getLower( i ) );\r
-    }\r
-  }\r
-}\r
-\r
-void QIntDefIter::getUppers( std::vector< Node >& reps ) {\r
-  for( unsigned i=0; i<getSize(); i++ ){\r
-    reps.push_back( getUpper( i ) );\r
-  }\r
-}\r
-\r
-Node QIntDefIter::getValue() {\r
-  return d_index_visited[ d_index_visited.size()-1 ]->getChild( d_index[d_index.size()-1] )->getValue();\r
-}\r
-\r
-\r
-//------------------------variable ordering----------------------------\r
-\r
-QuantVarOrder::QuantVarOrder( Node q ) : d_q( q ) {\r
-  d_var_count = 0;\r
-  initialize( q[1], 0, d_var_occur );\r
-}\r
-\r
-int QuantVarOrder::initialize( Node n, int minVarIndex, QIntVarNumIndex& vindex ) {\r
-  if( n.getKind()!=FORALL ){\r
-    //std::vector< Node > vars;\r
-    //std::vector< int > args;\r
-    int procVarOn = n.getKind()==APPLY_UF ? 0 : 1;\r
-    for( int r=0; r<=procVarOn; r++ ){\r
-      for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-        if( n[i].getKind()==BOUND_VARIABLE && r==procVarOn ){\r
-          int occ_index = -1;\r
-          for( unsigned j=0; j<d_var_to_num[n[i]].size(); j++ ){\r
-            if( d_var_to_num[n[i]][j]>=minVarIndex ){\r
-              occ_index = d_var_to_num[n[i]][j];\r
-            }\r
-          }\r
-          if( occ_index==-1 ){\r
-            //need to assign new\r
-            d_num_to_var[d_var_count] = n[i];\r
-            if( !d_var_to_num[n[i]].empty() ){\r
-              int v = d_var_to_num[n[i]][ d_var_to_num[n[i]].size()-1 ];\r
-              d_num_to_prev_num[ d_var_count ] = v;\r
-              d_num_to_next_num[ v ] = d_var_count;\r
-            }\r
-            d_var_num_index[ d_var_count ] = d_var_to_num[n[i]].size();\r
-            d_var_to_num[n[i]].push_back( d_var_count );\r
-            occ_index = d_var_count;\r
-            d_var_count++;\r
-          }\r
-          vindex.d_var_num[i] = occ_index;\r
-          minVarIndex = occ_index;\r
-        }else if( r==0 ){\r
-          minVarIndex = initialize( n[i], minVarIndex, vindex.d_var_index[i] );\r
-        }\r
-      }\r
-    }\r
-  }\r
-  return minVarIndex;\r
-}\r
-\r
-bool QuantVarOrder::getInstantiation( FirstOrderModelQInt * m, std::vector< Node >& l, std::vector< Node >& u,\r
-                                      std::vector< Node >& inst ) {\r
-  Debug("qint-var-order-debug2") << "Get for " << d_q << " " << l.size() << " " << u.size() << std::endl;\r
-  for( unsigned i=0; i<d_q[0].getNumChildren(); i++ ){\r
-    Debug("qint-var-order-debug2") << "Get for " << d_q[0][i] << " " << d_var_to_num[d_q[0][i]].size() << std::endl;\r
-    Node ll = Node::null();\r
-    Node uu = m->getMaximum( d_q[0][i].getType() );\r
-    for( unsigned j=0; j<d_var_to_num[d_q[0][i]].size(); j++ ){\r
-      Debug("qint-var-order-debug2") << "Go " << j << std::endl;\r
-      Node cl = ll;\r
-      Node cu = uu;\r
-      int index = d_var_to_num[d_q[0][i]][j];\r
-      Debug("qint-var-order-debug2") << "Do meet for " << index << "..." << std::endl;\r
-      Debug("qint-var-order-debug2") << l[index] << " " << u[index] << " " << cl << " " << cu << std::endl;\r
-      if( !m->doMeet( l[index], u[index], cl, cu, ll, uu ) ){\r
-        Debug("qint-var-order-debug2") << "FAILED" << std::endl;\r
-        return false;\r
-      }\r
-      Debug("qint-var-order-debug2") << "Result : " << ll << " " << uu << std::endl;\r
-    }\r
-    Debug("qint-var-order-debug2") << "Got " << uu << std::endl;\r
-    inst.push_back( uu );\r
-  }\r
-  return true;\r
-}\r
-\r
-void QuantVarOrder::debugPrint( const char * c ) {\r
-  Trace( c ) << "Variable order for " << d_q << " is : " << std::endl;\r
-  debugPrint( c, d_q[1], d_var_occur );\r
-  Trace( c ) << std::endl;\r
-  for( unsigned i=0; i<d_q[0].getNumChildren(); i++ ){\r
-    Trace( c ) << d_q[0][i] << " : ";\r
-    for( unsigned j=0; j<d_var_to_num[d_q[0][i]].size(); j++ ){\r
-      Trace( c ) << d_var_to_num[d_q[0][i]][j] << " ";\r
-    }\r
-    Trace( c ) << std::endl;\r
-  }\r
-}\r
-\r
-void QuantVarOrder::debugPrint( const char * c, Node n, QIntVarNumIndex& vindex ) {\r
-  if( n.getKind()==FORALL ){\r
-    Trace(c) << "NESTED_QUANT";\r
-  }else{\r
-    Trace(c) << n.getKind() << "(";\r
-    for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-      if( i>0 ) Trace( c ) << ",";\r
-      Trace( c ) << " ";\r
-      if( n[i].getKind()==BOUND_VARIABLE ){\r
-        Trace(c) << "VAR[" << vindex.d_var_num[i] << "]";\r
-      }else{\r
-        debugPrint( c, n[i], vindex.d_var_index[i] );\r
-      }\r
-      if( i==n.getNumChildren()-1 ) Trace( c ) << " ";\r
-    }\r
-    Trace(c) << ")";\r
-  }\r
-}\r
-\r
-QIntervalBuilder::QIntervalBuilder( context::Context* c, QuantifiersEngine* qe ) :\r
-QModelBuilder( c, qe ){\r
-  d_true = NodeManager::currentNM()->mkConst( true );\r
-}\r
-\r
-\r
-//------------------------model construction----------------------------\r
-\r
-void QIntervalBuilder::processBuildModel(TheoryModel* m, bool fullModel) {\r
-  Trace("fmf-qint-debug") << "process build model " << fullModel << std::endl;\r
-  FirstOrderModel* f = (FirstOrderModel*)m;\r
-  FirstOrderModelQInt* fm = f->asFirstOrderModelQInt();\r
-  if( fullModel ){\r
-    Trace("qint-model") << "Construct model representation..." << std::endl;\r
-    //make function values\r
-    for( std::map<Node, QIntDef * >::iterator it = fm->d_models.begin(); it != fm->d_models.end(); ++it ) {\r
-      if( it->first.getType().getNumChildren()>1 ){\r
-        Trace("qint-model") << "Construct for " << it->first << "..." << std::endl;\r
-        m->d_uf_models[ it->first ] = fm->getFunctionValue( it->first, "$x" );\r
-      }\r
-    }\r
-    TheoryEngineModelBuilder::processBuildModel( m, fullModel );\r
-    //mark that the model has been set\r
-    fm->markModelSet();\r
-    //debug the model\r
-    debugModel( fm );\r
-  }else{\r
-    fm->initialize( d_considerAxioms );\r
-    //process representatives\r
-    fm->d_rep_id.clear();\r
-    fm->d_max.clear();\r
-    fm->d_min.clear();\r
-    Trace("qint-model") << std::endl << "Making representatives..." << std::endl;\r
-    for( std::map< TypeNode, std::vector< Node > >::iterator it = fm->d_rep_set.d_type_reps.begin();\r
-         it != fm->d_rep_set.d_type_reps.end(); ++it ){\r
-      if( it->first.isSort() ){\r
-        if( it->second.empty() ){\r
-          std::cout << "Empty rep for " << it->first << std::endl;\r
-          exit(0);\r
-        }\r
-        Trace("qint-model") << "Representatives for " << it->first << " : " << std::endl;\r
-        for( unsigned i=0; i<it->second.size(); i++ ){\r
-          Trace("qint-model") << i << " : " << it->second[i] << std::endl;\r
-          fm->d_rep_id[it->second[i]] = i;\r
-        }\r
-        fm->d_min[it->first] = it->second[0];\r
-        fm->d_max[it->first] = it->second[it->second.size()-1];\r
-      }else{\r
-        //TODO: enumerate?\r
-      }\r
-    }\r
-    Trace("qint-model") << std::endl << "Making function definitions..." << std::endl;\r
-    //construct the models for functions\r
-    for( std::map<Node, QIntDef * >::iterator it = fm->d_models.begin(); it != fm->d_models.end(); ++it ) {\r
-      Node f = it->first;\r
-      Trace("qint-model-debug") << "Building Model for " << f << std::endl;\r
-      //reset the model\r
-      //get all (non-redundant) f-applications\r
-      std::vector< Node > fapps;\r
-      Trace("qint-model-debug") << "Initial terms: " << std::endl;\r
-      for( size_t i=0; i<fm->d_uf_terms[f].size(); i++ ){\r
-        Node n = fm->d_uf_terms[f][i];\r
-        if( !n.getAttribute(NoMatchAttribute()) ){\r
-          Trace("qint-model-debug") << "  " << n << std::endl;\r
-          fapps.push_back( n );\r
-        }\r
-      }\r
-      if( fapps.empty() ){\r
-        //choose arbitrary value\r
-        Node mbt = d_qe->getTermDatabase()->getModelBasisOpTerm(f);\r
-        Trace("qint-model-debug") << "Initial terms empty, add " << mbt << std::endl;\r
-        fapps.push_back( mbt );\r
-      }\r
-      //construct the interval model\r
-      it->second->construct( fm, fapps );\r
-      Trace("qint-model-debug") << "Definition for " << f << " : " << std::endl;\r
-      it->second->debugPrint("qint-model-debug", fm, Node::null() );\r
-\r
-      it->second->simplify( fm, Node::null() );\r
-      Trace("qint-model") << "(Simplified) definition for " << f << " : " << std::endl;\r
-      it->second->debugPrint("qint-model", fm, Node::null() );\r
-\r
-      if( Debug.isOn("qint-model-debug") ){\r
-        for( size_t i=0; i<fm->d_uf_terms[f].size(); i++ ){\r
-          Node e = it->second->evaluate_n( fm, fm->d_uf_terms[f][i] );\r
-          Debug("qint-model-debug") << fm->d_uf_terms[f][i] << " evaluates to " << e << std::endl;\r
-          Assert( fm->areEqual( e, fm->d_uf_terms[f][i] ) );\r
-        }\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-\r
-//--------------------model checking---------------------------------------\r
-\r
-//do exhaustive instantiation\r
-bool QIntervalBuilder::doExhaustiveInstantiation( FirstOrderModel * fm, Node q, int effort ) {\r
-  Trace("qint-check") << "exhaustive instantiation " << q << " " << effort << std::endl;\r
-  if (effort==0) {\r
-\r
-    FirstOrderModelQInt * fmqint = fm->asFirstOrderModelQInt();\r
-    QIntDef qid;\r
-    doCheck( fmqint, q, qid, q[1], fmqint->d_var_order[q]->d_var_occur );\r
-    //now process entries\r
-    Trace("qint-inst") << "Interpretation for " << q << " is : " << std::endl;\r
-    qid.debugPrint( "qint-inst", fmqint, q );\r
-    Trace("qint-inst") << std::endl;\r
-    Debug("qint-check-debug2") << "Make iterator..." << std::endl;\r
-    QIntDefIter qdi( fmqint, q, &qid );\r
-    while( !qdi.isFinished() ){\r
-      if( qdi.getValue()!=d_true ){\r
-        Debug("qint-check-debug2") << "Set up vectors..." << std::endl;\r
-        std::vector< Node > l;\r
-        std::vector< Node > u;\r
-        std::vector< Node > inst;\r
-        qdi.getLowers( l );\r
-        qdi.getUppers( u );\r
-        Debug("qint-check-debug2") << "Get instantiation..." << std::endl;\r
-        if( fmqint->d_var_order[q]->getInstantiation( fmqint, l, u, inst ) ){\r
-          Trace("qint-inst") << "** Instantiate with ";\r
-          //just add the instance\r
-          for( unsigned j=0; j<inst.size(); j++) {\r
-            Trace("qint-inst") << inst[j] << " ";\r
-          }\r
-          Trace("qint-inst") << std::endl;\r
-          d_triedLemmas++;\r
-          if( d_qe->addInstantiation( q, inst ) ){\r
-            Trace("qint-inst") << "   ...added instantiation." << std::endl;\r
-            d_addedLemmas++;\r
-          }else{\r
-            Trace("qint-inst") << "   ...duplicate instantiation" << std::endl;\r
-            //verify that instantiation is witness for current entry\r
-            if( Debug.isOn("qint-check-debug2") ){\r
-              Debug("qint-check-debug2") << "Check if : ";\r
-              std::vector< Node > exp_inst;\r
-              for( unsigned i=0; i<fmqint->getOrderedNumVars( q ); i++ ){\r
-                int index = fmqint->getOrderedVarNumToVarNum( q, i );\r
-                exp_inst.push_back( inst[ index ] );\r
-                Debug("qint-check-debug2") << inst[index] << " ";\r
-              }\r
-              Debug("qint-check-debug2") << " evaluates to " << qdi.getValue() << std::endl;\r
-              Assert( qid.evaluate( fmqint, exp_inst )==qdi.getValue() );\r
-            }\r
-          }\r
-        }else{\r
-          Trace("qint-inst") << "** Spurious instantiation." << std::endl;\r
-        }\r
-      }\r
-      qdi.increment();\r
-    }\r
-  }\r
-  return true;\r
-}\r
-\r
-bool QIntervalBuilder::doCheck( FirstOrderModelQInt * m, Node q, QIntDef & qid, Node n,\r
-                                QIntVarNumIndex& vindex ) {\r
-  Assert( n.getKind()!=FORALL );\r
-  std::map< unsigned, QIntDef > children;\r
-  std::map< unsigned, Node > bchildren;\r
-  int varChCount = 0;\r
-  for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-    if( n[i].getKind()==FORALL ){\r
-      bchildren[i] = Node::null();\r
-    }else if( n[i].getKind() == BOUND_VARIABLE ){\r
-      varChCount++;\r
-      bchildren[i] = n[i];\r
-    }else if( m->hasTerm( n[i] ) ){\r
-      bchildren[i] = m->getUsedRepresentative( n[i] );\r
-    }else{\r
-      if( !doCheck( m, q, children[i], n[i], vindex.d_var_index[i] ) ){\r
-        bchildren[i] = Node::null();\r
-      }\r
-    }\r
-  }\r
-  Trace("qint-check-debug") << "Compute Interpretation of " << n << " " << n.getKind() << std::endl;\r
-  if( n.getKind() == APPLY_UF || n.getKind() == VARIABLE || n.getKind() == SKOLEM ){\r
-    Node op = n.getKind() == APPLY_UF ? n.getOperator() : n;\r
-    //uninterpreted compose\r
-    qid.construct_compose( m, q, n, m->d_models[op], children, bchildren, varChCount, vindex );\r
-  }else if( !qid.construct_compose( m, q, n, NULL, children, bchildren, varChCount, vindex ) ){\r
-    Trace("qint-check-debug") << "** Cannot produce definition for " << n << std::endl;\r
-    return false;\r
-  }\r
-  Trace("qint-check-debug2") << "Definition for " << n << " is : " << std::endl;\r
-  qid.debugPrint("qint-check-debug2", m, q);\r
-  qid.simplify( m, q );\r
-  Trace("qint-check-debug") << "(Simplified) Definition for " << n << " is : " << std::endl;\r
-  qid.debugPrint("qint-check-debug", m, q);\r
-  Trace("qint-check-debug") << std::endl;\r
-  Assert( qid.isTotal( m, q ) );\r
-  return true;\r
-}\r
+/*********************                                                        */
+/*! \file qinterval_builder.cpp
+ ** \verbatim
+ ** Original author: Andrew Reynolds
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2013  New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Implementation of qinterval builder
+ **/
+
+
+#include "theory/quantifiers/qinterval_builder.h"
+#include "theory/quantifiers/term_database.h"
+
+
+using namespace std;
+using namespace CVC4;
+using namespace CVC4::kind;
+using namespace CVC4::context;
+using namespace CVC4::theory;
+using namespace CVC4::theory::quantifiers;
+
+//lower bound is exclusive
+//upper bound is inclusive
+
+struct QIntSort
+{
+  FirstOrderModelQInt * m;
+  bool operator() (Node i, Node j) {
+    return m->isLessThan( i, j );
+  }
+};
+
+void QIntDef::init_vec( FirstOrderModelQInt * m, Node q, std::vector< Node >& l, std::vector< Node >& u ) {
+  for( unsigned i=0; i<m->getOrderedNumVars( q ); i++ ){
+    l.push_back( Node::null() );
+    u.push_back( m->getMaximum( m->getOrderedVarType( q, i ) ) );
+  }
+}
+
+void QIntDef::debugPrint( const char * c, FirstOrderModelQInt * m, Node q, std::vector< Node >& l, std::vector< Node >& u )
+{
+  Trace(c) << "( ";
+  for( unsigned i=0; i<l.size(); i++ ){
+    if( i>0 ) Trace(c) << ", ";
+    //Trace(c) << l[i] << "..." << u[i];
+    int lindex = l[i].isNull() ? 0 : m->getRepId( l[i] ) + 1;
+    int uindex = m->getRepId( u[i] );
+    Trace(c) << lindex << "..." << uindex;
+  }
+  Trace(c) << " )";
+}
+
+
+int QIntDef::getEvIndex( FirstOrderModelQInt * m, Node n, bool exc ) {
+  if( n.isNull() ){
+    Assert( exc );
+    return 0;
+  }else{
+    int min = 0;
+    int max = (int)(d_def_order.size()-1);
+    while( min!=max ){
+      int index = (min+max)/2;
+      Assert( index>=0 && index<(int)d_def_order.size() );
+      if( n==d_def_order[index] ){
+        max = index;
+        min = index;
+      }else if( m->isLessThan( n, d_def_order[index] ) ){
+        max = index;
+      }else{
+        min = index+1;
+      }
+    }
+    if( n==d_def_order[min] && exc ){
+      min++;
+    }
+    Assert( min>=0 && min<(int)d_def_order.size() );
+    if( ( min!=0 && !m->isLessThan( d_def_order[min-1], n ) && ( !exc || d_def_order[min-1]!=n ) ) ||
+        ( ( exc || d_def_order[min]!=n ) && !m->isLessThan( n, d_def_order[min] ) ) ){
+      Debug("qint-error") << "ERR size : " << d_def_order.size() << ", exc : " << exc << std::endl;
+      for( unsigned i=0; i<d_def_order.size(); i++ ){
+        Debug("qint-error") << "ERR ch #" << i << " : " << d_def_order[i];
+        Debug("qint-error") << " " << m->getRepId( d_def_order[i] ) << std::endl;
+      }
+      Debug("qint-error") << " : " << n << " " << min << " " << m->getRepId( n ) << std::endl;
+    }
+
+    Assert( min==0 || m->isLessThan( d_def_order[min-1], n ) || ( exc && d_def_order[min-1]==n ) );
+    Assert( ( !exc && n==d_def_order[min] ) || m->isLessThan( n, d_def_order[min] ) );
+    return min;
+  }
+}
+
+void QIntDef::addEntry( FirstOrderModelQInt * m, Node q, std::vector< Node >& l, std::vector< Node >& u,
+                        Node v, unsigned depth ) {
+  if( depth==0 ){
+    Trace("qint-compose-debug") << "Add entry ";
+    debugPrint( "qint-compose-debug", m, q, l, u );
+    Trace("qint-compose-debug") << " -> " << v << "..." << std::endl;
+  }
+  //Assert( false );
+  if( depth==u.size() ){
+    Assert( d_def_order.empty() );
+    Assert( v.isNull() || v.isConst() || ( v.getType().isSort() && m->getRepId( v )!=-1 ) );
+    d_def_order.push_back( v );
+  }else{
+    /*
+    if( !d_def_order.empty() &&
+        ( l[depth].isNull() || m->isLessThan( l[depth], d_def_order[d_def_order.size()-1] ) ) ){
+      int startEvIndex = getEvIndex( m, l[depth], true );
+      int endEvIndex;
+      if( m->isLessThan( u[depth], d_def_order[d_def_order.size()-1] ) ){
+        endEvIndex = getEvIndex( m, u[depth] );
+      }else{
+        endEvIndex = d_def_order.size()-1;
+      }
+      Trace("qint-compose-debug2") << this << " adding for bounds " << l[depth] << "..." << u[depth] << std::endl;
+      for( int i=startEvIndex; i<=endEvIndex; i++ ){
+        Trace("qint-compose-debug2") << this << " add entry " << d_def_order[i] << std::endl;
+        d_def[d_def_order[i]].addEntry( m, q, l, u, v, depth+1 );
+      }
+    }
+    if( !d_def_order.empty() &&
+         d_def.find(u[depth])==d_def.end() &&
+         !m->isLessThan( d_def_order[d_def_order.size()-1], u[depth] ) ){
+      Trace("qint-compose-debug2") << "Bad : depth : " << depth << std::endl;
+    }
+    Assert( d_def_order.empty() ||
+            d_def.find(u[depth])!=d_def.end() ||
+            m->isLessThan( d_def_order[d_def_order.size()-1], u[depth] ) );
+
+    if( d_def_order.empty() || m->isLessThan( d_def_order[d_def_order.size()-1], u[depth] ) ){
+      Trace("qint-compose-debug2") << this << " add entry new : " << u[depth] << std::endl;
+      d_def_order.push_back( u[depth] );
+      d_def[u[depth]].addEntry( m, q, l, u, v, depth+1 );
+    }
+    */
+    //%%%%%%
+    bool success = true;
+    int nnum = m->getVarOrder( q )->getNextNum( depth );
+    Node pl;
+    Node pu;
+    if( nnum!=-1 ){
+      Trace("qint-compose-debug2") << "...adding entry #" << depth << " is #" << nnum << std::endl;
+      //Assert( l[nnum].isNull() || l[nnum]==l[depth] || m->isLessThan( l[nnum], l[depth] ) );
+      //Assert( u[nnum]==u[depth] || m->isLessThan( u[depth], u[nnum] ) );
+      pl = l[nnum];
+      pu = u[nnum];
+      if( !m->doMeet( l[nnum], u[nnum], l[depth], u[depth], l[nnum], u[nnum] ) ){
+        success = false;
+      }
+    }
+    //%%%%%%
+    if( success ){
+      Node r = u[depth];
+      if( d_def.find( r )!=d_def.end() ){
+        d_def[r].addEntry( m, q, l, u, v, depth+1 );
+      }else{
+        if( !d_def_order.empty() &&
+            !m->isLessThan( d_def_order[d_def_order.size()-1], u[depth] ) ){
+          Trace("qint-compose-debug2") << "Bad : depth : " << depth << " ";
+          Trace("qint-compose-debug2") << d_def_order[d_def_order.size()-1] << " " << u[depth] << std::endl;
+        }
+        Assert( d_def_order.empty() || m->isLessThan( d_def_order[d_def_order.size()-1], r ) );
+        d_def_order.push_back( r );
+        d_def[r].addEntry( m, q, l, u, v, depth+1 );
+      }
+    }
+    if( nnum!=-1 ){
+      l[nnum] = pl;
+      u[nnum] = pu;
+    }
+  }
+}
+
+Node QIntDef::simplify_r( FirstOrderModelQInt * m, Node q, std::vector< Node >& il, std::vector< Node >& iu,
+                          unsigned depth ) {
+  if( d_def.empty() ){
+    if( d_def_order.size()!=0 ){
+      Debug("qint-error") << "Simplify, size = " << d_def_order.size() << std::endl;
+    }
+    Assert( d_def_order.size()==1 );
+    return d_def_order[0];
+  }else{
+    Assert( !d_def_order.empty() );
+    std::vector< Node > newDefs;
+    Node curr;
+    for( unsigned i=0; i<d_def_order.size(); i++ ){
+      Node n = d_def[d_def_order[i]].simplify_r( m, q, il, iu, depth+1 );
+      if( i>0 ){
+        if( n==curr && !n.isNull() ){
+          d_def.erase( d_def_order[i-1] );
+        }else{
+          newDefs.push_back( d_def_order[i-1] );
+        }
+      }
+      curr = n;
+    }
+    newDefs.push_back( d_def_order[d_def_order.size()-1] );
+    d_def_order.clear();
+    d_def_order.insert( d_def_order.end(), newDefs.begin(), newDefs.end() );
+    return d_def_order.size()==1 ? curr : Node::null();
+  }
+}
+
+Node QIntDef::simplify( FirstOrderModelQInt * m, Node q ) {
+  std::vector< Node > l;
+  std::vector< Node > u;
+  if( !q.isNull() ){
+    //init_vec( m, q, l, u );
+  }
+  return simplify_r( m, q, l, u, 0 );
+}
+
+bool QIntDef::isTotal_r( FirstOrderModelQInt * m, Node q, std::vector< Node >& l, std::vector< Node >& u,
+                         unsigned depth ) {
+  if( d_def_order.empty() ){
+    return false;
+  }else if( d_def.empty() ){
+    return true;
+  }else{
+    //get the current maximum
+    Node mx;
+    if( !q.isNull() ){
+      int pnum = m->getVarOrder( q )->getPrevNum( depth );
+      if( pnum!=-1 ){
+        mx = u[pnum];
+      }
+    }
+    if( mx.isNull() ){
+      mx = m->getMaximum( d_def_order[d_def_order.size()-1].getType() );
+    }
+    //if not current maximum
+    if( d_def_order[d_def_order.size()-1]!=mx ){
+      return false;
+    }else{
+      Node pu = u[depth];
+      for( unsigned i=0; i<d_def_order.size(); i++ ){
+        u[depth] = d_def_order[i];
+        if( !d_def[d_def_order[i]].isTotal_r( m, q, l, u, depth+1 ) ){
+          return false;
+        }
+      }
+      u[depth] = pu;
+      return true;
+    }
+  }
+}
+
+bool QIntDef::isTotal( FirstOrderModelQInt * m, Node q ) {
+  std::vector< Node > l;
+  std::vector< Node > u;
+  if( !q.isNull() ){
+    init_vec( m, q, l, u );
+  }
+  return isTotal_r( m, q, l, u, 0 );
+}
+
+void QIntDef::construct_compose_r( FirstOrderModelQInt * m, Node q,
+                                    std::vector< Node >& l, std::vector< Node >& u,
+                                    Node n, QIntDef * f,
+                                    std::vector< Node >& args,
+                                    std::map< unsigned, QIntDef >& children,
+                                    std::map< unsigned, Node >& bchildren,
+                                    QIntVarNumIndex& vindex, unsigned depth ) {
+  //check for short circuit
+  if( !f ){
+    if( !args.empty() ){
+      if( ( n.getKind()==OR && args[args.size()-1]==m->d_true ) ||
+          ( n.getKind()==AND && args[args.size()-1]==m->d_false ) ){
+        addEntry( m, q, l, u, args[args.size()-1] );
+        return;
+      }
+    }
+  }
+
+  for( unsigned i=0; i<depth; i++ ) { Trace("qint-compose") << "  "; }
+  Trace("qint-compose") << (f ? "U" : "I" ) << "C( ";
+  for( unsigned i=0; i<l.size(); i++ ){
+    if( i>0 ) Trace("qint-compose") << ", ";
+    //Trace("qint-compose") << l[i] << "..." << u[i];
+    int lindex = l[i].isNull() ? 0 : m->getRepId( l[i] ) + 1;
+    int uindex = m->getRepId( u[i] );
+    Trace( "qint-compose" ) << lindex << "..." << uindex;
+  }
+  Trace("qint-compose") << " )...";
+
+  //finished?
+  if( ( f && f->d_def.empty() ) || args.size()==n.getNumChildren() ){
+    if( f ){
+      Assert( f->d_def_order.size()==1 );
+      Trace("qint-compose") << "UVALUE(" << f->d_def_order[0] << ")" << std::endl;
+      addEntry( m, q, l, u, f->d_def_order[0] );
+    }else{
+      Node nn;
+      bool nnSet = false;
+      for( unsigned i=0; i<args.size(); i++ ){
+        if( args[i].isNull() ){
+          nnSet = true;
+          break;
+        }
+      }
+      if( !nnSet ){
+        if( n.getKind()==EQUAL ){
+          nn = NodeManager::currentNM()->mkConst( args[0]==args[1] );
+        }else{
+          //apply the operator to args
+          nn = NodeManager::currentNM()->mkNode( n.getKind(), args );
+          nn = Rewriter::rewrite( nn );
+        }
+      }
+      Trace("qint-compose") << "IVALUE(" << nn << ")" << std::endl;
+      addEntry( m, q, l, u, nn );
+      Trace("qint-compose-debug2") << "...added entry." << std::endl;
+    }
+  }else{
+    //if a non-simple child
+    if( children.find( depth )!=children.end() ){
+      //***************************
+      Trace("qint-compose") << "compound child, recurse" << std::endl;
+      std::vector< int > currIndex;
+      std::vector< int > endIndex;
+      std::vector< Node > prevL;
+      std::vector< Node > prevU;
+      std::vector< QIntDef * > visited;
+      do{
+        Assert( currIndex.size()==visited.size() );
+
+        //populate the vectors
+        while( visited.size()<m->getOrderedNumVars( q ) ){
+          unsigned i = visited.size();
+          QIntDef * qq = visited.empty() ? &children[depth] : visited[i-1]->getChild( currIndex[i-1] );
+          visited.push_back( qq );
+          Node qq_mx = qq->getMaximum();
+          Trace("qint-compose-debug2") << "...Get ev indices " << i << " " << l[i] << " " << u[i] << std::endl;
+          currIndex.push_back( qq->getEvIndex( m, l[i], true ) );
+          Trace("qint-compose-debug2") << "...Done get curr index " << currIndex[currIndex.size()-1] << std::endl;
+          if( m->isLessThan( qq_mx, u[i] ) ){
+            endIndex.push_back( qq->getNumChildren()-1 );
+          }else{
+            endIndex.push_back( qq->getEvIndex( m, u[i] ) );
+          }
+          Trace("qint-compose-debug2") << "...Done get end index " << endIndex[endIndex.size()-1] << std::endl;
+          prevL.push_back( l[i] );
+          prevU.push_back( u[i] );
+          if( !m->doMeet( prevL[i], prevU[i],
+                          qq->getLower( currIndex[i] ), qq->getUpper( currIndex[i] ), l[i], u[i] ) ){
+            Assert( false );
+          }
+        }
+        for( unsigned i=0; i<depth; i++ ) { Trace("qint-compose") << "  "; }
+        for( unsigned i=0; i<currIndex.size(); i++ ){
+          Trace("qint-compose") << "[" << currIndex[i] << "/" << endIndex[i] << "]";
+        }
+        Trace("qint-compose") << std::endl;
+        //consider the current
+        int activeIndex = visited.size()-1;
+        QIntDef * qa = visited.empty() ? &children[depth] : visited[activeIndex]->getChild( currIndex[activeIndex] );
+        if( f ){
+          int fIndex = f->getEvIndex( m, qa->getValue() );
+          construct_compose_r( m, q, l, u, n, f->getChild( fIndex ), args, children, bchildren, vindex, depth+1 );
+        }else{
+          args.push_back( qa->getValue() );
+          construct_compose_r( m, q, l, u, n, f, args, children, bchildren, vindex, depth+1 );
+          args.pop_back();
+        }
+
+        //increment the index (if possible)
+        while( activeIndex>=0 && currIndex[activeIndex]==endIndex[activeIndex] ){
+          currIndex.pop_back();
+          endIndex.pop_back();
+          l[activeIndex] = prevL[activeIndex];
+          u[activeIndex] = prevU[activeIndex];
+          prevL.pop_back();
+          prevU.pop_back();
+          visited.pop_back();
+          activeIndex--;
+        }
+        if( activeIndex>=0 ){
+          for( unsigned i=0; i<depth; i++ ) { Trace("qint-compose") << "  "; }
+          Trace("qint-compose-debug") << "Increment at " << activeIndex << std::endl;
+          currIndex[activeIndex]++;
+          if( !m->doMeet( prevL[activeIndex], prevU[activeIndex],
+                          visited[activeIndex]->getLower( currIndex[activeIndex] ),
+                          visited[activeIndex]->getUpper( currIndex[activeIndex] ),
+                          l[activeIndex], u[activeIndex] ) ){
+            Assert( false );
+          }
+        }
+      }while( !visited.empty() );
+      //***************************
+    }else{
+      Assert( bchildren.find( depth )!=bchildren.end() );
+      Node v = bchildren[depth];
+      if( f ){
+        if( v.getKind()==BOUND_VARIABLE ){
+          int vn = vindex.d_var_num[depth];
+          Trace("qint-compose") << "variable #" << vn << ", recurse" << std::endl;
+          //int vn = m->getOrderedVarOccurId( q, n, depth );
+          Trace("qint-compose-debug") << "-process " << v << ", which is var #" << vn << std::endl;
+          Node lprev = l[vn];
+          Node uprev = u[vn];
+          //restrict to last variable in order
+          int pnum = m->getVarOrder( q )->getPrevNum( vn );
+          if( pnum!=-1 ){
+            Trace("qint-compose-debug") << "-restrict to var #" << pnum << " " << l[pnum] << " " << u[pnum] << std::endl;
+            l[vn] = l[pnum];
+            u[vn] = u[pnum];
+          }
+          int startIndex = f->getEvIndex( m, l[vn], true );
+          int endIndex = f->getEvIndex( m, u[vn] );
+          Trace("qint-compose-debug") << "--will process " << startIndex << " " << endIndex << std::endl;
+          for( int i=startIndex; i<=endIndex; i++ ){
+            if( m->doMeet( lprev, uprev, f->getLower( i ), f->getUpper( i ), l[vn], u[vn] ) ){
+              construct_compose_r( m, q, l, u, n, f->getChild( i ), args, children, bchildren, vindex, depth+1 );
+            }else{
+              Assert( false );
+            }
+          }
+          l[vn] = lprev;
+          u[vn] = uprev;
+        }else{
+          Trace("qint-compose") << "value, recurse" << std::endl;
+          //simple
+          int ei = f->getEvIndex( m, v );
+          construct_compose_r( m, q, l, u, n, f->getChild( ei ), args, children, bchildren, vindex, depth+1 );
+        }
+      }else{
+        Trace("qint-compose") << "value, recurse" << std::endl;
+        args.push_back( v );
+        construct_compose_r( m, q, l, u, n, f, args, children, bchildren, vindex, depth+1 );
+        args.pop_back();
+      }
+    }
+  }
+}
+
+
+void QIntDef::construct_enum_r( FirstOrderModelQInt * m, Node q, unsigned vn, unsigned depth, Node v ) {
+  if( depth==m->getOrderedNumVars( q ) ){
+    Assert( !v.isNull() );
+    d_def_order.push_back( v );
+  }else{
+    TypeNode tn = m->getOrderedVarType( q, depth );
+    //int vnum = m->getVarOrder( q )->getVar( depth )==
+    if( depth==vn ){
+      for( unsigned i=0; i<m->d_rep_set.d_type_reps[tn].size(); i++ ){
+        Node vv = m->d_rep_set.d_type_reps[tn][i];
+        d_def_order.push_back( vv );
+        d_def[vv].construct_enum_r( m, q, vn, depth+1, vv );
+      }
+    }else if( m->getVarOrder( q )->getVar( depth )==m->getVarOrder( q )->getVar( vn ) && depth>vn ){
+      d_def_order.push_back( v );
+      d_def[v].construct_enum_r( m, q, vn, depth+1, v );
+    }else{
+      Node mx = m->getMaximum( tn );
+      d_def_order.push_back( mx );
+      d_def[mx].construct_enum_r( m, q, vn, depth+1, v );
+    }
+  }
+}
+
+bool QIntDef::construct_enum( FirstOrderModelQInt * m, Node q, unsigned vn ) {
+  TypeNode tn = m->getOrderedVarType( q, vn );
+  if( tn.isSort() ){
+    construct_enum_r( m, q, vn, 0, Node::null() );
+    return true;
+  }else{
+    return false;
+  }
+}
+
+bool QIntDef::construct_compose( FirstOrderModelQInt * m, Node q, Node n, QIntDef * f,
+                                 std::map< unsigned, QIntDef >& children,
+                                 std::map< unsigned, Node >& bchildren, int varChCount,
+                                 QIntVarNumIndex& vindex ) {
+ Trace("qint-compose") << "Do " << (f ? "uninterpreted" : "interpreted");
+ Trace("qint-compose") << " compose, var count = " << varChCount << "..." << std::endl;
+  std::vector< Node > l;
+  std::vector< Node > u;
+  init_vec( m, q, l, u );
+  if( varChCount==0 || f ){
+    //standard (no variable child) interpreted compose, or uninterpreted compose
+    std::vector< Node > args;
+    construct_compose_r( m, q, l, u, n, f, args, children, bchildren, vindex, 0 );
+  }else{
+    //special cases
+    bool success = false;
+    int varIndex = ( bchildren.find( 0 )!=bchildren.end() && bchildren[0].getKind()==BOUND_VARIABLE ) ? 0 : 1;
+    if( varChCount>1 ){
+      if( n.getKind()==EQUAL ){
+        //make it an enumeration
+        unsigned vn = vindex.d_var_num[0];
+        if( children[0].construct_enum( m, q, vn ) ){
+          bchildren.erase( 0 );
+          varIndex = 1;
+          success = true;
+        }
+      }
+    }else{
+      success = n.getKind()==EQUAL;
+    }
+    if( success ){
+      int oIndex = varIndex==0 ? 1 : 0;
+      Node v = bchildren[varIndex];
+      unsigned vn = vindex.d_var_num[varIndex];
+      if( children.find( oIndex )==children.end() ){
+        Assert( bchildren.find( oIndex )!=bchildren.end() );
+        Node at = bchildren[oIndex];
+        Trace("qint-icompose") << "Basic child, " << at << " with var " << v << std::endl;
+        Node prev = m->getPrev( bchildren[oIndex].getType(), bchildren[oIndex] );
+        Node above = u[vn];
+        if( !prev.isNull() ){
+          u[vn] = prev;
+          addEntry( m, q, l, u, NodeManager::currentNM()->mkConst( false ) );
+        }
+        l[vn] = prev;
+        u[vn] = at;
+        addEntry( m, q, l, u, NodeManager::currentNM()->mkConst( true ) );
+        if( at!=above ){
+          l[vn] = at;
+          u[vn] = above;
+          addEntry( m, q, l, u, NodeManager::currentNM()->mkConst( false ) );
+        }
+      }else{
+        QIntDef * qid = &children[oIndex];
+        qid->debugPrint("qint-icompose", m, q );
+        Trace("qint-icompose") << " against variable..." << v << ", which is var #" << vn << std::endl;
+
+        TypeNode tn = v.getType();
+        QIntDefIter qdi( m, q, qid );
+        while( !qdi.isFinished() ){
+          std::vector< Node > us;
+          qdi.getUppers( us );
+          std::vector< Node > ls;
+          qdi.getLowers( ls );
+          qdi.debugPrint( "qint-icompose" );
+
+          Node n_below = ls[vn];
+          Node n_prev = m->getPrev( tn, qdi.getValue() );
+          Node n_at = qdi.getValue();
+          Node n_above = us[vn];
+          Trace("qint-icompose") << n_below << " < " << n_prev << " < " << n_at << " < " << n_above << std::endl;
+          if( n.getKind()==EQUAL ){
+            bool atLtAbove = m->isLessThan( n_at, n_above );
+            Node currL = n_below;
+            if( n_at==n_above || atLtAbove ){
+              //add for value (at-1)
+              if( !n_prev.isNull() && ( n_below.isNull() || m->isLessThan( n_below, n_prev ) ) ){
+                ls[vn] = currL;
+                us[vn] = n_prev;
+                currL = n_prev;
+                Trace("qint-icompose") << "-add entry(-) at " << ls[vn] << "..." << us[vn] << std::endl;
+                addEntry( m, q, ls, us, NodeManager::currentNM()->mkConst( false ) );
+              }
+              //add for value (at)
+              if( ( n_below.isNull() || m->isLessThan( n_below, n_at ) ) && atLtAbove ){
+                ls[vn] = currL;
+                us[vn] = n_at;
+                currL = n_at;
+                Trace("qint-icompose") << "-add entry(=) at " << ls[vn] << "..." << us[vn] << std::endl;
+                addEntry( m, q, ls, us, NodeManager::currentNM()->mkConst( true ) );
+              }
+            }
+            ls[vn] = currL;
+            us[vn] = n_above;
+            Trace("qint-icompose") << "-add entry(+) at " << ls[vn] << "..." << us[vn] << std::endl;
+            addEntry( m, q, ls, us, NodeManager::currentNM()->mkConst( n_at==n_above ) );
+          }else{
+            return false;
+          }
+          qdi.increment();
+
+          Trace("qint-icompose-debug") << "Now : " << std::endl;
+          debugPrint("qint-icompose-debug", m, q );
+          Trace("qint-icompose-debug") << std::endl;
+        }
+      }
+
+      Trace("qint-icompose") << "Result : " << std::endl;
+      debugPrint("qint-icompose", m, q );
+      Trace("qint-icompose") << std::endl;
+
+    }else{
+      return false;
+    }
+  }
+  Trace("qint-compose") << "Done i-compose" << std::endl;
+  return true;
+}
+
+
+void QIntDef::construct( FirstOrderModelQInt * m, std::vector< Node >& fapps, unsigned depth ) {
+  d_def.clear();
+  d_def_order.clear();
+  Assert( !fapps.empty() );
+  if( depth==fapps[0].getNumChildren() ){
+    //get representative in model for this term
+    Assert( fapps.size()>=1 );
+    Node r = m->getUsedRepresentative( fapps[0] );
+    d_def_order.push_back( r );
+  }else{
+    std::map< Node, std::vector< Node > > fapp_child;
+    //partition based on evaluations of fapps[1][depth]....fapps[n][depth]
+    for( unsigned i=0; i<fapps.size(); i++ ){
+      Node r = m->getUsedRepresentative( fapps[i][depth] );
+      fapp_child[r].push_back( fapps[i] );
+    }
+    //sort by QIntSort
+    for( std::map< Node, std::vector< Node > >::iterator it = fapp_child.begin(); it != fapp_child.end(); ++it ){
+      d_def_order.push_back( it->first );
+    }
+    QIntSort qis;
+    qis.m = m;
+    std::sort( d_def_order.begin(), d_def_order.end(), qis );
+    //construct children
+    for( unsigned i=0; i<d_def_order.size(); i++ ){
+      Node n = d_def_order[i];
+      if( i==d_def_order.size()-1 ){
+        d_def_order[i] = m->getMaximum( d_def_order[i].getType() );
+      }
+      Debug("qint-model-debug2") << "Construct for " << n << ", terms = " << fapp_child[n].size() << std::endl;
+      d_def[d_def_order[i]].construct( m, fapp_child[n], depth+1 );
+    }
+  }
+}
+
+Node QIntDef::getFunctionValue( FirstOrderModelQInt * m, std::vector< Node >& vars, unsigned depth ) {
+  if( d_def.empty() ){
+    Assert( d_def_order.size()==1 );
+    //must convert to actual domain constant
+    if( d_def_order[0].getType().isSort() ){
+      return m->d_rep_set.d_type_reps[ d_def_order[0].getType() ][ m->getRepId( d_def_order[0] ) ];
+    }else{
+      return m->getUsedRepresentative( d_def_order[0] );
+    }
+  }else{
+    TypeNode tn = vars[depth].getType();
+    Node curr;
+    int rep_id = m->d_rep_set.getNumRepresentatives( tn );
+    for( int i=(int)(d_def_order.size()-1); i>=0; i-- ){
+      int curr_rep_id = i==0 ? 0 : m->getRepId( d_def_order[i-1] )+1;
+      Node ccurr = d_def[d_def_order[i]].getFunctionValue( m, vars, depth+1 );
+      if( curr.isNull() ){
+        curr = ccurr;
+      }else{
+        std::vector< Node > c;
+        Assert( curr_rep_id<rep_id );
+        for( int j=curr_rep_id; j<rep_id; j++ ){
+          c.push_back( vars[depth].eqNode( m->d_rep_set.d_type_reps[tn][j] ) );
+        }
+        Node cond = c.size()==1 ? c[0] : NodeManager::currentNM()->mkNode( OR, c );
+        curr = NodeManager::currentNM()->mkNode( ITE, cond, ccurr, curr );
+      }
+      rep_id = curr_rep_id;
+    }
+    return curr;
+  }
+}
+
+Node QIntDef::evaluate_r( FirstOrderModelQInt * m, std::vector< Node >& reps, unsigned depth ) {
+  if( depth==reps.size() ){
+    Assert( d_def_order.size()==1 );
+    return d_def_order[0];
+  }else{
+    if( d_def.find( reps[depth] )!=d_def.end() ){
+      return d_def[reps[depth]].evaluate_r( m, reps, depth+1 );
+    }else{
+      int ei = getEvIndex( m, reps[depth] );
+      return d_def[d_def_order[ei]].evaluate_r( m, reps, depth+1 );
+    }
+  }
+}
+Node QIntDef::evaluate_n_r( FirstOrderModelQInt * m, Node n, unsigned depth ) {
+  if( depth==n.getNumChildren() ){
+    Assert( d_def_order.size()==1 );
+    return d_def_order[0];
+  }else{
+    Node r = m->getUsedRepresentative( n[depth] );
+    if( d_def.find( r )!=d_def.end() ){
+      return d_def[r].evaluate_n_r( m, n, depth+1 );
+    }else{
+      int ei = getEvIndex( m, r );
+      return d_def[d_def_order[ei]].evaluate_n_r( m, n, depth+1 );
+    }
+  }
+}
+
+
+
+QIntDef * QIntDef::getChild( unsigned i ) {
+  Assert( i<d_def_order.size() );
+  Assert( d_def.find( d_def_order[i] )!=d_def.end() );
+  return &d_def[ d_def_order[i] ];
+}
+
+void QIntDef::debugPrint( const char * c, FirstOrderModelQInt * m, Node q, int t ) {
+  /*
+  for( unsigned i=0; i<d_def_order.size(); i++ ){
+    for( int j=0; j<t; j++ ) { Trace(c) << " "; }
+    //Trace(c) << this << " ";
+    Trace(c) << d_def_order[i] << " : " << std::endl;
+    if( d_def.find( d_def_order[i] )!=d_def.end() ){
+      d_def[d_def_order[i]].debugPrint( c, m, t+1 );
+    }
+  }
+  */
+  //if( t==0 ){
+  QIntDefIter qdi( m, q, this );
+  while( !qdi.isFinished() ){
+    qdi.debugPrint( c, t );
+    qdi.increment();
+  }
+  //}
+}
+
+
+QIntDefIter::QIntDefIter( FirstOrderModelQInt * m, Node q, QIntDef * qid ) : d_fm( m ), d_q( q ){
+  resetIndex( qid );
+}
+
+void QIntDefIter::debugPrint( const char * c, int t ) {
+  //Trace( c ) << getSize() << " " << d_index_visited.size() << " ";
+  for( int j=0; j<t; j++ ) { Trace(c) << " "; }
+  std::vector< Node > l;
+  std::vector< Node > u;
+  getLowers( l );
+  getUppers( u );
+  QIntDef::debugPrint( c, d_fm, d_q, l, u );
+  Trace( c ) << " -> " << getValue() << std::endl;
+}
+
+void QIntDefIter::resetIndex( QIntDef * qid ){
+  //std::cout << "check : " << qid << " " << qid->d_def_order.size() << " " << qid->d_def.size() << std::endl;
+  if( !qid->d_def.empty() ){
+    //std::cout << "add to visited " <<  qid << std::endl;
+    d_index.push_back( 0 );
+    d_index_visited.push_back( qid );
+    resetIndex( qid->getChild( 0 ) );
+  }
+}
+
+bool QIntDefIter::increment( int index ) {
+  if( !isFinished() ){
+    index = index==-1 ? (int)(d_index.size()-1) : index;
+    while( (int)(d_index.size()-1)>index ){
+      //std::cout << "remove from visit 1 " << std::endl;
+      d_index.pop_back();
+      d_index_visited.pop_back();
+    }
+    while( index>=0 && d_index[index]>=(int)(d_index_visited[index]->d_def_order.size()-1) ){
+      //std::cout << "remove from visit " << d_index_visited[ d_index_visited.size()-1 ] << std::endl;
+      d_index.pop_back();
+      d_index_visited.pop_back();
+      index--;
+    }
+    if( index>=0 ){
+      //std::cout << "increment at index = " << index << std::endl;
+      d_index[index]++;
+      resetIndex( d_index_visited[index]->getChild( d_index[index] ) );
+      return true;
+    }else{
+      d_index.clear();
+      return false;
+    }
+  }else{
+    return false;
+  }
+}
+
+Node QIntDefIter::getLower( int index ) {
+  if( d_index[index]==0 && !d_q.isNull() ){
+    int pnum = d_fm->getVarOrder( d_q )->getPrevNum( index );
+    if( pnum!=-1 ){
+      return getLower( pnum );
+    }
+  }
+  return d_index_visited[index]->getLower( d_index[index] );
+}
+
+Node QIntDefIter::getUpper( int index ) {
+  return d_index_visited[index]->getUpper( d_index[index] );
+}
+
+void QIntDefIter::getLowers( std::vector< Node >& reps ) {
+  for( unsigned i=0; i<getSize(); i++ ){
+    bool added = false;
+    if( d_index[i]==0 && !d_q.isNull() ){
+      int pnum = d_fm->getVarOrder( d_q )->getPrevNum( i );
+      if( pnum!=-1 ){
+        added = true;
+        reps.push_back( reps[pnum] );
+      }
+    }
+    if( !added ){
+      reps.push_back( getLower( i ) );
+    }
+  }
+}
+
+void QIntDefIter::getUppers( std::vector< Node >& reps ) {
+  for( unsigned i=0; i<getSize(); i++ ){
+    reps.push_back( getUpper( i ) );
+  }
+}
+
+Node QIntDefIter::getValue() {
+  return d_index_visited[ d_index_visited.size()-1 ]->getChild( d_index[d_index.size()-1] )->getValue();
+}
+
+
+//------------------------variable ordering----------------------------
+
+QuantVarOrder::QuantVarOrder( Node q ) : d_q( q ) {
+  d_var_count = 0;
+  initialize( q[1], 0, d_var_occur );
+}
+
+int QuantVarOrder::initialize( Node n, int minVarIndex, QIntVarNumIndex& vindex ) {
+  if( n.getKind()!=FORALL ){
+    //std::vector< Node > vars;
+    //std::vector< int > args;
+    int procVarOn = n.getKind()==APPLY_UF ? 0 : 1;
+    for( int r=0; r<=procVarOn; r++ ){
+      for( unsigned i=0; i<n.getNumChildren(); i++ ){
+        if( n[i].getKind()==BOUND_VARIABLE && r==procVarOn ){
+          int occ_index = -1;
+          for( unsigned j=0; j<d_var_to_num[n[i]].size(); j++ ){
+            if( d_var_to_num[n[i]][j]>=minVarIndex ){
+              occ_index = d_var_to_num[n[i]][j];
+            }
+          }
+          if( occ_index==-1 ){
+            //need to assign new
+            d_num_to_var[d_var_count] = n[i];
+            if( !d_var_to_num[n[i]].empty() ){
+              int v = d_var_to_num[n[i]][ d_var_to_num[n[i]].size()-1 ];
+              d_num_to_prev_num[ d_var_count ] = v;
+              d_num_to_next_num[ v ] = d_var_count;
+            }
+            d_var_num_index[ d_var_count ] = d_var_to_num[n[i]].size();
+            d_var_to_num[n[i]].push_back( d_var_count );
+            occ_index = d_var_count;
+            d_var_count++;
+          }
+          vindex.d_var_num[i] = occ_index;
+          minVarIndex = occ_index;
+        }else if( r==0 ){
+          minVarIndex = initialize( n[i], minVarIndex, vindex.d_var_index[i] );
+        }
+      }
+    }
+  }
+  return minVarIndex;
+}
+
+bool QuantVarOrder::getInstantiation( FirstOrderModelQInt * m, std::vector< Node >& l, std::vector< Node >& u,
+                                      std::vector< Node >& inst ) {
+  Debug("qint-var-order-debug2") << "Get for " << d_q << " " << l.size() << " " << u.size() << std::endl;
+  for( unsigned i=0; i<d_q[0].getNumChildren(); i++ ){
+    Debug("qint-var-order-debug2") << "Get for " << d_q[0][i] << " " << d_var_to_num[d_q[0][i]].size() << std::endl;
+    Node ll = Node::null();
+    Node uu = m->getMaximum( d_q[0][i].getType() );
+    for( unsigned j=0; j<d_var_to_num[d_q[0][i]].size(); j++ ){
+      Debug("qint-var-order-debug2") << "Go " << j << std::endl;
+      Node cl = ll;
+      Node cu = uu;
+      int index = d_var_to_num[d_q[0][i]][j];
+      Debug("qint-var-order-debug2") << "Do meet for " << index << "..." << std::endl;
+      Debug("qint-var-order-debug2") << l[index] << " " << u[index] << " " << cl << " " << cu << std::endl;
+      if( !m->doMeet( l[index], u[index], cl, cu, ll, uu ) ){
+        Debug("qint-var-order-debug2") << "FAILED" << std::endl;
+        return false;
+      }
+      Debug("qint-var-order-debug2") << "Result : " << ll << " " << uu << std::endl;
+    }
+    Debug("qint-var-order-debug2") << "Got " << uu << std::endl;
+    inst.push_back( uu );
+  }
+  return true;
+}
+
+void QuantVarOrder::debugPrint( const char * c ) {
+  Trace( c ) << "Variable order for " << d_q << " is : " << std::endl;
+  debugPrint( c, d_q[1], d_var_occur );
+  Trace( c ) << std::endl;
+  for( unsigned i=0; i<d_q[0].getNumChildren(); i++ ){
+    Trace( c ) << d_q[0][i] << " : ";
+    for( unsigned j=0; j<d_var_to_num[d_q[0][i]].size(); j++ ){
+      Trace( c ) << d_var_to_num[d_q[0][i]][j] << " ";
+    }
+    Trace( c ) << std::endl;
+  }
+}
+
+void QuantVarOrder::debugPrint( const char * c, Node n, QIntVarNumIndex& vindex ) {
+  if( n.getKind()==FORALL ){
+    Trace(c) << "NESTED_QUANT";
+  }else{
+    Trace(c) << n.getKind() << "(";
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){
+      if( i>0 ) Trace( c ) << ",";
+      Trace( c ) << " ";
+      if( n[i].getKind()==BOUND_VARIABLE ){
+        Trace(c) << "VAR[" << vindex.d_var_num[i] << "]";
+      }else{
+        debugPrint( c, n[i], vindex.d_var_index[i] );
+      }
+      if( i==n.getNumChildren()-1 ) Trace( c ) << " ";
+    }
+    Trace(c) << ")";
+  }
+}
+
+QIntervalBuilder::QIntervalBuilder( context::Context* c, QuantifiersEngine* qe ) :
+QModelBuilder( c, qe ){
+  d_true = NodeManager::currentNM()->mkConst( true );
+}
+
+
+//------------------------model construction----------------------------
+
+void QIntervalBuilder::processBuildModel(TheoryModel* m, bool fullModel) {
+  Trace("fmf-qint-debug") << "process build model " << fullModel << std::endl;
+  FirstOrderModel* f = (FirstOrderModel*)m;
+  FirstOrderModelQInt* fm = f->asFirstOrderModelQInt();
+  if( fullModel ){
+    Trace("qint-model") << "Construct model representation..." << std::endl;
+    //make function values
+    for( std::map<Node, QIntDef * >::iterator it = fm->d_models.begin(); it != fm->d_models.end(); ++it ) {
+      if( it->first.getType().getNumChildren()>1 ){
+        Trace("qint-model") << "Construct for " << it->first << "..." << std::endl;
+        m->d_uf_models[ it->first ] = fm->getFunctionValue( it->first, "$x" );
+      }
+    }
+    TheoryEngineModelBuilder::processBuildModel( m, fullModel );
+    //mark that the model has been set
+    fm->markModelSet();
+    //debug the model
+    debugModel( fm );
+  }else{
+    fm->initialize( d_considerAxioms );
+    //process representatives
+    fm->d_rep_id.clear();
+    fm->d_max.clear();
+    fm->d_min.clear();
+    Trace("qint-model") << std::endl << "Making representatives..." << std::endl;
+    for( std::map< TypeNode, std::vector< Node > >::iterator it = fm->d_rep_set.d_type_reps.begin();
+         it != fm->d_rep_set.d_type_reps.end(); ++it ){
+      if( it->first.isSort() ){
+        if( it->second.empty() ){
+          std::cout << "Empty rep for " << it->first << std::endl;
+          exit(0);
+        }
+        Trace("qint-model") << "Representatives for " << it->first << " : " << std::endl;
+        for( unsigned i=0; i<it->second.size(); i++ ){
+          Trace("qint-model") << i << " : " << it->second[i] << std::endl;
+          fm->d_rep_id[it->second[i]] = i;
+        }
+        fm->d_min[it->first] = it->second[0];
+        fm->d_max[it->first] = it->second[it->second.size()-1];
+      }else{
+        //TODO: enumerate?
+      }
+    }
+    Trace("qint-model") << std::endl << "Making function definitions..." << std::endl;
+    //construct the models for functions
+    for( std::map<Node, QIntDef * >::iterator it = fm->d_models.begin(); it != fm->d_models.end(); ++it ) {
+      Node f = it->first;
+      Trace("qint-model-debug") << "Building Model for " << f << std::endl;
+      //reset the model
+      //get all (non-redundant) f-applications
+      std::vector< Node > fapps;
+      Trace("qint-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()) ){
+          Trace("qint-model-debug") << "  " << n << std::endl;
+          fapps.push_back( n );
+        }
+      }
+      if( fapps.empty() ){
+        //choose arbitrary value
+        Node mbt = d_qe->getTermDatabase()->getModelBasisOpTerm(f);
+        Trace("qint-model-debug") << "Initial terms empty, add " << mbt << std::endl;
+        fapps.push_back( mbt );
+      }
+      //construct the interval model
+      it->second->construct( fm, fapps );
+      Trace("qint-model-debug") << "Definition for " << f << " : " << std::endl;
+      it->second->debugPrint("qint-model-debug", fm, Node::null() );
+
+      it->second->simplify( fm, Node::null() );
+      Trace("qint-model") << "(Simplified) definition for " << f << " : " << std::endl;
+      it->second->debugPrint("qint-model", fm, Node::null() );
+
+      if( Debug.isOn("qint-model-debug") ){
+        for( size_t i=0; i<fm->d_uf_terms[f].size(); i++ ){
+          Node e = it->second->evaluate_n( fm, fm->d_uf_terms[f][i] );
+          Debug("qint-model-debug") << fm->d_uf_terms[f][i] << " evaluates to " << e << std::endl;
+          Assert( fm->areEqual( e, fm->d_uf_terms[f][i] ) );
+        }
+      }
+    }
+  }
+}
+
+
+//--------------------model checking---------------------------------------
+
+//do exhaustive instantiation
+bool QIntervalBuilder::doExhaustiveInstantiation( FirstOrderModel * fm, Node q, int effort ) {
+  Trace("qint-check") << "exhaustive instantiation " << q << " " << effort << std::endl;
+  if (effort==0) {
+
+    FirstOrderModelQInt * fmqint = fm->asFirstOrderModelQInt();
+    QIntDef qid;
+    doCheck( fmqint, q, qid, q[1], fmqint->d_var_order[q]->d_var_occur );
+    //now process entries
+    Trace("qint-inst") << "Interpretation for " << q << " is : " << std::endl;
+    qid.debugPrint( "qint-inst", fmqint, q );
+    Trace("qint-inst") << std::endl;
+    Debug("qint-check-debug2") << "Make iterator..." << std::endl;
+    QIntDefIter qdi( fmqint, q, &qid );
+    while( !qdi.isFinished() ){
+      if( qdi.getValue()!=d_true ){
+        Debug("qint-check-debug2") << "Set up vectors..." << std::endl;
+        std::vector< Node > l;
+        std::vector< Node > u;
+        std::vector< Node > inst;
+        qdi.getLowers( l );
+        qdi.getUppers( u );
+        Debug("qint-check-debug2") << "Get instantiation..." << std::endl;
+        if( fmqint->d_var_order[q]->getInstantiation( fmqint, l, u, inst ) ){
+          Trace("qint-inst") << "** Instantiate with ";
+          //just add the instance
+          for( unsigned j=0; j<inst.size(); j++) {
+            Trace("qint-inst") << inst[j] << " ";
+          }
+          Trace("qint-inst") << std::endl;
+          d_triedLemmas++;
+          if( d_qe->addInstantiation( q, inst ) ){
+            Trace("qint-inst") << "   ...added instantiation." << std::endl;
+            d_addedLemmas++;
+          }else{
+            Trace("qint-inst") << "   ...duplicate instantiation" << std::endl;
+            //verify that instantiation is witness for current entry
+            if( Debug.isOn("qint-check-debug2") ){
+              Debug("qint-check-debug2") << "Check if : ";
+              std::vector< Node > exp_inst;
+              for( unsigned i=0; i<fmqint->getOrderedNumVars( q ); i++ ){
+                int index = fmqint->getOrderedVarNumToVarNum( q, i );
+                exp_inst.push_back( inst[ index ] );
+                Debug("qint-check-debug2") << inst[index] << " ";
+              }
+              Debug("qint-check-debug2") << " evaluates to " << qdi.getValue() << std::endl;
+              Assert( qid.evaluate( fmqint, exp_inst )==qdi.getValue() );
+            }
+          }
+        }else{
+          Trace("qint-inst") << "** Spurious instantiation." << std::endl;
+        }
+      }
+      qdi.increment();
+    }
+  }
+  return true;
+}
+
+bool QIntervalBuilder::doCheck( FirstOrderModelQInt * m, Node q, QIntDef & qid, Node n,
+                                QIntVarNumIndex& vindex ) {
+  Assert( n.getKind()!=FORALL );
+  std::map< unsigned, QIntDef > children;
+  std::map< unsigned, Node > bchildren;
+  int varChCount = 0;
+  for( unsigned i=0; i<n.getNumChildren(); i++ ){
+    if( n[i].getKind()==FORALL ){
+      bchildren[i] = Node::null();
+    }else if( n[i].getKind() == BOUND_VARIABLE ){
+      varChCount++;
+      bchildren[i] = n[i];
+    }else if( m->hasTerm( n[i] ) ){
+      bchildren[i] = m->getUsedRepresentative( n[i] );
+    }else{
+      if( !doCheck( m, q, children[i], n[i], vindex.d_var_index[i] ) ){
+        bchildren[i] = Node::null();
+      }
+    }
+  }
+  Trace("qint-check-debug") << "Compute Interpretation of " << n << " " << n.getKind() << std::endl;
+  if( n.getKind() == APPLY_UF || n.getKind() == VARIABLE || n.getKind() == SKOLEM ){
+    Node op = n.getKind() == APPLY_UF ? n.getOperator() : n;
+    //uninterpreted compose
+    qid.construct_compose( m, q, n, m->d_models[op], children, bchildren, varChCount, vindex );
+  }else if( !qid.construct_compose( m, q, n, NULL, children, bchildren, varChCount, vindex ) ){
+    Trace("qint-check-debug") << "** Cannot produce definition for " << n << std::endl;
+    return false;
+  }
+  Trace("qint-check-debug2") << "Definition for " << n << " is : " << std::endl;
+  qid.debugPrint("qint-check-debug2", m, q);
+  qid.simplify( m, q );
+  Trace("qint-check-debug") << "(Simplified) Definition for " << n << " is : " << std::endl;
+  qid.debugPrint("qint-check-debug", m, q);
+  Trace("qint-check-debug") << std::endl;
+  Assert( qid.isTotal( m, q ) );
+  return true;
+}
index 8f48776ccd850719cda0585bbd017ef4b11722b6..6ec17756c21b00faf39ec5a8beae3f9801fdd4a2 100755 (executable)
-/*********************                                                        */\r
-/*! \file qinterval_builder.h\r
- ** \verbatim\r
- ** Original author: Andrew Reynolds\r
- ** Major contributors: none\r
- ** Minor contributors (to current version): none\r
- ** This file is part of the CVC4 project.\r
- ** Copyright (c) 2009-2013  New York University and The University of Iowa\r
- ** See the file COPYING in the top-level source directory for licensing\r
- ** information.\endverbatim\r
- **\r
- ** \brief qinterval model class\r
- **/\r
-\r
-#include "cvc4_private.h"\r
-\r
-#ifndef QINTERVAL_BUILDER\r
-#define QINTERVAL_BUILDER\r
-\r
-#include "theory/quantifiers/model_builder.h"\r
-#include "theory/quantifiers/first_order_model.h"\r
-\r
-namespace CVC4 {\r
-namespace theory {\r
-namespace quantifiers {\r
-\r
-class FirstOrderModelQInt;\r
-\r
-class QIntVarNumIndex\r
-{\r
-public:\r
-  std::map< int, int > d_var_num;\r
-  std::map< int, QIntVarNumIndex > d_var_index;\r
-};\r
-\r
-class QIntDef\r
-{\r
-private:\r
-  Node evaluate_r( FirstOrderModelQInt * m, std::vector< Node >& reps, unsigned depth );\r
-  Node evaluate_n_r( FirstOrderModelQInt * m, Node n, unsigned depth );\r
-  void construct_compose_r( FirstOrderModelQInt * m, Node q,\r
-                            std::vector< Node >& l, std::vector< Node >& u, Node n, QIntDef * f,\r
-                            std::vector< Node >& args,\r
-                            std::map< unsigned, QIntDef >& children,\r
-                            std::map< unsigned, Node >& bchildren,\r
-                            QIntVarNumIndex& vindex,\r
-                            unsigned depth );\r
-\r
-  void construct_enum_r( FirstOrderModelQInt * m, Node q, unsigned vn, unsigned depth, Node v );\r
-  int getEvIndex( FirstOrderModelQInt * m, Node n, bool exc = false );\r
-  void addEntry( FirstOrderModelQInt * m, Node q, std::vector< Node >& l, std::vector< Node >& u,\r
-                 Node v, unsigned depth = 0 );\r
-  Node simplify_r( FirstOrderModelQInt * m, Node q, std::vector< Node >& il, std::vector< Node >& iu,\r
-                   unsigned depth );\r
-  bool isTotal_r( FirstOrderModelQInt * m, Node q, std::vector< Node >& il, std::vector< Node >& iu,\r
-                  unsigned depth );\r
-public:\r
-  QIntDef(){}\r
-  std::map< Node, QIntDef > d_def;\r
-  std::vector< Node > d_def_order;\r
-\r
-  void construct( FirstOrderModelQInt * m, std::vector< Node >& fapps, unsigned depth = 0 );\r
-  bool construct_compose( FirstOrderModelQInt * m, Node q, Node n, QIntDef * f,\r
-                          std::map< unsigned, QIntDef >& children,\r
-                          std::map< unsigned, Node >& bchildren, int varChCount,\r
-                          QIntVarNumIndex& vindex );\r
-  bool construct_enum( FirstOrderModelQInt * m, Node q, unsigned vn );\r
-\r
-  Node evaluate( FirstOrderModelQInt * m, std::vector< Node >& reps ) { return evaluate_r( m, reps, 0 ); }\r
-  Node evaluate_n( FirstOrderModelQInt * m, Node n ) { return evaluate_n_r( m, n, 0 ); }\r
-\r
-  void debugPrint( const char * c, FirstOrderModelQInt * m, Node q, int t = 0 );\r
-  QIntDef * getChild( unsigned i );\r
-  Node getValue() { return d_def_order[0]; }\r
-  Node getLower( unsigned i ) { return i==0 ? Node::null() : d_def_order[i-1]; }\r
-  Node getUpper( unsigned i ) { return d_def_order[i]; }\r
-  Node getMaximum() { return d_def_order.empty() ? Node::null() : getUpper( d_def_order.size()-1 ); }\r
-  int getNumChildren() { return d_def_order.size(); }\r
-  bool isTotal( FirstOrderModelQInt * m, Node q );\r
-\r
-  Node simplify( FirstOrderModelQInt * m, Node q );\r
-  Node getFunctionValue( FirstOrderModelQInt * m, std::vector< Node >& vars, unsigned depth = 0 );\r
-\r
-  static void init_vec( FirstOrderModelQInt * m, Node q, std::vector< Node >& l, std::vector< Node >& u );\r
-  static void debugPrint( const char * c, FirstOrderModelQInt * m, Node q, std::vector< Node >& l, std::vector< Node >& u );\r
-};\r
-\r
-class QIntDefIter {\r
-private:\r
-  FirstOrderModelQInt * d_fm;\r
-  Node d_q;\r
-  void resetIndex( QIntDef * qid );\r
-public:\r
-  QIntDefIter( FirstOrderModelQInt * m, Node q, QIntDef * qid );\r
-  void debugPrint( const char * c, int t = 0 );\r
-  std::vector< QIntDef * > d_index_visited;\r
-  std::vector< int > d_index;\r
-  bool isFinished() { return d_index.empty(); }\r
-  bool increment( int index = -1 );\r
-  unsigned getSize() { return d_index.size(); }\r
-  Node getLower( int index );\r
-  Node getUpper( int index );\r
-  void getLowers( std::vector< Node >& reps );\r
-  void getUppers( std::vector< Node >& reps );\r
-  Node getValue();\r
-};\r
-\r
-\r
-class QuantVarOrder\r
-{\r
-private:\r
-  int initialize( Node n, int minVarIndex, QIntVarNumIndex& vindex );\r
-  int d_var_count;\r
-  Node d_q;\r
-  void debugPrint( const char * c, Node n, QIntVarNumIndex& vindex );\r
-public:\r
-  QuantVarOrder( Node q );\r
-  std::map< int, Node > d_num_to_var;\r
-  std::map< int, int > d_num_to_prev_num;\r
-  std::map< int, int > d_num_to_next_num;\r
-  std::map< Node, std::vector< int > > d_var_to_num;\r
-  std::map< int, int > d_var_num_index;\r
-  //std::map< Node, std::map< int, int > > d_var_occur;\r
-  //int getVarNum( Node n, int arg ) { return d_var_occur[n][arg]; }\r
-  unsigned getNumVars() { return d_var_count; }\r
-  Node getVar( int i ) { return d_num_to_var[i]; }\r
-  int getPrevNum( int i ) { return d_num_to_prev_num.find( i )!=d_num_to_prev_num.end() ? d_num_to_prev_num[i] : -1; }\r
-  int getNextNum( int i ) { return d_num_to_next_num.find( i )!=d_num_to_next_num.end() ? d_num_to_next_num[i] : -1; }\r
-  int getVarNumIndex( int i ) { return d_var_num_index[i]; }\r
-  bool getInstantiation( FirstOrderModelQInt * m, std::vector< Node >& l, std::vector< Node >& u,\r
-                         std::vector< Node >& inst );\r
-  void debugPrint( const char * c );\r
-  QIntVarNumIndex d_var_occur;\r
-};\r
-\r
-class QIntervalBuilder : public QModelBuilder\r
-{\r
-private:\r
-  Node d_true;\r
-  bool doCheck( FirstOrderModelQInt * m, Node q, QIntDef & qid, Node n,\r
-                QIntVarNumIndex& vindex );\r
-public:\r
-  QIntervalBuilder( context::Context* c, QuantifiersEngine* qe );\r
-  //process build model\r
-  void processBuildModel(TheoryModel* m, bool fullModel);\r
-  //do exhaustive instantiation\r
-  bool doExhaustiveInstantiation( FirstOrderModel * fm, Node q, int effort );\r
-};\r
-\r
-\r
-}\r
-}\r
-}\r
-\r
+/*********************                                                        */
+/*! \file qinterval_builder.h
+ ** \verbatim
+ ** Original author: Andrew Reynolds
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2013  New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief qinterval model class
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef QINTERVAL_BUILDER
+#define QINTERVAL_BUILDER
+
+#include "theory/quantifiers/model_builder.h"
+#include "theory/quantifiers/first_order_model.h"
+
+namespace CVC4 {
+namespace theory {
+namespace quantifiers {
+
+class FirstOrderModelQInt;
+
+class QIntVarNumIndex
+{
+public:
+  std::map< int, int > d_var_num;
+  std::map< int, QIntVarNumIndex > d_var_index;
+};
+
+class QIntDef
+{
+private:
+  Node evaluate_r( FirstOrderModelQInt * m, std::vector< Node >& reps, unsigned depth );
+  Node evaluate_n_r( FirstOrderModelQInt * m, Node n, unsigned depth );
+  void construct_compose_r( FirstOrderModelQInt * m, Node q,
+                            std::vector< Node >& l, std::vector< Node >& u, Node n, QIntDef * f,
+                            std::vector< Node >& args,
+                            std::map< unsigned, QIntDef >& children,
+                            std::map< unsigned, Node >& bchildren,
+                            QIntVarNumIndex& vindex,
+                            unsigned depth );
+
+  void construct_enum_r( FirstOrderModelQInt * m, Node q, unsigned vn, unsigned depth, Node v );
+  int getEvIndex( FirstOrderModelQInt * m, Node n, bool exc = false );
+  void addEntry( FirstOrderModelQInt * m, Node q, std::vector< Node >& l, std::vector< Node >& u,
+                 Node v, unsigned depth = 0 );
+  Node simplify_r( FirstOrderModelQInt * m, Node q, std::vector< Node >& il, std::vector< Node >& iu,
+                   unsigned depth );
+  bool isTotal_r( FirstOrderModelQInt * m, Node q, std::vector< Node >& il, std::vector< Node >& iu,
+                  unsigned depth );
+public:
+  QIntDef(){}
+  std::map< Node, QIntDef > d_def;
+  std::vector< Node > d_def_order;
+
+  void construct( FirstOrderModelQInt * m, std::vector< Node >& fapps, unsigned depth = 0 );
+  bool construct_compose( FirstOrderModelQInt * m, Node q, Node n, QIntDef * f,
+                          std::map< unsigned, QIntDef >& children,
+                          std::map< unsigned, Node >& bchildren, int varChCount,
+                          QIntVarNumIndex& vindex );
+  bool construct_enum( FirstOrderModelQInt * m, Node q, unsigned vn );
+
+  Node evaluate( FirstOrderModelQInt * m, std::vector< Node >& reps ) { return evaluate_r( m, reps, 0 ); }
+  Node evaluate_n( FirstOrderModelQInt * m, Node n ) { return evaluate_n_r( m, n, 0 ); }
+
+  void debugPrint( const char * c, FirstOrderModelQInt * m, Node q, int t = 0 );
+  QIntDef * getChild( unsigned i );
+  Node getValue() { return d_def_order[0]; }
+  Node getLower( unsigned i ) { return i==0 ? Node::null() : d_def_order[i-1]; }
+  Node getUpper( unsigned i ) { return d_def_order[i]; }
+  Node getMaximum() { return d_def_order.empty() ? Node::null() : getUpper( d_def_order.size()-1 ); }
+  int getNumChildren() { return d_def_order.size(); }
+  bool isTotal( FirstOrderModelQInt * m, Node q );
+
+  Node simplify( FirstOrderModelQInt * m, Node q );
+  Node getFunctionValue( FirstOrderModelQInt * m, std::vector< Node >& vars, unsigned depth = 0 );
+
+  static void init_vec( FirstOrderModelQInt * m, Node q, std::vector< Node >& l, std::vector< Node >& u );
+  static void debugPrint( const char * c, FirstOrderModelQInt * m, Node q, std::vector< Node >& l, std::vector< Node >& u );
+};
+
+class QIntDefIter {
+private:
+  FirstOrderModelQInt * d_fm;
+  Node d_q;
+  void resetIndex( QIntDef * qid );
+public:
+  QIntDefIter( FirstOrderModelQInt * m, Node q, QIntDef * qid );
+  void debugPrint( const char * c, int t = 0 );
+  std::vector< QIntDef * > d_index_visited;
+  std::vector< int > d_index;
+  bool isFinished() { return d_index.empty(); }
+  bool increment( int index = -1 );
+  unsigned getSize() { return d_index.size(); }
+  Node getLower( int index );
+  Node getUpper( int index );
+  void getLowers( std::vector< Node >& reps );
+  void getUppers( std::vector< Node >& reps );
+  Node getValue();
+};
+
+
+class QuantVarOrder
+{
+private:
+  int initialize( Node n, int minVarIndex, QIntVarNumIndex& vindex );
+  int d_var_count;
+  Node d_q;
+  void debugPrint( const char * c, Node n, QIntVarNumIndex& vindex );
+public:
+  QuantVarOrder( Node q );
+  std::map< int, Node > d_num_to_var;
+  std::map< int, int > d_num_to_prev_num;
+  std::map< int, int > d_num_to_next_num;
+  std::map< Node, std::vector< int > > d_var_to_num;
+  std::map< int, int > d_var_num_index;
+  //std::map< Node, std::map< int, int > > d_var_occur;
+  //int getVarNum( Node n, int arg ) { return d_var_occur[n][arg]; }
+  unsigned getNumVars() { return d_var_count; }
+  Node getVar( int i ) { return d_num_to_var[i]; }
+  int getPrevNum( int i ) { return d_num_to_prev_num.find( i )!=d_num_to_prev_num.end() ? d_num_to_prev_num[i] : -1; }
+  int getNextNum( int i ) { return d_num_to_next_num.find( i )!=d_num_to_next_num.end() ? d_num_to_next_num[i] : -1; }
+  int getVarNumIndex( int i ) { return d_var_num_index[i]; }
+  bool getInstantiation( FirstOrderModelQInt * m, std::vector< Node >& l, std::vector< Node >& u,
+                         std::vector< Node >& inst );
+  void debugPrint( const char * c );
+  QIntVarNumIndex d_var_occur;
+};
+
+class QIntervalBuilder : public QModelBuilder
+{
+private:
+  Node d_true;
+  bool doCheck( FirstOrderModelQInt * m, Node q, QIntDef & qid, Node n,
+                QIntVarNumIndex& vindex );
+public:
+  QIntervalBuilder( context::Context* c, QuantifiersEngine* qe );
+  //process build model
+  void processBuildModel(TheoryModel* m, bool fullModel);
+  //do exhaustive instantiation
+  bool doExhaustiveInstantiation( FirstOrderModel * fm, Node q, int effort );
+};
+
+
+}
+}
+}
+
 #endif
\ No newline at end of file
index 731b53dc40a664d4123c5abc46330346fd1e344b..8321f17ba681d745f655c07964d0586fdb351a6c 100755 (executable)
-/*********************                                                        */\r
-/*! \file quant_conflict_find.cpp\r
- ** \verbatim\r
- ** Original author: Andrew Reynolds\r
- ** Major contributors: none\r
- ** Minor contributors (to current version): none\r
- ** This file is part of the CVC4 project.\r
- ** Copyright (c) 2009-2013  New York University and The University of Iowa\r
- ** See the file COPYING in the top-level source directory for licensing\r
- ** information.\endverbatim\r
- **\r
- ** \brief quant conflict find class\r
- **\r
- **/\r
-\r
-#include <vector>\r
-\r
-#include "theory/quantifiers/quant_conflict_find.h"\r
-#include "theory/quantifiers/quant_util.h"\r
-#include "theory/theory_engine.h"\r
-#include "theory/quantifiers/options.h"\r
-#include "theory/quantifiers/term_database.h"\r
-#include "theory/quantifiers/trigger.h"\r
-\r
-using namespace CVC4;\r
-using namespace CVC4::kind;\r
-using namespace CVC4::theory;\r
-using namespace CVC4::theory::quantifiers;\r
-using namespace std;\r
-\r
-namespace CVC4 {\r
-\r
-Node QcfNodeIndex::existsTerm( TNode n, std::vector< TNode >& reps, int index ) {\r
-  if( index==(int)reps.size() ){\r
-    if( d_children.empty() ){\r
-      return Node::null();\r
-    }else{\r
-      return d_children.begin()->first;\r
-    }\r
-  }else{\r
-    std::map< TNode, QcfNodeIndex >::iterator it = d_children.find( reps[index] );\r
-    if( it==d_children.end() ){\r
-      return Node::null();\r
-    }else{\r
-      return it->second.existsTerm( n, reps, index+1 );\r
-    }\r
-  }\r
-}\r
-\r
-Node QcfNodeIndex::addTerm( TNode n, std::vector< TNode >& reps, int index ) {\r
-  if( index==(int)reps.size() ){\r
-    if( d_children.empty() ){\r
-      d_children[ n ].clear();\r
-      return n;\r
-    }else{\r
-      return d_children.begin()->first;\r
-    }\r
-  }else{\r
-    return d_children[reps[index]].addTerm( n, reps, index+1 );\r
-  }\r
-}\r
-\r
-\r
-void QcfNodeIndex::debugPrint( const char * c, int t ) {\r
-  for( std::map< TNode, QcfNodeIndex >::iterator it = d_children.begin(); it != d_children.end(); ++it ){\r
-    if( !it->first.isNull() ){\r
-      for( int j=0; j<t; j++ ){ Trace(c) << "  "; }\r
-      Trace(c) << it->first << " : " << std::endl;\r
-      it->second.debugPrint( c, t+1 );\r
-    }\r
-  }\r
-}\r
-\r
-\r
-void QuantInfo::initialize( Node q, Node qn ) {\r
-  d_q = q;\r
-  for( unsigned i=0; i<q[0].getNumChildren(); i++ ){\r
-    d_match.push_back( TNode::null() );\r
-    d_match_term.push_back( TNode::null() );\r
-  }\r
-\r
-  //register the variables\r
-  for( unsigned i=0; i<q[0].getNumChildren(); i++ ){\r
-    d_var_num[q[0][i]] = i;\r
-    d_vars.push_back( q[0][i] );\r
-  }\r
-\r
-  registerNode( qn, true, true );\r
-\r
-\r
-  Trace("qcf-qregister") << "- Make match gen structure..." << std::endl;\r
-  d_mg = new MatchGen( this, qn );\r
-\r
-  if( d_mg->isValid() ){\r
-    /*\r
-    for( unsigned j=0; j<q[0].getNumChildren(); j++ ){\r
-      if( d_inMatchConstraint.find( q[0][j] )==d_inMatchConstraint.end() ){\r
-        Trace("qcf-invalid") << "QCF invalid : variable " << q[0][j] << " does not exist in a matching constraint." << std::endl;\r
-        d_mg->setInvalid();\r
-        break;\r
-      }\r
-    }\r
-    */\r
-    if( d_mg->isValid() ){\r
-      for( unsigned j=q[0].getNumChildren(); j<d_vars.size(); j++ ){\r
-        if( d_vars[j].getKind()!=BOUND_VARIABLE ){\r
-          d_var_mg[j] = NULL;\r
-          bool is_tsym = false;\r
-          if( !MatchGen::isHandledUfTerm( d_vars[j] ) && d_vars[j].getKind()!=ITE ){\r
-            is_tsym = true;\r
-            d_tsym_vars.push_back( j );\r
-          }\r
-          if( !is_tsym || options::qcfTConstraint() ){\r
-            d_var_mg[j] = new MatchGen( this, d_vars[j], true );\r
-          }\r
-          if( !d_var_mg[j] || !d_var_mg[j]->isValid() ){\r
-            Trace("qcf-invalid") << "QCF invalid : cannot match for " << d_vars[j] << std::endl;\r
-            d_mg->setInvalid();\r
-            break;\r
-          }else{\r
-            std::vector< int > bvars;\r
-            d_var_mg[j]->determineVariableOrder( this, bvars );\r
-          }\r
-        }\r
-      }\r
-      if( d_mg->isValid() ){\r
-        std::vector< int > bvars;\r
-        d_mg->determineVariableOrder( this, bvars );\r
-      }\r
-    }\r
-  }else{\r
-    Trace("qcf-invalid") << "QCF invalid : body of formula cannot be processed." << std::endl;\r
-  }\r
-  Trace("qcf-qregister-summary") << "QCF register : " << ( d_mg->isValid() ? "VALID " : "INVALID" ) << " : " << q << std::endl;\r
-}\r
-\r
-void QuantInfo::registerNode( Node n, bool hasPol, bool pol, bool beneathQuant ) {\r
-  Trace("qcf-qregister-debug2") << "Register : " << n << std::endl;\r
-  if( n.getKind()==FORALL ){\r
-    registerNode( n[1], hasPol, pol, true );\r
-  }else{\r
-    if( !MatchGen::isHandledBoolConnective( n ) ){\r
-      if( n.hasBoundVar() ){\r
-        //literals\r
-        if( n.getKind()==EQUAL ){\r
-          for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-            flatten( n[i], beneathQuant );\r
-          }\r
-        }else if( MatchGen::isHandledUfTerm( n ) ){\r
-          flatten( n, beneathQuant );\r
-        }else if( n.getKind()==ITE ){\r
-          for( unsigned i=1; i<=2; i++ ){\r
-            flatten( n[i], beneathQuant );\r
-          }\r
-          registerNode( n[0], false, pol, beneathQuant );\r
-        }else if( options::qcfTConstraint() ){\r
-          //a theory-specific predicate\r
-          for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-            flatten( n[i], beneathQuant );\r
-          }\r
-        }\r
-      }\r
-    }else{\r
-      for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-        bool newHasPol;\r
-        bool newPol;\r
-        QuantPhaseReq::getPolarity( n, i, hasPol, pol, newHasPol, newPol );\r
-        //QcfNode * qcfc = new QcfNode( d_c );\r
-        //qcfc->d_parent = qcf;\r
-        //qcf->d_child[i] = qcfc;\r
-        registerNode( n[i], newHasPol, newPol, beneathQuant );\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-void QuantInfo::flatten( Node n, bool beneathQuant ) {\r
-  Trace("qcf-qregister-debug2") << "Flatten : " << n << std::endl;\r
-  if( n.hasBoundVar() ){\r
-    if( n.getKind()==BOUND_VARIABLE ){\r
-      d_inMatchConstraint[n] = true;\r
-    }\r
-    //if( MatchGen::isHandledUfTerm( n ) || n.getKind()==ITE ){\r
-    if( d_var_num.find( n )==d_var_num.end() ){\r
-      Trace("qcf-qregister-debug2") << "Add FLATTEN VAR : " << n << std::endl;\r
-      d_var_num[n] = d_vars.size();\r
-      d_vars.push_back( n );\r
-      d_match.push_back( TNode::null() );\r
-      d_match_term.push_back( TNode::null() );\r
-      if( n.getKind()==ITE ){\r
-        registerNode( n, false, false );\r
-      }else{\r
-        for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-          flatten( n[i], beneathQuant );\r
-        }\r
-      }\r
-    }else{\r
-      Trace("qcf-qregister-debug2") << "...already processed" << std::endl;\r
-    }\r
-  }else{\r
-    Trace("qcf-qregister-debug2") << "...is ground." << std::endl;\r
-  }\r
-}\r
-\r
-\r
-void QuantInfo::reset_round( QuantConflictFind * p ) {\r
-  for( unsigned i=0; i<d_match.size(); i++ ){\r
-    d_match[i] = TNode::null();\r
-    d_match_term[i] = TNode::null();\r
-  }\r
-  d_curr_var_deq.clear();\r
-  d_tconstraints.clear();\r
-  //add built-in variable constraints\r
-  for( unsigned r=0; r<2; r++ ){\r
-    for( std::map< int, std::vector< Node > >::iterator it = d_var_constraint[r].begin();\r
-         it != d_var_constraint[r].end(); ++it ){\r
-      for( unsigned j=0; j<it->second.size(); j++ ){\r
-        Node rr = it->second[j];\r
-        if( !isVar( rr ) ){\r
-          rr = p->getRepresentative( rr );\r
-        }\r
-        if( addConstraint( p, it->first, rr, r==0 )==-1 ){\r
-          d_var_constraint[0].clear();\r
-          d_var_constraint[1].clear();\r
-          //quantified formula is actually equivalent to true\r
-          Trace("qcf-qregister") << "Quantifier is equivalent to true!!!" << std::endl;\r
-          d_mg->d_children.clear();\r
-          d_mg->d_n = NodeManager::currentNM()->mkConst( true );\r
-          d_mg->d_type = MatchGen::typ_ground;\r
-          return;\r
-        }\r
-      }\r
-    }\r
-  }\r
-  d_mg->reset_round( p );\r
-  for( std::map< int, MatchGen * >::iterator it = d_var_mg.begin(); it != d_var_mg.end(); ++it ){\r
-    it->second->reset_round( p );\r
-  }\r
-  //now, reset for matching\r
-  d_mg->reset( p, false, this );\r
-}\r
-\r
-int QuantInfo::getCurrentRepVar( int v ) {\r
-  if( v!=-1 && !d_match[v].isNull() ){\r
-    int vn = getVarNum( d_match[v] );\r
-    if( vn!=-1 ){\r
-      //int vr = getCurrentRepVar( vn );\r
-      //d_match[v] = d_vars[vr];\r
-      //return vr;\r
-      return getCurrentRepVar( vn );\r
-    }\r
-  }\r
-  return v;\r
-}\r
-\r
-TNode QuantInfo::getCurrentValue( TNode n ) {\r
-  int v = getVarNum( n );\r
-  if( v==-1 ){\r
-    return n;\r
-  }else{\r
-    if( d_match[v].isNull() ){\r
-      return n;\r
-    }else{\r
-      Assert( getVarNum( d_match[v] )!=v );\r
-      return getCurrentValue( d_match[v] );\r
-    }\r
-  }\r
-}\r
-\r
-TNode QuantInfo::getCurrentExpValue( TNode n ) {\r
-  int v = getVarNum( n );\r
-  if( v==-1 ){\r
-    return n;\r
-  }else{\r
-    if( d_match[v].isNull() ){\r
-      return n;\r
-    }else{\r
-      Assert( getVarNum( d_match[v] )!=v );\r
-      if( d_match_term[v].isNull() ){\r
-        return getCurrentValue( d_match[v] );\r
-      }else{\r
-        return d_match_term[v];\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-bool QuantInfo::getCurrentCanBeEqual( QuantConflictFind * p, int v, TNode n, bool chDiseq ) {\r
-  //check disequalities\r
-  std::map< int, std::map< TNode, int > >::iterator itd = d_curr_var_deq.find( v );\r
-  if( itd!=d_curr_var_deq.end() ){\r
-    for( std::map< TNode, int >::iterator it = itd->second.begin(); it != itd->second.end(); ++it ){\r
-      Node cv = getCurrentValue( it->first );\r
-      Debug("qcf-ccbe") << "compare " << cv << " " << n << std::endl;\r
-      if( cv==n ){\r
-        return false;\r
-      }else if( chDiseq && !isVar( n ) && !isVar( cv ) ){\r
-        //they must actually be disequal if we are looking for conflicts\r
-        if( !p->areDisequal( n, cv ) ){\r
-          //TODO : check for entailed disequal\r
-\r
-          return false;\r
-        }\r
-      }\r
-    }\r
-  }\r
-  return true;\r
-}\r
-\r
-int QuantInfo::addConstraint( QuantConflictFind * p, int v, TNode n, bool polarity ) {\r
-  v = getCurrentRepVar( v );\r
-  int vn = getVarNum( n );\r
-  vn = vn==-1 ? -1 : getCurrentRepVar( vn );\r
-  n = getCurrentValue( n );\r
-  return addConstraint( p, v, n, vn, polarity, false );\r
-}\r
-\r
-int QuantInfo::addConstraint( QuantConflictFind * p, int v, TNode n, int vn, bool polarity, bool doRemove ) {\r
-  //for handling equalities between variables, and disequalities involving variables\r
-  Debug("qcf-match-debug") << "- " << (doRemove ? "un" : "" ) << "constrain : " << v << " -> " << n << " (cv=" << getCurrentValue( n ) << ")";\r
-  Debug("qcf-match-debug") << ", (vn=" << vn << "), polarity = " << polarity << std::endl;\r
-  Assert( doRemove || n==getCurrentValue( n ) );\r
-  Assert( doRemove || v==getCurrentRepVar( v ) );\r
-  Assert( doRemove || vn==getCurrentRepVar( getVarNum( n ) ) );\r
-  if( polarity ){\r
-    if( vn!=v ){\r
-      if( doRemove ){\r
-        if( vn!=-1 ){\r
-          //if set to this in the opposite direction, clean up opposite instead\r
-          //          std::map< int, TNode >::iterator itmn = d_match.find( vn );\r
-          if( d_match[vn]==d_vars[v] ){\r
-            return addConstraint( p, vn, d_vars[v], v, true, true );\r
-          }else{\r
-            //unsetting variables equal\r
-            std::map< int, std::map< TNode, int > >::iterator itd = d_curr_var_deq.find( vn );\r
-            if( itd!=d_curr_var_deq.end() ){\r
-              //remove disequalities owned by this\r
-              std::vector< TNode > remDeq;\r
-              for( std::map< TNode, int >::iterator it = itd->second.begin(); it != itd->second.end(); ++it ){\r
-                if( it->second==v ){\r
-                  remDeq.push_back( it->first );\r
-                }\r
-              }\r
-              for( unsigned i=0; i<remDeq.size(); i++ ){\r
-                d_curr_var_deq[vn].erase( remDeq[i] );\r
-              }\r
-            }\r
-          }\r
-        }\r
-        d_match[v] = TNode::null();\r
-        return 1;\r
-      }else{\r
-        //std::map< int, TNode >::iterator itm = d_match.find( v );\r
-\r
-        if( vn!=-1 ){\r
-          Debug("qcf-match-debug") << "  ...Variable bound to variable" << std::endl;\r
-          //std::map< int, TNode >::iterator itmn = d_match.find( vn );\r
-          if( d_match[v].isNull() ){\r
-            //setting variables equal\r
-            bool alreadySet = false;\r
-            if( !d_match[vn].isNull() ){\r
-              alreadySet = true;\r
-              Assert( !isVar( d_match[vn] ) );\r
-            }\r
-\r
-            //copy or check disequalities\r
-            std::map< int, std::map< TNode, int > >::iterator itd = d_curr_var_deq.find( v );\r
-            if( itd!=d_curr_var_deq.end() ){\r
-              for( std::map< TNode, int >::iterator it = itd->second.begin(); it != itd->second.end(); ++it ){\r
-                Node dv = getCurrentValue( it->first );\r
-                if( !alreadySet ){\r
-                  if( d_curr_var_deq[vn].find( dv )==d_curr_var_deq[vn].end() ){\r
-                    d_curr_var_deq[vn][dv] = v;\r
-                  }\r
-                }else{\r
-                  if( !p->areMatchDisequal( d_match[vn], dv ) ){\r
-                    Debug("qcf-match-debug") << "  -> fail, conflicting disequality" << std::endl;\r
-                    return -1;\r
-                  }\r
-                }\r
-              }\r
-            }\r
-            if( alreadySet ){\r
-              n = getCurrentValue( n );\r
-            }\r
-          }else{\r
-            if( d_match[vn].isNull() ){\r
-              Debug("qcf-match-debug") << " ...Reverse direction" << std::endl;\r
-              //set the opposite direction\r
-              return addConstraint( p, vn, d_vars[v], v, true, false );\r
-            }else{\r
-              Debug("qcf-match-debug") << "  -> Both variables bound, compare" << std::endl;\r
-              //are they currently equal\r
-              return p->areMatchEqual( d_match[v], d_match[vn] ) ? 0 : -1;\r
-            }\r
-          }\r
-        }else{\r
-          Debug("qcf-match-debug") << "  ...Variable bound to ground" << std::endl;\r
-          if( d_match[v].isNull() ){\r
-          }else{\r
-            //compare ground values\r
-            Debug("qcf-match-debug") << "  -> Ground value, compare " << d_match[v] << " "<< n << std::endl;\r
-            return p->areMatchEqual( d_match[v], n ) ? 0 : -1;\r
-          }\r
-        }\r
-        if( setMatch( p, v, n ) ){\r
-          Debug("qcf-match-debug") << "  -> success" << std::endl;\r
-          return 1;\r
-        }else{\r
-          Debug("qcf-match-debug") << "  -> fail, conflicting disequality" << std::endl;\r
-          return -1;\r
-        }\r
-      }\r
-    }else{\r
-      Debug("qcf-match-debug") << "  -> redundant, variable identity" << std::endl;\r
-      return 0;\r
-    }\r
-  }else{\r
-    if( vn==v ){\r
-      Debug("qcf-match-debug") << "  -> fail, variable identity" << std::endl;\r
-      return -1;\r
-    }else{\r
-      if( doRemove ){\r
-        Assert( d_curr_var_deq[v].find( n )!=d_curr_var_deq[v].end() );\r
-        d_curr_var_deq[v].erase( n );\r
-        return 1;\r
-      }else{\r
-        if( d_curr_var_deq[v].find( n )==d_curr_var_deq[v].end() ){\r
-          //check if it respects equality\r
-          //std::map< int, TNode >::iterator itm = d_match.find( v );\r
-          if( !d_match[v].isNull() ){\r
-            TNode nv = getCurrentValue( n );\r
-            if( !p->areMatchDisequal( nv, d_match[v] ) ){\r
-              Debug("qcf-match-debug") << "  -> fail, conflicting disequality" << std::endl;\r
-              return -1;\r
-            }\r
-          }\r
-          d_curr_var_deq[v][n] = v;\r
-          Debug("qcf-match-debug") << "  -> success" << std::endl;\r
-          return 1;\r
-        }else{\r
-          Debug("qcf-match-debug") << "  -> redundant disequality" << std::endl;\r
-          return 0;\r
-        }\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-bool QuantInfo::isConstrainedVar( int v ) {\r
-  if( d_curr_var_deq.find( v )!=d_curr_var_deq.end() && !d_curr_var_deq[v].empty() ){\r
-    return true;\r
-  }else{\r
-    Node vv = getVar( v );\r
-    //for( std::map< int, TNode >::iterator it = d_match.begin(); it != d_match.end(); ++it ){\r
-    for( unsigned i=0; i<d_match.size(); i++ ){\r
-      if( d_match[i]==vv ){\r
-        return true;\r
-      }\r
-    }\r
-    for( std::map< int, std::map< TNode, int > >::iterator it = d_curr_var_deq.begin(); it != d_curr_var_deq.end(); ++it ){\r
-      for( std::map< TNode, int >::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 ){\r
-        if( it2->first==vv ){\r
-          return true;\r
-        }\r
-      }\r
-    }\r
-    return false;\r
-  }\r
-}\r
-\r
-bool QuantInfo::setMatch( QuantConflictFind * p, int v, TNode n ) {\r
-  if( getCurrentCanBeEqual( p, v, n ) ){\r
-    Debug("qcf-match-debug") << "-- bind : " << v << " -> " << n << ", checked " <<  d_curr_var_deq[v].size() << " disequalities" << std::endl;\r
-    d_match[v] = n;\r
-    return true;\r
-  }else{\r
-    return false;\r
-  }\r
-}\r
-\r
-bool QuantInfo::isMatchSpurious( QuantConflictFind * p ) {\r
-  for( int i=0; i<getNumVars(); i++ ){\r
-    //std::map< int, TNode >::iterator it = d_match.find( i );\r
-    if( !d_match[i].isNull() ){\r
-      if( !getCurrentCanBeEqual( p, i, d_match[i], p->d_effort==QuantConflictFind::effort_conflict ) ){\r
-        return true;\r
-      }\r
-    }\r
-  }\r
-  return false;\r
-}\r
-\r
-bool QuantInfo::isTConstraintSpurious( QuantConflictFind * p, std::vector< Node >& terms ) {\r
-  if( !d_tconstraints.empty() ){\r
-    //check constraints\r
-    for( std::map< Node, bool >::iterator it = d_tconstraints.begin(); it != d_tconstraints.end(); ++it ){\r
-      //apply substitution to the tconstraint\r
-      Node cons = it->first.substitute( p->getQuantifiersEngine()->getTermDatabase()->d_vars[d_q].begin(),\r
-                                        p->getQuantifiersEngine()->getTermDatabase()->d_vars[d_q].end(),\r
-                                        terms.begin(), terms.end() );\r
-      cons = it->second ? cons : cons.negate();\r
-      if( !entailmentTest( p, cons, p->d_effort==QuantConflictFind::effort_conflict ) ){\r
-        return true;\r
-      }\r
-    }\r
-  }\r
-  return false;\r
-}\r
-\r
-bool QuantInfo::entailmentTest( QuantConflictFind * p, Node lit, bool chEnt ) {\r
-  Trace("qcf-tconstraint-debug") << "Check : " << lit << std::endl;\r
-  Node rew = Rewriter::rewrite( lit );\r
-  if( rew==p->d_false ){\r
-    Trace("qcf-tconstraint-debug") << "...constraint " << lit << " is disentailed (rewrites to false)." << std::endl;\r
-    return false;\r
-  }else if( rew!=p->d_true ){\r
-    //if checking for conflicts, we must be sure that the constraint is entailed\r
-    if( chEnt ){\r
-      //check if it is entailed\r
-      Trace("qcf-tconstraint-debug") << "Check entailment of " << rew << "..." << std::endl;\r
-      std::pair<bool, Node> et = p->getQuantifiersEngine()->getTheoryEngine()->entailmentCheck(THEORY_OF_TYPE_BASED, rew );\r
-      ++(p->d_statistics.d_entailment_checks);\r
-      Trace("qcf-tconstraint-debug") << "ET result : " << et.first << " " << et.second << std::endl;\r
-      if( !et.first ){\r
-        Trace("qcf-tconstraint-debug") << "...cannot show entailment of " << rew << "." << std::endl;\r
-        return false;\r
-      }else{\r
-        return true;\r
-      }\r
-    }else{\r
-      Trace("qcf-tconstraint-debug") << "...does not need to be entailed." << std::endl;\r
-      return true;\r
-    }\r
-  }else{\r
-    Trace("qcf-tconstraint-debug") << "...rewrites to true." << std::endl;\r
-    return true;\r
-  }\r
-}\r
-\r
-bool QuantInfo::completeMatch( QuantConflictFind * p, std::vector< int >& assigned, bool doContinue ) {\r
-  //assign values for variables that were unassigned (usually not necessary, but handles corner cases)\r
-  bool doFail = false;\r
-  bool success = true;\r
-  if( doContinue ){\r
-    doFail = true;\r
-    success = false;\r
-  }else{\r
-    //solve for interpreted symbol matches\r
-    //   this breaks the invariant that all introduced constraints are over existing terms\r
-    for( int i=(int)(d_tsym_vars.size()-1); i>=0; i-- ){\r
-      int index = d_tsym_vars[i];\r
-      TNode v = getCurrentValue( d_vars[index] );\r
-      int slv_v = -1;\r
-      if( v==d_vars[index] ){\r
-        slv_v = index;\r
-      }\r
-      Trace("qcf-tconstraint-debug") << "Solve " << d_vars[index] << " = " << v << " " << d_vars[index].getKind() << std::endl;\r
-      if( d_vars[index].getKind()==PLUS || d_vars[index].getKind()==MULT ){\r
-        Kind k = d_vars[index].getKind();\r
-        std::vector< TNode > children;\r
-        for( unsigned j=0; j<d_vars[index].getNumChildren(); j++ ){\r
-          int vn = getVarNum( d_vars[index][j] );\r
-          if( vn!=-1 ){\r
-            TNode vv = getCurrentValue( d_vars[index][j] );\r
-            if( vv==d_vars[index][j] ){\r
-              //we will assign this\r
-              if( slv_v==-1 ){\r
-                Trace("qcf-tconstraint-debug") << "...will solve for var #" << vn << std::endl;\r
-                slv_v = vn;\r
-                if( p->d_effort!=QuantConflictFind::effort_conflict ){\r
-                  break;\r
-                }\r
-              }else{\r
-                Node z = p->getZero( k );\r
-                if( !z.isNull() ){\r
-                  Trace("qcf-tconstraint-debug") << "...set " << d_vars[vn] << " = " << z << std::endl;\r
-                  assigned.push_back( vn );\r
-                  if( !setMatch( p, vn, z ) ){\r
-                    success = false;\r
-                    break;\r
-                  }\r
-                }\r
-              }\r
-            }else{\r
-              Trace("qcf-tconstraint-debug") << "...sum value " << vv << std::endl;\r
-              children.push_back( vv );\r
-            }\r
-          }else{\r
-            Trace("qcf-tconstraint-debug") << "...sum " << d_vars[index][j] << std::endl;\r
-            children.push_back( d_vars[index][j] );\r
-          }\r
-        }\r
-        if( success ){\r
-          if( slv_v!=-1 ){\r
-            Node lhs;\r
-            if( children.empty() ){\r
-              lhs = p->getZero( k );\r
-            }else if( children.size()==1 ){\r
-              lhs = children[0];\r
-            }else{\r
-              lhs = NodeManager::currentNM()->mkNode( k, children );\r
-            }\r
-            Node sum;\r
-            if( v==d_vars[index] ){\r
-              sum = lhs;\r
-            }else{\r
-              if( p->d_effort==QuantConflictFind::effort_conflict ){\r
-                Kind kn = k;\r
-                if( d_vars[index].getKind()==PLUS ){\r
-                  kn = MINUS;\r
-                }\r
-                if( kn!=k ){\r
-                  sum = NodeManager::currentNM()->mkNode( kn, v, lhs );\r
-                }\r
-              }\r
-            }\r
-            if( !sum.isNull() ){\r
-              assigned.push_back( slv_v );\r
-              Trace("qcf-tconstraint-debug") << "...set " << d_vars[slv_v] << " = " << sum << std::endl;\r
-              if( !setMatch( p, slv_v, sum ) ){\r
-                success = false;\r
-              }\r
-              p->d_tempCache.push_back( sum );\r
-            }\r
-          }else{\r
-            //must show that constraint is met\r
-            Node sum = NodeManager::currentNM()->mkNode( k, children );\r
-            Node eq = sum.eqNode( v );\r
-            if( !entailmentTest( p, eq ) ){\r
-              success = false;\r
-            }\r
-            p->d_tempCache.push_back( sum );\r
-          }\r
-        }\r
-      }\r
-\r
-      if( !success ){\r
-        break;\r
-      }\r
-    }\r
-    if( success ){\r
-      //check what is left to assign\r
-      d_unassigned.clear();\r
-      d_unassigned_tn.clear();\r
-      std::vector< int > unassigned[2];\r
-      std::vector< TypeNode > unassigned_tn[2];\r
-      for( int i=0; i<getNumVars(); i++ ){\r
-        if( d_match[i].isNull() ){\r
-          int rindex = d_var_mg.find( i )==d_var_mg.end() ? 1 : 0;\r
-          unassigned[rindex].push_back( i );\r
-          unassigned_tn[rindex].push_back( getVar( i ).getType() );\r
-          assigned.push_back( i );\r
-        }\r
-      }\r
-      d_unassigned_nvar = unassigned[0].size();\r
-      for( unsigned i=0; i<2; i++ ){\r
-        d_unassigned.insert( d_unassigned.end(), unassigned[i].begin(), unassigned[i].end() );\r
-        d_unassigned_tn.insert( d_unassigned_tn.end(), unassigned_tn[i].begin(), unassigned_tn[i].end() );\r
-      }\r
-      d_una_eqc_count.clear();\r
-      d_una_index = 0;\r
-    }\r
-  }\r
-\r
-  if( !d_unassigned.empty() && ( success || doContinue ) ){\r
-    Trace("qcf-check") << "Assign to unassigned..." << std::endl;\r
-    do {\r
-      if( doFail ){\r
-        Trace("qcf-check-unassign") << "Failure, try again..." << std::endl;\r
-      }\r
-      bool invalidMatch = false;\r
-      while( ( d_una_index>=0 && (int)d_una_index<(int)d_unassigned.size() ) || invalidMatch || doFail ){\r
-        invalidMatch = false;\r
-        if( !doFail && d_una_index==(int)d_una_eqc_count.size() ){\r
-          //check if it has now been assigned\r
-          if( d_una_index<d_unassigned_nvar ){\r
-            if( !isConstrainedVar( d_unassigned[d_una_index] ) ){\r
-              d_una_eqc_count.push_back( -1 );\r
-            }else{\r
-              d_var_mg[ d_unassigned[d_una_index] ]->reset( p, true, this );\r
-              d_una_eqc_count.push_back( 0 );\r
-            }\r
-          }else{\r
-            d_una_eqc_count.push_back( 0 );\r
-          }\r
-        }else{\r
-          bool failed = false;\r
-          if( !doFail ){\r
-            if( d_una_index<d_unassigned_nvar ){\r
-              if( !isConstrainedVar( d_unassigned[d_una_index] ) ){\r
-                Trace("qcf-check-unassign") << "Succeeded, variable unconstrained at " << d_una_index << std::endl;\r
-                d_una_index++;\r
-              }else if( d_var_mg[d_unassigned[d_una_index]]->getNextMatch( p, this ) ){\r
-                Trace("qcf-check-unassign") << "Succeeded match with mg at " << d_una_index << std::endl;\r
-                d_una_index++;\r
-              }else{\r
-                failed = true;\r
-                Trace("qcf-check-unassign") << "Failed match with mg at " << d_una_index << std::endl;\r
-              }\r
-            }else{\r
-              Assert( doFail || d_una_index==(int)d_una_eqc_count.size()-1 );\r
-              if( d_una_eqc_count[d_una_index]<(int)p->d_eqcs[d_unassigned_tn[d_una_index]].size() ){\r
-                int currIndex = d_una_eqc_count[d_una_index];\r
-                d_una_eqc_count[d_una_index]++;\r
-                Trace("qcf-check-unassign") << d_unassigned[d_una_index] << "->" << p->d_eqcs[d_unassigned_tn[d_una_index]][currIndex] << std::endl;\r
-                if( setMatch( p, d_unassigned[d_una_index], p->d_eqcs[d_unassigned_tn[d_una_index]][currIndex] ) ){\r
-                  d_match_term[d_unassigned[d_una_index]] = TNode::null();\r
-                  Trace("qcf-check-unassign") << "Succeeded match " << d_una_index << std::endl;\r
-                  d_una_index++;\r
-                }else{\r
-                  Trace("qcf-check-unassign") << "Failed match " << d_una_index << std::endl;\r
-                  invalidMatch = true;\r
-                }\r
-              }else{\r
-                failed = true;\r
-                Trace("qcf-check-unassign") << "No more matches " << d_una_index << std::endl;\r
-              }\r
-            }\r
-          }\r
-          if( doFail || failed ){\r
-            do{\r
-              if( !doFail ){\r
-                d_una_eqc_count.pop_back();\r
-              }else{\r
-                doFail = false;\r
-              }\r
-              d_una_index--;\r
-            }while( d_una_index>=0 && d_una_eqc_count[d_una_index]==-1 );\r
-          }\r
-        }\r
-      }\r
-      success = d_una_index>=0;\r
-      if( success ){\r
-        doFail = true;\r
-        Trace("qcf-check-unassign") << "  Try: " << std::endl;\r
-        for( unsigned i=0; i<d_unassigned.size(); i++ ){\r
-          int ui = d_unassigned[i];\r
-          if( !d_match[ui].isNull() ){\r
-            Trace("qcf-check-unassign") << "  Assigned #" << ui << " : " << d_vars[ui] << " -> " << d_match[ui] << std::endl;\r
-          }\r
-        }\r
-      }\r
-    }while( success && isMatchSpurious( p ) );\r
-  }\r
-  if( success ){\r
-    for( unsigned i=0; i<d_unassigned.size(); i++ ){\r
-      int ui = d_unassigned[i];\r
-      if( !d_match[ui].isNull() ){\r
-        Trace("qcf-check") << "  Assigned #" << ui << " : " << d_vars[ui] << " -> " << d_match[ui] << std::endl;\r
-      }\r
-    }\r
-    return true;\r
-  }else{\r
-    for( unsigned i=0; i<assigned.size(); i++ ){\r
-      d_match[ assigned[i] ] = TNode::null();\r
-    }\r
-    assigned.clear();\r
-    return false;\r
-  }\r
-}\r
-\r
-void QuantInfo::getMatch( std::vector< Node >& terms ){\r
-  for( unsigned i=0; i<d_q[0].getNumChildren(); i++ ){\r
-    //Node cv = qi->getCurrentValue( qi->d_match[i] );\r
-    int repVar = getCurrentRepVar( i );\r
-    Node cv;\r
-    //std::map< int, TNode >::iterator itmt = qi->d_match_term.find( repVar );\r
-    if( !d_match_term[repVar].isNull() ){\r
-      cv = d_match_term[repVar];\r
-    }else{\r
-      cv = d_match[repVar];\r
-    }\r
-    Debug("qcf-check-inst") << "INST : " << i << " -> " << cv << ", from " << d_match[i] << std::endl;\r
-    terms.push_back( cv );\r
-  }\r
-}\r
-\r
-void QuantInfo::revertMatch( std::vector< int >& assigned ) {\r
-  for( unsigned i=0; i<assigned.size(); i++ ){\r
-    d_match[ assigned[i] ] = TNode::null();\r
-  }\r
-}\r
-\r
-void QuantInfo::debugPrintMatch( const char * c ) {\r
-  for( int i=0; i<getNumVars(); i++ ){\r
-    Trace(c) << "  " << d_vars[i] << " -> ";\r
-    if( !d_match[i].isNull() ){\r
-      Trace(c) << d_match[i];\r
-    }else{\r
-      Trace(c) << "(unassigned) ";\r
-    }\r
-    if( !d_curr_var_deq[i].empty() ){\r
-      Trace(c) << ", DEQ{ ";\r
-      for( std::map< TNode, int >::iterator it = d_curr_var_deq[i].begin(); it != d_curr_var_deq[i].end(); ++it ){\r
-        Trace(c) << it->first << " ";\r
-      }\r
-      Trace(c) << "}";\r
-    }\r
-    if( !d_match_term[i].isNull() && d_match_term[i]!=d_match[i] ){\r
-      Trace(c) << ", EXP : " << d_match_term[i];\r
-    }\r
-    Trace(c) <<  std::endl;\r
-  }\r
-  if( !d_tconstraints.empty() ){\r
-    Trace(c) << "ADDITIONAL CONSTRAINTS : " << std::endl;\r
-    for( std::map< Node, bool >::iterator it = d_tconstraints.begin(); it != d_tconstraints.end(); ++it ){\r
-      Trace(c) << "   " << it->first << " -> " << it->second << std::endl;\r
-    }\r
-  }\r
-}\r
-\r
-MatchGen::MatchGen( QuantInfo * qi, Node n, bool isVar ){\r
-  Trace("qcf-qregister-debug") << "Make match gen for " << n << ", isVar = " << isVar << std::endl;\r
-  std::vector< Node > qni_apps;\r
-  d_qni_size = 0;\r
-  if( isVar ){\r
-    Assert( qi->d_var_num.find( n )!=qi->d_var_num.end() );\r
-    if( n.getKind()==ITE ){\r
-      d_type = typ_ite_var;\r
-      d_type_not = false;\r
-      d_n = n;\r
-      d_children.push_back( MatchGen( qi, d_n[0] ) );\r
-      if( d_children[0].isValid() ){\r
-        d_type = typ_ite_var;\r
-        for( unsigned i=1; i<=2; i++ ){\r
-          Node nn = n.eqNode( n[i] );\r
-          d_children.push_back( MatchGen( qi, nn ) );\r
-          d_children[d_children.size()-1].d_qni_bound_except.push_back( 0 );\r
-          if( !d_children[d_children.size()-1].isValid() ){\r
-            setInvalid();\r
-            break;\r
-          }\r
-        }\r
-      }else{\r
-        d_type = typ_invalid;\r
-      }\r
-    }else{\r
-      d_type = isHandledUfTerm( n ) ? typ_var : typ_tsym;\r
-      d_qni_var_num[0] = qi->getVarNum( n );\r
-      d_qni_size++;\r
-      d_type_not = false;\r
-      d_n = n;\r
-      //Node f = getOperator( n );\r
-      for( unsigned j=0; j<d_n.getNumChildren(); j++ ){\r
-        Node nn = d_n[j];\r
-        Trace("qcf-qregister-debug") << "  " << d_qni_size;\r
-        if( qi->isVar( nn ) ){\r
-          int v = qi->d_var_num[nn];\r
-          Trace("qcf-qregister-debug") << " is var #" << v << std::endl;\r
-          d_qni_var_num[d_qni_size] = v;\r
-          //qi->addFuncParent( v, f, j );\r
-        }else{\r
-          Trace("qcf-qregister-debug") << " is gterm " << nn << std::endl;\r
-          d_qni_gterm[d_qni_size] = nn;\r
-        }\r
-        d_qni_size++;\r
-      }\r
-    }\r
-  }else{\r
-    if( n.hasBoundVar() ){\r
-      d_type_not = false;\r
-      d_n = n;\r
-      if( d_n.getKind()==NOT ){\r
-        d_n = d_n[0];\r
-        d_type_not = !d_type_not;\r
-      }\r
-\r
-      if( isHandledBoolConnective( d_n ) ){\r
-        //non-literals\r
-        d_type = typ_formula;\r
-        for( unsigned i=0; i<d_n.getNumChildren(); i++ ){\r
-          if( d_n.getKind()!=FORALL || i==1 ){\r
-            d_children.push_back( MatchGen( qi, d_n[i], false ) );\r
-            if( !d_children[d_children.size()-1].isValid() ){\r
-              setInvalid();\r
-              break;\r
-            }\r
-          }\r
-          /*\r
-          else if( isTop && n.getKind()==OR && d_children[d_children.size()-1].d_type==typ_var_eq ){\r
-            Trace("qcf-qregister-debug") << "Remove child, make built-in constraint" << std::endl;\r
-            //if variable equality/disequality at top level, remove immediately\r
-            bool cIsNot = d_children[d_children.size()-1].d_type_not;\r
-            Node cn = d_children[d_children.size()-1].d_n;\r
-            Assert( cn.getKind()==EQUAL );\r
-            Assert( p->d_qinfo[q].isVar( cn[0] ) || p->d_qinfo[q].isVar( cn[1] ) );\r
-            //make it a built-in constraint instead\r
-            for( unsigned i=0; i<2; i++ ){\r
-              if( p->d_qinfo[q].isVar( cn[i] ) ){\r
-                int v = p->d_qinfo[q].getVarNum( cn[i] );\r
-                Node cno = cn[i==0 ? 1 : 0];\r
-                p->d_qinfo[q].d_var_constraint[ cIsNot ? 0 : 1 ][v].push_back( cno );\r
-                break;\r
-              }\r
-            }\r
-            d_children.pop_back();\r
-          }\r
-          */\r
-        }\r
-      }else{\r
-        d_type = typ_invalid;\r
-        //literals\r
-        if( isHandledUfTerm( d_n ) ){\r
-          Assert( qi->isVar( d_n ) );\r
-          d_type = typ_pred;\r
-        }else if( d_n.getKind()==BOUND_VARIABLE ){\r
-          Assert( d_n.getType().isBoolean() );\r
-          d_type = typ_bool_var;\r
-        }else if( d_n.getKind()==EQUAL || options::qcfTConstraint() ){\r
-          for( unsigned i=0; i<d_n.getNumChildren(); i++ ){\r
-            if( d_n[i].hasBoundVar() ){\r
-              if( !qi->isVar( d_n[i] ) ){\r
-                Trace("qcf-qregister-debug")  << "ERROR : not var " << d_n[i] << std::endl;\r
-              }\r
-              Assert( qi->isVar( d_n[i] ) );\r
-              if( d_n.getKind()!=EQUAL && qi->isVar( d_n[i] ) ){\r
-                d_qni_var_num[i+1] = qi->d_var_num[d_n[i]];\r
-              }\r
-            }else{\r
-              d_qni_gterm[i] = d_n[i];\r
-            }\r
-          }\r
-          d_type = d_n.getKind()==EQUAL ? typ_eq : typ_tconstraint;\r
-          Trace("qcf-tconstraint") << "T-Constraint : " << d_n << std::endl;\r
-        }\r
-      }\r
-    }else{\r
-      //we will just evaluate\r
-      d_n = n;\r
-      d_type = typ_ground;\r
-    }\r
-    //if( d_type!=typ_invalid ){\r
-      //determine an efficient children ordering\r
-      //if( !d_children.empty() ){\r
-        //for( unsigned i=0; i<d_children.size(); i++ ){\r
-        //  d_children_order.push_back( i );\r
-        //}\r
-        //if( !d_n.isNull() && ( d_n.getKind()==OR || d_n.getKind()==AND || d_n.getKind()==IFF ) ){\r
-          //sort based on the type of the constraint : ground comes first, then literals, then others\r
-          //MatchGenSort mgs;\r
-          //mgs.d_mg = this;\r
-          //std::sort( d_children_order.begin(), d_children_order.end(), mgs );\r
-        //}\r
-      //}\r
-    //}\r
-  }\r
-  Trace("qcf-qregister-debug")  << "Done make match gen " << n << ", type = ";\r
-  debugPrintType( "qcf-qregister-debug", d_type, true );\r
-  Trace("qcf-qregister-debug") << std::endl;\r
-  //Assert( d_children.size()==d_children_order.size() );\r
-\r
-}\r
-\r
-void MatchGen::collectBoundVar( QuantInfo * qi, Node n, std::vector< int >& cbvars ) {\r
-  int v = qi->getVarNum( n );\r
-  if( v!=-1 && std::find( cbvars.begin(), cbvars.end(), v )==cbvars.end() ){\r
-    cbvars.push_back( v );\r
-  }\r
-  for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-    collectBoundVar( qi, n[i], cbvars );\r
-  }\r
-}\r
-\r
-void MatchGen::determineVariableOrder( QuantInfo * qi, std::vector< int >& bvars ) {\r
-  Trace("qcf-qregister-debug") << "Determine variable order " << d_n << std::endl;\r
-  bool isCom = d_type==typ_formula && ( d_n.getKind()==OR || d_n.getKind()==AND || d_n.getKind()==IFF );\r
-  std::map< int, std::vector< int > > c_to_vars;\r
-  std::map< int, std::vector< int > > vars_to_c;\r
-  std::map< int, int > vb_count;\r
-  std::map< int, int > vu_count;\r
-  std::vector< bool > assigned;\r
-  Trace("qcf-qregister-debug") << "Calculate bound variables..." << std::endl;\r
-  for( unsigned i=0; i<d_children.size(); i++ ){\r
-    collectBoundVar( qi, d_children[i].d_n, c_to_vars[i] );\r
-    assigned.push_back( false );\r
-    vb_count[i] = 0;\r
-    vu_count[i] = 0;\r
-    for( unsigned j=0; j<c_to_vars[i].size(); j++ ){\r
-      int v = c_to_vars[i][j];\r
-      vars_to_c[v].push_back( i );\r
-      if( std::find( bvars.begin(), bvars.end(), v )==bvars.end() ){\r
-        vu_count[i]++;\r
-        if( !isCom ){\r
-          bvars.push_back( v );\r
-        }\r
-      }else{\r
-        vb_count[i]++;\r
-      }\r
-    }\r
-  }\r
-  if( isCom ){\r
-    //children that bind the least number of unbound variables go first\r
-    do {\r
-      int min_score = -1;\r
-      int min_score_index = -1;\r
-      for( unsigned i=0; i<d_children.size(); i++ ){\r
-        if( !assigned[i] ){\r
-          int score = vu_count[i];\r
-          if( min_score==-1 || score<min_score ){\r
-            min_score = score;\r
-            min_score_index = i;\r
-          }\r
-        }\r
-      }\r
-      Trace("qcf-qregister-debug") << "...assign child " << min_score_index << "/" << d_children.size() << std::endl;\r
-      Assert( min_score_index!=-1 );\r
-      //add to children order\r
-      d_children_order.push_back( min_score_index );\r
-      assigned[min_score_index] = true;\r
-      //if( vb_count[min_score_index]==0 ){\r
-      //  d_independent.push_back( min_score_index );\r
-      //}\r
-      //determine order internal to children\r
-      d_children[min_score_index].determineVariableOrder( qi, bvars );\r
-      Trace("qcf-qregister-debug")  << "...bind variables" << std::endl;\r
-      //now, make it a bound variable\r
-      for( unsigned i=0; i<c_to_vars[min_score_index].size(); i++ ){\r
-        int v = c_to_vars[min_score_index][i];\r
-        if( std::find( bvars.begin(), bvars.end(), v )==bvars.end() ){\r
-          for( unsigned j=0; j<vars_to_c[v].size(); j++ ){\r
-            int vc = vars_to_c[v][j];\r
-            vu_count[vc]--;\r
-            vb_count[vc]++;\r
-          }\r
-          bvars.push_back( v );\r
-        }\r
-      }\r
-      Trace("qcf-qregister-debug") << "...done assign child " << min_score_index << std::endl;\r
-    }while( d_children_order.size()!=d_children.size() );\r
-    Trace("qcf-qregister-debug") << "Done assign variable ordering for " << d_n << std::endl;\r
-  }else{\r
-    for( unsigned i=0; i<d_children.size(); i++ ){\r
-      d_children_order.push_back( i );\r
-      d_children[i].determineVariableOrder( qi, bvars );\r
-    }\r
-  }\r
-}\r
-\r
-\r
-void MatchGen::reset_round( QuantConflictFind * p ) {\r
-  d_wasSet = false;\r
-  for( unsigned i=0; i<d_children.size(); i++ ){\r
-    d_children[i].reset_round( p );\r
-  }\r
-  for( std::map< int, TNode >::iterator it = d_qni_gterm.begin(); it != d_qni_gterm.end(); ++it ){\r
-    d_qni_gterm_rep[it->first] = p->getRepresentative( it->second );\r
-  }\r
-  if( d_type==typ_ground ){\r
-    int e = p->evaluate( d_n );\r
-    if( e==1 ){\r
-      d_ground_eval[0] = p->d_true;\r
-    }else if( e==-1 ){\r
-      d_ground_eval[0] = p->d_false;\r
-    }\r
-  }else if( d_type==typ_eq ){\r
-    for( unsigned i=0; i<d_n.getNumChildren(); i++ ){\r
-      if( !d_n[i].hasBoundVar() ){\r
-        d_ground_eval[i] = p->evaluateTerm( d_n[i] );\r
-      }\r
-    }\r
-  }\r
-  d_qni_bound_cons.clear();\r
-  d_qni_bound_cons_var.clear();\r
-  d_qni_bound.clear();\r
-}\r
-\r
-void MatchGen::reset( QuantConflictFind * p, bool tgt, QuantInfo * qi ) {\r
-  d_tgt = d_type_not ? !tgt : tgt;\r
-  Debug("qcf-match") << "     Reset for : " << d_n << ", type : ";\r
-  debugPrintType( "qcf-match", d_type );\r
-  Debug("qcf-match") << ", tgt = " << d_tgt << ", children = " << d_children.size() << " " << d_children_order.size() << std::endl;\r
-  d_qn.clear();\r
-  d_qni.clear();\r
-  d_qni_bound.clear();\r
-  d_child_counter = -1;\r
-  d_tgt_orig = d_tgt;\r
-\r
-  //set up processing matches\r
-  if( d_type==typ_invalid ){\r
-    //do nothing\r
-  }else if( d_type==typ_ground ){\r
-    if( d_ground_eval[0]==( d_tgt ? p->d_true : p->d_false ) ){\r
-      d_child_counter = 0;\r
-    }\r
-  }else if( d_type==typ_bool_var ){\r
-    //get current value of the variable\r
-    TNode n = qi->getCurrentValue( d_n );\r
-    int vn = qi->getCurrentRepVar( qi->getVarNum( n ) );\r
-    if( vn==-1 ){\r
-      //evaluate the value, see if it is compatible\r
-      int e = p->evaluate( n );\r
-      if( ( e==1 && d_tgt ) || ( e==0 && !d_tgt ) ){\r
-        d_child_counter = 0;\r
-      }\r
-    }else{\r
-      //unassigned, set match to true/false\r
-      d_qni_bound[0] = vn;\r
-      qi->setMatch( p, vn, d_tgt ? p->d_true : p->d_false );\r
-      d_child_counter = 0;\r
-    }\r
-    if( d_child_counter==0 ){\r
-      d_qn.push_back( NULL );\r
-    }\r
-  }else if( d_type==typ_var ){\r
-    Assert( isHandledUfTerm( d_n ) );\r
-    Node f = getOperator( p, d_n );\r
-    Debug("qcf-match-debug") << "       reset: Var will match operators of " << f << std::endl;\r
-    QcfNodeIndex * qni = p->getQcfNodeIndex( Node::null(), f );\r
-    if( qni!=NULL ){\r
-      d_qn.push_back( qni );\r
-    }\r
-    d_matched_basis = false;\r
-  }else if( d_type==typ_tsym || d_type==typ_tconstraint ){\r
-    for( std::map< int, int >::iterator it = d_qni_var_num.begin(); it != d_qni_var_num.end(); ++it ){\r
-      int repVar = qi->getCurrentRepVar( it->second );\r
-      if( qi->d_match[repVar].isNull() ){\r
-        Debug("qcf-match-debug") << "Force matching on child #" << it->first << ", which is var #" << repVar << std::endl;\r
-        d_qni_bound[it->first] = repVar;\r
-      }\r
-    }\r
-    d_qn.push_back( NULL );\r
-  }else if( d_type==typ_pred || d_type==typ_eq ){\r
-    //add initial constraint\r
-    Node nn[2];\r
-    int vn[2];\r
-    if( d_type==typ_pred ){\r
-      nn[0] = qi->getCurrentValue( d_n );\r
-      vn[0] = qi->getCurrentRepVar( qi->getVarNum( nn[0] ) );\r
-      nn[1] = p->getRepresentative( d_tgt ? p->d_true : p->d_false );\r
-      vn[1] = -1;\r
-      d_tgt = true;\r
-    }else{\r
-      for( unsigned i=0; i<2; i++ ){\r
-        TNode nc;\r
-        std::map< int, TNode >::iterator it = d_qni_gterm_rep.find( i );\r
-        if( it!=d_qni_gterm_rep.end() ){\r
-          nc = it->second;\r
-        }else{\r
-          nc = d_n[i];\r
-        }\r
-        nn[i] = qi->getCurrentValue( nc );\r
-        vn[i] = qi->getCurrentRepVar( qi->getVarNum( nn[i] ) );\r
-      }\r
-    }\r
-    bool success;\r
-    if( vn[0]==-1 && vn[1]==-1 ){\r
-      //Trace("qcf-explain") << "    reset : " << d_n << " check ground values " << nn[0] << " " << nn[1] << " (tgt=" << d_tgt << ")" << std::endl;\r
-      Debug("qcf-match-debug") << "       reset: check ground values " << nn[0] << " " << nn[1] << " (" << d_tgt << ")" << std::endl;\r
-      //just compare values\r
-      if( d_tgt ){\r
-        success = p->areMatchEqual( nn[0], nn[1] );\r
-      }else{\r
-        if( p->d_effort==QuantConflictFind::effort_conflict ){\r
-          success = p->areDisequal( nn[0], nn[1] );\r
-        }else{\r
-          success = p->areMatchDisequal( nn[0], nn[1] );\r
-        }\r
-      }\r
-    }else{\r
-      //otherwise, add a constraint to a variable\r
-      if( vn[1]!=-1 && vn[0]==-1 ){\r
-        //swap\r
-        Node t = nn[1];\r
-        nn[1] = nn[0];\r
-        nn[0] = t;\r
-        vn[0] = vn[1];\r
-        vn[1] = -1;\r
-      }\r
-      Debug("qcf-match-debug") << "       reset: add constraint " << vn[0] << " -> " << nn[1] << " (vn=" << vn[1] << ")" << std::endl;\r
-      //add some constraint\r
-      int addc = qi->addConstraint( p, vn[0], nn[1], vn[1], d_tgt, false );\r
-      success = addc!=-1;\r
-      //if successful and non-redundant, store that we need to cleanup this\r
-      if( addc==1 ){\r
-        //Trace("qcf-explain") << "       reset: " << d_n << " add constraint " << vn[0] << " -> " << nn[1] << " (vn=" << vn[1] << ")" << ", d_tgt = " << d_tgt << std::endl;\r
-        for( unsigned i=0; i<2; i++ ){\r
-          if( vn[i]!=-1 && std::find( d_qni_bound_except.begin(), d_qni_bound_except.end(), i )==d_qni_bound_except.end() ){\r
-            d_qni_bound[vn[i]] = vn[i];\r
-          }\r
-        }\r
-        d_qni_bound_cons[vn[0]] = nn[1];\r
-        d_qni_bound_cons_var[vn[0]] = vn[1];\r
-      }\r
-    }\r
-    //if successful, we will bind values to variables\r
-    if( success ){\r
-      d_qn.push_back( NULL );\r
-    }\r
-  }else{\r
-    if( d_children.empty() ){\r
-      //add dummy\r
-      d_qn.push_back( NULL );\r
-    }else{\r
-      if( d_tgt && d_n.getKind()==FORALL ){\r
-        //do nothing\r
-      }else{\r
-        //reset the first child to d_tgt\r
-        d_child_counter = 0;\r
-        getChild( d_child_counter )->reset( p, d_tgt, qi );\r
-      }\r
-    }\r
-  }\r
-  d_binding = false;\r
-  d_wasSet = true;\r
-  Debug("qcf-match") << "     reset: Finished reset for " << d_n << ", success = " << ( !d_qn.empty() || d_child_counter!=-1 ) << std::endl;\r
-}\r
-\r
-bool MatchGen::getNextMatch( QuantConflictFind * p, QuantInfo * qi ) {\r
-  Debug("qcf-match") << "     Get next match for : " << d_n << ", type = ";\r
-  debugPrintType( "qcf-match", d_type );\r
-  Debug("qcf-match") << ", children = " << d_children.size() << ", binding = " << d_binding << std::endl;\r
-  if( d_type==typ_invalid || d_type==typ_ground ){\r
-    if( d_child_counter==0 ){\r
-      d_child_counter = -1;\r
-      return true;\r
-    }else{\r
-      d_wasSet = false;\r
-      return false;\r
-    }\r
-  }else if( d_type==typ_var || d_type==typ_eq || d_type==typ_pred || d_type==typ_bool_var || d_type==typ_tconstraint || d_type==typ_tsym ){\r
-    bool success = false;\r
-    bool terminate = false;\r
-    do {\r
-      bool doReset = false;\r
-      bool doFail = false;\r
-      if( !d_binding ){\r
-        if( doMatching( p, qi ) ){\r
-          Debug("qcf-match-debug") << "     - Matching succeeded" << std::endl;\r
-          d_binding = true;\r
-          d_binding_it = d_qni_bound.begin();\r
-          doReset = true;\r
-          //for tconstraint, add constraint\r
-          if( d_type==typ_tconstraint ){\r
-            std::map< Node, bool >::iterator it = qi->d_tconstraints.find( d_n );\r
-            if( it==qi->d_tconstraints.end() ){\r
-              qi->d_tconstraints[d_n] = d_tgt;\r
-              //store that we added this constraint\r
-              d_qni_bound_cons[0] = d_n;\r
-            }else if( d_tgt!=it->second ){\r
-              success = false;\r
-              terminate = true;\r
-            }\r
-          }\r
-        }else{\r
-          Debug("qcf-match-debug") << "     - Matching failed" << std::endl;\r
-          success = false;\r
-          terminate = true;\r
-        }\r
-      }else{\r
-        doFail = true;\r
-      }\r
-      if( d_binding ){\r
-        //also need to create match for each variable we bound\r
-        success = true;\r
-        Debug("qcf-match-debug") << "     Produce matches for bound variables by " << d_n << ", type = ";\r
-        debugPrintType( "qcf-match-debug", d_type );\r
-        Debug("qcf-match-debug") << "..." << std::endl;\r
-\r
-        while( ( success && d_binding_it!=d_qni_bound.end() ) || doFail ){\r
-          std::map< int, MatchGen * >::iterator itm;\r
-          if( !doFail ){\r
-            Debug("qcf-match-debug") << "       check variable " << d_binding_it->second << std::endl;\r
-            itm = qi->d_var_mg.find( d_binding_it->second );\r
-          }\r
-          if( doFail || ( d_binding_it->first!=0 && itm!=qi->d_var_mg.end() ) ){\r
-            Debug("qcf-match-debug") << "       we had bound variable " << d_binding_it->second << ", reset = " << doReset << std::endl;\r
-            if( doReset ){\r
-              itm->second->reset( p, true, qi );\r
-            }\r
-            if( doFail || !itm->second->getNextMatch( p, qi ) ){\r
-              do {\r
-                if( d_binding_it==d_qni_bound.begin() ){\r
-                  Debug("qcf-match-debug") << "       failed." << std::endl;\r
-                  success = false;\r
-                }else{\r
-                  --d_binding_it;\r
-                  Debug("qcf-match-debug") << "       decrement..." << std::endl;\r
-                }\r
-              }while( success && ( d_binding_it->first==0 || qi->d_var_mg.find( d_binding_it->second )==qi->d_var_mg.end() ) );\r
-              doReset = false;\r
-              doFail = false;\r
-            }else{\r
-              Debug("qcf-match-debug") << "       increment..." << std::endl;\r
-              ++d_binding_it;\r
-              doReset = true;\r
-            }\r
-          }else{\r
-            Debug("qcf-match-debug") << "       skip..." << d_binding_it->second << std::endl;\r
-            ++d_binding_it;\r
-            doReset = true;\r
-          }\r
-        }\r
-        if( !success ){\r
-          d_binding = false;\r
-        }else{\r
-          terminate = true;\r
-          if( d_binding_it==d_qni_bound.begin() ){\r
-            d_binding = false;\r
-          }\r
-        }\r
-      }\r
-    }while( !terminate );\r
-    //if not successful, clean up the variables you bound\r
-    if( !success ){\r
-      if( d_type==typ_eq || d_type==typ_pred ){\r
-        //clean up the constraints you added\r
-        for( std::map< int, TNode >::iterator it = d_qni_bound_cons.begin(); it != d_qni_bound_cons.end(); ++it ){\r
-          if( !it->second.isNull() ){\r
-            Debug("qcf-match") << "       Clean up bound var " << it->first << (d_tgt ? "!" : "") << " = " << it->second << std::endl;\r
-            std::map< int, int >::iterator itb = d_qni_bound_cons_var.find( it->first );\r
-            int vn = itb!=d_qni_bound_cons_var.end() ? itb->second : -1;\r
-            //Trace("qcf-explain") << "       cleanup: " << d_n << " remove constraint " << it->first << " -> " << it->second << " (vn=" << vn << ")" << ", d_tgt = " << d_tgt << std::endl;\r
-            qi->addConstraint( p, it->first, it->second, vn, d_tgt, true );\r
-          }\r
-        }\r
-        d_qni_bound_cons.clear();\r
-        d_qni_bound_cons_var.clear();\r
-        d_qni_bound.clear();\r
-      }else{\r
-        //clean up the matches you set\r
-        for( std::map< int, int >::iterator it = d_qni_bound.begin(); it != d_qni_bound.end(); ++it ){\r
-          Debug("qcf-match") << "       Clean up bound var " << it->second << std::endl;\r
-          Assert( it->second<qi->getNumVars() );\r
-          qi->d_match[ it->second ] = TNode::null();\r
-          qi->d_match_term[ it->second ] = TNode::null();\r
-        }\r
-        d_qni_bound.clear();\r
-      }\r
-      if( d_type==typ_tconstraint ){\r
-        //remove constraint if applicable\r
-        if( d_qni_bound_cons.find( 0 )!=d_qni_bound_cons.end() ){\r
-          qi->d_tconstraints.erase( d_n );\r
-          d_qni_bound_cons.clear();\r
-        }\r
-      }\r
-      /*\r
-      if( d_type==typ_var && p->d_effort==QuantConflictFind::effort_mc && !d_matched_basis ){\r
-        d_matched_basis = true;\r
-        Node f = getOperator( d_n );\r
-        TNode mbo = p->getQuantifiersEngine()->getTermDatabase()->getModelBasisOpTerm( f );\r
-        if( qi->setMatch( p, d_qni_var_num[0], mbo ) ){\r
-          success = true;\r
-          d_qni_bound[0] = d_qni_var_num[0];\r
-        }\r
-      }\r
-      */\r
-    }\r
-    Debug("qcf-match") << "    ...finished matching for " << d_n << ", success = " << success << std::endl;\r
-    d_wasSet = success;\r
-    return success;\r
-  }else if( d_type==typ_formula || d_type==typ_ite_var ){\r
-    bool success = false;\r
-    if( d_child_counter<0 ){\r
-      if( d_child_counter<-1 ){\r
-        success = true;\r
-        d_child_counter = -1;\r
-      }\r
-    }else{\r
-      while( !success && d_child_counter>=0 ){\r
-        //transition system based on d_child_counter\r
-        if( d_n.getKind()==OR || d_n.getKind()==AND ){\r
-          if( (d_n.getKind()==AND)==d_tgt ){\r
-            //all children must match simultaneously\r
-            if( getChild( d_child_counter )->getNextMatch( p, qi ) ){\r
-              if( d_child_counter<(int)(getNumChildren()-1) ){\r
-                d_child_counter++;\r
-                Debug("qcf-match-debug") << "       Reset child " << d_child_counter << " of " << d_n << std::endl;\r
-                getChild( d_child_counter )->reset( p, d_tgt, qi );\r
-              }else{\r
-                success = true;\r
-              }\r
-            }else{\r
-              //if( std::find( d_independent.begin(), d_independent.end(), d_child_counter )!=d_independent.end() ){\r
-              //  d_child_counter--;\r
-              //}else{\r
-              d_child_counter--;\r
-              //}\r
-            }\r
-          }else{\r
-            //one child must match\r
-            if( !getChild( d_child_counter )->getNextMatch( p, qi ) ){\r
-              if( d_child_counter<(int)(getNumChildren()-1) ){\r
-                d_child_counter++;\r
-                Debug("qcf-match-debug") << "       Reset child " << d_child_counter << " of " << d_n << ", one match" << std::endl;\r
-                getChild( d_child_counter )->reset( p, d_tgt, qi );\r
-              }else{\r
-                d_child_counter = -1;\r
-              }\r
-            }else{\r
-              success = true;\r
-            }\r
-          }\r
-        }else if( d_n.getKind()==IFF ){\r
-          //construct match based on both children\r
-          if( d_child_counter%2==0 ){\r
-            if( getChild( 0 )->getNextMatch( p, qi ) ){\r
-              d_child_counter++;\r
-              getChild( 1 )->reset( p, d_child_counter==1, qi );\r
-            }else{\r
-              if( d_child_counter==0 ){\r
-                d_child_counter = 2;\r
-                getChild( 0 )->reset( p, !d_tgt, qi );\r
-              }else{\r
-                d_child_counter = -1;\r
-              }\r
-            }\r
-          }\r
-          if( d_child_counter>=0 && d_child_counter%2==1 ){\r
-            if( getChild( 1 )->getNextMatch( p, qi ) ){\r
-              success = true;\r
-            }else{\r
-              d_child_counter--;\r
-            }\r
-          }\r
-        }else if( d_n.getKind()==ITE ){\r
-          if( d_child_counter%2==0 ){\r
-            int index1 = d_child_counter==4 ? 1 : 0;\r
-            if( getChild( index1 )->getNextMatch( p, qi ) ){\r
-              d_child_counter++;\r
-              getChild( d_child_counter==5 ? 2 : (d_tgt==(d_child_counter==1) ? 1 : 2) )->reset( p, d_tgt, qi );\r
-            }else{\r
-              if( d_child_counter==4 || ( d_type==typ_ite_var && d_child_counter==2 ) ){\r
-                d_child_counter = -1;\r
-              }else{\r
-                d_child_counter +=2;\r
-                getChild( d_child_counter==2 ? 0 : 1 )->reset( p, d_child_counter==2 ? !d_tgt : d_tgt, qi );\r
-              }\r
-            }\r
-          }\r
-          if( d_child_counter>=0 && d_child_counter%2==1 ){\r
-            int index2 = d_child_counter==5 ? 2 : (d_tgt==(d_child_counter==1) ? 1 : 2);\r
-            if( getChild( index2 )->getNextMatch( p, qi ) ){\r
-              success = true;\r
-            }else{\r
-              d_child_counter--;\r
-            }\r
-          }\r
-        }else if( d_n.getKind()==FORALL ){\r
-          if( getChild( d_child_counter )->getNextMatch( p, qi ) ){\r
-            success = true;\r
-          }else{\r
-            d_child_counter = -1;\r
-          }\r
-        }\r
-      }\r
-        d_wasSet = success;\r
-      Debug("qcf-match") << "    ...finished construct match for " << d_n << ", success = " << success << std::endl;\r
-      return success;\r
-    }\r
-  }\r
-  Debug("qcf-match") << "    ...already finished for " << d_n << std::endl;\r
-  return false;\r
-}\r
-\r
-bool MatchGen::getExplanation( QuantConflictFind * p, QuantInfo * qi, std::vector< Node >& exp ) {\r
-  if( d_type==typ_eq ){\r
-    Node n[2];\r
-    for( unsigned i=0; i<2; i++ ){\r
-      Trace("qcf-explain") << "Explain term " << d_n[i] << "..." << std::endl;\r
-      n[i] = getExplanationTerm( p, qi, d_n[i], exp );\r
-    }\r
-    Node eq = n[0].eqNode( n[1] );\r
-    if( !d_tgt_orig ){\r
-      eq = eq.negate();\r
-    }\r
-    exp.push_back( eq );\r
-    Trace("qcf-explain") << "Explanation for " << d_n << " (tgt=" << d_tgt_orig << ") is " << eq << ", set = " << d_wasSet << std::endl;\r
-    return true;\r
-  }else if( d_type==typ_pred ){\r
-    Trace("qcf-explain") << "Explain term " << d_n << "..." << std::endl;\r
-    Node n = getExplanationTerm( p, qi, d_n, exp );\r
-    if( !d_tgt_orig ){\r
-      n = n.negate();\r
-    }\r
-    exp.push_back( n );\r
-    Trace("qcf-explain") << "Explanation for " << d_n << " (tgt=" << d_tgt_orig << ") is " << n << ", set = " << d_wasSet << std::endl;\r
-    return true;\r
-  }else if( d_type==typ_formula ){\r
-    Trace("qcf-explain") << "Explanation get for " << d_n << ", counter = " << d_child_counter << ", tgt = " << d_tgt_orig << ", set = " << d_wasSet << std::endl;\r
-    if( d_n.getKind()==OR || d_n.getKind()==AND ){\r
-      if( (d_n.getKind()==AND)==d_tgt ){\r
-        for( unsigned i=0; i<getNumChildren(); i++ ){\r
-          if( !getChild( i )->getExplanation( p, qi, exp ) ){\r
-            return false;\r
-          }\r
-        }\r
-      }else{\r
-        return getChild( d_child_counter )->getExplanation( p, qi, exp );\r
-      }\r
-    }else if( d_n.getKind()==IFF ){\r
-      for( unsigned i=0; i<2; i++ ){\r
-        if( !getChild( i )->getExplanation( p, qi, exp ) ){\r
-          return false;\r
-        }\r
-      }\r
-    }else if( d_n.getKind()==ITE ){\r
-      for( unsigned i=0; i<3; i++ ){\r
-        bool isActive = ( ( i==0 && d_child_counter!=5 ) ||\r
-                          ( i==1 && d_child_counter!=( d_tgt ? 3 : 1 ) ) ||\r
-                          ( i==2 && d_child_counter!=( d_tgt ? 1 : 3 ) ) );\r
-        if( isActive ){\r
-          if( !getChild( i )->getExplanation( p, qi, exp ) ){\r
-            return false;\r
-          }\r
-        }\r
-      }\r
-    }else{\r
-      return false;\r
-    }\r
-    return true;\r
-  }else{\r
-    return false;\r
-  }\r
-}\r
-\r
-Node MatchGen::getExplanationTerm( QuantConflictFind * p, QuantInfo * qi, Node t, std::vector< Node >& exp ) {\r
-  Node v = qi->getCurrentExpValue( t );\r
-  if( isHandledUfTerm( t ) ){\r
-    for( unsigned i=0; i<t.getNumChildren(); i++ ){\r
-      Node vi = getExplanationTerm( p, qi, t[i], exp );\r
-      if( vi!=v[i] ){\r
-        Node eq = vi.eqNode( v[i] );\r
-        if( std::find( exp.begin(), exp.end(), eq )==exp.end() ){\r
-          Trace("qcf-explain") << "  add : " << eq << "." << std::endl;\r
-          exp.push_back( eq );\r
-        }\r
-      }\r
-    }\r
-  }\r
-  return v;\r
-}\r
-\r
-bool MatchGen::doMatching( QuantConflictFind * p, QuantInfo * qi ) {\r
-  if( !d_qn.empty() ){\r
-    if( d_qn[0]==NULL ){\r
-      d_qn.clear();\r
-      return true;\r
-    }else{\r
-      Assert( d_type==typ_var );\r
-      Assert( d_qni_size>0 );\r
-      bool invalidMatch;\r
-      do {\r
-        invalidMatch = false;\r
-        Debug("qcf-match-debug") << "       Do matching " << d_n << " " << d_qn.size() << " " << d_qni.size() << std::endl;\r
-        if( d_qn.size()==d_qni.size()+1 ) {\r
-          int index = (int)d_qni.size();\r
-          //initialize\r
-          TNode val;\r
-          std::map< int, int >::iterator itv = d_qni_var_num.find( index );\r
-          if( itv!=d_qni_var_num.end() ){\r
-            //get the representative variable this variable is equal to\r
-            int repVar = qi->getCurrentRepVar( itv->second );\r
-            Debug("qcf-match-debug") << "       Match " << index << " is a variable " << itv->second << ", which is repVar " << repVar << std::endl;\r
-            //get the value the rep variable\r
-            //std::map< int, TNode >::iterator itm = qi->d_match.find( repVar );\r
-            if( !qi->d_match[repVar].isNull() ){\r
-              val = qi->d_match[repVar];\r
-              Debug("qcf-match-debug") << "       Variable is already bound to " << val << std::endl;\r
-            }else{\r
-              //binding a variable\r
-              d_qni_bound[index] = repVar;\r
-              std::map< TNode, QcfNodeIndex >::iterator it = d_qn[index]->d_children.begin();\r
-              if( it != d_qn[index]->d_children.end() ) {\r
-                d_qni.push_back( it );\r
-                //set the match\r
-                if( qi->setMatch( p, d_qni_bound[index], it->first ) ){\r
-                  Debug("qcf-match-debug") << "       Binding variable" << std::endl;\r
-                  if( d_qn.size()<d_qni_size ){\r
-                    d_qn.push_back( &it->second );\r
-                  }\r
-                }else{\r
-                  Debug("qcf-match") << "       Binding variable, currently fail." << std::endl;\r
-                  invalidMatch = true;\r
-                }\r
-              }else{\r
-                Debug("qcf-match-debug") << "       Binding variable, fail, no more variables to bind" << std::endl;\r
-                d_qn.pop_back();\r
-              }\r
-            }\r
-          }else{\r
-            Debug("qcf-match-debug") << "       Match " << index << " is ground term" << std::endl;\r
-            Assert( d_qni_gterm.find( index )!=d_qni_gterm.end() );\r
-            Assert( d_qni_gterm_rep.find( index )!=d_qni_gterm_rep.end() );\r
-            val = d_qni_gterm_rep[index];\r
-            Assert( !val.isNull() );\r
-          }\r
-          if( !val.isNull() ){\r
-            //constrained by val\r
-            std::map< TNode, QcfNodeIndex >::iterator it = d_qn[index]->d_children.find( val );\r
-            if( it!=d_qn[index]->d_children.end() ){\r
-              Debug("qcf-match-debug") << "       Match" << std::endl;\r
-              d_qni.push_back( it );\r
-              if( d_qn.size()<d_qni_size ){\r
-                d_qn.push_back( &it->second );\r
-              }\r
-            }else{\r
-              Debug("qcf-match-debug") << "       Failed to match" << std::endl;\r
-              d_qn.pop_back();\r
-            }\r
-          }\r
-        }else{\r
-          Assert( d_qn.size()==d_qni.size() );\r
-          int index = d_qni.size()-1;\r
-          //increment if binding this variable\r
-          bool success = false;\r
-          std::map< int, int >::iterator itb = d_qni_bound.find( index );\r
-          if( itb!=d_qni_bound.end() ){\r
-            d_qni[index]++;\r
-            if( d_qni[index]!=d_qn[index]->d_children.end() ){\r
-              success = true;\r
-              if( qi->setMatch( p, itb->second, d_qni[index]->first ) ){\r
-                Debug("qcf-match-debug") << "       Bind next variable" << std::endl;\r
-                if( d_qn.size()<d_qni_size ){\r
-                  d_qn.push_back( &d_qni[index]->second );\r
-                }\r
-              }else{\r
-                Debug("qcf-match-debug") << "       Bind next variable, currently fail" << std::endl;\r
-                invalidMatch = true;\r
-              }\r
-            }else{\r
-              qi->d_match[ itb->second ] = TNode::null();\r
-              qi->d_match_term[ itb->second ] = TNode::null();\r
-              Debug("qcf-match-debug") << "       Bind next variable, no more variables to bind" << std::endl;\r
-            }\r
-          }else{\r
-            //TODO : if it equal to something else, also try that\r
-          }\r
-          //if not incrementing, move to next\r
-          if( !success ){\r
-            d_qn.pop_back();\r
-            d_qni.pop_back();\r
-          }\r
-        }\r
-      }while( ( !d_qn.empty() && d_qni.size()!=d_qni_size ) || invalidMatch );\r
-      if( d_qni.size()==d_qni_size ){\r
-        //Assert( !d_qni[d_qni.size()-1]->second.d_children.empty() );\r
-        //Debug("qcf-match-debug") << "       We matched " << d_qni[d_qni.size()-1]->second.d_children.begin()->first << std::endl;\r
-        Assert( !d_qni[d_qni.size()-1]->second.d_children.empty() );\r
-        TNode t = d_qni[d_qni.size()-1]->second.d_children.begin()->first;\r
-        Debug("qcf-match-debug") << "       " << d_n << " matched " << t << std::endl;\r
-        qi->d_match_term[d_qni_var_num[0]] = t;\r
-        //set the match terms\r
-        for( std::map< int, int >::iterator it = d_qni_bound.begin(); it != d_qni_bound.end(); ++it ){\r
-          Debug("qcf-match-debug") << "       position " << it->first << " bounded " << it->second << " / " << qi->d_q[0].getNumChildren() << std::endl;\r
-          //if( it->second<(int)qi->d_q[0].getNumChildren() ){   //if it is an actual variable, we are interested in knowing the actual term\r
-          if( it->first>0 ){\r
-            Assert( !qi->d_match[ it->second ].isNull() );\r
-            Assert( p->areEqual( t[it->first-1], qi->d_match[ it->second ] ) );\r
-            qi->d_match_term[it->second] = t[it->first-1];\r
-          }\r
-          //}\r
-        }\r
-      }\r
-    }\r
-  }\r
-  return !d_qn.empty();\r
-}\r
-\r
-void MatchGen::debugPrintType( const char * c, short typ, bool isTrace ) {\r
-  if( isTrace ){\r
-    switch( typ ){\r
-    case typ_invalid: Trace(c) << "invalid";break;\r
-    case typ_ground: Trace(c) << "ground";break;\r
-    case typ_eq: Trace(c) << "eq";break;\r
-    case typ_pred: Trace(c) << "pred";break;\r
-    case typ_formula: Trace(c) << "formula";break;\r
-    case typ_var: Trace(c) << "var";break;\r
-    case typ_ite_var: Trace(c) << "ite_var";break;\r
-    case typ_bool_var: Trace(c) << "bool_var";break;\r
-    }\r
-  }else{\r
-    switch( typ ){\r
-    case typ_invalid: Debug(c) << "invalid";break;\r
-    case typ_ground: Debug(c) << "ground";break;\r
-    case typ_eq: Debug(c) << "eq";break;\r
-    case typ_pred: Debug(c) << "pred";break;\r
-    case typ_formula: Debug(c) << "formula";break;\r
-    case typ_var: Debug(c) << "var";break;\r
-    case typ_ite_var: Debug(c) << "ite_var";break;\r
-    case typ_bool_var: Debug(c) << "bool_var";break;\r
-    }\r
-  }\r
-}\r
-\r
-void MatchGen::setInvalid() {\r
-  d_type = typ_invalid;\r
-  d_children.clear();\r
-}\r
-\r
-bool MatchGen::isHandledBoolConnective( TNode n ) {\r
-  return n.getType().isBoolean() && ( n.getKind()==OR || n.getKind()==AND || n.getKind()==IFF || n.getKind()==ITE || n.getKind()==FORALL || n.getKind()==NOT );\r
-}\r
-\r
-bool MatchGen::isHandledUfTerm( TNode n ) {\r
-  //return n.getKind()==APPLY_UF || n.getKind()==STORE || n.getKind()==SELECT ||\r
-  //       n.getKind()==APPLY_CONSTRUCTOR || n.getKind()==APPLY_SELECTOR_TOTAL || n.getKind()==APPLY_TESTER;\r
-  return inst::Trigger::isAtomicTriggerKind( n.getKind() );  \r
-}\r
-\r
-Node MatchGen::getOperator( QuantConflictFind * p, Node n ) {\r
-  if( isHandledUfTerm( n ) ){\r
-    return p->getQuantifiersEngine()->getTermDatabase()->getOperator( n );\r
-  }else{\r
-    return Node::null();\r
-  }\r
-}\r
-\r
-bool MatchGen::isHandled( TNode n ) {\r
-  if( n.getKind()!=BOUND_VARIABLE && n.hasBoundVar() ){\r
-    if( !isHandledBoolConnective( n ) && !isHandledUfTerm( n ) && n.getKind()!=EQUAL && n.getKind()!=ITE ){\r
-      return false;\r
-    }\r
-    for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-      if( !isHandled( n[i] ) ){\r
-        return false;\r
-      }\r
-    }\r
-  }\r
-  return true;\r
-}\r
-\r
-\r
-QuantConflictFind::QuantConflictFind( QuantifiersEngine * qe, context::Context* c ) :\r
-QuantifiersModule( qe ),\r
-d_c( c ),\r
-d_conflict( c, false ),\r
-d_qassert( c ) {\r
-  d_fid_count = 0;\r
-  d_true = NodeManager::currentNM()->mkConst<bool>(true);\r
-  d_false = NodeManager::currentNM()->mkConst<bool>(false);\r
-}\r
-\r
-Node QuantConflictFind::mkEqNode( Node a, Node b ) {\r
-  if( a.getType().isBoolean() ){\r
-    return a.iffNode( b );\r
-  }else{\r
-    return a.eqNode( b );\r
-  }\r
-}\r
-\r
-//-------------------------------------------------- registration\r
-\r
-void QuantConflictFind::registerQuantifier( Node q ) {\r
-  if( !TermDb::isRewriteRule( q ) ){\r
-    d_quants.push_back( q );\r
-    d_quant_id[q] = d_quants.size();\r
-    Trace("qcf-qregister") << "Register ";\r
-    debugPrintQuant( "qcf-qregister", q );\r
-    Trace("qcf-qregister") << " : " << q << std::endl;\r
-    //make QcfNode structure\r
-    Trace("qcf-qregister") << "- Get relevant equality/disequality pairs, calculate flattening..." << std::endl;\r
-    d_qinfo[q].initialize( q, q[1] );\r
-\r
-    //debug print\r
-    Trace("qcf-qregister") << "- Flattened structure is :" << std::endl;\r
-    Trace("qcf-qregister") << "    ";\r
-    debugPrintQuantBody( "qcf-qregister", q, q[1] );\r
-    Trace("qcf-qregister") << std::endl;\r
-    if( d_qinfo[q].d_vars.size()>q[0].getNumChildren() ){\r
-      Trace("qcf-qregister") << "  with additional constraints : " << std::endl;\r
-      for( unsigned j=q[0].getNumChildren(); j<d_qinfo[q].d_vars.size(); j++ ){\r
-        Trace("qcf-qregister") << "    ?x" << j << " = ";\r
-        debugPrintQuantBody( "qcf-qregister", q, d_qinfo[q].d_vars[j], false );\r
-        Trace("qcf-qregister") << std::endl;\r
-      }\r
-    }\r
-\r
-    Trace("qcf-qregister") << "Done registering quantifier." << std::endl;\r
-  }\r
-}\r
-\r
-int QuantConflictFind::evaluate( Node n, bool pref, bool hasPref ) {\r
-  int ret = 0;\r
-  if( n.getKind()==EQUAL ){\r
-    Node n1 = evaluateTerm( n[0] );\r
-    Node n2 = evaluateTerm( n[1] );\r
-    Debug("qcf-eval") << "Evaluate : Normalize " << n << " to " << n1 << " = " << n2 << std::endl;\r
-    if( areEqual( n1, n2 ) ){\r
-      ret = 1;\r
-    }else if( areDisequal( n1, n2 ) ){\r
-      ret = -1;\r
-    }\r
-    //else if( d_effort>QuantConflictFind::effort_conflict ){\r
-    //  ret = -1;\r
-    //}\r
-  }else if( MatchGen::isHandledUfTerm( n ) ){  //predicate\r
-    Node nn = evaluateTerm( n );\r
-    Debug("qcf-eval") << "Evaluate : Normalize " << nn << " to " << n << std::endl;\r
-    if( areEqual( nn, d_true ) ){\r
-      ret = 1;\r
-    }else if( areEqual( nn, d_false ) ){\r
-      ret = -1;\r
-    }\r
-    //else if( d_effort>QuantConflictFind::effort_conflict ){\r
-    //  ret = -1;\r
-    //}\r
-  }else if( n.getKind()==NOT ){\r
-    return -evaluate( n[0] );\r
-  }else if( n.getKind()==ITE ){\r
-    int cev1 = evaluate( n[0] );\r
-    int cevc[2] = { 0, 0 };\r
-    for( unsigned i=0; i<2; i++ ){\r
-      if( ( i==0 && cev1!=-1 ) || ( i==1 && cev1!=1 ) ){\r
-        cevc[i] = evaluate( n[i+1] );\r
-        if( cev1!=0 ){\r
-          ret = cevc[i];\r
-          break;\r
-        }else if( cevc[i]==0 ){\r
-          break;\r
-        }\r
-      }\r
-    }\r
-    if( ret==0 && cevc[0]!=0 && cevc[0]==cevc[1] ){\r
-      ret = cevc[0];\r
-    }\r
-  }else if( n.getKind()==IFF ){\r
-    int cev1 = evaluate( n[0] );\r
-    if( cev1!=0 ){\r
-      int cev2 = evaluate( n[1] );\r
-      if( cev2!=0 ){\r
-        ret = cev1==cev2 ? 1 : -1;\r
-      }\r
-    }\r
-\r
-  }else{\r
-    int ssval = 0;\r
-    if( n.getKind()==OR ){\r
-      ssval = 1;\r
-    }else if( n.getKind()==AND ){\r
-      ssval = -1;\r
-    }\r
-    bool isUnk = false;\r
-    for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-      int cev = evaluate( n[i] );\r
-      if( cev==ssval ){\r
-        ret = ssval;\r
-        break;\r
-      }else if( cev==0 ){\r
-        isUnk = true;\r
-      }\r
-    }\r
-    if( ret==0 && !isUnk ){\r
-      ret = -ssval;\r
-    }\r
-  }\r
-  Debug("qcf-eval") << "Evaluate " << n << " to " << ret << std::endl;\r
-  return ret;\r
-}\r
-\r
-short QuantConflictFind::getMaxQcfEffort() {\r
-  if( options::qcfMode()==QCF_CONFLICT_ONLY ){\r
-    return effort_conflict;\r
-  }else if( options::qcfMode()==QCF_PROP_EQ ){\r
-    return effort_prop_eq;\r
-  }else if( options::qcfMode()==QCF_MC ){\r
-    return effort_mc;\r
-  }else{\r
-    return 0;\r
-  }\r
-}\r
-\r
-bool QuantConflictFind::areMatchEqual( TNode n1, TNode n2 ) {\r
-  //if( d_effort==QuantConflictFind::effort_mc ){\r
-  //  return n1==n2 || !areDisequal( n1, n2 );\r
-  //}else{\r
-  return n1==n2;\r
-  //}\r
-}\r
-\r
-bool QuantConflictFind::areMatchDisequal( TNode n1, TNode n2 ) {\r
-  //if( d_effort==QuantConflictFind::effort_conflict ){\r
-  //  return areDisequal( n1, n2 );\r
-  //}else{\r
-  return n1!=n2;\r
-  //}\r
-}\r
-\r
-//-------------------------------------------------- handling assertions / eqc\r
-\r
-void QuantConflictFind::assertNode( Node q ) {\r
-  if( !TermDb::isRewriteRule( q ) ){\r
-    Trace("qcf-proc") << "QCF : assertQuantifier : ";\r
-    debugPrintQuant("qcf-proc", q);\r
-    Trace("qcf-proc") << std::endl;\r
-    d_qassert.push_back( q );\r
-    //set the eqRegistries that this depends on to true\r
-    //for( std::map< EqRegistry *, bool >::iterator it = d_qinfo[q].d_rel_eqr.begin(); it != d_qinfo[q].d_rel_eqr.end(); ++it ){\r
-    //  it->first->d_active.set( true );\r
-    //}\r
-  }\r
-}\r
-\r
-eq::EqualityEngine * QuantConflictFind::getEqualityEngine() {\r
-  //return ((uf::TheoryUF*)d_quantEngine->getTheoryEngine()->theoryOf( theory::THEORY_UF ))->getEqualityEngine();\r
-  return d_quantEngine->getTheoryEngine()->getMasterEqualityEngine();\r
-}\r
-bool QuantConflictFind::areEqual( Node n1, Node n2 ) {\r
-  return getEqualityEngine()->hasTerm( n1 ) && getEqualityEngine()->hasTerm( n2 ) && getEqualityEngine()->areEqual( n1,n2 );\r
-}\r
-bool QuantConflictFind::areDisequal( Node n1, Node n2 ) {\r
-  return n1!=n2 && getEqualityEngine()->hasTerm( n1 ) && getEqualityEngine()->hasTerm( n2 ) && getEqualityEngine()->areDisequal( n1,n2, false );\r
-}\r
-Node QuantConflictFind::getRepresentative( Node n ) {\r
-  if( getEqualityEngine()->hasTerm( n ) ){\r
-    return getEqualityEngine()->getRepresentative( n );\r
-  }else{\r
-    return n;\r
-  }\r
-}\r
-Node QuantConflictFind::evaluateTerm( Node n ) {\r
-  if( MatchGen::isHandledUfTerm( n ) ){\r
-    Node f = MatchGen::getOperator( this, n );\r
-    Node nn;\r
-    computeUfTerms( f );\r
-    if( getEqualityEngine()->hasTerm( n ) ){\r
-      computeArgReps( n );\r
-      nn = d_uf_terms[f].existsTerm( n, d_arg_reps[n] );\r
-    }else{\r
-      std::vector< TNode > args;\r
-      for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-        Node c = evaluateTerm( n[i] );\r
-        args.push_back( c );\r
-      }\r
-      nn = d_uf_terms[f].existsTerm( n, args );\r
-    }\r
-    if( !nn.isNull() ){\r
-      Debug("qcf-eval") << "GT: Term " << nn << " for " << n << " hasTerm = " << getEqualityEngine()->hasTerm( n )  << std::endl;\r
-      return getRepresentative( nn );\r
-    }else{\r
-      Debug("qcf-eval") << "GT: No term for " << n << " hasTerm = " << getEqualityEngine()->hasTerm( n )  << std::endl;\r
-      return n;\r
-    }\r
-  }else if( n.getKind()==ITE ){\r
-    int v = evaluate( n[0], false, false );\r
-    if( v==1 ){\r
-      return evaluateTerm( n[1] );\r
-    }else if( v==-1 ){\r
-      return evaluateTerm( n[2] );\r
-    }\r
-  }\r
-  return getRepresentative( n );\r
-}\r
-\r
-/*\r
-QuantConflictFind::EqcInfo * QuantConflictFind::getEqcInfo( Node n, bool doCreate ) {\r
-  std::map< Node, EqcInfo * >::iterator it2 = d_eqc_info.find( n );\r
-  if( it2==d_eqc_info.end() ){\r
-    if( doCreate ){\r
-      EqcInfo * eqci = new EqcInfo( d_c );\r
-      d_eqc_info[n] = eqci;\r
-      return eqci;\r
-    }else{\r
-      return NULL;\r
-    }\r
-  }\r
-  return it2->second;\r
-}\r
-*/\r
-\r
-QcfNodeIndex * QuantConflictFind::getQcfNodeIndex( Node eqc, Node f ) {\r
-  computeUfTerms( f );\r
-  std::map< TNode, QcfNodeIndex >::iterator itut = d_eqc_uf_terms.find( f );\r
-  if( itut==d_eqc_uf_terms.end() ){\r
-    return NULL;\r
-  }else{\r
-    if( eqc.isNull() ){\r
-      return &itut->second;\r
-    }else{\r
-      std::map< TNode, QcfNodeIndex >::iterator itute = itut->second.d_children.find( eqc );\r
-      if( itute!=itut->second.d_children.end() ){\r
-        return &itute->second;\r
-      }else{\r
-        return NULL;\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-QcfNodeIndex * QuantConflictFind::getQcfNodeIndex( Node f ) {\r
-  computeUfTerms( f );\r
-  std::map< TNode, QcfNodeIndex >::iterator itut = d_uf_terms.find( f );\r
-  if( itut!=d_uf_terms.end() ){\r
-    return &itut->second;\r
-  }else{\r
-    return NULL;\r
-  }\r
-}\r
-\r
-/** new node */\r
-void QuantConflictFind::newEqClass( Node n ) {\r
-  //Trace("qcf-proc-debug") << "QCF : newEqClass : " << n << std::endl;\r
-  //Trace("qcf-proc2-debug") << "QCF : finished newEqClass : " << n << std::endl;\r
-}\r
-\r
-/** merge */\r
-void QuantConflictFind::merge( Node a, Node b ) {\r
-  /*\r
-  if( b.getKind()==EQUAL ){\r
-    if( a==d_true ){\r
-      //will merge anyways\r
-      //merge( b[0], b[1] );\r
-    }else if( a==d_false ){\r
-      assertDisequal( b[0], b[1] );\r
-    }\r
-  }else{\r
-    Trace("qcf-proc") << "QCF : merge : " << a << " " << b << std::endl;\r
-    EqcInfo * eqc_b = getEqcInfo( b, false );\r
-    EqcInfo * eqc_a = NULL;\r
-    if( eqc_b ){\r
-      eqc_a = getEqcInfo( a );\r
-      //move disequalities of b into a\r
-      for( NodeBoolMap::iterator it = eqc_b->d_diseq.begin(); it != eqc_b->d_diseq.end(); ++it ){\r
-        if( (*it).second ){\r
-          Node n = (*it).first;\r
-          EqcInfo * eqc_n = getEqcInfo( n, false );\r
-          Assert( eqc_n );\r
-          if( !eqc_n->isDisequal( a ) ){\r
-            Assert( !eqc_a->isDisequal( n ) );\r
-            eqc_n->setDisequal( a );\r
-            eqc_a->setDisequal( n );\r
-            //setEqual( eqc_a, eqc_b, a, n, false );\r
-          }\r
-          eqc_n->setDisequal( b, false );\r
-        }\r
-      }\r
-      ////move all previous EqcRegistry's regarding equalities within b\r
-      //for( NodeBoolMap::iterator it = eqc_b->d_rel_eqr_e.begin(); it != eqc_b->d_rel_eqr_e.end(); ++it ){\r
-      //  if( (*it).second ){\r
-      //    eqc_a->d_rel_eqr_e[(*it).first] = true;\r
-      //  }\r
-      //}\r
-    }\r
-    //process new equalities\r
-    //setEqual( eqc_a, eqc_b, a, b, true );\r
-    Trace("qcf-proc2") << "QCF : finished merge : " << a << " " << b << std::endl;\r
-  }\r
-  */\r
-}\r
-\r
-/** assert disequal */\r
-void QuantConflictFind::assertDisequal( Node a, Node b ) {\r
-  /*\r
-  a = getRepresentative( a );\r
-  b = getRepresentative( b );\r
-  Trace("qcf-proc") << "QCF : assert disequal : " << a << " " << b << std::endl;\r
-  EqcInfo * eqc_a = getEqcInfo( a );\r
-  EqcInfo * eqc_b = getEqcInfo( b );\r
-  if( !eqc_a->isDisequal( b ) ){\r
-    Assert( !eqc_b->isDisequal( a ) );\r
-    eqc_b->setDisequal( a );\r
-    eqc_a->setDisequal( b );\r
-    //setEqual( eqc_a, eqc_b, a, b, false );\r
-  }\r
-  Trace("qcf-proc2") << "QCF : finished assert disequal : " << a << " " << b << std::endl;\r
-  */\r
-}\r
-\r
-//-------------------------------------------------- check function\r
-\r
-void QuantConflictFind::reset_round( Theory::Effort level ) {\r
-  d_needs_computeRelEqr = true;\r
-}\r
-\r
-/** check */\r
-void QuantConflictFind::check( Theory::Effort level ) {\r
-  Trace("qcf-check") << "QCF : check : " << level << std::endl;\r
-  if( d_conflict ){\r
-    Trace("qcf-check2") << "QCF : finished check : already in conflict." << std::endl;\r
-    if( level>=Theory::EFFORT_FULL ){\r
-      Trace("qcf-warn") << "ALREADY IN CONFLICT? " << level << std::endl;\r
-      //Assert( false );\r
-    }\r
-  }else{\r
-    int addedLemmas = 0;\r
-    if( d_performCheck ){\r
-      ++(d_statistics.d_inst_rounds);\r
-      double clSet = 0;\r
-      int prevEt = 0;\r
-      if( Trace.isOn("qcf-engine") ){\r
-        prevEt = d_statistics.d_entailment_checks.getData();\r
-        clSet = double(clock())/double(CLOCKS_PER_SEC);\r
-        Trace("qcf-engine") << "---Conflict Find Engine Round, effort = " << level << "---" << std::endl;\r
-      }\r
-      computeRelevantEqr();\r
-\r
-      //determine order for quantified formulas\r
-      std::vector< Node > qorder;\r
-      std::map< Node, bool > qassert;\r
-      //mark which are asserted\r
-      for( unsigned i=0; i<d_qassert.size(); i++ ){\r
-        qassert[d_qassert[i]] = true;\r
-      }\r
-      //add which ones are specified in the order\r
-      for( unsigned i=0; i<d_quant_order.size(); i++ ){\r
-        Node n = d_quant_order[i];\r
-        if( std::find( qorder.begin(), qorder.end(), n )==qorder.end() && qassert.find( n )!=qassert.end() ){\r
-          qorder.push_back( n );\r
-        }\r
-      }\r
-      d_quant_order.clear();\r
-      d_quant_order.insert( d_quant_order.begin(), qorder.begin(), qorder.end() );\r
-      //add remaining\r
-      for( unsigned i=0; i<d_qassert.size(); i++ ){\r
-        Node n = d_qassert[i];\r
-        if( std::find( qorder.begin(), qorder.end(), n )==qorder.end() ){\r
-          qorder.push_back( n );\r
-        }\r
-      }\r
-\r
-      if( Trace.isOn("qcf-debug") ){\r
-        Trace("qcf-debug") << std::endl;\r
-        debugPrint("qcf-debug");\r
-        Trace("qcf-debug") << std::endl;\r
-      }\r
-      short end_e = getMaxQcfEffort();\r
-      for( short e = effort_conflict; e<=end_e; e++ ){\r
-        d_effort = e;\r
-        Trace("qcf-check") << "Checking quantified formulas at effort " << e << "..." << std::endl;\r
-        for( unsigned j=0; j<qorder.size(); j++ ){\r
-          Node q = qorder[j];\r
-          QuantInfo * qi = &d_qinfo[q];\r
-\r
-          Assert( d_qinfo.find( q )!=d_qinfo.end() );\r
-          if( qi->d_mg->isValid() ){\r
-            Trace("qcf-check") << "Check quantified formula ";\r
-            debugPrintQuant("qcf-check", q);\r
-            Trace("qcf-check") << " : " << q << "..." << std::endl;\r
-\r
-            Trace("qcf-check-debug") << "Reset round..." << std::endl;\r
-            qi->reset_round( this );\r
-            //try to make a matches making the body false\r
-            Trace("qcf-check-debug") << "Get next match..." << std::endl;\r
-            while( qi->d_mg->getNextMatch( this, qi ) ){\r
-              Trace("qcf-check") << "*** Produced match at effort " << e << " : " << std::endl;\r
-              qi->debugPrintMatch("qcf-check");\r
-              Trace("qcf-check") << std::endl;\r
-              std::vector< int > assigned;\r
-              if( !qi->isMatchSpurious( this ) ){\r
-                if( qi->completeMatch( this, assigned ) ){\r
-                  /*\r
-                  if( options::qcfExp() && d_effort==effort_conflict ){\r
-                    std::vector< Node > exp;\r
-                    if( qi->d_mg->getExplanation( this, qi, exp ) ){\r
-                      Trace("qcf-check-exp") << "Base explanation is : " << std::endl;\r
-                      for( unsigned c=0; c<exp.size(); c++ ){\r
-                        Trace("qcf-check-exp") << "  " << exp[c] << std::endl;\r
-                      }\r
-                      std::vector< TNode > c_exp;\r
-                      eq::EqualityEngine* ee = ((uf::TheoryUF*)d_quantEngine->getTheoryEngine()->theoryOf( THEORY_UF ))->getEqualityEngine() ;\r
-                      for( unsigned c=0; c<exp.size(); c++ ){\r
-                        bool pol = exp[c].getKind()!=NOT;\r
-                        TNode lit = pol ? exp[c] : exp[c][0];\r
-                        Trace("qcf-check-exp") << "Explain " << lit << ", polarity " << pol << std::endl;\r
-                        if( lit.getKind()==EQUAL ){\r
-                          if( !pol && !ee->areDisequal( lit[0], lit[1], true ) ){\r
-                            exit( 98 );\r
-                          }else if( pol && !ee->areEqual( lit[0], lit[1] ) ){\r
-                            exit( 99 );\r
-                          }\r
-                          ee->explainEquality( lit[0], lit[1], pol, c_exp );\r
-                        }else{\r
-                          if( !ee->areEqual( lit, pol ? d_true : d_false ) ){\r
-                            exit( pol ? 96 : 97 );\r
-                          }\r
-                          ee->explainPredicate( lit, pol, c_exp );\r
-                        }\r
-                      }\r
-                      std::vector< Node > c_lem;\r
-                      Trace("qcf-check-exp") << "Actual explanation is : " << std::endl;\r
-                      for( unsigned c=0; c<c_exp.size(); c++ ){\r
-                        Trace("qcf-check-exp") << "  " << c_exp[c] << std::endl;\r
-                        Node ccc = c_exp[c].negate();\r
-                        if( std::find( c_lem.begin(), c_lem.end(), ccc )==c_lem.end() ){\r
-                          c_lem.push_back( ccc );\r
-                        }\r
-                      }\r
-\r
-                      c_lem.push_back( q.negate() );\r
-                      Node conf = NodeManager::currentNM()->mkNode( OR, c_lem );\r
-                      Trace("qcf-conflict") << "QCF conflict : " << conf << std::endl;\r
-                      d_quantEngine->addLemma( conf, false );\r
-                      d_conflict.set( true );\r
-                      ++(d_statistics.d_conflict_inst);\r
-                      ++addedLemmas;\r
-                      break;\r
-                    }\r
-                  }\r
-                  */\r
-                  std::vector< Node > terms;\r
-                  qi->getMatch( terms );\r
-                  if( !qi->isTConstraintSpurious( this, terms ) ){\r
-                    if( Debug.isOn("qcf-check-inst") ){\r
-                      //if( e==effort_conflict ){\r
-                      Node inst = d_quantEngine->getInstantiation( q, terms );\r
-                      Debug("qcf-check-inst") << "Check instantiation " << inst << "..." << std::endl;\r
-                      Assert( evaluate( inst )!=1 );\r
-                      Assert( evaluate( inst )==-1 || e>effort_conflict );\r
-                      //}\r
-                    }\r
-                    if( d_quantEngine->addInstantiation( q, terms, false ) ){\r
-                      Trace("qcf-check") << "   ... Added instantiation" << std::endl;\r
-                      Trace("qcf-inst") << "*** Was from effort " << e << " : " << std::endl;\r
-                      qi->debugPrintMatch("qcf-inst");\r
-                      Trace("qcf-inst") << std::endl;\r
-                      ++addedLemmas;\r
-                      if( e==effort_conflict ){\r
-                        d_quant_order.insert( d_quant_order.begin(), q );\r
-                        d_conflict.set( true );\r
-                        ++(d_statistics.d_conflict_inst);\r
-                        break;\r
-                      }else if( e==effort_prop_eq ){\r
-                        ++(d_statistics.d_prop_inst);\r
-                      }\r
-                    }else{\r
-                      Trace("qcf-check") << "   ... Failed to add instantiation" << std::endl;\r
-                      //Assert( false );\r
-                    }\r
-                  }\r
-                  //clean up assigned\r
-                  qi->revertMatch( assigned );\r
-                  d_tempCache.clear();\r
-                }else{\r
-                  Trace("qcf-check") << "   ... Spurious instantiation (cannot assign unassigned variables)" << std::endl;\r
-                }\r
-              }else{\r
-                Trace("qcf-check") << "   ... Spurious instantiation (match is inconsistent)" << std::endl;\r
-              }\r
-            }\r
-            if( d_conflict ){\r
-              break;\r
-            }\r
-          }\r
-        }\r
-        if( addedLemmas>0 ){\r
-          d_quantEngine->flushLemmas();\r
-          break;\r
-        }\r
-      }\r
-      if( Trace.isOn("qcf-engine") ){\r
-        double clSet2 = double(clock())/double(CLOCKS_PER_SEC);\r
-        Trace("qcf-engine") << "Finished conflict find engine, time = " << (clSet2-clSet);\r
-        if( addedLemmas>0 ){\r
-          Trace("qcf-engine") << ", effort = " << ( d_effort==effort_conflict ? "conflict" : ( d_effort==effort_prop_eq ? "prop_eq" : "mc" ) );\r
-          Trace("qcf-engine") << ", addedLemmas = " << addedLemmas;\r
-        }\r
-        Trace("qcf-engine") << std::endl;\r
-        int currEt = d_statistics.d_entailment_checks.getData();\r
-        if( currEt!=prevEt ){\r
-          Trace("qcf-engine") << "  Entailment checks = " << ( currEt - prevEt ) << std::endl;\r
-        }\r
-      }\r
-    }\r
-    Trace("qcf-check2") << "QCF : finished check : " << level << std::endl;\r
-  }\r
-}\r
-\r
-bool QuantConflictFind::needsCheck( Theory::Effort level ) {\r
-  d_performCheck = false;\r
-  if( options::quantConflictFind() && !d_conflict ){\r
-    if( level==Theory::EFFORT_LAST_CALL ){\r
-      d_performCheck = options::qcfWhenMode()==QCF_WHEN_MODE_LAST_CALL;\r
-    }else if( level==Theory::EFFORT_FULL ){\r
-      d_performCheck = options::qcfWhenMode()==QCF_WHEN_MODE_DEFAULT;\r
-    }else if( level==Theory::EFFORT_STANDARD ){\r
-      d_performCheck = options::qcfWhenMode()==QCF_WHEN_MODE_STD;\r
-    }\r
-  }\r
-  return d_performCheck;\r
-}\r
-\r
-void QuantConflictFind::computeRelevantEqr() {\r
-  if( d_needs_computeRelEqr ){\r
-    d_needs_computeRelEqr = false;\r
-    Trace("qcf-check") << "Compute relevant equalities..." << std::endl;\r
-    d_uf_terms.clear();\r
-    d_eqc_uf_terms.clear();\r
-    d_eqcs.clear();\r
-    d_model_basis.clear();\r
-    d_arg_reps.clear();\r
-    //double clSet = 0;\r
-    //if( Trace.isOn("qcf-opt") ){\r
-    //  clSet = double(clock())/double(CLOCKS_PER_SEC);\r
-    //}\r
-\r
-    //long nTermst = 0;\r
-    //long nTerms = 0;\r
-    //long nEqc = 0;\r
-\r
-    //which nodes are irrelevant for disequality matches\r
-    std::map< TNode, bool > irrelevant_dnode;\r
-    //now, store matches\r
-    eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( getEqualityEngine() );\r
-    while( !eqcs_i.isFinished() ){\r
-      //nEqc++;\r
-      Node r = (*eqcs_i);\r
-      TypeNode rtn = r.getType();\r
-      if( options::qcfMode()==QCF_MC ){\r
-        std::map< TypeNode, std::vector< TNode > >::iterator itt = d_eqcs.find( rtn );\r
-        if( itt==d_eqcs.end() ){\r
-          Node mb = getQuantifiersEngine()->getTermDatabase()->getModelBasisTerm( rtn );\r
-          if( !getEqualityEngine()->hasTerm( mb ) ){\r
-            Trace("qcf-warn") << "WARNING: Model basis term does not exist!" << std::endl;\r
-            Assert( false );\r
-          }\r
-          Node mbr = getRepresentative( mb );\r
-          if( mbr!=r ){\r
-            d_eqcs[rtn].push_back( mbr );\r
-          }\r
-          d_eqcs[rtn].push_back( r );\r
-          d_model_basis[rtn] = mb;\r
-        }else{\r
-          itt->second.push_back( r );\r
-        }\r
-      }else{\r
-        d_eqcs[rtn].push_back( r );\r
-      }\r
-      /*\r
-      eq::EqClassIterator eqc_i = eq::EqClassIterator( r, getEqualityEngine() );\r
-      while( !eqc_i.isFinished() ){\r
-        TNode n = (*eqc_i);\r
-        if( n.hasBoundVar() ){\r
-          std::cout << "BAD TERM IN DB : " << n << std::endl;\r
-          exit( 199 );\r
-        }\r
-        ++eqc_i;\r
-      }\r
-\r
-      */\r
-\r
-      //if( r.getType().isInteger() ){\r
-      //  Trace("qcf-mv") << "Model value for eqc(" << r << ") : " << d_quantEngine->getValuation().getModelValue( r ) << std::endl;\r
-      //}\r
-      //EqcInfo * eqcir = getEqcInfo( r, false );\r
-      //get relevant nodes that we are disequal from\r
-      /*\r
-      std::vector< Node > deqc;\r
-      if( eqcir ){\r
-        for( NodeBoolMap::iterator it = eqcir->d_diseq.begin(); it != eqcir->d_diseq.end(); ++it ){\r
-          if( (*it).second ){\r
-            //Node rd = (*it).first;\r
-            //if( rd!=getRepresentative( rd ) ){\r
-            //  std::cout << "Bad rep!" << std::endl;\r
-            //  exit( 0 );\r
-            //}\r
-            deqc.push_back( (*it).first );\r
-          }\r
-        }\r
-      }\r
-      */\r
-      //process disequalities\r
-      /*\r
-      eq::EqClassIterator eqc_i = eq::EqClassIterator( r, getEqualityEngine() );\r
-      while( !eqc_i.isFinished() ){\r
-        TNode n = (*eqc_i);\r
-        if( n.getKind()!=EQUAL ){\r
-          nTermst++;\r
-          //node_to_rep[n] = r;\r
-          //if( n.getNumChildren()>0 ){\r
-          //  if( n.getKind()!=APPLY_UF ){\r
-          //    std::cout << n.getKind() << " " << n.getOperator() << " " << n << std::endl;\r
-          //  }\r
-          //}\r
-          if( !quantifiers::TermDb::hasBoundVarAttr( n ) ){    //temporary\r
-\r
-            bool isRedundant;\r
-            std::map< TNode, std::vector< TNode > >::iterator it_na;\r
-            TNode fn;\r
-            if( MatchGen::isHandledUfTerm( n ) ){\r
-              Node f = MatchGen::getOperator( this, n );\r
-              computeArgReps( n );\r
-              it_na = d_arg_reps.find( n );\r
-              Assert( it_na!=d_arg_reps.end() );\r
-              Node nadd = d_eqc_uf_terms[f].d_children[r].addTerm( n, d_arg_reps[n] );\r
-              isRedundant = (nadd!=n);\r
-              d_uf_terms[f].addTerm( n, d_arg_reps[n] );\r
-            }else{\r
-              isRedundant = false;\r
-            }\r
-            nTerms += isRedundant ? 0 : 1;\r
-          }else{\r
-            if( Debug.isOn("qcf-nground") ){\r
-              Debug("qcf-nground") << "Non-ground term in eqc : " << n << std::endl;\r
-              Assert( false );\r
-            }\r
-          }\r
-        }\r
-        ++eqc_i;\r
-      }\r
-      */\r
-      ++eqcs_i;\r
-    }\r
-    /*\r
-    if( Trace.isOn("qcf-opt") ){\r
-      double clSet2 = double(clock())/double(CLOCKS_PER_SEC);\r
-      Trace("qcf-opt") << "Compute rel eqc : " << std::endl;\r
-      Trace("qcf-opt") << "   " << nEqc << " equivalence classes. " << std::endl;\r
-      Trace("qcf-opt") << "   " << nTerms << " / " << nTermst << " terms." << std::endl;\r
-      Trace("qcf-opt") << "   Time : " << (clSet2-clSet) << std::endl;\r
-    }\r
-    */\r
-  }\r
-}\r
-\r
-void QuantConflictFind::computeArgReps( TNode n ) {\r
-  if( d_arg_reps.find( n )==d_arg_reps.end() ){\r
-    Assert( MatchGen::isHandledUfTerm( n ) );\r
-    for( unsigned j=0; j<n.getNumChildren(); j++ ){\r
-      d_arg_reps[n].push_back( getRepresentative( n[j] ) );\r
-    }\r
-  }\r
-}\r
-\r
-void QuantConflictFind::computeUfTerms( TNode f ) {\r
-  if( d_uf_terms.find( f )==d_uf_terms.end() ){\r
-    d_uf_terms[f].clear();\r
-    unsigned nt = d_quantEngine->getTermDatabase()->getNumGroundTerms( f );\r
-    for( unsigned i=0; i<nt; i++ ){\r
-      Node n = d_quantEngine->getTermDatabase()->d_op_map[f][i];\r
-      if( getEqualityEngine()->hasTerm( n ) && !n.getAttribute(NoMatchAttribute()) ){\r
-        Node r = getRepresentative( n );\r
-        computeArgReps( n );\r
-        d_eqc_uf_terms[f].d_children[r].addTerm( n, d_arg_reps[n] );\r
-        d_uf_terms[f].addTerm( n, d_arg_reps[n] );\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-//-------------------------------------------------- debugging\r
-\r
-\r
-void QuantConflictFind::debugPrint( const char * c ) {\r
-  //print the equivalance classes\r
-  Trace(c) << "----------EQ classes" << std::endl;\r
-  eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( getEqualityEngine() );\r
-  while( !eqcs_i.isFinished() ){\r
-    Node n = (*eqcs_i);\r
-    //if( !n.getType().isInteger() ){\r
-    Trace(c) << "  - " << n << " : {";\r
-    eq::EqClassIterator eqc_i = eq::EqClassIterator( n, getEqualityEngine() );\r
-    bool pr = false;\r
-    while( !eqc_i.isFinished() ){\r
-      Node nn = (*eqc_i);\r
-      if( nn.getKind()!=EQUAL && nn!=n ){\r
-        Trace(c) << (pr ? "," : "" ) << " " << nn;\r
-        pr = true;\r
-      }\r
-      ++eqc_i;\r
-    }\r
-    Trace(c) << (pr ? " " : "" ) << "}" << std::endl;\r
-    /*\r
-    EqcInfo * eqcn = getEqcInfo( n, false );\r
-    if( eqcn ){\r
-      Trace(c) << "    DEQ : {";\r
-      pr = false;\r
-      for( NodeBoolMap::iterator it = eqcn->d_diseq.begin(); it != eqcn->d_diseq.end(); ++it ){\r
-        if( (*it).second ){\r
-          Trace(c) << (pr ? "," : "" ) << " " << (*it).first;\r
-          pr = true;\r
-        }\r
-      }\r
-      Trace(c) << (pr ? " " : "" ) << "}" << std::endl;\r
-    }\r
-    //}\r
-    */\r
-    ++eqcs_i;\r
-  }\r
-}\r
-\r
-void QuantConflictFind::debugPrintQuant( const char * c, Node q ) {\r
-  Trace(c) << "Q" << d_quant_id[q];\r
-}\r
-\r
-void QuantConflictFind::debugPrintQuantBody( const char * c, Node q, Node n, bool doVarNum ) {\r
-  if( n.getNumChildren()==0 ){\r
-    Trace(c) << n;\r
-  }else if( doVarNum && d_qinfo[q].d_var_num.find( n )!=d_qinfo[q].d_var_num.end() ){\r
-    Trace(c) << "?x" << d_qinfo[q].d_var_num[n];\r
-  }else{\r
-    Trace(c) << "(";\r
-    if( n.getKind()==APPLY_UF ){\r
-      Trace(c) << n.getOperator();\r
-    }else{\r
-      Trace(c) << n.getKind();\r
-    }\r
-    for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-      Trace(c) << " ";\r
-      debugPrintQuantBody( c, q, n[i] );\r
-    }\r
-    Trace(c) << ")";\r
-  }\r
-}\r
-\r
-QuantConflictFind::Statistics::Statistics():\r
-  d_inst_rounds("QuantConflictFind::Inst_Rounds", 0),\r
-  d_conflict_inst("QuantConflictFind::Instantiations_Conflict_Find", 0 ),\r
-  d_prop_inst("QuantConflictFind::Instantiations_Prop", 0 ),\r
-  d_entailment_checks("QuantConflictFind::Entailment_Checks",0)\r
-{\r
-  StatisticsRegistry::registerStat(&d_inst_rounds);\r
-  StatisticsRegistry::registerStat(&d_conflict_inst);\r
-  StatisticsRegistry::registerStat(&d_prop_inst);\r
-  StatisticsRegistry::registerStat(&d_entailment_checks);\r
-}\r
-\r
-QuantConflictFind::Statistics::~Statistics(){\r
-  StatisticsRegistry::unregisterStat(&d_inst_rounds);\r
-  StatisticsRegistry::unregisterStat(&d_conflict_inst);\r
-  StatisticsRegistry::unregisterStat(&d_prop_inst);\r
-  StatisticsRegistry::unregisterStat(&d_entailment_checks);\r
-}\r
-\r
-TNode QuantConflictFind::getZero( Kind k ) {\r
-  std::map< Kind, Node >::iterator it = d_zero.find( k );\r
-  if( it==d_zero.end() ){\r
-    Node nn;\r
-    if( k==PLUS ){\r
-      nn = NodeManager::currentNM()->mkConst( Rational(0) );\r
-    }\r
-    d_zero[k] = nn;\r
-    return nn;\r
-  }else{\r
-    return it->second;\r
-  }\r
-}\r
-\r
-\r
-}\r
+/*********************                                                        */
+/*! \file quant_conflict_find.cpp
+ ** \verbatim
+ ** Original author: Andrew Reynolds
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2013  New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief quant conflict find class
+ **
+ **/
+
+#include <vector>
+
+#include "theory/quantifiers/quant_conflict_find.h"
+#include "theory/quantifiers/quant_util.h"
+#include "theory/theory_engine.h"
+#include "theory/quantifiers/options.h"
+#include "theory/quantifiers/term_database.h"
+#include "theory/quantifiers/trigger.h"
+
+using namespace CVC4;
+using namespace CVC4::kind;
+using namespace CVC4::theory;
+using namespace CVC4::theory::quantifiers;
+using namespace std;
+
+namespace CVC4 {
+
+Node QcfNodeIndex::existsTerm( TNode n, std::vector< TNode >& reps, int index ) {
+  if( index==(int)reps.size() ){
+    if( d_children.empty() ){
+      return Node::null();
+    }else{
+      return d_children.begin()->first;
+    }
+  }else{
+    std::map< TNode, QcfNodeIndex >::iterator it = d_children.find( reps[index] );
+    if( it==d_children.end() ){
+      return Node::null();
+    }else{
+      return it->second.existsTerm( n, reps, index+1 );
+    }
+  }
+}
+
+Node QcfNodeIndex::addTerm( TNode n, std::vector< TNode >& reps, int index ) {
+  if( index==(int)reps.size() ){
+    if( d_children.empty() ){
+      d_children[ n ].clear();
+      return n;
+    }else{
+      return d_children.begin()->first;
+    }
+  }else{
+    return d_children[reps[index]].addTerm( n, reps, index+1 );
+  }
+}
+
+
+void QcfNodeIndex::debugPrint( const char * c, int t ) {
+  for( std::map< TNode, QcfNodeIndex >::iterator it = d_children.begin(); it != d_children.end(); ++it ){
+    if( !it->first.isNull() ){
+      for( int j=0; j<t; j++ ){ Trace(c) << "  "; }
+      Trace(c) << it->first << " : " << std::endl;
+      it->second.debugPrint( c, t+1 );
+    }
+  }
+}
+
+
+void QuantInfo::initialize( Node q, Node qn ) {
+  d_q = q;
+  for( unsigned i=0; i<q[0].getNumChildren(); i++ ){
+    d_match.push_back( TNode::null() );
+    d_match_term.push_back( TNode::null() );
+  }
+
+  //register the variables
+  for( unsigned i=0; i<q[0].getNumChildren(); i++ ){
+    d_var_num[q[0][i]] = i;
+    d_vars.push_back( q[0][i] );
+  }
+
+  registerNode( qn, true, true );
+
+
+  Trace("qcf-qregister") << "- Make match gen structure..." << std::endl;
+  d_mg = new MatchGen( this, qn );
+
+  if( d_mg->isValid() ){
+    /*
+    for( unsigned j=0; j<q[0].getNumChildren(); j++ ){
+      if( d_inMatchConstraint.find( q[0][j] )==d_inMatchConstraint.end() ){
+        Trace("qcf-invalid") << "QCF invalid : variable " << q[0][j] << " does not exist in a matching constraint." << std::endl;
+        d_mg->setInvalid();
+        break;
+      }
+    }
+    */
+    if( d_mg->isValid() ){
+      for( unsigned j=q[0].getNumChildren(); j<d_vars.size(); j++ ){
+        if( d_vars[j].getKind()!=BOUND_VARIABLE ){
+          d_var_mg[j] = NULL;
+          bool is_tsym = false;
+          if( !MatchGen::isHandledUfTerm( d_vars[j] ) && d_vars[j].getKind()!=ITE ){
+            is_tsym = true;
+            d_tsym_vars.push_back( j );
+          }
+          if( !is_tsym || options::qcfTConstraint() ){
+            d_var_mg[j] = new MatchGen( this, d_vars[j], true );
+          }
+          if( !d_var_mg[j] || !d_var_mg[j]->isValid() ){
+            Trace("qcf-invalid") << "QCF invalid : cannot match for " << d_vars[j] << std::endl;
+            d_mg->setInvalid();
+            break;
+          }else{
+            std::vector< int > bvars;
+            d_var_mg[j]->determineVariableOrder( this, bvars );
+          }
+        }
+      }
+      if( d_mg->isValid() ){
+        std::vector< int > bvars;
+        d_mg->determineVariableOrder( this, bvars );
+      }
+    }
+  }else{
+    Trace("qcf-invalid") << "QCF invalid : body of formula cannot be processed." << std::endl;
+  }
+  Trace("qcf-qregister-summary") << "QCF register : " << ( d_mg->isValid() ? "VALID " : "INVALID" ) << " : " << q << std::endl;
+}
+
+void QuantInfo::registerNode( Node n, bool hasPol, bool pol, bool beneathQuant ) {
+  Trace("qcf-qregister-debug2") << "Register : " << n << std::endl;
+  if( n.getKind()==FORALL ){
+    registerNode( n[1], hasPol, pol, true );
+  }else{
+    if( !MatchGen::isHandledBoolConnective( n ) ){
+      if( n.hasBoundVar() ){
+        //literals
+        if( n.getKind()==EQUAL ){
+          for( unsigned i=0; i<n.getNumChildren(); i++ ){
+            flatten( n[i], beneathQuant );
+          }
+        }else if( MatchGen::isHandledUfTerm( n ) ){
+          flatten( n, beneathQuant );
+        }else if( n.getKind()==ITE ){
+          for( unsigned i=1; i<=2; i++ ){
+            flatten( n[i], beneathQuant );
+          }
+          registerNode( n[0], false, pol, beneathQuant );
+        }else if( options::qcfTConstraint() ){
+          //a theory-specific predicate
+          for( unsigned i=0; i<n.getNumChildren(); i++ ){
+            flatten( n[i], beneathQuant );
+          }
+        }
+      }
+    }else{
+      for( unsigned i=0; i<n.getNumChildren(); i++ ){
+        bool newHasPol;
+        bool newPol;
+        QuantPhaseReq::getPolarity( n, i, hasPol, pol, newHasPol, newPol );
+        //QcfNode * qcfc = new QcfNode( d_c );
+        //qcfc->d_parent = qcf;
+        //qcf->d_child[i] = qcfc;
+        registerNode( n[i], newHasPol, newPol, beneathQuant );
+      }
+    }
+  }
+}
+
+void QuantInfo::flatten( Node n, bool beneathQuant ) {
+  Trace("qcf-qregister-debug2") << "Flatten : " << n << std::endl;
+  if( n.hasBoundVar() ){
+    if( n.getKind()==BOUND_VARIABLE ){
+      d_inMatchConstraint[n] = true;
+    }
+    //if( MatchGen::isHandledUfTerm( n ) || n.getKind()==ITE ){
+    if( d_var_num.find( n )==d_var_num.end() ){
+      Trace("qcf-qregister-debug2") << "Add FLATTEN VAR : " << n << std::endl;
+      d_var_num[n] = d_vars.size();
+      d_vars.push_back( n );
+      d_match.push_back( TNode::null() );
+      d_match_term.push_back( TNode::null() );
+      if( n.getKind()==ITE ){
+        registerNode( n, false, false );
+      }else{
+        for( unsigned i=0; i<n.getNumChildren(); i++ ){
+          flatten( n[i], beneathQuant );
+        }
+      }
+    }else{
+      Trace("qcf-qregister-debug2") << "...already processed" << std::endl;
+    }
+  }else{
+    Trace("qcf-qregister-debug2") << "...is ground." << std::endl;
+  }
+}
+
+
+void QuantInfo::reset_round( QuantConflictFind * p ) {
+  for( unsigned i=0; i<d_match.size(); i++ ){
+    d_match[i] = TNode::null();
+    d_match_term[i] = TNode::null();
+  }
+  d_curr_var_deq.clear();
+  d_tconstraints.clear();
+  //add built-in variable constraints
+  for( unsigned r=0; r<2; r++ ){
+    for( std::map< int, std::vector< Node > >::iterator it = d_var_constraint[r].begin();
+         it != d_var_constraint[r].end(); ++it ){
+      for( unsigned j=0; j<it->second.size(); j++ ){
+        Node rr = it->second[j];
+        if( !isVar( rr ) ){
+          rr = p->getRepresentative( rr );
+        }
+        if( addConstraint( p, it->first, rr, r==0 )==-1 ){
+          d_var_constraint[0].clear();
+          d_var_constraint[1].clear();
+          //quantified formula is actually equivalent to true
+          Trace("qcf-qregister") << "Quantifier is equivalent to true!!!" << std::endl;
+          d_mg->d_children.clear();
+          d_mg->d_n = NodeManager::currentNM()->mkConst( true );
+          d_mg->d_type = MatchGen::typ_ground;
+          return;
+        }
+      }
+    }
+  }
+  d_mg->reset_round( p );
+  for( std::map< int, MatchGen * >::iterator it = d_var_mg.begin(); it != d_var_mg.end(); ++it ){
+    it->second->reset_round( p );
+  }
+  //now, reset for matching
+  d_mg->reset( p, false, this );
+}
+
+int QuantInfo::getCurrentRepVar( int v ) {
+  if( v!=-1 && !d_match[v].isNull() ){
+    int vn = getVarNum( d_match[v] );
+    if( vn!=-1 ){
+      //int vr = getCurrentRepVar( vn );
+      //d_match[v] = d_vars[vr];
+      //return vr;
+      return getCurrentRepVar( vn );
+    }
+  }
+  return v;
+}
+
+TNode QuantInfo::getCurrentValue( TNode n ) {
+  int v = getVarNum( n );
+  if( v==-1 ){
+    return n;
+  }else{
+    if( d_match[v].isNull() ){
+      return n;
+    }else{
+      Assert( getVarNum( d_match[v] )!=v );
+      return getCurrentValue( d_match[v] );
+    }
+  }
+}
+
+TNode QuantInfo::getCurrentExpValue( TNode n ) {
+  int v = getVarNum( n );
+  if( v==-1 ){
+    return n;
+  }else{
+    if( d_match[v].isNull() ){
+      return n;
+    }else{
+      Assert( getVarNum( d_match[v] )!=v );
+      if( d_match_term[v].isNull() ){
+        return getCurrentValue( d_match[v] );
+      }else{
+        return d_match_term[v];
+      }
+    }
+  }
+}
+
+bool QuantInfo::getCurrentCanBeEqual( QuantConflictFind * p, int v, TNode n, bool chDiseq ) {
+  //check disequalities
+  std::map< int, std::map< TNode, int > >::iterator itd = d_curr_var_deq.find( v );
+  if( itd!=d_curr_var_deq.end() ){
+    for( std::map< TNode, int >::iterator it = itd->second.begin(); it != itd->second.end(); ++it ){
+      Node cv = getCurrentValue( it->first );
+      Debug("qcf-ccbe") << "compare " << cv << " " << n << std::endl;
+      if( cv==n ){
+        return false;
+      }else if( chDiseq && !isVar( n ) && !isVar( cv ) ){
+        //they must actually be disequal if we are looking for conflicts
+        if( !p->areDisequal( n, cv ) ){
+          //TODO : check for entailed disequal
+
+          return false;
+        }
+      }
+    }
+  }
+  return true;
+}
+
+int QuantInfo::addConstraint( QuantConflictFind * p, int v, TNode n, bool polarity ) {
+  v = getCurrentRepVar( v );
+  int vn = getVarNum( n );
+  vn = vn==-1 ? -1 : getCurrentRepVar( vn );
+  n = getCurrentValue( n );
+  return addConstraint( p, v, n, vn, polarity, false );
+}
+
+int QuantInfo::addConstraint( QuantConflictFind * p, int v, TNode n, int vn, bool polarity, bool doRemove ) {
+  //for handling equalities between variables, and disequalities involving variables
+  Debug("qcf-match-debug") << "- " << (doRemove ? "un" : "" ) << "constrain : " << v << " -> " << n << " (cv=" << getCurrentValue( n ) << ")";
+  Debug("qcf-match-debug") << ", (vn=" << vn << "), polarity = " << polarity << std::endl;
+  Assert( doRemove || n==getCurrentValue( n ) );
+  Assert( doRemove || v==getCurrentRepVar( v ) );
+  Assert( doRemove || vn==getCurrentRepVar( getVarNum( n ) ) );
+  if( polarity ){
+    if( vn!=v ){
+      if( doRemove ){
+        if( vn!=-1 ){
+          //if set to this in the opposite direction, clean up opposite instead
+          //          std::map< int, TNode >::iterator itmn = d_match.find( vn );
+          if( d_match[vn]==d_vars[v] ){
+            return addConstraint( p, vn, d_vars[v], v, true, true );
+          }else{
+            //unsetting variables equal
+            std::map< int, std::map< TNode, int > >::iterator itd = d_curr_var_deq.find( vn );
+            if( itd!=d_curr_var_deq.end() ){
+              //remove disequalities owned by this
+              std::vector< TNode > remDeq;
+              for( std::map< TNode, int >::iterator it = itd->second.begin(); it != itd->second.end(); ++it ){
+                if( it->second==v ){
+                  remDeq.push_back( it->first );
+                }
+              }
+              for( unsigned i=0; i<remDeq.size(); i++ ){
+                d_curr_var_deq[vn].erase( remDeq[i] );
+              }
+            }
+          }
+        }
+        d_match[v] = TNode::null();
+        return 1;
+      }else{
+        //std::map< int, TNode >::iterator itm = d_match.find( v );
+
+        if( vn!=-1 ){
+          Debug("qcf-match-debug") << "  ...Variable bound to variable" << std::endl;
+          //std::map< int, TNode >::iterator itmn = d_match.find( vn );
+          if( d_match[v].isNull() ){
+            //setting variables equal
+            bool alreadySet = false;
+            if( !d_match[vn].isNull() ){
+              alreadySet = true;
+              Assert( !isVar( d_match[vn] ) );
+            }
+
+            //copy or check disequalities
+            std::map< int, std::map< TNode, int > >::iterator itd = d_curr_var_deq.find( v );
+            if( itd!=d_curr_var_deq.end() ){
+              for( std::map< TNode, int >::iterator it = itd->second.begin(); it != itd->second.end(); ++it ){
+                Node dv = getCurrentValue( it->first );
+                if( !alreadySet ){
+                  if( d_curr_var_deq[vn].find( dv )==d_curr_var_deq[vn].end() ){
+                    d_curr_var_deq[vn][dv] = v;
+                  }
+                }else{
+                  if( !p->areMatchDisequal( d_match[vn], dv ) ){
+                    Debug("qcf-match-debug") << "  -> fail, conflicting disequality" << std::endl;
+                    return -1;
+                  }
+                }
+              }
+            }
+            if( alreadySet ){
+              n = getCurrentValue( n );
+            }
+          }else{
+            if( d_match[vn].isNull() ){
+              Debug("qcf-match-debug") << " ...Reverse direction" << std::endl;
+              //set the opposite direction
+              return addConstraint( p, vn, d_vars[v], v, true, false );
+            }else{
+              Debug("qcf-match-debug") << "  -> Both variables bound, compare" << std::endl;
+              //are they currently equal
+              return p->areMatchEqual( d_match[v], d_match[vn] ) ? 0 : -1;
+            }
+          }
+        }else{
+          Debug("qcf-match-debug") << "  ...Variable bound to ground" << std::endl;
+          if( d_match[v].isNull() ){
+          }else{
+            //compare ground values
+            Debug("qcf-match-debug") << "  -> Ground value, compare " << d_match[v] << " "<< n << std::endl;
+            return p->areMatchEqual( d_match[v], n ) ? 0 : -1;
+          }
+        }
+        if( setMatch( p, v, n ) ){
+          Debug("qcf-match-debug") << "  -> success" << std::endl;
+          return 1;
+        }else{
+          Debug("qcf-match-debug") << "  -> fail, conflicting disequality" << std::endl;
+          return -1;
+        }
+      }
+    }else{
+      Debug("qcf-match-debug") << "  -> redundant, variable identity" << std::endl;
+      return 0;
+    }
+  }else{
+    if( vn==v ){
+      Debug("qcf-match-debug") << "  -> fail, variable identity" << std::endl;
+      return -1;
+    }else{
+      if( doRemove ){
+        Assert( d_curr_var_deq[v].find( n )!=d_curr_var_deq[v].end() );
+        d_curr_var_deq[v].erase( n );
+        return 1;
+      }else{
+        if( d_curr_var_deq[v].find( n )==d_curr_var_deq[v].end() ){
+          //check if it respects equality
+          //std::map< int, TNode >::iterator itm = d_match.find( v );
+          if( !d_match[v].isNull() ){
+            TNode nv = getCurrentValue( n );
+            if( !p->areMatchDisequal( nv, d_match[v] ) ){
+              Debug("qcf-match-debug") << "  -> fail, conflicting disequality" << std::endl;
+              return -1;
+            }
+          }
+          d_curr_var_deq[v][n] = v;
+          Debug("qcf-match-debug") << "  -> success" << std::endl;
+          return 1;
+        }else{
+          Debug("qcf-match-debug") << "  -> redundant disequality" << std::endl;
+          return 0;
+        }
+      }
+    }
+  }
+}
+
+bool QuantInfo::isConstrainedVar( int v ) {
+  if( d_curr_var_deq.find( v )!=d_curr_var_deq.end() && !d_curr_var_deq[v].empty() ){
+    return true;
+  }else{
+    Node vv = getVar( v );
+    //for( std::map< int, TNode >::iterator it = d_match.begin(); it != d_match.end(); ++it ){
+    for( unsigned i=0; i<d_match.size(); i++ ){
+      if( d_match[i]==vv ){
+        return true;
+      }
+    }
+    for( std::map< int, std::map< TNode, int > >::iterator it = d_curr_var_deq.begin(); it != d_curr_var_deq.end(); ++it ){
+      for( std::map< TNode, int >::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 ){
+        if( it2->first==vv ){
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+}
+
+bool QuantInfo::setMatch( QuantConflictFind * p, int v, TNode n ) {
+  if( getCurrentCanBeEqual( p, v, n ) ){
+    Debug("qcf-match-debug") << "-- bind : " << v << " -> " << n << ", checked " <<  d_curr_var_deq[v].size() << " disequalities" << std::endl;
+    d_match[v] = n;
+    return true;
+  }else{
+    return false;
+  }
+}
+
+bool QuantInfo::isMatchSpurious( QuantConflictFind * p ) {
+  for( int i=0; i<getNumVars(); i++ ){
+    //std::map< int, TNode >::iterator it = d_match.find( i );
+    if( !d_match[i].isNull() ){
+      if( !getCurrentCanBeEqual( p, i, d_match[i], p->d_effort==QuantConflictFind::effort_conflict ) ){
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+bool QuantInfo::isTConstraintSpurious( QuantConflictFind * p, std::vector< Node >& terms ) {
+  if( !d_tconstraints.empty() ){
+    //check constraints
+    for( std::map< Node, bool >::iterator it = d_tconstraints.begin(); it != d_tconstraints.end(); ++it ){
+      //apply substitution to the tconstraint
+      Node cons = it->first.substitute( p->getQuantifiersEngine()->getTermDatabase()->d_vars[d_q].begin(),
+                                        p->getQuantifiersEngine()->getTermDatabase()->d_vars[d_q].end(),
+                                        terms.begin(), terms.end() );
+      cons = it->second ? cons : cons.negate();
+      if( !entailmentTest( p, cons, p->d_effort==QuantConflictFind::effort_conflict ) ){
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+bool QuantInfo::entailmentTest( QuantConflictFind * p, Node lit, bool chEnt ) {
+  Trace("qcf-tconstraint-debug") << "Check : " << lit << std::endl;
+  Node rew = Rewriter::rewrite( lit );
+  if( rew==p->d_false ){
+    Trace("qcf-tconstraint-debug") << "...constraint " << lit << " is disentailed (rewrites to false)." << std::endl;
+    return false;
+  }else if( rew!=p->d_true ){
+    //if checking for conflicts, we must be sure that the constraint is entailed
+    if( chEnt ){
+      //check if it is entailed
+      Trace("qcf-tconstraint-debug") << "Check entailment of " << rew << "..." << std::endl;
+      std::pair<bool, Node> et = p->getQuantifiersEngine()->getTheoryEngine()->entailmentCheck(THEORY_OF_TYPE_BASED, rew );
+      ++(p->d_statistics.d_entailment_checks);
+      Trace("qcf-tconstraint-debug") << "ET result : " << et.first << " " << et.second << std::endl;
+      if( !et.first ){
+        Trace("qcf-tconstraint-debug") << "...cannot show entailment of " << rew << "." << std::endl;
+        return false;
+      }else{
+        return true;
+      }
+    }else{
+      Trace("qcf-tconstraint-debug") << "...does not need to be entailed." << std::endl;
+      return true;
+    }
+  }else{
+    Trace("qcf-tconstraint-debug") << "...rewrites to true." << std::endl;
+    return true;
+  }
+}
+
+bool QuantInfo::completeMatch( QuantConflictFind * p, std::vector< int >& assigned, bool doContinue ) {
+  //assign values for variables that were unassigned (usually not necessary, but handles corner cases)
+  bool doFail = false;
+  bool success = true;
+  if( doContinue ){
+    doFail = true;
+    success = false;
+  }else{
+    //solve for interpreted symbol matches
+    //   this breaks the invariant that all introduced constraints are over existing terms
+    for( int i=(int)(d_tsym_vars.size()-1); i>=0; i-- ){
+      int index = d_tsym_vars[i];
+      TNode v = getCurrentValue( d_vars[index] );
+      int slv_v = -1;
+      if( v==d_vars[index] ){
+        slv_v = index;
+      }
+      Trace("qcf-tconstraint-debug") << "Solve " << d_vars[index] << " = " << v << " " << d_vars[index].getKind() << std::endl;
+      if( d_vars[index].getKind()==PLUS || d_vars[index].getKind()==MULT ){
+        Kind k = d_vars[index].getKind();
+        std::vector< TNode > children;
+        for( unsigned j=0; j<d_vars[index].getNumChildren(); j++ ){
+          int vn = getVarNum( d_vars[index][j] );
+          if( vn!=-1 ){
+            TNode vv = getCurrentValue( d_vars[index][j] );
+            if( vv==d_vars[index][j] ){
+              //we will assign this
+              if( slv_v==-1 ){
+                Trace("qcf-tconstraint-debug") << "...will solve for var #" << vn << std::endl;
+                slv_v = vn;
+                if( p->d_effort!=QuantConflictFind::effort_conflict ){
+                  break;
+                }
+              }else{
+                Node z = p->getZero( k );
+                if( !z.isNull() ){
+                  Trace("qcf-tconstraint-debug") << "...set " << d_vars[vn] << " = " << z << std::endl;
+                  assigned.push_back( vn );
+                  if( !setMatch( p, vn, z ) ){
+                    success = false;
+                    break;
+                  }
+                }
+              }
+            }else{
+              Trace("qcf-tconstraint-debug") << "...sum value " << vv << std::endl;
+              children.push_back( vv );
+            }
+          }else{
+            Trace("qcf-tconstraint-debug") << "...sum " << d_vars[index][j] << std::endl;
+            children.push_back( d_vars[index][j] );
+          }
+        }
+        if( success ){
+          if( slv_v!=-1 ){
+            Node lhs;
+            if( children.empty() ){
+              lhs = p->getZero( k );
+            }else if( children.size()==1 ){
+              lhs = children[0];
+            }else{
+              lhs = NodeManager::currentNM()->mkNode( k, children );
+            }
+            Node sum;
+            if( v==d_vars[index] ){
+              sum = lhs;
+            }else{
+              if( p->d_effort==QuantConflictFind::effort_conflict ){
+                Kind kn = k;
+                if( d_vars[index].getKind()==PLUS ){
+                  kn = MINUS;
+                }
+                if( kn!=k ){
+                  sum = NodeManager::currentNM()->mkNode( kn, v, lhs );
+                }
+              }
+            }
+            if( !sum.isNull() ){
+              assigned.push_back( slv_v );
+              Trace("qcf-tconstraint-debug") << "...set " << d_vars[slv_v] << " = " << sum << std::endl;
+              if( !setMatch( p, slv_v, sum ) ){
+                success = false;
+              }
+              p->d_tempCache.push_back( sum );
+            }
+          }else{
+            //must show that constraint is met
+            Node sum = NodeManager::currentNM()->mkNode( k, children );
+            Node eq = sum.eqNode( v );
+            if( !entailmentTest( p, eq ) ){
+              success = false;
+            }
+            p->d_tempCache.push_back( sum );
+          }
+        }
+      }
+
+      if( !success ){
+        break;
+      }
+    }
+    if( success ){
+      //check what is left to assign
+      d_unassigned.clear();
+      d_unassigned_tn.clear();
+      std::vector< int > unassigned[2];
+      std::vector< TypeNode > unassigned_tn[2];
+      for( int i=0; i<getNumVars(); i++ ){
+        if( d_match[i].isNull() ){
+          int rindex = d_var_mg.find( i )==d_var_mg.end() ? 1 : 0;
+          unassigned[rindex].push_back( i );
+          unassigned_tn[rindex].push_back( getVar( i ).getType() );
+          assigned.push_back( i );
+        }
+      }
+      d_unassigned_nvar = unassigned[0].size();
+      for( unsigned i=0; i<2; i++ ){
+        d_unassigned.insert( d_unassigned.end(), unassigned[i].begin(), unassigned[i].end() );
+        d_unassigned_tn.insert( d_unassigned_tn.end(), unassigned_tn[i].begin(), unassigned_tn[i].end() );
+      }
+      d_una_eqc_count.clear();
+      d_una_index = 0;
+    }
+  }
+
+  if( !d_unassigned.empty() && ( success || doContinue ) ){
+    Trace("qcf-check") << "Assign to unassigned..." << std::endl;
+    do {
+      if( doFail ){
+        Trace("qcf-check-unassign") << "Failure, try again..." << std::endl;
+      }
+      bool invalidMatch = false;
+      while( ( d_una_index>=0 && (int)d_una_index<(int)d_unassigned.size() ) || invalidMatch || doFail ){
+        invalidMatch = false;
+        if( !doFail && d_una_index==(int)d_una_eqc_count.size() ){
+          //check if it has now been assigned
+          if( d_una_index<d_unassigned_nvar ){
+            if( !isConstrainedVar( d_unassigned[d_una_index] ) ){
+              d_una_eqc_count.push_back( -1 );
+            }else{
+              d_var_mg[ d_unassigned[d_una_index] ]->reset( p, true, this );
+              d_una_eqc_count.push_back( 0 );
+            }
+          }else{
+            d_una_eqc_count.push_back( 0 );
+          }
+        }else{
+          bool failed = false;
+          if( !doFail ){
+            if( d_una_index<d_unassigned_nvar ){
+              if( !isConstrainedVar( d_unassigned[d_una_index] ) ){
+                Trace("qcf-check-unassign") << "Succeeded, variable unconstrained at " << d_una_index << std::endl;
+                d_una_index++;
+              }else if( d_var_mg[d_unassigned[d_una_index]]->getNextMatch( p, this ) ){
+                Trace("qcf-check-unassign") << "Succeeded match with mg at " << d_una_index << std::endl;
+                d_una_index++;
+              }else{
+                failed = true;
+                Trace("qcf-check-unassign") << "Failed match with mg at " << d_una_index << std::endl;
+              }
+            }else{
+              Assert( doFail || d_una_index==(int)d_una_eqc_count.size()-1 );
+              if( d_una_eqc_count[d_una_index]<(int)p->d_eqcs[d_unassigned_tn[d_una_index]].size() ){
+                int currIndex = d_una_eqc_count[d_una_index];
+                d_una_eqc_count[d_una_index]++;
+                Trace("qcf-check-unassign") << d_unassigned[d_una_index] << "->" << p->d_eqcs[d_unassigned_tn[d_una_index]][currIndex] << std::endl;
+                if( setMatch( p, d_unassigned[d_una_index], p->d_eqcs[d_unassigned_tn[d_una_index]][currIndex] ) ){
+                  d_match_term[d_unassigned[d_una_index]] = TNode::null();
+                  Trace("qcf-check-unassign") << "Succeeded match " << d_una_index << std::endl;
+                  d_una_index++;
+                }else{
+                  Trace("qcf-check-unassign") << "Failed match " << d_una_index << std::endl;
+                  invalidMatch = true;
+                }
+              }else{
+                failed = true;
+                Trace("qcf-check-unassign") << "No more matches " << d_una_index << std::endl;
+              }
+            }
+          }
+          if( doFail || failed ){
+            do{
+              if( !doFail ){
+                d_una_eqc_count.pop_back();
+              }else{
+                doFail = false;
+              }
+              d_una_index--;
+            }while( d_una_index>=0 && d_una_eqc_count[d_una_index]==-1 );
+          }
+        }
+      }
+      success = d_una_index>=0;
+      if( success ){
+        doFail = true;
+        Trace("qcf-check-unassign") << "  Try: " << std::endl;
+        for( unsigned i=0; i<d_unassigned.size(); i++ ){
+          int ui = d_unassigned[i];
+          if( !d_match[ui].isNull() ){
+            Trace("qcf-check-unassign") << "  Assigned #" << ui << " : " << d_vars[ui] << " -> " << d_match[ui] << std::endl;
+          }
+        }
+      }
+    }while( success && isMatchSpurious( p ) );
+  }
+  if( success ){
+    for( unsigned i=0; i<d_unassigned.size(); i++ ){
+      int ui = d_unassigned[i];
+      if( !d_match[ui].isNull() ){
+        Trace("qcf-check") << "  Assigned #" << ui << " : " << d_vars[ui] << " -> " << d_match[ui] << std::endl;
+      }
+    }
+    return true;
+  }else{
+    for( unsigned i=0; i<assigned.size(); i++ ){
+      d_match[ assigned[i] ] = TNode::null();
+    }
+    assigned.clear();
+    return false;
+  }
+}
+
+void QuantInfo::getMatch( std::vector< Node >& terms ){
+  for( unsigned i=0; i<d_q[0].getNumChildren(); i++ ){
+    //Node cv = qi->getCurrentValue( qi->d_match[i] );
+    int repVar = getCurrentRepVar( i );
+    Node cv;
+    //std::map< int, TNode >::iterator itmt = qi->d_match_term.find( repVar );
+    if( !d_match_term[repVar].isNull() ){
+      cv = d_match_term[repVar];
+    }else{
+      cv = d_match[repVar];
+    }
+    Debug("qcf-check-inst") << "INST : " << i << " -> " << cv << ", from " << d_match[i] << std::endl;
+    terms.push_back( cv );
+  }
+}
+
+void QuantInfo::revertMatch( std::vector< int >& assigned ) {
+  for( unsigned i=0; i<assigned.size(); i++ ){
+    d_match[ assigned[i] ] = TNode::null();
+  }
+}
+
+void QuantInfo::debugPrintMatch( const char * c ) {
+  for( int i=0; i<getNumVars(); i++ ){
+    Trace(c) << "  " << d_vars[i] << " -> ";
+    if( !d_match[i].isNull() ){
+      Trace(c) << d_match[i];
+    }else{
+      Trace(c) << "(unassigned) ";
+    }
+    if( !d_curr_var_deq[i].empty() ){
+      Trace(c) << ", DEQ{ ";
+      for( std::map< TNode, int >::iterator it = d_curr_var_deq[i].begin(); it != d_curr_var_deq[i].end(); ++it ){
+        Trace(c) << it->first << " ";
+      }
+      Trace(c) << "}";
+    }
+    if( !d_match_term[i].isNull() && d_match_term[i]!=d_match[i] ){
+      Trace(c) << ", EXP : " << d_match_term[i];
+    }
+    Trace(c) <<  std::endl;
+  }
+  if( !d_tconstraints.empty() ){
+    Trace(c) << "ADDITIONAL CONSTRAINTS : " << std::endl;
+    for( std::map< Node, bool >::iterator it = d_tconstraints.begin(); it != d_tconstraints.end(); ++it ){
+      Trace(c) << "   " << it->first << " -> " << it->second << std::endl;
+    }
+  }
+}
+
+MatchGen::MatchGen( QuantInfo * qi, Node n, bool isVar ){
+  Trace("qcf-qregister-debug") << "Make match gen for " << n << ", isVar = " << isVar << std::endl;
+  std::vector< Node > qni_apps;
+  d_qni_size = 0;
+  if( isVar ){
+    Assert( qi->d_var_num.find( n )!=qi->d_var_num.end() );
+    if( n.getKind()==ITE ){
+      d_type = typ_ite_var;
+      d_type_not = false;
+      d_n = n;
+      d_children.push_back( MatchGen( qi, d_n[0] ) );
+      if( d_children[0].isValid() ){
+        d_type = typ_ite_var;
+        for( unsigned i=1; i<=2; i++ ){
+          Node nn = n.eqNode( n[i] );
+          d_children.push_back( MatchGen( qi, nn ) );
+          d_children[d_children.size()-1].d_qni_bound_except.push_back( 0 );
+          if( !d_children[d_children.size()-1].isValid() ){
+            setInvalid();
+            break;
+          }
+        }
+      }else{
+        d_type = typ_invalid;
+      }
+    }else{
+      d_type = isHandledUfTerm( n ) ? typ_var : typ_tsym;
+      d_qni_var_num[0] = qi->getVarNum( n );
+      d_qni_size++;
+      d_type_not = false;
+      d_n = n;
+      //Node f = getOperator( n );
+      for( unsigned j=0; j<d_n.getNumChildren(); j++ ){
+        Node nn = d_n[j];
+        Trace("qcf-qregister-debug") << "  " << d_qni_size;
+        if( qi->isVar( nn ) ){
+          int v = qi->d_var_num[nn];
+          Trace("qcf-qregister-debug") << " is var #" << v << std::endl;
+          d_qni_var_num[d_qni_size] = v;
+          //qi->addFuncParent( v, f, j );
+        }else{
+          Trace("qcf-qregister-debug") << " is gterm " << nn << std::endl;
+          d_qni_gterm[d_qni_size] = nn;
+        }
+        d_qni_size++;
+      }
+    }
+  }else{
+    if( n.hasBoundVar() ){
+      d_type_not = false;
+      d_n = n;
+      if( d_n.getKind()==NOT ){
+        d_n = d_n[0];
+        d_type_not = !d_type_not;
+      }
+
+      if( isHandledBoolConnective( d_n ) ){
+        //non-literals
+        d_type = typ_formula;
+        for( unsigned i=0; i<d_n.getNumChildren(); i++ ){
+          if( d_n.getKind()!=FORALL || i==1 ){
+            d_children.push_back( MatchGen( qi, d_n[i], false ) );
+            if( !d_children[d_children.size()-1].isValid() ){
+              setInvalid();
+              break;
+            }
+          }
+          /*
+          else if( isTop && n.getKind()==OR && d_children[d_children.size()-1].d_type==typ_var_eq ){
+            Trace("qcf-qregister-debug") << "Remove child, make built-in constraint" << std::endl;
+            //if variable equality/disequality at top level, remove immediately
+            bool cIsNot = d_children[d_children.size()-1].d_type_not;
+            Node cn = d_children[d_children.size()-1].d_n;
+            Assert( cn.getKind()==EQUAL );
+            Assert( p->d_qinfo[q].isVar( cn[0] ) || p->d_qinfo[q].isVar( cn[1] ) );
+            //make it a built-in constraint instead
+            for( unsigned i=0; i<2; i++ ){
+              if( p->d_qinfo[q].isVar( cn[i] ) ){
+                int v = p->d_qinfo[q].getVarNum( cn[i] );
+                Node cno = cn[i==0 ? 1 : 0];
+                p->d_qinfo[q].d_var_constraint[ cIsNot ? 0 : 1 ][v].push_back( cno );
+                break;
+              }
+            }
+            d_children.pop_back();
+          }
+          */
+        }
+      }else{
+        d_type = typ_invalid;
+        //literals
+        if( isHandledUfTerm( d_n ) ){
+          Assert( qi->isVar( d_n ) );
+          d_type = typ_pred;
+        }else if( d_n.getKind()==BOUND_VARIABLE ){
+          Assert( d_n.getType().isBoolean() );
+          d_type = typ_bool_var;
+        }else if( d_n.getKind()==EQUAL || options::qcfTConstraint() ){
+          for( unsigned i=0; i<d_n.getNumChildren(); i++ ){
+            if( d_n[i].hasBoundVar() ){
+              if( !qi->isVar( d_n[i] ) ){
+                Trace("qcf-qregister-debug")  << "ERROR : not var " << d_n[i] << std::endl;
+              }
+              Assert( qi->isVar( d_n[i] ) );
+              if( d_n.getKind()!=EQUAL && qi->isVar( d_n[i] ) ){
+                d_qni_var_num[i+1] = qi->d_var_num[d_n[i]];
+              }
+            }else{
+              d_qni_gterm[i] = d_n[i];
+            }
+          }
+          d_type = d_n.getKind()==EQUAL ? typ_eq : typ_tconstraint;
+          Trace("qcf-tconstraint") << "T-Constraint : " << d_n << std::endl;
+        }
+      }
+    }else{
+      //we will just evaluate
+      d_n = n;
+      d_type = typ_ground;
+    }
+    //if( d_type!=typ_invalid ){
+      //determine an efficient children ordering
+      //if( !d_children.empty() ){
+        //for( unsigned i=0; i<d_children.size(); i++ ){
+        //  d_children_order.push_back( i );
+        //}
+        //if( !d_n.isNull() && ( d_n.getKind()==OR || d_n.getKind()==AND || d_n.getKind()==IFF ) ){
+          //sort based on the type of the constraint : ground comes first, then literals, then others
+          //MatchGenSort mgs;
+          //mgs.d_mg = this;
+          //std::sort( d_children_order.begin(), d_children_order.end(), mgs );
+        //}
+      //}
+    //}
+  }
+  Trace("qcf-qregister-debug")  << "Done make match gen " << n << ", type = ";
+  debugPrintType( "qcf-qregister-debug", d_type, true );
+  Trace("qcf-qregister-debug") << std::endl;
+  //Assert( d_children.size()==d_children_order.size() );
+
+}
+
+void MatchGen::collectBoundVar( QuantInfo * qi, Node n, std::vector< int >& cbvars ) {
+  int v = qi->getVarNum( n );
+  if( v!=-1 && std::find( cbvars.begin(), cbvars.end(), v )==cbvars.end() ){
+    cbvars.push_back( v );
+  }
+  for( unsigned i=0; i<n.getNumChildren(); i++ ){
+    collectBoundVar( qi, n[i], cbvars );
+  }
+}
+
+void MatchGen::determineVariableOrder( QuantInfo * qi, std::vector< int >& bvars ) {
+  Trace("qcf-qregister-debug") << "Determine variable order " << d_n << std::endl;
+  bool isCom = d_type==typ_formula && ( d_n.getKind()==OR || d_n.getKind()==AND || d_n.getKind()==IFF );
+  std::map< int, std::vector< int > > c_to_vars;
+  std::map< int, std::vector< int > > vars_to_c;
+  std::map< int, int > vb_count;
+  std::map< int, int > vu_count;
+  std::vector< bool > assigned;
+  Trace("qcf-qregister-debug") << "Calculate bound variables..." << std::endl;
+  for( unsigned i=0; i<d_children.size(); i++ ){
+    collectBoundVar( qi, d_children[i].d_n, c_to_vars[i] );
+    assigned.push_back( false );
+    vb_count[i] = 0;
+    vu_count[i] = 0;
+    for( unsigned j=0; j<c_to_vars[i].size(); j++ ){
+      int v = c_to_vars[i][j];
+      vars_to_c[v].push_back( i );
+      if( std::find( bvars.begin(), bvars.end(), v )==bvars.end() ){
+        vu_count[i]++;
+        if( !isCom ){
+          bvars.push_back( v );
+        }
+      }else{
+        vb_count[i]++;
+      }
+    }
+  }
+  if( isCom ){
+    //children that bind the least number of unbound variables go first
+    do {
+      int min_score = -1;
+      int min_score_index = -1;
+      for( unsigned i=0; i<d_children.size(); i++ ){
+        if( !assigned[i] ){
+          int score = vu_count[i];
+          if( min_score==-1 || score<min_score ){
+            min_score = score;
+            min_score_index = i;
+          }
+        }
+      }
+      Trace("qcf-qregister-debug") << "...assign child " << min_score_index << "/" << d_children.size() << std::endl;
+      Assert( min_score_index!=-1 );
+      //add to children order
+      d_children_order.push_back( min_score_index );
+      assigned[min_score_index] = true;
+      //if( vb_count[min_score_index]==0 ){
+      //  d_independent.push_back( min_score_index );
+      //}
+      //determine order internal to children
+      d_children[min_score_index].determineVariableOrder( qi, bvars );
+      Trace("qcf-qregister-debug")  << "...bind variables" << std::endl;
+      //now, make it a bound variable
+      for( unsigned i=0; i<c_to_vars[min_score_index].size(); i++ ){
+        int v = c_to_vars[min_score_index][i];
+        if( std::find( bvars.begin(), bvars.end(), v )==bvars.end() ){
+          for( unsigned j=0; j<vars_to_c[v].size(); j++ ){
+            int vc = vars_to_c[v][j];
+            vu_count[vc]--;
+            vb_count[vc]++;
+          }
+          bvars.push_back( v );
+        }
+      }
+      Trace("qcf-qregister-debug") << "...done assign child " << min_score_index << std::endl;
+    }while( d_children_order.size()!=d_children.size() );
+    Trace("qcf-qregister-debug") << "Done assign variable ordering for " << d_n << std::endl;
+  }else{
+    for( unsigned i=0; i<d_children.size(); i++ ){
+      d_children_order.push_back( i );
+      d_children[i].determineVariableOrder( qi, bvars );
+    }
+  }
+}
+
+
+void MatchGen::reset_round( QuantConflictFind * p ) {
+  d_wasSet = false;
+  for( unsigned i=0; i<d_children.size(); i++ ){
+    d_children[i].reset_round( p );
+  }
+  for( std::map< int, TNode >::iterator it = d_qni_gterm.begin(); it != d_qni_gterm.end(); ++it ){
+    d_qni_gterm_rep[it->first] = p->getRepresentative( it->second );
+  }
+  if( d_type==typ_ground ){
+    int e = p->evaluate( d_n );
+    if( e==1 ){
+      d_ground_eval[0] = p->d_true;
+    }else if( e==-1 ){
+      d_ground_eval[0] = p->d_false;
+    }
+  }else if( d_type==typ_eq ){
+    for( unsigned i=0; i<d_n.getNumChildren(); i++ ){
+      if( !d_n[i].hasBoundVar() ){
+        d_ground_eval[i] = p->evaluateTerm( d_n[i] );
+      }
+    }
+  }
+  d_qni_bound_cons.clear();
+  d_qni_bound_cons_var.clear();
+  d_qni_bound.clear();
+}
+
+void MatchGen::reset( QuantConflictFind * p, bool tgt, QuantInfo * qi ) {
+  d_tgt = d_type_not ? !tgt : tgt;
+  Debug("qcf-match") << "     Reset for : " << d_n << ", type : ";
+  debugPrintType( "qcf-match", d_type );
+  Debug("qcf-match") << ", tgt = " << d_tgt << ", children = " << d_children.size() << " " << d_children_order.size() << std::endl;
+  d_qn.clear();
+  d_qni.clear();
+  d_qni_bound.clear();
+  d_child_counter = -1;
+  d_tgt_orig = d_tgt;
+
+  //set up processing matches
+  if( d_type==typ_invalid ){
+    //do nothing
+  }else if( d_type==typ_ground ){
+    if( d_ground_eval[0]==( d_tgt ? p->d_true : p->d_false ) ){
+      d_child_counter = 0;
+    }
+  }else if( d_type==typ_bool_var ){
+    //get current value of the variable
+    TNode n = qi->getCurrentValue( d_n );
+    int vn = qi->getCurrentRepVar( qi->getVarNum( n ) );
+    if( vn==-1 ){
+      //evaluate the value, see if it is compatible
+      int e = p->evaluate( n );
+      if( ( e==1 && d_tgt ) || ( e==0 && !d_tgt ) ){
+        d_child_counter = 0;
+      }
+    }else{
+      //unassigned, set match to true/false
+      d_qni_bound[0] = vn;
+      qi->setMatch( p, vn, d_tgt ? p->d_true : p->d_false );
+      d_child_counter = 0;
+    }
+    if( d_child_counter==0 ){
+      d_qn.push_back( NULL );
+    }
+  }else if( d_type==typ_var ){
+    Assert( isHandledUfTerm( d_n ) );
+    Node f = getOperator( p, d_n );
+    Debug("qcf-match-debug") << "       reset: Var will match operators of " << f << std::endl;
+    QcfNodeIndex * qni = p->getQcfNodeIndex( Node::null(), f );
+    if( qni!=NULL ){
+      d_qn.push_back( qni );
+    }
+    d_matched_basis = false;
+  }else if( d_type==typ_tsym || d_type==typ_tconstraint ){
+    for( std::map< int, int >::iterator it = d_qni_var_num.begin(); it != d_qni_var_num.end(); ++it ){
+      int repVar = qi->getCurrentRepVar( it->second );
+      if( qi->d_match[repVar].isNull() ){
+        Debug("qcf-match-debug") << "Force matching on child #" << it->first << ", which is var #" << repVar << std::endl;
+        d_qni_bound[it->first] = repVar;
+      }
+    }
+    d_qn.push_back( NULL );
+  }else if( d_type==typ_pred || d_type==typ_eq ){
+    //add initial constraint
+    Node nn[2];
+    int vn[2];
+    if( d_type==typ_pred ){
+      nn[0] = qi->getCurrentValue( d_n );
+      vn[0] = qi->getCurrentRepVar( qi->getVarNum( nn[0] ) );
+      nn[1] = p->getRepresentative( d_tgt ? p->d_true : p->d_false );
+      vn[1] = -1;
+      d_tgt = true;
+    }else{
+      for( unsigned i=0; i<2; i++ ){
+        TNode nc;
+        std::map< int, TNode >::iterator it = d_qni_gterm_rep.find( i );
+        if( it!=d_qni_gterm_rep.end() ){
+          nc = it->second;
+        }else{
+          nc = d_n[i];
+        }
+        nn[i] = qi->getCurrentValue( nc );
+        vn[i] = qi->getCurrentRepVar( qi->getVarNum( nn[i] ) );
+      }
+    }
+    bool success;
+    if( vn[0]==-1 && vn[1]==-1 ){
+      //Trace("qcf-explain") << "    reset : " << d_n << " check ground values " << nn[0] << " " << nn[1] << " (tgt=" << d_tgt << ")" << std::endl;
+      Debug("qcf-match-debug") << "       reset: check ground values " << nn[0] << " " << nn[1] << " (" << d_tgt << ")" << std::endl;
+      //just compare values
+      if( d_tgt ){
+        success = p->areMatchEqual( nn[0], nn[1] );
+      }else{
+        if( p->d_effort==QuantConflictFind::effort_conflict ){
+          success = p->areDisequal( nn[0], nn[1] );
+        }else{
+          success = p->areMatchDisequal( nn[0], nn[1] );
+        }
+      }
+    }else{
+      //otherwise, add a constraint to a variable
+      if( vn[1]!=-1 && vn[0]==-1 ){
+        //swap
+        Node t = nn[1];
+        nn[1] = nn[0];
+        nn[0] = t;
+        vn[0] = vn[1];
+        vn[1] = -1;
+      }
+      Debug("qcf-match-debug") << "       reset: add constraint " << vn[0] << " -> " << nn[1] << " (vn=" << vn[1] << ")" << std::endl;
+      //add some constraint
+      int addc = qi->addConstraint( p, vn[0], nn[1], vn[1], d_tgt, false );
+      success = addc!=-1;
+      //if successful and non-redundant, store that we need to cleanup this
+      if( addc==1 ){
+        //Trace("qcf-explain") << "       reset: " << d_n << " add constraint " << vn[0] << " -> " << nn[1] << " (vn=" << vn[1] << ")" << ", d_tgt = " << d_tgt << std::endl;
+        for( unsigned i=0; i<2; i++ ){
+          if( vn[i]!=-1 && std::find( d_qni_bound_except.begin(), d_qni_bound_except.end(), i )==d_qni_bound_except.end() ){
+            d_qni_bound[vn[i]] = vn[i];
+          }
+        }
+        d_qni_bound_cons[vn[0]] = nn[1];
+        d_qni_bound_cons_var[vn[0]] = vn[1];
+      }
+    }
+    //if successful, we will bind values to variables
+    if( success ){
+      d_qn.push_back( NULL );
+    }
+  }else{
+    if( d_children.empty() ){
+      //add dummy
+      d_qn.push_back( NULL );
+    }else{
+      if( d_tgt && d_n.getKind()==FORALL ){
+        //do nothing
+      }else{
+        //reset the first child to d_tgt
+        d_child_counter = 0;
+        getChild( d_child_counter )->reset( p, d_tgt, qi );
+      }
+    }
+  }
+  d_binding = false;
+  d_wasSet = true;
+  Debug("qcf-match") << "     reset: Finished reset for " << d_n << ", success = " << ( !d_qn.empty() || d_child_counter!=-1 ) << std::endl;
+}
+
+bool MatchGen::getNextMatch( QuantConflictFind * p, QuantInfo * qi ) {
+  Debug("qcf-match") << "     Get next match for : " << d_n << ", type = ";
+  debugPrintType( "qcf-match", d_type );
+  Debug("qcf-match") << ", children = " << d_children.size() << ", binding = " << d_binding << std::endl;
+  if( d_type==typ_invalid || d_type==typ_ground ){
+    if( d_child_counter==0 ){
+      d_child_counter = -1;
+      return true;
+    }else{
+      d_wasSet = false;
+      return false;
+    }
+  }else if( d_type==typ_var || d_type==typ_eq || d_type==typ_pred || d_type==typ_bool_var || d_type==typ_tconstraint || d_type==typ_tsym ){
+    bool success = false;
+    bool terminate = false;
+    do {
+      bool doReset = false;
+      bool doFail = false;
+      if( !d_binding ){
+        if( doMatching( p, qi ) ){
+          Debug("qcf-match-debug") << "     - Matching succeeded" << std::endl;
+          d_binding = true;
+          d_binding_it = d_qni_bound.begin();
+          doReset = true;
+          //for tconstraint, add constraint
+          if( d_type==typ_tconstraint ){
+            std::map< Node, bool >::iterator it = qi->d_tconstraints.find( d_n );
+            if( it==qi->d_tconstraints.end() ){
+              qi->d_tconstraints[d_n] = d_tgt;
+              //store that we added this constraint
+              d_qni_bound_cons[0] = d_n;
+            }else if( d_tgt!=it->second ){
+              success = false;
+              terminate = true;
+            }
+          }
+        }else{
+          Debug("qcf-match-debug") << "     - Matching failed" << std::endl;
+          success = false;
+          terminate = true;
+        }
+      }else{
+        doFail = true;
+      }
+      if( d_binding ){
+        //also need to create match for each variable we bound
+        success = true;
+        Debug("qcf-match-debug") << "     Produce matches for bound variables by " << d_n << ", type = ";
+        debugPrintType( "qcf-match-debug", d_type );
+        Debug("qcf-match-debug") << "..." << std::endl;
+
+        while( ( success && d_binding_it!=d_qni_bound.end() ) || doFail ){
+          std::map< int, MatchGen * >::iterator itm;
+          if( !doFail ){
+            Debug("qcf-match-debug") << "       check variable " << d_binding_it->second << std::endl;
+            itm = qi->d_var_mg.find( d_binding_it->second );
+          }
+          if( doFail || ( d_binding_it->first!=0 && itm!=qi->d_var_mg.end() ) ){
+            Debug("qcf-match-debug") << "       we had bound variable " << d_binding_it->second << ", reset = " << doReset << std::endl;
+            if( doReset ){
+              itm->second->reset( p, true, qi );
+            }
+            if( doFail || !itm->second->getNextMatch( p, qi ) ){
+              do {
+                if( d_binding_it==d_qni_bound.begin() ){
+                  Debug("qcf-match-debug") << "       failed." << std::endl;
+                  success = false;
+                }else{
+                  --d_binding_it;
+                  Debug("qcf-match-debug") << "       decrement..." << std::endl;
+                }
+              }while( success && ( d_binding_it->first==0 || qi->d_var_mg.find( d_binding_it->second )==qi->d_var_mg.end() ) );
+              doReset = false;
+              doFail = false;
+            }else{
+              Debug("qcf-match-debug") << "       increment..." << std::endl;
+              ++d_binding_it;
+              doReset = true;
+            }
+          }else{
+            Debug("qcf-match-debug") << "       skip..." << d_binding_it->second << std::endl;
+            ++d_binding_it;
+            doReset = true;
+          }
+        }
+        if( !success ){
+          d_binding = false;
+        }else{
+          terminate = true;
+          if( d_binding_it==d_qni_bound.begin() ){
+            d_binding = false;
+          }
+        }
+      }
+    }while( !terminate );
+    //if not successful, clean up the variables you bound
+    if( !success ){
+      if( d_type==typ_eq || d_type==typ_pred ){
+        //clean up the constraints you added
+        for( std::map< int, TNode >::iterator it = d_qni_bound_cons.begin(); it != d_qni_bound_cons.end(); ++it ){
+          if( !it->second.isNull() ){
+            Debug("qcf-match") << "       Clean up bound var " << it->first << (d_tgt ? "!" : "") << " = " << it->second << std::endl;
+            std::map< int, int >::iterator itb = d_qni_bound_cons_var.find( it->first );
+            int vn = itb!=d_qni_bound_cons_var.end() ? itb->second : -1;
+            //Trace("qcf-explain") << "       cleanup: " << d_n << " remove constraint " << it->first << " -> " << it->second << " (vn=" << vn << ")" << ", d_tgt = " << d_tgt << std::endl;
+            qi->addConstraint( p, it->first, it->second, vn, d_tgt, true );
+          }
+        }
+        d_qni_bound_cons.clear();
+        d_qni_bound_cons_var.clear();
+        d_qni_bound.clear();
+      }else{
+        //clean up the matches you set
+        for( std::map< int, int >::iterator it = d_qni_bound.begin(); it != d_qni_bound.end(); ++it ){
+          Debug("qcf-match") << "       Clean up bound var " << it->second << std::endl;
+          Assert( it->second<qi->getNumVars() );
+          qi->d_match[ it->second ] = TNode::null();
+          qi->d_match_term[ it->second ] = TNode::null();
+        }
+        d_qni_bound.clear();
+      }
+      if( d_type==typ_tconstraint ){
+        //remove constraint if applicable
+        if( d_qni_bound_cons.find( 0 )!=d_qni_bound_cons.end() ){
+          qi->d_tconstraints.erase( d_n );
+          d_qni_bound_cons.clear();
+        }
+      }
+      /*
+      if( d_type==typ_var && p->d_effort==QuantConflictFind::effort_mc && !d_matched_basis ){
+        d_matched_basis = true;
+        Node f = getOperator( d_n );
+        TNode mbo = p->getQuantifiersEngine()->getTermDatabase()->getModelBasisOpTerm( f );
+        if( qi->setMatch( p, d_qni_var_num[0], mbo ) ){
+          success = true;
+          d_qni_bound[0] = d_qni_var_num[0];
+        }
+      }
+      */
+    }
+    Debug("qcf-match") << "    ...finished matching for " << d_n << ", success = " << success << std::endl;
+    d_wasSet = success;
+    return success;
+  }else if( d_type==typ_formula || d_type==typ_ite_var ){
+    bool success = false;
+    if( d_child_counter<0 ){
+      if( d_child_counter<-1 ){
+        success = true;
+        d_child_counter = -1;
+      }
+    }else{
+      while( !success && d_child_counter>=0 ){
+        //transition system based on d_child_counter
+        if( d_n.getKind()==OR || d_n.getKind()==AND ){
+          if( (d_n.getKind()==AND)==d_tgt ){
+            //all children must match simultaneously
+            if( getChild( d_child_counter )->getNextMatch( p, qi ) ){
+              if( d_child_counter<(int)(getNumChildren()-1) ){
+                d_child_counter++;
+                Debug("qcf-match-debug") << "       Reset child " << d_child_counter << " of " << d_n << std::endl;
+                getChild( d_child_counter )->reset( p, d_tgt, qi );
+              }else{
+                success = true;
+              }
+            }else{
+              //if( std::find( d_independent.begin(), d_independent.end(), d_child_counter )!=d_independent.end() ){
+              //  d_child_counter--;
+              //}else{
+              d_child_counter--;
+              //}
+            }
+          }else{
+            //one child must match
+            if( !getChild( d_child_counter )->getNextMatch( p, qi ) ){
+              if( d_child_counter<(int)(getNumChildren()-1) ){
+                d_child_counter++;
+                Debug("qcf-match-debug") << "       Reset child " << d_child_counter << " of " << d_n << ", one match" << std::endl;
+                getChild( d_child_counter )->reset( p, d_tgt, qi );
+              }else{
+                d_child_counter = -1;
+              }
+            }else{
+              success = true;
+            }
+          }
+        }else if( d_n.getKind()==IFF ){
+          //construct match based on both children
+          if( d_child_counter%2==0 ){
+            if( getChild( 0 )->getNextMatch( p, qi ) ){
+              d_child_counter++;
+              getChild( 1 )->reset( p, d_child_counter==1, qi );
+            }else{
+              if( d_child_counter==0 ){
+                d_child_counter = 2;
+                getChild( 0 )->reset( p, !d_tgt, qi );
+              }else{
+                d_child_counter = -1;
+              }
+            }
+          }
+          if( d_child_counter>=0 && d_child_counter%2==1 ){
+            if( getChild( 1 )->getNextMatch( p, qi ) ){
+              success = true;
+            }else{
+              d_child_counter--;
+            }
+          }
+        }else if( d_n.getKind()==ITE ){
+          if( d_child_counter%2==0 ){
+            int index1 = d_child_counter==4 ? 1 : 0;
+            if( getChild( index1 )->getNextMatch( p, qi ) ){
+              d_child_counter++;
+              getChild( d_child_counter==5 ? 2 : (d_tgt==(d_child_counter==1) ? 1 : 2) )->reset( p, d_tgt, qi );
+            }else{
+              if( d_child_counter==4 || ( d_type==typ_ite_var && d_child_counter==2 ) ){
+                d_child_counter = -1;
+              }else{
+                d_child_counter +=2;
+                getChild( d_child_counter==2 ? 0 : 1 )->reset( p, d_child_counter==2 ? !d_tgt : d_tgt, qi );
+              }
+            }
+          }
+          if( d_child_counter>=0 && d_child_counter%2==1 ){
+            int index2 = d_child_counter==5 ? 2 : (d_tgt==(d_child_counter==1) ? 1 : 2);
+            if( getChild( index2 )->getNextMatch( p, qi ) ){
+              success = true;
+            }else{
+              d_child_counter--;
+            }
+          }
+        }else if( d_n.getKind()==FORALL ){
+          if( getChild( d_child_counter )->getNextMatch( p, qi ) ){
+            success = true;
+          }else{
+            d_child_counter = -1;
+          }
+        }
+      }
+        d_wasSet = success;
+      Debug("qcf-match") << "    ...finished construct match for " << d_n << ", success = " << success << std::endl;
+      return success;
+    }
+  }
+  Debug("qcf-match") << "    ...already finished for " << d_n << std::endl;
+  return false;
+}
+
+bool MatchGen::getExplanation( QuantConflictFind * p, QuantInfo * qi, std::vector< Node >& exp ) {
+  if( d_type==typ_eq ){
+    Node n[2];
+    for( unsigned i=0; i<2; i++ ){
+      Trace("qcf-explain") << "Explain term " << d_n[i] << "..." << std::endl;
+      n[i] = getExplanationTerm( p, qi, d_n[i], exp );
+    }
+    Node eq = n[0].eqNode( n[1] );
+    if( !d_tgt_orig ){
+      eq = eq.negate();
+    }
+    exp.push_back( eq );
+    Trace("qcf-explain") << "Explanation for " << d_n << " (tgt=" << d_tgt_orig << ") is " << eq << ", set = " << d_wasSet << std::endl;
+    return true;
+  }else if( d_type==typ_pred ){
+    Trace("qcf-explain") << "Explain term " << d_n << "..." << std::endl;
+    Node n = getExplanationTerm( p, qi, d_n, exp );
+    if( !d_tgt_orig ){
+      n = n.negate();
+    }
+    exp.push_back( n );
+    Trace("qcf-explain") << "Explanation for " << d_n << " (tgt=" << d_tgt_orig << ") is " << n << ", set = " << d_wasSet << std::endl;
+    return true;
+  }else if( d_type==typ_formula ){
+    Trace("qcf-explain") << "Explanation get for " << d_n << ", counter = " << d_child_counter << ", tgt = " << d_tgt_orig << ", set = " << d_wasSet << std::endl;
+    if( d_n.getKind()==OR || d_n.getKind()==AND ){
+      if( (d_n.getKind()==AND)==d_tgt ){
+        for( unsigned i=0; i<getNumChildren(); i++ ){
+          if( !getChild( i )->getExplanation( p, qi, exp ) ){
+            return false;
+          }
+        }
+      }else{
+        return getChild( d_child_counter )->getExplanation( p, qi, exp );
+      }
+    }else if( d_n.getKind()==IFF ){
+      for( unsigned i=0; i<2; i++ ){
+        if( !getChild( i )->getExplanation( p, qi, exp ) ){
+          return false;
+        }
+      }
+    }else if( d_n.getKind()==ITE ){
+      for( unsigned i=0; i<3; i++ ){
+        bool isActive = ( ( i==0 && d_child_counter!=5 ) ||
+                          ( i==1 && d_child_counter!=( d_tgt ? 3 : 1 ) ) ||
+                          ( i==2 && d_child_counter!=( d_tgt ? 1 : 3 ) ) );
+        if( isActive ){
+          if( !getChild( i )->getExplanation( p, qi, exp ) ){
+            return false;
+          }
+        }
+      }
+    }else{
+      return false;
+    }
+    return true;
+  }else{
+    return false;
+  }
+}
+
+Node MatchGen::getExplanationTerm( QuantConflictFind * p, QuantInfo * qi, Node t, std::vector< Node >& exp ) {
+  Node v = qi->getCurrentExpValue( t );
+  if( isHandledUfTerm( t ) ){
+    for( unsigned i=0; i<t.getNumChildren(); i++ ){
+      Node vi = getExplanationTerm( p, qi, t[i], exp );
+      if( vi!=v[i] ){
+        Node eq = vi.eqNode( v[i] );
+        if( std::find( exp.begin(), exp.end(), eq )==exp.end() ){
+          Trace("qcf-explain") << "  add : " << eq << "." << std::endl;
+          exp.push_back( eq );
+        }
+      }
+    }
+  }
+  return v;
+}
+
+bool MatchGen::doMatching( QuantConflictFind * p, QuantInfo * qi ) {
+  if( !d_qn.empty() ){
+    if( d_qn[0]==NULL ){
+      d_qn.clear();
+      return true;
+    }else{
+      Assert( d_type==typ_var );
+      Assert( d_qni_size>0 );
+      bool invalidMatch;
+      do {
+        invalidMatch = false;
+        Debug("qcf-match-debug") << "       Do matching " << d_n << " " << d_qn.size() << " " << d_qni.size() << std::endl;
+        if( d_qn.size()==d_qni.size()+1 ) {
+          int index = (int)d_qni.size();
+          //initialize
+          TNode val;
+          std::map< int, int >::iterator itv = d_qni_var_num.find( index );
+          if( itv!=d_qni_var_num.end() ){
+            //get the representative variable this variable is equal to
+            int repVar = qi->getCurrentRepVar( itv->second );
+            Debug("qcf-match-debug") << "       Match " << index << " is a variable " << itv->second << ", which is repVar " << repVar << std::endl;
+            //get the value the rep variable
+            //std::map< int, TNode >::iterator itm = qi->d_match.find( repVar );
+            if( !qi->d_match[repVar].isNull() ){
+              val = qi->d_match[repVar];
+              Debug("qcf-match-debug") << "       Variable is already bound to " << val << std::endl;
+            }else{
+              //binding a variable
+              d_qni_bound[index] = repVar;
+              std::map< TNode, QcfNodeIndex >::iterator it = d_qn[index]->d_children.begin();
+              if( it != d_qn[index]->d_children.end() ) {
+                d_qni.push_back( it );
+                //set the match
+                if( qi->setMatch( p, d_qni_bound[index], it->first ) ){
+                  Debug("qcf-match-debug") << "       Binding variable" << std::endl;
+                  if( d_qn.size()<d_qni_size ){
+                    d_qn.push_back( &it->second );
+                  }
+                }else{
+                  Debug("qcf-match") << "       Binding variable, currently fail." << std::endl;
+                  invalidMatch = true;
+                }
+              }else{
+                Debug("qcf-match-debug") << "       Binding variable, fail, no more variables to bind" << std::endl;
+                d_qn.pop_back();
+              }
+            }
+          }else{
+            Debug("qcf-match-debug") << "       Match " << index << " is ground term" << std::endl;
+            Assert( d_qni_gterm.find( index )!=d_qni_gterm.end() );
+            Assert( d_qni_gterm_rep.find( index )!=d_qni_gterm_rep.end() );
+            val = d_qni_gterm_rep[index];
+            Assert( !val.isNull() );
+          }
+          if( !val.isNull() ){
+            //constrained by val
+            std::map< TNode, QcfNodeIndex >::iterator it = d_qn[index]->d_children.find( val );
+            if( it!=d_qn[index]->d_children.end() ){
+              Debug("qcf-match-debug") << "       Match" << std::endl;
+              d_qni.push_back( it );
+              if( d_qn.size()<d_qni_size ){
+                d_qn.push_back( &it->second );
+              }
+            }else{
+              Debug("qcf-match-debug") << "       Failed to match" << std::endl;
+              d_qn.pop_back();
+            }
+          }
+        }else{
+          Assert( d_qn.size()==d_qni.size() );
+          int index = d_qni.size()-1;
+          //increment if binding this variable
+          bool success = false;
+          std::map< int, int >::iterator itb = d_qni_bound.find( index );
+          if( itb!=d_qni_bound.end() ){
+            d_qni[index]++;
+            if( d_qni[index]!=d_qn[index]->d_children.end() ){
+              success = true;
+              if( qi->setMatch( p, itb->second, d_qni[index]->first ) ){
+                Debug("qcf-match-debug") << "       Bind next variable" << std::endl;
+                if( d_qn.size()<d_qni_size ){
+                  d_qn.push_back( &d_qni[index]->second );
+                }
+              }else{
+                Debug("qcf-match-debug") << "       Bind next variable, currently fail" << std::endl;
+                invalidMatch = true;
+              }
+            }else{
+              qi->d_match[ itb->second ] = TNode::null();
+              qi->d_match_term[ itb->second ] = TNode::null();
+              Debug("qcf-match-debug") << "       Bind next variable, no more variables to bind" << std::endl;
+            }
+          }else{
+            //TODO : if it equal to something else, also try that
+          }
+          //if not incrementing, move to next
+          if( !success ){
+            d_qn.pop_back();
+            d_qni.pop_back();
+          }
+        }
+      }while( ( !d_qn.empty() && d_qni.size()!=d_qni_size ) || invalidMatch );
+      if( d_qni.size()==d_qni_size ){
+        //Assert( !d_qni[d_qni.size()-1]->second.d_children.empty() );
+        //Debug("qcf-match-debug") << "       We matched " << d_qni[d_qni.size()-1]->second.d_children.begin()->first << std::endl;
+        Assert( !d_qni[d_qni.size()-1]->second.d_children.empty() );
+        TNode t = d_qni[d_qni.size()-1]->second.d_children.begin()->first;
+        Debug("qcf-match-debug") << "       " << d_n << " matched " << t << std::endl;
+        qi->d_match_term[d_qni_var_num[0]] = t;
+        //set the match terms
+        for( std::map< int, int >::iterator it = d_qni_bound.begin(); it != d_qni_bound.end(); ++it ){
+          Debug("qcf-match-debug") << "       position " << it->first << " bounded " << it->second << " / " << qi->d_q[0].getNumChildren() << std::endl;
+          //if( it->second<(int)qi->d_q[0].getNumChildren() ){   //if it is an actual variable, we are interested in knowing the actual term
+          if( it->first>0 ){
+            Assert( !qi->d_match[ it->second ].isNull() );
+            Assert( p->areEqual( t[it->first-1], qi->d_match[ it->second ] ) );
+            qi->d_match_term[it->second] = t[it->first-1];
+          }
+          //}
+        }
+      }
+    }
+  }
+  return !d_qn.empty();
+}
+
+void MatchGen::debugPrintType( const char * c, short typ, bool isTrace ) {
+  if( isTrace ){
+    switch( typ ){
+    case typ_invalid: Trace(c) << "invalid";break;
+    case typ_ground: Trace(c) << "ground";break;
+    case typ_eq: Trace(c) << "eq";break;
+    case typ_pred: Trace(c) << "pred";break;
+    case typ_formula: Trace(c) << "formula";break;
+    case typ_var: Trace(c) << "var";break;
+    case typ_ite_var: Trace(c) << "ite_var";break;
+    case typ_bool_var: Trace(c) << "bool_var";break;
+    }
+  }else{
+    switch( typ ){
+    case typ_invalid: Debug(c) << "invalid";break;
+    case typ_ground: Debug(c) << "ground";break;
+    case typ_eq: Debug(c) << "eq";break;
+    case typ_pred: Debug(c) << "pred";break;
+    case typ_formula: Debug(c) << "formula";break;
+    case typ_var: Debug(c) << "var";break;
+    case typ_ite_var: Debug(c) << "ite_var";break;
+    case typ_bool_var: Debug(c) << "bool_var";break;
+    }
+  }
+}
+
+void MatchGen::setInvalid() {
+  d_type = typ_invalid;
+  d_children.clear();
+}
+
+bool MatchGen::isHandledBoolConnective( TNode n ) {
+  return n.getType().isBoolean() && ( n.getKind()==OR || n.getKind()==AND || n.getKind()==IFF || n.getKind()==ITE || n.getKind()==FORALL || n.getKind()==NOT );
+}
+
+bool MatchGen::isHandledUfTerm( TNode n ) {
+  //return n.getKind()==APPLY_UF || n.getKind()==STORE || n.getKind()==SELECT ||
+  //       n.getKind()==APPLY_CONSTRUCTOR || n.getKind()==APPLY_SELECTOR_TOTAL || n.getKind()==APPLY_TESTER;
+  return inst::Trigger::isAtomicTriggerKind( n.getKind() );  
+}
+
+Node MatchGen::getOperator( QuantConflictFind * p, Node n ) {
+  if( isHandledUfTerm( n ) ){
+    return p->getQuantifiersEngine()->getTermDatabase()->getOperator( n );
+  }else{
+    return Node::null();
+  }
+}
+
+bool MatchGen::isHandled( TNode n ) {
+  if( n.getKind()!=BOUND_VARIABLE && n.hasBoundVar() ){
+    if( !isHandledBoolConnective( n ) && !isHandledUfTerm( n ) && n.getKind()!=EQUAL && n.getKind()!=ITE ){
+      return false;
+    }
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){
+      if( !isHandled( n[i] ) ){
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+
+QuantConflictFind::QuantConflictFind( QuantifiersEngine * qe, context::Context* c ) :
+QuantifiersModule( qe ),
+d_c( c ),
+d_conflict( c, false ),
+d_qassert( c ) {
+  d_fid_count = 0;
+  d_true = NodeManager::currentNM()->mkConst<bool>(true);
+  d_false = NodeManager::currentNM()->mkConst<bool>(false);
+}
+
+Node QuantConflictFind::mkEqNode( Node a, Node b ) {
+  if( a.getType().isBoolean() ){
+    return a.iffNode( b );
+  }else{
+    return a.eqNode( b );
+  }
+}
+
+//-------------------------------------------------- registration
+
+void QuantConflictFind::registerQuantifier( Node q ) {
+  if( !TermDb::isRewriteRule( q ) ){
+    d_quants.push_back( q );
+    d_quant_id[q] = d_quants.size();
+    Trace("qcf-qregister") << "Register ";
+    debugPrintQuant( "qcf-qregister", q );
+    Trace("qcf-qregister") << " : " << q << std::endl;
+    //make QcfNode structure
+    Trace("qcf-qregister") << "- Get relevant equality/disequality pairs, calculate flattening..." << std::endl;
+    d_qinfo[q].initialize( q, q[1] );
+
+    //debug print
+    Trace("qcf-qregister") << "- Flattened structure is :" << std::endl;
+    Trace("qcf-qregister") << "    ";
+    debugPrintQuantBody( "qcf-qregister", q, q[1] );
+    Trace("qcf-qregister") << std::endl;
+    if( d_qinfo[q].d_vars.size()>q[0].getNumChildren() ){
+      Trace("qcf-qregister") << "  with additional constraints : " << std::endl;
+      for( unsigned j=q[0].getNumChildren(); j<d_qinfo[q].d_vars.size(); j++ ){
+        Trace("qcf-qregister") << "    ?x" << j << " = ";
+        debugPrintQuantBody( "qcf-qregister", q, d_qinfo[q].d_vars[j], false );
+        Trace("qcf-qregister") << std::endl;
+      }
+    }
+
+    Trace("qcf-qregister") << "Done registering quantifier." << std::endl;
+  }
+}
+
+int QuantConflictFind::evaluate( Node n, bool pref, bool hasPref ) {
+  int ret = 0;
+  if( n.getKind()==EQUAL ){
+    Node n1 = evaluateTerm( n[0] );
+    Node n2 = evaluateTerm( n[1] );
+    Debug("qcf-eval") << "Evaluate : Normalize " << n << " to " << n1 << " = " << n2 << std::endl;
+    if( areEqual( n1, n2 ) ){
+      ret = 1;
+    }else if( areDisequal( n1, n2 ) ){
+      ret = -1;
+    }
+    //else if( d_effort>QuantConflictFind::effort_conflict ){
+    //  ret = -1;
+    //}
+  }else if( MatchGen::isHandledUfTerm( n ) ){  //predicate
+    Node nn = evaluateTerm( n );
+    Debug("qcf-eval") << "Evaluate : Normalize " << nn << " to " << n << std::endl;
+    if( areEqual( nn, d_true ) ){
+      ret = 1;
+    }else if( areEqual( nn, d_false ) ){
+      ret = -1;
+    }
+    //else if( d_effort>QuantConflictFind::effort_conflict ){
+    //  ret = -1;
+    //}
+  }else if( n.getKind()==NOT ){
+    return -evaluate( n[0] );
+  }else if( n.getKind()==ITE ){
+    int cev1 = evaluate( n[0] );
+    int cevc[2] = { 0, 0 };
+    for( unsigned i=0; i<2; i++ ){
+      if( ( i==0 && cev1!=-1 ) || ( i==1 && cev1!=1 ) ){
+        cevc[i] = evaluate( n[i+1] );
+        if( cev1!=0 ){
+          ret = cevc[i];
+          break;
+        }else if( cevc[i]==0 ){
+          break;
+        }
+      }
+    }
+    if( ret==0 && cevc[0]!=0 && cevc[0]==cevc[1] ){
+      ret = cevc[0];
+    }
+  }else if( n.getKind()==IFF ){
+    int cev1 = evaluate( n[0] );
+    if( cev1!=0 ){
+      int cev2 = evaluate( n[1] );
+      if( cev2!=0 ){
+        ret = cev1==cev2 ? 1 : -1;
+      }
+    }
+
+  }else{
+    int ssval = 0;
+    if( n.getKind()==OR ){
+      ssval = 1;
+    }else if( n.getKind()==AND ){
+      ssval = -1;
+    }
+    bool isUnk = false;
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){
+      int cev = evaluate( n[i] );
+      if( cev==ssval ){
+        ret = ssval;
+        break;
+      }else if( cev==0 ){
+        isUnk = true;
+      }
+    }
+    if( ret==0 && !isUnk ){
+      ret = -ssval;
+    }
+  }
+  Debug("qcf-eval") << "Evaluate " << n << " to " << ret << std::endl;
+  return ret;
+}
+
+short QuantConflictFind::getMaxQcfEffort() {
+  if( options::qcfMode()==QCF_CONFLICT_ONLY ){
+    return effort_conflict;
+  }else if( options::qcfMode()==QCF_PROP_EQ ){
+    return effort_prop_eq;
+  }else if( options::qcfMode()==QCF_MC ){
+    return effort_mc;
+  }else{
+    return 0;
+  }
+}
+
+bool QuantConflictFind::areMatchEqual( TNode n1, TNode n2 ) {
+  //if( d_effort==QuantConflictFind::effort_mc ){
+  //  return n1==n2 || !areDisequal( n1, n2 );
+  //}else{
+  return n1==n2;
+  //}
+}
+
+bool QuantConflictFind::areMatchDisequal( TNode n1, TNode n2 ) {
+  //if( d_effort==QuantConflictFind::effort_conflict ){
+  //  return areDisequal( n1, n2 );
+  //}else{
+  return n1!=n2;
+  //}
+}
+
+//-------------------------------------------------- handling assertions / eqc
+
+void QuantConflictFind::assertNode( Node q ) {
+  if( !TermDb::isRewriteRule( q ) ){
+    Trace("qcf-proc") << "QCF : assertQuantifier : ";
+    debugPrintQuant("qcf-proc", q);
+    Trace("qcf-proc") << std::endl;
+    d_qassert.push_back( q );
+    //set the eqRegistries that this depends on to true
+    //for( std::map< EqRegistry *, bool >::iterator it = d_qinfo[q].d_rel_eqr.begin(); it != d_qinfo[q].d_rel_eqr.end(); ++it ){
+    //  it->first->d_active.set( true );
+    //}
+  }
+}
+
+eq::EqualityEngine * QuantConflictFind::getEqualityEngine() {
+  //return ((uf::TheoryUF*)d_quantEngine->getTheoryEngine()->theoryOf( theory::THEORY_UF ))->getEqualityEngine();
+  return d_quantEngine->getTheoryEngine()->getMasterEqualityEngine();
+}
+bool QuantConflictFind::areEqual( Node n1, Node n2 ) {
+  return getEqualityEngine()->hasTerm( n1 ) && getEqualityEngine()->hasTerm( n2 ) && getEqualityEngine()->areEqual( n1,n2 );
+}
+bool QuantConflictFind::areDisequal( Node n1, Node n2 ) {
+  return n1!=n2 && getEqualityEngine()->hasTerm( n1 ) && getEqualityEngine()->hasTerm( n2 ) && getEqualityEngine()->areDisequal( n1,n2, false );
+}
+Node QuantConflictFind::getRepresentative( Node n ) {
+  if( getEqualityEngine()->hasTerm( n ) ){
+    return getEqualityEngine()->getRepresentative( n );
+  }else{
+    return n;
+  }
+}
+Node QuantConflictFind::evaluateTerm( Node n ) {
+  if( MatchGen::isHandledUfTerm( n ) ){
+    Node f = MatchGen::getOperator( this, n );
+    Node nn;
+    computeUfTerms( f );
+    if( getEqualityEngine()->hasTerm( n ) ){
+      computeArgReps( n );
+      nn = d_uf_terms[f].existsTerm( n, d_arg_reps[n] );
+    }else{
+      std::vector< TNode > args;
+      for( unsigned i=0; i<n.getNumChildren(); i++ ){
+        Node c = evaluateTerm( n[i] );
+        args.push_back( c );
+      }
+      nn = d_uf_terms[f].existsTerm( n, args );
+    }
+    if( !nn.isNull() ){
+      Debug("qcf-eval") << "GT: Term " << nn << " for " << n << " hasTerm = " << getEqualityEngine()->hasTerm( n )  << std::endl;
+      return getRepresentative( nn );
+    }else{
+      Debug("qcf-eval") << "GT: No term for " << n << " hasTerm = " << getEqualityEngine()->hasTerm( n )  << std::endl;
+      return n;
+    }
+  }else if( n.getKind()==ITE ){
+    int v = evaluate( n[0], false, false );
+    if( v==1 ){
+      return evaluateTerm( n[1] );
+    }else if( v==-1 ){
+      return evaluateTerm( n[2] );
+    }
+  }
+  return getRepresentative( n );
+}
+
+/*
+QuantConflictFind::EqcInfo * QuantConflictFind::getEqcInfo( Node n, bool doCreate ) {
+  std::map< Node, EqcInfo * >::iterator it2 = d_eqc_info.find( n );
+  if( it2==d_eqc_info.end() ){
+    if( doCreate ){
+      EqcInfo * eqci = new EqcInfo( d_c );
+      d_eqc_info[n] = eqci;
+      return eqci;
+    }else{
+      return NULL;
+    }
+  }
+  return it2->second;
+}
+*/
+
+QcfNodeIndex * QuantConflictFind::getQcfNodeIndex( Node eqc, Node f ) {
+  computeUfTerms( f );
+  std::map< TNode, QcfNodeIndex >::iterator itut = d_eqc_uf_terms.find( f );
+  if( itut==d_eqc_uf_terms.end() ){
+    return NULL;
+  }else{
+    if( eqc.isNull() ){
+      return &itut->second;
+    }else{
+      std::map< TNode, QcfNodeIndex >::iterator itute = itut->second.d_children.find( eqc );
+      if( itute!=itut->second.d_children.end() ){
+        return &itute->second;
+      }else{
+        return NULL;
+      }
+    }
+  }
+}
+
+QcfNodeIndex * QuantConflictFind::getQcfNodeIndex( Node f ) {
+  computeUfTerms( f );
+  std::map< TNode, QcfNodeIndex >::iterator itut = d_uf_terms.find( f );
+  if( itut!=d_uf_terms.end() ){
+    return &itut->second;
+  }else{
+    return NULL;
+  }
+}
+
+/** new node */
+void QuantConflictFind::newEqClass( Node n ) {
+  //Trace("qcf-proc-debug") << "QCF : newEqClass : " << n << std::endl;
+  //Trace("qcf-proc2-debug") << "QCF : finished newEqClass : " << n << std::endl;
+}
+
+/** merge */
+void QuantConflictFind::merge( Node a, Node b ) {
+  /*
+  if( b.getKind()==EQUAL ){
+    if( a==d_true ){
+      //will merge anyways
+      //merge( b[0], b[1] );
+    }else if( a==d_false ){
+      assertDisequal( b[0], b[1] );
+    }
+  }else{
+    Trace("qcf-proc") << "QCF : merge : " << a << " " << b << std::endl;
+    EqcInfo * eqc_b = getEqcInfo( b, false );
+    EqcInfo * eqc_a = NULL;
+    if( eqc_b ){
+      eqc_a = getEqcInfo( a );
+      //move disequalities of b into a
+      for( NodeBoolMap::iterator it = eqc_b->d_diseq.begin(); it != eqc_b->d_diseq.end(); ++it ){
+        if( (*it).second ){
+          Node n = (*it).first;
+          EqcInfo * eqc_n = getEqcInfo( n, false );
+          Assert( eqc_n );
+          if( !eqc_n->isDisequal( a ) ){
+            Assert( !eqc_a->isDisequal( n ) );
+            eqc_n->setDisequal( a );
+            eqc_a->setDisequal( n );
+            //setEqual( eqc_a, eqc_b, a, n, false );
+          }
+          eqc_n->setDisequal( b, false );
+        }
+      }
+      ////move all previous EqcRegistry's regarding equalities within b
+      //for( NodeBoolMap::iterator it = eqc_b->d_rel_eqr_e.begin(); it != eqc_b->d_rel_eqr_e.end(); ++it ){
+      //  if( (*it).second ){
+      //    eqc_a->d_rel_eqr_e[(*it).first] = true;
+      //  }
+      //}
+    }
+    //process new equalities
+    //setEqual( eqc_a, eqc_b, a, b, true );
+    Trace("qcf-proc2") << "QCF : finished merge : " << a << " " << b << std::endl;
+  }
+  */
+}
+
+/** assert disequal */
+void QuantConflictFind::assertDisequal( Node a, Node b ) {
+  /*
+  a = getRepresentative( a );
+  b = getRepresentative( b );
+  Trace("qcf-proc") << "QCF : assert disequal : " << a << " " << b << std::endl;
+  EqcInfo * eqc_a = getEqcInfo( a );
+  EqcInfo * eqc_b = getEqcInfo( b );
+  if( !eqc_a->isDisequal( b ) ){
+    Assert( !eqc_b->isDisequal( a ) );
+    eqc_b->setDisequal( a );
+    eqc_a->setDisequal( b );
+    //setEqual( eqc_a, eqc_b, a, b, false );
+  }
+  Trace("qcf-proc2") << "QCF : finished assert disequal : " << a << " " << b << std::endl;
+  */
+}
+
+//-------------------------------------------------- check function
+
+void QuantConflictFind::reset_round( Theory::Effort level ) {
+  d_needs_computeRelEqr = true;
+}
+
+/** check */
+void QuantConflictFind::check( Theory::Effort level ) {
+  Trace("qcf-check") << "QCF : check : " << level << std::endl;
+  if( d_conflict ){
+    Trace("qcf-check2") << "QCF : finished check : already in conflict." << std::endl;
+    if( level>=Theory::EFFORT_FULL ){
+      Trace("qcf-warn") << "ALREADY IN CONFLICT? " << level << std::endl;
+      //Assert( false );
+    }
+  }else{
+    int addedLemmas = 0;
+    if( d_performCheck ){
+      ++(d_statistics.d_inst_rounds);
+      double clSet = 0;
+      int prevEt = 0;
+      if( Trace.isOn("qcf-engine") ){
+        prevEt = d_statistics.d_entailment_checks.getData();
+        clSet = double(clock())/double(CLOCKS_PER_SEC);
+        Trace("qcf-engine") << "---Conflict Find Engine Round, effort = " << level << "---" << std::endl;
+      }
+      computeRelevantEqr();
+
+      //determine order for quantified formulas
+      std::vector< Node > qorder;
+      std::map< Node, bool > qassert;
+      //mark which are asserted
+      for( unsigned i=0; i<d_qassert.size(); i++ ){
+        qassert[d_qassert[i]] = true;
+      }
+      //add which ones are specified in the order
+      for( unsigned i=0; i<d_quant_order.size(); i++ ){
+        Node n = d_quant_order[i];
+        if( std::find( qorder.begin(), qorder.end(), n )==qorder.end() && qassert.find( n )!=qassert.end() ){
+          qorder.push_back( n );
+        }
+      }
+      d_quant_order.clear();
+      d_quant_order.insert( d_quant_order.begin(), qorder.begin(), qorder.end() );
+      //add remaining
+      for( unsigned i=0; i<d_qassert.size(); i++ ){
+        Node n = d_qassert[i];
+        if( std::find( qorder.begin(), qorder.end(), n )==qorder.end() ){
+          qorder.push_back( n );
+        }
+      }
+
+      if( Trace.isOn("qcf-debug") ){
+        Trace("qcf-debug") << std::endl;
+        debugPrint("qcf-debug");
+        Trace("qcf-debug") << std::endl;
+      }
+      short end_e = getMaxQcfEffort();
+      for( short e = effort_conflict; e<=end_e; e++ ){
+        d_effort = e;
+        Trace("qcf-check") << "Checking quantified formulas at effort " << e << "..." << std::endl;
+        for( unsigned j=0; j<qorder.size(); j++ ){
+          Node q = qorder[j];
+          QuantInfo * qi = &d_qinfo[q];
+
+          Assert( d_qinfo.find( q )!=d_qinfo.end() );
+          if( qi->d_mg->isValid() ){
+            Trace("qcf-check") << "Check quantified formula ";
+            debugPrintQuant("qcf-check", q);
+            Trace("qcf-check") << " : " << q << "..." << std::endl;
+
+            Trace("qcf-check-debug") << "Reset round..." << std::endl;
+            qi->reset_round( this );
+            //try to make a matches making the body false
+            Trace("qcf-check-debug") << "Get next match..." << std::endl;
+            while( qi->d_mg->getNextMatch( this, qi ) ){
+              Trace("qcf-check") << "*** Produced match at effort " << e << " : " << std::endl;
+              qi->debugPrintMatch("qcf-check");
+              Trace("qcf-check") << std::endl;
+              std::vector< int > assigned;
+              if( !qi->isMatchSpurious( this ) ){
+                if( qi->completeMatch( this, assigned ) ){
+                  /*
+                  if( options::qcfExp() && d_effort==effort_conflict ){
+                    std::vector< Node > exp;
+                    if( qi->d_mg->getExplanation( this, qi, exp ) ){
+                      Trace("qcf-check-exp") << "Base explanation is : " << std::endl;
+                      for( unsigned c=0; c<exp.size(); c++ ){
+                        Trace("qcf-check-exp") << "  " << exp[c] << std::endl;
+                      }
+                      std::vector< TNode > c_exp;
+                      eq::EqualityEngine* ee = ((uf::TheoryUF*)d_quantEngine->getTheoryEngine()->theoryOf( THEORY_UF ))->getEqualityEngine() ;
+                      for( unsigned c=0; c<exp.size(); c++ ){
+                        bool pol = exp[c].getKind()!=NOT;
+                        TNode lit = pol ? exp[c] : exp[c][0];
+                        Trace("qcf-check-exp") << "Explain " << lit << ", polarity " << pol << std::endl;
+                        if( lit.getKind()==EQUAL ){
+                          if( !pol && !ee->areDisequal( lit[0], lit[1], true ) ){
+                            exit( 98 );
+                          }else if( pol && !ee->areEqual( lit[0], lit[1] ) ){
+                            exit( 99 );
+                          }
+                          ee->explainEquality( lit[0], lit[1], pol, c_exp );
+                        }else{
+                          if( !ee->areEqual( lit, pol ? d_true : d_false ) ){
+                            exit( pol ? 96 : 97 );
+                          }
+                          ee->explainPredicate( lit, pol, c_exp );
+                        }
+                      }
+                      std::vector< Node > c_lem;
+                      Trace("qcf-check-exp") << "Actual explanation is : " << std::endl;
+                      for( unsigned c=0; c<c_exp.size(); c++ ){
+                        Trace("qcf-check-exp") << "  " << c_exp[c] << std::endl;
+                        Node ccc = c_exp[c].negate();
+                        if( std::find( c_lem.begin(), c_lem.end(), ccc )==c_lem.end() ){
+                          c_lem.push_back( ccc );
+                        }
+                      }
+
+                      c_lem.push_back( q.negate() );
+                      Node conf = NodeManager::currentNM()->mkNode( OR, c_lem );
+                      Trace("qcf-conflict") << "QCF conflict : " << conf << std::endl;
+                      d_quantEngine->addLemma( conf, false );
+                      d_conflict.set( true );
+                      ++(d_statistics.d_conflict_inst);
+                      ++addedLemmas;
+                      break;
+                    }
+                  }
+                  */
+                  std::vector< Node > terms;
+                  qi->getMatch( terms );
+                  if( !qi->isTConstraintSpurious( this, terms ) ){
+                    if( Debug.isOn("qcf-check-inst") ){
+                      //if( e==effort_conflict ){
+                      Node inst = d_quantEngine->getInstantiation( q, terms );
+                      Debug("qcf-check-inst") << "Check instantiation " << inst << "..." << std::endl;
+                      Assert( evaluate( inst )!=1 );
+                      Assert( evaluate( inst )==-1 || e>effort_conflict );
+                      //}
+                    }
+                    if( d_quantEngine->addInstantiation( q, terms, false ) ){
+                      Trace("qcf-check") << "   ... Added instantiation" << std::endl;
+                      Trace("qcf-inst") << "*** Was from effort " << e << " : " << std::endl;
+                      qi->debugPrintMatch("qcf-inst");
+                      Trace("qcf-inst") << std::endl;
+                      ++addedLemmas;
+                      if( e==effort_conflict ){
+                        d_quant_order.insert( d_quant_order.begin(), q );
+                        d_conflict.set( true );
+                        ++(d_statistics.d_conflict_inst);
+                        break;
+                      }else if( e==effort_prop_eq ){
+                        ++(d_statistics.d_prop_inst);
+                      }
+                    }else{
+                      Trace("qcf-check") << "   ... Failed to add instantiation" << std::endl;
+                      //Assert( false );
+                    }
+                  }
+                  //clean up assigned
+                  qi->revertMatch( assigned );
+                  d_tempCache.clear();
+                }else{
+                  Trace("qcf-check") << "   ... Spurious instantiation (cannot assign unassigned variables)" << std::endl;
+                }
+              }else{
+                Trace("qcf-check") << "   ... Spurious instantiation (match is inconsistent)" << std::endl;
+              }
+            }
+            if( d_conflict ){
+              break;
+            }
+          }
+        }
+        if( addedLemmas>0 ){
+          d_quantEngine->flushLemmas();
+          break;
+        }
+      }
+      if( Trace.isOn("qcf-engine") ){
+        double clSet2 = double(clock())/double(CLOCKS_PER_SEC);
+        Trace("qcf-engine") << "Finished conflict find engine, time = " << (clSet2-clSet);
+        if( addedLemmas>0 ){
+          Trace("qcf-engine") << ", effort = " << ( d_effort==effort_conflict ? "conflict" : ( d_effort==effort_prop_eq ? "prop_eq" : "mc" ) );
+          Trace("qcf-engine") << ", addedLemmas = " << addedLemmas;
+        }
+        Trace("qcf-engine") << std::endl;
+        int currEt = d_statistics.d_entailment_checks.getData();
+        if( currEt!=prevEt ){
+          Trace("qcf-engine") << "  Entailment checks = " << ( currEt - prevEt ) << std::endl;
+        }
+      }
+    }
+    Trace("qcf-check2") << "QCF : finished check : " << level << std::endl;
+  }
+}
+
+bool QuantConflictFind::needsCheck( Theory::Effort level ) {
+  d_performCheck = false;
+  if( options::quantConflictFind() && !d_conflict ){
+    if( level==Theory::EFFORT_LAST_CALL ){
+      d_performCheck = options::qcfWhenMode()==QCF_WHEN_MODE_LAST_CALL;
+    }else if( level==Theory::EFFORT_FULL ){
+      d_performCheck = options::qcfWhenMode()==QCF_WHEN_MODE_DEFAULT;
+    }else if( level==Theory::EFFORT_STANDARD ){
+      d_performCheck = options::qcfWhenMode()==QCF_WHEN_MODE_STD;
+    }
+  }
+  return d_performCheck;
+}
+
+void QuantConflictFind::computeRelevantEqr() {
+  if( d_needs_computeRelEqr ){
+    d_needs_computeRelEqr = false;
+    Trace("qcf-check") << "Compute relevant equalities..." << std::endl;
+    d_uf_terms.clear();
+    d_eqc_uf_terms.clear();
+    d_eqcs.clear();
+    d_model_basis.clear();
+    d_arg_reps.clear();
+    //double clSet = 0;
+    //if( Trace.isOn("qcf-opt") ){
+    //  clSet = double(clock())/double(CLOCKS_PER_SEC);
+    //}
+
+    //long nTermst = 0;
+    //long nTerms = 0;
+    //long nEqc = 0;
+
+    //which nodes are irrelevant for disequality matches
+    std::map< TNode, bool > irrelevant_dnode;
+    //now, store matches
+    eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( getEqualityEngine() );
+    while( !eqcs_i.isFinished() ){
+      //nEqc++;
+      Node r = (*eqcs_i);
+      TypeNode rtn = r.getType();
+      if( options::qcfMode()==QCF_MC ){
+        std::map< TypeNode, std::vector< TNode > >::iterator itt = d_eqcs.find( rtn );
+        if( itt==d_eqcs.end() ){
+          Node mb = getQuantifiersEngine()->getTermDatabase()->getModelBasisTerm( rtn );
+          if( !getEqualityEngine()->hasTerm( mb ) ){
+            Trace("qcf-warn") << "WARNING: Model basis term does not exist!" << std::endl;
+            Assert( false );
+          }
+          Node mbr = getRepresentative( mb );
+          if( mbr!=r ){
+            d_eqcs[rtn].push_back( mbr );
+          }
+          d_eqcs[rtn].push_back( r );
+          d_model_basis[rtn] = mb;
+        }else{
+          itt->second.push_back( r );
+        }
+      }else{
+        d_eqcs[rtn].push_back( r );
+      }
+      /*
+      eq::EqClassIterator eqc_i = eq::EqClassIterator( r, getEqualityEngine() );
+      while( !eqc_i.isFinished() ){
+        TNode n = (*eqc_i);
+        if( n.hasBoundVar() ){
+          std::cout << "BAD TERM IN DB : " << n << std::endl;
+          exit( 199 );
+        }
+        ++eqc_i;
+      }
+
+      */
+
+      //if( r.getType().isInteger() ){
+      //  Trace("qcf-mv") << "Model value for eqc(" << r << ") : " << d_quantEngine->getValuation().getModelValue( r ) << std::endl;
+      //}
+      //EqcInfo * eqcir = getEqcInfo( r, false );
+      //get relevant nodes that we are disequal from
+      /*
+      std::vector< Node > deqc;
+      if( eqcir ){
+        for( NodeBoolMap::iterator it = eqcir->d_diseq.begin(); it != eqcir->d_diseq.end(); ++it ){
+          if( (*it).second ){
+            //Node rd = (*it).first;
+            //if( rd!=getRepresentative( rd ) ){
+            //  std::cout << "Bad rep!" << std::endl;
+            //  exit( 0 );
+            //}
+            deqc.push_back( (*it).first );
+          }
+        }
+      }
+      */
+      //process disequalities
+      /*
+      eq::EqClassIterator eqc_i = eq::EqClassIterator( r, getEqualityEngine() );
+      while( !eqc_i.isFinished() ){
+        TNode n = (*eqc_i);
+        if( n.getKind()!=EQUAL ){
+          nTermst++;
+          //node_to_rep[n] = r;
+          //if( n.getNumChildren()>0 ){
+          //  if( n.getKind()!=APPLY_UF ){
+          //    std::cout << n.getKind() << " " << n.getOperator() << " " << n << std::endl;
+          //  }
+          //}
+          if( !quantifiers::TermDb::hasBoundVarAttr( n ) ){    //temporary
+
+            bool isRedundant;
+            std::map< TNode, std::vector< TNode > >::iterator it_na;
+            TNode fn;
+            if( MatchGen::isHandledUfTerm( n ) ){
+              Node f = MatchGen::getOperator( this, n );
+              computeArgReps( n );
+              it_na = d_arg_reps.find( n );
+              Assert( it_na!=d_arg_reps.end() );
+              Node nadd = d_eqc_uf_terms[f].d_children[r].addTerm( n, d_arg_reps[n] );
+              isRedundant = (nadd!=n);
+              d_uf_terms[f].addTerm( n, d_arg_reps[n] );
+            }else{
+              isRedundant = false;
+            }
+            nTerms += isRedundant ? 0 : 1;
+          }else{
+            if( Debug.isOn("qcf-nground") ){
+              Debug("qcf-nground") << "Non-ground term in eqc : " << n << std::endl;
+              Assert( false );
+            }
+          }
+        }
+        ++eqc_i;
+      }
+      */
+      ++eqcs_i;
+    }
+    /*
+    if( Trace.isOn("qcf-opt") ){
+      double clSet2 = double(clock())/double(CLOCKS_PER_SEC);
+      Trace("qcf-opt") << "Compute rel eqc : " << std::endl;
+      Trace("qcf-opt") << "   " << nEqc << " equivalence classes. " << std::endl;
+      Trace("qcf-opt") << "   " << nTerms << " / " << nTermst << " terms." << std::endl;
+      Trace("qcf-opt") << "   Time : " << (clSet2-clSet) << std::endl;
+    }
+    */
+  }
+}
+
+void QuantConflictFind::computeArgReps( TNode n ) {
+  if( d_arg_reps.find( n )==d_arg_reps.end() ){
+    Assert( MatchGen::isHandledUfTerm( n ) );
+    for( unsigned j=0; j<n.getNumChildren(); j++ ){
+      d_arg_reps[n].push_back( getRepresentative( n[j] ) );
+    }
+  }
+}
+
+void QuantConflictFind::computeUfTerms( TNode f ) {
+  if( d_uf_terms.find( f )==d_uf_terms.end() ){
+    d_uf_terms[f].clear();
+    unsigned nt = d_quantEngine->getTermDatabase()->getNumGroundTerms( f );
+    for( unsigned i=0; i<nt; i++ ){
+      Node n = d_quantEngine->getTermDatabase()->d_op_map[f][i];
+      if( getEqualityEngine()->hasTerm( n ) && !n.getAttribute(NoMatchAttribute()) ){
+        Node r = getRepresentative( n );
+        computeArgReps( n );
+        d_eqc_uf_terms[f].d_children[r].addTerm( n, d_arg_reps[n] );
+        d_uf_terms[f].addTerm( n, d_arg_reps[n] );
+      }
+    }
+  }
+}
+
+//-------------------------------------------------- debugging
+
+
+void QuantConflictFind::debugPrint( const char * c ) {
+  //print the equivalance classes
+  Trace(c) << "----------EQ classes" << std::endl;
+  eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( getEqualityEngine() );
+  while( !eqcs_i.isFinished() ){
+    Node n = (*eqcs_i);
+    //if( !n.getType().isInteger() ){
+    Trace(c) << "  - " << n << " : {";
+    eq::EqClassIterator eqc_i = eq::EqClassIterator( n, getEqualityEngine() );
+    bool pr = false;
+    while( !eqc_i.isFinished() ){
+      Node nn = (*eqc_i);
+      if( nn.getKind()!=EQUAL && nn!=n ){
+        Trace(c) << (pr ? "," : "" ) << " " << nn;
+        pr = true;
+      }
+      ++eqc_i;
+    }
+    Trace(c) << (pr ? " " : "" ) << "}" << std::endl;
+    /*
+    EqcInfo * eqcn = getEqcInfo( n, false );
+    if( eqcn ){
+      Trace(c) << "    DEQ : {";
+      pr = false;
+      for( NodeBoolMap::iterator it = eqcn->d_diseq.begin(); it != eqcn->d_diseq.end(); ++it ){
+        if( (*it).second ){
+          Trace(c) << (pr ? "," : "" ) << " " << (*it).first;
+          pr = true;
+        }
+      }
+      Trace(c) << (pr ? " " : "" ) << "}" << std::endl;
+    }
+    //}
+    */
+    ++eqcs_i;
+  }
+}
+
+void QuantConflictFind::debugPrintQuant( const char * c, Node q ) {
+  Trace(c) << "Q" << d_quant_id[q];
+}
+
+void QuantConflictFind::debugPrintQuantBody( const char * c, Node q, Node n, bool doVarNum ) {
+  if( n.getNumChildren()==0 ){
+    Trace(c) << n;
+  }else if( doVarNum && d_qinfo[q].d_var_num.find( n )!=d_qinfo[q].d_var_num.end() ){
+    Trace(c) << "?x" << d_qinfo[q].d_var_num[n];
+  }else{
+    Trace(c) << "(";
+    if( n.getKind()==APPLY_UF ){
+      Trace(c) << n.getOperator();
+    }else{
+      Trace(c) << n.getKind();
+    }
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){
+      Trace(c) << " ";
+      debugPrintQuantBody( c, q, n[i] );
+    }
+    Trace(c) << ")";
+  }
+}
+
+QuantConflictFind::Statistics::Statistics():
+  d_inst_rounds("QuantConflictFind::Inst_Rounds", 0),
+  d_conflict_inst("QuantConflictFind::Instantiations_Conflict_Find", 0 ),
+  d_prop_inst("QuantConflictFind::Instantiations_Prop", 0 ),
+  d_entailment_checks("QuantConflictFind::Entailment_Checks",0)
+{
+  StatisticsRegistry::registerStat(&d_inst_rounds);
+  StatisticsRegistry::registerStat(&d_conflict_inst);
+  StatisticsRegistry::registerStat(&d_prop_inst);
+  StatisticsRegistry::registerStat(&d_entailment_checks);
+}
+
+QuantConflictFind::Statistics::~Statistics(){
+  StatisticsRegistry::unregisterStat(&d_inst_rounds);
+  StatisticsRegistry::unregisterStat(&d_conflict_inst);
+  StatisticsRegistry::unregisterStat(&d_prop_inst);
+  StatisticsRegistry::unregisterStat(&d_entailment_checks);
+}
+
+TNode QuantConflictFind::getZero( Kind k ) {
+  std::map< Kind, Node >::iterator it = d_zero.find( k );
+  if( it==d_zero.end() ){
+    Node nn;
+    if( k==PLUS ){
+      nn = NodeManager::currentNM()->mkConst( Rational(0) );
+    }
+    d_zero[k] = nn;
+    return nn;
+  }else{
+    return it->second;
+  }
+}
+
+
+}
index 64ece7ed0fcc45bdaf9873cd01f29d7ea04a0d5f..6ea7849c4bbf1372c6a6c2e46ef1e9142b72fb1d 100755 (executable)
-/*********************                                                        */\r
-/*! \file quant_conflict_find.h\r
- ** \verbatim\r
- ** Original author: Andrew Reynolds\r
- ** Major contributors: none\r
- ** Minor contributors (to current version): none\r
- ** This file is part of the CVC4 project.\r
- ** Copyright (c) 2009-2013  New York University and The University of Iowa\r
- ** See the file COPYING in the top-level source directory for licensing\r
- ** information.\endverbatim\r
- **\r
- ** \brief quantifiers conflict find class\r
- **/\r
-\r
-#include "cvc4_private.h"\r
-\r
-#ifndef QUANT_CONFLICT_FIND\r
-#define QUANT_CONFLICT_FIND\r
-\r
-#include "context/cdhashmap.h"\r
-#include "context/cdchunk_list.h"\r
-#include "theory/quantifiers_engine.h"\r
-\r
-namespace CVC4 {\r
-namespace theory {\r
-namespace quantifiers {\r
-\r
-class QcfNode;\r
-\r
-class QuantConflictFind;\r
-\r
-class QcfNodeIndex {\r
-public:\r
-  std::map< TNode, QcfNodeIndex > d_children;\r
-  void clear() { d_children.clear(); }\r
-  void debugPrint( const char * c, int t );\r
-  Node existsTerm( TNode n, std::vector< TNode >& reps, int index = 0 );\r
-  Node addTerm( TNode n, std::vector< TNode >& reps, int index = 0 );\r
-};\r
-\r
-class QuantInfo;\r
-\r
-//match generator\r
-class MatchGen {\r
-  friend class QuantInfo;\r
-private:\r
-  //current children information\r
-  int d_child_counter;\r
-  //children of this object\r
-  std::vector< int > d_children_order;\r
-  unsigned getNumChildren() { return d_children.size(); }\r
-  MatchGen * getChild( int i ) { return &d_children[d_children_order[i]]; }\r
-  //MatchGen * getChild( int i ) { return &d_children[i]; }\r
-  //current matching information\r
-  std::vector< QcfNodeIndex * > d_qn;\r
-  std::vector< std::map< TNode, QcfNodeIndex >::iterator > d_qni;\r
-  bool doMatching( QuantConflictFind * p, QuantInfo * qi );\r
-  //for matching : each index is either a variable or a ground term\r
-  unsigned d_qni_size;\r
-  std::map< int, int > d_qni_var_num;\r
-  std::map< int, TNode > d_qni_gterm;\r
-  std::map< int, TNode > d_qni_gterm_rep;\r
-  std::map< int, int > d_qni_bound;\r
-  std::vector< int > d_qni_bound_except;\r
-  std::map< int, TNode > d_qni_bound_cons;\r
-  std::map< int, int > d_qni_bound_cons_var;\r
-  std::map< int, int >::iterator d_binding_it;\r
-  //std::vector< int > d_independent;\r
-  bool d_matched_basis;\r
-  bool d_binding;\r
-  //int getVarBindingVar();\r
-  std::map< int, Node > d_ground_eval;\r
-  //determine variable order\r
-  void determineVariableOrder( QuantInfo * qi, std::vector< int >& bvars );\r
-  void collectBoundVar( QuantInfo * qi, Node n, std::vector< int >& cbvars );\r
-public:\r
-  //type of the match generator\r
-  enum {\r
-    typ_invalid,\r
-    typ_ground,\r
-    typ_pred,\r
-    typ_eq,\r
-    typ_formula,\r
-    typ_var,\r
-    typ_ite_var,\r
-    typ_bool_var,\r
-    typ_tconstraint,\r
-    typ_tsym,\r
-  };\r
-  void debugPrintType( const char * c, short typ, bool isTrace = false );\r
-public:\r
-  MatchGen() : d_type( typ_invalid ){}\r
-  MatchGen( QuantInfo * qi, Node n, bool isVar = false );\r
-  bool d_tgt;\r
-  bool d_tgt_orig;\r
-  bool d_wasSet;\r
-  Node d_n;\r
-  std::vector< MatchGen > d_children;\r
-  short d_type;\r
-  bool d_type_not;\r
-  void reset_round( QuantConflictFind * p );\r
-  void reset( QuantConflictFind * p, bool tgt, QuantInfo * qi );\r
-  bool getNextMatch( QuantConflictFind * p, QuantInfo * qi );\r
-  bool getExplanation( QuantConflictFind * p, QuantInfo * qi, std::vector< Node >& exp );\r
-  Node getExplanationTerm( QuantConflictFind * p, QuantInfo * qi, Node t, std::vector< Node >& exp );\r
-  bool isValid() { return d_type!=typ_invalid; }\r
-  void setInvalid();\r
-\r
-  // is this term treated as UF application?\r
-  static bool isHandledBoolConnective( TNode n );\r
-  static bool isHandledUfTerm( TNode n );\r
-  static Node getOperator( QuantConflictFind * p, Node n );\r
-  //can this node be handled by the algorithm\r
-  static bool isHandled( TNode n );\r
-};\r
-\r
-//info for quantifiers\r
-class QuantInfo {\r
-private:\r
-  void registerNode( Node n, bool hasPol, bool pol, bool beneathQuant = false );\r
-  void flatten( Node n, bool beneathQuant );\r
-private: //for completing match\r
-  std::vector< int > d_unassigned;\r
-  std::vector< TypeNode > d_unassigned_tn;\r
-  int d_unassigned_nvar;\r
-  int d_una_index;\r
-  std::vector< int > d_una_eqc_count;\r
-public:\r
-  QuantInfo() : d_mg( NULL ) {}\r
-  ~QuantInfo() { delete d_mg; }\r
-  std::vector< TNode > d_vars;\r
-  std::map< TNode, int > d_var_num;\r
-  std::vector< int > d_tsym_vars;\r
-  std::map< TNode, bool > d_inMatchConstraint;\r
-  std::map< int, std::vector< Node > > d_var_constraint[2];\r
-  int getVarNum( TNode v ) { return d_var_num.find( v )!=d_var_num.end() ? d_var_num[v] : -1; }\r
-  bool isVar( TNode v ) { return d_var_num.find( v )!=d_var_num.end(); }\r
-  int getNumVars() { return (int)d_vars.size(); }\r
-  TNode getVar( int i ) { return d_vars[i]; }\r
-\r
-  MatchGen * d_mg;\r
-  Node d_q;\r
-  std::map< int, MatchGen * > d_var_mg;\r
-  void reset_round( QuantConflictFind * p );\r
-public:\r
-  //initialize\r
-  void initialize( Node q, Node qn );\r
-  //current constraints\r
-  std::vector< TNode > d_match;\r
-  std::vector< TNode > d_match_term;\r
-  std::map< int, std::map< TNode, int > > d_curr_var_deq;\r
-  std::map< Node, bool > d_tconstraints;\r
-  int getCurrentRepVar( int v );\r
-  TNode getCurrentValue( TNode n );\r
-  TNode getCurrentExpValue( TNode n );\r
-  bool getCurrentCanBeEqual( QuantConflictFind * p, int v, TNode n, bool chDiseq = false );\r
-  int addConstraint( QuantConflictFind * p, int v, TNode n, bool polarity );\r
-  int addConstraint( QuantConflictFind * p, int v, TNode n, int vn, bool polarity, bool doRemove );\r
-  bool setMatch( QuantConflictFind * p, int v, TNode n );\r
-  bool isMatchSpurious( QuantConflictFind * p );\r
-  bool isTConstraintSpurious( QuantConflictFind * p, std::vector< Node >& terms );\r
-  bool entailmentTest( QuantConflictFind * p, Node lit, bool chEnt = true );\r
-  bool completeMatch( QuantConflictFind * p, std::vector< int >& assigned, bool doContinue = false );\r
-  void revertMatch( std::vector< int >& assigned );\r
-  void debugPrintMatch( const char * c );\r
-  bool isConstrainedVar( int v );\r
-public:\r
-  void getMatch( std::vector< Node >& terms );\r
-};\r
-\r
-class QuantConflictFind : public QuantifiersModule\r
-{\r
-  friend class QcfNodeIndex;\r
-  friend class MatchGen;\r
-  friend class QuantInfo;\r
-  typedef context::CDChunkList<Node> NodeList;\r
-  typedef context::CDHashMap<Node, bool, NodeHashFunction> NodeBoolMap;\r
-private:\r
-  context::Context* d_c;\r
-  context::CDO< bool > d_conflict;\r
-  bool d_performCheck;\r
-  std::vector< Node > d_quant_order;\r
-  std::map< Kind, Node > d_zero;\r
-  //for storing nodes created during t-constraint solving (prevents memory leaks)\r
-  std::vector< Node > d_tempCache;\r
-private:\r
-  std::map< Node, Node > d_op_node;\r
-  int d_fid_count;\r
-  std::map< Node, int > d_fid;\r
-  Node mkEqNode( Node a, Node b );\r
-public:  //for ground terms\r
-  Node d_true;\r
-  Node d_false;\r
-  TNode getZero( Kind k );\r
-private:\r
-  Node evaluateTerm( Node n );\r
-  int evaluate( Node n, bool pref = false, bool hasPref = false );\r
-private:\r
-  //currently asserted quantifiers\r
-  NodeList d_qassert;\r
-  std::map< Node, QuantInfo > d_qinfo;\r
-private:  //for equivalence classes\r
-  eq::EqualityEngine * getEqualityEngine();\r
-  bool areDisequal( Node n1, Node n2 );\r
-  bool areEqual( Node n1, Node n2 );\r
-  Node getRepresentative( Node n );\r
-\r
-/*\r
-  class EqcInfo {\r
-  public:\r
-    EqcInfo( context::Context* c ) : d_diseq( c ) {}\r
-    NodeBoolMap d_diseq;\r
-    bool isDisequal( Node n ) { return d_diseq.find( n )!=d_diseq.end() && d_diseq[n]; }\r
-    void setDisequal( Node n, bool val = true ) { d_diseq[n] = val; }\r
-    //NodeBoolMap& getRelEqr( int index ) { return index==0 ? d_rel_eqr_e : d_rel_eqr_d; }\r
-  };\r
-  std::map< Node, EqcInfo * > d_eqc_info;\r
-  EqcInfo * getEqcInfo( Node n, bool doCreate = true );\r
-*/\r
-  // operator -> index(terms)\r
-  std::map< TNode, QcfNodeIndex > d_uf_terms;\r
-  // operator -> index(eqc -> terms)\r
-  std::map< TNode, QcfNodeIndex > d_eqc_uf_terms;\r
-  //get qcf node index\r
-  QcfNodeIndex * getQcfNodeIndex( Node eqc, Node f );\r
-  QcfNodeIndex * getQcfNodeIndex( Node f );\r
-  // type -> list(eqc)\r
-  std::map< TypeNode, std::vector< TNode > > d_eqcs;\r
-  std::map< TypeNode, Node > d_model_basis;\r
-  //mapping from UF terms to representatives of their arguments\r
-  std::map< TNode, std::vector< TNode > > d_arg_reps;\r
-  //compute arg reps\r
-  void computeArgReps( TNode n );\r
-  //compute\r
-  void computeUfTerms( TNode f );\r
-public:\r
-  enum {\r
-    effort_conflict,\r
-    effort_prop_eq,\r
-    effort_mc,\r
-  };\r
-  short d_effort;\r
-  void setEffort( int e ) { d_effort = e; }\r
-  static short getMaxQcfEffort();\r
-  bool areMatchEqual( TNode n1, TNode n2 );\r
-  bool areMatchDisequal( TNode n1, TNode n2 );\r
-public:\r
-  QuantConflictFind( QuantifiersEngine * qe, context::Context* c );\r
-  /** register quantifier */\r
-  void registerQuantifier( Node q );\r
-public:\r
-  /** assert quantifier */\r
-  void assertNode( Node q );\r
-  /** new node */\r
-  void newEqClass( Node n );\r
-  /** merge */\r
-  void merge( Node a, Node b );\r
-  /** assert disequal */\r
-  void assertDisequal( Node a, Node b );\r
-  /** reset round */\r
-  void reset_round( Theory::Effort level );\r
-  /** check */\r
-  void check( Theory::Effort level );\r
-  /** needs check */\r
-  bool needsCheck( Theory::Effort level );\r
-private:\r
-  bool d_needs_computeRelEqr;\r
-public:\r
-  void computeRelevantEqr();\r
-private:\r
-  void debugPrint( const char * c );\r
-  //for debugging\r
-  std::vector< Node > d_quants;\r
-  std::map< Node, int > d_quant_id;\r
-  void debugPrintQuant( const char * c, Node q );\r
-  void debugPrintQuantBody( const char * c, Node q, Node n, bool doVarNum = true );\r
-public:\r
-  /** statistics class */\r
-  class Statistics {\r
-  public:\r
-    IntStat d_inst_rounds;\r
-    IntStat d_conflict_inst;\r
-    IntStat d_prop_inst;\r
-    IntStat d_entailment_checks;\r
-    Statistics();\r
-    ~Statistics();\r
-  };\r
-  Statistics d_statistics;\r
-  /** Identify this module */\r
-  std::string identify() const { return "QcfEngine"; }\r
-};\r
-\r
-}\r
-}\r
-}\r
-\r
-#endif\r
+/*********************                                                        */
+/*! \file quant_conflict_find.h
+ ** \verbatim
+ ** Original author: Andrew Reynolds
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2013  New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief quantifiers conflict find class
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef QUANT_CONFLICT_FIND
+#define QUANT_CONFLICT_FIND
+
+#include "context/cdhashmap.h"
+#include "context/cdchunk_list.h"
+#include "theory/quantifiers_engine.h"
+
+namespace CVC4 {
+namespace theory {
+namespace quantifiers {
+
+class QcfNode;
+
+class QuantConflictFind;
+
+class QcfNodeIndex {
+public:
+  std::map< TNode, QcfNodeIndex > d_children;
+  void clear() { d_children.clear(); }
+  void debugPrint( const char * c, int t );
+  Node existsTerm( TNode n, std::vector< TNode >& reps, int index = 0 );
+  Node addTerm( TNode n, std::vector< TNode >& reps, int index = 0 );
+};
+
+class QuantInfo;
+
+//match generator
+class MatchGen {
+  friend class QuantInfo;
+private:
+  //current children information
+  int d_child_counter;
+  //children of this object
+  std::vector< int > d_children_order;
+  unsigned getNumChildren() { return d_children.size(); }
+  MatchGen * getChild( int i ) { return &d_children[d_children_order[i]]; }
+  //MatchGen * getChild( int i ) { return &d_children[i]; }
+  //current matching information
+  std::vector< QcfNodeIndex * > d_qn;
+  std::vector< std::map< TNode, QcfNodeIndex >::iterator > d_qni;
+  bool doMatching( QuantConflictFind * p, QuantInfo * qi );
+  //for matching : each index is either a variable or a ground term
+  unsigned d_qni_size;
+  std::map< int, int > d_qni_var_num;
+  std::map< int, TNode > d_qni_gterm;
+  std::map< int, TNode > d_qni_gterm_rep;
+  std::map< int, int > d_qni_bound;
+  std::vector< int > d_qni_bound_except;
+  std::map< int, TNode > d_qni_bound_cons;
+  std::map< int, int > d_qni_bound_cons_var;
+  std::map< int, int >::iterator d_binding_it;
+  //std::vector< int > d_independent;
+  bool d_matched_basis;
+  bool d_binding;
+  //int getVarBindingVar();
+  std::map< int, Node > d_ground_eval;
+  //determine variable order
+  void determineVariableOrder( QuantInfo * qi, std::vector< int >& bvars );
+  void collectBoundVar( QuantInfo * qi, Node n, std::vector< int >& cbvars );
+public:
+  //type of the match generator
+  enum {
+    typ_invalid,
+    typ_ground,
+    typ_pred,
+    typ_eq,
+    typ_formula,
+    typ_var,
+    typ_ite_var,
+    typ_bool_var,
+    typ_tconstraint,
+    typ_tsym,
+  };
+  void debugPrintType( const char * c, short typ, bool isTrace = false );
+public:
+  MatchGen() : d_type( typ_invalid ){}
+  MatchGen( QuantInfo * qi, Node n, bool isVar = false );
+  bool d_tgt;
+  bool d_tgt_orig;
+  bool d_wasSet;
+  Node d_n;
+  std::vector< MatchGen > d_children;
+  short d_type;
+  bool d_type_not;
+  void reset_round( QuantConflictFind * p );
+  void reset( QuantConflictFind * p, bool tgt, QuantInfo * qi );
+  bool getNextMatch( QuantConflictFind * p, QuantInfo * qi );
+  bool getExplanation( QuantConflictFind * p, QuantInfo * qi, std::vector< Node >& exp );
+  Node getExplanationTerm( QuantConflictFind * p, QuantInfo * qi, Node t, std::vector< Node >& exp );
+  bool isValid() { return d_type!=typ_invalid; }
+  void setInvalid();
+
+  // is this term treated as UF application?
+  static bool isHandledBoolConnective( TNode n );
+  static bool isHandledUfTerm( TNode n );
+  static Node getOperator( QuantConflictFind * p, Node n );
+  //can this node be handled by the algorithm
+  static bool isHandled( TNode n );
+};
+
+//info for quantifiers
+class QuantInfo {
+private:
+  void registerNode( Node n, bool hasPol, bool pol, bool beneathQuant = false );
+  void flatten( Node n, bool beneathQuant );
+private: //for completing match
+  std::vector< int > d_unassigned;
+  std::vector< TypeNode > d_unassigned_tn;
+  int d_unassigned_nvar;
+  int d_una_index;
+  std::vector< int > d_una_eqc_count;
+public:
+  QuantInfo() : d_mg( NULL ) {}
+  ~QuantInfo() { delete d_mg; }
+  std::vector< TNode > d_vars;
+  std::map< TNode, int > d_var_num;
+  std::vector< int > d_tsym_vars;
+  std::map< TNode, bool > d_inMatchConstraint;
+  std::map< int, std::vector< Node > > d_var_constraint[2];
+  int getVarNum( TNode v ) { return d_var_num.find( v )!=d_var_num.end() ? d_var_num[v] : -1; }
+  bool isVar( TNode v ) { return d_var_num.find( v )!=d_var_num.end(); }
+  int getNumVars() { return (int)d_vars.size(); }
+  TNode getVar( int i ) { return d_vars[i]; }
+
+  MatchGen * d_mg;
+  Node d_q;
+  std::map< int, MatchGen * > d_var_mg;
+  void reset_round( QuantConflictFind * p );
+public:
+  //initialize
+  void initialize( Node q, Node qn );
+  //current constraints
+  std::vector< TNode > d_match;
+  std::vector< TNode > d_match_term;
+  std::map< int, std::map< TNode, int > > d_curr_var_deq;
+  std::map< Node, bool > d_tconstraints;
+  int getCurrentRepVar( int v );
+  TNode getCurrentValue( TNode n );
+  TNode getCurrentExpValue( TNode n );
+  bool getCurrentCanBeEqual( QuantConflictFind * p, int v, TNode n, bool chDiseq = false );
+  int addConstraint( QuantConflictFind * p, int v, TNode n, bool polarity );
+  int addConstraint( QuantConflictFind * p, int v, TNode n, int vn, bool polarity, bool doRemove );
+  bool setMatch( QuantConflictFind * p, int v, TNode n );
+  bool isMatchSpurious( QuantConflictFind * p );
+  bool isTConstraintSpurious( QuantConflictFind * p, std::vector< Node >& terms );
+  bool entailmentTest( QuantConflictFind * p, Node lit, bool chEnt = true );
+  bool completeMatch( QuantConflictFind * p, std::vector< int >& assigned, bool doContinue = false );
+  void revertMatch( std::vector< int >& assigned );
+  void debugPrintMatch( const char * c );
+  bool isConstrainedVar( int v );
+public:
+  void getMatch( std::vector< Node >& terms );
+};
+
+class QuantConflictFind : public QuantifiersModule
+{
+  friend class QcfNodeIndex;
+  friend class MatchGen;
+  friend class QuantInfo;
+  typedef context::CDChunkList<Node> NodeList;
+  typedef context::CDHashMap<Node, bool, NodeHashFunction> NodeBoolMap;
+private:
+  context::Context* d_c;
+  context::CDO< bool > d_conflict;
+  bool d_performCheck;
+  std::vector< Node > d_quant_order;
+  std::map< Kind, Node > d_zero;
+  //for storing nodes created during t-constraint solving (prevents memory leaks)
+  std::vector< Node > d_tempCache;
+private:
+  std::map< Node, Node > d_op_node;
+  int d_fid_count;
+  std::map< Node, int > d_fid;
+  Node mkEqNode( Node a, Node b );
+public:  //for ground terms
+  Node d_true;
+  Node d_false;
+  TNode getZero( Kind k );
+private:
+  Node evaluateTerm( Node n );
+  int evaluate( Node n, bool pref = false, bool hasPref = false );
+private:
+  //currently asserted quantifiers
+  NodeList d_qassert;
+  std::map< Node, QuantInfo > d_qinfo;
+private:  //for equivalence classes
+  eq::EqualityEngine * getEqualityEngine();
+  bool areDisequal( Node n1, Node n2 );
+  bool areEqual( Node n1, Node n2 );
+  Node getRepresentative( Node n );
+
+/*
+  class EqcInfo {
+  public:
+    EqcInfo( context::Context* c ) : d_diseq( c ) {}
+    NodeBoolMap d_diseq;
+    bool isDisequal( Node n ) { return d_diseq.find( n )!=d_diseq.end() && d_diseq[n]; }
+    void setDisequal( Node n, bool val = true ) { d_diseq[n] = val; }
+    //NodeBoolMap& getRelEqr( int index ) { return index==0 ? d_rel_eqr_e : d_rel_eqr_d; }
+  };
+  std::map< Node, EqcInfo * > d_eqc_info;
+  EqcInfo * getEqcInfo( Node n, bool doCreate = true );
+*/
+  // operator -> index(terms)
+  std::map< TNode, QcfNodeIndex > d_uf_terms;
+  // operator -> index(eqc -> terms)
+  std::map< TNode, QcfNodeIndex > d_eqc_uf_terms;
+  //get qcf node index
+  QcfNodeIndex * getQcfNodeIndex( Node eqc, Node f );
+  QcfNodeIndex * getQcfNodeIndex( Node f );
+  // type -> list(eqc)
+  std::map< TypeNode, std::vector< TNode > > d_eqcs;
+  std::map< TypeNode, Node > d_model_basis;
+  //mapping from UF terms to representatives of their arguments
+  std::map< TNode, std::vector< TNode > > d_arg_reps;
+  //compute arg reps
+  void computeArgReps( TNode n );
+  //compute
+  void computeUfTerms( TNode f );
+public:
+  enum {
+    effort_conflict,
+    effort_prop_eq,
+    effort_mc,
+  };
+  short d_effort;
+  void setEffort( int e ) { d_effort = e; }
+  static short getMaxQcfEffort();
+  bool areMatchEqual( TNode n1, TNode n2 );
+  bool areMatchDisequal( TNode n1, TNode n2 );
+public:
+  QuantConflictFind( QuantifiersEngine * qe, context::Context* c );
+  /** register quantifier */
+  void registerQuantifier( Node q );
+public:
+  /** assert quantifier */
+  void assertNode( Node q );
+  /** new node */
+  void newEqClass( Node n );
+  /** merge */
+  void merge( Node a, Node b );
+  /** assert disequal */
+  void assertDisequal( Node a, Node b );
+  /** reset round */
+  void reset_round( Theory::Effort level );
+  /** check */
+  void check( Theory::Effort level );
+  /** needs check */
+  bool needsCheck( Theory::Effort level );
+private:
+  bool d_needs_computeRelEqr;
+public:
+  void computeRelevantEqr();
+private:
+  void debugPrint( const char * c );
+  //for debugging
+  std::vector< Node > d_quants;
+  std::map< Node, int > d_quant_id;
+  void debugPrintQuant( const char * c, Node q );
+  void debugPrintQuantBody( const char * c, Node q, Node n, bool doVarNum = true );
+public:
+  /** statistics class */
+  class Statistics {
+  public:
+    IntStat d_inst_rounds;
+    IntStat d_conflict_inst;
+    IntStat d_prop_inst;
+    IntStat d_entailment_checks;
+    Statistics();
+    ~Statistics();
+  };
+  Statistics d_statistics;
+  /** Identify this module */
+  std::string identify() const { return "QcfEngine"; }
+};
+
+}
+}
+}
+
+#endif
index aee6294bc76e5b2d414dc124ad197b71bda45014..18df0f7598905b8c72445bf1673bb2cfafb0a277 100644 (file)
-/*********************                                                        */\r
+/*********************                                                        */
 
-/*! \file regexp_operation.cpp\r
- ** \verbatim\r
- ** Original author: Tianyi Liang\r
- ** Major contributors: none\r
- ** Minor contributors (to current version): none\r
- ** This file is part of the CVC4 project.\r
- ** Copyright (c) 2009-2013  New York University and The University of Iowa\r
- ** See the file COPYING in the top-level source directory for licensing\r
- ** information.\endverbatim\r
- **\r
- ** \brief Symbolic Regular Expresion Operations\r
- **\r
- ** Symbolic Regular Expresion Operations\r
- **/\r
-\r
-#include "theory/strings/regexp_operation.h"\r
-#include "expr/kind.h"\r
-\r
-namespace CVC4 {\r
-namespace theory {\r
-namespace strings {\r
-\r
-RegExpOpr::RegExpOpr() {\r
-  d_emptyString = NodeManager::currentNM()->mkConst( ::CVC4::String("") );\r
-  d_true = NodeManager::currentNM()->mkConst( true );\r
-  d_false = NodeManager::currentNM()->mkConst( false );\r
-  d_zero = NodeManager::currentNM()->mkConst( ::CVC4::Rational(0) );\r
-  d_one = NodeManager::currentNM()->mkConst( ::CVC4::Rational(1) );\r
-  d_emptySingleton = NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP, d_emptyString );\r
-  std::vector< Node > nvec;\r
-  d_emptyRegexp = NodeManager::currentNM()->mkNode( kind::REGEXP_EMPTY, nvec );\r
-  d_sigma = NodeManager::currentNM()->mkNode( kind::REGEXP_SIGMA, nvec );\r
-  d_sigma_star = NodeManager::currentNM()->mkNode( kind::REGEXP_STAR, d_sigma );\r
-  d_card = 256;\r
-}\r
-\r
-int RegExpOpr::gcd ( int a, int b ) {\r
-  int c;\r
-  while ( a != 0 ) {\r
-     c = a; a = b%a;  b = c;\r
-  }\r
-  return b;\r
-}\r
-\r
-bool RegExpOpr::checkConstRegExp( Node r ) {\r
-  Trace("strings-regexp-cstre") << "RegExp-CheckConstRegExp starts with " << mkString( r ) << std::endl;\r
-  bool ret = true;\r
-  if( d_cstre_cache.find( r ) != d_cstre_cache.end() ) {\r
-    ret = d_cstre_cache[r];\r
-  } else {\r
-    if(r.getKind() == kind::STRING_TO_REGEXP) {\r
-      Node tmp = Rewriter::rewrite( r[0] );\r
-      ret = tmp.isConst();\r
-    } else {\r
-      for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-        if(!checkConstRegExp(r[i])) {\r
-          ret = false; break;\r
-        }\r
-      }\r
-    }\r
-    d_cstre_cache[r] = ret;\r
-  }\r
-  return ret;\r
-}\r
-\r
-// 0-unknown, 1-yes, 2-no\r
-int RegExpOpr::delta( Node r, Node &exp ) {\r
-  Trace("regexp-delta") << "RegExp-Delta starts with " << mkString( r ) << std::endl;\r
-  int ret = 0;\r
-  if( d_delta_cache.find( r ) != d_delta_cache.end() ) {\r
-    ret = d_delta_cache[r].first;\r
-    exp = d_delta_cache[r].second;\r
-  } else {\r
-    int k = r.getKind();\r
-    switch( k ) {\r
-      case kind::REGEXP_EMPTY: {\r
-        ret = 2;\r
-        break;\r
-      }\r
-      case kind::REGEXP_SIGMA: {\r
-        ret = 2;\r
-        break;\r
-      }\r
-      case kind::STRING_TO_REGEXP: {\r
-        Node tmp = Rewriter::rewrite(r[0]);\r
-        if(tmp.isConst()) {\r
-          if(tmp == d_emptyString) {\r
-            ret = 1;\r
-          } else {\r
-            ret = 2;\r
-          }\r
-        } else {\r
-          ret = 0;\r
-          if(tmp.getKind() == kind::STRING_CONCAT) {\r
-            for(unsigned i=0; i<tmp.getNumChildren(); i++) {\r
-              if(tmp[i].isConst()) {\r
-                ret = 2; break;\r
-              }\r
-            }\r
-\r
-          }\r
-          if(ret == 0) {\r
-            exp = r[0].eqNode(d_emptyString);\r
-          }\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_CONCAT: {\r
-        bool flag = false;\r
-        std::vector< Node > vec_nodes;\r
-        for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-          Node exp2;\r
-          int tmp = delta( r[i], exp2 );\r
-          if(tmp == 2) {\r
-            ret = 2;\r
-            break;\r
-          } else if(tmp == 0) {\r
-            vec_nodes.push_back( exp2 );\r
-            flag = true;\r
-          }\r
-        }\r
-        if(ret != 2) {\r
-          if(!flag) {\r
-            ret = 1;\r
-          } else {\r
-            exp = vec_nodes.size()==1 ? vec_nodes[0] : NodeManager::currentNM()->mkNode(kind::AND, vec_nodes);\r
-          }\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_UNION: {\r
-        bool flag = false;\r
-        std::vector< Node > vec_nodes;\r
-        for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-          Node exp2;\r
-          int tmp = delta( r[i], exp2 );\r
-          if(tmp == 1) {\r
-            ret = 1;\r
-            break;\r
-          } else if(tmp == 0) {\r
-            vec_nodes.push_back( exp2 );\r
-            flag = true;\r
-          }\r
-        }\r
-        if(ret != 1) {\r
-          if(!flag) {\r
-            ret = 2;\r
-          } else {\r
-            exp = vec_nodes.size()==1 ? vec_nodes[0] : NodeManager::currentNM()->mkNode(kind::OR, vec_nodes);\r
-          }\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_INTER: {\r
-        bool flag = false;\r
-        std::vector< Node > vec_nodes;\r
-        for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-          Node exp2;\r
-          int tmp = delta( r[i], exp2 );\r
-          if(tmp == 2) {\r
-            ret = 2;\r
-            break;\r
-          } else if(tmp == 0) {\r
-            vec_nodes.push_back( exp2 );\r
-            flag = true;\r
-          }\r
-        }\r
-        if(ret != 2) {\r
-          if(!flag) {\r
-            ret = 1;\r
-          } else {\r
-            exp = vec_nodes.size()==1 ? vec_nodes[0] : NodeManager::currentNM()->mkNode(kind::AND, vec_nodes);\r
-          }\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_STAR: {\r
-        ret = 1;\r
-        break;\r
-      }\r
-      case kind::REGEXP_PLUS: {\r
-        ret = delta( r[0], exp );\r
-        break;\r
-      }\r
-      case kind::REGEXP_OPT: {\r
-        ret = 1;\r
-        break;\r
-      }\r
-      case kind::REGEXP_RANGE: {\r
-        ret = 2;\r
-        break;\r
-      }\r
-      default: {\r
-        Trace("strings-error") << "Unsupported term: " << mkString( r ) << " in delta of RegExp." << std::endl;\r
-        Assert( false );\r
-        //return Node::null();\r
-      }\r
-    }\r
-    if(!exp.isNull()) {\r
-      exp = Rewriter::rewrite(exp);\r
-    }\r
-    std::pair< int, Node > p(ret, exp);\r
-    d_delta_cache[r] = p;\r
-  }\r
-  Trace("regexp-delta") << "RegExp-Delta returns : " << ret << std::endl;\r
-  return ret;\r
-}\r
-\r
-// 0-unknown, 1-yes, 2-no\r
-int RegExpOpr::derivativeS( Node r, CVC4::String c, Node &retNode ) {\r
-  Assert( c.size() < 2 );\r
-  Trace("regexp-derive") << "RegExp-derive starts with R{ " << mkString( r ) << " }, c=" << c << std::endl;\r
-\r
-  int ret = 1;\r
-  retNode = d_emptyRegexp;\r
-\r
-  PairNodeStr dv = std::make_pair( r, c );\r
-  if( d_deriv_cache.find( dv ) != d_deriv_cache.end() ) {\r
-    retNode = d_deriv_cache[dv].first;\r
-    ret = d_deriv_cache[dv].second;\r
-  } else if( c.isEmptyString() ) {\r
-    Node expNode;\r
-    ret = delta( r, expNode );\r
-    if(ret == 0) {\r
-      retNode = NodeManager::currentNM()->mkNode(kind::ITE, expNode, r, d_emptyRegexp);\r
-    } else if(ret == 1) {\r
-      retNode = r;\r
-    }\r
-    std::pair< Node, int > p(retNode, ret);\r
-    d_deriv_cache[dv] = p;\r
-  } else {\r
-    switch( r.getKind() ) {\r
-      case kind::REGEXP_EMPTY: {\r
-        ret = 2;\r
-        break;\r
-      }\r
-      case kind::REGEXP_SIGMA: {\r
-        retNode = d_emptySingleton;\r
-        break;\r
-      }\r
-      case kind::STRING_TO_REGEXP: {\r
-        Node tmp = Rewriter::rewrite(r[0]);\r
-        if(tmp.isConst()) {\r
-          if(tmp == d_emptyString) {\r
-            ret = 2;\r
-          } else {\r
-            if(tmp.getConst< CVC4::String >().getFirstChar() == c.getFirstChar()) {\r
-              retNode =  NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP,\r
-                tmp.getConst< CVC4::String >().size() == 1 ? d_emptyString : NodeManager::currentNM()->mkConst( tmp.getConst< CVC4::String >().substr(1) ) );\r
-            } else {\r
-              ret = 2;\r
-            }\r
-          }\r
-        } else {\r
-          ret = 0;\r
-          Node rest;\r
-          if(tmp.getKind() == kind::STRING_CONCAT) {\r
-            Node t2 = tmp[0];\r
-            if(t2.isConst()) {\r
-              if(t2.getConst< CVC4::String >().getFirstChar() == c.getFirstChar()) {\r
-                Node n =  NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP,\r
-                  tmp.getConst< CVC4::String >().size() == 1 ? d_emptyString : NodeManager::currentNM()->mkConst( tmp.getConst< CVC4::String >().substr(1) ) );\r
-                std::vector< Node > vec_nodes;\r
-                vec_nodes.push_back(n);\r
-                for(unsigned i=1; i<tmp.getNumChildren(); i++) {\r
-                  vec_nodes.push_back(tmp[i]);\r
-                }\r
-                retNode = NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, vec_nodes);\r
-                ret = 1;\r
-              } else {\r
-                ret = 2;\r
-              }\r
-            } else {\r
-              tmp = tmp[0];\r
-              std::vector< Node > vec_nodes;\r
-              for(unsigned i=1; i<tmp.getNumChildren(); i++) {\r
-                vec_nodes.push_back(tmp[i]);\r
-              }\r
-              rest = NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, vec_nodes);\r
-            }\r
-          }\r
-          if(ret == 0) {\r
-            Node sk = NodeManager::currentNM()->mkSkolem( "rsp", NodeManager::currentNM()->stringType(), "Split RegExp" );\r
-            retNode = NodeManager::currentNM()->mkNode(kind::STRING_TO_REGEXP, sk);\r
-            if(!rest.isNull()) {\r
-              retNode = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, retNode, rest));\r
-            }\r
-            Node exp = tmp.eqNode(NodeManager::currentNM()->mkNode(kind::STRING_CONCAT,\r
-                        NodeManager::currentNM()->mkConst(c), sk));\r
-            retNode = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::ITE, exp, retNode, d_emptyRegexp));\r
-          }\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_CONCAT: {\r
-        std::vector< Node > vec_nodes;\r
-        std::vector< Node > delta_nodes;\r
-        Node dnode = d_true;\r
-        for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-          Node dc;\r
-          Node exp2;\r
-          int rt = derivativeS(r[i], c, dc);\r
-          if(rt != 2) {\r
-            if(rt == 0) {\r
-              ret = 0;\r
-            }\r
-            std::vector< Node > vec_nodes2;\r
-            if(dc != d_emptySingleton) {\r
-              vec_nodes2.push_back( dc );\r
-            }\r
-            for(unsigned j=i+1; j<r.getNumChildren(); ++j) {\r
-              if(r[j] != d_emptySingleton) {\r
-                vec_nodes2.push_back( r[j] );\r
-              }\r
-            }\r
-            Node tmp = vec_nodes2.size()==0 ? d_emptySingleton :\r
-              vec_nodes2.size()==1 ? vec_nodes2[0] : NodeManager::currentNM()->mkNode( kind::REGEXP_CONCAT, vec_nodes2 );\r
-            if(dnode != d_true) {\r
-              tmp = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::ITE, dnode, tmp, d_emptyRegexp));\r
-              ret = 0;\r
-            }\r
-            if(std::find(vec_nodes.begin(), vec_nodes.end(), tmp) == vec_nodes.end()) {\r
-              vec_nodes.push_back( tmp );\r
-            }\r
-          }\r
-          Node exp3;\r
-          int rt2 = delta( r[i], exp3 );\r
-          if( rt2 == 0 ) {\r
-            dnode = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::AND, dnode, exp3));\r
-          } else if( rt2 == 2 ) {\r
-            break;\r
-          }\r
-        }\r
-        retNode = vec_nodes.size() == 0 ? d_emptyRegexp :\r
-              ( vec_nodes.size()==1 ? vec_nodes[0] : NodeManager::currentNM()->mkNode( kind::REGEXP_UNION, vec_nodes ) );\r
-        if(retNode == d_emptyRegexp) {\r
-          ret = 2;\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_UNION: {\r
-        std::vector< Node > vec_nodes;\r
-        for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-          Node dc;\r
-          int rt = derivativeS(r[i], c, dc);\r
-          if(rt == 0) {\r
-            ret = 0;\r
-          }\r
-          if(rt != 2) {\r
-            if(std::find(vec_nodes.begin(), vec_nodes.end(), dc) == vec_nodes.end()) {\r
-              vec_nodes.push_back( dc );\r
-            }\r
-          }\r
-          Trace("regexp-derive") << "RegExp-derive OR R[" << i << "]{ " << mkString(r[i]) << " returns " << mkString(dc) << std::endl;\r
-        }\r
-        retNode = vec_nodes.size() == 0 ? d_emptyRegexp :\r
-              ( vec_nodes.size()==1 ? vec_nodes[0] : NodeManager::currentNM()->mkNode( kind::REGEXP_UNION, vec_nodes ) );\r
-        if(retNode == d_emptyRegexp) {\r
-          ret = 2;\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_INTER: {\r
-        bool flag = true;\r
-        bool flag_sg = false;\r
-        std::vector< Node > vec_nodes;\r
-        for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-          Node dc;\r
-          int rt = derivativeS(r[i], c, dc);\r
-          if(rt == 0) {\r
-            ret = 0;\r
-          } else if(rt == 2) {\r
-            flag = false;\r
-            break;\r
-          }\r
-          if(dc == d_sigma_star) {\r
-            flag_sg = true;\r
-          } else {\r
-            if(std::find(vec_nodes.begin(), vec_nodes.end(), dc) == vec_nodes.end()) {\r
-              vec_nodes.push_back( dc );\r
-            }\r
-          }\r
-        }\r
-        if(flag) {\r
-          if(vec_nodes.size() == 0 && flag_sg) {\r
-            retNode = d_sigma_star;\r
-          } else {\r
-            retNode = vec_nodes.size() == 0 ? d_emptyRegexp :\r
-                  ( vec_nodes.size()==1 ? vec_nodes[0] : NodeManager::currentNM()->mkNode( kind::REGEXP_INTER, vec_nodes ) );\r
-            if(retNode == d_emptyRegexp) {\r
-              ret = 2;\r
-            }\r
-          }\r
-        } else {\r
-          retNode = d_emptyRegexp;\r
-          ret = 2;\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_STAR: {\r
-        Node dc;\r
-        ret = derivativeS(r[0], c, dc);\r
-        retNode = dc==d_emptyRegexp ? dc : (dc==d_emptySingleton ? r : NodeManager::currentNM()->mkNode( kind::REGEXP_CONCAT, dc, r ));\r
-        break;\r
-      }\r
-      default: {\r
-        Trace("strings-error") << "Unsupported term: " << mkString( r ) << " in derivative of RegExp." << std::endl;\r
-        Assert( false, "Unsupported Term" );\r
-      }\r
-    }\r
-    if(retNode != d_emptyRegexp) {\r
-      retNode = Rewriter::rewrite( retNode );\r
-    }\r
-    std::pair< Node, int > p(retNode, ret);\r
-    d_deriv_cache[dv] = p;\r
-  }\r
-\r
-  Trace("regexp-derive") << "RegExp-derive returns : " << mkString( retNode ) << std::endl;\r
-  return ret;\r
-}\r
-\r
-Node RegExpOpr::derivativeSingle( Node r, CVC4::String c ) {\r
-  Assert( c.size() < 2 );\r
-  Trace("regexp-derive") << "RegExp-derive starts with R{ " << mkString( r ) << " }, c=" << c << std::endl;\r
-  Node retNode = d_emptyRegexp;\r
-  PairNodeStr dv = std::make_pair( r, c );\r
-  if( d_dv_cache.find( dv ) != d_dv_cache.end() ) {\r
-    retNode = d_dv_cache[dv];\r
-  } else if( c.isEmptyString() ){\r
-    Node exp;\r
-    int tmp = delta( r, exp );\r
-    if(tmp == 0) {\r
-      // TODO variable\r
-      retNode = d_emptyRegexp;\r
-    } else if(tmp == 1) {\r
-      retNode = r;\r
-    } else {\r
-      retNode = d_emptyRegexp;\r
-    }\r
-  } else {\r
-    int k = r.getKind();\r
-    switch( k ) {\r
-      case kind::REGEXP_EMPTY: {\r
-        retNode = d_emptyRegexp;\r
-        break;\r
-      }\r
-      case kind::REGEXP_SIGMA: {\r
-        retNode = NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP, d_emptyString );\r
-        break;\r
-      }\r
-      case kind::STRING_TO_REGEXP: {\r
-        if(r[0].isConst()) {\r
-          if(r[0] == d_emptyString) {\r
-            retNode = d_emptyRegexp;\r
-          } else {\r
-            if(r[0].getConst< CVC4::String >().getFirstChar() == c.getFirstChar()) {\r
-              retNode =  NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP,\r
-                r[0].getConst< CVC4::String >().size() == 1 ? d_emptyString : NodeManager::currentNM()->mkConst( r[0].getConst< CVC4::String >().substr(1) ) );\r
-            } else {\r
-              retNode = d_emptyRegexp;\r
-            }\r
-          }\r
-        } else {\r
-          // TODO variable\r
-          retNode = d_emptyRegexp;\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_CONCAT: {\r
-        Node rees = NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP, d_emptyString );\r
-        std::vector< Node > vec_nodes;\r
-        for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-          Node dc = derivativeSingle(r[i], c);\r
-          if(dc != d_emptyRegexp) {\r
-            std::vector< Node > vec_nodes2;\r
-            if(dc != rees) {\r
-              vec_nodes2.push_back( dc );\r
-            }\r
-            for(unsigned j=i+1; j<r.getNumChildren(); ++j) {\r
-              if(r[j] != rees) {\r
-                vec_nodes2.push_back( r[j] );\r
-              }\r
-            }\r
-            Node tmp = vec_nodes2.size()==0 ? rees :\r
-              vec_nodes2.size()==1 ? vec_nodes2[0] : NodeManager::currentNM()->mkNode( kind::REGEXP_CONCAT, vec_nodes2 );\r
-            if(std::find(vec_nodes.begin(), vec_nodes.end(), tmp) == vec_nodes.end()) {\r
-              vec_nodes.push_back( tmp );\r
-            }\r
-          }\r
-          Node exp;\r
-          if( delta( r[i], exp ) != 1 ) {\r
-            break;\r
-          }\r
-        }\r
-        retNode = vec_nodes.size() == 0 ? d_emptyRegexp :\r
-              ( vec_nodes.size()==1 ? vec_nodes[0] : NodeManager::currentNM()->mkNode( kind::REGEXP_UNION, vec_nodes ) );\r
-        break;\r
-      }\r
-      case kind::REGEXP_UNION: {\r
-        std::vector< Node > vec_nodes;\r
-        for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-          Node dc = derivativeSingle(r[i], c);\r
-          if(dc != d_emptyRegexp) {\r
-            if(std::find(vec_nodes.begin(), vec_nodes.end(), dc) == vec_nodes.end()) {\r
-              vec_nodes.push_back( dc );\r
-            }\r
-          }\r
-          Trace("regexp-derive") << "RegExp-derive OR R[" << i << "]{ " << mkString(r[i]) << " returns " << mkString(dc) << std::endl;\r
-        }\r
-        retNode = vec_nodes.size() == 0 ? d_emptyRegexp :\r
-              ( vec_nodes.size()==1 ? vec_nodes[0] : NodeManager::currentNM()->mkNode( kind::REGEXP_UNION, vec_nodes ) );\r
-        break;\r
-      }\r
-      case kind::REGEXP_INTER: {\r
-        bool flag = true;\r
-        bool flag_sg = false;\r
-        std::vector< Node > vec_nodes;\r
-        for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-          Node dc = derivativeSingle(r[i], c);\r
-          if(dc != d_emptyRegexp) {\r
-            if(dc == d_sigma_star) {\r
-              flag_sg = true;\r
-            } else {\r
-              if(std::find(vec_nodes.begin(), vec_nodes.end(), dc) == vec_nodes.end()) {\r
-                vec_nodes.push_back( dc );\r
-              }\r
-            }\r
-          } else {\r
-            flag = false;\r
-            break;\r
-          }\r
-        }\r
-        if(flag) {\r
-          if(vec_nodes.size() == 0 && flag_sg) {\r
-            retNode = d_sigma_star;\r
-          } else {\r
-            retNode = vec_nodes.size() == 0 ? d_emptyRegexp :\r
-                  ( vec_nodes.size()==1 ? vec_nodes[0] : NodeManager::currentNM()->mkNode( kind::REGEXP_INTER, vec_nodes ) );\r
-          }\r
-        } else {\r
-          retNode = d_emptyRegexp;\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_STAR: {\r
-        Node dc = derivativeSingle(r[0], c);\r
-        if(dc != d_emptyRegexp) {\r
-          retNode = dc==NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP, d_emptyString ) ? r : NodeManager::currentNM()->mkNode( kind::REGEXP_CONCAT, dc, r );\r
-        } else {\r
-          retNode = d_emptyRegexp;\r
-        }\r
-        break;\r
-      }\r
-      default: {\r
-        //TODO: special sym: sigma, none, all\r
-        Trace("strings-error") << "Unsupported term: " << mkString( r ) << " in derivative of RegExp." << std::endl;\r
-        Assert( false, "Unsupported Term" );\r
-        //return Node::null();\r
-      }\r
-    }\r
-    if(retNode != d_emptyRegexp) {\r
-      retNode = Rewriter::rewrite( retNode );\r
-    }\r
-    d_dv_cache[dv] = retNode;\r
-  }\r
-  Trace("regexp-derive") << "RegExp-derive returns : " << mkString( retNode ) << std::endl;\r
-  return retNode;\r
-}\r
-\r
-//TODO:\r
-bool RegExpOpr::guessLength( Node r, int &co ) {\r
-  int k = r.getKind();\r
-  switch( k ) {\r
-    case kind::STRING_TO_REGEXP:\r
-    {\r
-      if(r[0].isConst()) {\r
-        co += r[0].getConst< CVC4::String >().size();\r
-        return true;\r
-      } else {\r
-        return false;\r
-      }\r
-    }\r
-      break;\r
-    case kind::REGEXP_CONCAT:\r
-    {\r
-      for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-        if(!guessLength( r[i], co)) {\r
-          return false;\r
-        }\r
-      }\r
-      return true;\r
-    }\r
-      break;\r
-    case kind::REGEXP_UNION:\r
-    {\r
-      int g_co;\r
-      for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-        int cop = 0;\r
-        if(!guessLength( r[i], cop)) {\r
-          return false;\r
-        }\r
-        if(i == 0) {\r
-          g_co = cop;\r
-        } else {\r
-          g_co = gcd(g_co, cop);\r
-        }\r
-      }\r
-      return true;\r
-    }\r
-      break;\r
-    case kind::REGEXP_INTER:\r
-    {\r
-      int g_co;\r
-      for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-        int cop = 0;\r
-        if(!guessLength( r[i], cop)) {\r
-          return false;\r
-        }\r
-        if(i == 0) {\r
-          g_co = cop;\r
-        } else {\r
-          g_co = gcd(g_co, cop);\r
-        }\r
-      }\r
-      return true;\r
-    }\r
-      break;\r
-    case kind::REGEXP_STAR:\r
-    {\r
-      co = 0;\r
-      return true;\r
-    }\r
-      break;\r
-    default:\r
-      Trace("strings-error") << "Unsupported term: " << mkString( r ) << " in membership of RegExp." << std::endl;\r
-      return false;\r
-  }\r
-}\r
-\r
-void RegExpOpr::firstChars( Node r, std::set<unsigned> &pcset, SetNodes &pvset ) {\r
-  std::map< Node, std::pair< std::set<unsigned>, SetNodes > >::const_iterator itr = d_fset_cache.find(r);\r
-  if(itr != d_fset_cache.end()) {\r
-    pcset.insert((itr->second).first.begin(), (itr->second).first.end());\r
-    pvset.insert((itr->second).second.begin(), (itr->second).second.end());\r
-  } else {\r
-    std::set<unsigned> cset;\r
-    SetNodes vset;\r
-    int k = r.getKind();\r
-    switch( k ) {\r
-      case kind::REGEXP_EMPTY: {\r
-        break;\r
-      }\r
-      case kind::REGEXP_SIGMA: {\r
-        for(unsigned i=0; i<d_card; i++) {\r
-          cset.insert(i);\r
-        }\r
-        break;\r
-      }\r
-      case kind::STRING_TO_REGEXP: {\r
-        Node st = Rewriter::rewrite(r[0]);\r
-        if(st.isConst()) {\r
-          CVC4::String s = st.getConst< CVC4::String >();\r
-          if(s.size() != 0) {\r
-            cset.insert(s[0]);\r
-          }\r
-        } else if(st.getKind() == kind::VARIABLE) {\r
-          vset.insert( st );\r
-        } else {\r
-          if(st[0].isConst()) {\r
-            CVC4::String s = st[0].getConst< CVC4::String >();\r
-            cset.insert(s[0]);\r
-          } else {\r
-            vset.insert( st[0] );\r
-          }\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_CONCAT: {\r
-        for(unsigned i=0; i<r.getNumChildren(); i++) {\r
-          firstChars(r[i], cset, vset);\r
-          Node n = r[i];\r
-          Node exp;\r
-          int r = delta( n, exp );\r
-          if(r != 1) {\r
-            break;\r
-          }\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_UNION: {\r
-        for(unsigned i=0; i<r.getNumChildren(); i++) {\r
-          firstChars(r[i], cset, vset);\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_INTER: {\r
-        //TODO: Overapproximation for now\r
-        for(unsigned i=0; i<r.getNumChildren(); i++) {\r
-          firstChars(r[i], cset, vset);\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_STAR: {\r
-        firstChars(r[0], cset, vset);\r
-        break;\r
-      }\r
-      default: {\r
-        Trace("strings-regexp") << "Unsupported term: " << r << " in getCharSet." << std::endl;\r
-        Assert( false, "Unsupported Term" );\r
-      }\r
-    }\r
-    pcset.insert(cset.begin(), cset.end());\r
-    pvset.insert(vset.begin(), vset.end());\r
-    std::pair< std::set<unsigned>, SetNodes > p(cset, vset);\r
-    d_fset_cache[r] = p;\r
-\r
-    Trace("regexp-fset") << "FSET( " << mkString(r) << " ) = { ";\r
-    for(std::set<unsigned>::const_iterator itr = cset.begin();\r
-      itr != cset.end(); itr++) {\r
-        Trace("regexp-fset") << CVC4::String::convertUnsignedIntToChar(*itr) << ",";\r
-      }\r
-    Trace("regexp-fset") << " }" << std::endl;\r
-  }\r
-}\r
-\r
-bool RegExpOpr::follow( Node r, CVC4::String c, std::vector< char > &vec_chars ) {\r
-  int k = r.getKind();\r
-  switch( k ) {\r
-    case kind::STRING_TO_REGEXP:\r
-    {\r
-      if(r[0].isConst()) {\r
-        if(r[0] != d_emptyString) {\r
-          char t1 = r[0].getConst< CVC4::String >().getFirstChar();\r
-          if(c.isEmptyString()) {\r
-            vec_chars.push_back( t1 );\r
-            return true;\r
-          } else {\r
-            char t2 = c.getFirstChar();\r
-            if(t1 != t2) {\r
-              return false;\r
-            } else {\r
-              if(c.size() >= 2) {\r
-                vec_chars.push_back( c.substr(1,1).getFirstChar() );\r
-              } else {\r
-                vec_chars.push_back( '\0' );\r
-              }\r
-              return true;\r
-            }\r
-          }\r
-        } else {\r
-          return false;\r
-        }\r
-      } else {\r
-        return false;\r
-      }\r
-    }\r
-      break;\r
-    case kind::REGEXP_CONCAT:\r
-    {\r
-      for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-        if( follow(r[i], c, vec_chars) ) {\r
-          if(vec_chars[vec_chars.size() - 1] == '\0') {\r
-            vec_chars.pop_back();\r
-            c = d_emptyString.getConst< CVC4::String >();\r
-          }\r
-        } else {\r
-          return false;\r
-        }\r
-      }\r
-      vec_chars.push_back( '\0' );\r
-      return true;\r
-    }\r
-      break;\r
-    case kind::REGEXP_UNION:\r
-    {\r
-      bool flag = false;\r
-      for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-        if( follow(r[i], c, vec_chars) ) {\r
-          flag=true;\r
-        }\r
-      }\r
-      return flag;\r
-    }\r
-      break;\r
-    case kind::REGEXP_INTER:\r
-    {\r
-      std::vector< char > vt2;\r
-      for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-        std::vector< char > v_tmp;\r
-        if( !follow(r[i], c, v_tmp) ) {\r
-          return false;\r
-        }\r
-        std::vector< char > vt3(vt2);\r
-        vt2.clear();\r
-        std::set_intersection( vt3.begin(), vt3.end(), v_tmp.begin(), v_tmp.end(), vt2.begin() );\r
-        if(vt2.size() == 0) {\r
-          return false;\r
-        }\r
-      }\r
-      vec_chars.insert( vec_chars.end(), vt2.begin(), vt2.end() );\r
-      return true;\r
-    }\r
-      break;\r
-    case kind::REGEXP_STAR:\r
-    {\r
-      if(follow(r[0], c, vec_chars)) {\r
-        if(vec_chars[vec_chars.size() - 1] == '\0') {\r
-          if(c.isEmptyString()) {\r
-            return true;\r
-          } else {\r
-            vec_chars.pop_back();\r
-            c = d_emptyString.getConst< CVC4::String >();\r
-            return follow(r[0], c, vec_chars);\r
-          }\r
-        } else {\r
-          return true;\r
-        }\r
-      } else {\r
-        vec_chars.push_back( '\0' );\r
-        return true;\r
-      }\r
-    }\r
-      break;\r
-    default: {\r
-      Trace("strings-error") << "Unsupported term: " << mkString( r ) << " in delta of RegExp." << std::endl;\r
-      //AlwaysAssert( false );\r
-      //return Node::null();\r
-      return false;\r
-    }\r
-  }\r
-}\r
-\r
-Node RegExpOpr::mkAllExceptOne( char exp_c ) {\r
-  std::vector< Node > vec_nodes;\r
-  for(char c=d_char_start; c<=d_char_end; ++c) {\r
-    if(c != exp_c ) {\r
-      Node n = NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP, NodeManager::currentNM()->mkConst( ::CVC4::String( c ) ) );\r
-      vec_nodes.push_back( n );\r
-    }\r
-  }\r
-  return NodeManager::currentNM()->mkNode( kind::REGEXP_UNION, vec_nodes );\r
-}\r
-\r
-//simplify\r
-void RegExpOpr::simplify(Node t, std::vector< Node > &new_nodes, bool polarity) {\r
-  Trace("strings-regexp-simpl") << "RegExp-Simpl starts with " << t << ", polarity=" << polarity << std::endl;\r
-  Assert(t.getKind() == kind::STRING_IN_REGEXP);\r
-  Node str = Rewriter::rewrite(t[0]);\r
-  Node re  = Rewriter::rewrite(t[1]);\r
-  if(polarity) {\r
-    simplifyPRegExp( str, re, new_nodes );\r
-  } else {\r
-    simplifyNRegExp( str, re, new_nodes );\r
-  }\r
-  Trace("strings-regexp-simpl") << "RegExp-Simpl  returns (" << new_nodes.size() << "):\n";\r
-  for(unsigned i=0; i<new_nodes.size(); i++) {\r
-    Trace("strings-regexp-simpl") << "\t" << new_nodes[i] << std::endl;\r
-  }\r
-}\r
-void RegExpOpr::simplifyNRegExp( Node s, Node r, std::vector< Node > &new_nodes ) {\r
-  std::pair < Node, Node > p(s, r);\r
-  std::map < std::pair< Node, Node >, Node >::const_iterator itr = d_simpl_neg_cache.find(p);\r
-  if(itr != d_simpl_neg_cache.end()) {\r
-    new_nodes.push_back( itr->second );\r
-  } else {\r
-    int k = r.getKind();\r
-    Node conc;\r
-    switch( k ) {\r
-      case kind::REGEXP_EMPTY: {\r
-        conc = d_true;\r
-        break;\r
-      }\r
-      case kind::REGEXP_SIGMA: {\r
-        conc = d_one.eqNode(NodeManager::currentNM()->mkNode(kind::STRING_LENGTH, s)).negate();\r
-        break;\r
-      }\r
-      case kind::STRING_TO_REGEXP: {\r
-        conc = s.eqNode(r[0]).negate();\r
-        break;\r
-      }\r
-      case kind::REGEXP_CONCAT: {\r
-        //TODO: rewrite empty\r
-        Node lens = NodeManager::currentNM()->mkNode(kind::STRING_LENGTH, s);\r
-        Node b1 = NodeManager::currentNM()->mkBoundVar(NodeManager::currentNM()->integerType());\r
-        Node b1v = NodeManager::currentNM()->mkNode(kind::BOUND_VAR_LIST, b1);\r
-        Node g1 = NodeManager::currentNM()->mkNode( kind::AND, NodeManager::currentNM()->mkNode(kind::GEQ, b1, d_zero),\r
-              NodeManager::currentNM()->mkNode( kind::GEQ, NodeManager::currentNM()->mkNode(kind::STRING_LENGTH, s), b1 ) );\r
-        Node s1 = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::STRING_SUBSTR_TOTAL, s, d_zero, b1));\r
-        Node s2 = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::STRING_SUBSTR_TOTAL, s, b1, NodeManager::currentNM()->mkNode(kind::MINUS, lens, b1)));\r
-        Node s1r1 = NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, s1, r[0]).negate();\r
-        if(r[0].getKind() == kind::STRING_TO_REGEXP) {\r
-          s1r1 = s1.eqNode(r[0][0]).negate();\r
-        } else if(r[0].getKind() == kind::REGEXP_EMPTY) {\r
-          s1r1 = d_true;\r
-        }\r
-        Node r2 = r[1];\r
-        if(r.getNumChildren() > 2) {\r
-          std::vector< Node > nvec;\r
-          for(unsigned i=1; i<r.getNumChildren(); i++) {\r
-            nvec.push_back( r[i] );\r
-          }\r
-          r2 = NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, nvec);\r
-        }\r
-        r2 = Rewriter::rewrite(r2);\r
-        Node s2r2 = NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, s2, r2).negate();\r
-        if(r2.getKind() == kind::STRING_TO_REGEXP) {\r
-          s2r2 = s2.eqNode(r2[0]).negate();\r
-        } else if(r2.getKind() == kind::REGEXP_EMPTY) {\r
-          s2r2 = d_true;\r
-        }\r
-\r
-        conc = NodeManager::currentNM()->mkNode(kind::OR, s1r1, s2r2);\r
-        conc = NodeManager::currentNM()->mkNode(kind::IMPLIES, g1, conc);\r
-        conc = NodeManager::currentNM()->mkNode(kind::FORALL, b1v, conc);\r
-        break;\r
-      }\r
-      case kind::REGEXP_UNION: {\r
-        std::vector< Node > c_and;\r
-        for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-          if(r[i].getKind() == kind::STRING_TO_REGEXP) {\r
-            c_and.push_back( r[i][0].eqNode(s).negate() );\r
-          } else if(r[i].getKind() == kind::REGEXP_EMPTY) {\r
-            continue;\r
-          } else {\r
-            c_and.push_back(NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, s, r[i]).negate());\r
-          }\r
-        }\r
-        conc = c_and.size() == 0 ? d_true :\r
-            c_and.size() == 1 ? c_and[0] : NodeManager::currentNM()->mkNode(kind::AND, c_and);\r
-        break;\r
-      }\r
-      case kind::REGEXP_INTER: {\r
-        bool emptyflag = false;\r
-        std::vector< Node > c_or;\r
-        for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-          if(r[i].getKind() == kind::STRING_TO_REGEXP) {\r
-            c_or.push_back( r[i][0].eqNode(s).negate() );\r
-          } else if(r[i].getKind() == kind::REGEXP_EMPTY) {\r
-            emptyflag = true;\r
-            break;\r
-          } else {\r
-            c_or.push_back(NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, s, r[i]).negate());\r
-          }\r
-        }\r
-        if(emptyflag) {\r
-          conc = d_true;\r
-        } else {\r
-          conc = c_or.size() == 1 ? c_or[0] : NodeManager::currentNM()->mkNode(kind::OR, c_or);\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_STAR: {\r
-        if(s == d_emptyString) {\r
-          conc = d_false;\r
-        } else if(r[0].getKind() == kind::REGEXP_EMPTY) {\r
-          conc = s.eqNode(d_emptyString).negate();\r
-        } else if(r[0].getKind() == kind::REGEXP_SIGMA) {\r
-          conc = d_false;\r
-        } else {\r
-          Node lens = NodeManager::currentNM()->mkNode(kind::STRING_LENGTH, s);\r
-          Node sne = s.eqNode(d_emptyString).negate();\r
-          Node b1 = NodeManager::currentNM()->mkBoundVar(NodeManager::currentNM()->integerType());\r
-          Node b1v = NodeManager::currentNM()->mkNode(kind::BOUND_VAR_LIST, b1);\r
-          Node g1 = NodeManager::currentNM()->mkNode( kind::AND, NodeManager::currentNM()->mkNode(kind::GEQ, b1, d_one),\r
-                NodeManager::currentNM()->mkNode( kind::GEQ, lens, b1 ) );\r
-          //internal\r
-          Node s1 = NodeManager::currentNM()->mkNode(kind::STRING_SUBSTR_TOTAL, s, d_zero, b1);\r
-          Node s2 = NodeManager::currentNM()->mkNode(kind::STRING_SUBSTR_TOTAL, s, b1, NodeManager::currentNM()->mkNode(kind::MINUS, lens, b1));\r
-          Node s1r1 = NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, s1, r[0]).negate();\r
-          Node s2r2 = NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, s2, r).negate();\r
-\r
-          conc = NodeManager::currentNM()->mkNode(kind::OR, s1r1, s2r2);\r
-          conc = NodeManager::currentNM()->mkNode(kind::IMPLIES, g1, conc);\r
-          conc = NodeManager::currentNM()->mkNode(kind::FORALL, b1v, conc);\r
-          conc = NodeManager::currentNM()->mkNode(kind::AND, sne, conc);\r
-        }\r
-        break;\r
-      }\r
-      default: {\r
-        Trace("strings-regexp") << "Unsupported term: " << r << " in simplifyNRegExp." << std::endl;\r
-        Assert( false, "Unsupported Term" );\r
-      }\r
-    }\r
-    conc = Rewriter::rewrite( conc );\r
-    new_nodes.push_back( conc );\r
-    d_simpl_neg_cache[p] = conc;\r
-  }\r
-}\r
-void RegExpOpr::simplifyPRegExp( Node s, Node r, std::vector< Node > &new_nodes ) {\r
-  std::pair < Node, Node > p(s, r);\r
-  std::map < std::pair< Node, Node >, Node >::const_iterator itr = d_simpl_cache.find(p);\r
-  if(itr != d_simpl_cache.end()) {\r
-    new_nodes.push_back( itr->second );\r
-  } else {\r
-    int k = r.getKind();\r
-    Node conc;\r
-    switch( k ) {\r
-      case kind::REGEXP_EMPTY: {\r
-        conc = d_false;\r
-        break;\r
-      }\r
-      case kind::REGEXP_SIGMA: {\r
-        conc = d_one.eqNode(NodeManager::currentNM()->mkNode(kind::STRING_LENGTH, s));\r
-        break;\r
-      }\r
-      case kind::STRING_TO_REGEXP: {\r
-        conc = s.eqNode(r[0]);\r
-        break;\r
-      }\r
-      case kind::REGEXP_CONCAT: {\r
-        std::vector< Node > nvec;\r
-        std::vector< Node > cc;\r
-        bool emptyflag = false;\r
-        for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-          if(r[i].getKind() == kind::STRING_TO_REGEXP) {\r
-            cc.push_back( r[i][0] );\r
-          } else if(r[i].getKind() == kind::REGEXP_EMPTY) {\r
-            emptyflag = true;\r
-            break;\r
-          } else {\r
-            Node sk = NodeManager::currentNM()->mkSkolem( "rc", s.getType(), "created for regular expression concat" );\r
-            Node lem = NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, sk, r[i]);\r
-            nvec.push_back(lem);\r
-            cc.push_back(sk);\r
-          }\r
-        }\r
-        if(emptyflag) {\r
-          conc = d_false;\r
-        } else {\r
-          Node lem = s.eqNode( NodeManager::currentNM()->mkNode(kind::STRING_CONCAT, cc) );\r
-          nvec.push_back(lem);\r
-          conc = nvec.size() == 1 ? nvec[0] : NodeManager::currentNM()->mkNode(kind::AND, nvec);\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_UNION: {\r
-        std::vector< Node > c_or;\r
-        for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-          if(r[i].getKind() == kind::STRING_TO_REGEXP) {\r
-            c_or.push_back( r[i][0].eqNode(s) );\r
-          } else if(r[i].getKind() == kind::REGEXP_EMPTY) {\r
-            continue;\r
-          } else {\r
-            c_or.push_back(NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, s, r[i]));\r
-          }\r
-        }\r
-        conc = c_or.size() == 0 ? d_false :\r
-            c_or.size() == 1 ? c_or[0] : NodeManager::currentNM()->mkNode(kind::OR, c_or);\r
-        break;\r
-      }\r
-      case kind::REGEXP_INTER: {\r
-        std::vector< Node > c_and;\r
-        bool emptyflag = false;\r
-        for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-          if(r[i].getKind() == kind::STRING_TO_REGEXP) {\r
-            c_and.push_back( r[i][0].eqNode(s) );\r
-          } else if(r[i].getKind() == kind::REGEXP_EMPTY) {\r
-            emptyflag = true;\r
-            break;\r
-          } else {\r
-            c_and.push_back(NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, s, r[i]));\r
-          }\r
-        }\r
-        if(emptyflag) {\r
-          conc = d_false;\r
-        } else {\r
-          conc = c_and.size() == 1 ? c_and[0] : NodeManager::currentNM()->mkNode(kind::AND, c_and);\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_STAR: {\r
-        if(s == d_emptyString) {\r
-          conc = d_true;\r
-        } else if(r[0].getKind() == kind::REGEXP_EMPTY) {\r
-          conc = s.eqNode(d_emptyString);\r
-        } else if(r[0].getKind() == kind::REGEXP_SIGMA) {\r
-          conc = d_true;\r
-        } else {\r
-          Node se = s.eqNode(d_emptyString);\r
-          Node sinr = NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, s, r[0]);\r
-          Node sk1 = NodeManager::currentNM()->mkSkolem( "rs", s.getType(), "created for regular expression star" );\r
-          Node sk2 = NodeManager::currentNM()->mkSkolem( "rs", s.getType(), "created for regular expression star" );\r
-          Node s1nz = sk1.eqNode(d_emptyString).negate();\r
-          Node s2nz = sk2.eqNode(d_emptyString).negate();\r
-          Node s1inr = NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, sk1, r[0]);\r
-          Node s2inrs = NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, sk2, r);\r
-          Node s12 = s.eqNode(NodeManager::currentNM()->mkNode(kind::STRING_CONCAT, sk1, sk2));\r
-\r
-          conc = NodeManager::currentNM()->mkNode(kind::AND, s12, s1nz, s2nz, s1inr, s2inrs);\r
-          conc = NodeManager::currentNM()->mkNode(kind::OR, se, sinr, conc);\r
-        }\r
-        break;\r
-      }\r
-      default: {\r
-        Trace("strings-regexp") << "Unsupported term: " << r << " in simplifyPRegExp." << std::endl;\r
-        Assert( false, "Unsupported Term" );\r
-      }\r
-    }\r
-    conc = Rewriter::rewrite( conc );\r
-    new_nodes.push_back( conc );\r
-    d_simpl_cache[p] = conc;\r
-  }\r
-}\r
-\r
-void RegExpOpr::getCharSet( Node r, std::set<unsigned> &pcset, SetNodes &pvset ) {\r
-  std::map< Node, std::pair< std::set<unsigned>, SetNodes > >::const_iterator itr = d_cset_cache.find(r);\r
-  if(itr != d_cset_cache.end()) {\r
-    pcset.insert((itr->second).first.begin(), (itr->second).first.end());\r
-    pvset.insert((itr->second).second.begin(), (itr->second).second.end());\r
-  } else {\r
-    std::set<unsigned> cset;\r
-    SetNodes vset;\r
-    int k = r.getKind();\r
-    switch( k ) {\r
-      case kind::REGEXP_EMPTY: {\r
-        break;\r
-      }\r
-      case kind::REGEXP_SIGMA: {\r
-        for(unsigned i=0; i<d_card; i++) {\r
-          cset.insert(i);\r
-        }\r
-        break;\r
-      }\r
-      case kind::STRING_TO_REGEXP: {\r
-        Node st = Rewriter::rewrite(r[0]);\r
-        if(st.isConst()) {\r
-          CVC4::String s = st.getConst< CVC4::String >();\r
-          s.getCharSet( cset );\r
-        } else if(st.getKind() == kind::VARIABLE) {\r
-          vset.insert( st );\r
-        } else {\r
-          for(unsigned i=0; i<st.getNumChildren(); i++) {\r
-            if(st[i].isConst()) {\r
-              CVC4::String s = st[i].getConst< CVC4::String >();\r
-              s.getCharSet( cset );\r
-            } else {\r
-              vset.insert( st[i] );\r
-            }\r
-          }\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_CONCAT: {\r
-        for(unsigned i=0; i<r.getNumChildren(); i++) {\r
-          getCharSet(r[i], cset, vset);\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_UNION: {\r
-        for(unsigned i=0; i<r.getNumChildren(); i++) {\r
-          getCharSet(r[i], cset, vset);\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_INTER: {\r
-        //TODO: Overapproximation for now\r
-        for(unsigned i=0; i<r.getNumChildren(); i++) {\r
-          getCharSet(r[i], cset, vset);\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_STAR: {\r
-        getCharSet(r[0], cset, vset);\r
-        break;\r
-      }\r
-      default: {\r
-        Trace("strings-regexp") << "Unsupported term: " << r << " in getCharSet." << std::endl;\r
-        Assert( false, "Unsupported Term" );\r
-      }\r
-    }\r
-    pcset.insert(cset.begin(), cset.end());\r
-    pvset.insert(vset.begin(), vset.end());\r
-    std::pair< std::set<unsigned>, SetNodes > p(cset, vset);\r
-    d_cset_cache[r] = p;\r
-\r
-    Trace("regexp-cset") << "CSET( " << mkString(r) << " ) = { ";\r
-    for(std::set<unsigned>::const_iterator itr = cset.begin();\r
-      itr != cset.end(); itr++) {\r
-        Trace("regexp-cset") << CVC4::String::convertUnsignedIntToChar(*itr) << ",";\r
-      }\r
-    Trace("regexp-cset") << " }" << std::endl;\r
-  }\r
-}\r
-\r
+/*! \file regexp_operation.cpp
+ ** \verbatim
+ ** Original author: Tianyi Liang
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2013  New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Symbolic Regular Expresion Operations
+ **
+ ** Symbolic Regular Expresion Operations
+ **/
 
-Node RegExpOpr::intersectInternal( Node r1, Node r2, std::map< unsigned, std::set< PairNodes > > cache, bool &spflag ) {\r
-  if(spflag) {\r
-    //TODO: var\r
-    return Node::null();\r
-  }\r
-  std::pair < Node, Node > p(r1, r2);\r
-  std::map < std::pair< Node, Node >, Node >::const_iterator itr = d_inter_cache.find(p);\r
-  Node rNode;\r
-  if(itr != d_inter_cache.end()) {\r
-    rNode = itr->second;\r
-  } else {\r
-    if(r1 == r2) {\r
-      rNode = r1;\r
-    } else if(r1 == d_emptyRegexp || r2 == d_emptyRegexp) {\r
-      rNode = d_emptyRegexp;\r
-    } else if(r1 == d_emptySingleton || r2 == d_emptySingleton) {\r
-      Node exp;\r
-      int r = delta((r1 == d_emptySingleton ? r2 : r1), exp);\r
-      if(r == 0) {\r
-        //TODO: variable\r
-        spflag = true;\r
-      } else if(r == 1) {\r
-        rNode = d_emptySingleton;\r
-      } else {\r
-        rNode = d_emptyRegexp;\r
-      }\r
-    } else {\r
-      std::set< unsigned > cset, cset2;\r
-      std::set< Node > vset, vset2;\r
-      getCharSet(r1, cset, vset);\r
-      getCharSet(r2, cset2, vset2);\r
-      if(vset.empty() && vset2.empty()) {\r
-        cset.clear();\r
-        firstChars(r1, cset, vset);\r
-        std::vector< Node > vec_nodes;\r
-        for(std::set<unsigned>::const_iterator itr = cset.begin();\r
-          itr != cset.end(); itr++) {\r
-          CVC4::String c( CVC4::String::convertUnsignedIntToChar(*itr) );\r
-          std::pair< Node, Node > p(r1, r2);\r
-          if(cache[ *itr ].find(p) == cache[ *itr ].end()) {\r
-            Node r1l = derivativeSingle(r1, c);\r
-            Node r2l = derivativeSingle(r2, c);\r
-            std::map< unsigned, std::set< PairNodes > > cache2(cache);\r
-            PairNodes p(r1l, r2l);\r
-            cache2[ *itr ].insert( p );\r
-            Node rt = intersectInternal(r1l, r2l, cache2, spflag);\r
-            if(spflag) {\r
-              //TODO:\r
-              return Node::null();\r
-            }\r
-            rt = Rewriter::rewrite( NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT,\r
-              NodeManager::currentNM()->mkNode(kind::STRING_TO_REGEXP, NodeManager::currentNM()->mkConst(c)), rt) );\r
-            vec_nodes.push_back(rt);\r
-          }\r
-        }\r
-        rNode = vec_nodes.size()==0 ? d_emptyRegexp : vec_nodes.size()==1 ? vec_nodes[0] :\r
-            NodeManager::currentNM()->mkNode(kind::REGEXP_UNION, vec_nodes);\r
-        rNode = Rewriter::rewrite( rNode );\r
-      } else {\r
-        //TODO: non-empty var set\r
-        spflag = true;\r
-      }\r
-    }\r
-    d_inter_cache[p] = rNode;\r
-  }\r
-  Trace("regexp-intersect") << "INTERSECT( " << mkString(r1) << ", " << mkString(r2) << " ) = " << mkString(rNode) << std::endl;\r
-  return rNode;\r
-}\r
-Node RegExpOpr::intersect(Node r1, Node r2, bool &spflag) {\r
-  std::map< unsigned, std::set< PairNodes > > cache;\r
-  if(checkConstRegExp(r1) && checkConstRegExp(r2)) {\r
-    return intersectInternal(r1, r2, cache, spflag);\r
-  } else {\r
-    spflag = true;\r
-    return Node::null();\r
-  }\r
-}\r
-\r
-Node RegExpOpr::complement(Node r, int &ret) {\r
-  Node rNode;\r
-  ret = 1;\r
-  if(d_compl_cache.find(r) != d_compl_cache.end()) {\r
-    rNode = d_compl_cache[r].first;\r
-    ret = d_compl_cache[r].second;\r
-  } else {\r
-    if(r == d_emptyRegexp) {\r
-      rNode = d_sigma_star;\r
-    } else if(r == d_emptySingleton) {\r
-      rNode = NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, d_sigma, d_sigma_star);\r
-    } else if(!checkConstRegExp(r)) {\r
-      //TODO: var to be extended\r
-      ret = 0;\r
-    } else {\r
-      std::set<unsigned> cset;\r
-      SetNodes vset;\r
-      firstChars(r, cset, vset);\r
-      std::vector< Node > vec_nodes;\r
-      for(unsigned i=0; i<d_card; i++) {\r
-        CVC4::String c = CVC4::String::convertUnsignedIntToChar(i);\r
-        Node n = NodeManager::currentNM()->mkNode(kind::STRING_TO_REGEXP, NodeManager::currentNM()->mkConst(c));\r
-        Node r2;\r
-        if(cset.find(i) == cset.end()) {\r
-          r2 = d_sigma_star;\r
-        } else {\r
-          int rt;\r
-          derivativeS(r, c, r2);\r
-          if(r2 == r) {\r
-            r2 = d_emptyRegexp;\r
-          } else {\r
-            r2 = complement(r2, rt);\r
-          }\r
-        }\r
-        n = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, n, r2));\r
-        vec_nodes.push_back(n);\r
-      }\r
-      rNode = vec_nodes.size()==0? d_emptyRegexp : vec_nodes.size()==1? vec_nodes[0] :\r
-            NodeManager::currentNM()->mkNode(kind::REGEXP_UNION, vec_nodes);\r
-    }\r
-    rNode = Rewriter::rewrite(rNode);\r
-    std::pair< Node, int > p(rNode, ret);\r
-    d_compl_cache[r] = p;\r
-  }\r
-  Trace("regexp-compl") << "COMPL( " << mkString(r) << " ) = " << mkString(rNode) << ", ret=" << ret << std::endl;\r
-  return rNode;\r
-}\r
-\r
-void RegExpOpr::splitRegExp(Node r, std::vector< PairNodes > &pset) {\r
-  Assert(checkConstRegExp(r));\r
-  if(d_split_cache.find(r) != d_split_cache.end()) {\r
-    pset = d_split_cache[r];\r
-  } else {\r
-    switch( r.getKind() ) {\r
-      case kind::REGEXP_EMPTY: {\r
-        break;\r
-      }\r
-      case kind::REGEXP_OPT: {\r
-        PairNodes tmp(d_emptySingleton, d_emptySingleton);\r
-        pset.push_back(tmp);\r
-      }\r
-      case kind::REGEXP_RANGE:\r
-      case kind::REGEXP_SIGMA: {\r
-        PairNodes tmp1(d_emptySingleton, r);\r
-        PairNodes tmp2(r, d_emptySingleton);\r
-        pset.push_back(tmp1);\r
-        pset.push_back(tmp2);\r
-        break;\r
-      }\r
-      case kind::STRING_TO_REGEXP: {\r
-        Assert(r[0].isConst());\r
-        CVC4::String s = r[0].getConst< CVC4::String >();\r
-        PairNodes tmp1(d_emptySingleton, r);\r
-        pset.push_back(tmp1);\r
-        for(unsigned i=1; i<s.size(); i++) {\r
-          CVC4::String s1 = s.substr(0, i);\r
-          CVC4::String s2 = s.substr(i);\r
-          Node n1 = NodeManager::currentNM()->mkNode(kind::STRING_TO_REGEXP, NodeManager::currentNM()->mkConst(s1));\r
-          Node n2 = NodeManager::currentNM()->mkNode(kind::STRING_TO_REGEXP, NodeManager::currentNM()->mkConst(s2));\r
-          PairNodes tmp3(n1, n2);\r
-          pset.push_back(tmp3);\r
-        }\r
-        PairNodes tmp2(r, d_emptySingleton);\r
-        pset.push_back(tmp2);\r
-        break;\r
-      }\r
-      case kind::REGEXP_CONCAT: {\r
-        for(unsigned i=0; i<r.getNumChildren(); i++) {\r
-          std::vector< PairNodes > tset;\r
-          splitRegExp(r[i], tset);\r
-          std::vector< Node > hvec;\r
-          std::vector< Node > tvec;\r
-          for(unsigned j=0; j<=i; j++) {\r
-            hvec.push_back(r[j]);\r
-          }\r
-          for(unsigned j=i; j<r.getNumChildren(); j++) {\r
-            tvec.push_back(r[j]);\r
-          }\r
-          for(unsigned j=0; j<tset.size(); j++) {\r
-            hvec[i] = tset[j].first;\r
-            tvec[0] = tset[j].second;\r
-            Node r1 = Rewriter::rewrite( hvec.size()==1?hvec[0]:NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, hvec) );\r
-            Node r2 = Rewriter::rewrite( tvec.size()==1?tvec[0]:NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, tvec) );\r
-            PairNodes tmp2(r1, r2);\r
-            pset.push_back(tmp2);\r
-          }\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_UNION: {\r
-        for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-          std::vector< PairNodes > tset;\r
-          splitRegExp(r[i], tset);\r
-          pset.insert(pset.end(), tset.begin(), tset.end());\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_INTER: {\r
-        bool spflag = false;\r
-        Node tmp = r[0];\r
-        for(unsigned i=1; i<r.getNumChildren(); i++) {\r
-          tmp = intersect(tmp, r[i], spflag);\r
-        }\r
-        splitRegExp(tmp, pset);\r
-        break;\r
-      }\r
-      case kind::REGEXP_STAR: {\r
-        std::vector< PairNodes > tset;\r
-        splitRegExp(r[0], tset);\r
-        PairNodes tmp1(d_emptySingleton, d_emptySingleton);\r
-        pset.push_back(tmp1);\r
-        for(unsigned i=0; i<tset.size(); i++) {\r
-          Node r1 = tset[i].first==d_emptySingleton ? r : NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, r, tset[i].first);\r
-          Node r2 = tset[i].second==d_emptySingleton ? r : NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, tset[i].second, r);\r
-          PairNodes tmp2(r1, r2);\r
-          pset.push_back(tmp2);\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_PLUS: {\r
-        std::vector< PairNodes > tset;\r
-        splitRegExp(r[0], tset);\r
-        for(unsigned i=0; i<tset.size(); i++) {\r
-          Node r1 = NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, r, tset[i].first);\r
-          Node r2 = NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, tset[i].second, r);\r
-          PairNodes tmp2(r1, r2);\r
-          pset.push_back(tmp2);\r
-        }\r
-        break;\r
-      }\r
-      default: {\r
-        Trace("strings-error") << "Unsupported term: " << r << " in splitRegExp." << std::endl;\r
-        Assert( false );\r
-        //return Node::null();\r
-      }\r
-    }\r
-    d_split_cache[r] = pset;\r
-  }\r
-}\r
-\r
-//printing\r
-std::string RegExpOpr::niceChar( Node r ) {\r
-  if(r.isConst()) {\r
-    std::string s = r.getConst<CVC4::String>().toString() ;\r
-    return s == "" ? "{E}" : ( s == " " ? "{ }" : s.size()>1? "("+s+")" : s );\r
-  } else {\r
-    std::string ss = "$" + r.toString();\r
-    return ss;\r
-  }\r
-}\r
-std::string RegExpOpr::mkString( Node r ) {\r
-  std::string retStr;\r
-  if(r.isNull()) {\r
-    retStr = "Empty";\r
-  } else {\r
-    int k = r.getKind();\r
-    switch( k ) {\r
-      case kind::REGEXP_EMPTY: {\r
-        retStr += "Empty";\r
-        break;\r
-      }\r
-      case kind::REGEXP_SIGMA: {\r
-        retStr += "{W}";\r
-        break;\r
-      }\r
-      case kind::STRING_TO_REGEXP: {\r
-        retStr += niceChar( r[0] );\r
-        break;\r
-      }\r
-      case kind::REGEXP_CONCAT: {\r
-        retStr += "(";\r
-        for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-          //if(i != 0) retStr += ".";\r
-          retStr += mkString( r[i] );\r
-        }\r
-        retStr += ")";\r
-        break;\r
-      }\r
-      case kind::REGEXP_UNION: {\r
-        if(r == d_sigma) {\r
-          retStr += "{A}";\r
-        } else {\r
-          retStr += "(";\r
-          for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-            if(i != 0) retStr += "|";\r
-            retStr += mkString( r[i] );\r
-          }\r
-          retStr += ")";\r
-        }\r
-        break;\r
-      }\r
-      case kind::REGEXP_INTER: {\r
-        retStr += "(";\r
-        for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
-          if(i != 0) retStr += "&";\r
-          retStr += mkString( r[i] );\r
-        }\r
-        retStr += ")";\r
-        break;\r
-      }\r
-      case kind::REGEXP_STAR: {\r
-        retStr += mkString( r[0] );\r
-        retStr += "*";\r
-        break;\r
-      }\r
-      case kind::REGEXP_PLUS: {\r
-        retStr += mkString( r[0] );\r
-        retStr += "+";\r
-        break;\r
-      }\r
-      case kind::REGEXP_OPT: {\r
-        retStr += mkString( r[0] );\r
-        retStr += "?";\r
-        break;\r
-      }\r
-      case kind::REGEXP_RANGE: {\r
-        retStr += "[";\r
-        retStr += niceChar( r[0] );\r
-        retStr += "-";\r
-        retStr += niceChar( r[1] );\r
-        retStr += "]";\r
-        break;\r
-      }\r
-      default:\r
-        Trace("strings-error") << "Unsupported term: " << r << " in RegExp." << std::endl;\r
-        //Assert( false );\r
-        //return Node::null();\r
-    }\r
-  }\r
-\r
-  return retStr;\r
-}\r
-\r
-}/* CVC4::theory::strings namespace */\r
-}/* CVC4::theory namespace */\r
-}/* CVC4 namespace */\r
+#include "theory/strings/regexp_operation.h"
+#include "expr/kind.h"
+
+namespace CVC4 {
+namespace theory {
+namespace strings {
+
+RegExpOpr::RegExpOpr() {
+  d_emptyString = NodeManager::currentNM()->mkConst( ::CVC4::String("") );
+  d_true = NodeManager::currentNM()->mkConst( true );
+  d_false = NodeManager::currentNM()->mkConst( false );
+  d_zero = NodeManager::currentNM()->mkConst( ::CVC4::Rational(0) );
+  d_one = NodeManager::currentNM()->mkConst( ::CVC4::Rational(1) );
+  d_emptySingleton = NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP, d_emptyString );
+  std::vector< Node > nvec;
+  d_emptyRegexp = NodeManager::currentNM()->mkNode( kind::REGEXP_EMPTY, nvec );
+  d_sigma = NodeManager::currentNM()->mkNode( kind::REGEXP_SIGMA, nvec );
+  d_sigma_star = NodeManager::currentNM()->mkNode( kind::REGEXP_STAR, d_sigma );
+  d_card = 256;
+}
+
+int RegExpOpr::gcd ( int a, int b ) {
+  int c;
+  while ( a != 0 ) {
+     c = a; a = b%a;  b = c;
+  }
+  return b;
+}
+
+bool RegExpOpr::checkConstRegExp( Node r ) {
+  Trace("strings-regexp-cstre") << "RegExp-CheckConstRegExp starts with " << mkString( r ) << std::endl;
+  bool ret = true;
+  if( d_cstre_cache.find( r ) != d_cstre_cache.end() ) {
+    ret = d_cstre_cache[r];
+  } else {
+    if(r.getKind() == kind::STRING_TO_REGEXP) {
+      Node tmp = Rewriter::rewrite( r[0] );
+      ret = tmp.isConst();
+    } else {
+      for(unsigned i=0; i<r.getNumChildren(); ++i) {
+        if(!checkConstRegExp(r[i])) {
+          ret = false; break;
+        }
+      }
+    }
+    d_cstre_cache[r] = ret;
+  }
+  return ret;
+}
+
+// 0-unknown, 1-yes, 2-no
+int RegExpOpr::delta( Node r, Node &exp ) {
+  Trace("regexp-delta") << "RegExp-Delta starts with " << mkString( r ) << std::endl;
+  int ret = 0;
+  if( d_delta_cache.find( r ) != d_delta_cache.end() ) {
+    ret = d_delta_cache[r].first;
+    exp = d_delta_cache[r].second;
+  } else {
+    int k = r.getKind();
+    switch( k ) {
+      case kind::REGEXP_EMPTY: {
+        ret = 2;
+        break;
+      }
+      case kind::REGEXP_SIGMA: {
+        ret = 2;
+        break;
+      }
+      case kind::STRING_TO_REGEXP: {
+        Node tmp = Rewriter::rewrite(r[0]);
+        if(tmp.isConst()) {
+          if(tmp == d_emptyString) {
+            ret = 1;
+          } else {
+            ret = 2;
+          }
+        } else {
+          ret = 0;
+          if(tmp.getKind() == kind::STRING_CONCAT) {
+            for(unsigned i=0; i<tmp.getNumChildren(); i++) {
+              if(tmp[i].isConst()) {
+                ret = 2; break;
+              }
+            }
+
+          }
+          if(ret == 0) {
+            exp = r[0].eqNode(d_emptyString);
+          }
+        }
+        break;
+      }
+      case kind::REGEXP_CONCAT: {
+        bool flag = false;
+        std::vector< Node > vec_nodes;
+        for(unsigned i=0; i<r.getNumChildren(); ++i) {
+          Node exp2;
+          int tmp = delta( r[i], exp2 );
+          if(tmp == 2) {
+            ret = 2;
+            break;
+          } else if(tmp == 0) {
+            vec_nodes.push_back( exp2 );
+            flag = true;
+          }
+        }
+        if(ret != 2) {
+          if(!flag) {
+            ret = 1;
+          } else {
+            exp = vec_nodes.size()==1 ? vec_nodes[0] : NodeManager::currentNM()->mkNode(kind::AND, vec_nodes);
+          }
+        }
+        break;
+      }
+      case kind::REGEXP_UNION: {
+        bool flag = false;
+        std::vector< Node > vec_nodes;
+        for(unsigned i=0; i<r.getNumChildren(); ++i) {
+          Node exp2;
+          int tmp = delta( r[i], exp2 );
+          if(tmp == 1) {
+            ret = 1;
+            break;
+          } else if(tmp == 0) {
+            vec_nodes.push_back( exp2 );
+            flag = true;
+          }
+        }
+        if(ret != 1) {
+          if(!flag) {
+            ret = 2;
+          } else {
+            exp = vec_nodes.size()==1 ? vec_nodes[0] : NodeManager::currentNM()->mkNode(kind::OR, vec_nodes);
+          }
+        }
+        break;
+      }
+      case kind::REGEXP_INTER: {
+        bool flag = false;
+        std::vector< Node > vec_nodes;
+        for(unsigned i=0; i<r.getNumChildren(); ++i) {
+          Node exp2;
+          int tmp = delta( r[i], exp2 );
+          if(tmp == 2) {
+            ret = 2;
+            break;
+          } else if(tmp == 0) {
+            vec_nodes.push_back( exp2 );
+            flag = true;
+          }
+        }
+        if(ret != 2) {
+          if(!flag) {
+            ret = 1;
+          } else {
+            exp = vec_nodes.size()==1 ? vec_nodes[0] : NodeManager::currentNM()->mkNode(kind::AND, vec_nodes);
+          }
+        }
+        break;
+      }
+      case kind::REGEXP_STAR: {
+        ret = 1;
+        break;
+      }
+      case kind::REGEXP_PLUS: {
+        ret = delta( r[0], exp );
+        break;
+      }
+      case kind::REGEXP_OPT: {
+        ret = 1;
+        break;
+      }
+      case kind::REGEXP_RANGE: {
+        ret = 2;
+        break;
+      }
+      default: {
+        Trace("strings-error") << "Unsupported term: " << mkString( r ) << " in delta of RegExp." << std::endl;
+        Assert( false );
+        //return Node::null();
+      }
+    }
+    if(!exp.isNull()) {
+      exp = Rewriter::rewrite(exp);
+    }
+    std::pair< int, Node > p(ret, exp);
+    d_delta_cache[r] = p;
+  }
+  Trace("regexp-delta") << "RegExp-Delta returns : " << ret << std::endl;
+  return ret;
+}
+
+// 0-unknown, 1-yes, 2-no
+int RegExpOpr::derivativeS( Node r, CVC4::String c, Node &retNode ) {
+  Assert( c.size() < 2 );
+  Trace("regexp-derive") << "RegExp-derive starts with R{ " << mkString( r ) << " }, c=" << c << std::endl;
+
+  int ret = 1;
+  retNode = d_emptyRegexp;
+
+  PairNodeStr dv = std::make_pair( r, c );
+  if( d_deriv_cache.find( dv ) != d_deriv_cache.end() ) {
+    retNode = d_deriv_cache[dv].first;
+    ret = d_deriv_cache[dv].second;
+  } else if( c.isEmptyString() ) {
+    Node expNode;
+    ret = delta( r, expNode );
+    if(ret == 0) {
+      retNode = NodeManager::currentNM()->mkNode(kind::ITE, expNode, r, d_emptyRegexp);
+    } else if(ret == 1) {
+      retNode = r;
+    }
+    std::pair< Node, int > p(retNode, ret);
+    d_deriv_cache[dv] = p;
+  } else {
+    switch( r.getKind() ) {
+      case kind::REGEXP_EMPTY: {
+        ret = 2;
+        break;
+      }
+      case kind::REGEXP_SIGMA: {
+        retNode = d_emptySingleton;
+        break;
+      }
+      case kind::STRING_TO_REGEXP: {
+        Node tmp = Rewriter::rewrite(r[0]);
+        if(tmp.isConst()) {
+          if(tmp == d_emptyString) {
+            ret = 2;
+          } else {
+            if(tmp.getConst< CVC4::String >().getFirstChar() == c.getFirstChar()) {
+              retNode =  NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP,
+                tmp.getConst< CVC4::String >().size() == 1 ? d_emptyString : NodeManager::currentNM()->mkConst( tmp.getConst< CVC4::String >().substr(1) ) );
+            } else {
+              ret = 2;
+            }
+          }
+        } else {
+          ret = 0;
+          Node rest;
+          if(tmp.getKind() == kind::STRING_CONCAT) {
+            Node t2 = tmp[0];
+            if(t2.isConst()) {
+              if(t2.getConst< CVC4::String >().getFirstChar() == c.getFirstChar()) {
+                Node n =  NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP,
+                  tmp.getConst< CVC4::String >().size() == 1 ? d_emptyString : NodeManager::currentNM()->mkConst( tmp.getConst< CVC4::String >().substr(1) ) );
+                std::vector< Node > vec_nodes;
+                vec_nodes.push_back(n);
+                for(unsigned i=1; i<tmp.getNumChildren(); i++) {
+                  vec_nodes.push_back(tmp[i]);
+                }
+                retNode = NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, vec_nodes);
+                ret = 1;
+              } else {
+                ret = 2;
+              }
+            } else {
+              tmp = tmp[0];
+              std::vector< Node > vec_nodes;
+              for(unsigned i=1; i<tmp.getNumChildren(); i++) {
+                vec_nodes.push_back(tmp[i]);
+              }
+              rest = NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, vec_nodes);
+            }
+          }
+          if(ret == 0) {
+            Node sk = NodeManager::currentNM()->mkSkolem( "rsp", NodeManager::currentNM()->stringType(), "Split RegExp" );
+            retNode = NodeManager::currentNM()->mkNode(kind::STRING_TO_REGEXP, sk);
+            if(!rest.isNull()) {
+              retNode = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, retNode, rest));
+            }
+            Node exp = tmp.eqNode(NodeManager::currentNM()->mkNode(kind::STRING_CONCAT,
+                        NodeManager::currentNM()->mkConst(c), sk));
+            retNode = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::ITE, exp, retNode, d_emptyRegexp));
+          }
+        }
+        break;
+      }
+      case kind::REGEXP_CONCAT: {
+        std::vector< Node > vec_nodes;
+        std::vector< Node > delta_nodes;
+        Node dnode = d_true;
+        for(unsigned i=0; i<r.getNumChildren(); ++i) {
+          Node dc;
+          Node exp2;
+          int rt = derivativeS(r[i], c, dc);
+          if(rt != 2) {
+            if(rt == 0) {
+              ret = 0;
+            }
+            std::vector< Node > vec_nodes2;
+            if(dc != d_emptySingleton) {
+              vec_nodes2.push_back( dc );
+            }
+            for(unsigned j=i+1; j<r.getNumChildren(); ++j) {
+              if(r[j] != d_emptySingleton) {
+                vec_nodes2.push_back( r[j] );
+              }
+            }
+            Node tmp = vec_nodes2.size()==0 ? d_emptySingleton :
+              vec_nodes2.size()==1 ? vec_nodes2[0] : NodeManager::currentNM()->mkNode( kind::REGEXP_CONCAT, vec_nodes2 );
+            if(dnode != d_true) {
+              tmp = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::ITE, dnode, tmp, d_emptyRegexp));
+              ret = 0;
+            }
+            if(std::find(vec_nodes.begin(), vec_nodes.end(), tmp) == vec_nodes.end()) {
+              vec_nodes.push_back( tmp );
+            }
+          }
+          Node exp3;
+          int rt2 = delta( r[i], exp3 );
+          if( rt2 == 0 ) {
+            dnode = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::AND, dnode, exp3));
+          } else if( rt2 == 2 ) {
+            break;
+          }
+        }
+        retNode = vec_nodes.size() == 0 ? d_emptyRegexp :
+              ( vec_nodes.size()==1 ? vec_nodes[0] : NodeManager::currentNM()->mkNode( kind::REGEXP_UNION, vec_nodes ) );
+        if(retNode == d_emptyRegexp) {
+          ret = 2;
+        }
+        break;
+      }
+      case kind::REGEXP_UNION: {
+        std::vector< Node > vec_nodes;
+        for(unsigned i=0; i<r.getNumChildren(); ++i) {
+          Node dc;
+          int rt = derivativeS(r[i], c, dc);
+          if(rt == 0) {
+            ret = 0;
+          }
+          if(rt != 2) {
+            if(std::find(vec_nodes.begin(), vec_nodes.end(), dc) == vec_nodes.end()) {
+              vec_nodes.push_back( dc );
+            }
+          }
+          Trace("regexp-derive") << "RegExp-derive OR R[" << i << "]{ " << mkString(r[i]) << " returns " << mkString(dc) << std::endl;
+        }
+        retNode = vec_nodes.size() == 0 ? d_emptyRegexp :
+              ( vec_nodes.size()==1 ? vec_nodes[0] : NodeManager::currentNM()->mkNode( kind::REGEXP_UNION, vec_nodes ) );
+        if(retNode == d_emptyRegexp) {
+          ret = 2;
+        }
+        break;
+      }
+      case kind::REGEXP_INTER: {
+        bool flag = true;
+        bool flag_sg = false;
+        std::vector< Node > vec_nodes;
+        for(unsigned i=0; i<r.getNumChildren(); ++i) {
+          Node dc;
+          int rt = derivativeS(r[i], c, dc);
+          if(rt == 0) {
+            ret = 0;
+          } else if(rt == 2) {
+            flag = false;
+            break;
+          }
+          if(dc == d_sigma_star) {
+            flag_sg = true;
+          } else {
+            if(std::find(vec_nodes.begin(), vec_nodes.end(), dc) == vec_nodes.end()) {
+              vec_nodes.push_back( dc );
+            }
+          }
+        }
+        if(flag) {
+          if(vec_nodes.size() == 0 && flag_sg) {
+            retNode = d_sigma_star;
+          } else {
+            retNode = vec_nodes.size() == 0 ? d_emptyRegexp :
+                  ( vec_nodes.size()==1 ? vec_nodes[0] : NodeManager::currentNM()->mkNode( kind::REGEXP_INTER, vec_nodes ) );
+            if(retNode == d_emptyRegexp) {
+              ret = 2;
+            }
+          }
+        } else {
+          retNode = d_emptyRegexp;
+          ret = 2;
+        }
+        break;
+      }
+      case kind::REGEXP_STAR: {
+        Node dc;
+        ret = derivativeS(r[0], c, dc);
+        retNode = dc==d_emptyRegexp ? dc : (dc==d_emptySingleton ? r : NodeManager::currentNM()->mkNode( kind::REGEXP_CONCAT, dc, r ));
+        break;
+      }
+      default: {
+        Trace("strings-error") << "Unsupported term: " << mkString( r ) << " in derivative of RegExp." << std::endl;
+        Assert( false, "Unsupported Term" );
+      }
+    }
+    if(retNode != d_emptyRegexp) {
+      retNode = Rewriter::rewrite( retNode );
+    }
+    std::pair< Node, int > p(retNode, ret);
+    d_deriv_cache[dv] = p;
+  }
+
+  Trace("regexp-derive") << "RegExp-derive returns : " << mkString( retNode ) << std::endl;
+  return ret;
+}
+
+Node RegExpOpr::derivativeSingle( Node r, CVC4::String c ) {
+  Assert( c.size() < 2 );
+  Trace("regexp-derive") << "RegExp-derive starts with R{ " << mkString( r ) << " }, c=" << c << std::endl;
+  Node retNode = d_emptyRegexp;
+  PairNodeStr dv = std::make_pair( r, c );
+  if( d_dv_cache.find( dv ) != d_dv_cache.end() ) {
+    retNode = d_dv_cache[dv];
+  } else if( c.isEmptyString() ){
+    Node exp;
+    int tmp = delta( r, exp );
+    if(tmp == 0) {
+      // TODO variable
+      retNode = d_emptyRegexp;
+    } else if(tmp == 1) {
+      retNode = r;
+    } else {
+      retNode = d_emptyRegexp;
+    }
+  } else {
+    int k = r.getKind();
+    switch( k ) {
+      case kind::REGEXP_EMPTY: {
+        retNode = d_emptyRegexp;
+        break;
+      }
+      case kind::REGEXP_SIGMA: {
+        retNode = NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP, d_emptyString );
+        break;
+      }
+      case kind::STRING_TO_REGEXP: {
+        if(r[0].isConst()) {
+          if(r[0] == d_emptyString) {
+            retNode = d_emptyRegexp;
+          } else {
+            if(r[0].getConst< CVC4::String >().getFirstChar() == c.getFirstChar()) {
+              retNode =  NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP,
+                r[0].getConst< CVC4::String >().size() == 1 ? d_emptyString : NodeManager::currentNM()->mkConst( r[0].getConst< CVC4::String >().substr(1) ) );
+            } else {
+              retNode = d_emptyRegexp;
+            }
+          }
+        } else {
+          // TODO variable
+          retNode = d_emptyRegexp;
+        }
+        break;
+      }
+      case kind::REGEXP_CONCAT: {
+        Node rees = NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP, d_emptyString );
+        std::vector< Node > vec_nodes;
+        for(unsigned i=0; i<r.getNumChildren(); ++i) {
+          Node dc = derivativeSingle(r[i], c);
+          if(dc != d_emptyRegexp) {
+            std::vector< Node > vec_nodes2;
+            if(dc != rees) {
+              vec_nodes2.push_back( dc );
+            }
+            for(unsigned j=i+1; j<r.getNumChildren(); ++j) {
+              if(r[j] != rees) {
+                vec_nodes2.push_back( r[j] );
+              }
+            }
+            Node tmp = vec_nodes2.size()==0 ? rees :
+              vec_nodes2.size()==1 ? vec_nodes2[0] : NodeManager::currentNM()->mkNode( kind::REGEXP_CONCAT, vec_nodes2 );
+            if(std::find(vec_nodes.begin(), vec_nodes.end(), tmp) == vec_nodes.end()) {
+              vec_nodes.push_back( tmp );
+            }
+          }
+          Node exp;
+          if( delta( r[i], exp ) != 1 ) {
+            break;
+          }
+        }
+        retNode = vec_nodes.size() == 0 ? d_emptyRegexp :
+              ( vec_nodes.size()==1 ? vec_nodes[0] : NodeManager::currentNM()->mkNode( kind::REGEXP_UNION, vec_nodes ) );
+        break;
+      }
+      case kind::REGEXP_UNION: {
+        std::vector< Node > vec_nodes;
+        for(unsigned i=0; i<r.getNumChildren(); ++i) {
+          Node dc = derivativeSingle(r[i], c);
+          if(dc != d_emptyRegexp) {
+            if(std::find(vec_nodes.begin(), vec_nodes.end(), dc) == vec_nodes.end()) {
+              vec_nodes.push_back( dc );
+            }
+          }
+          Trace("regexp-derive") << "RegExp-derive OR R[" << i << "]{ " << mkString(r[i]) << " returns " << mkString(dc) << std::endl;
+        }
+        retNode = vec_nodes.size() == 0 ? d_emptyRegexp :
+              ( vec_nodes.size()==1 ? vec_nodes[0] : NodeManager::currentNM()->mkNode( kind::REGEXP_UNION, vec_nodes ) );
+        break;
+      }
+      case kind::REGEXP_INTER: {
+        bool flag = true;
+        bool flag_sg = false;
+        std::vector< Node > vec_nodes;
+        for(unsigned i=0; i<r.getNumChildren(); ++i) {
+          Node dc = derivativeSingle(r[i], c);
+          if(dc != d_emptyRegexp) {
+            if(dc == d_sigma_star) {
+              flag_sg = true;
+            } else {
+              if(std::find(vec_nodes.begin(), vec_nodes.end(), dc) == vec_nodes.end()) {
+                vec_nodes.push_back( dc );
+              }
+            }
+          } else {
+            flag = false;
+            break;
+          }
+        }
+        if(flag) {
+          if(vec_nodes.size() == 0 && flag_sg) {
+            retNode = d_sigma_star;
+          } else {
+            retNode = vec_nodes.size() == 0 ? d_emptyRegexp :
+                  ( vec_nodes.size()==1 ? vec_nodes[0] : NodeManager::currentNM()->mkNode( kind::REGEXP_INTER, vec_nodes ) );
+          }
+        } else {
+          retNode = d_emptyRegexp;
+        }
+        break;
+      }
+      case kind::REGEXP_STAR: {
+        Node dc = derivativeSingle(r[0], c);
+        if(dc != d_emptyRegexp) {
+          retNode = dc==NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP, d_emptyString ) ? r : NodeManager::currentNM()->mkNode( kind::REGEXP_CONCAT, dc, r );
+        } else {
+          retNode = d_emptyRegexp;
+        }
+        break;
+      }
+      default: {
+        //TODO: special sym: sigma, none, all
+        Trace("strings-error") << "Unsupported term: " << mkString( r ) << " in derivative of RegExp." << std::endl;
+        Assert( false, "Unsupported Term" );
+        //return Node::null();
+      }
+    }
+    if(retNode != d_emptyRegexp) {
+      retNode = Rewriter::rewrite( retNode );
+    }
+    d_dv_cache[dv] = retNode;
+  }
+  Trace("regexp-derive") << "RegExp-derive returns : " << mkString( retNode ) << std::endl;
+  return retNode;
+}
+
+//TODO:
+bool RegExpOpr::guessLength( Node r, int &co ) {
+  int k = r.getKind();
+  switch( k ) {
+    case kind::STRING_TO_REGEXP:
+    {
+      if(r[0].isConst()) {
+        co += r[0].getConst< CVC4::String >().size();
+        return true;
+      } else {
+        return false;
+      }
+    }
+      break;
+    case kind::REGEXP_CONCAT:
+    {
+      for(unsigned i=0; i<r.getNumChildren(); ++i) {
+        if(!guessLength( r[i], co)) {
+          return false;
+        }
+      }
+      return true;
+    }
+      break;
+    case kind::REGEXP_UNION:
+    {
+      int g_co;
+      for(unsigned i=0; i<r.getNumChildren(); ++i) {
+        int cop = 0;
+        if(!guessLength( r[i], cop)) {
+          return false;
+        }
+        if(i == 0) {
+          g_co = cop;
+        } else {
+          g_co = gcd(g_co, cop);
+        }
+      }
+      return true;
+    }
+      break;
+    case kind::REGEXP_INTER:
+    {
+      int g_co;
+      for(unsigned i=0; i<r.getNumChildren(); ++i) {
+        int cop = 0;
+        if(!guessLength( r[i], cop)) {
+          return false;
+        }
+        if(i == 0) {
+          g_co = cop;
+        } else {
+          g_co = gcd(g_co, cop);
+        }
+      }
+      return true;
+    }
+      break;
+    case kind::REGEXP_STAR:
+    {
+      co = 0;
+      return true;
+    }
+      break;
+    default:
+      Trace("strings-error") << "Unsupported term: " << mkString( r ) << " in membership of RegExp." << std::endl;
+      return false;
+  }
+}
+
+void RegExpOpr::firstChars( Node r, std::set<unsigned> &pcset, SetNodes &pvset ) {
+  std::map< Node, std::pair< std::set<unsigned>, SetNodes > >::const_iterator itr = d_fset_cache.find(r);
+  if(itr != d_fset_cache.end()) {
+    pcset.insert((itr->second).first.begin(), (itr->second).first.end());
+    pvset.insert((itr->second).second.begin(), (itr->second).second.end());
+  } else {
+    std::set<unsigned> cset;
+    SetNodes vset;
+    int k = r.getKind();
+    switch( k ) {
+      case kind::REGEXP_EMPTY: {
+        break;
+      }
+      case kind::REGEXP_SIGMA: {
+        for(unsigned i=0; i<d_card; i++) {
+          cset.insert(i);
+        }
+        break;
+      }
+      case kind::STRING_TO_REGEXP: {
+        Node st = Rewriter::rewrite(r[0]);
+        if(st.isConst()) {
+          CVC4::String s = st.getConst< CVC4::String >();
+          if(s.size() != 0) {
+            cset.insert(s[0]);
+          }
+        } else if(st.getKind() == kind::VARIABLE) {
+          vset.insert( st );
+        } else {
+          if(st[0].isConst()) {
+            CVC4::String s = st[0].getConst< CVC4::String >();
+            cset.insert(s[0]);
+          } else {
+            vset.insert( st[0] );
+          }
+        }
+        break;
+      }
+      case kind::REGEXP_CONCAT: {
+        for(unsigned i=0; i<r.getNumChildren(); i++) {
+          firstChars(r[i], cset, vset);
+          Node n = r[i];
+          Node exp;
+          int r = delta( n, exp );
+          if(r != 1) {
+            break;
+          }
+        }
+        break;
+      }
+      case kind::REGEXP_UNION: {
+        for(unsigned i=0; i<r.getNumChildren(); i++) {
+          firstChars(r[i], cset, vset);
+        }
+        break;
+      }
+      case kind::REGEXP_INTER: {
+        //TODO: Overapproximation for now
+        for(unsigned i=0; i<r.getNumChildren(); i++) {
+          firstChars(r[i], cset, vset);
+        }
+        break;
+      }
+      case kind::REGEXP_STAR: {
+        firstChars(r[0], cset, vset);
+        break;
+      }
+      default: {
+        Trace("strings-regexp") << "Unsupported term: " << r << " in getCharSet." << std::endl;
+        Assert( false, "Unsupported Term" );
+      }
+    }
+    pcset.insert(cset.begin(), cset.end());
+    pvset.insert(vset.begin(), vset.end());
+    std::pair< std::set<unsigned>, SetNodes > p(cset, vset);
+    d_fset_cache[r] = p;
+
+    Trace("regexp-fset") << "FSET( " << mkString(r) << " ) = { ";
+    for(std::set<unsigned>::const_iterator itr = cset.begin();
+      itr != cset.end(); itr++) {
+        Trace("regexp-fset") << CVC4::String::convertUnsignedIntToChar(*itr) << ",";
+      }
+    Trace("regexp-fset") << " }" << std::endl;
+  }
+}
+
+bool RegExpOpr::follow( Node r, CVC4::String c, std::vector< char > &vec_chars ) {
+  int k = r.getKind();
+  switch( k ) {
+    case kind::STRING_TO_REGEXP:
+    {
+      if(r[0].isConst()) {
+        if(r[0] != d_emptyString) {
+          char t1 = r[0].getConst< CVC4::String >().getFirstChar();
+          if(c.isEmptyString()) {
+            vec_chars.push_back( t1 );
+            return true;
+          } else {
+            char t2 = c.getFirstChar();
+            if(t1 != t2) {
+              return false;
+            } else {
+              if(c.size() >= 2) {
+                vec_chars.push_back( c.substr(1,1).getFirstChar() );
+              } else {
+                vec_chars.push_back( '\0' );
+              }
+              return true;
+            }
+          }
+        } else {
+          return false;
+        }
+      } else {
+        return false;
+      }
+    }
+      break;
+    case kind::REGEXP_CONCAT:
+    {
+      for(unsigned i=0; i<r.getNumChildren(); ++i) {
+        if( follow(r[i], c, vec_chars) ) {
+          if(vec_chars[vec_chars.size() - 1] == '\0') {
+            vec_chars.pop_back();
+            c = d_emptyString.getConst< CVC4::String >();
+          }
+        } else {
+          return false;
+        }
+      }
+      vec_chars.push_back( '\0' );
+      return true;
+    }
+      break;
+    case kind::REGEXP_UNION:
+    {
+      bool flag = false;
+      for(unsigned i=0; i<r.getNumChildren(); ++i) {
+        if( follow(r[i], c, vec_chars) ) {
+          flag=true;
+        }
+      }
+      return flag;
+    }
+      break;
+    case kind::REGEXP_INTER:
+    {
+      std::vector< char > vt2;
+      for(unsigned i=0; i<r.getNumChildren(); ++i) {
+        std::vector< char > v_tmp;
+        if( !follow(r[i], c, v_tmp) ) {
+          return false;
+        }
+        std::vector< char > vt3(vt2);
+        vt2.clear();
+        std::set_intersection( vt3.begin(), vt3.end(), v_tmp.begin(), v_tmp.end(), vt2.begin() );
+        if(vt2.size() == 0) {
+          return false;
+        }
+      }
+      vec_chars.insert( vec_chars.end(), vt2.begin(), vt2.end() );
+      return true;
+    }
+      break;
+    case kind::REGEXP_STAR:
+    {
+      if(follow(r[0], c, vec_chars)) {
+        if(vec_chars[vec_chars.size() - 1] == '\0') {
+          if(c.isEmptyString()) {
+            return true;
+          } else {
+            vec_chars.pop_back();
+            c = d_emptyString.getConst< CVC4::String >();
+            return follow(r[0], c, vec_chars);
+          }
+        } else {
+          return true;
+        }
+      } else {
+        vec_chars.push_back( '\0' );
+        return true;
+      }
+    }
+      break;
+    default: {
+      Trace("strings-error") << "Unsupported term: " << mkString( r ) << " in delta of RegExp." << std::endl;
+      //AlwaysAssert( false );
+      //return Node::null();
+      return false;
+    }
+  }
+}
+
+Node RegExpOpr::mkAllExceptOne( char exp_c ) {
+  std::vector< Node > vec_nodes;
+  for(char c=d_char_start; c<=d_char_end; ++c) {
+    if(c != exp_c ) {
+      Node n = NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP, NodeManager::currentNM()->mkConst( ::CVC4::String( c ) ) );
+      vec_nodes.push_back( n );
+    }
+  }
+  return NodeManager::currentNM()->mkNode( kind::REGEXP_UNION, vec_nodes );
+}
+
+//simplify
+void RegExpOpr::simplify(Node t, std::vector< Node > &new_nodes, bool polarity) {
+  Trace("strings-regexp-simpl") << "RegExp-Simpl starts with " << t << ", polarity=" << polarity << std::endl;
+  Assert(t.getKind() == kind::STRING_IN_REGEXP);
+  Node str = Rewriter::rewrite(t[0]);
+  Node re  = Rewriter::rewrite(t[1]);
+  if(polarity) {
+    simplifyPRegExp( str, re, new_nodes );
+  } else {
+    simplifyNRegExp( str, re, new_nodes );
+  }
+  Trace("strings-regexp-simpl") << "RegExp-Simpl  returns (" << new_nodes.size() << "):\n";
+  for(unsigned i=0; i<new_nodes.size(); i++) {
+    Trace("strings-regexp-simpl") << "\t" << new_nodes[i] << std::endl;
+  }
+}
+void RegExpOpr::simplifyNRegExp( Node s, Node r, std::vector< Node > &new_nodes ) {
+  std::pair < Node, Node > p(s, r);
+  std::map < std::pair< Node, Node >, Node >::const_iterator itr = d_simpl_neg_cache.find(p);
+  if(itr != d_simpl_neg_cache.end()) {
+    new_nodes.push_back( itr->second );
+  } else {
+    int k = r.getKind();
+    Node conc;
+    switch( k ) {
+      case kind::REGEXP_EMPTY: {
+        conc = d_true;
+        break;
+      }
+      case kind::REGEXP_SIGMA: {
+        conc = d_one.eqNode(NodeManager::currentNM()->mkNode(kind::STRING_LENGTH, s)).negate();
+        break;
+      }
+      case kind::STRING_TO_REGEXP: {
+        conc = s.eqNode(r[0]).negate();
+        break;
+      }
+      case kind::REGEXP_CONCAT: {
+        //TODO: rewrite empty
+        Node lens = NodeManager::currentNM()->mkNode(kind::STRING_LENGTH, s);
+        Node b1 = NodeManager::currentNM()->mkBoundVar(NodeManager::currentNM()->integerType());
+        Node b1v = NodeManager::currentNM()->mkNode(kind::BOUND_VAR_LIST, b1);
+        Node g1 = NodeManager::currentNM()->mkNode( kind::AND, NodeManager::currentNM()->mkNode(kind::GEQ, b1, d_zero),
+              NodeManager::currentNM()->mkNode( kind::GEQ, NodeManager::currentNM()->mkNode(kind::STRING_LENGTH, s), b1 ) );
+        Node s1 = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::STRING_SUBSTR_TOTAL, s, d_zero, b1));
+        Node s2 = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::STRING_SUBSTR_TOTAL, s, b1, NodeManager::currentNM()->mkNode(kind::MINUS, lens, b1)));
+        Node s1r1 = NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, s1, r[0]).negate();
+        if(r[0].getKind() == kind::STRING_TO_REGEXP) {
+          s1r1 = s1.eqNode(r[0][0]).negate();
+        } else if(r[0].getKind() == kind::REGEXP_EMPTY) {
+          s1r1 = d_true;
+        }
+        Node r2 = r[1];
+        if(r.getNumChildren() > 2) {
+          std::vector< Node > nvec;
+          for(unsigned i=1; i<r.getNumChildren(); i++) {
+            nvec.push_back( r[i] );
+          }
+          r2 = NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, nvec);
+        }
+        r2 = Rewriter::rewrite(r2);
+        Node s2r2 = NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, s2, r2).negate();
+        if(r2.getKind() == kind::STRING_TO_REGEXP) {
+          s2r2 = s2.eqNode(r2[0]).negate();
+        } else if(r2.getKind() == kind::REGEXP_EMPTY) {
+          s2r2 = d_true;
+        }
+
+        conc = NodeManager::currentNM()->mkNode(kind::OR, s1r1, s2r2);
+        conc = NodeManager::currentNM()->mkNode(kind::IMPLIES, g1, conc);
+        conc = NodeManager::currentNM()->mkNode(kind::FORALL, b1v, conc);
+        break;
+      }
+      case kind::REGEXP_UNION: {
+        std::vector< Node > c_and;
+        for(unsigned i=0; i<r.getNumChildren(); ++i) {
+          if(r[i].getKind() == kind::STRING_TO_REGEXP) {
+            c_and.push_back( r[i][0].eqNode(s).negate() );
+          } else if(r[i].getKind() == kind::REGEXP_EMPTY) {
+            continue;
+          } else {
+            c_and.push_back(NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, s, r[i]).negate());
+          }
+        }
+        conc = c_and.size() == 0 ? d_true :
+            c_and.size() == 1 ? c_and[0] : NodeManager::currentNM()->mkNode(kind::AND, c_and);
+        break;
+      }
+      case kind::REGEXP_INTER: {
+        bool emptyflag = false;
+        std::vector< Node > c_or;
+        for(unsigned i=0; i<r.getNumChildren(); ++i) {
+          if(r[i].getKind() == kind::STRING_TO_REGEXP) {
+            c_or.push_back( r[i][0].eqNode(s).negate() );
+          } else if(r[i].getKind() == kind::REGEXP_EMPTY) {
+            emptyflag = true;
+            break;
+          } else {
+            c_or.push_back(NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, s, r[i]).negate());
+          }
+        }
+        if(emptyflag) {
+          conc = d_true;
+        } else {
+          conc = c_or.size() == 1 ? c_or[0] : NodeManager::currentNM()->mkNode(kind::OR, c_or);
+        }
+        break;
+      }
+      case kind::REGEXP_STAR: {
+        if(s == d_emptyString) {
+          conc = d_false;
+        } else if(r[0].getKind() == kind::REGEXP_EMPTY) {
+          conc = s.eqNode(d_emptyString).negate();
+        } else if(r[0].getKind() == kind::REGEXP_SIGMA) {
+          conc = d_false;
+        } else {
+          Node lens = NodeManager::currentNM()->mkNode(kind::STRING_LENGTH, s);
+          Node sne = s.eqNode(d_emptyString).negate();
+          Node b1 = NodeManager::currentNM()->mkBoundVar(NodeManager::currentNM()->integerType());
+          Node b1v = NodeManager::currentNM()->mkNode(kind::BOUND_VAR_LIST, b1);
+          Node g1 = NodeManager::currentNM()->mkNode( kind::AND, NodeManager::currentNM()->mkNode(kind::GEQ, b1, d_one),
+                NodeManager::currentNM()->mkNode( kind::GEQ, lens, b1 ) );
+          //internal
+          Node s1 = NodeManager::currentNM()->mkNode(kind::STRING_SUBSTR_TOTAL, s, d_zero, b1);
+          Node s2 = NodeManager::currentNM()->mkNode(kind::STRING_SUBSTR_TOTAL, s, b1, NodeManager::currentNM()->mkNode(kind::MINUS, lens, b1));
+          Node s1r1 = NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, s1, r[0]).negate();
+          Node s2r2 = NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, s2, r).negate();
+
+          conc = NodeManager::currentNM()->mkNode(kind::OR, s1r1, s2r2);
+          conc = NodeManager::currentNM()->mkNode(kind::IMPLIES, g1, conc);
+          conc = NodeManager::currentNM()->mkNode(kind::FORALL, b1v, conc);
+          conc = NodeManager::currentNM()->mkNode(kind::AND, sne, conc);
+        }
+        break;
+      }
+      default: {
+        Trace("strings-regexp") << "Unsupported term: " << r << " in simplifyNRegExp." << std::endl;
+        Assert( false, "Unsupported Term" );
+      }
+    }
+    conc = Rewriter::rewrite( conc );
+    new_nodes.push_back( conc );
+    d_simpl_neg_cache[p] = conc;
+  }
+}
+void RegExpOpr::simplifyPRegExp( Node s, Node r, std::vector< Node > &new_nodes ) {
+  std::pair < Node, Node > p(s, r);
+  std::map < std::pair< Node, Node >, Node >::const_iterator itr = d_simpl_cache.find(p);
+  if(itr != d_simpl_cache.end()) {
+    new_nodes.push_back( itr->second );
+  } else {
+    int k = r.getKind();
+    Node conc;
+    switch( k ) {
+      case kind::REGEXP_EMPTY: {
+        conc = d_false;
+        break;
+      }
+      case kind::REGEXP_SIGMA: {
+        conc = d_one.eqNode(NodeManager::currentNM()->mkNode(kind::STRING_LENGTH, s));
+        break;
+      }
+      case kind::STRING_TO_REGEXP: {
+        conc = s.eqNode(r[0]);
+        break;
+      }
+      case kind::REGEXP_CONCAT: {
+        std::vector< Node > nvec;
+        std::vector< Node > cc;
+        bool emptyflag = false;
+        for(unsigned i=0; i<r.getNumChildren(); ++i) {
+          if(r[i].getKind() == kind::STRING_TO_REGEXP) {
+            cc.push_back( r[i][0] );
+          } else if(r[i].getKind() == kind::REGEXP_EMPTY) {
+            emptyflag = true;
+            break;
+          } else {
+            Node sk = NodeManager::currentNM()->mkSkolem( "rc", s.getType(), "created for regular expression concat" );
+            Node lem = NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, sk, r[i]);
+            nvec.push_back(lem);
+            cc.push_back(sk);
+          }
+        }
+        if(emptyflag) {
+          conc = d_false;
+        } else {
+          Node lem = s.eqNode( NodeManager::currentNM()->mkNode(kind::STRING_CONCAT, cc) );
+          nvec.push_back(lem);
+          conc = nvec.size() == 1 ? nvec[0] : NodeManager::currentNM()->mkNode(kind::AND, nvec);
+        }
+        break;
+      }
+      case kind::REGEXP_UNION: {
+        std::vector< Node > c_or;
+        for(unsigned i=0; i<r.getNumChildren(); ++i) {
+          if(r[i].getKind() == kind::STRING_TO_REGEXP) {
+            c_or.push_back( r[i][0].eqNode(s) );
+          } else if(r[i].getKind() == kind::REGEXP_EMPTY) {
+            continue;
+          } else {
+            c_or.push_back(NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, s, r[i]));
+          }
+        }
+        conc = c_or.size() == 0 ? d_false :
+            c_or.size() == 1 ? c_or[0] : NodeManager::currentNM()->mkNode(kind::OR, c_or);
+        break;
+      }
+      case kind::REGEXP_INTER: {
+        std::vector< Node > c_and;
+        bool emptyflag = false;
+        for(unsigned i=0; i<r.getNumChildren(); ++i) {
+          if(r[i].getKind() == kind::STRING_TO_REGEXP) {
+            c_and.push_back( r[i][0].eqNode(s) );
+          } else if(r[i].getKind() == kind::REGEXP_EMPTY) {
+            emptyflag = true;
+            break;
+          } else {
+            c_and.push_back(NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, s, r[i]));
+          }
+        }
+        if(emptyflag) {
+          conc = d_false;
+        } else {
+          conc = c_and.size() == 1 ? c_and[0] : NodeManager::currentNM()->mkNode(kind::AND, c_and);
+        }
+        break;
+      }
+      case kind::REGEXP_STAR: {
+        if(s == d_emptyString) {
+          conc = d_true;
+        } else if(r[0].getKind() == kind::REGEXP_EMPTY) {
+          conc = s.eqNode(d_emptyString);
+        } else if(r[0].getKind() == kind::REGEXP_SIGMA) {
+          conc = d_true;
+        } else {
+          Node se = s.eqNode(d_emptyString);
+          Node sinr = NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, s, r[0]);
+          Node sk1 = NodeManager::currentNM()->mkSkolem( "rs", s.getType(), "created for regular expression star" );
+          Node sk2 = NodeManager::currentNM()->mkSkolem( "rs", s.getType(), "created for regular expression star" );
+          Node s1nz = sk1.eqNode(d_emptyString).negate();
+          Node s2nz = sk2.eqNode(d_emptyString).negate();
+          Node s1inr = NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, sk1, r[0]);
+          Node s2inrs = NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, sk2, r);
+          Node s12 = s.eqNode(NodeManager::currentNM()->mkNode(kind::STRING_CONCAT, sk1, sk2));
+
+          conc = NodeManager::currentNM()->mkNode(kind::AND, s12, s1nz, s2nz, s1inr, s2inrs);
+          conc = NodeManager::currentNM()->mkNode(kind::OR, se, sinr, conc);
+        }
+        break;
+      }
+      default: {
+        Trace("strings-regexp") << "Unsupported term: " << r << " in simplifyPRegExp." << std::endl;
+        Assert( false, "Unsupported Term" );
+      }
+    }
+    conc = Rewriter::rewrite( conc );
+    new_nodes.push_back( conc );
+    d_simpl_cache[p] = conc;
+  }
+}
+
+void RegExpOpr::getCharSet( Node r, std::set<unsigned> &pcset, SetNodes &pvset ) {
+  std::map< Node, std::pair< std::set<unsigned>, SetNodes > >::const_iterator itr = d_cset_cache.find(r);
+  if(itr != d_cset_cache.end()) {
+    pcset.insert((itr->second).first.begin(), (itr->second).first.end());
+    pvset.insert((itr->second).second.begin(), (itr->second).second.end());
+  } else {
+    std::set<unsigned> cset;
+    SetNodes vset;
+    int k = r.getKind();
+    switch( k ) {
+      case kind::REGEXP_EMPTY: {
+        break;
+      }
+      case kind::REGEXP_SIGMA: {
+        for(unsigned i=0; i<d_card; i++) {
+          cset.insert(i);
+        }
+        break;
+      }
+      case kind::STRING_TO_REGEXP: {
+        Node st = Rewriter::rewrite(r[0]);
+        if(st.isConst()) {
+          CVC4::String s = st.getConst< CVC4::String >();
+          s.getCharSet( cset );
+        } else if(st.getKind() == kind::VARIABLE) {
+          vset.insert( st );
+        } else {
+          for(unsigned i=0; i<st.getNumChildren(); i++) {
+            if(st[i].isConst()) {
+              CVC4::String s = st[i].getConst< CVC4::String >();
+              s.getCharSet( cset );
+            } else {
+              vset.insert( st[i] );
+            }
+          }
+        }
+        break;
+      }
+      case kind::REGEXP_CONCAT: {
+        for(unsigned i=0; i<r.getNumChildren(); i++) {
+          getCharSet(r[i], cset, vset);
+        }
+        break;
+      }
+      case kind::REGEXP_UNION: {
+        for(unsigned i=0; i<r.getNumChildren(); i++) {
+          getCharSet(r[i], cset, vset);
+        }
+        break;
+      }
+      case kind::REGEXP_INTER: {
+        //TODO: Overapproximation for now
+        for(unsigned i=0; i<r.getNumChildren(); i++) {
+          getCharSet(r[i], cset, vset);
+        }
+        break;
+      }
+      case kind::REGEXP_STAR: {
+        getCharSet(r[0], cset, vset);
+        break;
+      }
+      default: {
+        Trace("strings-regexp") << "Unsupported term: " << r << " in getCharSet." << std::endl;
+        Assert( false, "Unsupported Term" );
+      }
+    }
+    pcset.insert(cset.begin(), cset.end());
+    pvset.insert(vset.begin(), vset.end());
+    std::pair< std::set<unsigned>, SetNodes > p(cset, vset);
+    d_cset_cache[r] = p;
+
+    Trace("regexp-cset") << "CSET( " << mkString(r) << " ) = { ";
+    for(std::set<unsigned>::const_iterator itr = cset.begin();
+      itr != cset.end(); itr++) {
+        Trace("regexp-cset") << CVC4::String::convertUnsignedIntToChar(*itr) << ",";
+      }
+    Trace("regexp-cset") << " }" << std::endl;
+  }
+}
+
+
+Node RegExpOpr::intersectInternal( Node r1, Node r2, std::map< unsigned, std::set< PairNodes > > cache, bool &spflag ) {
+  if(spflag) {
+    //TODO: var
+    return Node::null();
+  }
+  std::pair < Node, Node > p(r1, r2);
+  std::map < std::pair< Node, Node >, Node >::const_iterator itr = d_inter_cache.find(p);
+  Node rNode;
+  if(itr != d_inter_cache.end()) {
+    rNode = itr->second;
+  } else {
+    if(r1 == r2) {
+      rNode = r1;
+    } else if(r1 == d_emptyRegexp || r2 == d_emptyRegexp) {
+      rNode = d_emptyRegexp;
+    } else if(r1 == d_emptySingleton || r2 == d_emptySingleton) {
+      Node exp;
+      int r = delta((r1 == d_emptySingleton ? r2 : r1), exp);
+      if(r == 0) {
+        //TODO: variable
+        spflag = true;
+      } else if(r == 1) {
+        rNode = d_emptySingleton;
+      } else {
+        rNode = d_emptyRegexp;
+      }
+    } else {
+      std::set< unsigned > cset, cset2;
+      std::set< Node > vset, vset2;
+      getCharSet(r1, cset, vset);
+      getCharSet(r2, cset2, vset2);
+      if(vset.empty() && vset2.empty()) {
+        cset.clear();
+        firstChars(r1, cset, vset);
+        std::vector< Node > vec_nodes;
+        for(std::set<unsigned>::const_iterator itr = cset.begin();
+          itr != cset.end(); itr++) {
+          CVC4::String c( CVC4::String::convertUnsignedIntToChar(*itr) );
+          std::pair< Node, Node > p(r1, r2);
+          if(cache[ *itr ].find(p) == cache[ *itr ].end()) {
+            Node r1l = derivativeSingle(r1, c);
+            Node r2l = derivativeSingle(r2, c);
+            std::map< unsigned, std::set< PairNodes > > cache2(cache);
+            PairNodes p(r1l, r2l);
+            cache2[ *itr ].insert( p );
+            Node rt = intersectInternal(r1l, r2l, cache2, spflag);
+            if(spflag) {
+              //TODO:
+              return Node::null();
+            }
+            rt = Rewriter::rewrite( NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT,
+              NodeManager::currentNM()->mkNode(kind::STRING_TO_REGEXP, NodeManager::currentNM()->mkConst(c)), rt) );
+            vec_nodes.push_back(rt);
+          }
+        }
+        rNode = vec_nodes.size()==0 ? d_emptyRegexp : vec_nodes.size()==1 ? vec_nodes[0] :
+            NodeManager::currentNM()->mkNode(kind::REGEXP_UNION, vec_nodes);
+        rNode = Rewriter::rewrite( rNode );
+      } else {
+        //TODO: non-empty var set
+        spflag = true;
+      }
+    }
+    d_inter_cache[p] = rNode;
+  }
+  Trace("regexp-intersect") << "INTERSECT( " << mkString(r1) << ", " << mkString(r2) << " ) = " << mkString(rNode) << std::endl;
+  return rNode;
+}
+Node RegExpOpr::intersect(Node r1, Node r2, bool &spflag) {
+  std::map< unsigned, std::set< PairNodes > > cache;
+  if(checkConstRegExp(r1) && checkConstRegExp(r2)) {
+    return intersectInternal(r1, r2, cache, spflag);
+  } else {
+    spflag = true;
+    return Node::null();
+  }
+}
+
+Node RegExpOpr::complement(Node r, int &ret) {
+  Node rNode;
+  ret = 1;
+  if(d_compl_cache.find(r) != d_compl_cache.end()) {
+    rNode = d_compl_cache[r].first;
+    ret = d_compl_cache[r].second;
+  } else {
+    if(r == d_emptyRegexp) {
+      rNode = d_sigma_star;
+    } else if(r == d_emptySingleton) {
+      rNode = NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, d_sigma, d_sigma_star);
+    } else if(!checkConstRegExp(r)) {
+      //TODO: var to be extended
+      ret = 0;
+    } else {
+      std::set<unsigned> cset;
+      SetNodes vset;
+      firstChars(r, cset, vset);
+      std::vector< Node > vec_nodes;
+      for(unsigned i=0; i<d_card; i++) {
+        CVC4::String c = CVC4::String::convertUnsignedIntToChar(i);
+        Node n = NodeManager::currentNM()->mkNode(kind::STRING_TO_REGEXP, NodeManager::currentNM()->mkConst(c));
+        Node r2;
+        if(cset.find(i) == cset.end()) {
+          r2 = d_sigma_star;
+        } else {
+          int rt;
+          derivativeS(r, c, r2);
+          if(r2 == r) {
+            r2 = d_emptyRegexp;
+          } else {
+            r2 = complement(r2, rt);
+          }
+        }
+        n = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, n, r2));
+        vec_nodes.push_back(n);
+      }
+      rNode = vec_nodes.size()==0? d_emptyRegexp : vec_nodes.size()==1? vec_nodes[0] :
+            NodeManager::currentNM()->mkNode(kind::REGEXP_UNION, vec_nodes);
+    }
+    rNode = Rewriter::rewrite(rNode);
+    std::pair< Node, int > p(rNode, ret);
+    d_compl_cache[r] = p;
+  }
+  Trace("regexp-compl") << "COMPL( " << mkString(r) << " ) = " << mkString(rNode) << ", ret=" << ret << std::endl;
+  return rNode;
+}
+
+void RegExpOpr::splitRegExp(Node r, std::vector< PairNodes > &pset) {
+  Assert(checkConstRegExp(r));
+  if(d_split_cache.find(r) != d_split_cache.end()) {
+    pset = d_split_cache[r];
+  } else {
+    switch( r.getKind() ) {
+      case kind::REGEXP_EMPTY: {
+        break;
+      }
+      case kind::REGEXP_OPT: {
+        PairNodes tmp(d_emptySingleton, d_emptySingleton);
+        pset.push_back(tmp);
+      }
+      case kind::REGEXP_RANGE:
+      case kind::REGEXP_SIGMA: {
+        PairNodes tmp1(d_emptySingleton, r);
+        PairNodes tmp2(r, d_emptySingleton);
+        pset.push_back(tmp1);
+        pset.push_back(tmp2);
+        break;
+      }
+      case kind::STRING_TO_REGEXP: {
+        Assert(r[0].isConst());
+        CVC4::String s = r[0].getConst< CVC4::String >();
+        PairNodes tmp1(d_emptySingleton, r);
+        pset.push_back(tmp1);
+        for(unsigned i=1; i<s.size(); i++) {
+          CVC4::String s1 = s.substr(0, i);
+          CVC4::String s2 = s.substr(i);
+          Node n1 = NodeManager::currentNM()->mkNode(kind::STRING_TO_REGEXP, NodeManager::currentNM()->mkConst(s1));
+          Node n2 = NodeManager::currentNM()->mkNode(kind::STRING_TO_REGEXP, NodeManager::currentNM()->mkConst(s2));
+          PairNodes tmp3(n1, n2);
+          pset.push_back(tmp3);
+        }
+        PairNodes tmp2(r, d_emptySingleton);
+        pset.push_back(tmp2);
+        break;
+      }
+      case kind::REGEXP_CONCAT: {
+        for(unsigned i=0; i<r.getNumChildren(); i++) {
+          std::vector< PairNodes > tset;
+          splitRegExp(r[i], tset);
+          std::vector< Node > hvec;
+          std::vector< Node > tvec;
+          for(unsigned j=0; j<=i; j++) {
+            hvec.push_back(r[j]);
+          }
+          for(unsigned j=i; j<r.getNumChildren(); j++) {
+            tvec.push_back(r[j]);
+          }
+          for(unsigned j=0; j<tset.size(); j++) {
+            hvec[i] = tset[j].first;
+            tvec[0] = tset[j].second;
+            Node r1 = Rewriter::rewrite( hvec.size()==1?hvec[0]:NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, hvec) );
+            Node r2 = Rewriter::rewrite( tvec.size()==1?tvec[0]:NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, tvec) );
+            PairNodes tmp2(r1, r2);
+            pset.push_back(tmp2);
+          }
+        }
+        break;
+      }
+      case kind::REGEXP_UNION: {
+        for(unsigned i=0; i<r.getNumChildren(); ++i) {
+          std::vector< PairNodes > tset;
+          splitRegExp(r[i], tset);
+          pset.insert(pset.end(), tset.begin(), tset.end());
+        }
+        break;
+      }
+      case kind::REGEXP_INTER: {
+        bool spflag = false;
+        Node tmp = r[0];
+        for(unsigned i=1; i<r.getNumChildren(); i++) {
+          tmp = intersect(tmp, r[i], spflag);
+        }
+        splitRegExp(tmp, pset);
+        break;
+      }
+      case kind::REGEXP_STAR: {
+        std::vector< PairNodes > tset;
+        splitRegExp(r[0], tset);
+        PairNodes tmp1(d_emptySingleton, d_emptySingleton);
+        pset.push_back(tmp1);
+        for(unsigned i=0; i<tset.size(); i++) {
+          Node r1 = tset[i].first==d_emptySingleton ? r : NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, r, tset[i].first);
+          Node r2 = tset[i].second==d_emptySingleton ? r : NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, tset[i].second, r);
+          PairNodes tmp2(r1, r2);
+          pset.push_back(tmp2);
+        }
+        break;
+      }
+      case kind::REGEXP_PLUS: {
+        std::vector< PairNodes > tset;
+        splitRegExp(r[0], tset);
+        for(unsigned i=0; i<tset.size(); i++) {
+          Node r1 = NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, r, tset[i].first);
+          Node r2 = NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT, tset[i].second, r);
+          PairNodes tmp2(r1, r2);
+          pset.push_back(tmp2);
+        }
+        break;
+      }
+      default: {
+        Trace("strings-error") << "Unsupported term: " << r << " in splitRegExp." << std::endl;
+        Assert( false );
+        //return Node::null();
+      }
+    }
+    d_split_cache[r] = pset;
+  }
+}
+
+//printing
+std::string RegExpOpr::niceChar( Node r ) {
+  if(r.isConst()) {
+    std::string s = r.getConst<CVC4::String>().toString() ;
+    return s == "" ? "{E}" : ( s == " " ? "{ }" : s.size()>1? "("+s+")" : s );
+  } else {
+    std::string ss = "$" + r.toString();
+    return ss;
+  }
+}
+std::string RegExpOpr::mkString( Node r ) {
+  std::string retStr;
+  if(r.isNull()) {
+    retStr = "Empty";
+  } else {
+    int k = r.getKind();
+    switch( k ) {
+      case kind::REGEXP_EMPTY: {
+        retStr += "Empty";
+        break;
+      }
+      case kind::REGEXP_SIGMA: {
+        retStr += "{W}";
+        break;
+      }
+      case kind::STRING_TO_REGEXP: {
+        retStr += niceChar( r[0] );
+        break;
+      }
+      case kind::REGEXP_CONCAT: {
+        retStr += "(";
+        for(unsigned i=0; i<r.getNumChildren(); ++i) {
+          //if(i != 0) retStr += ".";
+          retStr += mkString( r[i] );
+        }
+        retStr += ")";
+        break;
+      }
+      case kind::REGEXP_UNION: {
+        if(r == d_sigma) {
+          retStr += "{A}";
+        } else {
+          retStr += "(";
+          for(unsigned i=0; i<r.getNumChildren(); ++i) {
+            if(i != 0) retStr += "|";
+            retStr += mkString( r[i] );
+          }
+          retStr += ")";
+        }
+        break;
+      }
+      case kind::REGEXP_INTER: {
+        retStr += "(";
+        for(unsigned i=0; i<r.getNumChildren(); ++i) {
+          if(i != 0) retStr += "&";
+          retStr += mkString( r[i] );
+        }
+        retStr += ")";
+        break;
+      }
+      case kind::REGEXP_STAR: {
+        retStr += mkString( r[0] );
+        retStr += "*";
+        break;
+      }
+      case kind::REGEXP_PLUS: {
+        retStr += mkString( r[0] );
+        retStr += "+";
+        break;
+      }
+      case kind::REGEXP_OPT: {
+        retStr += mkString( r[0] );
+        retStr += "?";
+        break;
+      }
+      case kind::REGEXP_RANGE: {
+        retStr += "[";
+        retStr += niceChar( r[0] );
+        retStr += "-";
+        retStr += niceChar( r[1] );
+        retStr += "]";
+        break;
+      }
+      default:
+        Trace("strings-error") << "Unsupported term: " << r << " in RegExp." << std::endl;
+        //Assert( false );
+        //return Node::null();
+    }
+  }
+
+  return retStr;
+}
+
+}/* CVC4::theory::strings namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
index d5606627fe52f4ceaa864c86afef44ea820f9676..3d5ff2d6dbc56cc41c0a86ea73403ef310ecc7b6 100644 (file)
-/*********************                                                        */\r
-/*! \file regexp_operation.h\r
- ** \verbatim\r
- ** Original author: Tianyi Liang\r
- ** Major contributors: none\r
- ** Minor contributors (to current version): none\r
- ** This file is part of the CVC4 project.\r
- ** Copyright (c) 2009-2013  New York University and The University of Iowa\r
- ** See the file COPYING in the top-level source directory for licensing\r
- ** information.\endverbatim\r
- **\r
- ** \brief Symbolic Regular Expresion Operations\r
- **\r
- ** Symbolic Regular Expression Operations\r
- **/\r
-\r
-#include "cvc4_private.h"\r
-\r
-#ifndef __CVC4__THEORY__STRINGS__REGEXP__OPERATION_H\r
-#define __CVC4__THEORY__STRINGS__REGEXP__OPERATION_H\r
-\r
-#include <vector>\r
-#include <set>\r
-#include <algorithm>\r
-#include "util/hash.h"\r
-#include "util/regexp.h"\r
-#include "theory/theory.h"\r
-#include "theory/rewriter.h"\r
-//#include "context/cdhashmap.h"\r
-\r
-namespace CVC4 {\r
-namespace theory {\r
-namespace strings {\r
-\r
-class RegExpOpr {\r
-  typedef std::pair< Node, CVC4::String > PairNodeStr;\r
-  typedef std::set< Node > SetNodes;\r
-  typedef std::pair< Node, Node > PairNodes;\r
-\r
-private:\r
-  unsigned d_card;\r
-  Node d_emptyString;\r
-  Node d_true;\r
-  Node d_false;\r
-  Node d_emptySingleton;\r
-  Node d_emptyRegexp;\r
-  Node d_zero;\r
-  Node d_one;\r
-\r
-  char d_char_start;\r
-  char d_char_end;\r
-  Node d_sigma;\r
-  Node d_sigma_star;\r
-\r
-  std::map< PairNodes, Node > d_simpl_cache;\r
-  std::map< PairNodes, Node > d_simpl_neg_cache;\r
-  std::map< Node, std::pair< int, Node > > d_delta_cache;\r
-  std::map< PairNodeStr, Node > d_dv_cache;\r
-  std::map< PairNodeStr, std::pair< Node, int > > d_deriv_cache;\r
-  std::map< Node, std::pair< Node, int > > d_compl_cache;\r
-  std::map< Node, bool > d_cstre_cache;\r
-  std::map< Node, std::pair< std::set<unsigned>, std::set<Node> > > d_cset_cache;\r
-  std::map< Node, std::pair< std::set<unsigned>, std::set<Node> > > d_fset_cache;\r
-  std::map< PairNodes, Node > d_inter_cache;\r
-  std::map< Node, std::vector< PairNodes > > d_split_cache;\r
-  //bool checkStarPlus( Node t );\r
-  void simplifyPRegExp( Node s, Node r, std::vector< Node > &new_nodes );\r
-  void simplifyNRegExp( Node s, Node r, std::vector< Node > &new_nodes );\r
-  std::string niceChar( Node r );\r
-  int gcd ( int a, int b );\r
-  Node mkAllExceptOne( char c );\r
-\r
-  void getCharSet( Node r, std::set<unsigned> &pcset, SetNodes &pvset );\r
-  Node intersectInternal( Node r1, Node r2, std::map< unsigned, std::set< PairNodes > > cache, bool &spflag );\r
-  void firstChars( Node r, std::set<unsigned> &pcset, SetNodes &pvset );\r
-\r
-  //TODO: for intersection\r
-  bool follow( Node r, CVC4::String c, std::vector< char > &vec_chars );\r
-\r
-public:\r
-  RegExpOpr();\r
-\r
-  bool checkConstRegExp( Node r );\r
-  void simplify(Node t, std::vector< Node > &new_nodes, bool polarity);\r
-  int delta( Node r, Node &exp );\r
-  int derivativeS( Node r, CVC4::String c, Node &retNode );\r
-  Node derivativeSingle( Node r, CVC4::String c );\r
-  bool guessLength( Node r, int &co );\r
-  Node intersect(Node r1, Node r2, bool &spflag);\r
-  Node complement(Node r, int &ret);\r
-  void splitRegExp(Node r, std::vector< PairNodes > &pset);\r
-\r
-  std::string mkString( Node r );\r
-};\r
-\r
-}/* CVC4::theory::strings namespace */\r
-}/* CVC4::theory namespace */\r
-}/* CVC4 namespace */\r
-\r
-#endif /* __CVC4__THEORY__STRINGS__REGEXP__OPERATION_H */\r
+/*********************                                                        */
+/*! \file regexp_operation.h
+ ** \verbatim
+ ** Original author: Tianyi Liang
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2013  New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Symbolic Regular Expresion Operations
+ **
+ ** Symbolic Regular Expression Operations
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__THEORY__STRINGS__REGEXP__OPERATION_H
+#define __CVC4__THEORY__STRINGS__REGEXP__OPERATION_H
+
+#include <vector>
+#include <set>
+#include <algorithm>
+#include "util/hash.h"
+#include "util/regexp.h"
+#include "theory/theory.h"
+#include "theory/rewriter.h"
+//#include "context/cdhashmap.h"
+
+namespace CVC4 {
+namespace theory {
+namespace strings {
+
+class RegExpOpr {
+  typedef std::pair< Node, CVC4::String > PairNodeStr;
+  typedef std::set< Node > SetNodes;
+  typedef std::pair< Node, Node > PairNodes;
+
+private:
+  unsigned d_card;
+  Node d_emptyString;
+  Node d_true;
+  Node d_false;
+  Node d_emptySingleton;
+  Node d_emptyRegexp;
+  Node d_zero;
+  Node d_one;
+
+  char d_char_start;
+  char d_char_end;
+  Node d_sigma;
+  Node d_sigma_star;
+
+  std::map< PairNodes, Node > d_simpl_cache;
+  std::map< PairNodes, Node > d_simpl_neg_cache;
+  std::map< Node, std::pair< int, Node > > d_delta_cache;
+  std::map< PairNodeStr, Node > d_dv_cache;
+  std::map< PairNodeStr, std::pair< Node, int > > d_deriv_cache;
+  std::map< Node, std::pair< Node, int > > d_compl_cache;
+  std::map< Node, bool > d_cstre_cache;
+  std::map< Node, std::pair< std::set<unsigned>, std::set<Node> > > d_cset_cache;
+  std::map< Node, std::pair< std::set<unsigned>, std::set<Node> > > d_fset_cache;
+  std::map< PairNodes, Node > d_inter_cache;
+  std::map< Node, std::vector< PairNodes > > d_split_cache;
+  //bool checkStarPlus( Node t );
+  void simplifyPRegExp( Node s, Node r, std::vector< Node > &new_nodes );
+  void simplifyNRegExp( Node s, Node r, std::vector< Node > &new_nodes );
+  std::string niceChar( Node r );
+  int gcd ( int a, int b );
+  Node mkAllExceptOne( char c );
+
+  void getCharSet( Node r, std::set<unsigned> &pcset, SetNodes &pvset );
+  Node intersectInternal( Node r1, Node r2, std::map< unsigned, std::set< PairNodes > > cache, bool &spflag );
+  void firstChars( Node r, std::set<unsigned> &pcset, SetNodes &pvset );
+
+  //TODO: for intersection
+  bool follow( Node r, CVC4::String c, std::vector< char > &vec_chars );
+
+public:
+  RegExpOpr();
+
+  bool checkConstRegExp( Node r );
+  void simplify(Node t, std::vector< Node > &new_nodes, bool polarity);
+  int delta( Node r, Node &exp );
+  int derivativeS( Node r, CVC4::String c, Node &retNode );
+  Node derivativeSingle( Node r, CVC4::String c );
+  bool guessLength( Node r, int &co );
+  Node intersect(Node r1, Node r2, bool &spflag);
+  Node complement(Node r, int &ret);
+  void splitRegExp(Node r, std::vector< PairNodes > &pset);
+
+  std::string mkString( Node r );
+};
+
+}/* CVC4::theory::strings namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
+
+#endif /* __CVC4__THEORY__STRINGS__REGEXP__OPERATION_H */
index cbc0b843b789b759a80a7449533b9c4704919e3b..ce6f0d29bfd4db6ed1129f915a63e137f81e7385 100644 (file)
-/*********************                                                        */\r
-/*! \file regexp.cpp\r
- ** \verbatim\r
- ** Original author: Tianyi Liang\r
- ** Major contributors: none\r
- ** Minor contributors (to current version): Morgan Deters\r
- ** This file is part of the CVC4 project.\r
- ** Copyright (c) 2009-2013  New York University and The University of Iowa\r
- ** See the file COPYING in the top-level source directory for licensing\r
- ** information.\endverbatim\r
- **\r
- ** \brief [[ Add one-line brief description here ]]\r
- **\r
- ** [[ Add lengthier description here ]]\r
- ** \todo document this file\r
- **/\r
-\r
-#include "util/regexp.h"\r
-#include <iostream>\r
-#include <iomanip>\r
-\r
-using namespace std;\r
-\r
-namespace CVC4 {\r
-\r
-void String::toInternal(const std::string &s) {\r
-  d_str.clear();\r
-  unsigned i=0;\r
-  while(i < s.size()) {\r
-    if(s[i] == '\\') {\r
-      i++;\r
-      if(i < s.size()) {\r
-        switch(s[i]) {\r
-          case 'n':  {d_str.push_back( convertCharToUnsignedInt('\n') );i++;} break;\r
-          case 't':  {d_str.push_back( convertCharToUnsignedInt('\t') );i++;} break;\r
-          case 'v':  {d_str.push_back( convertCharToUnsignedInt('\v') );i++;} break;\r
-          case 'b':  {d_str.push_back( convertCharToUnsignedInt('\b') );i++;} break;\r
-          case 'r':  {d_str.push_back( convertCharToUnsignedInt('\r') );i++;} break;\r
-          case 'f':  {d_str.push_back( convertCharToUnsignedInt('\f') );i++;} break;\r
-          case 'a':  {d_str.push_back( convertCharToUnsignedInt('\a') );i++;} break;\r
-          case '\\': {d_str.push_back( convertCharToUnsignedInt('\\') );i++;} break;\r
-          case 'x': {\r
-            if(i + 2 < s.size()) {\r
-              if(isxdigit(s[i+1]) && isxdigit(s[i+2])) {\r
-                d_str.push_back( convertCharToUnsignedInt( hexToDec(s[i+1]) * 16 + hexToDec(s[i+2]) ) );\r
-                i += 3;\r
-              } else {\r
-                throw CVC4::Exception( "Illegal String Literal: \"" + s + "\"" );\r
-              }\r
-            } else {\r
-              throw CVC4::Exception( "Illegal String Literal: \"" + s + "\", must have two digits after \\x" );\r
-            }\r
-          }\r
-          break;\r
-          default: {\r
-            if(isdigit(s[i])) {\r
-              int num = (int)s[i] - (int)'0';\r
-              bool flag = num < 4;\r
-              if(i+1 < s.size() && num < 8 && isdigit(s[i+1]) && s[i+1] < '8') {\r
-                num = num * 8 + (int)s[i+1] - (int)'0';\r
-                if(flag && i+2 < s.size() && isdigit(s[i+2]) && s[i+2] < '8') {\r
-                  num = num * 8 + (int)s[i+2] - (int)'0';\r
-                  d_str.push_back( convertCharToUnsignedInt((char)num) );\r
-                  i += 3;\r
-                } else {\r
-                  d_str.push_back( convertCharToUnsignedInt((char)num) );\r
-                  i += 2;\r
-                }\r
-              } else {\r
-                d_str.push_back( convertCharToUnsignedInt((char)num) );\r
-                i++;\r
-              }\r
-            } else if((unsigned)s[i] > 127) {\r
-              throw CVC4::Exception( "Illegal String Literal: \"" + s + "\", must use escaped sequence" );\r
-            } else {\r
-              d_str.push_back( convertCharToUnsignedInt(s[i]) );\r
-              i++;\r
-            }\r
-          }\r
-        }\r
-      } else {\r
-        throw CVC4::Exception( "should be handled by lexer: \"" + s + "\"" );\r
-        //d_str.push_back( convertCharToUnsignedInt('\\') );\r
-      }\r
-    } else if((unsigned)s[i] > 127) {\r
-      throw CVC4::Exception( "Illegal String Literal: \"" + s + "\", must use escaped sequence" );\r
-    } else {\r
-      d_str.push_back( convertCharToUnsignedInt(s[i]) );\r
-      i++;\r
-    }\r
-  }\r
-}\r
-\r
-void String::getCharSet(std::set<unsigned int> &cset) const {\r
-  for(std::vector<unsigned int>::const_iterator itr = d_str.begin();\r
-    itr != d_str.end(); itr++) {\r
-      cset.insert( *itr );\r
-    }\r
-}\r
-\r
-std::size_t String::overlap(String &y) const {\r
-  std::size_t i = d_str.size() < y.size() ? d_str.size() : y.size();\r
-  for(; i>0; i--) {\r
-    String s = suffix(i);\r
-    String p = y.prefix(i);\r
-    if(s == p) {\r
-      return i;\r
-    }\r
-  }\r
-  return i;\r
-}\r
-\r
-std::string String::toString() const {\r
-  std::string str;\r
-  for(unsigned int i=0; i<d_str.size(); ++i) {\r
-    char c = convertUnsignedIntToChar( d_str[i] );\r
-    if(isprint( c )) {\r
-    if(c == '\\') {\r
-      str += "\\\\";\r
-    } else if(c == '\"') {\r
-      str += "\\\"";\r
-    } else {\r
-      str += c;\r
-    }\r
-    } else {\r
-      std::string s;\r
-      switch(c) {\r
-      case '\a': s = "\\a"; break;\r
-      case '\b': s = "\\b"; break;\r
-      case '\t': s = "\\t"; break;\r
-      case '\r': s = "\\r"; break;\r
-      case '\v': s = "\\v"; break;\r
-      case '\f': s = "\\f"; break;\r
-      case '\n': s = "\\n"; break;\r
-      case '\e': s = "\\e"; break;\r
-      default  : {\r
-        std::stringstream ss;\r
-        ss << std::setfill ('0') << std::setw(2) << std::hex << ((int)c);\r
-        std::string t = ss.str();\r
-        t = t.substr(t.size()-2, 2);\r
-        s = "\\x" + t;\r
-        //std::string s2 = static_cast<std::ostringstream*>( &(std::ostringstream() << (int)c) )->str();\r
-      }\r
-      }\r
-      str += s;\r
-    }\r
-  }\r
-  return str;\r
-}\r
-\r
-std::ostream& operator <<(std::ostream& os, const String& s) {\r
-  return os << "\"" << s.toString() << "\"";\r
-}\r
-\r
-std::ostream& operator<<(std::ostream& out, const RegExp& s) {\r
-  return out << "regexp(" << s.getType() << ')';\r
-}\r
-\r
-}/* CVC4 namespace */\r
+/*********************                                                        */
+/*! \file regexp.cpp
+ ** \verbatim
+ ** Original author: Tianyi Liang
+ ** Major contributors: none
+ ** Minor contributors (to current version): Morgan Deters
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2013  New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief [[ Add one-line brief description here ]]
+ **
+ ** [[ Add lengthier description here ]]
+ ** \todo document this file
+ **/
+
+#include "util/regexp.h"
+#include <iostream>
+#include <iomanip>
+
+using namespace std;
+
+namespace CVC4 {
+
+void String::toInternal(const std::string &s) {
+  d_str.clear();
+  unsigned i=0;
+  while(i < s.size()) {
+    if(s[i] == '\\') {
+      i++;
+      if(i < s.size()) {
+        switch(s[i]) {
+          case 'n':  {d_str.push_back( convertCharToUnsignedInt('\n') );i++;} break;
+          case 't':  {d_str.push_back( convertCharToUnsignedInt('\t') );i++;} break;
+          case 'v':  {d_str.push_back( convertCharToUnsignedInt('\v') );i++;} break;
+          case 'b':  {d_str.push_back( convertCharToUnsignedInt('\b') );i++;} break;
+          case 'r':  {d_str.push_back( convertCharToUnsignedInt('\r') );i++;} break;
+          case 'f':  {d_str.push_back( convertCharToUnsignedInt('\f') );i++;} break;
+          case 'a':  {d_str.push_back( convertCharToUnsignedInt('\a') );i++;} break;
+          case '\\': {d_str.push_back( convertCharToUnsignedInt('\\') );i++;} break;
+          case 'x': {
+            if(i + 2 < s.size()) {
+              if(isxdigit(s[i+1]) && isxdigit(s[i+2])) {
+                d_str.push_back( convertCharToUnsignedInt( hexToDec(s[i+1]) * 16 + hexToDec(s[i+2]) ) );
+                i += 3;
+              } else {
+                throw CVC4::Exception( "Illegal String Literal: \"" + s + "\"" );
+              }
+            } else {
+              throw CVC4::Exception( "Illegal String Literal: \"" + s + "\", must have two digits after \\x" );
+            }
+          }
+          break;
+          default: {
+            if(isdigit(s[i])) {
+              int num = (int)s[i] - (int)'0';
+              bool flag = num < 4;
+              if(i+1 < s.size() && num < 8 && isdigit(s[i+1]) && s[i+1] < '8') {
+                num = num * 8 + (int)s[i+1] - (int)'0';
+                if(flag && i+2 < s.size() && isdigit(s[i+2]) && s[i+2] < '8') {
+                  num = num * 8 + (int)s[i+2] - (int)'0';
+                  d_str.push_back( convertCharToUnsignedInt((char)num) );
+                  i += 3;
+                } else {
+                  d_str.push_back( convertCharToUnsignedInt((char)num) );
+                  i += 2;
+                }
+              } else {
+                d_str.push_back( convertCharToUnsignedInt((char)num) );
+                i++;
+              }
+            } else if((unsigned)s[i] > 127) {
+              throw CVC4::Exception( "Illegal String Literal: \"" + s + "\", must use escaped sequence" );
+            } else {
+              d_str.push_back( convertCharToUnsignedInt(s[i]) );
+              i++;
+            }
+          }
+        }
+      } else {
+        throw CVC4::Exception( "should be handled by lexer: \"" + s + "\"" );
+        //d_str.push_back( convertCharToUnsignedInt('\\') );
+      }
+    } else if((unsigned)s[i] > 127) {
+      throw CVC4::Exception( "Illegal String Literal: \"" + s + "\", must use escaped sequence" );
+    } else {
+      d_str.push_back( convertCharToUnsignedInt(s[i]) );
+      i++;
+    }
+  }
+}
+
+void String::getCharSet(std::set<unsigned int> &cset) const {
+  for(std::vector<unsigned int>::const_iterator itr = d_str.begin();
+    itr != d_str.end(); itr++) {
+      cset.insert( *itr );
+    }
+}
+
+std::size_t String::overlap(String &y) const {
+  std::size_t i = d_str.size() < y.size() ? d_str.size() : y.size();
+  for(; i>0; i--) {
+    String s = suffix(i);
+    String p = y.prefix(i);
+    if(s == p) {
+      return i;
+    }
+  }
+  return i;
+}
+
+std::string String::toString() const {
+  std::string str;
+  for(unsigned int i=0; i<d_str.size(); ++i) {
+    char c = convertUnsignedIntToChar( d_str[i] );
+    if(isprint( c )) {
+    if(c == '\\') {
+      str += "\\\\";
+    } else if(c == '\"') {
+      str += "\\\"";
+    } else {
+      str += c;
+    }
+    } else {
+      std::string s;
+      switch(c) {
+      case '\a': s = "\\a"; break;
+      case '\b': s = "\\b"; break;
+      case '\t': s = "\\t"; break;
+      case '\r': s = "\\r"; break;
+      case '\v': s = "\\v"; break;
+      case '\f': s = "\\f"; break;
+      case '\n': s = "\\n"; break;
+      case '\e': s = "\\e"; break;
+      default  : {
+        std::stringstream ss;
+        ss << std::setfill ('0') << std::setw(2) << std::hex << ((int)c);
+        std::string t = ss.str();
+        t = t.substr(t.size()-2, 2);
+        s = "\\x" + t;
+        //std::string s2 = static_cast<std::ostringstream*>( &(std::ostringstream() << (int)c) )->str();
+      }
+      }
+      str += s;
+    }
+  }
+  return str;
+}
+
+std::ostream& operator <<(std::ostream& os, const String& s) {
+  return os << "\"" << s.toString() << "\"";
+}
+
+std::ostream& operator<<(std::ostream& out, const RegExp& s) {
+  return out << "regexp(" << s.getType() << ')';
+}
+
+}/* CVC4 namespace */