Составные объекты данных и функторы

Составные объекты данных позволяют интерпретировать некоторые части информации как единое целое таким образом, чтобы затем можно было легко разделить их вновь (слайд 4)

Например, дата «14 ноября 2006 года» состоит из трех частей информации – день, месяц, год. Представим ее как древовидную структуру:

Такая структура может быть описана при помощи объявления домена date_t, содержащего составной объект b_date:

DOMAINS

date_t=b_date(unsigned, string, unsigned)

 

Затем в программе можно просто записать:

D = b_date(14, “Ноябрь”, 2006).

Такая запись похожа на факт Пролога, но не является им. Это объект данных, который можно обрабатывать наряду с символами и числами. Он начинается с имени, которое называется функтором (в нашем случае это b_date), за которым следуют три аргумента.

Функтор в языке Пролог – просто имя, которое определяет вид составного объекта данных и объединяет вместе его аргументы. Функтор не обозначает, что будут выполнены какие-либо вычисления, и не имеет ничего общего с функциями в других языках программирования, кроме внешнего вида.

Составные объекты состоят из функтора и объектов, принадлежащих этому функтору: functor(object1, object2,…, objectN). Составной объект можно унифицировать с простой переменной или с составным объектом, который ему соответствует. Это означает, что составной объект можно использовать для того, чтобы передавать целый набор значений как единый объект, и затем применять унификацию для их разделения. Аргументы составного объекта данных сами могут быть составными объектами.

Например, если рассматривать периоды жизни знаменитых русских людей, то эту информацию можно представить в виде следующей структуры:

 


 

 

На языке Пролог соответствующая запись выглядит следующим образом:

famous_russ(person("Александр","Пушкин"),poet,period(1739,1837)).

Пример 1. (слайды 5, 6 и 7)

В данном примере рассмотрена программа, основными фактами которой являются сведения о жизни знаменитых россиян. Имеются сведения об их именах, фамилиях, роде занятий, периоде жизни. Основной целью является определение списка людей, живущих в России в том году, который указан пользователем.

DOMAINS

zhizn = period(unsigned, unsigned)

name = person(symbol,symbol)

izvesten = symbol

famous_list = famous_list(name, izvesten, zhizn)

 

PREDICATES

famous_russ(name, izvesten, zhizn)

god(unsigned)

zagolovok

zapros

 

CLAUSES

famous_russ(person("Alexandr","Glazunov"),

kompozitor,period(1865,1936)).

famous_russ(person("Fedor","Glinka"),

archeolog,period(1786,1880)).

famous_russ(person("Ivan","Goncharov"),

prozaik,period(1812,1891)).

famous_russ(person("Alexandr","Gorchakov"),

diplomat,period(1798,1883)).

famous_russ(person("Vasiliy","Docuchaev"),

geolog,period(1846,1905)).

famous_russ(person("Alexandr","Dondukov_Korsakov"),

general,period(1820,1893)).

famous_russ(person("Fedor","Dostoevsky"),

prozaik,period(1821,1881)).

famous_russ(person("Michail","Dragomirov"),

prozaik,period(1830,1905)).

famous_russ(person("Nikolay","Ivashinzev"),

gidrograf,period(1819,1871)).

famous_russ(person("Dmitry","Ilovaisky"),

istorik,period(1832,1920)).

famous_russ(person("Alexandr","Borodin"),

kompozitor,period(1834,1887)).

famous_russ(person("Alexandr II","Romanov"),

imperator,period(1818,1881)).

famous_russ(person("Alexandr","Ostrovsky"),

dramaturg,period(1823,1886)).

famous_russ(person("Lev","Tolstoy"),

prozaik,period(1829,1910)).

famous_russ(person("Alexandr III","Romanov"),

imperator,period(1845,1894)).

famous_russ(person("Sergey","Vitte"),

ministr,period(1849,1915)).

 

god(GOD):-

famous_russ(X,Y,Z),

Z=period(R,G),

GOD>R, GOD<G,

X=person(I,F),

writef (" \n %-35s %-20s %-20s ", F, I, Y), fail.

god(_).

 

zagolovok:-

writef ("Фамилия Имя Род занятий").

 

zapros:-

famous_list(person("Alexandr","Glazunov"),Y,_),

write("Vvedite god"), readint(God), nl,

famous_list(person(I,F), Y, period(R,D)),

God>R, God<D, write(F," ",I), nl, fail.

 

GOAL

write("Введите год"), readint(God), zagolovok, god(God),nl.

Замечание. Если мы переопределим цели, и в качестве основной поставим поиск ответа на вопрос «Определить, кто из коллег по профессии Александра Глазунова жил в выбранном пользователем году?», то решение будет связано с успешностью предиката zapros. Первая из подцелей этого предиката определяет, в какой области известен Александр Глазунов и связывает эту область со значением переменной Y. Две следующие подцели обеспечивают запрос года, интересующего пользователя, и связывают это значение с переменной God. В согласование подцели famous_list(person(I,F), Y, period(R,D)) переменная Y вступит уже связанной, и если среди фактов при согласовании найдется соответствующий, то произойдет связывание значений переменных I, F, R, D. Далее значения переменных R и D, используются для согласования периода жизни, а переменные I и F – для вывода информации по запросу. n