Validate Natural Language

◷ Reading Time: 3 minutes

When you have an NL model you can validate the NL structure to ensure it is a valid NL. There are two ways to validate:

  1. Create an instance of an engine using RuntimeEngine
  2. Build the execution plan of NL using NaturalParser parser

If your Natural Language is not valid structurally, the execution plan cannot be built and an exception will be thrown. If you go with the second approach, you need to create the NL execution plan as well to ensure the XML structure is valid.

To validate the XML structure (i.e., Declaration, Define, etc.), you can check the XML against our Document Commands.

Using RuntimeEngine

When you create an instance of an IRuntimeEngine for a Natural Language, the execution plan will be created for NL immediately.

// get the binary of your NL model
var nlContent = Encoding.UTF8.GetBytes(rule);
 
// create an instance of an engine for the NL
var engine = RuntimeEngine.FromXml(nlContent);
 
// Force the engine to create the execution plan
engine.EnsureLoaded()

Using Natural Language Parser

In this approach, you can validate the NL format and structure:

// get the binary of your NL model
var nlContent = Encoding.UTF8.GetBytes(rule);
 
// Use table parser to build the execution plan for your NL
var nlPlanModel = NaturalParser.CreateParser().Parse(nlContent).First();

And then create an execution plan to ensure the whole XML document is valid:

// Create an Execution Plan for NL
var engine = RuntimeEngine.FromXml(nlContent);

Extract Expressions

When a Natural Language is compiled (parsed) to its execution plan, the execution steps become a Check element. So the application can traverse the Check elements and inspect the value attribute for expressions.

For example, consider below NL:

input car
when test price range
    car.Price is [2; 33]
end 

The result of NL to its execution plan is below Validation logic:

<Validation enable="true">
  <Declaration>
    <Define name="car" direction="Local" />
  </Declaration>
  <Logic name="test price range">
    <Group>
      <Check value="((car.Price >= 2) && (car.Price <=  33))" />
    </Group>
  </Logic>
</Validation>

Extracting expressions from Execution Plan:

  • Build execution plan
  • Traverse execution plan and extract Check/value expressions
  • Register parameters in Variable Container
  • Build an expression tree using ExpressionEval.Default.Compile
var parser = NaturalParser.CreateParser();
IElementModel model = parser.Parse(rule).First();
 
// Traverse the tree to extract the expressions to parse
var logicTestPriceRange = model.Childs.First(x => x.Name == "Logic");
var check = logicTestPriceRange.Childs[0].Childs[0];
var expression = check.Parameters["value"];
 
// create a Variable Container and register parameters
var parameters = model.GetDeclaration().Childs.Where(x => x.Name == "Define").Select(x => x.Parameters["name"]);
var vc = new VariableContainer();
foreach (var param in parameters)
    vc.RegisterVariable(param);
 
// Build the expression tree for the Check in execution plan
var tree = ExpressionEval.Default.Compile(vc, expression);

Expression Tree:

&&:
 compare.Greater, Equal:
   member:
     variable.car
     member.Price
   2
 compare.Equal, Less:
   member:
     variable.car
     member.Price
   33
Updated on April 19, 2020

Was this article helpful?

Related Articles