vestavěné predikáty a jejich použití (5)
DESCRIPTION
Vestavěné predikáty a jejich použití (5). Jan Hric, KTI MFF UK, 1997- 20 10a http://kti.ms.mff.cuni.cz/~hric. 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í - PowerPoint PPT PresentationTRANSCRIPT
Vestavěné predikáty a jejich použití (5)
Jan Hric, KTI MFF UK,1997-2010a
http://kti.ms.mff.cuni.cz/~hric
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í
Uspořádání termů
@</2, @>/2, @=</2, @>=/2 vzestupné pořadí: proměnné podle adresy atomy .. ascii hodnoty lexikograficky řetězce .. dtto čísla (int, float) .. hodnoty struktury .. dtto (LPA) konjunkce @< disjunkce
compare(Rel,T1,T2) Rel je <, =, >
Compare/3 - idea použití
umožňuje získat explicitní informaci o porovnání (tj. jako data místo stavu programu) vs. výsledek porovnání je dán postupem výpočtu
(hodnotou “Instruction Pointer”) aritm_rozskok(X,Y):- compare(Rel,X,Y),
rozskok(Rel,X,Y).rozskok(<,X,Y):- spracuj_X<Y .rozskok(=,X,Y):- spracuj_X=Y .rozskok(>,X,Y):- spracuj_X>Y .
Test shody termů
= vykoná unifikaci (a případně substituce) chceme: test termů (s proměnnými) na shodu
bez vykonání unifikace ==/2, \==/2
?- X=Y. uspěje?- X==Y. neuspěje?- X=Y, X==Y. uspěje X = Y = _1 odpověď
Test typu termu
atom/1 argument je atom atomic/1 arg. je konstanta, atom nebo číslo integer/1, float/1, number/1 var/1, nonvar/1, ground/1 (LPA) type(Term,Typ) vráti typ termu compound/1 arg. je složený, tj. neprázdný
seznam nebo struktura
Rozbor složených termů functor(Term, Functor, Arita)
k termu určí funktor a aritu; mod (+,?,?) k funktoru a aritě vytvoří term; mod (?,+,+)
arg(+N,+Term,?Argument) vybere n-tý arg. z Termu a unifikuje s Argument
X=..L % „univ“, mody (+,?) nebo (?,+) rozloží strukturu X na seznam funktor a argumenty?- f(a,g(b))=.. [f,a,g(b)]?- [a,b]=..[.,a,[b]] Nepoužívat, pokud je funkční s. známý (např. seznamy, bin.
stromy, log. fle) Určeno pro situace, kdy je vstup obecný term (s lib. funk. symboly) např: unifikace (viz), crossreference programu/termu, zpracování
programů …
Př.: Unifikace
unify(X,Y):- atomic(X), atomic(Y), X=Y.unify(X,Y):- var(X), X=Y ; var(Y), Y=X.unify(X,Y):- % struktury X=..[FX|AX], Y=..[FY|AY], % rozebrání FX=FY, % shoda funktorů unify_arg(AX,AY). % kontroluje i stejný #arg.unify_arg([],[]).unify_arg([X|AX],[Y|AY]):- unify(X,Y), unify_arg(AX,AY). Idea: unify_arg(AX,AY):-foreach(unify,AX,AY).
Unifikace II
unifikace struktur - varianta:unify(X,Y):- % struktury functor(X,FX,NX), functor(Y,FY,NY), FX=FY, % shoda funktorů NX=NY, % shoda počtu argumentů X=..[_FX|AX], Y=..[_FY|AY], % rozebrání unify_arg(AX,AY). % nepřímá rekurze Další varianty: viz Autotest
poznámky k foreach/3
Lepší abstrakce, standardní idiom Nemusí být podporováno jazykem I když konstrukci jazyk nepodporuje, lze ji
považovat za makro a vygenerovat zdrojak Tj. (způsob) rozšíření jazyka
V čistém Prologu (v logice 1. řádu) nejsou „funkcionální“ parametry -> opakování kódu Nahrazuje programování „kopírováním bloků“
...
Převod textových reprezentací
name(Konstanta,Retezec) mod (+,?) nebo (?,+) konstantu (atom, číslo) převede na řetězec znaků ?- name(abc,”abc”). ?- name(123,”123”).
použití: generování nových (jmen) konstant, predikátů, kompaktní reprezentace slov/textu, ... ale: nová jména: c(0) místo c0, vrchol(v,1) místo v1
Volba reprezentace: potřebné složky v termu datum(2005,10,31) vs. d051031 vs. “d051031”,“05/10/31”
Operátory
(pouze!) syntaktická konvence, syntaktický cukr umožňují pohodlnější zápis bez nadbytečných
závorek (dělá to mnohem méně než si myslíte)
nemění vnitřní reprezentaci termů (!)převod na vnitřní reprezentaci je (vždy) jednoznačný
Zdrojový kód vs. právnické texty, přirozený jazyk, uživ. specifikace
deklarace nezavede nový predikát/funkční symbol (!)nezmění (nerozšíří) chování is/2
lze použít pro termy i predikátypředdefinované operátory jsou i :- ; , ->
Deklarace operátorů :-op(Precedence, Druh, Jmeno).
deklarace je součást zdrojového kódu (v souboru) deklarace se vykonává, proto je uvedena :-
Nechci přidat fakt op/3, ale způsobit změnu interních tabulek Jmeno je jeden atom nebo seznam atomů; tyto atomy se
(pře)deklarují s danou precedencí a asociativitou deklarace je globální, platí pro všechny další čtení
(programu i dat) Precedence je přirozené číslo mezi 1 a 1200 (SWI, LPA)
Vyšší precedence je výš v termu, tj. později se váže opačně než priorita v matematice
Druh určuje druh a asociativitu (binární) infixní, (unární) pre-, postfixní doprava asociativní, doleva a., neasociativní
Operátory (pokrač.)
vyjádření druhu a asociativity prefixní: fx fy mínus,
negace postfixní: xf yf faktoriál infixní: xfy yfx xfx +, *, &, <, = pravěasoc.(^) levěasoc.(+) neasociativní (=)
význam písmenek: f - poloha funktoru, x - term s ostře nižší precedencí, y - term s nižší nebo stejnou precedencí
Operátory (pokrač.)závorky mají přednost při určování struktury termu
(jako obvykle)speciálně: precedence = 0 ruší deklaraci op.lexikální problém závorek, čárky a tečky
f(...) versus op (...) % významná mezera před (f(a,b) versus f((a,b)) …=f(’,’(a,b))a.b.[] vs. a. b. [] % významná mezera za . (tečkou)
- konec klauzule: tečka, bílý znak; chybně: .<EOF>př.: :-op(500,yfx, [+,-]).a+b+c yfx: (a+b)+c /*předdefinováno*/ xfy: a+(b+c)a=b=c xfx není povoleno, musíme uvést závorky, jinak synt. chyba
Operátory Příklad: pro doménu výrokových logických formulí:- op(500,xfx,ekv). % neasociativní:- op(400,xfy,imp). % doprava: A imp (B imp C):- op(300,yfx,or). % doleva: (A or B) or C:- op(290,yfx,and). :- op(200, fy,non). % fy umožní psát non non p(x) anebo:- op(500,xfx,<=>).:- op(400,xfy, =>). :- op(300,yfx, #). % or:- op(290,yfx, &). :- op(200, fy, \\\). % \\\ \\\ p(x)Umožnuje psát: eval( p(x)&p(y)=>p(y)&p(x), Prom,V).Místo: eval( =>(&(p(x),p(y)),&(p(y),p(x))), Prom,V). Přidání xor: :-op(301,yfx,xor). – pouze deklarace operátoru
Všechny knihovní procedury musím změnit – přidat zpracování xor/2 Jiné domény: kompozice obrázků (vedle, nad, přes, …), …
Operátory - příklad zpracování množin (analogicky is/2): is_set/2 sjednocení \-/ , průnik /-\ , seznamy
uspořádané vs. neuspořádané seznamy (ve skutečnosti asi Pascalská konvence +,*)
:- op(700,xfx,is_set).:- op(510,yfx,/-\).:- op(511,yfx,\-/). :- op(512,fx,suma).X is_set X :- seznam(X). % lépe: list2set(X,X0)X is_set Y\-/Z :- VY is_set Y, VZ is_set Z, sjednoceni(VY,VZ,X). /*mergesort*/X is_set Y/-\Z :- VY is_set Y, VZ is_set Z, prunik(VY,VZ,X). X is_set suma Y:- VY is_set Y, suma_množiny(VY,X). ?- X is_set ([1,2]\-/[3,4]) /-\ [2,3].?- is_set(X, /-\( \-/( [1,2], [3,4]), [2,3])).
Zjišťování definic operátorů
current_op(Prec, Asoc, Jmeno) mod (?,?,?) vrací backtrackingem všechny aktuálně
definované operátory ?- current_op(X,Y,is_set).?- current_op(510,Y,Z).
?- current_op(X,Y,Z). všechny aktuálně definované operátory, viz následující
tabulka
Předdefinované operátory (SWI)op( 200, xfx, **). op( 200, xfy, ^).op( 300, xfx, mod). /*LPA Prolog*/op( 400, yfx, [<<, /, //, >>, *, xor, mod, rem]).op( 500, yfx, [-, +, \/, /\]).op( 500, fx, [-, +, \, ?]).op( 600, xfy, : ).op( 700, xfx, [>, =, <, >=, =<, \=, @< ... @\=, =:=, =\=, is, =.., ==, \== ]).op( 850, yfx, [~>, <~]).op( 900, fy, [spy, nospy, \+, not, one]).op(1000, xfy, ’,’). % =< jsou pred. spojky, ()op(1050, xfy, -> ).op(1100, xfy, [’;’, ’|’]).op(1150, fx, [dynamic,public,multifile]). % a dalšíop(1200, xfx, [:-, -->]).op(1200, fx, [:-, ?-]).
Operátory na úrovni cílů
Příklad: (náchylné k chybám)a:- predzpracovani, % není součást testu, kvůli záv.
( test1->then1 % (1) závorky nutné ; test2->then2 % (2) syntakticky jsou ; a -> binární ; else ),
postzpracovani. % není součást else Při zpracování prologovských programů: pokud se
používají operátory (s prec. >= 1000) pro tvorbu klauzulí (tj. :- , ; ->) jako termy, musí se uzavřít do dodatečných závorek: testDisj((X ; Y)) :- …
(Operátory - dodatek) V Prologu jsou pouze infixové a unární operátory operátorovou syntaxi lze rozšířit
operátory s více klíčovými slovy if _ then _ else
distfixní (uzavřené) operátory i závorky lze takto chápat – např. XML uživatelské definice nových druhů závorek
– např. pro speciální (vnořenou) syntax syntaktická analýza je (velmi) jednoduchá
variabilní a opakované operátory seznamová notace jako operátor [ , | ]
dvourozměrná syntax (v Haskelli …) indentace namísto oddělovačů
Autotest unifikace pomocí přímého výběru
unifikovaných argumentů použít arg/3 ve “for” cyklu podle počtu arg.
pozbírat z termu všechny (konstanty, proměnné, podtermy)
použití =.. , var, ... funkční symboly, s četností, s počtem výskytů
funktor, is ... (proměnné bez opakování)
==, =
(navrhnout operátory pro bool. výrazy)