Složitější domény. Petr Štěpánek. S využitím materialu Krysztofa R. Apta



Podobné dokumenty
Domény. Petr Štěpánek. S využitím materialu Krysztofa R. Apta

Negativní informace. Petr Štěpánek. S použitím materiálu M.Gelfonda a V. Lifschitze. Logické programování 15 1

Logické programování I

Modely Herbrandovské interpretace

Occur-check (Test konfliktu proměnných)

Zastavování výpočtů (Terminace)

Prolog PROgramming in LOGic část predikátové logiky prvního řádu rozvoj začíná po roce 1970 Robert Kowalski teoretické základy Alain Colmerauer, David

Programování v čistém Prologu

Částečná korektnost. Petr Štěpánek. S využitím materialu Krysztofa R. Apta

Operace na datových strukturách

Operace na datových strukturách

Logické programování

Substituce. Petr Štěpánek. S využitím materialu Krysztofa R. Apta. Logické programování 2 1

4.2 Syntaxe predikátové logiky

Logické programy Deklarativní interpretace

Výroková a predikátová logika - VIII

Výroková a predikátová logika - VIII

SLD-derivace. Petr Štěpánek. S využitím materiálu Krysztofa R. Apta

Programování v C++ 1, 16. cvičení

Výroková a predikátová logika - V

Logické programování

Paradigmata programování 1

Výroková a predikátová logika - II

Stromy. Strom: souvislý graf bez kružnic využití: počítačová grafika seznam objektů efektivní vyhledávání výpočetní stromy rozhodovací stromy

PARADIGMATA PROGRAMOVÁNÍ 2 PŘÍSLIBY A LÍNÉ VYHODNOCOVÁNÍ

Algoritmy a datové struktury

Matematická logika. Rostislav Horčík. horcik

Unární je také spojka negace. pro je operace binární - příkladem může být funkce se signaturou. Binární je velká většina logických spojek

1 Linearní prostory nad komplexními čísly

1 Mnohočleny a algebraické rovnice

Základní datové struktury

Databázové systémy. * relační kalkuly. Tomáš Skopal. - relační model

Výroková a predikátová logika - III

Rekurzivní algoritmy

Reprezentace aritmetického výrazu - binární strom reprezentující aritmetický výraz

Základní datové struktury III: Stromy, haldy

5 Rekurze a zásobník. Rekurzivní volání metody

Binární vyhledávací stromy pokročilé partie

platné nejsou Sokrates je smrtelný. (r) 1/??

Úvod do logiky (presentace 2) Naivní teorie množin, relace a funkce

klauzulí deklarativní (specifikace programu je přímo programem) popel, glum & nepil 1/18

Predikátová logika. prvního řádu

Grafy. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 13.

Výroková a predikátová logika - VI

Logika a logické programování

Úvod do TI - logika Predikátová logika 1.řádu (4.přednáška) Marie Duží marie.duzi@vsb.cz

Programovací jazyk Prolog

Naproti tomu gramatika je vlastně soupis pravidel, jak

1 Mnohočleny a algebraické rovnice

Bezkontextové jazyky. Bezkontextové jazyky 1 p.1/39

Cílem kapitoly je seznámit studenta se seznamem a stromem. Jejich konstrukci, užití a základní vlastnosti.

[1] samoopravné kódy: terminologie, princip

Výroková a predikátová logika - X

Matematická logika. Miroslav Kolařík

Množinu všech slov nad abecedou Σ značíme Σ * Množinu všech neprázdných slov Σ + Jazyk nad abecedou Σ je libovolná množina slov nad Σ

Výroková a predikátová logika - VII

NP-úplnost problému SAT

popel, glum & nepil 16/28

Sémantika predikátové logiky

Red Black strom (Red Black Tree) Úvod do programování. Rotace. Red Black strom. Rotace. Rotace

Výroková a predikátová logika - II

Datové struktury 2: Rozptylovací tabulky

Algoritmizace Dynamické programování. Jiří Vyskočil, Marko Genyg-Berezovskyj 2010

Stromy, haldy, prioritní fronty

Dynamicky vázané metody. Pozdní vazba, virtuální metody

PQ-stromy a rozpoznávání intervalových grafů v lineárním čase

Algoritmus. Přesné znění definice algoritmu zní: Algoritmus je procedura proveditelná Turingovým strojem.

Výroková a predikátová logika - II

Vektorové podprostory, lineární nezávislost, báze, dimenze a souřadnice

