예제 #1
0
 def __init__(self, parent=None):
     self.rdrOwl = OwlReader()
     self.rdrDesig = DesignatorReader()
     
     self.arrExperiences = []
     
     self.knownTaskTypes = []
예제 #2
0
    def __init__(self, parent=None):
        self.rdrOwl = OwlReader()
        self.rdrDesig = DesignatorReader()

        self.arrExperiences = []
        self.dicEntities = {}

        self.app = QtGui.QApplication(sys.argv)
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.show()

        self.loadExperience(
            "/home/winkler/ros/catkin/src/semrec/scripts/bstools/Beliefstate Tools/Datasets/ds4/cram_log.owl",
            "/home/winkler/ros/catkin/src/semrec/scripts/bstools/Beliefstate Tools/Datasets/ds4/logged_designators.json"
        )

        sys.exit(self.app.exec_())
예제 #3
0
class LogReader:
    def __init__(self):
        self.rdrOwl = OwlReader()
        self.rdrDesig = DesignatorReader()

    def loadLog(self, strPath):
        log = Log()

        log.setOwlData(self.rdrOwl.loadOwl(strPath + "/cram_log.owl"))
        log.setDesignatorData(self.rdrDesig.loadDesignators(strPath + "/logged_designators.json"))
        
        return log
예제 #4
0
class LogReader:
    def __init__(self):
        self.rdrOwl = OwlReader()
        self.rdrDesig = DesignatorReader()

    def loadLog(self, strPath):
        log = Log()

        log.setOwlData(self.rdrOwl.loadOwl(strPath + "/cram_log.owl"))
        log.setDesignatorData(
            self.rdrDesig.loadDesignators(strPath +
                                          "/logged_designators.json"))

        return log
예제 #5
0
class ExperienceProcessor(QtGui.QMainWindow):
    def __init__(self, parent=None):
        self.rdrOwl = OwlReader()
        self.rdrDesig = DesignatorReader()

        self.arrExperiences = []
        self.dicEntities = {}

        self.app = QtGui.QApplication(sys.argv)
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.show()

        self.loadExperience(
            "/home/winkler/ros/catkin/src/semrec/scripts/bstools/Beliefstate Tools/Datasets/ds4/cram_log.owl",
            "/home/winkler/ros/catkin/src/semrec/scripts/bstools/Beliefstate Tools/Datasets/ds4/logged_designators.json"
        )

        sys.exit(self.app.exec_())

    def addExperience(self, expAdd):
        self.arrExperiences.append(expAdd)

    def loadExperience(self, strOwlFile, strDesignatorFile):
        logReturn = Log()

        logReturn.setOwlData(self.rdrOwl.loadOwl(strOwlFile))
        logReturn.setDesignatorData(
            self.rdrDesig.loadDesignators(strDesignatorFile))

        self.addExperience(logReturn)

    def update(self):
        self.updateEntities()
        self.renderCanvas()

    def updateEntities(self):
        pass

    def renderCanvas(self):
        for strName in self.dicEntities:
            self.renderEntity(dicEntities[strName])

    def renderEntity(self):
        pass
예제 #6
0
 def __init__(self, parent=None):
     self.rdrOwl = OwlReader()
     self.rdrDesig = DesignatorReader()
     
     self.arrExperiences = []
     self.dicEntities = {}
     
     self.app = QtGui.QApplication(sys.argv)
     QtGui.QWidget.__init__(self, parent)
     self.ui = Ui_MainWindow()
     self.ui.setupUi(self)
     
     self.show()
     
     self.loadExperience("/home/winkler/ros/catkin/src/semrec/scripts/bstools/Beliefstate Tools/Datasets/ds4/cram_log.owl", "/home/winkler/ros/catkin/src/semrec/scripts/bstools/Beliefstate Tools/Datasets/ds4/logged_designators.json")
     
     sys.exit(self.app.exec_())
예제 #7
0
class ExperienceProcessor(QtGui.QMainWindow):
    def __init__(self, parent=None):
        self.rdrOwl = OwlReader()
        self.rdrDesig = DesignatorReader()
        
        self.arrExperiences = []
        self.dicEntities = {}
        
        self.app = QtGui.QApplication(sys.argv)
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        
        self.show()
        
        self.loadExperience("/home/winkler/ros/catkin/src/semrec/scripts/bstools/Beliefstate Tools/Datasets/ds4/cram_log.owl", "/home/winkler/ros/catkin/src/semrec/scripts/bstools/Beliefstate Tools/Datasets/ds4/logged_designators.json")
        
        sys.exit(self.app.exec_())
    
    def addExperience(self, expAdd):
        self.arrExperiences.append(expAdd)
    
    def loadExperience(self, strOwlFile, strDesignatorFile):
        logReturn = Log()
        
        logReturn.setOwlData(self.rdrOwl.loadOwl(strOwlFile))
        logReturn.setDesignatorData(self.rdrDesig.loadDesignators(strDesignatorFile))
        
        self.addExperience(logReturn)
    
    def update(self):
        self.updateEntities()
        self.renderCanvas()
    
    def updateEntities(self):
        pass
    
    def renderCanvas(self):
        for strName in self.dicEntities:
            self.renderEntity(dicEntities[strName])
    
    def renderEntity(self):
        pass
