SUBROUTINE CKDICT(FDB,LOCAT,WORD,INDICT,DEBUG,INDXS) C+ C SUBROUTINE CKDICT WILL CHECK THE DICTIONARY TO SEE IF THE C WORD GIVEN IS THERE. INDICT IS SET ACCORDING TO THE RESULT. C C FDB IS THE FILE DESCRIPTOR BLOCK FOR THE RAF. C LOCAT IS THE TABLE OF CONTENTS SET UP BE FIRST READ AFTER C RAF IS OPENED. (BLOCK=1) C C THE SEARCH METHOD HAS BEEN MODIFIED TO BE A BINARY SEARCH C WITH THE REGION TO SEARCH TO BE DIVIDED IN HALF UNTIL THE C WORD IS FOUND OR NOT FOUND WHEN THERE IS NOTHING LEFT TO C DIVIDE. THUS 6 COMPARES SHOULD BE NECESSARY ON THE AVERAGE C WHILE ON THE OLD COMPARE TO EACH WORD, 32 COMPARES WOULD C HAVE BEEN NECESSARY ON THE AVERAGE. C C ALSO THE LAST LETNUM AND M BLOCK ARE KEPT SO THAT IF THE C NEW LETNUM AND/OR M ARE THE SAME NO RECALCULATION OR READ C OF THE DICTIONARY IS NECESSARY. THIS PROBABLY WILL NOT OCCUR C UNLESS TWO WORDS HAVE THE SAME SEVERAL STARTING LETTERS. C NOT LIKELY BUT MIGHT AS WELL SAVE SOME TIME IF POSSIBLE. C C LOCAL VARIABLES C BUFNUM - DISK BLOCK NUMBER OF START OF THIS LETTER C IBUG - HOLDER OF WHICH ERROR WE CAME ACROSS C IHALF - DENOTES WORD NUMBER OF HALF OF CORRECT SIDE C LAST - DENOTES WORD NUMBER OF LAST OF CORRECT SIDE C LASTM - PLACE HOLDER OF THE LAST M FOUND C LBUF - MAKES LETBUF OCCUR ON INTEGER BOUNDRY C LETBLK - BLOCK NUMBER OF THE LOCATION OF THIS LETTER INDEX C LETNUM - NUMBER OF LETTER OF ALPHABET C LETTER - STORAGE FOR THE FIRST LETTER OF WORD C LSTLET - PLACE HOLDER FOR LAST LETTER FOUND C M - FIRST GUESS OF DISK BLOCK CONTAINING WORD C NEXT - START OF NEXT HALF FOR BINARY SEARCH C NUMBUF - NUMBER OF DISK BLOCKS FOR THIS LETTER IN DICT C NUMWRD - NUMBER OF WORDS FOUND IN THIS DISK BLOCK C PRVS - HAVE LOOKED AT PREVIOUS DISK BLOCK C SIZE - PART OF LOCAT CONTAINS THE NUMBER OF DISK BLOCKS C START - PART OF LOCAT CONTAINS THE NUMBER OF STRT BLOCK C DCTWRD - LIST OF WORDS FOUND FROM BLOCK READ C LETBUF - INDEX FOR THIS LETTER FROM DICT C C SUBROUTINES AND FUNCTIONS REFERENCED C GET - GET THEE WORDS FROM THIS DISK BLOCK C INDX - WHICH LETTER OF ALPHABET IS THIS LETTER C IRDBLK - DETERMINE WHICH BLOCK TO START LOOKING IN C C- PARAMETER (IBUFSZ=512) PARAMETER (MAXDIC=125) LOGICAL*1 INDICT,DEBUG,PRVS VIRTUAL INDXS(512,26) BYTE INDXS BYTE FDB(128),LETBUF(IBUFSZ) CHARACTER*25 WORD,LETTER*1,DCTWRD(MAXDIC) INTEGER*4 LOCAT(2,26) INTEGER*2 START,SIZE,BUFNUM,LBUF EQUIVALENCE (LBUF,LETBUF(1)) DATA START/1/SIZE/2/NUMWRD/125/ C INDICT=.FALSE. PRVS=.FALSE. LETTER=WORD(1:1) !GET FIRST LETTER LETNUM=INDX(LETTER) !INDEX VALUE IF(LETNUM.LT.1.OR.LETNUM.GT.26)RETURN !MUST START WITH LETTER IF(DEBUG)WRITE(3,1010)LETTER BUFNUM=LOCAT(START,LETNUM) !WHERE BUFFER STARTS NUMBUF=LOCAT(SIZE,LETNUM) !LENGTH THIS LETTER IN BLOCKS LETBLK=BUFNUM-1 !BLOCK NUMBER OF LETTER INDEX IF(DEBUG)WRITE(3,1020)BUFNUM,NUMBUF,LETBLK IF(LETNUM.NE.LSTLET)THEN DO 10,I=1,IBUFSZ !LOAD CORRECT 10 LETBUF(I)=INDXS(I,LETNUM) !...LETTER BUFFER END IF !...IF NOT LOADED M=IRDBLK( LETBUF, WORD, DEBUG ) +LETBLK !M=BLOCK IT IS IN IF(DEBUG)WRITE(3,1030)M IF(M.NE.LASTM)THEN !LOAD DICT LIST WITH BLK M CALL GET(FDB,M,DCTWRD,NUMWRD,MAXDIC) END IF 20 CONTINUE IF(DEBUG)THEN WRITE(3,1000)1,DCTWRD(1) WRITE(3,1000)NUMWRD,DCTWRD(NUMWRD) END IF IF(LLT(WORD,DCTWRD(1)))THEN !IF LT 1ST WORD, PREVIOUS BLK IBUG=1 IF(DEBUG)WRITE(3,1040)IBUG IF(M.LE.BUFNUM)GO TO 50 !BEFORE FIRST WORD OF THIS LET M=M-1 !TRY PREVIOUS PRVS=.TRUE. !WE READ A PREVIOUS BLOCK CALL GET(FDB,M,DCTWRD,NUMWRD,MAXDIC)!LOAD DICT LIST WITH BLK M IF(LGT(WORD,DCTWRD(NUMWRD)))THEN!IF GT THAN LAST WORD, NOT HERE IBUG=2 GO TO 50 !NOT HERE ELSE GO TO 20 !TEST THE BLOCK WE READ END IF END IF 30 CONTINUE IF(LGT(WORD,DCTWRD(NUMWRD)))THEN !IF GT LAST WORD, NEXT BLOCK IBUG=3 IF(DEBUG)WRITE(3,1040)IBUG IF(PRVS)GO TO 50 !NXT BLK ALRDY USD, SO NOT FOUND IBUG=4 IF(M.GE.BUFNUM+NUMBUF-1)GO TO 50!AFTER LAST WORD THIS LETTER M=M+1 !TRY NEXT BUFFER CALL GET(FDB,M,DCTWRD,NUMWRD,MAXDIC) IF(LLT(WORD,DCTWRD(1)))THEN !IF LT 1ST WRD, NOT HERE IBUG=5 GO TO 50 !NOT IN DICT ELSE GO TO 20 !RETEST THIS BLOCK END IF END IF C C THEREFORE WORD SHOULD BE IN THIS BLOCK OF WORDS C USE A BINARY SEARCH METHOD SINCE THE LIST IS IN ALPHABETICAL C ORDER. FOR A LONG LIST (64 WORDS) THIS SHOULD CUT THE C COMPARES TO A FOURTH OF THE AVERAGE NUMBER OF THE LAST C METHOD (COMPARE TO EACH). C LAST=0 !SET UP REGION AS WHOLE LIST NEXT=NUMWRD IHALF=NEXT 40 CONTINUE IF(DEBUG)WRITE(3,1000)IHALF,DCTWRD(IHALF) IF(WORD.EQ.DCTWRD(IHALF))THEN !IF WE FOUND IT IF(DEBUG)WRITE(3,1050)WORD INDICT=.TRUE. !SET FOUND FLAG AND DO CLEAN UP GO TO 60 END IF IF(NEXT-LAST.LE.1)THEN !NOT FOUND, NO WORDS BETWEEN? IBUG=6 !YEP, SO SET FOR DEBUG GO TO 50 !WRITE MESSAGE AND RETURN END IF IF(WORD.GT.DCTWRD(IHALF))LAST=IHALF !IF IN LAST HALF, BRING UP BOT IF(WORD.LT.DCTWRD(IHALF))NEXT=IHALF !IF IN 1ST HALF, LOWER TOP IHALF=(NEXT+LAST)/2 !DIVIDE REGION IN HALF FOR TEST GO TO 40 !GO TEST NEXT WORD 50 IF(DEBUG)THEN WRITE(3,1060)WORD !NOT FOUND, SAY SO. WRITE(3,1040)IBUG !HOW WE GOT HERE END IF 60 LASTM=M !SET FOR NEXT TIME TRU LSTLET=LETNUM !SET THIS ALSO RETURN !RETURN TO CALLING 1000 FORMAT(' DCTWRD(',I3,')=',A25) 1010 FORMAT(' LET=',A1) 1020 FORMAT(' B,N,L=',3(I3,2X)) 1030 FORMAT(' M=',I3) 1040 FORMAT(' ?',I1) 1050 FORMAT(' ',A25,' FOUND') 1060 FORMAT(' ',A25,' NOT FOUND') END