// read by snoopy as colspn, colcpn, colhpn, when initial keyword set accordingly colspn [diffusion_3D26] { constants: all: int D = 2; int D1 = D; int D2 = D; int D3 = 1; // makes it 2D int M1 = D1/2+1; int M2 = D2/2+1; int M3 = D3/2+1; int R = 0; int S1 = 1; int S2 = 1; int S3 = 1; // set to 1 if dimension not required param: double k = 0.1; colorsets: Dot = {dot}; CD1 = {1..D1}; CD2 = {1..D2}; CD3 = {1..D3}; Distance = {1..D}; Grid3D = PROD(CD1,CD2,CD3); variables: CD1 : a; CD2 : b; CD3 : c; CD1 : x; CD2 : y; CD3 : z; CD1 : x0; CD2 : y0; CD3 : z0; colorfunctions: // Is (a,b,c) one of the 26 neighbours of (x,y,z) ? bool neighbour3D26(CD1 a,CD2 b,CD3 c,CD1 x,CD2 y,CD3 z) { (a=x-1 | a=x | a=x+1) & (b=y-1 | b=y | b=y+1) & (c=z-1 | c=z | c=z+1) & (!(a=x & b=y & c=z)) & (1<=x & x<=D1) & (1<=y & y<=D2) & (1<=z & z<=D3) }; // Is (a,b,c) one of the 6 neighbours of (x,y,z) ? bool neighbour3D6(CD1 a,CD2 b,CD3 c,CD1 x,CD2 y,CD3 z) { (a=x-1 | a=x | a=x+1) & (b=y-1 | b=y | b=y+1) & (c=z-1 | c=z | c=z+1) & (!(a=x & b=y & c=z)) & (( a=x & b=y) | (b=y & c=z) | (a=x & c=z)) & (1<=x & x<=D1) & (1<=y & y<=D2) & (1<=z & z<=D3) }; // Is (x,y,z) within the region around the centre (x0,y0,z0) // with a max distance from the centre of 'radius', and // a space of xd, yd, zd inbetween in the x/y/z-axis, resp. bool region(CD1 x,CD2 y,CD3 z,CD1 x0,CD2 y0,CD3 z0,Distance radius,Distance xd,Distance yd,Distance zd) { ( (x0-radius)<=x & x<=(x0+radius) ) & ( (y0-radius)<=y & y<=(y0+radius) ) & ( (z0-radius)<=z & z<=(z0+radius) ) & ( (1<=x & x<=D1) & (1<=y & y<=D2) & (1<=z & z<=D3) )& (x%xd=0 & y%yd=0 & z%zd=0) }; // example calls: // 2D: region(x,y,z,M1,M2,1,0,1,1,1): // one position in the mid point (M1,M2,1) of the 2D grid; // 2D: region(x,y,z,M1,M2,1,1,1,1,1): // 9 positions (R=1) around the mid point (M1,M2,1) of the 2D grid; // 2D: region(x,y,z,M1,M2,1,2,1,1,1): // a region of 25 positions (R=2) around the mid point (M1,M2,1) of the 2D grid, // comprising each position. // 2D: region(x,y,z,M1,M2,1,2,2,2,1): // a region of 25 positions (R=2) around the mid point (M1,M2,1) of the 2D grid, // comprising every second position in x/y dimensions. places: // discrete: // Grid3D P = 1`(M1,M2,1); // this works in snoopy only Grid3D P = 1000`region(x,y,z,M1,M2,1,R,S1,S2,S3); // this works in marcie + andl converter // generates 1,000 tokens for all colours (x,y,z) fulfilling the region condition // Grid3D P = [region(x,y,z,M1,M2,M3,R,S1,S2,S3)]1000`(x,y,z); // candl export generates extra [..] for the guard, i.e., {[neighbour3D6(x,y,z,a,b,c)]} transitions: t {neighbour3D26(x,y,z,a,b,c)} : : [P + {(a,b,c)}] & [P - {(x,y,z)}] : MassAction(k) ; } // end colspn [diffusion_3D26]