2017-05-20 4 views
1

나는 문자를 A, B, C, D 및 E로 5x5 행렬을 채워야하는 문제를 해결하려고합니다. 각 문자는 각 행과 각 열에 두 번 이상 나타날 수 없습니다 . 몇몇 초기 편지 위치가 주어진다. 저는 모든 직책을 별도의 사실로 작성했습니다. "M 1 1 X". 나는 올바른 편지로 사실을 주장하고 조건을 다시 확인하기 위해 진압을 반복하는 방법에 어려움을 겪고 있습니다. 그것은의를 주장 예 아니라를 위해 위의CLIPS에서 루핑 디플 루어

(defrule solveA5 
?a <-(M 5 ?c X) 
(not (M ?x ?c A)) 
=> 
(retract ?a) 
(assert (M 5 ?c A)) 
) 

코드 5 행의 모든 ​​위치에서의 존재를 확인하지만, 문제는 조건이 정확한 사실을 주장 만이 아닌 시작하고 다시 확인에 확인하는 것입니다 모든 위치.

deffunction을 사용하여 루프 이탈을 시도했습니다.

(deffunction solve (?letter) 
(loop-for-count (?x 1 5) do 
    (loop-for-count (?y 1 5) do 
     (build (str-cat"defrule costam 
      ?a <-(M ?x ?y X) 
      (not (and(M ?x ?a ?letter) (M ?b ?y ?letter)) 
      => 
      (retract ?a) 
      (assert (M ?x ?y ?letter))") 
     ) 
    ) 
) 
) 

은 불행하게도 "FALSE"

(solve A) 

수익을 실행하고있는 사실을 수정하지 않습니다.

답변

0

규칙 내에서 반복을 처리하려면 반복 정보를 사실로 지정해야 규칙에서이 정보를 일치시키고 수정할 수 있어야합니다. 배치에서, 어떤 특정 순서로이 작업을 수행하는 것이 중요하지, 그래서 당신은 임의로 규칙 화재 놓고 할 수 있도록 행, 열 및 문자를 포함하는 정보를 주장 할 수 있습니다 :이 예에서는

CLIPS> 
(deftemplate element 
    (slot row) 
    (slot column) 
    (slot value)) 
CLIPS>  
(deftemplate print 
    (slot row) 
    (slot column) 
    (slot end-of-row)) 
CLIPS>  
(deffacts initial 
    (rows 1 2 3 4 5) 
    (columns 1 2 3 4 5) 
    (letters A B C D E)) 
CLIPS>  
(defrule place 
    (rows $? ?r1 $?) 
    (columns $? ?c1 $?) 
    (letters $? ?l $?) 
    (not (element (row ?r1) (column ?c1))) 
    (not (and (element (row ?r2) 
         (column ?c2) 
         (value ?l)) 
      (test (or (= ?r1 ?r2) (= ?c1 ?c2))))) 
    => 
    (assert (element (row ?r1) (column ?c1) (value ?l)))) 
CLIPS>   
(defrule print-start 
    (declare (salience -10)) 
    (rows ?r $?) 
    (columns ?c $?rest) 
    => 
    (assert (print (row ?r) 
        (column ?c) 
        (end-of-row (= (length$ ?rest) 0))))) 
CLIPS>  
(defrule print-next-column 
    (declare (salience -10)) 
    ?f <- (print (column ?c)) 
    (columns $? ?c ?nc $?rest) 
    => 
    (modify ?f (column ?nc) 
       (end-of-row (= (length$ ?rest) 0)))) 
CLIPS> 
(defrule print-next-row 
    (declare (salience -10)) 
    ?f <- (print (column ?c) (row ?r)) 
    (columns $?first ?c) 
    (rows $? ?r ?nr $?) 
    => 
    (if (= (length$ ?first) 0) 
     then 
     (bind ?eor TRUE) 
     (bind ?nc ?c) 
     else 
     (bind ?eor FALSE) 
     (bind ?nc (nth$ 1 ?first))) 
    (modify ?f (row ?nr) 
       (column ?nc) 
       (end-of-row ?eor))) 
CLIPS>  
(defrule print-placed 
    (print (row ?r) (column ?c) (end-of-row ?eor)) 
    (element (row ?r) (column ?c) (value ?l)) 
    => 
    (if ?eor 
     then 
     (printout t ?l crlf) 
     else 
     (printout t ?l " "))) 
CLIPS> 
(defrule print-unplaced 
    (print (row ?r) (column ?c) (end-of-row ?eor)) 
    (not (element (row ?r) (column ?c))) 
    => 
    (if ?eor 
     then 
     (printout t "?" crlf) 
     else 
     (printout t "? "))) 
CLIPS> (reset) 
CLIPS> (run) 
E D C B A 
? C D A B 
? B A D C 
? A B C D 
A ? ? ? E 
CLIPS> 

을의 인쇄 규칙은 반복 정보를 사실에 저장하여 행과 열을 반복합니다. 임의의 방식으로 요소를 할당하는 작업 영역 규칙보다 훨씬 더 복잡하다는 것을 알 수 있습니다.

값을 임의로 또는 특정 순서로 할당하는 경우 솔루션을 방지하는 값을 할당 할 수 있으므로 솔루션을 찾는 데 필요한 역 추적을 구현해야합니다. 이 예에서, 사실은 시도 된 값의 게재 위치와 값의 순서에 대한 정보를 저장 :

CLIPS> (clear) 
CLIPS> 
(deftemplate element 
    (slot row) 
    (slot column) 
    (slot value (default unset)) 
    (multislot values) 
    (slot placement)) 
CLIPS>  
(deffacts initial 
    (placement 0) 
    (rows 1 2 3 4 5) 
    (columns 1 2 3 4 5) 
    (letters A B C D E)) 
CLIPS>  
(defrule prime 
    (placement ?p) 
    (rows $? ?r $?) 
    (columns $? ?c $?) 
    (letters $?l) 
    (not (element (placement ?p))) 
    (not (element (row ?r) (column ?c))) 
    => 
    (assert (element (placement ?p) (values ?l) (row ?r) (column ?c)))) 
CLIPS>  
(defrule place-good 
    ?f1 <- (placement ?p) 
    ?f2 <- (element (placement ?p) 
        (value unset) 
        (row ?r1) 
        (column ?c1) 
        (values ?v $?rest)) 
    (not (and (element (row ?r2) 
         (column ?c2) 
         (value ?v)) 
      (test (or (= ?r1 ?r2) (= ?c1 ?c2))))) 
    => 
    (retract ?f1) 
    (assert (placement (+ ?p 1))) 
    (modify ?f2 (value ?v) (values ?rest))) 
CLIPS>  
(defrule place-bad 
    (placement ?p) 
    ?f2 <- (element (placement ?p) 
        (value unset) 
        (row ?r1) 
        (column ?c1) 
        (values ?v $?rest)) 
    (element (row ?r2) 
      (column ?c2) 
      (value ?v)) 
    (test (or (= ?r1 ?r2) (= ?c1 ?c2))) 
    => 
    (modify ?f2 (values ?rest))) 
CLIPS>  
(defrule backtrack 
    ?f1 <- (placement ?p) 
    ?f2 <- (element (placement ?p) 
        (value unset) 
        (values)) 
    ?f3 <- (element (placement =(- ?p 1)) 
        (value ~unset)) 
    => 
    (retract ?f1) 
    (assert (placement (- ?p 1))) 
    (retract ?f2) 
    (modify ?f3 (value unset))) 
CLIPS>  
(defrule print 
    (declare (salience -10)) 
    (rows $?rows) 
    (columns $?columns) 
    => 
    (progn$ (?r ?rows) 
     (progn$ (?c ?columns) 
     (if (not (do-for-fact ((?f element)) 
           (and (= ?r ?f:row) (= ?c ?f:column)) 
        (printout t ?f:value " "))) 
      then 
      (printout t "? "))) 
     (printout t crlf))) 
CLIPS> (reset) 
CLIPS> (run) 
B C D E A 
A B C D E 
C A E B D 
D E A C B 
E D B A C 
CLIPS> 

인쇄 규칙을 하나의 규칙으로 단순화 된 그 행동의 행과 열을 반복 를 선택하고 사실 조회 함수를 사용하여 지정된 값을 검색합니다.

당신이 값의 일부 preassign 경우이 프로그램은 또한 작동

:

CLIPS> (reset) 
CLIPS> (assert (element (row 1) (column 1) (value A))) 
<Fact-5> 
CLIPS> (assert (element (row 3) (column 3) (value C))) 
<Fact-6> 
CLIPS> (assert (element (row 5) (column 4) (value E))) 
<Fact-7> 
CLIPS> (run) 
A C E D B 
B A D C E 
D E C B A 
E D B A C 
C B A E D 
CLIPS>