CEOPS++ Integração entre Objetos e Regras de Produção em C++ Aluno:Pablo de Santana Barbosa Orientador: Geber Lisboa Ramalho Jogos e RBS’s Jogos Exigência de uma IA cada vez mais sofisticada Realismo e oponentes competitivos RBS São muito utilizados em jogos Poucos motores código aberto no mercado O caso SmartSim Jogos e RBS’s Poucos Motores de código aberto no Mercado Princípios importante para o uso de RBS’s em jogos Uniformidade de integração Bom desempenho Roteiro Motores de código aberto CEOPS++ Conclusões Sistemas de Produção e Orientação a Objetos EOOPS Vantagens Facilidade de uso Engenharia de Software: reutilização, modularidade, extensibilidade... Desvantagens O problema da modificação dos objetos Quando usar regras ou objetos? Motores existentes Tabela de comparação Linguag. Uniformid. Desempenho Res. Conflitos Facilidade Integração Soar C - +/- - +/- Jeops Java + +/- + + Clips C - - +/- - Motor de referência: Jeops Agente insert run objects flush JEOPS Knowledge Base -- - - ----- - - ---- - - - ---- - - ----- - - -- 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 Base Interna de Regras Base de Objetos Base de Conhecimentos CEOPS++ Fatos Podem ser qualquer objeto ou estrutura em C++ O CEOPS++ armazena ponteiros para objetos (void*) Base de Objetos (ceops::ObjectBase) Guarda referências para todos os objetos da memória de trabalho Evita duplicação de fatos Armazena informações de herança de classes Principais Métodos bool Insert<T>(T* obj) bool Retract<T>(T* obj) void GetObjects<T>(vector<T*>& objs) GetSubclasses<T>(vector<string>& subclasses) Checagem de subtipos(1) (util::TypeCheckFunction) C++ não suporta reflexão Suporte limitado a RTTI(Runtime Type Information) Algumas API’s código aberto tentam prover reflexão Escolha de uma solução própria Usado em conjunto com a classe TypeCheck template<typename T> inline void TypeCheckFunction(T* type, vector<string>& subclasses); Checagem de subtipos(2) (util::TypeCheckFunction) template<typename T> class TypeCheck { public: TypeCheck() {} bool check(T* t) { return true; } bool check(T& t) { return true; } bool check(void* v) { return false; } }; Checagem de subtipos(3) (util::TypeCheckFunction) template<typename T> inline void TypeCheckFunction(T* type, vector<string>& subclasses) { TypeCheck<A> typeA; TypeCheck<B> typeB; TypeCheck<C> typeC; if(typeA.check(type)) { //verifica se eh subclasse de A subclasses.push_back(typeid(A).name()); } if(typeB.check(type)) { //verifica se eh subclasse de B subclasses.push_back(typeid(B).name()); } if(typeC.check(type)) { //verifica se eh subclasse de C subclasses.push_back(typeid(C).name()); } } Regras (ceops::AbstractRule) Sintaxe próxima de C++ Possui três campos distintos: Declarations Declaração de ponteiros para classes ou estruturas Conditions Qualquer expressão booleana válida em C++ Actions Qualquer comando válido em C++ Insert, Modify, Retract Exemplo de regra CEOPS++ rule GoDown { declarations Fibonacci* f0; conditions f0->getN() > 1; f0->getValue() == -1; f0->getSon1() == NULL; actions int n = f0->getN(); Fibonacci* s1 = new Fibonacci(n - 1); Fibonacci* s2 = new Fibonacci(n - 2); f0->setSon1(s1); f0->setSon2(s2); Insert(s1); Insert(s2); Modified(f0); } Base de Regras (ceops::AbstractRuleBase) Funciona apenas como um repositório de regras Representa o conjunto das regras definidas pelo usuário Gerada automaticamente pelo précompilador Pré-compilação Arquivo de Regras (.rules) Pré-compilador CEOPS++ Base de Regras Regras (*_rules.h) (*_rule_*.h) Compilador C++ Código Objeto Rete (rete::Rete) Possui apenas a funcionalidade de memorização das avaliações realizadas rule atacar { declarations AgenteJogador agente; //d1 Unidade unidade1; //d2 Unidade unidade2; //d3 Conditions agente.ehDono(unidade1); //c1 agente.ehInimigo(unidade2); //c2 unidade2.getPosicao().distancia( unidade1.getPosicao() ) <= unidade1.getAlcanceAtaque(); //c3 unidade1.getAtaque() > unidade2.getAtaque(); //c4 unidade1.tirosRestantes > 0; //c5 actions unidade1.atacar(unidade2); //a1 Rete (rete::Rete) ClassFilter d1 ClassFilter d2, d3 } FilterNode true FilterNode c5 FilterNode true JoinNode true JoinNode c1 JoinNode c2,c3,c4 FinalNode Conjunto de conflitos (conflict::ConflictSet) Conjunto que armazena as regras ativas e os objetos que as ativaram É uma interface que deve ser implementada pelo usuário Principais Métodos virtual void InsertElement(ConflictSetElement* element) virtual ConflictSetElement* NextElement() void RemoveElementsWith(void* obj) Elemento do conjunto de conflitos (conflict::ConflictSetElement) Representa uma regra ativa e os objetos que ativaram a regra Principais Métodos AbstractRule* GetRule() vector<Fact>& GetFacts() unsigned long GetTime() Base de Conhecimentos (ceops::KnowledgeBase) É a interface entre o usuário e o motor de inferência Deve ser inicializada com um conjunto de regras e um conjunto de conflitos Principais métodos: bool Insert<T>(T* fact) void Modify<T>(T* fact) void Retract<T>(T* fact) Resultados Fibonacci Oito rainhas CEOPS++ Jeops Fibonacci(20): 6765 6765 Nº disparos: 32836 32836 Criação da KB > 1 ms 15 ms 565ms 2,5min Tempo de Execução CEOPS++ Jeops Nº disparos: 92 92 Criação da KB 10 ms 45ms Tempo de Execução 15 ms 15 ms Considerações finais Contribuição Desenvolvimento de um motor original que concilia as vantagens do Jeops com uma demanda de performance (C++) Trabalhos futuros Construir um editor de regras Melhorar o pré-compilador Tornar o código portável para outros compiladores Principais referências Figueira, Carlos. JEOPS – Integração entre objetos e Regras de produção em Java. Dissertação de Mestrado, CIn – UFPE, 2000. CLIPS Basic Programming Guide. http://www.ghg.net/clips/download/documentation/b pg.pdf Soar 8 Manual. http://ai.eecs.umich.edu/soar/sitemaker/docs/manual s/Soar8Manual.pdf. Vollmann, Detlef. Metaclasses and Reflection in C++. http://vollmann.ch/en/pubs/meta/meta/meta.html.