Loading Dockerfile 0 → 100644 +15 −0 Original line number Diff line number Diff line FROM ubuntu:22.04 ENV DEBIAN_FRONTEND="noninteractive" TZ="Europe/London" RUN apt-get update RUN export PATH=$HOME/.local/bin:$PATH RUN apt-get install -y build-essential erlang git maven default-jre default-jdk zip vim ARG CACHE_DATE=2016-01-01 # # # INSTALL e-Knife RUN git clone https://kaz.dsic.upv.es/git/program-slicing/e-knife-erlang.git WORKDIR "/e-knife-erlang" RUN make release EDG/src/main/java/edg/slicing/AdaptedStandardAlgorithm.java +24 −5 Original line number Diff line number Diff line Loading @@ -26,17 +26,25 @@ public class AdaptedStandardAlgorithm extends StandardAlgorithm{ } protected void traverse(Node slicingCriterion, Set<Node> slice, Edge.Type... ignoreEdgeTypes) { final Deque<Node> pendingNodes = new LinkedList<>(slice); final Deque<SliceState> pendingNodes = new LinkedList<>(); for (Node n : slice) pendingNodes.add(new SliceState(n,null)); final Set<Edge.Type> ignoreEdgeTypesSet = new HashSet<>(Arrays.asList(ignoreEdgeTypes)); while (!pendingNodes.isEmpty()) { final Node pendingNode = pendingNodes.removeFirst(); final Set<Edge> nextEdges = edg.getEdges(pendingNode, sliceDirection); final SliceState pendingNode = pendingNodes.removeFirst(); final Set<Edge> nextEdges = edg.getEdges(pendingNode.getNode(), sliceDirection); nextEdges.removeIf(e -> ignoreEdgeTypesSet.contains(e.getType())); nextEdges.removeIf(Edge::isControlFlowEdge); nextEdges.removeIf(e -> !e.isTraversable()); if (pendingNode.getLastEdgeType() != null && pendingNode.getLastEdgeType() == Edge.Type.Structural) nextEdges.removeIf(e -> e.getType() != Edge.Type.Structural); for (Edge nextEdge : nextEdges) { final Node nextNode = sliceDirection == LAST.Direction.Backwards ? Loading @@ -53,12 +61,12 @@ public class AdaptedStandardAlgorithm extends StandardAlgorithm{ nextNodes.add(edg.getResFromNode(nextNode)); for (Node next : nextNodes) { pendingNodes.addLast(next); pendingNodes.addLast(new SliceState(next,nextEdge.getType())); slice.add(next); } } else { pendingNodes.addLast(nextNode); pendingNodes.addLast(new SliceState(nextNode,nextEdge.getType())); slice.add(nextNode); } } Loading Loading @@ -89,4 +97,15 @@ public class AdaptedStandardAlgorithm extends StandardAlgorithm{ return false; } } private class SliceState{ private Node node; private Edge.Type lastEdgeType; public SliceState(Node n, Edge.Type type){ node = n; lastEdgeType = type; } public Node getNode() { return node; } public Edge.Type getLastEdgeType() { return lastEdgeType; } } } e-Knife/src/main/java/eknife/BencherTest.java +19 −1 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ public class BencherTest { return Objects.equals(readFile(slice), readFile(referenceSlice)); } public static void main(String[] args) { public static void main0(String[] args) { new File(EKnife.sliceGenerationCsv).delete(); new File(EKnife.graphGenerationCsv).delete(); EKnife.printHeadings(EKnife.graphGenerationCsv, EKnife.sliceGenerationCsv); Loading Loading @@ -130,4 +130,22 @@ public class BencherTest { }); } public static void main(String[] args) { TEST_PKG = "SetB"; File testFolder = new File("./e-knife-v1.1.0-src/e-Knife/src/test/resources/PaperExperiments/", TEST_PKG); findFiles(testFolder, DOT_ERLANG, file -> { File outputDir = testFolder.getAbsoluteFile(); String inputFileName = testFolder.getAbsolutePath() + File.separator + file.getName(); String outputFileName = outputDir + File.separator + file.getName() + EDG_OUTPUT_SLICE; String[] arguments = {"-i", inputFileName, "-o", outputFileName, "-l", "1", "-v", "X"}; System.out.println("Slicing program "+ file.getName() + " " + BencherTest.cont + (TEST_PKG.equals("SetA") ? "/13": "/17")); BencherTest.cont++; EKnife.generateAllSlices(arguments); }); } } e-Knife/src/main/java/eknife/EKnife.java +161 −2 Original line number Diff line number Diff line Loading @@ -42,6 +42,8 @@ public class EKnife public static final String graphGenerationCsv = "/Users/serperu/Desktop/SlicerOutput/Times/generationTimeMilliseconds.csv"; public static final String sliceGenerationCsv = "/Users/serperu/Desktop/SlicerOutput/Times/slicingStatisticsMicroseconds.csv"; public static final String nodeCounterFile = "/Users/serperu/Desktop/SlicerOutput/Times/programSizes.txt"; public static final String outputSliceGenerationFolder = "/Users/serperu/Desktop/SlicerOutput/Slices/"; public static void main(String[] args) { Loading @@ -59,6 +61,22 @@ public class EKnife EKnife.run(arguments); } public static void generateAllSlices(String[] args){ if (args.length == 0) { EKnife.printHelp(); return; } final Args arguments = EKnife.processArguments(args); if (!arguments.isValid()) { EKnife.printHelp(); System.exit(3); } EKnife.sliceGenerationRun(arguments); } private static Args processArguments(String[] args) { Args kArgs = new Args(); Loading Loading @@ -418,6 +436,132 @@ public class EKnife // CodeFactory.createCode(Language.Erlang, a.outputFile, edg, slice); } private static void sliceGenerationRun(Args a) { // CONFIGURE MEASURED DIMENSIONS boolean performAllSCs = true; /* ***************************************************** */ /* ** MEASUREMENT OF GENERATION TIME (100 executions) ** */ /* ***************************************************** */ final LAST last = LASTFactory.createLAST(Language.Erlang, a.inputPath, true); final EDG edg = new EDGFactory(last).createEDG(); int scFunctionCounter = 0; /* ************************ */ /* ** MEASUREMENT OF SCs ** */ /* ************************ */ if (performAllSCs) { // SC SELECTION List<Node> clauses = edg.getNodes(Node.Type.Clause); clauses.removeIf(c -> edg.getParent(c).getType() != Node.Type.Routine); // printHeadings("/Users/serperu/Desktop/SlicerOutput/Times/slicingStatistics.txt", a.file); for (Node clause : clauses) { Map<String,String> functionCriteria = new HashMap<>(); List<Node> descendants = edg.getDescendants(clause); descendants.add(clause); List<Node> resultNodes = new LinkedList<>(); List<Node> nonResultNodes = new LinkedList<>(); for (Node n : descendants) if (n.getType() == Node.Type.Result) { if (edg.getNodeFromRes(n).getType() != Node.Type.Callee) resultNodes.add(n); } else nonResultNodes.add(n); nonResultNodes.add(clause); resultNodes.add(edg.getResFromNode(clause)); // IGNORE FUNCTIONS WITHOUT COMPOSITE STRUCTURES if (nonResultNodes.stream() .noneMatch( n -> { if (n.getType() == Node.Type.DataConstructor) return true; if (n.getType() == Node.Type.List) if (edg.getChildren(n).size() != 0 || edg.getParent(n).getType() == Node.Type.List) return true; return false;})) { System.out.println("File Name: " + a.file); int functionArity = edg.getChildrenNonResult(edg.getChild(clause, Node.Type.Parameters)).size(); System.out.println("Function " + edg.getParent(clause).getName() + "/" + functionArity + " has no valid slicing criteria."); continue; } /* FILTER SC NODES BY A CRITERION (CONSIDER ONLY VARIABLES) */ resultNodes.removeIf(n -> edg.getNodeFromRes(n).getType() != Node.Type.Variable); String moduleName = edg.getParent(edg.getParent(clause)).getName(); new File(outputSliceGenerationFolder+moduleName).mkdirs(); // CONFIGURE MEASURED DIMENSIONS boolean measureSlicingPerformance = true; final SlicingAlgorithm standardAlgorithm = new AdaptedTwoPassStandardAlgorithm(edg); final SlicingAlgorithm constrainedAlgorithm = new ConstrainedAlgorithm(edg); for (Node SC : resultNodes) { // System.out.println("ID: "+SC.getId()+" Line: "+SC.getInfo().getLine()+" Name "+edg.getNodeFromRes(SC).getName()); Node normalNodeSC = edg.getNodeFromRes(SC); String scString = "<"+normalNodeSC.getInfo().getLine()+","+normalNodeSC.getName()+">"; functionCriteria.put("#"+scFunctionCounter,scString); // INITIALIZATIONS // PERFORMANCE double standardSlicePercentage = 0.0; double constrainedSlicePercentage = 0.0; // MEASURE PERFORMARNCE final Set<Node> standardSlice = standardAlgorithm.slice(SC); // final Set<Node> constrainedSlice = constrainedAlgorithm.slice(SC); // PDG PRINT CodeFactory.createCode(Language.Erlang, new File(outputSliceGenerationFolder+moduleName+"/SDG"+"#"+scFunctionCounter+".erl"), edg, standardSlice); // CE-PDG PRINT // CodeFactory.createCode(Language.Erlang, // new File(outputSliceGenerationFolder+moduleName+"/CE-SDG"+"#"+scFunctionCounter+".erl"), // edg, constrainedSlice); scFunctionCounter++; // if (measureSlicingPerformance) { // standardSlice.removeIf(n -> n.getType() == Node.Type.Result); // standardSlicePercentage = standardSlice.size() * 100.0 / nonResultNodes.size(); // // constrainedSlice.removeIf(n -> n.getType() == Node.Type.Result); // constrainedSlicePercentage = constrainedSlice.size() * 100.0 / nonResultNodes.size(); // // if (standardSlicePercentage < constrainedSlicePercentage) // throw new IllegalStateException("The SDG cannot be more precise than the EDG"); // // } } // try { // File txt = new File(outputSliceGenerationFolder+moduleName+"/criteria_map.txt"); // txt.createNewFile(); // FileWriter fw = new FileWriter(txt,true); // for(String k : functionCriteria.keySet()){ // fw.append(k +" => "+ functionCriteria.get(k)+"\n"); // } // fw.close(); // } catch (IOException e) { // System.out.println("An error occurred."); // e.printStackTrace(); // } } } } public static int countSDGNodes(EDG edg) { Node root = edg.getRootNode(); return countSDGNodes(edg, root); Loading Loading @@ -535,12 +679,27 @@ public class EKnife } } // public static void printEachSCData(String file, String funName, int funNodeSize) { // // FileWriter timeFileWriter; // PrintWriter timeWriter = null; // try { // timeFileWriter = new FileWriter(sliceGenerationCsv, true); // timeWriter = new PrintWriter(timeFileWriter); // timeWriter.printf("%s;%s;%d\n",file,funName,funNodeSize); // // } catch (IOException e) { // System.out.println("FILE NOT FOUND ERROR"); // } finally { // if (timeWriter != null) // timeWriter.close(); // } // } /* *********************** *********************** *********************** *********************** */ /* *********************** *********************** *********************** *********************** */ /* *********************** *********************** *********************** *********************** */ static class Args { enum GraphFormat { PDF, DOT } Loading e-Knife/src/test/resources/PaperExperiments/SetA/bench11A.erl 0 → 100644 +13 −0 Original line number Diff line number Diff line -module(bench11). -export([lists/2]). lists(A,B) -> [H1|T1] = A, [H2|T2] = B, C = if % Slice C H1 >= 3 -> H2; true -> [H|_] = T2, H1 - H % Slice H end. No newline at end of file Loading
Dockerfile 0 → 100644 +15 −0 Original line number Diff line number Diff line FROM ubuntu:22.04 ENV DEBIAN_FRONTEND="noninteractive" TZ="Europe/London" RUN apt-get update RUN export PATH=$HOME/.local/bin:$PATH RUN apt-get install -y build-essential erlang git maven default-jre default-jdk zip vim ARG CACHE_DATE=2016-01-01 # # # INSTALL e-Knife RUN git clone https://kaz.dsic.upv.es/git/program-slicing/e-knife-erlang.git WORKDIR "/e-knife-erlang" RUN make release
EDG/src/main/java/edg/slicing/AdaptedStandardAlgorithm.java +24 −5 Original line number Diff line number Diff line Loading @@ -26,17 +26,25 @@ public class AdaptedStandardAlgorithm extends StandardAlgorithm{ } protected void traverse(Node slicingCriterion, Set<Node> slice, Edge.Type... ignoreEdgeTypes) { final Deque<Node> pendingNodes = new LinkedList<>(slice); final Deque<SliceState> pendingNodes = new LinkedList<>(); for (Node n : slice) pendingNodes.add(new SliceState(n,null)); final Set<Edge.Type> ignoreEdgeTypesSet = new HashSet<>(Arrays.asList(ignoreEdgeTypes)); while (!pendingNodes.isEmpty()) { final Node pendingNode = pendingNodes.removeFirst(); final Set<Edge> nextEdges = edg.getEdges(pendingNode, sliceDirection); final SliceState pendingNode = pendingNodes.removeFirst(); final Set<Edge> nextEdges = edg.getEdges(pendingNode.getNode(), sliceDirection); nextEdges.removeIf(e -> ignoreEdgeTypesSet.contains(e.getType())); nextEdges.removeIf(Edge::isControlFlowEdge); nextEdges.removeIf(e -> !e.isTraversable()); if (pendingNode.getLastEdgeType() != null && pendingNode.getLastEdgeType() == Edge.Type.Structural) nextEdges.removeIf(e -> e.getType() != Edge.Type.Structural); for (Edge nextEdge : nextEdges) { final Node nextNode = sliceDirection == LAST.Direction.Backwards ? Loading @@ -53,12 +61,12 @@ public class AdaptedStandardAlgorithm extends StandardAlgorithm{ nextNodes.add(edg.getResFromNode(nextNode)); for (Node next : nextNodes) { pendingNodes.addLast(next); pendingNodes.addLast(new SliceState(next,nextEdge.getType())); slice.add(next); } } else { pendingNodes.addLast(nextNode); pendingNodes.addLast(new SliceState(nextNode,nextEdge.getType())); slice.add(nextNode); } } Loading Loading @@ -89,4 +97,15 @@ public class AdaptedStandardAlgorithm extends StandardAlgorithm{ return false; } } private class SliceState{ private Node node; private Edge.Type lastEdgeType; public SliceState(Node n, Edge.Type type){ node = n; lastEdgeType = type; } public Node getNode() { return node; } public Edge.Type getLastEdgeType() { return lastEdgeType; } } }
e-Knife/src/main/java/eknife/BencherTest.java +19 −1 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ public class BencherTest { return Objects.equals(readFile(slice), readFile(referenceSlice)); } public static void main(String[] args) { public static void main0(String[] args) { new File(EKnife.sliceGenerationCsv).delete(); new File(EKnife.graphGenerationCsv).delete(); EKnife.printHeadings(EKnife.graphGenerationCsv, EKnife.sliceGenerationCsv); Loading Loading @@ -130,4 +130,22 @@ public class BencherTest { }); } public static void main(String[] args) { TEST_PKG = "SetB"; File testFolder = new File("./e-knife-v1.1.0-src/e-Knife/src/test/resources/PaperExperiments/", TEST_PKG); findFiles(testFolder, DOT_ERLANG, file -> { File outputDir = testFolder.getAbsoluteFile(); String inputFileName = testFolder.getAbsolutePath() + File.separator + file.getName(); String outputFileName = outputDir + File.separator + file.getName() + EDG_OUTPUT_SLICE; String[] arguments = {"-i", inputFileName, "-o", outputFileName, "-l", "1", "-v", "X"}; System.out.println("Slicing program "+ file.getName() + " " + BencherTest.cont + (TEST_PKG.equals("SetA") ? "/13": "/17")); BencherTest.cont++; EKnife.generateAllSlices(arguments); }); } }
e-Knife/src/main/java/eknife/EKnife.java +161 −2 Original line number Diff line number Diff line Loading @@ -42,6 +42,8 @@ public class EKnife public static final String graphGenerationCsv = "/Users/serperu/Desktop/SlicerOutput/Times/generationTimeMilliseconds.csv"; public static final String sliceGenerationCsv = "/Users/serperu/Desktop/SlicerOutput/Times/slicingStatisticsMicroseconds.csv"; public static final String nodeCounterFile = "/Users/serperu/Desktop/SlicerOutput/Times/programSizes.txt"; public static final String outputSliceGenerationFolder = "/Users/serperu/Desktop/SlicerOutput/Slices/"; public static void main(String[] args) { Loading @@ -59,6 +61,22 @@ public class EKnife EKnife.run(arguments); } public static void generateAllSlices(String[] args){ if (args.length == 0) { EKnife.printHelp(); return; } final Args arguments = EKnife.processArguments(args); if (!arguments.isValid()) { EKnife.printHelp(); System.exit(3); } EKnife.sliceGenerationRun(arguments); } private static Args processArguments(String[] args) { Args kArgs = new Args(); Loading Loading @@ -418,6 +436,132 @@ public class EKnife // CodeFactory.createCode(Language.Erlang, a.outputFile, edg, slice); } private static void sliceGenerationRun(Args a) { // CONFIGURE MEASURED DIMENSIONS boolean performAllSCs = true; /* ***************************************************** */ /* ** MEASUREMENT OF GENERATION TIME (100 executions) ** */ /* ***************************************************** */ final LAST last = LASTFactory.createLAST(Language.Erlang, a.inputPath, true); final EDG edg = new EDGFactory(last).createEDG(); int scFunctionCounter = 0; /* ************************ */ /* ** MEASUREMENT OF SCs ** */ /* ************************ */ if (performAllSCs) { // SC SELECTION List<Node> clauses = edg.getNodes(Node.Type.Clause); clauses.removeIf(c -> edg.getParent(c).getType() != Node.Type.Routine); // printHeadings("/Users/serperu/Desktop/SlicerOutput/Times/slicingStatistics.txt", a.file); for (Node clause : clauses) { Map<String,String> functionCriteria = new HashMap<>(); List<Node> descendants = edg.getDescendants(clause); descendants.add(clause); List<Node> resultNodes = new LinkedList<>(); List<Node> nonResultNodes = new LinkedList<>(); for (Node n : descendants) if (n.getType() == Node.Type.Result) { if (edg.getNodeFromRes(n).getType() != Node.Type.Callee) resultNodes.add(n); } else nonResultNodes.add(n); nonResultNodes.add(clause); resultNodes.add(edg.getResFromNode(clause)); // IGNORE FUNCTIONS WITHOUT COMPOSITE STRUCTURES if (nonResultNodes.stream() .noneMatch( n -> { if (n.getType() == Node.Type.DataConstructor) return true; if (n.getType() == Node.Type.List) if (edg.getChildren(n).size() != 0 || edg.getParent(n).getType() == Node.Type.List) return true; return false;})) { System.out.println("File Name: " + a.file); int functionArity = edg.getChildrenNonResult(edg.getChild(clause, Node.Type.Parameters)).size(); System.out.println("Function " + edg.getParent(clause).getName() + "/" + functionArity + " has no valid slicing criteria."); continue; } /* FILTER SC NODES BY A CRITERION (CONSIDER ONLY VARIABLES) */ resultNodes.removeIf(n -> edg.getNodeFromRes(n).getType() != Node.Type.Variable); String moduleName = edg.getParent(edg.getParent(clause)).getName(); new File(outputSliceGenerationFolder+moduleName).mkdirs(); // CONFIGURE MEASURED DIMENSIONS boolean measureSlicingPerformance = true; final SlicingAlgorithm standardAlgorithm = new AdaptedTwoPassStandardAlgorithm(edg); final SlicingAlgorithm constrainedAlgorithm = new ConstrainedAlgorithm(edg); for (Node SC : resultNodes) { // System.out.println("ID: "+SC.getId()+" Line: "+SC.getInfo().getLine()+" Name "+edg.getNodeFromRes(SC).getName()); Node normalNodeSC = edg.getNodeFromRes(SC); String scString = "<"+normalNodeSC.getInfo().getLine()+","+normalNodeSC.getName()+">"; functionCriteria.put("#"+scFunctionCounter,scString); // INITIALIZATIONS // PERFORMANCE double standardSlicePercentage = 0.0; double constrainedSlicePercentage = 0.0; // MEASURE PERFORMARNCE final Set<Node> standardSlice = standardAlgorithm.slice(SC); // final Set<Node> constrainedSlice = constrainedAlgorithm.slice(SC); // PDG PRINT CodeFactory.createCode(Language.Erlang, new File(outputSliceGenerationFolder+moduleName+"/SDG"+"#"+scFunctionCounter+".erl"), edg, standardSlice); // CE-PDG PRINT // CodeFactory.createCode(Language.Erlang, // new File(outputSliceGenerationFolder+moduleName+"/CE-SDG"+"#"+scFunctionCounter+".erl"), // edg, constrainedSlice); scFunctionCounter++; // if (measureSlicingPerformance) { // standardSlice.removeIf(n -> n.getType() == Node.Type.Result); // standardSlicePercentage = standardSlice.size() * 100.0 / nonResultNodes.size(); // // constrainedSlice.removeIf(n -> n.getType() == Node.Type.Result); // constrainedSlicePercentage = constrainedSlice.size() * 100.0 / nonResultNodes.size(); // // if (standardSlicePercentage < constrainedSlicePercentage) // throw new IllegalStateException("The SDG cannot be more precise than the EDG"); // // } } // try { // File txt = new File(outputSliceGenerationFolder+moduleName+"/criteria_map.txt"); // txt.createNewFile(); // FileWriter fw = new FileWriter(txt,true); // for(String k : functionCriteria.keySet()){ // fw.append(k +" => "+ functionCriteria.get(k)+"\n"); // } // fw.close(); // } catch (IOException e) { // System.out.println("An error occurred."); // e.printStackTrace(); // } } } } public static int countSDGNodes(EDG edg) { Node root = edg.getRootNode(); return countSDGNodes(edg, root); Loading Loading @@ -535,12 +679,27 @@ public class EKnife } } // public static void printEachSCData(String file, String funName, int funNodeSize) { // // FileWriter timeFileWriter; // PrintWriter timeWriter = null; // try { // timeFileWriter = new FileWriter(sliceGenerationCsv, true); // timeWriter = new PrintWriter(timeFileWriter); // timeWriter.printf("%s;%s;%d\n",file,funName,funNodeSize); // // } catch (IOException e) { // System.out.println("FILE NOT FOUND ERROR"); // } finally { // if (timeWriter != null) // timeWriter.close(); // } // } /* *********************** *********************** *********************** *********************** */ /* *********************** *********************** *********************** *********************** */ /* *********************** *********************** *********************** *********************** */ static class Args { enum GraphFormat { PDF, DOT } Loading
e-Knife/src/test/resources/PaperExperiments/SetA/bench11A.erl 0 → 100644 +13 −0 Original line number Diff line number Diff line -module(bench11). -export([lists/2]). lists(A,B) -> [H1|T1] = A, [H2|T2] = B, C = if % Slice C H1 >= 3 -> H2; true -> [H|_] = T2, H1 - H % Slice H end. No newline at end of file