Hide mutable collection of occurrences in Chunk and add 'principleConstraint' fun to its interface
This commit is contained in:
parent
c9b486c170
commit
e33df7aac2
|
|
@ -19,6 +19,7 @@ package jetbrains.mps.logic.reactor.core
|
|||
import jetbrains.mps.logic.reactor.program.Constraint
|
||||
import jetbrains.mps.logic.reactor.program.Rule
|
||||
|
||||
|
||||
interface IncrementalProgramSpec
|
||||
{
|
||||
fun isPrincipal(ctr: Constraint): Boolean
|
||||
|
|
|
|||
|
|
@ -48,25 +48,25 @@ interface MatchJournal : MutableIterable<MatchJournal.Chunk> {
|
|||
|
||||
data class View(val chunks: List<Chunk>, val nextChunkId: Int)
|
||||
|
||||
class Chunk(val match: RuleMatch, val id: Int, val justifications: Justs) : Pos {
|
||||
abstract class Chunk(val match: RuleMatch, val id: Int, val justifications: Justs) : Pos
|
||||
{
|
||||
data class Entry(val occ: Occurrence, val isDiscarded: Boolean = false) {
|
||||
override fun toString() = (if (isDiscarded) '-' else '+') + occ.toString()
|
||||
}
|
||||
|
||||
var occurrences: MutableList<Entry> = mutableListOf()
|
||||
abstract fun occurrences(): List<Entry>
|
||||
abstract fun findOccurrence(ctr: Constraint): Occurrence?
|
||||
abstract fun principalConstraint(): Constraint?
|
||||
|
||||
fun findOccurrence(ctr: Constraint): Occurrence? =
|
||||
occurrences.find { !it.isDiscarded && it.occ.constraint.symbol() == ctr.symbol() }?.occ
|
||||
|
||||
override fun toString() = "(id=$id, $justifications, ${match.rule().uniqueTag()}, $occurrences)"
|
||||
override fun toString() = "(id=$id, $justifications, ${match.rule().uniqueTag()}, ${occurrences()})"
|
||||
override fun equals(other: Any?) =
|
||||
other is Chunk
|
||||
&& other.id == id
|
||||
&& other.occurrences == occurrences
|
||||
&& other.occurrences() == occurrences()
|
||||
&& other.justifications == justifications
|
||||
|
||||
override fun chunk(): Chunk = this
|
||||
override fun entriesInChunk(): Int = occurrences.size
|
||||
override fun entriesInChunk(): Int = occurrences().size
|
||||
}
|
||||
|
||||
interface Pos {
|
||||
|
|
@ -82,34 +82,32 @@ internal open class MatchJournalImpl(
|
|||
) : MatchJournal
|
||||
{
|
||||
// invariant: never empty
|
||||
private val hist: MutableList<MatchJournal.Chunk>
|
||||
private val hist: MutableList<ChunkImpl>
|
||||
private var nextChunkId: Int
|
||||
|
||||
init {
|
||||
if (view == null) {
|
||||
hist = LinkedList<MatchJournal.Chunk>()
|
||||
hist = LinkedList()
|
||||
nextChunkId = 0
|
||||
val initChunk = MatchJournal.Chunk(InitRuleMatch, nextChunkId++, justsOf())
|
||||
val initChunk = ChunkImpl(ispec, InitRuleMatch, nextChunkId++, justsOf())
|
||||
hist.add(initChunk)
|
||||
} else {
|
||||
// fixme: check somehow that initial chunk is present?
|
||||
hist = LinkedList<MatchJournal.Chunk>(view.chunks)
|
||||
hist = LinkedList(view.chunks as List<ChunkImpl>)
|
||||
nextChunkId = view.nextChunkId
|
||||
}
|
||||
}
|
||||
|
||||
constructor(view: MatchJournal.View? = null) : this(IncrementalProgramSpec.NonIncrSpec, view)
|
||||
|
||||
private var pos: MutableListIterator<MatchJournal.Chunk> = hist.listIterator()
|
||||
private var current: MatchJournal.Chunk = pos.next() // take the initial chunk, move pos
|
||||
private var pos: MutableListIterator<ChunkImpl> = hist.listIterator()
|
||||
private var current: ChunkImpl = pos.next() // take the initial chunk, move pos
|
||||
|
||||
|
||||
override fun iterator() = hist.iterator()
|
||||
override fun iterator(): MutableIterator<MatchJournal.Chunk> = hist.iterator()
|
||||
|
||||
|
||||
override fun logMatch(match: RuleMatch) {
|
||||
// TODO: think, what about principal (i.e. 'matching') rules, but with empty head justs?
|
||||
|
||||
// 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.
|
||||
|
|
@ -117,7 +115,7 @@ internal open class MatchJournalImpl(
|
|||
if (ispec.isPrincipal(match.rule()) || !justs.isEmpty) {
|
||||
|
||||
justs.add(nextChunkId)
|
||||
val newChunk = MatchJournal.Chunk(match, nextChunkId, justs)
|
||||
val newChunk = ChunkImpl(ispec, match, nextChunkId, justs)
|
||||
pos.add(newChunk)
|
||||
|
||||
++nextChunkId
|
||||
|
|
@ -183,7 +181,7 @@ internal open class MatchJournalImpl(
|
|||
|
||||
val set = HashSet<Id<Occurrence>>()
|
||||
for (chunk in hist) { // initial chunk is counted too
|
||||
chunk.occurrences.forEach {
|
||||
chunk.occurrences().forEach {
|
||||
if (it.isDiscarded) set.remove(Id(it.occ)) else set.add(Id(it.occ))
|
||||
}
|
||||
if (chunk === current) {
|
||||
|
|
@ -194,6 +192,27 @@ internal open class MatchJournalImpl(
|
|||
}
|
||||
|
||||
|
||||
private class ChunkImpl(val ispec: IncrementalProgramSpec, match: RuleMatch, id: Int, justifications: Justs) : MatchJournal.Chunk(match, id, justifications)
|
||||
{
|
||||
var occurrences: MutableList<MatchJournal.Chunk.Entry> = mutableListOf()
|
||||
|
||||
override fun occurrences(): List<MatchJournal.Chunk.Entry> = occurrences
|
||||
|
||||
override fun findOccurrence(ctr: Constraint): Occurrence? =
|
||||
occurrences.find { !it.isDiscarded && it.occ.constraint.symbol() == ctr.symbol() }?.occ
|
||||
|
||||
override fun principalConstraint(): Constraint? {
|
||||
try {
|
||||
val body = match.rule().bodyAlternation().first()
|
||||
val princProds = body.filter { it is Constraint && it.isPrincipal() }
|
||||
return princProds.first() as Constraint
|
||||
} catch (e: NoSuchElementException) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class StoreViewImpl(occurrences: Sequence<Occurrence>) : StoreView {
|
||||
|
||||
val allOccurrences = occurrences.toSet()
|
||||
|
|
|
|||
|
|
@ -142,8 +142,7 @@ internal class ProcessingStateImpl(private var dispatchingFront: Dispatcher.Disp
|
|||
|
||||
while (it.hasNext()) { // note: if there's only an initial chunk, we have nothing to do
|
||||
val chunk = it.next()
|
||||
val chunkRule = chunk.match.rule()
|
||||
val pp = chunkRule.principalOccurrence()
|
||||
val pp = chunk.principalConstraint()
|
||||
|
||||
// Does this chunk have principal occurrence and can activate anything at all?
|
||||
if (pp != null) {
|
||||
|
|
@ -174,6 +173,7 @@ internal class ProcessingStateImpl(private var dispatchingFront: Dispatcher.Disp
|
|||
// either as the last one, after all existing activations
|
||||
// or according to the ordering between rules.
|
||||
|
||||
val chunkRule = chunk.match.rule()
|
||||
val currRuleOrder = ruleOrder[chunkRule.uniqueTag()]
|
||||
?: throw(IllegalStateException("There can be no chunks with rules not in rule index!"))
|
||||
val candRuleOrder = ruleOrder[candRule.uniqueTag()]
|
||||
|
|
@ -294,14 +294,4 @@ internal class ProcessingStateImpl(private var dispatchingFront: Dispatcher.Disp
|
|||
|
||||
|
||||
private fun RuleMatch.allStored() = (matchHeadKept() + matchHeadReplaced()).all { co -> (co as Occurrence).stored }
|
||||
|
||||
private fun Rule.headAll() = headKept() + headReplaced()
|
||||
|
||||
// todo: use IncrementalProgramSpec; move method to Chunk, supposedly?
|
||||
private fun Rule.principalOccurrence(): Constraint? {
|
||||
val princProds = bodyAlternation().first().filter {
|
||||
it is Constraint && it.isPrincipal()
|
||||
}
|
||||
return if (princProds.isNotEmpty()) princProds.first() as Constraint else null
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue