:-style_check(-singleton). % It is not easy to predict all possible consequences when two different % sequences of instructions are operating on the same data in an % unpredictable order. The predicate will shuffle lists of actions % together into a sequence and then obey them. % This is based on a sample GRE question 1991-1992. CS489 Fall92 % cobegin x:=1; y:=y+x; and y:=2; x:=x+3; end cobegin. % Solving this problem involves defining the semantics and % and syntax of assignments, sequences, and cobegin. go:-A=[let(x,1), let(y,y+x)], B=[let(y,2),let(x,x+3)], !, shuffle(A,B,C), initial_status, print_status, obey(C),print_status, nl,nl,fail. go. shuffle([], X, X). shuffle(X, [], X). shuffle([X|Y], Z, [X|W]):-shuffle(Y,Z,W),Z \= []. shuffle(Y, [X|Z], [X|W]):-shuffle(Y,Z,W),Y \= []. obey([]):-!. obey([X|Y]):- write(X), nl, X, print_status, obey(Y),!. % notice the simulated memory - needed since Prolog variables are temporary. % ram(x, v) is a clause when and only when x is a variable and v its % current value in the simulation. print_status:-ram(X, VX), write('RAM['), write(X), write(']='), write(VX), nl,fail. print_status:- write('-------------'), nl. initial_status:-abolish(ram,2), assert(ram(x,0)), assert(ram(y,0)),!. % we now have to define how to evaluate expressions using ram values. eval(X, V):-ram(X,V),!. eval(+Y, VX):-eval(X,VX), !. eval(-Y, V):-eval(X,VX), V is -VX, !. eval(X+Y, V):-eval(X,VX), eval(Y,VY), V is VX+VY, !. eval(X-Y, V):-eval(X,VX), eval(Y,VY), V is VX-VY, !. eval(X*Y, V):-eval(X,VX), eval(Y,VY), V is VX*VY, !. eval(X, V):-V is X,!. % Now define semantics of assignment statements used with our RAM. let(X,E):-eval(E,EV), store(X,EV). store(X,EV):-remove_old(X), assert(ram(X,EV)),!. remove_old(X):- (ram(X,Old), retract(ram(X,Old)); true),!. :-print('shuffle, obey and go loaded').