Science
Copyright © 2024 Jiri Kriz, www.nosco.ch

10    Rule-based Shell, Diagnosis

Solution of Exercise 10

10.1    Rule-based Shell (Backward Reasoning)

/* rules:  symptoms -> diagnosis
   the answers of the user are recorded
*/

:- dynamic told/2.		/* For SWI Prolog */

/* SWI Prolog does not allow to use or redefine the operator ':'
   so we use '#' instead. 
*/
 
define_operators :-
    op( 910, fy,  not), 
    op( 920, xfy, and), 
    op( 930, xfy, or),
    op( 940, xfx, cf), 
    op( 950, xfx, then),
    op( 960, fx,  if),
    op( 970, xfx, #).
	 
:- define_operators.

/* Inference Engine: rules, backward */

solve( P1 and P2) :- solve( P1), solve( P2).
solve( P1 or P2) :- solve( P1) ; solve( P2).
solve( not P) :- \+ solve( P).

solve( P) :- Rule # if P0 then P, solve( P0).
solve( P) :- Fact # P.

solve( P) :- askable( P), told( P, yes).
solve( P) :- askable( P), not told( P, _), ask( P).

ask( P) :- nl, write( P), write( ' [yes./no.] ? '),
           read( A), respond( P, A).
   
respond( P, yes) :- assert( told( P, yes)), !.
respond( P, no) :- assert( told( P, no)), !, fail.
respond( P, _) :- write(' valid answers are: yes, no'), ask( P).

init :- retractall( told( _, _)).


/* Shell for diagnosis */

diagnose( D) :-
    init,
    Fact # diagnosis( D),
    solve( D).

askable( S) :- Fact # symptom( S).

Back to example 10.1

10.2    Rule-based Diagnosis (Hypothesis Testing)

/* The shell from 10.1 must be consulted first */
	 
r1 # if   cloth_burnt 
     then temperature( too_high).

r2 # if   temperature( too_high) 
       or temperature( too_low)
     then temperature( wrong).

r3 # if   temperature( wrong)
      and thermostat( setup_correctly)
     then thermostat( faulty).

r4 # if   temperature( wrong)
      and not thermostat( setup_correctly)
     then thermostat( adjust_correctly).

r5_1 # if   no_steam
       then temperature( too_low).

r5_2 # if   no_steam 
       then steam_problem.

r6_1 # if   steam_problem 
       then no_water.

r6_2 # if   steam_problem
       then nozzle_congested.

r7 # if   ironing_poor 
     then temperature( too_low).

r8 # if   iron_cold 
      and lamp_shines
     then wait.

r9 # if   iron_cold 
      and not lamp_shines
     then no_power.

s1 # symptom( cloth_burnt).
s2 # symptom( no_steam).
s3 # symptom( ironing_poor).
s4 # symptom( iron_cold).
s5 # symptom( lamp_shines).
s6 # symptom( thermostat( setup_correctly)).

d1 # diagnosis( thermostat( faulty)).
d2 # diagnosis( thermostat( adjust_correctly)).
d3 # diagnosis( no_water).
d4 # diagnosis( nozzle_congested).
d5 # diagnosis( no_power).
d6 # diagnosis( wait).

/* Testing
?- diagnose(Fault).
*/

Back to example 10.2