HELP EDEN                                       Simon Perkins April 1992
                                                Jocelyn Ireson-Paine October 1992


CONTENTS

CHAPTER 1.........Introduction and overview of Eden
CHAPTER 2.........Eden's laws of physics
CHAPTER 3.........Running Eden
CHAPTER 4.........Writing brains to interface with Eden
CHAPTER 5.........Writing worlds for Eden
CHAPTER 6.........Additional facilities - the listener
CHAPTER 7.........Additional facilities - eden: saving cases and no-Ved
                  mode
CHAPTER 8.........Additional facilities - special output and
                  the view window
CHAPTER 9.........Useful routines
CHAPTER 10........Eden from Prolog
CHAPTER 11........Future extensions to Eden
CHAPTER 12........Conditions of use

You can jump to these chapters by searching for strings like 'CHAPTER
3' using the Ved command ENTER/search_stringRETURN.



CHAPTER 1 - Introduction
------------------------

Eden is a simple two-dimensional microworld written in Pop-11. You can
use it as a setting for AI programs by writing procedures to control a
``bug'' (named, with some lack of originality, Bug) which lives within
it. These procedures form Bug's brain; they have access to its
perceptions, and can use any AI techniques you want --- genetic
algorithms, neural nets, rule-based systems --- in arriving at sensible
actions which will keep Bug alive and fed.

Eden consists of a grid of cells, each of which can contain objects such
as keys, doors, boulders and quicksand. Bug's objective is to find and eat
a piece of food which the simulator has placed somewhere within this
grid. To do this, Bug must negotiate its way towards the food while
dealing intelligently with obstacles. Eden's laws of physics allow Bug
to take one of several different actions when it encounters an object.
The simulator then works out the consequences of the chosen action on
Bug and on Eden. Bug's perceptions are updated to reflect the new state
of the world, and the cycle repeats. It's important to choose the
actions with care! If you stop to use a key on a door, you'll open it;
but if you stop on a quicksand, you'll merely drown.

What actions is Bug allowed? Firstly, it can try moving forwards or
backwards, turning left or right. Sometimes, it will fail; it can move
``past'' some objects such as keys and hammers, but not past others
such as boulders and doors.

Bug can also grab and drop objects, picking up from, and dropping into,
the square it is currently standing on. Some objects, doors for example,
cannot be picked up.

There is a ``Use'' action which allows Bug to do sophisticated things
without needing lots of different commands. Its effect depends on what
Bug is holding and on the objects around it. For example, to eat food,
Bug ``uses'' it; to unlock a door, Bug ``uses'' a key while standing
next to the door.

Bug's sensory input is mainly visual, and allows it to see a 7 by 5
region around it. It can also perceive what it is holding (its
inventory) and how much energy it has left. In addition, it has a long
range sense of smell enabling it to tell which general direction the
food is in.

Bug's energy starts at an initial value set by the simulator, and
declines by one after each action. If it reaches zero, Bug dies. This
compels it to act intelligently rather than just performing brute force
search.

To implement a Bug brain, you must write a procedure named ``think'',
which the simulator calls once each cycle. This can access Bug's
perceptions by calling perceptual procedures which we supply, and must
return an action as its result.


The importance of learning
--------------------------

Eden is different from many microworlds in that Bug dies as soon as it
has eaten the first piece of food. It may also succumb to various
objects such as quicksands --- and, as we said above, it dies when it
runs out of energy.

This is less severe than it sounds. After each death, the simulator puts
Bug back into its original starting position, resets the rest of the
world to its starting state, calls ``bugdead'', and resets Bug's energy
to its initial value. However, Bug's brain is unaffected by the process,
and so when it dies, Bug does not forget anything it has already
learned. This makes death more like the ``go back to start'' square in a
board game.

This structure of linked reincarnations allows bugs to learn by trial
and error. During one lifetime, Bug can build up whatever data
structures it wants. Production-system bugs might learn new IF-THEN
rules or amend their old ones; neural-net bugs might change their
synaptic strengths; genetic-algorithm bugs might evolve towards a new
population of genes. Because brains are unaffected by death, the
learning process can be taken as far as you want just by repeating
training runs. When Bug dies, the simulator calls ``bugdead'', which you
must also write. This procedure is passed Bug's final energy, and a
success/failure indicator to say whether it had found food or was killed
in some other way. This enables Bug to decide whether to reward or
punish its previous pattern of behaviour.

This shows the main reason for death. It imposes a time limit on Bug's
finding the food, and gives it another chance to solve the world should
it get itself trapped (though this will probably not happen in the
simpler worlds).

How much learning you make Bug do is up to you. You could program in
some a priori knowledge about the properties of objects, and just let it
learn how to survive, given this knowledge. You could even try to
program correct behaviour patterns, so that it is more-or-less
instinct-driven. If you do this, you will probably find yourself using
classical ``symbolic'' AI techniques, writing planners, expert systems,
and so on. Alternatively, you could render Bug as helpless as a new born
baby and insist that it learn about the objects themselves by trial and
error: that it learn that keys open doors but not boulders, that you can
pick up a key but not a door, and so on. If you try this, you will
probably end up writing a neural net or a genetic algorithm.


The philosopy of Eden
---------------------

The idea behind Eden was to design a range of microworlds that though
simple, do require intelligent behaviour to do well in. This is not
trivial even when Bug knows something about the properties of its world
in advance. For example, in a STRIPS-style planner, you would have to
tell Bug that using a hammer removes a rock and that using a key removes
a door. Even with this knowledge, it would still take a considerable
amount of ``intelligence'' before Bug could choose sensible actions when
confronted with a selection of these objects scattered around it.

However, even if such a planner were very good at solving worlds whose
object properties it knew, it would be no good at worlds where new types
of objects were introduced. Because I (Simon) believe that learning is
an essential part of intelligence, I have designed Eden to emphasise it,
and to encourage people to experiment with bugs that have no
pre-programmed knowledge whatsoever.

To this end, we supply a selection of worlds, ranging from trivially
easy to extremely taxing. The simplest world might just be one cell
surrounded by walls, within which Bug has been placed already holding
some food. Once Bug has learnt that using the food is the way to
succeed, you could make the world harder - perhaps by starting with the
food on the ground, so that Bug now has to learn to pick it up first. If
your Bug is good enough at learning, this process can be continued until
it can cope with quite difficult worlds. Having said this, Eden is
designed so that you need not experiment with learning if you don't want
to.


The competition
---------------

We wanted to encourage co-operation with people in other universities,
and have managed to get Eden accepted by the Poplog Users' Group as a
national competition. You can enter this competition too - or can just
experiment with Eden on your own. For details, see HELP COMPETITION.


CHAPTER 2 - Eden's laws of physics
----------------------------------

Worlds
------

