From 54b8d42e5283d5ae1d615b0255b802411fc1a8d9 Mon Sep 17 00:00:00 2001 From: Fedor Isakov Date: Tue, 13 Apr 2021 12:23:05 +0200 Subject: [PATCH] Drop obsolete RuleMatcher implementation --- .../mps/logic/reactor/core/RuleMatcher.kt | 1 - .../reactor/core/internal/RuleMatcherImpl.kt | 245 ------------------ 2 files changed, 246 deletions(-) delete mode 100644 reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/RuleMatcherImpl.kt diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/RuleMatcher.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/RuleMatcher.kt index 2bd08228..5b9575bc 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/RuleMatcher.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/RuleMatcher.kt @@ -19,7 +19,6 @@ package jetbrains.mps.logic.reactor.core import gnu.trove.list.TIntList import gnu.trove.list.array.TIntArrayList import jetbrains.mps.logic.reactor.core.internal.ReteRuleMatcherImpl -import jetbrains.mps.logic.reactor.core.internal.RuleMatcherImpl import jetbrains.mps.logic.reactor.program.Rule /** diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/RuleMatcherImpl.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/RuleMatcherImpl.kt deleted file mode 100644 index b780972a..00000000 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/RuleMatcherImpl.kt +++ /dev/null @@ -1,245 +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.core.internal - -import jetbrains.mps.logic.reactor.core.* -import jetbrains.mps.logic.reactor.program.Constraint -import jetbrains.mps.logic.reactor.program.Rule -import jetbrains.mps.logic.reactor.util.* -import java.util.* -import kotlin.collections.ArrayList - - -/** - * This implementation of [RuleMatcher] is based on a simple algorithm which enumerates all possible - * permutations of occurrences potentially matching the rule's head. - * - * Optimizations are in place to cut out permutations that don't fit for the reason that the arguments are mismatched - * and/or logical variables are not unifiable with the substitutions calculated previously. - * - * @author Fedor Isakov - */ -internal class RuleMatcherImpl(private var ruleLookup: RuleLookup?, - private val tag: Any) : RuleMatcher -{ - - val head = lookupRule().run { ArrayList(headKept() + headReplaced()) } - - val propagation = lookupRule().headReplaced().count() == 0 - - fun lookupRule(): Rule = ruleLookup?.lookupRuleByTag(tag) ?: throw IllegalStateException("can't lookup rule by tag: '${tag}'") - - override fun rule() = lookupRule() - - override fun setRuleLookup(ruleLookup: RuleLookup) { this.ruleLookup = ruleLookup } - - override fun resetRuleLookup() { this.ruleLookup = null } - - override fun newProbe(): RuleMatchingProbe = - RuleMatchFront(emptyList(), - emptyList(), - Sets.of(IntArray(head.size).toSignature()), - Sets.of(), - Sets.of()) - .also { probe = it } - - override fun probe(): RuleMatchingProbe = probe ?: newProbe() - - private var probe: RuleMatchingProbe? = null - - inner class RuleMatchFront(private val trunkNodes: List, - private val leafNodes: List, - private val leafSignatures: PersSet, - private val seenOccurrences: PersSet, - private val consumedSignatures: PersSet) : RuleMatchingProbe - { - override fun rule(): Rule = lookupRule() - - override fun hasOccurrences(): Boolean = trunkNodes.size > 0 || leafNodes.size > 0 - - override fun matches(): Collection = - leafNodes - .filter { node -> !consumedSignatures.contains(node.signature()) } - .map { node -> node.toRuleMatch() } - - override fun consume(ruleMatch: RuleMatchEx): RuleMatchingProbe = - RuleMatchFront(trunkNodes, - leafNodes, - leafSignatures, - seenOccurrences, - consumedSignatures.put(ruleMatch.signatureArray().toSignature())) - - override fun forget(ruleMatch: RuleMatchEx): RuleMatchingProbe = - RuleMatchFront(trunkNodes, - leafNodes, - leafSignatures, - seenOccurrences, - consumedSignatures.without(ruleMatch.signatureArray().toSignature())) - - override fun forget(occ: Occurrence): RuleMatchingProbe = with(this.contract(occ)) { - val newConsumed = Sets.copyOf(consumedSignatures.filter{ !it.contains(occ.identity) }) - val newSeen = seenOccurrences.without(occ.identity) - RuleMatchFront(trunkNodes, - leafNodes, - leafSignatures, - newSeen, - newConsumed) - } - - override fun expand(occ: Occurrence): RuleMatchingProbe = - expand(occ, bitSetOfOnes(head.size)) - - /** - * Expands the front by creating new leaf nodes that match the occurrence. - * Mask specifies possible slots for the occurrence. - */ - override fun expand(occ: Occurrence, mask: BitSet, profiler: Profiler?): RuleMatchFront { - val reactivated = seenOccurrences.contains(occ.identity) - val newSeen = if (reactivated) seenOccurrences else seenOccurrences.put(occ.identity) - val newTrunkNodes = ArrayList(trunkNodes.size).apply { addAll(trunkNodes) } - val newLeafNodes = arrayListOf() - var newSignatures = leafSignatures - val expanded = ArrayList() - val effMask = mask.clone() as BitSet - - for (node in (trunkNodes.asSequence() + BaseMatchNode())) { - effMask.clear() - effMask.or(mask) - effMask.and(node.vacant) -// val effMask = mask.copyApply { and(node.vacant) } -// profiler.profile("expand_node1_${occ.constraint.symbol()}") { - - if (!(effMask.isEmpty || node is MatchNode && node.hasOccurrence(occ))) { - - expanded.clear() - - val it = effMask.allSetBits() - while (it.hasNext()) { - val headIdx = it.next() - val subst = if (node is MatchNode) node.subst else emptySubst() - with(createOccurrenceMatcher(subst)) { - if (matches(head[headIdx], occ)) { - expanded.add(MatchNode(subst(), node, occ, headIdx)) - } - } - } - - for (ex in expanded) { - if (ex.leaf) { - // ensure reactivated have effect - val signature = ex.signature() - if (!reactivated && newSignatures.contains(signature)) break - // ...unless propagation (to avoid cycles) - if (reactivated && propagation && consumedSignatures.contains(signature)) break - newLeafNodes.add(ex) - newSignatures = newSignatures.put(signature) - } - newTrunkNodes.add(ex) - - } - } - } - - return RuleMatchFront(newTrunkNodes, newLeafNodes, newSignatures, newSeen, consumedSignatures) - } - - override fun contract(occ: Occurrence): RuleMatchFront { - val newTrunkNodes = arrayListOf() - var newSignatures = Sets.of() - for (node in trunkNodes) { - if (!node.hasOccurrence(occ)) { - newTrunkNodes.add(node) - if (node.leaf) { - newSignatures = newSignatures.without(node.signature()) - } - } - } - - return RuleMatchFront(newTrunkNodes, emptyList(), newSignatures, seenOccurrences, consumedSignatures) - } - - override fun forgetConsumed(occ: Occurrence): RuleMatchFront { - val newConsumed = Sets.copyOf(consumedSignatures.filter{ !it.contains(occ.identity) }) - return RuleMatchFront(trunkNodes, leafNodes, leafSignatures, seenOccurrences, newConsumed) // NB: not modifying genId - } - - override fun forgetExpanded(occ: Occurrence): RuleMatchFront { - val newSeen = seenOccurrences.without(occ.identity) - return RuleMatchFront(trunkNodes, leafNodes, leafSignatures, newSeen, consumedSignatures) // NB: not modifying genId - } - - } - - open inner class BaseMatchNode(val vacant: BitSet = bitSetOfOnes(head.size)) { - - /** - * Folds the path to the root. - */ - inline protected fun fold(init: T, action: (T, MatchNode) -> T): T { - var rn = this - var curr = init - while (rn is MatchNode) { - curr = action(curr, rn) - rn = rn.parent - } - return curr - } - - } - - inner class MatchNode(val subst: Subst, - val parent: BaseMatchNode, - val occurrence: Occurrence, - val headIndex: Int) : BaseMatchNode(parent.vacant.clearBit(headIndex)) - { - val leaf = vacant.cardinality() == 0 - - val trail: PersSet = - if (parent is MatchNode) parent.trail.put(occurrence.identity) else Sets.of(occurrence.identity) - - fun constraint(): Constraint = head[headIndex] - - // a signature is a (partial) set of constraint occurrences that belong to this node - fun signature(): Signature = - fold(IntArray(head.size).toSignature()) { s, n -> - s.apply { set(n.headIndex, n.occurrence.identity) } } - - fun hasOccurrence(occ: Occurrence): Boolean = trail.contains(occ.identity) -// fold(false) { flag, n -> flag || n.occurrence === occ } // referential equality ! - - fun matches() : Subst? = - fold(createOccurrenceMatcher(emptySubst())) { matcher, n -> - matcher?.let { - if (it.matches(n.constraint(), n.occurrence)) it else null - } - }?.subst() - - fun toRuleMatch(): RuleMatchImpl { - val matched: Array = - fold(arrayOfNulls(head.size)) { arr, rn -> - arr[rn.headIndex] = rn.occurrence; arr - } as Array - - return RuleMatchImpl(lookupRule(), - subst, - ArrayList(matched.take(lookupRule().headKept().count())), - ArrayList(matched.takeLast(lookupRule().headReplaced().count()))) - } - } - - -}