4. ПРОСТІ ОБ’ЄКТИ ДАНИХ
Змінна або константа.
Змінна може зв'язуватися з довільним допустимим
аргументом Прологу або об'єктом даних. Змінні Прологу
локальні, а не глобальні.
Константи містять символи, числа і атоми (не плутайте
константи в даному контексті з символьними константами,константи в даному контексті з символьними константами,
визначеними в розділі constants програми !).
Анонімна змінна (_) використовується у випадках, коли
потрібно використовувати змінну, але не потрібно
співставляти її з певним значенням.
goal [ _,X2, _,X4|_ ] = [mia, vincent, marsellus, jody, yolanda].
X2 = vincent
X4 = jody
Yes
5. КОНСТАНТИ. СИМВОЛИ
Символи мають тип char.
Символ-константа записується
наступним чином:
Символьні константи, що представляють спеціальні
функції:
6. КОНСТАНТИ. ЧИСЛА. АТОМИ
Числа можуть бути цілими
(integer) або дійсними (real).
Атоми – тип symbol або string. Відмінність між ними - питання
машинного подання та реалізації.
8. 1. СКЛАДЕНІ ОБ’ЄКТИ ДАНИХ ТА ФУНКТОРИ
Складені об'єкти даних дозволяють інтерпретувати деякі
частини інформації як єдине ціле таким чином, щоб потім можна
було легко розділити їх знову.
9. 1. СКЛАДЕНІ ОБ’ЄКТИ ДАНИХ ТА ФУНКТОРИ
Аргументи складеного об'єкту даних можуть самі бути
складеними об'єктами.
У складеного об'єкту birthday в цьому прикладі є дві частини:
об'єкт person ("Leo", "Jensen")
об'єкт date ("Apr", 14, 1960).
Функтори для цих об'єктів будуть person і date.
10. 1. СКЛАДЕНІ ОБ’ЄКТИ ДАНИХ. УНІФІКАЦІЯ
Складений об'єкт може бути уніфікований з простою змінною або
із складеним об'єктом (таким, що містить змінні в якості частин у
внутрішній структурі), який йому відповідає.
співставляється з Х і присвоює Х значення date ("April", 14, I960).
співставляється з
І присвоює змінним Mo = "April", Da = 14 і Yr = I960.
11. Уніфікація:
мета зіставляється із заголовком пропозицій:
через знак рівності (=), який є інфіксним предикатом
(предикатом, який розташований між своїми аргументами, а не
перед ними).
1. СКЛАДЕНІ ОБ’ЄКТИ ДАНИХ. УНІФІКАЦІЯ
16. 1. ОГОЛОШЕННЯ СКЛАДЕНИХ ДОМЕНІВ.
Приклад. Програма, яка показує, як складові об'єкти з домену articles можуть
використовуватися у фактах, які визначають предикат owns.
18. БАГАТОРІВНЕВІ СКЛАДЕНІ ОБ'ЄКТИ
book ("The Ugly Duckling", "Andersen“)
book ("The Ugly Duckling", author ("Hans Christian", "Andersen"))
book (title, author)
author = symbolauthor = symbol
author = author (first_name, last_name)
19. 1. ВИЗНАЧЕННЯ СКЛАДЕНИХ ЗМІШАНИХ ДОМЕНІВ
Дозволяють використовувати предикати, які мають можливість:
• отримувати аргумент більш ніж одного типу;
• отримувати різну кількість аргументів, всі різних вказаних типів;
• отримувати різну кількість аргументів, деякі з яких можуть бути більш ніж
одного з можливих типів.
20. 3. ВИЗНАЧЕННЯ СКЛАДЕНИХ ЗМІШАНИХ ДОМЕНІВ. СПИСКИ
Припустимо, потрібно заповнити розклад занять з різних предметів, які
можуть проводити різні викладачі. Можна написати наступну програму:
Тут потрібно повторювати ім'я викладача для кожного предмета, який він
читає. Для кожного предмета доводиться додавати факт до бази даних. хоча
це і абсолютно правильно в такій ситуації, але можна знайти школу, де
викладають сотні предметів; такий тип даних стає дуже складним.
Тут було б зручно створити аргумент для предиката, який містить одне
або декілька значень.
23. 2. СПИСОК ЯК ЧАСТКОВИЙ ВИД СТРУКТУРИ
Під списком розуміють впорядковану послідовність
елементів, яка може мати довільну довжину.
Елементами списку можуть бути довільні терми-
константи, змінні, структури, останні можуть включати в
себе інші списки.
Список - це або порожній список, який не містить
жодного елемента, або структура, що має дважодного елемента, або структура, що має два
компоненти: голову та хвіст.
Кінець списку представляється як хвіст, який є
порожнім списком.
24. 2. СПОСОБИ ПРЕДСТАВЛЕННЯ СПИСКІВ
При використанні функторної форми запису голова і хвіст
є компонентами функтора, що позначається крапкою ".".
При використанні графічної форми запису список
представляється як спеціального виду дерево, що "зростає"
зліва направо, причому гілки спрямовані вниз ("виноградне
гроно").
При використанні дужкової форми запису послідовність
елементів списку, що розділені комами, заключається у
квадратні дужки.
25. 2. ОГОЛОШЕННЯ СПИСКІВ
domains
integerlist = integer *
Символ (*) означає "список чого-небудь»
Елементи списку можуть бути будь-якими, включаючи інші списки. Однак
всі його елементи повинні належати одному домену. Декларація домену для
елементів повинна бути наступного вигляду:
domains
elementlist = elements *elementlist = elements *
elements = ....
У Visual Prolog можна змішувати стандартні типи в списку.
elementlist = elements *
elements = integer; real; symbol / * Невірно * /
Але правильно:
elementlist = elements *
elements = i (integer); r (real); s (symbol) % функтори тут i, r і s
26. 2. ВИЗНАЧЕННЯ СПИСКІВ
Робота зі списками заснована на розщепленні на
голову і хвіст: [Head | Tail].
Голова є перший аргумент функтора " | ", хвіст -
другий: (Head | [Tail]]).
Функтор «|» використовується для конструювання
списку.списку.
Хвіст списку є списком, що складається з усіх
елементів вихідного списку, за винятком першого.
Приклади:
[1,2,3]-Head: 1, Tail: [2,3]; [[1], [2]]-Head: [1], Tail: [[2]].
39. 3. ВИВЕДЕННЯ СПСИКУ
Виводити порожній список -
значить нічого не робити.
Інакше, виводити список - означає
друкувати його голову (яка є одним
елементом), потім друкувати його
хвіст (список).
40. 3. ВИЗНАЧЕННЯ КІЛЬКОСТІ ЕЛЕМЕНТІВ СПИСКУ
Логічне визначення:
Довжина [] - 0.
Довжина будь-якого іншого списку - 1 плюс довжина його хвоста.
42. 3. ПЕРЕТВОРЕННЯ ЕЛЕМЕНТІВ СПИСКУ
Додасть 1 до кожного елементу числового списку.
Щоб додати 1 до всіх
елементів порожнього
списку, треба створити
інший порожній список.
Щоб додати 1 до всіх елементів будь-
якого непорожнього списку, треба
додати 1 до голови і зробити отриманий
елемент головою результуючого списку,
потім додати 1 до кожного елементу
хвоста списку і зробити це хвостом
результату.
43. 3. ПРИНАЛЕЖНІСТЬ ДО СПИСКУ
… виражається предикатом
member (name, namelist). % "Name" належить "namelist”
Name належить
списку, якщо Name є
перший елемент
списку,
або
Name належить
списку, якщо Name
належить хвосту.
44. 3. ПРОЦЕДУРА ПЕРЕВІРКИ НАЛЕЖНОСТІ СПИСКУ
"деякий елемент міститься у списку елементів, якщо він є
або головою списку, або міститься у хвості списку".
Гранична умова (1):
число належить спискучисло належить списку
цілих чисел, якщо воно
є головою списку.
Рекурсивне правило (2):
число, яке не являється
головою списку, належить
йому, якщо воно належить
хвосту списку.
45. conc([], L, L).
conc([H|L1], L2, [H|L3]):-
conc(L1, L2, L3).
L1H L2
[H|L1]
L3
L3H
L3
3. ОБ'ЄДНАННЯ
СПИСКІВ.
Рекурсивне визначення
Базове твердження: з’єднання порожнього списку з
довільним списком дає той самий список
Рекурсивний крок стверджує, що з’єднання
непорожнього списку [H|T] з списком L, дає список з
головою H і результат з’єднання T і L
conc(L1, L2, L3).
46. 3. ОБ'ЄДНАННЯ СПИСКІВ. ДЕРЕВО РІШЕНЬ
goal conc([a,b,c],[1,2,3], R).
conc([], L, L).
conc([H|L1], L2, [H|L3]):- conc(L1, L2, L3).
56. 3. ОБ'ЄДНАННЯ СПИСКІВ. РЕКУРСІЯ З ПРОЦЕДУРНОЇ ТОЧКИ ЗОРУ
append (List1, List2, List3)
Якщо List1
порожній, то
результатом
об'єднання List1 і
List2 залишиться
List2 :
append ([], List2,
List2).List2).
Якщо List1 не порожній, то можна об'єднати List1 і List2
для формування List3, зробивши голову List1 головою List3 :
append ([H | L1], List2, [H | L3]): -append (L1, List2, L3).
59. 3. СКЛАДЕНИЙ СПИСОК
Приклад, який демонструє об’єднання списків та використання
оголошення доменів в типовому випадку роботи зі списками.
60. 3. ДОДАТИ ЕЛЕМЕНТ В СПИСОК
Код:
LX
[X|L]
LX
add(X,L,[X|L]).
Приклад:
add(a,[1,2,3],L).
L
[L]
61. 3. ЗНИЩИТИ ЕЛЕМЕНТ ЗІ СПИСКУ
Вважаємо, що del(X,L,L1), знищує X з L і переміщує
новий список в L1.
Код:
del(X,[X|Tail],Tail). % якщо X голова списку L
del(X,[Y|Tail], [Y|Tail1]):- del(X,Tail,Tail1).del(X,[Y|Tail], [Y|Tail1]):- del(X,Tail,Tail1).
Приклад:
del(1,[1,2,3],L).
[Y|L1]
L1YLX
L
[Y|L ]
YX
62. 3. ПІДСПИСОК
S є підсписком L якщо:
(1) L може бути розбитий на 2 списка L1, L2 і
(2) L2 може бути розбитий на 2 спика: S і деякий L3
L1 L2X member(X,L)
L
member(X,L)
L1 L3S
L2
L
[X|L2]
sublist(S,L)
sublist(S,L):- conc(L1,L2,L),
conc(S,L3,L2).
64. 3. ПЕРЕСТАНОВКА
Відношення перестановка з 2-ма аргументами в 2-х
списках таким чином, щоб один з них був отриманий
шляхом перестановки елементів іншого.
goal permutation( [a,b,c], P ).
P = [a,b,c];
P = [a,c,b];
P = [b,a,c];
X L
додати X отримуючи
…
приклад:
goal permutation( [red,blue,green], P ).
P = [red, blue, green];
P = [red, green, blue];
P = [blue, red, green];
P = [blue, green, red];
P = [green, red, blue];
P = [green, blue, red];
no
L1
перестановку [X | L]
L1 - перестановка L
65. 1.Якщо список порожній, нова
перестановка є порожньою
перестановкою ([],[]).
2. Якщо список не порожній, він має вигляд [X|L].2. Якщо список не порожній, він має вигляд [X|L].
permutation([X|L],P):-
permutation(L,L1),
insert(X,L1,P).
66. 66
3. СОРТУВАННЯ СПИСКУ МЕТОДОМ ВСТАВКИ.
Cпочатку впорядкуємо хвіст, а потім вставимо голову
в потрібне місце хвоста.
Порожній список – впорядкований.
sort ( [ ], [ ]).
sort ( [ H | T ], S) :- sort (T, S1), insert (H, S1, S).sort ( [ H | T ], S) :- sort (T, S1), insert (H, S1, S).
insert (H, [ ], [H]).
insert (H, [ Y | T ], [ H | S ]) :- H<Y, S=[Y | T].
insert (H, [ Y | T ], [ Y | S ]) :- H>=Y, insert (H, T, S).
67. 3. СКЛАДЕНИЙ СПИСОК
Складені списки - це списки, в яких використовується більш ніж один тип
елементів. Для роботи зі списками з різнотипних елементів потрібні
спеціальні декларації, тому що Visual Prolog вимагає, щоб всі елементи
списку належали одному типу.
Приклад оголошення доменів для списку, який може містити символи,
цілі, рядки або списки:цілі, рядки або списки:
domains % функтори l, i, c та s
llist = l(list); i(integer); c(char); s(string)
list = llist *
список
[2, 9, ["food", "goo"], "new"] % Некоректно в Visual Prolog
повинен бути представлений в Visual Prolog як:
[ i(2), i(9), l([s(“food”), s(“goo")]), s(“new") ] % Коректно.
68. ГРАМАТИЧНИЙ РОЗБІР СПИСКІВ
Програма ілюструє
граматичний розбір списків.
Процес граматичного
розбору працює шляхом
спрощення проблеми: у
прикладі перетворюється
кожний рядок у структуру
Прологу, яку можна
використовувати або
обчислити пізніше.
73. 4. РЯДКИ
Предикат frontchar працює згідно рівності:
String1 = об’єднання Char і String2:
frontchar (Stringl, Char, String2)
%(i, o, o) (i, i, o) (i, o, i) (i, i, i) (o,i, i)
74. 4. РЯДКИ
fronttoken (Stringl,Token,Rest)
%(i, o, o) (i, i, o) (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 завершується успішно, інакше — неуспішно.
У випадку потоку (o, i, i), предикат створює обєднання Token і Rest,
звязуючи string1 з результатом.
Послідовність знаків є лексемою, якщо вона:
- імя згідно синтаксису Visual Prolog;
- число (знак є окремою лексемою);
- відмінний від «пробілу» знак.
76. 4. РЯДКИ
Предикат frontstr розщеплює string1 на дві частини:
frontstr(NumberOfChars, String1, StartStr, EndStr)
% (i, i, o, o)
де startstr містить NumberOfChars перших символів з string1,
a Endstr містить залишок.
При зверненні до frontstr перші два параметра повинні бути
звязаними, а останні два — вільними.звязаними, а останні два — вільними.
Предикат concat встановлює, що рядок strings є
результатом зчеплення String1 і String2:
concat(Stringl,String2,StringS)
%(i, i, o),(i, o, i),(o, i, i),(i, i, i)
Предикат str_len визначає або перевіряє довжину рядка
або повертає рядок «пробілів» заданої довжини:
str_len (StringArg, Length)
% (i, o), (i, i), (o, i)