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

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


The following commit(s) were added to refs/heads/NLPCRAFT-70_NEW by this push:
     new 41bf61a  WIP.
41bf61a is described below

commit 41bf61afa3f1cf935006b4c7a2af27ebebda2b25
Author: Sergey Kamov <[email protected]>
AuthorDate: Tue Jul 20 19:17:13 2021 +0300

    WIP.
---
 .../probe/mgrs/conn/NCConnectionManager.scala      |   2 +
 .../probe/mgrs/deploy/NCDeployManager.scala        |  31 ++--
 .../nlpcraft/model/ctxword/lightswitch_model2.yaml |  96 +++++++++++
 .../{ => org/apache/nlpcraft/model}/samples.txt    |   0
 .../apache/nlpcraft/model/NCIntentSampleSpec.scala |   3 +-
 .../model/ctxword/NCContextWordSpec3Samples.scala  | 190 ---------------------
 .../ctxword/NCLightSwitchScalaModel2Spec.scala     | 188 ++++++++++++++++++++
 7 files changed, 298 insertions(+), 212 deletions(-)

diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/conn/NCConnectionManager.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/conn/NCConnectionManager.scala
index b56b724..cdcb7a4 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/conn/NCConnectionManager.scala
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/conn/NCConnectionManager.scala
@@ -246,6 +246,8 @@ object NCConnectionManager extends NCService {
                                                         
p.getSynonyms.asScala.filter(p => !p.contains(" ")).asJava
                                                     )
 
