First gets the cell at BeliefState's keypath, or creates a new cell 
        from the first target that has that keypath (This could mess up if the
        member its copying from has a different Cell or domain for that keypath.)
        Second, this merges that cell with the value

def merge(self, keypath, value, op='set'):
        """
        First gets the cell at BeliefState's keypath, or creates a new cell 
        from the first target that has that keypath (This could mess up if the
        member its copying from has a different Cell or domain for that keypath.)
        Second, this merges that cell with the value
        """
        negated = False
        keypath = keypath[:] # copy it 
        if keypath[0] == 'target':
            # only pull negated if it can potentially modify target
            negated = self.get_environment_variable('negated', pop=False, default=False)
            if negated:
                keypath[0] = "distractor"

        if keypath not in self:
            first_referent = None
            if keypath[0] in ['target', 'distractor']:
                has_targets = False 
                for _, referent in self.iter_singleton_referents():
                    has_targets = True
                    if keypath[1:] in referent:
                        first_referent = referent
                        break
                if first_referent is None:
                    # this happens when none of the available targets have the
                    # path that is attempted to being merged to
                    if has_targets:
                        raise CellConstructionFailure("Cannot merge; no target: %s" \
                            % (str(keypath)))
                    else:
                        # this will always happen when size is 0
                        raise CellConstructionFailure("Empty belief state")
                # find the type and add it to the 
                cell = first_referent.get_value_from_path(keypath[1:]).stem()
                self.add_cell(keypath, cell)
            else:
                # should we allow merging undefined components outside of target?
                raise Exception("Could not find Keypath %s" % (str(keypath)))

        # break down keypaths into 
        cell = self
        if not isinstance(keypath, list):
            keypath = [keypath]
        for key in keypath:
            cell = cell[key]
        # perform operation (set, <=, >= etc)
        try:
            return getattr(cell, op)(value)
        except Contradiction as ctrd:
            # add more information to the contradiction
            raise Contradiction("Could not merge %s with %s: %s " % (str(keypath), str(value), ctrd))