You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nlpcraft.apache.org by ar...@apache.org on 2020/05/19 02:29:55 UTC

[incubator-nlpcraft] branch NLPCRAFT-30 updated: Refactoring & CR.

This is an automated email from the ASF dual-hosted git repository.

aradzinski pushed a commit to branch NLPCRAFT-30
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git


The following commit(s) were added to refs/heads/NLPCRAFT-30 by this push:
     new 7019644  Refactoring & CR.
7019644 is described below

commit 7019644b9be9b18cd9c4b6ad3c15c67bbb36b028
Author: Aaron Radzinzski <ar...@datalingvo.com>
AuthorDate: Mon May 18 19:29:47 2020 -0700

    Refactoring & CR.
---
 .../org/apache/nlpcraft/probe/NCProbeBoot.scala    |   3 -
 .../probe/mgrs/nlp/NCProbeEnrichmentManager.scala  |   7 +-
 .../NCEnricherUtils.scala}                         | 232 ++++++++++-----------
 .../mgrs/nlp/enrichers/limit/NCLimitEnricher.scala |   6 +-
 .../mgrs/nlp/enrichers/model/NCModelEnricher.scala |   7 +-
 .../enrichers/relation/NCRelationEnricher.scala    |   6 +-
 .../mgrs/nlp/enrichers/sort/NCSortEnricher.scala   |   6 +-
 7 files changed, 127 insertions(+), 140 deletions(-)

diff --git a/src/main/scala/org/apache/nlpcraft/probe/NCProbeBoot.scala b/src/main/scala/org/apache/nlpcraft/probe/NCProbeBoot.scala
index 9bfb88e..18a7c8c 100644
--- a/src/main/scala/org/apache/nlpcraft/probe/NCProbeBoot.scala
+++ b/src/main/scala/org/apache/nlpcraft/probe/NCProbeBoot.scala
@@ -45,7 +45,6 @@ import org.apache.nlpcraft.probe.mgrs.nlp.enrichers.relation.NCRelationEnricher
 import org.apache.nlpcraft.probe.mgrs.nlp.enrichers.sort.NCSortEnricher
 import org.apache.nlpcraft.probe.mgrs.nlp.enrichers.stopword.NCStopWordEnricher
 import org.apache.nlpcraft.probe.mgrs.nlp.enrichers.suspicious.NCSuspiciousNounsEnricher
-import org.apache.nlpcraft.probe.mgrs.nlp.impl.NCEnricherProcessor
 import org.apache.nlpcraft.probe.mgrs.nlp.validate.NCValidateManager
 
 import scala.collection.JavaConverters._
