正向推理:使数据和产生式左部匹配,对匹配成功的产生式执行其右部。
反向推理:把子目标和GDB中的数据或产生式右部匹配。与数据匹配成功者生成叶节点;产生式右部匹配成功者,则使该产生式左部成为新的子目标。
知识库:
R1: 如果 某动物有毛发(F1) 则 该动物是哺乳动物(M1)
R2: 如果 某动物有奶(F2) 则 该动物是哺乳动物(M1)
R3: 如果 某动物有羽毛(F3) 则 该动物是鸟(M4)
R4: 如果 某动物会飞(F4),且下蛋(F5) 则 该动物是鸟(M4)
R5: 如果 某动物吃肉(F6) 则 该动物是食肉动物(M2)
R6: 如果 某动物有锋利的牙齿(F7),且有爪(F8), 且眼睛盯着前方(F9) 则 该动物是食肉动物(M2)
R7: 如果 某动物是哺乳动物(M1),且有蹄(F10) 则 该动物是有蹄类哺乳动物(M3)
R8: 如果 某动物是哺乳动物(M1),且反刍(F11) 则 该动物是有蹄类哺乳动物(M3),且偶蹄类
R9: 如果 某动物是哺乳动物(M1),且是食肉动物(M2), 且黄褐色(F12),且有暗班(F13) 则 该动物是豹(H1)
R10:如果 某动物是哺乳动物(M1),且是食肉动物(M2), 且黄褐色(F12),且有黑色条纹(F14) 则 该动物是虎(H2)
R11:如果 某动物是有蹄类哺乳动物(M3),且有长脖子 (F15),且有长腿(F16),且有暗斑(F13) 则 该动物是长颈鹿(H3)
R12:如果 某动物是有蹄类哺乳动物(M3), 且有黑条纹(F14) 则 该动物是斑马(H4)
R13:如果 某动物是鸟(M4),且不会飞(F17), 且有长脖子(F15),且有长腿(F16), 且是黑白色(F18) 则 该动物是鸵鸟(H5)
R14:如果 某动物是鸟(M4),且不会飞(F17), 且会游泳(F19), 且是黑白色(F18) 则 该动物是企鹅(H6)
R15:如果 某动物是鸟(M4),且善飞(F20) 则 该动物是信天翁(H7)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-88k4bQx6-1642483263425)(C:\Users\pumpkin\AppData\Roaming\Typora\typora-user-images\image-20210413104013980.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fy91pDMV-1642483263426)(C:\Users\pumpkin\AppData\Roaming\Typora\typora-user-images\image-20210413172448711.png)]
public static int[][] pre = {{0},{1},{2},{3,4},{5},
{6,7,8},{20,9},{20,10},{20,21,11,12},{20,21,11,13},
{22,14,15,12},{22,13},{23,16,14,15,17},{23,16,18,17},{23,19}};
public static int[] after = {20,20,23,23,21,21,22,22,24,25,26,27,28,29,30};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qPTKTPLm-1642483263428)(C:\Users\pumpkin\AppData\Roaming\Typora\typora-user-images\image-20210413182742487.png)]
public static List<List<Integer>> getAvailRule(List<Integer> db){
List<List<Integer>> availRule = new ArrayList<>();
for (int i = 0; i < KB.rules().size(); i++) {
int cou = 0;
for (int j = 0; j < KB.rules().get(i).size(); j++) {
for (int k = 0; k < db.size(); k++) {
if (db.get(k) == KB.rules().get(i).get(j)){
cou++;
}
}
}
if (cou==KB.rules().get(i).size()) {
availRule.add(KB.rules().get(i));
}
}
return availRule;
}
正向推理:
infer.java
import java.util.*;
public class Infer {
public static void forward(){
List<Integer> db = getDB(); //将初始事实集加入数据基中
List<List<Integer>> availRule = getAvailRule(db); //扫描数据基和知识库,从知识库中寻找可用规则集
List<List<Integer>> preRule = new ArrayList<>();
while (availRule != null) {
for (int i = 0; i < availRule.size(); i++) {
if (preRule.contains(availRule.get(i))) continue;
Integer value = KB.getMatch().get(availRule.get(i));
System.out.println("由" + availRule.get(i) + "推出:" + value);
db.add(value);
preRule.add(availRule.get(i));
}
availRule = getAvailRule(db);
int flag = 0;
int result = 0;
for (int j = 0; j < db.size(); j++) {
if (KB.animal().contains(db.get(j))){
flag = 1;
result = db.get(j);
break;
}
}
if(flag == 1) {
System.out.println("此时,db为:" + db);
System.out.println("推理结果:" + KB.factsKB.get(result));
break;
}
}
}
public static List<Integer> getDB(){
List<Integer> db = new ArrayList<>();
Scanner in = new Scanner(System.in);
System.out.println("请输入初始事实集的序号:");
String fact = in.nextLine();
String[] arr = fact.split(" ");
for (int i = 0; i < arr.length; i++) {
db.add(Integer.parseInt(arr[i]));
}
return db;
}
public static List<List<Integer>> getAvailRule(List<Integer> db){
List<List<Integer>> availRule = new ArrayList<>();
for (int i = 0; i < KB.rules().size(); i++) {
int cou = 0;
for (int j = 0; j < KB.rules().get(i).size(); j++) {
for (int k = 0; k < db.size(); k++) {
if (db.get(k) == KB.rules().get(i).get(j)){
cou++;
}
}
}
if (cou==KB.rules().get(i).size()) {
availRule.add(KB.rules().get(i));
}
}
return availRule;
}
}
KB.java
import java.util.*;
public class KB {
public static String[] list = new String[]{
/*F1*/"有毛发",/*F2*/"有奶",/*F3*/"有羽毛",/*F4*/"会飞",/*F5*/"下蛋",
/*F6*/"吃肉",/*F7*/"犀利牙齿",/*F8*/"有爪",/*F9*/"眼睛前视",/*F10*/"有蹄",
/*F11*/"反刍动物",/*F12*/"黄褐色",/*F13*/"暗斑",/*F14*/"黑条纹",/*F15*/"长脖子",
/*F16*/"长腿",/*F17*/"不会飞",/*F18*/"黑白色",/*F19*/"会游泳",/*F20*/"善飞",
/*M1*/"哺乳动物",/*M2*/"食肉动物",/*M3*/"有蹄类",/*M4*/"鸟",
/*H1*/"豹",/*H2*/"虎",/*H3*/"长颈鹿",/*H4*/"斑马",/*H5*/"鸵鸟",/*H6*/"企鹅",/*H7*/"信天翁"
};
public static List<String> factsKB = Arrays.asList(list);
public static List<List<Integer>> rules(){
List<List<Integer>> pre = new ArrayList<>();
List<Integer> rule1 = new ArrayList<>();
rule1.add(0);
pre.add(rule1);
List<Integer> rule2 = new ArrayList<>();
rule2.add(1);
pre.add(rule2);
List<Integer> rule3 = new ArrayList<>();
rule3.add(2);
pre.add(rule3);
List<Integer> rule4 = new ArrayList<>();
rule4.add(3);
rule4.add(4);
pre.add(rule4);
List<Integer> rule5 = new ArrayList<>();
rule5.add(5);
pre.add(rule5);
List<Integer> rule6 = new ArrayList<>();
rule6.add(6);
rule6.add(7);
rule6.add(8);
pre.add(rule6);
List<Integer> rule7 = new ArrayList<>();
rule7.add(20);
rule7.add(9);
pre.add(rule7);
List<Integer> rule8 = new ArrayList<>();
rule8.add(20);
rule8.add(10);
pre.add(rule8);
List<Integer> rule9 = new ArrayList<>();
rule9.add(20);
rule9.add(21);
rule9.add(11);
rule9.add(12);
pre.add(rule9);
List<Integer> rule10 = new ArrayList<>();
rule10.add(20);
rule10.add(21);
rule10.add(11);
rule10.add(13);
pre.add(rule10);
List<Integer> rule11 = new ArrayList<>();
rule11.add(22);
rule11.add(14);
rule11.add(15);
rule11.add(12);
pre.add(rule11);
List<Integer> rule12 = new ArrayList<>();
rule12.add(22);
rule12.add(13);
pre.add(rule12);
List<Integer> rule13 = new ArrayList<>();
rule13.add(23);
rule13.add(16);
rule13.add(14);
rule13.add(15);
rule13.add(17);
pre.add(rule13);
List<Integer> rule14 = new ArrayList<>();
rule14.add(23);
rule14.add(16);
rule14.add(18);
rule14.add(17);
pre.add(rule14);
List<Integer> rule15 = new ArrayList<>();
rule15.add(23);
rule15.add(19);
pre.add(rule15);
return pre;
}
// public static int[][] pre = {{0},{1},{2},{3,4},{5},
// {6,7,8},{20,9},{20,10},{20,21,11,12},{20,21,11,13},
// {22,14,15,12},{22,13},{23,16,14,15,17},{23,16,18,17},{23,19}};
public static int[] after = {20,20,23,23,21,21,22,22,24,25,26,27,28,29,30};
public static Map<List<Integer>,Integer> getMatch() {
Map<List<Integer>,Integer> match = new HashMap<>();
for (int i = 0; i < after.length; i++) {
match.put(rules().get(i),after[i]);
}
return match;
}
public static List<Integer> animal(){
List<Integer> ani = new ArrayList<>();
ani.add(24);
ani.add(25);
ani.add(26);
ani.add(27);
ani.add(28);
ani.add(29);
ani.add(30);
return ani;
}
}
Animal.java
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Animal {
public static void main(String[] args) {
System.out.println("事实集如下:");
for (int i = 0; i < KB.factsKB.size()-7; i++){
System.out.println("事实" + (i) + ":" + KB.factsKB.get(i));
}
Infer.forward();
}
}
未完善的
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class InferBackward {
public static void backward() {
Scanner in = new Scanner(System.in);
for (int i = 0; i < KB.animal().size(); i++) {
System.out.println(i + ":" + KB.factsKB.get(KB.animal().get(i)));
}
System.out.println("请问你觉得你看到的动物是什么?请输入序号:");
int s = in.nextInt();
int g = s + 24;
System.out.println("事实集如下:");
for (int i = 0; i < KB.factsKB.size()-7; i++){
System.out.println("事实" + (i) + ":" + KB.factsKB.get(i));
}
System.out.println("请问你看到的事实都有哪些?请输入序号:");
Scanner in1 = new Scanner(System.in);
String fact = in1.nextLine();
String[] arr = fact.split(" ");
List<Integer> facts = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
facts.add(Integer.parseInt(arr[i]));
}
List<Integer> ach = new ArrayList<>(); //achieve返回一个列表
List<Integer> achieve = achieve(g, ach);
for (int i = 0; i < facts.size(); i++) {
if(facts.get(i) != achieve.get(i)){
System.out.println("该动物不是" + KB.factsKB.get(g));
break;
}
}
System.out.println("该动物是" + KB.factsKB.get(g));
}
public static List<List<Integer>> selRules(int g) {
List<List<Integer>> ruleSet = new ArrayList<>();
for (List<Integer> key : KB.getMatch().keySet()) {
if (KB.getMatch().get(key).equals(g)) {
ruleSet.add(key);
}
}
return ruleSet;
}
public static List<Integer> achieve(int g, List<Integer> ach){
List<List<Integer>> ruleset = selRules(g);
if (ruleset == null ) {
ach.add(g);
return ach;
}
else {
for (int i = 0; i < ruleset.size(); i++) {
for (int j = 0; j < ruleset.get(i).size(); j++) {
achieve(ruleset.get(i).get(j),ach);
}
}
}
return ach;
}
}
完全版
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class InferBackward {
public static void backward() {
Scanner in = new Scanner(System.in);
for (int i = 0; i < KB.animal().size(); i++) {
System.out.println(i + ":" + KB.factsKB.get(KB.animal().get(i)));
}
System.out.println("请问你觉得你看到的动物是什么?请输入序号:");
int s = in.nextInt();
int g = s + 24;
System.out.println("事实集如下:");
for (int i = 0; i < KB.factsKB.size()-7; i++){
System.out.println("事实" + (i) + ":" + KB.factsKB.get(i));
}
System.out.println("请问你看到的事实都有哪些?请输入序号:");
Scanner in1 = new Scanner(System.in);
String fact = in1.nextLine();
String[] arr = fact.split(" ");
List<Integer> facts = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
facts.add(Integer.parseInt(arr[i]));
}
List<Integer> ach = new ArrayList<>(); //achieve返回一个列表
List<Integer> achieve = achieve(g, ach, facts);
for (int i = 0; i < facts.size(); i++) {
if(facts.get(i) != achieve.get(i)){
System.out.println("该动物不是" + KB.factsKB.get(g));
break;
}
}
System.out.println("该动物是" + KB.factsKB.get(g));
}
public static List<List<Integer>> selRules(int g) {
List<List<Integer>> ruleSet = new ArrayList<>();
for (List<Integer> key : KB.getMatch().keySet()) {
if (KB.getMatch().get(key).equals(g)) {
ruleSet.add(key);
}
}
return ruleSet;
}
public static List<Integer> achieve(int g, List<Integer> ach, List<Integer> facts){
List<List<Integer>> ruleset = selRules(g);
if (ruleset.isEmpty() ) {
if (facts.contains(g)){
ach.add(g);
return ach;
}
}
for (int i = 0; i < ruleset.size(); i++) {
for (int j = 0; j < ruleset.get(i).size(); j++) {
achieve(ruleset.get(i).get(j),ach,facts);
}
}
return ach;
}
}
s){
List<List> ruleset = selRules(g);
if (ruleset.isEmpty() ) {
if (facts.contains(g)){
ach.add(g);
return ach;
}
}
for (int i = 0; i < ruleset.size(); i++) {
for (int j = 0; j < ruleset.get(i).size(); j++) {
achieve(ruleset.get(i).get(j),ach,facts);
}
}
return ach;
}
}