/* EDEN_CORE.PL */ /* :- module eden. :- public eden/0, eden/1, eden/2, eden/3, eden/4, resume_eden/0, exit_eden/0, retina/3, inventory/1, heard_from/2, say/2, exec/1, (bug_message)/1, bug_using_ved/0, (bug_view)/1, bug_view_on/0, bug_view_off/0. */ /* SPECIFICATION ------------- This is the main module defining Eden for Prolog. It has to be loaded by EDEN.PL. For details of Eden itself, see HELP EDEN. The specifications given below assume you have read that. Running Eden: ============= PUBLIC eden( ): 'eden' starts Eden running, putting a bug into a world and setting it off. The arguments are eden( , , ) eden( ) up to a limit of four arguments. stands for any number (including none), upto the argument limit, of the following arguments, in any order: noved batch [ save, ] and must be atoms, denoting files. The bug-file must be a file of Prolog code, and its extension defaults to .PL. The world-file contains a saved world, as saved by the Ved 'saveworld' command, and its extension defaults to .W. If a file is specified without a directory, Eden looks first in the 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. This assumes Eden and the standard worlds and bugs will have been set up as libraries, which I hope will be true on most systems. The noved and batch options are atoms. The save option is a list whose first element should be the atom 'save' and whose second element should be a filename. Example calls of eden are: eden( noved ). eden( 'MYBUG', tw1, [ save, mycases ] ). eden( manual_bug, 'MyWorld', [ save, 'CASES' ], 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', for instance: eden. eden( noved ); eden( [ save, 'CASES' ], batch ). 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. In the present version of of Prolog Eden, you only have one option, [ save, ] where is a filename, as an atom. This saves the perceptions to in the order retina sentence inventory You will need to enter Pop-11 to read them back, and you should use LIB STOW to do this. For further details, see HELP EDEN. Running without 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 are: eden( noved ). eden( talk_bug, tw3, noved ). Batch mode ---------- In normal use, whether Ved or non-Ved mode, Eden interacts with the user, prompting 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. EndedLife 1 494. Result from bugdead: rerun. Resuming Eden: ============== PUBLIC resume_eden: This resumes Eden from where it was last exited, using the current world and bug. Exiting Eden: ============= PUBLIC exit_eden/0: Exits cleanly from Eden. You should not use this during the competition. The senses: =========== PUBLIC retina( X?, Y?, Obj? ): If X and Y are instantiated, unifies Obj with the atom representing the object at location (X,Y) in Bug's retina. If there is no object, the atom returned is ' '. If X or Y or both are uninstantiated, scans the entire retina, returning each value of X and Y for which Obj unifies. If Obj is a variable, this will successively return all the objects seen. PUBLIC sentence( S? ): Unifies S with the last sentence ``heard'' by Bug. [] if none, otherwise a list of characters. PUBLIC inventory( I? ): Unifies I with the contents of Bug's inventory. This is an atom representing an object: ' ' if none. Special output: =============== PUBLIC bug_using_ved: Succeeds if Ved is being used, i.e. if 'eden' was called without the 'noved' option. Fails otherwise. PUBLIC bug_message Goal+: 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, and then writes a newline. An example is: bug_message output( Meaning ) This calls the goal output(Meaning), and displays the output it would send on the status line (in Ved mode). In non-Ved mode, it just calls output(Meaning). The view window: ================ The bug_view predicate allows you to write output that will get sent to a separate Ved window. There are also predicates for turning view output on and off. PUBLIC bug_view Goal+: bug_view is a prefix operator of precedence 250, whose argument should be a goal which generates some output. 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 are: bug_view write('Demonstrating my new bug\n') bug_view ( smell(S), write(S), nl ) PUBLIC bug_view_on: PUBLIC bug_view_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 statements in, but disable them on some runs. */ /* IMPLEMENTATION -------------- See notes in EDEN_CORE.P, and also below. Note that the encapsulation of retina/3 assumes that the retina is 5 by 7. */ :- library(chars_to_items). /* Load this so the user can access it without needing to load it. */ /* The top-level predicate: eden ---------------------------- These predicates just pass their arguments to the Pop-11 'eden', together with the special option "prolog". This enables Eden to adapt itself to the needs of Prolog, e.g. in calling predicates to interface the brain. */ eden :- prolog_eval( eden(prolog) ). eden( Arg ) :- prolog_eval( eden( quote(Arg), prolog ) ). eden( Arg1, Arg2 ) :- prolog_eval( eden( quote(Arg1), Arg2, prolog ) ). eden( Arg1, Arg2, Arg3 ) :- prolog_eval( eden( quote(Arg1), Arg2, Arg3, prolog ) ). eden( Arg1, Arg2, Arg3, Arg4 ) :- prolog_eval( eden( quote(Arg1), Arg2, Arg3, Arg4, prolog ) ). resume_eden :- prolog_eval( apply(valof(resume_eden)) ). exit_eden :- prolog_eval( apply(valof(exit_eden)) ). /* Interface to perceptions ------------------------ We can call some of the Pop-11 perceptual routines directly. Others have to be encapsulated, via interface routines defined below. */ retina( X, Y, NO ) :- ( var(X) ; var(Y) ), nonvar(NO), NO = nearest(Obj), retina_nearest( X, Y ), prolog_eval( consword( apply(X,Y,apply(valof(retina))),1), Obj ), !. retina( X, Y, Obj ) :- nonvar(X), nonvar(Y), !, prolog_eval( consword( apply(X,Y,apply(valof(retina))),1), Obj ). retina( X, Y, Obj ) :- retina_xbounds( X, XLow, XHigh ), retina_ybounds( Y, YLow, YHigh ), retina_sweep( X, XLow, XHigh, Y, YLow, YHigh, Obj ). retina_xbounds( X, X, X ) :- nonvar(X), !. retina_xbounds( _, 1, 5 ). retina_ybounds( Y, Y, Y ) :- nonvar(Y), !. retina_ybounds( _, 1, 7 ). retina_sweep( X, XLow, XHigh, Y, YLow, YHigh, Obj ) :- retina_between( X, XLow, XHigh ), retina_between( Y, YLow, YHigh ), prolog_eval( consword( apply(X,Y,apply(valof(retina))),1), Obj ). retina_between( _, Low, High ) :- Low > High, !, fail. retina_between( Low, Low, _ ). retina_between( X, Low, High ) :- Next is Low + 1, retina_between( X, Next, High ). retina_nearest(3,2). retina_nearest(3,3). retina_nearest(4,2). retina_nearest(3,4). retina_nearest(2,2). retina_nearest(5,2). retina_nearest(3,5). retina_nearest(3,1). retina_nearest(2,3). retina_nearest(1,2). retina_nearest(4,3). retina_nearest(4,1). retina_nearest(3,6). retina_nearest(2,4). retina_nearest(5,3). retina_nearest(5,1). retina_nearest(4,4). retina_nearest(3,7). retina_nearest(2,5). retina_nearest(2,1). retina_nearest(4,5). retina_nearest(2,6). retina_nearest(1,3). retina_nearest(1,1). retina_nearest(4,6). retina_nearest(2,7). retina_nearest(1,4). retina_nearest(5,4). retina_nearest(4,7). retina_nearest(1,5). retina_nearest(5,5). retina_nearest(1,6). retina_nearest(5,6). retina_nearest(1,7). retina_nearest(5,7). inventory( I ) :- prolog_eval( consword(apply(valof(inventory)),1), I ). heard_from( Id, S ) :- prolog_eval( heard_from(Id), S ). say( Id, S ) :- prolog_eval( say(Id,prolog_full_deref(quote(S))) ). exec( A ) :- prolog_eval( exec(A) ). /* bug_message and bug_using_ved ----------------------------- bug_message Goal passes Goal to the interface routine to_message, defined below. This switches cucharout so that all characters output are dumped into a string, which is then passed to the Pop-11 bug_messsage. We use prolog_invoke to call Goal: see next section. */ :- op( 250, fx, bug_message ). bug_message( Goal ) :- prolog_eval( apply( quote(Goal), valof(word_identifier(to_message_PL, section_subsect(eden,valof(pop_section),false), true ) ) ) ). :- prolog_language(pop11). section $-eden; define to_message_PL( goal ); lvars goal; vars cucharout; procedure (c); lvars c; c endprocedure -> cucharout; cons_with consstring {% prolog_invoke(goal).erase %}.bug_message enddefine; endsection; :- prolog_language(prolog). bug_using_ved :- prolog_evaltrue( apply(valof(bug_using_ved)) ). /* Viewing thoughts ---------------- bug_view Goal passes the constructed routine prolog_invoke(Goal)<>erase to the Pop-11 routine to_view, which underlies the Pop-11 bug_view. The constructed routine invokes Prolog on Goal, and then erases the result which will indicate success or failure. See HELP POPTOPLOG. */ :- op( 250, fx, bug_view ). bug_view( Goal ) :- prolog_eval( apply( quote(Goal), valof(word_identifier(view_PL, section_subsect(eden,valof(pop_section),false), true ) ) ) ). bug_view_on :- prolog_eval( apply(valof(bug_view_on)) ). bug_view_off :- prolog_eval( apply(valof(bug_view_off)) ). :- prolog_language(pop11). section $-eden; define view_PL( Goal ); $-eden$-to_view( prolog_invoke(%Goal%)<>erase ) enddefine; endsection; :- prolog_language(prolog). /* :- endmodule. */