norvig / paip-lisp

Lisp code for the textbook "Paradigms of Artificial Intelligence Programming"

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Chapter 8 - recursive expansion of abbreviated patterns

homedirectory opened this issue · comments

Description

8.3 Associativity and Commutativity
The following pattern matching abbreviations are defined in such a way that causes a recursive expansion:

;; Define n and m as numbers; s as a non-number:
(pat-match-abbrev 'n '(?is n numberp))
(pat-match-abbrev 'm '(?is m numberp))
(pat-match-abbrev 's '(?is s not-numberp))

For example, we can see here that the 2nd n got recursively expanded (its binding is the first item in the resulting list).

> (pat-match '(n n) '(5 5))
(((?IS (?IS N NUMBERP) NUMBERP) . 5) ((?IS N NUMBERP) . 5))

This happens because the first thing pat-match does is expand the received pattern. At the same time it might be called recursively (e.g., by single-matcher), thus expanding the rest of an already expanded pattern...
In the above example (n n) will be first expanded to ((?is n numberp) (?is n numberp)), the car of which will get processed by single-matcher, while the rest will be recursively processed by pat-match, which will expand (?is n numberp) into (?is (?is n numberp) numberp).

Improvement

I've managed to avoid this by eliminating the recursive relationship and using ?n instead:

(pat-match-abbrev '?n '(?is n numberp))

Consequently, affected simplification rules had to be modified to use ?n on the left-hand side but just n on the right hand-side. For example:

(?s * ?n = n * s)
(?n * (?m * x) = (n * m) * x)