Скачиваний:
16
Добавлен:
01.05.2014
Размер:
287.74 Кб
Скачать

Глава 2

1.

| ?-X is 10,Y is X*3.

Х=10

Y=30

| ?-X is 10, Y is X * 3, Y is 300.

нет

При вычислении третьей подцели последнего запроса переменная Y уже будет конкретизирована, поэтому данная подцель равнозначна провер­ке значения Y. В этом упражнении подчеркивается, что в Прологе отсут­ствует деструктивное присваивание.

2.

площадь (Основание, Высота, Площадь) : — Площадь is Основание * Высота.

| ?—площадь (10,2, П).

П=20

| ?-площадь (10, В, 20).

арифметическая ошибка

Данная программа не является обратимой.

4. Существует два простых решения. Первое из них по форме соответ­ствует процедуре "длина". Оно леворекурсивно и подсчитывает слова по пути назад от конца списка.

% + + найти_слово (Слово, [Слово | Список], Счетчик) :-

найти_слово (Слово, Список, СубСчетчик),

Счетчик is СубСчетчик + 1.

найти_слово (Слово, [ХСлово | Список], Счетчик) :-

найти_слово (Слово, Список, Счетчик).

найти_слово (_, [ ], 0) .

Второе решение является праворекурсивным. В нем используется до­полнительный аргумент, предназначенный для накопления суммы по мере продвижения к концу списка. Когда будет достигнут конец списка, накоп­ленная сумма будет передана четвертому аргументу. (Это решение будет более эффективным, чем предыдущее, для тех версий Пролога, где осущест­вляется оптимизация остаточной рекурсии; см. приложение IV.)

% + + +

найти-слово (Слово, [Слово ! Список], Накопитель, Счетчик) :-

НовНакопитель is Накопитель + 1,

найти_слово (Слово, Список, НовНакопитель, Счетчик).

найти_слово (Слово, [ХСлово \ Список], Накопитель, Счетчик) :-

найти_слово (Слово, Список, Накопитель, Счетчик).

найти-слово (_, [ ], Накопитель, Накопитель).

% пример запроса:

| ?- найти-слово (the, [the, dog, in, the, barn], О, С).

C=2

5. длина ([пусто | R], Счетчик) :-

длина (R, Счетчик).

длина ([F | R], Счетчик) :-

длина (R, ТекущСчетчик),

Счетчик is ТекущСчетчик + 1.

длина ([ ], 0).

6. Возможные ответы к этому упражнению рассматриваются в гл.4.

7.

всего ([кл.(_-, Тариф, Дни) | Остаток], Итого) : -

всего (Остаток, ТекущСумма),

Итого is ТекущСумма + Тариф * Дни.

всего ([ ], 0).

8.

родитель (генри, джек).

родитель (джек, ричард).

родитель (ричард, чарльз).

родитель (чарльз, джейн).

пред(Х,Y,[Х,Y]):-родитель(Х,Y).

пред(Х,Y, [Х | Остаток]) :-

родитель (X,Z),

пред(Z, Y, Остаток) .

10.

% +

дд_в_списокс (дд (Имя, Отд,Долж, Окл, Предыдущ, Последующ) ,

%

ИтогСписок) :—

дд_в_список (Предыдущ, ПредыдСписок),

дд_в_список (Последующ, ПоследСписок),

присоедишить (ПредыдСписок, [cл (Имя, Отд, Долж, Окл)|

ПоследСписок], ИтогСписок).

дд_в_список (end, [ ]).

11. В процедуре "обр_печать" при унификации заголовков фраз вы­полняется сопоставление с эталоном, которое определяет условия при­менения фраз. В процедуре "нпредок" нет сопоставления с эталоном при унификации заголовков фраз, поэтому интерпретатор должен активи­ровать тело фразы, чтобы определить, нужно ли использовать эту фразу.

Глава 3

1.

| ? путешествие (амтрак, нью_йорк, X, ),!,

путешествие (амтрак, X, Y, _).

2.

площадь (Основание, Высота, Площадь) :—

nonvar (Основание) > nonvar (Высота),

Площадь is Основание * Высота.

площадь (Основание, Высота, Площадь) :—

nonvar (Основание), nonvar (Площадь),

Высота is Площадь / Основание.

площадь (Основание, Высота, Площадь) :—

nonvar (Высота), nonvar (Площадь),

Основание is Площадь / Высота.

Если два из трех аргументов не будут конкретизированы, то задачу все равно можно решать, если воспользоваться процедурой, генерирующей це­лые числа. См. процедуру "ген_чисел" из приложения III.

