目录
②.设计界面,将数据库实现人机交互,用tkinter来展示整个系统。
一、实验主要步骤
①.设计规则,编辑知识库。
通过输入或修改规则建立规则库。
基于数学原理,自己设计了如下的命题和22条规则。
由于推理机后续工作时,可能会将当前输入的条件转换为可用知识进行下一步的推理,因此在设计规则时对规则进行了分层,推理机对规则的执行顺序为第一层——>第二层——>第三层——>第四层。
设计完知识库之后,存入数据库,便于修改知识库(本次实验使用的是sql数据库)。
②.设计界面,将数据库实现人机交互,用tkinter来展示整个系统。
首先使用treeview对数据库里的表格进行显示,当用户选中某个条件之后,可以将此条件添加到推理机里。当添加的条件合理且可以与数据库里的规则匹配成功时,点击结果便会呈现正确答案,反之则会显示无法推理。
编程过程中使用了tkinter库、sqlite3库以及类函数来实现,此部分代码部分如下:
class accounting:
#数据库名字
db_name = 'database.db'
#初始化操作
def __init__(self,window):
self.win=window
self.win.title("产生式系统")
width=1500
height=1000
align_str='%dx%d'%(width,height)
window.geometry(align_str)
#treeview进行左表格显示
self.tree=ttk.Treeview(height=31,column=("#0","#1"))
self.tree.grid(row=0,column=0,columnspan=1)
self.tree.heading("#0",text="编号",anchor=CENTER)
self.tree.heading("#1",text="内容",anchor=CENTER)
#绘制表格
records=self.tree.get_children()
for element in records:
self.tree.delete(element)
query="select * from chanshengshi order by num"
db_rows=self.run_query(query)
#填充表格
for row in db_rows:
self.tree.insert("",0,text=row[0],values=(row[1]))
global list_real
list_real=[]
ttk.Button(text='添加——>',command=self.add).grid(row=0, column=3, sticky=W + E)
self.message = Label(text='', fg='red')
self.message.grid(row=0, column=5, columnspan=5,sticky=W+E)
self.message['text']="您的选择是:"
self.message2 = Label(text=' ', fg='red')
self.message2.grid(row=0, column=20, columnspan=5,sticky=W+E)
self.message2['text']="前提条件为:\n"
ttk.Button(text='结果——>',command=self.resultword).grid(row=0, column=12, sticky=W + E)
以上是界面的设计,界面中有两个按钮“添加”和“结果”。
“添加”实现的功能是将条件加入到推理机中,代码展示如下:(“结果”按钮会调用推理的函数以及打印结果,此部分在“③推理算法介绍”中进行阐述)。
def add(self):
global list_real
list_real.append(str(self.tree.item(self.tree.selection())['text']))
print("lastadd",list_real)
self.message['text']=self.message['text']+'\n'+str(self.tree.item(self.tree.selection())['text'])+str(self.tree.item(self.tree.selection())['values'][0])
self.message.grid(row=0, column=4, columnspan=5,sticky=W+E)
③.推理算法介绍。
首先简要介绍一下推理的主要思想。
在①中提到了我将规则分为四层,但是分为四次推理效率低,时间复杂度高,因此对其进行简化。
第一层规则作为第一次推理,将第一次推理得出的图形称为“基础图形”。将剩下的三层规则作为第二次推理,推理机执行的顺序为:“基础图形”的命题序号从小到大。这样按顺序执行不会在条件转化为可用知识时产生遗漏,又可以提高效率,减少执行时间。
现在,介绍一下推理的步骤。
建立综合数据库(在程序中用字典“dic_before”进行表示),可用知识库(程序中用列表“list_real”进行表示),结果存储器(在程序中用列表“result”进行表示)。定义判断函数,推理机分别执行两次规则的推理,如果在推理过程中,已知条件与综合数据库的规则有所匹配,调用判断函数(判断该条件是否在可用数据库中已经存在,避免重复添加),打印推理过程,迭代推理。若得到“最终推理图形”,则结束推理,反之则告知用户无法推理。
二、实验结果展示
①.当推理失败时
当条件数量不够或者条件与规则不匹配时,会产生推理失败的情况,系统运行结果如下:
②.当推理成功时
当条件合理且与规则可以成功匹配时,则会产生正确的推理结果,结果展示如下:
三、附录
完整实验程序代码:
from tkinter import ttk
from tkinter import *
import sqlite3
class accounting:
#数据库名字
db_name = 'database.db'
#初始化操作
def __init__(self,window):
self.win=window
self.win.title("产生式系统")
width=1500
height=1000
align_str='%dx%d'%(width,height)
window.geometry(align_str)
#treeview进行左表格显示
self.tree=ttk.Treeview(height=31,column=("#0","#1"))
self.tree.grid(row=0,column=0,columnspan=1)
self.tree.heading("#0",text="编号",anchor=CENTER)
self.tree.heading("#1",text="内容",anchor=CENTER)
#绘制表格
records=self.tree.get_children()
for element in records:
self.tree.delete(element)
query="select * from chanshengshi order by num"
db_rows=self.run_query(query)
#填充表格
for row in db_rows:
self.tree.insert("",0,text=row[0],values=(row[1]))
global list_real
list_real=[]
ttk.Button(text='添加——>',command=self.add).grid(row=0, column=3, sticky=W + E)
self.message = Label(text='', fg='red')
self.message.grid(row=0, column=5, columnspan=5,sticky=W+E)
self.message['text']="您的选择是:"
self.message2 = Label(text=' ', fg='red')
self.message2.grid(row=0, column=20, columnspan=5,sticky=W+E)
self.message2['text']="前提条件为:\n"
ttk.Button(text='结果——>',command=self.resultword).grid(row=0, column=12, sticky=W + E)
#数据库操作方法
def run_query(self, query, params=()):
with sqlite3.connect(self.db_name) as conn:
cursor = conn.cursor()
result_ = conn.execute(query, params)
conn.commit()
return result_
#数据添加处理
def add(self):
global list_real
list_real.append(str(self.tree.item(self.tree.selection())['text']))
print("lastadd",list_real)
self.message['text']=self.message['text']+'\n'+str(self.tree.item(self.tree.selection())['text'])+str(self.tree.item(self.tree.selection())['values'][0])
self.message.grid(row=0, column=4, columnspan=5,sticky=W+E)
#自定义函数,判断有无重复元素
def judge_repeat(self,value,list_real):
for i in range(0,len(list_real)):
if(list_real[i]==value):
return 1
else:
if(i!=len(list_real)-1):
continue
else:
return 0
def resultword(self):
global list_real
global dic_before
global result
result=["0",0]
print("last11",list_real)
dic_before={'1':'由三条边组成','2':'内角和为180°','3':'内角和为360°','4':'两组对边互相平行','5':'每条边一样长','6':'每个角都是90°','7':'不是所有边都一样长',
'8':'面积为边长的平方','9':'面积为(上底+下底)*高/2','10':'每条边都不一样长','11':'形状是由矩形+菱形组成的','12':'对角线垂直','13':'一组邻边相等','14':'对角线相等',
'15':'对角线互相平分','16':'邻边垂直','17':'三角形','18':'平行四边形','19':'矩形','20':'正方形','21':'长方形',
'22':'菱形','23':'梯形','24':'筝形'}
#综合数据库
for i in range(0,len(list_real)):
self.message2['text']=self.message2['text']+" "+str(dic_before[list_real[i]])
self.message2['text']= self.message2['text']+'\n'+"推理过程如下:"+'\n'
#遍历综合数据库list_real中的前提条件
for i in list_real:
if(i=='1'):
if(self.judge_repeat('17',list_real)==0):
list_real.append('17')
self.message2['text']=self.message2['text']+dic_before['1']+"——>"+dic_before['17']+'\n'
result[0]=dic_before['17']
result[1]=17
if(i=='2'):
if(self.judge_repeat('17',list_real)==0):
list_real.append('17')
self.message2['text']=self.message2['text']+dic_before['2']+"——>"+dic_before['17']+'\n'
result[0]=dic_before['17']
result[1]=17
if(i=='3'):
for j in list_real:
if(j=='4'):
if(self.judge_repeat('18',list_real)==0):
list_real.append('18')
self.message2['text']=self.message2['text']+dic_before['3']+"+"+dic_before['4']+"——>"+dic_before['18']+'\n'
result[0]=dic_before['18']
result[1]=18
if(j=='6'):
if(self.judge_repeat('19',list_real)==0):
list_real.append('19')
self.message2['text']=self.message2['text']+dic_before['3']+"+"+dic_before['6']+"——>"+dic_before['19']+'\n'
result[0]=dic_before['19']
result[1]=19
if(j=='9'):
if(self.judge_repeat('23',list_real)==0):
list_real.append('23')
self.message2['text']=self.message2['text']+dic_before['3']+"+"+dic_before['9']+"——>"+dic_before['23']+'\n'
result[0]=dic_before['23']
result[1]=23
if(j=='10'):
if(self.judge_repeat('23',list_real)==0):
list_real.append('23')
self.message2['text']=self.message2['text']+dic_before['3']+"+"+dic_before['10']+"——>"+dic_before['23']+'\n'
result[0]=dic_before['23']
result[1]=23
if(j=='11'):
if(self.judge_repeat('23',list_real)==0):
list_real.append('23')
self.message2['text']=self.message2['text']+dic_before['3']+"+"+dic_before['11']+"——>"+dic_before['23']+'\n'
result[0]=dic_before['23']
result[1]=23
if(j=='12'):
if(self.judge_repeat('24',list_real)==0):
list_real.append('24')
self.message2['text']=self.message2['text']+dic_before['3']+"+"+dic_before['12']+"——>"+dic_before['24']+'\n'
result[0]=dic_before['24']
result[1]=24
if(j=='15'):
if(self.judge_repeat('18',list_real)==0):
list_real.append('18')
self.message2['text']=self.message2['text']+dic_before['3']+"+"+dic_before['15']+"——>"+dic_before['18']+'\n'
result[0]=dic_before['18']
result[1]=18
elif(i=='12'):
for j in list_real:
if(j=='15'):
if(self.judge_repeat('22',list_real)==0):
list_real.append('22')
self.message2['text']=self.message2['text']+dic_before['12']+"+"+dic_before['15']+"——>"+dic_before['22']+'\n'
result[0]=dic_before['22']
result[1]=22
elif(i=='14'):
for j in list_real:
if(j=='15'):
if(self.judge_repeat('19',list_real)==0):
list_real.append('19')
self.message2['text']=self.message2['text']+dic_before['14']+"+"+dic_before['15']+"——>"+dic_before['19']+'\n'
result[0]=dic_before['19']
result[1]=19
print("last0",list_real)
self.judge_last(list_real)
self.message2.grid(row=0, column=20, columnspan=5,sticky=W+E)
if result[1]>=17 and result[1]<=24:
self.message2['text']=self.message2['text']+"所识别的图形为:"+result[0]+"\n"
else:
self.message2['text']=self.message2['text']+"无法根据所给条件识别出图形\n"
#自定义函数,对已经整理好的综合数据库real_list进行最终的结果判断
def judge_last(self,list_real):
global dic_defore
flag=0
global result
for i in list_real:
if(i=='18'):
for j in list_real:
if(j=='5'):
self.message2['text']=self.message2['text']+dic_before['18']+"+"+dic_before['5']+"——>"+dic_before['22']+'\n'
result[0]=dic_before['22']
result[1]=22
flag=1
if(j=='6'):
self.message2['text']=self.message2['text']+dic_before['18']+"+"+dic_before['6']+"——>"+dic_before['19']+'\n'
result[0]=dic_before['19']
result[1]=19
flag=1
if(j=='12'):
self.message2['text']=self.message2['text']+dic_before['18']+"+"+dic_before['12']+"——>"+dic_before['22']+'\n'
result[0]=dic_before['22']
result[1]=22
flag=1
if(j=='13'):
self.message2['text']=self.message2['text']+dic_before['18']+"+"+dic_before['13']+"——>"+dic_before['22']+'\n'
result[0]=dic_before['22']
result[1]=22
flag=1
if(i=='19'):
for j in list_real:
if(j=='5'):
self.message2['text']=self.message2['text']+dic_before['19']+"+"+dic_before['5']+"——>"+dic_before['20']+'\n'
result=dic_before['20']
result[0]=dic_before['20']
result[1]=20
flag=1
if(j=='7'):
self.message2['text']=self.message2['text']+dic_before['19']+"+"+dic_before['7']+"——>"+dic_before['21']+'\n'
result=dic_before['21']
result[0]=dic_before['21']
result[1]=21
flag=1
if(j=='8'):
self.message2['text']=self.message2['text']+dic_before['19']+"+"+dic_before['8']+"——>"+dic_before['20']+'\n'
result=dic_before['20']
result[0]=dic_before['20']
result[1]=20
flag=1
if(j=='12'):
self.message2['text']=self.message2['text']+dic_before['19']+"+"+dic_before['12']+"——>"+dic_before['20']+'\n'
result=dic_before['20']
result[0]=dic_before['20']
result[1]=20
flag=1
if(j=='13'):
self.message2['text']=self.message2['text']+dic_before['19']+"+"+dic_before['13']+"——>"+dic_before['20']+'\n'
result=dic_before['20']
result[0]=dic_before['20']
result[1]=20
flag=1
if(i=='21'):
for j in list_real:
if(j=='16'):
self.message2['text']=self.message2['text']+dic_before['21']+"+"+dic_before['16']+"——>"+dic_before['20']+'\n'
result=dic_before['20']
result[0]=dic_before['20']
result[1]=20
flag=1
if(i=='24'):
for j in list_real:
if(j=='5'):
self.message2['text']=self.message2['text']+dic_before['24']+"+"+dic_before['5']+"——>"+dic_before['22']+'\n'
result=dic_before['22']
result[0]=dic_before['22']
result[1]=22
flag=1
if __name__ == '__main__':
window = Tk()
application = accounting(window)
window.mainloop()