Ejemplo n.º 1
0
def test_ground_actions_for_small_gripper():
    problem = create_sample_problem()

    # First try with the variable-only grounding strategy
    varonly_grounding = LPGroundingStrategy(problem, ground_actions=False)
    varonly_variables = varonly_grounding.ground_state_variables()
    assert len(varonly_variables) == 20

    # Now try full LP grounding
    grounding = LPGroundingStrategy(problem)
    actions = grounding.ground_actions()

    assert len(actions['pick']) == len(
        actions['drop']) == 16  # 4 balls, two rooms, two grippers
    assert len(actions['move']) == 2  # 2 rooms

    lpvariables = grounding.ground_state_variables()
    assert len(lpvariables) == 20
    # Check both grounding methods produce same set of ground variables
    assert set(lpvariables) == set(varonly_variables)

    grounding = NaiveGroundingStrategy(problem)
    naive_variables = grounding.ground_state_variables()
    # The naive grounding strategy will result in many unreachable state variables such as 'carry(left,left)'
    assert len(set(naive_variables) - set(lpvariables)) == 124
Ejemplo n.º 2
0
def ground_generate_task(domain_file,
                         problem_file,
                         out_task=None,
                         verbose_flag=False,
                         lenient_flag=False):
    """
    Uses Tarski Grounder to generate the output task using pddl

    Arguments
    =========
    domain_file  : domain pddl file location
    problem_file : problem pddl file location
    output_task  : C++ container to store/process domain and problem

    Returns
    =======
    None
    """
    global VERBOSE
    VERBOSE = verbose_flag
    global LENIENT_MODE
    LENIENT_MODE = lenient_flag
    parsing_timer = time.process_time()
    #Setup a reader to read the domain and problem pddl files
    with time_taken("reading and parsing pddl file"):
        if LENIENT_MODE:
            problem = FstripsReader( raise_on_error=True,
                theories=None, strict_with_requirements=False).\
            read_problem( domain_file, problem_file)
        else:
            problem = FstripsReader( raise_on_error=True,
                theories=None).\
            read_problem( domain_file, problem_file)

    with time_taken("preprocessing tarski problem"):
        process_problem(problem)
        init = problem.init_bk

    with time_taken("grounding"):
        grounding = LPGroundingStrategy(problem)
        reachable_action_params = copy.deepcopy(grounding.ground_actions())
        fluents = copy.deepcopy(grounding.ground_state_variables())
        del grounding
        count_params = 0
        for x, y in reachable_action_params.items():
            for z in y:
                count_params += 1
        if VERBOSE:
            print("Total number of reachable action params = ", count_params)

    return True
Ejemplo n.º 3
0
 def ground(self,
            problem: 'unified_planning.model.Problem') -> GroundingResult:
     tarski_problem = unified_planning.interop.convert_problem_to_tarski(
         problem)
     actions = None
     try:
         lpgs = LPGroundingStrategy(tarski_problem)
         actions = lpgs.ground_actions()
     except tarski.grounding.errors.ReachabilityLPUnsolvable:
         raise unified_planning.exceptions.UPUsageError(
             'tarski grounder can not find a solvable grounding.')
     grounded_actions_map: Dict[Action, List[Tuple[FNode, ...]]] = {}
     fluents = {fluent.name: fluent for fluent in problem.fluents}
     objects = {object.name: object for object in problem.all_objects}
     types: Dict[str, Optional['unified_planning.model.Type']] = {}
     if not problem.has_type('object'):
         types[
             'object'] = None  # we set object as None, so when it is the father of a type in tarski, in UP it will be None.
     for action_name, list_of_tuple_of_parameters in actions.items():
         action = problem.action(action_name)
         parameters = {
             parameter.name: parameter
             for parameter in action.parameters
         }
         grounded_actions_map[action] = []
         for tuple_of_parameters in list_of_tuple_of_parameters:
             temp_list_of_converted_parameters = []
             for p in tuple_of_parameters:
                 if isinstance(p, str):
                     temp_list_of_converted_parameters.append(
                         problem.env.expression_manager.ObjectExp(
                             problem.object(p)))
                 else:
                     temp_list_of_converted_parameters.append(convert_tarski_formula(problem.env, fluents, \
                         objects, parameters, types, p))
             grounded_actions_map[action].append(
                 tuple(temp_list_of_converted_parameters))
     unified_planning_grounder = Grounder(
         problem, grounding_actions_map=grounded_actions_map)
     grounded_problem = unified_planning_grounder.get_rewritten_problem()
     trace_back_map = unified_planning_grounder.get_rewrite_back_map()
     return GroundingResult(
         grounded_problem, partial(lift_action_instance,
                                   map=trace_back_map), self.name, [])
Ejemplo n.º 4
0
class DomainTheory(object):
    def __init__(self):
        self.problem = None
        self.grounding = None
        self.action_index = OrderedDict()

    def load(self, domain_file, instance_file):
        reader = FstripsReader(raise_on_error=True)
        reader.parse_domain(domain_file)
        reader.parse_instance(instance_file)
        self.problem = reader.problem
        self.ground_problem()
        self.setup_index()

    def ground_problem(self):
        if self.problem is None:
            raise RuntimeError(
                'DomainTheory.ground_problem(): no problem has been set!')
        self.grounding = LPGroundingStrategy(self.problem)

    def setup_index(self):
        self.index = OrderedDict()
        actions = self.grounding.ground_actions()
        for name, bindings in actions.items():
            schema = self.problem.get_action(name)
            self.index[name] = OrderedDict()
            for b in bindings:
                op = ground_schema(schema, b)
                #print(name, b)
                self.index[name][b] = op

    def match_observations(self, events):
        """
        Matches input observation sequence to indexed ground actions
        :param events: sequence of observations (pairs of action schema name and list of objects)
        :return: list of tuples (schema, object tuple, ground action)
        """
        O = []
        for name, b in events:
            schema = self.problem.get_action(name)
            try:
                b_constants = tuple(
                    [self.problem.language.get(bi) for bi in b])
            except UndefinedElement as e:
                raise ObservationNotMatched(
                    "Constant not defined in binding. {}.  schema: {} objects: {}"
                    .format(str(e), name, b))
            schema_entry = self.index[name]
            try:
                op = schema_entry[tuple(b)]
                O += [(schema, b_constants, op)]
            except KeyError as e:
                raise ObservationNotMatched("schema: {} objects: {}".format(
                    name, b))
        return O
Ejemplo n.º 5
0
    def __init__(self, instance_file, domain_data, max_num_states):
        self.instance_file = instance_file
        self.domain_data = domain_data

        self.problem = parse_instance_file(domain_data.domain_file,
                                           instance_file)
        grounder = LPGroundingStrategy(self.problem)
        self.tarski_dynamic_atoms, self.tarski_static_atoms_textual, self.tarski_sorts_textual = grounder.ground_atoms(
        )
        self.tarski_goal_atoms = parse_conjunctive_formula(self.problem.goal)
        self.instance_info, self.tarski_atom_to_dlplan_atom = construct_instance_info(
            domain_data, self)
        self.search_model = GroundForwardSearchModel(
            self.problem,
            ground_problem_schemas_into_plain_operators(self.problem))
        self.states = [
            State(index, model.as_atoms(),
                  self.map_tarski_atoms_to_dlplan_state(model.as_atoms()))
            for index, model in enumerate(
                state_space_exploration(self.problem, self.search_model,
                                        max_num_states))
        ]
Ejemplo n.º 6
0
def test_ground_actions_for_small_gripper():
    problem = create_sample_problem()
    grounding = LPGroundingStrategy(problem)
    actions = grounding.ground_actions()
    assert len(actions['pick']) == len(
        actions['drop']) == 16  # 4 balls, two rooms, two grippers
    assert len(actions['move']) == 2  # 2 rooms

    as_list2 = lambda symbols: sorted(map(str, symbols))
    lpvariables = grounding.ground_state_variables()
    assert len(lpvariables) == 20

    grounding = NaiveGroundingStrategy(problem)
    naive_variables = grounding.ground_state_variables()
    # The naive grounding strategy will result in many unreachable state variables such as 'carry(left,left)'
    assert len(set(as_list2(naive_variables)) -
               set(as_list2(lpvariables))) == 124
