Source Code: Robbie the Robot
ROBBIE.KSL Listing
/*
Robbie the Robot Example - Phil Vasey and Alan Westwood february 1999
=====================================================================
This example demonstrates the use of forward-chaining in a
configuration and resource allocation problem.
Description
-----------
This example implements a shopping expert system. The problem is in
three distinct stages:
1. Query the user to get the initial shopping list.
2. Check the compatibility of the items on the shopping list.
3. Pack the items on the shopping list into bags.
Running the Example
-------------------
The top-level goal to run the expert system is run/0. This can
be invoked by entering the following goal:
?- run.
Flex Technical Points
---------------------
The following flex technical points are demonstrated in this example:
1. Data-driven launch procedure.
2. The use of synonyms and templates
3. The use of nested groups
*/
% the text "choose a carrier X for Y" is mapped on to choose_bag( X, Y )
template choose_bag
choose a carrier ^ for ^ .
template pack_item
pack ^ .
% the following action is the backbone of the expert system
% the three stages are clearly defined
action run ;
do restart
and init_gensym( bag_number_ )
and write( '<h3>Asking for the initial shopping list<//h3>' )
and ask shopping
and display_shopping( initial )
and write( '<h3>Checking the compatibility of items<//h3>')
and invoke ruleset checking_rules
and display_shopping( final )
and write( '<h3>Packing the items into bags<//h3>' )
and invoke ruleset packing_rules
and display_bags .
% the following actions display information of various kinds
action write_nl( Message )
do nl
and write( Message )
and nl .
action display_shopping( Stage )
do write( 'The shopping list at the <em>' )
and write( Stage )
and write( '<//em> stage is ...' )
and write( '<ul>' )
and for all member( Item, shopping )
do write( '<li>' )
and write( Item )
and write( '<//li>' )
end for
and write( '<//ul>' ) .
% the nested for loops in the following action display every bag
% and every item in each bag
action display_bags
do nl
and for every Bag is some carrier
do write( '<h3>The contents of carrier ' )
and write( Bag )
and write( ' is<//h3>' )
and for every Item is included in the contents of Bag
do write( Item )
and tab( 1 )
end for
end for .
action display_new_bag( Bag )
do write( '<p><em>I Need a new carrier : ' )
and write( Bag )
and write( '<//em><//p>' ) .
action display_packed_item( Item, Bag )
do write( 'Packing ' )
and write( Item )
and write( ' into ' )
and write( Bag )
and write( '<br>' ) .
% the word large_maximum is replaced by 1 wherever it occurs in the file
synonym large_maximum 1 .
synonym items_maximum 3 .
% a frame and a launch procedure define the carrier bags
frame carrier
default contents are empty .
% the launch procedure creates and then reports a new carrier bag
launch new_carrier
when Bag is a new carrier
then display_new_bag( Bag ) .
% this action makes use of the choose_bag and pack_item templates to make
% the action easier to read
action pack an Item ;
do choose a carrier Bag for the Item
and remove the Item from the shopping
and include the Item in the Bag`s contents
and display_packed_item( Item, Bag ) .
% this relation either selects a currently used bag or creates a new one
relation choose a carrier Bag for an Item
if the Bag is some carrier
and length( the Bag`s contents, Count )
and if the Item`s size is large
then Count is less than the large_maximum
else Count is less than the items_maximum
end if
and ! .
relation choose a carrier Bag for an Item
if gensym( bag_number_, Bag )
and Bag is a new carrier .
% the goods group also includes the drink and nibbles groups
group goods
bread, butter, coffee, ice_cream, nibbles, drink, washing_powder .
group drink
beer, lemonade .
group nibbles
crisps, salted_peanuts .
% this section defines the characteristics of the items on the shopping
frame item .
frame large_item is an item ;
default size is large .
frame medium_item is an item ;
default size is medium .
frame small_item is an item ;
default size is small .
frame bread is a medium_item
default container is a plastic_bag and
default condition is fresh .
frame butter is a small_item
default container is a plastic_carton and
default condition is fresh .
frame coffee is a medium_item
default container is a jar and
default condition is freeze_dried .
frame ice_cream is a medium_item
default container is a cardboard_carton and
default condition is frozen .
frame crisps is a small_item
default container is a plastic_bag and
default condition is fragile .
frame salted_peanuts is a small_item
default container is a plastic_bag and
default condition is salted .
frame beer is a large_item
default container is a bottle and
default condition is liquid .
frame lemonade is a large_item
default container is a bottle and
default condition is liquid .
frame washing_powder is a large_item
default container is a cardboard_carton and
default condition is powder .
% this section defines the questions used in the expert system
question shopping
What is on your shopping list today ? ;
choose some of goods
because I need to check your shopping and then pack it into bags .
frame shopping_style ;
default prefill is { crisps, butter } and
default rows is 4 .
question drink
You must select a drink ! ;
choose one of drink
because There are nibbles on your shopping list .
frame drink_style ;
default method is radio and
default infix is br and
default rows is 4 and
default prefill is lemonade .
% this ruleset defines the forward chaining checking phase
% successful rules are removed after they are fired
ruleset checking_rules contains
check_nibbles,
check_bread_and_butter,
check_butter_and_bread ;
update ruleset by removing each selected rule .
rule check_nibbles
if the shopping includes X and X is some nibbles
and the shopping does not include some drink
then ask drink
and include the drink in the shopping
because Nibbles make you thirsty .
rule check_bread_and_butter
if the shopping includes bread
and the shopping does not include butter
then include butter in the shopping
and write( '<p>You forgot the butter!<//p>' )
because Bread is very dry by itself .
rule check_butter_and_bread
if the shopping includes butter
and the shopping does not include bread
then include bread in the shopping
and write( '<p>You forgot the bread!<//p>' )
because What is the use of butter without bread .
% this ruleset defines the forward chaining packing phase
% rules that do not apply are removed
ruleset packing_rules contains
pack_frozen_item,
pack_large_bottle,
pack_other_large_item,
pack_medium_item,
pack_small_item ;
update ruleset by removing any unsatisfied rules .
rule pack_frozen_item
if the shopping includes an Item
and the Item`s condition is frozen
then pack the Item .
rule pack_large_bottle
if the shopping includes an Item
and the Item`s container is bottle
and the Item`s size is large
then pack the Item .
rule pack_other_large_item
if the shopping includes an Item
and the Item`s size is large
then pack the Item .
rule pack_medium_item
if the shopping includes an Item
and the Item`s size is medium
then pack the Item .
rule pack_small_item
if the shopping includes an Item
and the Item`s size is small
then pack the Item .