Six ways to iterate in Prolog

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.)

1 Like