%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This file contains peridicates that exports the compiled ERG grammar in 
% ALE to TDL 
% RFD-21/June/08: Version 1.9 : exporting in native LKB list types
%
% Requirments:
% -----------
% ale.pl must be loaded, as well as load.pl and lex.pl
% After loading them run compile_gram command, and load this file.
% call export.
%
% SICStus 3.12.8 (x86-linux-glibc2.3): Tue May  8 13:30:29 CEST 2007
% Licensed to cs.toronto.edu
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
export:-
	use_module(library(system)),
	ex_subtype, % This will do the intros as well
	ex_cons,
	ex_lex,
	ex_rules.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ex_subtype/0: exports the sub_types of the system. 
%  Before writing sub_type tree in tdl format, it first computes the
%  transitive closure and reduction of the tree
%  after identifying all redundant edges, it will start writing them
%  to the given file in TDL format.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ex_subtype :- 
   see(user), 
   nl,write('********************************************************'),
   nl,write('Exporting the current (compiled) sub-Types to TDL format '),
   nl,write('      eg. types.tdl,in single quotes followed by a dot.'),nl, 
   nl,write('Enter the file name : '),
   read(File), 
   tell(File),
   write(';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;'),nl,
   write(';This file was generated by ALE, (http://www.ale.cs.toronto.edu) '),nl,
   datime(W),write('; '),write(W),nl,	
   write(';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;'),nl,
   nl,write(';;; LKB spec. types'),nl,
   write('string := *top*.'),nl,
   nl,nl,write(';;; Types'),nl,nl,	
   findall(X,(type(X)),Types),
   groundChk(Types,TypesChkd),
   trans2,		
   gen_immed_parents(TypesChkd),
   told,
   !.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ex_cons/0: exports the constraints defined on subtypes (defined in cons.pl)
%  to the given file in TDL format.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ex_cons :-
   see(user), 
   nl,write('**************************************************************'),
   nl,write('Exporting the current(compiled)Type Constraints to TDL format '),
   nl,write('      eg. cons.tdl'),nl, 
   nl,write('Enter the file name : '),
   read(File), 
   tell(File),
   write(';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;'),nl,
   write(';This file was generated by ALE, (http://www.ale.cs.toronto.edu) '),nl,
   datime(W),write('; '),write(W),nl,	
   write(';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;'),nl,
   nl,write(';;; Type Constraints'),nl,
   findall( X,( X cons _ ),ConsTypes),
   retractall(coref_num(_)),
   assert(coref_num(0)),
   cons_toTdl(ConsTypes),
   told,
   !.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ex_lex/0: exports the lexical entries defined in lex.pl
%  to the given file in TDL format.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ex_lex :-
   see(user), 
   nl,write('**************************************************************'),
   nl,write('Exporting the current Lexical Entries to TDL format '),
   nl,write('      eg. lexicon.tdl'),nl, 
   nl,write('Enter the file name : '),
   read(File), 
   tell(File),
   write(';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;'),nl,
   write(';This file was generated by ALE, (http://www.ale.cs.toronto.edu) '),nl,
   datime(W),write('; '),write(W),nl,	
   write(';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;'),nl,
   nl,write(';;; Lexical Entries'),nl,
   use_module(library(lists)),
   findall( X,( X ---> _ ),FLexEnts),
   remove_duplicates(FLexEnts,LexEnts),	
   lex_toTdl(LexEnts),
   told,
   !.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ex_rules/0: exports the grammar rules defined in grules.pl
