Vestavěné predikáty a jejich použití Jan Hric, KTI MFF UK 1997-2010c (oprava 4.5.)

Slides:



Advertisements
Podobné prezentace
DOTAZOVACÍ JAZYKY slajdy přednášce DBI006
Advertisements

J. Pokorný 1 DOTAZOVACÍ JAZYKY slajdy přednášce DBI006 J. Pokorný MFF UK
ŘÍDÍCÍ STRUKTURY - PODMÍNKY
Dynamické dokumenty na straně klienta Informatika pro ekonomy II.
Prolog – seznamy Jan Hric, 1997 – 2010b KTIML MFF UK URL:
Třída SIMSET je druhou standardní systémovou třídou, která obsahuje prostředky pro práci se spojovými seznamy. KRUHOVÉ SPOJOVÉ SEZNAMY Spojový seznam –
Ladění, pred. vyšších řádů (7)  Jan Hric, KTI MFF UK, a
Programování funkcí v Excelu
JUI - 3. přednáška Zpracování seznamů, predikátové a vyhodnocovací funkce RNDr. Jiří Dvořák, CSc.
10. Dynamické datové struktury
VISUAL BASIC Práce se soubory.
Programování v Pascalu Přednáška 5 RNDr. Hana Havelková.
Programování v Pascalu Přednáška 9 RNDr. Hana Havelková.
Neprocedurální programování Prolog 1.přednáška
Principy překladačů Mezikód Jakub Yaghob.
Programování v Pascalu Přednáška 7
Programování PA - 2.
Materiály k přednášce Úvod do programování Ondřej Čepek.
Generování mezikódu Jakub Yaghob
ADT Strom.
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.
PHP PHP – základy syntaxe (část 1) - 03 Mgr. Josef Nožička IKT PHP
Databáze Jiří Kalousek.
1IT S ÍŤOVÝ DATOVÝ MODEL Ing. Jiří Šilhán. S ÍŤOVÝ DATOVÝ MODEL Je historicky nejstarším datovým modelem. Jeho základem jsou vzájemně propojené množiny.
Informatika I 3. přednáška
Orbis pictus 21. století Tato prezentace byla vytvořena v rámci projektu.
Vyučovací hodina 1 vyučovací hodina: Opakování z minulé hodiny 5 min Nová látka 20 min Procvičení nové látky 15 min Shrnutí 5 min 2 vyučovací hodiny: Opakování.
A1PRG - Programování – Seminář Ing. Michal Operátory (2. část) 4 Verze
Algoritmy a programovací techniky
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
Stromy.
Predikátová logika.
Počítače a programování 1
Cvičení.
3. Příkazy  Příkazy dělíme na jednoduché a strukturované.  Jednoduché příkazy - žádnou jejich dílčí částí neni příkaz - přiřazovací, vstupu a výstupu,
Reprezentace (6)  Jan Hric, KTI MFF UK, a
Návrh a tvorba WWW Cvičení 4
Orbis pictus 21. století Tato prezentace byla vytvořena v rámci projektu.
VISUAL BASIC PRALG.
Jazyk XML Jazyk pro tvorbu strukturovaných dokumentů Syntaxí velmi podobný HTML Hlavní cíle návrhu: Snadná editace - jazyk je textový Snadné strojové zpracování.
Výroková logika.
STROMY Datová struktura sestávající z uzlů
7. Typ soubor Souborem dat běžně rozumíme uspořádanou množinu dat, uloženou mimo operační paměť počítače (na disku). Pascalský soubor je abstrakcí skutečného.
Programovací jazyk Haskell doc. Dr. Ing. Miroslav Beneš  katedra informatiky, A-1007 
XQuery Dotazovací jazyk XML Daniel Privalenkov. O čem bude prezentace Nutnost dotazovacího jazyku v XML Rychlý přehled XQuery Několik příkladů.
Uživatelem definované typy Ing. Lumír Návrat  katedra informatiky, A 1018 
Počítače a programování 1 7.přednáška. Základy Pole ve třídách a metodách Pole Arrays.
Vestavěné predikáty a jejich použití (5) Jan Hric, KTI MFF UK, a
Predikátová logika1 Predikátová logika 1. řádu Teď „logika naostro“ !
JUI přednáška Vstup a výstup, cykly RNDr. Jiří Dvořák, CSc.
Datové typy a operátory. Co jsou datové typy  Charakterizují proměnnou nebo konstantu – jaká data obsahuje  Data jsou v počítači ukládána jako skupiny.
Prolog (add) Jan Hric, KTI MFF UK, a
Pascal – strukturované příkazy
ACCESS DOTAZY Ing. Jana Horáková IKT MS Office
Algoritmizace a programování Soubory. Oč jde? Vytvoření externího souboru Vytvoření externího souboru Tento soubor může být: Tento soubor může být: Textový.
Tým 32, varianta b/4/I.  Jakub Kadlubiec  Roman Pijáček  Petr Pliska  Jan Štourač  Václav Tunka (vedoucí)
Překladače 6. Sémantická analýza
Výukový materiál zpracován v rámci projektu
Překladače 5. Syntaktická analýza
ZAL – 3. cvičení 2016.
Překladače Syntaktická analýza
Algoritmizace a programování
Programování 2. hodina RNDr. Jan Lánský, Ph.D.
PROLOG strategie vyhodnocení dotazu
Programovací jazyk Haskell
Podprogramy.
ALG 07 Selection sort (Select sort) Insertion sort (Insert sort)
Opakování ze 4. cvičení int a; printf("Zadej číslo: ");
Transkript prezentace:

Vestavěné predikáty a jejich použití Jan Hric, KTI MFF UK c (oprava 4.5.)

Vestavěné predikáty  aritmetika  výpočty, porovnávání  vstup/výstup  spracování termů a atomů  testy druhu, porovnávání, vytváření a dekompozice  řízení spracování  + práce s databází  práce s množinami řešení

Aritmetika  “speciální” predikáty, které vyhod. výrazy  důsledek neexistence typů  operátorová syntax  is/2  vyhodnotí výraz napravo a unifikuje s levou stranou  ?- is(X,1+3), X is 2+2.  is je operátor, oba zápisy jsou možné a rovnocenné  >/2, =/2, =</2, - porov. ar. výr.  =:=/2, =\=/2  vyhodnotí obě strany a porovná výsledky

Aritmetické funkce  které se vyhodnocují: (viz help a manuál, impl.)  + - * / // mod ^  max min rand/1 ip fp  ln log sin cos asin atan...  bitové: /\ \/ > \  ! Nevyhodnocuje se při předávání parametrů  Chybně 1: faktorial(N,...):-  faktorial(N-1,...),...  Přesněji: synt. OK, sem. chybně: ((2-1)-1)-1  Chybně 2: faktorial(N,...):- N is N-1,...  Dtto; proměnnou nelze měnit „na místě“, správně:...N1 is N-1,…

Délka seznamu  aritmetika je jednosměrná (a nedeklarativní) length([],0). % mod (+,?) length([_|L],N):- length(L,N1), N is N1+1.  seznam dané délky (z anonymních prom.) length1(0,[]). % mod (+,?) length1(N,[_|L]):- % impl. N>0,N1 is N-1,length1(N1,L).  test N>0: pro deklarativní správnost, brání cyklu  rozdíl: (+,+) neúspěch: l. po návratě z rek., l1. v hloubce

Unární aritmetika  V Prologu: číselné hodn. lze repr. pomocí termů  Dat. typ: 0 pro 0, s(N) pro n+1 (tj. následníka) ?- plus(s(s(0)),s(s(s(0))), X). % 2+3 je ? X=s(s(s(s(s(0)))))  I jiné reprezentace čísel: délkou seznamu ?- komb(3,[a,b,c,d,e],K). vs ?- komb(s(s(s(0))),[a,b,c,d,e],K). vs ?- K=[_,_,_],komb([a,b,c,d,e],K). %|K| = 3 DC: prostřední prvek, první (a druhá) polovina s.

