You can read English^some_pred(English, Spanish)
as "there exists an English
such that some_pred(English, Spanish
)`.
If the English^
were missing, then there would be an implicit “there exists” outside the bagof
and you’d generate only a single result. If you try translate_bag(["One", "Two"])
with English^
removed, you’ll see that it backtracks, giving one result at a time:
?- translate_bag(["One", "Two"], Z).
Z = ["Uno"] ;
Z = ["Dos"].
In general, I avoid findall
(based on Richard O’Keefe’s advise), and instead use this idiom (which I did not use in my translate_bag
; I leave the explanation as an “exercise for the reader”):
( bagof(X, some_pred(X), Xs) -> true ; Xs = [] )
because findall
results in []
if some_pred
has no solution but bagof
fails. (The reason for these different behaviors have to do with soundness and Richard O’Keefe explains the details.)