Você está na página 1de 102

Si

stema
para
Pr
ocessamento
de
Conheciment
o

Robert
oLinsdeCarval
ho
Sérgi
oGenaro
e
GrupoWit
ty

24 abr 2007
–i
i–
–i
ii–

Res
umo
O Wi t
ty é 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
trac
t
The Wi tt
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
ce

1. Prova automática de teoremas ......................................................................................................... 1


1.1 - Introdução 1
1.2 - Fundamentos 2
1.3 - Universo de Herbrand 7
1.4 - O Princípio da Resolução 13
2. Witty ..................................................................................................................................................... 17
2.1 - Instalação do programa 17
2.2 - Arquitetura 18
2.3 - Tela inicial 20
2.4 - Intrerface 22
3. Bases de conhecimento ...................................................................................................................... 25
3.1 - Conceituações 25
3.2 - Bases de Conhecimentos no Witty 27
3.3 - Consultando o Witty 29
3.4 - Efetuando deduções 30
4. Programando no Witty ...................................................................................................................... 33
4.1 - Programas simples 33
4.2 - Programas mais complexos 36
4.3 - Programas no Ambiente instalado 40
4.4 - Primitivas 42
4.5 – Controle de Programa 43
4.5.1 – Repetições: comando loop 43
4.5.2 – Sempre funciona: comando hold 44
4.5.3 – Backtraking: comando cut 44
4.5.4 – Sempre falha: comando fail 44
4.5.5 – Combinação cut & fail 45
4.5.6 – Nível de profundidade 46
4.6 – Seqüência de programa 47
5. Caixas de diálogos ............................................................................................................................. 51
5.1 – Consultando o usuário: comando ask 51
5.2 – Conversando com usuário: comando prompt 51
5.3 – Formulários: comando input 52
5.4 – Aquisição de conhecimento: primitiva acqbox 54
5.5 – Menus: o comando choose 57
6. Oráculos ............................................................................................................................................... 61
6.1 – Definições e Conceitos 61
6.2 - Uso de Oráculos no Witty 63
7. Gramáticas ........................................................................................................................................... 69
7.1 – Declaração de Registros 69
7.2 – Uso de expressões regulares no método 70
7.3 – Uso de arquivos no método 71
7.4 – Sistemas de Prost 72
7.5 – Gramáticas 73
8. Comunicação ....................................................................................................................................... 79
8.1 – TCP/IP 79
8.1.1 – Função servidor 79
8.1.2 – Área de transferência 80
8.2 - Ligação cliente servidor Witty 80
8.3 - Servidor padrão 90
Bibliografia ............................................................................................................................................... 95
–vi–
1.
ProvaAut
omát
icadeTeor
emas

1.
1–I
ntr
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ípiodaRe soluçã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ó gicaPr opo
sicional.
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
aestáiniciandoano velada ssei
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
mplo1.2–Ló gic
apr edicat
iva.
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 rdadei
ra sou f als
as. 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. Combinando-
as com emprego dos c one cti
vosló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 llfor me
dfo
rmul
a, nese trabalho abreviada por f
bf, ou simplesmente

rmul 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
bel
a1.
1–Ta
bel
as-
ver
dade
s.
Outro conceito importante é o de t aut o
logia, 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 ¬ P P ∨ ¬ P
V F V
F V V

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 –
termo s, pr e
dic adose quantif
ica
do r
es– 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 ri
dade ; assim é_maior_que e
ama têm a rida de2, succ e pai têm a ri
da de1. De maneira geral, se possuir n argumentos, dizemos que
apresenta a rida denou é n-áre
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
Todas as coisas são quentes ou não quentes.
é equivalente a
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
órmul a.
Mais formalmente, t ermopossui 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 t1,
..
.,tntemos, 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,.
..
,tnforem termos, então P( t
1,..
.,tn)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
Existem paralelogramos que são quadrados
ou seja
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 qua nti
f i
cadores.
–5–
Assim, a frase ‘para todo’ representa o q
uant
ifi
c ado
runi ver
sale será representado por ∀ e ‘existe’ o
quant
if
icadore xi
st
enc i
al, 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 imitadaquando 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 riáve
lél i
vrese e somente se apresentar ao menos uma ocorrência livre. Chama-se
sentenç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 Exempl o1.3–Re grasdeinferência.


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: A ∨ B
Premissa 2: ¬ A
Conclusão 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 B A ∨ B ¬ A (A∨B) ∧ ¬ A
V V V F F
V F V F F
F V V V V
F 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 do Absurdo (P → Q e ¬ Q) → ¬ P
<10> Lei da Adição P → P ∨ Q
<11> Lei da Dupla Negação P ↔ ¬¬P
<12> Lei da Contraposição (P → Q) ↔ (¬ Q → ¬ P)
<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 P → Q ↔ ¬P ∨ Q
Implicação e disjunção
<18> Lei da Negação para Implicação ¬ (P → Q) ↔ 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)

Ta
bel
a1.
2–Ta
uto
logi
asút
ei
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
ovadi
ret
a.
Como exemplo de derivação, consideremos o seguinte conjunto de premissas
[1] A → B ∨ C
[2] B → ¬A
[3] D → ¬C
[4] A
de onde pretende-se deduzir a seguinte conclusão
A → ¬D
pelos seguintes passos, garantidos por regras de inferências
[5] B ∨ C
[6] ¬B
[7] C
[8] ¬D
[9] A → ¬D
onde [5] se obtém de [1] e [4] por mo dusponendopo nes; [6] de [2] e [4] pela Lei da Dupla Negação e mo dus
to
ll
endot ol
lens, conforme o exemplo 1.3; [7] de [5] e [6] por mo dust ollendopo nes; [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 bfválidas de um sistema lógico são denominadas t e
orema s
. O procedimento descrito
atrás, que permite o estabelecimento de teoremas, é chamado pr o ce
dime ntodepr o va. Um procedimento é
compl etoquando toda fórmula válida pode ser demonstrada ser um teorema e c o
r re
tose 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 bf
.
–7–
Um l ite
ralé uma fórmula atômica ou sua negação. Uma fórmula F está na f
ormano
rma
lco
njunt
ivase
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 or mano r
ma lpr
ene
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] P ↔ Q = P → Q ∧ Q → P
[02] P → Q = ¬P ∨ Q
Em seguida, devem ser resolvidas as negações, que podem envolver as leis:
[03] ¬ (¬ P) = P
[04] ¬ (P ∨ Q) = ¬P ∧ ¬Q
[05] ¬ (P ∧ Q) = ¬P ∨ ¬Q
[06] ¬ (∀ x P(x)) = ∃x ¬ P(x)
[07] ¬ (∃x P(x)) = ∀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:
[08] Q(x) P(x) ∧ Q = Qx P(x) ε Q
[09] ∀ x P(x) ∧ ∀ x Q(x) = ∀ x (P(x) ∧ Q(x))
[10] ∃x P(x) ∨ ∃x Q(x) = ∃x (P(x) ∨ Q(x))
[11] Q1x P(x) ∧ Q2x Q(x) = Q1xQ2z (P(x) ε Q(z))
onde Q e Qi representam os quantificadores (∀ ou ∃) e ε os conectivos (∧ ou ∨).

n Exe
mpl
o1.
5–Fo
rmaNo
rma
lPr
ene
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)) [02]
2. ∀ x∀ y∀ z ((¬ P(x,z) ∨ ¬ P(y,z)) ∨ ∃u Q(x,y,u)) [06],[05]
1. ∀ x∀ y∀ z∃u (¬ P(x,y) ∨ ¬ P(y,z) ∨ Q(x,y,u)) [08]
conseguindo-se no último passo a forma normal pr
e xda fórmula dada. n
ne

1.
3–O Uni
ver
sodeHer
brand

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
ovapo
rre
fut
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] A → B ∨ C
[ 2] B → ¬A
[ 3] D → ¬C
[4’] 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] A ∧ D negação da conclusão
[ 5] B ∨ C de [1] e [4] por <01>
[ 6] ¬C de [3] e [4] por <01>
[ 7] B de [5] e [6] por <03>
[ 8] ¬A de [2] e [7] por <01>
[ 9] A ∧ ¬A de [4] e [8] por <05>
[10] A ∧ D → A ∧ ¬A de [4] e [9]
[11] A → ¬D 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 rmano rmalpre 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 tri
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 olem, cujos argumentos são todas as variáveis
universais em cujo escopo reside o quantificador existencial substituído. As funções de Sk ole
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 cláusul
a. Assim, podemos definir cláusula como uma disjunção de
literais.

n Exe
mpl
o1.
7–Ob
tenç
ãodec
láus
ula
.
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
em
∀ 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 versodeHe rb ra
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,...
,
tn)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í velide S e H o UniversodeHe r
brand.
–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
ver
soeBa
sedeHe
rbr
and.
Considere as cláusulas
1. P(x,a)
2. ¬ 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 = {a, b}
H1 = {a, b, f(a), f(b)}
H2 = {a, b, f(a), f(b), f(f(a)), f(f(b))},
H3 = {a, 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
ulas
Seja, dada a fórmula: ∀ x∀ y x < y → ∃z x + z = y
que em lógica predicativa, fica: ∀ x ∀ y menor_que(x,y) → ∀ z igual(soma(x,z),y)

Os passos para se chegar à cláusula equivalente são:

[1] Eliminar implicações: [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)

chegando-se à cláusula equivalente à fórmula dada.

Fi
gur
a1.
1–Pa
sso
spa
rao
bte
nçã
odeCl
áus
ula
s
Chama-se á r
voresemâ nt
icaà á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 complementares).

n Exempl o1.9–Ár voreSe mântica.


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
vor
eSe
mânt
ica
.n

n Exemplo1.l0–Ár vor
eSe mâ
nti
caf
echa
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. ¬ P(x) ∨ Q(x)
C2. P(f(y))
C3. ¬ Q(f(y))
Sua árvore semântica fechada está exibida na Fig. 1.3
–10–

Fi
gur
a1.
3–Ár
vor
ese
mânt
icaf
echa
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 nferênci
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
echada .
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 or
emadeHe r
br andse 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 brand: 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.11–Apl icaçãodoTe o
remadeHe rbr
and.
Dado o conjunto de cláusulas [exemplo de (Carvalho, 1985)]
1. P ∨ Q ∨ R 4. S ∨ ¬ R
2. ¬ P ∨ Q 5. ¬ T ∨ ¬ S
3. ¬ Q ∨ R 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
vor
ese
mânt
icapa
rae
xempl
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. P ∨ Q ∨ R 5. ¬ T ∨ ¬ S
2. ¬P ∨ Q 6. T ∨ ¬ R
3. ¬Q ∨ R 7. ¬ S ∨ ¬ R
4. 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. P ∨ Q ∨ R 5. ¬T ∨ ¬S
2. ¬P ∨ Q 6. T ∨ ¬R
3. ¬Q ∨ R 7. ¬S ∨ ¬R
4. S ∨ ¬R 8. ¬R
representada por:

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. 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
–12–
representada pela Fig. 1.7.