예제 #8
0
class MemoryCondenser:
    def __init__(self, parent=None):
        self.rdrOwl = OwlReader()
        self.rdrDesig = DesignatorReader()

        self.arrExperiences = []

    def countExperiences(self):
        return len(self.arrExperiences)

    def addExperience(self, expAdd):
        self.arrExperiences.append(expAdd)

    def loadExperience(self, strOwlFile, strDesignatorFile):
        logReturn = Log()

        logReturn.setOwlData(self.rdrOwl.loadOwl(strOwlFile))

        if strDesignatorFile != "":
            logReturn.setDesignatorData(
                self.rdrDesig.loadDesignators(strDesignatorFile))

        self.addExperience(logReturn)

    def condenseData(self, dataOwl):
        result = None

        self.tti = dataOwl["task-tree-individuals"]
        owlMeta = dataOwl["metadata"]
        owlAnnot = dataOwl["annotation"]

        if owlMeta:
            result = {
                "Toplevel": self.condenseNodes("", owlMeta.subActions())
            }
        else:
            print "No meta data in file!"

        return result

    def condenseNodes(self, strParentNode, arrNodes, nLevel=0):
        arrTypes = {}
        arrIndividuals = {}

        for strNode in arrNodes:
            owlNode = self.tti[strNode]
            ident = owlNode.taskContext()

            failures = owlNode.failures()
            failure = ""
            if len(failures) > 0:
                failure = self.tti[failures[0]].type()

            result = self.condenseNodes(strNode, owlNode.subActions(),
                                        nLevel + 1)
            if not ident in arrTypes:
                arrTypes[ident] = result
            else:
                arrTypes[ident] = self.unifyResults(arrTypes[ident], result)

            arrTypes[ident]["individuals"][strNode] = {
                "parameters": owlNode.annotatedParameters(True),
                "parent": strParentNode,
                "failure": failure
            }

        return {"subTypes": arrTypes, "individuals": {}}

    def unifyResults(self, res1, res2):
        resparams = {}
        if len(res1["individuals"]) > 0:
            resparams = res1["individuals"]

        if len(res2["individuals"]) > 0:
            resparams = dict(resparams.items() + res2["individuals"].items())

        unified = {"subTypes": {}, "individuals": resparams}

        for ressub1 in res1["subTypes"]:
            if ressub1 in res2["subTypes"]:
                unified["subTypes"][ressub1] = self.unifyResults(
                    res1["subTypes"][ressub1], res2["subTypes"][ressub1])
            else:
                unified["subTypes"][ressub1] = res1["subTypes"][ressub1]

        for ressub2 in res2["subTypes"]:
            if not ressub2 in res1["subTypes"]:
                unified["subTypes"][ressub2] = res2["subTypes"][ressub2]

        return unified

    def condense(self):
        arrStartNodes = []

        self.tti = {}

        for experience in self.arrExperiences:
            owlData = experience.getOwlData()
            metaData = owlData["metadata"]
            arrStartNodes += metaData.subActions()

            self.tti.update(owlData["task-tree-individuals"])

        self.processed_nodes = []
        tree = self.condenseNodesByContext(arrStartNodes)
        parameters = {}

        for node in self.processed_nodes:
            params = self.tti[node].annotatedParameters(
                bSingularParameters=True)

            if len(params) > 0:
                parameters[node] = {}
                for p in params:
                    if not p == "_time_created":
                        parameters[node][p.lstrip("parameter-")] = params[p]

        result = {"tree": tree, "parameters": parameters}

        print result

    def sortComparatorActionTime(self, action1, action2):
        if action1.timeSpan[0] > action2.timeSpan[0]:
            return 1
        elif action1.timeSpan[0] == action2.timeSpan[0]:
            return 0
        else:
            return -1

    def sortActionsByTime(self, actions):
        actions.sort(self.sortComparatorActionTime)

        return actions

    def condenseNodesByContext(self, nodes):
        # Separate nodes by their taskContext
        dicContexts = {}

        for node in nodes:
            self.processed_nodes.append(node)

            owlNode = self.tti[node]

            if not owlNode.taskContext() in dicContexts:
                dicContexts[owlNode.taskContext()] = {
                    "nodes": [],
                    "terminal-state": []
                }

            dicContexts[owlNode.taskContext()]["nodes"].append(node)

        for context in dicContexts:
            all_children = []

            for node in dicContexts[context]["nodes"]:
                sub_actions = self.sortActionsByTime(
                    self.tti[node].subActions())

                if len(sub_actions) > 0:
                    all_children += sub_actions
                else:
                    dicContexts[context]["terminal-state"].append(node)

            dicContexts[context]["children"] = self.condenseNodesByContext(
                all_children)

        return dicContexts

    def generalizeExperiences(self):
        self.generalizedExperience = {}
        self.tti = {}

        arrStartNodes = []

        for experience in self.arrExperiences:
            owlData = experience.getOwlData()
            metaData = owlData["metadata"]
            arrStartNodes += metaData.subActions()

            self.tti.update(owlData["task-tree-individuals"])

        for node in arrStartNodes:
            self.injectActionIntoGeneralizedExperience(
                node, self.generalizedExperience)

        print self.generalizedExperience

    def injectActionIntoGeneralizedExperience(self, action, target_branch):
        target_branch["a"] = 5

    def dotNode(self, node, first):
        dot = ""
        tti = self.t_tti[node]
        former_subnode = ""

        dot += "  {rank=same;"
        for subnode in tti.subActions():
            dot += " " + subnode
        dot += "}\n"

        for subnode in tti.subActions():
            dot += "  " + subnode + " [shape=box, label=\"" + self.t_tti[
                subnode].taskContext() + "\"]\n"
            #dot += "  edge ";

            if first == True:
                first = False
                dot += "edge [dir=both, arrowhead=normal, arrowtail=none]"
                dot += "\n  " + node + " -> " + subnode + "\n"
            else:
                pass  #dot += "[dir=both, arrowhead=diamond, arrowtail=ediamond]"

            if not former_subnode == "":
                dot += "  edge [arrowhead=empty, arrowtail=none]\n"
                dot += "  " + former_subnode + " -> " + subnode + "\n"

            dot += self.dotNode(subnode, True)

            former_subnode = subnode

        if len(tti.subActions()) == 0 and tti.nextAction() == None:
            #dot += "  terminal_state_" + node + " [shape=doublecircle, label=\"\"]\n"
            #dot += "  edge [arrowhead=empty, arrowtail=none]\n"
            #dot += "  " + node + " -> terminal_state_" + node + "\n"
            pass

        return dot

    def printExperiences(self, dot):
        for experience in self.arrExperiences:
            if dot:
                self.printDotExperience(experience)
            else:
                self.printRawExperience(experience)

    def printRawExperience(self, experience):
        owlData = experience.getOwlData()
        metaData = owlData["metadata"]
        start_nodes = metaData.subActions()
        self.t_tti = owlData["task-tree-individuals"]

        for node in start_nodes:
            self.printRawExperienceNode(node)

    def printRawExperienceNode(self, node, level=0):
        indent = "   " * level
        owl = self.t_tti[node]

        parameters = owl.annotatedParameters()
        param_str = "("
        first = True

        for parameter in parameters:
            if not parameter == "_time_created":
                if first == True:
                    first = False
                else:
                    param_str = param_str + ", "

                key_str = parameter[
                    10:] if parameter[:10] == "parameter-" else parameter
                param_str = param_str + key_str + "=" + parameters[parameter][0]

        param_str = param_str + ")"

        print indent + owl.taskContext() + " " + param_str

        if len(owl.subActions()) > 0:
            for node in owl.subActions():
                self.printRawExperienceNode(node, level + 1)

    def printDotExperience(self, experience):
        owlData = experience.getOwlData()
        metaData = owlData["metadata"]
        start_nodes = metaData.subActions()
        self.t_tti = owlData["task-tree-individuals"]

        dot = "digraph plangraph {\n"
        dot += "  label=\"Original Experiences\"\n"
        dot += "  labeljust=center\n"
        dot += "  labelloc=top\n"

        for node in start_nodes:
            dot += "  " + node + " [shape=box, label=\"" + self.t_tti[
                node].taskContext() + "\"]\n\n"

            dot += self.dotNode(node, True)

        dot += "}\n"

        print dot

    def compareSubActions(self, subaction1, subaction2):
        if subaction1 == subaction2:
            return 0

        next_action = subaction1

        while next_action != None:
            next_action = self.tti[subaction1].nextAction()

            if next_action == subaction2:
                return 1

        return -1

    def sortSubActions(self, subactions):
        subactions.sort(self.compareSubActions)

        return subactions

    def sortSubActionsList(self, subactions_list):
        sorted_list = []

        for subactions in subactions_list:
            sorted_list.append(self.sortSubActions(subactions))

        return sorted_list

    def generalizeNodes(self, nodes):
        sequences = []

        for node in nodes:
            sequences.append(self.tti[node].subActions())

        return sequences

    def workOnExperiences(self):
        start_nodes = []
        self.tti = {}

        for experience in self.arrExperiences:
            owlData = experience.getOwlData()
            metaData = owlData["metadata"]

            start_nodes += metaData.subActions()
            self.tti.update(owlData["task-tree-individuals"])

        print self.generalizeNodes(start_nodes)

    def injectExperiences(self, deduced=False, data=False):
        self.arrInjected = {}
        self.tti = {}
        self.uid_counter = 0

        root_action_count = 0

        for experience in self.arrExperiences:
            owlData = experience.getOwlData()
            metaData = owlData["metadata"]
            self.tti.update(owlData["task-tree-individuals"])

            for node in metaData.subActions():
                self.injectExperienceNode(node, self.arrInjected)
                root_action_count = root_action_count + 1

        for experience in self.arrExperiences:
            owlData = experience.getOwlData()
            metaData = owlData["metadata"]
            self.tti.update(owlData["task-tree-individuals"])

            for node in metaData.subActions():
                self.checkForTerminalStateOccurrences(
                    self.tti[node].taskContext(), self.arrInjected)

            for node in metaData.subActions():
                self.checkForOptionalInjectedNodes(
                    self.tti[node].taskContext(), self.arrInjected)

        if deduced:
            self.printDeduced(dot=not data,
                              root_action_count=root_action_count)
        else:
            self.printInjected(dot=not data)

    def injectExperienceNode(self,
                             node,
                             frame,
                             rootlevel=False,
                             invocation_path={}):
        ctx = self.tti[node].taskContext()

        params = self.tti[node].annotatedParameters()
        params_fixed = {}
        call_pattern = ""

        for param in params:
            if not param == "_time_created" and not param == "CALLPATTERN":
                key_str = param[10:] if param[:10] == "parameter-" else param
                params_fixed[key_str] = params[param][0]
            elif param == "CALLPATTERN":
                call_pattern = params[param][0]

        new_invocation_path = invocation_path.copy()

        if not ctx in frame:
            new_invocation_path.update({self.uid_counter: params_fixed})
            frame[ctx] = {
                "children": {},
                "next-actions": {},
                "uid": self.uid_counter,
                "terminal-state": "false",
                "start-state": "false",
                "optional": "false",
                "instances": 0,
                "invocations": [new_invocation_path],
                "call-pattern": call_pattern
            }
            self.uid_counter = self.uid_counter + 1
        else:
            new_invocation_path.update({frame[ctx]["uid"]: params_fixed})
            frame[ctx]["invocations"].append(new_invocation_path)

        frame[ctx]["instances"] = frame[ctx]["instances"] + 1

        sub_nodes = self.tti[node].subActions()

        for sub in sub_nodes:
            self.injectExperienceNode(sub, frame[ctx]["children"], False,
                                      new_invocation_path)

        next_node = self.tti[node].nextAction()

        if next_node:
            current_ctx = ctx
            while next_node:
                nextCtx = self.tti[next_node].taskContext()

                call_pattern = self.tti[next_node].annotatedParameterValue(
                    "CALLPATTERN")
                if not call_pattern:
                    call_pattern = ""

                if not current_ctx in frame:
                    frame[current_ctx] = {
                        "children": {},
                        "next-actions": {},
                        "uid": self.uid_counter,
                        "terminal-state": "false",
                        "start-state": "false",
                        "optional": "false",
                        "instances": 0,
                        "invocations": [],
                        "call-pattern": call_pattern
                    }
                    self.uid_counter = self.uid_counter + 1

                if not nextCtx in frame[current_ctx][
                        "next-actions"] and not rootlevel:
                    if not nextCtx == current_ctx:
                        if not nextCtx in frame[current_ctx]["next-actions"]:
                            frame[current_ctx]["next-actions"][nextCtx] = []

                        params = self.tti[next_node].annotatedParameters()
                        params_fixed = {}

                        for param in params:
                            if not param == "_time_created":
                                key_str = param[
                                    10:] if param[:10] == "parameter-" else param
                                params_fixed[key_str] = params[param][0]

                        frame[current_ctx]["next-actions"][nextCtx].append(
                            params_fixed)

                next_node = self.tti[next_node].nextAction()
                current_ctx = nextCtx
        else:
            if len(self.tti[node].subActions()) == 0:
                frame[ctx]["terminal-state"] = "true"

        if frame[ctx]["start-state"] == "false":
            if self.tti[node].previousAction() == None:
                frame[ctx]["start-state"] = "true"

    def checkForOptionalInjectedNodes(self,
                                      ctx,
                                      frame,
                                      parent_instances=-1,
                                      came_from=None):
        if not "check-optional" in frame[ctx]:
            frame[ctx]["check-optional"] = "done"

            came_from_terminates = False
            came_from_valid = True
            if came_from:
                if came_from == ctx:
                    came_from_valid = False

                if frame[came_from]["terminal-state"] == "true":
                    came_from_terminates = True

            if came_from_valid == True:
                if frame[ctx][
                        "instances"] < parent_instances or came_from_terminates:
                    frame[ctx]["optional"] = "true"

            for child in frame[ctx]["children"]:
                if frame[ctx]["children"][child]["start-state"] == "true":
                    self.checkForOptionalInjectedNodes(child,
                                                       frame[ctx]["children"],
                                                       frame[ctx]["instances"])

            for next_action in frame[ctx]["next-actions"]:
                if next_action in frame and not next_action == ctx:
                    self.checkForOptionalInjectedNodes(next_action, frame,
                                                       frame[ctx]["instances"],
                                                       ctx)

    def checkForTerminalStateOccurrences(self, ctx, frame):
        if not "check-terminal" in frame[ctx]:
            frame[ctx]["check-terminal"] = "done"

            child_instances = 0
            next_instances = 0

            if frame[ctx]["terminal-state"] == "true":
                for child in frame[ctx]["children"]:
                    if frame[ctx]["children"][child]["start-state"] == "true":
                        child_instances = child_instances + frame[ctx][
                            "children"][child]["instances"]

                for next_action in frame[ctx]["next-actions"]:
                    if next_action in frame and not next_action == ctx:
                        next_instances = next_instances + frame[next_action][
                            "instances"]

                terminal_instances = frame[ctx]["instances"] - (
                    child_instances + next_instances)

                if terminal_instances > 0:
                    frame[ctx]["terminal-instances"] = terminal_instances
                else:
                    frame[ctx]["terminal-instances"] = 0
            else:
                frame[ctx]["terminal-state"] = "false"
                frame[ctx]["terminal-instances"] = 0

            for child in frame[ctx]["children"]:
                self.checkForTerminalStateOccurrences(child,
                                                      frame[ctx]["children"])

            for next_action in frame[ctx]["next-actions"]:
                if next_action in frame and not next_action == ctx:
                    self.checkForTerminalStateOccurrences(next_action, frame)

    def printDeduced(self, dot=False, root_action_count=1):
        # TODO: Extend this to use all top-level nodes in case they
        # are different
        self.global_ctx_counter = 0
        deduced = self.expandPathways(self.arrInjected.keys()[0],
                                      self.arrInjected, root_action_count)

        fixed_deduced = []
        for d in deduced:
            fixed_singular = d[2:]
            for step in fixed_singular:
                for invocation in step["invocations"]:
                    invocation.pop(0, 0)
                    invocation.pop(1, 0)

            fixed_deduced.append(fixed_singular)

        with open("deduced_experiences.json", "w") as f:
            json.dump(fixed_deduced, f)

        if dot:
            self.printDotDeduced(deduced)
        else:
            print deduced

    def expandPathways(self, ctx, nodes, root_action_count, trace=[]):
        expanded_pathways = []

        if not nodes[ctx]["uid"] in trace:
            current_node = [{
                "node":
                ctx,
                "instances":
                nodes[ctx]["instances"],
                "uid":
                nodes[ctx]["uid"],
                "rel-occ":
                (float(nodes[ctx]["instances"]) / float(root_action_count)),
                "rel-term": (float(nodes[ctx]["terminal-instances"]) /
                             float(nodes[ctx]["instances"])),
                "invocations":
                nodes[ctx]["invocations"],
                "call-pattern":
                nodes[ctx]["call-pattern"]
            }]
            children = self.getStartNodes(nodes[ctx]["children"])

            had_non_optional_children = False
            for child in children:
                if not children[child]["optional"] == "true":
                    had_non_optional_children = True

                child_pathways = self.expandPathways(
                    child, nodes[ctx]["children"], nodes[ctx]["instances"],
                    trace + [nodes[ctx]["uid"]])

                for child_pathway in child_pathways:
                    expanded_pathways.append(current_node + child_pathway)

            if not had_non_optional_children:
                expanded_pathways.append(current_node)

            next_actions = nodes[ctx]["next-actions"]
            final_pathways = []

            had_non_optional_next_actions = False
            for next_action in next_actions:
                if next_action != ctx:
                    if not nodes[next_action]["optional"] == "true":
                        had_non_optional_next_actions = True

                    expanded_next_pathways = self.expandPathways(
                        next_action, nodes, nodes[ctx]["instances"],
                        trace + [nodes[ctx]["uid"]])

                    for expanded_next_pathway in expanded_next_pathways:
                        for expanded_pathway in expanded_pathways:
                            final_pathways = final_pathways + [
                                expanded_pathway + expanded_next_pathway
                            ]

            if not had_non_optional_next_actions:
                final_pathways = final_pathways + expanded_pathways

            return final_pathways
        else:
            return []

    def getStartNodes(self, nodes):
        start_nodes = {}

        for node in nodes:
            if nodes[node]["start-state"] == "true":
                start_nodes[node] = nodes[node]

        return start_nodes

    def printInjected(self, dot=False):
        if dot:
            self.printInjectedDot()
        else:
            print self.arrInjected

    def printInjectedChildren(self, children, parent=None):
        dot = ""
        edge_pointers = {}
        next_action_parameters = {}
        ids = {}
        optionals = {}

        parent_id = parent
        if not parent:
            parent_id = "root"

        for child in children:
            child_id = "node_" + child.replace("-", "_") + "_" + str(
                self.counterdot)
            ids[child] = child_id

            self.counterdot = self.counterdot + 1

            label = child
            if label[:21] == "REPLACEABLE-FUNCTION-":
                label = label[21:]

            dot += "  " + child_id + " [shape=box, label=\"" + label + " (" + str(
                children[child]["uid"]) + " / " + str(
                    children[child]["instances"]) + ")\"]\n"

            if children[child]["terminal-state"] == "true":
                if children[child]["terminal-instances"] > 0:
                    dot += "    ts_" + str(
                        self.counterdot
                    ) + " [shape=doublecircle, label=\"" + str(
                        children[child]["terminal-instances"]) + "\"]\n"
                    dot += "    edge [style=dashed, arrowhead=normal, arrowtail=none, label=\"terminal\"]\n"
                    dot += "    " + child_id + " -> " + "ts_" + str(
                        self.counterdot) + "\n"

            dot += self.printInjectedChildren(children[child]["children"],
                                              child_id)

            if parent:
                if children[child]["start-state"] == "true":
                    if children[child]["optional"] == "true":
                        dot += "  edge [style=solid, arrowhead=normal, arrowtail=none, label=\"optional\"]\n"
                    else:
                        dot += "  edge [style=solid, arrowhead=normal, arrowtail=none, label=\"\"]\n"
                else:
                    if children[child]["optional"] == "true":
                        dot += "  edge [style=dashed, arrowhead=none, arrowtail=none, label=\"\"]\n"
                    else:
                        dot += "  edge [style=dashed, arrowhead=none, arrowtail=none, label=\"\"]\n"

                dot += "  " + parent + " -> " + child_id + "\n"

            for na in children[child]["next-actions"]:
                if parent:
                    if not na in edge_pointers:
                        edge_pointers[na] = []
                        next_action_parameters[na] = {}

                    if not child_id in next_action_parameters[na]:
                        next_action_parameters[na][child_id] = []

                    edge_pointers[na].append(child_id)
                    #next_action_parameters[na][child_id].append(children[child]["next-actions"][na])

        #print "!"
        #print next_action_parameters
        for child in children:
            child_id = ids[child]

            if child in edge_pointers:
                for target in edge_pointers[child]:
                    param_str = ""
                    # for param_sets in next_action_parameters[child][target]:
                    #     for param_set in param_sets:
                    #         first_p = True
                    #         for p in param_set:
                    #             if first_p:
                    #                 first_p = False
                    #             else:
                    #                 param_str = param_str + ", "

                    #             param_str = param_str + p + " = " + param_set[p]

                    #         param_str = param_str + "\\n"
                    #if next_action_parameters[

                    if children[child]["optional"] == "true":
                        param_str = "optional"
                    else:
                        param_str = ""

                    dot += "  {rank=same; " + child_id + " " + target + "}\n"
                    dot += "  edge [style=solid, arrowhead=empty, arrowtail=none, label=\"" + param_str + "\"]\n"
                    dot += "  " + target + " -> " + child_id + "\n"

        return dot

    def printInjectedDot(self):
        self.counterdot = 0
        self.edge_pointers = {}

        dot = "digraph condensed {\n"
        dot += "  graph []\n"  #ranksep=0.5#nodesep=0.5#pad=0.5
        dot += "  label=\"Condensed Experience Graph\"\n"
        dot += "  labeljust=center\n"
        dot += "  labelloc=top\n"
        dot += self.printInjectedChildren(self.arrInjected)
        dot += "}\n"

        print dot

    def expScore(self, exp):
        acc_score = 1.0

        for item in exp:
            instances = item["instances"]
            rel_occ = item["rel-occ"]
            acc_score = acc_score * rel_occ

        last_item = exp[len(exp) - 1]
        acc_score = acc_score * last_item["rel-term"]

        return acc_score

    def expScoreCmp(self, exp1, exp2):
        score1 = self.expScore(exp1)
        score2 = self.expScore(exp2)

        if score1 < score2:
            return 1
        elif score1 > score2:
            return -1
        else:
            return 0

    def printDotDeduced(self, deduced):
        counter = 0
        subgraphcounter = 0

        dot = "digraph deduced {\n"
        dot += "  label=\"Deduced Possible Action Paths\"\n"
        dot += "  labeljust=center\n"
        dot += "  labelloc=top\n"

        highest_score = 0
        for line in deduced:
            acc_score = self.expScore(line)

            if acc_score > highest_score:
                highest_score = acc_score

        deduced.sort(self.expScoreCmp)

        for line in deduced:
            dot += "  \n"

            dot += "  subgraph cluster_" + str(subgraphcounter) + " {\n"
            dot += "    pencolor=transparent;\n"
            dot += "    \n"
            subgraphcounter = subgraphcounter + 1

            first = True
            acc_score = 1.0

            for item in line:
                instances = item["instances"]
                node = item["node"]
                rel_occ = item["rel-occ"]

                # Correct node label
                if node[:21] == "REPLACEABLE-FUNCTION-":
                    node = node[21:]

                acc_score = acc_score * rel_occ

                if not first:
                    dot += "    node_" + str(counter - 1) + " -> node_" + str(
                        counter) + "\n"
                else:
                    first = False

                dot += "    node_" + str(
                    counter) + " [shape=box, label=\"" + node + " (" + str(
                        round(rel_occ, 2)) + ")\"]\n"
                counter = counter + 1

            last_item = line[len(line) - 1]

            dot += "    ts_" + str(counter -
                                   1) + " [shape=doublecircle, label=\"" + str(
                                       round(last_item["rel-term"],
                                             2)) + "\"]\n"
            dot += "    edge [style=dashed, arrowhead=normal, arrowtail=none, label=\"\"]\n"
            dot += "    node_" + str(counter -
                                     1) + " -> " + "ts_" + str(counter -
                                                               1) + "\n"

            acc_score = acc_score * last_item["rel-term"]

            dot += "    \n"
            dot += "    label=\"Score: " + str(round(acc_score, 2)) + "\";\n"
            dot += "    labeljust=center;\n"
            dot += "    labelloc=top;\n"
            dot += "  }\n"

        dot += "}\n"

        print dot
