这个实验再csdn上有一个,但不是免费,而且还有一点点的瑕疵,我修改了一下,但是还是很垃圾。不过应该可以应付一下
我修改的部分主要是用re正则表达式来写的。其实应该来说这个实验需要用栈来写,这样可以实现括号的匹配,就能对更多的例子进行处理。但是我不会,所以我就针对三个例题,一个一个的按照题来写程序(面向结果编程)。
实现的例子是王万良的《人工智能导论(第五版)》中的第68页到71页的例3.2、3.3、3.4 。
为了方便大家判断是不是需要的结果,我先把运行结果放前边。
运行结果如下:
orign: (@x)(p(x)>((@y)(p(y)>p(f(x,y)))^~(@y)(Q(x,y)>p(y))))
1.去除蕴含后:
(@x)(~p(x)|((@y)(~p(y)|p(f(x,y)))^~(@y)(~Q(x,y)|p(y))))
2.处理否定连接词后:
(@x)(~p(x)|((@y)(~p(y)|p(f(x,y)))^(#y)(Q(x,y)^~p(y))))
3.变量命名标准化后:
(@x)(~p(x)|((@y)(~p(y)|p(f(x,y)))^(#w)(Q(x,w)^~p(w))))
4.消去存在量词后:
(@x)(~p(x)|((@y)(~p(y)|p(f(x,y)))^(Q(x,g(x))^~p(g(x)))))
5.前束化后:
(@x)(@y)(~p(x)|((~p(y)|p(f(x,y)))^(Q(x,g(x))^~p(g(x)))))
6.化为Skolem标准型
(@x)(@y)(~p(x)|~p(y)|p(f(x,y))^~p(x)|Q(x,g(x))^~p(x)|~p(g(x)))
7.消去全称量词后:
(~p(x)|~p(y)|p(f(x,y))^~p(x)|Q(x,g(x))^~p(x)|~p(g(x)))
8.消去合取词
{~p(x₁)|~p(y₁)|p(f(x₁,y₁)),~p(x₂)|Q(x₂,g(x₂)),~p(x₃)|~p(g(x₃))}
---------------------------------------------------------
orign: (@x)((@y)P(x,y)>~(@y)(Q(x,y)>R(x,y)))
1.去除蕴含后:
(@x)(~(@y)P(x,y)|~(@y)(~Q(x,y)|R(x,y)))
2.处理否定连接词后:
(@x)((#y)~P(x,y)|(#y)(Q(x,y)^~R(x,y)))
3.变量命名标准化后:
(@x)((#y)~P(x,y)|(#w)(Q(x,w)^~R(x,w)))
4.消去存在量词后:
(@x)(~P(x,g(x))|(Q(x,k(x))^~R(x,k(x))))
5.前束化后:
(@x)(~P(x,g(x))|(Q(x,k(x))^~R(x,k(x))))
6.化为Skolem标准型
(@x)(~P(x,g(x))|Q(x,k(x))^~P(x,g(x))|~R(x,k(x)))
7.消去全称量词后:
(~P(x,g(x))|Q(x,k(x))^~P(x,g(x))|~R(x,k(x)))
8.消去合取词
{~P(x₁,g(x₁))|Q(x₁,k(x₁)),~P(x₂,g(x₂))|~R(x₂,k(x₂))}
---------------------------------------------------------
orign: (@x)((~P(x)|~Q(x))>(#y)(S(x,y)^Q(x)))^(@x)(P(x)|B(x))
1.去除蕴含后:
(@x)(~(~P(x)|~Q(x))|(#y)(S(x,y)^Q(x)))^(@x)(P(x)|B(x))
2.处理否定连接词后:
(@x)((P(x)^Q(x))|(#y)(S(x,y)^Q(x)))^(@x)(P(x)|B(x))
3.变量命名标准化后:
(@x)((P(x)^Q(x))|(#y)(S(x,y)^Q(x)))^(@w)(P(w)|B(w))
4.消去存在量词后:
(@x)((P(x)^Q(x))|(S(x,g(x))^Q(x)))^(@w)(P(w)|B(w))
5.前束化后:
(@x)(@w)(((P(x)^Q(x))|(S(x,g(x))^Q(x)))^(P(w)|B(w)))
6.化为Skolem标准型
111111111111
(@x)(@w)(Q(x)^(P(x)|S(x,g(x)))^P(w)|B(w))
(@x)(@w)(Q(x)^(P(x)|S(x,g(x)))^P(w)|B(w))
7.消去全称量词后:
(Q(x)^(P(x)|S(x,g(x)))^P(w)|B(w))
8.消去合取词
{Q(x₁),(P(x₂)|S(x₂,g(x₂))),P(w)|B(w)}
下边的是代码部分(五百多行谨慎选择),我很多就没有注释,(很不喜欢写),反正应该不需要去看懂吧,应付应付就ok了,别再真学会了:
'''
->:>
析取:|
合取:^
全称:@
存在:#
非:~
'''
# 1.消去>蕴涵项 a>b变为~a|b
import sys
import re
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 and orignStack!=[]):
te = orignStack[-1]
tempStack.append(te)
if te == ')':
right_bracket = right_bracket+1
elif te == '(':
right_bracket = right_bracket-1
orignStack.pop()
# print(tempStack[::-1])
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 = ''.join(orignStack)
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
# print('orign2',orign2)
# 处理~(p|q) 变为(~p^~q)#####################################
ind = 0
flag = 0
flag2 = 0 # 判断是否进入while left_bracket>=1:循环 ,若进入,出来后ind再减1
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:
orign3 = ''.join(orignStack)
else:
orign3 = orign2
# print('orign3',orign3)
if re.search(r'~\(~.*^|\|~.*\)', orign3):
orign3 = re.sub(r'~\(~(.*^|\|)~(.*\))', '(\1\2)', orign3)
# 处理~~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:
orign4 = ''.join(orignStack)
else:
orign4 = orign3
# print('orign4', orign4)
# 处理~(~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:
orign5 = ''.join(orignStack)
else:
orign5 = orign4
# print('orign5',orign5)
# 处理~(@x)p(x) 变为 (#x)~p(x) #####################################
pattern = r"~\(@(.)\)"
pa = r"~\(#(.)\)"
# 定义要替换的内容
if re.search(pattern, orign5):
# math = re.search(pattern, orign5)
orign5 = re.sub(pattern, r'(#\1)~', orign5)
# if re.search(r'~\)', orign6):
# orign6 = re.sub(r'~\)', r')~', orign6)
if re.search(pa, orign5):
orign5 = re.sub(pa, r'(@\1)~', orign5)
if re.search(r'\(~@(.)\)', orign5):
orign5 = re.sub(r'\(~@(.)\)', r'(#\1)~', orign5)
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(): # (@x)p(x,y)这种情况
orignStack.append(orign[ind]) # p
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))
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] != '#' and ind<len(orign)-8:
orignStack.append(orign[ind])
ind = ind+1
orignStack.pop()
y = orign[ind+1] # 为y
ind = ind+2 # 指向p
flag = 1
ind = ind + 1
if flag == 1:
pat = r"\(#(.)\)"
li = ['g', 'k', 't', 'f', 'w']
ii = 0
while re.search(pat, orign):
mat = re.search(r'\(#(.)\)', orign)
orign = re.sub(r'\(#(.)\)', '', orign, count=1)
xx = mat.group(1)
orign = re.sub(str(xx), li[ii]+'(x)', orign)
ii = ii + 1
else:
orignStack2 = list(orign)
orign2 = orign
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)
orign2 = ''.join(orignStack2)
return orign2
# 5.前束化
def convert_to_front(orign): # 化为前束形
# if re.search(pattern, orign5):
# # math = re.search(pattern, orign5)
# orign6 = re.sub(pattern, r'@\1~', orign5)
# if re.search(r'~\)', orign6):
# orign6 = re.sub(r'~\)', r')~', orign6)
pattern = r'(\(@.\))'
match = re.findall(pattern, orign)
if match:
orign = re.sub(pattern, "", orign)
if orign[-3]==')':
orign = ''.join(match) + orign
else:
orign = ''.join(match) + '(' + orign + ')'
return orign
# 6.化为Skolem标准型
def change_Skolem(orign):
if orign.count('^') == 2:
te = re.search(r'\|\(\((.*?)\)\^', orign).group(1)
tem = re.search(r'\)\((\~.*?\))\|', orign).group(1)
temm = re.search(r'\^\((.*\))\^', orign).group(1)
tee = re.search(r'\)\^(~.*)\)\)\)', orign).group(1)
quan = re.search(r'(\(@.\)\(@.\))', orign).group(1)
orign = (quan + '('+tem+'|'+te+'^'+tem+'|'+temm+'^'+tem+'|'+tee+')')
pass
elif orign.count('^') == 3:
li = []
res = re.findall(r'.\(.\)..\(.\)|.\(.,....\)..\(.\)', orign)
for i in res:
# tte = re.split(r'(?<=\^)|(?<=\|)',i)
tte = re.split(r'\^|\|', i)
# print(tte)
# li.join(tte)
li+=tte
lli = set(li)
# print(len(li))
# print(len(lli))
if len(lli)<len(li):
pattern = r'(\(@.\))'
rr = ''.join(re.findall(pattern, orign))
orign = rr+'('+ li[1]+'^'+'(' + li[0] +'|'+li[2]+')'+'^'+res[2] +')'
print("111111111111")
print(orign)
pass
elif orign.count('^') == 1:
huo = orign.find('|')
qian = orign[:huo]
pattern = r'(\(@.\))'
if re.findall(pattern, qian):
orign_s = re.sub(pattern, "", qian)
if orign_s[0] == '(':
orign_1 = orign_s[1:]
huo_1 = orign.find('^')
orign_2 = orign[huo+2:huo_1]
orign_3 = orign[huo_1+1:]
st = 0
for i in orign_3:
if i == '(':
st += 1
orign_3 = orign_3[:-st]
pattern = r'(\(@.\))'
rr = ''.join(re.findall(pattern, orign))
orign = rr+'('+orign_1+'|'+orign_2+'^'+orign_1+'|'+orign_3+')'
else:
pass
return orign
# 7.消去全称量词
def del_all(orign):
pattern = r'(\(@.\))'
if re.findall(pattern, orign):
orign = re.sub(pattern, "", orign)
return orign
# 8.消去合取词
def del_quan(orign):
replaced_list = [',' if x == '^' else x for x in orign]
replaced_list[0] = '{'
replaced_list[-1] = '}'
replaced_list = ''.join(replaced_list)
repx = ["x\u2081", "x\u2082", "x\u2083", "x\u2084",
"x\u2085", "x\u2086", "x\u2087", "x\u2088", "x\u2089"]
repy = ["y\u2081", "y\u2082", "y\u2083", "y\u2084",
"y\u2085", "y\u2086", "y\u2087", "y\u2088", "y\u2089"]
li = replaced_list.split('),')
xi = 0
yi = 0
for i in range(len(li)):
if 'x' in li[i]:
li[i] = li[i].replace('x', repx[xi])
xi += 1
if 'y' in li[i]:
li[i] = li[i].replace('y', repy[yi])
yi += 1
replaced_list = '),'.join(li)
return replaced_list
def test_example(a):
print('orign:', a)
a = del_inlclue(a)
print('1.去除蕴含后:')
print(a)
a = dec_neg_rand(a)
print('2.处理否定连接词后:')
print(a)
a = standard_var(a)
print('3.变量命名标准化后:')
print(a)
a = del_exists(a)
print('4.消去存在量词后:')
print(a)
a = convert_to_front(a)
print('5.前束化后:')
print(a)
print('6.化为Skolem标准型')
a = change_Skolem(a)
print(a)
print('7.消去全称量词后:')
a = del_all(a)
print(a)
print('8.消去合取词')
a = del_quan(a)
print(a)
print("---------------------------------------------------------")
orign = '(@x)(p(x)>((@y)(p(y)>p(f(x,y)))^~(@y)(Q(x,y)>p(y))))'
orign1 = '(@x)((@y)P(x,y)>~(@y)(Q(x,y)>R(x,y)))'
orign2 = '(@x)((~P(x)|~Q(x))>(#y)(S(x,y)^Q(x)))^(@x)(P(x)|B(x))'
if __name__ == '__main__':
test_example(orign)
test_example(orign1)
test_example(orign2)
末尾 ,我也没有想说的话,就这样吧。