diff --git a/reactor/Bridge/src/jetbrains/mps/logic/reactor/handler/RuleHandler.java b/reactor/Bridge/src/jetbrains/mps/logic/reactor/handler/RuleHandler.java index 5100868d..8029cf48 100644 --- a/reactor/Bridge/src/jetbrains/mps/logic/reactor/handler/RuleHandler.java +++ b/reactor/Bridge/src/jetbrains/mps/logic/reactor/handler/RuleHandler.java @@ -19,6 +19,9 @@ public abstract class RuleHandler { public abstract void setRules(@NotNull Iterable rules); + @NotNull + public abstract Iterable rules(); + /** * SPI */ diff --git a/reactor/Core/src/jetbrains/mps/logicl/reactor/core/RuleHandler.kt b/reactor/Core/src/jetbrains/mps/logicl/reactor/core/RuleHandler.kt index 6cc0250e..584e5048 100644 --- a/reactor/Core/src/jetbrains/mps/logicl/reactor/core/RuleHandler.kt +++ b/reactor/Core/src/jetbrains/mps/logicl/reactor/core/RuleHandler.kt @@ -22,6 +22,10 @@ class RuleHandlerImpl : RuleHandler() { } } + override fun rules(): MutableIterable { + return myRules + } + companion object { fun init() { setOurCompanion (object : RuleHandler.Companion { diff --git a/reactor/Test/test/Rules.kt b/reactor/Test/test/Rules.kt new file mode 100644 index 00000000..d8933796 --- /dev/null +++ b/reactor/Test/test/Rules.kt @@ -0,0 +1,78 @@ +import jetbrains.mps.logic.reactor.constraint.occurrence.AbstractConstraintOccurrence +import jetbrains.mps.logic.reactor.constraint.occurrence.ConstraintOccurrence +import jetbrains.mps.logic.reactor.rule.Rule +import jetbrains.mps.logic.reactor.rule.RuleBuilder +import java.util.* +import kotlin.reflect.KClass + +/** + * @author Fedor Isakov + */ + +fun rule(tag: String, vararg component:RB.() -> Unit): Rule { + val rb = RB(tag) + for (cmp in component) { + rb.cmp() + } + return rb.toRule() +} + +fun headKept(vararg content : ConjBuilder.() -> Unit): RB.() -> Unit = { + appendHeadKept( * buildConjunction(ConstraintOccurrence::class.java, content).toArray()) +} +fun headReplaced(vararg content : ConjBuilder.() -> Unit): RB.() -> Unit = { + appendHeadKept( * buildConjunction(ConstraintOccurrence::class.java, content).toArray()) +} +fun guard(vararg content : ConjBuilder.() -> Unit): RB.() -> Unit = { + appendGuard( * buildConjunction(AbstractConstraintOccurrence::class.java, content).toArray()) +} +fun body(vararg content : ConjBuilder.() -> Unit): RB.() -> Unit = { + appendBody( * buildConjunction(AbstractConstraintOccurrence::class.java, content).toArray()) +} + +fun constraint(id: String): ConjBuilder.() -> Unit = { + add(ConstraintOccurrence.singleton(id)) +} +fun constraint(id: String, arg: Any): ConjBuilder.() -> Unit = { + add(ConstraintOccurrence.unitary(id, arg)) +} +fun constraint(id: String, arg1: Any, arg2: Any): ConjBuilder.() -> Unit = { + add(ConstraintOccurrence.binary(id, arg1, arg2)) +} +fun constraint(id: String, arg1: Any, arg2: Any, arg3: Any): ConjBuilder.() -> Unit = { + add(ConstraintOccurrence.ternary(id, arg1, arg2, arg3)) +} +fun constraint(id: String, args: Array): ConjBuilder.() -> Unit = { + add(ConstraintOccurrence.nary(id, * args)) +} + +class RB(tag: String) : RuleBuilder(tag) {} + +class ConjBuilder (val type: Class) { + val constraints = ArrayList() + fun add(constraint: AbstractConstraintOccurrence): Unit { + if (!type.isAssignableFrom(constraint.javaClass)) + throw IllegalArgumentException("unexpected constraint class '${constraint.javaClass}'") + constraints.add(constraint) + } + fun toArray(): Array = + if (ConstraintOccurrence::class.java.isAssignableFrom(type)) + Array(constraints.size) { + constraints.get(it) as ConstraintOccurrence + } as Array + else + Array(constraints.size) { + constraints.get(it) + } as Array +} + +private fun + buildConjunction(type: Class, content: Array Unit>): ConjBuilder +{ + var conjBuilder = ConjBuilder(type) + for (c in content) { + conjBuilder.c() + } + return conjBuilder +} + diff --git a/reactor/Test/test/TestRuleHandler.kt b/reactor/Test/test/TestRuleHandler.kt index b15f3a4c..f38f5677 100644 --- a/reactor/Test/test/TestRuleHandler.kt +++ b/reactor/Test/test/TestRuleHandler.kt @@ -1,9 +1,13 @@ import jetbrains.mps.logic.reactor.handler.RuleHandler +import jetbrains.mps.logic.reactor.rule.InvalidRuleException import jetbrains.mps.logicl.reactor.core.RuleHandlerImpl import org.junit.Before import org.junit.BeforeClass import org.junit.Test import java.util.* +import kotlin.reflect.KClass +import kotlin.test.assertEquals +import kotlin.test.expect /** * @author Fedor Isakov @@ -17,10 +21,48 @@ class Simple { } } + @Before fun beforeTest() { + handler = RuleHandler.with().newHandler() + } + + lateinit var handler:RuleHandler + + @Test fun empty() { - val handler = RuleHandler.with().newHandler() handler.setRules(ArrayList()) } + + @Test(expected = InvalidRuleException::class) + fun emptyBody() { + handler.setRules(arrayListOf( + rule("foo", + headKept( + constraint("bar") + )) + )) + } + + @Test + fun replace() { + handler.setRules(arrayListOf( + rule("foo", + headReplaced( + constraint("bar") + ), + body( + constraint("baz") + )) + )) + val sb = StringBuilder() + + handler.rules().forEach { + sb.append(it.tag()).append(": ") + it.all().joinTo(sb, ", ") + sb.append(";") + } + + assertEquals("foo", sb.toString()) + } }