Nested 我如何在口水中做嵌套孔? 问题:

Nested 我如何在口水中做嵌套孔? 问题:,nested,drools,forall,Nested,Drools,Forall,考虑到这些类别: class BookCase { ArrayList<Book> books } class Book { ArrayList<Page> pages } class Page { String color } 类书架{ArrayList books} 类书{ArrayList pages} 类页面{String color} 考虑到这一自然语言规则: 当书架上的所有页面都是黑色时,请执行以下操作: 简单的方法是嵌套forall子句,但在Droo

考虑到这些类别:

class BookCase { ArrayList<Book> books }

class Book { ArrayList<Page> pages }

class Page { String color }
类书架{ArrayList books}
类书{ArrayList pages}
类页面{String color}
考虑到这一自然语言规则:

当书架上的所有页面都是黑色时,请执行以下操作:

简单的方法是嵌套forall子句,但在Drools中不能这样做,因为forall子句只允许模式(而不是条件元素,forall子句是什么)在里面


那么我该如何用口水来表达呢?

当我写这个问题时,我想我自己找到了答案:

BookCase($caseContents : books)
$bookWithOnlyBlackPages : ArrayList<Page>() from $caseContents
forall ( $page : Page(this memberOf $bookWithOnlyBlackPages)
                 Page(this == $page,
                      color == "black") )
forall ( $bookInCase : ArrayList<Page>(this memberOf $caseContents)
                       ArrayList<Page>(this == $bookInCase,
                                       this == $bookWithOnlyBlackPages) )
书架($case目录:书籍)
$caseContents中的$bookWithOnlyBlackPages:ArrayList()
forall($page:page)(此$Book的成员仅包含lackPages)
第页(此==$Page,
颜色==“黑色”))
forall($bookInCase:ArrayList)(此成员为$caseContents)
ArrayList(this==$bookInCase,
此==$bookWithOnlyBlackPages)

当我写这个问题时,我想我自己找到了答案:

BookCase($caseContents : books)
$bookWithOnlyBlackPages : ArrayList<Page>() from $caseContents
forall ( $page : Page(this memberOf $bookWithOnlyBlackPages)
                 Page(this == $page,
                      color == "black") )
forall ( $bookInCase : ArrayList<Page>(this memberOf $caseContents)
                       ArrayList<Page>(this == $bookInCase,
                                       this == $bookWithOnlyBlackPages) )
书架($case目录:书籍)
$caseContents中的$bookWithOnlyBlackPages:ArrayList()
forall($page:page)(此$Book的成员仅包含lackPages)
第页(此==$Page,
颜色==“黑色”))
forall($bookInCase:ArrayList)(此成员为$caseContents)
ArrayList(this==$bookInCase,
此==$bookWithOnlyBlackPages)

这很接近,但并不完全正确:

rule "all black pages"
when
  BookCase( $books: books )
  $book: Book( $pages: pages ) from $books
  not Page( color != "black" ) from $pages
then
  System.out.println( "doing A" );
end
问题是,在所有页面都是黑色的情况下,每本书都会触发一次。要评估所有书籍中的所有页面,可以列出所有页面的列表,并确保它们都是黑色的:

rule "all black pages, take 2"
when
  BookCase( $books: books )
  $pages: ArrayList() from accumulate( Book( $ps: pages ) from $books,
       init( ArrayList list = new ArrayList(); ),
       action( list.addAll( $ps ); ),
       result( list ) )
  not Page( color != "black" ) from $pages
then
  System.out.println( "doing A" );
end

这很接近,但并不完全正确:

rule "all black pages"
when
  BookCase( $books: books )
  $book: Book( $pages: pages ) from $books
  not Page( color != "black" ) from $pages
then
  System.out.println( "doing A" );
end
问题是,在所有页面都是黑色的情况下,每本书都会触发一次。要评估所有书籍中的所有页面,可以列出所有页面的列表,并确保它们都是黑色的:

rule "all black pages, take 2"
when
  BookCase( $books: books )
  $pages: ArrayList() from accumulate( Book( $ps: pages ) from $books,
       init( ArrayList list = new ArrayList(); ),
       action( list.addAll( $ps ); ),
       result( list ) )
  not Page( color != "black" ) from $pages
then
  System.out.println( "doing A" );
end

如果不使用
forall(p1 p2 p3…
,但
not(p1和not(以及p2 p3…)
,实际上可以嵌套多个孔。然后,为了防止个别书籍和页面触发规则,chuck在它们之间存在一个

rule 'all pages in bookcase are black'
    when
        (and
        $bookCase: BookCase()
            (not (exists (and
                $book: Book() from $bookCase.books
                not( (and
                    not( (exists (and
                        $page: Page() from $book.pages
                        not( (and
                            // slightly different constraint than I used in question
                            eval($page.color == $book.color)
                        ) )
                    ) ) )
                ) )
            ) ) )
        )
    then
        ...
end

与使用
累积
创建所有页面的平面列表不同,这将维护
$page
的上下文,也就是说,当一个页面被置于与其父书本的约束中时,如上例所示,在这个解决方案中,Drools仍然“知道”父书本是什么。

如果不使用
forall(p1 p2 p3…
),实际上可以嵌套多个孔,但
不是(p1和not(以及p2 p3…)
。然后,为了防止个别书籍和页面触发规则,chuck在它们之间存在一个

rule 'all pages in bookcase are black'
    when
        (and
        $bookCase: BookCase()
            (not (exists (and
                $book: Book() from $bookCase.books
                not( (and
                    not( (exists (and
                        $page: Page() from $book.pages
                        not( (and
                            // slightly different constraint than I used in question
                            eval($page.color == $book.color)
                        ) )
                    ) ) )
                ) )
            ) ) )
        )
    then
        ...
end

与使用
累积
创建所有页面的平面列表不同,这将维护
$page
的上下文,也就是说,当一个页面被置于与其父书本的约束中时,如上例所示,在此解决方案中,Drools仍然“知道”父图书是什么。

第二种模式将ArrayList作为BookCase.books-:-$caseContent的元素,第四种模式假设book是同一集合的成员,并且等于ArrayList($bookWitOnlyBlackPages)。下定决心我发现书架书页是比嵌套ArrayList更好的选择,所以我用它作为解决方案的平台!那是个错误。我现在编辑了建议的解决方案,将第二个forall语句中的Book对象更改为ArrayList。这个错误的原因是,我最初是用一个Book对象提问的(确实好得多),但我把它改成了ArrayList,因为在现实世界中,我处理的是这样的,我无法改变它。但现在的情况是这样的,这样行吗?顺便说一下,谢谢你所有的Drools答案:)。它仍然不起作用-你甚至不能尝试此代码(因为DRL编译器不接受
)。请注意,这两个孔仍然并行工作,因此即使有一本书只有一个非黑色页面,规则也会反复触发。抱歉,但现在我发出的信号是-1。第二种模式将ArrayList作为BookCase.books-:-$caseContent的元素,第四种模式假设Book是同一集合的成员,并且等于ArrayList($bookWitOnlyBlackPages)。下定决心我发现书架书页是比嵌套ArrayList更好的选择,所以我用它作为解决方案的平台!那是个错误。我现在编辑了建议的解决方案,将第二个forall语句中的Book对象更改为ArrayList。这个错误的原因是,我最初是用一个Book对象提问的(确实好得多),但我把它改成了ArrayList,因为在现实世界中,我处理的是这样的,我无法改变它。但现在的情况是这样的,这样行吗?顺便说一下,谢谢你所有的Drools答案:)。它仍然不起作用-你甚至不能尝试此代码(因为DRL编译器不接受
)。请注意,这两个孔仍然并行工作,因此即使有一本书只有一个非黑色页面,规则也会反复触发。对不起,现在我在发a-1信号。