Beispiel #1
0
    def _gen_follow(self, command):
        """Generate statements for following."""
        # Env is stationary iff in the last state change our region and the env's region were stable
        stationary_explanation = "Definition of when the target is moving."
        stationary_safeties = \
            always(iff(next_(sys_(FOLLOW_STATIONARY)),
                       ENV_STATIONARY))
        stationary_lines = SpecChunk(stationary_explanation, [stationary_safeties], SpecChunk.SYS,
                                     command)

        # Stay there if environment is changing
        stay_there_explanation = "React immediately to the target moving."
        stay_there_safeties = \
            always(implies(not_(next_(sys_(FOLLOW_STATIONARY))), self._frag_stay()))
        stay_there_lines = \
            SpecChunk(stay_there_explanation, [stay_there_safeties], SpecChunk.SYS, command)

        # Match the sensor location to ours
        follow_goals = \
            [SpecChunk("Follow the target to {!r}.".format(region),
             [always_eventually(
              implies(and_((sys_(FOLLOW_STATIONARY), env(region))), sys_(region)))],
             SpecChunk.SYS, command) for region in self.regions]
        follow_env = SpecChunk("Target must obey map topology.",
                               [FOLLOW_SENSORS], SpecChunk.ENV, command)
        return ([stationary_lines, stay_there_lines] + follow_goals, [follow_env],
                [FOLLOW_STATIONARY], [])
Beispiel #2
0
    def _gen_follow(self, command):
        """Generate statements for following."""
        # Env is stationary iff in the last state change our region and the env's region were stable
        stationary_explanation = "Definition of when the target is moving."
        stationary_safeties = \
            always(iff(next_(sys_(FOLLOW_STATIONARY)),
                       ENV_STATIONARY))
        stationary_lines = SpecChunk(stationary_explanation, [stationary_safeties], SpecChunk.SYS,
                                     command)

        # Stay there if environment is changing
        stay_there_explanation = "React immediately to the target moving."
        stay_there_safeties = always(implies(not_(next_(sys_(FOLLOW_STATIONARY))), self._frag_stay()))
        stay_there_lines = SpecChunk(stay_there_explanation, [stay_there_safeties], SpecChunk.SYS,
                                     command)

        # Match the sensor location to ours
        follow_goals = \
          [SpecChunk("Follow the target to {!r}.".format(region),
            [always_eventually(implies(and_((sys_(FOLLOW_STATIONARY), env(region))), sys_(region)))],
            SpecChunk.SYS, command) for region in self.regions]
        follow_env = SpecChunk("Target must obey map topology.",
                               [FOLLOW_SENSORS], SpecChunk.ENV, command)
        return ([stationary_lines, stay_there_lines] + follow_goals, [follow_env], [FOLLOW_STATIONARY], [])
Beispiel #3
0
def _frag_complete_context(actuator, context_prop):
    """Generate fragments for completing an action in context."""
    actuator_done = _prop_actuator_done(actuator)
    eventually_actuator = always_eventually(env(actuator_done))
    return [and_((sys_(actuator), next_(env(actuator_done)), context_prop)), [eventually_actuator]]
