用逻辑类所作的一个反证法的实例

原创 2003年04月24日 08:53:00

      Power Logic Applications

http://www3.sympatico.ca/qingzhehuang/LogicApp.htm

This is actually Fourth( Really? I don't remember clearly and who cares?) edition of my logic class. And it would be
more precise to call it an application. However, there is indeed some improvement with little code added but 
powerful function achieved!( Really? I guess I won't believe what I said myself.)
I made little improvement to try to solve an logic proof in COMP238 sample test in other section. The problem is
like following:
p,q,r,s,t are all propositional functions. And the problem suggests a proof by contradiction. Indeed, if you
don't go this way, it is quite difficult, at least very tedious. 
I changed my major function "doAnalysing()" a little bit by adding a parameter of bool byContradiction to make
it look like "void doAnalysing(bool byContradiction = false)". So, when you want to prove by contradiction, 
simply pass a true parameter instead the default false parameter. Then in the implementation of the original 
function, I only compare the in-passing parameter and change the last result to be false to begin an analysing
if it is "proof by contradiction". That is it.
However, at first the program doesn't give correct outcome except only show that "t is false and all other is
unknown". This is quite normal as when program pass only once in formula, it won't make full use of newly-deducted
result of "t is false". How to make program to invoke new result as long as he gets it? Simply redo when there is
new discovery. That is what I did in changing the function "analysing" of class "Analyse". I simply add a 
recursive call of itself when "readStack()" return true which means the program did find new value and change it.
Originally I am so clever to write this "readStack()" as bool-return function. Now it proves it is worth the 
efforts!
   A. 
	Keep finding the  type in OpRec(the stack) and call "readStack", doing the analysing. Have to  for 
	next expression checking. 
.
(want to know more about Logic and Analyse class function? click here to see Power Logic.)
Once our great leader Chairman Mao taught us that "theory cannot be tested and developed unless it is combined with practice".
So, all the program I wrote needs to be put into practice to get qualified and developed.	
#include <iostream>

using namespace std;

const int StackLimit = 150;

enum LogicOp
{AND, OR, NOT, CONDITIONAL};

enum OpState
{Operand, Operator, Result};

enum LogicState
{Positive =1, Possible =0, Negative =-1};

bool operator == (LogicState self, LogicState dummy)
{
	return ((self - dummy) == 0);
}

//forward declaration
class Analyse;

char* OpStr[4] = {" AND ", " OR ", " NOT "," CONDITIONAL "};

class Logic
{
private:
	static Analyse* analyse;
	static bool status;
	static int logicCount;
	char* express;
	int index;
	LogicState state;
	void catName(char*, const char*, LogicOp); 
	static Logic* temp[100];
	static int tempCount;
	static Logic* TRUE;
	static Logic* FALSE;
	bool definedStatus;
	LogicState And(LogicState self, LogicState dummy);
	LogicState Or(LogicState self, LogicState dummy);
	LogicState Not(LogicState self);
	void pushStack(const Logic* self, const Logic* pDummy, LogicOp opCode); 
	Logic* getTemp() { return temp[tempCount -1];}
protected:
	void initialize();
	bool compare(const Logic& dummy);
	void uninitialize();
public:
	Analyse* getAnalyse();
	Logic(const char* newExpress, const LogicState value=Possible);
	~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(LogicState newState) { state = newState;}
	LogicState getState() const{ return state;}
	static const int count()  {return logicCount;}
	Logic& operator&&(Logic& dummy);
	Logic& operator||(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>>(Logic& dummy);
	void doAnalysing(bool byContradiction = false); 
	
};

union UNKNOWN
{
	LogicOp operator = (LogicOp dummy);
	Logic* operator = (const Logic* dummy);
	Logic* logic;
	LogicOp op;
};

struct OpRec
{
	OpState opType;
	union UNKNOWN unknown;
};


Logic* UNKNOWN::operator =(const Logic* dummy)
{
	logic = (Logic*)dummy;
	return logic;
}

LogicOp UNKNOWN::operator = (LogicOp dummy)
{
	op = dummy;
	return op;
}

class Analyse
{
private:
	bool analyAnd(Logic* op1, Logic* op2, Logic* result);
	bool analyOr(Logic* op1, Logic* op2, Logic* result);
	bool analyConditional(Logic* op1, Logic* op2, Logic* result);
	bool analyNot(Logic* op1, Logic* result);
	static OpRec* opStack[StackLimit];	
	int top;
	void clearStack();
	LogicOp findOpCode(int index);
	bool setNewOp(Logic* dummy, LogicState newValue);
	int findPreResult(int index);
	OpRec* getTop(){ if (top>0)  return opStack[top -1]; else return NULL;}
public:
	Analyse();
	~Analyse();
	void push(OpRec* newRec) {if (top<StackLimit) opStack[top++] = newRec;}
	OpRec* pop() {if (top>0) return opStack[--top];}
	bool readStack(int index);
	void analysing(bool byContradiction);
};

char* logicStr[3] = {"True", "Unknown", "False"};


//This is what we need to prove:
// [(p||t)&&(p-->q)&&(q-->r)&&(r-->s)&&(s-->t)] --> t

const int ElementNum = 5;

enum ElementIndex {P,Q,R,S,T};

Logic element[ElementNum];

char* factStr[ElementNum] = {"p","q","r","s","t"};

Logic& formular();



void displayResult();

void setFactStr();

int main()
{

	setFactStr();
	formular().doAnalysing(true);
	displayResult();
	return 0;
}


Logic& formular()
{
	return (((element[P]||element[T])&&(element[P]>>element[Q])&&(
		element[Q]>>element[R])&&(element[R]>>element[S])&&(element[S]>>
		element[T]))>>element[T]);
}


void setFactStr()
{
	for (int i=0; i< ElementNum; i++)
	{
		element[i].setExpress(factStr[i]);
	}
}

void displayResult()
{
	for (int i=0; i< ElementNum; i++)
	{
		cout<<"/nThe logic expression '"<<factStr[i]<<" 'is ";
		switch (element[i].getState())
		{
		case Positive:
			cout<<logicStr[0];
			break;
		case Possible:
			cout<<logicStr[1];
			break;
		case Negative:
			cout<<logicStr[2];
			break;
		}
		cout<<"/n";
	}
}




Analyse* Logic::getAnalyse()
{
	return analyse;
}


void Logic::doAnalysing(bool byContradiction)
{
	getAnalyse()->analysing(byContradiction);
}



int Analyse::findPreResult(int index)
{
	while (index > 0)
	{
		index -- ;
		if  (opStack[index]->opType== Result)
			return index;
	}
	return -1;
}

void Analyse::analysing(bool byContradiction)
{
	if (getTop()->opType!= Result)
	{
		cout<<"/nOpStack is not ended with Result:"<<endl;
			return ;
	}
	else
	{
	
		int i = top -1;
		if (!byContradiction)
		{
			opStack[i]->unknown.logic->setState(Positive);
		}
		else
		{
			opStack[i]->unknown.logic->setState(Negative);
		}

		while (i!= -1)
		{
			if (readStack(i))
			{
				analysing(byContradiction);
			}
			//readStack(i);
			i = findPreResult(i);		
		}
	}
	clearStack();
}



LogicOp Analyse::findOpCode(int index)
{
	int i = index;
	while (opStack[i]->opType != Operator)
	{
		i--;
	}
	return opStack[i]->unknown.op;
}

bool Analyse::readStack(int index)
{	
	bool result= false;
	LogicOp opCode;
	if (opStack[index]->opType != Result )
	{
		cout<<"Stack error!/n";
		return false;
	}
	opCode = findOpCode(index);
	switch (opCode)
	{
	case AND:
		result = analyAnd(opStack[index-3]->unknown.logic, 
			opStack[index - 1]->unknown.logic, 	opStack[index]->unknown.logic);
		break;
	case OR:
		result = analyOr(opStack[index-3]->unknown.logic, 
			opStack[index - 1]->unknown.logic, opStack[index]->unknown.logic);
		break;
	case CONDITIONAL:
		result = analyConditional(opStack[index-3]->unknown.logic, 
			opStack[index - 1]->unknown.logic, opStack[index]->unknown.logic);
		break;
	case NOT:
		result = analyNot(opStack[index -1]->unknown.logic, opStack[index]->unknown.logic);
		break;
	}
	return result;
}

bool Analyse::setNewOp(Logic* dummy, LogicState newValue)
{
	if (dummy->getState()!= newValue)
	{
		if (dummy->getState() != Possible)
		{
			cout<<"/nYou are changing expression '"<<dummy->getExpress()<<"' value!";
			return false;
		}
		else
		{
			dummy->setState(newValue);
			return true;
		}
	}
	else
		return false;
}

bool Analyse::analyAnd(Logic* op1, Logic* op2, Logic* result)
{
	bool newOp = false;
	switch (result->getState())
	{
	case Positive:
		if (op1->getState()==Negative||op2->getState()==Negative)
		{
			cout<<"/nThere is contradictive at:"<<result->getExpress();
			return false;
		}
	
		newOp =	setNewOp(op1, Positive) || setNewOp(op2 ,Positive);
			
		break;
	case Negative:
		if (op1->getState()==Positive&&op2->getState() == Positive)
		{
			cout<<"/nThere is contradictive at:"<<result->getExpress();
			return false;
		}
		if (op1->getState()==Positive)
		{
			newOp = setNewOp(op2, Negative);		
		}
		else
		{
			if (op2->getState() == Positive)
			{
				newOp = newOp || setNewOp(op1, Negative);
			}
		}
		break;
	case Possible:
		break;
	}
	return false;
}

bool Analyse::analyOr(Logic* op1, Logic* op2, Logic* result)
{
	bool newOp = false;
	switch(result->getState())
	{
	case Positive:
		if (op1->getState()==Negative && op2->getState()==Negative)
		{
			cout<<"/nThere is contradictive at:"<<result->getExpress();
			return false;
		}
		if (op1->getState() == Negative)
		{
			newOp = setNewOp(op2, Positive);
		}
		else
		{
			if (op2->getState() == Negative)
			{
				newOp = newOp || setNewOp(op1, Positive);
			}
		}
		break;
	case Negative:
		if (op1->getState()==Positive || op2->getState()== Positive)
		{
			cout<<"/nThere is contradictive at:"<<result->getExpress();
			return false;
		}
		break;
	case Possible:
		break;
	}
	return newOp;
}


bool Analyse::analyConditional(Logic* op1, Logic* op2, Logic* result)
{
	bool newOp = false;
	switch (result->getState())
	{
	case Positive:
		if (op1->getState()==Positive&& op2->getState()== Negative)
		{
			cout<<"/nThere is contradictive at:"<<result->getExpress();
			return false;
		}
		if (op1->getState()==Positive)
		{
			newOp = setNewOp(op2, Positive);
		}
		else
		{
			if (op2->getState() == Positive)
			{
				newOp = setNewOp(op1, Positive);
			}
		}
		break;
	case Negative:
		if (op1->getState() == Negative||op2->getState() == Positive)
		{
			cout<<"/nThere is contradictive at:"<<result->getExpress();
			return false;
		}
		newOp = setNewOp(op2, Negative);
		newOp = newOp || setNewOp(op1, Positive);
		break;
	case Possible:
		break;
	}
	return newOp;
}
	



bool Analyse::analyNot(Logic* op1, Logic* result)
{
	bool newOp = false;
	
	switch (result->getState())
	{
	case Positive:
		if (op1->getState() == Positive)
		{
			cout<<"/nThere is contradictive at:"<<result->getExpress();
			return false;
		}
		else
		{
			newOp = setNewOp(op1, Negative);
		}
		break;
	case Negative:
		if (op1->getState() == Negative)
		{
			cout<<"/nThere is contradictive at:"<<result->getExpress();
			return false;
		}
		else
		{
			newOp = setNewOp(op1, Positive);
		}
		break;
	case Possible:
		break;
	}
	return newOp;
}

	
Analyse* Logic::analyse = new Analyse;

OpRec* Analyse::opStack[StackLimit];

void Analyse::clearStack()
{
	for (int i =0; i< top; i++)
	{
		delete opStack[i];
	}
	top = 0;
}



Analyse::Analyse()
{
	top = 0;
}

Analyse::~Analyse()
{
	clearStack();
}

LogicState Logic::And(LogicState self, LogicState dummy)
{
	if (self!=dummy)
	{
		return (LogicState)(self*dummy);
	}
	else
	{
		return self;
	}
}

LogicState Logic::Or(LogicState self, LogicState dummy)
{
	return ((self>= dummy)?self: dummy);
}

LogicState Logic::Not(LogicState self)
{
	return (LogicState)(-1* self);
}



void Logic::prepare()
{
	for (int i=0; i< tempCount; i++)
	{
		free(temp[i]);
	}
	tempCount =0;
}



Logic& Logic::operator >>(Logic& dummy)
{
	char buffer[256];
	catName(buffer, dummy.getExpress(), CONDITIONAL);

	temp[tempCount] = new Logic(buffer);

	temp[tempCount]->setState(Or(Not(state), dummy.getState()));
	
	tempCount++;
	pushStack(this, &dummy, CONDITIONAL);

	return *temp[tempCount-1];		
}

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", Negative);

Logic& Logic::operator =(const Logic& dummy)
{
	setExpress(dummy.getExpress());
	setState(dummy.getState());
	return *this;
}

Logic* Logic::TRUE = new Logic("TRUE", Positive);;

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];
	OpRec* ptr;
	strcpy(buffer, OpStr[NOT]);
	strcat(buffer, getExpress());

	temp[tempCount] = new Logic(buffer);
	temp[tempCount]->setState(Not(getState()));

	tempCount++;
	
	ptr = new OpRec;
	ptr->opType = Operator;
	ptr->unknown = NOT;
	
	analyse->push(ptr);

	ptr = new OpRec;
	ptr->opType = Operand;
	ptr->unknown = this;

	analyse->push(ptr);

	ptr = new OpRec;
	ptr->opType = Result;
	ptr->unknown = temp[tempCount-1];

	analyse->push(ptr);

	return *temp[tempCount-1];	
}

void Logic::pushStack(const Logic* self, const Logic* pDummy, LogicOp opCode)
{
	OpRec* ptr;

	ptr = new OpRec;
	ptr->opType = Operand;
	ptr->unknown = self;
	analyse->push(ptr);

	ptr = new OpRec;
	ptr->opType = Operator;
	ptr->unknown = opCode;
	analyse->push(ptr);

	ptr = new OpRec;
	ptr->opType = Operand;
	ptr->unknown = pDummy;
	analyse->push(ptr);

	ptr = new OpRec;
	ptr->opType = Result;
	ptr->unknown = getTemp();
	analyse->push(ptr);
}
	

Logic& Logic::operator &&(Logic& dummy)
{
	char buffer[256];
	
	catName(buffer, dummy.getExpress(), AND);

	temp[tempCount] = new Logic(buffer);
	temp[tempCount]->setState(And(getState(),dummy.getState()));

	tempCount++;
	pushStack(this, &dummy, AND);

	return *temp[tempCount-1];
}

Logic& Logic::operator ||(Logic& dummy)
{
	char buffer[256];
	catName(buffer, dummy.getExpress(), OR);
	
	temp[tempCount] = new Logic(buffer);
	temp[tempCount]->setState(Or(getState(),dummy.getState()));

	tempCount++;
	pushStack(this, &dummy, OR);

	return *temp[tempCount-1];
}


int Logic::logicCount =0;

void Logic::initialize()
{
	express = NULL;
	state = Possible;
	definedStatus = false;
	setIndex(logicCount);
	logicCount++;
	status = false;
}

Logic::~Logic()
{

	if (!status)  //if you destroy one, then you destroy all!!!!!
	{
		uninitialize();
	}

	if (express!=NULL)
	{
		free(express);
	}
}

Logic::Logic(const char* newExpress, const LogicState 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)

设计一个类,我们只能生成该类的一个实例。

单例模式的要点有三个;一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。 从具体实现角度来说,就是以下三点:一是单例模式的类只提供私有的构造函数,二是类定义中...
  • youngyoungla
  • youngyoungla
  • 2016年06月12日 12:47
  • 1550

定义一个类让其只能实例化一个对象

一个类只实例化出一个对象称为单例模式
  • Dakuan_chen
  • Dakuan_chen
  • 2017年04月03日 18:42
  • 797

Yii CActiveRecord 逻辑删除封装

  • doushen1
  • doushen1
  • 2014年03月06日 08:51
  • 747

java思考题:设计一个只能创建一个唯一实例的类。

思考题:设计一个只能创建一个唯一实例的类。 有很多地方需要用到只能创建一个实例的类,比如说窗口上的工具箱,如果每次点击工具箱按钮都会创建一个工具箱实例,那么窗口中会出现很多工具箱,但是我们想要的是...
  • feng840401917
  • feng840401917
  • 2013年10月18日 16:34
  • 2258

用反证法证明有无穷多个素数

如何用反证法证明有无穷多个素数 今天在数据结构和算法分析里第一张看到这个问题,感觉书上写的反证法不够通透,省略了一些思考的步骤。自己也琢磨了半天才完全理解。 补充一下素数的定义:一个大于1的自然数,而...
  • a010655
  • a010655
  • 2015年05月09日 13:30
  • 553

Python 类的实 例化

在 Python 中对类进行实例化很直接。要对类进行实例化,只要调用类 (就好像它是一个函数),传入定义在 __init__ 方法中的参数。返回值将是新创建的对象。 1. 创建  Fi ...
  • lxgwm2008
  • lxgwm2008
  • 2013年07月05日 16:06
  • 6990

编程中实例是什么?什么是实例?实例化又是什么?什么是类?什么是对象?

实例(instance) 在面向对象程序设计中,“类”在实例化之后叫做一个“实例”。 “类”是静态的,不占进程内存,而“实例”拥有动态内存。 在数据库中,代表一些程序的集合。如Oracle中,实例就是...
  • czh500
  • czh500
  • 2016年11月10日 15:25
  • 2012

编写高质量代码改善Java程序的151个建议--总结摘抄

第一章  Java开发中通用的方法和准则 建议1:不要在常量和变量中出现易混淆的字母(i、l、1;o、0等); 建议2:莫让常量蜕变成变量;(代码运行工程中不要改变常量值) 建议3:三元操作符的类型务...
  • aishangyutian12
  • aishangyutian12
  • 2016年10月01日 12:59
  • 5486

实例化一个对象(类加载)的执行顺序详解

实例化一个对象(类加载)的执行顺序详解这篇博客将以类加载执行顺序为探索的起点,串讲涉及到的Java相关知识,主要是这个流程中JVN内部运行机制的解析。结论Created with Raphaël 2....
  • u013182381
  • u013182381
  • 2017年07月06日 17:27
  • 318

关于枚举的创建和使用

枚举简单的说也是一种数据类型,只不过是这种数据类型只包含自定义的特定数据,它是一组有共同特性的数据的集合。举个例子,颜色也可以定义成枚举类型,它可以包含你定义的任何颜色,当需要的时候,只需要通过枚举调...
  • aeiou20018
  • aeiou20018
  • 2016年07月10日 16:31
  • 3190
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用逻辑类所作的一个反证法的实例
举报原因:
原因补充:

(最多只允许输入30个字)