Station MinuitExplorer, comprendre, pratiquer

RAISONNEMENT — Raisonner et résoudreAutomne 2026

Semaine 7 — Logique et raisonnement : récursion et listes Prolog

5. Listes et prédicats fondamentaux

LECTURE 07 / 126 repèresCouverture déclarée complète

5. Listes et prédicats fondamentaux

5.1 Éléments, tête et queue

Une liste est une séquence ordonnée, qui peut contenir constantes, variables, termes et autres listes. Les doublons sont possibles. Elle s’écrit entre crochets : [a,b,3,c,pomme,'a b c'], [1,2,3], ou [] pour le vide.

Code (prolog) · sélectionner pour copier

?- [A,B,C] = [30,20,50].
A = 30, B = 20, C = 50.

?- [X|Y] = [30,20,50].
X = 30, Y = [20,50].

?- [a|Y] = [X,b,c].
X = a, Y = [b,c].

[A,B,C] exige exactement trois éléments. Dans [Tete|Queue], la tête est le premier élément et la queue contient tous les autres; pour une liste propre, cette queue est elle-même une liste. Ainsi [a] a pour tête a et pour queue []. La liste vide ne peut pas s’unifier avec une forme exigeant une tête.

Ce découpage permet un parcours sans connaître la longueur à l’avance : examiner la tête, puis appliquer le même prédicat à la queue. Il n’efface pas physiquement un élément de la liste d’entrée; chaque appel considère simplement une sous-structure.

5.2 Appartenance

Contrat : membre(X,L) est vrai si X s’unifie avec un élément de L. Voici les deux clauses du cours, avec _ pour les positions volontairement ignorées :

Code (prolog) · sélectionner pour copier

membre(X,[X|_]).
membre(X,[_|R]) :- membre(X,R).

La première clause reconnaît la tête. La seconde poursuit dans la queue. Aucun cas n’accepte [] : si une liste finie a été parcourue sans correspondance, le résultat est faux, et non une erreur d’exécution. Un avertissement de variable singleton dans la version du support signale une variable présente une seule fois; il n’invalide pas à lui seul la logique. Les _ ci-dessus évitent ces avertissements sans changer les contraintes utiles.

Tableau 1 — Requête · Résultat et raison
Requête Résultat et raison
membre(a,[a,b,c]) vrai : correspondance à la tête
membre(d,[a,b,c]) faux : le parcours atteint le vide
membre(a,[]) faux : aucune clause compatible
membre(X,[a,b,c]) X vaut successivement a, b, c par retour arrière
membre([a,b],[c,d,[a,b]]) vrai : la sous-liste entière est un élément de la liste externe

L’appartenance ne descend pas automatiquement dans les sous-listes. Des occurrences répétées peuvent aussi fournir plusieurs preuves. Le contrat simple vise les listes finies des exercices.

5.3 Longueur

Code (prolog) · sélectionner pour copier

longueur([],0).
longueur([_|R],N) :- longueur(R,M), N is M+1.

La liste vide a zéro élément. Pour une liste non vide, compter la queue puis ajouter 1. Le contenu de la tête n’intervient pas.

Code (text) · sélectionner pour copier

longueur([a,b,c],N)
  → longueur([b,c],M1)
    → longueur([c],M2)
      → longueur([],0)
    ← M2 = 0+1 = 1
  ← M1 = 1+1 = 2
← N  = 2+1 = 3

Les appels s’empilent jusqu’au vide; les valeurs nécessaires sont disponibles lors du dépilement. Placer N is M+1 avant le calcul de M risquerait une erreur d’instanciation.

Tableau 2 — Requête du cours · Réponse
Requête du cours Réponse
longueur([a],N) N=1
longueur([],X) X=0
longueur([a,b,c],X) X=3
longueur(K,0) Première réponse : K=[]
longueur([[a],[b,c]],X) X=2 : deux éléments au niveau externe
longueur([a,Y,c],X) X=3, même si Y est libre

La définition pédagogique utilisant is ne possède pas toutes les possibilités relationnelles du prédicat intégré length/2. Une première réponse inverse correcte, telle K=[], ne garantit pas une énumération inverse terminante.