The figure below shows our ``default world'', with a list of the
symbols:

        **********************************************
        * B        @ *            *    T             *
        *      QQQQQQ*            *                  *
        *      QQQQQQ*        ***********            *
        ** ** @QQQQkQ*        #         *            *
        *      QQQQQQ*        *********Q             *
        *      QQQQQQ*                *Q             *
        *          @ *                *Q             *
        *            *                *              *
        *        T   *                *              *
        *            *********        **************@*
        *            *                             *k*
        *            @                      ********@*
        *            *                      *+#      *
        *            *                      **********
        *            *                       *       *
        **********************************************

        B = Bug
        + = food        - eat this to gain energy.
        * = boulder     - impossible to move through.
        @ = rock        - can be smashed with hammer (T).
        # = door        - can be opened with key (k).
        Q = quicksand   - drowns you unless you immediately move off it.
        T = hammer      - smashes a rock.
        k = key         - opens a door.

Eden is two-dimensional, and divided into a rectangular grid of
squares. Each square can hold one object, and may also be able to
accomodate Bug. However, whether this is possible depends on
the object's ``size''. Boulders, rocks, and doors are big enough to
block a Bug from moving into the square they occupy; food, hammers,
and keys are smaller, and can be in the same square as a Bug.


Actions
-------

Bug can take one of eight actions:

    forward     back
    right       left
    grab        drop
    use         wait

Forward and back move one square forward or back, unless the square
being moved into is blocked as above, in which case nothing happens.

Right and left turn 90 degrees in the appropriate direction, but don't
move forward or back.

Drop and grab pick up or put down an object. If the Bug tries to grab an
object but the object is ``too heavy'', nothing will happen; also
nothing will happen if Bug is already carrying something. Dropping an
object leaves it in the current square; if this is already occupied by
another object (of whatever type) nothing happens.

Waiting does nothing for a turn.

The effect of using an object depends on its type, as summarised in the
table below. An n in the Use column means that using has no effect.

The table also indicates, in the Share column, what happens on moving
into the same square as an object. A y in the Share column means that
Bug can enter the same square as the object, n means it can't.

The Grab column indicates the effect of grabbing an object. y means that
it can be picked up; n, that it can't.

        Meaning   Grab  Share  Use
        -------   ----  -----  ---
    B   Bug       -     -      -
    +   food      y     y      (3)
    *   boulder   n     n      n
    @   rock      n     n      n
    #   door      n     n      n
    Q   quicksand n     (1)    n
    T   hammer    y     y      (4)
    k   key       y     y      (5)
    :   narrows   n     (2)    n

    (1) - moving forward or back off the quicksand is OK; any other
          action will drown you.
    (2) - you can only pass into a narrows if you are not holding
          anything.
    (3) - using food eats it; the simulator calls bugdead.
    (4) - using a hammer only does something if you are in front of
          a rock. The rock disappears, the hammer remains in your
          inventory.
    (5) - using a key only does something if you are in front of
          a door. The door and key both disappear.

In this table, the ``narrows'' is a new kind of object, not shown in the
default world. It corresponds to a narrow gap, that you can only move
through if not carrying anything.

Note that an unsuccessful action does not crash the system, it merely
has no effect.


Example
-------

    ***********
    *      *  *
    *   k  *  *
    *      *  *
    *  B   #  *
    *    * *  *
    *      *  *
    ***********

Bug is facing East. What actions must he take to open the door?

Answer:
    left, forward, right, forward, left, forward,
    grab,
    right, forward, forward, right, forward, forward, left,
    use

This answer was generated by an AI Bug that I (Jocelyn) am experimenting
with.


Energy, death, and reincarnation
--------------------------------

In most worlds, Bug starts off with 500 units of energy. This is reduced
by one each turn, whether or not the action was successful. If the
energy reaches zero, Bug dies. Bug also dies if it eats the food, or if
it drowns in a quicksand.

When your Bug dies, Eden calls the procedure 'bugdead' --- which you
must define --- with one argument. This argument is true if the Bug died
because it found food, and false if it died through running out of
energy, drowning, or for some other reason.

Your 'bugdead' must return an argument which tells Eden what to do next.
There are three choices:
(1) Exit from the simulation;
(2) Reincarnate in the current world;
(3) Reincarnate in a new world.


Bug's senses - vision
---------------------

Bug's main sense is vision. He sees a 5x7 rectangle, oriented as shown
below:

    .  .  .  .  .
    .  .  .  .  .         Bug here is facing upwards and
    .  .  .  .  .         is located in the 'H' position
    .  .  .  .  .
    .  .  .  .  .
    .  .  B  .  .
    .  .  .  .  .

So Bug's vision is biased towards the direction it is facing in. The
reason for doing this is the same reason humans don't have eyes in the
backs of their head - it allows you to have reasonably detailed fairly
long distance vision without having too much sensory input to handle.

As an example, in the default world, Bug would see the following:

     **  * QQ
      *
      *
      *
      *
      *B
      *

The B is a marker to indicate his position: he doesn't see it himself.
Note that near objects do not obstruct vision of more distant ones in
their line of sight.


Bug's senses - smell
--------------------

Bug also has a long-range sense of smell. This gives a partial
indication of the food's direction, as one of
    left    right   forward     back    here    carried

Unlike vision, smell works over any distance.


Bug's inventory
---------------

Bug can sense what it is carrying --- its ``inventory''. Strictly
speaking, this is unnecessary, since it can be deduced by knowing what
actions you have performed. However, it acts as a useful check, and
makes some programs easier to write. The inventory is returned as a
symbol denoting the object being carried.


Bug's energy
------------

Bug can sense how much energy it has left, as an integer. This is useful
in determining how urgent to make various actions. If energy is nearly
zero, you might want to make Bug less careful in seeking food.


Listening and replying to sentences
-----------------------------------

For those people interested in natural language processing, it is
possible to have Bug ``listen'' to sentences that you type at it, and to
reply to them.


CHAPTER 3  Running Eden
-----------------------

Running the program
-------------------

The program file is called EDEN.P. You first need to load it, which you
can do by calling
    lib eden;
from Pop-11.

You can then demonstrate it by calling
    eden( 'manual_bug', 'defaultworld' );

This loads the code defining the default world, and also that for a
``manual bug'', devised by Simon Perkins, which we supply. This bug has
no intelligence of its own, but simply reads actions as you type them
and carries them out.

The call to 'eden' will start up Ved, which the simulator uses to
display the world. You will see a simple pictorial representation of
Eden, one character representing each cell, as shown in the previous
chapter. Bug's position is shown by a 'B' in the cell containing it.
Empty cells are represented by spaces.

