" PRS (1.0)"

" (C) PARC 2004
  File: fs_triples.pl
  Purpose:  This is a file that maps f-structures through to a very
  basic triples format, intended for direct matching of f-structures
  against f-structures.  It is loaded by triples match if no rule
  file is specified, and fs_files are being matched against fs_files

  Note that it includes the node_label_rules file, in $XLEPATH/include
  to deal with node labelling.
"



grammar = fs_triples.

:- set_transfer_option(conflict_resolution, 0).
:- set_transfer_option(garbage_collection, 0).
:- set_transfer_option(include_eqs, 1).
:- set_transfer_option(include_proj, 1).
:- set_transfer_option(extra, [cf(1,root(var(0),x))]).


arg(%%,%%,%%) ==> 0.
nonarg(%%,%%,%%) ==> 0.
LEFT-SISTER(%%,%%) ==> 0.
RIGHT-SISTER(%%,%%) ==> 0.
LEFT-DAUGHTER(%%,%%) ==> 0.
RIGHT-DAUGHTER(%%,%%) ==> 0.
LEFT_SISTER(%%,%%) ==> 0.
RIGHT_SISTER(%%,%%) ==> 0.
LEFT_DAUGHTER(%%,%%) ==> 0.
RIGHT_DAUGHTER(%%,%%) ==> 0.


"==============
Remove optimality projections
==============="

o::(%%, var(%X)) ==>  to_delete(var(%X)).

  +to_delete(%X),
  ((qp(%P, [%X, var(%Y)]), {%P \= in_set})
  |
   in_set(var(%Y), %X)
  )
 *=>
  to_delete(var(%Y)).

+to_delete(%X), in_set(%%, %X) ==> 0.
+to_delete(%X), qp(%%, [%X, %%]) ==> 0.
to_delete(%%) ==> 0.

     
"==============
 flatten sets:
=============="

+ADJUNCT(%X,%Y), in_set(%Z,%Y) ==> ADJUNCT_x(%X,%Z).

+NAME-MOD(%X,%Y), in_set(%Z,%Y) ==> NAME-MOD_x(%X,%Z).

+MOD(%X,%Y), in_set(%Z,%Y) ==> MOD_x(%X,%Z).
    
" for older grammars: "
+APP(%X,%Y), -in_set(%%,%Y) ==> NAME-MOD_x(%X,%Y).
+APP(%X,%Y), in_set(%Z,%Y)   ==> NAME-MOD_x(%X,%Z).

"+COORD(%X, '+_'), in_set(%Z, %X) ==> COORD_x(%X,%Z). "
COORD(%X, '+_')  ==> PRED(%X,coord).
     
" for older grammars:"
CONJ(%X,'+_') ==> PRED(%X,coord).
+PRED(%X, coord), in_set(%Z,%X) ==> COORD(%X,%Z).

ADJUNCT(%%,%%) ==> 0.
ADJUNCT_x(%X,%Z) ==> ADJUNCT(%X,%Z).

NAME-MOD(%%,%%) ==> 0.
APP(%%,%%) ==> 0.
NAME-MOD_x(%X,%Z) ==> NAME-MOD(%X,%Z).

MOD(%%,%%) ==> 0.
MOD_x(%X,%Z) ==> MOD(%X,%Z).

" COORD(%X,%%) ==> PRED(%X,coord). "

     
"=====================
  The following two are to deal with sets that have no preds, and are
  not adjuncts, mods or coordinations.   Treat them as list
  coordinations.  See for example
  /project/nltt-2/TESTDATA/10-01-02/G5.pl
======================="

in_set(var(%X), var(%Y)) ==>
   COORD_x(var(%Y), var(%X)), PRED(var(%Y),coord).

+COORD_x(var(%Y), var(%%)), -PRED(var(%Y),%%) ==>
   PRED(var(%Y),coord).


COORD_x(%X,%Z) ==> COORD(%X,%Z).


root(%B,%%), -PRED(%B,%%) ==> PRED(%B,root).


