我如何在下面的流口水规则中传递参数来设置age(18岁应该是动态的)的比较值

package com.rule.models

import com.rule.models.User

rule "AgeCheck"
when
    $user: User( age < 18 )
then
    System.out.println("Warning, "+$user.getName()+" is below age!");
end

最佳答案

出于一点乐趣,我想我会举一个DRL示例,演示如何通过插入AgeLimit事实来完成此操作。

declare AgeLimit
    country: String
    age: int
end
declare Bar
    country: String
    revellers: java.util.Collection
end
declare Person
    age: int
end
declare ThrowOutOfTheBar
    person: Person
    bar: Bar
end

rule "UK drinking age" salience 1000 when then
    insertLogical( new AgeLimit( 'uk', 18 ) );
end
rule "US drinking age" salience 1000 when then
    insertLogical( new AgeLimit( 'us', 21 ) );
end

rule "Can I buy a beer?" when
    $p: Person()
    $bar: Bar( revellers contains $p )
    AgeLimit( country == $bar.country, age > $p.age )
then
    insertLogical( new ThrowOutOfTheBar($p, $bar) );
end

为了进一步减少手动DRL的数量,您可以使用API​​插入那些AgeLimit事实。例如,您可以维护一个国家年龄限制的数据库表,并且在 session 开始时,您可以将它们全部插入工作内存中。或者,您可以创建一个决策表,该决策表在幕后生成那些相同的年龄限制插入规则。例如,如果您希望为每个国家/地区设置年龄限制,这可能是一种管理事物的好方法。

进一步将硬编码的值排除在关键规则之外,值得阅读inference and truth maintenance。这可能会导致如下规则:
rule "Can I buy a beer?" when
    $p: Person()
    $bar: Bar( revellers contains $p )
    IsUnderAge( person == $p, country == $bar.country )
then
    insertLogical( new ThrowOutOfTheBar($p, $bar) );
end

这样做的好处是可以将规则封装在年龄限制周围,并提供一些重用潜力。但是,在上面的示例中要实现此目标,需要为每个年龄以下的国家/地区的每个人插入IsUnderAge事实。弄清楚这是否是件好事,使我陷入了各种偏离主题的思考,因此我将其遗漏了。 :)

10-02 06:44