Having drawn the world, the simulator gives a status report on Bug's
energy, inventory, position, etc., and asks if you want to continue.
You have several possible replies:
(1) Typing 'y' will run the world for one cycle before giving the same
prompt.
(2) Typing 'n' stops the simulation and returns to Pop-11.
(3) Typing 's' followed by a space and a number runs the world for that
number of cycles before asking if you want to continue again. We call
this ``slow'' mode, because the screen is updated on every cycle.
(4) Typing 'f' followed by a space and a number runs the world in fast
mode for that number of cycles. With fast mode enabled, the simulator
does not update the screen until the continue prompt is next given. This
allows you to run a large number of cycles much faster than in slow mode
where the screen is updated every cycle.
(5) Typing 'l' enables you to pass a sentence for Bug to ``listen'' to.
See Chapter 6, on the Eden ``listener''.
(6) Typing 'p' enables you to pass a piece of Pop-11 code to be obeyed.
This works in a similar way to the listener. However, instead of a
sentence, you should type one or more Pop-11 statements, which Eden
will obey.
(7) Typing 'r' refreshes the screen. This is useful if, say, the
operators have just broadcast a general message, and you want to remove
it.

In each case, you must hit RETURN after replying. Note that your
keystrokes are not displayed as you respond to this question. One thing
that catches many people out is if you accidentally type some extra
characters before answering the question and hitting RETURN, the program
will not understand what you meant and will repeat the question. In such
a case just be patient and retype.


The manual bug
--------------

The ``manual bug'' was described above. It prompts you for actions,
which it then returns as the result of its ``thoughts''. The prompts for
this are self-explanatory. All replies are one letter long, and you must
not hit RETURN after them. You can type in upper or lower case.


Other bugs
----------

We have one very simple bug. To demonstrate it, do
    eden( 'very_simple_bug', 'tw2' );

You can examine its code by the Pop-11 command
    showlib very_simple_bug
which you can give directly to Pop-11, or as a Ved ENTER command.

We also have some other bugs. These are not, at the moment, intended to
solve any problems in AI. Instead, they just demonstrate how to use
various features of Eden. Their names are
    exec_bug:           Demonstrates how to use the 'exec' library:
                        see Chapter 8.
    ps_bug:             A bug which uses the production system library
                        LIB PRODSYS.
    pse_bug:            Uses this and 'exec' to make a more realistic
                        production system.
    reincarnating_bug:  Shows how to pass from one world to another.
    search_bug:         Demonstrates various types of search, using
                        the 'exec' library.
    talk_bug:           Responds to simple sentences.
You can use 'showlib' to look at the code of any of these, as above.
search_bug needs to be run in treeworld; the others in one of the
tw training worlds, or in defaultworld.


Where the worlds and bugs are kept
----------------------------------

All the Eden stuff is kept safely as a Pop-11 library. To prevent it
getting accidentally or deliberately corrupted, it is not kept in the
AISOC account. This includes the worlds and bugs.

As you have seen above, if you pass the name of one of our library
worlds or bugs to 'eden', it will be able to find and load it. How can
you do this for your own worlds and bugs? When you give a filename to
'eden', it checks for it first in your own directory. If it can't find
it, it then looks in the library. So if you have a file with the same
name as one of ours, it will override the library version.

The Pop-11 command 'showlib' always looks in our library directories, so
you can say things like
    showlib talk_bug
to show you the code for that bug. If you want to print it, you can then
use the standard Ved commands to copy it into one of your own files, and
print that.

To look at a world, do
    help tw2
The original pictures of the worlds are kept with the HELP files, so
HELP will find them.


CHAPTER 4  Writing brains for Eden
----------------------------------

To write a brain to control Bug, you have to write a procedure called
'think'. This is called by the Eden simulator whenever it needs to
give Bug his next turn. Less important, but still necessary, are
procedures called 'start_thinking' and 'bugdead', which you also need.

Your 'think' procedure must follow certain rules in order to discover
Bug's perceptions and to return an action. Apart from these however,
anything goes and the actual method used by your procedure is entirely
your own choice. The only restriction is that it can't look at any
internal information about the current state of the world (e.g. the
exact location of the food) other than that passed to it by Bug's
perceptions.


think() and returning actions
-----------------------------

Your procedure must be called 'think', take no inputs, and return one
output. The output must be a Pop-11 word representing one of the eight
possible actions:
    forward     back
    right       left
    grab        drop
    use         wait

Note that this is a WORD and not a STRING. If you write it explicitly
(rather than, e.g., as part of a list), it must be enclosed in double
quotes: "forward".


Example
-------

This is a very silly Bug which always tries to move forward:
    define think();
        "forward"
    enddefine;


Bug's senses - vision
---------------------

As mentioned earlier, Bug sees a 5x7 rectangle around it. This is
returned in a two-dimensional array which you can access by calling the
defined procedure retina().

This call gives you the array, not an element of it. To get an element,
subscript it: the first subscript is an X value, going upward from 1;
the second is a Y value, also going from 1. Bug is in the position
(3,2). Thus the retinal image is mapped in the following way:

    ... ... ... ... 7,5
    ... ... ... ... ...
    ... ... ... ... ...
    ... ... ... ... ...
    ... ... ... ... ...
    2,1 ... .B. ... ...         <- Bug is in the middle of this row.
    1,1 1,2 1,3 1,4 1,5

Each element of the array is a single character, which is just the
symbol corresponding to the object in that cell. If there is no such
object, the character is a space. The contents of Bug's square is not
the character `B`, but whatever object is in the same square as Bug (` `
if none). Note that this does not show you what's in Bug's inventory.

It's worth mentioning for novices that there is a difference between
characters, strings, and words. Characters are written like this `B` and
are stored as integers being the ASCII code of that character. Words are
written like this "word"; strings are written like this 'string'.


Example
-------

    lvars image;
    ...
    retina() -> image;
    if image(2,3) = `+` then
        "grab" -> action
    endif;


Bug's senses - smell
--------------------

Bug's long-range sense of smell gives a partial indication of the food's
direction, as one of the words
    "left"    "right"   "forward"     "back"    "here"    "carried"
Unlike vision, smell works over any distance.

To access this, call the pre-defined procedure smell().


Example
-------

    define think();
        lvars dir;
        smell() -> dir;
        if dir = "forward" then "forward"
            ...
        endif;
    enddefine;


Bug's senses - the inventory
----------------------------

This is returned by the procedure inventory(), which returns a single
character representing the object being carried (` ` if none).


Example
-------

    define think();
        if inventory() = `+` then "use"
            ...
        endif;
    enddefine;


Bug's senses - energy
---------------------

This is returned by the procedure energy(), which returns an integer.


Example
-------

    define think();
        if energy() < 10 then
            ... better think of something quick ...
        endif;
    enddefine;


start_thinking() and initialising your brain
--------------------------------------------

Each time you call 'eden', the simulator calls the procedure
'start_thinking' before putting Bug into its world. You can use this if
you want to set up initial values for variables, to read data from file,
etc. You can't use it to generate actions, and although Pop will allow
you to call the sensory procedures from it, they will give complete
rubbish, since Bug is not yet embodied in a world.

In many cases, it will suffice to make this procedure a dummy that does
nothing. Do this just by writing no statements in it:
    define start_thinking();
    enddefine;

For an example where it does do something, see below.


bugdead()
---------

