I tried the brute force procedure search with a maximal depth limit, it is
really slow. while in other systems (like yap)it much faster.

In yap, I defined
move(x,y) :- up(x,y).
move(x,y) :- down(x,y).
move(x,y) :- right(x,y).
move(x,y) :- left(x,y).
and keep all the seen state in a list to avoid infinite loop.

I jess, I do the procedural search and my program is like
----
; define initial state
(bind ?initial
    (create$
        3 3 0    3 1 1    3 4 2    2 3 3
        1 2 4    4 2 5    4 4 6    3 2 7
        1 3 8    2 1 9    2 2 10   2 4 11
        1 1 12   1 4 13   4 1 14   4 3 15)
)
(printout t "initial = " ?initial crlf)

; define final state
(bind ?final
    (create$
        1 1 0    1 2 1    1 3 2    1 4 3
        2 1 4    2 2 5    2 3 6    2 4 7
        3 1 8    3 2 9    3 3 10   3 4 11
        4 1 12   4 2 13   4 3 14   4 4 15)
)
(printout t "final = " ?final crlf crlf)

; find the position of tile 0 in ?inlist
(deffunction find0 (?inlist)
    (for (bind ?i 3) (<= ?i 48) (bind ?i (+ ?i 3))
        (bind ?tile (nth$ ?i ?inlist))
        (if (= ?tile 0) then
            (bind ?x (nth$ (- ?i 2) ?inlist))
            (bind ?y (nth$ (- ?i 1) ?inlist))
            (bind ?coord (create$ ?x ?y))
            (return ?coord)
        ) ;end-if
    ); end-for
)
;(printout t "find0(initial) = " (find0 ?initial) crlf)
;(printout t "find0(final) = " (find0 ?final) crlf)

; find the tile at coordinate (?x, ?y) in ?inlist
(deffunction findtile (?inlist ?x ?y)
    (for (bind ?i 1) (<= ?i 16) (++ ?i)
        (bind ?x_comp (nth$ (- (* ?i 3) 2) ?inlist))
        (bind ?y_comp (nth$ (- (* ?i 3) 1) ?inlist))
        ;(printout t "x, y = " ?x ?y crlf)
        ;(printout t "x_comp, y_comp = " ?x_comp ?y_comp crlf)
        (if (and (eq ?x ?x_comp) (eq ?y ?y_comp)) then
            (bind ?return_val (nth$ (* ?i 3) ?inlist))
            (return ?return_val)
        ) ;end-if
    ) ;end-for
)
;(printout t "findtile(initial 2 3) = " (findtile ?initial 2 3) crlf)
;(printout t "findtile(final 2 3) = " (findtile ?final 2 3) crlf)

; remove a tile at coordinate (?x, ?y) from ?inlist
(deffunction removetile (?inlist ?x ?y)
    ;(printout t "removing (" ?x ", " ?y ") from " ?inlist crlf)
    (for (bind ?i 1) (<= ?i 16) (++ ?i)
        (bind ?x_comp (nth$ (- (* ?i 3) 2) ?inlist))
        (bind ?y_comp (nth$ (- (* ?i 3) 1) ?inlist))
        (if (and (eq ?x ?x_comp) (eq ?y ?y_comp)) then
            ;(printout t "    found, deleting" crlf)
            (bind ?outlist (delete$ ?inlist (- (* ?i 3) 2) (* ?i 3)))
            (return ?outlist)
        )
    )
)
;(printout t "remove(iniaitl 2 3) = " (removetile ?initial 2 3) crlf)
;(printout t "remove(final   2 3) = " (removetile ?final 2 3) crlf)

; check whether two states are equal, states are represented as lists
(deffunction equallist (?inlist1 ?inlist2)
    (for (bind ?i 1) (<= ?i 4) (++ ?i)
        (for (bind ?j 1) (<= ?j 4) (++ ?j)
            (bind ?tile1 (findtile ?inlist1 ?i ?j))
            (bind ?tile2 (findtile ?inlist2 ?i ?j))
            (bind ?comp_result (<> ?tile1 ?tile2))
            (if (<> ?tile1 ?tile2) then
                (return FALSE)
            )
        ) ;end-for-inner
    ) ;end-for-outer
    (return TRUE)
)
;(printout t "comp(initial final) = " (equallist ?initial ?final) crlf)
;(printout t "comp(initial initial2) = " (equallist ?initial ?initial2)
crlf)

; history will be asserted into memory, for the easy of keeping structured
list
(defquery query-history
    (history $?one_history)
)

; assert initial state into memory
(assert-string (str-cat "(history " (implode$ ?initial) ")"))

; whether a state is in history
(deffunction seen (?inlist)
    ;(printout t crlf "checking whether seen before" crlf)
    ;(printout t "inlist = " ?inlist crlf)
    ;(printout t "facts: " crlf)
    ;(facts)
    (bind ?histories (run-query* query-history))
    (while (?histories next)
        (bind ?one_history (?histories get one_history))
        ;(printout t "    one history = " ?one_history crlf)
        (if (equallist ?inlist ?one_history) then
            ;(printout t "    found, returning true" crlf)
            (return TRUE)
        )
    ) ;end-while
    ;(printout t "    not found, returning false" crlf)
    (return FALSE)
)