Insertsort % insert(+X,+L,-V):- zatřídí X do uspořádaného L a výsledek je V ; L je seznam čísel (protože používáme <...) insert(X,[],[X]). insert(X,[Y|L],[X,Y|L]):- X=<Y. insert(X,[Y|L],[Y|V]) :- X>Y, insert(X,L,V). % isort(+L,-V) :- utřídí L do V isort([],[]). isort([X|L],V):- isort(L,V1), insert(X,V1,V).  zobecnění: porovnávací procedura jako parametr

Mergesort % msort(+I::[Int],-O::[Int]) :- utřídí I do O msort([],[]). msort([X],[X]). %nutné obě koncové podm. msort(I,O):- I=[_,_|_], /*% I má aspoň dva prvky */ mergesplit(I,I1,I2), msort(I1,O1), msort(I2,O2), merge(O1,O2,O).  metoda: rozděl a panuj  jinak: mergesplit/3 obsahuje stráž-podmínku  ale pak není univerzální

Slití seznamů: merge/3  Slije uspořádané (číselné) seznamy, vyloučí vícenásobné % merge(+L1,+L2,-L) merge([],L,L). merge(L,[],L):- L\=[]. % bez opakovaných řešení merge([X1|L1],[X2|L2],[X1|L]):- X1<X2, merge(L1,[X2|L2],L). merge([X1|L1],[X2|L2],[X2|L]):- X1>X2, merge([X1|L1],L2,L). merge([X1|L1],[X2|L2],[X1|L]):- % bez opak. prvků X1=X2, merge(L1,L2,L). % test nutný pro dekl. spr.

Rozdělení: mergesplit/3 /* mergesplit(+L,-L1,-L2):- * rozdělí L na sudé (L1) a liché (L2) */ mergesplit([],[],[]). mergesplit([X],[X],[]). mergesplit([X,Y|L],[X|L1],[Y|L2]):- mergesplit(L,L1,L2).  viz autotest z minulé přednášky

Stavba Haldy  Stavba min-haldy přeuspořádáním ze stromu  Použitelné taky pro heapsort heapify(v,v). heapify(t(L,X,R),H):- heapify(L,HL), heapify(R,HR), adjust(X,HL,HR,H). adjust(X,HL,HR,t(HL,X,HR)):- tree_gt(X,HL),tree_gt(X,HR). adjust(X,t(L,X1,R),HR,t(HL,X1,HR)):- X>X1, tree_gt(X1,HR),adjust(X,L,R,HL). adjust(X,HL,t(L,X1,R),t(HL,X1,HR)):- X>X1, tree_gt(X1,HL),adjust(X,L,R,HR). tree_gt(X,v).% progr. technika: lifting, „zvednutí“ =< tree_gt(X,t(_L,X1,_R)) :- X=<X1.

Symbolické derivace  der(výraz, X, derivovaný_výraz), bez zjednodušování der(N,X,0) :- number(N). % test čísla der(X,X,1). % bez symb. parametrů, jiných proměnných a parciálních derivací  der(Y,X,0) :- atom(Y), X\=Y.% derivace podle jiné prom.anebo symb. konstanty der(X^N,X,N*X^N1):- N > 0, N1 is N-1. der(sin(X),X,cos(X)).% pro každou funkci 1 fakt (A) der(cos(X),X,-sin(X)).% anebo: …, (-1)*sin(X) ), když nemáte unární mínus. der(e^X,X,e^X). der(log(X),X,1/X). der(F+G,X,DF+DG):- % pro každý způsob skládání fcí (tj. operátor) 1 pravidlo der(F,X,DF),der(G,X,DG). der(F-G,X,DF-DG):-der(F,X,DF),der(G,X,DG). der(F*G,X, F*DG+DF*G):-der(F,X,DF),der(G,X,DG). der(1/F,X,-DF/(F*F)):-der(F,X,DF). % spec. případ další klauzule der(F/G,X,(G*DF-F*DG)/(G*G)):-der(F,X,DF),der(G,X,DG).  Bez zjednodušování: ?- der(3*x+2,x,D). –> D=(3*1+0*x)+0  Druhá derivace  : nepřehledná  Proměnné: doménové vs. Prologovské  Zde bez složených funkcí, lze implementovat rozepsáním podle vnější fce : der(sin(U),X,cos(U)*DU):-der(U,X,DU). % nahradí fakt (A)  Anebo změnou reprezentace termů: př.: t(sin,[t(^(2),[x])])  der(t(F,[G]),X,t(DF,[G])*DG):- der(G,X,DG), derF(F,DF).  derF(sin,cos). derF(exp,exp). % atd., nedokonalé: log potřebuje jiné (samostatné) pravidlo

N-arní stromy  struktura: t(sezn. podstromů f(klic,hodn,podstrom))% hranově ohodnocené stromy  Místo seznamů i jiné struktury: BVS  ! Vzájemně rekurzivní dat. strukturu ( t/1 a seznamy) zpracujeme vzájemně rek. Predikáty  Varianta: vrcholově ohodncené stromy: t(HodnotaVrch, [podstromy] ) t([f(k1,h1,v),f(k2,h2,t([f(k21,h21,v),f(k22,h22,v)])),f(k3,h3,v)])  Vyhledání složeného klíče s proměnou délkou (podle cesty), tj. vyhledávaní řetězců find([K],t(Ts),H):- member(f(K,H,_),Ts). find([K|Ks],t(Ts),H):- member(f(K,_,Ps),Ts), % jednoprvkový seznam … find(Ks,Ps,H). % … uspěje, ale pak v rekurzi neuspěje prázdný ?- find([k2,k21], T, H). H =h21; no  Datová struktura TRIE: vyhl. podle řetězců  Použitelné pro implemenataci vnořených záznamů s pojmenovanými položkami  Seznamy atribut-hodnota, zde jsou hodnoty strukturovány  Vlastně dopředný vyhledávací strom v alg. Aho-Corasicková  Ale nelze jednoduše odkázat a dostat se na daný podstrom  Aplikace: reprezentace XML, HTML … a jejich zpracování

Logické formule  struktura: true/0, false/0,  p/1…proměnné, explicitní funkční symbol  Nevhodné je negativní vymezení: atomy různé od true a false jsou proměnné  and/2, or/2, non/1, imp/2, ekv/2, (xor/2, nand/2…)  je_lf(LF).. LF je správně utvořená log. formule je_lf(true). je_lf(false). je_lf(p(_)). % elementární f. je_lf(and(A,B)):- je_lf(A), je_lf(B). % kontroluje funkční s. a #arg. je_lf(or(A,B)):- je_lf(A), je_lf(B). je_lf(non(A)):- je_lf(A). je_lf(imp(A,B)):- je_lf(A), je_lf(B). je_lf(ekv(A,B)):- je_lf(A), je_lf(B). % a další spojky… %nelze: je_lf(F(A,B)):- (F=and ; F=or ; F=imp ; F=ekv),…  Pro „dávkové“ ověření korektnosti vstupu z neověřeného zdroje do nekontrolujícího programu (prog. bez kontrol jsou přehlednější / kratší / lepší)  Dvě vrstvy interface: vnitřní nekontrolujíci, vnější kontrolující

Zjednodušování LF  zjedn(F,V) … zjednoduší f. odstraněním konstant zjedn(true,true). zjedn(false,false). zjedn(p(X),p(X)). zjedn(and(F,G),V):- zjedn(F,VF), zjedn(G,VG), zjedn_and(VF,VG,V). % další log. spojky analogicky zjedn(non(F),V):- zjedn(F,VF), zjedn_non(VF,V). zjedn_and(true,F,F). zjedn(F,true,F). zjedn_and(false,F,false). zjedn_and(F,false,false). zjedn_and(F,G,and(F,G)):- F\=true, F\=false, G\=true, G\=false. zjedn_non(true,false). zjedn_non(false,true). zjedn_non(F,non(F)) :- F\=true, F\=false.  Podobně zjednodušování aritmetických výrazů, např. pro derivace

