Предикат length/2, работающий с ограничениями

Вот короткий фрагмент кода, который является примером ситуации, в которой я часто оказываюсь, и который не работает так, как вы ожидаете:

?- 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 мы могли бы придумать, чтобы приведенный выше пример корректно завершился?


person Fatalize    schedule 28.11.2016    source источник
comment
У меня такое чувство, что я однажды задал точно такой же вопрос   -  person    schedule 28.11.2016