2016-03-09 1 views
1

J'apprends Prolog et j'ai suivi this tutorial for graphs. Voici mon code:Ecriture d'un prédicat Prolog pour fournir des paramètres par défaut à un autre prédicat

path(X, Y, Length, [X,Y], _) :- 
    connect(X, Y, Length). 
path(X, Y, Length, [X|P], V) :- 
    \+ member(X, V), 
    connect(X, Z, Length1), 
    path(Z, Y, Length2, P, [X|V]), 
    Length is Length1 + Length2. 

Pour utiliser cela, j'appelle

?- path(a, f, Length, Path, []). 

Cependant, je voudrais le raccourcir à:

?- path(a, f, Length, Path). 

Mais je ne peux pas la valeur par défaut paramètres à travailler.

+0

Voir ['this definition'] (http://stackoverflow.com/q/30328433). – false

+0

@false J'ai d'abord lié cette question même; cependant, si les bords ont des valeurs qui leur sont associées, ce n'est que la moitié de la réponse. Je veux profiter de cette occasion pour demander: y a-t-il un seul endroit où l'on peut trouver tout le bon code écrit par vous (et quelques-unes des bonnes réponses)? Actuellement, il est dispersé autour de la balise Prolog, et j'ai souvent du mal à la trouver même si je sais que c'est quelque part là-bas ... –

+0

@Boris: Voir mon profil et [cet endroit] (http: //www.complang.tuwien .ac.at/ulrich/Prolog-inédit /). Je prévois de les mettre sous une forme plus complète, mais c'est beaucoup plus de travail qu'il n'y paraît car j'essaie de me conformer à tous les égards possibles. – false

Répondre

6

straight-forward Tout: il suffit de définir un prédicat avec le même nom qui appelle le prédicat faire le travail:

path(X, Y, Length, Path) :- 
    path(X, Y, Length, Path, []). 

En Prolog, prédicats sont toujours appelés avec Name/Arity car même nom mais différent arité les rend deux prédicats séparés. Donc, maintenant votre programme aura à la fois path/4 et path/5 défini. En ce qui concerne la dénomination: si les deux prédicats font partie de votre interface, ils doivent avoir le même nom. De nombreux exemples dans les bibliothèques standard Prolog, par exemple format/1, format/2, format/3.

Si, toutefois, le prédicat de travail est uniquement destiné à être utilisé comme prédicat auxiliaire, vous lui attribuez généralement un suffixe. Pour utiliser quelque chose de simple comme list_max/2:

list_max([X|Xs], Max) :- 
    list_max_SUFFIX(Xs, X, Max). 

J'ai vu code où SUFFIX est juste un trait de soulignement: list_max_/3 (et vous continuer à ajouter des underscores pour plus d'aide prédicats dans la même lignée sous-jacente); ou, souligner + numéro: list_max_1/3 (et vous incrémentez le nombre); ou, _aux + numéro facultatif, si vous en avez plus: list_max_aux/3. En utilisant le caractère de soulignement + numéro:

list_max_1([], Max, Max). 
list_max_1([X|Xs], Max0, Max) :- 
    compare(Order, X, Max0), 
    list_max_2(Order, X, Max0, Xs, Max). 

list_max_2(<, _, Max0, Xs, Max) :- list_max_1(Xs, Max0, Max). 
list_max_2(=, _, Max0, Xs, Max) :- list_max_1(Xs, Max0, Max). 
list_max_2(>, X, _, Xs, Max) :- list_max_1(Xs, X, Max). 

Mais attendez, il y a plus. Si vous utilisez un schéma de dénomination pour vos prédicats où le nom représente les arguments, vous obtenez par exemple setup_call_cleanup/3 et call_cleanup/2, défini comme setup_call_cleanup(true, Goal, Cleanup). Avec ce schéma de nommage, vous appelleriez votre "chemin" prédicats peut-être from_to_length_path/4 et from_to_length_path_acc/5. Je trouve ce schéma de nommage sympa car il est auto-documenté, mais comme le montre cet exemple, il pourrait devenir excessif si votre prédicat a trop d'arguments.

+3

s (X) pour votre réponse élaborée! – repeat

+1

@repeat Apparemment, je n'ai rien de mieux à faire et nulle part ailleurs. –

+1

Il n'y a ** rien de mieux à faire et nulle part ailleurs :) – repeat