Одесский национальный университет им. И.И.Мечникова Министерство науки и образования Украины
Лабораторная работа №3
по курсу «Специализированные языки программирования»
выполнил студент III курса гр. МОКС
Свиридов Артём
Одесса 2012
Цель работы: приобретение навыков работы со строками в Прологпрограммах.
Задание 1.
Написать программу, которая по введенной строке определяет:
a.Количество цифр в строке.
b.Количество слов в строке. Слова отделяются одним или несколькими символами "пробел", ",", ".", ";", "-", ”!”, ”?”.
c.Удаляет лишние пробелы между словами.
d.меняет все вхождения слова "пес" на слово "кот"
e.Определяет количество чисел в строке
f.Находит в строке самое короткое слово.
g.Удаляет из строки гласные буквы.
Интерфейс с пользователем должен быть оформлен в виде простого меню.
Код программы на Visual Prolog 7.3:
implement main
open core, console, string
constants
className = "main". classVersion = "".
clauses
classInfo(className, classVersion).
class predicates
count_fig : (string,integer) procedure(i,o). count_fig : (string, integer, integer) procedure(i,i,o). count_numbers : (string,integer) procedure(i,o).
count_numbers : (string, integer, integer) procedure(i,i,o). count_words : (string,integer) procedure(i,o). count_words : (string, integer, integer) procedure(i,i,o). del_spaces : (string,string) procedure(i,o).
del_vowels : (string,string) procedure(i,o). dog_to_cat : (string, string) procedure(i,o). min_word : (string,string) procedure(i,o).
min_word_len : (string,integer,integer,integer) procedure(i,i,i,o). findmw : (string,integer,string) procedure(i,i,o).
is_numb : (char) determ(i). is_delim : (char) determ(i). is_vow : (char) determ(i). menu : (string) procedure(i).
menu : (string,integer) procedure(i,i). do_it : (string,char,integer) procedure(i,i,i).
clauses
is_numb(A) :- A>='0', A<='9', !. is_numb(_) :- fail.
is_delim(A) :- A='.' or A=',' or A=' ' or A=';' or A=':' or A='?' or A='!' or A='-', !. is_delim(_) :- fail.
is_vow(A) :- A='a' or A='e' or A='i' or A='o' or A='u' or A='а' or A='е' or A='ё' or A='и' or A='о' or A='у' or A='ы' or A='э' or A='ю' or A='я' or A='A' or A='E' or A='I' or A='O' or A='U' or A='А' or A='Е' or A='Ё' or A='И' or A='О' or A='У' or A='Ы' or A='Э' or A='Ю' or A='Я', !.
is_vow(_) :- fail.
count_fig(A,N) :- count_fig(A,0,N).
count_fig("",N,N) :- !.
count_fig(A,K,N) :- frontChar(A,C1,B), is_numb(C1), count_fig(B,K+1,N), !. count_fig(A,K,N) :- frontChar(A,_,B), count_fig(B,K,N), !.
count_fig(_,_,0).
count_numbers(A,N) :- count_numbers(A,0,N).
count_numbers(A,K,K+1) :- length(A)=1, frontChar(A,C,_), is_numb(C), !. count_numbers(A,K,K) :- length(A)=1, !.
count_numbers(A,K,N) :- frontChar(A,C1,B), frontChar(B,C2,_), is_numb(C1), not(is_numb(C2)), count_numbers(B,K+1,N), !.
count_numbers(A,K,N) :- frontChar(A,_,B), count_numbers(B,K,N), !. count_numbers(_,_,0).
count_words(A,N) :- count_words(A,0,N).
count_words(A,K,K+1) :- length(A)=1, frontChar(A,C,_), not(is_delim(C)), !. count_words(A,K,K) :- length(A)=1, !.
count_words(A,K,N) :- frontChar(A,C1,B), frontChar(B,C2,_), not(is_delim(C1)), is_delim(C2), count_words(B,K+1,N), !.
count_words(A,K,N) :- frontChar(A,_,B), count_words(B,K,N), !. count_words(_,_,0).
del_spaces(A,S) :- length(A)=1, S=A, !.
del_spaces(A,S) :- frontChar(A,C1,B), frontChar(B,C2,_), C1=' ', C2=' ', del_spaces(B,D), S=D, !. del_spaces(A,S) :- frontChar(A,C1,B), del_spaces(B,D), S=concat(createFromCharList([C1]),D), !. del_spaces(_,"").
dog_to_cat("","") :- !.
dog_to_cat(A,S) :- not(is_delim(frontChar(A))), frontToken(A,T,B), T = "пес", dog_to_cat(B,C), S=concat("кот",C), !.
dog_to_cat(A,S) :- not(is_delim(frontChar(A))), frontToken(A,T,B), dog_to_cat(B,C), S = concat(T,C), !. dog_to_cat(A,S) :- frontChar(A,C1,B), dog_to_cat(B,D), S=concat(createFromCharList([C1]),D), !. dog_to_cat(_,"").
min_word(A,S) :- B = concat(A,createFromCharList(['.'])), min_word_len(B,0,length(B),N), findmw(B,N,S).
min_word_len("",_,K1,K1) :- !.
min_word_len(A,K,K1,N) :- frontChar(A,C1,B), is_delim(C1), K>0, K<K1, min_word_len(B,0,K,N), !. min_word_len(A,_,K1,N) :- frontChar(A,C1,B), is_delim(C1), min_word_len(B,0,K1,N), !. min_word_len(A,K,K1,N) :- frontChar(A,_,B), min_word_len(B,K+1,K1,N), !. min_word_len(_,_,_,0).
findmw(A,N,S):- frontToken(A,T,_), length(T)=N, not(is_numb(frontChar(T))), not(is_delim(frontChar(T))),
S=T, !.
findmw(A,N,S):- frontToken(A,_,B), findmw(B,N,S), !. findmw(_,_,"").
del_vowels("","") :- !.
del_vowels(A,S) :- frontChar(A,C1,B), is_vow(C1), del_vowels(B,D), S = D, !.
del_vowels(A,S) :- frontChar(A,C1,B), del_vowels(B,D), S=concat(createFromCharList([C1]),D), !. del_vowels(_,"").
menu(A):- menu(A,1).
menu(A,1) :- nl,write("Enter the option: "),K=readLine(), do_it(A,frontChar(K),1), !. menu(_,_).
do_it(A,K,H) :- K='A', count_fig(A,F), write("Number of figures: ",F), nl, menu(A,H), !. do_it(A,K,H) :- K='B', count_words(A,W), write("Number of words: ",W), nl, menu(A,H), !. do_it(A,K,H) :- K='C', del_spaces(A,S), write("No extra spaces: '",S,"'"), nl, menu(A,H), !.
do_it(A,K,H) :- K='D', dog_to_cat(A,D), write("Dogs to Cats: '",D,"'"), nl, menu(A,H), !. do_it(A,K,H) :- K='E', count_numbers(A,N), write("Number of numbers: ",N), nl, menu(A,H), !. do_it(A,K,H) :- K='F', min_word(A,M), write("Smallest word: '",M,"'"), nl, menu(A,H), !. do_it(A,K,H) :- K='G', del_vowels(A,G), write("No vowels: '",G,"'"), nl, menu(A,H), !.
do_it(A,K,_) :- K='H', do_it(A,'A',0), do_it(A,'B',0), do_it(A,'C',0), do_it(A,'D',0), do_it(A,'E',0), do_it(A,'F',0), do_it(A,'G',0), menu(A,1), !.
do_it(_,_,_).
clauses run():-
console::init(), write("Write a string:"),nl, A = readLine(), menu(A).
end implement main
goal mainExe::run(main::run).
Описание пользовательского меню:
Пользователь должен ввести строку, затем ввести одну букву от A до G, соответствующую задаче с той же буквой из условия. Также можно ввести H для того, чтобы получить результаты всех задач сразу.
Ввод каких-либо других символов означает завершение работы программы.
Функции программы:
Общие функции.
is_numb(A) – определяет, является ли символ А цифрой;
is_delim(A) – определяет, является ли символ А разделителем (описаны в задаче b);
is_vow(A) – определяет, является ли символ А гласной буквой;
menu(A), menu(A,H) – позволяет взаимодействовать со строкой A с помощью простого меню;
do_it(A,K,H) – выполняет какое-нибудь одно действие K (его пользователь вводит в меню) со строкой А;
в последних двух функциях: H – дополнительное значение, определяющее, стоит ли вызывать меню после совершённого действия (т.к. в случае, если пользователь захотел выполнить все действия сразу, меню должно вызываться после всех действий, а не после каждого).
Задача A. Найти количество цифр в строке.
count_fig(A,N) – проверяет каждый символ строки A, считает количество N тех из них, которые являются цифрами.
Задача B. Количество слов в строке.
count_words(A,N) – в строке А проверяет каждые смежные два символа; если первый – не разделитель, а второй – разделитель, то считается, что слово обнаружено; для последнего слова без разделителя в конце (если такое есть) – отдельный обработчик.
N – результирующее количество слов.
Задача C. Удалить лишние пробелы между словами.
(на самом деле в Visual Prolog 7.3 есть встроенная функция trimInner, которая удаляет лишние пробелы в строке; но так как мы не ищем лёгких путей, требуемая функция написана собственноручно)
del_spaces(A,S) – проверяет каждые смежные два символа строки А, удаляет один из них если это два пробела, S – результирующая строка.
Задача D. Поменять все вхождения слова «пес» на слово «кот». dog_to_cat(A,S) – проверяет каждый токен строки A, и если данный токен –
«пес», то в результирующей строке S он меняется на «кот».
Задача E. Количество чисел в строке.
count_numbers(A,N) – аналогично функции для подсчёта слов в строке А – если первый из двух смежный символов является цифрой, а второй – не цифрой, то считается, что число обнаружено; для числа в конце, если таковое есть, отдельный обработчик. N – результирующее количество чисел.
Задача F. Самое короткое слово.
min_word(A,S) – определяет длину самого короткого слова в строке A с помощью вспомогательной функции min_word_len, находит первое слово с данной длиной с помощью вспомогательной функции find_mw. S – искомое слово.
Задача G. Удалить из строки гласные буквы.
del_vowels(A,S) – проверяет каждый символ строки А, является ли он гласной буквой; если да – не включает его в результирующую строку S.
Пример вывода результатов всех задач:
Задание 2.
Написать программу, определяющую – является ли введенное предложение палиндромом. Пример строки – палиндрома «аргентина манит негра». Строчные или заглавные буквы, пробелы и знаки препинания не учитывать.
Код программы на Visual Prolog 7.3:
implement main
open core, console, string
constants
className = "main". classVersion = "".
clauses
classInfo(className, classVersion).
class predicates
is_delim : (char) determ(i).
del_useless : (string,string) procedure(i,o). palindrom : (string,string) procedure(i,o). clockwise : (string,string) procedure(i,o).
clauses
is_delim(A) :- A='.' or A=',' or A=' ' or A=';' or A=':' or A='?' or A='!' or A='-', !. is_delim(_) :- fail.
del_useless("","") :- !.
del_useless(A,S) :- frontChar(A,C,B), is_delim(C), del_useless(B,D), S = D, !.
del_useless(A,S) :- frontChar(A,C,B), del_useless(B,D), S = concat(createFromCharList([C]), D), !. del_useless(_,"").
palindrom(A,S) :- del_useless(A,B), C = toLowerCase(B), clockwise(C,D), C = D, S = "It's a palindrom.", !. palindrom(_,S) :- S = "Not a palindrom!".
clockwise("","") :- !.
clockwise(A,S) :- frontChar(A,C,B), clockwise(B,D), S = concat(D,createFromCharList([C])), !. clockwise(_,"").
clauses run():-
console::init(), A = readLine(),nl, palindrom(A,S), write(S),nl,
console::clearInput, _=readLine().
end implement main
goal mainExe::run(main::run).
Функции программы:
is_delim(A) – аналогично одноимённой функции из задания 1, проверяет является ли символ А разделителем.