Si st ema par a Pr ocessament o de Conheci ment o
Rober t oLi nsdeCar val ho Sér gi oGena r o e Gr upoWi t t y
24 abr 2007
–i i–
–i i i–
Res umo O Wi t t y é um ambiente de desenvolvimento de sistemas baseados em conhecimento, que permite a confecção de aplicações de amplo espectro, particularmente sistemas voltados ao aprendizado, organização de informações e aquisição de conhecimento. Para isso, dispõe de uma máquina de inferência que permite efetuar deduções sobre uma ou mais bases de conhecimento, de um conjunto de centenas de primitivas em uma linguagem ao estilo do Prolog, de um método de casamento de padrões e de recursos de comunicação com outros processos ou com a Internet. Estes recursos possibilitam a rápida criação de protótipos. Em sua versão servidor, o Witty pode ser encapsulado em outra aplicação, mantendo todo seu potencial mas com uma interface mais adaptada à solução de um problema específico que a de uso geral.
Abs t r ac t The Wi t t yis a devellopment environment for knowledge based systems, that allow the application confecction for wide aspect, particularly systems for learning, information organization and knowledge acquisition. For this, have a inference engine that may effectuate dedutions about one or many knowledges bases, a set of handred primitives in a language Prolog like, a pattern matching method and communications resources with other process or Internet. This resources enable a prototype criations quickly. In servidor version, the Witty may be encapsuled in another application, sustainned all the power but with a interface more adjust for the specific problem instead the general user.
–i v–
–v–
Í ndi c e 1. Prova automática de teoremas ......................................................................................................... 1.1 - Introdução 1.2 - Fundamentos 1.3 - Universo de Herbrand 1.4 - O Princípio da Resolução 2. Witty ..................................................................................................................................................... 2.1 - Instalação do programa 2.2 - Arquitetura 2.3 - Tela inicial 2.4 - Intrerface 3. Bases de conhecimento ...................................................................................................................... 3.1 - Conceituações 3.2 - Bases de Conhecimentos no Witty 3.3 - Consultando o Witty 3.4 - Efetuando deduções 4. Programando no Witty ...................................................................................................................... 4.1 - Programas simples 4.2 - Programas mais complexos 4.3 - Programas no Ambiente instalado 4.4 - Primitivas 4.5 – Controle de Programa 4.5.1 – Repetições: comando loop 4.5.2 – Sempre funciona: comando hold 4.5.3 – Backtraking: comando cut 4.5.4 – Sempre falha: comando fail 4.5.5 – Combinação cut & fail 4.5.6 – Nível de profundidade 4.6 – Seqüência de programa 5. Caixas de diálogos ............................................................................................................................. 5.1 – Consultando o usuário: comando ask 5.2 – Conversando com usuário: comando prompt 5.3 – Formulários: comando input 5.4 – Aquisição de conhecimento: primitiva acqbox 5.5 – Menus: o comando choose 6. Oráculos ............................................................................................................................................... 6.1 – Definições e Conceitos 6.2 - Uso de Oráculos no Witty 7. Gramáticas ........................................................................................................................................... 7.1 – Declaração de Registros 7.2 – Uso de expressões regulares no método 7.3 – Uso de arquivos no método 7.4 – Sistemas de Prost 7.5 – Gramáticas 8. Comunicação ....................................................................................................................................... 8.1 – TCP/IP 8.1.1 – Função servidor 8.1.2 – Área de transferência 8.2 - Ligação cliente servidor Witty 8.3 - Servidor padrão Bibliografia ...............................................................................................................................................
1 1 2 7 13 17 17 18 20 22 25 25 27 29 30 33 33 36 40 42 43 43 44 44 44 45 46 47 51 51 51 52 54 57 61 61 63 69 69 70 71 72 73 79 79 79 80 80 90 95
–vi–
1. Pr ovaAut omát i c adeTeor emas
1. 1–I nt r oduç ão Desde o surgimento do primeiro computador eletrônico, sua tecnologia tem-se desenvolvido em velocidade fantástica e atualmente existem aplicações não somente para resolver problemas computacionais difíceis e trabalhosos, como transformadas de Fourier, inversão de matrizes de alta ordem, saldos bancários instantâneos, processamentos do imposto de renda e controle de naves espaciais, por exemplo, mas também para efetuar tarefas ditas inteligentes caso feitas por seres humanos. Algumas destas tarefas são: escrever programas, responder questões e demonstrar teoremas. Elas fazem parte da área de Inteligência Artificial. A base prova automática de teoremas foi estabelecida por Herbrand por volta de 1930, mas seu método permaneceu impraticável até o aparecimento dos computadores digitais, ganhando mais destaque com o principio de resolução de J. A. Robinson, em 1965. Desde então muitos refinamentos foram acrescentados, como a introdução do caminho retrospectivo, partindo do problema proposto para subproblemas. Seu nível de desempenho era superior, comparado com humanos, desenvolvendo a mesma tarefa, porém restrito a uma modesta porção do domínio do cálculo proposicional. O uso dos resultados de Herbrand permitiu translação de tarefas da lógica de primeira ordem para lógica proposicional, onde quantificadores eram explicitamente manuseados somente no inicio das tarefas. Mas o impulso mais significativo foi a publicação do Pr i nc í pi odaRe s o l uç ã ode Robinson (Robinson, 1965), que empregava uma única regra de inferência e não necessitava de axiomas lógicos – exceto aqueles associados com o problema em questão. Acoplado a este principio, Robinson propôs um mecanismo de substituição que permite a verificação da validade de uma fórmula. Embora elegante, o procedimento de resolução básico produz grande quantidade de cláusulas intermediárias (na verdade “subproblemas”), não conseguindo fugir à explosão combinatorial. Por isso, várias estratégias de refinamento, visando a limitar o número de cláusulas a ser verificado, foram propostas pelo próprio Robinson ou pesquisadores posteriores. Uma das características mais importantes das variantes de resolução existentes reside na flexibilidade de formatos de representação oferecidos. Mesmo que se selecione maneira para representar conhecimento diferente daquela tratada neste texto, muitos dos conceitos considerados – unificação, preferência às cláusulas unitárias, interpretação, linearidade – continuarão sendo utilizados. Paralelamente ao progresso destas técnicas, alcançou sucesso sua aplicação a vários problemas de Inteligência Artificial. Elas foram inicialmente aplicadas à extração de respostas e posteriormente a programas para solução de problemas, programação automática, análise de programas e muitos outros. Há muitos pontos de vista para se estudar lógica simbólica. Tradicionalmente tem sido aplicada em operações filosóficas ou matemáticas, contudo, pode-se constituir no fundamento para construção de solução de problemas difíceis. Para tal, deve-se usar lógica simbólica para representar problemas e obter suas soluções. Para demonstrar como lógica simbólica pode ser utilizada para resolver problemas, considere os seguintes exemplos, propositalmente simples para que se possa conferir a conclusão usando apenas a observação. n Exe mpl o1. 1–Ló gi c aPr o p o s i c i o na l . Assumindo a veracidade dos seguintes fatos: 1. Se for 6 horas em Tóquio será 18 horas em São Paulo. 2. Se for 18 horas em São Paulo, então estará iniciando a novela das seis. 3. Agora é 6 horas em Tóquio. A questão é: Ago r ae s t ái ni c i a ndoano ve l ada ss e i s ? Os fatos 1 a 3 acima estão expressos em linguagem corrente e utilizaremos símbolos para representálos. Desta forma, sejam P, Q e R respectivamente “6 horas em Tóquio”, “18 horas em São Paulo” e “Iniciando a novela das seis”. Introduzindo o símbolo lógico ‘→ ‘ (implica), chegaremos a 1. P → Q 2. Q → R 3. P
que é a tradução daquelas sentenças para fórmulas lógicas. Como conseqüência da validade das fórmulas de 1 a 3, pode-se deduzir que a fórmula 4. R
–2– é igualmente válida, ou seja, é conseqüência lógica das precedentes. Quer dizer, estará iniciando a novela das seis. n n Exe mpl o1. 2–Ló gi c apr e di c a t i va . Vamos agora considerar outro exemplo, expresso pelos seguintes fatos: 1. Descartes pensa. 2. Todos que pensam existem.
Para representar estes fatos precisamos de um novo conceito chamado predicado. Teremos pensa(x) representando “x pensa” e existe(x) para “x existe”. Também necessitaremos do símbolo ‘∀ ‘ para significar “para todo x”. Assim, os fatos referidos poderão ser escritos como: 1. pensa(Descartes) 2. ∀ x pensa(x) → existe(x)
a partir de onde pode-se deduzir logicamente que 3. existe(Descartes)
significando que Descartes existe. n Nos dois exemplos precedentes, evidenciamos que uma fórmula (teorema) é conseqüência lógica de outras fórmulas. A demonstração que um teorema é verdadeiro chama-se prova. A demonstração automática de teoremas constrói métodos mecânicos para encontrar provas de teoremas. Este procedimento é importante porque muitos problemas – como aqueles resolvidos através de sistemas baseados em conhecimento – podem ser transformados em problema de prova de teoremas, como por exemplo: 1. Sistemas de respostas a questões, onde fatos podem ser representados por fórmulas lógicas e para responder às perguntas a partir dos fatos, demonstra-se que a fórmula correspondente à pergunta é derivada das fórmulas que representam os fatos. 2. Análise de programas, quando pode-se descrever a execução de programas por uma fórmula A e as condições nas quais ele terminará por outra fórmula B; assim, provar que o programa de fato terminará é equivalente a demonstrar que a fórmula B é conseqüência lógica da fórmula A. 3. Em problemas de isomorfismo de grafos deseja-se saber se um grafo à isomorfo de um subgrafo de outro grafo aplicável, por exemplo, ao estudo de estrutura de compostos orgânicos (que podem ser descritos através de grafos) e será resolvido pela demonstração de que a fórmula que representa um grafo é conseqüência lógica da fórmula que representa outro grafo. 4. Em problemas de transformações de estados há uma coleção de estados e outra de operadores de estado e quando um operador é aplicado a um estado, um novo será obtido. Assim, partindo-se do estado inicial, o problema consiste em se estabelecer a seqüência de operadores que possa transformá-lo em algum estado desejado. Também neste caso, pode-se descrever estados e regras de transição por fórmulas lógicas; logo, a transformação desejada se reduz a verificar que a fórmula final é conseqüência lógica das fórmulas que representam o estado inicial e as regras de transição.
1. 2–OsFundament os Desde há muito o poder dedutivo da lógica, segundo o qual a partir de alguns pressupostos pode-se inferir conclusões úteis, tem fascinado os homens e incentivado a busca de procedimentos que o reunisse com a capacidade de processamento dos computadores. Recentemente, através de judiciosa representação do conhecimento, muitos domínios de conhecimento puderam ser alcançados através dos chamados sistemas baseados em conhecimento, permitindo a simulação no computador das tarefas de peritos humanos. Assim, a perfeita compreensão dos métodos empregados nesta área começa necessariamente pela lógica. E dentre a extensa gama de alternativas existentes, aquela que parecia mais atraente era a lógica proposicional, cujos elementos são a proposição e conectivos que podem ligar várias proposições. Para analisar problemas e conceitos do conhecimento sistemático, a lógica precisa desenvolver um vocabulário preciso e adequado; isto é, através da linguagem quotidiana, vaga e ambígua, deve criar outra linguagem precisa. Então, o primeiro passo é assentar corretamente as leis de uso para certas palavras-chave como ‘não’, ‘e’, ‘ou’, ‘se... então’, ‘se e somente se’. Estas palavras são os conectivos, e as representaremos neste trabalho respectivamente pelos símbolos ¬ , ∧, ∨, → e ↔ . Em lógica proposicional estamos interessados em sentenças declarativas – as proposições – que podem ser ve r da de i r a sou f a l s a s . Exemplos de proposição são “É dia”, “Chove” e “O sol brilha”. Denotando-as respectivamente por P, Q e R, estaremos utilizando símbolos chamados fórmulas atômicas. Combinandoas com emprego dos c o ne c t i vo slógicos poderemos chegar a “Se for dia e não estiver chovendo então o sol brilha” ou, simbolicamente P ∧ ¬ Q → R
–3– obteremos uma fórmula bem formada (we l lf o r me df o r mul a , nese trabalho abreviada por f b f , ou simplesmente f ó r mul a ). A definição rigorosa de fbf é recursiva: 1. Uma fórmula atômica é uma fórmula. 2. Se F é uma fórmula, então ¬ F também o será. 3. Se F e G são fórmulas, então F ∧ G, F ∨ G, F → G e F ↔ G são fórmulas. 4. Todas as fórmulas serão geradas pela aplicação das regras 1 a 3 acima. O que é muito importante nestes conectivos lógicos – fugindo um pouco do senso comum na linguagem usual que permite certas ambigüidades, geralmente resolvidas pelo contexto, é a rigorosa dependência do valor (verdadeiro ou falso) de uma fórmula dos valores das fórmulas atômicas componentes, logo, totalmente isentas do contexto. As leis que regem o emprego dos conectivos podem ser sumarizadas em forma tabular, onde estarão expressas todas as alternativas de combinações possíveis para os valores verdadeiro ou falso das fórmulas atômicas originais, assim como os valores resultantes da fórmula final, constituindo o que é denominado de tabelas-verdade, vistas na Tabela 1.1. A utilização destas tabelas-verdade pode ser demonstrada pelo seguinte exemplo: seja A uma fórmula atômica verdadeira e B outra falsa, então o que poderemos afirmar a respeito de uma fórmula composta como ((A ∨ B) ∧ ¬ A) →
(B →
¬ A)?
Vejamos: desde que A seja verdadeira, pela tabela concluímos que a disjunção A ∨ Bé verdadeira; a negação ¬ A é falsa, resultando ser a conjunção ( A ∨ B)∨ ¬ A falsa. Da tabela de implicação, como o antecedente é falso, concluímos que aquela proposição é verdadeira. O assinalamento dos valores verdadeiro ou falso às proposições A e B, respectivamente, é chamado uma interpretação da fórmula. Uma vez que para cada proposição há dois valores possíveis, existem neste caso quatro interpretações para a fórmula apresentada. Assim, dada uma fórmula proposicional P e sendo P1, P2, ... Pn as fórmulas atômicas ocorrendo em P, então uma interpretação de P é um assinalamento de valores a P1, P2, ..., Pn, no qual cada Pi assume um dos valores (verdadeiro ou falso), mas não ambos. Uma fórmula P é dita verdadeira numa interpretação se e somente se seu valor for verdadeiro naquela interpretação; caso contrário, ela é dita falsa naquela interpretação. Uma fórmula é válida se e somente se for verdadeira para todas as interpretações possíveis; será inválida caso existir alguma interpretação em que ela for falsa. Será inconsistente (ou insatisfatível) se e somente se for falsa para todas as suas interpretações e consistente se existir alguma interpretação onde ela for verdadeira. Negação
Conjunção
Disjunção
Implicação
Equivalência
P
¬P
P
Q
P ∧ Q
P
Q
P ∨ Q
P
Q
P→ Q
P
Q
P↔ Q
V
F
V
V
V
V
V
V
V
V
V
V
V
V
F
V
V
F
F
V
F
V
V
F
F
V
F
F
F
V
F
F
V
V
F
V
V
F
V
F
F
F
F
F
F
F
F
F
V
F
F
V
Ta b e l a1. 1–Ta b e l a s ve r da de s . Outro conceito importante é o de t a ut o l o gi a , ou seja, uma proposição que é sempre verdade, independente dos valores de seus componentes. Por exemplo, para qualquer proposição P, P ∨ ¬ P
é sempre verdade, logo, uma tautologia. Para verificar se uma dada fórmula é ou não tautologia torna-se muito conveniente e compacto o uso de tabelas-verdade: P V F
¬ P F V
P
∨ ¬ V V
P
onde a segunda coluna é obtida da primeira pela tabela de negação e a terceira das duas primeiras usando-se a conjunção. Como ambas as linhas da terceira coluna são ‘V’, a proposição à qual se refere é uma tautologia. No entanto, este procedimento pode-se tornar trabalhoso. O número de linhas (combinações) possíveis depende da quantidade de componentes; para três haverá oito combinações distintas de possíveis valores, desde que cada proposição individual assuma dois valores diferentes: verdadeiro ou falso. Em geral, se houver ncomponentes, haverá 2ncombinações permitidas.
–4– A grande vantagem da lógica proposicional reside no fato de possuir o que se chama “procedimento de decisão”, isto é, através do uso das tabelas-verdade – facilmente computáveis – sempre será possível estabelecer a verdade ou falsidade de uma fórmula proposicional, conhecendo-se os valores das fórmulas atômicas. lnfelizmente, seu poder de representação é limitado, ainda não sendo suficiente para expressar muitas coisas óbvias e elementares, pois não foram simbolizados substantivos, pronomes, verbos, adjetivos ou advérbios, uma vez que só se utilizou sentenças completas – ou “proposições”. O que se pretende agora é introduzir noções lógicas para expressar qualquer conjunto de fatos, através de três tipos de expressões – t e r mo s , pr e di c a do se q ua nt i f i c a do r e s– que correspondem a muitos tipos distintos na gramática da linguagem corrente. Supondo que se queira representar o fato que “x é maior que 5”, define-se inicialmente o predicado é_maior_que(x,y) significando que “x é maior que y” (note que um predicado é uma relação). Com esta notação, a representação da sentença anterior será é_maior_que(x,5). De maneira similar, pode-se representar “x ama y” pelo predicado ama(x,y) e, também, poderemos expressar que “Pedro ama Maria” através da proposição ama(Pedro,Maria). Pode-se empregar também símbolos funcionais na lógica de primeira ordem. Por exemplo, podemos usar succ(x) para denotar “x + 1” (sucessor) e pai_de(x) significando “pai de x”. As sentenças “o sucessor de um número é maior que ele” podem ser representadas por é_maior_que(succ(x),x) e “o pai de Luís o ama” por ama(pai_de(Luís),Luís). Acima, é_maior_que(x,5), ama(Pedro,Maria), é_maior_que(succ(x),x) e ama(pai_de(Luís),Luís) são fórmulas atômicas da lógica de primeira ordem, onde é_maior_que e ama são símbolos predicativos, x é variável, 5, Luís, Pedro e Maria são constantes e succ e pai são símbolos funcionais. O número de argumentos existentes num símbolo predicativo ou funcional identifica sua a r i da de ; assim é_maior_que e ama têm a r i da de2, succ e pai têm a r i da de1. De maneira geral, se possuir n argumentos, dizemos que apresenta a r i da denou é ná r e o . Uma função leva uma lista de constantes a uma constante. Assim, pai é uma função que relaciona uma pessoa chamada Luís com seu pai; pai(Luís) represente uma pessoa ainda que seu nome não seja conhecido. Chamamos pai(Luís) de um termo da lógica de primeira ordem. O termo mais importante em lógica denomina-se variável e será representado por letras minúsculas latinas do final do alfabeto, como ‘x’ ‘y’ e ‘z’ por exemplo. Outros termos são constantes e funções que são formadas pela aplicação de um símbolo funcional a outro termo. A função gramatical de variável é similar à de pronomes ou substantivos comuns na linguagem quotidiana. Assim, a sentença é equivalente a
Todas as coisas são quentes ou não quentes. Para todo x, x é quente ou x não é quente.
Os predicados serão denotados por letras maiúsculas. Assim, se ‘Q’ significar ‘é quente’, a frase acima pode ser reescrita como Para todo x, Q(x) ∨ ¬ Q(x),
e esta “frase lógica” Q(x) ∨ ¬ Q(x) é chamada f ó r mul a . Mais formalmente, t e r mopossui a seguinte definição recursiva 1. Uma constante é um termo. 2. Uma variável é um termo. 3. Se ffor um símbolo funcional n-áreo e t 1, . . . ,t ntemos, então f ( t 1, . . . ,t n)será um termo. 4. Todos os termos são gerados pela aplicação das regras acima. Se Pfor um símbolo funcional n-áreo e t 1, . . . , t nforem termos, então P( t 1, . . . ,t n)será uma fórmula atômica. Considerando esta outra sentença Todo quadrado é paralelogramo
que pode ser traduzida por
Para todo x, se x for um quadrado, então x será um paralelogramo
ou simbolizando o predicado ‘é um quadrado’ por ‘é_quadrado(x)’ e ‘é um paralelogramo por ‘é_paralelogramo(x)’, chega-se a Para todo x, é_quadrado(x) → é_paralelogramo(x).
Teria o mesmo significado afirmar que ou seja
Existem paralelogramos que são quadrados Existe x tal que é_paralelogramo(x) → é_quadrado(x).
Claramente, esta última sentença não poderia ser considerada verdadeira ou falsa, sem a informação inicial ‘existe x’. Também a frase ‘para todo x’ nos exemplos anteriores é de importância crucial para a lógica. Estas frases identificam os q ua nt i f i c a do r e s .
–5– Assim, a frase ‘para todo’ representa o q ua nt i f i c a do runi ve r s a le será representado por ∀ e ‘existe’ o q ua nt i f i c a do re xi s t e nc i a l , denotado por ∃. Com uso destes quantificadores, pode-se representar de forma mais compacta os exemplos anteriores: ∀ x é_quente(x) ∧ ¬ é_quente(x) ∀ x é_quadrado(x) → é_parelelogramo(x ) ∃x é_paralelogramo(x) → é_quadrado(x)
Desta forma, as ocorrências de variáveis numa fórmula podem ou não ser controladas por quantificadores. Para definir mais claramente este conceito, é necessário introduzir a idéia de escopo, que é a menor fórmula que segue imediatamente o quantificador. Nos dois primeiros exemplos, o escopo é o mesmo e no terceiro há dois escopos diferentes, separados pelo símbolo ‘∧‘ 1. ∃x M(x) ∨ R(x) 2. ∃x (M(x) ∨ R(x)) 3. ∃x∀ x (xy = 0) ∧ ∀ x∀ z (x + z = z + x)
Isto permite definir a ocorrência de uma variável como l i mi t a daquando e somente quando esta ocorrer dentro do escopo de um quantificador referente àquela variável, sendo a ocorrência livre em caso contrário. Desta forma, uma va r i á ve lél i vr ese e somente se apresentar ao menos uma ocorrência livre. Chama-se s e nt e nç aa uma fórmula que não possua variáveis livres. Em lógica de primeira ordem, variáveis poderão ocorrer somente como termos variáveis, nunca como predicados ou sentenças. Enquanto que a sentença ∀ xP(x)∨Q(x) é uma construção legal em lógica de primeira ordem, ∀ P P(x) e ∃s s, não o são. Tais construções pertencem a lógicas de ordem superior. As vantagens de se utilizar predicados ficam evidentes se compararmos as afirmações “as uvas estavam verdes” e “as uvas estavam maduras” que correspondem a duas proposições completamente desvinculadas entre si. No entanto, se adotarmos outra representação, digamos estavam_as(uvas,verdes) e estavam_as(uvas,maduras);
percebemos mais claramente o relacionamento existente. Assim, a capacidade de representar fatos da lógica de primeira ordem é superior à de proposições. Infelizmente, já foi demonstrado pelo matemático americano Alonzo Church que não existe um procedimento de decisão para fórmulas arbitrárias de primeira ordem. Como toda a matemática pode ser formalizada através de lógica de primeira ordem, a existência de tal procedimento permitiria a construção de máquinas para resolver qualquer problema matemático. O teorema de Church não só destruiu esta pretensão como também provou que tal procedimento não existe e nunca existirá. Desta forma, foi necessário desenvolver uma teoria de inferência lógica que possa validar fórmulas de primeira ordem. Esta teoria se baseia nas regras que governam o uso dos conectivos e seu objetivo é partir de um conjunto de fórmulas dadas (premissas) derivar uma outra (conclusão) que seja conseqüência lógica das premissas. O mais importante nesta teoria é que a partir de um conjunto dado de premissas as regras de derivação lógica devem inferir todas as conclusões que sejam conseqüências lógicas das premissas e somente estas. n Exe mpl o1. 3–Re gr a sdei nf e r ê nc i a . Vamos demonstrar o emprego destas leis de derivação, também chamadas regras de inferência, por simplicidade com proposições, o que permite por outro lado comparar os resultados obtidos por este método com as tabelas-verdade. Chamamos uma proposição S de uma derivação das proposições precedentes, se a conjunção destas tautologicamente implica S. Pode-se empregar as tabelas-verdade para o estabelecimento das regras de inferência, como está mostrado no exemplo a seguir: Premissa 1: Premissa 2: Conclusão
A ∨ B ¬ A B
Para decidir se o argumento é válido, deve-se verificar se a conjunção (A∨B)∧¬ A tautologicamente implica B. Para esta tarefa monta-se a seguinte tabela: A V V F F
B V F V F
A ∨ B V V V F
¬ A F F V V
(A∨B) ∧ ¬ A F F V F
Observa-se que no único caso em que a premissa (última coluna) é verdadeira, a conclusão (segunda coluna) é também verdadeira – o que ocorre na terceira linha. Logo, o argumento é válido, ou seja, a conclusão é conseqüência lógica das premissas. n
–6– <01> Modus ponendo ponens
P e (P → Q) → Q
<02> Modus tollendo tollens
¬ Q e (P → Q) → ¬ P
<03> Modus tollendo pones
¬ P e (P ∨ Q) → Q
<04> Lei da Simplificação
P e Q → Q
<05> Lei da Adjunção
P e Q → P ∧ Q
<06> Lei do Silogismo Hipotético
(P → Q) e (Q → R) → (P → R)
<07> Lei da Exportação
(P ∧ Q → R) → (P → (Q → R))
<08> Lei da Importação
(P → (Q → R)) → (P ∧ Q → R)
<09> Lei
(P → Q
do Absurdo
e ¬ Q) → ¬ P
<10> Lei da Adição
P → P ∨ Q
<11> Lei da Dupla Negação
P ↔
<12> Lei da Contraposição
(P → Q) ↔
<13> Leis de Morgan
¬ (P ∧ Q) ↔
P ∨ Q
<14>
¬ (P ∨ Q) ↔
¬P ∧ ¬ Q
<15> Leis Comutativas
P e Q
↔
Q ∨ P
<16>
P ∨ Q
↔
Q ∨ P
<17> Lei da Equivalência para Implicação e disjunção <18> Lei da Negação para Implicação
P → Q ↔
<19> Leis das Bicondicionais
(P ↔
Q) ↔
(P → Q) ∧ (Q → P)
<20>
(P ↔
Q) ↔
(P ∧ Q) ∧ (¬ P ∧ ¬ Q)
<21> Lei do Meio Excluído
P ∨ ¬P
<22> Lei da Continuação
¬ (P ∧ ¬ P)
¬¬P (¬ Q → ¬ P)
¬P ∨ Q
¬ (P → Q) ↔
P ∧ ¬Q
Ta b e l a1. 2–Ta ut o l o gi a sút e i s . Para auxiliar no processo de dedução, estão listadas na Tabela 1.2 as mais importantes tautologias. Nas referências a ela no texto do restante do capitulo, usaremos a numeração à esquerda entre parêntesis angulares para indicar quais foram empregadas.
n Exe mpl o1. 4–Pr o vadi r e t a .
Como exemplo de derivação, consideremos o seguinte conjunto de premissas [1] [2] [3] [4]
A → B ∨ C B → ¬A D → ¬C A
de onde pretende-se deduzir a seguinte conclusão A → ¬D
pelos seguintes passos, garantidos por regras de inferências [5] [6] [7] [8] [9]
B ∨ C ¬B C ¬D A → ¬D
onde [5] se obtém de [1] e [4] por mo duspo ne ndopo ne s ; [6] de [2] e [4] pela Lei da Dupla Negação e mo dus t o l l e ndot o l l e ns , conforme o exemplo 1.3; [7] de [5] e [6] por mo dust o l l e ndopo ne s ; [8] de [3] e [7] usando as mesmas regras utilizadas em [6]; e, finalmente, a conclusão [9] é resultado de [4] e [8]. n Usualmente as f b fválidas de um sistema lógico são denominadas t e o r e ma s . O procedimento descrito atrás, que permite o estabelecimento de teoremas, é chamado pr o c e di me nt odepr o va . Um procedimento é c o mpl e t oquando toda fórmula válida pode ser demonstrada ser um teorema e c o r r e t ose todo teorema produzido pelo procedimento de prova for realmente válido. No caso desejável de ser ambos, diz-se que é um procedimento de decisão. É fato conhecido que existe procedimento de prova para lógica de primeira ordem, porém não de decisão. Isto significa que não há garantias de que um procedimento de prova convergirá para a prova em um número finito de passos quando se tenta demonstrar um não teorema. Todavia, em termos práticos esta carência não restringe a aplicabilidade da lógica. Devido às limitações de tempo e espaço de memória existentes nos computadores reais, o poder heurístico do procedimento de prova (ou seja, sua habilidade de provar eficientemente teoremas úteis) é mais importante que sua limitação teórica. Assim, um procedimento de decisão que requeira enorme quantidade de tempo ou memória é indistingüível, na prática, de um procedimento de prova que nunca termine para algumas f b f .
–7– Um l i t e r a lé uma fórmula atômica ou sua negação. Uma fórmula F está na f o r mano r ma lc o nj unt i vase for composta de uma conjunção de outras fórmulas F1 ∧ F2 ∧ ... ∧ Fn
onde cada um dos F1, F2, ..., Fn é uma disjunção de literais. Assim, a fórmula F = (P ∨ ¬ Q ∨ R) (¬ R ∨ Q)
está na forma normal conjuntiva, pois teremos F1 = P ∨ ¬ Q ∨ R
e
F2 = ¬ R ∨ Q.
De maneira análoga, uma fórmula está na forma normal disjuntiva se e somente se estiver na forma F1 ∨ F2 ∨ ... ∨ Fn
onde cada um dos F1, F2, ..., Fn for uma conjunção de literais. Uma fórmula F na lógica de primeira ordem é dita estar na f o r mano r ma lpr e ne xcaso todos os quantificadores existentes prefixem a fórmula, isto é, se e somente se estiver na forma Q1x1 ... Qnxn (M)
onde Q1x1 será ou ∀ x1 ou ∃x1 e (M) uma fórmula que não contenha quantificadores. A razão de se considerar esta forma normal é para simplificar os procedimentos de prova que serão discutidos nas próximas seções. Assam, será útil estabelecer um método para transformar uma fórmula dada qualquer para esta forma. lnicialmente, para se poder colocar todos os quantificadores prefixando a fórmula, deveremos eliminar os sinais de implicação, o que será possível através do uso das seguintes leis (identificadas por colchetes, para não confundir com aquelas listadas na Tabela 3,1): [01] [02]
P ↔ Q P → Q
[03] [04] [05] [06] [07]
¬ (¬ P) = P ¬ (P ∨ Q) = ¬ (P ∧ Q) = ¬ (∀ x P(x)) ¬ (∃x P(x))
[08] [09] [10] [11]
Q(x) P(x) ∧ Q = Qx P(x) ε Q ∀ x P(x) ∧ ∀ x Q(x) = ∀ x (P(x) ∧ Q(x)) ∃x P(x) ∨ ∃x Q(x) = ∃x (P(x) ∨ Q(x)) Q1x P(x) ∧ Q2x Q(x) = Q1xQ2z (P(x) ε Q(z))
= =
P → Q ∧ Q → P ¬P ∨ Q
Em seguida, devem ser resolvidas as negações, que podem envolver as leis: ¬P ∧ ¬P ∨ = ∃x = ∀x
¬Q ¬Q ¬ P(x) ¬ P(x)
Algumas variáveis poderão ter suas denominações renomeadas, se necessário. Finalmente, os quantificadores poderão ser simplesmente deslocados, baseados nas leis:
onde Q e Qi representam os quantificadores (∀ ou ∃) e ε os conectivos (∧ ou ∨).
n Exe mpl o1. 5–Fo r maNo r ma lPr e ne x.
Para se obter a forma normal prenex, para a fórmula
∀ x∀ y (∃z (P(x,y) ∧ P(y,z)) → ∃u Q(x,y,u))
efetuaremos os seguintes passos:
1. ∀ x∀ y (¬ (∃z (P(x,z) ∧ P(y,z))) ∨ ∃u Q(x,y,u)) 2. ∀ x∀ y∀ z ((¬ P(x,z) ∨ ¬ P(y,z)) ∨ ∃u Q(x,y,u)) 1. ∀ x∀ y∀ z∃u (¬ P(x,y) ∨ ¬ P(y,z) ∨ Q(x,y,u))
conseguindo-se no último passo a forma normal pr e ne xda fórmula dada. n
[02] [06],[05] [08]
1. 3–O Uni ver s odeHer br and A mais importante contribuição para a prova automática de teoremas foi fornecida por Herbrand em 1930 (Herbrand, 1930), Como vimos, uma fórmula válida é aquela que é verdadeira em qualquer interpretação. Herbrand desenvolveu um algoritmo para encontrar uma interpretação que pode tornar falsa uma fórmula dada. Todavia, se a fórmula dada permanecer válida, tal interpretação não existe e seu algoritmo parará depois de um número finito de tentativas. O método de Herbrand se constitui na base dos procedimentos de prova automática de teoremas. Os procedimentos de Herbrand e de resolução, que será visto na próxima seção, não seguem a tradição da prova direta, conforme utilizada no exemplo 1.4, mas sim busca a prova por refutação, demonstrando que a negação da fórmula é inconsistente. A idéia intuitiva por trás deste procedimento é de que se a negação de um teorema for falsa então ele será verdadeiro (principio do meio excluído).
n Exe mpl o1. 6–Pr o vapo rr e f ut a ç ã o .
Para ilustrar este esquema e fornecer um exemplo de prova indireta, vamos demonstrar novamente a validade da conclusão em lógica proposicional A→ ¬ D
–8– A partir das premissas [ 1] [ 2] [ 3] [4’]
A → B ∨ C B → ¬A D → ¬C A
A negação da conclusão é obtida a partir de <18> (novamente se utilizando das leis da Tabela 1.1) que fornece A ∧ D, dado que A ∧ D ↔
¬ (A → ¬ D)
e por já incluir a premissa [4’] (por <04>) pode substituí-la: [ 4] [ 5] [ 6] [ 7] [ 8] [ 9] [10] [11]
A ∧ B ∨ ¬C B ¬A A ∧ A ∧ A →
D C
¬A D → ¬D
A ∧ ¬A
negação da conclusão de [1] e [4] por <01> de [3] e [4] por <01> de [5] e [6] por <03> de [2] e [7] por <01> de [4] e [8] por <05> de [4] e [9] de [10] por <09> n
Este método aplicado à lógica de primeira ordem é muito conveniente e com seu emprego não haverá perda de generalidade. No entanto, exige a conversão das fórmulas originais em formas padrão livres de quantificadores. Esta forma foi introduzida por Davis e Putnam em 1960 e equivale a inicialmente se obter a f o r mano r ma lpr e ne x, já vista na seção anterior, na qual os quantificadores são prefixados à fórmula; o restante da fórmula (algumas vezes chamada de ma t r i z ) consiste de conjunção de disjunções de fórmulas atômicas. Os quantificadores deverão ser abandonados no final do processo de obter-se a forma padrão, no pressuposto de que todas as variáveis sejam quantificadas universalmente. Desta forma, os quantificadores existenciais deverão ser substituídos pelas funções de Sk o l e m, cujos argumentos são todas as variáveis universais em cujo escopo reside o quantificador existencial substituído. As funções de Sk o l e m são formadas utilizando-se símbolos funcionais ainda não empregados. Assim, a fórmula ∀ x∃y P(x,y) skolemizada resulta
∀ x P(x,f(x)),
onde f(x) tem por único propósito garantir que existe algum valor (y) que depende de x, pois está dentro de seu escopo. No entanto, se o quantificador existencial não residir no escopo de outro universal, como em ∃y∀ x P(x,y)
a variável quantificada existencialmente será substituída por uma constante ∀ x P(x,a)
que assegura sua existência assim como sua independência de qualquer outra variável. Neste estágio, os quantificadores universais poderão ser abandonados. Foi rigorosamente provado que esta forma final livre de quantificadores é equivalente à forma original. Esta forma final é denominada c l áus ul a. Assim, podemos definir cláusula como uma disjunção de literais.
n Exe mpl o1. 7–Ob t e nç ã odec l á us ul a .
Para passar para a forma de cláusulas a fórmula discutida no exemplo 1.5 ∀ x∀ y (∃z (P(x,z) ∧ P(y,z)) → ∃u Q((x,y,u)) deveremos inicialmente passá-la para a forma normal prenex ∀ x∀ y∀ z ∃u (¬ P(x,z) ∨ ¬ P(y,z) ∨ Q(x,y,u)) como já visto naquele exemplo. A seguir, a variável quantificada existencialmente deverá ser substituída pela função de Sk o l e m ∀ x∀ y∀ z (¬ P(x,z) ∨ ¬ P(y,z) ∨ Q(x,y,f(x,y,z))) e, finalmente, abandonamos os quantificadores prefixados, chegando á cláusula (¬ P(x,z) ∨ ¬ P(y,z) ∨ Q(x,y,f(x,y,z))) perfeitamente equivalente à fórmula original. n Por definição, um conjunto de cláusulas S é insatisfatível se for falsa para todas as interpretações em todos os domínios. Como a análise de todas as interpretações possíveis é inviável, seria muito conveniente fixar-se um domínio especial H no qual S fosse insatisfatível se e somente se for falsa em todas as interpretações. Tal domínio existe e chama-se Uni ve r s odeHe r b r a ndde S definido a seguir. Seja H0 o conjunto de constantes que aparecem em S. Se nenhuma constante aparecer em S, então H0 consistirá de uma única constante, digamos H0 = {a}. Para i = 0, 1, 2, ..., seja Hi+1a união de Hicom o conjunto de todos os termos da forma f n( t 1, . . . , t n)para todos os símbolos funcionais de aridade nf nque ocorrem em S onde ti,j = 1,...,n são membros do conjunto Hi . Então cada Hié chamado de conjunto de constantes ní ve lide S e H o Uni ve r s odeHe r b r a nd.
–9– O conjunto A = Al, A2, ..., An de todas as fórmulas atômicas de S é denominado base de Herbrand.
n Exe mpl o1. 8–Uni ve r s oeBa s edeHe r b r a nd. Considere as cláusulas 1. 2.
P(x,a) ¬ Q(x) ∨ P(f(x),b)
O conjunto de cláusulas será então
S = {P(x,a), ¬ Q(x) ∨ P(f(x),b)},
contendo duas constantes e um símbolo funcional. Assim H0 H1 H2 H3
= = = =
{a, {a, {a, {a,
b} b, f(a), f(b)} b, f(a), f(b), f(f(a)), f(f(b))}, b, f(a), f(b), f(f(a)), f(f(b)), f(f(f(a)))), f(f(f(b)))}
e o universo de Herbrand de S é
H = {a, b, f(a), f(b), f(f(a)), f(f(b)), f(f(f(a))), .... }
Temos dois símbolos predicativos P e Q, logo a base de Herbrand de S será
A = {P(a,b), Q(a), Q(b), P(a,f(a)), Q(f(a)), P(a,f(b)), .... } n
Obt enç ãodeCl á us ul as Seja, dada a fórmula: que em lógica predicativa, fica:
∀ x∀ y x < y → ∃z x + z = y ∀ x ∀ y menor_que(x,y) → ∀ z igual(soma(x,z),y)
Os passos para se chegar à cláusula equivalente são: [p → q = ¬ p ∨ q] ∀ x ∀ y ¬ menor_que(x,y) ∨ ∃z igual(soma(x,z),y) [2] Prefixar os quantificadores: ∀ x∀ y∃z ¬ menor_que(x,y) ∨ igual(soma(x,z),y) [3] Eliminar os existenciais: ∀ x∀ y ¬ menor_que(x,y) v igual(soma(x,f(x,y)),y) [4] Abandonar os quantificadores: ¬ menor_que(x,y) ∨ igual(soma(x,f(x,y)),y) [1] Eliminar implicações:
chegando-se à cláusula equivalente à fórmula dada.
Fi gur a1. 1–Pa s s o spa r ao b t e nç ã odeCl á us ul a s Chama-se á r vo r es e mâ nt i c aà árvore binária tal que os descendentes de cada nó são respectivamente elementos da base de Herbrand e sua negação (fórmulas atômicas c o mpl e me nt a r e s ). n Exe mpl o1. 9–Ár vo r eSe mâ nt i c a . A árvore semântica associada ao conjunto de cláusulas do exemplo 1.8 S = {P(x,a) ¬ Q(x) ∨ P(f(x),b)}
está na Fig. 1.2 da página seguinte.
Fi gur a1. 2–Ar vo r eSe mâ nt i c a .n n Exe mpl o1.l 0–Ár vo r eSe mâ nt i c af e c ha da . Considere agora a fórmula
∀ x∀ y ((P(x) → Q(x)) ∧ P(f(y) ∧ ¬ Q(f(y))
que dá origem às seguintes cláusulas C1. C2. C3.
¬ P(x) ∨ Q(x) P(f(y)) ¬ Q(f(y))
Sua árvore semântica fechada está exibida na Fig. 1.3
–10–
Fi gur a1. 3–Ár vo r es e mâ nt i c af e c ha da .n Os caminhos existentes numa árvore semântica oferecem interpretações para o conjunto de cláusulas que representa, que podem satisfazê-lo ou não. Assim, o caminho 0-1 está garantido pela substituição em C2 de F(y) por a (denotamos: a/f(y), conforme será visto na seção 1.4); 1-3, por a/x em C1 e 3-7 por a/y em C2. No entanto, 7-13 não satisfaz o conjunto de cláusulas porque entra em contradição com C3. Desta forma, o nó 13 é denominado de falha e a partir do qual o caminho não pode prosseguir. Deveremos então retornar ao nó 7 e pesquisar outro caminho. Mas, o arco 7-14, igualmente, torna as cláusulas originais insatisfatíveis porque o conjunto de arcos {P(a), Q(a), P(f(a)), ¬ Q(f(a))}
não as satisfaz (viola a C1 para a substituição f(a)/x). Assim, o 14 também é um nó de falha. Desta forma, o nó 7, cujos dois descendentes são nós de falha, denomina-se nódei nf e r ê nc i a . Pode-se observar na figura que de maneira análoga, além dos nós 13 e 14, os nós 4, 8, 10, 11, 12, 15 e 16 também são de falha. Quando isto ocorrer, todas as folhas – nós de último nível – são nós de falha, a árvore semântica é dita f e c ha da . Abandonando os nós de falha, podemos diminuir o nível de profundidade da árvore, “podando-a” e se conseguirmos reduzi-la à raiz, o conjunto de cláusulas não possui interpretação no Universo de Herbrand (como, no exemplo). O Te o r e madeHe r b r a ndse constitui no mais importante teorema da lógica simbólica e na base dos procedimentos de prova em demonstração automática de teoremas. Segundo ele, para testar se um conjunto S de cláusulas é insatisfatível, necessita-se apenas considerar interpretações no universo de Herbrand dado que se S for falso em todas interpretações deste universo, pode-se concluir então que é insatisfatível. Uma vez que usualmente existem muitas interpretações, possivelmente infinitas, deve-se organizá-las de forma sistemática. Isto pode ser feito utilizando-se árvores semânticas. Teor ema de Her br and: Se S for um conjunto de cláusulas tal que seja falsa para toda interpretação I de Herbrand, então S é insatisfatível para qualquer domínio. Corol ár i o: Se a árvore semântica associada a um conjunto de cláusulas S for fechada, então S será insatisfatível.
Como conseqüência do Teorema de Herbrand, o processo de redução do nível de profundidade da árvore semântica sugerido anteriormente, pode ser aplicado para verificar se um conjunto de cláusulas é ou não satisfatível. Isto será mostrado no exemplo a seguir, por simplicidade, para lógica proposicional. n Exe mpl o1. 1 1–Apl i c a ç ã od oTe o r e madeHe r b r a nd. Dado o conjunto de cláusulas [exemplo de (Carvalho, 1985)] 1. P ∨ Q ∨ R 2. ¬ P ∨ Q 3. ¬ Q ∨ R
4. S ∨ ¬ R 5. ¬ T ∨ ¬ S 6. T ∨ ¬ R
para o qual construímos a árvore semântica da Fig. 1.4, a qual iremos percorrer caminhando pela esquerda e em profundidade. Verificando a validade das fórmulas atômicas dos arcos 0-1, 1-3, 3-7 e 7-13, percebemos que todos satisfazem o conjunto original de cláusulas. No entanto, quando passamos por 13-19, o conjunto {P, Q, R, S, T}
não as satisfaz (devido à cláusula 5). Escolhendo o outro caminho (11.20), o conjunto obtido {P, Q, R, S, ¬ T}
também as torna insatisfatíveis, por contrariar a cláusula 1. Então poderemos eliminar as fórmulas atômicas conjugadas T e ¬ T da árvore, reduzindo seu nível. Agora a árvore semântica representará não somente as cláusulas originais como também aquela obtida de 5 e 6 pela eliminação de T e ¬ T
–11–
Fi gur a1. 4-Ár vo r es e mâ nt i c apa r ae xe mpl o1. 11 Observe que esta nova cláusula acrescentada não altera a insatisfabilidade do conjunto, dado que somente será insatisfatível caso as cláusulas 5 e 6 o forem. Chegamos então á seguinte situação: 1. 2. 3. 4.
P ∨ Q ∨ R ¬P ∨ Q ¬Q ∨ R S ∨ ¬R
5. ¬ T ∨ ¬ S 6. T ∨ ¬ R 7. ¬ S ∨ ¬ R
descrita pela árvore semântica a seguir:
Fi gur a1. 5–Re duç ã odeT e¬ T Para o novo conjunto de cláusulas, o caminho de 0 a 13, isto é, com interpretação {P, Q, R, S}
é insatisfatível (cláusula 7) e 0-1, 1-3, 3-7, 7-14 produz {P, Q, R, ¬ S}
que igualmente não satisfaz (cláusula 4). Procedendo de maneira análoga, obteremos de 4 e 7 a nova cláusula ¬ R levando à nova situação: 1. 2. 3. 4.
representada por:
P ∨ Q ∨ R ¬P ∨ Q ¬Q ∨ R S ∨ ¬R
5. 6. 7. 8.
¬T ∨ ¬S T ∨ ¬R ¬S ∨ ¬R ¬R
Fi gur a1. 6–Re duç ã odeSe¬ S Neste ponto, o caminho 0 a 7 produz {P, Q, R} que é não satisfatível, (devido à cláusula 8) e 0-1, 1-3, 3-8, de onde vem {P, Q, ¬ R}, contradiz a cláusula 1. Com o mesmo procedimento conseguiremos nova cláusula de 8 e 3 (¬ Q), chegando-se a outra situação: 1. 2. 3. 4. 5.
P ∨ Q ∨ R ¬P ∨ Q ¬Q ∨ R S ∨ ¬R ¬T ∨ ¬S
6. T ∨ ¬ R 7. ¬ S ∨ ¬ R 8. ¬ R 9. ¬ Q
–12– representada pela Fig. 1.7.
Fi gur a1. 7–Re duç ã opa r c i a ldeRe¬ R Observe que neste caso somente foram eliminadas as folhas que contenham R ou ¬ R deste ramo, uma vez que devido á cláusula 1 (que envolve P, Q e R) os ramos da direita não puderam ser suprimidos. Agora, o percurso 0-3 que resulta {P, Q} não satisfaz a cláusula 9, e 0-1, 1-4 de onde vem {P, ¬ Q} que torna a cláusula 2 insatisfatível, o que nos leva à nova cláusula ¬ P, e à nova situação 1. P ∨ Q ∨ R 6. T ∨ ¬ R 2. ¬ P ∨ Q 7. ¬ S ∨ ¬ R 3. ¬ Q ∨ R 8. ¬ R 4. S ∨ ¬ R 9. ¬ Q 5. ¬ T ∨ ¬ S 10. ¬ P representada pela árvore da Fig. 1.8:
Fi gur a1. 8–Re duç ã opa r c i a ldeQ e¬ Q Agora, os caminhos pela direita 0-2-6-12 e 0-2-6-11 nos levam às interpretações {¬ P, ¬ Q, ¬ R} e {¬ P, ¬ Q, R} que não satisfazem, respectivamente, às cláusulas 1 e 8, produzindo P ∨ Q e eliminação definitiva de R e ¬ R. Com isto chegamos a 1. 2. 3. 4. 5. 6.
representadas por
P ∨ Q ∨ R ¬P ∨ Q ¬Q ∨ R S ∨ ¬R ¬T ∨ ¬S T ∨ ¬R
7. 8. 9. 10. 11.
¬S ∨ ¬R ¬R ¬Q ¬P P ∨ Q
Fi gur a1. 9–Re duç ã ode f i ni t i vadeRe¬ R Os caminhos 0-2-6 e 0-2-5 nos trazem {¬ P, ¬ Q e ¬ P, Q} que não satisfazem, na ordem, às cláusulas 11 e 9, o que nos permite eliminar de vez Q e ¬ Q, produzindo a nova cláusula P chegando, finalmente a 1. 2. 3. 4. 5. 6.
P ∨ Q ∨ R ¬P ∨ Q ¬Q ∨ R S ∨ ¬R ¬T ∨ ¬S T ∨ ¬R
7. 8. 9. 10. 11. 12.
¬S ∨ ¬R ¬R ¬Q ¬P P ∨ Q P
e à árvore da Fig. 1.10. A situação agora resultante é trivial, uma vez que as interpretações existentes P ou ¬ P não satisfazem, respectivamente, às cláusulas 10 e 12, o que nos permite reduzir a árvore semântica até a raiz, demonstrando a insatisfabilidade do conjunto original de cláusulas.
–13–
Fi gur a1. 10–Re duç ã ode f i ni t i vadeQ e¬ Q.n
1. 4–O Pr i nc í pi odaRes ol uç ão O Te o r e madeHe r b r a ndpermite, como visto atrás com uso das árvores semânticas, decidir se um conjunto de cláusulas dadas é insatisfatível. Esta árvore pode crescer exponencialmente dependendo das cláusulas em questão, a quantidade de elementos envolvidos pode superar a capacidade de armazenamento dos maiores computadores existentes, o que a torna impraticável. Para evitar esta excessiva geração de elementos, Robinson estabeleceu em 1965 outro algoritmo que pode ser aplicado diretamente sobre qualquer conjunto S de cláusulas para verificar sua insatisfabilidade – o Pr i nc i pi odaRe s o l uç ã o . Sua idéia essencial é verificar se S possui a cláusula vazia ou se não, se esta pode ser derivada de S. Caso isto ocorra, S será insatisfatível. Como vimos no exemplo 1.11, pela utilização do Teorema de Herbrand, podemos reduzir o número de nós da árvore semântica até a raiz, o que explicita a contradição existente. Este é também o fundamento do principio da resolução. Assim, ele pode ser visto como uma regra de inferência que pode ser usada para gerar novas cláusulas de S. Acrescendo S destas cláusulas, alguns nós da árvore original tornamse nós de falha. Então, o número de nós pode ser reduzido e a cláusula vazia pode eventualmente ser derivada. Basicamente, este principio consiste numa extensão do mo dust o l l e ndopo ne ns(<03> na Tabela 1.1), anteriormente explorado por Davis e Putnam, segundo o qual, das cláusulas , pode-se derivar
Cl: P C2: ¬ P ∨ Q
C3: Q.
Estendendo esta idéia para qualquer par de cláusulas (não necessariamente unitárias), podemos enunciar o Pr i nc i pi odaRe s o l uç ã oda forma seguinte: Para qualquer duas cláusulas C1 e C2, se existir um literal L1 em C1 que for complementar de outro literal L2 de C2, então, remova L1 de C1 e L2 de C2 e construa a disjunção dos remanescentes nas cláusulas. A nova cláusula construída é o resolvente de C1 e C2. O procedimento de prova por resolução usa sentenças na forma de cláusulas. Inicialmente, os axiomas e a negação do teorema que se deseja demonstrar são convertidos em cláusulas. Então novas cláusulas – os resolventes – são deduzidas pela regra de inferência acima. O teorema principal do procedimento estabelece que se um resolvente não for satisfeito, então nenhum de seus antecedentes o será, incluindo a negação do teorema inicial. Seu objetivo é obter a cláusula vazia, uma contradição explícita. O exemplo 1.11 pode ser uma demonstração da aplicação da resolução à lógica proposicional; os passos ali obtidos seriam exatamente os mesmos se empregássemos este princípio. Para maior clareza, este principio será aplicado para um exemplo mais simples na Fig. 1.11 a seguir, que servirá como um resumo. Para lógica de primeira ordem, no entanto, nem sempre os literais complementares são evidentes, como por exemplo nas cláusulas C1: C2:
P(x) ∨ Q(x) ¬ P(f(x)) ∨ R(x)
C1: C2:
P(f(a)) ∨ Q(f(a)) ¬ P(f(a)) ∨ R(a)
C3:
Q(f(a)) ∨ R(a)
C3’:
Q(f(x)) ∨ R(x).
eles somente aparecem se substituirmos x por f(a) em C1 e x por a em C2, resultando o que permite chegar ao seguinte resolvente:
Se escolhermos substituir x por f(x) em C1, chegaremos a um novo resolvente C3 é uma instância de C3’; então esta é a cláusula mais geral, no sentido que todas as demais cláusulas que podem ser produzidas por este processo são instâncias dela.
–14– Princípio da Resolução
Única Regra de Inferência
A ∨ B ¬A ∨ C B∨ C
Procedimentos: § Anexar aos axiomas a negação do teorema. § Prova por refutação: busca cláusula vazia (contradição). § Retomando o exemplo 1.6 onde os axiomas e o teorema foram convertidos em cláusulas: ( 1) ( 2) ( 3) ( 4) ( 5) ( 6) ( 7) ( 8) ( 9) (10)
¬A ∨ B ∨ C ¬B ∨ ¬A ¬D ∨ ¬C A D ¬ C ¬A ∨ B B ¬A (contradição)
[axioma] [axioma] [axioma] [negação do teorema] [negação do teorema] [5 e 3; 1] [6 e 1; 3] [7 e 4; 1] [8 e 2; 1] [9 e 4; 1]
Fi g.1. 11–Re s o l uç ã oe ml ó gi c apr o po s i c i o na l Com isso chega-se ao processo de unificação. Sua idéia básica é muito simples. Para demonstrá-la considere-se os literais amigo_de(Luís,Pedro) amigo_de(Luís,pai_de(Luís))
Para unificar dois literais, deve-se primeiro verificar se o predicado é o mesmo. Se for, pode-se prosseguir. Assim, os literais amigo_de(Luís,Pedro) parente_de(Luís,Pedro)
não podem ser unificados. Se os predicados combinarem, deve-se testar os argumentos; se o primeiro combinar, continua-se com o segundo e assim por diante. Para testar cada um deles, basta chamar o procedimento de unificação recursivamente: funções, predicados ou constantes diferentes não podem combinar; somente se forem idênticas. Uma variável pode-se combinar com outra, uma constante, uma função ou expressão predicativa, com a restrição que estas duas últimas não devem conter quaisquer instâncias das variáveis sendo comparadas. O alvo deste procedimento é descobrir ao menos uma substituição que causa igualdade de dois literais. Em geral, se houver uma tal substituição, haverá muitas igualdades. Por exemplo, os literais amigo_de(*x,*y) amigo_de(Luís,*z)
podem ser unificados por uma das seguintes substituições (Luís/*x, (Luís/*x, (Luís/*x, (Luís/*x,
*z/*y) *y/*z) Pedro/*y, Pedro/*z) Antonio/*y, Antonio/*z)
onde os dois primeiros são equivalentes, exceto por variação léxica. Os dois últimos também produzem igualdade, mas esta substituição é mais restritiva que a absolutamente necessária. Uma vez que o resultado deste algoritmo será utilizado no processo de resolução, é preferível empregar o mais geral unificador possível. Um importante detalhe adicional neste algoritmo é que numa expressão envolvendo uma dada variável não poderá ser unificada com ela própria, como por exemplo em f(*x,*x) f(g(*x),g(*x))
para tentar a substituição de *x por g(*x), deve-se substituir o *x no restante da expressão, chegando-se a uma recursão infinita, desde que não é possível eliminar *x. Agora já se tem elementos para julgar se dois literais são contraditórios – se um deles pode ser unificado com a negativa do outro. Assim, é_homem(*x) e ¬ é_homem(Maria) são contraditórios, uma vez que é_homem(*x) e é_homem(Maria) podem ser unificados. O correspondente intuitivo deste fato é que não pode ser verdade para todo *x que é_homem(*x) se for conhecido para algum *x, digamos Maria, para o qual é_homem(*x) for falso. Logo, para se utilizar resolução para expressões em lógica de predicados, devese empregar o algoritmo da unificação para localizar pares de literais que podem ser cancelados. Será preciso também usar o produto deste algoritmo para gerar cláusulas resolventes. Por exemplo, suponha que se deseje resolver: [1] é_homem(Pedro) [2] ¬ é_homem(*x) ∨ é_mortal(*x)
O literal é_homem(Pedro) pode ser unificado com o literal é_homem(*x) com a substituição Pedro/*x, o que informa que para *x = Pedro, ¬ é_homem(Pedro) é falsa. Mas não se pode simplesmente
–15– cancelar os dois literais envolvendo homem, como feito em lógica proposicional e obter o resolvente é_mortal(*x). [2] diz que para um dado *x, vale ¬ é_homem (x) ou é_mortal(x). Então para isto ser verdade, deve-se concluir somente que é_mortal(Pedro) deve ser verdadeira. Não é preciso que é_mortal(*x) seja verdadeiro para todo *x, dado que para alguns valores de *x ¬ é_homem(x) poderá ser verdadeiro, tornando é_mortal(*x) irrelevante para a verdade da cláusula completa. Logo, o resolvente gerado por [1] e [2] deve ser é_mortal(Pedro) – que se consegue aplicando o resultado do processo de unificação ao resolvente. Este exemplo ilustra a importância de padronizar variáveis durante o processo de converter expressões em forma de cláusulas, o que simplifica sobremaneira o procedimento. Se ocorrerem duas instâncias de uma mesma variável, elas devem ser submetidas à mesma substituição. De maneira formal, uma substituição é um conjunto finito da forma Θ = {t1/v1, t2/v2, ..., tn/vn},
onde cada vi é uma variável e cada ti um termo, sendo que não mais de um elemento do conjunto pode conter uma mesma variável após a barra. O significado de Θ é que o termo t1 substituirá a variável v1, t2 a v2 e assim por diante. Duas cláusulas C1 e C2 são unificáveis se existir uma substituição Θ tal que C1Θ = C2Θ . Se C’ = CΘ para qualquer Θ , então C’ será uma instância de C. Uma substituição Θ chama-se uni f i c a do rma i sge r a l( umg) de duas cláusulas C1 e C2 se e somente se: 1) C1Θ = C2Θ ; e 2) para qualquer outro unificador Θ ‘, C1Θ ‘ = C2Θ ‘ será uma instância de C1Θ = C2Θ .
Robinson demonstrou que se duas cláusulas forem unificáveis, então existirá o umgpara elas. O núcleo do processo de resolução é o algoritmo de unificação que determina ou não se duas cláusulas podem ser unificáveis e, no caso afirmativo, estabelece seu umg. A Fig. 1.12 resume a idéia de unificação ao efetuar uma resolução em lógica de primeira ordem, que com as Figs. 1.1 e 1.11 sintetisa os conceitos mais importantes deste capitulo. RESOLUÇÃO COM UNIFICAÇÃO Considerando-se as seguintes informações (formalizadas ao lado): 1. Toda atriz é bonita. ∀ x é_atriz(*x) → é_bonita(*x) 2. As avós não são bonitas. ∀ x é_avó(*x) → ¬ é_bonita(*x) 3. Algumas avós são inteligentes. ∃x é_avó(*x) ∧ é_inteligente(*x) Provar que: 4. Algumas que são inteligentes não são atrizes. ∃x é_inteligente(*x) ∧ ¬ é_atriz(*x) Para demonstração, passamos 1-3 e a negação de 4 para a forma de cláusula: 1. ¬ é_atriz(*x) ∨ é_bonita(*x) 2. ¬ é_avó(*y) ∨ ¬ é_bonita(*y) 3a. é_avó(a) 3b. é_inteligente(a) 4. ¬ é_inteligente(*z) ∨ é_atriz(*z) Segue-se a dedução por resolução: 5. 6. 7. 8. 9. 10. 11.
¬ é_inteligente(a) ∨ é_atriz(a) é_atriz(a) ¬ é_atriz(a) ∨ é_bonita(a) é_bonita(a) ¬ é_avó(a) ∨ ¬ é_bonita(a) ¬ é_avó(a) (contradição)
[4; a/*z] [5; 3b] [1; a/*x] [7; 6] [2; a/*y] [9; 8] [10;3a]
Fi g.1. 12–Re s o l uç ã oc o m uni f i c a ç ã o
–16–
–17–
2.
Wi t t y
A ferramenta Wi t t y® é um ambiente de desenvolvimento de sistemas baseados em conhecimento, que permite a confecção de aplicações de amplo espectro, particularmente sistemas voltados ao aprendizado, organização de informações e aquisição de conhecimento. Para isso, dispõe de uma máquina de inferência que permite efetuar deduções sobre uma ou mais bases de conhecimento, de um conjunto de centenas de primitivas em uma linguagem ao estilo do Prolog, de um método de casamento de padrões e de recursos de comunicação com outros processos ou com a Internet. Estes recursos possibilitam a rápida criação de protótipos. Em sua versão servidor, o Witty pode ser encapsulado em outra aplicação, mantendo todo seu potencial mas com uma interface mais adaptada à solução de um problema específico que a de uso geral. O produto teve como origem o SAFO ( Si s t e ma Aut o má t i c o pa r a Fo r ma l i z a ç ã o do Co nhe c i me nt o ) projetado e implementado por Roberto Lins de Carvalho e seus colaboradores (alunos de mestrado e doutorado), como resultado de uma linha de pesquisa em inteligência artificial na área de demonstração automática de teoremas, desenvolvida na PUC/RJ a partir de 1974, onde foram implementados sistemas provadores como o PROVAD, que evolui para o PROVAT a partir de 1983. O SAFO foi desenvolvido para fornecer um ambiente para manuseio de conhecimento, possuindo linguagem de programação em lógica do tipo Prolog e mecanismos que permitiam a introdução, manutenção e manipulação de conhecimento. Teve como função principal a dedução de fatos a partir de um banco de conhecimento composto de fatos e regras, armazenados na forma de cláusulas. Tinha a capacidade de manuseá-los, isto é, incluir, armazenar e excluir, além de diferenciar fatos de regras; respondendo perguntas usando inferência, tendo como base para as respostas o banco de conhecimento nele residente e explicar as conclusões obtidas quando isto fosse solicitado. O Witty é uma evolução tecnológica do SAFO, resultado de esforço conjunto de seu criador com Claudia Maria Garcia Medeiros de Oliveira implementada para uso em sua tese de doutorado no I mpe r i a l Co l l e gena Inglaterra (Oliveira, 1995). Produto integralmente desenvolvido pela inteligência brasileira, num esforço de oferecer ferramentas mais adequadas ao nosso ambiente, cultura e condições, para que, alicerçados na reconhecida capacidade de técnicos nacionais, possamos um dia alcançar a auto-suficiência de desenvolvimento de software na área de processamento de conhecimento. Provê um ambiente interativo para construção, consulta e atualização de informação referentes a um dado domínio de conhecimento. Seu uso não está condicionado a nenhum âmbito específico de conhecimento nem está prevista, explicitamente, a possibilidade de coexistência de vários assuntos numa única explicação.
2. 1–I ns t al aç ãodopr ogr ama A instalação do Witty é feita a partir de oito disquetes, denominados de disk1 a disk8, ou de sua imagem equivalente em outra mídia. Para efetuá-la, o que ocorrerá de forma automática, basta ativar o Wi ndo wsExpl o r e re clicar sobre o programa s et up. exedo primeiro disco:
Fi gur a2. 1–I ns t a l a ç ã odoWi t t y
–18– Isto ativará a rotina normal de instalação, mostrando o contrato sobre direitos de uso do software, solicitando informações do usuários, incluindo o número serial do produto e o diretório para instalação. Depois, todas as adaptações no ambiente Windows serão providenciadas, com a inclusão nos locais adequados de todos os elementos necessários para perfeito funcionamento do Witty, como as versões cliente, servidor, arquivos de ajuda e programas pré-instalados. Associará ao software suas extensões reservadas de arquivo (pr g, kbe gr m) assim como seus ícones de identificação. Desta forma, acionando-se (dois cliques) um arquivo com qualquer destas extensões, o programa será ativado. Todos estes procedimentos levam poucos minutos e nenhuma adaptação precisará ser realizada pelo usuário, que poderá começar utilizar o programa imediatamente.
2. 2–Ar qui t e t ur a A arquitetura básica do Witty é mostrada na Fig. 2.2 da página seguinte. Todos estes elementos serão discutidos no decorrer deste capítulo. Os módulos do Witty estão representados graficamente na figura acima. A seguir uma breve descrição de cada um deles. Módul oPr i nc i pal .Responsável por duas funcionalidades: § inicializar o sistema: criar as estruturas de dados permanentes e instalar o conjunto de comandos primitivos do sistema nas tabelas de símbolos; § iniciar e manter o laço permanente de execução do sistema. O laço permanente do sistema executa os seguintes passos: § obtém comando a ser executado; submete o comando ao analisador sintático e ao montador; § submete o comando ao interpretador.
Fi gur a2. 2–Es q ue madaa r q ui t e t ur amo dul a rb á s i c adaf e r r a me nt aWi t t y Módul oLi nguagens .A linguagem de comunicação entre o usuário e o Wi t t yé do tipo lógica (como o PROLOG) de comandos primitivos do sistema nas tabelas de símbolos. Este módulo analisa léxica e sintaticamente os comandos a serem executados e monta, com auxílio da tabela de símbolos, a expressão a ser interpretada pelo controle. Módul oCont r ol e.Responsável pelo fluxo de execução de comandos e programas. A árvore de execução é construída e interpretada, mantendo o estado de falha ou sucesso dos comandos, gerenciando as variáveis de programa e controlando o b a c k t r a c k i ng. Máqui nadeI nf er ênc i a.Implementa o mecanismo de inferência lógica do Wi t t y, baseado no algoritmo de resolução linear com oráculos e filtros. Os principais passos deste algoritmo são: § seleção de predicados da base de conhecimento; § unificação de predicados; § aplicação de filtros ou oráculo; § b a c k t r a c k i ng; § manutenção dos predicados de comunicação para construção de respostas.
–19– A Fig. 1.3 a seguir, é uma representação esquemática da máquina de inferência.
Fi gur a2. 3–O s i s t e mapr o va d o r Módul o Bas es de Conhe c i ment o.Responsável pela criação e manutenção do conjunto de bases de conhecimento do Wi t t y. Estas bases são armazenadas na forma de cláusulas gerais. O conjunto das bases está organizado linearmente a partir da base inicial chamada c haos .
Fi gur a2. 4–Ae s t r ut ur ada sb a s e sdec o nhe c i me nt o Módul oCas ament odePadr ões .Implementa as funcionalidades de tratamento de linguagens através de gramáticas. Além das funções de casamento de padrões disponíveis, o gerenciamento e o armazenamento de gramáticas e registros são implementados aqui. Módul oI nt er f ac es .Os dois tipos de interface com periféricos disponíveis no Wi t t yestão implementadas neste módulo: § interface com disco, através de arquivos, para manutenção, escrita, leitura e execução de programas externos; § interface com teclado e vídeo, através das caixas de diálogos. Módul oMáqui nadeEs t a dos .A técnica de programação baseada em máquina de estados é interpretada neste módulo. Módul oODBC.implementa funções de acesso a bancos de dados externos através do padrão de interface ODBC - Ope nDa t a b a s eCo nne c t i vi t y. Módul oAr i t mét i c a.Implementa funções aritméticas básicas. Módul oGer ênc i adeMemór i a.Toda a execução de comandos e inferências do Wi t t yé feita em memória gerenciada neste módulo, que inclui: alocação, liberação e ga r b a gec o l l e c t i o n(coleta de lixo). Além disso, o módulo contém algumas funções para facilitar a depuração no desenvolvimento do próprio sistema. Or ác ul o ef i l t r os .Ampliação ou restrição ao poder dedutivo da máquina de inferência, através de programas escritos na sua própria linguagem de programação. API .Rotinas de comunicação com outros programas, onde está implementado, por exemplo, o TCP-IP.
–20– Fr amesdepr ogr amas .A linguagem de comunicação entre o usuário e o Witty é do tipo lógica como PROLOG. Este módulo analisa léxica e sintaticamente os comandos a serem executados e monta, com auxílio da tabela de símbolos, a expressão a ser interpretada pelo controle.
Fi gur a2. 5–Fr a me sdepr o gr a ma s O processo de construção, consulta e atualização do banco de conhecimento é dirigido pelo usuário através de comandos que não obedecem a qualquer ordem de precedência e que compreendem: § introdução de fatos (explícitos) ou regras que propiciem a derivação de novos fatos a partir do conhecimento já existente sobre a área em consideração; § exibição ou editoração de fatos e regras de conhecimento do sistema; § inibição ou desibinição de fatos ou regras; § gravação do conjunto de fatos e regras em arquivos; § respostas a perguntas; § execução de um programa externo; § arquivamento de um texto explicativo da prova de dedução; § exibição de um arquivo. O Wi tt y opera em três níveis, de forma independente ou simultânea: § Como máquina de inferência, efetuando deduções sobre fatos e regras escritos em lógica de primeira ordem; § Como linguagem de programação ao estilo do PROLOG. § Efetuando traduções de linguagem. Combinando estes recursos, poderemos construir de forma bastante rápida protótipos de sistemas baseados em conhecimento.
2. 3–Tel aI ni c i al O programa exibe, já na entrada, algumas de suas principais funções:
Fi gur a2. 6–Te l ai ni c i a ldoWi t t y Ampliamos os elementos da parte superior da tela para melhor visualização:
–21–
Fi gur a2. 7–Pa r t es upe r i o rdat e l adea pr e s e nt a ç ã odoWi t t y A primeira linha exibe os me nus , objeto de uma primeira análise no decorrer deste texto; algumas funções serão melhor esclarecidas nos capítulos seguintes. A l i nhadec o ma ndopermite se digitar diretamente um programa simples; para colocá-lo em execução, é necessário pressionar o triângulo verde à direita. As operações mais comuns foram reunidas na b a r r adef e r r a me nt a s , cujos ícones permitem, pela ordem, as seguintes funções: § Novo § Rascunho § Abrir § Salvar § Salvar todos § Imprimir § Ferramentas de edição de textos § Carregar explicitadas na Fig. 2.8 a seguir.
Fi gur a2. 8–Ba r r adet a r e f a sdoWi t t y A janela Amb i e nt ei ns t a l a doexibe inicialmente as bases de conhecimento ativas. Estas bases são constituidas pelo conjunto de fatos e regras representados por lógica de primeira ordem de um determinado saber. Uma característica importante do W it ty é permitir múltiplas bases. Com isso estrutura-se o conhecimento de forma mais adequada, compartimentalizando-o. Por de f a ul t , todas as bases estão interligadas, na ordem em que forem criadas na sessão. Na abertura do programa aparece a base inicial c haos , fixa e predefinida, onde deve ser armazenado apenas o conhecimento sobre o próprio sistema, isto é, o me t a c o nhe c i me nt o , como por exemplo a estruturação das bases. Esta base é permanente, não podendo ser destruída.
Fi gur a2. 9–J a ne l amo s t r a ndooa mb i e nt ei ns t a l a dodoWi t t y
–22– Outra base particular é a bas es upor t e, que contém as negações das metas. Temporária, é criada no início da dedução e apagada em seu final. Para começar a inferência, a primeira cláusula desta base começa a ser comparada com as claúsulas das demais bases. Caso não seja resolvida, pode ser comparada então com a cláusula seguinte, se existir, da própria suporte. Pode ter qualquer nomeação, o que oferece mais flexibilidade para o caso de deduções simultâneas em paralelo, que devem ser efetuadas em bases suportes diferentes. Neste texto, será chamada de s up.
2. 4–I nt er f ac e No Amb i e nt ei ns t a l a do , clicando-se sobre Fa t o sou Re gr a s , permite-se abrir uma árvore avistando todos os elementos armazenados na base. Além de conferência, será possível também editar estes elementos, corrigindo, eliminando ou incluindo, como será visto no capítulo seguinte. As alças inferiores, possibilitam a mesma visualização para programas, gramáticas ou registros ativos, sempre associadas aos ícones da Fig. 2.10:
Fi gur a2. 10–Í c o ne sut i l i z a do spe l opr o gr a ma
Fi gur a2. 11–Me nudec o nt e xt o( b o t ã odi r e i t odomo us e )pa r ab a s e s Todos os menus do programa são sensíveis ao contexto com o b o t ã odi r e i t odo mouse permitindo acesso rápido a eles. A Fig. 2.11 acima exibe as funções disponíveis quando se usa este recurso dentro da janela de Amb i e nt ei ns t a l a do : à esquerda o menu referente à raiz (Ba s e s ) e à direita, sobre uma base específica. Com isso, a manutenção das bases torna-se bastante facilitada, podendo ser realizada interativamente sem uso de comandos. Esta forma de trabalhar é tão mais simples, que dispensa qualquer outra alternativa. Por isso não há opções de acessar as bases através de menus. A linha de menus do Witty segue o padrão utilizado por outros programas para o ambiente Windows, sendo a seguinte Ar qui vo Edi t ar Exi bi r Exec ut ar Fer r ament as J anel a Aj uda Para acionar qualquer um deles, basta clicar sobre a palavra. Se preferir, poderá utilizar o atalho de teclado do Windows que consiste na combinação das teclas Al t l e t r as ub l i nha da .De acordo com o mesmo padrão, se tiver um triângulo no canto direito indica a existência de submenus e se terminar com reticências (...), abrirá nova janela de diálogo. Discutiremos as funções do menu conforme sejam necessárias, associadas a tarefas sendo abordadas. Abaixo, descreveremos algumas características gerais. O menu Ar q ui vo , permite criar novo programa ou gramática, abrir arquivos específicos ou o de trabalho (rascunho.prg), além de fechar ou salvar algum arquivo ou todos que estiverem em uso. A segunda divisão tem a ver com impressão, a terceira com enviar arquivos e a quarta lista os últimos arquivos que foram abertos. O medu Edi t a rapresenta as alternativas usuais como desfazer, recortar, copiar e colar, além de localizar e substituir. O último item, Pr i mi t i va sPRG lista todos os comandos disponíveis do Witty, classificadas por tipo (primeira janela) e ordem alfabética da cabeça do comando (segunda janela). Presta-se a consultar rápidas pra dirimir dúvidas sobre a forma correta de escrever algum comando do Witty. O Me nuExi b i rpermite mostar ou ocultar algum elemento do ambiente, bastando clicar sobre seu nome no menu. Na Fig. 2.12 (página seguinte) os elementos presentes estão identificados por um tique (R ). O Vi s o ré utilizado para mensagens de retorno do sistema, podendo ser redimensionado como qualquer outra janela do ambiente. A alternativa Re l a t ó r i odeEr r o s , discutida adiante, abrirá uma janela contendo a listagem dos comandos programados de forma errônea.
–23–
Fi gur a2. 12–Me nuExi b i r O menu Exe c ut a rpermite lançar a primita codificada na linha de comando ou um arquivo de programa (extensão .prg) que estiver ativo e será visto no Cap. 9. Entre as opções do menu Fe r r a me nt a s , há a ativação o navegador interno do Witty, com a mesma a funcionalidade de produtos similares e será aberto na página definda como Home.
Fi gur a2. 13–Na ve ga do rdoWi t t y
Fi gur a2. 14–Me nuFe r r a me nt a s ,Opç õ e sFo nt e s
–24– A alternativa Opç õ e sdo Me nuFe r r a me nt a spermite algumas adaptações no ambiente visando torná-lo mais confortável. A primeira modificação possível é com tamanho, estilo e face das fontes, por exemplo aumentando-a e colocando-se negrito para maior visibilidade. O botão Mo di f i c a rabre a janela para escolha de fontes e o Pa dr ã orestaura aos valores iniciais. São permitidos alterar as fontes do Ambiente instalado, como na Fig. 2.14, dos editores e das caixas de diálogo. Uma vez feita a escolha, passa a valer imediatamente e em todas as sessões seguintes, até que seja novamente alterada. As demais abas de Opções serão vistas posterioremente. A alternativa Se r vi do rserá discutida no Cap. 13.
Fi gur a2. 15–Me nuJ a ne l a O Me nu J a ne l aapresenta dois blocos. O primeiro permite a reorganização das janelas abertas, conforme mostrado na Fig. 2.16 abaixo. O segundo lista todos os arquivos abertos, indicando o c o r r e nt ecom um tique (3). Clicando sobre outro nome (ou pelo atalho Al t núme r o ) tornará este o novo arquivo corrente. Esta lista é também útil para se procurar uma janela existente que ficou coberta por outra.
Fi gur a2. 16–Al t e r na t i va sdoMe nuJ a ne l a s :Ca s c a t a ,La doal a doho r i z o nt a leve r t i c a l Por último, o menu Aj uda , fornece informações on-line sobre diversos aspectos do programa, como a adescrição dos comandos internos do Witty, manual de programação e instruções passo-a-passo, exibido na Fig. 2.17 a seguir.
Fi gur a2. 17–Me nuAj uda
–25–
3. Bas esdec onhec i ment o 3. 1–Conc ei t uaç ões O alfabeto básico para representar conhecimento no Witty é o seguinte: § Letras: a, b, ..., z, A, B, ..., Z § Dígitos: 0, 1, 2, ... , 9 § Pontuação: (, ), . , ', “ § Especiais: +, -, *, <, >, =, _, etc. § Conectivos: o and conjunção; o ordisjunção; o not negação; o i mpl i es implicação; o i f f se e somente se; o i f . . .t hense... então. Esta linguagem é não-tipada, assim os valores tratados podem ser usados reciprocamente. As estruturas podem conter diferentes tipos de valor, como letras ou dígitos. Podemos comparar tipos diferentes de valor pela relação “=“ (i gua la ), mas esta nunca será satisfeita. Át omos . São cadeias de letras, dígitos ou símbolos do alfabeto básico começando com símbolo do alfabeto básico. Se contiverem o branco devem vir delimitadas por aspas. n Exemplos:não, OK, depende, “São Francisco”, “X y”, “15.2” n Cons t ant es .Uma constante pode ser um átomo, uma cadeia de dígitos ou uma cadeia de símbolos do alfabeto básico (podendo incluir o branco) delimitada por aspas (““). Var i ávei s .São cadeias de letras e dígitos iniciando com o símbolo “* ” (a s t e r i s c o ). Uma variável Witty denota um valor fixo mas de tipo desconhecido. Também é declarada implicitamente por sua ocorrência em uma cláusula, e seu escopo se dá na cláusula em que ocorre. n Exemplos: *x, *Y, *z, *Pa, *X15, *NOME, *resposta. n Ter mos .A estrutura de dados básica propiciada pela linguagem é o t e r moWi t t y, que pode ser uma constante, uma variável ou um termo funcional da forma f ( t 1,. . . ,t n) , onde fé um átomo (predicado) e t 1,. . . , t nsão também termos (variáveis ou constantes). I nt ei r os .São utilizados para operações aritméticas e usados freqüentemente em listas. n Exemplos: 16, 2000, 0, -27 n Reai s . (Ponto flutuante) Empregados para operações aritméticas em números decimais. Apresentam precisão de 15 casas após a vírgula (no caso, po nt ode c i ma l ). n Exemplos: 3.1416, -273.15, 6.0221 n Cadei adec ar ac t er es . São usadas para manipular textos; escritas em caracteres ASCII delimitadas por aspas: “cadeia”. Uma cadeia vazia é escrita como ““. n Exemplo: “O Witty é uma ferramenta adequada para aplicações educacionais”. n Fór mul aat ômi c a.Cadeia da forma: p( t 1,. . . ,t n) , onde t 1,. . . ,t nsão termos e p é um átomo no papel de um símbolo predicativo ná r i o(no exemplo abaixo é q ua t e r ná r i o ) n Exemplo:livro(autor,título,editora,ano) n Fat os . Se Afor uma fórmula atômica, então Aserá um fato posito e no tA, um fato negativo. n Exemplo:é_homem(Pedro), cujo significado é “Pedro é homem”. n Regr as . Se Ae B1, . . . ,Bnsão fatos, então as expressões: i fB1a nd. . .a ndBnt he nAé uma regra condicional, onde A é o c o ns e q üe nt ee B1, ..., Bn são os a nt e c e de nt e sda regra; B1a nd. . .a ndBni mpl i e sAé uma implicação.
–26– As disjunções são também consideradas como regras, a razão a implicação B1 and ... and Bn implies A é logicamente equivalente a not B1 or ... or not Bn or A. n Exemplo:é_homem(*x) and é_pai-de(*y,*x) implies é_filho-de(*x,*y) cujo significado é: “para todo x e y, x é filho de y se x for homem e y for pai de x”. n Cons ul t a.A consulta é implementada através da primitiva pr ove. n Exemplo: prove (sup,é_marido-de(“Pedro II”,”Teresa Cristina”) significando pr o veusando a base de suporte s up, que “Pedro II é marido de Teresa Cristina”. n Uni f i c aç ão.Nas linguagens de programação convencionais, o passo mais básico da programação é a atribuição de valores às variáveis. No Wi t t y, o processo de atribuição é um pouco diferente, sendo denominado uni f i c a ç ã oou c a s a me nt odepa dr õ e s . Essa operação consiste em tomar dois termos e tentar tornálos idênticos, através da substituição das variáveis existentes nos termos por valores. Se for possível torná-los idênticos, as variáveis serão trocadas pelos valores, sendo a unificação bem sucedida. Caso contrário, ela falhará. Dessa forma, torna-se possível atribuir a uma variável um valor qualquer. Dois termos se unificam se: § Eles forem idênticos, ou § As variáveis existentes nos termos podem ser substituídas por valores tais que, após a substituição, os termos se tornem idênticos. Regr asger ai sdeuni f i c aç ã o § Va r i á ve i sc o m va r i á ve i s : variáveis sempre se unificam com outras variáveis. Depois de uma delas ser substituída por um valor, a outra também será substituída pelo mesmo valor. § Co ns t a nt e sc o m va r i á ve i s : a variável é substituída pelo valor da constante. Isto pode ser visto como uma forma de atribuição. § Co ns t a nt e sc o mc o ns t a nt e s : para que a unificação seja bem sucedida, é necessário que as constantes sejam idênticas. Logo, átomos se unificam com átomos de mesmo nome, inteiros com inteiros de mesmo valor, etc. Já um átomo não se unifica com um inteiro ou com um real. Uma cadeia de caracteres e um átomo, mesmo que tenham o mesmo texto, também nunca se unificam. § Te r mo sf unc i o na i sc o mt e r mo sf unc i o na i s : os símbolos funcionais dos dois termos devem ser iguais, e além disso, os argumentos devem se unificar. n Exemplos: 1. Os termos funcionais r o ma nc e ( po l i c i a l )e r o ma nc e ( * x)se unificam: basta que a variável * xseja substituída pelo átomo po l i c i a l . 2. Os termos ma nua l ( Ba s e s , 17)e ma nua l ( * c a p, * pá g)se unificam se substituirmos as variáveis * c a pe * pá gpor Ba s e se 17, respectivamente. 3. A unificação de li vr o ( * no me , 17)e l i vr o ( t i t ul o , 18)falha, pois os argumentos inteiros 17 e 18 não se unificam. n Cons ul t as . Uma consulta força a execução de um programa, permitindo: § certificar-se a respeito de relacionamento entre objetos do domínio do problema; § recuperar dedutivamente informação armazenada. Quando se digita um programa no banco de conhecimento, e posteriormente desejar fazer uma consulta, o Wi t t yfará uma pesquisa para ver se encontra um fato que se unifique com a consulta, retornando sucesso ou falha. n Exemplo:Na base de conhecimento a seguir é_pai-de(“João IV”, “Pedro I”) é_pai-de(“João IV”, “Miguel de Bragança”) é_pai-de(“Pedro I”, “Pedro II”) é_pai-de(“Pedro I”, “Maria da Glória”) é_pai-de(“Pedro II”, “Princesa Isabel”) if é_pai-de(*x,*y) and é_pai-de(*y,*z) then é_avô-de(*x,*z)
se for feita a seguinte consulta: prove(sup, é_avô-de(“João VI”, “Pedro II”)).
a unificação desta cláusula com a regra, atribuirá a * xo valor “J o ã oVI ”e a * z , “Pe dr oI I ”. Assim, as cláusulas antecedentes resultarão em é _pa i de ( “J o ã o VI ”, * y)e é _pa i de ( * y, “Pe dr oI I ” ) . A primeira unifica com o primeiro
–27– fato resultando para * y“Pe dr oI ”; a segunda com o terceiro, resultando o mesmo valor pra *y. Logo, a resposta será afirmativa. Porém, se a consulta fosse prove(sup, é_avô-de(“Miguel de Bragança”, “Princesa Isabel”)).
a resposta seria negativa, por não encontrar fatos necessários para a unificação para Miguel de Bragança. n
3. 2–Bas esdec onhec i ment osnoWi t t y Para se criar uma base de conhecimento, parte-se do menu de contexto indicado escolhendo-se a opção No vab a s e , chega-se à janela Pr o pr i e da de sdab a s eda Fig. 3.1:
Fi gur a3. 1–Cr i a ç ã odeumab a s edec o nhe c i me nt o Na alça Ge r a lse estabelece o nome da base. O tamanho pode ser qualquer, respeitados os limites determinados pelo Windows, desde que não contenha brancos e s eut i l i z es o me nt ec a r a c t e r e smi nús c ul o s . As outras duas alças permitem a adição de Fa t o se Re gr a s , respectivamente. Neste caso devem ser escritas fórmulas bem formadas, de acordo com as regras da lógica de primeira ordem e convenções sintáticas impostas pelo programa sumariadas na seção anterior. A edição de Fatos ou de Regras é feita da mesma maneira. Escolhendo-se a alça desejada, todos os dados já existentes serão listados, numerados sequencialmente a partir do número 1. A janela inferior é a de edição. É nela que se escreve a fórmula. Pressionando-se o botão I nc l ui r , ela será adicionada no último lugar da lista. Caso se clique sobre alguma linha, esta será transportada para a janela de edição podendo ser corrigida. Neste caso deve-se utilizar o botão Al t e r a r . Finalmente, o botão Apa ga rremove a fórmula selecionada. Uma vez feitas as correções, estas podem ser confirmadas utilizando-e o botão OK ou abandonadas, se optar por Ca nc e l a r .
–28–
Fi gur a3. 2–Fa t o ser e gr a sdab a s eq ua dr o s Caso estas informações sejam confirmadas, a base de conhecimento terá o conteúdo mostrado na Fig. 3.3, a seguir:
Fi gur a3. 3–Co nt e údodeumab a s e Conforme atrás, o quadrado à esquerda que precede as linhas pode conter os símbolos '' ou '+'. No primeiro caso, só aparece o nível mais elevado do ramo e no último, a árvore estará expandida. Clicando-se sobre o quadrado, ele mudará de um conteúdo para o outro, permitindo se ver a árvore com o nível de detalhe desejado. Este funcionamento é similar ao do Wi ndo wsExpl o r e r . As bases oferecem agora um novo menu de contexto, já mostrado na Fig. 1.11, detalhado na Fig. 3.4 abaixo:
Fi gur a3. 4–Me nudec o nt e xt opa r aumab a s ee s pe c í f i c a Neste menu, os tiques (ü ) à esquerda indicam estados selecionados. No exemplo a base está ativa e foi solicitado que se mostrasse os números, como fica mais visível na Fig. 3.3 atrás. Caso a opção seja escolhida novamente, será desativada. No primero quadro, há apenas a escolha Pr o pr i e da de s . Selecionada, abrirá a janela Pr o pr i e da de sda
–29– b a s e ,alça Ge r a l , mostrada na Fig. 3.1. No segundo, No vac l á us ul a , abrirá a janela na alça Fa t o s , lado esquerdo da Fig. 3.2. No último quadro, as escolhas Sa l va re Sa l va rc o mo . . .armazenam o conteúdo da base em um arquivo com extensão . kbpara uso futuro. Li mpa rremoverá todos os fatos e regras da base, mas ainda a manterá ativa. Apa ga rfará isso e destruirá a base. Caso se deseje reativar uma base salva anteriormente, pode-se usar o menu de contexto das bases, exibido na Fig. 3.1. A saída do programa destruirá o conteúdo de todas as bases da sessão. Se desejar preservá-las, deve-se efetuar a gravação em disco, individualmente, ou em conjunto, com a última opção deste menu.
3. 3–Cons ul t ant ooWi t t y A criação de uma base de dados pode ser feita de forma interativa, através do comando as s er t . Para a utilização das bases em uma dedução, é preciso empregar o comando pr ove, que possui a seguinte sintaxe: prove(
,) A em questão é aquela de s upo r t e , cuja existência se restringe ao período de prova. A verificação se refere à base ativa no momento. Este comando pode ser combinado com outros que exibam a resposta da prova, como por exemplo lsmsg(<mensagem>), que exibe o conteúdo de <mensagem> em uma janela denominada Vi s o r . A forma mais curta para isso é: prove(,) & lsmsg(“SIM”) | lsmsg(“Não”) onde os símbolos “&”e “|”significam respectivamente E(a nd) e OU (o r ). O uso de aspas nas cadeias de caracteres somente serão obrigatórias caso esta cadeia contenha brancos (o que não é o caso). A execução de programas nesta linguagem segue a ordem de leitura. Se não houver falha, executará o E, exibindo SI M; caso contrário o OU, mostrando Não. No exemplo da Fig. 3.5, o comando prove foi emitido na janela de comando e executado a partir do menu.
Fi g.3. 5–Co ma ndoprove ap a r t i rdal i nhadec o ma ndo Pode-se também colocar em execução um programa da linha de comando pressionando-se o triângulo verde à sua direita. A idéia é utilizar este recurso para programas pequenos, como o do exemplo. Programas mais extensos – ou mesmo programas mais curtos que se deseja armazenar – são editados em um arquivo com extensão . pr g. Para tal, pode-se usar qualquer arquivo de texto que grave o formato ASC puro (texto). O Witty disponibiliza o seu próprio, semelhante ao Bloco de Notas. Pressionando-se novona barra de ferramentas, serão criados sucessivamente os arquivos Wi t t y1,Wi t t y2,. . .Wi t t yn, cujos nomes podem ser alterados na hora da gravação. Para se colocar um programa em execução, é obrigatório que seja gravado antes. A opção r as c unhoda barra, abre o arquivo r a s c unho . pr g, que é um único para todas as sessões do produto. Um programa Witty é uma seqüência de parágrafos (no exemplo, um único) que precisam ser
–30– encerrados pelo caractere núme r o (#). Estes parágrafos podem se estender por tantas linhas quantas necessárias, conforme o estilo do programador. São permitidos comentários em linhas iniciadas pelo caractere po r c e nt o(%), caso em que serão ignoradas pelo tradutor. Pode-se colocar também este caractere no meio de uma linha, convertendo-a em comentário a partir dali. Este assunto será explorado em mais detalhes no capítulo seguinte.
Fi g.3. 6–Co ma ndoprove ap a r t i rdea r q ui vodepr o gr a ma Após cada consulta, deve ser pressionado o botão Limpar da janela Visor para que o novo valor posssa ser exibido sem interferência da mensagem anterior.
3. 4–Ef et uandodeduç ões Para demonstrar o potencial deste recurso, vamos montar uma pequena base de conhecimento, inicialmente em linguagem usual e, posteriormente em lógica de primeira ordem sobre a qual poderemos executar a dedução de um conhecimento implícito. No exemplo a seguir, vamos considerar a base de conhecimento: 1. Canário canta. 2. Serpente é ovíparo. 3. Marreco é ovíparo. 4. Pardal é ovíparo. 5. Morcego voa. 6. Marreco voa. 3. Pardal voa. 3. Todo animal que canta é ave. 3. Todo ovíparo que voa é ave. 10. Toda ave tem penas.
Qua dr o3. 1–Ba s edec o nhe c i me nt os o b r ea ve s que, escrita em linguagem de primeira ordem, se converte em
–31– [F1] canta(canário). [F2] é_ovíparo(serpente). [F3] é_ovíparo(marreco). [F4] é_ovíparo(pardal). [F5] voa(morcego). [F6] voa(marreco). [F7] voa(pardal). [R1] if canta(*x) then é_ave(*x). [R2] if é_ovíparo(*x) and voa(*x) then é_ave(*x). [R3] if é_ave(*x) then tem_penas(*x).
Qua dr o3. 2–Ame s mab a s ee ml i ngua ge m depr i me i r ao r de m A pergunta que desejamos ser respondida é “O par dalt em penas ? ”. Inicialmente carregaremos a base, mas não mais de forma interativa e sim através de um arquivo de programa, c ar r ega_aves . pr g, com o seguinte conteúdo: newbase(aves)# assert(aves,canta(canário))# assert(aves,é_ovíparo(serpente))# assert(aves,é_ovíparo(marreco))# assert(aves,é_ovíparo(pardal))# assert(aves,voa(morcego))# assert(aves,voa(marreco))# assert(aves,voa(pardal))# assert(aves,if canta(*x) then é_ave(*x))# assert(aves,if é_ovíparo(*x) and voa(*x) then é_ave(*x))# assert(aves,if é_ave(*x) then tem_penas(*x))#
Qua dr o3. 3–Pr o gr a mapa r ac a r gadab a s ea ve s Neste caso, cada linha é um parágrafo, e, como tal deverá ser encerrada pelo caractere “#”. O primeiro comando cria a base de conhecimento avese os demais a povoam. Aliás esta seqüência de newbase e asserts é a forma utilizada pelo Witty para salvar as bases de conhecimento em arquivos de extensão kb. Em seguida, abrimos o arquivo t em_penas . pr g. Não precisaria ser necessariamente este, senão qualquer outro com tal extensão. Nele digitamos o programa: prove(sup,tem_penas(pardal)) & lsmsg(SIM) | lsmsg(Não)#
E pressionamos o botão de execução. Conforme esperado, o retorno é “SI M”, mostrado na Fig. 3.7:
Fi g.3. 7–Pr o vapa r aab a s ea ve s
–32–
–33–
4. Pr ogr amandonoWi t t y 4. 1–Pr ogr amass i mpl es Os programas no Witty podem ser graduados em nível de complexidade, desde uma linha até estruturas intrincadas que envolvam chamadas externas, comunicação TCP/IP ou recursos avançados de lógica com apoio de oráculos e gramática. Neste capítulo abordaremos de forma gradativa os esquemas mais básicos e, nos próximos, mostraremos a utilização dos demais tópicos citados. Os programas na linguagem Witty enquadram-se nas seguintes categorias: § Primitivos; § Seqüenciais; e § Alternativas. Informalmente chamaremos de s i mpl e sao programa que combinar estas categorias e puder ser escrito em uma única linha. A seguir, detalharemos alguns comandos primitivos e citaremos os principais. Os mais importantes serão objetos de estudo nos próximos capítulos. Como veremos, há farta documentação online sobre todos os comandos da linguagem. Alguns primitivos do Witty quando executados exibem caixas de diálogo para interação com o usuário, muitas bastante elaboradas, objetos do capítulo seguinte. Os mais simples podem ser escritos diretamente na l i nhadec o ma ndo , como o da Fig. 4.1 a seguir, que exemplifica o emprego do comando ms g( <me ns a ge m>, <po s x>, <po s y>) :
Fi gur a4. 1–Co ma ndopr i mi t i vomsg Para colocar em execução a partir da linha de comando, basta se teclar Enter ou se pressionar o triângulo verde à esquerda da linha. O botão para baixo no final da linha permite acesso aos dez últimos comandos digitados anteriormente. Convém ressaltar que os comandos devem sempre ser escritos com letras minúsculas. Outras primitivas realizam modificações internas no Witty, como por exemplo no a mb i e nt ei ns t a l a do , assim o comando a s s e r t ( , |)acrescenta um fato ou uma regra na base especificada. A Fig. 4.2 mostra esta possibilidade:
Fi gur a4. 2–Mo di f i c a ç ã odab a s echaos pe l ai nt r o duç ã odof a t oé_mineiro(Pelé)
–34– Outras modificações no Amb i e nt ei ns t a l a dosão possíveis em Pr o gr a ma s ,Gr a má t i c a se Re gi s t r o s , que podem ser acessadas pelas alças inferiores da janela. Estes últimos são utilizados para passagem de parâmetro entre módulos do programa e terão aplicação destacada nas Gramáticas, onde serão estudados em detalhe. Os comandos específicos de atribuição e recuperação de valores de registro são os seguintes: a s s i gn( , ) r e t r i e ve ( , ) Como será visto à frente, há um comando de criação de registro, porém o a s s i gncria o registro na primeira atribuição. A segunda primitiva move o conteúdo de um registro para uma variável para este valor ser usado em seguida em outro comando. Recordamos que as variáveis possuem nome iniciando obrigatoriamente com o caractere a s t e r i s c o(*). A Fig. 4.3 da página seguinte ilustra a criação de um registro e sua exibição no ambiente instalado. São também exibidos os registros pe r ma ne nt e s , que não podem ser destruídos nem seus conteúdos modificados, utilizados em tarefas especiais dentro do Witty. Entrte eles, há os que armazenam caracteres especiais como a c c e nt (‘ – apóstrofo), numb e r (# – número) e q uo t e (“ – aspas).
Fi gur a4. 3–Co nt e údodo sr e gi s t r o spe r ma ne nt e s A execução de programas em seqüência é permitida através do s e qüe nc i ador& (lê-se “e”), indicando que os comandos devam ser executados na ordem indicada, conforme exibido na Fig. 4.4 a seguir:
Fi gur a4. 4–Exe c uç ã odec o ma ndo se ms e q üê nc i a Há outra caixa de mensagem utilizada pelo sistema, o Vi s o r . Ao contrário da vista anteriormente, abrirá em posição aleatória da tela (dispensando assim se informar as coordenadas) e pode ser
–35– redimensionada arrastando-se seus contornos com o mouse. Para enviar dados para o Visor utiliza-se o comando l s ms g( “<me ns a ge m>“) . Lembramos que toda cadeia de caracteres em Witty deverá ser escrita entre aspas se contiver ao menos um caractere especial, como o espaço em branco. Se contiver apenas uma palavra, o uso dos aspas é opcional. A combinação deste comando com l f(nova linha) forma uma seqüência de fácil entendimento, explorada na Fig. 4.5:
Fi gur a4. 5–Co ma ndolsmsg eoVisor Há também comandos de verificação do ambiente, que testam alguma condição mas não o modificam. O comando pr o ve , visto no capítulo anterior, é um destes. Em geral, verifica se a afirmação é verdadeira ou falsa com respeito à informações armazenadas em uma base de conhecimento. No entanto, o comando permite acrescentar novas cláusulas como em pr o ve ( , ) 1> 2> n> Neste caso, somente a última será testada e todas as anteriores serão consideradas premissas e incluidas na b a s edes upo r t enomeada em e utilizadas para efetuar a dedução. Como nos casos discutidos no capítulo anterior, o comando retorna sucesso ou falha, conforme consigua ou não efetuar a prova. No exemplo a seguir iremos efetuar uma dedução sem base de conhecimento, somente com as cláusulas incluidas no próprio comando. Trata-se do mo duspo ne ns : p(a) p(a) implica p(b) p(b) realizado pelo programa digitado na linha de comando da Fig. 4.6:
Fi gur a4. 6–Co ma ndoprove ede s vi opa r aa l t e r na t i va s Um aspecto importante visto no exemplo acima é a possibilidade de se colocar várias alternativas através do al t e r nador“|” (lê-se “ou”). O comando pr o veforma uma seqüência com o primeiro l s ms g, que será executado quando o comando retornar sucesso. Se o comando falhasse (se por exemplo tentássemos provar p( c ) ), seria executado o segundo l s ms g, após o a l t e r na do r(|), exibindo a mensagem Fa l s o .
–36– 4. 2–Pr ogr amasmai sc ompl exos Ainda que seja permitido o uso da l i nhadec o ma ndopara programas mais longos, uma vez que a janela rola horizontalmente, sua utilização neste caso será, no mínimo, muito incomôda; além do fato de não possibilitar mais que duas alternativas. Há várias situações onde isto será necessário. Muitos comandos de interface com o usuário, por exemplo, devolvem um código de retorno que pode ser múltiplo. Assim, a estratégia para tal tratamento exigirá outro expediente, o a r q ui vodepr o gr a ma– um arquivo texto identificado pela extensão . pr g. A utilização deste tipo de arquivo exige cuidados que serão abordados gradativamente neste capítulo e resumidos na Tabela 4.1 (pág. 168) para facilitar a consulta. A criação de tais arquivos pode ser feito com qualquer editor de texto – desde que salvos como texto puro (ASC). O ambiente do Witty fornece um editor semelhante ao Bloco de Notas do Windows. O primeiro conjunto de ícones da barra de ferramentas é de manutenção de arquivos para o Witty: além dos de programas, há os referentes a base de dados (. kb) e a gramáticas (. gr m), objetos de outros capítulos. O primeiro ícone (no vo ) permite criar um novo arquivo no diretório atual com nome wi t t y1. pr gna primeira vez dentro da sessão, ou numerado seqüencialmente para os seguintes. O Witty exige que o arquivo seja gravado antes da execução e, nesta altura o nome pode ser modificado. O segundo (r a s c unho ) abre um arquivo específico r a s c unho . pr g, que é um só por instalação, com o último conteúdo (mesmo se for de sessão anterior) ou vazio, se for a primeira vez que for empregado. A idéia é utilizá-lo para verificações que não necessitem ser guardadas; enfim, como rascunho mesmo. O terceiro abre arquivo já existente no diretório corrente, por padrão com extensão . pr g– podendo ser alterado caso se deseje manusear outro tipo de arquivo. Os demais ícones são autoexplicativos. Convém ressaltar que os programas são seqüências de pa r á gr a f o s , que podem ocupar mais de uma linha. Nenhum sinal de continuação será preciso, porém será necessário indicar o seu final, através do caractere núme r o(#). O Witty ignora o conteúdo de uma linha após o sinal po r c e nt o(%), característica empregada para se adicionar comentários ao programa. Para exemplificar o uso de arquivo de programa, utilizaremos o comando de interface com o usuário as k: a s k ( , <* r e t o r no >, <po s x>, <po s y>) cujos códigos de retorno estão ilustrados na Fig. 4.7 a seguir:
Fi gur a4. 7–Có di go sder e t o r nopa r aoc o ma ndoask O programa da Fig. 4.8 (página seguinte) permite o tratamento de alternativas múltiplas. Note que cada parágrafo (encerrado por um ‘#’) é referente a uma dessas opções. Na primeira linha, a variável * x receberá um valor que depende do botão pressionado pelo usuário. Este valor é armazenado no registro r e g1 para ser utilizado também nos parágrafos seguintes, pois as variáves são estritamente locais ao parágrafo onde forem definidas. Na terceira linha há um teste do valor de retorno. Caso seja igual a zero, o comando seguinte, a emissão da mensagem, será executado. Como falha esta verificação (o valor para i gno r o é dois), nada acontece e o processamento segue para o parágrafo seguinte. No segundo parágrafo o valor do registro é recuperado para a variável * y para utilização na comparação a seguir. Nada impediria que se empregasse * xcomo variável, porque a existência delas é
–37– somente dentro de um parágrafo – aí sim, se houver mais de uma devem ter denominações distintas. A comparação também falha, a mensagem não será emitida e a execução passa para o último parágrafo. Neste, o processo é o mesmo, mas a comparação se verifica e a mensagem associada emitida. É essencial que a comparação apareça em todos os parágrafos, uma vez que a execução é seqüencial. Caso o último parágrafo fosse apenas l s ms g( “Va l o rder e t o r no :2>I gno r o ”) # seriam emitidos todas as mensagens duas mensagens emendadas.
Fi gur a4. 8–Ar q ui vodepr o gr a mapa r aa l t e r na t i va smúl t i pl a s
Fi gur a4. 9–De f i ni ç ã odepr o gr a ma s Há ainda o recurso de programação modular, quando se escrevem diversos programas que depois serão evocados. Para tal será necessário o comando para definição de programas: de f pr g( <no me _pr o gr a ma >, ) . No exemplo da Fig. 4.9 atrás, definiremos dois módulos e nt r a dae e xi b e , que serão chamados nesta ordem no final do programa. No primeiro, empregaremos uma simplificação do comando de entrada de dados: i nput ( 1, , , <* da do _di gi t a do >, <po s x>, <po s y>) onde fixamos a quantidade de campos para um. Este comando será detalhado no Cap. 10 –Ca i xa sdedi á l o go s . Os dois dados informados (nome e nota) ficarão armazenados em registros para utilização no programa seguinte.
–38– No 1 2 3 4
5 6
7 8
9
10
Regr a Devem ser utilizadas letras mi núscul asnos comandos, com exceção dos literais e alguns comandos especiais (como o NOT, diverso de cláusula negativa not ). A execução do programa é seqüencial, obedecendo a ordem de colocação dos comandos, a exemplo do PROLOG. De forma análoga ao PROLOG, os comandos são definidos por um nomee, dependendo da aridade, parâmetros entre parêntesis separados por vírgulas. Os parâmetros podem se constituir de const ant esou var i ávei s: Constantes numéricas ou literais (cadeias de caracteres); devem ser limitados por aspas(““) quando contiverem o caracteres especiais como branco, vírgula, parentêsis ou iniciar com asterisco, apóstrofo ou aspas; sendo seu uso opcional em caso contrário. Os nomes das variáveis devem ser precedidas por um ast er i sco(*). Todas as variáveis do W i t t y são estritamente locais, visíveis somente dentro do parágrafo onde forem definidas. A passagem de valores entre diversos parágrafos do programa é feito através de r egi st r os. Uma vez definido, mantém seu valor até que haja um comando explícito de modificação ou se encerrar a sessão. [Ver considerações no final desta seção] Todo parágrafo de programa, que poderá ocupar uma linha ou mais, deverá ser encerrado pelo caractere # (númer o). Dentro de um parágrafo, são permitidas ligações entre comandos utilizando-se: o seqüenciador & (ecomer ci al ) que se lê e; e o alternador | (bar r aver t i cal ) (ou). Os comentários são precedidos pelo sinal % (por cent agem). O conteúdo da linha após este caractere não será considerado. Pode ser utilizado na primeira coluna ou numa linha após um comando (exceto na última linha, caso em que gerará erro; se for necessário colocar linhas de comentário no final de um arquivo de programa, elas deverão ser sucedidas pelo comando hol d#). O arquivo r ascunho. pr g é utilizado como área de trabalho para escrever programas. Ao ser evocado, ele será aberto com o último conteúdo ou vazio.
Ta b e l a4. 1–Ca r a c t e r í s t i c a sdea r q ui vo sdepr o gr a mapa r aoWi t t y Exi b eé definido duas vezes. Poderiam ser mais caso necessário, uma para cada condição. A condição da quinta linha difere em ambos os casos. Se ela se verificar a mensagem será emitida; caso contrário a próxima definição será executada até que se encontre a correta. Os ramos onde a condição falha nada produzem, preservando o resultado correto. Neste programa usaremos a concateção de cadeias de caracteres c o nc a t ( , , <* c a de i a _c o nc a t e na da >) A Tabela 4.1 acima, reúne as características de arquivos de programas W it t y d is per sa s na s exp li ca ç õe s a nte ri or es. Para exercitar estas condições, vamos propor a execução do programa e r r o s . pr gque violará algumas destas regras. Desta forma será possível também, demonstrar os recursos de depuração existentes noWitty que facilitam a deteção de correção de erros. A listagem do programa está a seguir: % --- Programa de demonstração para corrigir erros Lsmsg(“Mensagem na primeira linha”) & lf# concat(Primeira Parte,Segunda Parte,tudo) & lf# ask(“Samambaia é vegetal?”,*x,100,200)# lsmsg(*x)#
Ao se colocar em execução, por exemplo através do botão c a r r e ga rda barra de ferramentas, os erros serão acusados um a um (a figura só exibe os primeiros). Clicando-se no botão OK, aparecerá o seguinte até que se esgotem. É muito comum em programas os erros serem encadeados, isto é, um deles poderá originar outros, dando a impressão de ser em maior número que na realidade.
–39–
Fi gur a4. 10–Me ns a ge m dee r r odepr o gr a ma Estas mensagens podem ser vista todas ao mesmo tempo acionando-se Exibir | Relatório de Erros, como mostra a Fig. 4.11:
Fi gur a4. 11–Re l a t ó r i odeEr r o s Corrigindo os erros mais evidentes, chegando-se ao seguinte resultado: Regras 1 4 e 7
% --- Programa de demonstração para corrigir erros lsmsg(“Mensagem na primeira linha”) & lf# concat(“Primeira Parte”,”Segunda Parte”,*tudo) & lsmsg(*tudo)# ask(“Samambaia é vegetal?”,*x,100,200)# lsmsg(*x)#
No primeiro comando a primeira inicial para letra minúscula ( r e gr a1) ; no segundo, os parâmetros de c o nc a testavam indevidamente representados, pois faltavam as aspas para delimitar as cadeias de caracteres e o asterisco inicial para a variável; estava ausente também o caractere número (#) final de parágrafo.
Fi gur a4. 12–Asva r i á ve i ss ã oe s t r i t a me nt el o c a i s
–40– Nenhum erro será detetado agora, porém o resultado obtido (Fig. 4.12) não é o esperado. O comando a s karmazena na variável *x o código de retorno, no caso “0”, porque foi pressionado o botão “Sim”. No entanto, o l s ms ga seguir lista * x0. Isto porque, devido à regra número 5 o conteúdo de uma variável não pode ser passado de um parágrafo a outro. Para funcionar, será necessário seqüenciar os dois último parágrafos em um só: a s k ( “Sa ma mb a i aéve t a l ?”, * x, 100, 2 00)& l s ms g( * x) # Os registros são entidades utilizadas para passagem de parâmetros e também em gramáticas, como será visto no Cap. 12. Sobre eles é importante realçar o seguinte: § Os r egi s t r ossão criados pelo comando ne wr e g( , , )onde é o nome do registro, o mé t o doe um pr o gr a mae xt e r no . Se não forem utilizados, os dois últimos valores poderão ser NULL(a s s i m me s mo ,e m ma i ús c ul a s ). § Os registros do tipo no me ( , NULL, NULL) , podem ser criados a partir do comando de atribuição a s s i gn( , <no me _r e gi s t r o >) . § Quando isso ocorrer, o valor da variável, conteúdo do registro, será denotado por [nome_registro] (entre c o l c he t e s ) e poderá se constituir em um literal ou fazer parte em sua composição. § O movimento inverso de valores entre um registro e uma variável, é feito pelo comando r e t r i e ve ( <no me _r e gi s t r o >, ) . Esta operação é necessária porque, como vimos acima, os parâmetros para os comandos podem ser somente constantes ou variáveis, nunca registros – com exceção dos quatro comandos que os tratam especificamente. § Para apagar o conteúdo dos registros existem dois comandos: c l r e g( <no me _r e gi s t r o >)e c l r e gs .O primeiro apaga o conteúdo, assinalando o valor NULL a um registro especificado. O segundo faz esta operação para todos os registros definidos.
4. 3–Pr ogr amasnoAmbi ent ei ns t al a do Outro recurso muito útil na programação é o item Pr o gr a ma sdo Ambiente instalado, que permite uma visualização clara dos programas – tanto do Sistema, pré-instalados como os ativos do usuário. Para tornar ativos os programas (e as gramáticas como vimos no cap. 6), seus arquivos devem ser abertos e colocados em execução. A edição pode ser feita como qualquer arquivo de texto, acionada a partir da linha de menu. A visualização pode ser efetuada de várias formas. Mostraremos aqui como utilizar o Amb i e nt ei ns t a l a do , ativando-se a alça correspondente. Clicando-se na alça inferior Pr o gr a ma s , obteremos a janela da Fig. 4.13 a seguir. Várias sub-alças podem aparecer, identificadas por um círculo à frente (verde para ativo e vermelho em caso contrário).
Fi gur a4. 13-Li s t a ge m do spr o gr a ma sa t i vo s A primeira, Si s t e ma , contém todas as primitivas do produto e pode servir também de fonte de consulta sobre a sintaxe dos comandos, na figura destacamos a do comando a s k :
–41–
Fi gur a4. 14–Pr o gr a ma sdoSi s t e ma( pr i mi t i vo s ) A us e r , são as genéricas para o usuário. Estas alças caracterizam os f r ames , categorias que podem ser criadas para melhor estruturar os programas de uma aplicação – que, em geral, são muitos – e facilitar a localização do programa desejado. Para tal a categoria necessita ser o primeiro parâmetro de de f pr gi n, como mostrado a seguir: % Pr ogr amaut i l i zadopar aexi bi rar qui vosdet ext o defprg-in(De_Exi bi ção,mostrarq(*x), assign(*x,arq) & evalsch(“learq [arq]”,*prg) & syscall(*prg,1,*y)&waitproc(*y,0,0,*sk))#
Repare na figura abaixo, o número que se segue ao dois pontos (:), no título dos programas é a a r i da deexigida pela sua definição. Agora, clicando-se no símbolo +que antecede alguns destes programas, o seu conteúdo será exibido, conforme a Fig. 4.15:
Fi gur a4. 15–Li s t a ge m deum pr o gr a maa t i vo O mesmo vale para os programas pré-instalados (pr e _i nt a l l ) conforme visto a seguir:
Fi gur a4. 16–De t a l ha me nt od eum pr o gr a mapr é i ns t a l a do
–42– 4. 4–Pr i mi t i vas As primitivas são programas já existentes, b ui l t i n, que podem ser utilizados na programação do Witty como comandos. Neste ponto, os recursos são muito amplos e variados, porque há centenas deles, oferecendo alto poder à linguagem. Por outro lado, esta imensa variedade chega a confundir o iniciante, que pode ignorar a sintaxe de comandos ou até mesmo desconher sua existência. Já foram apresentados atrás os recursos de apoio à programação, como o menu Aj uda , a opção Pr i mi t i va sPRG. . .do Me nuEdi t a re Pr o gr a ma s doSi s t e mano Amb i e nt ei ns t a l a do . Para uma primeira aproximação, nesta seção apenas identificamos as categorias em se enquadrem os comandos, o que os classifica por função. O detalhamento ocorrerá à medida que for necessário seu emprego em programas. Ar i t mét i c as Oferece um amplo leque para cálculos aritméticos. Aqui abordaremos apenas os inteiros, os únicos necessários. Inteiros são representados em 32 bits, usando c o mpl e me nt o de do i s . Cobrem o intervalo entre 2147483648 a +2147483647. Oper ador Si gni f i c ado
Exempl o
+
+(2,3,*x) +(2,*x,5) *(2,5,*x) *(*x,5,10) =(3,2) =(2,2) <>(3,2) <>(2,2) >(3,2) >(1,2) >=(3,2) >=(2,2) >=(1,2) <(1,2) <(3,2)
*x retorna 5 *x retorna 3 *x retorna 10 *x retorna 2 retorna falha retorna sucesso retorna sucesso retorna falha retorna sucesso retorna falha retorna sucesso retorna sucesso retorna falha retorna sucesso retorna falha
inc(*x,5) dec(*x,1)
incrementa x de 5 decrementa x de 5
*
Soma Soma (como subtração) Multiplicação Divisão
=
Igualdade
<>
Diferente
>
Maior que
>=
Maior que ou igual a
<
Menor que
<= inc dec
Menor que ou igual a Incremento Decremento
Cont r ol e São empregados para controlar a execução de programas, como c ut ,f a i l ,ho l de l o o p. Devido sua importância, serão discutidos na próxima seção. Há outros comandos além destes, entre os quais citamos e xe c pr g<no me _do _pr o gr a ma >, permitindo que, dentro de um programa, se ordene a execução de outro. Ar qui vos Necessárias para manipulação de arquivos, para o Witty quando em formato texto. (Aceita também arquivos gráficos no formato . bmp, porém neste caso, a única ação permitida é a exibição). Os comandos permitem a abertura, fechamento ou exclusão de arquivo. Esses arquivos são identificados internamente através de números inteiros. Gravam-se linhas nos arquivos, pelo emprego do comando wr i t e l i ne ( , ) . Gr amát i c a As gramáticas constituem-se em um dos mais poderosos recursos do Witty, por isso merecerão todo o Cap. 7, onde estes comandos serão discutidos. I nt er f ac e São aquelas utilizadas para se comunicar com o usuário. Já vimos algumas, de emprego imediato, como ms g, l s ms ge l f . No capítulo seguinte serão discutidas as que geram caixas de diálogo. Bas edeConhec i ment o Estes comandos dizem respeito a modificações introduzidas às bases de conhecimento. Já vimos no capítulo anterior os mais comuns, como a s s e r te ne wb a s e . Há dezenas de outras primitivas que poderão ser empregadas em condições específicas, como por exemplo q t yf a c t ( <no me _da _b a s e >, <* va r i á ve l >) , que retorna em * va r i á ve l , o número de fatos da base nomeada.
–43– Pr ogr amas Necessários para manter os programas em execução. Como um deles pode chamar outros, é necessário que todos os referenciados estejam na memória para a execução funcionar. Assim, poderemos apagar programas da memória, salvá-los, contá-los ou identificá-los. Já empregamos neste capítulo o de f pr g para a definição de programas e também é importante l o a dpr g( <no me _do _pr o gr a ma >)para carregá-lo na memória.
Es t r a t égi as São comandos que permitem modificar o funcionamento do Witty com respeito à maneira padrão. Exemplo típico são ge t d e pt h, e s e t de p t h, que verifica ou modifica, respectivamente, o nível de profundidade das deduções, como mostrado na seção seguinte. Nesta categoria se enquadram os comandos que permitem os oráculos – ao qual dedicamos todo o Cap. 6. Cadei aseRegi s t r ador es O Witty permite manipulação de cadeias de caracteres, como a concatenação (vista no capítulo seguinte) ou transformação (vista no final deste). Outras funções importantes com cadeias serão estudadas no capítulo seguinte. Os registros já apareceram neste capítulo porém seu detalhamento será no Cap. 12, pois seu uso está muito associado às gramáticas. Pr ovadeTeor emas Há vários comandos referentes a este assunto, sendo que o mais óbvio, pr o ve , já discutido no capítulo anterior. Na seção 4.6 à frente, mostraremos o uso do Ht e r m para recuperar informação da base de conhecimento.
4. 5–Cont r ol edePr ogr ama O controle de programas deste estilo de linguagem é algo difícil de ser compreendido por profissionais acostumado com rotinas procedimentais. Desta forma, ofereceremos neste ponto uma primeira abordagem, ainda que completa. Primeira por não esgotar o assunto, abordado em muitos dos exemplos dos próximos capítulos. A apresentação destes conceitos neste ponto será para lançar os fundamentos para a escrita de programas mais complexos. 4. 5. 1–Repet i ç ões :c omandol oop Controle de repetições, executa um laço de comandos até que uma condição de controle falhe. Não tem parâmetros sendo seu funcionamento mostrado a partir da seqüência de comandos: . . .& l oop& c omando1 & . . .& c omandon& c ondi ç ão& . . . quando o l o o pforça a execução do trecho entre c o ma ndo o ma ndo o ndi ç ã ose verifique. O exemplo 1e c naté que c da Fig. 4.17 ilustra o emprego desta primitiva.
Fi gur a4. 17–Empr e godoloop A primeira linha do programa atribui o valor 1 à variável *x. A segunda linha contém o trecho a ser repetido: a variável é listada, incrementada de 1 e comparada com o valor 4. Quando isso ocorrer, a execução sairá do laço, passando para a instrução seguinte. A última linha do programa é inútil; esta alternativa jamais será executada.
–44– 4. 5. 2–Sempr ef unc i ona:c omandohol d É um comando que não faz nada; porém é enganoso pensar que não tenha utilidade. Aparece em situações nas quais não pode haver vazios, por exemplo como linha final em arquivo de comando após um conjunto de comentários. Seu uso será explorado adiante. 4. 5. 3–Bac kt r aki ng:c omandoc ut Podemos controlar a execução de um programa pela ordenação das cláusulas e os objetivos dentro de cada cláusula. O mecanismo mais importante é o b a c k t r a c k i ng.Quando se efetua uma consulta e o objetivo não for satisfeito, lançamos mão deste recurso para tentar satisfazer a meta, buscando uma solução alternativa. Quando ocorrer conjunções em uma consulta, ele satisfaz na ordem em que foram escritos (da esquerda para direita). Ob a c k t r a c k i ngautomático é um conceito de programação útil porque desobriga o programador da responsabilidade de programá-lo de forma explícita. Por outro lado, a falta de controle pode causar ineficiência em um programa. Portanto, algumas vezes queremos controlar ou prevenir estes retornos compulsórios. Faremos isto usando a facilidade do c ut . Para demonstrar o efeito desta primitiva, vamos incluí-lo no loop do exemplo anterior. O resultado pode ser visto na Fig. 4.18:
Fi gur a4. 18–Empr e godocut A inclusão do c utna linha 2 cancela a função do l o o p, passando-se a execução para o comando seguinte. Sendo 2 o valor da variável * xneste ponto, o teste de igualdade falhará, desviando-se a execução para a alternativa que emite a mensagem na segunda linha do Visor. 4. 5. 4–Sempr ef a l ha:c oma ndof ai l Este é um comando sem argumentos que sempre falha, forçando retrocesso imediato em busca de uma resposta alternativa. No caso de um argumento não ser verdadeiro o programa usa o f a i lque sempre falha. A exemplo do ho l d, é mais importante que parece. Para demonstrar seu efeito, vamos utilizar a recuperação de dados de um banco de conhecimento. No capítulo anterior vimos que o comando pr o vedevolve apenas ve r da de i r oou f a l s o . Para nosso objetivo, será necessário utilizarmos em combinação com este, a primitiva Ht e r m (atenção: a inicial é maiúscula), com a seguinte sintaxe: Ht e r m( , <* var i áve l _da_pr ova>, * var i áve l _de _r e t or no>) onde: número é a instanciação da variável dentro da base *variável_da_prova é uma variável com mesmo nome da utilizada no prove *variável_de_retorno armazena o valor de retorno do banco de conhecimentos. Na Fig. 4.19, temos a base c a r i o c acom três fatos e uma regra. O programa utiliza variável no comando pr o ve , a mesma empregada em Ht e r m. O terceiro parâmetro desta primitiva é listado no Visor.
–45–
Fi gur a4. 19–Empr e godeHterm:r e c upe r a ç ã odeda do sdob a nc odec o nhe c i me nt o Apenas uma das possíveis alternativas foi recuperada: a última da lista de fatos. Isto se deve à estratégia implementada pelo Wi t t y, que utiliza a estrutura de pilhas. Caso quiséssemos retornar todas as possibilidades, precisaríamos forçar a falha na busca (mesmo com ela tendo sucesso!) para obrigar nova tentativa. Esta é a função do f a i l : Na Fig. 4.21 da página seguinte, o comando f a i lna terceira linha do programa força o retrocesso exibindo todas as possíveis alternativas da base de conhecimento. Quando estas se esgotarem, o pr o vefalhará sendo a execução desviada para o comando após o alternador (última linha do programa), emitindo a mensagem da quarta linha do visor. 4. 5. 5–Combi naç ãoc ut& f ai l Uma das mais poderosas – e difíceis – ferramentas de controle de programas. Usa-se quando uma porção do seu programa incluir alguma coisa que nunca deve ser verdadeira, então o c ut& f a i lpode eliminar a cláusula daquela porção do seu programa. O c utprevine que o programa tente provar novamente tal regra, perdendo tempo na busca de soluções alternativas. Para melhor compreensão do funcionamento destes comandos críticos, observe o programa esquematizado na Fig. 4.20 a seguir:
1
2
cut
3
4
fail
5
6
Fi gur a4. 20–Co mb i na ç ã oc ut& f a i l
Fi gur a4. 21–Co ma ndofail p a r ao b r i ga rno vape s q ui s a Ao encontrar o comando c ut , o conjunto de instruções entre os pontos 1e 2não será mais executado. O e nt r y po i ntdo programa será o comando que o sucede, representado pelo 3. A execução continua em seqüência até 4. Encontrado o f ai la seguir, a execução pára, forçando o b a c k t r a k i ngpara a posição 3. Um exemplo desta combinação está na Fig. 4.22 a seguir:
–46–
Fi gur a4. 22–Pr o gr a maus a ndoac o mb i na ç ã ocut & fail O programa i nve r t e vfestá definido em dois ramos na primeira parte do arquivo. Se a prova da linha 2 for bem sucedida, a combinação dos comandos c ut& f a i lserá executada, cortando a a possibilidade de passar para o outro ramo e devolvendo o valor f a l s o ; no caso contrário, esta combinação não será executada, desviando-se para o ramo da terceira linha, que retorna o valor ve r da de i r o . Este programa troca o retorno de verdadeiro para falso ou vice-versa. Na segunda parte, aplicamos o programa a uma tautologia (p( a )i mpl i e sp( a ) ) e o retorno é falso. 4. 5. 6–Ní veldepr of undi dade Um conceito muito importante para o controle de provas, o de ní ve ldepr o f undi da de , permanece subjacente e ímplicito. Para se entender com clareza, apresentamos a seguir uma representação gráfica da árvore de possibilidades que interliga as regras de uma base de conhecimento:
Fi gur a4. 23–Ní ve ldepr o f undi da de A pr o f undi da demá xi madede duç ã otem um valor pré-definido que pode ser modificado pelo comando s e t de pt h( ) , onde representa um número natural. Para se descobrir qual o valor corrente existe a primitiva ge t de pt h( * x) , que armazena na variável *x este valor. Este fato está demonstrado na Fig. 4.24, onde é exibido o valor padrão:
Fi gur a4. 24–Ve r i f i c a ç ã odoní ve lmá xi modepr o f undi da de Este número pode parecer muito pequeno, mas é suficiente para as demonstrações mais usuais e boa parte de conhecimento especializado. Se, por um lado, profundidade rasa acelera o processamento das inferências, pode eventualmente não encontrar a solução por esta se encontrar em nível mais profundo. Por isso, o estabelecimento do valor adequando para a profundidade, depende da estruturação das bases de conhecimento utilizadas e, a rigor, só pode ser convenientemente definido após várias experimentações. Há casos em que este controle se torna muito importante. Em certas circunstâncias, uma prova não deve ser feita de forma exaustiva, isto é, pode-se estar interessado em verificar se determinada cláusula é
–47– verdadeira sob certas restrições que podem estar direcionando o processo de prova. Convém ressaltar que tal controle é programável e dinâmico, podendo ser alterado a qualquer momento durante uma prova. Sistemas para processamento em tempo real ilustram situações típicas onde é necessário fazer provas sob severas restrições. Estreitamente ligada à noção de ní ve ldepr o f undi da deestá a noção de di s t â nc i ac o nc e i t ua l .A estruturação do conhecimento no ambiente W it ty é feita por uma hierarquia de pl a no sdec o nhe c i me nt o , de tal forma que um plano é básico (o inferior hierarquicamente) e os demais vão se superpondo de acordo com a cadeia de derivação entre os conceitos do conhecimento disponível. Assim, dados dois conceitos quaisquer do conhecimento disponível, é possível estabelecer uma distância entre eles, que pode ser desde z e r o(quando esteverem no mesmo plano) até o número máximo de planos existentes. Esta noção é fundamental para que se possa estabelecer os níveis de profundidade adequadamente durante uma prova.
4. 6–Seqüênc i adepr ogr ama A chave para a compreensão da programação em Wi t t yé entender o encadeamento da execução dos comandos dirigidos pelos s e q üe nc i a do r(&) e a l t e r na do r(|). Um programa em Witty funciona como uma árvore de decisões como mostrado na Fig. 4.25.
Fi gur a4. 25–Di a gr a ma sdee xe c uç ã odo sc o ma ndo s Na figura, acima e à direita, o diagrama exibe a condição ( a1& a2) , quando somente haverá sucesso se as duas forem verdadeiras: do primeiro nó (a1), se falhar, a condição já falhou e a segunda verificação nem será feita, desviando-se para baixo. Se encontrar sucesso, anda-se para direita para a segunda verificação, onde ocorrerá o mesmo. À esquerda, a condição é ( a1|a2) , que só falha se ambas falharem, saída para baixo a partir de (a2). Os dois outros diagramas são um pouco mais complexos. O inferior da esquerda combina as duas condições acima e o da direita demonstra a ação do comando c ut . Para demonstrar as implicações, vamos definir uma “base de conhecimento” com fatos estabelecidos à maneira de programação em lógica, como se fossem programas.
Fi gur a4. 26–De f i ni ç ã odef a t o sàl apr o gr a ma ç ã oe ml ó gi c a Na Fig. 4.26 acima, foram definidos os programas p(a), p(b) e p(c). Como somente interessam as instâncias do predicativo p, não há corpo do programa. No entanto, o comando de f pr gexige sua presença sob pena de erro de sintaxe. É o caso de se empregar o ho l d, preenchendo este vazio sem alterar a intenção original. Esta implementação está de acordo com a definição original do Prolog que, por muitos anos
–48– funcionou como paradigma de programação lógica, com a qual mantivemos compatibilidade. Este recurso será útil para as demonstrações que se seguem.
Fi gur a4. 27–Te s t edec o ndi ç õ e s A Fig. 4.27 é uma demonstração da seqüência da execução dos comandos. A expressão dentro do parêntese na primeira linha é avaliada, estabelecido que tanto p( a )como p( b )e p( c )são verdadeiros. Devido a condição desconhecida (p ( d) ), o teste falha, a instrução que segue ao & ignorada e desvia-se para a seguinte ao |, caindo-se em nova avaliação, agora uma disjunção. Há sucesso na primeira parte (p( b ) ) e falha na segunda, novamente devido ao p( d) . Porém, isto é suficiente para que haja sucesso, exibindo-se a listagem subseqüente no Visor. Dito de outra forma, quando uma condição for satisfeita, será procurado o primeiro comando que suceder a um s e q üe nc i a do r(&); caso contrário, desviar-se-á para o seguinte a um a l t e r na do r(|). A Fig. 4.28 a seguir, mostra graficamente esta afirmação.
Fi gur a4. 28–Se q üê nc i aede s vi o se nt r ec o ma ndo sdeum pr o gr a ma Esta estrutura também permite a recuperação de fatos em uma base de conhecimento, de forma semelhante ao visto (na Fig. 4.21). Na Fig. 4.29 abaixo usou-se o f a i lpara forçar a listagem todas as instâncias do predicado é _c a r i o c a . Caso não o utilizássemos, o retorno seria apenas a primeira instância (Zi c o ).
Fi gur a4. 29–Ex t r a ç ã odet o d a sa si ns t â nc i a sdaBa s ene s t ae s t r ut ur a Nas demonstrações seguintes, empregaremos um interessante comando, o t r a ns f , que permite efetuar casamentos de padrões poucos complicados de maneira simples e direta. No Cap. 12 veremos uma ferramenta que o suplanta – em poder e complexidade – as gramáticas. Sua sintaxe é a seguinte: onde:
t r ans f ( , <e s que ma1>, <e s que ma2>, { <* var >|} ) é a cadeia de caracteres que se deseja transformar; <esquema1> é o esquema de partida (entre aspas); <esquema2> é o esquema final desejado (entre aspas); <*var> | o resultado da transformação pode tanto ser armazenado em variável como em outro registro.
–49–
Fi gur a4. 30–O c o ma ndotransf O exemplo da Fig. 4.30 ilustra o emprego deste comando. Os dois registros necessários precisam ser definidos, uma vez que não há comando explícito de atribuição que os criariam. O comando t r a ns ffaz a comparação, caractere a caractere, da cadeia “todo gato é curioso” com “todo [um] é [dois]”. Ressalte-se que a notação [ um]indica conteúdo do registro um. Todos os caracteres situados entre “todo” e “é” (ga t o ) constituirão o valor do registro um. De forma idêntica, todo o restante da frase após o “é” (c ur i o s o ) o do registro do i s . Estes valores são substituidos no terceiro parâmetro do comando e o resultado final atribuido à variável * x, listada no Visor pela última linha do programa.
Fi gur a4. 31–Us odoc o ma nd otransf A Fig. 4.31 ilustra duas transformações sucessivas. Na primeira, o ponto de comparação é a primeira vírgula, transformada em “<-“, resultando como conteúdo do registro um o valor “a ”; e para do i s , “b,c”, conforme a primeira linha do Visor. Na segunda execução, a segunda vírgula é também transformada. Este tipo de transformação pode ser empregada para aproximar a representação dos fatos ao jeito programação em lógica, conforme a Fig. 4.32 a seguir. Neste caso sofisticaremos um pouco o programa, colocando um controle de varredura. A tranformação em si – “,” para “<-“ – é extremamente simples. Para tal, usaremos dois novos comandos: qt ypr g( <* npr gs >) onde <*nprgs> é uma variável a qual será atribuida a quantidade de programas ativos. ge t pr g( , <* var i áve l >) onde é um inteiro nque identifica o n-ésimo programa; <*variavel> variável que armazenará o n-ésimo programa.
4. 32–Pr o gr a maq uel i s t ao sf a t o sàma ne i r aPr o l o g No programa acima, a variável * npr gcontém o número total de programas e servirá de controle para ol o o p, que se encerrará quando * natingir este valor. Esta variável será incrementada de um em um, a partir do inicial um, permitindo que, a cada passada, o ge t pr g recupere um programa na variável * x. A transformação é feita desta para * z , cujas todas instâncias foram exibidas no Visor.
–50–
–51–
5. Cai xasdedi ál ogos O W it ty possui diversos recursos de interface através de caixas de diálogo, que agilizam a programação de rotinas de comunicação com o usuário e também simplificam a implantação de certo tipo de conhecimento. Além de a s ke i nput , introduzidos no capítulo anterior, há ainda os representados pelos comandos pr o mpt ,c ho o s ee a c q b o x. Pela importância destas primitivas, vamos destacá-las cada qual em uma seção deste capítulo, inclusive os já abordados, para facilitar o entendimento e eventuais consultas posteriores. A última seção trata de me nus , um recurso específico para tratamento de taxionomias.
5. 1–Cons ul t andoous uár i o:c omandoas k O comando a s kabre a seguinte janela de confirmação:
Fi gur a5. 1–J a ne l adec o nf i r ma ç ã odoc o ma ndoask através de quatro parâmetros com a seguinte sintaxe: as k( <me ns age m>, <* r e t or no>, <pos x>, <pos y>) onde:
<mensagem> <*retorno>
<pos-x> <pos-y>
é o texto da mensagem a ser exibida na caixa diálogos, sempre uma pergunta ao usuário; á a variável onde será armazenado o código de retorno, de acordo com o botão pressionado pelo usuário: 0 para Sim 1 para Não 2 para Ignoro; São as coordenadas na tela do vértice esquerdo superior da caixa de diálogos.
O uso deste recurso já foi demonstrado do capítulo anterior.
5. 2–Conver s a ndoc om us uár i o:c omandopr ompt A janela de diálogo aberta pelo prompt, oferece um campo para o usuário fornececer informações. Difere também do a s kpor permitir a atribuição de um título à janela. Seus parâmetros são: pr ompt ( , , * r e t or no, <pos x>, <pos y>) onde: é a cadeia de caracteres que constituirá o título da janela é o texto da cunsulta ao usuário *retorno é a variável que guardará os dados digitados pelo usuário <pos-x> são as coordenadas na tela do vértice superior esquerdo da <pos-y> caixa de diálogos
Figura 5.2 – Janela do pr o mpt
–52– 5. 3–For mul ár i os :c omandoi nput A construção de uma caixa de diálogo para formulário é feita através do comando i nput , com os seguintes parâmetros: i nput ( <e nt >, , op1/ op2/ . . . / opn, <* r e t or no>, <pos x>, <pos y>) onde: <ent> indica quantas entradas possui o campo; é a senteça que aparece no título da caixa de diálogo; títulos para campos de formulários (separadas por b a r r a ); <*retorno> é o valor da alternativa selecionada; <pos-x> são as coordenadas onde se posicionará, na tela, o canto superior <pos-y> esquerdo da caixa. Para exemplificar seu uso, considere o exemplo: input(5,"Cadastro de vendedores", "Nome/Endereço/Fone/Produto/Região",*x,125,100) & lsmsg(*x)#
Qua dr o5. 1–Ca i xa sdedi á l o g o s O programa acima resulta na caixa de entrada da Fig. 5.3, que armazena na variável *x os campos separados por barras (sem espaços entre eles), o que permite sua recuperação por um programa que trate estes dados. Note que no campo não preenchido a resposta foi substituída por um ponto de interrogação, conforme demonstrado na Fig. 5.4.
Fi gur a5. 3–Ca i xadee nt r a da
Fi gur a5. 4–Re t o r no A separação dos campos com a estrura acima não constitui problema, podendo facilmente ser efetuada com o emprego do comando ma t c h. Esse comando é mais poderoso que só isso, servindo para casar uma cadeia de caracteres com um esquema de acordo com um padrão, essencial na aplicação de gramáticas. O exemplo da Fig. 5.5 ilustra a utilização deste comando cuja sintaxe é a seguinte: mat c h( <e s que ma>)
–53–
Fi gur a5. 5–Us odoc o ma ndomatch Neste exemplo os registros precisaram ser definidos, uma vez que a atribuição de valor a eles deu-se pelo comando ma t c h. A representação [ r e gi s t r o ]indica o seu conteúdo. O comando varre da esquerda para a direita a cadeia de caracteres do primeiro parâmetro e a compara com o esquema do segundo parâmetro. Este processo denomina-se c a s a me nt odepa dr õ e se funciona da seguinte maneira:
Fi gur a5. 6–Co ma ndomatch:c a s a me nt odepa dr õ e s A coincidência entre os literais (no caso acima as palavras “o”) é crucial para o comando funcionar, caso contrário ele falha, não efetuando substituições. Isto porque fazem a função de uma “guia” para orientar a atribuição de valor aos registros envolvidos. Após a execução do comando, o conteúdo dos registros será: [suj] homem [pred] estuda [comp] livro ] Estes valores serão utilizados pelo comando seguinte e v al s c h, que avalia o esquema resultante (como o listado na Fig. 5.5), com a seguinte sintaxe: e val s c h( <e s que ma>, <* r e s ul t ado>) onde <esquema> é o esquema a ser avaliado e <*resultado> é a variável onde será colocado o resultado da avaliação.
Fi gur a5. 7-I nt e r f a c epa r ae s c r e ve rar e gr a O comando i nputgera a janela Es c r e vaar e gr a , com três campos: o primeiro para a numeração, o segundo para o antecedente o o último para o conseqüente da regra. Estes três campos serão armazenados na variável * x0separados por uma barra. O comando ma t c hos separa, colocando estes valores nos registros indicados. Finalmente o e va l s c h compõe as cadeias de caracteres com os conteúdos dos registros nas variáveis * x1, * x2e * x3 , listados no Visor, o primeiro na primeira linha e os dois restantes na segunda. Com uma pequana adaptação, poderemos ir mais longe, armazenando a regra em um banco de dados para acoplar este núcleo a comandos que alimentem um banco de conhecimento. Neste caso, ao invés de listar no visor, deverá ser utilizado o comando a s s e r t , que tem a sintaxe seguinte:
–54– as s e r t ( <nome _banc o>, |) <nome_banco> é o nome do banco de conhecimento e | é o fato ou regra escrito em lógica de primeira ordem. Desta forma, substituindo as duas últimas linhas do programa anterior, uma regra será introduzida no base chaos, conforme exibe a Fig. 5.8 a seguir. onde:
Fi gur a5. 8–Ent r a dader e gr a snab a s e Ampliando esta idéia para entrada de fatos também, chegamos ao programa a seguir: %--Entrada de fatos e regras com input newreg(esq,NULL,NULL)# newreg(dir,NULL,NULL)# newbase(entrada)# input(2,"Escreva a regra", "Causa (Fato)/Efeito",*t,125,100) & match(*t,[esq]/[dir])# retrieve(esq,*x) & retrieve(dir,*y) & =(*y,?) & % Tratamento de fato assert(entrada,*x) | evalsch("if [esq] then [dir]",*z) & % Tratamento de regra assert(entrada,*z)#
Qua dr o5. 2–Pr o gr a maEntraRegra2 Para o caso de fatos, deve-se deixar o segundo campo em branco. Neste caso, o comando ma t c ho representa por um ?(ponto de interrogação). Assim, o teste =( * y, ?)funcionará, executando-se o a s s e r tda linha seguinte. Senão, o teste falhará, este a s s e r tnão será executado, passando-se para a condição após o |, que é o tratamento da regra. Vale lembrar que este exemplo está aqui somente para tornar mais claro o uso do i nput , não sendo o mais adequado para esta serventia. Veremos tutoriais melhores, desenvolvidos com os recursos cumulativos de o r á c ul oe gr a má t i c a . Oi nputé indicado para entrada repetitiva de informações para povoar um banco de conhecimento.
5. 4–Aqui s i ç ãodec onhec i ment o:pr i mi t i vaac qbox Por ser bastante ampla, esta primitiva conta com treze parâmetros. Porém, como será visto nos exemplos a seguir, vale por todo um programa. Sua sintaxe é acqbox(,,<arquivo>,, <*analise_do_resumo>,<*tipo>,<*pergunta_mais_opções_de_resposta>, <*confiança_geral>,<*peso_geral>,,)
onde os quatro primeiros são cadeias de caracteres, os cinco seguintes variáveis reservadas para capturar a intervenção do usuário e as duas últimas são inteiros, conforme explicitado abaixo: Nome da primeira janela; Conteúdo da primeira janela; <arquivo> o nome de um arquivo, cujo conteúdo – texto ou imagem – ocupará a janela Documento (a intermediária); é o texto da janela Resumo (terceira) e o do objeto associado; <*analise_do_resumo> variável que armazena o texto alterado na própria janela, caso não se concorde com a informação prévia; <*tipo> variável que guarda um valor inteiro, definindo o botão selecionado: 1 para botão Co nf i r ma ; 2 para botão Ne ga ;
–55– 3 para botão Pe nde nt e 4 para botão . . . De s do b r a , opção De pe ndê nc i af a c t ua l 5 para botão . . . De s do b r a , opção De pe ndê nc i ac i r c uns t a nc i a l 8 para o botão Adi a 9 para o botão Co nt i nua 10para o botão Al t e r na t i va 11para o botão Exe c uç ã o 12para o botão Ab o r t a 13para o botão Co mpa r t i l ha <*pergunta_mais_opções_de_resposta> variável que mantém os textos da pergunta original e todas as respostas dadas pelo usuário, como uma única cadeia de caracteres, onde o caractere $(c i f r ã o ) separa pergunta das respostas; e / (b a r r a ) separa as respostas entre si. As respostas serão armazenadas na ordem inversa de entrada, mantendo sempre a mais recente primeiro. A forma como será feita, depende da escolha efetuada na janela Dependências: De pe ndê nc i a sf a c t ua i s : o texto das respostas, sem modificações; De pe ndê nc i a sc i r c uns t a nc i a i s : primitiva de s c _o f fcom quatro parâmetros: de s c _of f ( , <ar qui vo>, , ) onde: é o texto digitado pelo usuário no quadro Resumo, com substituição de alguns caracteres reservados, como: e s pa ç oe mb r a nc o trocado por s ub l i nha(_), pa r ê nt e s i s trocado por c ha ve s({ } ) e ví r gul a trocado por exclamação (! ); <arquivo> é o endereço completo (com subdiretórios) do arquivo relacionado em Documento; indica o valor selecionado na janela Co nf i a nç a ; mostra a escolha da janela Pe s o . variável que guarda os valores selecionados para confiança. De pe ndê nc i a sf a c t ua i s : observa a mesma estrutura da variável acima: De pe ndê nc i a sc i r c uns t a nc i a l : armazena apenas a confiança geral, dado que as demais estarão em parâmetros do desc_off. variável que contém os valores escolhidos para peso, com a mesma estrutura que . , são os valores, em pixels, da posição do vértice superior esquerdo da janela ac qbox. Nos exemplos a seguir, demonstraremos a utilização deste comando, armazenando os retornos em registros para permitir somente a sua visualização. É evidente que, uma vez estando disponíveis, estas respostas poderão sofrer outros tipos de tratamento mais sofisticado, inclusive serem armazenadas em bases de conhecimento. Vamos iniciar mostrando uma forma simplificada, onde são omitidos o arquivo de texto e o resumo, quando os terceiro e quarto parâmetros aparececem vazios – indicados por dois aspas seguidos (" " ). Por exemplo, o programa acqbox("Janela simplificada","Forma mais simples","","", *analise,*tipo,*resposta,*confianca,*peso,100,100)#
produz a seguinte interface:
Fi gur a5. 9–J a ne l as i mpl i f i c a da No entanto, caso aqueles dois parâmetros não estiverem vazios, surgirá a janela completa, como no exemplo seguinte.
–56–
Fi gur a5. 10–Pr i me i r aj a ne l adopr i mi t i vaacqbox e xi b i ndoa r q ui vodet e xt o( t x t ) A Fig. 5.10 exibe a janela principal evocada pelo comando. Esta janela possui três quadros e botões na parte inferior. O terceiro parâmetro indica um arquivo (witty.txt) cujo conteúdo foi espelhado no segundo quadro (Documento). Poderá ser também uma imagem, conforme mostrada na Fig. 5.11 (página seguinte). A cadeia do quarto parâmetro será o conteúdo do terceiro quadro (Resumo). Este quadro permite que nele se efetue correções no texto e, quando ocorrer, seu novo valor será guardado na variável *x1, a primeira, após os fatores de credibilidade. Analisaremos agora o uso dos botões da parte inferior. Conforme a escolha, haverá um seguimento diferente. O conjunto pemite várias ações: § Sim § Não § Desconhecido § Dependente O acionamento do botão Depende permite incluir dependências, factuais ou circunstanciais, ou acionar uma base de dados. Para tal, deve-se selecionar a opção desejada na caixa de diálogo que aparecerá, ilustrada pela Fig. 5.12 (pág. seguinte).
Fi gur a5. 11–J a ne l ado c ume nt odapr i mi t i vaacqbox e xi b i ndoa r q ui vodei ma ge m( b mp) Dependênc i asf ac t uai s . Nesta opção, será aberta a caixa de diálogos Dependências factuais que apresenta três quadros horizontais e quadro botões laterais. O primeiro quadro possui duas janelas de valores para Confiança geral e Peso geral, inicialmente indicados como 100 e 10 respectivamente. O segundo possui três janelas para entrada de dados: texto, confiança e peso. O primeiro botão, Inserir, transfere este conteúdo para a primeira linha da terceira janela, pautada para melhorar a visibilidade. Caso já haja linhas preenchidas, as novas inclusões ocorrerão abaixo, mantendo a ordem de entrada.
–57– Clicando-se em cima de uma linha e no botão Remover, seu conteúdo será apagado. Não há possibilidade de edição de linha; necessita-se removê-la para reescrita e nova inclusão. O botão Cancelar sai da opção e não registra nada. Finalmente, o botão Adquirir armazena todas as informações fornecidas, encerrando o comando. Dependênc i asc i r c uns t anc i ai s . A seleção da segunda opção da caixa de diálogos Dependências, abre a caixa de Dependências circunstanciais que possui três quadros diversos botões. O botão com ponto de interrogação ( ? ) ,abre uma janela de busca de documento onde se navega até encontrar o arquivo desejado. Escolhido, seu nome e caminho aparecerão na janela do último quadro. O primeiro quadro é para confiança e peso gerais atribuidos às informações. O segundo registra o arquivo selecionado, que será exibido no terceiro quadro. Sua confiança e peso podem ser corrigidos. Os botões Incluir e Remover são referentes a este arquivo selecionado. Abaixo, o botão Cancelar permite abandonar a operação e Adquirir a registra, ambos encerrando o comando. Bas edec onhec i ment o. Abre uma base de conhecimento que será utilizada para comandos que venham em seguida.
Fi gur a5. 12–Asde pe nd ê nc i a s 5. 5–Menus : oc omandoc hoos e Os menus são recursos muito úteis que são criados em caixas de diálogos a partir do comando choose que apresenta cinco parâmetros semelhantes ao input: c hoos e ( , , <* r e t or no>, , ) onde: é a senteça que aparece no título da caixa de diálogo; são as alternativas possíveis do menu (separadas por b a r r a ); <*retorno> é o valor da alternativa selecionada; são as coordenadas onde se posicionará, na tela, o canto superior esquerdo da caixa.
–58– O uso do comando está exemplificado na Fig. 5.13 a seguir:
Fi gur a5. 13–Exe mpl odous odechoose pa r ac r i a rme nu Como se nota, são possíveis respostas múltiplas, além de simples ou mesmo ausente. O valor da variável de retorno depende não somente das alternativas selecionadas como também do botão pressionado a seguir. A tabela da página seguinte resume as possibilidades: Al t er nat i va Uma opção Mais de uma opção Nenhuma opção
Bot ão Confirma Confirma Confirma Nenhum Cancel / Esc
Val orderet orno A opção Opções separadas por bar r as NONE NONE ?
Este comando permite estruturar o conhecimento do tipo classificatório, sem utilizar regras ou bases de conhecimentos. Para exemplificar, considere a seguinte apreciação estruturada sobre pei xesmar i nhos :
Fi gur a5. 14–Co nhe c i me nt os o b r epe i xe sma r i nho s Este saber e outros do tipo taxionomia pode ser implementado na forma de menus com bastante facilidade, através do programa do Quadro 5.3:
–59– % % %
Programa de menus Conhecimentos sobre peixes marinhos sem uso de bases
defprg(menu1, choose("Local de coleta", "Mar/Rio",*x,25,20) & assign(*x,ret) & =(*x,Mar) & menu2 & cut)# defprg(menu1,retrieve(ret,*x) & =(*x,Rio) & lsmsg("Não há informações sobre peixes de água doce") & lf & cut & fail)# defprg(menu2, choose("Tipo de mar","Alto/Litoral",*x,50,40) & assign(*x,ret) & =(*x,Alto) & menu31 & cut)# defprg(menu2,retrieve(ret,*x) & =(*x,Litoral) & menu32 & cut)# defprg(menu31, choose("Forma básica", "Fusiforme/Achatada_ventral/ Achatada_lateral/Nenhuma",*x,75,60) & assign(*x,ret) & =(*x,Fusiforme) & menu41 & cut)# defprg(menu31,retrieve(ret,*x) & =(*x,Achatada_ventral) & lsmsg(">>> A espécie é: MANTA BIROSTRIS") & lf & cut & fail)# defprg(menu31,retrieve(ret,*x) & =(*x,Achatada_lateral) & lsmsg(">>> A espécie é: MOLA MOLA") & lf & cut & fail)# defprg(menu31,retrieve(ret,*x) & =(*x,Nenhuma) & lsmsg("Não há informações para concluir") & lf & cut & fail)# defprg(menu32, choose("Forma geral", "Achatada/Não_achatada",*x,100,80) & assign(*x,ret) & =(*x,Achatada) & menu33)# defprg(menu32,retrieve(ret,*x) & =(*x,Não_achatada) & lsmsg(">>> A espécie é: OUTROS") & lf & cut & fail)# defprg(menu33, choose("Tipo de cauda", "Longa/Curta",*x,125,100) & assign(*x,ret) & =(*x,Longa) & lsmsg(">>> A espécie é: RAJA RAJA") & lf & cut & fail)#
defprg(menu33,retrieve(ret,*x) & =(*x,Curta) & lsmsg(">>> A espécie é: LINGUADO DO MAR") & lf & cut & fail)# defprg(menu41, choose("Tamanho do peixe", "Grande/Médio/Pequeno",*x,125,100) & assign(*x,ret) & =(*x,Grande) & menu51 & cut)# defprg(menu41,retrieve(ret,*x) & =(*x,Médio) & menu52 & cut)# defprg(menu41,retrieve(ret,*x) & =(*x,Pequeno) & lsmsg(">>> A espécie é: SARDINHA SARDINHA") & lf & cut & fail)# defprg(menu51, choose("Comprimento das nadadeiras", "Longo/Curto",*x,150,120) & assign(*x,ret) & =(*x,Longo) & lsmsg(">>> A espécie é: THYNNUS ALBACORA") & lf & cut & fail)# defprg(menu51,retrieve(ret,*x) & =(*x,Curto) & lsmsg(">>> A espécie é: THYNNUS THYNNUS") & lf & cut & fail)# defprg(menu52, choose("Padrão de coloração", "Rajado/Uniforme",*x,150,120) & assign(*x,ret) & =(*x,Rajado) & lsmsg(">>> A espécie é: CAVALA CAVALA") & lf & cut & fail)# defprg(menu52,retrieve(ret,*x) & =(*x,Uniforme) & menu62)# defprg(menu62, choose("Cor aparente", "Cinza/Dourado/Prateado",*x,175,140) & assign(*x,ret) & =(*x,Cinza) & lsmsg(">>> A espécie é: TAINHA TAINHA") & lf & cut & fail)# defprg(menu62,retrieve(ret,*x) & =(*x,Dourado) & lsmsg(">>> A espécie é: DOURADO SALGADO") & lf & cut & fail)# defprg(menu31,retrieve(ret,*x) & =(*x,Prateado) & lsmsg(">>> A espécie é: AGULHA MARÍTIMA") & lf & cut & fail)# choose("Conhecimentos sobre peixes marinhos. Prosseguir?", "Sim/Não",*x,0,0) & =(*x,Sim) & menu1 & cut#
Quadr o5. 3–Pr ogr amademe nuss obr epe i xe smar i nhos Um dos possíveis resultados de sua execução está na Fig. 5.15 da página seguinte:
–60–
Fi gur a5. 15–Re s ul t a dodae xe c uç ã odeme nuspa r ac o nhe c i me nt oc l a s s i f i c a t ó r i o
–61–
6. Or ác ul os 6. 1–Def i ni ç õeseConc ei t os Na Grécia antiga, o oráculo era presidido e inspirado por um deus, auxiliado por sacerdotes ou adivinhos que agiam como intermediários e intérpretes. O deus podia responder através de uma pítia ou de um a sibila, que ficava recolhida num local sagrado. Na ausência destas, podiam-se interpretar ruídos sistemáticas, como o murmúrio de uma fonte ou do vento nas árvores. Geralmente os oráculos visavam a apaziaguar os homens e evitar violência. Eram procurados tanto nos empreendimentos de paz como nas guerras e, sobretudo, nas fundações das cidades, exercendo, um papel político significativo. Expressavam-se por frases vagas e indeterminadas, passíveis de várias interpretações. Existiram oráculos no Egito e em Roma, porém os santuários mais famosos estavam na Grécia; o mais antigo é o de Zeus, em Dodona. Entre os oráculos de Apolo (os mais numerosos) destacavam-se o de Delfos, no monte Parnaso, e o da ilha de Delos. Embora não tivessem grandes oráculos nacionais, os romanos veneravam a gruta e o bosque de Albúnea, a Sibila de Cumas e os livros sibilinos, o oráculo de Fauno e da Fortuna, em Prenesta. Gr andeEnci cl opédi aLar ousseCul t ur al ,p.4225,v.18( ed.1998)
Já vimos a utilização do comando prove para ter acesso ao mecanismo de inferência do ambiente Wi tt y. Nos exemplos, trabalhamos com uma única base. No entanto, para maior flexibilidade na organização de conhecimento, o programa permite a utilização de múltiplas bases, através de prove-in(sup, b1, ... , bn, ) onde a primeira das bases deve ser necessariamente a de suporte. A seqüência das demais não é relevante a não ser como caminho de pesquisa, que parte da base chaos, passa pela de suporte e segue na ordem de apresentação das bases de conhecimento, terminando novamente na chaos. Trata-se de uma ligação circular. Com isso é possível verificar se é derivável do conhecimento disponível nas bases ativas no momento da execução do comando. Caso afirmativo, o comando prove retorna sucesso; caso contrário, falha. No exemplo seguinte, o conhecimento na base é insuficiente para a dedução solicitada; logo o retorno é negativo:
Fi gur a6. 1-Ba s edec o nhe c i me nt oc o m da do si ns uf i c i e nt e s Situações como esta podem ser comuns, uma dedução falhar por ausência de conhecimento suficiente. Imaginando que se está interagindo com o próprio especialista, seria razoável perguntar a ele a informação que falta, como forma de aprendizado. O mecanismo que permite esta ação é o or ác ul o. Do ponto de vista sistêmico, um oráculo nada mais é do que algum tipo de sistema capaz de fornecer informações a respeito de uma parte do mundo real sobre a qual ele tem conhecimento de modo a auxiliar ou orientar o consultante a resolver algum problema cuja solução seja dependente deste conhecimento (Carvalho, 1991). A idéia básica de oráculo neste trabalho é considerada como a intervenção de um sistema dedutivo com outros sistemas, isto é, um especialista, bases de dados ou bases de conhecimento ou pela execução de um programa interno ou externo. Um oráculo pode ser utilizado quando se esgotarem todos os caminhos possíveis para uma dedução em um sistema dedutivo, objetivando obter informações necessárias que estejam faltando. Mas também é possível utilizá-lo antes de estarem esgotados todos estes caminhos, em função de alguma estratégia adotada que seja mais adequada a melhorar a eficiência e dar mais flexibilidade a um sistema baseado em conhecimento. O conceito de oráculos, com o uso aqui pretendido, é apresentado em (Oliveira, 1995), como um redirecionador de busca por uma prova sempre que um provador de teoremas atinge um caminho sem sucesso, de modo a obter uma direção alternativa. Conforme ressaltado no trabalho citado, isto não é o mesmo que b a c k t r a c k i ng. Um oráculo procurará resolver um problema fora da situação corrente utilizando
–62– informação extra. Um oráculo associado a um provador de teoremas, cria um ambiente qualitativamente diferente, com características de mundoa b e r t o . A idéia de oráculos é profundamente explorada em (Valério, 1995). Nesse caso, ele se destina ao acompanhamento de uma prova por dedução. O oráculo pode ser ativado pela máquina de inferência toda vez que faltar um literal (conhecimento da base) necessário ao prosseguimento do processo de prova. Numa situação de falha o oráculo será ativado para capturar conhecimento externo. Um oráculo pode ser visto como um procedimento qualquer capaz de buscar em uma base de dados ou de tentar obter (perguntando) um valor para um literal necessário durante uma dedução. Em termos de aquisição de conhecimento esta capacidade é muito útil, pois a cada conceito ou construto obtido durante o processo de aquisição de conhecimento é possível verificar se falta – através de um processo de dedução – algum outro conceito a ele subordinado. Se este for o caso, pode ser acionado um oráculo para obter este conceito. Uma opção interessante é utilizar um oráculo como gerenciador de perguntas, desde a construção da pergunta até a determinação do momento adequado de fazê-la, bem como evitando repetição de perguntas. Oráculos representam uma alternativa para que um sistema com base em conhecimento não fique limitado ao conhecimento nele disponível, passando a equivaler a um Si s t e ma e m Mundo Ab e r t o . A construção destes sistemas pode estar baseada tanto nesta hipótese como na do MundoFe c ha do . Neste último caso, mais comum, é relativamente mais simples (Fig. 6.2). Entretanto, este é um fator que impõe severas limitações em relação a como tais sistemas lidam com o conhecimento necessário a resolver problemas do mundo real, pois basicamente, neste hipótese, o conhecimento que não está disponível ao sistema, é suposto como não verdadeiro. Deve ser ressaltado que o conhecimento necessário, embora não presente no sistema, poderá aparecer em outras fontes.
Fi gur a6. 2-Or á c ul onã oa t i va do :de duç ã os o bahi pó t e s edemundof e c ha do Por outro lado, quando se admite a hi pó t e s edomund oa b e r t o(Fig. 6.3), deve-se procurar obter, de alguma forma, o conhecimento necessário e não disponível. A forma natural encontrada para conseguir essa informação, é fazer com que o sistema consulte alguma fonte sobre o assunto até que as informações obtidas sejam suficientes para a conclusão do objetivo pretendido ou até esgotar a capacidade do sistema em procurar por uma resposta.
Fi gur a6. 3–Or á c ul oa t i va do : de duç ã os o bahi pó t e s edemundoa b e r t o A hipótese do mundo fechado, embora bastante limitativa, vem sendo a mais utilizada, pois são grandes as dificuldades em lidar com conhecimento em mundo aberto. A partir do uso de oráculos é possível minimizar estes problemas, viabilizando adotar a forma mais flexível e poderosa do mundo aberto. Será esta a opção deste trabalho.
–63– 6. 2-Us odeOr ác ul osnoWi t t y A passagem de parâmetros no Witty é efetuada através de um mecanismo denominado r egi s t r o, uma vez que as variáveis são estritamente locais. Os registros serão detalhado no próximo capítulo e tiveram uma breve abordagem anteriormente, suficiente para seu emprego neste tópico. Mostramos também que os registros podem ser visualizados dentro do Amb i e nt ei ns t a l a do , uma vez que são alterados e utilizados por programas e gramáticas. Já vimos no Cap. 4 (pág. 44) que tais registros são necessários devido a existência de c a r a c t e r e sr e s e r va do sque não podem ser usados diretamente. Seus valores são os seguintes: [acent] ' (a pó s t r o f o ); [number] # (núme r o ); e [quote] "(a s pa s ). Um or ác ul o no ambiente Wit ty, é uma primitiva que se destina a permitir acompanhar uma dedução, de modo a identificar a cada passo, o que está faltando para seu prosseguimento. Quando ocorrer uma falha, através do oráculo será possível identificar os literais ausentes (em dí vi da ). Este recurso é adequado à construção de sistemas baseados em conhecimento sob a hipótese de mundoa b e r t o , onde será possível ampliar o conhecimento disponível à medida da necessidade. O programa oráculo pode ser escrito no próprio Wi tt y, como qualquer outro programa, exceto que são previamente definidos tanto os seus argumentos, em número de três, quanto as suas respectivas funções. A codificação de um programa que cria um oráculo, parte da identificação, como por exemplo, or ac ul o1. Neste caso, seria: defprg(oraculo1(*x,*y,*z), )# onde *x, *y e *z são argumentos, cujas funções são armazenar: *x: o sinal (pos ou neg) do literal que está na cabeça da lista de dívidas; *y: o próprio literal que está na cabeça da lista de dívidas; *z: o restante da lista de dívidas; e é um ou mais comandos, incluindo ou não referências a outros programas. O código escrito em deverá ser ativado para que haja a sua execução, através da primitiva s e t o r a c l e ( ) . Em sentido inverso, a primitiva r s t o r a c l e ( ) , o desativa. Utilizando o exemplo a seguir, poderemos construir este programa como se segue: %----- ORACULO1 -um oráculo simples defprg(oraculo1(pos,*y,*z),assign(*y,lit) & evalsch(“Você sabe se [lit]?”,*perg) & ask(*perg,*ret,100,100) & =(*ret,0) & cut | cut & fail)# setoracle(oraculo1)#
Qua dr o6. 1–Um o r á c ul os i mpl e s A base desta solução está no comando a s kvisto no capítulo anterior e cujo código de retorno está na tabela a seguir: Com ando Respost adousuár i o SIM (afirmativa) NÃO (negativa) IGNORO
ask Códi goder et or no 0 1 2
O exemplo considerado trata unicamente a resposta SIM, em que o retorno é 0,quando é possível concluir a dedução com êxito. O 'ou' (|) após o primeiro cut é uma derivação para resposta diferente (são possíveis: não ou ignoro) ambas tratadas igualmente, ocasionando falha. Os demais comandos utilizados são discutidos a seguir: e va l s c h( “Vo c ês a b es e[ l i t ] ?”, * pe r g) . Monta uma pergunta, concatenando o literal informado com o predicado contido em lit, armazenada na variável *perg. Não é possível colocar esta expressão diretamente como o primeiro parâmetro da primitiva ask, porque neste caso, [lit] será considerado uma cadeia de caracteres, não sendo traduzido. a s k ( * pe r g, * r e t , 100, 10 0) . Abre uma caixa de diálogo, com vértice superior esquerdo na posição 100,100 obtendo a resposta na variável *ret. =( * r e t , 0) . Avalia a resposta. Aqui interessa verificar se a resposta foi SIM, pois é necessário o literal contido em *y com sinal positivo, isto é, afirmado.
–64– c ut . Caso a resposta tenha sido afirmativa, este comando interromperá a execução do oráculo retornando sucesso, de tal maneira que o mecanismo de inferência possa concluir a dedução com sucesso; caso a resposta tenha sido diferente, a execução do programa associado ao oráculo orac1 passará automaticamente para os comandos após o |(OU), onde o fail retorna falha para mecanismo de inferência concluir a dedução com falha. Com este oráculo ativado, a execução do prove da Fig. 6.1 (pág. 81), provocará a exibição da caixa de diálogo da Fig. 6.4 (página seguinte). Caso a resposta seja afirmativa, o mecanismo de inferência terá condições de responder positivamente ao prove. Se retornar NÃO a dedução falhará novamente, sendo aberta caixa de diálogo semelhante, inquirindo Vo c ês a b es eé _r a c i o na l ( Ze z i nho ) ?
Fi gur a6. 4–Ca i xadedi á l o goa c i o na dape l oo r á c ul o Esta característica de devolver a pergunta, indica indistinção pelo mecanismo de inferência, entre predicados observáveis (em geral do lado esquerdo das regras) e não observáveis (em suas conclusões). Pode ser evitada com a adição de um simples comando para indicar tal separação. Por valor de f a ul t , todos os predicados necessários para a dedução são perguntáveis, incluindo-se a própria meta. Há duas primitivas que proíbem ao oráculo perguntar sobre algum predicado ou liberam-no novamente para perguntas. São, pela ordem: o r a c o f f ( <pr e di c a do >)e o r a c o n( <pr e di c a do >) . Desta forma, pela adição de o r a c o f f ( r a c i o na l ) # como última linha do Quadro 6.1, a segunda pergunta jamais ocorrerá. Este oráculo, no entanto, está incompleto porque não está tratando literais negativos (com sinal neg) que ocorrem quando precedidos pelo NOT. Embora não seja corriqueiro em outras linguagens do mercado, o fato negativo é permitido no Wi tt y, aumentando significativamente seu poder de representação. Como exemplo, podemos citar a consideração com respeito aos latino-americanos: To dol a t i no a me r i c a noq uenã os e j ab r a s i l e i r o ,f a l ae s pa nho l . Sel a t i no ( * x)enã ob r a s i l e i r o ( * x)e nt ã of a l a _e s pa nho l ( * x) . Com isso, poderemos montar a seguinte consulta:
Fi gur a6. 5–Ba s es o b r el a t i no a me r i c a no s Se mantivermos o mesmo or ac ul o1ativado, o retorno será uma janela perguntando a própria meta. Para permitir a consulta de fatos negativos, será preciso ampliar o oráculo prevendo questões para ambos sinais, conforme feito no Quadro 6.2.
–65– %----- ORACULO2 - oráculo permitindo fatos negativos % Parte positiva resp: si m defprg(oraculo2(pos,*y,*z), assign(*y,lit) & evalsch(“Você sabe se [lit]?”,*perg) & ask(*perg,*ret,100,100) & =(*ret,0) & assign(*ret,ret) & oracoff(*y) & cut)# % Parte positiva resp: diferente de si m defprg(oraculo2(pos,*y,*z), retrieve(ret,*ret) & <>(*ret,0) & oracoff(*y) & cut & fail)# % Parte negativa resp: si m defprg(oraculo2(neg,*y,*z), assign(*y,lit) & evalsch(“Você sabe se não [lit] ?”,*perg) & ask(*perg,*ret,100,100) & assign(*ret,ret) & =(*ret,0) & oracoff(*y) & cut)# % Parte negativa resp: diferente de si m defprg(oraculo2(neg,*y,*z), retrieve(ret,*ret) & <>(*ret,0) & oracoff(*y) & cut & fail)# setoracle(oraculo2)# oracoff(fala_espanhol)# l i nhadecomando: prove(sup,fala_espanhol(Juan)) & lsmsg(SIM) | lsmsg(Não)
Qua dr o6. 2–Or á c ul oq uet r a t af a t o sne ga t i vo s As novidades são o uso da primitiva <> (sinais combinados de me no rq uee de ma i o rq ue , significando di f er ent e), verificando se o retorno não foi zero, além do uso do comando or ac of f ( * y)para evitar que se repita a pergunta para o mesmo predicado em cada parte. Este assinalamento é permanente. Caso deseje efetuar vários testes, é necessário retornar à situação anterior com o comando o r a c o n( <pr e di c a do >) . Neste caso, a execução do programa leva à caixa de diálogo a seguir
Fi gur a6. 6–Ca i xadedi á l o gob a s el a t i no cuja confirmação retornará a resposta SIM; qualquer outra resposta levará a Não De maneira semelhante, as consultas fala_espanhol(Pedro) ou fala_espanhol(Bill) retornam negativo, porque para eles há informação suficiente na base, contradizendo uma das cláusulas necessárias para se falar espanhol. No oráculo utilizado acima, o sistema não incorpora as respostas dadas pelo usuário, ou seja, caso fosse repetido o questionamento o sistema repetiria as mesmas perguntas. Denominados a este tipo de ferramenta, o r á c ul os e ma pr e ndi z a do(Fig. 6.8) utilizado nas situações que se quer verificar as hipóteses da prova, sem aprender os fatos. Isto é muito bom para se desenvolver o raciocínio utilizado durante a dedução.
–66–
Fi gur a6. 8–Es q ue madeum o r á c ul os e ma pr e ndi z a do Esta definição de oráculo funciona para ajudar a resolver uma dedução, contudo é ineficiente para o objetivo de aqui s i ç ãodec onhe c i me nt o, uma vez que as respostas obtidas não são registradas. Assim, caso aquele fato seja mais uma vez necessário, será perguntado novamente. Desta forma, para construção de um oráculo que se preste a registrar novas fórmulas válidas é necessário fazer uma distinção entre as respostas NÃO e IGNORO. No primeiro caso pode ser armazenada a negação da pergunta. No último, a informação está ausente e nada pode ser afirmado a seu respeito.
Fi gur a6. 9–Es q ue madeum o r á c ul oc o ma pr e ndi z a do Além destes acréscimos, será necessário utilizar uma nova base, a que chamaremos anexa, para registro dos dados aprendidos. O processo de prova, então, necessitará incluir esta base para não repetir perguntas, daí o uso de prove-in. O oráculo e a prova encontram-se no Quadro 6.3 a seguir. A base utilizada será a mesma espanhol do exemplo anterior. %----- ORACULO3 -Or ácul oqueapr ende newbase(anexa)# % base para guardar dados aprendidos % Parte positiva resp: sim (retorno 0) defprg(oraculo3(pos,*y,*z), assign(*y,lit) & evalsch(“Você sabe se [lit]?”,*perg) & ask(*perg,*ret,100,100) & =(*ret,0) & assign(*ret,ret) & assert(anexa,*y) & oracoff(*y) & cut)# % Parte positiva resp: não (retorno 1) defprg(oraculo3(pos,*y,*z), assign(*y,lit) & retrive(ret,*ret) & =(*ret,1) & assign(*ret,ret) & retrive(lit,*y) & assert(anexa,not *y) & oracoff(*y) & cut)# % Parte positiva resp: ignoro (ret 2) defprg(oraculo3(pos,*y,*z), retrieve(ret,*ret) & =(*ret,2) & oracoff(*y) & cut & fail)#
%
Parte negativa resp: sim
defprg(oraculo3(neg,*y,*z), assign(*y,lit) & evalsch(“Você sabe se não [lit] ?”,*perg) & ask(*perg,*ret,100,100) & assign(*ret,ret) & =(*ret,0) & assert(anexa,not *y) & oracoff(*y) & cut)# % Parte negativa resp: não defprg(oraculo3(neg,*y,*z), retrieve(ret,*ret) & =(*ret,1) & retrive(lit,*y) & assert(anexa,*y) & oracoff(*y) & cut & fail)# % Parte positiva resp: ignoro defprg(oraculo3(pos,*y,*z), retrieve(ret,*ret) & =(*ret,2) & oracoff(*y) & cut & fail)# setoracle(oraculo3)# oracoff(fala_espanhol)#
l i nhadecomando: prove-in(sup,anexa,espanhol,fala_espanhol(Juan)) & lsmsg(SIM) | lsmsg(Não)
Qua dr o6. 3–Or á c ul oq uea pr e nde
–67– Caso se responda SIM à pergunta do oráculo, o resultado desta prova será afirmativo e, caso provado novamente não fará mais a pergunta, com idêntica resposta, uma vez que a anexa conterá a informação no t b r a s i l e i r o ( J ua n) . Novas consultas poderão apresentar respostas inesperadas, devido à inibição do predicado ‘brasileiro’ através de o r a c o f f ( * y) , evitando a repetição da pergunta. Para executar novos testes, execute na janela de comandos o r a c o n( b r a s i l e i r o ) . O comportamento do oráculo anterior pode ser chamado de categórico, pois apenas processa respostas “sim” ou “não”. Com uma adaptação, será possível tratar a resposta “ignoro”. O ponto básico consiste em guardar tais respostas, com o objetivo de evitar que o sistema repita as perguntas correspondentes, no pressuposto que, se o especialista não sabia afirmar ou negar o literal necessário à uma dedução na primeira vez em que a pergunta foi feita, nada indica que ele saberá esta resposta em uma segunda oportunidade. Então, diante desta resposta, a dedução falhará e continuará falhando daí por diante. Será necessária a criação de uma nova base de conhecimento para receber as informações sobre as quais o especialista não foi categórico em suas respostas, além de um programa capaz de verificar o que existe nesta base e acrescentar um novo ramo ao oráculo para que se possa tratar a resposta “ignoro”. Basta apenas um ramo, pois, diante desta resposta, não é importante o sinal do literal necessário à conclusão da consulta. Sob o ponto de vista deste novo comportamento, se for afirmado ou negado não vai interferir, pois a dedução falhará em qualquer caso. Este oráculo pode ser chamado de per s i s t ent e, dada a forma com a resposta “ignoro” está sendo tratada. Assim, será colocado nesta nova base sem sinal, com o significado pretendido de apenas registrar que nada se pode afirmar sobre este literal. Considerando a base de dados da Fig. 6.5, o novo programa será o do quadro a seguir. %----- ORACULO4 -Or ácul oper si st ent e % Base para ignoro newbase(ignoro)# % Base para categóricas newbase(anexa)# % Positivo - sim defprg(oraculo4(pos,*y,*z), assign(*y,lit) & evalsch(“Você sabe se [lit]?”,*perg) & ask(*perg,*ret,100,100) & assign(*ret,ret) & =(*ret,0) & assert(anexa,*y) & oracoff(*y) & cut)# % Positivo - não defprg(oraculo4(pos,*y,*z), retrieve(ret,*ret) & =(*ret,1) & assert(anexa,not *y) & oracoff(*y) & cut & fail)#
% Negativo - sim defprg(oraculo4(neg,*y,*z), assign(*y,lit) & evalsch(“Você sabe se não [lit]?”,*perg) & ask(*perg,*ret,100,100) & assign(*ret,ret) & =(*ret,0) & assert(anexa,not *y) & oracoff(*y) & cut)# % Negativo - não defprg(oraculo4(neg,*y,*z),retrieve(ret,*ret) & =(*ret,1) & assert(anexa,*y) & oracoff(*y) & cut & fail)# % Sem sinal - ignoro defprg(oraculo4(*x,*y,*z),retrieve(ret,*ret) & =(*ret,2) & assert(ignoro,*y) & oracoff(*y) & cut & fail)# setoracle(oraculo4)# oracoff(fala_espanhol)#
l i nhadecomando: prove-in(sup,anexa,espanhol,fala_espanhol(Juan)) & lsmsg(SIM) | lsmsg(Não) ]
Qua dr o6. 4–Or á c ul ope r s i s t e nt e No programa anterior, a base ignoro não foi utilizada. Está prevista para armazenar as respostas ignoro, sobre as quais não há informações. Para evitar que a pergunta seja repetida, é necessário criar um programa que consulte esta base sobre o literal em questão e force falha quando ele existir. O programa j á di s s eabaixo, tem esta função. defprg(já-disse(*x),prove-in(sup,anexa,ignoro,*x) & cut & fail)# defprg(já-disse(*x),cut)#
Qua dr o6. 5–Pr o gr a mae vi t ar e pe t i ç ã odepe r gunt a s Assim, para completar o programa é necessário acrescentar “& já-disse(*y)” antes de cada um dos dois “evalsch”, logo após o “defprg”. Com isso, caso o literal já exista na base ignoro, fato que indica a pergunta já haver sido feita anteriormente, o programa forçará falha e a questão não será emitida.
–68–
–69–
7. Gr amát i c as Um esquema é um tipo cadeia de caracteres contendo um ou mais registros. Assim, todo registro é também um esquema. Abaixo, uma lista de exemplos de esquemas: Esquem as Vál i dos [quem] faz [o_que] [um] ama [quem] ama [um] [um]
Invál i dos ola] [cidade] é capital de [país
Os esquemas definem um padrão de formato de cadeia de caracteres. Uma cadeia estará dentro do padrão definido quando for possível igualar o esquema à cadeia de caracteres a partir da substituição dos registros por cadeias de caracteres quaisquer. Na tabela abaixo: Cadei a José faz mesas
Esquema [quem] faz [o_que]
a cadeia de caracteres obedece o padrão definido pelo esquema uma vez que podemos igualar as duas cadeias por meio da substituição do registro “[quem]” por “José” e do registro “[o_que]” por “mesas”. Um esquema composto por apenas um registro define o padrão que contém todas as cadeias de caracteres. Os esquemas podem ser usados por procedimentos para o reconhecimento de padrões e captura de subcadeias. Por exemplo, o procedimento match(,<esquema>) retorna com sucesso se pertencer ao padrão definido por <esquema>. Além disso, como efeito colateral, as subcadeias da que casarem com os registros serão capturadas por estes, e esta associação pode ser consultada posteriormente. No exemplo, match(“Picasso pintou Guernica”,[quem] pintou [o_que]) retorna com sucesso e os registros [quem] e [o_que] capturam as subcadeias “Picasso” e “Guernica” respectivamente, de acordo com:
Fi g.7. 1–Ba t i me nt odee s q ue ma Para se recuperar as cadeias de caracteres capturadas pelos registros deve-se usar o procedimento r e t r i e ve ( , ) . Na Fig. 7.2 (pág. seguinte), mostramos os procedimentos e seu resultado em Visor.
Fi g.7. 2–Exe mpl odous odee s q ue ma s
7. 1–Dec l ar aç ãodeRegi s t r os Os registros que ocorrem em um esquema devem ser declarados antes que possam ser usado em um procedimento. Como vimos na seção 9.3 (pág. 171), a declaração dos registros é realizada através do comando newr eg( , <mét odo>, <pr ogr ama>) onde
–70– <método>
denota o nome do registro que será criado, sendo o único obrigatório; permite limitar cadeias que podem ser capturadas pelos registros e pode ser: 1. uma expressão regular, precedida pelo caractere !(exclamação); 2. arquivos, precedido pelo caractere @(arroba); 3. uma gramática (vista à frente); 4. ausente, quando se deve especificar a palavra reservada NULL. <programa> denota um esquema de programa do ambiente hospedeiro, uma cadeia de caracteres contendo registros que, ao se substituir, uniformemente, os registros pelos seus conteúdos, resulte em um programa do ambiente hospedeiro. Quando isso ocorrer, o programa será executado. Se esta execução for bem sucedida, a atribuição da cadeia ao registro será mantida; caso contrário, o casamento será anulado. O programa será gerado dinamicamente, em tempo de execução das gramáticas. O resultado depende do conteúdo dos registros que ocorrem no esquema de programa. Pode ser: 1. o corpo de um programa; 2. o nome de um programa (interno ou externo); 3. um esquema; 4. ausente, quando se deve especificar a palavra reservada NULL. A seguir, exemplificaremos o emprego de cada uma destas possibilidades. O procedimento ne wr e g( r e g01, NULL, NULL)é a declaração mais simples do registro r eg01que, a partir de então, poderá ser usado em comandos. Neste caso, estão ausentes tanto o método quanto o procedimento e o conteúdo do registro poderá ser utilizado por primitivas como mat c h e eval s c h, por exemplo. O comando as s i gncria um registro deste tipo.
7. 2–Us odeexpr es s õesr egul ar esnomét odo As expressões regulares são úteis para expressar compactamente as cadeias que obedeçam um padrão simples. As expressões regulares são precedidas pelo caractere “! '' (po nt odee xc l a ma ç ã o ), para serem diferenciadas de outras opções possíveis para o mé t o do . Os metacaracteres utilizados para expressar uma linguagem regular estão reunidos na lista a seguir: Expr essão
Cadei ar esul t ant e
ba* (a|e|i|o|u)* {[az]}*
Iniciada com “b”, seguido de zero ou mais “a”s Qualquer seqüência que só possua vogais, incluindo a cadeia vazia Contém um número finito de caracteres entre a e z, incluindo a cadeia vazia Todos os números naturais
{09}{09}*
Por exemplo, o comando abaixo cria um registro que captura apenas as cadeias iniciadas por letras maiúsculas seguidas ou não de mais letras minúsculas: newreg(um,”!{AZ}{az}*”,NULL) No exemplo da Fig. 7.3, a definição do reg01 estabelece que ele somente poderá conter números:
Fi g.7. 3–Us odee xpr e s s õ e sr e gul a r e s
7. 3–Us odear qui vosnomét odo O comando newreg permite um nível de tradução adicional. No formato newreg(,”@arq1.txt,arq2.txt”,NULL) associa-se o atributo do registro ao conteúdo de um arquivo. Se a palavra foi encontrada no arquivo arq1.txt, é atribuído ao registro o valor correspondente no arquivo arq2.txt. Sendo assim, é possível fazer traduções usando o comando ‘newreg’ (com dois arquivos; um contendo cadeia original, e outro com as cadeias correspondentes reescritas). Este recurso é extremamente poderoso. Algumas aplicações possíveis seriam
–71– traduzir de um idioma para outro, converter abreviações para sua expressão por extenso, ou a passagem de um código para seu significado, só para citar alguns exemplos. Na Fig. 7.4 este fato está demonstrado para uma substituição de um número natural pelo seu valor por extenso (o numeral 5pela cadeia “c i nc o”):
Fi g.7. 4–Tr a duç ã oa t r a vé sdoc o ma ndone wr e g Os exemplos a seguir ilustram a utilização de registros.
Fi g.7. 5–Re gi s t r onã out i l i z a ndomé t o do Acima, o registro verbo aplica o programa q(*x) que só retorna sucesso caso o verbo seja 'amo' ou 'odeio'. O comando match utiliza verbo diferente ('adoro') o que faz retornar falha. Estes registros não empregam o segundo parâmetro (médodo).
Fi g.7. 6–Re gi s t r oq uede f i nee s q ue maa s s o c i a doapr o gr a ma Como o anterior, a aplicação deste registro apenas executa o programa pdefinido na segunda linha. Notem que o batimento do match não é efetuado porque a avaliação do programa a precede, por isso o valor do registro um não é substituido. O retorno no Visor depende do botão escolhido pelo usuário.
Fi g.7. 7–Re gi s t r oc o m mé t o doep r o g r a ma
–72– Neste caso, a prova do programa sempre falha, pois se trata de uma contradição. Então, a despeito do casamento do match funcionar, o resultado será falha. Pois, para haver sucesso, é preciso que ambos – c a s a me nt oe pr o gr a ma – funcionem. Substituindo-se o “not q(a)” da prova por “q(a)”, resultaria uma tautologia que, como tal, sempre retorna sucesso e a resposta seria afirmativa. Porém, se substituirmos a cadeia do match por qualquer outra diferente de “abc”, o resultado do casamento também falharia. Note que a expressão da prova deve vir entre aspas, devido a presença de caractreres especiais em sua representação, como vírgula e parêntesis. A senda aberta por este exemplo pode ser muito enriquecida quando a prova consultar uma base de conhecimento para tomar a decisão.
7. 4–Si s t emasdePr os t A rigor, a definição de gramática depende da conceituação de sistema formal. Um sistema formal F é uma tupla < Σ, L, A, R > em que: § Σ é um alfabeto; § L é um conjunto recursivo em Σ, chamado l i ngua ge m do sistema formal; § A é um subconjunto recursivo de L, chamado de a xi o ma s ; § R é um conjunto recursivo de relações em L. Existem três tipos básicos de sistemas formais: geradores, reconhecedores e transdutores. Os primeiros produzem cadeias de caracteres somente a partir dos axiomas; os reconhecedores admitem outras cadeias de entrada verificando se elas são adequadas, sem produzir cadeias de saída. Finalmente, os transdudores transformam cadeias de entrada em cadeias de saída. Um s i s t e madepr o duç ã odePr o s tS é um sistema formal < Σ, L, A, R > onde § Σ é um alfabeto composto pela união de dois subconjuntos disjuntos N e T, chamados respectivamente, de alfabeto terminal e não terminal e {[i] | i > 0} ⊆ N; § L é um conjunto de Σ*; § A é um subconjunto de Σ*, chamado de conjunto de palavras de partida; § R é um conjunto de relações binárias em L, que são chamadas de regras de produção; cada regra é da forma x0[i1]x1[i2]...xn-1[in]xn → y0[j1]y1[j2]...yn-1[jn]yn onde: i1,i2,...,in ∈ N j1,j2,...,jn ∈ { i1,i2,...,in } x0,x1,...,xn, y0,y1,...,yn ∈ (Σ - N)* As regras de inferência de um sistema de produção de Post podem ser bastante complexas. As operações básicas são de concatenação, casamento de padrões e substituição. Tais operações não fazem parte do sistema formal sendo de difícil execução, mesmo para operadores bem treinados. A complexidade da linguagem L é um fator preponderante tanto para uso do casamento de padrões como para constução de regras de inferência. O exemplo abaixo mostra a características tradutora de tal sistema. n Exe mpl o7. 1 : Seja o sistema de produção de Post no qual Σ = { , ∆, suc, S, , , 1, 2 } N = {S, suc, ,} A = {sucx | x ∈ (Σ - N)*} R={ 1. suc1 → S1, 2. S, 1 → 1 3. S1 ,2 → 1∆2 4. S1∆,2 → S1, 2 } Podemos interpretar esse sistema de produção de Post como gerando, a partir de um axioma sucz, em que z é a representação diádica de um natural no alfabeto { , ∆}, a representação z+1. n Uma gramática G é um sistema formal < Σ, L, A, R > onde: § Σ é um alfabeto consistindo de dois subconjuntos disjuntos N e T, chamados respectivamente, de alfabeto terminal e não terminal; § L é um conjunto de Σ*; § A é um subconjunto unitário {S}, sendo S∈ N, o símbolo de partida; § R é um conjunto de relações binárias em L, que são chamadas de regras de produção; Uma gramática pode ser considerada como um sistema de produção de Prost, cujas regras de produção da forma α → β são representadas como [1] α [2] → [1] β [2]. n Exe mpl o7. 2 : Seja a gramática G com N = {S}, T = {a,b,c} e as regras R = { S→ aSa, S→ bSb, S→ c}
–73– Então pode-se derivar, por exemplo, a seguinte seqüência: L(G) = { c, aca, aacaa, bcb, bacab, bbcbb, ... } onde o primeiro elemento obtém-se pela aplicação da terceira regra; o segundo a partir da primeira e terceira, de forma sucessiva; o terceiro pelas segunda e terceira e assim por diante. Notem que a terceira regra não permite nova derivação, por isso o elemento “c” será sempre único e central, cercados de “a”s e “b”s simétricos gerados pelas outras duas regras. n
7. 5–Gr amát i c as As gramáticas são utilizadas para reconhecer padrões mais complexos do que as linguagens regulares, podendo ainda traduzir a cadeia reconhecida em uma outra cadeia que seguir um formato diferente. Basicamente, as gramáticas são seqüências de r e gr a sdet r a duç ã o . Uma regra de tradução é uma tripla <esquema1,esquema2,esquema3> onde o e s q ue ma 1é utilizado para casar com a cadeia objetivo corrente. O e s q ue ma 3é um programa que será executado, caso o casamento com o esquema1 seja bem sucedido, em alguns casos afetando a tradução. Finalmente, o e s q ue ma 2será avaliado, caso os passos anteriores sejam bem sucedidos, gerando uma nova cadeia de retorno. Se ocorrer alguma falha (no casamento ou no programa), então o procedimento falhará também. De modo a facilitar a referência, chamaremos o e s q ue ma 2de e s q ue madet r a duç ã o . O esquema3 é opcional. Enfatizando, um arquivo que contenha uma gramática é um conjunto de diversas seqüências de três parágrafos, cada um significando um esquema: Gr amát i ca
Esquema
[suj] [verbo] [comp]# [verbo]([suj],[comp])# programa (externo ou do Witty)#
esquema1 esquema2 esquema3
O terceiro, uma chamada para execução de um programa (externo ou defindo em termos de linguagem de programação do Witty) é opcional. Caso não ocorra, a linha deve existir vazia, somente com o caractere “#” ( núme r o ) . A figura a seguir resume o funcionamento das gramáticas no Witty:
Fi g.7. 8–Func i o na me nt odagr a má t i c a Devido à sua grande importância e complexidade, as gramáticas também poder ser visualizadas de forma mais estruturada no Amb i e nt ei ns t a l a do , separando seus diversos componentes, conforme exibido a seguir.
Fi g.7. 9–Exi b i ç ã oda sgr a má t i c a sa t i va snoAmb i e nt ei ns t a l a do
–74– Uma gramática é composta por uma ou mais regras de tradução como visto acima. O caractere '#' sinaliza o fim do esquema. As gramáticas são armazenadas em arquivo de texto, podendo ser criadas por meio de qualquer editor. Antes de sua utilização no ambiente Witty elas devem possuir um nome lógico que será associado à gramática em tempo de carga, como no exemplo abaixo: newgram(gram) & loadgram(gram,arq.grm) O procedimento newgr am cria o nome lógico gram e o procedimento l oadgr am associa-o à gramática carregada do arquivo “arq.grm”. Após a carga, a gramática pode ser utilizada para reconhecer ou traduzir cadeias através do comando: appgram(,,) onde: cadeia de entrada que será traduzida; nome lógico da gramática que será usada; e variável que receberá o resultado da tradução. Já vimos a associação de e xpr e s s õ e sr e gul a r e sa registros, de forma a limitar as cadeias a ser capturadas por eles. De maneira análoga, podemos associar gramáticas a registros, pois elas também podem estabelecer limitações. O comando newr egpermite este tipo de associação, bastando para isso passar o nome lógico da gramática no segundo parâmetro do procedimento. Exemplo: newgram(gram) & loadgram(gram,arq.grm) & newreg(reg01,gram,NULL) As gramáticas são ainda mais poderosas que a expressões regulares. Conseguem especificar características para cadeias a ser capturadas pelos registros impossíveis de ser manifestadas por aquelas. Além disso, as gramáticas realizam traduções sobre as cadeias capturadas e o resultado dessas traduções também permanece associado aos registros.
Fi g.7. 10–Se nt e nç at r a duz i dapa r aaf o r mal ó gi c a A Fig. 7.10 acima mostra uma tradução simples, de português para lógica. A gramática witty1 associa à sentença “bem-te-vi é um pássaro”, uma forma em lógica predicativa desta sentença, que é “é_um(bem-tevi,pássaro)”, recurso muito útil para aquisição automática de conhecimento. O conjunto de exemplos a seguir procura explorar as possibilidades discutidas atrás.
Fi g.7. 11–Umagr a má t i c aq ues óa t i vaopr o gr a ma( s e mt r a duç ã o )
–75– No exemplo da Fig. 7.11 (pág. anterior) a gramática paciencia.grm não altera a entrada mas ativa o jogo Paciência (s ol . exe)do Windows através do comando s ys c al l , conforme pode ser visto na janela Ambiente instalado. Este comando tem a forma syscall(<programa>,,) onde: <programa> é o nome de um processo com os parâmetros necessários para chamada a execução, sem interromper o processamento do Witty; : 0 indicará que a janela da aplicação deverá permanecer fechada e 1quando a janela do processo deve ser ativada e mostrada no seu tamanho e posição correntes; é o identificador do processo criado. A seguir, o programa constante.prg cria o registo reg e associa o conteúdo do arquivo citado à gramática cosntante, carregando-a. Mantivemos a mesma denominação para evitar confusão, procedimento que repetiremos nos exemplos posteriores; contudo este cuidado não é necessário. Esta gramática é utilizada pelo programa witty3 que atribui o valor “qualquer coisa” à cadeia de entrada e lista no Visor a cadeia de saída. Na execução real, a janela do jogo Paciência – ativada antes de se efetuar o passo de tradução – se sobrepôs ao Visor que permenceu encoberto. Para melhor compreensão, reduzimos o tamanho da janela do jogo e o deslocamos para cima.
Fi g.7. 12–Umagr a má t i c aq uea t i vapr i mi t i vadoWi t t y A gramática constante.grm (Ambiente instalado) não altera o registro de entrada reg. No entando, o programa faz o assinalamento do valor “Uma sentença constante” para o mesmo registro. Pela exibição do registro de saída no Visor fica claro que o programa associado à regra media o casamento e a reescrita, pois o valor inicial do registro era “qualquer coisa” e foi alterado pelo programa.
Fi g.7. 13–Umagr a má t i c ac o mt r a duç ã o
–76– A gramática translation não ativa nenhum programa, contudo implementa tradução. Seu arquivo, mostrado no Ambiente instalado da Fig. 7.13, está repetido abaixo para melhor compreensão:
Fi g.7. 14–Ar q ui vodagr a má t i c ac o mt r a duç ã o A sentença de entrada, expressa em traduz.prg é “o rapaz ama a garota”. Desta forma não há casamento com o padrão estabelecido pelo primeira regra, que previa apenas três palavras. O batimento é efetuado pelo caractere branco deixado entre os registros com os espaços em branco na sentença original. O batimento ocorrerá com a segunda regra, resultando na seguinte atribuição de valores para os registros: [artigo] o
[sujeito] rapaz
[verbo] ama
[artigo1] a
[predicado] garota
A condição de reescrita mantém todos os registros na mesma ordem, porém com o parâmetro t , indicando que deverá haver tradução. Vamos acompanhar as ocorrências para esclarecer o mecanismo. Encontrando a condição [artigo,t] na formação da cadeia de saída, o Witty busca a definição do registro (em translation.prg) newreg(artigo,”@artigo.txt,article.txt”,NULL) que o instrui a procurar o valor original no primero dos arquivos indicados e substituí-lo pelo correspondente no segundo. Como “o” está na primeira linha de artigo.txt, será substuido pela palavra da primeira linha de article.txt, que é “t he”. A mesma substuição será efetuada nos demais registros: “rapaz” (terceira linha de sujeito.txt) se converterá em “boy” (terceira linha do arquivo associado agent.txt pela definição do registro sujeito); “ama” (primeira linha de verbos.txt) em “loves” (primeira linha de verbs.txt); “a” em “the” (segunda linha de artigo.txt e article.txt) e “garota” em “girl” (quarta linha de sujeito.txt e agent.txt).
Fi g.7. 15–Pe s q ui s adepa l a vr a s c ha ve A gramática pesquisa implementa uma forma de associar palavras-chave a arquivos de texto que as elucidem. O casamento é efetuado entre a sentença de entrada e três registros [inicio], [chave] e [final]. A definição dos primeiro e último não impõe nenhuma restrição ao seu conteúdo, porém para o restante, o estabelecimento de newreg(reg,”@chave.ctg,arqu.ctg”,NULL) somente permite ao registro valores existente no arquivo chave.ctg. (Um parêntesis: a extensão pode ser qualquer permitida pelo Windows, mas o arquivo deverá ser texto ASC, cada linha encerrada pelo caractere “#”); estamos utilizando esta para indicar a idéia de c a t e go r i a s ). Assim, ao processar a sentença de entrada O aperfeiçoamento da i nt el i gênci aaumenta a importância da tecnologia na formação de capital humano
será colocado no registrador [chave] a primeira palavra do texto que estiver no arquivo citado, ali grafado em negrito. Desta forma, será atribuído a [inicio] a parte da frase até a palavra chave selecionada e a [final] o restante até o final.
–77–
Fi g.7. 16Co nt e údodo sr e gi s t r o sa pó sc a s a me nt odepa dr õ e s A execução da gramática ativará o programa comandado por syscall(“notepad[reg,t]”,1,*x) que abrirá no Bloco de Notas o arquivo cujo nome será estabelecido por [reg,t], isto é o valor traduzido do conteúdo original do registro (inteligência) pela correspondente linha do arquivo arqu.ctg, resultando inte.txt.
Fi g.7. 17–Ar q ui vo sdea s s o c i a ç ã o A Fig. 7.18 a seguir, resume a execução da gramática descrita que busca uma palavra chave em um texto e, em seguida exibe um texto sobre tal assunto:
Fi g.7. 18–Gr a má t i c aa pl i c a d aab us c adepa l a vr ac ha vee ms e nt e nç a A gramática ensina.grm é semelhante e pode ser explorada para instrução a partir da identificação de palavras chave em um texto. Como acima, parte da identificação de uma palavra chave num texto, modificada para o corresponde valor em arqu.ctg.
Fi g.7. 19–Gr a má t i c ae ns i na
–78– O casamento de padrões é idêntico e também não há reescrita. Somente que ativa um programa escrito na linguagem do Witty definido como segue:
Fi g.7. 20–Pr o gr a maq uemo nt ano mer a ndô mi c o O programa mostra.prg que é chamado, monta um nome aleatório de arquivo, acrescentando ao registro traduzido por arqu.ctg um número randômico de 1 a 10.
Fi g.7. 21 –Apl i c a ç ã odagr a má t i c aae s t et e xt o Ao trabalhar o texto de entrada, a palavra “tecnologia” é reconhecida como da lista de palavras-chave (arquivo chave.ctg), sendo daí traduzida para “tecn” (ver. Fig. 7.15). O programa mostra adiciona um número, originando aleatoriamente do nome tecn1 a tecn10, exibindo o arquivo correspondente. Estes arquivos (com extensão .txt) devem ser pré-existentes. Desta forma, a cada vez que for encontrada uma palavra da lista, um arquivo com informações sobre o assunto será aberto ao acaso. Caso a mesma palavra seja repetida, o conteúdo exibido, com boa probabilidade, será diferente. Desta forma, será possível um diálogo de aprendizado, onde o interesse é determinado pela palavra-chave e as informações sobre o assunto serão fornecidas aos poucos. A Fig. 7.22 abaixo, simula a execução desta gramática para as variáveis acima e arquivos da Fig. 7.18. O resultado assume que o valor aleatório escolhido tenha sido 7.
Fi g.7. 22–Exi b i ç ã odet e xt oa l e a t ó r i os o b r ea s s unt ode t e t a dopo rpa l a vr a c ha ve
–79–
8. Comuni c aç ão O Witty oferece dois mecanismos que permitem a passagem de parâmetros entre processos independentes. Em deles é possível se comunicar com outros equipamentos desde que pertençam à mesma rede. Como se trata do TCP-IP, oferece adicionalmente o recurso de acessar à rede mundial Internet. A outra alternativa é passagem de cadeias de caracteres através da área de transferência do Windows, válidas apenas para um mesmo equipamento que utilize este sistema operacional. Para ilustrar estes processos, precisaremos introduzir o conceito de s e r vi do r . De forma simplificada, servidor é qualquer equipamento que resolva uma requisição de um outro, denominado c l i e nt e , devolvendo a este o resultado de uma consulta.
8. 1–TCP/ I P 8. 1. 1–Funç ãos er vi dor Há uma opção s e r vi do rdo Witty, ativada através do menu Fe r r a me nt a s , que permite a comunicação com qualquer outro processo sendo executado na rede, que tenha capacidade TCP-IP. Desta forma, ela pode atender solicitações que envolvam deduções sobre suas bases de conhecimento, potencializadas pela utilização de filtros, oráculos ou casamento de padrões. O pressuposto é a criação de um sistema híbrido, sob controle do usuário, sem ser privado do poder dedutivo fornecido pelo programa. Outra possibilidade aberta é o emprego de uma rede de servidores Witty (e outros, como de bancos de dados, por exemplo) se comunicando, cada qual instalado em um equipamento especializado, com tarefas bem determinadas. Desta forma haveria distribuição de inteligência pela rede. Para que o servidor funcione, será necessário ter o TCP-IP instalado no computador onde a versão será executada. Se este não for o caso, será preciso configurar o item Re deno Pa i ne ldeCo nt r o l e , selecionando a opção TCP/ I P>Ada pt a do rDi a l Up. Para demonstrar tal versão, vamos utilizar uma conexão cliente-servidor, ambos Witty, ressaltando que o cliente poderia ser qualquer outro programa do usuário. O comando que permite a comunicação está a seguir: TCP-IP(,<porta>,”“,) onde: é o nome de rede onde reside o servidor; caso esteja rodando isoladamente (sem nome de rede), pode ser utilizado o nome l o c a l ho s t . <porta> é um número entre 5000 e 9000 determinando a porta de comunicação. O par c o mput a do r po r t aé univocamente identificado. é qualquer comando válido para o Witty, devendo estar delimitados no início e no final com aspas (“), o que impede que este caractere faça parte do comando. onde o servidor colocará um valor de acordo com o resultado da solicitação efetuada. O protocolo de comunicação está sumarizado nas duas tabelas a seguir: M ensagem Nº 0 7 8 9
Descr i çãodocomando Mostre o conteúdo de uma base Mostre mensagem assincrona Mostre caixa de diálogo Mostre mensagem de erro
Si nt axe tamanho da tamanho da tamanho da tamanho da
Tipos de
cadeia,0,”conteúdo da base”, 0|1 (0 ativa; 1 desativa) cadeia,7,”mensagem” cadeia,8, ID do tipo de diálogo (vert abel aabai xo) cadeia,9,”mensagem de erro”
diálogos síncronos
Nº Comando Si nt axe 0 msg 0,”cadeia da mensagem”, posx,posy 1 ask 1,”cadeia da mensagem”,”pergunta”,posx,posy 2 3
prompt input
4 5
choose acqbox
6
sendsync
2,”titulo do diálogo”,”pergunta”,posx,posy 3,”pergunta”,”opções separadas por /”, “numero de boxes para texto”,posx,posy 4, pergunta”,”opções separadas por /”, posx,posy 5,”cadeia da pergunta”,posx,poxy 6,”cadeia de comando”
Ret or no — tamanho da cadeia, 0 = sim, 1 = não, ou 2 = desconheço. tamanho da cadeia, “cadeia de resposta” tamanho da cadeia, “resp. separadas por /”, (respostas em branco retornam ?) tamanho da cadeia,“resp. separadas por /” tamanho da cadeia, 1|2|3|4, “respostas separadas por /”,valor de confiança inteiro 0 se conseguiu executar 1 em caso contrário
–80– A Fig. 8.1 a seguir, ilustra a ativação da função servidor no Witty:
Fi gur a8. 1–O Se r vi do rWi t t y 8. 1. 2–Ár eadet r ans f er ênc i a A passagem de cadeias via área de transferência pode se dar entre dois quaisquer processos Windows, enventualmente entre duas instâncias do programa Witty. Através dela, pode-se contornar limitações existentes com o envio do comando diretamente. As primitivas que permitem esta troca de parâmetros são os seguintes: get-cl(*x) transfere o conteúdo da área de transferência para a variável put-cl(“cadeia”) coloca “cadeia” na área de transferência clear-cl apaga o conteúdo da área de transferência.
8. 2–Li gaç ãoc l i ent es er vi dorWi t t y Nesta seção explicaremos a construção de uma interface (programa cliente) para o WittyAcadêmico, na linguagem Vi s ua lBa s i c(versão 11.0), de forma simplificada com algumas caixas de diálogos. A interface é mostrada na Fig. 8.2 abaixo;
Fi g.8. 2–I nt e r f a c edec o muni c a ç ã opa dr ã oe s c r i t ae m VB Esta interface oferece um primeiro módulo que contém uma J a ne l adec o ma ndoas e re nvi a daa os e r vi do r e o botão Exe c ut ac o ma ndo . Na janela deve ser digitado o comando e, quando completado, deve-se pressionar o botão para acioná-lo. Trata-se da rotina mais crítica da aplicação, uma vez que estabelece a comunicação. A estratégia de implementação escolhida prevê, para cada comando enviado, a abertura da conexão, a execução do comando, exibição dos retornos e o fechamento. O segundo módulo, possui um botão e uma janela. Quando pressionado este botão, ativa-se o programa Witty Acadêmico, de sua localização padrão, através do comando Visual Basic: Shell "C:\Arquivo de programas\Witty\WittyAcademico\WittyAcademico.exe 5000", 1 onde o primeiro parâmetro é o caminho e o segundo indicação de janela normal. Inicia com os valores declarados para o servidor – l o c a l ho s te porta 5 000 , ambos podendo ser alterados conforme a necessidade. Para que tudo funcione é preciso que a máquina tenha um TCP-IP ativo. O programa VB trata os objetos (formulários, extensão f r m) mostrados na figura a seguir:
–81–
Fi g.8. 3–El e me nt o sgr á f i c o sdopr o j e t oCl i e nt ePa dr ã o A Fig. 8.3 exibe o formulário f r mCl i e nt . Os demais formulário aparecem a na Fig. 8.4 a seguir e serão demonstrados no correr deste texto.
Fi g.8. 4–Fo r mul á r i o s , frmdisplay, frmMsg, frmask eaqsregra Pressionando-se o símbolo do Witty indicado em 8.2 ele já será ativado no estado servidor. Porém, caso seja necessário fazê-lo, o processo será:
Fi g.8. 5–Es t a doSe r vi do rdoWi t t ynapo r t apa dr ã o50 00 O programa principal controla as caixas de diálogo permitidas através do parâmetros ID do protocolo de comunicação número 8 (Mostre caixa de diálogo), conforme as tabelas da página seguinte:
–82– M en sag en s
no 0
Descr i çãodocomando Mostre o conteúdo de uma base de conhecimento 1-6 desativadas 7 Mostre mensagem assincronamente 8 Mostre caixa de diálogo 9 Mostre mensagem de erro
Si nt axe tamanho da cadeia,0,"cadeia do conteúdo da base",0|1 (ativa|desativa) tamanho da cadeia,7,"cadeia da mensagem" tamanho do cadeia,8,ID do tipo de dialogo (tabela abaixo) tamanho do cadeia,9,"cadeia mensagem de erro"
T ip o s d e D iá lo g o s – to d o s sín cro n o s no 0 1 2 3
4 5
6
Comando Si nt axe msg 0,"cadeia da mensagem",pos x,pos y ask 1,"cadeia da mensagem",pos x,pos y pr ompt 2,"titulo dialogo","cadeia pergunta",posx,posy i nput 3,"cadeia da pergunta","cadeias das opções separadas por /",numero de caixas de textos,pos x,pos y choose 4,"cadeia da pergunta","cadeias das opções separadas por /" ,pos x,pos y acqbox 5,"cadeia da pergunta",pos x,pos y
sendsync 6,”cadeia de comando”
Ret or no sem retorno tamanho cadeia, 0 = "Sim" | 1 = Não" | 2 = "Desconheço" tamanho cadeia, "cadeia resposta" tamanho do cadeia,"cadeia das respostas separadas por /" (as em branco voltam com ?) tamanho do cadeia,"cadeia das respostas separadas por /" tamanho do cadeia, 1|2|3|4, "cadeia das respostas separadas por /",valor de confiança inteiro 0, se conseguir executar 1, em caso contrário
Ta b e l a8. 1–Pr o t o c o l odec o muni c a ç ã oc o m os e r vi do rWi t t y O Vi s o rnormal do programa listará toda a comunicação entre o cliente e o servidor, funcionando como um l o gda execução, como mostrados nos exemplos de diálogos permitidos pela interface.
Fi g.8. 6–Vi s o rc o molog dac o muni c a ç ã o Iniciaremos pela caixa de diálogos Li s t adeMe ns a ge m:
Fi g.8. 7–Ca i xa sdedi á l o gopa r ae xe c uç ã odoc o ma ndolsmsg(ok)
–83– Note no visor da figura acima a listagem de todas as operações, que detalharemos a seguir: conexão aceita recebendo mensagem lsmsg(ok) enviando mensagem: 6,7,”ok” enviando mensagem 6,12,”1”
O parâmetro 6 indica o tamanho da subcadeia que o segue até o final do comando; o 7 que se trata de um lsmsg e “ok”é o seu parâmetro. Novamente é 6 o tamanho da subcadeia à frente, 12 indica final de conexão e “1”é o código de retorno.
conexão fechada
A Fig. 8.8 abaixo, detalha a execução de outro comando de exibição de mensagem.
Fi g.8. 8–Ca i xa sdedi á l o gop a r ae xe c uç ã odoc o ma ndomsg conexão aceita recebendo mensagem msg(ok,100,100) enviando mensagem: 16,8,0,”ok”,100,100”
enviando mensagem 6,12,”1”
16indica o tamanho da subcadeia restante 8é mostre caixa de diálogo, onde 0explicita que se trata do ms g “ok”é a cadeia a ser exibida e 10 0, 1 00indica as coordenadas do vértice Este comando exige um retorno do usuário; assim esta linha ocorrerá somente após o clique no Vi s t o .
conexão fechada
A seguir, discutiremos a caixa de diálogos para o comando pr o mpt . Neste caso, será emitida uma pergunta, a que o usuário poderá responder em uma janela.
Fi g.8. 9–Ca i xa sdedi á l o gopa r ae xe c uç ã odoc o ma ndoprompt É esclarecedora a discussão da terceira linha do Visor:
–84– enviando mensagem: 39,8,2,”Pergunta”,”Como vai você?”,100,100 39 é o tamanho restante da subcadeia; 8 obriga a mostrar uma caixa de diálogo; 2 indica ser uma caixa para o comando prompt; “Per gunt a”é o título da caixa de diálogo; “Comovaivocê?”é a pergunta, colocada no interior da caixa; e 100, 100 são as posições horizontal e vertical do vértice superior esquerdo da caixa
O diálogo continuará ao se responder a pergunta e clicando em o k . Esta ação ocasionará a abertura da caixa de diálogo Li s t adeMe ns a ge ns , com o texto informado.
Fi g.8. 10 –Co nt i nua ç ã ododi á l o go
Fi g.8. 11–Ca i xadedi á l o goask No exemplo acima, a execução do comando a s kproduz a caixa de diálogo Co ns ul t a , que reproduz a pergunta efetuada e permite três alternativas de resposta: Si m,Nã oe De s c o nhe ç o . Este recurso é utilizado pelos Oráculos. Neste caso, o Witty aguarda a informação do usuário. Os códigos de retorno são respectivamente 0, 1e 2 . O código da resposta obtida (0de Si m), será exibido na caixa Li s t adeMe ns a ge ns . O Comando a c q b o xé mais complexo, possuindo 11 parâmetros. No entando, é bastante poderoso prestando-se a muitas situações para a geração de regras. Nossa implementação é simplificada, mas torna possível se consultar o usuário sobre uma determinada informação com quatro alternativas de resposta: 1) afirmativa; 2) negativa; 3) desconhecida totalmente; e 4) dependente (nesse caso pode ser de uma l i s t adef a t o sou de outra b a s edec o nhe c i me nt o ).
–85– A cada uma destas opções está associado um botão para a efetivação da resposta adequada. O comando foi programado mantendo compatibilidade com a primitiva a c q b o xdo Witty. De seus 11 parâmetros, os quatro iniciais são cadeias de caracteres com textos para a caixa de diálogo, os cinco seguintes variáveis e os dois últimos numéricos (posições x e y do vértice da janela). Neste caso não utilizaremos todos. A descrição de cada um deles será feita após o exemplo a seguir. Na Fig. 8.12 demonstramos o emprego do a c q b o xpara o caso mais simples, de retorno s i m, nã oou de s c o nhe c i do , listando-se a segunda variável (*y) que armazena o t i poda resposta do usuário, que informa o botão pressionado.
Fi g.8. 12–Us odoacqbox Caso se pressionasse nos botões De pe nde nt ee Li s t adef a t o s , seria aberta a janela I ns i r ai t e m para entrada destes fatos. A janela inferior lista os dois últimos fatos informados. Encerra-se com o botão Adq ui r a (ou Ca nc e l a ).
Fi g.8. 13–De pe ndê nc i af a c t ua l
Fi g.8. 14–Va l o r e sdava r i á ve ltipo,c o nf o r mer e s po s t adous uá r i o Na Fig. 8.14 acima estão demonstrados os valores da segunda variável (t i po ) que é armazenado em *y. A terceira (*z) guarda os valores de retorno, como visto na Fig. 8.15 (pág. seguinte). Os dois primeiros parâmetros fornecem, respectivamente, o título e o conteúdo do primeiro quadro da caixa de diálogo; os dois últimos a posição para exibição dessa caixa. Os demais não são utilizados.
–86–
Fi g.8. 15–Pr o c e s s a me nt odoacqbox Na Fig. 8.15 acima, exibe-se a listagem da terceira variável (*z) que captura as caixas de textos do diálogo I ns i r ai t e m. Acompanhe na Fig. 8.13 da página anterior e note que as janelas estão mostradas em ordem inversa e separadas por uma barra (/) e as linhas por um cifrão ($). A outra opção de dependência é de uma base de conhecimento existente que contenha a informação solicitada. Neste caso deve-se pressionar os botões De pe nde nt ee, a seguir, Ba s ee xi s t e nt e . Será introduzida a caixa de diálogos que permite abrir arquivos de base de conhecimento (.kb) no diretório corrente, com possibilidade de navegação se for necessário. Esta interação está demonstrada na Fig. 8.16 a seguir. A interação entre cliente e servidor está na Fig. 8.16. Nas páginas finaisdesta seção apresentamos a listagem do programa principal (c l i ent e . vbp) em Visual Basic.
Fi g.8. 16–De pe ndê nc i adeBa s ee xi s t e nt e
–87–
Fi g.8. 17–I nt e gr a ç ã oc l i e nt e s e r vi do rpa r aade pe ndê nc i adeb a s ee xi s t e nt e A comunicação entre cliente-servidor é possível através da área de transferência, conforme vimos no capítulo anterior, empregando-se as primitivas ge t c le put c l . Outra forma do cliente enviar ao servidor é através do comando TCP-IP, também comentado no capítulo anterior. Este comando não está disponível para transmissão em sentido inverso, caso em que será necessário empregar a primitiva sendsync com a seguinte sintaxe: sendsync(<”comando”>,) A Fig. 8.18 a seguir explora este recurso.
Fi g.8. 18–Co ma ndos e nds ync
–88– Li s t agem dopr ogr amapr i nc i pal Global Global Global Global
vez As Integer ent_comando As String volta As String wt_ligado As Boolean
Public Sub recebe(ByVal entrada As String) 'As funçoes são programadas de acordo com o seguinte protocolo: ' +-----+----------------------+------------------------------------------------------------------------+ ' | num | Comando Witty | | ' +-----+----------------------+------------------------------------------------------------------------+ ' | 0 | lsbase | tamanho cadeia,0,"cadeia conteudo base",0|1 (ativa|desativa) | ' | 1 | desativada | | ' | 2 | desativada | | ' | 3 | desativada | | ' | 4 | desativada | | ' | 5 | desativada | | ' | 6 | desativada | | ' | 7 | Mostre msg assincrona| tamanho cadeia,7,"cadeia mensagem" | ' | 8 | Mostre cx de diálogo | tamanho cadeia,8,ID do tipo dialogo (ver tabela abaixo) | ' | 9 | Mostre msg de erro | tamanho cadeia,9,"cadeia de mensagem de erro" | ' +-----------------------------------------------------------------------------------------------------+ '| TABELA ID do tipo de dialogo | ' +-----------------------------------------------------------------------------------------------------+ ' | num | Comando | | '| | Witty | | ' +-----+---------+-------------------------------------------------------------------------------------+ ' | 0 | msg | 0,"cadeia da mensagem",pos x,pos y sem retorno | ' | 1 | ask | 1,"cadeia da mensagem",pos x,pos y | ' | 2 | prompt | 2,"titulo do dialogo","cadeia da pergunta",pos x,pos y | ' | 3 | input | 3,"cadeia da pergunta","cadeia das opções separadas por /",nº textboxes,pos x,pos y | ' | 4 | choose | 4,"cadeia da pergunta","cadeia das opções separadas por /" ,pos x,pos y | ' | 5 | acqbox | 5,"cadeia da pergunta",pos x,pos y | ' | 6 | sendsync| 6,tamanho da cadeia,"cadeia do comando enviado" | ' +-----------------------------------------------------------------------------------------------------+ 'DECLARA VARIÁVEIS DO PROCEDIMENTO recebe Dim func As String Dim pos As Integer Dim ifecha As Boolean 'Acha posição da primeira virgula e a cadeia "func" que inicia entrada pos = InStr(1, entrada, ",") func = Mid$(entrada, 1, pos - 1) 'Se a entrada é , então func = Select Case func Case "7" ' Mensagem assíncrona lsmsg entrada = Mid$(entrada, pos + 2, Len(entrada) - pos - 2) frmdisplay.lstmsg.Text = frmdisplay.lstmsg.Text & entrada frmdisplay.Show Case "8" ' Várias possibilidades pos = InStr(1, entrada, ",") entrada = Mid$(entrada, pos + 1, Len(entrada) - pos) pos = InStr(1, entrada, ",") func = Mid$(entrada, 1, pos - 1) entrada = Mid$(entrada, pos + 1, Len(entrada) - pos) Select Case func Case "0" 'comando msg pos = InStr(1, entrada, Chr(34)) entrada = Mid$(entrada, pos + 1, Len(entrada) - pos) pos = InStr(1, entrada, Chr(34)) entrada = Mid$(entrada, 1, pos - 1) frmMsg.lbmsg.Text = entrada frmMsg.Show Case "1" '1 ask
1,"string da mensagem",pos x,pos y
pos = InStr(1, entrada, Chr(34)) entrada = Mid$(entrada, pos + 1, Len(entrada) - pos) pos = InStr(1, entrada, Chr(34)) func = Mid$(entrada, 1, pos - 1) entrada = Mid$(entrada, pos + 1, Len(entrada) - pos) frmask.pergunta.Text = func frmask.Show
–89– '-----------------------------------------------------------------------------------------------------'----------------INÍCIO DO CASO 8,2 prompt -----------------------------------------------------------'-----------------------------------------------------------------------------------------------------Case "2" '2 prompt
2,"titulo do dialogo","string da pergunta",pos x,pos y
pos = InStr(1, entrada, Chr(34)) entrada = Mid$(entrada, pos + 1, pos = InStr(1, entrada, Chr(34)) func = Mid$(entrada, 1, pos - 1) entrada = Mid$(entrada, pos + 1, prompt.Caption = " " & func pos = InStr(1, entrada, Chr(34)) entrada = Mid$(entrada, pos + 1, pos = InStr(1, entrada, Chr(34)) func = Mid$(entrada, 1, pos - 1) entrada = Mid$(entrada, pos + 1, prompt.txtperg.Caption = func prompt.Show
Len(entrada) - pos) Len(entrada) - pos) Len(entrada) - pos) Len(entrada) - pos)
Case "3" '3 input 3,"string pergunta","strings das opcoes separadas por /",numero de textboxes,pos x,pos y 'Deixamos para ser feito depois Case "4" '4 choose 4,"string da pergunta","strings das opcoes separadas por /" ,pos x,pos y 'Deixamos para ser feito depois '-----------------------------------------------------------------------------------------------------'----------------INÍCIO DO CASO 8,5 acqbox -----------------------------------------------------------'-----------------------------------------------------------------------------------------------------Case "5" '5 acqbox 5,"string da pergunta",pos x,pos y pos = InStr(1, entrada, Chr(34)) entrada = Mid$(entrada, pos + 1, Len(entrada) - pos) pos = InStr(1, entrada, Chr(34)) func = Mid$(entrada, 1, pos - 1) entrada = Mid$(entrada, pos + 1, Len(entrada) - pos) aqsregra.framPerg.Caption = func pos = InStr(1, entrada, Chr(34)) entrada = Mid$(entrada, pos + 1, Len(entrada) - pos) pos = InStr(1, entrada, Chr(34)) func = Mid$(entrada, 1, pos - 1) entrada = Mid$(entrada, pos + 1, Len(entrada) - pos) aqsregra.conc.Caption = func aqsregra.Show '-----------------------------------------------------------------------------------------------------'----------------FIM DO CASO 8,5 acqbox --------------------------------------------------------------'-----------------------------------------------------------------------------------------------------'-----------------------------------------------------------------------------------------------------'----------------INÍCIO DO CASO 8,6 sendsync ---------------------------------------------------------'-----------------------------------------------------------------------------------------------------Case "6" '6 sendsync tamanho do string,6,"string do comando enviado", 'O cliente trata o comando recebido e retorna uma resposta para 'o Witty-Server 'RETIRANDO AS ASPAS ( chr(34) )------------------------------------------------------------pos = InStr(2, entrada, Chr(34)) entrada = Mid$(entrada, 2, pos - 2) '------------------------------------------------------------------------------------------'TRATAMENTO DA CADEIA "entrada" -----------------------------------------------------------------'------------------------------------------------------------------------------------------------Select Case entrada 'casos que serão tratados pelo cliente Case "a" sendwt "Recebido a cadeia " & Chr(34) & "a" & Chr(34) & " como retorno ao Cliente" Case "b" sendwt "Recebido a cadeia " & Chr(34) & "b" & Chr(34) & " como retorno ao Cliente" Case Else 'Grava a entrada em um arquivo para testar execute no cliente um programa para ler o arquivo 'após a execução, por exemplo: ' openfile(entrada,r,1)& readline(1,*lido) & lsmsg(*lido)& closefile(1) ' lembrar que no Witty a entrada para o sendsync deve ser uma cadeia '----------------------------------------------------------------------------' EXEMPLO DE PROGRAMA DO WITTY PREPARANDO A ENTRADA ' defprg(sincrono(*entrada,*saida),assign(*entrada,comando)& ' retrieve(comando,*comando)& '% A ENTRADA AGORA É UMA CADEIA ' sendsync(*comando,*saida))# '-----------------------------------------------------------------------------
–90– 'ESTE PROGRAMA EVIDENCIA QUE O COMANDO É SÍNCRONO, POIS APENAS APÓS O ARQUIVO GRAVADO NO SERVER É 'QUE O CLIENTE RECEBE O RETORNO. Open "entrada" For Output As #1 vez = vez + 1 Print #1, entrada & vez Close #1 sendwt entrada ' "Recebida Outra cadeia diferente de " & Chr(34) & "a" & Chr(34) & " ou ‘ " & Chr(34) & "b" & Chr(34) & "...e que é " & entrada End Select '------------------------------------------------------------------------------------------------'------------------------------------------------------------------------------------------------'---------------FIM DO CASO 8,6 sendsync -------------------------------------------------------------End Select Case "9" pos = InStr(1, entrada, Chr(34)) entrada = Mid$(entrada, pos + 1, Len(entrada) - pos) pos = InStr(1, entrada, Chr(34)) func = Mid$(entrada, 1, pos - 1) MsgBox "ERRO DE EXECUÇÃO: " & func sendwt "true" End Select End Sub Public Sub sendwt(ByVal s As String) 'PROGRAMA PARA RETORNAR CADEIAS COMO RESPOSTA DO CLIENTE PARA O SERVER...... 'SÓ PODE SER UTILIZADO QUANDO O SERVER ENVIAR UM COMANDO QUE SEJA SÍNCRONO E PORTANTO 'ESPERANDO RESPOSTA A SER ENVIADA PELO CLIENTE............ Dim argu As String If wt_ligado Then argu = CStr(Len(s)) & "," & s ent_comando = argu If ent_comando <> "" Then frmClient.tcpClient.SendData ent_comando Else MsgBox "Comando não pode ser nulo" End If Else MsgBox "Não existe comunicação com o Server" End If End Sub
8. 3–Ser vi dorpadr ão Esta interface, escrita na linguagem Vi s ua lBa s i c(versão 6.0), apresenta um servidor padrão com algumas operações simples objetivando demonstrar o seu potencial. A idéia subjacente para este tipo de recurso é acrescentar novas potencialidades ao Witty, dotando-o de capacidades que não possua – ou que se torne muito complexo ou inadequado dotá-lo – pela possibilidade de trabalhar cooperativamente com outras aplicações. Desta forma, oWitty pode permanecer um programa mais enxuto, executando as funções nas quais é melhor, vistas nos capítulos precedentes. Se a aplicação requerer operações fora deste escopo – como acesso a banco de dados ou de textos, computação gráfica ou complexos cálculos estatísticos, por exemplo – pode solicitar estas funções de um produto especializado.
Fi g.8. 19–I nt e r f a c edoSe r vi do rpa dr ã oe s c r i t ae m VB
–91– A interface do Servidor padrão, exibida na Fig. 8.19 acima tem a única função de mostrar o protocolo de comunicação, pois a rigor um servidor não necessita ter interface com o usuário: basta que devolva o retorno das requisições do programa cliente. A janela superior Re c e b e ndoestá reservada para os detalhes da comunicação. O botão Li mpa rpermite apagar o resultado de uma sessão para se apreciar o de outra. A janela Po r tpermite que se modifique o valor da porta, cujo de f a ul té 5000. Neste caso, basta escrever o novo número e pressionar o botão At ua l i z a . Os três botões inferiores permitem modificar o conteúdo da janela superior. O valor padrão é o do meio, Mo ni t o r . O da esquerda, Te xt o , modifica-a para expor o retorno do comando l s ms g; o da direita, Fi gur a , apresenta o retorno de mos t r af i g, duas das funções implementadas para esta demonstração. A comunicação entre o clinete Witty e esse programa é pela primitiva TCP-IP, através da qual podese enviar comandos para serem executados no servidor. O servidor deste exemplo, foi programado para aceitar: § Mensagens de texto (l s ms g); § Exibição de figuras (mos t r af i g); § Adição de dois valores (s ome); § Mensagem (ms g) e § Aquisição de conhecimento (ac qbox). Nesta exemplificação, nos dois últimos casos optou-se por devolver o comando para execução no próprio cliente, uma vez que tem a capacidade de tratá-los.
Fi g.8. 20–I nt e r f a c egr á f i c o sdopr o j e t oSe r vi do rPa dr ã o A Fig. 8.20 exibe o o elemento gráfico do projeto, cuja listagem está em anexo no final deste capítulo. As figuras a seguir ilustram a execução deste programa para as situações previstas acima.
Fi g.8. 21–Exe c uç ã odopr o gr a matcp.prg Na Fig. 8.21 da página anterior está apontada a execução do comando ms g. Os números junto às setas indiquam a seqüência dos eventos. O resultado 1no Visor (seq. 4), indica processamento bem sucedido. Este caso é um daqueles para o qual o servidor simplesmente devolve o comando recebido para ser
–92– executado no cliente. Para isso utiliza a primitiva s ends ync . O outro comando nestas condições (ac qbox) não será aqui tratado. Nos exemplos a seguir manifestaremos os recursos da implementação em VB, iniciando pela exibição de textos, sendo que o comando l s ms gaí executado não é a primitiva Witty.
Fi g.8. 22–Exe c uç ã odopr o gr a malsmsg.prg Note na figura acima as duas funções da primeira janela da interface Servidor, como monitor e exibindo texto. Na Fig. 8.23 (página seguinte) ela mostrará uma figura ao executar o comando mos t r af i g, neste caso restrito a arquivos padrão BMP.
Fi g.8. 23–Exe c uç ã odopr o gr a mamostrafig.prg Abaixo, o programa s ome, um singelo cálculo de adição com duas parcelas, que retorna o resultado no registro $$vol t a:
–93–
Fi g.8. 24–Exe c uç ã odopr o gr a masome.prg
–94–
–95–
Bi bl i ogr af i a AIKINS, J S. Pr o t o t y pi c a lk no wl e d gef o re x pe r ts ys t e ms . Artificial Intelligence 20(2):163-210, feb 83. ALLEN, J., Na t ur a lLa ngua g eUnde r s t a ndi ng, New York, The Benjamin/ Cummings Publishing Company, 1987. BEARDON, D. L. & HOLMES,G., Na t ur a lLa ngua gea ndCo mput a t i o na lLi ngui s t i c s :a nI nt r o duc t i o n. Ellis Horwood Limited, New York, NY, 1991. BENNET, J. S., ROGET:A Kno wl e dge Ba s e a dSys t e mf o rAc q ui r i ngt heCo nc e pt ua lSt r uc t ur eo faDi a gno s t i c ,Ex pe r tSys t e m. In Journal of Automated Reasoning 1, 49-74, 1985. BENNETT, J et alii. Ak no wl e dg e b a s e dc o ns ul t a ntf o rs t r ut ur a la na l ys i s .Stanford Un, Ca., sep 78 (Computer Science Dept). BISWAS, G et alii. Kno wl e d ge a s s i t e ddo c ume ntr e t r i v a l . Journal The Am Soc for Info Science, 38(2):83-110, 87. BRACHAMM, R. J., ILi e dAb o utt h eTr e e s , AI Magazine, Vol. 6, (3), pp. 80-93, Fall, 1985. BRAGA, J. L., EPI STEME-Aq ui s i ç ã oeEs t r ut ur a ç ã oAut o má t i c a sdeCo nhe c i me nt o , Tese de D.Sc., Pontifícia Universidade Católica, Rio de Janeiro, RJ, Brasil, 1990. BUNGE, M., Sc i e nt i f i cRe s e a r c hITh eSe a r c hf o rTr ut h, New York, Springer-Verlag, 1967. BUNGE, M., Tr e a t i s eo nBa s i cPh i l o s o p hy ,Vo l umeI , Se ma nt i c sI :Se ns ea ndRe f e r e nc e , Dordrecht, D. Reidel Publishing Company, 1974. CARNAP, R., I nt r o duc t i o nt oSy mb o l i cLo gi ca ndi t sApp l i c a t i o ns , New York, Dover Publications, 1958. CARNAP, R., TheLo g i cSt r uc t ur eo ft heWo r l d , 2nd Edition, Los Angeles, University of California Press, 1969. CARVALHO, F M S et alii. Lí nguapo r t ugue s anal i nhadei nf o r ma ç õ e sdoCo mé r c i oExt e r i o r. Simp Bras IA, Anais 4º, p. 299-306, Uberlândia, out 87. CARVALHO, R. L., Ab s t r a c tSe ma nt i c a lSys t e ms , Relatório Interno LNCC no 008/90, Laboratório Nacional de Computação Científica, Rio de Janeiro, RJ, 1990. CARVALHO, R. L., Si s t e ma sc o m Ba s edeCo nhe c i me nt o , Relatório Interno LNCC s/no, Laboratório Nacional de Computação Científica, Rio de Janeiro, RJ, 1991. CHOMSKY, N. As pe c t o sdaTe o r i ad aSi nt a xe . A. Amado Editor, Coimbra, Portugal, 1965. FERREIRA, A C. DOUTOR:ums i s t e madea uxí l i oàd i a gno s e . PUC/RJ, Dep. Informática, fev 86 (dis. mestrado). GENARO, S. Si s t e ma se s pe c i a l i s t a s : oc o nhe c i me nt oa r t i f i c i a l . 1ª ed., Rio, 86, LTC, 192 p. GREEN, C C. Thea p pl i c a t i o no ft he o r e mpr o v i ngt oq ue s t i o na ns we r i ngs ys t e ms( QA3) . Stanford AI Project, june 69, 162 p. (PhD Thesis). LENAT, D P. EURI SKO: apr o gr a mat hel e a r nsne whe ur i s t i ca nddo ma i nc o nc e pt . AI, 21(1983):51-89, 83. LOBATO, L. M. P., Si nt a xeGe r a t i v ad oPo r t uguê s : daTe o r i aPa dr ã oàTe o r i ad aRe gê nc i aeLi ga ç ã o . Vigília Editora, Belo Horizonte, MG, 1986. LYONS, J., I nt r o duc t i o nt oThe o r e t i c a lLi ngui s t i c s , New York, Cambridge University Press, 1968. MARTINEZ, R. Pr o gr a ma c i o ne m Re gl a sdePr o duc c i o nunaI nt r o duc c i o nal o sSi s t e ma sdePr o duc c i o ne s . Campinas, Vieira Gráfica e Editora, 1991. MCT/CONI/SEI. ISe mi ná r i odeI nt e l i g ê nc i aAr t i c i a l : pe r s pe c t i vab r a s i l e i r a . Brasília, out 85. MINSKY, M., AFr a me wo r kf o rRe pr e s e nt i ngKno wl e d ge , In The Psychology of Computer Vision, McGraw-Hill, New York, 1975. MONTEIRO, S. L., Um Sub c o nj unt oRe gul a rdoPo r t uguê s , Relatório Interno LNCC no 027/88, Laboratório Nacional de Computação Científica, Rio de Janeiro, RJ, 1968. MUSEN, M. A., Aut o ma t e dGe ne r a t i o no fMo d e l Ba s e dKno wl e dgeAc q ui s i t i o nTo o l s , London, Pitman, 1989. NEWELL, A., TheKno wl e d geLe ve l , In: Artificial Intelligence, v. 18, no 1 (Jan), pp. 87-127, 1982. NILSSON, N J. Pr i nc i p l e so fa r t i f i c i a li nt e l l i ge nc e , 1ª ed., Berlin, 82, Springer-Verlag, 228 p. NOLT, J.& ROHATYN, D. Ló gi c a , Editora McGraw-Hill, São Paulo, Brasil, 1991. OGDEN, C. K.& RICHARDS, I. A., TheMe a ni ngo fMe a ni ng, London, Ark Paperbacks, 1923. OLIVEIRA, C. M. G. M., AnAr c hi t e c t ur ef o rLa b e l l e dTh e o r e m Pr o v i ngThe o r e t i c a lAs pe c t sa ndI mpl e me nt a t i o n, Ph.D. Dissertation, The University of London, London, England, 1995. OLIVEIRA, A. P., Ca s a me nt odePa dr õ e se m Amb i e nt epa r aPr o c e s s a me nt odeCo nhe c i me nt o , Tese de D.Sc., Pontifícia Universidade Católica, Rio de Janeiro, RJ, Brasil, 1996. POLIT, S. R1a ndb e y o nd :AIt e c hno l o g yt r a ns f e ra tDEC. The AI magazine, winter 85. PONTES, R. C. V., Aq ui s i ç ã odeCo nhe c i me nt opo rMá q ui na s , Tese de M. Sc., Instituto Militar de Engenharia, Rio de Janeiro, RJ, Brasil, 1990. POPPER, K. R., Ob j e c t i v eKno wl e dg eAnEv o l ut i o na r yApp r o a c h, Revised Edition, Oxford, Clarendon Press, 1979. QUENTAL, V., Li nguí s t i c aCo mput a c i o na l–A Ge r a ç ã oAut o má t i c adeTe xt o s , In: Cadernos Didáticos UFRJ 17, Espaços e Interfaces da Lingüística e da Lingüística Aplicada, Organizadores L. P. M. Lopes e M. C. Mollica, pp. 187-195, 1996. QUINLAN, J. R.Le a r ni ngEf f i c i e ntCl a s s i f i c a t i o nPr o c e dur e sa ndThe i rApp l i c a t i o nt oChe s sEndGa me s , In R. S. Michalski et al. (eds), Machine Learning: An Artificial Intelligence Approach, Tioga, Palo Alto, Calif., USA, l983. RICH, E. & KNIGHT, K. I nt e l i gê nc i aAr t i f i c i a l , São Paulo: McGraw Hill, 1994. SCOWN, S J. Thea r t i f i c i a li nt ge l l i ge nc ee x pe r i e nc e : a ni nt r o duc t i o n. Digital Equip. Co., 85 180 p. SILVA, J. L.T., Ut i l i z a ç ã odoPa r a d i gmadeMul t i a ge nt e snoPr o c e s s a me nt odaLi ngua ge m Na t ur a l ,Tese de M. Sc., Pontifícia Universidade Católica, Porto Alegre, RS, Brasil, 1997.
–96– SOUZA, E. M. M., Um Ve r i f i c a d o rGr a ma t i c a lpa r aum Sub c o nj unt odaGr a má t i c ad aLí nguaPo r t ugue s a , Tese de M.Sc., COPPE/UFRJ, Rio de Janeiro, RJ, Brasil, 1997. SOWA, J F. Co nc e pt ua ls t r uc t ur e s :i nf o r ma t i o npr o c e s s i ngi nmi nda ndma c hi ne . , 1ª ed., Reading Mass., 84, Addison-Wesley, 481 p. VALERIO, J. D. P., Us odeOr á c ul o snaAq ui s i ç ã oAut o má t i c adeCo nhe c i me nt o , Tese de D. Sc., COPPE/UFRJ, Rio de Janeiro, RJ, Brasil, 1998. VALERIO, J. D. P., Va l i d a ç ã oeMa nut e nç ã oe m Ba s e sdeCo nhe c i me nt o , Tese de M. Sc., Instituto Militar de Engenharia, Rio de Janeiro, RJ, Brasil, 1990. van MELLE, W. Ado ma i ns i nde pe nde tpr o duc t i o nr ul es ys t e mf o rc o ns ul t a t i o npr o gr a ms . Proc IJCAI-79, 79 p. 923-925. van MELLE, W et alii. EMYCI N:ak no wl e d gee ngi ne e r ' st o o lf o rc o ns t r ut i ngr ul e b a s e de xp e r ts y s t e msI n:Rul e Ba s e dEx pe r tSys t e ms(ed. Buchanan & Shortliffe). New York, 84, Addison-Wesley, p. 302-328. VLEDUTS-STOKOLOV, N. Co nc e ptr e c o gni t i o ni naa ut o ma t i ct e xt p r o c e s s i ngs ys t e mf o rt hel i f es c i e nc e s .Journal The Am Soc for Info Science, 38(4)269-287, 87. WATERMAN, D A & PETERSON, M A. Mo de l so fl e ga lde c i s i o nma k i ng. RAND Co, 81 (REport R-2717-ICJ). WINSTON, P H. Ar t i f i c i a li nt e l l i ge nc e . 2ª ed., Reading Mass., 84, Addison-Wesley, 524 p.