Абстрагирование данных можно рассматривать как процесс организации различных фрагментов информации в виде удобных для работы компонентов (возможно, по принципу создания иерархии) и, тем самым, структуризации информации в некоторой концептуально значимой форме. Каждый подобный информационный компонент должен быть легко доступным в программе. В идеальном случае все подробные сведения о реализации, такие как структура, должны быть невидимыми для пользователя информационной структуры; в таком случае программист сможет сосредоточиться на самих объектах и отношениях между ними. Подобный процесс предназначен для того, чтобы можно было обеспечить для программиста возможность использовать саму информацию, не думая о том, как фактически представлена эта информация.
Рассмотрим один из способов осуществления данного принципа в языке Prolog. Для этого снова вернемся к примеру с информацией о семье из предыдущего раздела. Информация о каждой семье представляет собой коллекцию различных фрагментов информации. Все эти фрагменты собраны в такие естественные информационные компоненты, как данные об отдельном лице или о семье, чтобы их можно было рассматривать как целостные объекты. Снова предположим, что информация о семье структурирована, как показано на рис. 4.1. В предыдущем разделе сведения о каждой семье были представлены в виде предложения Prolog. А в этом разделе данные о семье будут представлены в виде структурированного объекта, как показано ниже. FoxFaxily = family { person) ton, fox, _,_>,_,_>
Определим некоторые отношения, с помощью которых пользователь сможет обращаться к отдельным компонентам информации о семье без учета сведений, представленных на рис. 4,1. Подобные отношения можно назвать селективными, поскольку они позволяют извлекать из базы данных определенные компоненты. В качестве имени такого селективного отношения (или просто селектора) применяется имя выбираемого с его помощью компонента. Каждое отношение будет иметь два параметра: объект, содержащий компонент, и сам компонент:
selector_relation(Object, Component_selected)
Ниже приведены некоторые селекторы для структуры с описанием семьи.
children! family! _, _, ChiltiList), ChildList).
Кроме того, можно определить селекторы для первого и второго по счету ребенка следующим образом:
firstchildt Family, First):-
children) Family, [First |. _] >. secondchildt Family, Second):-
children) Family, [ _, Second _]),
Это определение можно уточнить, чтобы иметь возможность выбирать п-го ребенка, таким образом: nthchildl Ы, Family, Child):-
nth_membe^XChildList, Child). % n-й элемент списка
Еще одним интересным объектом является отдельное лицо. Ниже приведены некоторые селекторы, которые соответствуют структуре, приведенной на рис. 4.1.
firstnamef person (Hame, _,_,_), Наше). surname (реиоп Г_, Surname,, I, Surname].
borni person(_,_,Date, J, Date).
Преимущество селективных отношений состоит в том, что после их определения можно забыть о том, с помощью какого конкретного способа представлена та или иная структурированная информация. Для создания и манипулирования этой ин-
102 Часть I. Язык Prolog
формацией достаточно знать имена селективных отношений и использовать их в остальной части программы. В случае более сложных вариантов представления их использовать проще, чем всегда явно ссылаться на сами представления. В частности, в рассматриваемом примере семьи пользователю не требуется знать, что информация о детях представлена в виде списка. Предположим, например, что необходимо сформировать утверждение о том, что Том Фокс и Джим Фокс принадлежат к одной и той же семье и что Джим — второй ребенок Тома. С использованием приведенных выше селективных отношений можно определить два лица, скажем, Fersonl и Person2, и саму семью. Такую задачу позволяет выполнить следующий список целей:
firstnamef Fersonl, torn), surname (Personl, fox), % Fersonl - Том Фокс firstname< Person2, j im), surname (Person2, fox), % Person2 - Джим Фокс husband{ Family, Personl), secandchild; Family, Person2)
В результате конкретизация переменных Personl, Person2 и Family будет выполнена следующим образом:
Personl - person; torn, fox, _, _) Person2 = person; jirn, fox, _, _! Family = familyf person [torn, fox, _,_), _, [ _, person (jim, fox) | _ ]>
Использование селективных отношений позволяет также проще модифицировать программы. Достаточно представить себе, что возникла необходимость повысить эффективность программы путем выбора иного способа представления данных. После этого достаточно просто изменить определения селективных отношений, и остальная часть программы будет работать в неизменном виде с этим новым представлением.