Implementing Patr
Bibliographic Note
Material in this presentation is based on
Natural Language Processing in Prolog
G. Gazdar and C. Mellish, Addison-Wesley 1989.
Some Differences between
Patr and Prolog
Prolog requires explicit variables
Syntactic appearance of paths
Grammar Rules
Lexical Entries
Templates
Rule Format
R ule
S ---> [NP, VP] :S:cat === s,
NP:cat === np,
VP:cat === vp,
S:head === VP:head,
NP
=== VP:subcat:first.
Operator Definitions
op(500,xfy,:).
op(500,xfx,--->).
op(600,xfx,===).
op(400,xfx,ule).
op(500,xfx,ord).
Definition of ===
X===Y if and only if X and Y denote
unifiable items.
We achieve this by saying that there is
a third item that they both denote, i.e.
X === Y :denotes(X,Z),
denotes(Y,Z).
Definition of denote(X,Y).
We must take account of the fact that X can
be one of three things: variable, atom, or path
denotes(Var,Var) :- var(Var), !.
denotes(Atom,Atom) :atomic(Atom), !.
denotes(V:Path, Value) :pathval(V,Path,Value).
Modifying pathval
Notice that the second argument to pathval
need not be atomic. However, our existing
definition for pathval assumes that it is.
We therefore add a clause that applies
pathval applies to the first element of the path
to obtain a second value, and then applies
the rest of the path the new value.
New Definition of pathval
pathval([Attr:Val1 | X], Attr, Val2, X):!,unify(Val1, Val2).
pathval([AV | X], Attr, Val, [AV | Rem] )
:pathval(X, Attr, Val, Rem).
pathval(V1, Attr:Path, Value, Rem) :- !,
pathval(V1,Attr,V2,Rem),
pathval(V2,Path,Value,_).
Lexical Entries
W ord uther :W:cat = n,
W:head:trans = uther.
Uppercase can cause problems.
Use quote (e.g. ‘Uther’) if
necessary.
Connecting Words
to Lexical Entries
Represent strings as difference lists.
Define a predicate that associates
words in string with lexical entry.
leaf(W, [Word|Rest], Rest) :W ord Word.
leaf(C,X,X) :- R ule C ---> [].
In Other (DCG) Words ….
leaf(FS)-->
[Word], {FS ord Word}.
leaf(FS) –->
[_ ule Dag --- []}
Left Corner Recogniser
To recognise a string as an instance of FS1,
we need to consider an initial leaf FS0 and
prove that FS0 is a “left corner” of FS1, i.e.
that FS0 is a category that would appear at
the bottom left of a parse tree for it.
rec(FS1) -->
leaf(FS0), lc(FS0,FS1}.
Definition of left corner
lc(FS1,FS2)
If the end of the string has been
reached, then FS1 is a left corner of
FS2 if they unify.
Otherwise there is a rule
FS0 ---> [FS1|Rest] such that
The rest of the string is recognised as Rest
FS0 is a left corner of FS1
Code for lc
lc(FS1,FS2) --> [], {unify(FS1,FS2)}.
lc(FS1,FS2) -->
{ R ule FS0 ---> [FS1 | Rest] },
recognise_rest(Rest),
lc(FS0,FS2).
recognise_rest
recognise_rest( [ ] ) --> [ ].
recognise_rest([FS | FSs]) :recognise(FS),
recognise_rest(FSs).
© Copyright 2026 Paperzz