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