I\'ve been playing around with natural language parse trees and manipulating them in various ways. I\'ve been using Stanford\'s Tregex and Tsurgeon tools but the code is a mess
Here is a second version in Common Lisp. This time I'm using a pattern matcher.
I'm using a function that matches a pattern against Lisp data. PMATCH:MATCH is an enhanced version of a pattern matcher found in the book Winston/Horn, Lisp, 3rd Edition. There are similar pattern matching functions available.
The data is as in my other answer.
The tree mapping function is changed to use the pattern matcher. The PMATCH:MATCH function returns T or an assoc list of bindings if the match is successful. It returns NIL if the match is not successful. The PMATCH:INSTANTIATE-PATTERN takes a pattern and a set of bindings. It returns a new list structure, where the pattern variables are replaced with the bindings.
(defun treemapp (tree pattern transformer)
(cond ((null tree) nil)
((consp tree)
(let ((bindings (pmatch:match pattern tree)))
(if bindings
(pmatch:instantiate-pattern transformer bindings)
(cons (node-type tree)
(mapcar (lambda (child)
(treemapp child pattern transformer))
(node-children tree))))))
(t tree)))
The example uses now patterns.
The pattern is a list structure. #?symbol matches a single item and creates a binding for symbol. #$symbol matches a list of items and creates a binding for symbol.
The transformer is a pattern that will be instantiated with the bindings.
(defun example1 ()
(pprint (treemapp *tree*
'(NP (NP (#?type bank)) (PP #$children))
'(NP (NP (#?type bank) #$children)))))
Running this code returns the same result as in my other answer.