Бақылау сұрақтары
Бинарлы ағаштарға қандай амалдар қолдануға болады?
Граф деген не және оның қандай түрлері бар?
Екілік анықтамалық деген не?
Жиын және жиындарға қолданылатын амалдар.
Жиын қуаттылығы деген не және ол қалай анықталады?
Тақырып №13: Қатарлар. Қатарларды өңдеу. Стандарт предикаттар.
Прологта қатар ретінде қос тырнақшаға алынған символдар тізбегі түсініледі. Қатардың ұзындығын анықтауға арналған Str_len кірістірілген предикатын қарастырайық. Оның екі аргументі бар: біріншісі – қатар, екіншісі – символдар саны. Бұл предикатты қолданудың үш варианты бар. Біріншісі бұл предикатты қолданудың ең ыңғайлы варианты, мұнда бірінші аргумент байланысқан, ал екінші бос болып келеді. Бұл жағдайда екінші аргументке бірінші аргументтегі символдар саны орналастырылады.
Екіншісі, стандарты «прологтың» предикат үшін күтілетін варианты екі аргументте байланысқан болады. Бұл жағдайда предикат сәтті болады, егер бірінші аргументтің ұзындығы екінші аргументтің ұзындығымен сәйкес келсе, керісінше жағдайда– сәтсіз болады.
Және үшінші, жиі қолданыла бермейтін қолданылу варианты бұл – екінші аргумент байланысқан, ал біріншісі – бос болғанда. Бұл жағдайда бірінші аргумент бос орындардан тұратын қатар ретінде белгіленеді де, бос орындар саны екінші аргументке тең болады.
Келесі стандартты предикат concat - екі қатарды байланыстыруға немесе оларды конкатенациялауға арналған. Оның үш аргументі бар әрқайсысы қатарлық типті, ең болмағанда үш аргументтің екі байланысқан болуы керек. Нәтижесінде төрт мүмкін шаблонды және осы предикатты қолданудың төрт вариантына ие боламыз.
Бірінші вариант алғаш екі аргумент байланысқанда. Бұл жағдайда, екінші аргументтің біріншісіге көшіріп жазып алынуынан пайда болған үшінші аргумент қатар ретінде белгіленеді.
Екінші вариант, мұнда бірінші және үшінші аргумент байланысқан болады. Бұл жағдайда екінші аргумент бірінші аргументке көшіруден үшінші аргумент алынатын қатар ретінде белгіленеді. Егер мұндай қатар болмаса, предикат сәтсіз болады.
Үшінші вариант екіншіге ұқсас, мұнда екінші және үшінші аргументтер байланысқан, ал біріншісі – бос. Бұл жағдайда, әрине бірінші аргумент көшіру кезінде үшінші аргумент алуға болатын қатар болып белгіленеді. Керісінше жағдайда предикат сәтсіз болады.
Және, ең соңғы төртінші вариант барлық үш аргументте белгіленгенде пайда болады. Предикат сәтті болады, егер бірінші аргумент пен екінші аргуметті байланыстыруда үшінші аргумент алынса, сәтсіз болады – керісінше жағдайда.
Келесі үш кірістірілген предикаттар «қатарларды» құрамдарға арналған.
Frontchar предикаты бірінші символды өшіруден кейінгі қатарлар символдарынан тұратын бастапқы қатарды қалған бірінші символ мен «аяғына» бөлуге арналған. Бұл тізімдердің басы мен аяғына ұқсас болып келеді. Берілген аргументтің бірінші және үшінші аргументі қатарлық доменге тән, ал екіншісі – символдық доменге тән. Бұл предикатты қолданудың бес варианты бар.
Бірінші варианты, бірінші аргумент байланысқан, ал екінші мен үшінші – бос болғанда орындалады. Бұл жағдайда екінші аргумент қатардың бірінші символымен белгіленеді, ал үшінші аргументке екіншісінен бастап барлық символдар жазылады.
Екінші варианты, бұл предикаттың жиі қолданылатын варианттарының бірі, мұнда керісінше, бірінші аргумент бос, ал екінші мен үшіншісі – байланысқан болып келеді. Бұл жағдайда бірінші аргументке қатар сәйкес келеді. Бұл конкотанацияның қандай да бір түрі, бірақ екі қатар емес, символ мен қатар байланыстырылады.
Үшінші вариант, бірінші және екінші аргументтер белгіленген , ал үшіншісі белгіленбегенде пайда болады. Бұл жағдайда үшінші аргументке бірінші аргументтің барлық символдары жазылады, ол екінші символдан бастап жазылады, егер бірінші аргументтің бірінші символы екінші аргументпен сәйкес келгенде. Керісінше жағдайда предикат сәтсіз болады.
Төртінші вариант үшіншісіне ұқсас, бірақ екінші аргумент бос, ал бірінші мен үшінші байланысқан. Бұл жағдайда екінші аргумент бірінші аргументтің бірінші символымен белгіленеді, егер бірінші аргументтің қалған символдары үшінші аргументті құраиын болса. Керісінше жағдайда предикат сәтсіз болады.
Және ең соңғы бұл предикатты қолданудың бесінші варианты оның барлық үш аргументі де белгіленгенде пайда болады. Бұл кезде ол шын болады, егербірінші аргументте сақталатын қатар үшінші аргументтен екінші аргумент қатардың символына көшірілуімен алынған қатармен сәйкес келетін болса. Ол болмаған жағдайда ол жалған болады.
Frontstr предикаты frontchar предикаты қатарына енетін сөздер тізімін құру үшін кірістіруге болады. Предикаттың төрт параметрі бар. Бірінші параметрде екінші параметрден үшіншісіне көщірілетін символдар саны көрсетіледі; екінші параметр қолданылған төртінші аргумент белгіленеді. Бұл предикат жоғарыда сипаттплған жалғыз әдіспен қолданыла алады, ал – оның алғаш екі параметрі енуші, ал үшіншісі мен төртіншісі – шығушы.
Бірінші параметрде көрсетілген символдар саны екіншці параметрдегі қатар ұзындығынан асып кетсе, предикат сәтсіз болады.
Және ең соңғы fronttoken предикаты предикаттың бірінші параметрі ретінде көрсетілген бастапқы қатарды екі бөлікке бөлмейді, бөлшектейді. Екінші аргумент бірінші атомға барып түседі; үшіншісіне – одан атомды өшіргеннен соң қалған енуші қатар келіп түседі. Атом – бұл идентификатор не болмаса, белгіленбеген символ (бүтін неммесе заттай) немесе символ болып табылады. Бұл предикатты қолданудың бес варианты бар.
Бірінші вариант, бірінші аргумент байланысқан, ал екінші мен үшіншісі – бос болғанда орындалады. Бұл жағдайда қатардың бірінші аргументімен белгіленеді, ал үшінші аргументте бастапқы қатардың қалдығы жазылып қалады.
Бұл претикатты қолданудың екінші варианты керісінше бірінші аргумент бос болғанда, ал екінші мен үшінші – байланысқанда қолданылады. Бұл жағдайда бұл предикат қатарлар конткатенациясы сияқты жұмыс жасайды. Бірінші аргументке үшінші аргументтегі қатарды көшіріп алумен белгіленген қатар келіп түседі.
Үшінші вариант бірінші және үшінші аргумент белгіленіп, үшіншісі белгіленбегенде пайда болады. Бұл жағдайда бірінші аргументтің барлық символдары көшіріледі, егер бірінші агументтің атомы екінші аргументпен сәйкес келсе. Кері жағдайда, претикат сәтсіз болады.
Төртінші вариант үшінші вариант секілді, бірақ екінші аргумент бос, ал біріншісі мен үшіншісі байланысқан. Бұл жағдайда екінші аргумент бірінші аргументтің бірінші атомымен белгіленеді, егер бірінші аргументтің қалған символдары үшінші аргументегі қатармен сәйкес келеді. Олай болмаса предикат сәтсіз болады.
Және де соңғы бесінші аргумент оның барлық үш аргументтері де белгіленгенде пайда болады. Бұл жағдайда шын болады, егер бірінші аргументте сақталатын қатар үшінші аргументтегі екінші аргументтің қатары аргументіне көшіруілумен алынған қатармен сәйкес келсе. Кері жағдайда предикат жалған болады.
Isname предикаты егер оның аргументі идентификатор болса шын болады, ал кері жағдайда жалған болады.
Мысал. Енді жоғарыда аталып өткен предиактткрды қолданып көрейік. Қатарды символдар тізбегіне түрлендіретін предикатты құрайық. Предикаттың екі аргументі болады. Бірініші аргумент болып берілген қатар, ал екінші аргумент болып – бастапқы қатардың символдарынан тұратын тізім табылады.
Шешімі рекурсивті болып келеді. Базисі: бос қатарға бос тізім сәйкес келеді. Қадам: fronchar кірістірілген предикаты көмегімен қатарды бірінші символға және қатардың қалдығына бөлеміз, қатардың қалдық бюөлігін тізімге көшіріп жазымыз, сонан соң бірінші элемент ретінде осы тізімге бастапқы қатардың бірінші символын қосамыз. Бұл идеяны мына түрде жазамыз:
Str_list (“ “, []). /* бос қатарға бос тізім сәйкес келеді*/
Str_list (S , [H/T]): -
Frontchar (S, H, S1), /*H –S қатарының бірінші символы, S1 қатар қалды*/
Str_list (S1, T). /*T – S1 қатарына енетін символдардан тұратын тізім*/
Бұл претикатты сонымен қатар қатарға еретін сөздер тізімін құру үшін әрекеттесуге болады. Егер сөздер тек бос орындармен ғана бөлінсе, онда ені өзгеріссіз сәйкес келеді. Егер де қатарға белгілер енетін болса, онда олардың әр қайсысы нәтижелін тізімге жеке элементпен енеді. Тізімді шығарып алу үшін, одан белгілерді алып тастаса болғаны. Өкінішке орай, бұл идея тек ағылшын тілінде ғана жұмыс жасай алады. Орысша мәтінді бұл предикат сөздерге жеке символдарға бөліп тастайды.
Мысал. Символдар тізімен қатарға түрлендіретін предикаты жасаймыз. Предикаттың екі аргументі болады. Бірінші аргументі болып символдар тізімі табылады. Бірінші аргументі болып символдар тізімі табылады, ал екіншісі болып – тізімдер элементтерінен құрылған қатар табылады.
Рекурсия базисі: бос тізімге бос қатар сәйкес келеді қадам: егер бастапқы тізім бос болмаса, онда қатарға оның соңғы бөлігін көшіреміз, одан соң frontchar предикатын қолданып бастапқы тізімнің соңынан алынған қатарды тізімнің бірінші элементіне жазып қоюға болады. Бұл идеяны мына түрде жазамыз:
List_str ([],’’ ‘’). /* бос қатарға бос тізім сәйкес келеді*/
List_str ([H/T], S):-
List_str (T, S1), /* S1 – T тізімі элементтерімен тұрылған қатар*/
Frontchar (S, H, S1)7 /* S – H тізімінің бірінші элементтеріне S1 қатарын толық көшіруден алынған қатар*/
Мысал. Қатардың бір бөлігін өшіріп отыратын предикатты дасайық. Предикатың төртпараметрі болады. Алғаш үшеуі : біріншісі – бастапқы қатар, екіншісі – позиуия, үшіншісі - өшірілетін символдар саны, төртіншісі – шығушы – параметрі болып қатардан, бірінші параметрден көрсетілген символдарды өшіру нәтижесі болып табылады.
Бұл тапсырманың шешімін жазайық. Frontchar стандартты предиакты көмегімен бастапқы қатарда екі ішкі қатарға бөлеміз. Біріншісіне – бастапқы қатар басып жазамыз. Екінші ішкі қатарды тағы екі ішкі қатарға бөлеміз. Бірінші ішкі қатарға өшірілуі тиіс символдарды орналастырамыз. Екіншісіне бастапқы қатар символдарының қалдықтарын жазамыз. Жауап алу үшін бастапқы қатардың бірінші ішкі қатарын екінші ішкі қатардың соңғы қорытынды қатарда қалуы тиіс символдардан тұратын қатарды аламыз.
Прологта бұл тапсырманы былай жазуға болады:
Str_delete (s,I,C,So)& -
I1=I-1,
Frontstr (I1,S,S1,S2),
Frontstr (C,S2,_,S3),
Concat (S1,S3,S0).
Мысал. Қатардың бір бөлігін көшіретін предикат құрып көрелік. Предикаттың төрт параметрі болады: алғашүшеуі енуші: біріншісі – бастапқы қатар, екіншісі – символдар көшіріле бастайтын орны, үшіншісі – көшірілетін символдар саны. Төртіншісі шығушы – қатардан символдарды бірінші параметрде көрсетілген шекте көшіру, үшінші параметрде көрсетілген екінші параметрде көрсетілген орнынан бастап көшіреміз.
Бұл тапсырманы шешу үшін қайтадан frontstr предикатын пайдаланамыз. Алдымен біздің қатардың баған символдарды көшіру керек орнынан бастап шығарып аламыз. Егер осыдан соң көшірілу қажет болатындай жаңа символдардың бірінші символдары көлемін алсақ, алыну қажет жақты ішкі қатарды алуымызға болады. Бұл айтылғана мына түрде беріледі:
Str_copy (S,I,C,S0): -
I1=I-1,
Frontstr (I1,S,_,S1),
Frontstr (c,S1,S0)7
Достарыңызбен бөлісу: |