Prolog – seznamy Jan Hric, 1997 – 2010b KTIML MFF UK URL:

Slides:



Advertisements
Podobné prezentace
J. Pokorný 1 DOTAZOVACÍ JAZYKY slajdy přednášce DBI006 J. Pokorný MFF UK
Advertisements

Programovací jazyk C++
Ladění, pred. vyšších řádů (7)  Jan Hric, KTI MFF UK, a
Vstupy a výstupy v JavaScriptu Vstup: použitím metody prompt objektu window čtením hodnot z položek formuláře Výstup : použitím metody alert objektu window.
JUI - 3. přednáška Zpracování seznamů, predikátové a vyhodnocovací funkce RNDr. Jiří Dvořák, CSc.
Seznamy v jazyce Haskell doc. Dr. Ing. Miroslav Beneš  katedra informatiky, A-1007 
1 Vnitřní řazení s využitím dynamických struktur Tvorba spojového seznamu je vcelku triviální záležitostí: a)Vytvořím prázdný seznam příkazem LIST:=nil.
Semestrální práce KIV/PT Martin Kales Hana Hůlová.
BLIŽŠÍ POHLED NA TŘÍDY, DĚDIČNOST - úvod
Programovací jazyk Prolog
Neprocedurální programování Prolog 1.přednáška
Algoritmizace a programování Podprogramy v Delphi - 10
Výpočetní technika Akademický rok 2009/2010 Letní semestr Mgr. Petr Novák Katedra informatiky a geoinformatiky FŽP UJEP
Programování v C++ Cvičení.
Principy překladačů Běhová podpora Jakub Yaghob. Běhová podpora Statická podpora jazyka Překladač Interface na knihovny Hlavičkové soubory Dynamická podpora.
Varianty Turingova stroje Výpočet funkcí pomocí TS
Principy překladačů Mezikód Jakub Yaghob.
Implementace konečného automatu v Prologu Tato část popisuje strukturu konkrétního automatu a bude se lišit pro každý automat. 1.Definice přechodové funkce:
Generování mezikódu Jakub Yaghob
Medians and Order Statistics Nechť A je množina obsahující n různých prvků: Definice: Statistika i-tého řádu je i-tý nejmenší prvek, tj., minimum = statistika.
Skip-List je datová struktura, která může být použita jako náhrada za vyvážené stromy. představují pravděpodobnostní alternativu k vyváženým stromům (struktura.
Příklady z Matlabu (5) Jednoduché scripty.
MATLAB® ( Funkce v Matlabu ).
Řadicí algoritmy autor: Tadeáš Berkman.
Analýza informačního systému
Základy elektrotechniky Symbolicko-komplexní metoda řešení obvodů
JUI - 9. přednáška Ř ez, negace, práce s databází RNDr. Jiří Dvořák, CSc.
Sémantická analýza Jakub Yaghob
Syntaxí řízený překlad
Současný svět Projekt č. CZ /3. 1
Střední průmyslová škola strojnická Olomouc, tř.17. listopadu 49 Výukový materiál zpracovaný v rámci projektu „Učíme moderně“ Registrační číslo projektu:
Predikátová logika.
Počítače a programování 1
Reprezentace (6)  Jan Hric, KTI MFF UK, a
Přednáška 10 Logické programování, PROLOG (PROgramming in LOGic)
Vzorec v buňce v tabulkovém procesoru Vzorec v buňce v tabulkovém procesoru Microsoft ® Excel Zpracovala : Dana Lišková 4.B
Dokumentace informačního systému
Analýza infromačního systému. Matice afinity ISUD matice – Insert (vkládání dat) – Select (výběr dat) – Update (aktualizace dat) – Delete (vymazání dat)
Milan Kryl(c) 2004 MFF UK Databáze Caché NLS national language settings.
Název školyIntegrovaná střední škola technická, Vysoké Mýto, Mládežnická 380 Číslo a název projektuCZ.1.07/1.5.00/ Inovace vzdělávacích metod EU.
Programovací jazyk Haskell doc. Dr. Ing. Miroslav Beneš  katedra informatiky, A-1007 
Přednáška 10 Logické programování, PROLOG (PROgramming in LOGic)
Marie Duží vyučující: Marek Menšík Logika: systémový rámec rozvoje oboru v ČR a koncepce logických propedeutik pro mezioborová studia.
Databáze velké množství dat pevně dané struktury
Vektorové prostory.
Vestavěné predikáty a jejich použití (5) Jan Hric, KTI MFF UK, a
Vestavěné predikáty a jejich použití Jan Hric, KTI MFF UK c (oprava 4.5.)
Analýza informačního systému. Podrobně zdokumentovaný cílový stav Paramentry spojené s provozem systému – Cena – Přínosy – Náklady a úspory – …
Seznamy v jazyce Haskell Ing. Lumír Návrat  katedra informatiky, D-403 
JUI přednáška Vstup a výstup, cykly RNDr. Jiří Dvořák, CSc.
Soubory BI-PA1 Programování a algoritmizace 1, ZS Katedra teoretické informatiky © Miroslav Balík Fakulta informačních technologií České vysoké.
Prolog (add) Jan Hric, KTI MFF UK, a
C – procedury Mgr. Lenka Švancarová.
Vícerozměrná pole (1) Jazyk C povoluje, aby pole mělo více rozměrů (dimenzí) než jeden Z vícerozměrných polí bývá nejčastěji použí-váno pole dvourozměrné.
Podprogramy (subroutines) Pojmenované kousky programu, které –tvoří logicky ucelené části –se v programu opakují Jsou zapsány na jednom místě a v případě.
Datové typy IB111: Datové typy. Data a algoritmizace jaká data potřebuji pro vyřešení problému? jak budu data reprezentovat? jaké operaci s nimi potřebuji.
Tým 32, varianta b/4/I.  Jakub Kadlubiec  Roman Pijáček  Petr Pliska  Jan Štourač  Václav Tunka (vedoucí)
Programovací jazyk C# 4. část - cykly.
Vícerozměrná pole (1) Jazyk C povoluje, aby pole mělo více rozměrů (dimenzí) než jeden Z vícerozměrných polí bývá nejčastěji použí-váno pole dvourozměrné.
Výška stromu - algoritmus
Výukový materiál zpracován v rámci projektu
Programovací jazyk C++
PROLOG strategie vyhodnocení dotazu
Příkazy cyklu (1) Umožňují vícekrát (nebo ani jednou) pro-vést určitý příkaz Jazyk C rozlišuje příkaz cyklu: s podmínkou na začátku: obecný tvar: while.
Databázové systémy a SQL
Dynamické proměnné (1) Proměnné, jejichž počet a (nebo) velikost pa-měti využívané těmito proměnnými se v prů-běhu programu mění Dynamické proměnné lze.
Oblast platnosti identifikátoru (1)
Podprogramy.
ALG 07 Selection sort (Select sort) Insertion sort (Insert sort)
Logické programování Prezentace číslo 5.
Transkript prezentace:

Prolog – seznamy Jan Hric, 1997 – 2010b KTIML MFF UK URL:

není rozlišován vstupní vs. výst. argument + vstupní argument - výstupní argument +- arg. obsahuje volné proměnné ? cokoli mod predikátu a volání př: faktorial(+,?), rodic(-,-) - systém to nekontroluje, konvence programátora Tok dat

Tok dat - příklad definice rodic/2 predek(X,X). % 1. varianta predek(X,Y):- rodic(X,Z), predek(Z,Y). predek(X,X). % 2. varianta predek(X,Y):- rodic(Z,Y), predek(X,Z). volání p(+,+), p(+,-), p(-,+), p(-,-) stejné 1. lepší 2. lepší ?- p(adam,X) vs. ?- p(X,cyril) vhodnost závisí na zamýšleném (příp. obvyklém) použití jiné varianty (přehození cílů, klauzulí) jsou horší

Operace na seznamech zjistit, zda X je prvkem seznamu L % member(?X,+L) member(X,[X|_]). % X je hlavou member(X,[_|L]):- member(X,L). % X je v těle ?- member(b,[a,b,c]). % m(+,+) yes ?- member(X,[a,b]). % m(-,+) X=a; % generovani X=b; no

Zpracování rekurzívních dat. struktur - rekurzívní d.s. se zpracovávají rek. programy - koncové případy jsou ošetřeny fakty anebo nerekurzívní klauzulí - aspoň jeden fakt anebo nerek. klauzule ! - každý možný tvar d.s. (konstruktor) má být ošetřen - jinak neúspěch - např. seznamy: []/0,./2 stromy: void/0, t/3 - u member/2 ošetření [] není nutné (ekv. fail) - není to obvyklé

Member/2 - pokrač. - příklad podspecifikovaného cíle ?- member(a,L). % m(+,-) L = [a|_1]; L = [_1,a|_2]; L = [_1,_2,a|_3];... atd. - vydává se “nekonečně” mnoho řešení backtrackingem - _číslo je výpis volné proměnné

member – pro asociativní paměť Položky seznamu: klíč-hodnota % -(k,h) ?- Tab= [k1-h1,k2-h2,k2-h2b], % generovat member(k2-HN,Tab).% ke kN najde HN HN = h2; HN = h2b; No - Zde využíváme backtracking, ale lze vracet i všechny hodnoty najednou, v seznamu % lookup(Klic, Pamet, Hodnota) : interface pro vyhledávání v nějaké datové struktuře, nejen seznamu (BVS) lookup(K, Tab, H):- member(K-H, Tab). DC: lookup2D/3: vyhledávání pro dvousložkový klíč, v rovině

První a poslední prvek seznamu % first(?X,+L) :- X je první v L a) first(X,[X|_]). % dobrý styl b) first(X,L):- L=[X|_]. % last(?X,+L) :- X je poslední v L last(X,[X]). last(X,[_|L]):- last(X,L). %nesymetrický přístup: O(1) na první prvek vs. O(n) na poslední

