Бірінші тəсіл. Тізімнің бірінші элементі ізделінді элементпен сəйкес келмейтіндей тексеру ережесіне қосайық жəне тізімнің бірінші элементі ізделінді болмаған жағдайда тізімнің аяғында элементті іздеу. Модифицирияланған предикаттың түрі келесідей:
member2(X,[X|_]).
member2(X,[Y|T]):–
X<>Y, member2(X,T).
Member предикатының модификациясын тізімнің барлық элементтерін алуға қолдануға болмайтындығын ескерейік. Бірінші аргумент ретінде байланыспаған айнымалыны қойсақ , онда мақсатты келістіру кезінде белгіленбеген Х айнымалысы белгіленбеген У айнымалысымен салыстырылады. Қате туралы хабарлама аламыз"Free variable in expression".
Екінші тəсіл. Тізімнің бірінші элементі ізделінді элемент болғанда бастапқы тізімнің аяғында керек емес іздеу болмайтын фактті қосайық.Алатынымыз:
member3(X,[X|_]):–!.
member3(X,[_|T]):–
member3(X,T).
Member предикатының модификациясы бастапқыға қарағанда тиімдірек болғанымен , ізделінді элемент табылғаннан кейін аяғында іздеу жұмысы орындалмайды, оны тізімде нақты мəн бар екендігін тексеруге қолдануға болады. Егер біз байланыспаған айнымалының бірінші аргументі ретінде қойып тізімнің барлық элементтерін алуға қолдансақ, онда нəтижесі тек тізімнің бірінші элементі болады. Қалған элементтерді алуға кесу мүмкіндік бермейді.
Мысал. Екі тізімді қосып бір тізім жасайтын предикат құрайық . Предикаттың бастапқы екі аргументі біріктірілген тізімді көрсетеді , ал үшіншісі – біріктіру нəтижесін.
Бұл есепті шығарудың негізі ретінде бірінші тізім бойынша рекурсияны аламыз.
Рекурсияның базисі ретінде мынандай факт орнатамыз, егер тізімге бос тізімді қоссақ , онда нəтижесінде бастапқы тізімді аламыз. Рекурсияның қадамы басы мен аяғынан тұратын тізімнің элементтерін қайта жазуын анықтайтын ереже құруға , ал екінші тізімге екінші тізім мен аяғын қосып нəтижесіне бірінші тізімнің бірінші элементін алдына жазуға мүмкіндік береді.Шешімді жазайық:
conc([ ], L, L). /* бос тізіммен L тізімін біріктіргенде L тізімін аламыз */
conc([H|T], L, [H|T1]) :– conc(T,L,T1). /* L тізімі мен аяғын біріктіреміз де аяғының нəтижесін аламыз */
Бұл предикатты басқа көптеген есептерді шешуге қолдануға болатындығын ескерейік.
Біріншіден , тізімдерді біріктіру үшін. Мысалы, егер мынандай сұрақ қойсақ
conc([1, 2, 3], [4, 5], X) нəтижесінде алатынымыз X= [1, 2, 3, 4, 5]
Екіншіден ,екі тізімді біріктіргенде үшіншісін алуға болатындығын тексеру үшін. Мысалы ,
сұрақ :
conc([1, 2, 3], [4, 5], [1, 2, 5]).
жауабы əрине No болады.
Үшіншіден , бұл предикатты тізімді жазылымға бөлу үшін қолдануға болады. Мысалы, егер келесідей сұрақ қойсақ :
conc([1, 2], Y, [1, 2, 3]).
жауабы Y=[3].
мынандай сұраққа
conc(X, [3], [1, 2, 3]).
алатын жауабымыз X=[1, 2].
Енді сұрауға болады
conc(X, Y, [1, 2, 3]).
Төрт шешім аламыз:
X=[], Y=[1, 2, 3]
X=[1], Y=[2, 3]
X=[1, 2], Y=[3]
X=[1, 2, 3], Y=[]
Төртіншіден , бұл предикатты берілген элементтен оңға жəне солға қарай орналасқан элементтерді іздеуге қолдануға болады. Мысалы , егер бізді қандай элементтер 2 санының оң жағында жəне оған сəйкес сол жағында орналасқанын білгіміз келсе, онда мынандай сұрақ қоямыз:
conc(L, [2|R], [1, 2, 3, 2, 4]).
Екі шешім аламыз:
L=[1], R=[3, 2, 4].
L=[1, 2, 3], R=[4]
Бесіншіден , тізімнің соңғы элементін табатын conc предикатының негізінде предикат құру:
last(L,X):–
conc(_,[X],L).
Бұл предикатты conc предикатын қолданбай-ақ тікелей қолдануға болады :
last2([X],X). /* бұл элемент – бірэлементтік тізімнің соңғысы */
last2([_|L],X):–
last2(L,X). /* тізімнің соңғы элементі аяғының соңғы элементімен сəйкес келеді */
Алтыншыдан , conc, предикатты қолданып , элементтің тізімге жатуын тексеруді анықтауға болады. Егер элемент тізімге жатса , онда тізім екі тізімшеге бөлініп, ол ізделінді элементтің екінші тізімшесінің басы болуы мүмкіндігін қолданамыз:
member4(X,L):–
conc(_,[X|_],L).
Жетіншіден, тізімдерді біріктіруге болатын предикатты қолдана , тізімнің элементтері көршілес мəндерін тексеретін екі мəнді тізімді предикат құру . Предикаттың үш параметрі болады:екі біріншісі— мəні , үшіншісі — тізім.
Шешімнің қорытындысы келесідей болады. Егер тізімде екі элемент көршілес болса, онда бұл тізімді екі тізімшеге жіктеуге болады жəне екінші тізімшенің басы дұрыс тəртіпте біздің екі элементтен тұрады. Оның түрі келесідей болады:
neighbors(X,Y,L):–
c onc(_,[X,Y|_],L). /* тізімнің кейбіреуін біріктіруден L тізімін аламыз ,басы X и Y элементтерінен тұрады */
Бұл предикат көрсетілген тəртіпте керекті мəндерді тексеретініне назар аударыңыз. Егер бізге кейбір тізімде екі берілген мəн кездессе, оның тəртібінің қажеті жоқ , ізделінді элементтің орнын тексеретін нұсқаны алып одан көрсетілген предикаттың модификациясын жазып алу қажет. Ол үшін тізімді екі тізімшеге орналастырып жəне екінші тізімшенің басы біздің екі элементтерден тұратын болса жеткілікті. Сəйкес программалық кодтың түрі мынандай:
neighbors2(X,Y,L):–
conc(_,[X,Y|_],L);
conc(_,[Y,X|_],L). /*кейбір тізімді біріктру жолынан L болады, басы X
жəне Y элементтерінен құралады */
Достарыңызбен бөлісу: |