Drop unused code, cleanup and simplify code

This commit is contained in:
Fedor Isakov 2022-04-18 14:51:31 +02:00
parent dda4c9a7e6
commit 735c88cdba
12 changed files with 77 additions and 2469 deletions

View File

@ -69,36 +69,14 @@ interface Justified {
fun justifiedBy(other: Justified): Boolean =
this.justifications().contains(other.evidence)
/**
* Checks whether this [Justified] entity is supported by any of the [others] [Justified] entities.
*/
fun justifiedByAny(others: Collection<Justified>): Boolean =
others.any { this.justifiedBy(it) }
/**
* Checks whether this [Justified] entity is supported by the [others], and only by them.
*/
fun justifiedOnlyBy(others: Collection<Justified>): Boolean {
val allEvidence = justsFromCollection(others.map { it.evidence })
allEvidence.add(evidence)
return allEvidence.containsAll(justifications())
}
/**
* Append [Justifications] from [other] entity to justifications of this [Justified].
* After the operation this.justifiedBy(other) returns true.
*/
fun justifyBy(other: Justified): Unit {
// ensure operation doesn't break antisymmetric property of relation
assert(!other.justifiedBy(this) || this.evidence == other.evidence)
justifications().addAll(other.justifications())
}
/**
* Append [Justifications] from all [others] entities to justifications of this [Justified]
*/
fun justifyByAll(others: Iterable<Justified>): Unit = others.forEach { justifyBy(it) }
fun addJustifications(others: Iterable<Justified>): Unit = others.forEach {
// ensure operation doesn't break antisymmetric property of relation
assert(!it.justifiedBy(this) || evidence == it.evidence)
justifications().addAll(it.justifications())
}
}

View File

