:- load_files([flags,io,sets,wme,about,abcde],
			  [silent(true),if(not_loaded)]).

about(wme,
		(Relation,K,All,N,Other,OT,Data),
		[relation=Relation,n=N,other=Other,otherTotal=OT,
         all=All,klass=K,data=Data],
	    wme(Relation,N,Data,All,Other,K,OT),
	    wme(Relation,N,Data,All,Other,K,OT)
).

portray(wme(Relation,N,Data,All,Ohter,K,OT)) :-
	length(Data,M),
	write(wme(Relation,N,data/M,All,Ohter,K,OT)).

wme_(klasses,Ks,wme(_,_,D,_,_,_,_)) :- maplist(arg(1),D,Ks).
wme_(klass,  K, W)                  :- wme_(klasses,Ks,W), member(K,Ks).
wme_(data,D,   wme(_,_,D,_,_,_,_)).
wme_(independent,I=Details,W) :- wme_(data,D,W),
	member(I=Details,D),
	\+ dependent(I,_).

wme_(independentRange,Range * Variable=Instances,W) :-
	wme_(independent,Variable=Ranges,W),
	member(Range=Instances,Ranges).
	
all($all).

wmeData(Name,File,W0) :-
	retractall(relation(_,_,_,_)),
	[File],
	relation(Name,_,_,_),
	w(Name,Data),
	append(Others,[+Klass=Klasses],Data),
	member(+Other=Stuff2Sum,Others),
	sumThisStuff(Stuff2Sum,0,OtherTotal),
	wmeData1(Klasses,All,0,N),
	about(wme,(Name,Klass,All,N,Other,OtherTotal,Data),_,_,W0).

sumThisStuff([],N0,N) :- N is N0.
sumThisStuff([A=B|T],N0,N) :-
	length(B,L),
	sumThisStuff(T,N0+L*A,N).

wmeData1([],[],N0,N) :- N is N0.
wmeData1([A=B|T0],[A=N1|T],N0,N) :- 
	length(B,N1),
	wmeData1(T0,T,N0+N1,N).

wme2abcde(Target,wme(_,N,_,All,Other,Klass,E),ABDCE) :-
	member(Target=BD,All),	
	AC is N - BD,
    about(abcde,(Klass,Target, Other,E, AC,BD),_,_,ABDCE).

w(Name,W) :-
	retractall(memo(_,_,_)),
	good(relation(Name,Attrs,Scores,Data)),
	wme0(Attrs,W0),
	rows(Data,Scores,1,W0,W).

good(relation(Name,Attrs,Scores,Data)) :-
	relation(Name,Attrs,Scores,Data)
    -> (ground(relation(Name,Attrs,Scores,Data)) 
        -> true
        ;  error(not(ground(relation)))
       ),
	   \+ (nth1(N,Data,Datum),  
	       bad(Scores,Attrs,Datum,Because), 
           warning(row(N,Because))
          )
     ; warning(missing(relation(Name/4))).

bad(Scores,_,Datum,bad(Klass)) :- 
	last(Datum,Klass), 
	\+ number(Klass), 
	\+ member(Klass= _,Scores).
bad(_,Attrs,Datum, wrong(size(N))) :- 
	length(Datum,N),
	\+ length(Attrs,N).
	
wme0(L0,L) :- maplist(wme0a,L0,L).
wme0a(X,X=[]).

% for rows in relation do
rows([]        ,_     ,_,W, W).
rows([Row|Rows],Scores,N,W0,W) :- 
	row(Row,N,W0,W1), 
	N1 is N + 1, 
	rows(Rows,Scores,N1,W1,W).

% for cells in row do
row([],_,[],[]).
row([Input|Inputs],Row,[Attr=About0|W0],[Attr=About|W]) :-
	cell(Input,Attr,Row,About0,About),
	row(Inputs,Row,W0,W).

% for one cell do
cell(Value,_    ,_  ,About, About) :- dunno(Value),!.
cell(Value,Attr ,Row,About0,About) :- 
	forall(dependent(Attr,Attr1),assert(memo(Row,Attr1,Value))),
	@(Value,Old,[Row|Old],[],About0,About).		

dunno(?).
dependent(+ X,X).


