:- seqex([plausible/2, plausible1/2, printTree/4, between/3, pick/4, 
	  writeSpaces/1, seqStrategy/3, seqSbps/7]).

/* strategy(Coins, Weighings, DecisionTree) :- write([Weighings,Coins]), nl, 
					    2 =:= 3.  */
seqStrategy(coins(Normal, PossiblyHeavy, PossiblyLight, UnKnown), W, s) :-
	Total is  PossiblyHeavy+ PossiblyLight+ UnKnown, 
	Total < 2.

seqStrategy(coins(Normal, PossiblyHeavy, PossiblyLight, UnKnown), 
	 Weighings, t(weigh(Left,Right), eq(Teq), 	
			    leftHeavy(TLeft), rightHeavy(TRight))) :-
	Total is  PossiblyHeavy+ PossiblyLight+ UnKnown, 
	Total > 1,
	plausible(Weighings, coins(Normal, PossiblyHeavy, PossiblyLight, UnKnown)),
	Weighings > 0,
	MaxSize is (Normal+  PossiblyHeavy+ PossiblyLight+ UnKnown ) / 2,
	between(1,MaxSize, Size),
	Left = coins(0, H1, L1, U1), 
	pick(Size, coins(Normal, PossiblyHeavy, PossiblyLight, UnKnown),
		Left, Coins2),
	Right = coins(N2, H2, L2, U2),
	CoinsUnWeighed = coins(N3, H3, L3, U3),
	pick(Size, Coins2, Right, CoinsUnWeighed),

/* Now, you have to solve three subproblems for each of the 3 possible outcomes */
	Weighings1 is Weighings -1,
/* Check the plausibility of all the three subproblems before calling them */

  /* If the pans are Equal, All weighed coins are normal. Suspect in remainder. */

	N4 is Normal + H1+L1+U1 + H2+L2+U2,
	ProbEq = coins(N4, H3, L3, U3),
	plausible(Weighings1, ProbEq),
 /* If the Left pan was light, the UnWeighed ones are normal.
	The possibly_heavy on left and possibly_light on right are normal, But
	possibly_heavy on right and possibly_light on left are still suspect,
	and the unknowns on each side are possibly heavy/light */

	N5 is Normal 	+ H3+L3+U3 /* Unweighed */ + H1 + L2,
	H5 is H2 + U2,
	L5 is L1 + U1,
	U5 is UnKnown - (U1+U2+U3), /* i.e. 0 */
	ProbLeft = coins(N5, H5, L5, U5),
	plausible(Weighings1, ProbLeft),

 /* If the Right pan was light, the UnWeighed ones are normal.
	The possibly_heavy on right and possibly_light on left are normal, But
	The possibly_heavy on left and possibly_light on right are still suspect,
	and the unknowns on each side are possibly heavy/light */

	N6 is Normal 	+ H3+L3+U3 /* Unweighed */ + H2 + L1,
	H6 is H1 + U1,
	L6 is L2 + U2,
	U6 is UnKnown - (U1+U2+U3), /* i.e. 0 */
	ProbRight = coins(N6, H6, L6, U6),
	plausible(Weighings1, ProbRight),
	Teq = t(weigh(ELeft,ERight),eq(ETeq),leftHeavy(ETLeft),rightHeavy(ETRight)),
        TLeft =  t(weigh(LLeft,LRight),eq(LTeq),leftHeavy(LTLeft),rightHeavy(LTRight)),
	TRight = t(weigh(RLeft,RRight),eq(RTeq),leftHeavy(RTLeft),rightHeavy(RTRight)),
	seqSbps(Weighings1,coins(N4,H3,L3,U3), coins(N5,H5,L5,U5), 
			   coins(N6,H6,L6,U6), Teq, TLeft, TRight).


strategy(C, W, T) :- W < 2, seqStrategy(C,W,T).

strategy(coins(Normal, PossiblyHeavy, PossiblyLight, UnKnown), W, s) :-
	write(instrat(coins(Normal, PossiblyHeavy, PossiblyLight, UnKnown), W)), nl,
	Total is  PossiblyHeavy+ PossiblyLight+ UnKnown, 
	Total < 2.

strategy(coins(Normal, PossiblyHeavy, PossiblyLight, UnKnown), 
	 Weighings, t(weigh(Left,Right), eq(Teq), 	
			    leftHeavy(TLeft), rightHeavy(TRight))) :-
