КАТЕГОРИИ:
АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника
|
Метод отсечения и отката.В основе этого метода лежит использование комбинации предикатов fail (для имитации неудачи и искусственной организации отката) и "!" (отсечение или cut), который позволяет прервать этот процесс в случае выполнения какого-то условия. Пример: PREDICATES nal(symbol, symbol) zar(symbol) min(symbol) max(symbol) dop(symbol) prof(symbol,symbol)
CLAUSES nal(Pred, Vid_nal):-zar(Pred), prof(Pred, “Образование”),!, fail. nal(Pred, Vid_nal):-zar(Pred), max(Vid_nal). max(X):-min(X);dop(X). min(“Местные”). min(“На прибыль”). dop(“На добавочную стоимость”) . zar(“РГРТУ”). zar(“контора РиК”). prof(“РГРТУ”, “Образование”). prof(“Контора РиК”, “Комерция”).
Метод повтора Также использует откат, однако в отличие от отката после неудачи, в котором откат осуществляется только после специально созданной неудачи, в этом методе откат возможен всегда за счет использования специального предиката, обычно кодируемого в виде: repeat. repeat:– repeat.
Этот предикат всегда успешен после выполнения первого предложения процедуры в стек точек возврата запоминается указатель поскольку имеется ещё один альтернативный вариант. В теле второго предложения опять вызывается предикат repeat. Предикат repeat не является встроенным предикатом, а его имя – зарезервированным словом. Вместо этого имени можно использовать любое другое. С помощью подобного предиката можно организовывать циклы.
DATABASE counter(integer) PREDICATES repeat count GOAL count. CLAUSES repeat. repeat:-repeat. count:-assert(counter(0)),fail. count:-repeat,counter(X),Y=X+1,retract(counter(X)), asserta(counter(Y)),write(Y), nl, Y=5. Списки В императивных языках основной структурой данных являются массивы, а в Прологе списки. Списком называется упорядоченная последовательность элементов произвольной длины. Список задается перечислением элементов через запятую в квадратных списках. Рассмотрим пример: [Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday] []-пустой список listI = integer* /* список, элементы которого — целые числа */ listR = real* /* список, состоящий из вещественных чисел */ listC = char* /* список символов */ lists = string* /* список, состоящий из строк */ listL = listI* /* список, элементами которого являются списки целых чисел */
Дадим рекурсивное определение списка. Список — это структура данных, определяемая следующим образом:
Вертикальная черта позволяет разделить на хвост и голову. Если хвост не пуст, то также можно разбить для пустого списка. Чтобы организовать работу списка, достаточно задать правило порядка перехода от обработки всего непустого списка к обработке его хвоста. Пример. Создадим предикат, позволяющий вычислить длину списка, т.е. количество элементов в списке.
length([], 0). /* в пустом списке элементов нет */ length([_|T], L) :– length(T, L_T), /* L_T — количество элементов в хвосте */ L = L_T + 1. /* L — количество элементов исходного списка */
Пример. Создадим предикат, позволяющий проверить принадлежность элемента списку. Предикат будет иметь два аргумента: первый — искомое значение, второй — список, в котором производится поиск.
member(X,[X|_]). /* X — первый элемент списка */ member(X,[_|T]) :– member(X,T). /* X принадлежит хвосту T*/ GOAL member(2, [1, 2, 3]).
Результат:
X=1 X=2 X=3
Пример. Создадим предикат, позволяющий соединить два списка в один. Первые два аргумента предиката будут представлять соединяемые списки, а третий — результат соединения. conc([ ], L, L). /* при присоединении пустого списка к списку L получим список L */ conc([H|T], L, [H|T1]) :– conc(T,L,T1). /* соединяем хвост и список L, получаем хвост результата */
GOAL сonc([1,2,3],[4,5],X) Результат: X= [1, 2, 3, 4, 5]
Пример. Разработаем предикат, позволяющий "обратить" список (записать его элементы в обратном порядке). Предикат будет иметь два аргумента: первый — исходный список, второй — список, получающийся в результате записи элементов первого аргумента в обратном порядке. reverse([ ],[ ]). /* обращение пустого списка дает пустой список*/ reverse([X|T],Z):– reverse(T,S), conc(S,[X],Z). /* обращаем хвост и приписываем к нему справа первый элемент исходного списка*/
Пример. Создадим предикат, который позволит проверить, является ли список палиндромом. Палиндромом называется список, который совпадает со своим обращением. Соответственно, у данного предиката будет всего один аргумент (список, который проверяем на "палиндромность"). palindrom(L):– reverse (L,L).
Пример. Напишем предикат, позволяющий получать элемент списка по его номеру так же, как по номеру можно получать элемент массива в императивных языках программирования. Предикат будет трехаргументный: первый аргумент — исходный список, второй аргумент — номер элемента и третий — элемент списка, указанного в качестве первого аргумента предиката, имеющий номер, указанный в качестве второго аргумента. n_element([X|_],1,X). n_element([_|L],N,Y):– N1=N–1, n_element(L,N1,Y).
Пример. Создадим предикат, удаляющий все вхождения заданного значения из списка. Предикат будет зависеть от трех параметров. Первый параметр будет соответствовать удаляемому списку, второй — исходному значению, а третий — результату удаления из первого параметра всех вхождений второго параметра. Создадим его. delete_all(_,[],[]). delete_all(X,[X|L],L1):– delete_all (X,L,L1). delete_all (X,[Y|L],[Y|L1]):– X<>Y, delete_all (X,L,L1).
|