实现基于谓词逻辑的归结原理
人工智能第6章 谓词逻辑与归结原理

• 当量词仅对谓词的个体(变量)起限定作用,即谓词名视
为常量时,称其为一阶谓词(First Order Predication
Logic ).
• 若量词对个体和谓词都有限定作用时,称其为高阶谓词。 – 例如: Qy Q(y) 是二阶谓词; xyP( x, y) 是一阶谓词。 • 通常我们约定连接词和量词的优先级为:~, , 最高; 次
–连接 词: –量词:
全称量词
~ 否定(非); 合取(与); 析取(或); 蕴涵(IF......TH EN); 等价(双条件)
表示所有的,例如,对于所有个体x, 谓词F(x)均成立时,可表示为 x F ( x ) 表示存在某一些,例如,若存在某些个体x, 使谓词F(x)成立时,可表示为 x F ( x )
由于事先不知道哪两个子句可以进行归结更不知道通过对哪些子句对的归结可以尽快地得到空子句因而必须对子句集中的所有子句逐对地进行比较对任何一对可归结的子句对都进行归结这样的效率是很低的
第六章 谓词逻辑与归结原理
• 6.1 一阶谓词逻辑基础 • 6.2 归结法(消解Resolution) • 6.3 归结反演系统
4. 若A是合式公式,x是个体变量,则x(A)、
x(A)是合式公式。
•
所有合式公式都是有限次应用规则1~4得到的。
(1)谓词公式的解释
• 在应用谓词逻辑解决问题时,必须对谓词公式进行解释,即 人为地给谓词公式指派语义。
• 一阶谓词公式P的解释可有多种,其中一些解释可使P为真,
而另一些解释则可使P为假。
• 推理过程:反复使用谓词演算的基本等价式及推理规则, 对已知谓词公式进行变换,得到所需逻辑结论的过程。
6.1.6 谓词公式的规范化
为了方便使用WFF进行定理证明和逻辑推理,需要把 WFF变换为便于使用的规范形式,称为WFF范式。典型的 范式包括:前束范式,SKOLEM范式。
鲁滨逊归结原理

第5章 基于谓词逻辑的机器推理
推论 设C1,C2是子句集S的两个子句,C12是它们的 归结式,则 (1)若用C12代替C1,C2,得到新子句集S1,则由S1的 不可满足可推出原子句集S的不可满足。即 S1不可满足 S不可满足
(2) 若把 C12 加入到 S 中,得到新子句集 S2 ,则 S2 与
如果录取B,则一定录取C 求证:公司一定录取C
作业: 自然数都是大于零的整数,所有整数不是偶数就是奇
数,偶数除以2是整数。
证: 所有自然数不是奇数就是其一半为整数的数
第5章 基于谓词逻辑的机器推理
5.2.3 替换与合一 在一阶谓词逻辑中应用消解原理,不像命题逻辑中那样简 单,因为谓词逻辑中的子句含有个体变元,这就使寻找含互否 文字的子句对的操作变得复杂。例如: C1=P(x)∨Q(x)
k=0:
S0=S,σ0=ε, S0不是单元素集,D0={x,y} σ1=σ0·{y/x}={y/x} S1=S0{y/x}={P(y,y),P(y,f(y))}
k=1:
第5章 基于谓词逻辑的机器推理
S1不是单元素集,D1={y,f(y)},由于变元y在项 f(y)中出现,所以算法停止,S不存在最一般合一。 从合一算法可以看出,一个公式集S的最一般合一 可能是不唯一的,因为如果差异集Dk={ak,bk},且ak 和bk都是个体变元,则下面两种选择都是合适的:
中z是变元,且不在a中出现,所以有
σ1=σ0· { a/z } =ε· { a/z } = { a/z } S1=S0 { a/z } = {P(a,x,f(g(y))),P(a,h(a,u),f(u))} k=1: S1不是单元素集,求得D1={x,h(a,u)},
第5章 基于谓词逻辑的机器推理
人工智能第三章谓词逻辑与归结原理

