in nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/matcher/NCIntentSolverManager.scala [116:285]
def +=(that: Weight): Weight =
val tmp = mutable.ArrayBuffer[Int]()
for (i <- 0 until Math.max(buf.size, that.buf.size))
tmp.append(norm(i, buf) + norm(i, that.buf))
buf.clear()
buf ++= tmp
this
/**
* Appends new weight.
*
* @param w New weight to append.
*/
def append(w: Int): Weight =
buf.append(w)
this
/**
* Prepends new weight.
*
* @param w New weight to prepend.
*/
def prepend(w: Int): Weight =
buf.prepend(w)
this
/**
* Sets specific weight at a given index.
*
* @param idx
* @param w
*/
def setWeight(idx: Int, w: Int): Unit =
buf(idx) = w
/**
* Gets element at given index or zero if index is out of bounds.
*
* @param i Index in collection.
* @param c Collection.
*/
private def norm(i: Int, c: mutable.ArrayBuffer[Int]): Int = if i < c.size then c(i) else 0
/**
*
* @param that
*/
override def compare(that: Weight): Int =
def compareWeight(idx: Int): Option[Int] =
val res = Integer.compare(norm(idx, buf), norm(idx, that.buf))
Option.when(res != 0)(res)
(0 until Math.max(buf.size, that.buf.size)).flatMap(compareWeight).to(LazyList).headOption.getOrElse(0)
def toSeq: Seq[Int] = buf.toSeq
override def toString: String = buf.mkString("[", ", ", "]")
/**
*
* @param used
* @param entity
*/
private case class IntentEntity(var used: Boolean, var conv: Boolean, entity: NCEntity)
type ResultData = Either[NCResult, NCMatchedCallback]
/**
*
* @param result
* @param intentMatch
*/
private case class IterationResult(result: ResultData, intentMatch: NCIntentMatch)
/**
* @param termId
* @param usedEntities
* @param weight
*/
private case class TermMatch(termId: Option[String], usedEntities: List[IntentEntity], weight: Weight):
private lazy val maxIndex: Int = usedEntities.map(_.entity.getTokens.map(_.getIndex).max).max
def after(tm: TermMatch): Boolean = maxIndex > tm.maxIndex
/**
*
* @param entities
*/
private case class PredicateMatch(entities: List[IntentEntity], weight: Weight)
/**
*
* @param term
* @param usedEntities
*/
private case class TermEntitiesGroup(
term: NCIDLTerm,
usedEntities: List[IntentEntity]
)
/**
*
* @param entityGroups
* @param weight
* @param intent
*/
private case class IntentMatchHolder(
entityGroups: List[TermEntitiesGroup],
weight: Weight,
intent: NCIDLIntent
)
/**
*
* @param intentMatch
* @param callback
* @param variant
* @param variantIdx
*/
private case class MatchHolder(
intentMatch: IntentMatchHolder, // Match.
callback: NCCallbackInput => NCResult, // Callback function.
variant: IntentSolverVariant, // Variant used for the match.
variantIdx: Int // Variant index.
)
/**
*
* @param userId
* @param mldId
*/
private case class UserModelKey(userId: String, mldId: String)
import org.apache.nlpcraft.internal.intent.matcher.NCIntentSolverManager.*
/**
* Intent solver that finds the best matching intent given user sentence.
*/
class NCIntentSolverManager(
dialog: NCDialogFlowManager,
conv: NCConversationManager,
intents: Map[NCIDLIntent, NCCallbackInput => NCResult]
) extends LazyLogging:
private final val reqIds = mutable.HashMap.empty[UserModelKey, String]
/**
* Main entry point for intent engine.
*
* @param mdl Model.
* @param ctx Query context.
* @param intents Intents to match for.
*/
private def solveIntents(mdl: NCModel, ctx: NCContext, intents: Map[NCIDLIntent, NCCallbackInput => NCResult]): List[IntentSolverResult] =
dialog.ack(ctx.getRequest.getUserId)
val matches = mutable.ArrayBuffer.empty[MatchHolder]
// Find all matches across all intents and sentence variants.
for (
(vrn, vrnIdx) <- ctx.getVariants.zipWithIndex;
ents = vrn.getEntities;
varEntsGroups = ents.filter(t => t.getGroups != null && t.getGroups.nonEmpty).map(_.getGroups);
(intent, callback) <- intents
)
val convEnts: Seq[IntentEntity] =
if intent.terms.exists(_.conv) then
// We do not mix tokens with same group from the conversation and given sentence.
ctx.getConversation.getStm.
map(ent => ent -> (if ent.getGroups == null then Set.empty else ent.getGroups)).
filter { (_, entGroups) => !varEntsGroups.exists(_.subsetOf(entGroups)) }.