1. Několik základních pojmů ze středoškolské matematiky. Na začátku si připomeneme následující pojmy:

Binární vyhledávací stromy II

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 21.

Automaty a gramatiky(bi-aag) Motivace. 1. Základní pojmy. 2 domácí úkoly po 6 bodech 3 testy za bodů celkem 40 bodů

ALGORITMIZACE 2010/03 STROMY, BINÁRNÍ STROMY VZTAH STROMŮ A REKURZE ZÁSOBNÍK IMPLEMENTUJE REKURZI PROHLEDÁVÁNÍ S NÁVRATEM (BACKTRACK)

Definice. Vektorový prostor V nad tělesem T je množina s operacemi + : V V V, tj. u, v V : u + v V : T V V, tj. ( u V )( a T ) : a u V které splňují

Volné stromy. Úvod do programování. Kořenové stromy a seřazené stromy. Volné stromy

Tableaux metody. Jiří Vyskočil 2011

Stromy. Karel Richta a kol. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze Karel Richta a kol.

Základy algoritmizace c2005, 2007 Michal Krátký, Jiří Dvorský1/39

Matematická logika. Rostislav Horčík. horcik

1. Převeďte dané číslo do dvojkové, osmičkové a šestnáctkové soustavy: a) b)

Algoritmizace prostorových úloh

Bezkontextové jazyky 2/3. Bezkontextové jazyky 2 p.1/27

Výroková a predikátová logika - III

Úvod do informatiky. Miroslav Kolařík

Prolog 1-1. Rodinné vztahy pomocí Prologu:

Algoritmizace prostorových úloh

Predikátová logika. Teoretická informatika Tomáš Foltýnek

Limita a spojitost funkce a zobrazení jedné reálné proměnné

1 Predikátová logika. 1.1 Syntax. jaký mohou mít formule význam (sémantiku). 1. Logických symbolů: 2. Speciálních (mimologických) symbolů:

IB111 Úvod do programování skrze Python

Čtvrtek 8. prosince. Pascal - opakování základů. Struktura programu:

Výroková a predikátová logika - IX

V předchozí kapitole jsme podstatným způsobem rozšířili naši představu o tom, co je to číslo. Nadále jsou pro nás důležité především vlastnosti

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 12.

1 Báze a dimenze vektorového prostoru 1

bin arn ı vyhled av an ı a bst Karel Hor ak, Petr Ryˇsav y 23. bˇrezna 2016 Katedra poˇ c ıtaˇ c u, FEL, ˇ CVUT

Výroková a predikátová logika - VII

Turingovy stroje. Teoretická informatika Tomáš Foltýnek

Adresní vyhledávání (přímý přístup, zřetězené a otevřené rozptylování, rozptylovací funkce)

Transkript:

Složitější domény Petr Štěpánek S využitím materialu Krysztofa R. Apta 2006 Logické programování 11 1 V této části se budeme zabývat seznamy a binárními stromy. Naším cílem není tyto datové struktury podrobně rozebírat, spíše nám jde o to, ukázat, co všechno je možné v čistém Prologu s jeho prostředky naprogramovat. Seznamy Obecně řečeno, datová struktura, která pro posloupnosti podporuje jen jedinou operací - vložení nové položky na začátek - se obvykle nazývá seznam. Seznamy patří mezi základní datové struktury Prologu, a proto si zasloužily uživatelsky přátelské prostředí, které obsahuje speciální vestavěné funkce pro různé formy označování seznamů. Základem označování a definice seznamů je (jediná) konstanta [] a binární funkční symbol [... ]. Logické programování 11 2

Formálně se seznamy definují induktivně [] je seznam, je-lixs seznam, potom [x xs] je také seznam; x se nazývá hlavou a xs tělem seznamu. [] se nazývá prázdný seznam. Například [s(0) []] a [0 [x []]] jsou seznamy, zatímco [0 s(0)] není seznam, protože s(0) není seznam. Tento základní způsob označování seznamů není příliš přehledný, a proto se pro označování seznamů zavadějí synonyma. Také zde se postupuje nduktivně, pro n > 1 [s 0 [s 1,...,s n t]] se zkracuje na [s 0,s 1,...,s n t], [s 0,s 1,...,s n []] se zkracuje na [s 0,s 1,...,s n ]. Logické programování 11 3 Tedy. [a [b c]] se zkracuje na [a,b c], a. [a [b,c []]] se zkracuje na [a,b,c]. Použijeme-li vestavěný predikát rovnosti =/2 s infixní notací, jakoby byl vnitřně definován jedinou klauzulí: % X = Y X a Y se unifikují Prolog generuje následující konverzace?- X = [a [b, c]] X - [a,b c] yes?- [a,b c] = [a [b c]]?- X = [a [b,c []]] X = [a,b,c] atd. Logické programování 11 4

