JESS vs DROOLS: обратная цепочка

Я пытаюсь заменить Джесс на Drools в качестве движка правил обратной цепочки в нашем проекте. Я искал простые примеры того, как обратное связывание выполняется с Drools. Интересно, что на каждом сайте есть только 1 такой же пример (который я не понимаю, как это до н.э., но давайте пока забудем об этом).

Очень тривиальный пример БК в Джесс:

//q is a fact template with a slot named 'n'
//when there's a q with n==8 print something
//I need a q with n==8 to fire a rule so I will insert it myself!

(deftemplate q (slot n))
(do-backward-chaining q)
(defrule printq (q (n 8))   =>  (printout t "n is eight! yeah!" crlf))
(defrule iNeedn8 (need-q (n 8)) => (assert (q (n 8))))
(reset)
(run 1)
//fires printq and prints to console...

Эквивалент в Drools:

package com.example;

declare Q
    n : int
end

rule "print q"
when
    Q(n == 8)
then
    System.out.println("n is eight by drools!");
end

//I'M LOST HERE! HELP!

Как я могу добиться того же поведения с Drools?

2 ответа

В Drools общая идея BC - использовать запросы. В дополнение к вашему правилу "print q" вам нужно:

query noQ( int $num )
    Goal(num==$num) and not Q(num == $num)
end

rule goal when
    Goal( $n: num )
    noQ($n;)
then
    Q q = new Q($n);
    insert( q );
end

rule go when
then
    insert( new Goal( 8 ) );
end

Нет никакого способа поручить Друлам обнаружить пропущенный факт сам по себе; Вы должны предоставить цель и запросы, чтобы "преодолеть разрыв".

Вдохновленный особенностью Jess, есть экспериментальная, находящаяся в разработке функция, которая дает вам похожее поведение. Вот как будет выглядеть тест:

@Test
public void testFindQ8() {
    String droolsSource =
        " package org.drools.abductive.test;                 " +
        "                                                    " +
        " import " + Abducible.class.getName() + ";          " +
        " global java.util.List list;                     \n " +
        "                                                    " +
        " declare Q                                          " +
        "    @Abducible                                      " +
        "    id : int @key                                   " +
        " end                                             \n " +
        "                                                    " +
        " query foo( int $x )                                " +
        "    @Abductive( target=Q.class )                    " +
        "    not Q( $x; )                                    " +
        " end                                             \n " +
        "                                                    " +
        " rule R1                                            " +
        " when                                               " +
        "    $x := foo( 8 ; )                                " +
        " then                                               " +
        "    System.out.println( 'R1 returned ' + $x );      " +
        " end                                             \n " +
        "                                                    " +
        " rule R2                                            " +
        " when                                               " +
        "    $q : Q( 8; )                                    " +
        " then                                               " +
        "    System.out.println( 'We have 8!' );             " +
        " end                                                ";
    /////////////////////////////////////

    KieHelper kieHelper = new KieHelper();
    kieHelper.addContent( droolsSource, ResourceType.DRL ).build().newKieSession().fireAllRules();


}
Другие вопросы по тегам