% Grammar
% (c) Sandiway Fong, University of Arizona (2014,2015).
%% CHANGES
%% Updated:
%% October 2020 inherent theta
%% August 2020 Sag HPSG examples
%% March 2019 for additional relative clause examples
%% 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(_)]). % PRO
features(d_optC,[f(case,opt(_,obq),_),f('N',_)],[f(phi,[_,_,_],_),f(theta,_)],[occ(_)]). % optionally receive Case (temporal 'yesterday' etc.)
% theta may be valued: PM inherent theta role, e.g. yesterday
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),		% can't value uD
	  no_check('T')]).	% can't value uT

features(a,[f(case,_,_),f('N',_)],[f(phi,[3,sg,_],_),f(theta,_)],[occ(_)]).
features(one,[f(case,_,_),f('N',_)],[f(phi,[3,sg,_],_),f(theta,_)],[occ(_)]).
features(several,[f(case,_,_),f('N',_)],[f(phi,[3,pl,_],_),f(theta,_)],[occ(_)]).
features(many,[f(case,_,_),f('N',_)],[f(phi,[3,pl,_],_),f(theta,_)],[occ(_)]).
features(the,[f(case,_,_),f('N',_)],[f(theta,_)],[occ(_)]).
features(this,[f(case,_,_),f('N',_)],[f(theta,_)],[occ(_)]).

features(q,[f(case,_,_),f('N',_),f(scope,_)],[f(theta,_),f(wh)],[occ(_)]). % [q q n]
features(what:d,[f(case,_,_),f('N',_),f(scope,_)],
	 [f(phi,[3,_,_],_),f(theta,_),f(wh)],[occ(_)]).
features(which,[f(case,_,_),f('N',_),f(scope,_)],
	 [f(phi,[3,_,_],_),f(wh),f(theta,_)],[occ(_)]).
% which as a "relative pronoun"
% iWh controls pied-piping
features(which_rel,[f(case,_,_),f('N',_)],
	 [f(phi,[3,_,_],_),f(wh),f(theta,_),f(rel)],
	 [check('T'),		% can value uT
	  no_check(d),		% can't value uD
	  occ(_)]).
% who as a "relative pronoun"
features(who_rel,[f(case,_,_),f('N',_)],
	 [f(phi,[3,_,_],_),f(wh),f(theta,_),f(rel)],
	 [check('T'),		% can value uT
	  no_check(d),		% can't value uD
	  occ(_)]).

% to simulate who_rel with rel feature moved upwards to 's_rel
% features(who_def,[f(case,_,_),f('N',_)],
% 	 [f(phi,[3,_,_],_),f(wh),f(theta,_)],
% 	 [check('T'),		% can value uT
% 	  no_check(d),		% can't value uD
% 	  occ(_)]).

% who as a "relative pronoun"
features(what_rel,[f(case,_,_),f('N',_)],
	 [f(phi,[3,_,_],_),f(wh),f(theta,_),f(rel)],
	 [check('T'),		% can value uT
	  no_check(d),		% can't value uD
	  occ(_)]).

% when as a "relative pronoun"
features(when_rel,[f(case,_,_),f('N',_)],
	 [f(phi,[3,_,_],_),f(wh),f(theta,_),f(rel)],
	 [check('T'),		% can value uT
	  no_check(d),		% can't value uD
	  occ(_)]).

% where as a "relative pronoun"
features(where_rel,[f(case,_,_),f('N',_)],
	 [f(phi,[3,_,_],_),f(wh),f(theta,_),f(rel)],
	 [check('T'),		% can value uT
	  no_check(d),		% can't value uD
	  occ(_)]).

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

features(self,[f(case,_,_),f('N',_)],[f(theta,_)],
	 [phase(_),release(_),occ(_)]).
features('\'s',[f(case,_,_),f('N',_)],[f(phi,[3,_,_],_),f(theta,_)],
	 [ef(unvalued_iF(theta),_),phase(_),occ(_)]).
features('\'s_rel',[f(case,_,_),f('N',_)],[f(phi,[3,_,_],_),f(theta,_),f(rel)],
	 [ef(unvalued_iF(theta),_),phase(_),occ(_)]).

features('N',[],[],[]).
% special case: adjunct DP 'yesterday', inherent theta and case
features(yesterday,[f('D',_)],[f(phi,[3,sg,n],_),f(theta,temporal)],[occ(_)]).
features(N,[f('D',_)],[f(phi,[3,sg,n],_)],[occ(_)]) :- nRoot1(N).
features(N,[f('D',_)],[f(phi,[3,pl,n],_)],[occ(_)]) :- nRoot2(N).
features(N,[f('D',_)],[f(phi,[3,_,n],_)],[occ(_)]) :- nRoot3(N).

