我正在尝试为CLIPS中的八个皇后问题(https://en.wikipedia.org/wiki/Eight_queens_puzzle)开发解算器,但我是这种语言的新手。 首先,我试图制定一个规则来验证一个新的断言,比较先前断言的列/行。它在插入重复行时工作,但是当插入重复列时,它不会检测到它。这段代码有什么问题?
(defrule verificaAssercaoDamas ; verifica se atende as regras
?novaPosicao <- (d ?line ?column)
?posicao <- (d ?line2 ?column2)
(test (neq ?posicao ?novaPosicao))
(test (or (eq ?line2 ?line) (eq ?column column2)) )
=>
(retract ?novaPosicao)
(if (< (+ ?column 1) 9)
then (assert (d ?line (+ ?column 1) ))
)
CLIPS> (assert(d 0 0))
<Fact-1>
CLIPS> (assert(d 1 0))
<Fact-2>
CLIPS> (assert(d 0 1))
<Fact-3>
CLIPS> (agenda)
0 cerificaAssercaoDamas: f-3, f-1
0 cerificaAssercaoDamas: f-1, f-3
For a total of 2 activations.
CLIPS>
答案 0 :(得分:0)
您正在使用表达式(eq?column column2),它将变量?列与符号column2进行比较。您需要将其与变量?column2进行比较。
CLIPS> (clear)
CLIPS>
(defrule verificaAssercaoDamas
?novaPosicao <- (d ?line ?column)
?posicao <- (d ?line2 ?column2)
(test (neq ?posicao ?novaPosicao))
(test (or (eq ?line2 ?line) (eq ?column ?column2)))
=>
(retract ?novaPosicao)
(if (< (+ ?column 1) 9)
then (assert (d ?line (+ ?column 1)))))
CLIPS> (assert (d 0 0))
<Fact-1>
CLIPS> (assert (d 1 0))
<Fact-2>
CLIPS> (assert (d 0 1))
<Fact-3>
CLIPS> (agenda)
0 verificaAssercaoDamas: f-3,f-1
0 verificaAssercaoDamas: f-1,f-3
0 verificaAssercaoDamas: f-2,f-1
0 verificaAssercaoDamas: f-1,f-2
For a total of 4 activations.
CLIPS>
如果您正在测试数字的相等/不等式,则应使用=和!=(或&lt;&gt;)函数,因为这些函数将为非数字参数抛出错误:
CLIPS> (clear)
CLIPS>
(defrule verificaAssercaoDamas
?novaPosicao <- (d ?line ?column)
?posicao <- (d ?line2 ?column2)
(test (neq ?posicao ?novaPosicao))
(test (or (= ?line2 ?line) (= ?column column2)))
=>
(retract ?novaPosicao)
(if (< (+ ?column 1) 9)
then (assert (d ?line (+ ?column 1)))))
[ARGACCES5] Function = expected argument #2 to be of type integer or float
ERROR:
(defrule MAIN::verificaAssercaoDamas
?novaPosicao <- (d ?line ?column)
?posicao <- (d ?line2 ?column2)
(test (neq ?posicao ?novaPosicao))
(test (or (= ?line2 ?line) (= ?column column2)
CLIPS>
您还可以通过检查?novaPosicao的事实索引是否大于?posicao的事实索引来删除重复的激活:
CLIPS> (clear)
CLIPS>
(defrule verificaAssercaoDamas
?novaPosicao <- (d ?line ?column)
?posicao <- (d ?line2 ?column2)
(test (< (fact-index ?posicao) (fact-index ?novaPosicao)))
(test (or (= ?line2 ?line) (= ?column ?column2)))
=>
(retract ?novaPosicao)
(if (< (+ ?column 1) 9)
then (assert (d ?line (+ ?column 1)))))
CLIPS> (assert (d 0 0))
<Fact-1>
CLIPS> (assert (d 1 0))
<Fact-2>
CLIPS> (assert (d 0 1))
<Fact-3>
CLIPS> (agenda)
0 verificaAssercaoDamas: f-3,f-1
0 verificaAssercaoDamas: f-2,f-1
For a total of 2 activations.
CLIPS>