:- dynamic fact/3 .
% "pred" (auxiliary predicates for SMASS)
normal_distribution(N,AS,L,U,SI) :- MU is L + (0.5 * (U-L)),
( between(1,AS,A), determine_nd_value(N,MU,SI,L,U,A), fail; true),!.
determine_nd_value(N,MU,SI,L,U,A) :- repeat, X is
random(10001)+1,
X4 is (1/10000) * (((X-1) * U)+(10001-X) * L), W is integer(X4),
PI is pi, X1 is 2*(PI * (SI * SI)), X2 is (1 / sqrt(X1)),
X3 is (-((W-MU)*(W-MU))) / (SI*SI), Y is X2 * exp(X3),
W1 is random(10001)+1, Z is (W1-1)/10000, Z =< Y, between(L,U,W),
asserta(nd_expr(N,A,W)), !.
make_discrete_distribution(N,AS,EX,LIST) :-
( between(1,AS,A), determine_dd_value(N,A,EX,LIST), fail; true ),!.
determine_dd_value(N,A,EX,LIST) :- X is random(100)+1,
between(1,EX,Z), nth1(Z,LIST,W_Z), X < W_Z, assert( dd_expr(N,A,Z)),!.
calculate_sum(L,S) :- asserta(counter(0)), length(L,E),
( between(1,E,X), auxpred(L,X) , fail ; true), counter(S),
retract(counter(S)).
auxpred(L,X) :- nth1(X,L,N), counter(C), C1 is C+N,
retract(counter(C)), asserta(counter(C1)), !.
make_nbh(moore,N,I,J,L) :- gridwidth(G),
( N=1, moore_nbh_1(G,I,J,L)
; 1 < N, moore_nbh_1(G,I,J,L2), asserta(auxlist(I,J,L2)),
length(L2,K),
( between(1,K,X), mnbh(X,L2,N,G,I,J), fail ; true),
auxlist(I,J,L5), delete(L5,[I,J],L6), sort(L6,L),
retractall(auxlist(A,B,L8))
),!.
mnbh(X,L2,N,G,I,J) :- nth1(X,L2,Y), Y=[I1,J1], N1 is N-1,
make_nbh(moore,N1,I1,J1,L3), auxlist(I,J,L4), append(L4,L3,L5),
retract(auxlist(I,J,L4)), asserta(auxlist(I,J,L5)), !.
moore_nbh_1(G,I,J,L) :- recalculate_neg(G,I,1,Im),
recalculate_neg(G,J,1,Jm), recalculate_pos(G,I,1,Ip),
recalculate_pos(G,J,1,Jp),
L = [[I,Jm],[Im,Jm],[Im,J],[Im,Jp],[I,Jp],[Ip,Jp],[Ip,J],[Ip,Jm]].
recalculate_neg(G,I,H,I1) :- X is I-H, ( ( 0 < X, I1 is X
; 0 =:= X, I1 is G ) ; X < 0, I1 is (G+I)- H ),!.
recalculate_pos(G,I,H,I1) :- X is I+H, ( ( I < G, X =< G, I1 is X
; I =:= G, (H > 0, I1 is H; H =:= 0, I1 is G) ) ; I < G, X > G,
I1 is (H+I)-G ),!.
make_nbh(von_Neumann,N,I,J,L) :- gridwidth(G), ( N=1,
von_Neumann_nbh_1(G,I,J,L) ; 1 < N, von_Neumann_nbh_1(G,I,J,L2),
asserta(auxlist(I,J,L2)), length(L2,K),
( between(1,K,X), vNnbh(X,L2,N,G,I,J), fail ; true),
auxlist(I,J,L5),
delete(L5,[I,J],L6),
sort(L6,L),
retractall(auxlist(A,B,L8)) ),!.
vNnbh(X,L2,N,G,I,J) :- nth1(X,L2,Y), Y=[I1,J1], N1 is N-1,
make_nbh(von_Neumann,N1,I1,J1,L3), auxlist(I,J,L4), append(L4,L3,L5),
retract(auxlist(I,J,L4)), asserta(auxlist(I,J,L5)), !.
von_Neumann_nbh_1(G,I,J,L) :- recalculate_neg(G,I,1,Im),
recalculate_neg(G,J,1,Jm), recalculate_pos(G,I,1,Ip),
recalculate_pos(G,J,1,Jp), L = [[I,Jm],[Im,J],[I,Jp],[Ip,J]].
decompose(Y,I,J,G) :- between(1,G,Z), Y =< Z*G, Z1 is Z-1, I is Z,
J is Y-(Z1*G),!.