Um exemplo de encadeamento reverso em babas

Um exemplo de encadeamento reverso em babas

1. Visão geral

Neste artigo, veremos como é o Backward Chaining e como podemos usá-lo com o Drools.

Este artigo é parte de uma série que mostra osDrools Business Rules Engine.

2. Dependências do Maven

Vamos começar importando o drools-coredependency:


    org.drools
    drools-core
    7.4.1.Final

3. Encadeamento

Antes de tudo, com o encadeamento para a frente, começamos analisando os dados e caminhando para uma conclusão específica.

Um exemplo de aplicação de encadeamento direto seria um sistema que descobre novas rotas inspecionando conexões já conhecidas entre os nós.

4. Encadeamento inverso

Em oposição ao encadeamento direto,backward chaining starts directly with the conclusion (hypothesis) and validates it by backtracking through a sequence of facts.

Ao comparar o encadeamento direto e o encadeamento reverso,the first one can be described as “data-driven” (data as input), while the latter one can be described as “event(or goal)-driven” (goals as inputs).

Um exemplo de aplicação de encadeamento reverso seria validar se há uma rota conectando dois nós.

5. Drools Backward Chaining

O projeto Drools foi criado principalmente como um sistema de encadeamento direto. Mas, começando na versão 5.2.0, ele também suporta encadeamento reverso.

Vamos criar um aplicativo simples e tentar validar uma hipótese simples -if the Great Wall of China is on Planet Earth.

5.1. Os dados

Vamos criar uma base de fatos simples que descreve as coisas e sua localização:

  1. Planeta Terra

  2. Ásia, planeta terra

  3. China, Asia

  4. Grande Muralha da China, China

5.2. Definindo regras

Agora, vamos criar um arquivo “.drl” chamadoBackwardChaining.drl que colocaremos em/resources/com/example/drools/rules/. Isso conterá todas as consultas e regras necessárias para serem usadas no exemplo.

A consulta principalbelongsTo, que utilizará encadeamento reverso, pode ser escrita como:

query belongsTo(String x, String y)
    Fact(x, y;)
    or
    (Fact(z, y;) and belongsTo(x, z;))
end

Além disso, vamos adicionar duas regras que tornarão possível revisar nossos resultados facilmente:

rule "Great Wall of China BELONGS TO Planet Earth"
when
    belongsTo("Great Wall of China", "Planet Earth";)
then
    result.setValue("Decision one taken: Great Wall of China BELONGS TO Planet Earth");
end

rule "print all facts"
when
    belongsTo(element, place;)
then
    result.addFact(element + " IS ELEMENT OF " + place);
end

5.3. Criando o aplicativo

Agora, precisaremos de uma classe Java para representar fatos:

public class Fact {

    @Position(0)
    private String element;

    @Position(1)
    private String place;

    // getters, setters, constructors, and other methods ...
}

Aqui, usamos a anotação@Position para informar ao aplicativo em que ordem o Drools fornecerá valores para esses atributos.

Além disso, criaremos o POJO que representa os resultados:

public class Result {
    private String value;
    private List facts = new ArrayList<>();

    //... getters, setters, constructors, and other methods
}

E agora, podemos executar o exemplo:

public class BackwardChainingTest {

    @Before
    public void before() {
        result = new Result();
        ksession = new DroolsBeanFactory().getKieSession();
    }

    @Test
    public void whenWallOfChinaIsGiven_ThenItBelongsToPlanetEarth() {

        ksession.setGlobal("result", result);
        ksession.insert(new Fact("Asia", "Planet Earth"));
        ksession.insert(new Fact("China", "Asia"));
        ksession.insert(new Fact("Great Wall of China", "China"));

        ksession.fireAllRules();

        assertEquals(
          result.getValue(),
          "Decision one taken: Great Wall of China BELONGS TO Planet Earth");
    }
}

Quando os casos de teste são executados, eles adicionam os fatos dados (“Asia belongs to Planet Earth“, “Chinabelongs to Ásia”, “Grande Muralha da China pertence à China”).

Depois disso, os fatos são processados ​​com as regras descritas emBackwardChaining.drl, que fornece uma consulta recursivabelongsTo(String x, String y).

Esta consulta é invocada pelas regras que usam encadeamento reverso para descobrir se a hipótese (“Great Wall of China BELONGS TO Planet Earth”), é verdadeira ou falsa.

6. Conclusão

Mostramos uma visão geral do Backward Chaining, um recurso do Drools usado para recuperar uma lista de fatos para validar se uma decisão é verdadeira.

Como sempre, o exemplo completo pode ser encontrado em nossoGitHub repository.