/*	write(instrat2(Weighings)), nl,*/
	Weighings > 1,
	Total is  PossiblyHeavy+ PossiblyLight+ UnKnown, 
	Total > 1,
/*	write(Total), nl,*/
	plausible(Weighings, coins(Normal, PossiblyHeavy, PossiblyLight, UnKnown)),
	MaxSize is (Normal+  PossiblyHeavy+ PossiblyLight+ UnKnown ) / 2,
	between(1,MaxSize, Size),
	Left = coins(0, H1, L1, U1),
	pick(Size, coins(Normal, PossiblyHeavy, PossiblyLight, UnKnown),
		   coins(0,H1,L1,U1), Coins2),
	pick(Size, Coins2, coins(N2,H2,L2,U2), coins(N3,H3,L3,U3)),
	Right = coins(N2, H2, L2, U2),
	CoinsUnWeighed = coins(N3, H3, L3, U3),

/* Now, you have to solve three subproblems for each of the 3 possible outcomes */
	Weighings1 is Weighings -1,
/* Check the plausibility of all the three subproblems before calling them */

  /* If the pans are Equal, All weighed coins are normal. Suspect in remainder. */

	N4 is Normal + H1+L1+U1 + H2+L2+U2,
	ProbEq = coins(N4, H3, L3, U3),
	plausible(Weighings1, coins(N4,H3,L3,U3)),
 /* If the Left pan was light, the UnWeighed ones are normal.
	The possibly_heavy on left and possibly_light on right are normal, But
	possibly_heavy on right and possibly_light on left are still suspect,
	and the unknowns on each side are possibly heavy/light */

	N5 is Normal 	+ H3+L3+U3 /* Unweighed */ + H1 + L2,
	H5 is H2 + U2,
	L5 is L1 + U1,
	U5 is UnKnown - (U1+U2+U3), /* i.e. 0 */
	ProbLeft = coins(N5, H5, L5, U5),
	plausible(Weighings1, coins(N5,H5,L5,U5)),

 /* If the Right pan was light, the UnWeighed ones are normal.
	The possibly_heavy on right and possibly_light on left are normal, But
	The possibly_heavy on left and possibly_light on right are still suspect,
	and the unknowns on each side are possibly heavy/light */

	N6 is Normal 	+ H3+L3+U3 /* Unweighed */ + H2 + L1,
	H6 is H1 + U1,
	L6 is L2 + U2,
	U6 is UnKnown - (U1+U2+U3), /* i.e. 0 */
	ProbRight = coins(N6, H6, L6, U6),
	plausible(Weighings1, coins(N6,H6,L6,U6)),
	Teq = t(weigh(ELeft,ERight),eq(ETeq),leftHeavy(ETLeft),rightHeavy(ETRight)),
        TLeft =  t(weigh(LLeft,LRight),eq(LTeq),leftHeavy(LTLeft),rightHeavy(LTRight)),
	TRight = t(weigh(RLeft,RRight),eq(RTeq),leftHeavy(RTLeft),rightHeavy(RTRight)),
	sbps(Weighings1,coins(N4,H3,L3,U3), coins(N5,H5,L5,U5), 
		        coins(N6,H6,L6,U6), Teq, TLeft, TRight).

 
seqSbps(Weighings1,coins(A1,B1,C1,D1), coins(A2,B2,C2,D2), coins(A3,B3,C3,D3),
      t(weigh(ELeft,ERight),eq(ETeq),leftHeavy(ETLeft),rightHeavy(ETRight)),
      t(weigh(LLeft,LRight),eq(LTeq),leftHeavy(LTLeft),rightHeavy(LTRight)),
      t(weigh(RLeft,RRight),eq(RTeq),leftHeavy(RTLeft),rightHeavy(RTRight)))
   :-
      seqStrategy(coins(A1,B1,C1,D1), Weighings1, 
	t(weigh(ELeft,ERight),eq(ETeq),leftHeavy(ETLeft),rightHeavy(ETRight))),
      seqStrategy(coins(A2,B2,C2,D2), Weighings1, 
        t(weigh(LLeft,LRight),eq(LTeq),leftHeavy(LTLeft),rightHeavy(LTRight))),
      seqStrategy(coins(A3,B3,C3,D3), Weighings1, 
        t(weigh(RLeft,RRight),eq(RTeq),leftHeavy(RTLeft),rightHeavy(RTRight))).