%  to the given file in TDL format.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ex_rules :-
   see(user), 
   nl,write('**************************************************************'),
   nl,write('Exporting the current Grammar Rules to TDL format '),
   nl,write('      eg. rules.tdl'),nl, 
   nl,write('Enter the file name : '),
   read(File), 
   tell(File),
   write(';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;'),nl,
   write(';This file was generated by ALE, (http://www.ale.cs.toronto.edu) '),nl,
   datime(W),write('; '),write(W),nl,	
   write(';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;'),nl,
   nl,write(';;; Grammar Rules'),nl,
   findall(UR,(UR rule _ ===> cat> _ ),UnaryRules),
   findall(BR,(BR rule _ ===> cat> _ , cat> _),BinaryRules),
   binary_rules_toTdl(BinaryRules),
   unary_rules_toTdl(UnaryRules),
   told,
   !.

/*================= SUB TYPES AND INTROS ===========================*/

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%gen_immed_parents/1 : generates a list of immediate
% parents (i.e not their (grand)*parents)
% and calls toTdl2/2 for each type and the generated
% list of immediate parents.
%
% Side effect: Types and their parents are written in 
%       TDL format to the File opned/closed in export.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
gen_immed_parents([]).         
gen_immed_parents(Types) :-
	[Type|RestOfTypes]=Types,

	findall(X,(
		sub_type(X,Type),
         	X \== Type,
		\+red_edge(X,Type),	
		(immed_subtypes(X,SubType),
         	groundChk(SubType,SubTypeChkd),
         	member(Type,SubTypeChkd))
		 ),
               ImmParents),
	toTdl2(Type,ImmParents),
	gen_immed_parents(RestOfTypes).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% toTdl2/2:gets a type and a list of its sub-types and 
%        writes them in TDL sub-Type format.
% the user should is gen_subs/1 ( NOT for bot type )
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
toTdl2(_T,[]).
toTdl2(T,ImmParents) :-  
	check_list_types(T,TDLT),write(TDLT), write(' := '),
	toTdl2_s(T,ImmParents).

toTdl2_s(_,[]).
toTdl2_s(T,[Parent]) :- 
	check_list_types(Parent,TDLParent),
	(write(TDLParent),add_intro(T),write('.'),nl).

toTdl2_s(T,[Parent1|RestOfParents]) :-  
        check_list_types(Parent1,TDLParent1),
	write(TDLParent1),write(' & '),toTdl2_s(T,RestOfParents).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% for adding intro if any for a type
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
add_intro(Type):-
	((Type intro Intro)) ->
	 (
	   write(' & '),introToTdl(Intro,[],TDLIntro),write(TDLIntro)
	 )
	 ;true.

%RFD-DBG: May20,08
introToTdl([],Acc,Intros):- reverse(Acc,Intros).

%introToTdl([],Acc,Acc).
introToTdl([(ALEH1:H2)|Rest],Acc,TDLIntro):-
	check_list_fs(ALEH1,H1),
	(((H1 == 'META-PREFIX');
	  (H1 == 'META-SUFFIX');
	  (H1 == 'RULE-NAME');
	  (H1 == 'LABLE-NAME');
	  (H1 == 'TITLE');
          (H1 == 'EXCL');
          (H1 == 'CONST_VALUE');
	  (H1 == 'SEASON');
	  (H1 == 'YEAR');
	  (H1 == 'NAMED');
	  (H1 == 'HOUR');
	  (H1 == 'DAY');
	  (H1 == 'MONTH');
	  (\+atom(H2))	
	 )
	 ->(name(H1,Dec),name(string,Type))
	   ;(
	      (H2 == bot) -> (name(H1,Dec),name('*top*',Type))	
		;((H2 == list) -> (name(H1,Dec),name('*list*',Type))
		   ;(name(H1,Dec),name(H2,Type))   
		 )
	    )
	),
	append(Dec,[32],Dec2),
	append(Dec2,Type,X),
	name(TDLEntry,X),
	introToTdl(Rest,[TDLEntry|Acc],TDLIntro).

/*================= CONSTRAINTS========================*/

check_list_fs(hd,TDLF):-
 !, TDLF = 'FIRST'.

check_list_fs(tl,TDLF):-
 !, TDLF = 'REST'.

check_list_fs('HD',TDLF):-
 !, TDLF = 'FIRST'.

