Esempio n. 1
0
def test_strips_analysis():
    problem = generate_strips_blocksworld_problem()
    assert is_strips_problem(problem)

    lang = problem.language
    clear, on, ontable, handempty, holding = lang.get('clear', 'on', 'ontable',
                                                      'handempty', 'holding')
    x = lang.variable('x', 'object')

    phi = clear(x) & ~ontable(x)
    assert not is_conjunction_of_positive_atoms(clear(x) & ~ontable(x))

    assert is_strips_effect_set([DelEffect(ontable(x)), DelEffect(clear(x))])
    assert is_strips_effect_set([DelEffect(ontable(x)), DelEffect(ontable(x))])
    # Not strips, as it has an effect with conditions:
    assert not is_strips_effect_set(
        [DelEffect(ontable(x), clear(x)),
         AddEffect(ontable(x))])
    # Not strips, as it has two contradictory effects:
    assert not is_strips_effect_set(
        [DelEffect(ontable(x)), AddEffect(ontable(x))])

    problem = generate_fstrips_counters_problem(ncounters=3)

    assert not is_strips_problem(problem)
    inc = problem.get_action('increment')
    assert not is_strips_effect_set(inc.effects)
Esempio n. 2
0
def test_effect_writing():
    problem, loc, clear, b1, table = get_bw_elements()
    block_var = problem.language.variable("b", "block")

    e1 = loc(b1) << table
    e2 = AddEffect(clear(b1))
    e3 = DelEffect(clear(b1))

    s1, s2, s3 = [print_effect(e) for e in [e1, e2, e3]]
    assert s1 == "(assign (loc b1) table)"
    assert s2 == "(clear b1)"
    assert s3 == "(not (clear b1))"
    assert print_effects([e1, e2, e3]) == "(and\n    {}\n    {}\n    {})".format(s1, s2, s3)

    e4 = UniversalEffect([block_var], [AddEffect(clear(block_var))])
    s4 = print_effect(e4)

    assert s4 == "(forall (?b - block) (clear ?b))"

    e5 = UniversalEffect([block_var], [AddEffect(clear(block_var)), loc(block_var) << table])
    s5 = print_effect(e5)

    assert s5 == "(forall (?b - block) (and\n    (clear ?b)\n    (assign (loc ?b) table)))"

    e6 = UniversalEffect([block_var], [FunctionalEffect(loc(block_var), table, condition=clear(block_var))])
    s6 = print_effect(e6)

    assert s6 == "(forall (?b - block) (when (clear ?b) (assign (loc ?b) table)))"
Esempio n. 3
0
def create_two_action_version(problem):
    lang = problem.language
    cell_t, at, reward, unblocked, picked, adjacent = lang.get("cell", "at", "reward", "unblocked", "picked", "adjacent")
    from_ = lang.variable("from", cell_t)
    to = lang.variable("to", cell_t)
    c = lang.variable("c", cell_t)
    problem.action(name='move', parameters=[from_, to],
                   precondition=land(adjacent(from_, to), at(from_), unblocked(to), flat=True),
                   effects=[DelEffect(at(from_)),
                            AddEffect(at(to))])

    x = lang.variable("x", cell_t)
    problem.action(name='pick-reward', parameters=[x],
                   precondition=at(x) & reward(x),
                   effects=[DelEffect(reward(x)),
                            AddEffect(picked(x))])
Esempio n. 4
0
def create_noop(problem):
    # A hackish no-op, to prevent the planner from detecting that the action is useless and pruning it
    lang = problem.language
    node_t, at = lang.get("node", "at")
    x = lang.variable("x", node_t)
    problem.action(name='noop',
                   parameters=[x],
                   precondition=at(x),
                   effects=[AddEffect(at(x))])
