Abstract java interfaces for incrementality-related classes for interop between reactor and coderules

This commit is contained in:
Grigorii Kirgizov 2019-06-18 20:15:22 +03:00 committed by Fedor Isakov
parent 79b08c6f83
commit 155266d8ca
15 changed files with 249 additions and 112 deletions

View File

@ -21,7 +21,7 @@ import jetbrains.mps.logic.reactor.core.internal.RuleMatchImpl
import com.github.andrewoma.dexx.collection.Map as PersMap
typealias DispatchingFrontState = PersMap<Any, RuleMatchingProbe>
typealias DispatchingFrontState = Map<Any, RuleMatchingProbe>
/**
* A front-end interface to [RuleMatcher].
@ -91,7 +91,7 @@ class Dispatcher (val ruleIndex: RuleIndex) {
*/
fun matches() : Iterable<RuleMatchEx> = allMatches
fun state() : DispatchingFrontState = ruletag2probe
fun state() : DispatchingFrontState = ruletag2probe.asMap()
/**
* Returns a new [DispatchingFront] instance that is "expanded" with matches corresponding to the

View File

@ -16,6 +16,7 @@
package jetbrains.mps.logic.reactor.core
import jetbrains.mps.logic.reactor.evaluation.RuleMatchingProbeState
import jetbrains.mps.logic.reactor.program.Rule
import java.util.BitSet
@ -25,7 +26,7 @@ import java.util.BitSet
*
* @author Fedor Isakov
*/
interface RuleMatchingProbe {
interface RuleMatchingProbe : RuleMatchingProbeState {
fun rule(): Rule

View File

@ -23,6 +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.Predicate
import jetbrains.mps.logic.reactor.util.Profiler
import jetbrains.mps.logic.reactor.util.profile
@ -31,7 +32,7 @@ import com.github.andrewoma.dexx.collection.Map as PersMap
internal class ControllerImpl (
val supervisor: Supervisor,
val state: ProcessingStateImpl,
val ispec: IncrementalProgramSpec = IncrementalProgramSpec.NonIncrSpec,
val ispec: IncrementalProgramSpec = IncrementalProgramSpec.DefaultSpec,
val trace: EvaluationTrace = EvaluationTrace.NULL,
val profiler: Profiler? = null) : Controller
{
@ -147,7 +148,6 @@ internal class ControllerImpl (
val itemOk = when (item) {
is Constraint -> {
// track justifications only for principal constraints
// val justs = if (item.isPrincipal) currentJusts else emptyJusts()
val justs = if (ispec.isPrincipal(item)) currentJusts else emptyJusts()
activateConstraint(item, justs, context)
}
@ -313,11 +313,11 @@ fun createController(
Dispatcher(ruleIndex).front(),
MatchJournalImpl(),
ruleIndex,
IncrementalProgramSpec.NonIncrSpec,
IncrementalProgramSpec.DefaultSpec,
trace,
profiler
),
IncrementalProgramSpec.NonIncrSpec,
IncrementalProgramSpec.DefaultSpec,
trace,
profiler
)

View File

@ -20,6 +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.Program
import jetbrains.mps.logic.reactor.util.Profiler
import java.util.*
@ -41,31 +42,29 @@ internal class EvaluationSessionImpl private constructor (
override fun controller() = controller
// private fun launch(main: Constraint, profiler: Profiler?) : FeedbackStatus {
// val journal = MatchJournalImpl()
// val state = ProcessingStateImpl(journal, dispatcher, trace, profiler)
// this.controller = ControllerImpl(supervisor, state, trace, profiler)
// return controller.activate(main)
// }
private fun incrLaunch(main: Constraint, profiler: Profiler?, token: SessionToken?, ispec: IncrementalProgramSpec) : FeedbackStatus {
val ruleIndex = RuleIndex(program().handlers())
val dispatcher = Dispatcher(ruleIndex)
if (ispec is IncrementalProgramSpec.NonIncrSpec || token == null) {
val state = ProcessingStateImpl(dispatcher.front(), MatchJournalImpl(ispec), ruleIndex, ispec, trace, profiler)
val state = ProcessingStateImpl(
dispatcher.front(),
MatchJournalImpl(ispec),
ruleIndex, ispec, trace, profiler
)
this.controller = ControllerImpl(supervisor, state, ispec, trace, profiler)
return controller.activate(main)
} else {
val tkn = token as SessionTokenImpl
val state = ProcessingStateImpl(
dispatcher.frontFromState(token.frontState),
MatchJournalImpl(ispec, token.journalView),
dispatcher.frontFromState(tkn.frontState),
MatchJournalImpl(ispec, tkn.journalView),
ruleIndex, ispec, trace, profiler
)
val rulesDiff = RulesDiff.findDiff(token.ruleTags, ruleIndex)
val rulesDiff = RulesDiff.findDiff(tkn.ruleTags, ruleIndex)
this.controller = ControllerImpl(supervisor, state, ispec, trace, profiler)
return controller.incrLaunch(main, rulesDiff)
}
@ -77,7 +76,7 @@ internal class EvaluationSessionImpl private constructor (
var evaluationTrace: EvaluationTrace = EvaluationTrace.NULL
var ispec: IncrementalProgramSpec = IncrementalProgramSpec.NonIncrSpec
var ispec: IncrementalProgramSpec = IncrementalProgramSpec.DefaultSpec
var token: SessionToken? = null
@ -118,7 +117,6 @@ internal class EvaluationSessionImpl private constructor (
var failure: Feedback? = null
try {
val main = parameters[ParameterKey.of("main", Constraint::class.java)] as Constraint
// val status = session.launch(main, profiler)
val status = session.incrLaunch(main, profiler, token, ispec)
if (status is FAILED) {
failure = status.failure

View File

@ -16,14 +16,14 @@
package jetbrains.mps.logic.reactor.core.internal
import gnu.trove.set.TIntSet
import jetbrains.mps.logic.reactor.core.*
import jetbrains.mps.logic.reactor.evaluation.ConstraintOccurrence
import jetbrains.mps.logic.reactor.evaluation.RuleMatch
import jetbrains.mps.logic.reactor.evaluation.StoreView
import jetbrains.mps.logic.reactor.evaluation.*
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.*
import jetbrains.mps.logic.reactor.program.IncrementalProgramSpec
import jetbrains.mps.logic.reactor.util.Id
import java.util.*
@ -60,28 +60,35 @@ interface MatchJournal : MutableIterable<MatchJournal.Chunk> {
}.maxWith(this) // compare positions: find latest
}
data class View(val chunks: List<Chunk>, val nextChunkId: Int)
data class View(private val chunks: List<Chunk>, private val nextChunkId: Int) : MatchJournalView {
override fun getChunks(): List<Chunk> = chunks
override fun getNextChunkId(): Int = nextChunkId
override fun getStoreView(): StoreView = StoreViewImpl(
chunks.flatMap { it.entriesLog() }.allOccurrences().asSequence()
)
}
abstract class Chunk(val match: RuleMatch, val id: Int, val justifications: Justs) : Pos()
abstract class Chunk(val match: RuleMatch, val id: Int, val justifications: Justs) : MatchJournalChunk, Pos()
{
data class Entry(val occ: Occurrence, val isDiscarded: Boolean = false) {
override fun toString() = (if (isDiscarded) '-' else '+') + occ.toString()
override fun match(): RuleMatch = match
override fun id(): Int = id
override fun justifications(): TIntSet = justifications
data class Entry(val occ: Occurrence, val discarded: Boolean = false) : MatchJournalChunk.Entry {
override fun occ(): ConstraintOccurrence = occ
override fun discarded(): Boolean = discarded
override fun toString() = (if (discarded) '-' else '+') + occ.toString()
}
fun isDescendantOf(chunkId: Int): Boolean = justifications.contains(chunkId)
fun isTopLevel(): Boolean = justifications.size() <= 1 // this condition implies that there're no ancestor chunks
fun isDescendantOf(chunkId: Int): Boolean = justifications().contains(chunkId)
fun isTopLevel(): Boolean = justifications().size() <= 1 // this condition implies that there're no ancestor chunks
abstract fun entriesLog(): List<Entry>
fun activatedLog(): List<Occurrence> = entriesLog().filter { !it.isDiscarded }.map { it.occ }
fun discardedLog(): List<Occurrence> = entriesLog().filter { it.isDiscarded }.map { it.occ }
fun activatedLog(): List<Occurrence> = entriesLog().filter { !it.discarded() }.map { it.occ() as Occurrence }
fun discardedLog(): List<Occurrence> = entriesLog().filter { it.discarded() }.map { it.occ() as Occurrence }
// Get the resulting set of activated occurrences
fun activated(): List<Occurrence> = HashSet<Id<Occurrence>>().apply {
entriesLog().forEach {
if (it.isDiscarded) remove(Id(it.occ)) else add(Id(it.occ))
}
}.map { it.wrapped }
fun activated(): List<Occurrence> = entriesLog().allOccurrences()
override fun toString() = "(id=$id, $justifications, ${match.rule().uniqueTag()}, ${entriesLog()})"
override fun toString() = "(id=${id()}, ${justifications()}, ${match().rule().uniqueTag()}, ${entriesLog()})"
override fun chunk(): Chunk = this
override fun entriesInChunk(): Int = entriesLog().size
@ -106,7 +113,7 @@ interface MatchJournal : MutableIterable<MatchJournal.Chunk> {
?: return null
val offset = chunk.entriesLog().indexOfFirst { entry ->
Id(entry.occ) == idOcc && !entry.isDiscarded
Id(entry.occ()) == idOcc && !entry.discarded()
}
return if (offset >= 0) OccurrencePos(occ, chunk, offset) else null
}
@ -121,9 +128,9 @@ interface MatchJournal : MutableIterable<MatchJournal.Chunk> {
internal open class MatchJournalImpl(
private val ispec: IncrementalProgramSpec,
view: MatchJournal.View? = null
) : MatchJournal
{
view: MatchJournalView? = null
) : MatchJournal {
// invariant: never empty
private val hist: MutableList<ChunkImpl>
private var nextChunkId: Int
@ -142,7 +149,7 @@ internal open class MatchJournalImpl(
}
}
constructor(view: MatchJournal.View? = null) : this(IncrementalProgramSpec.NonIncrSpec, view)
constructor(view: MatchJournal.View? = null) : this(IncrementalProgramSpec.DefaultSpec, view)
private var pos: MutableListIterator<ChunkImpl> = hist.listIterator()
private var current: ChunkImpl = pos.next() // take the initial chunk, move pos
@ -166,27 +173,28 @@ internal open class MatchJournalImpl(
current = newChunk
}
// Log discards
(match as RuleMatchImpl).forEachReplaced {occ ->
current.occurrences.add(MatchJournal.Chunk.Entry(occ, true))
// Log discards
(match as RuleMatchImpl).forEachReplaced { occ ->
current.entries.add(MatchJournal.Chunk.Entry(occ, true))
}
}
override fun logActivation(occ: Occurrence) {
current.occurrences.add(MatchJournal.Chunk.Entry(occ))
current.entries.add(MatchJournal.Chunk.Entry(occ))
}
override fun currentPos(): MatchJournal.Pos = current
// fixme: unclear, whether this makes sense here, in "pure" journal without store? along with reset and replay?
// reset to the beginning, even before the initial chunk, because 'replay' after 'resetPos' is expected
override fun resetPos() { pos = hist.listIterator() }
override fun resetPos() {
pos = hist.listIterator()
}
override fun reset(pastPos: MatchJournal.Pos) {
while (pos.hasPrevious()) {
if (current === pastPos.chunk()) {
current.occurrences = current.occurrences.subList(0, pastPos.entriesInChunk())
current.entries = current.entries.subList(0, pastPos.entriesInChunk())
return
}
current = pos.previous()
@ -199,17 +207,17 @@ internal open class MatchJournalImpl(
while (pos.hasNext()) {
current = pos.next()
if (futurePos.chunk() === current) {
replayOccurrences(controller, current.occurrences.take(futurePos.entriesInChunk()))
replayOccurrences(controller, current.entries.take(futurePos.entriesInChunk()))
return
}
replayOccurrences(controller, current.occurrences)
replayOccurrences(controller, current.entries)
}
if (currentPos() != futurePos) throw IllegalStateException()
}
private fun replayOccurrences(controller: Controller, occSpecs: Iterable<MatchJournal.Chunk.Entry>) =
occSpecs.forEach {
if (it.isDiscarded) {
if (it.discarded) {
it.occ.terminate(controller)
it.occ.stored = false
} else {
@ -233,7 +241,8 @@ internal open class MatchJournalImpl(
val set = HashSet<Id<Occurrence>>()
for (chunk in hist) { // initial chunk is counted too
chunk.entriesLog().forEach {
if (it.isDiscarded) set.remove(Id(it.occ)) else set.add(Id(it.occ))
val idOcc = Id(it.occ)
if (it.discarded()) set.remove(idOcc) else set.add(idOcc)
}
if (chunk === current) {
return set.map { it.wrapped }.asSequence()
@ -242,15 +251,14 @@ internal open class MatchJournalImpl(
throw IllegalStateException()
}
private class ChunkImpl(match: RuleMatch, id: Int, justifications: Justs) : MatchJournal.Chunk(match, id, justifications) {
private class ChunkImpl(match: RuleMatch, id: Int, justifications: Justs) : MatchJournal.Chunk(match, id, justifications)
{
var occurrences: MutableList<Entry> = mutableListOf()
var entries: MutableList<MatchJournal.Chunk.Entry> = mutableListOf()
override fun entriesLog(): List<Entry> = occurrences
override fun entriesLog(): List<MatchJournal.Chunk.Entry> = entries
}
class IndexImpl(ispec: IncrementalProgramSpec, chunks: Iterable<MatchJournal.Chunk>): MatchJournal.Index
private class IndexImpl(ispec: IncrementalProgramSpec, chunks: Iterable<ChunkImpl>): MatchJournal.Index
{
private val chunkOrder: Map<Int, Int>
// only for principal constraints
@ -260,7 +268,7 @@ internal open class MatchJournalImpl(
init {
chunkOrder = HashMap<Int, Int>().apply {
chunks.forEachIndexed { index, chunk -> put(chunk.id, index) }
chunks.forEachIndexed { index, chunk -> put(chunk.id(), index) }
}
val m = HashMap<Id<Occurrence>, MatchJournal.Chunk>()
@ -268,7 +276,7 @@ internal open class MatchJournalImpl(
chunks.forEach { chunk ->
// actually there should be only a single principal occurrence, 'find' is enough
chunk.entriesLog().forEachIndexed { index, e ->
if (ispec.isPrincipal(e.occ.constraint) && !e.isDiscarded) {
if (ispec.isPrincipal(e.occ.constraint()) && !e.discarded()) {
m[Id(e.occ)] = chunk
m2[chunk.id] = MatchJournal.OccurrencePos(e.occ, chunk, index)
}
@ -291,21 +299,6 @@ internal open class MatchJournalImpl(
}
private class StoreViewImpl(occurrences: Sequence<Occurrence>) : StoreView {
val allOccurrences = occurrences.toSet()
val allSymbols = allOccurrences.map { co -> co.constraint().symbol() }.toSet()
override fun constraintSymbols(): Iterable<ConstraintSymbol> = allSymbols
override fun allOccurrences(): Iterable<ConstraintOccurrence> = allOccurrences
override fun occurrences(symbol: ConstraintSymbol): Iterable<ConstraintOccurrence> =
allOccurrences.filter { co -> co.constraint().symbol() == symbol }.toSet()
}
object InitRuleMatch : RuleMatch {
override fun rule(): Rule = EmptyRule
override fun matchHeadKept(): Iterable<ConstraintOccurrence> = emptyList()
@ -329,7 +322,32 @@ internal open class MatchJournalImpl(
}
fun MatchJournal.justs() = this.currentPos().chunk().justifications
private class StoreViewImpl(occurrences: Sequence<Occurrence>) : StoreView {
val allOccurrences = occurrences.toSet()
val allSymbols = allOccurrences.map { co -> co.constraint().symbol() }.toSet()
override fun constraintSymbols(): Iterable<ConstraintSymbol> = allSymbols
override fun allOccurrences(): Iterable<ConstraintOccurrence> = allOccurrences
override fun occurrences(symbol: ConstraintSymbol): Iterable<ConstraintOccurrence> =
allOccurrences.filter { co -> co.constraint().symbol() == symbol }.toSet()
}
private fun Iterable<MatchJournalChunk.Entry>.allOccurrences(): List<Occurrence> {
val set = HashSet<Id<Occurrence>>()
for (it in this) {
val idOcc = Id(it.occ() as Occurrence)
if (it.discarded()) set.remove(idOcc) else set.add(idOcc)
}
return set.map { it.wrapped }
}
fun MatchJournal.justs() = this.currentPos().chunk().justifications()
private fun RuleMatch.headJustifications(): Justs {
val res: Justs = justsOf()

View File

@ -18,7 +18,9 @@ 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.evaluation.RuleMatch
import jetbrains.mps.logic.reactor.evaluation.SessionToken
import jetbrains.mps.logic.reactor.program.Rule
import jetbrains.mps.logic.reactor.util.Id
import jetbrains.mps.logic.reactor.util.Profiler
@ -43,7 +45,7 @@ import java.util.*
internal class ProcessingStateImpl(private var dispatchingFront: Dispatcher.DispatchingFront,
journal: MatchJournalImpl,
ruleIndex: RuleIndex,
private val ispec: IncrementalProgramSpec = IncrementalProgramSpec.NonIncrSpec,
private val ispec: IncrementalProgramSpec = IncrementalProgramSpec.DefaultSpec,
val trace: EvaluationTrace = EvaluationTrace.NULL,
val profiler: Profiler? = null)
: StoreAwareJournalImpl(journal)
@ -83,13 +85,13 @@ internal class ProcessingStateImpl(private var dispatchingFront: Dispatcher.Disp
while (it.hasNext()) {
val chunk = it.next()
val toRemove = ruleIds.contains(chunk.match.rule().uniqueTag())
val toRemove = ruleIds.contains(chunk.match().rule().uniqueTag())
if (toRemove) {
justificationRoots.add(chunk.id)
// We removed the match, so need to reactivate all still valid occurrences from the head
// by definition of Chunk and principal rule, all occurrences from the head are principal
val matchedOccs = chunk.match.allHeads() as Iterable<Occurrence>
val matchedOccs = chunk.match().allHeads() as Iterable<Occurrence>
val (invalidatedOccs, validOccs) = matchedOccs.partition { occ ->
occ.justifications().intersects(justificationRoots)
}
@ -113,11 +115,11 @@ internal class ProcessingStateImpl(private var dispatchingFront: Dispatcher.Disp
// Seems, it's not strictly necessary, because some of its head occurrences are anyway invalidated forever
// and storing this invalid consumed match can make no harm, except some memory overhead.
// fixme: move Chunk's interface to RuleMatchEx instead of RuleMatch
dispatchingFront = dispatchingFront.forget(chunk.match as RuleMatchEx)
dispatchingFront = dispatchingFront.forget(chunk.match() as RuleMatchEx)
// Need to 'cancel' discarding.
// These nodes may become valid and will be processed due to reactivation of needed occurrences.
chunk.match.matchHeadReplaced().forEach {
chunk.match().matchHeadReplaced().forEach {
dispatchingFront = dispatchingFront.forget(it as Occurrence)
}
// 'Undo' all activated in this chunk occurrences
@ -168,7 +170,7 @@ internal class ProcessingStateImpl(private var dispatchingFront: Dispatcher.Disp
// Place to activate candidate:
// either as the last one, after all existing activations
// or according to the ordering between rules.
val placeToInsertFound = ruleOrdering.compare(chunk.match.rule(), candRule) > 0
val placeToInsertFound = ruleOrdering.compare(chunk.match().rule(), candRule) > 0
val childChunksEnded = !chunk.isDescendantOf(parentId)
val pos =
@ -221,9 +223,8 @@ internal class ProcessingStateImpl(private var dispatchingFront: Dispatcher.Disp
return FeedbackStatus.NORMAL()
}
fun snapshot(): SessionToken {
return SessionToken(view(), ruleOrdering.ruleTags, dispatchingFront.state())
}
fun snapshot(): SessionToken =
SessionTokenImpl(view(), ruleOrdering.ruleTags, dispatchingFront.state())
/**
* Called to update the state with the currently active constraint occurrence.

View File

@ -0,0 +1,31 @@
/*
* 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.core.internal
import jetbrains.mps.logic.reactor.core.DispatchingFrontState
import jetbrains.mps.logic.reactor.evaluation.MatchJournalView
import jetbrains.mps.logic.reactor.evaluation.SessionToken
data class SessionTokenImpl(
private val journalView: MatchJournal.View,
private val ruleTags: Iterable<Any>,
private val frontState: DispatchingFrontState
) : SessionToken {
override fun getJournalView(): MatchJournalView = journalView
override fun getRuleTags(): Iterable<Any> = ruleTags
override fun getFrontState(): DispatchingFrontState = frontState
}

View File

@ -16,8 +16,6 @@
package jetbrains.mps.logic.reactor.evaluation;
import jetbrains.mps.logic.reactor.core.SessionToken;
/**
* @author Fedor Isakov
*/

View File

@ -17,8 +17,7 @@
package jetbrains.mps.logic.reactor.evaluation;
import jetbrains.mps.logic.reactor.core.IncrementalProgramSpec;
import jetbrains.mps.logic.reactor.core.SessionToken;
import jetbrains.mps.logic.reactor.program.IncrementalProgramSpec;
import jetbrains.mps.logic.reactor.program.Program;
/**

View File

@ -14,20 +14,20 @@
* limitations under the License.
*/
package jetbrains.mps.logic.reactor.core
package jetbrains.mps.logic.reactor.evaluation;
import jetbrains.mps.logic.reactor.program.Constraint
import jetbrains.mps.logic.reactor.program.Rule
import gnu.trove.set.TIntSet;
import java.util.List;
interface IncrementalProgramSpec
{
fun isPrincipal(ctr: Constraint): Boolean
fun isPrincipal(rule: Rule): Boolean
object NonIncrSpec : IncrementalProgramSpec
{
override fun isPrincipal(ctr: Constraint): Boolean = false
override fun isPrincipal(rule: Rule): Boolean = false
public interface MatchJournalChunk {
interface Entry {
ConstraintOccurrence occ();
boolean discarded();
}
}
RuleMatch match();
int id();
TIntSet justifications();
List<Entry> entriesLog();
}

View File

@ -0,0 +1,29 @@
/*
* 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.evaluation;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public interface MatchJournalView {
@NotNull
List<MatchJournalChunk> getChunks();
int getNextChunkId();
StoreView getStoreView();
}

View File

@ -14,8 +14,8 @@
* limitations under the License.
*/
package jetbrains.mps.logic.reactor.core
package jetbrains.mps.logic.reactor.evaluation;
import jetbrains.mps.logic.reactor.core.internal.MatchJournal
data class SessionToken(val journalView: MatchJournal.View, val ruleTags: Iterable<Any>, val frontState: DispatchingFrontState)
// fixme: empty interface and unchecked cast to RuleMatchingProbe in EvaluationSessionImpl
public interface RuleMatchingProbeState {
}

View File

@ -0,0 +1,29 @@
/*
* 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.evaluation;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
public interface SessionToken {
@NotNull()
MatchJournalView getJournalView();
@NotNull()
Iterable<Object> getRuleTags();
@NotNull()
Map<Object, RuleMatchingProbeState> getFrontState();
}

View File

@ -0,0 +1,33 @@
/*
* 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);
class NonIncrSpec implements IncrementalProgramSpec {
@Override
public boolean isPrincipal(Constraint ctr) { return false; }
@Override
public boolean isPrincipal(Rule rule) { return false; }
}
NonIncrSpec DefaultSpec = new NonIncrSpec();
}

View File

@ -1,8 +1,8 @@
import jetbrains.mps.logic.reactor.core.IncrementalProgramSpec
import jetbrains.mps.logic.reactor.program.IncrementalProgramSpec
import jetbrains.mps.logic.reactor.core.Occurrence
import jetbrains.mps.logic.reactor.core.ReactorLifecycle
import jetbrains.mps.logic.reactor.core.SessionToken
import jetbrains.mps.logic.reactor.core.internal.MatchJournal
import jetbrains.mps.logic.reactor.evaluation.SessionToken
import jetbrains.mps.logic.reactor.evaluation.EvaluationResult
import jetbrains.mps.logic.reactor.evaluation.EvaluationSession
import jetbrains.mps.logic.reactor.program.Constraint
@ -65,7 +65,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: IncrementalProgramSpec, sessionToken: SessionToken, resultHandler: (EvaluationResult) -> Unit )
: Pair<Builder, EvaluationResult>
{
val result = EvaluationSession.newSession(program(name))
@ -80,10 +80,10 @@ class TestIncrementalProgram {
private fun EvaluationResult.chunksSymbolView() = this.token().journalView.chunks.map {
it.entriesLog().map { entry -> !entry.isDiscarded to entry.occ.constraint().symbol() }
it.entriesLog().map { entry -> !entry.discarded() to entry.occ().constraint().symbol() }
}
private fun EvaluationResult.lastChunk() = this.token().journalView.chunks.last()
private fun EvaluationResult.lastChunk() = this.token().journalView.chunks.last() as MatchJournal.Chunk
private fun EvaluationResult.countChunks() = this.token().journalView.chunks.size