I'm trying to solve 8 queens problem using CLIPS. This my code solves part of it. Only horizontal and vertical checks, so you can say it solves 8 rooks problem. What i can't get is how to make a diagonal check. CLIPS wont allow any checks for facts like (not (queen ?i-1 ?j-1)), (not (queen ?i-2 ?j-2)) and so on...
(assert (cur 1 1))
(assert (placed 0))
(defrule placer "Placer"
?a <- (cur ?i ?j)
?b <- (placed ?placed)
(test (<= ?i 8))
(test (<= ?j 8))
(test (< ?placed 8))
(not (queen ?i 1|2|3|4|5|6|7|8))
(not (queen 1|2|3|4|5|6|7|8 ?j))
(not (queen (?i-1)| //diagonal check there
=>
(assert (queen ?i ?j))
(assert (placed (+ ?placed 1)))
(retract ?b)
(if (< ?j 8)
then (assert (cur ?i (+ ?j 1)))
else (assert (cur (+ ?i 1) 1)))
(retract ?a)
(printout t "Placing queen" crlf)
)
(defrule horiz "Check-hor"
?a <- (cur ?i ?j)
?b <- (placed ?placed)
(test (<= ?i 8))
(test (<= ?j 8))
(test (< ?placed 8))
(queen ?i 1|2|3|4|5|6|7|8)
=>
(if (< ?j 8)
then (assert (cur ?i (+ ?j 1)))
else (assert (cur (+ ?i 1) 1)))
(retract ?a)
(printout t "Horiz" crlf)
)
(defrule vert "Check-vert"
?a <- (cur ?i ?j)
?b <- (placed ?placed)
(test (<= ?i 8))
(test (<= ?j 8))
(test (< ?placed 8))
(queen 1|2|3|4|5|6|7|8 ?j)
=>
(if (< ?j 8)
then (assert (cur ?i (+ ?j 1)))
else (assert (cur (+ ?i 1) 1)))
(retract ?a)
(printout t "Vert" crlf)
)
The return value constraint is what you want to use:
However, I'd suggest fully constraining the queen like this:
If you modify your rules, you can now get a partial solution:
Only 5 queens have been placed. Because you don't implement any backtracking in your program, it's possible to validly place a queen that prevents all 8 queens from being placed.
Here's an N Queens program from https://sites.google.com/site/drriggsnewsite/Home/half-baked-essays/composing-thoughts-an-introduction-to-rules/eight-queens-problem that implements backtracking: