Refactor code for better readability
This commit is contained in:
parent
cde05c1d7d
commit
3d57a5abc3
|
|
@ -28,13 +28,20 @@ typealias Evidence = Int
|
||||||
/**
|
/**
|
||||||
* [Justifications] is a set of [Evidence]s.
|
* [Justifications] is a set of [Evidence]s.
|
||||||
*/
|
*/
|
||||||
typealias Justifications = TIntSet
|
data class Justifications(private val evidenceSet: TIntSet) {
|
||||||
|
companion object {
|
||||||
fun emptyJustifications(): Justifications = TIntHashSet(1)
|
fun empty() = Justifications (TIntHashSet(1))
|
||||||
fun justsOf(vararg elements: Evidence): Justifications = TIntHashSet(elements)
|
fun of(vararg elements: Evidence) = Justifications(TIntHashSet(elements))
|
||||||
fun justsFromCollection(collection: Collection<Evidence>): Justifications = TIntHashSet(collection)
|
fun of(collection: Collection<Evidence>) = Justifications(TIntHashSet(collection))
|
||||||
fun justsCopy(other: Justifications): Justifications = TIntHashSet(other)
|
fun copy(other: Justifications) = Justifications(TIntHashSet(other.evidenceSet))
|
||||||
|
}
|
||||||
|
fun addAll(that: Justifications) { evidenceSet.addAll(that.evidenceSet) }
|
||||||
|
fun add(evidence: Evidence) { evidenceSet.add(evidence) }
|
||||||
|
fun contains(evidence: Evidence) = evidenceSet.contains(evidence)
|
||||||
|
fun forEach(action: (Evidence) -> Boolean) {
|
||||||
|
evidenceSet.forEach(action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A logical entity whose existence is supported by some
|
* A logical entity whose existence is supported by some
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,7 @@ internal class ConstraintsProcessing(
|
||||||
|
|
||||||
// By default share justifications (as a small optimization)
|
// By default share justifications (as a small optimization)
|
||||||
val evidence = nextEvidence()
|
val evidence = nextEvidence()
|
||||||
val justifications = justsCopy(savedJustifications).apply { add(evidence) }
|
val justifications = Justifications.copy(savedJustifications).apply { add(evidence) }
|
||||||
|
|
||||||
return Occurrence(
|
return Occurrence(
|
||||||
this, logicalContext, arguments, evidence,
|
this, logicalContext, arguments, evidence,
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ interface MatchJournal : EvidenceSource {
|
||||||
val occ: Occurrence
|
val occ: Occurrence
|
||||||
}
|
}
|
||||||
|
|
||||||
open class Pos(val chunk: Chunk, val entriesCount: Int) {
|
class Pos(val chunk: Chunk, val entriesCount: Int) {
|
||||||
|
|
||||||
override fun equals(other: Any?) =
|
override fun equals(other: Any?) =
|
||||||
other is Pos
|
other is Pos
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ internal open class MatchJournalImpl(
|
||||||
val trace: EvaluationTrace = EvaluationTrace.NULL
|
val trace: EvaluationTrace = EvaluationTrace.NULL
|
||||||
) : MatchJournal {
|
) : MatchJournal {
|
||||||
|
|
||||||
private abstract class ChunkImpl : Chunk {
|
private sealed class ChunkImpl : Chunk {
|
||||||
var entries: MutableList<Chunk.Entry> = mutableListOf()
|
var entries: MutableList<Chunk.Entry> = mutableListOf()
|
||||||
override fun entries(): List<Chunk.Entry> = entries
|
override fun entries(): List<Chunk.Entry> = entries
|
||||||
override fun addEntry(e: Chunk.Entry) = entries.add(e)
|
override fun addEntry(e: Chunk.Entry) = entries.add(e)
|
||||||
|
|
@ -54,7 +54,7 @@ internal open class MatchJournalImpl(
|
||||||
|
|
||||||
private object CornerChunk : ChunkImpl() {
|
private object CornerChunk : ChunkImpl() {
|
||||||
override val evidence: Evidence = -1
|
override val evidence: Evidence = -1
|
||||||
override fun justifications(): Justifications = emptyJustifications()
|
override fun justifications() = Justifications.empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -209,70 +209,12 @@ internal open class MatchJournalImpl(
|
||||||
throw IllegalStateException()
|
throw IllegalStateException()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides [MatchJournal] look-ahead traverse.
|
|
||||||
*/
|
|
||||||
abstract private class AbstractChunkIterator(private val iter: ListIterator<ChunkImpl>) : ChunkIterator
|
|
||||||
{
|
|
||||||
protected var __next: ChunkImpl
|
|
||||||
protected var __current: ChunkImpl
|
|
||||||
|
|
||||||
init {
|
|
||||||
__current = iter.next()
|
|
||||||
__next = iter.next()
|
|
||||||
iter.previous()
|
|
||||||
|
|
||||||
assert(__current is CornerChunk)
|
|
||||||
}
|
|
||||||
|
|
||||||
final override val current: Chunk get() = __current
|
|
||||||
|
|
||||||
final override fun atStart(): Boolean = __current is CornerChunk
|
|
||||||
final override fun atEnd(): Boolean = __next is CornerChunk
|
|
||||||
|
|
||||||
protected fun updateNext() {
|
|
||||||
assert(iter.hasNext()) { "journal iterator must always have next chunk (maybe the final)" }
|
|
||||||
__next = iter.next()
|
|
||||||
iter.previous() // iterator always points between stored chunks
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun nextImpl(): Chunk {
|
|
||||||
__current = iter.next()
|
|
||||||
assert(__current === __next)
|
|
||||||
updateNext()
|
|
||||||
return __current
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal infix fun ChunkIterator.assertAt(pos: 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.
|
* Provides [MatchJournal] modification and look-ahead traverse with [Chunk] replay.
|
||||||
* Represents [MatchJournal] state: additions & removals happen at pointed-to position.
|
* Represents [MatchJournal] state: additions & removals happen at pointed-to position.
|
||||||
* [Cursor] points at position between [current] & [initial].
|
* [Cursor] points at position between [current] & [initial].
|
||||||
*/
|
*/
|
||||||
private inner class Cursor(private val iter: MutableListIterator<ChunkImpl>) : AbstractChunkIterator(iter){
|
private inner class Cursor(private val iter: MutableListIterator<ChunkImpl>) : ChunkIterator {
|
||||||
/**
|
/**
|
||||||
* Replays [Chunk]s while iterating
|
* Replays [Chunk]s while iterating
|
||||||
*/
|
*/
|
||||||
|
|
@ -312,6 +254,40 @@ internal open class MatchJournalImpl(
|
||||||
this assertAt pastPos
|
this assertAt pastPos
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var __next: ChunkImpl
|
||||||
|
private var __current: ChunkImpl
|
||||||
|
|
||||||
|
init {
|
||||||
|
__current = iter.next()
|
||||||
|
__next = iter.next()
|
||||||
|
iter.previous()
|
||||||
|
|
||||||
|
assert(__current is CornerChunk)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val current: Chunk get() = __current
|
||||||
|
|
||||||
|
override fun atStart(): Boolean = __current is CornerChunk
|
||||||
|
override fun atEnd(): Boolean = __next is CornerChunk
|
||||||
|
|
||||||
|
private fun updateNext() {
|
||||||
|
assert(iter.hasNext()) { "journal iterator must always have next chunk (maybe the final)" }
|
||||||
|
__next = iter.next()
|
||||||
|
iter.previous() // iterator always points between stored chunks
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun nextImpl(): Chunk {
|
||||||
|
__current = iter.next()
|
||||||
|
assert(__current === __next)
|
||||||
|
updateNext()
|
||||||
|
return __current
|
||||||
|
}
|
||||||
|
|
||||||
|
infix fun assertAt(pos: Pos) {
|
||||||
|
if (!(this at pos))
|
||||||
|
throw IllegalStateException("Position wasn't found in journal: $pos")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -348,13 +324,13 @@ internal open class MatchJournalImpl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// returns new collection of justifications
|
// returns new collection of justifications
|
||||||
internal fun RuleMatch.collectJustifications(vararg withEvidence: Evidence): Justifications =
|
internal fun RuleMatch.collectJustifications(vararg withEvidence: Evidence): Justifications =
|
||||||
justsOf(*withEvidence).also { allJss ->
|
Justifications.of(*withEvidence).also { justifications ->
|
||||||
this.allHeads().forEach { allJss.addAll(it.justifications()) }
|
this.allHeads().forEach { justifications.addAll(it.justifications()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun <E> MutableList<E>.push(element: E) = this.add(element)
|
internal fun <E> MutableList<E>.push(element: E) = this.add(element)
|
||||||
internal fun <E> MutableList<E>.pop() = this.removeAt(this.size - 1)
|
internal fun <E> MutableList<E>.pop() = this.removeAt(this.size - 1)
|
||||||
internal fun <E> MutableList<E>.peek() = this.last()
|
internal fun <E> MutableList<E>.peek() = this.last()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014-2024 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.Occurrence
|
||||||
|
import jetbrains.mps.logic.reactor.evaluation.ConstraintOccurrence
|
||||||
|
import jetbrains.mps.logic.reactor.evaluation.StoreView
|
||||||
|
import jetbrains.mps.logic.reactor.program.ConstraintSymbol
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
import jetbrains.mps.logic.reactor.core.*
|
import jetbrains.mps.logic.reactor.core.*
|
||||||
import jetbrains.mps.logic.reactor.core.internal.*
|
import jetbrains.mps.logic.reactor.core.internal.*
|
||||||
import jetbrains.mps.logic.reactor.evaluation.PredicateInvocation
|
|
||||||
import jetbrains.mps.logic.reactor.evaluation.Solver
|
|
||||||
import jetbrains.mps.logic.reactor.evaluation.StoreView
|
|
||||||
import jetbrains.mps.logic.reactor.logical.Logical
|
import jetbrains.mps.logic.reactor.logical.Logical
|
||||||
import jetbrains.mps.logic.reactor.logical.LogicalContext
|
import jetbrains.mps.logic.reactor.logical.LogicalContext
|
||||||
import jetbrains.mps.logic.reactor.logical.MetaLogical
|
import jetbrains.mps.logic.reactor.logical.MetaLogical
|
||||||
|
|
@ -102,7 +99,7 @@ fun equals(left: Any, right: Any): ConjBuilder.() -> Unit = {
|
||||||
|
|
||||||
fun occurrence(id: String, vararg args: Any): Occurrence =
|
fun occurrence(id: String, vararg args: Any): Occurrence =
|
||||||
MockConstraint(ConstraintSymbol.symbol(id, args.size))
|
MockConstraint(ConstraintSymbol.symbol(id, args.size))
|
||||||
.occurrence(listOf(* args), 0, justsOf(0), noLogicalContext)
|
.occurrence(listOf(* args), 0, Justifications.of(0), noLogicalContext)
|
||||||
|
|
||||||
fun justifiedOccurrence(id: String, evidence: Evidence, justifications: Justifications, principal: Boolean, vararg args: Any): Occurrence =
|
fun justifiedOccurrence(id: String, evidence: Evidence, justifications: Justifications, principal: Boolean, vararg args: Any): Occurrence =
|
||||||
MockConstraint(ConstraintSymbol.symbol(id, args.size), principal)
|
MockConstraint(ConstraintSymbol.symbol(id, args.size), principal)
|
||||||
|
|
@ -115,7 +112,7 @@ fun justifiedOccurrence(id: String, hist: MatchJournal, vararg args: Any): Occur
|
||||||
justifiedOccurrence(id, hist.evidence(), hist.justifications(), false, * args)
|
justifiedOccurrence(id, hist.evidence(), hist.justifications(), false, * args)
|
||||||
|
|
||||||
fun principalOccurrenceInit(id: String, vararg args: Any): Occurrence =
|
fun principalOccurrenceInit(id: String, vararg args: Any): Occurrence =
|
||||||
justifiedOccurrence(id, 0, justsFromCollection(setOf(0)), true, * args)
|
justifiedOccurrence(id, 0, Justifications.of(setOf(0)), true, * args)
|
||||||
|
|
||||||
fun sym0(id: String): ConstraintSymbol =
|
fun sym0(id: String): ConstraintSymbol =
|
||||||
ConstraintSymbol(id, 0)
|
ConstraintSymbol(id, 0)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
import jetbrains.mps.logic.reactor.core.*
|
import jetbrains.mps.logic.reactor.core.*
|
||||||
import jetbrains.mps.logic.reactor.core.internal.*
|
import jetbrains.mps.logic.reactor.core.internal.*
|
||||||
import jetbrains.mps.logic.reactor.program.Constraint
|
|
||||||
import jetbrains.mps.logic.reactor.program.Rule
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.Assert.*
|
import org.junit.Assert.*
|
||||||
|
|
||||||
|
|
@ -75,7 +73,7 @@ class TestStoreAwareJournal {
|
||||||
{
|
{
|
||||||
with(JournalDispatcherHelper(Dispatcher(RuleIndex(rules)))) {
|
with(JournalDispatcherHelper(Dispatcher(RuleIndex(rules)))) {
|
||||||
|
|
||||||
hist.justifications() shouldBe justsOf(0) // initial chunk
|
hist.justifications() shouldBe Justifications.of(0) // initial chunk
|
||||||
|
|
||||||
logExpand(principalOccurrenceInit("foo"))
|
logExpand(principalOccurrenceInit("foo"))
|
||||||
val fooMatches = d.matches()
|
val fooMatches = d.matches()
|
||||||
|
|
@ -84,7 +82,7 @@ class TestStoreAwareJournal {
|
||||||
// log first 'foo' match
|
// log first 'foo' match
|
||||||
|
|
||||||
hist.logMatch(fooMatches.first())
|
hist.logMatch(fooMatches.first())
|
||||||
hist.justifications() shouldBe justsOf(0,1)
|
hist.justifications() shouldBe Justifications.of(0,1)
|
||||||
|
|
||||||
logExpandJustified("bar")
|
logExpandJustified("bar")
|
||||||
d.matches().count() shouldBe 0
|
d.matches().count() shouldBe 0
|
||||||
|
|
@ -92,13 +90,13 @@ class TestStoreAwareJournal {
|
||||||
// log second 'foo' match
|
// log second 'foo' match
|
||||||
|
|
||||||
hist.logMatch(fooMatches.elementAt(1))
|
hist.logMatch(fooMatches.elementAt(1))
|
||||||
hist.justifications() shouldBe justsOf(0,2)
|
hist.justifications() shouldBe Justifications.of(0,2)
|
||||||
|
|
||||||
logExpandJustified("qux")
|
logExpandJustified("qux")
|
||||||
d.matches().count() shouldBe 1
|
d.matches().count() shouldBe 1
|
||||||
|
|
||||||
logFirstMatch()
|
logFirstMatch()
|
||||||
hist.justifications() shouldBe justsOf(0,1,2,3)
|
hist.justifications() shouldBe Justifications.of(0,1,2,3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue