Are they consistent?

A. The problem:

    R: "It is raining."

    S: "It is snowing."

    I: "I get ill."

    W: "I get wet."

    D: "I need a doctor."

    H: "It is hot."

    F: "I have a fevor."

    Now I give you some facts which can be regarded as a collection of rules:

    1) ~R|W      (R->W)   If it is raining, then I get wet.

    2)  R|W      (~R->S)  If it is not raining, then it is snowing.

    3)  ~R|~S    (R->~S)   If it is raining, then it is not snowing.

    4)  ~S|~H     (S->~H)  If it is snowing, then it is not hot.

    5)  ~W|H|I    (  W->(H|I)   )  If it is wet, then it is either hot or I get ill.

    6)  ~I|~F|D   (I-> (~F|D) )  If I get ill, then I either don't have a fever or need a doctor.

    7)  F|~D      (  ~F->~D )  If I do not have a fever, then I don't need a doctor. 

    8)  ~S|~H     (  S->~H   ) If it is snowing, then it is not hot.

    9)  ~I|H|D    (  I->(H|D)  ) If I get ill then it is either hot or I need a doctor.

    10) H|~I|~W|F  ( (I&&W)->(H|F)) If I get both wet and ill then it is either hot 

                                or I have a fever.

    Suppose we have following facts:

    1)  R    2)~H

    Can we make conclusion that D?

    or in other words that suppose "it is raining" and "it is not hot", can we conclude that 

    "I need  a doctor"?

    The answer is NO! And the program outcome proves that.This wrong!

   The answer is YES! And the program outcome proves that. The problem is that I missed a input in checking function 6---"D".

so the correct outcome is here.

B.Second Edition
This is the second edition of my Logic class, I only write a simple test program to check if a collection of
propositions are in consistent or in other words if there is a proper truth value for each proposition to 
satisfy all propositions.
1¡£ Basic idea: It is quite streight forward to test all possible combination of truth value of all propostions.
2¡£ Program design: I make all seven facts to be seven Logic class objects and assign them all possible 
combinations of truth values by a "setupFacts()" function, then for each "state", I use 10 rule-checking functions
to check if the truth value can satisfy all rules. If no combination can satisfy all rule function, it proves no 
solution and as I make a assumption of the conclusion "D is true", then it means "if D is true, no combination 
to satisfy all rules". So "D cannot be true."
3¡£ Major function£º
     A. bool setupFacts();    bool checkConsistent()	
	setupFacts() function is like a "slot machine" which gives all truth value combination to the Facts[7].
	And later by function "checkConsistent()" assign all these truth values to element[7] which are 7 Logic 
	class objects. Please before call "checkConsistent()", I use 3 bool variable to store the "predefined"
	truth value of "R, H, D".	  
	B. void prepare()
	This function is a painful choice, as I mentioned in last version that I made a new Logic objects whenever
	there is an operation. For example: (element[D])&&(element[F])||(element[H]); each operation will create
	a new temperary object and this is also the return value to make further operation. However, I record all
	these objects in a private static array---static Logic* temp[100]. And 100 is not enough for this simple 
	program. Even 1000 is not enough! So you see there are too many in-process objects, I have to clear them 
	every time I start a new "rule checking".¡¡
4¡£ Further improvement£º
	A. It is still a painful compromise for me to use temperary objects for return value of each operation.
	B. For a time, I made up my mind to use object itself for return value, however, it changes expression of
	itself which is not good.
	
		
#include <iostream>
using namespace std;
enum LogicOp
{AND, OR, NOT, CONDITIONAL};
const ElementNum = 7;
char* OpStr[4] = {" AND ", " OR ", " NOT "," CONDITIONAL "};
enum ELEMENT
{R,S,I,W,D,H,F};
char* factStr[7] = 
	{"It is raining", "It is snowing", "I get ill","I get wet", "I need doctor",
	"It is hot", "I have a fevor"};
