Annotation of researchv9/cmd/emacs/hyde.c, revision 1.1.1.1

1.1       root        1: #include <stdio.h>
                      2: #define trace if (traceon) printf
                      3: 
                      4: extern FILE *popen();
                      5: extern char *getenv();
                      6: extern char *malloc();
                      7: 
                      8: /* HYpothesis Driven Expert */
                      9: 
                     10: struct ref {
                     11:        struct ref *next;
                     12:        struct defblk *this;
                     13:        char *text;
                     14: };
                     15: struct defblk {
                     16:        struct defblk *next;
                     17:        char *name;
                     18:        int type;
                     19:        struct ref *definition;
                     20: };
                     21: struct conc {
                     22:        int weight;
                     23:        struct hype *hypo;
                     24:        int vector;
                     25:        int num;
                     26:        struct fact *confirms[];
                     27: };
                     28: struct fact {
                     29:        struct fact *next;
                     30:        struct defblk *name;
                     31:        int truth;
                     32:        struct concr *setlist;
                     33: };
                     34: 
                     35: struct concr {
                     36:        struct concr *next;
                     37:        struct conc *this;
                     38: };
                     39: struct hype {
                     40:        struct hype *next;
                     41:        struct defblk *name;
                     42:        int confid;
                     43:        short asked;
                     44:        short action;
                     45:        struct ref *queries;
                     46:        char *text;
                     47:        char *explain;
                     48: };
                     49: 
                     50: #define NHASH 255
                     51: struct defblk *hashtable[NHASH];
                     52: 
                     53: 
                     54: #define FACT 1
                     55: #define HYPO 2
                     56: #define STRING 3
                     57: 
                     58: #define ASK 1
                     59: #define SCAN 2
                     60: #define RUN 3
                     61: 
                     62: #define FUNKNOWN 0
                     63: #define FTRUE 1
                     64: #define FFALSE -1
                     65: 
                     66: #define HUNCERTAIN 10
                     67: #define HTRUE 100
                     68: #define HFALSE 0
                     69: 
                     70: struct hype *hypes;
                     71: struct fact *facts;
                     72: 
                     73: int tot_facts;
                     74: int tot_hypes;
                     75: int traceon = 0;
                     76: FILE *kfile;
                     77: 
                     78: #define SYMCHAR 1
                     79: #define WHITE 2
                     80: char ctype[128] = {
                     81:        0,      0,      0,      0,      0,      0,      0,      0,
                     82:        0,      WHITE,  WHITE,  0,      0,      0,      0,      0,
                     83:        0,      0,      0,      0,      0,      0,      0,      0,
                     84:        0,      0,      0,      0,      0,      0,      0,      0,
                     85:        WHITE,  0,      0,      0,      0,      0,      0,      0,
                     86:        0,      0,      0,      0,      0,      0,      0,      0,
                     87:        SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,
                     88:        SYMCHAR,SYMCHAR,0,      0,      0,      0,      0,      0,
                     89:        0,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,
                     90:        SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,
                     91:        SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,
                     92:        SYMCHAR,SYMCHAR,SYMCHAR,0,      0,      0,      0,      SYMCHAR,
                     93:        0       ,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,
                     94:        SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,
                     95:        SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,SYMCHAR,
                     96:        SYMCHAR,SYMCHAR,SYMCHAR,0,      0,      0,      0,      0
                     97: };
                     98: #define streq(x,y) (strcmp(x,y) == 0)
                     99: 
                    100: struct defblk *getref(name,type,create)
                    101: 
                    102: /* Keywords: symbol-table:50 internal-database:50 */
                    103: 
                    104: char *name;
                    105: int type;
                    106: int create;
                    107: {
                    108:        int hash;
                    109:        char *np;
                    110:        struct defblk *defp;
                    111: 
                    112:        np = name;
                    113:        hash = 0;
                    114:        while (*np) hash += *np++;
                    115:        hash = hash %NHASH;
                    116:        defp = hashtable[hash];
                    117:        while (defp && strcmp(name,defp->name)) defp = defp->next;
                    118:        if (defp == NULL) {
                    119:                struct fact *factp;
                    120:                struct hype *hypep;
                    121: 
                    122:                if (create == 0) return(NULL);
                    123:                defp = ((struct defblk *) malloc(sizeof(*defp)));
                    124:                defp->next = hashtable[hash];
                    125:                hashtable[hash] = defp;
                    126:                defp->name = (char *) malloc(strlen(name)+1);
                    127:                strcpy(defp->name,name);
                    128:                defp->type = type;
                    129:                switch(type) {
                    130: 
                    131:                case STRING:
                    132:                        defp->definition = NULL;
                    133:                        break;
                    134:                case FACT:
                    135:                
                    136:                        tot_facts++;
                    137:                        defp->definition = (struct ref *) malloc(sizeof(*factp));
                    138:                        factp = (struct fact *) defp->definition;
                    139:                        factp->name = defp;
                    140:                        factp->next = facts;
                    141:                        facts = factp;
                    142:                        factp->truth = FUNKNOWN;
                    143:                        factp->setlist = NULL;
                    144:                        trace ("Defining fact %s\n",name);
                    145:                        break;
                    146:                case HYPO:
                    147:                        tot_hypes++;
                    148:                        defp->definition = (struct ref *) malloc(sizeof(*hypep));
                    149:                        hypep = (struct hype *) defp->definition;
                    150:                        hypep -> name = defp;
                    151:                        hypep -> next = hypes;
                    152:                        hypes = hypep;
                    153:                        hypep -> asked = 0;
                    154:                        hypep -> confid = HUNCERTAIN;
                    155:                        hypep -> text = NULL;
                    156:                        hypep -> explain = NULL;
                    157:                        hypep -> queries = NULL;
                    158:                        trace ("Defining hypothesis %s\n",name);
                    159:                        break;
                    160:                }
                    161:        } else {
                    162:                if (type && (type != defp->type)) {
                    163:                        fprintf(stderr,"Multiply defined symbol: %s\n",name);
                    164:                }
                    165:        }
                    166:        return(defp);
                    167: }
                    168: 
                    169: char expbuf[512];
                    170: 
                    171: char *expcom(oldcom)
                    172: register char *oldcom;
                    173: {
                    174:        register char *newcom;
                    175:        char symbuf[128];
                    176:        char *symp;
                    177:        struct defblk *defp;
                    178:        struct fact *factp;
                    179:        int infalse;
                    180:        newcom = expbuf;
                    181: 
                    182:        while (*oldcom) {
                    183:                switch (*oldcom) {
                    184:                        
                    185:                case '\\':
                    186:                        *newcom++ = * ++oldcom;
                    187:                        break;
                    188:                case '%':
                    189:                        oldcom++;
                    190:                        symp = symbuf;
                    191:                        while ((ctype[*oldcom] & SYMCHAR)==0) oldcom++;
                    192:                        while ((ctype[*oldcom] & SYMCHAR)) *symp++ = *oldcom++;
                    193:                        *symp = 0;
                    194:                        defp = getref(symbuf,0,0);
                    195:                        if (defp ) switch(defp->type) {
                    196:                        case STRING:
                    197:                                symp = (char *) defp->definition;
                    198:                                while (*symp) *newcom++ = *symp++;
                    199:                                oldcom--;
                    200:                                break;
                    201:                        case FACT:
                    202:                                factp = (struct fact *) defp->definition;
                    203:                                while (*oldcom != '(' ) oldcom++;
                    204:                                infalse = 0;
                    205:                                oldcom++;
                    206:                                while (1) {
                    207:                                        switch (*oldcom) {
                    208:                                        case 0:
                    209:                                        case ')':
                    210:                                                goto done;
                    211:                                        case ':':
                    212:                                                infalse++;
                    213:                                                break;
                    214:                                        case '\\':
                    215:                                                ++oldcom;
                    216:                                        default:
                    217:                                                if (((factp->truth == FTRUE) && (infalse == 0)) ||
                    218:                                                        ((factp->truth == FFALSE) && (infalse))) {
                    219:                                                                 
                    220:                                                        *newcom++ = *oldcom;
                    221:                                                }
                    222:                                                break;
                    223:                                        }
                    224:                                        oldcom++;
                    225:                                }
                    226:                        } else {
                    227:                                fprintf(stderr,"%s is undefined on expansion",symbuf);
                    228:                        }
                    229: done:                  break;
                    230:                default:
                    231:                        *newcom++ = *oldcom;
                    232:                }
                    233:                oldcom++;
                    234:        }
                    235:        *newcom= 0;
                    236:        trace ("Expanded into %s\n",expbuf);
                    237:        return(expbuf);
                    238: }
                    239: 
                    240: 
                    241: struct hype * curhype()
                    242: {
                    243:        struct hype *hype,*rehype;
                    244:        int maxhype;
                    245:        
                    246:        maxhype = HUNCERTAIN;           /* Cut off any below this level */
                    247:        rehype = NULL;
                    248:        for (hype = hypes; hype; hype = hype-> next) if ((hype->asked==0) && (hype->confid > maxhype)) {
                    249:                maxhype = hype->confid;
                    250:                rehype = hype;
                    251:        }
                    252:        trace ("Best hypothesis is %s\n",rehype->name->name);
                    253:        return(rehype);
                    254: }
                    255: reset()
                    256: {
                    257:        struct fact *factp;
                    258:        struct hype *hypep;
                    259:        struct defblk *defp;
                    260:        int i;
                    261:        
                    262:        for (i = 0; i < NHASH; i++) {
                    263:                for (defp = hashtable[i]; defp; defp = defp->next) {
                    264:                        if (defp->type == STRING) defp->definition = NULL;
                    265:                }
                    266:        }
                    267:        for (factp = facts; factp; factp = factp->next) factp->truth=FUNKNOWN;
                    268:        for (hypep = hypes; hypep; hypep = hypep->next) {
                    269:                hypep->confid = HUNCERTAIN;
                    270:                hypep->asked = 0;
                    271:        }
                    272:        defp = getref("start",FACT,1);
                    273:        setfact(defp->definition,FTRUE);                /* Start up the inference engine */
                    274: }
                    275: 
                    276: askhype(hype)
                    277: struct hype *hype;
                    278: {
                    279:        char buf[20];
                    280:        struct defblk *defp;
                    281:        struct ref *refp;
                    282:        struct fact *factp;
                    283:        struct fact *factors[20];
                    284:        int truth[20];
                    285:        int nfact = 0;
                    286:        int i;
                    287:        char *bufp;
                    288:        FILE *fp;
                    289:        
                    290:        trace ("Asking about hypothesis %s\n",hype->name->name);
                    291:        refp = hype->queries;
                    292:        while (refp) {
                    293:                defp = refp->this;
                    294:                if (defp->type == STRING) {
                    295:                        if (defp->definition) return(0);
                    296:                        goto setup;
                    297:                }
                    298:                factp = (struct fact *) defp->definition;
                    299:                trace ("Sub-fact %s, state %d\n",factp->name->name,factp->truth);
                    300:                if (factp->truth == FUNKNOWN) {
                    301:                        if (nfact == 0) {
                    302: setup:                         switch (hype->action) {
                    303:                                case ASK: printf ("%s\n\n",expcom(hype->text));
                    304:                                        if (defp->type == STRING) {
                    305:                                                gets(buf);
                    306:                                                defp->definition = (struct ref *) malloc(strlen(buf)+1);
                    307:                                                strcpy(defp->definition,buf);
                    308:                                                return(1);
                    309:                                        }
                    310:                                        break;
                    311:                                case SCAN:
                    312:                                        fp = fopen(hype->text,"r");
                    313:                                        trace ("Scanning %s from hypothesis %s\n", hype->text,hype->name->name);
                    314:                                        fmatch(fp,hype->queries);
                    315:                                        fclose(fp);
                    316:                                        return(1);
                    317:                                case RUN:
                    318:                                        fp = popen(expcom(hype->text),"r");
                    319:                                        trace ("Running %s from hypothesis %s\n", hype->text,hype->name->name);
                    320:                                        fmatch(fp,hype->queries);
                    321:                                        pclose(fp);
                    322:                                        return(1);
                    323:                                }
                    324:                        }
                    325:                        factors[nfact++] = factp;
                    326:                        printf ("       %d) %s\n",nfact,refp->text);
                    327:                }
                    328:                refp = refp->next;
                    329:        }
                    330:        if (nfact == 0) return(0);
                    331:        
                    332:        printf ("\n? ");
                    333: again: gets(buf);
                    334:        for (i = 0; i < nfact; i++) truth[i] = FFALSE;
                    335:        for (bufp = buf; *bufp; bufp++) {
                    336:                if (*bufp == 't') {
                    337:                        traceon = !traceon;
                    338:                        continue;
                    339:                }
                    340:                if (*bufp == '!') {
                    341:                        bufp++;
                    342:                        if (*bufp == 0) {
                    343:                                bufp = getenv("SHELL");
                    344:                                if ((bufp == NULL) || (*bufp == 0)) bufp= "/bin/sh";
                    345:                        }
                    346:                        system (bufp);
                    347:                        return(askhype(hype));
                    348:                }
                    349:                if (*bufp == 'q') return(-1);
                    350:                if ((*bufp < '1') || (*bufp > '0'+nfact)) {
                    351:                        if ((*bufp == ' ') || (*bufp == ',')) continue;
                    352:                        printf ("Please type all of the numbers that apply\n");
                    353:                        goto again;
                    354:                }
                    355:                truth[*bufp-'1'] = FTRUE;
                    356:        }
                    357:        for (i = 0; i < nfact; i++) {
                    358:                setfact(factors[i],truth[i]);
                    359:        }
                    360:        return(1);
                    361: }
                    362: 
                    363: setfact(factp,truth)
                    364: struct fact *factp;
                    365: int truth;
                    366: {
                    367:        struct hype *hype;
                    368:        struct conc *concp;
                    369:        struct concr *refp;
                    370:        int trigger;
                    371:        int i;
                    372:        
                    373:        factp->truth = truth;
                    374:        
                    375:        trace ("Setting fact %s to %d\n",factp->name->name,truth);
                    376:        
                    377:        for (refp = factp->setlist; refp; refp = refp ->next) {
                    378:                concp = refp->this;
                    379:                trigger = 1;
                    380:                for (i = 0;(trigger && (i < concp->num)); i++) {
                    381:                        if (concp->confirms[i]->truth == FUNKNOWN) trigger = 0;
                    382:                        else {
                    383:                                if ((concp->vector>>i) & 1) {
                    384:                                        if (concp->confirms[i]->truth == FFALSE) trigger = 0;
                    385:                                } else {
                    386:                                        if (concp->confirms[i]->truth == FTRUE) trigger = 0;
                    387:                                }
                    388:                        }
                    389:                }
                    390:                if (trigger) {
                    391:                        sethype(concp->hypo,concp->weight);
                    392:                }
                    393: 
                    394:        }
                    395: }
                    396: 
                    397: sethype(hype,weight)
                    398: 
                    399: struct hype *hype;
                    400: int weight;
                    401: {
                    402: 
                    403:        if (hype->name->type == FACT) {
                    404:                struct fact *factp;
                    405:                factp = (struct fact *) hype;
                    406:                if (factp-> truth != FUNKNOWN) return;
                    407:                if (weight ==  0) {
                    408:                        setfact(factp,FFALSE);
                    409:                } else {
                    410:                        setfact(factp,FTRUE);
                    411:                }
                    412:                return;
                    413:        }
                    414:        if (weight < 0) hype->confid = HTRUE;
                    415:        else {
                    416:                hype->confid *= weight;
                    417:                hype->confid /= 10;
                    418:        }
                    419:        if (hype->confid > HTRUE) hype->confid = HTRUE;
                    420:        trace ("Adjusting hypothesis %s by %d gives %d\n",hype->name->name,weight,hype->confid);
                    421: }
                    422: 
                    423: dumplike()
                    424: {
                    425:        struct hype *hypo;
                    426:        
                    427:        for (hypo = hypes; hypo; hypo = hypo->next) {
                    428:                hypo->asked = 0;
                    429:        }
                    430:        while (hypo = curhype()) {
                    431:                hypo->asked = 1;
                    432:                if (hypo->explain) {
                    433:                        printf ("The following is a possible cause of your problem:\n\n%s\n",hypo->explain);
                    434:                        printf ("\nThis explaination has a confidence factor of %d on a scale of %d to %d\n",hypo->confid,HFALSE,HTRUE);
                    435:                        printf ("_________________________________________________________________________\n");
                    436:                }
                    437:        }
                    438: }
                    439: 
                    440: cycle()
                    441: {
                    442:        struct hype *hypo;
                    443:        int ret;
                    444: 
                    445: #ifdef DIAGNOSE
                    446:        printf ("You will be asked to clarify your problem\n");
                    447: #endif
                    448:        printf ("For each question, please answer with all of the numbers\n");
                    449:        printf ("of the statements that apply.  For example 136\n");
                    450:        printf ("if answers 1, 3, and 6 apply.  If you would like to quit, type 'q'\n");
                    451:        printf ("If you would like to escape to run a unix commmand, type '!'\n");
                    452:        printf ("or '!command' in response to a question.\n\n");
                    453:        
                    454:        while (hypo = curhype()) {
                    455:                if (ret= askhype(hypo)) {
                    456:                        if (ret < 0) return; /* User quit */
                    457:                        if (hypo->explain == NULL) hypo->asked = 1;
                    458:                } else {
                    459:                        hypo->asked = 1;
                    460:                        if (hypo->explain) {
                    461: #ifdef DIAGNOSE
                    462:                                printf ("The following is a possible cause of your problem:\n\n%s\n",hypo->explain);
                    463:                                printf ("\nThis explaination has a confidence factor of %d on a scale of %d to %d\n",hypo->confid,HFALSE,HTRUE);
                    464:                                if (gyn("Would you like to continue to identify other possible causes") == 0) return;
                    465: #else
                    466:                                printf("%s\n",hypo->explain);
                    467:                                return(0);
                    468: #endif
                    469:                        }
                    470:                }
                    471:        }
                    472: }
                    473: 
                    474: gyn(string)
                    475: char *string;
                    476: {
                    477:        char buf[100];
                    478:        
                    479:        while (1) {
                    480:                printf ("%s\n",string);
                    481:                if (gets(buf) == NULL) return(0);
                    482:                if (buf[0] == 'y') return(1);
                    483:                if (buf[0] == 'n') return(0);
                    484:                printf ("Please answer with 'yes' or 'no'\n");
                    485:        }
                    486: }
                    487: 
                    488: char *
                    489: gstring()
                    490: {
                    491:        char buf[512];
                    492:        char *bufp;
                    493:        int c;
                    494:        
                    495:        c = nonblank();
                    496:        if (c != '"') {
                    497:                fprintf("Missing character string argument\n");
                    498:                ungetc(c,kfile);
                    499:                return;
                    500:        }
                    501:        bufp = buf;
                    502:        while (((c =getc(kfile)) != EOF) && (c != '"')) {
                    503:                if (c == '\\') c = getc(kfile);
                    504:                *bufp++ = c;
                    505:        }
                    506:        *bufp++ = 0;
                    507:        bufp = malloc(bufp-buf+1);
                    508:        strcpy(bufp,buf);
                    509:        trace ("Storing character string %s\n",bufp);
                    510:        return(bufp);
                    511: }
                    512: 
                    513: nonblank()
                    514: {
                    515:        int c;
                    516: 
                    517:        while ((c = getc(kfile)) != EOF) {
                    518:                if ((ctype[c] & WHITE) == 0) return(c);
                    519:        }
                    520:        return(EOF);
                    521: }
                    522: 
                    523: int number(sp)
                    524: /* Keywords: string-processing file-scanning:50 user-interface:10 */
                    525: 
                    526: char *sp;
                    527: {
                    528:        int n;
                    529:        n = 0;
                    530:        while (*sp) n = n*10 + (*sp++) -'0';
                    531:        return(n);
                    532: }
                    533: 
                    534: char symbuf[64];
                    535: 
                    536: char * symbol()
                    537: {
                    538:        int c;
                    539:        char *symp;
                    540:        
                    541:        symp = symbuf;
                    542:        
                    543:        c = nonblank();
                    544:        while ((c != EOF) && (ctype[c]&SYMCHAR)) {
                    545:                *symp++ = c;
                    546:                c = getc(kfile);
                    547:        }
                    548:        if (c == EOF) return(NULL);
                    549:        ungetc(c,kfile);
                    550:        *symp++ = 0;
                    551:        trace ("Reading symbol: %s\n",symbuf);
                    552:        return(symbuf);
                    553: }
                    554: 
                    555: 
                    556: /* Knowledge file formats: */
                    557: 
                    558: 
                    559: /* Hypothesis name: {  */
                    560: /*     Ask: "text for asking" */
                    561: /*     Scan: "file(s) to scan"  */
                    562: /*     Run: "command to run" */
                    563: /*     Replies: { */
                    564: /*             factname: "description" */
                    565: /*     } */
                    566: /*     Read: string */
                    567: 
                    568: /*     Explain: "explaination if terminal diagnosis" */
                    569: 
                    570: /* Infer hypothesis <with certaintity number> from { */
                    571: /* Conclude fact from { */
                    572: /*     fact, or !fact */
                    573: /* } */
                    574: 
                    575: main(argc, argv)
                    576: 
                    577: /* Keywords: user-interface command-line file-scanning:10 file-opening:10 */
                    578: 
                    579: int argc;
                    580: char *argv [];
                    581: 
                    582: {
                    583:        int i;
                    584:        int ktest = 0;
                    585:        for (i = 1; i < argc; i++) {
                    586:                if (streq(argv[i],"-t")) {
                    587:                        traceon++;
                    588:                        i++;
                    589:                }
                    590:                if (streq(argv[i],"-k")) {
                    591:                        ktest++;
                    592:                        i++;
                    593:                }
                    594:                if (argc>2) printf ("Loading file %s\n",argv[i]);
                    595:                parse(argv[i]);
                    596:        }
                    597:        if (ktest) {
                    598:                dumpknow();
                    599:        }
                    600:        while (1) {
                    601:                reset();
                    602:                cycle();
                    603: #ifdef DIAGNOSE
                    604:                printf ("I can offer no further help with this problem\n");
                    605:                printf ("If you are still having trouble, contact ihnss!warren\n\n");
                    606: 
                    607:                if (gyn("Would you like a summary of all likely causes?")) dumplike();
                    608:                if (gyn("Would you like to try another diagnosis?")==0) break;
                    609: #else
                    610:                if (gyn("Would you like to do something else?")==0) break;
                    611: #endif
                    612:        }
                    613: }
                    614: dumpknow()
                    615: {
                    616:        struct fact *factp;
                    617:        struct hype *hypep;
                    618:        struct ref *refp;
                    619:        struct conc *consp;
                    620:        struct concr *concrp;
                    621:        int header;
                    622:        
                    623:        reset();
                    624:        header = 0;
                    625:        for (factp = facts; factp; factp= factp->next) {
                    626:                for (concrp = factp->setlist; concrp; concrp = concrp->next) {
                    627:                        concrp->this->hypo->asked = 1;
                    628:                }
                    629:        }
                    630:        header = 0;
                    631:        for (hypep = hypes; hypep; hypep = hypep->next) {
                    632:                if ((hypep->text == NULL)&& (hypep->explain == NULL)) {
                    633:                        if (header == 0) {
                    634:                                header = 1;
                    635:                                printf ("The following hypotheses are never defined:\n");
                    636:                        }
                    637:                        printf ("       %s\n",hypep->name->name);
                    638:                }
                    639:                for (refp = hypep->queries; refp; refp = refp->next) {
                    640:                        ((struct fact *) refp->this->definition)->truth = FTRUE;
                    641:                }
                    642:        }
                    643:        header = 0;
                    644:        for (hypep = hypes; hypep; hypep = hypep->next) {
                    645:                if (hypep->asked == 0) {
                    646:                        if (header == 0) {
                    647:                                header = 1;
                    648:                                printf ("The following hypotheses are not inferred by any facts:\n");
                    649:                        }
                    650:                        printf ("       %s\n",hypep->name->name);
                    651:                }
                    652:        }
                    653:        header = 0;
                    654:        for (factp = facts; factp; factp= factp->next) {
                    655:                if (factp->truth == FUNKNOWN) {
                    656:                        if (header == 0) {
                    657:                                header = 1;
                    658:                                printf ("The following facts are never set:\n");
                    659:                        }
                    660:                        printf ("       %s\n",factp->name->name);
                    661:                }
                    662:        }
                    663:        header = 0;
                    664:        for (factp = facts; factp; factp= factp->next) {
                    665:                if (factp->setlist == NULL) {
                    666:                        if (header == 0) {
                    667:                                header = 1;
                    668:                                printf ("The following facts are never used to infer anything:\n");
                    669:                        }
                    670:                        printf ("       %s\n",factp->name->name);
                    671:                }
                    672:        }
                    673:        reset();
                    674: }
                    675: parse(np)
                    676: 
                    677: /* Keywords: file-scanning file-opening:10 preprocessor:10 database-input:10 */
                    678: 
                    679: char *np;
                    680: {
                    681:        register char *symp;
                    682:        char c;
                    683:        kfile = fopen(np,"r");
                    684: 
                    685:        if (kfile == NULL) {
                    686:                fprintf(stderr,"Can't open %s\n",np);
                    687:                return;
                    688:        }
                    689:        
                    690:        while (symp = symbol()) {
                    691:                if (streq(symp,"Hypothesis")) addhype();
                    692:                else if (streq(symp,"Infer")) addinfer(HYPO);
                    693:                else if (streq(symp,"Conclude")) addinfer(FACT);
                    694:                else {
                    695:                        fprintf (stderr,"Bad keyword %s\n",symp);
                    696:                        c = nonblank();
                    697:                        if (ctype[c] & SYMCHAR) ungetc(c,kfile);
                    698:                }
                    699:        }
                    700: }
                    701: 
                    702: addhype()
                    703: {
                    704:        register char *sp;
                    705:        register struct hype *hypep;
                    706:        register struct defblk *defp;
                    707:        register struct fact *factp;
                    708:        struct ref *refp;
                    709:        char c;
                    710:        
                    711:        sp = symbol();
                    712:        if (sp == NULL) {
                    713: eof:   fprintf(stderr,"Unexpected EOF in hypothesis\n");
                    714:                return;
                    715:        }
                    716:        defp = getref(sp,HYPO,1);
                    717:        hypep = (struct hype *) defp->definition;
                    718:        c = nonblank();
                    719:        if (c != ':') {
                    720:                fprintf(stderr,"Missing ':' after hypothesis name %s\n",sp);
                    721:        }
                    722:        c = nonblank();
                    723:        if (c != '{') {
                    724:                fprintf (stderr,"Empty hypothesis body %s\n",sp);
                    725:        }
                    726:        while (1) {
                    727:                c = nonblank();
                    728:                if ((c == EOF) || (c == '}')) return;
                    729:                ungetc(c,kfile);
                    730:                sp = symbol();
                    731:                c = nonblank();
                    732:                if (c != ':') {
                    733:                        fprintf(stderr,"Missing ':' after hypothesis name %s\n",sp);
                    734:                }
                    735:                if (streq(sp,"Ask")) {
                    736:                        hypep->text = gstring();
                    737:                        hypep->action = ASK;
                    738:                }
                    739:                else if (streq(sp,"Scan")) {
                    740:                        hypep->text = gstring();
                    741:                        hypep->action = SCAN;
                    742:                }
                    743:                else if (streq(sp,"Run")) {
                    744:                        hypep->text = gstring();
                    745:                        hypep->action = RUN;                    
                    746:                } else if (streq(sp,"Explain")) {
                    747:                        hypep->explain = gstring();
                    748:                } else if (streq(sp,"Read")) {
                    749:                        sp = symbol();
                    750:                        defp = getref(sp,STRING,1);
                    751:                        refp = (struct ref *) malloc(sizeof *refp);
                    752:                        refp->next = hypep->queries;
                    753:                        refp->this = defp;
                    754:                        refp->text = NULL;
                    755:                        hypep->queries = refp;
                    756:                } else if (streq(sp,"Replies")) {
                    757:                        c = nonblank();
                    758:                        if (c != '{') {
                    759:                                fprintf (stderr,"Empty replies body %s\n",sp);
                    760:                        }
                    761:                        while (1) {
                    762:                                c = nonblank();
                    763:                                if (c == '}') break;
                    764:                                ungetc(c,kfile);
                    765:                                sp = symbol();
                    766:                                c = nonblank();
                    767:                                if (c != ':') {
                    768:                                        fprintf(stderr,"Missing ':' after reply name %s\n",sp);
                    769:                                }
                    770:                                if ((*sp >= 'A') && (*sp <= 'Z')) {
                    771: 
                    772: /* Define a hypothesis and fact of the same name, and make an inference */
                    773: 
                    774:                                        struct hype *infhype;
                    775:                                        struct conc *concp;
                    776:                                        struct concr *concrp;
                    777:                                        
                    778:                                        defp = getref(sp,HYPO,1);
                    779:                                        infhype = (struct hype *) defp->definition;
                    780:                                        *sp += 32;
                    781:                                        defp = getref(sp,FACT,1);
                    782:                                        factp = (struct fact *) defp->definition;
                    783:                                        if (factp->setlist) {
                    784: 
                    785:                                                /* Already exists, assume the infers part does to */
                    786:                                                goto makeref; /* Join other branch to make this reference to it. */
                    787:                                        }
                    788:                                        concrp = (struct concr *) malloc(sizeof *concrp);
                    789:                                        factp->setlist = concrp;
                    790:                                        concp = (struct conc *) malloc((sizeof *concp) + (sizeof factp));
                    791:                                        concrp->this = concp;
                    792:                                        concrp->next = NULL;
                    793:                                        concp -> weight = -1;
                    794:                                        concp ->hypo = infhype;
                    795:                                        concp -> vector = 1;
                    796:                                        concp -> num = 1;
                    797:                                        concp ->confirms[0] = factp;
                    798:                                } else {
                    799:                                        defp = getref(sp,FACT,1);
                    800:                                        factp = (struct fact *) defp->definition;
                    801:                                }
                    802: makeref:
                    803:                                c = nonblank();
                    804:                                ungetc(c,kfile);
                    805:                                refp = (struct ref *) malloc(sizeof *refp);
                    806:                                refp -> next = hypep -> queries;
                    807:                                hypep->queries = refp;
                    808:                                refp->this = defp;
                    809:                                if (c == '"') {
                    810:                                        refp->text = gstring();
                    811:                                }
                    812:                        }
                    813:                } else {
                    814:                        fprintf (stderr,"Bad Keyword %s\n",sp);
                    815:                }
                    816:        }
                    817: }
                    818: addinfer(type)
                    819: int type;
                    820: {
                    821:        struct hype *hypep;
                    822:        struct fact *factp;
                    823:        struct conc *concp;
                    824:        struct fact *facts[20];
                    825:        struct concr *concrp;
                    826:        struct ref *refp;
                    827:        struct defblk *defp;
                    828:        register char *sp;
                    829:        int factor;
                    830:        int vector;
                    831:        int c;
                    832:        int numinf;
                    833:        int num;
                    834:        
                    835:        sp = symbol();
                    836:        factor = -1;
                    837:        if (*sp == '!') {
                    838:                factor = 0;
                    839:                sp++;
                    840:        }
                    841:        defp = getref(sp,type,1);
                    842:        hypep = (struct hype *) defp->definition;
                    843: 
                    844:        sp = symbol();
                    845:        if (streq(sp,"certainty")) {
                    846:                if (type != HYPO) fprintf(stderr,"Conclude clause can't have a certainty factor\n");
                    847:                sp = symbol();
                    848:                factor = number(sp);
                    849:                sp = symbol();
                    850:        }
                    851:        if (streq(sp,"from")) {
                    852:                c = nonblank();
                    853:                if (c == '{') {
                    854:                        num=1000;
                    855:                } else {
                    856:                        ungetc(c,kfile);
                    857:                        num = 1;
                    858:                } 
                    859:                vector = 0;
                    860:                numinf = 0;
                    861:                while (num--) {
                    862:                        c = nonblank();
                    863:                        if (c == '}') break;
                    864:                        vector = vector << 1;
                    865:                        if (c != '!' ) {
                    866:                                vector += 1;
                    867:                                ungetc(c,kfile);
                    868:                }
                    869:                        sp = symbol();
                    870:                        defp = getref(sp,FACT,1);
                    871:                        facts[numinf++] = (struct fact *) defp->definition;
                    872:                }
                    873:                if (numinf) {
                    874:                        int x;
                    875:                        
                    876:                        concp = (struct conc *) malloc((sizeof *concp) + numinf * (sizeof factp));
                    877:                        concp ->hypo = hypep;
                    878:                        concp -> weight = factor;
                    879:                        concp -> vector = vector;
                    880:                        concp -> num = numinf;
                    881:                        x = 0;
                    882:                        while (--numinf >= 0) {
                    883:                                factp = facts[numinf];
                    884:                                concrp = (struct concr *) malloc(sizeof *concrp);
                    885:                                concrp ->next = factp->setlist;
                    886:                                factp->setlist = concrp;
                    887:                                concrp->this = concp;
                    888:                                concp->confirms[x++]  = factp;
                    889:                        }
                    890:                }
                    891:        }
                    892: }
                    893: 
                    894: 
                    895: match(pat,targ)
                    896: char *pat,*targ;
                    897: {
                    898:        int first;
                    899:        register char *p, *t;
                    900:        
                    901:        if (*pat== '^') {
                    902:                first=1;
                    903:                pat++;
                    904:        } else first = 0;
                    905:        
                    906:        while ( *targ) {
                    907:                if (*pat == *targ) {
                    908:                        p = pat;
                    909:                        t = targ;
                    910:                        while (*p) if (*p++ != *t++)  goto next;
                    911:                        return(1);
                    912:                }
                    913: next:          if (first) return(0);
                    914:                targ++;
                    915:        }
                    916:        return(0);
                    917: }
                    918: 
                    919: fmatch(fp,refp)
                    920: FILE *fp;
                    921: struct ref *refp;
                    922: {
                    923:        struct fact *factp;
                    924:        struct ref *rp;
                    925:        char buf[512];
                    926:        
                    927:        if (fp == NULL) return;
                    928:        while (fgets(buf,512,fp)) {
                    929:                for (rp = refp; rp != NULL; rp = rp->next) {
                    930:                        if (rp->this->type == STRING) {
                    931:                                buf[strlen(buf)-1] = 0;
                    932:                                rp->this->definition = (struct ref *) malloc(strlen(buf)+1);
                    933:                                strcpy(rp->this->definition,buf);
                    934:                        } else {
                    935:                                factp = (struct fact *) rp->this->definition;
                    936:                                if ((factp->truth == FUNKNOWN) && match(rp->text,buf)) setfact(factp,FTRUE);
                    937:                        }
                    938:                }
                    939:        }
                    940:        for (rp = refp; rp != NULL; rp = rp->next) {
                    941:                if (rp->this->type == FACT) {
                    942:                        factp = (struct fact *) rp->this->definition;
                    943:                        if (factp->truth == FUNKNOWN) setfact(factp,FFALSE);
                    944:                }
                    945:        }
                    946: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.