//	Find all the political parties ...

allParty;
// [Fel,Val,Ind,SDP,WRP,Com,Con,NF,E,Gre,Lab,Lib]


//	Find the total number of wards ...

$ allWard;
// 36


//	Find all the details of all the wards in Eltham ...

|ward_details (Any,Any,Any,Eltham);
// [(W3,Avery_Hill,1,Eltham),(W7,Coldharbour,2,Eltham),(W8,Deansfield,1,Eltham), ...


//	Find all the details of ward 20 in Eltham ...

|ward_details (W20,Any,Any,Eltham);
// [(W20,Palace,1,Eltham)]


//	Find the total votes for the Conservatives in 1978 ...

sum [v | (w,1978,c,Con,v) <- |ward_results (Any,1978,Any,Con,Any)];
// 50419


//	Define a function `total_votes' which does this for given years, wards and parties ...

_define total_votes (y,w,p) ==	sum [v | (w,y,c,p,v) <- |ward_results (w,y,Any,p,Any)];
// `total_votes' now has type `(Num,Ward,Party)->Num'


//	Use `total_votes' to find out:
//		(i)	the no. of conservative votes in W20 in 1978
//		(ii)	the total no. of votes in W20 in 1978
//		(iii)	the total no. of votes in all wards in 1978


 total_votes (1978,W20,Con);
// 882
 total_votes (1978,W20,Any);
// 1514
 total_votes (1978,Any,Any);
// 119803


//	Define functions which when given a year, ward and party return:
//		(i)	the no. of candidates for the party in the ward;
//		(ii)	the percentage of the total no. of votes in the
//			ward obtained by the party
//		(iii)	the ratio of the total no. of votes for the party
//			in the ward to the total no. of votes for the 
//			conservative party in the ward

_define total_cands (y,w,p) ==	$ (|ward_results (w,y,Any,p,Any));
_define percentage (y,w,p)	==	(total_votes (y,w,p) * 100) / (total_votes (y,w,Any));
_define ratio (y,w,p)	==	(total_votes (y,w,p)) / (total_votes (y,w,Con));

//	Construct a list of (w,p) pairs such that w is a ward and p is the
//	percentage of the votes obtained by labour in w in 1982:

[(w,percentage (1982,w,Lab)) | w <- allWard];
// [(W1,39.3309),(W10,47.2172),(W11,45.5262),(W12,61.903), ...


//	Construct a list of (w,r) pairs such that w is a ward and r is the 
//	ratio of labour votes to conservative votes in w in 1982:
//	(Later, try the same query for 1978!)

[(w,ratio (1982,w,Lab)) | w <- allWard];
// [(W1,1.61474),(W10,2.45491),(W11,1.60835),(W12,3.60486), ...


//	Write queries to give the Labour results for 1982 in increasing order of:
//		(i)	percentage of the vote in the ward
//		(ii)	ratio to conservative votes in the ward
//	(Hint: investigate the xsort2 and proj_m_n functions)
//	Then write queries to find the best 10 Labour results based upon:
//		(iii)	percentage of the vote in the ward
//		(iv)	ratio to conservative votes in the ward
//	(Hint: investigate the use of `take' and `reverse'!)

msort2 proj_2_2 [(w,percentage (1982,w,Lab)) | w <- allWard];
// [(W18,17.7206),(W9,19.4423),(W4,19.6771),(W27,19.7889), ...

msort2 proj_2_2 [(w,ratio (1982,w,Lab)) | w <- allWard];
// [(W18,0.299208),(W9,0.361205),(W30,0.367424),(W20,0.379571), ...

take 10 (reverse (msort2 proj_2_2 [(w,percentage (1982,w,Lab)) | w <- allWard]));
// [(W2,67.2613),(W19,62.395),(W5,61.9266),(W12,61.903),(W24,59.2262), ...

take 10 (reverse (msort2 proj_2_2 [(w,ratio (1982,w,Lab)) | w <- allWard]));
// [(W2,6.10476),(W19,4.4),(W5,4.35484),(W24,3.67008),(W12,3.60486), ...


//	Write a query to give a list of pairs (c,w) such that c is a candidate
//	who has stood in a ward w for two or more parties:

[(c,w) |	w <- allWard; y1 <- |election Any; y2 <- |election Any; y1 < y2;
		(w,y1,c,p1,v1) <- |ward_results (w,y1,Any,Any,Any);
		(w,y2,c,p2,v2) <- |ward_results (w,y2,c,Any,Any);
		p1 != p2];
// [(Mallone_R_S,W15),(Mallone_R_S,W15),(Mallone_R_S,W15),(Fay_C,W33),...]


//	Define a function `no_seats' which gives the number of seats for a given ward:

_define no_seats w ==	head [s | (w,n,s,c) <- |ward_details (w,Any,Any,Any)];

//	Find all the results for the national front:

|ward_results (Any,Any,Any,NF,Any);
// [(W25,1978,Hepden_A,NF,71),(W7,1978,Bristo_L,NF,77), ...


//	Define a function `order_res' which sorts a given list of ward
//	results into descending order of votes received:
//	(Hint: use xsort2 and proj_m_n again!)

_define order_res x ==	reverse (msort2 proj_5_5 x);

//	Find the all-time top three results for the national front:

take 3 (order_res (|ward_results (Any,Any,Any,NF,Any)));
// [(W15,1978,Powell_E,NF,121),(W11,1978,Lovell_W_J,NF,113),(W28,1978,Ross_J_J,NF,100)]


//	Define `winners' which finds the winners of a ward for a given year:

_define winners (w,y) ==	take (no_seats w) (order_res (|ward_results (w,y,Any,Any,Any)));

//	Give a list abstraction to determine whether anyone has ever 
//	won the same ward for two different parties:

[(c1,w,p1,p2) |	w <- allWard; y1 <- |election Any; y2 <- |election Any; y1 < y2;
		(w,y1,c1,p1,v1) <- winners (w,y1);
		(w,y2,c2,p2,v2) <- winners (w,y2);
		p1 != p2; c1 = c2];
// []

//	Finally, and only for the very very keen, determine whether anyone 
//	has ever won two different wards in consecutive years

[(c1,w1,w2) |	(y1,y2)  <- zip (|election Any) (tail (|election Any));
			w1 <- allWard; w2 <- allWard; w1 != w2;
			(w1,y1,c1,p1,v1) <- winners (w1,y1);
			(w2,y2,c2,p2,v2) <- winners (w2,y2);
			c1 = c2];
// [(Kingwell_M_I,W16,W28),(Kear_K_L,W34,W9),(Graham_P,W36,W10),^C<<task aborted>>

