def assert_frame_axioms(self): ml = self.metalang tvar = _get_timestep_var(ml) # First deal with predicates; for p in get_symbols(self.lang, type_="all", include_builtin=False): if not self.symbol_is_fluent(p): continue self.comments[len(self.theory)] = f";; Frame axiom for symbol {p}:" lvars = generate_symbol_arguments(self.lang, p) atom = p(*lvars) fquant = generate_symbol_arguments(ml, p) + [tvar] if isinstance(p, Predicate): # pos: not p(x, t) and p(x, t+1) => \gamma_p^+(x, t) # neg: p(x, t) and not p(x, t+1) => \gamma_p^-(x, t) at_t = self.to_metalang(atom, tvar) at_t1 = self.to_metalang(atom, tvar + 1) pos = forall(*fquant, implies(~at_t & at_t1, self.gamma_pos[p.name])) neg = forall(*fquant, implies(at_t & ~at_t1, self.gamma_neg[p.name])) self.theory += [pos, neg] else: # fun: f(x, t) != f(x, t+1) => \gamma_f[y/f(x, t+1)] yvar = ml.variable("y", ml.get_sort(p.codomain.name)) at_t = self.to_metalang(atom, tvar) at_t1 = self.to_metalang(atom, tvar + 1) gamma_replaced = term_substitution(self.gamma_fun[p.name], {symref(yvar): at_t1}) fun = forall(*fquant, implies(at_t != at_t1, gamma_replaced)) self.theory += [fun]
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 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 test_simple_expression_substitutions(): lang = tarski.benchmarks.blocksworld.generate_strips_bw_language(nblocks=2) clear, b1, b2 = [lang.get(name) for name in ('clear', 'b1', 'b2')] x, y = lang.variable('x', 'object'), lang.variable('y', 'object') formula = clear(x) replaced = substitute_expression(formula, substitution={symref(x): b1}, inplace=False) replaced2 = substitute_expression(formula, substitution={symref(x): b2}, inplace=False) assert not formula.is_syntactically_equal(replaced) assert str(formula) == "clear(x)" and str(replaced) == "clear(b1)" and str( replaced2) == "clear(b2)" # Now let's do the same but inplace replaced = substitute_expression(formula, substitution={symref(x): b1}, inplace=True) assert formula.is_syntactically_equal(replaced) assert str(formula) == str(replaced) == "clear(b1)" formula = forall(x, clear(x) & clear(y)) replaced = substitute_expression(formula, substitution={ symref(x): b1, symref(y): b2 }, inplace=False) assert str(formula) == "forall x : ((clear(x) and clear(y)))" and \ str(replaced) == "forall b1 : ((clear(b1) and clear(b2)))"
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 test_formula_writing1(): problem, loc, clear, b1, table = get_bw_elements() lang = problem.language assert print_formula(clear(b1)) == "(clear b1)" assert print_formula(loc(b1) == table) == "(= (loc b1) table)" assert print_formula(loc(b1) != table) == "(not (= (loc b1) table))" assert print_formula(clear(b1) | clear(table)) == "(or (clear b1) (clear table))" b = lang.variable('B', lang.ns.block) assert print_formula(forall(b, clear(b))) == "(forall (?B - block) (clear ?B))" assert print_formula(exists(b, clear(b))) == "(exists (?B - block) (clear ?B))"
def test_node_collection(): lang = generate_bw_loc_and_clear(3) b1, b2, b3, clear, loc = lang.get('b1', 'b2', 'b3', 'clear', 'loc') e = clear(b1) & clear(b2) assert len(collect_unique_nodes(e)) == 5 # (clear(b1) and clear(b2)), clear(b2), b1, clear(b1), b2 assert len(collect_unique_nodes(e, lambda x: isinstance(x, Constant))) == 2 assert len(collect_unique_nodes(e, lambda x: isinstance(x, Atom))) == 2 assert len(collect_unique_nodes(e, lambda x: isinstance(x, Variable))) == 0 e = clear(b1) | (loc(b2) == b3) assert len(collect_unique_nodes(e)) == 7 v = Variable('x', lang.Object) e = forall(v, e | (loc(v) == v)) assert len(collect_unique_nodes(e)) == 12 assert len(collect_unique_nodes(e, lambda x: isinstance(x, Variable))) == 1
def assert_interference_axioms(self): ml = self.metalang tvar = _get_timestep_var(ml) for a1, a2 in itertools.combinations_with_replacement( self.problem.actions.values(), 2): a1_args = generate_action_arguments(ml, a1, char="x") a2_args = generate_action_arguments(ml, a2, char="y") a1_happens_at_t = ml.get_predicate(a1.name)(*a1_args, tvar) a2_happens_at_t = ml.get_predicate(a2.name)(*a2_args, tvar) allargs = a1_args + a2_args + [tvar] sentence = lor(~a1_happens_at_t, ~a2_happens_at_t) if a1.name == a2.name: x_neq_y = lor(*(x != y for x, y in zip(a1_args, a2_args)), flat=True) sentence = implies(x_neq_y, sentence) self.theory += [forall(*allargs, sentence)]