⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expertsys.c

📁 专家系统程序:推理机,这里是一个通用专家系统程序
💻 C
字号:
/* An improved expert system that finds multiple goals and displays reasoning*/
#include "stdio.h"
#include "alloc.h"
#define MAX 100

struct attribute {
	char attrib[80];
	struct attribute *next;/*use linked list */
	} at;

struct object {
	char name[80];
	struct attribute *alist;/*pointer to list of attributes */
	} ob;
struct rejected_object{
	char name[80];
	char attrib[80];/*attribute that caused rejection*/
	char condition;/*should it or shouldn't it have been found */
	} rj;
struct rejected_object r_base[MAX];

struct object k_base[MAX];/*holds the knowledge base */
int l_pos=-1;/* location of top of k base */
int r_pos=-1;/*location of top of reject base */

struct attribute *yes,*no;/* used for yes and no lists */
struct attribute *yesnext,*nonext;


main()
{
	 char ch;

	 no=yes='\0';
	 do{
		free_trails();
		ch=menu();
		switch(ch){
			case 'e':enter();
				break;
			case 'q':query();
				break;
			case 's':save();
				break;
			case 'l':load();
		      }

	 }while(ch!='x');
}
	free_trails()
	{
		struct attribute *p;
		while(yes){
			p=yes->next;
			free(yes);
			yes=p;
		}
		while(no){
			p=no->next;
			free(no);
			no=p;
		}
		r_pos=-1;
	}
	/* input an object and its list of attributes */
	enter()
	{
		int t,i;
		struct attribute *p,*oldp;
		for (;;){
			t=get_next();/*get the index of the next       */
					/*available object in k_base */
			if(t==-1){
				printf("Out of list space.\n");
				return;
			}
			printf("Object name: ");
			gets(k_base[t].name);
			if(!*k_base[t].name){
				l_pos--;
				break;
			}
			p=(struct attribute *) malloc(sizeof(at));
			if(p=='\0'){
				printf("Out of memory.\n");
				return;
			}
			k_base[t].alist=p;
			for(i=0;i<sizeof(p->attrib);i++)p->attrib[i]=' ';
			printf("Enter attributes (RETURN to quit)\n");
			for(;;){
				printf(": ");
				gets(p->attrib);
				if(!p->attrib[0])break;
				oldp=p;
				p->next=(struct attribute *)malloc(sizeof(at));
				if(p->next=='\0'){
					printf("Out of memory.\n");
					return;
				}
				p=p->next;
				p->next='\0';
				for(i=0;i<sizeof(p->attrib);i++)p->attrib[i]=' ';
			}
			oldp->next='\0';
		}
	}
	/* inquire information from the expert */
	query()
	{
		int t;
		char ch;
		struct attribute *p;

		for(t=0;t<=l_pos;t++){
			p=k_base[t].alist;
			if(try(p,k_base[t].name)){
				printf("%s fits current description\n",k_base[t].name);
				printf("continue? (Y/N):");
				ch=tolower(getche());
				printf("\n");
				if(ch=='n') return;
			}
		}
		printf("No (more) object(s) found\n");
	}

	/* try an object */
	try(p,ob)
	struct attribute *p;
	char *ob;
	{
		char answer;
		struct attribute *a,*t;
		if(!trailno(p,ob)) return 0;
		if(!trailyes(p,ob)) return 0;
		while(p){
			/*if already been asked then move on to next attribute */
			if(ask(p->attrib)){
				printf("is/does/has it %s? ",p->attrib);
				answer=tolower(getche());
				printf("\n");

				a=(struct attribute *)malloc(sizeof(at));
				if(!a){
					printf("out of memory\n");
					return;
				}
				a->next='\0';
				switch(answer){
					case 'n':
						strcpy(a->attrib,p->attrib);
						if(!no){
							no=a;
							nonext=no;
						}
						else{
							nonext->next=a;
							nonext=a;
						}
						reject(ob,p->attrib,'n');
						return ;
					case 'y':
						strcpy(a->attrib,p->attrib);
						if(!yes){
							yes=a;
							yesnext=yes;
						}
						else{
							yesnext->next=a;
							yesnext=a;
						}
						p=p->next;
						break;
					case 'w':/* why? */
						reasoning(ob);
						break;
					}
				}
				else p=p->next;
			}
			return 1;
		}

		/* see if it has any attributes known not to be part of the
			object by checking the no list */
		trailno(p,ob)
		struct attribute *p;
		char *ob;
		{
			struct attribute *a,*t;
			a=no;
			while(a){
				t=p;
				while(t){
					if(!strcmp(t->attrib,a->attrib)){
						reject(ob,t->attrib,'n');
						return 0;/*does hve a negative attribute */
					}
					t=t->next;
				}
				a=a->next;
			}
			return 1;
		}

		/* see if it has all attributes known
			to be part of the object by checking the yes list */
		trailyes(p,ob)
		char *ob;
		{
			struct attribute *a,*t;
			char ok;

			a=yes;
			while(a){
				ok=0;
				t=p;
				while(t){
					if(!strcmp(t->attrib,a->attrib)){
						ok=1;/*does have a needed attribute */
					}
					t=t->next;
				}
				if(!ok){
					reject(ob,a->attrib,'y');
					return 0;
				}
				a=a->next;
			}
			return 1;
		}
		/* see if attribute already asked */
		ask(attrib)
		char *attrib;
		{
			struct attribute *p;

			p=yes;
			while(p && strcmp(attrib,p->attrib))
				p=p->next;

			if(!p)return 1;/* false if end of list */
			else return 0;
		}
		/* show why a line of reasoning is being followed */
		reasoning(ob)
		char *ob;
		{
			struct attribute *t;
			int i;

			printf("Trying %s\n",ob);
			if(yes)
				printf("it is/has/does:\n");
			t=yes;
			while(t){
				printf("%s\n",t->attrib);
				t=t->next;
			}
			if(no)printf("it is/has/does not:\n");
			t=no;
			while(t){
				printf("%s\n",t->attrib);
				t=t->next;
			}

			for(i=0;i<=r_pos;i++){
				printf("%s is rejected because ",r_base[i].name);
				if(r_base[i].condition=='n')
					printf("%s is not an attribute.\n",r_base[i].name);
				else
					printf("%s is a required attribute.\n",r_base[i].attrib);
			}
		}

		/* place rejected object into database */
		reject (ob,at,cond)
		char *ob,*at,cond;
		{
			r_pos++;
			strcpy(r_base[r_pos].name,ob);
			strcpy(r_base[r_pos].attrib,at);
			r_base[r_pos].condition=cond;
		}

		/* get next free index in k_base array */
		get_next()
		{
			l_pos++;
			if(l_pos<MAX)return l_pos;
			else return -1;
		}

		menu()
		{
			char ch;
			printf("(E)nter,(Q)uery,(S)ave,(L)oad,e(X)it\n");
			do{
				printf("choose one: ");
				ch=tolower(getche());
				}while(!is_in(ch,"eqslx"));
			printf("\n");
			return ch;
		}

		save()
		{
			int t,x;
			struct attribute *p;
			FILE *fp;
			if((fp=fopen("expert.dat","w"))==0){
				printf("cannot open file\n");
				return;
			}
			printf("saving knowledge base\n");
			for(t=0;t<=l_pos;++t){
				for(x=0;x<sizeof(k_base[t].name);x++)
					putc(k_base[t].name[x],fp);
				p=k_base[t].alist;/*原来是k_base[c].alist;下标是c,可以根本没定义变量c. */
				while(p){
					for(x=0;x<sizeof(p->attrib);x++)
						putc(p->attrib[x],fp);
					p=p->next;
				}
				/* end of list marker */
				for(x=0;x<sizeof(p->attrib);x++)putc('\o',fp);
			}
			putc(0,fp);
			fclose(fp);
		}

		load()
		{
			int t,x;
			struct attribute *p,*oldp;
			FILE *fp;
			if((fp=fopen("expert.dat","r"))==0){
				printf("cannot open file\n");
				return;
			}
			printf("loading knowledge base\n");
			/*free any old lists */
			clear_kbase();
			for(t=0;t<MAX;++t){
				if((k_base[t].name[0]=getc(fp))==0)break;
				for(x=1;x<sizeof(k_base[t].name);x++)
					k_base[t].name[x]=getc(fp);

				k_base[t].alist=(struct attribute *)malloc(sizeof(at));
				p=k_base[t].alist;
				if(!p){
						printf("Out of memory\n");
						return;
				}
				for(;;){
					for(x=0;x<sizeof(p->attrib);x++)
						p->attrib[x]=getc(fp);
					
					oldp=p;/*加上此行*/
					if(!p->attrib[0]){
						oldp->next='\0';
						break;/* end of list */
					}
					p->next=(struct attribute *)malloc(sizeof(at));
					if(!p->next){
						printf("out of memory\n");
						break;
					}
					oldp=p;
					p=p->next;
				}
			}

			fclose(fp);
			l_pos=t-1;
		}

		clear_kbase()
		{
			int t;
			struct attribute *p,*p2;
			
			for(t=0;t<=l_pos;t++){
				p=k_base[t].alist;
				while(p){
					p2=p->next;
					free(p);
					p=p2;
				}
			}
		}
			
		is_in(ch,s)
		char ch,*s;
		{
			while(*s)
				if(ch==*s++)return 1;
			return 0;
		}
			

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -