functional dependencies gone wild added by bfig on Sun Apr 8 06:35:22 2012
;utility library ;Bruno Figares (use srfi-1) (define (make-eq? tag) (lambda (x) (eq? tag x))) (define (apply-with x) (lambda (f) (f x))) (define (eq-any? set) (lambda (x) (any (apply-with x) (map make-eq? set)))) (define (one-step-closure set deps) (delete-duplicates (concatenate (cons set (map (lambda (lreq->lget) (if (every (eq-any? set) (car lreq->lget)) (cdr lreq->lget) '())) deps))))) (define (closure set deps) (let loop ((closure set)) (let ((nextstep (one-step-closure closure deps))) (if (= (length nextstep) (length closure)) closure (loop nextstep))))) (define (change-deps toremove prevdeps) (let* ((eq-any? (eq-any? toremove)) (changedep (lambda (lreq->lget) (if (or (every eq-any? (car lreq->lget)) (every eq-any? (cdr lreq->lget))) '() `(,(cons (lset-difference eq? (car lreq->lget) toremove) (lset-difference eq? (cdr lreq->lget) toremove))))))) (concatenate (map changedep prevdeps)))) (define (list-of-deps-arrangements avail-deps) (let loop ((accum-lst '()) (lst-next avail-deps)) (if (null? lst-next) accum-lst (loop (cons (cons (car lst-next) (cdr lst-next)) accum-lst) (cdr lst-next))))) (define (find-superkey relational-schema functional-dependencies) (letrec ((sol-size (length relational-schema)) (sol-list (list relational-schema)) (add-solution (lambda (newsol) (if (< (length newsol) sol-size) (begin (set! sol-list (list newsol)) (set! sol-size (length newsol))) (set! sol-list (cons newsol sol-list))))) (forward? (lambda (nextstep) (<= nextstep (sol-size)))) (init-elems (lset-difference eq? relational-schema (concatenate (map cdr functional-dependencies)))) (temp-closure (closure init-elems functional-dependencies)) (init-reduced-fd (change-deps temp-closure functional-dependencies)) (to-determine (lset-difference eq? relational-schema temp-closure)) (list-of-deps-arrangements (lambda (avail-deps) (let loop ((accum-lst '()) (lst-next avail-deps)) (if (null? lst-next) accum-lst (loop (cons (cons (car lst-next) (cdr lst-next)) accum-lst) (cdr lst-next)))))) (find-sk-internal (lambda (next-dependency available-keys functional-dependencies set-to-determine preset) (let* ((fd-closure (closure (car next-dependency) functional-dependencies)) (new-av-keys (change-deps fd-closure available-keys)) (new-fd-keys (change-deps fd-closure functional-dependencies)) (new-preset (begin (newline) (display (car next-dependency)) (newline) (display preset) (newline) (delete-duplicates eq? (concatenate (list preset (car next-dependency)))))) (new-set-to-determine (lset-difference eq? set-to-determine new-preset))) (if (null? new-set-to-determine) (add-solution new-preset) (for-each (lambda (key-avkeys) (if (forward? (+ (length (car key-avkeys)) (length new-preset))) (find-sk-internal (car key-avkeys) (cdr key-avkeys) new-fd-keys new-set-to-determine new-preset) (list-of-deps-arrangements new-av-keys))))))))) (if (null? to-determine) (list init-elems) (begin (for-each (lambda (key-avkeys) (find-sk-internal (car key-avkeys) (cdr key-avkeys) init-reduced-fd to-determine init-elems)) (list-of-deps-arrangements init-reduced-fd)) (sol-list))))) (find-superkey '(A B C) '( ((A) . (B)) ((B) . (A)) ((A) . (C)))) (define func-dep-1 '((A B) . (G))) (define func-dep-2 '((B) . (C))) (define func-dep-3 '((D) . (A))) (define func-dep-4 '((A) . (B))) (define fd-list `(,func-dep-1 ,func-dep-2 ,func-dep-3 ,func-dep-4))