真值表-Python实现

实验内容

  1. 设命题变元 P1、P2、P3、…、Pn 是出现在公式 G 中的所有命题变元,指定 P1、 P2、P3、…、Pn的一组真值,则这组真值称为 G 的一个解释或指派,常记为I
  2. 真值表:公式 G 在其所有可能的解释下所取真值的表

本实验要求从键盘输入一个命题公式列出其真值表。

程序设计

实现真值表难点在于:

  1. 对变元的 T(True) F(False) 的枚举,相当于未知阶的嵌套循环,对此应用递归解决
    对此首先找到递归结束的标志,即把所有变元的TF都枚举出来
  2. 找到命题包含的变元很简单,只需要构造一个集合,或者使用列表
  3. 对于中缀表达式转换后缀表达式,请参考后缀表达式

代码实现

operators = ['!','&', '|', '*', '+'] # 按照优先级从高到低的顺序

def postfix(elements):
    global operators
    stack = list()
    output = list()
    for ele in elements:
        if ele not in operators and ele not in ('(',')'): #
            output.append(ele)
        # '(' 在运算符中优先级最小,其唯一出栈条件时遇到右括号
        elif ele == '(':
            stack.append(ele)
        # 若是 ) ,则出栈直到遇到 ( ,这里注意: ) 遇到的第一个 ( 一定是匹配的一对
        elif ele == ')':
            val = stack.pop()
            while val !='(':
                output.append(val)
                if stack:
                    val = stack.pop()
                else:
                    break
        elif ele in ('&', '|', '*', '+', '!'): # 遇到运算符,比较优先级
            if len(stack) == 0:
                stack.append(ele)
                continue
            # 比较该运算符与栈顶运算符的优先级,遇到比该运算符优先级大于或等于的则将其弹出,最后将该运算符压栈
            while (ele == '!' and stack[-1] =='!') or \
                    (ele == '&' and stack[-1] in ('!', '&')) or \
                    (ele == '|' and stack[-1] in ('!', '&', '|')) or \
                    (ele == '*' and stack[-1] in ('!', '&', '|', '*')) or \
                    (ele == '+' and stack[-1] in ('!', '&', '|', '*', '+')):
                val = stack.pop()
                output.append(val)
                if not stack:
                    break
            stack.append(ele)
    while stack: # 当表达式完全处理完之后,把栈中的运算符一一出栈,FILO,转化成后缀表表达式
        output.append(stack.pop())
    return ''.join(output)

def logicalOp(tmp):
    idx = 0  # 当前命题元素的位置
    while len(tmp) > 1:  # 当最后命题仅为真值后,退出循环
        if tmp[idx] in operators:
            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 += 1
    print(tmp[0])

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

if __name__=='__main__':
    """
    Attention :
    定义:
    !:非 (单命题变元)
    &:合取
    |:析取
    *:单条件(则)
    +:双条件(当且仅当)
    """
    print('please input the problem\tExample:  (p*q)&!r  p&q|r*q&!s|r')
    inp = input('>>>')
    expr = postfix(inp)  # expr为生成的后缀表达式
    var = list()  # var为命题变元
    for item in expr:
        # 找出变元且不能重复
        if item not in operators and \
                item not in var and \
                item not in ('(', ')'):
            var.append(item)
    # 对变元枚举TF字典
    enum = {}.fromkeys(var)
    # 打印表头
    print('\t'.join(var),end='\t')
    print(inp)
    # 从第一个变元枚举
    e(0)
Attention :
定义:
!:非 (单命题变元)
&:合取
|:析取
*:单条件(则)
+:双条件(当且仅当)

