130 likes | 240 Views
JUI - 7. přednáška Deklarativní a procedurální sémantika, zpracování seznamů a čísel. RNDr. Jiří Dvořák, CSc. dvorak@uai.fme.vutbr.cz. Deklarativní a procedurální sémantika. Deklarativní sémantika programu : vztahy mezi objekty (tzn. CO platí). Procedurální sémantiku programu :
E N D
JUI - 7. přednáškaDeklarativní a procedurální sémantika, zpracování seznamů a čísel RNDr. Jiří Dvořák, CSc. dvorak@uai.fme.vutbr.cz
Deklarativní a procedurální sémantika • Deklarativní sémantika programu: • vztahy mezi objekty (tzn. CO platí). • Procedurální sémantiku programu: • způsob, JAK Prolog využívá svoji databázi při zodpovídání dotazů, jaká je posloupnost dílčích kroků při této činnosti. • Příklad: Mějme klauzuli tvaru • P :– Q, R. • Při deklarativním pohledu můžeme tuto klauzuli číst takto: • P je pravdivé, jestliže Q i R jsou pravdivé, • z platnosti Q a R plyne P, apod. • Při procedurálním pohledu chápeme tuto klauzuli takto: • aby se vyřešil problém P, je třeba nejprve vyřešit Q a pak vyřešit R, • aby se splnil cíl P, je třeba nejprve splnit cíl Q a potom splnit cíl R.
Substituce • Substituci je možno definovat jako konečnou množinu dvojic • = {X1= t1, X2= t2, … , Xn= tn} • kde Xijsou proměnné a tijsou termy, přičemž Xi Xj a žádný z termů tineobsahuje proměnné Xjpro všechna j. • Výsledek substituce na term A je term, který se získá dosazením termu tiza každý výskyt proměnné Xiv termu A. Tento term označme jako A . • Term (klauzule) B je instancí termu (klauzule) A, pokud existuje taková substituce , pro kterou platí B = A . • Variantou termu (klauzule) nazýváme takovou jeho instanci, v níž se každá proměnná nahradila jinou proměnnou.
Deklarativní sémantika • Deklarativní sémantika programu v Prologu má základ ve vztahu Prologu a predikátové logiky. Místo pojmu formule se používá pojem cíl. • Pro daný program a cíl G stanoví deklarativní sémantika, že cíl G je pravdivý právě tehdy, když v programu existuje klauzule C taková, že existuje její instance I taková, že • (a) hlava klauzule I je identická s cílem G a současně • (b) všechny cíle z těla klauzule I jsou pravdivé. • Deklarativní sémantika dotazu majícího tvar posloupnosti cílů • G1, G2, ..., Gnse definuje v Prologu tak, že všechny cíle této posloupnosti musí být pravdivé pro stejnou substituci proměnných. Substituce získaná jako výsledek zpracování dotazu je nejobecnější takovou substitucí.
Procedurální sémantika • Procedurální sémantika vyjadřuje, jak Prolog zodpovídá dotazy. Zodpovědět dotaz znamená pokusit se splnit cíle, které jsou v něm uvedeny, neboli nalézt takovou substituci proměnných uvedených v těchto cílech, že cíle logicky vyplývají z programu. • Procedurální sémantiku Prologu tedy můžeme vyjádřit procedurou, kterou se vyhodnocuje posloupnost cílů s ohledem na zadaný program. • Vyhodnocovací proceduru nazvěme Evaluate. Při vyhodnocení posloupnosti cílů postupuje procedura Evaluate takto: • Je-li posloupnost cílů prázdná, vyhodnocení končí úspěchem. • Pro neprázdnou posloupnost cílů G1, G2, … , Gmse provádí operace označená jako PROHLÍŽENÍ.
Operace PROHLÍŽENÍ • Prohlíží se klauzule programu shora dolů až do nalezení první klauzule C takové, že její hlava se úspěšně unifikuje s cílem G1. Pokud se taková klauzule nenalezne, končí vyhodnocení neúspěšně. • Mějme klauzuli C tvaru • A :– B1 , B2 , … , Bn . • Přejmenují se všechny její proměnné tak, aby se dostala varianta C' klauzule C, která nemá žádné společné proměnné s cíli • G1, G2, … , Gm . Nechť má C' tvar • A' :– B1', B2', … , Bn' . • Unifikují se G1 a A'. Je-li unifikace úspěšná, získá se substituce . • V posloupnosti cílů se cíl G1 nahradí tělem klauzule C', takže se získá nová posloupnost cílů ve tvaru • B1', B2', … , Bn', G2 , … , Gm.
Je-li klauzule C faktem, pak je n = 0 a posloupnost cílů se tak fakticky zkrátí o jeden cíl, což může posléze vést k jejímu vyprázdnění a úspěšnému ukončení vyhodnocení. • Provede se substituce do nového seznamu cílů, takže se získá další tvar • B1', B2', … , Bn', G2, … , Gm . • Rekurzivním voláním procedury Evaluate se vyhodnotí tato posloupnost cílů a přitom se průběžně doplňuje vytvářená substituce. Skončí-li toto vyhodnocení úspěšně, také původní vyhodnocení se považuje za úspěšné. • Není-li toto vyhodnocení úspěšné, provede se návrat k předchozí posloupnosti cílů, přičemž se odstraní ty části substituce, které byly doplněny při zpracování klauzule C. Dále se pokračuje v PROHLÍŽENÍ bezprostředně za klauzulí C ve snaze nalézt další použitelnou klauzuli.
Blokový model vyhodnocování • Každý cíl, který má být splněn, si můžeme představit jako schránku či blok(box) se čtyřmi branami (porty), které mají názvy CALL, EXIT, FAIL, REDO. • Brány CALL a REDO jsou vstupní, brány EXIT a FAIL výstupní. Při volání cíle se vstoupí branou CALL. Je-li cíl splněn, vystoupí se z boxu branou EXIT. Není-li cíl splněn, vystoupí se branou FAIL. • Když dojde k návratu, tj. při požadavku nalézt alternativní řešení, vstoupí se opět do schránky, ale branou REDO. Je-li cíl splněn, vystoupí se branou EXIT a není-li splněn, vystoupí se branou FAIL. CALL EXIT Cíl FAIL REDO
Seznamy • Seznam v Prologu má tvar • [t1, t2, … , tn] • kde ti jsou termy. • Vnitřní reprezentace seznamu odpovídá složenému termu • .(t1, [t2, … , tn]) • kde . (tečka) je speciální binární funktor, jehož prvním argumentem je první prvek seznamu a druhým argumentem je zbytek seznamu. Tato struktura je tedy analogií lispovské tečky-dvojice. • Na rozdíl od Lispu atom nil nevyjadřuje prázdný seznam. Prázdný seznam se v Prologu dá vyjádřit pouze takto: • []
Další zápisy seznamu • Další analogií tečky dvojice je zápis • [1.prvek seznamu|zbytek seznamu] • Tento způsob zápisu je možno zobecnit tak, že před znakem | se může nacházet i více prvků seznamu. • Seznam • [t1,t2, … ,tn] • je tedy možno zapsat také těmito způsoby: • [t1|[t2, … ,tn]] • [t1,t2|[t3, … ,tn]] • [t1,t2,t3|[t4, … ,tn]] • ... • [t1,t2, … ,tn|[]]
Zpracování čísel • Prolog byl koncipován jako jazyk vhodný pro symbolické výpočty a programování číselných operací má v něm ještě menší podporu než např. v Lispu. Bez počítání s čísly se však neobejdeme ani v logickém programování, a tak je celočíselná aritmetika součástí každé implementace Prologu. • Operátory, které implementace Prologu dovolují používat při zápisu aritmetických výrazů, zpravidla vyjadřují všechny čtyři základní aritmetické operace (t.j. +, –, *, /), k dispozici mohou být i operátor celočíselného dělení a zbytku (div a mod). Operátor / pak v takovém případě vyjadřuje dělení s výsledkem typu real. • Možnost zapisovat v Prologu aritmetické výrazy v infixové notaci ještě neznamená, že aritmetický výraz se vždy vyhodnocuje. Pro vyhodnocení aritmetických výrazů slouží operátor is, který patří mezi tzv. standardní neboli zabudované predikáty Prologu.
Operátor is • Predikát is funguje do jisté míry podobně jako operátor přiřazení v imperativních programovacích jazycích. Nejprve se vyhodnotí aritmetický výraz na pravé straně. Pak se ale neprovede běžné přiřazení vzniklé hodnoty, nýbrž její unifikace s proměnnou na straně levé. • To znamená, že pokud tato proměnná zatím není nastavena na konkrétní datovou hodnotu, získá hodnotu výrazu a is skončí úspěšně. Pokud již proměnná hodnotu má, pak se musí rovnat spočtené hodnotě výrazu, jinak is skončí neúspěchem. • Samozřejmým předpokladem úspěšného vyhodnocení výrazu na pravé straně je to, aby všechny proměnné obsažené v tomto výrazu měly v době vyhodnocení definovanou číselnou hodnotu. Pokud tato podmínka není splněna, vyhodnocení skončí chybovým hlášením (nikoliv tedy mechanismem neúspěchu!).
Relační operátory • Vedle aritmetických operátorů jsou v Prologu k dispozici také následující infixové binární operátory umožňující srovnání číselných hodnot vyjádřených aritmetickými výrazy: • < menší než • =< menší nebo rovno • =:= rovno • > větší než • >= větší nebo rovno • =\= různé • Tyto operátory slouží v Prologu výhradně ke srovnání číselných hodnot a způsobí automatické vyhodnocení svých operandů na obou stranách. • Pozn.: Operátor = slouží ke srovnání (unifikaci) termů!