	REM -------FILE BIBSR2.BAS

	REM SEGMENT TWO OF BIBLIOGRAPHY SEARCH PROGRAM
	COMMON KEYWD$(1),LIBNAME$,RLEN%,TRUE%,AUTH.LEN5,TITL.LEN%
	COMMON MAXBIB%,MAXDESC%,MAXDEF%,MAXKEYS%,MAXCON%,CONCEPT$(1)
	COMMON ISS.LEN%,CLS$,ERR%,JOUR.LEN%,KWD,LEN%,CMD$(1)
	COMMON LFT%(1),RGHT%(1),CON.KEY%(2),CON.RATE(2),QUERY$,L%

	DIM OP.STK$(MAXCON%),V.STK(MAXCON%), ART.KEY%(MAXDESC%)
	DIM RPT%(11), ART.VAL(MAXDESC%),V(MAXCON%),RATING%(MAXBIB%)

	REM FUZZY LOGICAL FUNCTIONS
	DEF FN.ZADEH(A,B,CH$)
	ERR%=0
	IF CH$="*" THEN 4E1
	IF CH$="*" THEN 4.1E1
	IF CH$<>"*" THEN FN.ZADEH=0 : ERR%=3 : RETURN
	IF B>(1.0-A) THEN FN.ZADEH=B ELSE FN.ZADEH=1.0-A
	RETURN

	REM CONVERT TWO ASCII HEX TO INTEGER
	DEF FN.TWO.INT%(DUM$)
	TEN%=ASC(MID$(DUM$,1,1))
	IF TEN%>64 THEN TEN%=TEN%-55 ELSE TEN%=TEN%-48
	ONE%=ASC(MID$(DUM$,2,1))
	IF ONE%>64 THEN ONE%=ONE%-55 ELSE ONE%=ONE%-48
	FN.TWO.INT%=16*TEN%+ ONE%
	RETURN
	FEND

	REM CONVERT ONE ASCII HEX TO REAL
	DEF FN.ONEREAL(DUM$)
	ONE%=ASC(MID$(DUM$,3,1))
	IF ONE%>64 THEN ONE%=ONE%-55 ELSE ONE%=ONE%-48
	FN.ONEREAL=ONE%/10.0
	RETURN
	FEND

4E1     IF A<B THEN FN.ZADEH=A ELSE FN.ZADEH=B
	RETURN

4.1E1   IF A>B THEN FN.ZADEH=A ELSE FN.ZADEH=B
	RETURN
	FEND

	GOSUB 19E1
	CHAIN "BIBLIO"
	STOP

3E1     REM BUILD STRING Y$ FROM QUERY$ BY REPLACING CONCEPT
	REM NAMES WITH THEIR VALUES
	Y$="" : Y$=LEFT$(QUERY$,LFT%(1)-1):LFT%(L%+1)=LEN(QUERY$)+1
	FOR I%=1 TO L%
  	V$=STR$(V(I%)):Y$=Y$+V$+MID$(QUERY$,RGHT%(I%),LFT%(I%+1)-RGHT%(I%))
  	NEXT I%
	RETURN

2E1     REM REDUCE Y$ BY PERFORMING FUZZY LOGICAL OPS
	J%=1 : L1%=LEN(Y$)
	IF LEFT$(Y$,1)<>"(" THEN RETURN
	WHILE MID$(Y$,J%,1)<>")"
  	J%=J%+1 
	WEND
	I%=J%
	WHILE MID$(Y$,I%,1)<>"("
  	I%=I%-1  
	WEND
	I%=I%+1:M%=I%:V.PTR%=MAXCON% : OP.PTR%=MAXCON%

2.2E1   K%=M%
	WHILE (ASC(MID$(Y$,K%,1))>=44)
  	K%=K%+1  
	WEND
	V.STK(V.PTR%)=VAL(MID$(Y$,M%,K%-M%)):V.PTR%=V.PTR%-1
	IF K%-J% THEN 2.1E1
	OP.STK$(OP.PTR%)=MID$(Y$,K%,1):OP.PTR%=OP.PTR%-1:M%=K%+1:GOTO 2.2E1

2.1E1   WHILE OP.PTR%<MAXCON%
  	OP.PTR%=OP.PTR%+1 : OP$=OP.STK$(OP.PTR%)
  	V.PTR%=V.PTR%+1   : V1=V.STK(V.PTR%)
  	V.PTR%=V.PTR%+1   : V2=V.STK(V.PTR%)
  	T=FN.ZADEH(V1,V2,OP$)
  	IF ERR% THEN RETURN
  	V.STK(V.PTR%)=T  :  V.PTR%=V.PTR%-1
  	WEND
	V.PTR%=V.PTR%+1  :  V1=V.STK(V.PTR%)
	IF MID$(Y$,J%+1,1)="'" THEN V1=1.0-V1 : \
  	Y$=LEFT$(Y$,I%-2)+STR$(V1)+RIGHT$(Y$,L1%-J%-1) \
  	ELSE Y$=LEFT$(Y$,I%-2)+STR$(V1)+RIGHT$(Y$,L1%-J%):GOTO 2E1
	RETURN

19E1    REM READ IN BIBLIO AND CALCULATE SATISFACTION LEVELS
	IF END #2 THEN 20.1E1
	BIB.LEN%=0 : DESC.BEG%=AUTH.LEN%+TITL.LEN%+JOUR.LEN%+ISS.LEN%+1
	OPEN LIBNAME$+".BIB" AS 2 BUFF 16 RECS 128
	READ #2; LINE BUFF$
	WHILE TRUE%
  	READ #2; LINE BUFF$
  	BIB.LEN%=BIB.LEN%+1
  	IF LEFT$(BUFF$,5)="zzzzz" THEN RATING%(BIB.LEN%)=0 : GOTO 19.5E1
  	REM DECODE DESCRIPTORS
  	K%=DESC.BEG% : DESC.NO%=0
  	WHILE TRUE%
    	DUM$=MID$(BUFF$,K%,3)
    	IF DUM$="FFF" THEN 19.1E1
    	DESC.NO%=DESC.NO%+1:ART.KEY%(DESC.NO%)=FN.TWO.INT%(DUM$)
    	ART.VAL(DESC.NO%)=FN.ONEREAL(DUM$):K%=K%+3
    	WEND

19.1E1  REM DETERMINE ARTICLE VALUE V(J%) FOR EACH CONCEPT
	FOR J%=1 TO L%
  	KEY%=1 : MIN=1.0 : MAX=0.0
  	WHILE CON.KEY%(J%,KEY%)<>0
    	REM FIND MATCHING ART.KEY%
    	RAL=0.0
    	FOR I%=1 TO DESC.NO%
      	IF ART.KEY%(I%)=CON.KEY%(J%,KEY%) THEN RAL=ART.VAL(I%)
      	NEXT I%
    	IF RAL<CON.RATE(J%,KEY%) THEN MIN=RAL ELSE MIN=CON.RATE(J%,KEY%)
    	IF MIN>MAX THEN MAX=MIN
    	KEY%=KEY%+1
    	WEND
  	V(J%)=MAX
  	NEXT J%
	GOSUB 3E1:GOSUB 2E1
	IF ERR% THEN 22E1
	RATING%(BIB.LEN%)=10*VAL(Y$)

19.5E1  WEND

20.1E1  CLOSE 2

21E1    REM SEARCH OVER RATINGS TO COMPUTE *ARTICLES VS RATINGS
	FOR I%=1 TO 11 : RPT%(I%)=0 : NEXT I%
	FOR I%=1 TO BIB.LEN%:K%=RATING%(I%)+1:RPT%(K%)=RPT%(K%)+1:NEXT I%
	FOR I%=10 TO 1 STEP -1:RPT%(I%)=RPT^(I%)+RPT^(I%+1):NEXT I%

21.3E1  PRINT CLS$
	PRINT TAB(11); "NUMBER OF ARTICLES THAT MEET OR EXCEED RATING OF"
	PRINT TAB(28); "0.0.....1.0":PRINT
	PRINT TAB(11);"RATINGS";TAB(22);"#ARTICLES";
	PRINT TAB(39);"RATINGS";TAB(50);"#ARTICLES":PRINT
	FOR I%=1 TO 6
  	FOR K%=0 TO 1
    	IND%=I%+6*K%
    	IF IND%>11 THEN 21.9E1
    	PRINT USING "#.#";TAB(13+28*K%); (IND%-1)/10.0;
    	PRINT USING "###"; TAB(24+28*K%); RPT%(IND%);
    	NEXT K%