• 所以要考虑置换与合一。即对变量 作适当的替换。
《人工智能》第三章 谓词逻辑与归结原理
置换
• 置换:可以简单的理解为是在一个谓词公式中用 置换项去置换变量。
• 定义: 置换是形如{t1/x1, t2/x2, …, tn/xn}的有限集合。其 中,x1, x2, …, xn是互不相同的变量,t1, t2, …, tn是 不同于xi的项(常量、变量、函数);ti/xi表示用ti 置换xi,并且要求ti与xi不能相同,而且xi不能循环 地出现在另一个ti中。
例如: {a/x,c/y,f(b)/z}是一个置换。 {g(y)/x,f(x)/y}不是一个置换。
《人工智能》第三章 谓词逻辑与归结原理
置换的合成
• 设={t1/x1, t2/x2, …, tn/xn}, ={u1/y1, u2/y2, …, un/yn},是两个置换。 则与的合成也是一个置换,记作·。它是从集合
• 最一般合一求取方法
– 令W={F1,F2} – 令k=0,W0=W, σ0=ε – 如果Wk已合一,停止, σk=mgu,否则找Dk – 若Dk中存在元素vk和tk,其中,vk不出现在tk中,转下一
步,否则,不可合一。 – 令σk+1= σk.{tk/vk},Wk+1=Wk{tk/vk}=W σk+1 – K=k+1转第3步。
《人工智能》第三章 谓词逻辑与归结原理
谓词归结子句形
• 子句与子句集
– 文字:不含任何连接词的谓词公式。 – 子句:一些文字的析取(谓词的和)。 – 空子句:不含任何文字的子句。记作NIL或
□ – 子句集:所有子句的集合。 – 对于任何一个谓词公式G,都可以通过
人工智能导论课件:第四章 谓词逻辑与归结原理

谓词逻辑
是一种形式语言,具有严密的理论体系 是一种常用的知识表示方法, 例:
City(北京) City(上海) Age(张三,23) (X)(Y)(Z)(father(X, Y)father(Y,
Z)gf(X, Z)
6
归结原理
归结原理是一种定理证明方法,1965年由 J.A.Robinson提出,从理论上解决了定理证明 问题。当时被认为是人工智能领域的重大突破。
例如:令E为p(x,y,f(a))
={b/x,f(x)/y},则 E= ?
E=p(b,f(x),f(a)) 此例显示了同时置换的含义. 可以看到E是
在E上的作用,也就是将E中的(i=1, ,n)同时换成相 应的ti所得到的公式.
34
ห้องสมุดไป่ตู้
置换乘法
定义 令 ={s1/y1,,sm/ym}, ={t1/x1,,tn/xn},则与的复合是
32
置换
定义: 置换是形如{t1/x1,,tn/xn}的有限集,其中xi是 互不相同的变量,ti是不等于xi的项,且xi与ti互不循环 出现. 如果ti都是不含变量的项(基项),称该置换为基置换. 若={ },则称为空置换(表示不做置换),记为.
例如:1) {a/x,g(y)/y,f(g(b))/z}是一个置换? (是, 但不是基置换).
F1F2…Fn~W为永假,可以通过证明F所 对应的子句集S=S0∪{~W}是不可满足的。
22
命题: P|=F P{F}是不可满足的。 证明: ① 若P {~F}是不可满足的,则 P|= F ② 若P|=F 则 P {~F}是不可 满足的。(反证法)
23
归结原理
基本思想 将待证明的逻辑公式的结论(F),通过 等值公式转换成附加前提,再证明该逻 辑公式是不可满足的。
第三章 谓词逻辑与归结原理

