Your definition of changeFst/4
is incorrect on many counts like changeFst(o,[o,o],n,[m,y,s,t,e,r,y]).
succeeds, but clearly it should fail. The reason is your incorrect usage of cuts. If you want to learn Prolog, stick to the pure declarative subset first. That means no cuts, and no side-effects.
So here is a definition that does not rely on cuts:
changeFst(Old,[Old|Olds],New,[New|Olds]).
changeFst(Old,[E|Olds],New,[E|News]):-
dif(Old, E),
changeFst(Old,Olds,New,News).
One advantage of such a pure relation is that we can use the most general query to see what answers we get:
?- changeFst(Old, Olds, New, News).
Olds = [Old|_A], News = [New|_A]
; Olds = [_A,Old|_B], News = [_A,New|_B], dif(Old,_A)
; Olds = [_A,_B,Old|_C], News = [_A,_B,New|_C],
dif(Old,_A), dif(Old,_B)
; Olds = [_A,_B,_C,Old|_D], News = [_A,_B,_C,New|_D],
dif(Old,_A), dif(Old,_B), dif(Old,_C)
; ... .
Do you note that the answers always contain for Olds
a partial list? Like:
Olds = [Old|_A]
in the first answer. That might be a bit too general, after all it means that even nonlists are now accepted:
?- changeFst(o,[o|nonlist], New, News).
News = [New|nonlist]
; false.
So you might want to ensure that Olds
and News
are always lists.
But my point to show this is rather to you show you that with a pure relation you see many things that a cut-ridden program can never show you that directly.
If we are at it: What to do with the empty list? The current version suggests that changeFst/4
should fail. Not sure what you want here, but in case you want it to succeed, add a fact changeFst(_,[],_,[]).
first.
See this answer for a definition of dif/2
(prolog-dif) should your Prolog not support it.