From ac914c719d401c44cb2633127952b022bf563ff3 Mon Sep 17 00:00:00 2001 From: René den Hertog Date: Thu, 26 Oct 2017 17:34:51 +0200 Subject: 'Bounded Retransmission Protocol' Blob --- .../Source/basiclearner/ObservationTree.java | 118 +++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 assignments/assignment2/Bounded Retransmission Protocol Tester/Source/basiclearner/ObservationTree.java (limited to 'assignments/assignment2/Bounded Retransmission Protocol Tester/Source/basiclearner/ObservationTree.java') diff --git a/assignments/assignment2/Bounded Retransmission Protocol Tester/Source/basiclearner/ObservationTree.java b/assignments/assignment2/Bounded Retransmission Protocol Tester/Source/basiclearner/ObservationTree.java new file mode 100644 index 0000000..9cb6ec6 --- /dev/null +++ b/assignments/assignment2/Bounded Retransmission Protocol Tester/Source/basiclearner/ObservationTree.java @@ -0,0 +1,118 @@ +package basiclearner; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import net.automatalib.words.Word; + +/** + * @author Ramon Janssen + * + * @param the input type of the observations + * @param the output type of the observations + */ +public class ObservationTree { + private final ObservationTree parent; + private final I parentInput; + private final O parentOutput; + private final Map> children; + private final Map outputs; + + public ObservationTree() { + this(null, null, null); + } + + private ObservationTree(ObservationTree parent, I parentInput, O parentOutput) { + this.children = new HashMap<>(); + this.outputs = new HashMap<>(); + this.parent = parent; + this.parentInput = parentInput; + this.parentOutput = parentOutput; + } + + /** + * @return The outputs observed from the root of the tree until this node + */ + private List getOutputChain() { + if (this.parent == null) { + return new LinkedList(); + } else { + List parentChain = this.parent.getOutputChain(); + parentChain.add(parentOutput); + return parentChain; + } + } + + private List getInputChain() { + if (this.parent == null) { + return new LinkedList(); + } else { + List parentChain = this.parent.getInputChain(); + parentChain.add(this.parentInput); + return parentChain; + } + } + + /** + * Add one input and output symbol and traverse the tree to the next node + * @param input + * @param output + * @return the next node + * @throws InconsistencyException + */ + public ObservationTree addObservation(I input, O output) throws CacheInconsistencyException { + O previousOutput = this.outputs.get(input); + boolean createNewBranch = previousOutput == null; + if (createNewBranch) { + // input hasn't been queried before, make a new branch for it and traverse + this.outputs.put(input, output); + ObservationTree child = new ObservationTree(this, input, output); + this.children.put(input, child); + return child; + } else if (!previousOutput.equals(output)) { + // input is inconsistent with previous observations, throw exception + List oldOutputChain = this.children.get(input).getOutputChain(); + List newOutputChain = this.getOutputChain(); + List inputChain = this.getInputChain(); + newOutputChain.add(output); + throw new CacheInconsistencyException(toWord(inputChain), toWord(oldOutputChain), toWord(newOutputChain)); + } else { + // input is consistent with previous observations, just traverse + return this.children.get(input); + } + } + + /** + * Add Observation to the tree + * @param inputs + * @param outputs + * @throws CacheInconsistencyException Inconsistency between new and stored observations + */ + public void addObservation(Word inputs, Word outputs) throws CacheInconsistencyException { + addObservation(inputs.asList(), outputs.asList()); + } + + + public void addObservation(List inputs, List outputs) throws CacheInconsistencyException { + if (inputs.isEmpty() && outputs.isEmpty()) { + return; + } else if (inputs.isEmpty() || outputs.isEmpty()) { + throw new RuntimeException("Input and output words should have the same length:\n" + inputs + "\n" + outputs); + } else { + I firstInput = inputs.get(0); + O firstOutput = outputs.get(0); + try { + this.addObservation(firstInput, firstOutput) + .addObservation(inputs.subList(1, inputs.size()), outputs.subList(1, outputs.size())); + } catch (CacheInconsistencyException e) { + throw new CacheInconsistencyException(toWord(inputs), e.getOldOutput(), toWord(outputs)); + } + } + } + + public static Word toWord(List symbolList) { + return Word.fromList(symbolList); + } +} -- cgit v1.2.3