def test_de_morgans_law(self): t = ''' ((not (and (a) (or (b) (not (c)))))) ''' actual = logical_expression.build(s_expression.parse(t)) actual = logical_expression.convert_to_nnf(actual) # !(a && (b || !c)) -> !a || !(b || c) -> !a || (!b && c) expected = node_type.LogicalOp( op = node_type.OP_OR, children = [ node_type.LogicalOp( op = node_type.OP_NOT, children = [ node_type.Atom(name='a') ]), node_type.LogicalOp( op = node_type.OP_AND, children = [ node_type.LogicalOp( op = node_type.OP_NOT, children = [node_type.Atom(name='b')]), node_type.Atom(name='c'), ]) ]) self.assertEqual(expected, actual)
def test_and_chain_is_flattened(self): t = ''' ((not (and (a) (and (b) (or (c) (d)) (and (e) (f)))))) ''' actual = logical_expression.build(s_expression.parse(t)) actual = logical_expression.flatten(actual) # (a && (b && (c && d))) -> a && b && c && d expected = node_type.LogicalOp( op = node_type.OP_NOT, children = [ node_type.LogicalOp( op = node_type.OP_AND, children = [ node_type.Atom(name='a'), node_type.Atom(name='b'), node_type.LogicalOp( op = node_type.OP_OR, children = [ node_type.Atom(name='c'), node_type.Atom(name='d'), ]), node_type.Atom(name='e'), node_type.Atom(name='f'), ]), ]) self.assertEqual(expected, actual)
def test_vars_are_bound_or_free_or_constants(self): t = ''' ((or (a ?method_var str_const1) (b ?method_var str_const2)) (c ?method_var ?out_var) (d ?out_var 123.0)) ''' actual = logical_expression.build(s_expression.parse(t)) actual = logical_expression.convert_to_dnf(actual) bound_variables = ['?method_var'] logical_expression.classify_variables(bound_variables=bound_variables, root_node=actual) # bound_variables argument isn't mutable self.assertEqual(['?method_var'], bound_variables) a_node = list(self.world_state_facts(actual, 'a'))[0] b_node = list(self.world_state_facts(actual, 'b'))[0] c_node = list(self.world_state_facts(actual, 'c'))[0] d_node = list(self.world_state_facts(actual, 'd'))[0] self.assertEqual(set(['?method_var']), set(a_node.bound_variables)) self.assertEqual(set(['str_const1']), set(a_node.constants)) self.assertEqual(set(['?method_var']), set(b_node.bound_variables)) self.assertEqual(set(['str_const2']), set(b_node.constants)) self.assertEqual(set(['?method_var']), set(c_node.bound_variables)) self.assertEqual(set(), set(c_node.constants)) self.assertEqual(set(['?out_var']), set(d_node.bound_variables)) self.assertEqual(set([123.0]), set(d_node.constants))
def test_conversion_with_call_term(self): t = ''' ((or (a) (b)) (call func ?x ?y)) ''' actual = logical_expression.build(s_expression.parse(t)) actual = logical_expression.convert_to_dnf(actual) expected = '(or (and a func) (and b func))' self.assertEqual(expected, self.tree_to_sexp(actual))
def test_literal_is_dnf(self): actual = logical_expression.build(s_expression.parse('((a))')) actual = logical_expression.convert_to_dnf(actual) expected = node_type.LogicalOp( op=node_type.OP_OR, children=[node_type.Atom(name='a')]) self.assertEqual(expected, actual) actual = logical_expression.build(s_expression.parse('((not (a)))')) actual = logical_expression.convert_to_dnf(actual) expected = node_type.LogicalOp( op=node_type.OP_OR, children=[node_type.LogicalOp( op=node_type.OP_NOT, children=[node_type.Atom(name='a')])]) self.assertEqual(expected, actual)
def test_neg_neg_is_pos(self): t = ''' ((not (not (a)))) ''' actual = logical_expression.build(s_expression.parse(t)) actual = logical_expression.convert_to_nnf(actual) expected = node_type.Atom(name='a') self.assertEqual(expected, actual)
def test_conversion_5(self): t = ''' ((t1) (or (not (t2)) (and (t2) (t3) (t4)))) ''' actual = logical_expression.build(s_expression.parse(t)) actual = logical_expression.convert_to_dnf(actual) expected = '(or (and t1 (not t2)) (and t1 t2 t3 t4))' self.assertEqual(expected, self.tree_to_sexp(actual))
def test_conversion_4(self): t = ''' ((or (not (call f1)))) ''' actual = logical_expression.build(s_expression.parse(t)) actual = logical_expression.convert_to_dnf(actual) expected = '(or (not f1))' self.assertEqual(expected, self.tree_to_sexp(actual))
def test_conversion_2(self): t = ''' ((a) (not (or (b) (c)))) ''' actual = logical_expression.build(s_expression.parse(t)) actual = logical_expression.convert_to_dnf(actual) expected = '(or (and a (not b) (not c)))' self.assertEqual(expected, self.tree_to_sexp(actual))
def test_conversion_1(self): t = ''' ((and (q1) (or (r1) (r2)) (q2) (or (r3) (r4)) (q3))) ''' actual = logical_expression.build(s_expression.parse(t)) actual = logical_expression.convert_to_dnf(actual) expected = '(or (and q1 r1 q2 r3 q3) (and q1 r1 q2 r4 q3) (and q1 r2 q2 r3 q3) (and q1 r2 q2 r4 q3))' self.assertEqual(expected, self.tree_to_sexp(actual))
def test_and_is_default_root(self): t = ''' ((a) (b)) ''' actual = logical_expression.build(s_expression.parse(t)) expected = node_type.LogicalOp( op = node_type.OP_AND, children = [ node_type.Atom(name='a'), node_type.Atom(name='b'), ]) self.assertEqual(expected, actual)
def test_simple(self): t = ''' ((or (a) (b) (c))) ''' actual = logical_expression.build(s_expression.parse(t)) expected = node_type.LogicalOp( op = node_type.OP_OR, children = [ node_type.Atom(name='a'), node_type.Atom(name='b'), node_type.Atom(name='c'), ]) self.assertEqual(expected, actual)
def test_no_conversion_is_required(self): t = ''' ((or (a) (b))) ''' actual = logical_expression.build(s_expression.parse(t)) actual = logical_expression.convert_to_nnf(actual) expected = node_type.LogicalOp( op = node_type.OP_OR, children = [ node_type.Atom(name='a'), node_type.Atom(name='b'), ]) self.assertEqual(expected, actual)
def build_branch(name, precondition_expr, tasklist_expr, method_node): branch = node_type.Branch() branch.name = lex_token.fixup_name(name) if match_child(precondition_expr, 0, s_expression.Symbol, lex_token.PERMUTE): permute_atom_expr = assert_child(precondition_expr, 1, s_expression.List) branch.permute_atom = build_permute_atom(permute_atom_expr) precondition_expr.children = precondition_expr.children[2:] precondition_node = logical_expression.build(precondition_expr) precondition_node = logical_expression.convert_to_dnf(precondition_node) logical_expression.classify_variables(method_node.variables, precondition_node) task_list_nodes = build_task_list(tasklist_expr) branch.children = [precondition_node] + task_list_nodes return branch
def test_empty_expression_is_dnf(self): actual = logical_expression.build(s_expression.parse('()')) actual = logical_expression.convert_to_dnf(actual) expected = node_type.LogicalOp(op=node_type.OP_OR) self.assertEqual(expected, actual)