From b4e9d45f7e8eb170d94fd5c134a6e313e0deb55c Mon Sep 17 00:00:00 2001 From: Fedor Isakov Date: Thu, 13 Oct 2016 11:07:27 +0200 Subject: [PATCH] Enforce the constraint transparency contract on bound logicals: treat the value as the constraint argument. Remove misbehaving test. --- .../mps/logic/reactor/core/OccurrenceStore.kt | 26 +++++-- reactor/Test/test/TestOccurrenceStore.kt | 68 +++++++++++++++---- reactor/Test/test/TestProfiler.kt | 67 ------------------ 3 files changed, 75 insertions(+), 86 deletions(-) delete mode 100644 reactor/Test/test/TestProfiler.kt diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/OccurrenceStore.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/OccurrenceStore.kt index bebe7b43..73ececba 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/OccurrenceStore.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/OccurrenceStore.kt @@ -134,19 +134,21 @@ class OccurrenceStore : LogicalObserver, OccurrenceIndex { symbol2occurrences[symbol]?.add(occ) ?: singletonSet(occ)) for (arg in occ.arguments()) { - when (arg) { + val value = if (arg is Logical<*> && arg.isBound) arg.findRoot().value() else arg + when (value) { is Logical<*> -> { - val argId = IdWrapper(arg.findRoot()) + // free logical + val argId = IdWrapper(value.findRoot()) this.logical2occurrences = logical2occurrences.put(argId, logical2occurrences[argId]?.add(occ) ?: singletonSet(occ)) - currentFrame().addObserver(arg) { frame -> frame.store() } + currentFrame().addObserver(value) { frame -> frame.store() } } is Term -> { - this.term2occurrences = term2occurrences.put(arg, occ) + this.term2occurrences = term2occurrences.put(value, occ) } is Any -> { - this.value2occurrences = value2occurrences.put(arg, - value2occurrences[arg]?.add(occ) ?: singletonSet(occ)) + this.value2occurrences = value2occurrences.put(value, + value2occurrences[value]?.add(occ) ?: singletonSet(occ)) } else -> { // never happens @@ -206,7 +208,17 @@ class OccurrenceStore : LogicalObserver, OccurrenceIndex { } override fun forLogical(logical: Logical<*>): Iterable { - return (logical2occurrences[IdWrapper(logical.findRoot())] ?: emptySet()).filter { co -> co.isStored() } + return if (logical.isBound) { + val value = logical.findRoot().value() + when (value) { + is Term -> forTerm(value) + is Any -> forValue(value) + else -> throw NullPointerException() + } + + } else { + (logical2occurrences[IdWrapper(logical.findRoot())] ?: emptySet()).filter { co -> co.isStored() } + } } override fun forTerm(term: Term): Iterable { diff --git a/reactor/Test/test/TestOccurrenceStore.kt b/reactor/Test/test/TestOccurrenceStore.kt index 3ed8fa81..fede711a 100644 --- a/reactor/Test/test/TestOccurrenceStore.kt +++ b/reactor/Test/test/TestOccurrenceStore.kt @@ -1,13 +1,12 @@ import jetbrains.mps.logic.reactor.core.* import jetbrains.mps.logic.reactor.logical.Logical -import jetbrains.mps.logic.reactor.program.ConstraintSymbol import jetbrains.mps.logic.reactor.program.ConstraintSymbol.symbol import jetbrains.mps.logic.reactor.util.emptyConsList -import jetbrains.mps.unification.test.MockTermsParser +import jetbrains.mps.unification.Term import jetbrains.mps.unification.test.MockTermsParser.parse -import org.jetbrains.kotlin.js.parser.parse import org.junit.Test import org.junit.Assert.* +import org.junit.Before /** * @author Fedor Isakov @@ -47,11 +46,15 @@ class TestOccurrenceStore { } } + lateinit var occstore: OccurrenceStore + + @Before + fun setup() { + occstore = OccurrenceStore { MockProxy { occstore } } + } + @Test fun testMergeLogicals() { - var occstore : OccurrenceStore? = null - occstore = OccurrenceStore { MockProxy { occstore!! } } - val foo = logical("foo") val bar = logical("bar") @@ -81,10 +84,54 @@ class TestOccurrenceStore { } @Test - fun testValueIndex () { - var occstore : OccurrenceStore? = null - occstore = OccurrenceStore { MockProxy { occstore!! } } + fun testLateGroundLogical() { + val foo = logical("foo") + val bar = logical("bar") + val cnst = occurrence("cnst", foo) + occstore.store(cnst) + assertEquals(listOf(cnst), occstore.forLogical(foo)) + assertEquals(listOf(cnst), occstore.forSymbol(symbol("cnst", 1))) + + foo.set(parse("a{b c d{e}}")) + + assertEquals(listOf(cnst), occstore.forLogical(foo)) + assertEquals(listOf(cnst), occstore.forTerm(parse("a{b c d{e}}"))) + + foo.union(bar) + assertEquals(listOf(cnst), occstore.forLogical(bar)) + } + + @Test + fun testEarlyGroundLogical() { + val foo = logical("foo") + + foo.set(parse("a{b c d{e}}")) + + val cnst = occurrence("cnst", foo) + occstore.store(cnst) + + assertEquals(listOf(cnst), occstore.forLogical(foo)) + assertEquals(listOf(cnst), occstore.forSymbol(symbol("cnst", 1))) + assertEquals(listOf(cnst), occstore.forTerm(parse("a{b c d{e}}"))) + } + + @Test + fun testIndependentlyGroundLogical() { + val foo = logical("foo") + + val cnst = occurrence("cnst", parse("a{b c d{e}}")) + occstore.store(cnst) + + foo.set(parse("a{b c d{e}}")) + + assertEquals(listOf(cnst), occstore.forSymbol(symbol("cnst", 1))) + assertEquals(listOf(cnst), occstore.forTerm(parse("a{b c d{e}}"))) + assertEquals(listOf(cnst), occstore.forLogical(foo)) + } + + @Test + fun testValueIndex () { val value = "foobar" val main = occurrence("main", value) occstore.store(main) @@ -94,9 +141,6 @@ class TestOccurrenceStore { @Test fun testTermIndex () { - var occstore : OccurrenceStore? = null - occstore = OccurrenceStore { MockProxy { occstore!! } } - val foo = occurrence("foo", parse("a{b c}")) occstore.store(foo) diff --git a/reactor/Test/test/TestProfiler.kt b/reactor/Test/test/TestProfiler.kt deleted file mode 100644 index f5812895..00000000 --- a/reactor/Test/test/TestProfiler.kt +++ /dev/null @@ -1,67 +0,0 @@ -import jetbrains.mps.logic.reactor.util.Profiler -import jetbrains.mps.logic.reactor.util.profile -import org.junit.Test -import org.junit.Assert.* - -/** - * @author Fedor Isakov - */ - - -class TestProfiler { - - @Test - fun testFooBar() { - - val profiler = Profiler() - - val foo = profiler.start("foo") - - Thread.sleep(10) - - val bar1 = profiler.start("bar") - - Thread.sleep(20) - - profiler.end(bar1) - - val bar2 = profiler.start("bar") - - Thread.sleep(20) - - profiler.end(bar2) - - profiler.end(foo) - - val durationsMap = profiler.rawProfilingData() - - assertEquals(1, durationsMap["foo"]!!.first / 10000000L) - assertEquals(4, durationsMap["bar"]!!.first / 10000000L) - assertEquals(1, durationsMap["foo"]!!.second) - assertEquals(2, durationsMap["bar"]!!.second) - - } - - @Test - fun testProfile() { - Profiler().run { - profile("foo", { - Thread.sleep(10) - profile("bar", { - Thread.sleep(20) - }) - profile("bazz", { - Thread.sleep(30) - }) - }) - - val durationsMap = rawProfilingData() - - assertEquals(1, durationsMap["foo"]!!.first / 10000000L) - assertEquals(2, durationsMap["bar"]!!.first / 10000000L) - assertEquals(3, durationsMap["bazz"]!!.first / 10000000L) - } - } - -} -