以正向推理所得结果作为假设进 行反向推理
退出
是 还需要正向推理吗?
否
2014-4-9
18
华北电力大学
概述-推理的控制策略
搜索策略
推理时,要反复用到知识库中的规则,而知识库中 的规则又很多,这样就存在着如何在知识库中寻找 可用规则的问题 为有效控制规则的选取,可以采用各种搜索策略 常用搜索策略:
归结推理方法在人工智能推理方法中有着很重 要的历史地位,是机器定理证明的主要方法
2014-4-9
25
华北电力大学
归结法的特点
归结法是一阶逻辑中,至今为止的最有效的半可 判定的算法。也是最适合计算机进行推理的逻辑 演算方法 半可判定 一阶逻辑中任意恒真公式,使用归结原理,总 可以在有限步内给以判定(证明其为永真式) 当不知道该公式是否为恒真时,使用归结原理 不能得到任何结论
(5) 上下文限制
上下文限制就是把产生式规则按它们所描述的上下文分组,在某种 上下文条件下,只能从与其相对应的那组规则中选择可应用的规则
2014-4-9
22
华北电力大学
概述-推理的控制策略
推理的控制策略
3.冲突解决策略
(6) 按匹配度排序
在不精确匹配中,为了确定两个知识模式是否可以进行匹配,需要 计算这两个模式的相似程度,当其相似度达到某个预先规定的值时,就 认为它们是可匹配的。若有几条规则均可匹配成功,则可根据它们的匹 配度来决定哪一个产生式规则可优先被应用
如专家系统、智能机器人、模式识别、自然语言理解等
推理
按照某种策略从已有事实和知识推出结论的过程。 推理是由程序实现的,
称为推理机
医疗诊断专家系统
• 知识库中存储经验及医学常识 • 数据库中存放病人的症状、化验结果等初始事实 • 利用知识库中的知识及一定的控制策略,为病人诊治疾病、开出医疗处方就 是推理过程
人工智能技术导论——基于谓词逻辑的机器推理

⼈⼯智能技术导论——基于谓词逻辑的机器推理⼀、⼀阶谓词逻辑1、谓词、函数、量词设a1, a2, …, an表⽰个体对象, A表⽰它们的属性、状态或关系, 则表达式A(a1, a2, …, an)在谓词逻辑中就表⽰⼀个(原⼦)命题。
例如,(1) 素数(2), 就表⽰命题“2是个素数”。
(2) 好朋友(张三, 李四), 就表⽰命题“张三和李四是好朋友”。
⼀般地, 表达式P(x1,x2,…,xn)在谓词逻辑中称为n元谓词。
其中P是谓词符号,也称谓词,代表⼀个确定的特征或关系(名)。
x1,x2,…,xn称为谓词的参量或者项,⼀般表⽰个体。
个体变元的变化范围称为个体域(或论述域),包揽⼀切事物的集合称为全总个体域。
为了表达个体之间的对应关系,我们引⼊通常数学中函数的概念和记法。
例如我们⽤father(x)表⽰x的⽗亲,⽤sum(x,y)表⽰数x和y之和,⼀般地,我们⽤如下形式:f(x1,x2,…,xn)表⽰个体变元x1,x2,…,xn所对应的个体y,并称之为n元个体函数,简称函数(或函词、函词命名式)。
其中f是函数符号,有了函数的概念和记法,谓词的表达能⼒就更强了。
例如,我们⽤Doctor(father(Li))表⽰“⼩李的⽗亲是医⽣”,⽤E(sq(x),y))表⽰“x的平⽅等于y”。
以后我们约定⽤⼤写英⽂字母作为谓词符号,⽤⼩写字母f,g, h等表⽰函数符号,⽤⼩写字母x, y, z等作为个体变元符号, ⽤⼩写字母a, b, c等作为个体常元符号。
我们把“所有”、“⼀切”、“任⼀”、“全体”、“凡是”等词统称为全称量词, 记为∀x; 把“存在”、“有些”、“⾄少有⼀个”、 “有的”等词统称为存在量词,记为∃ x。
其中M(x)表⽰“x是⼈”, N(x)表⽰“x有名字”, 该式可读作“对于任意的x, 如果x是⼈, 则x有名字”。
这⾥的个体域取为全总个体域。
如果把个体域取为⼈类集合, 则该命题就可以表⽰为同理, 我们可以把命题“存在不是偶数的整数”表⽰为其中G(x)表⽰“x是整数”, E(x)表⽰“x是偶数”。
谓词逻辑与归结原理

