From 54335cb2fdd7b01b4a0adca7c1ef20c1c0da39d0 Mon Sep 17 00:00:00 2001 From: Grigorii Kirgizov Date: Thu, 23 Jul 2020 12:13:29 +0300 Subject: [PATCH] Introduce incrementality-allowed levels: No, Unsafe, Yes Instead of simple allowed/not option sometimes Unsafe is useful. 'Unsafe' status may be present when there're few "bad" rules. With this level end code may resolve to go with incrementality without strict guarantees. --- .../core/internal/ConstraintsProcessing.kt | 8 +- .../reactor/core/internal/ControllerImpl.kt | 8 +- .../core/internal/EvaluationSessionImpl.kt | 22 +++--- .../reactor/core/internal/IncrSpecHolder.kt | 6 +- .../reactor/core/internal/MatchJournalImpl.kt | 4 +- .../core/internal/StoreAwareJournal.kt | 4 +- .../reactor/evaluation/EvaluationSession.java | 7 +- .../program/IncrementalProgramSpec.java | 40 ---------- .../reactor/program/IncrementalSpec.java | 78 +++++++++++++++++++ reactor/Test/test/MockIncrProgSpec.kt | 12 +-- reactor/Test/test/TestIncrementalProgram.kt | 6 +- reactor/Test/test/TestStoreAwareJournal.kt | 7 +- 12 files changed, 120 insertions(+), 82 deletions(-) delete mode 100644 reactor/Core/src/jetbrains/mps/logic/reactor/program/IncrementalProgramSpec.java create mode 100644 reactor/Core/src/jetbrains/mps/logic/reactor/program/IncrementalSpec.java diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ConstraintsProcessing.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ConstraintsProcessing.kt index 5efd5bde..997d6f4f 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ConstraintsProcessing.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ConstraintsProcessing.kt @@ -18,7 +18,7 @@ package jetbrains.mps.logic.reactor.core.internal import jetbrains.mps.logic.reactor.core.* import jetbrains.mps.logic.reactor.evaluation.EvaluationTrace -import jetbrains.mps.logic.reactor.program.IncrementalProgramSpec +import jetbrains.mps.logic.reactor.program.IncrementalSpec import jetbrains.mps.logic.reactor.evaluation.SessionToken import jetbrains.mps.logic.reactor.logical.Logical import jetbrains.mps.logic.reactor.logical.LogicalContext @@ -43,7 +43,7 @@ internal class ConstraintsProcessing(private var dispatchingFront: Dispatcher.Di journal: MatchJournalImpl, private val ruleIndex: RuleIndex, val logicalState: LogicalState, - override val ispec: IncrementalProgramSpec = IncrementalProgramSpec.DefaultSpec, + override val ispec: IncrementalSpec = IncrementalSpec.DefaultSpec, val trace: EvaluationTrace = EvaluationTrace.NULL, val profiler: Profiler? = null) : StoreAwareJournalImpl(journal, logicalState), IncrSpecHolder @@ -222,7 +222,9 @@ internal class ConstraintsProcessing(private var dispatchingFront: Dispatcher.Di logActivation(active) active.revive(logicalState) - if (ispec.assertContracts()) active.addContractObservers(logicalState) + if (ispec.assertLevel().assertContracts()) { + active.addContractObservers(logicalState) + } } assert(active.alive) diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ControllerImpl.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ControllerImpl.kt index 27711707..4d9d10f6 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ControllerImpl.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ControllerImpl.kt @@ -23,7 +23,7 @@ import jetbrains.mps.logic.reactor.logical.Logical import jetbrains.mps.logic.reactor.logical.LogicalContext import jetbrains.mps.logic.reactor.logical.MetaLogical import jetbrains.mps.logic.reactor.program.Constraint -import jetbrains.mps.logic.reactor.program.IncrementalProgramSpec +import jetbrains.mps.logic.reactor.program.IncrementalSpec import jetbrains.mps.logic.reactor.program.Predicate import jetbrains.mps.logic.reactor.util.Profiler import jetbrains.mps.logic.reactor.util.profile @@ -31,7 +31,7 @@ import jetbrains.mps.logic.reactor.util.profile internal class ControllerImpl ( val supervisor: Supervisor, val processing: ConstraintsProcessing, - override val ispec: IncrementalProgramSpec = IncrementalProgramSpec.DefaultSpec, + override val ispec: IncrementalSpec = IncrementalSpec.DefaultSpec, val trace: EvaluationTrace = EvaluationTrace.NULL, val profiler: Profiler? = null) : Controller, IncrSpecHolder { @@ -369,11 +369,11 @@ fun createController( MatchJournalImpl(), ruleIndex, logicalState, - IncrementalProgramSpec.DefaultSpec, + IncrementalSpec.DefaultSpec, trace, profiler ), - IncrementalProgramSpec.DefaultSpec, + IncrementalSpec.DefaultSpec, trace, profiler ) diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/EvaluationSessionImpl.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/EvaluationSessionImpl.kt index b203055f..04da33aa 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/EvaluationSessionImpl.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/EvaluationSessionImpl.kt @@ -20,7 +20,7 @@ import jetbrains.mps.logic.reactor.core.* import jetbrains.mps.logic.reactor.core.internal.FeedbackStatus.FAILED import jetbrains.mps.logic.reactor.evaluation.* import jetbrains.mps.logic.reactor.program.Constraint -import jetbrains.mps.logic.reactor.program.IncrementalProgramSpec +import jetbrains.mps.logic.reactor.program.IncrementalSpec import jetbrains.mps.logic.reactor.program.Program import jetbrains.mps.logic.reactor.util.Profiler import java.util.* @@ -41,7 +41,7 @@ internal class EvaluationSessionImpl private constructor ( private fun launch( main: Constraint, profiler: Profiler?, - token: SessionToken?, rulesDiff: RulesDiff, ispec: IncrementalProgramSpec + token: SessionToken?, rulesDiff: RulesDiff, incrementality: IncrementalSpec ) : EvaluationResult { val newToken: SessionToken @@ -50,15 +50,15 @@ internal class EvaluationSessionImpl private constructor ( val ruleIndex = RuleIndex(program.rulesLists()) - if (ispec is IncrementalProgramSpec.NonIncrSpec || token == null) { + if (!incrementality.ability().allowed() || token == null) { val logicalState = LogicalState() val processing = ConstraintsProcessing( Dispatcher(ruleIndex).front(), - MatchJournalImpl(ispec), - ruleIndex, logicalState, ispec, trace, profiler + MatchJournalImpl(incrementality), + ruleIndex, logicalState, incrementality, trace, profiler ) - val controller = ControllerImpl(supervisor, processing, ispec, trace, profiler) + val controller = ControllerImpl(supervisor, processing, incrementality, trace, profiler) logicalState.init(controller) status = controller.activate(main) @@ -71,10 +71,10 @@ internal class EvaluationSessionImpl private constructor ( val processing = ConstraintsProcessing( Dispatcher(ruleIndex, tkn.getFrontState()).front(), - MatchJournalImpl(ispec, tkn.journalView as MatchJournal.View), - ruleIndex, logicalState, ispec, trace, profiler + MatchJournalImpl(incrementality, tkn.journalView as MatchJournal.View), + ruleIndex, logicalState, incrementality, trace, profiler ) - val controller = ControllerImpl(supervisor, processing, ispec, trace, profiler) + val controller = ControllerImpl(supervisor, processing, incrementality, trace, profiler) logicalState.init(controller) val status2tags = controller.incrLaunch(main, rulesDiff) @@ -97,7 +97,7 @@ internal class EvaluationSessionImpl private constructor ( var evaluationTrace: EvaluationTrace = EvaluationTrace.NULL - var ispec: IncrementalProgramSpec = IncrementalProgramSpec.DefaultSpec + var ispec: IncrementalSpec = IncrementalSpec.DefaultSpec var token: SessionToken? = null @@ -115,7 +115,7 @@ internal class EvaluationSessionImpl private constructor ( return this } - override fun withIncrSpec(ispec: IncrementalProgramSpec): EvaluationSession.Config { + override fun withIncrSpec(ispec: IncrementalSpec): EvaluationSession.Config { this.ispec = ispec return this } diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/IncrSpecHolder.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/IncrSpecHolder.kt index 521b5df6..ed90daa0 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/IncrSpecHolder.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/IncrSpecHolder.kt @@ -19,11 +19,11 @@ package jetbrains.mps.logic.reactor.core.internal import jetbrains.mps.logic.reactor.core.Occurrence import jetbrains.mps.logic.reactor.evaluation.RuleMatch import jetbrains.mps.logic.reactor.program.IncrementalContractViolationException -import jetbrains.mps.logic.reactor.program.IncrementalProgramSpec +import jetbrains.mps.logic.reactor.program.IncrementalSpec import jetbrains.mps.logic.reactor.program.Rule interface IncrSpecHolder { - val ispec: IncrementalProgramSpec + val ispec: IncrementalSpec val Occurrence.isPrincipal get() = ispec.isPrincipal(this.constraint()) @@ -47,5 +47,5 @@ inline fun IncrSpecHolder.assertContract(lazyValue: () -> Boolean) { assertContract(lazyValue) { "Contract assertion failed" } } inline fun IncrSpecHolder.assertContract(lazyValue: () -> Boolean, noinline lazyMsg: () -> String) { - if (ispec.assertContracts()) checkContract(lazyValue(), lazyMsg) + if (ispec.assertLevel().assertContracts()) checkContract(lazyValue(), lazyMsg) } diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/MatchJournalImpl.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/MatchJournalImpl.kt index 039416bd..15b44473 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/MatchJournalImpl.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/MatchJournalImpl.kt @@ -30,7 +30,7 @@ import java.util.* internal open class MatchJournalImpl( - override val ispec: IncrementalProgramSpec, + override val ispec: IncrementalSpec, view: MatchJournal.View? = null ) : MatchJournal, IncrSpecHolder { @@ -87,7 +87,7 @@ internal open class MatchJournalImpl( ancestorChunksStack = mutableListOf(initialChunk()) } - constructor(view: MatchJournal.View? = null) : this(IncrementalProgramSpec.DefaultSpec, view) + constructor(view: MatchJournal.View? = null) : this(IncrementalSpec.DefaultSpec, view) // pointer to current position in history where logging (chunk additions) and log erasing (chunk removals) happens diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/StoreAwareJournal.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/StoreAwareJournal.kt index bd11704b..0415eae0 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/StoreAwareJournal.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/StoreAwareJournal.kt @@ -17,7 +17,7 @@ package jetbrains.mps.logic.reactor.core.internal import jetbrains.mps.logic.reactor.core.LogicalStateObservable -import jetbrains.mps.logic.reactor.program.IncrementalProgramSpec +import jetbrains.mps.logic.reactor.program.IncrementalSpec import java.lang.IllegalArgumentException @@ -34,7 +34,7 @@ interface StoreAwareJournal : MatchJournal, LogicalStateObservable { // for tests companion object { fun fromView( - ispec: IncrementalProgramSpec = IncrementalProgramSpec.DefaultSpec, + ispec: IncrementalSpec = IncrementalSpec.DefaultSpec, view: MatchJournal.View? = null ): StoreAwareJournal = StoreAwareJournalImpl(MatchJournalImpl(ispec, view)) } diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/EvaluationSession.java b/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/EvaluationSession.java index 6ce652ba..236fadd8 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/EvaluationSession.java +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/EvaluationSession.java @@ -17,12 +17,9 @@ package jetbrains.mps.logic.reactor.evaluation; -import jetbrains.mps.logic.reactor.core.RulesDiff; -import jetbrains.mps.logic.reactor.program.IncrementalProgramSpec; +import jetbrains.mps.logic.reactor.program.IncrementalSpec; import jetbrains.mps.logic.reactor.program.Program; -import java.util.Map; - /** * The starting point to evaluate a program. *

