NRQL Negation

The behaviour of "neg" seemed to be unclear to us. The following example illustrates the confusion. A solution is given then below.

Given the knowledge base: (in-tbox tmp-tbox)

(signature :atomic-concepts (place person)      :roles ((lives-in :domain person :range place))       :individuals (paul konrad paris berlin))

(in-abox tmp-abox tmp-tbox)

(related konrad berlin lives-in) (related paul paris lives-in) And the task is to retrieve all persons not living in Berlin. Why does the following query fail?

(retrieve (?x) (and (neg (?x berlin lives-in)) (?x person)))
 * answer 1 "(((?X PAUL)) ((?X KONRAD)))"

Whereas this version yield the correct answer:

(retrieve (?x) (and (neg (?x ?y lives-in)) (= ?y berlin) (?x person)))
 * answer 2 "(((?X PAUL)))"

The explanation given by a Racer developer:

Dies wird verständlich, wenn Sie sich die intern umgeschriebenen Anfragen anschauen:

11 ? (RETRIEVE (?X) (?X BERLIN LIVES-IN)) 11 > (((?X KONRAD)))

12 ? (DESCRIBE-QUERY :LAST) 12 > (:QUERY-6     (:ACCURATE :PROCESSED)      (RETRIEVE (?X) (AND (SAME-AS $?BERLIN-ANO1 BERLIN) (?X $?BERLIN-ANO1 LIVES-IN)) :ABOX TEST))

Individuen (Konstanten) in nRQL sind also in Wirklichkeit Hilfsvariablen ("$?BERLIN-ANO1"), die mittels SAME-AS an entsprechende ABox-Individuen gebunden werden; der Anfrage-Körper wurde also zu

(AND (SAME-AS $?BERLIN-ANO1 BERLIN) (?X $?BERLIN-ANO1 LIVES-IN))

Das Ergebnis von (?x berlin lives-in) ist in Wirklichkeit ein Paar / 2-Tupel:

13 ? (RETRIEVE (?X BERLIN) (?X BERLIN LIVES-IN)) 13 > (((?X KONRAD) ($?BERLIN BERLIN))),

und (retrieve (?x) ...) bedeutet letztlich eine Projektion auf das erste Argument der Paare / Tupel.

Die Semantik von nRQL ist nun so eingerichtet, dass "(UNION (neg ))" stets alle Tupel-Kombinationen bzw. das volle kartesische Produkt für die in vorkommenden Variablen liefert, um eine klare mathematische Semantik zu gewährleisten (damit z.B. das DeMorgansche Gesetzt gilt).

Daher muss für die zweidimensionalen Tupel gelten: 14 ? (RETRIEVE (?X BERLIN) (NEG (?X BERLIN LIVES-IN))) 14 > (((?X PAUL) ($?BERLIN PAUL))     ((?X PARIS) ($?BERLIN PAUL))      ((?X KONRAD) ($?BERLIN PAUL))      ((?X BERLIN) ($?BERLIN PAUL))      ((?X PAUL) ($?BERLIN PARIS))      ((?X PARIS) ($?BERLIN PARIS))      ((?X KONRAD) ($?BERLIN PARIS))      ((?X BERLIN) ($?BERLIN PARIS))      ((?X PAUL) ($?BERLIN KONRAD))      ((?X PARIS) ($?BERLIN KONRAD))      ((?X KONRAD) ($?BERLIN KONRAD))      ((?X BERLIN) ($?BERLIN KONRAD))      ((?X PAUL) ($?BERLIN BERLIN))      ((?X PARIS) ($?BERLIN BERLIN))      ((?X BERLIN) ($?BERLIN BERLIN))) denn dies ist genau das zweidimensionale Komplement von (((?X KONRAD) ($?BERLIN BERLIN))).

Konsequenterweise ergibt daher die folgende Anfrage alle 4x4 = 16 Tupel, also das volle Kreuzprodukt: 15 ? (RETRIEVE     (?X BERLIN)      (UNION (?X BERLIN LIVES-IN) (NEG (?X BERLIN LIVES-IN))))

