Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Применения множественных выражений




Множественные выражения являются существенным дополнением к Прологу. Их использование вкупе с другими, уже рассмотренными методами программирования для многих задач приводит к искусным решениям. В этом разделе в качестве примеров представлены три программы: программа обхода графа в ширину, программа порождения ключевого слова в контекстном указателе.

В разд. 14.2 были рассмотрены три программы 14.8, 14.9 и 14.10 для обхода графа в глубину. Здесь обсуждаются эквивалентные программы для обхода графа в ширину.

 

connected (X,Y) ¬

Связь вершины X с вершиной Y в ориентированном ациклическом графе определяется предложением edge/2.

connected(X,Y) ¬ connected_bfs([X | Xs])\Xs,Y).

connected_bfs([ ] \ [ ], Y) ¬!, fail.

connected_bfs([X | Xs]\Ys, X).

connected_bfs([X | Xs] \ Ys, Y) ¬

find_all_dI(N,edge(X,N),Ys\Zs),

connected_bfs(Xs\Zs,Y).

 

Данные

edge(a,b). edge(a,c). edge(a,d). edge(a,e).

edge(f,i). edge(c,f). edge(c,g). edge(f.h).

edge(e.k). edge(d.j). edge(x,y). edge(y,z).

edge(z,x). edge(y.u). edge(z,v).

Программа 17.4. Программа и тестовые данные для проверки алгоритма обхода в ширину ориентированного ациклического графа.

 

Основным отношением является connected(X,Y), которое истинно, если вершины Х и Y связны. Это отношение определено в программе 17.4. Поиск в ширину реализуется посредством ведения такой очереди вершин, следуя которой происходит обход графа в ширину. Соответственно предложение connected вызывает отношение connected_bfs(Queue,Y), которое истинно, если Y принадлежит связному компоненту графа, представленному вершинами в очереди Queue.

При каждом обращении к предикату connectd_bfs текущая вершина извлекается из очереди, находится множество связанных с ней вершин, которые добавляются в конец очереди. Очередь представлена разностным списком. Кроме того, здесь используется множественный предикат find_all_dl. Если очередь пуста, то выполнение программы завершается отказом. Поскольку разностные списки являются неполными структурами данных, необходимо предусмотреть явную проверку пустоты очереди. В противном случае выполнение программы может не завершаться,

Рассмотрим факты edge в программе 17.4, представляющие граф, показанный на рис. 14.3 слева. Для них вопрос connected(a.X) дает решения b, с, d, e, f, g, j, k, h, i как результат обхода графа в ширину.

Программа 17.4, подобно программе 14.8, пригодна для обхода конечного дерева или ориентированного ациклического графа. В случае циклического графа выполнение программы не завершится.

 

connected(X. Y) ¬

Связь вершины Х с вершиной У в графе определяется предложением edge/ 2.

connected(X,Y) ¬ connected(X | Xs]\Xs, Y,[X]).

connected ([ ]\[ ], Y, Visited) ¬!, fail.

connected ([A | Xs]\Ys, A, Visited).

connected ([A | Xs]\Ys,B, Visited) ¬

set_of(N,edge(A,N),Ns),

filter([Ns, Visited, Visited],Xs\Ys,Xsl),

connected(Xsi, B, Visited1).

filter([N [ Ns], Visited, Visited l,Xs,Xsl)¬

rnember(N, Visited),

filter(Ns, Visited, Visitedl, Xs, Xs1).

filter([N|Ns],Visited,Xs\[N|Ys],Xs\Ys) ¬

not rnembcr(N,Visited),

filter(Ns,[N | Visited], Visitedl,Xs\Ys,Xsl).

filter([ ],V,V,Xs, Xs).

Программа 17.5. Проверка связности графа путем обхода в ширину.

 

По сравнению с программой 17.4 программа 17.5 более совершенна, в ней, в частности, ведется список просмотренных вершин графа. В конец очереди добавляются не все дочерние вершины, а только те, которые еще не просматривались, Такая проверка в программе 17.5 выполняется с помощью предиката filter.

На самом деле программа 17.5 является более мощной, чем ее эквивалент с обходом в глубину – программа 14.10. Она не только осуществляет корректный обход любого конечного графа, но с тем же успехом может использоваться и для обхода бесконечных графов. Полезно заметить, что расширения чистого Пролога необходимы для увеличения эффективности поиска на графах. Используя чистый Пролог, можно писать корректные программы поиска на конечных деревьях и ориентированных ациклических графах. Добавление отрицания позволяет реализовать корректный поиск на конечных графах с циклами, а множественные выражения необходимы для работы с бесконечными графами. На рис. 17.2 эти соображения представлены в сжатом виде.

Определение пути между двумя вершинами графа представляет собой несколько более сложную задачу, чем поиск в глубину. Вместе с каждой вершиной в очереди здесь необходимо хранить список вершин, по которым проходит путь, связывающий ее с исходной вершиной. Этот метод демонстрируется в программе 18.6 в следующей главе.

 

(1) Конечные деревья и ориентированные ациклические графы. Чистый Пролог.

(2) Конечные графы.

Чистый Пролог + отрицание.

(3) Бесконечные графы.

Чистый Пролог + множественные выражения + отрицание.

Рис. 17.2. Средства Пролога для решения различных задач поиска на графах.

 

В последнем примере этого раздела решается задача поиска ключевых слов в контексте. И вновь объединение недетерминированного программирования с программированием второго порядка позволяет с помощью простой Пролог-программы решить сложную задачу.

Нахождение ключевых слов в контексте связано с поиском всех вхождений множества ключевых слов в определенный текст и выделением контекстов, в которых они встречаются. Здесь будет рассмотрен следующий вариант этой общей задачи: «Для данного списка заголовков сформировать упорядоченный список всех вхождений в данные заголовки множества ключевых слов вместе с их контекстами».

Пример входных и ожидаемых выходных данных для такой программы представлен на рис. 17.4. Контекст описывается как вращение заголовка, конец которого отмечен вертикальной чертой «|». В рассматриваемом примере использован следующий набор «нетривиальных» ключевых слов: algorithmic, debugging, logic, problem, program, programming, prolog и solving.

В данной задаче подлежит вычислению отношение kwic(Titles,KwicTit1es), где Tub's- список заголовков, из которых должны быть выделены ключевые слова, а КwicTitles – отсортированный список ключевых слов в их контекстах. Предполагается, что входной и выходной тексты представлены в виде списков слов. В более общей программе должны быть предусмотрены предварительный шаг преобразования входного текста в свободной форме в списки слов, а также выдача результатов в удобном для чтения виде.

 

 

Вход: programming in prolog logic for problem solving logic programming algorithmic program debugging

Выход: algorithmic program debugging |, debugging | algorithmic program, logic for problem solving |, logic programming, |, problem solving | logic for, program debugging | algorithmic, programming in prolog |. programming | logic, prolog | programming in, solving | logic for problem

Рис17.4. Вход и выход для задачи поиска вхождений ключевых слов в контексте.

 

Рассмотрим поэтапное представление программы. Основа программы – недетерминированное описание вращения списка слов. С помощью предиката append ему можно дать следующее элегантное определение:

rotate(Xs,Ys) ¬ append(As,Bs,Xs). append! Bs,As.Ys).

