• Nenhum resultado encontrado

PSMF com Arrays: exemplo de suíte de testes

2 Para ser conciso, só foi relatado a síntese do aMax. Os scripts para todos os outros exemplo podem ser encontrados no website do projeto PSMF: https://github.com/PSMFg/psmf/wiki.

1 _ o u t _ i n t _ O u t L o c =13; _ i n _ i n t _ I n L o c 1 =0; _ i n _ i n t _ I n L o c 2 =4; _ i n _ i n t A r r _ I n A r r a y 1 = [ 0 ] 2 = [ 1 ] 4 = [ 2 ] 6 = [ 3 ] 1 3 = [ 4 ] 0 = [ 5 ] 0 ; 2 _ o u t _ i n t _ O u t L o c =13; _ i n _ i n t _ I n L o c 1 =0; _ i n _ i n t _ I n L o c 2 =5; _ i n _ i n t A r r _ I n A r r a y 1 = [ 0 ] 5 = [ 1 ] 2 = [ 2 ] 1 = [ 3 ] 1 3 = [ 4 ] 6 = [ 5 ] 0 ; 3 _ o u t _ i n t _ O u t L o c =13; _ i n _ i n t _ I n L o c 1 =0; _ i n _ i n t _ I n L o c 2 =6; _ i n _ i n t A r r _ I n A r r a y 1 = [ 0 ] 2 = [ 1 ] 6 = [ 2 ] 1 = [ 3 ] 4 = [ 4 ] 1 3 = [ 5 ] 5 ;

Finalmente, os programas aMax, aSum e eCount usamarrays apenas para entrada dos valores, o que implica que os estados inicial e final dos elementos dos arrays permanecem o mesmo. Por outro lado, os programas aDouble, aBubSort e aSelSort usam arrays para entradas e saídas, o que significa que seus estados inicial e final irão mudar e esse fato tem uma relação direta com o problema da explosão de estados no analisador Alloy* relatado nas seções 1.2 e 2.1.2.

Soft Sketch → há diversas soluções, em termos de código-fonte, para o programa aMax, e uma delas é mostrada na coluna Programa sintetizado na Figura 8. Neste caso, o PSMF pode manipular até 10 possíveis lacunas sintáticas, denotada pelos símbolos ?1, . . . , ?10 na coluna Lacuna sintática. A coluna Lacuna sintática mostra um sketch tradicional de Solar-Lezama (SOLAR-LEZAMA et al., 2006), que também pode ser usado no PSMF em conjunto com o soft sketch.

Agora, observe a coluna Soft sketch. Perceba que tanto a linha //s1 quanto //s2 do soft sketch podem preencher as lacunas ?2 ou ?4. Também, as linhas //s3 e //s4 do soft sketch podem preencher a lacuna sintática ?5=?6, ?8, ou ?9=?10. Mais ainda, a lacuna ?8 pode ser qualquer expressão aritmética, inclusive uma expressão vazia. Como o PSMF funciona com soft sketches, a ordem de execução (//s2→//s1→//s4→//s3) do Programa sintetizado foi diferente da ordem listada na coluna de Soft sketch (//s1→//s2→//s3→//s4).

Finalmente, ao olhar para a coluna Lacuna sintática da Tabela 8 no aMax, percebe- se que, embora o PSMF desconheça, o código-fonte esperado teria 10 lacunas para serem preenchidas (?1, . . . , ?10). Note que o soft sketch apresentado na mesma Tabela ajuda a preencher 4 lacunas sintáticas (por exemplo: ?2, ?4, ?6 e ?10), ou seja, o PSMF foi capaz de preencher 6 (que corresponde a até 60%) das lacunas sintáticas na síntese do programa aMax. À medida que os programas foram ficando mais complexos, ocorreu um aumento da dificuldade em sintetizar o código-fonte a partir dos sketches fornecidos. O PSMF preencheu até: 57% (4 of 7) das lacunas, incluindo o índice do array nos programas aDouble e aSum; e 60% (6 of 10) no programa eCount. Na síntese dos programas de ordenação, foram preenchidos (43%, 7 de 16) no aBubSort e (25%, 5 of 20) no aSelSort. Nestes programas de ordenação, o tamanho dos sketches chegaram a ser próximos do código-fonte solução, semelhante ao que aconteceu no trabalho de Solar-Lezama et al. (2006).

