栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

命题逻辑推理

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

命题逻辑推理

命题逻辑推理
(1)实现命题逻辑的语法检查功能:合式公式的判定
(2)判断命题公式是否可满足;
(3)判断命题公式的蕴含关系是否成立。
参考链接:C语言中缀表达式转后缀表达式
离散数学判断合式公式,并打印真值表、求主析取、主合取范式

#include
#include
#include 
#include 
#include 
#include 
using namespace std;
stack s3;//栈s3存储后缀表达式
mapch;//映射表示原子命题真假
setsh;//统计原子命题
//定义联结词优先次序
//case '!':return 5; break;
//case '&':return 4; break;
//case '|':return 3; break;
//case '-':return 2; break;
//case '=':return 1; break;
int Compare(char str1) {
	if (str1 == '!') {
		return 5;
	}
	else if (str1 == '&') {
		return 4;
	}
	else if (str1 == '|') {
		return 3;
	}
	else if (str1 == '-') {
		return 2;
	}
	else if (str1 == '=') {
		return 1;
	}
	else if (str1 == '(' || str1 == ')') {
		return 0;
	}
	else {
		return -1; //字母或者数字 
	}
}
bool Fouding(bool a)//否定运算
{
	if (a)return false;
	else return true;
}
bool And(bool a, bool b)//合取
{
	if (!a || !b)return false;
	else return true;
}
bool Or(bool a, bool b)//析取
{
	if (a || b)return true;
	else return false;
}
bool One(bool a, bool b)//条件
{
	if (a && !b)return false;
	else return true;
}
bool Two(bool a, bool b)//双条件
{
	if (a == b)return true;
	else return false;
}

void appoint(int num)
{
	for (set::iterator it = sh.begin(); it != sh.end(); it++)//遍历原子命题
	{
		if (num % 2)
			ch[*it] = true;
		else
			ch[*it] = false;
		num /= 2;
	}
}

