Uploaded image for project: 'Drools'
  1. Drools
  2. DROOLS-5019

Unexpected rule match with forall pattern

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major Major
    • None
    • 7.29.0.Final, 7.30.0.Final, 7.31.0.Final, 7.32.0.Final
    • core engine
    • None
    • 2020 Week 04-06 (from Jan 20)
    • Hide

      run

      mvn clean test
      

      on attached reproducer.

      Show
      run mvn clean test on attached reproducer.
    • NEW
    • NEW

      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:

      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
      

      Example of DRL not behaving as expected (the 53_54_55_NotificationTestInterlineAllFlight rule will now fire when the forall clause is not satisfied):

      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
      

      The issue does not occur when using Drools <= 7.28.0.Final.

              mfusco@redhat.com Mario Fusco
              mcasalino Matteo Casalino (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved: