Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2757 connectés 

  FORUM HardWare.fr
  Programmation
  Divers

  [Prolog] débutant..

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[Prolog] débutant..

n°1540175
guiguivts
Posté le 08-04-2007 à 12:45:45  profilanswer
 

Salut!
 
j'ai un petit probleme prolog pas bien compliqué je pense mais je voie pas trop comment le résoudre  
 
C'est par rapport à ce prédicat :  
 

Code :
  1. deplacementdroiteinutile(X,Y) :- vision(A,B) , A is (X+1) , vue(A,B) , voisin(A,B,C,D) , vue(C,D).


 
En fait à partir d'une case de coordonnée X et Y je récupere les voisins à droite de cette case ( (X,Y+1) , (X,Y) , (X,Y-1) )  
 
J'en ai donc au maximums trois et à partir de ces trois nouvelles cases je récupère la liste des voisins de ces trois cases grace au prédicat voisin ( je suis sûr qu'il fonctionne je l'ai testé) et je voudrai que TOUS ces voisins soient vus (grace au prédicat vue(C,D) )  
 
Mon problème c'est que le prédicat déplacementdroiteinutile est vrai si il y a au moins un vue(C,D) vrai. or je voudrai qu'ils soient tous vrai mais je ne voie pas comment faire..
 
merci d'avance :mrgreen:


Message édité par guiguivts le 08-04-2007 à 12:46:16
mood
Publicité
Posté le 08-04-2007 à 12:45:45  profilanswer
 

n°1540178
guiguivts
Posté le 08-04-2007 à 13:08:46  profilanswer
 

En fait pour réduire le problème  
 
Pour ce prédicat :  
 

Code :
  1. toto :- case(X,Y) , paire(X).


 
Il me sort vrai car il existe une case de coordonnée X paire mais comment faire si je veux que toutes les cases aient X paire ?

Message cité 1 fois
Message édité par guiguivts le 08-04-2007 à 13:13:02
n°1540233
Trap D
Posté le 08-04-2007 à 16:24:56  profilanswer
 

guiguivts a écrit :

En fait pour réduire le problème  
 
Pour ce prédicat :  
 

Code :
  1. toto :- case(X,Y) , paire(X).


 
Il me sort vrai car il existe une case de coordonnée X paire mais comment faire si je veux que toutes les cases aient X paire ?

essaie :

Code :
  1. toto :-
  2.   forall(case(X,_), paire(X)).

Valalble avec SWI-Prolog.


Message édité par Trap D le 08-04-2007 à 16:25:32
n°1540258
guiguivts
Posté le 08-04-2007 à 18:17:47  profilanswer
 

J'ai trouvé un moyen détourner mais ça peut toujours servir merci ;)

n°1540376
guiguivts
Posté le 09-04-2007 à 12:07:39  profilanswer
 

Salut , toujours question de débutant :  
 
J'ai un damier de créer avec des cases des murs etc..
 
Je cherche à faire un prédicat me disant s'il y a un chemin entre une case et une autre :  
 
j'ai fait ça :  
 
existechemin(X,Y,A,B) :- voisin(X,Y,A,B).
existechemin(X,Y,A,B) :- existechemin(C,D,A,B) , voisin(X,Y,C,D).  
 
L'ennui c'est que bien sûr ça boucle.. je voie bien d'ou ça vient et comment corriger le problème en utilisant des listes. (enfin je pense..) mais est ce que c'est possible sans utiliser de listes ?  

n°1540417
Trap D
Posté le 09-04-2007 à 16:01:56  profilanswer
 

On touche aux graphes là, et sans les listes, je ne vois pas trop comment t'en sortir.

n°1540458
guiguivts
Posté le 09-04-2007 à 19:05:26  profilanswer
 

Oki j'ai trouvé des tutos intéressants je vais donc devoir me les taper :(  
 
J'ai déjà vu djikstra et autres en cours mais de là à les faire en prolog :( berk!

n°1540514
Trap D
Posté le 09-04-2007 à 21:53:26  profilanswer
 

guiguivts a écrit :

