Решение простое: impure(Ls) :- length(Ls, L), write(L).
.
Однако это очень плохая идея по нескольким причинам.
Очень важным является то, что вещи, которые появляются только на вашем экране, не могут быть рассмотрены в Prolog!
Таким образом, если вы просто записываете некоторые результаты с помощью write/1
, вы не можете запускать автоматические тестовые примеры, чтобы увидеть, действительно ли ваш предикат ведет себя так, как ожидалось. По крайней мере, таким образом написание тестов становится намного сложнее.
Напротив, с исходной, более чистой версией кода (в которой не использовались побочные эффекты) вы можете легко протестировать, например:
?- length([a,b,c], 3).
true.
а также запустить несколько таких тестовых случаев автоматически и использовать Prolog, чтобы увидеть, успешны ли они. Например, пакет из 10 000 тестов может выглядеть так (поиск контрпримеров):
?- between(1, 10_000, L), length(Ls, L), length([_|Ls], L1), L1 =\= L+1.
false.
Напротив, как проверить нечистый предикат?
?- between(1, 10_000, L), length(Ls, L), impure([_|Ls]) what now??
Как видите, действительно трудно рассуждать о выводе предиката!
Кроме того, это делает ваш предикат намного менее общим, чем ваша текущая версия! Вы больше не можете использовать нечистую версию в других направлениях. Например, как теперь сгенерировать список заданной длины? Нет возможности поставить длину!
Оставайтесь чистыми людьми и используйте верхний уровень Пролога для получения ответов вместо того, чтобы писать их на экране!
person
mat
schedule
25.11.2015
length/1
гораздо менее полезен, чем предикатlength/2
. Обычно вы бы сделали,length([1,2,3], N), write(N), nl.
Вы могли бы легко превратить это в предикатlength/1
, если хотите. Немного смущают принципы, которым они, кажется, учат на курсах по Прологу. Кажется, что они преподают Пролог как тупой и ограниченный императивный язык, а не как простой, но мощный реляционный язык, которым он является. - person lurker   schedule 25.11.2015