Jess内部的数据类型在具体应用的时候常给人以模糊的感觉,比如,

(deftemplate (Item (slot value (type STRING))))
(bind ?item (assert (Item)))
(modify ?item (value "HelloWorld"))
(modify ?item ("value" HelloWorld))

打开watch all后可以看到,

<=> f-1 (MAIN::Item (value "HelloWorld"))
<=> f-1 (MAIN::Item (value HelloWorld))

两个modify操作都是合法的,但是修改的值却是不同的,可以简单验证,

(printout t (eq "HelloWorld" HelloWorld) crlf)

控制台输出FALSE。在一些条件下加上引号的字符串和无引号的字符串可以混用,如上述代码中用于指明modify操作中slot名字的value/”value”,但作为值来进行比较的时候,两者却又是不同的。

差别在哪呢?想想很有可能是类型的问题,引号存在与否可能就是Jess中STRING和SYMBOL的差别。

实现一个Userfunction用于进行类型转化,

public class ObjectTypeCast implements Userfunction {
    public String getName() {
        return "object-type-cast";
    }
    public Value call(ValueVector vv, Context context) throws JessException {
        if (vv.size() != 3) {
            throw new JessException(getName(), "Not enough parameters.", JessException.GENERAL_ERROR);            
        }
        String value = vv.get(1).stringValue(context);
        int type = vv.get(2).intValue(context);
        return new Value(value, type);
    }
}

在Jess中调用如下,

(printout t (eq "HelloWorld" (object-type-cast "HelloWorld" (get-member RU STRING))) crlf)
(printout t (eq "HelloWorld" (object-type-cast "HelloWorld" (get-member RU SYMBOL))) crlf)
(printout t (eq HelloWorld (object-type-cast "HelloWorld" (get-member RU SYMBOL))) crlf)
(printout t (eq HelloWorld (object-type-cast "HelloWorld" (get-member RU STRING))) crlf)

输出TRUE, FALSE, TRUE, FALSE,数据类型果然是这问题的原因所在。