bool Facts[ElementNum] = {false};
class Logic
{
private:
	static bool status;
	static int logicCount;
	char* express;
	int index;
	bool state;
	void catName(char*, const char*, LogicOp); 
	static Logic* temp[100];
	static int tempCount;
	static Logic* TRUE;
	static Logic* FALSE;
	Logic* checkList[30];
	bool definedStatus;
protected:
	void initialize();
	bool compare(const Logic& dummy);
	void uninitialize();
public:
	Logic(const char* newExpress, const bool value=false);
	~Logic();
	Logic();
	void prepare();
	bool getStatus() const {return definedStatus;}
	void setStatus(const bool newStatus) {definedStatus = newStatus;}
	void setExpress(const char*);
	char* getExpress() const {return express;}
	void setIndex(const int newIndex) { index = newIndex;}
	int getIndex() const {return index;}
	void setState(bool newState) { state = newState;}
	bool getState() const{ return state;}
	static const int count()  {return logicCount;}
	Logic& operator&&(const Logic& dummy);
	Logic& operator||(const Logic& dummy);
	Logic& operator!();
	bool operator==(const Logic& dummy);
	Logic& operator&&(const bool value);
	Logic& operator||(const bool value);	
	Logic& operator=(const Logic& dummy);
	Logic& operator>>(const Logic& dummy);
	void addRule(const Logic* rule);
};
Logic element[ElementNum];
bool setupFacts();
void setFactStr();
bool checkConsistent();
Logic& check1();
Logic& check2();
Logic& check3();
Logic& check4();
Logic& check5();
Logic& check6();
Logic& check7();
Logic& check8();
Logic& check9();
Logic& check10();
Logic& (* checkLists[10])() = {check1, check2, check3, check4, check5, check6,
	check7, check8, check9, check10};
void displayResult();
int main()
{
	setFactStr();
	if (!setupFacts())
		cout<<"no hope\n";	
	return 0;
}
void displayResult()
{
	for (int i=0; i<ElementNum; i++)
	{
		cout<<"\n"<<factStr[i]<<" is "<<(Facts[i]?"true":"false")<<endl;
	}
	for (i=0; i< 10; i++)
	{
		cout<<((Logic&)(checkLists[i]())).getExpress()<<" is true\n";
	}
}
void setFactStr()
{
	for (int i=0; i< ElementNum; i++)
	{
		element[i].setExpress(factStr[i]);
	}
}
Logic& check1()
{
	return (!element[R])||(element[W]);
}
Logic& check2()
{
	return (element[R])||(element[S]);
}
Logic& check3()
{
	return (!element[R])||(!element[S]);
}
Logic& check4()
{
	return (!element[S])||(!element[H]);
}
Logic& check5()
{
	return (!element[W])||(element[H])||(element[I]);
}
Logic& check6()
{
	return (!element[I])||(!element[F])||(element[D]); //this is reason of error in last time.
}
Logic& check7()
{
	return (element[F])||(!element[D]);
}
Logic& check8()
{
	return (!element[S])||(!element[H]);
}
Logic& check9()
{
	return (!element[I])||(element[H])||(element[D]);
}
Logic& check10()
{
	return (element[H])||(!element[I])||(!element[W])||(element[F]);
}
bool checkConsistent()
{
		
	for (int i =0; i< ElementNum; i++)
	{
		element[i].setState(Facts[i]);
	}
	for (int j=0; j<10; j++)
	{
		element[0].prepare();
		if (!((checkLists[j]()).getState()))
		{
			return false;
		}
	}
	return true;
}

bool setupFacts()
{
	bool rec1, rec2, rec3;
	int i=0;
	while (i<ElementNum)
	{
		Facts[i] = !Facts[i];
		while(!Facts[i])
		{
			i++;
			if (i == ElementNum)
			{
				return false;
			}
			Facts[i] = !Facts[i];
		}
		
		rec1 = Facts[R];
		rec2 = Facts[H];
		rec3 = Facts[D];
		Facts[R] = true;
		Facts[H] = false;
		Facts[D] = true;
		if (checkConsistent())
		{
			displayResult();
			//return true;
		}
		Facts[R] = rec1;
		Facts[H] = rec2;
		Facts[D] = rec3;
		i=0;
	}
	return false;
}
void Logic::prepare()
{
	for (int i=0; i< tempCount; i++)
	{
		free(temp[i]);
	}
	tempCount =0;
}

Logic& Logic::operator >>(const Logic& dummy)
{
	char buffer[256];
	catName(buffer, dummy.getExpress(), CONDITIONAL);
	temp[tempCount] = new Logic(buffer);
	if (state&&(!dummy.getState()))
	{
		temp[tempCount]->setState(false);
	}
	else
	{
		temp[tempCount]->setState(true);
	}
	tempCount++;
	return *temp[tempCount-1];	
	/*
	temp->setExpress(buffer);
	if (state&&(!dummy.getState()))
	{
		temp->setState(false);
	}
	else
	{
		temp->setState(true);
	}
	return *this;
	*/
}
void Logic::uninitialize()
{
	status = true;
	
	for (int i=0; i< tempCount;i++)
	{
		delete temp[i];
	}
}
bool Logic::status = false;
Logic* Logic::temp[100] = {NULL}; // = new Logic;
int Logic::tempCount = 0;
Logic* Logic::FALSE = new Logic("FALSE", false);
Logic& Logic::operator =(const Logic& dummy)
{
	setExpress(dummy.getExpress());
	setState(dummy.getState());
	return *this;
}
Logic* Logic::TRUE = new Logic("TRUE", true);;
Logic& Logic::operator &&(const bool value)
{
	if (value)
	{
		return (*this)&&(*TRUE);
	}
	else
	{
		return (*this)&&(*FALSE);
	}
}
Logic& Logic::operator ||(const bool value)
{
	if (value)
	{
		return (*this)||(*TRUE);
	}
	else
	{
		return (*this)||(*FALSE);
	}
}
bool Logic::operator ==(const Logic& dummy)
{
	return compare(dummy);
}
bool Logic::compare(const Logic& dummy)
{
	return (index==dummy.getIndex());
}
void Logic::catName(char* buffer, const char* second, LogicOp opcode)
{	
	strcpy(buffer, getExpress());
	strcat(buffer, OpStr[opcode]);
	strcat(buffer, second);
}
Logic& Logic::operator !()
{
	char buffer[256];
	strcpy(buffer, OpStr[NOT]);
	strcat(buffer, getExpress());
	/*
	temp->setExpress(buffer);
	temp->setState(!getState());
	return *this;
	*/
	temp[tempCount] = new Logic(buffer);
	temp[tempCount]->setState(!getState());
	tempCount++;
	return *temp[tempCount-1];	
}
Logic& Logic::operator &&(const Logic& dummy)
{
	char buffer[256];
	catName(buffer, dummy.getExpress(), AND);
	temp[tempCount] = new Logic(buffer);
	temp[tempCount]->setState(getState()&&dummy.getState());
	tempCount++;
	return *temp[tempCount-1];
	
		/*
	temp->setExpress(buffer);
	temp->setState(getState()&&dummy.getState());
	return *this;
*/
}
Logic& Logic::operator ||(const Logic& dummy)
{
	char buffer[256];
	catName(buffer, dummy.getExpress(), OR);
	
	temp[tempCount] = new Logic(buffer);
	temp[tempCount]->setState(getState()||dummy.getState());
	tempCount++;
	return *temp[tempCount-1];
		/*
	temp->setExpress(buffer);
	temp->setState(getState()||dummy.getState());
	return *this;
		*/
}
int Logic::logicCount =0;
void Logic::initialize()
{
	express = NULL;
	state = false;
	definedStatus = false;
	setIndex(logicCount);
	logicCount++;
}
Logic::~Logic()
{
	if (!status)  //if you destroy one, then you destroy all!!!!!
	{
		uninitialize();
	}
	if (express!=NULL)
	{
		free(express);
	}
}
Logic::Logic(const char* newExpress, const bool value)
{
	initialize();
	setExpress(newExpress);
	setState(value);
}
Logic::Logic()
{
	initialize();
}
void Logic::setExpress(const char* newExpress)
{
	int i;
	i = strlen(newExpress) +1;
	if (express==NULL)
	{	
		express = (char*)malloc(i);		
	}
	else
	{
		express = (char*)realloc((void*)express, i);
	}
	strcpy(express, newExpress);
}
¡¡
	

                                                         back.gif (341 bytes)       up.gif (335 bytes)         next.gif (337 bytes)

Hosted by www.Geocities.ws

1