2 | C ++ implementation to find if the given expression is satisfiable using the Kosaraju 's Algorithm ; data structures used to implement Kosaraju 's Algorithm. Please refer http:www.geeksforgeeks.org/strongly-connected-components/ ; this array will store the SCC that the particular node belongs to ; counter maintains the number of the SCC ; adds edges to form the original graph ; add edges to form the inverse graph ; for STEP 1 of Kosaraju 's Algorithm ; for STEP 2 of Kosaraju 's Algorithm ; function to check 2 - Satisfiability ; adding edges to the graph ; variable x is mapped to x variable - x is mapped to n + x = n - ( - x ) for a [ i ] or b [ i ] , addEdges - a [ i ] -> b [ i ] AND - b [ i ] -> a [ i ] ; STEP 1 of Kosaraju 's Algorithm which  traverses the original graph ; STEP 2 pf Kosaraju 's Algorithm which  traverses the inverse graph. After this,  array scc[] stores the corresponding value ; for any 2 vairable x and - x lie in same SCC ; no such variables x and - x exist which lie in same SCC ; Driver function to test above functions ; n is the number of variables 2 n is the total number of nodes m is the number of clauses ; each clause is of the form a or b for m clauses , we have a [ m ] , b [ m ] representing a [ i ] or b [ i ] Note : 1 <= x <= N for an uncomplemented variable x - N <= x <= - 1 for a complemented variable x - x is the complement of a variable x The CNF being handled is : ' + ' implies ' OR ' and ' * ' implies ' AND ' ( x1 + x2 ) * ( x2 + x3 ) * ( x1 + x2 ) * ( x3 + x4 ) * ( x3 + x5 ) * ( x4 + x5 ) * ( x3 + x4 ) ; We have considered the same example for which Implication Graph was made
#include <bits/stdc++.h> NEW_LINE using namespace std ; const int MAX = 100000 ; vector < int > adj [ MAX ] ; vector < int > adjInv [ MAX ] ; bool visited [ MAX ] ; bool visitedInv [ MAX ] ; stack < int > s ; int scc [ MAX ] ; int counter = 1 ; void addEdges ( int a , int b ) { adj [ a ] . push_back ( b ) ; } void addEdgesInverse ( int a , int b ) { adjInv [ b ] . push_back ( a ) ; } void dfsFirst ( int u ) { if ( visited [ u ] ) return ; visited [ u ] = 1 ; for ( int i = 0 ; i < adj [ u ] . size ( ) ; i ++ ) dfsFirst ( adj [ u ] [ i ] ) ; s . push ( u ) ; } void dfsSecond ( int u ) { if ( visitedInv [ u ] ) return ; visitedInv [ u ] = 1 ; for ( int i = 0 ; i < adjInv [ u ] . size ( ) ; i ++ ) dfsSecond ( adjInv [ u ] [ i ] ) ; scc [ u ] = counter ; } void is2Satisfiable ( int n , int m , int a [ ] , int b [ ] ) { for ( int i = 0 ; i < m ; i ++ ) { if ( a [ i ] > 0 && b [ i ] > 0 ) { addEdges ( a [ i ] + n , b [ i ] ) ; addEdgesInverse ( a [ i ] + n , b [ i ] ) ; addEdges ( b [ i ] + n , a [ i ] ) ; addEdgesInverse ( b [ i ] + n , a [ i ] ) ; } else if ( a [ i ] > 0 && b [ i ] < 0 ) { addEdges ( a [ i ] + n , n - b [ i ] ) ; addEdgesInverse ( a [ i ] + n , n - b [ i ] ) ; addEdges ( - b [ i ] , a [ i ] ) ; addEdgesInverse ( - b [ i ] , a [ i ] ) ; } else if ( a [ i ] < 0 && b [ i ] > 0 ) { addEdges ( - a [ i ] , b [ i ] ) ; addEdgesInverse ( - a [ i ] , b [ i ] ) ; addEdges ( b [ i ] + n , n - a [ i ] ) ; addEdgesInverse ( b [ i ] + n , n - a [ i ] ) ; } else { addEdges ( - a [ i ] , n - b [ i ] ) ; addEdgesInverse ( - a [ i ] , n - b [ i ] ) ; addEdges ( - b [ i ] , n - a [ i ] ) ; addEdgesInverse ( - b [ i ] , n - a [ i ] ) ; } } for ( int i = 1 ; i <= 2 * n ; i ++ ) if ( ! visited [ i ] ) dfsFirst ( i ) ; while ( ! s . empty ( ) ) { int n = s . top ( ) ; s . pop ( ) ; if ( ! visitedInv [ n ] ) { dfsSecond ( n ) ; counter ++ ; } } for ( int i = 1 ; i <= n ; i ++ ) { if ( scc [ i ] == scc [ i + n ] ) { cout << " The ▁ given ▁ expression ▁ " " is ▁ unsatisfiable . " << endl ; return ; } } cout << " The ▁ given ▁ expression ▁ is ▁ satisfiable . " << endl ; return ; } int main ( ) { int n = 5 , m = 7 ; int a [ ] = { 1 , -2 , -1 , 3 , -3 , -4 , -3 } ; int b [ ] = { 2 , 3 , -2 , 4 , 5 , -5 , 4 } ; is2Satisfiable ( n , m , a , b ) ; return 0 ; }