Program to prove logical validity

P

Protoman

I'm writing a program to calc truth tables of arguments to prove that
they are logically valid. Currently, I have to tell the program to
print a truth table, and check it by hand to prove it's valid. I'm
tired of doing this. I need to write a fn that, given three
functions/one function and two variables or anyother combo, run through
all four rows, and determine if it's valid. An argument is invalid iff
any row has true premises and a false conclusion or vice versa.

Here's a truth table for an invalid arg:

Denying the Antecedent T-Table:
A B A->B ~A .:~B
--------------------------------------------------------------
1 1 1 0 0
0 1 1 1 0
1 0 0 0 1
0 0 1 1 1

And here's my code:

//operators.hpp

#pragma once
bool NOT(bool A);
bool AND(bool A,bool B);
bool OR(bool A, bool B);
bool XOR(bool A, bool B);
bool NAND(bool A,bool B);
bool NOR(bool A, bool B);
bool XNOR(bool A, bool B);
bool IF(bool A, bool B);
bool IMP(bool A, bool B);
bool NIF(bool A, bool B);
bool NIMP(bool A, bool B);

//operators.cpp

#include "operators.hpp"

bool NOT(bool A)
{
if(A==true)
return false;
else return true;
}
bool AND(bool A,bool B)
{
if(A==true&&B==true)
return true;
else if(A==false&&B==true)
return false;
else if(A==true&&B==false)
return false;
else return false;
}
bool OR(bool A, bool B)
{
if(A==true&&B==true)
return true;
else if(A==false&&B==true)
return true;
else if(A==true&&B==false)
return true;
else return false;
}
bool XOR(bool A, bool B)
{
if(A==true&&B==true)
return false;
else if(A==false&&B==true)
return true;
else if(A==true&&B==false)
return true;
else return false;
}
bool NAND(bool A,bool B){return NOT(AND(A,B));}
bool NOR(bool A, bool B){return NOT(OR(A,B));}
bool XNOR(bool A, bool B){return NOT(XOR(A,B));}
bool IF(bool A, bool B){return NOT(AND(A,NOT(B)));}
bool IMP(bool A, bool B){return NOT(AND(B,NOT(A)));}
bool NIF(bool A, bool B){return NOT(IF(A,B));}
bool NIMP(bool A, bool B){return NOT(IMP(A,B));}

//main.cpp

#include "operators.hpp"
#include <iostream>
#include <cstdlib>
using namespace std;

int main()
{
bool A=true,B=true;
cout << "A" << " " << "B" << " " << "A->B" <<" " << "A" << ".:B" <<
endl;
cout << "----------------------" << endl;
cout << A << " " << B << " " << IF(A,B) << " " << A << " " << B <<
endl;
A=false;B=true;
cout << A << " " << B << " " << IF(A,B) << " " << A << " " << B <<
endl;
A=true;B=false;
cout << A << " " << B << " " << IF(A,B) << " " << A << " " << B <<
endl;
A=false;B=false;
cout << A << " " << B << " " << IF(A,B) << " " << A << " " << B <<
endl;
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}

Could you please tell me how to write an IsValid fn? Thanks!!!!!!!
 
J

Jim Langston

Protoman said:
I'm writing a program to calc truth tables of arguments to prove that
they are logically valid. Currently, I have to tell the program to
print a truth table, and check it by hand to prove it's valid. I'm
tired of doing this. I need to write a fn that, given three
functions/one function and two variables or anyother combo, run through
all four rows, and determine if it's valid. An argument is invalid iff
any row has true premises and a false conclusion or vice versa.

Here's a truth table for an invalid arg:

Denying the Antecedent T-Table:
A B A->B ~A .:~B
--------------------------------------------------------------
1 1 1 0 0
0 1 1 1 0
1 0 0 0 1
0 0 1 1 1

And here's my code:

//operators.hpp

#pragma once
bool NOT(bool A);
bool AND(bool A,bool B);
bool OR(bool A, bool B);
bool XOR(bool A, bool B);
bool NAND(bool A,bool B);
bool NOR(bool A, bool B);
bool XNOR(bool A, bool B);
bool IF(bool A, bool B);
bool IMP(bool A, bool B);
bool NIF(bool A, bool B);
bool NIMP(bool A, bool B);

