csi2520, hiver 2007 les entrées-sorties ecriture sur l'écran ou dans un fichier lecture à...

Post on 04-Apr-2015

105 Views

Category:

Documents

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

CSI2520, Hiver 2007

Les entrées-sorties

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

* write(1+2) affiche 1+2 * write(X). affiche la valeur courante de X sur le flot

de sortie courant (par défaut l'écran), * nl permet de passer à la ligne suivante.* writeln(X) :- write(X), nl.* tab tel que tab(N) affiche N espaces

CSI2520, Hiver 2007

Affichage

• Affichage de termes (suite) :* display/1 agit comme write/1 mais en affichant la

représentation sous forme d’arbre* Ex :

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

Affiche :

3+4

+(3,4)

YES

CSI2520, Hiver 2007

Lecture

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

* Il 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).

YES {X = a(1,2)}

CSI2520, Hiver 2007

Exemple

age(X, Y) :- write('Give the age of '), write(X), write(': '), read(Y).?- age(teddy, Z).Give the age of teddy: 22.Z = 22Yes

?- age(teddy, 22).Give the age of teddy: 23.No?- read(abc).:23.No?- read(X + Y).:2 + 3.X = 2Y = 3Yes

CSI2520, Hiver 2007

Un autre exemple

lire des expressions arithmétiques, les évaluer et les imprimer jusqu'à ce que l’utilisateur rentre « fin » au clavier.

calculateur :- repeat, % boucle read(X), % lecture

expression eval(X,Y), %

évaluation write(Y), nl, %

affichage Y = fin, !. %

condition d'arrêteval(fin, fin) :- !. % cas particuliereval(X, Y) :- Y is X. % calcul d’expressions

CSI2520, Hiver 2007

Le repeatLe predicat repeat laisse toujours un point de choix derrière lui.

repeat.repeat :- repeat.

Exemple d’utilisation :?- calculateur.: 2+3 . 5: 3+2*4 -1.10: fin.finYES

Autre exemple avec repeat

CSI2520, Hiver 2007

test :- repeat, write(‘SVP, entrer un nombre’), read(X), (X=:=42).

CSI2520, Hiver 2007

Ouvrir un fichier

– En écriture : * mode write : son contenu est effacé avant que Prolog y

écrive.

* mode append : Prolog écrira à partir de la fin du fichier.

– Ouverture d’un fichier : prédicat open/3 * argument 1 : nom du fichier

* argument 2 : mode d’ouverture write, append ou read

* argument 3 : variable qui va recevoir un identificateur de fichier appelé flux ou stream.

CSI2520, Hiver 2007

Lire et écrire

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

* Ex : write(Flux, X). où Flux est un identificateur de fichier

* Ex : read(Flux,X), get(Flux, X), get0(Flux,X)

* Fermeture du fichier : prédicat close/1 qui prend en argument le flux associé au fichier.

CSI2520, Hiver 2007

Exemple

ecrire(T) :-

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

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

close(Flux). (*fermeture*)

CSI2520, Hiver 2007

Les flots d’entrée et de sortie

• see(Filename), le fichier est l’entrée courante.• seen. La console redevient l’entrée courante.• tell(Filename), le fichier est la sortie courante.• told. La console redevient la sortie courante.

CSI2520, Hiver 2007

Les caractères

• put(CodeASCII) : imprime le caractère correspondant au code ASCII.

• get0(Code) : unifie la variable avec le code ASCII du caractère entré.

• get(Code) : même chose que get0, mais saute par-dessus les espaces.

Exemple interactif

CSI2520, Hiver 2007

capitale(ontario,toronto).capitale(quebec,quebec).capitale(cb,victoria).capitale(alberta,edmonton).capitale(terre-neuve,st-jean).capitale(nouvelle-ecosse,halifax).capitale(saskatchewan,regina).capitale(manitoba,winnipeg).capitale(nouveau-brunswick,fredericton).capitale(ipe,charlottetown).start:-write('Les Capitales du Canada'),nl,demander.demander:-write('Province? '),read(Province),reponse(Province).reponse(stop):-write('merci'),nl.reponse(Province):-capitale(Province,Ville),write('la capitale de '), write(Province),write(' est '),write(Ville),nl,nl,demander.

Exemple (suite)

CSI2520, Hiver 2007

?- start.Les Capitales du CanadaProvince? ontario.la capitale de ontario est toronto

Province? cb.la capitale de cb est victoria

Province? stop.mercitrue .

CSI2520, Hiver 2007

Les Listes

