2013-12-16 3 views
1

У меня есть некоторые проблемы, вызывающие перегруженные функции от Jess и получившие неожиданные результаты, а иногда и исключения. Результаты не слишком предсказуемы. Кажется, что они зависят, среди прочего, от количества перегруженных функций.Jess и вызов перегруженных статических методов Java

Существуют ли надежные способы обеспечения правильности функций? Любая обратная связь будет принята с благодарностью. Пожалуйста, будьте терпеливы, потому что это будет немного долго.

У меня есть следующие:

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) 

следующие вызовы все в конечном итоге вызова Длинная версия, 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, короткие и длинные предметы.

Вот еще перегружен образец с 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; 
} 

Для экономии места я не включаю перегруженные функции с Струнным, коротким, длинным, датой, характером и Byte.

ПСЯ вызвать некоторые из этих статических методов:

(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 
+0

Вы понимаете, что переменные Джесса не печатаются? И это перегрузочное разрешение - это что-то для компилятора Java, и на самом деле не ожидается, что он будет выполняться во время работы подключением Джесса к Java, где он просто повредит производительность. - Есть ли оправдание для этого расширенного использования перегрузки? – laune

ответ

0

Я не могу воспроизвести проблему, используя упрощенную версию только с одним аргументом каждого из числовых классов.

Однако я несколько подозрительно отношусь к функции ObjectsObjectCreator.createInteger, которую вы не указали. Вы убедились (используя (java-objectp)), что результаты этих методов действительно являются объектами Java?

Попробуйте выполнить вызов перегруженной функции, используя, например,

(call JessOverLoaded function (new Integer 1)(new Integer 2)(new Integer 3)) 
+0

К сожалению, мне приходится иметь дело с объектами Java, которые возвращают байты, короткие, целые, длинные, плавающие, двойные и т. Д. И их массивы [] и [] []. У Джес есть внутренние представления, и он должен догадываться, чтобы найти правильные перегруженные методы. Как вы уже упоминали, вам нужно создать экземпляр Integer прямо из Jess, чтобы получить экземпляры Integer. В противном случае большинство, если не все классы Java, которые переносят простые типы Java, если они передаются из Java, будут представлены собственными представлениями Джесса. – user3108924

+0

Ну, вот вы ... Вы можете убедиться, что разрешение перегрузки выбирает правильный метод. Это то, о чем вы просили. – laune

0

Честно говоря, если вам придется иметь дело с такого рода вещи, самый простой способ сделать это было бы написать класс Java, чтобы служить в качестве адаптера; класс Java может переименовывать перегрузки, чтобы устранить их, и поэтому вы можете избежать всей проблемы. Разрешение перегрузки Джесса может упасть в сложных ситуациях, и это вряд ли когда-либо будет полностью исправлено. Вы обнаружите, что другие динамические языки имеют схожие проблемы (хотя, по общему признанию, некоторые из них лучше, чем Джесс в этом отношении.)

Это немного лучше в Jess 8, которая в настоящее время находится в раннем выпуске, но она все еще не идеальна.

Смежные вопросы