check_list_fs('TL',TDLF):-
 !, TDLF = 'REST'.

check_list_fs(X,X).



check_list_types(bot,TDLType):-
 !,TDLType = '*top*'.

check_list_types(list,TDLType):-
 !,TDLType = '*list*'.

check_list_types(e_list,TDLType):-
 !,TDLType = '*null*'.

check_list_types(ne_list,TDLType):-
 !,TDLType = '*ne_list*'.

check_list_types(X,X).

/* 
check_list_types(Type,TDLType):-
       ( (Type == bot ) -> TDLType = '*top*'
	  ;((Type == list ) -> TDLType = '*list*'
	    ;((Type == e_list ) -> TDLType = '*null*'
	       ;(Type == ne_list ) -> TDLType = '*ne_list*'
		 ; TDLType = Type 
	      )	
	   )	
	).
check_list_fs(ALEF,TDLF):-
       ((ALEF == hd) -> TDLF = 'FIRST'
	 ;((ALEF == tl) -> TDLF = 'REST'
	    ;TDLF=ALEF
          )
	).
*/

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% cons_toTdl/1 : 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
cons_toTdl([]).         
cons_toTdl([Type|RestOfTypes]) :-
	immed_cons(Type,LHSDesc,_),
	check_list_types(Type,TDLType),write(TDLType), write(' :+ '),
	tdl_desc((LHSDesc)),write(' .'),nl,
	cons_toTdl(RestOfTypes).

/*================= LEXICON ========================*/

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% lex_toTdl/1 : converts the ALE lexal entry to its TDL 
% counterpart for each of the given Lexical Entry given in
% the LexEnts.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
lex_toTdl([]).
lex_toTdl([LexEnt|RestOfLexEnts]) :-
	findall(LHSDesc,(LexEnt ---> LHSDesc),LexEntDescs),
	write_lex_entries(LexEnt,LexEntDescs,0),
	lex_toTdl(RestOfLexEnts).

write_lex_entries(_,[],_).
write_lex_entries(LexEnt,[LHSDesc|RestOfDescs],N):-
	retractall(coref_num(_)),
   	assert(coref_num(0)),
	write(LexEnt),
	NewN is N +1,
	write('_'),write(NewN),write('  := '),
	tdl_desc(LHSDesc),write('.'),
	nl,nl,
	write_lex_entries(LexEnt,RestOfDescs,NewN).


/*================= GRAMMAR RULES ========================*/

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% binary_rules_toTdl/1 : converts the ALE binary grammar
% rules to its TDL counterpart. 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
binary_rules_toTdl([]).
binary_rules_toTdl([BR|RestOfBRs]) :-
  retractall(coref_num(_)),
  assert(coref_num(0)),
  write(BR),write(' := '),
  (BR rule Mom ===> cat> Dtr1 , cat> Dtr2),	
  tdl_desc(Mom),write(' & [ ARGS '),tdl_desc([Dtr1,Dtr2]),write(' ].'),
  nl,nl,
  binary_rules_toTdl(RestOfBRs).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% unary_rules_toTdl/1 : converts the ALE unary grammar
% rules to its TDL counterpart. 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
unary_rules_toTdl([]).
unary_rules_toTdl([UR|RestOfURs]) :-
  retractall(coref_num(_)),
  assert(coref_num(0)),
  write(UR),write(' := '),
  (UR rule Mom ===> cat> Dtr1),	
  tdl_desc(Mom),nl,write(' & [ ARGS '),tdl_desc([Dtr1]),write(' ].'),
  %tdl_desc( (Mom,('ARGS' :([Dtr1])) ) ),
  %tdl_desc((Mom,([Dtr1]))),
  nl,nl,
  unary_rules_toTdl(RestOfURs).


/* ============== DESCRIPTIONS =========================== */

