% Grammar
% (c) Trevor Sullivan and Sandiway Fong, University of Arizona (2015).

%% CHANGES
%% phase => phase(_) for phase completeness
%% v* not a phase, T a phase (for doubling constituent release)

%% HEADS

% features of heads
% label x uninterpretable features x interpretable features x features
features(d0,[f(case,null(_),_),f('N',_)],[f(phi,[_,_,_],_),f(theta,_)],[occ(_)]).
features(d,[f(case,_,_),f('N',_)],[f(phi,[_,_,_],_),f(theta,_)],[occ(_)]).
features(d_rel,[f(case,_,_),f('N',_)],
	 [f(phi,[_,_,_],_),f(theta,_),f(rel)],
	 [occ(_),no_check(d),no_check('T')]).

features(q,[f(case,_,_),f('N',_),f(scope,_)],[f(theta,_),f(wh)],[occ(_)]). % [q q n]

features('N',[],[],[]).
features(N,[f('D',_)],[f(phi,[3,sg,n],_)],[occ(_)]) :- nRoot1(N).
features(N,[f('D',_)],[f(phi,[3,sg,f],_)],[occ(_)]) :- nRoot2(N).

% pronouns
% 'I' [1.sg], 'we' [1.pl]
features(man,[f('D',_)],[f(phi,[1,sg,mf],_)],[occ(_)]).
features(ma,[f('D',_)],[f(phi,[1,pl,mf],_)],[occ(_)]).
% 'you' [2.sg], shoma [2.pl]
features(to,[f('D',_)],[f(phi,[2,sg,mf],_)],[occ(_)]).
features(shoma,[f('D',_)],[f(phi,[2,pl,_],_)],[occ(_)]).
% 'he/she' u  [3.sg]
% 'it'     an [3.sg]
% they 	   anha [3.pl]
features(u,[f('D',_)],[f(phi,[3,sg,mf],_)],[occ(_)]).
features(an,[f('D',_)],[f(phi,[3,sg,n],_)],[occ(_)]).
features(anha,[f('D',_)],[f(phi,[3,pl,_],_)],[occ(_)]).

features(pl,[],[],[]).

% Persian verbalizer: values uD (iPhi?) from nominal, in morphology space
features('V',[f('N',_)],[],[morphology]).		
features(V,[],[],[]) :- vRoot(V).

features(a_,[],[],[ef(_,_)]).
features(A,[],[],[]) :- aRoot(A).
features(A,[],[],[attach(left),occ(_)]) :- aRootL(A).

% Inventory of little v's
% Name	  	Spellout	Features		Agree
% v* 				EF(theta), uPhi		acc case
% v_unerg 			EF(theta)
% PRT		-en		EF, uCase, uPhi([N,G])
% [ PRT2	-en		uCase, uPhi([N,G]) ]
% v~		be		EF, check theta TOS
% v~unacc			EF, check theta TOS
% v_ex				EF(expl)
% v		have
% v_be		be		EF	(can host expl "it" in "it is tough..")
% v_nop				(dummy)
% perf		-en
% prog		-ing		EF
% cause				EF

% features('v*',[f(phi,_,_)],[],[ef(unvalued_iF(theta),_),phase(_),occ(_),sp(_)]).
% features('v_unerg',[],[],[ef(unvalued_iF(theta),_),phase(_),occ(_),sp(_)]).
features('v*',[f(phi,_,_)],[],[ef(unvalued_iF(theta),_),occ(_),sp(_)]).
% v 'kard' (PST form default)
% 'kon' (PRES)
features(kard,[],[],[]).	% do
features(gereft,[],[],[]).	% take

features('v_unerg',[],[],[ef(unvalued_iF(theta),_),occ(_),sp(_)]).