Fi
gur
a1.
7–Re
duç
ãopa
rci
aldeRe¬ 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
rci
aldeQ 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. P ∨ Q ∨ R 7. ¬S ∨ ¬R
2. ¬P ∨ Q 8. ¬R
3. ¬Q ∨ R 9. ¬Q
4. S ∨ ¬R 10. ¬P
5. ¬T ∨ ¬S 11. P ∨ Q
6. T ∨ ¬R
representadas por

Fi
gur
a1.
9–Re
duç
ãode
fi
nit
ivadeRe¬ 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. P ∨ Q ∨ R 7. ¬S ∨ ¬R
2. ¬P ∨ Q 8. ¬R
3. ¬Q ∨ R 9. ¬Q
4. S ∨ ¬R 10. ¬P
5. ¬T ∨ ¬S 11. P ∨ Q
6. T ∨ ¬R 12. 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
fi
nit
ivadeQ e¬ Q.n

1.
4–O Pr
inc
ípi
odaRes
oluç
ão

O Te ore
madeHe rbrandpermite, 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
incipiodaRe soluçã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 tornam-
se 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 ol
lendopo nens(<03> na Tabela 1.1),
anteriormente explorado por Davis e Putnam, segundo o qual, das cláusulas ,
Cl: P
C2: ¬ P ∨ Q
pode-se derivar
C3: Q.
Estendendo esta idéia para qualquer par de cláusulas (não necessariamente unitárias), podemos
enunciar o Pr i
nc i
piodaRe 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: P(x) ∨ Q(x)
C2: ¬ P(f(x)) ∨ R(x)
eles somente aparecem se substituirmos x por f(a) em C1 e x por a em C2, resultando
C1: P(f(a)) ∨ Q(f(a))
C2: ¬ P(f(a)) ∨ R(a)
o que permite chegar ao seguinte resolvente:
C3: Q(f(a)) ∨ R(a)
Se escolhermos substituir x por f(x) em C1, chegaremos a um novo resolvente
C3’: Q(f(x)) ∨ R(x).
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 A ∨ B
Única Regra ¬A ∨ C
Resolução de Inferência
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) ¬A ∨ B ∨ C [axioma]
( 2) ¬B ∨ ¬A [axioma]
( 3) ¬D ∨ ¬C [axioma]
( 4) A [negação do teorema]
( 5) D [negação do teorema]
( 6) ¬ C [5 e 3; 1]
( 7) ¬A ∨ B [6 e 1; 3]
( 8) B [7 e 4; 1]
( 9) ¬A [8 e 2; 1]
(10) (contradição) [9 e 4; 1]
Fi
g.1.
11–Re
sol
uçã
oeml
ógi
capr
opo
sic
iona
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, *z/*y)
(Luís/*x, *y/*z)
(Luís/*x, Pedro/*y, Pedro/*z)
(Luís/*x, 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, deve-
se 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
ic
adorma isge ral(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. ¬ é_inteligente(a) ∨ é_atriz(a) [4; a/*z]
6. é_atriz(a) [5; 3b]
7. ¬ é_atriz(a) ∨ é_bonita(a) [1; a/*x]
8. é_bonita(a) [7; 6]
9. ¬ é_avó(a) ∨ ¬ é_bonita(a) [2; a/*y]
10. ¬ é_avó(a) [9; 8]
11. (contradição) [10;3a]

Fi
g.1.
12–Re
sol
uçã
oco
m uni
fi
caç
ão
–16–
–17–
2. Wi
tty

A ferramenta Wi tty® é 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 st
ema Automátic
o pa ra For
ma lização do Co nhe cime nto)
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
ial
Co ll
egena 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
nst
alaç
ã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
WindowsExplorere clicar sobre o programa setup.exedo primeiro disco:

Fi
gur
a2.
1–I
nst
ala
çãodoWi
tt
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
tet
ura

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 oPrincipal.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
que
madaa
rqui
te
tur
amo
dul
arb
ási
cadaf
err
ame
ntaWi
tt
y
Módul oLi nguagens .A linguagem de comunicação entre o usuário e o Wi ttyé 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 role.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 backtr
acking.
Máqui nadeI nferência.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 acktracki
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
ist
emapr
ova
dor
Módul o Bas es de Conhe ciment o.Responsável pela criação e manutenção do conjunto de bases de
conhecimento do Wi tt
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
str
utur
ada
sba
sesdec
onhe
cime
nto
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 oInter f
aces
.Os dois tipos de interface com periféricos disponíveis no Wi
ttyestã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
tados
.A técnica de programação baseada em máquina de estados é interpretada
neste módulo.
MóduloODBC.implementa funções de acesso a bancos de dados externos através do padrão de interface
ODBC - Ope
nDa
tab
aseCo
nne c
tivi
ty.
Módul
oAr
itmét
ica.Implementa funções aritméticas básicas.
Módul oGer ênc i
adeMemór ia.Toda a execução de comandos e inferências do Wi t
tyé feita em memória
gerenciada neste módulo, que inclui: alocação, liberação e ga
rba
gec o
llect
ion(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áculo ef iltros.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–
Framesdepr 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
ame
sdepr
ogr
ama
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
aIni
cial

O programa exibe, já na entrada, algumas de suas principais funções:

Fi
gur
a2.
6–Te
lai
nic
ialdoWi
tt
y
Ampliamos os elementos da parte superior da tela para melhor visualização:
–21–

Fi
gur
a2.
7–Pa
rtes
upe
rio
rdat
el
adea
pre
sent
açã
odoWi
tt
y
A primeira linha exibe os menus, objeto de uma primeira análise no decorrer deste texto; algumas
funções serão melhor esclarecidas nos capítulos seguintes. A l
inhadec oma 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 arradef err a
mentas, 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
rradet
are
fasdoWi
tt
y
A janela Amb ie
nt einst
aladoexibe 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
ault, todas as bases estão
interligadas, na ordem em que forem criadas na sessão. Na abertura do programa aparece a base inicial
chaos , fixa e predefinida, onde deve ser armazenado apenas o conhecimento sobre o próprio sistema, isto é,
o me ta -co nhecimento, como por exemplo a estruturação das bases. Esta base é permanente, não podendo ser
destruída.

Fi
gur
a2.
9–J
ane
lamo
str
andooa
mbi
ent
eins
tal
adodoWi
tt
y
–22–

Outra base particular é a bas


es uporte, 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
nter
fac
e

No Amb ient
einsta
lado, clicando-se sobre Fa
tosou Re gras, 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–Í
cone
sut
il
iz
ado
spe
lopr
ogr
ama

Fi
gur
a2.
11–Me
nudec
ont
ext
o(b
otã
odi
rei
todomo
use
)pa
rab
ase
s
Todos os menus do programa são sensíveis ao contexto com o b otãodi r ei
todo 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
ent ei
ns tal
ado: à esquerda o menu referente à raiz (Ba s
es) 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 quivo Edi tar Exi bir Exec utar Fer rament as J anela 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
etras ub l
inha 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 quivo, 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
ivasPRG 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 birpermite 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
oré utilizado para mensagens de retorno do sistema, podendo ser redimensionado como qualquer
outra janela do ambiente. A alternativa Re lat
óriodeEr ros, discutida adiante, abrirá uma janela contendo a
listagem dos comandos programados de forma errônea.
–23–

Fi
gur
a2.
12–Me
nuExi
bir
O menu Exe cutarpermite 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 rrame ntas, 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
vega
dordoWi
tt
y

Fi
gur
a2.
14–Me
nuFe
rra
ment
as,Opç
õesFo
nte
s
–24–

A alternativa Opçõ esdo Me nuFe rrament aspermite 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 dif
icarabre a janela para escolha
de fontes e o Padr ã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 rvidorserá discutida no Cap. 13.

Fi
gur
a2.
15–Me
nuJ
ane
la
O Me nu Ja
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
rrentecom
um tique (3). Clicando sobre outro nome (ou pelo atalho Al t-núme ro) 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
te
rna
tiva
sdoMe
nuJ
ane
las
:Ca
sca
ta,La
doal
adoho
riz
ont
aleve
rti
cal
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
iment
o

3.
1–Conc
eit
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 ies implicação;
o i ff 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.
Átomos . 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 tant 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
ste
ris
co). 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
Termos .A estrutura de dados básica propiciada pela linguagem é o t ermoWi tt
y, que pode ser uma
constante, uma variável ou um termo funcional da forma f
(t
1,.
..
,tn)
, onde fé um átomo (predicado) e t
1,.
..
,
tnsão também termos (variáveis ou constantes).
I
ntei
ros
.São utilizados para operações aritméticas e usados freqüentemente em listas.
n Exemplos: 16, 2000, 0, -27 n
Reais . (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
ntode
cima
l).
n Exemplos: 3.1416, -273.15, 6.0221 n
Cadeiadec ar
ac ter
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órmul aat ômica.Cadeia da forma: p(
t1,..
.,tn), onde t
1,...,t
nsão termos e p é um átomo no papel de um
símbolo predicativo n-
ári
o(no exemplo abaixo é quat
ernári
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:
ifB1a nd. ..andBnt he
nAé uma regra condicional, onde A é o c
ons
eqüe
ntee B1, ..., Bn são os a
nte
cede
nte
sda
regra;
B1a nd. ..andBni mpli
esAé 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
ult
a.A consulta é implementada através da primitiva pr
ove.
n Exemplo:
prove (sup,é_marido-de(“Pedro II”,”Teresa Cristina”)
significando pr oveusando a base de suporte s
up, que “Pedro II é marido de Teresa Cristina”. n
Uni fi
caç ã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 tty, o processo de atribuição é um pouco diferente, sendo
denominado uni fi
caçãoou c a samentodepa dr
õ es
. 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
aisdeuni ficação
§ Va riávei
sc om va ri
ávei
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 nstantescom va ri
áveis: a variável é substituída pelo valor da constante. Isto pode ser visto como
uma forma de atribuição.
§ Co nstantescomc onst
ant es: 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 rmo sf
unc ionaiscomt e rmo sfunciona is: 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 omance(poli
ci
al)e ro
ma nc
e(*x)se unificam: basta que a variável * xseja substituída
pelo átomo po li
cia
l.
2. Os termos ma nual(Bases
,17)e ma nual
(*cap,
*pá
g)se unificam se substituirmos as variáveis * cape *pá gpor
Basese 17, respectivamente.
3. A unificação de li
vr o
(*nome,17)e li
vro
(ti
tulo,
18)falha, pois os argumentos inteiros 17 e 18 não se unificam.
n
Cons ultas . 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
tyfará 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
droI I
”. Assim, as cláusulas
antecedentes resultarão em é _pa
i-de(
“Joã oVI ”,
*y)e é _pa
i-de(*y,
“PedroI
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
iment
osnoWi
tt
y

Para se criar uma base de conhecimento, parte-se do menu de contexto indicado escolhendo-se a
opção Novab ase, chega-se à janela Pr
opr
ieda
desdab
aseda Fig. 3.1:

Fi
gur
a3.
1–Cr
iaç
ãodeumab
asedec
onhe
cime
nto
Na alça Ge ralse estabelece o nome da base. O tamanho pode ser qualquer, respeitados os limites
determinados pelo Windows, desde que não contenha brancos e s eutili
zes ome ntec arac
ter
esmi nús cul
os. As
outras duas alças permitem a adição de Fa tose Regras, 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 Inclui
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
erar. Finalmente, o botão Apa garremove 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 nce
la r.
–28–

Fi
gur
a3.
2–Fa
toser
egr
asdab
aseq
uadr
os
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
nte
údodeumab
ase
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 orer.
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
ont
ext
opa
raumab
asee
spe
cíf
ic
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 priedades. Selecionada, abrirá a janela Pr opr i
edadesda
–29–
base,alça Ge r
al, mostrada na Fig. 3.1. No segundo, No vac
láusula, abrirá a janela na alça Fa
tos
, lado esquerdo
da Fig. 3.2. No último quadro, as escolhas Sa lvare Sal
varc 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 garfará 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
ult
ant
ooWi
tt
y

A criação de uma base de dados pode ser feita de forma interativa, através do comando as ser t. Para
a utilização das bases em uma dedução, é preciso empregar o comando pr ove, que possui a seguinte sintaxe:
prove(<base_sup>,<fórmula>)
A <base_sup> em questão é aquela de s uporte, 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 sor
. A forma
mais curta para isso é:
prove(<base_sup>,<fórmula>) & 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
mandoprove ap
art
irdal
inhadec
oma
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 tt
y1,Wi tt
y2,..
.Wittyn, 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 ascunhoda barra, abre o arquivo r ascunho.prg, 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 ro (#). 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 porcento(%), 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
mandoprove ap
art
irdea
rqui
vodepr
ogr
ama
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
etuandodeduç
õ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
dro3.
1–Ba
sedec
onhe
cime
ntos
obr
eave
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
dro3.
2–Ame
smab
asee
mli
ngua
gem depr
ime
irao
rde
m
A pergunta que desejamos ser respondida é “O par daltem penas ? ”.
Inicialmente carregaremos a base, mas não mais de forma interativa e sim através de um arquivo de
programa, car r
ega_aves .prg, 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
dro3.
3–Pr
ogr
amapa
rac
argadab
asea
ves
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 .prg. 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
ovapa
raab
asea
ves
–32–
–33–

4.
Progr
amandonoWi
tt
y

4.
1–Pr
ogr
amass
impl
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 esao 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 oma ndo, como o da Fig. 4.1 a seguir, que exemplifica o emprego do comando
ms g(<me nsage
m>, <pos-x>,
<po s
-y>) :

Fi
gur
a4.
1–Co
mandopr
imi
ti
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
enteins t
a l
ado,
assim o comando a ss
ert(<b ase
>,<f a
to>|<r egr
a>)acrescenta um fato ou uma regra na base especificada. A
Fig. 4.2 mostra esta possibilidade:

Fi
gur
a4.
2–Mo
dif
ic
açã
odab
asechaos pe
lai
ntr
oduç
ãodof
atoé_mineiro(Pelé)
–34–
Outras modificações no Amb i
entei ns t
ala
dosão possíveis em Pr ogramas,Gr amá ti
case Re gi
stros, 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:
assign(<val
or>,<r egistro>)
retrie
ve(<re
gistro>, <va r
iável>)
Como será visto à frente, há um comando de criação de registro, porém o a ss
igncria 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 ster
isco(*).
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 rma ne nte
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
accent (‘ – apóstrofo),
numb er (# – número) e
quote (“ – aspas).

Fi
gur
a4.
3–Co
nte
údodo
sre
gis
tro
spe
rma
nent
es
A execução de programas em seqüência é permitida através do s
eqü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
cuç
ãodec
oma
ndo
sems
eqüê
nci
a
Há outra caixa de mensagem utilizada pelo sistema, o Vi
sor
. 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 nsagem>“) . 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
mandolsmsg eoVisor
Há também comandos de verificação do ambiente, que testam alguma condição mas não o
modificam. O comando pr ove, 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 ove(<b
ase-
sup>, <c láus
ula1>,
<c láusul
a2> ,
...
,<cláus
ul an>,
<tese
>)
Neste caso, somente a última será testada e todas as anteriores serão consideradas premissas e incluidas na
basedes upo rtenomeada em <b ase-sup>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 nens:
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
mandoprove ede
svi
opa
raa
lte
rna
tiva
s
Um aspecto importante visto no exemplo acima é a possibilidade de se colocar várias alternativas
através do al t
er nador“|” (lê-se “ou”). O comando pr o
veforma uma seqüência com o primeiro l sms 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 ls
msg, após o a
lte
rna
dor(|), exibindo a mensagem Fa l
s o.
–36–
4.
2–Pr
ogr
amasmai
scompl
exos

Ainda que seja permitido o uso da l inhadec oma 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 arquivodepr ogra
ma– um arquivo texto identificado
pela extensão . prg.
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 (.
grm), objetos de outros capítulos.
O primeiro ícone (no vo) permite criar um novo arquivo no diretório atual com nome wi tty1.prgna
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 ascunho )
abre um arquivo específico r ascunho .
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ágra f
os, 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 ro(#). O Witty ignora o conteúdo de uma linha após o sinal po rcento(%), 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:
ask
(<pe r
gunta>,<* re
torno >,<po s-x>,<pos-
y>)
cujos códigos de retorno estão ilustrados na Fig. 4.7 a seguir:

Fi
gur
a4.
7–Có
digo
sder
eto
rnopa
raoc
oma
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
reg1 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 ro
é 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
lsmsg(“Va lo
rder e
torno:2->Ignoro”)
#
seriam emitidos todas as mensagens duas mensagens emendadas.

Fi
gur
a4.
8–Ar
qui
vodepr
ogr
amapa
raa
lte
rna
tiva
smúl
ti
pla
s

Fi
gur
a4.
9–De
fi
niç
ãodepr
ogr
ama
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
fpr
g(<no
me_pr
ogr
ama
>,<c
orpo
_pr
ogr
ama
>).
No exemplo da Fig. 4.9 atrás, definiremos dois módulos e
ntra
dae exibe, 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,<tít
ulo>,<campo >, <*dado _di
git
ado>,<po
s-x>,
<pos-y>)
onde fixamos a quantidade de campos para um. Este comando será detalhado no Cap. 10 –Ca ixa
sdediálo
go s.
Os dois dados informados (nome e nota) ficarão armazenados em registros para utilização no programa
seguinte.
–38–

No Regr
a
1 Devem ser utilizadas letras mi núsculasnos comandos, com exceção dos literais e alguns comandos especiais
(como o NOT, diverso de cláusula negativa not ).
2 A execução do programa é seqüencial, obedecendo a ordem de colocação dos comandos, a exemplo do
PROLOG.
3 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.
4 Os parâmetros podem se constituir de const antesou var iáveis:
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
isco(*).
5 Todas as variáveis do W i t t y são estritamente locais, visíveis somente dentro do parágrafo onde forem
definidas.
6 A passagem de valores entre diversos parágrafos do programa é feito através de r egistros. 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]
7 Todo parágrafo de programa, que poderá ocupar uma linha ou mais, deverá ser encerrado pelo caractere #
(númer o).
8 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
ical) (ou).
9 Os comentários são precedidos pelo sinal % (por centagem). 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#).
10 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
bel
a4.
1–Ca
rac
ter
íst
ica
sdea
rqui
vosdepr
ogr
amapa
raoWi
tt
y
Exibeé 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
conc a
t(<c adeia1>,
<ca
dei
a2>,
<*cadei
a_c onca t
ena 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 rros.prgque 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 arregarda 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
nsa
gem dee
rrodepr
ogr
ama
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
lat
óri
odeEr
ros
Corrigindo os erros mais evidentes, chegando-se ao seguinte resultado:

Regras % --- Programa de demonstração para corrigir erros


1 lsmsg(“Mensagem na primeira linha”) & lf#
4 e 7 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 ( regr


a1); no segundo, os parâmetros de
conc atestavam 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
riá
vei
ssã
oes
tri
tame
ntel
oca
is
–40–

Nenhum erro será detetado agora, porém o resultado obtido (Fig. 4.12) não é o esperado. O comando
askarmazena na variável *x o código de retorno, no caso “0”, porque foi pressionado o botão “Sim”. No
entanto, o ls msga 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 sk
(“Sa mamb ai
aéve ta l
?”,*x,100,2 00)& lsms 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 egistrossão criados pelo comando ne wr e
g( <cadei
a1>,<cadei
a2>,<cade i
a3>)onde <cadeia1> é o
nome do registro, <cadeia2> o mé to doe <cadeia3> um pr ogramaext e
rno. Se não forem utilizados,
os dois últimos valores poderão ser NULL(a ss im mes
mo ,em maiús
c ul
as).
§ Os registros do tipo no me (<cade i
a>, NULL, NULL) , podem ser criados a partir do comando de
atribuição a ssi
gn( <va riável>,<nome _regi
stro>).
§ Quando isso ocorrer, o valor da variável, conteúdo do registro, será denotado por
[nome_registro] (entre c ol
chetes) 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
retri
e ve
(<no me_registro>, <variável
>) . 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 lr
eg(<no me_regi
stro>)e c lr
egs.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
eins
tal
ado

Outro recurso muito útil na programação é o item Pr ogramasdo 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
entei nstal
ado , ativando-se a alça correspondente. Clicando-se na alça inferior Pr
ogr
ama 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
st
age
m do
spr
ogr
ama
sat
ivo
s

A primeira, Si stema , 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
sk:
–41–

Fi
gur
a4.
14–Pr
ogr
ama
sdoSi
st
ema(
pri
mit
ivo
s)
A user, são as genéricas para o usuário. Estas alças caracterizam os frames, 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 defprg-
in, como
mostrado a seguir:
% Pr ogramaut il
izadopar aexibirarquivosdet exto
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
ari
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
st
age
m deum pr
ogr
amaa
tivo
O mesmo vale para os programas pré-instalados (pr
e_i
nta
ll
) conforme visto a seguir:

Fi
gur
a4.
16–De
tal
hame
ntod
eum pr
ogr
amapr
é-i
nst
ala
do
–42–
4.
4–Pr
imi
ti
vas

As primitivas são programas já existentes, b ui l


t-in, 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 Primit
iva
sPRG. .
.do Me nuEdi t
are Pr ogra mas
doSi s
temano Amb i
enteins ta
lado
.
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.
Aritmét icas
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
omplemento-de
-do
is. Cobrem o intervalo entre -
2147483648 a +2147483647.

Oper
ador Si
gni
fic
ado Exempl
o
+ Soma +(2,3,*x) *x retorna 5
Soma (como subtração) +(2,*x,5) *x retorna 3
* Multiplicação *(2,5,*x) *x retorna 10
Divisão *(*x,5,10) *x retorna 2
=(3,2) retorna falha
= Igualdade
=(2,2) retorna sucesso
<>(3,2) retorna sucesso
<> Diferente
<>(2,2) retorna falha
>(3,2) retorna sucesso
> Maior que
>(1,2) retorna falha
>=(3,2) retorna sucesso
>= Maior que ou igual a >=(2,2) retorna sucesso
>=(1,2) retorna falha
<(1,2) retorna sucesso
< Menor que
<(3,2) retorna falha
<= Menor que ou igual a
inc Incremento inc(*x,5) incrementa x de 5
dec Decremento dec(*x,1) decrementa x de 5

Controle
São empregados para controlar a execução de programas, como c ut,fail,hol
de l oop. Devido sua
importância, serão discutidos na próxima seção. Há outros comandos além destes, entre os quais citamos
exe
cprg<nome _do_programa >, permitindo que, dentro de um programa, se ordene a execução de outro.
Ar quivos
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
tel
ine(
<inteiro>,<te
xt o
>).
Gr amát ica
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.
Int
erfac
e
São aquelas utilizadas para se comunicar com o usuário. Já vimos algumas, de emprego imediato,
como msg, l
sms
ge lf. No capítulo seguinte serão discutidas as que geram caixas de diálogo.
BasedeConhec imento
Estes comandos dizem respeito a modificações introduzidas às bases de conhecimento. Já vimos no
capítulo anterior os mais comuns, como a ss
erte ne
wbase. Há dezenas de outras primitivas que poderão ser
empregadas em condições específicas, como por exemplo q tyf
act(<nome _da_base>,<*vari
ável>)
, que retorna
em *va ri
ável, o número de fatos da base nomeada.
–43–
Programas
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
fpr
g
para a definição de programas e também é importante l oa dprg(<no me _do
_pro
gra
ma >)para carregá-lo na
memória.

Estrat
égi as
São comandos que permitem modificar o funcionamento do Witty com respeito à maneira
padrão. Exemplo típico são ge
tde
pth, e s
etdepth, 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 strador 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.
ProvadeTeor emas
Há vários comandos referentes a este assunto, sendo que o mais óbvio, pr
ove
, já discutido no capítulo
anterior. Na seção 4.6 à frente, mostraremos o uso do Ht e
rm para recuperar informação da base de
conhecimento.

4.
5–Cont
rol
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 oopforça a execução do trecho entre c
oma
ndo
1e c
oma
ndo
naté que c
ondi
çãose verifique. O exemplo
da Fig. 4.17 ilustra o emprego desta primitiva.

Fi
gur
a4.
17–Empr
egodoloop
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
efunc
iona: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 ktraking: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 ck
trac
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 acktr
ackingautomá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
egodocut
A inclusão do c utna linha 2 cancela a função do l oop, 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 alha: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 ailque 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 ovedevolve apenas ve rdadei
roou f als
o . Para nosso objetivo, será
necessário utilizarmos em combinação com este, a primitiva Ht erm (atenção: a inicial é maiúscula), com a
seguinte sintaxe:
Hterm(<núme ro>, <*variáve l_da_pr ova>, * vari
ável_de_retor 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 ariocacom três fatos e uma regra. O programa utiliza variável no
comando pr ove , a mesma empregada em Ht erm. O terceiro parâmetro desta primitiva é listado no Visor.
–45–

Fi
gur
a4.
19–Empr
egodeHterm:r
ecupe
raç
ãodeda
dosdob
anc
odec
onhe
cime
nto
Apenas uma das possíveis alternativas foi recuperada: a última da lista de fatos. Isto se deve à estratégia
implementada pelo Wi t
ty, 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 fai
l:
Na Fig. 4.21 da página seguinte, o comando f ailna 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& fai 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
ailpode eliminar
a cláusula daquela porção do seu programa. O cutprevine 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 3 4 5 6
cut fail

Fi
gur
a4.
20–Co
mbi
naç
ãoc
ut& f
ai
l

Fi
gur
a4.
21–Co
mandofail p
arao
bri
garno
vape
squi
sa
Ao encontrar o comando c ut , o conjunto de instruções entre os pontos 1e 2não será mais executado. O e
ntr
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
aila seguir, a execução pára, forçando o b acktrak
ingpara a posição 3.
Um exemplo desta combinação está na Fig. 4.22 a seguir:
–46–

Fi
gur
a4.
22–Pr
ogr
amaus
andoac
omb
ina
çãocut & fail
O programa i nvert
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 also; no caso contrário, esta combinação
não será executada, desviando-se para o ramo da terceira linha, que retorna o valor ve rdadei
ro. Este
programa troca o retorno de verdadeiro para falso ou vice-versa. Na segunda parte, aplicamos o programa a
uma tautologia (p(a)impliesp(a)) e o retorno é falso.

4.5.
6–Ní veldepr ofundi dade
Um conceito muito importante para o controle de provas, o de ní veldepr
ofundidade, 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í
veldepr
ofundi
dade
A pr ofundidademá xi
madede duç ã
otem um valor pré-definido que pode ser modificado pelo comando
set
de pt
h(<n>) , onde <n> representa um número natural. Para se descobrir qual o valor corrente existe a
primitiva getdepth(
*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
rif
ic
açã
odoní
velmá
ximodepr
ofundi
dade
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í veldeprof
undidadeestá a noção de dist
ânciaconceitua l.A estruturação
do conhecimento no ambiente W it ty é feita por uma hierarquia de pl anosdec o
nhecimento , 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 ero(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
iadepr
ogr
ama

A chave para a compreensão da programação em Wi ttyé entender o encadeamento da execução dos


comandos dirigidos pelos s e
q üe
nciador(&) e a l
ter
nado
r(|). Um programa em Witty funciona como uma
árvore de decisões como mostrado na Fig. 4.25.

Fi
gur
a4.
25–Di
agr
ama
sdee
xec
uçã
odo
sco
mando
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
fi
niç
ãodef
ato
sàl
apr
ogr
ama
çãoe
mló
gic
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
fprgexige 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
stedec
ondi
çõ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 eqüe nci
ador(&); caso contrário, desviar-se-á para o seguinte a um a lt
ernador(|). A Fig. 4.28 a
seguir, mostra graficamente esta afirmação.

Fi
gur
a4.
28–Se
qüê
nci
aede
svi
ose
ntr
eco
mando
sdeum pr
ogr
ama
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
ai
lpara forçar a listagem todas as instâncias
do predicado é_carioca. Caso não o utilizássemos, o retorno seria apenas a primeira instância (Zi
co).

Fi
gur
a4.
29–Ex
tra
çãodet
oda
sasi
nst
ânc
iasdaBa
sene
stae
str
utur
a
Nas demonstrações seguintes, empregaremos um interessante comando, o t r
ansf, 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:
trans f
(<cade
i a>,<e s
que ma1>, <e sque ma2>, {<*var >|<r eg>})
onde: <cadeia> é a cadeia de caracteres que se deseja transformar;
<esquema1> é o esquema de partida (entre aspas);
<esquema2> é o esquema final desejado (entre aspas);
<*var> | <reg> o resultado da transformação pode tanto ser armazenado em
variável como em outro registro.
–49–

Fi
gur
a4.
30–O c
oma
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 ra nsffaz 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 to
)
constituirão o valor do registro um. De forma idêntica, todo o restante da frase após o “é” (c ur ioso) o do
registro dois. 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
oma
ndotransf
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 doi
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 yprg(<*npr gs>)
onde <*nprgs> é uma variável a qual será atribuida a quantidade de programas ativos.
ge tprg(<nume r
o>,<* var
iável>)
onde <numero> é um inteiro nque identifica o n-ésimo programa;
<*variavel> variável que armazenará o n-ésimo programa.

4.
32–Pr
ogr
amaq
uel
is
tao
sfa
tosàma
nei
raPr
olo
g
No programa acima, a variável * npr gcontém o número total de programas e servirá de controle para
ol oo
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 tprg 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
álogos

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 ske i nput , introduzidos no capítulo anterior, há ainda os representados pelos
comandos pr ompt ,choosee acqbox.
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 menus , um recurso específico para tratamento de taxionomias.

5.
1–Cons
ult
andoous
uár
io:c
omandoas
k

O comando a
skabre a seguinte janela de confirmação:

Fi
gur
a5.
1–J
ane
ladec
onf
ir
maç
ãodoc
oma
ndoask
através de quatro parâmetros com a seguinte sintaxe:
as
k(<me
nsage
m>,
<*r
etor
no>,
<pos
-x>,
<pos
-y>)
onde: <mensagem> é o texto da mensagem a ser exibida na caixa diálogos, sempre uma
pergunta ao usuário;
<*retorno> á 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;
<pos-x> São as coordenadas na tela do vértice esquerdo superior da caixa de
<pos-y> diálogos.
O uso deste recurso já foi demonstrado do capítulo anterior.

5.
2–Conver
sandoc
om us
uár
io: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 skpor permitir a atribuição de um título à janela. Seus parâmetros são:
prompt (<título>,<c onsulta>,*retorno, <pos -x>,<pos -y>)
onde: <título> é a cadeia de caracteres que constituirá o título da janela
<consulta> é 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


ompt
–52–
5.
3–For
mul
ári
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:
input (<e
nt>, <titulo>,op1/ op2/.
..
/opn, <*retorno>, <pos -
x>, <pos-y>)
onde:
<ent> indica quantas entradas possui o campo;
<titulo> é a senteça que aparece no título da caixa de diálogo;
<opn> títulos para campos de formulários (separadas por b a r
ra);
<*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
dro5.
1–Ca
ixa
sdedi
ál
ogo
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
ixadee
ntr
ada

Fi
gur
a5.
4–Re
tor
no
A separação dos campos com a estrura acima não constitui problema, podendo facilmente ser
efetuada com o emprego do comando ma tc
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 ch(<cadeia><esque ma>)
–53–

Figur a5.
5–Us odoc oma ndomatch
Neste exemplo os registros precisaram ser definidos, uma vez que a atribuição de valor a eles deu-se
pelo comando ma tc
h. A representação [ regis
tro]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 asamentodepa drõ
ese funciona da seguinte maneira:

Fi
gur
a5.
6–Co
mandomatch:c
asa
ment
odepa
drõ
es
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 eval
sch, que avalia o esquema resultante (como o listado na
Fig. 5.5), com a seguinte sintaxe:
eval sch( <es que ma>, <* resultado>)
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
nte
rfa
cepa
rae
scr
eve
rar
egr
a
O comando i nputgera a janela Es crevaar egr 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 tchos separa, colocando estes valores nos registros
indicados. Finalmente o e val
sch 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 ssert
, que tem a sintaxe seguinte:
–54–
assert(<nome _banc o>,
<f at
o>|<r egra>)
onde: <nome_banco> é o nome do banco de conhecimento e
<fato> | <regra> é 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.

Fi
gur
a5.
8–Ent
radader
egr
asnab
ase
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
dro5.
2–Pr
ogr
amaEntraRegra2
Para o caso de fatos, deve-se deixar o segundo campo em branco. Neste caso, o comando ma t
cho
representa por um ?(ponto de interrogação). Assim, o teste =( *y,?)funcionará, executando-se o a sser
tda
linha seguinte. Senão, o teste falhará, este a
sse
rtnã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 oráculoe gra máti
ca. Oi nputé indicado para entrada repetitiva de informações para povoar um banco de
conhecimento.

5.
4–Aqui
siç
ãodec
onhec
iment
o:pr
imi
tivaac
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(<titulo>,<pergunta>,<arquivo>,<texto>,
<*analise_do_resumo>,<*tipo>,<*pergunta_mais_opções_de_resposta>,
<*confiança_geral>,<*peso_geral>,<coord-x>,<coord-y>)

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:
<título> Nome da primeira janela;
<pergunta> Conteúdo da primeira janela;
<arquivo> o nome de um arquivo, cujo conteúdo – texto ou imagem – ocupará a janela Documento (a
intermediária);
<texto> é 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 nfi
r ma
;
2 para botão Ne ga;
–55–
3 para botão Pe nde nte
4 para botão . ..De sdobr a, opção De pendê nciafa
ctual
5 para botão . ..De sdobr a, opção De pendê nciaci
rcunsta nci
a l
8 para o botão Adi a
9 para o botão Co nt i
nua
10para o botão Al terna tiva
11para o botão Exe c
uç ão
12para o botão Ab orta
13para o botão Co mpa rtilha
<*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
frão) separa pergunta das respostas; e
/ (barra ) 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 pendênci asfactuais: o texto das respostas, sem modificações;
De pendênci ascircuns tanc i
ais: primitiva de s
c_o ffcom quatro parâmetros:
desc_off( <respos ta>, <ar qui vo>, <c onfi
anç a>, <peso>)
onde:
<resposta> é o texto digitado pelo usuário no quadro Resumo, com substituição de alguns
caracteres reservados, como:
espaçoe mb ranc o trocado por s ubli
nha(_),
pa r
êntesis trocado por c haves({
}) e
vírgula trocado por exclamação (! );
<arquivo> é o endereço completo (com subdiretórios) do arquivo relacionado em
Documento;
<confiança> indica o valor selecionado na janela Co nf i
anç a;
<peso> mostra a escolha da janela Pe so.
<confiança_geral> variável que guarda os valores selecionados para confiança.
De pendê nci
a sf act
ua is
: observa a mesma estrutura da variável acima:
<confiança_geral$conf_ultimo_fator/ conf_penúltimo_fator/ ...>
De pendê nci
a sc i
rcuns tancial: armazena apenas a confiança geral, dado que as demais estarão em
parâmetros do desc_off.
<peso_geral> variável que contém os valores escolhidos para peso, com a mesma estrutura que
<confiança_geral>.
<coord-x>,<coord-y> são os valores, em pixels, da posição do vértice superior esquerdo da janela acqbox.
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
ane
las
impl
if
ic
ada
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
ime
iraj
ane
ladopr
imi
ti
vaacqbox e
xib
indoa
rqui
vodet
ext
o(t
xt)
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
ane
lado
cume
ntodapr
imi
ti
vaacqbox e
xib
indoa
rqui
vodei
mage
m(b
mp)
Dependênc i
asf actuais. 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 iasc i
rcuns t
anc iai
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.
Basedec onhec
iment
o. Abre uma base de conhecimento que será utilizada para comandos que venham em
seguida.

Fi
gur
a5.
12–Asde
pend
ênc
ias

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:
choos e(<titulo>,<op1/ op2/
...
/opn>,<*retorno>, <coor d-x>,<c
oord- y>)
onde: <titulo> é a senteça que aparece no título da caixa de diálogo;
<opn> são as alternativas possíveis do menu (separadas por b arr
a);
<*retorno> é o valor da alternativa selecionada;
<coord-x> são as coordenadas onde se posicionará, na tela, o canto superior
<coord-y> 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
rac
ria
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
ter
nat
iva Bot
ão Val
orderet
orno
Uma opção Confirma A opção
Mais de uma opção Confirma Opções separadas por bar
ras
Nenhuma opção Confirma NONE
Nenhum NONE
Cancel / Esc ?

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 inhos:

Fi
gur
a5.
14–Co
nhe
cime
ntos
obr
epe
ixe
sma
rinho
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 defprg(menu33,retrieve(ret,*x)
% Conhecimentos sobre peixes marinhos & =(*x,Curta)
% sem uso de bases & lsmsg(">>> A espécie é: LINGUADO DO MAR")
& lf & cut & fail)#

defprg(menu1, defprg(menu41,
choose("Local de coleta", "Mar/Rio",*x,25,20) choose("Tamanho do peixe",
& assign(*x,ret) "Grande/Médio/Pequeno",*x,125,100)
& =(*x,Mar) & assign(*x,ret)
& menu2 & cut)# & =(*x,Grande) & menu51 & cut)#
defprg(menu1,retrieve(ret,*x)
& =(*x,Rio) defprg(menu41,retrieve(ret,*x)
& lsmsg("Não há informações sobre peixes de água & =(*x,Médio) & menu52 & cut)#
doce") & lf defprg(menu41,retrieve(ret,*x)
& cut & fail)# & =(*x,Pequeno)
& lsmsg(">>> A espécie é: SARDINHA
defprg(menu2, SARDINHA") & lf & cut & fail)#
choose("Tipo de mar","Alto/Litoral",*x,50,40)
& assign(*x,ret) defprg(menu51,
& =(*x,Alto) & menu31 & cut)# choose("Comprimento das nadadeiras",
defprg(menu2,retrieve(ret,*x) "Longo/Curto",*x,150,120)
& =(*x,Litoral) & assign(*x,ret)
& menu32 & cut)# & =(*x,Longo)
& lsmsg(">>> A espécie é: THYNNUS
defprg(menu31, ALBACORA") & lf & cut & fail)#
choose("Forma básica", defprg(menu51,retrieve(ret,*x)
"Fusiforme/Achatada_ventral/ & =(*x,Curto)
Achatada_lateral/Nenhuma",*x,75,60) & lsmsg(">>> A espécie é: THYNNUS THYNNUS")
& assign(*x,ret) & lf & cut & fail)#
& =(*x,Fusiforme) & menu41 & cut)#
defprg(menu31,retrieve(ret,*x) defprg(menu52,
& =(*x,Achatada_ventral) choose("Padrão de coloração",
& lsmsg(">>> A espécie é: MANTA BIROSTRIS") "Rajado/Uniforme",*x,150,120)
& lf & cut & fail)# & assign(*x,ret)
defprg(menu31,retrieve(ret,*x) & =(*x,Rajado)
& =(*x,Achatada_lateral) & lsmsg(">>> A espécie é: CAVALA CAVALA")
& lsmsg(">>> A espécie é: MOLA MOLA") & lf & cut & fail)#
& lf & cut & fail)# defprg(menu52,retrieve(ret,*x)
defprg(menu31,retrieve(ret,*x) & =(*x,Uniforme)
& =(*x,Nenhuma) & menu62)#
& lsmsg("Não há informações para concluir")
& lf & cut & fail)# defprg(menu62,
choose("Cor aparente",
defprg(menu32, "Cinza/Dourado/Prateado",*x,175,140)
choose("Forma geral", & assign(*x,ret)
"Achatada/Não_achatada",*x,100,80) & =(*x,Cinza)
& assign(*x,ret) & lsmsg(">>> A espécie é: TAINHA TAINHA")
& =(*x,Achatada) & lf & cut & fail)#
& menu33)# defprg(menu62,retrieve(ret,*x)
defprg(menu32,retrieve(ret,*x) & =(*x,Dourado)
& =(*x,Não_achatada) & lsmsg(">>> A espécie é: DOURADO
& lsmsg(">>> A espécie é: OUTROS") SALGADO")
& lf & cut & fail)# & lf & cut & fail)#
defprg(menu31,retrieve(ret,*x)
defprg(menu33, & =(*x,Prateado)
choose("Tipo de cauda", & lsmsg(">>> A espécie é: AGULHA MARÍTIMA")
"Longa/Curta",*x,125,100) & lf & cut & fail)#
& assign(*x,ret)
& =(*x,Longa) choose("Conhecimentos sobre peixes marinhos.
& lsmsg(">>> A espécie é: RAJA RAJA") Prosseguir?", "Sim/Não",*x,0,0)
& lf & cut & fail)# & =(*x,Sim)
& menu1 & cut#

Quadr
o5.
3–Pr
ogr
amademe
nuss
obr
epe
ixe
smar
inhos

Um dos possíveis resultados de sua execução está na Fig. 5.15 da página seguinte:
–60–

Fi
gur
a5.
15–Re
sul
tadodae
xec
uçã
odeme
nuspa
rac
onhe
cime
ntoc
las
sif
ic
ató
rio
–61–

6.
Orác
ulos

6.
1–Def
ini
çõeseConc
eit
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 clopédiaLar ousseCul tur
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, <fórmula>)
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 <fórmula> é 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
sedec
onhe
cime
ntoc
om da
dosi
nsuf
ic
ient
es
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 ackt
racking. 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 berto
. 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 stema em Mundo Ab erto. A
construção destes sistemas pode estar baseada tanto nesta hipótese como na do MundoFe cha 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
ácul
onã
oat
iva
do:de
duç
ãos
obahi
pót
esedemundof
echa
do
Por outro lado, quando se admite a hi póte
sedomund oaberto(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
ácul
oat
iva
do:
deduç
ãos
obahi
pót
esedemundoa
ber
to
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
ácul
osnoWi
tt
y

A passagem de parâmetros no Witty é efetuada através de um mecanismo denominado r egi


stro,
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
ent einstalado, 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 ca rac
te resreserva dosque não podem ser usados diretamente. Seus valores são os seguintes: [acent] '
(apóstrof
o); [number] # (núme r
o ); e [quote] "(as pa
s).
Um or ácul 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 bert
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,
oracul o1. Neste caso, seria:
defprg(oraculo1(*x,*y,*z), <corpo do programa> )#
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 <corpo do programa> é um ou mais comandos, incluindo ou não referências a outros programas.
O código escrito em <c orpodopr ograma> deverá ser ativado para que haja a sua execução, através da
primitiva s eto
ra cl
e(<o ráculo>).
Em sentido inverso, a primitiva r stor
acl
e(<o r
á cul
o >), 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
dro6.
1–Um o
rác
ulos
impl
es
A base desta solução está no comando a
skvisto no capítulo anterior e cujo código de retorno está na
tabela a seguir:

Com ando ask


Respost adousuár i
o Códi
goder
etor
no
SIM (afirmativa) 0
NÃO (negativa) 1
IGNORO 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:
evals
ch( “Vo cês abes e[ l
it
]?”,*pe
rg) . 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.
ask(*
pe rg, *
ret
,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.
=(*ret
,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–
cut. 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 êsa beseé_racional(
Ze z i
nho
)?

Fi
gur
a6.
4–Ca
ixadedi
ál
ogoa
cio
nadape
loo
rác
ulo
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 faul
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 racof
f(<pr edic
a do>)e o racon(
<predic
a do
>). Desta forma, pela adição de o racof
f(raci
onal)# 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 at
ino -
ameri
ca noquenãos e
jabrasil
eiro,falaes
pa nhol
.
Sel atino(
* x)enãob ras
ile
iro
(*x)entãofal
a_e s
pa nhol
(*x).
Com isso, poderemos montar a seguinte consulta:

Fi
gur
a6.
5–Ba
ses
obr
ela
tino
-ame
ric
ano
s
Se mantivermos o mesmo or aculo1ativado, 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: sim
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 sim
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 sim
defprg(oraculo2(neg,*y,*z),
retrieve(ret,*ret)
& <>(*ret,0)
& oracoff(*y)
& cut & fail)#
setoracle(oraculo2)#
oracoff(fala_espanhol)#

li
nhadecomando:
prove(sup,fala_espanhol(Juan)) & lsmsg(SIM) | lsmsg(Não)

Qua
dro6.
2–Or
ácul
oquet
rat
afa
tosne
gat
ivo
s
As novidades são o uso da primitiva <> (sinais combinados de me norquee de maio
rq ue
, significando
diferent e), verificando se o retorno não foi zero, além do uso do comando or ac
off(
*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
raco
n(<pre
dica
do>).
Neste caso, a execução do programa leva à caixa de diálogo a seguir

Fi
gur
a6.
6–Ca
ixadedi
ál
ogob
asel
ati
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, oráculos ema pre
ndizado(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
que
madeum o
rác
ulos
ema
pre
ndi
zado
Esta definição de oráculo funciona para ajudar a resolver uma dedução, contudo é ineficiente para o
objetivo de aqui siçãodec onhecime nto, 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
que
madeum o
rác
uloc
oma
pre
ndi
zado
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 % Parte negativa resp: sim
newbase(anexa)#
defprg(oraculo3(neg,*y,*z),
% base para guardar dados aprendidos
assign(*y,lit)
% Parte positiva resp: sim (retorno 0)
& evalsch(“Você sabe se não [lit] ?”,*perg)
defprg(oraculo3(pos,*y,*z),
& ask(*perg,*ret,100,100)
assign(*y,lit)
& assign(*ret,ret)
& evalsch(“Você sabe se [lit]?”,*perg)
& =(*ret,0)
& ask(*perg,*ret,100,100)
& assert(anexa,not *y)
& =(*ret,0)
& oracoff(*y)
& assign(*ret,ret)
& cut)#
& assert(anexa,*y)
& oracoff(*y)
% Parte negativa resp: não
& cut)#
defprg(oraculo3(neg,*y,*z),
% Parte positiva resp: não (retorno 1)
retrieve(ret,*ret)
defprg(oraculo3(pos,*y,*z),
& =(*ret,1)
assign(*y,lit)
& retrive(lit,*y)
& retrive(ret,*ret)
& assert(anexa,*y)
& =(*ret,1)
& oracoff(*y)
& assign(*ret,ret)
& cut & fail)#
& retrive(lit,*y)
& assert(anexa,not *y)
% Parte positiva resp: ignoro
& oracoff(*y)
defprg(oraculo3(pos,*y,*z),
& cut)#
retrieve(ret,*ret)
% Parte positiva resp: ignoro (ret 2)
& =(*ret,2)
defprg(oraculo3(pos,*y,*z),
& oracoff(*y)
retrieve(ret,*ret)
& cut & fail)#
& =(*ret,2)
setoracle(oraculo3)#
& oracoff(*y)
oracoff(fala_espanhol)#
& cut & fail)#

li
nhadecomando:
prove-in(sup,anexa,espanhol,fala_espanhol(Juan)) & lsmsg(SIM) | lsmsg(Não)
Qua
dro6.
3–Or
ácul
oquea
pre
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
brasi
leiro(Juan).
Novas consultas poderão apresentar respostas inesperadas, devido à inibição do predicado ‘brasileiro’
através de o rac of
f(
*y), evitando a repetição da pergunta. Para executar novos testes, execute na janela de
comandos o rac o
n(brasile
iro).
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 sistente, 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
sist
ent
e % Negativo - sim
defprg(oraculo4(neg,*y,*z),
% Base para ignoro assign(*y,lit)
newbase(ignoro)# & evalsch(“Você sabe se não [lit]?”,*perg)
% Base para categóricas & ask(*perg,*ret,100,100)
newbase(anexa)# & assign(*ret,ret)
% Positivo - sim & =(*ret,0)
defprg(oraculo4(pos,*y,*z), & assert(anexa,not *y)
assign(*y,lit) & oracoff(*y)
& evalsch(“Você sabe se [lit]?”,*perg) & cut)#
& ask(*perg,*ret,100,100) % Negativo - não
& assign(*ret,ret) defprg(oraculo4(neg,*y,*z),retrieve(ret,*ret)
& =(*ret,0) & =(*ret,1)
& assert(anexa,*y) & assert(anexa,*y) & oracoff(*y)
& oracoff(*y) & cut)# & cut & fail)#
% Positivo - não % Sem sinal - ignoro
defprg(oraculo4(pos,*y,*z), defprg(oraculo4(*x,*y,*z),retrieve(ret,*ret)
retrieve(ret,*ret) & =(*ret,2)
& =(*ret,1) & assert(ignoro,*y) & oracoff(*y)
& assert(anexa,not *y) & cut & fail)#
& oracoff(*y) setoracle(oraculo4)#
& cut & fail)# oracoff(fala_espanhol)#
li
nhadecomando:
]
prove-in(sup,anexa,espanhol,fala_espanhol(Juan)) & lsmsg(SIM) | lsmsg(Não)

Qua
dro6.
4–Or
ácul
ope
rsi
ste
nte
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á-
diss
eabaixo, tem esta função.

defprg(já-disse(*x),prove-in(sup,anexa,ignoro,*x)
& cut & fail)#
defprg(já-disse(*x),cut)#

Qua
dro6.
5–Pr
ogr
amae
vit
are
pet
içã
odepe
rgunt
as
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.
Gramát
icas

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álidos Invál i
dos
[quem] faz [o_que] ola]
[um] ama [quem] ama [um] [cidade] é capital de [país
[um]

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 Esquema
José faz mesas [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(<cadeia>,<esquema>)
retorna com sucesso se <cadeia> pertencer ao padrão definido por <esquema>. Além disso, como efeito
colateral, as subcadeias da <cadeia> 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
time
ntodee
sque
ma
Para se recuperar as cadeias de caracteres capturadas pelos registros deve-se usar o procedimento
r
etr
ieve
(<regis
t ro>,<vari
á vel>)
.
Na Fig. 7.2 (pág. seguinte), mostramos os procedimentos e seu resultado em Visor.

Fi
g.7.
2–Exe
mpl
odous
odee
sque
mas

7.
1–Dec
lar
açãodeRegi
str
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( <r
egistro>,<método>,<progr
ama>)
onde
–70–
<registro> denota o nome do registro que será criado, sendo o único obrigatório;
<método> 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 wreg( r
eg01, 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 ch e eval s
ch, por
exemplo. O comando as s
igncria um registro deste tipo.

7.
2–Us
odeexpr
ess
õesr
egul
aresnomé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
ntodee xcl
ama ção
), para serem
diferenciadas de outras opções possíveis para o mé t
odo
. Os metacaracteres utilizados para expressar uma
linguagem regular estão reunidos na lista a seguir:

Expr
essão Cadei
aresul
tant
e
ba* Iniciada com “b”, seguido de zero ou mais “a”s
(a|e|i|o|u)* Qualquer seqüência que só possua vogais, incluindo a cadeia vazia
{[az]}* Contém um número finito de caracteres entre a e z, incluindo a cadeia
vazia
{09}{09}* Todos os números naturais

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
ess
õesr
egul
are
s

7.
3–Us
odear
qui
vosnomét
odo

O comando newreg permite um nível de tradução adicional. No formato


newreg(<registro>,”@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 inc o”):

Fig.7. 4–Tr a
duç ãoa travésdoc
oma
ndone
wre
g
Os exemplos a seguir ilustram a utilização de registros.

Fi
g.7.
5–Re
gis
tronã
out
il
iz
andomé
todo
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
gis
troq
uede
fi
nee
sque
maa
sso
cia
doapr
ogr
ama
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
gis
troc
om mé
todoep
rog
rama
–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 –
casamentoe pr ogra
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
stemasdePr
ost
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 gem 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 ist
emadepr oduç ãodePr o stS é 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 Exempl 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
mplo7. 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
icas

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
grasdet ra dução
. Uma regra de tradução é uma
tripla
<esquema1,esquema2,esquema3>
onde o e squema 1é utilizado para casar com a cadeia objetivo corrente. O es
quema3é um programa que será
executado, caso o casamento com o esquema1 seja bem sucedido, em alguns casos afetando a tradução.
Finalmente, o e squema 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 squema 2de e s
quemadet raduçã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
ica Esquema
[suj] [verbo] [comp]# esquema1
[verbo]([suj],[comp])# esquema2
programa (externo ou do Witty)# 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 ro). A figura a seguir resume o funcionamento das gramáticas no Witty:

Fi
g.7.
8–Func
iona
ment
odagr
amá
tic
a
Devido à sua grande importância e complexidade, as gramáticas também poder ser visualizadas de
forma mais estruturada no Amb ienteinstalado, separando seus diversos componentes, conforme exibido a
seguir.

Fi
g.7.
9–Exi
biç
ãoda
sgr
amá
tic
asa
tiva
snoAmb
ient
eins
tal
ado
–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(<cadeia>,<gramática>,<variável>)
onde: <cadeia> cadeia de entrada que será traduzida;
<gramática> nome lógico da gramática que será usada; e
<variável> variável que receberá o resultado da tradução.
Já vimos a associação de expressõesregularesa 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
nte
nçat
raduz
idapa
raaf
ormal
ógi
ca
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-te-
vi,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
amá
tic
aques
óat
ivaopr
ogr
ama(
semt
raduç
ã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 ysc al
l, conforme pode ser visto na janela
Ambiente instalado. Este comando tem a forma
syscall(<programa>,<inteiro>,<variável de retorno>)
onde: <programa> é o nome de um processo com os parâmetros necessários para chamada a execução,
sem interromper o processamento do Witty;
<inteiro>:
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;
<variável de retorno> é 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
amá
tic
aquea
tivapr
imi
ti
vadoWi
tt
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
amá
tic
aco
mtr
aduç
ã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
qui
vodagr
amá
tic
aco
mtr
aduç
ã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] [sujeito] [verbo] [artigo1] [predicado]


o rapaz ama a 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
squi
sadepa
lavr
as-
cha
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
ate
gor
ias
). Assim, ao processar a sentença de entrada
O aperfeiçoamento da i
ntel
igê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
nte
údodo
sre
gis
tro
sapó
sca
same
ntodepa
drõ
es
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
qui
vosdea
sso
cia
çã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
amá
tic
aapl
ic
adaab
usc
adepa
lavr
acha
vee
mse
nte
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
amá
tic
aens
ina
–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
ogr
amaq
uemo
ntano
mer
andô
mic
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
ic
açã
odagr
amá
tic
aae
stet
ext
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
biç
ãodet
ext
oal
eat
óri
oso
brea
ssunt
ode
tet
adopo
rpa
lavr
a-c
have
–79–

8.
Comuni
caç
ã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
ervidor
. De forma simplificada,
servidor é qualquer equipamento que resolva uma requisição de um outro, denominado c l
ie
nte, devolvendo
a este o resultado de uma consulta.

8.
1–TCP/
IP

8.1.1–Funç ãos ervidor


Há uma opção s ervidordo Witty, ativada através do menu Fe r
rament as, 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 Redeno Pa ineldeControle, selecionando
a opção TCP/ IP- >Ada pta
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(<computador>,<porta>,”<comando>“,<variável de retorno>)
onde: <computador> é o nome de rede onde reside o servidor; caso esteja rodando isoladamente (sem nome
de rede), pode ser utilizado o nome l ocalhos
t.
<porta> é um número entre 5000 e 9000 determinando a porta de comunicação. O par c omputador
-
po r taé univocamente identificado.
<comando> é 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.
<variável de retorno> 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º Descr i
çãodocomando Sint
axe
0 Mostre o conteúdo de uma base tamanho da cadeia,0,”conteúdo da base”, 0|1 (0 ativa; 1 desativa)
7 Mostre mensagem assincrona tamanho da cadeia,7,”mensagem”
8 Mostre caixa de diálogo tamanho da cadeia,8, ID do tipo de diálogo (vert
abelaabai xo)
9 Mostre mensagem de erro tamanho da cadeia,9,”mensagem de erro”

Tipos de diálogos síncronos


Nº Comando Sintaxe Ret orno
0 msg 0,”cadeia da mensagem”, posx,posy —
1 ask 1,”cadeia da mensagem”,”pergunta”,posx,posy tamanho da cadeia,
0 = sim, 1 = não, ou 2 = desconheço.
2 prompt 2,”titulo do diálogo”,”pergunta”,posx,posy tamanho da cadeia, “cadeia de resposta”
3 input 3,”pergunta”,”opções separadas por /”, tamanho da cadeia, “resp. separadas por /”,
“numero de boxes para texto”,posx,posy (respostas em branco retornam ?)
4 choose 4, pergunta”,”opções separadas por /”, posx,posy tamanho da cadeia,“resp. separadas por /”
5 acqbox 5,”cadeia da pergunta”,posx,poxy tamanho da cadeia, 1|2|3|4, “respostas
separadas por /”,valor de confiança inteiro
6 sendsync 6,”cadeia de comando” 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
rvi
dorWi
tt
y

8.1.2–Ár eadet rans f


erência
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
lient
eser
vidorWi
tt
y

Nesta seção explicaremos a construção de uma interface (programa cliente) para o WittyAcadêmico,
na linguagem Vi s
ua lBasic(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
nte
rfa
cedec
omuni
caç
ãopa
drã
oes
cri
tae
m VB
Esta interface oferece um primeiro módulo que contém uma J a
ne l
adec oma ndoas ere nvia
daaos er
vido r
e o botão Exe cutac oma 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 oc
alhoste 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 rm) mostrados na figura a seguir:
–81–

Fi
g.8.
3–El
eme
nto
sgr
áfi
cosdopr
oje
toCl
ie
ntePa
drã
o
A Fig. 8.3 exibe o formulário f
rmCl
ie
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
rmul
ári
os, 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
tadoSe
rvi
dordoWi
tt
ynapo
rtapa
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 Descr i
çãodocomando Sint axe
0 Mostre o conteúdo de uma base de tamanho da cadeia,0,"cadeia do conteúdo da base",0|1
conhecimento (ativa|desativa)
1-6 desativadas
7 Mostre mensagem assincronamente tamanho da cadeia,7,"cadeia da mensagem"
8 Mostre caixa de diálogo tamanho do cadeia,8,ID do tipo de dialogo (tabela abaixo)
9 Mostre mensagem de erro 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 Comando Si
nt axe Retorno
0 msg 0,"cadeia da mensagem",pos x,pos y sem retorno
1 ask 1,"cadeia da mensagem",pos x,pos y tamanho cadeia, 0 = "Sim" | 1 = Não"
| 2 = "Desconheço"
2 prompt 2,"titulo dialogo","cadeia pergunta",posx,posy tamanho cadeia, "cadeia resposta"
3 i
nput 3,"cadeia da pergunta","cadeias das opções tamanho do cadeia,"cadeia das
separadas por /",numero de caixas de textos,pos respostas separadas por /"
x,pos y (as em branco voltam com ?)
4 choose 4,"cadeia da pergunta","cadeias das opções tamanho do cadeia,"cadeia das
separadas por /" ,pos x,pos y respostas separadas por /"
5 acqbox 5,"cadeia da pergunta",pos x,pos y tamanho do cadeia, 1|2|3|4, "cadeia
das respostas separadas por /",valor de
confiança inteiro
6 sendsync 6,”cadeia de comando” 0, se conseguir executar
1, em caso contrário
Ta
bel
a8.
1–Pr
oto
col
odec
omuni
caç
ãoc
om os
ervi
dorWi
tt
y
O Viso
rnormal do programa listará toda a comunicação entre o cliente e o servidor, funcionando
como um l
ogda execução, como mostrados nos exemplos de diálogos permitidos pela interface.

Fi
g.8.
6–Vi
sorc
omolog dac
omuni
caç
ão
Iniciaremos pela caixa de diálogos Li
stadeMe
nsa
gem:

Fi
g.8.
7–Ca
ixa
sdedi
ál
ogopa
rae
xec
uçã
odoc
oma
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” 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.
enviando mensagem 6,12,”1” 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
ixa
sdedi
ál
ogop
arae
xec
uçã
odoc
oma
ndomsg
conexão aceita
recebendo mensagem msg(ok,100,100)
enviando mensagem: 16,8,0,”ok”,100,100” 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
100,100indica as coordenadas do vértice
enviando mensagem 6,12,”1” Este comando exige um retorno do usuário; assim esta linha
ocorrerá somente após o clique no Vi
sto.
conexão fechada

A seguir, discutiremos a caixa de diálogos para o comando pr


ompt
. Neste caso, será emitida uma
pergunta, a que o usuário poderá responder em uma janela.

Fi
g.8.
9–Ca
ixa
sdedi
álo
gopa
rae
xec
uçã
odoc
oma
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 Lis
tadeMe nsagens , com o texto informado.

Fi
g.8.
10–Co
nti
nua
çãododi
ál
ogo

Fi
g.8.
11–Ca
ixadedi
ál
ogoask
No exemplo acima, a execução do comando a skproduz a caixa de diálogo Co ns ult
a, que reproduz a
pergunta efetuada e permite três alternativas de resposta: Si m,Nã oe De sconheç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 ListadeMe nsagens .
O Comando a cqb oxé 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 ist
adefa tosou de outra b asedec onhecimento).
–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
qboxdo 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 cqboxpara o caso mais simples, de retorno s im, nãoou
desconhe ci
do, listando-se a segunda variável (*y) que armazena o t ipoda resposta do usuário, que informa o
botão pressionado.

Fi
g.8.
12–Us
odoacqbox
Caso se pressionasse nos botões De pende ntee Listadef a
tos, seria aberta a janela I
nsi
rai
tem para
entrada destes fatos. A janela inferior lista os dois últimos fatos informados. Encerra-se com o botão Adqui
ra
(ou Cancel
a).

Fi
g.8.
13–De
pendê
nci
afa
ctua
l

Fig.8.14–Va loresdava r
iáve
ltipo,conformer espo
stadous
uário
Na Fig. 8.14 acima estão demonstrados os valores da segunda variável (tipo
) 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
oce
ssa
ment
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 nsir
ai tem. 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 pendentee, a seguir, Ba seexist
ente. 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 liente.vbp) em Visual Basic.

Fi
g.8.
16–De
pendê
nci
adeBa
see
xis
tent
e
–87–

Fi
g.8.
17–I
nte
gra
çãoc
li
ent
e-s
ervi
dorpa
raade
pendê
nci
adeb
asee
xis
tent
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 get-
cle put -cl
. 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”>,<variável de retorno>)
A Fig. 8.18 a seguir explora este recurso.

Fi
g.8.
18–Co
mandos
ends
ync
–88–
Li
stagem dopr
ogr
amapr
inc
ipal
Global vez As Integer
Global ent_comando As String
Global volta As String
Global 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 é <num>,<restante da entrada> então func = <num>

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, Len(entrada) - pos)
pos = InStr(1, entrada, Chr(34))
func = Mid$(entrada, 1, pos - 1)
entrada = Mid$(entrada, pos + 1, Len(entrada) - pos)
prompt.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)
prompt.txtperg.Caption = func
prompt.Show

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
vidorpadr
ão

Esta interface, escrita na linguagem Vi s


ua lBa si
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
nte
rfa
cedoSe
rvi
dorpa
drã
oes
cri
tae
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 cebendoestá 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 rtpermite que se modifique o valor da porta, cujo de f
aulté 5000. Neste caso, basta escrever o novo número
e pressionar o botão At ual
iza. Os três botões inferiores permitem modificar o conteúdo da janela superior. O
valor padrão é o do meio, Mo nito r
. O da esquerda, Te xto, modifica-a para expor o retorno do comando
lsms g; o da direita, Fi
gura, apresenta o retorno de mos tr
af ig, 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 pode-
se enviar comandos para serem executados no servidor.
O servidor deste exemplo, foi programado para aceitar:
§ Mensagens de texto (l sms g);
§ Exibição de figuras (mos t
raf ig);
§ 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
nte
rfa
cegr
áfi
cosdopr
oje
toSe
rvi
dorPa
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
cuç
ãodopr
ogr
amatcp.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 sms gaí executado não é a primitiva Witty.

Fi
g.8.
22–Exe
cuç
ãodopr
ogr
amalsmsg.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
traf
ig,
neste caso restrito a arquivos padrão BMP.

Fi
g.8.
23–Exe
cuç
ãodopr
ogr
amamostrafig.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
cuç
ãodopr
ogr
amasome.prg
–94–
–95–
Bi
bli
ogr
afi
a

AIKINS, J S. Pr
oto
typi
calk
nowl
edgef
ore
xpe
rts
yst
ems
. Artificial Intelligence 20(2):163-210, feb 83.
ALLEN, J., Na
tur
alLa
ngua
geUnde
rst
andi
ng, New York, The Benjamin/ Cummings Publishing Company, 1987.
BEARDON, D. L. & HOLMES,G., Na
tur
alLa
ngua
gea
ndCo
mput
ati
ona
lLi
ngui
sti
cs:a
nInt
roduc
tio
n. Ellis Horwood Limited, New York, NY,
1991.
BENNET, J. S., ROGET:A Kno
wl edge-Ba seadSyst
emf
orAc
qui
ri
ngt
heCo
nce
ptua
lSt
ruc
tur
eofaDi
agno
sti
c,Ex
per
tSys
tem. In Journal of
Automated Reasoning 1, 49-74, 1985.
BENNETT, J et alii. Ak
nowl
edg
e-b
ase
dco
nsul
tantf
ors
trut
ura
lana
lys
is.Stanford Un, Ca., sep 78 (Computer Science Dept).
BISWAS, G et alii. Kno
wle
dge
-as
sit
eddo
cume
ntr
etr
iva
l. Journal The Am Soc for Info Science, 38(2):83-110, 87.
BRACHAMM, R. J., ILi
edAb
outt
heTr
ees
, AI Magazine, Vol. 6, (3), pp. 80-93, Fall, 1985.
BRAGA, J. L., EPISTEME-Aq ui
si ç
ãoeEs
trut
ura
çãoAut
omá
tic
asdeCo
nhe
cime
nto
, Tese de D.Sc., Pontifícia Universidade Católica, Rio de
Janeiro, RJ, Brasil, 1990.
BUNGE, M., Sc
ient
if
icRe
sea
rchITh
eSe
arc
hfo
rTr
uth, New York, Springer-Verlag, 1967.
BUNGE, M., Tr
eat
iseo
nBa
sicPh
ilo
sop
hy,Vo
lumeI
,Se
mant
icsI
:Se
nsea
ndRe
fer
enc
e, Dordrecht, D. Reidel Publishing Company, 1974.
CARNAP, R., I
ntr
oduc
tio
ntoSy
mbo
licLo
gica
ndi
tsApp
lic
ati
ons
, New York, Dover Publications, 1958.
CARNAP, R., TheLo
gicSt
ruc
tur
eoft
heWo
rld
, 2nd Edition, Los Angeles, University of California Press, 1969.
CARVALHO, F M S et alii. Lí
nguapo
rtugue
sanal
inhadei
nfo
rma
çõe
sdoCo
mér
cioExt
eri
or. Simp Bras IA, Anais 4º, p. 299-306, Uberlândia,
out 87.
CARVALHO, R. L., Abst r
ac tSe ma nt
ica
lSys
tems
, Relatório Interno LNCC no 008/90, Laboratório Nacional de Computação Científica,
Rio de Janeiro, RJ, 1990.
CARVALHO, R. L., Si
stema sc om Bas
edeCo
nhe
cime
nto
, Relatório Interno LNCC s/no, Laboratório Nacional de Computação Científica,
Rio de Janeiro, RJ, 1991.
CHOMSKY, N. As
pec
tosdaTe
ori
adaSi
nta
xe. A. Amado Editor, Coimbra, Portugal, 1965.
FERREIRA, A C. DOUTOR:ums
ist
emadea
uxí
li
oàd
iagno
se. PUC/RJ, Dep. Informática, fev 86 (dis. mestrado).
GENARO, S. Si
ste
mase
spe
cia
lis
tas
:oc
onhe
cime
ntoa
rti
fi
ci
al. 1ª ed., Rio, 86, LTC, 192 p.
GREEN, C C. Thea
ppl
ic
ati
ono
fthe
ore
mpr
ovi
ngt
oque
sti
on-
ans
wer
ings
yst
ems(
QA3)
. Stanford AI Project, june 69, 162 p. (PhD Thesis).
LENAT, D P. EURI
SKO:
apr
ogr
amat
hel
ear
nsne
whe
uri
st
ica
nddo
mai
nco
nce
pt. AI, 21(1983):51-89, 83.
LOBATO, L. M. P., Si
nta
xeGe
rat
ivad
oPo
rtuguê
s:daTe
ori
aPa
drã
oàTe
ori
adaRe
gênc
iaeLi
gaç
ão. Vigília Editora, Belo Horizonte, MG, 1986.
LYONS, J., I
ntr
oduc
tio
ntoThe
ore
tic
alLi
ngui
sti
cs, New York, Cambridge University Press, 1968.
MARTINEZ, R. Pr
ogr
ama
cio
nem Re
gla
sdePr
oduc
cio
n­unaI
ntr
oduc
cio
nal
osSi
ste
masdePr
oduc
cio
nes
. Campinas, Vieira Gráfica e Editora,
1991.
MCT/CONI/SEI. ISe
miná
riodeI
nte
li
gênc
iaAr
tic
ial
:pe
rspe
cti
vab
ras
il
ei
ra. Brasília, out 85.
MINSKY, M., AFr
ame
wor
kfo
rRe
pre
sent
ingKno
wle
dge
, In The Psychology of Computer Vision, McGraw-Hill, New York, 1975.
MONTEIRO, S. L., Um Sub conjuntoRe gulardoPo
rtuguê
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
oma
tedGe
ner
ati
ono
fMo
del
-Ba
sedKno
wle
dgeAc
qui
si
ti
onTo
ols
, London, Pitman, 1989.
NEWELL, A., TheKno
wle
dgeLe
vel
, In: Artificial Intelligence, v. 18, no 1 (Jan), pp. 87-127, 1982.
NILSSON, N J. Pr
inc
ipl
eso
far
ti
fi
ci
ali
nte
ll
ige
nce
, 1ª ed., Berlin, 82, Springer-Verlag, 228 p.
NOLT, J.& ROHATYN, D.
Lógi
ca, Editora McGraw-Hill, São Paulo, Brasil, 1991.
OGDEN, C. K.& RICHARDS, I. A., TheMe
ani
ngo
fMe
ani
ng, London, Ark Paperbacks, 1923.
OLIVEIRA, C. M. G. M., AnAr chi
tec
turef o
rLa belledTh e
ore
m Pr
ovi
ngThe
ore
tic
alAs
pec
tsa
ndI
mpl
eme
nta
tio
n, Ph.D. Dissertation, The
University of London, London, England, 1995.
OLIVEIRA, A. P., Casame ntodePa dr õ
ese m Amb
ient
epa
raPr
oce
ssa
ment
odeCo
nhe
cime
nto
, Tese de D.Sc., Pontifícia Universidade Católica,
Rio de Janeiro, RJ, Brasil, 1996.
POLIT, S. R1a
ndb
eyo
nd:AIt
echno
log
ytr
ans
fera
tDEC. The AI magazine, winter 85.
PONTES, R. C. V., Aq
uis
içã
odeCo
nhe
cime
ntopo
rMá
qui
nas
, Tese de M. Sc., Instituto Militar de Engenharia, Rio de Janeiro, RJ, Brasil,
1990.
POPPER, K. R., Ob
jec
tiv
eKno
wle
dgeAnEv
olut
iona
ryApp
roa
ch, Revised Edition, Oxford, Clarendon Press, 1979.
QUENTAL, V., Li
nguí sti
caCo mput a ci
onal–A Ge r
açãoAut omá ti
cadeTe xto
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
arni
ngEf fi
cientCl assifi
cati
onProceduresa ndThe irApp li
ca ti
ont oChe ssEndGa 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.
Int
eli
gênc
iaAr
tif
ic
ial
, São Paulo: McGraw Hill, 1994.
SCOWN, S J. Thea
rti
fi
ci
ali
ntge
ll
ige
ncee
xpe
rie
nce
:ani
ntr
oduc
tio
n. Digital Equip. Co., 85 180 p.
SILVA, J. L.T., Utili
zaçãodoPa ra di
gmadeMul ti
a ge
nte
snoPr
oce
ssa
ment
odaLi
ngua
gem Na
tur
al,Tese de M. Sc., Pontifícia Universidade
Católica, Porto Alegre, RS, Brasil, 1997.
–96–
SOUZA, E. M. M., Um Ve rifi ca
dorGra
mat
ica
lpa
raum Sub
conj
unt
odaGr
amá
tic
adaLí
nguaPo
rtugue
sa, Tese de M.Sc., COPPE/UFRJ, Rio de
Janeiro, RJ, Brasil, 1997.
SOWA, J F. Co
nce
ptua
lst
ruc
tur
es:i
nfo
rma
tio
npr
oce
ssi
ngi
nmi
nda
ndma
chi
ne.
, 1ª ed., Reading Mass., 84, Addison-Wesley, 481 p.
VALERIO, J. D. P., Us
odeOr
ácul
osnaAq
uis
içã
oAut
omá
tic
adeCo
nhe
cime
nto
, Tese de D. Sc., COPPE/UFRJ, Rio de Janeiro, RJ, Brasil, 1998.
VALERIO, J. D. P., Val
ida
çãoeMa
nut
enç
ãoe
m Ba
sesdeCo
nhe
cime
nto
, Tese de M. Sc., Instituto Militar de Engenharia, Rio de Janeiro, RJ,
Brasil, 1990.
van MELLE, W. Ado
mai
ns-
inde
pende
tpr
oduc
tio
n-r
ules
yst
emf
orc
ons
ult
ati
onpr
ogr
ams
. Proc IJCAI-79, 79 p. 923-925.
van MELLE, W et alii. EMYCIN:ak nowledgee ngi
neer'sto
olforc ons truti
ngr ul
e-b
ase
dexp
erts
yst
emsI
n:Rul
e-Ba
sedEx
per
tSys
tems(ed.
Buchanan & Shortliffe). New York, 84, Addison-Wesley, p. 302-328.
VLEDUTS-STOKOLOV, N. Co nceptr
eco
gni
ti
oni
naa
uto
mat
ict
ext
-pr
oce
ssi
ngs
yst
emf
ort
hel
if
esc
ienc
es.Journal The Am Soc for Info
Science, 38(4)269-287, 87.
WATERMAN, D A & PETERSON, M A. Mo
del
sofl
ega
lde
cis
ion-
mak
ing.
RAND Co, 81 (REport R-2717-ICJ).
WINSTON, P H. Ar
tif
ic
iali
nte
ll
ige
nce
. 2ª ed., Reading Mass., 84, Addison-Wesley, 524 p.