This is an automated email from the ASF dual-hosted git repository.
sergeykamov pushed a commit to branch NLPCRAFT-387
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git
The following commit(s) were added to refs/heads/NLPCRAFT-387 by this push:
new 9735f10 Fuzzy numerics logic implemented. Minor tests fixes.
9735f10 is described below
commit 9735f10621ddc59246cedafb812be46bd452a303
Author: Sergey Kamov <[email protected]>
AuthorDate: Mon Aug 2 17:05:43 2021 +0300
Fuzzy numerics logic implemented. Minor tests fixes.
---
.../nlpcraft/examples/alarm/NCAlarmModelSpec.scala | 60 +++++++++++++++++++++
.../common/nlp/numeric/NCFuzzyNumericsConfig.scala | 62 ++++++++++++++++++++++
.../nlpcraft/common/nlp/numeric/NCNumeric.scala | 41 ++++++++++++++
3 files changed, 163 insertions(+)
diff --git
a/nlpcraft-examples/alarm/src/test/java/org/apache/nlpcraft/examples/alarm/NCAlarmModelSpec.scala
b/nlpcraft-examples/alarm/src/test/java/org/apache/nlpcraft/examples/alarm/NCAlarmModelSpec.scala
new file mode 100644
index 0000000..dd74617
--- /dev/null
+++
b/nlpcraft-examples/alarm/src/test/java/org/apache/nlpcraft/examples/alarm/NCAlarmModelSpec.scala
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+package org.apache.nlpcraft.examples.alarm
+
+import org.apache.nlpcraft.examples.alarm.AlarmModel.calculateTime
+import org.apache.nlpcraft.model.{NCIntentRef, NCIntentTerm, NCResult, NCToken}
+import org.apache.nlpcraft.{NCTestContext, NCTestEnvironment}
+import org.junit.jupiter.api.Test
+
+import java.time.LocalDateTime
+import java.time.temporal.ChronoUnit.MILLIS
+import scala.jdk.CollectionConverters.SeqHasAsJava
+
+class AlarmModelWrapper extends AlarmModel {
+ @NCIntentRef("alarm")
+ def onMatch(@NCIntentTerm("nums") numToks: List[NCToken]): NCResult =
+ NCResult.text(String.valueOf(calculateTime(numToks.asJava)))
+}
+
+@NCTestEnvironment(model = classOf[AlarmModelWrapper], startClient = true)
+class NCAlarmModelSpec extends NCTestContext {
+ // Checks with 10 seconds precision. Enough to be sure that calculation
result is correct.
+ private def check(req: String, expectedTime: Long): Unit =
+ checkResult(req, _.toLong, (calcTime: Long) => Math.abs(expectedTime -
calcTime) <= 10000)
+
+ @Test
+ def test(): Unit = {
+ val now = LocalDateTime.now
+
+ def mkPeriod(hours: Int, mins: Int): Long =
now.until(now.plusHours(hours).plusMinutes(mins), MILLIS)
+
+ // Fuzzy.
+ check("Buzz me in few minutes.", mkPeriod(0, 5))
+ check("Buzz me in an hour.", mkPeriod(1, 0))
+
+ // Complex periods.
+ check("Buzz me in an hour and 15mins", mkPeriod(1, 15))
+ check("Buzz me in one hour and 15mins", mkPeriod(1, 15))
+ check("Buzz me in 1 hour and 15mins", mkPeriod(1, 15))
+ check("Buzz me in 1h and 15mins", mkPeriod(1, 15))
+
+ check("Buzz me in one day, 1h and 15mins", mkPeriod(25, 15))
+ check("Buzz me in a day, 1h and 15mins", mkPeriod(25, 15))
+ }
+}
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/nlp/numeric/NCFuzzyNumericsConfig.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/nlp/numeric/NCFuzzyNumericsConfig.scala
new file mode 100644
index 0000000..745b9d1
--- /dev/null
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/nlp/numeric/NCFuzzyNumericsConfig.scala
@@ -0,0 +1,62 @@
+/*
+ * 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.common.nlp.numeric
+
+import org.apache.nlpcraft.common.makro.NCMacroParser
+
+case class NCFuzzyNumericPeriod(unit: NCNumericUnit, value: Int)
+
+/**
+ * Fuzzy numeric configuration.
+ */
+object NCFuzzyNumericsConfig {
+ val NUMS: Map[String, NCFuzzyNumericPeriod] = {
+ val parser = new NCMacroParser
+
+ def make(txt: String, unit: NCNumericUnit, value: Int): Seq[(String,
NCFuzzyNumericPeriod)] =
+ parser.expand(txt).map(_ -> NCFuzzyNumericPeriod(unit, value))
+
+ import org.apache.nlpcraft.common.nlp.numeric.{NCNumericUnit => U}
+
+ // Datetime 1.
+ val singleDt =
+ Map(
+ "in {a|an} second" -> U("second", "datetime"),
+ "in {a|an} hour" -> U("hour", "datetime"),
+ "in {a|an} minute" -> U("minute", "datetime"),
+ "in {a|an} day" -> U("day", "datetime"),
+ "in {a|an} week" -> U("week", "datetime"),
+ "in {a|an} month" -> U("month", "datetime"),
+ "in {a|an} year" -> U("year", "datetime")
+ ).flatMap { case (txt, u) => make(txt, u, 1) }
+
+ // Datetime 2.
+ val fewDt =
+ Map(
+ "in {a|an|_} few seconds" -> U("second", "datetime"),
+ "in {a|an|_} few minutes" -> U("minute", "datetime"),
+ "in {a|an|_} few hours" -> U("hour", "datetime"),
+ "in {a|an|_} few days" -> U("day", "datetime"),
+ "in {a|an|_} few weeks" -> U("week", "datetime"),
+ "in {a|an|_} few months" -> U("month", "datetime"),
+ "in {a|an|_} few years" -> U("year", "datetime")
+ ).flatMap { case (txt, u) => make(txt, u, 5) }
+
+ singleDt ++ fewDt
+ }
+}
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/nlp/numeric/NCNumeric.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/nlp/numeric/NCNumeric.scala
new file mode 100644
index 0000000..75a3365
--- /dev/null
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/nlp/numeric/NCNumeric.scala
@@ -0,0 +1,41 @@
+/*
+ * 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.common.nlp.numeric
+
+import org.apache.nlpcraft.common.nlp.NCNlpSentenceToken
+
+/**
+ *
+ * @param name
+ * @param unitType
+ */
+case class NCNumericUnit(name: String, unitType: String)
+
+/**
+ *
+ * @param tokens
+ * @param value
+ * @param isFractional
+ * @param unit
+ */
+case class NCNumeric(
+ tokens: Seq[NCNlpSentenceToken],
+ value: Double,
+ isFractional: Boolean,
+ unit: Option[NCNumericUnit]
+)