<< Previous exercise (4.76) | Index | Next exercise (4.78) >>
we can simply rearrange the order of clauses of compound queries by putting all filters at the end, which is an efficient and trivial method. In order to accomplish this, we will normalize the non-normalized compound queries during the parse phase of qeval.
;;; Exercise 4.77 (define compound-table '()) (define (put-compound combinator) (set! compound-table (cons combinator compound-table))) (define (compound? query) (memq (type query) compound-table)) (define filter-table '()) (define (put-filter operator) (set! filter-table (cons operator filter-table))) (define (filter? query) (memq (type query) filter-table)) (define (normalize clauses) (let ((filters (filter filter? clauses)) (non-filters (filter (lambda (x) (not (filter? x))) clauses))) (append non-filters filters))) (define (qeval query frame-stream) (let ((qproc (get (type query) 'qeval))) (cond ((compound? query) (qproc (normalize (contents query)) frame-stream)) (qproc (qproc (contents query) frame-stream)) (else (simple-query query frame-stream))))) (put-compound 'and) (put-filter 'not) (put-filter 'lisp-value) (put-filter 'unique)
unique is also sort of filter, but won't work with this because the contents of unique usually contain at least one variable that is not relevant with other variables.