def create_small_bw_task(): lang = generate_small_fstrips_bw_language() init = tarski.model.create(lang) b1, b2, b3, b4, clear, loc, table = lang.get('b1', 'b2', 'b3', 'b4', 'clear', 'loc', 'table') block, place = lang.get('block', 'place') 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) src = lang.variable('src', block) dest = lang.variable('dest', place) x = lang.variable('x', block) y = lang.variable('y', block) clear_constraint = forall( x, equiv(neg(clear(x)), land(x != table, exists(y, loc(y) == x)))) G = land(loc(b1) == b2, loc(b2) == b3, loc(b3) == b4, loc(b4) == table) problem = fs.Problem("tower4", "blocksworld") problem.language = lang problem.init = init problem.goal = G problem.constraints += [clear_constraint] problem.action('move', [src, dest], land(clear(src), clear(dest)), [fs.FunctionalEffect(loc(src), dest)]) return problem
def create_actions(problem, add_fuel): lang = problem.language at, cell_t, empty, carrying, adjacent = lang.get("at", "cell", "empty", "carrying", "adjacent") t = lang.variable("t", 'truck') p = lang.variable("p", 'package') x = lang.variable("x", cell_t) f = lang.variable("from", cell_t) to = lang.variable("to", cell_t) problem.action(name='pick-package', parameters=[t, p, x], precondition=land(at(p, x), at(t, x), empty(t), flat=True), effects=[ fs.DelEffect(at(p, x)), fs.DelEffect(empty(t)), fs.AddEffect(carrying(t, p)), ]) problem.action(name='drop-package', parameters=[t, p, x], precondition=land(at(t, x), carrying(t, p), flat=True), effects=[ fs.AddEffect(empty(t)), fs.DelEffect(carrying(t, p)), fs.AddEffect(at(p, x)), ]) problem.action(name='move', parameters=[t, f, to], precondition=land(adjacent(f, to), at(t, f), flat=True), effects=[ fs.DelEffect(at(t, f)), fs.AddEffect(at(t, to)), ])
def test_variables_classification(): tw = tarskiworld.create_small_world() x = tw.variable('x', tw.Object) y = tw.variable('y', tw.Object) s = neg(land(tw.Cube(x), exists(y, land(tw.Tet(x), tw.LeftOf(x, y))))) free = free_variables(s) assert len(free) == 1 and symref(free[0]) == symref(x) assert len(all_variables(s)) == 2
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 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
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 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"
def test_literal_collection(): lang = generate_small_fstrips_bw_language(nblocks=5) clear, loc, b1, b2, b3 = lang.get('clear', 'loc', 'b1', 'b2', 'b3') x = lang.variable('x', lang.ns.block) assert rep.collect_literals_from_conjunction(clear(b1)) == {(clear(b1), True)} assert rep.collect_literals_from_conjunction(~clear(b1)) == {(clear(b1), False)} assert len(rep.collect_literals_from_conjunction(clear(b1) & ~clear(b2))) == 2 assert len( rep.collect_literals_from_conjunction( land(clear(b1), clear(b2), clear(b3)))) == 3 assert len( rep.collect_literals_from_conjunction(clear(x) & clear(b1) & clear(x))) == 2 # These ones are not conjunctions of literals, so should return None assert rep.collect_literals_from_conjunction(~(clear(b1) & clear(b2))) is None assert rep.collect_literals_from_conjunction((clear(b1) & clear(b2)) | clear(b3)) is None assert rep.collect_literals_from_conjunction(exists(x, clear(x))) is None # ATM we don't want to deal with the complexity of nested negation, so we expect the method to return None for # "not not clear(b2)" assert rep.collect_literals_from_conjunction(clear(b1) & ~~clear(b2)) is None
def test_formula_flattening(): lang = generate_bw_loc_and_clear(3) b1, b2, b3, clear = lang.get('b1', 'b2', 'b3', 'clear') f1 = land(clear(b1), clear(b2), clear(b3), clear(b1), flat=True) f2 = lor(clear(b1), clear(b2), clear(b3), clear(b1), flat=True) assert f1 == flatten(f1) # both are already flat - this tests for syntactic identity assert f2 == flatten(f2) # Now test formulas which are not flat, so flattening them will change their syntactic form f1 = land(clear(b1), clear(b2), clear(b3), clear(b1), flat=False) f2 = lor(clear(b1), f1, clear(b3), (clear(b3) | clear(b1)), flat=False) z = flatten(f1) assert f1 != z and len(z.subformulas) == 4 z = flatten(f2) assert f2 != z and len(z.subformulas) == 5 assert clear(b1) == flatten(clear(b1)) # Flattening non-compound formulas leaves them untouched
def get_conjunctions(self, fluent_list): if len(fluent_list) == 0: return top if len(fluent_list) <= 1: return self.add_predicates_to_the_prob(list(fluent_list)[0])(*) else: try: return land(*[self.add_predicates_to_the_prob(fl) for fl in fluent_list]) except AssertionError as exc: raise Exception("Message:",exc," Original fluent set", fluent_list)
def test_simplification_of_negation(): problem = tarski.benchmarks.blocksworld.generate_strips_blocksworld_problem( ) lang = problem.language b1, clear, on, ontable, handempty, holding = lang.get( 'b1', 'clear', 'on', 'ontable', 'handempty', 'holding') s = Simplify(problem, problem.init) cb1 = clear(b1) assert str(s.simplify_expression(land(cb1, neg(bot)))) == 'clear(b1)' assert str(s.simplify_expression(cb1)) == 'clear(b1)' # No evaluation made assert str(s.simplify_expression(neg( neg(cb1)))) == 'clear(b1)' # Double negation gets removed assert s.simplify_expression(land(neg(bot), neg(bot))) is True assert s.simplify_expression(lor(neg(top), neg(bot))) is True assert s.simplify_expression(lor(neg(top), neg(top))) is False act = problem.get_action('unstack') simp = s.simplify_action(act) assert simp
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))])
def get_conjunctions(self, fluent_list, flag): if len(fluent_list) == 0: if flag == POS_PREC: return top else: return [] elif len(fluent_list) <= 1: fluent = fluent_list[0] variables = fluent[1] var = [ self.variable_map[variable.replace('?', '')] for variable in variables ] if flag == POS_PREC: return self.predicate_map[fluent[0]](*var) elif flag == ADDS: return [fs.AddEffect(self.predicate_map[fluent[0]](*var))] elif flag == DELS: return [fs.DelEffect(self.predicate_map[fluent[0]](*var))] else: and_fluent_list = [] if flag == POS_PREC: for fluent in fluent_list: variables = fluent[1] var = [ self.variable_map[variable.replace('?', '')] for variable in variables ] and_fluent_list.append(self.predicate_map[fluent[0]](*var)) return land(*and_fluent_list) elif flag == ADDS: for fluent in fluent_list: variables = fluent[1] var = [ self.variable_map[variable.replace('?', '')] for variable in variables ] and_fluent_list.append( fs.AddEffect(self.predicate_map[fluent[0]](*var))) return and_fluent_list elif flag == DELS: for fluent in fluent_list: variables = fluent[1] var = [ self.variable_map[variable.replace('?', '')] for variable in variables ] and_fluent_list.append( fs.DelEffect(self.predicate_map[fluent[0]](*var))) return and_fluent_list
def get_goals(self, fluent_list): temp_model = model.create(self.fstrips_problem.language) if len(fluent_list) == 0: return top elif len(fluent_list) <= 1: temp_model.add(self.predicate_map[fluent_list[0][0]], *fluent_list[0][1]) return temp_model.as_atoms() else: try: for subgoal in fluent_list: temp_model.add(self.predicate_map[subgoal[0]], *subgoal[1]) return land(*temp_model.as_atoms()) except AssertionError as exc: raise Exception("Message:", exc, " Original fluent set", fluent_list)
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))])
def assert_action(self, op): """ For given operator op and timestep t, assert the SMT expression: op@t --> op.precondition@t op@t --> op.effects@(t+1) """ ml = self.metalang vart = _get_timestep_var(ml) apred = ml.get_predicate(op.name) vars_ = generate_action_arguments(ml, op) # Don't use the timestep arg substitution = { symref(param): arg for param, arg in zip(op.parameters, vars_) } args = vars_ + [vart] happens = apred(*args) prec = term_substitution(flatten(op.precondition), substitution) a_implies_prec = forall(*args, implies(happens, self.to_metalang(prec, vart))) self.theory.append(a_implies_prec) for eff in op.effects: eff = term_substitution(eff, substitution) antec = happens # Prepend the effect condition, if necessary: if not isinstance(eff.condition, Tautology): antec = land(antec, self.to_metalang(eff.condition, vart)) if isinstance(eff, fs.AddEffect): a_implies_eff = implies( antec, self.to_metalang(eff.atom, vart + 1, subt=vart)) elif isinstance(eff, fs.DelEffect): a_implies_eff = implies( antec, self.to_metalang(~eff.atom, vart + 1, subt=vart)) elif isinstance(eff, fs.FunctionalEffect): lhs = self.to_metalang(eff.lhs, vart + 1, subt=vart) rhs = self.to_metalang(eff.rhs, vart, subt=vart) a_implies_eff = implies(antec, lhs == rhs) else: raise TransformationError(f"Can't compile effect {eff}") self.theory.append(forall(*args, a_implies_eff))
def create_small_task(): upp = create_small_language() dummy_sheet = upp.constant('dummy-sheet', upp.sheet_t) sheet1 = upp.constant('sheet1', upp.sheet_t) M = tsk.model.create(upp) M.evaluator = evaluate M.add(upp.Uninitialized) M.add(upp.Location, dummy_sheet, upp.some_finisher_tray) M.add(upp.Prevsheet, sheet1, dummy_sheet) M.add(upp.Sheetsize, sheet1, upp.letter) M.add(upp.Location, sheet1, upp.some_feeder_tray) M.set(upp.total_cost(), 0) sheet = upp.variable('sheet', upp.sheet_t) prevsheet = upp.variable('prevsheet', upp.sheet_t) precondition = land( upp.Available(upp.finisher2_rsrc), upp.Prevsheet(sheet, prevsheet), upp.Location(prevsheet, upp.some_finisher_tray), upp.Sheetsize(sheet, upp.letter), upp.Location(sheet, upp.finisher2_entry_finisher1_exit)) effects = [ fs.DelEffect(upp.Available(upp.finisher2_rsrc)), fs.DelEffect(upp.Location(sheet, upp.finisher2_entry_finisher1_exit)), fs.AddEffect(upp.Location(sheet, upp.some_finisher_tray)), fs.AddEffect(upp.Stackedin(sheet, upp.finisher2_tray)), fs.AddEffect(upp.Available(upp.finisher2_rsrc)), fs.IncreaseEffect(upp.total_cost(), 8000) ] problem = fs.Problem() problem.name = "fun" problem.language = upp problem.init = M problem.goal = top problem.action('Finisher2-Stack-Letter', [sheet, prevsheet], precondition, effects) problem.metric = fs.OptimizationMetric(upp.total_cost(), fs.OptimizationType.MINIMIZE) 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_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): 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 compute_gamma(self, ml, symbol, idx): tvar = _get_timestep_var(ml) disjuncts = [] for act, eff in idx[symbol.name]: action_binding = generate_action_arguments(ml, act) action_happens_at_t = ml.get_predicate(act.name)(*action_binding, tvar) effcond = self.to_metalang(eff.condition, tvar) gamma_binding = self.compute_gamma_binding(ml, eff, symbol) gamma_act = land(action_happens_at_t, effcond, *gamma_binding, flat=True) if action_binding: # exist-quantify the action parameters other than the timestep t gamma_act = exists(*action_binding, gamma_act) # We chain a couple of simplifications of the original gamma expression gamma_act = Simplify().simplify_expression( simplify_existential_quantification(gamma_act)) disjuncts.append(gamma_act) return lor(*disjuncts, flat=True)
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 test_instance_creation(): L = tsk.language("mylang", theories=[Theory.EQUALITY, Theory.ARITHMETIC]) int_t = L.Integer obj_t = L.Object platform_t = L.sort('platform') rov1 = L.constant('rov1', platform_t) direction = L.function('direction', platform_t, int_t) sensor_sort = L.sort('sensor') camera, range, bearing = [L.constant(name, sensor_sort) for name in ('camera', 'range', 'bearing')] engaged = L.function('engaged', sensor_sort, int_t) region_t = L.sort('region') p0 = L.constant('p0', region_t) p1 = L.constant('p1', region_t) p2 = L.constant('p2', region_t) t0 = L.constant('t0', obj_t) t1 = L.constant('t1', obj_t) t2 = L.constant('t2', obj_t) #t0, t1, t2 = [L.constant('t{}'.format(i), obj_t) # for i in range(3)] position = L.predicate('position', obj_t, region_t) observed = L.predicate('observed', obj_t) estimated_range = L.predicate('estimated_range', obj_t) estimated_bearing = L.predicate('estimated_bearing', obj_t) req_1 = temporal.ResourceLock(**{ "ts": 0.0, "td": 10.0, "r": engaged(camera) }) req_2 = temporal.ResourceLock(**{ "ts": 0.0, "td": 10.0, "r": engaged(range) }) req_3 = temporal.ResourceLock(**{ "ts": 0.0, "td": 10.0, "r": engaged(bearing) }) req_4 = temporal.ResourceLevel(**{ "ts": 0.0, "td": 20.0, "r": direction(rov1), "n": L.constant(0, int_t) }) a1 = temporal.Action( name='localize_t0', parameters=[], precondition=position(rov1, p0), requirements=[ TimedEffect(0.0, req_2), TimedEffect(0.0, req_3)], timed_effects=[ TimedEffect(15.0, estimated_range(t0)), TimedEffect(20.0, estimated_bearing(t0))], untimed_effects=[] ) a2 = temporal.Action( name='observed_t0', parameters=[], precondition=land(position(rov1, p0), estimated_range(t0), estimated_bearing(t0)), requirements=[ TimedEffect(0.0, req_1), TimedEffect(0.0, req_2)], timed_effects=[ TimedEffect(21.0, observed(t0))], untimed_effects=[] ) initial = Model(L) initial.add(position, rov1, p0) initial.evaluator = evaluate inst = temporal.Instance( L=L, X=[position(rov1, p0), estimated_range(t0), estimated_bearing(t0), observed(t0), estimated_range(t1), estimated_bearing(t1), observed(t1), estimated_range(t2), estimated_bearing(t2), observed(t2)], I=initial, A=[a1, a2], G=observed(t0) ) assert len(inst.R) == 3
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_4blocks_task(): bw = generate_bw_loc_and_clear(4) M = tarski.model.create(bw) loc = bw.get_function('loc') clear = bw.get_predicate('clear') b1, b2, b3, b4 = [bw.get_constant('b{}'.format(k)) for k in range(1, 5)] table = bw.get_constant('table') hand = bw.get_constant('hand') M.setx(loc(b1), b2) # loc(b1) := b2 M.setx(loc(b2), b3) # loc(b2) := b3 M.setx(loc(b3), table) # loc(b3) := table M.setx(loc(b4), table) # loc(b4) := table M.setx(loc(table), table) M.setx(loc(hand), hand) M.add(clear, b1) # clear(b1) M.add(clear, b4) # clear(b4) M.add(clear, hand) # handempty G = land(loc(b1) == b2, loc(b2) == b3, loc(b3) == b4, loc(b4) == table) P = fs.Problem() P.name = "tower4" P.domain_name = "blocksworld" P.language = bw P.init = M P.goal = G # P.constraints += [clear_constraint] # @NOTE: These are the state variables associated with the constraint above P.state_variables = [ ] # [StateVariable(clear(dest), [tb]) for tb in [tb1, tb2, tb3, tb4, table]] b = bw.variable('b', bw.Object) P.action( 'pick_up', [b], land(clear(b), clear(hand), loc(b) == table, b != hand, b != table), [ fs.FunctionalEffect(loc(b), hand), fs.DelEffect(clear(b)), fs.DelEffect(clear(hand)) ]) P.action('put_down', [b], land(loc(b) == hand, b != table, b != hand), [ fs.FunctionalEffect(loc(b), table), fs.AddEffect(clear(b)), fs.AddEffect(clear(hand)) ]) src = bw.variable('src', bw.Object) dest = bw.variable('dest', bw.Object) P.action( 'stack', [src, dest], land( loc(src) == hand, clear(dest), src != dest, src != table, src != hand, dest != table, dest != hand), [ fs.FunctionalEffect(loc(src), dest), fs.DelEffect(clear(dest)), fs.AddEffect(clear(src)), fs.AddEffect(clear(hand)) ]) P.action( 'unstack', [src, dest], land(clear(hand), loc(src) == dest, clear(src), src != dest, src != table, src != hand, dest != table, dest != hand), [ fs.FunctionalEffect(loc(src), hand), fs.DelEffect(clear(src)), fs.AddEffect(clear(dest)), fs.DelEffect(clear(hand)) ]) return P
def test_syntax_shorthands(): assert lor(*[]) == Contradiction(), "a lor(·) of no disjuncts is False" assert land(*[]) == Tautology(), "a land(·) of no conjuncts is True" assert land( bot & top ) == bot & top, "A land(·) of a single element returns that single element"
def test_detect_free_variables(): tw = tarskiworld.create_small_world() x = tw.variable('x', tw.Object) y = tw.variable('y', tw.Object) s = neg(land(tw.Cube(x), exists(y, land(tw.Tet(x), tw.LeftOf(x, y))))) assert len(free_variables(s)) == 1
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