Source Code: Holidays

HOLIDAYS.KSL Listing

/*

   HOLIDAYS.KSL  - Clive Spenser May  2002
                 - Updated       July 2003

This program is based on TREE.KSL and generates a question/answer session on the subject of holidays.

It uses the group and question definitions, and a number of different relations.

Method
------

We use partially named relations and partially parametrised;

each relation performs a test of the form:

'if questionN is value'

This invokes the Flex Question/Answer mechanism.
Depending on the answer, we follow down a different branch of the tree.
This is in the form of invoking another relation.

We have N tests in a relation to handle the N different answers.

Notice: we have slightly different questions for the different branches.

The tree, viewed thru the names of the relations, is:

level0
   level1(y)
      level2(y,a)
         level3(y,a,X)
      level2(y,b)
         level3(y,b,X)
      level2(y,c)
         level3(y,c,X)
   level1(n)
      level2(n,a)
         level3(n,a,X)
      level2(n,b)
         level3(n,b,X)
      level2(n,c)
         level3(n,c,X)

Branching 2 then 3 then 4; this gives 24 outcomes (leaf nodes)

There are questions for each brach with a related name, which take their
options from a group. The naming convention is:

levelN_X

where N is the level number and
      X is y/n or a/b/c relating to the answer

and

levelN_X_q

is the next question to ask

As the method is totally generic, you can easily (?) adapt the example to fit your domain

*/


action run1;
   do  restart
   and level0
   and display_reasons
   and true .

/* pick-up the answers and reverse them in a set
   we use the $ symbol to avoid derefencing the name of the question to the answer */
action display_reasons;
   do  true
   and findall( cv(Q,B), valid_answered_question(Q,B), AnswersRev )
   and sort( $AnswersRev, Answers )
   and write_answers( $Answers )
   and !
   and true .

action valid_answered_question( Q, B )
   do  true
   and current_value( Q, A, B )
   and isa_question( Q, _, _, _ )
   and true .


/* extract the first answer and call program to write it out */
relation write_answers( {} ).
relation write_answers( Items )
   if  remove( First, $Items, Rest )
   and write_one_answer( $First )
   and write_answers( $Rest ).

/* writes out one answer */
action write_one_answer( cv(Q,B) );
   do  true
   and isa_question( Q, Text, _, _)
   and my_write_list_to_string( Text , TText )
   and !
   and write( ' You answered: ')
   and write( B )
   and write(' to: ')
%   and write( $Q )
   and write( ''  )
   and write( TText  )
   and write( '' )
   and true .


relation my_write_list( {} ) .
relation my_write_list( Items )
   if  remove( First, Items, Rest )
   and write( First ) and write(' ')
   and my_write_list( Rest ) .


action my_write_list_to_string( Items, TText )
   do ~>( my_write_list( Items), TText ) .


relation level0
   if  true
   and ask  level0_q
   and ans( level0_q, YN )
   and findall( R, get_recommendation(YN,ABC,_,R), Rs )
   and viabilities becomes empty
   and include Rs in viabilities
   and level1( YN ).

relation level1(y)
   if  ans( level1_y_q, yes, ABC)
   and findall( R, get_recommendation(y,ABC,_,R), Rs )
   and viabilities becomes empty
   and include Rs in viabilities
   and level2( y, ABC ) .

relation level1(n)
   if  ans( level1_n_q, no , ABC)
   and findall( R, get_recommendation(n,ABC,_,R), Rs )
   and viabilities becomes empty
   and include Rs in viabilities
   and level2( n, ABC ) .

/* end of level1 */

/* level 2    */

/* level 2y   */
relation level2( y, a)
   if  ans( level2_ya_q, yes, a, Sel )
   and level3( y, a, Sel) .
relation level2( y, b)
   if  ans( level2_yb_q, yes, b, Sel )
   and level3( y, b, Sel) .
relation level2( y, c)
   if  ans( level2_yc_q, yes, c, Sel )
   and level3( y, c, Sel) .

relation level2( n, a)
   if  ans( level2_na_q, no , a, Sel )
   and level3( n, a, Sel) .
relation level2( n, b)
   if  ans( level2_nb_q, no , b, Sel )
   and level3( n, b, Sel) .
relation level2( n, c)
   if  ans( level2_nc_q, no , c, Sel )
   and level3( n, c, Sel) .


/* the questions */

/* choice of yes or no */

question level0_q
   Do you prefer hot to cold holidays? ;
   choose one of yesno .

/* choice of a, b, c */

question level1_y_q
   Which continent do you prefer? ;
   choose one of abc_y .

question level1_n_q
   Which continent do you prefer? ;
   choose one of abc_n .

/* choice of 1, 2, 3, 4 */
question level2_ya_q
   Which terrain do you prefer? ;
   choose one of '1234_ya'.

question level2_yb_q
   Which terrain do you prefer? ;
   choose one of '1234_yb'.

question level2_yc_q
   Which terrain do you prefer? ;
   choose one of '1234_yc'.

question level2_na_q
   Which terrain do you prefer? ;
   choose one of '1234_na'.

question level2_nb_q
   Which terrain do you prefer? ;
   choose one of '1234_nb'.

