Скачиваний:
201
Добавлен:
17.06.2016
Размер:
2.69 Mб
Скачать

Упражнение

Примените предложения, определяющие member в программе CH08EX06.PRO

и перепишите предложения для предиката even_member, который удовлетворяет

целевому утверждению:

even_member(2, [1, 2, 3, 4, 5, 6]).

Предикат должен также продемонстрировать результат:

X=2

X=4

X=6

3 Solutions

для целевого утверждения:

even_member(X, [1, 2, 3, 4, 5, 6]).

Немедленный поиск всех решений

В Главе 7 сравнивались поиск с возвратом и рекурсия, как способы вы-

полнения повторяющихся процедур. У рекурсии преимущества потому, что в

отличие от поиска с возвратом, она передает информацию (через параметры)

от одного рекурсивного вызова к следующему. Поэтому рекурсивная процедура

может хранить дорожку промежуточных результатов или отчетов, по мере того

как она выполняется.

Но есть одна вещь, которую поиск с возвратом может делать, а рекур-

сия - нет, это поиск всех альтернативных решений в целевом утверждении.

Таким образом, вы можете оказаться в затруднении. Вам нужны все решения

для целевого утверждения, но они нужны все сразу, как часть единой сос-

тавной структуры данных. Что делать?

К счастью, в Турбо Прологе есть возможность выйти из этого положе-

ния. Встроенный предикат findall использует целевые утверждения в качест-

ве одного из своих аргументов и собирает все решения для этого целевого

утверждения в единый список. У предиката findal три аргумента:

'Первый аргумент, VarName (имя переменной), определяет параметр, ко-

торый необходимо собрать в список.

'Второй аргумент, mypredicate (мой предикат), определяет предикат,

из которого надо собрать значения.

'Третий аргумент, ListParam (список параметров), содержит список

значений, собранных методом поиска с возвратом. Заметьте, что дол-

жен быть определенный пользователем тип, которому принадлежит зна-

чения ListParam.

Программа CH08EX08.PRO использует findall для печати среднего воз-

раста группы людей.

/*Программа CH08EX08.PRO - использование findall*/

domains

name, address = string

age = integer

list = age*

predicates

person(name, address, age)

sumlist(list, age, integer)

goal

findall(Age, person(_, _, Age), L),

sumlist(L, sum, N),

Ave = Sum/N,

write("Average =", Ave), n1.

clauses

sumlist([], 0, 0).

sumlist([H|T], Sum, N) :-

sumlist(T, S1, N1), Sum=H+S1, N=1+N1.

person("Sherlock Holmes", "22B Baker Street", 42).

person("Pate Spiers", Art. 22, 2lst Street", 36).

person("Mery Darrow", "Suite 2, Cmega Home", 51).

Предложение findall в этой программе создает список L, в котором

собраны все возрасты, полученные из предиката person. Если бы вы захотели

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

следующее подцелевое утверждение:

findall(Who, person(Who, _, 42), List)

Соседние файлы в папке Документация