% This file started from the version in /projects/tambay/Cob/helper
% This file contains efficient definition of index with cuts and 
% also the first 30 indices are sort of hard coded.
% Declarations of constant sized arrays are translated to makearray

%:- use_module(library(lists)). - BJ


conditional_constraint(A, B) :- ground(B), call(B), !, call(A).
conditional_constraint(A, B) :- !.
% BJ: 2/17/2012 - above rule causes CC to skip when B is non-ground. 
%               - Have to revisit this logic later.  
conditional_constraint(A, _) :- ground(A), call(A), ! .
%changed this clause due to move to SICStus
%conditional_constraint(A, B) :- ground(A), !, not (B).
%BJ(2/12/2012) conditional_constraint(A, B) :- ground(A), !,  naf(B).
conditional_constraint(_, B) :- ground(B), !.
conditional_constraint(A, B) :- 
   B =..[CobExists|_], 
   name(CobExists, N),	% clpr does not have 'name'; must change this.
   name(cobexists, N1),
   prefix(N1, N),
   call(B), !, call(A).
conditional_constraint(A, B) :- 
   B =..[CobExists|_],
   name(CobExists, N),
   name(cobexists, N1),
   prefix(N1, N), 
   !.
conditional_constraint(A, B) :- 
   (B) =..[\+, C|_], 
   C =..[CobExists|_],
   name(CobExists, N),
   name(cobexists, N1),
   prefix(N1, N), 
   call(B), !, call(A).
conditional_constraint(A, B) :- 
   (B) =..[\+, C|_], 
   C =..[CobExists|_],
   name(CobExists, N),
   name(cobexists, N1),
   prefix(N1, N),
   !.

%conditional_constraint(A, _) :- call(A), ! .
%conditional_constraint(_, B) :- \+(call(B)) .


index([X|_], 1, X) :- !.
index([_,X|_], 2, X) :- !.
index([_,_,X|_], 3, X) :- !.
index([_,_,_,X|_], 4, X) :- !.
index([_,_,_,_,X|_], 5, X) :- !.
index([_,_,_,_,_,X|_], 6, X) :- !.
index([_,_,_,_,_,_,X|_], 7, X) :- !.
index([_,_,_,_,_,_,_,X|_], 8, X) :- !.
index([_,_,_,_,_,_,_,_,X|_], 9, X) :- !.
index([_,_,_,_,_,_,_,_,_,X|_], 10, X) :- !.
index([_,_,_,_,_,_,_,_,_,_,X|_], 11, X) :- !.
index([_,_,_,_,_,_,_,_,_,_,_,X|_], 12, X) :- !.
index([_,_,_,_,_,_,_,_,_,_,_,_,X|_], 13, X) :- !.
index([_,_,_,_,_,_,_,_,_,_,_,_,_,X|_], 14, X) :- !.
index([_,_,_,_,_,_,_,_,_,_,_,_,_,_,X|_], 15, X) :- !.
index([_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,X|_], 16, X) :- !.
index([_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,X|_], 17, X) :- !.
index([_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,X|_], 18, X) :- !.
index([_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,X|_], 19, X) :- !.
index([_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,X|_], 20, X) :- !.
index([_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,X|_], 21, X) :- !.
index([_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,X|_], 22, X) :- !.
index([_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,X|_], 23, X) :- !.
index([_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,X|_], 24, X) :- !.
index([_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,X|_], 25, X) :- !.
index([_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,X|_], 26, X) :- !.
index([_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,X|_], 27, X) :- !.
index([_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,X|_], 28, X) :- !.
index([_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,X|_], 29, X) :- !.
index([_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,X|_], 30, X) :- !.
index(Array, Index, Value) :- Index > 30, index(Array, 1, Index, Value).
index([X|_], I, I, X) :- !.
index([_|T], I, N, X) :- index(T, I + 1, N, X).
index(Array, Index, _Value) :- %Detect illegal array indexing.
   sizeof(Array, Size), 
   Index > Size,
   print('Illegal Array Indexing'),
   !, fail.

output([]).
output([X|T]) :- print(X), nl, output(T).

makearray([N], V) :- !, sizeof(V, N), !.
makearray([N|Rest], V) :- !, sizeof(V, N), makearrayofeach(Rest,V).
makearray(_,_). % when array dimensions are left unspecified.

makearrayofeach(NL,[V]) :- makearray(NL, V), !.
makearrayofeach(L, [V1|Rest]) :- makearray(L, V1), makearrayofeach(L,Rest).

sizeof([], 0) :- !.
sizeof([_|T], N+1) :- sizeof(T, N).

min(X,Y,Z) :- ((nonvar(X), nonvar(Y))-> Z=min(X,Y); (nonvar(X)->Z=X; (nonvar(Y)-> Z=Y;true))).

max(X,Y,Z) :- ((nonvar(X), nonvar(Y))-> Z=max(X,Y); (nonvar(X)->Z=X; (nonvar(Y)-> Z=Y;true))).

makelistfromto(M, M, [M]).
makelistfromto(N, M, [N|NtoM]) :- 
	N < M, 
	N1 = N+1, 
	makelistfromto(N1, M, NtoM).

naf(B) :- call(B), !, fail.
naf(B).

ln(X,L) :- X > 0,
	   T = (X-1)/(X+1),
	   T3 =  T*T*T,
           T5 =  T3*T*T,
           T7 =  T5*T*T,
           T9 =  T7*T*T,
           T11 = T9*T*T,
           L  =  2*(T + (1/3)*T3+ (1/5)*T5 + (1/7)*T7 + (1/9)*T9 + (1/11)*T11).


/*
log(X,L) :- X > 0, X <= 2,
	    T1 = (X-1),
            T2 = 0.5 * T1*T1,
            T3 = 0.666 * T2*T1,
            T4 = T2*T2,
            L = (T1 + T2 + T3 + T4).
*/