예제 #9
0
 def __init__(self):
     self.rdrOwl = OwlReader()
     self.rdrDesig = DesignatorReader()
예제 #10
0
class MemoryCondenser:
    def __init__(self, parent=None):
        self.rdrOwl = OwlReader()
        self.rdrDesig = DesignatorReader()
        
        self.arrExperiences = []
        
        self.knownTaskTypes = []
    
    def countExperiences(self):
        return len(self.arrExperiences)
    
    def addExperience(self, expAdd):
        self.arrExperiences.append(expAdd)
    
    def loadExperience(self, strOwlFile, strDesignatorFile):
        logReturn = Log()
        
        logReturn.setOwlData(self.rdrOwl.loadOwl(strOwlFile))
        
        if strDesignatorFile != "":
            logReturn.setDesignatorData(self.rdrDesig.loadDesignators(strDesignatorFile))
        
        self.addExperience(logReturn)
    
    def durations_for_task_type(self, data, task_type):
        collected_durations = []
        
        for key in data:
            if key == task_type:
                collected_durations += data[key]["durations"]
            
            collected_durations += self.durations_for_task_type(data[key]["children"], task_type)
        
        return collected_durations
    
    def condenseData(self, dataOwl):
        result = None
        
        self.tti = dataOwl["task-tree-individuals"]
        owlMeta = dataOwl["metadata"]
        owlAnnot = dataOwl["annotation"]
        
        if owlMeta:
            result = {"Toplevel" : self.condenseNodes("", owlMeta.subActions())};
        else:
            print "No meta data in file!"
        
        return result
    
    def condenseNodes(self, strParentNode, arrNodes, nLevel = 0):
        arrTypes = {}
        arrIndividuals = {}
        
        for strNode in arrNodes:
            owlNode = self.tti[strNode]
            ident = owlNode.taskContext()
            
            failures = owlNode.failures()
            failure = ""
            if len(failures) > 0:
                failure = self.tti[failures[0]].type()
            
            result = self.condenseNodes(strNode, owlNode.subActions(), nLevel + 1)
            if not ident in arrTypes:
                arrTypes[ident] = result
            else:
                arrTypes[ident] = self.unifyResults(arrTypes[ident], result)
            
            arrTypes[ident]["individuals"][strNode] = {"parameters" : owlNode.annotatedParameters(True),
                                                       "parent" : strParentNode,
                                                       "failure" : failure}
        
        return {"subTypes" : arrTypes,
                "individuals" : {}}
    
    def unifyResults(self, res1, res2):
        resparams = {}
        if len(res1["individuals"]) > 0:
            resparams = res1["individuals"]
        
        if len(res2["individuals"]) > 0:
            resparams = dict(resparams.items() + res2["individuals"].items())
        
        unified = {"subTypes" : {},
                   "individuals" : resparams}
        
        for ressub1 in res1["subTypes"]:
            if ressub1 in res2["subTypes"]:
                unified["subTypes"][ressub1] = self.unifyResults(res1["subTypes"][ressub1],
                                                                 res2["subTypes"][ressub1])
            else:
                unified["subTypes"][ressub1] = res1["subTypes"][ressub1]
        
        for ressub2 in res2["subTypes"]:
            if not ressub2 in res1["subTypes"]:
                unified["subTypes"][ressub2] = res2["subTypes"][ressub2]
        
        return unified
    
    def condense(self):
        arrStartNodes = []
        
        self.tti = {}
        
        for experience in self.arrExperiences:
            owlData = experience.getOwlData()
            metaData = owlData["metadata"]
            arrStartNodes += metaData.subActions()
            
            self.tti.update(owlData["task-tree-individuals"])
        
        self.processed_nodes = []
        tree = self.condenseNodesByContext(arrStartNodes)
        parameters = {}
        
        for node in self.processed_nodes:
            params = self.tti[node].annotatedParameters(bSingularParameters = True)
            
            if len(params) > 0:
                parameters[node] = {}
                for p in params:
                    if not p == "_time_created":
                        parameters[node][p.lstrip("parameter-")] = params[p]
        
        result = {"tree": tree,
                  "parameters": parameters}
        
        print result
    
    def sortComparatorActionTime(self, action1, action2):
        if action1.timeSpan[0] > action2.timeSpan[0]:
            return 1
        elif action1.timeSpan[0] == action2.timeSpan[0]:
            return 0
        else:
            return -1
    
    def sortActionsByTime(self, actions):
        actions.sort(self.sortComparatorActionTime)
        
        return actions
    
    def condenseNodesByContext(self, nodes):
        # Separate nodes by their taskContext
        dicContexts = {}
        
        for node in nodes:
            self.processed_nodes.append(node)
            
            owlNode = self.tti[node]
            
            if not owlNode.taskContext() in dicContexts:
                dicContexts[owlNode.taskContext()] = {"nodes": [],
                                                      "terminal-state": []}
            
            dicContexts[owlNode.taskContext()]["nodes"].append(node)
        
        for context in dicContexts:
            all_children = []
            
            for node in dicContexts[context]["nodes"]:
                sub_actions = self.sortActionsByTime(self.tti[node].subActions())
                
                if len(sub_actions) > 0:
                    all_children += sub_actions
                else:
                    dicContexts[context]["terminal-state"].append(node)
            
            dicContexts[context]["children"] = self.condenseNodesByContext(all_children)
        
        return dicContexts
    
    def generalizeExperiences(self):
        self.generalizedExperience = {}
        self.tti = {}
        
        arrStartNodes = []
        
        for experience in self.arrExperiences:
            owlData = experience.getOwlData()
            metaData = owlData["metadata"]
            arrStartNodes += metaData.subActions()
            
            self.tti.update(owlData["task-tree-individuals"])
        
        for node in arrStartNodes:
            self.injectActionIntoGeneralizedExperience(node, self.generalizedExperience)
        
        print self.generalizedExperience
    
    def injectActionIntoGeneralizedExperience(self, action, target_branch):
        target_branch["a"] = 5
    
    def dotNode(self, node, first):
        dot = ""
        tti = self.t_tti[node]
        former_subnode = ""
        
        dot += "  {rank=same;"
        for subnode in tti.subActions():
            dot += " " +subnode
        dot += "}\n"
        
        for subnode in tti.subActions():
            param_line = ""
            for param in self.t_tti[subnode].annotatedParameters():
                if param != "_time_created" and param != "CALLPATTERN":
                    value = self.t_tti[subnode].tagNodeValues("knowrob:" + param)[0]
                    param_line += param + " = " + value + "\n"
            
            dot += "  " + subnode + " [shape=box, label=\"" + self.t_tti[subnode].taskContext() + " (" + str(round(self.t_tti[subnode].time(), 3)) + "s)\n" + param_line + "\"]\n"
            
            if first == True:
                first = False
                dot += "edge [dir=both, arrowhead=normal, arrowtail=none]"
                dot += "\n  " + node + " -> " + subnode + "\n"
            
            if not former_subnode == "":
                dot += "  edge [arrowhead=empty, arrowtail=none]\n"
                dot += "  " + former_subnode + " -> " + subnode + "\n"
            
            dot += self.dotNode(subnode, True)
            
            former_subnode = subnode
        
        return dot
    
    def printExperiences(self, dot):
        for experience in self.arrExperiences:
            if dot:
                self.printDotExperience(experience)
            else:
                self.printRawExperience(experience)
    
    def printRawExperience(self, experience):
        owlData = experience.getOwlData()
        metaData = owlData["metadata"]
        start_nodes = metaData.subActions()
        self.t_tti = owlData["task-tree-individuals"]
        
        for node in start_nodes:
            self.printRawExperienceNode(node)
    
    def printRawExperienceNode(self, node, level = 0):
        indent = "   " * level
        owl = self.t_tti[node]
        
        parameters = owl.annotatedParameters()
        param_str = "("
        first = True
        
        for parameter in parameters:
            if not parameter == "_time_created":
                if first == True:
                    first = False
                else:
                    param_str = param_str + ", "
                
                key_str = parameter[10:] if parameter[:10] == "parameter-" else parameter
                param_str = param_str + key_str + "=" + parameters[parameter][0]
        
        param_str = param_str + ")"
        
        print indent + owl.taskContext() + " " + param_str
        
        if len(owl.subActions()) > 0:
            for node in owl.subActions():
                self.printRawExperienceNode(node, level + 1)
    
    def printDotExperience(self, experience):
        owlData = experience.getOwlData()
        metaData = owlData["metadata"]
        start_nodes = metaData.subActions()
        self.t_tti = owlData["task-tree-individuals"]
        
        dot = "digraph plangraph {\n"
        dot += "  label=\"Original Experiences\"\n"
        dot += "  labeljust=center\n"
        dot += "  labelloc=top\n"
        
        for node in start_nodes:
            dot += "  " + node + " [shape=box, label=\"" + self.t_tti[node].taskContext() + "\"]\n\n"
            
            dot += self.dotNode(node, True)
        
        dot += "}\n"
        
        print dot
    
    def compareSubActions(self, subaction1, subaction2):
        if subaction1 == subaction2:
            return 0
        
        next_action = subaction1
        
        while next_action != None:
            next_action = self.tti[subaction1].nextAction()
            
            if next_action == subaction2:
                return 1
        
        return -1
    
    def sortSubActions(self, subactions):
        subactions.sort(self.compareSubActions)
        
        return subactions
    
    def sortSubActionsList(self, subactions_list):
        sorted_list = []
        
        for subactions in subactions_list:
            sorted_list.append(self.sortSubActions(subactions))
        
        return sorted_list
    
    def generalizeNodes(self, nodes):
        sequences = []
        
        for node in nodes:
            sequences.append(self.tti[node].subActions())
        
        return sequences
    
    def workOnExperiences(self):
        start_nodes = []
        self.tti = {}
        
        for experience in self.arrExperiences:
            owlData = experience.getOwlData()
            metaData = owlData["metadata"]
            
            start_nodes += metaData.subActions()
            self.tti.update(owlData["task-tree-individuals"])
        
        print self.generalizeNodes(start_nodes)
    
    def injectExperiences(self, deduced = False, data = False):
        self.arrInjected = {}
        self.tti = {}
        self.uid_counter = 0;
        
        root_action_count = 0
        
        for experience in self.arrExperiences:
            owlData = experience.getOwlData()
            metaData = owlData["metadata"]
            self.tti.update(owlData["task-tree-individuals"])
            
            for node in metaData.subActions():
                self.injectExperienceNode(node, self.arrInjected, True)
                root_action_count = root_action_count + 1
        
        for experience in self.arrExperiences:
            owlData = experience.getOwlData()
            metaData = owlData["metadata"]
            self.tti.update(owlData["task-tree-individuals"])
            
            for node in metaData.subActions():
                self.checkForTerminalStateOccurrences(self.tti[node].taskContext(), self.arrInjected)
            
            for node in metaData.subActions():
                self.checkForOptionalInjectedNodes(self.tti[node].taskContext(), self.arrInjected)
        
        self.taskDurations = {}
        for task_type in self.knownTaskTypes:
            self.taskDurations[task_type] = self.durations_for_task_type(self.arrInjected, task_type)
        
        if deduced:
            self.printDeduced(dot = not data, root_action_count = root_action_count)
        else:
            self.printInjected(dot = not data)
    
    def getParameters(self, node):
        params_fixed = {}
        call_pattern = ""
        
        params = self.tti[node].annotatedParameters()
        
        for param in params:
            if not param == "_time_created" and not param == "CALLPATTERN":
                key_str = param[10:] if param[:10] == "parameter-" else param
                params_fixed[key_str] = params[param][0]
            elif param == "CALLPATTERN":
                call_pattern = params[param][0]
        
        return (call_pattern, params_fixed)
    
    def emptyContext(self, invocation_path, call_pattern):
        ctx = {"children": {},
               "next-actions" : {},
               "uid" : self.uid_counter,
               "terminal-state": "false",
               "start-state": "false",
               "optional": "false",
               "instances": 0,
               "durations": [],
               "outcomes": {},
               "invocations": [invocation_path],
               "call-pattern": call_pattern}
        self.uid_counter = self.uid_counter + 1
        
        return ctx
    
    def updateFrameContext(self, node, frame, invocation_path, previous_ctx):
        ctx = self.tti[node].taskContext()
        
        if ctx != previous_ctx:
            (call_pattern, params) = self.getParameters(node)
            
            if not ctx in frame:
                invocation_path.update({self.uid_counter: params})
                frame[ctx] = self.emptyContext(invocation_path, call_pattern)
            else:
                invocation_path.update({frame[ctx]["uid"]: params})
                frame[ctx]["invocations"].append(invocation_path)
            
            if frame[ctx]["start-state"] == "false":
                if not self.tti[node].previousAction():
                    frame[ctx]["start-state"] = "true"
            
            frame[ctx]["instances"] += 1
            frame[ctx]["durations"].append(self.tti[node].time())
            
            failures = self.tti[node].failures()
            outcome = ""
            
            if len(failures) > 0:
                outcome = self.tti[failures[0]].tagNodeValues("rdfs:label")[0].split(":")[1]
            else:
                outcome = "SUCCESS"
            
            if not outcome in frame[ctx]["outcomes"]:
                frame[ctx]["outcomes"][outcome] = 0
            
            frame[ctx]["outcomes"][outcome] += 1
            
            if previous_ctx:
                if not ctx in frame[previous_ctx]["next-actions"]:
                    frame[previous_ctx]["next-actions"][ctx] = []
                
                frame[previous_ctx]["next-actions"][ctx].append(params)
    
    def injectExperienceNode(self, node, frame, rootlevel = False, invocation_path = {}, previous_node = None):
        ctx = self.tti[node].taskContext()
        new_invocation_path = invocation_path.copy()
        
        if not ctx in self.knownTaskTypes:
            self.knownTaskTypes.append(ctx)
        
        self.updateFrameContext(node, frame, new_invocation_path, self.tti[previous_node].taskContext() if previous_node else None)
        num_children = len(frame[ctx]["children"])
        num_siblings = len(frame[ctx]["next-actions"])
        
        for sub in self.tti[node].subActions():
            if not self.tti[sub].previousAction():
                self.injectExperienceNode(sub, frame[ctx]["children"], False, new_invocation_path)
        
        next_node = self.tti[node].nextAction()
        
        if next_node and not rootlevel and not ctx == self.tti[next_node].taskContext():
            self.injectExperienceNode(next_node, frame, False, new_invocation_path, node)
    
    def checkForOptionalInjectedNodes(self, ctx, frame, parent_instances = -1, came_from = None):
        if not "check-optional" in frame[ctx]:
            frame[ctx]["check-optional"] = "done"
            frame[ctx]["optional"] = "false"
            
            came_from_terminates = False
            came_from_valid = True
            if came_from:
                if came_from == ctx:
                    came_from_valid = False
                
                if frame[came_from]["terminal-state"] == "true":
                    came_from_terminates = True
            
            if came_from_valid == True:
                if frame[ctx]["instances"] < parent_instances:
                    frame[ctx]["optional"] = "true"
            
            for child in frame[ctx]["children"]:
                if frame[ctx]["children"][child]["start-state"] == "true":
                    self.checkForOptionalInjectedNodes(child, frame[ctx]["children"], frame[ctx]["instances"])
            
            for next_action in frame[ctx]["next-actions"]:
                if next_action in frame and not next_action == ctx:
                    self.checkForOptionalInjectedNodes(next_action, frame, frame[ctx]["instances"], ctx)
    
    def checkForTerminalStateOccurrences(self, ctx, frame):
        if not "check-terminal" in frame[ctx]:
            frame[ctx]["check-terminal"] = "done"
            frame[ctx]["terminal-state"] = "true"
            
            child_instances = 0
            next_instances = 0
            
            for child in frame[ctx]["children"]:
                if frame[ctx]["children"][child]["start-state"] == "true":
                    child_instances = child_instances + frame[ctx]["children"][child]["instances"]
            
            for next_action in frame[ctx]["next-actions"]:
                if next_action in frame and not next_action == ctx:
                    next_instances = next_instances + frame[next_action]["instances"]
            
            terminal_instances = frame[ctx]["instances"] - (child_instances + next_instances)
            
            if terminal_instances > 0:
                frame[ctx]["terminal-instances"] = terminal_instances
            else:
                frame[ctx]["terminal-instances"] = 0
            
            for child in frame[ctx]["children"]:
                self.checkForTerminalStateOccurrences(child, frame[ctx]["children"])
            
            for next_action in frame[ctx]["next-actions"]:
                if next_action in frame and not next_action == ctx:
                    self.checkForTerminalStateOccurrences(next_action, frame)
    
    def printDeduced(self, dot = False, root_action_count = 1):
        # TODO: Extend this to use all top-level nodes in case they
        # are different
        self.global_ctx_counter = 0
        deduced = self.expandPathways(self.arrInjected.keys()[0], self.arrInjected, root_action_count)
        
        fixed_deduced = []
        for d in deduced:
            # Go down two levels
            fixed_singular = d["child"]["child"]
            
            for invocation in fixed_singular["invocations"]:
                invocation.pop(0, 0)
                invocation.pop(1, 0)
            
            fixed_deduced.append(fixed_singular)
        
        with open("deduced_experiences.json", "w") as f:
            json.dump(fixed_deduced, f)
        
        if dot:
            self.printDotDeduced(deduced)
        else:
            print deduced
    
    def allPossibleCombinations(self, n, static_indices):
        solutions = []
        prototype = []
        
        for i in range(n):
            prototype.append(1 if i in static_indices else 0)
        
        run = True
        while run:
            prototype[0] = prototype[0] + 1
            
            for i in range(n):
                if prototype[i] > 1:
                    prototype[i] = 1 if i in static_indices else 0
                    
                    if i < n - 1:
                        prototype[i + 1] = prototype[i + 1] + 1
                    else:
                        run = False
            
            solutions.append(copy.deepcopy(prototype))
        
        return solutions
    
    def allPossiblePermutationIndices(self, lengths):
        indices = []
        for i in range(len(lengths)):
            indices.append(0)
        
        solutions = []
        
        if len(indices) > 0:
            run = True
            while run:
                indices[0] = indices[0] + 1
                
                for i in range(len(lengths)):
                    if indices[i] >= lengths[i]:
                        indices[i] = 0
                        
                        if i == len(lengths) - 1:
                            run = False
                        else:
                            indices[i + 1] = indices[i + 1] + 1
                
                solutions.append(copy.deepcopy(indices))
        
        return solutions
    
    def allPossiblePermutations(self, objects):
        lengths = []
        for object in objects:
            lengths.append(len(object))
        
        indices = self.allPossiblePermutationIndices(lengths)
        solutions = []
        
        for index in indices:
            solution = []
            
            for i in range(len(objects)):
                solution.append(objects[i][index[i]])
            
            solutions.append(copy.deepcopy(solution))
        
        return solutions
    
    def allPossibleSingularPermutations(self, objects, static_indices):
        objects_extended = []
        for i in range(len(objects)):
            add = [object, None] if not i in static_indices else [object]
            objects_extended.append(add)
        
        solutions_pre = self.allPossiblePermutations(objects_extended)
        solutions = []
        
        for solution_pre in solutions_pre:
            for bit in solution_pre:
                if bit != None:
                    solutions.append(bit)
        
        return solutions
    
    def expandPaths(self, ctx, nodes, trace):
        paths = []
        
        node = nodes[ctx]
        if not node["uid"] in trace:
            ci_n = len(node["durations"])
            ci_N = len(self.taskDurations[ctx])
            
            # https://www.stat.tamu.edu/~lzhou/stat302/standardnormaltable.pdf
            ci_alpha = 0.05 # Not really used, more for reference
            ci_z = 1.96 # From standard distribution table for alpha = 0.5 (z_{1-alpha/2})
            
            ci_x_bar = sum(node["durations"]) / float(ci_n)
            ci_s_square = 0
            for i in range(ci_n):
                ci_s_square += (node["durations"][i] - ci_x_bar) * (node["durations"][i] - ci_x_bar)
            
            if ci_n != 1:
                ci_s_square /= (ci_n - 1)
            else:
                ci_s_square /= ci_n # Foo foo
            
            ci_sigma_hat_x_bar_pre = (ci_s_square / ci_n) * (1 - ci_n / ci_N)
            
            if abs(ci_sigma_hat_x_bar_pre) > 0:
                ci_sigma_hat_x_bar = math.sqrt(ci_sigma_hat_x_bar_pre)
            else:
                ci_sigma_hat_x_bar = 0
            
            ci = [ci_x_bar - ci_z * ci_sigma_hat_x_bar, ci_x_bar + ci_z * ci_sigma_hat_x_bar]
            
            node_desc = {"node": node["uid"],
                         "name": ctx,
                         "durations": node["durations"],
                         "outcomes": node["outcomes"],
                         "optional": node["optional"],
                         "duration-confidence": ci,
                         "invocations": [],
                         "instances": node["instances"],
                         "call-pattern": node["call-pattern"],
                         "theoretical": "false"}
            current_trace = copy.deepcopy(trace) + [node_desc["node"]]
            
            for invocation in node["invocations"]:
                invocation_fits = True
                
                for uid in invocation:
                    if not uid in current_trace:
                        invocation_fits = False
                        break
                
                if invocation_fits:
                    node_desc["invocations"].append(invocation)
            
            if len(node_desc["invocations"]) == 0:
                node_desc["theoretical"] = "true"
            
            child_paths = []
            
            for child in self.getStartNodes(node["children"]):
                expanded_child_paths = self.expandPaths(child, node["children"], current_trace)
                child_paths += expanded_child_paths
            
            next_action_paths = []
            
            for next_action in node["next-actions"]:
                if next_action != ctx:
                    expanded_next_action_paths = self.expandPaths(next_action, nodes, current_trace)
                    next_action_paths += expanded_next_action_paths
            
            if len(child_paths) > 0 and len(next_action_paths) > 0:
                children_optional = True
                
                for child_path in child_paths:
                    current_child_copy = copy.deepcopy(node_desc)
                    current_child_copy["child"] = child_path
                    
                    if child_path["optional"] != "true":
                        children_optional = False
                    
                    next_actions_optional = True
                    
                    for next_action in next_action_paths:
                        current_child_next_copy = copy.deepcopy(current_child_copy)
                        current_child_next_copy["next-action"] = next_action
                        
                        if next_action["optional"] != "true":
                            next_actions_optional = False
                        
                        paths.append(current_child_next_copy)
                    
                    if next_actions_optional:
                        paths.append(current_child_copy)
                if children_optional:
                    paths.append(node_desc)
            elif len(child_paths) > 0:
                children_optional = True
                
                for child_path in child_paths:
                    current_child_copy = copy.deepcopy(node_desc)
                    current_child_copy["child"] = child_path
                    
                    if child_path["optional"] != "true":
                        children_optional = False
                    
                    paths.append(current_child_copy)
                
                if children_optional:
                    paths.append(node_desc)
            elif len(next_action_paths) > 0:
                next_actions_optional = True
                
                for next_action in next_action_paths:
                    current_next_copy = copy.deepcopy(node_desc)
                    current_next_copy["next-action"] = next_action
                    
                    if next_action["optional"] != "true":
                        next_actions_optional = False
                    
                    paths.append(current_next_copy)
                
                if next_actions_optional:
                    paths.append(node_desc)
            else:
                paths.append(node_desc)
        
        return paths
    
    def printPath(self, path, indentation = "", is_next = False):
        sys.stdout.write(indentation + str(path["node"]))
        
        if "next-action" in path:
            self.printPath(path["next-action"], "   ", True)
        
        if not is_next:
            sys.stdout.write("\n")
        
        if "child" in path:
            if is_next:
                sys.stdout.write("   \n")
            
            self.printPath(path["child"], "    " if is_next else "")
    
    def expandPathways(self, ctx, nodes, root_action_count, trace = [], relation = "root", correspondant = ""):
        pathways = self.expandPaths(ctx, nodes, [])
        
        return pathways
    
    def getStartNodes(self, nodes):
        start_nodes = {}
        
        for node in nodes:
            if nodes[node]["start-state"] == "true":
                start_nodes[node] = nodes[node]
        
        return start_nodes
    
    def printInjected(self, dot = False):
        if dot:
            self.printInjectedDot()
        else:
            print self.arrInjected
    
    def printInjectedChildren(self, children, parent = None):
        dot = ""
        edge_pointers = {}
        next_action_parameters = {}
        ids = {}
        optionals = {}
        
        parent_id = parent
        if not parent:
            parent_id = "root"
        
        for child in children:
            child_id = "node_" + child.replace("-", "_") + "_" + str(self.counterdot)
            ids[child] = child_id
            
            self.counterdot = self.counterdot + 1
            
            label = child
            if label[:21] == "REPLACEABLE-FUNCTION-":
                label = label[21:]
            
            call_pattern = children[child]["call-pattern"]
            
            dot += "  " + child_id + " [shape=box, label=\"" + label + " (" + str(children[child]["uid"]) + " / " + str(children[child]["instances"]) + ")\n" + call_pattern + "\"]\n"
            
            if children[child]["terminal-state"] == "true":
                if children[child]["terminal-instances"] > 0:
                    dot += "    ts_" + str(self.counterdot) + " [shape=doublecircle, label=\"" + str(children[child]["terminal-instances"]) + "\"]\n"
                    dot += "    edge [style=dashed, arrowhead=normal, arrowtail=none, label=\"terminal\"]\n"
                    dot += "    " + child_id + " -> " + "ts_" + str(self.counterdot) + "\n"
            
            dot += self.printInjectedChildren(children[child]["children"], child_id)
            
            if parent:
                if children[child]["start-state"] == "true":
                    if children[child]["optional"] == "true":
                        dot += "  edge [style=solid, arrowhead=normal, arrowtail=none, label=\"optional\"]\n"
                    else:
                        dot += "  edge [style=solid, arrowhead=normal, arrowtail=none, label=\"\"]\n"
                else:
                    if children[child]["optional"] == "true":
                        dot += "  edge [style=dashed, arrowhead=none, arrowtail=none, label=\"\"]\n"
                    else:
                        dot += "  edge [style=dashed, arrowhead=none, arrowtail=none, label=\"\"]\n"
                
                dot += "  " + parent + " -> " + child_id + "\n"
            
            for na in children[child]["next-actions"]:
                if parent:
                    if not na in edge_pointers:
                        edge_pointers[na] = []
                        next_action_parameters[na] = {}
                    
                    if not child_id in next_action_parameters[na]:
                        next_action_parameters[na][child_id] = []
                    
                    edge_pointers[na].append(child_id)
        
        for child in children:
            child_id = ids[child]
            
            if child in edge_pointers:
                for target in edge_pointers[child]:
                    param_str = ""
                    # for param_sets in next_action_parameters[child][target]:
                    #     for param_set in param_sets:
                    #         first_p = True
                    #         for p in param_set:
                    #             if first_p:
                    #                 first_p = False
                    #             else:
                    #                 param_str = param_str + ", "
                                
                    #             param_str = param_str + p + " = " + param_set[p]
                            
                    #         param_str = param_str + "\\n"
                    #if next_action_parameters[
                    
                    if children[child]["optional"] == "true":
                        param_str = "optional"
                    else:
                        param_str = ""
                    
                    dot += "  {rank=same; " + child_id + " " + target + "}\n"
                    dot += "  edge [style=solid, arrowhead=empty, arrowtail=none, label=\"" + param_str + "\"]\n"
                    dot += "  " + target + " -> " + child_id + "\n"
        
        return dot
    
    def printInjectedDot(self):
        self.counterdot = 0
        self.edge_pointers = {}
        
        dot = "digraph condensed {\n"
        dot += "  graph []\n"#ranksep=0.5#nodesep=0.5#pad=0.5
        dot += "  label=\"Condensed Experience Graph\"\n"
        dot += "  labeljust=center\n"
        dot += "  labelloc=top\n"
        dot += self.printInjectedChildren(self.arrInjected)
        dot += "}\n"
        
        print dot
    
    def expScore(self, exp):
        acc_score = 1.0
        
        for item in exp:
            instances = item["instances"]
            rel_occ = item["rel-occ"]
            acc_score = acc_score * rel_occ
        
        last_item = exp[len(exp) - 1]
        acc_score = acc_score * last_item["rel-term"]
        
        return acc_score
    
    def expScoreCmp(self, exp1, exp2):
        score1 = self.expScore(exp1)
        score2 = self.expScore(exp2)
        
        if score1 < score2:
            return 1
        elif score1 > score2:
            return -1
        else:
            return 0
    
    def reconstructItem(self, root, sequential):
        if not "children" in root:
            root["children"] = []
        
        if not "next" in root:
            root["next"] = None
        
        for item in sequential:
            #print item["correspondant"], root["uid"]
            if item["correspondant"] == root["uid"]:
                enriched_item = self.reconstructItem(item, sequential)
                
                if item["relation"] == "child":
                    root["children"].append(enriched_item)
                elif item["relation"] == "sibling":
                    root["next"] = enriched_item
        
        return root
    
    def reassambleStructure(self, sequential):
        root = None
        
        for item in sequential:
            #sys.stderr.write(str(item))
            if item["relation"] == "root":
                root = item
                break
        
        if root:
            root = self.reconstructItem(root, sequential)
        
        return root
    
    def printDeducedPlan(self, plan, indentation):
        dot = ""
        
        this_node = "node_" + str(self.node_counter)
        name = (plan["name"][21:] if plan["name"][:21] == "REPLACEABLE-FUNCTION-" else plan["name"]).lower()
        
        line_name = name + " (ID " + str(plan["node"]) + "" + (", theoretical" if plan["theoretical"] == "true" else "") + "), "
        line_call_pattern = plan["call-pattern"]
        line_invocations = str(len(plan["invocations"])) + " invocation" + ("" if len(plan["invocations"]) == 1 else "s")
        
        line_name = line_name + ("" if line_name == "" else "\n")
        line_call_pattern = line_call_pattern + ("" if line_call_pattern == "" else "\n")
        line_invocations = line_invocations + ("" if line_invocations == "" else "\n")
        
        dot += indentation + this_node + " [shape=box, label=\"" + line_name + line_call_pattern + line_invocations + "\"];\n"
        self.node_counter = self.node_counter + 1
        
        if "next-action" in plan:
            (dot_new, that_node) = self.printDeducedPlan(plan["next-action"], indentation)
            dot += dot_new
            
            dot += indentation + "{rank=same; " + this_node + " " + that_node + "};\n"
            
            dot += indentation + "edge [arrowhead=empty, arrowtail=none, label=\"sequence\"]\n"
            dot += indentation + this_node + " -> " + that_node + ";\n"
        
        if "child" in plan:
            (dot_new, that_node) = self.printDeducedPlan(plan["child"], indentation)
            dot += dot_new
            
            dot += indentation + "edge [arrowhead=normal, arrowtail=none, label=\"child\"]\n"
            dot += indentation + this_node + " -> " + that_node + ";\n"
        
        return (dot, this_node)
    
    def printDotDeduced(self, deduced):
        self.node_counter = 0
        
        counter = 0
        subgraphcounter = 0
        #print len(deduced)
        #print deduced
        #exit(-1)
        dot = "digraph deduced {\n"
        dot += "  label=\"Deduced Possible Action Paths\"\n"
        dot += "  labeljust=center\n"
        dot += "  labelloc=top\n"
        
        cluster_index = 0
        for plan in deduced:
            dot += "  \n"
            dot += "  subgraph cluster_" + str(cluster_index) + " {\n"
            dot += "    label=\"\";\n"
            (cluster, something) = self.printDeducedPlan(plan, "    ");
            dot += cluster
            dot += "  }\n"
            
            cluster_index = cluster_index + 1
        
        dot += "}\n"
        
        print dot
예제 #11
0
class MemoryCondenser:
    def __init__(self, parent=None):
        self.rdrOwl = OwlReader()
        self.rdrDesig = DesignatorReader()
        
        self.arrExperiences = []
    
    def countExperiences(self):
        return len(self.arrExperiences)
    
    def addExperience(self, expAdd):
        self.arrExperiences.append(expAdd)
    
    def loadExperience(self, strOwlFile, strDesignatorFile):
        logReturn = Log()
        
        logReturn.setOwlData(self.rdrOwl.loadOwl(strOwlFile))
        
        if strDesignatorFile != "":
            logReturn.setDesignatorData(self.rdrDesig.loadDesignators(strDesignatorFile))
        
        self.addExperience(logReturn)
    
    def condenseData(self, dataOwl):
        result = None
        
        self.tti = dataOwl["task-tree-individuals"]
        owlMeta = dataOwl["metadata"]
        owlAnnot = dataOwl["annotation"]
        
        if owlMeta:
            result = {"Toplevel" : self.condenseNodes("", owlMeta.subActions())};
        else:
            print "No meta data in file!"
        
        return result
    
    def condenseNodes(self, strParentNode, arrNodes, nLevel = 0):
        arrTypes = {}
        arrIndividuals = {}
        
        for strNode in arrNodes:
            owlNode = self.tti[strNode]
            ident = owlNode.taskContext()
            
            failures = owlNode.failures()
            failure = ""
            if len(failures) > 0:
                failure = self.tti[failures[0]].type()
            
            result = self.condenseNodes(strNode, owlNode.subActions(), nLevel + 1)
            if not ident in arrTypes:
                arrTypes[ident] = result
            else:
                arrTypes[ident] = self.unifyResults(arrTypes[ident], result)
            
            arrTypes[ident]["individuals"][strNode] = {"parameters" : owlNode.annotatedParameters(True),
                                                       "parent" : strParentNode,
                                                       "failure" : failure}
        
        return {"subTypes" : arrTypes,
                "individuals" : {}}
    
    def unifyResults(self, res1, res2):
        resparams = {}
        if len(res1["individuals"]) > 0:
            resparams = res1["individuals"]
        
        if len(res2["individuals"]) > 0:
            resparams = dict(resparams.items() + res2["individuals"].items())
        
        unified = {"subTypes" : {},
                   "individuals" : resparams}
        
        for ressub1 in res1["subTypes"]:
            if ressub1 in res2["subTypes"]:
                unified["subTypes"][ressub1] = self.unifyResults(res1["subTypes"][ressub1],
                                                                 res2["subTypes"][ressub1])
            else:
                unified["subTypes"][ressub1] = res1["subTypes"][ressub1]
        
        for ressub2 in res2["subTypes"]:
            if not ressub2 in res1["subTypes"]:
                unified["subTypes"][ressub2] = res2["subTypes"][ressub2]
        
        return unified
    
    def condense(self):
        arrStartNodes = []
        
        self.tti = {}
        
        for experience in self.arrExperiences:
            owlData = experience.getOwlData()
            metaData = owlData["metadata"]
            arrStartNodes += metaData.subActions()
            
            self.tti.update(owlData["task-tree-individuals"])
        
        self.processed_nodes = []
        tree = self.condenseNodesByContext(arrStartNodes)
        parameters = {}
        
        for node in self.processed_nodes:
            params = self.tti[node].annotatedParameters(bSingularParameters = True)
            
            if len(params) > 0:
                parameters[node] = {}
                for p in params:
                    if not p == "_time_created":
                        parameters[node][p.lstrip("parameter-")] = params[p]
        
        result = {"tree": tree,
                  "parameters": parameters}
        
        print result
    
    def sortComparatorActionTime(self, action1, action2):
        if action1.timeSpan[0] > action2.timeSpan[0]:
            return 1
        elif action1.timeSpan[0] == action2.timeSpan[0]:
            return 0
        else:
            return -1
    
    def sortActionsByTime(self, actions):
        actions.sort(self.sortComparatorActionTime)
        
        return actions
    
    def condenseNodesByContext(self, nodes):
        # Separate nodes by their taskContext
        dicContexts = {}
        
        for node in nodes:
            self.processed_nodes.append(node)
            
            owlNode = self.tti[node]
            
            if not owlNode.taskContext() in dicContexts:
                dicContexts[owlNode.taskContext()] = {"nodes": [],
                                                      "terminal-state": []}
            
            dicContexts[owlNode.taskContext()]["nodes"].append(node)
        
        for context in dicContexts:
            all_children = []
            
            for node in dicContexts[context]["nodes"]:
                sub_actions = self.sortActionsByTime(self.tti[node].subActions())
                
                if len(sub_actions) > 0:
                    all_children += sub_actions
                else:
                    dicContexts[context]["terminal-state"].append(node)
            
            dicContexts[context]["children"] = self.condenseNodesByContext(all_children)
        
        return dicContexts
    
    def generalizeExperiences(self):
        self.generalizedExperience = {}
        self.tti = {}
        
        arrStartNodes = []
        
        for experience in self.arrExperiences:
            owlData = experience.getOwlData()
            metaData = owlData["metadata"]
            arrStartNodes += metaData.subActions()
            
            self.tti.update(owlData["task-tree-individuals"])
        
        for node in arrStartNodes:
            self.injectActionIntoGeneralizedExperience(node, self.generalizedExperience)
        
        print self.generalizedExperience
    
    def injectActionIntoGeneralizedExperience(self, action, target_branch):
        target_branch["a"] = 5
    
    def dotNode(self, node, first):
        dot = ""
        tti = self.t_tti[node]
        former_subnode = ""
        
        dot += "  {rank=same;"
        for subnode in tti.subActions():
            dot += " " +subnode
        dot += "}\n"
        
        for subnode in tti.subActions():
            dot += "  " + subnode + " [shape=box, label=\"" + self.t_tti[subnode].taskContext() + "\"]\n"
            #dot += "  edge ";
            
            if first == True:
                first = False
                dot += "edge [dir=both, arrowhead=normal, arrowtail=none]"
                dot += "\n  " + node + " -> " + subnode + "\n"
            else:
                pass#dot += "[dir=both, arrowhead=diamond, arrowtail=ediamond]"
            
            
            if not former_subnode == "":
                dot += "  edge [arrowhead=empty, arrowtail=none]\n"
                dot += "  " + former_subnode + " -> " + subnode + "\n"
            
            dot += self.dotNode(subnode, True)
            
            former_subnode = subnode
        
        if len(tti.subActions()) == 0 and tti.nextAction() == None:
            #dot += "  terminal_state_" + node + " [shape=doublecircle, label=\"\"]\n"
            #dot += "  edge [arrowhead=empty, arrowtail=none]\n"
            #dot += "  " + node + " -> terminal_state_" + node + "\n"
            pass
        
        return dot
    
    def printExperiences(self, dot):
        for experience in self.arrExperiences:
            if dot:
                self.printDotExperience(experience)
            else:
                self.printRawExperience(experience)
    
    def printRawExperience(self, experience):
        owlData = experience.getOwlData()
        metaData = owlData["metadata"]
        start_nodes = metaData.subActions()
        self.t_tti = owlData["task-tree-individuals"]
        
        for node in start_nodes:
            self.printRawExperienceNode(node)
    
    def printRawExperienceNode(self, node, level = 0):
        indent = "   " * level
        owl = self.t_tti[node]
        
        parameters = owl.annotatedParameters()
        param_str = "("
        first = True
        
        for parameter in parameters:
            if not parameter == "_time_created":
                if first == True:
                    first = False
                else:
                    param_str = param_str + ", "
                
                key_str = parameter[10:] if parameter[:10] == "parameter-" else parameter
                param_str = param_str + key_str + "=" + parameters[parameter][0]
        
        param_str = param_str + ")"
        
        print indent + owl.taskContext() + " " + param_str
        
        if len(owl.subActions()) > 0:
            for node in owl.subActions():
                self.printRawExperienceNode(node, level + 1)
    
    def printDotExperience(self, experience):
        owlData = experience.getOwlData()
        metaData = owlData["metadata"]
        start_nodes = metaData.subActions()
        self.t_tti = owlData["task-tree-individuals"]
        
        dot = "digraph plangraph {\n"
        dot += "  label=\"Original Experiences\"\n"
        dot += "  labeljust=center\n"
        dot += "  labelloc=top\n"
        
        for node in start_nodes:
            dot += "  " + node + " [shape=box, label=\"" + self.t_tti[node].taskContext() + "\"]\n\n"
            
            dot += self.dotNode(node, True)
        
        dot += "}\n"
        
        print dot
    
    def compareSubActions(self, subaction1, subaction2):
        if subaction1 == subaction2:
            return 0
        
        next_action = subaction1
        
        while next_action != None:
            next_action = self.tti[subaction1].nextAction()
            
            if next_action == subaction2:
                return 1
        
        return -1
    
    def sortSubActions(self, subactions):
        subactions.sort(self.compareSubActions)
        
        return subactions
    
    def sortSubActionsList(self, subactions_list):
        sorted_list = []
        
        for subactions in subactions_list:
            sorted_list.append(self.sortSubActions(subactions))
        
        return sorted_list
    
    def generalizeNodes(self, nodes):
        sequences = []
        
        for node in nodes:
            sequences.append(self.tti[node].subActions())
        
        return sequences
    
    def workOnExperiences(self):
        start_nodes = []
        self.tti = {}
        
        for experience in self.arrExperiences:
            owlData = experience.getOwlData()
            metaData = owlData["metadata"]
            
            start_nodes += metaData.subActions()
            self.tti.update(owlData["task-tree-individuals"])
        
        print self.generalizeNodes(start_nodes)
    
    def injectExperiences(self, deduced = False, data = False):
        self.arrInjected = {}
        self.tti = {}
        self.uid_counter = 0;
        
        root_action_count = 0
        
        for experience in self.arrExperiences:
            owlData = experience.getOwlData()
            metaData = owlData["metadata"]
            self.tti.update(owlData["task-tree-individuals"])
            
            for node in metaData.subActions():
                self.injectExperienceNode(node, self.arrInjected)
                root_action_count = root_action_count + 1
        
        for experience in self.arrExperiences:
            owlData = experience.getOwlData()
            metaData = owlData["metadata"]
            self.tti.update(owlData["task-tree-individuals"])
            
            for node in metaData.subActions():
                self.checkForTerminalStateOccurrences(self.tti[node].taskContext(), self.arrInjected)
            
            for node in metaData.subActions():
                self.checkForOptionalInjectedNodes(self.tti[node].taskContext(), self.arrInjected)
        
        if deduced:
            self.printDeduced(dot = not data, root_action_count = root_action_count)
        else:
            self.printInjected(dot = not data)
    
    def injectExperienceNode(self, node, frame, rootlevel = False, invocation_path = {}):
        ctx = self.tti[node].taskContext()
        
        params = self.tti[node].annotatedParameters()
        params_fixed = {}
        call_pattern = ""
        
        for param in params:
            if not param == "_time_created" and not param == "CALLPATTERN":
                key_str = param[10:] if param[:10] == "parameter-" else param
                params_fixed[key_str] = params[param][0]
            elif param == "CALLPATTERN":
                call_pattern = params[param][0]
        
        new_invocation_path = invocation_path.copy()
        
        if not ctx in frame:
            new_invocation_path.update({self.uid_counter: params_fixed})
            frame[ctx] = {"children": {}, "next-actions" : {}, "uid" : self.uid_counter, "terminal-state": "false", "start-state": "false", "optional": "false", "instances": 0, "invocations": [new_invocation_path], "call-pattern": call_pattern}
            self.uid_counter = self.uid_counter + 1
        else:
            new_invocation_path.update({frame[ctx]["uid"]: params_fixed})
            frame[ctx]["invocations"].append(new_invocation_path)
        
        frame[ctx]["instances"] = frame[ctx]["instances"] + 1
        
        sub_nodes = self.tti[node].subActions()
        
        for sub in sub_nodes:
            self.injectExperienceNode(sub, frame[ctx]["children"], False, new_invocation_path)
        
        next_node = self.tti[node].nextAction()
        
        if next_node:
            current_ctx = ctx
            while next_node:
                nextCtx = self.tti[next_node].taskContext()
                
                call_pattern = self.tti[next_node].annotatedParameterValue("CALLPATTERN")
                if not call_pattern:
                    call_pattern = ""
                
                if not current_ctx in frame:
                    frame[current_ctx] = {"children": {}, "next-actions" : {}, "uid" : self.uid_counter, "terminal-state": "false", "start-state": "false", "optional": "false", "instances": 0, "invocations": [], "call-pattern": call_pattern}
                    self.uid_counter = self.uid_counter + 1
                
                if not nextCtx in frame[current_ctx]["next-actions"] and not rootlevel:
                    if not nextCtx == current_ctx:
                        if not nextCtx in frame[current_ctx]["next-actions"]:
                            frame[current_ctx]["next-actions"][nextCtx] = []
                        
                        params = self.tti[next_node].annotatedParameters()
                        params_fixed = {}
                        
                        for param in params:
                            if not param == "_time_created":
                                key_str = param[10:] if param[:10] == "parameter-" else param
                                params_fixed[key_str] = params[param][0]
                        
                        frame[current_ctx]["next-actions"][nextCtx].append(params_fixed)
                    
                next_node = self.tti[next_node].nextAction()
                current_ctx = nextCtx
        else:
            if len(self.tti[node].subActions()) == 0:
                frame[ctx]["terminal-state"] = "true"
        
        if frame[ctx]["start-state"] == "false":
            if self.tti[node].previousAction() == None:
                frame[ctx]["start-state"] = "true"
    
    def checkForOptionalInjectedNodes(self, ctx, frame, parent_instances = -1, came_from = None):
        if not "check-optional" in frame[ctx]:
            frame[ctx]["check-optional"] = "done"
            
            came_from_terminates = False
            came_from_valid = True
            if came_from:
                if came_from == ctx:
                    came_from_valid = False
                
                if frame[came_from]["terminal-state"] == "true":
                    came_from_terminates = True
            
            if came_from_valid == True:
                if frame[ctx]["instances"] < parent_instances or came_from_terminates:
                    frame[ctx]["optional"] = "true"
            
            for child in frame[ctx]["children"]:
                if frame[ctx]["children"][child]["start-state"] == "true":
                    self.checkForOptionalInjectedNodes(child, frame[ctx]["children"], frame[ctx]["instances"])
            
            for next_action in frame[ctx]["next-actions"]:
                if next_action in frame and not next_action == ctx:
                    self.checkForOptionalInjectedNodes(next_action, frame, frame[ctx]["instances"], ctx)
    
    def checkForTerminalStateOccurrences(self, ctx, frame):
        if not "check-terminal" in frame[ctx]:
            frame[ctx]["check-terminal"] = "done"
            
            child_instances = 0
            next_instances = 0
            
            if frame[ctx]["terminal-state"] == "true":
                for child in frame[ctx]["children"]:
                    if frame[ctx]["children"][child]["start-state"] == "true":
                        child_instances = child_instances + frame[ctx]["children"][child]["instances"]
                
                for next_action in frame[ctx]["next-actions"]:
                    if next_action in frame and not next_action == ctx:
                        next_instances = next_instances + frame[next_action]["instances"]
                
                terminal_instances = frame[ctx]["instances"] - (child_instances + next_instances)
                
                if terminal_instances > 0:
                    frame[ctx]["terminal-instances"] = terminal_instances
                else:
                    frame[ctx]["terminal-instances"] = 0
            else:
                frame[ctx]["terminal-state"] = "false"
                frame[ctx]["terminal-instances"] = 0
            
            for child in frame[ctx]["children"]:
                self.checkForTerminalStateOccurrences(child, frame[ctx]["children"])
            
            for next_action in frame[ctx]["next-actions"]:
                if next_action in frame and not next_action == ctx:
                    self.checkForTerminalStateOccurrences(next_action, frame)
    
    def printDeduced(self, dot = False, root_action_count = 1):
        # TODO: Extend this to use all top-level nodes in case they
        # are different
        self.global_ctx_counter = 0
        deduced = self.expandPathways(self.arrInjected.keys()[0], self.arrInjected, root_action_count)
        
        fixed_deduced = []
        for d in deduced:
            fixed_singular = d[2:]
            for step in fixed_singular:
                for invocation in step["invocations"]:
                    invocation.pop(0, 0)
                    invocation.pop(1, 0)
            
            fixed_deduced.append(fixed_singular)
        
        with open("deduced_experiences.json", "w") as f:
            json.dump(fixed_deduced, f)
        
        if dot:
            self.printDotDeduced(deduced)
        else:
            print deduced
    
    def expandPathways(self, ctx, nodes, root_action_count, trace = []):
        expanded_pathways = []
        
        if not nodes[ctx]["uid"] in trace:
            current_node = [{"node": ctx, "instances": nodes[ctx]["instances"], "uid": nodes[ctx]["uid"], "rel-occ": (float(nodes[ctx]["instances"]) / float(root_action_count)), "rel-term": (float(nodes[ctx]["terminal-instances"]) / float(nodes[ctx]["instances"])), "invocations": nodes[ctx]["invocations"], "call-pattern": nodes[ctx]["call-pattern"]}]
            children = self.getStartNodes(nodes[ctx]["children"])
            
            had_non_optional_children = False
            for child in children:
                if not children[child]["optional"] == "true":
                    had_non_optional_children = True
                    
                child_pathways = self.expandPathways(child, nodes[ctx]["children"], nodes[ctx]["instances"], trace + [nodes[ctx]["uid"]])
                
                for child_pathway in child_pathways:
                    expanded_pathways.append(current_node + child_pathway)
                    
            if not had_non_optional_children:
                expanded_pathways.append(current_node)
                
            next_actions = nodes[ctx]["next-actions"]
            final_pathways = []
            
            had_non_optional_next_actions = False
            for next_action in next_actions:
                if next_action != ctx:
                    if not nodes[next_action]["optional"] == "true":
                        had_non_optional_next_actions = True
                        
                    expanded_next_pathways = self.expandPathways(next_action, nodes, nodes[ctx]["instances"], trace + [nodes[ctx]["uid"]])
                    
                    for expanded_next_pathway in expanded_next_pathways:
                        for expanded_pathway in expanded_pathways:
                            final_pathways = final_pathways + [expanded_pathway + expanded_next_pathway]
                            
            if not had_non_optional_next_actions:
                final_pathways = final_pathways + expanded_pathways
                
            return final_pathways
        else:
            return []
    
    def getStartNodes(self, nodes):
        start_nodes = {}
        
        for node in nodes:
            if nodes[node]["start-state"] == "true":
                start_nodes[node] = nodes[node]
        
        return start_nodes
    
    def printInjected(self, dot = False):
        if dot:
            self.printInjectedDot()
        else:
            print self.arrInjected
    
    def printInjectedChildren(self, children, parent = None):
        dot = ""
        edge_pointers = {}
        next_action_parameters = {}
        ids = {}
        optionals = {}
        
        parent_id = parent
        if not parent:
            parent_id = "root"
        
        for child in children:
            child_id = "node_" + child.replace("-", "_") + "_" + str(self.counterdot)
            ids[child] = child_id
            
            self.counterdot = self.counterdot + 1
            
            label = child
            if label[:21] == "REPLACEABLE-FUNCTION-":
                label = label[21:]
            
            dot += "  " + child_id + " [shape=box, label=\"" + label + " (" + str(children[child]["uid"]) + " / " + str(children[child]["instances"]) + ")\"]\n"
            
            if children[child]["terminal-state"] == "true":
                if children[child]["terminal-instances"] > 0:
                    dot += "    ts_" + str(self.counterdot) + " [shape=doublecircle, label=\"" + str(children[child]["terminal-instances"]) + "\"]\n"
                    dot += "    edge [style=dashed, arrowhead=normal, arrowtail=none, label=\"terminal\"]\n"
                    dot += "    " + child_id + " -> " + "ts_" + str(self.counterdot) + "\n"
            
            dot += self.printInjectedChildren(children[child]["children"], child_id)
            
            if parent:
                if children[child]["start-state"] == "true":
                    if children[child]["optional"] == "true":
                        dot += "  edge [style=solid, arrowhead=normal, arrowtail=none, label=\"optional\"]\n"
                    else:
                        dot += "  edge [style=solid, arrowhead=normal, arrowtail=none, label=\"\"]\n"
                else:
                    if children[child]["optional"] == "true":
                        dot += "  edge [style=dashed, arrowhead=none, arrowtail=none, label=\"\"]\n"
                    else:
                        dot += "  edge [style=dashed, arrowhead=none, arrowtail=none, label=\"\"]\n"
                
                dot += "  " + parent + " -> " + child_id + "\n"
            
            for na in children[child]["next-actions"]:
                if parent:
                    if not na in edge_pointers:
                        edge_pointers[na] = []
                        next_action_parameters[na] = {}
                    
                    if not child_id in next_action_parameters[na]:
                        next_action_parameters[na][child_id] = []
                    
                    edge_pointers[na].append(child_id)
                    #next_action_parameters[na][child_id].append(children[child]["next-actions"][na])
        
        #print "!"
        #print next_action_parameters
        for child in children:
            child_id = ids[child]
            
            if child in edge_pointers:
                for target in edge_pointers[child]:
                    param_str = ""
                    # for param_sets in next_action_parameters[child][target]:
                    #     for param_set in param_sets:
                    #         first_p = True
                    #         for p in param_set:
                    #             if first_p:
                    #                 first_p = False
                    #             else:
                    #                 param_str = param_str + ", "
                                
                    #             param_str = param_str + p + " = " + param_set[p]
                            
                    #         param_str = param_str + "\\n"
                    #if next_action_parameters[
                    
                    if children[child]["optional"] == "true":
                        param_str = "optional"
                    else:
                        param_str = ""
                    
                    dot += "  {rank=same; " + child_id + " " + target + "}\n"
                    dot += "  edge [style=solid, arrowhead=empty, arrowtail=none, label=\"" + param_str + "\"]\n"
                    dot += "  " + target + " -> " + child_id + "\n"
        
        return dot
    
    def printInjectedDot(self):
        self.counterdot = 0
        self.edge_pointers = {}
        
        dot = "digraph condensed {\n"
        dot += "  graph []\n"#ranksep=0.5#nodesep=0.5#pad=0.5
        dot += "  label=\"Condensed Experience Graph\"\n"
        dot += "  labeljust=center\n"
        dot += "  labelloc=top\n"
        dot += self.printInjectedChildren(self.arrInjected)
        dot += "}\n"
        
        print dot
    
    def expScore(self, exp):
        acc_score = 1.0
        
        for item in exp:
            instances = item["instances"]
            rel_occ = item["rel-occ"]
            acc_score = acc_score * rel_occ
        
        last_item = exp[len(exp) - 1]
        acc_score = acc_score * last_item["rel-term"]
        
        return acc_score
    
    def expScoreCmp(self, exp1, exp2):
        score1 = self.expScore(exp1)
        score2 = self.expScore(exp2)
        
        if score1 < score2:
            return 1
        elif score1 > score2:
            return -1
        else:
            return 0
    
    def printDotDeduced(self, deduced):
        counter = 0
        subgraphcounter = 0
        
        dot = "digraph deduced {\n"
        dot += "  label=\"Deduced Possible Action Paths\"\n"
        dot += "  labeljust=center\n"
        dot += "  labelloc=top\n"
        
        highest_score = 0
        for line in deduced:
            acc_score = self.expScore(line)
            
            if acc_score > highest_score:
                highest_score = acc_score
        
        deduced.sort(self.expScoreCmp)
        
        for line in deduced:
            dot += "  \n"
            
            dot += "  subgraph cluster_" + str(subgraphcounter) + " {\n"
            dot += "    pencolor=transparent;\n"
            dot += "    \n"
            subgraphcounter = subgraphcounter + 1
            
            first = True
            acc_score = 1.0
            
            for item in line:
                instances = item["instances"]
                node = item["node"]
                rel_occ = item["rel-occ"]
                
                # Correct node label
                if node[:21] == "REPLACEABLE-FUNCTION-":
                    node = node[21:]
                
                acc_score = acc_score * rel_occ
                
                if not first:
                    dot += "    node_" + str(counter - 1) + " -> node_" + str(counter) + "\n"
                else:
                    first = False
                
                dot += "    node_" + str(counter) + " [shape=box, label=\"" + node + " (" + str(round(rel_occ, 2)) + ")\"]\n"
                counter = counter + 1
            
            last_item = line[len(line) - 1]
            
            dot += "    ts_" + str(counter - 1) + " [shape=doublecircle, label=\"" + str(round(last_item["rel-term"], 2)) + "\"]\n"
            dot += "    edge [style=dashed, arrowhead=normal, arrowtail=none, label=\"\"]\n"
            dot += "    node_" + str(counter - 1) + " -> " + "ts_" + str(counter - 1) + "\n"
            
            acc_score = acc_score * last_item["rel-term"]
            
            dot += "    \n"
            dot += "    label=\"Score: " + str(round(acc_score, 2)) + "\";\n"
            dot += "    labeljust=center;\n"
            dot += "    labelloc=top;\n"
            dot += "  }\n"
            
        dot += "}\n"
        
        print dot
예제 #12
0
 def __init__(self):
     self.rdrOwl = OwlReader()
     self.rdrDesig = DesignatorReader()