name, address = string
age = integer
list = age*
Predicates
person(name, address, age)
sumlist(list, age, integer)
Goal
Findall(Age, person(_, _, Age), L),
Sumlist(L, Sum, N),
Ave = Sum/N,
write("Average =", Ave), nl.
Clauses
sumlist([], 0, 0).
sumlist([H|T], Sum, N):- sumlist(T, S1, N1), Sum=H+S1,
N=1+N1.
person("Sherlock Holmes", "22B Baker Street", 42).
person("Pete Spiers", "Apt. 22, 21st Street", 36).
person("Mary Darrow", "Suite 2, Omega Home", 51).
В цій програмі фраза findall створює список L, який містить числа, які відповідають віку всіх людей з предикату person. Якщо ви бажаєте зробити список людей вік яких 42 роки, тоді ви можете написати ціль
Findall(Who, person(Who,_,42), List).
8.5.Складні списки.
Часто вам потрібно зберігати комбинацію різних типів елементів всередині одного списку, як наприклад
[2,3,5,12,[food,"goo"], "new"]
Складними будемо називати списки, які містять більше одного типу аргументів. Нам будуть потрібні спеціальні декларації, щоб обробити списки багатотипних елементів, тому що Пролог вимагає, щоб всі елементи списку належали одній області. Для опису різнотипних списків потрібно використовувати функтори.
Наступний приклад декларації області для списку, який може мати символ, ціле число, літеру, стрічку або ж список із них. Декларація списку повинна мати функтор, а потім повинна бути декларована рекурсивно. Так, попередній список повинен бути описаний:
Domains
llist = l(list); s(symbol); i(integer); c(char); t(string)
list = llist *
І буде задаватись в Пролозі:
[i(2),і(3),i(5),i(12), [c(food),s(“goo”)],s(“new”)]
Наступний приклад з предикатом append показує як використовувати такий опис:
Domains
llist = l(list); s(symbol); i(integer); c(char); t(string)
list = llist *
Predicates
Append(list, list, list)
Goal
makewindow(1,7,7, "answer",15,0,8,80),
/*Note how you can use the same code but need functors *
* append([likes,[bill,mary]],[bill,sue],Ans) */
append([s(likes),l([s(bill),s(mary)])],[s(bill),s(sue)],Ans), */
write("First List:", Ans), nl,nl,
/*The trick is to write the list first, than add the functors *
* append([apple,[[[47], '\1']], [[["This is a string",b,7, *
* 'w']],bee], ['c'], Ans2) */
*
append([l[s("This"), s("is",s("a"),s("list"))]), s(bee)],
[c('c')], Ans2),
write("Second List:", Ans2), nl.
Clauses
/* Concatenate two lists */
append([], L, L).
append([X|L1], L2, [X|L3]):- append(L1, L2, L3).
8.6.Реалізація синтаксичного аналізу за допомогою списків.
Розглянемо задачу синтаксичного аналізу для деякої примітивної мови програмування паскалеподібного типу.
Розіб'ємо задачу на дві підзадачі: сканування і синтаксичний аналіз.
Розглянемо програму:
Domains
toklist = string*
Predicates
Tokl(string, toklist)