Translating a tabled predicate from b-prolog to gprolog

≯℡__Kan透↙ 提交于 2020-01-05 04:06:33

问题


For fun I've been attempting to write a Knight's Tour (https://en.wikipedia.org/wiki/Knight%27s_tour) solver in gprolog using Warnsdorf's rule.

I found another SO post asking about efficiency that provided a solution in B-prolog: knight's tour efficient solution.

My problem arises with the following section:

:- table warnsdorff(+,+,+,+,+,-,-,min).
warnsdorff(R, C, X, Y, Visits, NewX, NewY, Score) :-
    possible_knight_moves(R, C, X, Y, Visits, NewX, NewY),
    possible_moves_count(R, C, NewX, NewY, [(NewX, NewY) | Visits], Score).

B-prolog features tabled predicates and gprolog does not. I'm having a great deal of difficulty trying to translate the table section to gprolog. In practice, the function is supposed to return the move from the current position that results in the least number of possible moves from the new position (ties are chosen at random).

Any help would be greatly appreciated. Cheers!


回答1:


Probably, tabling is overkill for this problem. Since the Visits lists already is carried on while solving, just use memberchk/2. I get this solution in SWI-Prolog (where, BTW, tabling is implemented, but fails to solve the puzzle using the original coding you linked to):

?- time(knight(8, 8, 1, 1, [], Path))...
% 19,973 inferences, 0.019 CPU in 0.019 seconds (100% CPU, 1047591 Lips)
[(1,1),(2,3),(1,5),(2,7),(4,8),(6,7),(8,8),(7,6),(6,8),(8,7),(7,5),(8,3),(7,1),(5,2),(3,1),(1,2),(2,4),(1,6),(2,8),(3,6),(1,7),(3,8),(5,7),(7,8),(8,6),(7,4),(8,2),(6,1),(4,2),(2,1),(1,3),(3,2),(5,1),(6,3),(8,4),(7,2),(5,3),(4,1),(2,2),(1,4),(3,3),(2,5),(4,4),(6,5),(4,6),(3,4),(5,5),(4,3),(6,2),(8,1),(7,3),(5,4),(3,5),(4,7),(2,6),(1,8),(3,7),(4,5),(6,4),(5,6),(7,7),(5,8),(6,6),(8,5)]

If you want, I can show you the Warnsdorff rule. I've used setof/3, to get the minimum count, joining possible_knight_moves/7 and possible_moves_count/6.

edit

as required:

warnsdorff(R, C, X, Y, Visits, NewX_, NewY_) :-
    setof((Count, NewX, NewY), (
              possible_knight_moves(R, C, X, Y, Visits, NewX, NewY),
              possible_moves_count(R, C, NewX, NewY, [(NewX, NewY) | Visits], Count)
          ), [(_, NewX_, NewY_)|_]).

For clarity, I've renamed the output variables NewX_, NewY_, but that's irrelevant - it worked with the original naming as well.



来源:https://stackoverflow.com/questions/43600928/translating-a-tabled-predicate-from-b-prolog-to-gprolog

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!