CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

Prolog

omegasf3
omegasf3
Niveau 8
09 juin 2004 à 20:52:27

Salut est ce qu´il y a des personne qui utilise prolog, si oui quelqu´un pourrait il m´expliquer
comment marcher le ifthenelse merci.

Thanhatos
Thanhatos
Niveau 39
15 novembre 2010 à 06:58:22

Je relève ce topic pour quelque chose de plus basique.

Je ne comprends quasiment RIEN à ce langage pas comme les autres. Or, c'est une matière que je dois passer. Repasser même.

Est ce qu'il traine une âme charitable qui puisse m'expliquer le fonctionnement, la logique, m'apporter le truc, l'étincelle qui me fera comprendre quelque chose au prolog s'il vous plait ?

J'ai encore 2 mois pour essayer d'entraver quelque chose, un détail, un bout de logique... Je désespère. En 25 ans c'est la première fois que je passe totalement à côté d'un truc même en faisant des efforts.

A moins de tomber sur un tutoriel style "site du zéro", c'est à dire aussi clair et bien expliqué pas à pas, ce n'est pas la peine de me donner des tutoriels parce que tant que je n'ai pas saisi comment ça fonctionne je peux lire, avoir l'impression de comprendre... et toujours être incapable de résoudre le moindre exercice.
(Et puis je sais encore chercher sur le net pour les éléments basiques. ^^)

Merci d'avance. :mort:

godrik
godrik
Niveau 30
15 novembre 2010 à 17:15:21

j'ai peur de n'avoir rien de plus a t'en dire que la page de wikipedia. Poses des questions precises peut etre.

saleGauss
saleGauss
Niveau 9
15 novembre 2010 à 21:00:55

Je peux essayer de faire un aide de survis, mais il faudra que tu pose des questions plus précises.

En Prolog, il existe deux grandes choses :

1/ Tes données
2/ Tes règles.

Tes données représentent ton monde.
Bien. Tu y décris les choses par des prédicats, qui AFFIRMENT des faits.
Par exemple, tu ecris
"mange(pierre,salade)"
pour dire que pierre mange une salade.
(Un détail pas important dans un premier temps :
En terme logique tu as dis que
Il existe pierre, il existe salade, tel que mange(pierre,salade).
Mange est bien un prédicat)

Bien, donc tu représente tes données de cette manière.
Tu vas avoir ainsi une (relativement) grosse base de FAITS : de choses qui sont VRAIES.
Par exemple :
pere(Paul,Sabine). @ Paul est le Père de Sabine
pere(Eric,Paul). @ Eric est Père de Paul
pere(Paul,Adrien). @ Paul est le père d'Adrien

On a donc choisit de modéliser ces informations, et on a choisit de les modéliser de cette manière (penser à se souvenir qu'on a décidé que le premier argument était le Papa, et le deuxième le fiston).
En clair, on fixe des choses, mais ce n'est pas magique, il faudra être cohérent par la suite.

Bien, et maintenant, on en fais quoi ?
Et bien on va écrire des règles, qui vont nous permettre de résoudre NOTRE problème.
On écrit donc pas des règles au pif, ou juste pour le plaisir, on écris des règles pour résoudre un problème.

Bien, alors d'abord fixons l'écriture des règles en Prolog, et puis fixons nous un problème.

Alors les règles c'est ainsi :
pere(X,Y) :- fils(Y,X).

Voila, c'est un exemple de regle (qui sert à rien à part à présenter la syntaxe et le sens).
Et j'ai dis quoi la dedans ? J'ai dis que
X est le pere de Y SI Y est le fils de X.
Alors tu remarqueras que le SI est donné par le ":-"
En clair, le prédicat de gauche est vrai si le prédicat de droite est vrai.
On a donc une implication logique : fils(Y,X) -> pere(X,Y)
(et n'ont pas le contraire ! On retourne la "phrase" pour donner son équivalent logique en terme d'implication !)
Bien, deuxième chose à remarquer : j'ai utilisé ici un X et un Y. Ce sont des variables.
j'ai donc dis que pere(X,Y) est vrai (X est le pere de Y) si fils(Y,X) (Y est le fils de X) est vrai, et cela QUELQUE SOIT X et Y.

Cela signifie qu'il pourra déduire pere(X,Y) à chaque fois que Prolog trouvera un fils(Y,X).
Et où Prolog trouve t'il ça ?
Dans les données qu'on lui a donné bien sur !

Bon, bien sur, là on a donné aucune données sur fils(), donc il ne déduire rien pour pere.

Maintenant que l'on a fixé la syntaxe des règles par cet exemple qui n'apportait rien, on va voir un problème :

ecrire un predicat qui permet de trouver les ancetres d'une personne :
ancetre(X,Y) telle que X soit un ancetre de Y.

Alors, nous aurons :
ancetre(X,Y) :- enfant(Y,X) @ X est un ancetre de Y si Y est l'enfant de X

ancetre(X,Y) :- enfant(Y,Z),ancetre(Z,X) @ X est l'ancetre de Y si Z est l'enfant de Y, et que ce même Z est l'encetre de notre X !

Tu remarqueras que nous avons alors deux regles pour ce prédicat : une regle simple, et une regle recursive (qui se définie avec elle même).

Voila. On a une jolie regle. Et donc maintenant si on a plein de données du genre :

enfant(chantal,francois).
enfant(rose,philippe).
enfant(france,henri).
enfant(henri,jean)
enfant(julie,paul).

Et bien on pourra demander à prolog de chercher :

encetre(france,X).

Et prolog va chercher avec nos deux regles !
Et il va suivre le processus de l'unification que je te décrirais une prochaine fois, si tu as déja réussi à suivre ce que je viens de raconter là.

Comprend juste qu'il essaye avec la première regle PUIS avec la deuxième. Et ceci jusqu'à ce qu'il est tout exploré.

En conclusion :

un programme prolog c'est :
I/ Des données = des faits = des choses vraies
II/ Des règles pour déduire des nouvelles choses dans le but de résoudre un probleme

Bon, c'est du écrit en direct, donc il y a peut etre des erreurs, n'hesitez pas à me les signaler.

Bonne soirée

Thanhatos
Thanhatos
Niveau 39
16 novembre 2010 à 03:03:03

godrik : je risque de poser des exercices que je ne sais pas résoudre (ce qui est différent de ne pas comprendre, mais revient au même sur la copie. :fou: ).

saleGauss : merci !
T'es déjà plus clair que ce que j'ai pu avoir comme cours.
Le "SI" dans une règle est une nuance que je viens d'apprendre.

Par contre, il n'y a pas une erreur là ?
"ancetre(X,Y) :- enfant(Y,Z),ancetre(Z,X) @ X est l'ancetre de Y si Z est l'enfant de Y, et que ce même Z est l'encetre de notre X !"
=>
J'aurais dit que ça signifie plutôt : X est l'ancêtre de Y SI Y est l'enfant de Z ET Z l'ancêtre de X.

Bon sur un petit dessin ça place Z tout en haut, X en dessous et Y en dernier.
Donc Y n'est pas l'enfant de Z mais le petit enfant. ^^

C'est bon, c'est faux ? Pourquoi ?

Ensuite tu dis "Comprend juste qu'il essaye avec la première regle PUIS avec la deuxième. Et ceci jusqu'à ce qu'il est tout exploré."
Ce qui signifie qu'il va d'abord chercher/dérouler tous les enfants(Y,Z) sans se soucier des ancêtres(Z,X) ?

Donc jusque là je pense avoir assimilé (??).
Le processus d'unification de variable, je pensais l'avoir compris aussi mais je veux bien ta version avec des mots et une façon de procéder que je comprends comme dans ton message. ^^

Je te remercie beaucoup pour ton temps !
Si je te comprends bien, et que m'aide à avoir le déclic, je risque de repasser redemander des explications et de l'aide. :p)

Sinon, voilà un exemple type d'exercice dont je comprends ce qu'on me demande sans réussir à en écrire une ligne (ou du moins je suis bloqué rapidement).
J'ai un problème de "lancement" dans l'écriture d'un programme en prolog.

Réaliser les prédicats prolog qui permettent :
1. Faire la rotation d'une liste du nombre d'éléments indiqués en paramètre, comme dans l'exemple
suivant :
{ ?- rotation([a,b,c,d,e],3,L).
{ L = [c,d,e,a,b]
{ ?- rotation([a,b,c,d,e],-1,L).
{ L = [b,c,d,e,a]

2. Compter le nombre d'occurrence d'éléments qui se suivent dans une liste, comme dans l'exemple
suivant :
{ ?-occurrence([a,a,b,b,b,a,e,e,e],L).
{ L = [[a,2],[b,3],[a,1],[e,3]]

J'ai la correction sous les yeux, mais si je la mets de côté je ne suis pas capable de réécrire avec la totale compréhension de ce que je fais.
Et si je me contente bêtement de recopier la correction pour essayer d'assimiler, je ne comprends pas ce que je fais (grrrr). Et je déteste ne pas comprendre.

Il me manque un cheminement logique. Pour le moment je nage.

Si jamais quelqu'un a la patience de me montrer sa façon de faire l'exercice, et surtout de m'expliquer pourquoi il fait ceci et pas cela, qu'est ce qui l'amène à écrire ça et pas autre chose, etc, ce serait sympa et instructif. ^^

Merci d'avance.

Thanhatos
Thanhatos
Niveau 39
16 novembre 2010 à 03:09:48

Pour précision, parce que le prolog n'est pas un langage classique, à chaque nouvel exercice j'ai l'impression d'être bloqué. De découvrir le langage. Et de devoir utiliser des méthodes que je ne connais pas.

Contrairement à d'autres langages où on peut toujours partir d'une brique et une après l'autre on arrive à quelque chose.
Là je me retrouve comme un c*n devant mon exercice à savoir le lire mais sans avoir les outils pour le résoudre.

C'est pour ça que je parle d'un déclic ou d'une logique qui m'échappe. Ou que je demande un cheminement général, si ça existe. ^^

Si ça peut vous simplifier la façon de m'expliquer les choses, ce sera pas perdu.

saleGauss
saleGauss
Niveau 9
16 novembre 2010 à 14:34:57

Je suis en cours, mais je répond ce soir de manière détaillée, promis.

saleGauss
saleGauss
Niveau 9
16 novembre 2010 à 21:10:49

Oui tu as entierement raison, je m'étais planté en écrivant mon exemple.
Voici la bonne version :

ancetre(X,Y) :- enfant(Y,Z),ancetre(X,Z).
En francais : "X est l'ancetre de Y si il existe un Z tel que Y soit l'enfant de Z, ET que X soit l'ancêtre de ce même Z"

Bien, parlons un peu de l'unification.
L'idée, c'est qu'à chaque fois que Prolog doit prouver un predicat, il va essayer en prenant une regle pour ce meme prédicat, et tenter d'unifier les variables qu'il a aux constantes et variables de la regle qu'il a.
Une variable pourra etre unifiée à n'impore quelle constante, et vis vers ça.
Une constante ne peut etre unifiée qu'avec elle meme.
Et si Prolog passe l'unification, et bien au lieu de résoudre ce qu'il avait à résoudre, il va essayer de résoudre la partie droite de la regle avec laquelle l'unification a marché.
Et il va continuer ainsi à chaque étape.
A un moment, il peut rencontrer un echec d'unification : par exemple, s'il essaye d'unifier chantal à marie.
Dans ce cas, ce noeud ne donne pas de solution, et prolog va alors remonter, et continuer à explorer ce qu'il n'a pas encore exploré (avec les autres données, et avec les autres regles).

Bien, essayons de résoudre ton premier probleme.
(je n'ai pas Swi prolog sous la main, il faudra donc bien vérifier ce que je raconte)).

On te demande d'écrire un predicat rotation(I,X,L)
Il faut deja bien savoir comment est-ce que dans le futur on compte se servir du predicat que l'on aura écrit.
On va s'en servir comme dans tes exemples, en fournissant la liste de depart I, et le X qui sera le nomdre d'elements que l'on souhaite deplacer.

Mon approche serait de résoudre cela par récurence sur X : tu sais facilement faire une rotation de 0 elements.
Et si tu sais faire une rotation pour N-1 elements, la faire pour N elements ne devrait pas etre trop dur.
(I sera la liste "In")

essayons :
rotation(I,0,I). [REGLE 1]
C'est une regle, la regle numero 1, qui dit qu'il est toujours vrai que I est la rotation de I avec 0 elements deplacés.
Tu remarqueras que moi je t'avais parlé des regles conditionnelles. Ici c'est une regle sans condition : elle est toujours vrai.
En réalité, la condition intuitive que l'on comprend, c'est que la liste d'entrée et la liste de sortie doivent etre égales.
Mais on a pas à l'écrire en condition, on le met direct en utilisant l'unification !
En mettant rotation(I,0,I), on lui a imposé que le premier arg et le 3 eme doivent etre les meme. Le predicat sera donc vrai PAR CETTE REGLE lorsqu'il arrivera à unifier de sorte que le premier et le troisisme soient les meme, et X zero. Sinon il fera un echec à l'unification quand il essayera de se servir de ma regle.

Alors, autres regle ?

Si j'ai une rotation de X elements à faire sur sur la liste I, je dois faire quoi ?

[Etape 1]
Et bien si X est strictement superieur à zero, je vais essayer de faire une rotation de X-1 elements sur I (appel recursif), et je nomme le resultat temporaire R.

Et sur ce R, il me reste un cycle à faire : je dois enlever la queue de ma liste I, et la mettre en tete.
On va proceder par etape :

[Etape 2]
Quand j'enleve la queue de ma liste R, j'appelle un predicat enleveQueue(A,Q,B) qui quand je lui donne A me donne dans Q la queue (=le dernier element)de I, et dans B la liste sans la queue.
Je vais donc appeller ce predicat ainsi (reprendre là où j'en étais!) :
enleverQueue(R,Q,R2).

[Etape 3]
Et maintenant, je dois faire quoi ? Ma liste L que je cherche sera ma liste R2 obtenue juste au dessus auquel je met en tete Q.

ce qui me donne :
(je l'ecris en deux temps)
rotation(I,X,?) :- N>0, Y is X-1, rotation(I,Y,R), @ Etape 1
enleveQueue(R,Q,R2), @ Etape 2

Et l'etape 3, et bien au lieu de la faire en condition, j'utilise l'unification (encore !)
C'est à dire que je l'écris ainsi :

rotation(I,X,[Q|R2]) :- X>0, Y is X-1, rotation(I,Y,R),
enleveQueue(R,Q,R2). [REGLE 2]

je dis là dedans que Q mit en tete de R2 est la rotation de X elements de I SI X est supérieur à zero, si R est la rotation de X-1 elements de I, et si enfin R2 est R auquel on a enleve la queue Q.

Il ne nous reste plus qu'à écrire le predicat enleveQueue(A,Q,B) que j'ai utilisé.
A : liste In
Q : queue (=dernier element de A) (out)
B : liste A privee de sa queue (out)

Faisons le par induction sur notre liste d'entrée A (comme souvent, un bon informaticien n'a que l'induction structurelle pour résoudre ses problemes !).

Quels cas à-t'on ? On a le cas d'une liste à un element (à zero ca serait un probleme, on ne peut pas renvoyer sa queue), et le cas d'une liste à plusieurs elements.

enleveQueue([E],E,[]) @ Si on a une liste à un seul element (un singleton), la queue c'est l'unique element, et la liste privee de sa queue c'est juste la liste vide.

enleveQueue([T|R],Q,[T|K]) :- enleveQueue(R,Q,K)

Comment j'ai construis cette regle ?
-------------------------
j'ai commencé par ecrire :
enleveQueue([T|R],Q,???) :-
Et je me suis dis : bon, donc je suis dans le cas où je veux enlever la queue (le dernier element) d'une liste [T|R] pour obtenir une liste ???, et Q sera la queue que j'ai enlevé.
je dois faire quoi ?
Et bien je dois enlever la queue du reste, et cette queue du reste sera justement la queue de ma liste [T|R] !

enleveQueue([T|R],Q,???) :- enleveQueue(R,Q,K)

J'ai donc appelé K la liste R privee de sa queue.
Et moi, je veux à la place des ??? la liste [T|R] privee de sa queue.
Je dois donc renvoyer [T|K] car K c'est le reste privee de la queue !

Ce qui donne bien :
enleveQueue([T|R],Q,[T|K]) :- enleveQueue(R,Q,K)
-----------------------------

Quelques remarques :

-Il resterait à faire maintenant rotation() pour un X<0.
Je t'aiderais à le faire plus tard, mais je veux etre sur que l'on s'est bien compris, et que je n'ai pas (encore!) laissé d'erreurs.

- Tu remarquera que pour faire de l'arithmétique dans mon rotation(), je n'ai pas pu utiliser directement X-1 comme argument d'un predicat.
j'ai du dire Y is X-1 et utiliser Y.
Cela parce que les arguments doivent etre des variables au sens de prolog, pas des expressions.
Penser donc toujours à faire juste avant un petit calcul necessaire, lui donner un petit nom, et s'en servir apres.

-Tu remarquera que pour rotation() il est INDISPENSABLE de vérifier que X>0 dans ma regle [2], sans quoi lorsqu'on appelle notre rotation() avec X qui vaut zero, et bien les deux iraient, et on partirait avec [2] dans les negatifs en recursivité infinie !
On parle de rendre les regles [1] et [2] exclusives.
Elles ne sont dans e cas là pas rendues exclusives par l'unification, car une liste peut etre bien etre unifiée à la liste I (dans [1]), ou au I de la regle [2].
Lorsqu'on ne peut pas les rendre exclusives par l'unification, on les rend exclusives par programmation, dans notre cas grace au X>0 de [2] qui ne tolere pas que X soit zero.

Bien, je vais te laisser ingurgiter ça, et te laisser tester, car je le rappelle, je n'ai malheureusement pas pu tester !

Je tiens à préciser que la reflexion que j'ai ai est juste "à froid", sans reflexion sur papier.
Il y a donc surrement plus élégant, et surrement plus concis.

j'ai juste laissé aparaitre la démarche qui m'a guidé pour essayer de résoudre ton probleme.

Je repost plus tard pour continuer/corriger si nécessaire.

Bon courage et have fun !
C'est sympa prolog avec le temps, tu vas voir.
Un peu prise de tete mais sympa ! :p

saleGauss
saleGauss
Niveau 9
16 novembre 2010 à 21:25:15

Note pour moi même, ecrire un jour un petit cours de Prolog.
Ca sera plus propre que sur un forum, et mieux structuré.
Youpi ! Un truc de plus à faire ! :p

Un dernier detail :
Garde bien en tete deux choses quand tu fais du Prolog:

1/ Les predicats ne représentent pas des resultats !
Si tu as fais un langage fonctionnel (Ocaml, autre), tu risque de vouloir parfois utiliser, par exemple, enleverQueue() comme si c'était le resultat, et donc une liste. Et non ! enleverQueue() c'est un predicat : ca prend des choses en entrée, et c'est soit vrai, soit faux !

Du coup, lorsque tu ecris des prédicats, fais si possible comme j'ai procédé, dis toi "bon, je vais m'en servir comment ? Je lui donnerais le premier argument, et pour les autres je lui donnerais des variables, et il unifiera mes variables avec ce qui a marché !
Mes resultats sont donc des les arguments que j'ai concu comme des "arguments out".

2/ Penses toujours à utiliser au maximum l'unification. Pour cela, inspire toi de la manière de ce que j'ai fais :
j'ai ecris un truc du genre
pred([T|R],???) :-
et je me suis dis, bon, je suis dans le cas où je recois [T|R], et je veux renvoyer ????.
Construit alors dans la partie droite ce qu'il te faut pour pouvoir remplacer les ??? par ce que tu cherchais.
N'en écris pas plus que necessaire dans la partie à drotie du ":-"

j'espère sincerement ne pas t'avoir trop embrouillé.
C'est que mine de rien, c'est dur à expliquer sur une page de texte :-(
Si t'étais à coté, avec une feuille de papier on tracerait des superbes arbres pour bien voir comment l'interpretre Prolog recherche.
Je vais voir si je peux faire mieux et scanner un truc si tu as des soucis pour voir le fonctionnement.

Thanhatos
Thanhatos
Niveau 39
17 novembre 2010 à 02:41:33

Merci encore.

Bon, là je vais pas dire que j'ai tout compris... Je vais relire, et brouillonner des trucs pour voir. :peur:

Sinon pour information j'utilise le locigiel Sixtus prolog pour... heu, des fois je l'utilise. ^^

Je bidouille et je pose des questions.

Thanhatos
Thanhatos
Niveau 39
17 novembre 2010 à 06:40:55

"Une variable pourra etre unifiée à n'impore quelle constante, et vis vers ça.
Une constante ne peut etre unifiée qu'avec elle meme."
:doute:

Tu veux dire ça =>
Un "X" (variable) pourra être unifié avec un "2" (constante).
Et un "2" (constante) pourra être unifié avec un "X" (variable".
Mais un "2" (constante) ne pourra PAS être unifié avec une AUTRE constante ? Donc si c'est "2" ça restera "2" et ça ne s'unifiera pas avec "3" par exemple.

J'ai compris ?

"Mon approche serait de résoudre cela par récurence sur X : tu sais facilement faire une rotation de 0 elements.
Et si tu sais faire une rotation pour N-1 elements, la faire pour N elements ne devrait pas etre trop dur."
Heu... :peur:
Non, pars du principe que je ne sais pas faire. ^^
La rotation de 0 éléments, bah c'est ne rien changer, donc mettre une variable qui sera unifiée à 0.
N-1 élément tu m'as perdu. :rouge:

"(I sera la liste "In")"
=>
Là, tu as juste noté ça pour t'en rappeler plus tard ? Mais pourquoi si c'est la liste In tu ne l'appelles pas In dès le départ ?

(Je commence à comprendre pourquoi j'ai du mal à comprendre et faire du prolog : les variables ont toujours les mêmes noms => des lettres, ce qui n'est pas explicite pour moi. ^^
Si c'était des mots encore. Un truc clair quoi. On se fait engueuler quand on donne des noms de variables qui ne veulent rien dire ou qui ne parlent que pour nous dans les autres langages de programmation et ici on colle que des lettres :fou: ).

La différence entre une règle conditionnelle et non conditionnelle c'est quoi ?
Le fait que la non conditionnelle n'a pas de règles derrière le ":-" mais se termine directement par un "." ?

Le prédicat rotation(I,0,I). tu le lis comment ? J'ai besoin de "verbose" pour retenir.

"[Etape 1]
Et bien si X est strictement superieur à zero, je vais essayer de faire une rotation de X-1 elements sur I (appel recursif), et je nomme le resultat temporaire R."
=>
On est d'accord que X est supérieur à 0 donc que tu retranches un positif.
Mais dans mon exercice c'est soit un décalage de 3, soit un décalage de -1.
Du coup c'est ton "X-1" que j'ai du mal à comprendre.
Dans mon exercice ça donnerait "X-3" ??

Comment tu vois/crée/fais du récursif ? (oui, je suis un gros noob)
C'est inhérent à l'utilisation du prolog pour ce que j'en ai compris, avec dépilement successifs, mais à quoi on le voit que là ça va être récursif et là non ? ^^

"Q : queue (=dernier element de A) (out)
B : liste A privee de sa queue (out)"
=>
Il veut dire quoi ton "(out)" ?

Après tu m'as largué. Je comprends pas d'où tu sors des variables T.
Et comme les variables veulent "rien dire" dans ce langage, je suis planté. :mort:
Je visualise pas le code entier de l'exercice. T'as gardé les mêmes variables ou tu en as changé en cours de route ??

"Cela parce que les arguments doivent etre des variables au sens de prolog, pas des expressions."
Ok.
Là je le vois comme attribuer une valeur à une variable, dans un autre langage. Donc je le comprends. ^^

"j'ai juste laissé aparaitre la démarche qui m'a guidé pour essayer de résoudre ton probleme."
=>
C'est pas plus mal. Parce que le corrigé n'est pas forcément intuitif...

    • ***********************************************
    • *******************

Pour info en langage j'ai que des connaissances en PHP et en java (html, css, ça "compte pas" ^^).

Je vais peut-être devoir reprendre l'aide sur les premiers petits exercices plutôt que les gros directement. :peur:

saleGauss
saleGauss
Niveau 9
17 novembre 2010 à 17:20:41

Bonjour,

Alors, tout d'abord, pour te répondre, il n'y a pas de "noob" qui tienne.
Il faut bien découvrir les choses une première fois, c'est parfaitement normal.
Tu as l'air de vouloir comprendre, je ne me fais pas de soucis pour toi, car c'est le principal.

Alors, allons y:

1/ Concernant l'unification, tu as compris le principe : l'idée est d'associer "ce qu'on a dans une regle" (variables, constantes) à ce qu'on a à prouver (variables, constantes), pour pouvoir se dire "ok, je suis bien de cette forme là (de la regle), et pour prouver ce que j'avais à prouver, je peux essayer de prouver la partie droite de la regle".

Je vais tout de suite donner un exemple tres simple, pour que l'on voit bien l'idée simple derriere cela.
Ce qui suit explique donc par un exemple l'exploration de l'arbre de recherche ET l'unification.

________________________
DEBUT DE L'EXEMPLE 1

Tu as des données :
[1/] mange(pierre,salade). @ J'affirme par cette donné que pierre mange de la salade
[2/]mange(paul,poisson). @ J'affirme par cette donné que paul mange du poisson.
[3/]mange(pierre,viande).

Si je pose à prolog la question
mange(pierre,X). (je ne met donc pas ça dans mon fichier, je l'entre sur l'interprete, comme pour toutes les questions que je lui pose)
ca veut dire que je lui demande de trouver tout ce que pierre mange (c'est à dire de trouver tous les X tels que mange(pierre,X) soit vrai).

Que fait prolog ?
Il va passer en revue tout ce qu'il sait sur le predicat mange() : les données (les 3 que l'on a ), et les regles (aucune ici).

Je dois résoudre mange(pierre,X) (en donnant à l'arrivée les valeurs de X qui vont bien)
Il commence en regardant la donnée [1] qu'il a dans son stock :
mange(pierre,salade)
Pour pouvoir utiliser ca, il doit pouvoir unifier pierre (de ce qu'il doit resoudre) à pierre (de la donnée) et X (de ce qu'il doit resoudre) à salade (de la donné).
On dit que l'unifieur est donc {pierre/pierre, salade/X}, ou plus simplement juste {salade/X} : on a unifié la variable X à la constante salade.
Et donc là Prolog a gagné : il peut utiliser la donnée, et comme la donnée affirme que mange(pierre,salade), il a réussi : il trouve X = salade.

Mais il n'a pas fini !
Il a trouvé une solution, mais Prolog va les chercher TOUTES !
Il a encore deux données à exploiter, on ne sait donc pas encore si il y a d'autres solutions, et on va bien voir :

Il regarde donc la donnée [2] :
mange(paul,poisson)
Je rappelle qu'il essaye de resoudre mange(pierre,X).
Pour utiliser cette donnée, il doit donc unifier paul à pierre, et poisson à X.
Et là ca coince ! Car il ne peut pas unifier paul à pierre !
Ce sont deux constantes différentes !
On parle "d'echec à l'unification".
Il ne peut donc pas utiliser cette donnée.
Cette "branche" ne donne donc pas de solution, elle.

L'interprete prolog n'a toujours pas fini !
Il doit à présent essayer d'utiliser la donnée [3] :
mange(pierre,viande)
Et je rappelle encore une fois qu'il essaye de resoudre :
mange(pierre,X).
On commence à etre habitué, et on voit tout de suite le succes : pierre est sans soucis unifié à pierre (il n'y a rien à faire) ET X est unifié à viande.
C'est un succès ! On peut donc utiliser cette donnée !
On a donc X = viande qui est une (autre) solution au probleme qu'on a posé.

Et là, Prolog n'a plus rien à faire : il avait trois données, il les a toutes regardé. Il n'avait aucune regle.
Il a donc regardé TOUT ce qu'il pouvait pour résoudre son probleme.
Et il a obtenu deux solutions, qui sont, je le rappelle : X = salade et X = viande

______________________________
FIN DE L'EXEMPLE 1

Maintenant que l'on a vu comment il fonctionne pour des choses tres tres simples, il faut voir comment il fonctionne quand il a à sa dispotion une regle. Et c'est exactement le meme principe !
Si ce n'est qu'avec une donnée, quand il arrive à unifier, il a gagné !
Et avec une regle, si il arrive à unifier ce qu'il doit demontrer à la tete de la regle (la partie à gauche du ":-") et bien cela signifie que pour démontrer ce qu'il doit démontrer, il peut se servir de cette regle, et il SE RAMENE DONC à resoudre la partie droite de la regle, en prenant en compte les unifications qui ont été faites en tete de regle bien sur.

_______________________________________

NOUVEL EXEMPLE (EXEMPLE 2)!
Reprenons exactement le meme exemple, et ajoutons une regle :

on a toujours les meme données :
[1/] mange(pierre,salade). @ J'affirme par cette donné que pierre mange de la salade
[2/]mange(paul,poisson). @ J'affirme par cette donné que paul mange du poisson.
[3/]mange(pierre,viande).

On a maintenant en plus une regle :
mange(pierre,Y) :- mange(paul,Y).
Que dit cette regle idiote ? Elle dit que mange(pierre,Y) EST VRAI SI mange(paul,Y) l'ai.
En clair, pierre mange tout ce que mange paul.
Cela signifie que pour trouver ce que pierre mange, on peut se servir de cette regle en regardant ce que mange paul, et conclure la meme chose pour pierre.
C'est donc une maniere DE PLUS de trouver ce que mange pierre.

Imaginons que l'on demande à Prolog de résoudre le meme probleme qu'avant :
mange(pierre,X).
Que se passe-t'il?

Le debut est exactement le meme !
Il regarde avec sa donnée 1, reussi en trouvant X = salade
Il regarde avec sa donnée 2, il echoue à l'unification.
Il regarde avec sa donnée 3, il reussi et trouve X = viande

A t-'il fini ? Non !
Il a une regle à essayer d'exploiter. Peut etre va t'on trouver encore autre chose !

Alors il doit (toujours) resoudre mange(pierre,X)
Et il a comme regle : mange(pierre,Y) :- mange(paul,Y)
On va donc essayer de faire "coller" ce qu'on doit prouver à la tete (la partie à gauche du ":-") de la regle :
Et on peut le faire en unifiant pierre à pierre, et X à Y.
On a donc reussi, cela signie que l'on peut utiliser cette regle ! Cela ne veut pas encore dire qu'elle nous donnera quelque chose, mais on peut l'explorer.
Donc, maintenant, il nous reste à résoudre la QUEUE de la regle : c'est à dire mange(paul,Y).
Et oui ! la regle ne nous a rien affirmé de spécial, elle nous a juste "renvoyée" vers quelque chose d'autre à démontrer.
ON ENTRE DONC DANS UN MORCEAU INDENTE Où ON ESSAYE DE RESOUDRE CE NOUVEAU TRUC :
-----Pour démontrer notre mange(pierre,X), on est donc amené -----à resoudre mange(paul,Y).

-----Et là que se passet-il ?
-----Et bien on va passer en revue nos données, nos regles, -----dans l'espoir de resoudre ce NOUVEAU basard.
-----Avec la donne 1/, on arrivera à rien, car on doit -----resoudre mange(paul,Y) et on a comme donne -----mange(pierre,salade).
-----On ne peut pas unifier paul à pierre, echec à -----l'unification.

-----Avec la donne 2/ :
-----On doti resoudre mange(paul,Y)
-----et la donnee nous dit mange(paul,poisson).
-----Et hop ! On peut unifier paulà paul sans soucis, et Y à -----poisson sans soucis !
-----On trouve donc Y = poisson.
-----Et on a prouvé le truc annexe que l'on devait prouver.
-----Mais je rappelle qu'on l'a pas prouvé pour rien !
-----On devait resoudre mange(pierre,X).
-----On avait unifié X à Y, et on était amené à resoudre -----mange(paul,Y).
-----On a trouvé Y = poisson.
-----Et donc X = poisson car X et Y on été unifiées !
-----C'est donc une nouvelle solution !

-----Avec la donnee 3/.
-----Et bien là, on aura rien.
-----Je rappelle que là, on cherche à resoudre mange(paul,Y).
-----Et que la donne 3/ nous dit mange(pierre,poisson)
-----On ne peut pas unifier paul à pierre, c'est un echec à -----l'unification.
-----On ne trouve rien ici.

-----A t-on fini ? NON !
-----On doit essayer la regle !
-----On doit prouver mange(paul,Y) et la regle nous dit :
-----mange(pierre,Y) :- mange(paul,Y).
-----Et on ne peut rien faire : on doit faire correspondre -----la partie gauche de la regle à ce que l'on doit -----prouver, mais on ne peut pas, car on ne peut pas -----unifier pierre à paul !

-----Et là, on a fini pour cette indentation!

On revient donc à notre mange(pierre,X). On a essayé les 3 données (qui ont amené deux succès), et la regle (qui a amené un succès).
Et on a plus rien à exploiter.
C'est FI-NI !

____________________________________
FIN DE L'EXEMPLE 2

Quelques remarques :

-Maintenant je pense que tu vois bien, l'unification, et la recherche dans l'arbre.
Là je dois t'avouer que j'ai été gentil, car je n'ai pas eu de conflits de variables : un X d'une regle pourrait rentrer en collision avec le X de quelque chose que l'on doit prouver.
Et ces deux X ne se connaissent pas, ce sont des X différents, comme dans "quelque soit X, A(X) est vrai"
mit à coté de "Il existe X tel que B(X)".
Ce sont des X qui ne se connaissent pas, qui n'ont rien à voir.
Bon et bien dans ces cas là, on effectuera un renommage pour ne pas faire rentrer en collision des choses (variables) qui bien qu'ayant la meme lettre par malchance ne se connaissent pas !
(Tu remarqueras que ici, il n'y avait pas de pb, car dans ma regle j'ai utilisé un Y ! :p )

- N'oublie pas que ce que j'ai essayé de te montrer sur un format textuel : la trace de la recherche de prolog dans nos donnees, c'est à en fait un arbre.
A chaque fois que je disais "donnée machin marche pas" ou "regle machin marche pas", on remonte au noeux qui nous a amené ici, et on continue avec les autres donnees/regles !

Je reponds à présent à tes questions :

->Là, tu as juste noté ça pour t'en rappeler plus tard ? Mais pourquoi si c'est la liste In tu ne l'appelles pas In dès le départ ?

La vérité, c'est que j'ai rajouté cette phrase apres, au depart j'ai ecris mon machin avec I, en ayant dans la tete "In".
Et je me suis dis, je vais lui préciser que c'est I pour abréger "In".
Tu as bien entendu le droit d'utiliser des noms plus longs.
Je ne sais pas pourquoi, la coutume en prolog fait qu'on utiliser souvent une seul lettre, et tu as raison, c'est tres moche !
Si tu as besoin de mettre In, met In.
Une seule regle : une variable commence par une Majuscule, et une constante par une minuscule ! (si je ne mettais pas de majuscule au prenom, ce n'est donc pas par impolitesse ! :p Ce sont des constantes)
Bref, il y avait bien une seule variable que j'ai nommé I, mais que tu peux appeller (et changer) en In.

(suite apres, message trop long :d)

saleGauss
saleGauss
Niveau 9
17 novembre 2010 à 17:21:17

-> <<< La différence entre une règle conditionnelle et non conditionnelle c'est quoi ?
Le fait que la non conditionnelle n'a pas de règles derrière le ":-" mais se termine directement par un "." ?

Le prédicat rotation(I,0,I). tu le lis comment ? J'ai besoin de "verbose" pour retenir. >>>

Ce que j'ai appellé regle conditionnelle c'est :
-------------------------------
A(X) :- B(X).
. Ce que ca raconte
Qui veut dire en logique : B(X) -> A(X)
Et qui se lit en francais "A(X) est vrai Si B(X) est vrai"
Ou encore "Si B(X) Alors A(X)".
Dans tous les cas, l'idée est que l'on pourra CONCLURE A(X) si l'on arrive à résoudre B(X).
. utilisation par nous :
On s'en sert pour raconter que implications logique.
Comme je l'ai fais avec mange(pierre,Y) :- mange(paul,Y)
J'ai raconté que mange(paul,Y) implique mange(pierre,Y)
. utilisation par l'interpretre prolog
Lorsque prolog doit resoudre A(Z), à un moment donné, il va essayer cette regle (comme TOUTES les données, et TOUTES les regles).
Il va donc essayer de faire coller la tete de la regle (la CONCLUSION) à ce que l'on essaye de resoudre (A(Z)).
Si il arrive, ca veut dire que cette regle va peut etre lui apporter quelque chose.
Et pour savoir, il n'aura plus qu'à résoudre la partie droite de la regle.
Si il y arrive, et bien il aura resolu grace à la regle (et eventuellement d'autres choses derriere) ce qu'il devait resoudre.

Ce que j'ai appelé regle inconditionne c'est :
----------------------------------
A(X).
. Qui signifie "A(X) est toujours vrai".
Et pourquoi ? Et bien pense la comme une regle conditionnelle, mais avec aucune condition en partie droite du ":-".
Et on a donc toujours A(X).
. Utilisation par nous
On crée ce genre de regle pour définir quelque chose de paramétré par des variables (ce n'est donc pas une donnée, car il y a une/des variables) qui est toujours vrai.
Par exemple dans mon rotation(I,0,I) :
(je rappelle que arg 1 : liste IN
arg 2 : entier in
arg3 : liste IN avec les rotations de faites
je disais qu'il est toujours vrai qu'une liste I est la rotation d'elle meme (I) avec 0 deplacements.

. utilisation par l'interprete prolog
Et bien si prolog doit resoudre
rotation([A,B,C],0,X), il pourra unifier I à [A,B,C], 0 à 0 et I à X.
Au final, il aura unifié X à [A,B,C].
C'est donc une reussite à l'unification.
Et donc il trouve que X = [A,B,C]

Contrairement aux regles que j'appellais conditionnelles, si il passe l'unification, boum il a un resultat !
Alors qu'avec une regle conditionnelle, si il passait l'unification il lui restait encore à résoudre la partie droite de la regle !

-> <<<<< "[Etape 1]
Et bien si X est strictement superieur à zero, je vais essayer de faire une rotation de X-1 elements sur I (appel recursif), et je nomme le resultat temporaire R."
=>
On est d'accord que X est supérieur à 0 donc que tu retranches un positif.
Mais dans mon exercice c'est soit un décalage de 3, soit un décalage de -1.
Du coup c'est ton "X-1" que j'ai du mal à comprendre.
Dans mon exercice ça donnerait "X-3" ?? >>>

ATTENTION !
Dans tes exemples, tu as des des exemples d'utilisation de ton predicat (que tu dois coder)!
Il te dit que si tu demandera à prolog de resoudre

{ ?- rotation([a,b,c,d,e],3,L).

Il devra te repondre :
{ L = [c,d,e,a,b]

Si tu demande à prolog de resoudre :
{ ?- rotation([a,b,c,d,e],-1,L).

Il devra te repondre :
{ L = [b,c,d,e,a]

Ce sont des exemple d'utilisation de ton FUTUR predicat, qui doivent te permettre de comprendre le probleme.
Ce ne sont que des exemples.
TOn programme devra marcher avec X = 3, X = -1, MAIS AUSSI X = -18, X = 14...

Les exemples d'utilisations t'aident à comprendre le probleme que tu dois resoudre, et comment on utilisera le predicat que tu dois coder.
Ils te montrent aussi ici que ton predicat doit marcher pour un X < 0 aussi, que tu aurais pu ne pas traiter! Là c'est imposé ! On t'a montré qu'on doit pouvoir se servir du machin (predicat) que tu vacoder pour un nombre negatif. Et l'exemple t'aide à voir comment le predicat que tu vas ecrire devra reagir : là on voit qu'on (ton prof) EXIGE que ca fasse une rotation dans l'autre sens.
Comme je te l'ai dis, j'avais moi travaillé le cas X > 0.
il restait donc le cas X<0 à traiter.

-> <<<< Comment tu vois/crée/fais du récursif ? (oui, je suis un gros noob)
C'est inhérent à l'utilisation du prolog pour ce que j'en ai compris, avec dépilement successifs, mais à quoi on le voit que là ça va être récursif et là non ? ^^ >>>>>

C'est une question large.
Je pense rapidement à la recursivité lorsque je dois resoudre un probleme sur des structures de données qui sont inductives (comme des listes : c'est un element en tete d'un reste).
Ca c'est le cas le plus frequent.

Mais moi là, j'ai fais de la resursivité sur un entier (X).
Les entiers ont une strucutre inductive : tout naturel est soit zero soit le successeur d'un autre naturel).
Mais ce n'est pas cela qui m'a poussé à ecrire quelque chose de reursif ici.
Ou du moins pas que.
Il y a le fait que l'on doit faire quelque chose qui semble compliqué pour un N.
Or, passer de N-1 à N, dans notre probleme, c'est juste deplacer la queue (le dernier element) de la liste en tete.
Donc Imaginons que je sache resoudre le probleme pour X-1, et bien je peux facilement faire cela pour X.
Et c'est ce que j'ai fais.
J'ai dis, pour X, fais le pour X-1, puis fais deplace la queue en tete.

Et j'ai bien sur un cas d'arret : Pour X=0, c'est la regle 1/. La fameuse rotation(I,0,I), qui me permettra de m'arreter.

Je n'ai malheureusement plus trop de temps, et puis on s'eloignerais du sujet et mon pavé commence à etre enorme là, mais sache que la recursivté/l'induction c'est :

Si Je sais resoudre mon probleme pour une valeur simple.

ET

Si la faculté de resoudre le probleme pour X-1 me permet de resoudre le probleme pour X,

Alors je sais resoudre mon probleme pour X quelconque !

pense à une echelle :
SI je sais monter sur le premier barreau.
Et SI la faculté de monter sur un barreau X me donne tres facilement la faculté de monter sur le barreau X+1
ALORS je sais monter sur tous les barreaux de l'echelle.

Si tu as vu la recurrence (qur les suites) en terminale, c'est exactement le meme principe.
Sauf que l'induction, c'est plus general que "juste" pour les entiers.

-> <<<< "Q : queue (=dernier element de A) (out)
B : liste A privee de sa queue (out)"
=>
Il veut dire quoi ton "(out)" ? >>>>

Mon (out) sert à te précier, et à préciser à l'utilisateur de mon futur predicat, que cette variable est concue pour etre une variable de sortie. C'est un RESULTAT.

Et les arguments (in) sont pensés pour etre donné en ENTREE.

Bon, tu verras bien plus tard que des arguments que l'on a prvu pour etre des entrées peuvent sertir de sortie aussi, mais là, c'est carrement supperflu pour le moment.
Sache juste que cela s'appelle la reversibilité, et que c'est quelque chose de très puissant.
Mais dans un premier temps : on fixe des truc qui vont rentrer dans notre predicat, des trucs qui sont des sorties (donc on donne une variable V et il nous donnera une constante), et on RACONTE quand est-ce que le predicat est vrai.

Voila, j'espere sincerement ne pas t'avoir largué.
Bon courage, bosse bien.
Et n'hesite pas à taper "recursvivité", "induction structurelle", "récurrence", pour bien voir le principe.
En prolog, c'est vraiment omnipresent (comme dans les langages fonctionnels d'ailleurs).

Thanhatos
Thanhatos
Niveau 39
18 novembre 2010 à 04:57:48

Exemple 1 : compris.

Exemple 2 :
- Quand tu m'expliques ce qui se passe pour la donnée 2, tu n'as pas confondu X avec Y ?
J'aurais dit qu'on a unifié Y à Y, puisqu'au départ notre règle est """ mange(pierre,Y) :- mange(paul,Y) """.
- Auquel cas, même si dans notre "base de données/faits" on n'a pas écrit mange(pierre,poisson), le fait que la condition nous sorte qu'il existe un mange(paul,poisson) et que poisson est unifié à Y ne nous donne donc pas au final un résultat comme quoi mange(pierre,poisson) ?
Fait qui n'est pas dans notre base, mais comme les variables ont été unifiées, ce que mange pierre devient ce que mange paul.
C'est correct ou à côté de la plaque ?

En tappant sur Sicstus j'obtiens ça =>
? mange(pierre,Y) :- mange(paul,Y).
Context error: clause appeared in query
goal: mange(pierre,_80):-mange(paul,_80)

Donc où je ne comprends pas l'erreur, ou en fait tu voulais écrire la règle suivante => mange(pierre,X) :- mange(paul,Y).
??

[ 5 minutes plus tard ]

Aaaaaah.
En écrivant la règle dans mon programme, j'ai compris (faut dire que je suis pas à l'aise avec le bouzin pour le moment).

Donc comme je l'avais pensé juste au dessus, tu avais bien mis des Y pour les 2 termes, et donc prolog dans le déroulement me donne bien pour mange(pierre,Y) :- mange(paul,Y). les résultats suivants =>
Y= salade ? ;
Y = viande ? ;
ET ENSUITE il s'occupe de vérifier l'autre partie de la règle, la condition concernant mange(paul,Y). Et là il me trouve =>
Y = poisson ? ;
Et plus de résultat supplémentaire derrière, car il a vidé toutes les possibilités.

J'ai compris le truc ?

[C'est une logique tordue à mon goût... mais je commence peut-être à voir poindre le bout de logique auquel je peux me raccrocher. ^^]

Règle de syntaxe des variables et des constantes : ok.

Différence entre règle conditionnelle et règle inconditionnée : ok.

Ma terminale remonte à il y a 7 ans (que c'est loin punaise), donc j'ai que de très vagues souvenirs des maths de l'époque, surtout en ayant changé d'orientation pour aller en informatique depuis les dernières années. Pour info'. ^^

Mais j'ai relu les définitions de récurrence et récursivité pour me remettre ça en tête. C'est beau la magie du net.

In et Out : ok.
En fait quand j'ai vu In pour in j'ai compris que c'était pas Ln (va savoir pourquoi j'ai lu un L...).

Je te remercie beaucoup. Tu ne m'as pas largué, bien au contraire.
Je commence à comprendre le truc même si c'est fragile. Maintenant j'ai pas pris l'exercice qui m'était le plus facile à comprendre non plus... ^^

Je vais surement te reposer des questions et/ou des exercices, mais pour l'heure je fais une pause et je dois pas oublier les autres matières.

Encore merci, je désespère un peu moins de comprendre comment ça marche ! :-)

Thanhatos
Thanhatos
Niveau 39
18 novembre 2010 à 04:59:58

Au passage, les pavés ne me dérangent pas. ^^
Je suis pas du genre à me plaindre de la longueur des écrits.

Si ce qui est simple s'énonce clairement ce n'est pas pour autant que l'on peut tout contracter et l'énoncer rapidement.
C'est un concept qui a du mal à se faire une place dans notre société actuelle du "tout tout de suite"...

Tu pourrais écrire 3 pages que je prendrais le temps mais je le lirais (surtout quand c'est pour moi ^^).

Merci.

saleGauss
saleGauss
Niveau 9
18 novembre 2010 à 07:39:08

Avec grand plaisir.
J'avoue que j'aime vraiment Prolog (du moins, pour les problemes qui se prettent à son utilisation), donc je me fais plaisir à essayer de te raconter un peu tout ça.

Je pense que tu as compris le truc, que ça commence à saisir.
Pour l'exemple 2, je pense aussi que tu as saisi : c'est comme l'exemple 1 (il passe en revue toutes les données pour ce predicat qu'il a sous la main), PLUS toutes les regles qu'il a sous la main pour ce predicat là (ici, une seule).
Lorsqu'il utilise une regle, il fait coller (=unifier) la partie conclusion (la partie gauche) de la regle à ce qu'il doit prouver. Et si il réussit, il n'a plus qu'à démontrer la partie droite.

Ici, notre regle a servit quand il devait resoudre mange(pierre,X), qu'il a reussi à le coller à sa regle :
mange(pierre,Y) -: mange(paul,Y)
(en unifiant X à Y), et il ne lui restais plus qu'à résoudre mange(paul,Y) : ce qui est parfaitement logique en soit, car on a bien vue que cette regle nous dit "Pierre mangera tout ce que mange Paul". Si on cherche ce que mange Paul (dans la partie indentée avec des -----), on pourra donc peut etre trouver des solution à ce "sous-probleme" (des Y=...), qui nous amenene directement à des solutions à notre probleme initial (des X=....)
(Cela car X et Y ont été unifié pour pouvoir utiliser la regle).

Bref, en prenant du recul, le comportement de Prolog est normal : il te revoit bien les 3 valeurs de X que nous avions prévu : les deux premieres sont obtenues avec les données, et le troisieme (le X = poisson), grace à l'utilisation par l'interprete Prolog de la regle PUIS la résolution de mange(paul,Y) (en indenté).

Je te souhaite une bonne journée, et n'hesite pas si tu coince.
Je ferrais de mon mieux.

Sous forums
  • Aide à l'achat Mac
  • Steam Deck
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Macintosh
  • Hardware
La vidéo du moment