|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.