Ingredientes sintáticos → para manipulararrays, foram incluídos mais quatro cons- trutores sintáticos: Swap (que troca o valor entre duas variáveis, por exemplo x=a; y=b;

Prog Lacuna sintática Exemplos Soft sketch Programa sintetizado aMax ?1(?2) { ?3(?4) { ?5=?6; } ?7 { ?8 } ?9=?10; } [0]2; [1]3; [2]1→3 InArray1[InLoc1] > OutLoc //s1 InLoc2 > InLoc1 //s2 ??=InLoc1+1 //s3 ??=InArray1[InLoc1] //s4

OutLoc=0; //Read InLoc1, //Read InLoc2, inArray1 while(InLoc2 >InLoc1) { if(InArray1[InLoc1] >OutLoc) { OutLoc=InArray1[InLoc1]; } else { } InLoc1=InLoc1+1; } aDouble ?1(?2) { ?3= ?4; ?5= ?6; } [0]2; [1]3; [2]1→ [0]4; [1]6; [2]2 InLoc1<InLoc2 //s1 ??= InLoc1+1 //s2 ??= 2*IOArray1[??] //s3 OutLoc=0; InLoc1=0; //read InLoc2; IOArray1; while(InLoc1 < InLoc2) { IOArray1[InLoc1]= 2*IOArray1[InLoc1]; InLoc1= InLoc1+1; } aSum ?1(?2) { ?3= ?4; ?5= ?6; } [0]2; [1]3; [2]1→6 InLoc2 >InLoc1 //s1 ??=InLoc1+1 //s2 ??=OutLoc+ InArray1[??] //s3

OutLoc=0; //Read InLoc1, //Read InLoc2, inArray1 while(InLoc2 > InLoc1) { OutLoc= OutLoc+ InArray1[InLoc1]; InLoc1= InLoc1+1; } eCount ?1(?2) { ?3(?4) { ?5=?6; } ?7 { ?8 } ?9= ?10; } [0]2; [1]3; [2]2; [3]1; [4]2→3 InArray1[InLoc1]== InLoc3 //s1 InLoc2 >InLoc1 //s2 InLoc1=InLoc1+1 //s3 OutLoc=OutLoc+1 //s4

OutLoc=0; //Read InLoc1, InLoc2 //Read InLoc3, inArray1

while(InLoc2>InLoc1) { if(InArray1[InLoc1]==InLoc3) { OutLoc=OutLoc+1; } else { } InLoc1= InLoc1+1; } aBubSort ?1(?2) { ?3=?4; ?5 (?6) { ?7 (?8) { swap(?9, ?10) } ?11 { ?12 } ?13=?14; } ?15=?16; } [0]2; [1]3; [2]1→[0]1; [1]2; [2]3 while (?2) { ?3=InLocI+1; while (?6) { if (?8) { swap(j, i); } else { ?12 } ?13=InLocJ+1; } ?15=InLocI+1; } InLocI=0; InLimI=IONum.length-1; InLocJ=0; InLimJ=IONum.length; while (InLocI<InLimI) { InLocJ=InLocI+1; while (InLocJ<InLimJ) { if (j<i) { swap(j, i); } else { } //skip InLocJ= InLocJ+1; } InLocI=InLocI+1; } aSelSort ?1(?2) { ?3=?4; ?5=?6; ?7(?8) { ?9(?10) { ?11=?12; } ?13 { ?14 } ?15=?16; } swap(?17, ?18) ?19=?20; } [0]2; [1]3; [2]1→[0]1; [1]2 [2]3 while (InLocI< InLocN-1) { ?3 = InLocI; ?5 = InLocI+1; while (InLocJ< InLocN) { if (j<m) { ?11= InLocJ; } else { } ?15=InLocJ+1; } swap(i, m) ?19=?20; } InLocN = IONum.length; InLocI=InLocMin=InLocJ=0; while (InLocI< InLocN-1) { InLocMin = InLocI; InLocJ = InLocI+1; while (InLocJ<InLocN) { if (j<m) { InLocMin= InLocJ; } else { } InLocJ=InLocJ+1; } swap(i, m) InLocI=InLocI+1; }

Tabela 8 – Entradas e programas sintetizado usando PSMF com arrays. Para simplificar a exibição, considere j=IONum[InLocJ], i=IONum[InLocI], e m=IONum[InLocMin].

→ x=b; y=a;), IntArrVar (arrays de inteiros), LTH (operador menor que <) e Skip (um comando que faz nada, usado, por exemplo, em uma estrutura if-then-else, quando o construtor else é vazio). Passando de 14 para 18 ingredientes sintáticos a serem usados no PSMF, que funcionam do mesmo jeito descrito na Seção 4.2.1.

Na síntese do aMax (Tabela 9), foram definidos os seguintes construtores sintáticos: Sketch (Assign, Add, IntArrVar, GTH); Manual (Swap 0:0); e Automático (IntVar, IntVal, SComp, CondS, Skip, While, Sub, Mult, EQ, NEQ, LEQ, GEQ, LTH). A Tabela 8 mostra os programas, lacunas sintáticas, soft sketch e código-fonte sintetizado para os programas aMax, aSum, aDouble, eCount, aBubSort e aSelSort.

Para cada programa sintetizado, é mostrado na Tabela 9 o tempo médio de 10 execu- ções (em segundos), o desvio padrão, o coeficiente de variação e o número de programas candidatos que o sistema testou antes de entregar uma solução (#Cand).

Prog. Média Desv. Pad. Coef. Var(%) #Cand.

aMax 14,0 0,4 2,97 1 aDouble 18,0 0,8 4,31 1 aSum 151,0 6,1 4,07 16 eCount 347,3 7,2 2,08 15 aBubSort 271,0 1,0 0,37 3 aSelSort 407,0 5,6 1,37 10

Tabela 9 – Tempo de execução (segundos) da tarefa de síntese.

Em linhas gerais, o desempenho dos seis programas (Tabela 9) tem uma relação direta com as complexidades: (i) do soft sketch usado na tarefa de síntese; e (ii) do código-fonte como solução esperada. Ao olharmos para a coluna Programa sintetizado (Tabela 8) perceberemos, mesmo que subjetivamente, a diferença de complexidade entre os códigos- fontes, por exemplo, o do aBubSort é mais complexo do que o do aDouble.

Contudo, olhando para aSum e aMax na coluna Programa sintetizado (Tabela 8) o leitor indicaria o aMax sendo mais complexo que o aSum. Mas por que o número de programas candidatos e o tempo para encontrar uma solução no aSum foi tão maior que os do aMax? Neste caso, ao olhar para a coluna Soft sketch da Tabela 8 percebe-se que no aMax o índice do array já foi indicado InArray1[InLoc1], enquanto que no aSum está como lacuna sintática InArray1[??], e essa diferença aumenta o espaço de busca. Assim, observa-se que no aMax o PSMF foi capaz de encontrar uma solução logo no primeiro programa candidato (#Cand.=1) após 14 segundos, enquanto que no aSum só se chegou a uma solução, depois de gerar e testar 16 programas candidatos e um consumo de tempo quase onze vezes maior (151 segundos) que o aMax.

4.3.2 Discussão dos resultados

Do que foi apresentado até aqui, verifica-se que o PSMF proposto trouxe alguns benefí- cios para realizar a tarefa de síntese, vistos três desafios na área de síntese de programas (seção 2.1.2) e quatro do PSMF inicial 2.5.3). Os desafios analisados na síntese de pro- gramas sem Arrays (Seção 4.2.3), tiveram aqui (com Arrays) resultados análogos, exceto dois deles que serão detalhados a seguir:

1. Explosão de estados → com o uso de arrays, o problema de explosão de esta- dos (Seção 2.1.2) volta a ser uma preocupação crucial. Grosso modo, o sintetizador manipula arrays tratando o container que o representa como uma sequência de elementos variáveis individuais (variável que guarda apenas um elemento) e, por isso, a cada iteração do programa, irá guardar os estados inicial e final de todos os elementos do array no container. Note que, se fosse uma sequência de variáveis individuais, poderia ser até menos custoso pois, no caso docontainer que representa o array, se o elemento sofreu (ou não) alteração, gerará a necessidade de guardar os seus estados. Usando um exemplo em linguagem Java, teríamos um array ax que poderia armazenar até três elementos (int[3] ax;) consumindo o mesmo recurso computacional de três variáveis x1, x2, x3 (int x1, x2, x3;) que armazenam ape- nas um elemento cada. Desta forma a síntese de programas que envolvam poucos

arrays e seus respectivos containers com muitos elementos (por exemplo, suponha

guardar num laço while os estados inicial e final de 3arrays com 10 elementos cada. A cada volta no laço estamos falando em guardar até 60 estados nos containers). Ou o reverso (muitos arrays com poucos elementos), que pode exceder a capacidade de memória do analisador Alloy*, inviabilizando o uso do PSMF. Uma alternativa para mitigar a dificuldade apresentada seria continuar a usar os exemplos E/S com o menor número de elementos (três no máximo) e a menor quantidade de arrays (um ou dois), deixando para a suíte de testes tantos arrays e tão longos quantos forem a vontade do usuário (diversos arrays com dezenas, centenas ou milhares de elementos).

2. Definição do sketch → voltando a observar a coluna Lacuna sintática, da Ta- bela 8, percebe-se que, embora o PSMF desconheça, o código-fonte esperado para o aMax teria 10 lacunas para serem preenchidas (?1, . . . , ?10). Note que o soft

sketch apresentado na mesma Tabela ajudou a preencher 4 lacunas sintáticas (por

exemplo: ?2, ?4, ?6 e ?10), ou seja, foi fornecido até 40% (4 de 10) de soft sketch na síntese do aMax, patamar que ficou próximo dos problemas de síntese sem Ar-

rays (PSMF proposto na Seção 4.2.3). À medida que os programas foram ficando

mais complexos (usando o mesmo raciocínio adotado para o aMax) o percentual de soft sketch fornecido se igualou ou aumentou em relação ao aMax: 40% no pro- grama eCount, 43% nos programas aDouble e aSum. Na síntese dos programas de

ordenação, foram incluídos até 57% no aBubSort e 75% no aSelSort de sketch. Nes- tes programas de ordenação, o tamanho dos sketches chegaram a ser próximos do código-fonte solução, situação semelhante ao que aconteceu no trabalho de Solar- Lezama et al. (2006). Uma alternativa para mitigar a dificuldade apresentada, seria gerar os soft sketches automaticamente, estendendo a estratégia evolucionária usada neste trabalho (Seção 3.6.1).

4.4 EFETIVIDADE DO ALGORITMO GENÉTICO NO PSMF PROPOSTO

Esta seção ilustra como mudanças nos parâmetros do PSMF proposto afetam o tempo de busca por uma solução ao mesmo tempo que testa a eficiência da técnica de algoritmo genético (fundamentada nas seções 2.3 e 3.6) quando a faixa de valores do escopo de alguns ingredientes sintáticos é alargada.

São usados os mesmos ajustes dos experimentos da Seção 4.2, exceto que:

• O tamanho da população de programas candidatos foi alargado de 3 para 30 indi- víduos;

• O número de gerações que a população de programas candidatos pode evoluir foi alargado de 5 para 20;

• O espaço de busca foi alargado, visto que as faixas de valores dos palpites manu- ais de alguns ingredientes sintáticos foram alargados dos valores lbfrom:ubfrom (que aparecem na Tabela 4 sendo aqui repetidos) para os valores lbto:ubto, ou seja, na proporção lbfrom:ubfrom → lbto:ubto.

• Por exemplo, quando mudamos o escopo de 3 ingredientes sintáticos, o espaço de busca foi expandido 64 vezes no Maj5 (SComp 1:1→0:3, CondS 1:1→0:3, GTH 1:1→0:3) e 16 vezes no Fib (SComp 2:2→0:3, While 1:1→0:1, GTH 1:1→0:1). Ou seja, olhando para o Maj5, percebe-se que CondS saltou de 1 para 4 possíveis valores {1} → {0, 1, 2, 3} o que implica 1 → 4, raciocínio análogo se aplica à SComp e GTH, resultando em 4(SComp) * 4(CondS) * 4(GTH) = 64.

Com essas mudanças o tempo usado pelo PSMF proposto para encontrar uma solução aumentou:

• De 56 segundos (no 6o cromossomo na 1a geração) para 3 horas e 55 minutos (no 729o cromossomo na 3a geração) no Maj5; e

• De 16 minutos (no 6o cromossomo na 1a geração) para 12 horas e 45 minutos (no 96o cromossomo na 4a geração) no Fib.

Note que, embora a população seja de 30 indivíduos, houve 729 tentativas e, falando em grosso modo, aproximadamente 90 (que equivale a 3 gerações) viraram programas

candidatos no caso do Maj5, o que representa uma taxa de descarte de ≈ 87% de cromos- somos inaptos. Por raciocínio análogo, no caso do Fib a taxa de descarte foi bem menor visto que apenas ≈ 5% (5 de 96) foram descartados.

Programa Tempo c/ cromossomo feliz Aumento espaço busca Tempo c/ aumento espaço Cromossomo (geração) Descarte % Maj5 00h00m56s 64x 03h55m00s 729o (3a) 87% Fib 00h16m00s 16x 12h45m00s 96o (4a) 05%

Tabela 10 – Efetividade da técnica de algoritmo genético

Com esses resultados (Tabela 10), pode-se inferir que dotar o PSMF com a técnica de algoritmo genético pode levar o PSMF proposto a gastar horas ou dias para encontrar uma solução satisfatória, quanto mais relaxados forem os palpites manuais do usuário ou os ingredientes sintáticos forem deixados em modo automático.

Contudo, dotar o PSMF com a técnica de algoritmo genético pode ainda ser mais interessante do que deixar o usuário realizar a tarefa manualmente como acontecia no PSMF inicial.

No futuro, explorar os estados intermediários dos programas candidatos (como está relatado no Anexo A) poderá ajudar o PSMF a melhorar a eficiência em encontrar um programa candidato que seja a solução da tarefa de síntese.

4.5 CONSIDERAÇÕES FINAIS

Este capítulo apresentou um conjunto de experimentos e avaliação do problema de síntese de programas enunciado nos capítulos 1 e 2 e de uma solução proposta no Capítulo 3. Além das contribuições (Seção 4.1), o comportamento do PSMF foi analisado a partir da defi- nição de um conjunto de parâmetros do sistema, que caracterizam um cromossomo feliz, com experimentos conduzidos na síntese de dezesseis programas clássicos, sem (Seção 4.2) e comArrays (Seção 4.3). Em seguida, os parâmetros que caracterizam o cromossomo feliz foram relaxados, aumentando o espaço de busca 16 vezes (no Fib) e 64 vezes (no Maj5), evidenciando a efetividade da estratégia de algoritmo genético no PSMF (Seção 4.4). Os resultados dos experimentos mostraram que algumas das dificuldades apontadas na ta- refa de síntese (Seção 2.1.2) e no PSMF inicial (Seção 2.5.3) foram mitigadas. Ainda que restem algumas situações de exceção, propostas de como enfrentá-las foram apresentadas, potencializando o uso do PSMF pelo usuário final.

Além dos 4 programas sintetizados no PSMF inicial (Swap2, Max2, Max3 e GCD), o PSMF proposto também sintetizou mais outros 13 programas (Maj5, maioria de 8 valores ou Majority8 (Maj8), Max4, resto da divisão entre 2 números (Modu), fatorial de um número (Fact), IntSqrt, Fib, aMax, aDouble, aSum, eCount, aBubSort e aSelSort) como mostrado nas tabelas 3 e 11 e cujo tempo de síntese é mostrado nas tabelas 7 e 9.

Programa Exemplos Soft sketch Programa sintetizado Fib 3→2; ?? = Res+v3; ?? = Res-v3; ?? = v2+1; v1=read();v2=Res=0;v3=1; while (v1 > v2) { v2 = v2 + 1; Res= Res + v3; v3= Res - v3; } Maj5 1,2,1,1,1→1; 2,1,1,2,1→1; 1,2,2,1,2→2; ?? = v1; ?? = v2; ??= v4+v5+. . . +v8; v1=1; v2=2; v3=7; Res=0; //Read v4,v5,v6,v7,v8 Res=v4+v5+v6+v7+v8; if(Res >v3) { Res = v2;} else { Res = v1; } Maj8 1,2,1,1,1,1, 1,1→1; 2,2,1,2,1,2, 1,1→1; 1,2,2,1,2,2, 1,2→2; ?? = v1; ?? = v2; ??=v4+v5+. . . +v11; v1 = 1; v2 = 2; v3= 12; Res = 0; // Read v4,v5,..,v11 Res=v4+v5+...+v11; if (Res >v3) {Res = v2;} else {Res = v1;} Max4 5,7,2,1→7; 7,2,5,1→7; 1,5,7,2→7; 5,1,2,7→7; v1 >v2; v1 >v3; v1 >v4; v2 >v3; v2 >v4; v3 >v4; ?? = v1; ?? = v2; ?? = v3; ?? = v4; Res=0;//Read v1,v2,v3,v4 if(v1 >v2) { if(v1 >v3) { if(v1 >v4) {Res = v1;} else {Res = v4;} } else { if(v3 >v4) {Res=v3;} else {Res = v4;} } } else { if(v2 >v3) { if(v2 >v4) {Res = v2;} else {Res = v4;} } else { if(v3 >v4) {Res = v3;} else {Res = v4;} } } Modu 3,2→1; ?? = v2+v1 -v3; ?? = v4+1; ?? = v2*v4; //Read v1,v2 v3=v4=Res=0; while(v3 <= v1) { v4 = v4 + 1; v3 = v2 * v4; Res = v2 + v1 - v3; } Fact 3→6; ?? = v2; ?? = v2 * v3; ?? = v3 + 1; v1=read();v2=1;v3=Res=0; while(v1 >v3) { v3 = v3 + 1; v2 = v2 * v3; } Res = v2;

5 PSMF E OUTRAS FITNESS

Este capítulo apresenta uma proposta para melhorar a convergência para uma solução na tarefa de síntese (Seção 2.1.2). Com o objetivo mencionado e contribuições elencadas (Se- ção 5.2), cinco distâncias diferentes da métrica discreta (através de uma estratégia aqui denominada de S1) são implementadas no PSMF, permitindo ao usuário escolher uma das seis disponíveis (discreta, Manhattan, Euclidiana quadrática, Chebyshev, Hellinger, Minkowski) de um conjunto de distâncias (DEZA; DEZA, 2009; CHA, 2007) como métrica do cálculo da fitness (Seção 5.3). O comportamento do PSMF é analisado a partir da defi- nição de um conjunto de parâmetros do sistema com experimentos conduzidos (Seção 5.4) na síntese de dois programas conhecidos (GCD e Max4) e resultados são apresentados, discutidos (Seção 5.5) e conclusões são emitidas (Seção 5.6).

5.1 CARACTERIZAÇÃO DO PROBLEMA E OBJETIVO

Entre as dificuldades e propostas de mitigá-las, apresentadas na Seção 2.1.2, este capítulo usa métricas alternativas para cálculo da função de fitness (neste documento definida como Estratégia S1) para tentar melhorar a convergência para uma solução (Dificuldade D1).

Surgem então o seguinte questionamento: Se usarmos outras distâncias, dife- rentes da discreta, se encontrará uma solução com menos (mais ou a mesma quantidade de) chamadas para o cálculo da fitness? Alguma das distâncias a serem usadas teria melhor desempenho, ou seja, chegar-se-ia a uma solução com o menor número de chamadas do cálculo da fitness?

A hipótese nula 𝐻0 é que as diferentes métricas para a função de fitness dão pratica- mente o mesmo resultado no uso do sistema. Portanto: 𝐻0 denota que não há diferença em adotar preferencialmente alguma métrica. A hipótese alternativa 𝐻1 é que ocorrerá uma diferença significativa após a implementação da Estratégia S1. São conduzidos ex- perimentos e análise estatística (Seção 5.4) para rejeitar (ou não) 𝐻0.

A motivação para investigar o comportamento do PSMF com outras métricas para o cálculo da função de fitness encontra fundamentação em dois aspectos (GAUDESI; SQUIL- LERO; TONDA, 2013): (i) poder revelar diferenças nos dados de saída que a distância discreta não revela; (ii) gerar expectativa de que características do fenótipo1 de um pro- grama candidato (até então não observadas) possam emergir.

1 Biologicamente falando, fenótipo é a composição das características observáveis de um indivíduo resul- tante da interação do seu genótipo com o ambiente. Este conceito é difícil de traduzir para computação evolucionária, uma vez que o ambiente não está presente. Logo, tenta-se definir o fenótipo indireta- mente, observando o valor de fitness do programa candidato.

Por exemplo, considere dois programas candidatos 𝑝1 e 𝑝2, com saída calculada/espe- rada (𝑝1:3/5 e 𝑝2:7/30) em um teste. Usando distância discreta, verifica-se que o valor de fitness será o mesmo, o que indica que 𝑝1 e 𝑝2 tem a mesma probabilidade de compor a próxima geração no processo evolucionário. Se usarmos uma distância que revele esta diferença do valor de saída calculado/esperado, poderá favorecer programas candidatos com distâncias mais próximas de uma solução. Mais informação sobre os aspectos de motivação são apresentadas na Seção 5.3.

5.2 CONTRIBUIÇÕES

As principais contribuições descritas neste capítulo são:

1. Verificar se a convergência para uma solução na tarefa de síntese melhora (ou não) ao permitir o uso de cinco métricas diferentes da distância discreta para cálculo da função de fitness (estratégia S1);

2. Incorporar no sintetizador PSMF uma nova funcionalidade que permite ao usuá- rio escolher uma métrica entre seis disponíveis (discreta, Manhattan, Euclidiana quadrática, Chebyshev, Hellinger, Minkowski) para o cálculo do valor da fitness; 3. No contexto dos itens anteriores, apresentar um conjunto de experimentos ilus-

trando o desempenho do sistema na síntese de dois programas bem conhecidos: GCD e Max4. Os resultados revelam que não há melhora (ou piora) em usar ou- tras distâncias, como também indicam que usar a distância discreta é suficiente e, portanto, a melhor escolha para o cálculo do fitness entre as outras cinco; e

4. Compilar o sistema como um software disponibilizado publicamente2 para que in- teressados possam repetir os resultados aqui gerados e sintetizar outros programas com similar nível de complexidade.

5.3 SISTEMA PROPOSTO

O sistema proposto tem as mesmas características do proposto no Capítulo 3, adicionando a capacidade de usar métricas alternativas para cálculo da função de fitness (estratégia S1).

No contexto deste trabalho, Métrica, Distância e Similaridade são assim definidos (DEZA; DEZA, 2009):

1. Métrica → Seja 𝑋 um conjunto. Uma função 𝑑 : 𝑋 × 𝑋 → R é chamada uma métrica em 𝑋 se, para todo 𝑥, 𝑦, 𝑧 ∈ 𝑋, sempre se verificam as seguintes pro- priedades: (i) não negatividade 𝑑(𝑥, 𝑦) ≥ 0; (ii) identidade 𝑑(𝑥, 𝑦) = 0, se e so- 2 Mais informação no website do projeto PSMF: https://github.com/PSMFg/psmf/wiki.

mente se 𝑥 = 𝑦; (iii) simetria 𝑑(𝑥, 𝑦) = 𝑑(𝑦, 𝑥); e (iv) desigualdade triangular

𝑑(𝑥, 𝑦) ≤ 𝑑(𝑥, 𝑧) + 𝑑(𝑧, 𝑦).

2. Distância → Seja 𝑋 um conjunto. Uma função 𝑑 : 𝑋 × 𝑋 → R é chamada uma distância ou dissimilaridade em 𝑋 se, para todo 𝑥, 𝑦 ∈ 𝑋, sempre se verificam as seguintes propriedades: (i) não negatividade 𝑑(𝑥, 𝑦) ≥ 0; (ii) simetria 𝑑(𝑥, 𝑦) =

𝑑(𝑦, 𝑥); e (iii) reflexibilidade 𝑑(𝑥, 𝑥) = 0.

3. Similaridade → Seja X um conjunto. Uma função 𝑠 : 𝑋 × 𝑋 → R é chamada uma similaridade em X, se para todo 𝑥, 𝑦 ∈ 𝑋, sempre se verificam as seguintes propriedades: (i) não negatividade 𝑠(𝑥, 𝑦) ≥ 0; (ii) simetria 𝑠(𝑥, 𝑦) = 𝑠(𝑦, 𝑥); e (iii) se 𝑠(𝑥, 𝑦) ≤ 𝑠(𝑥, 𝑥), onde a igualdade dessa inequação ocorrerá apenas quando

𝑥 = 𝑦.

Em relação à função defitness, a proposta do Capítulo 3 usa métrica discreta (também conhecida como métrica trivial). Ou seja, em cada teste, é verificado se a saída calculada do programa candidato (𝑞𝑖) foi igual à saída esperada (𝑝𝑖), resultando em uma resposta

“sim” ou “não” (0 ou 1). A partir disto, então calculava-se a taxa de acertos (percentual de testes que passaram). Ou seja, quanto maior o valor de fitness, melhor para o processo evolucionário convergir para o êxito da tarefa de síntese (achar uma solução desejada).

Neste capítulo, a métrica discreta se transforma em distância discreta 𝑑𝐷𝑠𝑐𝑡 (assim

como todas as demais métricas que também serão usadas como distâncias). A distância discreta 𝑑𝐷𝑠𝑐𝑡 é definida como

𝑑𝐷𝑠𝑐𝑡(𝑝1, . . . 𝑝𝑛, 𝑞1, . . . , 𝑞𝑛) = 100 𝑛 𝑛 ∑︁ 𝑖=1 𝑟𝑖(𝑝𝑖, 𝑞𝑖) (5.1)

onde 𝑟𝑖(𝑝𝑖, 𝑞𝑖) = 0 se 𝑝𝑖 = 𝑞𝑖, e 𝑟𝑖(𝑝𝑖, 𝑞𝑖) = 1 caso contrário, 𝑝𝑖 é a saída esperada e 𝑞𝑖 é a

saída calculada do programa candidato. Ou seja, quanto menor a distância, mais próximo da solução. Logo o valor de fitness poderá diminuir até ser igual a zero, denotando que encontrou uma solução que passa em todos os testes da suíte.

A introdução de outras distâncias pode revelar diferenças nos dados de saída que a distância discreta não revela. Suponha dois programas candidatos: 𝑝𝑐1, que devolve para os testes 𝑡1 e 𝑡2 os valores 2 e 5, respectivamente, quando os valores esperados seriam 3 e 4. E 𝑝𝑐2, que devolve para os mesmos testes 𝑡1 e 𝑡2 os valores -30 e 75, quando os valores esperados seriam os mesmos 3 e 4, respectivamente. Na distância discreta, os dois programas candidatos (𝑝𝑐1 e 𝑝𝑐2) terão o mesmo valor defitness (vão ser computados dois erros em cada) não levando-se em conta a distância (diferença de valores) entra a saída esperada e a saída calculada e isso pode ser relevante para o processo de busca.

Dois diferentes aspectos podem ser examinados quando uma distância é definida: o propósito de calculá-la; e o nível no qual a distância é calculada.

No primeiro aspecto, a intenção é ter um balizador que ajude a guiar a busca do ponto inicial até atingir o alvo. Ou seja, se, a cada novo programa candidato, a distância usada

no cálculo do fitness diminuir, tem-se um indicador de que a busca pode convergir para o alvo (se a distância for igual a zero, chegou-se a uma solução).

O segundo aspecto pode ocorrer em três níveis: Genótipo, fitness ou fenótipo. Os dois primeiros níveis são fáceis de definir, pois o genótipo corresponde à representação interna (genes) de um programa candidato e a função de fitness corresponde ao valor resultante da sua avaliação. Biologicamente falando, o fenótipo é a composição de todas as características observáveis de um indivíduo resultante da interação do seu genótipo com o ambiente. Esse conceito de fenótipo é difícil de traduzir para a área de computação evolucionária, uma vez que o ambiente não está presente. Logo, tenta-se definir o fenótipo