:-set_flag(all_dynamic,on).

:- op(980, xfx, [<-+-]).
:- op(980, xfx, [<---]).
:- op(980, xfx, [<-++-]).
:- op(980, xfx, [<-+--]).
:- op(980, xfx, [<--+-]).
:- op(980, xfx, [<----]).

poss(C,S):- member(A,C),
	    not aPrimitiveNonPoss(C,S),
	    not conflict(C,S),
	    not rangeViolation(do(C,S)).

aPrimitiveNonPoss(C,S):- member(A,C),
	                 not poss(A,S).

rangeViolation(S):- value(F,V,S),
	            (lower(F,L), V < L ;
		     upper(F,U), V > U).

dContr(F,C,V,S):- sumContr(F,C,V,S).

sumContr(F,[A],V,S):- contr(F,A,V,S).
sumContr(F,[A|As],V,S):- sumContr(F,As,Vs,S),
                         contr(F,A,V1,S),
			 V is Vs+V1.

iContr(F,C,V,S):- (F <-+- EG),
	          EG =.. [Op,K,G],
                  dContr(G,C,V1,S),
                  iContr(G,C,V2,S),
                  tContr(G,C,V3,S),
                  VR is V1+V2-V3,
		  ECG =.. [Op,K,VR],
		  V is ECG, !.

iContr(F,C,V,S):- (F <--- EG),
	          EG =.. [Op,K,G],
                  dContr(G,C,V1,S),
                  iContr(G,C,V2,S),
                  tContr(G,C,V3,S),
                  VR is -(V1+V2-V3),
		  ECG =.. [Op,K,VR],
		  V is ECG, !.

iContr(F,C,0,S):- (F <-+-- G ; F <--+- G),
                  tContr(G,C,0,S),!.

iContr(F,C,V,S):- (F <-+-- EG),
	          EG =.. [Op,K,G],
                  tContr(G,C,V1,S),
                  V1 =< 0,
		  ECG =.. [Op,K,V1],
		  VR is ECG,
		  V is -VR, !.

iContr(F,C,V,S):- (F <--+- EG),
	          EG =.. [Op,K,G],
                  tContr(G,C,V1,S),
                  V1 >= 0,
		  ECG =.. [Op,K,V1],
		  VR is ECG,
                  V is -VR,!.

iContr(F,C,0,S).

dContrPlusiContr(F,C,V,S):- dContr(F,C,V1,S),
	                    iContr(F,C,V2,S),
			    V is V1+V2.

tContr(F,C,V,S):- (F=small;F=medium;F=large),
	          upper(F,U),
	          value(F,Vs,S),
		  V is U - Vs,
		  dContrPlusiContr(F,C,Vp,S),
		  Vp > V,!.

tContr(F,C,V,S):- (F=small;F=medium;F=large),
	          lower(F,L),
	          value(F,Vs,S),
		  V is L - Vs,
		  dContrPlusiContr(F,C,Vp,S),
		  Vp < V,!.

tContr(F,C,V,S):- dContrPlusiContr(F,C,V,S).