Spojení seznamů - append(L1,L2,L3) spojí L1 a L2 do L3 append([],L,L). append([X|L1],L2,[X|L3]):- append(L1,L2,L3). ?- append([a,b],[c,d],[a,b,c,d]). %(+,+,+) yes ?- append([a,b],[c,d],L). % mod (+,+,-) L=[a,b,c,d]; no - programátorské idiomy: strukturální rekurze podle prvního arg., tvorba výsledku - skládáním substitucí -Pozn.: polymorfizmus – analyzuje a využívá se pouze „horní“ struktura

?- X=[a,b], Y=[c,d], append(X,Y,Z). Z=[a,b,c,d] tvorba Z - skládáním substitucí Z = _L3´ Z = [a|_L3´´] Z = [a,b|_L3´´´] Z = [a,b,c,d] X Z Y.. \. / \. / \.. a / \ c / \ [] [] b d

append/3 jako (nederministický) generátor ?- append(L1,L2,[a,b,c]). % (-,-,+) L1=[] L2=[a,b,c]; L1=[a] L2=[b,c]; L1=[a,b] L2=[c]; L1=[a,b,c] L2=[]; no

concat/2 – Spojení seznamů - převod (řádkové) matice na vektor % concat(+L,-K) – seznam seznamů L spojí do jednoúrovňového seznamu K concat([], []). concat([Xs|L1],L0) :- append(Xs,L2,L0), concat(L1,L2). ?- concat([[1,2],[5],[],[3,4]],Lout). Lout=[1,2,5,3,4] -Počas výpočtu je L0 seznam s volným koncem -L0=[1,2|L2’] ~> [1,2,5|L2’’] ~> [1,2,5,3,4|L2’’’] ~> [1,2,5,3,4] -Nelze použít concat(-,+) pro rozdělení; generuje Xs=[]

Obracení seznamu % reverse(L,R):- R je L pozpátku % mod (+,-) reverse([],[]). reverse([X|L],R):- reverse(L,R1), append(R1,[X],R). - nepříjemnost: složitost O(n^2) - typická struktura rekurzívních klauzulí pred :- předvýpočet, % analýza d.s. pred, % rek. výpočet mezivýsl. postvýpočet. % použití -”-

Obracení seznamu II - lineárně reverse(L,R):- rev1(L,[],R). rev1([],R,R). % mod (+,+,-) rev1([X|L],A,R):- rev1(L,[X|A],R). - programátorská technika - akumulátor: “A” - inicializace - samostatná klauzule/predikát - odstínění uživatele od technických detailů - předávání (volné) výstupní prom. v rek.: “R” - obvykle samostatný argument - ukončení - předání: “R:=A” %3.arg := 2.arg x skládání substitucí - přístup na akum. počas výpočtu

Vypouštění prvku % delete(X,I,O):- vypuštěním X ze seznamu I je seznam O; X musí být v I, vypouštíme jeden (lib.) výskyt % mody vypouštění (?,+,-), vkládání (?,-,+); presneji (?,[?],-) delete(X,[X|I],I).%1 X musí být v arg2 delete(X,[Y|I],[Y|O]):-%2 delete(X,I,O). ?- delete(X,[1,2,3],O). % 3 výsledky ?- delete(a,I,[b,c]). %vkládání,3x Varianta: delete1/3: vypustí prvek a vždy uspěje delete1(X,[],[]).%3+^1+^2: falešné matche! Nekorektní další výsledky; správnost všech v.! DC: deleteAll(X,Lin,Lout);