处理机:能执行软件、具有计算能力的结点,如主机、服务器、 客户机等; 设备:没有计算能力的结点,如打印机、传感器、终端等。
构件图概念
构件
构件是定义了良好接口的物理实现单元,是系统中可替 换的物理部件。它把系统的实现打包,并提供一组接口 的实现 构件具有确定的接口,相互之间可以调用,构件之间存 在依赖关系。 在UML中,构件用一个左侧带有突出两个小矩形的矩 形来表示。
构件图概念
构件
构件的类型(UML2.0)
为了从物理层面描述软件开发过程中的用到的构件和结点, 也经常使用构件图和部署图
构件图概念
构件与构件图
构件(component): 是一个相对独立的可装配的物理块, 一般作为一个独立的文件存在,也翻译为组件。 构件图则表示一组构件以及它们之间的相互关系,包括 编译、链接或执行时构件之间的依赖关系
部署图概念
部署图的用途
显示系统结点的拓扑结构和通信路径、结点上执行 的软件构件、以及硬件设备的配置
部署图的组成元素
结点(Node) 关联关系(Association)
部署图概念
结点
结点(node) 是运行时代表计算资源的物理元素。结点通 常有内存及处理能力,它可以是物理设备及运行在该设 备上的软件系统. 结点分为处理机(processor)和设备(device)两类。
square类 (square.obj)
main类 (main.cpp) 依赖
main类 (main.obj)
主执行程序 (main.exe)
构件
谓词逻辑与归结原理1

