Abstract java interfaces for incrementality-related classes for interop between reactor and coderules
This commit is contained in:
parent
79b08c6f83
commit
155266d8ca
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
package jetbrains.mps.logic.reactor.evaluation;
|
||||
|
||||
import jetbrains.mps.logic.reactor.core.SessionToken;
|
||||
|
||||
/**
|
||||
* @author Fedor Isakov
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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 {
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue