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.