features('v*ef',[f(phi,_,_)],[],[ef(unvalued_iF(theta),_),ef(iF(expl),_),phase(_),occ(_),sp(_)]). % Dutch (TEC)
features(v_ex,[],[],[ef(iF(expl),_),occ(_),sp(_)]).
% features(v,[],[],[ef(internal(_),_)]). % spell-out have, internal merge only
features(v,[],[],[occ(_),sp(_)]). % spell-out have
% features(v_be,[],[],[occ(_),sp(_)]). % spell-out be
features(v_be,[],[],[ef(_,_),occ(_),sp(_),edge_preference(stack)]). % spell-out be, int. over ext. pref.
features(perf,[],[],[]). % spell-out -en
features('v~',[],[],[ef(_,_),occ(_),sp(_)]). % little v progressive be, passive be
features('v~unacc',[],[],[ef(_,_),occ(_),sp(_)]). % little v for unaccusative
features(prog,[],[],[ef(_,_)]). % spell-out -ing
features(caus,[],[],[ef(_,_)]). 
features(caus_v,[f(phi,_,_)],[],[occ(_),sp(_),phase(_)]).
features(v_nop,[],[],[occ(_),sp(_)]).

% Sobin's Voice_pass requires an EF for TH/EX of the OBJ in passive constructions
% (OBJ appears to the left of the verb)
features(prt,[f(phi,[x,_,_],_),f(case,_,_)],[],[ef(_,_)]). % spell-out: -en
features(prt2,[f(phi,[x,_,_],_),f(case,_,_)],[],[]). % original version no-EF, spell-out: -en

% Durative
features(dur,[],[],[]).

% T
% local C and T share ID
% features('T',[f(phi,_,_)],[],[ef(valued_iF(theta),_),occ(_),id(_)]).
features('T',[f(phi,_,_)],[],[ef(_,_),occ(_),id(_)]).
features('Tpast',[f(phi,_,_)],[],[ef(_,_),occ(_),id(_)]).
features('Tinf',[f(phi,_,_)],[],[nullCase,ef(_,_),occ(_),id(_)]).

%% declarative c

% matrix declarative
features(c,[],[],[id(_),phase(_)]).		      

xmit_uFs(c_Q,[f(v,_)],'T').

% Verbal roots
vRoot(dummy).

% Adjectival roots
aRoot(dummy).

% temporary hack
aRootL(dummy).

% Nominal roots
nRoot1(mehmun).			% guest
nRoot1(davat).			% invitation
nRoot1(zabun).			% language
nRoot1(yad).			% memory

nRoot2(bahar).			% Name (f)

% type equivalences
type(c,c).		type(c_e,c).		type(c_rel,c).
type(c_Q,c).		type(c_eQ,c).
type(c_Qe,c).		type(c_Qm,c).

type('T','T').		type('Tdef','T').	type('Tinf','T').
type('Tpast','T').

type(v,v).		type(v_ex,v).		type('v*',v).
type(prt,v).		type(prt2,v).
type('v*ef',v).		type(perf,v). 		type(prog,v).
type('v~unacc',v).	type('v~',v).		type(v_unerg,v).
type(caus,v).		type(caus_v,v).
type(kard,v).		type(gereft,v).

type(dur,v).

type(v_ex,v_ex).	type(v_nop,v).
type('v~','v~').	type('v~unacc','v~').	

type('V','V').		type(V,'V') :- vRoot(V).
type(be,'V'). 			% main verb 'be'

type(a_,a).
type(A,a) :- aRoot(A).
type(A,a) :- aRootL(A).

type(p,p).		

type(d,d).		type(q,d).		type(one,d).	

type(n,n).		type(pro_n,n).

type(N,n) :- nRoot1(N).
type(N,n) :- nRoot2(N).
type(_:C,C).

type(man,n).		type(to,n).		type(u,n). 		type(an,n).
type(ma,n).		type(shoma,n).					type(anha,n).

type(pl,pl).

%% SPELL-OUT

parameter(head(first)).
parameter(head(final('V'))).
parameter(head(final(v))).
parameter(head(final('T'))).

% parameter(head(final)).

% English spell-out
% heads or features that translate into morphemes: 
%	prog, perf, v~, PRT, Tpast, T
% heads that don't: 
% 	c, q, v_unerg, 'v*', v_ex, v~unacc,  d

