Mathematica: что такое символьное Программирование?



Я большой поклонник Стивена Вольфрама, но он определенно не стесняется петь свой собственный Рог. Во многих ссылках он превозносит Mathematica как другую парадигму символического программирования. Я не являюсь пользователем Mathematica.



мои вопросы: что это за символическое Программирование? И как это соотносится с функциональными языками (такими как Haskell)?

720   5  

5 ответов:

вы можете думать о символическом программировании Mathematica как о системе поиска и замены, в которой вы программируете, указав правила поиска и замены.

например, вы можете указать следующее правило

area := Pi*radius^2;

в следующий раз, когда вы используете area, он будет заменен с Pi*radius^2. Теперь предположим, что вы определяете новое правило

radius:=5

теперь, когда вы используете radius он будет переписан в 5. Если вы оцениваете area он будет переписан в Pi*radius^2 который запускает правило перезаписи для radius и вы Pi*5^2 как промежуточный результат. Эта новая форма вызовет встроенное правило перезаписи для ^ операция, поэтому выражение будет переписано в Pi*25. На этом этапе перезапись останавливается, потому что нет применимых правил.

вы можете эмулировать функциональное программирование, используя ваши правила замены в качестве функции. Например, если вы хотите определить функцию, которая добавляет, Вы можете сделать

add[a_,b_]:=a+b

теперь add[x,y] переписывается в x+y. Если вы хотите добавить только применить для числовых a, b, вы могли бы вместо этого сделать

add[a_?NumericQ, b_?NumericQ] := a + b

теперь add[2,3] переписывается в 2+3 используя свое правило, а затем в 5 используя встроенное правило для +, а add[test1,test2] остается неизменным.

вот пример интерактивного правила замены

a := ChoiceDialog["Pick one", {1, 2, 3, 4}]
a+1

здесь a заменяется на ChoiceDialog, который затем получает заменено номером, который пользователь выбрал в появившемся диалоговом окне, что делает оба количества числовыми и запускает правило замены для +. Вот,ChoiceDialog как встроенное правило замены по строкам "заменить ChoiceDialog[некоторые вещи] со значением кнопки, которую нажал пользователь".

Правила могут быть определены с использованием условий, которые сами должны пройти переписывание правил, чтобы произвести True или False. Предположим, что вы изобрели новое уравнение метод решения, но вы думаете, что он работает только тогда, когда конечный результат вашего метода является положительным. Вы можете сделать следующее правило

 solve[x + 5 == b_] := (result = b - 5; result /; result > 0)

здесь solve[x+5==20] заменяется на 15, но solve[x + 5 == -20] не изменяется, потому что нет никакого правила, которое применяется. Условие, препятствующее применению этого правила, -/;result>0. Оценщик по существу смотрит потенциальный выход приложения правила, чтобы решить, следует ли идти вперед с ним.

оценщик Mathematica жадно переписывает каждый шаблон с одним из правил, которые применяются для этого символа. Иногда вы хотите иметь более точный контроль, и в таком случае вы можете определить свои собственные правила и применить их вручную, как это

myrules={area->Pi radius^2,radius->5}
area//.myrules

это будет применяться правила, определенные в myrules пока результат не перестанет меняться. Это очень похоже на оценки по умолчанию, но теперь вы можете иметь несколько наборов правил и применять их выборочно. Более продвинутый пример показывает, как сделать Пролог-как оценщик это поиск по последовательностям приложений правил.

один недостаток текущей версии Mathematica возникает, когда вам нужно использовать оценщик Mathematica по умолчанию (чтобы использовать Integrate,Solve, etc)и хотите изменить последовательность оценки по умолчанию. Это возможно, но сложные, и мне нравится думать, что некоторые будущие реализации символьного программирования будут иметь более элегантный способ управления последовательностью оценки

когда я слышу фразу "символическое Программирование", LISP, Prolog и (да) Mathematica сразу же приходят на ум. Я бы охарактеризовал среду символьного программирования как такую, в которой выражения, используемые для представления текста программы, также являются первичной структурой данных. В результате становится очень легко строить абстракции на абстракциях, так как данные могут быть легко преобразованы в код и наоборот.

Mathematica активно использует эту возможность. Еще больше сильно, чем Лисп и пролог (ИМХО).

в качестве примера символьного программирования рассмотрим следующую последовательность событий. У меня есть CSV-файл, который выглядит так:

r,1,2
g,3,4

я прочитал этот файл в:

Import["somefile.csv"]
--> {{r,1,2},{g,3,4}}

является ли результат данных или кода? Это оба. Это данные, полученные в результате чтения файла, но это также выражение, которое будет строить эти данные. Как код идет, однако, это выражение является инертным, так как результат оценка - это просто сама по себе.

Итак, теперь я применяю преобразование к результату:

% /. {c_, x_, y_} :> {c, Disk[{x, y}]}
--> {{r,Disk[{1,2}]},{g,Disk[{3,4}]}}

не останавливаясь на деталях, все, что произошло то, что Disk[{...}] был обернут вокруг последних двух чисел из каждой входной строки. Результат все еще данные/код, но все еще инертный. Еще одна трансформация:

