简体   繁体   English

在Java LinkedList上执行Drools insertLogical

[英]Drools insertLogical on Java LinkedList

I have a LinkedList created (instantiated) in Java, which have several nodes (items). 我有一个用Java创建(实例化)的LinkedList,它具有多个节点(项目)。 This list is also used in Drools, and to be exactly, modified by Drools. 该列表在Drools中也使用过,确切地说,由Drools修改过。 I need to insert a new item in the list, but this insertion must be only temporary. 我需要在列表中插入一个新项目,但此插入必须只是临时的。 I do not know when the removal of this item could occur, so I'm obliged to use insertLogical statement (right?). 我不知道什么时候可以删除该项目,所以我不得不使用insertLogical语句(对吗?)。

This is my code, i add three "Nodo" item in the list called "lista". 这是我的代码,我在名为“ lista”的列表中添加了三个“ Nodo”项。 Nodo is the class that follow, which has the constructor and the set/get method: Nodo是后面的类,它具有构造函数和set / get方法:

package com.sample;

public class Nodo {

    private int valore;

    public Nodo(){}

    public Nodo(int valore){
        this.valore=valore;
    }

    public int getValore() {
        return valore;
    }

    public void setValore(int valore) {
        this.valore = valore;
    }

}

this is java Main class instead, which call fireAllRules(): 这是java Main类,它调用fireAllRules():

package com.sample;

/**
* This is a sample class to launch a rule.
*/

import java.util.LinkedList;
import java.util.List;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;


public class DroolsTest {

public static final void main(String[] args) {
    try {
       // load up the knowledge base
       KieServices ks = KieServices.Factory.get();
       KieContainer kContainer = ks.getKieClasspathContainer();
       KieSession kSession = kContainer.newKieSession("ksession-rules");           

       List<Nodo> lista = new LinkedList();
       Nodo n1 = new Nodo(11);
       Nodo n2 = new Nodo(12);
       Nodo n3 = new Nodo(13);

       lista.add(n1);
       lista.add(n2);
       lista.add(n3);

       kSession.insert(lista);
       kSession.fireAllRules();

       for(Nodo nodo : lista){
           System.out.println( nodo.getValore());
       }

       System.out.println( "End");

    } catch (Throwable t) {
        t.printStackTrace();
    }
}
}

The output of Main class is Main class的输出是

11 12 13 50 11 12 13 50

but what i really wanted was only 但是我真正想要的只是

11 12 13 11 12 13

because the "50" value is inserted logically in Drools and then immediately removed. 因为在逻辑上将“ 50”值插入Drools中,然后立即将其删除。 The "hello" message is not printed, because the 50 item isn't in the list anymore. 因为该50项不再在列表中,所以不会打印“ hello”消息。 (correctly, because the list items was removed). (正确,因为列表项已删除)。

The Drools rule file is that which follows: Drools规则文件如下:

rule "Rule 1"
no-loop true
when
    $l : LinkedList(get(0).getValore() == 11)
then
    Nodo a = new Nodo(50);
    $l.add(0,a);
    insertLogical($l);
end


rule "Rule 2"
no-loop true
when
    $l : LinkedList(get(0).getValore() == 50)
then
    modify($l){remove(0)};
end


rule "Rule 3"
when
    $p: Nodo(valore==50)
then
   System.out.println("hello");
end

I tried this way, and I established the list item is correctly retracted from Drools working memory but the item on the list on Java side still continues to exists. 我尝试过这种方法,并且确定列表项已从Drools工作内存中正确撤回,但Java端列表上的项仍继续存在。 I would like to know why the list item remains, how to remove it (without explicitly destroying). 我想知道为什么列表项仍然存在,如何将其删除(不明确销毁)。

Is this a Drools problem with LinkedList or I have not correctly understood insertLogical usage? 这是LinkedList的Drools问题,还是我没有正确理解insertLogical用法?

I also tried to use LinkedList items defined not n the java.util package, but in the drools one "org.drools.core.util.LinkedList" with some error compilation. 我还尝试使用不是在java.util包中定义的LinkedList项目,而是在流口水中使用一个“ org.drools.core.util.LinkedList”进行定义,并进行一些错误编译。

What is the correct solutions ? 什么是正确的解决方案? Thanks 谢谢

There is Java: with objects of all kinds. 有Java:具有各种对象。 They have their methods, and with collections (like LinkedList) you can call methods to change the their composition, adding or removing elements. 它们有其方法,并且可以使用集合(如LinkedList)调用方法以更改其组成,添加或删除元素。

There is Drools: it has a big pool of Facts (Working Memory, WM), each of which is a Java object. 有Drools:它有大量的事实库(工作内存,WM),每个事实库都是Java对象。 Promotion to a Fact is done by an insert operation, and a Fact can be demoted to its nothing-but-POJO existence by a retract: automatically or explicitly. 提升为事实是通过插入操作完成的,事实可以通过撤消(自动或显式)降级为仅存在POJO。

No add to a collection has any effect on the added object being or not being a Fact. 没有添加到集合对添加的对象是否为事实没有任何影响。 Reciprocally, neither insertion into or removal from working memory changes anything in the Java-ish existence of the object. 相应地,无论是插入工作存储器还是从工作存储器中删除,都不会改变对象在Java方面的存在。

Moreover, a list is one object, and its elements are other objects. 此外,列表是一个对象,其元素是其他对象。 Each object is jealously safeguarding its own status as a Fact, and a collection doesn't care two hoots about any of its elements becoming promoted or demoted - and you can bet that a list element couldn't care less about its container being in the WM or not. 每个对象都在嫉妒地维护其本身的事实地位,并且一个集合并不关心它的任何元素被提升或降级的两个陷阱-您可以打赌,列表元素可以毫不在乎它的容器位于WM与否。

Later 后来

Rule 1 is weird: its right hand side destroys the truth of the left hand side, due to the addition of a Nodo(50) at index 0. There is no modify or update on the list object, and therefore the logically inserted fact isn't retracted right away. 规则1很奇怪:由于在索引0处添加了Nodo(50) ,因此其右手边破坏了左手边的真相。列表对象上没有修改或更新,因此逻辑上插入的事实是不会立即缩回。 Even weirder: the RHS inserts the list object that is already in WM. 甚至更奇怪:RHS插入WM中已经存在的列表对象。

Rule 2 is never executed, because the add in Rule 1 is not signalled to the Engine. 规则2永远不会执行,因为规则1中的添加不会发信号给引擎。

Rule 3 is never executed, because the Nodo(50) is never inserted as a Fact anyway. 规则3永远不会执行,因为Nodo(50)永远不会作为事实插入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM