aalpy.learning_algs.non_deterministic.TraceTree
View Source
from collections import defaultdict from aalpy.base import SUL class SULWrapper(SUL): """ Wrapper for non-deterministic SUL. After every step, input/output pair is added to the tree containing all traces. """ def __init__(self, sul: SUL): super().__init__() self.sul = sul self.pta = TraceTree() def pre(self): """ """ self.pta.reset() self.sul.pre() def post(self): """ """ self.sul.post() def step(self, letter): """ Args: letter: Returns: """ out = self.sul.step(letter) self.pta.add_to_tree(letter, out) return out class Node: """ """ def __init__(self, output): self.output = output self.children = defaultdict(list) def get_child(self, inp, out): """ Args: inp: out: Returns: """ return next((child for child in self.children[inp] if child.output == out), None) class TraceTree: """ """ def __init__(self): self.root_node = Node(None) self.curr_node = None def reset(self): """ """ self.curr_node = self.root_node def add_to_tree(self, inp, out): """ Args: inp: out: Returns: """ if inp not in self.curr_node.children.keys() or out not in [child.output for child in self.curr_node.children[inp]]: node = Node(out) self.curr_node.children[inp].append(node) else: self.curr_node = self.curr_node.get_child(inp, out) def get_all_outputs(self, inputs, outputs, e): """ It should basically do this. Get to the node that you reach when following input and outputs. Than, from that node on, with input values in e, record ALL possible paths that follow it. Edi 2 Konstantin: In case of any questions about this, let me know. Args: inputs: outputs: e: Returns: """ e = list(e) curr_node = self.root_node for i, o in zip(inputs, outputs): node = curr_node.get_child(i, o) if node is None: return None curr_node = node # from this point all record all possible outputs nodes_to_process = [curr_node] # TODO RETURN WHOLE TRACES NOT JUST SINGLE OUTPUTS # below this line it is faulty (but general idea is there, it is just wrong) # also you can change stuff above it while True: if not e: return tuple(node.output for node in nodes_to_process if node.output) i = e.pop(0) children = [] for node in nodes_to_process: if node.children[i]: children.extend(node.children[i]) nodes_to_process = children
View Source
class SULWrapper(SUL): """ Wrapper for non-deterministic SUL. After every step, input/output pair is added to the tree containing all traces. """ def __init__(self, sul: SUL): super().__init__() self.sul = sul self.pta = TraceTree() def pre(self): """ """ self.pta.reset() self.sul.pre() def post(self): """ """ self.sul.post() def step(self, letter): """ Args: letter: Returns: """ out = self.sul.step(letter) self.pta.add_to_tree(letter, out) return out
Wrapper for non-deterministic SUL. After every step, input/output pair is added to the tree containing all traces.
View Source
def __init__(self, sul: SUL): super().__init__() self.sul = sul self.pta = TraceTree()
View Source
def pre(self): """ """ self.pta.reset() self.sul.pre()
View Source
def post(self): """ """ self.sul.post()
View Source
def step(self, letter): """ Args: letter: Returns: """ out = self.sul.step(letter) self.pta.add_to_tree(letter, out) return out
Args: letter:
Returns:
Inherited Members
View Source
class Node: """ """ def __init__(self, output): self.output = output self.children = defaultdict(list) def get_child(self, inp, out): """ Args: inp: out: Returns: """ return next((child for child in self.children[inp] if child.output == out), None)
View Source
def __init__(self, output): self.output = output self.children = defaultdict(list)
View Source
def get_child(self, inp, out): """ Args: inp: out: Returns: """ return next((child for child in self.children[inp] if child.output == out), None)
Args: inp: out:
Returns:
View Source
class TraceTree: """ """ def __init__(self): self.root_node = Node(None) self.curr_node = None def reset(self): """ """ self.curr_node = self.root_node def add_to_tree(self, inp, out): """ Args: inp: out: Returns: """ if inp not in self.curr_node.children.keys() or out not in [child.output for child in self.curr_node.children[inp]]: node = Node(out) self.curr_node.children[inp].append(node) else: self.curr_node = self.curr_node.get_child(inp, out) def get_all_outputs(self, inputs, outputs, e): """ It should basically do this. Get to the node that you reach when following input and outputs. Than, from that node on, with input values in e, record ALL possible paths that follow it. Edi 2 Konstantin: In case of any questions about this, let me know. Args: inputs: outputs: e: Returns: """ e = list(e) curr_node = self.root_node for i, o in zip(inputs, outputs): node = curr_node.get_child(i, o) if node is None: return None curr_node = node # from this point all record all possible outputs nodes_to_process = [curr_node] # TODO RETURN WHOLE TRACES NOT JUST SINGLE OUTPUTS # below this line it is faulty (but general idea is there, it is just wrong) # also you can change stuff above it while True: if not e: return tuple(node.output for node in nodes_to_process if node.output) i = e.pop(0) children = [] for node in nodes_to_process: if node.children[i]: children.extend(node.children[i]) nodes_to_process = children
View Source
def __init__(self): self.root_node = Node(None) self.curr_node = None
View Source
def reset(self): """ """ self.curr_node = self.root_node
View Source
def add_to_tree(self, inp, out): """ Args: inp: out: Returns: """ if inp not in self.curr_node.children.keys() or out not in [child.output for child in self.curr_node.children[inp]]: node = Node(out) self.curr_node.children[inp].append(node) else: self.curr_node = self.curr_node.get_child(inp, out)
Args: inp: out:
Returns:
View Source
def get_all_outputs(self, inputs, outputs, e): """ It should basically do this. Get to the node that you reach when following input and outputs. Than, from that node on, with input values in e, record ALL possible paths that follow it. Edi 2 Konstantin: In case of any questions about this, let me know. Args: inputs: outputs: e: Returns: """ e = list(e) curr_node = self.root_node for i, o in zip(inputs, outputs): node = curr_node.get_child(i, o) if node is None: return None curr_node = node # from this point all record all possible outputs nodes_to_process = [curr_node] # TODO RETURN WHOLE TRACES NOT JUST SINGLE OUTPUTS # below this line it is faulty (but general idea is there, it is just wrong) # also you can change stuff above it while True: if not e: return tuple(node.output for node in nodes_to_process if node.output) i = e.pop(0) children = [] for node in nodes_to_process: if node.children[i]: children.extend(node.children[i]) nodes_to_process = children
It should basically do this. Get to the node that you reach when following input and outputs. Than, from that node on, with input values in e, record ALL possible paths that follow it. Edi 2 Konstantin: In case of any questions about this, let me know.
Args: inputs: outputs: e:
Returns: