├── out ├── production │ └── expertSystem │ │ ├── META-INF │ │ └── expertSystem.kotlin_module │ │ └── chgl16 │ │ └── space │ │ ├── Core.class │ │ ├── Main.class │ │ ├── Test.class │ │ ├── Core$1.class │ │ ├── pojo │ │ ├── Rule.class │ │ ├── ResultDto.class │ │ └── RuleProperty.class │ │ ├── controller │ │ ├── IndexController.class │ │ └── RuleController.class │ │ ├── rules.txt │ │ └── view │ │ ├── index.fxml │ │ └── rules.fxml └── artifacts │ └── expertSystem │ ├── expertSystem.jar │ ├── expertSystem.jnlp │ └── expertSystem.html ├── .idea ├── encodings.xml ├── vcs.xml ├── description.html ├── gradle.xml ├── modules.xml ├── misc.xml ├── compiler.xml ├── artifacts │ └── expertSystem.xml ├── uiDesigner.xml └── workspace.xml ├── src └── chgl16 │ └── space │ ├── rules.txt │ ├── Main.java │ ├── pojo │ ├── Rule.java │ ├── ResultDto.java │ └── RuleProperty.java │ ├── controller │ ├── IndexController.java │ └── RuleController.java │ ├── view │ ├── index.fxml │ └── rules.fxml │ └── Core.java ├── expertSystem.iml └── README.md /out/production/expertSystem/META-INF/expertSystem.kotlin_module: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /out/artifacts/expertSystem/expertSystem.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chgl16/animal-recognition-expert-system/HEAD/out/artifacts/expertSystem/expertSystem.jar -------------------------------------------------------------------------------- /out/production/expertSystem/chgl16/space/Core.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chgl16/animal-recognition-expert-system/HEAD/out/production/expertSystem/chgl16/space/Core.class -------------------------------------------------------------------------------- /out/production/expertSystem/chgl16/space/Main.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chgl16/animal-recognition-expert-system/HEAD/out/production/expertSystem/chgl16/space/Main.class -------------------------------------------------------------------------------- /out/production/expertSystem/chgl16/space/Test.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chgl16/animal-recognition-expert-system/HEAD/out/production/expertSystem/chgl16/space/Test.class -------------------------------------------------------------------------------- /out/production/expertSystem/chgl16/space/Core$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chgl16/animal-recognition-expert-system/HEAD/out/production/expertSystem/chgl16/space/Core$1.class -------------------------------------------------------------------------------- /out/production/expertSystem/chgl16/space/pojo/Rule.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chgl16/animal-recognition-expert-system/HEAD/out/production/expertSystem/chgl16/space/pojo/Rule.class -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /out/production/expertSystem/chgl16/space/pojo/ResultDto.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chgl16/animal-recognition-expert-system/HEAD/out/production/expertSystem/chgl16/space/pojo/ResultDto.class -------------------------------------------------------------------------------- /out/production/expertSystem/chgl16/space/pojo/RuleProperty.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chgl16/animal-recognition-expert-system/HEAD/out/production/expertSystem/chgl16/space/pojo/RuleProperty.class -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/description.html: -------------------------------------------------------------------------------- 1 | Simple JavaFX 2.0 application that includes simple .fxml file with attached controller and Main class to quick start. Artifact to build JavaFX application is provided. 2 | -------------------------------------------------------------------------------- /out/production/expertSystem/chgl16/space/controller/IndexController.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chgl16/animal-recognition-expert-system/HEAD/out/production/expertSystem/chgl16/space/controller/IndexController.class -------------------------------------------------------------------------------- /out/production/expertSystem/chgl16/space/controller/RuleController.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chgl16/animal-recognition-expert-system/HEAD/out/production/expertSystem/chgl16/space/controller/RuleController.class -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/chgl16/space/rules.txt: -------------------------------------------------------------------------------- 1 | 有毛发->哺乳动物 2 | 有奶->哺乳动物 3 | 有羽毛->鸟 4 | 会飞&会下蛋->鸟 5 | 吃肉->食肉动物 6 | 有锋利牙齿&有爪&眼向前方->食肉动物 7 | 哺乳动物&有蹄->有蹄类动物 8 | 哺乳动物&反刍->有蹄类动物 9 | 哺乳动物&食肉动物&有黄褐色皮毛&暗斑点->豹 10 | 哺乳动物&食肉动物&有黄褐色皮毛&有黑色条纹->虎 11 | 有蹄类动物&有长脖子&有长腿&有暗斑点->长颈鹿 12 | 有蹄类动物&有黑色条纹->斑马 13 | 鸟&不会飞&有长脖子&有长腿&有黑白二色->鸵鸟 14 | 鸟&会游泳&不会飞&有黑白二色->企鹅 15 | 鸟&善飞->信天翁 -------------------------------------------------------------------------------- /out/production/expertSystem/chgl16/space/rules.txt: -------------------------------------------------------------------------------- 1 | 有毛发->哺乳动物 2 | 有奶->哺乳动物 3 | 有羽毛->鸟 4 | 会飞&会下蛋->鸟 5 | 吃肉->食肉动物 6 | 有锋利牙齿&有爪&眼向前方->食肉动物 7 | 哺乳动物&有蹄->有蹄类动物 8 | 哺乳动物&反刍->有蹄类动物 9 | 哺乳动物&食肉动物&有黄褐色皮毛&暗斑点->豹 10 | 哺乳动物&食肉动物&有黄褐色皮毛&有黑色条纹->虎 11 | 有蹄类动物&有长脖子&有长腿&有暗斑点->长颈鹿 12 | 有蹄类动物&有黑色条纹->斑马 13 | 鸟&不会飞&有长脖子&有长腿&有黑白二色->鸵鸟 14 | 鸟&会游泳&不会飞&有黑白二色->企鹅 15 | 鸟&善飞->信天翁 -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /expertSystem.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /out/artifacts/expertSystem/expertSystem.jnlp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | My App 5 | Unknown 6 | expertSystem 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/chgl16/space/Main.java: -------------------------------------------------------------------------------- 1 | package chgl16.space; 2 | 3 | import javafx.application.Application; 4 | import javafx.fxml.FXMLLoader; 5 | import javafx.scene.Parent; 6 | import javafx.scene.Scene; 7 | import javafx.stage.Stage; 8 | 9 | public class Main extends Application { 10 | 11 | public static Stage stage; 12 | 13 | @Override 14 | public void start(Stage primaryStage) throws Exception{ 15 | Parent root = FXMLLoader.load(getClass().getResource("view/index.fxml")); 16 | primaryStage.setTitle("动物识别专家系统"); 17 | primaryStage.setScene(new Scene(root)); 18 | primaryStage.setResizable(false); 19 | primaryStage.show(); 20 | } 21 | 22 | 23 | public static void main(String[] args) { 24 | // 加载预设规则集 25 | Core.init(); 26 | launch(args); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.idea/artifacts/expertSystem.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | $PROJECT_DIR$/out/artifacts/expertSystem 4 | 5 | 6 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/chgl16/space/pojo/Rule.java: -------------------------------------------------------------------------------- 1 | package chgl16.space.pojo; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 规则类 7 | * @author chgl16 8 | * @date 2019/12/22 22:44 9 | */ 10 | public class Rule { 11 | /** 条件 */ 12 | private List p; 13 | 14 | /** 结果 */ 15 | private String q; 16 | 17 | public Rule(List p, String q) { 18 | this.p = p; 19 | this.q = q; 20 | } 21 | 22 | public Rule() { 23 | } 24 | 25 | public List getP() { 26 | return p; 27 | } 28 | 29 | public void setP(List p) { 30 | this.p = p; 31 | } 32 | 33 | public String getQ() { 34 | return q; 35 | } 36 | 37 | public void setQ(String q) { 38 | this.q = q; 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return "Rule{" + 44 | "p=" + p + 45 | ", q='" + q + '\'' + 46 | '}'; 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /src/chgl16/space/pojo/ResultDto.java: -------------------------------------------------------------------------------- 1 | package chgl16.space.pojo; 2 | 3 | /** 4 | * 推理返回过程和结果 5 | * @author chgl16 6 | * @date 2019/12/22 22:36 7 | */ 8 | public class ResultDto { 9 | /** 过程 */ 10 | private String process; 11 | 12 | /** 结果 */ 13 | private String answer; 14 | 15 | public String getProcess() { 16 | return process; 17 | } 18 | 19 | public void setProcess(String process) { 20 | this.process = process; 21 | } 22 | 23 | public String getAnswer() { 24 | return answer; 25 | } 26 | 27 | public void setAnswer(String answer) { 28 | this.answer = answer; 29 | } 30 | 31 | public ResultDto(String process, String answer) { 32 | this.process = process; 33 | this.answer = answer; 34 | } 35 | 36 | public ResultDto() { 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return "ResultDto{" + 42 | "process='" + process + '\'' + 43 | ", answer='" + answer + '\'' + 44 | '}'; 45 | } 46 | } -------------------------------------------------------------------------------- /out/artifacts/expertSystem/expertSystem.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | 36 | 37 | 38 |

Test page for expertSystem

39 | Webstart: click to launch this app as webstart


40 | 41 | 42 |
43 | 44 | -------------------------------------------------------------------------------- /src/chgl16/space/pojo/RuleProperty.java: -------------------------------------------------------------------------------- 1 | package chgl16.space.pojo; 2 | 3 | import javafx.beans.property.SimpleIntegerProperty; 4 | import javafx.beans.property.SimpleListProperty; 5 | import javafx.beans.property.SimpleStringProperty; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * JavaFX TableView的ObservableList记录列表泛型对象,对应Rule 12 | * @author chgl16 13 | * @date 2019/12/23 9:24 14 | */ 15 | public class RuleProperty { 16 | private SimpleIntegerProperty id; 17 | 18 | private SimpleStringProperty condition; 19 | 20 | private SimpleStringProperty result; 21 | 22 | public RuleProperty(Integer id, List condition, String result) { 23 | this.id = new SimpleIntegerProperty(id); 24 | this.condition = new SimpleStringProperty(condition.toString()); 25 | this.result = new SimpleStringProperty(result); 26 | } 27 | 28 | public Integer getId() { 29 | return id.get(); 30 | } 31 | 32 | public void setId(Integer id) { 33 | this.id.set(id); 34 | } 35 | 36 | public String getCondition() { 37 | return condition.get(); 38 | } 39 | 40 | public void setCondition(List condition) { 41 | this.condition.set(condition.toString()); 42 | } 43 | 44 | public String getResult() { 45 | return result.get(); 46 | } 47 | 48 | public void setResult(String result) { 49 | this.result.set(result); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/chgl16/space/controller/IndexController.java: -------------------------------------------------------------------------------- 1 | package chgl16.space.controller; 2 | 3 | import chgl16.space.Core; 4 | import chgl16.space.Main; 5 | import chgl16.space.pojo.ResultDto; 6 | import javafx.fxml.FXML; 7 | import javafx.fxml.FXMLLoader; 8 | import javafx.fxml.Initializable; 9 | import javafx.scene.Parent; 10 | import javafx.scene.Scene; 11 | import javafx.scene.control.TextArea; 12 | import javafx.scene.control.TextField; 13 | import javafx.stage.Stage; 14 | 15 | import java.io.IOException; 16 | import java.net.URL; 17 | import java.util.HashSet; 18 | import java.util.ResourceBundle; 19 | import java.util.Set; 20 | 21 | public class IndexController implements Initializable { 22 | 23 | @FXML 24 | private TextArea userInputComponent; 25 | 26 | @FXML 27 | private TextField resultComponent; 28 | 29 | @FXML 30 | private TextArea processComponent; 31 | 32 | public void initialize(URL location, ResourceBundle resources) { 33 | 34 | } 35 | 36 | public void goReason() { 37 | // 获取用户输入的事实转为set 38 | Set dataBase = new HashSet<>(); 39 | String[] arr = userInputComponent.getText().split("\n"); 40 | for (String str : arr) { 41 | dataBase.add(str); 42 | 43 | } 44 | 45 | ResultDto resultDto = Core.reason(dataBase); 46 | System.out.println(dataBase); 47 | resultComponent.setText(resultDto.getAnswer()); 48 | processComponent.setText(resultDto.getProcess()); 49 | System.out.println("推理结果为: " + resultDto.getAnswer()); 50 | } 51 | 52 | public void goRuleView() throws IOException { 53 | // 打开新窗口 54 | Parent root = FXMLLoader.load(Main.class.getResource("view/rules.fxml")); 55 | Stage stage = new Stage(); 56 | stage.setTitle("动物识别专家系统"); 57 | Scene scene = new Scene(root); 58 | stage.setScene(scene); 59 | stage.show(); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 动物识别专家系统 2 | 用产生式系统设计的一个简单动物识别专家系统,正向推理,支持规则增删改查 3 | 4 | 5 | ## 1. 开发环境 6 | ![Depfu](https://img.shields.io/depfu/chgl16/animal-recognition-expert-system?color=green&label=Java&logo=V&logoColor=green&style=flat-square) 7 |   ![Depfu](https://img.shields.io/depfu/chgl16/animal-recognition-expert-system?color=red&label=SceneBuilder&logo=V&logoColor=blue&style=flat-square) 8 | 9 | ## 2. 运行效果 10 | ```bash 11 | java -jar out/artifacts/expertSystem/expertSystem.jar 12 | ``` 13 | 14 | ![程序一次推理过程展示](https://i.loli.net/2020/01/10/FGVZhpw2c1v6UbI.png) 15 | 16 | ![规则的增删改查操作界面](https://i.loli.net/2020/01/10/1b7fIXpsP3w9heK.png) 17 | 18 | ## 3. 设计实现 19 | #### 步骤一:规则库、目标集、数据库的建立 20 | 1. 规则库ruleBase采用全局变量方式声明,类型为List,泛型的Rule对象是包括规则前提条件P和结论Q的POJO。使用List也是为了方便JavaFX表格单元的索引操作问题。 21 | 2. 数据库Set dataBase即用户输入的事实、规则前提,作为输入参数传入推理机推理。Set使用HashSet实现类,内部的即HashMap哈斯表结构,无冲突情况下可以在O(1)时间复杂度内命中规则前提P。 22 | 3. 目标集Set aims也为全局变量,元素是要求识别的动物:虎、豹、斑马等。Set也是使用HashSet实现类,更快判断aims.contains(rule.Q)。 23 | 24 | #### 步骤二:推理机的设计和实现 25 | 推理机的推理逻辑过程如下: 26 | 1. 遍历规则库中的所有规则,对于每条规则Ri,判断当前数据库是否包括Ri的所有前提P。如果是,把Ri的结论Q加入数据库。 27 | 2. 多次循环遍历,直到遍历的规则Ri的结论Q属于目标集aims,推理结束,识别动物为Q,或者所有规则遍历结束后,数据库也不再变化,推理结束,无法识别具体动物。 28 | 29 | ```java 30 | /** 31 | * 推理机 32 | * @param dataBase 用户输入的事实检索条件,即当前数据库 33 | * @return 推理过程和结果对象ResultDto 34 | */ 35 | public static ResultDto reason(Set dataBase) { 36 | ResultDto resultDto = new ResultDto(); 37 | resultDto.process = ""; 38 | int count = 0; 39 | while (true) { 40 | // 判断是否有新的推理可用 41 | boolean change = false; 42 | for (Rule rule : ruleBase) { 43 | // 判断数据库是否包含当前规则的所有条件 44 | boolean flag = true; 45 | for (String condition : rule.p) { 46 | if (!dataBase.contains(condition)) { 47 | flag = false; 48 | break; 49 | } 50 | } 51 | // 满足当前规则所有条件 52 | if (flag) { 53 | // 将当前规则结果加入数据库 54 | if (!dataBase.contains(rule.q)) { 55 | dataBase.add(rule.q); 56 | change = true; 57 | resultDto.process += count + ".使用规则: " 58 | + rule.toString() + ", 推出了: " 59 | + rule.q + "\n"; 60 | resultDto.process += "当前数据库: " 61 | + dataBase + "\n\n"; 62 | } 63 | 64 | // 如果是目标集元素,推理结束 65 | if (aims.contains(rule.q)) { 66 | resultDto.answer = rule.q; 67 | return resultDto; 68 | } 69 | } 70 | } 71 | // 没有新推理可用 72 | if (!change) 73 | break; 74 | } 75 | resultDto.answer = "无法识别具体目标动物"; 76 | return resultDto; 77 | } 78 | ``` 79 | 80 | ## 4. 问题总结 81 | [1. JavaFX开发总结](http://chgl16.space/2019/12/10/java/javafx-chang-yong-zong-jie/) -------------------------------------------------------------------------------- /src/chgl16/space/view/index.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |