:- expects_dialect(lps). % Conway's game of life. % cells assumed dead by default % x-y represents that the cell at column x and row y is alive % XSB requires: :- use_module(basics, [member/2]). maxTime(8). fluents X - Y. actions die(_), live(_). initially 2-3,3-3,4-3. % blinker %initially 6-3,7-3,8-3. % another %initially 6-6,7-6,8-6. % yet another %Notice that times can sometimes be omitted, as in these rules: % if X-Y at T, aliveNeighbors(X-Y,N) at T, N<2 then die(X-Y). if X-Y at T, aliveNeighbors(X-Y,N) at T, N>3 then die(X-Y). if cell(X,Y), aliveNeighbors(X-Y,3) at T then live(X-Y). % The following two clauses, which are time-independent, are in Prolog. % cell(X,Y) :- Range = [1,2,3,4,5,6,7,8,9,10], member(X,Range), member(Y,Range). adjacent(X-Y,L) :- findall(Ax-Ay,( member(Dx,[-1,0,1]), member(Dy,[-1,0,1]), not (Dx=0,Dy=0), Ax is X+Dx, Ay is Y+Dy ), L). % The following four clauses define predicates that depend on the state at time T. % aliveNeighbors(X-Y,N) at T if adjacent(X-Y,L), countLivingNeighbors(L,N) at T. countLivingNeighbors([],0) at _. countLivingNeighbors([X-Y|Cells],N) at T if X-Y at T, countLivingNeighbors(Cells,N1) at T, N is N1+1. countLivingNeighbors([X-Y|Cells],N) at T if not(X-Y) at T, countLivingNeighbors(Cells,N) at T. live(X-Y) initiates X-Y. die(X-Y) terminates X-Y. d(X-Y,[center:[XX,YY], radius:5, type:circle, fillColor:green]) :- XX is X*10, YY is Y*10. d(live(X-Y),[type:star, center:[XX,YY], points:7, radius1:4, radius2:7, fillColor:red]) :- XX is X*10, YY is Y*10. d(die(X-Y),[type:star, center:[XX,YY], points:7, radius1:4, radius2:7, fillColor:black]) :- XX is X*10, YY is Y*10. d(timeless,[[type:raster,position:[50,120], scale:0.08, % more complicated: transform:[-0.1,0,0,0.1,0,0], source:'https://upload.wikimedia.org/wikipedia/commons/0/04/John_H_Conway_2005_%28cropped%29.jpg'], [type:text, point:[0,5], content:'Conway\'s Game of Life']]). /** ?- go(Timeline). */