int DPLL_propagate_binary_equivalence( const int bieq ) { int i, j, ceqsubst; int lit1, lit2; int value; lit1 = Ceq[ bieq ][ 0 ]; lit2 = Ceq[ bieq ][ 1 ]; value = CeqValues[ bieq ]; for( i = 1; i < Veq[ lit1 ][ 0 ]; i++ ) { ceqsubst = Veq[ lit1 ][ i ]; for( j = 1; j < Veq[ lit2 ][ 0 ]; j++ ) { if( (ceqsubst == Veq[ lit2 ][ j ]) ) { fixEq( lit1, i, 1); PUSH( sub, lit1 ); fixEq( lit2, j, value); PUSH( sub, lit2 * value ); if( CeqSizes[ ceqsubst ] == 0 ) if (CeqValues[ ceqsubst ] == -1 ) return UNSAT; if( CeqSizes[ ceqsubst ] == 1 ) if( !look_fix_binary_implications(Ceq[ceqsubst][0] * CeqValues[ceqsubst]) ) return UNSAT; if( CeqSizes[ ceqsubst ] == 2 ) PUSH( newbi, ceqsubst ); i--; break; } } } if( (DPLL_add_binary_implications( lit1, -lit2 * value ) && DPLL_add_binary_implications( -lit1, lit2 * value )) == UNSAT ) return UNSAT; return SAT; }
inline int DPLL_update_datastructures( const int nrval ) { int i, *bImp; #ifdef EQ int nr, ceqidx; nr = NR( nrval ); PUSH( sub, STACK_BLOCK ); #endif // printf("FIXING %i\n", nrval ); FIX( nrval, NARY_MAX ); // diff[ nrval ] = 0; // diff[ -nrval ] = 0; #ifdef TIMEOUT if( (int) clock() > CLOCKS_PER_SEC * TIMEOUT ) return SAT; #endif unitResolveCount++; reduce_freevars( nrval ); bImp = BIMP_START(-nrval); for( i = BIMP_ELEMENTS; --i; ) bImp_satisfied[ -(*(bImp++)) ]++; // Update eager datastructures if( kSAT_flag == 0 ) { #ifdef GLOBAL_AUTARKY int lit1, lit2; int *tImp = TernaryImp[ nrval ] + 2 * TernaryImpSize[ nrval ]; for( i = TernaryImpLast[ nrval ] - TernaryImpSize[ nrval ]; i--; ) { lit1 = *(tImp++); lit2 = *(tImp++); if( IS_REDUCED_TIMP( lit1, lit2 ) ) TernaryImpReduction[ lit1 ]--; else if( IS_REDUCED_TIMP( lit2, lit1 ) ) TernaryImpReduction[ lit2 ]--; } #endif remove_satisfied_implications( nrval ); remove_satisfied_implications( -nrval ); #ifdef GLOBAL_AUTARKY tImp = TernaryImp[ -nrval ]; for( i = tmpTernaryImpSize[ -nrval ]; i--; ) { TernaryImpReduction[ *(tImp++) ]++; TernaryImpReduction[ *(tImp++) ]++; } #endif } else { int *clauseSet, clause_index; // REMOVE SATISFIED CLAUSES clauseSet = clause_set[ nrval ]; while( *clauseSet != LAST_CLAUSE ) { clause_index = *(clauseSet++); // if clause is not satisfied if( clause_length[ clause_index ] < SAT_INCREASE - 2 ) { #ifdef GLOBAL_AUTARKY // if clause is already been reduced if( clause_reduction[ clause_index ] > 0 ) { int *literals = clause_list[ clause_index ]; while( *literals != LAST_LITERAL ) TernaryImpReduction[ *(literals++) ]--; } clause_SAT_flag[ clause_index ] = 1; #endif reduce_big_occurences( clause_index, nrval ); } clause_length[ clause_index ] += SAT_INCREASE; } #ifdef GLOBAL_AUTARKY for( i = 0; i < btb_size[ nrval ]; ++i ) { // decrease literal reduction int *literals = clause_list[ big_to_binary[ nrval ][ i ] ], flag = 0; while( *literals != LAST_LITERAL ) { if( timeAssignments[ *(literals++) ] == NARY_MAX ) { if( flag == 1 ) { flag = 0; break; } flag = 1; } } if( flag == 1 ) { clause_SAT_flag[ big_to_binary[ nrval ][ i ] ] = 1; literals = clause_list[ big_to_binary[ nrval ][ i ] ]; while( *literals != LAST_LITERAL ) TernaryImpReduction[ *(literals++) ]--; } } #endif } #ifdef GLOBAL_AUTARKY #ifdef EQ tmpEqImpSize[ nr ] = Veq[ nr ][ 0 ]; for( i = 1; i < Veq[ nr ][0]; i++ ) { int j; ceqidx = Veq[ nr ][i]; for( j = 0; j < CeqSizes[ ceqidx ]; j++ ) TernaryImpReduction[ Ceq[ceqidx][j] ]++; } #endif #endif if( kSAT_flag ) { int UNSAT_flag, *clauseSet, clause_index; int first_lit, *literals, lit; // REMOVE UNSATISFIED LITERALS UNSAT_flag = 0; clauseSet = clause_set[ -nrval ]; while( *clauseSet != LAST_CLAUSE ) { clause_index = *(clauseSet++); #ifdef GLOBAL_AUTARKY // if clause is for the first time reduced if( clause_reduction[ clause_index ] == 0 ) { int *literals = clause_list[ clause_index ]; while( *literals != LAST_LITERAL ) TernaryImpReduction[ *(literals++) ]++; clause_red_depth[ clause_index ] = depth; } clause_reduction[ clause_index ]++; #endif clause_length[ clause_index ]--; #ifdef HIDIFF HiRemoveLiteral( clause_index, nrval ); #endif if( clause_length[ clause_index ] == 2 ) { #ifdef GLOBAL_AUTARKY literals = clause_list[ clause_index ]; while( *literals != LAST_LITERAL ) { lit = *(literals)++; if( timeAssignments[ lit ] < NARY_MAX ) big_to_binary[ lit ][ btb_size[ lit ]++ ] = clause_index; } #endif reduce_big_occurences( clause_index, -nrval ); clause_length[ clause_index ] = SAT_INCREASE; if( UNSAT_flag == 0 ) { first_lit = 0; literals = clause_list[ clause_index ]; while( *literals != LAST_LITERAL ) { lit = *(literals)++; if( IS_NOT_FIXED( lit ) ) { if( first_lit == 0 ) first_lit = lit; else { UNSAT_flag = !DPLL_add_binary_implications( first_lit, lit ); goto next_clause; } } else if( !FIXED_ON_COMPLEMENT(lit) ) goto next_clause; } if( first_lit != 0 ) UNSAT_flag = !look_fix_binary_implications( first_lit ); else UNSAT_flag = 1; } next_clause:; } } if( UNSAT_flag ) return UNSAT; } if( kSAT_flag == 0 ) { int *tImp = TernaryImp[ -nrval ]; for( i = tmpTernaryImpSize[ -nrval ] - 1; i >= 0; i-- ) { int lit1 = *(tImp++); int lit2 = *(tImp++); if( DPLL_add_binary_implications( lit1, lit2 ) == UNSAT ) return UNSAT; } } #ifdef EQ while( Veq[ nr ][ 0 ] > 1 ) { ceqidx = Veq[ nr ][ 1 ]; fixEq( nr, 1, SGN(nrval)); PUSH( sub, nrval ); if( CeqSizes[ ceqidx ] == 2 ) { if ( DPLL_propagate_binary_equivalence( ceqidx ) == UNSAT ) return UNSAT; } else if( CeqSizes[ ceqidx ] == 1 ) { if( look_fix_binary_implications(Ceq[ceqidx][0]*CeqValues[ceqidx]) == UNSAT ) return UNSAT; } } while( newbistackp != newbistack ) { POP( newbi, ceqidx ); if( CeqSizes[ ceqidx ] == 2 ) if ( DPLL_propagate_binary_equivalence( ceqidx ) == UNSAT ) return UNSAT; } #endif return SAT; }
/* MALLOCS: _Vc, _Vc[], _VcTemp REALLOCS: - FREES: _VcTemp, _Vc[ * ], _Vc */ int propagate_unary_clauses() { int i, j, nrval, clsidx, *_simplify_stackp; int **_variableArray; _simplify_stackp = simplify_stack; allocateSmallVc( &_variableArray , 1 ); _variableArray += nrofvars; /* fix monotone variables that do not occur in equivalence clauses */ #ifdef FIX_MONOTONE for( i = 1; i <= nrofvars; i++ ) if( Veq[ i ][ 0 ] == 1 ) { if( (_variableArray[ i ][ 0 ] == 0) && (_variableArray[ -i ][ 0 ] > 0) ) { PUSH_PARSER_NA( -i ); } else if( (_variableArray[ i ][ 0 ] > 0) && (_variableArray[ -i ][ 0 ] == 0) ) { PUSH_PARSER_NA( i ); } } #endif while( _simplify_stackp < simplify_stackp ) { nrval = *( _simplify_stackp++ ); freevars--; /* All clauses containing nrval are satisfied. They are removed from the CNF by setting Clength = 0. */ for( i = 1; i <= _variableArray[ nrval ][ 0 ] ; i++ ) Clength[ _variableArray[ nrval ][ i ] ] = 0; /* All clauses containing ~nrval are shortened by removing ~nrval from the clause. If this operation results in a unary clause, then this clause is removed from the CNF by setting Clength = 0 and the literal is pushed on the fix stack to be fixed later. */ for( i = 1; i <= _variableArray[ -nrval ][ 0 ]; i++ ) { clsidx = _variableArray[ -nrval ][ i ]; for( j = 0; j < Clength[ clsidx ]; j++ ) { if( Cv[ clsidx ][ j ] == -nrval ) { /* Swap literal to the front of the clause. */ Cv[ clsidx ][ j-- ] = Cv[ clsidx ][ --( Clength[ clsidx ] ) ]; if( Clength[ clsidx ] == 1 ) { PUSH_PARSER_NA( Cv[ clsidx ][ 0 ] ); Clength[ clsidx ] = 0; } } } } while( Veq[ NR(nrval) ][ 0 ] > 1 ) { clsidx = Veq[ NR(nrval) ][ 1 ]; fixEq( NR(nrval), 1, SGN(nrval)); if( CeqSizes[ clsidx ] == 1 ) { PUSH_PARSER_NA( Ceq[ clsidx ][ 0 ] * CeqValues[ clsidx ] ); } } } /* Free temporary allocated space. */ _variableArray -= nrofvars; freeSmallVc( _variableArray ); return 1; }