Ejemplo n.º 7
0
def do_reachability_analysis(problem, reachability):
    # ATM This is not being used

    do_reachability = reachability != 'none'

    if do_reachability:
        ground_actions = reachability == 'full'
        msg = "Computing reachable groundings " + (
            "(actions+vars)" if ground_actions else "(vars only)")
        with resources.timing(msg, newline=True):
            grounding = LPGroundingStrategy(
                problem,
                ground_actions=ground_actions,
                include_variable_inequalities=False)
            ground_variables = grounding.ground_state_variables()
            if ground_actions:
                action_groundings = grounding.ground_actions()
                # Prune those action schemas that have no grounding at all
                for name, a in list(problem.actions.items()):
                    if not action_groundings[name]:
                        del problem.actions[name]
    else:
        with resources.timing(f"Computing naive groundings", newline=True):
            grounding = NaiveGroundingStrategy(problem,
                                               ignore_symbols={'total-cost'})
            ground_variables = grounding.ground_state_variables()
            action_groundings = grounding.ground_actions()

    statics, fluents = grounding.static_symbols, grounding.fluent_symbols
    simplifier = Simplify(problem, problem.init)
    operators = []
    for name, act in problem.actions.items():
        for grounding in action_groundings[name]:
            op = ground_schema_into_plain_operator_from_grounding(
                act, grounding)
            if reachability == 'full':
                operators.append(op)
            else:
                s = simplifier.simplify_action(op, inplace=True)
                if s is not None:
                    operators.append(s)
Ejemplo n.º 8
0
 def ground_problem(self):
     if self.problem is None:
         raise RuntimeError(
             'DomainTheory.ground_problem(): no problem has been set!')
     self.grounding = LPGroundingStrategy(self.problem)
Ejemplo n.º 9
0
def test_action_grounding_on_standard_benchmarks(instance_file, domain_file):
    lenient = any(d in domain_file for d in get_lenient_benchmarks())

    reader_ = reader(strict_with_requirements=not lenient,
                     case_insensitive=lenient)
    problem = reader_.read_problem(domain_file, instance_file)
    grounder = LPGroundingStrategy(problem)
    actions = grounder.ground_actions()

    expected = {  # A compilation of the expected values for each tested domain
        "BLOCKS": {
            'pick-up': 4,
            'put-down': 4,
            'stack': 16,
            'unstack': 16
        },
        "grid-visit-all": {
            'move': 528
        },
        'openstacks-sequencedstrips': {
            'setup-machine': 30,
            'make-product': 30,
            'start-order': 25,
            'ship-order': 25,
            'open-new-stack': 5
        },  # TODO Revise this figures
        # Parcprinter:
        'upp': {
            'initialize': 1,
            'EndCap-Move-Letter': 1,
            'HtmOverBlack-Move-Letter': 1,
            'ColorContainer-ToIME-Letter': 1,
            'ColorContainer-FromIME-Letter': 1,
            'ColorPrinter-Simplex-Letter': 0,
            'ColorPrinter-SimplexMono-Letter': 2,
            'ColorFeeder-Feed-Letter': 1,
            'BlackFeeder-Feed-Letter': 1,
            'Down-MoveTop-Letter': 1,
            'Down-MoveBottom-Letter': 1,
            'Down-MoveDown-Letter': 1,
            'HtmOverColor-Move-Letter': 1,
            'BlackContainer-ToIME-Letter': 1,
            'BlackContainer-FromIME-Letter': 1,
            'BlackPrinter-Simplex-Letter': 2,
            'BlackPrinter-SimplexAndInvert-Letter': 2,
            'Up-MoveTop-Letter': 1,
            'Up-MoveUp-Letter': 1,
            'Finisher1-PassThrough-Letter': 1,
            'Finisher1-Stack-Letter': 1,
            'Finisher2-PassThrough-Letter': 1,
            'Finisher2-Stack-Letter': 1
        },
        'floor-tile': {
            'change-color': 8,
            'paint-up': 36,
            'paint-down': 36,
            'up': 18,
            'down': 18,
            'right': 16,
            'left': 16
        },
        # This works for both versions of pipesworld:
        "pipesworld_strips": {
            'PUSH-START': 0,
            'PUSH-END': 0,
            'POP-START': 0,
            'POP-END': 0,
            'PUSH-UNITARYPIPE': 64,
            'POP-UNITARYPIPE': 64
        },
        'Pathways-Propositional': {
            'choose': 48,
            'initialize': 16,
            'associate': 7,
            'associate-with-catalyze': 5,
            'synthesize': 0,
            'DUMMY-ACTION-1': 1
        },
        'organic-synthesis': {
            'additionofrohacrossgemdisubstitutedalkene': 448,
            'additionofrohacrossmonosubstitutedalkene': 192,
            'additionofrohacrosstetrasubstitutedalkene': 72,
            'additionofrohacrosstrisubstitutedalkene': 120,
            'additionofrohacrossvicdisubstitutedalkene': 72,
            'etherformationbysulfonatedisplacement': 0,
            'hydroborationofdiortrisubstitutedalkene': 0,
            'hydroborationofgemdisubstitutedalkene': 0,
            'hydroborationofmonosubstitutedalkene': 0,
            'hydroborationoftetrasubstitutedalkene': 0,
            'oxidationofborane': 0,
            'sulfonylationofalcohol': 0
        },
        'genome-edit-distance': {
            'begin-cut': 9,
            'continue-cut': 9,
            'end-cut-1': 9,
            'end-cut-2': 9,
            'begin-transpose-splice': 9,
            'continue-splice-1': 9,
            'continue-splice-2': 9,
            'end-splice-1': 9,
            'end-splice-2': 9,
            'begin-transverse-splice': 9,
            'begin-inverse-splice': 9,
            'begin-inverse-splice-special-case': 3,
            'continue-inverse-splice-1A': 9,
            'continue-inverse-splice-1B': 9,
            'continue-inverse-splice-2': 9,
            'end-inverse-splice-1A': 9,
            'end-inverse-splice-1B': 9,
            'end-inverse-splice-2': 9,
            'invert-single-gene-A': 3,
            'invert-single-gene-B': 3,
            'reset-1': 3
        }
    }[problem.domain_name]

    # Make sure that the number of possible groundings of each action schema in the domain is as expected
    # (check at runtime with: {schema: len(groundings) for schema, groundings in actions.items()} )
    assert all(
        len(groundings) == expected[schema]
        for schema, groundings in actions.items())
Ejemplo n.º 10
0
                    format(st.sort.name))
        syms.append(st)
        instantiations.append(list(st.sort.domain()))
        cardinality *= len(instantiations[-1])
    return cardinality, syms, instantiations

if __name__ == "__main__" :
    reader = FstripsReader(raise_on_error=True, theories=None)
    ### Uncomment this for PARCPRINTER test
    """
    problem = reader.read_problem("parcprinter_p01-domain.pddl","parcprinter_p01.pddl")
    problem.init.function_extensions = dict()
    for _,action in problem.actions.items():
        new_effects = []
        for effect in action.effects:
            if not isinstance(effect, FunctionalEffect):
                new_effects.append(effect)
        action.effects = new_effects
    """
    ### Uncomment this for FLOORTILE TEST
    #problem = reader.read_problem("floortile_domain.pddl","floortile_p01-4-3-2.pddl")

    # Comment this
    problem = reader.read_problem("tidybot_domain.pddl","tidybot_p02.pddl")

    grounding = LPGroundingStrategy(problem)
    actions = grounding.ground_actions()
    actions = grounding.ground_state_variables()
    print(actions)
    print("Tests passed")