离散数学——python实现真值表和打印主范式

离散数学——python实现真值表和打印主范式
最近⽤python实现了真值表,经过有点⼉曲折,刚开始没考虑优先级,直到前天才发现这个问题(离散数学没学好啊),⽤栈改了⼀下。话说python就是强,把列表类型当栈⽤,直接调⽤列表的pop()和append()⾮常⽅便,废话少说上代码(命令⾏版)。
1. ⾸先是导⼊外部库和定义函数
#导⼊正则表达式re库,⽤来从字符串中提取信息
import re
#prettytable库帮我们打印出漂亮的表格
from prettytable import PrettyTable
#过滤掉(
def filter_brackets(string):
p=repile(r'[(]+(.*)')
return(p.findall(string)[0])
#判断格式是否合理,并返回真值表的列名
def to_show(string):
#利⽤patten提取括号中的内容
patten=repile(r'[(](.*?)[)]')
contents_in_brackets=patten.findall(string)
#contents_in_brackets中的元素存在'('的现象,故对所有元素进⾏遍历过滤掉这些括号
for i in range(len(contents_in_brackets)):
if contents_in_brackets[i].startswith('('):
contents_in_brackets[i]=filter_brackets(contents_in_brackets[i])
#利⽤sp提取命题变元,n为命题变元的个数
sp=repile('[a-zA-Z]')
simple_exp=sp.findall(string)
l=simple_exp+contents_in_brackets
#l去重得到l1
l1=[]
for i in l:
if i not in l1:
l1.append(i)
l1.append(string)
l1.sort(key=len)
#第⼀项是要展⽰的部分,第⼆项是命题变元(有重复)
return([l1,simple_exp])
2. 其次是运算部分
def get_prioty(operator):
#if operator=='(' or operator==')'船用锚机
p=-1
if operator=='(':
p=6
elif operator=='!':
p=5
elif operator=='&':
p=4
elif operator=='#':
p=3
elif operator=='|':
p=2
elif operator=='>':
p=1
elif operator=='=':
p=0
return(p)
#两命题变元运算
def cal(a,operator,b=-1):
if operator == '!':
boo = not a
elif operator == '&':
boo = a and b
elif operator == '|':
boo = a or b
#异或
麦弗逊式独立悬架elif operator == '#':
boo = (a and (not b)) or ((b and (not a)))
#条件(注意顺序是反的)
elif operator == '>':
boo = (not b) or a
#等值
elif operator == '=':
boo = ((not a) and (not b)) or (a and b)
else:
print("there is no such operator")金属焊接
return(None)
if(boo):
return(1)
else:
return(0)
#对传⼊的字符串进⾏运算(传⼊的字符串⽆括号),且
def cal_str(Str,dic):
i=0
#s0为数字栈
s0=[]
#s1为运算符栈
s1=[]
while i<len(Str) or len(s1)!=0:
if i<len(Str):
c=Str[i]
else:
c=''
if c.isalpha():
s0.append(dic[c])
i=i+1
else:
if len(s1)==0 or (c!=')'and s1[-1]=='(') or get_prioty(c)>=get_prioty(s1[-1]):
s1.append(c)
i=i+1
continue
if  c==')'and s1[-1]=='(':
s1.pop()
i=i+1
continue
if (i>=len(Str) and len(s1)!=0) or (c==')'and s1[-1]!='(') or get_prioty(c)<=get_prioty(s1[-1]):
opt=s1.pop()
if opt!='!':
result=cal(s0.pop(),opt,s0.pop())
elif opt=='!':
result=cal(s0.pop(),opt)
s0.append(result)
return(s0[0])
3. 利⽤bin()函数得到相应元素个数的全部真值赋值,经过⼀顿操作使⽤zip()函数将命题变元与其真值(0或1)绑定起来,遍历所有的真
值赋值情况,计算每种真值情况下的各个表达式的值,得到真值表
#产⽣真值序列(字典形式)的列表
def gen_truth_list(elems):
num=len(elems)
tl=[]
for i in range(2**num):
st=bin(i)[2:].zfill(num)
truth_list=list(map(lambda j:int(j),list(st)))
#append:将字典以整体形式加到列表中
tl.append(dict(zip(elems,truth_list)))
return(tl)
def gen_all_line(truth_list,header):
#产⽣真值表数据
all_line=[]
for line_truth in truth_list:
per_line=[]
for exp in header:
truth=cal_str(exp,line_truth)
per_line.append(truth)
all_line.append(per_line)
return(all_line)
4. 根据真值表获得主范式
#返回⼀个⼩项
def get_minterm(term):
if len(term)!=0:
return('('+'&'.join(term)+')')
else:
return('')
变压器骨架
#返回⼀个⼤项
def get_maxterm(term):
if len(term)!=0:
return('('+'|'.join(term)+')')
else:
return('')
def get_dnf(header,elems):
truth_list=gen_truth_list(elems)
minterms=[]
all_line=gen_all_line(truth_list,header)
#遍历每⼀⾏
for line_id in range(2**len(elems)):
#term为包含某⼩项中各命题变元正确形式的列表
term=[]
#如果该⾏的真值赋值使得表达式为1
if all_line[line_id][-1]==1:
#遍历该⾏对应的真值赋值
for t in truth_list[line_id]:
if truth_list[line_id][t]==1:
term.append(t)
luciano rivarolaelse:
term.append('!'+t)
#表达式为1才能加⼊⼩项列表
minterm=get_minterm(term)
if minterm!='':
minterms.append(minterm)
return('|'.join(minterms))
def get_cnf(header,elems):
truth_list=gen_truth_list(elems)iphd
maxterms=[]
all_line=gen_all_line(truth_list,header)
#遍历每⼀⾏
for line_id in range(2**len(elems)):
term=[]
#如果该⾏的真值赋值使得表达式为0
if all_line[line_id][-1]==0:
#遍历该⾏对应的真值赋值
for t in truth_list[line_id]:
if truth_list[line_id][t]==0:
term.append(t)
else:
term.append('!'+t)
#表达式为1才能加⼊⼩项列表
maxterm=get_maxterm(term)
if maxterm!='':
maxterms.append(maxterm)
return('&'.join(maxterms))
5. 主函数如下
if__name__=="__main__":
#获取字符串
string=input('input:')
header=to_show(string)[0]
elem=to_show(string)[1]
elems=[]
for i in elem:
if i not in elems:
elems.append(i)
truth_list=gen_truth_list(elems)
all_line=[]
for line_truth in truth_list:
per_line=[]
for exp in header:
truth=cal_str(exp,line_truth)
per_line.append(truth)
all_line.append(per_line)
truth_table=PrettyTable(header)
for line in all_line:
truth_table.add_row(line)
print('The truth table of this formula is printed below:')
print(truth_table)
continue_or_not=input('Show "principal disjunctive normal form" \n or  "principal conjunctive normal form"? [y/n]\n') #继续输出主范式
if continue_or_not=='y':
print('pdnf(主析取范式): '+get_dnf(header,elems))
print('pcnf(主合取范式): '+get_cnf(header,elems))
第⼀次写技术博客,有点⼉激动,先写到这,过两天给出⼀个GUI版本的。

本文发布于:2024-09-20 20:26:20,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/4/276565.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:真值表   真值   变元   命题   赋值   元素
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议