diff --git a/reactor/API/src/jetbrains/mps/logic/reactor/logical/LogicalContext.java b/reactor/API/src/jetbrains/mps/logic/reactor/logical/LogicalContext.java index 7d967730..da106365 100644 --- a/reactor/API/src/jetbrains/mps/logic/reactor/logical/LogicalContext.java +++ b/reactor/API/src/jetbrains/mps/logic/reactor/logical/LogicalContext.java @@ -5,6 +5,6 @@ package jetbrains.mps.logic.reactor.logical; public interface LogicalContext { - public V valueFor(LogicalPattern logicalPattern); + public Logical variable(LogicalPattern logicalPattern); } diff --git a/reactor/API/src/jetbrains/mps/logic/reactor/logical/trace.info b/reactor/API/src/jetbrains/mps/logic/reactor/logical/trace.info index 2522a1f0..43ec22fc 100644 --- a/reactor/API/src/jetbrains/mps/logic/reactor/logical/trace.info +++ b/reactor/API/src/jetbrains/mps/logic/reactor/logical/trace.info @@ -146,7 +146,7 @@ - + diff --git a/reactor/API/src/jetbrains/mps/logic/reactor/program/Constraint.java b/reactor/API/src/jetbrains/mps/logic/reactor/program/Constraint.java index 8ee2233d..d637a05f 100644 --- a/reactor/API/src/jetbrains/mps/logic/reactor/program/Constraint.java +++ b/reactor/API/src/jetbrains/mps/logic/reactor/program/Constraint.java @@ -3,6 +3,8 @@ package jetbrains.mps.logic.reactor.program; /*Generated by MPS */ import java.util.List; +import java.util.Collection; +import jetbrains.mps.logic.reactor.logical.LogicalContext; /** * A constraint provided by a handler. Can only be told. @@ -13,4 +15,5 @@ public interface Constraint extends AndItem { public List> argumentTypes(); + public Collection occurrenceArguments(LogicalContext logicalContext); } diff --git a/reactor/API/src/jetbrains/mps/logic/reactor/program/Predicate.java b/reactor/API/src/jetbrains/mps/logic/reactor/program/Predicate.java index 4ec8eeb1..fab43e86 100644 --- a/reactor/API/src/jetbrains/mps/logic/reactor/program/Predicate.java +++ b/reactor/API/src/jetbrains/mps/logic/reactor/program/Predicate.java @@ -2,6 +2,8 @@ package jetbrains.mps.logic.reactor.program; /*Generated by MPS */ +import java.util.Collection; +import jetbrains.mps.logic.reactor.logical.LogicalContext; /** * A predicate that is provided by a solver. Can be either told or asked. @@ -10,4 +12,7 @@ public interface Predicate extends AndItem { public PredicateSymbol symbol(); + public Collection invocationArguments(LogicalContext logicalContext); + + } diff --git a/reactor/API/src/jetbrains/mps/logic/reactor/program/trace.info b/reactor/API/src/jetbrains/mps/logic/reactor/program/trace.info index f7a7d587..c9e3e0db 100644 --- a/reactor/API/src/jetbrains/mps/logic/reactor/program/trace.info +++ b/reactor/API/src/jetbrains/mps/logic/reactor/program/trace.info @@ -178,18 +178,26 @@ - - - - - + + + + + + + + + - - - + + + + + + + diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/Handler.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/Handler.kt index 765d415d..2c380c0a 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/Handler.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/Handler.kt @@ -136,26 +136,19 @@ class Handler { } -private fun AndItem.argumentValues(context: LogicalContext): List = - arguments().map { arg -> if (arg is LogicalPattern<*>) context.valueFor(arg) else arg!! }.toList() - - -private fun Constraint.occurrence(handler: Handler, context: LogicalContext): ConstraintOccurrence = - MemConstraintOccurrence(handler, this, argumentValues(context)) - private val noLogicalContext: LogicalContext = object: LogicalContext { - override fun valueFor(logicalPattern: LogicalPattern): V? = null + override fun variable(logicalPattern: LogicalPattern): Logical = TODO() } +private fun Constraint.occurrence(handler: Handler, context: LogicalContext): ConstraintOccurrence = + MemConstraintOccurrence(handler, this, occurrenceArguments(context)) -private fun Predicate.invocation(logicalContext: LogicalContext): PredicateInvocation { - return object: PredicateInvocation { +private fun Predicate.invocation(logicalContext: LogicalContext): PredicateInvocation = object: PredicateInvocation { override fun predicate(): Predicate = this@invocation - override fun arguments(): Collection = argumentValues(logicalContext) + override fun arguments(): Collection<*> = invocationArguments(logicalContext) } -} fun ConstraintOccurrence.terminate() { if (this is MemConstraintOccurrence) { @@ -163,7 +156,7 @@ fun ConstraintOccurrence.terminate() { } } -private data class MemConstraintOccurrence(val handler: Handler, val constraint: Constraint, val arguments: List, val id: Int) : +private data class MemConstraintOccurrence(val handler: Handler, val constraint: Constraint, val arguments: List<*>, val id: Int) : ConstraintOccurrence, LogicalValueObserver { @@ -174,8 +167,8 @@ private data class MemConstraintOccurrence(val handler: Handler, val constraint: val random = Random() } - constructor(handler: Handler, constraint: Constraint, arguments: List) : - this(handler, constraint, arguments, random.nextInt()) + constructor(handler: Handler, constraint: Constraint, arguments: Collection<*>) : + this(handler, constraint, ArrayList(arguments), random.nextInt()) { for (a in arguments) { if (a is Logical<*>) { @@ -186,7 +179,7 @@ private data class MemConstraintOccurrence(val handler: Handler, val constraint: override fun constraint(): Constraint = constraint - override fun arguments(): Collection = arguments + override fun arguments(): Collection<*> = arguments override fun valueUpdated(logical: Logical<*>) { handler.queue(this) diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/Logical.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/Logical.kt index b42a4822..42af8a3f 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/Logical.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/Logical.kt @@ -26,6 +26,8 @@ internal fun Logical<*>.removeObserver(observer: LogicalValueObserver) { fun LogicalPattern.logical(): Logical = MemLogical(name()) +fun LogicalPattern.logical(value: V): Logical = MemLogical(name(), value) + class MemLogical : SolverLogical { companion object { @@ -53,6 +55,11 @@ class MemLogical : SolverLogical { this.name = name } + constructor(name: String, value: T) { + this.name = name + this._value = value + } + constructor(pattern: LogicalPattern) { this.pattern = pattern this.name = pattern.name() diff --git a/reactor/Test/src/program/MemConstraint.kt b/reactor/Test/src/program/MemConstraint.kt index 19df3f65..6fe1b264 100644 --- a/reactor/Test/src/program/MemConstraint.kt +++ b/reactor/Test/src/program/MemConstraint.kt @@ -1,6 +1,8 @@ package program import jetbrains.mps.logic.reactor.evaluation.ConstraintOccurrence +import jetbrains.mps.logic.reactor.logical.LogicalContext +import jetbrains.mps.logic.reactor.logical.LogicalPattern import jetbrains.mps.logic.reactor.program.Constraint import jetbrains.mps.logic.reactor.program.ConstraintSymbol import java.util.* @@ -15,6 +17,11 @@ data class MemConstraint(val symbol: ConstraintSymbol, val arguments: List) override fun arguments(): List = arguments + override fun occurrenceArguments(logicalContext: LogicalContext): Collection<*> = arguments.map { a -> + if (a is LogicalPattern<*>) logicalContext.variable(a) + else a + } + override fun symbol(): ConstraintSymbol = symbol override fun argumentTypes(): List> = arguments.map { arg -> arg.javaClass } diff --git a/reactor/Test/test/JavaExpressionHelper.kt b/reactor/Test/test/JavaExpressionHelper.kt index 29263ec0..ce7d2784 100644 --- a/reactor/Test/test/JavaExpressionHelper.kt +++ b/reactor/Test/test/JavaExpressionHelper.kt @@ -97,6 +97,10 @@ data class TestJavaPredicate(val symbol: JavaPredicateSymbol, val expr: JavaExpr override fun symbol(): PredicateSymbol = symbol + override fun invocationArguments(logicalContext: LogicalContext): Collection<*> = args.map { a -> + if (a is LogicalPattern<*>) logicalContext.variable(a) + else a + } } diff --git a/reactor/Test/test/LogicalHelper.kt b/reactor/Test/test/LogicalHelper.kt index d4d93463..75d61484 100644 --- a/reactor/Test/test/LogicalHelper.kt +++ b/reactor/Test/test/LogicalHelper.kt @@ -49,4 +49,9 @@ data class TestEqPredicate(val left: Any, val right: Any) : Predicate { override fun symbol(): PredicateSymbol = PredicateSymbol("equals", 2) + override fun invocationArguments(logicalContext: LogicalContext): Collection<*> = listOf(left, right).map { a -> + if (a is LogicalPattern<*>) logicalContext.variable(a) + else a + } + } \ No newline at end of file diff --git a/reactor/Test/test/TestMatcher.kt b/reactor/Test/test/TestMatcher.kt index c60617e5..e8f51b66 100644 --- a/reactor/Test/test/TestMatcher.kt +++ b/reactor/Test/test/TestMatcher.kt @@ -194,10 +194,10 @@ class TestMatcher { ) ) ).matcher().lookupMatches(occurrence("foo", "blah", b)).first().run { - assertEquals("blah", logicalContext().valueFor(A)) - assertSame(b, logicalContext().valueFor(B)) - assertEquals(C.logical().name(), (logicalContext().valueFor(C) as Logical<*>).name()) - assertEquals(C.logical().pattern(), (logicalContext().valueFor(C) as Logical<*>).pattern()) + assertEquals("blah", logicalContext().variable(A).findRoot().value()) + assertSame(b, logicalContext().variable(B)) + assertEquals(C.logical().name(), logicalContext().variable(C).name()) + assertEquals(C.logical().pattern(), logicalContext().variable(C).pattern()) } } @@ -241,7 +241,8 @@ class TestMatcher { matcher(occurrence("foo", 42)).lookupMatches(occurrence("foo", 16)).let { matches -> assertEquals(2, matches.count()) assertEquals(listOf("main1", "main1"), matches.map { m -> m.rule.tag() }) - matches.map { m -> setOf(M, N).map { lp -> m.logicalContext().valueFor(lp) } }.forEach { vals -> + matches.map { m -> setOf(M, N).map { lp -> + m.logicalContext().variable(lp).findRoot().value() } }.forEach { vals -> assertEquals(setOf(42, 16), vals.toSet()) } assertTrue(matches.all{ m -> m.occurrences().toSet().size == 2 })