Problema al escribir LHS de Drools / Reglas de JBoss donde coincido con un hecho y luego lo uso para determinar si existe otro hecho

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

  •  03-07-2019
  •  | 
  •  

Pregunta

Estoy usando Drools (por primera vez) para expresar algunas reglas y ha estado funcionando muy bien hasta ahora. Sin embargo, me han dado una nueva condición que no puedo expresar muy claramente en el lenguaje de las reglas.

Esencialmente, necesito realizar una acción en la cuenta de los jugadores si tienen un saldo pendiente en esa cuenta entre cierta cantidad, en la que no han realizado un pago en la última semana y en la que no han realizado un pago en las últimas 4 semanas que es mayor o igual a una deducción semanal. Hay algunas otras reglas, pero las he eliminado en un esfuerzo por simplificar la regla para esta pregunta. Es la última regla que me está causando un problema.

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

El problema es que simplemente no funciona, sigo recibiendo las excepciones de org.drools.rule.InvalidRulePackage. Estaba adivinando sobre la sintaxis, pero no pude encontrar un ejemplo que mostrara lo que estoy tratando de hacer. ¿Es incluso posible?


El mensaje de error original completo es:

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

Después de intentar la sugerencia en el primer comentario, el error es:

"[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"
¿Fue útil?

Solución

sí, como lo adivinó, necesita poner un explícito '' y '' dentro de " no " Patrón para unirlos juntos.

La única vez que no necesita el " y " está en el nivel superior:

por ejemplo

when Foo() Bar()

No requiere un " y "

pero esto es implícitamente lo mismo que

when Foo() and Bar()

Entonces tu solución parece correcta. La falta de un nivel superior '' y '' parece ser una convención en la mayoría de los lenguajes de reglas (¡volviendo a CLIPS!)

Otros consejos

Después de un poco más de pirateo, lo siguiente no causa ningún error de tiempo de ejecución (aunque todavía no estoy seguro de si es correcto). Reescribí la cláusula para poner lo existente en torno a los hechos y usé un infijo y los agrupé.

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

Gracias por toda la ayuda hasta ahora.

¿Qué pasa con ($ deducción- > amountInPence * 4) ? Creo que el - > debería ser un . en su lugar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top