int rps(string& str, string ss, string sd, int runum)//用"sd"替换"str"中的"ss"
{

	int i = str.length(), p;
	while (p = str.find(ss) + 1)
		str.replace(p - 1, ss.length(), sd);

	return str.length() - i;
}
bool judge(string& str)//判断是否为合式公式
{
	string strtmp = str;
	for (int i = 0; i < str.length(); i++)
		if (isalpha(str[i]))
			str[i] = '1';

	while (rps(str, "!1", "1", 2) || rps(str, "(1)", "1", 2) || rps(str, "1&1", "1", 3) || rps(str, "1|1", "1", 3) || rps(str, "1-1", "1", 3) || rps(str, "1=1", "1", 3));//使用规则2、3
	if (str == "1")
	{
		cout << strtmp << "是合式公式" << endl;
		return true;
	}
	else
	{
		cout << strtmp << "不是合式公式" << endl;
		return false;
	}
}
//∧∨→ <=>
void turn(string& s)
{
	stacks1, s2;
	for (int i = 0; i < s.size(); i++)
	{
		char p = s[i];
		if (isalpha(p))
			s1.push(p);         //原子命题直接压入s1
		else if (p == '(')      //左括号直接压入s2
			s2.push(p);
		else if (p == ')')
		{
			//遇右括号将s2中左括号前面的元素依次弹出压入s1
			while (!s2.empty() && s2.top() != '(')
			{
				s1.push(s2.top());
				s2.pop();
			}
			s2.pop();
		}
		else        //遇到逻辑符号
		{
			if (s2.empty())
				s2.push(p);
			else if (s2.top() == '(')
				s2.push(p);
			else if (Compare(p) > Compare(s2.top()))
				s2.push(p);
			else
			{
				while (!s2.empty() && s2.top() != '(' && Compare(p) <= Compare(s2.top()))
				{
					s1.push(s2.top());
					s2.pop();
				}
				s2.push(p);
			}
		}
	}
	while (!s2.empty())//将s2中剩余元素压入s1
	{
		s1.push(s2.top());
		s2.pop();
	}

	while (!s1.empty())//将后缀表达式存储在栈s3中
	{
		s3.push(s1.top());
		s1.pop();
	}

}
int  value()//后缀表达式求值
{
	ch['T'] = true;
	ch['F'] = false;
	stackc, s;
	s = s3;
	while (!s.empty())
	{
		char p = s.top();//取栈顶元素
		s.pop();
		if (isalpha(p))
			c.push(p);//原子命题直接压入c
		else if (p == '!')//联结词!处理
		{
			char t = c.top();
			c.pop();
			Fouding(ch[t]) ? c.push('T') : c.push('F');
		}
		else
		{
			char ph;
			char t1 = c.top();
			c.pop();
			char t2 = c.top();
			c.pop();
			switch (p)
			{
			case '&':And(ch[t2], ch[t1]) ? ph = 'T' : ph = 'F'; break;
			case '|':Or(ch[t2], ch[t1]) ? ph = 'T' : ph = 'F'; break;
			case '-':One(ch[t2], ch[t1]) ? ph = 'T' : ph = 'F'; break;
			case '=':Two(ch[t2], ch[t1]) ? ph = 'T' : ph = 'F'; break;
			}
			c.push(ph);
		}
	}
	if (c.top() == 'T')  return true;
	else return false;
}
int judge2(int cou)
{
	for (int i = 0; i < cou; i++)//打印真值表
	{
		appoint(i);//指派
		for (set::iterator it = sh.begin(); it != sh.end(); it++)
		{
			if (value() == 1)
			{
				return 1;
			}
			else continue;
		}
	}
	return 0;
}
int judge3(int cou)
{
	for (int i = 0; i < cou; i++)//打印真值表
	{
		appoint(i);//指派
		for (set::iterator it = sh.begin(); it != sh.end(); it++)
		{
			if (value() == 0)
			{
				return 0;
			}
			else
				continue;
		}
	}
	return 1;
}
void Menu() {
	printf("*************************************************n");
	printf("*t欢迎使用命题逻辑推理系统V1.0tt*n");
	printf("*tt请选择功能ttt*n");
	printf("*************************************************n");
	printf("*t0.退出命题逻辑推理系统ttt*n");
	printf("*t1.判定命题公式是否为合式公式tt*n");
	printf("*t2.判断命题公式是否可满足tt*n");
	printf("*t3.判断命题公式的蕴含关系是否成立t*n");
	printf("*************************************************n");
}

int main()
{
	
	Menu();
	string str, input;
	cout << "请输入合式公式(!否定 , 合取 & , 析取 | , 条件 - ,双条件 = ):" << endl;
	while (1)
	{
		int choice;
		cin >> choice;
		switch (choice)
		{
		case 0:
		{
			cout << "感谢你使用命题逻辑推理系统,,请关掉程序!!!" << endl;
			system("pause");
		}break;
		case 1:
		{
			cin >> str;
			judge(str);
		}break;
		case 2:
		{
			cin >> str;
			for (int i = 0; i < str.size(); i++)//将原子命题建立到set容器中
				if (isalpha(str[i]))sh.insert(str[i]);
			turn(str);//将前缀表达式转化为后缀表达式
			int cou = pow(2, sh.size());
			if (judge2(cou) == 1)
			{
				cout << "命题公式满足" << endl;
			}
			else
				cout << "命题公式不满足" << endl;

		}break;
		case 3:
		{
			cin >> str;
			for (int i = 0; i < str.size(); i++)//将原子命题建立到set容器中
			if (isalpha(str[i]))sh.insert(str[i]);
			turn(str);//将前缀表达式转化为后缀表达式
			int cou = pow(2, sh.size());
			if (judge3(cou) == 1)
			{
				cout << "命题公式的蕴含关系成立" << endl;
			}
			else
				cout << "命题公式的蕴含关系不成立" << endl;
		}break;
		default:
		{
			printf("选择错误,请重新输入0.0n");
		}break;
		}
	}
	system("pause");
	return 0;

	}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/429910.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号