+                                                set.add(p.getName)
+
                                                 set
                                             }).toMap.asJava
                                     ).toMap
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala
index a4b4681..beaa447 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala
@@ -432,32 +432,21 @@ object NCDeployManager extends NCService {
         ).toMap
 
         if (ctxCatElems.nonEmpty) {
-            val singleValsElems: Map[String, Int] =
-                elems.flatMap(e => {
-                    val cnt =
-                        if (e.getValues != null)
-                            e.getValues.asScala.map(
-                                p => if (p.getSynonyms != null) 
p.getSynonyms.asScala.count(!_.contains(" ")) else 0
-                            ).sum
-                        else
-                            0
-                    if (cnt != 0) Some(e.getId -> cnt) else None
-                }).toMap
-
-
-            var ids = ctxCatElems.filter { case (elemId, _) => 
!singleValsElems.keySet.contains(elemId) }.keys
-
-            if (ids.nonEmpty)
-                // TODO:
-                throw new NCE(s"Model doesn't contain values elements with 
following identifiers: ${ids.mkString(", ")}")
-
-            ids = ctxCatElems.filter { case (_, conf) => conf < 0 || conf > 1  
}.keys
+            val ids = ctxCatElems.filter { case (_, conf) => conf < 0 || conf 
> 1  }.keys
 
             if (ids.nonEmpty)
                 // TODO:
                 throw new NCE(s"Context word confidences are out of range 
(0..1) for elements : ${ids.mkString(", ")}")
 
-            val cnt = singleValsElems.values.sum
+            val cnt =
+                elems.map(e =>
+                    if (e.getValues != null)
+                        e.getValues.asScala.map(
+                            p => if (p.getSynonyms != null) 
p.getSynonyms.asScala.count(!_.contains(" ")) else 0
+                        ).sum + 1 // 1 for value name.
+                    else
+                        0
+                ).sum
 
             if (cnt > MAX_CTXWORD_VALS_CNT)
                 // TODO: do we need print recommended value.?
diff --git 
a/nlpcraft/src/test/resources/org/apache/nlpcraft/model/ctxword/lightswitch_model2.yaml
 
b/nlpcraft/src/test/resources/org/apache/nlpcraft/model/ctxword/lightswitch_model2.yaml
new file mode 100644
index 0000000..f15442c
--- /dev/null
+++ 
b/nlpcraft/src/test/resources/org/apache/nlpcraft/model/ctxword/lightswitch_model2.yaml
@@ -0,0 +1,96 @@
+#
+# 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.
+#
+
+id: "nlpcraft.lightswitch.ex2"
+name: "Light Switch Example Model 2"
+version: "1.0"
+description: "NLI-powered light switch example model 2."
+macros:
+  - name: "<ACTION>"
+    macro: "{turn|switch|dial|let|set|get|put}"
+  - name: "<KILL>"
+    macro: "{shut|kill|stop|eliminate}"
+enabledBuiltInTokens: [] # This example doesn't use any built-in tokens.
+permutateSynonyms: true
+abstractTokens:
+  - "ls:part:place"
+  - "ls:part:floor"
+  - "ls:part:placeType"
+  - "ls:part:light"
+sparse: true
+elements:
+  - id: "ls:part:place"
+    description: "Abstract element. Used for top level element `ls:loc`"
+    # TODO: Value is not so big because this category is vague enough.
+    categoryConfidence: 0.4
+    values:
+      - name: "room"
+      - name: "closet"
+      - name: "kitchen"
+      - name: "bedroom"
+      - name: "washroom"
+      - name: "garage"
+
+  # For simplifying example, concrete floor type can be recognized by these 
synonyms words.
+  - id: "ls:part:placeFloor"
+    description: "Abstract element. Used for top level element `ls:loc`"
+    synonyms:
+       - 
"{upstairs|downstairs|{1st|first|2nd|second|3rd|third|4th|5th|top|ground} 
floor|_}"
+
+  # For simplifying example, concrete place type can be recognized by these 
synonyms words.
+  - id: "ls:part:placeType"
+    description: "Abstract element. Used for top level element `ls:loc`"
+    synonyms:
+      - "{dinning|laundry|play|master|kid|children|child|guest}"
+
+  - id: "ls:part:light"
+    description: "Abstract element. Used for top level elements `ls:on` and 
`ls:of`"
+    synonyms:
+      - "{light|illumination|lamp|lamplight}"
+
+  - id: "ls:loc"
+    description: "Top level element. Used in intents.`"
+    synonyms:
+      # Parts can be extracted from `ls:loc` to specify certain location point.
+      # Part `ls:part:place` is mandatory.
+      # Parts `ls:part:placeFloor` and `ls:part:placeType` are optional.
+      - "{^^{tok_id() == 'ls:part:placeFloor'}^^|_} ^^{tok_id() == 
'ls:part:place'}^^ {^^{tok_id() == 'ls:part:placeType'}^^|_}"
+      - "{^^{tok_id() == 'ls:part:placeFloor'}^^|_} {^^{tok_id() == 
'ls:part:placeType'}^^|_} ^^{tok_id() == 'ls:part:place'}^^"
+
+  - id: "ls:on"
+    groups:
+      - "act"
+    description: "Light switch ON action.`"
+    synonyms:
+      # It's parts help to catch this element, after they can be ignored.
+      - "<ACTION> {on|up|_} ^^{tok_id() == 'ls:part:light'}^^ {on|up|_}"
+      - "^^{tok_id() == 'ls:part:light'}^^ {on|up}"
+
+  - id: "ls:off"
+    groups:
+      - "act"
+    description: "Light switch OFF action.`"
+    synonyms:
+      # It's parts help to catch this element, after they can be ignored.
+      - "<ACTION> ^^{tok_id() == 'ls:part:light'}^^ {off|out}"
+      - "{<ACTION>|<KILL>} {off|out} ^^{tok_id() == 'ls:part:light'}^^"
+      - "<KILL> ^^{tok_id() == 'ls:part:light'}^^"
+      - "^^{tok_id() == 'ls:part:light'}^^ <KILL>"
+      - "no ^^{tok_id() == 'ls:part:light'}^^"
+
+intents:
+  - "intent=ls term(act)={has(tok_groups(), 'act')} term(loc)={tok_id() == 
'ls:loc'}"
\ No newline at end of file
diff --git a/nlpcraft/src/test/resources/samples.txt 
b/nlpcraft/src/test/resources/org/apache/nlpcraft/model/samples.txt
similarity index 100%
rename from nlpcraft/src/test/resources/samples.txt
rename to nlpcraft/src/test/resources/org/apache/nlpcraft/model/samples.txt
diff --git 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/NCIntentSampleSpec.scala 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/NCIntentSampleSpec.scala
index 5e14b07..0272477 100644
--- a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/NCIntentSampleSpec.scala
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/NCIntentSampleSpec.scala
@@ -39,7 +39,8 @@ class NCIntentSampleSpecModel extends NCModelAdapter(
     @NCIntentSample(Array("unknown", "unknown"))
     private def onX1(ctx: NCIntentMatch): NCResult = "OK"
 
-    @NCIntentSampleRef("samples.txt")
+    // Look at resources folder.
+    @NCIntentSampleRef("org/apache/nlpcraft/model/samples.txt")
     @NCIntent("intent=intent2 term~{tok_id()=='x2'}")
     private def onX2(ctx: NCIntentMatch): NCResult = "OK"
 }
