def test_logic_cmp(): l1 = And('a', Not('b')) l2 = And('a', Not('b')) assert hash(l1) == hash(l2) assert (l1 == l2) == T assert (l1 != l2) == F assert And('a', 'b', 'c') == And('b', 'a', 'c') assert And('a', 'b', 'c') == And('c', 'b', 'a') assert And('a', 'b', 'c') == And('c', 'a', 'b')
def test_logic_not(): assert Not(False) is True assert Not('a') != '~a' assert Not('~a') != 'a' # NOTE: we may want to change default Not behaviour and put this # functionality into some method. assert Not(And('a', 'b')) == Or(Not('a'), Not('b')) assert Not(Or('a', 'b')) == And(Not('a'), Not('b')) pytest.raises(ValueError, lambda: Not(ValueError))
def test_logic_expand(): t = And(Or('a', 'b'), 'c') assert t.expand() == Or(And('a', 'c'), And('b', 'c')) t = And(Or('a', Not('b')), 'b') assert t.expand() == And('a', 'b') t = And(Or('a', 'b'), Or('c', 'd')) assert t.expand() == \ Or(And('a', 'c'), And('a', 'd'), And('b', 'c'), And('b', 'd'))
def test_logic_fromstring(): s = Logic.fromstring assert s('a') == 'a' assert s('~a') == Not('a') assert s('a & b') == And('a', 'b') assert s('a | b') == Or('a', 'b') assert s('a | b & c') == And(Or('a', 'b'), 'c') assert s('a & b | c') == Or(And('a', 'b'), 'c') assert s('a & b & c') == And('a', 'b', 'c') assert s('a | b | c') == Or('a', 'b', 'c') pytest.raises(ValueError, lambda: s('| a')) pytest.raises(ValueError, lambda: s('& a')) pytest.raises(ValueError, lambda: s('a | | b')) pytest.raises(ValueError, lambda: s('a | & b')) pytest.raises(ValueError, lambda: s('a & & b')) pytest.raises(ValueError, lambda: s('a |')) pytest.raises(ValueError, lambda: s('a|b')) pytest.raises(ValueError, lambda: s('~')) pytest.raises(ValueError, lambda: s('~ a')) pytest.raises(ValueError, lambda: s('a b')) pytest.raises(ValueError, lambda: s(''))
def test_deduce_alpha_implications(): def D(i): I = deduce_alpha_implications(i) P = rules_2prereq({(k, True): {(v, True) for v in S} for k, S in I.items()}) return I, P # transitivity I, P = D([('a', 'b'), ('b', 'c')]) assert I == { 'a': {'b', 'c'}, 'b': {'c'}, Not('b'): {Not('a')}, Not('c'): {Not('a'), Not('b')} } assert P == {'a': {'b', 'c'}, 'b': {'a', 'c'}, 'c': {'a', 'b'}} # Duplicate entry I, P = D([('a', 'b'), ('b', 'c'), ('b', 'c')]) assert I == { 'a': {'b', 'c'}, 'b': {'c'}, Not('b'): {Not('a')}, Not('c'): {Not('a'), Not('b')} } assert P == {'a': {'b', 'c'}, 'b': {'a', 'c'}, 'c': {'a', 'b'}} # see if it is tolerant to cycles assert D([('a', 'a'), ('a', 'a')]) == ({}, {}) assert D([('a', 'b'), ('b', 'a')]) == ({ 'a': {'b'}, 'b': {'a'}, Not('a'): {Not('b')}, Not('b'): {Not('a')} }, { 'a': {'b'}, 'b': {'a'} }) # see if it catches inconsistency pytest.raises(ValueError, lambda: D([('a', Not('a'))])) pytest.raises(ValueError, lambda: D([('a', 'b'), ('b', Not('a'))])) pytest.raises( ValueError, lambda: D([('a', 'b'), ('b', 'c'), ('b', 'na'), ('na', Not('a'))])) # see if it handles implications with negations I, P = D([('a', Not('b')), ('c', 'b')]) assert I == { 'a': {Not('b'), Not('c')}, 'b': {Not('a')}, 'c': {'b', Not('a')}, Not('b'): {Not('c')} } assert P == {'a': {'b', 'c'}, 'b': {'a', 'c'}, 'c': {'a', 'b'}} I, P = D([(Not('a'), 'b'), ('a', 'c')]) assert I == { 'a': {'c'}, Not('a'): {'b'}, Not('b'): {'a', 'c'}, Not('c'): {Not('a'), 'b'} } assert P == {'a': {'b', 'c'}, 'b': {'a', 'c'}, 'c': {'a', 'b'}} # Long deductions I, P = D([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'e')]) assert I == { 'a': {'b', 'c', 'd', 'e'}, 'b': {'c', 'd', 'e'}, 'c': {'d', 'e'}, 'd': {'e'}, Not('b'): {Not('a')}, Not('c'): {Not('a'), Not('b')}, Not('d'): {Not('a'), Not('b'), Not('c')}, Not('e'): {Not('a'), Not('b'), Not('c'), Not('d')} } assert P == { 'a': {'b', 'c', 'd', 'e'}, 'b': {'a', 'c', 'd', 'e'}, 'c': {'a', 'b', 'd', 'e'}, 'd': {'a', 'b', 'c', 'e'}, 'e': {'a', 'b', 'c', 'd'} } # something related to real-world I, P = D([('rat', 'real'), ('int', 'rat')]) assert I == { 'int': {'rat', 'real'}, 'rat': {'real'}, Not('real'): {Not('rat'), Not('int')}, Not('rat'): {Not('int')} } assert P == { 'rat': {'int', 'real'}, 'real': {'int', 'rat'}, 'int': {'rat', 'real'} }
def test_apply_beta_to_alpha_route(): APPLY = apply_beta_to_alpha_route pytest.raises(TypeError, lambda: APPLY({}, [(Not('a'), 'b')])) # indicates empty alpha-chain with attached beta-rule #bidx def Q(bidx): return set(), [bidx] # x -> a &(a,b) -> x -- x -> a A = {'x': {'a'}} B = [(And('a', 'b'), 'x')] assert APPLY(A, B) == {'x': ({'a'}, []), 'a': Q(0), 'b': Q(0)} # x -> a &(a,~x) -> b -- x -> a A = {'x': {'a'}} B = [(And('a', Not('x')), 'b')] assert APPLY(A, B) == {'x': ({'a'}, []), Not('x'): Q(0), 'a': Q(0)} # x -> a b &(a,b) -> c -- x -> a b c A = {'x': {'a', 'b'}} B = [(And('a', 'b'), 'c')] assert APPLY(A, B) == \ {'x': ({'a', 'b', 'c'}, []), 'a': Q(0), 'b': Q(0)} # x -> a &(a,b) -> y -- x -> a [#0] A = {'x': {'a'}} B = [(And('a', 'b'), 'y')] assert APPLY(A, B) == {'x': ({'a'}, [0]), 'a': Q(0), 'b': Q(0)} # x -> a b c &(a,b) -> c -- x -> a b c A = {'x': {'a', 'b', 'c'}} B = [(And('a', 'b'), 'c')] assert APPLY(A, B) == \ {'x': ({'a', 'b', 'c'}, []), 'a': Q(0), 'b': Q(0)} # x -> a b &(a,b,c) -> y -- x -> a b [#0] A = {'x': {'a', 'b'}} B = [(And('a', 'b', 'c'), 'y')] assert APPLY(A, B) == \ {'x': ({'a', 'b'}, [0]), 'a': Q(0), 'b': Q(0), 'c': Q(0)} # x -> a b &(a,b) -> c -- x -> a b c d # c -> d c -> d A = {'x': {'a', 'b'}, 'c': {'d'}} B = [(And('a', 'b'), 'c')] assert APPLY(A, B) == { 'x': ({'a', 'b', 'c', 'd'}, []), 'c': ({'d'}, []), 'a': Q(0), 'b': Q(0) } # x -> a b &(a,b) -> c -- x -> a b c d e # c -> d &(c,d) -> e c -> d e A = {'x': {'a', 'b'}, 'c': {'d'}} B = [(And('a', 'b'), 'c'), (And('c', 'd'), 'e')] assert APPLY(A, B) == { 'x': ({'a', 'b', 'c', 'd', 'e'}, []), 'c': ({'d', 'e'}, []), 'a': Q(0), 'b': Q(0), 'd': Q(1) } # x -> a b &(a,y) -> z -- x -> a b y z # &(a,b) -> y A = {'x': {'a', 'b'}} B = [(And('a', 'y'), 'z'), (And('a', 'b'), 'y')] assert APPLY(A, B) == { 'x': ({'a', 'b', 'y', 'z'}, []), 'a': (set(), [0, 1]), 'y': Q(0), 'b': Q(1) } # x -> a b &(a,~b) -> c -- x -> a b A = {'x': {'a', 'b'}} B = [(And('a', Not('b')), 'c')] assert APPLY(A, B) == \ {'x': ({'a', 'b'}, []), 'a': Q(0), Not('b'): Q(0)} # ~x -> ~a ~b &(~a,b) -> c -- ~x -> ~a ~b A = {Not('x'): {Not('a'), Not('b')}} B = [(And(Not('a'), 'b'), 'c')] assert APPLY(A, B) == \ {Not('x'): ({Not('a'), Not('b')}, []), Not('a'): Q(0), 'b': Q(0)} # x -> a b &(b,c) -> ~a -- x -> a b A = {'x': {'a', 'b'}} B = [(And('b', 'c'), Not('a'))] assert APPLY(A, B) == {'x': ({'a', 'b'}, []), 'b': Q(0), 'c': Q(0)} # x -> a b &(a, b) -> c -- x -> a b c p # c -> p a A = {'x': {'a', 'b'}, 'c': {'p', 'a'}} B = [(And('a', 'b'), 'c')] assert APPLY(A, B) == { 'x': ({'a', 'b', 'c', 'p'}, []), 'c': ({'p', 'a'}, []), 'a': Q(0), 'b': Q(0) }
def test_logic_xnotx(): assert And('a', Not('a')) == F assert Or('a', Not('a')) == T