in_set(%Atom,%%), {%Atom \= var(%%)} ==> 0.

"============================
 flatten internal structure:
============================"

  qp(%P1,[%A,var(%B)]), -(eq(var(%B), %V), {%V \= var(%%)}),
  -PRED(var(%B),%%),
  +qp(%P2,[var(%B),%%]),
  {%P1 \= in_set}, {%P2 \= in_set}, {%P1 \= eq},  {%P2 \= eq},
  {%P1 \= scopes}, {%P2 \= scopes}
==>
  internal_node(%A, var(%B), %P1).


  +internal_node(%A, %B, %PA), +internal_node(%B, %C, %PB),
  +internal_node(%C, %D, %PC), +internal_node(%D, %E, %PD),
  -internal_node(%E,%%,%P), qp(%P,[%E,%V]), {%P \= eq}
==>
  qp(%P,[%A,%V,[%PA,%PB,%PC,%PD]]).


  +internal_node(%A, %B, %PA), +internal_node(%B, %C, %PB),
  +internal_node(%C, %D, %PC),
  -internal_node(%D,%%,%P), qp(%P,[%D,%V]), {%P \= eq}
==>
  qp(%P,[%A,%V,[%PA,%PB,%PC]]).

    
  +internal_node(%A, %B, %PA), +internal_node(%B, %C, %PB),
  -internal_node(%C,%%,%P), qp(%P,[%C,%V]), {%P \= eq}
==>
  qp(%P,[%A,%V,[%PA,%PB]]).

    
  +internal_node(%A, %B, %PA),
  -internal_node(%B,%%,%P), qp(%P,[%B,%V]), {%P \= eq}
==>
  qp(%P,[%A,%V,[%PA]]).


  internal_node(%%,%%,%%) ==> 0.

"=================
 labelling nodes:
================="

include(`.`./transfer/triples/node_label_rules).

@label_nodes.


node_label(%%,eq:%%) ==> 0.
eq(%%,%%) ==> 0.

label_feats ::
  qp(%P, [var(%N), var(%M)]),
  +node_label(var(%N), %L:%X),
  +node_value(var(%M), %MAttr) ==>
  qp(%P,[%L:%X, %MAttr]);

  qp(%P, [var(%N), var(%M)]),
  +node_label(var(%N), %L:%X),
  +node_label(var(%M), %MAttr) ==>
  qp(%P,[%L:%X, %MAttr]);

  qp(%P, [var(%N), %Val]), {%P \= node_label},
  +node_label(var(%N), %L:%X) ==>
  qp(%P,[%L:%X, %Val]);

  qp(%P, [var(%N), var(%M), %Path]),
  +node_label(var(%N), %L:%X),
  +node_value(var(%M), %MAttr) ==>
  qp(%P,[%L:%X, %MAttr, %Path]);

  qp(%P, [var(%N), var(%M), %Path]),
  +node_label(var(%N), %L:%X),
  +node_label(var(%M), %MAttr) ==>
  qp(%P,[%L:%X, %MAttr, %Path]);

  qp(%P, [var(%N), %Val, %Path]), {%P \= node_label},
  +node_label(var(%N), %L:%X) ==>
  qp(%P,[%L:%X, %Val, %Path]).



@label_feats.

node_label(%%,%%) ==> 0.
node_value(%%,%%) ==> 0.
internal_node(%%,%%, %%) ==> 0.
lex_id(%%,%%) ==> 0.
root(%%,%%) ==> 0.

" last ditch, in case node labelling hasn't worked"
qp(%P, [var(%N), %Val]) ==> qp(%P, [var:%N, %Val]).
qp(%P, [%Val, var(%N)]) ==> qp(%P, [%Val, var:%N]).
qp(%P, [var(%N), %Val, %Path]) ==> qp(%P, [var:%N, %Val, %Path]).
qp(%P, [%Val, var(%N), %Path]) ==> qp(%P, [%Val, var:%N, %Path]).