[Date Prev] [Date Next] [Thread Prev] [Thread Next] Date Index Thread Index Search archive:
Date:Mon Oct 15 00:51:21 1996 
Subject:Using pattern variables as lvars 
From:Aaron Sloman 
Volume-ID:961015.01 

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