Search code examples
droolsrule-engine

In Drools, how to find the keyword with the least number of matches?


I have some tokenized string like this

declare UserAddress
    tokens : List
end

and I have a list of recognized tokens like this

rule "Count Frequency of RealTokens occurrence in RealAddresses"
salience -10
when
    $token : RealToken();
    $count : List() from collect(RealAddress(tokens contains $token.getToken()));   
then
    modify($token) { setCount($count) };
end

Using drools, how can I determine, which of the tokens in a given UserAddress matches the RealToken with the lowest possible $count value?

I already tried this:

rule "Find the Most Statistically Significant Token for each User Address"
salience -20
    $ua : UserAddress();
    $ut : String( length() > 0) from $ua.getTokens().subList(1, $ua.getTokens().size());
    $rt : RealToken(token == $ut);
    not(RealToken(token == $ut && this.count < $rt.count));
then
    System.out.println("MSST: " + $ua.toString() + " = " + $rt.toString());
end 

But couldn't get past the DRL syntax issue:

java.lang.IllegalArgumentException: Found errors in package builder
[85,1]: [ERR 102] Line 85:1 mismatched input '$ua' in rule "Find the Most Statistically Significant Token for each User Address"
[0,0]: Parser returned a null Package

Solution

  • The error message is quite clear, and when you would have bothered to look at line 85, you would have found that

    rule "Find the Most Statistically Significant Token for each User Address"
    salience -20
        $ua : UserAddress();  ############################### line 85
        $ut : String( length() > 0) from $ua.getTokens().subList(1, $ua.getTokens().size());
        $rt : RealToken(token == $ut);
    

    there is no keyword when preceding the first pattern.