= person(symbol, symbol) /* (First, Last) */
birthday=b_date(symbol,integer,integer) /*(Month, Day,Year)*/
ph_num = symbol /* Phone_number */
predicates
phone_list(name, symbol, birthday)
get_months_birthdays
convert_month(symbol, integer)
check_birthday_month(integer, birthday)
write_person(name)
clauses
get_months_birthdays:- makewindow(1,7,7, " This Month's
Birthday List ", 0, 0, 25, 80),
write(" First name\t Last Name\n"),
date(_, This_month, _),
phone_list(Person, _, Date),
check_birthday_month(This_month, Date),
write_person(Person),
fail.
get_months_birthdays :- write("\n\n Press any key to
continue: "),
readchar(_).
write_person(person(First_name, Last_name)):-
write(" ",First_name, "\t\t ", Last_name), nl.
check_birthday_month(Mon, b_date(Month, _, _)) :-
convert_month(Month, Month1),
Mon = Month1.
phone_list(person(ed, willis), "767-8463", b_date(jan, 3,
1955)).
phone_list(person(benjamin, thomas), "438-8400",
b_date(feb, 5, 1985)).
phone_list(person(ray, william),"555-5653", b_date(mar,
3,1935)).
phone_list(person(thomas, alfred), "767-2223",
b_date(apr, 29, 1951)).
phone_list(person(chris, grahm),
"555-1212", b_date(may, 12, 1962)).
phone_list(person(dustin, robert), "438-8400", b_date(jun,
17, 1980)).
phone_list(person(anna, friend), "767-8463",
b_date(jun, 20, 1986)).
phone_list(person(brandy, rae),"555-5653", b_date(jul, 16,
1981)).
phone_list(person(naomi, friend), "767-2223", b_date(aug,
10, 1981)).
phone_list(person(christina, lynn), "438-8400",
b_date(sep, 25, 1981)).
phone_list(person(kathy, ann),
"438-8400", b_date(oct, 20, 1952)).
phone_list(person(elizabeth, ann), "555-1212", b_date(nov,
9, 1984)).
phone_list(person(aaron, friend), "767-2223",
b_date(nov, 15, 1987)).
phone_list(person(jennifer, caitlin), "438-8400",
b_date(dec, 31, 1981)).
convert_month(jan, 1).
convert_month(feb, 2).
convert_month(mar, 3).
convert_month(apr, 4).
convert_month(may, 5).
convert_month(jun, 6).
convert_month(jul, 7).
convert_month(aug, 8).
convert_month(sep, 9).
convert_month(oct, 10).
convert_month(nov, 11).
convert_month(dec, 12).
Як працює програма?
1. Спочатку, програма робить вікно на екрані дисплею для відображення результату.
2. Після, вона друкує заголовок у вікно, для полегшення інтерпретації результату.
3. Далі, в предикаті get_month_birthday за допомогою вмонтованого предикату date отримуємо значення поточного місяця.
4. Після, програма робить пошук по базі даних списку людей, які народилися в поточному місяці.
Знаходиться перша особа в базі даних. Виклик предикату phone_list(Person,_,Date) зв'язує ім'я і прізвище цієї особи з змінною Pеrson для співставлення функтору person з змінною Person. Виклик також зв'язує день народження цієї особи з змінною Date.
Відмітимо, що вам досить використання однієї змінної для запам'ятовування повного імені особи і однієї змінної для запам'ятовування повної дати дня народження. Це результат використання складних об'єктів.
5. Зараз програма може обробляти день народження особи, використовуючи змінну Date. Така обробка починається в наступній підцілі, де програма обробляє поточний місяць, який заданий числом і день народження особи в предикаті check_birthday_month.
6. Звернемо увагу на те, як цей процес проходить. Пролог викликає предикат check_birthday_month з двома змінними: перша змінна зв'язана з цілим, а друга - з функтором і його трьома аргументами. В голові правила, де визначається предикат check_birthday_month перший аргумент This_month зрівнюється з змінною Моn. Другий аргумент Date співставляється з b_date(Month,_,_). Це добре, оскільки він є тим же значенням об'єкту даних, яке ви обробляєте.
Оскільки всі наші дії пов'язані тільки з місяцем народження особи, в якості дня і року народження можуть виступати анонімні змінні.
7. Предикат check_birthday_month спочатку конвертує символьне позначення місяця в числове значення. Після, Пролог може порівняти значення поточного місяця з значенням місяця народження особи. Якщо порівняння задовольнилось, обробка може закінчуватись. Тому далі стоїть підціль fail. В іншому випадку Пролог-система починає бектрекінг для пошуку іншого розв'язку.
8.Наступна підціль write_person друкує повне ім'я особи до списку осіб, день народження яких належить поточному місяцю, підціль fail форсує бектрекінг.
5.4.Опис доменів складних об'єктів.
В цій секції ми покажемо як визначаються домени для складних об'єктів.
Після компілювання програми, яка містить наступні відношення:
owns(john,book('From Here to Eternity','james Jones')).
і
owns(john,horse(blacky)).
ми можемо системі задати запит goal:owns(john,X).
Змінна X після цього може бути зв'язана з різними типами об'єктів: книгою, конем, або ж можливо іншим об'єктом, який ви визначили. Це випливає із нашого визначення предикату owns. Тому нам не бажане старе використання предикату:
owns (symbol,symbol).
Замість нього ми мусимо сформулювати нове визначення предикату, наприклад:
owns(name,articles)
Зараз, ми можемо описати об'єкт articles в секції domains наступним чином:
domains
articles=book(title,author);
horse(name)
title,author,name=symbol
Крапка з комою читається тут як "або". В цьому випадку можливі альтернативи: книга може ідентифікуватись назвою і автором; або ж кінь ідентифікується своєю кличкою. Всі об'єкти title , аuthor, name є стандартними, символьного типу.
До опису об'єктів може бути добавлено і більше альтернатив. Наприклад, articles може бути судновою книгою, або ж банківською книгою. У випадку суднової книги можемо використати функтор без аргументів, банківську книгу можемо описати як bankbook(balance). В цьому випадку об'єкт articles може бути описаний:
articles =book(title,author); horse(name); boat; bankbook(balance)
title,author,name = symbol
balance =real
Далі приведемо повну програму, яка демонструє використання в фактах, що описуються предикатом owns, складного об'єкту типу articles:
domain
articles = book(title, author) ;
horse(name) ;
boat ;
bankbook(balance)
title, author, name = symbol
balance = real
predicates
owns(name,articles)
clauses
owns(john, book("A friend of the family", "Irwin Shaw")).
owns(john, horse(blacky)).
owns(john, boat).
owns(john, bankbook(1000)).
Тепер відкомпілюємо нашу програму. Коли ми задамо системі запит:
goal: owns(john,Thihg).
Вона видасть чотири рішення:
Thing = book('A friend of the family','Irwin Shaw')
Thing = horse(blacky)
Thing = boat
Thing = bankbook(1000')
4Solutions
Таким чином, опис домену складного об'єкту в загальному має такий вигляд:
domain object= alter1(D,D,...);
alter2(D,D,...);
...
де alter1 і alter2 довільні, але різні функтори. Позначення (D,D,...) задає список імен доменів, які або ж описані десь в іншому допустимому місці, або ж мають один із стандартних типів. Відмітимо наступне:
1. Альтернативи розділяються крапкою з комою.
2. Кожна альтернатива має функтор і можливо список доменів для відповідних аргументів.
5.5.Багаторівневі складні об'єкти.
Пролог дозволяє нам конструювати складні об'єкти на декількох рівнях. Наприклад, в предикаті
book('The Ugly Duckling'.'Andersen')
замість використання прізвища автора, ми хочемо використати нову структуру, яка більш детально описує автора, включаючи до попередньої інформації ще й ім'я.