Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 5 sur 5
  1. #1
    Membre à l'essai
    Homme Profil pro Ali
    Étudiant
    Inscrit en
    octobre 2012
    Messages
    44
    Détails du profil
    Informations personnelles :
    Nom : Homme Ali
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : octobre 2012
    Messages : 44
    Points : 22
    Points
    22

    Par défaut Probleme prolog fonction séparation liste

    Bonjour,
    je vous expose mon probleme:
    Mon but est d'écrire une fonction qui sépare une liste L en deux sous listes L1 et L2, L1 étant la suite des premiers éléments de L égaux, L2 étant le reste, par exemple:
    L = [a,a,a,a,n,j].
    L1=[a,a,a,a],
    L2=[n,j].

    Voici mon code
    Code :
    1
    2
    3
    4
    5
    recup([X|L],L1,L2):- recup(L,L1,L2,[X],X).
    recup([],A,[],A,B).
    recup([X|L],[X|Pile],K,Pile,Cri):- X = Cri,Pile2=[X|Pile], recup(L,F,K,Pile2,Cri),!.
    recup([X|L],A,B,Pile,Cri):-not(X=Cri),A = Pile, B=[X|L],!.
    Malheuresement, ça ne fait pas tout à fait ce que je désire, par exemple pour L= [a,a,a,a,b,j,k], j'ai L1= [a,a] et L2= [b,j,k].

    Je suis prêt à donner des explications si ce n'est pas clair.

  2. #2
    Membre à l'essai
    Homme Profil pro Ali
    Étudiant
    Inscrit en
    octobre 2012
    Messages
    44
    Détails du profil
    Informations personnelles :
    Nom : Homme Ali
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : octobre 2012
    Messages : 44
    Points : 22
    Points
    22

    Par défaut

    J'ai réussi à faire un truc qui fonctionne, je met le code:

    Code :
    1
    2
    3
    4
    5
    6
    7
    recup2([X|L],K):- recup2(L,K,X).
    recup2([],[],_).
    recup2([X|L],K,Cri):- X = Cri,recup2(L,K,Cri),!.
    recup2(A,A,_).
    
    recup(L,L1,L2):-recup2(L,L2), append(L1,L2,L),!.
    Par contre j'ai tellement souffert sur la première question que j'aimerais pas mal avoir une idée de pourquoi ça ne fonctionnait pas.

  3. #3
    Rédacteur/Modérateur
    Avatar de Trap D
    Inscrit en
    septembre 2003
    Messages
    4 515
    Détails du profil
    Informations forums :
    Inscription : septembre 2003
    Messages : 4 515
    Points : 5 403
    Points
    5 403

    Par défaut

    Euh, ta deuxième version ne fonctionne pas :
    recup( [x, y,a,a,t, u,a,a,b,j,k], L1, L2).
    L1 = [x],
    L2 = [y,a,a,t,u,a,a,b,j,k].
    Qu'en est-il de liste de ce type ?
    recup([a,a,a, b,b, c,d,e], L1, L2) ??
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : Intérieur avec jeune femme de Vilhelm Hammershoi

  4. #4
    Membre à l'essai
    Homme Profil pro Ali
    Étudiant
    Inscrit en
    octobre 2012
    Messages
    44
    Détails du profil
    Informations personnelles :
    Nom : Homme Ali
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : octobre 2012
    Messages : 44
    Points : 22
    Points
    22

    Par défaut

    Ma deuxieme version fonctionne, c'est bien ce que je voulais.

    Pour recup([a,a,a, b,b, c,d,e], L1, L2) ,
    il faut:
    L1=[a,a,a],
    L2=[b,b,c,d,e].

    Le but est de récupérer dans L1 tous les éléments tant qu'ils sont égaux au tout premier élément, et dans L2 la suite de la liste à partir du premier élément différent du premier.


    Donc ma deuxième version fonctionne correctement; la première version devrait aussi d'après moi, mais ce n'est pas le cas

  5. #5
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    juin 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Enseignement

    Informations forums :
    Inscription : juin 2013
    Messages : 10
    Points : 20
    Points
    20

    Par défaut

    Réponse tardive, sur un sujet ancien et donc à forte probabilité d'être clos, mais réponse tout de même concernant les interrogations sur le code suivant :
    Code :
    1
    2
    3
    4
    recup([X|L],L1,L2):- recup(L,L1,L2,[X],X).
    recup([],A,[],A,B).
    recup([X|L],[X|Pile],K,Pile,Cri):- X = Cri,Pile2=[X|Pile], recup(L,F,K,Pile2,Cri),!.
    recup([X|L],A,B,Pile,Cri):-not(X=Cri),A = Pile, B=[X|L],!.
    Il peut sembler difficile de trouver l'erreur, mais pourtant elle est bien là, visible et sous vos yeux. Je vous propose de commencer par donner les définitions du prédicat recup() que vous avez écrit :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    %recup/3
    % recup(ListeAetudier,Liste1,Liste2) 
    %     ListeAetudier = la liste que l'on souhaite traiter
    %     Liste1 = La liste n caractères identiques au premier
    %     Liste2 = La liste restante
    recup([X|L],L1,L2) :- 
         recup(L,L1,L2,[X],X).
    
    % recup/5
    % recup(ListeAetudier,Liste1,Liste2,Temp,Valeur)
    %     ListeAetudier = la liste que l'on souhaite traiter
    %     Liste1 = La liste n caractères identiques au premier
    %     Liste2 = La liste restante
    %     Temp = Le tampon pour former Liste1
    %     Val = La première valeur servant de comparaison
    recup([],A,[],A,B).
    recup([X|L],[X|Pile],K,Pile,Cri):- X = Cri,Pile2=[X|Pile], recup(L,F,K,Pile2,Cri),!.
    recup([X|L],A,B,Pile,Cri):-not(X=Cri),A = Pile, B=[X|L],!.
    J'ai marqué en orange les variables inutilisées (qui provoquent normalement des "warnings"). J'ai marqué en bleu et souligné l'origine de l'erreur avec en italique et en bleu la valeur associée.

    Si on exécute par exemple le programme à la main avec comme appel de départ :
    Code :
    recup([a,a,a,b],L1,L2).
    On obtient dès la deuxième ligne l'erreur :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    recup([a|[a,a,b]],L1,L2) 
    -> recup([a,a,b],L1,L2,[a],a).
        recup([a|[a,b]],[a|[a]],L2,[a],a)
            avec pour valeurs pour le deuxième prédicat recup/5 :
             * X = a
             * L = [a,b]
             * Pile = [a]
             * Cri = a
             * L1 = [X|Pile] = [a|[a]] = [a,a]
             * L2 = ?
    Et même s'il y a appel récursif, la valeur de L1 est déjà trouvée, s'il y a plus de deux caractères identiques au premier en comptant celui-ci, L1 vaudra toujours deux fois le premier caractère.

    Le problème est que vous avez mélangé votre accumulateur (que j'ai abusivement noté Temp dans la définition) avec la liste de retour Liste1. En effet, d'après la structure actuelle, c'est le premier ou le dernier prédicat recup/5 qui se chargeront de retourner les valeurs pour Liste1 et Liste2. Si on se contente juste de corriger le prédicat qui pose problème on obtient donc :
    Code :
    1
    2
    3
    4
    recup([X|L],F,K,Pile,Cri):- 
         X = Cri,
         Pile2=[X|Pile], 
         recup(L,F,K,Pile2,Cri),!.
    NB : De nombreuses simplifications sont possibles entre autre les X = Cri tout comme l'utilisation de Pile2 = ... ou de A = ... ou encore B = ...
    Le cut une fois la correction effectuée n'est pas utile

    Voici votre code après correction et simplification :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    recup([X|L],L1,L2) :- 
         recup(L,L1,L2,[X],X).
    
    recup([],A,[],A,_).
    recup([Cri|L],F,K,Pile,Cri):- recup(L,F,K,[X|Pile],Cri).
    recup([X|L],Pile,[X|L],Pile,Cri):- X \= Cri. 
    % Comprendre X \= Cri comme X différent de Cri 
    % tel que X ne s'associe pas avec Cri
    L'utilisation du prédicat déjà fourni : append/3 qui concatène deux listes aurait pu être envisagé pour résoudre le problème ... En effet, ListeAtraiter = L1 + L2 ... je vous mets en pièce-jointe une solution envisageable en utilisant le prédicat append.

    Cdt,

    --
    Pour les plus fainéants, l'utilisation du mode trace via par exemple cette commande aurait permis de trouver l'erreur
    Code :
    trace,recup([a,a,a,b],L1,L2).
    Fichiers attachés Fichiers attachés

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •