summaryrefslogtreecommitdiff
path: root/assignments/assignment2/Bounded Retransmission Protocol Tester/Source/brpcompare/GraphvizParser.java
blob: 49c29c7020d18443e685399ca772e87cd388346f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package brpcompare;

import com.google.common.collect.Lists;
import net.automatalib.automata.transout.impl.compact.CompactMealy;
import net.automatalib.util.automata.builders.AutomatonBuilders;
import net.automatalib.util.automata.builders.MealyBuilder;
import net.automatalib.words.Alphabet;
import net.automatalib.words.impl.Alphabets;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.*;

/**
 * A class which is just able to parse the output generated by LearnLib (why is this not included in LearnLib itself?
 * I have no clue.) It is *not* a general graphviz parser, it only parses the things I needed for the mealy machines.
 */
public class GraphvizParser {
    public static class Edge {
        public final String from;
        public final String to;
        public final String label;
        Edge(String b, String e, String l){
            from = b;
            to = e;
            label = l;
        }
    }

    public final Set<String> nodes;
    public final Set<Edge> edges;
    public String initialState;

    GraphvizParser(Path filename) throws IOException {
    	File file = new File(filename.toString());
    	if (!file.exists()) {
    		throw new RuntimeException("File '" + filename + "' does not exist");
    	}
    	if (file.isDirectory()) {
    		throw new RuntimeException("File " + filename + "' is a directory");
    	}
    	
        nodes = new HashSet<>();
        edges = new HashSet<>();

        Scanner s = new Scanner(filename);
        while(s.hasNextLine()){
            String line = s.nextLine();

            if(!line.contains("label")) continue;

            if(line.contains("->")){
                int e1 = line.indexOf('-');
                int e2 = line.indexOf('[');
                int b3 = line.indexOf('"');
                int e3 = line.lastIndexOf('"');

                String from = line.substring(0, e1).trim();
                String to = line.substring(e1+2, e2).trim();
                String label = line.substring(b3+1, e3).trim();

                // First read state will be the initial one.
                if(initialState == null) initialState = from;

                nodes.add(from);
                nodes.add(to);
                edges.add(new Edge(from, to, label));
            } else {
                int end = line.indexOf('[');
                if(end <= 0) continue;
                String node = line.substring(0, end).trim();

                nodes.add(node);
            }
        }
    }

    CompactMealy<String, String> createMachine(){
        Set<String> inputs = new HashSet<>();
        for(Edge e : edges){
            String[] io = e.label.split("/");
            inputs.add(io[0].trim());
        }

        List<String> inputList = Lists.newArrayList(inputs.iterator());
        Alphabet<String> alphabet = new HashAlphabet<>(Alphabets.fromList(inputList));

        MealyBuilder<?, String, ?, String, CompactMealy<String, String>>.MealyBuilder__1 builder = AutomatonBuilders.<String, String>newMealy(alphabet).withInitial(initialState);

        for(Edge e : edges){
            String[] io = e.label.split("/");

            builder.from(e.from).on(io[0].trim()).withOutput(io[1].trim()).to(e.to);
        }

        return builder.create();
    }

}