На этом шаге мы рассмотрим основные предикаты управления строкой.
Строки и их обработка подчиняются определенным правилам. Так, в строках Пролога обратный слэш (\) является управляющим символом, позволяющим вставлять в строки символы, которых нет на клавиатуре.
Предикаты, описываемые на этом шаге, являются основой обработки в Прологе; они служат для нескольких целей:
Предикат frontchar действует согласно равенству:
String1 = объединение Char и String2
и имеет следующий формат:
frontchar(String1,Char,String2) %(i,o,o) (i,i,о) (i,o,i) (i,i,i) (o,i,i)
Предикат frontchar имеет три аргумента: первый из них - строка, второй - симвoл (первый символ первой строки), третий - остаток первой строки.
Предикат frontchar можно использовать для расщепления строки в последовательность символов или для создания строки из последовательности символов, а также проверки символов в строке. Если аргумент String1 связан со строкой нулевой длины, то предикат завершается неуспешно.
В следующей программе frontchar используется для определения предиката, преобразующего строку в список символов.
Задайте цель:
string_chlist("ABC",Z)
После обработки этого целевого утверждения Z будет связано со списком ['A','В','С'].
domains charlist=char* predicates string_chlist(string,charlist) clauses string_chlist("",[ ]):-!. string_chlist(S,[H |T]):- frontchar(S,H,S1), string_chlist(S1,T).
Предикат fronttoken выполняет три взаимосвязанные функции, в зависимости от типа аргументов, который используется для обращения к нему.
fronttoken(String1,Token,Rest) %(i,о,о) (i,i,о) (i,o,i) (i,i,i) (o,i,i)
В случае потока (i,o,o) fronttoken находит первую лексему в String1, связывает ее с Token, а остаток String1 связывает с Rest. Варианты потока (i,i,o), (i,o,i), а также (i, i, i) служат для проверки: если связанные аргументы соответствуют частям String1 (первой лексеме, всему, что находится после первой лексемы, или же и тому и другому), то fronttoken завершается успешно, в противном случае - неуспешно.
В случае если использован поток (о,i,i), предикат создает объединение Token и Rest, связывая String1 с результатом.
Последовательность знаков является лексемой, если она представляет собой:
Предикат fronttoken отлично приспособлен для разбиения строки на лексические символы.
Пример в следующей программе иллюстрирует способ использовании предиката fronttoken для разбития предложения на список имен. Если задать целевое утверждение:
string_namelist("bill fred tom dick harry",X).
[bill,fred,tom,dick,harry]
domains namelist=name* name=symbol predicates string_namelist(string,namelist) clauses string_namelist(S,[H |T]):- fronttoken(S,H,S1),!, string_namelist(S1,T). string_namelist(_, []).
Предикат frontstr расщепляет String1 на две части. Синтаксис предиката:
frontstr(NumberOfChars,String1,StartStr,EndStr) % (i,i,o,o)
где StartStr содержит NumberOfChars первых символов из String1, a EndStr содержит остаток. При обращении к frontstr первые два параметра должны быть связанными, а последние два - свободными.
Предикат concat устанавливает, что строка String3 является результатом сцепления String1 и String2. Он имеет форму:
concat(String1,Sring2,String3) % (i,i,o), (i,o,i), (o,i,i), (i,i,i)
По крайней мере два параметра должны быть связаны перед тем, как вы вызываете concat; это означает, что этот предикат всегда дает только одно решение (другими словами, он - детерминированный). Например, мы вызываем
concat("croco","dile",In_a_while)
связывая In_a_while с crocodile. В другом случае, если See_ya_later связано, то вращение к предикату
concat("alli","gator",See_ya_later)
завершается успешно, только если See_ya_later является связанным с alligator.
Предикат str_len решает следующие задачи: определяет или проверяет длину строки или возвращает строку пробелов заданной длины. Он имеет формат:
str_len(StringArg,Length) % (i,o), (i,i), (o,i)
Предикат str_len связывает переменную Length с длиной строки StringArg или проверяет, имеет ли StringArg данную длину Length. Length - это беззнаковое целое. В версии предиката с третьим потоком str_len возвращает строку пробелов данной длины, что может быть использовано для распределения буферов и других операций.
Предикат isname проверяет, является ли аргумент допустимым именем согласно синтаксису Пролога, и имеет формат:
isname(String) % (i)
Имя начинается с буквы алфавита или символа подчеркивания, за которым следует любое число букв, цифр и символов подчеркивания. Предыдущие и последующие пробелы игнорируются.
Предикат format выполняет преобразования, аналогичные writef, но format выдает результат в виде строковой переменной.
format(OutputString,FormatString,Arg1,Arg2,Arg3, ..., ArgN) %(o,i,i,i,...,i)
На следующем шаге мы рассмотрим преобразование типов.