实验一 命题逻辑:求给定命题公式的真值表
实验原理:[可忽略]
将命题公式A在所有赋值下取值情况列成表,称作A的真值表。
构造真值表的具体步骤如下:
(1) 找出公式中所含的全体命题变项p1,p2,…,pn (若无下角标就按字典顺序排列),列出2n个赋值。本课程规定,赋值从00…0开始,然后按二进制加法依次写出各赋值,直到11…1为止。
(2) 按从低到高的顺序写出公式的各个层次。
(3) 对应各个赋值计算出各层次的真值,直到最后计算出公式的真值。 实验要求和说明: 本实验要求大家利用编程语言,编写程序,输出给定命题公式(p→q)∧r的真值表。一般我们将公式中的命题变元放在真值表的左边,将公式的结果放在真值表的右边。
.
(p→q)∧r的真值表如下: | 程序预期输出: |
---|
| |
预期实现
- 输入任意表达式能出对应的结果
- 能对(与 或 非 蕴含 等价 括号)进行运算
- 能进行优先级处理
- 能识别多个命题不会重复
代码实现效果
将与 或 非 蕴含 等价 括号符号化
中文 | 逻辑表达 | 代码表达 |
---|
析取式 | ∨ | | |
合取式 | ∧ | & |
非/取反 | ᒣ | ! |
蕴含式 | → | -> |
等值式 | ↔ | <-> |
输入如上例题的表达式:(p→q)∧r
则输入(p->q)&r 即可 | |
---|
复杂输入优先级以及等值式展开测试(完美通过) | |
代码分享
#include <math.h>
#include <stdio.h>
#include <string.h>
#define N 500
void binaryAdder(int b[N], int f)
{
if (b[f] == 0)
b[f] = 1;
else
{
b[f] = 0;
binaryAdder(b, f + 1);
}
}
int getAns0(char expression[N], char variable[N], int loop[N], int h0)
{
int i, h = 0, j = 0, j1 = 0, j2 = 0, j3 = 0, i1, i2, p1 = -1, p2 = -1, s;
char dt[N];
s = strlen(expression);
if (s == 1)
if (expression[0] == -2)
return 0;
else
return 1;
else
{
for (i = 0; i < s - j; i++)
{
if (expression[i] == '!')
{
for (i1 = 0; i1 < h0; i1++)
if (expression[i + 1] == variable[i1])
p1 = loop[i1];
if (expression[i + 1] == -2)
p1 = 0;
if (p1 == -1)
p1 = expression[i + 1];
dt[j + 2] = !p1;
expression[i] = j + 2;
j++;
p1 = 0;
for (i1 = i + 1; i1 < s - j; i1++)
expression[i1] = expression[i1 + 1];
}
}
p1 = -1;
j1 = j;
for (i = 0; i < s - j1 - 2 * j2; i++)
if (expression[i] == '&')
{
for (i1 = 0; i1 < h0; i1++)
{
if (expression[i - 1] == variable[i1])
p1 = loop[i1];
if (expression[i + 1] == variable[i1])
p2 = loop[i1];
}
for (i2 = 2; i2 < j + 2; i2++)
{
if (expression[i - 1] == i2)
p1 = dt[i2];
if (expression[i + 1] == i2)
p2 = dt[i2];
}
if (expression[i - 1] == -2)
p1 = 0;
if (expression[i + 1] == -2)
p2 = 0;
if (p1 == -1)
p1 = (int)(expression[i - 1]);
if (p2 == -1)
p2 = (int)(expression[i + 1]);
dt[j + 2] = p1 && p2;
expression[i - 1] = j + 2;
j++;
j2++;
p1 = -1;
p2 = -1;
for (i1 = i; i1 < s - j1 - 2 * j2; i1++)
expression[i1] = expression[i1 + 2];
i = i - 1;
}
for (i = 0; i < s - j1 - 2 * j2 - 2 * j3; i++)
if (expression[i] == '|')
{
for (i1 = 0; i1 < h0; i1++)
{
if (expression[i - 1] == variable[i1])
p1 = loop[i1];
if (expression[i + 1] == variable[i1])
p2 = loop[i1];
}
for (i2 = 2; i2 < j + 2; i2++)
{
if (expression[i - 1] == i2)
p1 = dt[i2];
if (expression[i + 1] == i2)
p2 = dt[i2];
}
if (expression[i - 1] == -2)
p1 = 0;
if (expression[i + 1] == -2)
p2 = 0;
if (p1 == -1)
p1 = expression[i - 1];
if (p2 == -1)
p2 = expression[i + 1];
dt[j + 2] = p1 || p2;
expression[i - 1] = j + 2;
j++;
j3++;
p1 = -1;
p2 = -1;
for (i1 = i; i1 < s - j1 - 2 * j2 - 2 * j3; i1++)
expression[i1] = expression[i1 + 2];
i--;
}
return dt[j + 1];
}
}
int getAns(char expression[N], char variable[N], int loop[N], int h0)
{
int i, j, k, slen, bracketsNum = 0, bracketsIndex[N], flag;
char charStore[N], brackets[N];
slen = strlen(expression);
for (i = 0; i < slen; i++)
{
if (expression[i] == '(' || expression[i] == ')')
{
bracketsIndex[bracketsNum] = i;
brackets[bracketsNum] = expression[i];
bracketsNum++;
}
}
if (bracketsNum == 0)
return getAns0(expression, variable, loop, h0);
else
{
for (i = 0; i < bracketsNum; i++)
if (brackets[i] == ')')
break;
for (j = bracketsIndex[i - 1] + 1, k = 0; j < bracketsIndex[i]; j++, k++)
charStore[k] = expression[j];
charStore[k] = '\0';
flag = getAns0(charStore, variable, loop, h0);
if (flag == 1)
expression[bracketsIndex[i - 1]] = 1;
else
expression[bracketsIndex[i - 1]] = -2;
for (j = bracketsIndex[i - 1] + 1; j < slen + bracketsIndex[i - 1] - bracketsIndex[i]; j++)
expression[j] = expression[j + bracketsIndex[i] - bracketsIndex[i - 1]];
expression[j] = '\0';
return getAns(expression, variable, loop, h0);
}
}
void format(char expression[N])
{
while (1)
{
int flag = 1;
char left[N], midLeft[N], midRight[N], right[N];
int slen = strlen(expression);
for (int i = 0; i < slen; i++)
{
if (expression[i] == '-' && expression[i + 1] == '>')
{
flag = 0;
int li = i - 1, bracketsNum = 0;
while (li >= 0)
{
if (expression[li] == ')')
bracketsNum--;
else if (expression[li] == '(')
bracketsNum++;
if (bracketsNum > 0)
break;
li--;
}
if (bracketsNum > 0)
{
int j = 0, tempi = li + 1;
for (tempi; tempi < i; tempi++)
{
midLeft[j++] = expression[tempi];
}
midLeft[j] = '\0';
for (tempi = 0; tempi <= li; tempi++)
{
left[tempi] = expression[tempi];
}
left[tempi] = '\0';
}
else
{
int tempi;
left[0] = '\0';
for (tempi = 0; tempi < i; tempi++)
{
midLeft[tempi] = expression[tempi];
}
midLeft[tempi] = '\0';
}
li = i + 2, bracketsNum = 0;
while (li < slen && expression[li] != '-' && expression[li] != '<')
{
if (expression[li] == ')')
bracketsNum--;
else if (expression[li] == '(')
bracketsNum++;
if (bracketsNum < 0)
break;
li++;
}
if (bracketsNum < 0 || expression[li] == '-' || expression[li] == '<')
{
int j = 0, tempi;
for (tempi = i + 2; tempi < li; tempi++)
{
midRight[j++] = expression[tempi];
}
midRight[j] = '\0';
j = 0;
for (tempi = li; tempi < slen; tempi++)
{
right[j++] = expression[tempi];
}
right[j] = '\0';
}
else
{
int tempi;
right[0] = '\0';
int j = 0;
for (tempi = i + 2; tempi < slen; tempi++)
{
midRight[j++] = expression[tempi];
}
midRight[j] = '\0';
}
expression[0] = '\0';
strcat(expression, left);
strcat(expression, "(!");
if (strlen(midLeft) > 1)
strcat(expression, "(");
strcat(expression, midLeft);
if (strlen(midLeft) > 1)
strcat(expression, ")");
strcat(expression, "|");
if (strlen(midRight) > 1)
strcat(expression, "(");
strcat(expression, midRight);
if (strlen(midRight) > 1)
strcat(expression, ")");
strcat(expression, ")");
strcat(expression, right);
break;
}
else if (i + 2 < slen && expression[i] == '<' && expression[i + 1] == '-' && expression[i + 2] == '>')
{
flag = 0;
int li = i - 1, bracketsNum = 0;
while (li >= 0)
{
if (expression[li] == ')')
bracketsNum--;
else if (expression[li] == '(')
bracketsNum++;
if (bracketsNum > 0)
break;
li--;
}
if (bracketsNum > 0)
{
int j = 0, tempi = li + 1;
for (tempi; tempi < i; tempi++)
{
midLeft[j++] = expression[tempi];
}
midLeft[j] = '\0';
for (tempi = 0; tempi <= li; tempi++)
{
left[tempi] = expression[tempi];
}
left[tempi] = '\0';
}
else
{
int tempi;
left[0] = '\0';
for (tempi = 0; tempi < i; tempi++)
{
midLeft[tempi] = expression[tempi];
}
midLeft[tempi] = '\0';
}
li = i + 2, bracketsNum = 0;
while (li < slen && expression[li] != '-' && expression[li] != '<')
{
if (expression[li] == ')')
bracketsNum--;
else if (expression[li] == '(')
bracketsNum++;
if (bracketsNum < 0)
break;
li++;
}
if (bracketsNum < 0 || expression[li] == '-' || expression[li] == '<')
{
int j = 0, tempi;
for (tempi = i + 3; tempi < li; tempi++)
{
midRight[j++] = expression[tempi];
}
midRight[j] = '\0';
j = 0;
for (tempi = li; tempi < slen; tempi++)
{
right[j++] = expression[tempi];
}
right[j] = '\0';
}
else
{
int tempi;
right[0] = '\0';
int j = 0;
for (tempi = i + 3; tempi < slen; tempi++)
{
midRight[j++] = expression[tempi];
}
midRight[j] = '\0';
}
expression[0] = '\0';
strcat(expression, left);
strcat(expression, "((!");
if (strlen(midLeft) > 1)
strcat(expression, "(");
strcat(expression, midLeft);
if (strlen(midLeft) > 1)
strcat(expression, ")");
strcat(expression, "|");
if (strlen(midRight) > 1)
strcat(expression, "(");
strcat(expression, midRight);
if (strlen(midRight) > 1)
strcat(expression, ")");
strcat(expression, ")&");
strcat(expression, "(!");
if (strlen(midRight) > 1)
strcat(expression, "(");
strcat(expression, midRight);
if (strlen(midRight) > 1)
strcat(expression, ")");
strcat(expression, "|");
if (strlen(midLeft) > 1)
strcat(expression, "(");
strcat(expression, midLeft);
if (strlen(midLeft) > 1)
strcat(expression, ")");
strcat(expression, "))");
strcat(expression, right);
break;
}
}
if (flag)
break;
}
}
void printTable()
{
int i1, i2, loop[N], bracketsNum = 0, ans, variableNum = 0;
char expression[N], oldexpression[N], variable[N], expressionTemp[N];
printf("【请输入一个合法的命题公式】\n");
printf("|基本析取:q|p |\n");
printf("|基本合取: q&p |\n");
printf("|可包含蕴含式 : q->r |\n");
printf("|可包含等价式 : q<->r |\n");
printf("|可包含否和括号: p|(!q|r) |\n");
printf("|\n|\n|:");
scanf("%s", expression);
strcpy(oldexpression, expression);
format(expression);
strcpy(expressionTemp, expression);
for (i1 = 0; i1 < strlen(expression); i1++)
{
if (expression[i1] == ')' || expression[i1] == '(')
bracketsNum++;
if (expression[i1] >= 'a' && expression[i1] <= 'z' || expression[i1] >= 'A' && expression[i1] <= 'Z')
{
for (i2 = 0; i2 < variableNum; i2++)
if (variable[i2] == expression[i1])
break;
if (i2 == variableNum)
{
variable[variableNum] = expression[i1];
variableNum++;
}
}
}
printf("总变量个数为: %d\n", variableNum);
variableNum;
printf("输出真值表如下: \n");
for (i1 = 0; i1 < variableNum; i1++)
printf(" %c ", variable[i1]);
printf("[%s] ==> ", oldexpression);
printf("[%s] ", expression);
printf("\n");
for (i1 = 0; i1 < variableNum; i1++)
loop[i1] = 0;
for (i1 = 0; i1 < (int)pow(2, variableNum); i1++)
{
if (i1 != 0)
binaryAdder(loop, 0);
ans = getAns(expression, variable, loop, variableNum);
strcpy(expression, expressionTemp);
for (i2 = 0; i2 < variableNum; i2++)
printf(" %d ", loop[i2]);
for (int formati = 0; formati < strlen(oldexpression) + 5; formati++)
printf("-");
printf("> ");
for (int formati = 0; formati < strlen(oldexpression); formati++)
printf(" ");
printf("%d\n", ans);
}
getchar();
getchar();
}
int main()
{
do
{
printTable();
} while (1);
}
最后就完成了,代码如上,欢迎学习与参考