% used for EC_rule generalization: cover()<50


:-use_module(library(ordsets)).
%:-['testInput'].



set(evDepth,7).

/*********************Inconsistent Check ************************/
% T is discarded once cover one negative example
coverNeg(NegList):-
	member(NegEI,NegList),
	ex(NegEI,E,0), %%write('one Negative example'),%write(NegEI),
	set(evDepth,DepthLimit),
	depth_bound_call(user:E, DepthLimit).


	

/*********************Integrity Constraint ************************/


/***************Count Coverage (RELATIVE) *********/
% only check those from check list
unCoverRecord([],[]).
unCoverRecord([Index|CheckList],NUnCoverList):-
	%write('%%%%% covering'),%write(Index),
	(integer(Index)->
		ex(Index,E,PosNegSign),
		((set(etoB,yes),PosNegSign==1)->
			retract(ex(Index,E,PosNegSign));
			Flag=0	% Flag is for later added
		);  % not necessarily positive -- used for count FalseNeg
		E=Index
	),
	%%write(E),

	%%write('%%%%% covering'),
	set(evDepth,DepthLimit),
	%%write('%%%%% covering'),

	(depth_bound_call(user:E, DepthLimit)->
		NUnCoverList=UnCoverList;
		NUnCoverList=[Index|UnCoverList]
	),
	(Flag==0 ->	
		Foo2=1;	% do nothing
		assert(ex(Index,E,PosNegSign))
	),
	%%write('%%%%% finish this example'),nl,
	unCoverRecord(CheckList,UnCoverList).



/***************SCORE ********************/
% Sequentially compute each T: add T, score it, remove T0

tCompScore([],0).
tCompScore([ClaI|T],NTScore):-
	tCompScore(T,TScore), 
	claInterpreter(ClaI,Cla),
	length(Cla,HL),
	NTScore is TScore+HL.


% score = TComplex+NumUnCover(Overall)
% {PreSocre,PreUnCover,T}	
% {Score,UnCover,NewTSoFar,T}
scoreTs(PosList,NegList,TSoFar,[],[]).
scoreTs(PosList,NegList,TSoFar,[T|Ts],NScoredTs):-

	scoreTs(PosList,NegList,TSoFar,Ts,ScoredTs),

	%write('^^^Start scoring this T: Clause under inspection'), %write(T),	nl,
	addTI(TSoFar,[],RefTSoFar),%write('TSoFar'),%write(TSoFar),%write('&&&'),
	addTI(T,RefTSoFar,RefAllT),%write('???Problem here'),%write(RefAllT),nl,
	
	%nl,nl,%write(TSoFar), %write('ADDing '), %%print_list(T),nl,listing,
	
	
	((coverNeg(NegList);once(integrityConstraint))->	% expensive to check redundancy, so remove as much as possible at this stage
		%write('---inconsistent---'),nl,
		removeRefT(RefAllT,UselessT),
		NScoredTs=ScoredTs;

		%write('----Fine'),nl,
		%write('$$$$Check Redundant'),
		removeRedundant(RefAllT,NewRefAllT),
		%write('$$$$Finish'),nl,
		unCoverRecord(PosList,UnCover), %write('for this example'),%write(UnCover),nl,
		length(UnCover,K),

		removeRefT(NewRefAllT,NewAllT),
		tCompScore(NewAllT,TComplex),
		
		Score is TComplex+K,

		NScoredTs=[{Score,UnCover,NewAllT,T}|ScoredTs], % T itself is useless in the next gene--but to debug increamental
		write('')%write('Finish this score'),%write({Score,UnCover,NewAllT,T}),nl

	).
	%%write('^^^ finish'),%write({Score,UnCover,NewAllT,T}),nl.

	

/*************** START *******************/

% AllPEs initial set of PE (sampled for training--different from that for GenEList-include that not in AllPE)
assembleHs(AllPEs,[],[]).
assembleHs(AllPEs,[_-{T,GenEList}|Ts],[{Score,UnCover,[],T}|NewTs]):-
	assembleHs(AllPEs,Ts,NewTs),
	ord_subtract(AllPEs,GenEList,UnCover).

