/*16-DIMENSIONAL BOOLEAN MULTIVALUED LOGICSUZUKI HisashiAugust 2017*/
#include "stdio.h"#include "stdlib.h"#include "string.h"#include "math.h"#include "time.h"
/*a logic value is formally a fixed-point number whose fractional part comprises 16 bits;identify any logic value n defined in "LV_T" type with n / 2^16 = n * 0.0000152587890625;term "logic value" means the raw expression n in "LV_T" type;term "truth value" means the fractional expression n / 2^16 in double type;ex. l.v.: 0000000000001111b = 15 <=> t.v.: 0.0000000000001111b = 15 / 2^16 = 0.0002288818359375------------------------------------t.v.: expression in natural language------------------------------------ 1 : absolutely 0.9: almost 0.8: probably 0.7: likely 0.6: rather 0.5: may 0.4: rather not 0.3: possibly 0.2: little 0.1: hardly 0 : never------------------------------------*/#define LV_T unsigned int
#define ALL0 0x0000 /* identify with 0.0000000000000000b = 0 */#define ALL1 0xffff /* identify with 0.1111111111111111b = 0.9999847412109375 ~ 1 */
#define MAXLEN 1000 /* upper bound of string length */
/* these parameters control convergency in running function "_globopt" */#define CONVRGNCYFACTOR 16#define MAX_LOCALTRIALS 1000
/* constants indicating results of processing */#define SUCC 1#define FAIL 0
/* constants assigned to "prtsw" */#define ON 1#define OFF 0
/* structure for representing trees */struct NODE { char index[MAXLEN]; struct NODE *sub1; struct NODE *sub2; };#define NODESZ sizeof(struct NODE)
/* function prototypes for external use */double lvtotv(const LV_T lv);LV_T tvtolv(const double frac);LV_T not(const LV_T lv);LV_T and(const LV_T lv1, const LV_T lv2);LV_T ior(const LV_T lv1, const LV_T lv2);LV_T xor(const LV_T lv1, const LV_T lv2);LV_T imp(const LV_T lv1, const LV_T lv2);LV_T eqv(const LV_T lv1, const LV_T lv2);double cond(const LV_T lv1, const LV_T lv2);void prtlv(const char* str, const LV_T lv);void prtatoms(const char *atomfile);LV_T evalform(const char *atomfile, const char *form, const int prtsw);double evalgap(const char *atomfile, const char *knowfile, const int prtsw);double optatoms(const char *atomfile, const char *knowfile, const int numtrials, const int prtsw);void demo_bird1(void);void demo_bird2(void);void demo_bird3(void);void demo_cake1(void);void demo_cake2(void);
/* function prototypes for internal use */double _fracrand(void);char *_lvtobins(LV_T n, char *str);void _prtlv(LV_T lv);char *_fclr(char *objfile);char *_fcpy(char *newfile, char *orgfile);int _evalatom(FILE *atomfp, char *atom, LV_T *lv);int _evalop(FILE *atomfp, char *op, LV_T lv1, LV_T lv2, LV_T *lv);void _extarg(char *(*p), char delimiter, char *arg);int _extargs(char *str, char *index, char *op, char *arg1, char *arg2);int _parse(char *form, char *op, char *arg1, char *arg2);struct NODE *_parsetree(char *form, struct NODE *tree);int _evalnode(FILE *atomfp, struct NODE *tree, LV_T *lv);int _evalform(FILE *atomfp, char *form, double *tv);double _evalgap(FILE *atomfp, FILE *knowfp, double *avsqgap, double *maxabsgap, int prtsw);LV_T _fluct(LV_T lv, int ith);void _atomfluct(FILE *orgfp, FILE *newfp, int ith);double _localopt(char *atomfile, char *knowfile, int prtsw);double _globopt(char *atomfile, char *knowfile, int prtsw);
/* generate random numbers in [0, 1] */double _fracrand(void) { return (double) rand() / RAND_MAX; }
/* convert logic value "lv" of "LV_T" type to the truth value of double type */double lvtotv(const LV_T lv) { return (double) (0xffff & lv) / 0x10000; }
/*convert double type "frac" to an "LV_T" type value whose truth value is nearest to "frac";"lvtotv(tvtolv(frac))" doesn't always coincide with "frac" since the precision of "LV_T" type is 16bit;*/LV_T tvtolv(const double frac) { LV_T lv, _lv; double temp; if(frac <= 0) return ALL0; if(frac >= ((double) 0xffff / 0x10000)) return ALL1; lv = (LV_T) floor(temp = frac * 0x10000); _lv = (LV_T) ceil(temp); if(frac - lvtotv(lv) > lvtotv(_lv) - frac) return _lv; return lv;}
/* convert an integer to a 0/1-sequence of length 16 */char *_lvtobins(LV_T lv, char *str) { LV_T temp = lv; char *p = str; int i = 0; for(; i < 16; i++, temp <<= 1, p++) *p = 0x8000 & temp ? '1' : '0'; *p = '\0'; return str;}
/* logic operations */LV_T not(const LV_T lv) { return 0xffff & ~lv; }LV_T and(const LV_T lv1, const LV_T lv2) { return 0xffff & (lv1 & lv2); }LV_T ior(const LV_T lv1, const LV_T lv2) { return 0xffff & (lv1 | lv2); }LV_T xor(const LV_T lv1, const LV_T lv2) { return 0xffff & (lv1 ^ lv2); }LV_T imp(const LV_T lv1, const LV_T lv2) { return 0xffff & (~lv1 | lv2); }LV_T eqv(const LV_T lv1, const LV_T lv2) { return 0xffff & ~(lv1 ^ lv2); }
/*calculate the ratio of logic value "lv2" conditioned by logic value "lv1";lv1 is 0.0000000000001111b = 0.0002288818359375lv2 is 0.1001100110011001b = 0.5999908447265625and(lv1,lv2) is 0.0000000000001001b = 0.0001373291015625cond(lv1,lv2) is 0.0000000000001001b / 0.0000000000001111b = 9 / 15 = 0.6*/double cond(const LV_T lv1, const LV_T lv2) { LV_T lv = and(lv1, lv2); return lv1 == ALL0 ? 0 : (double) lv / lv1; /* output 0 if "lv1" is 0 as a convention */}
/* print logic value "lv" in an easy-to-see format */void _prtlv(LV_T lv) { char bins[MAXLEN]; printf("0.%s (%18.16f)\n", _lvtobins(lv, bins), lvtotv(lv)); return;}
/* print logic value "lv" in an easy-to-see format beginning with arbitrary explanation "str" */void prtlv(const char* str, const LV_T lv) { printf("%s: ", str); _prtlv(lv); return; }
/* print all atoms and their truth values contained in "atomfile" */void prtatoms(const char *atomfile) { char str[MAXLEN], *p, temp[MAXLEN]; FILE *atomfp; if((atomfp = fopen(atomfile, "r")) == NULL) exit(1); while(!feof(atomfp)) { *str = '\0'; fgets(str, MAXLEN, atomfp); if((p = strtok(str, ":")) != NULL) prtlv(strcpy(temp, p), atol(strtok(NULL, "\n\0"))); } fclose(atomfp); return;}
/* clear file "objfile" */char *_fclr(char *objfile) { FILE *fp; if((fp = fopen(objfile, "w")) == NULL) exit(1); fprintf(fp, ""); fclose(fp); return objfile;}
/* copy file "orgfile" to file "newfile" */char *_fcpy(char *newfile, char *orgfile) { char str[MAXLEN]; FILE *orgfp, *newfp; if((orgfp = fopen(orgfile, "r")) == NULL) exit(1); if((newfp = fopen(newfile, "w")) == NULL) exit(1); while(!feof(orgfp)) { *str = '\0'; fgets(str, MAXLEN, orgfp); fprintf(newfp, "%s", str); } fclose(newfp); fclose(orgfp); return newfile;}
/*seek "atom" in the file pointed by "atomfp", and get a logic value "lv";output SUCC (= 1) or FAIL (= 0) according to whether the file includes this atom or not;append any unknown atom as 0.100...0b = 0.5 as a convention to the file;*/int _evalatom(FILE *atomfp, char *atom, LV_T *lv) { char str[MAXLEN], *p; int status = FAIL; long mark = ftell(atomfp); *lv = 0x8000; for(fseek(atomfp, 0, SEEK_SET); !feof(atomfp); ) { *str = '\0'; fgets(str, MAXLEN, atomfp); if(((p = strtok(str, ":")) != NULL) && !strcmp(atom, p)) { *lv = atol(strtok(NULL, "\n\0")); status = SUCC; break; } } if(!status) { fseek(atomfp, 0, SEEK_END); fprintf(atomfp, "%s:%05d\n", atom, *lv); } fseek(atomfp, mark, SEEK_SET); return status;}
/*apply logic operation "op" on logic values "lv1" and "lv2" to get a result "lv";don't care about "lv2" if "op" is a monadic operation;regard "op" as an atom if "op" is no logic operation;output FAIL (= 0) only if atom "op" is new;*/int _evalop(FILE *atomfp, char *op, LV_T lv1, LV_T lv2, LV_T *lv) { if(!strcmp(op, "not")) { *lv = not(lv1); return SUCC; } if(!strcmp(op, "and")) { *lv = and(lv1, lv2); return SUCC; } if(!strcmp(op, "ior")) { *lv = ior(lv1, lv2); return SUCC; } if(!strcmp(op, "xor")) { *lv = xor(lv1, lv2); return SUCC; } if(!strcmp(op, "imp")) { *lv = imp(lv1, lv2); return SUCC; } if(!strcmp(op, "eqv")) { *lv = eqv(lv1, lv2); return SUCC; } if(!strcmp(op, "cond")) { *lv = tvtolv(cond(lv1, lv2)); return SUCC; } return _evalatom(atomfp, op, lv); /* if "op" is an atom, fill "lv" with the logic value */}
/* extract a substring "arg" from string "*p" with "delimiter" */void _extarg(char *(*p), char delimiter, char *arg) { int bal = 0; strcpy(arg, ++(*p)); for(*p = arg; !((bal == 0) && (*(*p) == delimiter)); (*p)++) { if(*(*p) == '(') bal++; else if (*(*p) == ')') bal--; } *(*p) = '\0'; return;}
/*if logic formula "form" includes a logic operator "index",extract the operator "op" with arguments "arg1" and "arg2";output SUCC (= 1) or FAIL (= 0) according to whether "form" is legal or not;*/int _extargs(char *form, char *index, char *op, char *arg1, char *arg2) { char *p = form + strlen(index); if((strstr(form, index) == form) && (*p == '(')) { strcpy(op, index); if(!strcmp(index, "not")) { _extarg(&p, ')', arg1); *arg2 = '\0'; } else { _extarg(&p, ',', arg1); _extarg(&p, ')', arg2); } return SUCC; } else return FAIL;}
/*extract operator "op", 1st argument "arg1", and 2nd argument "arg2" from logic formula "form";output the arity of "op";*/int _parse(char *form, char *op, char *arg1, char *arg2) { if(_extargs(form, "not", op, arg1, arg2)) return 1; /* output 1 if op is monadic operation */ if(_extargs(form, "and", op, arg1, arg2)) return 2; /* output 2 if op is dyadic operation */ if(_extargs(form, "ior", op, arg1, arg2)) return 2; if(_extargs(form, "xor", op, arg1, arg2)) return 2; if(_extargs(form, "imp", op, arg1, arg2)) return 2; if(_extargs(form, "eqv", op, arg1, arg2)) return 2; if(_extargs(form, "cond", op, arg1, arg2)) return 2; strcpy(op, form); *arg1 = *arg2 = '\0'; return 0; /* output 0 if op is no operation */}
/* parse logic formula "form" to a tree, and output "tree" pointing the root */struct NODE *_parsetree(char *form, struct NODE *tree) { char op[MAXLEN], arg1[MAXLEN], arg2[MAXLEN]; int kind = _parse(form, op, arg1, arg2); size_t size = NODESZ; struct NODE *sub1, *sub2; strcpy(tree -> index, op); switch(kind) { case 2: sub1 = malloc(size); tree -> sub1 = sub1; _parsetree(arg1, sub1); sub2 = malloc(size); tree -> sub2 = sub2; _parsetree(arg2, sub2); break; case 1: sub1 = malloc(size); tree -> sub1 = sub1; _parsetree(arg1, sub1); tree -> sub2 = NULL; break; case 0: tree -> sub1 = tree -> sub2 = NULL; } return tree;}
/*evaluate the logic value "lv" of an arbitrary logic formula parsed to the tree pointed by "tree";output FAIL (= 0) only if the logic formula contains any unknown atom;*/int _evalnode(FILE *atomfp, struct NODE *tree, LV_T *lv) { int status = SUCC; LV_T lv1, lv2; struct NODE *sub1 = tree -> sub1, *sub2 = tree -> sub2; if(sub1 != NULL) { if(!_evalnode(atomfp, sub1, &lv1)) status = FAIL; free(sub1); if(sub2 != NULL) { if(!_evalnode(atomfp, sub2, &lv2)) status = FAIL; free(sub2); } } if(!_evalop(atomfp, tree -> index, lv1, lv2, lv)) status = FAIL; return status;}
/*calculate the truth value "tv" of an arbitrary logic formula "form" by calling "_evalnode";output FAIL (= 0) only if "form" contains any unknown atom;*/int _evalform(FILE *atomfp, char *form, double *tv) { LV_T lv; struct NODE tree; int status = _evalnode(atomfp, _parsetree(form, &tree), &lv); *tv = lvtotv(lv); return status;}
/*evaluate any logic formula "form" by using "atomfile" and output the result;"prtsw" = ON/OFF controls whether printing the history or hiding;*/LV_T evalform(const char *atomfile, const char *form, const int prtsw) { char _form[MAXLEN]; LV_T lv; double tv; FILE *atomfp; if((atomfp = fopen(atomfile, "r+")) == NULL) exit(1); _evalform(atomfp, strcpy(_form, form), &tv); fclose(atomfp); lv = tvtolv(tv); if(prtsw) prtlv(form, lv); return lv;}
/*concerning each logic formula contained in the knowledge file pointed by "knowfp",evaluate the gap between the t.v. calculated from the atom file and the t.v. specified in the knowledge file,where the atom file is pointed by "atomfp";fill "avsqgap" with the average of squared gaps, and output "avsqgap";fill "maxabsgap" with the maximum of absolute gaps;"prtsw" = ON/OFF controls whether printing the history or hiding;*/double _evalgap(FILE *atomfp, FILE *knowfp, double *avsqgap, double *maxabsgap, int prtsw) { char str[MAXLEN], form[MAXLEN], *p; int num = 0; double tv, rqtv, gap, absgap, sumsqgap = 0; long mark = ftell(knowfp); *maxabsgap = 0; for(fseek(knowfp, 0, SEEK_SET); !feof(knowfp); ) { *str = '\0'; fgets(str, MAXLEN, knowfp); if((p = strtok(str, ":")) != NULL) { num++; strcpy(form, p); rqtv = atof(strtok(NULL, "\n\0")); _evalform(atomfp, form, &tv); sumsqgap += (gap = tv - rqtv) * gap; if((absgap = fabs(gap)) > *maxabsgap) *maxabsgap = absgap; if(prtsw) printf("[%d] %s: %18.16f = %18.16f%+18.16f\n", num, form, tv, rqtv, gap); } } fseek(knowfp, mark, SEEK_SET); *avsqgap = num ? sumsqgap / num : 0; if(prtsw) printf("GAP DEV: %18.16f; MAX ABSOL GAP: %18.16f\n", sqrt(*avsqgap), *maxabsgap); return *avsqgap;}
/*concerning each logic formula contained in the knowledge file "knowfile",evaluate the gap between the t.v. calculated from "atomfile" and the t.v. specified in the "knowfile";fill "avsqgap" with the average of squared gaps, and output "avsqgap";"prtsw" = ON/OFF controls whether printing the history or hiding;*/double evalgap(const char *atomfile, const char *knowfile, const int prtsw) { double avsqgap, maxabsgap; FILE *atomfp, *knowfp; if((atomfp = fopen(atomfile, "r+")) == NULL) exit(1); if((knowfp = fopen(knowfile, "r")) == NULL) exit(1); _evalgap(atomfp, knowfp, &avsqgap, &maxabsgap, prtsw); fclose(knowfp); fclose(atomfp); return avsqgap;}
/* change randomly each bit from "ith" to 16th on logic value "lv" */LV_T _fluct(LV_T lv, int ith) { int i; LV_T _lv = lv, mask; for(i = 16, mask = 1; i >= ith; i--, mask <<= 1) if(_fracrand() < 0.5) _lv = 0xffff & (_lv & mask ? _lv & not(mask) : _lv | mask); return _lv;}
/*apply function "_fluct" with argument "ith" on each atom contained in the atom file pointed by "orgfp";generate a new atom file pointed by "newfp";*/void _atomfluct(FILE *orgfp, FILE *newfp, int ith) { char str[MAXLEN], *p; long orgfmark = ftell(orgfp), newfmark = ftell(newfp); for(fseek(orgfp, 0, SEEK_SET), fseek(newfp, 0, SEEK_SET); !feof(orgfp); ) { *str = '\0'; fgets(str, MAXLEN, orgfp); if((p = strtok(str, ":")) != NULL) fprintf(newfp, "%s:%05d\n", p, _fluct(atol(strtok(NULL, "\n\0")), ith)); } fseek(orgfp, orgfmark, SEEK_SET); fseek(newfp, newfmark, SEEK_SET); return;}
/*let the average square gap outputted by function "_evalgap" converge to a local minimum;output "avsqgap" minimized locally;"prtsw" = ON/OFF controls whether printing the history or hiding;*/double _localopt(char *atomfile, char *knowfile, int prtsw) { char _atomfile[] = "localopt.tmp"; int ith; double avsqgap, _avsqgap, maxabsgap, _maxabsgap; FILE *atomfp, *_atomfp, *knowfp; if((knowfp = fopen(knowfile, "r")) == NULL) exit(1); if((atomfp = fopen(atomfile, "r+")) == NULL)exit(1); _evalgap(atomfp, knowfp, &avsqgap, &maxabsgap, OFF); for(ith = 1; ith <= 16; ith++) { if(avsqgap == 0) return avsqgap; if((_atomfp = fopen(_atomfile, "w+")) == NULL) exit(1); _atomfluct(atomfp, _atomfp, ith); _evalgap(_atomfp, knowfp, &_avsqgap, &_maxabsgap, OFF); fclose(_atomfp); if(avsqgap > _avsqgap) { avsqgap = _avsqgap; fclose(atomfp); remove(atomfile); rename(_atomfile, atomfile); if((atomfp = fopen(atomfile, "r+")) == NULL) exit(1); } if(maxabsgap > _maxabsgap) maxabsgap = _maxabsgap; if(prtsw) printf("[%d]%18.16f ", ith, avsqgap); } fclose(atomfp); fclose(knowfp); remove(_atomfile); if(prtsw) putchar('\n'); return avsqgap;}
/*apply function "_localopt" at most MAX_LOCALTRIALS timesuntil the average square gap outputted by "_localopt" stays unchanged for CONVRGNCYFACTOR times;output "avsqgap" minimized globally;you can increase CONVRGNCYFACTOR for improving the approximation by sacrificing the computation time;"prtsw" = ON/OFF controls whether printing the history or hiding;*/double _globopt(char *atomfile, char *knowfile, int prtsw) { char _atomfile[] = "globopt.tmp"; int numunchng, i; double avsqgap, _avsqgap; avsqgap = _localopt(_fclr(atomfile), knowfile, OFF); if(prtsw) printf("[0]%18.16f", avsqgap); for(numunchng = i = 1; (numunchng < CONVRGNCYFACTOR) && (i <= MAX_LOCALTRIALS); i++) { if(avsqgap == 0) return avsqgap; _avsqgap = _localopt(_fcpy(_atomfile, atomfile), knowfile, OFF); if(avsqgap > _avsqgap) { numunchng = 1; avsqgap = _avsqgap; remove(atomfile); rename(_atomfile, atomfile); if(prtsw) printf(" > [%d]%18.16f", i, avsqgap); } else { numunchng++; if(prtsw) printf(" = [%d]", i); } } if(prtsw) putchar('\n'); remove(_atomfile); return avsqgap;}
/*apply function "_globopt", "numtrials" times, and outputs "avsqgap" approximately minimized;you can increase "numtrials" for improving the approximation by sacrificing the computation time;"prtsw" = ON/OFF controls whether printing the history or hiding;*/double optatoms(const char *atomfile, const char *knowfile, const int numtrials, const int prtsw) { char temp[MAXLEN], _knowfile[MAXLEN], _atomfile[] = "optatoms.tmp"; int i; double avsqgap, _avsqgap; srand(time(NULL)); /* initialize the seed of random number generator */ for(i = 1; i <= numtrials; i++) { if(!prtsw) putchar('.'); if(i == 1) avsqgap = _globopt(strcpy(temp, atomfile), strcpy(_knowfile, knowfile), prtsw); else { if(avsqgap == 0) return avsqgap; if(avsqgap > (_avsqgap = _globopt(_atomfile, _knowfile, prtsw))) { avsqgap = _avsqgap; remove(atomfile); rename(_atomfile, atomfile); } } } if(!prtsw) putchar('\n'); remove(_atomfile); return avsqgap;}
/* example of external use of functions */void demo_bird1(void) { char atomfile[] = "ATOMS.DAT", knowfile[] = "KNOWS.DAT"; int numglobtimes = 30; FILE *knowfp;
if((knowfp = fopen(knowfile, "w")) == NULL) exit(1); fprintf(knowfp, "cond(falcon,bird):1\n"); fprintf(knowfp, "cond(falcon,fly):0.9\n"); fprintf(knowfp, "cond(pigeon,bird):1\n"); fprintf(knowfp, "cond(pigeon,fly):0.9\n"); fprintf(knowfp, "cond(fly,good_reflexes):0.75\n"); fprintf(knowfp, "cond(penguin,bird):1\n"); fprintf(knowfp, "cond(penguin,fly):0\n"); fprintf(knowfp, "cond(falcon,ride_bicycle):0\n"); fclose(knowfp);
printf("OPTIMIZIG TRUTH VALUES OF ATOMS"); optatoms(atomfile, knowfile, numglobtimes, OFF); printf("\n/* [num] 'logic formula':' optimized tv' = 'desired tv'+-'gap' */\n"); evalgap(atomfile, knowfile, ON);
printf("\n*** Atoms ***\n"); prtatoms("ATOMS.DAT");
printf("\n*** Inferences ***\n"); lvtotv(evalform(atomfile, "cond(and(not(bird),good_reflexes),ride_bicycle)", ON)); lvtotv(evalform(atomfile, "cond(ride_bicycle,good_reflexes)", ON)); lvtotv(evalform(atomfile, "cond(ride_bicycle,fly)", ON));
return;}
/* example of external use of functions */void demo_bird2(void) { char atomfile[] = "ATOMS.DAT", knowfile[] = "KNOWS.DAT"; int numglobtimes = 30; FILE *knowfp;
if((knowfp = fopen(knowfile, "w")) == NULL) exit(1); fprintf(knowfp, "cond(falcon,bird):1\n"); fprintf(knowfp, "cond(falcon,fly):0.9\n"); fprintf(knowfp, "cond(pigeon,bird):1\n"); fprintf(knowfp, "cond(pigeon,fly):0.9\n"); fprintf(knowfp, "cond(fly,good_reflexes):0.75\n"); fprintf(knowfp, "cond(penguin,bird):1\n"); fprintf(knowfp, "cond(penguin,fly):0\n"); fprintf(knowfp, "cond(falcon,ride_bicycle):0\n"); fprintf(knowfp, "cond(good_reflexes,ride_bicycle):0.75\n"); fclose(knowfp);
printf("OPTIMIZIG TRUTH VALUES OF ATOMS"); optatoms(atomfile, knowfile, numglobtimes, OFF); printf("\n/* [num] 'logic formula':' optimized tv' = 'desired tv'+-'gap' */\n"); evalgap(atomfile, knowfile, ON);
printf("\n*** Atoms ***\n"); prtatoms("ATOMS.DAT");
printf("\n*** Inferences ***\n"); lvtotv(evalform(atomfile, "cond(and(not(bird),good_reflexes),ride_bicycle)", ON)); lvtotv(evalform(atomfile, "cond(ride_bicycle,good_reflexes)", ON)); lvtotv(evalform(atomfile, "cond(ride_bicycle,fly)", ON));
return;}
/* example of external use of functions */void demo_bird3(void) { char atomfile[] = "ATOMS.DAT", knowfile[] = "KNOWS.DAT"; int numglobtimes = 30; FILE *knowfp;
if((knowfp = fopen(knowfile, "w")) == NULL) exit(1); fprintf(knowfp, "cond(falcon,bird):1\n"); fprintf(knowfp, "cond(falcon,fly):0.9\n"); fprintf(knowfp, "cond(pigeon,bird):1\n"); fprintf(knowfp, "cond(pigeon,fly):0.9\n"); fprintf(knowfp, "cond(fly,good_reflexes):0.75\n"); fprintf(knowfp, "cond(penguin,bird):1\n"); fprintf(knowfp, "cond(penguin,fly):0\n"); fprintf(knowfp, "cond(falcon,ride_bicycle):0\n"); fprintf(knowfp, "cond(and(not(bird),good_reflexes),ride_bicycle):0.75\n"); fclose(knowfp);
printf("OPTIMIZIG TRUTH VALUES OF ATOMS"); optatoms(atomfile, knowfile, numglobtimes, OFF); printf("\n/* [num] 'logic formula':' optimized tv' = 'desired tv'+-'gap' */\n"); evalgap(atomfile, knowfile, ON);
printf("\n*** Atoms ***\n"); prtatoms("ATOMS.DAT");
printf("\n*** Inferences ***\n"); lvtotv(evalform(atomfile, "cond(and(not(bird),good_reflexes),ride_bicycle)", ON)); lvtotv(evalform(atomfile, "cond(ride_bicycle,good_reflexes)", ON)); lvtotv(evalform(atomfile, "cond(ride_bicycle,fly)", ON));
return;}
/* example of external use of functions */void demo_cake1(void) { char atomfile[] = "ATOMS.DAT", knowfile[] = "KNOWS.DAT"; int numglobtimes = 30; FILE *knowfp;
if((knowfp = fopen(knowfile, "w")) == NULL) exit(1); fprintf(knowfp, "cond(and(cake,eat),happy):1\n"); fprintf(knowfp, "cond(and(cake,not(eat)),happy):0\n"); fprintf(knowfp, "cond(eat,cake):0\n"); fclose(knowfp);
printf("OPTIMIZING TRUTH VALUES OF ATOMS"); optatoms(atomfile, knowfile, numglobtimes, OFF); evalgap(atomfile, knowfile, ON);
printf("\nATOMS\n"); prtatoms("ATOMS.DAT");
printf("\nINFERENCES\n"); lvtotv(evalform(atomfile, "cond(cake,happy)", ON)); lvtotv(evalform(atomfile, "cond(cake,eat)", ON)); printf("\n");
return;}