Декларативно: Ys – вращение Xs, если Xs состоит из As, за которым следует Bs, а Ys состоит из Bs, за которым следует As.

Следующий этап связан с идентификацией отдельных слов как потенциальных ключевых слов. Это выполняется посредством выбора слова в первом вызове предиката append. Отметим, что следующее новое правило является примером предыдущего правила rotate:

rotate(Xs,Ys) ¬ append(As.[Key | Bs],Xs), append([Key | Bs].As,Ys).

Кроме того, это определение лучше предыдущего, поскольку в нем предусмотрено удаление одинаковых решений, когда один из расщепленных списков пуст, а другой – полон.

Следующее улучшение связано с более детальной проверкой потенциального ключевого слова. Предположим, что каждое ключевое слово Word определяется фактом вида keyword(Word). Решения в процессе rotate могут быть отфильтрованы так, чтобы воспринимались только те слова, которые идентифицированы как ключевые. Соответствующая версия рассматриваемого предложения имеет вид

rotate_and_filter(Xs,Ys) ¬

append(As,[Key | Bs],Xs), keyword(Key), append([Key | Bs],As,Ys).

Операционное поведение данной процедуры: она рассматривает все ключевые слова, отфильтровывая нежелательные альтернативы. Для максимизации эффективности программы в данном случае важен порядок целей.

В программе 17.7, окончательной версии интересующей нас программы, предусмотрены дополнительные средства для распознавания ключевых слов. Любое слово Word считается ключевым, если оно не специфицировано с помощью факта вида insignificant(Word) как незначащее. Кроме того, в процедуре выполняется вставка в конец заголовка маркера «|», отмечающего контекстную информацию. Это реализуется добавлением дополнительного символа во втором обращении к предикату append. Соответствующее предложение rotate_and_filter содержится в программе 17.7.

Наконец, для получения всех решений использован множественный предикат. Квантификация необходима повсем возможным заголовкам. Явным преимуществом использования предиката set_of является сортировка ответов. Полная программа для решения рассматриваемой задачи (программа 17.7) элегантный пример выразительной мощности Пролога. Для тестирования в программе использован предикат test_kwic/2.

 

kwic(Tites, КWTitles) ¬

КWTities – KWIC-индекс списка заголовков Titles.

kwic(Titles.KWTilles)¬

set_of(Ys,Xs ­ (member(Xs, Titles),

rotate_and_fiIter(Xs,Ys)),KWTitles).

rotate_and_filter (Xs, Ys) ¬

Ys – вращение списка Xs, такое, что первое слово Ys значимо, и знак '|' вставлен после последнего слова Xs.

rotate_and_filter(Xs,Ys) ¬

append (As, [Key | Bs],Xs),

not insignificant(Key),

append([Key,’|’ | Bs],As,Ys).

Словарь незначимых слов

insignificant(a). insignificant(the).

insignificant(in). insignificant (for).

Предложения и данные для тестирования

test_kwic(Books,Kwic) ¬

titles(Books,Titles),kwic(Titles,Kwic).

titles(lp, [[logic, for, problem,solving],

[logic, programming],

[algorithmic, program, debugging],

[programming, in, prolog]]).

Программа 17.7. Создание индекса в задаче поиска ключевых слов вместе с их контекстами.

 




Поделиться с друзьями:


Дата добавления: 2014-01-07; Просмотров: 270; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.023 сек.