Thank you for the bug report. It was in a bagof/3 when used in place of a findall/3 (it is the case in your code). Fixed in the git.
Workaround: replace setoff by findall in your program. This gives:
actionBagof(CONF, ALL_CONF) :- findall(RES, action(CONF, RES), ALL_CONF).
Daniel
%************************************ DATA piece(0, [(4, -1), (0, 0), (1, 0), (2, 0), (3, 0), (5, 0), (6, 0), (7, 0), (8,0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (8, 1), (8, 2), (8, 3), (8, 4), (8, 5), (8, 6), (8, 7), (8, 8), (1, 8), (2, 8), (3, 8), (4, 8), (5, 8), (6, 8), (7, 8), (1, 1), (7, 1), (1, 7), (7, 7)]). %the container box piece(1, [(0, 0), (1, 0), (2, 0), (0, 1), (2, 1)]). piece(2, [(0, 0), (0, 1), (0, 2)]). piece(3, [(0, 0), (1, 0), (2, 0)]). piece(4, [(0, 0), (1, 0), (1, 1), (0, 2), (1, 2)]). piece(5, [(0, 0), (1, 0), (0, 1)]). piece(6, [(0, 0), (1, 0), (2, 0)]). piece(7, [(0, 0), (0, 1), (0, 2)]). piece(8, [(1, 0), (1, 1), (1, 2), (0, 2)]). piece(9, [(0, 0), (1, 0)]). piece(10, [(0, 0), (0, 1)]). piece(11, [(0, 0)]). %the diamond confInit([(0,0,0),(1,4,1),(2,2,1),(3,5,3),(4,6,4),(5,4,4),(6,1,6),(7,3,1),(8,4,5),(9,2,7),(10,2,4),(11,3,4)]). solution(11, 4, 1). %*********************************** PROGRAM move(up, 0, -1). move(right, 1, 0). move(down, 0, 1). move(left, -1, 0).
calcPos([], _, []). calcPos([(PX1, PY1)|L], (ATx, ATy), [(PX_RES, PY_RES)|L_RES]) :- PX_RES is PX1 + ATx, PY_RES is PY1 + ATy, calcPos(L, (ATx, ATy), L_RES).
isAnyCommon(L1, L2) :- member(X, L1), member(X, L2), !.
isOverlapsSub((P1, X1, Y1), (P2, X2, Y2)) :- piece(P1, LP1), piece(P2, LP2), calcPos(LP1, (X1, Y1), LP1prime), calcPos(LP2, (X2, Y2), LP2prime), isAnyCommon(LP1prime, LP2prime).
isOverlaps(P1info, CONF) :- select(P2info, CONF, _), isOverlapsSub(P1info, P2info), !.
action((LM, CONF), ([(P, M)|LM], [Pprime|CONF_RES])) :- select((P, Px, Py), CONF, CONF_RES), P =\= 0, %0 is the container (static) move(M, INCx, INCy), Px_prime is Px + INCx, Py_prime is Py + INCy, Pprime = (P, Px_prime, Py_prime), \+ isOverlaps(Pprime, CONF_RES).
actionBagof(CONF, ALL_CONF) :- bagof(RES, action(CONF, RES), ALL_CONF).
histoPurge([], []). histoPurge([(M, CONF1)|LCONF], [(M, CONF1prime)|LCONFres]) :- sort(CONF1, CONF1prime), \+ histo(CONF1prime), !, asserta(histo(CONF1prime)), histoPurge(LCONF, LCONFres). histoPurge([_|LCONF], LCONFres) :- histoPurge(LCONF, LCONFres).
soluceSub([], []). soluceSub([X|LCONF], RES) :- actionBagof(X, LCONFprime), histoPurge(LCONFprime, LCONFsecond), append(LCONFsecond, INTER, RES), soluceSub(LCONF, INTER).
soluceFound([], _) :- !, fail. soluceFound([(RES, Lconf)|_], (RES, Lconf)) :- solution(Psol, Px, Py), member((Psol, Px, Py), Lconf), !. soluceFound([_|L], RES) :- soluceFound(L, RES).
soluce(INIT, RES) :- asserta(tree(INIT)), repeat, retract(tree(LCONF)), soluceSub(LCONF, LRES), asserta(tree(LRES)), retract(rec(REC)), RECprime is REC + 1, length(LRES, LEN), asserta(rec(RECprime)), print(RECprime + LEN),nl, ((LRES = [], !, fail) ; soluceFound(LRES, RES)).
%(0,0,0) always : it's the container of the pieces. main :- confInit(CONF), INIT = ([], CONF), asserta(tree(x)), retractall(tree(_)), asserta(histo(x)), retractall(histo(_)), asserta(rec(0)), retractall(rec(_)), asserta(rec(0)),!, soluce([INIT], RES), print(RES).
--
Ce message a été vérifié par
MailScanner
pour des virus ou des polluriels et rien de
suspect n'a été trouvé.
|