append_green([],[],X,X,5):-
write('Final Green: '),
writeln(X).
append_green([CorrectHead|CorrectTail], [GuessHead|GuessTail], Grn, _FinalGreen, N):-
N < 5,
( CorrectHead = GuessHead
-> replace(Grn,N,GuessHead,FinalGrn),
N1 is N 1,
append_green(CorrectTail, GuessTail, FinalGrn, FinalGrn, N1)
; N1 is N 1,
append_green(CorrectTail, GuessTail, Grn, Grn, N1) ).
replace([_|T], 0, X, [X|T]).
replace([H|T], I, X, [H|R]):-
I > 0,
I1 is I-1,
replace(T, I1, X, R).
Hi, I'm trying to write a wordle solver using SWI prolog but I'm running into a few issues that I can't figure out. The code above is for a predicate that is supposed to update the list of green characters given the correct word and a guess.
The first parameter is the correct word that the program is attempting to guess in the format of a list, i.e. ['w','o','r','d','s'].
The second parameter is the "guess" in the same format. Grn is the existing list of green characters in the format ['.', '.', '.', '.', '.'] where the periods are placeholders for empty spots.
When called, the predicate is supposed to find the updated Green list, but instead just prints 'true' in console. The strange part is that the print statement in the base case displays the correct list.
Included below is what shows up when I trace it in SWI-prolog:
[trace] ?- append_green([w,h,i,c,h],[h,i,t,c,h],[.,.,.,.,.],X,0).
Call: (10) append_green([w, h, i, c, h], [h, i, t, c, h], ['.', '.', '.', '.', '.'], _25506, 0) ? creep
Call: (11) 0<5 ? creep
Exit: (11) 0<5 ? creep
Call: (11) w=h ? creep
Fail: (11) w=h ? creep
Redo: (10) append_green([w, h, i, c, h], [h, i, t, c, h], ['.', '.', '.', '.', '.'], _25506, 0) ? creep
Call: (11) _30726 is 0 1 ? creep
Exit: (11) 1 is 0 1 ? creep
Call: (11) append_green([h, i, c, h], [i, t, c, h], ['.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.'], 1) ? creep
Call: (12) 1<5 ? creep
Exit: (12) 1<5 ? creep
Call: (12) h=i ? creep
Fail: (12) h=i ? creep
Redo: (11) append_green([h, i, c, h], [i, t, c, h], ['.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.'], 1) ? creep
Call: (12) _36790 is 1 1 ? creep
Exit: (12) 2 is 1 1 ? creep
Call: (12) append_green([i, c, h], [t, c, h], ['.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.'], 2) ? creep
Call: (13) 2<5 ? creep
Exit: (13) 2<5 ? creep
Call: (13) i=t ? creep
Fail: (13) i=t ? creep
Redo: (12) append_green([i, c, h], [t, c, h], ['.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.'], 2) ? creep
Call: (13) _42854 is 2 1 ? creep
Exit: (13) 3 is 2 1 ? creep
Call: (13) append_green([c, h], [c, h], ['.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.'], 3) ? creep
Call: (14) 3<5 ? creep
Exit: (14) 3<5 ? creep
Call: (14) c=c ? creep
Exit: (14) c=c ? creep
Call: (14) replace(['.', '.', '.', '.', '.'], 3, c, _48146) ? creep
Call: (15) 3>0 ? creep
Exit: (15) 3>0 ? creep
Call: (15) _50430 is 3 -1 ? creep
Exit: (15) 2 is 3 -1 ? creep
Call: (15) replace(['.', '.', '.', '.'], 2, c, _48914) ? creep
Call: (16) 2>0 ? creep
Exit: (16) 2>0 ? creep
Call: (16) _54222 is 2 -1 ? creep
Exit: (16) 1 is 2 -1 ? creep
Call: (16) replace(['.', '.', '.'], 1, c, _52706) ? creep
Call: (17) 1>0 ? creep
Exit: (17) 1>0 ? creep
Call: (17) _58014 is 1 -1 ? creep
Exit: (17) 0 is 1 -1 ? creep
Call: (17) replace(['.', '.'], 0, c, _56498) ? creep
Exit: (17) replace(['.', '.'], 0, c, [c, '.']) ? creep
Exit: (16) replace(['.', '.', '.'], 1, c, ['.', c, '.']) ? creep
Exit: (15) replace(['.', '.', '.', '.'], 2, c, ['.', '.', c, '.']) ? creep
Exit: (14) replace(['.', '.', '.', '.', '.'], 3, c, ['.', '.', '.', c, '.']) ? creep
Call: (14) _63346 is 3 1 ? creep
Exit: (14) 4 is 3 1 ? creep
Call: (14) append_green([h], [h], ['.', '.', '.', c, '.'], ['.', '.', '.', c, '.'], 4) ? creep
Call: (15) 4<5 ? creep
Exit: (15) 4<5 ? creep
Call: (15) h=h ? creep
Exit: (15) h=h ? creep
Call: (15) replace(['.', '.', '.', c, '.'], 4, h, _4622) ? creep
Call: (16) 4>0 ? creep
Exit: (16) 4>0 ? creep
Call: (16) _6906 is 4 -1 ? creep
Exit: (16) 3 is 4 -1 ? creep
Call: (16) replace(['.', '.', c, '.'], 3, h, _5390) ? creep
Call: (17) 3>0 ? creep
Exit: (17) 3>0 ? creep
Call: (17) _10698 is 3 -1 ? creep
Call: (17) replace(['.', c, '.'], 2, h, _9182) ? creep
Call: (18) 2>0 ? creep
Exit: (18) 2>0 ? creep
Call: (18) _14490 is 2 -1 ? creep
Exit: (18) 1 is 2 -1 ? creep
Call: (18) replace([c, '.'], 1, h, _12974) ? creep
Call: (19) 1>0 ? creep
Exit: (19) 1>0 ? creep
Call: (19) _18282 is 1 -1 ? creep
Exit: (19) 0 is 1 -1 ? creep
Call: (19) replace(['.'], 0, h, _16766) ? creep
Exit: (19) replace(['.'], 0, h, [h]) ? creep
Exit: (18) replace([c, '.'], 1, h, [c, h]) ? creep
Exit: (17) replace(['.', c, '.'], 2, h, ['.', c, h]) ? creep
Exit: (16) replace(['.', '.', c, '.'], 3, h, ['.', '.', c, h]) ? creep
Exit: (15) replace(['.', '.', '.', c, '.'], 4, h, ['.', '.', '.', c, h]) ? creep
Call: (15) _24376 is 4 1 ? creep
Exit: (15) 5 is 4 1 ? creep
Call: (15) append_green([], [], ['.', '.', '.', c, h], ['.', '.', '.', c, h], 5) ? creep
Call: (16) write('Final Green: ') ? creep
Final Green:
Exit: (16) write('Final Green: ') ? creep
Call: (16) writeln(['.', '.', '.', c, h]) ? creep
[.,.,.,c,h]
Exit: (15) append_green([], [], ['.', '.', '.', c, h], ['.', '.', '.', c, h], 5) ? creep
Exit: (14) append_green([h], [h], ['.', '.', '.', c, '.'], ['.', '.', '.', c, '.'], 4) ? creep
Exit: (13) append_green([c, h], [c, h], ['.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.'], 3) ? creep
Exit: (12) append_green([i, c, h], [t, c, h], ['.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.'], 2) ? creep
Exit: (11) append_green([h, i, c, h], [i, t, c, h], ['.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.'], 1) ? creep
Exit: (10) append_green([w, h, i, c, h], [h, i, t, c, h], ['.', '.', '.', '.', '.'], _18, 0) ? creep
true
Could anyone help me figure out what is wrong with the recursion that would cause it to do this? Thank you!
CodePudding user response:
Although this is not the main cause of the error in your code, it is worth noting that there is no need to use the predicate replace/4
to solve the problem:
% update_green( Correct, Guess, gReen, -Updated)
updated_green([], [], R, R).
updated_green([C|Cs], [G|Gs], [R|Rs], [U|Us]):-
( C = G
-> U = G
; U = R ),
updated_green(Cs, Gs, Rs, Us).
Example:
?- updated_green([w,h,i,c,h], [h,i,t,c,h], [.,.,.,.,.], UpdatedGreen).
UpdatedGreen = ['.', '.', '.', c, h].
Alternatively, you can define a predicate to update only one element of the list:
updated_element(C, G, R, U) :-
( C = G
-> U = G
; U = R ).
And then use this predicate (with maplist/4) to map elements from the input lists to the desired output list.
?- maplist(updated_element, [w,h,i,c,h], [h,i,t,c,h], [.,.,.,.,.], UpdatedGreen).
UpdatedGreen = ['.', '.', '.', c, h].