• Comme en programmation fonctionnelle, la liste est une structure de donnée de base :– [1, 2, 3, 4]– [] la liste vide ;– [Head | Tail] la tete et le reste de la liste ;– [1, 2, "trois"] une liste de 3 éléments ;– [1, 2 | Tail] une liste d’au moins deux éléments.

CSI2520, Hiver 2007

Format Tête et Queue?- [T | Q] = [1, 2, 3, 4].T= 1,Q= [2,3,4]?- [1 | [2,3,4]] = L.L= [1,2,3,4]?- [1,2,3 | [4]] = L.L= [1,2,3,4]?- [T | Q] = [1].T= 1,Q= []?- [T | Q] = [].no

CSI2520, Hiver 2007

Exemple

readline(Line) :- get0(Ch), readline(Ch, Line).

readline(10, []).readline(Ch, [Ch | RestOfLine]) :- Ch \= 10, get0(NextCh), readline(NextCh, RestOfLine).

Lire des caractères en créant une liste, jusqu’à la fin d’une ligne (code 10)

CSI2520, Hiver 2007

Construction de listes

cons(X, Y, [X|Y]).

?- cons(1, [2,3,4], L).L= [1,2,3,4]

?- cons(X, Y, [1,2,3,4]).X= 1,Y= [2,3,4]

?- cons(1, [2,3,4], [1,2,3,4]).yes

CSI2520, Hiver 2007

Concaténation de listes

notre-append([],Y,Y).notre-append([A|B],Y,[A|W]) :- notre-append(B,Y,W).

?- notre-append([1,2], [3,4], L).L= [1,2,3,4]?- notre-append(X, [3,4], [1,2,3,4]).X= [1,2]?- notre-append([1,2], [3,4], [1,2,3,4]).yes

CSI2520, Hiver 2007

Inversion de listes, version 1

notre-reverse([],[]).notre-reverse([H|T],L) :- notre-reverse(T,LL),

notre-append(LL,[H],L).

?- notre-reverse([1,2,3,4],L).L= [4,3,2,1]

?- notre-reverse(L,[1,2,3,4]).L= [4,3,2,1]

Inversion de listes, version 2

CSI2520, Hiver 2007

renverser([],L,L)-!.renverser([H|T],L,R):- renverser(T,[H|L],R).

notre-reverse([H|T],L,R) :- renverser(L,[],R).

Sans la coupe, il y aurait une boucle infinie après lapremière solution de:?- notre-reverse(L,[1,2,3,4]).

CSI2520, Hiver 2007

Appartenance à une liste

notre-member(X,[X|L]).notre-member(X,[Y|L]) :- notre-member(X,L).

CSI2520, Hiver 2007

Longueur d’une liste

notre-length([],0).notre-length([X|L],N) :- notre-length(L,NN), N is NN+1.

CSI2520, Hiver 2007

Insertion dans une liste

notre-insert(A,L,[A|L]).notre-insert(A,[X|L], [X|LL]) :- notre-insert(A,L,LL).

?- insert(c, [a, b], L).L = [c, a, b] ;L = [a, c, b] ;L = [a, b, c] ;no

CSI2520, Hiver 2007

Insertion dans une liste

?- insert(a, L, [b, a, d, a, f]).L = [b, d, a, f] ;L = [b, a, d, f] ;no

L’insertion et le retrait sont 2 concepts complémentaires!

CSI2520, Hiver 2007

Retrait dans une liste

notre-delete(R,[R|L],L).notre-delete(R,[X|LL], [X|L]) :- notre-delete(R,LL,L).

Retrait dans une liste

CSI2520, Hiver 2007

deleteall(X,[],[]).deleteall(X,[X|T],Result) :- deleteall(X,T,Result),!.deleteall(X,[H|T],[H|Result]) :- deleteall(X,T,Result).

?- deleteall(2,[1,2,4,3,2,6,2,2],L).L = [1, 4, 3, 6].

Qu’arrive-t-il si on retire la coupe?

CSI2520, Hiver 2007

Intersection entre listes

intersection( [], Ys, [] ).

intersection( [ X | Xs ], Ys, Zs ) :-

not member( X, Ys),

intersection( Xs, Ys, Zs ).

intersection( [ X | Xs ], Ys, [ X | Zs ] ) :-

member( X, Ys ),

intersection( Xs, Ys, Zs ).

CSI2520, Hiver 2007

Tri d’une liste

tri([],[]).tri([P|Q],T) :- partition(P,Q,G,D),

tri(G,GG), tri(D,DD),append(GG,[P|DD],T).

partition(P,[X|L],[X|PG],PD) :- X < P, partition(P,L,PG,PD).partition(P,[X|L],PG,[X|PD]) :- X >= P, partition(P,L,PG,PD).partition(P,[],[],[]).

