I developed an expert system that is capable of assisting a medical professional diagnose a patient with an explicit heart condition. The system will then, based upon that heart condition and its specifications, prescribe the proper treatment for the diagnosis.
In this expert system I used the forward and backward chaining algorithms to properly assign the valid consequents to their corresponding rules based on a set of user queries output by the software. Predicated upon the user’s response, the software is able to guide the user “backwards” through the knowledge base, to a generated diagnosis. This approach is considered backwards since it is goal driven. This fact can be more easily visualized by observing the backward chaining decision tree that I developed, which is documented further in this report. Next, I constructed the forward chaining decision tree which is derived from the diseases established in the backward chaining decision tree. This means that instead of predicating my decisions upon diagnostic conclusions, I started at the root of the tree (the diseases) and branched out based upon specific characteristics of the patient, who would ultimately be prescribed the proper treatment for their disease. Since it would allow me to have the components of the knowledge base (the diseases) required in order to properly construct the forward chaining tree, I developed the backward chaining decision tree before I developed the forward chaining decision tree. It is typical for the backward chaining algorithm to be implemented into a program before the forward chaining algorithm.
As previously stated, this expert system is comprised of two primary algorithms that control the data-flow of the program. The first algorithm that is compiled when the program is ran is called the backward chaining algorithm. Although the functionality of this algorithm may not be obvious from the following code segement, the following segmement demonstrates a proper implementation of the algorithm in C++.
void diagnose()
{
printf("\n \nSTART THE PROCESS TO DIAGNOSE. \nHIT RETURN TO CONTINUE");
gets(buff);
printf("*** CONCLUSION LIST ***\n");
for (i=1; i<31; i++) printf("CONCLUSION %d %s\n", i,conclt[i]);
printf("HIT RETURN TO CONTINUE");
gets(buff);
printf("\n*** VARIABLE LIST *\n");
for(i=1; i<22; i++) printf("VARIABLE %d %s\n", i, varlt[i]);
printf("HIT RETURN KEY TO CONTINUE");
gets(buff);
printf("*** CLAUSE VARIABLE LIST ***\n");
for(i=1; i<31; i++)
{
printf("** CLAUSE %d\n", i);
for(int j=1; j<6; j++)
{ k = 5 * (i-1) + j;
cout <<"VARIABLE "<< j << " "<< find_var_in_clvarlt(clvarlt, k) << endl;
}
if (i==30)
{ printf("HIT RETURN KEY TO CONTINUE"); gets(buff); }
}
strcpy(DE,""); strcpy(BI,""); strcpy(SA,""); strcpy(PC,""); strcpy(HM,"");strcpy(MD,"");
strcpy(ST,""); strcpy(ID,""); strcpy(VS,""); strcpy(DI,""); strcpy(HF,"");
strcpy(VI,""); strcpy(SB,""); strcpy(DZ,""); strcpy(FA,""); strcpy(AR,"");
strcpy(NV,""); strcpy(EI,""); strcpy(AM,""); strcpy(FE,""); strcpy(PB,"");
strcpy(NA,""); strcpy(SR,""); strcpy(SL,""); strcpy(HC,""); strcpy(VO,""); strcpy(FN,""); strcpy(CP,"");
strcpy(HP,""); strcpy(TD,""); strcpy(SF,""); strcpy(RV,""); strcpy(HB,"");
printf("** ENTER CONCLUSION ? "); gets(varble);
this->process_stack();
printf("HIT RETURN TO CONTINUE");
gets(buff);
}
The second algorithm that is compiled when the program is ran is called the forward chaining algorithm. Although the functionality of this algorithm may not be obvious from the following code segement, the following segmement demonstrates a proper implementation of the algorithm in C++.
void recommend_treatment()
{
printf("START THE PROCESS TO FIND THE TREATMENT. \n HIT RETURN TO CONTINUE");
gets(buff);
printf("*** VARIABLE LIST ***\n");
for (i=1;i < 36; i++) printf("ENTER VARIABLE %d %s\n", i, varlt[i]);
printf("HIT RETURN TO CONTINUE");
gets(buff);
printf("\n*** CLAUSE-VARIABLE LIST ***\n");
for (i = 1; i < 24; i++)
{
printf("** CLAUSE %d\n", i);
for (j = 1; j < 6; j++)
{
k = 5 * (i - 1) + j;
cout <<"VARIABLE "<< j << " "<< find_var_in_clvarlt(clvarlt, k) << endl;
}
if (i==23)
{
printf("HIT RETURN TO CONTINUE");
gets(buff);
}
}
printf("\nPROCESSING TO GIVE THE TREATMENT \n");
strcpy(cndvar[bp], "HD");
bp = bp + 1;
sn = 1; cn = 1;
f=1;
find_treatment();
return;
}
void find_treatment()
{
search();
cn=1;
if (sn != 0)
{
i = 5 * (sn-1) + cn;
strcpy(v, (find_var_in_clvarlt(clvarlt, i)).c_str());
while (strcmp(v, "") && i < (5 * (sn-1) + 6)) // FIX
{
check_instantiation();/* check instantiation of this clause */
cn = cn+1;
i = 5 * (sn-1) + cn; /* check next clause */
strcpy(v, (find_var_in_clvarlt(clvarlt, i)).c_str());
}
s = 0;
check_if_part();
if (s != 1)
{
f = sn + 1;
find_treatment();
}
put_var_into_ccls_queue();
f = sn + 1;
find_treatment();
}
fp=fp+1;
if (fp < bp)
{
f = 1;
find_treatment();
}
return exit(EXIT_SUCCESS);
}
What I concluded from this project is a greater comprehension of expert systems and the implementation process of the forward and backward chaining algorithms. In reflection, developing this system has provided me with a greater understanding and appreciation of the intricacies involved in programming an artificially intelligent system. I’ve digested the significant details about all of the primary components that make up my expert system. These components are the user query (the questions generated by my program), the user interface (the output of my executable file), the inference engine (in this case the backward and forward chaining algorithms), the knowledge base (all of the stored rules and their accompanying data), the response to the user (the disease diagnosis and treatment generated by my program), and all of the other, less pertinent, data structures encapsuled within my expert system that give it the ability to suitably function. Furthermore, I was required to rehash my comprehension of some C++ concepts and structures that I was not familiar with. Generally, this project has challenged me to become an improved critical thinker, software engineer, and artificial intelligent systems developer.
Copyright © Lucas Thormann