This is an automated email from the ASF dual-hosted git repository.
sergeykamov pushed a commit to branch NLPCRAFT-376
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git
The following commit(s) were added to refs/heads/NLPCRAFT-376 by this push:
new 157265a WIP.
157265a is described below
commit 157265a3dac3f46ebc0b1aa6c402ca153dc78f8a
Author: Sergey Kamov <[email protected]>
AuthorDate: Wed Jul 28 11:46:58 2021 +0300
WIP.
---
.../model/intent/solver/NCIntentSolver.scala | 172 ++++++++++++++++++++-
.../probe/mgrs/sentence/NCSentenceManager.scala | 56 +------
2 files changed, 167 insertions(+), 61 deletions(-)
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolver.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolver.scala
index bd6e734..5efe204 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolver.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolver.scala
@@ -27,9 +27,9 @@ import org.apache.nlpcraft.model.impl.{NCMetadataAdapter,
NCVariantImpl}
import org.apache.nlpcraft.model.intent.NCIdlIntent
import org.apache.nlpcraft.model.{NCContext, NCIntentMatch, NCIntentSkip,
NCModel, NCRejection, NCResult, NCToken, NCVariant}
import org.apache.nlpcraft.probe.mgrs.dialogflow.NCDialogFlowManager
-import org.apache.nlpcraft.probe.mgrs.sentence.NCSentenceManager
-import java.util.{List => JList}
+import java.util.{Collections, List => JList}
+import scala.collection.mutable
import scala.jdk.CollectionConverters.{ListHasAsScala, SeqHasAsJava}
/**
@@ -102,17 +102,16 @@ class NCIntentSolver(intents:
List[(NCIdlIntent/*Intent*/, NCIntentMatch => NCRe
val intentToks =
res.groups.map(_.tokens).map(toks => {
toks.filter(allConvToks.contains).foreach(convTok =>
- NCSentenceManager.fixMeta(convTok, nonConvToks,
allConvToks)
- )
+ fixBuiltTokensMeta(convTok, nonConvToks,
allConvToks))
- toks
- })
+ toks.asJava
+ }).asJava
ctx.getConversation.getTokens
val intentMatch: NCIntentMatch = new NCMetadataAdapter with
NCIntentMatch {
override val getContext: NCContext = ctx
- override val getIntentTokens: JList[JList[NCToken]] =
intentToks.map(_.asJava).asJava
+ override val getIntentTokens: JList[JList[NCToken]] =
intentToks
override val getVariant: NCVariant = new
NCVariantImpl(res.variant.tokens)
override val getIntentId: String = res.intentId
override def getTermTokens(idx: Int): JList[NCToken] =
res.groups(idx).tokens.asJava
@@ -175,4 +174,163 @@ class NCIntentSolver(intents:
List[(NCIdlIntent/*Intent*/, NCIntentMatch => NCRe
throw new NCRejection("No matching intent found - all intents were
skipped.")
}
+
+
+ /**
+ *
+ * @param convTok
+ * @param nonConvToks
+ * @param allConvToks
+ */
+ private def fixBuiltTokensMeta(convTok: NCToken, nonConvToks:
Seq[NCToken], allConvToks: Seq[NCToken]): Unit = {
+ def isReference(tok: NCToken, id: String, idx: Int): Boolean =
tok.getId == id && tok.getIndex == idx
+ def sameGroup(t1: NCToken, t2: NCToken): Boolean = {
+ val gs1 = t1.getGroups.asScala
+ val gs2 = t2.getGroups.asScala
+
+ gs1.exists(gs2.contains)
+ }
+
+ def getSeq[T](tok: NCToken,name: String): Seq[T] = {
+ val list = tok.meta[JList[T]](name)
+
+ if (list == null) Seq.empty else list.asScala
+ }
+
+ convTok.getId match {
+ case "nlpcraft:sort" =>
+ def fix(notesName: String, idxsName: String): Unit = {
+ val refIds: Seq[String] = getSeq(convTok,
s"nlpcraft:sort:$notesName")
+ val refIdxs: Seq[Int] = getSeq(convTok,
s"nlpcraft:sort:$idxsName")
+
+ require(refIds.length == refIdxs.length)
+
+ // Can be empty section for sort.
+ if (refIds.nonEmpty) {
+ var data = mutable.ArrayBuffer.empty[(String, Int)]
+ val notFound = mutable.ArrayBuffer.empty[(String, Int)]
+
+ // Sort elements can be different types.
+ // Part of them can be in conversation , part of them
- in actual variant.
+ refIds.zip(refIdxs).map { case (refId, refIdx) =>
+ val seq =
+ nonConvToks.find(isReference(_, refId,
refIdx)) match {
+ case Some(_) => data
+ case None => notFound
+ }
+
+ seq += refId -> refIdx
+ }
+
+ notFound.
+ groupBy { case (nfRefId, _) => nfRefId }.
+ map { case (nfRefId, data) => nfRefId ->
data.map(_._2).sorted }.foreach {
+ case (nfRefId, nfRefIdsx) =>
+ val convRefs = allConvToks.filter(_.getId ==
nfRefId)
+
+ if (convRefs.map(_.getIndex).sorted !=
nfRefIdsx)
+ throw new NCE(
+ s"Conversation references are not
found [id=$nfRefId, " +
+ s"indexes=${nfRefIdsx.mkString(",
")}]"
+ )
+
+ val convRefsAny = convRefs.head
+
+ val newNonConvRefs =
nonConvToks.filter(sameGroup(convRefsAny, _))
+
+ if (newNonConvRefs.nonEmpty &&
newNonConvRefs.size != nfRefIdsx.size)
+ throw new NCE(
+ s"Variant references are not found
[id=$nfRefId, count=${nfRefIdsx.size}]"
+ )
+
+ val refs = if (newNonConvRefs.nonEmpty)
newNonConvRefs else convRefs
+
+ refs.foreach(t => data += t.getId ->
t.getIndex)
+ }
+
+ data = data.sortBy(_._2)
+
+ convTok.getMetadata.put(s"nlpcraft:sort:$notesName",
data.map(_._1).asJava)
+ convTok.getMetadata.put(s"nlpcraft:sort:$idxsName",
data.map(_._2).asJava)
+ }
+ }
+
+ fix("bynotes", "byindexes")
+ fix("subjnotes", "subjindexes")
+ case "nlpcraft:limit" =>
+ val refId = convTok.meta[String]("nlpcraft:limit:note")
+ val refIdxs =
convTok.meta[JList[Int]]("nlpcraft:limit:indexes").asScala
+
+ require(refIdxs.size == 1)
+
+ val refIdx = refIdxs.head
+
+ if (!nonConvToks.exists(isReference(_, refId, refIdx))) {
+ val convRefs = allConvToks.filter(_.getId == refId)
+
+ if (convRefs.size != 1 || convRefs.head.getIndex != refIdx)
+ throw new NCE(s"Conversation reference is not found
[id=$refId, index=$refIdx]")
+
+ val convRef = convRefs.head
+
+ val nonConvRefs = nonConvToks.filter(sameGroup(convRef, _))
+
+ if (nonConvRefs.nonEmpty && nonConvRefs.size != 1)
+ throw new NCE(s"Variant reference are not found
[id=$refId]")
+
+ val ref = if (nonConvRefs.nonEmpty) nonConvRefs.head else
convRef
+
+ convTok.getMetadata.put(s"nlpcraft:limit:note", ref.getId)
+ convTok.getMetadata.put(s"nlpcraft:limit:indexes",
Collections.singleton(ref.getIndex))
+ }
+
+ case "nlpcraft:relation" =>
+ val refId = convTok.meta[String]("nlpcraft:relation:note")
+ val refIdxs =
convTok.meta[JList[Int]]("nlpcraft:relation:indexes").asScala.sorted
+
+ val convRefs = allConvToks.filter(_.getId == refId)
+
+ val nonConvRefs = nonConvToks.filter(t => t.getId == refId &&
refIdxs.contains(t.getIndex))
+
+ if (nonConvRefs.nonEmpty && nonConvRefs.size != refIdxs.size)
+ throw new NCE(
+ s"References are not found [id=$refId, " +
+ s"indexes=${refIdxs.mkString(", ")}]"
+ )
+
+ if (nonConvRefs.isEmpty) {
+ val convRefs = allConvToks.filter(t => t.getId == refId
&& refIdxs.contains(t.getIndex))
+
+ if (convRefs.size != refIdxs.size)
+ throw new NCE(
+ s"Conversation references are not found
[id=$refId, " +
+ s"indexes=${refIdxs.mkString(", ")}]"
+ )
+
+ val convRefsAny = convRefs.head
+
+ val newNonConvRefs =
nonConvToks.filter(sameGroup(convRefsAny, _))
+
+ if (newNonConvRefs.nonEmpty && newNonConvRefs.size !=
refIdxs.size)
+ throw new NCE(
+ s"Variant references are not found [id=$refId,
count=${refIdxs.size}]"
+ )
+
+ val refs = if (newNonConvRefs.nonEmpty) newNonConvRefs
else convRefs
+
+ val refsIds = refs.map(_.getId).distinct
+
+ if (refsIds.size != 1)
+ throw new NCE(
+ s"Variant references are not found [id=$refId,
count=${refIdxs.size}]"
+ )
+
+
+ convTok.getMetadata.put(s"nlpcraft:relation:note",
refsIds.head)
+ convTok.getMetadata.put(s"nlpcraft:relation:indexes",
refs.map(_.getIndex).asJava)
+ }
+
+ case _ => // No-op.
+ }
+ }
}
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/sentence/NCSentenceManager.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/sentence/NCSentenceManager.scala
index 115d7f9..74ead87 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/sentence/NCSentenceManager.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/sentence/NCSentenceManager.scala
@@ -22,7 +22,7 @@ import org.apache.nlpcraft.common.nlp.NCNlpSentence.NoteLink
import org.apache.nlpcraft.common.nlp.pos.NCPennTreebank
import org.apache.nlpcraft.common.nlp.{NCNlpSentence, NCNlpSentenceNote,
NCNlpSentenceToken}
import org.apache.nlpcraft.common.{NCE, NCService, U, _}
-import org.apache.nlpcraft.model.{NCModel, NCToken}
+import org.apache.nlpcraft.model.NCModel
import org.apache.nlpcraft.probe.mgrs.NCTokenPartKey
import java.io.{Serializable => JSerializable}
@@ -43,6 +43,7 @@ object NCSentenceManager extends NCService {
type CacheValue = Seq[Seq[NCNlpSentenceNote]]
private val combCache = mutable.HashMap.empty[String,
mutable.HashMap[CacheKey, CacheValue]]
+
/**
*
* @param notes
@@ -790,57 +791,4 @@ object NCSentenceManager extends NCService {
* @param srvReqId
*/
def clearCache(srvReqId: String): Unit = combCache -= srvReqId
-
-
-
- /**
- *
- * @param convTok
- * @param nonConvToks
- * @param allConvToks
- */
- def fixMeta(convTok: NCToken, nonConvToks: Seq[NCToken], allConvToks:
Seq[NCToken]): Unit =
- convTok.getId match {
- case "nlpcraft:sort" =>
- def fix(notesName: String, idxsName: String): Unit = {
- val notes =
convTok.meta[JList[String]](s"nlpcraft:sort:$notesName")
- val idxs =
convTok.meta[JList[Int]](s"nlpcraft:sort:$idxsName")
-
- require(notes == null && idxs == null || notes.size() ==
idxs.size())
-
- if (notes != null && !notes.isEmpty) {
- val data: Seq[(String, Int)] =
- notes.asScala.zip(idxs.asScala).map { case (note,
idx) =>
- nonConvToks.find(t => t.getId == note &&
t.getIndex == idx) match {
- case Some(_) => (note, idx)
- case None =>
- val ref =
- allConvToks.
- find(t => t.getId == note &&
t.getIndex == idx).
- getOrElse(
- throw new NCE(s"Reference
is not found [note=$note, index=$idx]")
- )
-
- val newRef =
- nonConvToks.
- find(t =>
-
t.getGroups.asScala.toSet.intersect(ref.getGroups.asScala.toSet).nonEmpty
- ).
- getOrElse(
- throw new NCE(s"New
reference is not found [note=$note, index=$idx]")
- )
-
- (newRef.getId, newRef.getIndex)
- }
- }
-
- convTok.getMetadata.put(s"nlpcraft:sort:$notesName",
data.map(_._1).asJava)
- convTok.getMetadata.put(s"nlpcraft:sort:$idxsName",
data.map(_._2).asJava)
- }
- }
-
- fix("bynotes", "byindexes")
- fix("subjnotes", "subjindexes")
- case _ => // TODO: implement all other.
- }
}