/*

pp_desc(X) :-
  var(X),
  !, pp_fs(X).

pp_desc(FS) :-
  functor(FS,Module,Arity),
  clause(marity(Module,Arity),true),
  !,
  pp_fs(FS).


pp_desc([]) :-
  !,write([]).

pp_desc([H|T]) :-
  !,write('['),
  pp_desc(H),
  pp_tail(T).

pp_desc(F:Desc) :-
  !, write_feature(F),
   pp_desc(Desc).

pp_desc((D1,D2)) :-
  !, 
  pp_desc(D1), write(','), %&
  pp_desc(D2).



pp_desc(a_ X,Dups,Dups,Vis,Vis,_,HD,HD) :-
  !, write('a_ '),write(X).

pp_desc(Other,DupsIn,DupsOut,VisIn,VisOut,Col,HDIn,HDOut) :-
				% handles types, functions and macros
  Other =.. [Head|Args],
  write(Head),
  ( Args = [] -> VisOut = VisIn, DupsOut = DupsIn, HDOut = HDIn
  ; write('('),
    name(Head,Name), length(Name,N), NewCol is Col + N + 1,
    pp_descs(Args,DupsIn,DupsOut,VisIn,VisOut,NewCol,HDIn,HDOut)
  ).

pp_descs([Desc],DupsIn,DupsOut,VisIn,VisOut,Col,HDIn,HDOut) :-
  !, pp_desc(Desc,DupsIn,DupsOut,VisIn,VisOut,Col,HDIn,HDOut), write(')').
pp_descs([D|Ds],DupsIn,DupsOut,VisIn,VisOut,Col,HDIn,HDOut) :-
  pp_desc(D,DupsIn,DupsMid,VisIn,VisMid,Col,HDIn,HDMid), write(','), nl, tab(Col),
  pp_descs(Ds,DupsMid,DupsOut,VisMid,VisOut,Col,HDMid,HDOut).

pp_tail([],Dups,Dups,Vis,Vis,_,HD,HD) :-
  !,write(']').
pp_tail([H|T],DupsIn,DupsOut,VisIn,VisOut,Col,HDIn,HDOut) :-
  !,write(','),pp_desc(H,DupsIn,DupsMid,VisIn,VisMid,Col,HDIn,HDMid),
  pp_tail(T,DupsMid,DupsOut,VisMid,VisOut,Col,HDMid,HDOut).
pp_tail(NonList,DupsIn,DupsOut,VisIn,VisOut,Col,HDIn,HDOut) :-
  write('|'),pp_desc(NonList,DupsIn,DupsOut,VisIn,VisOut,Col,HDIn,HDOut),
  write(']').


*/




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Desc Helpers for reentrant variables
% and corefrences

:-dynamic coref_num/1.

gen_next_corer(N):-
	coref_num(CurrN),
	NewN is CurrN +1,
	retract(coref_num(CurrN)),
	assert(coref_num(NewN)),
	name(NewN,NewL),
	append([35],NewL,NL),
	name(N,NL).

is_coref(X):-
	atom(X),
	name(X,XL),
	append([35],_,XL).

both_type_or_coref(D1,D2):-
	(type(D1);is_coref(D1)),
	(type(D2);is_coref(D2)).

coref_and_type(D1,D2):-
	is_coref(D1),
	type(D2).


/*===============================================================*
 * Handling lists of descriptions:
 *
 * Features can have a list of descs as their value
 * for example in ALE  could have
 *  'ARG-S':[a,b] 
 *  and here is how LKB wants it:
 * [ARG-S  ne_list & [ HD a, TL  ne_list & [ HD b, TL e_list ] ] ].
 *============================================================== */

 
tdl_tail([T]) :-
  !,(var(T)->
    ( gen_next_corer(N2),
      T = N2
    );true
  ),	 
  tdl_tail(T),write(' > ').

tdl_tail(NonList) :-
  !,	 
  tdl_desc(NonList),write(' > ').

