产生式系统Python PySide2的GUI界面

一、实验目的:

熟悉一阶谓词逻辑和产生式表示法,掌握产生式系统的运行机制,以及基于规则推理的基本方法。

二、实验内容:

运用所学知识,设计并编程实现一个小型人工智能系统(如分类、诊断、预测等类型)。

三、实验步骤:

1)系统设置,包括设置系统名称和系统谓词,给出谓词名及其含义。

2)编辑知识库,通过输入规则或修改规则等,完成整个规则库的建立。

3)建立事实库(综合数据库),输入多条事实或结论。

4)运行推理,包括正向推理和反向推理,给出相应的推理过程、事实区和规则区。

如果在macOS下Pyside2运行有问题去看我另一篇文章

一共有需要三个文件,分别是Plants,Feature和Rule。具体文件路径需要在py文件里自行更改。

在这里插入图片描述

文件内容为:

Plants:

玫瑰
荷花
仙人球
水棉
苹果树
油菜
海带
松树

Feature:

种子有果皮
被子植物
种子无果皮
裸子植物
无茎叶
无根
藻类植物
有托叶
蔷薇科
吸引菜粉蝶
十字花科
十字形花冠
缺水环境
仙人掌科
有刺
玫瑰
水生
可食用
结果实
荷花
喜阳
仙人球
药用
水棉
木本
苹果树
黄色花
油菜
有白色粉末
海带
叶片针状
松树

Rule:

