drools DSL添加表达式到最后一个模式,'-'不起作用 [英] drools dsl adding expression to last pattern with '-' not working

查看:66
本文介绍了drools DSL添加表达式到最后一个模式,'-'不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Drools规则已有一段时间了,最​​近才开始使用DSL来使最终用户更容易编写规则。虽然我已经能够定义一个简单的dsl并按预期正确地编译为drl,但是我无法使用在前一个表达式中添加约束的dsl功能来工作。
我什至尝试使用drools dsl指南中最简单的示例,并且这不会将我以-开头定义的条件编译到上一个表达式中。编译时,规则 Rule1Sample_0错误不断出现输入不匹配的价格。正如我说的,
可以用于简单的条件表达式和结果表达式。但是在文档后添加约束将根本无法正常工作。
我使用的是Drools版本7.0.0.Final,直到更高版本才支持该功能吗?

I have been working with drools rules for a while and just recently started on a dsl to make the rule authoring easier for end users. While I have been able to get a simple dsl defined and correctly compiling into drl as expected, i cannot get the dsl feature of 'adding constraints to previous expression' to work. I am even trying the simplest of examples from the drools dsl guide and this will not compile the Conditions i have defined beginning with '-' into the previous expression. I keep getting a 'mismatched input 'price' in rule "Rule1Sample_0" error on compiling it. as i said I have this working for straightforward Condition expressions and Consequence expressions. but adding contraints following the docs is just not working at all. I am using drools version 7.0.0.Final, is this something thats not supported until a later version?

在我正在测试的简单示例中, dsl文件仅包含:

in the simple example i am testing, my dsl file just contains:

[condition][]There is a {ShoppingCart} that=${ShoppingCart!lc} : ${ShoppingCart!ucfirst}()
[condition][]- total price is greater than 1000 =totalPrice > 1000

[consequence]Update {ShoppingCart}=System.out.println("{ShoppingCart}" + " test")

这里是条件

"There is a ShoppingCart that total price is greater than 1000"

以及我为模板的时间和部分指定的操作:

and Action which i am specifying for the when and then part of my template:

"Action" "Update ShoppingCart"

在将其传递给DrlParser之前,这是编译的drl:

Here is the compiled drl before I pass it to the DrlParser:


    rule "Test1"
      dialect "mvel"
      when
         "There is a ShoppingCart that total price is greater than 1000"
      then
        "Update ShoppingCart"
    end

在上面的代码段运行之后,expandedDrl字符串包含了以下内容:

This is what expandedDrl string contains after above code snippet runs:

package com.sample.test

rule "Test1"
  dialect "mvel"
  when
     $shoppingcart : $Shoppingcart() total price is greater than 1000
  then
    System.out.println("ShoppingCart" + " test")
end

这是当我使用DRLParser解析它时生成的drl:

And here is the generated drl for this when i parse it using the DRLParser:

