You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nlpcraft.apache.org by se...@apache.org on 2021/12/09 10:34:48 UTC

[incubator-nlpcraft] branch master_test created (now 2e0298d)

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

sergeykamov pushed a change to branch master_test
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git.


      at 2e0298d  WIP.

This branch includes the following new commits:

     new 2e0298d  WIP.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[incubator-nlpcraft] 01/01: WIP.

Posted by se...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 2e0298dfd3f8c0e1f441da428a0de8140d055a0d
Author: Sergey Kamov <sk...@gmail.com>
AuthorDate: Thu Dec 9 13:34:11 2021 +0300

    WIP.
---
 .../scala/org/apache/nlpcraft/NCModelClient.java   |   8 +-
 .../org/apache/nlpcraft/NCModelConfigAdapter.java  |  43 +++++--
 .../enrichers/entity/NCFileUserEntityParser.scala} |  50 ++------
 .../enrichers/entity/NCUserEntityParser.scala}     |  52 ++------
 .../opennlp/NCOpenNlpDateEntityParser.scala}       |  45 +------
 .../opennlp/NCOpenNlpLocationEntityParser.scala}   |  45 +------
 .../opennlp/NCOpenNlpMoneyEntityParser.scala}      |  45 +------
 .../NCOpenNlpOrganizationEntityParser.scala}       |  45 +------
 .../opennlp/NCOpenNlpPercentageEntityParser.scala} |  45 +------
 .../opennlp/NCOpenNlpPersonEntityParser.scala}     |  45 +------
 .../opennlp/NCOpenNlpTimeEntityParser.scala}       |  45 +------
 .../token/NCEnDictionaryTokenEnricher.scala}       |  45 +------
 .../enrichers/token/NCEnQuotesTokenEnricher.scala} |  45 +------
 .../token/NCEnSwearWordsTokenEnricher.scala}       |  45 +------
 .../tokenizers/NCEnTokenParser.scala}              |  45 +------
 .../apache/nlpcraft/alarm/LightSwitchModel.java    |  73 +++++++++++
 .../nlpcraft/alarm/LightSwitchModelTest.java       | 137 +++++++++++++++++++++
 .../nlpcraft/alarm/LightSwitchModelTest2.java      |  75 +++++++++++
 nlpcraft/src/test/resources/lightswitch_model.json |  67 ++++++++++
 nlpcraft/src/test/resources/lightswitch_model.yaml |  28 +++++
 20 files changed, 497 insertions(+), 531 deletions(-)

diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelClient.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelClient.java
index 83b73ec..ba96d60 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelClient.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelClient.java
@@ -42,7 +42,7 @@ public class NCModelClient {
      * @return
      * @throws NCException
      */
-    CompletableFuture<NCResult> ask(String txt, Map<String, Object> data, String usrId) {
+    public CompletableFuture<NCResult> ask(String txt, Map<String, Object> data, String usrId) {
         return null; // TODO
     }
 
@@ -54,7 +54,7 @@ public class NCModelClient {
      * @return
      * @throws NCException
      */
-    NCResult askSync(String txt, Map<String, Object> data, String usrId) {
+    public NCResult askSync(String txt, Map<String, Object> data, String usrId) {
         return null; // TODO
     }
 
@@ -63,7 +63,7 @@ public class NCModelClient {
      * @param usrId
      * @throws NCException
      */
-    void clearConversation(String usrId) {
+    public void clearConversation(String usrId) {
         // TODO
     }
 
@@ -72,7 +72,7 @@ public class NCModelClient {
      * @param usrId
      * @throws NCException
      */
-    void clearDialog(String usrId) {
+    public void clearDialog(String usrId) {
         // TODO
     }
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
index e9d3b2f..8ca392c 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
@@ -22,39 +22,68 @@ import java.util.*;
 /**
  *
  */
+// TODO: validation for constructor and all setters.
 public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
+    private final String id;
+    private final String name;
+    private final String version;
+    private final NCTokenParser tokParser;
+
+    private List<NCTokenEnricher> tokenEnrichers;
+    private List<NCEntityEnricher> entityEnrichers;
+    private List<NCEntityParser> entityParsers;
+
+    public NCModelConfigAdapter(String id, String name, String version, NCTokenParser tokParser) {
+        this.id = id;
+        this.name = name;
+        this.version = version;
+        this.tokParser = tokParser;
+    }
+
     @Override
     public String getId() {
-        return null; // TODO
+        return id;
     }
 
     @Override
     public String getName() {
-        return null; // TODO
+        return name;
     }
 
     @Override
     public String getVersion() {
-        return null; // TODO
+        return version;
     }
 
     @Override
     public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
+        return tokenEnrichers;
     }
 
     @Override
     public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
+        return entityEnrichers;
     }
 
     @Override
     public NCTokenParser getTokenParser() {
-        return null; // TODO
+        return tokParser;
     }
 
     @Override
     public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
+        return entityParsers;
+    }
+
+    public void setTokenEnrichers(List<NCTokenEnricher> tokenEnrichers) {
+        this.tokenEnrichers = tokenEnrichers;
+    }
+
+    public void setEntityEnrichers(List<NCEntityEnricher> entityEnrichers) {
+        this.entityEnrichers = entityEnrichers;
+    }
+
+    public void setEntityParsers(List<NCEntityParser> entityParsers) {
+        this.entityParsers = entityParsers;
     }
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/NCFileUserEntityParser.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/NCFileUserEntityParser.scala
index e9d3b2f..2c44e25 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/NCFileUserEntityParser.scala
@@ -14,47 +14,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.entity
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.*
 
-import java.util.*;
+import java.io.File
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+// File with 3 sections: Look at NCUserEntityParser
+// Element ID / Map element properties (parent, group, etc)
+// Macros ID / Macros body.
+// Element ID / Synonyms list, based on words and macros.
+class NCFileUserEntityParser(file: File) extends NCEntityParser {
+    override def parse(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/NCUserEntityParser.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/NCUserEntityParser.scala
index e9d3b2f..a362366 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/NCUserEntityParser.scala
@@ -14,47 +14,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.entity
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.*
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCUserEntityParser(
+    // Element ID / Map element properties (parent, group, etc)
+    elementsDesc: util.Map[String, util.Map[String, String]],
+    // Macros ID / Macros body.
+    macros: util.Map[String, String],
+    // Element ID / Synonyms list, based on words and macros.
+    synonyms: util.Map[String, util.List[String]]
+) extends NCEntityParser {
+    override def parse(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpDateEntityParser.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpDateEntityParser.scala
index e9d3b2f..5bb1d87 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpDateEntityParser.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.entity.opennlp
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.{NCEntity, NCEntityParser, NCModelConfig, NCRequest, NCToken}
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCOpenNlpDateEntityParser extends NCEntityParser {
+    override def parse(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpLocationEntityParser.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpLocationEntityParser.scala
index e9d3b2f..efd9471 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpLocationEntityParser.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.entity.opennlp
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.*
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCOpenNlpLocationEntityParser extends NCEntityParser {
+    override def parse(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpMoneyEntityParser.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpMoneyEntityParser.scala
index e9d3b2f..18378e0 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpMoneyEntityParser.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.entity.opennlp
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.*
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCOpenNlpMoneyEntityParser extends NCEntityParser {
+    override def parse(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpOrganizationEntityParser.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpOrganizationEntityParser.scala
index e9d3b2f..560eb88 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpOrganizationEntityParser.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.entity.opennlp
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.*
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCOpenNlpOrganizationEntityParser extends NCEntityParser {
+    override def parse(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpPercentageEntityParser.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpPercentageEntityParser.scala
index e9d3b2f..ecc1bd6 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpPercentageEntityParser.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.entity.opennlp
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.*
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCOpenNlpPercentageEntityParser extends NCEntityParser {
+    override def parse(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpPersonEntityParser.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpPersonEntityParser.scala
index e9d3b2f..2b4e2ef 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpPersonEntityParser.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.entity.opennlp
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.*
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCOpenNlpPersonEntityParser extends NCEntityParser {
+    override def parse(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpTimeEntityParser.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpTimeEntityParser.scala
index e9d3b2f..e71870b 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpTimeEntityParser.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.entity.opennlp
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.*
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCOpenNlpTimeEntityParser extends NCEntityParser {
+    override def parse(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/token/NCEnDictionaryTokenEnricher.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/token/NCEnDictionaryTokenEnricher.scala
index e9d3b2f..53849a5 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/token/NCEnDictionaryTokenEnricher.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.token
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.{NCModelConfig, NCRequest, NCToken, NCTokenEnricher}
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCEnDictionaryTokenEnricher extends NCTokenEnricher {
+    override def enrich(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): Unit = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/token/NCEnQuotesTokenEnricher.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/token/NCEnQuotesTokenEnricher.scala
index e9d3b2f..671de22 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/token/NCEnQuotesTokenEnricher.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.token
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.{NCModelConfig, NCRequest, NCToken, NCTokenEnricher}
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCEnQuotesTokenEnricher extends NCTokenEnricher {
+    override def enrich(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): Unit = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/token/NCEnSwearWordsTokenEnricher.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/token/NCEnSwearWordsTokenEnricher.scala
index e9d3b2f..834d6fb 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/token/NCEnSwearWordsTokenEnricher.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.token
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.{NCModelConfig, NCRequest, NCToken, NCTokenEnricher}
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCEnSwearWordsTokenEnricher extends NCTokenEnricher {
+    override def enrich(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): Unit = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/tokenizers/NCEnTokenParser.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/tokenizers/NCEnTokenParser.scala
index e9d3b2f..cc840a7 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/tokenizers/NCEnTokenParser.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.tokenizers
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.{NCRequest, NCToken, NCTokenParser}
 
-import java.util.*;
+import java.util;
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCEnTokenParser extends NCTokenParser {
+    override def parse(req: NCRequest): util.List[NCToken] = ???
 }
diff --git a/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModel.java b/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModel.java
new file mode 100644
index 0000000..632bc52
--- /dev/null
+++ b/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModel.java
@@ -0,0 +1,73 @@
+/*
+ * 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.alarm;
+
+import org.apache.nlpcraft.NCModelAdapter;
+import org.apache.nlpcraft.*;
+import org.apache.nlpcraft.NCModelConfig;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class LightSwitchModel extends NCModelAdapter {
+    public LightSwitchModel(NCModelConfig cfg) {
+        super(cfg);
+    }
+
+    // TODO: groups ?
+    @NCIntent("intent=ls term(act)={has(tok_groups, 'act')} term(loc)={# == 'ls:loc'}*")
+    @NCIntentSample({
+        "Turn the lights off in the entire house.",
+        "Turn off all lights now",
+        "Switch on the illumination in the master bedroom closet.",
+        "Off the lights on the 1st floor",
+        "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.",
+        "Turn down lights in 1st floor bedroom",
+        "Lights on at second floor kitchen",
+        "Please, no lights!",
+        "Kill off all the lights now!",
+        "Down the lights in the garage",
+        "Lights down in the kitchen!",
+        "Turn up the illumination in garage and master bedroom",
+        "Turn down all the light now!",
+        "No lights in the bedroom, please.",
+        "Light up the garage, please!",
+        "Kill the illumination now!"
+    })
+    NCResult onMatch(
+        @NCIntentTerm("act") NCEntity actTok,
+        @NCIntentTerm("loc") List<NCEntity> locToks) {
+        String status = actTok.getId().equals("ls:on") ? "on" : "off";
+        String locations = locToks.isEmpty() ?
+            "entire house" :
+            locToks.stream().
+                map(p -> p.getTokens().stream().map(x -> x.getOriginalText()).collect(Collectors.joining(" "))).
+                collect(Collectors.joining(", "));
+
+        return new NCResult(
+            "Lights are [" + status + "] in [" + locations.toLowerCase() + "].",
+            NCResultType.ASK_RESULT
+        );
+    }
+}
diff --git a/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModelTest.java b/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModelTest.java
new file mode 100644
index 0000000..92a18ac
--- /dev/null
+++ b/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModelTest.java
@@ -0,0 +1,137 @@
+/*
+ * 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.alarm;
+
+import org.apache.nlpcraft.NCModelClient;
+import org.apache.nlpcraft.NCModelConfigAdapter;
+import org.apache.nlpcraft.NCResult;
+import org.apache.nlpcraft.impl.enrichers.entity.NCFileUserEntityParser;
+import org.apache.nlpcraft.impl.enrichers.entity.NCUserEntityParser;
+import org.apache.nlpcraft.impl.tokenizers.NCEnTokenParser;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.apache.nlpcraft.NCModelConfig;
+import org.apache.nlpcraft.NCEntityParser;
+
+
+import static java.util.Arrays.asList;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class LightSwitchModelTest {
+    @Test
+    public void test() {
+        NCModelClient client = new NCModelClient(new LightSwitchModel(mkConfigManual()));
+
+        Assertions.assertNotNull(client.askSync("Hi!", null, null).getBody());
+    }
+
+    private static NCModelConfigAdapter mkConfigAdapter(NCEntityParser entityParser) {
+        NCModelConfigAdapter cfg =
+            new NCModelConfigAdapter(
+                "nlpcraft.lightswitch.ex",
+                "Light Switch Example Model",
+                "1.0",
+                new NCEnTokenParser()
+            );
+
+        // Order is important.
+//        cfg.setTokenEnrichers(
+//            asList(
+//                new NCEnDictionaryTokenEnricher(),
+//                new NCEnQuotesTokenEnricher(),
+//                new NCEnSwearWordsTokenEnricher()
+//            )
+//        )
+
+        cfg.setEntityParsers(asList(entityParser));
+
+//        // Don't need any entity enrichers.
+//        cfg.setEntityEnrichers(null)
+        return cfg;
+    }
+
+
+    private static NCModelConfigAdapter mkConfigManual() {
+        Map<String, Map<String, String>> elements = new HashMap<>() {{
+            put(
+                "ls:loc",
+                Collections.emptyMap()
+            );
+
+            put("ls:on",
+                new HashMap<>() {{
+                    put("group", "act");
+                }}
+            );
+
+            put("ls:off",
+                new HashMap<>() {{
+                    put("group", "act");
+                }}
+            );
+        }};
+
+        Map<String, String> macros = new HashMap<>() {{
+            put("<ACTION>", "{turn|switch|dial|let|set|get|put}");
+            put("<KILL>", "{shut|kill|stop|eliminate}");
+            put("<ENTIRE_OPT>", "{entire|full|whole|total|_}");
+            put("<FLOOR_OPT>", "{upstairs|downstairs|{1st|first|2nd|second|3rd|third|4th|fourth|5th|fifth|top|ground} floor|_}");
+            put("<TYPE>", "{room|closet|attic|loft|{store|storage} {room|_}}");
+            put("<LIGHT>", "{all|_} {it|them|light|illumination|lamp|lamplight}");
+        }};
+
+        Map<String, List<String>> synonyms = new HashMap<>() {{
+            put(
+                "ls:loc",
+                asList(
+                    "<ENTIRE_OPT> <FLOOR_OPT> {kitchen|library|closet|garage|office|playroom|{dinning|laundry|play} <TYPE>}",
+                    "<ENTIRE_OPT> <FLOOR_OPT> {master|kid|children|child|guest|_} {bedroom|bathroom|washroom|storage} {<TYPE>|_}",
+                    "<ENTIRE_OPT> {house|home|building|{1st|first} floor|{2nd|second} floor}"
+                )
+            );
+
+            put(
+                "ls:on",
+                asList(
+                    "<ACTION> {on|up|_} <LIGHT> {on|up|_}",
+                    "<LIGHT> {on|up}"
+                )
+            );
+
+            put(
+                "ls:off",
+                asList(
+                    "<ACTION> <LIGHT> {off|out|down}",
+                    "{<ACTION>|<KILL>} {off|out|down} <LIGHT>",
+                    "<KILL> <LIGHT>",
+                    "<LIGHT> <KILL>",
+                    "{out|no|off|down} <LIGHT>",
+                    "<LIGHT> {out|off|down}"
+                )
+            );
+
+        }};
+
+        return mkConfigAdapter(new NCUserEntityParser(elements, macros, synonyms));
+    }
+}
diff --git a/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModelTest2.java b/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModelTest2.java
new file mode 100644
index 0000000..47e3ba2
--- /dev/null
+++ b/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModelTest2.java
@@ -0,0 +1,75 @@
+/*
+ * 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.alarm;
+
+import org.apache.nlpcraft.NCEntityParser;
+import org.apache.nlpcraft.NCModelClient;
+import org.apache.nlpcraft.NCModelConfig;
+import org.apache.nlpcraft.NCModelConfigAdapter;
+import org.apache.nlpcraft.impl.enrichers.entity.NCFileUserEntityParser;
+import org.apache.nlpcraft.impl.enrichers.entity.NCUserEntityParser;
+import org.apache.nlpcraft.impl.tokenizers.NCEnTokenParser;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static java.util.Arrays.asList;
+
+public class LightSwitchModelTest2 {
+    @Test
+    public void test() {
+        NCModelClient client = new NCModelClient(new LightSwitchModel(mkConfigFile(new File("lightswitch.json"))));
+
+        Assertions.assertNotNull(client.askSync("Hi!", null, null).getBody());
+    }
+
+    private static NCModelConfigAdapter mkConfigAdapter(NCEntityParser entityParser) {
+        NCModelConfigAdapter cfg =
+            new NCModelConfigAdapter(
+                "nlpcraft.lightswitch.ex",
+                "Light Switch Example Model",
+                "1.0",
+                new NCEnTokenParser()
+            );
+
+        // Order is important.
+//        cfg.setTokenEnrichers(
+//            asList(
+//                new NCEnDictionaryTokenEnricher(),
+//                new NCEnQuotesTokenEnricher(),
+//                new NCEnSwearWordsTokenEnricher()
+//            )
+//        )
+
+        cfg.setEntityParsers(asList(entityParser));
+
+//        // Don't need any entity enrichers.
+//        cfg.setEntityEnrichers(null)
+        return cfg;
+    }
+
+
+    private static NCModelConfig mkConfigFile(File f) {
+        return mkConfigAdapter(new NCFileUserEntityParser(f));
+    }
+}
diff --git a/nlpcraft/src/test/resources/lightswitch_model.json b/nlpcraft/src/test/resources/lightswitch_model.json
new file mode 100644
index 0000000..f2b7b57
--- /dev/null
+++ b/nlpcraft/src/test/resources/lightswitch_model.json
@@ -0,0 +1,67 @@
+{
+  "elements": [
+    {
+      "ls:loc": [
+      ]
+    },
+    {
+      "ls:on": [
+        {
+          "group": "act"
+        }
+      ]
+    },
+    {
+      "ls:off": [
+        {
+          "group": "act"
+        }
+      ]
+    }
+  ],
+  "macros": [
+    {
+      "<ACTION>": "{turn|switch|dial|let|set|get|put}"
+    },
+    {
+      "<KILL>": "{shut|kill|stop|eliminate}"
+    },
+    {
+      "<ENTIRE_OPT>": "{entire|full|whole|total|_}"
+    },
+    {
+      "<FLOOR_OPT>": "{upstairs|downstairs|{1st|first|2nd|second|3rd|third|4th|fourth|5th|fifth|top|ground} floor|_}"
+    },
+    {
+      "<TYPE>": "{room|closet|attic|loft|{store|storage} {room|_}}"
+    },
+    {
+      "<LIGHT>": "{all|_} {it|them|light|illumination|lamp|lamplight}"
+    }
+  ],
+  "synonyms": [
+    {
+      "ls:loc": [
+        "<ENTIRE_OPT> <FLOOR_OPT> {kitchen|library|closet|garage|office|playroom|{dinning|laundry|play} <TYPE>}",
+        "<ENTIRE_OPT> <FLOOR_OPT> {master|kid|children|child|guest|_} {bedroom|bathroom|washroom|storage} {<TYPE>|_}",
+        "<ENTIRE_OPT> {house|home|building|{1st|first} floor|{2nd|second} floor}"
+      ]
+    },
+    {
+      "ls:on": [
+        "<ACTION> {on|up|_} <LIGHT> {on|up|_}",
+        "<LIGHT> {on|up}"
+      ]
+    },
+    {
+      "ls:off": [
+        "<ACTION> <LIGHT> {off|out|down}",
+        "{<ACTION>|<KILL>} {off|out|down} <LIGHT>",
+        "<KILL> <LIGHT>",
+        "<LIGHT> <KILL>",
+        "{out|no|off|down} <LIGHT>",
+        "<LIGHT> {out|off|down}"
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/nlpcraft/src/test/resources/lightswitch_model.yaml b/nlpcraft/src/test/resources/lightswitch_model.yaml
new file mode 100644
index 0000000..802197c
--- /dev/null
+++ b/nlpcraft/src/test/resources/lightswitch_model.yaml
@@ -0,0 +1,28 @@
+elements:
+  - "ls:loc": []
+  - "ls:on":
+      - "group": "act"
+  - "ls:off":
+      - "group": "act"
+macros:
+  - "<ACTION>": "{turn|switch|dial|let|set|get|put}"
+  - "<KILL>": "{shut|kill|stop|eliminate}"
+  - "<ENTIRE_OPT>": "{entire|full|whole|total|_}"
+  - "<FLOOR_OPT>": "{upstairs|downstairs|{1st|first|2nd|second|3rd|third|4th|fourth|5th|fifth|top|ground} floor|_}"
+  - "<TYPE>": "{room|closet|attic|loft|{store|storage} {room|_}}"
+  - "<LIGHT>": "{all|_} {it|them|light|illumination|lamp|lamplight}"
+synonyms:
+  - "ls:loc":
+      - "<ENTIRE_OPT> <FLOOR_OPT> {kitchen|library|closet|garage|office|playroom|{dinning|laundry|play} <TYPE>}",
+      - "<ENTIRE_OPT> <FLOOR_OPT> {master|kid|children|child|guest|_} {bedroom|bathroom|washroom|storage} {<TYPE>|_}",
+      - "<ENTIRE_OPT> {house|home|building|{1st|first} floor|{2nd|second} floor}"
+  - "ls:on":
+      - "<ACTION> {on|up|_} <LIGHT> {on|up|_}"
+      - "<LIGHT> {on|up}"
+  - "ls:off":
+      - "<ACTION> <LIGHT> {off|out|down}"
+      - "{<ACTION>|<KILL>} {off|out|down} <LIGHT>"
+      - "<KILL> <LIGHT>"
+      - "<LIGHT> <KILL>"
+      - "{out|no|off|down} <LIGHT>"
+      - "<LIGHT> {out|off|down}"