Ihre Frage ist sehr legitim, +1.
Der Grund für diese scheinbar willkürliche Wahl ist, dass (is)/2
ein vergleichsweise niedrige Ebene Prädikat ist und funktioniert nur in sehr speziellen Fällen, die nur prozedural verstanden werden können, deklarativ nicht. Daher ist (is)/2
für Anfänger sehr schwer zu verstehen und sollte besser vermieden werden, da es viele relationale Eigenschaften zerstört, die wir bei der Verwendung von Prolog genießen möchten.
Die deklarative Lösung ist Constraints, wo Sie genau das tun können, was Sie sagen. Bei Beziehungen über ganze Zahlen ersetzen Sie einfach (is)/2
durch (#=)/2
, um die relationalen Eigenschaften zu genießen, die Sie intuitiv erwarten.
Zum Beispiel mit GNU Prolog:
count([], 0).
count([_|Ls], N) :-
count(Ls, X),
X #= N - 1,
N #> 0.
In anderen Systemen wie SICStus Prolog und SWI, die Sie aktuell benötigen noch library(clpfd)
für diesen Einsatz. Darüber hinaus empfehle ich einen deklarativen Namen für diese Beziehung, klar zu machen, welches Argument, was bedeutet:
:- use_module(library(clpfd)).
list_length([], 0).
list_length([_|Ls], N) :-
list_length(Ls, X),
X #= N - 1,
N #> 0.
Beispielabfragen:
?- list_length([_,_,_], N).
N = 3.
?- list_length(Ls, 2).
Ls = [_G602, _G605] .
Ich lasse die Verbesserung die Beendigung Eigenschaften dieses Prädikats als einfaches Übung.
Minor Nit: Affektiertheit bedeutet eher Zuordnung. – false