CSI2520, Hiver 2007

Opérations répétitives

• Effectuer un traitement sur les éléments de listes

traite-liste([],[]).

traite-liste([X|L],[Y|T]) :- traite(X,Y), traite-liste(L,T).

somme(L,S) :- somme(L,0,S).

somme([X|L],T,S) :- TT is T+X, somme(L,TT,S).

somme([],S,S).

Les nombres premiers

• Générer tous les nombres premiers de 1 à N

• Crible d'Ératosthène:– Générer tous les entiers de 2 à N– Supprimer tous les multiples de 2, de 3, de 4,

etc. jusqu’à ce que le carré du plus petit entier soit plus grand que le plus grand entier.

CSI2520, Hiver 2007

Les nombres premiers

CSI2520, Hiver 2007

genereListe(0,[]).genereListe(N,[N|Xs]):- N > 0, N1 is N-1,genereListe(N1,Xs).

retireMultiple(X,[],[]).retireMultiple(X,[T|Q],Resultat) :- T>X, T mod X =:= 0, retireMultiple(X,Q,Resultat),!.retireMultiple(X,[T|Q],[T|Resultat]) :- retireMultiple(X,Q,Resultat).

retireTousLesMultiples(N,[],[]).retireTousLesMultiples(1,L,L).retireTousLesMultiples(N,Li,L):- N>1, retireMultiple(N,Li,LL), N1 is N-1, retireTousLesMultiples(N1,LL,L).

premiers(N,L):- genereListe(N,Li), retireTousLesMultiples(N,Li,L).

Inversion d’une liste (double récursion)

CSI2520, Hiver 2007

mirror([ ], [ ]). mirror([X|L1], L2) :-mirror(L1,L3), append(L3, [X], L2). % append will dig into the list a second time

Inversion d’une liste (avec accumulateur)

CSI2520, Hiver 2007

mirror2(Left, Right) :-  invert(Left, [ ], Right).invert([X|L1], L2, L3) :-       % the list is 'poured' invert(L1, [X|L2], L3).  % into the second argument invert([ ], L, L).  % at the deepest level, the result L is merely copied

CSI2520, Hiver 2007

Représentation des Listes

• Les listes peuvent être représentée avec le symbole fonctionnel binaire « . »– suite {e1, e2, …} ==> liste (e1.(e2.(…)))

• La liste vide est notée « nil ». Elle sert souvent à marquer la fin de liste.

• Exemples :– suite des variables X et Y => (X.Y)– suite {gateau, fruit, glace} =>(gateau.(fruit.(glace.nil)))

CSI2520, Hiver 2007

Représentation en arbre

• Exemples :

.

X Y

.

.

.

gateau

fruit

glace nil

CSI2520, Hiver 2007

Propriété fondamentale

• Une liste correspond au cas particulier ou les branches gauches sont toujours des feuilles.– On utilise le terme de peigne pour les désigner.

• Exercice : – résoudre l'équation X.Y = gateau.fruit.glace.nil– par identification on a la solution :

• {X = gateau; Y = fruit.glace.nil}

CSI2520, Hiver 2007

Propriété fondamentale (2)

• La notation X.Y représente une liste dont la tête (le 1er élément) est X et la queue (le reste de la liste) est Y.

• Cela constitue la base de l’utilisation des listes dans les programmes Prolog.

• Attention le terme X.Y n’est pas une liste mais plutôt une paire.

CSI2520, Hiver 2007

Prédicats avec nombre de paramètres variables

• Les villes d'une province:province(ontario,toronto,ottawa,hamilton,kitchener,london).province(quebec,montreal,quebec_city,sherbrooke,trois_rivie

res).province(new_brunswick,saint_john,moncton,fredericton).

• Il faut plutôt utiliser une liste (province/2):province(quebec, montreal.( quebec_city .(sherbrooke .(trois_rivieres.nil)))).province(new_brunswick, saint_john .(moncton .(fredericton.nil))).province(ontario, toronto.ottawa.hamilton.kitchener.london.nil).

CSI2520, Hiver 2007

Accès aux éléments d’une liste(1)

• En pratique, on représente une liste avec les '[ ]':montreal .(quebec_city .(sherbrooke .(trois_rivieres. nil)))

est représentée par:[montreal, quebec_city, sherbrooke, trois_rivieres]

• Pour avoir accés aux différents paramètres – on utilise le '|'.– On a donc [tete|queue].

CSI2520, Hiver 2007

Accès aux éléments d’une liste(2)

• Ainsi, on peut écrire:– [saint_john,moncton,fredericton] qui est equivalent a:– [saint_john | [moncton,fredericton]] qui est equivalent a:– [saint_john | [moncton | [fredericton]]] qui est equivalent a:– [saint_john | [moncton | [fredericton | [ ]]]] ou encore:– [saint_john, moncton | [fredericton]] ou:– [saint_john, moncton, fredericton | []]

• De manière générale:– [x | queue] une liste d’au moins un élément.– [x, y | queue] une liste d’au moins deux éléments.

CSI2520, Hiver 2007

Utilisation de memberRegle inProvince/2 qui retourne la province dans laquelle se trouve une ville X:

inProvince(X,P) :- province(P, L), member(X, L).

?- inProvince(ottawa, P). P = ontario ;

No

?- inProvince(V, new_brunswick).C = saint_john ;C = moncton ;C = fredericton ;No

Exemple du fermier

CSI2520, Hiver 2007

% etat(Fermier,Renard,Poule,Blé).

initial(etat([gauche, gauche, gauche, gauche])).final(etat([droite, droite, droite, droite])).

Exemple du fermier

CSI2520, Hiver 2007

traverse(etat([gauche,X,Y,Z]),etat([droite,X,Y,Z]), fermier_traverse).traverse(etat([droite,X,Y,Z]),etat([gauche,X,Y,Z]), fermier_revient).

traverse(etat([gauche,X,gauche,Z]),etat([droite,X,droite,Z]), fermier_amene_poule).traverse(etat([droite,X,droite,Z]),etat([gauche,X,gauche,Z]), fermier_ramene_poule).

traverse(etat([gauche, gauche, X, Y]),etat([droite, droite, X, Y]), fermier_amene_renard).traverse(etat([droite, droite, X, Y]),etat([gauche, gauche, X, Y]), fermier_ramene_renard).

traverse(etat([gauche, X, Y, gauche]),etat([droite, X, Y, droite]), fermier_amene_ble).traverse(etat([droite, X, Y, droite]),etat([gauche, X, Y, gauche]), fermier_ramene_ble).

Exemple du fermier

CSI2520, Hiver 2007

interdit(etat([X, Y, Y, _])) :- X \== Y.interdit(etat([X, _, Y, Y])) :- X \== Y.

riviere(P) :- initial(Depart), final(Arrivee), riviere_aux(Depart, Arrivee, [Depart], P).

Exemple du fermier

CSI2520, Hiver 2007

riviere_aux(A,A,_,[]).

% V sont les états déjà visitéesriviere_aux(A, B,V, P) :- traverse(A,C,Action), not(interdit(C)), not(member(C,V)), riviere_aux(C,B,[C|V],Plan), P = [Action | Plan].

CSI2520, Hiver 2007

Le prédicat setof

aime(jean,pomme).aime(marie,poire).

?- setof([X,Y],aime(X,Y),L).L=[[jean,pomme],[marie,poire]].

age(pierre,5).age(paul,7).age(henri,5).

?- setof(C,age(C,5),L).L=[henri,pierre].

bagof est similaire, sauf qu’il n’élimine pas les répétitions et ne tri pas les éléments.

Exemple

CSI2520, Hiver 2007

bag(2,4,1).bag(3,5,2).bag(7,8,2).bag(4,3,1).bag(5,2,4).bag(2,1,4).bag(2,2,4).bag(7,3,5).bag(7,3,3).

% bagof(Z,bag(X,Y,Z),B).% bagof(Z,(bag(X,Y,Z),Z>2),B).% bagof(Z,X^bag(X,Y,X),B).% setof(Z,X^bag(X,Y,X),B).% bagof(Z,X^Y^bag(X,Y,X),B).% findall(Z,bag(X,Y,X),B).

Exemple

CSI2520, Hiver 2007

connait(vincent,david).connait(vincent,antoine).connait(vincent,alex).connait(melodie,alex).connait(melodie,patrick).connait(patrick,melodie).connait(patrick,ahmed).connait(patrick,eddie).connait(patrick,david).

% setof(X,connait(X,Y),B).% setof(Y,connait(X,Y),B).% setof(Y,X^connait(X,Y),B).% bagof(Y,X^connait(X,Y),B).% setof([X,Y],connait(X,Y),B).

Exemple

CSI2520, Hiver 2007

age(vincent,8).age(melodie,4).age(patrick,3).age(ahmed,7).age(eddie,4).% setof(A,N^age(N,A),B).% setof(A,N^age(N,A),[T|Q]).% setof(A,N^age(N,A),[T|_]).% setof([A,N],age(N,A),[[_,J]|_]).% age(P,A1),\+((age(_,A2),A2<A1)).

top related