TD1 - Mise À Niveau PROLOG: Exercice 1: Arbre Généalogique
TD1 - Mise À Niveau PROLOG: Exercice 1: Arbre Généalogique
Q2. Définir les relations de famille suivantes : sister, brother, son_of, mother_in_law, aunt.
Q3. Définir le prédicat parent. Comment peut-on reécrire le prédicat sibling maintenant ?
Q4. Définir le prédicat has_children et expliquer comment peut-on l’utiliser pour obtenir la liste de toutes
les personnes qui ont un enfant.
1
Q6. On veut rendre maintenant le prédicat married valide pour deux personnes étant mariées, et ce indé-
pendamment de l’ordre des arguments. Apporter les modifications nécessaires.
Q2. Définir le prédicat max_list(List, Max), qui unifie Max avec le maximum de la liste List.
Rappel : en PROLOG l’affectation n’existe pas, on utilise uniquement le concept d’unification.
[eclipse 5]: max_list([5,2,8,12,0], Max).
Max = 12
Q3. Définir les prédicats delete_elem et insert_elem.
[eclipse 6]: delete_elem(5, [6,5,4,3], X).
X = [6, 4, 3]
X = [5, 6, 4, 3]
X = [6, 5, 4, 3]
X = [6, 4, 5, 3]
X = [6, 4, 3, 5]
Q4. Définir le prédicat permutation(List, X), qui génère la liste de toutes les permutations possibles.
[eclipse 10]: permutation([1,2,3], X).
X = [1, 2, 3]
X = [2, 1, 3]
X = [2, 3, 1]
X = [1, 3, 2]
X = [3, 1, 2]
X = [3, 2, 1]
Q5. Définir le prédicat no_doubles(List, NDList), qui prend une liste List et génère une nouvelle liste
en enlevant tous les doublons.
[eclipse 11]: no_doubles([3,5,2,3,5,4,2,5,5], X).
X = [4, 2, 5, 3]
On va maintenant travailler avec des listes de couples (nombre, lettre) :
Q6.* Écrire le prédicat qui est valide uniquement si les deux couples passés en argument sont égaux.
2
eq_pairs(pair(1,a), pair(1,a)).
Q7. Écrire le prédicat zip(L1, L2, Res) qui unifie une liste d’entiers et une liste de caractères avec une
liste de couples.
Q8. Écrire le prédicat unzip(L, R1, R2) qui unifie une liste de couples avec une liste d’entiers et une
liste de caractères.
[eclipse 20]: unzip([pair(1, a), pair(2, b), pair(3, c)], Int, Alpha).
Int = [1, 2, 3]
Alpha = [a, b, c]
Q9.* Adapter les prédicats max_list et no_doubles aux listes de couples.
Exercice 3 : Quicksort
Le tri rapide (en anglais quicksort) est un tri fondé sur le paradigme “diviser pour régner”. Pour rappel, cet
algorithme se divise en trois etapes :
1. choisir un élément arbitraire du vecteur, que nous appelons élément pivot
2. réorganiser les éléments du vecteur de sorte que tous les éléments inférieurs ou égaux au pivot soient
à gauche du pivot et les éléments supérieurs au pivot à droite du pivot dans la liste
3. trier récursivement la partie gauche et la partie droite du vecteur
Q1. Écrire la fonction qui prend une liste d’entiers et un pivot P et qui produit deux listes : la première
contenant tous les éléments inférieurs ou égaux à P et la deuxième tous les élément supérieurs.
Smaller = [5, 3]
Greater = [10, 12]
Q2. Écrire l’algorithme de tri. Pour concaténer les listes, on pourra utiliser le prédicat append(?List1, ?List2, ?List3)
qui unifie Liste3 avec la concaténation des listes Liste1 et Liste2.
Q3. Est-ce que cette implémentation est efficace, par rapport à une implémentation classique en C ? Pour-
quoi ?
3
1. reporter la 1ère lettre du mot en fin de mot
2. rajouter aléatoirement un des suffixes “em”, “ji”, “oc” ou “muche”
3. remplacer la 1ère lettre du mot par la lettre ’l’.
Exemples :
[eclipse 9]: loucherbem([b,o,u,c,h,e,r], X).
X = [l, o, u, c, h, e, r, b, e, m]
X = [l, a, c, h, e, v, o, c]
S E N D
+ M O R E
= M O N E Y
Tous les nombres sont bien formés (aucun ne commence par 0).
On va utiliser l’approche “generate and test” : décrire la relation entre les variables et ensuite générer
toutes les combinaisons possibles d’entiers, jusqu’à trouver celle qui vérifie la relation. On pourra utiliser
le prédicat member(X, List), qui unifie X avec une valeur dans la liste List.
4
Ensuite, il faut définir le prédicat safe(State) qui vérifie si un état est valide (le loup ne peut pas manger
la chèvre et la chèvre ne peut pas manger le chou).
La dernière étape consiste à définir le prédicat solution(Config, MoveList). Qui à partir d’une confi-
guration initiale cherche une liste de transitions menant à la configuration gagnante.
Remarque : on pourra fixer la taille de la solution recherchée en appliquant à MoveList le prédicat length(MoveList,
X), où X est la taille souhaitée.
En TP
On utilise ECLi PSe , un langage de programmation par contraintes basé sur PROLOG.
Un première liste de commandes :
Lancement/execution :
eclipse : pour lancer ECLi PSe en ligne de commande
[nom_module]. : charger/recharger le module nom_module en ECLi PSe
halt. : arrêt d’ ECLi PSe
Tracer l’exécution :
trace/notrace : active/desactive l’exécution pas à pas
spy(predicate_name/arity) : trace pas à pas l’exécution du prédicat predicate_name
Modules :
:- module(name). : au début d’un fichier, il définit le module name.
:- use_module(name). : permet d’importer le module name à l’intérieur d’un autre module.
:- export(name/arity). : rend la fonction name visible à l’extérieur du module.
Pour plus d’informations, il y a le tutoriel d’ECLi PSe .