Wie werden die entsprechenden Vergleichsprädikate für sichere Begriffe in ISO Prolog definiert (und benannt)?
Standard-Termreihenfolge (ISO / IEC 13211-1 7.2 Termreihenfolge) wird über alle Terme definiert - einschließlich Variablen. Es gibt zwar gute Verwendungsmöglichkeiten dafür - denken Sie an die Implementierung vonsetof/3
, dies macht viele ansonsten saubere und logische Verwendungen der in 8.4 enthaltenen Termvergleiche zu einem deklarativen Albtraum, der überall von Imps (Kurzform für imperative Konstrukte) umgeben ist. 8.4 Termvergleichsfunktionen:
8.4.1 (@ = <) / 2, (==) / 2, (\ ==) / 2, (@ <) / 2, (@>) / 2, (@> =) / 2.
8.4.2 compare / 3.
8.4.3 sort / 2.
8.4.4 keysort / 2.
Um ein Beispiel zu geben, betrachten Sie:
?- X @< a.
true.
Dies ist erfolgreich, weil
7.2 LaufzeitbestellungEine Bestellung term_precedes (3.181) definiert, ob oder
kein BegriffX
term-steht vor einem BegriffY
.
WennX
undY
sind identische Begriffe dannX
term_precedes Y
undY
term_precedes X
sind beide falsch.
WennX
undY
haben verschiedene Typen:X
term_precedesY
iff das
eine Art vonX
steht vor dem Typ vonY
in der folgenden Reihenfolgevariable
geht @ vorfloating point
geht @ vorinteger
precedesatom
geht @ vorcompound
.
NOTE - Eingebaute Prädikate, die die Reihenfolge der Begriffe testen
sind in 8.4 definiert.
...
Und somit sind alle Variablen kleiner alsa
. Aber einmalX
wird instanziiert:
?- X @< a, X = a.
X = a.
das Ergebnis wird ungültig.
So das ist das Problem. Um dies zu überwinden, kann man entweder Einschränkungen verwenden oder sich nur an das Kernverhalten halten und daher ein @ erzeugeinstantiation_error
.
Errors werden nach der Form von @ klassifizieError_term
:
a) Es soll ein Instanziierungsfehler auftreten, wenn ein
argument oder eine seiner Komponenten ist eine Variable und ein
instantiated Argument oder Komponente ist erforderlich. Es ha
die Forminstantiation_error
.
uf diese Weise wissen wir mit Sicherheit, dass ein Ergebnis gut definiert ist, solange kein Instanziierungsfehler auftrit
Zum(\==)/2
gibt es schon entwederdif/2
die Einschränkungen verwendet oderiso_dif/2
was einen sauberen Instanziierungsfehler erzeugt.
iso_dif(X, Y) :-
X \== Y,
( X \= Y -> true
; throw(error(instantiation_error,iso_dif/2))
).
So, worum es in meiner Frage geht: Wie werden die entsprechenden Vergleichsprädikate für sichere Begriffe in @ definiert (und benanntISO Prolog? Idealerweise ohne expliziten Begriff Traversal. Vielleicht zur Klarstellung: Obeniso_dif/2
verwendet keinen expliziten Begriff Traversal. Beide(\==)/2
und(\=)/2
durchlaufen den Term intern, aber der Overhead dafür ist im Vergleich zum expliziten Durchlaufen mit @ extrem geri(=..)/2
oderfunctor/3, arg/3
.