• Nenhum resultado encontrado

3 Paradigma Orientado a Notificações

3.3 Materializações do PON

3.3.1 Arquétipo ou Framework

A primeira implementação dos conceitos do PON foi realizada sobre um arquétipo ou Framework desenvolvido em linguagem de programação C++. O objetivo deste Framework é oferecer uma interface de programação (API - Application

Programming Interface) para o desenvolvimento de aplicações seguindo o modelo

PON, com abstrações necessárias para compor as FBE e Rules (BANASZEWSKI, 2009; RONSZCKA, 2012; VALENÇA, 2012).

O Framework PON C++ prototipal (ou referencial) foi proposto por Simão em 2007 (SIMÃO et al., 2012c; SIMÃO; STADZISZ, 2008), remontando ao Framework que implementa o metamodelo do Controle Orientado a Notificações (CON) sobre a ferramenta ANALYTICE II (SIMÃO, 2005). Tal Framework prototipal foi refeito no

trabalho de Banaszewski (2009) gerando o chamado Framework PON C++ 1.0 (ou original) . Subsequentemente, uma nova versão do Framework, otimizada e orientada a padrões de projeto, foi elaborada nos trabalhos de Valença (2012) e Ronszcka (2012) sendo chamada de Framework PON C++ 2.0 (ou otimizado). Este ainda se constitui na principal materialização estável do PON para software (RONSZCKA, 2012; RONSZCKA et al., 2015; VALENÇA, 2012).

O Framework PON C++ é implementado por um conjunto de classes cujos métodos são materializados em PI, sendo que sua implementação se baseia em percorrer estruturas de dados (originalmente fornecidas pela STL– Standard Template

Library na versão 1.0 do Framework – e subsequentemente por biblioteca própria na

versão 2.0 do Framework) para avaliação das relações lógico-causais e fazer o envio de notificações na forma de chamada de métodos. Tal abordagem é desvantajosa à filosofia do PON em si, pois há uma enorme dependência de estruturas de dados e a execução sobre tais estruturas se dá de forma sequencial, decorrendo assim em degradação de desempenho (LINHARES, 2015; RONSZCKA, 2012; VALENÇA, 2012). Neste âmbito, Valença (2012) e Ronszcka (2012) efetuaram uma série de otimizações com objetivo de aprimorar a performance de execução das aplicações sobre Framework C++ PON, o que foi chamado de Framework C++ PON 2.0.

O Framework PON C++ 2.0 é baseado em uma variedade de estruturas de dados mais otimizadas do que as equivalentes fornecidas pela STL, por exemplo, vetores (PONVECTOR), listas (PONLIST) e tabelas hash (PONHASH). Tais otimizações, frente ao Framework PON C++ 1.0, fizeram o Framework PON C++ 2.0 apresentar ganhos de desempenho em diversas aplicações (RONSZCKA, 2012; VALENÇA, 2012).

Segundo Ronszcka (2012), as entidades do PON, no Framework PON C++ 2.0, estão estruturadas na forma de classes/objetos, sendo relacionados por meio de estruturas de dados, com referência às entidades que têm interesse em seus estados. Para uma melhor visualização de tais relacionamentos, a Figura 23 apresenta um diagrama de classes do Framework PON C++ 2.0. Em tempo, esse Framework PON é aqui considerado por ter servido como primeira abordagem ou protótipo para NeuroPON, a ser explicado subsequentemente neste trabalho (SCHÜTZ et al., 2015).

De acordo com a Figura 23, o Framework PON C++ 2.0 subdivide-se em três pacotes principais. O pacote Application é formado exclusivamente pela classe

Application, sendo que tal classe representa a ponte de ligação entre uma aplicação

representa as implementações das classes de resolução de conflitos (RONSZCKA, 2012). Por fim, o pacote Core contém as classes colaboradoras, responsáveis pelo processo de notificação do Framework (RONSZCKA, 2012). Em tempo, uma vez que a cadeia de notificações é determinante nos conceitos do PON, a Figura 24 apresenta tal pacote em detalhes, com o detalhamento de suas entidades componentes.

Figura 23 - Estrutura do Framework PON C++ 2.0, demonstrada por Diagrama de Classes e Pacotes em UML

Fonte: Ronszcka, 2012.

Neste contexto, é importante destacar o relacionamento entre a estrutura apresentada na Figura 24 e a estrutura apresentada na Figura 20, indicando que o pacote CORE implementa a estrutura de entidades do PON, adicionando algumas particularidades necessárias ao modelo. Como exemplo, as classes Method e Rule, que definem as entidades puras do PON, são estendidas de modo a proporcionar funcionalidades adicionais (RONSZCKA, 2012).

Também em conjunto com o pacote CORE, os subpacotes Attributes e

Conditions podem ser destacados. O subpacote Attribute é formado pelas classes

responsáveis por encapsular os tipos primitivos da POO. Estas classes (Boolean, Char,

Double, Integer e String) introduzem reatividade aos tipos primitivos, permitindo que

estes façam parte de estruturas causais do PON (RONSZCKA, 2012). Por sua vez, o subpacote Conditions é formado pelas classes que fazem parte da composição de uma respectiva Condition. Particularmente, a classe LogicalOperator e suas derivadas

(Conjunction, Disjunction e Single), definem a operação lógica utilizada pela Condition de maneira a aprovar uma determinada Rule (RONSZCKA, 2012).

Figura 24 - Estrutura do pacote CORE, representada por meio de um Diagrama de Classes em UML

Fonte: Ronszcka, 2012.

Visando demonstrar a utilização do Framework PON C++ 2.0, alguns trechos de códigos são aqui apresentados. Quanto à sua codificação, o Framework segue a sintaxe da linguagem C++. Para que se possa criar uma aplicação, o desenvolvedor precisa estender a classe NOPApplication, cuja instância coordena todo o processo. As entidades do PON possuem classes base que o desenvolvedor precisa estender e instanciar, como FBE, ou apenas instanciar, como Rule. Ainda, a classe Attribute é estendida de acordo com seu tipo: Boolean, Integer, Double, Char ou String.

Quando uma classe NOPApplication é criada ou instanciada e alguns Attributes são ajustados, o núcleo do Framework configura todas as tarefas necessárias, e inicia a cadeia de notificações. O Código 4 mostra um trecho de código da declaração da classe GateSystem para o controle de um portão eletrônico, a qual estende

Código 4 - Classe NetworkSystem que estende NOPApplication, cuja instância coordena todo o sistema 01 02 03 04 05 06 07 08 09 10 11 12 13

class GateSystem : public NOPApplication { public: Gate *gate; RemoteControl *remoteControl; public: GateSystem(); virtual ~GateSystem(); private: void initStartApplicationComponents(); void initFactBase(); void initSharedEntities(); void initRules(); void codeApplication(); };

Fonte: Autoria Própria

A Código 5 apresenta um código que corresponde a um FBE para execução de uma aplicação PON por meio do Framework. Este exemplo consiste na definição do próprio portão, por meio da FBE Gate.

Código 5 - Código: estrutura de uma FBE no Framework PON C++ 2.0

01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18

class Gate: public FBE{ public: Integer* attGateState; Integer* attTimer; public: Gate(); void Opened(); void Closed(); void Opening(); void Closing(); void StopOpening(); void StopClosing(); MethodPointer<Gate>* mtStatusOpened; MethodPointer<Gate>* mtStatusClosed; MethodPointer<Gate>* mtStatusOpening; MethodPointer<Gate>* mtStatusClosing; MethodPointer<Gate>* mtStatusStopOpen; MethodPointer<Gate>* mtStatusStopClose; };

Fonte: Autoria Própria

O Código 5 apresenta a estrutura para a criação de Rules em Framework PON C++ 2.0. Neste caso, a Rule controla o processo de abertura do portão a partir de três

Premises: a primeira verifica se o controle remoto está ativo, a segunda valida se o

abertura). Em caso de uma conjunção verdadeira entre as três Premises, o Method mthOpening é instigado, e a abertura do portão é iniciada.

Código 6 - Código: estrutura das Premises para o Framework PON C++

01 02 03 04 05 06 07 08 09 10 11 12

RULE(rleOpeningGate, SingletonScheduler::getInstance(), Condition::SINGLE); PREMISE(preOpening0, remotecontrol->attRemoteStatus, true, Premise::EQUAL, Premise::STANDARD, false);

PREMISE(preOpening1, this->attGateState, 0, Premise::EQUAL, Premise::STANDARD, false);

PREMISE(preOpening2, this->attTimer, 0, Premise::EQUAL, Premise::STANDARD, false);

mthOpening = new MethodPointer<Gate>(this, &Gate::opening); rleOpeningGate->addPremise(preOpening0);

rleOpeningGate->addPremise(preOpening1); rleOpeningGate->addPremise(preOpening2); rleOpeningGate->addMethod(mthOpening);

Fonte: Autoria Própria

A apresentação dos trechos do Código 5 e do Código 6 visa exemplificar a sintaxe do Framework PON C++ 2.0, destacando apenas as definições para execução de uma Rule. Informações mais detalhadas estão nos trabalhos de Ronszcka (2012), Ronszcka et al. (2017), Valença (2012), e Valença et al. (2011). Ademais, a implementação de uma RNA em PON, utilizando o Framework PON C++ 2.0, é descrita em Schütz et al. (2015), bem como no Capítulo 4 do presente trabalho.

Segundo Ronszcka (2012), o Framework PON C++ 2.0 permite uma rápida prototipação de aplicações PON para teste sobre plataformas de computação convencionais. Entretanto, mesmo após otimizações feitas no âmbito do Framework, experimentos foram conduzidos sendo que os resultados ainda não se mostraram satisfatórios em termos de desempenho vis-à-vis o cálculo assintótico do PON (BANASZEWSKI, 2009; SIMÃO et al, 2012a). Tal degradação se deve principalmente ao uso de estruturas de dados custosas à execução do processo de inferência.

Muito embora efetivamente funcional e com resultados de desempenho aceitáveis ainda que aquém do desejado à luz da natureza do PON, o Framework PON C++ 2.0 não é concorrente e, portanto, não paralelizável em si. Baseando-se nesta característica, uma extensão para o Framework PON C++ 2.0 foi criada a fim de executar de forma concorrente e, ademais, sobre processadores multicore. Tal extensão é chamada de Framework PON C++ 3.0, e é assunto da seção 3.3.3.

Ainda que o Framework 3.0 e suas tecnologias associadas permitam processamento paralelizado de granularidade fina em ambientes multicore, as estruturas de dados que degradam o desempenho ainda estão presentes. Desta forma,

motivou-se a criação de uma linguagem e compilador específicos ao modelo PON, com o objetivo de eliminar ou minimizar os problemas apresentados nos frameworks quanto ao uso de estrutradas de dados (FERREIRA, 2015). Tal linguagem e compilador são descritos na seção 3.3.2.