Question

Je l'ai mis en œuvre la fonction suivante dans Prolog avec le code suivant:

abs2(X, Y) :- X < 0, Y is -X.
abs2(X, X) :- X >= 0, !.

Comment puis-je mettre en œuvre cette fonction sans l'utilisation de coupe ( « ! »)?

Était-ce utile?

La solution

Il y a la coupe "caché" dans le if-then-else construction de Prolog:

abs2(X,Y) :- X < 0 -> Y is -X ; Y = X.

Il est quelque chose d'une bizarrerie, mais Prolog ne backtrack sur le sous-but qui forme la « prémisse » d'un if-then ou if-then-else construction. Ici, si X <0 réussit le premier essai, le choix de « puis » clause sur la clause « else » est engagée (donc la description de ce comportement comme une coupure « cachée »).

Il y a plus d'un rôle pour une coupe dans la premier clause du prédicat ABS2 / 2 comme il est écrit dans la question. Comme Nicholas souligne, la coupe à la fin de la deuxième clause n'a pas d'effet (il n'y a pas de points de choix à gauche quand vous y arrivez). Mais comme Kaarel souligne, il y a un point de choix reste ouvert si la première clause réussit.

Alors, ce que je l'ai écrit, ce qui permet l'utilisation d'une coupure, est la suivante:

abs2(X,X) :- X >= 0, !.
abs2(X,Y) :- Y is -X.

Les commentaires de Nicholas suggèrent également des moyens de « arithmetize » la valeur absolue (plutôt que d'utiliser une définition logique) et éviter « cut » de cette façon.

Autres conseils

Mon Prolog est un peu rouillé, mais pourquoi avez-vous besoin même la coupe? Si vous écrivez le prédicat correctement, retours en arrière ne peut pas réussir, de sorte que la coupe est inutile:

abs(X, Y) :- number(X) , X <  0 , Y is -X .
abs(X, X) :- number(X) , X >= 0 .

Pas besoin d'utiliser

Il suffit d'écrire:

abs2(X,Y) :- Y is abs(X).
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top