% triggers Doubling Constituent (DC) merge
features(he,[f('D',_)],[f(phi,[3,sg,m],_)],[dc,occ(_)]).
features(she,[f('D',_)],[f(phi,[3,sg,f],_)],[dc,occ(_)]).
% features(pro,[f(case,_,_)],[f(phi,_Phi,_),f(theta,_)],[dc,unify(iF(theta)),occ(_)]).
features(pro,[f(case,_,_)],[f(phi,_Phi,_),f(theta,_)],[dc,occ(_)]).

features(pro_n,[f('D',_)],[f(phi,[3,sg,n],_)],[occ(_)]).
features(pro2,[f('D',_)],[f(phi,[2,_,mf],_)],[occ(_)]).

features(i,[f('D',_)],[f(phi,[1,sg,mf],_)],[occ(_)]).
features(you,[f('D',_)],[f(phi,[2,pl,mf],_)],[occ(_)]).
features(they,[f('D',_)],[f(phi,[3,pl,mf],_)],[occ(_)]).
features(we,[f('D',_)],[f(phi,[3,pl,mf],_)],[occ(_)]).

features(n,[f('D',_)],[f(phi,[3,sg,n],_)],[]).
features(nPl,[f('D',_)],[f(phi,[3,pl,m],_)],[]).

features(there,[f(phi,[_,x,x],_)],[f(expl)],[noProject,occ(_)]).
features(it,[f(case,_,_)],[f(phi,[3,sg,m],_),f(expl)],[noProject,occ(_)]).

features(p,[],[],[]).
% features('G',[],[],[ef(internal(unvalued_uF(case)),_)]). % not sure why internal & uCase
features('G',[],[],[ef(internal(unvalued_iF(theta)),_)]).
features('G_nc',[],[],[ef(unvalued_iF(theta),_),nocase]).
% features(to:p,[],[],[ef(unvalued_iF(theta),_),occ(_)]).
features(to,[],[],[ef(unvalued_iF(theta),_),occ(_)]).
% features(to,[],[],[occ(_)]). % monadic preposition "to"
features(to,[],[],[nocase,occ(_)]). % e.g. talk to
features(up,[],[],[nocase,occ(_)]). % e.g. talk to
features(about,[],[],[occ(_)]).
features(from,[],[],[ef(unvalued_iF(theta),_)]).
features(of,[],[],[occ(_)]).
features('G2',[],[],[occ(_),no_pied_pipe]). % award [the driver] [G2 a prize]
features(on,[],[],[nocase,occ(_)]).
features(on,[],[],[ef(unvalued_iF(theta),_),occ(_)]).
features(on_nc,[],[],[ef(unvalued_iF(theta),_),nocase,occ(_)]).
features(in,[],[],[occ(_)]).
features(in,[],[],[ef(unvalued_iF(theta),_),occ(_)]).
features(caus_p,[],[],[ef(unvalued_iF(theta),_),nocase]).

features(by,[],[],[occ(_)]).
features(than,[],[],[occ(_)]).

features('V',[],[],[]).
features(V,[],[],[occ(_)]) :- vRoot(V). % no occ before?

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

features(A,[],[],[ef(unvalued_iF(theta),_)]) :- aRoot2(A).

features(Adv,[],[],[]) :- advRoot(Adv).

% 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(_)]).
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(will,[],[],[occ(_),sp(_)]).
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

% 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('Tdef',[f(phi,_,_)],[],[ef(_,_),occ(_),id(_)]).
features('Tinf',[f(phi,_,_)],[],[nullCase,ef(_,_),occ(_),id(_)]).

%% allow 'for' to value T, used in c_rel for
%% allow 'for' to raise to edge of c_rel
features(for,[f(phi,_,_)],['T'],[occ(_),phase(_)]).

%% declarative c

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

% embedded declarative
features(c_e,[f('T',_)],[f(theta,_)],[ef(_,_),id(_),phase(_)]).   

% embedded declarative (wh-mvmt host) = c_Q minus feature xmission
% c_eQ should not have iScope, other it will value uScope too early
features(c_eQ,[f(wh,_),f('T',_)],[f(theta,_)],[ef(_,_),id(_),phase(_)]). 

%% interrogative c
% uWh before uT (because T to C relies on being blocked for economy)

% matrix interrogative
features(c_Q,[f(wh,_),f('T',_)],[f(scope)],[ef(_,_),id(_),phase(_)]).  

