Do (lst)
Predicates
Domains
Lst = integer*
Goal
Do([3, 1, 5, 11]).
Clauses
Do ([]).
Do ([H|T]):-do (T), write (H).
При зіставленні цілі Do([3, 1, 5, 11]) з секції Goal з умовним твердженням Do ([H|T]) змінна Н конкретизується 3, а Т=[1, 5, 11] і значення змінних зберігаються у стеку. Далі процедура Do викликається з хвостом списку – Т = [1, 5, 11]. Процес зображено у вигляді дерева, що подано вище і закінчується узгодженням цілі do (T) з фактом, коли список стане порожнім.
Тобто ціль do (T) стає істинною і може бути виконана наступна процедура write. Процедура write виводить верхній елемент стеку, який є останнім елемент списку. Після виводу елементу він вилучається зі стеку і верхнім елементом стеку стає другий з кінця списку. Тобто елементи списку будуть виводитися в зворотному порядку.
Стандартні рекурсивні процедури
Нижче подано стандартні рекурсивні процедури, відомі з літератури. Але Visual Prolog їх не знає, тому для використання їх треба визначати в програмі.
Процедура „Належить”
Процедура перевіряє чи входить елемент у список:
Domains
list = integer*
Predicates
in (integer, list)
Goal
readterm (list, L)
readint (N), in (N, L),
write (“Входить ”, N,” в ” L);
write (“Не входить ”).
Clauses
in (H, [H | _] ).
in (X, [_ | T] ): - in (X, T).
Граничною умовою рекурсивної процедури є факт: елемент знайдено.
Рекурсивна умова виконується, якщо елемент не знайдено. Пошук продовжується у хвості списку.
Процедура “ Приєднати (pr) ”
Процедура працює в трьох режимах залежно від завдання цілі:
1) Процедура з’єднує два списки.
Ціль: Перші два аргументи конкретизовані списки, третій аргумент вільна змінна.
Приклад :
Domains
List = integer*
Predicates
pr (list, list, list)
Clauses
pr ([ ], L, L),
pr ([Н | L1], L2, [Н | L3]): - pr (L1, L2, L3).
Goal pr([1,2], [4,5], L).
Ціль не може бути зіставлена з фактом, тому що перший аргумент факту порожній список.
Ціль зіставляється з головою правила. Змінні Н першого і третього аргументу конкретизуються 1, а L1 конкретизується списком [2]. L2 конкретизується списком [4,5]. Змінна L3 третього аргументу невизначена, тому відбувається зчеплення вільної змінної L з цілі з наполовину визначеною структурою [1 | L3] із голови правила.
Значення змінних передаються в тіло правила. Нова поточна ціль стане: pr([2],[4, 5],L3).
Таким чином, щоб з'єднати списки [1,2] і [4, 5] потрібно спочатку відкинути голову першого списку і з'єднати списки [2] і [4, 5].
Процедура рекурсивно викликається знову. В змінні Н першого і третього аргументів голови правила попадає 2, а в L1 – порожній список. Список [4, 5] як і раніше конкретизує змінну L2.
Значення змінних передаються в тіло правила. Нова поточна ціль стане: pr([],[4, 5],L3).
Одержаний рекурсивний виклик зіставляється з фактом, перший аргумент - []. Другий і перший аргумент факту мають однакові імена, тому L3 одержує значення список [4, 5].
Див. Схему співставлення:
pr ( [] L L)
pr ( [] [4, 5] L3)
Після зіставлення з фактом починається зворотний процес. До значення змінної L3, конкретизованої значенням [4, 5], поступово додаються елементи Н зі стеку і підіймаються через зчепленні змінні до цілі.
Результат: L = [1, 2, 4, 5].
2) Процедура розділяє список на два за вказаним елементом.
Ціль: Перший аргумент вільна змінна, яку буде конкретизовано першим списком. Другий аргумент структура, голова якої елемент, що розбиває список на два підсписки, а хвіст структури вільна змінна, яка буде конкретизована другим списком. Третій аргумент цілі список.
Domains
List = integer*
Predicates
pr (list, list, list)
Clauses
pr ([ ], L, L),
pr ([Н | L1], L2, [Н | L3]): - pr (L1, L2, L3).
Goal Pr (Do, [ 2 | Pisl ],[1,2,3]).