Refactor ExecPos from ExecQueue to work with OccChunk instead of any Occurrence

This interface change it means that only Occurrences from previous session can be reexecuted.
This commit is contained in:
Grigorii Kirgizov 2020-02-03 13:59:56 +03:00
parent b909706a04
commit ab3eb716ae
4 changed files with 25 additions and 12 deletions

View File

@ -170,7 +170,7 @@ internal class ConstraintsProcessing(private var dispatchingFront: Dispatcher.Di
else
continue
execQueue.offer(pos, occChunk.occ)
execQueue.offer(pos, occChunk)
trace.potentialMatch(occChunk.occ, candRule)
// Drop the candidate if appropriate activation place is found.
aIt.remove()

View File

@ -28,7 +28,18 @@ internal class ExecutionQueue(
private val ruleOrdering: RuleOrdering
) {
private data class ExecPos(val pos: MatchJournal.Pos, val activeOcc: Occurrence)
/**
* Specifies position in [MatchJournal] for continuing Coderules program evaluation,
* where it's supposed that [pos] must be a descendant of [ancestor].
* (i.e. `pos.isDescendantOf(ancestor.id) == true`)
*/
private data class ExecPos(val pos: MatchJournal.Pos, val ancestor: MatchJournal.OccChunk) {
constructor(active: MatchJournal.OccChunk) : this(active.toPos(), active)
val activeOcc: Occurrence
get() = ancestor.occ
}
// It is a position in Journal from previous session,
// from which incremental execution continues.
@ -94,7 +105,7 @@ internal class ExecutionQueue(
// if it is a future match
if (pos2occ != null && journalIndex.compare(lastIncrementalRootPos, pos2occ.first) < 0) {
val idOcc = Id(pos2occ.second)
val idOcc = Id(pos2occ.second.occ)
postponedMatches[idOcc] = (postponedMatches[idOcc] ?: emptyList()) + listOf(m)
offer(pos2occ.first, pos2occ.second)
} else {
@ -135,21 +146,22 @@ internal class ExecutionQueue(
// (i.e. don't reactivate additional, inactive heads that only completed the match?)
fun offerAll(occs: Iterable<Occurrence>): Boolean =
execQueue.addAll(occs.mapNotNull { occ ->
journalIndex.activatingChunkOf(Id(occ))?.let { chunk ->
ExecPos(chunk.toPos(), occ).let {
journalIndex.activatingChunkOf(Id(occ))?.let { occChunk ->
ExecPos(occChunk).let {
if (seen.add(it)) it else null
}
}
})
fun offer(posInJournal: MatchJournal.Pos, activeOcc: Occurrence): Boolean =
ExecPos(posInJournal, activeOcc).let {
fun offer(posInJournal: MatchJournal.Pos, ancestor: MatchJournal.OccChunk): Boolean =
ExecPos(posInJournal, ancestor).let {
if (seen.add(it)) execQueue.offer(it) else false
}
// todo: remove
// special case when position in trace corresponds to position of activated occurrence
fun offer(posInJournal: MatchJournal.Pos): Boolean =
offer(posInJournal, posInJournal.occ)
// fun offer(posInJournal: MatchJournal.Pos): Boolean =
// offer(posInJournal, posInJournal.occ)
fun isEmpty(): Boolean = execQueue.isEmpty()

View File

@ -128,7 +128,7 @@ interface MatchJournal : MutableIterable<MatchJournal.Chunk> {
* according to its indexed head [Occurrence]s.
* May return null for matches of non-principal rules.
*/
fun activationPos(match: RuleMatchEx): Pair<Pos, Occurrence>?
fun activationPos(match: RuleMatchEx): Pair<Pos, OccChunk>?
/**
* Length of the indexed [MatchJournal]
@ -198,6 +198,7 @@ interface MatchJournal : MutableIterable<MatchJournal.Chunk> {
}
open class Pos(val chunk: Chunk, val entriesCount: Int) {
// todo: remove
val occ: Occurrence
get() = chunk.entriesLog()[entriesCount - 1].occ()

View File

@ -256,7 +256,7 @@ internal open class MatchJournalImpl(
override fun lastDescendantOf(occChunk: OccChunk): Chunk? = occChunk2LastDescendant[occChunk.id]
override fun activationPos(match: RuleMatchEx): Pair<Pos, Occurrence>? {
override fun activationPos(match: RuleMatchEx): Pair<Pos, OccChunk>? {
// The latest matched occurrence from match's head is
// (by definition) the occurrence which activated this match.
@ -277,7 +277,7 @@ internal open class MatchJournalImpl(
lastDescendantOf(activatingChunk)!!
else
activatingChunk
return posChunk.toPos() to activatingChunk.occ
return posChunk.toPos() to activatingChunk
}
// todo: throw for invalid positions?