84 votes

Mathematica : ce qui est programmation symbolique ?

Je suis un grand fan de Stephen Wolfram, mais il est certainement un pas timide de tooting sa corne. De nombreuses références, il exalte mathematica comme un paradigme de programmation symbolique différent. Je ne suis pas un utilisateur de mathematica, donc ma question est quelle est cette programmation symbolique, et comment se comparent-ils aux langages fonctionnels tels que Haskell ?

77voto

WReach Points 13161

Quand j'entends l'expression "programmation symbolique", LISP, Prolog et (oui) Mathematica immédiatement vient à l'esprit. Je caractériser une symbolique environnement de programmation dans lequel les expressions utilisées pour représenter du texte de programme aussi arriver à être la principale structure de données. Par conséquent, il devient très facile de construire des abstractions sur des abstractions puisque les données peuvent être facilement transformés en code et vice versa.

Mathematica exploite cette capacité fortement. Encore plus lourdement que LISP et Prolog (à mon humble avis).

Comme un exemple de programmation symbolique, considérons la séquence suivante d'événements. J'ai un fichier CSV qui ressemble à ceci:

r,1,2
g,3,4

J'ai lu le fichier en question:

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

Est le résultat de données ou de code? C'est les deux. C'est les données qui résulte de la lecture du fichier, mais il arrive aussi d'être l'expression qui permettra de construire des données. Que le code va, toutefois, cette expression est inerte depuis le résultat de l'évaluation, il est tout simplement lui-même.

Alors maintenant, j'applique une transformation à la suite:

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

Sans s'attarder sur les détails, tout ce qui s'est passé, c'est qu' Disk[{...}] a été enroulée autour des deux derniers chiffres de chaque ligne de saisie. Le résultat est encore de données/code, mais toujours inerte. Une autre transformation:

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

Oui, toujours inerte. Cependant, par une remarquable coïncidence, ce dernier résultat est juste une liste de directives valables dans Mathematica est intégré dans un domaine spécifique de la langue pour les graphiques. Une dernière transformation, et les choses commencent à se produire:

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

En fait, vous ne voulez pas voir que le dernier résultat. Une épopée d'affichage de sucre syntaxique, Mathematica serait montrer cette image de rouge et de vert cercles:

alt text

Mais le plaisir ne s'arrête pas là. En dessous de tout ce que sucre syntaxique, nous avons encore une expression symbolique. Je peux appliquer une autre règle de transformation:

% /. Red -> Black

alt text

Presto! Le cercle rouge est devenu noir.

C'est ce genre de symbole "poussant" qui caractérise la programmation symbolique. Une grande majorité de Mathematica de programmation est de cette nature.

Fonctionnelle vs Symbolique

Je ne vais pas aborder les différences entre symbolique et fonctionnelle programmation en détail, mais je vais contribuer à un certain nombre de remarques.

On pourrait considérer programmation symbolique comme une réponse à la question: "Qu'arriverait-il si j'ai essayé de modèle tout en utilisant seulement l'expression des transformations?" Programmation fonctionnelle, en revanche, peut être vue comme une réponse à: "Qu'arriverait-il si j'ai essayé de modèle tout en utilisant uniquement les fonctions?" Tout comme symbolique de la programmation, la programmation fonctionnelle rend facile de créer rapidement des couches d'abstractions. L'exemple que j'ai donné ici pourrait être facilement reproduit dans, disons, Haskell à l'aide d'un fonctionnel réactif animation de la démarche. La programmation fonctionnelle est tout au sujet de la composition de fonctions, aux fonctions de haut niveau, combinators -- tous les chouettes choses que vous pouvez faire avec les fonctions.

Mathematica est clairement optimisé pour la programmation symbolique. Il est possible d'écrire du code dans le style fonctionnel, mais les caractéristiques fonctionnelles de Mathematica sont vraiment juste un mince placage sur des transformations (et une abstraction qui fuit, voir la note de bas de page ci-dessous).

Haskell est clairement optimisé pour la programmation fonctionnelle. Il est possible d'écrire du code dans le style symbolique, mais je tiens à redire que la syntaxiques représentation de programmes et de données sont tout à fait distinctes, ce qui rend l'expérience optimale.

Remarques Finales

En conclusion, je plaide pour qu'il existe une distinction entre la programmation fonctionnelle (incarnée par Haskell) et de la programmation symbolique (comme illustrée par Mathematica). Je pense que si l'on étudie à la fois, alors on va en apprendre beaucoup plus que d'étudier un seul, le test ultime de la distinction.


Qui fuit Fonctionnelle de l'Abstraction dans Mathematica?

Yup, qui fuit. Essayez ceci, par exemple:

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

Dûment signalés, et reconnu par l'IRG. La réponse: éviter l'utilisation de l' Function[var, body] (Function[body] est d'accord).

75voto

Yaroslav Bulatov Points 7316

Vous pouvez penser de Mathematica est symbolique de la programmation comme un rechercher-remplacer le système où vous programme en spécifiant la recherche et le remplacement de règles.

