:- dynamic fact/3 .
% "rules" (the action rules in SMASS)
% RULE 1: `donothin'. The person intentionally does not do anything.%
domain_of_wealths(50,500). sigma_wealths(20). exist_min(20).
prepare(R,T,donothin) :- true.
act_in_mode(donothin,A,R,T) :- feasible(donothin,A,R,T),
chooseaction(donothin,A,R,T), perform(donothin,A,R,T),!.
feasible(donothin,A,R,T) :- fact(R,T,wealth_dono(A,W)), exist_min(E),
E1 is 3*E, W1 is W-E1, W1 > 0,!.
chooseaction(donothin,A,R,T) :- true,!.
perform(donothin,A,R,T) :- fact(R,T,wealth_dono(A,W)), W1 is W-5,
retract(fact(R,T,wealth_dono(A,W))),
asserta(fact(R,T,wealth_dono(A,W1))),!.
protocol(donothin,A,R,T) :- fail.
adjust(donothin,A,R,T):- true.
adjust(donothin,R,T) :- true.
%-------------------------------------------------------------------------------
% RULE 2: `schellin'. The person move to a better location, if she likes the
% new ambience. This rule is synchronous because an actor can move only once in a period.
prepare(R,T,schellin) :-
asserta(occupied([])), gridwidth(G),
G1 is G*G, findall(X,between(1,G1,X),CL),
actors(AS),
asserta(list222(CL)),
( between(1,AS,A), subtract_cell(A,CL,R,T,G), fail ; true),!,
list222(LFree), retract(list222(LFree)), asserta(free_cells(LFree)),!.
subtract_cell(A,CL,R,T,G) :- fact(R,T,location(A,I,J)),
( member(B,CL), decompose(B,I,J,G), list222(LFree),
subtract(LFree,[B],LFreenew), retract(list222(LFree)), asserta(list222(LFreenew))
;
true
),!.
act_in_mode(schellin,A,R,T) :- feasible(schellin,A,R,T),
chooseaction(schellin,A,R,T), perform(schellin,A,R,T),!.
feasible(schellin,A,R,T) :- true.
chooseaction(schellin,A,R,T) :-
gridwidth(G),
fact(R,T,location(A,I,J)), scan_neighbourhood(A,G,I,J,R,T,ANSWER),
( ANSWER=yes ; calculate_move(A,R,T,G,schellin) ),!.
calculate_move(A,R,T,G,schellin) :-
free_cells(LFree), length(LFree,EFree),
asserta(pot_cells([])),
( between(1,EFree,X), check_cell(X,R,T,A,G,LFree,schellin), fail ;true),!,
pot_cells(LC), length(LC,EE), retract(pot_cells(LC)),
asserta(yes_list([])),
( between(1,EE,NC), nth1(NC,LC,C), enter(C), fail ; true),!,
yes_list(LYES), retract(yes_list(LYES)),
occupied(Locu),
( LYES = []
/* does not */
;
LYES \= [], compare1(LYES,Locu,LL),
( LL = []
/* does not */
;
LL \= [], nth1(1,LL,IntC), nth1(1,IntC,B), nth1(2,IntC,I), nth1(3,IntC,J),
IntCnew = [A,I,J],
append(Locu,[IntCnew],Locunew), retract(occupied(Locu)),
asserta(occupied(Locunew))
)
),!.
compare1(LYES,Locu,LL) :-
length(LYES,EL), asserta(list111([])),
( between(1,EL,Z), compare_cell(Z,LYES,Locu), fail ; true),!,
list111(LL), retract(list111(LL)),!.
compare_cell(Z,LYES,Locu) :- nth1(Z,LYES,C), nth1(1,C,B), nth1(2,C,UU), nth1(1,UU,I), nth1(2,UU,J),
U = [X,I,J],
( member(U,Locu)
/* nichts machen */
;
list111(LL), append(LL,[U],LLnew), retract(list111(LL)), asserta(list111(LLnew))
),!.
enter(C) :- yes_list(LYES), nth1(3,C,ANS),
( ANS = yes , append(LYES,[C],LYESnew), retract(yes_list(LYES)),
asserta(yes_list(LYESnew))
;
true
),!.
check_cell(X,R,T,A,G,LFree,schellin) :- nth1(X,LFree,B), decompose(B,I,J,G),
scan_neighbourhood(A,G,I,J,R,T,ANSWER), pot_cells(LL),
append(LL,[[B,[I,J],ANSWER]],LLnew), retract(pot_cells(LL)),
asserta(pot_cells(LLnew)),!.
%---------------------------------------------------------------------------------
scan_neighbourhood(A,G,I,J,R,T,ANSWER) :-
type_of_neighbourhood(schellin,TW,TG),
make_nbh(TW,TG,I,J,L),
findall(N,neighb(N,L,R,T),L1), length(L1,E1),
findall(N1, equal_colour(N1,A,L,R,T), L2), length(L2,E2),
(
(
( E1 =< 2, 1 =< E2; 3 =< E1, E1 =< 5, 2 =< E2 )
;
6 =< E1, E1 =<
8, 5 =< E2
), ANSWER=yes
;
ANSWER=no
),!.
neighb(N,L,R,T) :- member([I,J],L), fact(R,T,location(N,I,J)).
equal_colour(N,A,L,R,T) :- member([I,J],L), fact(R,T,location(N,I,J)),
fact(R,T,colour(N,CN)), fact(R,T,colour(A,CA)), CA=CN.
% ---------------------------------------------------------------------
perform(schellin,A,R,T) :- true.
protocol(schellein,A,R,T) :- fail.
adjust(schellin,A,R,T) :-
occupied(LL),
( LL=[]
;
LL \= [] ,
(
nth1(X,LL,[A,I,J]),
fact(R,T,location(A,Iold,Jold)),
retract(fact(R,T,location(A,Iold,Jold))),
asserta(fact(R,T,location(A,I,J)))
;
true
)
),!.
adjust(schellin,R,T) :- free_cells(LFree), retract(free_cells(LFree)),
occupied(LL), retract(occupied(LL)),!.
% --------------------------------------------------------------
% RULE 3: `takeweak'. The person takes wealth from a weaker person. Here we find an asynchronous
% rule of a strange -but realistic- way of cheating.
prepare(R,T,takeweak) :- true.
act_in_mode(takeweak,A,R,T) :-
feasible(takeweak,A,R,T),
chooseaction(takeweak,A,R,T), perform(takeweak,A,R,T).
feasible(takeweak,A,R,T) :- exist_min(MIN),
domain_of_values(SS),
type_of_neighbourhood(takeweak,TW,GW),
fact(R,T,location(A,IA,JA)),
make_nbh(TW,GW,IA,JA,NHA),!,
length(NHA,E), asserta(neighlist([])),
( between(1,E,Y), locate(Y,R,T,NHA), fail; true),!,
neighlist(NHL), append(results), write(neighlist(A,i,NHL)), write('.'),
nl, told,
length(NHL,E1),
retract(neighlist(NHL)),
fact(R,T,strength(A,SA)),
asserta(n_strength([])),
( between(1,E1,X), investigate(R,T,X,NHL,MIN,SA,SS), fail; true),!,
n_strength(LL), length(LL,E2), retract(n_strength(LL)),
( E2 = 0, fail
;
0 < E2,
sort(LL,LLnew), length(LLnew,E3), nth1(E3,LLnew,WW),
WW = [NB,SB],
asserta(neighb(NB))
),!.
locate(Y,R,T,NHA) :- nth1(Y,NHA,[I,J]), fact(R,T,location(B,I,J)),
neighlist(LL), append(LL,[B],LLnew), retract(neighlist(LL)),
asserta(neighlist(LLnew)),!.
investigate(R,T,X,NHL,MIN,SA,SS) :- n_strength(LL),
( nth1(X,NHL,NB), fact(R,T,strength(NB,SB)),
SB < SA,
fact(R,T,wealth_take(NB,WB)), W1 is WB-(3*SS), !,
MIN =< W1, append(LL,[[NB,SB]],LLnew),
retract(n_strength(LL)), asserta(n_strength(LLnew))
;
true
),!.
chooseaction(takeweak,A,R,T) :- true.
perform(takeweak,A,R,T) :-
neighb(NB), retract(neighb(NB)),
fact(R,T,wealth_take(A,WA)), domain_of_values(SS), S1 is 3*SS,
X is random(S1), WA1 is WA+X, retract(fact(R,T,wealth_take(A,WA))),
asserta(fact(R,T,wealth_take(A,WA1))), T1 is T+1,
asserta(fact(R,T1,give_to_the_strong(NB,X))).
protocol(takeweak,A,R,T) :- fact(R,T,give_to_the_strong(A,X)),
fact(R,T,wealth_take(A,WA)), exist_min(MIN), W1 is max(WA-X,MIN),
retract(fact(R,T,wealth_take(A,WA))),
asserta(fact(R,T,wealth_take(A,W1))),
retract(fact(R,T,give_to_the_strong(A,X))).
adjust(takeweak,A,R,T) :- true.
adjust(takeweak,R,T) :- true.