MatchJournal now adds chunks for principal occurrences: search is simplified, case of several principal occs in rule is handled.
This commit is contained in:
parent
43a8838c5a
commit
ef2627cab4
|
|
@ -112,14 +112,19 @@ class Dispatcher (val ruleIndex: RuleIndex) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a new [DispatchingFront] instance which "forgot" that it seen occurrence.
|
||||
* Need it for incremental reactivations to discern them from reactivations due to logicals.
|
||||
* Returns a new [DispatchingFront] instance which "forgot" that it has seen occurrence.
|
||||
* Needed for incremental reactivations to discern them from reactivations due to logicals.
|
||||
*/
|
||||
internal fun forgetSeen(dropped: Occurrence) =
|
||||
forRelatedProbe(dropped) { probe ->
|
||||
probe.forgetSeen(dropped)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new [DispatchingFront] instance which contracts state with this occurrence
|
||||
* and "forgets" that has seen it or that consumed any matches involving it.
|
||||
* Needed for pruning outdated unrelevant state on incremental reactivations.
|
||||
*/
|
||||
internal fun forget(dropped: Occurrence) =
|
||||
forRelatedProbe(dropped) { probe ->
|
||||
probe.contract(dropped).forgetSeen(dropped).forgetConsumed(dropped)
|
||||
|
|
|
|||
|
|
@ -91,26 +91,11 @@ interface MatchJournal : MutableIterable<MatchJournal.Chunk> {
|
|||
* Also serves as a comparator for positions: later in journal means greater.
|
||||
*/
|
||||
interface Index : Comparator<Pos> {
|
||||
|
||||
/**
|
||||
* Returns [Chunk] where provided occurrence was activated.
|
||||
* Works not for all occurrences: may return null even if there exists activating chunk.
|
||||
* Must work for principal occurrences.
|
||||
* Returns [Chunk] where provided principal occurrence was activated.
|
||||
* Returns null for non-principal occurrences.
|
||||
*/
|
||||
fun activatingChunkOf(occId: Id<Occurrence>): Chunk?
|
||||
|
||||
/**
|
||||
* Returns position of the first principal occurrence activated in provided chunk.
|
||||
* Returns null if the chunk activates no principal occurrences.
|
||||
*/
|
||||
fun principalOccurrenceOf(chunk: Chunk): Pos?
|
||||
|
||||
/**
|
||||
* Find [Pos] by occurrence.
|
||||
*/
|
||||
fun principalPos(occ: Id<Occurrence>): Pos? =
|
||||
// just a composition of two operations
|
||||
activatingChunkOf(occ)?.let { principalOccurrenceOf(it) }
|
||||
fun activatingChunkOf(occId: Id<Occurrence>): OccChunk?
|
||||
|
||||
/**
|
||||
* Find [Pos] at which provided match was triggered.
|
||||
|
|
@ -121,7 +106,7 @@ interface MatchJournal : MutableIterable<MatchJournal.Chunk> {
|
|||
// The latest matched occurrence from match's head is(by definition)
|
||||
// the occurrence which activated this match.
|
||||
match.signature().mapNotNull { occSig ->
|
||||
occSig?.let { principalPos(it) }
|
||||
occSig?.let { activatingChunkOf(it)?.toPos() }
|
||||
}.maxWith(this) // compare positions: find latest
|
||||
}
|
||||
|
||||
|
|
@ -136,11 +121,13 @@ interface MatchJournal : MutableIterable<MatchJournal.Chunk> {
|
|||
)
|
||||
}
|
||||
|
||||
abstract class Chunk(val match: RuleMatch, val id: Int, val justifications: Justs) : MatchJournalChunk
|
||||
{
|
||||
override fun match(): RuleMatch = match
|
||||
override fun id(): Int = id
|
||||
override fun justifications(): TIntSet = justifications
|
||||
interface Chunk : MatchJournalChunk {
|
||||
val id: Int
|
||||
val justifications: Justs
|
||||
|
||||
// fixme: hide rm-mutability
|
||||
var entries: MutableList<Entry>
|
||||
override fun entriesLog(): List<Entry> = entries
|
||||
|
||||
data class Entry(val occ: Occurrence, val discarded: Boolean = false) : MatchJournalChunk.Entry {
|
||||
override fun occ(): Occurrence = occ
|
||||
|
|
@ -148,10 +135,9 @@ interface MatchJournal : MutableIterable<MatchJournal.Chunk> {
|
|||
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 override fun entriesLog(): List<Entry>
|
||||
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 }
|
||||
|
||||
|
|
@ -161,11 +147,31 @@ interface MatchJournal : MutableIterable<MatchJournal.Chunk> {
|
|||
*/
|
||||
fun activated(): List<Occurrence> = entriesLog().allOccurrences()
|
||||
|
||||
override fun toString() = "(id=${id()}, ${justifications()}, ${match().rule().uniqueTag()}, ${entriesLog()})"
|
||||
|
||||
fun toPos(): Pos = Pos(this, entriesLog().size)
|
||||
}
|
||||
|
||||
class MatchChunk(override val id: Int, val match: RuleMatch) : Chunk {
|
||||
override val justifications: Justs = match.headJustifications().apply { add(id) }
|
||||
|
||||
override var entries: MutableList<Chunk.Entry> = mutableListOf()
|
||||
|
||||
override fun entriesLog(): List<Chunk.Entry> = entries
|
||||
|
||||
override fun toString() = "(id=$id, $justifications, ${match.rule().tag()}, $entries)"
|
||||
}
|
||||
|
||||
class OccChunk(override val id: Int, val occ: Occurrence) : Chunk {
|
||||
|
||||
init { occ.justifications.add(id) }
|
||||
|
||||
override val justifications: Justs
|
||||
get() = occ.justifications
|
||||
|
||||
override var entries: MutableList<Chunk.Entry> = mutableListOf()
|
||||
|
||||
override fun toString() = "(id=$id, $justifications, activation of $occ)"
|
||||
}
|
||||
|
||||
open class Pos(val chunk: Chunk, val entriesCount: Int) {
|
||||
val occ: Occurrence
|
||||
get() = chunk.entriesLog()[entriesCount - 1].occ()
|
||||
|
|
@ -176,6 +182,8 @@ interface MatchJournal : MutableIterable<MatchJournal.Chunk> {
|
|||
&& other.entriesCount == entriesCount
|
||||
|
||||
override fun hashCode(): Int = 31 * chunk.hashCode() + entriesCount
|
||||
|
||||
override fun toString(): String = "($chunk, $entriesCount)"
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import jetbrains.mps.logic.reactor.core.Controller
|
|||
import jetbrains.mps.logic.reactor.core.Justs
|
||||
import jetbrains.mps.logic.reactor.core.Occurrence
|
||||
import jetbrains.mps.logic.reactor.core.justsOf
|
||||
import jetbrains.mps.logic.reactor.core.internal.MatchJournal.*
|
||||
import jetbrains.mps.logic.reactor.evaluation.ConstraintOccurrence
|
||||
import jetbrains.mps.logic.reactor.evaluation.MatchJournalView
|
||||
import jetbrains.mps.logic.reactor.evaluation.RuleMatch
|
||||
|
|
@ -31,25 +32,28 @@ import jetbrains.mps.logic.reactor.program.*
|
|||
import jetbrains.mps.logic.reactor.util.Id
|
||||
import java.util.*
|
||||
|
||||
//typealias Chunk = MatchJournal.Chunk
|
||||
|
||||
internal open class MatchJournalImpl(
|
||||
private val ispec: IncrementalProgramSpec,
|
||||
view: MatchJournalView? = null
|
||||
) : MatchJournal {
|
||||
|
||||
// invariant: never empty
|
||||
private val hist: IteratorMutableList<ChunkImpl>
|
||||
private val hist: IteratorMutableList<Chunk>
|
||||
private var nextChunkId: Int
|
||||
|
||||
init {
|
||||
if (view == null) {
|
||||
nextChunkId = 0
|
||||
val initChunk = ChunkImpl(InitRuleMatch, nextChunkId, justsOf(nextChunkId))
|
||||
nextChunkId++
|
||||
hist = IteratorMutableList(LinkedList<ChunkImpl>().apply { add(initChunk) })
|
||||
val initChunk = MatchChunk(nextChunkId++, InitRuleMatch)
|
||||
hist = IteratorMutableList(LinkedList<Chunk>().apply { add(initChunk) })
|
||||
} else {
|
||||
// assert that initial chunk is present
|
||||
assert (view.chunks.first().match() is InitRuleMatch)
|
||||
hist = IteratorMutableList(LinkedList(view.chunks as List<ChunkImpl>))
|
||||
with (view.chunks.first()) {
|
||||
assert(this is MatchChunk && match is InitRuleMatch)
|
||||
}
|
||||
hist = IteratorMutableList(LinkedList(view.chunks as List<Chunk>))
|
||||
nextChunkId = view.nextChunkId
|
||||
}
|
||||
}
|
||||
|
|
@ -57,37 +61,31 @@ internal open class MatchJournalImpl(
|
|||
constructor(view: MatchJournal.View? = null) : this(IncrementalProgramSpec.DefaultSpec, view)
|
||||
|
||||
// pointer to current position in history where logging (chunk additions) and log erasing (chunk removals) happens
|
||||
private var posPtr: MutableListIterator<ChunkImpl> = hist.listIterator()
|
||||
private var posPtr: MutableListIterator<Chunk> = hist.listIterator()
|
||||
// invariant: always contains valid chunk
|
||||
private var current: ChunkImpl = posPtr.next() // take the initial chunk, move posPtr
|
||||
private var current: Chunk = posPtr.next() // take the initial chunk, move posPtr
|
||||
|
||||
|
||||
override fun iterator(): MutableIterator<MatchJournal.Chunk> = hist.iterator()
|
||||
override fun iterator(): MutableIterator<Chunk> = hist.iterator()
|
||||
|
||||
|
||||
override fun logMatch(match: RuleMatch) {
|
||||
// Two cases when a new chunk is created:
|
||||
// either the set of justifications isn't empty
|
||||
// or we directly know that we deal with a principal rule.
|
||||
val justs = match.headJustifications()
|
||||
if (ispec.isPrincipal(match.rule()) || !justs.isEmpty) {
|
||||
|
||||
justs.add(nextChunkId)
|
||||
val newChunk = ChunkImpl(match, nextChunkId, justs)
|
||||
posPtr.add(newChunk)
|
||||
|
||||
++nextChunkId
|
||||
current = newChunk
|
||||
if (ispec.isPrincipal(match.rule())) {
|
||||
current = MatchChunk(nextChunkId++, match)
|
||||
posPtr.add(current)
|
||||
}
|
||||
|
||||
// Log discards
|
||||
// Log discarded occurrences
|
||||
(match as RuleMatchImpl).forEachReplaced { occ ->
|
||||
current.entries.add(MatchJournal.Chunk.Entry(occ, true))
|
||||
current.entries.add(Chunk.Entry(occ, true))
|
||||
}
|
||||
}
|
||||
|
||||
override fun logActivation(occ: Occurrence) {
|
||||
current.entries.add(MatchJournal.Chunk.Entry(occ))
|
||||
if (ispec.isPrincipal(occ.constraint)) {
|
||||
current = OccChunk(nextChunkId++, occ)
|
||||
posPtr.add(current)
|
||||
}
|
||||
current.entries.add(Chunk.Entry(occ))
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -138,7 +136,7 @@ internal open class MatchJournalImpl(
|
|||
|
||||
override fun storeView(): StoreView = StoreViewImpl(allOccurrences())
|
||||
|
||||
override fun index(): MatchJournal.Index = IndexImpl(ispec, hist)
|
||||
override fun index(): MatchJournal.Index = IndexImpl(hist)
|
||||
|
||||
private fun allOccurrences(): Sequence<Occurrence> {
|
||||
// the following loop doesn't handle this case of starting posPtr, when 'current' isn't valid (e.g. just right after resetPos())
|
||||
|
|
@ -168,44 +166,22 @@ internal open class MatchJournalImpl(
|
|||
override fun listIterator(index: Int): MutableListIterator<E> = l.listIterator(index)
|
||||
}
|
||||
|
||||
private class ChunkImpl(match: RuleMatch, id: Int, justifications: Justs) : MatchJournal.Chunk(match, id, justifications) {
|
||||
|
||||
var entries: MutableList<Entry> = mutableListOf()
|
||||
|
||||
override fun entriesLog(): List<Entry> = entries
|
||||
}
|
||||
|
||||
private class IndexImpl(ispec: IncrementalProgramSpec, chunks: Iterable<ChunkImpl>): MatchJournal.Index
|
||||
private class IndexImpl(chunks: Iterable<Chunk>): MatchJournal.Index
|
||||
{
|
||||
private val chunkOrder: Map<Int, Int>
|
||||
// only for principal constraints
|
||||
private val parentChunks: Map<Id<Occurrence>, MatchJournal.Chunk>
|
||||
|
||||
private val principalOccurrences: Map<Int, MatchJournal.Pos>
|
||||
private val chunkOrder = HashMap<Int, Int>()
|
||||
private val occChunks = HashMap<Id<Occurrence>, OccChunk>()
|
||||
|
||||
init {
|
||||
chunkOrder = HashMap<Int, Int>().apply {
|
||||
chunks.forEachIndexed { index, chunk -> put(chunk.id(), index) }
|
||||
}
|
||||
chunks.forEachIndexed { index, chunk ->
|
||||
chunkOrder[chunk.id] = index
|
||||
|
||||
val m = HashMap<Id<Occurrence>, MatchJournal.Chunk>()
|
||||
val m2 = HashMap<Int, MatchJournal.Pos>()
|
||||
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.discarded()) {
|
||||
m[Id(e.occ)] = chunk
|
||||
m2[chunk.id] = MatchJournal.Pos(chunk, index + 1)
|
||||
}
|
||||
if (chunk is OccChunk) {
|
||||
occChunks[Id(chunk.occ)] = chunk
|
||||
}
|
||||
}
|
||||
parentChunks = m
|
||||
principalOccurrences = m2
|
||||
}
|
||||
|
||||
override fun activatingChunkOf(occId: Id<Occurrence>) = parentChunks[occId]
|
||||
|
||||
override fun principalOccurrenceOf(chunk: MatchJournal.Chunk) = principalOccurrences[chunk.id]
|
||||
override fun activatingChunkOf(occId: Id<Occurrence>) = occChunks[occId]
|
||||
|
||||
// todo: throw for invalid positions?
|
||||
override fun compare(lhs: MatchJournal.Pos, rhs: MatchJournal.Pos): Int {
|
||||
|
|
@ -231,19 +207,19 @@ internal open class MatchJournalImpl(
|
|||
object EmptyRule : Rule() {
|
||||
override fun kind(): Kind = Kind.PROPAGATION
|
||||
override fun uniqueTag(): Any = tag().hashCode()
|
||||
override fun tag(): String = "initialrule${"initial_rule".hashCode()}"
|
||||
override fun tag(): String = "initialrule${"initialrule".hashCode()}"
|
||||
override fun headKept(): Iterable<Constraint> = emptyList()
|
||||
override fun headReplaced(): Iterable<Constraint> = emptyList()
|
||||
override fun guard(): Iterable<Predicate> = emptyList()
|
||||
override fun bodyAlternation(): Iterable<Iterable<AndItem>> = emptyList() // fixme: maybe provide 'main' constraint prod?
|
||||
override fun bodyAlternation(): Iterable<Iterable<AndItem>> = emptyList()
|
||||
override fun all(): Iterable<AndItem> = emptyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun MatchJournal.justs() = this.currentPos().chunk.justifications()
|
||||
fun MatchJournal.justs() = this.currentPos().chunk.justifications
|
||||
|
||||
private fun RuleMatch.headJustifications(): Justs {
|
||||
fun RuleMatch.headJustifications(): Justs {
|
||||
val res: Justs = justsOf()
|
||||
this.matchHeadKept().forEach { it.justifications().let { res.addAll(it) } }
|
||||
this.matchHeadReplaced().forEach { it.justifications().let { res.addAll(it) } }
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ internal class ProcessingStateImpl(private var dispatchingFront: Dispatcher.Disp
|
|||
|
||||
private data class ExecPos(val pos: MatchJournal.Pos, val activeOcc: Occurrence)
|
||||
|
||||
private data class MatchCandidate(val rule: Rule, val occ: Occurrence, val occParentId: Int)
|
||||
private data class MatchCandidate(val rule: Rule, val occChunk: MatchJournal.OccChunk)
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -87,13 +87,12 @@ internal class ProcessingStateImpl(private var dispatchingFront: Dispatcher.Disp
|
|||
while (it.hasNext()) {
|
||||
val chunk = it.next()
|
||||
|
||||
val toRemove = ruleIds.contains(chunk.match().rule().uniqueTag())
|
||||
if (toRemove) {
|
||||
if (chunk is MatchJournal.MatchChunk && ruleIds.contains(chunk.match.rule().uniqueTag())) {
|
||||
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)
|
||||
}
|
||||
|
|
@ -102,33 +101,36 @@ internal class ProcessingStateImpl(private var dispatchingFront: Dispatcher.Disp
|
|||
// todo: do need to reactivate only the main, matching~activating match?
|
||||
// (i.e. don't reactivate additional, inactive heads that only completed the match?)
|
||||
execQueue.addAll(validOccs.mapNotNull { occ ->
|
||||
journalIndex.activatingChunkOf(Id(occ))?.let { chunkPos ->
|
||||
ExecPos(chunkPos.toPos(), occ)
|
||||
journalIndex.activatingChunkOf(Id(occ))?.let { chunk ->
|
||||
ExecPos(chunk.toPos(), occ)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Invalidating dependent chunks
|
||||
val toInvalidate = toRemove || chunk.justifications.intersects(justificationRoots)
|
||||
if (toInvalidate) {
|
||||
// Remove the chunk from the journal
|
||||
if (chunk.justifications.intersects(justificationRoots)) {
|
||||
|
||||
// Remove chunk from the journal
|
||||
it.remove()
|
||||
trace.invalidate(chunk.match())
|
||||
|
||||
// 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)
|
||||
|
||||
// Need to 'cancel' discarding.
|
||||
// These nodes may become valid and will be processed due to reactivation of needed occurrences.
|
||||
chunk.match().matchHeadReplaced().forEach {
|
||||
dispatchingFront = dispatchingFront.forget(it as Occurrence)
|
||||
}
|
||||
// 'Undo' all activated in this chunk occurrences
|
||||
chunk.activated().forEach {
|
||||
dispatchingFront = dispatchingFront.forget(it)
|
||||
}
|
||||
|
||||
if (chunk is MatchJournal.MatchChunk) {
|
||||
trace.invalidate(chunk.match)
|
||||
|
||||
// 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)
|
||||
|
||||
// Need to 'cancel' discarding.
|
||||
// These nodes may become valid and will be processed due to reactivation of needed occurrences.
|
||||
chunk.match.matchHeadReplaced().forEach {
|
||||
dispatchingFront = dispatchingFront.forget(it as Occurrence)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prevChunk = chunk
|
||||
|
|
@ -146,21 +148,19 @@ internal class ProcessingStateImpl(private var dispatchingFront: Dispatcher.Disp
|
|||
var prevChunk = chunk
|
||||
|
||||
while (true) {
|
||||
// Does this chunk have principal occurrence and can activate anything at all?
|
||||
journalIndex.principalOccurrenceOf(chunk)?.occ?.let { pOcc ->
|
||||
|
||||
if (chunk is MatchJournal.OccChunk) {
|
||||
// filters out rules using occurrence's arguments
|
||||
val allRuleCandidates = ruleIndex.forOccurrence(pOcc).map { it.uniqueTag() }.toHashSet()
|
||||
val allRuleCandidates = ruleIndex.forOccurrence(chunk.occ).map { it.uniqueTag() }.toHashSet()
|
||||
|
||||
for (rule in rules) {
|
||||
if (allRuleCandidates.contains(rule.uniqueTag()) && canMatch(rule, pOcc)) {
|
||||
if (allRuleCandidates.contains(rule.uniqueTag()) && canMatch(rule, chunk.occ)) {
|
||||
// Can this rule be matched by principal occurrence?
|
||||
// Then we will need to find the place among existing child chunks
|
||||
// (i.e. among some number of following ones)
|
||||
// to activate this occurrence, to (possibly) match this rule.
|
||||
// Also remember the parent justification of this rule candidate
|
||||
// to drop it from monitoring when child chunks end.
|
||||
activationCandidates.add(MatchCandidate(rule, pOcc, chunk.id))
|
||||
activationCandidates.add(MatchCandidate(rule, chunk))
|
||||
// todo: also use the rule to help Dispatcher in future?
|
||||
// i.e. try matching only on the candidate rule
|
||||
}
|
||||
|
|
@ -169,13 +169,14 @@ internal class ProcessingStateImpl(private var dispatchingFront: Dispatcher.Disp
|
|||
|
||||
val aIt = activationCandidates.listIterator()
|
||||
while (aIt.hasNext()) {
|
||||
val (candRule, candOcc, parentId) = aIt.next()
|
||||
val (candRule, occChunk) = aIt.next()
|
||||
|
||||
// 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 childChunksEnded = !chunk.isDescendantOf(parentId)
|
||||
// either according to the ordering between rules.
|
||||
// or as the last one, after all existing activations
|
||||
val placeToInsertFound =
|
||||
chunk is MatchJournal.MatchChunk && ruleOrdering.compare(chunk.match.rule(), candRule) > 0
|
||||
val childChunksEnded = !chunk.isDescendantOf(occChunk.id)
|
||||
|
||||
val pos =
|
||||
// We need the previous chunk as pos here (i.e. adding after it).
|
||||
|
|
@ -184,8 +185,8 @@ internal class ProcessingStateImpl(private var dispatchingFront: Dispatcher.Disp
|
|||
else if (!it.hasNext()) chunk.toPos()
|
||||
else continue
|
||||
|
||||
execQueue.offer(ExecPos(pos, candOcc))
|
||||
trace.potentialMatch(candOcc, candRule)
|
||||
execQueue.offer(ExecPos(pos, occChunk.occ))
|
||||
trace.potentialMatch(occChunk.occ, candRule)
|
||||
// Drop the candidate if appropriate activation place is found.
|
||||
aIt.remove()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
package jetbrains.mps.logic.reactor.evaluation;
|
||||
|
||||
import gnu.trove.set.TIntSet;
|
||||
//import gnu.trove.set.TIntSet;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
|
|
@ -26,8 +26,7 @@ public interface MatchJournalChunk {
|
|||
boolean discarded();
|
||||
}
|
||||
|
||||
RuleMatch match();
|
||||
int id();
|
||||
TIntSet justifications();
|
||||
// int id();
|
||||
// TIntSet justifications();
|
||||
List<Entry> entriesLog();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue