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 Config::parseOpenSMTCMDLine( int argc , char * argv[ ] ) { char config_name[ 64 ]; for ( int i = 1 ; i < argc - 1 ; i ++ ) { const char * buf = argv[ i ]; // Parsing of configuration options if ( sscanf( buf, "--config=%s", config_name ) == 1 ) { parseConfig( config_name ); break; } else if ( strcmp( buf, "--help" ) == 0 || strcmp( buf, "-h" ) == 0 ) { printHelp( ); exit( 1 ); } else { printHelp( ); opensmt_error2( "unrecognized option", buf ); } } if ( dump_log ) log_out.open( ".opensmt_log.smt2" ); }
int process_bch(config const & config) { FILE * fin = nullptr; string filename = config.get_filename(); // Make sure file exists if ((fin = fopen(filename.c_str(), "rt")) == nullptr) { opensmt_error2("can't open file", filename.c_str()); } ::bchset_in(fin); ::bch_init_parser(); ::bchparse(); OpenSMTContext & ctx = *bch_ctx; if (config.get_precision() > 0) { ctx.setPrecision(config.get_precision()); } ctx.setLocalOpt(config.get_local_opt()); ctx.setDebug(config.get_debug()); ctx.setPolytope(config.get_polytope()); ctx.setShrinkForDop(config.get_sync()); unordered_map<string, Enode *> var_map = bch_var_map; vector<Enode *> & costs = bch_costs; vector<Enode *> & ctrs_X = bch_ctrs; int const ret = process_main(ctx, config, costs, var_map, ctrs_X); ::bchlex_destroy(); fclose(fin); ::bch_cleanup_parser(); return ret; }
void THandler::verifyCallWithExternalTool( bool res, size_t trail_size ) { // First stage: print declarations const char * name = "/tmp/verifycall.smt2"; std::ofstream dump_out( name ); core_solver.dumpHeaderToFile( dump_out ); dump_out << "(assert" << endl; dump_out << "(and" << endl; for ( size_t j = 0 ; j <= trail_size ; j ++ ) { Var v = var( trail[ j ] ); if ( v == var_True || v == var_False ) continue; // Enode * e = var_to_enode[ v ]; Enode * e = varToEnode( v ); assert( e ); if ( !e->isTAtom( ) ) continue; bool negated = sign( trail[ j ] ); if ( negated ) dump_out << "(not "; e->print( dump_out ); if ( negated ) dump_out << ")"; dump_out << endl; } dump_out << "))" << endl; dump_out << "(check-sat)" << endl; dump_out << "(exit)" << endl; dump_out.close( ); // Second stage, check the formula const bool tool_res = callCertifyingSolver( name ); if ( res == false && tool_res == true ) opensmt_error2( config.certifying_solver, " says SAT stack, but we say UNSAT" ); if ( res == true && tool_res == false ) opensmt_error2( config.certifying_solver, " says UNSAT stack, but we say SAT" ); }
void THandler::verifyDeductionWithExternalTool( Enode * imp ) { assert( imp->isDeduced( ) ); // First stage: print declarations const char * name = "/tmp/verifydeduction.smt2"; std::ofstream dump_out( name ); core_solver.dumpHeaderToFile( dump_out ); dump_out << "(assert" << endl; dump_out << "(and" << endl; for ( int j = 0 ; j < trail.size( ) ; j ++ ) { Var v = var( trail[ j ] ); if ( v == var_True || v == var_False ) continue; Enode * e = varToEnode( v ); assert( e ); if ( !e->isTAtom( ) ) continue; bool negated = sign( trail[ j ] ); if ( negated ) dump_out << "(not "; e->print( dump_out ); if ( negated ) dump_out << ")"; dump_out << endl; } if ( imp->getDeduced( ) == l_True ) dump_out << "(not " << imp << ")" << endl; else dump_out << imp << endl; dump_out << "))" << endl; dump_out << "(check-sat)" << endl; dump_out << "(exit)" << endl; dump_out.close( ); // Second stage, check the formula const bool tool_res = callCertifyingSolver( name ); if ( tool_res ) opensmt_error2( config.certifying_solver, " says this is not a valid deduction" ); }
//TODO: more intelligent value parsing would be nice. // // Parse the bound value and the type of the constraint // void LAVar::setBounds( Enode * e, Enode * e_bound ) { assert( e->isAtom( ) ); assert( e_bound->isConstant( ) ); bool revert = false; if( !( e->get1st( )->isConstant( ) ) ) revert = true; if( e_bound->isConstant( ) ) setBounds( e, e_bound->getComplexValue( ), revert ); else opensmt_error2( "unexpected Num: ", e_bound ); }
opensmt_context opensmt_mk_context( opensmt_logic l ) { OpenSMTContext * c = new OpenSMTContext( ); OpenSMTContext & context = *c; // IMPORTANT: // Any parameter in the config should be set // here, BEFORE SetLogic is called. In SetLogic // solvers are initialized with values taken // from the config ... SMTConfig & config = context.getConfig( ); // When API is active incremental solving must be on config.incremental = 1; // // Set ad-hoc default parameters // if ( l == qf_ct ) { // Settings copied/adapted from pbct 0.1.2 config.sat_polarity_mode = 1; config.sat_use_luby_restart = 1; config.sat_preprocess_booleans = 0; config.uf_disable = 1; } // Set the right logic switch( l ) { case qf_uf: context.SetLogic( QF_UF ); break; case qf_bv: context.SetLogic( QF_BV ); break; case qf_rdl: context.SetLogic( QF_RDL ); break; case qf_idl: context.SetLogic( QF_IDL ); break; case qf_lra: context.SetLogic( QF_LRA ); break; case qf_lia: context.SetLogic( QF_LIA ); break; case qf_ufidl: context.SetLogic( QF_UFIDL ); break; case qf_uflra: context.SetLogic( QF_UFLRA ); break; case qf_nra: context.SetLogic( QF_NRA ); break; case qf_nra_ode: context.SetLogic( QF_NRA_ODE ); break; case qf_bool: context.SetLogic( QF_BOOL ); break; case qf_ct: context.SetLogic( QF_CT ); break; opensmt_error2( "unsupported logic: ", l ); } // Return context return static_cast< void * >( c ); }
int process_inv(config const & config) { FILE * fin = nullptr; string filename = config.get_filename(); // Make sure file exists if ((fin = fopen(filename.c_str(), "rt")) == nullptr) { opensmt_error2("can't open file", filename.c_str()); } ::invset_in(fin); ::inv_init_parser(); ::invparse(); OpenSMTContext & ctx = *inv_ctx; if (inv_prec > 0) { ctx.setPrecision(inv_prec); } if (config.get_precision() > 0) { ctx.setPrecision(config.get_precision()); } int const ret = process_main(ctx, config); ::invlex_destroy(); fclose(fin); ::inv_cleanup_parser(); return ret; }
void THandler::verifyExplanationWithExternalTool( vector< Enode * > & expl ) { // First stage: print declarations const char * name = "/tmp/verifyexp.smt2"; std::ofstream dump_out( name ); core_solver.dumpHeaderToFile( dump_out ); dump_out << "(assert " << endl; dump_out << "(and" << endl; for ( size_t j = 0 ; j < expl.size( ) ; j ++ ) { Enode * e = expl[ j ]; assert( e->isTAtom( ) ); assert( e->getPolarity( ) != l_Undef ); bool negated = e->getPolarity( ) == l_False; if ( negated ) dump_out << "(not "; e->print( dump_out ); if ( negated ) dump_out << ")"; dump_out << endl; } dump_out << "))" << endl; dump_out << "(check-sat)" << endl; dump_out << "(exit)" << endl; dump_out.close( ); // Third stage, check the formula const bool tool_res = callCertifyingSolver( name ); if ( tool_res == true ) opensmt_error2( config.certifying_solver, " says this is not an explanation" ); }
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( ); }
// // Performs the actual cnfization // bool Tseitin::cnfize( Enode * formula, map< enodeid_t, Enode * > & cnf_cache ) { (void)cnf_cache; assert( formula ); assert( !formula->isAnd( ) ); Enode * arg_def = egraph.valDupMap1( formula ); if ( arg_def != NULL ) { vector< Enode * > clause; clause.push_back( arg_def ); #ifdef PRODUCE_PROOF if ( config.produce_inter > 0 ) return solver.addSMTClause( clause, egraph.getIPartitions( formula ) ); #endif return solver.addSMTClause( clause ); } vector< Enode * > unprocessed_enodes; // Stack for unprocessed enodes unprocessed_enodes.push_back( formula ); // formula needs to be processed // // Visit the DAG of the formula from the leaves to the root // while( !unprocessed_enodes.empty( ) ) { Enode * enode = unprocessed_enodes.back( ); // // Skip if the node has already been processed before // if ( egraph.valDupMap1( enode ) != NULL ) { unprocessed_enodes.pop_back( ); continue; } bool unprocessed_children = false; Enode * arg_list; for ( arg_list = enode->getCdr( ) ; arg_list != egraph.enil ; arg_list = arg_list->getCdr( ) ) { Enode * arg = arg_list->getCar( ); assert( arg->isTerm( ) ); // // Push only if it is an unprocessed boolean operator // if ( enode->isBooleanOperator( ) && egraph.valDupMap1( arg ) == NULL ) { unprocessed_enodes.push_back( arg ); unprocessed_children = true; } // // If it is an atom (either boolean or theory) just // store it in the cache // else if ( arg->isAtom( ) ) { egraph.storeDupMap1( arg, arg ); } } // // SKip if unprocessed_children // if ( unprocessed_children ) continue; unprocessed_enodes.pop_back( ); Enode * result = NULL; // // At this point, every child has been processed // // // Do the actual cnfization, according to the node type // char def_name[ 32 ]; if ( enode->isLit( ) ) { result = enode; } else if ( enode->isNot( ) ) { Enode * arg_def = egraph.valDupMap1( enode->get1st( ) ); assert( arg_def ); result = egraph.mkNot( egraph.cons( arg_def ) ); // Toggle the literal } else { Enode * arg_def = NULL; Enode * new_arg_list = egraph.copyEnodeEtypeListWithCache( enode->getCdr( ) ); // // If the enode is not top-level it needs a definition // if ( formula != enode ) { sprintf( def_name, CNF_STR, formula->getId( ), enode->getId( ) ); egraph.newSymbol( def_name, sstore.mkBool( ) ); arg_def = egraph.mkVar( def_name ); #ifdef PRODUCE_PROOF if ( config.produce_inter > 0 ) { // Tag Positive and negative literals egraph.tagIFormula( arg_def , egraph.getIPartitions( enode ) ); egraph.tagIFormula( egraph.mkNot( egraph.cons( arg_def ) ) , egraph.getIPartitions( enode ) ); } #endif } #ifdef PRODUCE_PROOF uint64_t partitions = 0; if ( config.produce_inter > 0 ) { partitions = egraph.getIPartitions( enode ); assert( partitions != 0 ); } #endif // // Handle boolean operators // if ( enode->isAnd( ) ) cnfizeAnd( new_arg_list, arg_def #ifdef PRODUCE_PROOF , partitions #endif ); else if ( enode->isOr( ) ) cnfizeOr( new_arg_list, arg_def #ifdef PRODUCE_PROOF , partitions #endif ); else if ( enode->isIff( ) ) cnfizeIff( new_arg_list, arg_def #ifdef PRODUCE_PROOF , partitions #endif ); else if ( enode->isXor( ) ) cnfizeXor( new_arg_list, arg_def #ifdef PRODUCE_PROOF , partitions #endif ); else { opensmt_error2( "operator not handled ", enode->getCar( ) ); } if ( arg_def != NULL ) result = arg_def; } assert( egraph.valDupMap1( enode ) == NULL ); egraph.storeDupMap1( enode, result ); } if ( formula->isNot( ) ) { // Retrieve definition of argument Enode * arg_def = egraph.valDupMap1( formula->get1st( ) ); assert( arg_def ); vector< Enode * > clause; clause.push_back( toggleLit( arg_def ) ); #ifdef PRODUCE_PROOF if ( config.produce_inter > 0 ) return solver.addSMTClause( clause, egraph.getIPartitions( formula ) ); #endif return solver.addSMTClause( clause ); } return true; }
void SMTConfig::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 << "# " << endl; 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, "produce_models %d\n" , &produce_models ) == 1 ); else if ( sscanf( buf, "produce_proofs %d\n" , &produce_proofs ) == 1 ); else if ( sscanf( buf, "produce_inter %d\n" , &produce_inter ) == 1 ); 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, "verbosity %d\n" , &verbosity ) == 1 ); else if ( sscanf( buf, "certification_level %d\n" , &certification_level ) == 1 ); else if ( sscanf( buf, "certifying_solver %s\n" , certifying_solver ) == 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_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_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_remove_mixed %d\n" , &(proof_remove_mixed)) == 1 ); else if ( sscanf( buf, "proof_use_sym_inter %d\n" , &(proof_use_sym_inter)) == 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 ); else { opensmt_error2( "unrecognized option ", buf ); } } // Close fclose( filein ); } if ( produce_stats ) stats_out.open( "stats.out" ); }
Enode * Egraph::canonizeDTC( Enode * formula , bool split_eqs ) { assert( config.sat_lazy_dtc != 0 ); assert( config.logic == QF_UFLRA || config.logic == QF_UFIDL ); list< Enode * > dtc_axioms; vector< Enode * > unprocessed_enodes; initDupMap1( ); unprocessed_enodes.push_back( formula ); // // Visit the DAG of the formula from the leaves to the root // while( !unprocessed_enodes.empty( ) ) { Enode * enode = unprocessed_enodes.back( ); // // Skip if the node has already been processed before // if ( valDupMap1( enode ) != NULL ) { unprocessed_enodes.pop_back( ); continue; } bool unprocessed_children = false; Enode * arg_list; for ( arg_list = enode->getCdr( ) ; arg_list != enil ; arg_list = arg_list->getCdr( ) ) { Enode * arg = arg_list->getCar( ); assert( arg->isTerm( ) ); // // Push only if it is unprocessed // if ( valDupMap1( arg ) == NULL ) { unprocessed_enodes.push_back( arg ); unprocessed_children = true; } } // // SKip if unprocessed_children // if ( unprocessed_children ) continue; unprocessed_enodes.pop_back( ); Enode * result = NULL; // // Replace arithmetic atoms with canonized version // if ( enode->isTAtom( ) && !enode->isIff( ) && !enode->isUp( ) ) { // No need to do anything if node is purely UF if ( isRootUF( enode ) ) { if ( config.verbosity > 2 ) cerr << "# Egraph::Skipping canonization of " << enode << " as it's root is purely UF" << endl; result = enode; } else { LAExpression a( enode ); result = a.toEnode( *this ); if ( split_eqs && result->isEq( ) ) { #ifdef PRODUCE_PROOF if ( config.produce_inter != 0 ) opensmt_error2( "can't compute interpolant for equalities at the moment ", enode ); #endif LAExpression aa( enode ); Enode * e = aa.toEnode( *this ); Enode * lhs = e->get1st( ); Enode * rhs = e->get2nd( ); Enode * leq = mkLeq( cons( lhs, cons( rhs ) ) ); LAExpression b( leq ); leq = b.toEnode( *this ); Enode * geq = mkGeq( cons( lhs, cons( rhs ) ) ); LAExpression c( geq ); geq = c.toEnode( *this ); Enode * not_e = mkNot( cons( enode ) ); Enode * not_l = mkNot( cons( leq ) ); Enode * not_g = mkNot( cons( geq ) ); // Add clause ( !x=y v x<=y ) Enode * c1 = mkOr( cons( not_e , cons( leq ) ) ); // Add clause ( !x=y v x>=y ) Enode * c2 = mkOr( cons( not_e , cons( geq ) ) ); // Add clause ( x=y v !x>=y v !x<=y ) Enode * c3 = mkOr( cons( enode , cons( not_l , cons( not_g ) ) ) ); // Add conjunction of clauses Enode * ax = mkAnd( cons( c1 , cons( c2 , cons( c3 ) ) ) ); dtc_axioms.push_back( ax ); result = enode; } } } // // If nothing have been done copy and simplify // if ( result == NULL ) result = copyEnodeEtypeTermWithCache( enode ); assert( valDupMap1( enode ) == NULL ); storeDupMap1( enode, result ); } Enode * new_formula = valDupMap1( formula ); assert( new_formula ); doneDupMap1( ); if ( !dtc_axioms.empty( ) ) { dtc_axioms.push_back( new_formula ); new_formula = mkAnd( cons( dtc_axioms ) ); } return new_formula; }
void OpenSMTContext::SetOption( const char * key ) { opensmt_error2( "command not supported (yet)", key ); }
void SMTConfig::parseCMDLine( int argc , char * argv[ ] ) { char config_name[ 64 ]; for ( int i = 1 ; i < argc - 1 ; i ++ ) { const char * buf = argv[ i ]; // Parsing of configuration options if ( sscanf( buf, "--config=%s", config_name ) == 1 ) { parseConfig( config_name ); continue; } if ( sscanf( buf, "--precision=%lf", &nra_precision ) == 1) { if(nra_precision <= 0.0) { printHelp( ); exit( 1 ); } continue; } if ( sscanf( buf, "--ode-step=%lf", &nra_ODE_step ) == 1) { if(nra_ODE_step <= 0.0) { printHelp( ); exit( 1 ); } continue; } if ( sscanf( buf, "--ode-order=%d", &nra_ODE_taylor_order ) == 1) { continue; } if ( sscanf( buf, "--ode-grid=%d", &nra_ODE_grid_size ) == 1) { continue; } if ( strcmp( buf, "--ode-parallel" ) == 0 ) { nra_parallel_ODE = true; continue; } if ( strcmp( buf, "--help" ) == 0 ) { printHelp( ); exit( 1 ); } if ( strcmp( buf, "--proof" ) == 0 ) { nra_proof = true; /* Open file stream */ nra_proof_out_name = string(argv[ argc - 1 ]) + ".proof"; nra_proof_out.open (nra_proof_out_name.c_str(), std::ofstream::out | std::ofstream::trunc); if(nra_proof_out.fail()) { cout << "Cannot create a file: " << nra_proof_out_name << endl; exit( 1 ); } continue; } if ( strcmp( buf, "--visualize" ) == 0 ) { nra_json = true; string filename = string(argv[ argc - 1 ]) + ".json"; /* Open file stream */ nra_json_out.open (filename.c_str(), std::ofstream::out | std::ofstream::trunc ); if(nra_json_out.fail()) { cout << "Cannot create a file: " << filename << endl; exit( 1 ); } continue; } if ( strcmp( buf, "--verbose" ) == 0) { set_log_level(LogLevel::DEBUG); nra_verbose = true; continue; } else { printHelp( ); opensmt_error2( "unrecognized option", buf ); } } }
void THandler::verifyInterpolantWithExternalTool( vector< Enode * > & expl , Enode * interp_list ) { uint64_t mask = 0xFFFFFFFFFFFFFFFEULL; for ( unsigned in = 1 ; in < core_solver.getNofPartitions( ) ; in ++ ) { Enode * args = interp_list; // Advance in the interpolants list for ( unsigned i = 0 ; i < in - 1 ; i ++ ) args = args->getCdr( ); Enode * interp = args->getCar( ); mask &= ~SETBIT( in ); // Check A -> I, i.e., A & !I // First stage: print declarations const char * name = "/tmp/verifyinterp.smt2"; std::ofstream dump_out( name ); core_solver.dumpHeaderToFile( dump_out ); // Print only A atoms dump_out << "(assert " << endl; dump_out << "(and" << endl; for ( size_t j = 0 ; j < expl.size( ) ; j ++ ) { Enode * e = expl[ j ]; assert( e->isTAtom( ) ); assert( e->getPolarity( ) != l_Undef ); assert( (core_solver.getIPartitions( e ) & mask) != 0 || (core_solver.getIPartitions( e ) & ~mask) != 0 ); if ( (core_solver.getIPartitions( e ) & ~mask) != 0 ) { bool negated = e->getPolarity( ) == l_False; if ( negated ) dump_out << "(not "; e->print( dump_out ); if ( negated ) dump_out << ")"; dump_out << endl; } } dump_out << "(not " << interp << ")" << endl; dump_out << "))" << endl; dump_out << "(check-sat)" << endl; dump_out << "(exit)" << endl; dump_out.close( ); // Check ! bool tool_res; if ( int pid = fork() ) { int status; waitpid(pid, &status, 0); switch ( WEXITSTATUS( status ) ) { case 0: tool_res = false; break; case 1: tool_res = true; break; default: perror( "Tool" ); exit( EXIT_FAILURE ); } } else { execlp( "tool_wrapper.sh", "tool_wrapper.sh", name, 0 ); perror( "Tool" ); exit( 1 ); } if ( tool_res == true ) opensmt_error2( config.certifying_solver, " says A -> I does not hold" ); // Now check B & I dump_out.open( name ); core_solver.dumpHeaderToFile( dump_out ); // Print only B atoms dump_out << "(assert " << endl; dump_out << "(and" << endl; for ( size_t j = 0 ; j < expl.size( ) ; j ++ ) { Enode * e = expl[ j ]; assert( e->isTAtom( ) ); assert( e->getPolarity( ) != l_Undef ); assert( (core_solver.getIPartitions( e ) & mask) != 0 || (core_solver.getIPartitions( e ) & ~mask) != 0 ); if ( (core_solver.getIPartitions( e ) & mask) != 0 ) { bool negated = e->getPolarity( ) == l_False; if ( negated ) dump_out << "(not "; e->print( dump_out ); if ( negated ) dump_out << ")"; dump_out << endl; } } dump_out << interp << endl; dump_out << "))" << endl; dump_out << "(check-sat)" << endl; dump_out << "(exit)" << endl; dump_out.close( ); // Check ! tool_res; if ( int pid = fork() ) { int status; waitpid(pid, &status, 0); switch ( WEXITSTATUS( status ) ) { case 0: tool_res = false; break; case 1: tool_res = true; break; default: perror( "Tool" ); exit( EXIT_FAILURE ); } } else { execlp( "tool_wrapper.sh", "tool_wrapper.sh", name, 0 ); perror( "Tool" ); exit( 1 ); } if ( tool_res == true ) opensmt_error2( config.certifying_solver, " says B & I does not hold" ); } }
// // Resolves the PTRef for name s taking into account polymorphism // Creates the term. // Returns PTRef_Undef if the name is not defined anywhere // SymRef PtStore::lookupSymbol(const char* s, const vec<PTRef>& args) { if (symstore.contains(s)) { const vec<SymRef>& trefs = symstore.nameToRef(s); if (symstore[trefs[0]].noScoping()) { // No need to look forward, this is the only possible term // list for (int i = 0; i < trefs.size(); i++) { SymRef ctr = trefs[i]; const Symbol& t = symstore[ctr]; if (t.nargs() == args.size_()) { // t is a potential match. Check that arguments match uint32_t j = 0; for (; j < t.nargs(); j++) { SymRef argt = pta[args[j]].symb(); if (t[j] != symstore[argt].rsort()) break; } if (j == t.nargs()) { // Create / lookup the proper term and return the reference return ctr; } } // The term might still be one of the special cases: // left associative // - requires that the left argument and the return value have the same sort else if (t.left_assoc() && symstore[pta[args[0]].symb()].rsort() == t.rsort()) { int j = 1; for (; j < args.size(); j++) { SymRef argt = pta[args[j]].symb(); if (symstore[argt].rsort() != t[1]) break; } if (j == args.size()) return ctr; } else if (t.right_assoc()) { opensmt_error2("right assoc term not implemented yet", symstore.getName(ctr)); return SymRef_Undef; } else if (t.nargs() < args.size_() && t.chainable()) { opensmt_error2("chainable term not implemented yet", symstore.getName(ctr)); return SymRef_Undef; } else if (t.nargs() < args.size_() && t.pairwise()) { int j = 0; for (; j < args.size(); j++) { SymRef argt = pta[args[j]].symb(); if (symstore[argt].rsort() != t[0]) break; } if (j == args.size()) return ctr; } else return SymRef_Undef; } } } // We get here if it was not in let branches either if (symstore.contains(s)) { const vec<SymRef>& trefs = symstore.nameToRef(s); for (int i = 0; i < trefs.size(); i++) { SymRef ctr = trefs[i]; const Symbol& t = symstore[ctr]; if (t.nargs() == args.size_()) { // t is a potential match. Check that arguments match uint32_t j = 0; for (; j < t.nargs(); j++) { SymRef argt = pta[args[j]].symb(); if (t[j] != symstore[argt].rsort()) break; } if (j == t.nargs()) return ctr; } } } // Not found return SymRef_Undef; }
void MiniSATP::popBacktrackPoint ( ) { // // Force restart, but retain assumptions // cancelUntil(0); // // Shrink back trail // int new_trail_size = undo_trail_size.back( ); undo_trail_size.pop_back( ); for ( int i = trail.size( ) - 1 ; i >= new_trail_size ; i -- ) { Var x = var(trail[i]); assigns[x] = toInt(l_Undef); reason [x] = NULL; insertVarOrder(x); } trail.shrink(trail.size( ) - new_trail_size); assert( trail_lim.size( ) == 0 ); qhead = trail.size( ); // // Undo operations // size_t new_stack_size = undo_stack_size.back( ); undo_stack_size.pop_back( ); while ( undo_stack_oper.size( ) > new_stack_size ) { const oper_t op = undo_stack_oper.back( ); if ( op == NEWVAR ) { #ifdef BUILD_64 long xl = reinterpret_cast< long >( undo_stack_elem.back( ) ); const Var x = static_cast< Var >( xl ); #else const Var x = reinterpret_cast< int >( undo_stack_elem.back( ) ); #endif // Undoes insertVarOrder( ) assert( order_heap.inHeap(x) ); order_heap .remove(x); // Undoes decision_var ... watches decision_var.pop(); polarity .pop(); seen .pop(); activity .pop(); level .pop(); assigns .pop(); reason .pop(); watches .pop(); watches .pop(); } else if ( op == NEWUNIT ) { } else if ( op == NEWCLAUSE ) { Clause * c = (Clause *)undo_stack_elem.back( ); assert( clauses.last( ) == c ); // assert( c->id + 1 == (int)clause_id_to_enode.size( ) ); clauses.pop( ); removeClause( *c ); // clause_id_to_enode.pop_back( ); } else { opensmt_error2( "unknown undo operation in BitBlaster", op ); } undo_stack_oper.pop_back( ); undo_stack_elem.pop_back( ); } while( learnts.size( ) > 0 ) { Clause * c = learnts.last( ); learnts.pop( ); removeClause( *c ); } while( removed.size( ) > 0 ) { Clause * c = removed.last( ); removed.pop( ); free( c ); } assert( undo_stack_elem.size( ) == undo_stack_oper.size( ) ); assert( learnts.size( ) == 0 ); assert( removed.size( ) == 0 ); }