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