tdl_desc([]) :-
  !,write(' < > ').

tdl_desc([H|T]) :-
  !,
  write(' < '),
  (var(H)->
    ( gen_next_corer(N1),
      H = N1
    );true
  ),
  (var(T)->
    ( gen_next_corer(N2),
      T = N2
    );true
  ),	 
  tdl_desc(H),
  write(' , '),tdl_tail(T).

tdl_desc(F:D) :-
  !, 
  write('[ '),check_list_fs(F,F1),
  write(F1),write(' '),
  (var(D)->
    ( gen_next_corer(N),
      D = N
    );true
  ),	
  tdl_desc(D),write(']').

tdl_desc((D1,D2)) :-
  !,
  (var(D1)->
    ( gen_next_corer(N),
      D1 = N
    );true
  ),
  ((coref_and_type(D1,D2)) ->
  (
    check_list_types(D1,TDLT1),write(TDLT1),write(' & '),
    check_list_types(D2,TDLT2),tdl_desc(TDLT2)
  );
  (
   tdl_desc(D1),
   write(' & '),
   tdl_desc(D2)
  )).

tdl_desc(a_ X) :-
  !, ((is_list(X))->(name(N,X),write('"'),write(N),write('"'));(write('string'))).

tdl_desc(X) :-
  !, atom(X),write(' '),check_list_types(X,TDLX),check_list_fs(TDLX,TDLY),write(TDLY).


/*
tdl_tail([]) :-
  !,write('e_list ').

tdl_tail(NonList) :-
  tdl_desc(NonList).
 
tdl_tail([T]) :-
  !,(var(T)->
    ( gen_next_corer(N2),
      T = N2
    );true
  ),	 
  tdl_tail(T).


tdl_desc([]) :-
  !,write('e_list').


tdl_desc([H|T]) :-
  !,write(' [ HD '),
  (var(H)->
    ( gen_next_corer(N1),
      H = N1
    );true
  ),
  (var(T)->
    ( gen_next_corer(N2),
      T = N2
    );true
  ),	 
  tdl_desc(H),
  write(', TL '),tdl_tail(T), write(' ]').

tdl_desc(F:D) :-
  !, 
  write('['),
  write(F),write(' '),
  (var(D)->
    ( gen_next_corer(N),
      D = N
    );true
  ),	
  tdl_desc(D),write(']').

tdl_desc((D1,D2)) :-
  !, 
  (var(D1)->
    ( gen_next_corer(N),
      D1 = N
    );true
  ),
  ((coref_and_type(D1,D2)) ->
  (
    write(D1),write(' & '),
    ((D2 == bot)-> write('*top*');tdl_desc(D2))
  );
  (
   tdl_desc(D1),
   write(' & '),
   tdl_desc(D2)
  )).

tdl_desc(a_ X) :-
  !, ((is_list(X))->(name(N,X),write('"'),write(N),write('"'));(write('string'))).

tdl_desc(X) :-
  !, atom(X),write(' '),((X == bot)-> write('*top*');write(X)).

*/


/*
tdl_tail([]) :-
  !,%write(']').
   write('>').

tdl_tail([H|T]) :-
  !,write(','),tdl_desc(H),
  tdl_tail(T).

tdl_tail(NonList) :-
  %write('|'),
  write(','),
  tdl_desc(NonList),
  write('>').

tdl_descs([Desc]) :-
  !, tdl_desc(Desc), write(')').

tdl_descs([D|Ds]) :-
  tdl_desc(D), write(','), 
  tdl_descs(Ds).

'ARGS':(tl:e_list,hd:'SYNSEM':'LOCAL':'CAT':('HEAD':(verb,'MOD':(hd: DTR2 ,tl:e_list),'VFORM':fin),'MC':plus))

*/



/******** HELPER PERIDICATES AND UTILS *********************/

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%groundChk/2: gets two list, and examine each member of the 
% first list to be bounded to a logical variable, it eliminates
% all wierd (a_ _A, a_ _B, etc.)types and puts the desired types
% into the second Grounded list.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
groundChk(NonGrounded,Grounded) :-
	findall(X,(member(X,NonGrounded),ground(X)),Grounded).

/*----------------------- Transitive Reduction ---------------------------------*/
/*----------------------- Transitive Reduction ---------------------------------*/
/*----------------------- Transitive Reduction ---------------------------------*/

/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 * TODO: this is the old version of transitive reduction 
 * if there are far too many redundant links it will give an
 * error saying too many choicepoints, for example after DMC
 * completion, but here, it works fine, upgrade to the 
 * transitive reduction used for DMC completion.
 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */

:- dynamic open/1,close/3,red_edge/2,out/2,topo/1.

do_dfs(V,Out,Out_star,Out_red):-
        Out_star = [V], Out_red = [],
        asserta(open(V)),
        traverse(V,Out,Out_star,Out_red).

traverse(V,[W|Rest],Out_star,Out_red):-
        member(W,Out_star) ->
          (
            NewOut_star = Out_star, NewOut_red = Out_red,
            assert(red_edge(V,W)),
            traverse(V,Rest,NewOut_star,NewOut_red)
          )
         ;(
            (
             close(W,Out_star_w,_) ->
             (
                union(Out_star_w,Out_star,NewOut_star)
             )
             ;(
                immed_subs_topo_sorted(W,Out_W),
                do_dfs(W,Out_W,Out_star_w,_Out_red_w),
                close(W,OS,_),
                union(OS,Out_star,NewOut_star)
             )
            ),NewOut_red=[W|Out_red]
          ),traverse(V,Rest,NewOut_star,NewOut_red).

traverse(V,[],Out_star,Out_red) :-
        open(V),asserta(close(V,Out_star,Out_red)),retract(open(V)).

immed_subs_topo_sorted(Type_node,Out):-
        immed_subtypes(Type_node,Sorted_subs_n),
	groundChk(Sorted_subs_n,Sorted_subs),
	topo(Topo),
	gen_out(Type_node,Topo,Sorted_subs,[]),
	out(Type_node,OutR),reverse(OutR,Out),!.
	
gen_out(V,[T|TopoRest],Ims,Out):-
	member(T,Ims)->
	gen_out(V,TopoRest,Ims,[T|Out])
	;gen_out(V,TopoRest,Ims,Out).			

gen_out(V,[],_Ims,Out) :- 
	assert(out(V,Out)).

gen_topo:-
	findall(X,type(X),VN), %first find all of the types ( V nodes)
	groundChk(VN,V),sort(V,Vs), % refine and sort them
	gen_top_in(Vs,[]).
		
gen_top_in([V|Vs],TopoInput):-
	immed_subtypes(V,Ims),groundChk(Ims,GIms),
	gen_top_in(Vs,[V-GIms|TopoInput]).

gen_top_in([],TopoInput):- 
		reverse(TopoInput,L),top_sort(L,Top),assert(topo(Top)).


union([X|Y],Z,W) :- member(X,Z),  union(Y,Z,W).
union([X|Y],Z,[X|W]) :- \+ member(X,Z), union(Y,Z,W).
union([],Z,Z).

trans2 :-
        retractall(red_edge(_,_)),
        retractall(close(_,_,_)),
        retractall(open(_)),
	retractall(out(_,_)),
	retractall(topo(_)),
	gen_topo,
        immed_subs_topo_sorted(bot,Out),
        do_dfs(bot,Out,_,_).

/*----------------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------------*/

%%%%%%%%%%%%%%%%%%%%% INDIVIDUAL TEST CALLS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

trule:-
  retractall(coref_num(_)),
   assert(coref_num(0)),
  write('np_n_cmpnd_2  := '),
  (np_n_cmpnd_2	 rule Mom ===> cat> Dtr1 , cat> Dtr2),	
  tdl_desc(Mom),write('& [ ARGS '),tdl_desc([Dtr1,Dtr2]),write(' ].').

