计算机自动求解命题公式的主范式
- 格式:doc
- 大小:228.00 KB
- 文档页数:21
收稿日期:2006 04 19.作者简介:张会凌(1954 ),男,甘肃成县人,甘肃联合大学数学与信息学院副教授,主要从事微分几何与计算机方面的研究.文章编号:1672 691X(2006)05 0049 04命题公式主范式的自动生成与形式输出张会凌(甘肃联合大学数学与信息学院,甘肃兰州730000)摘 要:在文[1]和文[2]的基础上,给出了命题逻辑中任一命题公式的主析取范式和主合取范式的自动生成算法,并实现了多个命题公式主范式的同时形式化输出.关键词:命题公式;主析取范式;主合取范式;自动生成;形式输出中图分类号:T P301.1 文献标识码:A求一个给定的命题公式的主析取范式((Spe cial)Disjunctive No rmal Form,简记为DNF)与主合取范式((Special )Conjunctive Nor mal For m,简记为CNF)是命题逻辑中一类很重要的工作.因为命题公式的主范式(主合取与主析取范式的总称)是DDP 分解和进一步进行机器处理的基础.通常求主范式的方法有二.一是将已知命题公式等值变换为所要求的主范式;二是列出真值表后,根据真值表写出相应的极大项和极小项,最后写出主合取范式与主析取范式.当给定的命题公式所含命题变元较多或公式的构成比较复杂时,用这两种方法求其主范式总是有很大的工作量且容易出错.由于我们已经在[1]和[2]中成功地解决了任一含n 个变元的命题公式F 的基本真值矩阵A n 和B n 的生成算法,以及F 的真值表的计算和输出问题,故可在此基础上参考用手工写出主范式的方法,给出在计算机上计算和输出主范式的算法.在这里,关键是如何根据给定的命题公式按照要求形式地输出正确的主范式.本文仍用N-S 图给出针对所要解决的问题的核心算法,而将源程序略去.1 主合取范式的自动计算与输出命题公式F(P 0,P 1, ,P n -1)的主合取范式CNF 是若干关于命题变元P 0,P 1, ,P n -1的极大项 P 0 P 1 P n -1的合取,其中 P i 为P i 或 P i (i =0,1, ,n -1),CNF 必与F 等价.当不考虑极大项的排列顺序时,F 的CNF 是惟一的.此处为极大项的排列规定一个顺序.对于每个极大项 P 0 P 1 P n -1,使其对应一个二进制数 0 1 n -1,其中1=0,若 P 1为P i ;1,若 P 1为 P i .并且规定,对应的二进制数小的极大项排在前面.二进制数0 1 n -1可看成对应极大项的编码.这种规定保证了CNF 表示的惟一性,以及在形式上的统一.在将F 的真值表!横排∀后,从左到右依次求得极大项后再将其合取,结果即与这里的规定完全一致.为了在某种特定的编程语言(如C 语言)环境下形象地输出主范式,约定当两个命题变元或两个子公式之间用逻辑联结符#联结时,!#∀可以省去.而当它们用逻辑联结符 联结时,则用两个半角字符!\∀和!/∀的组合! ∀表示.逻辑非的符号! ∀用!!∀代替(下同).下面给出计算和输出主合取范式的算法模块.假定需要求N 个命题公式F 0,F 1, ,F N -1的主合取范式,而基本真值矩阵B n =(b ij )和这N 个命题公式F 的真值表构成的矩阵F V (见[2])已经求出,这里矩阵F V 的第k 行是公式F k 的真值.为了把永真式(即重言式)的主合取范式按1输出,把永假式(即矛盾式)的主析取范式按0输出,先以流程图1给出一个识别模块M 1.这样,在这N 个命题公式中,某个F k 是永真式当且仅当其对应的g k =1,是永假式当且仅当第20卷第5期甘肃联合大学学报(自然科学版)V o l.20No.5 2006年9月Jo urnal of G ansu L ianhe U niv ersity (N atural Sciences)Sept.2006图1 关于永真式和永假式的识别模块Fig ure1 An ident ifying module fortauto log y and co nt radiction其对应的s k =0.于是在计算出真值表并运行了上面的识别模块之后,同时计算和输出多个命题公式的主合取范式的算法模块如图2所示.图2 计算和输出多个命题公式的主合取范式的算法模块Fig ure2 Algo rithm mo dule calculating and outputting CN F o f sev eral pr opositional fo rmulea算法中把永真式的主合取范式按1输出.必须强调的是,此模块对命题公式的主合取范式的输出是形式上的,是对手工列真值表,然后根据真值表写出主合取范式的过程的模拟.主析取范式DNF 的输出也是形式上的.2 主析取范式的自动计算和输出命题公式F(P 0,P 1, ,P n -1)的主析取范式DNF 是若干关于命题变元P 0,P 1, ,P n -1的极小项 P 0# P 1# # P n -1的析取,其中 P i 为P i 或 P i (i =0,1, ,n -1),DNF 必与F 等价.同样,当不考虑极小项的排列顺序时,F 的DNF 是惟一确定的.为了保证DNF 在内容和形式上都惟一,类似地为极小项的排列规定一个顺序.对于每个极小项 P 0# P 1# # P n -1,使其对应一个二进制数 0 1 n -1,其中i =0,若 P 1为 P i ;1,若 P i 为P i .规定对应的二进制数小的极小项排在前面.二进制数 0 1 n -1可看成对应极小项的编码.假定命题公式的基本真值矩阵B n 和N 个命题公式F 的真值表构成的矩阵F V 已经求出,则计算和输出N 个命题公式的主析取范式的算法如图3所示.算法中把永假式的主析取范式按0输出.在主析取范式中,极小项用圆括号括起来,各个极小项之间是用析取符号! ∀联结的.标志变量r 的作用是为了避免在最后一个极小项的右括号!)∀之后再打印一个多余的! ∀.例 给出两个命题公式F 0= (P 0 P 1 P 2 P 3)和F 1=(P 0#P 1)∃(P 2∃ P 3),求它们的主合取范式与主析取范式.将所给的两个命题公式输入,依据上面的算法编程运行,则系统有如下的输出结果.公式F 0和F 1的真值表是(如[2]所示,输出的真值表是一般的教科书上的真值表的!转置∀):P[0] 0000000011111111P[1]0000111100001111P[2]0011001100110011P[3]0101010101010101F 0010000000000000050甘肃联合大学学报(自然科学版) 第20卷F10110011001101111图3 计算和输出多个命题公式的主析取落式的算法模块F igure3 A lg or ithm module calculating and outputt ing DN F o f sev eral pr oposit ional fo rmulae公式F0的主合取范式是:(P0\/P1\/P2\/P3)(P0\/P1\/!P2\/ P3)(P0\/P1\/!P2\/!P3)(P0\/!P1\/P2 \/P3)(P0\/!P1\/P2\/!P3)(P0\/!P1\/!P2\/P3)(P0\/!P1\/! P2\/!P3)(!P0\/P1\/P2\/P3)(!P0\/P1 \/P2\/!P3)(!P0\/P1\/!P2\/P3)(!P0\/P1\/!P2\/!P3)(!P0\/!P1 \/P2\/P3)(!P0\/!P1\/P2\/!P3)(!P0 \/!P1\/!P2\/P3)(!P0\/!P1\/!P2\/! P3)公式F1的主合取范式是:(P0\/P1\/P2\/P3)(P0\/P1\/!P2\/! P3)(P0\/!P1\/P2\/P3)(P0\/!P1\/!P2\/!P3)(!P0\/P1\/P2\/P3)(!P0\/P1\/!P2\/!P3)公式F0的主析取范式是:(!P0!P1!P2P3)公式F1的主析取范式是:(!P0!P1!P2P3)\/(!P0!P1P2! P3)\/(!P0P1!P2P3)\/(!P0P1P2! P3)\/(P0!P1!P2P3)\/(P0!P1P2!P3)\/(P0P1!P2!P3) \/(P0P1!P2P3)\/(P0P1P2!P3)\/ (P0P1P2P3)尽管所给的例子中只有4个命题变元,用手工计算列出的真值表也有16行.直接计算主合取范式和主析取范式进行核对,可知程序输出的结51第5期 张会凌:命题公式主范式的自动生成与形式输出果是完全正确的.当命题变元数n%5时,自动计算和输出主范式的优点显得尤为突出.本文所给的算法已在C语言和VC环境下完全实现.参考文献:[1]张会凌.命题逻辑判定系统中基本真值矩阵的生成算法[J].甘肃联合大学学报(自然科学版),2005,19(1):16 19.[2]张会凌.命题公式真值表的生成与公式类型的机械判定[J].甘肃联合大学学报(自然科学版),2006,20(1):25 34.Automatic Generation and Formal Output of Special Normal Forms ofPropositional FormulaeZH A N G H ui ling(School of M at hematics and Info rmatio n,Gansu L ianhe U niversity,Lanzho u730000,China)Abstract:Based on paper[1]and[2],this paper g iv es tw o g enerating alg orithms to calculate and out put the special co njunctiv e no rmal for ms and special disjunctiv e fo rms of g iven pro positio nal for mulas automatically and form ally.Key words:pro positional form ula;special conjunctive nor mal form;special disjunctive normal fo rm;au to matic g eneration;form al output(上接第3页)[6]教育部办公厅.高等学校学报管理办法[S].中国高等学报自然科学学报研究会.会讯,1998(总30):封二.[7]孙德存.地方高校的本地化定位[J].吉昌学院学报,2004(4):72 74.[8]窦炎国,周继红.努力为地方经济、社会服务[J].苏州科技学院学报(社科版),2004,21(3):135 138.Exploratory Advancing and Pioneering Innovating&&&J ournal of G ansu L ianhe Univer sity(Ed ition of N atural S cience)Has Finished Its Publication for21YearsZH AN G Fu long(Department of Journal of Gansu L ianhe U niver sity,L anzho u730070,China)Abstract:T he autho r review s the development course of J our nal of G ansu L ianhe Univ ersity(Edition o f N atur al S cience),analyzes and sums up the practical ex perience o f running the jo urnal and their a chievement.H e also po ints out the future orientation.Key words:jour nal(edition o f natural science);teaching;scientific research;tr aining of talent;ex plora tion;review52 甘肃联合大学学报(自然科学版) 第20卷。
离散数学上机实验指导徐凤生如果你需要索取源程序,请发邮件至xfs@。
实验11实验内容(1)求任意一个命题公式的真值表。
(2)利用真值表求任意一个命题公式的主范式。
(3)利用真值表进行逻辑推理。
注:(2)和(3)可在(1)的基础上完成。
2实验目的真值表是命题逻辑中的一个十分重要的概念,利用它几乎可以解决命题逻辑中的所有问题。
例如,利用命题公式的真值表,可以判断命题公式的类型、求命题公式的主范式、判断两命题公式是否等价,还可以进行推理等。
本实验通过编写一个程序,让计算机给出命题公式的真值表,并在此基础上进行命题公式类型的判定、求命题公式的主范式等。
目的是让学生更加深刻地理解真值表的概念,并掌握真值表的求解方法及其在解决命题逻辑中其他问题中的应用。
3算法的主要思想利用计算机求命题公式真值表的关键是:①给出命题变元的每一组赋值;②计算命题公式在每一组赋值下的真值。
真值表中命题变元的取值具有如下规律:每列中0和1是交替出现的,且0和1连续出现的个数相同。
n个命题变元的每组赋值的生成算法可基于这种思想。
含有n个命题变元的命题公式的真值的计算采用的方法为“算符优先法”。
为了程序实现的方便,约定命题变元只用一个字母表示,非、合取、析取、条件和双条件联结词分别用!、&、|、-、+来表示。
算符之间的优先关系如表1-32所示:为实现算符优先算法,另一个称作OPND,用以寄存操作数或运算结果。
算法的基本思想是:(1)首先设置操作数栈为空栈,符号“@”为运算符的栈底元素;(2)调用函数Divi(exp,myopnd)得到命题公式包含的命题变元序列myopnd(按字典序排列,同一个命题变元只出现一次);(3)依次读入命题公式中的每个字符,若是命题变元则其对应的赋值进OPND栈,若是运算符,则和OPTR栈的栈顶运算符比较后作相应操作,直至整个命题公式求值完毕。
实验21实验内容(1)求任意两个集合的交集、并集、差集。
(2)求任意一个集合的幂集。
含3个命题变项的命题公式的主合取范式是指将命题公式中的所有合取项都列出,并且将其中的命题变项取值情况都考虑进去,然后对这些合取项进行合取运算得到的一个式子。
那么,如何找到一个命题公式的主合取范式呢?我们需要找出命题公式中的所有合取项。
一个命题公式可以分解为多个合取项,每个合取项中包含若干个命题变项以及它们的否定。
对于含有3个命题变项的命题公式来说,我们需要列出所有可能的合取项。
这样的合取项总数是有限的,因为每个命题变项可以取真或假两种情况,所以总共有2^3=8种可能的合取项。
我们需要根据这8种合取项的取值情况进行合取运算。
合取运算的结果是真当且仅当所有合取项中的命题变项都取真。
我们可以根据这8种合取项的取值情况,得到合取运算的结果。
这个结果就是命题公式的主合取范式。
举个例子来说,如果我们有一个命题公式为(A∨¬B∨C)∧(¬A∨B∨¬C),其中A、B、C分别为三个命题变项。
那么我们首先列出所有可能的合取项:A为真,B为真,C为真,合取项为真;A为真,B为真,C为假,合取项为真;A为真,B为假,C为真,合取项为真;A为真,B为假,C为假,合取项为假;A为假,B为真,C为真,合取项为假;A为假,B为真,C为假,合取项为真;A为假,B为假,C为真,合取项为假;A为假,B为假,C为假,合取项为假。
我们进行合取运算,将所有合取项为真的情况进行合取运算,得到的结果就是命题公式的主合取范式。
含有3个命题变项的命题公式的主合取范式可以通过列出所有合取项的取值情况,并进行合取运算得到。
这样的方法可以很好地帮助我们理解命题公式的结构和逻辑含义。
个人观点上,我认为找到一个命题公式的主合取范式对于理解命题逻辑和解决相关问题是非常有帮助的。
通过找到主合取范式,我们可以清晰地看到命题公式中各个命题变项的逻辑关系,从而更好地理解整个命题公式的含义和结构。
对于含有多个命题变项的命题公式来说,找到其主合取范式是非常重要的。
命题逻辑中的析取范式与合取范式命题逻辑是形式逻辑的一个分支,主要研究命题之间的逻辑关系。
其中,析取范式(Disjunctive Normal Form,DNF)和合取范式(Conjunctive Normal Form,CNF)是常见的逻辑表达形式。
本文将详细介绍析取范式和合取范式的定义、性质以及在命题逻辑中的应用。
一、析取范式(DNF)1.1 定义在命题逻辑中,析取范式是一种命题逻辑公式的标准形式,即由多个子句的析取组成的命题逻辑公式。
子句是由多个命题变量的析取构成,形如 (p1 ∨ p2 ∨ ... ∨ pn),其中 p1、p2、...、pn 是命题变量或者它们的否定。
1.2 性质(1) 析取范式可以通过使用分配律和德摩根定律推导得到。
(2) 析取范式可以表达任意逻辑公式,即任意逻辑公式都可以转化为析取范式的形式。
1.3 应用(1) 析取范式在工程和计算机科学中有着广泛应用。
例如,在电路设计中,可以使用析取范式来描述不同的输入输出关系。
(2) 析取范式还可以在知识表示和推理的领域中应用,用于描述和推理复杂的逻辑关系。
二、合取范式(CNF)2.1 定义在命题逻辑中,合取范式是一种命题逻辑公式的标准形式,即由多个子句的合取组成的命题逻辑公式。
子句是由多个命题变量的合取构成,形如 (p1 ∧ p2 ∧ ... ∧ pn),其中 p1、p2、...、pn 是命题变量或者它们的否定。
2.2 性质(1) 合取范式可以通过使用分配律和德摩根定律推导得到。
(2) 合取范式可以表达任意逻辑公式,即任意逻辑公式都可以转化为合取范式的形式。
2.3 应用(1) 合取范式在逻辑推理和知识表示中具有重要作用。
例如,在人工智能的专家系统中,可以使用合取范式来表示专家知识,并进行推理和决策。
(2) 合取范式也可以应用于自动化推理、模型检查和程序验证等领域,用于描述和分析复杂系统的逻辑关系。
三、析取范式与合取范式的关系3.1 转化关系在命题逻辑中,任意逻辑公式都可以转化为析取范式和合取范式。
3 计算机自动求解命题公式的主范式一.需求分析(1)用户输入一任意命题公式,计算机程序自动输出其主析取范式和主合取范式。
(2)求任意一个命题公式的真值表,并根据真值表求主范式。
(3)关于命题公式的形式和运算符(即联结词)的运算首先根据离散数学的相关知识,命题公式由命题变元和运算符(即联结词)组成,命题变元用大写字母英文表示(本次试验没有定义命题常元T和F,即T、F都表示命题变元),每个命题变元都有两种真值指派0和1,对应于一种真值指派,命题公式有一个真值,由所有可能的指派和命题公式相应的真值按照一定的规范构成的表格称为真值表。
目前离散数学里用到的包括扩充联结词总共有九种,即析取(或)、合取(与)、非、蕴含、等值、与非、或非、异或、蕴含否定,常用的为前五种,其中除了非运算为一元运算以外,其它四种为二元运算。
所以本次实验设计时只定义了前五种运算符,同时用“/”表示非,用“*”表示合取,用“+”表示析取,用“>”表示蕴含,用“:”表示等值,且这五种运算符的优先级依次降低,如果需用括号改变运算优先级,则用小括号()改变。
以下为上述五种运算符运算时的一般真值表,用P和Q表示命题变元:1.非,用“/”表示2. 合取(与),用“*”表示3.析取(或),用“+”表示4.蕴含,用“>”表示5.等值,用“:”表示下面是求取后缀表达式的规则:1.从中缀表达式左边起逐个字符判断,如果是命题变元,则直接输出;如果是运算符,则将其与当前有效栈顶字符(即非空,可能为运算符或左半括号;如果栈为空,则直接入栈)的优先级比较,如果大于栈顶字符优先级,则直接入栈,如果小于或等于栈顶字符优先级,则弹出栈中字符并输出,直到大于栈顶字符优先级;2.如果遇到左半括号,则直接入栈,也就是栈外左半括号的优先级最高,入栈以后,其优先级变为最低,也就是不管下一个字符是什么,该左半括号都不出栈,当且仅当遇到与其对应的右半括号时(遇到右半括号前,所有的字符按1中的规则或左半括号的入栈规则入栈或出栈),将栈中该左半括号以上的字符按照出栈规则弹出并输出,最后该左半括号出栈并和右半括号一起被丢掉(右半括号永不入栈),余下的字符不出栈;3.按照上述规则判断命题公式中的所有字符后,如果栈中还有有效字符,则依次弹出并输出。
3 计算机自动求解命题公式的主范式一.需求分析(1)用户输入一任意命题公式,计算机程序自动输出其主析取范式和主合取范式。
(2)求任意一个命题公式的真值表,并根据真值表求主范式。
(3)关于命题公式的形式和运算符(即联结词)的运算首先根据离散数学的相关知识,命题公式由命题变元和运算符(即联结词)组成,命题变元用大写字母英文表示(本次试验没有定义命题常元T和F,即T、F都表示命题变元),每个命题变元都有两种真值指派0和1,对应于一种真值指派,命题公式有一个真值,由所有可能的指派和命题公式相应的真值按照一定的规范构成的表格称为真值表。
目前离散数学里用到的包括扩充联结词总共有九种,即析取(或)、合取(与)、非、蕴含、等值、与非、或非、异或、蕴含否定,常用的为前五种,其中除了非运算为一元运算以外,其它四种为二元运算。
所以本次实验设计时只定义了前五种运算符,同时用“/”表示非,用“*”表示合取,用“+”表示析取,用“>”表示蕴含,用“:”表示等值,且这五种运算符的优先级依次降低,如果需用括号改变运算优先级,则用小括号()改变。
以下为上述五种运算符运算时的一般真值表,用P和Q表示命题变元:1.非,用“/”表示2. 合取(与),用“*”表示3.析取(或),用“+”表示4.蕴含,用“>”表示5.等值,用“:”表示下面是求取后缀表达式的规则:1.从中缀表达式左边起逐个字符判断,如果是命题变元,则直接输出;如果是运算符,则将其与当前有效栈顶字符(即非空,可能为运算符或左半括号;如果栈为空,则直接入栈)的优先级比较,如果大于栈顶字符优先级,则直接入栈,如果小于或等于栈顶字符优先级,则弹出栈中字符并输出,直到大于栈顶字符优先级;2.如果遇到左半括号,则直接入栈,也就是栈外左半括号的优先级最高,入栈以后,其优先级变为最低,也就是不管下一个字符是什么,该左半括号都不出栈,当且仅当遇到与其对应的右半括号时(遇到右半括号前,所有的字符按1中的规则或左半括号的入栈规则入栈或出栈),将栈中该左半括号以上的字符按照出栈规则弹出并输出,最后该左半括号出栈并和右半括号一起被丢掉(右半括号永不入栈),余下的字符不出栈;3.按照上述规则判断命题公式中的所有字符后,如果栈中还有有效字符,则依次弹出并输出。
以/A*(B+/C)为例,说明后缀表达式的求法:(二)概要分析。
(三)详细设计1、输入合法命题公式的地址。
其流程图如下四、调试分析在输入命题公式时要注意输入格式区分大小写,要理解程序的含义五、使用说明输入任意命题公式,按回车结束,然后会列出真值表,根据真值表会列出其主析取主合取范式。
得到客户需要的结果。
六、源程序清单#include <stdio.h>#include <stdlib.h>#include <string.h>/*-----------------------------------------------------------------------*/ //Read the propositional formula, and judges its validity, if the illegal to re-enter/*-----------------------------------------------------------------------*/ char *pp,formula[100]={0};int valid=1;char *getformula(){char temp[100]={0},tempsign[3]={0};int i,j,len,flag=0;printf("\nPlease enter a propositional formula\n");printf("\n\"/\"said non,\"*\"to denote conjunction,\"and\"said disjunction,\",\"said contains,\"said:\"equivalent\n");printf("\n brackets are\"\"()said:\n");printf("\nPropositional variable uppercase English letters, to the end of the Enter key input:\n\n");while(flag==0){gets(temp);if(temp[0]=='\0'){valid=0;break;}for(j=0,i=0;*(temp+i);i++)if(*(temp+i)!=' '){*(formula+j)=*(temp+i);j++;}len=strlen(formula);if(!(formula[len-1]>=65&&formula[len-1]<=90||formula[len-1]==')')|| !((formula[0]>=65&&formula[0]<=90)||formula[0]=='('||formula[0]= ='/'))flag=0;else{for(pp=formula;*pp!='\0';pp++){if(!((*pp>=65&&*pp<=90)||*pp=='/'||*pp=='*'||*pp=='+'||*pp=='>'||*pp==':'||*pp= ='('||*pp==')')){flag=0;break;}else{tempsign[0]=*pp;tempsign[1]=*(pp+1);tempsign[2]='\0';if(strcmp(tempsign,"(+")==0||strcmp(tempsign,"(*")==0||strcmp(tempsign,"/)")==0 ||strcmp(tempsign,"+)")==0||strcmp(tempsign,"*)")==0||strcmp(tempsign,")/")==0||strcmp(tempsign,"*+")==0||strcmp(tempsign,"/*")==0||strcmp(tempsign,")(")==0||strcmp(tempsign,"+*")==0||strcmp(tempsign,"/+")==0||strcmp(tempsign,"()")==0||strcmp(tempsign,">+")==0||strcmp(tempsign,"+>")==0||strcmp(tempsign,"*>")==0||strcmp(tempsign,">*")==0||strcmp(tempsign,"(>")==0||strcmp(tempsign,">)")==0||strcmp(tempsign,"/>")==0||strcmp(tempsign,"+:")==0||strcmp(tempsign,":+")==0||strcmp(tempsign,"*:")==0||strcmp(tempsign,":*")==0||strcmp(tempsign,":>")==0||strcmp(tempsign,">:")==0||strcmp(tempsign,"/:")==0||strcmp(tempsign,"(:")==0|| strcmp(tempsign,":)")==0){flag=0;break;}if((tempsign[0]>=65&&tempsign[0]<=90)&&(tempsign[1]>=65&&tempsign[1]<=90)) {flag=0;break;}if(((tempsign[0]>=65&&tempsign[0]<=90)&&(tempsign[1]=='/'||tempsign[1]=='('))||((tempsign[1]>=65&&tempsign[1]<=90)&&tempsign[0]==')')){flag=0;break;}elseflag=1;}}}if(flag==0){printf("Expression is in error, please enter again:\n");for(i=0;*(temp+i)!='\0';i++)*(temp+i)='\0';for(i=0;*(formula+i)!='\0';i++)*(formula+i)='\0';}}pp=formula;// if(flag!=0)printf("%s",pp);return pp;}/*-----------------------------------------------------------------------*/ //Infix expression into a suffix expression is in error, please enter again /*-----------------------------------------------------------------------*/ char suf_formula[100]={0};char *convert_suffix(char *formula){// char plus,and,not,left,right;char stack[30],digit_stack[30];char *pt;int i=0,j=0,top=1,digit_top=1;pt=formula;for(i=0;*pt;pt++){if(*pt>=65&&*pt<=90)suf_formula[i++]=*pt;elseswitch(*pt)//优先级高低顺序,栈内(、:、>、+、*、/依次升高,分别用1、2、3、4、5、6表示 {case ':':// if(stack[0]=='\0')// {// stack[top++]='+';// digit_stack[digit_top++]=2;// }// else{for(;2<=digit_stack[digit_top-1];top--,digit_top--){suf_formula[i++]=stack[top-1];stack[top-1]='\0';digit_stack[digit_top-1]=0;}stack[top++]=':';digit_stack[digit_top++]=2;}break;case '>':// if(stack[0]=='\0')// {// stack[top++]='+';// digit_stack[digit_top++]=2;// }// else{for(;3<=digit_stack[digit_top-1];top--,digit_top--){suf_formula[i++]=stack[top-1];stack[top-1]='\0';digit_stack[digit_top-1]=0;}stack[top++]='>';digit_stack[digit_top++]=3;}break;case '+':// if(stack[0]=='\0')// {// stack[top++]='+';// digit_stack[digit_top++]=2;// }// else{for(;4<=digit_stack[digit_top-1];top--,digit_top--){suf_formula[i++]=stack[top-1];stack[top-1]='\0';digit_stack[digit_top-1]=0;}stack[top++]='+';digit_stack[digit_top++]=4;}break;case '*': //if(stack[0]=='\0')// {// stack[top++]='+';// digit_stack[digit_top++]=3;// }//elsefor(;5<=digit_stack[top-1];top--,digit_top--){suf_formula[i++]=stack[top-1];stack[top-1]='\0';digit_stack[digit_top-1]=0;}stack[top++]='*';digit_stack[digit_top++]=5;}break;case '/':// if(stack[0]=='\0')// {// stack[top++]='+';// digit_stack[digit_top++]=4;// }// else{for(;6<=digit_stack[top-1];top--,digit_top--){suf_formula[i++]=stack[top-1];stack[top-1]='\0';digit_stack[digit_top-1]=0;}stack[top++]='/';digit_stack[digit_top++]=6;}break;case '(': stack[top++]='(';digit_stack[digit_top++]=1;break;case ')': for(;stack[top-1]!='(';top--,digit_top--)suf_formula[i++]=stack[top-1];stack[top-1]='\0';digit_stack[digit_top-1]=0;}stack[top-1]='\0';digit_stack[top-1]=0;top--;digit_top--;break;default:;}}for(;top>=1;i++,top--){if(stack[top-1])suf_formula[i]=stack[top-1];}printf("\n");// printf("%s\n",suf_formula);return suf_formula;}/*---------------------------------------------------------------------------*/// Statistical suffix expression the variable/*---------------------------------------------------------------------------*/char var[16]={0};void variable(char *suf_formula){int i,j,len=0,flag=0;char temp;for(i=0;*(suf_formula+i);i++)//统计后缀表达式中的{ //变元if(suf_formula[i]>=65&&suf_formula[i]<=90) //{ //for(j=0;*(var+j);j++)if(suf_formula[i]==var[j]){flag=1;break;}if(flag!=1){len=strlen(var);var[len]=suf_formula[i];}flag=0;}}for(i=0;*(var+i);i++) //从小到大排列变元for(j=i+1;*(var+j);j++)if(var[i]>var[j]){temp=var[i];var[i]=var[j];var[j]=temp;}// return var;}/*-----------------------------------------------------------------------*/ // Calculate the value of the suffix expressions/*-----------------------------------------------------------------------*/ char normal_form[100][16]={0};void calc(char *suf_formula){char bin_val[16]={0}; //指派真值char suf_val[100]={0}; //后缀表达式相应的变元真值、运算符构成的序列inti,j,end=0,sum,result=1,index,temp_index,flag=0,xiqu_num=0,hequ_num=0;char *p,temp;int xiqu[50]={0},hequ[50]={0};variable(suf_formula);index=strlen(var);temp_index=index;if(index==0) //根据变元数计算指派的真值的最大值 result=1;elsefor(;temp_index>0;temp_index--)result=result*2;printf("\nExpression of truth value table as follows\n\n");for(i=0;*(var+i);i++)printf("%c ",*(var+i));printf("\t\t");printf("%s\n\n",formula);for(sum=0;sum<result;sum++){j=sum;for(i=0;i<16;i++)bin_val[i]=0+'0';for(i=0;j!=0;i++) //指派的真值以二进制字符串形式存储{bin_val[i]=j%2+'0';j=j/2;}// printf("%s\n",formula);// for(i=0;*(var+i);i++) //输出公式中所含变元// printf("%c ",*(var+i));// printf("\n");for(j=index;j>0;j--) //输出指派的真值printf("%d ",bin_val[j-1]-'0');// printf("\n");strcpy(suf_val,suf_formula);for(i=0;i<index/2;i++)//因变元(大写英文字母 )从小到大排列 ,以A为最高位,{ //而上面指派的真值刚好从bin_val低位(对应A位)开始,temp=bin_val[i]; //故需将真值序列反序bin_val[i]=bin_val[index-i-1];bin_val[index-i-1]=temp;}for(i=0;suf_formula[i];i++)for(j=0;var[j];j++)if(var[j]==suf_formula[i])suf_val[i]=bin_val[j];// printf("\n%s",suf_val);p=suf_val;for(i=0;*(p+i);) //计算由变元和运算符构成的后缀表达式 {switch(*(p+i)){case ':': if(*(p+i-1)==*(p+i-2)){*(p+i-2)='1';for(j=i+1;*(p+j);j++)*(p+j-2)=*(p+j);*(p+j-1)='\0';*(p+j-2)='\0';// printf("\n%s\n",suf_val);}else{*(p+i-2)='0';for(j=i+1;*(p+j);j++)*(p+j-2)=*(p+j);*(p+j-1)='\0';*(p+j-2)='\0';// printf("\n%s\n",suf_val); }i=0;break;case '>': if(*(p+i-1)=='0'&&*(p+i-2)=='1') {*(p+i-2)='0';for(j=i+1;*(p+j);j++)*(p+j-2)=*(p+j);*(p+j-1)='\0';*(p+j-2)='\0';// printf("\n%s\n",suf_val); }else{*(p+i-2)='1';for(j=i+1;*(p+j);j++)*(p+j-2)=*(p+j);*(p+j-1)='\0';*(p+j-2)='\0';// printf("\n%s\n",suf_val); }i=0;break;case '+': if(*(p+i-1)=='1'&&*(p+i-2)=='1') {*(p+i-2)='1';for(j=i+1;*(p+j);j++)*(p+j-2)=*(p+j);*(p+j-1)='\0';*(p+j-2)='\0';// printf("\n%s\n",suf_val);}else{*(p+i-2)=(*(p+i-2)-'0')+(*(p+i-1)-'0')+'0'; for(j=i+1;*(p+j);j++)*(p+j-2)=*(p+j);*(p+j-1)='\0';*(p+j-2)='\0';// printf("\n%s\n",suf_val);}i=0;break;case '*': *(p+i-2)= (*(p+i-2)-'0')*(*(p+i-1)-'0')+'0';for(j=i+1;*(p+j);j++)*(p+j-2)=*(p+j);*(p+j-1)='\0';*(p+j-2)='\0';// printf("\n%s\n",suf_val);for(j=i+1;*(p+j);j++)*(p+j-1)=*(p+j);*(p+j-1)='\0';// printf("\n%s\n",suf_val);i=0;break;default: i++;if(*(suf_val+1)=='\0')end=1;}if(end==1)break;}end=0;printf("\t\t%d\n",*p-'0');if(*p-'0'==1)xiqu[xiqu_num++]=sum+1;elseif(*p-'0'==0)hequ[hequ_num++]=sum+1;}printf("\nPrincipal disjunctive normal form is as follows:\n\n");for(i=0;xiqu[i]!=0;i++){printf("M%d",xiqu[i]-1);if(xiqu[i+1]!=0)printf("+");// if((i+1)%6==0) printf("\n");}printf("\n\nPrincipal conjunctive as follows:\n\n");for(i=0;hequ[i]!=0;i++){printf("m%d",hequ[i]-1);if(hequ[i+1]!=0)printf("*");// if((i+1)%6==0) printf("\n");}}/*-----------------------------------------------------------------------*/ // The main function/*-----------------------------------------------------------------------*/int main(){char *formula;formula=getformula();if(valid==1)//输入的表达式非空才可继续执行(即第一个字符不是回车符){convert_suffix(formula);calc(suf_formula);}getchar();return 0;}七截图是否 开始pp=formula ,i=-1i++,*(pp+i)(1) 真值i++,*(temp+i )非空 i=0 *(temp+i+1)非空 *(temp+i)=运算符 输出结果,即temp[0] 真值指派完毕 结束。