IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Prolog Discussion :

Probleme prolog fonction séparation liste


Sujet :

Prolog

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2012
    Messages : 51
    Points : 51
    Points
    51
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2012
    Messages : 51
    Points : 51
    Points
    51
    Par défaut
    J'ai réussi à faire un truc qui fonctionne, je met le code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    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 : La Madeleine à la veilleuse de Georges de La Tour

  4. #4
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2012
    Messages : 51
    Points : 51
    Points
    51
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    recup([a,a,a,b],L1,L2).
    On obtient dès la deuxième ligne l'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    trace,recup([a,a,a,b],L1,L2).
    Fichiers attachés Fichiers attachés

Discussions similaires

  1. Linked list: problemes avec fonction de recherche
    Par virtuadrack dans le forum C
    Réponses: 13
    Dernier message: 11/11/2007, 21h43
  2. Réponses: 17
    Dernier message: 24/03/2005, 12h24
  3. [langage] problème avec fonction read
    Par domidum54 dans le forum Langage
    Réponses: 2
    Dernier message: 30/03/2004, 20h42
  4. [VB6]Problème de fonction
    Par mustang-ffw02 dans le forum VB 6 et antérieur
    Réponses: 13
    Dernier message: 27/03/2004, 15h09
  5. Probleme de fonction
    Par yenna dans le forum ASP
    Réponses: 6
    Dernier message: 01/03/2004, 14h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo