The selection function returns two values: the selected element and its position. The Lisp definition of the selection function currently used is as follows
(defun dynamic-selection (clause &aux (body (clause-body clause))) (if body ;; if clause has a body (multiple-value-bind (selected-element pos) ;; determine the selected-element and its position (get-next-dtr body) (if selected-element ;; return both if found (values selected-element pos) ;; otherwise choose the leftmost, which has pos 0 (values (first body) 0))) ;; NIL is used to indicate epsilon (values nil nil))) (defun get-next-dtr (body) "loop through the elements of the body until there is a body whose essential feature is instantiated. In that case return the relation and its position. Otherwise return NIL." (let ((cnt 0)) (dolist (relation body (values nil nil)) (if (if (equal *ef* *sem-path*) (get-sem-constraints relation *sem-path*) (get-string-constraints relation *phon-path*)) (return (values relation cnt)) (incf cnt)))))
We use a dispatching mechanism to store the selection function to be used by the inference rules. This is easily done in Lisp by storing the selection function as a property to a specific Lisp symbol. The inference rules then have to access this property field and then call the bound function to the current arguments. In our system we use the symbol :selector and the property :function to bind the selection function. Thus, when a new item is created, the currently bound selection function is activated by the call:
(funcall (get :selector :function) clause)
We have used such a mechanism to be able to experiment with several selection functions without the need for recompiling the whole code. Furthermore, if it is known that for a specific grammar the leftmost selection function is needed, it is very easy to define such a function and to make it available to the inference rules. For example the definition of the leftmost selection function could be:
(defun leftmost-selection (clause &aux (body (clause-body clause))) (if body (values (first body) 0) (values nil nil)))
Thus, our implementation is modular with respect to the selection function.