1

Assume I have a Policy object in Drools, that object contains a List of Cover objects, called covers and a List of String objects, which are called requestedCovers.

The Cover object contains type field, which is a String object.

I want to fire a rule if a requestedCover does not match a type in the Covers list.

rule "Add validation error for policies with requested covers that are not available"
when
    $p: Policy(available == true, $requestedCovers: requestedCovers, $covers: covers)
    $requestedCover: String() from $requestedCovers
    Cover(type not contains $requestedCover) from $covers 
then
    log.error("RHS rule not implemented yet. Found type {}.", $requestedCover);
end

However this seems to trigger every Cover is the covers list.

How to create this rule?

Martijn Burger
  • 7,315
  • 8
  • 54
  • 94

2 Answers2

1

Finally figured it out, thanks to @laune for the help

when
    $p: Policy(available == true, $requestedCovers: requestedCovers, $covers: covers)
    $requestedCover: String() from $requestedCovers
    $coverTypes: List(!this.isEmpty()) from accumulate(Cover($coverType: type) from $covers; collectList($coverType))
    eval(!$coverTypes.contains($requestedCover))
Martijn Burger
  • 7,315
  • 8
  • 54
  • 94
0

You have two lists in this unwieldy object, and one of them is a cut of another list. What you need is the set of requestedCovers - covers.type (a set difference).

It's a cinch to write the set difference as a method, either in Policy or (as a static) in a separate utility class.

If you insist on Drools, you'll have to

rule x
when
  Policy( available, $reqs: requestedCovers, $covs: covers )
  accumulate( Cover( $type: type ) from $covs;
              $covered: collectSet( $type ) )
  $s: String( this not memberOf $covered ) from $reqs
then
  ...$s is not covered...
end

Untested!

laune
  • 31,114
  • 3
  • 29
  • 42