Создание калькулятора естественного языка
Данный пример демонстрирует создание простого калькулятора, который работает с числами в естественном языке и поддерживает несколько инфиксных операторов различных относительных предшествований.
Используйте встроенную форму лексемы "SemanticNumber" и четыре другие собственные лексемы.
tokens = {GrammarToken["SemanticNumber"], GrammarToken["Summand"],
GrammarToken["Multiplicand"], GrammarToken["Addition"],
GrammarToken["Multiplication"]};
Слагаемое может быть полным выражением сложения (для внедрения ассоциативности), полным выражением умножения или числом. Множитель может быть полным выражением умножения (также для внедрения ассоциативности) или числом, но не выражением сложения, что присваивает умножению более высокий статус.
defs1 = {"Summand" ->
s : (GrammarToken["Addition"] | GrammarToken["Multiplication"] |
GrammarToken["SemanticNumber"]) :> s,
"Multiplicand" ->
m : (GrammarToken["Multiplication"] |
GrammarToken["SemanticNumber"]) :> m};
Создайте ассоциацию лексемы "Addition" с суммами и остатками, а лексему "Multiplication" - с произведениями и делениями. Остатки и деления не являются коммутативными, поэтому Вам следует сохранять порядок членов при помощи FixedOrder.
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};
Разверните объект GrammarRules в облаке Wolfram Cloud.
calc = CloudDeploy[GrammarRules[tokens, Join[defs1, defs2]]];
Оцените некоторые арифметические вводы, содержащие естественный язык.
GrammarApply[calc, "one + one"]
GrammarApply[calc, "one + two + three"]
GrammarApply[calc, "five + seventeen * ten"]
GrammarApply[calc, "one hundred - one hundredth"]
GrammarApply[calc, "zero + one/forty-five"]
GrammarApply[calc, "one/forty-five - one"]