2012-10-06 16 views
8

In Grammatikregeln (), gibt es mehrere vordefinierte Konstrukte: (',')//2 Bedeutung Verkettungs, ('|')//2 bedeutet Wechsel usw. Ein Konstrukt, das von mehreren, aber nicht allen Prolog Systemen unterstützt (\+)//1 ist.Legitimate Verwendungen von ( +) // 1

Persönlich habe ich es nur für die Verwendung verwendet. Ich habe es nie in Code von anderen geschrieben gesehen.

Also, gibt es legitime Verwendungen von (\+)//1?

Edit: Und zusätzlich gibt es legitime Verwendung von (\+)//1 innerhalb einer Abfrage phrase(nt, L) mit L eine uninstantiierte Variable.

Antwort

4

\ + kann verwendet werden, um weniger zweideutige Grammatiken zu erstellen. Der Vorteil der Verwendung von \ + over! Zum Beispiel ist eine bestimmte Deklaration von \ +, so dass zum Beispiel die resultierenden DCG Regeln neu geordnet werden können.

sich ein Beispiel machen, sollen Sie die folgende Grammatik:

s([X|Y]) --> t(X), s(Y).    % 1 
s([]) --> [].      % 2 

t(2)  --> [a,a].     % 3 
t(1)  --> [a].      % 4 

Die obige Grammatik ist sehr zweideutig, zum Beispiel ich mehr für die folgende Eingabe analysiert:

?- phrase(s(A),[a,a,a,a,a]). 
A = [2,2,1] ; 
A = [2,1,2] ; 
A = [2,1,1,1] ; 
etc.. 
Jetzt

gehe ich davon wollen den langen Parse von t über die kurze Parse von t bevorzugen. Ich kann dies mit einem Schnitt wie folgt tun:

t(2)  --> [a,a], !.     % 5 
t(1)  --> [a].      % 6 

?- phrase(s(A),[a,a,a,a,a]). 
A = [2,2,1] ; 
No 

Leider kann ich nicht neu anordnen. Da das folgende nicht das gewünschte Ergebnis liefert. Obwohl s (A) jetzt die Ergebnisse in einer anderen Reihenfolge ergibt, sind wir eines, auf Platz zurück da die Grammatik wieder zweideutig ist:

t(1)  --> [a].      % 7 
t(2)  --> [a,a], !.     % 8 

?- phrase(s(A),[a,a,a,a,a]). 
A = [1,1,1,1,1] ; 
A = [1,1,1,2] ; 
A = [1,1,2,1] ; 
etc... 

läßt nun das gleiche versuchen mit \ +. Wir können den Schnitt durch die folgende Negation ersetzen:

t(2)  --> [a,a].     % 9 
t(1)  --> [a], \+ [a].    % 10 

?- phrase(s(A),[a,a,a,a,a]). 
A = [2,2,1] ; 
No 

können nun versuchen, ob wir neu ordnen können. Wir ordnen die Grammatikregeln von T // 1:

t(1)  --> [a], \+ [a].    % 11 
t(2)  --> [a,a].     % 12 

?- phrase(s(A),[a,a,a,a,a]). 
A = [2,2,1] ; 
No 

Die Deklarativität sehr nützlich ist. Es bedeutet zum Beispiel , dass wir \ + in einem rechts-nach-links-Diagramm-Parser verwenden können, der die Grammatikregeln in einer willkürlichen Reihenfolge auswählt. Die Deklarativität stellt sicher, dass die Bottom-up-Vorwärtsverkettung des Diagrammparsers das gleiche Ergebnis unabhängig von die Reihenfolge der DCG-Regeln ergibt.

Es ist dann möglich, die DCG-Technik in großen Natural Language (NL) -Projekten anzuwenden und es skaliert gut. Die NL-Grammatiken können empirisch auf Determinismus abgestimmt werden. Je deterministischer eine Grammatik desto effizienter ihre Parsing. Komplexe NL-Grammatiken, die sonst sind, werden praktikabel.

Bye

+0

+1, aber ich bin * sehr * skeptisch über Ihren Deklarationsanspruch: 'Satz (s ([1]), [a]).' gelingt, aber 'Satz (s ([1]), L)' scheitert. Genau diese Art von Unreinheit stört mich. – false

+0

Das ist: Wie zeichnen Sie die Grenze zwischen legitimen und nicht legitimen Anwendungen? – false

+0

Ich beanspruche keine allgemeine Deklaration. Ich schrieb "gewisse Deklarativität". Sie können eine Deklarativität für ein Adorament festlegen (= Datenbanksprache für Prolog-Modus-Deklaration). Die Techniken können auch auf Grammatiken angewendet werden. Siehe auch: ftp://ftp.inf.ethz.ch/doc/tech-reports/1xx/177.pdf –

1

Wenn L nicht dann die Grammatik verwendet wird für Textgenerierung instanziiert wird. Dann brauchen Sie die Grammatik \ + überhaupt nicht. Da gibt es kein Problem der Mehrdeutigkeit aus irgendeinem Text.

wir ein Beispiel machen, sollten Sie die folgende Grammatik:

s([X|Y]) --> t(X), s(Y).    % 1 
s([]) --> [].      % 2 

t(2)  --> [a,a].     % 3 
t(1)  --> [a].      % 4 

Jede unterschiedliche Parse einen anderen Parse-Baum hat. Und es gibt keine Mehrdeutigkeit in mit Phrase/2, um Text zu generieren. Die folgenden Abfragen geben genau eine Antwort:

?- phrase(s([2,1]),L). 
L = [a,a,a] 
?- phrase(s([1,2]),L). 
L = [a,a,a] 
?- phrase(s([1,1,1]),L). 
L = [a,a,a] 

Aber es ist ein wenig Wiederverwendung Problem. Angenommen, ich habe eine NL-Grammatik mit \ + für parsing. Ich kann es dann nicht zum Unversuchen verwenden. Da das Instanziierungsmuster des \ + -Ziels unterschiedlich ist, ändert sich daher die Semantik des Konstrukts .

Der Ausweg ist wahrscheinlich nur zwei Grammatiken zu verwenden. Eine für Parsing und eine für . Ich denke, Parsing und Unversucht sind zwei verschiedene kognitive Fähigkeiten. Denken Sie daran, in der Schule gab es Leseübungen und Schreibübungen. Die gleiche geschieht in der Informatik.

Ich denke, es ist auch in einigen Fällen möglich, eine einzelne Grammatik zu verwenden, und Ansicht \ + als eine Anmerkung für Begriffsklärung, dass während unparse oder anders behandelt fallen gelassen wird. Man könnte einen solchen Mechanismus bauen. Aber die Probleme mit unparsing gegen Parsen sind tiefer: Bidirectionallity von Nebenbedingungen ({}/1), Linksrekursion während unparsing, etc ...

Bye

+0

Hier hilft wieder eine deduktive Datenbanktechnologie. Es ist ein erster Schritt, ein bidirektionales Adorment (= Datenbank-Jargon für die Prolog-Modus-Deklaration) zu erstellen. Aber das ist kein normaler Prolog mehr. –

Verwandte Themen