@@ -88,7 +85,7 @@ public abstract class EvaluationSession { public Config withSessionToken(SessionToken token) { return this; } - public Config withIncrSpec(IncrementalProgramSpec ispec) { return this; } + public Config withIncrSpec(IncrementalSpec ispec) { return this; } public abstract EvaluationResult start(Supervisor supervisor); diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/program/IncrementalProgramSpec.java b/reactor/Core/src/jetbrains/mps/logic/reactor/program/IncrementalProgramSpec.java deleted file mode 100644 index 4a38d5d0..00000000 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/program/IncrementalProgramSpec.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2014-2019 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package jetbrains.mps.logic.reactor.program; - -public interface IncrementalProgramSpec { - - boolean isPrincipal(Constraint ctr); - boolean isPrincipal(Rule rule); - boolean isWeakPrincipal(Rule rule); - - boolean assertContracts(); - - class NonIncrSpec implements IncrementalProgramSpec { - @Override - public boolean isPrincipal(Constraint ctr) { return false; } - @Override - public boolean isPrincipal(Rule rule) { return false; } - @Override - public boolean isWeakPrincipal(Rule rule) { return false; } - - @Override - public boolean assertContracts() { return false; } - } - - NonIncrSpec DefaultSpec = new NonIncrSpec(); -} diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/program/IncrementalSpec.java b/reactor/Core/src/jetbrains/mps/logic/reactor/program/IncrementalSpec.java new file mode 100644 index 00000000..8b408e07 --- /dev/null +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/program/IncrementalSpec.java @@ -0,0 +1,78 @@ +/* + * Copyright 2014-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package jetbrains.mps.logic.reactor.program; + +import org.jetbrains.annotations.NotNull; + +public interface IncrementalSpec { + + boolean isPrincipal(Constraint ctr); + boolean isPrincipal(Rule rule); + boolean isWeakPrincipal(Rule rule); + + @NotNull + Enabled ability(); + @NotNull + AssertLevel assertLevel(); + + enum Enabled { + No, Unsafe, Yes; + + public Enabled min(Enabled other) { + return this.compareTo(other) <= 0 ? this : other; + } + + public boolean allowed() { + return this.compareTo(Enabled.No) > 0; + } + + public boolean strict() { + return this.compareTo(Enabled.Yes) >= 0; + } + } + + enum AssertLevel { + Normal, AssertContracts; + + public AssertLevel max(AssertLevel other) { + return this.compareTo(other) >= 0 ? this : other; + } + + public boolean assertContracts() { + return this.compareTo(AssertLevel.AssertContracts) >= 0; + } + } + + class StubSpec implements IncrementalSpec { + @Override + public boolean isPrincipal(Constraint ctr) { return false; } + @Override + public boolean isPrincipal(Rule rule) { return false; } + @Override + public boolean isWeakPrincipal(Rule rule) { return false; } + + @Override + @NotNull + public Enabled ability() { return Enabled.No; } + @NotNull + @Override + public AssertLevel assertLevel() { return AssertLevel.Normal; } + } + + StubSpec DefaultSpec = new StubSpec(); +} + diff --git a/reactor/Test/test/MockIncrProgSpec.kt b/reactor/Test/test/MockIncrProgSpec.kt index 7d31f5c7..877a12e0 100644 --- a/reactor/Test/test/MockIncrProgSpec.kt +++ b/reactor/Test/test/MockIncrProgSpec.kt @@ -14,27 +14,27 @@ * limitations under the License. */ -import jetbrains.mps.logic.reactor.core.allHeads import jetbrains.mps.logic.reactor.program.Constraint import jetbrains.mps.logic.reactor.program.ConstraintSymbol -import jetbrains.mps.logic.reactor.program.IncrementalProgramSpec +import jetbrains.mps.logic.reactor.program.IncrementalSpec import jetbrains.mps.logic.reactor.program.Rule class MockIncrProgSpec( val principalRuleTags: Set, val principalCtrSyms: Set, val weakPrincipalRuleTags: Set, - private var checkContracts: Boolean = false -) : IncrementalProgramSpec { + private var strictness: IncrementalSpec.AssertLevel = IncrementalSpec.AssertLevel.Normal +) : IncrementalSpec { constructor(principalRuleTags: Set, principalCtrSyms: Set) : this(principalRuleTags, principalCtrSyms, emptySet()) - fun withContractChecks() = this.also { checkContracts = true } + fun withContractChecks() = this.also { strictness = IncrementalSpec.AssertLevel.AssertContracts } override fun isPrincipal(ctr: Constraint): Boolean = principalCtrSyms.contains(ctr.symbol()) override fun isPrincipal(rule: Rule): Boolean = principalRuleTags.contains(rule.uniqueTag()) override fun isWeakPrincipal(rule: Rule): Boolean = weakPrincipalRuleTags.contains(rule.uniqueTag()) - override fun assertContracts(): Boolean = checkContracts + override fun ability(): IncrementalSpec.Enabled = IncrementalSpec.Enabled.Yes + override fun assertLevel(): IncrementalSpec.AssertLevel = strictness } \ No newline at end of file diff --git a/reactor/Test/test/TestIncrementalProgram.kt b/reactor/Test/test/TestIncrementalProgram.kt index 34f259f5..f6494171 100644 --- a/reactor/Test/test/TestIncrementalProgram.kt +++ b/reactor/Test/test/TestIncrementalProgram.kt @@ -1,4 +1,4 @@ -import jetbrains.mps.logic.reactor.program.IncrementalProgramSpec +import jetbrains.mps.logic.reactor.program.IncrementalSpec import jetbrains.mps.logic.reactor.core.Occurrence import jetbrains.mps.logic.reactor.core.ReactorLifecycle import jetbrains.mps.logic.reactor.core.RulesDiff @@ -51,7 +51,7 @@ class TestIncrementalProgram { } } - private fun Builder.launch(name: String, incrSpec: IncrementalProgramSpec, resultHandler: (EvaluationResult) -> Unit) + private fun Builder.launch(name: String, incrSpec: IncrementalSpec, resultHandler: (EvaluationResult) -> Unit) : Pair { val result = EvaluationSession.newSession(program(name)) @@ -63,7 +63,7 @@ class TestIncrementalProgram { return this to result } - private fun Builder.relaunch(name: String, incrSpec: IncrementalProgramSpec, sessionToken: SessionToken, resultHandler: (EvaluationResult) -> Unit ) + private fun Builder.relaunch(name: String, incrSpec: IncrementalSpec, sessionToken: SessionToken, resultHandler: (EvaluationResult) -> Unit ) : Pair { val prog = program(name).withRulesDiff( diff --git a/reactor/Test/test/TestStoreAwareJournal.kt b/reactor/Test/test/TestStoreAwareJournal.kt index 6fd84aae..352a2ccb 100644 --- a/reactor/Test/test/TestStoreAwareJournal.kt +++ b/reactor/Test/test/TestStoreAwareJournal.kt @@ -2,7 +2,7 @@ import jetbrains.mps.logic.reactor.core.* import jetbrains.mps.logic.reactor.core.internal.* import jetbrains.mps.logic.reactor.program.Constraint import jetbrains.mps.logic.reactor.program.ConstraintSymbol -import jetbrains.mps.logic.reactor.program.IncrementalProgramSpec +import jetbrains.mps.logic.reactor.program.IncrementalSpec import jetbrains.mps.logic.reactor.program.Rule import org.junit.Test import org.junit.Assert.* @@ -27,14 +27,15 @@ import org.junit.Ignore class TestStoreAwareJournal { - private object LegacyMockIncrProgSpec : IncrementalProgramSpec.NonIncrSpec() { + private object LegacyMockIncrProgSpec : IncrementalSpec.StubSpec() { override fun isPrincipal(ctr: Constraint): Boolean = ctr.isPrincipal override fun isPrincipal(rule: Rule): Boolean = rule.all().any { it is Constraint && it.isPrincipal } + override fun ability(): IncrementalSpec.Enabled = IncrementalSpec.Enabled.Yes } private class JournalDispatcherHelper( dispatcher: Dispatcher, - ispec: IncrementalProgramSpec = LegacyMockIncrProgSpec, + ispec: IncrementalSpec = LegacyMockIncrProgSpec, val hist: StoreAwareJournal = StoreAwareJournal.fromView(ispec) ) { var d: Dispatcher.DispatchingFront = dispatcher.front()