% embedded interrogative
features(c_Qe,[f(wh,_),f('T',_)],[f(theta,_),f(scope)],[ef(iF(wh),_),id(_),phase(_)]).  

%%% NEW: c_rel has phi-features
% Note: simplifies probegoal: phi after rel
features(c_rel,[f(rel,_),f('T',_),f(phi,_,_)],[],[ef(_,_),id(_),phase(_)]).

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

% Verbal roots
vRoot(annoy).
vRoot(arrest).
vRoot(arrive).
vRoot(ask).
vRoot(award).
vRoot(be).
vRoot(believe).
vRoot(bring).
vRoot(buy).
vRoot(call).
vRoot(catch).
vRoot(cause).
vRoot(consider).
vRoot(dedicate).
vRoot(die).
vRoot(donate).
vRoot(expect).
vRoot(fall).
vRoot(find).
vRoot(get).
vRoot(give).
vRoot(grow).
vRoot(inspire).
vRoot(kill).
vRoot(know).
vRoot(laugh).
vRoot(live).
vRoot(leave).
vRoot(like).
vRoot(love).
vRoot(meet).
vRoot(offend).
vRoot(place).
vRoot(play).
vRoot(please).
vRoot(praise).
vRoot(put).
vRoot(read).
vRoot(recognize).
vRoot(rely).
vRoot(run).
vRoot(say).
vRoot(see).
vRoot(seem).
vRoot(sell).
vRoot(show).
vRoot(study).
vRoot(take).
vRoot(talk).
vRoot(teach).
vRoot(tell).
vRoot(think).
vRoot(visit).
vRoot(worry).
vRoot(watch).
vRoot(write).

% Adjectival roots
aRoot(available).
aRoot(drunk).
aRoot(easy).
aRoot(hard).
aRoot(intelligent).
aRoot(likely).
% aRoot(proud).
aRoot(smart).
aRoot(tiny).
aRoot(tough).

% proud(X,Y)
aRoot2(fond).
aRoot2(proud).

% temporary hack (attributive)
aRootL(favorite).
aRootL(flying).
aRootL(large).
aRootL(silly).
aRootL(small).

% Nominal roots
nRoot1(ann).
nRoot1(bill).
nRoot1(dick).
nRoot1(hannah).
nRoot1(john).
nRoot1(mike).
nRoot1(mary).
nRoot1(max).
nRoot1(pat).
nRoot1(patrick).
nRoot1(pete).
nRoot1(peter).
nRoot1(sandra).
nRoot1(sue).

nRoot1(what:n).
nRoot1(someone).
nRoot1(who).
nRoot1('PRO').

nRoot1(apple).
nRoot1(appearance).
nRoot1(audience).
nRoot1(baker).
nRoot1(ball).
nRoot1(box).
nRoot1(book).
nRoot1(boy).
nRoot1(brother).
nRoot1(building).
nRoot1(cake).
nRoot1(car).
nRoot1(charity).
nRoot1(dog).
nRoot1(driver).
nRoot1(english).
nRoot1(floor).
nRoot1(fortune).
nRoot1(friend).
nRoot1(girl).
nRoot1(house).
nRoot1(here).
nRoot1(letter).
nRoot1(linguist).
nRoot1(lobbyist).
nRoot1(man).
nRoot1(mirror).
nRoot1(mother).
nRoot1(number).
nRoot1(package).
nRoot1(person).
nRoot1(phone).
nRoot1(picture).
nRoot1(present).
nRoot1(prize).
nRoot1(problem).
nRoot1(saucer).
nRoot1(scandal).
nRoot1(senator).
nRoot1(shelf).
nRoot1(sister).
nRoot1(sonata).
nRoot1(student).
nRoot1(story).
nRoot1(table).
nRoot1(time).
nRoot1(town).
nRoot1(train).
nRoot1(trust).
nRoot1(violin).
nRoot1(war).

% Ns -s -> NPl spelling rule
nRoot2(NPl) :-
	(nRoot2x(NPl) -> true
	;
	 (var(NPl) ->
	  nRoot1(Nsg), atomic(Nsg),
	  atomic_list_concat([Nsg,s],NPl),
	  !			% green
	 ;
	  atomic(NPl),		% block -suffix
	  atom_chars(NPl,Cs),
	  append(C,[s],Cs),
	  atom_chars(Nsg,C),
	  nRoot1(Nsg),
	  !			% green
	 )).

% exceptions to the -s spelling rule
nRoot2x(boxes).
nRoot2x(charities).
nRoot2x(englishes).
nRoot2x(men).
nRoot2x(shelves).
nRoot2x(stories).

nRoot3(fish). 			% need to fix features

advRoot(better).

