Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ФиЛП_материалы / Материалы / Prolog / ПособиеПролог.doc
Скачиваний:
55
Добавлен:
01.06.2015
Размер:
449.02 Кб
Скачать

9. Работа с именами и строками

Имена и строки в программах авто­матически преобразуются друг в друга (компилятор VIP выдает предупреждение), и все предикаты, определенные для строки, могут быть применены и к символическим именам. Доступ к именам осуществляется быстрее, чем к строкам, обработка которых ведется посимвольно.

Ниже мы рассмотрим наиболее часто используемые встроенные предикаты для работы с именами и строками, имеющимися в Visual Prolog 5.1.

1.Предикаты преобразования типов из string в другие встроенные и наоборот.

str_int(String, Int) /* (i, o), (o, i), (i, i)*/

преобразует строку String, содержащую целое чис­ло, в целое число Int; например,

GOAL

str_ int ("123", X).

X=123

GOAL

str_int (“asd”, X) .

No solution

б) str_char(String, Char) /* (i, o), (o, i), (i, i) */

преобразует строку из одного символа в символ.

в) str_real(String, Real) преобразует строку, содержащую вещест­венное число, в вещественное число.

str_real ("12.3", 12.3)

2. Предикат frontchar/З используется для выделения первого символа строки:

frontchar(Строка, Символ, Остаток) /* (i,o,o) (i,i,o) (i,o,i) (i,i,i) (o,i,i) */

Предикат связывает три параметра: первый символ Строка заносится в Символ, оставшаяся часть – в Остаток. Согласно flow patterns предикат frontchar/З может использоваться для соединения строки и символа (о, i, i), разделения строки на символ и строку (i,o,o), для по­символьного просмотра и анализа строки и т. п.

3. Предикат fronttoken/З разделяет текст или строку Строка на первую лексему Слово и оставшуюся часть текста или строки Остаток, и имеет формат:

fronttoken(Строка, Слово, Остаток) /* (i,o,o) (i,i,o) (i,o,i) (i,i,i) (o,i,i) */

(Лексема - слово, знак препинания, число.)

Предикаты frontchar и fronttoken используются для организации рекурсии по схеме, аналогичной процедурам работы со списками: аргументом рекурсивного вызова является Остаток; вызовы повторяются до тех пор, пока Остаток не станет пустой строкой.

В качестве примера приведем программу, преобразующую заданную строку в список символов (процедура «строка_список») и в список лексем (процедура «строка_список_имен»).

DOMAINS

список1 = char* /* Список символов */

список 2 = symbol* /* Список имен */

PREDICATES

nondeterm строка_список (string, список1)

nondeterm строка_список_имен(string, список 2)

CLAUSES

строка_список ("",[ ]):-!. /* терминальный пре

дикат*/

строка_список(S,[H|T]) :-frontchar(S, H, S1),

строка_список (S1, T).

строка_список_имен ("", [ ]):-!./* терминальный

предикат*/

строка_список_имен(S,[H|T]):-fronttoken(S, H,

SI), строка_список_имен (SI, T).

GOAL

Y="Языки Lisp и Prolog",

строка_список(Y, X), write(X),

строка_список_имен (Y, Z), write(Z).

X=['Я','з','ы','к','и',' ', 'L','i','s','p',' ','и','P','r','o','l','o','g'],

Z=["Языки","Lisp","и","Prolog"]

Ниже приведена программа, распознающая в заданном тексте лексемы, символы и числа и возвращающая соответствующий список с элементами различных типов(см. разд. 7). Так, текст “Год рождения Иванова П. - 1990” будет преобразован в список

[name("Год"), name("рождения"), name("Иванова"), name("П"),

char('.'), char('-'), numb(1990)].

DOMAINS

лексема = numb(integer); name(string);

char(char) /* смешанный список */

список = лексема *

PREDICATES

nondeterm scanner(string, список)

nondeterm выделить (string, лексема)

CLAUSES

scanner("",[]). %терминальныйпредикат

scanner(Str,[H|Rest]):- fronttoken(Str, L, Str1), выделить(L, H), scanner(Str1, Rest).

выделить (S,name(S)):-isname(S).

/*Стандартный предикат isname проверяет, является ли аргумент строкой */

выделить (S,numb(N)):-str_int(S,N).

выделить (S,char(C)):-str_char(S, C).

GOAL

write("Введите текст:"),nl,

readln(Text),nl, scanner(Text,List),write(List).

4. Предикат concat/З соединяет две строки в одну String3:

concat(Stringl, String2, String3) /* (i,i,o) (i,o,i) (i,x,i) (o,i,i) */

GOAL

соnсаt("Моя", "внучка", String3).

String3="Моя внучка".

5. Предикат str_len/2 используется для определения длины строки или для создания строки пробелов заданной длины. Например, при доказа­тельстве цели str_len("строка", Dlina) получим Dlina = 6, а для цели str_len(X, 3) результат X = " ".

6. Предикаты выделения части строки.

subchar(String, Position, Char) возвращает символ Char строки String, находящийся в заданной позиции Position;

substring(Str_in, Pos, Len, Str_out) копирует из строки Str_in подстроку Str_out, начиная с позиции Pos длиной Len.

GOAL

substring(“Прощай”, 4, 3, Str_out).

Str_out = "щай".

searchchar(String, Char, Position) возвращает позицию Position перво­го местонахождения символа Char в строке String.

7. Сравнение символов, строк и символических имен.

При сравнении символов происходит сравнение их кодов.

GOAL

'л' > 'т'

При сравнении строк последовательно сравнива­ются символы в соответствующих позициях. Как только найдены отли­чающиеся символы, так результат определяется по сравнению их кодов.

GOAL

"варежка" > "вареник"

Сравнение символических имен не может выполняться непосредственно. Сначала символи­ческие имена надо связать с переменными, а затем сравнивать последние. Пример успешного сравнения:

GOAL

PI = холод, Р2 = холодный, Р1 < Р2.

Соседние файлы в папке Prolog