Using rule attributes no-loop and lock-on-active is advertised as simplifying rule authoring, which is true in a certain percentage of use cases. It is, however, always a way to avoid stringent application of logic, the fundament of rule conditions. Although adding full logic to rule conditions may require more work,...
workflow,drools,jbpm,drools-guvnor
It's in the "global" folder of your project. If you switch your Project Explorer to "Repository View" and click on the top-level global folder you will find the customeditors json config file. See http://i.imgur.com/yufVf0m.png for reference.
The following code will not fix your problem but it should help you diagnose whether you really run the rules and the session you think you do. I'm using Java notation. KieSession kieSession = ... KieBase kieBase = kieSession.getKieBase(); Collection<KiePackage> kiePackages = kieBase.getKiePackages(); for( KiePackage kiePackage: kiePackages ){ for( Rule...
Use a single condition column: CONDITION ExampleEntity($mf: mainField) SecondEntity secondField == $mf /*param*/ Combine Ex with Sec on equal field values x The /*param*/ and the x is a hack to get the condition being generated for the row....
Got it working! I have done the following: extend the domain objects for Vehicle and Customer to reflect these. //Vehicle.java protected boolean secure; public boolean isSecure() {return secure;} public void setSecure(boolean secure) {this.secure = secure;} //Customer.java protected boolean needsSecure; public boolean isNeedsSecure() {return needsSecure;} public void setNeedsSecure(boolean needsSecure) {this.needsSecure =...
Here is a set of rules that implements the algorithm. It will not be very efficient on large numbers of As and Ps. A pure Java solution shouldn't be all that difficult either. Note that a complete sort isn't necessary after removing one A from the set and clearing away...
The null-safe operator in Drools is !., not .? - see the documentation. You can use it inside decision tables just as you would when writing rules. In your example, change the condition from mdcl.MDCL_Health.get("MDCL").Value to mdcl!.MDCL_Health.get("MDCL").Value to only fire the rule if mdcl is not null....
Esper analyzes the rule and only stores derived state (aggregations etc., if any) and if needed by the rule also a subset of events. Esper allows defining contexts like described in the book by Opher Etzion and Peter Niblet. I recommend reading. By specifying a context Esper can minimize the...
I think what's happening here is that some Java code from seams (and your app) is compiled using a java 8 compiler. Then org.drools.compiler.PackageBuilder is called to compile some DRL. This will, eventually, call a Java compiler to compile the Java code generated from the DRL. For this, a Java...
There was indeed a change, as (IIRC) the Drools team appeared to dislike the resulting effect and/or the incompletely defined semantics of timers running while the Rule Engine was not active. (Note that you can call session.fire*() repeatedly on a session.) On the move to 6.x, the decision was made...
Most likely you are seeing an initial phase where the count of events in the window and according to the constraints hasn't reached the length specified in window:length yet. For instance, rule "Your First Rule" when accumulate( $st : Applicant($age: age > 5) over window:length(10) from entry-point X, $avg: average...
As the documentation says: Drools 4.0 supported custom conflict resolution strategies; while this capability still exists in Drools it has not yet been exposed to the end user via knowledge-api in Drools 5.0. http://docs.jboss.org/drools/release/5.2.0.Final/drools-expert-docs/html/ch04.html So if you are using Drools 5+ you will not be able to change conflict resolver...
Two alternatives: rule "Difference in offsets" dialect "java" no-loop true when $mode:SensorMode( $mo: modeOffset ); //... then System.out.println("---modeOffset---"+ $mo); //... end Or: rule "Difference in offsets" dialect "java" no-loop true when $mode:SensorMode(); //... then System.out.println("---modeOffset---"+ $mode.getModeOffset() ); //... end It's possible that dialect "mvel" is a third option, but this...
You have to add XML namespache and scema reference to your xml file: XML namespace: xmlns:vm="http://www.mulesoft.org/schema/mule/vm" XML Schema Location: http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/3.6/mule-vm.xsd So it looks like so: <mule xmlns:bpm="http://www.mulesoft.org/schema/mule/bpm" xmlns:vm="http://www.mulesoft.org/schema/mule/vm" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking"...
Yes, you can use an alias. Change your condition to: $s : sv2.SV202_CompMedProcedId.get("SV202-02").Value >= '70010' && $s <= '76499' || $s >= '76506' && $s <= '76999' || $s >= '77001' && $s <= '77032' || $s >= '77051' && $s <= '77059' || $s >= '77071' && $s <=...
collections,types,drools,rules,declare
Since ArrayList is a generic collection, Gson is not able to correctly identify the type of the address object when processing the JSON string. The easiest way to accomplish what you are trying to do would be to use an array instead of a ArrayList: declare Person firstName : String...
deployment,drools,jbpm,jboss-eap-6
That's because the war is prepared for wildfly (there are some specific dependencies that needs to be added to it to work), so you need to get the EAP distribution, or you can build that from the source code. If you clone and build this repository: https://github.com/droolsjbpm/kie-wb-distributions/ (most specifically the...
The DRL construct that fits is the compound restriction using "in", written as e.g. Person( name in ("Joe", "Tom", "Fred") ) In your case the DSLR definition should be [condition][]The customer firstName is in this list {nameList}= Customer( firstName in ({nameList}) ) Note that in the DSL you'll have to...
Try calling fireAllRules(); available in Drools session. It provides you following variances: fireAllRules(); fireAllRules(AgendaFilter agendaFilter) fireAllRules(AgendaFilter agendaFilter, int max) fireAllRules(int max) In last two variances, max is the upper limit on the rules to be fired. In your example, if you use max as 10, it can fire all 10...
Two comments. (1) The abundant usage of rule attributes is something to be avoided. (2) Rule "Difference in offsets" implements a procedural paradigm: map elements of one list to create another list. That said, I'd do the calculation of the "changes intervals" on the right hand side of a rule...
Actually I found the problem, well it is not a problem in first place :) Maybe rule name is little bit misleading. Anyway, problem is actually in too crowded curriculums. Like we had 30-40 courses, which makes 80-100 lectures. And for a 45 hours week, it is impossible to fit...
This could be rewritten simply as: rule "ruleX" when MyObject( string in ("ABC", "DEF") ) then //do stuff end Note that the list after in could also contain (previously) bound variables. If you have the values in a collection, you can also write rule "ruleY" when Data( $los: listOfStrings )...
I'm not sure from where that org.dools.RuleBaseFactory was taken. Below is how it was done in Drools 5.3 (and possibly earlier) up to 5.6: KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); kbuilder.add( ..., ResourceType.DRL); if( kbuilder.hasErrors() ){ System.err.println( "### compilation errors ###" ); KnowledgeBuilderErrors errors = kbuilder.getErrors(); for( KnowledgeBuilderError err: errors ){ System.err.println(...
The order that the commands are added matters. Adding the query command is a signal to the engine to execute that query, therefore the facts were being inserted and the query run BEFORE the process was started. Reversing the lines where the queries were added and the process started was...
You can write your own accumulate: rule coll when $map: Map() from accumulate( $o: Order( $t: type ), init( Map m = new HashMap(); m.put( "A", new HashSet() ); m.put( "B", new HashSet() ); ), action( ((Set)m.get( $t )).add( $o ); ), reverse( ((Set)m.get( $t )).remove( $o ); ), result(...
You can collect two lists in the same accumulate CE - I didn't see any difference in the two accumulates for pairing BasePriceUpchargeConfig and CoverUpChargeConfig. rule "check-multiple instance-on-cover-type" extends "base" when accumulate ( $b: BasePriceUpchargeConfig( prefix contains $prefix, style contains $style, $baseCoverType : baseCoverType ) and $c : CoverUpChargeConfig( baseCoverType...
For a dynamic switch you need another object, PersonControl with boolean attributes: $applicant : Applicant ($age : age, $gender : gender, $income : income) PersonControl( $igAge: igAge, $igGender: ifGender, $igIncome: igIncome) $person : Person( age == $age || $igAge, gender == $gender || $igGender, income == $income || $igIncome )...
Not sure how large "large" is (of course there's always a performance tradeoff), but you could also use an inserted object to pull from a database (/cache) and have the rules access the values via method. when $y : AnObject (name == "car", lookupPrice > 10000 ); where AnObject.getLookupPrice() is...
If you have a condition CONDITION Fact age > Test for age limit 42 the rule will contain Fact(age > "42") However, if you use CONDITION Fact age > $param Test for age limit 42 the rule will contain Fact(age > 42) But, normally, this should not matter and the...
You have written class Customer, or must know it to understand what's going on here. Presumably it contains a Collection<Account> accounts (see note), which is (by the engine) retrieved one by one so that the rule fires for each Account object contained in Customer's object. The rule will fire once...
java,eclipse,eclipse-plugin,drools
Drools does not require you to add a semicolon after a statement on the right hand side if there is a line end following it. RHS code is parsed by a special (peculiar) parser, not strictly adhering to Java syntax. It's more lenient, but may not always be able to...
Unfortunately there doesn't seem to be a direct way to do this just for .drl files (even with the drools plugin installed). By default eclipse will use the general text editor for drools files. You can change the font size for this in Preferences/General/Appearance/colors and Fonts... Basic/Text Font ...this will...
It is advisable to write $notification : NotificationVO( offsetChngesIntervall != null && offsetChngesInterval.size() > 0 ) to make sure that the list isn't empty. Perhaps also a check that it is not null....
This rule needs to be rewritten as rule "Add type Marque taxe" when $d : Demarche( typeDemarche == "Marque", $t: listTaxes) // I AM GUESSING HERE not IsMarque(demarche == $d) then modify($t){ put(14, 1) } insert( new IsMarque( $d ) ); System.out.println("infer marque"); end And no no-loop true and lock-on-active...
Functions can't actually access the working memory. You could bind the required facts in your rule and then send them as parameters to your function. A better approach would be to use a Query instead of a function. You can read more about queries in Drools' documentation: http://docs.jboss.org/drools/release/6.3.0.Beta1/drools-docs/html_single/index.html#QuerySection...
The event "match created" means that a rule and a set of facts have been combined and put on the agenda, because the facts match the conditions of that rule. This combination may stay a short or long while on the agenda, until its time has come for being "fired",...
If you use the KieFileSystem directly, you must ensure that the content reflects the required maven structure. So, you should write: kfs.write("src/main/resources/org.drools.test.testrule.drl", resource); In alternative, set the sourcePath on the resource and write it directly: resource.setSourcePath( "org.drools.test.testrule.drl" ); kfs.write( resource ); ...
After fixing the mismatch person/$person, the rule compiles and fires if there is a person with "Knitting" in the hobbies collection. (Version 5.5, but I have no doubt that other versions work just as well.) rule "who knits" when $person: Person( $name: name ) Hobby(name == "Knitting") from $person.hobbies then...
REduce your code, and add -KieBase and KieSession creation: KieServices ks = KieServices.Factory.get(); KieFileSystem kFileSystem = ks.newKieFileSystem(); FileInputStream fis = new FileInputStream( "...drl" ); kFileSystem.write("src/main/resources/somename.drl", ks.getResources().newInputStreamResource( fis ) ); //XXX KieBuilder kbuilder = ks.newKieBuilder( kFileSystem ); kbuilder.buildAll(); if (kbuilder.getResults().hasMessages(org.kie.api.builder.Message.Level.ERROR)) { throw new RuntimeException("Build time Errors: " +...
I think that this query combination is (if you pardon the expression) a wash-out. Running bind_tsEquivalent_value"(sub, obj) without a matching Statement leads to an evaluation of bind_phxEquivalent_inverse_value(sub) and this delegates to bind_tsEquivalent_inverse_value(sub) and then to bind_phxEquivalent_inverse_value(sub) and now you are caught in an infinite recursive loop. A logical "or" without...
Rules aren't functions (or methods) and don't "return" values or objects. The right hand side is just Java code. You can call static methods, but stick to correct Java syntax: Person p = new Person(ServiceLongDong.sayHello(), person.age, person.name); ServiceLongDong.sayHello(); ServiceLongDong.finish(x); This can't be correct Java if ServiceLongDong is a class: ......
drools,drools-guvnor,drools-planner,drools-fusion,drools-flow
Your code is somewhat unusual, but thus rule should do. Note that I have used Document as the type for the elements in the list returned by GovernmentAgencyGoodsItem.getDocuments(). rule atLeastOne when $gs: GoodsShipment() List( size > 0 ) from accumulate ( $gi: GoodsItem() from $gs.getGoodsItems() and $d: Document() from $gi.getDocuments();...
Importing methods from Scala Object types can be problematic in Drools. The simple reason is that static methods do not exist in Scala in contrast with Java. This is because Scala takes a more stricter interpretation of what it means to be a pure object orientated language. What this means...
Objects of class C are: C(101, "BU1", 1,"2014-11-23"); C(101, "BU1", 2,"2014-11-24"); C(101, "BU1", 3,"2014-11-25"); C(101, "BU1", 4,"2014-11-26") Let's assume that we have A(101,...) B("BU1") Then the pattern C(iValue == $iVal, bId == $bVal,$lsequence : sequence,...) matches any of these C objects, binding $lsequence to 1, 2, 3 and so on....
You might say that there is a bug in org.drools.template.parser.StringCell, method public void addValue(Map<String, Object> vars) { vars.put(column.getName(), value); } Here, the value is added to the Map as a String but this does not take into account that string values are usually expanded into string literals. Therefore, an embedded...
While I don't know what the rule should evaluate, this is more like the style your rule should be written. I don't know how LicenseCredential is declared, nor do I know those Util.getXyz functions, so this may not work. Also, I've skipped the last condition. rule "Renewal alert for 60...
A KieContainer when used with dynamic modules keeps all the jars it loads in an isolated ClassLoader. So you can put your models into their own jar and specify them as a maven dependency on the project being deployed. If you are using kie-ci it will resolve the transitive dependencies...
As my hint in the question, this can be achieved more elegantly with a custom accumulate function: rule "odd" when accumulate($l : Integer(), $r : reverseSort($l); $r.size > 2, ($r[0] % 2) == 1, ($r[1] % 2) == 1, ($r[2] % 2) == 1) then System.out.println("Best 3 are odd numbers:...
Not sure why some folks are so afraid of no-loop. It exists for a perfectly good reason. i.e. It instructs the engine to not re-evaluate a rule if the reason for that re-evaluation is due to modifications or insertions in that rule. However, you can do it manually through your...
If you want to tell gradle to look at different locations you should write the repositories like this: repositories { maven { name 'central' url 'http://repo1.maven.org/maven2' } maven { name 'jboss' url 'http://repository.jboss.org/nexus/content/groups/public-jboss' } } ...
I have to (ab)use an answer so that I can ask my questions to understand the problem. class RoutePair{...} class RouteRun( RoutePair routePair; RunId runId } class PairableRuns( RunId runId1; // maybe String or int - doesn't matter RunId runId2; } After the first collect, $routeRunListAm is a List of...
This class is gone from the 5.5.0.Final distribution. It was present in 5.3.0 and 5.4.0 (jar: drools-core.jar), presumably also earlier. org.drools.base and ...evaluators wasn't part of the stable API in 5.3 and 5.4, so using it was risky. If you post how your code is using that class, s.o. might...
<scoreDsl> is not (yet) available, as there's no field for it on ScoreDirectorFactoryConfig.java. I believe that if you specify a DSL resource in <scoreDrl> in 6.2, it would actually work (yes, I realize that's semantically incorrect), because it ends up calling this code: kieFileSystem.write(kieResources.newClassPathResource(scoreDrl, "UTF-8")); so any KIE resource would...
You can change the value of the object reference stored in a DRL global only by using the API: then //... kcontext.getKieRuntime().setGlobal( "deviceCapacity", $snrData.getDeviceCapacity() ); end Clearly, this is ugly and not checked at compile time. You might consider writing a wrapper class IntWrapper { private int value; // getter,...
java,eclipse,drools,rule-engine,business-rules
You can create a utility that creates a static kSession. Then create a method that takes your input and fires your rules something like the following(untested code). Whenever you wanted to use it you could call. DroolsTest.getInstance().fire(input); public class DroolsTest { private static KieSession kSession; private DroolsTest instance; private DroolsTest(){...
You need to: import org.mule.MessageExchangePattern Otherwise your Drools MVEL script will have no idea what MessageExchangePattern.ONE_WAY is....
Some 6.x code for building: KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem(); FileInputStream fis = new FileInputStream( "sale/sale.drl" ); kfs.write( "src/main/resources/sale.drl", ks.getResources().newInputStreamResource( fis ) ); KieBuilder kieBuilder = ks.newKieBuilder( kfs ).buildAll(); Results results = kieBuilder.getResults(); if( results.hasMessages( Message.Level.ERROR ) ){ System.out.println( results.getMessages() ); throw new IllegalStateException( "### errors ###"...
The first pattern picks any TestEvent irrespective of its linkId. If there are n TestEvent facts with a certain linkId, the acivation proceeds n times. To restrict this rule to fire once you could select a single TestEvent out of any such group of n. Any attribute with a unique...
Probably worth pointing out that you're using the wrong drools-api version: <dependency> <groupId>org.drools</groupId> <artifactId>drools-api</artifactId> <version>5.1.1</version> </dependency> When everything else is referring to ${drools.version}, which is 6.1.0.Final. Note that "drools-api" is now "kie-api". The dependency you should be using is: <dependency> <groupId>org.kie</groupId> <artifactId>kie-api</artifactId>...
A DRL global is a POJO, which exists as long as there exists at least one reference to it. After setGlobal, a session keeps one (additional) reference, which is made accessible via the global's name, courtesy of the DRL compiler. If the session is disposed this reference evaporates. The term...
int nRules = 0; Collection<KiePackage> packages = kieBase.getKiePackages(); for( KiePackage pack: packages ){ nRules += pack.getRules().size(); } You can also count the rows below the header lines in your decision table: one row - one rule....
java,curl,web,drools,kie-workbench
There is a bug in UrlResource which has been fixed. See https://issues.jboss.org/browse/DROOLS-693 Here is an alternative solution: http://stackoverflow.com/a/28230876/418730...
Plain English. Let there be a purchase with a total greater than 15.- (Purchase ( total > 15)) and let's call it $p. Now, if there is another purchase (Purchase ( this != $p,) where the taco count is greater than two (tacoCount > 2)) then let's do something. I...
It's best to write this as two rules - which will happen anyway. The syntax requires you to write an infix or on the LHS as when ( Type(...) or Type(...) ) then and the prefix or as when (or Type(...) Type(...)) then neither of which is easy to achieve...
If no value is given in the column where the list of PromoCode values is provided you need another rule, i.e., the right hand side cannot contain the same statement sequence. Omit the selection mark for the RHS action, to avoid the generation of a statement referencing $code and provide...
drools,optaplanner,kie-workbench
After a while, I was able to read in a jar file that contains rules files and fact objects, then use those in solving for a plan. so, with the jar file being served, here is the code that worked for me. String url = "http://<enter url to service endpoint...
It's quite simple: whenever a fact is modified, all rules referencing that fact are evaluated again, and if the condition is true, they result in another activation. To break this vicious circle, you have several options, but using no-loop on both rules isn't one of them. First, you can add...
Through @PropertyReactive annotation; it is working as per my expectation.It is not reactivating the rule "logical insert" and not going in to loop.
The rule name is composed from the string after RuleTable, the cell indicating the start of another decision table, an underscore, and the row number. For instance: 20 RuleTable Foo 21 22 23 24 25 --------------------- results in rule Foo_25 You could produce the rule name in its row using...
There is a REST API, but it would be of no use to you. The rules don't get executed in Workbench. It's really just a repository for them. The REST API would let you download the rules, but you wouldn't be able to execute them in a .NET application. Instead...
Overloading a DRL function isn't possible in any Drools version. The usual workaround for problems with functions (there are more restrictions) is to use and import static Java methods from a class such as: public class Utils { public static String obtenirValeurParametre(String valeurActuelle, String parametre){ if(parametreEstVide(parametre)) return ""; return "*".equals(parametre)...
Finally, I have made it work. The most important mistake I was making was that I was trying to use EclipseLink as JPA provider. This approach will not work, since besides the custom persistency classes, Drools uses two other persistency-annotated classes: org.drools.persistence.info.SessionInfo and org.drools.persistence.info.WorkItemInfo. These two contain Date fields which...
If both components change from row to row, it may be useful to have two action entries. If a constant should be appended, add it in the code snippet in line 3: ACTION ACTION System.out System.out print($param) println($param + "!") part 1 part 2 "The city is: " $city.getName() "No...
Very simple: you use the conditional element not which implements the negated existential quantifier ∄. Of course, you must ascertain the absence of the negated condition, i.e. not Train( ! (driver == "Ted") && ! (driver == "Joe" && destCountry == "Scotland") && ! (driver == "Andy" && origin ==...
maven,jboss,drools,nexus,sonatype
Ok, problem resolved! It took several steps, some of which are mentioned elsewhere on stackoverflow and had already been tried unsuccessfully, but the order really mattered here: The dashboard-builder artifact was not located in Maven Central proxy, but in JBoss public proxy. That proxy needed to be created locally (it...
You can synthesize the name of a binding variable like any other chunk of text: [when][]there is a qualification of type {qualification}= ${qualification}: {qualification}() But it's going to be tricky because you'll have to make references to this variable variable variable, too: [then] print {qualification}=System.out.println( ${qualification} ); instead of the...
Perhaps like this: when $list: List() B($id: ID) from $list A(ID == $id) then Using a container as a fact is usually considered (at least by me) as being an antipattern. Things are easier if the B's are facts. A($id: ID) B(ID == $id) You can still insert the List...
This query delivers Item facts with a price < p and a score > s: query "price and score" (double p, double s) item: Item(price < p, score > s) end To compose a query as a conjunction of two queries, you must provide a variable for binding a reference...
You can use an eval: ewl: c eval(ewl.getExList().containsAll(Arrays.asList($param))) -- check ... -- "firstElement" "second","third","fourth" There is no Drools operator for set or list operations. But you could implement a custom operator. Adding a method to EntityWithList would simplify the expression. Edit: Inserted Arrays.asList...
com/sun/tools/xjc/Options.class is in the jar jaxb-xjc.jar that comes with the JAXB distribution. Normally, javax.xml.bind and the xjc tool are available via JDK and the Java binaries. But, if some application needs to call the XML Schema compiler via its API, the individual classes contained in that jar must be available.
The third column can be written as CONDITION $c2: College(stdId==$s.id)/*$param*/ match student id x x ... The x is required to trigger insertion of the conditional expression from row 2....
list,scala,drools,scala-option
Since you are doing a lot of Java and Scala interop, I suggest you make yourself very familiar with the Scala's javaconverters functionality. This handy collection of utilities allows you to convert Scala collections to Java collection and vice versa. In your case, I think you need to convert from...
optimization,drools,optaplanner
Hacking the ScoreHolder is not the way to do this (although by creating a custom ScoreDefinition you can do it that way). Instead, your rule can use an insertLogical() to insert the intermediate results as a new fact, instead of modifying the ScoreHolder directly. Then another rule matches on that...
There was a similar question posted some days ago: How to get max min item from a list in Drools There are 2 solutions posted there: Create your own accumulate function Use 2 simple patterns Following the first approach, you would need to write something like this: when $maxAssignment: ShiftAssignment()...
It is indeed a bug. The problem is in the use of "contains" : Drools (MVEL) is very liberal in assuming that properties contains "X" should be interpreted as properties.containsKey("X"). After some iterations, though, the just-in-time compilation of the constraints enforces a stricter mode, where the former expression can't be...
This isn't possible usind "collect" because multiple patterns aren't possible inside the collect CE. (Do you mean to collect A's or B's or both?) You can easily change this to accumulate which gives you full control over what is accumulated: $myFact: MyFact() $filteredListOfA: List( size > 0 ) from accumulate...
marshalling,global,drools,unmarshalling,kie
Globals are not inserted into the Working Memory, consequently they are not saved with the KieSession's state. Globals have to be inserted every time you restore KieSession's state....
This compiles with 5.5, so it shouldn't be a problem with 6.x either. The duplication of the accumulate can't be helped unless you consider a more complicated evaluation involving derived facts. rule "find best BaseUpChargeConfig" when // pick up some PricingLineItem $pli: PricingLineItem( $prefix: prefix, $ackId : ackId ) //...
It would be more convenient to create the "output object" on the right and side, and you can insert it or pass it to a global collection. The somewhat contrived workaround for including a condition for the mere presence of a fact looks like this: CONDITION $output : JSONWrapper /*$param*/...
containers,drools,workbench,kie
I ended up converting drools 6.2 to .net dll using IKVM. Here is the post that i created to show how to do it: http://droolstonet.blogspot.com/2015/05/how-to-use-drools-62-in-net-using-ikvm.html...
The difference is about the same as using String.matches( Regex regex ) versus String.contains( CharSequence charSeq ) in Java. Regular expressions need to be compiled and interpreted when evaluated against a CharSequence; looking for a substring in a string matching the given string requires less effort. And it's quite easy...