命题逻辑推理 (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; }
上一篇 (C语言之路-----p2:函数)
下一篇 刷洛谷/LintCode/牛客刷题学习心得(1)(c语言查漏补缺)
版权所有 (c)2021-2022 MSHXW.COM
ICP备案号:晋ICP备2021003244-6号