---
active_crumb: Pizzeria <code><sub>ex</sub></code>
layout: documentation
id: pizzeria
fa_icon: fa-cube
---

<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You 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.
-->

<div class="col-md-8 second-column example">
    <section id="overview">
        <h2 class="section-title">Overview <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2>
        <p>
            This example provides a simple pizza ordering model.
            It demonstrates how to work with dialogue systems which require confirmation logic.
        </p>
        <p>
            <b>Complexity:</b> <span class="complexity-three-star"><i class="fas fa-gem"></i> <i class="fas fa-gem"></i> <i class="fas fa-gem"></i></span><br/>
            <span class="ex-src">Source code: <a target="github" href="https://github.com/apache/incubator-nlpcraft/tree/master/nlpcraft-examples/caclulator">GitHub <i class="fab fa-fw fa-github"></i></a><br/></span>
            <span class="ex-review-all">Review: <a target="github" href="https://github.com/apache/incubator-nlpcraft/tree/master/nlpcraft-examples">All Examples at GitHub <i class="fab fa-fw fa-github"></i></a></span>
        </p>
    </section>
    <section id="new_project">
        <h2 class="section-title">Create New Project <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2>
        <p>
            You can create new Scala projects in many ways - we'll use SBT
            to accomplish this task. Make sure that <code>build.sbt</code> file has the following content:
        </p>
        <pre class="brush: js, highlight: [7]">
            ThisBuild / version := "0.1.0-SNAPSHOT"
            ThisBuild / scalaVersion := "3.1.3"
            lazy val root = (project in file("."))
              .settings(
                name := "NLPCraft Calculator Example",
                version := "{{site.latest_version}}",
                libraryDependencies += "org.apache.nlpcraft" % "nlpcraft" % "{{site.latest_version}}",
                libraryDependencies += "org.apache.nlpcraft" % "nlpcraft-stanford" % "1.0.0",
                libraryDependencies += "edu.stanford.nlp" % "stanford-corenlp" % "4.5.1",
                libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.14" % "test"
              )
        </pre>
        <p><b>NOTE: </b>use the latest versions of Scala, ScalaTest and StanfordNLP library.</p>
        <p>Create the following files so that resulting project structure would look like the following:</p>
        <ul>
            <li><code>pizzeria_model.yaml</code> - YAML configuration file which contains model description.</li>
            <li><code>PizzeriaModel.scala</code> - Model implementation.</li>
            <li><code>PizzeriaOrder.scala</code> - Pizza order state representation.</li>
            <li><code>PizzeriaModelPipeline.scala</code> - Model pipeline definition class.</li>
            <li><code>PizzeriaOrderMapper.scala</code> - <a href="../apis/latest/org/apache/nlpcraft/NCEntityMapper.html">NCEntityMapper</a> custom implementation.</li>
            <li><code>PizzeriaOrderValidator.scala</code> - <a href="../apis/latest/org/apache/nlpcraft/NCEntityValidator.html">NCEntityValidator</a>> custom implementation.</li>
            <li><code>PizzeriaModelSpec.scala</code> - Test that allows to test your model.</li>
        </ul>
        <pre class="brush: plain, highlight: [7, 11, 12, 13, 14, 15, 19]">
            |  build.sbt
            +--project
            |    build.properties
            \--src
               +--main
               |  +--resources
               |  |  pizzeria_model.yaml
               |  \--scala
               |     \--demo
               |        \--components
               |             PizzeriaModelPipeline.scala
               |             PizzeriaOrderMapper.scala
               |             PizzeriaOrderValidator.scala
               |          PizzeriaModel.scala
               |          PizzeriaOrder.scala
               \--test
                  \--scala
                     \--demo
                          PizzeriaModelSpec.scala
        </pre>
    </section>
    <section id="model">
        <h2 class="section-title">Data Model<a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2>
        <p>
            We are going to start with declaring the static part of our model using YAML which we will later load using
            <a href="../apis/latest/org/apache/nlpcraft/NCModelAdapter.html">NCModelAdapter</a> custom implementation in our Scala-based model implementation.
            Open <code>src/main/resources/<b>pizzeria_model.yaml</b></code>
            file and replace its content with the following YAML:
        </p>
        <pre class="brush: js, highlight: [2, 9, 16, 23, 29, 35, 40, 46, 51]">
             elements:
              - id: "ord:pizza"
                description: "Kinds of pizza."
                values:
                  "margherita": [ ]
                  "carbonara": [ ]
                  "marinara": [ ]

              - id: "ord:pizza:size"
                description: "Size of pizza."
                values:
                  "small": [ "{small|smallest|min|minimal|tiny} {size|piece|_}" ]
                  "medium": [ "{medium|intermediate|normal|regular} {size|piece|_}" ]
                  "large": [ "{big|biggest|large|max|maximum|huge|enormous} {size|piece|_}" ]

              - id: "ord:drink"
                description: "Kinds of drinks."
                values:
                  "tea": [ ]
                  "coffee": [ ]
                  "cola": [ "{pepsi|sprite|dr. pepper|dr pepper|fanta|soda|cola|coca cola|cocacola|coca-cola}" ]

              - id: "ord:yes"
                description: "Confirmation (yes)."
                synonyms:
                  - "{yes|yeah|right|fine|nice|excellent|good|correct|sure|ok|exact|exactly|agree}"
                  - "{you are|_} {correct|right}"

              - id: "ord:no"
                description: "Confirmation (no)."
                synonyms:
                  - "{no|nope|incorrect|wrong}"
                  - "{you are|_} {not|are not|aren't} {correct|right}"

              - id: "ord:stop"
                description: "Stop and cancel all."
                synonyms:
                  - "{stop|cancel|clear|interrupt|quit|close} {it|all|everything|_}"

              - id: "ord:status"
                description: "Order status information."
                synonyms:
                  - "{present|current|_} {order|_} {status|state|info|information}"
                  - "what {already|_} ordered"

              - id: "ord:finish"
                description: "The order is over."
                synonyms:
                  - "{i|everything|order|_} {be|_} {finish|ready|done|over|confirmed}"

              - id: "ord:menu"
                description: "Order menu."
                synonyms:
                  - "{menu|carte|card}"
                  - "{products|goods|food|item|_} list"
                  - "{hi|help|hallo}"
        </pre>

        <ul>
            <li>
                <code>Lines 1, 9, 16</code> define order elements which present parts of order.
            </li>
            <li>
                <code>Lines 35, 40, 46, 51</code> define command elements which are used to control order state.
            </li>
            <li>
                <code>Lines 23, 29</code> define elements which are used for commands confirmation or cancellation.
            </li>
        </ul>
        <div class="bq info">
            <p><b>YAML vs. API</b></p>
            <p>
                As usual, this YAML-based static model definition is convenient but totally optional. All elements definitions
                can be provided programmatically inside Scala model <code>PizzeriaModel</code> class as well.
            </p>
        </div>
    </section>
    <section id="code">
        <h2 class="section-title">Model Class <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2>

        <p>
            Open <code>src/main/scala/demo/<b>PizzeriaOrder.scala</b></code> file and replace its content with the following code:
        </p>
        <pre class="brush: scala, highlight: [6, 17, 20, 25]">
            package demo

            import scala.collection.mutable
            import org.apache.nlpcraft.*

            enum PizzeriaOrderState:
                case DIALOG_EMPTY, DIALOG_IS_READY, DIALOG_SHOULD_CANCEL, DIALOG_SPECIFY, DIALOG_CONFIRM

            private object OrderPosition:
                val DFLT_QTY = 1

            private trait OrderPosition:
                val name: String
                var qty: Option[Int]
                require(name != null && name.nonEmpty)

            case class Pizza(name: String, var size: Option[String], var qty: Option[Int]) extends OrderPosition:
                override def toString = s"$name '${size.getOrElse("undefined size")}' ${qty.getOrElse(OrderPosition.DFLT_QTY)} pcs"

            case class Drink(name: String, var qty: Option[Int]) extends OrderPosition:
                override def toString = s"$name ${qty.getOrElse(OrderPosition.DFLT_QTY)} pcs"

            import PizzeriaOrderState.*

            class PizzeriaOrder:
                private var state = DIALOG_EMPTY
                private val pizzas = mutable.ArrayBuffer.empty[Pizza]
                private val drinks = mutable.ArrayBuffer.empty[Drink]

                def isEmpty: Boolean = pizzas.isEmpty && drinks.isEmpty

                def isValid: Boolean = !isEmpty && findPizzaWithoutSize.isEmpty

                def add(ps: Seq[Pizza], ds: Seq[Drink]): Unit =
                    def setByName[T <: OrderPosition](buf: mutable.ArrayBuffer[T], t: T): Unit =
                            buf.find(_.name == t.name) match
                            case Some(foundT) => if t.qty.nonEmpty then foundT.qty = t.qty
                            case None => buf += t

                    for (p <- ps)
                        def setPizza(pred: Pizza => Boolean, notFound: => () => Unit): Unit =
                            pizzas.find(pred) match
                                case Some(foundPizza) =>
                                    if p.size.nonEmpty then foundPizza.size = p.size
                                    if p.qty.nonEmpty then foundPizza.qty = p.qty
                                case None => notFound()

                        if p.size.nonEmpty then setPizza(
                            x => x.name == p.name && x.size == p.size,
                            () => setPizza(x => x.name == p.name && x.size.isEmpty, () => pizzas += p)
                        )
                        else setByName(pizzas, p)

                    for (d <- ds) setByName(drinks, d)

                def findPizzaWithoutSize: Option[Pizza] = pizzas.find(_.size.isEmpty)

                def fixPizzaWithoutSize(size: String): Boolean =
                    findPizzaWithoutSize match
                        case Some(p) =>
                            p.size = size.?
                            true
                        case None => false

                def getState: PizzeriaOrderState = state

                def setState(state: PizzeriaOrderState): Unit = this.state = state

                override def toString: String =
                    if !isEmpty then
                        val ps = if pizzas.nonEmpty then s"pizza: ${pizzas.mkString(", ")}" else ""
                        val ds = if drinks.nonEmpty then s"drinks: ${drinks.mkString(", ")}" else ""

                        if ds.isEmpty then ps else if ps.isEmpty then ds else s"$ps, $ds"
                    else "nothing ordered"
        </pre>

        <ul>
            <li>
                <code>Line 6</code> defines order states enumeration.
            </li>
            <li>
                <code>Lines 17 and 20</code> define order parts classes definition.
            </li>
            <li>
                <code>Line 25</code> defines pizza order state representation.
            </li>
        </ul>

        <p>
            Open <code>src/main/scala/demo/<b>PizzeriaModel.scala</b></code> file and replace its content with the following code:
        </p>
        <pre class="brush: scala, highlight: [12, 27, 114, 115, 116, 126, 127, 135, 136, 143, 145, 147, 148, 158, 159, 168, 170, 173, 174, 187, 188, 201]">
            package demo

            import com.typesafe.scalalogging.LazyLogging
            import org.apache.nlpcraft.*
            import org.apache.nlpcraft.NCResultType.*
            import org.apache.nlpcraft.annotations.*
            import demo.{PizzeriaOrder as Order, PizzeriaOrderState as State}
            import demo.PizzeriaOrderState.*
            import demo.components.PizzeriaModelPipeline
            import org.apache.nlpcraft.nlp.*

            object PizzeriaExtractors:
                def extractPizzaSize(e: NCEntity): String = e[String]("ord:pizza:size:value")
                def extractQty(e: NCEntity, qty: String): Option[Int] =
                    Option.when(e.contains(qty))(e[String](qty).toDouble.toInt)
                def extractPizza(e: NCEntity): Pizza =
                    Pizza(
                        e[String]("ord:pizza:value"),
                        e.get[String]("ord:pizza:size"),
                        extractQty(e, "ord:pizza:qty")
                    )
                def extractDrink(e: NCEntity): Drink =
                    Drink(e[String]("ord:drink:value"), extractQty(e, "ord:drink:qty"))

            import PizzeriaExtractors.*

            object PizzeriaModel extends LazyLogging:
                type Result = (NCResult, State)
                private val UNEXPECTED_REQUEST =
                    new NCRejection("Unexpected request for current dialog context.")

                private def getCurrentOrder()(using ctx: NCContext): Order =
                    val sess = ctx.getConversation.getData
                    val usrId = ctx.getRequest.getUserId
                    sess.get[Order](usrId) match
                        case Some(ord) => ord
                        case None =>
                            val ord = new Order()
                            sess.put(usrId, ord)
                            ord

                private def mkResult(msg: String): NCResult = NCResult(msg, ASK_RESULT)
                private def mkDialog(msg: String): NCResult = NCResult(msg, ASK_DIALOG)

                private def doRequest(body: Order => Result)(using ctx: NCContext, im: NCIntentMatch): NCResult =
                    val o = getCurrentOrder()

                    logger.info(s"Intent '${im.getIntentId}' activated for text: '${ctx.getRequest.getText}'.")
                    logger.info(s"Before call [desc=${o.getState.toString}, resState: $o.")

                    val (res, resState) = body.apply(o)
                    o.setState(resState)

                    logger.info(s"After call [desc=$o, resState: $resState.")

                    res

                private def askIsReady(): Result = mkDialog("Is order ready?") -> DIALOG_IS_READY

                private def askSpecify(o: Order): Result =
                    require(!o.isValid)

                    o.findPizzaWithoutSize match
                        case Some(p) =>
                            mkDialog(s"Choose size (large, medium or small) for: '${p.name}'") -> DIALOG_SPECIFY
                        case None =>
                            require(o.isEmpty)
                            mkDialog("Please order something. Ask `menu` to look what you can order.") ->
                                DIALOG_SPECIFY

                private def askShouldStop(): Result =
                    mkDialog("Should current order be canceled?") ->
                        DIALOG_SHOULD_CANCEL

                private def doShowMenuResult(): NCResult =
                    mkResult(
                        "There are accessible for order: margherita, carbonara and marinara. " +
                        "Sizes: large, medium or small. " +
                        "Also there are tea, coffee and cola."
                    )

                private def doShowMenu(state: State): Result = doShowMenuResult() -> state

                private def doShowStatus(o: Order, state: State): Result =
                    mkResult(s"Current order state: $o.") -> state

                private def askConfirm(o: Order): Result =
                    require(o.isValid)
                    mkDialog(s"Let's specify your order: $o. Is it correct?") -> DIALOG_CONFIRM

                private def doResultWithClear(msg: String)(using ctx: NCContext, im: NCIntentMatch): Result =
                    val conv = ctx.getConversation
                    conv.getData.remove(ctx.getRequest.getUserId)
                    conv.clearStm(_ => true)
                    conv.clearDialog(_ => true)
                    mkResult(msg) -> DIALOG_EMPTY

                private def doStop(o: Order)(using ctx: NCContext, im: NCIntentMatch): Result =
                    doResultWithClear(
                        if !o.isEmpty then "Everything cancelled. Ask `menu` to look what you can order."
                        else "Nothing to cancel. Ask `menu` to look what you can order."
                    )

                private def doContinue(): Result = mkResult("OK, please continue.") -> DIALOG_EMPTY
                private def askConfirmOrAskSpecify(o: Order): Result =
                    if o.isValid then askConfirm(o) else askSpecify(o)
                private def askIsReadyOrAskSpecify(o: Order): Result =
                    if o.isValid then askIsReady() else askSpecify(o)
                private def askStopOrDoStop(o: Order)(using ctx: NCContext, im: NCIntentMatch): Result =
                    if o.isValid then askShouldStop() else doStop(o)

            import PizzeriaModel.*

            class PizzeriaModel extends NCModelAdapter(
                NCModelConfig("nlpcraft.pizzeria.ex", "Pizzeria Example Model", "1.0"),
                PizzeriaModelPipeline.PIPELINE
            ) with LazyLogging:
                // This method is defined in class scope and has package access level for tests reasons.
                private[demo] def doExecute(o: Order)(using ctx: NCContext, im: NCIntentMatch): Result =
                    require(o.isValid)
                    doResultWithClear(s"Executed: $o.")

                private def doExecuteOrAskSpecify(o: Order)(using ctx: NCContext, im: NCIntentMatch): Result =
                    if o.isValid then doExecute(o) else askSpecify(o)

                @NCIntent("intent=yes term(yes)={# == 'ord:yes'}")
                def onYes(using ctx: NCContext, im: NCIntentMatch): NCResult = doRequest(
                    o => o.getState match
                        case DIALOG_CONFIRM => doExecute(o)
                        case DIALOG_SHOULD_CANCEL => doStop(o)
                        case DIALOG_IS_READY => askConfirmOrAskSpecify(o)
                        case DIALOG_SPECIFY | DIALOG_EMPTY => throw UNEXPECTED_REQUEST
                )

                @NCIntent("intent=no term(no)={# == 'ord:no'}")
                def onNo(using ctx: NCContext, im: NCIntentMatch): NCResult = doRequest(
                    o => o.getState match
                        case DIALOG_CONFIRM | DIALOG_IS_READY => doContinue()
                        case DIALOG_SHOULD_CANCEL => askConfirmOrAskSpecify(o)
                        case DIALOG_SPECIFY | DIALOG_EMPTY => throw UNEXPECTED_REQUEST
                )

                @NCIntent("intent=stop term(stop)={# == 'ord:stop'}")
                // It doesn't depend on order validity and dialog state.
                def onStop(using ctx: NCContext, im: NCIntentMatch): NCResult = doRequest(askStopOrDoStop)

                @NCIntent("intent=status term(status)={# == 'ord:status'}")
                def onStatus(using ctx: NCContext, im: NCIntentMatch): NCResult = doRequest(
                    o => o.getState match
                        // Ignore `status`, confirm again.
                        case DIALOG_CONFIRM => askConfirm(o)
                        // Changes state.
                        case DIALOG_SHOULD_CANCEL => doShowStatus(o, DIALOG_EMPTY)
                         // Keeps same state.
                        case DIALOG_EMPTY | DIALOG_IS_READY | DIALOG_SPECIFY => doShowStatus(o, o.getState)
                )

                @NCIntent("intent=finish term(finish)={# == 'ord:finish'}")
                def onFinish(using ctx: NCContext, im: NCIntentMatch): NCResult = doRequest(
                    o => o.getState match
                        // Like YES if valid.
                        case DIALOG_CONFIRM => doExecuteOrAskSpecify(o)
                        // Ignore `finish`, specify again.
                        case DIALOG_SPECIFY => askSpecify(o)
                        case DIALOG_EMPTY | DIALOG_IS_READY | DIALOG_SHOULD_CANCEL => askConfirmOrAskSpecify(o)
                )

                @NCIntent("intent=menu term(menu)={# == 'ord:menu'}")
                // It doesn't depend and doesn't influence on order validity and dialog state.
                def onMenu(using ctx: NCContext, im: NCIntentMatch): NCResult =
                    doRequest(o => doShowMenu(o.getState))

                @NCIntent("intent=order term(ps)={# == 'ord:pizza'}* term(ds)={# == 'ord:drink'}*")
                def onOrder(
                    using ctx: NCContext,
                    im: NCIntentMatch,
                    @NCIntentTerm("ps") ps: List[NCEntity],
                    @NCIntentTerm("ds") ds: List[NCEntity]
                ): NCResult = doRequest(
                    o =>
                        require(ps.nonEmpty || ds.nonEmpty);
                        // It doesn't depend on order validity and dialog state.
                        o.add(ps.map(extractPizza), ds.map(extractDrink));
                        askIsReadyOrAskSpecify(o)
                )

                @NCIntent("intent=orderSpecify term(size)={# == 'ord:pizza:size'}")
                def onOrderSpecify(
                    using ctx: NCContext,
                    im: NCIntentMatch,
                    @NCIntentTerm("size") size: NCEntity
                ): NCResult =
                    doRequest(
                        // If order in progress and has pizza with unknown size, it doesn't depend on dialog state.
                        o =>
                            if !o.isEmpty && o.fixPizzaWithoutSize(extractPizzaSize(size))
                                then askIsReadyOrAskSpecify(o)
                                else throw UNEXPECTED_REQUEST
                    )

                override def onRejection(
                    using ctx: NCContext, im: Option[NCIntentMatch], e: NCRejection
                ): Option[NCResult] =
                    if im.isEmpty || getCurrentOrder().isEmpty then throw e
                    Option(doShowMenuResult())
        </pre>
        <p>
            There are a number of intents in the given model which allow to prepare, change, confirm and cancel pizza orders.
            Note that given test model works with only one single user.
            Let's review this implementation step by step:
        </p>
        <ul>
            <li>
                <code>Line 12</code> declares <code>PizzeriaExtractors</code> helper object which provides
                conversion methods from <a href="../apis/latest/org/apache/nlpcraft/NCEntity.html">NCEntity</a> objects and model data objects.
            </li>
            <li>
                <code>Line 27</code> defines <code>PizzeriaModel</code> companion object which contains
                static content and helper methods.
            </li>
            <li>
                On <code>line 114</code> our class <code>PizzeriaModel</code> extends <a href="../apis/latest/org/apache/nlpcraft/NCModelAdapter.html">NCModelAdapter</a> that allows us to pass
                prepared configuration and pipeline into the model.
            </li>
            <li>
                <code>Line 115</code> creates model configuration with most default parameters.
            </li>
            <li>
                <code>Line 116</code> passes pipeline parameter which was prepared in <code>PizzeriaModelPipeline</code>.
            </li>
            <li>
                <code>Lines 173 and 174</code> annotate intents <code>order</code> and its callback method <code>onOrder()</code>.
                Intent <code>order</code> requires lists of pizza and drinks for the order.
                Note that at least one of these lists shouldn't be empty, otherwise intent is not triggered.
                In its callback current order state is changed.
                If processed order is in valid state user receives order confirmation request like "<i>Is order ready?</i>",
                otherwise user receives request which asks him to specify the order.
                Both responses have <a href="../apis/latest/org/apache/nlpcraft/NCResultType.html#ASK_DIALOG-0">ASK_DIALOG</a> type.
            </li>

            <li>
                Order pizza sizes can be specified by the model as it was described above in <code>order</code> intent.
                <code>Lines 187 and 188</code> annotate intents <code>orderSpecify</code> and its callback method <code>onOrderSpecify()</code>.
                Intent <code>orderSpecify</code> requires pizza size value parameter.
                Callback checks that it was called just for suitable order state.
                Current order state is changed  and user receives order confirmation request like "<i>Is order ready?</i>" again.
            </li>
            <li>
                <code>Lines 126, 127 and 135, 136</code> annotate intents <code>yes</code> and <code>no</code>
                with related callbacks <code>onYes()</code> and <code>onNo()</code>.
                These intents are expected after user answered on received confirmation requests.
                Callbacks change order state, send another requests to user or reject these intents depending on current order state.
            </li>
            <li>
                <code>Lines 143 and 145, 147 and 148, 158 and 159, 168 and 170</code> annotate intents
                <code>stop</code>, <code>status</code>, <code>finish</code> and <code>menu</code> intents
                with related callbacks. They are order management commands, their actions are depend on current order state.
            </li>
            <li>
                <code>Line 201</code> annotates <code>onRejection</code> method
                which is called if there aren't any triggered intents.
            </li>
        </ul>

        <p>
            Open <code>src/main/scala/demo/components/<b>PizzeriaOrderValidator.scala</b></code> file and replace its content with the following code:
        </p>
        <pre class="brush: scala, highlight: []">
            package demo.components

            import org.apache.nlpcraft.*

            class PizzeriaOrderValidator extends NCEntityValidator:
                override def validate(req: NCRequest, cfg: NCModelConfig, ents: List[NCEntity]): Unit =
                    def count(id: String): Int = ents.count(_.getId == id)

                    val cntPizza = count("ord:pizza")
                    val cntDrink = count("ord:drink")
                    val cntNums = count("stanford:number")
                    val cntSize = count("ord:pizza:size")

                    // Single size - it is order specification request.
                    if cntSize != 1 && cntSize > cntPizza then
                        throw new NCRejection("There are unrecognized pizza sizes in the request, maybe because some misprints.")

                    if cntNums > cntPizza + cntDrink then
                        throw new NCRejection("There are many unrecognized numerics in the request, maybe because some misprints.")
        </pre>

        <p>
            <code>PizzeriaOrderValidator</code> is implementation of <a href="../apis/latest/org/apache/nlpcraft/NCEntityValidator.html">NCEntityValidator</a>.
            It is designed for validation order content that allows to reject invalid orders right away.
        <p>

        <p>
            Open <code>src/main/scala/demo/components/<b>PizzeriaOrderMapper.scala</b></code> file and replace its content with the following code:
        </p>
        <pre class="brush: scala, highlight: [11, 25, 30, 61]">
            package demo.components

            import org.apache.nlpcraft.*
            import com.typesafe.scalalogging.LazyLogging
            import org.apache.nlpcraft.NCResultType.ASK_DIALOG
            import scala.collection.*

            case class PizzeriaOrderMapperDesc(elementId: String, propertyName: String)

            object PizzeriaOrderMapper:
                extension(entity: NCEntity)
                    def position: Double =
                        val toks = entity.getTokens
                        (toks.head.getIndex + toks.last.getIndex) / 2.0
                    def tokens: List[NCToken] = entity.getTokens

                private def str(es: Iterable[NCEntity]): String =
                    es.map(e => s"id=${e.getId}(${e.tokens.map(_.getIndex).mkString("[", ",", "]")})").
                        mkString("{", ", ", "}")

                def apply(extra: PizzeriaOrderMapperDesc, dests: PizzeriaOrderMapperDesc*): PizzeriaOrderMapper =
                    new PizzeriaOrderMapper(extra, dests)

            import PizzeriaOrderMapper.*

            case class PizzeriaOrderMapper(
                extra: PizzeriaOrderMapperDesc,
                dests: Seq[PizzeriaOrderMapperDesc]
            ) extends NCEntityMapper with LazyLogging:
                override def map(req: NCRequest, cfg: NCModelConfig, ents: List[NCEntity]): List[NCEntity] =
                    def map(destEnt: NCEntity, destProp: String, extraEnt: NCEntity): NCEntity =
                        new NCPropertyMapAdapter with NCEntity:
                            destEnt.keysSet.foreach(k => put(k, destEnt(k)))
                            put[String](destProp, extraEnt[String](extra.propertyName).toLowerCase)
                            override val getTokens: List[NCToken] =
                                (destEnt.tokens ++ extraEnt.tokens).sortBy(_.getIndex)
                            override val getRequestId: String = req.getRequestId
                            override val getId: String = destEnt.getId

                    val destsMap = dests.map(p => p.elementId -> p).toMap
                    val destEnts = mutable.HashSet.empty ++ ents.filter(e => destsMap.contains(e.getId))
                    val extraEnts = ents.filter(_.getId == extra.elementId)

                    if destEnts.nonEmpty && extraEnts.nonEmpty && destEnts.size >= extraEnts.size then
                        val used = (destEnts ++ extraEnts).toSet
                        val dest2Extra = mutable.HashMap.empty[NCEntity, NCEntity]

                        for (extraEnt <- extraEnts)
                            val destEnt = destEnts.minBy(m => Math.abs(m.position - extraEnt.position))
                            destEnts -= destEnt
                            dest2Extra += destEnt -> extraEnt

                        val unrelated = ents.filter(e => !used.contains(e))
                        val artificial = for ((m, e) <- dest2Extra) yield map(m, destsMap(m.getId).propertyName, e)
                        val unused = destEnts

                        val res = (unrelated ++ artificial ++ unused).sortBy(_.tokens.head.getIndex)

                        logger.debug(s"Elements mapped [input=${str(ents)}, output=${str(res)}]")

                        res
                    else ents
        </pre>

        <p>
            <code>PizzeriaOrderMapper</code> is implementation of <a href="../apis/latest/org/apache/nlpcraft/NCEntityMapper.html">NCEntityMapper</a>.
            It is designed for complex compound entities building based on another entities.
        <p>
        <ul>
            <li>
                <code>Line 11</code> defines <code>PizzeriaOrderMapper</code> model companion object which contains
                helper methods.
            </li>
            <li>
                <code>Line 25</code> defines <code>PizzeriaOrderMapper</code> model which implements <a href="../apis/latest/org/apache/nlpcraft/NCEntityMapper.html">NCEntityMapper</a>.
            </li>
            <li>
                <code>Line 30</code> defines helper method
                <a href="../apis/latest/org/apache/nlpcraft/NCEntityMapper.html#map-fffff77c">map()</a> w
                hich clones <code>destEn</code> entity,
                extends it by <code>extraEnt</code> tokens and <code>destProp</code> property and, as result,
                returns new entities instances instead of passed into the method.
            </li>
            <li>
                <code>Line 61</code> defines <code>PizzeriaOrderMapper</code> result.
                These entities will be processed further instead of passed into this component method.
            </li>
        </ul>

        <p>
            Open <code>src/main/scala/demo/components/<b>PizzeriaModelPipeline.scala</b></code> file and replace its content with the following code:
        </p>
        <pre class="brush: scala, highlight: [14, 31, 37, 43]">
            package demo.components

            import edu.stanford.nlp.pipeline.StanfordCoreNLP
            import opennlp.tools.stemmer.PorterStemmer
            import org.apache.nlpcraft.nlp.parsers.*
            import org.apache.nlpcraft.nlp.entity.parser.stanford.NCStanfordNLPEntityParser
            import org.apache.nlpcraft.nlp.token.parser.stanford.NCStanfordNLPTokenParser
            import org.apache.nlpcraft.*
            import org.apache.nlpcraft.nlp.enrichers.NCEnStopWordsTokenEnricher
            import org.apache.nlpcraft.nlp.parsers.{NCSemanticEntityParser, NCSemanticStemmer}
            import java.util.Properties

            object PizzeriaModelPipeline:
                val PIPELINE: NCPipeline =
                    val stanford =
                        val props = new Properties()
                        props.setProperty("annotators", "tokenize, ssplit, pos, lemma, ner")
                        new StanfordCoreNLP(props)
                    val tokParser = new NCStanfordNLPTokenParser(stanford)
                    val stemmer = new NCSemanticStemmer():
                        private val ps = new PorterStemmer
                        override def stem(txt: String): String = ps.synchronized { ps.stem(txt) }

                    import PizzeriaOrderMapperDesc as D

                    new NCPipelineBuilder().
                        withTokenParser(tokParser).
                        withTokenEnricher(new NCEnStopWordsTokenEnricher()).
                        withEntityParser(new NCStanfordNLPEntityParser(stanford, Set("number"))).
                        withEntityParser(NCSemanticEntityParser(stemmer, tokParser, "pizzeria_model.yaml")).
                        withEntityMapper(
                            PizzeriaOrderMapper(
                                extra = D("ord:pizza:size", "ord:pizza:size:value"),
                                dests = D("ord:pizza", "ord:pizza:size")
                            )
                        ).
                        withEntityMapper(
                            PizzeriaOrderMapper(
                                extra = D("stanford:number", "stanford:number:nne"),
                                dests = D("ord:pizza", "ord:pizza:qty"), D("ord:drink", "ord:drink:qty")
                            )
                        ).
                        withEntityValidator(new PizzeriaOrderValidator()).
                        build
        </pre>
        <p>
            There is model pipeline preparing place.
        <p>
        <ul>
            <li>
                <code>Line 14</code> defines the pipeline.
            </li>
            <li>
                <code>Line 30</code> declares <a href="../apis/latest/org/apache/nlpcraft/nlp/parsers/NCSemanticEntityParser.html">NCSemanticEntityParser</a>
                which is based on YAM model definition <code>pizzeria_model.yaml</code>.
            </li>
            <li>
                <code>Lines 31 and 37</code> define entity mappers <code>PizzeriaOrderMapper</code> instances which
                map <code>ord:pizza</code> elements with theirs sizes from <code>ord:pizza:size</code> and
                quantities from <code>stanford:number</code>.
            </li>
            <li>
                <code>Line 43</code> defines <code>PizzeriaOrderValidator</code> class described above.
            </li>
        </ul>

    </section>

    <section id="testing">
        <h2 class="section-title">Testing <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2>
        <p>
            The test defined in <code>PizzeriaModelSpec</code> allows to check that all input test sentences are
            processed correctly and trigger the expected intents:
        </p>
        <pre class="brush: scala, highlight: [14, 48, 61, 96]">
            package demo

            import org.apache.nlpcraft.*
            import org.apache.nlpcraft.NCResultType.*
            import demo.PizzeriaModel.Result
            import demo.PizzeriaOrderState.*
            import org.scalatest.BeforeAndAfter
            import org.scalatest.funsuite.AnyFunSuite

            import scala.language.implicitConversions
            import scala.util.Using
            import scala.collection.mutable

            object PizzeriaModelSpec:
                type Request = (String, NCResultType)
                private class ModelTestWrapper extends PizzeriaModel:
                    private var o: PizzeriaOrder = _

                    override def doExecute(o: PizzeriaOrder)(using ctx: NCContext, im: NCIntentMatch): Result =
                        val res = super.doExecute(o)
                        this.o = o
                        res

                    def getLastExecutedOrder: PizzeriaOrder = o
                    def clearLastExecutedOrder(): Unit = o = null

                private class Builder:
                    private val o = new PizzeriaOrder
                    o.setState(DIALOG_EMPTY)
                    def withPizza(name: String, size: String, qty: Int): Builder =
                        o.add(Seq(Pizza(name, Some(size), Some(qty))), Seq.empty)
                        this
                    def withDrink(name: String, qty: Int): Builder =
                        o.add(Seq.empty, Seq(Drink(name, Some(qty))))
                        this
                    def build: PizzeriaOrder = o

            import PizzeriaModelSpec.*

            class PizzeriaModelSpec extends AnyFunSuite with BeforeAndAfter:
                private val mdl = new ModelTestWrapper()
                private val client = new NCModelClient(mdl)
                private val msgs = mutable.ArrayBuffer.empty[mutable.ArrayBuffer[String]]
                private val errs = mutable.HashMap.empty[Int, Throwable]

                private var testNum: Int = 0

                after {
                    if client != null then client.close()

                    for ((seq, num) <- msgs.zipWithIndex)
                        println("#" * 150)
                        for (line <- seq) println(line)
                        errs.get(num) match
                            case Some(err) => err.printStackTrace()
                            case None => // No-op.

                    require(errs.isEmpty, s"There are ${errs.size} errors above.")
                }

                private def dialog(exp: PizzeriaOrder, reqs: Request*): Unit =
                    val testMsgs = mutable.ArrayBuffer.empty[String]
                    msgs += testMsgs

                    testMsgs += s"Test: $testNum"

                    for (((txt, expType), idx) <- reqs.zipWithIndex)
                        try
                            mdl.clearLastExecutedOrder()
                            val resp = client.ask(txt, "userId")

                            testMsgs += s">> Request: $txt"
                            testMsgs += s">> Response: '${resp.getType}': ${resp.getBody}"

                            if expType != resp.getType then
                                errs += testNum -> new Exception(s"Unexpected result type [num=$testNum, txt=$txt, expected=$expType, type=${resp.getType}]")

                            // Check execution result on last request.
                            if idx == reqs.size - 1 then
                                val lastOrder = mdl.getLastExecutedOrder
                                def s(o: PizzeriaOrder) = if o == null then null else s"Order [state=${o.getState}, desc=$o]"
                                val s1 = s(exp)
                                val s2 = s(lastOrder)
                                if s1 != s2 then
                                    errs += testNum ->
                                        new Exception(
                                            s"Unexpected result [num=$testNum, txt=$txt]" +
                                            s"\nExpected: $s1" +
                                            s"\nReal    : $s2"
                                        )
                        catch
                            case e: Exception => errs += testNum -> new Exception(s"Error during test [num=$testNum]", e)

                    testNum += 1

                test("test") {
                    given Conversion[String, Request] with
                        def apply(txt: String): Request = (txt, ASK_DIALOG)

                    dialog(
                        new Builder().withDrink("tea", 2).build,
                        "Two tea",
                        "yes",
                        "yes" -> ASK_RESULT
                    )

                    dialog(
                        new Builder().
                            withPizza("carbonara", "large", 1).
                            withPizza("marinara", "small", 1).
                            withDrink("tea", 1).
                            build,
                        "I want to order carbonara, marinara and tea",
                        "large size please",
                        "smallest",
                        "yes",
                        "correct" -> ASK_RESULT
                    )

                    dialog(
                        new Builder().withPizza("carbonara", "small", 2).build,
                        "carbonara two small",
                        "yes",
                        "yes" -> ASK_RESULT
                    )

                    dialog(
                        new Builder().withPizza("carbonara", "small", 1).build,
                        "carbonara",
                        "small",
                        "yes",
                        "yes" -> ASK_RESULT
                    )

                    dialog(
                        null,
                        "marinara",
                        "stop" -> ASK_RESULT
                    )

                    dialog(
                        new Builder().
                            withPizza("carbonara", "small", 2).
                            withPizza("marinara", "large", 4).
                            withDrink("cola", 3).
                            withDrink("tea", 1).
                            build,
                        "3 cola",
                        "one tea",
                        "carbonara 2",
                        "small",
                        "4 marinara big size",
                        "menu" -> ASK_RESULT,
                        "done",
                        "yes" -> ASK_RESULT
                    )

                    dialog(
                        new Builder().
                            withPizza("margherita", "small", 2).
                            withPizza("marinara", "small", 1).
                            withDrink("tea", 3).
                            build,
                        "margherita two, marinara and three tea",
                        "small",
                        "small",
                        "yes",
                        "yes" -> ASK_RESULT
                    )

                    dialog(
                        new Builder().
                            withPizza("margherita", "small", 2).
                            withPizza("marinara", "large", 1).
                            withDrink("cola", 3).
                            build,
                        "small margherita two, marinara big one and three cola",
                        "yes",
                        "yes" -> ASK_RESULT
                    )

                    dialog(
                        new Builder().
                            withPizza("margherita", "small", 1).
                            withPizza("marinara", "large", 2).
                            withDrink("coffee", 2).
                            build,
                        "small margherita, 2 marinara and 2 coffee",
                        "large",
                        "yes",
                        "yes" -> ASK_RESULT
                    )
                }
        </pre>

        <p>
            <code>PizzeriaModelSpec</code> is complex test which is designed as dialog with pizza ordering bot.
        </p>

        <ul>
            <li>
                <code>Line 14</code> declares <code>PizzeriaModelSpec</code> test companion object which contains
                static content and helper methods.
            </li>
            <li>
                <code>Line 48</code> defines <code>after</code> block.
                It closes model client and prints test results.
            </li>
            <li>
                <code>Line 61</code> defines test helper method <code>dialog()</code>.
                It sends request to model via client's method
                <a href="../apis/latest/org/apache/nlpcraft/NCModelClient.html#ask-fffff9ce">ask()</a>
                and accumulates execution results.
            </li>
            <li>
                <code>Line 96</code> defines main test block.
                It contains user request descriptions and their expected results taking into account order state.
            </li>
        </ul>
        <p>
            You can run this test via SBT task <code>executeTests</code> or using IDE.
        </p>
        <pre class="brush: scala, highlight: []">
            PS C:\apache\incubator-nlpcraft-examples\pizzeria> sbt executeTests
        </pre>
    </section>
    <section>
        <h2 class="section-title">Done! 👌 <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2>
        <p>
            You've created pizza model and tested it.
        </p>
    </section>
</div>
<div class="col-md-2 third-column">
    <ul class="side-nav">
        <li class="side-nav-title">On This Page</li>
        <li><a href="#overview">Overview</a></li>
        <li><a href="#new_project">New Project</a></li>
        <li><a href="#model">Data Model</a></li>
        <li><a href="#code">Model Class</a></li>
        <li><a href="#testing">Testing</a></li>
        {% include quick-links.html %}
    </ul>
</div>