Vyhodnocení LF 1/2  eval(LF,Ps,V).. Vyhodnotí LF s prom. Ps do V eval(true,_Ps,true). eval(false,_Ps,false). eval(p(X),Ps,V):-lookup(X,Ps,V). % vyhledání proměnné eval(and(F,G),Ps,V):-eval(F,Ps,VF), eval(G,Ps,VG), eval_and(VF,VG,V). % analogicky or, non eval(imp(F,G),Ps,V) :- eval(or(non(F),G),Ps,V). %převedení %eval(ekv(F,G),Ps,V) :- % nevhodné, exp. složitost % eval(or(and(F,G),and(non(F),non(G))),Ps,V). eval(ekv(F,G),Ps,V) :- eval(F,Ps,VF), eval(G,Ps,VG), eval(or(and(VF,VG),and(non(VF),non(VG))),Ps,V).

Vyhodnocení LF 2/2  Vlastní sprac. spojek eval_and(false,_VG,false). eval_and(VF,false,false):-VF\=false. %bez opak. řeš. eval_and(VF,VG,true):-VF\=false,VG\=false.  DC: rozšířit LF o sprac. konstanty unk/0 ve významu hodnota není známá, výsledek může být unk  opatrně: eval_ekv(X,X,true). % zdá se OK, ale platí pouze pro X=true a X=false -> přidat podmínky  ?- eval_ekv(unk,unk, true). ?? %rozšíření programu není OK

Typy: btree a log. fle  neformálně: typy pomocí BNF (Backus-Naurova forma)  bude (více) formálně: typy v Haskellu ::= v | t(,, )  dtto bin. strom, s “typem” parametrů ::= v | t(,, )  Typ l.f. ::= true | false | p( ) | and(, ) | or(, ) | non( ) | imp(, ) | ekv(, ) ad p/1: doménová jména proměnných jsou vnořeny v p/1 mají „samostatný namespace“: p(x), p(1), p(true), p(and)

Autotest  převést stručné seznamy čísel na úplné: rozvin/2 ../2 je aritm. posl., krok je daný rozdílem prvních dvou členů  když nejsou, tak default kroku je 1 .. považujme za operátor  jinak je nutné psát: [..(1,10),9,..(8,1)]  [1..6] ==> [1,2,3,4,5,6]  [1,3..6] ==> [1,3,5]  [5,4.. -1] ==> [5,4,3,2,1,0,-1]  jiná konvence: neuvedený krok je +1 nebo -1 podle pořadí mezí: [5.. -1]

Práce s programem  consult(Soubor)  anebo v menu  compile(Soubor)  listing(Co)  Co je Predikat, Predikat/Arita, seznam předcházejících ?- listing([append/3, member]). ?- listing. seznam všech nakonzultovaných predikátů

I/O  Termový  write(X) výpis termu  display(X) výpis bez operátorů, vše v prefixním tvaru  writeq(X) výpis v zpětně čitatelném tvaru, speciálně apostrofy  print(X)  používá portray/1 pro uživatelský výpis (idea: late binding – TVM) Bin. strom: |3|v>, nebo |3| |5|v>>  zkracuje (dlouhé) výpisy: vypíše „horní“ část termu, pak „…“  read(X) čtení jednoho termu s tečkou (a bílým znakem)  term(s(teckou),[na,konci]).  pokud může následovat operátor, musím mít konvenci, jak term ukončit  ! Syntaktická analýza zdarma (pokud reprezentujete vstup termem)  Používá se při čtení klauzulí programu: za tečkou nesmí být EOF  znakový nl, get(X),get0(X), put(X)  X je Ascii kód jednoho přečteného/vypsaného znaku (tj. číslo)  ovládání proudů (vstupního a výstupního)  formátovaný I/O, spolupráce s OS - viz manuál Backtracking nevrací přečtené/vypsané data

Ovládání proudů  vstupní a výstupní proud (stream)  aktuálními proudy jsou použity write, nl, read  vstupní proud  see(+Soubor) přesměruje vstup na Soubor  jméno je atom, často v apostrofech ’c:/home/m.pl’  seeing(?S) vrátí jméno akt. vstup. proudu  seen/0 přesměruje na stand. vstup, zvaný user klávesnice  výstupní proud - analogicky  tell/1, telling/1, told/0  ?-tell(’m.pl’),write(hello),told.  výpis (generovaného) programu „zdarma“  user je obrazovka

Řetězce a ascii kódy  řetězce jsou seznamy ascii kódů znaků  následující zápisy jsou totožné:  ”abc”  [97,98,99] % výpis  [0’a,0’b,0’c]  Ř. využijeme, pokud potřebujeme přístup na znaky, často stačí (a jsou správnou d.s.) atomy  Použitelné pro vstup, čitatelný výst. nutno naprogramovat  ascii kódy znaků:  0’a = 97  ! zápis ’a’ je atom a

Autotest  třídění  výběrem: vybere se minimum jako hlava výsledku a dále rekurze  quicksort  průnik, sjednocení: pro uspořádané seznamy (čísel)  napište predikát, který interní formu řetězců vypíše jako posloupnost znaků v uvozovkách (včetně okrajových uvozovek)  [97,99,98] ~> “acb”

Převod do DNF  dnf(F,V).. V je ekv. formule k F v DNF

Zavěsné mobily (rybičky)  Vyváženost, bezpečnost mobilu: vracíme seznam “chybných” mobilů  (pod)mobily nejsou pojmenované, vracíme celou strukturu mobilu  jiné možnosti: (jednoznačné ) jméno ve struktuře, polohu chyby vůči kořeni  D.s.: m(DelkaL-MobilL, DelkaR-MobilR) nebo z(Hmotnost ) jeVyv(z(H), H, V, V). %mod(+,-,+,-) jeVyv(m(DL-ML,DR-MR),H,V1,V0):- % do V0 se vloží výstupní hodn., podle větve jeVyv(ML,HL,V1,V2), jeVyv(MR,HR,V2,V3), % „stav“ V - tok dat: V1->V2->V3->V0 H is HL+HR, % celková hmotnost (jeVyvKoren(DL,HL,DR,HR) -> V0 = V3% „přiřazení“ výstupu V0 ; V0 = [m(DL-ML,DR-MR)|V3] ).% dtto, se změnou jeVyvKoren(DL,HL, DR,HR):- DL*HL=:=DR*HR. % sémantiku dodá doménový expert jeBezp(z(_H),0,V,V). jeBezp(m(DL-ML,DR-MR), D,V1,V0):- jeBezp(ML,D1,V1,V2), jeBezp(MR,D2,V2,V3), D is max(DL+D1,DR+D2), % delší rameno (jeBezpKoren(DL,D1, DR,D2) -> V0=V3 ; V0 = [m(DL-ML,DR-MR)|V3] ). jeBezpKoren(DL,D1, DR,D2) :- DL+DR > D1+D2.  Programátorský idiom: tok dat předáváním stavu, tj. akumulátor  Při předávání do/z/mezi voláním procedur se stav může změnit – zde: V3 na V0  Programy jsou strukturou podobné, liší se výkonnou částí : chtěli bychom abstrakci

if - then - else  v těle můžeme používat kromě čárky a středníku:  If -> Then ; Else  podmínka se vyhodnocuje 1x, uvnitř částí se může backtrackovat  nebacktrackuje se mezi Then a podmínkou, mezi Then a Else if1->(then % ”->“ a “;” jsou binární operátory stejné ;(if2->(then2 % priority asociované doprava ;(if3->(then3 ;else3 )) )) )

Slití seznamů: merge/3  Slije uspořádané (číselné) seznamy, vyloučí vícenásobné % merge(+L1,+L2,-L) merge([],L,L). merge(L,[],L). merge([X1|L1],[X2|L2],[X|L]):- X1 X=X1,merge(L1,[X2|L2],L) ; X1>X2 -> X=X2,merge([X1|L1],L2,L) ; /*X1=X2*/ X=X1,merge(L1,L2,L).  varianta: každá větev samostatně merge([X1|L1],[X2|L2],[X1|L]):- % X1 ve výst. X1<X2, merge(L1,[X2|L2],L).