@ -94,6 +94,7 @@ class Occurrence (observable: LogicalStateObservable,
private fun handleFeedbackStatus(status: FeedbackStatus) {
if (status is FeedbackStatus.FAILED) {
// FIXME failureCause() is nullable, can't throw null
throw status.failure.failureCause()
}
}

View File

@ -56,23 +56,6 @@ internal class ConstraintsProcessing(
logicalState.clearController(controller)
}
fun evaluate(controller: Controller, prototype: Occurrence, inStatus: FeedbackStatus) : FeedbackStatus =
profiler.profile<FeedbackStatus>("activate_${prototype.constraint().symbol()}") {
// fixme: ensure justifications are tracked (incremented) correctly in processing & creator
// NB: provide new justifications instead of occ.justifications
with(JustifiedOccurrenceCreator(evidence(), initialChunk().justifications())) {
prototype.constraint.occurrence(
controller.logicalStateObservable(), prototype.arguments(), prototype.logicalContext(), prototype.sourceRule()
).let { occ ->
trace.activate(occ)
processActivated(controller, occ, initialChunk(), inStatus)
}
}
}
/**
* Called to update the state with the currently active constraint occurrence.
* Calls the controller to process matches (if any) that were triggered.

View File

@ -117,7 +117,7 @@ internal class EvaluationSessionImpl private constructor (
}
override fun endSession(session: SessionParts): SessionToken = with(session) {
SessionTokenImpl(journal.view(), ruleIndex.toRules(), emptyFrontState(), ruleIndex, logicalState, principalObservers.apply { clearTriggerReceiver() })
SessionTokenImpl(journal.storeView(), ruleIndex.toRules(), emptyFrontState(), ruleIndex, logicalState, principalObservers.apply { clearTriggerReceiver() })
}
override fun runSession(session: SessionParts, main: Constraint): EvaluationResult = with(session) {
@ -222,7 +222,7 @@ internal class EvaluationSessionImpl private constructor (
val invalidRules: Collection<Any>
): EvaluationResult {
override fun token() = token
override fun storeView(): StoreView = token.journalView.storeView
override fun storeView(): StoreView = token.storeView
override fun feedback(): EvaluationFeedback? = if (status is FAILED) status.failure else null
override fun invalidFeedbackKeys(): Collection<Any> = invalidFeedbackKeys
override fun invalidRules(): Collection<Any> = invalidRules

View File

@ -30,7 +30,7 @@ interface IncrSpecHolder {
val RuleMatch.isPrincipal get() = ispec.isPrincipal(this.rule())
val Rule.isPrincipal get() = ispec.isPrincipal(this)
// val Rule.isPrincipal get() = ispec.isPrincipal(this)
val RuleMatch.isWeakPrincipal get() = ispec.isWeakPrincipal(this.rule())

View File

@ -31,9 +31,8 @@ interface MatchJournal : EvidenceSource {
// for tests
companion object {
fun fromView(
ispec: IncrementalSpec = IncrementalSpec.DefaultSpec,
view: MatchJournal.View? = null
): MatchJournal = MatchJournalImpl(ispec, EvaluationTrace.NULL, view)
ispec: IncrementalSpec = IncrementalSpec.DefaultSpec
): MatchJournal = MatchJournalImpl(ispec, EvaluationTrace.NULL)
}
/**
@ -41,13 +40,13 @@ interface MatchJournal : EvidenceSource {
* Log occurrences discarded by match in current [Chunk].
* Returns added [Chunk], null for non-principal rules.
*/
fun logMatch(match: RuleMatch): MatchChunk?
fun logMatch(match: RuleMatch)
/**
* Log occurrence activation in current [Chunk].
* Returns added [Chunk], null for non-principal occurrences.
*/
fun logActivation(occ: Occurrence): OccChunk?
fun logActivation(occ: Occurrence)
/**
* Returns nearest [MatchChunk] which justifies current chunk.
@ -86,6 +85,7 @@ interface MatchJournal : EvidenceSource {
/**
* Returns snapshot of the journal.
* FOR TESTS ONLY
*/
fun view(): View
@ -96,15 +96,17 @@ interface MatchJournal : EvidenceSource {
fun storeView(): StoreView
fun basisRuleTags(chunk: Chunk): List<Any>
// NB: returns same collection of justifications, not copy
fun justifications() = this.currentPos().chunk.justifications()
fun evidence() = this.currentPos().chunk.evidence
/**
* Immutable snapshot of [MatchJournal].
* FOR TESTS ONLY
*/
data class View(val chunks: List<Chunk>, val evidenceSeed: Evidence) : MatchJournalView {
override fun getStoreView(): StoreView = StoreViewImpl(
chunks.flatMap { it.entries() }.allOccurrences().asSequence()
)
data class View(val chunks: List<Chunk>, val evidenceSeed: Evidence) {
}
/**
@ -176,46 +178,3 @@ interface ChunkIterator {
infix fun at(chunk: MatchJournal.Chunk) = current === chunk
}
interface MutableChunkIterator: ChunkIterator {
fun addChunk(chunk: MatchJournal.Chunk)
}
internal infix fun ChunkIterator.assertAt(pos: MatchJournal.Pos) {
if (!(this at pos))
throw IllegalStateException("Position wasn't found in journal: $pos")
}
internal 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<MatchJournal.Chunk.Entry>.allOccurrences(): List<Occurrence> {
val set = HashSet<Id<Occurrence>>()
for (it in this) {
val idOcc = Id(it.occ)
if (it.discarded) set.remove(idOcc) else set.add(idOcc)
}
return set.map { it.wrapped }
}
// NB: returns same collection of justifications, not copy
fun MatchJournal.justifications() = this.currentPos().chunk.justifications()
fun MatchJournal.evidence() = this.currentPos().chunk.evidence
// todo: this should be more correct
//fun MatchJournal.justifications() = this.parentChunk().justifications()
//fun MatchJournal.evidence() = this.parentChunk().evidence

View File

@ -32,8 +32,7 @@ import java.util.*
internal open class MatchJournalImpl(
override val ispec: IncrementalSpec,
val trace: EvaluationTrace = EvaluationTrace.NULL,
view: MatchJournal.View? = null
val trace: EvaluationTrace = EvaluationTrace.NULL
) : MatchJournal, IncrSpecHolder {
private abstract class ChunkImpl : Chunk {
@ -82,17 +81,12 @@ internal open class MatchJournalImpl(
final override fun nextEvidence(): Evidence = evidenceSeed++
init {
if (view == null) {
val initChunk = MatchChunkImpl(nextEvidence(), InitRuleMatch)
hist = IteratorMutableList(LinkedList<ChunkImpl>().apply {
add(CornerChunk)
add(initChunk)
add(CornerChunk)
})
} else {
hist = IteratorMutableList(LinkedList(view.chunks as List<ChunkImpl>))
evidenceSeed = view.evidenceSeed
}
val initChunk = MatchChunkImpl(nextEvidence(), InitRuleMatch)
hist = IteratorMutableList(LinkedList<ChunkImpl>().apply {
add(CornerChunk)
add(initChunk)
add(CornerChunk)
})
ancestorChunksStack = mutableListOf()
__cursor = Cursor(hist.listIterator())
@ -100,31 +94,25 @@ internal open class MatchJournalImpl(
assert(initialChunk.match is InitRuleMatch)
}
constructor(trace: EvaluationTrace = EvaluationTrace.NULL,
view: MatchJournal.View? = null) : this(IncrementalSpec.DefaultSpec, trace, view)
override fun logMatch(match: RuleMatch): MatchChunk? {
val added: MatchChunk?
constructor(trace: EvaluationTrace = EvaluationTrace.NULL) : this(IncrementalSpec.DefaultSpec, trace)
override fun logMatch(match: RuleMatch) {
if (match.isPrincipal) {
added = MatchChunkImpl(nextEvidence(), match)
__cursor.addChunk(added)
trackAncestor(added)
logAncestor(added)
val nextChunk = MatchChunkImpl(nextEvidence(), match)
__cursor.addChunk(nextChunk)
resetParentChunk(nextChunk)
pushParentChunk(nextChunk)
} else {
added = null
val dummy: Justified = MatchChunkImpl(nullEvidence, match) // collects justifications
trackAncestor(dummy)
resetParentChunk(dummy)
// If a non-principal match has any principal
// occurrences in head -- they must be tracked
logJustificationsFrom(match)
collectJustificationsFrom(match)
}
// Log discarded occurrences
(match as RuleMatchImpl).forEachReplaced { occ ->
__cursor.addEntryToCurrent(Chunk.Entry(occ, true))
}
return added
}
private fun indexChunk(chunk: Chunk) {
@ -134,18 +122,18 @@ internal open class MatchJournalImpl(
private fun lookupChunkByEvidence(evidence: Evidence) =
chunkIndex.get(evidence)
private fun trackAncestor(logEvent: Justified) {
private fun resetParentChunk(logEvent: Justified) {
while (!logEvent.justifiedBy(parentChunk())) {
ancestorChunksStack.pop()
}
assert(logEvent.justifiedBy(parentChunk()))
}
private fun logAncestor(nextChunk: MatchChunk) {
private fun pushParentChunk(nextChunk: MatchChunk) {
ancestorChunksStack.push(nextChunk)
}
private fun logJustificationsFrom(match: RuleMatch) {
private fun collectJustificationsFrom(match: RuleMatch) {
val parent: MatchChunk = parentChunk()
val moreJustified = match.allHeads().filter {
@ -155,24 +143,17 @@ internal open class MatchJournalImpl(
if (moreJustified.isNotEmpty()) {
__cursor.applyToPast(parent.toPos()) { child ->
child.justifyByAll(moreJustified)
child.addJustifications(moreJustified)
}
}
}
override fun logActivation(occ: Occurrence): OccChunk? {
val added: OccChunk?
trackAncestor(occ)
override fun logActivation(occ: Occurrence) {
resetParentChunk(occ)
if (occ.isPrincipal) {
added = OccChunkImpl(occ)
__cursor.addChunk(added)
} else {
added = null
__cursor.addChunk(OccChunkImpl(occ))
}
__cursor.addEntryToCurrent(Chunk.Entry(occ))
return added
}
internal fun resetOccurrences(occSpecs: List<Chunk.Entry>) =
@ -204,7 +185,7 @@ internal open class MatchJournalImpl(
override fun reset(pastPos: MatchJournal.Pos) {
__cursor.moveToPastRemoving(pastPos) {
popAncestor()
popParentChunk()
resetOccurrences(it.entries())
}
// drop occurrences at final chunk
@ -215,7 +196,7 @@ internal open class MatchJournalImpl(
__cursor assertAt pastPos
}
private fun popAncestor() {
private fun popParentChunk() {
if (__cursor at ancestorChunksStack.peek()) ancestorChunksStack.pop()
}
@ -291,24 +272,45 @@ internal open class MatchJournalImpl(
}
}
internal infix fun ChunkIterator.assertAt(pos: MatchJournal.Pos) {
if (!(this at pos))
throw IllegalStateException("Position wasn't found in journal: $pos")
}
internal 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()
}
/**
* Provides [MatchJournal] modification and look-ahead traverse with [Chunk] replay.
* Represents [MatchJournal] state: additions & removals happen at pointed-to position.
* [Cursor] points at position between [current] & [initial].
*/
private inner class Cursor(private val iter: MutableListIterator<ChunkImpl>) : AbstractChunkIterator(iter),
MutableChunkIterator {
private inner class Cursor(private val iter: MutableListIterator<ChunkImpl>) : AbstractChunkIterator(iter){
/**
* Replays [Chunk]s while iterating
*/
fun initial(): Chunk {
assert(atStart())
assert(__next is MatchChunk)
logAncestor(__next as MatchChunk)
pushParentChunk(__next as MatchChunk)
return nextImpl()
}
override fun addChunk(chunk: Chunk) {
fun addChunk(chunk: Chunk) {
iter.add(chunk as ChunkImpl)
__current = chunk
indexChunk(chunk)

View File

@ -17,14 +17,13 @@
package jetbrains.mps.logic.reactor.core.internal
import jetbrains.mps.logic.reactor.core.DispatchingFrontState
import jetbrains.mps.logic.reactor.core.Occurrence
import jetbrains.mps.logic.reactor.core.RuleIndex
import jetbrains.mps.logic.reactor.evaluation.MatchJournalView
import jetbrains.mps.logic.reactor.evaluation.SessionToken
import jetbrains.mps.logic.reactor.evaluation.StoreView
import jetbrains.mps.logic.reactor.program.Rule
data class SessionTokenImpl(
private val journalView: MatchJournal.View,
private val storeView: StoreView,
private val rules: Iterable<Rule>,
private val frontState: DispatchingFrontState,
val ruleIndex: RuleIndex,
@ -32,6 +31,6 @@ data class SessionTokenImpl(
val principalObservers: PrincipalObserverDispatcher = PrincipalObserverDispatcher.EMPTY
) : SessionToken
{
override fun getJournalView(): MatchJournalView = journalView
override fun getStoreView(): StoreView = storeView
override fun getRules(): Iterable<Rule> = rules
}

View File

@ -1,21 +0,0 @@
/*
* 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;
public interface MatchJournalView {
StoreView getStoreView();
}

View File

@ -21,8 +21,9 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
public interface SessionToken {
@NotNull()
MatchJournalView getJournalView();
@NotNull
StoreView getStoreView();
@NotNull()
Iterable<Rule> getRules();
}

View File

@ -1,41 +0,0 @@
/*
* 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.
*/
import jetbrains.mps.logic.reactor.program.Constraint
import jetbrains.mps.logic.reactor.program.ConstraintSymbol
import jetbrains.mps.logic.reactor.program.IncrementalSpec
import jetbrains.mps.logic.reactor.program.Rule
class MockIncrProgSpec(
val principalRuleTags: Set<Any>,
val principalCtrSyms: Set<ConstraintSymbol>,
val weakPrincipalRuleTags: Set<Any>,
private var strictness: IncrementalSpec.AssertLevel = IncrementalSpec.AssertLevel.Normal
) : IncrementalSpec {
constructor(principalRuleTags: Set<Any>, principalCtrSyms: Set<ConstraintSymbol>) :
this(principalRuleTags, principalCtrSyms, emptySet())
fun withContractChecks() = this.also { strictness = IncrementalSpec.AssertLevel.AssertContracts }
override fun isPrincipal(ctr: Constraint): Boolean = principalCtrSyms.contains(ctr.symbol())
override fun isPrincipal(rule: Rule): Boolean = principalRuleTags.contains(rule.uniqueTag())
override fun isWeakPrincipal(rule: Rule): Boolean = weakPrincipalRuleTags.contains(rule.uniqueTag())
override fun ability(): IncrementalSpec.Enabled = IncrementalSpec.Enabled.Yes
override fun incrLevel(): IncrementalSpec.IncrLevel = IncrementalSpec.IncrLevel.Full
override fun assertLevel(): IncrementalSpec.AssertLevel = strictness
}

File diff suppressed because it is too large Load Diff