Tyto konvence usnadňující čtení seznamů přidáme k čistému Prologu, také budeme přidávat koncovky s k proměnným za které se mají dosazovat seznamy. Ačkoliv uvedené příklady to neuvádějí, prvky seznamů nemusí být jen základní termy. Následuje směska programů, které používají seznamy. LIST (SEZNAM) % list(xs) Xs je seznam.. list([]).. list[_ Ts]) list(ts). Logické programování 11 5 Stejně jako u programu NUMERAL platí je-lit seznam, dotaz list(t) končíúspěšně, je-lit základní term, který není seznamem, dotaz list(t)konečně selhává, pro proměnnou X, dotaz list(x) generuje nekonečně mnoho odpovědí. Délka seznamu se definuje induktivně délka prázdného seznamu [] je 0, je-li n délka seznamu Xs, potom délka seznamu [X Xs] je n+1. Program LENGTH len([],0).. len([_ Ts],s(N)) len(ts,n). Logické programování 11 6

Pomocí programu LENGTH můžeme počítat délku seznamů pomocí numerálů.?- len([a,b,c,d],n). N = s(s(s(s(0)))) Program může také generovat seznam dané délky, sestávající z proměnných.?- len(xs,s(s(s(s(0)))). N = [_A,_B,_C,_D] kde _A,_B,_C,_D jsou proměnné generované sytémem Prologu. Později ukážeme, k čemu jsou takové proměnné užitečné. Logické programování 11 7 Program MEMBER % member(element,list) Element je prvkem List(u). member(x,[x _]). member(x,[_ Xs]) member(x,xs).?- member(x,[1,2]). X = 1 ; X = 2 ; no?- member_both(x,[1,2,3],[2,3,5]). X = 2 ; X = 3 ; no Logické programování 11 8

Špatně typované dotazy mohou vést k nečekaným odpovědím. yes?- member(0,[0,s(0)]. Takjakou programů LIST a NUMERAL si odpověď no na takový dotaz vynutíme vložením testu do první klauzule programu MEMBER. member(x,[x Xs]) list(xs). Program SUBSET % subset(xs,ys) každý prvek seznamu Xs je prvkem seznamu. Ys. subset([],_). subset([x Xs],Ys) member(x,ys),subset(xs,ys). Logické programování 11 9 V programu SUBSET nejde vlastně o množiny ale o multimnožiny, v seznamech je dovoleno opakování položek. Můžeme tedy dostat yes?- subset([a,a],[a]). APPEND je známý program pro zřetězení (spojování) seznamů. app([],ys,ys). app([x Xs],Ys,[X Zs]) app(xs,ys,zs). Program APPEND má mnoho použití, můžeme s jeho pomocí vynechat určitou položku ze seznamu. To může být jedna z verzí programu SELECT (DELETE). select(x,xs,ys) app(x1s,[x X2s],Xs),. app(x1s,x2s,zs) + APPEND. Logické programování 11 10

Elegantnější verze programu SELECT definuje predikát select induktivně. % select(x,xs,zs) Zs vznikne vynecháním jednoho výskytu položky X ze seznamu Xs. select(x,[x,xs],xs). select(x,[y Xs],[Y,Zs]) select(x,xs,zs). Pokud se položka X v seznamu Xs nevyskytuje, oba programy skončí výpočet neúspěchem. Přidáním klauzule select(x,xs,xs). na konec programu skončí výpočet i v takovém případě úspěšně. Pomocí programu SELECT je možné sestrojit program, který postupně generuje všechny permutace daného seznamu. Logické programování 11 11 PERMUTACE perm([],[]). perm(xs,[x Ys]) perm(xs,[x Ys]),. select(x,xs,zs),. perm(zs,ys). Jinou variantu programu PERMUTACE získáme rozepsáním definice predikátu select pomocí app(end). Pomocí programu APPEND můžeme snadno definovat počáteční i koncový úsek seznamu. prefix(xs,ys) app(xs,_,ys). suffix(xs,ys) app(_,xs,ys). a program APPEND. Logické programování 11 12

Podseznam nějakého seznamu pak lze formálně definovat takto Seznam as je podseznamem seznamu bs, jestliže as je prefixem nějakého sufixu seznamu bs. Predikát sublist je pak definován jedinou klauzulí: sublist(xs,ys) app(_,zs,ys),app(xs,_,zs). V této klauzuli je Zs sufixem Ys a Xs je prefixem Zs. Abychom dostali program SUBLIST přidáme ještě program APPEND. Obracení seznamů. Krátce připomeneme dvě verze programů na obracení seznamů, Naivní revers a Revers s akumulátorem. Logické programování 11 13 Naivní REVERS % reverse(xs,ys) Ys vznikne obracením seznamu Xs. reverse([],[]). reverse([x Xs],Ys) reverse(xs,zs),. app(zs,[x],ys). Tento program je oblíbený pro svou neefektivnost jako testovací program pro implementace. Délka výpočtu je kvadratická vzhledem k délce vstupního seznamu. Logické programování 11 14

Vyjádříme-li klauzule rekurzivními rovnicemi podle délky x daného seznamu, dostaneme pro první klauzuli r(0) = 1 a pro druhou klauzuli r(x + 1) = r(x) + a(x), a(x) = x + 1. Celkem tedy r(x) = x. (x + 1) /2 + 1. Logické programování 11 15 REVERSE s akumulátorem je algoritmus lineární vzhledem k délce seznamu. reverse(x1s,x2s) reverse(x1s,[],x2s), reverse([],xs,xs). reverse([x X1s],X2s,Ys) reverse(x1s,[x X2s],Ys). Anonymní proměnné se mohou používát nejenom v klauzulích, ale i v dotazech, takže?- reverse([a,b,a,d],[x Ls]). X = d Ls = [a,b,a] Logické programování 11 16

ale také?- reverse([a,b,a,d],[x _]). X = d Připomeňme, že každý výskyt anonymní proměnné zastupuje jinou proměnnou, proto v databázi CENTRAL_AMERICA,kde predikát sousedství je definován jen pro různé země, dotaz neighbour([x,x]) neuspěje, ale dotaz neighbour([_,_]) ano. Přitom anonymní proměnné nelze chápat jako existenční kvantifikátory, jak by to naznačoval poslední dotaz, ale v dotazu?- app(x1s,[x X2s],[a,b,a,c]), app(x1s,x2s,zs). musíme pomocné proměnné X1s a X2s vyjmenovat, protože se každá z nich v dotazu vyskytuje dvakrát. Logické programování 11 17 Pomocí programu REVERSE můžeme jednoduše vyjádřit test, zda daný seznam tvoří palindrom. Program PALINDROM % palindrom(xs) seznam Xs čtenýoběma směry dává stejné slovo. palindrom(xs) reverse(xs,xs). a program REVERSE. yes.?- palindrom([t,a,b,a,k,a,b,a,t]). Logické programování 11 18

Následující program ukazuje jak anonymni proměnné mohou zjednodušit čitelnost programu. Problém: vytvořit seznam, ve kterém budou třijedničky, tři dvojky,..., tři devítky uspořádány tak, že pro i = 1, 2,..., 9 mezi každými dvěma následujícími výskyty čísla i bude právě i čísel. Program SEKVENCE % sequence(xs) Xs je seznam 27 položek. sequence([_,...27krát...]). question(ss) sublist([1,_,1,_,1]),. sublist([2,_,_,2,_,_,2],. sublist([3,_,_,_,3,_,_,_,3]),..... sublist([9,_,9krát,9,_,9krát,_,9]). Logické programování 11 19 a program SUBLIST. Následující konverzace s Prologem vydá všech šest řešení problému.?- question(ss). Ss = [1,9,1,2,1,8,2,4,6,2,7,9,4,5,8,6,3,4,7,5,3,9,6,8,3,5,7] ; Ss = [1,8,1,9,1,5,2,6,7,2,8,5,2,9,6,4,7,5,3,8,4,6,3,9,7,4,3] ; Ss = [1,9,1,6,1,8,2,5,7,2,6,9,2,5,8,4,7,6,3,5,4,9,3,8,7,4,3] ; Ss = [3,4,7,8,3,9,4,5,3,6,7,4,8,5,2,9,6,2,7,5,2,8,1,6,1,9,1] ; Ss = [3,4,7,9,3,6,4,8,3,5,7,4,6,9,2,5,8,2,7,6,2,5,1,9,1,8,1] ; Ss = [7,5,3,8,6,9,3,5,7,4,3,6,8,5,4,9,7,2,6,4,2,8,1,2,1,9,1] ; no Při podrobnějším prohlédnutí nabízených řešení zjistíme, že poslední tři seznamy (řešení) vzniknou obrácením prvních tří seznamů. Není těžké ukázat, že je-li seznam řešením tohoto problému, pak jeho obrácením vznikne také řesení. Logické programování 11 20

Domény závislé na aplikacích Budeme se zabývat doménami, které používají funkčních symbolů závislých na aplikacích. Takové domény odpovídají složeným typůmdatv imperativních a funkcionálních jazycích. Obarvení mapy. V tomto případě se hodí již uvedný příklad Střední Ameriky, kde na obarvení stačíjentři barvy. Program i řešení tak budou přehlednější. Podle definice, mapa je správně obarvena danou množinou barev, pokud žádné dvě sousedící země nejsou obarveny stejnou barvou. Volba vhodné reprezentace dat může podstatně zjednodušit řešení daného problému. Logické programování 11 21 Mapu budeme reprezentovat seznamem oblastí a seznamem barev. Hlavní váha tedy spočívá na reprezentaci oblastí. Každá oblast je určena svým jménem, barvou a barvami jejich sousedů, tedy termem region(name,colour,neighbours), kde neighbours je seznam barev sousedících oblastí. Vlastní program je jen odrazem následující definice správného obarvení Mapajesprávně obarvená, jsou-li správně obarveny všechny oblasti. Oblast region(name,colour,neighbours) je správně obarvená, jestliže colour a položky seznamu neighbours patří do seznamu použitelných barev a colour není v seznamu neighbours. Logické programování 11 22

% colour_map(map,colours)... Map(a) je správně obarvena barvami ze seznamu Colours. colour_map([],_). colour_map([region Regions],Colours). colour_region,colours),. colour_map(regions,colours). % colour_region(region,colours) Region a její sousedé. jsou správně obarveni. barvami z Colours. colour_region(region(_,colour,neighbours),colours). select(colour,colours,colours1),. subset(neighbours,colours1).. +SELECT a SUBSET. Nejprve je třeba vhodná reprezentace mapy Střední Ameriky, vyjádřená jediným atomem u predikátu map: Logické programování 11 23 map([ region(belize,belize,[guatemala]), region(guatemala,guatemala,[belize,el_salvador, Honduras]), region(el_salvador,el_salvador,[guatemala,honduras]), region(honduras,honduras,[guatemala,el_salvador,nicaragua]), region(nicaragua,nicaragua,[honduras,costa_rica]), region(costa_rica,costa_rica,[nicaragua,panama]), region(panama,panama,[costa_rica]) ]).?- map(map),colour_map(map,[green,blue,red]). Map = [ region(belize,green,[blue]), region(guatemala,blue,[green,green,red]), region(el_salvador,green,[blue,red]), region(honduras,red,[blue,green,green]), region(nicaragua,green,[red,blue]), region(costa_rica,blue,[green,green]), region(panama,green,[blue]) ]). Logické programování 11 24

1 2 3 4 5 6 7 1 Belize 2 Guatemala 3 El Salvador 4 Honduras 5 Nicaragua 6 Costa Rica 7 Panama Logické programování 11 25 Binární stromy Binární stromy jsou jinou fundamentalní datovou strukturou. Prolog nemá žádné vestavěné prostředky k těmto strukturám, na rozdíl od seznamů. V literatuře o Prologu najdeme řady různých definic binárních stromů. Musíme si tedy posloužit definici vlastní. Ingredience. konstanta void označující prázdný strom, ternarní funkce tree, která konstruuje binární strom přidáním levého a pravého podstromu k listu dosud sestrojeného binárního stromu. Binární stromy budeme definovat induktivně podle následující definice. Logické programování 11 26

Nejprve neformální definice: void je prázdný binární strom, jsou-lileft a right binární stromy, potom term tree(x,left,right) je binární strom. Říkáme, že x je jeho kořenem a left je jeho levým a right pravým podstromem. Prázdné binární stromy zaplňují místa (podstromy), ve kterých nejsou uložena žádná data. Při vizualizaci je praktické jejich přítomnost ignorovat. Tak například binární strom tree(c,void,void) potom odpovídá stromu jehož jediným uzlem je kořen c. Logické programování 11 27 Naproti tomu binární strom: tree(a,tree(b,tree(c,void,void),tree(d,void,void)), tree(e,void,void)) lze znázornit následovně a b e c d takže uzly tohoto stromu jsou reprezentovány termy tvaru. tree(s,void,void) kde s nabývá hodnot c, d, e. Logické programování 11 28

Z pragmatických důvodů budeme mluvit krátce o stromech místo o binárních stromech. Musíme si ovšem vždy uvědomovat, že je rozdíl mezi termem, který je (binární) strom podle naší definice, a jeho vizualizací, která je stromem. Jako obvykla začneme programem, který testuje zda daný term je binárním stromem. % bin_tree(t) < T je strom. bin_tree(void). bin_tree(tree(_,left,right)) <.. bin_tree(left),..... bin_tree(right). Logické programování 11 29 Tak jako vždy konstatujeme: pro strom t dotaz bin_tree(t) končí úspěšně, pro základní term t, který není stromem dotaz konečně selhává, bin_tree(t) pro proměnnou x dotaz bin_tree(x) generuje nekonečně mnoho odpovědí. Jak známo, stromy lze použít k ukládání dat a udržování různých operací s těmito daty. Logické programování 11 30

Prvky stromu: je přirozené, že náležení prvků x do stromu T odpovídá induktivní definici stromu. Tedy položka x náleží do stromu T, právě když x je kořenem stromu T nebo x je prvkem levého podstromu T nebo x je prvkem pravého podstromu T. Program TREE_MEMBER % tree_member(e,t) < E je prvkem stromu Tree. tree_member(x,_,_)). tree_member(x,tree(_,left,_)) <. tree_member(x,left). tree_member(x,tree(_,_,right)) <. tree_member(x,right). Logické programování 11 31 Program TREE_MEMBER lze použít například k těmto účelům: k testování, zda daná položka x náleží do stromu t dotazem tree_member(x,t), nebo k postupnému generování všech prvků daného stromu t dotazem tree_member(x,t). Procházení stromem se obvykle provádí třemi způsoby pree_order - v každém podstromu je navštíven nejprve kořen, potom uzly levého a nakonec pravého podstromu, in_order - nejprve jsou navštíveny všechny uzly levého podstromu, potom kořen stromu a nakonec všechny uzly pravého podstromu, post_order - nejprve jsou navštíveny uzly levého postromu, potom pravého a nakonec kořen stromu. Každý se jednoduše překládá do programu v Prologu. Logické programování 11 32

Například: % in-order(tree,list) < List je seznam uzlů stromu Tree v pořadí, které odpovídá průchodu in_order. in-order(void,[]). in-order(tree(x,left,right),xs) <. in-order(left,ls),.. in-order(right,rs),. app(ls,[x Rs],Xs).. + program APPEND Frontier (hranice) stromu je seznam vytvořený z jeho listů. Připomeňme, že listy jsou vyjádřeny termy. tree(a,void,void). Logické programování 11 33 Při programování výpočtu hranice stromu rozeznáváme tři typy stromů: prázdný strom - void, list - tree(a,void,void), neprázdný strom, který není listem (krátce nel-tree), reprezentovaný termem tree(x,l,r). Program FRONTIER (nejprve definujeme pomocnou relaci nel_tree. % nel_tree(t) < t je nel_tree. nel_tree(tree(_,tree(_,_,_),_)). nel_tree(_,_,tree(_,_,_))). Logické programování 11 34

% front(tree,list) < List je hranicí stromu Tree. front(void,[]). front(tree(x,void,void),[x]). front(tree(x,l,r),xs) <. nel_tree(tree(x,l,r)),. front(l,ls),. front(r,rs),. app(ls,rs,xs).. + APPEND Dotaz nel-tree(t) může končit úspěchem i pro termy, které nejsou stromy, následující (zdánlivě jednodušší) program proto není korektní. Logické programování 11 35 % front(tree,list) < List je hranicí stromu Tree. front(void,[]). front(tree(x,void,void),[x]). front(tree(_,l,r),xs) <.. front(l,ls),. front(r,rs),.. app(ls,rs,xs).. + APPEND není korektní. Dotaz front(tree(x,void,void),xs) dává dvě různé odpovědi {Xs/[X]} podle druhé klauzule a {Xs/[]} podle třetí klauzule. Ovšem v předchozí verzi byl podprogram NEL-TREE používán jen na termy, které jsou stromy. Logické programování 11 36

Shrnutí Doména prázdná konečná Seznamy Binární stromy Inventář žádné funkce ani predikáty jen konstanty konstanta a binární funkční symbol konstanta a ternární funkční symbol Logické programování 11 37