Have you been avoiding the Pop-11 pattern matcher because its variables
cannot be lexically scoped, and/or because it cannot be used inside a
section?
If you are using Poplog V15.0 or later, a solution is now available for
this, which uses the fact that the pattern matcher uses "valof" and
since Poplog V15, valof and its updater work on identifiers as well as
on words.
THE SOLUTION:
I have defined "!" as a new syntactic operator which can precede an
ordinary Pop-11 pattern. It has two effects:
(a) All pattern variables, indicated by "?" and "??" are treated as
lvars local to the current procedure (outside any procedure they are
left as vars, unless already declared as top level lvars).
(b) The words following "?" and "??" are replaced by identifiers in the
pattern, at compile time.
=======================================================================
Example using the "!" pattern prefix:
define list_between(item1, item2, list) -> found;
;;; return a list of items found between item1 and item2 in list
unless list matches ![== ^item1 ??found ^item2 ==] then
false -> found;
endunless;
enddefine;
vars words = [a b c d e f g];
list_between("a", "g", words) =>
** [b c d e f]
list_between("c", "g", words) =>
** [d e f]
=======================================================================
This avoids the problem that you cannot use the pattern matcher in a
section, and cannot do things like
lvars person;
if list matches [ .... ?person ....] then
.... person ...
endif
since the lexical variable person, and the pattern variable person have
nothing to do with each other. By using "!" before the pattern you can
link those variables.
The above could also be done using the library LIB FMATCHES instead of
MATCHES, but only with pattern expresssions directly following
"fmatches".
There is no such restriction in the new facility: you can also use "!"
inside a procedure that passes a pattern to another procedure, such as
one of the Pop-11 database procedures. E.g.
define has_parent(person) -> parent;
unless present( ! [parent ^person ?parent] ) then
false -> parent
endunless
enddefine;
The use of the matcher inside the database procedure PRESENT will set
the value of the lexical variable parent from the procedure has_parent.
So the new technique is quite powerful. "!" also works with foreach,
forevery, flush, etc.
Also if you use a pattern variable inside a procedure, without
previously declaring it as lvars you'll get an error message like this
define silly(list);
list matches ! [?x is ?y]
enddefine;
;;; WARNING DECLARING PATTERN VARIABLE x AS LVARS
;;; IN FILE /home/staff/axs/news/comp.lang.pop.patterns
;;; LINE 85
;;; WARNING DECLARING PATTERN VARIABLE y AS LVARS
;;; IN FILE /home/staff/axs/news/comp.lang.pop.patterns
;;; LINE 85
This will make it much easier to detect errors due to mistyped
pattern variables. However, the warnings can be turned off, since the
pattern variables are declared as lvars anyway.
SUGGESTION:
I would recommend that "!" should be defined as a standard syntax
operator in Pop-11 with this function, even though there are plans to
introduce a new more general type of pattern data-structure and matcher
that's not restricted to lists. The idea is that "=" will recognize
these pattern datastructures in any object, and behave appropriately.
I don't think the new matcher will make the old one totally redundant.
For several years to come there will be code that uses "matches" and its
derivatives, and more importantly there will be masses of teaching
material that uses it. I am now converting my teaching materials,
available in
ftp://ftp.cs.bham.ac.uk/pub/dist/poplog/teach
to use "!" and lvars declarations for pattern variables, and this is
much easier than switching to a new matcher, which would require far
more rewriting.
If you want to get the new matcher there are three main files available
from the Birmingham Poplog ftp directory:
ftp://ftp.cs.bham.ac.uk/pub/dist/poplog/lib/readpattern.p
Defines the library, to go into $poplocal/local/lib/
ftp://ftp.cs.bham.ac.uk/pub/dist/poplog/auto/!.p
This is a simple file that compiles lib readpattern. It makes
the operator "!" autoloadable, if put in
$poplocal/local/auto/!.p
ftp://ftp.cs.bham.ac.uk/pub/dist/poplog/help/readpattern
The HELP file.
For convenience I've made available a compressed tar file in
ftp://ftp.cs.bham.ac.uk/pub/dist/poplog/readpattern.tar.gz
This contains the four files:
lib/readpattern.p auto/!.p
help/readpattern teach/matches
I've rewritten quite a lot of teach files to use this syntax, all in
ftp://ftp.cs.bham.ac.uk/pub/dist/poplog/teach/
A substantial collection of teaching materials and utilities from
Birmingham, including the above, is available in the compressed tar
file:
ftp://ftp.cs.bham.ac.uk/pub/dist/poplog/linux/bhamteachtar.gz
This is small enough to fit on a single diskette, which may be useful to
linux Poplog users wishing to transfer a useful set of teaching
extensions to their PC.
NOTE: the latest version of the forward chaining production system
interpreter Poprulebase (successor to Newpsys) also uses lexically
scoped pattern variables. Source code and documentation available
in this directory tree:
ftp://ftp.cs.bham.ac.uk/pub/dist/poplog/prb/
or in a compressed tar file in
ftp://ftp.cs.bham.ac.uk/pub/dist/poplog/prbtar.gz
Other tar files available by ftp are described in:
ftp://ftp.cs.bham.ac.uk/pub/dist/poplog/README
Comments and suggestions welcome.
Aaron
---
--
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
|