noGenAssemble(AllPEs,[],[]).
noGenAssemble(AllPEs,[{_,T}|Ts],[{Score,AllPEs,[],T}|NewTs]):-
	noGenAssemble(AllPEs,Ts,NewTs).

%set(depthLimit,DepthLimit):-numMap(20,DepthLimit).	

cover([],_,FinalT,FinalT). % All Cover
cover(EIs,_,FinalT,FinalT):-
	length(EIs, RemainedNum),RemainedNum < 50,!. % only 100 remained
cover([EI|UnCover],NegList,TSoFar,FinalT):-
	set(depthLimit,DepthLimit),
	singleE(DepthLimit,EI,Ts),
	%nl,keggMapping(EI,KeggRID),%write(KeggRID),%write('*********Hypothesis for this example is '), %write(Ts),nl,%length(Ts,K),%write(K),nl,
	%%write('@@@@@@@Input for evaluation'), %write(UnCover),nl,%write(NegList),nl,nl,
	%%write('__________Start Scoring'),nl,
	evOneGen(Ts,TSoFar,UnCover,NegList,{NUnCover,NewTSoFar}),
	%write('--- Those remain uncover are'), %write(NUnCover),nl,maplist(keggMapping,NUnCover,RIDs),%write(RIDs),nl,
	%maplist(%writeReaction,RIDs),
	%%write('T So Far are : '), nl,%print_list(NewTSoFar),nl,%listing,nl,
	%%write('finish this one eGen evaluation, and '), 
	%length([EIndex|UnCover],Num),
	%length(NUnCover,NNum),
	%NewCoveredNum is Num-NNum, %write(NewCoveredNum),
	%%write(' more are covered, while remain uncover is: '),
	%%write(NUnCover),nl,
	%%write(NewTSoFar),nl,
	
	cover(NUnCover,NegList,NewTSoFar,FinalT).


keggMapping(EI,KeggRID):-
	ex(EI,E,PosNegSign),
	E=reactionClass(RID,_),concept_accession(RID,'KEGG',KeggRID,false).


outputList([],[]).
outputList([X|Rest],[X|Rest]):-
	set(depthLimit,DepthLimit),
	%write(X),%write('~~~~~~!!!!!!!!'),
	outputList(Rest,Rest).
	

% no worry about cover uncover--PosList
evOneGen(Ts,TSoFar,PosList,NegList,{UnCovered,NewTSoFar}):-
	scoreTs(PosList,NegList,TSoFar,Ts,ScoredTs),%write('^&^&^&^& finish scoring'),nl,

	%sort(ScoredTs,[{Min,UnCovered,NewTSoFar,BestT}|RestTs]),
	%%write('best for this examples is '),nl,%write({Min,UnCovered,NewTSoFar,BestT}),
	%%write('?2'),
	sort(ScoredTs,SortedTs),%write('?1'),write(SortedTs),

	SortedTs=[{Score,UnCovered,NewTSoFar,ChosenT}|Rest],%write({Score,UnCovered,NewTSoFar,ChosenT}),nl,
	%minSets(SortedTs,MinSet),
	%first5(SortedTs,MinSet),
	%print_list(MinSet),
	%print_list([{Score,UnCovered,NewTSoFar,ChosenT}|Rest]),
	%member({Score,UnCovered,NewTSoFar,ChosenT},SortedTs),

	%addT(NewTSoFar,TRef),
	%%print_list([{Min,UnCovered,NewTSoFar,BestT}|RestTs]),
nl.

first5([A,B,C,D,E|R],[A,B,C,D,E]).
minSets([{Min,UnCovered,NewTSoFar,ChosenT}|Lists],[{Min,UnCovered,NewTSoFar,ChosenT}|Same]):-
	(once(append(Same,[{Score1,UnCovered1,NewTSoFar1,ChosenT1}|ListB],Lists),Score1\==Min),!;Same=[]). % find the first one that is not the same as Min
	


