Commit 4118cc15 authored by Sergio Pérez's avatar Sergio Pérez
Browse files

* Added Experimental execution

 * Added bencher intra- and inter-procedural suits
 * Added Dockerfile
parent bb713dbc
Loading
Loading
Loading
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
+24 −5
Original line number Diff line number Diff line
@@ -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 ?
@@ -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);
                    }
                }
@@ -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; }
    }
}
+19 −1
Original line number Diff line number Diff line
@@ -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);
@@ -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);
        });
    }

}
+161 −2
Original line number Diff line number Diff line
@@ -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)
	{
@@ -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();
@@ -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);
@@ -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 }

+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