一、实验目的
1、 熟悉子句集化简的九个步骤。
2、 理解消解规则,能把任意谓词公式转换成子句集。
二、实验原理
对子句集进行消解推理,得到相应的结论。为了对含有变量的子句使用消解规则,我们必须找到一个置换,作用于父辈子句使其含有互补文字。消解两个子句时,可能有一个以上的消解式。子句消解规则:
(1) 假言推理
(2) 合并
(3) 重言式
(4) 空子句(矛盾)
(5) 链式(三段论)
三、实验步骤及内容
在谓词逻辑中,任何一个谓词公式都可以通过应用等价关系及推理规则化成相应的子句集。使用Python实现以下步骤。
(1) 消去连接词“”和“”,反复使用如下等价公式:
即可消去谓词公式中的连接词“ ”和“ ”。
(2) 减少否定符号的辖域,反复使用双重否定率,摩根定律,量词转换率,将每个否定符号移到仅靠谓词的位置,使得每个否定符号最多只作用于一个谓词上。
双重否定率
摩根定律
量词转换率
(3) 对变元标准化,在一个量词的辖域内,把谓词公式中受该量词约束的变元全部用另外一个没有出现过的任意变元代替,使不同量词约束的变元有不同的名字。
(4) 化为前束范式,化为前束范式的方法:把所有量词都移到公式的左边,并且移动时不能改变其相对顺序。
(5) 消去存在量词。
(6) 化为Skolem标准形,对上述前束范式的母式应用以下等价关系。
(7) 消去全称量词。
(8) 消去合取词,在母式中消去所有合取词,把母式用子句集的形式表示出来。其中,子句集中的每一个元素都是一个子句。
(9) 更换变量名称,对子句集中的某些变量重新命名,使任意两个子句中不出现相同的变量名。
输入样例:(@x)(p(x)>((@y)(p(y)>p(f(x,y)))^~(@y)(Q(x,y)>p(y)))),来测试程序。
四、实验代码
#1.消去>蕴含项a>b变为~a%b
def del_inlclue(orign):
ind = 0
flag = 0
orignStack = []
right_bracket = 0
while (ind < len(orign)):
orignStack.append(orign[ind])
if ((ind+1<len(orign)) and (orign[ind+1]=='>')):
flag = 1
if orign[ind].isalpha(): #是字母
orignStack.pop()
orignStack.append('~')
orignStack.append(orign[ind])
orignStack.append('%')
ind = ind+1
if orign[ind]==')':
right_bracket=right_bracket+1
tempStack =[]
while(right_bracket!=-1):
tempStack.append(orignStack[-1])
if orignStack[-1]=='(':
right_bracket=right_bracket-1
orignStack.pop()
right_bracket= right_bracket+1
tempStack.pop() #去掉‘(’
orignStack.append('(~')
tempStack.reverse()
for i in tempStack:
orignStack.append(i)
orignStack.append('%')
ind =ind+1
ind=ind+1
if flag ==1:
a=''
for i in orignStack:
a=a+i
return a
else:
return orign
#2.处理否定连接词
def dec_neg_rand(orign):
#处理~(@x)p(x)变为(#x)~p(x)
ind = 0
flag = 0
orignStack = []
left_bracket = 0
while (ind <len(orign)):
orignStack.append(orign[ind])
if orign[ind]=='~':
if orign[ind+1]=='(':
if orign[ind+2]=="@" or orign[ind+2]=='#':
flag= 1
ind =ind +1
orignStack.pop() # 去掉前面的~
orignStack.append(orign[ind])
if orign[ind+1]=='@':
orignStack.append('#')
else:
orignStack.append('@')
orignStack.append(orign[ind+2]) #'x'
orignStack.append(orign[ind+3]) #')'
orignStack.append('~')
ind = ind +3
ind =ind+1
if flag==1:
a=''
for i in orignStack:
a=a+i
orign2=a
else:
orign2 =orign
#处理~(p%q)变为(~p^~q)
ind =0
flag =0
flag2 =0
orignStack = []
left_bracket = 0
while (ind<len(orign2)):
orignStack.append(orign2[ind])
if orign2[ind] == '~':
if orign2[ind+1]=='(':
orignStack.pop()
ind =ind + 2 #此时为p
left_bracket=left_bracket+1
orignStack.append('(~')
while left_bracket>=1:
flag2=1
orignStack.append(orign2[ind])
if orign2[ind] == '(':
left_bracket=left_bracket+1
if orign2[ind] == ')':
left_bracket=left_bracket-1
if left_bracket==1 and orign2[ind+1]=='%' and orign2[ind+2]!='@' and orign2[ind+2]!='#':
flag=1
orignStack.append('^~')
ind =ind +1
if left_bracket ==1 and orign2[ind+1]=='^' and orign2[ind+2]!= '@' and orign2[ind+2]!='#':
flag = 1
orignStack.append('%~')
ind =ind+1
ind=ind+1
if flag2== 1:
ind=ind-1
flag2=0
ind=ind+1
if flag==1:
a=''
for i in orignStack:
a=a+i
orign3=a
else:
orign3=orign2
#处理~~p变为p
ind =0
flag =0
bflag = 0
orignStack = []
while (ind<len(orign3)):
orignStack.append(orign3[ind])
if orign3[ind]=='~':
if orign3[ind+1] == '~':
flag = 1
orignStack.pop()
ind = ind +1
ind =ind+1
if flag == 1:
a=''
for i in orignStack:
a=a+i
orign4 = a
else:
orign4 =orign3
#处理~(~p)变为p
ind =0
flag =0
bflag =0
orignStack=[]
while (ind <len(orign4)):
orignStack.append(orign4[ind])
if orign4[ind] == '~':
if orign4[ind+1] == '(':
left_bracket = 1
if orign4[ind+2] == '~':
flag =1
orignStack.pop()
ind =ind +2
while left_bracket>=1:
orignStack.append(orign4[ind+1])
if orign4[ind+1]=='(':
left_bracket=left_bracket+1
if orign4[ind+1]==')':
left_bracket=left_bracket-1
if orign4[ind+1]=='%' or orign4[ind+1]=='^':
bflag=1
ind =ind +1
orignStack.pop()
ind = ind + 1
if flag==1 and bflag==0:
a=''
for i in orignStack:
a=a+i
orign5=a
else:
orign5=orign4
return orign5
#3.命题变量标准化,使后面y=w
def standard_var(orign):
flag =1
desori = []
des = ['w','k','j']
j=0
orignStack = []
left_bracket=0
ind=0
while flag!=0:
flag=0
while (ind < len(orign)):
orignStack.append(orign[ind])
if orign[ind] == '@' or orign[ind] == '#':
x=orign[ind+1] #保存x
if orign[ind+1] in desori:
orignStack.append(des[j])
desori.append(des[j])
j=j+1
orignStack.append(')')
ind=ind+3
if ind<len(orign):
if orign[ind].isalpha():
orignStack.append(orign[ind])
ind =ind +1
if orign[ind]=='(':
left_bracket = left_bracket+1
orignStack.append(orign[ind])
ind=ind+1
while left_bracket>0:
if orign[ind]==')':
left_bracket=left_bracket-1
if orign[ind]=='(':
left_bracket=left_bracket+1
if orign[ind]==x:
flag=1
orignStack.append(des[j-1])
else:
orignStack.append(orign[ind])
ind=ind+1
ind=ind-1
if ind<len(orign):
if orign[ind]=='(':
left_bracket=left_bracket+1
orignStack.append(orign[ind])
ind=ind+1
while left_bracket>0:
if orign[ind]==')':
left_bracket=left_bracket-1
if orign[ind]=='(':
left_bracket=left_bracket+1
if orign[ind]==x:
flag=1
orignStack.append(des[j-1])
else:
orignStack.append(orign[ind])
ind=ind+1
ind=ind-1
else:
desori.append(orign[ind+1])
ind=ind+1
a=''
for i in orignStack:
a=a+i
orign2=a
return orign2
#4.消去存在量词(skolem化)
def del_exists(orign):
ind = 0
flag = 1
orignStack = []
x=''
y=''
#1.第一种情况:前面的全称量词(@x)(#y)p(x,y)变成(@x)p(x,f(x))
orignStack2 = []
while flag!=0:
flag=0
while (ind<len(orign)):
orignStack.append(orign[ind])
if orign[ind]=='(' and orign[ind+1]=='@' and orign[ind+4]=='(':
x=orign[ind+2]
orignStack.append(orign[ind+1:ind+5])
ind = ind + 5 #指向
while orign[ind]!='#':
orignStack.append(orign[ind])
ind = ind+1
orignStack.pop()
y=orign[ind+1] #为y
ind=ind+2
flag=1
ind = ind+1
if flag==1:
orignStack2=[]
for i in orignStack:
if i==y:
orignStack2.append('g(')
orignStack2.append(x)
orignStack2.append(')')
else:
orignStack2.append(i)
a=''
for i in orignStack2:
a=a+i
orign2 = a
ind =0
flag=1
orignStack=[]
#2.第二种情况:前面没有全称量词(#y)p(x,y)变为p(x,A)
while flag!= 0:
flag=0
while (ind<len(orign2)):
orignStack.append(orign2[ind])
if orign2[ind]=='#':
y=orign2[ind+1]
orignStack.pop()
orignStack.pop()
ind=ind+2 #指向‘)’
flag=1
ind =ind+1
if flag==1:
orignStack2=[]
for i in orignStack:
if i==y:
orignStack2.append('A')
else:
orignStack2.append(i)
a=''
for i in orignStack2:
a=a+i
orign2=a
return orign2
#5.前束化
def convert_to_front(orign):
ind =0
orignStack=[]
tempStack=[] #存放全称量词
while (ind<len(orign)):
orignStack.append(orign[ind])
if orign[ind]=='(' and orign[ind+1]=='@':
orignStack.pop()
tempStack.append(orign[ind:ind+4])
ind=ind+3
ind=ind+1
orignStack=tempStack+orignStack
a=''
for i in orignStack:
a=a+i
orign2=a
return orign2
#6.消去全称量词
def del_all(orign):
ind =0
orignStack=[]
return orign[8:]
#代码的测试
orign ='(@x)(p(x)>((@y)(p(y)>p(f(x,y)))^~(@y)(Q(x,y)>p(y))))'
print('orign:',orign)
a=del_inlclue(orign)
print('去除蕴含后',a)
a=dec_neg_rand(a)
print('处理否定连接词后:')
print(a)
a=standard_var(a)
print('变量命名标准化后:')
print(a)
a=del_exists(a)
print('消去存在量词后:')
print(a)
a=convert_to_front(a)
print('前束化后:')
print(a)
a=del_all(a)
print('消去全程量词后:')
print(a)
五、实验结果
六、实验总结
通过本次人工智能导论子句集消解实验,我们深入了解了子句集消解的原理和实现方法,并成功将其应用于实际问题中。实验结果证明了该方法的有效性和实用性。展望未来,我们可以在此基础上进一步优化算法性能、提高处理大规模子句集的能力;同时,可以尝试将该方法应用于更广泛的领域和问题中,为人工智能领域的发展做出贡献。此外,可以考虑将子句集消解与其他人工智能技术(如机器学习、自然语言处理等)相结合,以实现更复杂的应用场景。