Beispiel #4
0
    def _gen_conditional(self, command):
        """Generate a conditional action"""

        if isinstance(command.condition, Event):
            # Validate the condition
            if not command.condition.theme:
                raise KeyError("Cannot understand condition:\n{}".format(command.condition))
            condition = command.condition.theme.name
            if condition not in self.sensors:
                raise KeyError("No sensor to detect condition {!r}".format(command.condition.theme.name))
            if command.condition.sensor != SEE_ACTION:
                raise KeyError("Cannot use action {!r} as a condition".format(command.condition.action))
            condition_frag = env(condition)
            explanation = "To react to {!r},".format(condition)
        elif isinstance(command.condition, Assertion):
            # TODO: Add support for assertions not about "you". Ex: If there is a hostage...
            # Validate the condition
            if not command.condition.location:
                raise KeyError("Cannot understand condition:\n{}".format(command.condition))
            condition = command.condition.location.name
            condition_frag = sys_(condition)
            explanation = "When in {!r},".format(condition)
        else:
            raise KeyError("Cannot understand condition:\n{}".format(command.condition))

        # Validate the action
        action = command.action
        if action not in self.REACTIONS:
            raise KeyError("Unknown reaction {!r}".format(action))

        # Create the right type of reaction
        new_props = []
        if action in self.props:
            # Simple actuator
            reaction_prop = action
        elif action == STAY_ACTION:
            reaction_prop = STAY_THERE
        else:
            # Reaction proposition
            reaction_prop_name = REACT + "_" + condition
            reaction_prop = sys_(reaction_prop_name)
            self.react_props.add(reaction_prop_name)
            new_props.append(reaction_prop_name)

        # Generate the response
        sys_statements = []
        if action in (GO_ACTION, AVOID_ACTION):
            # Go is unusual because the outcome is not immediately satisfiable
            if not command.location:
                raise KeyError("No location in go reaction")
            destination = command.location.name

            # Negation is easy, so we take a shortcut
            if ((action == GO_ACTION and command.negation) or
                (action == AVOID_ACTION and not command.negation)):
                sys_statements.append(always(implies(next_(condition_frag),
                                                     not_(next_(sys_(destination))))))
                explanation += " avoid {!r}.".format(command.location.name)
            else:
                destination_stmt = sys_(destination)
                # New goal for where we should go
                go_goal = always_eventually(implies(reaction_prop, destination_stmt))
                # Safety that persists
                go_safety = \
                    always(iff(next_(reaction_prop),
                                 or_([reaction_prop, next_(condition_frag)])))
                # Make sure we act immediately: []((!react & next(react) )-> stay_there)
                stay_there = always(implies(and_((not_(reaction_prop), next_(reaction_prop))),
                                              self._frag_stay()))

                sys_statements.extend([go_goal, go_safety, stay_there])
                explanation += " go to {!r}.".format(command.location.name)
        elif action == STAY_ACTION:
            sys_statements.append(always(implies(condition_frag, reaction_prop)))
            explanation += " stay there."
        else:
            if command.theme.name not in self.props:
                raise KeyError("Unknown actuator {!r}".format(command.theme.name))
            # Otherwise we are always creating reaction safety
            sys_statements.append(always(iff(next_(condition_frag), next_(reaction_prop))))
            template = " {} {!r}." if not command.negation else " do not {} {!r}."
            explanation += template.format(action, command.theme.name)

            if not command.negation:
                handler = self.REACTIONS[action]
            else:
                handler = self.NEG_REACTIONS[action]
            reaction_frag = handler(command)
            react = always(implies(next_(reaction_prop), reaction_frag))
            stay_there = always(implies(and_((not_(reaction_prop), next_(reaction_prop))),
                                        self._frag_stay()))
            sys_statements.extend([react, stay_there])

        sys_chunk = SpecChunk(explanation, sys_statements, SpecChunk.SYS, command)
        return ([sys_chunk], [], new_props, [])
Beispiel #5
0
def _frag_complete_context(actuator, context_prop):
    """Generate fragments for completing an action in context."""
    actuator_done = _prop_actuator_done(actuator)
    eventually_actuator = always_eventually(env(actuator_done))
    return [and_((sys_(actuator), next_(env(actuator_done)), context_prop)), [eventually_actuator]]
