blob: 8abc6a555b7a61954304d6a08ab401804c388bb4 [file] [log] [blame]
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]--><head>
<meta charset='utf-8'/><meta http-equiv='X-UA-Compatible' content='IE=edge'/><meta name='viewport' content='width=device-width, initial-scale=1'/><meta name='keywords' content='groovy, natural language processing, nlp, nlpcraft'/><meta name='description' content='This blog looks at using Apache NLPCraft from Groovy.'/><title>The Apache Groovy programming language - Blogs - Converting natural language into actions with NLPCraft and Groovy</title><link href='../img/favicon.ico' type='image/x-ico' rel='icon'/><link rel='stylesheet' type='text/css' href='../css/bootstrap.css'/><link rel='stylesheet' type='text/css' href='../css/font-awesome.min.css'/><link rel='stylesheet' type='text/css' href='../css/style.css'/><link rel='stylesheet' type='text/css' href='https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.css'/>
</head><body>
<div id='fork-me'>
<a href='https://github.com/apache/groovy'>
<img style='position: fixed; top: 20px; right: -58px; border: 0; z-index: 100; transform: rotate(45deg);' src='/img/horizontal-github-ribbon.png'/>
</a>
</div><div id='st-container' class='st-container st-effect-9'>
<nav class='st-menu st-effect-9' id='menu-12'>
<h2 class='icon icon-lab'>Socialize</h2><ul>
<li>
<a href='http://groovy-lang.org/mailing-lists.html' class='icon'><span class='fa fa-envelope'></span> Discuss on the mailing-list</a>
</li><li>
<a href='https://twitter.com/ApacheGroovy' class='icon'><span class='fa fa-twitter'></span> Groovy on Twitter</a>
</li><li>
<a href='http://groovy-lang.org/events.html' class='icon'><span class='fa fa-calendar'></span> Events and conferences</a>
</li><li>
<a href='https://github.com/apache/groovy' class='icon'><span class='fa fa-github'></span> Source code on GitHub</a>
</li><li>
<a href='http://groovy-lang.org/reporting-issues.html' class='icon'><span class='fa fa-bug'></span> Report issues in Jira</a>
</li><li>
<a href='http://stackoverflow.com/questions/tagged/groovy' class='icon'><span class='fa fa-stack-overflow'></span> Stack Overflow questions</a>
</li><li>
<a href='http://groovycommunity.com/' class='icon'><span class='fa fa-slack'></span> Slack Community</a>
</li>
</ul>
</nav><div class='st-pusher'>
<div class='st-content'>
<div class='st-content-inner'>
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]--><div><div class='navbar navbar-default navbar-static-top' role='navigation'>
<div class='container'>
<div class='navbar-header'>
<button type='button' class='navbar-toggle' data-toggle='collapse' data-target='.navbar-collapse'>
<span class='sr-only'></span><span class='icon-bar'></span><span class='icon-bar'></span><span class='icon-bar'></span>
</button><a class='navbar-brand' href='../index.html'>
<i class='fa fa-star'></i> Apache Groovy
</a>
</div><div class='navbar-collapse collapse'>
<ul class='nav navbar-nav navbar-right'>
<li class=''><a href='http://groovy-lang.org/learn.html'>Learn</a></li><li class=''><a href='http://groovy-lang.org/documentation.html'>Documentation</a></li><li class=''><a href='/download.html'>Download</a></li><li class=''><a href='http://groovy-lang.org/support.html'>Support</a></li><li class=''><a href='/'>Contribute</a></li><li class=''><a href='http://groovy-lang.org/ecosystem.html'>Ecosystem</a></li><li class=''><a href='/blogs'>Blog posts</a></li><li class=''><a href='https://groovy.apache.org/events.html'></a></li><li>
<a data-effect='st-effect-9' class='st-trigger' href='#'>Socialize</a>
</li><li class=''>
<a href='../search.html'>
<i class='fa fa-search'></i>
</a>
</li>
</ul>
</div>
</div>
</div><div id='content' class='page-1'><div class='row'><div class='row-fluid'><div class='col-lg-3'><ul class='nav-sidebar'><li><a href='./'>Blog index</a></li><li class='active'><a href='#doc'>Converting natural language into actions with NLPCraft and Groovy</a></li><li><a href='#_controlling_house_light_switches' class='anchor-link'>Controlling house light switches</a></li><li><a href='#_asking_for_the_time' class='anchor-link'>Asking for the time</a></li><li><a href='#_further_information' class='anchor-link'>Further information</a></li></ul><br/><ul class='nav-sidebar'><li style='padding: 0.35em 0.625em; background-color: #eee'><span>Related posts</span></li><li><a href='./natural-language-processing-with-groovy'>Natural Language Processing with Groovy, OpenNLP, CoreNLP, Nlp4j, Datumbox, Smile, Spark NLP, DJL and TensorFlow</a></li></ul></div><div class='col-lg-8 col-lg-pull-0'><a name='doc'></a><h1>Converting natural language into actions with NLPCraft and Groovy</h1><p><span>Author: <i>Paul King</i></span><br/><span>Published: 2023-03-10 07:22PM (Last updated: 2023-03-13 01:32PM)</span></p><hr/><div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>This blog looks at using
<a href="https://nlpcraft.apache.org/index.html">Apache NLPCraft</a>
with Groovy.</p>
</div>
<div class="paragraph">
<p>Apache NLPCraft (incubating) is a library for converting
natural language into actions.
It is designed around an advanced Intent Definition Language (IDL) for
defining natural language <em>intents</em> and a fully deterministic intent
matching algorithm.</p>
</div>
<div class="paragraph">
<p>The
<a href="https://github.com/paulk-asert/groovy-data-science">groovy-data-science</a>
GitHub repo has an example using the previous 0.9.0 version of Apache NLPCraft.
The earlier version supported Java, Scala2, Kotlin and Groovy.
The
<a href="https://github.com/paulk-asert/groovy-data-science/blob/master/subprojects/LanguageProcessingNLPCraft/src/main/groovy/Lights.groovy">example</a> in the
<a href="https://github.com/paulk-asert/groovy-data-science/blob/master/subprojects/LanguageProcessingNLPCraft/">LanguageProcessingNLPCraft</a> project showed how
to interact with models in all 4 of those languages.</p>
</div>
<div class="paragraph">
<p>The project recently announced the release of version
<a href="https://nlpcraft.apache.org/relnotes/release-notes-1.0.0.html">1.0.0</a>
which represents a deep refactoring over 18 months.
The new version offers many enhancements and supports Scala3 for its models.
If you are going to be using NLPCraft extensively, then Scala3
is probably your best choice as programming language. Having said that,
since we are on the JVM, certain integration steps aren&#8217;t too hard.
We&#8217;ll show using Groovy as the client language.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_controlling_house_light_switches">Controlling house light switches</h2>
<div class="sectionbody">
<div class="paragraph">
<p><span class="image right"><img src="https://original.accentuate.io/556263801041/1636542278424/Lighting-Automation-Mob.jpg" alt="House lighting (source: accentuate.io)" width="180"></span>
First, a bit of background about the example.
We are trying to determine the intent behind English language
commands to turn lights on and off in a house.
We are going to use the project&#8217;s pre-defined model which is part of their examples.
It is defined using a combination of
<a href="https://nlpcraft.apache.org/examples/light_switch.html#model">YAML</a>
and
<a href="https://nlpcraft.apache.org/examples/light_switch.html#code">Scala3 code</a>.
The key thing to note is that the model is made up of a number of keywords
comprising <em>actions</em> and <em>locations</em>.
If these are matched, the lightswitch (<code>ls</code>) intent is triggered.
Actions and locations will become more obvious soon in our example.</p>
</div>
<div class="paragraph">
<p>Our example uses an English language model but NLPCraft can support
any natural language.
They provide the lightswitch model also in
<a href="https://nlpcraft.apache.org/examples/light_switch_fr.html">French</a> and other languages.</p>
</div>
<div class="paragraph">
<p>We also need to add NLPCraft dependencies: <code>org.apache.nlpcraft:nlpcraft:1.0.0</code>
and <code>org.apache.nlpcraft:nlpcraft-example-lightswitch:1.0.0</code> (for the pre-compiled model). You can use <code>@Grab</code> statements in your script or add the dependencies to your build file.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
Depending on the Groovy version and modules you are using, if you see exceptions
complaining about Jackson databind versions, simply exclude the Jackson versions
Groovy is referencing. They are more recent than what Scala is expecting.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Finally, here is the Groovy code:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="groovy">import org.apache.nlpcraft.NCModelClient
import org.apache.nlpcraft.examples.lightswitch.LightSwitchModel
import static scala.collection.immutable.HashMap$.MODULE$ as ScalaMap
var data = ScalaMap.empty() // no optional data
var user = 'someUserId'
var expectedIntent = 'ls' // from model
var phrases = [
'Turn on the lights in the master bedroom',
'Please, no lights!',
'Turn up the illumination in garage and 1st floor'
]
new NCModelClient(new LightSwitchModel()).withCloseable { client -&gt;
phrases.each { phrase -&gt;
var result = client.ask(phrase, user, data)
println result.body
assert result.intentId.get() == expectedIntent
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here, we are just going to print the result returned by the callback
in the model class. Typically, we&#8217;d instead have HomeKit, Arduino or
some other kind of integration at this point. We&#8217;ll also check that
the <code>ls</code> intent was triggered.</p>
</div>
<div class="paragraph">
<p>When we run this script, our assertions pass, and the output is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>Lights are [on] in [master bedroom].
Lights are [off] in [entire house].
Lights are [on] in [1st floor, garage].</pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_asking_for_the_time">Asking for the time</h2>
<div class="sectionbody">
<div class="paragraph">
<p><span class="image right"><img src="https://www.personalrobots.biz/wp-content/uploads/2021/10/takara-robot-watch-calculator.jpg" alt="Robot watch (source: personalrobots.biz)" width="150"></span>
Let&#8217;s now look at the NLPCraft <code>time</code> <a href="https://nlpcraft.apache.org/examples/time.html">example</a>.
It&#8217;s a very simple world time bot implementation.</p>
</div>
<div class="paragraph">
<p>The model is again defined as a combination of
<a href="https://nlpcraft.apache.org/examples/time.html#model">YAML</a>
and
<a href="https://nlpcraft.apache.org/examples/time.html#code">Scala3 code</a>.
A pre-compiled version is available as
<code>org.apache.nlpcraft:nlpcraft-example-time:1.0.0</code> from Maven central.
We used a locally built version with <code>DefaultScalaModule</code> enabled
for YAML processing.
We also need the <code>groovy-yaml</code> module on the Groovy side if not already there.</p>
</div>
<div class="paragraph">
<p>The model defines two intents:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>intent2</code> should be triggered
if a match is found for a city location.</p>
</li>
<li>
<p><code>intent1</code> will be triggered
if it looks like you are asking for the time without a city; this
corresponds to finding the local time.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Here is the Groovy client code:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="groovy">import groovy.yaml.YamlSlurper
import org.apache.nlpcraft.NCModelClient
import org.apache.nlpcraft.examples.time.TimeModel
import static scala.collection.immutable.HashMap$.MODULE$ as ScalaMap
var data = ScalaMap.empty() // no optional data
var user = 'someUserId'
var phrases = [
"What time is it now in New York City?" : 'intent2',
"What's the current time in Singapore?" : 'intent2',
"Show me time of the day in London." : 'intent2',
"Can you please give me Tokyo's current date and time." : 'intent2',
"What's the local time?" : 'intent1'
]
new NCModelClient(new TimeModel()).withCloseable { client -&gt;
phrases.each { phrase, expected -&gt;
var result = client.ask(phrase, user, data)
assert result.intentId.get() == expected
var body = new YamlSlurper().parseText(result.body)
body.with{ println "$city, $country: $localTime" }
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Again, all our assertions pass, and here is the output:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>New york city, United states: 12 Mar. 2023, 10:09:41 pm
Singapore, Singapore: 13 Mar. 2023, 10:09:41 am
London, United kingdom: 13 Mar. 2023, 2:09:41 am
Tokyo, Japan: 13 Mar. 2023, 11:09:41 am
Brisbane, Australia: 13 Mar. 2023, 12:09:42 pm</pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_further_information">Further information</h2>
<div class="sectionbody">
<div class="paragraph">
<p><a href="https://nlpcraft.apache.org/index.html">Apache NLPCraft website</a></p>
</div>
<div class="sidebarblock">
<div class="content">
<div class="title">Update history</div>
<div class="paragraph">
<p><strong>13/Mar/2023</strong>: Added the time example.</p>
</div>
</div>
</div>
</div>
</div></div></div></div></div><footer id='footer'>
<div class='row'>
<div class='colset-3-footer'>
<div class='col-1'>
<h1>Groovy</h1><ul>
<li><a href='http://groovy-lang.org/learn.html'>Learn</a></li><li><a href='http://groovy-lang.org/documentation.html'>Documentation</a></li><li><a href='/download.html'>Download</a></li><li><a href='http://groovy-lang.org/support.html'>Support</a></li><li><a href='/'>Contribute</a></li><li><a href='http://groovy-lang.org/ecosystem.html'>Ecosystem</a></li><li><a href='/blogs'>Blog posts</a></li><li><a href='https://groovy.apache.org/events.html'></a></li>
</ul>
</div><div class='col-2'>
<h1>About</h1><ul>
<li><a href='https://github.com/apache/groovy'>Source code</a></li><li><a href='http://groovy-lang.org/security.html'>Security</a></li><li><a href='http://groovy-lang.org/learn.html#books'>Books</a></li><li><a href='http://groovy-lang.org/thanks.html'>Thanks</a></li><li><a href='http://www.apache.org/foundation/sponsorship.html'>Sponsorship</a></li><li><a href='http://groovy-lang.org/faq.html'>FAQ</a></li><li><a href='http://groovy-lang.org/search.html'>Search</a></li>
</ul>
</div><div class='col-3'>
<h1>Socialize</h1><ul>
<li><a href='http://groovy-lang.org/mailing-lists.html'>Discuss on the mailing-list</a></li><li><a href='https://twitter.com/ApacheGroovy'>Groovy on Twitter</a></li><li><a href='http://groovy-lang.org/events.html'>Events and conferences</a></li><li><a href='https://github.com/apache/groovy'>Source code on GitHub</a></li><li><a href='http://groovy-lang.org/reporting-issues.html'>Report issues in Jira</a></li><li><a href='http://stackoverflow.com/questions/tagged/groovy'>Stack Overflow questions</a></li><li><a href='http://groovycommunity.com/'>Slack Community</a></li>
</ul>
</div><div class='col-right'>
<p>
The Groovy programming language is supported by the <a href='http://www.apache.org'>Apache Software Foundation</a> and the Groovy community.
</p><div text-align='right'>
<img src='../img/asf_logo.png' title='The Apache Software Foundation' alt='The Apache Software Foundation' style='width:60%'/>
</div><p>Apache&reg; and the Apache feather logo are either registered trademarks or trademarks of The Apache Software Foundation.</p>
</div>
</div><div class='clearfix'>&copy; 2003-2023 the Apache Groovy project &mdash; Groovy is Open Source: <a href='http://www.apache.org/licenses/LICENSE-2.0.html' alt='Apache 2 License'>license</a>, <a href='https://privacy.apache.org/policies/privacy-policy-public.html'>privacy policy</a>.</div>
</div>
</footer></div>
</div>
</div>
</div>
</div><script src='../js/vendor/jquery-1.10.2.min.js' defer></script><script src='../js/vendor/classie.js' defer></script><script src='../js/vendor/bootstrap.js' defer></script><script src='../js/vendor/sidebarEffects.js' defer></script><script src='../js/vendor/modernizr-2.6.2.min.js' defer></script><script src='../js/plugins.js' defer></script><script src='https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.js'></script><script>document.addEventListener('DOMContentLoaded',prettyPrint)</script><script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-257558-10', 'auto');
ga('send', 'pageview');
</script>
</body></html>