Sentences are the level at which the engine recognizes user input. A sentence rule is defined using a C# method. It takes as parameters the parsed tokens from the input (words, values, database objects, ...) and returns a single value None to indicate that it was successful in responding to the sentence.

You can think of these sentence rules as being a bit like action methods in ASP.NET MVC 3+. When a request comes in the engine picks the appropriate controller class, instantiates it (using dependency injection), and then executes the action method. The 'routing engine' that the NLP engine uses to map user input onto these methods is however much more complicated than an MVC route because it converts plain english text into tokens and then matches those tokens to rules whilst allowing permutations and optional parameters. Also, unlike ASP.NET MVC a rule can run for an indeterminate period of time, asynchronously responding to the user, or it can return a value Continue to indicate that it could not work with the tokens passed to it, and that allows another lower priority rule to run.

Here's a sample sentence rule:

public NLPActionResult ExerciseForADistanceOrTime
       (I me, 
       Verb.Type.ExercisePast verb, 
       [Permute][Optional]Distance distance, 
       [Permute][Optional]TimePeriod time, 
       [Permute][Optional]TemporalSetCollection when)
   return NLPActionResult.None;

This one rule will fire for literally millions of possible user inputs including sentences like:

I ran 2 miles
I walked for 20 minutes this afternoon
I swam 100 yards
I rode 27.8 miles

Each parameter in the sentence can be any of:-

  • An interface representing a subset of the common words defined as lexemes (e.g. Verb.Type.Past)
  • A common .NET class like int, double, ...
  • One of the provided token classes like 'Distance', 'TimePeriod', ...
  • The special TemporalSet class (which merits separate discussion)
  • A custom token class that you write to recognize specific words of interest (e.g. company part numbers, invoice numbers, ...)
  • A custom token class that you write that queries a database (e.g. NetflixMovie) during the parsing operation

Rules exist in classes that are instantiated prior to rule execution. Any context a rule needs can be provided through these controller classes (e.g. a User object representing the current user, a History object representing the conversation history, ...) This context is injected either by passing values to the Execute method or through a dependency injection framework like Autofac.

The whole mechanism by which AboditNLP responds to the user is, in fact, just another injected object which means the engine itself is totally decoupled from how you choose to implement conversations and conversational memory, from whether you choose synchronous (e.g. email) or asynchronous (e.g. chat) communication, and whether you format the responses as plain text, HTML, markdown or more complex multi-valued responses containing both text and webpage panel updates like you will see in the demo later.