2011-10-20 4 views
0

Je suis en train de mettre en œuvre un arbre généalogique en utilisant Strawberry Prolog (ce que les laboratoires d'informatique ont à mon école) et je voudrais me débarrasser des réponses en double. La fonction findall fonctionne dans Strawberry Prolog qui met toutes les réponses dans une liste, mais je crois que setof n'existe pas avec ce compilateur. Je pourrais soit basculer les compilateurs ou ajouter la fonction setof à celui-ci. Je pense que ce dernier serait une meilleure expérience d'apprentissage, mais je n'ai aucune idée par où commencer.Strawberry Prolog setof

Est-ce que quelqu'un connaît le code derrière la fonction setof dans d'autres compilateurs et comment le convertir en Strawberry Prolog? Ou existe-t-il déjà une fonction similaire à setof dans Strawberry Prolog?

Merci.

Répondre

0

Vous pouvez simplement trier la sortie de findall. Bien sûr, l'implémentation de setof est beaucoup plus gratifiante, mais certainement pas simple. Voici la source de SWI-Prolog:

%%  setof(+Var, +Goal, -Set) is semidet. 
% 
% Equivalent to bagof/3, but sorts the resulting bag and removes 
% duplicate answers. We sort immediately after the findall/3, 
% removing duplicate Templ-Answer pairs early. 

setof(Templ, Goal0, List) :- 
    '$free_variable_set'(Templ^Goal0, Goal, Vars), 
    ( Vars == v 
    -> findall(Templ, Goal, Answers), 
     Answers \== [], 
     sort(Answers, List) 
    ; findall(Vars-Templ, Goal, Answers), 
     ( ground(Answers) 
     -> sort(Answers,Sorted), 
     pick(Sorted,Vars,List) 
     ; bind_bagof_keys(Answers,_VDict), 
     sort(Answers, Sorted), 
     pick(Sorted, Vars, Listu), 
     sort(Listu,List) % Listu ordering may be nixed by Vars 
     ) 
    ). 

Comme vous pouvez le voir, la base, il est toujours findall ...

+0

Merci. J'ai essayé de l'implémenter, sans succès. J'ai fini par passer à SWI-Prolog. J'ai réussi à faire fonctionner mon programme, mais j'ai maintenant un problème différent. La liste que j'imprime à l'écran est trop longue et une partie de celle-ci est coupée en tant que | ...]. Y at-il une commande que je peux utiliser pour étendre la taille maximale de la liste ou modifier la longueur d'impression? – Tijgerlili

+0

Peu importe. Je l'ai compris. :RÉ – Tijgerlili