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

       

Описания объектов



Рисунок 4. 2.    Описания объектов по их структурным свойствам:  (а)   любая семья Армстронгов;  (b)  любая семья, имеющая ровно трех детей;  (с)  любая семья, имеющая по крайней мере три ребенка. Структура  (с)  дает возможность получить имя и фамилию жены конкретизацией переменных Имя  и  Фамилия.


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

        муж( X) :-                           % X - муж
               семья( X, _, _ ).

        жена( X) :-                         % X - жена
               семья( _, X, _ ).

        ребенок( X) :-                     % X - ребенок
               семья( _, _, Дети),
               принадлежит( X, Дети).

        принадлежит( X, [X | L ]).

        принадлежит( X, [Y | L ]) :-
               принадлежит( X, L).

        существует( Членсемьи) :-
                                   % Любой член семьи в базе данных

            муж( Членсемьи);
            жена( Членсемьи);
            ребенок( Членсемьи).

        дата рождения( Членсемьи( _, _, Дата, _ ), Дата).

        доход( Членсемьи( _, _, _, работает( _, S) ), S).
                                                                % Доход работающего

        доход( Членсемьи( _, _, _, неработает), 0).
                                                                % Доход неработающего

Этими процедурами можно воспользоваться, например, в следующих запросах к базе данных:

  • Найти имена всех людей из базы данных:

            ?-  существует( членсемьи( Имя,Фамилия, _, _ )).
  • Найти всех детей, родившихся в 1981 году:

            ?-  ребенок( X), датарождения( X, дата( _, _, 1981) ).
  • Найти всех работающих жен:

            ?-  жена( членсемьи( Имя, Фамилия, _, работает( _, _ ))).
  • Найти имена и фамилии людей, которые не работают и родились до 1963 года:

    ?-  существует членсемьи( Имя, Фамилия, дата( _, _, Год), неработает) ),
         Год < 1963.

  • Найти людей, родившихся до 1950 года, чей доход меньше, чем 8000:

            ?-  существует( Членсемьи),
                 датарождения( Членсемьи, дата( _, _, Год) ),
                 Год < 1950,
                 доход( Членсемьи, Доход),
                 Доход < 8000.

  • Найти фамилии людей, имеющих по крайней мере трех детей:

            ?-  семья( членсемьи( _, Фамилия, _, _ ), _, [ _, _, _ | _ ]).

Для подсчета общего дохода семья полезно определить сумму доходов людей из некоторого списка в виде двухаргументного отношения:

        общий( Список_Людей, Сумма_их_доходов)

Это отношение можно запрограммировать так:

        общий( [ ], 0).                     % Пустой список людей

        общий( [ Человек | Список], Сумма) :-
               доход( Человек, S),

                                % S - доход первого человека
               общий( Список, Остальные),
                                % Остальные - сумма доходов остальных
               Сумма is S + Остальные.

Теперь общие доходы всех семей могут быть найдены с помощью вопроса:

        ?-  семья( Муж, Жена, Дети),
             общий( [Муж, Жена | Дети], Доход).

Пусть отношение длина подсчитывает количество элементов списка, как это было определено в разд. 3.4. Тогда мы можем найти все семьи, которые имеют доход на члена семьи, меньший, чем 2000, при помощи вопроса:

        ?-  семья( Муж, Жена, Дети),
             общий( [ Муж, Жена | Дети], Доход),
             длина( [ Муж, Жена | Дети], N),
             Доход/N < 2000.



Содержание раздела