Prolog - Définition

Source: Wikipédia sous licence CC-BY-SA 3.0.
La liste des auteurs de cet article est disponible ici.

Exécution

Prolog est un langage logique, aussi en théorie vous ne devriez pas vous préoccuper de la façon dont il s’exécute. Cependant il est quelquefois prudent de prendre en compte comment l’algorithme d’inférence agit, pour éviter qu’un programme Prolog ne dure trop longtemps.

Par exemple, nous pouvons écrire du code pour compter le nombre d’éléments d’une liste.

      elems([],0).      elems([H|T], X):- elems(T, Y), X is Y + 1.      

Cela signifie simplement; si la liste est vide, le nombre d’éléments est zéro. Si une liste n’est pas vide, alors X est augmenté de un par rapport à Y, lequel est le nombre d’éléments dans le reste de la liste sans le premier élément.

Dans ce cas, il y a une distinction claire entre les cas dans l’antécédent dans les règles. Mais considérez le cas où vous avez besoin de décider si vous continuez à jouer dans un casino;

      miser(X):- avoirargent(X).      miser(X):- avoircrédit(X), NOT avoirargent(X).            

Si vous avez de l’argent, vous continuez à miser. Si vous avez tout perdu vous avez besoin d’emprunter, ou sinon... plus de pari. avoirargent(X) peut être une fonction très coûteuse, par exemple, si elle peut accéder à votre compte bancaire par l’internet. Mais c’est la même chose pour avoircrédit.

En théorie, les implémentations de Prolog peuvent évaluer ces règles dans n’importe quel ordre, aussi vous pourriez aussi bien avoir écrit;

      miser(X):- avoircrédit(X), NOT avoirargent(X).      miser(X):- avoirargent(X).      

Ce qui est bien, parce que les deux options s’excluent l’une l’autre. Cependant vérifier si vous pouvez obtenir un prêt n’est pas nécessaire si vous savez que vous avez de l’argent. Aussi en pratique, les implémentations de Prolog testeront d'abord la règle que vous avez écrit en premier. Vous pouvez utiliser l’opérateur cut pour dire à l’interpréteur de sauter la deuxième option si la première suffit. Par exemple:

      miser(X):- avoirargent(X), !.      miser(X):- avoircrédit(X), NOT avoirargent(X).      

Cela est appelé un opérateur d’arrêt vert. Le ! dit simplement à l’interpréteur de ne plus chercher d’alternative. Mais vous notez que si vous avez besoin d’argent il a besoin d’évaluer la seconde règle, et il le fera. Evaluer avoirargent dans la deuxième règle est plutôt inutile car vous savez que vous n’en avez pas, pour la bonne raison que, sinon, la seconde règle ne serait pas évaluée. Aussi vous pouvez changer le code en:

      miser(X):- avoirargent(X), !.      miser(X):- avoircrédit(X).      

Cela est appelé un opérateur d’arrêt rouge, parce qu’il est dangereux de faire cela. Vous êtes maintenant dépendant du placement correct de l’opérateur d’arrêt et l’ordre des règles pour déterminer leur sens logique. Les accidents de Couper-et-coller guettent dans les coins sombres. Si les règles sont mélangées, vous pouvez maintenant utiliser votre carte de crédit avant de dépenser votre argent disponible.

Évaluation

Quand l’interpréteur reçoit une requête, il recherche les règles (faits inclus) dont la partie gauche peut être unifiée avec la requête, et effectue cette unification avec la première règle trouvée. Par exemple ayant ce code Prolog :

      frère_ou_sœur(X,Y):- parent(Z,X), parent(Z,Y), X \= Y.      parent(X,Y):- père(X,Y).      parent(X,Y):- mère(X,Y).      mère(trude, sally).      père(tom, sally).      père(tom, erica).      père(mike, tom).            

Il en résulte que la demande suivante est évaluée comme vraie:

      ?- frère_ou_sœur(sally, erica).           oui.      

L’interpréteur arrive à ce résultat en faisant correspondre la règle frère_ou_sœur(X,Y) en unifiant X avec sally et Y avec erica. Cela signifie que la demande peut être étendue à parent(Z,sally), parent(Z,erica). Faire correspondre cette conjonction est obtenu en regardant tous les parents possibles de sally. Cependant, parent(trude,sally) ne mène pas à une solution viable, parce que si trude est substitué pour Z, parent(trude,erica) devra être vrai, et aucun fait tel (ou quelque règle qui peut satisfaire cela) n'est présent. Aussi à la place, tom est substitué pour Z, et erica et sally apparaissent être frère_ou_sœur néanmoins.

Négation par l'échec

La négation logique pure n'existe pas en Prolog, on se repose sur la négation par l'échec, qui se note différemment suivant les implémentations de Prolog (nous adopterons la notation par le mot-clé not). En négation par l'échec, un prédicat est considéré comme faux si, en un temps fini, on échoue à montrer qu'il est vrai (par l'algorithme de résolution de Prolog). Cela est appelé l'hypothèse du monde clos (opposé à l'hypothèse du monde ouvert) : on considère que tout ce qui doit être connu est inclus dans la base de données, il n’y a pas de monde extérieur qui pourrait contenir des éléments de preuve inconnus du programme. En d'autres termes, tant qu'un fait n’est pas connu comme étant vrai, il est considéré comme faux.

Une règle comme celle-ci :

      mangeable(X):- not indigeste(X).      

peut seulement être évaluée en cherchant d'abord à montrer que 'indigeste(X)' est vrai. Si cette recherche échoue, alors "mangeable(X)" est vrai. C'est ce qu'on appelle la négation par l'échec.

Page générée en 0.006 seconde(s) - site hébergé chez Contabo
Ce site fait l'objet d'une déclaration à la CNIL sous le numéro de dossier 1037632
A propos - Informations légales | Partenaire: HD-Numérique
Version anglaise | Version allemande | Version espagnole | Version portugaise