mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	Support for CWeb language (#3592)
Move .w file extension for CWeb to its own entry.
This commit is contained in:
		
				
					committed by
					
						 Colin Seymour
						Colin Seymour
					
				
			
			
				
	
			
			
			
						parent
						
							20fdac95f6
						
					
				
				
					commit
					d490fc303f
				
			| @@ -455,7 +455,6 @@ C: | |||||||
|   - ".cats" |   - ".cats" | ||||||
|   - ".h" |   - ".h" | ||||||
|   - ".idc" |   - ".idc" | ||||||
|   - ".w" |  | ||||||
|   interpreters: |   interpreters: | ||||||
|   - tcc |   - tcc | ||||||
|   ace_mode: c_cpp |   ace_mode: c_cpp | ||||||
| @@ -589,6 +588,13 @@ CSV: | |||||||
|   extensions: |   extensions: | ||||||
|   - ".csv" |   - ".csv" | ||||||
|   language_id: 51 |   language_id: 51 | ||||||
|  | CWeb: | ||||||
|  |   type: programming | ||||||
|  |   extensions: | ||||||
|  |   - ".w" | ||||||
|  |   tm_scope: none | ||||||
|  |   ace_mode: text | ||||||
|  |   language_id: 657332628 | ||||||
| Cap'n Proto: | Cap'n Proto: | ||||||
|   type: programming |   type: programming | ||||||
|   tm_scope: source.capnp |   tm_scope: source.capnp | ||||||
|   | |||||||
							
								
								
									
										404
									
								
								samples/CWeb/sat-life.w
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										404
									
								
								samples/CWeb/sat-life.w
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,404 @@ | |||||||
|  | \datethis | ||||||
|  | @*Intro. This program generates clauses for the transition relation | ||||||
|  | from time $t$ to time $t+1$ in Conway's Game of Life, assuming that | ||||||
|  | all of the potentially live cells at time $t$ belong to a pattern | ||||||
|  | that's specified in |stdin|. The pattern is defined by one or more | ||||||
|  | lines representing rows of cells, where each line has `\..' in a | ||||||
|  | cell that's guaranteed to be dead at time~$t$, otherwise it has `\.*'. | ||||||
|  | The time is specified separately as a command-line parameter. | ||||||
|  |  | ||||||
|  | The Boolean variable for cell $(x,y)$ at time $t$ is named by its | ||||||
|  | so-called ``xty code,'' namely by the decimal value of~$x$, followed | ||||||
|  | by a code letter for~$t$, followed by the decimal value of~$y$. For | ||||||
|  | example, if $x=10$ and $y=11$ and $t=0$, the variable that indicates | ||||||
|  | liveness of the cell is \.{10a11}; and the corresponding variable | ||||||
|  | for $t=1$ is \.{10b11}. | ||||||
|  |  | ||||||
|  | Up to 19 auxiliary variables are used together with each xty code, | ||||||
|  | in order to construct clauses that define the successor state. | ||||||
|  | The names of these variables are obtained by appending one of | ||||||
|  | the following two-character combinations to the xty code: | ||||||
|  | \.{A2}, \.{A3}, \.{A4}, | ||||||
|  | \.{B1}, \.{B2}, \.{B3}, \.{B4}, | ||||||
|  | \.{C1}, \.{C2}, \.{C3}, \.{C4}, | ||||||
|  | \.{D1}, \.{D2}, | ||||||
|  | \.{E1}, \.{E2}, | ||||||
|  | \.{F1}, \.{F2}, | ||||||
|  | \.{G1}, \.{G2}. | ||||||
|  | These variables are derived from the Bailleux--Boufkhad method | ||||||
|  | of encoding cardinality constraints: | ||||||
|  | The auxiliary variable \.{A$k$} stands for the condition | ||||||
|  | ``at least $k$ of the eight neighbors are alive.'' Similarly, | ||||||
|  | \.{B$k$} stands for ``at least $k$ of the first four neighbors | ||||||
|  | are alive,'' and \.{C$k$} accounts for the other four neighbors. | ||||||
|  | Codes \.D, \.E, \.F, and~\.G refer to pairs of neighbors. | ||||||
|  | Thus, for instance, \.{10a11C2} means that at least two of the | ||||||
|  | last four neighbors of cell $(10,11)$ are alive. | ||||||
|  |  | ||||||
|  | Those auxiliary variables receive values by means of up to 77 clauses per cell. | ||||||
|  | For example, if $u$ and~$v$ are the neighbors of cell~$z$ that correspond | ||||||
|  | to a pairing of type~\.D, there are six clauses | ||||||
|  | $$\bar u d_1,\quad | ||||||
|  |   \bar v d_1,\quad | ||||||
|  |   \bar u\bar v d_2,\quad | ||||||
|  |   u v\bar d_1,\quad | ||||||
|  |   u\bar d_2,\quad | ||||||
|  |   v\bar d_2.$$ | ||||||
|  | The sixteen clauses | ||||||
|  | $$\displaylines{\hfill | ||||||
|  | \bar d_1b_1,\quad | ||||||
|  | \bar e_1b_1,\quad | ||||||
|  | \bar d_2b_2,\quad | ||||||
|  | \bar d_1\bar e_1b_2,\quad | ||||||
|  | \bar e_2b_2,\quad | ||||||
|  | \bar d_2\bar e_1b_3,\quad | ||||||
|  | \bar d_1\bar e_2b_3,\quad | ||||||
|  | \bar d_2\bar e_2b_4, | ||||||
|  | \hfill\cr\hfill | ||||||
|  | d_1e_1\bar b_1,\quad | ||||||
|  | d_1e_2\bar b_2,\quad | ||||||
|  | d_2e_1\bar b_2,\quad | ||||||
|  | d_1\bar b_3,\quad | ||||||
|  | d_2e_2\bar b_3,\quad | ||||||
|  | e_1\bar b_3,\quad | ||||||
|  | d_2\bar b_4,\quad | ||||||
|  | e_2\bar b_4 | ||||||
|  | \hfill}$$ | ||||||
|  | define $b$ variables from $d$'s and $e$'s; and another sixteen | ||||||
|  | define $c$'s from $f$'s and $g$'s in the same fashion. | ||||||
|  | A similar set of 21 clauses will define the $a$'s from the $b$'s and $c$'s. | ||||||
|  |  | ||||||
|  | Once the $a$'s are defined, thus essentially counting the | ||||||
|  | live neighbors of cell $z$, the next | ||||||
|  | state~$z'$ is defined by five further clauses | ||||||
|  | $$\bar a_4\bar z',\quad | ||||||
|  | a_2\bar z',\quad | ||||||
|  | a_3z\bar z',\quad | ||||||
|  | \bar a_3a_4z',\quad | ||||||
|  | \bar a_2a_4\bar zz'.$$ | ||||||
|  | For example, the last of these states that $z'$ will be true | ||||||
|  | (i.e., that cell $z$ will be alive at time $t+1$) if | ||||||
|  | $z$ is alive at time~$t$ and has $\ge2$ live neighbors | ||||||
|  | but not $\ge4$. | ||||||
|  |  | ||||||
|  | Nearby cells can share auxiliary variables, according to a tricky scheme that | ||||||
|  | is worked out below. In consequence, the actual number of auxiliary variables | ||||||
|  | and clauses per cell is reduced from 19 and $77+5$ to 13 and $57+5$, | ||||||
|  | respectively, except at the boundaries. | ||||||
|  |  | ||||||
|  | @ So here's the overall outline of the program. | ||||||
|  |  | ||||||
|  | @d maxx 50 /* maximum number of lines in the pattern supplied by |stdin| */ | ||||||
|  | @d maxy 50 /* maximum number of columns per line in |stdin| */ | ||||||
|  |  | ||||||
|  | @c | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | char p[maxx+2][maxy+2]; /* is cell $(x,y)$ potentially alive? */ | ||||||
|  | char have_b[maxx+2][maxy+2]; /* did we already generate $b(x,y)$? */ | ||||||
|  | char have_d[maxx+2][maxy+2]; /* did we already generate $d(x,y)$? */ | ||||||
|  | char have_e[maxx+2][maxy+4]; /* did we already generate $e(x,y)$? */ | ||||||
|  | char have_f[maxx+4][maxy+2]; /* did we already generate $f(x-2,y)$? */ | ||||||
|  | int tt; /* time as given on the command line */ | ||||||
|  | int xmax,ymax; /* the number of rows and columns in the input pattern */ | ||||||
|  | int xmin=maxx,ymin=maxy; /* limits in the other direction */ | ||||||
|  | char timecode[]="abcdefghijklmnopqrstuvwxyz"@| | ||||||
|  |       "ABCDEFGHIJKLMNOPQRSTUVWXYZ"@| | ||||||
|  |       "!\"#$%&'()*+,-./:;<=>?@@[\\]^_`{|}~"; /* codes for $0\le t\le83$ */ | ||||||
|  | @q$@> | ||||||
|  | char buf[maxy+2]; /* input buffer */ | ||||||
|  | unsigned int clause[4]; /* clauses are assembled here */ | ||||||
|  | int clauseptr; /* this many literals are in the current clause */ | ||||||
|  | @<Subroutines@>@; | ||||||
|  | main(int argc,char*argv[]) { | ||||||
|  |   register int j,k,x,y; | ||||||
|  |   @<Process the command line@>; | ||||||
|  |   @<Input the pattern@>; | ||||||
|  |   for (x=xmin-1;x<=xmax+1;x++) for (y=ymin-1;y<=ymax+1;y++) { | ||||||
|  |     @<If cell $(x,y)$ is obviously dead at time $t+1$, |continue|@>; | ||||||
|  |     a(x,y); | ||||||
|  |     zprime(x,y); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ @<Process the command line@>= | ||||||
|  | if (argc!=2 || sscanf(argv[1],"%d",&tt)!=1) { | ||||||
|  |   fprintf(stderr,"Usage: %s t\n",argv[0]); | ||||||
|  |   exit(-1); | ||||||
|  | } | ||||||
|  | if (tt<0 || tt>82) { | ||||||
|  |   fprintf(stderr,"The time should be between 0 and 82 (not %d)!\n",tt); | ||||||
|  |   exit(-2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ @<Input the pattern@>= | ||||||
|  | for (x=1;;x++) { | ||||||
|  |   if (!fgets(buf,maxy+2,stdin)) break; | ||||||
|  |   if (x>maxx) { | ||||||
|  |     fprintf(stderr,"Sorry, the pattern should have at most %d rows!\n",maxx); | ||||||
|  |     exit(-3); | ||||||
|  |   } | ||||||
|  |   for (y=1;buf[y-1]!='\n';y++) { | ||||||
|  |     if (y>maxy) { | ||||||
|  |       fprintf(stderr,"Sorry, the pattern should have at most %d columns!\n", | ||||||
|  |              maxy); | ||||||
|  |       exit(-4); | ||||||
|  |     } | ||||||
|  |     if (buf[y-1]=='*') { | ||||||
|  |       p[x][y]=1; | ||||||
|  |       if (y>ymax) ymax=y; | ||||||
|  |       if (y<ymin) ymin=y; | ||||||
|  |       if (x>xmax) xmax=x; | ||||||
|  |       if (x<xmin) xmin=x; | ||||||
|  |     }@+else if (buf[y-1]!='.') { | ||||||
|  |       fprintf(stderr,"Unexpected character `%c' found in the pattern!\n", | ||||||
|  |               buf[y-1]); | ||||||
|  |       exit(-5); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ @d pp(xx,yy) ((xx)>=0 && (yy)>=0? p[xx][yy]: 0) | ||||||
|  |  | ||||||
|  | @<If cell $(x,y)$ is obviously dead at time $t+1$, |continue|@>= | ||||||
|  | if (pp(x-1,y-1)+pp(x-1,y)+pp(x-1,y+1)+ | ||||||
|  |     pp(x,y-1)+p[x][y]+p[x][y+1]+ | ||||||
|  |     pp(x+1,y-1)+p[x+1][y]+p[x+1][y+1]<3) continue; | ||||||
|  |  | ||||||
|  | @ Clauses are assembled in the |clause| array (surprise), where we | ||||||
|  | put encoded literals. | ||||||
|  |  | ||||||
|  | The code for a literal is an unsigned 32-bit quantity, where the leading | ||||||
|  | bit is 1 if the literal should be complemented. The next three bits | ||||||
|  | specify the type of the literal (0 thru 7 for plain and \.A--\.G); | ||||||
|  | the next three bits specify an integer~$k$; and the next bit is zero. | ||||||
|  | That leaves room for two 12-bit fields, which specify $x$ and $y$. | ||||||
|  |  | ||||||
|  | Type 0 literals have $k=0$ for the ordinary xty code. However, the | ||||||
|  | value $k=1$ indicates that the time code should be for $t+1$ instead of~$t$. | ||||||
|  | And $k=2$ denotes a special ``tautology'' literal, which is always true. | ||||||
|  | If the tautology literal is complemented, we omit it from the clause; | ||||||
|  | otherwise we omit the entire clause. | ||||||
|  | Finally, $k=7$ denotes an auxiliary literal, used to avoid | ||||||
|  | clauses of length~4. | ||||||
|  |  | ||||||
|  | Here's a subroutine that outputs the current clause and resets | ||||||
|  | the |clause| array. | ||||||
|  |  | ||||||
|  | @d taut (2<<25) | ||||||
|  | @d sign (1U<<31) | ||||||
|  |  | ||||||
|  | @<Sub...@>= | ||||||
|  | void outclause(void) { | ||||||
|  |   register int c,k,x,y,p; | ||||||
|  |   for (p=0;p<clauseptr;p++) | ||||||
|  |     if (clause[p]==taut) goto done; | ||||||
|  |   for (p=0;p<clauseptr;p++) if (clause[p]!=taut+sign) { | ||||||
|  |     if (clause[p]>>31) printf(" ~");@+else printf(" "); | ||||||
|  |     c=(clause[p]>>28)&0x7; | ||||||
|  |     k=(clause[p]>>25)&0x7; | ||||||
|  |     x=(clause[p]>>12)&0xfff; | ||||||
|  |     y=clause[p]&0xfff; | ||||||
|  |     if (c) printf("%d%c%d%c%d", | ||||||
|  |              x,timecode[tt],y,c+'@@',k); | ||||||
|  |     else if (k==7) printf("%d%c%dx", | ||||||
|  |              x,timecode[tt],y); | ||||||
|  |     else printf("%d%c%d", | ||||||
|  |              x,timecode[tt+k],y); | ||||||
|  |   } | ||||||
|  |   printf("\n"); | ||||||
|  | done: clauseptr=0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ And here's another, which puts a type-0 literal into |clause|. | ||||||
|  |  | ||||||
|  | @<Sub...@>= | ||||||
|  | void applit(int x,int y,int bar,int k) { | ||||||
|  |   if (k==0 && (x<xmin || x>xmax || y<ymin || y>ymax || p[x][y]==0)) | ||||||
|  |     clause[clauseptr++]=(bar? 0: sign)+taut; | ||||||
|  |   else clause[clauseptr++]=(bar? sign:0)+(k<<25)+(x<<12)+y; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ The |d| and |e| subroutines are called for only one-fourth | ||||||
|  | of all cell addresses $(x,y)$. Indeed, one can show that | ||||||
|  | $x$ is always odd, and that $y\bmod4<2$. | ||||||
|  |  | ||||||
|  | Therefore we remember if we've seen $(x,y)$ before. | ||||||
|  |  | ||||||
|  | Slight trick: If |yy| is not in range, we avoid generating the | ||||||
|  | clause $\bar d_k$ twice. | ||||||
|  |  | ||||||
|  | @d newlit(x,y,c,k) clause[clauseptr++]=((c)<<28)+((k)<<25)+((x)<<12)+(y) | ||||||
|  | @d newcomplit(x,y,c,k)  | ||||||
|  |    clause[clauseptr++]=sign+((c)<<28)+((k)<<25)+((x)<<12)+(y) | ||||||
|  |  | ||||||
|  | @<Sub...@>= | ||||||
|  | void d(int x,int y) { | ||||||
|  |   register x1=x-1,x2=x,yy=y+1; | ||||||
|  |   if (have_d[x][y]!=tt+1) { | ||||||
|  |     applit(x1,yy,1,0),newlit(x,y,4,1),outclause(); | ||||||
|  |     applit(x2,yy,1,0),newlit(x,y,4,1),outclause(); | ||||||
|  |     applit(x1,yy,1,0),applit(x2,yy,1,0),newlit(x,y,4,2),outclause(); | ||||||
|  |     applit(x1,yy,0,0),applit(x2,yy,0,0),newcomplit(x,y,4,1),outclause(); | ||||||
|  |     applit(x1,yy,0,0),newcomplit(x,y,4,2),outclause(); | ||||||
|  |     if (yy>=ymin && yy<=ymax) | ||||||
|  |       applit(x2,yy,0,0),newcomplit(x,y,4,2),outclause(); | ||||||
|  |     have_d[x][y]=tt+1; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @# | ||||||
|  | void e(int x,int y) { | ||||||
|  |   register x1=x-1,x2=x,yy=y-1; | ||||||
|  |   if (have_e[x][y]!=tt+1) { | ||||||
|  |     applit(x1,yy,1,0),newlit(x,y,5,1),outclause(); | ||||||
|  |     applit(x2,yy,1,0),newlit(x,y,5,1),outclause(); | ||||||
|  |     applit(x1,yy,1,0),applit(x2,yy,1,0),newlit(x,y,5,2),outclause(); | ||||||
|  |     applit(x1,yy,0,0),applit(x2,yy,0,0),newcomplit(x,y,5,1),outclause(); | ||||||
|  |     applit(x1,yy,0,0),newcomplit(x,y,5,2),outclause(); | ||||||
|  |     if (yy>=ymin && yy<=ymax) | ||||||
|  |       applit(x2,yy,0,0),newcomplit(x,y,5,2),outclause(); | ||||||
|  |     have_e[x][y]=tt+1; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |      | ||||||
|  | @ The |f| subroutine can't be shared quite so often. But we | ||||||
|  | do save a factor of~2, because $x+y$ is always even. | ||||||
|  |  | ||||||
|  | @<Sub...@>= | ||||||
|  | void f(int x,int y) { | ||||||
|  |   register xx=x-1,y1=y,y2=y+1; | ||||||
|  |   if (have_f[x][y]!=tt+1) { | ||||||
|  |     applit(xx,y1,1,0),newlit(x,y,6,1),outclause(); | ||||||
|  |     applit(xx,y2,1,0),newlit(x,y,6,1),outclause(); | ||||||
|  |     applit(xx,y1,1,0),applit(xx,y2,1,0),newlit(x,y,6,2),outclause(); | ||||||
|  |     applit(xx,y1,0,0),applit(xx,y2,0,0),newcomplit(x,y,6,1),outclause(); | ||||||
|  |     applit(xx,y1,0,0),newcomplit(x,y,6,2),outclause(); | ||||||
|  |     if (xx>=xmin && xx<=xmax) | ||||||
|  |       applit(xx,y2,0,0),newcomplit(x,y,6,2),outclause(); | ||||||
|  |     have_f[x][y]=tt+1; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ The |g| subroutine cleans up the dregs, by somewhat tediously | ||||||
|  | locating the two neighbors that weren't handled by |d|, |e|, or~|f|. | ||||||
|  | No sharing is possible here. | ||||||
|  |  | ||||||
|  | @<Sub...@>= | ||||||
|  | void g(int x,int y) { | ||||||
|  |   register x1,x2,y1,y2; | ||||||
|  |   if (x&1) x1=x-1,y1=y,x2=x+1,y2=y^1; | ||||||
|  |   else x1=x+1,y1=y,x2=x-1,y2=y-1+((y&1)<<1); | ||||||
|  |   applit(x1,y1,1,0),newlit(x,y,7,1),outclause(); | ||||||
|  |   applit(x2,y2,1,0),newlit(x,y,7,1),outclause(); | ||||||
|  |   applit(x1,y1,1,0),applit(x2,y2,1,0),newlit(x,y,7,2),outclause(); | ||||||
|  |   applit(x1,y1,0,0),applit(x2,y2,0,0),newcomplit(x,y,7,1),outclause(); | ||||||
|  |   applit(x1,y1,0,0),newcomplit(x,y,7,2),outclause(); | ||||||
|  |   applit(x2,y2,0,0),newcomplit(x,y,7,2),outclause(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ Fortunately the |b| subroutine {\it can\/} be shared (since |x| is always | ||||||
|  | odd), thus saving half of the sixteen clauses generated. | ||||||
|  |  | ||||||
|  | @<Sub...@>= | ||||||
|  | void b(int x,int y) { | ||||||
|  |   register j,k,xx=x,y1=y-(y&2),y2=y+(y&2); | ||||||
|  |   if (have_b[x][y]!=tt+1) { | ||||||
|  |     d(xx,y1); | ||||||
|  |     e(xx,y2); | ||||||
|  |     for (j=0;j<3;j++) for (k=0;k<3;k++) if (j+k) { | ||||||
|  |       if (j) newcomplit(xx,y1,4,j); /* $\bar d_j$ */ | ||||||
|  |       if (k) newcomplit(xx,y2,5,k); /* $\bar e_k$ */ | ||||||
|  |       newlit(x,y,2,j+k); /* $b_{j+k}$ */ | ||||||
|  |       outclause(); | ||||||
|  |       if (j) newlit(xx,y1,4,3-j); /* $d_{3-j}$ */ | ||||||
|  |       if (k) newlit(xx,y2,5,3-k); /* $e_{3-k}$ */ | ||||||
|  |       newcomplit(x,y,2,5-j-k); /* $\bar b_{5-j-k}$ */ | ||||||
|  |       outclause();       | ||||||
|  |     } | ||||||
|  |     have_b[x][y]=tt+1; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ The (unshared) |c| subroutine handles the other four neighbors, | ||||||
|  | by working with |f| and |g| instead of |d| and~|e|. | ||||||
|  |  | ||||||
|  | If |y=0|, the overlap rules set |y1=-1|, which can be problematic. | ||||||
|  | I've decided to avoid this case by omitting |f| when it is | ||||||
|  | guaranteed to be zero. | ||||||
|  |  | ||||||
|  | @<Sub...@>= | ||||||
|  | void c(int x,int y) { | ||||||
|  |   register j,k,x1,y1; | ||||||
|  |   if (x&1) x1=x+2,y1=(y-1)|1; | ||||||
|  |   else x1=x,y1=y&-2; | ||||||
|  |   g(x,y); | ||||||
|  |   if (x1-1<xmin || x1-1>xmax || y1+1<ymin || y1>ymax) | ||||||
|  |     @<Set |c| equal to |g|@>@; | ||||||
|  |   else { | ||||||
|  |     f(x1,y1); | ||||||
|  |     for (j=0;j<3;j++) for (k=0;k<3;k++) if (j+k) { | ||||||
|  |       if (j) newcomplit(x1,y1,6,j); /* $\bar f_j$ */ | ||||||
|  |       if (k) newcomplit(x,y,7,k); /* $\bar g_k$ */ | ||||||
|  |       newlit(x,y,3,j+k); /* $c_{j+k}$ */ | ||||||
|  |       outclause(); | ||||||
|  |       if (j) newlit(x1,y1,6,3-j); /* $f_{3-j}$ */ | ||||||
|  |       if (k) newlit(x,y,7,3-k); /* $g_{3-k}$ */ | ||||||
|  |       newcomplit(x,y,3,5-j-k); /* $\bar c_{5-j-k}$ */ | ||||||
|  |       outclause(); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ @<Set |c| equal to |g|@>= | ||||||
|  | { | ||||||
|  |   for (k=1;k<3;k++) { | ||||||
|  |     newcomplit(x,y,7,k),newlit(x,y,3,k),outclause(); /* $\bar g_k\lor c_k$ */ | ||||||
|  |     newlit(x,y,7,k),newcomplit(x,y,3,k),outclause(); /* $g_k\lor\bar c_k$ */ | ||||||
|  |   } | ||||||
|  |   newcomplit(x,y,3,3),outclause(); /* $\bar c_3$ */ | ||||||
|  |   newcomplit(x,y,3,4),outclause(); /* $\bar c_4$ */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ Totals over all eight neighbors are then deduced by the |a| | ||||||
|  | subroutine. | ||||||
|  |  | ||||||
|  | @<Sub...@>= | ||||||
|  | void a(int x,int y) { | ||||||
|  |   register j,k,xx=x|1; | ||||||
|  |   b(xx,y); | ||||||
|  |   c(x,y); | ||||||
|  |   for (j=0;j<5;j++) for (k=0;k<5;k++) if (j+k>1 && j+k<5) { | ||||||
|  |     if (j) newcomplit(xx,y,2,j); /* $\bar b_j$ */ | ||||||
|  |     if (k) newcomplit(x,y,3,k); /* $\bar c_k$ */ | ||||||
|  |     newlit(x,y,1,j+k); /* $a_{j+k}$ */ | ||||||
|  |     outclause(); | ||||||
|  |   } | ||||||
|  |   for (j=0;j<5;j++) for (k=0;k<5;k++) if (j+k>2 && j+k<6 && j*k) { | ||||||
|  |     if (j) newlit(xx,y,2,j); /* $b_j$ */ | ||||||
|  |     if (k) newlit(x,y,3,k); /* $c_k$ */ | ||||||
|  |     newcomplit(x,y,1,j+k-1); /* $\bar a_{j+k-1}$ */ | ||||||
|  |     outclause(); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ Finally, as mentioned at the beginning, $z'$ is determined | ||||||
|  | from $z$, $a_2$, $a_3$, and $a_4$. | ||||||
|  |  | ||||||
|  | I actually generate six clauses, not five, in order to stick to | ||||||
|  | {\mc 3SAT}. | ||||||
|  |  | ||||||
|  | @<Sub...@>= | ||||||
|  | void zprime(int x,int y) { | ||||||
|  |   newcomplit(x,y,1,4),applit(x,y,1,1),outclause(); /* $\bar a_4\bar z'$ */ | ||||||
|  |   newlit(x,y,1,2),applit(x,y,1,1),outclause(); /* $a_2\bar z'$ */ | ||||||
|  |   newlit(x,y,1,3),applit(x,y,0,0),applit(x,y,1,1),outclause(); | ||||||
|  |                /* $a_3z\bar z'$ */ | ||||||
|  |   newcomplit(x,y,1,3),newlit(x,y,1,4),applit(x,y,0,1),outclause(); | ||||||
|  |                /* $\bar a_3a_4z'$ */ | ||||||
|  |   applit(x,y,0,7),newcomplit(x,y,1,2),newlit(x,y,1,4),outclause(); | ||||||
|  |                /* $x\bar a_2a_4$ */ | ||||||
|  |   applit(x,y,1,7),applit(x,y,1,0),applit(x,y,0,1),outclause(); | ||||||
|  |                /* $\bar x\bar zz'$ */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @*Index. | ||||||
		Reference in New Issue
	
	Block a user