Análise de Impacto de Mudanças de Software Fernando H. B. Cardoso, Lile Hattori, Marcus Costa Sampaio Departamento de Sistemas e Computação – Universidade Federal de Campina Grande Av. Aprígio Veloso, S/N – 58.101-291 – Campina Grande – PB {fernando,hattori,Sampaio}@dsc.ufcg.edu.br 1. Introdução Os componentes de um software, durante o seu desenvolvimento, sofrem diversas mudanças para permitir sua evolução. Porém, antes de proceder a uma mudança em um componente, é necessário ter conhecimento do impacto que ela terá nos outros módulos. Por exemplo: a remoção de um parâmetro na assinatura de uma função implica na mudança também de todos os componentes que executam chamadas à mesma, uma vez que eles não mais funcionarão caso permaneçam com o parâmetro removido. Desta forma, para se ter noção do impacto que uma mudança pode provocar no software, é importante ter ciência dos componentes que freqüentemente sofrem modificações ao mesmo tempo. Uma rica fonte dos dados que concernem às mudanças dos componentes de um software são os registros (logs) do sistema de controle de versões utilizado. Neste documento, será apresentada a aplicação de técnicas de descoberta de regras de associação de análise de logs de sistemas de controle de versão de Software para análise de impacto de mudanças de software, utilizando . O restante do documento está organizado como segue: a Seção 2 dá uma descrição mais completa do problema a ser resolvido e a Seção 3 relaciona o problema descrito com a técnica de descoberta de regras de associação, a Seção 4 descreve os procedimentos necessários de transformação e limpeza dos dados, a Seção 5 relata os resultados do algoritmo de descoberta de regras de associação e uma conclusão é fornecida na Seção 6. 2. Descrição do Problema Para facilitar a gerência de configurações de um software, são utilizados sistemas de controle de versão como o Concurrent Version System (CVS) [CVS,2007] e o mais recente Subversion (SVN) [SVN, 2007]. O modo de utilização destes sistemas, e em especial do CVS por ser o objeto de estudo deste trabalho, pode ser simplificadamente descrito da seguinte maneira: os membros da equipe de desenvolvimento devem obter de um repositório centralizado cópias dos arquivos de código fonte do software e realizar as modificações necessárias nos mesmos. Após terminadas as modificações, os arquivos são gravados (commit) no repositório em lotes (transações) com um comentário associado à transação, que geralmente é utilizado para descrever os motivos das mudanças realizadas. Observar diagrama exibido na Figura 1. Figura 1 - Modo de operação do CVS Quando o software desenvolvido é escrito sob os moldes do paradigma de programação orientada a objetos, cada arquivo fonte corresponde a uma classe, de modo que esta é a unidade de código considerada para o estudo descrito neste trabalho. Um acoplamento de mudanças é um conjunto de classes que sofreu commit, atomicamente (logicamente, uma transação). No contexto de um arquivo .CVS, que é um histórico de mudanças, são commits de classes que têm o mesmo autor, estão na mesma janela de tempo e apresentam o mesmo comentário. O critério da janela de tempo é necessário, pois os commits são sempre atômicos, e não há, no CVS, o conceito explícito de transação. Para ilustrar, suponha-se que o conjunto de classes g = {C1, C2, C3} sofreu commit dentro de uma mesma janela de tempo, por um mesmo autor e com o mesmo comentário, ou seja, compõe uma transação. O conjunto g é um subconjunto de h = {C1, C2, C3, C4, C5}, que também compõe uma outra transação. Então, g e h são ambos acoplamento de mudanças, com duas ocorrências de g e uma de h. Desta forma, o problema abordado neste trabalho pode ser enunciado por duas questões, não excludentes e relacionadas a acoplamento de mudanças: (q1) quais classes mudam juntas freqüentemente ao longo do desenvolvimento de um sistema?; e (q2) se uma classe mudar, qual a probabilidade que outras classes também mudem?. A solução do problema envolve achar a resposta para as duas questões, a um custo aceitável. A análise de impacto de mudanças pode ser realizada através da análise estática do código-fonte do sistema. A análise estática busca toda a árvore de dependência de uma entidade no sistema, considerando entidade como classe, método ou atributo. Há pelo menos uma desvantagem desta abordagem: é muito improvável que toda a árvore de dependência sofra impacto; a conseqüência é que o custo da solução possivelmente será muito alto. Para a solução do problema a um custo baixo, técnicas de mineração de dados são investigadas, visando à indução automática de modelos de impacto. A título de estudo de caso, será estudado o log das versões de um software escrito na linguagem de programação Java utilizado pelo Grupo de Métodos Formais (GMF) da Universidade Federal de Campina Grande (UFCG): o Design Wizard. O log utilizado apresenta informações sobre 1416 commits efetuados em 734 arquivos que compunham o software. As etapas do pré-processamento, bem como os resultados obtidos são detalhados adiante. 3. Mineração de Repositórios Para o problema da análise de impacto de mudanças em software, conforme descrito na Seção 2, é necessário proceder a uma análise de associações entre as classes que compõem cada transação de commits no sistema de versionamento do software (CVS). A partir de utilização de um algoritmo de extração de regras de regras de associação, como por exemplo o Apriori [Witten e Frank, 2005], será possível obter regras do tipo: Se a classe Design mudar, então a classe DesignIF também muda, com confiança de 100% e suporte de 0,5%. Isto permite responder ao segundo quesito (q2) da definição do problema: no mesmo exemplo, pode-se estimar que a classe DesignIF tem 100% de probabilidade de mudar, dado que foi alterada a classe Design. Nem sempre, no entanto, é possível obter regras tão diretas quanto às acima: há casos em que o algoritmo Apriori induz regras do tipo Se a C1, C2, e C3 mudam, então C4 e C5 também mudam, com confiança de 86% e suporte de 1%. Neste caso, não é possível determinar a probabilidade de mudança de nenhuma das classes, dado que outra mudou. Pode-se, porém, proceder a cálculos estatísticos, desde que se saibam o suporte de cada itemset: para se obter a probabilidade de Ci mudar, dado que Cj mudou utiliza-se a Equação (1). (1) P(Ci | C j ) sup( Ci C j ) sup( C j ) Para responder ao primeiro quesito (q1), deve-se proceder a uma separação do arquivo de dados em subconjuntos de commits formados pelos grupos de classes que produzem às regras utilizadas para responder a q2. Após esta separação, consideram-se acoplamentos de mudanças os itemsets (e não as regras) que apresentarem maior suporte em cada um dos subconjuntos submetidos ao algoritmo Apriori. 4. Preparação dos Dados Para proceder à execução dos algoritmos de descoberta de regras de associação nos logs de CVS fornecidos e descobrir os acoplamentos de mudanças nas classes que compõem o software que se quer analisar, é necessário proceder a uma série de passos de preparação dos dados, uma vez que os mesmos não estão apresentados de maneira correta, além de trazerem consigo uma série de informações que devem ser desconsideradas. O primeiro destes passos é filtrar do log do CVS os arquivos que não dizem respeito ao software. Por este ter sido escrito na linguagem de programação Java, é sabido que os códigos fontes de suas classes (a palavra classe, neste documento, se refere às classes e às interfaces Java) apresentam a extensão de arquivo .java. Desta maneira, todos os arquivos que não apresentavam tal extensão foram desconsiderados da análise de associações. Tendo restado apenas as informações referentes aos commits efetuados nos arquivos de código fonte das classes que compõem o software, foi necessário agregá-los de modo a decidir quais arquivos sofreram commits que satisfazem as seguintes condições: (i) efetuados pelo mesmo autor, (ii) com o mesmo comentário e (iii) dentro de uma mesma janela de tempo. Em outras palavras, foi necessário agrupar os commits em transações. Segundo Zimmermann e Weißgerber, os melhores resultados da mineração de dados em repositórios CVS são obtidos utilizando uma janela de tempo deslizante, de tamanho de 200 segundos [Zimmerman e Weißgerber, 2004]. Figura 2 - Processo de preparação dos dados O passo seguinte da preparação dos dados foi a limpeza dos mesmos, para retirar as informações consideradas como ruído. Foram desconsideradas todas as classes que apenas sofreram um commit no CVS, uma vez que se esta classe não sofreu alterações, ela não está acoplada a nenhuma outra. As transações que envolvem muitos arquivos (mais de 20) também foram descartadas por serem, geralmente, correspondentes a mudanças infra-estruturais no software e não a mudanças devidas à evolução do mesmo. Após este processo, as transações vazias foram retiradas do conjunto de dados, para não interferir no cômputo dos valores de suporte dos itemsets encontrados. Por fim, uma vez que os algoritmos, para serem executados pela plataforma Weka, exigem que os dados estejam no formato ARFF [WF05], foi montado um arquivo nestes moldes, no qual cada atributo corresponde a uma classe do software analisado, e cada linha representa uma transação (vide arquivo em anexo). As classes que não fazem parte de um commit têm seu valor indefinido (?) uma vez que, caso tenham valor negativo (n) o algoritmo Apriori gera regras do tipo “Se a classe_A não estiver no commit, então a classe_B também não está”, enquanto o interesse é por regras positivas, tanto no antecedente quanto no conseqüente da regra. Para resumir o processo de preparação dos dados, a Figura 2 exibe um diagrama dos mesmos, ilustrando as operações efetuadas para transformar o log do CVS em um arquivo no formato ARFF. Após o processo de preparação, restaram ao arquivo do estudo de caso 75 classes e 78 transações no CVS. 4. Resultados Obtidos De posse do arquivo no formato ARFF, foi possível executar o algoritmo Apriori, fornecido pela plataforma de mineração de dados WEKA. Este algoritmo foi adotado por ser o único a fornecer os suportes dos itemsets que encontrados, o que é necessário para proceder à análise probabilística que permite responder às questões (q1) e (q2) da definição do problema. Para a execução do mesmo, os parâmetros fornecidos foram confiança mínima de 75% para geração das regras (o que é irrelevante, uma vez que as regras geradas não foram consideradas, e sim os itemsets), e suporte mínimo de 7,5% (6 ocorrências de um itemset, para ele ser levado em consideração). A resposta à primeira questão (q1) pode ser obtida através da análise dos maiores itemsets encontrados com a execução do algoritmo Apriori, que estão exibidas a seguir (caminho do arquivo no sistema de pacotes Java e nome da classe em negrito): 1. designwizard/design/ClassNode.java, designwizard/design/Design.java e designwizard/design/MethodNode.java 2. designwizard/design/ClassNode.java, designwizard/design/FieldNode.java e designwizard/design/MethodNode.java 3. designwizard/design/Design.java, designwizard/design/manager/DesignManager.java 4. designwizard/design/Design.java, designwizard/design/manager/DesignManager.java e designwizard/test/AllTest.java designwizard/design/DesignIF.java e Vale ressaltar que todos os subconjuntos destes acoplamentos de mudanças também o são, de modo que estes são os maiores grupos de classes que mudam juntos e respeitam o suporte mínimo de 7,5%. O resultado completo da execução do algoritmo Apriori com os parâmetros indicados estão em anexo. Para responder à questão (q2), é necessário analisar os suportes dos itemsets de tamanho 1 e dos itemsets de tamanho 2 e aplicar a Equação (1) de modo a obter a probabilidade de, dado que uma classe tenha mudado, uma outra classe também muda. O resultado desta análise, para as classes que têm probabilidade de mudar maior que 50% está exibido a seguir (Se a Classe1 muda => a Classe 2 muda com (p) de probabilidade): designwizard/design/ClassNode.java => designwizard/design/Entity.java (0.6153846153846154) designwizard/design/ClassNode.java => designwizard/design/FieldNode.java (0.5384615384615384) designwizard/design/ClassNode.java => designwizard/design/MethodNode.java (0.6923076923076923) designwizard/design/ClassNode.java => designwizard/design/test/ClassNodeTest.java (0.5384615384615384) designwizard/design/DesignIF.java => designwizard/design/Design.java (1.0) designwizard/design/DesignIF.java => designwizard/design/manager/DesignManager.java (0.8571428571428571) designwizard/design/Entity.java => designwizard/design/ClassNode.java (0.6666666666666666) designwizard/design/Entity.java => designwizard/design/FieldNode.java (0.5833333333333334) designwizard/design/FieldNode.java => designwizard/design/ClassNode.java (0.5833333333333334) designwizard/design/FieldNode.java => designwizard/design/Entity.java (0.5833333333333334) designwizard/design/FieldNode.java => designwizard/design/MethodNode.java (0.5833333333333334) designwizard/design/MethodNode.java => designwizard/design/ClassNode.java (0.5294117647058824) designwizard/design/MethodNode.java => designwizard/design/Design.java (0.5294117647058824) designwizard/design/entity/AbstractEntity.java => designwizard/design/Design.java (0.6666666666666666) designwizard/design/entity/AbstractEntity.java => designwizard/design/manager/DesignManager.java (0.6666666666666666) designwizard/design/entity/ClassBL.java => designwizard/design/entity/ui/Class.java (0.75) designwizard/design/entity/ClassNode.java => designwizard/design/Design.java (0.875) designwizard/design/entity/ClassNode.java => designwizard/design/entity/test/ClassNodeTest.java (0.75) designwizard/design/entity/test/ClassNodeTest.java => designwizard/design/entity/ClassNode.java (0.75) designwizard/design/entity/ui/Class.java => designwizard/design/Design.java (0.5454545454545454) designwizard/design/entity/ui/Class.java => designwizard/design/entity/ClassBL.java (0.5454545454545454) designwizard/design/entity/ui/Class.java => designwizard/design/entity/ui/Field.java (0.5454545454545454) designwizard/design/entity/ui/Class.java => designwizard/design/entity/ui/Method.java (0.5454545454545454) designwizard/design/entity/ui/Field.java => designwizard/design/entity/ui/Class.java (0.8571428571428571) designwizard/design/entity/ui/Method.java => designwizard/design/entity/ui/Class.java (0.6) designwizard/design/test/ClassNodeTest.java => designwizard/test/AllTest.java (0.6) designwizard/main/DesignWizard.java => designwizard/design/manager/DesignManager.java (0.5833333333333334) designwizard/main/test/DesignWizardTest.java => designwizard/design/Design.java (0.7777777777777778) designwizard/main/test/DesignWizardTest.java => designwizard/design/test/ClassNodeTest.java (0.6666666666666666) designwizard/main/test/DesignWizardTest.java => designwizard/test/AllTest.java (0.6666666666666666) designwizard/patternchecker/CheckingResult.java (0.8571428571428571) => designwizard/patternchecker/SingletonPatternChecker.java designwizard/patternchecker/SingletonPatternChecker.java => designwizard/patternchecker/CheckingResult.java (0.75) designwizard/patternchecker/SingletonPatternChecker.java => designwizard/patternchecker/test/SingletonPatternCheckerTest.java (0.75) designwizard/patternchecker/test/SingletonPatternCheckerTest.java => designwizard/patternchecker/SingletonPatternChecker.java (0.75) designwizard/test/AllTest.java => designwizard/design/Design.java (0.65) Os valores obtidos, no entanto, não possuem nenhum valor semântico, e devem, portanto, ser utilizados com bastante cuidado. Por exemplo, a regra designwizard/design/DesignIF.java => designwizard/design/Design.java (1.0) não indica nenhuma relação de causa entre mudanças nas classes DesignIF e Design. Desta forma, é necessário sempre analisar as regras obtidas sob a ótica do propósito que cada classe tem no contexto do software em questão. 4. Conclusões e Trabalhos Futuros Os resultados obtidos com o emprego de técnicas de mineração de dados, mais especificamente de descoberta de regras de associação com o algoritmo Apriori, mostram que é possível obter informações úteis acerca do impacto de mudanças de software a partir dos logs do sistema de versões concorrentes. No entanto, como em qualquer processo de mineração de dados, os valores numéricos encontrados não levam em consideração relações de causa e efeito nas mudanças de classes do software, o que traz à tona a necessidade de conhecimento acerca do papel desempenhado por cada classe no funcionamento do software. Mais investigações devem ser conduzidas no que diz respeito a aplicar as técnicas apresentadas neste estudo em outros softwares com mais classes e mais commits efetuados no sistema, a fim de se determinar o efeito do tamanho do software na qualidade dos acoplamentos de mudanças encontrados. Da mesma maneira, é importante investigar o efeito da separação das classes do software em subsistemas antes de proceder à execução dos algoritmos, a fim de verificar o efeito que esta ação tem na qualidade das regras obtidas. Referencias CVS. Concurrent Versions Systems. Disponível online em http://savannah.nongnu.org/projects/cvs/. 2007. Acessado pela ultima vez em 16 de dezembro de 2007. SVN. Subversion. Disponível online em http://subversion.tigris.org/. 2007. Acessado pela ultima vez em 16 de dezembro de 2007. Ian H. Witten and Eibe Frank (2005) "Data Mining: Practical machine learning tools and techniques", 2nd Edition, Morgan Kaufmann, San Francisco, 2005. T. Zimmerman and P. Weißgerber (2004) " Preprocessing CVS data for fine-grained analysis ", Proc. International Workshop on Mining Software Repositories (MSR 2004) 2004. Anexo A: Arquivo ARFF @relation changelog @attribute resources/test_aplications/AttibuteRedefined/SubClass.java {y,n} @attribute resources/test_aplications/Patterns/SingletonBadConstructor/SingletonBadConstructor.java {y,n} @attribute resources/test_aplications/Patterns/SingletonWrong1/SingletonBadConstructor.java {y,n} @attribute SubClass.java {y,n} @attribute SuperClass.java {y,n} @attribute designwizard/common/Config.java {y,n} @attribute designwizard/comparator/CalculateDiffAction.java {y,n} @attribute designwizard/comparator/DesignDiff.java {y,n} @attribute designwizard/comparator/SimpleCalculateDiffAction.java {y,n} @attribute designwizard/design/AbstractEntity.java {y,n} @attribute designwizard/design/ClassNode.java {y,n} @attribute designwizard/design/Design.java {y,n} @attribute designwizard/design/DesignIF.java {y,n} @attribute designwizard/design/Entity.java {y,n} @attribute designwizard/design/FieldNode.java {y,n} @attribute designwizard/design/MethodNode.java {y,n} @attribute designwizard/design/Modifier.java {y,n} @attribute designwizard/design/entity/AbstractEntity.java {y,n} @attribute designwizard/design/entity/ClassBL.java {y,n} @attribute designwizard/design/entity/ClassNode.java {y,n} @attribute designwizard/design/entity/Entity.java {y,n} @attribute designwizard/design/entity/FieldBL.java {y,n} @attribute designwizard/design/entity/FieldNode.java {y,n} @attribute designwizard/design/entity/MethodBL.java {y,n} @attribute designwizard/design/entity/MethodNode.java {y,n} @attribute designwizard/design/entity/factory/ElementsFactory.java {y,n} @attribute designwizard/design/entity/test/ClassNodeTest.java {y,n} @attribute designwizard/design/entity/test/FieldNodeTest.java {y,n} @attribute designwizard/design/entity/test/GetConstructorsTest.java {y,n} @attribute designwizard/design/entity/test/ReturnTest.java {y,n} @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute designwizard/design/entity/test/ThrowsTest.java {y,n} designwizard/design/entity/test/VisibilityTest.java {y,n} designwizard/design/entity/ui/Class.java {y,n} designwizard/design/entity/ui/Field.java {y,n} designwizard/design/entity/ui/Method.java {y,n} designwizard/design/factory/ElementsFactory.java {y,n} designwizard/design/manager/DesignManager.java {y,n} designwizard/design/manager/test/DesignManagerTest.java {y,n} designwizard/design/manager/util/TranslatorUtil.java {y,n} designwizard/design/relation/Relation.java {y,n} designwizard/design/relation/test/RelationTest.java {y,n} designwizard/design/test/ClassNodeTest.java {y,n} designwizard/design/test/FieldNodeTest.java {y,n} designwizard/design/test/InheritanceTest.java {y,n} designwizard/design/test/MethodNodeTest.java {y,n} designwizard/design/test/ReturnTest.java {y,n} designwizard/design/test/VisibilityTest.java {y,n} designwizard/main/DesignWizard.java {y,n} designwizard/main/ResultOfImpact.java {y,n} designwizard/main/test/DesignWizardTest.java {y,n} designwizard/main/util/FileUtil.java {y,n} designwizard/patternchecker/CheckError.java {y,n} designwizard/patternchecker/CheckWarning.java {y,n} designwizard/patternchecker/CheckingResult.java {y,n} designwizard/patternchecker/SingletonPatternChecker.java {y,n} designwizard/patternchecker/test/SingletonPatternCheckerTest.java {y,n} designwizard/test/AllTest.java {y,n} designwizard/test/DescriptionTest.java {y,n} designwizard/test/EARTest.java {y,n} designwizard/test/ImpactTest.java {y,n} designwizard/test/TraceForMethods.java {y,n} designwizard/test/design/AllClassesInSuiteTest.java {y,n} designwizard/test/design/CatchBlockTest.java {y,n} designwizard/test/design/CatchedExceptionsTest.java {y,n} designwizard/test/design/DesignWizardTest.java {y,n} designwizard/test/design/EJBTest.java {y,n} designwizard/test/design/ImpactTest.java {y,n} designwizard/test/design/RedBarTest.java {y,n} designwizard/test/design/UseFieldTest.java {y,n} designwizard/test/design/WarningTest.java {y,n} designwizard/test/impact/DescriptionTest.java {y,n} designwizard/test/impact/EARFilesTest.java {y,n} designwizard/test/impact/ImpactTest.java {y,n} designwizard/test/impact/TraceForMethods.java {y,n} designwizard/testcases/InheritanceTest.java {y,n} @data ?,?,?,?,?,?,?,?,?,?,?,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,y,?,y,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,y,?,?,?,y,?,?,?,?,?,?,?,?,?,?, ?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,y,y,?,y,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,y,?,?,?,?,?,?,?,y,?,?,y,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,y,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,y,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,y,y,?,?,?,?,y,y,?,y,?,?,y,?,?,?,?,?,?,y,y,y,?,y,y,y,?,?,?,y,?,?,?, ?,?,?,?,?,y,?,?,?,?,?,?,y,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,y,?,?,?,y,y,y,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,y,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,y,y,?,?,?,?,y,y,?,?,y,?,y,?,?,?,?,?,?,?,?,y,?,?,?,y,?,?,y,?,?,?,?, ?,?,?,y,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,y,y,?,y,?,?,?,?,?,?,?,?,?,?,y,?,y,?,?,?,y,?,?,?, ?,?,?,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,y,?,y,y,?,y,?,?,?,?,?,?,?,?,y,y,y,?,y,?,?,?,?,?,?,?, ?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?, ?,?,?,y,y,?,?,?,?,?,?,?,?,y,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,y,y,?,?,?,?,y,y,y,y,y,y,y,y,y,?,?,?,?,?,?,y,y,y,?,y,?,?,?,y,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? y,?,?,?,?,?,y,?,?,?,?,y,y,?,?,?,?,y,?,y,y,?,y,?,y,y,?,y,?,?,?,?,?,?,y,?,y,?,?,y,y,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,y,?,y,y,?,y,?,?,?,y,y,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,y,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,y,?,?,y,?,?,?,y,y,?,?,y,?,y,y,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,y,y,?,y,y,?,?,?,?,?,?,?,?,?,y,?,y,y,? ?,?,?,?,?,?,?,?,?,?,?,y,y,?,?,?,?,?,?,y,?,?,y,?,?,?,y,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,y,y,?,?,?,?,y,?,y,?,?,?,?,?,?,y,y,?,?,?,?,y,?,?,?,y,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,y,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,y,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,y,?,?,?,?,y,?,y,?,?,y,?,?,y,y,y,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,y,y,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,y,y,y,?,?,?,y,y,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,y,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,y,? ?,?,?,?,?,?,?,?,?,?,y,y,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,y,?,?, ?,?,?,?,?,?,y,?,?,?,?,?,y,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,y,?,?,y,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,y,?,?,y,?,?, ?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,y,?,?,?,?,?,?,?,?,?,? y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?, ?,y,y,y,?,y,y,?,?,?,?,?,?,?,?,?,?,y,y,y,y,?,?,y,y,y,y,?,y,y,? ?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,y,?,?,?,?,?,y,?,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,y,?,?,?,?, ?,?,?,y,?,?,?,?,?,?,?,?,y,?,?,?,?,y,?,?,y,y,?,?,?,?,y,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,y,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,y,y,?,?,y,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,y,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,y,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,y,?,y,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?, ?,?,y,y,?,y,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,y,?,?,y,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,y,?,?,y,y,?, y,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?, ?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,y,y,?,?,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,y,?,?,y,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,y,?,?,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?, ?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,? ?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,y,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,y,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,y,y,?,?,?,?,y,y,?,?,y,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,y,y,?,?,y,y,?, ?,?,?,?,?,?,?,?,?,?,y,?,y,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,y,?,?,?,?,y,y,?,y,y,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,y,?,?,y,y,y, ?,?,?,?,?,y,?,?,?,y,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,y,y,?,?,?,? ?,?,?,?,?,?,?,?,?,?,y,y,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?, ?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,? y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? y,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,y,y,?,?,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,y,y, ?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y ?,?,?,?,?,y,?,?,?,?,y,y,?,y,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,y,?,y,?,y, y,?,?,?,?,y,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,y ?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?, ?,?,?,y,?,?,?,?,?,?,?,?,y,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,y,?,y,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,? ?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,y,y,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,y,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,y,?,y,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?, ?,?,?,?,?,y,?,y,y,y,y,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,y,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,y,?,?,?,?,?,?, ?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,y,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,y,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,y,?,?,?,y,?,?, ?,?,?,?,?,y,?,?,?,?,?,?,y,?,?,?,?,y,?,?,y,?,?,?,?,?,?,?,?,?,? Anexo B: Registro de Resultado da Execução do Algoritmo Apriori === Run information === Scheme: weka.associations.Apriori -I -N 100 -T 0 -C 0.75 -D 0.0050 -U 1.0 -M 0.075 -S -1.0 Relation: changelog-weka.filters.unsupervised.attribute.Remove-R1-5,7-22,24-33,35124,133,140,144,150-151,154,163-166,169-170,175,177,179,183,185-191,199-200,215,223-229 Instances: 78 Attributes: 75 resources/test_aplications/AttibuteRedefined/SubClass.java resources/test_aplications/Patterns/SingletonBadConstructor/SingletonBadConstructor.java resources/test_aplications/Patterns/SingletonWrong1/SingletonBadConstructor.java SubClass.java SuperClass.java designwizard/common/Config.java designwizard/comparator/CalculateDiffAction.java designwizard/comparator/DesignDiff.java designwizard/comparator/SimpleCalculateDiffAction.java designwizard/design/AbstractEntity.java designwizard/design/ClassNode.java designwizard/design/Design.java designwizard/design/DesignIF.java designwizard/design/Entity.java designwizard/design/FieldNode.java designwizard/design/MethodNode.java designwizard/design/Modifier.java designwizard/design/entity/AbstractEntity.java designwizard/design/entity/ClassBL.java designwizard/design/entity/ClassNode.java designwizard/design/entity/Entity.java designwizard/design/entity/FieldBL.java designwizard/design/entity/FieldNode.java designwizard/design/entity/MethodBL.java designwizard/design/entity/MethodNode.java designwizard/design/entity/factory/ElementsFactory.java designwizard/design/entity/test/ClassNodeTest.java designwizard/design/entity/test/FieldNodeTest.java designwizard/design/entity/test/GetConstructorsTest.java designwizard/design/entity/test/ReturnTest.java designwizard/design/entity/test/ThrowsTest.java designwizard/design/entity/test/VisibilityTest.java designwizard/design/entity/ui/Class.java designwizard/design/entity/ui/Field.java designwizard/design/entity/ui/Method.java designwizard/design/factory/ElementsFactory.java designwizard/design/manager/DesignManager.java designwizard/design/manager/test/DesignManagerTest.java designwizard/design/manager/util/TranslatorUtil.java designwizard/design/relation/Relation.java designwizard/design/relation/test/RelationTest.java designwizard/design/test/ClassNodeTest.java designwizard/design/test/FieldNodeTest.java designwizard/design/test/InheritanceTest.java designwizard/design/test/MethodNodeTest.java designwizard/design/test/ReturnTest.java designwizard/design/test/VisibilityTest.java designwizard/main/DesignWizard.java designwizard/main/ResultOfImpact.java designwizard/main/test/DesignWizardTest.java designwizard/main/util/FileUtil.java designwizard/patternchecker/CheckError.java designwizard/patternchecker/CheckWarning.java designwizard/patternchecker/CheckingResult.java designwizard/patternchecker/SingletonPatternChecker.java designwizard/patternchecker/test/SingletonPatternCheckerTest.java designwizard/test/AllTest.java designwizard/test/DescriptionTest.java designwizard/test/EARTest.java designwizard/test/ImpactTest.java designwizard/test/TraceForMethods.java designwizard/test/design/AllClassesInSuiteTest.java designwizard/test/design/CatchBlockTest.java designwizard/test/design/CatchedExceptionsTest.java designwizard/test/design/DesignWizardTest.java designwizard/test/design/EJBTest.java designwizard/test/design/ImpactTest.java designwizard/test/design/RedBarTest.java designwizard/test/design/UseFieldTest.java designwizard/test/design/WarningTest.java designwizard/test/impact/DescriptionTest.java designwizard/test/impact/EARFilesTest.java designwizard/test/impact/ImpactTest.java designwizard/test/impact/TraceForMethods.java designwizard/testcases/InheritanceTest.java === Associator model (full training set) === Apriori ======= Minimum support: 0.07 (6 instances) Minimum metric <confidence>: 0.75 Number of cycles performed: 185 Generated sets of large itemsets: Size of set of large itemsets L(1): 30 Large Itemsets L(1): designwizard/common/Config.java=y 6 designwizard/design/ClassNode.java=y 13 designwizard/design/Design.java=y 26 designwizard/design/DesignIF.java=y 7 designwizard/design/Entity.java=y 12 designwizard/design/FieldNode.java=y 12 designwizard/design/MethodNode.java=y 17 designwizard/design/Modifier.java=y 6 designwizard/design/entity/AbstractEntity.java=y 9 designwizard/design/entity/ClassBL.java=y 8 designwizard/design/entity/ClassNode.java=y 8 designwizard/design/entity/Entity.java=y 7 designwizard/design/entity/FieldBL.java=y 6 designwizard/design/entity/MethodBL.java=y 9 designwizard/design/entity/test/ClassNodeTest.java=y 8 designwizard/design/entity/ui/Class.java=y 11 designwizard/design/entity/ui/Field.java=y 7 designwizard/design/entity/ui/Method.java=y 10 designwizard/design/manager/DesignManager.java=y 23 designwizard/design/relation/Relation.java=y 8 designwizard/design/test/ClassNodeTest.java=y 15 designwizard/design/test/FieldNodeTest.java=y 8 designwizard/main/DesignWizard.java=y 12 designwizard/main/test/DesignWizardTest.java=y 9 designwizard/patternchecker/CheckingResult.java=y 7 designwizard/patternchecker/SingletonPatternChecker.java=y 8 designwizard/patternchecker/test/SingletonPatternCheckerTest.java=y 8 designwizard/test/AllTest.java=y 20 designwizard/test/design/AllClassesInSuiteTest.java=y 7 designwizard/test/design/DesignWizardTest.java=y 12 Size of set of large itemsets L(2): 36 Large Itemsets L(2): designwizard/design/ClassNode.java=y designwizard/design/Design.java=y 6 designwizard/design/ClassNode.java=y designwizard/design/Entity.java=y 8 designwizard/design/ClassNode.java=y designwizard/design/FieldNode.java=y 7 designwizard/design/ClassNode.java=y designwizard/design/MethodNode.java=y 9 designwizard/design/ClassNode.java=y designwizard/design/test/ClassNodeTest.java=y 7 designwizard/design/Design.java=y designwizard/design/DesignIF.java=y 7 designwizard/design/Design.java=y designwizard/design/FieldNode.java=y 6 designwizard/design/Design.java=y designwizard/design/MethodNode.java=y 9 designwizard/design/Design.java=y designwizard/design/entity/AbstractEntity.java=y 6 designwizard/design/Design.java=y designwizard/design/entity/ClassNode.java=y 7 designwizard/design/Design.java=y designwizard/design/entity/ui/Class.java=y 6 designwizard/design/Design.java=y designwizard/design/manager/DesignManager.java=y 11 designwizard/design/Design.java=y designwizard/design/test/ClassNodeTest.java=y 7 designwizard/design/Design.java=y designwizard/main/test/DesignWizardTest.java=y 7 designwizard/design/Design.java=y designwizard/test/AllTest.java=y 13 designwizard/design/DesignIF.java=y designwizard/design/manager/DesignManager.java=y 6 designwizard/design/Entity.java=y designwizard/design/FieldNode.java=y 7 designwizard/design/Entity.java=y designwizard/design/MethodNode.java=y 6 designwizard/design/Entity.java=y designwizard/test/AllTest.java=y 6 designwizard/design/FieldNode.java=y designwizard/design/MethodNode.java=y 7 designwizard/design/FieldNode.java=y designwizard/design/test/ClassNodeTest.java=y 6 designwizard/design/MethodNode.java=y designwizard/design/test/ClassNodeTest.java=y 7 designwizard/design/MethodNode.java=y designwizard/test/AllTest.java=y 6 designwizard/design/entity/AbstractEntity.java=y designwizard/design/manager/DesignManager.java=y 6 designwizard/design/entity/ClassBL.java=y designwizard/design/entity/ui/Class.java=y 6 designwizard/design/entity/ClassNode.java=y designwizard/design/entity/test/ClassNodeTest.java=y 6 designwizard/design/entity/ui/Class.java=y designwizard/design/entity/ui/Field.java=y 6 designwizard/design/entity/ui/Class.java=y designwizard/design/entity/ui/Method.java=y 6 designwizard/design/manager/DesignManager.java=y designwizard/main/DesignWizard.java=y 7 designwizard/design/manager/DesignManager.java=y designwizard/test/AllTest.java=y 8 designwizard/design/test/ClassNodeTest.java=y designwizard/main/test/DesignWizardTest.java=y 6 designwizard/design/test/ClassNodeTest.java=y designwizard/test/AllTest.java=y 9 designwizard/main/test/DesignWizardTest.java=y designwizard/test/AllTest.java=y 6 designwizard/patternchecker/CheckingResult.java=y designwizard/patternchecker/SingletonPatternChecker.java=y 6 designwizard/patternchecker/SingletonPatternChecker.java=y designwizard/patternchecker/test/SingletonPatternCheckerTest.java=y 6 designwizard/test/AllTest.java=y designwizard/test/design/DesignWizardTest.java=y 6 Size of set of large itemsets L(3): 4 Large Itemsets L(3): designwizard/design/ClassNode.java=y designwizard/design/Design.java=y designwizard/design/MethodNode.java=y 6 designwizard/design/ClassNode.java=y designwizard/design/FieldNode.java=y designwizard/design/MethodNode.java=y 6 designwizard/design/Design.java=y designwizard/design/DesignIF.java=y designwizard/design/manager/DesignManager.java=y 6 designwizard/design/Design.java=y designwizard/design/manager/DesignManager.java=y designwizard/test/AllTest.java=y 6 Best rules found: 1. designwizard/design/DesignIF.java=y 7 ==> designwizard/design/Design.java=y 7 conf:(1) 2. designwizard/design/DesignIF.java=y designwizard/design/manager/DesignManager.java=y 6 ==> designwizard/design/Design.java=y 6 conf:(1) 3. designwizard/design/ClassNode.java=y designwizard/design/Design.java=y 6 ==> designwizard/design/MethodNode.java=y 6 conf:(1) 4. designwizard/design/entity/ClassNode.java=y 8 ==> designwizard/design/Design.java=y 7 conf:(0.88) 5. designwizard/design/DesignIF.java=y 7 ==> designwizard/design/Design.java=y designwizard/design/manager/DesignManager.java=y 6 conf:(0.86) 6. designwizard/design/Design.java=y designwizard/design/DesignIF.java=y 7 ==> designwizard/design/manager/DesignManager.java=y 6 conf:(0.86) 7. designwizard/design/ClassNode.java=y designwizard/design/FieldNode.java=y 7 ==> designwizard/design/MethodNode.java=y 6 conf:(0.86) 8. designwizard/design/FieldNode.java=y designwizard/design/MethodNode.java=y 7 ==> designwizard/design/ClassNode.java=y 6 conf:(0.86) 9. designwizard/patternchecker/CheckingResult.java=y 7 ==> designwizard/patternchecker/SingletonPatternChecker.java=y 6 conf:(0.86) 10. designwizard/design/entity/ui/Field.java=y 7 ==> designwizard/design/entity/ui/Class.java=y 6 conf:(0.86) 11. designwizard/design/DesignIF.java=y 7 ==> designwizard/design/manager/DesignManager.java=y 6 conf:(0.86) 12. designwizard/main/test/DesignWizardTest.java=y 9 ==> designwizard/design/Design.java=y 7 conf:(0.78) 13. designwizard/design/manager/DesignManager.java=y designwizard/test/AllTest.java=y 8 ==> designwizard/design/Design.java=y 6 conf:(0.75) 14. designwizard/patternchecker/SingletonPatternChecker.java=y 8 ==> designwizard/patternchecker/test/SingletonPatternCheckerTest.java=y 6 conf:(0.75) 15. designwizard/patternchecker/test/SingletonPatternCheckerTest.java=y 8 ==> designwizard/patternchecker/SingletonPatternChecker.java=y 6 conf:(0.75) 16. designwizard/patternchecker/SingletonPatternChecker.java=y 8 ==> designwizard/patternchecker/CheckingResult.java=y 6 conf:(0.75) 17. designwizard/design/entity/ClassNode.java=y 8 ==> designwizard/design/entity/test/ClassNodeTest.java=y 6 conf:(0.75) 18. designwizard/design/entity/test/ClassNodeTest.java=y 8 ==> designwizard/design/entity/ClassNode.java=y 6 conf:(0.75) 19. designwizard/design/entity/ClassBL.java=y 8 ==> designwizard/design/entity/ui/Class.java=y 6 conf:(0.75) Anexo C: Regras Obtidas Através da Equação (1) designwizard/design/ClassNode.java (0.46153846153846156) designwizard/design/ClassNode.java (0.6153846153846154) designwizard/design/ClassNode.java (0.5384615384615384) designwizard/design/ClassNode.java (0.6923076923076923) designwizard/design/ClassNode.java (0.5384615384615384) designwizard/design/Design.java => (0.23076923076923078) designwizard/design/Design.java => (0.2692307692307692) designwizard/design/Design.java => (0.23076923076923078) designwizard/design/Design.java => (0.34615384615384615) designwizard/design/Design.java => (0.23076923076923078) designwizard/design/Design.java => (0.2692307692307692) designwizard/design/Design.java => (0.23076923076923078) designwizard/design/Design.java => (0.4230769230769231) => designwizard/design/Design.java => designwizard/design/Entity.java => designwizard/design/FieldNode.java => designwizard/design/MethodNode.java => designwizard/design/test/ClassNodeTest.java designwizard/design/ClassNode.java designwizard/design/DesignIF.java designwizard/design/FieldNode.java designwizard/design/MethodNode.java designwizard/design/entity/AbstractEntity.java designwizard/design/entity/ClassNode.java designwizard/design/entity/ui/Class.java designwizard/design/manager/DesignManager.java designwizard/design/Design.java => designwizard/design/test/ClassNodeTest.java (0.2692307692307692) designwizard/design/Design.java => designwizard/main/test/DesignWizardTest.java (0.2692307692307692) designwizard/design/Design.java => designwizard/test/AllTest.java (0.5) designwizard/design/DesignIF.java => designwizard/design/Design.java (1.0) designwizard/design/DesignIF.java => designwizard/design/manager/DesignManager.java (0.8571428571428571) designwizard/design/Entity.java => designwizard/design/ClassNode.java (0.6666666666666666) designwizard/design/Entity.java => designwizard/design/FieldNode.java (0.5833333333333334) designwizard/design/Entity.java => designwizard/design/MethodNode.java (0.5) designwizard/design/Entity.java => designwizard/test/AllTest.java (0.5) designwizard/design/FieldNode.java => designwizard/design/ClassNode.java (0.5833333333333334) designwizard/design/FieldNode.java => designwizard/design/Design.java (0.5) designwizard/design/FieldNode.java => designwizard/design/Entity.java (0.5833333333333334) designwizard/design/FieldNode.java => designwizard/design/MethodNode.java (0.5833333333333334) designwizard/design/FieldNode.java => designwizard/design/test/ClassNodeTest.java (0.5) designwizard/design/MethodNode.java => designwizard/design/ClassNode.java (0.5294117647058824) designwizard/design/MethodNode.java => designwizard/design/Design.java (0.5294117647058824) designwizard/design/MethodNode.java => designwizard/design/Entity.java (0.35294117647058826) designwizard/design/MethodNode.java => designwizard/design/FieldNode.java (0.4117647058823529) designwizard/design/MethodNode.java => designwizard/design/test/ClassNodeTest.java (0.4117647058823529) designwizard/design/MethodNode.java => designwizard/test/AllTest.java (0.35294117647058826) designwizard/design/entity/AbstractEntity.java => designwizard/design/Design.java (0.6666666666666666) designwizard/design/entity/AbstractEntity.java => designwizard/design/manager/DesignManager.java (0.6666666666666666) designwizard/design/entity/ClassBL.java => designwizard/design/entity/ui/Class.java (0.75) designwizard/design/entity/ClassNode.java => designwizard/design/Design.java (0.875) designwizard/design/entity/ClassNode.java => designwizard/design/entity/test/ClassNodeTest.java (0.75) designwizard/design/entity/test/ClassNodeTest.java => designwizard/design/entity/ClassNode.java (0.75) designwizard/design/entity/ui/Class.java => designwizard/design/Design.java (0.5454545454545454) designwizard/design/entity/ui/Class.java => designwizard/design/entity/ClassBL.java (0.5454545454545454) designwizard/design/entity/ui/Class.java => designwizard/design/entity/ui/Field.java (0.5454545454545454) designwizard/design/entity/ui/Class.java => designwizard/design/entity/ui/Method.java (0.5454545454545454) designwizard/design/entity/ui/Field.java => designwizard/design/entity/ui/Class.java (0.8571428571428571) designwizard/design/entity/ui/Method.java => designwizard/design/entity/ui/Class.java (0.6) designwizard/design/manager/DesignManager.java => designwizard/design/Design.java (0.4782608695652174) designwizard/design/manager/DesignManager.java => designwizard/design/DesignIF.java (0.2608695652173913) designwizard/design/manager/DesignManager.java => designwizard/design/entity/AbstractEntity.java (0.2608695652173913) designwizard/design/manager/DesignManager.java => designwizard/main/DesignWizard.java (0.30434782608695654) designwizard/design/manager/DesignManager.java => designwizard/test/AllTest.java (0.34782608695652173) designwizard/design/test/ClassNodeTest.java => designwizard/design/ClassNode.java (0.4666666666666667) designwizard/design/test/ClassNodeTest.java => designwizard/design/Design.java (0.4666666666666667) designwizard/design/test/ClassNodeTest.java => designwizard/design/FieldNode.java (0.4) designwizard/design/test/ClassNodeTest.java => designwizard/design/MethodNode.java (0.4666666666666667) designwizard/design/test/ClassNodeTest.java => designwizard/main/test/DesignWizardTest.java (0.4) designwizard/design/test/ClassNodeTest.java => designwizard/test/AllTest.java (0.6) designwizard/main/DesignWizard.java => designwizard/design/manager/DesignManager.java (0.5833333333333334) designwizard/main/test/DesignWizardTest.java => designwizard/design/Design.java (0.7777777777777778) designwizard/main/test/DesignWizardTest.java => designwizard/design/test/ClassNodeTest.java (0.6666666666666666) designwizard/main/test/DesignWizardTest.java => designwizard/test/AllTest.java (0.6666666666666666) designwizard/patternchecker/CheckingResult.java => designwizard/patternchecker/SingletonPatternChecker.java (0.8571428571428571) designwizard/patternchecker/SingletonPatternChecker.java => designwizard/patternchecker/CheckingResult.java (0.75) designwizard/patternchecker/SingletonPatternChecker.java => designwizard/patternchecker/test/SingletonPatternCheckerTest.java (0.75) designwizard/patternchecker/test/SingletonPatternCheckerTest.java => designwizard/patternchecker/SingletonPatternChecker.java (0.75) designwizard/test/AllTest.java => designwizard/design/Design.java (0.65) designwizard/test/AllTest.java => designwizard/design/Entity.java (0.3) designwizard/test/AllTest.java => designwizard/design/MethodNode.java (0.3) designwizard/test/AllTest.java => designwizard/design/manager/DesignManager.java (0.4) designwizard/test/AllTest.java => designwizard/design/test/ClassNodeTest.java (0.45) designwizard/test/AllTest.java => designwizard/main/test/DesignWizardTest.java (0.3) designwizard/test/AllTest.java => designwizard/test/design/DesignWizardTest.java (0.3) designwizard/test/design/DesignWizardTest.java => designwizard/test/AllTest.java (0.5)