Skip to content

Commit

Permalink
Merge pull request #167 from kusumotolab/keep_fixed_variants
Browse files Browse the repository at this point in the history
KGenProgMainの最低限の機能を実装
  • Loading branch information
shinsuke-mat authored Jul 11, 2018
2 parents bd71563 + d92fd16 commit 9634f17
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 25 deletions.
84 changes: 72 additions & 12 deletions src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package jp.kusumotolab.kgenprog;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jp.kusumotolab.kgenprog.fl.FaultLocalization;
Expand Down Expand Up @@ -33,23 +37,55 @@ public class KGenProgMain {
private SourceCodeValidation sourceCodeValidation;
private VariantSelection variantSelection;
private TestProcessBuilder testProcessBuilder;
private final List<Variant> completedVariants;

// 以下,一時的なフィールド #146 で解決すべき
private final long timeout;
private final int maxGeneration;
private final int requiredSolutions;

// TODO #146
// workingdirのパスを一時的にMainに記述
// 別クラスが管理すべき情報?
private final Path WORKING_DIR = Paths.get(System.getProperty("java.io.tmpdir"), "kgenprog-work");
public final Path workingDir;

public KGenProgMain(TargetProject targetProject, FaultLocalization faultLocalization,
Mutation mutation, Crossover crossover, SourceCodeGeneration sourceCodeGeneration,
SourceCodeValidation sourceCodeValidation, VariantSelection variantSelection) {

this(targetProject, faultLocalization, mutation, crossover, sourceCodeGeneration,
sourceCodeValidation, variantSelection, 60, 10, 1);
}

public KGenProgMain(TargetProject targetProject, FaultLocalization faultLocalization,
Mutation mutation, Crossover crossover, SourceCodeGeneration sourceCodeGeneration,
SourceCodeValidation sourceCodeValidation, VariantSelection variantSelection,
final long timeout, final int maxGeneration, final int requiredSolutions) {

this.workingDir = Paths.get(System.getProperty("java.io.tmpdir"), "kgenprog-work");
try {
if (Files.exists(this.workingDir)) {
FileUtils.deleteDirectory(this.workingDir.toFile());
}
} catch (final IOException e) {
e.printStackTrace();
}

this.targetProject = targetProject;
this.faultLocalization = faultLocalization;
this.mutation = mutation;
this.crossover = crossover;
this.sourceCodeGeneration = sourceCodeGeneration;
this.sourceCodeValidation = sourceCodeValidation;
this.variantSelection = variantSelection;
this.testProcessBuilder = new TestProcessBuilder(targetProject, WORKING_DIR);
this.testProcessBuilder = new TestProcessBuilder(targetProject, this.workingDir);
this.completedVariants = new ArrayList<>();

this.timeout = timeout;
this.maxGeneration = maxGeneration;
this.requiredSolutions = requiredSolutions;


}

public void run() {
Expand All @@ -58,10 +94,16 @@ public void run() {
final Variant initialVariant = targetProject.getInitialVariant();
selectedVariants.add(initialVariant);
mutation.setCandidates(initialVariant.getGeneratedSourceCode().getFiles());

final long startTime = System.nanoTime();
int generation = 0;
while (true) {
if (isTimedOut() || reachedMaxGeneration() || isSuccess(selectedVariants)) {

// 制限時間に達したか,最大世代数に到達した場合には GA を抜ける
if (isTimedOut(startTime) || reachedMaxGeneration(generation++)) {
break;
}

List<Gene> genes = new ArrayList<>();
for (Variant variant : selectedVariants) {
List<Suspiciouseness> suspiciousenesses =
Expand All @@ -84,28 +126,46 @@ public void run() {
variants.add(variant);
}

// この世代で生成された Variants のうち,Fitnessが 1.0 なものを complatedVariants に追加
final List<Variant> newComplatedVariants =
variants.stream().filter(v -> 0 == Double.compare(v.getFitness().getValue(), 1.0d))
.collect(Collectors.toList());
completedVariants.addAll(newComplatedVariants);

// しきい値以上の complatedVariants が生成された場合は,GAを抜ける
if (areEnoughComplatedVariants()) {
break;
}

// Fitness が 1.0 な Variants は除いた上で,次世代を生成するための Variants を選択
variants.removeAll(newComplatedVariants);
selectedVariants = variantSelection.exec(variants);
}
log.debug("exit run()");
}

// hitori
private boolean reachedMaxGeneration() {
private boolean reachedMaxGeneration(final int generation) {
log.debug("enter reachedMaxGeneration()");
// TODO Auto-generated method stub
return false;
return this.maxGeneration <= generation;
}

// hitori
private boolean isTimedOut() {
private boolean isTimedOut(final long startTime) {
log.debug("enter isTimedOut()");
// TODO Auto-generated method stub
return false;
final long elapsedTime = System.nanoTime() - startTime;
return elapsedTime > this.timeout * 1000 * 1000 * 1000;
}

// hitori
@Deprecated
private boolean isSuccess(List<Variant> variants) {
log.debug("enter isSuccess(List<>)");
return false;
}

private boolean areEnoughComplatedVariants() {
return this.requiredSolutions <= completedVariants.size();
}

public List<Variant> getComplatedVariants() {
return this.completedVariants;
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package jp.kusumotolab.kgenprog.ga;

import java.util.Collections;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SiglePointCrossover implements Crossover{
public class SiglePointCrossover implements Crossover {

private static Logger log = LoggerFactory.getLogger(SiglePointCrossover.class);

@Override
public List<Gene> exec(List<Variant> variants) {
public List<Gene> exec(final List<Variant> variants) {
log.debug("enter exec(List<>)");
// TODO Auto-generated method stub
return null;
return Collections.emptyList();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,27 @@

import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.text.edits.MalformedTreeException;
import jp.kusumotolab.kgenprog.project.GeneratedAST;
import jp.kusumotolab.kgenprog.project.GeneratedSourceCode;
import jp.kusumotolab.kgenprog.project.GenerationFailedSourceCode;
import jp.kusumotolab.kgenprog.project.Location;
import jp.kusumotolab.kgenprog.project.Operation;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.text.edits.MalformedTreeException;

public interface JDTOperation extends Operation {
@Override
default public GeneratedSourceCode apply(final GeneratedSourceCode generatedSourceCode,
final Location location) {

try {
final List<GeneratedAST> newASTs = generatedSourceCode.getFiles().stream()
.map(ast -> applyEachAST(ast, location)).collect(Collectors.toList());
.map(ast -> applyEachAST(ast, location)).collect(Collectors.toList());
return new GeneratedSourceCode(newASTs);
}catch (Exception e) {
e.printStackTrace();
} catch (Exception e) {
// e.printStackTrace();
return GenerationFailedSourceCode.GENERATION_FAILED;
}
}
Expand All @@ -49,4 +49,4 @@ default public GeneratedAST applyEachAST(final GeneratedAST ast, final Location

public void applyToASTRewrite(final GeneratedJDTAST ast, final JDTLocation location,
final ASTRewrite astRewrite);
}
}
118 changes: 118 additions & 0 deletions src/test/java/jp/kusumotolab/kgenprog/KGenProgMainTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package jp.kusumotolab.kgenprog;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
import jp.kusumotolab.kgenprog.fl.FaultLocalization;
import jp.kusumotolab.kgenprog.fl.Ochiai;
import jp.kusumotolab.kgenprog.ga.Crossover;
import jp.kusumotolab.kgenprog.ga.DefaultCodeValidation;
import jp.kusumotolab.kgenprog.ga.DefaultSourceCodeGeneration;
import jp.kusumotolab.kgenprog.ga.DefaultVariantSelection;
import jp.kusumotolab.kgenprog.ga.Mutation;
import jp.kusumotolab.kgenprog.ga.RandomMutation;
import jp.kusumotolab.kgenprog.ga.SiglePointCrossover;
import jp.kusumotolab.kgenprog.ga.SourceCodeGeneration;
import jp.kusumotolab.kgenprog.ga.SourceCodeValidation;
import jp.kusumotolab.kgenprog.ga.VariantSelection;
import jp.kusumotolab.kgenprog.project.DiffOutput;
import jp.kusumotolab.kgenprog.project.ResultOutput;
import jp.kusumotolab.kgenprog.project.SourceFile;
import jp.kusumotolab.kgenprog.project.TargetSourceFile;
import jp.kusumotolab.kgenprog.project.TestSourceFile;
import jp.kusumotolab.kgenprog.project.factory.JUnitLibraryResolver.JUnitVersion;
import jp.kusumotolab.kgenprog.project.factory.TargetProject;
import jp.kusumotolab.kgenprog.project.factory.TargetProjectFactory;

public class KGenProgMainTest {

@Test
public void testExample04() {

final Path rootPath = Paths.get("example/example04/");
final List<SourceFile> targetSourceFiles = new ArrayList<>();
targetSourceFiles.add(new TargetSourceFile(
Paths.get("example/example04/src/jp/kusumotolab/BuggyCalculator.java")));
final List<SourceFile> testSourceFiles = new ArrayList<>();
testSourceFiles.add(new TestSourceFile(
Paths.get("example/example04/src/jp/kusumotolab/BuggyCalculatorTest.java")));

final TargetProject project = TargetProjectFactory.create(rootPath, targetSourceFiles,
testSourceFiles, Collections.emptyList(), JUnitVersion.JUNIT4);

final FaultLocalization faultLocalization = new Ochiai();
final Mutation mutation = new RandomMutation();
final Crossover crossover = new SiglePointCrossover();
final SourceCodeGeneration sourceCodeGeneration = new DefaultSourceCodeGeneration();
final SourceCodeValidation sourceCodeValidation = new DefaultCodeValidation();
final VariantSelection variantSelection = new DefaultVariantSelection();

final KGenProgMain kGenProgMain = new KGenProgMain(project, faultLocalization, mutation,
crossover, sourceCodeGeneration, sourceCodeValidation, variantSelection);
kGenProgMain.run();

final ResultOutput ro = new DiffOutput(kGenProgMain.workingDir);
ro.outputResult(project, kGenProgMain.getComplatedVariants());
}

@Test
public void testExample05() {

final Path rootPath = Paths.get("example/example05/");
final List<SourceFile> targetSourceFiles = new ArrayList<>();
targetSourceFiles.add(new TargetSourceFile(
Paths.get("example/example05/src/jp/kusumotolab/BuggyCalculator.java")));
final List<SourceFile> testSourceFiles = new ArrayList<>();
testSourceFiles.add(new TestSourceFile(
Paths.get("example/example05/src/jp/kusumotolab/BuggyCalculatorTest.java")));

final TargetProject project = TargetProjectFactory.create(rootPath, targetSourceFiles,
testSourceFiles, Collections.emptyList(), JUnitVersion.JUNIT4);

FaultLocalization faultLocalization = new Ochiai();
Mutation mutation = new RandomMutation();
Crossover crossover = new SiglePointCrossover();
SourceCodeGeneration sourceCodeGeneration = new DefaultSourceCodeGeneration();
SourceCodeValidation sourceCodeValidation = new DefaultCodeValidation();
VariantSelection variantSelection = new DefaultVariantSelection();

KGenProgMain kGenProgMain = new KGenProgMain(project, faultLocalization, mutation, crossover,
sourceCodeGeneration, sourceCodeValidation, variantSelection);
kGenProgMain.run();

final ResultOutput ro = new DiffOutput(kGenProgMain.workingDir);
ro.outputResult(project, kGenProgMain.getComplatedVariants());
}

@Test
public void testExample06() {

final Path rootPath = Paths.get("example/example06/");
final List<SourceFile> targetSourceFiles = new ArrayList<>();
targetSourceFiles.add(new TargetSourceFile(
Paths.get("example/example06/src/jp/kusumotolab/BuggyCalculator.java")));
final List<SourceFile> testSourceFiles = new ArrayList<>();
testSourceFiles.add(new TestSourceFile(
Paths.get("example/example06/src/jp/kusumotolab/BuggyCalculatorTest.java")));

final TargetProject project = TargetProjectFactory.create(rootPath, targetSourceFiles,
testSourceFiles, Collections.emptyList(), JUnitVersion.JUNIT4);

FaultLocalization faultLocalization = new Ochiai();
Mutation mutation = new RandomMutation();
Crossover crossover = new SiglePointCrossover();
SourceCodeGeneration sourceCodeGeneration = new DefaultSourceCodeGeneration();
SourceCodeValidation sourceCodeValidation = new DefaultCodeValidation();
VariantSelection variantSelection = new DefaultVariantSelection();

KGenProgMain kGenProgMain = new KGenProgMain(project, faultLocalization, mutation, crossover,
sourceCodeGeneration, sourceCodeValidation, variantSelection);
kGenProgMain.run();

final ResultOutput ro = new DiffOutput(kGenProgMain.workingDir);
ro.outputResult(project, kGenProgMain.getComplatedVariants());
}
}

0 comments on commit 9634f17

Please sign in to comment.