5.4 Concaténation

Contrat : concat(L1,L2,L3) relie L3 à L1 suivie de L2.

Code (prolog) · sélectionner pour copier

concat([],L2,L2).
concat([X|R1],L2,[X|L3]) :- concat(R1,L2,L3).

Si L1 est vide, le résultat est L2. Sinon, la même tête X apparaît au début de L1 et du résultat; l’appel récursif relie le reste de L1, L2 inchangée et la queue du résultat. Les structures du résultat se construisent par unification avec le patron de la clause.

Pour vérifier concat([a],[b,c],[a,b,c]), la règle impose X=a, R1=[], et la queue de résultat [b,c]. Il reste concat([],[b,c],[b,c]), qui réussit par la base. Le nom local L3 dans la règle représente la queue du résultat de cet appel, et non une variable globale contenant toujours la liste entière.

Tableau 3 — Requête · Réponse
Requête Réponse
concat([a],[b,c],[a,b,c]) vrai
concat([d],[a,b,c],X) X=[d,a,b,c]
concat([],[a,b,c],L) L=[a,b,c]
concat([a],[],K) K=[a]
concat([d],K,[d,a,b,c]) K=[a,b,c]
concat(K,[a,b,c],[X,a,b,c]) K=[X]

Le même prédicat peut donc vérifier une concaténation, construire un résultat ou retrouver une partie manquante. L’ordre appartient au contrat : inverser simplement L1 et L2 donne généralement une autre liste. Une autre méthode évoquée oralement doit préserver cet ordre pour résoudre le même problème.

5.5 Prédicats prédéfinis et redéfinitions pédagogiques

Tableau 4 — Prédicat · Rôle
Prédicat Rôle
member(X,L) Appartenance; peut aussi énumérer les éléments
length(L,N) Relation entre liste et nombre d’éléments
append(L1,L2,L3) Concaténation de deux listes dans cet ordre
reverse(L,R) Ordre des éléments inversé
sort(L,S) En SWI-Prolog, tri selon l’ordre standard des termes et suppression des doublons

Les noms français membre, longueur, concat servent à étudier les mécanismes sans redéfinir les prédicats de bibliothèque. La remarque orale selon laquelle on peut trier dans les deux sens concerne le tri en général : sort/2 n’a pas d’argument de direction. On peut inverser une liste avec reverse/2. Cette précision de bibliothèque est vérifiée dans la documentation primaire SWI-Prolog; le cours ne demande pas de reconstruire ici un algorithme de tri ou d’inversion.

Longueur : descendre puis calculer au retourSur une liste finie, la queue est strictement plus courte. La base lie 0; chaque retour ajoute 1 avec is, après que le résultat récursif est connu.Appels : [a,b,c] → [b,c] → [c] → []Base : longueur([],0)Retours : 0 → 1 → 2 → 3
Longueur : descendre puis calculer au retour

Sur une liste finie, la queue est strictement plus courte. La base lie 0; chaque retour ajoute 1 avec is, après que le résultat récursif est connu.

Source : Ajout pédagogique du portail depuis le maître S07 du cours; aucune source brute diffusée. · 5. Listes

Retour au sommaire de l’unitéHaut de page
Récupérer manuellement les données locales

Copier séparément les données ci-dessous dans des fichiers texte avant de fermer la page ou de modifier le stockage. Une valeur illisible ou incompatible reste en place. Aucun effacement ni rétablissement écrasant n’est effectué automatiquement. L’export/import JSON est disponible sur la page Progression du thème. Cette récupération séparée reste utile pour une valeur brute ou un conflit.

Clé de ce cours : . Format v1 porté par cette clé; dates UTC et identifiants durables.

Si l’accès est refusé, la valeur persistée peut rester inaccessible. Réautoriser le stockage dans le navigateur puis rouvrir ce cours permet de la relire. Une réinitialisation exige une décision explicite après récupération; aucune commande de suppression n’est proposée ici. Les données restent sur cette origine et cet appareil, sans transfert automatique.