Опубликован: 12.02.2014 | Доступ: свободный | Студентов: 818 / 236 | Длительность: 11:22:00
Специальности: Программист
Лекция 10:

Арифметика и строки

< Лекция 9 || Лекция 10: 12 || Лекция 11 >
Аннотация: Рассматриваются примеры реализации некоторых операций над целыми числами, предикаты класса math и предикаты класса string. Строится изображение троичного острова Коха.

В настоящей главе рассматриваются примеры реализации некоторых операций над целыми числами, предикаты класса math и предикаты класса string. Строится изображение троичного острова Коха.

10.1. Математические операции

Рассмотрим встроенные операции над целыми числами, а также предикаты класса math.

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

class predicates
    gcd: (unsigned64, unsigned64) -> unsigned64.
clauses
    gcd(X, 0) = X:- !.
    gcd(X, Y) = gcd(Y, X mod Y).

    run():-
        X = 194546742,  Y = 387623625,
        Z = gcd(X, Y),
        writef("Наибольший общий делитель % и % = %\n",
            X, Y, Z),
        writef("Наименьшее общее кратное % и % = %\n",
            X, Y, (Y div Z) * X),
        _ = readLine().
Пример 10.1. Наибольший общий делитель. Наименьшее общее кратное

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

Конструкция if-then-else позволяет определить операцию вычисления наибольшего делителя с помощью всего одного правила (см. программу).

class predicates
    simplify: (tuple{integer, integer}) -> tuple{integer, integer}.
    gcd: (integer, integer) -> integer.
    toStr: (integer) -> string.
clauses
    simplify(tuple(X, Y)) = tuple(X div Z, Y div Z):-
        Z = gcd(X, Y).

    gcd(X, Y) = if Y = 0 then X else gcd(Y, X mod Y) end if.

    toStr(X) = toString(X):-
        X >= 0,
        !.
    toStr(X) = string::format("(%)", X).

    run():-
        X = 386,  Y = -514,
        tuple(A, B) = simplify(tuple(X, Y)),
        writef("% / % = % / %", X, toStr(Y), A, toStr(B)),
        _ = readLine().
Пример 10.2. Сокращение дробей

Предикат toString переводит элемент любого домена в элемент домена string. Предикат format форматирует строку.

В приведенной ниже программе строится снежинка Коха (рис. 10.1). Отрезок в консоли изображается в виде последовательности точек. Перед печатанием каждой точки делается небольшая пауза. Цвет точек генерируется случайным образом.

 Снежинка Коха: (a) 0; (b) 3 итерации

увеличить изображение
Рис. 10.1. Снежинка Коха: (a) 0; (b) 3 итерации
     open core, console, console_native, math

class facts
    w : integer := getConsoleWidth() - 1.

class predicates
    fractal: (positive, real, real, real, real, real [out], real [out]).
    line: (integer, integer, integer, integer).
    printPoint: (integer, integer).
    f: (real) -> integer.
clauses
    f(X) = restrict(round(X), 0, w).

    printPoint(X, Y):-
        programControl::sleep(10),
        setLocation(coord(X + 0, Y + 0)),
        setTextAttribute(math::random(7) + 9),
        write(".").

    line(X1, Y, X2, Y):- !,
        foreach X = std::between(X1, X2) do printPoint(X, Y)
        end foreach.
    line(X1, Y1, X2, Y2):-
        foreach Y = std::between(Y1, Y2) do
            printPoint(round(X1 + (Y - Y1) * (X2 - X1)/(Y2 - Y1)), Y)
        end foreach.

    fractal(0, X, Y, L, A, X1, Y1):-  !,
        X1 = X + L * cos(A),
        Y1 = Y + L * sin(A),
        line(f(2 * X), f(Y), f(2 * X1), f(Y1)).
    fractal(I, X, Y, L, A, X4, Y4):-
        I1 = I - 1,
        L1 = L / 3,
        fractal(I1, X, Y, L1, A, X1, Y1),
        fractal(I1, X1, Y1, L1, A - pi/3, X2, Y2),
        fractal(I1, X2, Y2, L1, A + pi/3, X3, Y3),
        fractal(I1, X3, Y3, L1, A, X4, Y4).

    run():-
        N = 3,
        L = 36,
        fractal(N, 2, 11, L, 0, X1, Y1),
        fractal(N, X1, Y1, L, 2 * pi/3, X2, Y2),
        fractal(N, X2, Y2, L, 4 * pi/3, _, _),
        _ = readLine().
Пример 10.3. Снежинка Коха

Предикат round округляет число до ближайшего целого. Предикат restrict возвращает число из указанного промежутка, ближайшее к заданному числу. Предикат between недетерминированно возвращает целые числа в указанных пределах. Предикаты cos и sin вычисляют соответственно косинус и синус заданного действительного аргумента.

Программа выполняет три итерации. На нулевой итерации рисуется равносторонний треугольник (см. рис. 10.1 (a)). Количество итераций указывается в определении предиката run (N = 3). На последующих итерациях каждый отрезок преобразуется по правилу \to (см. рис. 10.1 (b)).

< Лекция 9 || Лекция 10: 12 || Лекция 11 >
Жаныл Айкын
Жаныл Айкын
Rustam Inatov
Rustam Inatov

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

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

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