**

实验一:产生式系统实验

**
一、实验目的:
熟悉一阶谓词逻辑和产生式表示法,掌握产生式系统的运行机制,以及基于规则推理的基本方法。
二、实验内容:
设计并编程实现一个小型产生式系统(如分类、诊断等类型)
三、实验要求:
1.具体应用领域自选,具体系统名称自定。
2.用一阶谓词逻辑和产生式规则作为知识表示,利用产生式系统实验程序,建立知识库,分别运行正、反推理。
四、实验算法:
本次实验我实现了动物识别系统的产生式系统,在实验开始前首先应建立该系统的综合数据库,规则库,和目标库。
初学者,不喜勿喷
实验准备:
规则库:rules.txt
在这里插入图片描述
目标库:goal.txt
在这里插入图片描述
综合数据库:data.txt
在这里插入图片描述
实验代码:

package AI.Text;

import java.util.Scanner;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.sql.SQLException;
import java.io.*;

public class text_1 {
	public static String Data[]=new String[50];   //综合数据库
	public static int Data_count=0;   //记录综合数据库中数据的个数
	public static int Rules_Cond[][]=new int [100][100];  //记录规则库中的规则条件
	public static int Rules_Cond_count[]=new int[100];   //记录每条规则条件的个数
	public static int Rules_Resl[]=new int [100];   //记录规则库中的规则结果
	public static int Rules_count=0;               //规则数
	public static String Goal[]=new String[50];    //目标数组
	public static int Goal_count=0;				//目标的数量
	public static String Jug[]=new String[50];   //存放输入的条件
	public static int Jug_int[]=new int[50];	//存放输入的条件的编号  其中Jug_int[i]+1=data里面的编号
	public static int Jug_count=0;     //记录输入的条件数
	public static int etc[]=new int[100];

//初始化函数
	public static void Init() {
		for(int i=0;i<Rules_count;i++) {
			etc[i]=0;
		}
		for(int i=0;i<Jug_count;i++) {
			Jug[i]=null;
			Jug_int[i]=0;
		}
		Jug_count=0;
	}

//读取特征
	public static void ReadData() throws IOException {
		BufferedReader filereade = new BufferedReader(new FileReader("data.txt"));
		String Temp;
		//计算数据的个数
		while ((Temp = filereade.readLine()) != null) {
			Data_count++;
		}
		
		BufferedReader filereader = new BufferedReader(new FileReader("data.txt"));
		int i=0;
		while ((Temp = filereader.readLine()) != null) {
			Data[i++]=Temp.substring(3);
		}
	}

//读取规则
	public static void ReadRules() throws IOException {
		BufferedReader filereade = new BufferedReader(new FileReader("rules.txt"));
		String Temp;
		//计算数据的个数
		while ((Temp = filereade.readLine()) != null) {
			Rules_count++;
		}
		BufferedReader filereader = new BufferedReader(new FileReader("rules.txt"));
		int i=0;
		while ((Temp = filereader.readLine()) != null) {
			Temp=Temp.substring(4);
			int m=0;
			int n=0;
			int len=Temp.length();
			for(int j=0;j<len;j++) {
				
				if(Temp.charAt(j)=='&') {
					String str=Temp.substring(m,j);
					Rules_Cond[i][n++]=Integer.valueOf(str).intValue();
					m=j+1;
				}
				else if(Temp.charAt(j)=='-') {
					String str=Temp.substring(m,j);
					Rules_Cond[i][n++]=Integer.valueOf(str).intValue();
					m=j+2;
				}
				else if(Temp.charAt(j)==';') {
					String str=Temp.substring(m,j);
					Rules_Resl[i]=Integer.valueOf(str).intValue();
					break;
				}
			}//for
			Rules_Cond_count[i++]=n;
		}//while
		Init();
	}

//读取目标文件
	public static void ReadGoal() throws IOException{
		BufferedReader filereade = new BufferedReader(new FileReader("goal.txt"));
		String Temp;
		//计算数据的个数
		while ((Temp = filereade.readLine()) != null) {
			Goal_count++;
		}
		
		BufferedReader filereader = new BufferedReader(new FileReader("goal.txt"));
		int i=0;
		while ((Temp = filereader.readLine()) != null) {
			Goal[i++]=Temp.substring(2);
		}
	}
//将输入的条件转换为编号
	public static void Trans() {
		for(int i=0;i<Jug_count;i++) {
			
			String str=Jug[i];
			for(int j=0;j<Data_count;j++) {
				if(str.equals(Data[j])) {
					Jug_int[i]=j;
					break;
				}
			}
			
		}
	}
	public static void Add() {
		for(int i=0;i<Rules_count;i++) {
			int flag=0;
			int resl=Rules_Resl[i];
			for(int j=0;j<Goal_count;j++) {
				if(Data[resl-1].equals(Goal[j])) {
					flag=1;
					break;
				}
			}
			if(flag==1) {   //判断目标是不是goal里面的
				continue;
			}else {      
				int sd=1;
				for(int k=0;k<Rules_Cond_count[i];k++) {
					int npc=Rules_Cond[i][k];
					int q=0;
					for(int p=0;p<Jug_count;p++) {
						if(npc-1==Jug_int[p]) {
							q=1;     //找到了
							break;
						}
					}//p
					if(q==0) {   //没找到
						sd=0;
						break;
					}
				}//k
				if(sd==1) {
					Jug[Jug_count++]=Data[Rules_Resl[i]-1];
					Trans();
				}
			}//else
		}//i
	}
//逆向搜索主程序
	public static void Find_1() {
		JFrame tf = new JFrame("推理过程及推理结果:");
		tf.setSize(500, 300);
		tf.setLocation(300, 200);
		tf.setVisible(true);
		tf.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
		JTextArea showarea = new JTextArea(12, 34);
		JScrollPane scrollpane = new JScrollPane(showarea);
		showarea.setEditable(false);
		tf.add(scrollpane);
		showarea.setText("");
		Add();
		String str = null;
		for(int i=0;i<Goal_count;i++) {
			int npc=1;
			showarea.append("判断该动物是不是"+Goal[i]+"\n");
			int tr = 0;   //记录目标
			int pc=0;
			for(int j=0;j<Data_count;j++) {
				if(Goal[i].equals(Data[j])) {
					tr=j;
					break;
				}
			}
			for(int j=0;j<Rules_count;j++) {
				if(tr+1==Rules_Resl[j]) {//tr+1
					pc=j;
					break;
				}
			}
			for(int j=0;j<Rules_Cond_count[pc];j++) {
				int flag=0;
				int we=Rules_Cond[pc][j];
				showarea.append("它是"+Data[we-1]+"吗?\t");
				for(int k=0;k<Jug_count;k++) {
					if(we-1==Jug_int[k]) {
						showarea.append("是"+"\n");
						flag=1;
						break;
					}
				}
				if(flag==0) {
					showarea.append("否"+"\n");
					npc=0;
					break;
				}
			}
			if(npc==0) {
				showarea.append("它不是"+Goal[i]+"\n\n");
			}else {
				str=Goal[i];
				showarea.append("它是"+Goal[i]+"\n\n");
			}
		}
		if(str!=null)
			showarea.append("\n推理结果:它是"+str);
		else
			showarea.append("\n条件不足,推理不出!!");
	}
//正向搜索主程序
	public static void Find() {
		JFrame tf = new JFrame("推理过程及推理结果:");
		tf.setSize(500, 300);
		tf.setLocation(300, 200);
		tf.setVisible(true);
		tf.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
		JTextArea showarea = new JTextArea(12, 34);
		JScrollPane scrollpane = new JScrollPane(showarea);
		showarea.setEditable(false);
		tf.add(scrollpane);
		showarea.setText("");
		while(true) {
			
			int flag = 0;
			String ob = null;
			int npc=0;
			for(int i=0;i<Rules_count;i++) {
				if(etc[i]==1) {
					continue;
				}
				int num=Rules_Cond_count[i];
				for(int j=0;j<num;j++) {
					flag=0;
					for(int k=0;k<Jug_count;k++) {
						if(Rules_Cond[i][j]-1==Jug_int[k]) {
							ob=Data[Rules_Resl[i]-1];
							flag=1;
							break;
						}
					}
					if(flag==0)
						break;
				}
				if(flag==1) {
					int w=i+1;
					showarea.append("使用规则"+w+":");
					for(int r=0;r<num;r++) {
						if(r<num-1)
							showarea.append(Data[Rules_Cond[i][r]-1]+"    &    ");
						else
							showarea.append(Data[Rules_Cond[i][r]-1]+"");
					}
					showarea.append("---->"+Data[Rules_Resl[i]-1]+"\n\n");
					Jug_int[Jug_count++]=Rules_Resl[i]-1;
					etc[i]=1;
					for(int q=0;q<Goal_count;q++) {
						if(ob.equals(Goal[q])) {
							npc=1;
							showarea.append("推理结果为:"+ob);
							break;
						}
					}
					break;
				}	
			}
			if(flag==0) {
				showarea.append("条件不足!");
				return;
			}
			if(npc!=0) 
				break;
		}
		
	}
	
//制作界面
	private static void createAndShowGUI() {
		JFrame f = new JFrame("动物识别系统");
		f.setLayout(new FlowLayout(FlowLayout.LEFT, 200, 50));
		f.setSize(500, 300);
		f.setLocation(300, 200);
		f.setVisible(true);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		JButton btn0 = new JButton("进入");
		JButton btn1 = new JButton("退出");
		f.add(btn0);
		f.add(btn1);
	//进入
		btn0.addActionListener(e -> {
			JFrame tf = new JFrame("查询");
			tf.setSize(700, 500);
			tf.setLocation(300, 200);
			tf.setVisible(true);
			tf.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
			JTextArea showarea = new JTextArea(20, 50);
			JScrollPane scrollpane = new JScrollPane(showarea);
			showarea.setEditable(false);
			JPanel panel = new JPanel(new GridLayout(0, 2,50, 20));
			
			showarea.setText("");
			showarea.append("规则库:\n");
			showarea.append("序号\t结论\t\t\t条件\n\n");
			int npc=1;
			for (int i = 0; i < Rules_count; i++) {
				showarea.append("R"+npc+":\t");
				showarea.append("animal["+Data[Rules_Resl[i]-1]+"]:----------->\t");
				int t=Rules_Cond_count[i];
				for(int j=0;j<t;j++) {
					if(j<t-1)
						showarea.append("is["+Data[Rules_Cond[i][j]-1]+"]    &    ");
					else
						showarea.append("is["+Data[Rules_Cond[i][j]-1]+"]\n");
				}
				showarea.append("\n");
				npc++;
			}
			JTextField Rule = new JTextField(1000);
			JLabel label_Rule = new JLabel("         输入综合数据库中存放的实事(以;间隔;结束):");
			JButton btn = new JButton("正向推理");
			JButton btn_1 = new JButton("逆向推理");
		//逆向推理btn_1
			btn_1.addActionListener(o -> {
				Init();
				String rule = Rule.getText();
				if (rule != null && !rule.trim().equals("")) {
					int m=0;
					for(int i=0;i<rule.length();i++) {
						if(rule.charAt(i)==';') {
							Jug[Jug_count++]=rule.substring(m, i);
							m=i+1;
							
						}
					}
					Trans();
					Find_1();
				}else {
					JDialog dialog = new JDialog(tf, "提示", true);
					dialog.setSize(200, 100);
					dialog.setLocation(500, 300);
					JLabel label = new JLabel("          推理规则不能为空!");
					dialog.add(label);
					dialog.setVisible(true);
					dialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
				}
			});
		//正向推理btn
			btn.addActionListener(o -> {
				Init();
				String rule = Rule.getText();
				if (rule != null && !rule.trim().equals("")) {
					int m=0;
					for(int i=0;i<rule.length();i++) {
						if(rule.charAt(i)==';') {
							Jug[Jug_count++]=rule.substring(m, i);
							m=i+1;
							
						}
					}
					Trans();
					Find();
				}else {
					JDialog dialog = new JDialog(tf, "提示", true);
					dialog.setSize(200, 100);
					dialog.setLocation(500, 300);
					JLabel label = new JLabel("          推理规则不能为空!");
					dialog.add(label);
					dialog.setVisible(true);
					dialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
				}
			});
			
			panel.add(label_Rule);
			panel.add(Rule);
			panel.add(btn);
			panel.add(btn_1);
			tf.add(scrollpane);
			tf.add(panel, BorderLayout.PAGE_END);
		});
	//退出
		btn1.addActionListener(e -> System.exit(0));
	}
	
	public static void Run() throws IOException {
		ReadData();
		ReadRules();
		ReadGoal();
	}
	
	public static void main(String[] args) throws IOException {
		Scanner in = new Scanner(System.in);
		Run();
		SwingUtilities.invokeLater(text_1::createAndShowGUI);
	}

}

五、运行结果及分析:
运行主界面:
在这里插入图片描述

点击【进入】后:进入查询界面;这个界面上面是一个文本域,在文本域里面有显示规则库,中间部分是输入框,输入想查询的事实。注:每个事实之间以英文的分号分隔开,并且需要以英文分号结束。下面是两个按钮,分别是【正向推理】和【反向推理】,可以选择自己想要的推理方式。
在这里插入图片描述
在这里插入图片描述
上面输入的事实是书上给出的例子,看下会不会得到同样的结果。
输入的事实为书上的例子:有暗斑点;长脖子;长腿;有奶;有蹄;
逆向推理:下面是截长图的效果。可以清晰看到推理结果正确,因此,逆向推理正确!

在这里插入图片描述
正向推理:书上给出的也是正向推理,推理结果及过程完全和书上的一样,因此正向推理正确!

在这里插入图片描述

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