Шаг 58.
Основы логического программирования.
Основные предикаты управления строкой

    На этом шаге мы рассмотрим основные предикаты управления строкой.

    Строки и их обработка подчиняются определенным правилам. Так, в строках Пролога обратный слэш (\) является управляющим символом, позволяющим вставлять в строки символы, которых нет на клавиатуре.

    Предикаты, описываемые на этом шаге, являются основой обработки в Прологе; они служат для нескольких целей:

Предикат frontchar/3

    Предикат 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/3

    Предикат 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).
то после выполнения 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/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)

    По крайней мере два параметра должны быть связаны перед тем, как вы вызываете 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/2

    Предикат str_len решает следующие задачи: определяет или проверяет длину строки или возвращает строку пробелов заданной длины. Он имеет формат:

   str_len(StringArg,Length) % (i,o), (i,i), (o,i)

    Предикат str_len связывает переменную Length с длиной строки StringArg или проверяет, имеет ли StringArg данную длину Length. Length - это беззнаковое целое. В версии предиката с третьим потоком str_len возвращает строку пробелов данной длины, что может быть использовано для распределения буферов и других операций.

Предикат isname/1

    Предикат isname проверяет, является ли аргумент допустимым именем согласно синтаксису Пролога, и имеет формат:

   isname(String) % (i)

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

Предикат format/*

    Предикат format выполняет преобразования, аналогичные writef, но format выдает результат в виде строковой переменной.

   format(OutputString,FormatString,Arg1,Arg2,Arg3, ..., ArgN) %(o,i,i,i,...,i)

    На следующем шаге мы рассмотрим преобразование типов.




Предыдущий шаг Содержание Следующий шаг