В настоящей главе рассматриваются примеры реализации некоторых операций над целыми числами, предикаты класса math и предикаты класса string. Строится изображение троичного острова Коха.
Рассмотрим встроенные операции над целыми числами, а также предикаты класса 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().
Следующая программа посвящена сокращению дробей. Если знаменатель исходной дроби является отрицательным числом, а числитель положительным, то после сокращения отрицательным становится числитель. Если знаменатель исходной дроби равен нулю, то и после сокращения он равен нулю.
Конструкция 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().
Предикат toString переводит элемент любого домена в элемент домена string. Предикат format форматирует строку.
В приведенной ниже программе строится снежинка Коха (рис. 10.1). Отрезок в консоли изображается в виде последовательности точек. Перед печатанием каждой точки делается небольшая пауза. Цвет точек генерируется случайным образом.
(рис 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().
Предикат round округляет число до ближайшего целого. Предикат restrict возвращает число из указанного промежутка, ближайшее к заданному числу. Предикат between недетерминированно возвращает целые числа в указанных пределах. Предикаты cos и sin вычисляют соответственно косинус и синус заданного действительного аргумента.
Программа выполняет три итерации. На нулевой итерации рисуется равносторонний треугольник (см. рис 10.1 (см. рис. 10.1 (b)).
В языке Visual Prolog имеется класс string, в котором реализовано большое количество предикатов обработки строк.
Следующая программа посвящена поиску токенов наибольшей длины в строке. Длиной строки (string) называется количество символов. Строка разбивается на токены. Находится токен наибольшей длины. В результате следующего преобразования в списке остаются только токены, длина которых совпадает с длиной токена наибольшей длины (используется предикат list::filter/2).
Предикат string::frontToken отделяет первый токен от строки. Предикат toTokens разбивает строку на список токенов. Предикат string::length возвращает длину строки.
open core, console, string
class predicates
toTokens: (string) -> string*.
maxTokens: (string, string* [out], charCount [out]).
clauses
toTokens(Str) = [Tok | toTokens(RestStr)]:-
frontToken(Str, Tok, RestStr),
!.
toTokens(_) = [].
maxTokens(Str, MaxTokList, MaxLen):-
TokList = toTokens(Str),
TokLenList = list::map(TokList, {(Tok) = length(Tok)}),
MaxLen = list::maximum(TokLenList),
MaxTokList = list::filter(TokList, {(S):- length(S) = MaxLen}).
run():-
Str = "И редкий солнца луч, и первые морозы",
maxTokens(Str, MaxTokList, Length),
write(MaxTokList, "\n", Length),
_ = readLine().
В следующей программе текст разбивается на предложения. Знаки препинания ".", "!" и "?" используются в тексте только как знаки конца предложения. Предложение может заканчиваться последовательностью знаков, например, многоточием.
open core, console, string
class predicates
toSentences: (string) -> string*.
getSentence: (string, string, string Sent [out], string [out]).
clauses
toSentences(Str) = [Sentence | toSentences(RestStr)]:-
splitStringBySeparators(Str, ".?!", FirstStr, Sign, Str1),
FirstStr1 = trim(FirstStr),
FirstStr1 <> "",
!,
getSentence(Str1, concat(FirstStr1, charToString(Sign)),
Sentence, RestStr).
toSentences(_) = [].
getSentence(Str, Sent, Sentence, Rest):-
splitStringBySeparators(Str, ".?!", FirstStr, Sign, RestStr),
"" = trim(FirstStr),
!,
getSentence(RestStr, concat(Sent, charToString(Sign)),
Sentence, Rest).
getSentence(Str, Sent, Sent, Str).
run():-
Str = "Зима!.. Крестьянин, торжествуя, "
"На дровнях обновляет путь...",
L = toSentences(Str),
list::forAll(L, {(Sent):- write(Sent), nl}),
_ = readLine().
Предикат splitStringBySeparators находит префикс строки до какого-либо разделителя из символов ".?!", встретившегося в строке первым. Кроме этого, он возвращает сам разделитель, а также остаток строки. Предикат concat выполняет операцию конкатенации строк.
В настоящей главе рассматриваются примеры реализации некоторых операций над целыми числами, предикаты класса math и предикаты класса string. Строится изображение троичного острова Коха.
Рассмотрим встроенные операции над целыми числами, а также предикаты класса 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().
Следующая программа посвящена сокращению дробей. Если знаменатель исходной дроби является отрицательным числом, а числитель положительным, то после сокращения отрицательным становится числитель. Если знаменатель исходной дроби равен нулю, то и после сокращения он равен нулю.
Конструкция 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().
Предикат toString переводит элемент любого домена в элемент домена string. Предикат format форматирует строку.
В приведенной ниже программе строится снежинка Коха (рис. 10.1). Отрезок в консоли изображается в виде последовательности точек. Перед печатанием каждой точки делается небольшая пауза. Цвет точек генерируется случайным образом.
(рис 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().
Предикат round округляет число до ближайшего целого. Предикат restrict возвращает число из указанного промежутка, ближайшее к заданному числу. Предикат between недетерминированно возвращает целые числа в указанных пределах. Предикаты cos и sin вычисляют соответственно косинус и синус заданного действительного аргумента.
Программа выполняет три итерации. На нулевой итерации рисуется равносторонний треугольник (см. рис 10.1 (см. рис. 10.1 (b)).
В языке Visual Prolog имеется класс string, в котором реализовано большое количество предикатов обработки строк.
Следующая программа посвящена поиску токенов наибольшей длины в строке. Длиной строки (string) называется количество символов. Строка разбивается на токены. Находится токен наибольшей длины. В результате следующего преобразования в списке остаются только токены, длина которых совпадает с длиной токена наибольшей длины (используется предикат list::filter/2).
Предикат string::frontToken отделяет первый токен от строки. Предикат toTokens разбивает строку на список токенов. Предикат string::length возвращает длину строки.
open core, console, string
class predicates
toTokens: (string) -> string*.
maxTokens: (string, string* [out], charCount [out]).
clauses
toTokens(Str) = [Tok | toTokens(RestStr)]:-
frontToken(Str, Tok, RestStr),
!.
toTokens(_) = [].
maxTokens(Str, MaxTokList, MaxLen):-
TokList = toTokens(Str),
TokLenList = list::map(TokList, {(Tok) = length(Tok)}),
MaxLen = list::maximum(TokLenList),
MaxTokList = list::filter(TokList, {(S):- length(S) = MaxLen}).
run():-
Str = "И редкий солнца луч, и первые морозы",
maxTokens(Str, MaxTokList, Length),
write(MaxTokList, "\n", Length),
_ = readLine().
В следующей программе текст разбивается на предложения. Знаки препинания ".", "!" и "?" используются в тексте только как знаки конца предложения. Предложение может заканчиваться последовательностью знаков, например, многоточием.
open core, console, string
class predicates
toSentences: (string) -> string*.
getSentence: (string, string, string Sent [out], string [out]).
clauses
toSentences(Str) = [Sentence | toSentences(RestStr)]:-
splitStringBySeparators(Str, ".?!", FirstStr, Sign, Str1),
FirstStr1 = trim(FirstStr),
FirstStr1 <> "",
!,
getSentence(Str1, concat(FirstStr1, charToString(Sign)),
Sentence, RestStr).
toSentences(_) = [].
getSentence(Str, Sent, Sentence, Rest):-
splitStringBySeparators(Str, ".?!", FirstStr, Sign, RestStr),
"" = trim(FirstStr),
!,
getSentence(RestStr, concat(Sent, charToString(Sign)),
Sentence, Rest).
getSentence(Str, Sent, Sent, Str).
run():-
Str = "Зима!.. Крестьянин, торжествуя, "
"На дровнях обновляет путь...",
L = toSentences(Str),
list::forAll(L, {(Sent):- write(Sent), nl}),
_ = readLine().
Предикат splitStringBySeparators находит префикс строки до какого-либо разделителя из символов ".?!", встретившегося в строке первым. Кроме этого, он возвращает сам разделитель, а также остаток строки. Предикат concat выполняет операцию конкатенации строк.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.