270 likes | 403 Views
SLX: Procedimentos para WFSX. SLX (SL with eXplicit negation) é um procedimento top-down para a WFSXp Aqui apresenta-se apenas a caracterização de AND-trees Os detalhes do procedimento estão em [AP96] É semelhante ao SLDNF Os nós são sucedidos ou falhados
E N D
SLX:Procedimentos para WFSX • SLX (SL with eXplicit negation) é um procedimento top-down para a WFSXp • Aqui apresenta-se apenas a caracterização de AND-trees • Os detalhes do procedimento estão em [AP96] • É semelhante ao SLDNF • Os nós são sucedidos ou falhados • Resolução com regras do programa é como em SLDNF • Em SLX, falha não significa falsidade. Quer antes dizer não-veracidade (i.e. falso or indefinido)
Sucesso e falha • Uma árvore finita é sucedida se a sua raiz é sucedida, e falhada se a sua raiz é falhada • O estado dum nó da árvore é determinado por: • Uma folha com um literal objectivo é falhada • Uma folha com true é sucedida • Um nó intermédio é sucedido se todos os seus filhos são sucedidos, e falhado caso contrário
Negação por falha? • Como em SLS, para reslver recursões positivas infinitas, árvores infinitas são (por definição) falhadas • Pode-se usar NAF? Sim True de not A sucede se true-or-undefined de A falha True-or-undefined de not A sucede se true de A falha • É esta a base do SLX. Define: • T-Trees para provar verdade • TU-Trees para provar verdade ou indefinição
T TU T a a b b TU not b not b not a not a … T e TU-trees • Diferem no facto de literais envolvidos em recursão sobre negação, e portanto indefinidos em WFSXp, falham em T-Trees mas sucedem em TU-Trees x a ¬ not b b ¬ not a x x x
a a ¬a not ¬a not ¬a not b not b true b b ¬a not a not a true … Negação explícita em SLX • ¬-literais são tratados como átomos • Para impôr coerência, usa-se versão semi-normal nas TU-trees x x a ¬ not b b ¬ not a ¬a x x x
a not ¬a b ¬b not ¬b not c true c c c c c … not c not c not c not c not c Negação explícita em SLX (2) • Em TU-trees: L também falha se ¬L sucede em T • I.e. se not ¬L falha em TU ¬a not a x x x c ¬ not c b ¬ not c ¬b a ¬ b x x x x x x x
Definição de T e TU-trees • T-Trees (resp TU-trees) são AND-trees etiquetadas por literais, construidas de forma top-down a partir da raiz, expandido nós da seguinte forma • Nós com literal objectivo A • Se não há regras com cabeça A, o nó é uma folha leaf • Caso contrário, seleccione-se não-deterministicamente uma regra para A A ¬ L1,…,Lm, not Lm+1,…, not Ln • Numa T-tree os filhos de A são L1,…,Lm, not Lm+1,…, not Ln • Numa TU-tree A tem, para além daqueles, o filho not ¬A • Nós com default literals são folhas
Sucesso e falha • Todas as árvores infinitas são falhadas. Uma árvore finita é sucedida se a sua raiz é sucedida e falhada caso contrário. O estado dos nós é determinado por: • Uma folha com etiqueta true é sucedida • Uma folha com um literal objectivo é falhada • Uma folha numa T-tree (resp. TU) com etiqueta not A é sucedida se todas as TU-trees (resp. T) com raiz A (árvores subsidiárias) são falhada; é falhada caso contrário • Um nó intermédio é sucedido se todos os seus filhos são sucedidos; caso contrário é falhado • Depois de aplicar todas estas regas, alguns literais podem com estado indeterminado (recursão sobre) • Nós indeterminados em T-trees (resp.TU) são por definição falhados (resp. sucedidos)
WFM is {s, not p, not q, not r} s ¬ not p, not q, not r p ¬ not s, q, not r q ¬ r, not p r ¬ p, not q s r p not q not p not q not r p q not s not r q q not s not r not p r not p r not p not q r p not q p q not s not r Exemplo de árvores infinitas x x x
s ¬ true s q q ¬ not p(0), not s p(N) ¬ not p(s(N)) not p(0) not s true WFM = {s, not q} p(2) p(0) p(0) p(1) p(1) p(2) not p(2) not p(1) not p(3) not p(3) not p(1) not p(2) Exemplo com recursão sobre negação not q 6 x … x x x x … not p(0) x x x
Garantindo terminação • Por causa de loops, este método não é eficaz • Para garantir terminação em programas ground: Ancestors locais dum nó n são literais no caminho entre n e a raiz, excluindo o próprio n Ancestors globaissão atribuidos a árvores: • A árvore raiz não tem ancestors globais • Os ancestors globais de T, uma árvore subsidiária do nó n em T’, são os ancestors globais de T’ mais os ancestors locais de n • Os ancestors globais dividem-se entre aqueles que provêm de T-trees e os que provêm de TU-trees
Regras de Pruning • Para recursão sobre positivos: Regra 1 Se a etiqueta dum nó pertence aos seus ancestors locais, então o nó é falhado e os seus filhos ignorados Para recursão sobre negação: Regra 2 Se um literal L numa T-tree ocorre nos seus ancestors globais-T, então o nó é falhado e os seus filhos ignorados
Regra1 Regra 2 L L L L Regras de prunning (2) …
Outras regras correctas Regra 3 Se um literal L numa T-tree ocorre nos seus ancestors globais-TU, então o nó é falhado e os seus filhos ignorados Regra 4 Se um literal L numa TU-tree ocorre nos seus ancestors globais-T, então o nó é sucedido e os seus filhos ignorados Regra 5 Se um literal L numa TU-tree ocorre nos seus ancestors globais-TU, então o nó é sucedido e os seus filhos ignorados
a ¬a not ¬a not b true 6 Regra 2 a not ¬a b ¬b c b not ¬b not c true not a not c 6 Regra 3 Exemplos de Prunning a ¬ not b b ¬ not a ¬a 6 6 b ¬a c ¬ not c b ¬ not c ¬b a ¬ b not a 6 6 6 6 6
Que fazer? Caso não-ground • A caracterização e regra de prunning só se aplica a programas allowed com perguntas ground • Como é há muito reconhecido, não é possível aplicar regras de prunning no caso geral: p(X) • Se “falha”, então respostas incompletas • Se “continua” então loop p(X) ¬ p(Y) p(a) p(Y) p(Z)
Tabling • Para garantir terminação em programas não-ground, em vez de ancestors e prunning, são necessários mecanismos de tabulação (tabling) • Se há um possível loop, suspender a literal e tentar soluções alternativas • Quando se encontra uma solução, guarda-se numa tabela • Acordar nós suspensos com novas soluções da tabela • Aplicar um algoritmo para determinar a completação do processo, i.e. deerminar quando já não há mais soluções, e falhar restantes nós suspensos
Tabela para p(X) Exemplo de Tabling p(X) ¬ p(Y) p(a) • O XSB-Prolog usa tabling e implementa a WFS • Experimentem em: p(X) 1) suspender X = a p(Y) 2) acordar http://xsb.sourceforge.net Y = a X = a X = _
Tabling (cont.) • Se a solução já está na tabela, e o predicado é chamado novamente, então: • Não é necessário calcular a solução novamente • Vai-se simplesmente buscar à tabela! • Isto aumenta a eficiência. Algumas vezes em ordens de magnitude.
fib(4,H) fib(5,Y) fib(4,A) fib(3,F) Tabela de fib fib(3,B) fib(2,E) Q F fib(2,C) fib(1,D) C=1 D=1 Exemplo de Fibonacci fib(6,X) fib(1,1). fib(2,1). fib(X,F) :- fib(X-1,F1), fib(X-2,F2), F is F1 + F2. X=11 Y=7 H=4 A=4 F=3 B=3 2 1 E=1 1 1 3 3 4 4 Linear em vez de exponencial 5 7 6 11
XSB-Prolog • Usado para perguntas na WFS • Prolog + tabling • Para usar tabling, eg, no predicado p com 3 argumentos: :- table p/3. • Para usar tabling em todos os predicados necessários: :- auto_table.
XSB Prolog (cont.) • As tabelas são usadas de chamada para chamada até que: abolish_all_table,abolish_table_pred(P/A) • Negação WF negation é usada via tnot(Pred) • (Negação explícita via –Pred) • A resposta a Q é yes se Q é true ou undefined no WFM • É no se Q é false no WFM do programa
Distinguir T de U • Depois de todas as respostas, as tabelas guardam literais suspensos por recursão via negação →Residual Program • Se o residual é vazio, então True • Se não é vazio, então Undefined • O residual pode ser examinado através de: • get_residual(Pred,Residual)
Exemplo de Residual program :- table a/0. :- table b/0. :- table c/0. :- table d/0. a :- b, tnot(c). c :- tnot(a). b :- tnot(d). d :- d. | ?- a,b,c,d,fail. no | ?- get_residual(a,RA). RA = [tnot(c)] ; no | ?- get_residual(b,RB). RB = [] ; no | ?- get_residual(c,RC). RC = [tnot(a)] ; no | ?- get_residual(d,RD). no | ?-
Devido à circularidade a completação não concluí not reach(c) SLDNF (e Prolog) entram em loop XSB-Prolog trabalha bem Fecho transitivo :- auto_table. edge(a,b). edge(c,d). edge(d,c). reach(a). reach(A) :- edge(A,B),reach(B). |?- reach(X). X = a; no. |?- reach(c). no. |?-tnot(reach(c)). yes.
:- auto_table. edge(a,b). edge(c,d). edge(d,c). reach(a). reach(A) :- reach(B), edge(A,B). Em vez disto, poderiamos ter escrito Fecho transitivo (cont) :- auto_table. edge(a,b). edge(c,d). edge(d,c). reach(a). reach(A) :- edge(A,B),reach(B). Semântica declarativa mais próximo da operacional Recursão à esquerda tratada correctamente A versão da direita até é mais eficiênte
SLX e XSB • Existe uma implementação do SLX usando tabulação • Essa implementação está baseada no XSB-Prolog • Vem de base com o XSB-Prolog desde a versão 2.0, cf: http://xsb.sourceforge.net