Beispiel #6
0
    def _gen_conditional(self, command, assume_eventual_relief=False):
        """Generate a conditional action"""
        # TODO: Properly document and condition assume_eventual_relief

        env_chunks = []
        if isinstance(command.condition, Event):
            # Validate the condition
            if not command.condition.theme:
                raise KeyError("Cannot understand condition:\n{}".format(command.condition))
            condition = command.condition.theme.name
            if condition not in self.sensors:
                raise KeyError(
                    "No sensor to detect condition {!r}".format(command.condition.theme.name))
            if command.condition.sensor != SEE_ACTION:
                raise KeyError(
                    "Cannot use action {!r} as a condition".format(command.condition.action))
            condition_frag = env(condition)
            explanation = "To react to {!r},".format(condition)
            if assume_eventual_relief:
                relief_explanation = "Assume {!r} eventually goes away.".format(condition)
                relief = always_eventually(not_(condition_frag))
                relief_chunk = SpecChunk(relief_explanation, [relief], SpecChunk.ENV, command)
                env_chunks.append(relief_chunk)
        elif isinstance(command.condition, Assertion):
            # TODO: Add support for assertions not about "you". Ex: If there is a hostage...
            # Validate the condition
            if not command.condition.location:
                raise KeyError("Cannot understand condition:\n{}".format(command.condition))
            condition = command.condition.location.name
            condition_frag = sys_(condition)
            explanation = "When in {!r},".format(condition)
        else:
            raise KeyError("Cannot understand condition:\n{}".format(command.condition))

        # Validate the action
        action = command.action
        if action not in self.REACTIONS:
            raise KeyError("Unknown reaction {!r}".format(action))

        # Create the right type of reaction
        new_props = []
        if action in self.props:
            # Simple actuator
            reaction_prop = action
        else:
            # Reaction proposition
            reaction_prop_name = REACT + "_" + condition
            reaction_prop = sys_(reaction_prop_name)
            new_props.append(reaction_prop_name)
            self.react_props.add(reaction_prop_name)

        # Generate the response
        sys_statements = []
        if action in (GO_ACTION, AVOID_ACTION):
            # Go is unusual because the outcome is not immediately satisfiable
            if not command.location:
                raise KeyError("No location in go reaction")
            destination = command.location.name

            # Negation is easy, so we take a shortcut
            if ((action == GO_ACTION and command.negation) or
                    (action == AVOID_ACTION and not command.negation)):
                sys_statements.append(always(implies(next_(condition_frag),
                                                     not_(next_(sys_(destination))))))
                explanation += " avoid {!r}.".format(command.location.name)
            else:
                destination_stmt = sys_(destination)
                # New goal for where we should go
                go_goal = always_eventually(implies(reaction_prop, destination_stmt))
                # Safety that persists
                go_safety = \
                    always(iff(next_(reaction_prop),
                               or_([reaction_prop, next_(condition_frag)])))
                # Make sure we act immediately: []((!react & next(react) )-> stay_there)
                stay_there = always(implies(and_((not_(reaction_prop), next_(reaction_prop))),
                                            self._frag_stay()))

                sys_statements.extend([go_goal, go_safety, stay_there])
                explanation += " go to {!r}.".format(command.location.name)
        elif action == STAY_ACTION:
            sys_statements.append(always(iff(next_(condition_frag), next_(reaction_prop))))
            sys_statements.append(always(implies(or_([reaction_prop, next_(reaction_prop)]),
                                                 STAY_THERE)))
            explanation += " stay there."
        else:
            if command.theme.name not in self.props:
                raise KeyError("Unknown actuator {!r}".format(command.theme.name))
            # Otherwise we are always creating reaction safety
            sys_statements.append(always(iff(next_(condition_frag), next_(reaction_prop))))
            template = " {} {!r}." if not command.negation else " do not {} {!r}."
            explanation += template.format(action, command.theme.name)

            if not command.negation:
                handler = self.REACTIONS[action]
            else:
                handler = self.NEG_REACTIONS[action]
            reaction_frag = handler(command)
            react = always(implies(next_(reaction_prop), reaction_frag))
            stay_there = always(implies(or_([reaction_prop, next_(reaction_prop)]),
                                       self._frag_stay()))
            sys_statements.extend([react, stay_there])

        sys_chunk = SpecChunk(explanation, sys_statements, SpecChunk.SYS, command)
        return ([sys_chunk], env_chunks, new_props, [])