(full-reset) (undefine-all) ;;; ;;; Required axioms ;;; (disjoint c1 c2 c3 c4 c5 c6 c7 c8 c9) (define-primitive-role r) (define-primitive-role q1 :transitive t :parent r) (define-primitive-role q2 :transitive t :parent r) (define-primitive-role h1 :transitive t :parent r) (define-primitive-role h2 :transitive t :parent r) (define-primitive-role v1 :transitive t :parent r) (define-primitive-role v2 :transitive t :parent r) (implies top (and (or c1 c2 c3 c4 c5 c6 c7 c8 c9) (or (not c1) (all r (not c1))) (or (not c2) (all r (not c2))) (or (not c3) (all r (not c3))) (or (not c4) (all r (not c4))) (or (not c5) (all r (not c5))) (or (not c6) (all r (not c6))) (or (not c7) (all r (not c7))) (or (not c8) (all r (not c8))) (or (not c9) (all r (not c9))))) ;;; ;;; Required MiniLisp helper functions ;;; (define rel (a b r) (cond ((eq r 'q) (add-role-assertion (current-abox) a b 'q1) (add-role-assertion (current-abox) b a 'q2)) ((eq r 'h) (add-role-assertion (current-abox) a b 'h1) (add-role-assertion (current-abox) b a 'h2)) ((eq r 'v) (add-role-assertion (current-abox) a b 'v1) (add-role-assertion (current-abox) b a 'v2)))) (define i (x y) (to-symbol (format nil "i~A~A" x y))) (define grid () ;; 3x3 (dolist (x-off '(0 3 6)) (dolist (y-off '(0 3 6)) (rel (i (+ x-off 1) (+ y-off 1)) (i (+ x-off 1) (+ y-off 2)) 'q) (rel (i (+ x-off 1) (+ y-off 2)) (i (+ x-off 1) (+ y-off 3)) 'q) (rel (i (+ x-off 1) (+ y-off 3)) (i (+ x-off 2) (+ y-off 3)) 'q) (rel (i (+ x-off 2) (+ y-off 3)) (i (+ x-off 3) (+ y-off 3)) 'q) (rel (i (+ x-off 3) (+ y-off 3)) (i (+ x-off 3) (+ y-off 2)) 'q) (rel (i (+ x-off 3) (+ y-off 2)) (i (+ x-off 3) (+ y-off 1)) 'q) (rel (i (+ x-off 3) (+ y-off 1)) (i (+ x-off 2) (+ y-off 1)) 'q) (rel (i (+ x-off 2) (+ y-off 1)) (i (+ x-off 2) (+ y-off 2)) 'q))) ;;; ;;; ;;; (dotimes (y-off 9) (let ((y-off (1+ y-off))) (rel (i 1 y-off) (i 2 y-off) 'h) (rel (i 2 y-off) (i 3 y-off) 'h) (rel (i 3 y-off) (i 4 y-off) 'h) (rel (i 4 y-off) (i 5 y-off) 'h) (rel (i 5 y-off) (i 6 y-off) 'h) (rel (i 6 y-off) (i 7 y-off) 'h) (rel (i 7 y-off) (i 8 y-off) 'h) (rel (i 8 y-off) (i 9 y-off) 'h))) ;;; ;;; ;;; (dotimes (x-off 9) (let ((x-off (1+ x-off))) (rel (i x-off 1) (i x-off 2) 'v) (rel (i x-off 2) (i x-off 3) 'v) (rel (i x-off 3) (i x-off 4) 'v) (rel (i x-off 4) (i x-off 5) 'v) (rel (i x-off 5) (i x-off 6) 'v) (rel (i x-off 6) (i x-off 7) 'v) (rel (i x-off 7) (i x-off 8) 'v) (rel (i x-off 8) (i x-off 9) 'v)))) ;;; ;;; MiniLisp interface functions ;;; (define sudoku-web (rows) (forget-abox 'default) (let ((n (length rows))) (cond ((= n 9) (grid) (let ((x 0)) (maplist (lambda (row) (incf x) (let ((y 0)) (maplist (lambda (item) (incf y) (when (and (numberp item) (> item 0)) (add-concept-assertion (current-abox) (to-symbol (format nil "i~A~A" x y)) (to-symbol (format nil "c~A" item))))) row))) rows)) (with-html ("result.html") (html (head) (html (title) (content "Sudoku"))) (if (abox-consistent-p) (let ((n 9)) (html (body) (html (h1) (content "Sudoku Solution")) (html (table :border 1) (dotimes (x n) (html (tr) (dotimes (y n) (html (td) (content (subseq (symbol-name (first (first (most-specific-instantiators (to-symbol (format nil "i~A~A" (1+ x) (1+ y))) (current-abox))))) 1))))))))) (html (h1) (content "Sorry, no solution")))) (publish-file "result.html" "/sudoku.html" "text/html")) (t (format t "~%Bad Sudoku."))))) (define sudoku (rows) (forget-abox 'default) (let ((n (length rows))) (cond ((= n 9) (grid) (let ((x 0)) (maplist (lambda (row) (incf x) (let ((y 0)) (maplist (lambda (item) (incf y) (when (and (numberp item) (> item 0)) (add-concept-assertion (current-abox) (to-symbol (format nil "i~A~A" x y)) (to-symbol (format nil "c~A" item))))) row))) rows)) (if (abox-consistent-p) (let ((n 9)) (terpri) (terpri) (dotimes (x n) (format t "-------------------------------------") (terpri) (dotimes (y n) (format t "| ~A " (subseq (symbol-name (first (first (most-specific-instantiators (to-symbol (format nil "i~A~A" (1+ x) (1+ y))) (current-abox))))) 1))) (format t "|") (terpri)) (format t "-------------------------------------") (terpri)) (format t "~%Sorry, no solution"))) (t (format t "~%Bad Sudoku."))))) ;;; ;;; Register new server functions... ;;; (server-function sudoku-web) (server-function sudoku) ;;; ;;; ... and use them! ;;; (time (SUDOKU ((0 6 0 5 0 3 2 0 8) (1 0 5 0 0 8 0 0 3) (8 0 0 0 0 6 4 1 0) (9 0 0 0 0 1 0 4 0) (0 7 0 3 0 4 0 8 0) (0 8 0 7 0 0 0 0 9) (0 1 8 4 0 0 0 0 6) (2 0 0 8 0 0 7 0 1) (7 0 6 1 0 5 0 3 0)))) (time (SUDOKU-web ((2 0 0 8 5 0 0 0 7) (0 7 0 4 1 0 0 3 0) (5 0 0 0 2 0 0 0 8) (0 0 0 0 0 0 0 8 1) (7 1 2 0 0 0 9 4 5) (3 8 0 0 0 0 0 0 0) (6 0 0 0 8 0 0 0 9) (0 2 0 0 9 5 0 7 0) (1 0 0 0 3 6 0 0 4)))) ;;; open http://localhost:8080/sudoku.html in your WebBrowser