1

我在从 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;  
}  

为了节省空间,我没有包含 String、Short、Long、Date、Character 和 Byte 的重载函数。

调用其中一些静态方法的 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  
4

2 回答 2

0

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

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

于 2013-12-18T19:31:59.270 回答
0

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

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

尝试使用例如调用您的重载函数

 (call JessOverLoaded function (new Integer 1)(new Integer 2)(new Integer 3))
于 2013-12-18T06:11:44.673 回答