Problème lors de l'écriture de LHS de Drools / JBoss Rules où je fais correspondre un fait et que j'utilise ensuite ce fait pour déterminer si un autre fait existe

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

  •  03-07-2019
  •  | 
  •  

Question

J'utilise Drools (pour la première fois) pour exprimer certaines règles et cela fonctionne très bien jusqu'à présent. Cependant, on m'a donné une nouvelle condition que je ne suis pas en mesure d'exprimer très clairement dans le langage des règles.

Je dois effectuer une action sur le compte du joueur s’il a un solde en souffrance entre un certain montant, s’il n’a pas effectué de paiement la semaine dernière et s’il n’a pas effectué de paiement dans les 4 dernières semaines qui est supérieure ou égale à une déduction hebdomadaire. Il y a quelques autres règles mais je les ai supprimées dans le but de simplifier la règle pour cette question. C’est la dernière règle qui me pose problème.

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

Le problème est que cela ne fonctionne tout simplement pas, je continue à recevoir des exceptions org.drools.rule.InvalidRulePackage. J'étais en train de deviner la syntaxe mais je n'arrivais pas à trouver un exemple montrant ce que j'essayais de faire. Est-ce même possible?

Le message d'erreur d'origine complet est le suivant:

"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'"

Après avoir essayé la suggestion du premier commentaire, l'erreur est la suivante:

"[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"
Était-ce utile?

La solution

Oui, comme vous l'avez deviné, vous devez définir explicitement les "" and"; à l'intérieur du " pas " motif pour les joindre ensemble.

La seule fois où vous n’avez pas besoin des " et " est au plus haut niveau:

par exemple

when Foo() Bar()

Ne nécessite pas de """

mais cela est implicitement identique à

when Foo() and Bar()

Votre solution semble donc correcte. L'absence d'un niveau supérieur "et" semble être une convention dans la plupart des langages de règles (revenir à CLIPS!)

Autres conseils

Après un peu plus de piratage, ce qui suit n’entraîne aucune erreur d’exécution (bien que je ne sois pas sûr que ce soit "correct"). J'ai réécrit la clause pour mettre les existences autour des faits et j'ai utilisé un infixe pour les regrouper.

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

Merci pour toute l'aide apportée jusqu'à présent.

Qu'en est-il de ($ deduction- > amountInPence * 4) ? Je pense que le - > devrait être un . à la place.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top