p
q 1 0 1 0
p →q 1 0 1 1
q是p的必要条件有许多不同的叙述方式
– 因为p,所以q
– p仅当q – 只有q才p
– 除非q才p
– 除非q,否则非p
14/52
例 将下列命题符号化,并指出其真值
(1) (2) (3) (4)
如果3+3=6,则雪是白的。 如果3+3≠6,则雪是白的。 如果3+3=6,则雪不是白的。 如果3+3≠6,则雪不是白的。
解:令p:3+3=6,p的真值为1。 q:雪是白色的,q的真值也为1。 (1) p→q 1 1 0 1
15/52
(2)┐p→q
(3) p→┐q
(4) ┐p→┐q
例 将下列命题符号化,并指出其真值
以下命题中出现的a是一个给定的正整数: (5) 只要a能被4整除,则a一定能被2整除。 (6) a能被4整除,仅当a能被2整除。 (7) 除非a能被2整除, a才能被4整除。 (8) 除非a能被2整除,否则a不能被4整除。 (9) 只有a能被2整除, a才能被4整除。 (10)只有a能被4整除, a才能被2整除。
9/52
例 将下列命题符号化
(1) (2) (3)
(4)
(5)
吴颖既用功又聪明。 p: 吴颖用功。 q: 吴颖不仅用功而且聪明。 吴颖聪明。 r: 张辉是三好学生。 吴颖虽然聪明,但不用 s: 王丽是三好学生。 功。 t: 张辉与王丽是同学。 张辉与王丽都是三好学 生。 张辉与王丽是同学。 (1)p∧q
22/52
赋值举例
在公式(┐p1∧┐p2∧┐p3)∨(p1∧p2)中, 000(p1=0,p2=0,p3=0), 110(p1=1,p2=1,p3=0)都是成真赋值, 001(p1=0,p2=0,p3=1), 011(p1=0,p2=1,p3=1)都是成假赋值。 在(p∧┐q)→r中, 011(p1=0,p2=1,p3=1)为成真赋值, 100(p1=1,p2=0,p3=0)为成假赋值。 重要结论: 含n(n≥1)个命题变项的公式共有2n个不同的赋 值。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
河南城建学院《人工智能》实验报告实验名称:实现基于谓词逻辑的归结原理成绩:____专业班级:学号:姓名:实验日期:20 14 年 05 月 13日实验器材:一台装PC机。
一、实验目的熟练掌握使用归结原理进行定理证明的过程,掌握基于谓词逻辑的归结过程中,子句变换过程、替换与合一算法、归结过程及简单归结策略等重要环节,进一步了解机器自动定理证明的实现过程。
二、实验要求对于任意给定的一阶谓词逻辑所描述的定理,要求实现如下过程:(1) 谓词公式到子句集变换;(2) 替换与合一算法;(3) 在某简单归结策略下的归结。
三、实验步骤步1 设计谓词公式及自居的存储结构,即内部表示。
注意对全称量词∀x和存在量词∃x可采用其他符号代替;步2 实现谓词公式到子句集变换过程;步3 实现替换与合一算法;步4 实现某简单归结策略;步5 设计输出,动态演示归结过程,可以以归结树的形式给出;步6 实现谓词逻辑中的归结过程,其中要调用替换与合一算法和归结策略。
四、代码谓词公式到子句集变换的源代码:#include<iostream>#include<sstream>#include<stack>#include<queue>using namespace std;//一些函数的定义void initString(string &ini);//初始化string del_inlclue(string temp);//消去蕴涵符号string dec_neg_rand(string temp);//减少否定符号的辖域string standard_var(string temp);//对变量标准化string del_exists(string temp);//消去存在量词string convert_to_front(string temp);//化为前束形string convert_to_and(string temp);//把母式化为合取范式string del_all(string temp);//消去全称量词string del_and(string temp);//消去连接符号合取%string change_name(string temp);//更换变量名称//辅助函数定义bool isAlbum(char temp);//是字母string del_null_bracket(string temp);//删除多余的括号string del_blank(string temp);//删除多余的空格void checkLegal(string temp);//检查合法性char numAfectChar(int temp);//数字显示为字符//主函数void main(){cout<<"------------------求子句集九步法演示-----------------------"<<endl;system("color 0A");//orign = "Q(x,y)%~(P(y)";//orign = "(@x)(P(y)>P)";//orign = "~(#x)y(x)";//orign = "~((@x)x!b(x))";//orign = "~(x!y)";//orign = "~(~a(b))";string orign,temp;char command,command0,command1,command2,command3,command4,command5, command6,command7,command8,command9,command10;//================================================================= ============cout<<"请输入(Y/y)初始化谓词演算公式"<<endl;cin>>command;if(command == 'y' || command == 'Y')initString(orign);elseexit(0);//================================================================= ============cout<<"请输入(Y/y)消除空格"<<endl;cin>>command0;if(command0 == 'y' || command0 == 'Y'){//del_blank(orign);//undonecout<<"消除空格后是"<<endl<<orign<<endl;}elseexit(0);//================================================================= ============cout<<"请输入(Y/y)消去蕴涵项"<<endl;cin>>command1;if(command1 == 'y' || command1 == 'Y'){orign =del_inlclue(orign);cout<<"消去蕴涵项后是"<<endl<<orign<<endl;}elseexit(0);//================================================================= ============cout<<"请输入(Y/y)减少否定符号的辖域"<<endl;cin>>command2;if(command2 == 'y' || command2 == 'Y'){do{temp = orign;orign = dec_neg_rand(orign);}while(temp != orign);cout<<"减少否定符号的辖域后是"<<endl<<orign<<endl;}elseexit(0);//================================================================= ============cout<<"请输入(Y/y)对变量进行标准化"<<endl;cin>>command3;if(command3 == 'y' || command3 == 'Y'){orign = standard_var(orign);cout<<"对变量进行标准化后是"<<endl<<orign<<endl;}elseexit(0);//================================================================= ============cout<<"请输入(Y/y)消去存在量词"<<endl;cin>>command4;if(command4 == 'y' || command4 == 'Y'){orign = del_exists(orign);cout<<"消去存在量词后是(w = g(x)是一个Skolem函数)"<<endl<<orign<<endl;}elseexit(0);//================================================================= ============cout<<"请输入(Y/y)化为前束形"<<endl;cin>>command5;if(command5 == 'y' || command5== 'Y'){orign = convert_to_front(orign);cout<<"化为前束形后是"<<endl<<orign<<endl;}elseexit(0);//================================================================= ============cout<<"请输入(Y/y)把母式化为合取方式"<<endl;cin>>command6;if(command6 == 'y' || command6 == 'Y'){orign = convert_to_and(orign);cout<<"把母式化为合取方式后是"<<endl<<orign<<endl;}elseexit(0);//================================================================= ============cout<<"请输入(Y/y)消去全称量词"<<endl;cin>>command7;if(command7 == 'y' || command7 == 'Y'){orign= del_all(orign);cout<<"消去全称量词后是"<<endl<<orign<<endl;}elseexit(0);//================================================================= ============cout<<"请输入(Y/y)消去连接符号"<<endl;cin>>command8;if(command8 == 'y' || command8 == 'Y'){orign = del_and(orign);cout<<"消去连接符号后是"<<endl<<orign<<endl;}elseexit(0);//================================================================= ============cout<<"请输入(Y/y)变量分离标准化"<<endl;cin>>command9;if(command9 == 'y' || command9 == 'Y'){orign = change_name(orign);cout<<"变量分离标准化后是(x1,x2,x3代替变量x)"<<endl<<orign<<endl;}elseexit(0);//================================================================= ===========cout<<"-------------------------完毕-----------------------------------"<<endl;cout<<"(请输入Y/y)结束"<<endl;do{}while('y' == getchar() || 'Y'==getchar());exit(0);}void initString(string &ini){char commanda,commandb;cout<<"请输入您所需要转换的谓词公式"<<endl;cout<<"需要查看输入帮助(Y/N)? "<<endl;cin>>commanda;if(commanda == 'Y' || commanda == 'y')cout<<"本例程规定输入时蕴涵符号为>,全称量词为@,存在量词为#,"<<endl <<"取反为~,吸取为!,合取为%,左右括号分别为( 、),函数名请用一个字母"<<endl;cout<<"请输入(y/n)选择是否用户自定义"<<endl;cin>>commandb;if(commandb =='Y'|| commandb=='y')cin>>ini;elseini = "(@x)(P(x)>((@y)(P(y)>P(f(x, y)))%~(@y)(Q(x,y)>P(y))))";cout<<"原始命题是"<<endl<<ini<<endl;}string del_inlclue(string temp)//消去>蕴涵项{//a>b变为~a!bchar ctemp[100]={""};string output;int length = temp.length();int i = 0,right_bracket = 0,falg= 0;stack<char> stack1,stack2,stack3;strcpy(ctemp,temp.c_str());while(ctemp[i] != '\0' && i <= length-1){stack1.push(ctemp[i]);if('>' == ctemp[i+1])//如果是a>b则用~a!b替代{falg = 1;if(isAlbum(ctemp[i]))//如果是字母则把ctemp[i]弹出{stack1.pop();stack1.push('~');stack1.push(ctemp[i]);stack1.push('!');i = i + 1;}else if(')' == ctemp[i]){right_bracket++;do{if('(' == stack1.top())right_bracket--;stack3.push(stack1.top());stack1.pop();}while((right_bracket != 0));stack3.push(stack1.top());stack1.pop();stack1.push('~');while(!stack3.empty()){stack1.push(stack3.top());stack3.pop();}stack1.push('!');i = i + 1;}}i++;}while(!stack1.empty()){stack2.push(stack1.top());stack1.pop();}while(!stack2.empty()){output += stack2.top();stack2.pop();}if(falg == 1)return output;elsereturn temp;}string dec_neg_rand(string temp)//减少否定符号的辖域{char ctemp[100],tempc;string output;int flag2 = 0;int i = 0,left_bracket = 0,length = temp.length();stack <char> stack1,stack2;queue <char> queue1;strcpy(ctemp,temp.c_str());//复制到字符数组中while(ctemp[i] != '\0' && i <= length - 1){stack1.push(ctemp[i]);if(ctemp[i] == '~')//如果是~否则什么都不做{char fo = ctemp[i+2];if(ctemp[i+1] == '(')//如果是(,否则什么都不做{if(fo == '@' || fo =='#')//如果是全称量词{flag2 = 1;i++;stack1.pop();stack1.push(ctemp[i]);if(fo == '@')stack1.push('#');elsestack1.push('@');stack1.push(ctemp[i+2]);stack1.push(ctemp[i+3]);stack1.push('(');stack1.push('~');if(isAlbum(ctemp[i+4])){stack1.push(ctemp[i+4]);i = i + 5;}elsei = i + 4;do{queue1.push(temp[i]);if(temp[i] == '(')left_bracket ++;else if(temp[i] == ')')left_bracket --;i ++;}while(left_bracket != 0 && left_bracket >=0);queue1.push(')');while(!queue1.empty()){tempc = queue1.front();queue1.pop();stack1.push(tempc);}}}}i ++;}while(!stack1.empty()){stack2.push(stack1.top());stack1.pop();}while(!stack2.empty()){output += stack2.top();stack2.pop();}if(flag2 == 1)temp = output;/************************************************************/ char ctemp1[100];string output1;stack<char> stack11,stack22;int falg1 = 0;int times = 0;int length1 = temp.length(),inleftbackets = 1,j = 0;strcpy(ctemp1,temp.c_str());while(ctemp1[j] != '\0' && j <= (length1 -1)){stack11.push(ctemp1[j]);if(ctemp1[j] == '~'){if(ctemp1[j+1] == '(' /*&& ctemp1[j + 2] != '~'*/){j = j + 2;stack11.push('(');////////////////while(inleftbackets != 0 && inleftbackets >=0 && times <= (length1 - j) && times >= 0){stack11.push(ctemp1[j]);if(ctemp1[j] == '(')inleftbackets ++;else if(ctemp1[j] == ')')inleftbackets --;if(inleftbackets == 1 && ctemp1[j+1] == '!' && ctemp1[j+2] != '@' && ctemp1[j+2] != '#'){falg1 =1;stack11.push(')');//////////stack11.push('%');stack11.push('~');stack11.push('(');//////////j = j+1;}if(inleftbackets == 1 && ctemp1[j+1] == '%' && ctemp1[j+2] != '@' && ctemp1[j+2] != '#'){falg1 =1;stack11.push(')');//////////stack11.push('!');stack11.push('~');stack11.push('(');//////////j = j+1;}j = j +1;}if(falg1 == 1)stack11.push(')');stack11.pop();stack11.push(')');//此处有bugstack11.push(')');//此处有bug}}j ++;}while(!stack11.empty()){stack22.push(stack11.top());stack11.pop();}while(!stack22.empty()){output1 += stack22.top();stack22.pop();}if(falg1 == 1)temp = output1;/************************************************************/ char ctemp3[100];string output3;int k = 0,left_bracket3 = 1,length3 = temp.length();stack <char> stack13,stack23;int flag = 0,bflag = 0;strcpy(ctemp3,temp.c_str());//复制到字符数组中while(ctemp3[k] != '\0' && k <= length3-1){stack13.push(ctemp3[k]);if(ctemp3[k] == '~'){if(ctemp3[k+1] == '('){if(ctemp3[k + 2] == '~'){flag = 1;stack13.pop();k =k + 2;while(left_bracket3 != 0 && left_bracket3 >=0){stack13.push(ctemp3[k+1]);if(ctemp3[k+1] == '(')left_bracket3 ++;if(ctemp3[k+1] == ')')left_bracket3 --;if(ctemp3[k+1] == '!' || ctemp3[k+1] == '%')bflag = 1;k ++;}stack13.pop();}}}k ++;}while(!stack13.empty()){stack23.push(stack13.top());stack13.pop();}while(!stack23.empty()){output3 += stack23.top();stack23.pop();}if(flag == 1 && bflag == 0)temp = output3;return temp;}string standard_var(string temp)//对变量标准化,简化,不考虑多层嵌套{char ctemp[100],des[10]={" "};strcpy(ctemp,temp.c_str());stack <char> stack1,stack2;int l_bracket = 1,falg = 0,bracket = 1;int i = 0,j = 0;string output;while(ctemp[i] != '\0' && i < temp.length()){stack1.push(ctemp[i]);if(ctemp[i] == '@' || ctemp[i] == '#'){stack1.push(ctemp[i+1]);des[j] = ctemp[i+1];j++;stack1.push(ctemp[i+2]);i = i + 3;stack1.push(ctemp[i]);i++;if(ctemp[i-1] == '('){while(ctemp[i] != '\0' && l_bracket != 0){if(ctemp[i] == '(')l_bracket ++;if(ctemp[i] == ')')l_bracket --;if(ctemp[i] == '(' && ctemp[i+1] == '@' ){des[j] = ctemp[i+2];j++;}if(ctemp[i+1] == '(' && ctemp[i+2] == '#' ){falg = 1;int kk = 1;stack1.push(ctemp[i]);stack1.push('(');stack1.push(ctemp[i+2]);i = i+3;if(ctemp[i] == 'y')ctemp[i] ='w';stack1.push(ctemp[i]);stack1.push(')');stack1.push('(');i = i+3;while(kk != 0){if(ctemp[i]=='(')kk++;if(ctemp[i] ==')')kk--;if(ctemp[i] == 'y')ctemp[i] ='w';stack1.push(ctemp[i]);i++;}}stack1.push(ctemp[i]);i ++;}}}i ++;}while(!stack1.empty()){stack2.push(stack1.top());stack1.pop();}while(!stack2.empty()){output += stack2.top();stack2.pop();}if(falg == 1)return output;elsereturn temp;}string del_exists(string temp)//消去存在量词{char ctemp[100],unknow;strcpy(ctemp,temp.c_str());int left_brackets = 0,i = 0,falg = 0;queue<char> queue1;string output;while(ctemp[i] != '\0' && i < temp.length()){if(ctemp[i] =='(' && ctemp[i+1] =='#'){falg = 1;unknow = ctemp[i+2];i = i+4;do{if(ctemp[i] == '(')left_brackets ++;if(ctemp[i] == ')')left_brackets --;if(ctemp[i] == unknow){queue1.push('g');queue1.push('(');queue1.push('x');queue1.push(')');}if(ctemp[i] != unknow)queue1.push(ctemp[i]);i++;}while(left_brackets != 0);}queue1.push(ctemp[i]);i++;}while(!queue1.empty()){output+= queue1.front();queue1.pop();}if(falg == 1)return output;elsereturn temp;}string convert_to_front(string temp)//化为前束形{char ctemp[100];strcpy(ctemp,temp.c_str());int i = 0;string out_var = "",output = "";while(ctemp[i] != '\0' && i < temp.length()){if(ctemp[i] == '(' && ctemp[i+1] == '@'){out_var = out_var + ctemp[i] ;//(@)out_var = out_var + ctemp[i+1] ;out_var = out_var +ctemp[i+2];out_var = out_var +ctemp[i+3];i = i + 4;}output = output + ctemp[i];i++;}output = out_var + output;return output;}string convert_to_and(string temp)//把母式化为合取范式,Q/A?{temp = "(@x)(@y)((~P(x)!(~P(y))!P(f(x,y)))%((~P(x)!Q(x,g(x)))%((~P(x))!(~P(g(x)))))";return temp;}string del_all(string temp)//消去全称量词{char ctemp[100];strcpy(ctemp,temp.c_str());int i = 0,flag = 0;string output = "";while(ctemp[i] != '\0' && i < temp.length()){if(ctemp[i] == '(' && ctemp[i+1] == '@'){i = i + 4;flag = 1;}else{output = output + ctemp[i];i ++;}}return output;}string del_and(string temp)//消去连接符号合取% {char ctemp[100];strcpy(ctemp,temp.c_str());int i = 0,flag = 0;string output = "";while(ctemp[i] != '\0' && i < temp.length()){if(ctemp[i] == '%' ){ctemp[i] = '\n';}output = output +ctemp[i];i++;}return output;}string change_name(string temp)//更换变量名称{char ctemp[100];strcpy(ctemp,temp.c_str());string output = "";int i = 0,j = 0,falg = 0;while(ctemp[i] != '\0' && i < temp.length()){falg++;while('\n' != ctemp[i] && i < temp.length()){if('x' == ctemp[i]){output = output + ctemp[i] ;output = output + numAfectChar(falg);}elseoutput = output + ctemp[i] ;i++;}output = output + ctemp[i] ;i ++;}return output;}bool isAlbum(char temp){if(temp <= 'Z' && temp >= 'A' || temp <= 'z' && temp >= 'a') return true;return false;}char numAfectChar(int temp)//数字显示为字符{int t;switch (temp){case 1:t = 1;break;case 2:t = 2;break;case 3:t = 3;break;case 4:t = 4;break;default:t = 89;break;}return t;}五、结果分析(1)非用户自定义时:六、心得体会通过这次实验,熟悉了谓词公式转换成子句集的步骤,理解消解(谓词公式化为子句集)规则,能把任意谓词公式转换成子句集。