|
|
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.