SQL Server Central is supported by Red Gate Software Ltd.
 
Log in  ::  Register  ::  Not logged in
Search:  
 
 

The Truth Table

By Yousef Ekhtiari, 2007/04/19

Total article views: 9675 | Views in the last 30 days: 68

Background

As we all know, we use a logical operator in a WHERE clause. It means each of us are consciously or unconsciously familiar with propositional logic. In propositional logic, we only have two values for each variable: True or False (1 or 0), therefore, any logic statement can be analyzed using a table which lists all possible values of the variable: a Truth Table.

Since each variable can take only two values, a statement with "n" variables requires a table with 2^n rows which is difficult to construct when the number of variables are more than 4.

Truth Table

In this article I will show you how SQL can help to construct the Truth Table. In order to construct the Truth Table I wrote a stored procedure:

 
create PROC Usp_BuildTruthTable ( @variables xml,
                                 @expressions xml)
AS
DECLARE @docHandle int,
        @SELECT varchar(8000),
        @FROM  varchar(8000),
	    @SQL nvarchar(4000)
EXEC sp_xml_preparedocument @docHandle OUTPUT, @variables

SELECT @FROM=isnull( @FROM +char(13)
     +' cross join  (select cast(0 as bit)union all 
	  select cast(1 as bit) ) as '+value+'('+value+')'+char(13) 
	  ,  ' (select cast(0 as bit) union all select  cast( 1 as bit) ) as' 
	  +value+'('+value+')')
FROM OPENXML(@docHandle, N'/Variables/var') 
with (value  char(1)    )
EXEC sp_xml_removedocument @docHandle 

--constructing the Select Clause     
EXEC sp_xml_preparedocument @docHandle OUTPUT, @expressions

SELECT       @SELECT=isnull(@SELECT+' ,['+col+']='+col, '['+col+']='+col)
 FROM OPENXML(@docHandle, N'/expressions/exp') 
WITH (col VARCHAR(8000) '@val')  

    SET @SQL='select *,'+@SELECT+ '  from '+char(13) +@FROM
   EXEC( @SQL)
EXEC sp_xml_removedocument @docHandle 

As you can see it accepts two parameters which are declared as XML data type that is new to SQL Server 2005. If you are not familiar with the XML procedure which I used in the Usp_BuildTruthTable, you can refer to BOL documentations.

The main core of stored procedure is the statement "(select cast(0 as bit)union all select cast(1 as bit) )", which assigns all the possible values to the variables and the CROSS JOIN that is used to produce all possible combinations of variables. The @SELECT will evaluate the expression, and the logic behind this is simple: SQL Server has a bitwise operator, so it can evaluate bitwise expressions. This is the reason that I converted zero and one to the bit data type. There are 4 bitwise operators in SQL SERVER:

Operator Meaning
~ NOT
& AND
| INCLUSIVE OR
^ EXCLUSIVE OR

Now I want to show you how to use these bitwise operators in logical connectives:

Logical operator Expression Bitwise
Not P ~P
And P AND Q P & Q
Inclusive or P OR Q P | Q
Exclusive or P XOR Q P ^ Q
Implies P IMP Q ~P | Q
Equivalence P EQU Q ==( P IMP Q) & (Q IMP P) (~P | Q ) & (~Q | P )

You have to pass variables and expressions with the following format:


<Variables>
<var value="VAR1" />
.
.
.
<var value=" VARn" /> 
</Variables>


<expressions>
<exp val="EXP1" />
.
.
.
<exp val="EXPn" />
</expressions>

Note: you have to use "& amp;" (remove th space between the & and amp) instead of & or else you get the following error:

.Net SqlClient Data Provider: Msg 9421, Level 16, State 1, Procedure Usp_BuildTruthTable, 
Line 0
XML parsing: line 3, character 15, illegal name character

To test the stored procedure, run the following snippet:

exec usp_BuildTruthTable '<Variables> 
<var value="a" /> 
<var value="b" /> 
</Variables>'  ,
'<expressions>
<exp val="~a" />
 <exp val="a & amp; b" />
<exp val="(a | b)" />
<exp val="(a ^ b)" />
<exp val="(~a | b)" />
<exp val="(~a | b)& amp; (~b | a)" />
</expressions>   '

Note: Remove the space between the & and amp in the code.

Here is the result:


a     b     ~a    a & b (a | b) (a ^ b) (~a |b) (~a | b)& (~b | a)
----- ----- ----- ----- ------- ------- ------- ------------------
0     0     1     0     0       0       1       1
0     1     1     0     1       1       1       0
1     0     0     0     1       1       0       0
1     1     0     1     1       0       1       1

Let's check a complicated expression:

((P imp Q) and (Q imp R)) imp (P imp R) == ~ ((~P |Q) & (~Q | R)) | (~P | R)
We have three variables and an expression, so we invoke the stored procedure as follows:

exec usp_BuildTruthTable 
'<Variables>
<var value="P" /> 
<var value="Q" /> 
<var value="R" /> 
</Variables>' ,
'<expressions>
<exp val="~((~p |Q) & amp;  (~Q |R)) | (~P|R)" />
</expressions>   '

And here is the result:


P     Q     R     ~((~p |Q) &  (~Q |R)) | (~P|R)
----- ----- ----- ------------------------------
0     0     0     1
0     1     0     1
1     0     0     1
1     1     0     1
0     0     1     1
0     1     1     1
1     0     1     1
1     1     1     1


you can download the code from here

By Yousef Ekhtiari, 2007/04/19

Total article views: 9675 | Views in the last 30 days: 68
Your response
 
 
Related tags

Advanced Querying    
T-SQL    
 
Already registered?  

Free registration required

To read the rest of this article, and access thousands of other articles, we ask you to register on the site and subscribe to our newsletters.

Register

E-mail address:
Password:
Password (confirm):

  

Subscriptions

We ask you to register on the site and subscribe to our newsletters. Subscribing to our newsletters gets you:

  • ALL of our content (thousands of articles, scripts, and forum postings)
  • A daily newsletter (example)
  • A weekly news round up (example)
  • The opportunity to ask and answer questions in our forums
  • A daily Question of the Day to test and help you increase your knowledge of SQL Server.

We ask that you give the newsletter a try for a week. Over 200,000 SQL Server Professionals a day find it entertaining and useful. If not, you are welcome to unsubscribe at anytime.

Steve Jones
Editor, SQLServerCentral.com