Esempio n. 1
0
void
OpenSMTContext::SetInfo( const Anode* attrs )
{
  assert( attrs );

  if ( attrs->type == AT_KEY && strcmp( attrs->value, ":status" ) == 0 )
  {
    if ( attrs->children.size() > 0 && attrs->children[0]->type == AT_SYM ) {
      Anode& res = *(attrs->children[0]);
      if ( strcmp( res.value, "sat" ) == 0 )
        config.status = l_True;
      else if ( strcmp( res.value, "unsat" ) == 0 )
        config.status = l_False;
      else if ( strcmp( res.value, "unknown" ) == 0 )
        config.status = l_Undef;
      else
        opensmt_error2( "unrecognized status", res.value );
    }
    else
      opensmt_error( "was expecting type symbol" );
  }
  else if ( attrs->type == AT_KEY && strcmp( attrs->value, ":smt-lib-version" ) == 0 )
    ; // Do nothing
  else if ( attrs->type == AT_KEY && strcmp( attrs->value, ":category" ) == 0 )
    ; // Do nothing
  else if ( attrs->type == AT_KEY && strcmp( attrs->value, ":source" ) == 0 )
    ; // Do nothing
  else
    opensmt_error2( "unrecognized key", attrs->value );
}
Esempio n. 2
0
void
OpenSMTContext::SetOption( const char * key, const char * attr )
{
  assert( key );
  assert( attr );

  if ( strcmp( key, ":print-success" ) == 0 )
  {
    if ( strcmp( attr, "true" ) == 0 )
      config.print_success = true;
  }
  else if ( strcmp( key, ":expand-definitions" ) == 0 )
    opensmt_warning2( key, " not yet supported, skipping.")
  else if ( strcmp( key, ":interactive-mode" ) == 0 )
    opensmt_warning2( key, " not yet supported, skipping.")
  else if ( strcmp( key, ":produce-proofs" ) == 0 )
  {
    if ( strcmp( attr, "true" ) == 0 )
    {
#ifndef PRODUCE_PROOF
      opensmt_error( "You must configure code with --enable-proof to produce proofs" );
#endif
      config.setProduceProofs( );
    }
  }
  else if ( strcmp( key, ":produce-interpolants" ) == 0 )
  {
    if ( strcmp( attr, "true" ) == 0 )
    {
#ifndef PRODUCE_PROOF
      opensmt_warning( "You must configure code with --enable-proof to produce interpolants" );
#endif
      config.setProduceInter( );
    }
  }
  else if ( strcmp( key, ":produce-unsat-cores" ) == 0 )
    opensmt_warning2( key, " not yet supported, skipping.")
  else if ( strcmp( key, ":produce-models" ) == 0 )
  {
    if ( strcmp( attr, "true" ) == 0 )
      config.setProduceModels( );
  }
  else if ( strcmp( key, ":produce-assignments" ) == 0 )
    opensmt_warning2( key, " not yet supported, skipping.")
  else if ( strcmp( key, ":produce-interpolants" ) == 0 )
    config.setProduceInter( );
  else if ( strcmp( key, ":regular-output-channel" ) == 0 )
    config.setRegularOutputChannel( attr );
  else if ( strcmp( key, ":diagnostic-output-channel" ) == 0 )
    config.setDiagnosticOutputChannel( attr );
  else if ( strcmp( key, ":random-seed" ) == 0 )
    opensmt_warning2( key, " not yet supported, skipping.")
  else if ( strcmp( key, ":verbosity" ) == 0 )
    config.verbosity = atoi( attr );
  else
    opensmt_warning2( "skipping option ", key );
}
Esempio n. 3
0
void
Config::parseCMDLine( int argc
                       , char * argv[ ] )
{
  assert( tool != TOOL_UNDEF );
  if ( tool == OPENSMT )
    parseOpenSMTCMDLine( argc, argv );
  else if ( tool == MCMT )
    parseMCMTCMDLine( argc, argv );
  else
    opensmt_error( "Uknown tool" );
}
Esempio n. 4
0
void OpenSMTContext::PrintResult( const lbool & result, const lbool & config_status )
{
  ostream & out = config.getRegularOut( );
#ifdef SMTCOMP
  (void)config_status;
#else
  fflush( stderr );
  (void)config_status;
  //
  // For testing purposes we return error if bug is found
  //
  if ( config_status != l_Undef
    && result != l_Undef
    && result != config_status )
    out << "error" << endl;
  else
#endif
  if ( result == l_True )
    out << "sat" << endl;
  else if ( result == l_False )
    out << "unsat" << endl;
  else if ( result == l_Undef )
    out << "unknown" << endl;
  else
    opensmt_error( "unexpected result" );

  fflush( stdout );

#ifndef SMTCOMP
  if ( config.verbosity )
  {
    //
    // Statistics
    //
    double   cpu_time = cpuTime();
    reportf( "#\n" );
    reportf( "# CPU Time used: %g s\n", cpu_time == 0 ? 0 : cpu_time );
    uint64_t mem_used = memUsed();
    reportf( "# Memory used: %.3f MB\n",  mem_used == 0 ? 0 : mem_used / 1048576.0 );
    reportf( "#\n" );
  }
#endif
}
Esempio n. 5
0
//
// Execute a script in which there is only
// one check-sat. We can use specialized
// functions, such as preprocessing, to
// improve performance
//
int OpenSMTContext::executeStatic( )
{
  assert( init );
  //assert( config.incremental == 0 );
  //
  // Hack for SMT-COMP 2010 for retrieving formula
  //
  for ( size_t i = 0 ; i < command_list.size( ) ; i ++ )
  {
    Command & c = command_list[ i ];
    if ( c.command == ASSERT )
      Assert( c.enode );
    else if ( c.command == CHECK_SAT )
    {
      // Reduced check for computing interpolants
#ifdef PRODUCE_PROOF
      if ( config.produce_inter != 0 )
	staticCheckSATInterp( );
      else
#endif
      {
	staticCheckSAT( );
        ostream & out = config.getRegularOut( );
        if ( state == l_Undef )
            out << "unknown" << endl;
        else if ( state == l_False )
            out << "unsat" << endl;
        else
            out << "sat" << endl;
      }
    }
    else if ( c.command == EXIT )
      Exit( );
    else if ( c.command == GET_PROOF )
      GetProof( );
    else if ( c.command == GET_INTERPOLANTS )
      GetInterpolants( );
    else
      opensmt_error( "command not supported (yet)" );
  }

  return 0;
}
Esempio n. 6
0
void Config::printHelp( )
{
  const char opensmt_help_string[] 
    = "Usage: ./opensmt [OPTION] filename\n"
      "where OPTION can be\n"
      "  --help [-h]                                   print this help\n"
      "  --config=<filename>                           use configuration file <filename>\n";
                                                       
  const char mcmt_help_string[]                        
    = "Usage: ./mcmt [OPTION] filename\n"              
      "where OPTION can be\n"                          
      "  --help [-h]                                   print this help\n"
      "  --config=<filename>                           use configuration file <filename>\n"
      "  --auto-test [-at]                             automatic test feature\n" 
      "  --node_limit=N  [-dN]                         stop state space exploration after N nodes (N is a positive integer,\n" 
      "                                                default is 50000)\n"
      "  --depth_limit=N [-DN]                         stop state space exploration when depth N is reached (bounded model\n" 
      "                                                checking mode)\n"
      "  --resume [-e]                                 resume previous state space exploration\n"
      "  --tex [-t]                                    print report in two files: report.tex (containing the list of nodes in LaTex)\n" 
      "                                                and report.dot (containing the graph of the search space in Dot format)\n"
      "  --flex_fix_point [-f]                         flexible instantiation for fix-point checks (user can also specify in the\n" 
      "                                                input file depth and number of variables to be fixed - expert users only)\n" 
      "  --verbosity [-v]                              set verbosity level (1 default, 0 silent)\n"
      "  --predicate_abstr [-a]                        enable index and predicate abstraction in invariant search (user can specify an\n" 
      "                                                abstract signature in the input file)\n"
      "  --constant_abstr [-c]                         constant abstraction in invariant search\n"
      "  --log [-y]                                    printf the log of the proof obligations generated for Yices\n" 
      "                                                (in the file .yices-log)\n"
      "  --olog [-ol]                                  printf the log of the proof obligations generated for OpenSMT\n" 
      "                                                (in the file .opensmt_log.smt2)\n"
      "  --weak_fix_point [-wN]                        enable an incomplete heuristics for fix-point checks after node N (expert\n" 
      "                                                users only)\n"
      "  --incr_fix_point=N [-pN]                      set how many new configurations should be considered for incremental\n" 
      "                                                fix-point checks\n"
      "  --breadth_search [-bs]                        enable breadth-first exploration of state space\n"
      "  --depth_search [-ds]                          enable depth-first exploration of state space\n"
      "  --simpl_level=N [-SN]                         set the simplification level\n" 
      "                                                N=0: none, N=1 : lazy, N=2 : eager,\n" 
      "                                                N=3: eager+eager real quantifier elimination\n"
      "  --e_simpl_level=N [-EN]                       set the egraph simplification level\n" 
      "                                                N=0: naively remove duplicates in ands\n"
      "                                                N=1: aggressively remove duplicates in ands\n"
      "  --full_inv_search [-I]                        enables one/two variables invariant search, plus dynamic predicate and constant\n" 
      "                                                abstraction\n"
      "  --parsing_tests   [-P]                        just do parsing tests on formulae (Yices executable required in the shell path)\n"
      "  --simplify_preimages [-sp]                    simplifies the preimages when generated, deleteting unuseful ones\n"
      "  --report [-r]                                 write a report of nodes in the file report.log\n"
      "  --suppress_eager_fixpoint [-no_efp]           suppress the eager fixpoint (i.e. a fixpoint test is performed BEFORE\n"
      "                                                enter the node in the ToBeVisited list).\n"
      "  --suppress_lazy_fixpoint [-no_lfp]            suppress the lazy fixpoint (enabled by default)\n"
      "  --optimization [-o]                           enables optimization features\n"
      "  --fix_point_period=N [-fppN]                  Change the number of assertions before calling the SMT-solver (default is 10)\n"
      "  --check_compatible=N [-ccN]                   N=1 : simpliest (and less precise) check of transition compatibility (default)\n"
      "                                                N=2 : more precise check of compatibility\n"
      "  --iterative [-it]                             Iterative version\n"
      "  --counterexample [-ce]                        Get the counterexample unsafety is detected\n"
      "  --invariant [-i]                              \"Old-style\" invariant search\n"
      "  --invariant_nodes=N [-inN]                    Can generate at most N nodes while checking candidate invariants\n"
      "  --invariant_pattern [-ip]                     Pattern-based invariant search\n"
      "  --generate_invariants [-gi]                   Generate invariants\n"
      "\n  LAZY ABSTRACTION OPTIONS -- these options work only with abstraction!\n"
      "  --abstraction_power=N [-apN]                  Different levels of abstraction power\n"
      "                                                N=0: minimum power (default)\n"
      "                                                N=1: maximum\n"
      "  --term_abstraction [-ta]                      Enables term abstraction\n"
      "  --abstract_unsafe [-au]                       Abstract all the unsafe configurations (default=no)\n"
      "  --abstraction_report [-ar]                    Produces a graphviz+log before every refinement\n"
      "  --abstraction_limit=N [-alimN]                Maximum number of abstractions (-1 = unbounded, default)\n"
      "  --abstraction_locking=N [-alN]                Enables lock features:\n"
      "                                                N=0: no locking\n"
      "                                                N=1: check with parents\n"
      "                                                N=2: check with nodes previously generated (default)\n"
      "  --refinement_depth=N [-rdN]                   Change the depth of the refinement:\n"
      "                                                N=-1: refines all the nodes on the trace (default)\n"
      "                                                N=1,2,3...: refines up to the last but N nodes of the trace\n"
      "  --start_interp_algo=N [-siaN]                 Change the first interpolation algorhtm (0,1,2)\n"
      "  --abstraction_arithmetic [-arh]               Abstract arithmetic literals\n"
      "\n"
      "Transitions to be accelerated can be specified in the input file\n";
  
  assert( tool != TOOL_UNDEF );
  if ( tool == OPENSMT )
    cerr << opensmt_help_string;
  else if ( tool == MCMT )
    cerr << mcmt_help_string;
  else
    opensmt_error( "Unknown tool" );
}
Esempio n. 7
0
void Config::parseConfig ( char * f )
{
  FILE * filein = NULL;
  // Open configuration file
  if ( ( filein = fopen( f, "rt" ) ) == NULL )
  {
    // No configuration file is found. Print out
    // the current configuration
    cerr << "# WARNING: No configuration file " << f << ". Dumping default setting to " << f << endl;
    ofstream fileout( f );
    printConfig( fileout );
    fileout.close( );
  }
  else
  {
    int line = 0;

    while ( !feof( filein ) )
    {
      line ++;
      char buf[ 128 ];
      char * res = fgets( buf, 128, filein );
      (void)res;
      // Stop if finished
      if ( feof( filein ) )
	break;
      // Skip comments
      if ( buf[ 0 ] == '#' )
	continue;

      char tmpbuf[ 32 ];

      // GENERIC CONFIGURATION
	   if ( sscanf( buf, "incremental %d\n"                   , &incremental )                    == 1 );
      else if ( sscanf( buf, "produce_stats %d\n"                 , &produce_stats )                  == 1 );
      else if ( sscanf( buf, "print_stats %d\n"                   , &print_stats )                    == 1 );
      else if ( sscanf( buf, "print_proofs_smtlib2 %d\n"          , &print_proofs_smtlib2 )           == 1 );
      else if ( sscanf( buf, "print_proofs_dotty %d\n"            , &print_proofs_dotty )             == 1 );
      else if ( sscanf( buf, "produce_models %d\n"                , &produce_models )                 == 1 )
      {
#ifndef PRODUCE_PROOF
	if ( produce_proofs != 0 )
	  opensmt_error( "You must configure code with --enable-proof to produce proofs" );
#endif
      }
      else if ( sscanf( buf, "produce_inter %d\n"                 , &produce_inter )                  == 1 )
      {
#ifndef PRODUCE_PROOF
	if ( produce_inter != 0 )
	  opensmt_error( "You must configure code with --enable-proof to produce interpolants" );
#endif
      }
      else if ( sscanf( buf, "regular_output_channel %s\n"        , tmpbuf )                          == 1 )
	setRegularOutputChannel( tmpbuf );
      else if ( sscanf( buf, "diagnostic_output_channel %s\n"     , tmpbuf )                          == 1 )
	setDiagnosticOutputChannel( tmpbuf );                                                         
      else if ( sscanf( buf, "dump_formula %d\n"                  , &dump_formula )                   == 1 );
      else if ( sscanf( buf, "dump_log %d\n"                      , &dump_log )                       == 1 );
      else if ( sscanf( buf, "verbosity %d\n"                     , &verbosity )                      == 1 );
      else if ( sscanf( buf, "print_success %d\n"                 , &print_success )                  == 1 );
      else if ( sscanf( buf, "certification_level %d\n"           , &certification_level )            == 1 );
      else if ( sscanf( buf, "certifying_solver %s\n"             , certifying_solver )               == 1 );
      else if ( sscanf( buf, "split_equalities %d\n"              , &split_equalities )               == 1 );
      // SAT SOLVER CONFIGURATION                                                                     
      else if ( sscanf( buf, "sat_theory_propagation %d\n"        , &(sat_theory_propagation))        == 1 );
      else if ( sscanf( buf, "sat_polarity_mode %d\n"             , &(sat_polarity_mode))             == 1 );
      else if ( sscanf( buf, "sat_initial_skip_step %lf\n"        , &(sat_initial_skip_step))         == 1 );
      else if ( sscanf( buf, "sat_skip_step_factor %lf\n"         , &(sat_skip_step_factor))          == 1 );
      else if ( sscanf( buf, "sat_restart_first %d\n"             , &(sat_restart_first))             == 1 );
      else if ( sscanf( buf, "sat_restart_increment %lf\n"        , &(sat_restart_inc))               == 1 );
      else if ( sscanf( buf, "sat_use_luby_restart %d\n"          , &(sat_use_luby_restart))          == 1 );
      else if ( sscanf( buf, "sat_learn_up_to_size %d\n"          , &(sat_learn_up_to_size))          == 1 );
      else if ( sscanf( buf, "sat_temporary_learn %d\n"           , &(sat_temporary_learn))           == 1 );
      else if ( sscanf( buf, "sat_preprocess_booleans %d\n"       , &(sat_preprocess_booleans))       == 1 );
      else if ( sscanf( buf, "sat_preprocess_theory %d\n"         , &(sat_preprocess_theory))         == 1 );
      else if ( sscanf( buf, "sat_centrality %d\n"                , &(sat_centrality))                == 1 );
      else if ( sscanf( buf, "sat_trade_off %d\n"                 , &(sat_trade_off))                 == 1 );
      else if ( sscanf( buf, "sat_minimize_conflicts %d\n"        , &(sat_minimize_conflicts))        == 1 );
      else if ( sscanf( buf, "sat_dump_cnf %d\n"                  , &(sat_dump_cnf))                  == 1 );
      else if ( sscanf( buf, "sat_dump_rnd_inter %d\n"            , &(sat_dump_rnd_inter))            == 1 );
      else if ( sscanf( buf, "sat_lazy_dtc %d\n"                  , &(sat_lazy_dtc))                  == 1 );
      else if ( sscanf( buf, "sat_lazy_dtc_burst %d\n"            , &(sat_lazy_dtc_burst))            == 1 );
      // PROOF PRODUCTION CONFIGURATION                                                               
      else if ( sscanf( buf, "proof_reduce %d\n"                  , &(proof_reduce))                  == 1 );
      else if ( sscanf( buf, "proof_random_seed %d\n"             , &(proof_random_seed))             == 1 );
      else if ( sscanf( buf, "proof_ratio_red_solv %lf\n"         , &(proof_ratio_red_solv))          == 1 );
      else if ( sscanf( buf, "proof_red_time %lf\n"               , &(proof_red_time))                == 1 );
      else if ( sscanf( buf, "proof_num_graph_traversals %d\n"    , &(proof_num_graph_traversals))    == 1 );
      else if ( sscanf( buf, "proof_red_trans %d\n"               , &(proof_red_trans))               == 1 );
      else if ( sscanf( buf, "proof_reorder_pivots %d\n"          , &(proof_reorder_pivots))          == 1 );
      else if ( sscanf( buf, "proof_reduce_while_reordering %d\n" , &(proof_reduce_while_reordering)) == 1 );
      else if ( sscanf( buf, "proof_random_context_analysis %d\n" , &(proof_random_context_analysis)) == 1 );
      else if ( sscanf( buf, "proof_random_swap_application %d\n" , &(proof_random_swap_application)) == 1 );
      else if ( sscanf( buf, "proof_remove_mixed %d\n"            , &(proof_remove_mixed))            == 1 );
      else if ( sscanf( buf, "proof_set_inter_algo %d\n"          , &(proof_set_inter_algo))          == 1 );
      else if ( sscanf( buf, "proof_certify_inter %d\n"           , &(proof_certify_inter))           == 1 );
      // EUF SOLVER CONFIGURATION                                                                     
      else if ( sscanf( buf, "uf_disable %d\n"                    , &(uf_disable))                    == 1 );
      else if ( sscanf( buf, "uf_theory_propagation %d\n"         , &(uf_theory_propagation))         == 1 );
      // BV SOLVER CONFIGURATION                                                                            
      else if ( sscanf( buf, "bv_disable %d\n"                    , &(bv_disable))                    == 1 );
      else if ( sscanf( buf, "bv_theory_propagation %d\n"         , &(bv_theory_propagation))         == 1 );
      // DL SOLVER CONFIGURATION                                                                            
      else if ( sscanf( buf, "dl_disable %d\n"                    , &(dl_disable))                    == 1 );
      else if ( sscanf( buf, "dl_theory_propagation %d\n"         , &(dl_theory_propagation))         == 1 );
      // LRA SOLVER CONFIGURATION                                                                           
      else if ( sscanf( buf, "lra_disable %d\n"                   , &(lra_disable))                   == 1 );
      else if ( sscanf( buf, "lra_theory_propagation %d\n"        , &(lra_theory_propagation))        == 1 );
      else if ( sscanf( buf, "lra_poly_deduct_size %d\n"          , &(lra_poly_deduct_size))          == 1 );
      else if ( sscanf( buf, "lra_gaussian_elim %d\n"             , &(lra_gaussian_elim))             == 1 );
      else if ( sscanf( buf, "lra_integer_solver %d\n"            , &(lra_integer_solver))            == 1 );
      else if ( sscanf( buf, "lra_check_on_assert %d\n"           , &(lra_check_on_assert))           == 1 );
      // MCMT related options
      else if ( sscanf( buf, "node_limit %d\n"                    , &(node_limit))                    == 1 );
      else if ( sscanf( buf, "depth_limit %d\n"                   , &(depth_limit))                   == 1 );
      else if ( sscanf( buf, "verbosity %d\n"                     , &(verbosity))                     == 1 );      
      else if ( sscanf( buf, "simpl_level %d\n"                   , &(simpl_level))                   == 1 );      
      else if ( sscanf( buf, "e_simpl_level %d\n"                 , &(e_simpl_level))                 == 1 );      
      else if ( sscanf( buf, "fix_point_strategy %d\n"            , &(fix_point_strategy))            == 1 );
      else if ( sscanf( buf, "fix_point_period %d\n"              , &(fix_point_period))              == 1 );
      else if ( sscanf( buf, "check_compatible %d\n"              , &(check_compatible))              == 1 );
      else if ( sscanf( buf, "invariant_nodes %d\n"               , &(invariant_nodes))               == 1 );
      else if ( (report_tex            = (strcmp( buf, "tex\n" )                      == 0)) );
      else if ( (flex_fix_point        = (strcmp( buf, "flex_fix_point\n" )           == 0)) );
      else if ( (predicate_abstr       = (strcmp( buf, "predicate_abstr\n" )          == 0)) );
      else if ( (constant_abstr        = (strcmp( buf, "constant_abstr\n" )           == 0)) ); 
      else if ( (log                   = (strcmp( buf, "log\n" )                      == 0)) );
      else if ( (weak_fix_point        = (strcmp( buf, "weak_fix_point\n" )           == 0)) );
      else if ( (incr_fix_point        = (strcmp( buf, "incr_fix_point\n" )           == 0)) ); 
      else if ( (breadth_search        = (strcmp( buf, "breadth_search\n" )           == 0)) );
      else if ( (breadth_search        = (strcmp( buf, "depth_search\n" )             == 0)) );
      else if ( (full_inv_search       = (strcmp( buf, "full_inv_search\n" )          == 0)) );
      else if ( (parsing_tests         = (strcmp( buf, "parsing_tests\n" )            == 0)) );  
      else if ( (simplify_preimages    = (strcmp( buf, "simplify_preimages\n" )       == 0)) );  
      else if ( (report                = (strcmp( buf, "report\n" )                   == 0)) );  
      else if ( (optimization          = (strcmp( buf, "optimization\n" )             == 0)) ); 
      else if ( (iterative             = (strcmp( buf, "iterative\n" )                == 0)) ); 
      else if ( (invariant_pattern     = (strcmp( buf, "invariant_pattern\n" )        == 0)) ); 
      else if ( (classic_invariant     = (strcmp( buf, "invariant\n" )                == 0)) ); 
      else if ( (counterexample        = (strcmp( buf, "counterexample\n" )           == 0)) ); 
      else if ( (generate_invariants   = (strcmp( buf, "generate_invariants\n" )      == 0)) ); 
      else
      {
	opensmt_error2( "unrecognized option ", buf );
      }
    }

    if ( invariant_pattern || classic_invariant )
    {
      global_invariant = true;
    }

    // Close
    fclose( filein );
  }

  if ( produce_stats ) stats_out.open( ".stats.out" );
  if ( dump_log )      log_out.open( ".opensmt_log.smt2" );
}
Esempio n. 8
0
int main( int argc, char * argv[] )
{
  opensmt::stop = false;
  // Allocates Command Handler (since SMT-LIB 2.0)
  OpenSMTContext context( argc, argv );
  // Catch SigTerm, so that it answers even on ctrl-c
  signal( SIGTERM, opensmt::catcher );
  signal( SIGINT , opensmt::catcher );
  // Initialize pointer to context for parsing
  parser_ctx    = &context;
  const char * filename = argv[ argc - 1 ];
  assert( filename );
  // Accepts file from stdin if nothing specified
  FILE * fin = NULL;
  // Print help if required
  if ( strcmp( filename, "--help" ) == 0
    || strcmp( filename, "-h" ) == 0 )
  {
    context.getConfig( ).printHelp( );
    return 0;
  }
  // File must be last arg
  if ( strncmp( filename, "--", 2 ) == 0
    || strncmp( filename, "-", 1 ) == 0 )
    opensmt_error( "input file must be last argument" );
  // Make sure file exists
  if ( argc == 1 )
    fin = stdin;
  else if ( (fin = fopen( filename, "rt" )) == NULL )
    opensmt_error( "can't open file" );

  // Parse
  // Parse according to filetype
  if ( fin == stdin )
  {
    smt2set_in( fin );
    smt2parse( );
  }
  else
  {
    const char * extension = strrchr( filename, '.' );
    // if ( strcmp( extension, ".smt" ) == 0 )
    // {
    //   opensmt_error( "SMTLIB 1.2 format is not supported in this version, sorry" );
    //   smtset_in( fin );
    //   smtparse( );
    // }
    // else if ( strcmp( extension, ".cnf" ) == 0 )
    // {
    //   context.SetLogic( QF_BOOL );
    //   cnfset_in( fin );
    //   cnfparse( );
    // }
    //else
    if ( strcmp( extension, ".smt2" ) == 0 )
    {
      smt2set_in( fin );
      smt2parse( );
    }
    else
    {
      opensmt_error2( extension, " extension not recognized. Please use one in { smt2, cnf } or stdin (smtlib2 is assumed)" );
    }
  }

  fclose( fin );

#ifndef SMTCOMP
  if ( context.getConfig( ).verbosity > 0 )
  {
    const int len_pack = strlen( PACKAGE_STRING );
    const char * site = "http://verify.inf.usi.ch/opensmt";
    const int len_site = strlen( site );

    cerr << "#" << endl
         << "# -------------------------------------------------------------------------" << endl
         << "# " << PACKAGE_STRING;

    for ( int i = 0 ; i < 73 - len_site - len_pack ; i ++ )
      cerr << " ";

    cerr << site << endl
         << "# Compiled with gcc " << __VERSION__ << " on " << __DATE__ << endl
         << "# -------------------------------------------------------------------------" << endl
         << "#" << endl;
  }
#endif

  //
  // This trick (copied from Main.C of MiniSAT) is to allow
  // the repeatability of experiments that might be compromised
  // by the floating point unit approximations on doubles
  //
#if defined(__linux__) && !defined( SMTCOMP )
  fpu_control_t oldcw, newcw;
  _FPU_GETCW(oldcw); newcw = (oldcw & ~_FPU_EXTENDED) | _FPU_DOUBLE; _FPU_SETCW(newcw);
#endif

#ifdef PEDANTIC_DEBUG
  opensmt_warning("pedantic assertion checking enabled (very slow)");
#endif

#ifndef OPTIMIZE
//  opensmt_warning( "this binary is compiled with optimizations disabled (slow)" );
#endif
  //
  // Execute accumulated commands
  // function defined in OpenSMTContext.C
  //
  return context.executeCommands( );
}
Esempio n. 9
0
lbool SimpSMTSolver::solve( const vec< Lit > & assumps
    , const unsigned conflicts
    , bool do_simp
    , bool turn_off_simp)
{
  vec<Var> extra_frozen;
  bool     result = true;

  if ( config.sat_preprocess_theory == 0 )
    goto skip_theory_preproc;

  opensmt_error( "preprocess theory has been temporairly disabled in this version" );

skip_theory_preproc:

  // Added Code
  //=================================================================================================

  do_simp &= use_simplification;

  if (do_simp)
  {
    // Assumptions must be temporarily frozen to run variable elimination:
    for (int i = 0; i < assumps.size(); i++)
    {
      Var v = var(assumps[i]);

      // If an assumption has been eliminated, remember it.
      if (isEliminated(v))
	remember(v);

      if (!frozen[v])
      {
	// Freeze and store.
	setFrozen(v, true);
	extra_frozen.push(v);
      }
    }

    result = eliminate(turn_off_simp);
  }

#ifdef STATISTICS
  CoreSMTSolver::preproc_time = cpuTime( );
#endif

  lbool lresult = l_Undef;
  if (result)
    lresult = CoreSMTSolver::solve(assumps, conflicts);
  else
    lresult = l_False;

  if (lresult == l_True)
  {
    extendModel();
    // Previous line
    // #ifndef NDEBUG
#ifndef SMTCOMP
    verifyModel();
#endif
  }

  if (do_simp)
    // Unfreeze the assumptions that were frozen:
    for (int i = 0; i < extra_frozen.size(); i++)
      setFrozen(extra_frozen[i], false);

  return lresult;
}
Esempio n. 10
0
void ProofGraph::transfProof( )
{
  // Time left for transformation
  double leftTime = cpuTime( );

  size_t size=0;
  int numnodes=0;
  int numedges=0;
  int numleaves=0;
  int numvars=0;
  double avgdeg=0;
  int dia=0;
  int maxclasize=0;
  double avgclasize=0;
  int unsatcoredim=0;
  int numunary=0;
  double avgnumresunary=0;
  double avgnumres=0;
  int maxnumres=0;
  double varnumres=0;
  double varclasize=0;

  if ( verbose() )
  {
    getGraphInfo( );

    size = graph.size( );
    numnodes=num_nodes;
    numedges=num_edges;
    numleaves=num_leaves;
    numvars=numVars;
    avgdeg=(double)numedges / (double)numnodes;
    dia=diameter;
    maxclasize=max_cla_size;
    avgclasize=av_cla_size;
    unsatcoredim=dim_unsat_core;
    numunary=num_unary;
    avgnumresunary=avg_num_res_unary;
    avgnumres=avg_num_res;
    maxnumres=max_num_res;
    varnumres=var_num_res;
    varclasize=var_cla_size;
  }

  double time=0;

  if( produceProof() )
  {
    if ( reduceProof() > 0 )
    {
      time = doIt( leftTime );
    }
  }
  else if( produceInterpolants() > 0 )
  {
    //No need to transform proof if no AB-mixed predicate is present!
    assert(!lightVars.empty());

    if ( reorderPivots() > 0)
      time = doIt( leftTime );
    else
    {
      opensmt_error( "Cannot produce interpolants because of AB-mixed predicates. Please enable pivot reordering in config file" );
    }
  }

#ifndef OPTIMIZE
  checkProof();
  cleanProofGraph( );
  checkProof();
#endif
  if ( verbose() > 0 )
  {
    getGraphInfo( );

    double perc_nodes=(((double)num_nodes-(double)numnodes)/(double)numnodes)*100;
    double perc_edges=(((double)num_edges-(double)numedges)/(double)numedges)*100;
    double perc_leaves=(((double)num_leaves-(double)numleaves)/(double)numleaves)*100;
    double perc_unsatcore=(((double)dim_unsat_core-(double)unsatcoredim)/(double)unsatcoredim)*100;
    cerr << "#" << endl;
    cerr << "# ------------------------------------" << endl;
    cerr << "# PROOF GRAPH TRASFORMATION STATISTICS    " << endl;
    cerr << "# ------------------------------------" << endl;
    cerr << "# Structural properties" << endl;
    cerr << "# ---------------------" << endl;
    cerr << "# Light variables............: ";
    fprintf( stderr, "%-10ld\n", lightVars.size( ) );
    cerr << "# Nominal num proof variables: ";
    fprintf( stderr, "%-10ld\n", numVarsLimit );
    cerr << "# Actual num proof variables.: ";
    fprintf( stderr, "%-10d %-10d\n", numvars, numVars );
    cerr << "# Nodes......................: ";
    fprintf( stderr, "%-10d %-10d\n", numnodes, num_nodes );
    cerr << "# Nodes variation............: ";
    fprintf( stderr, "%-9.2f %%\n", perc_nodes );
    cerr << "# Leaves.....................: ";
    fprintf( stderr, "%-10d %-10d\n", numleaves, num_leaves );
    cerr << "# Leaves variation...........: ";
    fprintf( stderr, "%-9.2f %%\n", perc_leaves );
    cerr << "# Unsat core.................: ";
    fprintf( stderr, "%-10d %-10d\n", unsatcoredim, dim_unsat_core );
    cerr << "# Unsat core variation.......: ";
    fprintf( stderr, "%-9.2f %%\n", perc_unsatcore );
    cerr << "# Edges......................: ";
    fprintf( stderr, "%-10d %-10d\n", numedges, num_edges );
    cerr << "# Edges variation............: ";
    fprintf( stderr, "%-9.2f %%\n", perc_edges );
    cerr << "# Graph vector size..........: ";
    fprintf( stderr, "%-10ld %-10ld\n", size, graph.size( ) );
    cerr << "# Average degree.............: ";
    fprintf( stderr, "%-10.2f %-10.2f\n", avgdeg, (double)num_edges / (double)num_nodes );
    cerr << "# Diameter...................: ";
    fprintf( stderr, "%-10d %-10d\n", dia, diameter );
    cerr << "# Unary clauses..............: ";
    fprintf( stderr, "%-10d %-10d\n", numunary, num_unary );
    cerr << "# Max clause size............: ";
    fprintf( stderr, "%-10d %-10d\n", maxclasize, max_cla_size );
    cerr << "# Average clause size........: ";
    fprintf( stderr, "%-10.2f %-10.2f\n", avgclasize, av_cla_size );
    cerr << "# Variance clause size.......: ";
    fprintf( stderr, "%-10.2f %-10.2f\n", varclasize, var_cla_size );
    cerr << "# Max num res................: ";
    fprintf( stderr, "%-10d %-10d\n", maxnumres, max_num_res );
    cerr << "# Average num res............: ";
    fprintf( stderr, "%-10.2f %-10.2f\n", avgnumres, avg_num_res );
    cerr << "# Avg num res unary clauses..: ";
    fprintf( stderr, "%-10.2f %-10.2f\n", avgnumresunary, avg_num_res_unary );
    cerr << "# Variance num res...........: ";
    fprintf( stderr, "%-10.2f %-10.2f\n", varnumres, var_num_res );
    cerr << "# -------------------------" << endl;
    cerr << "# Transformation statistics" << endl;
    cerr << "# -------------------------" << endl;
    cerr << "# Graph building time........: " << building_time << " s" << endl;
    cerr << "# Transformation time........: " << time << " s" << endl;
    cerr << "# Duplications...............: " << num_dup << endl;
    cerr << "# Node additions due to A1...: " << num_node_add_A1 << endl;
    cerr << "# ---------------------------" << endl;
    cerr << "# Rules application statistics" << endl;
    cerr << "# ---------------------------" << endl;
    cerr << "# A1.........................: " << A1 << endl;
    cerr << "# A1 undo....................: " << A1Undo << endl;
    cerr << "# A1 to B....................: " << A1B << endl;
    cerr << "# A2.........................: " << A2 << endl;
    cerr << "# A2 to B....................: " << A2B << endl;
    cerr << "# A2 unary...................: " << A2U << endl;
    cerr << "# B1.........................: " << B1 << endl;
    cerr << "# B2.........................: " << B2 << endl;
    cerr << "# B2 killer..................: " << B2K << endl;
    cerr << "# B3.........................: " << B3 << endl;
    cerr << "# ---------------------------" << endl;
  }
}
Esempio n. 11
0
void OpenSMTContext::staticCheckSATInterp( ) 
{
  assert( config.produce_inter != 0 );

  // From now on coloring for new enodes
  // is automatically computed based on
  // the colors of the arguments. Unless
  // forced otherwise ...
  egraph.setAutomaticColoring( );
  // Propagate ABcommon terms if
  // tagged as Alocal/Blocal
  egraph.maximizeColors( );
  
  if ( config.verbosity > 1 )
    cerr << "# OpenSMTContext::Statically Checking" << endl;

  if ( config.logic == UNDEF )
    opensmt_error( "unable to determine logic" );

  if ( config.logic == QF_UFIDL 
    || config.logic == QF_UFLRA )
  {
    if ( config.sat_lazy_dtc == 0 )
      opensmt_warning( "Overriding option sat_lazy_dtc" );
    config.sat_lazy_dtc = 1;
    config.incremental = 1;
    config.sat_polarity_mode = 4;
  }

  // Gather partitions
  vector< Enode * > assertions;
  for ( ;; )
  {
    // Get partition
    Enode * formula = egraph.getNextAssertion( );
    if ( formula == NULL ) break;
    assertions.push_back( formula );
  }

  // Purifier for DTC
  if ( config.logic == QF_UFIDL
    || config.logic == QF_UFLRA )
  {
    Purify purifier( egraph, config );
    purifier.doit( assertions );
  }

  // Ite expander
  ExpandITEs expander( egraph, config );
  
  // Top-Level Propagator. It also canonize atoms
  TopLevelProp propagator( egraph, config );

  // Initialize theory solvers
  egraph.initializeTheorySolvers( &solver );

  // Initialize AXDIFF preprocessor
  AXDiffPreproc axdiffpreproc( egraph, sstore, config );

  for ( size_t in = 0 ; in < assertions.size( ) ; in ++ )
  {
    // Get formula
    Enode * formula = assertions[ in ];
    // const ipartitions_t partition = SETBIT( in + 1 );
    ipartitions_t partition = 0;
    setbit( partition, in + 1 );
    assert( in != 0 || formula != NULL );
    // Remove ites 
    formula = expander.doit( formula );
    // Canonize atoms
    formula = propagator.doit( formula );
    // Preprocessing for AX 
    if ( config.logic == QF_AX
      || config.logic == QF_AXDIFF )
    {
      formula = axdiffpreproc.doit( formula, partition );
    }
    // Some predicates may have been introduced
    // by the last steps. Color them if they are
    // not colored already
    egraph.finalizeColors( formula, partition );

    if ( config.dump_formula != 0 )
    {
      char buf[ 32 ];
      sprintf( buf, "presolve_%ld.smt2", in + 1 );
      egraph.dumpToFile( buf, formula );
    }
    // Restore
    assertions[ in ] = formula;
  }
  //
  // Now give to solver
  //
  for ( size_t in = 0 ; in < assertions.size( ) ; in ++ )
  {
    // const ipartitions_t partition = SETBIT( in + 1 );
    ipartitions_t partition = 0;
    setbit( partition, in + 1 );
    // Get partition
    Enode * formula = assertions[ in ];
    // CNFize the input formula and feed clauses to the solver
    state = cnfizer.cnfizeAndGiveToSolver( formula, partition );
  }

  // Solve
  if ( state == l_Undef )
  {
    if ( config.sat_preprocess_booleans != 0
      || config.sat_preprocess_theory != 0 )
      opensmt_warning( "not using SMT-preprocessing with interpolation" );
    state = solver.smtSolve( false );
  }

  // If computation has been stopped, return undef
  if ( opensmt::stop ) state = l_Undef;
}
Esempio n. 12
0
void OpenSMTContext::staticCheckSAT( ) 
{
  if ( config.verbosity > 1 )
    cerr << "# OpenSMTContext::Statically Checking" << endl;

  // Retrieve the formula
  Enode * formula = egraph.getUncheckedAssertions( );

  if ( config.dump_formula != 0 )
    egraph.dumpToFile( "original.smt2", formula );

  if ( formula == NULL )
    opensmt_error( "formula undefined" );

  if ( config.logic == UNDEF )
    opensmt_error( "unable to determine logic" );

  // Removes ITEs if there is any
  if ( egraph.hasItes( ) )
  {
    ExpandITEs expander( egraph, config );
    formula = expander.doit( formula );

    if ( config.dump_formula != 0 )
      egraph.dumpToFile( "ite_expanded.smt2", formula );
  }

  // Gather interface terms for DTC
  if ( ( config.logic == QF_UFIDL
      || config.logic == QF_UFLRA )
    // Don't use with DTC of course
    && config.sat_lazy_dtc == 1
    // Don't use when dumping interpolants
    && config.sat_dump_rnd_inter == 0 )
  {
    Purify purifier( egraph, config );
    purifier.doit( formula );
  }

  // Ackermanize away functional symbols
  if ( ( config.logic == QF_UFIDL
      || config.logic == QF_UFLRA )
    // Don't use with DTC of course
    && config.sat_lazy_dtc == 0
    // Don't use when dumping interpolants
    && config.sat_dump_rnd_inter == 0 )
  {
    Ackermanize ackermanizer( egraph, config );
    formula = ackermanizer.doit( formula );

    if ( config.dump_formula != 0 )
      egraph.dumpToFile( "ackermanized.smt2", formula );
  }

  // Artificially create a boolean
  // abstraction, if necessary
  if ( config.logic == QF_BV )
  {
    BVBooleanize booleanizer( egraph, config );
    formula = booleanizer.doit( formula );
  }

  if ( config.dump_formula != 0 )
    egraph.dumpToFile( "prepropagated.smt2", formula );

  // Top-Level Propagator. It also canonize atoms
  TopLevelProp propagator( egraph, config );
  // Only if sat_dump_rnd_inter is not set
  if ( config.sat_dump_rnd_inter == 0 )
    formula = propagator.doit( formula );

  if ( config.dump_formula != 0 )
    egraph.dumpToFile( "propagated.smt2", formula );

  AXDiffPreproc2 axdiffpreproc( egraph, sstore, config );
  if ( config.logic == QF_AX
    || config.logic == QF_AXDIFF )
  {
    formula = axdiffpreproc.doit( formula );
    if ( config.dump_formula != 0 )
      egraph.dumpToFile( "axdiffpreproc.smt2", formula );
  }

  // Convert RDL into IDL, also compute if GMP is needed
  if ( config.logic == QF_RDL )
  {
    DLRescale rescaler( egraph, config );
    rescaler.doit( formula );
  }

  // For static checking, make sure that if DTC is used
  // then incrementality is enabled
  if ( ( config.logic == QF_UFIDL
      || config.logic == QF_UFLRA )
      && config.sat_lazy_dtc != 0 )
  {
    config.incremental = 1;
    config.sat_polarity_mode = 4;
  }

  if ( config.dump_formula != 0 )
    egraph.dumpToFile( "presolve.smt2", formula );

  // Solve only if not simplified already
  if ( formula->isTrue( ) )
  {
    state = l_True;
  }
  else if ( formula->isFalse( ) )
  {
    state = l_False;
  }
  else
  {
    assert(egraph.isInitialized());
    // Initialize theory solvers
    // egraph.initializeTheorySolvers( &solver );

    // Compute polarities
    egraph.computePolarities( formula );

    // CNFize the input formula and feed clauses to the solver
    state = cnfizer.cnfizeAndGiveToSolver( formula );

    // Solve
    if ( state == l_Undef )
    {
      state = solver.smtSolve( config.sat_preprocess_booleans != 0
                            || config.sat_preprocess_theory   != 0 );
    }

    // If computation has been stopped, return undef
    if ( opensmt::stop ) state = l_Undef;
  }
}
Esempio n. 13
0
//
// Execute a generic SMTLIB2 script
//
int OpenSMTContext::executeIncremental( )
{
  assert( init );
  assert( config.incremental == 1 );

  // Initialize theory solvers
  egraph.initializeTheorySolvers( &solver );

  lbool status = l_Undef;

  for ( size_t i = 0 ; i < command_list.size( ) ;  ++ i )
  {
    Command & c = command_list[ i ];

    // Commands blocked with assert( false ) are issued from parser directly
    switch( c.command )
    {
      case SET_LOGIC:
	assert( false );
	break;
      case SET_OPTION:
	assert( false );
	break;
      case SET_INFO:
	assert( false );
	break;
      case DECLARE_SORT:
	DeclareSort( c.str, c.num );
	break;
      case DEFINE_SORT:
	opensmt_error( "construct define-sort not yet supported" );
	break;
      case DECLARE_FUN:
	DeclareFun( c.str, c.sort_arg, c.sort_ret );
	break;
      case DEFINE_FUN:
	opensmt_error( "construct define-fun not yet supported" );
	break;
      case PUSH:
	Push( );
	break;
      case POP:
	Pop( );
	break;
      case ASSERT:
	Assert( c.enode );
	break;
      case CHECK_SAT:
	status = CheckSAT( );
	break;
      case GET_ASSERTIONS:
	opensmt_error( "construct get-assertions not yet supported" );
	break;
      case GET_PROOF:
	GetProof( );
	break;
      case GET_INTERPOLANTS:
	GetInterpolants( );
	break;
      case GET_UNSAT_CORE:
	opensmt_error( "construct get-unsat-core not yet supported" );
	break;
      case GET_VALUE:
	opensmt_error( "construct get-value not yet supported" );
	break;
      case GET_ASSIGNMENT:
	opensmt_error( "construct get-assignment not yet supported" );
	break;
      case GET_OPTION:
	opensmt_error( "construct get-option not yet supported" );
	break;
      case GET_INFO:
	opensmt_error( "construct get-info not yet supported" );
	break;
      case EXIT:
	Exit( );
	break;
      default:
	opensmt_error( "case not handled" );
    }
  }

  return 0;
}
Esempio n. 14
0
void CGraph::colorEdgesFrom( CNode * x, const uint64_t mask )
{
  // Color from x
  CNode * n = NULL;
  while( x->next != NULL
      && x->next->color == CG_UNDEF )
  {
    n = x->next->target;
    // Congruence edge, recurse on arguments
    if ( x->next->reason == NULL )
    {
      assert( x->e->getArity( ) == n->e->getArity( ) );
      // Color children of the congruence relation, and
      // introduce intermediate nodes if necessary
      Enode * arg_list_x, * arg_list_n;
      for ( arg_list_x = x->e->getCdr( )
          , arg_list_n = n->e->getCdr( )
          ; !arg_list_x->isEnil( )
          ; arg_list_x = arg_list_x->getCdr( )
          , arg_list_n = arg_list_n->getCdr( ) )
      {
        Enode * arg_x = arg_list_x->getCar( );
        Enode * arg_n = arg_list_n->getCar( );
        if ( arg_x == arg_n ) continue;
        // Call recursively on arguments
        colorEdgesRec( cnodes_store[ arg_x->getId( ) ]
                     , cnodes_store[ arg_n->getId( ) ]
                     , mask );
      }
      // Incompatible colors: this is possible
      // for effect of congruence nodes: adjust
      if ( (x->color == CG_A && n->color == CG_B)
        || (x->color == CG_B && n->color == CG_A) )
      {
        // Need to introduce auxiliary nodes and edges
        // For each argument, find node that is equivalent
        // and of shared color
        list< Enode * > new_args;
        Enode * arg_list_x, * arg_list_n;
        for ( arg_list_x = x->e->getCdr( )
            , arg_list_n = n->e->getCdr( )
            ; !arg_list_x->isEnil( )
            ; arg_list_x = arg_list_x->getCdr( )
            , arg_list_n = arg_list_n->getCdr( ) )
        {
          Enode * arg_x = arg_list_x->getCar( );
          Enode * arg_n = arg_list_n->getCar( );
          CNode * cn_arg_x = cnodes_store[ arg_x->getId( ) ];
          CNode * cn_arg_n = cnodes_store[ arg_n->getId( ) ];
          // If same node, keep
          if ( arg_x == arg_n )
          {
            new_args.push_front( arg_x );
          }
          // If argument
          else if ( (cn_arg_x->color & n->color) == 0 )
          {
            // Scan first argument that is equivalent to x and shared
            CNode * xnext;
            for ( xnext = cn_arg_x->next->target
                ; xnext != NULL
                ; xnext = xnext->next->target )
            {
              if ( xnext->color == CG_AB )
                break;
            }
            assert( xnext != NULL );
            assert( xnext->color == CG_AB );
            new_args.push_front( xnext->e );
          }
          else if ( (cn_arg_n->color & x->color) == 0 )
          {
            // Scan first argument that is equivalent to x and shared
            CNode * nnext;
            for ( nnext = cn_arg_n->next->target
                ; nnext != NULL
                ; nnext = nnext->next->target )
            {
              if ( nnext->color == CG_AB )
                break;
            }
            assert( nnext != NULL );
            assert( nnext->color == CG_AB );
            new_args.push_front( nnext->e );
          }
          else
          {
            opensmt_error( "something went wrong" );
          }
          // New arguments must be shared
          assert( cnodes_store[ new_args.front( )->getId( ) ]->color == CG_AB );
        }
        Enode * na = egraph.cons( new_args );
        Enode * s = x->e->getCar( );
        // nn is the node that can be connected to x and n
        Enode * nn = egraph.cons( s, na );
        // There are two cases now. It is possible
        // that nn is equal to either x or n
        assert( nn != x->e );
        assert( nn != n->e );
        // Adds corresponding node
        addCNode( nn );
        // Remember this
        assert( x->next->target == n );
        CNode * cnn = cnodes.back( );
        cnn->color = CG_AB;
        /*
        // Situation ... --> x | then make ... --> x --> nn
        if ( x->next == NULL )
          addCEdge( x->e, nn, NULL );
        // Situation ... <-- x | then make ... <-- x <-- nn
        else
        {
          addCEdge( nn, x->e, NULL );
        }
        */
        // Situation x --> n | then make x --> nn
        x->next = NULL;
        addCEdge( x->e, nn, NULL );
        assert( x->next->target == cnn );
        // Choose a color
        cedges.back( )->color = x->color;
        /*
        // Situation x --> nn   n | then make x --> nn --> n
        if ( cnn->next == NULL )
          addCEdge( nn, x->e, NULL );
        // Situation x <-- nn   n <-- | then make x <-- nn <-- n <--
        else if ( n->next == NULL )
          addCEdge( nn, n->e, NULL );
        // Situation x <-- nn   n --> | then make x <-- nn <-- n <--
        else
        {
          revertEdges( n );
          addCEdge( n->e, nn, NULL );
        }
        */
        addCEdge( nn, n->e, NULL );
        cedges.back( )->color = n->color;
        x = cnn;
      }
      // Now all the children are colored, we can decide how to color this
      if ( x->color == n->color )
      {
        assert( x->color );
        // Choose one color: default A
        if ( x->color == CG_AB )
          x->next->color = CG_A;
        // Color with proper color
        else
          x->next->color = x->color;
      }
      // Different colors: choose intersection
      else
      {
        // It is not possible that are incompatible
        assert( x->color != CG_A || n->color != CG_B );
        assert( x->color != CG_B || n->color != CG_A );
        x->next->color = x->color & n->color;
        assert( x->next->color != CG_UNDEF );
      }
    }
    // Color basic edge with proper color
    else
    {
      // If it's AB, color B
      x->next->color = ((egraph.getIPartitions( x->next->reason ) & mask) != 0)
                  ? CG_B
                  : CG_A;
    }
    // Color must be a power of 2
    assert( x->next->color == CG_A || x->next->color == CG_B );
    assert( x->next->color != CG_A || x->next->color != CG_B );
    // Pass to next node
    x = n;
  }
}