BLOCK UNIT BACKTRACK: CLASS; HIDDEN SE,ELEM,TOP; VAR ROOT:NODE,SEARCH:SE,FOUND,OPT:NODE, NUMBER_OF_NODES,NUMBER_OF_LEAVES,NUMBER_OF_ANSWERS:INTEGER; UNIT NODE: COROUTINE(FATHER:NODE); VAR NSONS,LEVEL: INTEGER , DEADEND:BOOLEAN; UNIT VIRTUAL LEAF: FUNCTION :BOOLEAN; END LEAF; UNIT VIRTUAL ANSWER :FUNCTION :BOOLEAN; END ANSWER; UNIT VIRTUAL LASTSON: FUNCTION : BOOLEAN; END LASTSON; UNIT VIRTUAL NEXTSON: FUNCTION : NODE; END NEXTSON; UNIT VIRTUAL EQUAL : FUNCTION (W:NODE):BOOLEAN; END EQUAL; UNIT VIRTUAL COST: FUNCTION :REAL; END COST; BEGIN IF FATHER =/= NONE THEN LEVEL:=FATHER.LEVEL+1 ELSE LEVEL:=0 FI; END NODE; UNIT OK: FUNCTION (V:NODE):BOOLEAN; VAR W:NODE; BEGIN IF V=NONE THEN RESULT:=FALSE; RETURN FI; RESULT:=TRUE; W:=V.FATHER; WHILE W =/= NONE DO IF V.EQUAL(W) THEN RESULT:=FALSE; RETURN FI; W:=W.FATHER OD END OK; UNIT PURGE: PROCEDURE (V:NODE); VAR W: NODE; BEGIN IF V=NONE THEN RETURN FI; DO W:=V.FATHER; KILL(V); IF W=NONE THEN RETURN FI; W.NSONS:=W.NSONS-1; IF W.NSONS =/= 0 THEN RETURN FI; V:=W OD; END PURGE; VAR TOP:ELEM; UNIT ELEM: CLASS (NEXT:ELEM, V:NODE); END ELEM; UNIT VIRTUAL INSERT: PROCEDURE(V:NODE); BEGIN TOP:=NEW ELEM(TOP,V); END INSERT; UNIT VIRTUAL DELETE: FUNCTION :NODE; VAR E:ELEM; BEGIN IF TOP =/= NONE THEN RESULT:=TOP.V; E:=TOP; TOP:=TOP.NEXT; KILL(E); FI; END DELETE; UNIT SE: COROUTINE ; VAR I:INTEGER,V,W:NODE; BEGIN RETURN; CALL INSERT(ROOT); DO V:=DELETE; IF V=NONE THEN EXIT FI; ATTACH(V); IF V.ANSWER THEN NUMBER_OF_ANSWERS:=NUMBER_OF_ANSWERS+1; FOUND:=V; IF OPT=NONE ORIF V.COST < OPT.COST THEN OPT:=V FI; DETACH; (* HERE THE USER OF BACKTRACK MAY UNDERTAKE SOME ACTIONS ON THE ANSWER NODES. IF NOT NECESSARY DO ATTACH *) ELSE IF V.DEADEND THEN NUMBER_OF_LEAVES:=NUMBER_OF_LEAVES+1; CALL PURGE(V); ELSE DO W:=V.NEXTSON; V.NSONS:=V.NSONS+1; NUMBER_OF_NODES:=NUMBER_OF_NODES+1; IF OK(W) THEN W.DEADEND:=W.LEAF; CALL INSERT(W); FI; IF V.LASTSON THEN EXIT FI; OD; FI; FI; OD; FOUND:=NONE; END SE; UNIT KILLALL :PROCEDURE; VAR V:NODE; BEGIN DO V:=DELETE; IF V=NONE THEN RETURN FI; CALL PURGE(V); OD; END KILLALL; BEGIN SEARCH:=NEW SE; INNER; KILL(SEARCH); CALL KILLALL; END BACKTRACK; VAR N,M,I,J:INTEGER,H1,H2,H3:CHAR; VAR INC: ARRAYOF ARRAYOF BOOLEAN; BEGIN DO WRITE(" NUMBER OF VERTICES= "); READLN(N); IF N=0 THEN EXIT FI; WRITE(" NUMBER OF COLOURS= "); READLN(M); ARRAY INC DIM (1:N); FOR I:=1 TO N DO ARRAY INC(I) DIM (1:I); OD; WRITELN(" GIVE A GRAPH BY DEFINING SUCCESSIVE EDGES"); WRITELN(" TO END A LIST WRITE 0"); FOR I:=1 TO N DO WRITELN(" VERTEX ",I:3," IS INCIDENT WITH VERTICES="); DO READ(J); IF J>1 AND J<=N THEN INC(J,I):=TRUE ELSE EXIT FI; OD; WRITELN(" END OF EDGES WITH VERTEX", I:3) OD; WRITELN(" GRAPH HAS THE FOLLOWING INCIDENCE MATRIX"); FOR I:=1 TO N DO FOR J:=1 TO I DO IF INC(I,J) THEN WRITE(1:2) ELSE WRITE(0:2) FI; OD; WRITELN; OD; PREF BACKTRACK BLOCK VAR K:INTEGER; UNIT STATE: NODE CLASS(I,J,NC:INTEGER); (*I- VERTEX, J-COLOUR, NC-NUMBER OF COLOURS *) UNIT VIRTUAL ANSWER: FUNCTION: BOOLEAN; BEGIN RESULT:= I=N AND OKGO(THIS STATE) END ANSWER; UNIT VIRTUAL LEAF: FUNCTION :BOOLEAN; BEGIN RESULT:=I=N OR NOT OKGO(THIS STATE) END LEAF; UNIT OKGO: FUNCTION(V:STATE) : BOOLEAN; VAR I,J:INTEGER; BEGIN I:=V.I; J:=V.J; DO V:=V.FATHER; IF V=NONE THEN RESULT:=TRUE; EXIT FI; IF V.J=J AND INC(I,V.I) THEN EXIT FI; OD; END OKGO; UNIT VIRTUAL LASTSON: FUNCTION :BOOLEAN; BEGIN IF K=M THEN RESULT:=TRUE; K:=0; FI; END LASTSON; UNIT VIRTUAL NEXTSON : FUNCTION :STATE; VAR V:STATE,NCK:INTEGER; BEGIN V:=THIS STATE; K:=K+1; NCK:=NC; DO IF V=NONE THEN NCK:=NCK+1; EXIT FI; IF V.J=K THEN EXIT FI; V:=V.FATHER; OD; RESULT:=NEW STATE(THIS STATE,I+1,K,NCK); END NEXTSON; UNIT VIRTUAL EQUAL: FUNCTION(S:STATE):BOOLEAN; BEGIN RESULT:=I=S.I AND J=S.J END EQUAL; UNIT VIRTUAL COST: FUNCTION :REAL; BEGIN RESULT:=NC END COST; BEGIN RETURN; DO DETACH OD; END STATE; UNIT DISPLAY: PROCEDURE(V:STATE); BEGIN IF V=NONE THEN WRITELN(" NO SOLUTIONS"); RETURN FI; WRITELN("VERTEX COLOUR"); DO WRITE(V.I); WRITE(" "); WRITELN(V.J); V:=V.FATHER; IF V=NONE THEN EXIT FI OD; WRITELN; END DISPLAY; BEGIN READLN; ROOT:=NEW STATE(NONE,1,1,1); WRITE("DO YOU WANT TO OPTIMIZE "); WRITELN("OR TO PRINT ALL THE SOLUTIONS ?"); WRITELN(" (ANSWER OPT OR ALL)"); READLN(H1,H2,H3); IF H1='O' AND H2='P' AND H3='T' THEN DO ATTACH(SEARCH); IF FOUND=NONE THEN EXIT FI; IF OPT =/= NONE ANDIF OPT.COST