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)
def test_cost_function_identification():
    problem = generate_fstrips_counters_problem(ncounters=3)
    functions = identify_cost_related_functions(problem)
    assert functions == set()

    problem = parse_benchmark_instance("agricola-opt18-strips:p01.pddl")
    functions = identify_cost_related_functions(problem)
    assert functions == {"group_worker_cost"}
Exemple #3
0
def test_counters():
    problem = generate_fstrips_counters_problem(ncounters=3)
    lang = problem.language
    value, c1 = lang.get('value', 'c1')

    # More than testing some particular property, here we want to test that the generator can run correctly
    assert is_and(problem.goal) and len(problem.goal.subformulas) == 2
    assert problem.init[value(c1)] == 0
Exemple #4
0
def test_cost_function_identification():
    problem = generate_fstrips_counters_problem(ncounters=3)
    functions = identify_cost_related_functions(problem)
    assert functions == set()

    instance_file, domain_file = collect_strips_benchmarks(["agricola-opt18-strips:p01.pddl"])[0]
    problem = reader().read_problem(domain_file, instance_file)
    functions = identify_cost_related_functions(problem)
    assert functions == {"group_worker_cost"}
Exemple #5
0
def test_on_counters():
    counters = generate_fstrips_counters_problem(ncounters=3)
    # Optimal plan is a length-3 sequence with 'increment(c2)', 'increment(c3)', 'increment(c3)'
    assert run_on_problem(counters, reachability="none", max_horizon=1, grounding='none') is None,\
        "Not solvable in 1 timestep"
    assert run_on_problem(counters, reachability="none", max_horizon=2, grounding='none') is None, \
        "Not solvable in 2 timesteps"

    plan = run_on_problem(counters, reachability="none", max_horizon=3, grounding='none')
    assert len(plan) == 3 and plan.count('(increment c3)') == 2 and plan.count('(increment c2)') == 1
Exemple #6
0
def test_sort_domain_retrieval():
    problem = generate_fstrips_counters_problem(ncounters=6)
    lang = problem.language

    assert len(list(lang.get("counter").domain())) == 6
    assert len(list(lang.get(
        "val").domain())) == 13, "Val must range from 0 to 12, both included"

    with pytest.raises(err.TarskiError):
        lang.Integer.domain()  # Domain too large to iterate over it
Exemple #7
0
def test_requirements_string():
    problem = parcprinter.create_small_task()

    # action costs should be required if there is a metric defined.
    assert sorted(get_requirements_string(problem)) == [':action-costs', ':equality', ':numeric-fluents', ':typing']

    problem, loc, clear, b1, table = get_bw_elements()
    assert sorted(get_requirements_string(problem)) == [':equality', ':typing']

    problem = generate_fstrips_counters_problem()
    assert sorted(get_requirements_string(problem)) == [':equality', ':numeric-fluents', ':typing']
Exemple #8
0
def test_simplifier():
    problem = generate_fstrips_counters_problem(ncounters=3)
    lang = problem.language
    value, max_int, counter, val_t, c1 = lang.get('value', 'max_int',
                                                  'counter', 'val', 'c1')
    x = lang.variable('x', counter)
    two, three, six = [lang.constant(c, val_t) for c in (2, 3, 6)]

    s = Simplify(problem, problem.init)
    assert symref(s.simplify_expression(x)) == symref(x)
    assert symref(s.simplify_expression(value(c1) < max_int())) == symref(
        value(c1) < six)  # max_int evaluates to 6
    assert s.simplify_expression(two < max_int()) is True
    assert s.simplify_expression(two > three) is False

    # conjunction evaluates to false because of first conjunct:
    falseconj = land(two > three, value(c1) < max_int())
    assert s.simplify_expression(falseconj) is False
    assert s.simplify_expression(neg(falseconj)) is True

    # first conjunct gets removed:
    assert str(s.simplify_expression(land(
        two < three,
        value(c1) < max_int()))) == '<(value(c1),6)'

    # first disjunct gets removed because it is false
    assert str(s.simplify_expression(lor(
        two > three,
        value(c1) < max_int()))) == '<(value(c1),6)'

    assert str(s.simplify_expression(forall(
        x,
        value(x) < max_int()))) == 'forall x : (<(value(x),6))'
    assert s.simplify_expression(forall(x, two + three <= 6)) is True

    inc = problem.get_action('increment')
    simp = s.simplify_action(inc)
    assert str(simp.precondition) == '<(value(c),6)'
    assert str(simp.effects) == str(inc.effects)

    eff = UniversalEffect(x, [value(x) << three])
    assert str(
        s.simplify_effect(eff)) == '(T -> forall (x) : ((T -> value(x) := 3)))'

    simp = s.simplify()
    assert str(simp.get_action('increment').precondition) == '<(value(c),6)'

    # Make sure there is no mention to the compiled away "max_int" symbol in the language
    assert not simp.language.has_function("max_int")

    # Make sure there is no mention to the compiled away "max_int" symbol in the initial state
    exts = list(simp.init.list_all_extensions().keys())
    assert ('max_int', 'val') not in exts