question level2_nc_q
   Which terrain do you prefer? ;
   choose one of '1234_nc'.

/* Style descriptions */

frame generic_style ;
   default method is radio .

frame level0_q_style    is a generic_style .
frame level1_y_q_style  is a generic_style .
frame level1_n_q_style  is a generic_style .
frame level2_ya_q_style is a generic_style .
frame level2_yb_q_style is a generic_style .
frame level2_yc_q_style is a generic_style .
frame level2_na_q_style is a generic_style .
frame level2_nb_q_style is a generic_style .
frame level2_nc_q_style is a generic_style .


/* the answers */

relation level3( Y, A, Num )
   if  true
   and get_recommendation( Y, A, Num, Message )
   and viabilities becomes empty
   and write( Message )
   and include Message in viabilities
   and true .

relation get_recommendation( y, a, 1,'I suggest a trip down the Nile' ) .
relation get_recommendation( y, a, 2,'I suggest a trip to Gambia'     ) .
relation get_recommendation( y, a, 3,'I suggest a trip to the Sahara' ) .
relation get_recommendation( y, a, 4,'I suggest a trip to Nigeria'    ) .

relation get_recommendation( y, b, 1,'I suggest a trip along the Amazon' ) .
relation get_recommendation( y, b, 2,'I suggest a trip to Bahia'     ) .
relation get_recommendation( y, b, 3,'I suggest a trip to  Venezuela' ) .
relation get_recommendation( y, b, 4,'I suggest a trip to Peru'    ) .

relation get_recommendation( y, c, 1,'I suggest a trip along the Rhone' ) .
relation get_recommendation( y, c, 2,'I suggest a trip to Faro'     ) .
relation get_recommendation( y, c, 3,'I suggest a trip to the Alps' ) .
relation get_recommendation( y, c, 4,'I suggest a trip to Venice'    ) .

relation get_recommendation( n, a, 1,'I suggest a trip to Katmandu' ) .
relation get_recommendation( n, a, 2,'I suggest a trip to Siberia'     ) .
relation get_recommendation( n, a, 3,'I suggest a trip to Anartica' ) .
relation get_recommendation( n, a, 4,'I suggest a trip to Mongolia'    ) .

relation get_recommendation( n, b, 1,'I suggest a trip along the Mississippi' ) .
relation get_recommendation( n, b, 2,'I suggest a trip to Boston'     ) .
relation get_recommendation( n, b, 3,'I suggest a trip to the Rockies' ) .
relation get_recommendation( n, b, 4,'I suggest a trip to Victoria'    ) .


relation get_recommendation( n, c, 1,'I suggest a trip along the Rhine' ) .
relation get_recommendation( n, c, 2,'I suggest a trip to Baltic'     ) .
relation get_recommendation( n, c, 3,'I suggest a trip to the Alps' ) .
relation get_recommendation( n, c, 4,'I suggest a trip to Ireland'    ) .

/* the groups for the questions */

group yesno
   yes,
   no .

group abc_y
   'Africa',
   'South America',
   'Europe'.

group abc_n
   'Asia',
   'North America',
   'Europe'.

group '1234_ya'
   rivers, sea, desert, mixed .

group '1234_yb'
   rivers, sea, desert, mixed .

group '1234_yc'
   rivers, sea, mountains, mixed .

group '1234_na'
   rivers, sea, snow, mixed .

group '1234_nb'
   rivers, sea, ice, mixed .

group '1234_nc'
   rivers, sea, mountains, mixed .


/* ans/2 is a utility which maps real anserws on pseudo answers */
relation ans( yes,        y ).
relation ans( no,         n ).


/* ans/3 is a utility which maps real anserws on pseudo answers */
relation ans( 'Africa',        yes, a ).
relation ans( 'South America', yes, b ).
relation ans( 'Europe',        yes, c ).

relation ans( 'Asia',          no,  a ).
relation ans( 'North America', no,  b ).
relation ans( 'Europe',        no,  c ).


/* ans/4 is a utility which maps real anserws on pseudo answers */
relation ans( rivers,      yes, a, 1 ).
relation ans( sea,         yes, a, 2 ).
relation ans( desert,      yes, a, 3 ).
relation ans( mixed,       yes, a, 4 ).

relation ans( rivers,      yes, b, 1 ).
relation ans( sea,         yes, b, 2 ).
relation ans( desert,      yes, b, 3 ).
relation ans( mixed,       yes, b, 4 ).

relation ans( rivers,      yes, c, 1 ).
relation ans( sea,         yes, c, 2 ).
relation ans( mountains,   yes, c, 3 ).
relation ans( mixed,       yes, c, 4 ).

relation ans( rivers,      no,  a, 1 ).
relation ans( sea,         no,  a, 2 ).
relation ans( snow,        no,  a, 3 ).
relation ans( mixed,       no,  a, 4 ).

relation ans( rivers,      no,  b, 1 ).
relation ans( sea,         no,  b, 2 ).
relation ans( ice,         no,  b, 3 ).
relation ans( mixed,       no,  b, 4 ).

relation ans( rivers,      no,  c, 1 ).
relation ans( sea,         no,  c, 2 ).
relation ans( mountains,   no,  c, 3 ).
relation ans( mixed,       no,  c, 4 ).