178 lines
6.0 KiB
Kotlin
178 lines
6.0 KiB
Kotlin
import jetbrains.mps.logic.reactor.core.ReactorLifecycle
|
|
import jetbrains.mps.logic.reactor.evaluation.EvaluationSession
|
|
import jetbrains.mps.logic.reactor.evaluation.StoreView
|
|
import jetbrains.mps.logic.reactor.logical.Logical
|
|
import jetbrains.mps.logic.reactor.program.Constraint
|
|
import jetbrains.mps.logic.reactor.program.ConstraintSymbol
|
|
import org.junit.AfterClass
|
|
import org.junit.Assert.assertEquals
|
|
import org.junit.BeforeClass
|
|
import org.junit.Test
|
|
import program.MockConstraint
|
|
import solver.eq
|
|
|
|
/**
|
|
* @author Fedor Isakov
|
|
*/
|
|
|
|
class TestProgram {
|
|
|
|
companion object {
|
|
@BeforeClass
|
|
@JvmStatic
|
|
fun setup() {
|
|
ReactorLifecycle.init();
|
|
}
|
|
|
|
@AfterClass
|
|
@JvmStatic
|
|
fun teardown() {
|
|
ReactorLifecycle.deinit();
|
|
}
|
|
}
|
|
|
|
private fun Builder.session(name: String): StoreView {
|
|
val programBuilder = ProgramBuilder(MockConstraintRegistry())
|
|
for (h in handlers) {
|
|
programBuilder.addHandler(h)
|
|
}
|
|
val session = EvaluationSession.newSession(programBuilder.program(name))
|
|
.withParameter(EvaluationSession.ParameterKey.of("main", Constraint::class.java), MockConstraint(ConstraintSymbol("main", 0)))
|
|
.start()
|
|
return session.storeView()
|
|
}
|
|
|
|
@Test
|
|
fun replace() {
|
|
programWithRules(
|
|
rule("main",
|
|
headReplaced(
|
|
constraint("main")
|
|
),
|
|
body(
|
|
constraint("foo")
|
|
)),
|
|
rule("main.foo",
|
|
headKept(
|
|
constraint("foo")
|
|
),
|
|
body(
|
|
constraint("bar")
|
|
)
|
|
)
|
|
).session("replace").run {
|
|
assertEquals(setOf(ConstraintSymbol("foo", 0), ConstraintSymbol("bar", 0)), constraintSymbols())
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun logicalValue() {
|
|
val (X, Y, Z) = metaLogical<Int>("X", "Y", "Z")
|
|
programWithRules(
|
|
rule("main",
|
|
headReplaced(
|
|
constraint("main")
|
|
),
|
|
body(
|
|
statement({ z -> z eq 33 }, Z),
|
|
constraint("foo", Z)
|
|
)
|
|
),
|
|
rule("rule1",
|
|
headKept(
|
|
constraint("foo", X)
|
|
),
|
|
body(
|
|
statement({ x, y -> y eq (x.get() * 2) }, X, Y),
|
|
constraint("bar", Y)
|
|
)
|
|
)
|
|
).session("logicalValue").run {
|
|
assertEquals(setOf(ConstraintSymbol("foo", 1), ConstraintSymbol("bar", 1)), constraintSymbols())
|
|
assertEquals(2, allOccurrences().count())
|
|
val yval = occurrences(ConstraintSymbol("bar", 1)).first().arguments().first()
|
|
assertEquals(66, (yval as Logical<Int>).get())
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun simpleProgram() {
|
|
val (X, Y) = metaLogical<Int>("X", "Y")
|
|
|
|
programWithRules(
|
|
rule("main",
|
|
headReplaced(constraint("main")), body(statement({ x -> x.set(5) }, X),
|
|
constraint("val", X))
|
|
),
|
|
rule("dec",
|
|
headReplaced(constraint("val", X)), guard(expression({ x -> x.get() > 0 }, X)),
|
|
body(constraint("trail", X),
|
|
statement({ x, y -> y.set(x.get() - 1) }, X, Y),
|
|
constraint("val", Y))
|
|
)
|
|
).session("dec").run {
|
|
assertEquals(setOf(ConstraintSymbol("val", 1), ConstraintSymbol("trail", 1)), constraintSymbols())
|
|
assertEquals(1, occurrences(ConstraintSymbol.symbol("val", 1)).count())
|
|
val a = occurrences(ConstraintSymbol.symbol("val", 1)).first().arguments().first()
|
|
assertEquals(0, (a as Logical<Int>).get())
|
|
assertEquals(5, occurrences(ConstraintSymbol.symbol("trail", 1)).count())
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun gcd() {
|
|
val (M, N, TMP) = metaLogical<Int>("M", "N", "TMP")
|
|
programWithRules(
|
|
rule("main",
|
|
headReplaced(constraint("main")), body(statement({ m, n -> m.set(21); n.set(35) }, M, N),
|
|
constraint("gcd", M),
|
|
constraint("gcd", N))
|
|
),
|
|
rule("trivial",
|
|
headReplaced(constraint("gcd", M)), guard(expression({ x -> x.get() == 0 }, M)),
|
|
body(statement { } /*nothing*/)
|
|
),
|
|
rule("step",
|
|
headKept(constraint("gcd", N)),
|
|
headReplaced(constraint("gcd", M)),
|
|
guard(expression({ m, n -> m.get() >= n.get() }, M, N)),
|
|
body(statement({ m, n, tmp -> tmp.set(m.get() - n.get()) }, M, N, TMP),
|
|
constraint("gcd", TMP)
|
|
)
|
|
)
|
|
).session("gcd").run {
|
|
assertEquals(1, allOccurrences().count())
|
|
val arg = allOccurrences().first().arguments().first()
|
|
assertEquals(7, (arg as Logical<Int>).get())
|
|
}
|
|
}
|
|
|
|
|
|
@Test
|
|
fun primes() {
|
|
val (M, N) = metaLogical<Int>("M", "N")
|
|
programWithRules(
|
|
rule("main",
|
|
headReplaced(constraint("main")), body(statement({ n -> n.set(10) }, N),
|
|
constraint("prime", N))
|
|
),
|
|
rule("gen",
|
|
headKept(constraint("prime", N)), guard(expression({ n -> n.get() > 2 }, N)),
|
|
body(statement({ m, n -> m.set(n.get() - 1) }, M, N),
|
|
constraint("prime", M))
|
|
),
|
|
rule("sift",
|
|
headKept(constraint("prime", M)),
|
|
headReplaced(constraint("prime", N)),
|
|
guard(expression({ m, n -> (n.get() % m.get()) == 0 }, M, N)),
|
|
body(statement { } /* nothing */)
|
|
)
|
|
).session("primes").run {
|
|
assertEquals(4, allOccurrences().count())
|
|
assertEquals(setOf(2, 3, 5, 7), occurrences(ConstraintSymbol.symbol("prime", 1)).flatMap { co -> co.arguments() }.map { a -> (a as Logical<Int>).findRoot().value() }.toSet())
|
|
}
|
|
|
|
}
|
|
|
|
}
|