Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабы_ЭкспСист / Лабораторная №6.doc
Скачиваний:
12
Добавлен:
09.02.2015
Размер:
69.63 Кб
Скачать

6.4.2. Функторы

Исчисление предикатов, ветвь логики, имеет тип данных, называемый функциональный символ (functional symbol). Функциональный символ имеет название, или функтор, за которым следуют аргументы. Аргументы записываются между круглыми скобками, и отделяются друг от друга запятыми. Говоря проще, они имеют в точности ту же форму записи, что и функции. Вот несколько примеров функциональных символов:

author("Wellesley", "Barros", 1970)

book( author("Peter", "Novig", 1960),"Artificial Intelligence")

date("July", 15, 1875)

entry("Prolog", "A functional language")

index("Functors", 165)

sunday

Последний пример показывает, что функциональный символ может вообще не иметь аргументов. Об этом сказали, давайте теперь посмотрим, как объявлять типы данных для новых функторов.

Пример вычисляет день недели для любой даты между годами 2000 и 2099. Он имеет следующие объявления доменов:

  • year = integer. year является синонимом integer. Использование синонимов делает вещи яснее.

  • day = sun; mon;tue; wed; thu; fri; sat; err. Этот аргумент имеет множество функциональных символов без аргументов. Каждый функциональный символ отделен от следующего точкой с запятой и отображает день недели.

  • month = jan; feb; mar; apr; may; jun; jul; aug; sep; oct; nov; dec. Ещё один домен (тип) с более чем одним функциональным символом.

  • month code = m(month, integer). Здесь, имеем функциональный символ с двумя аргументами.

  • numberOfDays=nd(integer);february. Другой тип с двумя функциональными символами: первый функциональный символ имеет один аргумент; второй не имеет ни одного.

Объявление списка:

% File newdomains.pro

implement newdomains

open core

constants

className = "newdomains".

classVersion = "".

class predicates

sum:(real*, real) procedure (i, o).

clauses

classInfo(className, classVersion).

sum([], 0) :- !.

sum([X|Xs], X+S) :- sum(Xs, S).

clauses

run():- console::init(),

sum([1, 2, 3, 4, 5, 6], A),

stdio::writef("The sum is %-4.0f", A).

end implement newdomains

goal

mainExe::run(newdomains::run).

% File: func.pro

% This program calculates the day of the week

% for the years between 2000 and 2099.

implement func

open core

constants

className = "func".

classVersion = "".

domains

year= integer.

day= sun; mon;tue; wed; thu; fri; sat; err.

month= jan;feb;mar;apr;may;jun;jul;aug;sep;oct;nov;dec.

month_code= m(month, integer).

numberOfDays= nd(integer); february.

clauses

classInfo(className, classVersion).

class predicates

monthCode:(string, month_code, numberOfDays)

determ (i, m(o,o), nd(o)) (i, m(o, o), o).

dayOfWeek:(integer, day) procedure (i, o).

calculateDay:( string Month, integer Day_of_the_month, year, day)

procedure (i, i, i, o).

clauses

monthCode("January", m(jan, 6), nd(31)) :- !.

monthCode("February", m(feb, 2), february ) :- !.

monthCode("March", m(mar, 2), nd(31)) :- !.

monthCode("April", m(apr, 5), nd(30)) :- !.

monthCode("May", m(may, 0), nd(31)) :- !.

monthCode("June", m(jun, 3), nd(30)) :- !.

monthCode("July", m(jul, 5), nd(31)) :- !.

monthCode("August", m(aug, 1), nd(31)) :- !.

monthCode("September", m(sep, 4), nd(30)) :- !.

monthCode("October", m(oct, 6), nd(31)) :- !.

monthCode("November", m(nov, 2), nd(30)) :- !.

monthCode("December", m(dec, 4), nd(31)) :- !.

dayOfWeek(0, sun) :- !.

dayOfWeek(1, mon) :- !.

dayOfWeek(2, tue) :- !.

dayOfWeek(3, wed) :- !.

dayOfWeek(4, thu) :- !.

dayOfWeek(5, fri) :- !.

dayOfWeek(6, sat) :- !.

dayOfWeek(_, err).

calculateDay(Month, MD, Year, D) :-

Y= Year-2000, % Берём две последние цифры Year.

monthCode(Month, m(_M, C), _), !, % Получаем код месяца.

S= Y+Y div 4+C+MD,

R= S mod 7, /* День недели как число между 0 (воскресенье) и 6 (суббота) */

dayOfWeek(R, D). % Получаем функциональный символ дня

calculateDay(_, _, _, err).

run():-

console::init(),

calculateDay("May", 3, 2005, R),

stdio::write("Day of the week: ", R), stdio::nl,

succeed(). % place your own code here

end implement func

goal

mainExe::run(func::run).

1Немецкий математик Эрнст Фридрих Фердинанд Цермело изобрёл запись множеств, которую мы использовали.

Соседние файлы в папке Лабы_ЭкспСист