Intelligence Artificielle AI - Prolog : TP 2 Variables numériques & Récursivité
Télécharger PDFVariables numériques et récursivité en Prolog sous SWI-Prolog
En Prolog, l'écriture X = Y peut avoir différents comportements selon le statut des variables X et Y :
- Si X et Y sont liées, répondra
Yessi elles sont égales,Nosinon. - Si X est libre et Y est liée, propose comme solution X prenant la valeur de Y.
- Si X est liée et Y est libre, propose comme solution Y prenant la valeur de X.
- Si X et Y sont libres, génère une erreur (car il existe une infinité de solutions possibles).
Cependant, l'écriture X = Y + 1 (équivalent à Y + 1 = X) pose des problèmes. Il est obligatoire que Y soit liée, car Prolog ne peut pas inverser une équation. De plus, l'opérateur = ne calcule pas directement la valeur : il recopie simplement l'équation.
Par exemple, si Y vaut 23 et X est défini comme X = Y + 1, puis que l'on exécute write(X), le résultat sera 23+1 et non 24.
Opérateurs pour évaluer les expressions numériques
Pour résoudre ces limitations, Prolog définit deux autres opérateurs :
is: calcule (ou évalue) la valeur à droite (qui doit être liée) et instancie le résultat à la variable libre à gauche, ou la compare à la valeur liée de gauche. Exemple :X is 10 + 15instancie X à 25, ou répondYessi X vaut déjà 25.=:=: évalue les expressions à droite et à gauche, puis vérifie si les résultats sont égaux. Les deux arguments doivent être liés.
D'autres opérateurs de comparaison évaluent également les expressions des deux côtés :
\=(différent)<et><=et>=
Les opérateurs arithmétiques disponibles incluent : +, -, *, /, mod, **, sin, cos, log, etc.
Prédicats prédéfinis pour les variables numériques
Prolog propose plusieurs prédicats pour manipuler les variables numériques et effectuer des opérations arithmétiques :
var(X): vérifie si X est une variable non liée.nonvar(X): vérifie si X est une variable liée.plus(X, Y, Z): réussit si X, Y et Z sont des entiers relatifs vérifiantZ = X + Y.fois(X, Y, Z): réussit si X, Y et Z sont des entiers relatifs vérifiantZ = X * Y.div(X, Y, Z): réussit si X, Y et Z sont des entiers relatifs vérifiantZ = X / Y(quotient entier).between(X, Y, Z): réussit si X, Y et Z sont des entiers relatifs vérifiantX <= Z <= Y.
Exercices pratiques
Exercice 1
- Écrire un prédicat
mention(M)qui affiche la mention d'un étudiant selon sa moyenne M :- Note éliminatoire si
M = 0 - Médiocre si
M < 10 - Passable si
M < 12 - Assez bien si
M < 14 - Bien si
M < 16 - Très bien si
M >= 16
- Note éliminatoire si
- Écrire un programme qui affiche les solutions (X1 et X2) d'une équation du second degré (
A * X^2 + B * X + C = 0) en entrant les valeurs des variables A, B et C. - Écrire un programme qui, pour un but
affiche1(N), affiche les nombres de N à 0 dans l'ordre décroissant. - Écrire un programme qui, pour un but
affiche(N, Ordre), affiche les nombres de N à 0 selon l'ordre défini par le paramètre Ordre (croissant ou décroissant). - Écrire un prédicat
puissance(X, N, P)qui calculeXà la puissanceNet met le résultat dansP. Ce prédicat accepte les deuxième et troisième paramètres comme variables libres. - Écrire un programme qui, pour un but
fact(N, X), affiche les factoriels de 0 à N et enregistre la factorielle de N dans X.
Exercice 2
- Redéfinir le prédicat
plus(A, B, C)pour qu'il réussisse si C est égal à la somme de A et B. Il doit accepter au maximum une variable libre.- Exemple :
plus(10, 20, X)→X = 30 - Exemple :
plus(10, X, 30)→X = 20 - Exemple :
plus(X, 20, 30)→X = 10 - Exemple :
plus(10, 20, 30)→true - Exemple :
plus(10, 15, 30)→false
- Exemple :
- Redéfinir le prédicat
fois(A, B, C)pour qu'il réussisse si C est égal au produit de A et B. Il doit accepter au maximum une variable libre. Deux versions sont demandées :- Version 1 : en utilisant tous les opérateurs arithmétiques (
+, -, *, /, //). - Version 2 : en utilisant uniquement le prédicat
plus.
- Exemple :
fois(2, 3, X)→X = 6 - Exemple :
fois(2, X, 6)→X = 3 - Exemple :
fois(X, 3, 6)→X = 2 - Exemple :
fois(2, 3, 6)→true - Exemple :
fois(2, 3, 10)→false
- Version 1 : en utilisant tous les opérateurs arithmétiques (
- Redéfinir le prédicat
div(A, B, C)pour qu'il réussisse si C est égal au quotient de la division de A par B. Il doit accepter uniquement C comme variable libre, et utiliser uniquement le prédicatplus.- Exemple :
div(2, 3, X)→X = 0 - Exemple :
div(10, 3, X)→X = 3 - Exemple :
div(2, 3, 1)→false
- Exemple :
- Redéfinir le prédicat
between(A, B, C)pour qu'il réussisse si C est compris entre les valeurs de A et B. Il doit accepter uniquement C comme variable libre.- Exemple :
between(2, 6, X)→X = 2 ; X = 3 ; X = 4 ; X = 5 ; X = 6 - Exemple :
between(2, 6, 4)→true - Exemple :
between(2, 6, 10)→false
- Exemple :
FAQ
Quelle est la différence entre = et is en Prolog ?
= est un opérateur d'unification qui ne calcule pas les expressions, tandis que is évalue la valeur à droite et instancie le résultat à gauche.
Comment utiliser between pour générer une liste de nombres ?
Le prédicat between(A, B, C) peut être utilisé dans une clause avec un point-virgule (;) pour générer une succession de valeurs de A à B.
Pourquoi le prédicat div ne retourne-t-il que le quotient entier ?
Le prédicat div est conçu pour retourner uniquement le quotient entier de la division, conformément aux règles de Prolog pour les opérations arithmétiques sur les entiers.