Par exemple, vous pouvez spécifier la règle suivante

area := Pi*radius^2;

La prochaine fois que vous utilisez area, il va être remplacé par Pi*radius^2. Maintenant, supposons que vous définissez la nouvelle règle

radius:=5

Maintenant, chaque fois que vous utilisez radius, elle peut être réécrite en 5. Si vous évaluez area il va avoir réécrit en Pi*radius^2 qui déclenche la règle de réécriture pour radius et vous obtiendrez Pi*5^2 comme un résultat intermédiaire. Cette nouvelle forme de déclencher un construit-dans la règle de réécriture pour ^ ainsi, l'expression obtiendrez de plus amples réécrit en Pi*25. À ce point de réécriture s'arrête car il n'existe pas de règles applicables.

Vous pouvez retrouver la programmation fonctionnelle en utilisant vos règles de remplacement en fonction. Par exemple, si vous souhaitez définir une fonction qui ajoute, que vous pourriez faire

add[a_,b_]:=a+b

Maintenant, add[x,y] obtient réécrit en x+y. Si vous voulez ajouter de n'appliquer que des nombres a,b, vous pourriez faire au lieu de

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

Maintenant, add[2,3] obtient réécrit en 2+3 à l'aide de votre règle et, ensuite, en 5 à l'aide intégrée dans la règle pour +, alors que add[test1,test2] reste inchangé.

Voici un exemple d'un système interactif de règle de remplacement

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

Ici, a sera remplacé par ChoiceDialog, qui est ensuite remplacé par le nombre que l'utilisateur a choisi dans la boîte de dialogue qui surgit, ce qui le rend à la fois des quantités numériques et déclenche la règle de remplacement pour +. Ici, ChoiceDialog comme un construit-dans le remplacement de la règle le long des lignes de "remplacer ChoiceDialog[des choses] avec la valeur de bouton l'utilisateur a cliqué".

Des règles peuvent être définies à l'aide de conditions qui eux-mêmes ont besoin de passer par la règle de réécriture afin de produire de l' True ou False. Par exemple, supposons que vous avez inventé une nouvelle méthode de résolution de l'équation, mais vous pensez qu'il ne fonctionne que lorsque le résultat final de votre méthode est positif. Vous pourriez faire la règle suivante

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

Ici, solve[x+5==20] sera remplacé par le 15, mais solve[x + 5 == -20] est inchangé car il n'y a aucune règle qui s'applique. La condition qui empêche l'application de cette règle à partir de l'application est - /;result>0. L'évaluateur s'intéresse essentiellement de la production potentielle de l'application de la règle de décider d'aller de l'avant.

Mathematica de l'évaluateur goulûment réécrit chaque modèle avec une des règles qui s'appliquent à ce symbole. Parfois, vous voulez avoir plus de contrôle, et dans de tels cas, vous pouvez définir vos propres règles et de les appliquer manuellement comme ceci

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

Cela permettra d'appliquer les règles définies dans myrules jusqu'au résultat de cesse de changer. C'est assez similaire à la valeur par défaut de l'évaluateur, mais maintenant vous pouvez avoir plusieurs ensembles de règles et de les appliquer de manière sélective. Un plus avancés exemple montre comment faire un Prologue comme évaluateur que les recherches sur les séquences de la règle des applications.

Un inconvénient de l'actuel Mathematica version vient quand vous avez besoin d'utiliser Mathematica par défaut de l'évaluateur de faire usage de l' Integrate, Solve, etc) et souhaitez modifier la valeur par défaut de la séquence de l'évaluation. C'est possible, mais compliqué, et j'aime à penser que l'avenir de la mise en œuvre de la programmation symbolique aura une façon plus élégante de contrôle de l'évaluation de la séquence

11voto

Michael Kohl Points 33345

Comme d'autres ici, déjà mentionné, Mathematica fait beaucoup de réécriture de termes. Peut-être Haskell n'est pas la meilleure comparaison, mais Pure est une belle fonctionnelle terme de réécriture de la langue (qui devrait être familier pour les gens avec un Haskell arrière-plan). Peut-être que la lecture de leur page Wiki sur la réécriture de termes vont se préciser un peu les choses pour vous:

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

6voto

SK-logic Points 6952

Mathematica est à l'aide de la réécriture de termes fortement. Le langage fournit une syntaxe spéciale pour les diverses formes de la réécriture, de soutien spécial pour les règles et les stratégies. Le paradigme n'est pas un "nouveau" et bien sûr, il n'est pas unique, mais ils sont certainement sur un bord de saignement de cette "programmation symbolique de chose", aux côtés des autres acteurs puissants comme Axiome.

Comme pour la comparaison de Haskell, eh bien, vous pourriez faire de la réécriture de là, avec un peu d'aide à partir de rebuts de votre standard de la bibliothèque, mais il n'est pas aussi facile que dans un typées dynamiquement Mathematica.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X