Exemple #9
0
def test_sort_id_assignment_on_lang_with_intervals():
    problem = generate_fstrips_counters_problem(ncounters=6)
    lang = problem.language

    sortmap = compute_direct_sort_map(lang)
    cards = {s.name: len(objs) for s, objs in sortmap.items()}
    assert cards == {
        'object': 0,
        'counter': 6
    }  # Make sure 'object' doesn't include integer constants
    bounds, ids = compute_sort_id_assignment(lang)

    assert bounds[lang.Object] == bounds[lang.get('counter')] == (0, 6)
Exemple #10
0
def test_requirements_string():
    problem = parcprinter.create_small_task()

    # action costs should be required if there is a metric defined, but if "total-cost" is the only arithmetic
    # function, we don't print the ':numeric-fluents' requirement
    assert sorted(get_requirements_string(problem)) == [
        ':action-costs', ':equality', ':typing'
    ]

    problem, loc, clear, b1, table = get_bw_elements()
    assert sorted(get_requirements_string(problem)) == [':equality', ':typing']

    problem = generate_fstrips_counters_problem()
    assert sorted(get_requirements_string(problem)) == [
        ':equality', ':numeric-fluents', ':typing'
    ]
Exemple #11
0
def test_simplification_of_ex_quantification():
    problem = generate_fstrips_counters_problem(ncounters=3)
    lang = problem.language
    value, max_int, counter, val_t, c1 = lang.get('value', 'max_int',
                                                  'counter', 'val', 'c1')
    x = lang.variable('x', counter)
    z = lang.variable('z', counter)
    two, three, six = [lang.constant(c, val_t) for c in (2, 3, 6)]

    phi = exists(z, land(x == z, top, value(z) < six))
    assert simplify_existential_quantification(phi, inplace=False) == land(top, value(x) < six), \
        "z has been replaced by x and removed from the quantification list, thus removing the quantifier"

    phi = exists(x, z, land(x == z, z == x, value(z) < six, flat=True))
    assert simplify_existential_quantification(phi, inplace=False) == exists(x, value(x) < six), \
        "The circular substitution dependency has been treated appropriately and only one substitution performed"
Exemple #12
0
def test_simplification_pruning():
    problem = generate_fstrips_counters_problem(ncounters=3)
    lang = problem.language
    value, max_int, counter, val_t, c1 = lang.get('value', 'max_int',
                                                  'counter', 'val', 'c1')
    three, six = [lang.constant(c, val_t) for c in (3, 6)]

    s = Simplify(problem, problem.init)

    a = problem.get_action('decrement')
    a.precondition = (three > six)
    # increment action must be pruned because its precondition is are statically inapplicable:
    assert len(s.simplify().actions) == 1

    a = problem.get_action('increment')
    a.effects[0].condition = (three > six)

    # increment action must be pruned because all its effects are statically inapplicable:
    assert len(s.simplify().actions) == 0