please input the problem	Example:  (p*q)&!r  p&q|r*q&!s|r
>>>p&q|r*q&!s|r
p	q	r	s	p&q|r*q&!s|r
0	0	0	0	1
0	0	0	1	1
0	0	1	0	1
0	0	1	1	1
0	1	0	0	1
0	1	0	1	1
0	1	1	0	1
0	1	1	1	1
1	0	0	0	1
1	0	0	1	1
1	0	1	0	1
1	0	1	1	1
1	1	0	0	1
1	1	0	1	0
1	1	1	0	1
1	1	1	1	1
  • 9
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 在Python中,可以通过真值表来判断一个逻辑表达式的真假。首先,我们需要定义逻辑表达式的各个变量和对应的可能取值。然后,根据真值表中的每一行,将变量赋予不同的取值,并计算逻辑表达式的结果。 假设逻辑表达式是由n个变量组成,那么对于每一个变量,可以用0和1来表示其可能的取值。通过计算不同的取值组合,可以生成真值表。例如,如果表达式为A and B,则其真值表如下所示: A B Result 0 0 0 0 1 0 1 0 0 1 1 1 在Python中,可以使用循环嵌套来遍历所有的取值组合。首先,定义变量的取值范围和表达式。然后,使用两个嵌套的for循环来生成不同的取值组合,并将其赋给变量。在每一轮循环中,计算逻辑表达式的结果,并将结果输出。 以下是一个实现的示例代码: ```python variables = ['A', 'B'] expression = '(A and B)' # 生成真值表的表头 header = '\t'.join(variables + ['Result']) print(header) # 遍历所有取值组合 for i in range(2): for j in range(2): # 将当前取值组合赋给变量 values = [i, j] # 计算逻辑表达式的结果 result = int(eval(expression, dict(zip(variables, values)))) # 将取值组合和计算结果转换为字符串,以制表符分隔 row = '\t'.join(map(str, values + [result])) print(row) ``` 通过以上代码,可以得到逻辑表达式的真值表。根据实际需要,可以修改变量和表达式的值,以及输出的格式。这种方法可以用来处理任何逻辑表达式的真值判断。 ### 回答2: 要基于Python实现通过真值表判断一个逻辑表达式,可以采取以下步骤: 1. 定义逻辑表达式:首先,可以通过字符串的方式输入逻辑表达式,例如:"A and B or C"。在这个例子中,我们使用了逻辑运算符"and"和"or",以及变量"A"、"B"和"C"。这里假设所有变量的值只有两种可能,即True和False。 2. 生成真值表:接下来,可以通过遍历所有可能的变量取值组合,生成真值表。对于变量"A"、"B"和"C"来说,共有2^3=8种可能的取值组合,可以用二进制表示为000, 001, 010, 011, 100, 101, 110, 111。将这些二进制数字转换为True和False的组合,就可以得到真值表。 3. 解析逻辑表达式:将逻辑表达式转换为可以计算的形式,例如将"and"转换为"and"操作符,将"or"转换为"or"操作符。可以使用Python中的eval函数来实现此功能。例如,eval("True and False")的结果为False。 4. 计算结果:对于真值表中的每一行,根据逻辑表达式的计算规则,将变量替换为相应的取值,用步骤3中的方法计算逻辑表达式的结果。将结果保存在一个列表中,即可以得到逻辑表达式对于每个取值组合的结果。 5. 输出结果:最后,可以根据结果列表生成输出,例如打印出每个取值组合和对应的结果。 整个过程可以通过编写Python函数来实现,并在主程序中调用该函数进行测试。此外,为了提高程序的可读性和可扩展性,还可以考虑加入输入校验、异常处理和模块化设计等。 ### 回答3: 首先,在Python实现通过真值表判断一个逻辑表达式,可以采用以下步骤: 1. 创建一个真值表真值表是一个二维列表,其中每一行表示一个输入的组合,每一列表示对应输入组合下的输出值。根据逻辑表达式中的变量个数来确定真值表的行数,根据变量可能的取值(True和False)来确定真值表的列数。例如,如果逻辑表达式有两个变量,那么真值表将有4行(2^2)。 2. 获取逻辑表达式:从用户或其他来源获取逻辑表达式,可以通过输入或直接在代码中定义。 3. 解析逻辑表达式:将逻辑表达式解析成运算符和变量的组合。可以使用库函数或自己编写解析函数。 4. 根据解析后的逻辑表达式,计算真值表中每一行对应的输出。 5. 比较计算得到的输出与真值表中的输出,判断逻辑表达式的真值。 以下是通过Python实现上述步骤的示例代码: ```python import itertools def evaluate_expression(expression, values): # 表达式求解逻辑,根据需要自行实现 def get_truth_table(variables): # 根据变量个数获取真值表 n = len(variables) truth_table = list(itertools.product([True, False], repeat=n)) return truth_table def main(): variables = input("请输入逻辑表达式中的变量,以逗号分隔: ").split(",") truth_table = get_truth_table(variables) expression = input("请输入逻辑表达式(使用逻辑运算符): ") for row in truth_table: values = dict(zip(variables, row)) output = evaluate_expression(expression, values) print("输入:{},输出:{}".format(values, output)) if __name__ == "__main__": main() ``` 上述代码示例中,`evaluate_expression`函数实现了表达式求解的逻辑,根据具体的逻辑运算符定义并计算输出值。`get_truth_table`函数用于生成真值表,采用`itertools.product`函数生成变量可能的取值组合。`main`函数获取用户输入的变量和逻辑表达式,并通过循环计算真值表中的每一行对应的输出值。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值