Ты слишком много думаешь. В первом случае:
sample(1, [1,2,3])
Пролог может связывать X, потому что 1 равно 1:
sample(1, [1,2,3])
X=1, Tail=[2,3]
Пролог затем проверяет тело предложения:
member(X, Tail) -> member(1, [2,3])
Это, очевидно, неверно, поэтому sample(1, [1,2,3])
не удается.
В следующем случае привязка все еще работает, но Tail привязан к чему-то еще:
sample(1, [1,2,1])
X=1, Tail=[2,1]
Итак, мы проверяем тело:
member(1, [2,1])
что, очевидно, верно, поэтому sample(1, [1,2,1])
успешно.
Теперь, если вы попробуете этот звонок:
sample(1, [2,3,1])
Вы все равно получите false, потому что в этом случае 1 не равно 2, поэтому нет возможности связать X в начале, поэтому тело никогда не проверяется. sample(1, [2,3,1])
имеет значение false, хотя 1 появляется в обоих местах, потому что он также не появился в начале списка.
Я понятия не имею, зачем вам такая функция, но она работает так, как и следовало ожидать. Здесь не происходит перезаписи переменных.