Jess和重载Java静态方法的调用

时间:2013-12-16 22:28:55

标签: methods static call jess

我有一些问题从Jess调用重载函数并获得意外结果,有时会出现异常。结果不太可预测。除了其他方面,它们似乎依赖于有多少重载函数。

是否有可靠的方法来确保调用正确的函数?任何反馈将不胜感激。请耐心等待,因为这会有点长。

我有以下clp:

(deffunction functionShort (?a1 ?a2 ?a3) (JessOverLoaded.function ?a1 ?a2 ?a3))  
(deffunction functionInteger (?a1 ?a2 ?a3) (JessOverLoaded.function ?a1 ?a2 ?a3))  
(deffunction functionLong (?a1 ?a2 ?a3) (JessOverLoaded.function ?a1 ?a2 ?a3))  

Java静态方法:

public static boolean function(Integer arg1, Integer arg2, Integer arg3)  
public static boolean function(Short arg1, Short arg2, Short arg3)  
public static boolean function(Long arg1, Long arg2, Long arg3)   
public static boolean function(Double arg1, Double arg2, Double arg3)  
public static boolean function(Float arg1, Float arg2, Float arg3)  

以下调用最终都会调用Long版本function(Long, Long, Long)。 我希望通过将Java对象传递给Jess,它会选择适当的方法来调用。

(functionInteger (FunctionsObjectCreator.createInteger)(FunctionsObjectCreator.createInteger) (FunctionsObjectCreator.createInteger))  
(functionShort (FunctionsObjectCreator.createShort)
(FunctionsObjectCreator.createShort) (FunctionsObjectCreator.createShort))  
(functionLong (FunctionsObjectCreator.createLong) (FunctionsObjectCreator.createLong)  (FunctionsObjectCreator.createLong))  

其中FunctionsObjectCreator.createXYZ()创建Integer,Short和Long对象。

这是另一个以Integer作为主要类的重载示例:

public static boolean inRange(Integer $impliedParameter, Integer lowerBound, Integer upperBound) {  
    System.out.println("inRange Integer 1");  
    return false;  
}  
public static boolean inRange(Integer $impliedParameter, Integer lowerBound, Integer upperBound, Integer[] exclusions) {  
    System.out.println("inRange Integer 2");  
    return false;  
}  
public static boolean inRange(Integer $impliedParameter, Integer[][] listOfRanges, Integer[] exclusions) {  
    System.out.println("inRange Integer 3");  
    return false;  
}  
public static boolean inRange(Integer $impliedParameter, Integer[][] listOfRanges, boolean inclusiveLower, boolean inclusiveUpper, Integer[] exclusions) {  
    System.out.println("inRangeInteger 4");  
    return false;  
}  

为了节省空间,我没有包含字符串,短,长,日期,字符和字节的重载函数。

clp调用其中一些静态方法:

(deffunction  functionShort1 (?a1 ?a2 ?a3)  
(JessOverLoaded.inRange ?a1 ?a2 ?a3))  

(deffunction  functionInteger1 (?a1 ?a2 ?a3)  
(JessOverLoaded.inRange ?a1 ?a2 ?a3))  

(deffunction  functionLong1 (?a1 ?a2 ?a3)  
(JessOverLoaded.inRange ?a1 ?a2 ?a3))  

(functionInteger1 (FunctionsObjectCreator.createInteger)  (FunctionsObjectCreator.createInteger) (FunctionsObjectCreator.createInteger))  
(functionShort1 (FunctionsObjectCreator.createShort) (FunctionsObjectCreator.createShort)  (FunctionsObjectCreator.createShort))  
(functionLong1 (FunctionsObjectCreator.createLong) (FunctionsObjectCreator.createLong)  (FunctionsObjectCreator.createLong))  

上述调用无法调用正确的静态方法或接收异常。一个例外是:

Jess reported an error in routine JessOverLoaded.inRange  
    while executing (JessOverLoaded.inRange ?a1 ?a2 ?a3)  
    while executing deffunction functionInteger1  
    while executing (functionInteger1 (FunctionsObjectCreator.createInteger)   (FunctionsObjectCreator.createInteger) (FunctionsObjectCreator.createInteger)).
  Message: Error during execution.  
  Program text: ( functionInteger1 ( FunctionsObjectCreator.createInteger ) (   FunctionsObjectCreator.createInteger ) ( FunctionsObjectCreator.createInteger ) )  at line  28 in file src/com/softwareag/rules/functions/JessOverloaded.clp.  
    at jess.Funcall.execute(Funcall.java:346)  
    at jess.FuncallValue.resolveValue(FuncallValue.java:29)  
    at jess.Deffunction.call(Deffunction.java:214)  
    at jess.FunctionHolder.call(FunctionHolder.java:35)  
    at jess.Funcall.execute(Funcall.java:338)  
    at jess.Jesp.parseAndExecuteFuncall(Jesp.java:2309)  
    at jess.Jesp.parseExpression(Jesp.java:459)  
    at jess.Jesp.promptAndParseOneExpression(Jesp.java:309)  
    at jess.Jesp.parse(Jesp.java:288)  
    at jess.Batch.batch(Batch.java:132)  
    at jess.Batch.batch(Batch.java:113)  
    at jess.Batch.batch(Batch.java:75)  
    at jess.Batch.batch(Batch.java:40)  
    at jess.Rete.batch(Rete.java:2791)  
    at com.softwareag.rules.functions.parser.JessFunctions.main(JessFunctions.java:18)  
Caused by: java.lang.IllegalArgumentException: Can't convert '64' to required type   [[Ljava.lang.Double;  
    at jess.RU.valueToObject(RU.java:385)  
    at jess.RU.valueToObject(RU.java:289)  
    at jess.SerializableMD.invoke(SerializableMD.java:62)  
    at jess.MethodFunction.call(StaticMemberImporter.java:102)  
    at jess.FunctionHolder.call(FunctionHolder.java:35)  
    at jess.Funcall.execute(Funcall.java:338)  
    ... 14 more  

2 个答案:

答案 0 :(得分:0)

我无法使用每个数字类只有一个参数的简化版本来重现问题。

但是,我有点怀疑你没有显示的FunctionsObjectCreator.createInteger。您是否确定(使用(java-objectp))这些方法的结果确实是Java对象?

尝试使用例如

调用重载函数
 (call JessOverLoaded function (new Integer 1)(new Integer 2)(new Integer 3))

答案 1 :(得分:0)

老实说,如果你需要处理这类事情,最简单的方法就是编写一个Java类作为适配器; Java类可以重命名重载以消除它们的歧义,因此您可以避免整个问题。 Jess的重载分辨率可能会在复杂情况下崩溃,而且这种情况不太可能完全修复。您会发现其他动态语言也存在类似的问题(尽管在这方面肯定会有一些比Jess更好。)

在Jess 8中有点好,目前处于早期发布阶段,但它仍然不完美。