demo3

Transcription

demo3
Le langage Prolog
(DemoIII)
Atefeh Farzindar
1
Table des matières
Demo 3
•
Cut (!)
•
If… Then… Else
•
Prédicats dynamiques
•
Le prédicat assert/1
•
Le prédicat retract/1
•
Solution des exercises
2
Cut (!)
• Le predicat prédéfini « ! » – le cut – permet de
changer le contrôle d’un programme et
d’empêcher le retour en arrière.
• Les conséquences du cut sont d’améliorer
l’efficacité et d’exprimer le déterminisme; mais il
revient à faire fonctionner le Prolog comme un
langage procédural et il peux introduire des
erreurs de programmation vicieuses. Il faut donc
l’utiliser avec parcimonie.
3
Utilisations de Cut
1. ! coupe toutes les clauses alternative en dessous de lui.
2. ! coupe tous les solutions alternatives de prédicats à gauche
,
3. En revanche, possibilité de retour arrière sur les sous buts à
la droite du cut.
P:- A1,...,Ai,!,Ai+1,...,An.
P:- B1,...,Bm.
4
Exemple 1.
appartient-a(titi,andré).
% BC
appartient-a(titi,marie).
femme(marie).
a(X,Y):-appartient-a(X,Y),femme(Y). %Règle
Question:
?- a(X,Y).
X=titi Y=marie
Comparer cette Règle avec cut:
a(X,Y):-appartient-a(X,Y),!,femme(Y).
?- a(X,Y).
no
5
Exemple 2.
B.C.
b(1).
b(2).
?- b(X), b(Y).
X = 1,Y = 1 ? ;
X = 1,Y = 2 ? ;
X = 2,Y = 1 ? ;
X = 2,Y = 2
?- b(X),b(Y),!.
X = 1,Y = 1
?- b(X),!,b(Y).
X = 1,Y = 1 ? ;
X = 1,Y = 2 ?
6
Règles pratiques d’utilisation
• Bonne utilisation : cuts verts (peut être enlevé sans
changer la logique d’une clause).
• Mauvaise utilisation : cuts rouges (changer la
logique d’une clause).
7
Cut Rouge et Vert
ifthenelse(P, Q, R):- P, Q.
%Vrai si P et Q sont vrais
ifthenelse(P, Q, R):- not P, R.
%Vrai si P et faux et R est vrai
Cut Vert:
ifthenelse(P, Q, R):- P, !, Q.
ifthenelse(P, Q, R):- not P, !, R .
Cut Rouge:
ifthenelse(P, Q, R):-P, !, Q.
ifthenelse(P, Q, R):-R.
8
Exemples de Cut rouge
1) Le minimum:
min(X, Y, X) :- X < Y, !.
min(_, Y, Y). %sinon
2) Prédicat « not »,
si P est vrais
alors retourner faux
sinon retourner vrai
not(p):-p,!,fail.
not(p).
%sinon
9
Prédicats dynamiques
Pour modifier la base de connaissance
pendant l’exécution du programme.
10
Manipuler l'ensemble des clauses
Ces prédicats engendrent un effet de bord, ce qu'ils font n'est
pas défait par un retour en arrière. Ces prédicats ont un
seul argument : une clause qui doit être mise entre
parenthèses si c'est une règle.
Déclaration des prédicats
:- dynamic (pred / arité).
Ou
:- dynamic (pred).
11
Le prédicat assert/1
assert(P) permet d’ajouter P à la base de données.
En fait, on ne sait pas si assert/1 ajoute au début ou à la
fin des faits. Il existe deux variantes :
•
On ajoute au début de la base de données avec
asserta/1
• On ajoute à la fin avec assertz/1
!
12
Exemple:
État de la base à l’instant 1:
| ?- personne(X).
! Error procedure user:personne/1 does not exist!
| ?- assert(personne(françois)),
assertz(personne(isa)),
asserta(personne(jean)).
yes
État de la base à l’instant 2
| ?- personne(X).
X = jean ? ;
X = françois ? ;
X = isa
13
Le prédicat retract/1
retract(P) permet de retirer P de la base de données.
• retract(P) cherche une clause dans la base de
connaissance qui s’unifie à P et l’efface.
• Si aucune clause ne s’unifie à P, retract(P) est évalue
à FAUX.
• retractall(P) Enlève TOUTES les clauses qui
s’unifient à P.
14
Exemple:
B.C.
:- dynamic lent/1.
rapide(anne).
lent(jean).
lent(alain).
?- assert((plusrapide(X,Y):-rapide(X),lent(Y))).
yes|
?- plusrapide(X,Y).
X = anne, Y = jean ? ;
?-retract(lent(X)).
X=jean
?- plusrapide(anne,X).
X=alain
15
Exemple (suite):
B.C.
:- dynamic lent/1.
rapide(anne).
lent(jean).
lent(alain).
?- assert((plusrapide(X,Y):-rapide(X),lent(Y))).
yes|
?- plusrapide(X,Y).
X = anne, Y = jean ? ;
?-retractall(lent(X)).
%retire predicat lent/1.
?- plusrapide(anne,X).
no
16
Solution des Eexercices
1. Effacer un element d'une liste
args: terme, liste, liste
2. Le dernier d'une liste non vide
args: liste, terme
3. Somme les elements d'une liste
args: liste de nombres, nombre
4. Reverse d'une liste
args: liste, liste
5. Trie d'une liste
args: liste de nombres, listeTriée
17
Effacer un element d'une liste
args: terme, liste, liste
delete(_,[],[]).
delete(X,[X|L],L1):-delete(X,L,L1).
delete(X,[Y|L],[Y|L1]):-delete(X,L,L1).
18
Le prédicat delete/3
Efface un élément d’une liste.
delete(Élément,Liste,ListeSansÉlément).
delete(_,[],[]).
%Cas trivial
%Cas où Élément est en tête de liste
delete(Élément, [Élément| Liste],
ListeSansÉlément):delete(Élément, Liste,
ListeSansÉlément).
%Cas où Élément n’est pas en tête de liste (filtrage avec les règles
précédentes.)
delete(Élément, [T|Liste],
[T|ListeSansÉlément]):delete(Élément, Liste,
ListeSansÉlément).
19
trace et notrace
| ?-trace.
| ?- delete(marie,[paul,marie,claud],ListeSansÉlément).
?
?
?
?
1 1 Call: delete(marie,[paul,marie,claud],_518) ?
2
2 Call: delete(marie,[marie,claud],_1057) ?
3
3 Call: delete(marie,[claud],_1057) ?
4
4 Call: delete(marie,[],_2025) ?
4 4 Exit: delete(marie,[],[]) ?
3 3 Exit: delete(marie,[claud],[claud]) ?
2
2 Exit: delete(marie,[marie,claud],[claud]) ?
1
1 Exit:
delete(marie,[paul,marie,claud],[paul,claud]) ?
ListeSansÉlément = [paul,claud]
| ?-notrace.
% Switched off
20
Le dernier d'une liste non vide
args: liste, terme
last([X],X).
last([_,X|L],Y):-last([X|L],Y).
21
Somme les elements d'une liste
args: liste de nombres, nombre
somme_list([],0).
somme_list([X|L],S):somme_list(L,SL),
S is SL+X.
22
Reverse d'une liste
args: liste, liste
reverse([],[]).
reverse([X|L],L1):reverse(L,L2),append(L2,[X],L1).
23
Trie par insertion d’une liste,
en ordre croissant
arg: liste de nombre, listeTriée
tri([],[]).
tri([H | T],Liste):tri(T,ListeTemp),
insert(H, ListeTemp, Liste).
24
Insertion d’une liste
insert(X, [] , [X]).
insert(X,[H | T1], [X,H | T1]):X<=H.
insert(X ,[H | T1] ,[H | T2]):X>H, insert(X, T1, T2).
25

Documents pareils