logo search
TurboProlog / Документация / TOM_1

Примеры.

1. Данный пример показывает, как объявление доменов помогает доку-

ментировать ваши предикаты. Необходимо объявить предикат, раскрывающий

следующее предложение естественного языка:

Франк - мужчина, которому 45 лет.

Используя стандартные домены, вы можете так объявить соответствующий

предикат:

person (symbol,symbol,integer)

В большинстве случаев такое объявление будет работать очень хорошо.

Однако предположим, что несколько месяцев спустя после написания програм-

мы, вы решили скорректировать ее. Но уже через шесть месяцев подобное об-

ъявление этого предиката абсолютно ничего вам не скажет. И напротив, дек-

ларация этого же предиката, представленная ниже, поможет вам разобраться

в том, что же представляют собой аргументы данного предиката:

domains

name,sex=symbol /*имя,пол*/

age =integer /*возраст*/

predicates

person (name,sex,age)

Одним из главных преимуществ объявления собственных доменов является

то, что Турбо Пролог может отслеживать ошибки типов, как, например, при

следующей очевидной ошибке:

same_sex (X,Y):-

person (X,Sex,_),

person (Sex,X,_).

Несмотря на то, что и "name" и "sex" описываются как symbol, они не

эквивалентны друг другу. Это и позволяет Турбо Прологу определить ошибку

в случае, если вы перепутаете их. Данная особенность очень полезна, осо-

бенно в случаях, когда ваши программы очень велики и сложны.

Вы можете пожелать узнать, почему же мы не можем использовать специ-

альные домены для объявления всех аргументов, ведь такие домены привносят

намного больше смысла в обозначение аргументов. Ответ заключается в том,

что аргументы с типами из специальных доменов не могут смешиваться между

собой, даже если эти домены одинаковы! Именно поэтому, несмотря на то,

что name и sex принадлежат одному домену (symbol), - они не могут смеши-

ваться.

2. Следующий пример программы приведет (при его загрузке) к ошибке

типа:

/* Программа CH04EX01.PRO */

domains

product, sum = integer

predicates

add_em_up(sum, sum, sum)

multiply_em(product, product, product)

clauses

add_em_up(X, Y, Sum):- Sum = X + Y.

multiply_em(X, Y, Product):- Product = X * Y.

Эта программа выполняет две операции: складывает и умножает. Зададим

ей следующую цель:

add_em_up(32, 54, Sum).

Турбо Пролог ответит:

Sum = 86

1 Solution

что является суммой двух целых чисел, которые вы передали в програм-

му.

С другой стороны эта же программа (с помощью предиката multiply_em)

умножает два аргумента. Поэкспериментируем. Если вам нужно узнать произ-

ведение 13 и 31, то введите цель:

multiply_em(31, 13, Product).

Турбо Пролог вернет вам корректный результат:

Product = 403

1 Solution

А теперь предположим, что вам понадобилась сумма 42 и 17; цель для

этого выглядит так:

add_em_up(42, 17, Sum).

Теперь же вы хотите удвоить произведение 31 на 17 и, поэтому, задае-

те следующую цель:

multiply_em(31, 17, Sum), add_em_up(Sum, Sum, Answer).

Вы ждете, что Турбо Пролог ответит:

Sum = 527, Answer = 1054

1 Solution

Однако, вместо этого вы получите ошибку типа. Это случится из-за то-

го, что вы попытались передать результирующее значение предиката

multiply_em (которое относится к домену product) в качестве первого и

второго аргументов в предикат add_em_up, которые относятся к домену sum.

Это и привело к ошибке, т.к. домен product отличается от домена sum. И

хотя оба эти домена, в действительности, соответствуют типу integer - это

различные домены.

Поэтому, если переменная в предложении используется более, чем в од-

ном предикате, она должна быть одинаково объявлена в каждом из этих пре-

дикатов. Очень важно, чтобы вы полностью поняли концепцию описанной здесь

ошибки типа; знание этой концепции позволит вам избегать сообщений об

ошибках компиляции.

3. В свете еще более полного понимания того, как вы можете использо-

вать объявления доменов для отслеживания ошибок типа, рассмотрим следую-

щий пример программы:

/* Программа CH04EX02.PRO */

domains

brand, color = symbol

age, price = integer

mileage = real

predicates

car(brand, mileage, age, color, price)

clauses

car(chrysler, 130000, 3, red, 12000).

car(ford, 90000, 4, gray, 25000).

car(datsun, 8000, 1, red, 30000).

Предикат car, объявленный в секции predicates, имеет 5 аргументов.

Два из них относятся к доменам целого типа age и price (это могут быть

числа от -32,768 до +32,767). Остальные домены - это: mileage действи-

тельного типа и brand и color - символьного типа.

Загрузите и запустите данную программу и попытайтесь вычислить, по

очереди, следующие цели:

car(renault, 13.0, 40000, red, 12000).

car(ford, 90000, gray, 4, 25000).

car(1, red, 30000, 80000, datsun).

Каждая из этих целей приведет к ошибке типа. В первом случае, напри-

мер, это произойдет из-за того, что age должен быть целым. Следовательно,

Турбо Пролог сможет легко определить, что при вводе этой цели объекты

mileage и age (в предикате car) были перепутаны местами. Во втором случае

были перепутаны age и color, а в третьем - попытайтесь найти ошибку са-

мостоятельно.