Опубликован: 12.02.2014 | Уровень: для всех | Доступ: платный
Лекция 5:

Рекурсия

< Лекция 4 || Лекция 5: 1234 || Лекция 6 >

5.2. Функции

В языке Visual Prolog наряду с предикатным стилем можно использовать функции и функциональный стиль программирования. Функции объявляются следующим образом:

class predicates
    имя_функции: (домен1, домен2, …) -> домен_значений.

Например:

class predicates
    f: (real, real) -> real.
clauses
    f(X, Y) = X + Y.

После знака -> стоит имя домена, которому принадлежит значение функции. В правиле это значение определяется после знака равенства. Аргументы функции могут быть как входными, так и выходными. Функция может иметь любой режим детерминизма.

Аналогичное определение функции f из приведенного выше примера в предикатном стиле имеет вид:

class predicates
    f: (real, real, real [out]).
clauses
    f(X, Y, X + Y).

Предикатный домен — это домен, элементами которого являются предикаты. Имена этих предикатов могут быть аргументами предикатов высшего порядка. В объявлении предикатных доменов указываются типы предикатов вместе с режимами детерминизма и потоками параметров. Предикатный домен функций объявляется и используется, например, следующим образом:

domains
    fun = (real, real) -> real.

class predicates
    f : fun.
    g : fun.
clauses
    f(X, Y) = X + Y.
    g(X, Y) = X * Y.

    run():-
        (F = f; F = g),
            R = F(2, 3),
            write(R), nl,
        fail;
        _ = readLine().

В следующих двух программах генерируются натуральные числа в порядке убывания, от заданного числа n до единицы включительно. Например, цель

number(3, X)

имеет следующий набор решений:

X = 3
X = 2
X = 1

Используется сначала предикатный стиль, а затем, для сравнения, функциональный.

class predicates
    number: (positive Граница, positive Число) multi (i,o).
clauses
    number(X, X).
    number(N, X):-
        N > 1,
        number(N - 1, X).

    run():-
        number(3, X),
            write(X), nl,
        fail;
        _ = readLine().
Пример 5.2. "Числа". Предикатный стиль
class predicates
    number: (positive) -> positive multi.
clauses
    number(N) = N.
    number(N) = number(N - 1):-
        N > 1.

    run():-
        write(number(3)), nl,
        fail;
        _ = readLine().
Пример 5.3. "Числа". Функциональный стиль

Упражнение 2. Напишите генератор натуральных чисел по возрастанию от 1 до заданного числа N.

В следующей программе факториал целых неотрицательных чисел определяется в виде функции, с помощью хвостовой рекурсии.

class predicates
    fact: (positive) -> unsigned64.
    fact: (positive, unsigned64) -> unsigned64.
clauses
    fact(N) = fact(N, 1).

    fact(0, X) = X:- !.
    fact(N, X) = fact(N - 1, N * X).

    run():-
        write(fact(5)),
        _ = readLine().
Пример 5.4. "Факториал"

Используем функции для вычисления чисел Фибоначчи. Последовательность Фибоначчи — это последовательность натуральных чисел, которая определяется следующим образом:

f(1) = f(2) = 1,  f(n) = f(n – 1) + f(n – 2) для n > 2.

Это определение можно буквально перенести в программу:

class predicates 
    f: (positive) -> unsigned64.
clauses
    f(N) = 1:- N < 3, !.
    f(N) = f(N - 1) + f(N - 2).

Но эта программа уже при n = 40 требует для поиска решения нескольких секунд. Поэтому используем для вычисления n-го числа Фибоначчи хвостовую рекурсию. Для этого будем хранить на каждом шаге рекурсии два соседних элемента последовательности.

class predicates
    fib: (positive) -> unsigned64.
    fib: (positive, unsigned64, unsigned64) -> unsigned64.
clauses
    fib(0) = 0:- !.
    fib(N) = fib(N, 0, 1).

    fib(1, _, Y) = Y:- !.
    fib(N, X, Y) = fib(N - 1, Y, X + Y).

    run():-
        write(fib(70)),
        _ = readLine().
Пример 5.5. "Числа Фибоначчи"

Упражнение 2. Напишите программу, которая по заданному натуральному числу определяет номер наибольшего элемента последовательности Фибоначчи, не превосходящего этого числа.

< Лекция 4 || Лекция 5: 1234 || Лекция 6 >
Жаныл Айкын
Жаныл Айкын
Rustam Inatov
Rustam Inatov

Доброго времени суток, подскажите пожалуйста, visual prolog examples, pie, vip7.5 - это все, где я могу скачать? (в смысле) может быть на сайте есть какой-то архив? Увы я не нашел его.

Подскажите, пожалуйста.

С уважением, Рустам.

Айдана Ахметова
Айдана Ахметова
Россия
Дмитрий Куянов
Дмитрий Куянов
Россия, Омск, ОмГТУ