Last active
June 24, 2023 16:26
-
-
Save dacr/55b8f8d90570ac6546413734d552a418 to your computer and use it in GitHub Desktop.
Simple drools backward chaining example. / published by https://github.com/dacr/code-examples-manager #5b2fc2f1-e0f3-4960-b729-7d15200e2688/5162551c896f46213d30f918bdc99a1a3269229b
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// summary : Simple drools backward chaining example. | |
// keywords : scala, drools, mvel, scalatest, ai, @testable | |
// publish : gist | |
// authors : David Crosson | |
// license : Apache NON-AI License Version 2.0 (https://raw.githubusercontent.com/non-ai-licenses/non-ai-licenses/main/NON-AI-APACHE2) | |
// id : 5b2fc2f1-e0f3-4960-b729-7d15200e2688 | |
// execution : scala ammonite script (http://ammonite.io/) - run as follow 'amm scriptname.sc' | |
// created-on : 2018-09-12T21:11:39+02:00 | |
// managed-by : https://github.com/dacr/code-examples-manager | |
// run-with : scala-cli $file | |
// --------------------- | |
//> using scala "3.3.0" | |
//> using dep "fr.janalyse::drools-scripting:1.1.0" | |
//> using dep "org.scalatest::scalatest:3.2.16" | |
// --------------------- | |
import fr.janalyse.droolscripting._, org.scalatest._, flatspec._, matchers._, OptionValues._ | |
import scala.jdk.CollectionConverters._ | |
import org.kie.api.runtime.rule.Variable | |
import DroolsEngineConfig._ | |
object SimpleDroolsBackwardChainingTest extends AnyFlatSpec with should.Matchers { | |
override val suiteName = "SimpleDroolsBackwardChainingTest" | |
"drools" should "be able to achieve backward chaining" in { | |
val drl = | |
"""package testdrools | |
| | |
| | |
|declare Someone | |
| name: String | |
| age: int | |
|end | |
| | |
|declare ParentOf | |
| child: Someone | |
| parent: Someone | |
|end | |
| | |
|rule "init" | |
|when | |
|then | |
| Someone a = new Someone("john", 12); | |
| Someone b = new Someone("sarah", 50); | |
| Someone c = new Someone("mickael", 60); | |
| ParentOf rab = new ParentOf(a, b); | |
| ParentOf rbc = new ParentOf(b, c); | |
| insert(a); | |
| insert(b); | |
| insert(c); | |
| insert(rab); | |
| insert(rbc); | |
|end | |
| | |
|query "adult" | |
| person:Someone(age>=18) | |
|end | |
| | |
|query inParented(Someone x, Someone y) | |
| ParentOf(x,y;) // ; is mandatory here | |
| or | |
| ( ParentOf(z,y;) and ?inParented(x, z;) ) | |
|end | |
| | |
|""".stripMargin | |
val engine = DroolsEngine(drl, configWithIdentity) | |
engine.fireAllRules() | |
val r = engine.session.getQueryResults("adult") | |
r.size() shouldBe 2 | |
val people = engine.getModelInstances("testdrools.Someone") | |
people.size shouldBe 3 | |
val peopleByName = | |
people | |
.groupBy(p => engine.getModelInstanceAttribute(p, "name").value) | |
.view | |
.mapValues(_.head) | |
.collect{case (name:String, someone:Object) => name -> someone} | |
.toMap | |
val john = peopleByName.get("john").value | |
val sarah = peopleByName.get("sarah").value | |
val mickael = peopleByName.get("mickael").value | |
// First check if we can find undirect parent relationship | |
val r2 = engine.session.getQueryResults("inParented", john, mickael) | |
r2.size shouldBe 1 | |
info(r2.getIdentifiers.mkString(",")) | |
info(r2.asScala.head.get("x").toString) | |
// it has returned both x and y | |
// now let's try again to see who has families using unification | |
val r3 = engine.session.getQueryResults("inParented", Variable.v, mickael) | |
r3.size shouldBe 2 | |
r3.asScala.map(_.get("x")) should contain allOf(john, sarah) | |
// So john AND sarah are in parented of mickael | |
} | |
} | |
SimpleDroolsBackwardChainingTest.execute() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment