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 :

meta-interpreteur: comment trouver un prédicat?


Sujet :

Prolog

  1. #1
    Futur Membre du Club
    Inscrit en
    Mai 2009
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 6
    Points : 5
    Points
    5
    Par défaut meta-interpreteur: comment trouver un prédicat?
    Il y a longtemps, j'ai suivi un cours du langage APL.
    L'instructeur a commencé en disant "Pour apprendre l'APL, la pire handicap est d'avoir appris un autre langage auparavant".

    C'est peut-être vrai pour prolog aussi, en tous cas pour moi...
    J'ai un petit meta-interpreteur:
    fact(father(mel,maurice)).
    fact(father(maurice,thomas)).
    fact(father(maurice,nicolas)).
    rule(son(X,Y),[father(Y,X)]).
    rule(grandson(X,Z),[son(X,Y),son(Y,Z)]).

    prove([],E):-
    E=[].
    prove([X|Y],[E1|E2]):-
    prove(X,E1),
    prove(Y,E2).
    prove(X,E):-
    \+ rule(X,_),
    fact(X),
    E=X.
    prove(X,E):-
    rule(X,[R1|R2]),
    prove([R1|R2],[E1|E2]),
    E=[E1|E2].
    qui fonctionne bien:
    20 ?- prove(grandson(X,Y),Z).
    X = thomas,
    Y = mel,
    Z = [[father(maurice, thomas)], [father(mel, maurice)]] ;
    X = nicolas,
    Y = mel,
    Z = [[father(maurice, nicolas)], [father(mel, maurice)]] ;
    false.

    21 ?- prove(grandson(thomas,mel),Z).
    Z = [[father(maurice, thomas)], [father(mel, maurice)]] ;
    false.
    Cependant, je ne vois pas comment poser la question "quelle est la relation entre X et Y?", à la sauce:
    22 ?- relation(thomas,mel,X).
    X = grandson
    Je voudrais garder les primitifs FACT et RULE car j'utilise prolog comme moteur intégré dans une autre application.

    Possible?

    Merci d'avance!

  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
    Bonjour.

    je n'ai pas le temps d'approfondir tout de suite, mais tu devrais t'intéresser au prédicat =.. qui permet ce genre de décomposition :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    12 ?- father(mel,maurice) =.. L.
    L = [father, mel, maurice] ;
    false.
    Je pense qu'en trifouillant avec tu devrais arriver à obtenir des résultats !

    Attention c'est du SWI-Prolog.

  3. #3
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Bon, finalement, ça a été plus rapide que je pensais :
    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
    relation(X, Y, R1) :-
    	rule(R, _F),
    	R =.. [R1, _, _],
    	R2 =..[R1, X, Y],
    	rule(R2, F),
    	test_regle(F).
     
    test_regle([]).
     
    test_regle([F | T]) :-
    	fact(F),
    	test_regle(T).
     
    test_regle([F | T]) :-
    	rule(F, L),
    	test_regle(L),
    	test_regle(T).
     
     
    test :-
    	writeln('relation(maurice, mel, R)'),
    	relation(maurice, mel, R),
    	writeln(R), nl,	
    	writeln('relation(thomas, mel, R)'),
    	relation(thomas, mel, R1),
    	writeln(R1).
    avec pour résultat :
    23 ?- test.
    relation(maurice, mel, R)
    son

    relation(thomas, mel, R)
    grandson
    true.

  4. #4
    Futur Membre du Club
    Inscrit en
    Mai 2009
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Comme d'habitude, très, très fort. Merci beaucoup.

    Cependant:
    1 ?- relation(maurice,X,Y).
    X = mel,
    Y = son ;
    false.
    Alors que j'ai deux fils, Thomas et Nicolas.
    J'ai essayé de m'inspirer en ajoutant:
    relation(X, Y, R1) :-
    fact(R),
    R =.. [R1, _, _],
    R2 =..[R1, X, Y],
    fact(R2).
    mais mes fils se multiplient comme des lapins:
    7 ?- relation(maurice,X,Y).
    X = mel,
    Y = son ;
    X = thomas,
    Y = father ;
    X = nicolas,
    Y = father ;
    X = thomas,
    Y = father ;
    X = nicolas,
    Y = father ;
    X = thomas,
    Y = father ;
    X = nicolas,
    Y = father.
    8 ?-


    Désolé de ne pas capter plus vite, c'est vraiment une autre manière de penser.

    Merci beaucoup encore pour ton aide.

  5. #5
    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
    Et sous cette forme ?
    17 ?- relation(X, maurice, R).
    X = thomas,
    R = son ;
    X = nicolas,
    R = son ;
    false.
    Il y a un ordre dans X et Y.

  6. #6
    Futur Membre du Club
    Inscrit en
    Mai 2009
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    D'accord, mais où est

    X = mel
    R = father ?

    J'ai un papa aussi !

    En réalité il faut que relation(X,Y,Z) énumère TOUTES les rélations.

  7. #7
    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
    Tu t'es un peu compliqué la vie, mais tu étais sur la bonne voie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    relation(X, Y, R1) :-
    	rule(R, _F),
    	R =.. [R1, X, Y],
    	rule(R, F),
    	test_regle(F).
     
    relation(X, Y, R1) :-
    	fact(R),
    	R =.. [R1, X, Y].
    Sortie
    12 ?- relation(maurice,X,Y).
    X = mel,
    Y = son ;
    X = thomas,
    Y = father ;
    X = nicolas,
    Y = father.

  8. #8
    Futur Membre du Club
    Inscrit en
    Mai 2009
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Superbe, merci beaucoup !



    Pour ceux qui voudrait essayer l'ensemble:
    fact(father(mel,maurice)).
    fact(father(maurice,thomas)).
    fact(father(maurice,nicolas)).

    rule(son(X,Y),[father(Y,X)]).
    rule(grandson(X,Z),[son(X,Y),son(Y,Z)]).

    % Find if a predicate relation of the form R1(X,Y) exists
    relation(X, Y, R1) :-
    rule(R, _F),
    R =.. [R1, _, _],
    R2 =..[R1, X, Y],
    rule(R2, F),
    derivable(F).
    relation(X, Y, R1) :-
    fact(R),
    R =.. [R1, X, Y].

    % Used by relation to see if the rule or fact can be derived
    derivable([]).
    derivable([F | T]) :-
    fact(F),
    derivable(T).
    derivable([F | T]) :-
    rule(F, L),
    derivable(L),
    derivable(T).

    % If a fact X of the form A(B,C,..) can be proved, show how it is proven, as a list of facts
    prove([],E):-
    E=[].
    prove([X|Y],[E1|E2]):-
    prove(X,E1),
    prove(Y,E2).
    prove(X,E):-
    \+ rule(X,_),
    fact(X),
    E=X.
    prove(X,E):-
    rule(X,[R1|R2]),
    prove([R1|R2],[E1|E2]),
    E=[E1|E2].

    test:-
    writeln('Maurice has the following relations:'),
    findall((X,Y),relation(maurice,X,Y),R),
    writeln(R),
    writeln('Thomas is a grandson of somebody, because:'),
    findall((X,Y),prove(grandson(thomas,X),Y),P),
    writeln(P).
    Ce qui donne:
    29 ?- test.
    Maurice has the following relations:
    [ (mel, son), (thomas, father), (nicolas, father)]
    Thomas is a grandson of somebody, because:
    [ (mel, [[father(maurice, thomas)], [father(mel, maurice)]])]
    true.

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

Discussions similaires

  1. Comment trouver le texte sous le curseur ?
    Par deetox dans le forum Langage
    Réponses: 2
    Dernier message: 06/08/2005, 13h54
  2. Comment trouver de vieux outils (MASM51 CL PROM86 XLINK86)
    Par CFred dans le forum Choisir un environnement de développement
    Réponses: 2
    Dernier message: 11/01/2005, 17h54
  3. Réponses: 3
    Dernier message: 21/01/2004, 08h47
  4. Comment trouver le répertoire démarrage sous 98?
    Par PHILOSOPHE dans le forum API, COM et SDKs
    Réponses: 6
    Dernier message: 18/11/2003, 20h10
  5. [CR] Comment trouver un champs dans un report ??
    Par Madduck dans le forum SAP Crystal Reports
    Réponses: 4
    Dernier message: 18/09/2003, 08h31

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