Permutace % perm(I,O):- O je permutací I, (+,-) perm([],[]). perm(I,[X|O]):- delete(X,I,I1), perm(I1,O). ?- perm([1,2,3,4],O). - skládání substitucí - rekurze podle výstupu - nederminizmus: řešení se vrací postupně - jiná (těžší) možnost: vrátit najednou seznam všech permutací - DC: permutace rekurzí podle vstupu. V jakém pořadí budou vydávány?

Použití append/3 last(X,L):- append(_,[X],L). - stejná asymptotická složitost - horší konkrétní složitost, ošetřujeme v append 1.arg. zbytečně delete(X,I,O):- append(L1,[X|L2],I), append(L1, L2, O). - L1 se prochází 2x - nejde použít v modu (?,-,+) - muselo by se napsat jinak: prohodit cíle v těle prefix/2, suffix/2 - zdarma (bez rekurze) prefix(P,L):- append(P,_,L). Pozn. SwIng: budování konkrétních predikátů zvrchu vs. obecné predikáty zespodu (do knihoven) a příp. interface. Při (častých) změnách méně výkonného kódu ~> méně úprav a chyb

Seznam výsledků % suffix(+L,-S) – S je přípona L, backtrackingem suffix(S,S).% zahrnuje suffix([],[]). suffix([_|L],S):- suffix(L,S). ?- suffix([1,2,3],L). L=[1,2,3] ; L=[2,3] ; L=[3] ; L=[] ; no % suffixy(+L,-Ss) – Ss jsou všechny prípony L v seznamu suffixy([],[[]]). suffixy([X|Xs],[[X|Xs]|Ss]):- suffixy(Xs,Ss). ?- suffixy([1,2,3],Ss). Ss=[[1,2,3],[2,3],[3],[]]% typicky vhodnější

Prefixy % prefixy(+Xs,-Ps)- Ps je seznam všech předpon Xs prefixy([],[[]]). prefixy([X|Xs],[[]|P0]) :- prefixy(Xs,P1), map_pridejH(X,P1,P0).% (1) prefixy v P1 upravíme % přidáva hlavu ke každému seznamu v P1 map_pridejH(_X,[],[]).% jednoúčelové map map_pridejH( X,[P|Ps],[[X|P]|Ps0]):- map_pridejH(X,Ps,Ps0). ?- prefixy([1,2,3],Ps). Ps=[[],[1],[1,2],[1,2,3]] - Průběžně: Ps’=[[],[2],[2,3]], Ps’’=[[],[3]], Ps’’’=[[]] - (1) obecné map:..,map(pridejH(X),P1,P0),… -pridejH(X,L,[X|L]). % mimo logiku 1. řádu

Seznam prvků ve stromu tree2list(Strom,Seznam) :- do Seznamu pozbírá prvky Stromu (zleva doprava) tree2list(void,[]). tree2list(t(L,X,R),O):- tree2list(L,OL), %rekurze doleva tree2list(R,OR), %rekurze doprava append(OL,[X|OR],O). % spojení inorder - seznam jako výsledek -pre-,post-,inorder (zleva): rozdíl toku programu a “toku” dat -append/3 na stejném místě, ale s jinak předávanými parametry - pro generování  stromů (mod (-,+) ) nutno prohodit cíle - pro repr. stromů použít funkční symbol t/3, a void/0 - nevhodný je (zde trojprvkový) seznam, pokud je počet položek pevný ?- TestData = t( t(void,1,void), 2, t(void,3,void)), tree2list(TestData,V).

Výroba vyváženého stromu - z (uspořádaného) seznamu L chci vyvážený strom T % vyvazBS(+L,-T). vyvazBS([],void). %vyvazBS([X],t(void,X,void)). %konc.podm.není nutná vyvazBS(L,t(TL,X,TR)):- rozdel(L,L1,[X|L2]),% rozdělí na poloviny % pro uspořádaný seznam L: X je medián vyvazBS(L1,TL), vyvazBS(L2,TR). - vyvazBS/2 lze použít v heapsortu pro vybudování správné struktury „haldy“ (bez uspořádání)

Rozdel/3 -rozdel(L,L1,L2) – rozdělí L na první a druhou polovinu, |L1|<=|L2|<=|L1|+1 -Použije v rozdel1/4 druhý arg. jako čítač rozdel(L,L1,L2):- rozdel1(L,L,L1,L2). % interface rozdel1(L2,[],[],L2).% sudá délka rozdel1(L2,[_],[],L2).% lichá délka rozdel1([X|L],[_,_|Acc],[X|L1],L2):- rozdel1(L,Acc,L1,L2).

Množinové výrazy -Výraz obsahuje +/2 pro sjednocení, */2 pro průnik, -/2 pro rozdíl, seznam pro množinu a i(D,H) pro celočíselný interval. - evalS: interpret množinových výrazů, term je program porovnejte s Aho-Corasick: vzorky (1) jsou program (v neplnohodnotném jazyce, doménově specifický jazyk - DSL), který dokonce dokážeme přeložit ad(1): vzorky jsou seznam seznamů (reprezentací) znaků, např. [[h,e],[s,h,e],[h,e,r]] ?- evalS(-(+([3,1,3],i(2,4)),[2,3]), S). S = [1,4] % synt. cukr: zápis s operátory ?-evalS(([3,1,3]+ i(2,4))–[2,3], S). evalS(L,S):- isList(L), list2set(L,S). % převod na (usp.) množinu evalS(i(D,H),S) :- genInterval(D,H,S). evalS(+(E1,E2),S):-evalS(E1,S1), evalS(E2,S2),union(S1,S2,S). evalS(-(E1,E2),S):-evalS(E1,S1), evalS(E2,S2), rozdilS(S1,S2,S). evalS(*(E1,E2),S):-evalS(E1,S1), evalS(E2,S2),prunik(S1,S2,S). -lze použít pro uspořádané i neuspořádané  množiny na výst. -Impl. se liší ve výkonných pred. union/3, …, list2set/2, genInterval/2. -DC: interpret multimnožinových výrazů

Shrnutí - tok dat, mody - dvojí použití predikátů: výpočet, test - problémy s podspecifikovanými argumenty v cíli - nedeterminizmus - zpracování rek. struktur - strukturální rekurze - tvorba výsledků - skládáním substitucí - akumulátor -použít interface: pokud rekurzi nejde použít přímo (např. je potřebný „lokální“ argument) - dobrý styl: nezatěžovat uživatele „technickými“ zbytečnostmi - seznam výsledků, místo vracení backtrackingem - o rekurzi víte vše, dále vestavěné predikáty, programátorské techniky a příklady

Autotest naprogramujte permutace pomocí vkládání prvku a akumulátoru návod: použijte akumulátor na permutaci dosud zpracovaného prefixu vstupního seznamu napište rozdělení prvků seznamu na sudé a liché (podle pořadí) - v jednom průchodu seznamem - správně ošetřete seznam liché délky - použití v “rozděl a panuj”: mergesort ? je append/3 použitelný v modu (+,-,-) ? jak se bude chovat volání: append([a,b],X,Y) - pokud má otázka smysl