3. Полное множество ответов должно состоять только лишь из ответов мери и бранен. Запрос А полон и неэффективен. Запрос Б неполон и неэф­фективен. Запрос В неполон и эффективен. Запрос Г и полон, и эффективен.

права (X) :-

шоферские_курсы (X),

возраст (X, 16).

права (X) :-

возраст (X, Возраст), Возраст > = 17.

4.

нью_йоркский_адрес (милфорд_плаза).

ныо_йоркский_адрес (конфуциус_плаза).

связывает (А, Б, такси) :—

нью_йоркский_адрес (А),

нью_ йоркский_адрес (Б ),

not (связывает (А, Б, автобус) ),

not (связывает (А, Б, поезд) ).

состояние (Машина, нормальное) :—

not (включен_аварийный_сигнал (Машина, Аварийныи_сигнал) ).

клиент (X,'AT&T') :-

имеет_телефон (X),

not (клиент (X, mci)),

not (клиент (X, sprint)).

5.

| ?- repeat,

write ('введите имя школьного товарища: '),

read (Имя),

( Имя = end % обход добавления факта

% "школьный_товарищ (end)".

;

assert (школьный_товарищ(Имя))

),

Имя = end,

!,

школьньй_товарищ (Имя),

write (Имя),nl,

fail.

6. Первый способ: база данных является множеством фактов.

сделка (смит, авиабилет, 139).

сделка (родригес, благотворительный_взнос, 25).

текущ_сумма (0).

% + -

сумма_сделки (Имя, Сумма) :—

сделка (Имя, __, Стоимость),

один_раз (retract (текущ_сумма (Текущ) )),

НовТекущ is Текущ + Стоимость,

assert (текущ_сумма (НовТекущ) ),

fail.

сумма_сделки (Имя, Сумма) :-

retract (текущ_ сумма (Сумма)),

assert (текущ_сумма (0) ).

Второй способ: база данных является списком структур. Для удобства проверки этот список хранится в программе в виде факта "список".

список ([сд (смит, авиабилет, 139),

сд (родригес, благотворительный_взнос, 25)]).

% + ?

р_сумма_сделки ([сд (Имя, __, Стоимость) | Остаток], Имя, Сумма) :-

р_сумма_сделки (Остаток, Имя, ТекущСумма),

Сумма is ТекущСумма + Стоимость.

р_сумма_сделки([сд(ХИмя,_ , Стоимость) | Остаток], Имя, Сумма) :—

ХИмя \== Имя,

р_сумма сделки (Остаток, Имя, Сумма).

р_сумма_сделки([ ],_, 0).

| ?— список (L), р_сумма_сделки (L, смит, Итого).

Итого =139

8.

список путешествий (

[п(амтрак, нью_йорк, бостон, поезд),

п(ндж_транзит, нью_йорк, принстон, поезд),

п(амтрак, бостон, портленд, поезд),

п(грейхаунд, бостон, портленд, автобус),

п(амтрак, нью_йорк, Вашингтон, поезд),

п(пиплз, нью_йорк, Вашингтон, самолет),

п(пиплз, бирлингтон, нью_йорк, самолет)]).

можно_путешествовать(ГородА, ГородБ, Список) :-

элемент (п(_, ГородА, ГородБ, _), Список).

можно_путешествовать(ГородА, ГородБ, Список) :-

элемент (п (_, ГородА, ГородВ, _), Список),

можно_путешествовать(ГородВ, ГородБ, Список).

|?— список_путешествий (СП),

можно_путешествовать(нью_йорк, портленд, СП).

9.

% Многие Один группа0 (генри, компиляторы).

группа0(нэнси, компиляторы).

группа0 (сюзан, сети).

группа (Имя, Группа) :~

nonvar (Имя),

группа0 (Имя, Группа),!.

группа (Имя, Группа) :—

vаг(Имя),

группа0 (Имя, Группа).

группа (Имя, Группа) :~

not (группа0 (Имя, Группа) ),

( vаг(Имя),

write ('имя?'),

read (Имя),

;

nonvar (Имя)

),

( var( Группа),

write ('группа? '),

read (Группа),

; nonvar (Группа)

),

assert (группа0 (Имя, Группа)).

11.

:-ор (500, xfy, —). :-

op(499,xfy, ->).

можно_путешествовать5 (А, Б, (А— Вид_тр—>Б)) :—

путешествие (_, А, Б, Вид_тр).