sbps(Weighings1,coins(A1,B1,C1,D1), coins(A2,B2,C2,D2), coins(A3,B3,C3,D3), Teq, TLeft, TRight) :-
	 strategy(coins(A1,B1,C1,D1), Weighings1, Teq) //
	 sbps1(coins(A2,B2,C2,D2), coins(A3,B3,C3,D3),Weighings1,TLeft,TRight).
	
sbps1(coins(A2,B2,C2,D2), coins(A3,B3,C3,D3),Weighings1,TLeft,TRight) :-
	 strategy(coins(A2,B2,C2,D2), Weighings1, TLeft) //
	 strategy(coins(A3,B3,C3,D3), Weighings1, TRight),
	write(yessss3), nl.

/*
sbps(Weighings1,coins(A1,B1,C1,D1), coins(A2,B2,C2,D2), coins(A3,B3,C3,D3), Teq, TLeft, TRight) :-
	strategy(coins(A1,B1,C1,D1), Weighings1, Teq),
	strategy(coins(A2,B2,C2,D2), Weighings1, TLeft),
	strategy(coins(A3,B3,C3,D3), Weighings1, TRight).
*/



between(M,N,M) :- N >= M.
between(M,N,X) :- N>M, M1 is M+1, between(M1,N,X).

/*
between(0,M,0).
between(0,M,1) :- 1 =< M.
between(0,M,2) :- 2 =< M.
between(0,M,3) :- 3 =< M.
between(0,M,4) :- 4 =< M.
between(0,M,5) :- 5 =< M.
between(0,M,6) :- 6 =< M.

between(1,M,1) :- 1 =< M.
between(1,M,2) :- 2 =< M.
between(1,M,3) :- 3 =< M.
between(1,M,4) :- 4 =< M.
between(1,M,5) :- 5 =< M.
between(1,M,6) :- 6 =< M.
*/

pick(Size, coins(N1, H1, L1, U1), coins(N2, H2, L2, U2), 
	       coins(N3, H3, L3, U3)) :-
	between(0,N1,N2), between(0,H1,H2), between(0,L1,L2), 
	U2 is Size - (N2+H2+L2), U2 >= 0,between(0,U1, U2),
	N3 is N1-N2, H3 is H1-H2, L3 is L1-L2, U3 is U1-U2.


/* plausible(N,M) :- write(plaus(N,M)), nl, fail.*/
plausible(W, coins(N,H,L,U)) :- 
	Possibilities is H+ L+ 2*U,
	plausible1(W, Possibilities).

plausible1(0, MaybeFaulty) :-  MaybeFaulty =< 1.
plausible1(1, MaybeFaulty) :-  MaybeFaulty =< 3.
plausible1(Weighings, MaybeFaulty) :-  /* Would information theory allow it? */
				      /* Log MaybeFaulty wrt 3 */
	Weighings > 1,
	W1 is Weighings-1,
	M1 is (MaybeFaulty + 2) / 3,
	plausible1(W1,M1).


main(C,W) :- strategy(C,W,T). /* , printTree(W, 0, 'top', T). */

printTree(W,Spaces, Symbol, T) :- W < 1.
printTree(W,Spaces, Symbol, t(weigh(coins(N1,H1,L1,U1),coins(N2,H2,L2,U2)), 
	    eq(Teq), leftHeavy(Tl), rightHeavy(Tr)) ) :-
	W>0,
	writeSpaces(Spaces), write(Symbol), write('--> '),
	 write([N1,H1,L1,U1]), write(':'), write([N2,H2,L2,U2]),nl,
	S2 is Spaces+1, W2 is W-1,
	printTree(W2,S2, ' = ', Teq),
	printTree(W2,S2, ' > ', Tl),
	printTree(W2,S2, ' < ', Tr).

writeSpaces(0).
writeSpaces(N) :- N>0, write('.....'), N1 is N-1, writeSpaces(N1).


/* ?- main(coins(0,0,3,0), 1), write(yes), nl. */
?- write(start), nl, main(coins(0,0,9,0), 2), write(yes), nl. 
/* ?- main(coins(0,0,0,12),3), write(yes), nl. */

/* main(coins(0,27,0,0), 3), write(yes), nl. */


