|
L=TailLength + 1.
51. Основные предикаты управления строкой.
Предикаты, описываемые на этом шаге, являются основой обработки в Прологе; они служат для нескольких целей:
· разделение строки на подстроки и лексемы;
· построение строки из определенных подстрок и лексем;
· проверка, состоит ли строка из определенных подстрок или лексем;
· возврат лексемы или списка лексем из данной строки;
· проверка или определение длины строки;
· создание пустой строки определенной длины;
· проверка, является ли строка термином, определенным в Прологе;
· форматирование переменного числа аргументов в строковую переменную.
Предикат frontchar/3
Предикат frontchar действует согласно равенству:
String1 = объединение Char и String2
Предикат fronttoken/3
Предикат fronttoken выполняет три взаимосвязанные функции, в зависимости от типа аргументов, который используется для обращения к нему.
fronttoken(String1,Token,Rest) %(i,о,о) (i,i,о) (i,o,i) (i,i,i) (o,i,i)
Предикат frontstr/4
Предикат frontstr расщепляет String1 на две части. Синтаксис предиката:
frontstr(NumberOfChars,String1,StartStr,EndStr) % (i,i,o,o)
где StartStr содержит NumberOfChars первых символов из String1, a EndStr содержит остаток. При обращении к frontstr первые два параметра должны быть связанными, а последние два - свободными.
Предикат concat/3
Предикат concat устанавливает, что строка String3 является результатом сцепления String1 и String2. Он имеет форму:
concat(String1,Sring2,String3) % (i,i,o), (i,o,i), (o,i,i), (i,i,i)
Предикат isname/1
Предикат isname проверяет, является ли аргумент допустимым именем согласно синтаксису Пролога, и имеет формат:
isname(String) % (i)
Имя начинается с буквы алфавита или символа подчеркивания, за которым следует любое число букв, цифр и символов подчеркивания. Предыдущие и последующие пробелы игнорируются.
Предикат format/*
Предикат format выполняет преобразования, аналогичные writef, но format выдает результат в виде строковой переменной.
format(OutputString,FormatString,Arg1,Arg2,Arg3,..., ArgN) %(o,i,i,i,...,i)
52. Преобразования типов.
На этом шаге мы рассмотрим стандартные предикаты, предназначенные для преобразования типов. Это предикаты char_int, str_char, str_int, str_real, upper_lower.
Предикат char_int/2
Предикат char_int преобразует символ в целое число или целое в символ и имеет формат:
char_int(Char,Integer) % (i,o), (o,i), (i,i)
Предикат str_char/2
Предикат str_char преобразует строку, содержащую один и только один символ, в символ или символ в строку из одного символа; предикат имеет формат:
str_char(String,Char) % (i,o), (o,i), (i,i)
Предикат str_int/2
Предикат str_int преобразует строку, содержащую целое число, в его текстовое представление и имеет формат:
str_int(String,Integer) % (i,o), (o,i), (i,i)
Предикат str_real/2
Предикат str_real преобразует строку в вещественное число или вещественное число в строку и имеет формат:
str_real(String,Real) % (i,o), (o,i), (i,i)
Предикат upper_lower/2
Предикат upper_lower преобразует строку, все символы (или часть символов) которой являются символами верхнего регистра, в строку соответствующих символов нижнего регистра, и наоборот. Формат предиката:
upper_lower(Upper,Lower) % (i,o), (o,i), (i,i)
53. Множества.
Список, который не содержит повторных вхождений элементов называется множеством.
Начнем с написания предиката, превращающего произвольный список во множество. Для этого нужно удалить все повторные вхождения элементов. При этом мы воспользуемся предикатом delete_all. Предикат будет иметь два аргумента: первый – исходный список (возможно, содержащий повторные вхождения элементов), второй – выходной (то, что остается от первого аргумента после удаления повторных вхождений элементов).
Предикат будет реализован посредством рекурсии. Базисом рекурсии является очевидный факт: в пустом списке никакой элемент не встречается более одного раза.
Шаг рекурсии позволит выполнить правило: чтобы сделать из непустого списка множество, нужно удалить из хвоста списка все вхождения первого элемента списка, если таковые вдруг обнаружатся. После выполнения этой операции первый элемент гарантированно будет встречаться в списке ровно один раз. Для того чтобы превратить во множество весь список, остается превратить во множество хвост исходного списка. Для этого нужно только рекурсивно применить к хвосту исходного списка наш предикат, удаляющий повторные вхождения элементов. Полученный в результате из хвоста список с приписанным в качестве головы первым элементом и будет требуемым результатом.
Закодируем наши рассуждения.
list_set([],[]). /* пустой список является списком
в нашем понимании */
list_set ([H|T],[H|T1]):–
delete_all(H,T,T2),
/* T2 — результат удаления
вхождений первого элемента
исходного списка H из хвоста T */
list_set (T2,T1).
/* T1 — результат удаления повторных вхождений элементов из списка T2*/
Например, если применить этот предикат к списку [1,2,1,2,3, 2,1], то результатом будет список [1,2,3].
Заметим, что в предикате, обратном только что записанному предикату list_set и переводящем множество в список, нет никакой необходимости по той причине, что наше множество уже является списком.
54. Раздел предложений.
В раздел clauses (предложений) вы помещаете все факты и правила, составляющие вашу программу. Основное внимание на этом шаге было уделено рассмотрению предложений (фактов и правил) программы: что они означают, как их писать и т. д.
Если вы поняли, что собой представляют факты и правила и как их записывать в Прологе, то вы знаете, что все предложения для каждого конкретного предиката в разделе clauses должны располагаться вместе. Последовательность предложений, описывающих один предикат, называется процедурой.
Пытаясь разрешить цель, Пролог (начиная с первого предложения раздела clauses) будет просматривать каждый факт и каждое правило, стремясь найти сопоставление. По мере продвижения вниз по разделу clauses, он устанавливает внутренний указатель на первое предложение, являющееся частью пути, ведущего к решению. Если следующее предложение не является частью этого логического пути, то Пролог возвращается к установленному указателю и ищет очередное подходящее сопоставление, перемещая указатель на него (этот процесс называется поиск с возвратом).
55. Раздел предикатов.
Если в разделе clauses программы на Прологе вы описали собственный предикат, то вы обязаны объявить его в разделе predicates (предикатов); в противном случае Пролог не поймет, о чем вы ему "говорите". В результате объявления предиката вы сообщаете, к каким доменам (типам) принадлежат аргументы этого предиката.
Предикаты задают факты и правила. В разделе же predicates все предикаты просто перечисляются с указанием типов (доменов) их аргументов. Эффективность работы Пролога значительно возрастает именно из-за того, что вы объявляете типы объектов (аргументов), с которыми работают ваши факты и правила.
Дата добавления: 2015-07-20; просмотров: 110 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Головы и хвосты | | | Имена предикатов |