можно_путешествовать5(А, Б, (А—Вид_тр— >Рпуть)) :—

путешествие (_, А, В, Вид_тр),

можно_путешествовать5 (В, Б, Рпуть).

Гл а в а 4

1. Ниже приводятся новые версии базы данных и процедур, в которых учитывается расстояние.

% Из В Транспорт Мили

путешествие (манхэттен, ньюарк, автобус, 15).

путешествие (манхэттен, куинс, жел_дорога, 5).

путешествие (ньюарк, бронкс, автомобиль, 25).

путешествие (бронкс, куинс, автобус, 8)

путешествие (манхэттен, бронкс, метро, 4).

путешествие (ньюарк, принстон, автомобиль, 35).

путешествие (манхэттен, принстон, автобус, 50).

% Обеспечение симметрии запросов к базе данных

% ''путешествием"

сим_путешествие (А, Б, Вид_тр, Мили) :-

путешествие (А, Б, Вид_тр, Мили).

сим_путешествие (А, Б, Вид_тр, Мили) : —

путешествие (Б, А, Вид_тр, Мили).

% . + + + -

тснр_путешествовать3 (След, А, Б, Мили—м (Вид_тр, Б)) :— % (1)

А\==Б,

сим путешествие (А, Б, Вид_тр,Мили).

тснр_путешествоватьЗ(След, А, Б, Мили—м(Вид_тр1,В,Вид_тр2) :- % (2)

А \ == Б,

сим_путешествие(А, В, Вид_тр1, Мили1), % генерировать В

not (элемент (В, След) ), % проверить В

тснр_путешествовать3 ([В | След], В, Б, Мили2—Видтр2),

Мили is Мили1 + Мили2.

Рекурсивное решение:

р_наилучший_маршрут(А, Б, Маршрут) :—

findall (Вид_тр,

тснр_путешествовать3 ([ ], А, Б, Вид_тр),

Список),

keysort (Список, ОрсортСписок),

ОтсортСписок = [Маршрут [ _ ] •

Решение, в котором используется поиск с возвратом:

оптимальный_маршрут (_, 100000).

наилучший_маршрут(А, Б, Маршрут) :—

тснр_путешествовать3 ([ ], А, Б, Мили—Маршрут),

один_раз (оптимальный_маршрут(ОптМаршрут, ОптМили)),

( Мили < ОптМили,

один_ раз (retract (оптимальный_маршрут(, _))) ,

assert (оптимальный_маршрут (Маршрут, Мили))

;

Мили>= ОптМили

),

fail.

наилучший_маршрут(А, Б, Маршрут) :-

retract (оптимальный_маршрут (Маршрут, )),

assert (оптимальный_маршрут(_, 100000)).

Если в Вашей версии Пролога достаточно эффективно реализован встроен­ный предикат "key sort", то рекурсивная версия программы будет выпол­няться более быстро. Версия программы в которой используется поиск с возвратом, потребует меньшего объема памяти. Рекурсивное решение осно­вывается на подходе к программе с позиций потока данных, а решение, в котором используется поиск с возвратом, — на бихевиористическом подходе.

2. Нижеследующее правило "можно_запрашивать" охватывает случай, когда пункт отправления неизвестен:

% неизвестен пункт отправления:

можно_запрашивать (путешествие (А, Б> Вид_тр),

'введите пункт отправления: ',

А):-

non var (Вид_тр), non var (Б).

Далее приводится версия процедуры "найти_или_спросить", которая может работать с любым количеством неизвестных аргументов. Вторым аргументом факта "можно_запрашивать2" является список подсказок — по одной на каждый аргумент факта "путешествие".

можно_запрашивать2 (путешествие (Исх_пункт, Пункт_назнач, Вид_тр),

['откуда?', 'куда?', 'вид транспорта?'']).

найти_или_спросить2 (Запрос) :- Запрос.

найти_или_спросить2 (Запрос) :-

not(3anpoc), % это правило вступает в силу, если

% запрос терпит неудачу

можно_запрашивать2 (Запрос, СписокПодсказок),

Запрос = .. [Пред | СписокАрг],

проверить_каждый (СписокАрг, СписокПодсказок),

assert (Запрос).

проверить_ каждый ([Арг | СписокАрг],

[Подсказка ; СписокПодсказок]) :-

( var (Арг),

write (Подсказка),

read (Арг)

;

nonvar (Арг)

),

!, проверить_каждый (СписокАрг, СписокПодсказок).

проверить каждый ([ ], _).

Соседние файлы в папке Гл.6,7,Прилож.,Допол