Ejemplo n.º 1
0
    def check_state_transitions_declarations(self):
        conditions = set()
        st_used = set()
        br_used = set()

        validate(type(self.klass.state_transitions) == list,
            "%s.state_transitions must be a valid list" % self.name)

        for idx, st in enumerate(self.klass.state_transitions):
            validate(type(st) in (list, tuple),
                "%s.state_transitions[%d] should be a tuple" % (st, idx))
            validate(len(st) == 3,
                "%s.state_transitions[%d] has %d entries, expecting 3" \
                    % (st, idx, len(st)))

            st_from, tf, st_to = st
            validate(type(st_from) == str
                        and type(tf) == str
                        and type(st_to) in (str, list, tuple),
                "%s.state_transitions[%d] contains non-string entries")

            if type(st_to) == str:
                validate(tf in self.st_classes,
                    "%s.state_transitions[%d]: "
                    "invalid transition function %s" % (self.name, idx, tf))
                st_used.add(tf)
            else:
                validate(tf in self.branches,
                    "%s.state_transitions[%d]: "
                    "invalid branch function %s" % (self.name, idx, tf))
                br_used.add(tf)
                for f, s, c in st_to:
                    validate(f in self.st_classes,
                        "%s.state_transitions[%d]: "
                        "invalid transition function %s" % (self.name,
                                                                idx, tf))
                    st_used.add(f)
                    validate(c not in conditions,
                        "%s.state_transitions[%d]: "
                        "condition labels must be unique. "
                        "Duplicate entry found - %s." % (self.name, idx, c))
                    conditions.add(c)

        for u in set(self.st_classes).difference(st_used):
            warn("Transition function %s.%s is not used." % (self.name, u))
        for u in set(self.branches).difference(br_used):
            warn("Branch function %s.%s is not used." % (self.name, u))
Ejemplo n.º 2
0
    def _validate_message_usage(self):
        msgs = set(self.messages)
        msg_reads = set()
        msg_posts = set()
        for agent_name, agent_def in self.agents.iteritems():
            for st_name, st_class in agent_def.st_classes.iteritems():
                label = "%s.%s" % (agent_name, st_name)
                mr = set(st_class.msg_reads)
                mp = set(st_class.msg_posts)
                msg_reads.update(mr)
                msg_posts.update(mp)

                undef = mr - msgs
                validate(not undef,
                    "Undefined message in %s.msg_reads: %s" \
                    % (label, ", ".join(undef)))

                undef = mp - msgs
                validate(not undef,
                    "Undefined message in %s.msg_posts: %s" \
                    % (label, ", ".join(undef)))

        for msg in msg_posts - msg_reads:
            warn("'%s' message is posted but never read." % msg)
        for msg in msg_reads - msg_posts:
            warn("'%s' message is read but never posted." % msg)
        for msg in msgs - msg_posts - msg_reads:
            warn("'%s' message is defined but never used." % msg)
Ejemplo n.º 3
0
    def __init__(self, agent_class):
        self.klass = agent_class
        self.name = agent_class.__name__
        self.st_classes = None
        self.branches = None
        #self.state_graph = None  # set by self.load_states()

        validate(issubclass(agent_class, Agent),
                "%s not a subclass of papaya.core.agent.Agent" % self.name)
        validate(not agent_class.abstract,
                "%s is an abstract agent class" % self.name)

        # load agent memory variables
        self.memory = dict((name, inst)
                            for name, inst in inspect.getmembers(agent_class)
                            if isinstance(inst, Variable))
        if not self.memory:
            warn("No memory variables defined for %s" % self.name)

        self.load_st_and_branch_classes()
        self.check_mem_access_declarations()
        self.check_state_transitions_declarations()
Ejemplo n.º 4
0
    def check_mem_access_declarations(self):
        # keep track of mem vars that have been read/written to
        mem_read = set()
        mem_written = set()

        # validate read/write declarations for each state transition function
        for name, inst in self.st_classes.iteritems():
            fname = "%s.%s." % (self.name, name)
            self._val_rw_list(inst.reads, fname + "reads")
            self._val_rw_list(inst.writes, fname + "writes")
            self._val_rw_list(inst.msg_posts, fname + "msg_posts", "MSG")
            self._val_rw_list(inst.msg_reads, fname + "msg_reads", "MSG")
            mem_read.update(inst.reads)
            mem_written.update(inst.writes)

            msg_conflicts = set(inst.msg_posts).intersection(inst.msg_reads)
            validate(not msg_conflicts,
                "access conflict (read AND post) to mesage board - "
                "%s (%s.%s)" % (", ".join(msg_conflicts), self.name, name))

        # validate read/write declarations for each state branch routine
        for name, inst in self.branches.iteritems():
            fname = "%s.%s." % (self.branches, name)
            self._val_rw_list(inst.reads, fname + "reads")
            self._val_rw_list(inst.writes, fname + "writes")
            mem_read.update(inst.reads)
            mem_written.update(inst.writes)

        # ---- Check if all declared agent mem are actually used --
        mem_all = set(self.memory.keys())

        # check for unaccessed memory variables
        unused = mem_all - mem_read - mem_written
        for v in unused:
            warn("%s.%s is never accessed." % (self.name, v))

        # written but never read
        unread = mem_written - mem_read
        for v in unread:
            warn("%s.%s is written to but never read." % (self.name, v))

        # read but never written and not a constant
        unchanged = mem_read - mem_written
        for v in unchanged:
            if not self.memory[v]._constant:
                warn("%s.%s is never updated. "
                      "Consider setting constant=True." % (self.name, v))