| Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente |
| cnam:utc503:declarative:prolog [2023/11/26 17:51] – [Règles] jcheron | cnam:utc503:declarative:prolog [2023/12/07 01:30] (Version actuelle) – [Listes] jcheron |
|---|
| </WRAP> | </WRAP> |
| |
| | Soient les règles suivantes : |
| | |
| | * « Anne aime tous les rois ». |
| | * « Arthur aime ceux qui l’aiment ». |
| | * « Jean aime toutes les femmes ». |
| | * « Paul aime les gens qui aiment la biere et Londres ». |
| | * « Il faut taxer les riches ». |
| | * « Marie aime toutes les villes ». |
| | |
| | Elles s'écriront en Prolog : |
| | <sxh prolog> |
| | aime(anne, UnRoi) :- roi(UnRoi, Pays). |
| | aime(arthur, X) :- aime(X, arthur). |
| | aime(jean, X) :- femme(X). |
| | aime(paul, X) :- aime(X, biere), aime(X, londres). |
| | taxer(UnePersonne) :- riche(UnePersonne). |
| | aime(marie, UneVille) :- ville(UneVille). |
| | </sxh> |
| | |
| | ==== Exercices ==== |
| | |
| | Soit la base de connaissances : |
| | <sxh prolog> |
| | masculin(hubert). |
| | masculin(denis). |
| | masculin(robert). |
| | masculin(joseph). |
| | masculin(georges). |
| | masculin(henri). |
| | feminin(nelly). |
| | feminin(martine). |
| | feminin(anne). |
| | feminin(jeanne). |
| | % parent(X,Y) est vrai si Y est le pere/mere de X |
| | parent(robert, hubert). |
| | parent(robert, georges). |
| | parent(robert, anne). |
| | parent(joseph, nelly). |
| | parent(hubert, denis). |
| | parent(hubert, martine). |
| | parent(nelly, denis). |
| | parent(nelly, martine). |
| | parent(georges, jeanne). |
| | parent(georges, henri). |
| | </sxh> |
| | <WRAP TODO> |
| | Définissez une règle pere(Pere, Enfant) qui est vrai si Pere est le père de Enfant. |
| | |
| | Faites de même avec la relation mere(Mere, Enfant). |
| | |
| | Définissez une règle fils(Fils, Parent) qui est vrai si Fils est le fils du parent Parent. Faites de même avec la relation fille(Fille, Parent). |
| | |
| | Définissez les règles |
| | * frere(Frere, X) qui est vrai si Frere est le frère de X. |
| | * oncle(Oncle, X) qui est vrai si Oncle est l’oncle de X. |
| | * neveu(Neveu, X) qui est vrai si Neveu est le neveu de X. |
| | * grand-pere(GP, X) qui est vrai si GP est le grand-père de X. |
| | </WRAP> |
| | ==== Exercice ==== |
| | |
| | On considère les affirmations suivantes (dues à Lewis Carroll, dans La logique symbolique) : |
| | - Tous les canards vivant dans ce village qui sont marqués d’un B appartiennent à Mrs. Bond. |
| | - Les canards vivant dans ce village ne portent pas de col en dentelle, à moins qu’ils n’appartiennent à Mrs. Bond. |
| | - Mrs. Bond ne possède aucun canard gris vivant dans ce village. |
| | <WRAP TODO>Traduisez ces affirmations sous la forme de règles Prolog dans un fichier canards.pl en vous appuyant sur les constantes **ce_village** et **mrs_bond**, les prédicats unaires **canard** et **porte_col_dentelle**, et les prédicats binaires **appartient_a**, **marque_avec**, **pas_gris** et **vit_dans** (et aucun autre prédicat ou symbole de fonction). |
| | </WRAP> |
| | <WRAP TODO> |
| | À présent, on considère George, un canard de ce village marqué AB et qui porte un col de dentelles et Augusta, une cane de ce village marquée B. Ajoutez les faits correspondant à votre fichier. |
| | </WRAP> |
| | <WRAP TODO> |
| | On se demande quels sont les canards de la base qui ne sont pas gris. Utilisez l’interprète Prolog pour répondre à cette question. |
| | </WRAP> |
| | |
| | ==== Récursivité ==== |
| | === Liste des nombres de N à 1 === |
| | <sxh prolog> |
| | /* de N à 1 */ |
| | decroissant(0). |
| | decroissant(N) :- N>0, write(N), nl, N1 is N-1, decroissant(N1). |
| | </sxh> |
| | === Liste des nombres de 1 à N === |
| | <sxh prolog> |
| | /* de 1 à N */ |
| | croissant(0). |
| | croissant(N) :- N>0, N1 is N-1, croissant(N1), write(N), nl. |
| | </sxh> |
| | |
| | === Nombres pairs === |
| | |
| | <sxh prolog> |
| | pair(0). |
| | pair(X) :- X>0, X2 is X-2, pair(X2). |
| | </sxh> |
| | |
| | === Somme des N premiers entiers === |
| | |
| | <sxh prolog> |
| | som(0,0). |
| | som(N,X) :- N>0, N1 is N-1, som(N1,X1), X is N+X1. |
| | </sxh> |
| | |
| | === Factorielle === |
| | <sxh prolog> |
| | fact(0,1). |
| | fact(N,X) :- N>0, N1 is N-1, fact(N1,X1), X is N*X1. |
| | </sxh> |
| | |
| | === Suite de Fibonacci === |
| | <sxh prolog> |
| | fibo(1,1). |
| | fibo(2,1). |
| | fibo(N,X) :- N>2, U is N-1, V is N-2, fibo(U,U1), fibo(V,V1), |
| | X is U1+V1. |
| | </sxh> |
| | |
| | ==== Listes ==== |
| | <WRAP info> |
| | En Prolog, Les tableaux sont des listes, dans lesquelles les indices des éléments ne sont pas disponibles. |
| | |
| | En revanche, une liste L peut toujours être décomposée en L=[E|R] où E est le premier élément de la liste (E n'est pas une liste) et où R est le reste de la liste L (R est une liste : c'est en fait la tranche de L qui démarre apres E). |
| | |
| | La liste vide est []. |
| | </WRAP> |
| | |
| | === Affichage === |
| | |
| | <sxh prolog> |
| | affiche([]). |
| | affiche([X|R]) :- write(X), nl, affiche(R). |
| | </sxh> |
| | |
| | === Premier élément === |
| | |
| | <sxh prolog> |
| | premier([X|_],X). |
| | </sxh> |
| | |
| | === Dernier élément === |
| | |
| | <sxh prolog> |
| | dernier([X],X). |
| | dernier([_|L],X) :- dernier(L,X). |
| | </sxh> |
| | |
| | === Compte === |
| | |
| | <sxh prolog> |
| | compte([],0). |
| | compte([_|R],N) :- compte(R,N1), N is N1+1, N>0. |
| | </sxh> |
| | |
| | === Somme === |
| | |
| | <sxh prolog> |
| | somme([],0). |
| | somme([X|R],N) :- somme(R,N1), N is N1+X. |
| | </sxh> |
| | ==== Sudoku ==== |
| | |
| | === Base de connaissances : === |
| | |
| | <sxh prolog;title:sudoku.pl> |
| | sudoku(Rows) :- |
| | length(Rows, 9), maplist(same_length(Rows), Rows), |
| | append(Rows, Vs), Vs ins 1..9, |
| | maplist(all_distinct, Rows), |
| | transpose(Rows, Columns), |
| | maplist(all_distinct, Columns), |
| | Rows = [As,Bs,Cs,Ds,Es,Fs,Gs,Hs,Is], |
| | blocks(As, Bs, Cs), |
| | blocks(Ds, Es, Fs), |
| | blocks(Gs, Hs, Is). |
| | blocks([], [], []). |
| | blocks([N1,N2,N3|Ns1], [N4,N5,N6|Ns2], [N7,N8,N9|Ns3]) :- |
| | all_distinct([N1,N2,N3,N4,N5,N6,N7,N8,N9]), |
| | blocks(Ns1, Ns2, Ns3). |
| | problem(1, [[_,2,7,1,_,_,_,_,8], |
| | [_,_,_,_,7,_,_,4,2], |
| | [_,8,_,_,_,_,_,9,_], |
| | [1,_,_,_,_,_,6,_,_], |
| | [5,_,_,_,2,_,_,_,_], |
| | [_,_,_,_,8,5,_,_,_], |
| | [_,7,1,4,_,_,_,_,_], |
| | [_,4,_,2,6,_,_,_,_], |
| | [_,_,_,_,_,_,_,_,3]]). |
| | |
| | </sxh> |
| | |
| | === Résolution === |
| | |
| | <sxh prolog;gutter:false> |
| | use_module(library(clpfd)). |
| | [sudoku]. |
| | problem(1, Rows), sudoku(Rows), maplist(portray_clause, Rows). |
| | </sxh> |