27 iunie 2010

Problema reginelor in Clips

; Placing N non-attacking queens on a NxN chessboard
; ==================================================
; CGA 2009

(deftemplate board (slot id) (slot free_line) (multislot queens))
; chessboard = (board (id an_id) (free_line l) (queens [1 c1 ] [ 2 c2 ] ... [ N cN ] ))

(defrule read_size
=>
(printout t "Board size: ")
(bind ?n (read))
(assert (board (id (gensym)) (free_line ?n) (queens))
(solutions 0))
(if (> ?n 0) then (assert (column ?n))))

(defrule lines_and_columns
(column ?n&~1)
=>
(assert (column (- ?n 1))))

(defrule place_queen
(board (id ?id) (free_line ?l&~0) (queens $?q))
(column ?c)
(not (board (id ?id)
(queens $? [ ?lq ?cq&:(or (= ?cq ?c) (= (- ?lq ?l) (abs (- ?cq ?c)))) ] $?)))
=>
(assert (board (id (gensym)) (free_line (- ?l 1)) (queens [ ?l ?c ] $?q))))

(defrule solution
?f <- (board (free_line 0) (queens $?q))
?g <- (solutions ?c)
=>
(retract ?f ?g)
(assert (solutions (+ ?c 1)))
(printout t $?q crlf))

(defrule print_count
(declare (salience -10))
(solutions ?n)
=>
(printout t ?n " solutions" crlf))

Niciun comentariu: