Problem Schreiben LHS von Drools / JBoss Rules, wo ich eine Tatsache bin passend und dann diese Tatsache, um festzustellen, ob eine andere Tatsache existiert

StackOverflow https://stackoverflow.com/questions/415907

  •  03-07-2019
  •  | 
  •  

Frage

Ich bin mit Drools (zum ersten Mal) einige Regeln zum Ausdruck bringen und es bisher wirklich gut gearbeitet hat. Allerdings habe ich eine neue Bedingung gegeben, dass ich nicht in der Lage bin in der Regelsprache zum Ausdruck bringt sehr deutlich.

Im Grunde brauche ich eine Aktion auszuführen, auf der Spieler-Konto, wenn sie ein hervorragendes Gleichgewicht dort Rechnung zwischen einem bestimmten Betrag haben, wo sie eine Zahlung in der letzten Woche nicht gemacht haben und wo sie eine Zahlung nicht gemacht haben, in die letzten 4 Wochen, die größer oder gleich einen wöchentlichen Abzug ist. Es gibt ein paar andere Regeln, aber ich habe sie in dem Bemühen, entfernt, um die Regel für diese Frage zu vereinfachen. Es ist die letzte Regel, die mir ein Problem verursacht.

rule "The broken rule"
   salience 10
   no-loop
   when
      Player( $playerNumber : playerNumber )
      $a : Account( // balance between £5 and £100 and no arrangement
       playerNumber == $playerNumber &&
         accountBalanceInPence >= 500 &&
         accountBalanceInPence <= 10000
      )
      not ( // no payment in last week
         exists AccountTransaction(
            playerNumber == $playerNumber &&
            transactionDate >= oneWeekAgo &&
            transactionCode == "P" // payment
         )
      )
      /* It's this next bit that is broken */
      not ( // no payment > (weekly cost * 4) paid within last 4 weeks
         $deduction : AccountTransaction( // a recent transaction
            playerNumber == $playerNumber &&
            transactionDate >= fourWeeksAgo &&
            transactionCode == "D" // deduction
         )
         exists AccountTransaction( // the payment
            playerNumber == $playerNumber &&
            transactionDate >= fourWeeksAgo &&
            transactionCode == "P" // payment
            amountInPence >= ($deduction->amountInPence * 4)
         )
   )
   then
      // do some action to the account
end

Das Problem ist, dass es funktioniert einfach nicht, ich bekomme immer wieder geworfen org.drools.rule.InvalidRulePackage Ausnahmen. Ich kann nur raten auf der Syntax, konnte aber nicht scheinen, um ein Beispiel zu finden, das zeigte, was ich zu tun werde versuchen. Ist es überhaupt möglich?


Die vollständige Original-Fehlermeldung lautet:

"unknown:50:3 mismatched token: [@255,1690:1695='exists',<39>,50:3]; expecting type RIGHT_PAREN[54,4]: unknown:54:4 mismatched token: [@284,1840:1852='amountInPence',<7>,54:4]; expecting type RIGHT_PAREN[54,22]: unknown:54:22 Unexpected token '$payment'"

den Vorschlag in den ersten Kommentar Nach dem Versuch, der Fehler ist:

"[50,3]: unknown:50:3 mismatched token: [@255,1690:1695='exists',<39>,50:3]; expecting type RIGHT_PAREN[54,4]: unknown:54:4 mismatched token: [@284,1840:1852='amountInPence',<7>,54:4]; expecting type RIGHT_PAREN[54,45]: unknown:54:45 mismatched token: [@293,1881:1881='*',<71>,54:45]; expecting type LEFT_PAREN[55,3]: unknown:55:3 mismatched token: [@298,1890:1890=')',<12>,55:3]; expecting type THEN"
War es hilfreich?

Lösung

ja, wie Sie erraten haben, müssen Sie eine explizite setzen „und“ in der „nicht“ -Muster sie miteinander zu verbinden.

Die einzige Zeit, die Sie nicht brauchen die „und“ auf der obersten Ebene ist:

zB

when Foo() Bar()

erfordert keine eine "und"

, aber das ist implizit die gleiche wie

when Foo() and Bar()

So Ihre Lösung scheint richtig. Das Fehlen eines Top-Level „und“ scheint Konvention in den meisten Regelsprachen zu sein (geht zurück auf CLIPS!)

Andere Tipps

Nach etwas mehr Hacking um die folgenden keine Laufzeitfehler verursachen (obwohl ich nicht sicher bin, ob es „richtige“ noch) nicht. Ich schrieb die Klausel zu setzen die existiert um sowohl die Fakten und verwendet, um eine Infix und gruppieren.

  not ( // no payment > (weekly cost * 4) paid within last 4 weeks
     exists (
        AccountTransaction( // a recent transaction
           playerNumber == $playerNumber &&
           transactionDate >= fourWeeksAgo &&
           transactionCode == "D" // deduction
           $recentDeducation : amountInPence
        ) and
        AccountTransaction( // the payment
           playerNumber == $playerNumber &&
           transactionDate >= fourWeeksAgo &&
           transactionCode == "P" // payment
           amountInPence >= ($recentDeducation * 4)
        )
     )
  )

Vielen Dank für die Hilfe bisher.

Was ist ($deduction->amountInPence * 4)? Ich denke, sollte die -> stattdessen eine . sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top