# 【日常Python-5】求真值表和主范式

1.问题描述

2.实验代码

# -*- coding:gbk -*-

sInput = '' #输入的命题公式字符串
sParse = '' #化简后的sInput
variable = [] #保存公式中的变量
ornl = [] #主析取范式最小项
andnl = [] #主合取范式最大项
fore = '' #符号前面的部分
back = '' #符号后面的部分

def myinput():
global sInput
print("请输入一个任意命题公式(原子命题用字母表示,'~'表示非 '&'表示合取 '|'表示析取 '>'表示蕴含 ':'表示等价 '@'表示异或,可用括号'()'):")
sInput = input()

def getVariale():
global sInput,variable
for c in sInput:
if c >= 'A' and c <= 'Z' or c >= 'a' and c <= 'z' :
if c not in variable:
variable.append(c)
elif c!='~' and c!='&' and c!='|' and c!='(' and c!=')' and c!='>' and c!=':' and c!='@':
print('输入有误！！')
variable = sorted(variable)

def getFB(c):
global sInput,sParse,fore,back
slen = len(sParse)
for i in range(0,slen):  #遍历sParse中所有字符
if sParse[i] is c:
if sParse[i-1] is not ')': #找到fore
fore = sParse[i-1]
else:
flag = 1
j = i-2
while flag is not 0:
if sParse[j] is '~':
j-=1
if sParse[j] is '(':
flag-=1
if sParse[j] is ')':
flag+=1
j-=1
fore = sParse[j+1:i]
if sParse[i+1] is not '(': #找到back
back = sParse[i+1]
else:
flag = 1
j = i+2
while flag is not 0:
if sParse[j] is '~':
j+=1
if sParse[j] is ')':
flag-=1
if sParse[j] is '(':
flag+=1
j+=1
back = sParse[i+1:j]
if c is '>':
sParse = sParse.replace(fore+'>'+back,'('+'~'+fore+'|'+back+')')
elif c is ':':
sParse = sParse.replace(fore+':'+back,'('+fore+'&'+back+')|(~'+fore+'&~'+back+')')
elif c is '@':
sParse = sParse.replace(fore+'@'+back,'~('+'('+fore+'&'+back+')|(~'+fore+'&~'+back+')'+')')

def parseInput():
global sInput,sParse
sParse = sInput
getFB('>')
getFB(':')
getFB('@')

def cal():
global sInput,sParse,variable,ornl,andnl,orResult,andResult
vlen = len(variable) #变量个数
n = 2**vlen   #所有情况个数
print('真值表如下：')
print(variable,sInput+'即',sParse)
for nl in range(0,n):      #获取真值表
value = []    #数值
j = nl   #真值表当前行
for i in range(0,vlen):
value.append(0)
i = 0
while j!=0:
value[i]=j%2
j=j//2
i+=1
value.reverse()
value = list(map(str,value))
s = sParse
for x in range(0,vlen):
s = s.replace(variable[x],value[x])
result = eval(s)&1
if result is 1:
ornl.append(nl)
else:
andnl.append(nl)
print(value,result)

def outprint():
print('主析取范式：')
print('∑',ornl,sep='')
print('主合取范式：')
print('∏',andnl,sep='')

def main():
myinput()
getVariale()
parseInput()
cal()
outprint()

if __name__=='__main__':
main()



3.实验截图

1. 利用计算机求命题公式真值表的关键是：①给出命题变元的每一组赋值；②计算命题公式在每一组赋值下的真值。

2. 真值表中命题变元的取值具有如下规律：每列中0和1是交替出现的，且0和1连续出现的个数相同。n个命题变元的每组赋值的生成算法可基于这种思想。

3. 含有n个命题变元的命题公式的真值的计算采用的方法为“算符优先法”，如下表所示。
为了程序实现的方便，约定命题变元只用一个字母表示，非、合取、析取、条件和双条件联结词分别用！、&、|、－、＋来表示。

4. 合取：二元命题联结词。将两个命题P、Q联结起来，构成一个新的命题P∧Q, 读作P、Q的合取, 也可读作P与Q。这个新命题的真值与构成它的命题P、Q的真值间的关系为只有当两个命题变项P = T, Q = T时方可P∧Q =T, 而P、Q只要有一为F则P∧Q = F。这样看来，P∧Q可用来表示日常用语P与Q, 或P并且Q。

5. 析取：二元命题联结词。将两个命题P、Q联结起来，构成一个新的命题P∨Q, 读作P、Q的析取, 也可读作P或Q。这个新命题的真值与构成它的命题P、Q的真值间的关系为只有当两个命题变项P = F, Q = F时方可P∨Q =F, 而P、Q只要有一为T则P∨Q = T。这样看来，P∨Q可用来表示日常用语P或者Q。

6. 条件：二元命题联结词。将两个命题P、Q联结起来，构成一个新的命题P→Q, 读作P条件Q, 也可读作如果P，那么Q。这个新命题的真值与构成它的命题P、Q的真值间的关系为只有当两个命题变项P = T, Q = F时方可P→Q =F, 其余均为T。

7. 双条件：二元命题联结词。将两个命题P、Q联结起来，构成一个新的命题P←→Q, 读作P双条件于Q。这个新命题的真值与构成它的命题P、Q的真值间的关系为当两个命题变项P = T, Q =T时方可P←→Q =T, 其余均为F。

8. 真值表:表征逻辑事件输入和输出之间全部可能状态的表格。列出命题公式真假值的表。通常以1表示真，0 表示假。命题公式的取值由组成命题公式的命题变元的取值和命题联结词决定，命题联结词的真值表给出了真假值的算法。 真值表是在逻辑中使用的一类数学表，用来确定一个表达式是否为真或有效。

©️2019 CSDN 皮肤主题: 创作都市 设计师: CSDN官方博客