Initial support for logicals. Small refactoring in tests.

This commit is contained in:
Fedor Isakov 2015-12-10 12:56:45 +01:00
parent fc372c1420
commit d15f6908d5
9 changed files with 500 additions and 253 deletions

View File

@ -65,14 +65,7 @@ class RuleHandler {
private fun activate(constraint: Constraint): ConstraintOccurrence = occurrenceFactory(constraint)
private fun tellPredicate(predicate: Predicate) {
when (predicate.symbol()) {
is JavaPredicateSymbol -> evalJava(predicate)
else -> TODO()
}
}
private fun evalJava(expr: Predicate) {
sessionSolver.tell(expr.symbol(), * expr.arguments().toTypedArray())
sessionSolver.tell(predicate.symbol(), * predicate.arguments().toTypedArray())
}
fun lookupMatches(occ: ConstraintOccurrence): Iterable<PartialMatch> {

View File

@ -6,17 +6,7 @@ import jetbrains.mps.logic.reactor.constraint.*
* @author Fedor Isakov
*/
class ReactorSessionSolver(val expressionSolver: Queryable) : SessionSolver() {
constructor() : this(object: Queryable {
override fun ask(predicateSymbol: PredicateSymbol?, vararg args: Any?): Boolean {
throw UnsupportedOperationException()
}
override fun tell(symbol: Symbol?, vararg args: Any?) {
throw UnsupportedOperationException()
}
})
class ReactorSessionSolver(val expressionSolver: Queryable, val equalsSolver: Queryable) : SessionSolver() {
override fun solverClass(predicateSymbol: PredicateSymbol?): Class<out Queryable>? {
throw UnsupportedOperationException()
@ -24,8 +14,9 @@ class ReactorSessionSolver(val expressionSolver: Queryable) : SessionSolver() {
override fun registerSymbol(predicateSymbol: PredicateSymbol, computingTracer: ComputingTracer?) {
when (predicateSymbol) {
is JavaPredicateSymbol -> registerSolver(predicateSymbol, expressionSolver)
else -> throw UnsupportedOperationException("not implemented")
is JavaPredicateSymbol -> registerSolver(predicateSymbol, expressionSolver)
PredicateSymbol("equals", 2) -> registerSolver(predicateSymbol, equalsSolver)
else -> throw UnsupportedOperationException("not implemented")
}
}

View File

@ -0,0 +1,104 @@
import jetbrains.mps.logic.reactor.constraint.*
import java.util.*
/**
* @author Fedor Isakov
*/
fun expression(body: () -> Boolean): ConjBuilder.() -> Unit = {
add(TestJavaPredicate(JavaPredicateSymbol(1),body))
}
fun expression(body: (Any) -> Boolean, vararg args: Any): ConjBuilder.() -> Unit = {
add(TestJavaPredicate(JavaPredicateSymbol(2), body, * args))
}
fun expression(body: (Any, Any) -> Boolean, vararg args: Any): ConjBuilder.() -> Unit = {
add(TestJavaPredicate(JavaPredicateSymbol(3), body, * args))
}
fun expression(body: (Any, Any, Any) -> Boolean, vararg args: Any): ConjBuilder.() -> Unit = {
add(TestJavaPredicate(JavaPredicateSymbol(4), body, * args))
}
class ExpressionSolver : Queryable {
override fun ask(predicateSymbol: PredicateSymbol, vararg args: Any): Boolean {
return javaPredicates[predicateSymbol]?.expr?.invoke(listOf(* args)) ?:
ERROR("no such symbol $predicateSymbol")
}
override fun tell(symbol: Symbol, vararg args: Any) {
when (symbol) {
is JavaPredicateSymbol -> javaPredicates[args[0]]?.expr?.invoke(listOf(* args).drop(1))
else -> ERROR("uknown symbol $symbol")
}
}
fun addMaybeJavaPredicate(item: AndItem) {
if (item is TestJavaPredicate) {
addJavaPredicate(item)
}
}
private val javaPredicates = HashMap<Any, TestJavaPredicate>()
private fun addJavaPredicate(javaPredicate: TestJavaPredicate) {
javaPredicates[javaPredicate.args[0]] = javaPredicate
}
private fun ERROR(msg: String) : Nothing = throw IllegalArgumentException(msg)
}
private interface JavaExpression {
fun invoke(args: List<Any>): Boolean
}
private class JavaExpression0(val code: () -> Boolean) : JavaExpression {
override fun invoke(args: List<Any>): Boolean {
if (args.size != 0) throw IllegalArgumentException("arity mismatch")
return code()
}
}
private class JavaExpression1(val code: (Any) -> Boolean) : JavaExpression {
override fun invoke(args: List<Any>): Boolean {
if (args.size != 1) throw IllegalArgumentException("arity mismatch")
return code(args[0])
}
}
private class JavaExpression2(val code: (Any, Any) -> Boolean) : JavaExpression {
override fun invoke(args: List<Any>): Boolean {
if (args.size != 2) throw IllegalArgumentException("arity mismatch")
return code(args[0], args[1])
}
}
private class JavaExpression3(val code: (Any, Any, Any) -> Boolean) : JavaExpression {
override fun invoke(args: List<Any>): Boolean {
if (args.size != 3) throw IllegalArgumentException("arity mismatch")
return code(args[0], args[1], args[2])
}
}
private data class TestJavaPredicate(val symbol: JavaPredicateSymbol, val expr: JavaExpression, val args: List<Any>) : Predicate {
constructor(symbol: JavaPredicateSymbol, code: () -> Boolean, vararg args: Any) :
this(symbol, JavaExpression0(code), listOf(code.toString()) + listOf(* args)) {}
constructor(symbol: JavaPredicateSymbol, code: (Any) -> Boolean, vararg args: Any) :
this(symbol, JavaExpression1(code), listOf(code.toString()) + listOf(* args)) {}
constructor(symbol: JavaPredicateSymbol, code: (Any, Any) -> Boolean, vararg args: Any) :
this(symbol, JavaExpression2(code), listOf(code.toString()) + listOf(* args)) {}
constructor(symbol: JavaPredicateSymbol, code: (Any, Any, Any) -> Boolean, vararg args: Any) :
this(symbol, JavaExpression3(code), listOf(code.toString()) + listOf(* args)) {}
override fun arguments(): List<Any> = args
override fun symbol(): PredicateSymbol = symbol
}

View File

@ -0,0 +1,161 @@
import jetbrains.mps.logic.reactor.constraint.Predicate
import jetbrains.mps.logic.reactor.constraint.PredicateSymbol
import jetbrains.mps.logic.reactor.constraint.Queryable
import jetbrains.mps.logic.reactor.constraint.Symbol
import jetbrains.mps.logic.reactor.logical.ILogical
import jetbrains.mps.logic.reactor.logical.NamingContext
/**
* @author Fedor Isakov
*/
fun logical(name: String) = TestLogical<Any>(name)
fun logical(name1: String, name2: String) = Pair(TestLogical<Any>(name1), TestLogical<Any>(name2))
fun logical(name1: String, name2: String, name3: String) = Triple(TestLogical<Any>(name1), TestLogical<Any>(name2), TestLogical<Any>(name3))
fun setValue(logical: Any, value: Any) { (logical as TestLogical<Any>).find().value = value }
fun getValue(logical: Any) = (logical as TestLogical<Any>).find().value()
class EqualsSolver : Queryable {
override fun ask(predicateSymbol: PredicateSymbol?, vararg args: Any?): Boolean {
if (args.size != 2) ERROR("arity mismatch")
val left = args[0]
val right = args[1]
return if (left is TestLogical<*> && right is TestLogical<*>) {
ask_logical_logical(left, right)
}
else if (left is TestLogical<*>) {
ask_logical_value(left, right)
}
else if (right is TestLogical<*>) {
ask_value_logical(left, right)
}
else {
ask_value_value(left, right)
}
}
override fun tell(symbol: Symbol, vararg args: Any) {
if (args.size != 2) ERROR("arity mismatch")
val left = args[0]
val right = args[1]
if (left is TestLogical<*> && right is TestLogical<*>) {
tell_logical_logical(left, right)
}
else if (left is TestLogical<*>) {
tell_logical_value(left, right)
}
else if (right is TestLogical<*>) {
tell_value_logical(left, right)
}
else {
tell_value_value(left, right)
}
}
fun ask_logical_logical(left: TestLogical<*>, right: TestLogical<*>): Boolean {
return left.isBound && right.isBound && left.findRoot().value() == right.findRoot().value()
}
fun ask_logical_value(left: TestLogical<*>, right: Any?): Boolean {
return left.isBound && left.findRoot().value() == right
}
fun ask_value_logical(left: Any?, right: TestLogical<*>): Boolean {
return right.isBound && right.findRoot().value() == left
}
fun ask_value_value(left: Any?, right: Any?): Boolean {
return left == right
}
fun tell_logical_logical(left: TestLogical<*>, right: TestLogical<*>) {
if (left.isBound && right.isBound) {
check (left.find().value == right.find().value)
left.union(right)
}
else if (left.isBound) {
right.union(left)
}
else if (right.isBound) {
left.union(right)
}
else {
left.union(right)
}
}
fun tell_logical_value(left: TestLogical<*>, right: Any?) {
if (left.isBound) {
check(left.find().value == right)
}
else {
// TODO hack!
(left.find() as TestLogical<Any>).value = right
}
}
fun tell_value_logical(left: Any?, right: TestLogical<*>) {
if (right.isBound) {
check(right.find().value == left)
}
else {
// TODO: hack!
(right.find() as TestLogical<Any>).value = left
}
}
fun tell_value_value(left: Any?, right: Any?) {
check(left == right)
}
private fun check(condition: Boolean) {
if (!condition) throw IllegalStateException()
}
private fun ERROR(msg: String) : Nothing = throw IllegalArgumentException(msg)
}
data class TestLogical<T>(val name: String, var value: T?, var parent: TestLogical<T>?) : ILogical<T> {
constructor(name: String) : this(name, null, null) {}
override fun name(): String = name
override fun name(namingContext: NamingContext?): String? {
throw UnsupportedOperationException()
}
override fun findRoot(): ILogical<T> = find()
override fun value(): T? = value
override fun isBound(): Boolean = find().value != null
override fun isWildcard(): Boolean {
throw UnsupportedOperationException()
}
fun find(): TestLogical<T> {
val tmp = parent
if (tmp == null) return this
else {
val root = tmp.find()
this.parent = root
return root
}
}
fun union(other: TestLogical<T>) {
if (find() != other.find()) find().parent = other
}
}
data class TestEqPredicate(val left: Any, val right: Any) : Predicate {
override fun arguments(): List<Any> = listOf(left, right)
override fun symbol(): PredicateSymbol = PredicateSymbol("equals", 2)
}

View File

@ -1,219 +0,0 @@
import jetbrains.mps.logic.reactor.constraint.*
import jetbrains.mps.logic.reactor.rule.Rule
import jetbrains.mps.logic.reactor.rule.RuleBuilder
import java.util.*
/**
* @author Fedor Isakov
*/
fun program(vararg ruleBuilders : Environment.() -> Rule): Program {
val env = Environment()
val rules = ArrayList<Rule>()
with (env) {
for (rb in ruleBuilders) {
rules.add(rb())
}
}
return Program(env, rules)
}
fun rule(tag: String, vararg component:RB.() -> Unit): Environment.() -> Rule = {
rule(tag, this, * component)
}
fun rule(tag: String, env: Environment, vararg component:RB.() -> Unit): Rule {
val rb = RB(tag, env)
for (cmp in component) {
rb.cmp()
}
return rb.toRule()
}
fun headKept(vararg content : ConjBuilder.() -> Unit): RB.() -> Unit = {
appendHeadKept( * buildConjunction(Constraint::class.java, env, content).toArray())
}
fun headReplaced(vararg content : ConjBuilder.() -> Unit): RB.() -> Unit = {
appendHeadReplaced( * buildConjunction(Constraint::class.java, env, content).toArray())
}
fun guard(vararg content : ConjBuilder.() -> Unit): RB.() -> Unit = {
appendGuard( * buildConjunction(Predicate::class.java, env, content).toArray())
}
fun body(vararg content : ConjBuilder.() -> Unit): RB.() -> Unit = {
appendBody( * buildConjunction(AndItem::class.java, env, content).toArray())
}
fun constraint(id: String, vararg args: Any): ConjBuilder.() -> Unit = {
add(TestConstraint(ConstraintSymbol.symbol(id, args.size), * args))
}
fun expression(body: () -> Boolean): ConjBuilder.() -> Unit = {
add(TestJavaPredicate(JavaPredicateSymbol(1),body))
}
fun expression(body: (Any) -> Boolean, vararg args: Any): ConjBuilder.() -> Unit = {
add(TestJavaPredicate(JavaPredicateSymbol(2), body, * args))
}
fun expression(body: (Any, Any) -> Boolean, vararg args: Any): ConjBuilder.() -> Unit = {
add(TestJavaPredicate(JavaPredicateSymbol(3), body, * args))
}
fun expression(body: (Any, Any, Any) -> Boolean, vararg args: Any): ConjBuilder.() -> Unit = {
add(TestJavaPredicate(JavaPredicateSymbol(4), body, * args))
}
class Program(val env: Environment, val rules: List<Rule>) {
fun occurrenceFactory() : (Constraint) -> ConstraintOccurrence = { cst -> TestOccurrence(cst) }
}
class Environment() {
val javaPredicates = HashMap<Any, TestJavaPredicate>()
fun expressionSolver(): Queryable = object : Queryable {
override fun ask(predicateSymbol: PredicateSymbol, vararg args: Any): Boolean {
return javaPredicates[predicateSymbol]?.expr?.invoke(listOf(* args)) ?:
ERROR("no such symbol $predicateSymbol")
}
override fun tell(symbol: Symbol, vararg args: Any) {
when (symbol) {
is JavaPredicateSymbol -> javaPredicates[args[0]]?.expr?.invoke(listOf(* args).drop(1))
else -> ERROR("uknown symbol $symbol")
}
}
private fun ERROR(msg: String) : Nothing = throw IllegalArgumentException(msg)
}
fun addJavaPredicate(javaPredicate: TestJavaPredicate) {
javaPredicates[javaPredicate.args[0]] = javaPredicate
}
}
class RB(tag: String, val env: Environment?) : RuleBuilder(tag) {}
class ConjBuilder {
val constraints = ArrayList<AndItem>()
val type: Class<out AndItem>
val _env: Environment?
val env: Environment
get() { return _env ?: throw IllegalStateException("no enviroment") }
constructor(type: Class<out AndItem>, env: Environment?) {
this.type = type
this._env = env
}
fun add(item: AndItem): Unit {
if (!type.isAssignableFrom(item.javaClass))
throw IllegalArgumentException("unexpected constraint class '${item.javaClass}'")
constraints.add(item)
if (item is TestJavaPredicate) {
env.addJavaPredicate(item)
}
}
fun <T : AndItem> toArray(): Array<T> =
if (Constraint::class.java.isAssignableFrom(type))
Array<Constraint>(constraints.size) {
constraints.get(it) as Constraint
} as Array<T>
else
Array<AndItem>(constraints.size) {
constraints.get(it)
} as Array<T>
}
private fun buildConjunction(type: Class<out AndItem>,
env: Environment?,
content: Array<out ConjBuilder.() -> Unit>): ConjBuilder
{
var conjBuilder = ConjBuilder(type, env)
for (c in content) {
conjBuilder.c()
}
return conjBuilder
}
data class TestOccurrence(val arguments : List<Any>, val constraint : Constraint) : ConstraintOccurrence {
constructor(id: String, vararg args: Any) :
this(listOf(* args), TestConstraint(ConstraintSymbol.symbol(id, args.size))) {}
constructor(constraint: Constraint) : this(constraint.arguments(), constraint) {}
override fun constraint(): Constraint = constraint
override fun arguments(): List<Any> = arguments
override fun toString(): String = "#${constraint().symbol()}(${arguments().joinToString()})"
}
data class TestConstraint(val symbol: ConstraintSymbol, val arguments: List<Any>) : Constraint {
constructor(symbol: ConstraintSymbol, vararg args: Any) : this(symbol, listOf(* args)) {}
override fun arguments(): List<Any> = arguments
override fun symbol(): ConstraintSymbol = symbol
override fun argumentTypes(): List<Class<*>> = arguments.map { arg -> arg.javaClass }
override fun toString(): String = "${symbol()}(${arguments().joinToString()})"
}
interface JavaExpression {
fun invoke(args: List<Any>): Boolean
}
class JavaExpression0(val code: () -> Boolean) : JavaExpression {
override fun invoke(args: List<Any>): Boolean {
if (args.size != 0) throw IllegalArgumentException("arity mismatch")
return code()
}
}
class JavaExpression1(val code: (Any) -> Boolean) : JavaExpression {
override fun invoke(args: List<Any>): Boolean {
if (args.size != 1) throw IllegalArgumentException("arity mismatch")
return code(args[0])
}
}
class JavaExpression2(val code: (Any, Any) -> Boolean) : JavaExpression {
override fun invoke(args: List<Any>): Boolean {
if (args.size != 2) throw IllegalArgumentException("arity mismatch")
return code(args[0], args[1])
}
}
class JavaExpression3(val code: (Any, Any, Any) -> Boolean) : JavaExpression {
override fun invoke(args: List<Any>): Boolean {
if (args.size != 3) throw IllegalArgumentException("arity mismatch")
return code(args[0], args[1], args[2])
}
}
data class TestJavaPredicate(val symbol: JavaPredicateSymbol, val expr: JavaExpression, val args: List<Any>) : Predicate {
constructor(symbol: JavaPredicateSymbol, code: () -> Boolean, vararg args: Any) :
this(symbol, JavaExpression0(code), listOf(code.toString()) + listOf(* args)) {}
constructor(symbol: JavaPredicateSymbol, code: (Any) -> Boolean, vararg args: Any) :
this(symbol, JavaExpression1(code), listOf(code.toString()) + listOf(* args)) {}
constructor(symbol: JavaPredicateSymbol, code: (Any, Any) -> Boolean, vararg args: Any) :
this(symbol, JavaExpression2(code), listOf(code.toString()) + listOf(* args)) {}
constructor(symbol: JavaPredicateSymbol, code: (Any, Any, Any) -> Boolean, vararg args: Any) :
this(symbol, JavaExpression3(code), listOf(code.toString()) + listOf(* args)) {}
override fun arguments(): List<Any> = args
override fun symbol(): PredicateSymbol = symbol
}

View File

@ -0,0 +1,141 @@
import jetbrains.mps.logic.reactor.constraint.*
import jetbrains.mps.logic.reactor.logical.ILogical
import jetbrains.mps.logic.reactor.logical.NamingContext
import jetbrains.mps.logic.reactor.rule.Rule
import jetbrains.mps.logic.reactor.rule.RuleBuilder
import java.util.*
/**
* @author Fedor Isakov
*/
class Program(val env: Environment, val rules: List<Rule>) {
fun occurrenceFactory() : (Constraint) -> ConstraintOccurrence = { cst -> TestOccurrence(cst) }
}
class Environment() {
val equalsSolver = EqualsSolver()
val expressionSolver = ExpressionSolver()
}
fun program(vararg ruleBuilders : Environment.() -> Rule): Program {
val env = Environment()
val rules = ArrayList<Rule>()
with (env) {
for (rb in ruleBuilders) {
rules.add(rb())
}
}
return Program(env, rules)
}
fun rule(tag: String, vararg component:RB.() -> Unit): Environment.() -> Rule = {
rule(tag, this, * component)
}
fun rule(tag: String, env: Environment, vararg component:RB.() -> Unit): Rule {
val rb = RB(tag, env)
for (cmp in component) {
rb.cmp()
}
return rb.toRule()
}
fun headKept(vararg content : ConjBuilder.() -> Unit): RB.() -> Unit = {
appendHeadKept( * buildConjunction(Constraint::class.java, env, content).toArray())
}
fun headReplaced(vararg content : ConjBuilder.() -> Unit): RB.() -> Unit = {
appendHeadReplaced( * buildConjunction(Constraint::class.java, env, content).toArray())
}
fun guard(vararg content : ConjBuilder.() -> Unit): RB.() -> Unit = {
appendGuard( * buildConjunction(Predicate::class.java, env, content).toArray())
}
fun body(vararg content : ConjBuilder.() -> Unit): RB.() -> Unit = {
appendBody( * buildConjunction(AndItem::class.java, env, content).toArray())
}
fun constraint(id: String, vararg args: Any): ConjBuilder.() -> Unit = {
add(TestConstraint(ConstraintSymbol(id, args.size), * args))
}
fun equals(left: Any, right: Any): ConjBuilder.() -> Unit = {
add(TestEqPredicate(left, right))
}
fun occurrence(id: String, vararg args: Any) : ConstraintOccurrence = TestOccurrence(id, * args)
class RB(tag: String, val env: Environment?) : RuleBuilder(tag) {}
class ConjBuilder {
val constraints = ArrayList<AndItem>()
val type: Class<out AndItem>
val _env: Environment?
val env: Environment
get() { return _env ?: throw IllegalStateException("no enviroment") }
constructor(type: Class<out AndItem>, env: Environment?) {
this.type = type
this._env = env
}
fun add(item: AndItem): Unit {
if (!type.isAssignableFrom(item.javaClass))
throw IllegalArgumentException("unexpected constraint class '${item.javaClass}'")
constraints.add(item)
env.expressionSolver.addMaybeJavaPredicate(item)
}
fun <T : AndItem> toArray(): Array<T> =
if (Constraint::class.java.isAssignableFrom(type))
Array<Constraint>(constraints.size) {
constraints.get(it) as Constraint
} as Array<T>
else
Array<AndItem>(constraints.size) {
constraints.get(it)
} as Array<T>
}
private fun buildConjunction(type: Class<out AndItem>,
env: Environment?,
content: Array<out ConjBuilder.() -> Unit>): ConjBuilder
{
var conjBuilder = ConjBuilder(type, env)
for (c in content) {
conjBuilder.c()
}
return conjBuilder
}
private data class TestOccurrence(val arguments : List<Any>, val constraint : Constraint) : ConstraintOccurrence {
constructor(id: String, vararg args: Any) :
this(listOf(* args), TestConstraint(ConstraintSymbol.symbol(id, args.size))) {}
constructor(constraint: Constraint) : this(constraint.arguments(), constraint) {}
override fun constraint(): Constraint = constraint
override fun arguments(): List<Any> = arguments
override fun toString(): String = "#${constraint().symbol()}(${arguments().joinToString()})"
}
private data class TestConstraint(val symbol: ConstraintSymbol, val arguments: List<Any>) : Constraint {
constructor(symbol: ConstraintSymbol, vararg args: Any) : this(symbol, listOf(* args)) {}
override fun arguments(): List<Any> = arguments
override fun symbol(): ConstraintSymbol = symbol
override fun argumentTypes(): List<Class<*>> = arguments.map { arg -> arg.javaClass }
override fun toString(): String = "${symbol()}(${arguments().joinToString()})"
}

View File

@ -1,3 +1,6 @@
import jetbrains.mps.logic.reactor.constraint.PredicateSymbol
import jetbrains.mps.logic.reactor.constraint.Queryable
import jetbrains.mps.logic.reactor.constraint.Symbol
import jetbrains.mps.logic.reactor.core.ReactorEvaluationSession
import jetbrains.mps.logic.reactor.core.ReactorPlanningSession
import jetbrains.mps.logic.reactor.predicate.ReactorSessionSolver
@ -26,8 +29,13 @@ class TestBasicProgram {
}
}
val dummySolver = object : Queryable {
override fun ask(predicateSymbol: PredicateSymbol?, vararg args: Any?): Boolean = TODO()
override fun tell(symbol: Symbol?, vararg args: Any?) = TODO()
}
@Before fun beforeTest() {
planningSession = PlanningSession.newSession("test", ReactorSessionSolver())
planningSession = PlanningSession.newSession("test", ReactorSessionSolver(dummySolver, dummySolver))
evalConfig = EvaluationSession.newSession(planningSession)
}

View File

@ -1,3 +1,6 @@
import jetbrains.mps.logic.reactor.constraint.PredicateSymbol
import jetbrains.mps.logic.reactor.constraint.Queryable
import jetbrains.mps.logic.reactor.constraint.Symbol
import jetbrains.mps.logic.reactor.program.PlanningSession
import jetbrains.mps.logic.reactor.rule.InvalidConstraintException
import jetbrains.mps.logic.reactor.rule.InvalidRuleException
@ -23,8 +26,13 @@ class TestPlanningSession {
}
}
val dummySolver = object : Queryable {
override fun ask(predicateSymbol: PredicateSymbol?, vararg args: Any?): Boolean = TODO()
override fun tell(symbol: Symbol?, vararg args: Any?) = TODO()
}
@Before fun beforeTest() {
session = PlanningSession.newSession("test", ReactorSessionSolver())
session = PlanningSession.newSession("test", ReactorSessionSolver(dummySolver, dummySolver))
}
lateinit var session: PlanningSession

View File

@ -1,8 +1,6 @@
import jetbrains.mps.logic.reactor.constraint.ConstraintOccurrence
import jetbrains.mps.logic.reactor.constraint.JavaPredicateSymbol
import jetbrains.mps.logic.reactor.constraint.Queryable
import jetbrains.mps.logic.reactor.constraint.SessionSolver
import jetbrains.mps.logic.reactor.constraint.*
import jetbrains.mps.logic.reactor.core.RuleHandler
import jetbrains.mps.logic.reactor.logical.ILogical
import jetbrains.mps.logic.reactor.predicate.ReactorSessionSolver
import org.junit.Before
import org.junit.BeforeClass
@ -18,13 +16,12 @@ import kotlin.test.assertTrue
class TestRuleHandler {
fun occurrence(id: String, vararg args: Any) : TestOccurrence = TestOccurrence(id, * args)
fun sessionSolver(exprSolver: Queryable) : SessionSolver =
ReactorSessionSolver(exprSolver).apply { init(JavaPredicateSymbol.EXPRESSION0, JavaPredicateSymbol.EXPRESSION1, JavaPredicateSymbol.EXPRESSION2, JavaPredicateSymbol.EXPRESSION3) }
fun sessionSolver(exprSolver: Queryable, equalsSolver: Queryable) : SessionSolver =
ReactorSessionSolver(exprSolver, equalsSolver).apply {
init(PredicateSymbol("equals",2), JavaPredicateSymbol.EXPRESSION0, JavaPredicateSymbol.EXPRESSION1, JavaPredicateSymbol.EXPRESSION2, JavaPredicateSymbol.EXPRESSION3) }
fun Program.handler(vararg occurrences: ConstraintOccurrence): RuleHandler =
RuleHandler(sessionSolver(env.expressionSolver()), rules, occurrenceFactory(), listOf(* occurrences))
RuleHandler(sessionSolver(env.expressionSolver, env.equalsSolver), rules, occurrenceFactory(), listOf(* occurrences))
companion object {
@BeforeClass @JvmStatic fun setup() {
@ -135,7 +132,7 @@ class TestRuleHandler {
constraint("bar")
))).run {
val matches = handler(TestOccurrence("aux")).lookupMatches(occurrence("main"))
val matches = handler(occurrence("aux")).lookupMatches(occurrence("main"))
assertFalse { matches.any { m -> m.isPartial() } }
assertEquals(rules, matches.map { m -> m.rule })
@ -252,9 +249,72 @@ class TestRuleHandler {
))).run {
val result = handler().process(occurrence("main"))
assertEquals("value", test)
}
}
@Test
fun paramExpression() {
var test : String = "not initialized"
program(
rule("main",
headKept(
constraint("main")
),
body(
expression ({ v -> test = v as String; true }, "value")
))).run {
val result = handler().process(occurrence("main"))
assertEquals("value", test)
}
}
@Test
fun basicLogical() {
var test : String? = "not initialized"
val x = logical("x")
x.value = "expected"
program(
rule("main",
headKept(
constraint("main")
),
body(
expression ({ v -> test = (v as ILogical<String>).value(); true }, x)
))).run {
val result = handler().process(occurrence("main"))
assertEquals("expected", test)
}
}
@Test
fun logicalCopy() {
var test : String? = "not initialized"
val (x,y) = logical("x", "y")
x.value = "expected"
program(
rule("main",
headKept(
constraint("main")
),
body(
equals(x, y),
constraint("next")
)),
rule("aux",
headKept(
constraint("next")
),
body(
expression ({ v -> test = getValue(v) as String; true }, y)
))).run {
handler().apply { process(occurrence("main")) }.run {
assertEquals(setOf(occurrence("main"), occurrence("next")), occurrences())
}
assertEquals("expected", test)
}
}