离散数学实验一 · 命题逻辑与真值表

一、实验目的

用python实现命题逻辑的五个基本运算,并计算命题公式真值。熟悉不同命题逻辑词以及真值表。

二、实验内容

1.输入两个命题P、Q的真值,求其与、或、蕴含、等值的真值;

2.对输入的一个命题公式,如:P->(Q->R),能够输出真值表;

三、Python代码部分

Priority = ['!','&','|','*','+'] # 非、与、或、蕴含、等值
print("1.输入P和Q的值来计算真值")
print("2.输入命题公式,并输出对应真值表")
Choose=input("请选择所需功能:")

def True_value():
    T,F="1","0"
    P=input("请输入P的真值(0或1):")
    Q=input("请输入Q的真值(0或1):")
    if int(P)==1 and int(Q)==1:
        value1=T
    else:
        value1=F
    print("命题P和Q的与的真值为:   ",value1)
    if int(P)==0 and int(Q)==0:
        value2=F
    else:
        value2=T
    print("命题P和Q的或的真值为:   ",value2)
    if int(P)==1 and int(Q)==0:
        value3=F
    else:
        value3=T
    print("命题P和Q的蕴含的真值为: ",value3)
    if int(P)==int(Q):
        value4=T
    else:
        value4=F
    print("命题P和Q的等值的真值为: ",value4)

def postfix(elements):
    global Priority
    stack = list()
    output = list()
    for x in elements:
        if x not in Priority and x not in ('(',')'):    #如果不是运算符和括号
            output.append(x)    #把变元添加至output列表
        elif x == '(':  #如果是左括号,把变元加入stack列表并等待右括号
            stack.append(x)
        elif x == ')':  #如果是右括号,把变元拉出stack列表
            val = stack.pop()
            while val !='(':
                output.append(val)
                if stack:
                    val = stack.pop()
                else:
                    break
        elif x in ('&', '|', '*', '+', '!'):    #如果遇到运算符则比较其优先级
            if len(stack) == 0:
                stack.append(x)
                continue
            while (x == '!' and stack[-1] =='!') or \
                  (x == '&' and stack[-1] in ('!', '&')) or \
                  (x == '|' and stack[-1] in ('!', '&', '|')) or \
                  (x == '*' and stack[-1] in ('!', '&', '|', '*')) or \
                  (x == '+' and stack[-1] in ('!', '&', '|', '*', '+')):
                val = stack.pop()
                output.append(val)
                if not stack:
                    break
            stack.append(x)
    while stack:    #处理完毕后把stack列表的运算符转移至output列表
        output.append(stack.pop())
    return ''.join(output)

def Logica_operation(tmp):
    global idx
    idx = 0  # 当前命题元素的位置
    while len(tmp) > 1:  # 当最后命题仅为真值后,退出循环
        if tmp[idx] in Priority:
            if tmp[idx] == '!':  # 非
                # 把命题变元进行转换,根据后缀表达式,一定满足idx的前1位或前2位是真值而不是运算符
                tmp[idx - 1] = 1 if int(tmp[idx - 1]) == 0 else 0
                tmp[idx:idx + 1] = []  # 子命题结果对原命题覆盖
                # 处理完毕后回到命题起点继续运算
                idx = 0
                continue
            elif tmp[idx] == '&':  # 与
                tmp[idx] = 1 if int(tmp[idx - 1]) == 1 and int(tmp[idx - 2]) == 1 else 0
                tmp[idx - 2:idx] = []
                idx = 0
                continue
            elif tmp[idx] == '|':  # 或
                tmp[idx] = 0 if int(tmp[idx - 1]) == 0 and int(tmp[idx - 2]) == 0 else 1
                tmp[idx - 2:idx] = []
                idx = 0
                continue
            elif tmp[idx] == '*':  # 蕴含
                tmp[idx] = 0 if int(tmp[idx - 2]) == 1 and int(tmp[idx - 1]) == 0 else 1
                tmp[idx - 2:idx] = []
                idx = 0
                continue
            elif tmp[idx] == '+':  # 等值
                tmp[idx] = 1 if int(tmp[idx - 2]) == int(tmp[idx - 1]) else 0
                tmp[idx - 2:idx] = []
                idx = 0
                continue
        idx = idx + 1
    print(tmp[0])

def End(idx):
    global expr
    if idx == len(enum): # 递归终止条件为枚举完全部的变元
        print('\t'.join(list(enum.values())),end='\t') # 打印出枚举情况
        tmp = ' '.join(expr) # tmp为对命题处理带入真值的中间量
        for x in expr:
            if x in enum:
                tmp = tmp.replace(x, enum[x])
        tmp = tmp.split(' ') # 转化成list,由于字符串内部不能修改
        Logica_operation(tmp)
        return
    enum[var[idx]] = '0' # 枚举False,最后在转换为int类型,使得可使用字符串替换,把0,1代入
    End(idx+1) # 接着对下一位变元枚举
    enum[var[idx]] = '1' # 枚举True
    End(idx+1)

if int(Choose)==2:
    print("定义:"'\n'"————————————————"'\n'"|   !: 非     &: 与     |: 或  |"'\n'"|       *: 蕴含    +: 等值     |"'\n'"————————————————"'\n'"命题公式例子:"'\n'"(p*q)&!r // p&q|r*q&!s|r"'\n')
    inp = input("请输入命题公式:")
    expr = postfix(inp)  # expr为生成的后缀表达式
    var = list()  # var为命题变元
    for item in expr:
    # 找出变元且不能重复
        if item not in Priority and \
            item not in var and \
            item not in ('(', ')'):
            var.append(item)
            # 对变元枚举TF字典
    enum = {}.fromkeys(var)
    # 打印表头
    print('\t'.join(var),end='\t')
    print(inp)
    # 从第一个变元枚举
    End(0)
elif int(Choose)==1:
     True_value()

四、运行结果演示

  • 8
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值