]
Mario Fusco resolved DROOLS-5019.
---------------------------------
Resolution: Done
Fixed by
Unexpected rule match with forall pattern
-----------------------------------------
Key: DROOLS-5019
URL:
https://issues.redhat.com/browse/DROOLS-5019
Project: Drools
Issue Type: Bug
Components: core engine
Affects Versions: 7.29.0.Final, 7.30.0.Final, 7.31.0.Final, 7.32.0.Final
Reporter: Matteo Casalino
Assignee: Mario Fusco
Priority: Major
Attachments: forall-unwanted-match.tgz
As of Drools 7.29.0.Final, rules with a forall pattern sometimes won't match as
expected.
In particular we notice that adding an extra (apparently unrelated) rule causes the rule
containing forall to fire when it is not expected to. No inference is involved.
Example of DRL behaving as expected:
{noformat}
package org.drools.reproducer
declare Request
skippne : boolean
pneeligid : String
applicableAirlines : java.util.List
officeid : String
end
declare Flight
id : int
marketingairlinecode : String
cabin : String
end
declare Offer
id : int
flightIds : java.util.List
boundIds : java.util.List
passengerId : int
notificationFlightId : int
stayDurationBeforeDeparture : int
end
declare Passenger
id : int
end
rule "53_54_55_NotificationTestInterlineAllFlight"
when
Offer( $thisOfferId: id, $offerFlightIds : flightIds, $offerBoundIds : boundIds,
$thisPassengerId: passengerId, $thisNotificationFlightId: notificationFlightId )
Flight( id == $thisNotificationFlightId, $offerFlightIds contains id )
Passenger( id == $thisPassengerId )
Request( $skippne: skippne, pneeligid == "100000053" || skippne,
$applicableAirlines: applicableAirlines )
forall(
$fact : Flight( $applicableAirlines contains marketingairlinecode )
Flight( this == $fact, cabin == "Y" ) )
then
System.out.println("53_54_55_NotificationTestInterlineAllFlight");
end
rule "2_SmsNotificationCheckinTestFNDCall"
when
Offer( $thisOfferId: id, $thisPassengerId: passengerId, $thisNotificationFlightId:
notificationFlightId, $offerFlightIds : flightIds, $offerBoundIds : boundIds,
$stayDurationBeforeDeparture: stayDurationBeforeDeparture )
Flight( id == $thisNotificationFlightId, $offerFlightIds contains id, $thisFlightId:
id )
Passenger( id == $thisPassengerId )
Request( $skippne: skippne, pneeligid == "checkin" || skippne,
$applicableAirlines: applicableAirlines )
Flight( id == $thisNotificationFlightId, $offerFlightIds contains id,
$applicableAirlines contains marketingairlinecode, cabin == "L" )
then
System.out.println("2_SmsNotificationCheckinTestFNDCall");
end
{noformat}
Example of DRL not behaving as expected (the 53_54_55_NotificationTestInterlineAllFlight
rule will now fire when the forall clause is not satisfied):
{noformat}
package org.drools.reproducer
declare Request
skippne : boolean
pneeligid : String
applicableAirlines : java.util.List
officeid : String
end
declare Flight
id : int
marketingairlinecode : String
cabin : String
end
declare Offer
id : int
flightIds : java.util.List
boundIds : java.util.List
passengerId : int
notificationFlightId : int
stayDurationBeforeDeparture : int
end
declare Passenger
id : int
end
rule "53_54_55_NotificationTestInterlineAllFlight"
when
Offer( $thisOfferId: id, $offerFlightIds : flightIds, $offerBoundIds : boundIds,
$thisPassengerId: passengerId, $thisNotificationFlightId: notificationFlightId )
Flight( id == $thisNotificationFlightId, $offerFlightIds contains id )
Passenger( id == $thisPassengerId )
Request( $skippne: skippne, pneeligid == "100000053" || skippne,
$applicableAirlines: applicableAirlines )
forall(
$fact : Flight( $applicableAirlines contains marketingairlinecode )
Flight( this == $fact, cabin == "Y" ) )
then
System.out.println("53_54_55_NotificationTestInterlineAllFlight");
end
rule "2_SmsNotificationCheckinTestFNDCall"
when
Offer( $thisOfferId: id, $thisPassengerId: passengerId, $thisNotificationFlightId:
notificationFlightId, $offerFlightIds : flightIds, $offerBoundIds : boundIds,
$stayDurationBeforeDeparture: stayDurationBeforeDeparture )
Flight( id == $thisNotificationFlightId, $offerFlightIds contains id, $thisFlightId:
id )
Passenger( id == $thisPassengerId )
Request( $skippne: skippne, pneeligid == "checkin" || skippne,
$applicableAirlines: applicableAirlines )
Flight( id == $thisNotificationFlightId, $offerFlightIds contains id,
$applicableAirlines contains marketingairlinecode, cabin == "L" )
then
System.out.println("2_SmsNotificationCheckinTestFNDCall");
end
rule "3_XmlNotificationCheckinTestFNDCall"
when
Offer( $thisOfferId: id, $thisPassengerId: passengerId, $thisNotificationFlightId:
notificationFlightId, $offerFlightIds : flightIds, $offerBoundIds : boundIds,
$stayDurationBeforeDeparture: stayDurationBeforeDeparture )
Flight( id == $thisNotificationFlightId, $offerFlightIds contains id, $thisFlightId:
id )
Passenger( id == $thisPassengerId )
Request( $skippne: skippne, pneeligid == "checkin" || skippne,
$applicableAirlines: applicableAirlines )
Flight( id == $thisNotificationFlightId, $offerFlightIds contains id,
$applicableAirlines contains marketingairlinecode, cabin == "Q" )
then
System.out.println("3_XmlNotificationCheckinTestFNDCall");
end
{noformat}
The issue does not occur when using Drools <= 7.28.0.Final.