def generate_small_fstrips_bw_problem(): """ Generate a small Functional STRIPS BW problem with a few blocks, types, and one single action""" lang = generate_small_fstrips_bw_language(nblocks=4) problem = create_fstrips_problem(domain_name='blocksworld', problem_name='test-instance', language=lang) b1, b2, b3, b4, clear, loc, table = lang.get('b1', 'b2', 'b3', 'b4', 'clear', 'loc', 'table') problem.goal = (loc(b1) == b2) & (loc(b2) == b3) & (clear(b1)) to = lang.variable('to', 'place') b = lang.variable('b', 'block') problem.action("move", [b, to], precondition=land(b != to, loc(b) != to, clear(b), clear(to)), effects=[ loc(b) << to, fs.AddEffect(clear(loc(b))), fs.DelEffect(clear(loc(b)), condition=to != table) ]) init = tarski.model.create(lang) init.set(loc, b1, b2) # loc(b1) := b2 init.set(loc, b2, b3) # loc(b2) := b3 init.set(loc, b3, table) # loc(b3) := table init.set(loc, b4, table) # loc(b4) := table init.add(clear, b1) # clear(b1) init.add(clear, b4) # clear(b4) init.add(clear, table) # clear(table) problem.init = init return problem
def generate_small_fstrips_bw_problem(): lang = generate_small_fstrips_bw_language() problem = create_fstrips_problem(domain_name='blocksworld', problem_name='test-instance', language=lang) b1, b2, b3, clear, loc = lang.get('b1', 'b2', 'b3', 'clear', 'loc') problem.goal = (loc(b1) == b2) & (loc(b2) == b3) & (clear(b1)) return problem
def generate_problem(nblocks, run): lang = generate_atomic_bw_language(nblocks) problem = create_fstrips_problem(lang, domain_name="blocksworld-atomic", problem_name=f'instance-{nblocks}-{run}') clear, on, diff, table = lang.get('clear', 'on', 'diff', 'table') # Generate init pattern clearplaces, locations = generate_random_bw_pattern(lang) for x, y in locations: problem.init.add(on, lang.get(x), lang.get(y)) for x in clearplaces: problem.init.add(clear, lang.get(x)) # Add the quadratic number of (static) diff(b, c) atoms for x, y in itertools.permutations(lang.constants(), 2): problem.init.add(diff, x, y) # Generate goal pattern _, locations = generate_random_bw_pattern(lang) conjuncts = [] for x, y in locations: conjuncts.append(on(lang.get(x), lang.get(y))) problem.goal = land(*conjuncts, flat=True) b, x, y = [lang.variable(name, 'object') for name in ['b', 'x', 'y']] problem.action('move', [b, x, y], precondition=land(diff(b, table), diff(y, table), diff(b, y), clear(b), on(b, x), clear(y), flat=True), effects=[ fs.DelEffect(on(b, x)), fs.AddEffect(clear(x)), fs.DelEffect(clear(y)), fs.AddEffect(on(b, y)) ]) problem.action('move-to-table', [b, x], precondition=land(diff(b, table), diff(x, table), clear(b), on(b, x), flat=True), effects=[ fs.DelEffect(on(b, x)), fs.AddEffect(clear(x)), fs.AddEffect(on(b, table)) ]) return problem, [table]
def generate_small_strips_bw_problem(): """ Generate the standard BW encoding, untyped and with 4 action schemas """ lang = generate_small_strips_bw_language() problem = create_fstrips_problem(domain_name='blocksworld', problem_name='test', language=lang) b1, b2, b3, clear, on, ontable, handempty, holding = \ lang.get('b1', 'b2', 'b3', 'clear', 'on', 'ontable', 'handempty', 'holding') problem.goal = (on(b1, b2)) & (on(b2, b3)) & (clear(b1)) x = lang.variable('x', 'object') y = lang.variable('y', 'object') problem.action('pick-up', [x], precondition=clear(x) & ontable(x) & handempty(), effects=[ fs.DelEffect(ontable(x)), fs.DelEffect(clear(x)), fs.DelEffect(handempty()), fs.AddEffect(holding(x)) ]) problem.action('put-down', [x], precondition=holding(x), effects=[ fs.AddEffect(ontable(x)), fs.AddEffect(clear(x)), fs.AddEffect(handempty()), fs.DelEffect(holding(x)) ]) problem.action('unstack', [x, y], precondition=on(x, y) & clear(x) & handempty(), effects=[ fs.DelEffect(on(x, y)), fs.AddEffect(clear(y)), fs.DelEffect(clear(x)), fs.DelEffect(handempty()), fs.AddEffect(holding(x)) ]) problem.action('stack', [x, y], precondition=(x != y) & holding(x) & clear(y), effects=[ fs.AddEffect(on(x, y)), fs.DelEffect(clear(y)), fs.AddEffect(clear(x)), fs.AddEffect(handempty()), fs.DelEffect(holding(x)) ]) return problem
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"
def create_simple_problem(): lang = create_simple_untyped_language() problem = fs.create_fstrips_problem(lang, problem_name="simple", domain_name="simple") p, q, a = lang.get("p", "q", "a") init = tarski.model.create(lang) problem.init = init init.add(p, a) # p(a) init.add(q, a) # q(a) problem.goal = neg(p(a)) x = lang.variable("x", lang.Object) problem.action("negate", [x], precondition=p(a), effects=[fs.DelEffect(p(a))]) return problem
def test_symbol_collection(): 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-action1', [x], precondition=(loc(x) == table), effects=[loc(x) << table]) # dummy indeed :-) problem.goal = top assert clear not in collect_all_symbols( problem), "clear doesn't appear in any action or goal" problem.goal = clear(table) assert {loc, clear}.issubset(collect_all_symbols( problem)), "clear should now be collected: it appears in the goal"
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
def generate_small_gridworld(): lang = language(theories=[Theory.EQUALITY, Theory.ARITHMETIC]) problem = create_fstrips_problem(domain_name='grid-circles', problem_name='10x10', language=lang) coord_t = lang.interval('coordinate', lang.Integer, 1, 10) xpos = lang.function('X', coord_t) ypos = lang.function('Y', coord_t) problem.action(name='move-up', parameters=[], precondition=Tautology(), # effects=[fs.FunctionalEffect(ypos(), ypos() + 1)]) effects=[ypos() << ypos() + 1]) problem.init.setx(xpos(), 1) problem.init.setx(ypos(), 10) problem.goal = land(xpos() == 2, ypos() == 3) return problem
def generate_propositional_domain(gridsize): lang = language(theories=[Theory.EQUALITY]) problem = create_fstrips_problem(domain_name='gridworld-strips', problem_name="gridworld-{}x{}".format(gridsize, gridsize), language=lang) coord_t = lang.sort('coordinate') xpos = lang.function('xpos', coord_t) ypos = lang.function('ypos', coord_t) maxx = lang.function('maxpos', coord_t) goal_xpos = lang.function('goal_xpos', coord_t) goal_ypos = lang.function('goal_ypos', coord_t) succ = lang.predicate("succ", coord_t, coord_t) coordinates = ["c{}".format(i) for i in range(1, gridsize+1)] _ = [lang.constant(c, coord_t) for c in coordinates] # Create the "integer" objects x1 = lang.variable("x1", coord_t) # Create the actions problem.action(name='move_x', parameters=[x1], precondition=succ(xpos(), x1) | succ(x1, xpos()), effects=[xpos() << x1]) problem.action(name='move_y', parameters=[x1], precondition=succ(ypos(), x1) | succ(x1, ypos()), effects=[ypos() << x1]) last = coordinates[-1] problem.init.set(xpos, coordinates[0]) problem.init.set(ypos, coordinates[0]) problem.init.set(maxx, last) problem.init.set(goal_xpos, last) problem.init.set(goal_ypos, last) _ = [problem.init.add(succ, x, y) for x, y in zip(coordinates, coordinates[1:])] problem.goal = land(xpos() == goal_xpos(), ypos() == goal_ypos()) return problem
def generate_domain(gridsize): lang = language(theories=[Theory.EQUALITY, Theory.ARITHMETIC]) problem = create_fstrips_problem(domain_name='gridworld', problem_name="gridworld-{}x{}".format(gridsize, gridsize), language=lang) coord_t = lang.interval('coordinate', lang.Integer, lower_bound=1, upper_bound=gridsize) xpos = lang.function('xpos', coord_t) ypos = lang.function('ypos', coord_t) goal_xpos = lang.function('goal_xpos', coord_t) goal_ypos = lang.function('goal_ypos', coord_t) maxx = lang.function('maxpos', coord_t) # Create the actions problem.action(name='move-up', parameters=[], precondition=ypos() < maxx(), effects=[ypos() << ypos() + 1]) problem.action(name='move-right', parameters=[], precondition=xpos() < maxx(), effects=[xpos() << xpos() + 1]) problem.action(name='move-down', parameters=[], precondition=ypos() > coord_t.lower_bound, effects=[ypos() << ypos() - 1]) problem.action(name='move-left', parameters=[], precondition=xpos() > coord_t.lower_bound, effects=[xpos() << xpos() - 1]) problem.init.set(xpos, 1) problem.init.set(ypos, 1) problem.init.set(maxx, gridsize) problem.init.set(goal_xpos, gridsize) problem.init.set(goal_ypos, gridsize) problem.goal = land(xpos() == goal_xpos(), ypos() == goal_ypos()) return problem
def generate_propositional_domain(gridsize, num_rewards, num_blocked_cells, add_noop=False): lang = language(theories=[Theory.EQUALITY]) problem = create_fstrips_problem(domain_name='reward-strips', problem_name=f"reward-{gridsize}x{gridsize}", language=lang) cell_t = lang.sort('cell') at = lang.predicate('at', cell_t) reward = lang.predicate('reward', cell_t) unblocked = lang.predicate('unblocked', cell_t) picked = lang.predicate('picked', cell_t) adjacent = lang.predicate('adjacent', cell_t, cell_t) # visited = lang.predicate('visited', cell_t) # Create the actions # create_single_action_version(problem) create_two_action_version(problem) if add_noop: create_noop(problem) rng = range(0, gridsize) coordinates = list(itertools.product(rng, rng)) def cell_name(x, y): return "c_{}_{}".format(x, y) # Declare the constants: coord_objects = [lang.constant(cell_name(x, y), cell_t) for x, y in coordinates] # Declare the adjacencies: adjacent_coords = [(a, b, c, d) for (a, b), (c, d) in itertools.combinations(coordinates, 2) if abs(a-c) + abs(b-d) == 1] for a, b, c, d in adjacent_coords: problem.init.add(adjacent, cell_name(a, b), cell_name(c, d)) problem.init.add(adjacent, cell_name(c, d), cell_name(a, b)) # for (x0, y0), (x1, y1) in itertools.combinations(coordinates, 2): # if abs(x0-x1) + abs(y0-y1) == 1: # problem.init.add(adjacent, cell_name(x0, y0), cell_name(x1, y1)) # The initial position is already visited, by definition # problem.init.add(visited, initial_position) problem.init.add(at, cell_name(0, 0)) problem.init.add(unblocked, cell_name(0, 0)) # Set some random rewards and cell blocks: if num_rewards + num_blocked_cells > len(coordinates) - 1: raise RuntimeError("Number of rewards and blocks higher than total number of available cells!") cd = coordinates[1:] # Clone the list of coordinates excluding the initial position random.shuffle(cd) num_unblocked = len(cd) - num_blocked_cells for x, y in cd[0:num_unblocked]: problem.init.add(unblocked, cell_name(x, y)) cells_with_reward = list() for x, y in cd[0:num_rewards]: problem.init.add(reward, cell_name(x, y)) cells_with_reward.append(cell_name(x, y)) # Set the problem goal c = lang.variable("c", cell_t) # problem.goal = forall(c, ~reward(c)) # This one's good, and doesn't require a "picked" predicate, but cannot be parsed by Pyperplan: # problem.goal = land(*[~reward(c) for c in coord_objects], flat=True) problem.goal = land(*[picked(lang.get(c)) for c in cells_with_reward], flat=True) return problem
def generate_domain(gridsize, npackages, add_fuel=True): lang = language(theories=[Theory.EQUALITY, Theory.ARITHMETIC]) problem = create_fstrips_problem(domain_name='delivery', problem_name=f"delivery-{gridsize}x{gridsize}-{npackages}", language=lang) cell_t = lang.sort('cell') lang.sort('locatable') lang.sort('package', 'locatable') lang.sort('truck', 'locatable') at = lang.predicate('at', 'locatable', 'cell') lang.predicate('carrying', 'truck', 'package') empty = lang.predicate('empty', 'truck') adjacent = lang.predicate('adjacent', cell_t, cell_t) # Create the actions create_actions(problem, add_fuel) rng = range(0, gridsize) coordinates = list(itertools.product(rng, rng)) def cell_name(x, y): return f"c_{x}_{y}" truck = lang.constant('t1', 'truck') # Declare the constants: coord_objects = [lang.constant(cell_name(x, y), cell_t) for x, y in coordinates] package_objects = [lang.constant(f"p{i}", "package") for i in range(1, npackages+1)] # Declare the adjacencies: adjacent_coords = [(a, b, c, d) for (a, b), (c, d) in itertools.combinations(coordinates, 2) if abs(a-c) + abs(b-d) == 1] for a, b, c, d in adjacent_coords: problem.init.add(adjacent, cell_name(a, b), cell_name(c, d)) problem.init.add(adjacent, cell_name(c, d), cell_name(a, b)) cd = coord_objects[:] random.shuffle(cd) # Initial positions problem.init.add(at, truck, cd.pop()) for p in package_objects: problem.init.add(at, p, cd.pop()) problem.init.add(empty, truck) # Set the problem goal target = cd.pop() goal = [at(p, target) for p in package_objects] problem.goal = land(*goal, flat=True) if add_fuel: # Our approach is not yet too int-friendly :-( # fuel_level_t = lang.interval('fuel_level', lang.Integer, lower_bound=0, upper_bound=10) fuel_level_t = lang.sort('fuel_level') current_fuel = lang.function('current_fuel', fuel_level_t) loc_fuel = lang.function('loc_fuel', cell_t) max_fuel_level = lang.function('max_fuel_level', fuel_level_t) min_fuel_level = lang.function('min_fuel_level', fuel_level_t) # The whole succ-predicate stuff succ = lang.predicate("succ", fuel_level_t, fuel_level_t) levels = ["f{}".format(i) for i in range(0, 11)] _ = [lang.constant(c, fuel_level_t) for c in levels] # Create the "integer" objects _ = [problem.init.add(succ, x, y) for x, y in zip(levels, levels[1:])] problem.init.set(current_fuel, random.choice(levels)) problem.init.set(min_fuel_level, levels[0]) problem.init.set(max_fuel_level, levels[-1]) problem.init.set(loc_fuel, cd.pop()) return problem
def create_sample_problem(): lang = create_sample_language() init = tarski.model.create(lang) room, ball, at_robby, free, at, gripper, carry = lang.get( "room", "ball", "at-robby", "free", "at", "gripper", "carry") rooma, roomb, ball4, ball3, ball2, ball1, left, right = lang.get( 'rooma', 'roomb', 'ball4', 'ball3', 'ball2', 'ball1', 'left', 'right') init.add(room, rooma) init.add(room, roomb) init.add(ball, ball1) init.add(ball, ball2) init.add(ball, ball3) init.add(ball, ball4) init.add(gripper, left) init.add(gripper, right) init.add(at_robby, rooma) init.add(free, left) init.add(free, right) init.add(at, ball1, rooma) init.add(at, ball2, rooma) init.add(at, ball3, rooma) init.add(at, ball4, rooma) problem = fs.create_fstrips_problem(lang, problem_name="sample", domain_name="gripper-strips") problem.init = init problem.goal = land(at(ball1, roomb), at(ball2, roomb), at(ball3, roomb), at(ball4, roomb)) from_, to, o, r, g = [ lang.variable(x, lang.Object) for x in ["from", "to", "o", "r", "g"] ] problem.action( "move", [from_, to], precondition=land(from_ != to, room(from_), room(to), at_robby(from_), flat=True), effects=[fs.AddEffect(at_robby(to)), fs.DelEffect(at_robby(from_))]) problem.action("pick", [o, r, g], precondition=land(ball(o), room(r), gripper(g), at(o, r), at_robby(r), free(g), flat=True), effects=[ fs.AddEffect(carry(o, g)), fs.DelEffect(at(o, r)), fs.DelEffect(free(g)) ]) problem.action("drop", [o, r, g], precondition=land(ball(o), room(r), gripper(g), carry(o, g), at_robby(r), flat=True), effects=[ fs.DelEffect(carry(o, g)), fs.AddEffect(at(o, r)), fs.AddEffect(free(g)) ]) return problem
def generate_strips_3op_blocksworld_problem(nblocks): """ Generate the standard BW encoding, untyped and with 4 action schemas """ lang = generate_strips_3op_bw_language(nblocks=nblocks) problem = create_fstrips_problem(lang, domain_name=BASE_DOMAIN_NAME, problem_name=f'random-{nblocks}-blocks') clear, on, ontable = lang.get('clear', 'on', 'ontable') # Generate init pattern clearplaces, locations = generate_random_bw_pattern(lang) for x, y in locations: if y == 'table': problem.init.add(ontable, lang.get(x)) else: problem.init.add(on, lang.get(x), lang.get(y)) for x in clearplaces: if x != 'table': problem.init.add(clear, lang.get(x)) # Generate goal pattern _, locations = generate_random_bw_pattern(lang) conjuncts = [] for x, y in locations: if y == 'table': conjuncts.append(ontable(lang.get(x))) else: conjuncts.append(on(lang.get(x), lang.get(y))) problem.goal = land(*conjuncts, flat=True) b = lang.variable('b', 'object') f = lang.variable('from', 'object') t = lang.variable('to', 'object') problem.action('move-block-to-block', [b, f, t], precondition=land(clear(b), clear(t), on(b, f), flat=True), effects=[ fs.AddEffect(on(b, t)), fs.DelEffect(on(b, f)), fs.AddEffect(clear(f)), fs.DelEffect(clear(t)), ]) problem.action('move-block-to-table', [b, f], precondition=land(clear(b), on(b, f), flat=True), effects=[ fs.AddEffect(ontable(b)), fs.DelEffect(on(b, f)), fs.AddEffect(clear(f)), ]) problem.action('move-table-to-block', [b, t], precondition=land(clear(b), clear(t), ontable(b), flat=True), effects=[ fs.AddEffect(on(b, t)), fs.DelEffect(ontable(b)), fs.DelEffect(clear(t)), ]) return problem