When your Bug dies, Eden calls the procedure 'bugdead' with one
argument. This will be true if the Bug died because it found food, and
false if it died through running out of energy, drowning, or for some
other reason. You can return a result telling Eden whether you want to
stop altogether and exit from the program, reincarnate in the current
world, or move to a new world.

To exit, return the word "stop".

To reincarnate in the current world, return the word "rerun". Eden will
reset the world to its initial state, restoring all objects to their
original positions, and restoring the Bug's energy to its initial value.
The Bug's brain is not touched, and can keep any information it built up
during the life just ended.

To reincarnate in a new world, return a two-element list, [% "rerun"
filename %]. filename must be a string or word naming a world, the same
form as supplied to 'eden'. Once again, the Bug's brain can retain any
information it built up.


Example 1
---------

    define bugdead( success );
        lvars success;
        "rerun"
    enddefine;

This will often be adequate. It just returns Bug to the current world.


Example 2
---------

    vars world_no;

    define start_thinking();
        1 -> world_no;
    enddefine;

    define bugdead( success );
        lvars success;
        if success then
            if world_no = 10 then
                "stop"
            else
                1 + world_no -> world_no;
                [% rerun 'WORLD'>;
    endsection;

Anything declared within these brackets will then be invisible to the
program outside, unless you explicitly ``export'' it: how to do so is
described in HELP SECTION. The point of this is that it enables you to
divide a large program into chunks, and ensure that the variables and
routines in one chunk don't conflict with those in another, even if they
have the same name. This helps, for example, when several people are
collaborating on the same program.

In Eden, the code of the Eden simulator itself is bracketed thus:
    section $-eden;
    endsection;
which puts it into a section called 'eden'. From your point of view,
this is useful because it means that, even if you write a routine with
the same name as one used by the simulator, there's no danger of them
interfering. However, when writing your own objects, you do need to call
the simulator routines. So you, as it were, have to slip your code into
the same space by bracketing it in the same way. This is what we have
done in defaultobjects.


Object names and symbols
------------------------

Another thing that needs explanation is the 'newproperty' statement
which is used to initialise the 'objects' table:

    newproperty([[` ` {%"nothing",nothing%}]
                 [`*` {%"boulder",boulder%}]
                 [`@` {%"rock",rock%}]
                 [`T` {%"hammer",hammer%}]
                 [`#` {%"door",door%}]
                 [`k` {%"key",key%}]
                 [`:` {%"narrows",narrows%}]
                 [`+` {%"food",food%}]
                 [`Q` {%"quicksand",quicksand%}]],
                  100,{%"unknown",unknown%},true)->
        objects;

Each object is represented by its character, and has a 2 element vector
associated with it. The fist element is the object's name, as a word.
This is only used when displaying things on the screen; it plays no part
in the Eden simulation proper.

The second element of each vector is crucial to the simulation, and is a
procedure that defines the object's interactions with Bug.

How does this work? Basically, to create a new object you have to define
the way in which it responds to 16 different ``context messages''. The
simulator sends these to an object when Bug has returned an action; the
result determines how the object is affected by that action.

Each action has associated with it two such messages. The first one is
sent to the object Bug has in its inventory at the time of carrying out
the action. The message has the form _held e.g. "grab_held",
"forward_held", "wait_held" etc. All messages are WORDS incidentally.

The second sort of message is sent to the object in the outside world
that might be affected by the action. Such messages have the form
_ext. e.g. if the action is "forward" then the message
"forward_ext" would be sent to the object in the next square in front of
the Bug. If the action is "drop" the message "drop_ext" is sent to the
object contained in the same cell as the bug.

Objects can respond to these messages in several ways. The object's
procedure must return a result that is one of "continue", "fail" or
"stop". In addition the object's procedure may contain additional code
to do things like reducing Bug's energy to zero if it has just set off a
trap, or moving Bug 3 squares ahead if it has just walked onto a
springboard.

Whenever an action is processed the simulator does as follows:

(1) It sends the appropriate _held message to the object in Bug's
    inventory.

(2) If the result is "stop", the simulator does no further processing.
    This result normally means that the object has done something
    special and has already carried out all the results of the action.

(3) It sends the appropriate _out message is then sent to the relevant
    object in the outside world.

(4) If both message calls returned "continue" then the default result
    of the action is carried out. e.g. for "forward" Bug is moved one
    square ahead, for "grab" the object in the current cell is
    moved into Bug's inventory.


Another example - TREEOBJECTS.P
-------------------------------

This is another library file, which defines some different objects.
These are used by SEARCH_BUG for demonstrating various types of search.


Useful routines for object writers
----------------------------------

The section below describes some routines which you can use when writing
your own objects. Some of them just examine the current state of the
world or bug; others change it. Those that do the latter will raise an
error if you try to do something like picking up a non-existent object,
or moving the bug outside the world.

Note that these routines do not update Bug's perceptions. This means
that if you were to call one of them, for example place_bug_at, and then
call retina() or smell(), the results would be the same as before. The
reason for this is that the perceptions can't be updated until the
objects have finished reacting, and that's what you're making them do.

Note also that these routines don't respect the properties of other
objects. For example, you can place_bug_at a square, even if it contains
a boulder. The reason is, again, that you are defining the properties of
your objects, and it's your job to make sure that they are respected.


World properties
----------------

world_width():
    The width (along the world's X-axis) of the current world. Since
    the world origin is (0,0), the largest X location is world_width-1.

world_height():
    The height (along the world's Y-axis) of the current world.


Changing world properties
-------------------------

place_object_at( xW, yW, char ):
    Place the object whose character is char at (xW,yW).


Bug's location and heading
--------------------------

bug_xW():
    Bug's X co-ordinate in the world co-ordinate system.

bug_yW():
    Bug's Y co-ordinate in the world co-ordinate system.

xV():
    The X-position of Bug within its visual array. The left-hand bottom
    corner of this array is (1,1). Note: this position is set when the
    bug is created, and does not change as it moves. In this version of
    Eden, it is fixed at 3.

yV():
    The Y-position of Bug within its visual array. In this version of
    Eden, it is fixed at 2.

forwardvector():
    Bug's forwardvector: a unit vector pointing in his current forward
    direction. This points along the Y-axis of his local co-ordinate
    system. See HELP VEC for details of how to handle vectors.

rightvector():
    Bug's rightvector: a unit vector pointing in his current right
    direction. This points along the X-axis of his local co-ordinate
    system, and is his forwardvector rotated right by 90 degrees.

direction():
    The direction Bug is heading in, as one of "east", "north", "west",
    "south". The obvious correspondance holds between forwardvector and
    direction: (0,1) -> north, (1,0) -> east.

one_forward( xW, yW ):
    Returns the co-ordinates of the square one place forward from
    (xW,yW), i.e. one place along Bug's forwardvector.

one_back( xW, yW ):
    Returns the co-ordinates of the square one place back from (xW,yW).

one_right( xW, yW ):
    Returns the co-ordinates of the square one place right from (xW,yW),
    i.e. one place along Bug's rightvector.

one_left( xW, yW ):
    Returns the co-ordinates of the square one place left from (xW,yW).

object_at_bug():
    The object in Bug's square, as a character. ` ` if none.


Bug's senses, actions, and other properties
-------------------------------------------

initial_energy():
    The energy Bug gets initially and on each reincarnation.

reply():
    The last reply Bug made, i.e. the argument of the last call of
    say(). Will be [] if Bug has said nothing since the start of the
    current cycle.


Changing Bug's properties
-------------------------

kill():
    Notes that Bug has been killed, by some means _other_ than finding
    food. You must call this whenever it is killed, since the simulator
    uses it to tell when to stop and call 'bugdead'.

fed():
    Notes that Bug has been killed, by finding food. You must call this
    whenever it finds food, since the simulator uses it to tell when to
    stop and call 'bugdead'.

place_bug_at( xW, yW ):
    Moves Bug to (xW,yW). Error if either of these is outside the
    world.

right():
    Move Bug one place right, i.e. along its rightvector.

left():
    Move Bug one place left.

drop():
    Make Bug drop the object it is holding. Error if it isn't
    holding anything.

grab():
    Make Bug grab the object in its square. Error if there's nothing
    there.

set_energy( e ):
    Set Bug's energy to e. Error if e is less than zero, or
    greater than the bug's initial energy.


CHAPTER 6  Additional facilities - the listener
-----------------------------------------------


Reading sentences
-----------------

As you will have noticed, the Eden prompt contains the option
'l(isten)'. This enables you to type a sentence for Bug to process. You
can use this in several ways. If you're experimenting with natural
language processing, the sentence might be a command to obey, or a
question to answer. For a Pop-11 demo that might give you some ideas on
this, you can play with a (very) cut-down version of the Shrdlu program.
Just type
    lib msblocks;
    go();
and follow the instructions.

You could also put in sentences that request Bug to print diagnostic
messages. In this case, the ``sentences'' could just be simple Pop
words, or perhaps, if you're using Prolog, Prolog goals.

To use the listen option, type l and hit return. The Ved cursor will then
move under the Bug status lines, and a question mark will be displayed.
In effect, Ved is now giving you one line on which to type and edit your
sentence: it won't let you move off that line, but you can move within
it, deleting characters and so on. When you have finished, hit RETURN or
ENTER. The sentence will then be transmitted to Bug, and you will get
another Continue prompt from Eden.

When running Eden, Ved displays the last heard sentence just below the
status line, where you typed it. If Bug replies, its reply is displayed
on the line below that. These are both set blank at the start of each
new cycle.

There are three routines to do with sentences: one for getting the last
sentence ``heard'', one for replying, and one to make analysis easier.


Hearing a sentence - sentence() and chars_to_items()
----------------------------------------------------

This returns the last ``heard'' sentence as a list of characters. You
call it in the same way as smell(), energy(), etc. Thus, if the sentence
typed had been
    where is the food?
then sentence() would return
    [119 104 101 114 101 32 105 115 32 116 104 101 32 102 111 111 100
     63]
Novices should remember that characters are represented as their ASCII
codes, as integers. See HELP ASCII for more information.

For many purposes, lists of characters are not very convenient! It would
be nicer to have them packaged up into numbers and bits of text. You can
do this with the procedure chars_to_items, which takes one argument, a
list of characters, and returns a list of ``items''. Essentially,
``item'' is Pop terminology for a number, word (in the Pop-11 sense), or
other basic unit of program text.
Thus:
    Characters: 'I saw 2 dogs'
    Items:      "I" "saw" 2 "dogs"

Items are useful here, because (in most cases), Pop-11 items correspond
to words in English. Hence char_to_items is a quick way to convert a
continuous stream of characters into a list whose elements you can treat
as English words. In general, numbers will be converted to Pop-11
integers or reals; sequences of letters, to Pop-11 words. For the full
rules, see REF ITEMISE.

Note to experts: sentence() returns characters because you might want to
do your own tokenisation, rather than using the Pop-11 itemisation
rules.


Replying to a sentence - say()
------------------------------

The procedure say() is the opposite to sentence(). It takes a sentence,
and displays it back to you. The reply will appear on the line just
below the sentence you typed.

The argument to say() should be a list whose elements are words,
strings, or numbers. Unlike sentence(), say() does not expect
a list of characters.


Example
-------

Here is a bug which responds to the queries
    where is the food?
    what are you holding?

    define think();
        lvars sent;

        chars_to_items( sentence() ) -> sent;

        if sent matches [ where is the food ? ] then
            say( [ the food is ^smell() ] )
        elseif sent matches [ what are you holding ? ] then
            if inventory() = ` ` then
                say ( [ i am holding nothing ] )
            else
                say( [ i am holding % consword(inventory(),1) % ] )
            endif
        endif;

        if inventory() = `+` then
            "use" -> action
        elseif smell() = "here" then
            "grab" -> action
        else
            smell() -> action;
        endif;

    enddefine;


In the present version of Eden, your Bug can only hear one sentence per
cycle; the latest one typed will replace earlier ones. It can however,
say as many sentences as it likes, at any time. Later versions of Eden
will allow Bug to react more immediately.


CHAPTER 7  Additional facilities - eden(), saving cases, no-Ved mode
--------------------------------------------------------------------

The routine eden(), used for starting Eden, offers more facilities than
those mentioned in Chapter 3. These allow you to
(1) Save perceptions and actions for later use;
(2) Run without using Ved;
(3) Avoid repeating previous filenames;
(4) Run in batch mode.


Full specification of eden()
---------------------------

So far, you have seen eden() used with two arguments, specifying the
files from which the bug and world are to be loaded. You can omit these
if the same files are to be used as last time. You can also give it
extra arguments which cause it to save information, or to run without
Ved.

The full specification is:
    eden( , ,  )
    eden(  )
where  stands for any number (including none) of the following
arguments, in any order:
    "noved"
    "batch"
    [% "save", file, proc, proc, ... %]

 and  must be strings, denoting files. The
bug-file must be a file of Pop-11 code, and its extension defaults to
.P. The world-file must be as saved by the Ved command 'saveworld'. Its
extension defaults to .W.

If a file is specified without a directory, Eden looks first in your
current directory. If it can't find the file there, it then searches the
library files, as defined by 'popuseslist'. See HELP POPUSESLIST for
more details. On most systems, Eden and the standard worlds and bugs
will have been set up as libraries.

The "noved" and "batch" options are Pop-11 words. The save option is a
list whose first element should be the word "save", whose second element
should be a filename, and whose remaining elements should be procedures.


Examples
--------

    eden( "noved" );
    eden( 'MYBUG', 'tw1', [ save mycases ^energy ^retina ] );
    eden( 'manual_bug', 'MyWorld',
          [% "save", 'CASES', retina, smell, energy %], "batch" );


How to avoid repeating filenames
--------------------------------

If the world and bug you want to run are exactly the same as last time,
you can omit them. You can still specify the other options to eden().


Examples
--------

    eden();
    eden( "batch" );
    eden( [% "save", 'CASES', retina, smell, energy %], "noved" );


Saving cases
------------

By using the save option, you can direct that perceptions and actions
are to be stored in a file. You can then read this back later, and use
it (for example) for training a neural net. To make this more concrete,
you might want to train a net to do maze-following, but without having a
good idea of the algorithm to be used. You could construct a number of
worlds which contain mazes, and run the manual bug through them, leading
it around the mazes by hand. By saving its perceptions and actions, you
then have a mass of data on which you can try training a net to do the
same task.

The best way of introducing this option is by examples:
    [ save cases ^energy ^retina ^smell ]
    [ save fred ]
    [ save cases ^myproc ^energy ]

In each of these, the second element is a filename. It can be either a
word or a string. The remaining elements are procedure names. Each
procedure should return at least one result. The procedures can be
Eden's perceptual procedures, 'smell', 'energy', etc., or can be your
own.

When running your bug in save mode, Eden starts each cycle by invoking
your 'think' procedure, and noting the action returned. It then calls
each procedure in your save-list, and makes a list of the results. It
puts the action at the end of this list, and saves the whole list in a
your file. So if your save option was this
    [ save cases ^energy ^retina ^smell ]
then the first list saved might be
    [% 500, R, "forward", "forward" %]
where 500 is the energy, R stands for the retina (it will be saved as an
array, of course), and the last two elements are the smell and the bug's
action. These lists would all be saved in the file CASES. Everything
else works as without the save option; the only difference you may
notice is that the simulation will be slightly slower.

If your save option was
    [ save fred ]
then each list saved would contain only an action, and would be saved in
FRED.

If your save option was
    [ save cases ^myproc ^energy ]
then the format of the saved lists would depend on 'myproc'. Suppose it
returns two results, being the bug's X and Y distances from the food.
Then the first list saved might be
    [% 4, 5, 500, "forward" %]
and the second might be
    [% 4, 4, 499, "forward" %]
These would all be saved in a file called CASES.


How to read the saved cases
---------------------------

Eden comes with a library called STOW, described in HELP STOW. Briefly,
suppose you have a case file called CASES. You can ``open'' this by
doing
    unstow_from( 'CASES' ) -> r;
This makes 'r' into a ``repeater'' --- that is a procedure that, on each
call, returns the next item in sequence.

So if your save option had been
    [ save cases ^energy ^retina ^smell ]
then each call of r would give you a list whose first element was the
energy, whose second was the retina, and whose third was the smell. As
mentioned above, the first of these might be
    [% 500, R, "forward", "forward" %]


Running without Ved
-------------------

It is sometimes useful to run outside Ved, for the following reasons:
(1) By using the library commands 'record' and 'endrecord' (see HELP
RECORD), you can log output to a file. However, they don't log Ved
output, so if you want that, you need to run outside Ved.
(2) When testing bugs, you may want to trace procedures, to write
diagnostics, etc. This can be tricky in Ved.

To run outside Ved, give the "noved" option to eden(). Eden will run,
displaying the world and status information for each cycle in teletype
mode, as a sequence of lines. The prompts are the same, but you won't be
able to edit sentences passed to the listener.


Examples
--------

    eden( "noved" );
    eden( 'talk_bug', 'tw3', "noved" );


Batch mode
----------

In normal use, whether Ved or non-Ved mode, Eden prompts you for the
number of cycles to run next. This would make it tedious to run a bug
which needs to run through several hundred or even thousand worlds. By
giving the "batch" option, you can specify that Eden is to run lives
until bugdead finally returns "stop", without any prompting or display
of the world. In batch mode, Eden prints three lines to the standard
output for each life, like this:
    Starting life 1.
    Life 1 succeeded on energy 494.
    Result from bugdead: rerun.


CHAPTER 8  Special output and the view window
---------------------------------------------

Eden provides several routines for displaying output as the bug runs.
The first of these is bug_message, which (in Ved mode) puts a message on
the Ved status line. The second is bug_view. This sends its output to an
auxiliary window, which is opened as needed. There is also a routine for
discovering whether Bug has been called from within Ved.


bug_message
-----------

This is a procedure of one argument, which can be anything at all.
bug_message(x) converts x to a string, and calls vedputmessage if in Ved
mode. In non-Ved mode, it prints the string and then takes a newline.


bug_using_ved
-------------

This is a procedure of no arguments. bug_using_ved() returns true if the
bug is running in Ved mode, false otherwise. You can use this to
allow your bug output procedures to adapt their output to the current
mode.


The view window
---------------

If you are writing lots of information, then you have problems in Ved
mode. The status line isn't big enough, and there is nowhere else in the
window to display it. The bug_view routine allows you to write output
that will get sent to a separate Ved window.

bug_view is a syntax word which must be followed by an expression. This
expression should be a call to an output routine. In Ved mode, before
calling the routine, bug_view opens a new Ved window for a buffer called
VIEW, and gives it the bottom half of the screen, leaving the bug in the
top half. bug_view then arranges for the output of this routine to be
sent to the next location in the window. Once bug_view has finished, the
window remains open until the end of the run. Subsequent calls to
bug_view will write their output at the end of the same window.

In non-Ved mode, bug_view proc() is equivalent to proc().


Examples
--------

    bug_view pr('Demonstrating my new bug\n');
    bug_view printf('Smell was: %p\n', [% smell() %] );


Turning view on and off
-----------------------

The routines bug_view_on() and bug_view_off() turn view on and off. By
default, 'eden' turns it on. If it's turned off, calls to bug_view will
have no effect. This is useful if you want to leave bug_view statements
in, but disable them on some runs.


CHAPTER 9  Useful routines
--------------------------

I have written some routines you may find useful. These are fully
described in their HELP files:

HELP AWM:
These are routines with which Bug can build a map of its surroundings,
can search for paths, find regions, and so on.

HELP AWM_PATH:
These are routines for finding a path within an AWM.

HELP AWM_TO_REGIONS:
These are routines for marking regions within an AWM.

HELP CHARS_TO_ITEMS:
This exports a routine for converting character lists into item lists,
useful when processing sentences. It was described in Chapter 6.

HELP EXEC:
This library allows you to use coroutines or processes when controlling
bugs. The idea is that you can write your ``brain'' as a continuous loop
which sends back actions from time to time, rather than as a procedure
which must be called afresh on each turn. Some brains are much easier to
write in this style.

HELP NEEDS:
This exports the 'needs' macro, which Eden uses for loading various
library files. Novices probably won't need it; more experienced
programmers may find it useful if you want to avoid loading the same
library more than once, or if you want to ensure that libraries are
always compiled in the top-level section.

HELP PATH_TO_MOVES:
This library defines a routine for converting a path, expressed as
a list of points, into a series of moves.

HELP RETINA:
This library contains routines for manipulating Bug retinas. Novices
probably won't need them, since it's sufficient to treat it as a simple
array. However, they're useful when writing your own variants of Eden,
or when testing complicated vision routines.

HELP SEARCH:
These are the routines for searching. You can use them to discover
whether there's a path between two points, to find the path, and so on.

HELP SENSES_TO_FEATURE_VECTOR:
This defines routines for converting Bug's senses into a ``feature
vector''. These are particularly useful if you want to train a
neural-network bug, and need to interface its retina with the net.

HELP STOW:
These are the routines for reading saved cases, described in Chapter 7.
You can also use the routine 'stow_to' in this library to save your own
data in a file.

HELP VEC:
These are routines for manipulating 2-D vectors. They are useful when
calculating how Bug has to turn, and so on. They are also useful when
writing new objects, see Chapter 5.

SHOWLIB WORLDS:
WORLDS.P is the module which implements the basic world-handling
routines used by Eden. Most of it will only be of interest if you want
to modify Eden. However, the routines for converting world text files to
save files are useful if you need to save a large number of worlds
automatically.

There are several other files used by Eden itself, but of no interest to
the bug writer. These can all be examined by doing SHOWLIB, and are all
commented with their purpose and the specification of the exported
routines. To find out where they are, do SHOWLIB EDEN and work back via
the call to 'needs'.


CHAPTER 10  Eden from Prolog
----------------------------

Rather than describe Eden from scratch in a Prolog context, I'll assume
you have read the description of how it works under Pop-11. The Prolog
interface is similar, with appropriate changes in datatypes and
arguments.


Running Eden
------------

You do this with the 'eden' predicate. There are five forms, eden/0
through eden/4. The full specification is:
    eden( , ,  )
    eden(  )
where  stands for any number upto the limit of
four arguments, in any order:
    noved
    [ save,  ]

 and  must be atoms, denoting files. The bug-file
must be a file of Prolog code. If no extension is given, it defaults to
.PL. The world-file must be as saved by the Ved command 'saveworld'. If
no extension is given, it defaults to .W.

If a file is specified without a directory, Eden looks first in your
current directory. If it can't find the file there, it then searches the
library files, as defined by 'prologliblist'. See HELP LIBRARY for more
details. On most systems, Eden and the standard worlds and bugs will
have been set up as libraries.

The 'noved' option is an atom; the 'save' option is a list whose head is
an atom and whose second element is a filename, as an atom.


Examples
--------

    eden( noved ).
    eden( '/MyBug', tw1, [save,'SAVE'] ).
    eden( manual_bug, 'MyWorld', [save,cases] noved ).


How to avoid repeating filenames
--------------------------------

If the world and bug you want to run are exactly the same as last time,
you can omit them. You can still specify the other options to 'eden'.


Examples
--------

    eden.
    eden( noved ).
    eden( [save,cases], noved ).


Saving cases
------------

By using the save option, you can direct that perceptions and actions
are to be stored in a file. You can then read this back later, and use
it (for example) for training a neural net.

The Pop-11 save option is described in Chapter 7. In the current version
of Prolog Eden, you only have one option, [ save,  ], which saves
the perceptions to  in the order
    retina sentence smell inventory energy

You will need to enter Pop-11 to read them back, and you should use LIB
STOW to do this. For further details, see Chapter 7. For calling Pop-11
from Prolog, see HELP PLOGTOPOP.


Running without Ved
-------------------

It is sometimes useful to run outside Ved, for the following reasons:

(1) By using the library predicates 'log' and 'nolog' (see HELP LOG),
you can log output to a file. However, they don't log Ved output, so if
you want that, you need to run outside Ved.

(2) When testing bugs, you
may want to spy on predicates, to write diagnostics, etc. This can be
tricky in Ved.

To run outside Ved, give the 'noved' option to 'eden'. Eden will run,
displaying the world and status information for each cycle in teletype
mode, as a sequence of lines. The prompts are the same, but you won't be
able to edit sentences passed to the listener.


Examples
--------

    eden( noved ).
    eden( talk_bug, tw3, noved ).


Batch mode
----------

In normal use, whether Ved or non-Ved mode, Eden prompts you for the
number of cycles to run next. This would make it tedious to run a bug
which needs to run through several hundred or even thousand worlds. By
giving the batch option, you can specify that Eden is to run lives until
bugdead finally returns 'stop', without any prompting or display of the
world. In batch mode, Eden prints three lines to the standard output for
each life, like this:
    Starting life 1.
    Life 1 succeeded on energy 494.
    Result from bugdead: rerun.


Bug's senses - vision
---------------------

These are accessed via the predicate retina/3. Its first two arguments
should be the X and Y co-ordinates. The third will be instantiated to an
atom which is the character seen at that location.


Example
-------

    retina( 3, 2, X )
sets X to '+' if Bug is standing on the food.


Bug's senses - the sentence
---------------------------

This is accessed via the predicate sentence/1. It unifies its argument
with a list of characters. You can convert these to items (atoms and
numbers) by using the library predicate chars_to_items.


Example
-------

    sentence( Chars ), chars_to_items( Chars, S )
might unify S with [where,is,the,food,?].


Bug's senses - smell
--------------------

Access this via the predicate smell/1. It unifies its argument
with one of the atoms 'forward', 'back', 'left', 'right', 'here',
'carried'.


Bug's senses - the inventory
----------------------------

Access this via the predicate inventory/1. It unifies its argument
with an atom for the object being carried: ' ' if none.


Bug's senses - energy
---------------------

Access this via the predicate energy/1. It unifies its argument
with an integer giving the energy.


Saying a sentence
-----------------

You do this with the predicate say/1. It takes one argument, which is
a list.


start_thinking() and initialising your brain
--------------------------------------------

Each time you call 'eden', the simulator calls the predicate
start_thinking/0 before putting Bug into its world. You can use this if
you want to set up initial values for assertions, to read data from
file, etc. You can't use it to generate actions, and although Pop will
allow you to call the sensory predicates from it, they will give
complete rubbish, since Bug is not yet embodied in a world.

In many cases, it will suffice to make this predicate a dummy that does
nothing. Do this just by writing:
    start_thinking.

For an example where it does do something, see below.


bugdead
-------

When your Bug dies, Eden calls the predicate bugdead/2. The first
argument will be 'succeeded' if the Bug died because it found food, and
'failed' if it died through running out of energy, drowning, or for some
other reason. You can return a result via the second argument telling
Eden whether you want to stop altogether and exit from the program,
reincarnate in the current world, or move to a new world.

To exit, return the atom 'stop'.

To reincarnate in the current world, return the atom 'rerun'. Eden will
reset the world to its initial state, restoring all objects to their
original positions, and restoring the Bug's energy to its initial value.
The Bug's brain is not touched, and can keep any information it built up
during the life just ended.

To reincarnate in a new world, return a two-element list,
    [ rerun,  ].
file must be an atom or Pop-11 string naming a world, the same
form as supplied to 'eden'. Once again, the Bug's brain can retain any
information it built up.


Example 1
---------

    bugdead( _, rerun ).

This will often be adequate. It just returns Bug to the current world.


Example 2
---------

    start_thinking :-
        assert( current_world(1) ).

    think( left ).

    bugdead( success, stop ) :-
        current_world(50),
        !.

    bugdead( _, [ rerun, Name ] ) :-
        retract( current_world( W ) ),
        WNext is W + 1,
        assert( current_world( WNext ) ),
        Name is ><( tw, WNext ).

I assume that this Bug is running through the fifty training worlds, TW1
to TW50. If it succeeds in finding food, it goes on to the next world if
there is one, otherwise it exits. If it doesn't succeed, it tries the
same world again. This code can be found in REINCARNATING_BUG.PL.

Note the final line of 'bugdead'. This calls the Pop-11 string
catenation operator >< to construct a filename from the prefix 'tw' and
the world number. It is possible to call any Pop-11 function from 'is':
see HELP IS. Contrary to what is said there, the function need not
return a number: here, it returns a Pop-11 string.


bug_message
-----------

bug_message is used to write to the Ved status line. It is a unary
operator of precedence 250, which takes a goal as argument. In Ved mode,
it calls its argument, which should produce some output. Rather than
displaying this immediately, it collects the output in a string, and
then displays that string on the status line.

In non-Ved mode, it just calls its argument.


Example
--------

    bug_message output( Meaning )
This calls the goal output(Meaning), and displays the output it would
send on the status line (in Ved mode).


bug_using_ved
-------------

This is a predicate of no arguments; it succeeds in Ved mode and fails
otherwise. You can use it allow your bug output predicates to adapt
their output to the current mode.


The view window
---------------

If you are writing lots of information, then you have problems in Ved
mode. The status line isn't big enough, and there is nowhere else in the
window to display it. The bug_view predicate allows you to write output
that will get sent to a separate Ved window.

bug_view is a prefix operator of precedence 250, whose argument should
be a goal which generates some output, as for bug_message. In Ved mode,
before obeying the goal, bug_view opens a new Ved window for a buffer
called VIEW, and gives it the bottom half of the screen, leaving the bug
in the top half. bug_view then arranges for the output from the goal to
be sent to the next location in the window. Once bug_view has finished,
the window remains open until the end of the run. Subsequent calls to
bug_view will write their output at the end of the same window.

In non-Ved mode, bug_view Goal is equivalent to Goal.


Examples
--------

    bug_view write('Demonstrating my new bug\n')
    bug_view ( smell(S), write_list(['Smell was: ',S]), nl )
In the second example, the argument to bug_view is a compound goal which
fetches S, writes it, and takes a newline. The example assumes a
predicate write_list for writing lists.


Turning view output on and off
------------------------------

The predicates bug_view_on and bug_view_off turn view on and off. By
default, 'eden' turns it on. If it's turned off, calls to bug_view will
have no effect. This is useful if you want to leave bug_view calls
in, but disable them on some runs.


Useful libraries
----------------

You can call any of the libraries mentioned in Chapter 9 from Prolog.
See HELP PLOGTOPOP for how to call Pop-11 from Prolog. I have also
written a few which can be called directly as Prolog predicates. See
the following Prolog HELP files:
    HELP EXEC
    HELP VEC
These are equivalents of the Pop-11 libraries with the same name.


Bugs
----

The following bugs are available:
    exec_bug:           Demonstrates how to use the Prolog 'exec'
                        library.
    manual_bug:         Prolog encapsulation of the Pop-11 manual
                        bug.
    planning_bug:       An experimental bug which can parse simple
                        commands and make plans to carry them out.
                        At the moment, this is the only piece of
                        true AI here. There is a draft AI tutorial
                        based on this in POPBEAST.TEX, in Latex
                        format.
    reincarnating_bug:  Shows how to pass from one world to another.
    search_bug:         Demonstrates various types of search, using
                        the 'exec' library.
    talk_bug:           Responds to simple sentences.
    very_simple_bug:    Finds food in an uncluttered world.

You can use 'showlib' to look at the code of any of these. Except for
manual_bug, they are all written in Prolog.

search_bug needs to be run in treeworld; planning_bug must be run in
planning_world. The others in one of the tw training worlds, or in
defaultworld.


CHAPTER 11 - Future extensions to Eden
--------------------------------------

There are many possibilities. They include the following:


1) Multiple bugs. WORLDS.P is written so that several bugs can co-exist
in the same world. With VT100 graphics, we can't display the status of
them all, and also we can't display squares with more than one bug.
However, there are no difficulties in principle, and I hope to implement
this later. There will be a choice between sequential and parallel
turn-taking. In sequential turn-taking, bug 1 will take an action and
have the world updated; bug 2 will take an action and have the world
updated; and so on. In parallel turn-taking, all the bugs will see the
same perceptions and generate an action; Eden will then choose one
action randomly, update the world, do the same with the next, and so on.
This avoids complex conflict resolution, which as Brooks has pointed out
is unnecessary.

There needs to be some way for a bug to see a square containing another
bug and an object: the retina will return a list of objects.


2) More reactivity. Have a bug able to respond as soon as another one
"says" something to it. This would allow one to experiment with
co-operative planning and dialogue, and also with Artificial Life
experiments such as neural nets that learn to communicate.


3) Multiple objects. Again, the limit of one object per square is
imposed by the graphics. The simulator should have little difficulty in
coping with more.


