字句集消解实验(人工智能导论实验)

这个实验再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)

末尾 ,我也没有想说的话,就这样吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

远歌已逝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值