我对Drools很新,但想把它用于我需要解决的案例。
基本上我的规则需要执行以下操作:
所以,我想链接几个规则...首先要这样做,创建包含结果的新列表,在下一个规则中使用新列表,对其执行进一步过滤,创建具有更多过滤元素的新列表......等等在......
老实说,如前所述,我完全被困住了,以为我可以得到一些adivsory ......
我想出的最初规则是这样的:
package com.acme.rulesets
import com.acme.domain.TopLocation
import com.acme.domain.Person
import com.acme.storage.LocationContainer
import com.acme.helper.GeoHelpers
rule "Get by Distance"
salience 10
when
$allLocations: LocationContainer()
$person: Person()
$loc: TopLocation() from $allLocations.getAllLocations()
then
double distance = GeoHelpers.getInstance().getHaversineInMiles($person.getLat(), $person.getLon(), $loc.getLat(), $loc.getLon());
System.out.println($loc.getTitle() + " -- distance in miles to person: " + distance);
end;
它没有 - 到目前为止 - 我想要实现的目标......但也许你可以给出一些提示......
所以,首先我认为我需要在规则的LHS中调用我的静态java方法(它只计算两个给定点之间的距离),但是一旦我(尝试)这样做,它就会编译规则失败。然后我需要使用$ dist的结果来确定,如果当前条目需要放入新列表(我怎么能a。)创建一个新列表,然后b。)将当前条目放入其中?)..然后,下一个逻辑步骤是创建一个具有更高显着性的新规则“按位置标题获取”并使用新的过滤列表。所以最后,当我回到java端时,我可以从工作记忆中获取所有列表,并用它们做更多的事情。
是的,我知道,我的问题可能非常糟糕......但我找不到任何可以从中得出用例的内容。
但是,提前谢谢。
答案 0 :(得分:1)
我将逐点解决这个问题,而不是尝试提供“完整”的解决方案。你必须决定使用什么。
首先,可能有充分的理由将容器类中的所有位置保留为单一事实,但通常,如果容器元素本身是事实,则规则更容易编写。
rule "person and location"
when
$p: Person()
$l: TopLocation(...)
...
(当然,你可以坚持from
条款。)
要选择具有特定属性的位置以及Person:使用任何布尔表达式作为约束或eval模式。如果表达式涉及一些静态Java函数,则将其导入(就像在Java中一样)或将其实现为DRL函数。我将把它说明为三者的组合。
import com.acme.helper.GeoHelpers
function double dist( Person p, TopLocation t ){
double d =
GeoHelpers.getInstance().getHaversineInMiles(p.getLat(), p.getLon(),
t.getLat(), t.getLon());
}
rule "p & l closer than"
when
$p: Person()
$l: TopLocation( dist($p,$l) < 100.0 )
...
要按更多条件过滤地点,您可以使用附加规则,其中选择了符合所需“标题”的位置,但这需要跟踪按距离选择的位置。要做到这一点,只需在规则中添加“标题”约束:
rule "p & l: Hotel closer than 100"
when
$p: Person()
$l: TopLocation( dist($p,$l) < 100.0,
title == "Hotel" )
...
等等。
你会说这个规则仅适用于单个选择用例 - 如果距离不同或者你正在寻找书店怎么办?
您可以使用参数块事实来定义文字。
rule "p & l, X loc closer than D"
when
Param( $d: distance, $t: title )
$p: Person()
$l: TopLocation( dist($p,$l) < $d, title == $t )
...
你可能会说这很好但是如果选择标准本身的组合变化,而不仅仅是值?然后,当然,拥有单独的规则可能确实更好,每个规则都按单个标准选择位置。有了这个,提供参数可以与选择适当的规则相结合,这可以由多个Param子类完成。还会出现另一个问题:如何跟踪选择集。为此,我们可能必须使用另一个辅助事实,我们称之为ResultSet
。假设距离始终是一个标准,我们可以编写诸如
rule "p & l, closer than D"
when
$dp: DistParam( $v: distance )
$p: Person()
$l: ArrayList() from
collect( $l: TopLocation( dist($p,$l) < $v )
then
retract( $dp );
insert( new ResultSet( $l ) );
end
rule "p & l, filter by title"
when
$t: TitleParam( $v: title )
$r: ResultSet( $s: result )
$l: ArrayList() from
collect( $l: TopLocation( title == $v ) from $s
then
retract( $t );
modify( $r ){ setResult($l) }
end
现在很容易有一个任意选择的标准,其值来自当前搜索。 - 您可以在ResultSet
返回后使用API检索fireAllRules
,或者编写其他规则来处理和撤消。
我建议您研究现有文献。