Oki j'ai trouvé des tutos intéressants je vais donc devoir me les taper :(  
 
J'ai déjà vu djikstra et autres en cours mais de là à les faire en prolog :( berk!

Pas berk  :??:  
Je t'invite à y réfléchir sérieusement, tu auras beaucoup à y gagner.
Cette adressepour te montrer ce qu'on peut faire

n°1541300
guiguivts
Posté le 11-04-2007 à 13:55:09  profilanswer
 

J'ai commencer à voir comment tester si un chemin existait en utilisant les listes mais je bloque. j'ai ça comme prédicat :  
 

Code :
  1. existechemin(X,Y,X,Y,_).
  2. existechemin(X,Y,A,B,_) :- voisin(X,Y,A,B),!.
  3. existechemin(X,Y,A,B,L) :- voisin(X,Y,C,D) , not(membre(case(C,D),L)) ,existechemin(C,D,A,B,[case(X,Y)|L]).
  4. membre(case(X,Y),[case(X,Y)|_]).
  5. membre(case(X,Y),[_|S]) :- membre(case(X,Y),S).


 
mais bien sûr ça ne fonctionne pas :)


Message édité par guiguivts le 11-04-2007 à 13:55:25
n°1541332
guiguivts
Posté le 11-04-2007 à 14:36:29  profilanswer
 

Etonnant j'ai rajouté dans mon troisieme existe chemin un prédicat estliste(L) décrit comme ça :  
 
estliste([]).
estliste([X|S]).
 
et ça fonctionne, à priori ça ne marche pas sans ça car on ne sait pas ce que c'est L mais j'avoue que je voie pas tres bien pourquoi !

mood
Publicité
Posté le 11-04-2007 à 14:36:29  profilanswer
 

n°1541361
guiguivts
Posté le 11-04-2007 à 15:13:36  profilanswer
 

Enfin de compte ça ne marche pas si le chemin n'existe pas, il boucle...

n°1541403
guiguivts
Posté le 11-04-2007 à 15:54:38  profilanswer
 

