def test_functional_effect_invalid_creation(): import tarski.fstrips.errors as err lang = fs.language() t1 = lang.constant('x', 'object') t2 = lang.constant('y', 'object') with pytest.raises(err.InvalidEffectError): _ = t1 << t2 # i.e. x := y
def test_increase_effect_valid_creation(): lang = fs.language('lang') lang.total_cost = lang.function('total-cost', lang.Real) eff = fs.IncreaseEffect(lang.total_cost(), 5) assert isinstance(eff, fs.IncreaseEffect) assert eff.rhs == 5
def test_term_hash_raises_exception(): # from tarski.fstrips import language # from tarski.syntax import symref lang = fs.language("test") counter = defaultdict(int) c = lang.constant('c', 'object') f = lang.function('f', 'object', 'object') # Trying to use associative containers on terms raises a standard TypeError with pytest.raises(TypeError): counter[c] += 2 with pytest.raises(TypeError): counter[f(c)] += 2 # Using symrefs instead works correctly: counter[symref(c)] += 2 assert counter[symref(c)] == 2 counter[symref(f(c))] += 2 assert counter[symref(f(c))] == 2 # Atoms and in general formulas can be used without problem atom = f(c) == c counter[atom] += 2 assert counter[atom] == 2
def test_increase_effect_valid_creation(): lang = fs.language('lang', theories=[Theory.EQUALITY, Theory.ARITHMETIC]) lang.total_cost = lang.function('total-cost', lang.Real) eff = fs.IncreaseEffect(lang.total_cost(), 5) assert isinstance(eff, fs.IncreaseEffect) assert eff.rhs == 5
def test_functional_effect_valid_creation(): lang = fs.language() t1 = lang.constant('x', lang.Object) t2 = lang.constant('y', lang.Object) f = lang.function('foo', lang.Object, lang.Object) eff = f(t1) << t2 assert isinstance(eff, fs.FunctionalEffect)
def __init__(self, model): self.model_dict = model self.fluent_set_map = {} self.create_all_predicates() # functions self.fstrips_problem = create_fstrips_problem(language(),"test_domain", "instance1") self.count = 1 self.populate_fstrips_object()
def __init__(self, model): self.model_dict = model self.predicate_map = {} self.functions = {} self.variable_map = {} self.fstrips_problem = create_fstrips_problem(language(), "instance1", "test_domain") sorts.attach_arithmetic_sorts(self.fstrips_problem.language) # self.fstrips_problem.metric_ = ("minimize","(total-cost)") self.populate_fstrips_problem()
def test_numeric_builtin_addition_int(): lang = language(theories=[Theory.EQUALITY, Theory.ARITHMETIC]) # The sorts particle = lang.sort('bowl') eggs = lang.function('eggs', lang.Object, lang.Integer) bowl_1 = lang.constant('bowl_1', particle) model = tarski.model.create(lang) model.evaluator = evaluate model.set(eggs(bowl_1), 1) expr = model[eggs(bowl_1) + 1] assert isinstance(expr, Constant) assert isinstance(expr.symbol, int) assert expr.symbol == 2
def create_sample_language(): # The standard, untyped version of gripper lang = fs.language("gripper") object_t = lang.get_sort('object') [ lang.predicate(p, object_t) for p in ["room", "ball", "gripper", "at-robby", "free"] ] [lang.predicate(p, object_t, object_t) for p in ["at", "carry"]] [ lang.constant(name, object_t) for name in [ 'rooma', 'roomb', 'ball4', 'ball3', 'ball2', 'ball1', 'left', 'right' ] ] return lang
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 create_simple_untyped_language(): lang = fs.language("simple") lang.predicate("p", lang.Object) lang.predicate("q", lang.Object) lang.constant("a", lang.Object) return lang
#!/usr/bin/env python3 import sys from tarski import fstrips sys.path.append('../src') from src import tarski as tsk if __name__ == "__main__": # First we create the necessary elements of the FOL language fol = fstrips.language( ) # i.e. create a (first-order) "language" object, which will act as facade to all things FOL block = fol.sort('block') place = fol.sort('place') loc = fol.function('loc', 'place') clear = fol.predicate('clear', 'place') b1 = fol.const('b1', block) b2 = fol.const('b2', block) b3 = fol.const('b3', block) table = fol.const('table', place) # Now we create the different elements of the planning problem, which mostly build # on the first-order language we have created above # The goal goal = (loc(b1) == b2) & (loc(b2) == table)
def test_metric_writing(): lang = fs.language('lang', theories=[Theory.ARITHMETIC]) cost = lang.function('total-cost', lang.Real) metric = fs.OptimizationMetric(cost(), fs.OptimizationType.MINIMIZE) metric_string = print_metric(metric) assert metric_string == '(:metric minimize (total-cost ))'
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