21.9E1  PRINT
	NEXT I%:PRINT

	REM FIND AND LIST ARTICLES THAT MEET MINIMUM THRESHOLD
	INPUT "ENTER MINIMUM RATING DESIRED FOR ARTICLE PRINTOUT: ";MINRAT
	GOSUB 24E1
	OPEN LIBNAME$+".BIB" RECL RLEN% AS 2
	I%=0
	IF END #2 THEN 21.2E1
	WHILE I%<BIB.LEN%
	I%=I%+1
  	IF RATING%(I%) < INT%(10.0*MINRAT) THEN 21.1E1
  	READ #2,I%+1; LINE BUFF$
  	GOSUB 25E1

21.1E1  WEND

21.2E1  CLOSE 2:CONSOLE
	INPUT "DO YOU WISH TO RE-SEARCH WITH DIFFERENT THRESHOLD(Y/N) ";ANS$
	IF UCASE$(LEFT$(ANS$,1))="Y" THEN 21.3E1
	FOR I%=1 TO MAXCON% : OP.STK$(I%)="" : NEXT I%
	RETURN

22E1    PRINT "INVALID FUZZY OPERATOR IN INTERROGATION PHRASE"
	INPUT "PRESS RETURN TO RESTART SEARCH ROUTINE "; LINE ANS$
	CHAIN "BIBSRCH"

24E1    REM PRINT OUTPUT HEADER INFO
	INPUT "DO YOU WISH A PRINTED OUTPUT (Y/N)? "; PRNT$
	IN%=1 : LLEN%=63
	IF UCASE$(LEFT$(PRNT$,1))="Y" THEN LPRINTER:IN%=6:LLEN%=79
        FOR IP%=1 TO 5:PRINT:NEXT IP%
	PRINT TAB(21); "Fuzzy Search of Library "; LIBNAME$
	PRINT TAB(IN%) ;
	FOR IP%=1 TO 63 : PRINT "-"; : NEXT IP% : PRINT
	PRINT TAB(IN%); "Interrogation Phrase :"
	PRINT TAB(IN%+3); QUERY
	PRINT TAB(IN%); "Interrogation Phrase Definitions :"
	FOR IP%=1 TO L%
  	PRINT TAB(IN%+3) ; CONCEPT$(IP%) ; " : ";
  	PRINT CMD$(IP%)
  	NEXT IP%
	PRINT TAB(IN%); "Selection Level : ";
	PRINT USING "#.#"; MINRAT
	PRINT TAB(IN%);
	FOR IP%=1 TO 63 : PRINT "-"; : NEXT IP% : PRINT
	LCNT%=L%+13:RETURN

25E1    REM PRINT ARTICLE DATE
	SP%=IN%+5
	IF JOUR.LEN%>ISS.LEN% THEN SP%=SP%+JOUR.LEN% ELSE SP%=SP%+ISS.LEN%
	IF LCNT%>57 THEN \
           FOR IP%=1 TO 71-LCNT%:PRINT:NEXT IP%:LCNT%=LCNT%+5
	PRINT TAB(IN%);"Record : ";
	PRINT USING "####"; I%;
	IF (SP%+11)>LLEN% THEN PRINT TAB(IN%);:LCNT%=LCNT%+1: \
           ELSE PRINT TAB(SP%);
	PRINT "Level : ";:PRINT USING "#.#"; RATING%(I%)/10.0
	PRINT TAB(IN%); MID$(BUFF$,AUTH.LEN%+TITL.LEN%+1,JOUR.LEN%);
	IF (SP+TITL.LEN%)>LLEN% THEN PRINT TAB(IN%); : LCNT%=LCNT%+1 : \
  	   ELSE PRINT TAB(SP%)
	PRINT MID$(BUFF$,AUTH.LEN%+1,TITL.LENT%)
	PRINT TAB(IN%);MID$(BUFF$,AUTH.LEN%+TITL.LEN%+JOUR.LEN%+1,ISS.LEN%);
	IF (SP%+AUTH.LEN%)>LLEN% THEN PRINT TAB(IN%); : LCNT%=LCNT%+1 : \
  	   ELSE PRINT TAB(SP%);
	PRINT LEFT$(BUFF$,AUTH.LEN%):PRINT:LCNT%=LCNT%+4:RETURN