4) X-windows interface. This speaks for itself. I'll do it if I can
get the resources: anyone know how I might get external funding for
developing Eden into a proper teaching kit?


5) Randomness in perception and action. We could have actions
occasionally fail, or perceptions occasionally return the wrong result.
This would force planners to be more intelligent. Alternatively, we
could "explain" these randomnesses (of actions anyway) by having
randomly moving objects, e.g. tiles blown about by the wind.


6) Very large worlds. Given suitable graphics, one could have worlds of
several thousand squares in each direction, and correspondingly large
visual arrays, with some of the data therein being inexact. This would
make it possible to incorporate convolution and other vision methods.


7) Different kinds of world. I would like to design something that's
more continuous, both in space and time, getting away from the grid
structure. Ideas?


CHAPTER 12 - Conditions of use
------------------------------

Eden is supplied as public-domain software: you can, and should, pass it
on to others.

In using Eden, you accept that the same condition applies to any
software you write for it, any modifications or translations you make,
and any documentation for these. This includes new bug ``brains'' and
all the software they call, new worlds, modifications of Eden such as
those suggested above, course notes which refer to these, and
translations of Eden into C or other languages. These should be sent to
me if I request, so that I can include them with future versions.

The point of imposing this condition is to enable me to create a
public-domain library of microworlds and bugs, hopefully demonstrating
many different AI techniques. This will have failed its purpose, which
is to demonstrate a wide variety of AI techniques in a light-hearted
fashion, unless anyone with access to the library can download and run
(compiler permitting) anyone else's bug in the appropriate world.


Jocelyn Ireson-Paine November 30th 1992