Почему ключевое слово from повторяется в обратном направлении? - PullRequest
2 голосов
/ 20 января 2011

У меня есть ArrayList в рабочей памяти, который я повторяю с оператором 'from' в моем предложении when.Тем не менее, правило повторяется в обратном направлении по массиву.Есть ли способ контролировать это поведение?

Создание списка:

List<Map<String,String>> list = new ArrayList<Map<String,String>>();
Map<String,String> m1 = ...
Map<String,String> m2 = ...
list.add(m1);
list.add(m2);
ImportItem item = new ImportItem(list);  //model object. Constructor arg returned by getInput()
StatelessKnowledgeSession session = knowledgeBase.newStatelessKnowledgeSession();
session.insert(item);
session.fireAllRules();

Правила слюни:

rule "My Rule"
dialect "java"
when
    item : ImportItem(ignore == false)  //model object that holds the input
    map  : Map() from item.getInput()  // == the ArrayList from above
then
    System.out.println(map);
end

Производит

<output of m2>
<output of m1>

Ответы [ 2 ]

3 голосов
/ 28 января 2011

Итерация не обратная, как вы можете видеть, если вы присоединяете журнал аудита к вашему сеансу. Выполнение правил - это то, что следует по умолчанию порядку LIFO (в случае, если вы не используете какую-либо другую стратегию разрешения конфликтов).

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

Например:

rule "Process lines in order"
   // salience executes from higher number to lowest number, so using the 
   // negative value you will executem them from the first to the last
   salience (- $lineNumber )
when
   $line : Line( $lineNumber : lineNumber )
then
   // do something with $line
end

Очевидно, что тот же трюк можно использовать с выбранным вами подходом "из", но механизм гораздо более эффективно сопоставляет факты в рабочей памяти, чем перебирает коллекции объектов.

Надеюсь, это поможет. Эдсон

0 голосов
/ 21 января 2011

Вы всегда должны пытаться написать правила, чтобы порядок не учитывался. Однако, если вам действительно нужно иметь правила выполнения в определенном порядке, или в этом случае получите факты из списка в определенном порядке. Убедитесь, что любые изменения во внутренних механизмах правил не нарушают ваши правила при обновлении до более новой версии механизма.

Вы не можете доверять «от», даже если он выполнял итерацию наоборот.

Существует одна проблема с этим решением. Если вы обновите ImportItem и вам нужно будет повторить ввод, вам нужно убрать связанный с ним MyIterator.

declare MyIterator
    index:int
    lastIndex:int
    importItem:ImportItem
end 

rule "Insert ImportItem iterator"
    when
        item : ImportItem()
        not MyIterator( importItem == item )
    then
        MyIterator myIterator = new MyIterator();
        myIterator.setImportItem( item );
        myIterator.setIndex( 0 );
        myIterator.setLastIndex( item.getInput().size() ); 
        insert( myIterator );
end

rule "My Rule"
    when
        myIterator :MyIterator( index < lastIndex )
        item : ImportItem(  this == myIterator.importItem, 
                            ignore == false )
        map  : Map() from item.getInput().get( myIterator.getIndex() )  
    then
        System.out.println(map);

        myIterator.setIndex( myIterator.getIndex() + 1 );
        update( myIterator );
end
...