Skip to content

Commit

Permalink
split FunctorNode into three files
Browse files Browse the repository at this point in the history
  • Loading branch information
gciatto committed May 25, 2020
1 parent 3c73776 commit 0aaf1ce
Show file tree
Hide file tree
Showing 10 changed files with 238 additions and 220 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ package it.unibo.tuprolog.collections.rete.custom

/**Marker interface to expand the capabilites of a [ReteNode] to behave as an [IndexingLeaf
*/
internal interface IndexingNode : ReteNode, IndexingLeaf {}
internal interface IndexingNode : ReteNode, IndexingLeaf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import it.unibo.tuprolog.collections.rete.custom.Utils.nestedFirstArgument
import it.unibo.tuprolog.collections.rete.custom.clause.IndexedClause
import it.unibo.tuprolog.collections.rete.custom.clause.SituatedIndexedClause
import it.unibo.tuprolog.collections.rete.custom.nodes.FunctorIndexing
import it.unibo.tuprolog.collections.rete.custom.nodes.FunctorNode
import it.unibo.tuprolog.collections.rete.custom.nodes.FunctorIndexingNode
import it.unibo.tuprolog.core.Clause
import it.unibo.tuprolog.core.Var
import it.unibo.tuprolog.utils.Cached
Expand Down Expand Up @@ -44,7 +44,7 @@ internal class CompoundIndex(
clause.nestedFunctor().let {
if (ordered) {
functors.getOrPut(it) {
FunctorNode.FunctorIndexingNode(ordered, nestingLevel)
FunctorIndexingNode(ordered, nestingLevel)
}.assertA(clause + this)
} else {
assertZ(clause)
Expand All @@ -54,7 +54,7 @@ internal class CompoundIndex(
override fun assertZ(clause: IndexedClause) =
clause.nestedFunctor().let {
functors.getOrPut(it) {
FunctorNode.FunctorIndexingNode(ordered, nestingLevel)
FunctorIndexingNode(ordered, nestingLevel)
}.assertZ(clause + this)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package it.unibo.tuprolog.collections.rete.custom.nodes

import it.unibo.tuprolog.collections.rete.custom.ReteNode

internal abstract class ArityNode : ReteNode {

}
internal abstract class ArityNode : ReteNode


Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import it.unibo.tuprolog.collections.rete.custom.Utils
import it.unibo.tuprolog.collections.rete.custom.clause.SituatedIndexedClause
import it.unibo.tuprolog.core.Clause

internal class FamilyArityIndexingNode(private val ordered: Boolean, nestingLevel: Int) :
FamilyArityReteNode(ordered, nestingLevel),
ArityIndexing {
internal class FamilyArityIndexingNode(
private val ordered: Boolean,
nestingLevel: Int
) : FamilyArityReteNode(ordered, nestingLevel), ArityIndexing {

override fun getFirstIndexed(clause: Clause): SituatedIndexedClause? =
if (ordered) orderedLookahead(clause)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ import it.unibo.tuprolog.core.*
import it.unibo.tuprolog.utils.Cached
import it.unibo.tuprolog.utils.dequeOf

internal open class FamilyArityReteNode(private val ordered: Boolean, private val nestingLevel: Int) :
ArityNode(),
ArityRete {
internal open class FamilyArityReteNode(
private val ordered: Boolean,
private val nestingLevel: Int
) : ArityNode(), ArityRete {

protected val numericIndex: IndexingLeaf =
NumericIndex(ordered, nestingLevel)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package it.unibo.tuprolog.collections.rete.custom.nodes

import it.unibo.tuprolog.collections.rete.custom.Utils
import it.unibo.tuprolog.collections.rete.custom.Utils.arityOfNestedFirstArgument
import it.unibo.tuprolog.collections.rete.custom.Utils.nestedFirstArgument
import it.unibo.tuprolog.collections.rete.custom.clause.IndexedClause
import it.unibo.tuprolog.collections.rete.custom.clause.SituatedIndexedClause
import it.unibo.tuprolog.core.Clause
import it.unibo.tuprolog.core.Rule
import it.unibo.tuprolog.core.Var
import it.unibo.tuprolog.unify.Unificator.Companion.matches
import it.unibo.tuprolog.utils.Cached
import it.unibo.tuprolog.utils.dequeOf

internal class FunctorIndexingNode(
private val ordered: Boolean,
private val nestingLevel: Int
) : FunctorNode(), FunctorIndexing {

private val arities: MutableMap<Int, ArityIndexing> = mutableMapOf()
private val theoryCache: Cached<MutableList<SituatedIndexedClause>> = Cached.of(this::regenerateCache)

override fun get(clause: Clause): Sequence<Clause> =
arities[clause.nestedArity()]?.get(clause) ?: emptySequence()

override fun assertA(clause: IndexedClause) {
arities.getOrPut(clause.nestedArity()) {
FamilyArityIndexingNode(
ordered,
nestingLevel
)
}.assertA(clause + this)
}

override fun assertZ(clause: IndexedClause) {
arities.getOrPut(clause.nestedArity()) {
FamilyArityIndexingNode(
ordered,
nestingLevel
)
}.assertZ(clause + this)
}

override fun retractAll(clause: Clause): Sequence<Clause> =
arities[clause.nestedArity()]?.retractAll(clause)
?: emptySequence()

override fun getCache(): Sequence<SituatedIndexedClause> =
theoryCache.value.asSequence()

override fun getFirstIndexed(clause: Clause): SituatedIndexedClause? =
if (clause.isGlobal()) {
Utils.merge(
arities.values.map {
it.extractGlobalIndexedSequence(clause)
}
).firstOrNull { it.innerClause matches clause }
} else arities[clause.nestedArity()]?.getFirstIndexed(clause)

override fun getIndexed(clause: Clause): Sequence<SituatedIndexedClause> {
return if (clause.isGlobal()) {
Utils.merge(
arities.values.map {
it.getIndexed(clause)
}
)
} else {
arities[clause.nestedArity()]?.getIndexed(clause) ?: emptySequence()
}
}

override fun retractAllIndexed(clause: Clause): Sequence<SituatedIndexedClause> =
if (clause.isGlobal()) {
val partialResult = Utils.merge(
arities.values.map {
it.extractGlobalIndexedSequence(clause)
})
.filter { it.innerClause matches clause }
.toList()
if (partialResult.isNotEmpty()) {
invalidateCache()
partialResult.forEach { it.removeFromIndex() }
}
partialResult.asSequence()
} else {
arities[clause.nestedArity()]?.retractAllIndexed(clause)
?: emptySequence()
}

override fun extractGlobalIndexedSequence(clause: Clause): Sequence<SituatedIndexedClause> {
return if (ordered) {
Utils.merge(
arities.values.map {
it.extractGlobalIndexedSequence(clause)
}
)
} else {
Utils.flattenIndexed(
arities.values.map {
it.extractGlobalIndexedSequence(clause)
}
)
}
}

private fun Clause.isGlobal(): Boolean =
this is Rule && this.head.nestedFirstArgument(nestingLevel) is Var

private fun Clause.nestedArity(): Int =
(this as? Rule)?.head?.arityOfNestedFirstArgument(nestingLevel)
?: error("The nestedArity method cannot be invoked on non-rule clauses")

private fun IndexedClause.nestedArity(): Int =
this.innerClause.head!!.arityOfNestedFirstArgument(nestingLevel)

override fun invalidateCache() {
theoryCache.invalidate()
// arities.values.forEach { it.invalidateCache() }
}

private fun regenerateCache(): MutableList<SituatedIndexedClause> =
dequeOf(
if (ordered) {
Utils.merge(
arities.values.map {
it.getCache()
}
)
} else {
Utils.flattenIndexed(
arities.values.map { outer ->
outer.getCache()
}
)
}
)

}
Loading

0 comments on commit 0aaf1ce

Please sign in to comment.