				% Edgar (SEC) parsing, 04/21/2014
				% LPImmes, 508 579 2683

% Parsing tools are included in this file, unlike edgar2.m.
% I want to make interface to java easier.

%edgar2a 476>cat edgar2.bash
%mmc --make --fully-strict -s java -E -v -O 6 --use-subdirs edgar2

% 04/21/2014, Monday
% mercury-srcdist-14.01 479>./configure --enable-libgrades=hlc.gc,none.gc,none.gc.stseg,java
% mercury-srcdist-14.01 479>make
% mercury-srcdist-14.01 479>make install

% ~ 497>mmc -version
% mercury_compile: invalid grade `ion'
% Mercury Compiler, version 14.01, configured for x86_64-apple-darwin13.1.0



% BUILD
% edgar2ax 501>pwd
% /Users/lpimmes/Documents/lpimmesOnly/mercuryPrograms/edgar2a
% edgar2 501>./edgar2.bash 

% RUN
%edgar2a 464>./edgar2 In our company sales increased during last quarter
%sales increased
%edgar2 501>./edgar2 in the quarter revenues up
%revenues up
%edgar2 504>./edgar2 revenues in the quarter were $89.7 million up 16.8% from $76.8 million in 2012
%revenues up
%edgar2 505>./edgar2 revenues in the quarter were $89.7 million
%Failed to parse input sentence.

:- module edgar2.	% This file name for now.
:- interface.
:- import_module io.

% I need main/2 to test parse/2.
:- pred main(io, io).	    % main/2 used in interface, so include it!
:- mode main(di, uo) is det. % committed choice multideterminism- choose first goal that succeeds.́

:- implementation.
:- import_module list, string, bool, int, char.
%% myUil module works, but easier to include at bottom of file.
% :- import_module myUtil.	% lstToStr/3, formattedStr/2,
% 				% oneOrMore/4, oneOrMoreLst/4,
% 				% zeroOrMore/4, zeroOrMoreLst/4
% 				% optional/4

main(In, Out) :-
	io.command_line_arguments(Input, In, Out9), % Input list(string) returned
	lstToStr(Input, "", InputStr),
	parse(InputStr, OutputStr),
	io.format("%s\n", [s(OutputStr)], Out9, Out).

%%%%% Copy from here down to mercury_lib.m
% We expect string input; return string output; this is what we call from JAVA.
:- pred parse(string, string).
:- mode parse(in, out) is det.
parse(InputStr, Output) :-
	InputLst = string.words_separator(char.is_whitespace, InputStr),
	(if			
	edgarParse(KeyWrdsFnd, InputLst, []) % Last argument [] required so that difference lists work!
				% Bookkeeping: Our Input is consumed, and transferred to original [].
				% Input (eventually) becomes [], and the output (original: []) becomes populated
				% with that same Input. Eventually, KeyWrdsFnd, mode: out, will become
				% populated with pertinent keywords.
	
	then
	 KeyWrdsFnd = Output % OK parse; return keywords of interest found.

	else
	Output = "Failed to parse input sentence."
	). %  if


:- pred anyWrd(string, list(string), list(string)).
:- mode anyWrd(out,     in, out) is semidet. 
anyWrd(Ret) --> (
		 arbitraryWrd(Ret)
		).

:- pred arbitraryWrd(string, list(string), list(string)).
:- mode arbitraryWrd(out,     in, out) is semidet.
arbitraryWrd(S) --> [S]. % Thank god I don't have to enumerate them.


:- pred lstToStr(list(string), string, string).
:- mode lstToStr(in, in, out) is det.
lstToStr(Lst, Accum, Result) :-
	(if
	Lst = []
	then
	Result = Accum
	else
	
	H = list.det_head(Lst), % don't use [H| Rest], because of semidet. use:
	 Rest = list.det_tail(Lst),
	 length(Lst, Len),
	 Acc = Accum ++ H,
	 (if
	 Len = 1
	 then
	 A = Acc
	 
	 else
	 A = Acc ++ " "
	 ),
	 lstToStr(Rest, A, Result)
	).

:- pred formattedStr(list(string), string).
:- mode formattedStr(in, out) is det.
formattedStr(InStr, OutStr) :-
	delete_elems(InStr, [""], NonEmptyRemain),
	OutStr = join_list(" ", NonEmptyRemain).

:- pred zeroOrMore(pred(string, list(string), list(string)), string,
		   list(string), % Input
		   list(string)). % Consumed
:- mode zeroOrMore(in(pred(out,in,out) is semidet), out,     in, out) is semidet.
zeroOrMore(Pred, Ret)  --> numX(Pred, NumX),
	{
	 (if
	  length(NumX, 0)
	  then
	  Ret = ""
	  else
	  lstToStr(NumX, "", Ret)
	 )
	 }.

% Call input predicate Pred for X number of times-- depending upon length of list.
:- pred numX(   pred(string, list(string), list(string)),
		list(string),	% H, T, [H|T]
		
		list(string),	% Input, implicit
		list(string)). % Consumed, implicit
%% How do I write this funcitonality with semidet, i.e., adding other two clauses?
%% Compiler complains, args must be after --> then {...}
:- mode numX(in(pred(out, in, out) is semidet),  out,     in, out) is semidet.
numX(Pred, [H|T]) -->  call(Pred, H), numX(Pred, T), { T \= [] }.
%numX(Pred, [H])   -->   call(Pred, H).
%numX(_,    [])    -->   [].


% % Use first date, when two dates mentioned.
% %edgar2 543>./edgar2 bentonville ark. feb. 20 2014    wal mart stores inc.  nyse: wmt  today reported financial results for the fourth quarter and fiscal year ended jan. 31
% %DATE february 20 2014

% %edgar2 559>./edgar2 valley forge pa january 23 2014 ¾ amerisourcebergen corporation  nyse:abc  today reported that in its fiscal year 2014 first quarter ended december 31 2013
% %DATE january 23 2014

% %edgar2 559>./edgar2 dallas tx february 6 2014 – alliance data systems corporation  nyse: ads  a leading global provider of data driven marketing and loyalty solutions today announced results for the year ended december 31 2013
% %DATE february 6 2014


% %% (Ret ) -->     means (Ret, In, Out)  -->      implicit last 2 arguments.
:- pred edgarParse(string, list(string), list(string)).
:- mode edgarParse(out,     in, out) is semidet.  % 1 or 0 times; I don't want multiple times
edgarParse(Ret) -->
	zeroOrMore(anyWrd, _), impWrd(Ac), zeroOrMore(anyWrd, _),
	{
	 formattedStr([Ac], Ret)
	}.


% All words assumed to be in lower case, and no punctuation should be attached.
:- pred impWrd(string, list(string), list(string)).
:- mode impWrd(out,     in, out) is semidet.
impWrd("acquires") --> ["acquires"].
impWrd("acquire") --> ["acquire"].
impWrd("agreement") --> ["agreement"].
% impWrd("all") --> ["all"].
% impWrd("and") --> ["and"].
% impWrd("common") --> ["common"].
% impWrd("consecutive") --> ["consecutive"].
% impWrd("declares") --> ["declares"].
% impWrd("dividend") --> ["dividend"].
% impWrd("earnings") --> ["earnings"].
% impWrd("ffo") --> ["ffo"]. % funds from operations
% impWrd("grew") --> ["grew"].
% impWrd("having") --> ["having"].
% impWrd("highest") --> ["highest"].
% impWrd("high") --> ["high"].
% impWrd("income") --> ["income"].
% impWrd("increased") --> ["increased"].
% impWrd("increase") --> ["increase"].
% impWrd("increases") --> ["increases"].
% impWrd("interest") --> ["interest"].
% impWrd("its") --> ["its"].
% impWrd("market") --> ["market"].
% impWrd("minority") --> ["minority"].
% impWrd("quarter") --> ["quarter"].
% impWrd("produce") --> ["produce"].
% impWrd("profit") --> ["profit"].
% impWrd("profits") --> ["profits"].
% impWrd("raises") --> ["raises"].
% impWrd("record") --> ["record"].
% impWrd("records") --> ["records"].
% impWrd("reflect") --> ["reflect"].
% impWrd("revenues") --> ["revenues"].
% impWrd("revenue") --> ["revenue"].
% impWrd("sales") --> ["sales"].
% impWrd("share") --> ["share"].
% impWrd("time") --> ["time"].
% impWrd("to") --> ["to"].
% impWrd("up") --> ["up"].

% impWrd("1") --> ["1"].
% impWrd("2") --> ["2"].
% impWrd("3") --> ["3"].
% impWrd("4") --> ["4"].
% impWrd("5") --> ["5"].
% impWrd("6") --> ["6"].
% impWrd("7") --> ["7"].
% impWrd("8") --> ["8"].
% impWrd("9") --> ["9"].

% impWrd("01") --> ["01"].
% impWrd("02") --> ["02"].
% impWrd("03") --> ["03"].
% impWrd("04") --> ["04"].
% impWrd("05") --> ["05"].
% impWrd("06") --> ["06"].
% impWrd("07") --> ["07"].
% impWrd("08") --> ["08"].
% impWrd("09") --> ["09"].

% impWrd("10") --> ["10"].
% impWrd("11") --> ["11"].
% impWrd("12") --> ["12"].
% impWrd("13") --> ["13"].
% impWrd("14") --> ["14"].
% impWrd("15") --> ["15"].
% impWrd("16") --> ["16"].
% impWrd("17") --> ["17"].
% impWrd("18") --> ["18"].
% impWrd("19") --> ["19"].
% impWrd("20") --> ["20"].
% impWrd("21") --> ["21"].
% impWrd("22") --> ["22"].
% impWrd("23") --> ["23"].
% impWrd("24") --> ["24"].
% impWrd("25") --> ["25"].
% impWrd("26") --> ["26"].
% impWrd("27") --> ["27"].
% impWrd("28") --> ["28"].
% impWrd("29") --> ["29"].
% impWrd("30") --> ["30"].
% impWrd("31") --> ["31"].

% impWrd("jan.") --> ["jan."].
% impWrd("feb.") --> ["feb."].
% impWrd("mar.") --> ["mar."].
% impWrd("apr.") --> ["apr."].
% impWrd("may") --> ["may."].
% impWrd("jun.") --> ["jun."].
% impWrd("jul.") --> ["jul."].
% impWrd("aug.") --> ["aug."].
% impWrd("sept.") --> ["sept."].
% impWrd("oct.") --> ["oct."].
% impWrd("nov.") --> ["nov."].
% impWrd("dec.") --> ["dec."].

% impWrd("january") --> ["january"].
% impWrd("february") --> ["february"].
% impWrd("march") --> ["march"].
% impWrd("april") --> ["april"].
% impWrd("may") --> ["may"].
% impWrd("june") --> ["june"].
% impWrd("july") --> ["july"].
% impWrd("august") --> ["august"].
% impWrd("september") --> ["september"].
% impWrd("october") --> ["october"].
% impWrd("november") --> ["november"].
% impWrd("december") --> ["december"].

% impWrd("2014") --> ["2014"]. % now is 03/28/2014
% impWrd("2013") --> ["2013"]. % too many dates are failing

% %%%%%%%%%%
% :- pred salRvEr(string).
% :- mode salRvEr(out) is multi.
% salRvEr("earnings").
% salRvEr("ffo").
% salRvEr("income").
% salRvEr("profit").
% salRvEr("profits").
% salRvEr("revenue").
% salRvEr("revenues").
% salRvEr("sales").

% :- pred goUp(string).
% :- mode goUp(out) is multi.
% goUp("grew").
% goUp("increased").
% goUp("increases").
% goUp("increase").
% goUp("up").


% :- pred high(string).
% :- mode high(out) is multi.
% high("high").
% high("record").
% high("records").

% :- pred day(string).
% :- mode day(out) is multi.
% day("1").
% day("2").
% day("3").
% day("4").
% day("5").
% day("6").
% day("7").
% day("8").
% day("9").

% day("01").
% day("02").
% day("03").
% day("04").
% day("05").
% day("06").
% day("07").
% day("08").
% day("09").

% day("10").
% day("11").
% day("12").
% day("13").
% day("14").
% day("15").
% day("16").
% day("17").
% day("18").
% day("19").
% day("20").
% day("21").
% day("22").
% day("23").
% day("24").
% day("25").
% day("26").
% day("27").
% day("28").
% day("29").
% day("30").
% day("31").

% :- pred monShrt(string).
% :- mode monShrt(out) is multi.
% monShrt("jan.").
% monShrt("feb.").
% monShrt("mar.").
% monShrt("apr.").
% monShrt("may").
% monShrt("jun.").
% monShrt("jul.").
% monShrt("aug.").
% monShrt("sept.").
% monShrt("oct.").
% monShrt("nov.").
% monShrt("dec.").

% :- pred mon(string).
% :- mode mon(out) is multi.
% mon("january").
% mon("february").
% mon("march").
% mon("april").
% mon("may").
% mon("june").
% mon("july").
% mon("august").
% mon("september").
% mon("october").
% mon("november").
% mon("december").

% :- pred monShrtToLng(string, string).
% :- mode monShrtToLng(in, out) is semidet.
% monShrtToLng("jan.", "january").
% monShrtToLng("feb.", "february").
% monShrtToLng("mar.", "march").
% monShrtToLng("apr.", "april").
% monShrtToLng("may", "may").
% monShrtToLng("jun.", "june").
% monShrtToLng("jul.", "july").
% monShrtToLng("aug.", "august").
% monShrtToLng("sept.", "september").
% monShrtToLng("oct.", "october").
% monShrtToLng("nov.", "novermber").
% monShrtToLng("dec.", "december").

% :- pred monNum(string).
% :- mode monNum(out) is multi.
% monNum("01").
% monNum("02").
% monNum("03").
% monNum("04").
% monNum("05").
% monNum("06").
% monNum("07").
% monNum("08").
% monNum("09").
% monNum("10").
% monNum("11").
% monNum("12").

% :- pred year(string).
% :- mode year(out) is multi.
% year("2014").
% year("2013").

% :- pred conj1(string, list(string), list(string)).
% :- mode conj1(out,     in, out) is nondet.
% conj1(Ret) -->
% 	zeroOrMore(anyWrd, _),
% 	impWrd(Ref), zeroOrMore(anyWrd, _), impWrd(Inc), zeroOrMore(anyWrd, _),
% 	impWrd(Market), impWrd(Share),
% 	{
% 	 Ref="reflect", Inc="increase",
% 	 Market="market", Share= "share",
% 	  formattedStr([ Ref, Inc, Market, Share ], Ret)
% 	}.


% %edgar2 519>./edgar2 we can ride the boat january 29 2014 I love it
% %DATE january 29 2014

% %edgar2 520>./edgar2 we can ride the boat apr. 29 2014
% %DATE april 29 2014

% %edgar2 521>./edgar2 we can ride the boat 03 29 2014
% %DATE 03 29 2014
% edgarParse(Ret) -->
% 	zeroOrMore(anyWrd, _), impWrd(M), impWrd(D), impWrd(Y), zeroOrMore(anyWrd, _),
% 	{
% 	 mon(M), day(D), year(Y),
% 	 formattedStr(["DATE", M, D, Y], Ret)
% 	}.

% edgarParse(Ret) -->
% 	zeroOrMore(anyWrd, _), impWrd(M), impWrd(D), impWrd(Y), zeroOrMore(anyWrd, _),
% 	{
% 	 monShrt(M), day(D), year(Y),
% 	 monShrtToLng(M, Mlg),
% 	 formattedStr(["DATE", Mlg, D, Y], Ret)
% 	}.

% % / replaced by space via my JAVA
% edgarParse(Ret) -->
% 	zeroOrMore(anyWrd, _), impWrd(M),   impWrd(D), impWrd(Y), zeroOrMore(anyWrd, _),
% 	{
% 	 monNum(M),  day(D), year(Y),
% 	 formattedStr(["DATE", M, D, Y], Ret)
% 	}.

% edgarParse(Ret) -->
% 	zeroOrMore(anyWrd, _), impWrd(Decl),   impWrd(Div), zeroOrMore(anyWrd, _),
% 	{
% 	 Decl = "declares", Div = "dividend",
% 	 formattedStr([Decl, Div], Ret)
% 	}.
% edgarParse(Ret) -->
% 	zeroOrMore(anyWrd, _), impWrd(Rais),  impWrd(Com), impWrd(Div), zeroOrMore(anyWrd, _),
% 	{
% 	 Rais = "raises", Com = "common", Div = "dividend",
% 	 formattedStr([Rais, Com, Div], Ret)
% 	}.
% edgarParse(Ret) -->
% 	zeroOrMore(anyWrd, _), impWrd(Incr),  impWrd(Its), impWrd(Div), zeroOrMore(anyWrd, _),
% 	{
% 	 Incr = "increases", Its = "its", Div = "dividend",
% 	 formattedStr([Incr, Its, Div], Ret)
% 	}.

% %% ./edgar2 norman h. asbjornson president and ceo stated the third quarter gains in income and profits from operations primarily reflect an increase in market share as well as price increases and a decline in cost of materials gross profit as a percent of sales
% %%income and profits reflect increase market share

% %%edgar2 558>./edgar2 norman h. asbjornson president and ceo stated the third quarter gains in profits from operations primarily reflect an increase in market share as well as price increases and a decline in cost of materials gross profit as a percent of sales
% %%profits reflect increase market share
% edgarParse(Ret) -->
% 	zeroOrMore(anyWrd, _), impWrd(R1), impWrd(And), impWrd(R2),
% 	conj1(Sen), zeroOrMore(anyWrd, _),
% 	{
% 	 salRvEr(R1), And="and", salRvEr(R2),
% 	 formattedStr([R1, And, R2, Sen], Ret)
% 	}.
% edgarParse(Ret) -->
% 	zeroOrMore(anyWrd, _), impWrd(R1),
% 	conj1(Sen), zeroOrMore(anyWrd, _),
% 	{
% 	 salRvEr(R1),
% 	 formattedStr([R1, Sen], Ret)
% 	}.

% % symbol:  aeee
% % failed: OK fine, not that important
% %./edgar2 the increase in earnings reflected
% % FAIL POSITIVE HERE:
% % 88: ./edgar2 higher electric delivery earnings recognized under formula ratemaking resulting from increased infrastructure investment a higher allowed return on equity due to higher 30-year treasury bond yields and the absence in 2013 of a 2012 contribution
% %earnings increased
% %% We could prohibit     earnings recognized...
% edgarParse(Ret) -->
% 	%%                      revenues in the quarter were $89.7 million up 16.8% from $76.8 million in 2012
% 	zeroOrMore(anyWrd, _), impWrd(R), zeroOrMore(anyWrd, _),  impWrd(U),  zeroOrMore(anyWrd,_), 
% 	{
% 	salRvEr(R),
% 	goUp(U),
% 	  formattedStr([ R, U ], Ret)
% 	}.

% %%%%%%%%%%
% edgarParse(Ret) -->
% 	%%                        consecutive quarter to produce the highest sales 
% 	zeroOrMore(anyWrd, _), impWrd(C), impWrd(Q), zeroOrMore(anyWrd, _),
% 	impWrd(Pro),  zeroOrMore(anyWrd,_),
% 	impWrd(H), xAndY(SaAndProfits),
% 	zeroOrMore(anyWrd, _),
% 	{
% 	 C = "consecutive", Q = "quarter",
% 	 Pro = "produce", H = "highest",
% 	  formattedStr([ C, Q, Pro, H, SaAndProfits ], Ret)
% 	}.


% %%%%%%%%
% %% Cannot combine via conjunction.
% edgarParse(Ret) -->
% 	%% xxxxx xxxxx sales and earnings for the nine months ended september 30 2013 were also all time records
% 	zeroOrMore(anyWrd, _),
% 	impWrd(Sa), impWrd(And), impWrd(Er),
% 	zeroOrMore(anyWrd, _),
% 	impWrd(All), impWrd(Time), impWrd(High),
% 	zeroOrMore(anyWrd, _),
% 	{
% 	 salRvEr(Sa), salRvEr(Er),
% 	 All = "all", Time = "time", high(High),
% 	  formattedStr([ Sa, And, Er, All, Time, High ], Ret)
% 	}.

% edgarParse(Ret) -->
% 	%%earnings for the nine months ended september 30 2013 were also all time records
% 	zeroOrMore(anyWrd, _),
% 	impWrd(Sa), 
% 	zeroOrMore(anyWrd, _),
% 	impWrd(All), impWrd(Time), impWrd(High),
% 	zeroOrMore(anyWrd, _),
% 	{
% 	 salRvEr(Sa),
% 	 All = "all", Time = "time", high(High),
% 	  formattedStr([ Sa, All, Time, High ], Ret)
% 	}.

% %mr. asbjornson said while we are confident of having record sales and profits for 2013 we expect a decline in sales and fairly level profits in the fourth quarter of 2013 compared to an exceptionally strong fourth quarter last year
% edgarParse(Ret) -->
% 	zeroOrMore(anyWrd, _),
% 	impWrd(Having), impWrd(Rec), xAndY(SalesAndProfit),
% 	zeroOrMore(anyWrd, _),
% 	{
% 	 Having="having", Rec="record", 
% 	  formattedStr([ Having, Rec, SalesAndProfit ], Ret)
% 	}.

% %%%% Allow both conjuncts or either one
% :- pred xAndY(string, list(string), list(string)).
% :- mode xAndY(out,     in, out) is nondet.
% xAndY(Ret) -->
% 	 impWrd(Sales), impWrd(And), impWrd(Profit),
% 	 {
% 	  salRvEr(Sales), And="and", salRvEr(Profit),
% 	  formattedStr([ Sales, And, Profit ], Ret)
% 	  }.
% xAndY(Ret) -->
% 	 impWrd(Profit),
% 	 {
% 	  salRvEr(Profit),
% 	  formattedStr([ Profit ], Ret)
% 	  }.


%%%%%%% ENVIRONMENT
% edgar2a 470>which mmc
% /usr/local/mercury-14.01/bin/mmc
% edgar2a 469>

% edgar2a 471>gcc --version
% Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
% Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
% Target: x86_64-apple-darwin13.1.0
% Thread model: posix
