Le langage Prolog - WordPress.com · 2016-03-22 · Affichage (fin) l Affichage de caractères et...

Post on 26-Jul-2020

5 views 0 download

Transcript of Le langage Prolog - WordPress.com · 2016-03-22 · Affichage (fin) l Affichage de caractères et...

ProLog

Partie 5 : Pour aller plus loin

Mathieu Vidal

Université Grenoble Alpes

Année 2015-2016

L2 - MIASHS

Grenoble - France

Plan

l Opérateurs mathématiquesl Entrées-Sortiesl Modularitél Création dynamique de faits et de règles

Partie 1-

Opérateurs mathématiques

Les expressions arithmétiques

l Prolog connaît les entiers et les nombres flottants.

l Les expressions arithmétiques sont construites à partir de nombres, de variables et d'opérateurs arithmétiques.

l Evaluation : par l’utilisation de l'opérateur is par exemple dans X is 3 - 2.

Les expressions arithmétiques

l Opérations habituelles :

addition (+), soustraction (-),

multiplication (*), division entière (//),

division flottante (/), modulo (mod)l Fonctions mathématiques préféfinies :

abs(X), log(X), sqrt(X), exp(X), sign(X), random(X), sin(X), cos(X), tan(X), min(X,Y), max(X,Y), etc.

l Les expressions sont représentées par des arbres Prolog

l Opérateur binaire infixé : il figure entre ses 2 arguments et désigne un arbre binaire

X + Y

l Opérateur unaire préfixé : il figure avant son argument et désigne un arbre unaire

-X

Les opérateurs

+

YX

-

X

Les expressions arithmétiques

l Expressions et unification : attention à certaines tentatives d ’unificationl la tentative d’unification entre 3+2 et 5 échouera. En

effet, l’expression 3+2 est un arbre alors que 5 est un nombre.

l L'évaluation des expressions ne fait pas partie de l’algorithme d’unification.

Les prédicats de comparaisonl Comparaison des expressions arithmétiques

l X =:= Y se traduit par X est égal à Yl X =\= Y se traduit par X est différent de Yl X < Yl X =< Yl X > Yl X >= Y

Il y a évaluation puis comparaison.

?- 5 = 3 + 2.No?- 5 =:= 3 + 2.Yes

Comparaison et unification de termesl Fonctions de vérification de type : var, nonvar, integer,

float, number, atom, string, …l Comparer deux termes :

l T1==T2 réussit si T1 est identique à T2l T1\==T2 réussit si T1 n’est pas identique à T2

l Unification de deux termes :l T1=T2 unifie T1 avec T2l T1\=T2 réussit si T1 n’est pas unifiable à T2

Exemple:?- f(X)==f(x).No?- f(X)=f(x).X = xYes

Exercicel Donner les réponses de Prolog aux requêtes suivantes

l ?- X is 9 mod 4.l ?- X = 9 mod 4.l ?- X == 9 mod 4.

Solutionl Donner les réponses de Prolog aux requêtes suivantes

l ?- X is 9 mod 4.X = 1.

l ?- X = 9 mod 4.X = 9 mod 4.

l ?- X == 9 mod 4.false.

Partie 2-

Fichiers : Lecture et Ecriture

Intro - Affichage

l Ecriture sur l'écran ou dans un fichierl Lecture à partir du clavier ou d’un fichierl Affichage de termes :

l write(1+2) affiche 1+2

l write(X). affiche X sur l'écran, sous la forme _245 qui est le nom interne de la variable.

l nl/0 : nl permet de passer à la ligne

l tab/1 : tab(N) affiche N espaces

Affichage (suite)

l Affichage de termes (suite) :l display/1 agit comme write/1 mais en affichant la représentation

sous forme d’arbrel Ex :

write(3+4), nl, display(3+4), nl.

Affiche :

3+4

+(3,4)

YES

Affichage (fin)

l Affichage de caractères et de chaînesput/1 s’utilise en donnant le code ASCII

d’un caractère :put(97).affiche : a

l Prolog connaît aussi les chaînes de caractères. Elles sont notées entre "  ". Mais pour Prolog la chaîne est une liste de codes ASCII des caractères la composant.

Lecture

l Lecture de termes :read/1 admet n’importe quel terme en argument.

read lit un terme au clavier et l’unifie avec son argument. Le terme lu doit être obligatoirement suivi d’un point. Certains systèmes Prolog affichent un signe d’invite lorsque le prédicat read/1 est utilisé.

Exemple :?- read(X).

|: a(1,2). '| :' est le signe d'invite en Swi-Prolog

X = (a(1,2))

Lecture de caractères

l Lecture de caractères :get/1 et get0/1. Tous les deux prennent en

argument un terme unifié avec le code ASCII du caractère lu. Si l’argument est une variable, celle-ci prendra pour valeur le code ASCII du caractère lu. get/1 ne lit que les caractères de code compris entre 33 et 126, pour les autres caractères utiliser get0.

Fichiers

l Les fichiers :l Un fichier peut être ouvert en lecture ou écriture.l En écriture :l mode write : son contenu est effacé avant que Prolog y écrive.l mode append : Prolog écrira à partir de la fin du fichier.

l Ouverture d’un fichier : prédicat open/3l argument 1 : nom du fichierl argument 2 : mode d’ouverture write, append ou read l argument 3 : variable qui va recevoir un identificateur de fichier appelé flux ou

stream.

Lecture Ecriture avec fichiers

l Tous les prédicats read, write et autres vus auparavant admettent un second argument : le flux identifiant le fichier.

l Ex : write(Flux, X). où Flux est un identificateur de fichierl Ex : read(Flux,X), get(Flux, X), get0(Flux,X)l at_end_of_stream : succès lorsque le dernier caractère du

stream a été lul Fermeture du fichier : prédicat close/1 qui prend en argument le

flux associé au fichier.

Exemple d'écriture

l Exemple d’utilisationecrire(T) :-

open(‘a.pl’, append, Flux), /* ouverture */

write(Flux, T), nl(Flux), /* écriture */

close(Flux). /* fermeture */

Exercice

l Affichage de tous les éléments d’une liste sur la console avec le prédicat affiche/1 dont l'argument est la liste à affichée. Il faut passer à la ligne à chaque élément.

Solution

l Affichage de tous les éléments d’une liste avec passage à la ligne

affiche([]).

affiche([T|Q]) :- write(T),nl,affiche(Q).

Partie 3-

Modularité

Intérêt

l Il est malcommode d'écrire un programme complexe dans un fichier unique

l On souhaite réutiliser certaines fonctionnalités dans des programmes différents sans avoir à les recopier à chaque fois.

l On souhaite distribuer certaines fonctionnalités à d'autres programmeurs

l Solution : Mettre une fonctionnalité dans un fichier unique

Charger un programme source

l Dans SWI-Prolog, on utilise le sous-menu « Consult »

l Il est aussi possible de taper dans l'interpréteur la commande ?- [nomFichier1].

l Possibilité de charger plusieurs fichiers

?- [nomFichier1, …, nomFichierN].l Possibilité d'effectuer ce même chargement dans

un programme source. :- [nomFichier1, …, nomFichierN].

Charger un programme source

l Dans SWI-Prolog, on utilise le sous-menu « Consult »

l Il est aussi possible de taper dans l'interpréteur la commande ?- [nomFichier1].

l Possibilité de charger plusieurs fichiers

?- [nomFichier1, …, nomFichierN].l Possibilité d'effectuer ce même chargement dans

un programme source (main.pl). :- [nomFichier1, …, nomFichierN].

Vérification avant chargement

l En utilisant la forme suivante, Prolog ne vérifie pas s'il a ou pas déjà chargé le fichier.

l :- [nomFichier1, …, nomFichierN].l Problème dans des programmes complexes avec

des fichiers très longs qui prennent du temps à charger

l Solution : ensure_loaded([nomFichier]).

Intérêt des modules

l Imaginons un prédicat défini deux fois de manière différente dans deux fichiers chargés

l L'interpréteur va demander si l'on souhaite conserver l'ancienne ou la nouvelle version

l Problème : on souhaite conserver les deux définitions car elles correspondent toutes deux à un contexte particulier (interne, externe)

l Solution 1 : renommer un des prédicatsl Solution 2 : Utilisation des modules pour cacher

certains prédicats

l Imaginons un prédicat défini deux fois de manière différente dans deux fichiers chargés

l L'interpréteur va demander si l'on souhaite conserver l'ancienne ou la nouvelle version

l Problème : on souhaite conserver les deux définitions car elles correspondent toutes deux à un contexte particulier (2 utilisations internes)

l Solution 1 : renommer un des prédicatsl Solution 2 : Utilisation des modules pour cacher

certains prédicats

Utilisation des modules

l Déclaration des modules en tête du fichier:l :- module(nomModule,ListePredicatsExportes)l Exemple :

l :- module(affichage, [afficherCarre/2]).

l Les prédicats exportés sont « publiques »l Les prédicats non exportés sont « privés »l Chargement de modules grâce à au prédicat

« use_module »l :- use_module(affichage).

Utilisation des modules

l Déclaration des modules en tête du fichier:l :- module(nomModule,ListePredicatsExportes)l Exemplel :- module(affichage, [afficherCarre/2]).l Les prédicats exportés sont « publiques »l Les prédicats non exportés sont « privés »l Chargement de modules grâce à au prédicat

« use_module »l :- use_module(affichage).

Librairies

l Chaque implémentation de Prolog fournit en général un certain nombre de prédicats prédéfinis

l SWI-Prolog en charge automatiquement certains mais pas tous

l Possibilité de charger ces librairies prédéfinies avec la commande use_module, mais en précisant que ce sont des librairies. Expl :

l :- use_module(library(csv)).l Ces librairies diffèrent avec les implémentations

Exercice

l Vous disposez de deux fichiers sources : 'main.pl' qui est votre programme principale et 'fichier.pl' dans lequel vous avez défini les prédicats ecrire/1, lire/1, ecrire/2, lire/2 qui vous permettent de lire et écrire dans des fichiers. Vous ne souhaitez utilisez que les prédicats ecrire/1 et lire/1 dans le programme principal. Utilisez les modules pour implémenter ce comportement

Solution

l Dans 'fichier.pl' :

:- module(fichier, [ecrire/1, lire/1]).l Dans 'main.pl' :

:- use_module(fichier).

Partie 4-

Création dynamique

Listing

l listing : liste tous les faits et règles de la base de connaissance

l listing(Pred) : liste tous les prédicats ayant pour nom Pred dans la base de connaissance

l Utile pour savoir si vous avez bien chargé votre base

l SWI-Prolog charge automatiquement un certain nombre de prédicats au démarrage.

Assert

l Un prédicat particulier nommé « assert » permet de créer dynamiquement en mémoire de nouveaux faits ou de nouvelles règles.

l Exemples:l ?- assert(homme(louis)).l ?- assert(fait(not(idiot(jules)))).l ?- assert(intelligent(X):-fait(not(idiot(X)))).l ?- intelligent(A).

A = jules

Asserta - Assertz

l On peut insérer des faits (ou règles) en tête de la liste des faits (ou règles) par le prédicat asserta

l On peut insérer des faits (ou règles) en fin de la liste des faits (ou règles) par le prédicat assertz

:- asserta(homme(jean)).

Insère le fait homme(jean) en tête de la liste des faits nommés « homme »

:- assert(maxim(A,B,A):-A>B).

true.

:- asserta(maxim(A,B,B):-A=<B).

Programmation dynamique

l Cette possibilité de pouvoir construire des programmes dynamiquement est l’une des caractéristiques de l’Intelligence Artificielle

l Une autre possibilité de créer des programmes dynamiquement consiste à les produire dans un fichier de texte, puis à les charger dynamiquement par le prédicat consult.

l consult(load) : charge le fichier load ou load.pll Outil puissant mais complexe.