**Counting Boolean Parenthesis**

Let’s say there is a boolean expression, a string which contains True or False as operands and between each pair of operand we have boolean operator (and, or and xor). An example of a boolean expression is T and F or T xor F. Ask of **boolean parenthesization problem** is to find number of ways in which this boolean expression can be parenthesized so that expression evaluates to True. For example :

Expression : T ^ F & T Two ways : ((T ^ F) & T) and (T ^ (F & T)) T | T & F ^ T Four ways : ((T|T)&(F^T)), (T|(T&(F^T))), (((T|T)&F)^T) and (T|((T&F)^T))

Let’s understand the concept first for solution and then we will see how can we implement it. If we start with an expression with only one boolean value T or F, how many way we can parenthesized it? Well, there are two answers to it. For T, there is one way, (T), whereas for F, there no way we can parenthesize to evaluates True. First take away for this insight is that we got the base case for recursion, if our solution is recursive. Second take away is that there can be two different outputs an expression or subexpression can evaluates and we have to store them both.

if T(i,j) is number of ways expression from i to j can be parenthesized so that it evaluates to True. Similarly, F(i,j) is number of ways expression evaluates to False. From above expression we know that :

T(i,i) = 1 if operand is T 0 if operand is F F(i,i) = 0 if operand is T 1 if operand is F

How to calculate T(i,j)? Let’s try to split this problem into smaller subproblems and reach at base case. If take an index k such that i<k<j, we have two smaller subproblems to solve now, T(i,k) and T(k+1,j). How can solution to these subproblems can be combined to get solution to bigger problem T(i,j). This is tricky part and depends on operator (and, or, xor) after k operand.

If there is “and” operand between two subexpressions (i,k) and (k+1,j) then how can expression (i,j) be True? Yes, only if expression (i,k) and expression (k+1,j) are True. For “and” operator, T(i,j) is:

T(i,j) = Summation ( T(i,k) * T(k+1,j)) for all k such that i < k < j

How about expression (i,j) being evaluates to False? Simple enough, one of the two expression should evaluate to False.

F(i,j) = Sum ( Total (i,j) - T(i,k)* T(k+1)) for all k for i< k< j

What is Total(i,j) here?

Total(i,j) = Total(i,k) * Total( k+1, j) ) Total(i,k) = T(i,k) + F(i,k) Total(k+1,j) = T(k+1,j) + F(k+1,j) In short, Total(i,j) = T(i,j) + F(i,j)

When operand between (i,k) and (k+1, j) is or:

T(i,j) = sum ( Total(i,j) - F(i,k)* F(k+1,j)) for k such i<k<j F(i,j) = sum ( F(i,k) * F(k+1, j)) for k such that i<k<j

In the same vein, T(i,j) and F(i,j) when operand is xor will be

T(i,j) = sum(T(i,k)*F(k+1,j) + F(i,k)* T(k+1,j)) for k such i<k<j F(i,j) = sum(T(i,k) * T(k+1,j) + F(i,k)*F(k+1,j)) for k such that i<k<j

To find solution to problem all we need to find is T(1,n). Now, let’s see how to implement the approach.

**Dynamic programming implementation for boolean parenthesization problem**

We will have two strings, one string operands[] represents all operands (T or F) and other string operations[] representing all operator (‘&’, ‘|’ , ‘^’). Operands[i] is inserted at operands[i+1] to generates the expression. Below is the code which uses this definition and provides implementation of method discussed earlier.

#include<stdio.h> #include<string.h> int countNumberOfWaysToParenthesize(char operands[], char operators[], int n){ int F[n][n], T[n][n]; for (int i=0; i<n; i++){ F[i][i] = (operands[i] == 'F')? 1: 0; T[i][i] = (operands[i] == 'T')? 1: 0; } for (int L=1; L<n; L++) { for (int i=0, j=L; j<n; ++i, ++j){ T[i][j] = F[i][j] = 0; for (int count=0; count<L; count++){ int k = i + count; int totalIK = T[i][k] + F[i][k]; int totalKJ = T[k+1][j] + F[k+1][j]; if (operators[k] == '&') { T[i][j] += T[i][k]*T[k+1][j]; F[i][j] += (totalIK *totalKJ - T[i][k]*T[k+1][j]); } if (operators[k] == '|'){ F[i][j] += F[i][k]*F[k+1][j]; T[i][j] += (totalIK*totalKJ - F[i][k]*F[k+1][j]); } if (operators[k] == '^'){ T[i][j] += F[i][k]*T[k+1][j] + T[i][k]*F[k+1][j]; F[i][j] += T[i][k]*T[k+1][j] + F[i][k]*F[k+1][j]; } } } } return T[0][n-1]; } int main(){ char operands[] = "TTFT"; char operators[] = "|&^"; int n = strlen(operands); printf ("\n Number of ways to parenthesize expression : %d", countNumberOfWaysToParenthesize(operands, operators, n)); return 0; }

Complexity of this approach to find ways to parenthesize a boolean expression so that it evaluates to True is O(n^{3}). There is also O(n^{2}) space complexity.

Please share if there is something missing or wrong. If you want to contribute to algorithms and me, please contact us.

Pingback: Matrix chain multiplication problem - Algorithms and Me()