2012-05-21 1 views
2

J'essaye d'écrire un programme d'arbre généalogique dans Prolog pour mes devoirs. C'est une partie du code.Arbre généalogique Prolog

/** a sample fact **/ 
parents(someone, someoneelse, child). 

/** are M and F parents of the children in the given list? **/ 
parents(M,F,[]) :- parents(M,F,_). 
parents(M,F,[First|Rest]) :- parents(M,F,First), parents(M,F,Rest). 

/** are M and F parents? **/ 
parents(M,F) :- parents(M,F,_). 

Lorsque j'utilise une requête qui correspond au fait, le code ci-dessus fonctionne.

[trace] 25 ?- parents(someone,someoneelse). 
     Call: (6) parents(someone, someoneelse) ? creep 
     Call: (7) parents(someone, someoneelse, _G586) ? creep 
     Exit: (7) parents(someone, someoneelse, child) ? creep 
     Exit: (6) parents(someone, someoneelse) ? creep 
    true 
    . 

Mais quand j'essaie ceci:

[trace] 26 ?- parents(aa, bb). 
    Call: (6) parents(aa, bb) ? creep 
    Call: (7) parents(aa, bb, _G541) ? creep 
    Call: (8) parents(aa, bb, _G541) ? creep 
    Call: (9) parents(aa, bb, _G541) ? creep 
    Call: (10) parents(aa, bb, _G541) ? 
... 

cela ne fonctionne pas, il entre dans une boucle infinie. Qu'est-ce que je fais mal ici?

Edit: J'ai changé le code en tant que tel:

/** a sample fact **/ 
parents(someone, someoneelse, child). 

/** are M and F parents of the children in the given list? **/ 
parents(M,F,[]). 
parents(M,F,[First|Rest]) :- parents(M,F,First), parents(M,F,Rest). 

/** are M and F parents? **/ 
parents(M,F) :- parents(M,F,A), not(A=[]). 

Maintenant ce que je reçois est ceci:

[trace] 3 ?- parents(a,b). 
    Call: (6) parents(a, b) ? creep 
    Call: (7) parents(a, b, _G514) ? creep 
    Exit: (7) parents(a, b, []) ? creep 
^ Call: (7) not([]=[]) ? creep 
^ Fail: (7) not(user: ([]=[])) ? creep 
    Redo: (7) parents(a, b, _G514) ? creep 
    Call: (8) parents(a, b, _G508) ? creep 
    Exit: (8) parents(a, b, []) ? creep 
    Call: (8) parents(a, b, _G509) ? creep 
    Exit: (8) parents(a, b, []) ? creep 
    Exit: (7) parents(a, b, [[]]) ? creep 
^ Call: (7) not([[]]=[]) ? creep 
^ Exit: (7) not(user: ([[]]=[])) ? creep 
    Exit: (6) parents(a, b) ? creep 
true 
. 

Je ne comprends pas pourquoi il va refaire après échec maintenant. Des idées?

Répondre

0

Vous devez arrêter la recherche. Prolog va passer toutes les règles et trouver une correspondance. Si cela correspond, alors il va passer par l'expansion et répéter le processus.

La 2ème ligne est la cause de la boucle inf, car ne s'en soucie pas (de la dernière règle) est mappée à [].

Si vous voulez savoir si une paire est parent d'un enfant ou non, vous supprimez juste les 2 règles du milieu:

parents(M,F,[]) :- parents(M,F,_). 
parents(M,F,[First|Rest]) :- parents(M,F,First), parents(M,F,Rest). 
+0

Que voulez-vous dire avec ne pas le déclarer? – hattenn

+0

Si vous ne déclarez pas le fait, prolog ne peut pas produire de réponse. Eh bien, c'est ce que je peux dire à partir de l'information donnée. – nhahtdh

+0

parents (quelqu'un, quelqu'un, enfant). Cette ligne ne déclare-t-elle pas le fait? – hattenn

0

J'ai le sentiment que vous confondez deux prédicats différents en un seul :

/** a sample fact **/ 
parents(someone, someoneelse, child). 

/** are M and F parents of any child? **/ 
parents(M,F) :- parents(M,F,_). 

/** are M and F parents of the children in the given list? **/ 
parents_of_all_children(M,F,[]). 
parents_of_all_children(M,F,[First|Rest]) :- 
    parents(M,F,First), parents_of_all_children(M,F,Rest). 

Ensuite, vos requêtes de sens:

?- parents(someone, someoneelse, C). 
C = child. 
%-- someone & someoneelse have child "child" 

?- parents(A, B). 
A = someone, 
B = someoneelse. 
%-- all possible parent pairs out there 

?- parents(aa, bb). 
false. 
%-- do "aa" & "bb" form a parents pair? 
Questions connexes