我正在尝试根据另一事实的内容编写适用于一组事实的规则。我已将问题简化为带房间的房子。假设我们有类似的东西:
House(id);
Room(id, houseId, floor, side, paint);
现在,如果我想在所有房间的左侧都以绿色绘制的所有房屋上触发规则,我会写:
rule "Left side 1st floor green"
when
$h: House()
forall($r: Room(houseId=$h.id, floor==1, side=="left")
Room(id == $r.id, paint == "green"))
then
//Do whatever on rule triggering
end
但是,如果工作存储器中的对象是以这种方式组织的,那该怎么办?
House(id, List<> roomIds);
Room(id, floor, side, paint);
如何为给定房屋的房间写一个foreach条件(或任何其他方法)以进行相同考虑?是有意义的,还是我应该更好地尝试重新组织对象,使关系以另一种方式表达出来?
谢谢
答案 0 :(得分:0)
根据您的规则,您没有带房间的房屋。根据您的定义,在工作记忆中有房屋,在工作记忆中有房间,然后尝试匹配这些房屋。
为什么您的房屋中没有房间清单?那会更有意义:
House(houseId, List<Room> rooms)
Room(roomId, floor, side, paint)
那么您的规则将是:
rule "Left side 1st floor green"
when
$houses : House ($rooms : rooms, $houseId : houseId)
$room : Room ($roomId : roomId, floor==1 && side=="left" && paint == "green") from $rooms
then
//Rule would trigger for each room left side 1st floor green rooms
System.out.println("House "+$houseId+" has following left side 1st floor green room: "+$roomId);
end
答案 1 :(得分:0)
假设House
中的List<> roomIds
是Room.id
的列表,那么您可以执行以下操作:
rule "Left side 1st floor green"
when
$h: House(/* .. conditions for specific house? .. */)
$r : Room($h.roomIds contains id, floor==1, side=="left", paint == "green")
then
//Do whatever on rule triggering
end
但是这有点效率不高,我也同意其他人的回答,更改业务/数据模型会使编写这种规则更加习惯和更有效率。例如,如果“房屋”确实具有“房间”列表,则还可以使用OOPath来按需导航结构。