From 64591e113b4bc3c3c671df326ba0814057de1f2a Mon Sep 17 00:00:00 2001 From: Fedor Isakov Date: Tue, 8 Mar 2016 11:40:31 +0100 Subject: [PATCH] Attempting optimizations in the matcher. Minor refactorings. --- .../mps/logic/reactor/core/Matcher.kt | 23 +++++++++------ .../reactor/core/MemEvaluationSession.kt | 6 ++-- .../mps/logic/reactor/core/PartialMatch.kt | 28 +++++++++---------- .../mps/logic/reactor/core/Profiler.kt | 4 +-- .../mps/logic/reactor/core/RuleIndex.kt | 2 +- 5 files changed, 35 insertions(+), 28 deletions(-) diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/Matcher.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/Matcher.kt index 27b63f2e..e4aed06a 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/Matcher.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/Matcher.kt @@ -14,6 +14,7 @@ import jetbrains.mps.logic.reactor.program.Rule import jetbrains.mps.unification.Substitution import jetbrains.mps.unification.Term import jetbrains.mps.unification.Unification +import java.util.* /** * @author Fedor Isakov @@ -45,18 +46,22 @@ class Matcher { fun lookupMatches(occ: ConstraintOccurrence): Sequence { return profiler.profile>("lookupMatches", { - val partialMatches = rules.forSymbol(occ.constraint().symbol())?.asSequence()?.flatMap { r -> - val matchedKept = r.headKept().filter { cst -> cst.matches(occ) }.asSequence() - val matchedDiscarded = r.headReplaced().filter { cst -> cst.matches(occ) }.asSequence() + val matchingRules = rules.forConstraint(occ.constraint().symbol()) + val partialMatches = matchingRules?.asSequence()?.flatMap { rule -> + + rule.headKept().asSequence().filter { cst -> + cst.symbol() == occ.constraint().symbol() && cst.matches(occ, profiler) }.map { cst -> + PartialMatch(rule, profiler).keep(cst, occ) } + + + rule.headReplaced().asSequence().filter { cst -> + cst.symbol() == occ.constraint().symbol() && cst.matches(occ, profiler) }.map { cst -> + PartialMatch(rule, profiler).discard(cst, occ) } - matchedKept.map { cst -> PartialMatch(r, profiler).keep(cst, occ) } + - matchedDiscarded.map { cst -> PartialMatch(r, profiler).discard(cst, occ) } } - partialMatches?.flatMap { pm -> - pm.completeMatch(auxLookup) }?.filter { pm -> - pm.matches() && !propHistory.isRecorded(pm) } ?: emptySequence() + val fullMatches = partialMatches?.flatMap { pm -> pm.completeMatch(auxLookup) } + fullMatches?.filter { pm -> !propHistory.isRecorded(pm) && pm.matches() } ?: emptySequence() }) } @@ -92,7 +97,7 @@ private class PropagationHistory { } -private class IdWrapper(val wrapped: T) { +class IdWrapper(val wrapped: T) { val idHash = System.identityHashCode(wrapped) diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/MemEvaluationSession.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/MemEvaluationSession.kt index 2d264350..4a284830 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/MemEvaluationSession.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/MemEvaluationSession.kt @@ -59,8 +59,10 @@ class MemEvaluationSession : EvaluationSession { } finally { ourBackend.ourSession.set(null) - profiler?.formattedData()?.entries?.forEach { e -> durations?.put(e.key, e.value) } - profiler?.clear() + profiler?.run { + formattedData().entries.forEach { e -> durations?.put(e.key, e.value) } + clear() + } } return session diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/PartialMatch.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/PartialMatch.kt index c4b3d45b..99790d8d 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/PartialMatch.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/PartialMatch.kt @@ -23,6 +23,8 @@ class PartialMatch(val rule: Rule, val profiler: Profiler? = null) : MatchRule { private set var discarded = emptyConsList>() private set + var matched = emptyConsList>() + private set var meta2logical = Maps.of, PersSet>>() private set private lateinit var logicalContext : LogicalContext @@ -34,7 +36,7 @@ class PartialMatch(val rule: Rule, val profiler: Profiler? = null) : MatchRule { { this.kept = if (keep != null) original.kept.prepend(keep) else original.kept this.discarded = if (discard != null) original.discarded.prepend(discard) else original.discarded - + this.matched = original.matched.prepend(IdWrapper((keep?.first ?: discard?.first)!!)) // exactly one is not null this.meta2logical = original.meta2logical val pair = keep ?: discard!! for ((ptr, log) in pair.first.arguments().zip(pair.second.arguments())) { @@ -50,24 +52,22 @@ class PartialMatch(val rule: Rule, val profiler: Profiler? = null) : MatchRule { return profiler.profile>("completeMatch", { - val matchesFromKept = - rule.headKept(). - filter { cst -> !kept.any { p -> cst === p.first } }. - asSequence(). - flatMap { cst -> findOccurrences(aux, cst).flatMap { occ -> keep(cst, occ).completeMatch(aux) } } + rule.headKept().asSequence().filter { cst -> !matched.contains(IdWrapper(cst)) }.flatMap { cst -> + lookupAuxOccurrences(aux, cst).flatMap { occ -> + keep(cst, occ).completeMatch(aux) + } + } + - val matchesFromDiscarded = - rule.headReplaced(). - filter { cst -> !discarded.any { p -> cst === p.first } }. - asSequence(). - flatMap { cst -> findOccurrences(aux, cst).flatMap { occ -> discard(cst, occ).completeMatch(aux) } } - - matchesFromKept + matchesFromDiscarded + rule.headReplaced().asSequence().filter { cst ->!matched.contains(IdWrapper(cst)) }.flatMap { cst -> + lookupAuxOccurrences(aux, cst).flatMap { occ -> + discard(cst, occ).completeMatch(aux) + } + } }) } - fun findOccurrences(aux: Matcher.AuxOccurrencesLookup, cst: Constraint): Sequence { + fun lookupAuxOccurrences(aux: Matcher.AuxOccurrencesLookup, cst: Constraint): Sequence { val logicals = HashSet>() val values = HashSet() diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/Profiler.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/Profiler.kt index 3887535b..5c3ab99a 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/Profiler.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/Profiler.kt @@ -89,7 +89,7 @@ class Token(val name: String, val id: Int) { inline fun Profiler?.profile(name: String, proc: () -> Unit): Unit { val tok = this?.start(name) try { - proc.invoke() + proc() } finally { this?.end(tok) @@ -99,7 +99,7 @@ inline fun Profiler?.profile(name: String, proc: () -> Unit): Unit { inline fun Profiler?.profile(name: String, function: () -> R): R { val tok = this?.start(name) try { - return function.invoke() + return function() } finally { this?.end(tok) diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/RuleIndex.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/RuleIndex.kt index 40c37797..c10a4df3 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/RuleIndex.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/RuleIndex.kt @@ -21,7 +21,7 @@ class RuleIndex : Iterable { buildIndex(rules) } - fun forSymbol(symbol: ConstraintSymbol): Iterable? = symbol2rules[symbol] + fun forConstraint(symbol: ConstraintSymbol): Iterable? = symbol2rules[symbol] override fun iterator(): Iterator = rules.iterator()