//operators.cpp

#include "operators.hpp"

bool NOT(bool A)
{
if(A==true)
return false;
else return true;
}
bool AND(bool A,bool B)
{
if(A==true&&B==true)
return true;
else if(A==false&&B==true)
return false;
else if(A==true&&B==false)
return false;
else return false;
}
bool OR(bool A, bool B)
{
if(A==true&&B==true)
return true;
else if(A==false&&B==true)
return true;
else if(A==true&&B==false)
return true;
else return false;
}
bool XOR(bool A, bool B)
{
if(A==true&&B==true)
return false;
else if(A==false&&B==true)
return true;
else if(A==true&&B==false)
return true;
else return false;
}
bool NAND(bool A,bool B){return NOT(AND(A,B));}
bool NOR(bool A, bool B){return NOT(OR(A,B));}
bool XNOR(bool A, bool B){return NOT(XOR(A,B));}
bool IF(bool A, bool B){return NOT(AND(A,NOT(B)));}
bool IMP(bool A, bool B){return NOT(AND(B,NOT(A)));}
bool NIF(bool A, bool B){return NOT(IF(A,B));}
bool NIMP(bool A, bool B){return NOT(IMP(A,B));}

//main.cpp

#include "operators.hpp"
#include <iostream>
#include <cstdlib>
using namespace std;

int main()
{
bool A=true,B=true;
cout << "A" << " " << "B" << " " << "A->B" <<" " << "A" << ".:B" <<
endl;
cout << "----------------------" << endl;
cout << A << " " << B << " " << IF(A,B) << " " << A << " " << B <<
endl;
A=false;B=true;
cout << A << " " << B << " " << IF(A,B) << " " << A << " " << B <<
endl;
A=true;B=false;
cout << A << " " << B << " " << IF(A,B) << " " << A << " " << B <<
endl;
A=false;B=false;
cout << A << " " << B << " " << IF(A,B) << " " << A << " " << B <<
endl;
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}

Could you please tell me how to write an IsValid fn? Thanks!!!!!!!

I don't understand why you are using functions such as NOT, AND, OR, etc..
Why aren't you using the bool operators ~ & | etc...?

Lets take your function:
bool NOT(bool A)
{
if(A==true)
return false;
else return true;
}

This can be simplified to:

bool NOT( bool A )
{
return !A;
}

and further simplyfied by just using
!A

instead of calling the function.

Anyway, on to your question... You want a function to take a series of
functions and do some logic. Well, all your functions return a bool. So
you might as just well accept bools.

I'm really not sure what you're looking for, though. Is it something like
this?

bool IsValid( bool A, bool B, bool C, bool D )
{
// Do whatever checking you want here and just either
return true;
// or
return false;
}

I *really* don't understand what you are trying to do so can't be more
helpful.
 
P

Protoman

Jim said:
I don't understand why you are using functions such as NOT, AND, OR, etc..
Why aren't you using the bool operators ~ & | etc...?

Lets take your function:
bool NOT(bool A)
{
if(A==true)
return false;
else return true;
}

This can be simplified to:

bool NOT( bool A )
{
return !A;
}

and further simplyfied by just using
!A

instead of calling the function.

Anyway, on to your question... You want a function to take a series of
functions and do some logic. Well, all your functions return a bool. So
you might as just well accept bools.

I'm really not sure what you're looking for, though. Is it something like
this?

bool IsValid( bool A, bool B, bool C, bool D )
{
// Do whatever checking you want here and just either
return true;
// or
return false;
}

I *really* don't understand what you are trying to do so can't be more
helpful.

Take a beginner's course on propositional logic. Find someone from
sci.logic to help us out. And those & | ops are bitwise, not logical.
The reason I made fns for NOT, AND, OR, and XOR is for symmetry. Anyone
else here know how to help? Thanks!!!!!
 
B

Ben Pope

Protoman said:
First, can we try answering the original question?

In all the times you've posted here and been told how to post, you still
cannot.

You have misquoted benben.

IMO what benben wrote is acceptable. IMO what Jim wrote is acceptable.
Yes, | and & are bitwise. You're using bools, how many bits does a
bool represent? Does it matter that the operators are bitwise?

Try reading the FAQ again on how to post. And try using some
indentation in your code.

Ben Pope
 
B

Ben Bacarisse

I'm writing a program to calc truth tables of arguments to prove that they
are logically valid. Currently, I have to tell the program to print a
truth table, and check it by hand to prove it's valid. I'm tired of doing
this. I need to write a fn that, given three functions/one function and
two variables or anyother combo, run through all four rows, and determine
if it's valid. An argument is invalid iff any row has true premises and a
false conclusion or vice versa.

The most general way to do this is by building a data structure to
represent the boolean expressions. The "real" C++ way to build them is as
a set of classes derived from an abstract base class:

class BoolExp {
public:
virtual bool evaluate(bool *vars) = 0;
};

class Var : public BoolExp {
public:
Var(int n) : var_num(n) {}
bool evaluate(bool *vars) { return vars[var_num]; }
private:
int var_num;
};

class NotExp : public BoolExp {
public:
NotExp(BoolExp *e) : exp(e) {}
~NotExp() { delete exp; }
bool evaluate(bool *vars) { return !exp->evaluate(vars); }
protected:
BoolExp *exp;
};

class BinaryExp : public BoolExp {
public:
BinaryExp(BoolExp *e1, BoolExp *e2) : exp1(e1), exp2(e2) {}
~BinaryExp() { delete exp1; delete exp2; }
protected:
BoolExp *exp1, *exp2;
};

class AndExp : public BinaryExp {
public:
AndExp(BoolExp *e1, BoolExp *e2) : BinaryExp(e1, e2) {}
bool evaluate(bool *vars) {
return exp1->evaluate(vars) && exp2->evaluate(vars);
}
};

class OrExp : public BinaryExp {
public:
OrExp(BoolExp *e1, BoolExp *e2) : BinaryExp(e1, e2) {}
bool evaluate(bool *vars) {
return exp1->evaluate(vars) || exp2->evaluate(vars);
}
};

class NandExp : public NotExp {
public:
NandExp(BoolExp *e1, BoolExp *e2) : NotExp(new AndExp(e1, e2)) {}
};

class NorExp : public NotExp {
public:
NorExp(BoolExp *e1, BoolExp *e2) : NotExp(new OrExp(e1, e2)) {}
};

and so on for any other basic terms you want to define. This looks like a
lot of code, but it is mostly syntactic noise required to establish these
very simple classes. You may wan to include shorthand for the variables
you use a lot:

// Shorthands for A, B etc:

class VarA : public Var {
public:
VarA() : Var(0) {}
};

class VarB : public Var {
public:
VarB() : Var(1) {}
};

Now you can write expressions like this:

BoolExp *exp = new AndExp(new NotExp(new VarA), new VarB);

Given an array of values for the variables (2 in this case) like this:

bool values[2] = { 1, 0 };

you can enquire the value of the expression using:

exp->evaluate(values);

I won't go much further, but to test my syntax a wrote a quite function to
tabulate the value of an expression which is very similar to the function
you want to write, so I include it here:

void tabulate(int n_vars, BoolExp *exp)
{
bool increment(int n, bool *bp);

bool *vars = new bool[n_vars];
int i;
for (i = 0; i < n_vars; i++)
vars = 0;
for (i = 0; i < n_vars; i++)
std::cout << " " << char('A' + i);
std::cout << std::endl;
do {
for (int i = 0; i < n_vars; i++)
std::cout << " " << vars;
std::cout << " " << exp->evaluate(vars) << std::endl;
} while (increment(n_vars, vars));
}

bool increment(int n, bool *bp)
{
int i;
for (i = 0; i < n && bp; i++)
bp = 0;
return i < n ? (bp = 1) : 0;
}

Is this getting near your goal?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top