Esempio n. 5
0
def generate_fstrips_blocksworld_problem(nblocks=4,
                                         init="random",
                                         goal="random"):
    lang = generate_fstrips_bw_language(nblocks=nblocks)
    problem = create_fstrips_problem(lang,
                                     domain_name=BASE_DOMAIN_NAME,
                                     problem_name='test-instance')

    block, place, clear, loc, table = lang.get('block', 'place', 'clear',
                                               'loc', 'table')

    # Generate init pattern
    if init == 'random':
        clearplaces, locations = generate_random_bw_pattern(lang)
    else:
        if len(init) != nblocks:
            raise ValueError(
                f"Blocksworld configuration ({init}) does not match given number of blocks ({nblocks})"
            )
        locations = init
        clearplaces = compute_clear_from_pattern(lang, locations)

    for x, y in locations:
        problem.init.set(loc(lang.get(x)), lang.get(y))
    for x in clearplaces:
        problem.init.add(clear, lang.get(x))

    # Generate goal pattern
    if goal == 'random':
        clearplaces, locations = generate_random_bw_pattern(lang)
    else:
        if len(goal) != nblocks:
            raise ValueError(
                f"Blocksworld configuration ({goal}) does not match given number of blocks ({nblocks})"
            )
        locations = goal

    problem.goal = land(*(loc(lang.get(x)) == lang.get(y)
                          for x, y in locations),
                        flat=True)

    # Generate move action: move x to y
    x = lang.variable('x', block)
    y = lang.variable('y', place)

    problem.action('move', [x, y],
                   precondition=land(x != y,
                                     loc(x) != y, clear(x), clear(y)),
                   effects=[
                       loc(x) << y,
                       AddEffect(clear(loc(x))),
                       DelEffect(clear(y), condition=(y != table))
                   ])
    return problem
Esempio n. 6
0
def create_single_action_version(problem):
    lang = problem.language
    cell_t, at, reward, unblocked, picked, adjacent = lang.get("cell", "at", "reward", "unblocked", "picked", "adjacent")
    from_ = lang.variable("from", cell_t)
    to = lang.variable("to", cell_t)
    c = lang.variable("c", cell_t)
    problem.action(name='move', parameters=[from_, to],
                   precondition=land(adjacent(from_, to), at(from_), unblocked(to), exists(c, reward(c)), flat=True),
                   effects=[DelEffect(at(from_)),
                            AddEffect(at(to)),
                            # AddEffect(visited(to)),
                            DelEffect(reward(to))])
Esempio n. 7
0
def test_effect_writing():
    problem, loc, clear, b1, table = get_bw_elements()

    e1 = loc(b1) << table
    e2 = AddEffect(clear(b1))
    e3 = DelEffect(clear(b1))

    s1, s2, s3 = [print_effect(e) for e in [e1, e2, e3]]
    assert s1 == "(assign (loc b1) table)"
    assert s2 == "(clear b1)"
    assert s3 == "(not (clear b1))"
    assert print_effects([e1, e2,
                          e3]) == "(and\n    {}\n    {}\n    {})".format(
                              s1, s2, s3)
Esempio n. 8
0
def test_symbol_classification_with_nested_effect_heads():
    lang = generate_fstrips_bw_language(nblocks=3)
    problem = create_fstrips_problem(lang,
                                     domain_name='blocksworld',
                                     problem_name='test-instance')
    block, place, clear, loc, table = lang.get('block', 'place', 'clear',
                                               'loc', 'table')

    x = lang.variable('x', 'block')
    problem.action('dummy-action', [x],
                   precondition=loc(x) == table,
                   effects=[AddEffect(clear(loc(x)))])

    fluent, static = approximate_symbol_fluency(problem, include_builtin=True)
    assert loc in static and clear in fluent, "loc has not been detected as fluent even though it " \
                                              "appears (nested) in the head of an effect"
