/* define characteristic examples
(1) contain all types of paris
(2) does the triple count? for example although same types of pairs, but different triples
abab
aabb 

s->empty
s-> asb
s-> bsa
s->a
s->b

abab
aabb

aab
abb

ab
ba
aa
bb

ababbb {ab}{ba}{bb}
abbbba	
*/

% negative examples are put at the end, since they are just to made sure that it is not too general,
reorder_examples(PosEIs0,PosEIs,NegEIs0,NegEIs):-
	% positive examples are re-ordered by their lengths
	maplist(assign_lengthLabel,PosEIs0,LengthLabeledPosEIs),
	sort(LengthLabeledPosEIs,SortedLengthLabeledPosEIs),
	maplist(removeLengthLabel_addProveSign,SortedLengthLabeledPosEIs,PosEIs),

	% negatives are re-ordered by their lengths
	maplist(assign_lengthLabel,NegEIs0,LengthLabeledNegEIs),
	sort(LengthLabeledNegEIs,SortedLengthLabeledNegEIs),
	maplist(removeLengthLabel_addProveSign,SortedLengthLabeledNegEIs,NegEIs).

	
assign_lengthLabel(EI,Length-EI):-
	ex(EI,parse(Seq),PosNegSign),
	length(Seq,Length).
removeLengthLabel_addProveSign(Length-EI,EI).


% assign_labels([NumPairs-AllPairs-(-SeqLength)-EI],[GroupSign-InductiveSign-SeqLength-EI])
assign_labels(AllPairs-FinalGroupSign,[],[]).
	
assign_labels(PreTotalPairs-PreGroupSign,[NumPairs-SeqLength-AllPairs-EI|PairsEIs],[GroupSign-InductiveSign-SeqLength-EI|LabelledEIs]):-	
	(ord_subset(AllPairs,PreTotalPairs) ->
		GroupSign=PreGroupSign,
		InductiveSign=1,
		TotalPairs=PreTotalPairs;
		GroupSign is PreGroupSign+1,
		InductiveSign=0,
		ord_union(AllPairs,PreTotalPairs,TotalPairs)
	),
	assign_labels(TotalPairs-GroupSign,PairsEIs,LabelledEIs).


remove_label(GroupSign-InductiveSign-SeqLength-EI,InductiveSign-EI).

/* Tail Recursion
% assign_labels([NumPairs-AllPairs-(-SeqLength)-EI],[GroupSign-InductiveSign-SeqLength-EI])
assign_labels(AllPairs-0,[NumPairs-(-SeqLength)-AllPairs-EI],[0-0-SeqLength-EI]).
	
assign_labels(TotalPairs-GroupSign,[NumPairs-(-SeqLength)-AllPairs-EI|PairsEIs],[GroupSign-InductiveSign-SeqLength-EI|LabelledEIs]):-
	assign_labels(PreTotalPairs-PreGroupSign,PairsEIs,LabelledEIs),
	(ord_subset(AllPairs,PreTotalPairs) ->
		GroupSign=PreGroupSign,
		InductiveSign=1,
		TotalPairs=PreTotalPairs;
		GroupSign is PreGroupSign+1,
		InductiveSign=0,
		ord_union(AllPairs,PreTotalPairs,TotalPairs)
	). */



% minus sequence so that the shorter one is orderd later; while once the group sign is given 
get_allPairs(EI,NumPairsSign-SeqLength-AllPairs-EI):-
	ex(EI,parse(Seq),PosNegSign),
	get_allPairs0(Seq,AllPairs),
	(set(grammar_type,regularOnly) ->
		AllTriples=[];
		get_allTriples0(Seq,AllTriples)
	),
	append(AllPairs,AllTriples,AllVarieties),
	length(AllVarieties,NumPairs),NumPairsSign is 0-NumPairs,
	length(Seq,SeqLength).


get_allPairs0([Ele],[{Ele}]).
get_allPairs0(Seq,AllPairs):-
	setof({X,Y},Pre^Post^append(Pre,[X,Y|Post],Seq),AllPairs).
get_allTriples0([Ele],[{Ele}]).
get_allTriples0([Ele1,Ele2],[{Ele1,Ele2}]).
get_allTriples0(Seq,AllPairs):-
	setof({X,Y,Z},Pre^Post^append(Pre,[X,Y,Z|Post],Seq),AllPairs).


% put in groups, -- if same pairs, then shortest first
% connect together.


% get_allPairs
% get_alltypes and assign the group sign 
% sortby the big group, while within the group, deductive sign--> sign by 1 and 0; shorter length.