%        format("Here0~n",[]),
%coverTest(EI):-
c:-
	%write('abc start greedy search now'),

        statistics(cputime,[Total1,Previous]),

	tell('ec1_March_4.txt'),
	numbersList(1,483,PosEIs),
	NegEIs=[],

	%tell('odd.txt'),
	%cover([EI|[2,3,4,5,6,7,8]],[9,10,11,12,13,14,15,16],[],FinalT), % both even and odd
	%cover([EI|[4,6,8]],[9,10,11,12,13,14,15,16],[],FinalT), % both even and odd
	%cover([EI|[4,6,8]],[9,11,13,15],[],FinalT),	% only odd

	%

	%tell('inoue.txt'),
	%PosEIs=[1,2,3],NegEIs=[],

	%tell('metaLogAbduction.txt'),
	%numbersList(1,20,PosEIs),
	%PosEIs=[1,2,3,4,5,6,8,9,10,11,13,12,14,15,16,17,18,19,20],

	/*tell('animal.txt'),
	%numbersList(1,16,PosEIs),
	PosEIs=[1,2,3,4,5,6,7,8,9,10,11,13,12,14,15,16],
	numbersList(17,58,NegEIs),*/

	%tell('grammar.txt'),
	%numbersList(1,40,PosEIs0),
	%permutation(PosEIs0,PosEIs),
	%PosEIs=[1,19],
	%PosEIs=[21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,1,2,3,4,5,6,8,9,10,11,13,12,14,15,16,17,18,19,20],
	%numbersList(41,48,NegEIs),

	%tell('odd_even.txt'),
	%PosEIs=[19,5,7,11,1],NegEIs=[2,6,8,12,20],
	%PosEIs=[1,3,5,7,9,11,13,15,17,19],NegEIs=[2,4,6,8,10,12,14,16,18,20],

	cover(PosEIs,NegEIs,[],FinalTI), 

	statistics(cputime,[Total2,Now]),
	TimeTaken is Now-Previous,
	%write('Final Learning Result'),nl,
	tInterpreter(FinalTI,FinalT),
	%print_list(FinalT),

	%write('Total Time Taken is '), %write(TimeTaken),
	nl.%told.


% change that in evOneGen (from choosing only head to one of (member))
all:-	
	%write('Find all possible HYPOTHESES'),
statistics(cputime,[Total1,Previous]),
	
	%tell('ec1.txt'),
	%numbersList(1,483,EIs),
	%cover(EIs,[],[],FinalT),

	%tell('odd.txt'),
	%cover([EI|[2,3,4,5,6,7,8]],[9,10,11,12,13,14,15,16],[],FinalT), % both even and odd
	%cover([EI|[4,6,8]],[9,10,11,12,13,14,15,16],[],FinalT), % both even and odd
	%cover([EI|[4,6,8]],[9,11,13,15],[],FinalT),	% only odd

	%

	tell('inoueAll.txt'),
	PosEIs=[1,2,3],NegEIs=[],
	

	%tell('metaLogAbduction.txt'),
	%numbersList(1,20,PosEIs),
	%PosEIs=[1,2,3,4,5,6,8,9,10,11,13,12,14,15,16,17,18,19,20],

	/*tell('animal.txt'),
	%numbersList(1,16,PosEIs),
	PosEIs=[1,2,3,4,5,6,7,8,9,10,11,13,12,14,15,16],
	numbersList(17,58,NegEIs),*/

	%tell('grammar.txt'),
	%numbersList(1,26,PosEIs),
	%numbersList(27,33,NegEIs),


	findall(FinalTI,
(cover(PosEIs,NegEIs,[],FinalTI),
nl%tInterpreter(FinalTI,FinalT)
),
	AllPossibilities),

length(AllPossibilities,AllNum),%write(AllNum),


statistics(cputime,[Total2,Now]),
	TimeTaken is Now-Previous,
	%write('All Learning Result'),nl,
	%writeTheories(AllPossibilities),

	%write('Total Time Taken is '), %write(TimeTaken),
	told.



