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 ); }
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 ); }
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" ); }
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 }
// // 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; }
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" ); }
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" ); }
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( ); }
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; }
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; } }
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; }
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; } }
// // 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; }
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; } }