Strange behavior with findall/3

Hello, I am using SWI version 9.2.2 (on macOS), and have a concern related to findall/3.

According to the documentation:

Sourcefindall(+Template, :Goal, -Bag):
Create a list of the instantiations Template gets successively on backtracking over Goal and unify the result with Bag. Succeeds with an empty list if Goal has no solutions.
findall/3 is equivalent to bagof/3 with all free variables appearing in Goal scoped to the Goalwith an existential (caret) operator (^), except that bagof/3 fails when Goal has no solutions.

Below are highly simplified versions of two versions of an extract from my code, but they do not produce the same answer:

findall(I, between(1, 2, I) -> true, Is).
% Is = [1]
findall(I, between(1, 2, I), Is).
% Is = [1, 2]

Is this intentional? Is it due to the way in which findall/3 is implemented?

Thank you in advance.

Try just the goals, without findall, and you will see the same:

?- between(1, 2, X) -> true.
X = 1.

?- between(1, 2, X).
X = 1 ;
X = 2.

So this is not about findall, maybe it is the if-then ->/2.

The meaning of ->/2 is crucial - why use it here? An alternative: *->/2, purely for comparison:

?- findall(I, between(1, 2, I) *-> true, Is).
Is = [1, 2].

I had accidentally used ->/2 here, and this is what caused me to discover this behavior. The following code has the same behavior as the ->/2 case:

findall(I, (between(1, 2, I), !), Is).

I’m wondering why the cut causes findall/3 to behave like findnsols/4 when cutting behavior proceeds the first valid solution, despite variables in Goal being supposedly bound to each instance of Goal.

I think this makes sense now — the cutting behavior prevents backtracking on I which causes this behavior. Thank you for your answer and apologies for any inconvenience caused.