种子有果皮 被子植物
种子无果皮 裸子植物
无茎叶 无根 藻类植物
被子植物 有托叶 蔷薇科
被子植物 吸引菜粉蝶 十字花科
被子植物 十字形花冠 十字花科
被子植物 缺水环境 仙人掌科
被子植物 蔷薇科 有刺 玫瑰
被子植物 水生 可食用 结果实 荷花
被子植物 仙人掌科 喜阳 有刺 仙人球
藻类植物 水生 药用 水棉
被子植物 蔷薇科 木本 可食用 结果实 苹果树
被子植物 十字花科 黄色花 可食用 结果实 油菜
藻类植物 水生 可食用 有白色粉末 海带
裸子植物 木本 叶片针状 结果实 松树

 (数据和代码框架借鉴https://blog.csdn.net/weixin_53056212/article/details/124394320)在它的框架下添加了功能并优化了GUI界面。

from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton
from PySide2.QtWidgets import QPlainTextEdit
from PySide2.QtWidgets import QMessageBox

Plants = []
Feature = []
Rules = []
dy_data = []
tested_1 = []
tested_2 = []
num = []
mid_result = []
weici1 = '1'
weici2 = '2'

class GUI():
    def __init__(self):

        self.window = QMainWindow()
        self.window.resize(600, 500)
        self.window.move(300, 310)

        self.textEdit6 = QPlainTextEdit(self.window)
        self.textEdit6.setPlaceholderText("请输入系统名称)")
        self.textEdit6.move(180, 420)
        self.textEdit6.resize(120, 30)



        self.textEdit7 = QPlainTextEdit(self.window)
        self.textEdit7.setPlaceholderText("请输入系统谓词1)")
        self.textEdit7.move(330, 420)
        self.textEdit7.resize(120, 30)

        self.textEdit8 = QPlainTextEdit(self.window)
        self.textEdit8.setPlaceholderText("请输入系统谓词2)")
        self.textEdit8.move(460, 420)
        self.textEdit8.resize(120, 30)

        self.textEdit = QPlainTextEdit(self.window)
        self.textEdit.setPlaceholderText("请输入已有特征信息的序号(以空格分隔)")
        self.textEdit.move(220, 50)
        self.textEdit.resize(100, 300)

        info = []
        for i in range(len(Feature)):
            s = "%d: %s " % (i + 1, Feature[i])
            info.append(s)
        self.textEdit2 = QPlainTextEdit(self.window)
        self.textEdit2.setPlainText(str(info))
        self.textEdit2.move(10, 50)
        self.textEdit2.resize(200, 300)

        self.textEdit3 = QPlainTextEdit(self.window)
        self.textEdit3.setPlainText('所有特征')
        self.textEdit3.move(10, 15)
        self.textEdit3.resize(120, 30)

        self.textEdit4 = QPlainTextEdit(self.window)
        self.textEdit4.move(430, 50)
        self.textEdit4.resize(150, 300)

        self.button1 = QPushButton('正向推理', self.window)
        self.button1.move(330, 130)
        self.button1.clicked.connect(self.handle)

        self.button2 = QPushButton('反向推理', self.window)
        self.button2.move(330, 190)
        self.button2.clicked.connect(self.handle2)

        self.button3 = QPushButton('展示所有规则', self.window)
        self.button3.resize(150, 100)
        self.button3.move(10, 380)
        self.button3.clicked.connect(self.display_rules)

        self.textEdit5 = QPlainTextEdit(self.window)
        self.textEdit5.setPlaceholderText("请输入要添加的规则")
        self.textEdit5.move(180, 360)
        self.textEdit5.resize(250, 50)

        self.button4 = QPushButton('添加规则', self.window)
        self.button4.resize(100, 50)
        self.button4.move(460, 360)
        self.button4.clicked.connect(self.add_rules)

        self.button5 = QPushButton('设置系统标题', self.window)
        self.button5.move(180, 455)
        self.button5.clicked.connect(self.set_titile)

        self.button6 = QPushButton('设置系统谓词', self.window)
        self.button6.move(380, 455)
        self.button6.clicked.connect(self.set_weici)




    def set_titile(self):
        self.window.setWindowTitle(self.textEdit6.toPlainText())

    def set_weici(self):
        global weici1
        global weici2
        weici1 = self.textEdit7.toPlainText()
        weici2 = self.textEdit8.toPlainText()

    def display_rules(self):
        Rules=[]
        with open("/Users/baorunfeng/Downloads/AiGUI/Rule.txt", 'r', encoding='utf8') as f3:
            for line in f3:
                line = line.split()
                Rules.append(line)
            f3.close()
        info = []
        for i in range(len(Rules)):  # 使输出有序
            s = "%d: %s " % (i + 1, Rules[i])
            info.append(s)
        QMessageBox.about(self.window, '所有规则',f'''如下:\n\n{'       '.join(info)}''')

    def add_rules(self):
        info = self.textEdit5.toPlainText()
        file = open('/Users/baorunfeng/Downloads/AiGUI/Rule.txt', 'a')
        file.write('\n'+info)
        file.close()

    def handle2(self):
        global num
        init_info = []
        info = self.textEdit.toPlainText()
        num = list(map(int, info.split()))
        for i in num:
            dy_data.append(Feature[i - 1])
            init_info.append(Feature[i - 1])
        infer = inference2()

        self.textEdit4.setPlainText(f'''您初始输入的特征信息有:\n{' '.join(init_info)}
            {'            '.join(mid_result)}\n\n您得到的答案是:\n{infer}''')


    def handle(self):
        global num
        init_info = []
        info = self.textEdit.toPlainText()
        num = list(map(int, info.split()))
        for i in num:
            dy_data.append(Feature[i - 1])
            init_info.append(Feature[i - 1])
        infer = inference()
        self.textEdit4.setPlainText(f'''您初始输入的特征信息有:\n{' '.join(init_info)}
                    {'            '.join(mid_result)}\n\n您得到的答案是:\n{infer}''')



def Database(file1, file2, file3):
    with open(file1, 'r', encoding='utf8') as f1:
        for line in f1.readlines():
            line = str(line).split()
            Plants.extend(line)
        f1.close()
    with open(file2, 'r', encoding='utf8') as f2:
        for line in f2.readlines():
            line = str(line).split()
            Feature.extend(line)
        f2.close()
    with open(file3, 'r', encoding='utf8') as f3:
        for line in f3:
            line = line.split()
            Rules.append(line)
        f3.close()


def inference():
    flag = 1
    while (flag):
        for i in range(len(dy_data)):
            if(dy_data[i] in Plants):
                return dy_data[i]
        tested_1 = []
        for i in range(len(Rules)):
            if (Rules[i] in tested_2):  # 防止规则重复匹配
                pass
            else:
                sub = Rules[i][:-1]
                for j in sub:
                    if (j not in dy_data):
                        break
                    if (j == sub[-1]):
                        if (Rules[i][-1] not in dy_data):  # 避免匹配到的规则后件重复加入
                            dy_data.append(Rules[i][-1])
                        s = "\n匹配的规则:"
                        s += weici1
                        for g in Rules[i]:
                            if (g == Rules[i][-2]):
                                s += g
                                s += '--->'
                                s += weici2
                            else:
                                s += g
                                s += '、'
                        mid_result.append(s)
                        ss = "\n目前综合数据库信息:"
                        for g in dy_data:
                            ss += g
                            ss += '、'
                        mid_result.append(ss)
                        tested_1.append(Rules[i])
                        tested_2.append(Rules[i])
        if (tested_1 == []):
            flag = 0  # 匹配失败,查找不到
    return False

def inference2(): 
    for i in range(len(Rules)):
        if (Rules[i][0] in dy_data):
            s = "\n匹配的规则:"
            for g in Rules[i]:
                if(g == Rules[i][0]):
                    s += weici2
                    s += g
                    s += '--->'
                    s += weici1
                else:
                    s += g
                    s += '、'
            mid_result.append(s)

            for j in range(len(Rules[i])):
                if(j!=0):dy_data.append(Rules[i][j])

            ss = "\n目前综合数据库信息:"
            for g in dy_data:
                ss += str(g)
                ss += '、'
            mid_result.append(ss)
            return dy_data


file1_path = "/Users/baorunfeng/Downloads/AiGUI/Plants.txt"
file2_path = "/Users/baorunfeng/Downloads/AiGUI/Feature.txt"
file3_path = "/Users/baorunfeng/Downloads/AiGUI/Rule.txt"
Database(file1_path, file2_path, file3_path)
app = QApplication([])
gg = GUI()
gg.window.show()
app.exec_()


实验结果:

产生式系统Python PySide2的GUI界面_第1张图片

(实验数据我已经改成这个球员判别系统了) 

记得要先输入两个谓词后点击设置,才能正常使用,谓词可以是Postive和Player_is.

你可能感兴趣的:(人工智能)