Обработка вперед 1: n отношений с слюнями - PullRequest
0 голосов
/ 24 мая 2019

Я пытаюсь написать правило, которое применяется к набору фактов, основанных на содержании другого факта. Я упростил задачу до дома с комнатами. Допустим, у нас есть что-то вроде:

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 (или любой другой подход), чтобы сделать то же самое в отношении комнат для данного дома? Имеет ли смысл или мне лучше попытаться реорганизовать свои объекты заранее, чтобы отношения были выражены наоборот?

Спасибо

Ответы [ 2 ]

0 голосов
/ 22 июня 2019

Если в House List<> roomIds указан список Room.id (s), то вы можете сделать что-то вроде:

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 для навигации по структуре.

0 голосов
/ 11 июня 2019

Согласно вашему правилу, у вас нет домов с комнатами.Согласно тому, что вы определили, у вас есть дома в вашей рабочей памяти, и у вас есть комнаты в вашей рабочей памяти, и вы пытаетесь сопоставить их.

Почему у вас нет Списка комнат в вашем доме?Это будет иметь гораздо больше смысла:

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
...