[Date Prev] [Date Next] [Thread Prev] [Thread Next] Date Index Thread Index Search archive:
Date:Mon Dec 2 15:53:33 1995 
Subject:Re: Making the matcher robust? 
From:Jonathan Cunningham 
Volume-ID:951202.09 

In article <49lrtm$3n8@percy.cs.bham.ac.uk>,
A.Sloman@cs.bham.ac.uk (Aaron Sloman) wrote:

>I was discussing recent developments with a new convert to Pop-11
>at Birmingham, Riccardo Poli, who uses it for teaching and research
>(even on evolutionary algorithms).
>
>When I mentioned that I had found a way to make the matcher work with
>lvars by using lib readpattern and the syntax ![ ..... ] for patterns,
>he commented that in effect that violated the spirit of lvars because
>the matcher is then a procedure defined elsewhere that has access to the
>lvars variables, which is not supposed to be possible with lexical
>scoping!
>
>This is a point that had never occurred to me nor, it seems, to others
>who had wanted the matcher to be made to work with lvars.
>
(snip)
>
>What do others think?
>Aaron

I often write code (in languages other than pop11) which use a
procedural matcher (i've lost count of how many times i've written
simple, one-off, dedicated matchers :-). [Presumably anathema to
Chris Dollins ;-)].

If I had to now add matching to pop11, I would do it like this.
(1) use instances of a pattern variable class, instead of query
variable-name. A bit like the way prolog unification works.
(2) provide two pieces of syntactic sugar: to initialise lvars to
instances of pattern objects, and to de-reference them.

Some examples to show what this would look like:

;;; this
    vars x, y;
    if [?x ?y] matches [a b] then
        [first is ^x]=>
;;; becomes
    pvars x, y;
    if [^x ^y] matches [a b] then
        instantiate x;
        [first is ^x]=>

;;; and this
    lvars pat;
    vars x, y, z;
    [== ?x ??y ?z ==] -> pat;
    some_procedure_or_other(pat);
    do_something(x, y, z);
;;; becomes this
    lvars pat;
    pvars x, y = "??", z;
    [== ^x ^y ^z ==] -> pat;
    some_procedure_or_other(pat);
    instantiate x, y, z;
    do_something(x, y, z);

The examples are _not_ intended to specify what the syntax should be
like; there are lots of detailed design decisions needed. I intend only
to illustrate what I meant. In particular, you probably wouldn't use
the "pat" variable in the above example, but it does illustrate a
problem: after dereferencing x, y and z, you could still use the
pattern in pat, but you couldn't dereference x, y and z a second
time. You could, however, do something like

   lvars xx, yy, zz;
   foreach pat do
        x, y, z -> xx, yy, zz;
        instantiate xx, yy, zz;

The underlying mechanisms are ok and don't violate locality of access
to lvars whilst allowing matching procedures, but clearly better syntax
is needed.

But one further comment: Don't (as mentioned in an earlier post)
have two different pattern variable classes: there are many other
ways to extend pattern matching other than just adding segment
pattern elements. Use one class and allow subclassing (i.e. there should
be hooks in the matcher which call methods of the pattern variable
instance - an obvious use of this is in restriction procedures).

As an example of an extension, you could subclass
the segment pattern variable class to allow arbitrary order of
elements in the subsequence, so that the pattern (with ss a pvar)
    [== foo ^ss baz ^ss grum ==]
would match
    [cat foo dog hen baz hen dog grum cow]

Many other extensions spring to mind.

Jonathan Cunningham