Wolfram Language

Text & Language Processing

Create a Natural Language Calculator

This example builds a simple calculator that takes numbers in natural language and supports several infix operators of different relative precedence.

Use the built-in token form "SemanticNumber" and four more custom tokens.

In[1]:=
Click for copyable input
tokens = {GrammarToken["SemanticNumber"], GrammarToken["Summand"], GrammarToken["Multiplicand"], GrammarToken["Addition"], GrammarToken["Multiplication"]};

A summand can be a full addition expression (to implement associativity), a full multiplication expression, or a number. A multiplicand can be a full multiplication expression (again to implement associativity) or a number, but not an addition expression, which assigns higher precedence to multiplication.

In[2]:=
Click for copyable input
defs1 = {"Summand" -> s : (GrammarToken["Addition"] | GrammarToken["Multiplication"] | GrammarToken["SemanticNumber"]) :> s, "Multiplicand" -> m : (GrammarToken["Multiplication"] | GrammarToken["SemanticNumber"]) :> m};

Associate the "Addition" token to sums and rests, and the "Multiplication" token to products and divisions. Rests and divisions are not commutative, and therefore you need to keep the order of terms by using FixedOrder.

In[3]:=
Click for copyable input
defs2 = { "Addition" -> FixedOrder[a : GrammarToken["Summand"], "+", b : GrammarToken["Summand"]] :> a + b, "Addition" -> FixedOrder[a : GrammarToken["Summand"], "-", b : GrammarToken["Summand"]] :> a - b, "Multiplication" -> FixedOrder[a : GrammarToken["Multiplicand"], "*", b : GrammarToken["Multiplicand"]] :> a*b, "Multiplication" -> FixedOrder[a : GrammarToken["Multiplicand"], "/", b : GrammarToken["Multiplicand"]] :> a/b};

Deploy the GrammarRules object to the Wolfram Cloud.

In[4]:=
Click for copyable input
calc = CloudDeploy[GrammarRules[tokens, Join[defs1, defs2]]];

Evaluate some arithmetic inputs containing natural language.

In[5]:=
Click for copyable input
GrammarApply[calc, "one + one"]
Out[5]=
In[6]:=
Click for copyable input
GrammarApply[calc, "one + two + three"]
Out[6]=
In[7]:=
Click for copyable input
GrammarApply[calc, "five + seventeen * ten"]
Out[7]=
In[8]:=
Click for copyable input
GrammarApply[calc, "one hundred - one hundredth"]
Out[8]=
In[9]:=
Click for copyable input
GrammarApply[calc, "zero + one/forty-five"]
Out[9]=
In[10]:=
Click for copyable input
GrammarApply[calc, "one/forty-five - one"]
Out[10]=

Related Examples

de es fr ja ko pt-br ru zh