Y a pas des connaisseurs en prolog par ici ? :(

n°1541507
guiguivts
Posté le 11-04-2007 à 17:40:35  profilanswer
 

?

n°1541516
Pablo Escr​obarbe
Retour d'exil
Posté le 11-04-2007 à 17:48:14  profilanswer
 

non apparement. [:dawa]

n°1541518
_darkalt3_
Proctopathe
Posté le 11-04-2007 à 17:49:26  profilanswer
 

FUIS PENDANT QU4IL EN EST ENCORE TEMPS PAUVRE FOU §§§§ [:gandalf]


---------------
Töp of the plöp
n°1541519
Trap D
Posté le 11-04-2007 à 17:49:52  profilanswer
 

Plusieurs choses
Choisis, travaille avec des cases ou avec des coordonnées mais là tu mélangers un peu.
 
Ton prédicat membre/2, tu peux l'écrire comme ça, ce sera plus général :

Code :
  1. membre(X, [X| _]) :- !.
  2. membre(X, [_ | T] :-
  3.     membre(X, T).


 
 
Sans test aucun car je n'ai pas Prolog sous la main, je ferais comme ça :
Je pars de la case (X,Y) et je veux aller à la case (A,B)

Code :
  1. existechemin(X,Y,X,Y,[]). % le chemin est vide entre les deux mêmes cases
  2. existechemin(X,Y,A,B,[case(A,B)]) :- voisin(X,Y,A,B),!.
  3. existechemin(X,Y,A,B,[case(A,B) | L] ) :-
  4.     % La case(C,D) est proche de la case (A,B)
  5.     voisin(X,Y,C,D) ,
  6.     % je regarde s'il existe un chemin de la case(X,Y) à la case(C,D)
  7.     existechemin(X,YC,D,L),
  8.     %  On regarde si la case n'a pas déjà été visitée.
  9.     not(membre(case(A,B),L)).

Attention ce code te donne le chemin à l'envers.
Maintenant, personnellement, je chercherais toutes les cases accessibles en 1 pas, puis toutes celles accessibles en 2, puis 3 jusqu'a arriver à la case(A,B). Cette méthode te donnera en plus le plus court chemin.
 
_darkalt3_ [:alana21]


Message édité par Trap D le 11-04-2007 à 17:53:16
n°1541553
guiguivts
Posté le 11-04-2007 à 18:20:47  profilanswer
 

J'ai fait plus ou moins pareil je trouve non ?  
 
Tu pars de la case X,Y pour aller à la case A,B donc tu cherches récursivement s'il existe un chemin de X,Y à C,D C,D étant proche de A,B  
 
Moi je pars de X,Y pour aller à A,B et je cherche s'il existe un chemin entre C,D et A,B C et D étan proche de X,Y ça revient au même je trouve mais je peux me tromper.  
 
J'ai tester ton code ça revient au même que le mien ça boucle dans certains cas lorsque le chemin n'existe pas :(  
 
bye

n°1541707
Trap D
Posté le 12-04-2007 à 00:05:55  profilanswer
 

Bon, je suis devant SWI-Prolog et maintenant ça fonctionne.
 
Voilà comment j'ai travaillé.
J'ai défini le prédicat voisin comme ceci :

Code :
  1. voisin(case(X,Y),case(A,B)) :-
  2.       (   A is X - 1, B = Y, case(A,B));
  3.       (   A is X + 1, B = Y, case(A,B));
  4.       (   A = X, B is Y - 1, case(A,B));
  5.       (   A = X, B is Y + 1, case(A,B)).

Pour pouvoir, en interrogeant la base de fait  de cette façon : voisin(case(X,Y),Z). obtenir toutes les cases voisines de la case(X,Y).
 
J'utilise maintenant un prédicat existechemin(X,Y,L, NL) donc à 4 arguments où
X est la case de départ,  
Y est la case d'arrivée,  
L est le chemin déjà parcouru
NL le chemin final  
 
Maintenant on construit le chemin :

Code :
  1. % Quand les deux case sont voisines on ajoute simplement
  2. % les deux cases au chemin déjà parcouru (on a terminé).
  3. existechemin(X,Y,L, L1) :-
  4. voisin(X,Y),
  5. !,
  6. append([X,Y], L, L1).
  7. % Sinon, on va chercher une case voisine
  8. existechemin(X , Y, L, L1) :-   
  9. % La case Z est proche de la case Y
  10. voisin(Y,Z),
  11. % la case n'a pas déjà été visitée
  12. \+membre(Z,L),
  13. % je calcule le chemin de la case X à la case Z
  14. existechemin(X, Z, [Y | L], L1).


Le chemin est construit dans l'ordre.
Maintenant, pour rechercher un chemin, tu fais par exemple

Code :
  1. existechemin(case(1,1), case(5,4), [], L).


Message édité par Trap D le 12-04-2007 à 00:16:31
n°1541860
guiguivts
Posté le 12-04-2007 à 11:29:13  profilanswer
 

Bon bien ça ne marche pas il aime pas ton append et même sans rajouter de L1 en gardant juste L il boucle j'utilise sicstus prolog mais je crois que je vais arréter je perd trop de temps

n°1541869
Trap D
Posté le 12-04-2007 à 11:43:59  profilanswer
 

Dommage, utilise SWi-Prolog, c'est mieux.
 
PS : si c'est la append qui te gène, fais

Code :
  1. existechemin(X,Y,L, [X, Y | L]) :-   
  2.     voisin(X,Y),    !.


Message édité par Trap D le 12-04-2007 à 11:52:56
n°1541886
guiguivts
Posté le 12-04-2007 à 11:54:44  profilanswer
 

je peux utiliser que sicstus car je l interface avec java  
 
merci en tous cas

n°1541906
guiguivts
Posté le 12-04-2007 à 12:06:09  profilanswer
 

en fait le soucis c'est que dans ce prédicat  
 
existechemin(X , Y, L, L1) :-    
voisin(Y,Z),
/+membre(Z,L),
 existechemin(X, Z, [Y | L], L1).
 
Ptet que ça marche mais je ne comprend pas dans ce cas , comme on rajoute La nouvelle case Y dans l'appel récursif il est possible que l'on teste quand même deux fois ce Y.  
 
Par exemple on appelle une premiere fois ce prédicat et X à plusieurs voisins Z On rappelle ce prédicat récursivement avec le premier voisins et donc le premiers voisin va rajouter ses propres voisins à L. Mais lorsque cet appel sera terminé le permier appel du prédicat va reprendre avec un autre voisin mais avec l'ancienne liste L et donc il est possible de tester plusieurs fois la même case c'est peut etre ce qui boucle je ne sais pas.
 
ça ne boucle que sur certain cas c'est bizarre.

n°1541946
Trap D
Posté le 12-04-2007 à 13:35:22  profilanswer
 

Peux-tu m'indiquer tes cases valides ?
Moi j'ai défini dans ma base de faits
case(1,1).
case(1,2).
case(1,3).
etc, de manière à avoir plusieurs possibilités de chemins pour aller d'une case à une autre, et je les obtiens tous. Le problème vient peut-être de cette définitions de case.
 
voisin(Y,Z) doit fournir un voisin de Y à chaque appel, c'est essentiel.
Par le phénomène de backtrack, quand un parcours échoue on revient sur ses pas et on essaye avec un nouveau voisin.
 
 
 

n°1541969
guiguivts
Posté le 12-04-2007 à 14:01:10  profilanswer
 

Oui je comprend pas non plus. en fait j'ai un damier de 10 sur 10 avec des murs à l'intérieur si je prend un nombre assez petit de case par exemple 10 12 ça fonctionne mais si j'en prend 50 ça ne marche plus.
 
Il y a donc 100 cases mais elles ne sont pas forcément accessibles.

n°1541987
guiguivts
Posté le 12-04-2007 à 14:24:36  profilanswer
 

Voilà mon code : voisin j'ai testé à beaucoup de reprises et il fonctionne :  
 
le prolog :
 

Code :
  1. membre(X,[X|_]) :- !.
  2. membre(X,[_|T]) :- membre(X,T).
  3. voisindeux(case(X,Y),case(A,B)) :- voisin(X,Y,A,B).
  4. existechemin(X,Y,L,[X,Y|L]) :- voisindeux(X,Y) , ! .
  5. existechemin(X,Y,L,L1) :- voisindeux(Y,Z) , \+membre(Z,L) , existechemin(X,Z,[Y|L],L1).


 
 
le java
 

Code :
  1. if(sp.boolRequete("existechemin(case(1,1),case(10,1),[],L)." ))
  2. {
  3. System.out.println("il y a un chemin" );
  4. }
  5. else
  6. {
  7. System.out.println("il n y a pas de chemin" );
  8. }


 
Je pige pas..
 
 
 

n°1542065
guiguivts
Posté le 12-04-2007 à 15:52:55  profilanswer
 

Pourquoi ça marche pas :'(

n°1542165
Trap D
Posté le 12-04-2007 à 17:39:40  profilanswer
 

Tu es sûr de l'interface avec Java ?
D'autre part cette méthode bouffe pas mal de mémoire, des algos plus élaborés seraient sans doute plus adaptés.
Cependant, je viens de faire le test avec ça,  

Code :
  1. damier(L) :-
  2. L = [[1,1,1,0,0,0,1,1,1,0],
  3.      [1,0,1,0,0,0,1,1,1,1],
  4.      [1,1,1,1,1,1,1,0,0,1],
  5.      [1,1,1,0,0,0,1,0,1,0],
  6.      [1,0,1,1,1,1,1,1,1,0],
  7.      [1,1,0,0,0,0,1,0,1,0],
  8.      [0,1,1,0,0,0,1,0,1,0],
  9.      [0,1,0,0,0,0,1,0,1,0],
  10.      [1,1,1,0,0,0,1,1,1,0],
  11.      [1,1,1,1,1,1,1,1,1,1]].
  12. cell(X,Y):-
  13. damier(L),
  14. nth1(X,L, R),
  15. nth1(Y,R,1).

Ca fonctionne très bien.


Message édité par Trap D le 12-04-2007 à 17:57:59
n°1542191
guiguivts
Posté le 12-04-2007 à 18:05:13  profilanswer
 

honnetement je comprend pas ça fait 24h que je suis dessus quand même :p  
 
je viens de passer 10 minutes à faire exactement la même chose en utilisant java et prolog juste pour tester si les faits existent et ça fonctionne donc je voie pas mais bon ça a l'air de marcher :)  
 
Par contre comme prévu c'est long et lourd en java alors qu'en prolog c'est censé faire 3 lignes..

n°1542198
Trap D
Posté le 12-04-2007 à 18:15:37  profilanswer
 

Pour Plus de renseignements sur l'interface Java, reagarde là :
http://groups.google.de/group/comp.lang.prolog/topics

n°1542201
guiguivts
Posté le 12-04-2007 à 18:18:18  profilanswer
 

merci pr tout ;)

n°1542658
Trap D
Posté le 13-04-2007 à 14:41:06  profilanswer
 

Ce petit programme en java fonctionne très bien avec l'interface jpl de SWI-Prolog.

Code :
  1. import java.util.Hashtable;
  2. import jpl.*;
  3. import jpl.Query;
  4. public class Labyrinthe
  5. {
  6. public static void
  7. main( String argv[] )
  8. {
  9.  String t1 = "consult('Labyrinthe.pl')";
  10.  Query q1 = new Query(t1);
  11.  System.out.println( t1 + " " + (q1.hasSolution() ? "succeeded" : "failed" ) );
  12.  String t2 = "existechemin(cell(7,9), cell(10,10), [], L)";
  13.  Query q2 = new Query(t2);
  14.  System.out.println( "first solution of " + t2 + ": L = " + q2.oneSolution().get("L" ));
  15.  //--------------------------------------------------
  16.  java.util.Hashtable[] ss2 = q2.allSolutions();
  17.  System.out.println( "all solutions of " + t2);
  18.  for ( int i=0 ; i<ss2.length ; i++ ) {
  19.   System.out.println( "L = " + ss2[i].get("L" ));
  20.  }
  21.  //--------------------------------------------------
  22.  System.out.println( "each solution of " + t2);
  23.  while ( q2.hasMoreSolutions() ){
  24.   java.util.Hashtable s2 = q2.nextSolution();
  25.   System.out.println( "L = " + s2.get("L" ));
  26.  }
  27. }
  28. }

Code de Labyrinthe.pl

Code :
  1. damier(L) :-
  2. L = [[1,1,1,0,0,0,1,1,1,0],
  3.      [1,0,1,0,0,0,1,1,1,1],
  4.      [1,1,1,1,1,1,1,0,0,1],
  5.      [1,1,1,0,0,0,1,0,1,0],
  6.      [1,0,1,1,1,1,1,1,1,0],
  7.      [1,1,0,0,0,0,1,0,1,0],
  8.      [0,1,1,0,0,0,1,0,1,0],
  9.      [0,1,0,0,0,0,1,0,0,0],
  10.      [1,1,1,0,0,0,0,1,0,0],
  11.      [1,1,1,1,1,1,1,1,1,1]].
  12. cell(X,Y):-
  13. damier(L),
  14. nth1(X,L, R),
  15. nth1(Y,R,1).
  16. voisin(cell(X,Y),cell(A,B)) :-
  17.       (   A is X - 1, B = Y, cell(A,B));
  18.       (   A is X + 1, B = Y, cell(A,B));
  19.       (   A = X, B is Y - 1, cell(A,B));
  20.       (   A = X, B is Y + 1, cell(A,B)).
  21. %  existechemin(X,X,L,[X | L]). % le chemin est vide entre les deux
  22. %  mêmes cases
  23. existechemin(X,Y,L, [X,Y |L]) :-
  24. voisin(X,Y),
  25. !.
  26. %append([X,Y], L, L1).
  27. existechemin(X , Y, L, L1) :-   
  28. % La case Z est proche de la case Y
  29. voisin(Y,Z),
  30. \+membre(Z,L),
  31. % je regarde s'il existe un chemin de la case X à la case Z
  32. existechemin(X, Z, [Y | L], L1).
  33. membre(X,[X |_]):- !.
  34. membre(X,[_|S]) :-
  35. membre(X,S).


n°1555516
guiguivts
Posté le 04-05-2007 à 19:01:25  profilanswer
 

Salut,  
 
merci pour ton dernier message. J'avais un peu laissé tombé mais quand même réussi à faire fonctionner chemin
 
là j'essaye de récupérer la liste des chemin mais ça ne fonctionne malheureusement pas :-(
 
donc j'ai plus ou mon les mêmes prédicats pour existe chemin :  
 

Code :
  1. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2. % prédicat permettant de trouver un chemin entre deux cases %
  3. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4. voisindeux(case(X,Y),case(A,B)) :- voisin(X,Y,A,B).
  5. existechemin(X,X,L,[X | L]). % le chemin est vide entre les deux
  6. existechemin(X,Y,L, [X,Y |L]) :- voisindeux(X,Y) , !.
  7. existechemin(X , Y, L, L1) :-  voisindeux(Y,Z) , \+membre(Z,L), existechemin(X, Z, [Y | L], L1).


 
 
Pour récuperer une liste de résultat nous utilisons une fonction faite par le prof :  
 

Code :
  1. public LinkedList listeresultat(String texte,String terme){
  2.  HashMap resultat = new HashMap();
  3.  LinkedList retour = new LinkedList();
  4.  try {
  5.   SPQuery query=sp.openQuery(texte,resultat);
  6.   while (query.nextSolution ()) {
  7.       retour.add(((SPTerm)resultat.get(terme)).toString());
  8.   }
  9.   query.close();
  10.  } catch (Exception e) {e.printStackTrace();}
  11.  return retour;
  12. }


 
 
Et j'appelle ça comme ça :  
 
listechemin =_sp.listelisteresultat("existechemin(case(1,1),case(3,1),[],L).", "L" );
 
malheureusement ça boucle..
 
J'ai une autre méthode pour récuperer le premier résultat de cette liste  :  
 

Code :
  1. public String premierresultat(String texte, String terme){
  2.  HashMap result = this.requete(texte);
  3.  if (result.size()>0) return ((SPTerm)result.get(terme)).toString();
  4.  else return "";
  5. }


 
Cela fonctionne pourtant !  
 
bye

n°1555552
guiguivts
Posté le 04-05-2007 à 20:48:49  profilanswer
 

:)

n°1555642
Trap D
Posté le 05-05-2007 à 11:37:48  profilanswer
 

Je ne m'y connais malheureusement pas assez en Java pour te conseiller.  
Tout ce que je peux dire, c'est que dans l'exemple que j'ai posté, je récupère tous les chemins. Il est adapté des exemples de JPL de SWI-Prolog.

n°1555654
guiguivts
Posté le 05-05-2007 à 12:11:21  profilanswer
 

Oui moi aussi il le fait bien, l'ennui c'est que lorsqu'il n'y a plus de chemins  possibles ça boucle :( de même avec ton exemple quand je teste sur un chemin qui n'existe pas il boucle :(

n°1555715
Trap D
Posté le 05-05-2007 à 15:16:34  profilanswer
 

Je viens de faire le test, le programme génère une exception que tu peux intercepter si le chemin n'existe pas, (toujours avec SWI-Prolog et JPL).

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Divers

  [Prolog] débutant..

 

Sujets relatifs
[cpp] [Débutant]Question à propos de liste chainéesDevcpp pour les nuls [Débutant]
faire une boucle correcte... grand débutantDébutant PHP,besoin d'aide
Problemme sur fonction [debutant]aide pour creation annuaire (débutant)
SSH, serveur dédié pour débutant, comment?Compilation de template... (débutant)
[Résolu][VBS Débutant Boucle Do-While-Loop Active Directory][SQL] une question de pur debutant
Plus de sujets relatifs à : [Prolog] débutant..


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR