Calcul formel et programmation logique

Le calcul formel est le calcul qui porte sur des expressions mathématiques formalisées. Il est actuellement mis en oeuvre dans des outils spécialisés pour les mathématiciens (Mathematica, Maple,...).

Ce calcul utilise la sérialisabilité des formules mathématiques, c'est à dire le fait qu'elles sont exprimables sous la forme suite de caractères formant une expression bien parenthésée dans un langage défini.
Prenons, par exemple, l'expression des fonctions en analyse. Il existe des fonctions désignées par un symbole spécifique (log, exp, sin, cos,...), mais ce n'est qu'un nombre réduit de fonctions qui sont ainsi exprimées. Dans, le cas général, une fonction est une combinaison par sommes et produits d'expression de ce genre. Une telle expression peut être représentée par un arbre.
Soit, par exemple, la fonction:
f(x) = ex2 • log(x) + log(x)3

L'interprétation de sa syntaxe donne l'arbre suivant:
+

^
e
^
x
2
log
x
^
log
x
3

On peut donc la représenter sans ambiguité sous la forme de la chaine de caractères suivante:
exp(x^2)*log(x)+log(x)^3
C'est sous cette forme qu'elle sera représentée en Prolog, et l'arbre servira de base aux opérations d'unification.
L'unification se fera donc dans l'ordre de cet arbre.

Exercice 1:

Prenons, par exemple, la dérivation formelle. Une base de règles exprimant cette opération formelle va donc exprimer les règles usuelles sur la dérivation en analyse: dérivée d'une somme, d'un produit, d'un quotient, d'une puisance:
d(U+V,X,DU+DV) :- d(U,X,DU),d(V,X,DV).
d(U-V,X,DU-DV) :- d(U,X,DU),d(V,X,DV).
d(U*V,X,DU*V+U*DV) :- d(U,X,DU),d(V,X,DV)
d(U^N,X,DU*N*U^N1) :- integer(N),N1 is N-1,d(U,X,DU).
Puis les principaux cas particuliers seront exprimés.
d(exp(U),X,exp(U)*DU) :- d(U,X,DU).
d(log(U),X,DU/U) :- d(U,X,DU).
d(X,X,1).
d(C,X,0).

La dernière règle exprime que la dérivée d'une constante est nulle. Chargez donc cette base de règles, et essayez de dériver l'expression donnée plus haut: que constatez vous?

Complément de cours:

Il est nécessaire à ce stade de s'attarder un peu sur deux prédicats particuliers en Prolog: le "cut" et la négation. C'est l'objet de ce complément de cours.

Exercice 2:

Il faudrait parvenir à exprimer que la constante ne dépend pas de X, ce qui est compliqué, pour ne pas dire impossible. Une autre solution serait que cette règle ne soit atteinte que si aucune autre unification n'a été trouvée. Plus précisément, dès qu'une unification est trouvée, on coupe les autres alternatives.
Modifiez les règles précédentes pour obtenir ce résultat.
Que se passe-t-il si on donne à cette base un quotient à dériver?
Ajouter la règle nécessaire à corriger cette situation.

Exercice 3:

Si l'unification rencontre la règle d(U+V,X,DU+DV) :- d(U,X,DU),d(V,X,DV). elle pourra aussi bien l'utiliser avec le premier argument variable (calcul de la dérivée) qu'avec le second (calcul de l'intégrale).

Mais il n'en est pas de même pour la règle d(U^N,X,DU*N*U^N1) :- integer(N),N1 is N-1,!,d(U,X,DU). à cause de l'opérateur d'affectation et du test de type.

Comment caractériser les cas où cette règle fonctionne aussi bien dans un sens que dans l'autre?
Même question pour les autres règles.