; define moves
; define right
(deffunction right (?inlist)
    ;(printout t "moving right ..." crlf)
    (bind ?coord0 (find0 ?inlist))
    (bind ?x0 (nth$ 1 ?coord0))
    (bind ?y0 (nth$ 2 ?coord0))
    (if (< ?y0 4) then
        (bind ?y1 (+ ?y0 1))
        (bind ?tile (findtile ?inlist ?x0 ?y1))
        (bind ?outlist (removetile ?inlist ?x0 ?y0))
        (bind ?outlist (removetile ?outlist ?x0 ?y1))
        (bind ?outlist (create$ ?x0 ?y0 ?tile ?x0 ?y1 0 ?outlist))
        (return ?outlist)
     else
        (return ?inlist)
    ) ;end-if
)

; define left
(deffunction left (?inlist)
    ;(printout t "moving left ..." crlf)
    (bind ?coord0 (find0 ?inlist))
    (bind ?x0 (nth$ 1 ?coord0))
    (bind ?y0 (nth$ 2 ?coord0))
    (if (> ?y0 1) then
        (bind ?y1 (- ?y0 1))
        (bind ?tile (findtile ?inlist ?x0 ?y1))
        (bind ?outlist (removetile ?inlist ?x0 ?y0))
        (bind ?outlist (removetile ?outlist ?x0 ?y1))
        (bind ?outlist (create$ ?x0 ?y0 ?tile ?x0 ?y1 0 ?outlist))
        (return ?outlist)
     else
        (return ?inlist)
    ) ;end-if
)

; define up
(deffunction up (?inlist)
    ;(printout t "moving up ..." crlf)
    (bind ?coord0 (find0 ?inlist))
    (bind ?x0 (nth$ 1 ?coord0))
    (bind ?y0 (nth$ 2 ?coord0))
    (if (< ?x0 4) then
        (bind ?x1 (+ ?x0 1))
        (bind ?tile (findtile ?inlist ?x1 ?y0))
        (bind ?outlist (removetile ?inlist ?x0 ?y0))
        (bind ?outlist (removetile ?outlist ?x1 ?y0))
        (bind ?outlist (create$ ?x0 ?y0 ?tile ?x1 ?y0 0 ?outlist))
        (return ?outlist)
     else
        (return ?inlist)
    ) ;end-if
)

; define down
(deffunction down (?inlist)
    ;(printout t "moving down ..." crlf)
    (bind ?coord0 (find0 ?inlist))
    (bind ?x0 (nth$ 1 ?coord0))
    (bind ?y0 (nth$ 2 ?coord0))
    (if (> ?x0 1) then
        (bind ?x1 (- ?x0 1))
        (bind ?tile (findtile ?inlist ?x1 ?y0))
        (bind ?outlist (removetile ?inlist ?x0 ?y0))
        (bind ?outlist (removetile ?outlist ?x1 ?y0))
        (bind ?outlist (create$ ?x0 ?y0 ?tile ?x1 ?y0 0 ?outlist))
        (return ?outlist)
     else
        (return ?inlist)
    ) ;end-if
)

