Материал: Волченков Логическое программирование язык пролог 2015

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Ответ:

W = 'zy#$#%$%%^&877665534456578hyt'

vv(W):-get0(X), vv1([X],L,X), name(W, L), vv2(L), nl.

vv1(L, L, 122). % 122 – код символа z vv1(B, L, X):- get0(Y), vv1([Y|B], L, Y).

vv2([]) :- !.

vv2([C|T]) :- put(C), vv2(T).

| ?- vv(W).

|: abcdefgh12345!@#$%yz zy%$#@!54321hgfedcba

W = 'zy%$#@!54321hgfedcba'

Встроенные предикаты управления. Методы реализации циклов

Задача 3. В базу данных Пролога загружены факты о преподавателях кафедры «Кибернетика» НИЯУ МИФИ со спецификацией prep/10. Напечатать все эти факты «в столбик». (Использовать возвратный метод организации цикла.)

Решение:

печать_факта(F, N) :- functor(S, F, N), печать_факта(S).

печать_факта(S) :- call(S), write(S), nl, fail.

печать_факта(_).

Задача 4. В базу данных Пролога загружены факты о преподавателях кафедры «Кибернетика» НИЯУ МИФИ со спецификацией prep/10. Факты отсортированы по возрастанию ФИО (2-й аргумент). Напечатать «в столбик» факты, у которых значение ФИО =< ’Щукин Б.А.’. (Использовать метод CAF организации цикла.)

Решение:

печать_факта(F, N) :- functor(S, F, N), печать_факта(S).

печать_факта(S) :- call(S), write(S), nl, arg(2, S, ’Щукин Б.А.’), !.

61

Задача 5. Печатать «в столбик» целые случайные числа от 0 до 99 до тех пор, пока не появится число, превышающее 90. (Использовать метод UDR организации цикла.)

Решение:

печать_случайного_числа :- repeat, rrr(X), X>90. rrr(X) :- X is int(rand(100)), !.

Предикаты преобразования структур

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

Предикат name/2

Отметим, что в поздних версиях Пролога, в частности, в LPA WIN-PROLOG 4.200 атомы можно строить из строчной «кирилли-

цы»:

| ?- name(еёжз, X).

X = [1077,1105,1078,1079]

| ?- name(X, [1077,1105,1078,1079]).

X = еёжз

Задача 6.

Замените в 1-м вызове 2-й аргумент на _еёжз. Что ответит Про- лог-система?

Замените во 2-м вызове 1-й аргумент на _еёжз, а 2-й аргумент на

[95,1077,1105,1078,1079]. Что ответит Пролог-система?

Что Пролог-система ответит на вызов: ?- name('_еёжз', _еёжз).

Ответ:

| ?- name('_еёжз', _еёжз).

_еёжз = [95,1077,1105,1078,1079]

Предикат functor/3

Задача 7.

Ранее были приведены примеры вызова данного предиката:

? – functor(f(a, b, c), X, Y).

→

X = f, Y = 3

? – functor(X, f, 3). →

X = f(_, _, _)

 

62

 

Замените в 1-м вызове f(a, b, c) на 1+2+3+4.

Замените во 2-м вызове f на is, 3 на 2. Что получится в результате?

Ответ:

В результате получится: в 1-м вызове: X = ’+’, Y = 2; во 2-м вызове: X = _ is _.

Предикат arg/3.

Напомним, что в отличие от предыдущих предикатов этот предикат работает только в одну сторону: его спецификация arg/(i, i, o). По номеру компонента (1-й аргумент) структуры произвольного вида (2-й аргумент) находится значение этого компонента (3-й ар-

гумент). Но не наоборот.

 

? – arg(2, f(a, b, c), X). →

X = b

Задача 8. Напишите определение предиката arg1/(?, i, ?). Точнее, спецификация этого предиката должна быть либо arg1/(i, i, o),

либо arg1/(o, i, i).

Указание: можно использовать встроенный предикат var/1, проверяющий, не является ли терм неозначенной переменной.

Ответ:

% S – всегда входной параметр (исходная структура).

arg1(N, S, X) :- var(N), !, % (o, i, i) – по значению аргумента

functor(S, _, A),

% ищем его номер

arg1(1, A, N, S, X).

arg1(N, S, X) :- !,

% (i, i, ?) – по номеру аргумента

arg(N, S, X). % ищем (или проверяем) его значение

arg1(I, A, _, _, _) :- I > A, !, fail. arg1(N, _, N, S, X) :- arg(N, S, X).

arg1(I, A, N, S, X) :- I1 is I + 1, arg1(I1, A, N, S, X).

63

Консоль:

| ?-

# 0.000 seconds to consult arg1.pl [c:\prolog\lpa\] | ?- arg1(3, f(a,b,c,b), c).

yes

| ?- arg1(3, f(a,b,c,b), b). no

| ?- arg1(3, f(a,b,c,b), X). X = c

| ?- arg1(X, f(a,b,c,b), b). X = 2 ;

X = 4 ; no

Предикат =../2.

Напомним, что этот предикат осуществляет преобразование структуры произвольного вида (1-й аргумент) в список (2-й аргумент), или наоборот. 1-й элемент списка – имя структуры, 2-й элемент – компоненты структуры. Таким образом, длина списка на единицу больше числа компонентов структуры.

? – f(a, b, c) =.. X.

→

X = [f, a, b, c]

? – X =.. [f, a, b, c].

→

X = f(a, b, c)

Задача 9. В базе данных Пролога есть данные о преподавателях кафедры «Кибернетика» МИФИ в виде фактов prep/10. Второй аргумент этой структуры данных – ФИО преподавателя. Не пользуясь предикатом arg/3, найдите шифр (значение 1-го аргумента) и должность (значение 3-го аргумента) преподавателя Щукина Б.А.

Ответ:

? – functor(P, prep, 10), call(P), P =.. [X, ’Щукин Б.А.’, Y|_].

64

Методы и примеры определений предикатов обработки списков

В разд.2 данной лекции были приведены определения предика-

тов обработки списков: member/2, append/3, reverse/2, sort/2 и т.д.

Задача 10. Напишите определение предиката sort_k/(i, o, i) для сортировки списка термов t/(a1, ..., an) по ключу: (ai, ..., aj). Ключ – список целых чисел – номеров аргументов терма, по которым производится сортировка. Для проверки определите вспомогательный предикат test/3, с помощью которого задаётся проверочная информация, например:

test(List, SortedList, Key) :- K=[2, 3], List=[f(d,m,8), f(d,m,3), f(d,k,9)], sort_k(List, SortedList, Key).

Ответ:

%Сортировка списка термов t/(a1, ..., an)

%по ключу: (ai, ..., aj).

sort_k([], [], _) :- !.

sort_k([T|Ts], Res, Key) :- sort_k(Ts, Res1, Key), in_sort_k(T, Res1, Res, Key).

in_sort_k(T, [], [T], _).

in_sort_k(T, [H|R], [T, H|R], K) :- less_eq_k(T, H, K),!. in_sort_k(T, [H|R], [H|R1], K) :- !,

in_sort_k(T, R, R1, K).

less_eq_k(X, Y, K) :- lista(X, K, L1), lista(Y, K, L2), L1 @=< L2, !.

lista(_, [], []) :- !.

lista(T, [N|K], [A|L]) :- arg(N, T, A), lista(T, K, L).

65

Источник: https://studfile.net/preview/16708744/