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 :

petit projet Prolog


Sujet :

Prolog

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 899
    Par défaut petit projet Prolog
    bonjour,
    Voilà j'ai à écrire un petit projet en Prolog gérant une base de données d'agence de voyage avec un prédicat segment(Depart, Arrivée,Moyent, Cout) ou Depart est la ville de départ, Arrivée la ville d'arrivée, Moyen le moyen de transport, et Cout son prix.
    Pour les exemples on suppose la base de données :

    segment(paris,lyon,peniche,200).
    segment(paris,lyon,train,200).
    segment(lyon,marseille,train,750).
    segment(lyon,marseille,peniche,100).

    Je voudrais écrire un prédicat connection(D,A,X) qui vérifie qu'on peut aller de la ville D à la ville A en utilisant uniquement le moyen de transport X.
    Pour démarrer j'ai écris une règle simple qui fonctionne mais qui ne gère pas le "uniquement " moyen de transport :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    connection(D,A,X):-segment(D,A,X,C).
    en effet Prolog me réponds à cette requete :

    | ?- connection(paris,lyon,train).

    yes
    | ?-

    Et ça me vas pas car il existe un autre moyen de transport la péniche.
    Si quelqu'un a une idée ... merçi

  2. #2
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    not(P) :- call(P), !, fail. 
    not(P).
    segment(paris,lyon,peniche,200).
    segment(paris,lyon,train,200).
    segment(lyon,marseille,train,750).
    segment(lyon,marseille,peniche,100).
    connection(D,A,X):-segment(D,A,X,_).
    otherconnection(D,A,X):-segment(D,A,Y,_), not(Y == X), !.
    onlyconnection(D,A,X):-connection(D,A,X), not(otherconnection(D,A,X)).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    | ?- onlyconnection(paris, lyon, train).
     
    no

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 899
    Par défaut
    Citation Envoyé par JeitEmgie Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    not(P) :- call(P), !, fail. 
    not(P).
    segment(paris,lyon,peniche,200).
    segment(paris,lyon,train,200).
    segment(lyon,marseille,train,750).
    segment(lyon,marseille,peniche,100).
    connection(D,A,X):-segment(D,A,X,_).
    otherconnection(D,A,X):-segment(D,A,Y,_), not(Y == X), !.
    onlyconnection(D,A,X):-connection(D,A,X), not(otherconnection(D,A,X)).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    | ?- onlyconnection(paris, lyon, train).
    no
    MErçi pour ta réponse j'aurais 2 ou 3 questions par apport à ton code.
    Tout d'abord j'utilise GNU Prolog qui me réponds à cette requette :

    | ?- connection(paris,lyon,peniche).

    true ? ;

    no

    Simple petite différence avec true ?
    Bon ca c'est pas grave le résultat est le même...
    Ensuite j'aimerais que tu m'expliques pourquoi tu as mis au début de ton code ceçi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    not(P) :- call(P), !, fail. 
    not(P).
    C'est pour m'expliquer le fonctionnement du cut ? Ensuite quelle est l'utilité de call ?
    Enfin dans ta 2ème règle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    otherconnection(D,A,X):-segment(D,A,Y,_), not(Y == X), !.
    tu utilises un cut et j'aimerais que tu me confirmes ou pas : si je trouve une "otherconnection" le programme s'arrête et c'est échec sinon je continue et c'est success pour "onlyconnection" ?
    Merçi de me confirmer ou pas car j'ai quelques lacunes avec le cut.
    A + et merçi pour ton aide

  4. #4
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    le cut dans not et otherconnection ont le même but logique :

    on n'est pas interessé par toutes les propositions possibles qui vérifient le prédicat, d'un moment qu'il y en a une le prédicat est vérifié…

    dans le cas du not :
    si l'appel call(P) est vrai, peu importe le nombre de façon qu'il puisse être "vrai"… alors not(P) est faux…

    dans le cas du otherconnection :
    peu importe le nombre de "autre" connection, s'il y a en au moins une, le prédicat est vérifié…

    ce sont donc 2 cuts d'optimisation…


    Le "not" est là parce que tout simplement je ne me souvenais plus de la syntaxe de la négation par failure dans GnuProlog : vous pouvez mettre \+ à la place…

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    otherconnection(D,A,X):-segment(D,A,Y,_), \+ (Y == X), !.
    onlyconnection(D,A,X):-connection(D,A,X), \+ (otherconnection(D,A,X)).

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 899
    Par défaut ce fameux "cut" ...
    Bonsoir er merçi pour votre aide.
    Vous dites :

    "dans le cas du otherconnection :
    peu importe le nombre de "autre" connection, s'il y a en au moins une, le prédicat est vérifié…"


    J'ai testé la règle "otherconnection" avec et sans le cut le résultat est le même, je me permets de revenir dessus, pourriez-vous me dire que fais le cut exactement en cas d'échec et en cas de success
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    otherconnection(D,A,X):-segment(D,A,Y,_),Y\=X,!.
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    otherconnection(D,A,X):-segment(D,A,Y,_),Y\=X.
    Merçi

  6. #6
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    le cut empêche de réévaluer le prédicat (jusqu'au point où il se situe) dans le cas du backtracking…

    le résultat est le même oui évidemment…
    mais pas la vitesse …

    le cut sert à optimiser…

    si vous aviez des milliers de clauses vous verriez une différence dans la vitesse d'exécution…

    le cut empêche donc d'utiliser otherconnection dans un findall car il ne renverra jamais que la première qu'il trouve…

    question convention de nommage pour pourrier avoir un otherconnection sans cut (utilisable dans findall) et avec 4 arguments et un hasotherconnection avec le cut et les 3 arguments…

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    otherconnection(D,A,X,Y) :- segment(D,A,Y,_), \+ (Y == X).
    hasotherconnection(D,A,X) :- segment(D,A,Y,_), \+ (Y == X), !.

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 899
    Par défaut
    bsr et merçi pour votre réponse, je pense avoir saisi cette fois le sens du cut par contre je patoge un peu je n'arrive pas à faire tourner votre code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    segment(bordeaux,toulouse,peniche,200).
    segment(bordeaux,toulouse,train,200).
    segment(toulouse,marseille,train,750).
    segment(toulouse,marseille,peniche,100).
     
    connection(D,A,X):-segment(D,A,X,_).
    otherconnection(D,A,X):-segment(D,A,Y,_),Y\=X,!.
    onlyconnection(D,A,X):-connection(D,A,X),not(otherconnection(D,A,X)).
    En effet j'utilise GNU Prolog pour Windows, à la compilation pas de problème mais quand je lance :

    | ?- onlyconnection(bordeaux,toulouse,peniche).

    Prolog me réponds ce message plutôt aggacent :

    uncaught exception: error(existence_error(procedure,not/1),onlyconnection/3)

    Quand j'enlève le not là il tourne bien.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    onlyconnection(D,A,X):-connection(D,A,X),otherconnection(D,A,X).
    Savez vous comment exprimer le not sous GNU autrement ?
    Merçi

  8. #8
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    je vous l'ai dit plus haut :

    not() c'est \+ en gprolog

    relisez les posts précédents…

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 899
    Par défaut
    merçi pour votre réponse ok pardon j'avais pas bien vu ...
    Le but de ce projet est aussi de vérifier que l'on peut aller de D à A en utilisant le moyen de transport X.
    J'ai écrit cette règle qui fonctionne mais qui ne vérifie pas s'il existe un autre moyen, si vous avez une idée merçi de m'en faire part :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    segment(paris,lyon,train,200).
    segment(lyon,marseille,train,750).
    %segment(paris,lyon,peniche,150).
    segment(lyon,marseille,peniche,100).
    dblconn(D,A,X):-segment(D,A1,X,_),segment(A1,A,X,_),!.
    En effet (paris,lyon,marseille) par train fonctionne mais si je rajoute (paris,lyon,marseille) par peniche ça fonctionne aussi mais ça me dit pas que j'ai une autre possibilité.
    Merçi encore
    A +

  10. #10
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    segment(paris,lyon,peniche,200).
    segment(paris,lyon,train,200).
    segment(lyon,marseille,train,750).
    segment(lyon,marseille,peniche,100).
    segment(paris,marseille,avion,900).
     
    directconnectionby(D,A,X,L) :- segment(D,A,X,L).
    directconnectionby(D,A,X) :- segment(D,A,X,_).
    directconnection(D,A) :- segment(D,A,_,_).
     
    connectionby(D,A,X) :- directconnectionby(D,A,X).
    connectionby(D,A,X) :- directconnectionby(B,A,X), connectionby(D,B,X).
     
    dconnectionby(D,A,X,L) :- directconnectionby(D,A,X,L).
    dconnectionby(D,A,X,L) :- directconnectionby(B,A,X,L1), dconnectionby(D,B,X,L2), L is L1 + L2.
     
    sconnectionby(D,A,X,0) :- directconnectionby(D,A,X).
    sconnectionby(D,A,X,L) :- directconnectionby(B,A,X), sconnectionby(D,B,X,L1), L is L1 + 1.
     
    anyconnection(D,A) :- directconnection(D,A).
    anyconnection(D,A) :- anyconnection(D,B), directconnection(B,A).
     
    hasotherconnectionby(D,A,X) :- segment(D,A,Y,_), \+ (Y == X), !.
    otherconnectionby(D,A,X,Y) :- connectionby(D,A,Y), \+ (Y == X).
    otherdconnectionby(D,A,X,Y) :- directconnectionby(D,A,Y), \+ (Y == X).
    onlyconnectionby(D,A,X) :- connectionby(D,A,X), \+ (hasotherconnectionby(D,A,X)).
     
    allconnection(D,A,L) :- findall(X, connectionby(D,A,X), L).
    alldirectconnection(D,A,L) :- findall(X, directconnectionby(D,A,X), L).
    allotherconnection(D,A,M,L) :- findall(X, otherconnectionby(D,A,M,X), L).
    allotherdconnection(D,A,M,L) :- findall(X, otherdconnectionby(D,A,M,X), L).

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 899
    Par défaut
    merçi pour votre réponse.
    Juste une petite question par apport à votre code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    allconnection(D,A,L) :- findall(X, connectionby(D,A,X), L).
    Je suppose que la fonction findall permet de trouver toutes les occurences voulues en paramètres mais pouvez vous m'expliquer son fonctionnement car dans l'aide c'est pas trés clair.
    Merçi

  12. #12
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    Citation Envoyé par xeron33 Voir le message
    merçi pour votre réponse.
    Juste une petite question par apport à votre code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    allconnection(D,A,L) :- findall(X, connectionby(D,A,X), L).
    Je suppose que la fonction findall permet de trouver toutes les occurences voulues en paramètres mais pouvez vous m'expliquer son fonctionnement car dans l'aide c'est pas trés clair.
    Merçi
    une façon simple de dire est que findall répond "oui" pour vous chaque fois que le prédicat passé en paramètre 2 est vrai et collecte les réponses (les valeurs prises par le paramètre 1) dans le paramètre 3.

  13. #13
    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
    Par défaut
    Citation Envoyé par xeron33 Voir le message
    merçi pour votre réponse.
    Juste une petite question par apport à votre code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    allconnection(D,A,L) :- findall(X, connectionby(D,A,X), L).
    Je suppose que la fonction findall permet de trouver toutes les occurences voulues en paramètres mais pouvez vous m'expliquer son fonctionnement car dans l'aide c'est pas trés clair.
    Merçi
    Un lien sur findall : http://pcaboche.developpez.com/artic...l-bagof-setof/
    "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

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Petit projet RMI sous eclipse
    Par Goupil dans le forum API standards et tierces
    Réponses: 3
    Dernier message: 21/10/2008, 22h49
  2. Cherche tuteur pour encadrer un petit projet.
    Par mikaloop dans le forum Access
    Réponses: 11
    Dernier message: 05/03/2006, 18h15
  3. petit projet sur le port série et parallele
    Par pepper18 dans le forum C
    Réponses: 5
    Dernier message: 12/01/2006, 14h14
  4. Avis sur un petit projet
    Par nicolas66 dans le forum OpenGL
    Réponses: 10
    Dernier message: 02/02/2005, 00h27

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