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 :

Listes en Prolog


Sujet :

Prolog

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2013
    Messages : 16
    Points : 9
    Points
    9
    Par défaut Listes en Prolog
    Bonjour,

    Je suis actuellement en cours d'apprentissage du langage Prolog et disons que je rame un peu (beaucoup).
    Je dois réaliser un prédicat qui compte le nombre d'entiers dans une liste. Donc par exemple nb_int([1,g,2,2.3,d], R), R=2.
    Seulement je n'y arrive pas. Ca doit être tout bête mais impossible d'y arriver.

    J'en suis là :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    nb_int([], 0).
    nb_int([integer(X)], 1).
    nb_int([integer(X)|Y], 1).
    nb_int([X|Y], R):- nb_int(Y, R).
    et ce code me renvoie toujours R=0. Si quelqu'un peut m'aider.
    Ca ne passe jamais sur les lignes 2 & 3. En fait, je ne sais pas comment faire pour savoir si l'élément X est un entier ou non (mais je sais qu'il faut utiliser integer...).
    Merci d'avance et bonne journée,
    Zikee.

  2. #2
    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
    Non, ça ne fonctionne pas, car Prolog n'évalue pas ses arguments.
    Ceci fonctionne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    nb_int([], 0).
    nb_int([X|Y], R1):-
    	nb_int(Y, R),
    	(   integer(X)
    	->  R1 is R+1
    	;    R1 = R).
    "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

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2013
    Messages : 16
    Points : 9
    Points
    9
    Par défaut
    Merci beaucoup ça fonctionne maintenant.
    J'avais essayé quelque chose de la même forme mais ça ne fonctionne pas. Dans notre cours l'opérateur "implication" n'est, il me semble, pas mentionnée, je n'y avais donc pas pensé.

  4. #4
    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
    Ce n'est pas une implication, c'est un if/then/else.
    On peut le faire sans le if/then/else :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    nb_int([], 0).
    nb_int([X|Y], R1):-
    	integer(X),
    	nb_int(Y, R),
    	R1 is R+1.
     
    nb_int([X|Y], R):-
    	\+integer(X),
    	nb_int(Y, R).
    On peut rendre le code tail-recursif en utilisant la technique de l'accumulateur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    nb_int(L, R) :-
      nb_int(L, 0, R).
     
    nb_int([], R, R).
    nb_int([X|Y], CR, FR):-
    	integer(X),
            CR1 is CR+1,
    	nb_int(Y, CR1, FR).
     
    nb_int([X|Y], CR, FR):-
    	\+integer(X),
    	nb_int(Y, CR, FR).
    "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

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2013
    Messages : 16
    Points : 9
    Points
    9
    Par défaut
    Que signifie la ligne "\+integer(X)" ?

  6. #6
    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
    \+ integer(X) réussit lorsque integer(X) échoue. C'est en quelque sorte la négation.
    Tout ce que je dis peut-être trouvé dans la doc de SWI-Prolog.
    "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

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2013
    Messages : 16
    Points : 9
    Points
    9
    Par défaut
    D'accord, merci.

    Maintenant j'essaie de trier une liste dans l'ordre croissant. Et comment dire... Ca ne se trie pas. Enfin si, seulement à certains endroits.

    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
    tri_croissant([],[]).
    tri_croissant([X], [X]).
     
    tri_croissant([X,Y], R):- X > Y,
    		R = [Y,X].
     
    tri_croissant([X,Y], R):- X < Y,
    		R = [X, Y].
     
    tri_croissant([X,Y|Z], R):- X < Y,
    		tri_croissant([Y|Z], R1),
    		R = [X|R1].
     
    tri_croissant([X,Y|Z], R):- X > Y,
    		tri_croissant([X|Z], R1),
    	        R = [Y|R1].
    Donc si vous pouvez m'aider...
    Vraiment pas évident à intégrer ce langage...

    Merci d'avance

  8. #8
    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
    Le problème est que l'algo est faux.
    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    tri_croissant([X,Y|Z], R):- X < Y,
    		tri_croissant([Y|Z], R1),
    		R = [X|R1].
    Que se passe-t-il si dans Z il y a un élément plus petit que X ?
    Un tri assez simple à implémenter est le tri par insertion.

    Vraiment pas évident à intégrer ce langage...
    Comme disait quelqu'un , quand on commence Prolog, on commence par oublier tout ce qu'on sait de la prog.
    "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

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2013
    Messages : 16
    Points : 9
    Points
    9
    Par défaut
    J'ai finalement réussi. Je me suis servi d'un prédicat ajout_trie([X|Y], Element, R).

    Maintenant je suis sur un problème d'arbre. Je dois compter le nombre de noeuds dans cet arbre. Il est de la forme : [Valeur, SousArbreGauche, SousArbreDroit].

    J'ai donc fait un prédicat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    /* Nombre de noeuds dans un arbe */
    nb_noeuds([_], 1).
    nb_noeuds([], 0).
    nb_noeuds([_, [Y], [Z]], N):-
    	/*write(Y),*/
    	nb_noeuds([Y], N1),
    	nb_noeuds([Z], N2),
    	N is N1 + N2 + 1.
    Je fais des appels récursifs sur chaque sous-arbre pour compter le nombre de noeuds dans chacun d'entre eux. Seulement, avec l'exemple suivant :

    nb_noeuds([50, [20, [10, [], []], [25, [], [28, [], []]]], [75, [], [100, [80; [], []], []]]], R).
    J'ai R = 3. Or, ça devrait m'afficher R = 8.

    Merci d'avance pour votre aide...

  10. #10
    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
    Il me semble qu'il n'y a qu'un seul cas de base, l'arbre vide :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    nb_noeuds([], 0).
    nb_noeuds([_, Y, Z], N):-
    	nb_noeuds(Y, N1),
    	nb_noeuds(Z, N2),
    	N is N1 + N2 + 1.
    Attention, il y a une faute de frappe dans l'appel
    nb_noeuds([50, [20, [10, [], []], [25, [], [28, [], []]]], [75, [], [100, [80; [], []], []]]], R). :
    il y a un point virgule après 80.
    "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

Discussions similaires

  1. probleme avec les listes Swi prolog
    Par JemiliSourour dans le forum Prolog
    Réponses: 4
    Dernier message: 27/07/2010, 16h23
  2. Fichier .txt vers liste en Prolog
    Par Voltyr dans le forum Prolog
    Réponses: 7
    Dernier message: 24/12/2009, 11h12
  3. Liste en Prolog
    Par acacia dans le forum Prolog
    Réponses: 7
    Dernier message: 10/09/2007, 08h23
  4. Tri d'une liste en Prolog
    Par faressam dans le forum Prolog
    Réponses: 11
    Dernier message: 29/03/2007, 09h33

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