15 > (((?X KONRAD) ($?BERLIN BERLIN))     ((?X PAUL) ($?BERLIN PAUL))      ((?X PARIS) ($?BERLIN PAUL))      ((?X KONRAD) ($?BERLIN PAUL))      ((?X BERLIN) ($?BERLIN PAUL))      ((?X PAUL) ($?BERLIN PARIS))      ((?X PARIS) ($?BERLIN PARIS))      ((?X KONRAD) ($?BERLIN PARIS))      ((?X BERLIN) ($?BERLIN PARIS))      ((?X PAUL) ($?BERLIN KONRAD))      ((?X PARIS) ($?BERLIN KONRAD))      ((?X KONRAD) ($?BERLIN KONRAD))      ((?X BERLIN) ($?BERLIN KONRAD))      ((?X PAUL) ($?BERLIN BERLIN))      ((?X PARIS) ($?BERLIN BERLIN))      ((?X BERLIN) ($?BERLIN BERLIN))) Wenn Sie nun das Ergebnis von 16 ? (RETRIEVE (?X BERLIN) (NEG (?X BERLIN LIVES-IN)))

16 > (((?X PAUL) ($?BERLIN PAUL))     ((?X PARIS) ($?BERLIN PAUL))      ((?X KONRAD) ($?BERLIN PAUL))      ((?X BERLIN) ($?BERLIN PAUL))      ((?X PAUL) ($?BERLIN PARIS))      ((?X PARIS) ($?BERLIN PARIS))      ((?X KONRAD) ($?BERLIN PARIS))      ((?X BERLIN) ($?BERLIN PARIS))      ((?X PAUL) ($?BERLIN KONRAD))      ((?X PARIS) ($?BERLIN KONRAD))      ((?X KONRAD) ($?BERLIN KONRAD))      ((?X BERLIN) ($?BERLIN KONRAD))      ((?X PAUL) ($?BERLIN BERLIN))      ((?X PARIS) ($?BERLIN BERLIN))      ((?X BERLIN) ($?BERLIN BERLIN)))

auf "?x" projezieren (genau das macht (retrieve (?x) ...)), erhalten Sie konsequenterweise 17 ? (RETRIEVE (?X) (NEG (?X BERLIN LIVES-IN)))

17 > (((?X PAUL)) ((?X PARIS)) ((?X KONRAD)) ((?X BERLIN))) Natürlich ist das Erscheinen von "(?X KONRAD)" hier erstmal überraschend, ergibt sich aber zwingend aus der Semantik.

Oftmals möchte man tatsächlich zuerst projezieren, *bevor* das Komplement mittels NEG des Atomes berechnet wird. In diesem Fall müssen Sie "project-to" verwenden:

18 ? (RETRIEVE (?X) (NEG (PROJECT-TO (?X) (?X BERLIN LIVES-IN)))) 18 > (((?X PAUL)) ((?X PARIS)) ((?X BERLIN))) So werden Sie also auch "(?X KONRAD)" los aus der Antwortmenge.

Man sieht auch, dass diese Query intern anders umgeschrieben wurde: 19 ? (DESCRIBE-QUERY :LAST) 19 > (:QUERY-8     (:PROCESSED)      (RETRIEVE (?X) (NOT (:PROJECT-TO (?X) (AND (SAME-AS $?BERLIN-ANO1-ANO2 BERLIN)                 (?X $?BERLIN-ANO1-ANO2 LIVES-IN)))) :ABOX TEST)) denn

20 ? (RETRIEVE (?X BERLIN) (NEG (?X BERLIN LIVES-IN))) 20 > (((?X PAUL) ($?BERLIN PAUL)) ...)

21 ? (DESCRIBE-QUERY :LAST) 21 > (:QUERY-20     (:ACCURATE :PROCESSED)      (RETRIEVE (?X $?BERLIN) (OR (AND (NOT (SAME-AS $?BERLIN BERLIN)) (TOP ?X))          (AND (TOP BERLIN) (NOT (?X $?BERLIN LIVES-IN)))) :ABOX TEST))