EN → DE A-AA+ Sitemap Search

# 11    Rule-based Shell, Explanations

## 11.1    Rule-based Shell with Explanations

``````/* rules: symptoms -> diagnosis, backward chaining, explanation why, how */

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

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, Trace, Proof1 and Proof2) :-
solve( P1, Trace, Proof1), solve( P2, Trace, Proof2).

solve( P1 or P2, Trace, Proof) :- solve( P1, Trace, Proof).
solve( P1 or P2, Trace, Proof) :- solve( P2, Trace, Proof).

solve( not P, Trace, failed( P)) :- \+ solve( P, Trace, _).
/* sorry: negation not treated satisfactorily */

solve( P, Trace, Fact # P ) :- Fact # P.

solve( P, Trace, R # if Proof then P) :-
R # if P0 then P,
solve( P0, [R | Trace], Proof).

solve( P, Trace, told( P) ) :- told( P, yes).
solve( P, Trace, told( P) ) :- askable( P), \+ told( P, _),

ask( P, Trace) :- nl, write( P), write( ' [yes./no./why.] ? '),
read( A), respond( P, A, Trace).

respond( P, yes, Trace) :- assert( told( P, yes)), !.
respond( P, no, Trace) :- assert( told( P, no)), !, fail.

respond( P, why, []):- !, nl, write( ' you ask too many questions'),
respond( P, why, [H]) :- !, nl, write( H), write(' is my hypothesis'),
respond( P, why, [R | Trace]) :- !,
R # if G1 then G,
nl, write(' trying to apply the rule'),
show_rule( R # if G1 then G),
nl, write( 'to prove the conclusion '), write( G),

respond( P, _, Trace) :- write(' valid answers are: yes., no., why.'),

show_rule( R # if P0 then P) :-
nl, write( R ), write( ' # '),
nl, write( '   if   '), write( P0 ),
nl, write( '   then '), write( P ).

how1( G, Fact # G) :- !,
nl, write( G), write( ' is a fact '), write( Fact).

how1( G, told( G) ) :- !,
nl, write( G), write( ' was told me').

how1( not G, failed( G) ) :- !,
nl, write( not G), write( ' proved by failure of '), write( G).

how1( G, R # if _ then G) :- !,
nl, write( G), write( ' was proved by using the rule: '),
R # if P then G,
show_rule( R # if P then G).

how1( G, R # if Proof then _) :-
how( G, Proof).

how1( G, Proof1 and Proof2) :-
how( G, Proof1) ; how( G, Proof2).

how( G, Proof) :- how1( G, Proof), !.
how( G, _) :- nl, write( G), write( ' was not proved').

explain( Proof) :-
nl, nl, write( 'explanation ? [Goal./no.]: '), read( G),
( G \= no -> how( G, Proof), explain( Proof) ; true),
!.

backtrack :- nl, nl, write( 'further solutions ? [yes./no.]: '), read( no).

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

/* Shell */

shell :-
init,
goal( G),
solve( G, [G], Proof),
nl, nl, write( 'diagnosis: '), write( G),
explain( Proof),
backtrack.

test(G, Proof) :-
init,
goal( G),
solve( G, [G], Proof).

``````

Back to example 11.1

## 11.2    Rule-based Diagnosis

``````/* The shell from 11.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)

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)).
d3 # diagnosis( no_water).
d4 # diagnosis( nozzle_congested).
d5 # diagnosis( no_power).
d6 # diagnosis( wait).

diagnose :-
shell.

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

goal( G) :- D # diagnosis( G).

/* Testing
?- diagnose.
*/

``````

Back to example 11.2