In my poprulebase library[*] I have included actions to allow control to
be transferred from one "ruleset" to another, including allowing
rulesets to be stacked, etc. (loosely corresponding to SOAR's changing
problem spaces, though more general as it is not dedicated to a
particular sort of philosophy or cognitive architecture).
The rules include conditions that are interpreted using the Pop-11
pattern matcher. Since V15 the matcher allows identifiers to be included
as pattern variables, but I have not yet adapted poprulebase to use
lvars in patterns. Instead I allow a ruleset to be associated with a
pop-11 section (loosely analogous to a package in common lisp).
This required the poprulebase interpreter to able to save and restore
sections if this facility is used. That's easy using
dlocal current_section;
to ensure that current_section is saved on entry and always restored on
exit.
However, switching sections (by assigning to current_section) is a
complicated and slow process (it changes the mapping between dictionary
entries and identifiers), so I thought I would have a global variable
prb_use_sections to specify whether sections are being used.
However this does not work:
if prb_use_sections then
dlocal current_section;
endif;
That's because if a dlocal expression occurs anywhere in a procedure,
whether inside a conditional branch or not, the relevant code has to be
included in the procedure record. (It's like "vars" and "lvars" in that
respect). I.e. the conditional test has no effect.
I suppose the compiler might be made clever, to detect whether dlocal is
within a conditional and if so insert an appropriate test in the
compiled code, but that would be very difficult, since the code for
dlocal expressions is run on procedure entry and exit, whereas the user
might expect the test to be done where the instruction occurs.
Anyhow to get round this I did the following:
lvars oldsect = current_section;
dlocal 0 %, (if prb_use_sections then oldsect -> current_section endif)%;
In a dlocal expression of the form % <action1>, <action2> %
<action1> is executed on procedure entry and <action2> on procedure
exit (whether normal or abnormal exit - see HELP DLOCAL).
This seems to fix the problem as the test is included in the exit
action.
WARNING: if you wish to use any lvars in the scope of a dlocal
expression then you must EXPLICITLY declare them as lvars, even if one
of them is one of the procedure input variables. Do not assume that the
implicit declaration of input variables as lvars since Poplog version 15
will do this. It looks as if dlocal expressions are compiled before the
input and output locals are handled.
Thus the following does not work.
define test(restore, y);
lvars old = tttt;
dlocal 0 %, if restore then old -> tttt endif%;
[old tttt ^tttt]=>
y -> tttt;
[new tttt ^tttt] =>
chain(procedure; [global tttt ^tttt] => end)
enddefine;
It produces the following warning during compilation:
;;; DECLARING VARIABLE restore
caused by the compilation of the dlocal expression.
I am not sure whether this is a fixable bug. It does not seem to be
consistent with the published changes for V15.
Aaron
[*]
Poprulebase is available from the Birmingham Poplog ftp directory
ftp://ftp.cs.bham.ac.uk/pub/dist/poplog/
though it is in the process of being extended radically to improve
integration with the sim-agent toolkit, including the addition of a
concept of a "rulesystem". A rulesystem is a set of rulesets, plus the
notion of the current ruleset, and possibly a stack of rulesets waiting
to be popped, a section to be used, and other control information. Each
agent may contain a number of interacting rulesystems, e.g. one for
vision, one for hearing, one for motive generation, one for planning,
one for creating messages to other agents, one for managing the agent's
long term memory, etc.etc. Different rulesystems within an agent may
have overlapping databases.
--
Aaron Sloman, ( http://www.cs.bham.ac.uk/~axs )
School of Computer Science, The University of Birmingham, B15 2TT, England
EMAIL A.Sloman@cs.bham.ac.uk
Phone: +44-121-414-4775 (Sec 3711) Fax: +44-121-414-4281
|