Я новичок в Прологе с опытом программирования. Решая задания с этого сайта , я наткнулся на два упражнения: первое касается нахождения k-го элемента списка , второе - нахождения списка длина . Это классические задачи обработки списков с довольно простым решением, в том числе и для такого начинающего, как я. То, что я не смог понять, было (очевидно) другое использование встроенного предиката is/2
. Насколько мне известно, этот предикат заставляет Пролога выполнять арифметическое вычисление и, возможно, присваивать результат левому члену. Мне сказали, что нужно знать, что, , хотя можно использовать переменные в правой части, они должны быть созданы с использованием термина без переменных в момент оценки .
Для первого упражнения предлагаемое решение следующее:
element_at(X,[X|_],1).
element_at(X,[_|L],K) :- K > 1, K1 is K - 1, element_at(X,L,K1).
и способ использования is
имеет смысл для меня: поскольку K
предоставляется в качестве аргумента, K1
может быть немедленно оценен и предоставлен как новый аргумент в рекурсивном вызове.
Путем написания Решением второго упражнения, а именно поиска длины списка, я придумал следующее:
my_length([], 0).
my_length([_|L], K) :- K is K1 + 1, my_length(L, K1).
и Prolog был уведомлен о том, что «аргументы недостаточно проработаны» .
Правильное решение оказалось таким:
my_length([], 0).
my_length([_|L], K) :- my_length(L, K1), K is K1 + 1.
В этом случае рекурсивный вызов выполняется перед , оценивая K с помощью is
. В предыдущем упражнении это было сделано после оценки K is K-1
.
Я думаю, что я неправильно понял некоторые ключевые понятия. В каких случаях is/2
должен использоваться до рекурсивного вызова и, с другой стороны, когда он должен использоваться после? Почему это так?
Любая помощь и объяснения приветствуются (я использую SWI-Prolog 7.6.4).