Positional features are accessed through special bit-manipulation subprimitives. Here, we describe the links between the primitive operations provided to the grammar writer and the subprimitives that reference and set positional features.
posInfo
type subprimitives are suffixed as follows:
Suffix | Input |
---|---|
(None) | Constituent |
1 | Feature complex |
(For details on how constituents are organized, see constituent structure.)
Adjunction
Operations: adjoined/{1,2,3}
/ adjoin/4
/ highestSegment/1
/ lowestSegment/1
Subprimitives: posInfoAdjoined1
/ posInfoProj1
/ posInfoLSeg
/ posInfoLSeg1
/ setPosDInfo
Adjunction Accessors
Bit 1 in Pn
, the internal positional feature bitset,
indicates whether there is something adjoined to this structure.
posInfoAdjoined
/posInfoAdjoined1
is the
subprimitive that encodes this:
posInfoAdjoined([F|_]) :- arg(3,F,Pn), 2 is Pn /\ 2. % 2nd bit posInfoAdjoined1(F) :- arg(3,F,Pn), 2 is Pn /\ 2. % 2nd bitHence:
adjoined([F,_,_|_]) :- posInfoAdjoined1(F).Using information about downwards projection, we can retrieve the adjunct and lower segment as follows:
adjoined([F,L,R],A) :- posInfoAdjoined1(F), posInfoProj1(F,I), (I =:= 0 -> A = R ; A = L). % assume numeric adjoined([F,L,R],A,S) :- posInfoAdjoined1(F), posInfoProj1(F,I), (I =:= 0 -> S = L, A = R ; S = R, A = L). % assume numericBit 0 (LSB) in
Pn
indicates whether there is further
downward projection. Bits 2 and up form an index into the head.
posInfoProj
/posInfoProj1
is the subprimitive
that returns the index of the head:
% Phrase -> value(head) provided phrase projects posInfoProj([F|_],I) :- arg(3,F,Pn), 1 is Pn /\ 1, % lsb I is Pn >> 2. % skip lsb and 2nd bit % FC -> value(head) provided phrase projects posInfoProj1(F,I) :- arg(3,F,Pn), 1 is Pn /\ 1, % lsb I is Pn >> 2. % skip lsb and 2nd bit
Pd
indicates whether the constituent is a lower
segment in an adjunction structure. We can use this information to
detect whether the constituent is the highest segment in an adjunction
cascade:
% works for even non-adjoined phrases highestSegment(X) :- \+ posInfoLSeg(X).
posInfoLSeg
is the subprimitive that tests
Pd
bit 0:
posInfoLSeg([F|_]) :- arg(4,F,Pd), 1 is Pd /\ 1. % lsb posInfoLSeg1(F) :- arg(4,F,Pd), 1 is Pd /\ 1. % lsbNote that if no adjunction has taken place at all, bit 0 will be 0 anyway. This will give the correct result.
The actual code is a little more complex to allow testing to succeed
for unattached constituents. In other words,
highestSegment(X)
holds if X
is the top
constituent:
% new version: Pd not set, let it pass highestSegment([F|_]) :- arg(4,F,Pd), (var(Pd) -> true ; \+ 1 is Pd /\ 1). % lsbIn the complementary case where we're testing for lowest segments, the criterion is:
Pd
lower segment bit must be set and
Pn
adjoined bit must be clear:
% requires adjunction lowestSegment([F|_]) :- posInfoLSeg1(F), \+ posInfoAdjoined1(F).
adjoin(Dir,Adjunct,X,X')
must not only create the larger
constituent, but also set the internal positional features of the new
constituent (Pn
) as well as setting the attachment
features of the adjunct and original phrase:
adjoin(left,A,X,[c(C,Fs,7,_,_),A,X]) :- % proj:1 adjoined:1 head:1 X = [c(C,Fs,_,1,_)|_], % lseg:1 adjunct:0 ... setPosDInfo(0,1,0,0,0,0,A). % lseg:0 adjunct:1 ... adjoin(right,A,X,[c(C,Fs,3,_,_),X,A]) :- % proj:1 adjoined:1 head:0 X = [c(C,Fs,_,1,_)|_], % lseg:1 adjunct:0 ... setPosDInfo(0,1,0,0,0,0,A). % lseg:0 adjunct:1 ...The positional features are set as follows:
Constituent | Pn | Pd |
---|---|---|
X | N/A | lseg:1 adjunct:0 apos:0 compl:0 ido:0 |
Adjunct | N/A | lseg;0 adjunct:1 apos:0 compl:0 ido:0 |
[X Adjunct X] | proj:1 adjoined:1 head:1 | Not specified |
[X X Adjunct] | proj:1 adjoined:1 head:0 | Not specified |
Pd
features are set using the subprimitive
setPosDInfo
:
setPosDInfo(LSeg,Adjunct,Apos1,Apos2,Compl,IDO,[F|_]) :- Pd is LSeg + Adjunct + Adjunct + ((Apos1 + Apos2 + Apos2 + ((Compl + IDO + IDO) << 2)) << 2), arg(4,F,Pd).(The suffix 1 version is also provided but not shown here.)
Actually, Nmacros
unrolls this computation at
compile-time using:
translateNR(setPosDInfo,7,setPosDInfo(L,A,Ap1,Ap2,C,I,X), setPosDInfo(Pd,X),[]) :- nonvar(L), nonvar(A), nonvar(Ap1), nonvar(Ap2), nonvar(C), nonvar(I), !, Pd is L + A + A + ((Ap1 + Ap2 + Ap2 + ((C + I + I) << 2)) << 2).Hence, the actual primitive used at run-time is:
setPosDInfo(Pd,[F|_]) :- arg(4,F,Pd). setPosDInfo1(Pd,F) :- arg(4,F,Pd).