Динамическое описание математических правил - PullRequest
2 голосов
/ 17 января 2012

Я хочу иметь возможность задавать математические правила во внешнем местоположении для моего приложения, и чтобы мое приложение обрабатывало их во время выполнения и выполняло действия (снова описанные внешне). Каков наилучший способ сделать это?

Например, я мог бы захотеть выполнить функцию MyFunction1(), когда следующее значение оценивается как true:

(a < b) & MyFunction2() & (myWord == "test").

Заранее спасибо за помощь.

(Если это имеет какое-либо отношение, я хочу использовать C ++, C или C ++ / CLI)

Ответы [ 4 ]

3 голосов
/ 17 января 2012

Я бы не стал изобретать велосипед - используйте встроенный скриптовый движок. Это означает, что вы будете использовать стандартную форму для описания действий и логики. Есть несколько отличных вариантов, которые, вероятно, подойдут для ваших нужд.

Хорошие варианты включают в себя:

  1. Javascript, хотя Google v8. (Я не люблю это с точки зрения вложения, но с javascript легко работать, и многие это уже знают)

  2. Lua. Это быстро и портативно. Синтаксис, возможно, не так хорош, как Javascript, но встраивание легко.

  3. Python. Чистый синтаксис, множество библиотек. Не очень интересно встраивать.

Я хотел бы рассмотреть возможность использования SWIG для создания привязок ... Я знаю, что это работает для python и lua, не уверен насчет v8.

1 голос
/ 17 января 2012

Я бы посмотрел на шаблон команды для обработки вызова внешних математических предикатов, а также на шаблон Factory для запуска внешнего кода.

0 голосов
/ 20 января 2012

Если этот расчет происходит во внутреннем цикле, вам нужна высокая производительность, вы не можете использовать языки сценариев.Исходя из того, насколько «разворачиваемым» и насколько независимым от платформы вы хотели бы, чтобы это было:

1) Вы можете выразить уравнения в C ++ и позволить g ++ скомпилировать их для вас во время выполнения, и вы можете сослаться нарезультирующий общий объект.Но этот метод очень сильно зависит от платформы на каждом шагу!Необходимые системные вызовы, используемый компилятор, флаги, загрузка общего объекта (или DLL) ... В конце концов, это будет очень быстро, особенно если вы скомпилируете самый внутренний цикл с помощью уравнения.Уравнение будет встроено и все.

2) Вы можете использовать Java таким же образом.Вы можете получить хороший java-компилятор в java (я думаю, из Eclipse, но вы можете легко его встроить).При таком решении результат будет немного медленнее (в зависимости от того, сколько магии шаблонов вы хотите), как я ожидаю, в 2 раза для большинства целей.Но это решение чрезвычайно портативно.Как только вы запустите его, нет никаких причин, по которым оно нигде не должно работать, вам не нужно ничего внешнего для вашей программы.Еще одним недостатком является необходимость писать уравнения в синтаксисе Java, что уродливо для сложной математики.Первое решение намного лучше в этом отношении, так как перегрузка операторов очень помогает в математических уравнениях.

3) Я немного знаю о C #, но может быть решение, подобное (2).Если есть, я знаю, что в C # есть перегрузка операторов, поэтому ваши уравнения было бы более приятным для написания и просмотра.

0 голосов
/ 17 января 2012

Если ваш язык математических выражений настолько прост, то вы можете определить для него грамматику, например ::

expr = bin-op-expr | rel-expr | func-expr | var-expr | "(" expr ")"

bin-op = "&" | "|" | "!"
bin-op-expr = expr bin-op expr

rel-op = "<" | ">" | "==" | "!=" | "<=" | ">="
rel-expr = expr rel-op expr

func-args = "(" ")"
func-expr = func-name func-args

var-expr = name

, а затем перевести это в грамматику для парсера. Например. Вы можете использовать Boost.Spirit, который предоставляет DSL, чтобы позволить вам выразить грамматику в вашем коде C ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...