<commit_before>from pybbn.graph.graph import Ug
from enum import Enum


class JoinTree(Ug):
    def __init__(self):
        Ug.__init__(self)
        self.potentials = dict()
        self.evidences = dict()
        self.listener = None

    def get_bbn_potential(self, node):
        clique = node.metadata['parent.clique']
        return None

    def __notify_listener__(self, change):
        if self.listener is None:
            return
        if ChangeType.RETRACTION == change:
            self.listener.evidence_retracted(self)
        elif ChangeType.UPDATE == change:
            self.listener.evidence_updated(self)


class PathDetector:<commit_msg>added lotsa code; not done yet<commit_after>from pybbn.graph.graph import Ug
from pybbn.graph.potential import Potential, PotentialEntry, PotentialUtil
from pybbn.graph.node import Clique, SepSet
from pybbn.graph.edge import JtEdge
from enum import Enum


class JoinTree(Ug):
    def __init__(self):
        Ug.__init__(self)
        self.potentials = dict()
        self.evidences = dict()
        self.listener = None

    def get_bbn_potential(self, node):
        clique = node.metadata['parent.clique']
        return PotentialUtil.normalize(PotentialUtil.marginalize_for(self, clique, [node]))

    def unmark_cliques(self):
        for clique in self.get_cliques():
            clique.unmark()

    def get_bbn_nodes(self):
        nodes = dict()
        for clique in self.get_cliques():
            for node in clique.nodes:
                nodes[node.id] = node
        return list(nodes.values())

    def get_bbn_node(self, id):
        for node in self.get_bbn_node():
            if id == node.id:
                return node
        return None

    def get_bbn_node_by_name(self, name):
        for node in self.get_bbn_node():
            if name == node.variable.name:
                return node
        return None

    def find_cliques_with_node_and_parents(self, id):
        ids = self.__get_parent_ids__(id)
        ids.append(id)

        set1 = set(ids)
        return [clique for clique in self.get_cliques() if set(clique.get_node_ids()).issuperset(set1)]

    def add_potential(self, clique, potential):
        self.potentials[clique.id] = potential
        return self

    def get_cliques(self):
        return [clique for clique in self.get_nodes() if isinstance(clique, Clique)]

    def get_sep_sets(self):
        return [sep_set for sep_set in self.get_nodes() if isinstance(sep_set, SepSet)]

    def add_edge(self, edge):
        if not isinstance(edge, JtEdge):
            return self
        if self.__shouldadd__(edge):
            sep_set = edge.sep_set
            lhs = edge.i
            rhs = edge.j

            self.add_node(sep_set)
            self.add_node(lhs)
            self.add_node(rhs)

            if sep_set.id not in self.map:
                self.map[sep_set.id] = set()
            if lhs.id not in self.map:
                self.map[lhs.id] = set()
            if rhs.id not in self.map:
                self.map[rhs.id] = set()

            self.map[lhs.id].add(sep_set.id)
            self.map[rhs.id].add(sep_set.id)

            self.map[sep_set.id].add(lhs.id)
            self.map[sep_set.id].add(rhs.id)

        return self

    def set_listener(self, listener):
        self.listener = listener

    def get_evidence(self, node, value):
        if node.id not in self.evidences:
            self.evidences[node.id] = dict()

        if value not in self.evidences[node.id]:
            entry = PotentialEntry()
            entry.add(node.id, value)
            entry.value = 1.0

            potential = Potential()
            potential.add_entry(entry)

            self.evidences[node.id] = potential

        return self.evidences[node.id][value]

    def get_change_type(self, evidences):
        changes = []
        for evidence in evidences:
            node = evidence.node
            clique = self.find_cliques_with_node_and_parents(node.id)[0]
            potentials = self.evidences[node.id]
            change = evidence.compare(potentials)
            changes.append(change)

        count = len([change for change in changes if ChangeType.RETRACTION == change])
        if count > 0:
            return ChangeType.RETRACTION

        count = len([change for change in changes if ChangeType.UPDATE == change])
        if count > 0:
            return ChangeType.UPDATE

        return ChangeType.NONE

    def get_unobserved_evidence(self, node):
        evidence = Evidence(node, EvidenceType.UNOBSERVE)
        for value in node.variable.values:
            evidence.add_value(value, 1.0)
        return evidence

    def unobserve(self, nodes):
        evidences = [self.get_unobserved_evidence(node) for node in nodes]
        self.update_evidences(evidences)
        return self

    def unobserve_all(self):
        self.unobserve(self.get_bbn_nodes())
        return self

    def update_evidences(self, evidences):
        for evidence in evidences:
            evidence.validate()
        change = self.get_change_type(evidences)
        for evidence in evidences:
            node = evidence.node
            potentials = self.evidences[node.id]

            for k, v in evidence.values:
                potential = potentials[k]
                potential.entries[0].value = v
        self.__notify_listener__(change)
        return self

    def set_observation(self, evidence):
        if EvidenceType.OBSERVATION != evidence.type:
            return self

        potentials = self.evidences[evidence.node.id]

        return self

    def __shouldadd__(self, edge):
        lhs = edge.i
        rhs = edge.j

        if lhs.id == rhs.id:
            return False

        if not PathDetector(self, lhs.id, rhs.id).exists():
            return True

        return False

    def __get_parent_ids__(self, id):
        node = self.get_bbn_node(id)
        if 'parents' in node.metadata:
            return [node.id for node in node.metadata['parents']]
        return []

    def __notify_listener__(self, change):
        if self.listener is None:
            return
        if ChangeType.RETRACTION == change:
            self.listener.evidence_retracted(self)
        elif ChangeType.UPDATE == change:
            self.listener.evidence_updated(self)


class PathDetector:
{'fraction_non_alphanumeric': 0.09136815527852296, 'fraction_numerical': 0.0015780337699226763, 'mean_word_length': 2.055930568948891, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '82416', 'n_tokens_mistral': 1940, 'n_tokens_neox': 1840, 'n_words': 444}