Вот короткий фрагмент кода, который является примером ситуации, в которой я часто оказываюсь, и который не работает так, как вы ожидаете:
?- L in 1..3, length(Ls, L). L = 1, Ls = [_G2634] ; L = 2, Ls = [_G2634, _G2637] ; L = 3, Ls = [_G2634, _G2637, _G2640] ; <infinite loop>
Мы можем очень легко увидеть, что length/2
плохо сочетается с ограничениями. Когда можно было бы ожидать, что length/2
проверит, что его второй аргумент находится в правильном домене, прежде чем пытаться создать экземпляр списка, кажется, что он делает обратное и проверяет, что его второй аргумент соблюдает ограничение после попытки создать экземпляр списка.
Как обычно решается эта проблема? Какую реализацию, скажем, clength/2
мы могли бы придумать, чтобы приведенный выше пример корректно завершился?