diff --git 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/ctxword/NCContextWordSpec3Samples.scala
 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/ctxword/NCContextWordSpec3Samples.scala
deleted file mode 100644
index 38ceb79..0000000
--- 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/ctxword/NCContextWordSpec3Samples.scala
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * 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
- *
- *      https://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.
- */
-
-package org.apache.nlpcraft.model.ctxword
-
-import org.apache.nlpcraft.{NCTestContext, NCTestEnvironment}
-import org.apache.nlpcraft.model.tools.test.NCTestAutoModelValidator
-import org.apache.nlpcraft.model.{NCElement, NCIntent, NCIntentSample, 
NCIntentTerm, NCModel, NCResult, NCToken, NCValue}
-import org.junit.jupiter.api.{Assertions, Test}
-
-import java.util.{Collections, Optional}
-import java.{lang, util}
-import scala.jdk.CollectionConverters.{MapHasAsJava, SeqHasAsJava, 
SetHasAsJava}
-
-object NCContextWordSpecModel3 {
-    private def mkElement(id: String, group: Option[String], syns: String*): 
NCElement =
-        new NCElement {
-            override def getId: String = id
-            override def getSynonyms: util.List[String] = syns.asJava
-            override def getGroups: util.List[String] =
-                group match {
-                    case Some(g) => Collections.singletonList(g)
-                    case None => super.getGroups
-                }
-        }
-    private def mkValuesElement(id: String, conf: Double, valSyns: String*): 
NCElement =
-        new NCElement {
-            override def getId: String = id
-            override def getCategoryConfidence: Optional[lang.Double] = 
Optional.of(conf)
-            override def getValues: util.List[NCValue] = valSyns.map(p => new 
NCValue {
-                override def getName: String = p
-                override def getSynonyms: util.List[String] = 
Collections.singletonList(p)
-            }).asJava
-        }
-}
-
-import NCContextWordSpecModel3._
-
-/**
-  * Test model.
-  */
-class NCContextWordSpecModel3 extends NCModel {
-    override def getId: String = this.getClass.getSimpleName
-    override def getName: String = this.getClass.getSimpleName
-    override def getVersion: String = "1.0.0"
-    override def isPermutateSynonyms: Boolean = true
-    override def isSparse: Boolean = true
-
-    override def getMacros: util.Map[String, String] =
-        Map(
-            "<ACTION>" -> "{turn|switch|dial|let|set|get|put}",
-            "<KILL>" -> "{shut|kill|stop|eliminate}",
-            "<ENTIRE_OPT>" -> "{entire|full|whole|total|_}"
-        ).asJava
-
-    override def getAbstractTokens: util.Set[String] = Set("ls:part:place", 
"ls:part:floor", "ls:part:placeType", "ls:part:light").asJava
-
-    override def getElements: util.Set[NCElement] =
-        Set(
-            // Abstract element. Used for top level element `ls:loc`. Note, 
that this element is defined via context word categories.
-            mkValuesElement(
-                id = "ls:part:place",
-                conf = 0.7,
-                valSyns = "room", "closet", "attic", "loft", "kitchen", 
"library", "closet", "garage", "office", "playroom", "bedroom", "washroom"
-            ),
-            // Abstract element. Used for top level element `ls:loc`.
-            mkElement(
-                id =  "ls:part:floor",
-                group = None,
-                syns = "{house|home|building|_} 
{upstairs|downstairs|{1st|2nd|3rd|4th|5th|top|ground} floor|_}"
-            ),
-            // Abstract element. Used for top level element `ls:loc`.
-            mkElement(
-                id =  "ls:part:placeType",
-                group = None,
-                syns = 
"{dinning|laundry|play|master|kid|children|child|guest|_}"
-            ),
-            // Abstract element. Used for top level elements `ls:on` and 
`ls:of`.
-            mkElement(
-                id =  "ls:part:light",
-                group = None,
-                syns = "{all|_} {light|illumination|lamp|lamplight|it|them}"
-            ),
-
-            // Top level element. Used in intents.
-            // Part `ls:part:place` is mandatory.
-            // Parts `ls:part:floor` and `ls:part:placeType` are optional.
-            // Parts can be extracted from `ls:loc` to specify certain 
location point.
-            mkElement(
-                id =  "ls:loc",
-                group = None,
-                syns =
-                    "<ENTIRE_OPT> ^^{tok_id() == 'ls:part:floor'}^^? 
^^{tok_id() == 'ls:part:place'}^^ ^^{tok_id() == 'ls:part:placeType'}^^?",
-                    "<ENTIRE_OPT> ^^{tok_id() == 'ls:part:floor'}^^? 
^^{tok_id() == 'ls:part:placeType'}^^? ^^{tok_id() == 'ls:part:place'}^^",
-            ),
-            // Top level element. Used in intents. It's parts help to catch 
this element, after they can be ignored.
-            mkElement(
-                id = "ls:on",
-                group = Some("act"),
-                syns =
-                    "<ACTION> {on|up|_} ^^{tok_id() == 'ls:part:light'}^^ 
{on|up|_}",
-                    "^^{tok_id() == 'ls:part:light'}^^ {on|up}"
-            ),
-            // Top level element. Used in intents. It's parts help to catch 
this element, after they can be ignored.
-            mkElement(
-                id = "ls:off",
-                group = Some("act"),
-                syns =
-                    "<ACTION> ^^{tok_id() == 'ls:part:light'}^^ {off|out}",
-                    "{<ACTION>|<KILL>} {off|out} ^^{tok_id() == 
'ls:part:light'}^^",
-                    "<KILL> ^^{tok_id() == 'ls:part:light'}^^",
-                    "^^{tok_id() == 'ls:part:light'}^^ <KILL>",
-                    "no ^^{tok_id() == 'ls:part:light'}^^"
-            )
-        ).asJava
-
-    @NCIntent("intent=ls term(act)={has(tok_groups(), 'act')} 
term(loc)={tok_id() == 'ls:loc'}*")
-    @NCIntentSample(Array(
-        "Turn the lights off in the entire house.",
-        "Turn off all lights now",
-        "Switch on the illumination in the master bedroom closet.",
-        "Get the lights on.",
-        "Lights up in the kitchen.",
-        "Please, put the light out in the upstairs bedroom.",
-        "Set the lights on in the entire house.",
-        "Turn the lights off in the guest bedroom.",
-        "Could you please switch off all the lights?",
-        "Dial off illumination on the 2nd floor.",
-        "Please, no lights!",
-        "Kill off all the lights now!",
-        "No lights in the bedroom, please.",
-        "Light up the garage, please!",
-        "Kill the illumination now!"
-    ))
-    def onMatch(
-        @NCIntentTerm("act") actTok: NCToken,
-        @NCIntentTerm("loc") locToks: List[NCToken]
-    ): NCResult = {
-        val status = if (actTok.getId == "ls:on") "on" else "off"
-        val locations =
-            if (locToks.isEmpty)
-                "entire house"
-            else
-                
locToks.map(_.meta[String]("nlpcraft:nlp:origtext")).mkString(", ")
-
-        // By default - just return a descriptive action string.
-        NCResult.text(s"Lights are [$status] in [${locations.toLowerCase}].")
-    }
-}
-
-/**
-  * Verifies samples set.
-  */
-class NCContextWordSpec3Samples {
-    @Test
-    private[ctxword] def testSamples(): Unit = {
-        System.setProperty("NLPCRAFT_TEST_MODELS", 
classOf[NCContextWordSpecModel3].getName)
-
-        Assertions.assertTrue(NCTestAutoModelValidator.isValid(),"See error 
logs above.")
-    }
-}
-
-/**
-  *  Extra values set.
-  */
-@NCTestEnvironment(model = classOf[NCContextWordSpecModel3], startClient = 
true)
-class NCContextWordSpec3Extra extends NCTestContext {
-    @Test
-    private[ctxword] def testValues(): Unit = {
-        // Look at `ls:type3` element definition.
-        // `bedroom` is defined, but 'bathroom' and 'hallway' are not
-        // (detected as `ls:type3` by context word category enricher.)
-        checkIntent("Switch on the illumination in the master bathroom 
closet.", "ls")
-        checkIntent("Switch on the illumination in the master hallway 
closet.", "ls")
-    }
-}
\ No newline at end of file
diff --git 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/ctxword/NCLightSwitchScalaModel2Spec.scala
 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/ctxword/NCLightSwitchScalaModel2Spec.scala
new file mode 100644
index 0000000..3948a73
--- /dev/null
+++ 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/ctxword/NCLightSwitchScalaModel2Spec.scala
@@ -0,0 +1,188 @@
+/*
+ * 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
+ *
+ *      https://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.
+ */
+
+package org.apache.nlpcraft.model.ctxword
+
+import com.fasterxml.jackson.databind.ObjectMapper
+import com.fasterxml.jackson.module.scala.DefaultScalaModule
+import org.apache.nlpcraft.model.tools.test.NCTestAutoModelValidator
+import org.apache.nlpcraft.model.{NCIntentRef, NCIntentSample, NCIntentTerm, 
NCModelFileAdapter, NCResult, NCToken}
+import org.apache.nlpcraft.{NCTestContext, NCTestEnvironment}
+import org.junit.jupiter.api.Assertions.{assertEquals, assertTrue}
+import org.junit.jupiter.api.{Assertions, Test}
+
+import scala.jdk.CollectionConverters.ListHasAsScala
+
+object NCContextWordSpecModel3Data {
+    final val MAPPER = new ObjectMapper()
+
+    MAPPER.registerModule(DefaultScalaModule)
+}
+
+case class NCContextWordSpecModel3Data(
+    action: String,
+    place: String,
+    placeType: Option[String] = None,
+    placeFloor: Option[String] = None
+)
+
+import org.apache.nlpcraft.model.ctxword.NCContextWordSpecModel3Data._
+
+/**
+  * Test model.
+  */
+class NCLightSwitchScalaModel2 extends 
NCModelFileAdapter("org/apache/nlpcraft/model/ctxword/lightswitch_model2.yaml") 
{
+    @NCIntentRef("ls")
+    @NCIntentSample(Array(
+        "Turn the lights off in the room.",
+        "Set the lights on in in the room.",
+        "Lights up in the kitchen.",
+        "Please, put the light out in the upstairs bedroom.",
+        "Turn the lights off in the guest bedroom.",
+        "No lights in the first floor guest washroom, please.",
+        "Light up the garage, please!",
+        "Kill the illumination now second floor kid closet!"
+    ))
+    def onMatch(@NCIntentTerm("act") actTok: NCToken, @NCIntentTerm("loc") 
locTok: NCToken): NCResult = {
+        def getPart(id: String): Option[String] = 
locTok.getPartTokens.asScala.find(_.getId == id) match {
+            case Some(t) => Some(t.getOriginalText.toLowerCase)
+            case None => None
+        }
+
+        NCResult.json(
+            MAPPER.writeValueAsString(
+                NCContextWordSpecModel3Data(
+                    action = if (actTok.getId == "ls:on") "on" else "off",
+                    place = getPart("ls:part:place").get,
+                    placeType = getPart("ls:part:placeType"),
+                    placeFloor = getPart("ls:part:placeFloor")
+                )
+            )
+        )
+    }
+}
+
+/**
+  * Verifies samples set.
+  */
+class NCLightSwitchScalaModel2SpecSamples {
+    @Test
+    private[ctxword] def testSamplesStandard(): Unit = {
+        System.setProperty("NLPCRAFT_TEST_MODELS", 
classOf[NCLightSwitchScalaModel2].getName)
+
+        Assertions.assertTrue(NCTestAutoModelValidator.isValid(),"See error 
logs above.")
+    }
+}
+
+/**
+  *  Extra values set.
+  */
+@NCTestEnvironment(model = classOf[NCLightSwitchScalaModel2], startClient = 
true)
+class NCLightSwitchScalaModel2Spec extends NCTestContext {
+    import org.apache.nlpcraft.model.ctxword.{NCContextWordSpecModel3Data => R}
+
+    private def test0(txt: String, expected: NCContextWordSpecModel3Data): 
Unit = {
+        val res = getClient.ask(txt)
+
+        assertTrue(res.isOk, s"Checked: $txt")
+        assertTrue(res.getResult.isPresent, s"Checked: $txt")
+
+        val actual = MAPPER.readValue(res.getResult.get(), 
classOf[NCContextWordSpecModel3Data])
+
+        assertEquals(expected, actual, s"Expected: $expected, actual: $actual")
+    }
+
+    @Test
+    def testSamplesDetailed(): Unit = {
+        test0(
+            "Turn the lights off in the room.",
+            R(action = "off", place = "room")
+        )
+        test0(
+            "Set the lights on in in the room.",
+            R(action = "on", place = "room")
+        )
+        test0(
+            "Lights up in the kitchen.",
+            R(action = "on", place = "kitchen")
+        )
+        test0(
+            "Please, put the light out in the upstairs bedroom.",
+            R(action = "off", place = "bedroom", placeFloor = Some("upstairs"))
+        )
+        test0(
+            "Turn the lights off in the guest bedroom.",
+            R(action = "off", place = "bedroom", placeType = Some("guest"))
+        )
+        test0(
+            "No lights in the first floor guest washroom, please.",
+            R(action = "off", place = "washroom", placeType = Some("guest"), 
placeFloor = Some("first floor"))
+        )
+        test0(
+            "Light up the garage, please!",
+            R(action = "on", place = "garage")
+        )
+        test0(
+            "Kill the illumination now second floor kid closet!",
+            R(action = "off", place = "closet",  placeType = Some("kid"), 
placeFloor = Some("second floor"))
+        )
+    }
+
+    @Test
+    def testSynonymsSameCategory(): Unit = {
+        // Word `loft` is not defined as place.
+        test0(
+            "Turn the lights off in the loft.",
+            R(action = "off", place = "loft")
+        )
+        // Word `loft` is not defined as place.
+        test0(
+            "Set the lights on in in the loft.",
+            R(action = "on", place = "loft")
+        )
+        // Word `office` is not defined as place.
+        test0(
+            "Lights up in the office.",
+            R(action = "on", place = "office")
+        )
+        // Word `library` is not defined as place.
+        test0(
+            "Please, put the light out in the upstairs library.",
+            R(action = "off", place = "library", placeFloor = Some("upstairs"))
+        )
+        // Word `office` is not defined as place.
+        test0(
+            "Turn the lights off in the guest office.",
+            R(action = "off", place = "office", placeType = Some("guest"))
+        )
+        // Word `chamber` is not defined as place.
+        test0(
+            "No lights in the first floor guest chamber, please.",
+            R(action = "off", place = "chamber", placeType = Some("guest"), 
placeFloor = Some("first floor"))
+        )
+        // Word `office` is not defined as place.
+        test0(
+            "Light up the office, please!",
+            R(action = "on", place = "office")
+        )
+        // Word `chamber` is not defined as place.
+        test0(
+            "Kill the illumination now second floor kid chamber!",
+            R(action = "off", place = "chamber",  placeType = Some("kid"), 
placeFloor = Some("second floor"))
+        )
+    }
+}
\ No newline at end of file

Reply via email to