@@ -425,7 +424,6 @@ private [probe] object NCProbeBoot extends LazyLogging with NCOpenCensusTrace {
             NCModelManager.start(span)
             NCCommandManager.start(span)
             NCDictionaryManager.start(span)
-            NCEnricherProcessor.start(span)
             NCStopWordEnricher.start(span)
             NCModelEnricher.start(span)
             NCLimitEnricher.start(span)
@@ -451,7 +449,6 @@ private [probe] object NCProbeBoot extends LazyLogging with NCOpenCensusTrace {
             NCConnectionManager.stop(span)
             NCProbeEnrichmentManager.stop(span)
             NCConversationManager.stop(span)
-            NCEnricherProcessor.stop(span)
             NCDictionaryEnricher.stop(span)
             NCValidateManager.stop(span)
             NCSuspiciousNounsEnricher.stop(span)
diff --git a/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnrichmentManager.scala b/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnrichmentManager.scala
index a25316b..b4acee9 100644
--- a/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnrichmentManager.scala
+++ b/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnrichmentManager.scala
@@ -39,6 +39,7 @@ import org.apache.nlpcraft.probe.mgrs.conn.NCConnectionManager
 import org.apache.nlpcraft.probe.mgrs.conversation.NCConversationManager
 import org.apache.nlpcraft.probe.mgrs.dialogflow.NCDialogFlowManager
 import org.apache.nlpcraft.probe.mgrs.model.NCModelManager
+import org.apache.nlpcraft.probe.mgrs.nlp.enrichers.NCEnricherUtils
 import org.apache.nlpcraft.probe.mgrs.nlp.enrichers.dictionary.NCDictionaryEnricher
 import org.apache.nlpcraft.probe.mgrs.nlp.enrichers.limit.NCLimitEnricher
 import org.apache.nlpcraft.probe.mgrs.nlp.enrichers.model.NCModelEnricher
@@ -396,7 +397,7 @@ object NCProbeEnrichmentManager extends NCService with NCOpenCensusModelStats {
                             val diff = notes2.filter(n ⇒ !notes1.contains(n))
 
                             val diffRedundant = diff.flatMap(n2 ⇒
-                                notes1.find(n1 ⇒ NCEnricherProcessor.equalOrSimilar(n1, n2, nlpSen)) match {
+                                notes1.find(n1 ⇒ NCEnricherUtils.equalOrSimilar(n1, n2, nlpSen)) match {
                                     case Some(similar) ⇒ Some(n2 → similar)
                                     case None ⇒ None
                                 }
@@ -437,7 +438,7 @@ object NCProbeEnrichmentManager extends NCService with NCOpenCensusModelStats {
                         logger.info(s"Enrichment finished [step=$step]")
             }
 
-            NCEnricherProcessor.collapse(mdlDec, nlpSen.clone(), span).
+            NCEnricherUtils.collapse(mdlDec, nlpSen.clone(), span).
                 // Sorted to support deterministic logs.
                 sortBy(p ⇒
                 p.map(p ⇒ {
@@ -478,7 +479,7 @@ object NCProbeEnrichmentManager extends NCService with NCOpenCensusModelStats {
         val varsNlp = sensSeq.map(_.toSeq)
         val req = NCRequestImpl(meta, srvReqId)
 
-        var senVars = NCEnricherProcessor.convert(mdlDec, srvReqId, varsNlp)
+        var senVars = NCEnricherUtils.convert(mdlDec, srvReqId, varsNlp)
 
         // Sentence variants can be filtered by model.
         val fltSenVars: Seq[(Seq[NCToken], Int)] =
diff --git a/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/impl/NCEnricherProcessor.scala b/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/NCEnricherUtils.scala
similarity index 79%
rename from src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/impl/NCEnricherProcessor.scala
rename to src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/NCEnricherUtils.scala
index 2a9f12a..2103e63 100644
--- a/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/impl/NCEnricherProcessor.scala
+++ b/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/NCEnricherUtils.scala
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.nlpcraft.probe.mgrs.nlp.impl
+package org.apache.nlpcraft.probe.mgrs.nlp.enrichers
 
 import java.io.Serializable
 import java.util
@@ -25,26 +25,18 @@ import com.typesafe.scalalogging.LazyLogging
 import io.opencensus.trace.Span
 import org.apache.nlpcraft.common.nlp.pos.NCPennTreebank
 import org.apache.nlpcraft.common.nlp.{NCNlpSentence, NCNlpSentenceNote, NCNlpSentenceToken}
-import org.apache.nlpcraft.common.{NCE, NCService, TOK_META_ALIASES_KEY}
+import org.apache.nlpcraft.common.{NCE, TOK_META_ALIASES_KEY}
 import org.apache.nlpcraft.model.NCToken
 import org.apache.nlpcraft.model.impl.NCTokenImpl
 import org.apache.nlpcraft.probe.mgrs.NCModelDecorator
-import scala.collection.JavaConverters._
 
+import scala.collection.JavaConverters._
 import scala.collection.{Map, Seq, Set, mutable}
 
 /**
   *
   */
-object NCEnricherProcessor extends NCService with LazyLogging {
-    override def start(parent: Span = null): NCService = startScopedSpan("start", parent) { _ ⇒
-        super.start()
-    }
-
-    override def stop(parent: Span = null): Unit = startScopedSpan("stop", parent) { _ ⇒
-        super.stop()
-    }
-
+object NCEnricherUtils extends LazyLogging {
     /**
       *
       * @param note
@@ -252,7 +244,7 @@ object NCEnricherProcessor extends NCService with LazyLogging {
 
                     if (fixed.forall(_.size == 1)) {
                         // Fix double dimension array to one dimension,
-                        // so it should be called always inspite of fixIndexesReferences method.
+                        // so it should be called always in spite of 'fixIndexesReferences' method.
                         ns.fixNote(n, idxsField → fixed.map(_.head).asJava.asInstanceOf[java.io.Serializable])
 
                         def x(seq: Seq[Seq[Int]]): String = s"[${seq.map(p ⇒ s"[${p.mkString(",")}]").mkString(", ")}]"
@@ -514,138 +506,134 @@ object NCEnricherProcessor extends NCService with LazyLogging {
       * @return
       */
     @throws[NCE]
-    def collapse(mdl: NCModelDecorator, ns: NCNlpSentence, parent: Span = null): Seq[NCNlpSentence] =
-        startScopedSpan("collapse", parent,
-            "srvReqId" → ns.srvReqId,
-            "txt" → ns.text,
-            "modelId" → mdl.model.getId) { _ ⇒
-            // Always deletes `similar` notes.
-            // Some words with same note type can be detected various ways.
-            // We keep only one variant -  with `best` direct and sparsity parameters,
-            // other variants for these words are redundant.
-            val redundant: Seq[NCNlpSentenceNote] =
-                ns.flatten.filter(!_.isNlp).distinct.
-                    groupBy(p ⇒ getKey(p)).
-                    map(p ⇒ p._2.sortBy(p ⇒
-                        (
-                            // System notes don't have such flags.
-                            if (p.isUser) {
-                                if (p.isDirect) 0 else 1
-                            }
-                            else
-                                0,
-                            if (p.isUser) p.sparsity else 0
-                        )
-                    )).
-                    flatMap(_.drop(1)).
-                    toSeq
+    def collapse(mdl: NCModelDecorator, ns: NCNlpSentence, parent: Span = null): Seq[NCNlpSentence] = {
+        // Always deletes `similar` notes.
+        // Some words with same note type can be detected various ways.
+        // We keep only one variant -  with `best` direct and sparsity parameters,
+        // other variants for these words are redundant.
+        val redundant: Seq[NCNlpSentenceNote] =
+            ns.flatten.filter(!_.isNlp).distinct.
+                groupBy(p ⇒ getKey(p)).
+                map(p ⇒ p._2.sortBy(p ⇒
+                    (
+                        // System notes don't have such flags.
+                        if (p.isUser) {
+                            if (p.isDirect) 0 else 1
+                        }
+                        else
+                            0,
+                        if (p.isUser) p.sparsity else 0
+                    )
+                )).
+                flatMap(_.drop(1)).
+                toSeq
 
-            redundant.foreach(ns.removeNote)
+        redundant.foreach(ns.removeNote)
 
-            def getNotNlpNotes(toks: Seq[NCNlpSentenceToken]): Seq[NCNlpSentenceNote] =
-                toks.flatten.filter(!_.isNlp).distinct
+        def getNotNlpNotes(toks: Seq[NCNlpSentenceToken]): Seq[NCNlpSentenceNote] =
+            toks.flatten.filter(!_.isNlp).distinct
 
-            val delCombs: Seq[NCNlpSentenceNote] =
-                getNotNlpNotes(ns).
-                    flatMap(note ⇒ getNotNlpNotes(ns.slice(note.tokenFrom, note.tokenTo + 1)).filter(_ != note)).
-                    distinct
+        val delCombs: Seq[NCNlpSentenceNote] =
+            getNotNlpNotes(ns).
+                flatMap(note ⇒ getNotNlpNotes(ns.slice(note.tokenFrom, note.tokenTo + 1)).filter(_ != note)).
+                distinct
 
-            val toksByIdx: Seq[Seq[NCNlpSentenceNote]] =
-                delCombs.flatMap(note ⇒ note.wordIndexes.map(_ → note)).
-                    groupBy { case (idx, _) ⇒ idx }.
-                    map { case (_, seq) ⇒ seq.map { case (_, note) ⇒ note } }.
-                    toSeq.sortBy(-_.size)
+        val toksByIdx: Seq[Seq[NCNlpSentenceNote]] =
+            delCombs.flatMap(note ⇒ note.wordIndexes.map(_ → note)).
+                groupBy { case (idx, _) ⇒ idx }.
+                map { case (_, seq) ⇒ seq.map { case (_, note) ⇒ note } }.
+                toSeq.sortBy(-_.size)
 
-            val minDelSize = if (toksByIdx.isEmpty) 1 else toksByIdx.map(_.size).max - 1
+        val minDelSize = if (toksByIdx.isEmpty) 1 else toksByIdx.map(_.size).max - 1
 
-            val sens =
-                if (delCombs.nonEmpty) {
-                    val deleted = mutable.ArrayBuffer.empty[Seq[NCNlpSentenceNote]]
+        val sens =
+            if (delCombs.nonEmpty) {
+                val deleted = mutable.ArrayBuffer.empty[Seq[NCNlpSentenceNote]]
 
-                    val sens =
-                        (minDelSize to delCombs.size).
-                            flatMap(i ⇒
-                                delCombs.combinations(i).
-                                    filter(delComb ⇒ !toksByIdx.exists(_.count(note ⇒ !delComb.contains(note)) > 1))
-                            ).
-                            sortBy(_.size).
-                            flatMap(delComb ⇒
-                                // Already processed with less subset of same deleted tokens.
-                                if (!deleted.exists(_.forall(delComb.contains))) {
-                                    val nsClone = ns.clone()
+                val sens =
+                    (minDelSize to delCombs.size).
+                        flatMap(i ⇒
+                            delCombs.combinations(i).
+                                filter(delComb ⇒ !toksByIdx.exists(_.count(note ⇒ !delComb.contains(note)) > 1))
+                        ).
+                        sortBy(_.size).
+                        flatMap(delComb ⇒
+                            // Already processed with less subset of same deleted tokens.
+                            if (!deleted.exists(_.forall(delComb.contains))) {
+                                val nsClone = ns.clone()
 
-                                    delComb.foreach(nsClone.removeNote)
+                                delComb.foreach(nsClone.removeNote)
 
-                                    // Has overlapped notes for some tokens.
-                                    require(!nsClone.exists(_.count(!_.isNlp) > 1))
+                                // Has overlapped notes for some tokens.
+                                require(!nsClone.exists(_.count(!_.isNlp) > 1))
 
-                                    deleted += delComb
+                                deleted += delComb
 
-                                    val notNlpTypes = getNotNlpNotes(nsClone).map(_.noteType).distinct
+                                val notNlpTypes = getNotNlpNotes(nsClone).map(_.noteType).distinct
 
-                                    if (collapse(nsClone, notNlpTypes)) Some(nsClone) else None
-                                }
-                                else
-                                    None
-                            )
+                                if (collapse(nsClone, notNlpTypes)) Some(nsClone) else None
+                            }
+                            else
+                                None
+                        )
 
-                    // It removes sentences which have only one difference - 'direct' flag of their user tokens.
-                    // `Direct` sentences have higher priority.
-                    case class Key(
-                        sysNotes: Seq[Map[String, java.io.Serializable]],
-                        userNotes: Seq[Map[String, java.io.Serializable]]
-                    )
-                    case class Value(sentence: NCNlpSentence, directCount: Int)
+                // It removes sentences which have only one difference - 'direct' flag of their user tokens.
+                // `Direct` sentences have higher priority.
+                case class Key(
+                    sysNotes: Seq[Map[String, java.io.Serializable]],
+                    userNotes: Seq[Map[String, java.io.Serializable]]
+                )
+                case class Value(sentence: NCNlpSentence, directCount: Int)
 
-                    val m = mutable.HashMap.empty[Key, Value]
+                val m = mutable.HashMap.empty[Key, Value]
 
-                    sens.map(sen ⇒ {
-                        val notes = sen.flatten
+                sens.map(sen ⇒ {
+                    val notes = sen.flatten
 
-                        val sysNotes = notes.filter(_.isSystem)
-                        val nlpNotes = notes.filter(_.isNlp)
-                        val userNotes = notes.filter(_.isUser)
+                    val sysNotes = notes.filter(_.isSystem)
+                    val nlpNotes = notes.filter(_.isNlp)
+                    val userNotes = notes.filter(_.isUser)
 
-                        def get(seq: Seq[NCNlpSentenceNote], keys2Skip: String*): Seq[Map[String, java.io.Serializable]] =
-                            seq.map(p ⇒
-                                // We have to delete some keys to have possibility to compare sentences.
-                                p.clone().filter(_._1 != "direct")
-                            )
+                    def get(seq: Seq[NCNlpSentenceNote], keys2Skip: String*): Seq[Map[String, java.io.Serializable]] =
+                        seq.map(p ⇒
+                            // We have to delete some keys to have possibility to compare sentences.
+                            p.clone().filter(_._1 != "direct")
+                        )
 
-                        (Key(get(sysNotes), get(userNotes)), sen, nlpNotes.map(p ⇒ if (p.isDirect) 0 else 1).sum)
-                    }).
-                        foreach { case (key, sen, directCnt) ⇒
-                            m.get(key) match {
-                                case Some(v) ⇒
-                                    // Best sentence is sentence with `direct` synonyms.
-                                    if (v.directCount > directCnt)
-                                        m += key → Value(sen, directCnt)
-                                case None ⇒ m += key → Value(sen, directCnt)
-                            }
+                    (Key(get(sysNotes), get(userNotes)), sen, nlpNotes.map(p ⇒ if (p.isDirect) 0 else 1).sum)
+                }).
+                    foreach { case (key, sen, directCnt) ⇒
+                        m.get(key) match {
+                            case Some(v) ⇒
+                                // Best sentence is sentence with `direct` synonyms.
+                                if (v.directCount > directCnt)
+                                    m += key → Value(sen, directCnt)
+                            case None ⇒ m += key → Value(sen, directCnt)
                         }
+                    }
 
-                    m.values.map(_.sentence).toSeq
+                m.values.map(_.sentence).toSeq
+            }
+            else {
+                if (collapse(ns, getNotNlpNotes(ns).map(_.noteType).distinct)) Seq(ns) else Seq.empty
+            }.distinct
+
+        sens.foreach(sen ⇒
+            sen.foreach(tok ⇒
+                tok.size match {
+                    case 1 ⇒ require(tok.head.isNlp, s"Unexpected non-'nlpcraft:nlp' token: $tok")
+                    case 2 ⇒ require(tok.head.isNlp ^ tok.last.isNlp, s"Unexpected token notes: $tok")
+                    case _ ⇒ require(requirement = false, s"Unexpected token notes count: $tok")
                 }
-                else {
-                    if (collapse(ns, getNotNlpNotes(ns).map(_.noteType).distinct)) Seq(ns) else Seq.empty
-                }.distinct
-
-            sens.foreach(sen ⇒
-                sen.foreach(tok ⇒
-                    tok.size match {
-                        case 1 ⇒ require(tok.head.isNlp, s"Unexpected non-'nlpcraft:nlp' token: $tok")
-                        case 2 ⇒ require(tok.head.isNlp ^ tok.last.isNlp, s"Unexpected token notes: $tok")
-                        case _ ⇒ require(requirement = false, s"Unexpected token notes count: $tok")
-                    }
-                )
             )
+        )
 
-            // Drops similar sentences (with same tokens structure).
-            // Among similar sentences we prefer one with minimal free words count.
-            sens.groupBy(_.flatten.filter(!_.isNlp).map(note ⇒ getKey(note, withIndexes = false))).
-            map { case (_, seq) ⇒ seq.minBy(_.filter(p ⇒ p.isNlp && !p.isStopWord).map(_.wordIndexes.length).sum) }.
-            toSeq
-        }
+        // Drops similar sentences (with same tokens structure).
+        // Among similar sentences we prefer one with minimal free words count.
+        sens.groupBy(_.flatten.filter(!_.isNlp).map(note ⇒ getKey(note, withIndexes = false))).
+        map { case (_, seq) ⇒ seq.minBy(_.filter(p ⇒ p.isNlp && !p.isStopWord).map(_.wordIndexes.length).sum) }.
+        toSeq
+    }
 
     /**
       *
diff --git a/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/limit/NCLimitEnricher.scala b/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/limit/NCLimitEnricher.scala
index 23be9fd..a533c68 100644
--- a/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/limit/NCLimitEnricher.scala
+++ b/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/limit/NCLimitEnricher.scala
@@ -27,7 +27,7 @@ import org.apache.nlpcraft.common.nlp.{NCNlpSentence, NCNlpSentenceNote, NCNlpSe
 import org.apache.nlpcraft.common.{NCE, NCService}
 import org.apache.nlpcraft.probe.mgrs.NCModelDecorator
 import org.apache.nlpcraft.probe.mgrs.nlp.NCProbeEnricher
-import org.apache.nlpcraft.probe.mgrs.nlp.impl.NCEnricherProcessor
+import org.apache.nlpcraft.probe.mgrs.nlp.enrichers.NCEnricherUtils
 
 import scala.collection.JavaConverters._
 import scala.collection.{Map, Seq, mutable}
@@ -216,7 +216,7 @@ object NCLimitEnricher extends NCProbeEnricher {
             // Tries to grab tokens reverse way.
             // Example: A, B, C ⇒ ABC, BC, AB .. (BC will be processed first)
             for (toks ← ns.tokenMixWithStopWords().sortBy(p ⇒ (-p.size, -p.head.index))
-                 if NCEnricherProcessor.validImportant(ns, toks, isImportant)
+                 if NCEnricherUtils.validImportant(ns, toks, isImportant)
             )
                 tryToMatch(numsMap, groupsMap, toks) match {
                     case Some(m) ⇒
@@ -232,7 +232,7 @@ object NCLimitEnricher extends NCProbeEnricher {
 
                             val note = NCNlpSentenceNote(m.matched.map(_.index), TOK_ID, params: _*)
 
-                            if (!notes.exists(n ⇒ NCEnricherProcessor.equalOrSimilar(note, n, ns))) {
+                            if (!notes.exists(n ⇒ NCEnricherUtils.equalOrSimilar(note, n, ns))) {
                                 notes += note
 
                                 m.matched.foreach(_.add(note))
diff --git a/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/model/NCModelEnricher.scala b/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/model/NCModelEnricher.scala
index 72ffc78..0cc3978 100644
--- a/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/model/NCModelEnricher.scala
+++ b/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/model/NCModelEnricher.scala
@@ -25,7 +25,8 @@ import org.apache.nlpcraft.common._
 import org.apache.nlpcraft.common.nlp.{NCNlpSentenceToken, _}
 import org.apache.nlpcraft.model._
 import org.apache.nlpcraft.probe.mgrs.nlp.NCProbeEnricher
-import org.apache.nlpcraft.probe.mgrs.nlp.impl.{NCEnricherProcessor, NCRequestImpl}
+import org.apache.nlpcraft.probe.mgrs.nlp.enrichers.NCEnricherUtils
+import org.apache.nlpcraft.probe.mgrs.nlp.impl.NCRequestImpl
 import org.apache.nlpcraft.probe.mgrs.{NCModelDecorator, NCSynonym}
 
 import scala.collection.JavaConverters._
@@ -376,10 +377,10 @@ object NCModelEnricher extends NCProbeEnricher with DecorateAsScala {
 
                                 if (collapsedSens == null)
                                     collapsedSens =
-                                        NCEnricherProcessor.convert(
+                                        NCEnricherUtils.convert(
                                             mdl,
                                             ns.srvReqId,
-                                            NCEnricherProcessor.collapse(mdl, ns.clone(), span).map(_.tokens)
+                                            NCEnricherUtils.collapse(mdl, ns.clone(), span).map(_.tokens)
                                         )
 
                                 if (seq == null)
diff --git a/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/relation/NCRelationEnricher.scala b/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/relation/NCRelationEnricher.scala
index eba50eb..558fcee 100644
--- a/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/relation/NCRelationEnricher.scala
+++ b/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/relation/NCRelationEnricher.scala
@@ -26,7 +26,7 @@ import org.apache.nlpcraft.common.nlp.{NCNlpSentence, NCNlpSentenceNote, NCNlpSe
 import org.apache.nlpcraft.common.{NCE, NCService}
 import org.apache.nlpcraft.probe.mgrs.NCModelDecorator
 import org.apache.nlpcraft.probe.mgrs.nlp.NCProbeEnricher
-import org.apache.nlpcraft.probe.mgrs.nlp.impl.NCEnricherProcessor
+import org.apache.nlpcraft.probe.mgrs.nlp.enrichers.NCEnricherUtils
 
 import scala.collection.JavaConverters._
 import scala.collection.{Map, Seq, mutable}
@@ -132,7 +132,7 @@ object NCRelationEnricher extends NCProbeEnricher {
             def isImportant(t: NCNlpSentenceToken): Boolean =
                 t.exists(n ⇒ n.isUser || REL_TYPES.contains(n.noteType)) || ALL_FUNC_STEMS.contains(t.stem)
 
-            for (toks ← ns.tokenMixWithStopWords() if NCEnricherProcessor.validImportant(ns, toks, isImportant))
+            for (toks ← ns.tokenMixWithStopWords() if NCEnricherUtils.validImportant(ns, toks, isImportant))
                 tryToMatch(toks) match {
                     case Some(m) ⇒
                         for (refNote ← m.refNotes) {
@@ -144,7 +144,7 @@ object NCRelationEnricher extends NCProbeEnricher {
                                 "note" → refNote
                             )
 
-                            if (!notes.exists(n ⇒ NCEnricherProcessor.equalOrSimilar(note, n, ns))) {
+                            if (!notes.exists(n ⇒ NCEnricherUtils.equalOrSimilar(note, n, ns))) {
                                 notes += note
 
                                 m.matched.filter(_ != m.matchedHead).foreach(_.addStopReason(note))
diff --git a/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/sort/NCSortEnricher.scala b/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/sort/NCSortEnricher.scala
index bd9df0e..fc9d4a8 100644
--- a/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/sort/NCSortEnricher.scala
+++ b/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/sort/NCSortEnricher.scala
@@ -26,7 +26,7 @@ import org.apache.nlpcraft.common.nlp.core.NCNlpCoreManager
 import org.apache.nlpcraft.common.nlp.{NCNlpSentence, NCNlpSentenceNote, NCNlpSentenceToken}
 import org.apache.nlpcraft.probe.mgrs.NCModelDecorator
 import org.apache.nlpcraft.probe.mgrs.nlp.NCProbeEnricher
-import org.apache.nlpcraft.probe.mgrs.nlp.impl.NCEnricherProcessor
+import org.apache.nlpcraft.probe.mgrs.nlp.enrichers.NCEnricherUtils
 
 import scala.collection.JavaConverters._
 import scala.collection.mutable.ArrayBuffer
@@ -431,7 +431,7 @@ object NCSortEnricher extends NCProbeEnricher {
             val notes = mutable.HashSet.empty[NCNlpSentenceNote]
             def isImportant(t: NCNlpSentenceToken): Boolean = isUserNotValue(t) || MASK_WORDS.contains(t.stem)
 
-            for (toks ← ns.tokenMixWithStopWords() if NCEnricherProcessor.validImportant(ns, toks, isImportant)) {
+            for (toks ← ns.tokenMixWithStopWords() if NCEnricherUtils.validImportant(ns, toks, isImportant)) {
                 tryToMatch(toks) match {
                     case Some(m) ⇒
                         def addNotes(
@@ -449,7 +449,7 @@ object NCSortEnricher extends NCProbeEnricher {
                         def mkNote(params: ArrayBuffer[(String, Any)]): Unit = {
                             val note = NCNlpSentenceNote(m.main.map(_.index), TOK_ID, params: _*)
 
-                            if (!notes.exists(n ⇒ NCEnricherProcessor.equalOrSimilar(note, n, ns))) {
+                            if (!notes.exists(n ⇒ NCEnricherUtils.equalOrSimilar(note, n, ns))) {
                                 notes += note
 
                                 m.main.foreach(_.add(note))