Artificial Intelligence and Prolog
Copyright © 2020 Jiri Kriz, www.nosco.ch

9    An Information System

Solution of Exercise 9

/* Inference Shell */

:- dynamic tr/1.  /* For SWI Prolog */
:- dynamic tr_index/1.  

index_set( Index) :-
	retractall(tr_index(_)),
	assert(tr_index(Index)).

trace_set( List) :-
	retractall(tr(_)), 
	assert(tr(List)).
 
trace_update( ID) :- 
	tr( T), tr_index( Ix),
	length(T, Len),
	(Ix < Len -> list_crop(T, Len, Ix, T_cropped)
			  ;  T_cropped = T
	),
	Ix1 is Ix + 1,
	trace_set([ ID| T_cropped]),
	index_set( Ix1).	
	
trace_move( Offset, Elem) :-
	tr( T), tr_index( Ix),
	length(T, Len),
	Ix1 is Ix + Offset,
	RevIx is Len - Ix1 + 1,
	list_element(T, RevIx, Elem),
	index_set( Ix1).
	
init :- trace_set( []), index_set( 0).
     
show( ID) :-
     ( object( ID, _, _, _) -> trace_update( ID), display( ID)
	                       ;  write( 'object does not exist'), nl
     ),  !.
  
back :-
	tr_index(Ix),
	(Ix > 1 -> trace_move( -1, ID), display( ID)
			;  write( 'already at the beginning')
    ), !.

fwd :-
	tr( T), tr_index( Ix),
	length( T, L),
	(Ix < L -> trace_move( 1, ID), display( ID)
			;  write( 'already at the end')
    ), !.

     
list_element([ Elem| _], 1, Elem).
list_element([ _| Elems], N, Elem) :-
	N1 is N - 1,
	N1 > 0,
	list_element(Elems, N1, Elem).
	
list_crop(List, Len, Len, List).
list_crop([ _| Elems], Len, Ix, List_cropped) :-
	Len > Ix, 
	Len1 is Len - 1, 
	list_crop(Elems, Len1, Ix, List_cropped).

display( ID) :-
     object( ID, Name, Text, Refs),
     nl,
     write( Name), 
     write( ' (ID='), write( ID), write( ')'), nl, nl,
     write_text( Text), nl,
    ( Refs \= [] -> write( 'See also:'), nl, 
					write_objects( Refs)
				  ; true
     ), !.
	 
show_all :-
     object( ID, Name, _, _),
     write( ID - Name), nl, fail.
show_all.	
     
trace :-
     tr( Trace), write_objects( Trace),
     !.
     
write_text( [ T| Ts]) :- 
     write( T), nl,
     write_text( Ts).
write_text( []) :- !.

write_objects( [ ID| IDs]) :- 
     object( ID, Name, _, _),
     write( ID - Name), nl,
     write_objects( IDs).
write_objects( [ ]) :- !.
 

:- init.

/* Knowledge Base */	 

object( 1, 'Atom',	 
	['is the smallest constituent unit of ordinary matter ', 
	'that has the properties of a chemical element. ',
	'Every atom is composed of a nucleus and ',
	'one or more electrons bound to the nucleus.'], 
	[2, 3, 6] ).

object( 2, 'Atomic nucleus',
	['is the very dense region consisting of ',
	'protons and neutrons at the center of an atom. ',
	'Protons are positively charged while ',
	'neutrons have no electrical charge. ',
	'Atoms that differ only in the number of neutrons ',
	'are called isotopes.'],
	[4, 5, 1]).

object( 3, 'Electron',
	['is a stable, negatively charged elementary particle ...'],
	[1]).
	
object( 4, 'Proton',
	['is a stable, positively charged elementary particle ...'],
	[2]).
	
object( 5, 'Neutron',
	['is a stable elementary particle without electrical charge ...'],
	[2]).

object( 6, 'Nuclear power',
	['is the use of nuclear reactors to release nuclear energy, ',
	'and thereby generate electricity. ',
	'Nuclear binding energy is the energy that would be required ',
	'to disassemble the nucleus of an atom into its component parts. '],
	[]).

Back to example 9.0