% 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_be,v).		
type('v~unacc',v).	type('v~',v).		type(v_unerg,v).
type(caus,v).		type(will,v).		type(caus_v,v).

type(v_ex,v_ex).	type(v_nop,v).
type('v~','v~').		% note: v~ is already 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) :- aRoot2(A).
type(A,a) :- aRootL(A).

type(adv,adv).		type(better,adv).

type(p,p).		type(of,p).		type('G',p).
type('G2',p).		type(on_nc,p).		
type(from,p).		type(about,p).		type(on,p).
type(in,p).		type(to,p).		type('G_nc',p).
type(caus_p,p).		type(for,p).		type(by,p).
type(than,p).		type(up,p).

type(d,d).		type(q,d).		type(one,d).	
type(what,d).		type(how,d).		type(many,d).
type(a,d).		type(the,d).		type(several,d). 
type(which,d).		type(self,d).		type('\'s',d).
type(d0,d).		type(this,d).		type(pro,d).
type(d_optC,d).
type(d_rel,d).		type(which_rel,d).	type(who_rel,d).
type(what_rel,d).	type('\'s_rel',d).	type(when_rel,d).
type(where_rel,d).
type(who_def,d).

type(n,n).		type(nPl,n).		type(pro_n,n).
type(pro2,n).
type(yesterday,n).

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

type(he,n).		type(we,n).		type(they,n).
type(you,n).		type(she,n).		type(i,n).


%% SPELL-OUT

parameter(head(first)).

% 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(n). 	
no_spellout(d0). 	
no_spellout(d). 	
no_spellout(d_optC). 	
no_spellout(d_rel). 	
no_spellout(q).
no_spellout('G').
no_spellout('G2').
no_spellout('G_nc').
no_spellout(caus_p).
no_spellout('caus_v').
no_spellout('PRO').
no_spellout(pro).
no_spellout(pro_n).
no_spellout(pro2).
no_spellout(a_).

% 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).

% of who_rel cannot spell out at all (e.g. as whose)
% than who_rel cannot spell out at all (no pied-piping, assuming than:p)
block_heads(of,who_rel).
block_heads(than,who_rel).

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

% who + 's -> whose
realize_heads2(who_def,'\'s_rel',[whose]).
realize_heads2(who_rel,'\'s',[whose]).

% possessive pronouns
realize_heads2(he,'\'s',[his]).
realize_heads2(she,'\'s',[her]).
realize_heads2(they,'\'s',[their]).
realize_heads2(you,'\'s',[your]).
realize_heads2(i,'\'s',[my]).
realize_heads2(it,'\'s',[its]).

realize2_head(_,_) :- fail.

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

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

realize_head(prog,-ing).
realize_head('v~',be).
realize_head(v,have).
realize_head(v_be,be).
realize_head(perf,-en).
realize_head(prt,-en).
realize_head(prt2,-en).

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

realize_head(t(_,_,Occ),_) :- nonvar(Occ), !, fail.
realize_head(t(X,[unified(Y),Z],V),S) :- realize_head(t(X,[Y,Z],V),S).
realize_head(t(pres,[1,sg],_),-m).	 % am
realize_head(t(pres,[2,sg],_),-re). % are
realize_head(t(pres,[3,sg],_),-s).
realize_head(t(pres,[_,pl],_),-re).	% are
realize_head(t(past,[1,sg],_),-ed(sg)).
realize_head(t(past,[1,pl],_),-ed(pl)).
realize_head(t(past,[2,_],_),-ed(pl)).
realize_head(t(past,[3,sg],_),-ed(sg)).
realize_head(t(past,[3,pl],_),-ed(pl)).

% assume aux verbs are little v's
realize_head(will,will).

realize_head(on_nc,on).
realize_head(which_rel,which).
realize_head(who_rel,who).
realize_head(who_def,who).
realize_head(what_rel,what).
realize_head(when_rel,when).
realize_head(where_rel,where).

%%% Initial caps, works only for spellout
realize_head(i,'I').
realize_head(ann,'Ann').
realize_head(bill,'Bill').
realize_head(dick,'Dick').
realize_head(english,'English').
realize_head(hannah,'Hannah').
realize_head(john,'John').
realize_head(mike,'Mike').
realize_head(mary,'Mary').
realize_head(max,'Max').
realize_head(pat,'Pat').
realize_head(patrick,'Patrick').
realize_head(pete,'Pete').
realize_head(peter,'Peter').
realize_head(sandra,'Sandra').
realize_head(sue,'Sue').

realize_head('Tinf',to).
realize_head(for,for).

realize2_heads(_,_,_) :- fail.

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

% affix + head => spell-out
spell_out(m,be,am).
spell_out(s,be,is).
spell_out(re,be,are).
spell_out(ing,be,being).
spell_out(en,be,been).
spell_out(ed(sg),be,was).
spell_out(ed(pl),be,were).
spell_out(s,have,has).
spell_out(ing,have,having).
spell_out(en,have,had).
spell_out(ed(_),have,had).

spell_out(acc,who,whom).
spell_out(acc,he,him).
spell_out(acc,she,her).
spell_out(acc,they,them).
spell_out(acc,i,me).
spell_out(acc,'I',me).
spell_out(acc,we,us).
spell_out(obq,he,him).
spell_out(obq,she,her).
spell_out(obq,they,them).
spell_out(obq,i,me).
spell_out(obq,we,us).

spell_out(self,him,himself).
spell_out(self,her,herself).
spell_out(self,my,myself).
spell_out(self,you,yourself).
spell_out(self,you,yourselves).	% plural
spell_out(self,our,ourselves).
spell_out(self,they,themselves).
spell_out(self,he,nospellout).	% lexical gap

% irregular forms
spell_out(en,catch,caught).
spell_out(en,take,taken).
spell_out(ed(_),bring,brought).
spell_out(en,bring,brought).
spell_out(s,bring,brings).
spell_out(ed(_),buy,bought).
spell_out(en,buy,bought).
spell_out(ed(_),will,would).
spell_out(en,will,would).
spell_out(s,will,will).
spell_out(ed(_),do,did).
spell_out(s,do,does).
spell_out(m,do,do).
spell_out(re,do,do).
spell_out(en,fall,fell).
spell_out(ed(_),fall,fallen).
spell_out(s,fall,falls).
spell_out(en,find,found).
spell_out(ed(_),find,found).
spell_out(s,find,finds).
spell_out(en,get,gotten).
spell_out(ed(_),get,got).
spell_out(s,get,gets).
spell_out(en,give,given).
spell_out(ed(_),give,gave).
spell_out(s,give,gives).
spell_out(en,grow,grown).
spell_out(ed(_),grow,grew).
spell_out(en,know,known).
spell_out(ed(_),know,knew).
spell_out(ed(_),leave,left).
spell_out(en,put,put).
spell_out(ed(_),put,put).
spell_out(s,put,puts).
spell_out(en,read,read).
spell_out(ed(_),read,read).
spell_out(s,read,reads).
spell_out(en,rely,relied).
spell_out(ed(_),rely,relied).
spell_out(s,rely,relies).
spell_out(en,run,run).
spell_out(ed(_),run,ran).
spell_out(en,see,seen).
spell_out(ed(_),see,saw).
spell_out(s,see,sees).
spell_out(en,say,said).
spell_out(ed(_),say,said).
spell_out(s,say,says).
spell_out(en,sell,sold).
spell_out(ed(_),sell,sold).
spell_out(s,sell,sells).
spell_out(s,study,studies).
spell_out(ed(_),study,studied).
spell_out(ed(_),teach,taught).
spell_out(en,teach,taught).
spell_out(s,teach,teaches).
spell_out(en,tell,told).
spell_out(ed(_),tell,told).
spell_out(s,tell,tells).
spell_out(en,write,written).
spell_out(ed(_),write,wrote).
spell_out(s,write,writes).
spell_out(en,worry,worried).
spell_out(ed(_),worry,worried).
spell_out(s,worry,worries).

% rules
spell_out(m,V,V).
spell_out(re,V,V).
spell_out(s,V,Vs) :- atomic_list_concat([V,s],Vs).
spell_out(s,V,Vs) :- atomic_list_concat([V,s],Vs).
spell_out(ed(_),V,Ved) :- 
    (ends_with_e(V,V1) -> true ; V1 = V), 
    atomic_list_concat([V1,ed],Ved).
spell_out(en,V,Ven) :- 
    (ends_with_e(V,V1) -> true ; V1 = V), 
    atomic_list_concat([V1,ed],Ven).
spell_out(ing,V,Ving) :- 
    (ends_with_e(V,V1) -> true ; V1 = V), 
    atomic_list_concat([V1,ing],Ving).

ends_with_e(X,Y) :- atom_chars(X,L), append(L2,[e],L), atom_chars(Y,L2).

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]).

% d with uCase, if uCase is non-nominative, -Case is spelled out
% e.g. -acc, -gen
portray_emptyhead(d,UFs,_Fs,[-C]) :-
    member(f(case,C,_),UFs),
    nonvar(C), \+ (C = nom ; C = nom(_)).

% Case parameters
case_parameter(p,obq).