% spell-out substitutions (potentially) apply to the 
% following categories
morph(c). morph(v). morph('T').

% no spellout	
no_spellout(d). 	
no_spellout(t).
no_spellout('V').

% 1st stage morpheme realization

% T v => affix v
realize_heads(T,v(_,Occ),[M]) :- 
    morpheme_withFs(T,'T'), var(Occ), 
    realize_head(T,M), arg(3,T,V), var(V), V=1.

% covert v c_Qm => do
realize_heads(v(LV,Occ),c_Qm,[do]) :- covert(LV), Occ = 1.

% T C => that
realize_heads(T,C,[that]) :- morpheme_withFs(T,'T'), type(C,c).

% C v => [] (deletes both)
realize_heads2(C,v(_,Occ),[]) :- type(C,c), var(Occ).

covert(X) :- type(X,v) -> empty(X) ; \+ realize_head(X,_).

empty('v*').	empty('v_unerg'). 

realize_head(dur,mi=).
realize_head(pl,#a).

realize_head(kard,kard).
realize_head(gereft,gereft).
realize_head(t(TNS,AGR,V),t(TNS,AGR,V)).

% first occ only
realize_head(v(Name,Occ),M) :- var(Occ), realize_head(Name,M), Occ = 1.

% 2nd stage morpheme realization

% kard PST => kard
% kard PRES => kon
realize2_heads(kard,t(past,_Phi,_),[kard]).
realize2_heads(kard,t(pres,_Phi,_),[kon]).

% gereft PST => gereft
% gereft PRES => gerav
realize2_heads(gereft,t(past,_Phi,_),[gereft]).
realize2_heads(gereft,t(pres,_Phi,_),[gerav]).

% TNS phi-feature spellout 
%   SG     PL
% 1 -am    -im
% 2 -i     -it
% 3 Ø      -and
realize2_head(t(_TNS,[1,sg],_),#am).
realize2_head(t(_TNS,[2,sg],_),#i).
realize2_head(t(_TNS,[1,pl],_),#im).
realize2_head(t(_TNS,[2,pl],_),#it).
realize2_head(t(_TNS,[3,pl],_),#and).
realize2_head(t(_TNS,[3,sg],_),[]). % null

%realize2_head(_,_) :- fail.

tense(X,TNS) :- label(X,T), tense(T,TNS).
tense('Tpast',past).
tense('T',pres).

% Last stage:
% ending V => V-ending
% -acc doesn't spell
spell_out(X,V,Vs) :- X \== acc, atomic_list_concat([V,'-',X],Vs).

morpheme_withFs(t(_TNS,_Phi,_PhiO),'T').
morpheme_withFs(t(_TNS,_Phi,_PhiO)).
morpheme_withFs(v(_V,_O)).

% tensed T 		t(TNS,[Person,Number],Phi_Occ)
% Note: implemented using occurrences on uPhi (3rd arg)
% little v              v(Name,Occ)
% Note: implemented using spellout formal feature sp(Occ)
% self => -self if non-nom case
% d => -acc if acc case
% d => -obq if obq case

portray_emptyhead(who_rel,UFs,_Fs,[whom]) :-
    member(f(case,V,_),UFs),
    V == acc.
portray_emptyhead(C,UFs,_Fs,[t(TNS,[P,N],Occ)]) :-
    type(C,'T'),
    tense(C,TNS),
    member(f(phi,[P,N,_],Occ),UFs).
portray_emptyhead(C,_UFs,Fs,[v(C,Occ)]) :-
    type(C,v),
    member(sp(Occ),Fs).
portray_emptyhead(self,UFs,_Fs,L) :-
    member(f(case,V,_),UFs),
    nonvar(V),
    ((V = nom ; V = nom(_))
     -> L = [-self]
     ;  L = [-self,-V]).

portray_emptyhead(d,UFs,_Fs,[-C]) :-
    member(f(case,C,_),UFs),
    nonvar(C), \+ (C = nom ; C = nom(_)).

% Case parameters
case_parameter(p,obq).

