Representação do conhecimento híbrida com regras e objetos André Novaes, Bruno Jamir Jacques Robin CIn-UFPE Roteiro Motivação da integração regras + objetos Variedades de integração JEOPS: um sistema de produção embutido em Java Flora: uma extensão orientada a objetos de Prolog Comparação JEOPS X Flora FRC híbridos regras+objetos: motivação Pontos fortes dos sistemas baseado em regras fornece com built-in dedução lógica da 1a ordem com negação por falha um mecanismo de inferência poderoso e o mais versátil de todos com semântica formal que pode também servir de base para implementação de outros mecanismos como abdução, indução, planejamento, raciocínio não monótono usam regras que: são intuitivas e modulares preservam a verdade (detachment) pode ser adquiridas por aprendizagem de máquina Pontos fracos dos sistemas baseado em regras codificação não intuitiva do conhecimento terminológico e procedimental quase nenhuma facilidade para estruturação de entidades complexas limitações das ferramentas e metodologias de desenvolvimento distribuído em larga escala pouca padronização poucos serviços computacionais não de IA implementados com regras interoperabilidade limitada com outras linguagens FRC híbridos regras+objetos: motivação Pontos fortes dos sistemas orientado a objetos como FRC codificação intuitiva do conhecimento terminológico e procedimental facilidade para estruturação de entidades complexas ferramentas e metodologias de desenvolvimento distribuído em larga escala consolidadas e muito difundidas API para os mais variados serviços computacionais e linguagens ênfase na padronização, interoperabilidade e reuso Pontos fracos dos sistemas orientado a objetos como FRC sem máquina de inferência built-in de propósito geral qualquer mecanismo de inferência além da herança deve ser implementado de zero parte comportamental codificada de maneira procedimental ausência da técnicas de aprendizagem de máquina de classes e objetos sem semântica formal FRC híbridos regras+objetos: almejar “o melhor dos 2 mundos” Requisitos Raciocino: • Linguagem declarativa • Predicados com variáveis lógicas • Dedução automática • Semântica formal • Completude computacional Requisitos OO: • Identidade de objetos • Objetos complexos • Classes • Encapsulamento • Herança • Sobrescrita e sobrecarga FRC Híbrido Regras + Objetos Formalismos de Representação do Conhecimento Híbridos Regras + Objetos Inferência Baseada em Regras Inferência Baseada em Modelagem Orientada a Objetos Frames Sistemas de Produção Linguagem de Programação Orientada a Objetos Programação em Lógica Sistemas de Produção com Frames Sistemas de Produção Embutidos em Linguagem Orientada a Objetos EOOPS Programação em Lógica Orientada a Objetos OOLP Lógicas Descritivas Programação em Lógica Descritiva Formalismos de Representação de Conhecimento Escaláveis e Persistentes Híbridos Regras + Objetos Inferência Baseada em Regras Serviços de Banco de Dados Sistemas de Produção BD Ativos BD Relacional BD Ativos OO BD ObjetoRelacional BD Orientado a Objetos Programação em Lógica BD Dedutivos BD Dedutivos OO DOOD Sistema Orientado a Objetos Regras e objetos: como integrar? Hierarquia de Classes Cn Ani: Cnq Mnj: Sistema Baseado em Regras {while ... do ... if ... then ... else ... } Base de Regras f1(...,X,...)...fn(...,X,...) f0(...,X,...) Cp Api: Cpk Mpj: f1(...,a,...) fn(...,a,...) f0(...,a,...) f1(...,b,...) fn(...,c,...) f0(...,d,...) Base de Fatos {while ... do ... if ... then ... else ... } Cm Ami: Cmr Mmj: Opi Opmk Omj Api: Opk Ami: Omr Ami: Omr Base de Objetos {while ... do ... if ... then ... else ... } Integrar regras com objetos: alternativas sintáticas Sistema híbrido = sistema orientado a objetos no qual: métodos procedimentais das classes foram substituídos por bases de regras encapsuladas Sistema híbrido = sistema baseado em regras no qual: instâncias de termos lógicos na base de fatos foram substituídos por objetos instâncias de uma hierarquia de classes termos lógicos nas premissas e conclusões das regras foram substituídos por padrões de objetos com variáveis lógicas no lugar de: nome de objetos e valores de atributos possivelmente também nome de classe e atributos Substituir base de fatos por base de objetos Hierarquia de Classes Cn Ani: Cnq Mnj: Cp Api: Cpk Mpj: Base de Regras f1(...,X,...)...fn(...,X,...) f0(...,X,...) {while ... do ... if ... then ... else ... } {while ... do ... if ... then ... else ... } Cm Ami: Cmr Mmj: Opi Opmk Omj Api: Opk Ami: Omr Ami: Omr Base de Objetos {while ... do ... if ... then ... else ... } Substituir métodos procedimentais por bases de regras Hierarquia de Classes Cn Ani: Cnq Mnj: Cp Api: Cpk Mpj: Opi Api: Opk fmj1(...,X,...) ... fmjn(...,X,...) fmn0(...,X,...) fpj1(...,X,...) ... fpjn(...,X,...) fpn0(...,X,...) Cm Ami: Cmr Mmj: Opmk Ami: Omr Omj Base de Objetos Ami: Omr fnj1(...,X,...) ... fnjn(...,X,...) fnn0(...,X,...) Integrar regras com objetos: alternativas de implementação Camada de Regras Linguagem Hóspede Lógica CLIPS, RAL/C++, NéOpus, JESS, JEOPS Flora, Logtalk Linguagem de Regras Orientada a Objetos Linguagem de Implementação Lógica LoPiX, SiLRI Sistemas de produção orientados a objetos EOOPS Sistema Ling. Progr. CLIPS C++ - - +/- - RAL/C++ C++ +/- + + - + - +/- + NéOpus Smalltalk Unif. Resol. Serviços Eficiência Encad. Integr. Conflitos JESS Java - +/- +/- - JEOPS Java + + +/- +/- Regras JESS Pode usar classes Java, com restrições class Pessoa { private String nome; private Pessoa pai; ... } (defclass Pessoa Pessoa) Regras com sintaxe própria (lisp-like) (defrule RegraAvo "O pai do pai de alguém é seu avô” ?a <- (Pessoa (nome ?nomeAvo)) ?p <- (Pessoa (nome ?nomePai) (pai ?a)) ?n <- (Pessoa (nome ?nomeNeto) (pai ?p)) => (printout t ?nomeAvo “ é avô de ” ?nomeNeto crlf)) JEOPS: Java Embedded Object-Oriented Production System Sistema desenvolvido no CIn-UFPE Base de conhecimento JEOPS: Parte intencional terminológica: definições de classes Java Parte extensional: definições de objetos Java Parte intencional dedutiva: regras de produção onde cada premissa invoca algum método Java booleano definido em uma classe da parte terminológica da base cada ação invoca um método Java arbitrário definido em uma classe da parte terminológica da base Base de fato substituída por base de objetos Fases de casamento de padrão e de execução de ações incluem herança Fase de resolução de conflito não modificada (mas poderia se aproveitar da herança) Lembrete sobre sistemas de produção Base de Regras unificação Base de Fatos Conjunto de Conflito resolução de conflitos Ciclo Regra execução Novos Fatos Obs: para não ter de re-testar a cada ciclo, só testa os fatos modificados (retirados, adicionados) Casamento de padrão comportamental Mudança de paradigma Fatos: Termos Lógicos Objetos Predicados: Símbolos Lógicos Métodos Booleanos Java Casamento estrutural Casamento comportamental (pertinência a classes + veracidade dos predicados) p1, p2, p3: Pai(p1,p2) Pai(p2,p3) Avo(p1,p3) Pai(João, José) Pai(José, Marcos) Nome: Marcos Pessoa pai Nome: José Pessoa pai Nome: João Pessoa Regra Avo Para todo objeto p1, p2 e p3 da classe Pessoa, SE p1.ehPai(p2); p2.ehPai(p3); ENTÃO Regras JEOPS Rule ::= "rule" "{" <Rule Body> "}" Rule Body ::= <Declarations> <Local Declarations>? <Conditions> <Actions> Declarations ::= "declarations" (<class name> <ident> ("," <ident>)* )* Local Declarations ::= "localdecl" (<class name> <ident> "=" <expression>)* Conditions ::= "conditions" (<expression>)* Actions ::= (Action)+ Action ::= "assert" "(" <expression> ")" | "retract" "(" <expression> ")" | "modified" "(" <expression> ")" | <block> JEOPS - Arquitetura Agente assert run objects flush JEOPS ClassFilter Decl 1 ClassFilter Decl 2 ClassFilter Decl 3 FilterNode Decl 1 FilterNode Decl 2 FilterNode Decl 3 JoinNode Decl 1 JoinNode Decls 1 a 2 JoinNode Decls 1 a 3 Rete Gera entradas Conjunto de Conflito FinalNode Regra n Consulta Knowledge Base -- - - ----- - - ---- - - - ---- - - ----- - - -- Base Interna de Regras Base de Objetos Base de Conhecimentos Assert = insere objetos na base de objetos Objects = recupera objetos da base de objetos Flush = limpa base de fatos JEOPS JEOPS Compilation CompilationEnvironment Environment Rule Base JEOPS Rule Base (.rules) Rule Pre-Compiler (.java) JEOPS Esquema de Compilação • Mais simples de implementar • Mais rápido de executar Engine Application JAVA (.java) Compiler ByteCodes (.class) JAVA JEOPS JEOPS Runtime RuntimeEnvironment Environment JEOPS Inference Engine Exemplo ilustrativo: base de conhecimento de planejamento de safári Motivação: Exemplos clássicos não ficam naturais se resolvidos utilizando Regras + OO Problema das rainhas Resolução do fibonacci Exemplo do Wumpus não ilustra bem o problema Objetos simples sem herança Sem cálculos matemáticos Sem casamento de padrões por classes Solução Modelagem de um novo problema com Vários objetos Regras com casamento de padrões por tipos Herança Problema: sem profundidade de associação de objetos Exemplo ilustrativo: base de conhecimento de planejamento de safári Organizando uma expedição de safári Objetivos: Qual animal será a caça? Em que ambiente será realizado o safári? Veículo: Aquático? Terrestre? Tripulação: Quantos guias serão necessários? Quantos caçadores? Quantos motoristas? Armas: Armas de fogo? Armas brancas? Base de conhecimento de planejamento de safári: Ontologia UML Como implementar o safári em JEOPS? Diagrama de Classes Classes UML Classes Java Restrições OCL regras de produção OO Encadeamento de regras Detalhamento dos Casos de Uso + Diagrama de seqüências Comportamento do fluxo e chamadas à base de conhecimento Métodos numéricos Métodos nas classes Java Passos de desenvolvimento de uma base de conhecimento JEOPS 1. Definir as classes Atributos e métodos 2. Definir as regras Interação entre os objetos da base 3. Voltar ao passo 1 4. Deixar a base de conhecimentos trabalhar... 5. Escolher estratégia de resolução de conflito Exemplo de uso: Safári Definição das classes Arma, ArmaFogo, GrupoSafari, ... Abstract class Arma { private int preco; private String nome; ... } class ArmaFogo extends Arma { private int calibre; private int qtdMunicao; private int precoMunicao; ... } class GrupoSafari{ public Vector tripulantes; public Vector pertences; public Vector veiculos; public int financiamento; public int numeroMaximoTripulantes; ... } Exemplo de uso: Safári Criação das regras rule ContrataGuia{ declarations GrupoSafari g; Guia guia; localdecl conditions g.getTripulantes().size() < g.getNumeroMaximoTripulantes(); g.getLocal().instanceOf(LocalTerrestre); ((LocalTerrestre) g.getLocal).getAberto() == false; g.getNumeroGuias == 0; actions g.putTripulante(guia); modified(g); } Exemplo de uso: Safári Criação dos objetos RegrasSafari base = new RegrasSafari(); base.assert(new AnimalAquatico(“baleia”, "grande", false)); base.assert(new LocalAquaticoTerrestre("Pântano", "raso", false)); base.assert(new VeiculoAquatico("Lancha", 8, new Vector("baixa", "media")); ... Execução do motor de inferência base.run(); JEOPS: características interessantes Pré-compilação de regras Regras convertidas em classes Java Extensão de Rete para objetos complexos com herança Algoritmo eficiente de casamento de padrão entre fatos e premissa de regra Estratégias built-in de resolução de conflitos LRUConflictSet MRUConflictSet NaturalConflictSet OneShotConflictSet PriorityConflictSet KEOPS: Versão J2ME para rodar em dispositivos móveis Usado para implementar inteligência embutidos em jogos para celulares JEOPS: aplicações práticas Agentes de administração de rede Jogos interativos Recuperação de informação na web Música computacional Flora = Frame Logic + HiLog + Transaction Logic + XSB • Organização do conhecimento em hierarquia de classes • Representação de conhecimento taxonômico • Herança múltipla e dinâmica • Uso de processos de desenvolvimento OO Flora • Atualizações na base de fatos • Integrado ao backtrack • Representação de conhecimento procedimental Frame Logic Transaction Logic HiLog Compilador Flora Prolog tabelado XSB • • • • Sintaxe de ordem superior Semântica da 1a ordem Meta-programação Meta-consultas ao esquema • Terminação garantida em muito mais casos • Cache se sub-provas • Negação por falha com semântica declarativa bem fundamentada Exemplo de programa Flora Classes: veiculo[capacidade=>integer]. veiculoAquatico::veiculo[profundidade=>>string]. armaFogo::arma[ calibre *=> integer, qtdMunicao *=> integer, precoTotal(integer)*=>integer ]. arma[preco*=>integer, precoMunicao(10)->8, precoMunicao(12)->9]. rifle::armaFogo[calibre*->12,preco*->500]. Instâncias: baleia:animalAquatico[porte->grande,perigoso->nao]. bote:veiculoAquatico[profundidade->>baixa]. lancha:veiculoAquatico[profundidade->>{baixa,media}]. Exemplo de programa Flora Regras A[precoTotal*->P] :- A::armaBranca[preco*->P]. X:grupo[armas->>{arpao}] :- X:grupo[animal->baleia]. X[veiculos->>{V}] :comprouVeiculo, X:grupo.local:localAquatico[profundidade->P], V:veiculoAquatico[profundidade->>P], btinsert{comprouVeiculo}. A[precoTotal(Q)*->T] :A::armaFogo[preco*->P,calibre*->C], arma[precoMunicao(C)->PC], T is PC*Q+P. X[armas->>{rifle_ld1:rifle_longa_dist[qtdMunicao->10],rifle1:rifle[qtdMunicao->20]}] :X:grupo[animal->_A:animalTerrestre[porte->T]], T \= pequeno, Soma is rifle_longa_dist!precoTotal(10) + rifle!precoTotal(20), precoArmasMaximo(PM), Soma < PM. Exemplo de programa Flora Consultas g1:grupo[animal->leao]. g2:grupo[animal->baleia]. ?- G:grupo[armas->>R[qtdMunicao->Y]]. G = g1 G = g1 R = rifle1 Y = 20 R = rifle_ld1 Y = 10 ?- G:grupo[armas->>R:armaBranca]. G = g2 R = arpao ?- G :grupo[animal->A], tnot A[porte->medio]. G = g2 A = baleia Sintaxe Legenda: c: classe, o: objeto, m: método, v: valor, p: parâmetro c1::c2 Herança de classes animalTerrestre::animal o1:c1 Instanciação de Objeto leao:animalTerrestre c[m=>t] Assinatura de Métodos Univalorados grupo[animal=>animal]. c[m=>>t] Assinatura de Métodos Multivalorados grupo[armas=>>arma]. c[m->v] Métodos Univalorados grupo[animal->leao]. c[m->>{v1,...,vn}] Métodos Multivalorados grupo[armas->>{rifle1,rifle2}]. *-> *->> *=> *=>> Métodos que são herdados pelas subclasses/instancias rifle::armaFogo[calibre*->12]. armaFogo::arma[calibre *=> integer]. Agrupando: veiculoAquatico::veiculo[profundidade=>integer,profundidade*->media]. rifle:armaFogo[calibre->12,preco->500]. g1:grupo[animal->X[porte->medio]]. Sintaxe head :-p1,...pn Regra ?- p1,...pn Conculta tnot Negação tabelada X[voa->sim] :- X:ave, tnot X:pinguim. \+ Negação não tabelada p(X) :- \+ q(X). X \= Z Diferença X[irmao->Y] :X[pai->Z], Y[pai->Z], X \= Z. c1.m1, c1!m1(m. Herdado) Expressão de caminho –método univalorado ?- g1.animal[porte->X] ?- g1[animal->A], A[porte->X] o1..m2, Expressão de caminho o1!!m2 (m.herdado) -método multivalorado ?- g1..arma[preco->X] ?- g1[arma->>A], A[preco->X] ; ?- a:[porte->medio] ; a:[porte->grande] ou X:grupo[armas->>{arpao}] :X:grupo[animal->baleia]. Sintaxe Predicados como em Prolog: g1:grupo[armas->>{a1,a2}]. arma_grupo(g1,a1). arma_grupo(g1,a2). Permite aninhar objetos em predicados arma_grupo(a1:arma[preco->100]). Não permite aninhar predicados dentro de objetos Consultas Flora X SQL Flora ?- g1:grupo.animal[porte->X] SQL - Classes create table animal ( id_animal varchar(...), porte varchar(...) ); create table grupo ( id_grupo varchar(...), id_animal varchar(...), ); SQL - Instancias insert into grupo values(...) insert into animal values(...) SQL - Consultas select animal.porte as X from grupo, animal where grupo.id_grupo = g1 and grupo.id_animal = animal.id_animal Herança elefante[cor*->cinza]. clyde:elefante[cor->branca]. ?- clyde[cor->X]. X = branca d[m*->e]. d::b. b[m*->c]. a:b. a:d :- a[m->c]. ?- X[m*->Y]. X=bY=c X=dY=e ?- X[m->Y]. X=aY=c X=aY=e HiLog Sintaxe de alto nivel Semântica de primeira ordem Podem aparecer em qualquer lugar onde um simbolo de função apareça Ex: p(f(x))(a,b,c) , g(f)(g)[m(h(x))->b] Variaveis podem aparecer em qualquer parte Permite meta-programação Todos os metodos univalorados da classe c1: ? - c1[M=>T] Todas as subclasses de classes com o metodo m: ? - X::c1[m=>_] Traduzido por predicados apply/N closure(R) (X,Y) apply(apply(closure,R),X,Y) Transaction Logic Permite atualização da base de fatos Representação de conchecimento procedimental Sintaxe: operacao{literais[|query]} Non-Backtrackable update Operações desfeitas quando há backtrack insert,insertall,delete,deleteall,erase,eraseall Backtrackable update Operações persistem após backtrack btinsert,btinsertall,btdelete,btdeleteall,bterase,bteraseall Problemas com tabelamento Transaction Logic transfer(Amt,Acct1,Acct2) :withdrawn(Amt,Acct1), deposit(Amt,Acct2). withdrawn(Amt,Acct) :balance(Acct,Bal), Bal >= Amt, Bal2 is Bal - Amt ,change_balance(Acct,Bal,Bal2). deposit(Amt,Acct) :balance(Acct,Bal), Bal2 is Bal + Amt ,change_balance(Acct,Bal,Bal2). change_balance(Acct,Bal1,Bal2) :- ... ?- insert{balance(c1,100)}, insert{balance(c2,0)}, insert{balance(c3,0)}. ?- transfer(100,c1,c2),transfer(100,c1,c3). ?- balance(c1,X). Com backtrack Sem backtrack(como em prolog) change_balance(Acct,Bal1,Bal2) :btdelete{balance(Acct,Bal1)}, btinsert{balance(Acct,Bal2)}. change_balance(Acct,Bal1,Bal2) :delete{balance(Acct,Bal1)}, insert{balance(Acct,Bal2)}. X = 100. X = 0. F-Logic: aplicações práticas Engenharia de software: especificação formal executável orientada a objetos Inteligência artificial: representação do conhecimento por meio de regras e hierarquias conceituais Banco de dados: BD dedutivas orientada a objetos integração de dados integração de codificações integração de esquemas integração de BD com modelos de dados diferentes Web semântica: Agentes inteligentes de processamento de informação na web Dedução automática sobre documentos, objetos e dados na web Implementações de F-Logic Flora: F-Logic + HiLog + Transaction Logic Compilador F-Logic para XSB Prolog implementado em Prolog Domínio público, open source Stony Brook University, New York LoPiX: F-Logic + XPath + XML Implementado em C++, no entanto sem API C++ Domínio público, executável University of Freiburg, Alemanha SiRLI: F-Logic com extensões lógicas (quantificadores existenciais, conectivas) Implementado em Java Comercial, ontoprise.com TRIPLE F-Logic + RDF Compilador para Flora Domínio público Stanford/DFKI Floracle F-Logic + HiLog + Transaction Logic Compilador para Oracle9i Em desenvolvimento no CIn por mim! Substituir métodos procedimentais por bases de regras: exemplo (Linguagem Pluto) class person [ address => string; spouse => person; public mary(person); public divorce(); X[mary(Y)] :- X[not spouse -> Z, gender -> G], Y[not spouse -> Z1], not gender -> G], ins X[spouse -> Y], ins Y[spouse -> X]; X[divorce] :- del X[spouse -> Y], del Y[spouse -> X]] class employee isa person[ worksIn => dept; salary => integer; public raise(integer); X[raise(Y)] :- S2 is S1 + S2 * Y, del X[sakary ->S1], ins X[salary -> S2]] Substituir fatos por objetos: exemplo (Linguagem Flora) person[address => string, spouse => person, mary(person) => void, divorce => void]. employee::person[worksIn => dept, salary => integer, raise(integer) => void]. X:person[mary(Y:person[gender -> Gy]), gender -> Gx] :not X.spouse, not Y.spouse, Gx =/ Gy, ins(X[spouse -> Y]), ins(Y[spouse -> X]). X:person[divorce,spouse -> Y[spouse -> X]] :del(X[spouse -> Y]), del(Y[spouse -> X]). class dept. X:employee[raise(R:integer), salary -> S] :S1 is S + R, del(X[salary -> S]), ins(X[salary -> S1]). tom:employee[worksIn -> cpsc, spouse -> pat, salary -> 20000]. cpsc:dept. pat:person[spouse -> tom]. tom:employee[worksIn -> cpsc, spouse -> pat, salary -> 20000]. cpsc:dept. pat:person[spouse -> tom]. Qual conhecimento codificar nas regras e qual conhecimento codificar nos objetos? Não existe metodologia estabelecida para fazer tal escolha Com a experiência da codificação de bases de conhecimento em domínio diversos, o engenheiro do conhecimento desenvolve intuição para distinguir entre: conhecimento dedutivo x conhecimento terminológico conhecimento declarativo x conhecimento procedimental Identificar critérios gerais e rigorosos para fazer essas distinções permanece um problema aberto de pesquisa Conhecimento dedutivo melhor codificado com regras Conhecimento terminológico melhor codificado com hierarquia de classes Conhecimento procedimental melhor codificado com métodos Flora x JEOPS Flora Programação em lógica OO Hospedado em Prolog tabelado Sem procedimentos imperativos Sem encapsulamento Unificação estrutural incorporando herança Com semântica formal Encadeamento regressivo Variáveis lógicas em qualquer posição de estruturas de objetos ou classes Fracamente tipada Generaliza modelos de dados relacional, orientado a objetos e objeto-relacional JEOPS Sistema de produção OO Hospedado em Java Com procedimentos imperativos Com encapsulamento Casamento de padrões comportamental incorporando herança Sem semântica formal Encadeamento progressivo Variáveis apenas em posição de nome de objeto e valor de atributo Fortemente tipada Flora x JEOPS Vantagens de Flora Linguagem multiuso: especificação formal executável programação banco de dados representação do conhecimento Semântica formal bem definida Concisão do código Expressões de ordem superior para meta-programação e consultas a esquema de BD Prototipagem rápida de metainterpretadores para: abdução, indução, resolução de restrições, planejamento e raciocínio bayesiano Encadeamento regressivo natural para agentes deliberativos Eficiência Vantagens de JEOPS Incorporação imediata dos milhares de serviços disponíveis via API Java Fácil de aprendizagem para larga base de desenvolvedores Java Encadeamento progressivo natural para agentes reativos Flora x JEOPS: comparação para safári armaFogo::arma[calibre *=> integer,qtdMunicao *=> integer, precoTotal(integer)*=>integer ]. public class ArmaFogo extends Arma{ private int calibre; private int quantidadeMunicao; private int precoMunicao; public ArmaFogo(String nome, int preco, int calibre, int quantidadeMunicao, int precoMunicao){ super(nome, preco); ... } public void setCalibre(int calibre){...} public int getCalibre(){...} ... public int getPrecoTotal(){ ...} ... } rifle::armaFogo[calibre*->12,preco*->500]. public class Rifle extends ArmaFogo{ public Rifle( String nome, int quantidadeMunicao, int precoMunicao){ } } super(nome, 500, 12, quantidadeMunicao, precoMunicao); Flora x JEOPS: comparação para safári baleia:animalAquatico[ porte->grande, perigoso->nao ]. lancha:veiculoAquatico[ profundidade->>{baixa,media} ]. pantano:localAquatico, localTerrestre[ profundidade->baixa, aberto->nao ]. AnimalAquatico baleia = new AnimalAquatico("grande", false); VeiculoAquatico lancha = new VeiculoAquatico("Lancha", 8, new Vector("baixa", "media") ); LocalAquaticoTerrestre pantano = new LocalAquaticoTerrestre( "Pântano", "raso", false); Flora x JEOPS: comparação para safári X[veiculos->>{V}] :comprouVeiculo, X:grupo.local:localAquatico[profundidade->P], V:veiculoAquatico[profundidade->>P], btinsert{comprouVeiculo}. rule CompraVeiculoAquatico{ declarations GrupoSafari g; VeiculoAquatico embarcacao; conditions g.getVeiculos().size()==0; g.getLocal().instanceOf(LocalAquatico); embarcacao.getProfundidades().contains( ((LocalAquatico)g.getLocal()).getProfundidade()); actions g.putVeiculo(embarcacao); modified(g); } Flora x JEOPS: comparação para safári A[precoTotal(Q)*->T] :A::armaFogo[ preco*->P, calibre*->C ], arma[precoMunicao(C)->PC], T is PC*Q+P. public int getPrecoTotal(){ int preco = 0; preco = this.getPreco() + (this.getPrecoMunicao() * this.getQuantidadeMunicao()); return preco; } Flora x JEOPS: comparação para safári grupo1[armas->>R[qtdMunicao->Y]] GrupoSafari grupo = New GrupoSafari(...); ... Vector armas = grupo.getArmas(); Arma arma = null; for(int i; i< armas.size(); i++) { arma = (Arma) armas.get(i); System.out.println(arma.toString()); }