(此处为代码段,有些

DrlParser parser = new DrlParser();
        DefaultExpanderResolver resolver = new DefaultExpanderResolver(new StringReader(dsl));
        String expandedDrl = parser.getExpandedDRL(dslr, resolver);

在上面的代码段运行后,expandedDrl字符串包含以下内容:

This is what expandedDrl string contains after above code snippet runs:

package com.sample.test

rule "Test1"
  dialect "mvel"
  when
     $shoppingcart : $Shoppingcart() total price is greater than 1000
  then
    System.out.println("ShoppingCart" + " test")
end

我在控制台中看到的编译器错误:

And the compiler error i see in the console:

[[13,43]: [ERR 102] Line 13:43 mismatched input 'price' in rule "Test1"  ....


推荐答案

可以尝试条件

There is a ShoppingCart that
- total price is greater than 1000






您能否尝试遵循dsl


Could you try following dsl

... business definitions
[when]complex condition = (simple condition 
                           or another condition)
[when]simple condition = (total price is not 0)
[when]another condition = (total price greater than 10)

... field definitions
[when]total price = totalPrice

... consequences I advise to wrap in java util class each as a static method to write java code in java code
[consequence]Update {ShoppingCart}=System.out.println("{ShoppingCart}" + " test")

... tech dsl at the bottom

[when]There (is( an?)?|are) {entityType}s?( that)? = ${entityType}: {entityType}()
[when](is\s+)?not less than(\s+an?)? = >=
[when](is\s+)?less than(\s+an?)? = <
[when](is\s+)?not greater than(\s+an?)? = <=
[when](is\s+)?greater than(\s+an?)? = >
[when]((is|do(es)?)\s+)?not equals?(\s+to)? = !=
[when](is\s+)?equals?(\s+to)? = ==
[when]is not(\s+an?)? = !=
[when]is(\s+an?)? = ==
[when]like(\s+an?)? = matches
[when]{prefix}?\s*(?<![\w])and(?![\w])\s*{suffix}? = {prefix} && {suffix}
[when]{prefix}?\s*(?<![\w])or(?![\w])\s*{suffix}? = {prefix} || {suffix}
[when]{prefix}?\s*(?<![\w])not(?! (in|matches|contains|memberOf|soundslike|str))(\s+an?)?(?![\w])\s*\({suffix}? = {prefix} false == (true && {suffix}
[when]{prefix}?\s*(?<![\w])not(?! (in|matches|contains|memberOf|soundslike|str))(\s+an?)?(?![\w])\s*{suffix}? = {prefix} !{suffix}
[when](?<![^\(,])\s*- = 

这应该能够处理类似规则

this should be able to process rules like

There is a ShoppingCart that
- total price is greater than 1000
- not complex condition

如果您想在其他条件下重用条件,则希望它们是原子性的。用右括号()括住RHS的良好经验法则不会破坏记录的原子性

If you want to reuse conditions in other conditions you want them to be atomic. Good rule of the thumb to embrace RHS with braces () not to break atomicy of the record

测试

@DroolsSession({ "classpath:/test.rdslr", "classpath:/business.dsl", "classpath:/keywords.dsl" })
public class PlaygroundTest {

    @Rule
    public DroolsAssert drools = new DroolsAssert();

    @Test
    public void testIt() {
        drools.insertAndFire(new ShoppingCart(BigDecimal.valueOf(1000.5)));
        drools.insertAndFire(new ShoppingCart(BigDecimal.valueOf(999)));
    }
}

public class ShoppingCart {
    public BigDecimal totalPrice;

    public ShoppingCart(BigDecimal totalPrice) {
        this.totalPrice = totalPrice; 
    }
}

rdslr

rule Test1
    when
        There is a ShoppingCart that 
        - total price is greater than 1000
    then
        print eligible price
end

rule Test2
    when
        There is a ShoppingCart that 
        - worth a discount
    then
        print eligible price
end

business.dsl

business.dsl

[when]worth a discount = 
    (total price is not less than 500
    and not over limit
    or total price is greater than 5000)
// stupid condition just for demonstration
[when]over limit = ((total price + total price * 0.05) > total price + 50)
[when]total price = totalPrice

[then]print eligible price = System.out.println($ShoppingCart.totalPrice);

keywords.dsl

keywords.dsl

[when]There (is( an?)?|are) {entityType}s?( that)? = ${entityType}: {entityType}()
[when](is )?not within\s*\({tail}?= not in ({tail}
[when](is )?within\s*\({tail}?= in ({tail}
[when](is )?not one of\s*\({tail}?= not in ({tail}
[when](is )?one of\s*\({tail}?= in ({tail}
[when]ignore case '{tail}?= '(?i){tail}
[when]{param:[$\w\.!'\[\]]+} as {param2:[$\w\.!'\[\]]+}=(({param2}) {param})
[when](is\s+)?not less than(\s+an?)? = >=
[when](is\s+)?less than(\s+an?)? = <
[when](is\s+)?not greater than(\s+an?)? = <=
[when](is\s+)?greater than(\s+an?)? = >
[when]((is|do(es)?)\s+)?not equals?(\s+to)? = !=
[when](is\s+)?equals?(\s+to)? = ==
[when]is not(\s+an?)? = !=
[when]is(\s+an?)? = ==
[when]like(\s+an?)? = matches
[when]{prefix}?\s*(?<![\w])and(?![\w])\s*{suffix}? = {prefix} && {suffix}
[when]{prefix}?\s*(?<![\w])or(?![\w])\s*{suffix}? = {prefix} || {suffix}
[when]{prefix}?\s*(?<![\w])not(?! (in|matches|contains|memberOf|soundslike|str))(\s+an?)?(?![\w])\s*\({suffix}? = {prefix} false == (true && {suffix}
[when]{prefix}?\s*(?<![\w])not(?! (in|matches|contains|memberOf|soundslike|str))(\s+an?)?(?![\w])\s*{suffix}? = {prefix} !{suffix}
[when](?<![^\(,])\s*- = 

测试输出

00:00:00 --> inserted: ShoppingCart[totalPrice=1000.5]
00:00:00 --> fireAllRules
00:00:00 <-- 'Test1' has been activated by the tuple [ShoppingCart]
1000.5
00:00:00 --> inserted: ShoppingCart[totalPrice=999]
00:00:00 --> fireAllRules
00:00:00 <-- 'Test2' has been activated by the tuple [ShoppingCart]
999

这篇关于drools DSL添加表达式到最后一个模式,'-'不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