Jess学习基础(二)

项目要开发一个专家系统,以Jess进行推理决策,以Java作为外层框架进行开发。因为专家系统方向的资料比较少,目前仍然在摸索中。把已经掌握的知识写出了,给个参考。
好在Jess官方提供了一个java+jess的example,虽然没有说明,慢慢摸索理解了一下, 在此与大家分享。

之前的博客中已经给出了Jess作为插件在Eclipse中的安装过程,在此可以直接使用。


一、工程搭建



1、新建一个Dynamic web project;
2、增加jess.jar包,并bulid path;
3、 在该工程中新建一个*.clp文件。(新建文件,手动增加后缀为.clp即可)

如图:
这里写图片描述

得到的目录如下图:

这里写图片描述

二、源码分析


下面我们来看项目的源码。

这是一个价格计算的项目,根据消费者购买的商品的数量、价格等进行打折或者提供赠品。

model包中提供了商品目录CatalogItem.java、消费者消费次数Customer.java、消费者订单Order.java及商家提供的优惠活动Offer.java。

demo包中的demo.java是主程序入口,DemoDatabase.java提供数据接口的实现。

diagnosis包中Database.java提供数据接口,PricingEngine.java实现价格计算引擎。正是PricingEngine.java实现了pricing.clp与Java程序连接。

下面是PricingEngine.java中的源码部分。

public class PricingEngine {
    private Rete engine;
    private WorkingMemoryMarker marker;
    private Database database;

    public PricingEngine(Database aDatabase) throws JessException {
        // Create a Jess rule engine
        engine = new Rete();//创建Jess规则引擎
        engine.reset();

        // Load the pricing rules
        engine.batch("pricing.clp");//加载价格规则

        // Load the catalog data into working memory
        database = aDatabase;
        engine.addAll(database.getCatalogItems());//加载目录数据到工作存储区

        // Mark end of catalog data for later
        marker = engine.mark();//标记目录数据
    }

    private void loadOrderData(int orderNumber) throws JessException {
        // Retrive the order from the database
        Order order = database.getOrder(orderNumber);//从数据库获取订单

        if (order != null) {
            // Add the order and its contents to working memory,增加订单及订单目录到工作存储区
            engine.add(order);
            engine.add(order.getCustomer());
            engine.addAll(order.getItems());
        }
    }

    public Iterator run(int orderNumber) throws JessException {
        // Remove any previous order data, leaving only catalog data
        engine.resetToMark(marker);//重置规则引擎

        // Load data for this order
        loadOrderData(orderNumber);//加载数据

        // Fire the rules that apply to this order 
        engine.run();//启动规则引擎

        // Return the list of offers created by the rules
        return engine.getObjects(new Filter.ByClass(Offer.class));
    }
}

将数据库中的内容增加到规则库的存储区中,通过PricingEngine规则引擎来加载规则库

那么,Java如何带动这个规则引擎呢?
下面给出Demo中的main函数,可以看到,通过新建规则库,可以很容易地将规则引擎加入到Java中。

public static void main(String[] args) {
        try {
            DemoDatabase database = new DemoDatabase();//新建数据库
            PricingEngine engine = new PricingEngine(database);//新建规则引擎

            processOrder(database, engine, 123);//处理订单
            processOrder(database, engine, 567);
            processOrder(database, engine, 666);

        } catch (JessException e) {
            e.printStackTrace();
        }

    }

那么,将Jess的规则处理加入到了Java中,它是如何处理数据的呢

下面是pricing.clp 中的内容

(import model.*)
(deftemplate Order       (declare (from-class Order)))
(deftemplate OrderItem   (declare (from-class OrderItem)))
(deftemplate CatalogItem (declare (from-class CatalogItem)))
(deftemplate Customer    (declare (from-class Customer)))

(defrule 10%-volume-discount
    "Give a 10% discount to everybody who spends more than $100."
    ?o <- (Order {total > 100})
    =>
    (add (new Offer "10% volume discount" (/ ?o.total 10))))

可以看到(import model.*) 同Java中的import是一致的。
(declare (from-class Order))这一部分正是从Java的类中获得的。这样Jess就可以使用Java中的对象了。

(defrule 10%-volume-discount
    "Give a 10% discount to everybody who spends more than $100."
    ?o <- (Order {total > 100})
    =>
    (add (new Offer "10% volume discount" (/ ?o.total 10))))

这一部分的功能是对所有的订单消费超过100$的消费者打九折的优惠。
在Order中的{total}是方法名去掉get,并且将首字母变为小写(如果紧挨着的第二个字母也是大写,则不会变为小写,编写代码时会有智能提示),而不是Java类中的变量名。

程序的运行结果如下

这里写图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值