; define find
(deffunction find (?inlist ?curstep ?maxstep)
    ;(printout t crlf crlf "entering find ..." crlf)
    ;(printout t "inlist = " ?inlist crlf)
    ;(printout t "curstep = " ?curstep crlf)
    ;(printout t "maxstep = " ?maxstep crlf crlf)
    (if (equallist ?inlist ?final) then
        ;(printout t crlf "reached final state ^-^" crlf crlf)
        (return TRUE)
    )
    (if (>= ?curstep ?maxstep) then
        ;(printout t "maximal steps reached, backtracking" crlf crlf)
        (return FALSE)
    )

    ;(printout t "searching normally ..." crlf)
    (bind ?rightlist (right ?inlist))
    ;(printout t "rightlist = " ?rightlist crlf)
    (bind ?seenright (seen ?rightlist))
    ;(printout t "seenright = " ?seenright crlf crlf)

    (bind ?leftlist (left ?inlist))
    ;(printout t "leftlist  = " ?leftlist crlf)
    (bind ?seenleft  (seen ?leftlist))
    ;(printout t "seenleft = " ?seenleft crlf crlf)

    (bind ?uplist (up ?inlist))
    ;(printout t "uplist    = " ?uplist crlf)
    (bind ?seenup    (seen ?uplist))
    ;(printout t "seenup = " ?seenup crlf crlf)

    (bind ?downlist (down ?inlist))
    ;(printout t "downlist  = " ?downlist crlf)
    (bind ?seendown  (seen ?downlist))
    ;(printout t "seendown = " ?seendown crlf crlf)
    ;(printout t "testing searching done ..." crlf crlf crlf)

    (if (and (not (equallist ?rightlist ?inlist)) (not ?seenright)) then
        (bind ?toassert (str-cat "(history " (implode$ ?rightlist) ")"))
        ;(printout t "toassertRight = " ?toassert crlf)
        (assert-string ?toassert)
        (bind ?right_r (find ?rightlist (+ ?curstep 1) ?maxstep))
        ;(printout t "?right_r = " ?right_r ", ?curstep = " ?curstep crlf
crlf)
        (if ?right_r then
            (return TRUE)
        )
    )
    (if (and (not (equallist ?leftlist ?inlist)) (not ?seenleft)) then
        (bind ?toassert (str-cat "(history " (implode$ ?leftlist) ")"))
        ;(printout t "toassertLeft = " ?toassert crlf)
        (assert-string ?toassert)
        (bind ?left_r (find ?leftlist (+ ?curstep 1) ?maxstep))
        ;(printout t "?left_r = " ?left_r ", ?curstep = " ?curstep crlf
crlf)
        (if ?left_r then
            (return TRUE)
        )
    )
    (if (and (not (equallist ?uplist ?inlist)) (not ?seenup)) then
        (bind ?toassert (str-cat "(history " (implode$ ?uplist) ")"))
        ;(printout t "toassertUp = " ?toassert crlf)
        (assert-string ?toassert)
        (bind ?up_r (find ?uplist (+ ?curstep 1) ?maxstep))
        ;(printout t "?up_r = " ?up_r ", ?curstep = " ?curstep crlf crlf)
        (if ?up_r then
            (return TRUE)
        )
    )
    (if (and (not (equallist ?downlist ?inlist)) (not ?seendown)) then
        ;(printout t "asserting downlist" crlf)
        (bind ?toassert (str-cat "(history " (implode$ ?downlist) ")"))
        ;(printout t "toassertDown = " ?toassert crlf)
        (assert-string ?toassert)
        (bind ?down_r (find ?downlist (+ ?curstep 1) ?maxstep))
        ;(printout t "?down_r = " ?down_r ", ?curstep = " ?curstep crlf
crlf)
        (if ?down_r then
            (return TRUE)
        )
    )

    ;(printout t "all search directions tried, returing false" crlf)
    ;(printout t "curstep = " ?curstep crlf crlf crlf)
    (return FALSE)
)

; get cputime
; get cputime
(bind ?tmx (call java.lang.management.ManagementFactory getThreadMXBean))
(deffunction cputime ()
             (return (* (?tmx getCurrentThreadCpuTime) 1E-9))
)

; tests
(bind ?starttime (time))
(bind ?starttime_cpu (cputime))
(printout t "success = " (find ?initial 0 14) crlf)
(bind ?endtime (time))
(bind ?endtime_cpu (cputime))
(printout t "steps = 14, walltime = " (- ?endtime ?starttime) " sec" crlf)
(printout t "steps = 14, cpu time = " (- ?endtime_cpu ?starttime_cpu) " sec"
crlf crlf)

---

Thanks, Senlin


On Fri, May 9, 2008 at 8:24 AM, Wolfgang Laun <[EMAIL PROTECTED]>
wrote:

>
>
> On Thu, May 8, 2008 at 8:30 PM, <[EMAIL PROTECTED]> wrote:
>
>>  It's probably one of those things that
>> would be easier to do procedurally, since brute forcing seems to be
>> relatively straight forward.
>>
>
> Yes, although it might be slow without heuristics, i.e., some good strategy
> according to what you've outlined.
>
>
>>
>> Also, I believe there are number combinations of the 15-puzzle that are
>> not
>> solvable, so keep that in mind.
>>
>
> All the odd permutations cannot be solved. (I used to have a mechanical
> version where you could rearrange the squares...)
>
>
>>
>> I'm not exactly a jess master, so I'll leave that part up to someone else.
>>
>> --
>> Dane Wyrick
>> [EMAIL PROTECTED]
>> 402-544-0872
>>
>>
>>             "Wolfgang Laun"
>>
>>
>> I have never seen a program for this one in any language. Have you, or
>> anybody else?
>> -W
>>
>> On Thu, May 8, 2008 at 2:39 PM, Senlin Liang wrote:
>>  Dear all,
>>
>>  I am trying to solve the puzzle 15 problem using jess, but failed to find
>>  a good solution. Is anyone has a ready program for it?
>>
>>  Thanks,
>>  Senlin
>>
>>
>> .
>>
>>  This message and any attachments contain information from Union Pacific
>> which may be confidential and/or privileged.
>> If you are not the intended recipient, be aware that any disclosure,
>> copying, distribution or use of the contents of this message is strictly
>> prohibited by law. If you receive this message in error, please contact the
>> sender immediately and delete the message and any attachments.
>>
>>
>>
>> --------------------------------------------------------------------
>> To unsubscribe, send the words 'unsubscribe jess-users [EMAIL PROTECTED]'
>> in the BODY of a message to [EMAIL PROTECTED], NOT to the list
>> (use your own address!) List problems? Notify [EMAIL PROTECTED]
>> .
>> --------------------------------------------------------------------
>>
>>
>


--
Senlin Liang

Reply via email to