Esempio n. 9
0
def transform_universal_effects(lang, uni_eff) :
    """
    Elimates univeral effects by transforming to multiple conditional effects

    Arguments
    =========
    lang: object of type FirstOrderLanguage
    uni_effect: object of type UniversalEffect

    Returns
    =======
    list: list of instantiated effects
    """
    assert isinstance(uni_eff, UniversalEffect)
    effect_l = [] # new list of effects
    for effect in uni_eff.effects :
        # eliminate quantifiers from formula
        effect.condition = process_formula(effect.condition, lang)

        # if effect is Uni. Effect then transform to a list of Add/Del effects
        if isinstance(effect, UniversalEffect):
            effect_l += transform_universal_effects(lang, effect)
            continue

        # else if Add/Del effect, just instantiate condition and atom
        assert isinstance(effect, AddEffect) or isinstance(effect, DelEffect)

        card, syms, substs = _enumerate_instantiations(uni_eff.variables)
        if card == 0 :
            raise TransformationError("universal effect elimination",
                    uni_eff, "No constants were defined!")
        cond_effects    = []
        for values in itertools.product(*substs) :
            subst       = create_substitution(syms, values)
            cond_sub    = term_substitution(lang, effect.condition, subst)
            atom_sub    = term_substitution(lang, effect.atom, subst)
            if isinstance(effect, AddEffect) :
                ce = AddEffect(atom_sub, cond_sub)
            elif isinstance(effect, DelEffect) :
                ce = DelEffect(atom_sub, cond_sub)
            else :
                raise TransformationError("universal effect elimination",
                        uni_eff, "Effect type can't be handled!")
            cond_effects.append(ce)
        effect_l = effect_l + cond_effects
    return effect_l
Esempio n. 10
0
def test_neg_precondition_compilation_on_problem():
    problem = generate_strips_blocksworld_problem()
    lang = problem.language
    b1, clear, on, ontable, handempty, holding = lang.get('b1', 'clear', 'on', 'ontable', 'handempty', 'holding')
    x = lang.variable('x', 'object')

    compiled = compile_negated_preconditions_away(problem)

    # Check that nothing was changed
    for aname, a1 in problem.actions.items():
        a2 = compiled.get_action(aname)
        assert flatten(a1.precondition) == a2.precondition

    act1 = problem.action('act1', [x],
                          precondition=clear(x) & ~ontable(x) & handempty(),
                          effects=[DelEffect(ontable(x), ~clear(x)),
                                   AddEffect(ontable(x))])
    compiled = compile_negated_preconditions_away(problem)
    assert str(compiled.get_action('act1').precondition) == '(clear(x) and _not_ontable(x) and handempty())'
Esempio n. 11
0
def test_neg_precondition_compilation_on_action():
    problem = generate_strips_blocksworld_problem()
    lang = problem.language
    clear, on, ontable, handempty, holding = lang.get('clear', 'on', 'ontable', 'handempty', 'holding')
    x = lang.variable('x', 'object')

    negpreds = dict()
    
    pickup = problem.get_action('pick-up')
    pickupc = compile_action_negated_preconditions_away(pickup, negpreds)
    assert flatten(pickup.precondition) == pickupc.precondition and len(negpreds) == 0

    act1 = problem.action('act1', [x],
                          precondition=clear(x) & ~ontable(x) & handempty(),
                          effects=[DelEffect(ontable(x), ~clear(x)),
                                   AddEffect(ontable(x))])
    act1c = compile_action_negated_preconditions_away(act1, negpreds)
    assert len(negpreds) == 2  # For ontable and for clear
    assert str(act1c.precondition) == '(clear(x) and _not_ontable(x) and handempty())'
    assert str(act1c.effects[0].condition) == '_not_clear(x)'
Esempio n. 12
0
def generate_propositional_domain(nnodes, nedges, add_noop=False):
    lang = language(theories=[Theory.EQUALITY])
    problem = create_fstrips_problem(
        domain_name='graph-traversal-strips',
        problem_name="graph-traversal-{}x{}".format(nnodes, nedges),
        language=lang)

    node_t = lang.sort('node')
    at = lang.predicate('at', node_t)
    adjacent = lang.predicate('adjacent', node_t, node_t)

    # Create the actions
    from_, to = [lang.variable(name, node_t) for name in ("from", "to")]
    problem.action(name='move',
                   parameters=[from_, to],
                   precondition=adjacent(from_, to) & at(from_),
                   effects=[DelEffect(at(from_)),
                            AddEffect(at(to))])

    if add_noop:
        create_noop(problem)

    def node_name(i):
        return "n_{}".format(i)

    # Declare the constants:
    node_ids = list(range(0, nnodes))
    nodes = [lang.constant(node_name(i), node_t) for i in node_ids]

    # Declare the adjacencies:
    adjacencies = random.sample(list(itertools.permutations(nodes, 2)), nedges)
    for n1, n2 in adjacencies:
        problem.init.add(adjacent, n1, n2)

    source_node = nodes[0]
    target_node = nodes[-1]

    problem.init.add(at, source_node)
    problem.goal = at(target_node)

    return problem
Esempio n. 13
0
def test_complex_action_grounding():
    problem = generate_strips_blocksworld_problem(nblocks=1)
    lang = problem.language
    handempty, clear, b1 = lang.get('handempty', 'clear', 'b1')

    problem.actions = OrderedDict()
    problem.goal = ~handempty()  # Just to make the goal reachable

    x = lang.variable('x', 'object')

    ue = UniversalEffect([],
                         effects=[AddEffect(clear(x)),
                                  DelEffect(handempty())])
    action = problem.action('fake', [x],
                            precondition=handempty(),
                            effects=[ue])

    op = ground_schema_into_plain_operator_from_grounding(action, (b1, ))

    assert len(op.effects) == 1
    eff = op.effects[0]

    assert all(is_ground(sube.atom) for sube in eff.effects)
Esempio n. 14
0
def process_effects(eff, action, lang, task_id=[
    0,
]):
    """
    Elimates univeral effects by transforming to multiple conditional effects

    Arguments
    =========
    lang: object of type FirstOrderLanguage
    eff:  any effect type object
    task_id - Usage same as 'process_problem' method
    Returns
    =======
    list: list of effects
    """
    effect_l = []  # new list of effects
    if isinstance(eff, UniversalEffect) and (0 in task_id or 1 in task_id):
        for effect in eff.effects:
            effect.condition = process_formula(effect.condition, lang)

            # if Uni. Effect then transform to a list of Add/Del Effects
            if isinstance(effect, UniversalEffect):
                effect_l += process_effects(effect, action, lang)
                continue

            # else if Add/Del effect, just instantiate condition and atom
            assert isinstance(effect, AddEffect) or isinstance(
                effect, DelEffect)

            card, syms, substs = _enumerate_instantiations(eff.variables)
            if card == 0:
                raise TransformationError("universal effect elimination", eff,
                                          "No constants were defined!")
            cond_effects = []
            for values in itertools.product(*substs):
                subst = create_substitution(syms, values)
                cond_sub = process_formula(
                    term_substitution(lang, effect.condition, subst), lang)
                atom_sub = term_substitution(lang, effect.atom, subst)
                if isinstance(effect, AddEffect):
                    ce = AddEffect(atom_sub, cond_sub)
                elif isinstance(effect, DelEffect):
                    ce = DelEffect(atom_sub, cond_sub)
                else:
                    raise TransformationError("universal effect elimination",
                                              eff,
                                              "Effect type can't be handled!")
                cond_effects.append(ce)
            effect_l += cond_effects
    elif isinstance(
            eff, FunctionalEffect) and (eff.lhs.symbol.symbol
                                        == 'total-cost') and (0 in task_id
                                                              or 2 in task_id):
        action.cost = eff.rhs
    elif (isinstance(eff, AddEffect) or isinstance(eff, DelEffect)) and \
            (0 in task_id or 1 in task_id) :
        eff.condition = process_formula(eff.condition, lang)
        effect_l.append(eff)
    else:
        effect_l.append(eff)

    return effect_l