trule2:-
  retractall(coref_num(_)),
   assert(coref_num(0)),
  write('yesno  := '),
  (yesno rule Mom ===> cat> Dtr1),	
  tdl_desc(Mom),write('& [ ARGS '),tdl_desc([Dtr1]),write(' ].').


trule3:-
  retractall(coref_num(_)),
   assert(coref_num(0)),
  write('hspec  := '),
  (hspec rule Mom ===> cat> Dtr1 , cat> Dtr2),	
  tdl_desc(Mom),write('& [ ARGS '),tdl_desc([Dtr1,Dtr2]),write(' ].').


%%%%%%%%%%%%%%%%%%% RULES NEEDED FOP where is %%%%%%%%%%%%%%%%%%%%%
trule4:-
  retractall(coref_num(_)),
  assert(coref_num(0)),
  write('fillhead_wh_nr_f  := '),
  (fillhead_wh_nr_f rule Mom ===> cat> Dtr1 , cat> Dtr2),	
  tdl_desc(Mom),write('& [ ARGS '),tdl_desc([Dtr1,Dtr2]),write(' ].').


trule5:-
  retractall(coref_num(_)),
   assert(coref_num(0)),
  write('temp_np  := '),
  (temp_np rule Mom ===> cat> Dtr1),	
  tdl_desc(Mom),write('& [ ARGS '),tdl_desc([Dtr1]),write(' ].').



trule6:-
  retractall(coref_num(_)),
   assert(coref_num(0)),
  write('extrasubj_f  := '),
  (extrasubj_f rule Mom ===> cat> Dtr1),	
  tdl_desc(Mom),write('& [ ARGS '),tdl_desc([Dtr1]),write(' ].').

tlex4:-
  lex_toTdl([where]).

tlex5:-
  lex_toTdl([is]).



tlex:-
  retractall(coref_num(_)),
   assert(coref_num(0)),
  write('sounds_2  :=  '),
  tdl_desc((lex_rule_infl_affixed,'C-CONT':('INDEX':(A,'full_ref-ind','DIVISIBLE':plus,'PNG':'PN':'3pl*'),'LISZT':('LAST':(B,[(C,'_sound_rel','HANDEL':D,'INST':A,'LABEL':ne_list)|E]),'LIST':B),'TOP':D),'INFLECTED':plus,'NEEDS-AFFIX':plus,'ROOT':minus,'STEM':hd:(a_[83,79,85,78,68,83]),'SYNSEM':(noun_nocomp_synsem,'LOCAL':(plur_noun,'AGR':A,'ARG-S':[(F,synsem,'LOCAL':('CAT':('HEAD':det,'VAL':('COMPS':'*olist*','SPR':'*olist*','SUBJ':[])),'CONT':mrs_min,'KEYS':'KEY':quant_or_wh_rel),'NON-LOCAL':('QUE':G,'REL':H,'SLASH':I),'OPT':minus)|(J,[])],'CAT':('HC-LEX':minus,'HEAD':('noun*','MOD':[],'POSS':minus),'MC':na,'VAL':('COMPS':J,'SPR':[F],'SUBJ':[])),'CONJ':cnil,'CONT':('nom-obj_mrs','--TOPKEY':C,'H-CONS':('LAST':K,'LIST':K),'INDEX':A,'LISZT':('LAST':E,'LIST':B),'TOP':D),'KEYS':('KEY':C,'MESSAGE':('0-dlist','LAST':(L,'0-1-list'),'LIST':L)),'STEMHEAD':countnstem),'MODIFIED':notmod,'NON-LOCAL':('QUE':G,'REL':H,'SLASH':I)))).
 
tlex2:-
  lex_toTdl([sounds]).

tlex3:-
  lex_toTdl([november]).


