Мысал . Тізімнің ұзындығын есептеуге мүмкіндік беретін предикат құрайық , яғни тізімдегі элементтер санын. Бұл есепті шығару үшін белгілі фактті қолданайық , бос тізімде элементтер жоқ ал бос емес тізімдегі элементтер саны бірге үлкейтілген бірінші элемент пен аяғын қосу түріндегі элементтер санына тең болады. Бұл идеяны жазайық:
length([], 0). /* бос тізімде элементтер жоқ */
length([_|T], L) :–
length(T, L_T), /* L_T — аяғындағы элементтер саны */
L = L_T + 1. /* L — нəтижелі тізімнің элементтер саны */
Барлық тізімнен оның аяғына өткенде тізімнің бірінші элементі неге тең екендігі қажет емес, сол үшін белгісіз айнымалыны қолданамыз.
Қалай жұмыс істейтіндігін мысалда қарастырайық. [1,2,3] тізіміндегі элементтер саны бізге керек болсын . Пролог-жүйеге сəйкес сұрақты жазайық:
length([1,2,3],X).
Жүйе басында біздің мақсатымызды бірінші length([], 0) ұсынысымен салыстыруға тырысады , бірақ оны жасау мүмкін емес, өйткені аргументтің бірінші мақсаты бос емес тізім болып табылады.Жүйе процедураның екінші ұсынысына көшеді. Тақырыпшамен салыстыру ереже бойынша табысты, X айнымалысы L айнымалысымен байланысады, [1,2,3] тізімі [_|T] тізімімен салыстырылады, T айнымалысы [2,3] мəнімен нақтыланады. Енді жүйе length(T,L_T) мақсатына жетуге тырысады. Алдыңғы жағдайлар сияқты Т тізімі бос емес болғандықтан бірінші ұсыныс мақсатымен салыстырылмайды. Тақырыпты ереже мақсатымен салыстыру кезінде Т аяғы бірэлементті [3] тізімімен нақтыланады . Рекурсияның келесі қадамында Т айнымалысы бос тізіммен белгіленген. Яғни біздің мақсатымыздың түрі мынандай: length([], L_T). Бұл мақсат фактпен салыстырылады, L_T айнымалысы 0-ге тең болады. Рекурсияның қайта жолын кері айналдыру: L_T айнымалысы бір бірлікке көбейеді , нəтижесі L айнымалысына кіреді. Осыдан [3] тізімінің ұзындығы бірге тең болатындығын аламыз.Келесі кері қадамда тағы бір бірлік қосылады , осыдан кейін [2,3] тізімінің ұзындығы екімен нақтыланады. Соңғы қайтарылған қадамда L айнымалысының 3 санымен білдірілуі көрсетіледі .
Мысал. Элементтің тізімге жатуын тексеруге мүмкіндік беретін предикат құрайық.
Предикат екі аргументтен тұрады: біріншісі — ізделінді мəн , екіншісі — тізім, онда іздеу жүргізіледі.
Берілген предикатты мынандай фактке қарап құрайық : объект тізімге жатсын , ол не тізімнің бірінші элементі болады не аяғының элементі болады. Бұл екі сөйлем түрінде жазылуы мүмкін:
member(X,[X|_]). /* X —тізімнің бірінші элементі*/
member(X,[_|T]) :–
member(X,T). /* X аяққа жатады T*/
Бірінші жағдайда тізімнің аяғы қандай екендігі ескерілген жоқ ,сондықтан аяғы ретінде белгісіз айнымалыны көрсетуге болады .Егер екінші жағдайда Х аяққа жатса , бізге бірінші элемент қандай екендігі қажет емес.
Жазылған предикатты екі жағдайда қолдануға болатындығы белгілі: біріншіден, оны не үшін құрдық соған байланысты , яғни тізімде нақты мəн бар ма екендігін тексеру үшін. Біз, мысалы , [1, 2, 3]тізіміне екі жататындығын тексереміз :
member(2, [1, 2, 3]).
Əрине "Yes" жауабын аламыз.
Осылайша , 4 саны [1, 2, 3] тізімінің элементіне кіре ма екендігін сұрауға болады:
member(4, [1, 2, 3]).
Əрине жауабы "No" болады.
Берілген предикатты қолданудың екінші əдісі — олардың элементтерін тізім бойынша алу.
Ол үшін предикаттың бірінші аргументі ретінде бос айнымалыны көрсету керек. Мысалы:
member(X, [1, 2, 3]).
Нəтиже ретінде тізімнің барлық элементтер тізімін аламыз:
X=1
X=2
X=3
Үшінші əдіс тізімдердің нұсқасын элемент бойынша алуына мүмкіндік береді. Енді бос айнымалыны предикаттың екінші аргументі ретінде жазып алайық , ал біріншісін – нақты мəн деп . Мысалы __________,
member(1, X).
Басында Пролог-жүйе X айнымалысының бірінші ұсыныспен байланысты еместігін ескереді
("708 WARNING: The variable is not bound in this clause. (F10=ok, Esc=abort)").
Осы ескертудің назар аударылуына 2 тəсіл бар: бірлікті құрайтын элемент ретінде генерация тізімінен бас тарту үшін Esc батырмасын басу; мақсатты орындауды жалғастыру үшін F10 батырмасын басу. Екінші жағдайда бірлікті құрайтын тізімдер нұсқасын Пролог-жүйе бере бастайды:
X=[1|_] /* бірлік — тізімнің бірінші элементі */
X=[_,1|_] /* бірлік — тізімнің екінші элементі */
X=[_,_,1|_] /* бірлік — тізімнің үшінші элементі */
жəне т.б
Бұл процесс Ctrl+Break батырмасын басқанша жалғаса береді.
Егер берілген предикатты тек бірінші тəсілмен қолдану жоспарланса , тізімнің аяғында элементті іздеуді жойып оның жұмысын тездетуге болады , егер ол тізімнің бірінші элементі ретінде табылған болса.Оны екі тəсілмен жасауға болады.
Достарыңызбен бөлісу: |