210 likes | 296 Views
Prolog (8). Jan Hric, KTI MFF UK,1997 -20 10a http://kti.ms.mff.cuni.cz/~hric. Heuristické prohledávání grafu. Heuristicke prohledavani, pomoci prioritni fronty, vybirame vrchol, ktery ma nejbliz do Cile interface grafu: start/1, solution/1, child/2 (anebo children/2)
E N D
Prolog (8) Jan Hric, KTI MFF UK,1997-2010a http://kti.ms.mff.cuni.cz/~hric
Heuristické prohledávání grafu Heuristicke prohledavani, pomoci prioritni fronty, vybirame vrchol, ktery ma nejbliz do Cile • interface grafu: start/1, solution/1, child/2 (anebo children/2) • interface heuristiky: estimate_goal(+Node, - Estimate) • interface haldy: empty_heap(-H), add_heap(+H0,+Cost,+Node,-H), get_from_heap/4 % ADT • knihovna: keysort/2, ord_union/4 best_first(Answer):- start(Start), initial_heap(Start, Heap), best_star(Heap,[Start],Answer), % b_s(otevrene, uzavrene, answer) solution(Answer). initial_heap(Start,Heap):- estimate_goal(Start, Estimate), % odhad ceny do cile empty_heap(Empty), add_heap(Empty, Estimate, Start, Heap). % pridani startu do haldy best_star(Heap, Closed, Answer):- get_from_heap(Heap, _, Node, Heap1), % vraci min. z haldy ( Answer=Node % akt. Vrchol na vystup ; children_4(Node, Closed,Closed1, Heap1, Heap2), % deti aktualniho Node best_star( Heap2, Closed1, Answer) % rekurze, s novymi akumulatory ). children_4(ParentNode, Closed, Closed1, Heap, Heap1):- % pridani deti ordered_children(ParentNode,Closed,Closed1, OrdPairs), % zjisteni sjedn. a novych vrcholu add_children(OrdPairs, Heap, Heap1). % vlastni pridani do haldy, bez opakovani(!)
Heuristicke prohledavani grafu 2 ordered_children(ParentNode, Closed, Closed1, OrdPairs):- children(ParentNode, ChildrenSet), ord_union(Closed, ChildrenSet, Closed1, NewChildren), % z knihovny compute_ranks(NewChildren, RawPairs), keysort(RawPairs,OrdPairs). % usporadani podle klice-kriteria compute_ranks([],[]). compute_ranks([Child|Children],[Estimate-Child|Pairs]):- % vyroba seznamu vrcholu s odhadem estimate_goal(Child, Estimate), % pouziti heuristiky compute_ranks(Children, Pairs). add_children([],Heap, Heap). add_children([Estimate-Child|Children], Heap0, Heap):- % pridani novych v. na haldu add_heap(Heap0,Estimate, Child, Heap1), add_children(Children,Heap1,Heap). - v umělé inteligenci alg. A* pro hledání nejkratší cesty - seřazení vrcholů podle ceny: součet ceny od startu a odhadu do cíle(jiná interpretace estimate_goal/2)
Dámy na šachovnici (generuj a testuj) queens(N,Queens):- length(Queens,N), % volné proměnné: Qs=[_,_,_, …] rows_columns(Queens,Rows,Cols,0), % čísluje Rows od 1 % Qs=[1-C1, 2-C2, 3-C3, …] perm(Rows,Cols), % naváže Cols; generuj … noattack(Queens). % … a testuj, rows_columns([],[],[],_). % výroba dvojic, řádků a (volných) sloupců rows_columns([R-C|Queens],[R|Rs],[C|Cs],R0) :- R is R0+1, row_columns(Queens,Rs,Cs,R). % R je posl. vygener. sloupec noattack([]). % kontrola neohrožování na celé desce noattack([R-C|Queens]):- noattack(Queens,R,C),noattack(Queens). noattack([],_,_). % kontrola ostatních vůči jedné noattack([R2-C2|Queens], R1, C1):- % kontrola ostatních vůči jedné R2 + C2 =\= R1 + C1, R2 – C2 =\= R1 – C1, % různá diagonála noattack(Queens, R1,C1) %
Eliza – z oboru Umělé Inteligence Eliza – simulace rozhovoru s psychoanalytikem (pp.151) Fraze = [[w(i),s(X),w(my),s(Y)]-[w(your),s(Y),s([?,why,do,you]),s(X),s([it,?])], …], KlicFraze = [mother-[s(X)]*[s([tell,me,more,about,your,family])], alike-[s(X)]*[in,what,way,?],…], % data: každý uživatel má svoje odezva(Fraze,KlicFraze,Veta,Odezva):- ( member(VzorF-VzorO,Fraze) % přímé reakce ; member(Klic,Veta), member(Klic-VzorF*VzorO,KlicFraze) %reakce podle klíče ), match(VzorF,Veta), match(VzorO,Odezva), % porovnani vzoru a odpoved match([],[]). match([Vzor|Vzory], [Slovo|Slova]):- match(Vzor, Vzory, Slovo, Slova). match(w(Slovo),Vzory,Slovo,Slova):- match(Vzory,Slova). % porovnani slova match(s([Slovo|Seg]),Vzory,Slovo,Slova0):- append(Seg,Slova1, Slova0), match(Vzory,Slova1).%porovnani segmentu, nedeterministicky ?- odezva(F,KF,[i,like,my,job],O). O=[your,job,?,why,do,you, like,it,?] - vyloučení opakování reakcí, pamatování si klíčů a návrat k tématům (ze zásobníku)
Eliza - příklad > all men are alike. % klíč. slovo In what way ? > they always want the same thing. Can you be more specific ? > are you trying to be funny? % vzor: are you X Would you prefer it if I weren't trying to be funny ? %..weren’t Y > computers are stupid. % X are Y What if they were not stupid ? % ... were not Y > This conversation is silly. % bez klíče I'm sorry. Could you please rephrase that ? > .
Plánování interpretace datové struktury struktura plánů: Act1 // Act2 - paralelní vykonávání Act1 , Act2 - nejprve Act1, pak Act2 do(BasicAct) - vykonej primitivní akci execute(Plan) – jako Popis, kde plan(Plan, Popis) informace o BasicAct precond(BA1,BA2) – před BA1 se musí uskutečnit BA2 cost(BA, Cena) - cena zákl. plánu • spočítání ceny plánu (pp. 267) plan_cost(Plan, Cost) :- plan_cost(Plan,0,Cost). plan_cost(Act1 // Act2, C0, C):- plan_cost(Act1,C0,C1), plan_cost(Act2,C1,C). plan_cost((Act1,Act2), C0, C):- plan_cost(Act1,C0,C1), plan_cost(Act2,C1,C). plan_cost(do(BasicAct), C0, C):- cost(BasicAct, Cost), C is C0+Cost. plan_cost(execute(Name), C0, C):- plan(Name,Plan), plan_cost(Plan,C0,C). - skontrolování správnosti plánu
(Práce s databází) • assert(C), assertz(C) -vloží klauzuli na konec db. • asserta(C) .. vloží na začátek db. • př.: assert((member(X,[_|L]):-member(X,L)). • závorky kolem (částí) klauzulí :- -> ; , • retract(C) .. vypustí klauzuli z db. • nesubstituuje za volné výstupní proměnné • statické vs. dynamické predikáty. • :- dynamic append/3. % direktiva v zdroj.soub., • Informace pro kompilátor, že se pracuje s predikátem dynamicky • abolish(P/N) .. zničí definici P/N • ?- abolish([p/1,q/2]). • databáze záznamů (blackboard), impl. závislé (SWI ) • recorda(+Klic,+Hodn), recordz(+K,+H), recorded(+K,-H), erase(+K)
Clause • umožňuje přístup do databáze • clause(Hlava,Telo) • Hlava musí určit aspoň jméno a četnost predikátu ?- clause(member(A,B),C). A=_1 B=[_1|_2] C=true ; A=_1 B=[_2|_3] C=member(_1,_3) ; no • fakty vrací: Telo = true
Datové struktury • binární stromy void/0, t/3 • map_t(P,T1,T0) • St má 4 param. ; 3 vstupní a 1 výstupní • 2-3 stromy: void/0, t2/3, t3/5 • map_t23(P,T1,T0) • Asociativní seznam: nil/0, cons/3 (klic, hodn, AS) • ... • map může převádět na jiné struktury: seznam • seznam klíčů, seznam hodnot ...
Neúplné datové struktury • (vyhledávací slovník) • rozdílové seznamy • graf • pointry jsou realizovány vazbami proměnných • problémy se změnami (log. prom.) • při změně se struktura kopíruje • pro Prolog jsou strukt. “nekonečné” • problém s výpisy, unifikací ...
Rozdílové seznamy • umožňují spojení seznamů v konstantním čase • k danému seznamu je možné připojit jen jeden seznam • je přístupný konec seznamu pomocí volné (logické) proměnné • idea: [a,b,c] ~> [a,b,c|K]-K; []~>K-K • rozdílový seznam - d.s.: Začátek - Konec • převody: seznam <~> rozdíl. seznam • list2dlist(L,Z-K):- append(L,K,Z). • append/3 ušetříme, pouze pokud nepřevádíme • dlist2list(L-[],L). • dappend(Z1-K1,Z2-K2,Z1-K2):-K1=Z2. %...
Aplikace r. seznamů • Program: qsort([],Z-Z). qsort([X|L],Z-K):- split(X,L,L1,L2), qsort(L1,Z-[X|K1]), % přidání prvku X nakonec qsort(L2,K1-K). • volání: ?- qsort([3,1,4,2],V-[]). • Argumenty lze předat samostatně, podobné akumulátoru • 2.arg je výstup, 3. arg je akumulátor,který naplňujeme odzadu ?- qsort([3,1,4,2],V,[]).
Kompilace • aritm. výrazu, do zásobníkového stroje • :- op(600,xfx, :=). • ?- cc(var(a):=var(b)+const(1), Kod,[]). % volání • Kod=[load(b),load(const(1)),plus,store(a)] cc(var(V),[load(V)|Kod],Kod). cc(const(C),[load(const(C))|Kod],Kod). cc(V1+V2, Kod1,Kod3):- cc(V1,Kod1,Kod2), cc(V2,Kod2,[plus|Kod3]). % postfixní kód cc(var(V):=Vyr,Kod1,Kod2):- cc(Vyr,Kod1,[store(V)|Kod2]). • Podobně interpretace výrazu
Kompilace příkazů • DC • faktorial cc(( read(i); j:=1; while(i>0, ( j:= j*i; i:= i-1 ) ); write(j) ), Kod,[]).
Programování s omezujícími podmínkami • Prolog řeší rovnice nad “symbolickými” výrazy • jiné domény: reálná čísla, konečné domény, řetězce, množiny, grafy ... • interface Prolog - řešič • Prolog posílá podmínky (a odebírá), deklarativně • řešič vrací “soustava podmínek je řešitelná” • na konci výpočtu: nějaký tvar řešení • zjednodušené podmínky (vyřešený tvar) • posloupnost řešení • př.: rovnice nad reálnými čísly • vyřešené lineární rovnice a nerovnice s par. • zbylé nelineární podm.
Konečné domény • řešení kombinatorických problémů • grafy, plánování ... • místo “generuj a testuj”: “omez a generuj” • obarvení grafu n barvami • pro v_i prom. X_i • pro hranu v_i - v_j podm. X_i\=X_j • domény: X_i :: {1,2,..n} • Prakticky používané systémy • Eclipse • ILOG solver - knihovny řešiče a interface pro C
Příště • funkcionální programování ...
Binární vyhl. stromy • %insert(X,I,O) • insert(X,void,t(void,X,void). • insert(X,t(L,Y,R),t(L1,Y,R):-X@=<Y,insert(X,L,L1). • insert(X,t(L,Y,R),t(L,Y,R1):-X@>Y,insert(X,R,R1).
Insert do AVL stromu • strukt: v/0, t(Levy,Koren, < = >, Pravy) • i(+Strom, +Y, -NovyStrom, +deltaHloubky: inc,noinc) - insert i(v,Y,t(v,Y,=,v),inc). % dále pouze přidávání do levého podstromu i(t(L,X,V,R),Y,t(L0,X,V0,R),DH0):-Y@<X,(V= =;V= <), i(L,Y,L0,DH), upd0(V,DH,V0,DH0). %bez změny hloubky i(t(t(LL,LX,LV,LR),X,>,R),Y,t(LL0,LX,LV0,t(LR,X,=,R),DH0):- Y@<LX, (LV= =;LV= <), i(LL,Y,LL0,DH), upd1(LV,DH,LV0,DH0). %jednoduchá rotace i(t(t(LL,LX,LV,t(LLL,LLX,LLV,LLR)),X,V,R), Y, t(t(LL,LX,V1,LLL0),LLX,=,t(LLR,X,V3,R)), noinc):- %dvojitá r. Y@<LLX, LX@=<Y, i(LLL,Y,LLL0,DH), upd2(left,LLV,…). i(t(t(LL,LX,LV,t(LLL,LLX,LLV,LLR)),X,V,R), Y, t(t(LL,LX,V1,LLL),LLX,=,t(LLR0,X,V3,R)), noinc):- Y@>=LLX, LX@=<X, i(LLR,Y,LLR0,DH), upd2(right,…). upd0(V,D,V0,D0):- member(f(V,D,V0,D0), [f(X,noinc,X,noinc), f(=,inc,>,inc), f(<,inc, =,noinc)]).% seznam případů místo klauzulí upd1(V,D,V0,D0):- member(f(V,D,V0,D0), [f(=,noinc,<,noinc), f(=,inc,=,inc), f(<,inc,<,inc)]). % ?? upd2(S,V,D,V1,V2,noinc):- member(f(S,V,D,V1,V2), [f(left,>,noinc,>,<), f(_,=,noinc,>,<), f(left,>,inc,=,<), f(left,=,inc,=,=), f(right,>,inc,>,=), f(right,=,inc,>,=)]). • Jiná reprezentace: vyvážení jako čísla -1, 0, +1 .