建立一个动物识别系统的规则库,用以识别虎、豹、斑马、长颈鹿、企鹅、鸵鸟、信天翁等7种动物,其中规则如下。此时,如果初始综合数据库包含的事实有:动物有暗斑点,有长脖子,有长腿,有奶,有蹄,请问推理出的结果是什么动物?(长颈鹿)
为了识别这些动物,可以根据动物识别的特征,建立包含下述规则的规则库:
R1:if 动物有毛发 then 动物是哺乳动物
R2:if 动物有奶 then 动物是哺乳动物
R3:if 动物有羽毛 then 动物是鸟
R4:if 动物会飞 and 会生蛋 then 动物是鸟
R5:if 动物吃肉 then 动物是食肉动物
R6:if 动物有犀利牙齿 and 有爪 and 眼向前方 then 动物是食肉动物
R7:if 动物是哺乳动物and有蹄then动物是有蹄类动物
R8:if 动物是哺乳动物and反刍then动物是有蹄类动物
R9:if 动物是哺乳动物and是食肉动物and有黄褐色 and 有暗斑点 then 动物是豹
R10:if 动物是哺乳动物 and是食肉动物and有黄褐色 and 有黑色条纹 then 动物是虎
R11:if 动物是有蹄类动物 and 有长脖子and有长腿and有暗斑点 then 动物是长颈鹿
R12:if 动物是有蹄类动物 and有黑色条纹 then 动物是斑马
R13:if 动物是鸟and不会飞 and有长脖子and有长腿 and有黑白二色 then 动物是鸵鸟
R14:if 动物是鸟 and不会飞 and会游泳 and有黑白二色 then 动物是企鹅
R15:if 动物是鸟 and善飞 then 动物是信天翁
项目程序设计的总体思路:
首先思考用什么数据结构来构建规则库,因为规则库总是一条或多条条件推出一个结论,所以想到用List<String>来存储条件,结论就用Sting来存储,于是一条规则我们就可以用Map<List<String>,Sting>来存储,同时为了方便对规则进行引用或做标记,我们需要给规则标号,于是就再把规则封装成Map<Integer,Map<List<String>,Sting>>,为了方便构建规则库,我们把规则库封装成对象,里面包含两个属性一个是Map<Integer,Map<List<String>,Sting>>类型的规则,一个是int类型的编号。然后想到创建一个方法,用来给这个规则库对象添加规则,于是可以编写出方法:
public void addRule(Map<List<String>, String> rule) {
rules.put(ruleCount, rule); // 将规则存入规则库
ruleCount++; // 规则编号递增
}
接下来思考程序的展现形式,为了让用户更直观的使用,顺便复习GUI的相关知识,我们决定为程序做一个图形化界面。于是设计一个主界面,提示用户输入事实,并展示给用户规则库的信息,并设置正向推理和反向推理两个按钮,让用户选择推理方式。同时,为了防止用户输入不合法的信息,我们给用户写了一个帮助说明,提示用户该如何使用本程序。
正向推理思路:
我参照实验指导书中产生式系统的问题求解基本过程,首先将用户传过来的事实库信息封装成List数组,然后遍历所有规则库中的规则,如果规则的前提条件能和事实区的内容相匹配,且这个规则没有使用过,就把规则编号加入一个数组中,称为可用规则集,接着从可用规则集中选取第一个可用规则(冲突消解策略,我这里选择最旧选择),将规则所得到的结论加入到事实库中,并对规则做上标记,表示已使用,然后判断事实库中是否包含问题的解,即七种动物,没有就继续重复以上步骤,直到规则库中没有未使用的规则或者可用规则数量为0时,表示问题无解,提示用户进一步提供关于该问题的已知事实。
反向推理思路:
参照实验指导书的推理规则,进行反向推导。实现过程如下:首先建立了两个List类型变量onlycondition:用来存储只能作为规则库中条件的事实,condAndaml:用来存储既能作为条件又能作为结果的事实。将用户输入的事实库当作是待对比结果集合,然后遍历规则库中推导结果为7种动物的规则,获取该动物对应的条件1,判断条件1中是否含有数组condAndaml中的元素,若含有将此元素,将此元素在规则库中的前提条件2提取出来。重复上述的步骤,直到条件中不再含有condAndaml中的元素。将条件1,条件2等与待对比结果集合进行比较,如果与待对比结果集合一一对应,最终就取此动物为用户输入的事实所对应的最终结果。这样做,虽然代码比较冗余,但是非常好理解。
规则库对象:
//定义一个KnowledgeBase类,表示一个知识库
public class KnowledgeBase {
//定义一个ruleCount变量,表示规则的编号
private int ruleCount;
//用一个Map<Integer, Map<List<String>, String>>来存储规则
private Map<Integer, Map<List<String>, String>> rules;
public KnowledgeBase() {
ruleCount = 1; // 初始化规则编号从1开始
rules = new HashMap<>();
}
public void addRule(Map<List<String>, String> rule) {
rules.put(ruleCount, rule); // 将规则存入规则库
ruleCount++; // 规则编号递增
}
}
主界面设计:
代码:
public class AnimalRecognitionGUI extends JFrame {
private JTextArea ruleArea = new JTextArea();
// 构造方法,初始化界面
public AnimalRecognitionGUI() {
setTitle("动物识别系统");
setSize(730, 450);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
// 设置窗口布局为边界布局
setLayout(new BorderLayout());
// 创建一个面板,用于放置输入框和开始按钮
JPanel inputPanel = new JPanel();
// 设置面板布局为流式布局
inputPanel.setLayout(new FlowLayout());
JLabel inputLabel = new JLabel("请输入动物的特征:");
inputLabel.setFont(new Font("微软雅黑", Font.BOLD, 20));
// 创建一个输入框,用于用户输入特征
JTextField inputField = new JTextField(30);
// 创建一个正向推理按钮,用于触发正向推理
JButton startButton = new JButton("正向推理");
// 创建一个反向推理按钮,用于触发反向推理
JButton reverseButton = new JButton("反向推理");
inputPanel.add(inputLabel);
inputPanel.add(inputField);
inputPanel.add(startButton);
inputPanel.add(reverseButton);
// 创建一个面板,用于放置规则库文本区域和帮助按钮
JPanel rulePanel = new JPanel();
rulePanel.setLayout(new BorderLayout());
// 创建一个标签,提示用户规则库内容
JLabel ruleLabel = new JLabel("规则库:");
Font labelFont = ruleLabel.getFont();
ruleLabel.setFont(new Font(labelFont.getName(), Font.PLAIN, 20)); // 设置字体大小为16
ruleLabel.setHorizontalAlignment(SwingConstants.LEFT);
ruleArea.setEditable(false);
ruleArea.setFont(new Font("宋体", Font.PLAIN, 16));
// 设置文本区域的内容
ruleArea.setText("R1:if 动物有毛发 then 动物是哺乳动物 \n" +
"R2:if 动物有奶 then 动物是哺乳动物 \n" +
"R3:if 动物有羽毛 then 动物是鸟 \n" +
"R4:if 动物会飞 and 会生蛋 then 动物是鸟 \n" +
"R5:if 动物吃肉 then 动物是食肉动物 \n" +
"R6:if 动物有犀利牙齿 and 有爪 and 眼向前方 then 动物是食肉动物 \n" +
"R7:if 动物是哺乳动物and有蹄then动物是有蹄类动物 \n" +
"R8:if 动物是哺乳动物and反刍then动物是有蹄类动物 \n" +
"R9:if 动物是哺乳动物and是食肉动物and有黄褐色 and 有暗斑点 then 动物是豹 \n" +
"R10:if 动物是哺乳动物 and是食肉动物and有黄褐色 and 有黑色条纹 then 动物是虎 \n" +
"R11:if 动物是有蹄类动物 and 有长脖子and有长腿and有暗斑点 then 动物是长颈鹿 \n" +
"R12:if 动物是有蹄类动物 and有黑色条纹 then 动物是斑马 \n" +
"R13:if 动物是鸟and不会飞 and有长脖子and有长腿 and有黑白二色 then 动物是鸵鸟 \n" +
"R14:if 动物是鸟 and不会飞 and会游泳 and有黑白二色 then 动物是企鹅 \n" +
"R15:if 动物是鸟 and善飞 then 动物是信天翁 ");
// 创建一个滚动面板,用于包裹文本区域,实现滚动效果
JScrollPane scrollPane = new JScrollPane(ruleArea);
// 创建一个面板,用于放置帮助按钮
JPanel helpPanel = new JPanel();
// 设置面板布局为流式布局
helpPanel.setLayout(new FlowLayout());
JButton helpButton = new JButton("帮助");
JButton clearButton = new JButton("清空");
helpPanel.add(helpButton);
helpPanel.add(clearButton);
// 将标签、滚动面板和帮助按钮添加到面板中
rulePanel.add(ruleLabel, BorderLayout.NORTH);
rulePanel.add(scrollPane, BorderLayout.CENTER);
// 将三个面板添加到窗口中
add(inputPanel, BorderLayout.NORTH);
add(rulePanel, BorderLayout.CENTER);
add(helpPanel, BorderLayout.SOUTH);
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFrame tf = new JFrame("正向推理过程及结果:");
tf.setSize(500, 300);
// 设置窗口居中显示
tf.setLocationRelativeTo(null);
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);
KnowledgeBase knowledgeBase = createKnowledgeBase();
String fact = inputField.getText();
List<String> factList = stringToList(fact);
showarea.setText("");
showarea.append(knowledgeBase.solve(factList));
}
});
}
帮助界面设计:
代码:
public class HelpWindow extends JFrame {
//定义一个文本区域,用来显示帮助说明
private JTextArea helpText;
//构造方法,设置窗口的属性和布局
public HelpWindow() {
setTitle("动物识别系统帮助说明");
setSize(600, 520);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setVisible(true);
//创建一个文本区域,用来显示帮助说明
helpText = new JTextArea();
helpText.setFont(new Font("宋体", Font.PLAIN, 16));
//设置文本区域的自动换行
helpText.setLineWrap(true);
helpText.setEditable(false);
helpText.setText(getHelpContent());
//创建一个滚动面板,用来包含文本区域
JScrollPane scrollPane = new JScrollPane(helpText);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
//把滚动面板添加到窗口的内容面板中
getContentPane().add(scrollPane);
}
private String getHelpContent() {
//使用StringBuilder来拼接帮助说明的内容
StringBuilder sb = new StringBuilder();
sb.append("这个系统是一个基于产生式系统的动物识别系统,它可以根据你输入的一些关键字,推理出你想要识别的动物的名称。这个系统可以识别以下七种动物:\n\n");
sb.append("1. 豹 2. 虎 3. 长颈鹿 4. 斑马 5. 鸵鸟 6. 企鹅 7. 信天翁\n\n");
sb.append("为了使用这个系统,你需要遵循以下规则:\n\n");
sb.append("1. 你需要输入一些关键字,描述你想要识别的动物的特征,例如:有毛发,有羽毛,会飞,吃肉等。\n");
sb.append("2. 你需要用英文的逗号分隔每个关键字,例如:有毛发,有羽毛,会飞。\n");
sb.append("3. 你只能输入以下关键字,其余的关键字均无法识别。\n\n");
sb.append(" 有毛发 有奶 有羽毛 会飞 吃肉 有犀利牙齿\n" +
" 有爪 眼向前方 有蹄 会生蛋 黄褐色 有暗斑点\n" +
" 黑色条纹 长脖子 有长腿 不会飞 有黑白二色 会游泳\n" +
" 善飞 鸟 哺乳动物 有蹄类动物 豹 食肉动物\n" +
" 虎 长颈鹿 斑马 鸵鸟 企鹅 信天翁\n\n");
sb.append("- 系统会根据你输入的关键字,使用一系列的规则,推理出你想要识别的动物的名称,并打印出推理的过程和结果。\n");
sb.append("- 如果你输入的关键字与任何动物都不匹配,系统会提示你该问题无解,并终止推理过程。\n\n");
return sb.toString();
}
}
为按钮添加事件:
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFrame tf = new JFrame("正向推理过程及结果:");
tf.setSize(500, 300);
// 设置窗口居中显示
tf.setLocationRelativeTo(null);
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);
KnowledgeBase knowledgeBase = createKnowledgeBase();
String fact = inputField.getText();
List<String> factList = stringToList(fact);
showarea.setText("");
showarea.append(knowledgeBase.solve(factList));
}
});
reverseButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFrame tf = new JFrame("反向推理过程及结果:");
tf.setSize(500, 300);
// 设置窗口居中显示
tf.setLocationRelativeTo(null);
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);
KnowledgeBase knowledgeBase = createKnowledgeBase();
String fact = inputField.getText();
List<String> factList = stringToList(fact);
showarea.setText("");
showarea.append(knowledgeBase.reverseSolve(factList));
}
});
clearButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
inputField.setText("");
}
});
// 为帮助按钮添加监听事件,用于弹出帮助窗口
helpButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 创建一个帮助窗口对象,用于显示帮助说明
HelpWindow helpWindow = new HelpWindow();
}
});
/**
* (1)初始化综合数据库,即把欲解决问题的已知事实送入综合数据库中
* @return 返回规则库
*/
public static KnowledgeBase createKnowledgeBase(){
//创建一个规则库对象
KnowledgeBase kb = new KnowledgeBase();
Map<List<String>, String>[] rules = new HashMap[15];
rules[0] = createRule(Arrays.asList("有毛发"), "哺乳动物");
rules[1] = createRule(Arrays.asList("有奶"), "哺乳动物");
rules[2] = createRule(Arrays.asList("有羽毛"), "鸟");
rules[3] = createRule(Arrays.asList("会飞", "会生蛋"), "鸟");
rules[4] = createRule(Arrays.asList("吃肉"), "食肉动物");
rules[5] = createRule(Arrays.asList("有犀利牙齿", "有爪", "眼向前方"), "食肉动物");
rules[6] = createRule(Arrays.asList("哺乳动物", "有蹄"), "有蹄类动物");
rules[7] = createRule(Arrays.asList("哺乳动物", "反刍"), "有蹄类动物");
rules[8] = createRule(Arrays.asList("哺乳动物", "食肉动物", "黄褐色", "有暗斑点"), "豹");
rules[9] = createRule(Arrays.asList("哺乳动物", "食肉动物", "黄褐色", "黑色条纹"), "虎");
rules[10] = createRule(Arrays.asList("有蹄类动物", "长脖子", "有长腿", "有暗斑点"), "长颈鹿");
rules[11] = createRule(Arrays.asList("有蹄类动物", "黑色条纹"), "斑马");
rules[12] = createRule(Arrays.asList("鸟", "不会飞", "长脖子", "有长腿", "有黑白二色"), "鸵鸟");
rules[13] = createRule(Arrays.asList("鸟", "不会飞", "会游泳", "有黑白二色"), "企鹅");
rules[14] = createRule(Arrays.asList("鸟", "善飞"), "信天翁");
for (Map<List<String>, String> rule : rules) {
kb.addRule(rule);
}
return kb;
}
private static Map<List<String>, String> createRule(List<String> conditions, String result) {
Map<List<String>, String> rule = new HashMap<>();
rule.put(conditions, result);
return rule;
}
/**
* 将逗号分隔的字符串转换为字符串列表
* @param input 逗号分隔的字符串
* @return 字符串列表
*/
public static List<String> stringToList(String input) {
// 使用逗号分隔字符串,并去除空格
String[] array = input.split("\\s*,\\s*");
// 将数组转换为列表
List<String> list = Arrays.asList(array);
return list;
}
正向推理代码:
/**
* 通过正向推理规则解决问题
* @param facts 已知事实
* @return 推理过程的输出内容
*/
public String solve(List<String> facts) {
// 复制已知事实到数据库
List<String> database = new ArrayList<>(facts);
// 标记问题是否已解决
boolean solved = false;
// 已使用的规则编号集合
Set<Integer> used = new HashSet<>();
// 用于存储输出内容的字符串构建器
StringBuilder output = new StringBuilder();
// 开始推理过程
while (!solved) {
// (7)若知识库中不再有未使用规则,也说明该问题无解,终止问题求解过程
if(used.size()==rules.size()){
output.append("该问题无解\n");
break;
}
// (3)检查规则库的未使用规则中是否有其前提可与综合数据库中已知事实相匹配的规则,若有,形成当前可用规则集
// 当前可用的规则集合
List<Integer> available = new ArrayList<>();
// 遍历所有规则,找出当前可用的规则
for (Map.Entry<Integer, Map<List<String>, String>> entry : rules.entrySet()) {
int number = entry.getKey();
Map<List<String>, String> rule = entry.getValue();
List<String> conditional = rule.keySet().iterator().next();
// 如果规则已经被使用过,则跳过
if (used.contains(number)) {
continue;
}
// 如果规则的前提可以与已知事实相匹配,把规则的编号加入当前可用规则集
if (match(conditional, database)) {
available.add(number);
}
}
if (!available.isEmpty()) {
// (4)按照冲突消解策略(这里选择最旧选择:选择最早被添加到可用规则集合中的规则来执行。)
// 从当前可用规则集中选择一个最早被添加到可用规则集合中的规则执行,并对该规则作上标记。
int chosen = available.get(0);
// 获取选择的规则的前提和结果
Map<List<String>, String> rule = rules.get(chosen);
List<String> conditional = rule.keySet().iterator().next();
String result = rule.get(conditional);
output.append("使用规则R"+chosen+": "+conditional+"---->"+result+"\n");
// 把执行该规则后所得到的结论作为新的事实放入综合数据库
database.add(result);
// 对该规则作上标记,表示已使用
used.add(chosen);
// (5)检查已知事实中是否包含了问题的解
List<String> animals = Arrays.asList("长颈鹿", "豹", "虎", "斑马", "鸵鸟", "企鹅", "信天翁");
for (String animal : animals) {
if (database.contains(animal)) {
output.append("推理结果为: "+animal+"\n");
solved = true;
}
}
// (6)当规则库中还有未使用规则,但均不能与综合数据库中的已有事实相匹配时,要求用户进一步提供关于该问题的已知事实
}else if(available.isEmpty()&&used.size()<rules.size()){
if(!solved){
output.append("该问题无解\n\n原因:\n\n规则库中虽然还有未使用规则,但均不能与综合数据库中的已有事实相匹配," +
"\n你可以进一步提供关于该问题的已知事实");
break;
}
}
}
// 返回推理过程的输出内容
return output.toString();
}
运行结果:
输入:哺乳动物,有暗斑点,长脖子,有长腿,有奶,有蹄
输入:有毛发,吃肉,黄褐色,黑色条纹
反向推理代码:
public String reverseSolve(List<String> facts) {
String[] condition = new String[20];//存储只能作为条件的特征
List<String> onlycondition=new ArrayList<>();
onlycondition.add("有毛发");
onlycondition.add("有奶");
onlycondition.add("有羽毛");
onlycondition.add("会飞");
onlycondition.add("会生蛋");
onlycondition.add("吃肉");
onlycondition.add("有犀利牙齿");
onlycondition.add("有爪");
onlycondition.add("眼睛向前方");
onlycondition.add("有蹄");
onlycondition.add("反刍");
onlycondition.add("黄褐色");
onlycondition.add("有暗斑点");
onlycondition.add("黑色条纹");
onlycondition.add("长脖子");
onlycondition.add("有长腿");
onlycondition.add("不会飞");
onlycondition.add("会游泳");
onlycondition.add("有黑白二色");
onlycondition.add("善飞");
List<String>condAndaml = new ArrayList<>();//存储既能作为条件也能作为结果的的特征
condAndaml.add("哺乳动物");
condAndaml.add("鸟");
condAndaml.add("食肉动物");
condAndaml.add("有蹄类动物");
// 复制已知事实到数据库
List<String> database = new ArrayList<>(facts);
// 用于存储输出内容的字符串构建器
StringBuilder output = new StringBuilder();
for (Map.Entry<Integer, Map<List<String>, String>> entry : rules.entrySet()) {
//获取规则编号
int number = entry.getKey();
boolean flag=true;
//只遍历规则库中后7条结果是动物的规则
if (number >= 9) {
Map<List<String>, String> rule = entry.getValue();
//获取结果对应的条件conditional
List<String> conditional = rule.keySet().iterator().next();
//获取规则对应的结果
String result = rule.get(conditional);
output.append("判断该动物是不是"+result+"?"+"\n");
for(String emplot1:conditional)
{
if(condAndaml.contains(emplot1))//判断这个特征在规则库中是否既是条件也是结果
{
if(database.contains(emplot1))//判断事实库中是否存在这个特征
{
//存在
output.append(emplot1+" 是"+"\n");
flag=true;
}
else
{
for (Map.Entry<Integer, Map<List<String>, String>> entry1 : rules.entrySet()) {
boolean flag1 = true;
boolean f=false;
Map<List<String>, String> rule1 = entry1.getValue();
List<String> conditional1 = rule1.keySet().iterator().next();
if (rule1.get(conditional1).equals(emplot1)) {
output.append("这个动物是" + emplot1 + "?" + "\n");
for (String emplot2 : conditional1) {
f=true;
if (condAndaml.contains(emplot2))//判断这个特征在规则库中是否既是条件也是结果
{
if (database.contains(emplot2))//判断事实库中是否存在这个特征
{
//存在
output.append(emplot2 + " 是" + "\n");
flag1 = flag1 && true;
} else {
for (Map.Entry<Integer, Map<List<String>, String>> entry2 : rules.entrySet()) {
boolean flag2 = true;
boolean t=false;
Map<List<String>, String> rule2 = entry2.getValue();
List<String> conditional2 = rule2.keySet().iterator().next(); // 获取对应的键
if (rule2.get(conditional2).equals(emplot2)) {
output.append("这个动物是" + emplot2+ "?" + "\n");
for (String emplot3 : conditional2) {
f=true;
if (condAndaml.contains(emplot3))//判断这个特征在规则库中是否既是条件也是结果
{
if (database.contains(emplot3))//判断事实库中是否存在这个特征
{
//存在
output.append(emplot3 + " 是" + "\n");
flag2 =true;
}
} else//emplot3在规则库中只是条件
{
if (database.contains(emplot3))//判断事实库中是否存在这个特征
{
//存在
output.append(emplot3 + " 是" + "\n");
flag2 = true;
} else {
//不存在
output.append(emplot3 + " 否" + "\n");
t=false;
flag2 = false;
}
}
}
}
flag1 = flag1 && flag2;
if(t)//如果遍历的条件全都是true,直接跳出循环,去遍历下一个特征
{
break;
}
}
}
} else//emplot2在规则库中只是条件
{
if (database.contains(emplot2))//判断事实库中是否存在这个特征
{
//存在
output.append(emplot2 + " 是" + "\n");
flag1 = flag1 && true;
} else {
//不存在
output.append(emplot2 + " 否" + "\n");
f=false;
flag1 = flag1 && false;
}
}
}
}
flag = flag && flag1;
if(f)
{
break;
}
}
}
}
else//emplot1在规则库中只是条件
{
if(database.contains(emplot1))//判断事实库中是否存在这个特征
{
//存在
output.append(emplot1+" 是"+"\n");
flag=flag&&true;
}
else
{
//不存在
output.append(emplot1+" 否"+"\n");
flag=flag&&false;
}
}
}
if(flag)//如果是该动物,直接给出结果。
{
output.append("这个动物是"+result+"\n\n\n");
return output.toString();
}
else{
output.append("这个动物不是"+result+"\n\n\n");
}
}
}
output.append("\n\n\n\n\n");
output.append("对不起未推理出结果!!");
// 推理结果
return output.toString();
}
运行结果:
输入:哺乳动物,有暗斑点,长脖子,有长腿,有奶,有蹄