I have some issues calling overloaded functions from Jess and got unexpected results and sometimes exceptions. The results are not too predictable. They seem to depend on, among other things, how many overloaded functions there are.
Are there reliable ways to ensure the correct functions are called? Any feedback will be greatly appreciated. Please, be patient because this is going to be a bit long.
I have the following 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))
And the Java static methods:
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)
The following calls all end up calling the Long version, function(Long, Long, Long).
I was hoping that, by passing Java objects to Jess, it would select the appropriate method to call.
(functionInteger (FunctionsObjectCreator.createInteger)(FunctionsObjectCreator.createInteger) (FunctionsObjectCreator.createInteger))
(functionShort (FunctionsObjectCreator.createShort)
(FunctionsObjectCreator.createShort) (FunctionsObjectCreator.createShort))
(functionLong (FunctionsObjectCreator.createLong) (FunctionsObjectCreator.createLong) (FunctionsObjectCreator.createLong))
where FunctionsObjectCreator.createXYZ() create Integer, Short and Long objects.
Here is another overloaded sample with Integer as the primary class:
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;
}
To save space, I do not include the overloaded functions with String, Short, Long, Date, Character and Byte.
The clp to invoke some of these static methods:
(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))
The above invocations either fail to call the correct static methods or receive an exception. One such exception is:
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
I cannot reproduce the problem using a simplified version with just one argument of each of the numeric classes.
However, I'm somewhat suspicious of the FunctionsObjectCreator.createInteger you have not shown. Did you make sure (using (java-objectp)) that the results of these methods are indeed Java objects?
Try a call to your overloaded function using e.g.