Ответы к некоторым упражнениям Назад | Содержание | Вперёд

ОТВЕТЫ К НЕКОТОРЫМ УПРАЖНЕНИЯМ Глава 1 1. 1 (a)    no

(b)    X = пат   

(c)    X = боб

(d)    X = боб,    Y = пат

1. 2 (a)    ?-  родитель( X, пат).

(b)    ?-  родитель( лиз, X).

(c)    ?-  родитель( Y, пат),     родитель( X, Y).

1. 3 (a)    счастлив( X) :-

                родитель( X, Y).

(b)    имеетдвухдетей( X) :-

                родитель( X, Y),

                сестра( Z, Y).

1. 4 внук( X, Z) :-

        родитель( Y, X),

        родитель( Z, Y).

1. 5 тетя( X, Y) :-

        родитель( Z, Y),

        сестра( X, Z).

1. 6 Да.    (Определение верно)

1. 7 (a)    возвратов не будет

(b)    возвратов не будет

(c)    возвратов не будет

(d)    возвраты будут

Глава 2 2. 1 (a)    переменная

(b)    атом

(c)    атом

(d)    переменная

(e)    атом

(f)    структура

(g)    число

(h)    синтаксически неправильное выражение

(i)    структура

(j)    структура

2. 3 (a)    успех

(b)    неуспех

(c)    неуспех

(d)    D = 2,    Е = 2

(e)    Р1 = точка(-1, 0)

        Р2 = точка( 1, 0)

        Р3 = точка( 0, Y)

Такая конкретизация определяет семейство треугольников, у которых две вершины располагаются на оси х в точках 1 и -1, а третья - в произвольной точке оси у.

2. 4 отр( точка( 5, Y1),    точка( 5, Y2) )

2. 5 регулярный( прямоугольник( точка( X1, Y1),

                                    точка( Х2, Y1), точкa( X2, Y3),

                                    точка( X1, Y3) ) ).

Здесь предполагается, что первая точка соответствует нижней левой вершине прямоугольника.

2. 6 (a)    А = два

(b)    no

(c)    С = один

(d)    D = s(s(1));

        D = s(s(s(s(s(1)))))

2. 7 родственники( X, Y) :-

    предок( X, Y);

    предок( Y, X);

    предок( Z, X),

    предок( Z, Y);

    предок( X, Z),

    предок( Y, Z).

2. 8 преобразовать( 1, один).

преобразовать( 2, два).

преобразовать( 3, три).

2. 9 В случае, изображенном на рис. 2.10, пролог-система выполняет несколько больший объем работы.

2. 10 В соответствии с определением сопоставления, приведенном в разд. 2.2, данное сопоставление будет успешным. X приобретает вид циклической структуры, в которой сам X присутствует в качестве одного из аргументов.

Глава 3 3. 1 (a)    конк( L1, [ _, _, _ ], L)

(b)    конк( [ _, _, _ ], L1, L),

                        % Удалить 3 первые элемента L

        конк( L2, [ _, _, _ ], L1)

                        % Удалить 3 последние элемента L1

Вот более короткий вариант, предложенный I. Tvrdy:       

        конк( [ _, _, _ | L2], [ _, _, _ ], L)

3. 2 (а)    последний( Элемент, Список) :-

        конк( _, [Элемент], Список).

(b)    последний( Элемент, [Элемент]).

        последиий( Элемент, [Первый | Остальные]):-

        последний( Элемент, Остальные).

3. 3 четнаядлина( [ ] ).

четнаядлина( [Первый | Остальные] ) :-

    нечетнаядлина( Остальные).

нечетнаядлина( [ _ ] ).

нечетнаядлина( [Первый | Остальные] ) :-

    четнаядлина( Остальные).

3. 4 обращение( [ ], [ ]).

обращение( [Первый | Остальные], ОбращСпис): -

    обращение( Остальные, ОбращСписОстальных),

конк( О6ращСписОстальных, [Первый], ОбращСпис).

3. 5 % Такой предикат легко определить при помощи отношения обратить

палиндром( Список) :-

    обратить( Список, Список).

% Вот другое решение, не использующее обратить

палиндром1( [ ] ).

палиндром1( [ _ ] ).

палиндром1 [Первый | Остальные] ) :-

    конк( Середина, [Первый], Остальные),

    палиндром1( Середина).

3. 6 сдвиг( [Первый | Остальные], Сдвинут) :-

    конк( Остальные, [Первый], Сдвинут).

3. 7 перевод( [ ], [ ]).

перевод( [Голова | Хвост], [Голова1 | Хвост1]) :-

    означает( Голова, Голова1),

    перевод( Хвост, Хвост1).

3. 8 подмножество( [ ], [ ] ).

подмножество( [Первый | Остальные], [Первый | Подмн]):-

                                % Оставить первый элемент в подмножестве

    подмножество( Остальные, Подмн).

подмножество( [Первый | Остальные], Подмн) :-

                                % Убрать первый элемент из подмножества

    подмножество( Остальные, Подмн).

3. 9 разбиениесписка( [ ], [ ], [ ]).                           % Разбивать нечего

разбиениесписка( [X], [X], [ ]).

                            % Разбиение одноэлементного списка

разбиениесписка( [X, Y | Список], [Х | Список1],

                                [Y | Список2]) :-

    разбиениесписка( Список, Список1, Список2).

3. 10 можетзавладеть( состояние( _, _, _, имеет), [ ] ).

                                % Ничего не надо делать

можетзавладеть( Состояние, [Действие | Действия]):-

    ход( Состояние, Действие, НовоеСостояние),

                                % Первое действие

    можетзавладеть( НовоеСостояние, Действия).

                                % Оставшиеся действия

3. 11 линеаризация( [Голова | Хвост], ЛинейныйСписок ) :-

                                % Линеаризация непустого списка

    линеаризация( Голова, ЛинейнаяГолова ),

    линеаризация( Хвост, ЛинейныйХвост ),

    конк( ЛинейнаяГолова, ЛинейныйХвост,

        ЛинейныйСписок ).

линеаризация( [ ], [ ] ).                  % Линеаризация пустого списка

линеаризация( X, [X] ).

                            % Линеаризация объекта, не являющегося списком

% Замечание: при попытке получить от этой программы более

% одного варианта решения выдается бессмыслица

3. 12 Терм1 = играет_в( джимми, и( футбол, сквош) )

Терм2 = играет_в( сьюзан, и( теннис,

                                    и( баскетбол, волейбол) ) )

3. 13 :- ор( 300, xfx, работает)

:- ор( 200, xfx, в)

:- ор( 100, xfx, нашем)

3. 14 (a)    А = 1 + 0

(b)    В = 1 + 1 + 0

(c)    С = 1 + 1 + 1 + 1 + 0

(d)    D = 1 + 1 + 0 + 1

3. 15 :- ор( 100, xfx, входит_в)

:- ор( 300, fx, конкатенация_списков)

:- ор( 200, xfx, дает)

:- ор( 100, xfx, и)

:- ор( 300, fx, удаление_элемента)

:- ор( 100, xfx, из_списка)                         % Принадлежность к списку

Элемент входит_в [Элемент | Список].

Элемент входит_в [Первый | СписокОстальных] :-

Элемент входит_в СписокОстальных.

% Конкатенация списков

конкатенация_списков [ ] и Список дает Список.

конкатенация_списков [X | L1] и L2 дает [X | L3] :-

    конкатенация_списков L1 и L2 дает L3.

% Удаление элемента из списка

удаление_элемента Элемент иэ_списка

            [Элемент | ОстальныеЭлементы]

            дает ОстальныеЭлементы.

удаление_элемента Элемент из_списка

        [Первый | ОстальныеЭлементы]

        дает [Первый | НовСписОстЭлементов] :-

    удаление_элемента Элемент из_списка

            ОстальныеЭлементы дает НовСписОстЭлементов.

3. 16 max( X, Y, X) :-

    X >= Y.

max( X, Y, Y) :-

    X <Y.

3. 17 максспис( [X], X).

                            % Максимум в одноэлементном списке

максспис( [X, Y | Остальные], Мах) :-

                            % В списке есть по крайней мере два элемента?

    максспис( [Y | Остальные], МаксОстальные),

    mах( X, МаксОстальные, Мах).

                            % Мах наибольшее из чисел X и МаксОстальные

3. 18 сумспис( [ ], 0).

сумспис( [Первый | Остальные], Сумма) :-

    сумспис( Остальные, СуммаОстальных),

    Сумма is Первый + СуммаОстальных.

3. 19 упорядоченный ([ ]).

                        % Одноэлементный список является упорядоченным

упорядоченный( [X, Y | Остальные] :-

    X =< Y,

    упорядоченный( [Y | Остальные] ).

3. 20 подсумма( [ ], 0, [ ]).

подсумма( [N | Список], Сумма, [N | Подмн]) :-

                    % N принадлежит подмножеству

    Сумма1 is Сумма - N,

    подсумма( Список, Сумма1, Подмн).

подсумма( [N | Список], Сумма, Подмн) :-

                    % N не принадлежит подмножеству

    подсумма( Список, Сумма, Подмн).

3. 21 между( N1, N2, N1) :-

    N1 =< N2.

между( N1, N2, X) :-

    N1 < N2,

    HoвoeNl is N1 + 1,

    между( HoвoeNl, N2, X).

3. 22 :- ор( 900, fx, если).

:- ор( 800, xfx, то).

:- ор( 700, xfx, иначе).

:- ор( 600, xfx, :=).

если Вел1 > Вел2 то Перем := Вел3

                                иначе ЧтоУгодно :-

    Вел1 > Вел2,

    Перем = Вел3.

если Вел1 > Вел2 то ЧтоУгодно

                                иначе Перем := Вел4 :-

    Вел1 =< Вел2,

    Перем = Вел4.

Глава 4 4. 1 (a)    ?-  семья(членсемьи( _, Фамилия, _, _ ), _, [ ]).

(b)    ?-  ребенок( членсемьи( Имя, Фамилия, _,

                                работает( _, _ ) )).

(c)    семья(членсемьи( _, Фамилия, _, неработает),

                    членсемьи( _, _, _, работает( _, _ ) ),_ ).

(d)    ?-  семья( Муж, Жена, Дети),

            датарождения( Муж, дата( _, _, Год1) ),

            датарождения( Жена, дата( _, _, Год2) ),

            ( Год1 - Год2 >= 15;

              Год2 - Год1 >= 15 ),

            принадлежит( Ребенок, Дети).

4. 2 близнецы( Ребенок1, Ребенок2) :-

    семья( _, _, Дети),

    удалить( Ребенок1, Дети, ДругиеДети),

                            % Выделить первого ребенка

    принадлежит( Ребенок2, ДругиеДети),

    принадлежит( Ребенок1, Дата),

    принадлежит( Ребенок2, Дата).

4. 3 n_элемент( 1, [X | L], X).

                            % X - первый элемент списка [X | L]

n_элемент( N, [Y | L], X) :-

                            % X - n-й элемент [Y | L]

N1 is N - 1,

n_элемент( N1, L, X).

4. 4 Входная цепочка укорачивается на каждом неспонтанном цикле, а укорачиваться бесконечно она не может.

4. 5 допускается( S, [ ], _ ) :-

    конечное( S).

допускается( S, [X | Остальные], Макс_переходов) :-

    Макс_переходов > 0,

    переход( S, X, S1),

    НовыйМакс is Макс_переходов - 1,

    допускается( S1, Остальные, НовыйМакс).

допускается( S, Цепочка, Макс_переходов) :-

    Макс_переходов > 0,

    спонтанный( S, S1),

    НовыйМакс is Макс_переходов - 1,

    допускается( S1, Цепочка, НовыйМакс).

4. 7 (а)    ходконя( X/Y, X1/Y1) :-

                        % Ход коня с поля X/Y на поле X1/Y1

            ( dxy( DX, DY);

                        % Расстояния по направлениям X и Y

              dxy( DY, DX) ),

                        % Или расстояния по направлениям Y и X

            X1 is X + DX,

                        % X1 расположен в пределах шахматной доски

            надоске( X1),

            Y1 is Y + DY,

                        % Y1 расположен в пределах шахматной доски

            надоске( Y1).

        dxy( 2, 1).             % 2 поля вправо, 1 поле вперед

        dxy( 2, -1).            % 2 поля вправо, 1 поле назад

        dxy( -2, 1).            % 2 поля влево, 1 поле вперед

        dxy( -2, -1).           % 2 поля влево, 1 поле назад

        надоске( Коорд) :-

                            % Координаты в пределах доски

            0 < Коорд,

            Коорд < 9.

(b)    путьконя( [ Поле]).         % Конь стоит на поле Поле

            путьконя( [S1, S2 | Остальные] ) :-

            ходконя( S1, S2),

            путьконя( [S2 | Остальные]).

(c)    ?-  путьконя( [2/1, R, 5/4, S, Х/8] ).

Глава 5 5. 1 (a)    X = 1;

        X = 2

(b)    X = 1;

        Y = 1;

        X = 1;

        Y = 2;

        X = 2;

        Y = 1;

        X = 2

        Y = 2;

(c)    X = 1;

        Y = 1;

        X = 1;

        Y = 2;

5. 2 класс( Число, положительное) :-

    Число > 0,  !.

класс( 0, нуль) :-  !.

класс( Число, отрицательное).

5. 3 разбить( [ ], [ ], [ ]).

разбить( [X | L], [X | L1], L2) :-

    X >= 0,  !,

    разбить( L, L1, L2).

разбить( [X | L], L1, [X | L2]) .

    разбить( L, L1, L2).

5. 4 принадлежит( Некто, Кандидаты),

        not принадлежит( Некто, Исключенные)

5. 5 разность( [ ], _, [ ]).

разность( [X | L1], L2, L):-

    принадлежит( X, L2),  !,

    разность( L1, L2, L).

разность( [X | L1], L2, [X | L]) :-

    разность( L1, L2, L).

5. 6 унифицируемые( [ ], _, [ ]).

унифицируемые( [Первый | Остальные], Терм, Список) : -

    not( Первый = Терм),  !,

    унифицируемые( Остальные, Терм, Список).

унифицируемые( [Первый | Остальные], Терм,

                                [Первый | Список] ) :-

    унифицируемые( Остальные, Терм, Список).

Глава 6 6. 1 найтитерм( Терм) :-

                            % Пусть текущий входной поток - это файл f

    read( Терм),  !,

                            % Текущий терм из f сопоставим с Терм'ом?

    write( Терм);                  % Если да - вывести его на терминал

    найтитерм( Терм).       % В противном случае - обработать

6. 2 найтитермы( Терм) :-

    read( ТекущийТерм),

    обработать( ТекущийТерм, Терм).

обработать( end_of_file, _ ) :-  !.

обработать( ТекущийТерм, Терм) :-

    ( not( ТекущийТерм = Терм),  !;

                        % Термы несопоставимы

      write( ТекущийТерм), nl),

                        % В противном случае вывести текущий терм

    найтивсетермы( Терм).

                        % Обработать оставшуюся часть файла

6. 4 начинается( Атом, Символ) :-

    name( Символ, [ Код]),

    name( Атом, [Код | _ ]).

6. 5 plural( Существительное, Существительные) :-

    name( Существительное, СписокКодов),

    name( s, КодS),

    конк( СписокКодов, КодS, НовыйСписокКодов),

    name( Существительные, НовыйСписокКодов).

Глава 7 7. 2 добавить( Элемент, Список) :-

    var( Список),  !,

                        % Переменная Список представляет пустой список

Список = [Элемент | Хвост].

добавить( Элемент, [ _ | Хвост]) :-

    добавить( Элемент, Хвост).

принадлежит( X, Список) :-

    var( Список),  !,

                    % Переменная Список представляет пустой список,

                           % поэтому X не может ему принадлежать

fail.

принадлежит( X, [X | Хвост]).

принадлежит( X, [ _ | Хвост] ) :-

    принадлежит( X, Хвост).

Глава 8 8. 2 добавить_в_конец( L1-[Элемент | Z2], Элемент, L1 - Z2).

8. 3 обратить( А - Z, L - L) :-

                        % Результатом является пустой список,

                                % если A-Z представляет пустой список

    А == Z,  !.

обратить( [X | L] - Z, RL - RZ ) :-

                        % Непустой список

    обратить( L - Z, RL - [X | RZ].

Глава 9 9. 1 список( [ ]).

список( [ _ | Хвост]) :-

    список( Хвост).

9. 2 принадлежит( X, X затем ЧтоУгодно).

принадлежит( X, Y затем Спис) :-

    принадлежит( X, Спис).

9. 3 преобр( [ ], ничего_не_делать).

преобр( [Первый | Хвост], Первый затем Остальные):-

    преобр( Хвост, Остальные).

9. 4 преобр( [ ], ПустСпис, _, ПустСпис).

                                % Случай пустого списка

преобр( [Первый | Хвост], НовСпис, Функтор, Пустой) :-

    НовСпис =.. [Функтор, Первый, НовХвост],

    преобр( Хвост, НовХвост, Функтор, Пустой).

9. 8 сорт1( [ ], [ ]).

сорт1( [X], [X]).

сорт1( Спис, УпорСпис) :-

    разбить( Спис, Спис1, Спис2),

                            % Разбить на 2 прибл. равных списка

    сорт1( Спис1, Упор1),

    сорт1( Спис2, Упор2),

    слить( Упор1, Упор2, УпорСпис).

                            % Слить отсортированные списки

разбить( [ ], [ ], [ ]).

разбить( [X], [X], [ ]).

разбить( [X, Y | L], [X | L1], [Y | L2]) :-

                            % X и Y помещаются в разные списки

    разбить( L, L1, L2).

9. 9 (а)    двдерево( nil).

        двдерево( д( Лев, Кор, Прав) ) :-

            двдерево( Лев),

            двдерево( Прав).

9. 10 глубина( пусто, 0).

глубина( д( Лев, Кор, Прав), Г) :-

    глубина( Лев, ГЛ),

    глубина( Прав, ГП),

    макс( ГЛ, ГП, МГ),

    Г is МГ + 1.

макс( А, В, А) :-

    А >= В,  !.

макс( А, В, В).

9. 11 линеаризация( nil, [ ]).

линеаризация( д( Лев, Кор, Прав), Спис) :-

    линеаризация( Лев, Спис1),

    линеаризация( Прав, Спис2),

    конк( Спис1, [Кор | Спис2], Спис).

9. 12 максэлемент( д( _, Кор, nil), Кор) :-  !.

                            % Корень - самый правый элемент

максэлемент( д( _, _, Прав,), Макс) :-

                            % Правое поддерево непустое

    максэлемент( Прав, Макс).

9. 13 внутри( Элем, д( _, Элем, _ ), [ Элем]).

внутри( Элем, д( Лев, Кор, _ ), [Кор | Путь]) :-

    больше( Кор, Элем),

    внутри( Элем, Лев, Путь).

внутри( Элем,д( _, Кор, Прав), [Кор | Путь]) :-

    больше( Элем, Кор),

    внутри( Элем, Прав, Путь).

9. 14 % Отображение двоичного дерева, растущего сверху вниз

% Предполагается, что каждая вершина занимает при печати

% один символ

отобр( Дер) :-

    уровни( Дер, 0, да).

                            % Обработать все уровни

уровни( Дер, Уров, нет) :-  !.

                            % Ниже уровня Уров больше нет вершин

уровни( Дер, Уров, да) :-

                            % Обработать все уровни, начиная с Уров

    вывод( Дер, Уров, 0, Дальше), nl,

                            % Вывести вершины уровня Уров

    Уров1 is Уров + 1,

    уровни( Дер, Уров1, Дальше).

                            % Обработать следующие уровни

вывод( nil, _, _, _, _ ).

вывод( д( Лев, X, Прав), Уров, ГлубХ, Дальше) :-

    Глуб1 is ГлубХ + 1,

    вывод( Лев, Уров, Глуб1, Дальше),

                            % Вывод левого поддерева

( Уров = ГлубХ,  !,

                            % X на нашем уровне?

        write( X), Дальше = да;

                            % Вывести вершину, продолжить

        write(' ') ),

                            % Иначе - оставить место

        вывод( Прав, Уров, Глуб1, Дальше).

                            % Вывод левого поддерева

Глава 10 10. 1 внутри( Элем, л( Элем)).             % Элемент найден в листе

внутри( Элем, в2( Д1, М, Д2) ):-

                                                    % Вершина имеет два поддерева

    больше( М, Элем),  !,           % Вершина не во втором поддереве

    внутри( Элем, Д1);               % Поиск в первом поддереве

    внутри( Элем, Д2).               % Иначе - во втором поддереве

внутри( Элем, в3( Д1, М2, Д2, М3, Д3) ):-

                                                    % Вершина имеет три поддерева

    больше( М2, Элем),  !,

                % Элемент не во втором и не в третьем поддереве

    внутри( Элем, Д1);               % Поиск в первом поддереве

    больше( М3, Элем),  !,         % Элемент не в третьем поддереве

    внутри( Элем, Д2);               % Поиск во втором поддереве

    внутри( Элем, Д3).               % Поиск в третьем поддереве

10. 3 avl( Дер) :-

    аvl( Дер, Глуб).         % Дер является AVL-деревом глубины Глуб

avl( nil, 0).                     % Пустое дерево  -   AVL -дерево глубины 0

avl( д( Лев, Кор, Прав), Г) :-

    avl( Лев, ГЛ),

    avl( Прав, ГП),

    ( ГЛ is ГП; ГЛ is ГП + 1; ГЛ is ГП - 1),

                                    % Глубины поддеревьев примерно совпадают

        макс( ГЛ, ГП, Г).

макс1( U, V, М) :-                                     % М = 1 + макс( U, V)

    U > V,  !, М is U + 1;

    М is V + 1.

Глава 11 11. 1 вглубину1( [Верш | Путь], [Верш | Путь]) :-

    цель( Верш).

вглубину1( [Верш | Путь], Решение) :-

    после( Верш, Верш1),

    not принадлежит( Верш1, Путь),

    вглубину1( [ Верш1, Верш | Путь], Решение).

11. 6 решить( СтартМнож, Решение) :-

                            % СтартМнож - множество стартовых вершин

    bagof( [Верш], принадлежит( Верш, СтартМнож),

                                                        Пути),

    вширину( Пути, Решение).

Назад | Содержание | Вперёд

ha();

Соседние файлы в папке Программирование на языке Пролог для искусственного интеллекта