% /. {"r" -> Red, "g" -> Green}
--> {{Red,Disk[{1,2}]},{Green,Disk[{3,4}]}}

Да, все еще инертный. Однако по замечательному совпадению этот последний результат просто оказывается списком действительных директив в Системы Mathematica встроенный проблемно-ориентированный язык для работы с графикой. Одна последняя трансформация, и все начинает происходить:

% /. x_ :> Graphics[x]
--> Graphics[{{Red,Disk[{1,2}]},{Green,Disk[{3,4}]}}]

на самом деле, вы не увидите, что последний результат. В эпической демонстрации синтаксического сахара Mathematica показала бы эту картину красных и зеленых кругов:

alt text

но веселье на этом не заканчивается. Под всем этим синтаксическим сахаром у нас все еще есть символическое выражение. Я могу применить другое преобразование правило:

% /. Red -> Black

alt text

вуаля! Красный круг стал черным.

именно этот вид "подталкивания символа" характеризует символическое Программирование. Подавляющее большинство программ Mathematica имеет такую природу.

функциональная и символическая

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

можно посмотреть символический программирование как ответ на вопрос: "Что произойдет, если я попытаюсь смоделировать все, используя только преобразования выражений? Функциональное программирование, напротив, можно рассматривать как ответ на вопрос: "Что произойдет, если я попытаюсь моделировать все, используя только функции?"Так же, как и символьное Программирование, функциональное программирование позволяет быстро создавать слои абстракций. Пример, который я привел здесь, можно легко воспроизвести, скажем, в Haskell, используя функциональную реактивную анимацию подход. Функциональное программирование - это все о композиции функций, функциях более высокого уровня, комбинаторах-всех тонких вещах, которые вы можете делать с функциями.

Mathematica явно оптимизирована для символьного программирования. Можно писать код в функциональном стиле, но функциональные возможности в Mathematica-это действительно просто тонкий шпон над преобразованиями (и дырявая абстракция при этом, см. сноску ниже).

Haskell явно оптимизирован для функциональное программирование. Можно написать код в символическом стиле, но я бы придирался, что синтаксические представление программ и данных совершенно различны, что делает опыт неоптимальным.

Заключение


дырявая функциональная Абстракция в Mathematica?

Ага, дырявый. Попробуйте это, например:

f[x_] := g[Function[a, x]];
g[fn_] := Module[{h}, h[a_] := fn[a]; h[0]];
f[999]

должным образом доложено и подтверждено WRI. Ответ: избегайте использования Function[var, body] (Function[body] это хорошо).

Как уже упоминалось здесь, Mathematica делает много переписывания терминов. Может быть, Хаскелл не лучшее сравнение, хотя, но чисто это хороший функциональный термин-язык перезаписи (который должен быть знаком людям с фоном Haskell). Возможно, чтение их вики-страницы по переписыванию терминов прояснит для вас несколько вещей:

http://code.google.com/p/pure-lang/wiki/Rewriting

Mathematica использует термин переписывание сильно. Язык предоставляет специальный синтаксис для различных форм перезаписи, специальную поддержку правил и стратегий. Парадигма не такая уж " новая "и, конечно, она не уникальна, но они определенно находятся на краю этого" символического программирования", наряду с другими сильными игроками, такими как Axiom.

Что касается сравнения с Haskell, ну, вы могли бы сделать переписывание там, с небольшой помощью от лома вашего шаблона библиотека, но это не так просто, как в динамически типизированной Mathematica.

символ не должен быть противопоставлен функционалу, он должен быть противопоставлен численному программированию. Рассмотрим в качестве примера MatLab vs Mathematica. Предположим, я хочу характеристический многочлен матрицы. Если бы я хотел сделать это в Mathematica, я мог бы получить матрицу идентичности (I) и саму матрицу (A) в Mathematica, а затем сделать это:

Det[A-lambda*I]

и я бы получил характеристический полином (неважно, что, вероятно, есть характеристический полином с другой стороны, если бы я был в MatLab, я не мог бы сделать это с base MatLab, потому что base MatLab (неважно, что там, вероятно, есть характеристическая полиномиальная функция) хорош только для вычисления чисел конечной точности, а не вещей, где есть случайные лямбды (наш символ) там. То, что вам нужно сделать, это купить надстройку Symbolab, а затем определить lambda как свою собственную строку кода ,а затем записать это (при этом он скорее преобразует вашу матрицу в матрицу рациональных чисел чем десятичные дроби конечной точности), и хотя разница в производительности, вероятно, будет незаметна для такого небольшого случая, она, вероятно, будет делать это намного медленнее, чем Mathematica с точки зрения относительной скорости.

Так вот в чем разница, символьные языки заинтересованы в выполнении вычислений с идеальной точностью (часто используя рациональные числа, а не числовые) и языки численного программирования, с другой стороны, очень хороши в подавляющем большинстве вычислений вы нужно было бы сделать, и они, как правило, быстрее в числовых операциях, для которых они предназначены (MatLab почти не имеет себе равных в этом отношении для языков более высокого уровня - исключая C++ и т. д.), и моча плохо справляется с символическими операциями.

Comments

    Ничего не найдено.