Last active
October 6, 2024 10:54
-
-
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/263a0b165c3f48c5180913f49746a2cf55ff9bf2
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.5.1" | |
//> using dep "fr.janalyse::drools-scripting:1.2.0" | |
//> using dep "org.scalatest::scalatest:3.2.19" | |
// --------------------- | |
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