EMD 2 / 12-13 Enoncé 1) Donnez les formes normales, quand elles existent, des -expressions suivantes : a) (x. x 2) (y. + y 3) → (y. + y 3) 2 → + 2 3 → 5 b) ((x. y. x y) (x. y x)) 3 → (y'. (x. y x) y') 3) → (x. y x) 3) → (y 3) c) (x. y. + x ((x. * x y) 3) ) 1 5 → (y. + 1 ((x. * x y) 3) ) 5 → (+ 1 ((x. * x 5) 3) ) → (+ 1 (* 3 5) ) → (+ 1 15) → 16 d) (y. (x. + x (x 3) y) (y. * y 2) ) 5 → (x. + x (x 3) 5) (y. * y 2) → (+ (y. * y 2) ((y. * y 2) 3) 5) → (+ (* ((y. * y 2) 3) 2) 5) → (+ (* (* 3 2) 2) 5) → (+ (* 6 2) 5) → (+ 12 5) → 17 2) Que veut dire, en programmation fonctionnelle, qu'un programme P calcule partiellement une fonction f ? Quel est le lien avec la théorie du point fixe ? - Un programme P calcule partiellement une fonction f, si à chaque fois que P s'arrête, il retourne la même chose que f. - Dans la théorie du point fixe, l'espace des fonctions, ordonné par la relation « moins définie que » est inductif et tout programme récursif (fonctionnel) peut être vu comme étant une équation à point fixe, dont les solutions autre que la plus petite, sont les fonctions partiellement calculées par le programme. 3) Donnez en Prolog, un prédicat 'SubSetSum(L1, L2, S)' qui sera évalué à vrai si tous les éléments de la liste L2 se trouvent dans la liste L1 et leur somme (les éléments de L2) vaut S. L1 et L2 étant des listes d'entiers. Exemple : SubSetSum( [4,5,3,1,7], [1,5], 6) est vrai. SubSetSum( _, [], 0). SubSetSum( L1, [X|L2], S ):App(X, L1), S2 = S-X, SubSetSum( L1, L2, S2 ). App( X, [X|_] ). App( X, [_|L] ):- App( X,L). 4) On décide de représenter un graphe non orienté en Prolog par le terme structuré suivant : g(V,E), tel que V est une liste de sommets et E une liste d'arêtes. Chaque arête est représentée par un terme structuré a(X,Y) où X et Y sont des sommets. Les sommets sont représentés par des indices et sont donc des entiers. a) Donnez la représentation du graphe ci-dessous, sous forme de terme structuré: g( [1,2,3,4], [a(1,2), a(1,3), a(2,3), a(3,4)] ) 1 3 2 (Un qu'il 4 Donnez en Prolog, un prédicat 'connexe(G)' évalué à vrai si G représente un graphe non orienté connexe. graphe non orienté est connexe, si tous ses sommets sont connectés, c'est-à-dire existe une chaîne entre chaque couple de sommet.) connexe( G ) :G = g(V,_), V = [X|L], tester( G, X, L ). tester( _, _, [] ). tester( G, X, [Y|L] ) :chemin( X, Y, G, _, [] ), tester( G, X, L ). chemin( X, Y, G , [X,Y], Lv ) :voisin( X, Y, G ), notapp( Y, Lv). chemin( X, Y, G , [X|L], Lv ) :voisin( X, Z, G ), notapp( Z, Lv), chemin( Z, Y, G, L, [X|Lv] ). voisin( X, Y, g(V,E) ) :app( X, V ), app( Y, V ), app( a(X,Y), E ). voisin( X, Y, g(V,E) ) :app( X, V ), app( Y, V ), app( a(Y,X), E ). app( X, [X|_] ). app( X, [_|L] ) :- app( X, L ). notapp( _, [] ). notapp( X, [Y|L] ) :- X \== Y , notapp( X, L ). 5) Expliquez comment, en programmation logique, un problème peut-il être résolu avec un style purement déclaratif ? Lors du déroulement du processus de preuve avec la résolution, un certain nombre d'unifications sont automatiquement générées entre la dénégation et un des littéraux positifs des hypothèses. Comme les unifications sont en fait, des substitutions, donc des affectations de termes à des variables, leur enchaînement produit, implicitement, un programme procédural pour la résolution du problème initial.