void OpenSMTContext::GetProof( ) { #ifdef PRODUCE_PROOF if ( state == l_False ) solver.printProof( config.getRegularOut( ) ); else opensmt_warning( "Skipping command (get-proof) as formula is not unsat" ); #else opensmt_warning( "Skipping command (get-proof): you need a version of opensmt compiled with --enable-proof" ); #endif }
void SimpSMTSolver::initialize( ) { CoreSMTSolver::initialize( ); #ifdef PRODUCE_PROOF if ( config.sat_preprocess_booleans != 0 || config.sat_preprocess_theory != 0 ) { opensmt_warning( "disabling SATElite preprocessing to track proof" ); use_simplification = false; config.sat_preprocess_booleans = 0; config.sat_preprocess_theory = 0; } #else use_simplification = config.sat_preprocess_booleans != 0; #endif // Add clauses for true/false // Useful for expressing TAtoms that are constantly true/false // const Var var_True = newVar( ); // const Var var_False = newVar( ); // setFrozen( var_True, true ); // setFrozen( var_False, true ); // vec< Lit > clauseTrue, clauseFalse; // clauseTrue.push( Lit( var_True ) ); // addClause( clauseTrue ); // clauseFalse.push( Lit( var_False, true ) ); // addClause( clauseFalse ); // theory_handler = new THandler( egraph, config, *this, trail, level, assigns, var_True, var_False ); }
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 OpenSMTContext::GetInterpolants( ) { #ifdef PRODUCE_PROOF if ( config.produce_inter == 0 ) { opensmt_warning( "Skipping command (get-interpolants) as (produce-interpolants) is not set" ); } else if ( state == l_False ) { solver.printInter( config.getRegularOut( ) ); } else { opensmt_warning( "Skipping command (get-interpolants) as formula is not unsat" ); } #else opensmt_warning( "Skipping command (get-interpolants): you need a version of opensmt compiled with --enable-proof" ); #endif }
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( ); }
// // Main Routine. Examine formula and give it to the solver // lbool Cnfizer::cnfizeAndGiveToSolver( Enode * formula #ifdef PRODUCE_PROOF , const uint64_t partitions #endif ) { #ifdef PRODUCE_PROOF // No partitions assigned ? assert( config.produce_inter == 0 || partitions != 0 ); // Mixed partition assigned ? assert( config.produce_inter == 0 || partitions != 1 ); // Not a power of two ? assert( (partitions & (partitions - 1)) == 0 ); current_partitions = partitions; #endif egraph.initDupMap1( ); assert( formula ); vector< Enode * > top_level_formulae; // Retrieve top-level formulae retrieveTopLevelFormulae( formula, top_level_formulae ); assert( !top_level_formulae.empty( ) ); map< enodeid_t, Enode * > cnf_cache; bool res = true; // For each top-level conjunct for ( unsigned i = 0 ; i < top_level_formulae.size( ) && res ; i ++ ) { Enode * f = top_level_formulae[ i ]; #ifdef PRODUCE_PROOF if ( config.produce_inter != 0 && config.sat_dump_rnd_inter == 0 && !checkCnf( f ) ) opensmt_warning( "Input formula must be in CNF to be correctly interpolated" ); #endif // Give it to the solver if already in CNF if ( checkCnf( f ) ) { res = giveToSolver( f ); } // Check whether it can be rewritten using deMorgan laws else if ( checkDeMorgan( f ) ) { res = deMorganize( f ); } // Otherwise perform cnfization else { map< enodeid_t, int > enodeid_to_incoming_edges; computeIncomingEdges( f, enodeid_to_incoming_edges ); // Compute incoming edges for f and children f = rewriteMaxArity( f, enodeid_to_incoming_edges ); // Rewrite f with maximum arity for operators res = cnfize( f, cnf_cache ); // Perform actual cnfization (implemented in subclasses) } } egraph.doneDupMap1( ); if ( !res ) return l_False; return l_Undef; }
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; }