def test_count_ops_visual(): ADD, MUL, POW, SIN, COS, EXP, AND, D, G, M = symbols( 'Add Mul Pow sin cos exp And Derivative Integral Sum'.upper()) DIV, SUB, NEG = symbols('DIV SUB NEG') LT, LE, GT, GE, EQ, NE = symbols('LT LE GT GE EQ NE') NOT, OR, AND, XOR, IMPLIES, EQUIVALENT, _ITE, BASIC, TUPLE = symbols( 'Not Or And Xor Implies Equivalent ITE Basic Tuple'.upper()) def count(val): return count_ops(val, visual=True) assert count(7) is S.Zero assert count(S(7)) is S.Zero assert count(-1) == NEG assert count(-2) == NEG assert count(S(2) / 3) == DIV assert count(Rational(2, 3)) == DIV assert count(pi / 3) == DIV assert count(-pi / 3) == DIV + NEG assert count(I - 1) == SUB assert count(1 - I) == SUB assert count(1 - 2 * I) == SUB + MUL assert count(x) is S.Zero assert count(-x) == NEG assert count(-2 * x / 3) == NEG + DIV + MUL assert count(Rational(-2, 3) * x) == NEG + DIV + MUL assert count(1 / x) == DIV assert count(1 / (x * y)) == DIV + MUL assert count(-1 / x) == NEG + DIV assert count(-2 / x) == NEG + DIV assert count(x / y) == DIV assert count(-x / y) == NEG + DIV assert count(x**2) == POW assert count(-x**2) == POW + NEG assert count(-2 * x**2) == POW + MUL + NEG assert count(x + pi / 3) == ADD + DIV assert count(x + S.One / 3) == ADD + DIV assert count(x + Rational(1, 3)) == ADD + DIV assert count(x + y) == ADD assert count(x - y) == SUB assert count(y - x) == SUB assert count(-1 / (x - y)) == DIV + NEG + SUB assert count(-1 / (y - x)) == DIV + NEG + SUB assert count(1 + x**y) == ADD + POW assert count(1 + x + y) == 2 * ADD assert count(1 + x + y + z) == 3 * ADD assert count(1 + x**y + 2 * x * y + y**2) == 3 * ADD + 2 * POW + 2 * MUL assert count(2 * z + y + x + 1) == 3 * ADD + MUL assert count(2 * z + y**17 + x + 1) == 3 * ADD + MUL + POW assert count(2 * z + y**17 + x + sin(x)) == 3 * ADD + POW + MUL + SIN assert count(2 * z + y**17 + x + sin(x**2)) == 3 * ADD + MUL + 2 * POW + SIN assert count(2 * z + y**17 + x + sin(x**2) + exp(cos(x))) == 4 * ADD + MUL + 2 * POW + EXP + COS + SIN assert count(Derivative(x, x)) == D assert count(Integral(x, x) + 2 * x / (1 + x)) == G + DIV + MUL + 2 * ADD assert count(Sum(x, (x, 1, x + 1)) + 2 * x / (1 + x)) == M + DIV + MUL + 3 * ADD assert count(Basic()) is S.Zero assert count({x + 1: sin(x)}) == ADD + SIN assert count([x + 1, sin(x) + y, None]) == ADD + SIN + ADD assert count({x + 1: sin(x), y: cos(x) + 1}) == SIN + COS + 2 * ADD assert count({}) is S.Zero assert count([x + 1, sin(x) * y, None]) == SIN + ADD + MUL assert count([]) is S.Zero assert count(Basic()) == 0 assert count(Basic(Basic(), Basic(x, x + y))) == ADD + 2 * BASIC assert count(Basic(x, x + y)) == ADD + BASIC assert [count(Rel(x, y, op)) for op in '< <= > >= == <> !='.split() ] == [LT, LE, GT, GE, EQ, NE, NE] assert count(Or(x, y)) == OR assert count(And(x, y)) == AND assert count(Or(x, Or(y, And(z, a)))) == AND + OR assert count(Nor(x, y)) == NOT + OR assert count(Nand(x, y)) == NOT + AND assert count(Xor(x, y)) == XOR assert count(Implies(x, y)) == IMPLIES assert count(Equivalent(x, y)) == EQUIVALENT assert count(ITE(x, y, z)) == _ITE assert count([Or(x, y), And(x, y), Basic(x + y)]) == ADD + AND + BASIC + OR assert count(Basic(Tuple(x))) == BASIC + TUPLE #It checks that TUPLE is counted as an operation. assert count(Eq(x + y, S(2))) == ADD + EQ
def test_simplification(): """ Test working of simplification methods. """ set1 = [[0, 0, 1], [0, 1, 1], [1, 0, 0], [1, 1, 0]] set2 = [[0, 0, 0], [0, 1, 0], [1, 0, 1], [1, 1, 1]] assert SOPform([x, y, z], set1) == Or(And(Not(x), z), And(Not(z), x)) assert Not(SOPform([x, y, z], set2)) == \ Not(Or(And(Not(x), Not(z)), And(x, z))) assert POSform([x, y, z], set1 + set2) is true assert SOPform([x, y, z], set1 + set2) is true assert SOPform([Dummy(), Dummy(), Dummy()], set1 + set2) is true minterms = [[0, 0, 0, 1], [0, 0, 1, 1], [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 1, 1]] dontcares = [[0, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 1]] assert (SOPform([w, x, y, z], minterms, dontcares) == Or(And(Not(w), z), And(y, z))) assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z) minterms = [1, 3, 7, 11, 15] dontcares = [0, 2, 5] assert (SOPform([w, x, y, z], minterms, dontcares) == Or(And(Not(w), z), And(y, z))) assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z) minterms = [1, [0, 0, 1, 1], 7, [1, 0, 1, 1], [1, 1, 1, 1]] dontcares = [0, [0, 0, 1, 0], 5] assert (SOPform([w, x, y, z], minterms, dontcares) == Or(And(Not(w), z), And(y, z))) assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z) minterms = [1, {y: 1, z: 1}] dontcares = [0, [0, 0, 1, 0], 5] assert (SOPform([w, x, y, z], minterms, dontcares) == Or(And(Not(w), z), And(y, z))) assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z) minterms = [{y: 1, z: 1}, 1] dontcares = [[0, 0, 0, 0]] minterms = [[0, 0, 0]] raises(ValueError, lambda: SOPform([w, x, y, z], minterms)) raises(ValueError, lambda: POSform([w, x, y, z], minterms)) raises(TypeError, lambda: POSform([w, x, y, z], ["abcdefg"])) # test simplification ans = And(A, Or(B, C)) assert simplify_logic(A & (B | C)) == ans assert simplify_logic((A & B) | (A & C)) == ans assert simplify_logic(Implies(A, B)) == Or(Not(A), B) assert simplify_logic(Equivalent(A, B)) == \ Or(And(A, B), And(Not(A), Not(B))) assert simplify_logic(And(Equality(A, 2), C)) == And(Equality(A, 2), C) assert simplify_logic(And(Equality(A, 2), A)) is S.false assert simplify_logic(And(Equality(A, 2), A)) == And(Equality(A, 2), A) assert simplify_logic(And(Equality(A, B), C)) == And(Equality(A, B), C) assert simplify_logic(Or(And(Equality(A, 3), B), And(Equality(A, 3), C))) \ == And(Equality(A, 3), Or(B, C)) b = (~x & ~y & ~z) | (~x & ~y & z) e = And(A, b) assert simplify_logic(e) == A & ~x & ~y raises(ValueError, lambda: simplify_logic(A & (B | C), form='blabla')) # Check that expressions with nine variables or more are not simplified # (without the force-flag) a, b, c, d, e, f, g, h, j = symbols('a b c d e f g h j') expr = a & b & c & d & e & f & g & h & j | \ a & b & c & d & e & f & g & h & ~j # This expression can be simplified to get rid of the j variables assert simplify_logic(expr) == expr # check input ans = SOPform([x, y], [[1, 0]]) assert SOPform([x, y], [[1, 0]]) == ans assert POSform([x, y], [[1, 0]]) == ans raises(ValueError, lambda: SOPform([x], [[1]], [[1]])) assert SOPform([x], [[1]], [[0]]) is true assert SOPform([x], [[0]], [[1]]) is true assert SOPform([x], [], []) is false raises(ValueError, lambda: POSform([x], [[1]], [[1]])) assert POSform([x], [[1]], [[0]]) is true assert POSform([x], [[0]], [[1]]) is true assert POSform([x], [], []) is false # check working of simplify assert simplify((A & B) | (A & C)) == And(A, Or(B, C)) assert simplify(And(x, Not(x))) == False assert simplify(Or(x, Not(x))) == True assert simplify(And(Eq(x, 0), Eq(x, y))) == And(Eq(x, 0), Eq(y, 0)) assert And(Eq(x - 1, 0), Eq(x, y)).simplify() == And(Eq(x, 1), Eq(y, 1)) assert And(Ne(x - 1, 0), Ne(x, y)).simplify() == And(Ne(x, 1), Ne(x, y)) assert And(Eq(x - 1, 0), Ne(x, y)).simplify() == And(Eq(x, 1), Ne(y, 1)) assert And(Eq(x - 1, 0), Eq(x, z + y), Eq(y + x, 0)).simplify() == And(Eq(x, 1), Eq(y, -1), Eq(z, 2)) assert And(Eq(x - 1, 0), Eq(x + 2, 3)).simplify() == Eq(x, 1) assert And(Ne(x - 1, 0), Ne(x + 2, 3)).simplify() == Ne(x, 1) assert And(Eq(x - 1, 0), Eq(x + 2, 2)).simplify() == False assert And(Ne(x - 1, 0), Ne(x + 2, 2)).simplify() == And(Ne(x, 1), Ne(x, 0))
def test_true_false(): assert true is S.true assert false is S.false assert true is not True assert false is not False assert true assert not false assert true == True assert false == False assert not (true == False) assert not (false == True) assert not (true == false) assert hash(true) == hash(True) assert hash(false) == hash(False) assert len({true, True}) == len({false, False}) == 1 assert isinstance(true, BooleanAtom) assert isinstance(false, BooleanAtom) # We don't want to subclass from bool, because bool subclasses from # int. But operators like &, |, ^, <<, >>, and ~ act differently on 0 and # 1 then we want them to on true and false. See the docstrings of the # various And, Or, etc. functions for examples. assert not isinstance(true, bool) assert not isinstance(false, bool) # Note: using 'is' comparison is important here. We want these to return # true and false, not True and False assert Not(true) is false assert Not(True) is false assert Not(false) is true assert Not(False) is true assert ~true is false assert ~false is true for T, F in cartes([True, true], [False, false]): assert And(T, F) is false assert And(F, T) is false assert And(F, F) is false assert And(T, T) is true assert And(T, x) == x assert And(F, x) is false if not (T is True and F is False): assert T & F is false assert F & T is false if F is not False: assert F & F is false if T is not True: assert T & T is true assert Or(T, F) is true assert Or(F, T) is true assert Or(F, F) is false assert Or(T, T) is true assert Or(T, x) is true assert Or(F, x) == x if not (T is True and F is False): assert T | F is true assert F | T is true if F is not False: assert F | F is false if T is not True: assert T | T is true assert Xor(T, F) is true assert Xor(F, T) is true assert Xor(F, F) is false assert Xor(T, T) is false assert Xor(T, x) == ~x assert Xor(F, x) == x if not (T is True and F is False): assert T ^ F is true assert F ^ T is true if F is not False: assert F ^ F is false if T is not True: assert T ^ T is false assert Nand(T, F) is true assert Nand(F, T) is true assert Nand(F, F) is true assert Nand(T, T) is false assert Nand(T, x) == ~x assert Nand(F, x) is true assert Nor(T, F) is false assert Nor(F, T) is false assert Nor(F, F) is true assert Nor(T, T) is false assert Nor(T, x) is false assert Nor(F, x) == ~x assert Implies(T, F) is false assert Implies(F, T) is true assert Implies(F, F) is true assert Implies(T, T) is true assert Implies(T, x) == x assert Implies(F, x) is true assert Implies(x, T) is true assert Implies(x, F) == ~x if not (T is True and F is False): assert T >> F is false assert F << T is false assert F >> T is true assert T << F is true if F is not False: assert F >> F is true assert F << F is true if T is not True: assert T >> T is true assert T << T is true assert Equivalent(T, F) is false assert Equivalent(F, T) is false assert Equivalent(F, F) is true assert Equivalent(T, T) is true assert Equivalent(T, x) == x assert Equivalent(F, x) == ~x assert Equivalent(x, T) == x assert Equivalent(x, F) == ~x assert ITE(T, T, T) is true assert ITE(T, T, F) is true assert ITE(T, F, T) is false assert ITE(T, F, F) is false assert ITE(F, T, T) is true assert ITE(F, T, F) is false assert ITE(F, F, T) is true assert ITE(F, F, F) is false assert all(i.simplify(1, 2) is i for i in (S.true, S.false))
def test_minisat22_minimal_satisfiable(): A, B, C = symbols('A,B,C') minisat22_satisfiable = lambda expr, minimal=True: satisfiable( expr, algorithm="minisat22", minimal=True) assert minisat22_satisfiable(A & ~A) is False assert minisat22_satisfiable(A & ~B) == {A: True, B: False} assert minisat22_satisfiable(A | B) in ({ A: True }, { B: False }, { A: False, B: True }, { A: True, B: True }, { A: True, B: False }) assert minisat22_satisfiable((~A | B) & (~B | A)) in ({ A: True, B: True }, { A: False, B: False }) assert minisat22_satisfiable((A | B) & (~B | C)) in ({ A: True, B: False, C: True }, { A: True, B: True, C: True }, { A: False, B: True, C: True }, { A: True, B: False, C: False }) assert minisat22_satisfiable(A & B & C) == {A: True, B: True, C: True} assert minisat22_satisfiable((A | B) & (A >> B)) in ({ B: True, A: False }, { B: True, A: True }) assert minisat22_satisfiable(Equivalent(A, B) & A) == {A: True, B: True} assert minisat22_satisfiable(Equivalent(A, B) & ~A) == {A: False, B: False} g = satisfiable((A | B | C), algorithm="minisat22", minimal=True, all_models=True) sol = next(g) first_solution = {key for key, value in sol.items() if value} sol = next(g) second_solution = {key for key, value in sol.items() if value} sol = next(g) third_solution = {key for key, value in sol.items() if value} assert not first_solution <= second_solution assert not second_solution <= third_solution assert not first_solution <= third_solution
("square", "matrices.AskSquareHandler"), ("integer_elements", "matrices.AskIntegerElementsHandler"), ("real_elements", "matrices.AskRealElementsHandler"), ("complex_elements", "matrices.AskComplexElementsHandler"), ] for name, value in _handlers: register_handler(name, _val_template % value) known_facts_keys = [ getattr(Q, attr) for attr in Q.__dict__ if not attr.startswith('__') ] known_facts = And( Implies(Q.real, Q.complex), Implies(Q.real, Q.hermitian), Equivalent(Q.even, Q.integer & ~Q.odd), Equivalent(Q.extended_real, Q.real | Q.infinity), Equivalent(Q.odd, Q.integer & ~Q.even), Equivalent(Q.prime, Q.integer & Q.positive & ~Q.composite), Implies(Q.integer, Q.rational), Implies(Q.rational, Q.algebraic), Implies(Q.algebraic, Q.complex), Implies(Q.imaginary, Q.complex & ~Q.real), Implies(Q.imaginary, Q.antihermitian), Implies(Q.antihermitian, ~Q.hermitian), Equivalent(Q.negative, Q.nonzero & ~Q.positive), Equivalent(Q.positive, Q.nonzero & ~Q.negative), Equivalent(Q.rational, Q.real & ~Q.irrational), Equivalent(Q.real, Q.rational | Q.irrational), Implies(Q.nonzero, Q.real), Equivalent(Q.nonzero, Q.positive | Q.negative),
def apply(self): from sympy import isprime return Equivalent(self.args[0], isprime(self.expr))
def test_fcode_Xlogical(): x, y, z = symbols("x y z") # binary Xor assert fcode(Xor(x, y, evaluate=False)) == "x .neqv. y" assert fcode(Xor(x, Not(y), evaluate=False)) == "x .neqv. .not. y" assert fcode(Xor(Not(x), y, evaluate=False)) == "y .neqv. .not. x" assert fcode(Xor(Not(x), Not(y), evaluate=False)) == ".not. x .neqv. .not. y" assert fcode(Not(Xor(x, y, evaluate=False), evaluate=False)) == ".not. (x .neqv. y)" # binary Equivalent assert fcode(Equivalent(x, y)) == "x .eqv. y" assert fcode(Equivalent(x, Not(y))) == "x .eqv. .not. y" assert fcode(Equivalent(Not(x), y)) == "y .eqv. .not. x" assert fcode(Equivalent(Not(x), Not(y))) == ".not. x .eqv. .not. y" assert fcode(Not(Equivalent(x, y), evaluate=False)) == ".not. (x .eqv. y)" # mixed And/Equivalent assert fcode(Equivalent(And(y, z), x)) == "x .eqv. y .and. z" assert fcode(Equivalent(And(z, x), y)) == "y .eqv. x .and. z" assert fcode(Equivalent(And(x, y), z)) == "z .eqv. x .and. y" assert fcode(And(Equivalent(y, z), x)) == "x .and. (y .eqv. z)" assert fcode(And(Equivalent(z, x), y)) == "y .and. (x .eqv. z)" assert fcode(And(Equivalent(x, y), z)) == "z .and. (x .eqv. y)" # mixed Or/Equivalent assert fcode(Equivalent(Or(y, z), x)) == "x .eqv. y .or. z" assert fcode(Equivalent(Or(z, x), y)) == "y .eqv. x .or. z" assert fcode(Equivalent(Or(x, y), z)) == "z .eqv. x .or. y" assert fcode(Or(Equivalent(y, z), x)) == "x .or. (y .eqv. z)" assert fcode(Or(Equivalent(z, x), y)) == "y .or. (x .eqv. z)" assert fcode(Or(Equivalent(x, y), z)) == "z .or. (x .eqv. y)" # mixed Xor/Equivalent assert fcode(Equivalent(Xor(y, z, evaluate=False), x)) == "x .eqv. (y .neqv. z)" assert fcode(Equivalent(Xor(z, x, evaluate=False), y)) == "y .eqv. (x .neqv. z)" assert fcode(Equivalent(Xor(x, y, evaluate=False), z)) == "z .eqv. (x .neqv. y)" assert fcode(Xor(Equivalent(y, z), x, evaluate=False)) == "x .neqv. (y .eqv. z)" assert fcode(Xor(Equivalent(z, x), y, evaluate=False)) == "y .neqv. (x .eqv. z)" assert fcode(Xor(Equivalent(x, y), z, evaluate=False)) == "z .neqv. (x .eqv. y)" # mixed And/Xor assert fcode(Xor(And(y, z), x, evaluate=False)) == "x .neqv. y .and. z" assert fcode(Xor(And(z, x), y, evaluate=False)) == "y .neqv. x .and. z" assert fcode(Xor(And(x, y), z, evaluate=False)) == "z .neqv. x .and. y" assert fcode(And(Xor(y, z, evaluate=False), x)) == "x .and. (y .neqv. z)" assert fcode(And(Xor(z, x, evaluate=False), y)) == "y .and. (x .neqv. z)" assert fcode(And(Xor(x, y, evaluate=False), z)) == "z .and. (x .neqv. y)" # mixed Or/Xor assert fcode(Xor(Or(y, z), x, evaluate=False)) == "x .neqv. y .or. z" assert fcode(Xor(Or(z, x), y, evaluate=False)) == "y .neqv. x .or. z" assert fcode(Xor(Or(x, y), z, evaluate=False)) == "z .neqv. x .or. y" assert fcode(Or(Xor(y, z, evaluate=False), x)) == "x .or. (y .neqv. z)" assert fcode(Or(Xor(z, x, evaluate=False), y)) == "y .or. (x .neqv. z)" assert fcode(Or(Xor(x, y, evaluate=False), z)) == "z .or. (x .neqv. y)" # ternary Xor assert fcode(Xor(x, y, z, evaluate=False)) == "x .neqv. y .neqv. z" assert fcode(Xor(x, y, Not(z), evaluate=False)) == "x .neqv. y .neqv. .not. z" assert fcode(Xor(x, Not(y), z, evaluate=False)) == "x .neqv. z .neqv. .not. y" assert fcode(Xor(Not(x), y, z, evaluate=False)) == "y .neqv. z .neqv. .not. x"
def teams_operations(db, db_ops, dic, sat_solver): # The status order is S, H, Q, U, I # The operations order is recover, infect, H_noop, U_noop, S_noop, vac, quar, Q_noop, I_noop, end_of_Q maps = dic["observations"] police = dic["police"] medics = dic["medics"] maps_num = len(maps) row_num = len(maps[0]) col_num = len(maps[0][0]) false_literal = 15*(maps_num)*(row_num)*(col_num) + 2 for t in range(maps_num-1): for row in range(row_num): for col in range(col_num): # vac & I_noop if t+1 < maps_num and medics > 0: # At least 2 maps I_temp_list = [] # [H_t, vac_t, I_t+1, I_noop_t+1, I_t+2, I_t, I_noop_t] I_temp_list.append(db[1][t][row][col]) I_temp_list.append(db_ops[5][t][row][col]) I_temp_list.append(db[4][t+1][row][col]) for I_index in range(len(I_temp_list)): I_temp_list[I_index] = symbols('{}'.format(I_temp_list[I_index])) I_first_st = Equivalent((I_temp_list[0] & I_temp_list[2]), I_temp_list[1]) I_st_list = [I_first_st] if t+2 < maps_num: # At least 3 maps I_temp_list.append(db_ops[8][t+1][row][col]) I_temp_list.append(db[4][t+2][row][col]) for I_index in range(3,len(I_temp_list)): I_temp_list[I_index] = symbols('{}'.format(I_temp_list[I_index])) I_second_st = Equivalent((I_temp_list[2] & I_temp_list[4]), I_temp_list[3]) I_st_list.append(I_second_st) if t+3 < maps_num: # At least 4 maps I_temp_list.append(db[4][t][row][col]) I_temp_list.append(db_ops[8][t][row][col]) for I_index in range(5,len(I_temp_list)): I_temp_list[I_index] = symbols('{}'.format(I_temp_list[I_index])) I_third_st = Equivalent((I_temp_list[5] & I_temp_list[2]),I_temp_list[6]) I_st_list.append(I_third_st) I_forth_st = Equivalent(I_temp_list[6], I_temp_list[3]) I_st_list.append(I_forth_st) for I_st in I_st_list: I_st_output = sympy_to_pysat(I_st, True) for I_i in I_st_output: sat_solver.add_clause(I_i) # quar & Q_noop & end_of_Q if t+1 < maps_num and police > 0: # At least 2 maps Q_temp_list = [] # [S_t, quar_t, Q_t+1, Q_noop_t+1, Q_t+2, end_of_Q_t+2 , H_t+3] Q_temp_list.append(db[0][t][row][col]) Q_temp_list.append(db_ops[6][t][row][col]) Q_temp_list.append(db[2][t+1][row][col]) for Q_index in range(len(Q_temp_list)): Q_temp_list[Q_index] = symbols('{}'.format(Q_temp_list[Q_index])) Q_first_st = Equivalent((Q_temp_list[0] & Q_temp_list[2]), Q_temp_list[1]) Q_st_list = [Q_first_st] if t+2 < maps_num: # At least 3 maps Q_temp_list.append(db_ops[7][t+1][row][col]) Q_temp_list.append(db[2][t+2][row][col]) for Q_index in range(3,len(Q_temp_list)): Q_temp_list[Q_index] = symbols('{}'.format(Q_temp_list[Q_index])) Q_second_st = Equivalent((Q_temp_list[2] & Q_temp_list[4]), Q_temp_list[3]) Q_st_list.append(Q_second_st) Q_third_st = Equivalent(Q_temp_list[1], Q_temp_list[3]) Q_st_list.append(Q_third_st) if t+3 < maps_num: # At least 4 maps Q_temp_list.append(db_ops[9][t+2][row][col]) Q_temp_list.append(db[1][t+3][row][col]) for Q_index in range(5,len(Q_temp_list)): Q_temp_list[Q_index] = symbols('{}'.format(Q_temp_list[Q_index])) Q_forth_st = Equivalent((Q_temp_list[2] & Q_temp_list[4]), Q_temp_list[5]) Q_st_list.append(Q_forth_st) Q_fifth_st = Equivalent((Q_temp_list[4] & Q_temp_list[6]), Q_temp_list[5]) Q_st_list.append(Q_fifth_st) Q_six_st = Equivalent(Q_temp_list[3], Q_temp_list[5]) Q_st_list.append(Q_six_st) for Q_st in Q_st_list: Q_st_output = sympy_to_pysat(Q_st, True) for Q_i in Q_st_output: sat_solver.add_clause(Q_i) # S_noop & recover: if maps_num <= 3: # Just S_noop S_temp_list = [] # [S_t, S_t+1, S_noop] S_temp_list.append(db[0][t][row][col]) S_temp_list.append(db[0][t+1][row][col]) S_temp_list.append(db_ops[4][t][row][col]) for S_index in range(len(S_temp_list)): S_temp_list[S_index] = symbols('{}'.format(S_temp_list[S_index])) S_st = Equivalent((S_temp_list[0] & S_temp_list[1]), S_temp_list[2]) S_st_output = sympy_to_pysat(S_st, True) for S_i in S_st_output: sat_solver.add_clause(S_i) else: if t+3 < maps_num: S_temp_list = [] # [S_t, S_t+1, S_t+2, S_t+3, H_t+3, recover_t+2, S_noop_t+2] S_temp_list.append(db[0][t][row][col]) S_temp_list.append(db[0][t+1][row][col]) S_temp_list.append(db[0][t+2][row][col]) S_temp_list.append(db[0][t+3][row][col]) S_temp_list.append(db[1][t+3][row][col]) S_temp_list.append(db_ops[0][t+2][row][col]) S_temp_list.append(db_ops[4][t+2][row][col]) for S_index in range(len(S_temp_list)): S_temp_list[S_index] = symbols('{}'.format(S_temp_list[S_index])) S_first_st = Equivalent((S_temp_list[0] & S_temp_list[1] & S_temp_list[2]), S_temp_list[5]) S_second_st = Equivalent((S_temp_list[2] & S_temp_list[4]), S_temp_list[5]) S_third_st = Equivalent((S_temp_list[2] & S_temp_list[3]), S_temp_list[6]) S_st_list = [S_first_st, S_second_st, S_third_st] for S_st in S_st_list: S_st_output = sympy_to_pysat(S_st, True) for S_i in S_st_output: sat_solver.add_clause(S_i) # H_noop & infect: H_temp_list = [] # [S_row+1, S_row-1, S_col+1, S_col-1, H_t, H_t+1, S_t+1, infect, H_noop] if row+1 == row_num: H_temp_list.append(false_literal) else: H_temp_list.append(db[0][t][row+1][col]) # Sick neighbor at previous time if row-1 < 0: H_temp_list.append(false_literal) else: H_temp_list.append(db[0][t][row-1][col]) if col+1 == col_num: H_temp_list.append(false_literal) else: H_temp_list.append(db[0][t][row][col+1]) if col-1 < 0: H_temp_list.append(false_literal) else: H_temp_list.append(db[0][t][row][col-1]) sat_solver.add_clause([-false_literal]) H_temp_list.append(db[1][t][row][col]) H_temp_list.append(db[1][t+1][row][col]) H_temp_list.append(db[0][t+1][row][col]) H_temp_list.append(db_ops[1][t][row][col]) H_temp_list.append(db_ops[2][t][row][col]) for H_index in range(len(H_temp_list)): H_temp_list[H_index] = symbols('{}'.format(H_temp_list[H_index])) H_first_st = Equivalent(((H_temp_list[0] | H_temp_list[1] | H_temp_list[2] | H_temp_list[3]) & H_temp_list[4]), H_temp_list[7]) H_second_st = Equivalent((H_temp_list[4] & H_temp_list[6]), H_temp_list[7]) H_third_st = Equivalent((H_temp_list[4] & H_temp_list[5]), H_temp_list[8]) H_st_list = [H_first_st, H_second_st, H_third_st] for H_st in H_st_list: H_st_output = sympy_to_pysat(H_st, True) for H_i in H_st_output: sat_solver.add_clause(H_i) # U_noop: U_temp_list = [db[3][t][row][col], db[3][t+1][row][col], db_ops[3][t][row][col]] for U_index in range(len(U_temp_list)): U_temp_list[U_index] = symbols('{}'.format(U_temp_list[U_index])) U_st = Equivalent((U_temp_list[0] & U_temp_list[1]),U_temp_list[2]) st_output = sympy_to_pysat(U_st, True) for U_i in st_output: sat_solver.add_clause(U_i)
def initial_clause(db, db_ops, dic, sat_solver): # The status order is S, H, Q, U, I # The operations order is recover, infect, H_noop, U_noop, S_noop, vac, quar, Q_noop, I_noop, end_of_Q maps = dic["observations"] maps_num = len(maps) row_num = len(maps[0]) col_num = len(maps[0][0]) police = dic["police"] medics = dic["medics"] for t in range(maps_num): for row in range(row_num): for col in range(col_num): if maps[t][row][col] == 'S': sat_solver.add_clause([db[0][t][row][col]]) sat_solver.add_clause([-db[1][t][row][col]]) sat_solver.add_clause([-db[2][t][row][col]]) sat_solver.add_clause([-db[3][t][row][col]]) sat_solver.add_clause([-db[4][t][row][col]]) # Operations: if police == 0: sat_solver.add_clause([-db_ops[1][t][row][col]]) sat_solver.add_clause([-db_ops[2][t][row][col]]) sat_solver.add_clause([-db_ops[3][t][row][col]]) if maps_num >= 4: temp_list = [db_ops[0][t][row][col],db_ops[4][t][row][col]] for index in range(len(temp_list)): temp_list[index] = symbols('{}'.format(temp_list[index])) st = (temp_list[0] ^ temp_list[1]) st_output = sympy_to_pysat(st, True) for i in st_output: sat_solver.add_clause(i) else: sat_solver.add_clause([-db_ops[0][t][row][col]]) sat_solver.add_clause([db_ops[4][t][row][col]]) sat_solver.add_clause([-db_ops[5][t][row][col]]) sat_solver.add_clause([-db_ops[6][t][row][col]]) sat_solver.add_clause([-db_ops[7][t][row][col]]) sat_solver.add_clause([-db_ops[8][t][row][col]]) sat_solver.add_clause([-db_ops[9][t][row][col]]) elif police > 0: sat_solver.add_clause([-db_ops[1][t][row][col]]) sat_solver.add_clause([-db_ops[2][t][row][col]]) sat_solver.add_clause([-db_ops[3][t][row][col]]) sat_solver.add_clause([-db_ops[5][t][row][col]]) sat_solver.add_clause([-db_ops[7][t][row][col]]) sat_solver.add_clause([-db_ops[8][t][row][col]]) sat_solver.add_clause([-db_ops[9][t][row][col]]) if maps_num >= 4: temp_list = [db_ops[0][t][row][col], db_ops[4][t][row][col], db_ops[6][t][row][col]] sat_solver.add_clause(temp_list) sat_solver.add_clause([-temp_list[0], -temp_list[1]]) sat_solver.add_clause([-temp_list[0], -temp_list[2]]) sat_solver.add_clause([-temp_list[1], -temp_list[2]]) else: sat_solver.add_clause([-db_ops[0][t][row][col]]) temp_list = [db_ops[4][t][row][col], db_ops[6][t][row][col]] for index in range(len(temp_list)): temp_list[index] = symbols('{}'.format(temp_list[index])) st = (temp_list[0] ^ temp_list[1]) st_output = sympy_to_pysat(st, True) for i in st_output: sat_solver.add_clause(i) elif maps[t][row][col] == 'H': sat_solver.add_clause([-db[0][t][row][col]]) sat_solver.add_clause([db[1][t][row][col]]) sat_solver.add_clause([-db[2][t][row][col]]) sat_solver.add_clause([-db[3][t][row][col]]) sat_solver.add_clause([-db[4][t][row][col]]) # Operations: if medics == 0: sat_solver.add_clause([-db_ops[0][t][row][col]]) sat_solver.add_clause([-db_ops[3][t][row][col]]) sat_solver.add_clause([-db_ops[4][t][row][col]]) sat_solver.add_clause([-db_ops[5][t][row][col]]) sat_solver.add_clause([-db_ops[6][t][row][col]]) sat_solver.add_clause([-db_ops[7][t][row][col]]) sat_solver.add_clause([-db_ops[8][t][row][col]]) sat_solver.add_clause([-db_ops[9][t][row][col]]) temp_list = [db_ops[1][t][row][col],db_ops[2][t][row][col]] for index in range(len(temp_list)): temp_list[index] = symbols('{}'.format(temp_list[index])) st = (temp_list[0] ^ temp_list[1]) st_output = sympy_to_pysat(st, True) for i in st_output: sat_solver.add_clause(i) elif medics > 0: sat_solver.add_clause([-db_ops[0][t][row][col]]) sat_solver.add_clause([-db_ops[3][t][row][col]]) sat_solver.add_clause([-db_ops[4][t][row][col]]) sat_solver.add_clause([-db_ops[6][t][row][col]]) sat_solver.add_clause([-db_ops[7][t][row][col]]) sat_solver.add_clause([-db_ops[8][t][row][col]]) sat_solver.add_clause([-db_ops[9][t][row][col]]) temp_list = [db_ops[1][t][row][col], db_ops[2][t][row][col], db_ops[5][t][row][col]] sat_solver.add_clause(temp_list) sat_solver.add_clause([-temp_list[0], -temp_list[1]]) sat_solver.add_clause([-temp_list[0], -temp_list[2]]) sat_solver.add_clause([-temp_list[1], -temp_list[2]]) elif maps[t][row][col] == 'Q': sat_solver.add_clause([-db[0][t][row][col]]) sat_solver.add_clause([-db[1][t][row][col]]) sat_solver.add_clause([db[2][t][row][col]]) sat_solver.add_clause([-db[3][t][row][col]]) sat_solver.add_clause([-db[4][t][row][col]]) # Operations: sat_solver.add_clause([-db_ops[0][t][row][col]]) sat_solver.add_clause([-db_ops[1][t][row][col]]) sat_solver.add_clause([-db_ops[2][t][row][col]]) sat_solver.add_clause([-db_ops[3][t][row][col]]) sat_solver.add_clause([-db_ops[4][t][row][col]]) sat_solver.add_clause([-db_ops[5][t][row][col]]) sat_solver.add_clause([-db_ops[6][t][row][col]]) sat_solver.add_clause([-db_ops[8][t][row][col]]) temp_list = [db_ops[7][t][row][col],db_ops[9][t][row][col]] for index in range(len(temp_list)): temp_list[index] = symbols('{}'.format(temp_list[index])) st = (temp_list[0] ^ temp_list[1]) st_output = sympy_to_pysat(st, True) for i in st_output: sat_solver.add_clause(i) elif maps[t][row][col] == 'U': sat_solver.add_clause([-db[0][t][row][col]]) sat_solver.add_clause([-db[1][t][row][col]]) sat_solver.add_clause([-db[2][t][row][col]]) sat_solver.add_clause([db[3][t][row][col]]) sat_solver.add_clause([-db[4][t][row][col]]) # Operations: only U_noOp and NOT all the rest sat_solver.add_clause([-db_ops[0][t][row][col]]) sat_solver.add_clause([-db_ops[1][t][row][col]]) sat_solver.add_clause([-db_ops[2][t][row][col]]) sat_solver.add_clause([db_ops[3][t][row][col]]) sat_solver.add_clause([-db_ops[4][t][row][col]]) sat_solver.add_clause([-db_ops[5][t][row][col]]) sat_solver.add_clause([-db_ops[6][t][row][col]]) sat_solver.add_clause([-db_ops[7][t][row][col]]) sat_solver.add_clause([-db_ops[8][t][row][col]]) sat_solver.add_clause([-db_ops[9][t][row][col]]) elif maps[t][row][col] == 'I': sat_solver.add_clause([-db[0][t][row][col]]) sat_solver.add_clause([-db[1][t][row][col]]) sat_solver.add_clause([-db[2][t][row][col]]) sat_solver.add_clause([-db[3][t][row][col]]) sat_solver.add_clause([db[4][t][row][col]]) # Operations: only I_noOp and NOT all the rest sat_solver.add_clause([-db_ops[0][t][row][col]]) sat_solver.add_clause([-db_ops[1][t][row][col]]) sat_solver.add_clause([-db_ops[2][t][row][col]]) sat_solver.add_clause([-db_ops[3][t][row][col]]) sat_solver.add_clause([-db_ops[4][t][row][col]]) sat_solver.add_clause([-db_ops[5][t][row][col]]) sat_solver.add_clause([-db_ops[6][t][row][col]]) sat_solver.add_clause([-db_ops[7][t][row][col]]) sat_solver.add_clause([db_ops[8][t][row][col]]) sat_solver.add_clause([-db_ops[9][t][row][col]]) elif maps[t][row][col] == '?': # For each time and location insert "?" as (some state) and ~(other states) for each state temp_list = [db[0][t][row][col],db[1][t][row][col],db[2][t][row][col],db[3][t][row][col],db[4][t][row][col]] temp_op_list = [db_ops[0][t][row][col],db_ops[1][t][row][col],db_ops[2][t][row][col],db_ops[3][t][row][col],db_ops[4][t][row][col]] # Operations: if medics + police == 0: sat_solver.add_clause(temp_op_list) sat_solver.add_clause([-db_ops[0][t][row][col],-db_ops[1][t][row][col]]) sat_solver.add_clause([-db_ops[0][t][row][col],-db_ops[2][t][row][col]]) sat_solver.add_clause([-db_ops[0][t][row][col],-db_ops[3][t][row][col]]) sat_solver.add_clause([-db_ops[0][t][row][col],-db_ops[4][t][row][col]]) sat_solver.add_clause([-db_ops[1][t][row][col],-db_ops[2][t][row][col]]) sat_solver.add_clause([-db_ops[1][t][row][col],-db_ops[3][t][row][col]]) sat_solver.add_clause([-db_ops[1][t][row][col],-db_ops[4][t][row][col]]) sat_solver.add_clause([-db_ops[2][t][row][col],-db_ops[3][t][row][col]]) sat_solver.add_clause([-db_ops[2][t][row][col],-db_ops[4][t][row][col]]) sat_solver.add_clause([-db_ops[3][t][row][col],-db_ops[4][t][row][col]]) if medics + police > 0: teams_temp_op_list = [db_ops[0][t][row][col],db_ops[1][t][row][col],db_ops[2][t][row][col],db_ops[3][t][row][col],db_ops[4][t][row][col],db_ops[5][t][row][col],db_ops[6][t][row][col],db_ops[7][t][row][col],db_ops[8][t][row][col],db_ops[9][t][row][col]] sat_solver.add_clause(teams_temp_op_list) c = 0 for one in teams_temp_op_list: c += 1 for two in teams_temp_op_list[c:]: sat_solver.add_clause([-one,-two]) if t == maps_num-1: # if U_t >> U forever (U_t-1 <> U_t) U_temp_list = [db[3][t-1][row][col],db[3][t][row][col]] for U_index in range(len(U_temp_list)): U_temp_list[U_index] = symbols('{}'.format(U_temp_list[U_index])) U_st = Equivalent(U_temp_list[0], U_temp_list[1]) U_st_output = sympy_to_pysat(U_st, True) for U_i in U_st_output: sat_solver.add_clause(U_i) if t < maps_num-1: # if U_t >> U forever (U_t <> U_t+1) U_temp_list = [db[3][t][row][col],db[3][t+1][row][col]] for U_index in range(len(U_temp_list)): U_temp_list[U_index] = symbols('{}'.format(U_temp_list[U_index])) U_st = Equivalent(U_temp_list[0], U_temp_list[1]) U_st_output = sympy_to_pysat(U_st, True) for U_i in U_st_output: sat_solver.add_clause(U_i) #status: if t != 0: sat_solver.add_clause(temp_list) sat_solver.add_clause([-db[0][t][row][col],-db[1][t][row][col]]) sat_solver.add_clause([-db[0][t][row][col],-db[2][t][row][col]]) sat_solver.add_clause([-db[0][t][row][col],-db[3][t][row][col]]) sat_solver.add_clause([-db[0][t][row][col],-db[4][t][row][col]]) sat_solver.add_clause([-db[1][t][row][col],-db[2][t][row][col]]) sat_solver.add_clause([-db[1][t][row][col],-db[3][t][row][col]]) sat_solver.add_clause([-db[1][t][row][col],-db[4][t][row][col]]) sat_solver.add_clause([-db[2][t][row][col],-db[3][t][row][col]]) sat_solver.add_clause([-db[2][t][row][col],-db[4][t][row][col]]) sat_solver.add_clause([-db[3][t][row][col],-db[4][t][row][col]]) if t == 0: sat_solver.add_clause([-db[4][t][row][col]]) sat_solver.add_clause([-db[2][t][row][col]]) sat_solver.add_clause([db[1][t][row][col],db[3][t][row][col],db[0][t][row][col]]) sat_solver.add_clause([-db[0][t][row][col],-db[1][t][row][col]]) sat_solver.add_clause([-db[0][t][row][col],-db[3][t][row][col]]) sat_solver.add_clause([-db[1][t][row][col],-db[3][t][row][col]])
def get_known_facts(): return And( Implies(Q.infinite, ~Q.finite), Implies(Q.real, Q.complex), Implies(Q.real, Q.hermitian), Equivalent(Q.even, Q.integer & ~Q.odd), Equivalent(Q.extended_real, Q.real | Q.infinite), Equivalent(Q.odd, Q.integer & ~Q.even), Equivalent(Q.prime, Q.integer & Q.positive & ~Q.composite), Implies(Q.integer, Q.rational), Implies(Q.rational, Q.algebraic), Implies(Q.algebraic, Q.complex), Equivalent(Q.transcendental, Q.complex & ~Q.algebraic), Implies(Q.imaginary, Q.complex & ~Q.real), Implies(Q.imaginary, Q.antihermitian), Implies(Q.antihermitian, ~Q.hermitian), Equivalent(Q.negative, Q.nonzero & ~Q.positive), Equivalent(Q.positive, Q.nonzero & ~Q.negative), Implies(Q.positive, ~Q.negative), Equivalent(Q.rational, Q.real & ~Q.irrational), Equivalent(Q.real, Q.rational | Q.irrational), Implies(Q.nonzero, Q.real), Equivalent(Q.nonzero, Q.positive | Q.negative), Equivalent(Q.nonpositive, ~Q.positive & Q.real), Equivalent(Q.nonnegative, ~Q.negative & Q.real), Equivalent(Q.zero, Q.real & ~Q.nonzero), Implies(Q.zero, Q.even), Implies(Q.orthogonal, Q.positive_definite), Implies(Q.orthogonal, Q.unitary), Implies(Q.unitary & Q.real, Q.orthogonal), Implies(Q.unitary, Q.normal), Implies(Q.unitary, Q.invertible), Implies(Q.normal, Q.square), Implies(Q.diagonal, Q.normal), Implies(Q.positive_definite, Q.invertible), Implies(Q.diagonal, Q.upper_triangular), Implies(Q.diagonal, Q.lower_triangular), Implies(Q.lower_triangular, Q.triangular), Implies(Q.upper_triangular, Q.triangular), Implies(Q.triangular, Q.upper_triangular | Q.lower_triangular), Implies(Q.upper_triangular & Q.lower_triangular, Q.diagonal), Implies(Q.diagonal, Q.symmetric), Implies(Q.unit_triangular, Q.triangular), Implies(Q.invertible, Q.fullrank), Implies(Q.invertible, Q.square), Implies(Q.symmetric, Q.square), Implies(Q.fullrank & Q.square, Q.invertible), Equivalent(Q.invertible, ~Q.singular), Implies(Q.integer_elements, Q.real_elements), Implies(Q.real_elements, Q.complex_elements), )
def operations(db, db_ops, dic, sat_solver): # The status order is S, H, Q, U, I # The operations order is recover, infect, H_noop, U_noop, S_noop maps = dic["observations"] maps_num = len(maps) row_num = len(maps[0]) col_num = len(maps[0][0]) false_literal = 15*(maps_num)*(row_num)*(col_num) + 1 for t in range(maps_num-1): for row in range(row_num): for col in range(col_num): # S_noop & recover: if maps_num <= 3: # Just S_noop S_temp_list = [] # [S_t, S_t+1, S_noop] S_temp_list.append(db[0][t][row][col]) S_temp_list.append(db[0][t+1][row][col]) S_temp_list.append(db_ops[4][t][row][col]) for S_index in range(len(S_temp_list)): S_temp_list[S_index] = symbols('{}'.format(S_temp_list[S_index])) S_st = Equivalent((S_temp_list[0] & S_temp_list[1]), S_temp_list[2]) S_st_output = sympy_to_pysat(S_st, True) for S_i in S_st_output: sat_solver.add_clause(S_i) else: if t+3 < maps_num: S_temp_list = [] # [S_t, S_t+1, S_t+2, S_t+3, H_t+3, recover_t+2, S_noop_t+2] S_temp_list.append(db[0][t][row][col]) S_temp_list.append(db[0][t+1][row][col]) S_temp_list.append(db[0][t+2][row][col]) S_temp_list.append(db[0][t+3][row][col]) S_temp_list.append(db[1][t+3][row][col]) S_temp_list.append(db_ops[0][t+2][row][col]) S_temp_list.append(db_ops[4][t+2][row][col]) for S_index in range(len(S_temp_list)): S_temp_list[S_index] = symbols('{}'.format(S_temp_list[S_index])) S_first_st = Equivalent((S_temp_list[0] & S_temp_list[1] & S_temp_list[2]), S_temp_list[5]) S_second_st = Equivalent((S_temp_list[2] & S_temp_list[4]), S_temp_list[5]) S_third_st = Equivalent((S_temp_list[2] & S_temp_list[3]), S_temp_list[6]) S_st_list = [S_first_st, S_second_st, S_third_st] for S_st in S_st_list: S_st_output = sympy_to_pysat(S_st, True) for S_i in S_st_output: sat_solver.add_clause(S_i) # H_noop & infect: H_temp_list = [] # [S_row+1, S_row-1, S_col+1, S_col-1, H_t, H_t+1, S_t+1, infect, H_noop] if row+1 == row_num: H_temp_list.append(false_literal) else: H_temp_list.append(db[0][t][row+1][col]) # Sick neighbor at previous time if row-1 < 0: H_temp_list.append(false_literal) else: H_temp_list.append(db[0][t][row-1][col]) if col+1 == col_num: H_temp_list.append(false_literal) else: H_temp_list.append(db[0][t][row][col+1]) if col-1 < 0: H_temp_list.append(false_literal) else: H_temp_list.append(db[0][t][row][col-1]) sat_solver.add_clause([-false_literal]) H_temp_list.append(db[1][t][row][col]) H_temp_list.append(db[1][t+1][row][col]) H_temp_list.append(db[0][t+1][row][col]) H_temp_list.append(db_ops[1][t][row][col]) H_temp_list.append(db_ops[2][t][row][col]) for H_index in range(len(H_temp_list)): H_temp_list[H_index] = symbols('{}'.format(H_temp_list[H_index])) H_first_st = Equivalent(((H_temp_list[0] | H_temp_list[1] | H_temp_list[2] | H_temp_list[3]) & H_temp_list[4]), H_temp_list[7]) H_second_st = Equivalent((H_temp_list[4] & H_temp_list[6]), H_temp_list[7]) H_third_st = Equivalent((H_temp_list[4] & H_temp_list[5]), H_temp_list[8]) H_st_list = [H_first_st, H_second_st, H_third_st] for H_st in H_st_list: H_st_output = sympy_to_pysat(H_st, True) for H_i in H_st_output: sat_solver.add_clause(H_i) # U_noop: U_temp_list = [db[3][t][row][col], db[3][t+1][row][col], db_ops[3][t][row][col]] for U_index in range(len(U_temp_list)): U_temp_list[U_index] = symbols('{}'.format(U_temp_list[U_index])) U_st = Equivalent((U_temp_list[0] & U_temp_list[1]),U_temp_list[2]) st_output = sympy_to_pysat(U_st, True) for U_i in st_output: sat_solver.add_clause(U_i)
def get_known_facts(x=None): """ Facts between unary predicates. Parameters ========== x : Symbol, optional Placeholder symbol for unary facts. Default is ``Symbol('x')``. Returns ======= fact : Known facts in conjugated normal form. """ if x is None: x = Symbol('x') fact = And( # primitive predicates for extended real exclude each other. Exclusive(Q.negative_infinite(x), Q.negative(x), Q.zero(x), Q.positive(x), Q.positive_infinite(x)), # build complex plane Exclusive(Q.real(x), Q.imaginary(x)), Implies(Q.real(x) | Q.imaginary(x), Q.complex(x)), # other subsets of complex Exclusive(Q.transcendental(x), Q.algebraic(x)), Equivalent(Q.real(x), Q.rational(x) | Q.irrational(x)), Exclusive(Q.irrational(x), Q.rational(x)), Implies(Q.rational(x), Q.algebraic(x)), # integers Exclusive(Q.even(x), Q.odd(x)), Implies(Q.integer(x), Q.rational(x)), Implies(Q.zero(x), Q.even(x)), Exclusive(Q.composite(x), Q.prime(x)), Implies(Q.composite(x) | Q.prime(x), Q.integer(x) & Q.positive(x)), Implies(Q.even(x) & Q.positive(x) & ~Q.prime(x), Q.composite(x)), # hermitian and antihermitian Implies(Q.real(x), Q.hermitian(x)), Implies(Q.imaginary(x), Q.antihermitian(x)), Implies(Q.zero(x), Q.hermitian(x) | Q.antihermitian(x)), # define finity and infinity, and build extended real line Exclusive(Q.infinite(x), Q.finite(x)), Implies(Q.complex(x), Q.finite(x)), Implies( Q.negative_infinite(x) | Q.positive_infinite(x), Q.infinite(x)), # commutativity Implies(Q.finite(x) | Q.infinite(x), Q.commutative(x)), # matrices Implies(Q.orthogonal(x), Q.positive_definite(x)), Implies(Q.orthogonal(x), Q.unitary(x)), Implies(Q.unitary(x) & Q.real_elements(x), Q.orthogonal(x)), Implies(Q.unitary(x), Q.normal(x)), Implies(Q.unitary(x), Q.invertible(x)), Implies(Q.normal(x), Q.square(x)), Implies(Q.diagonal(x), Q.normal(x)), Implies(Q.positive_definite(x), Q.invertible(x)), Implies(Q.diagonal(x), Q.upper_triangular(x)), Implies(Q.diagonal(x), Q.lower_triangular(x)), Implies(Q.lower_triangular(x), Q.triangular(x)), Implies(Q.upper_triangular(x), Q.triangular(x)), Implies(Q.triangular(x), Q.upper_triangular(x) | Q.lower_triangular(x)), Implies(Q.upper_triangular(x) & Q.lower_triangular(x), Q.diagonal(x)), Implies(Q.diagonal(x), Q.symmetric(x)), Implies(Q.unit_triangular(x), Q.triangular(x)), Implies(Q.invertible(x), Q.fullrank(x)), Implies(Q.invertible(x), Q.square(x)), Implies(Q.symmetric(x), Q.square(x)), Implies(Q.fullrank(x) & Q.square(x), Q.invertible(x)), Equivalent(Q.invertible(x), ~Q.singular(x)), Implies(Q.integer_elements(x), Q.real_elements(x)), Implies(Q.real_elements(x), Q.complex_elements(x)), ) return fact
def get_known_facts(): # We build the facts starting with primitive predicates. # DO NOT include the predicates in get_composite_predicates()'s keys here! return And( # primitive predicates exclude each other Implies(Q.negative_infinite, ~Q.positive_infinite), Implies(Q.negative, ~Q.zero & ~Q.positive), Implies(Q.positive, ~Q.zero), # build real line and complex plane Implies(Q.negative | Q.zero | Q.positive, ~Q.imaginary), Implies(Q.negative | Q.zero | Q.positive | Q.imaginary, Q.algebraic | Q.transcendental), # other subsets of complex Implies(Q.transcendental, ~Q.algebraic), Implies(Q.irrational, ~Q.rational), Equivalent(Q.rational | Q.irrational, Q.negative | Q.zero | Q.positive), Implies(Q.rational, Q.algebraic), # integers Implies(Q.even, ~Q.odd), Implies(Q.even | Q.odd, Q.rational), Implies(Q.zero, Q.even), Implies(Q.composite, ~Q.prime), Implies(Q.composite | Q.prime, (Q.even | Q.odd) & Q.positive), Implies(Q.even & Q.positive & ~Q.prime, Q.composite), # hermitian and antihermitian Implies(Q.negative | Q.zero | Q.positive, Q.hermitian), Implies(Q.imaginary, Q.antihermitian), Implies(Q.zero, Q.hermitian | Q.antihermitian), # define finity and infinity, and build extended real line Implies(Q.infinite, ~Q.finite), Implies(Q.algebraic | Q.transcendental, Q.finite), Implies(Q.negative_infinite | Q.positive_infinite, Q.infinite), # commutativity Implies(Q.finite | Q.infinite, Q.commutative), # matrices Implies(Q.orthogonal, Q.positive_definite), Implies(Q.orthogonal, Q.unitary), Implies(Q.unitary & Q.real_elements, Q.orthogonal), Implies(Q.unitary, Q.normal), Implies(Q.unitary, Q.invertible), Implies(Q.normal, Q.square), Implies(Q.diagonal, Q.normal), Implies(Q.positive_definite, Q.invertible), Implies(Q.diagonal, Q.upper_triangular), Implies(Q.diagonal, Q.lower_triangular), Implies(Q.lower_triangular, Q.triangular), Implies(Q.upper_triangular, Q.triangular), Implies(Q.triangular, Q.upper_triangular | Q.lower_triangular), Implies(Q.upper_triangular & Q.lower_triangular, Q.diagonal), Implies(Q.diagonal, Q.symmetric), Implies(Q.unit_triangular, Q.triangular), Implies(Q.invertible, Q.fullrank), Implies(Q.invertible, Q.square), Implies(Q.symmetric, Q.square), Implies(Q.fullrank & Q.square, Q.invertible), Equivalent(Q.invertible, ~Q.singular), Implies(Q.integer_elements, Q.real_elements), Implies(Q.real_elements, Q.complex_elements), )
def _(expr): allargs_square = allargs(x, Q.square(x), expr) allargs_invertible = allargs(x, Q.invertible(x), expr) return Implies(allargs_square, Equivalent(Q.invertible(expr), allargs_invertible))
def __len__(self): return len(self.d) def __repr__(self): return repr(self.d) fact_registry = ClassFactRegistry() def register_fact(klass, fact, registry=fact_registry): registry[klass] |= {fact} for klass, fact in [ (Mul, Equivalent(Q.zero, AnyArgs(Q.zero))), (MatMul, Implies(AllArgs(Q.square), Equivalent(Q.invertible, AllArgs(Q.invertible)))), (Add, Implies(AllArgs(Q.positive), Q.positive)), (Add, Implies(AllArgs(Q.negative), Q.negative)), (Mul, Implies(AllArgs(Q.positive), Q.positive)), (Mul, Implies(AllArgs(Q.commutative), Q.commutative)), (Mul, Implies(AllArgs(Q.real), Q.commutative)), (Pow, CustomLambda(lambda power: Implies(Q.real(power.base) & Q.even(power.exp) & Q.nonnegative(power.exp), Q.nonnegative(power)))), (Pow, CustomLambda(lambda power: Implies(Q.nonnegative(power.base) & Q.odd(power.exp) & Q.nonnegative(power.exp), Q.nonnegative(power)))), (Pow, CustomLambda(lambda power: Implies(Q.nonpositive(power.base) & Q.odd(power.exp) & Q.nonnegative(power.exp), Q.nonpositive(power)))), # This one can still be made easier to read. I think we need basic pattern # matching, so that we can just write Equivalent(Q.zero(x**y), Q.zero(x) & Q.positive(y)) (Pow, CustomLambda(lambda power: Equivalent(Q.zero(power), Q.zero(power.base) & Q.positive(power.exp)))),
def parse_srl(contents, verbose): grounded = subprocess.run(['problog', 'ground', '-'], stdout=subprocess.PIPE, input=contents.encode()) grounded_str = grounded.stdout.decode() #grounded_str = "" # TODO: first variable pass and then built clauses as order isn't preserved #with open(pl_file_name, "r") as f: # grounded_str = f.read() factory = problog.program.PrologFactory() parser = problog.parser.PrologParser(factory) parsed = parser.parseString(grounded_str) clauses = {} # map of name to list of formulas, which need to be ored disjunctions = [ ] # list of disjunctions: list of list of var names that are xor [['a1', 'a2'], ['b1', 'b2', 'b3']] evidence = [] # list of evidence (var_name, evidence = true or false) queries = [] # list of variables to query for clause in parsed: if verbose: print(type(clause)) print(clause) if type(clause) is problog.logic.Clause: head = clause.head if verbose: print(head) head_name = term_to_var_name(head) body = clause.body if verbose: print(body) print(type(body)) bform = parse_formula(body) # handle probability if head.probability is not None: temp_name = head_name + "_p" + str(curVarId) v = get_var(temp_name, head.probability) bform &= v[0] if head_name in clauses: clauses[head_name].append(bform) else: if head_name not in variables: get_var(head_name, None) # No probability, handled above clauses[head_name] = [bform] elif type(clause) is problog.logic.Or: # disjunction with probabilities disj = [] ors = [clause] terms = [] while len(ors) > 0: cur_or = ors.pop() e1 = cur_or.op1 e2 = cur_or.op2 if type(e1) is problog.logic.Or: ors.append(e1) else: terms.append(e1) if type(e2) is problog.logic.Or: ors.append(e2) else: terms.append(e2) if verbose: print("terms: ", terms) disj = [] for term in terms: name = term_to_var_name(term) name_alter = name + "_a" + str(curVarId) get_var(name) get_var(name_alter, term.probability) add_clause( clauses, name, variables[name_alter][0]) # equivalance between vars disj.append((name, name_alter)) disjunctions.append((disj, None)) elif type(clause) is problog.logic.AnnotatedDisjunction: # create variable for clause: head_name = "temp_" + str(curVarId) get_var(head_name) sum_prob = 0 # create var for each head: disj = [] for head in clause.heads: name = term_to_var_name(head) name_alter = name + "_a" + str(curVarId) get_var(name) get_var(name_alter, head.probability) add_clause(clauses, name, variables[name_alter][0]) disj.append((name, name_alter)) sum_prob += float(head.probability) if sum_prob < 1: rest = 1 - sum_prob name = "temp_" + str(curVarId) get_var(name, rest) disj.append((None, name)) disjunctions.append((disj, head_name)) if verbose: print("heads: ", disj) bodyf = parse_formula(clause.body) clauses[head_name] = [bodyf] elif type(clause) is problog.logic.Term: if clause.functor == "query": queries.append(term_to_var_name(clause.args[0])) elif clause.functor == "evidence": func = clause.args[0] if func.functor == '\\+': evidence.append((term_to_var_name(func.args[0]), False)) else: evidence.append((term_to_var_name(func), True)) else: name = term_to_var_name(clause) prob = clause.probability name_alter = name + "_a" + str(curVarId) if verbose: print(name, prob) if prob is None: prob = 1.0 get_var(name) get_var(name_alter, prob) add_clause(clauses, name, variables[name_alter][0]) if verbose: print() if verbose: print("varialbes: \t", variables) print("disjunctions: \t", disjunctions) print("clauses: \t", clauses) print("evidence: \t", evidence) print("queries: \t", queries) print() total = True # generate disjunctions: for disj_tuple in disjunctions: disj = disj_tuple[0] head_name = disj_tuple[1] head_sym = variables[head_name][0] if head_name is not None else None syms = [variables[x[1]][0] for x in disj] # add head_name to a v b v c ors = None if head_name is not None: ors = Or(*(syms + [~head_sym])) else: ors = Or(*syms) total &= ors l = len(syms) # add clauses to assert that all syms are diffrent for j in range(l): for i in range(j): total &= ~syms[i] | ~syms[j] # add clauses to make all false in case of head_name == false if head_sym is not None: for sym in syms: total &= head_sym | ~sym # add clauses: for head_name in clauses: bodies = clauses[head_name] ors = Or(*bodies) sym = variables[head_name][0] total &= Equivalent(sym, ors) if verbose: print("total: ", total) print() cnf_total = to_cnf(total) if verbose: print("cnf: ", cnf_total) print() # weights: weights = {} # var name to tuple (prob true, prob false) for disj in disjunctions: for var in disj[0]: alter_name = var[1] vtuple = variables[alter_name] weights[alter_name] = (float(vtuple[1]), 1) for var_name in variables: vtuple = variables[var_name] if var_name in weights: continue # disjunction prob = vtuple[1] if prob is None: weights[var_name] = (1, 1) else: p = float(prob) weights[var_name] = (p, 1 - p) vars = list(variables.keys()) return vars, cnf_total, weights, evidence, queries
def apply(self): return Equivalent(self.args[0], evaluate_old_assump(self.args[0]))
def test_functions_in_assumptions(): from sympy.logic.boolalg import Equivalent, Xor x = symbols('x') assert ask(x, Q.negative, Q.real(x) >> Q.positive(x)) is False assert ask(x, Q.negative, Equivalent(Q.real(x), Q.positive(x))) is False assert ask(x, Q.negative, Xor(Q.real(x), Q.negative(x))) is False
def test_equals(): assert Not(Or(A, B)).equals(And(Not(A), Not(B))) is True assert Equivalent(A, B).equals((A >> B) & (B >> A)) is True assert ((A | ~B) & (~A | B)).equals((~A & ~B) | (A & B)) is True assert (A >> B).equals(~A >> ~B) is False assert (A >> (B >> A)).equals(A >> (C >> A)) is False
def apply(self, expr=None, is_Not=False): arg = self.args[0](expr) if callable(self.args[0]) else self.args[0] res = Equivalent(arg, evaluate_old_assump(arg)) return to_NNF(res, get_composite_predicates())
def test_fcode_precedence(): assert fcode(And(x < y, y < x + 1)) == "x < y .and. y < x + 1" assert fcode(Or(x < y, y < x + 1)) == "x < y .or. y < x + 1" assert fcode(Xor(x < y, y < x + 1, evaluate=False)) == "x < y .neqv. y < x + 1" assert fcode(Equivalent(x < y, y < x + 1)) == "x < y .eqv. y < x + 1"
def apply(self, expr=None, is_Not=False): from sympy import isprime arg = self.args[0](expr) if callable(self.args[0]) else self.args[0] res = Equivalent(arg, isprime(expr)) return to_NNF(res, get_composite_predicates())
def test_entails(): A, B, C = symbols('A, B, C') assert entails(A, [A >> B, ~B]) is False assert entails(B, [Equivalent(A, B), A]) is True assert entails((A >> B) >> (~A >> ~B)) is False assert entails((A >> B) >> (~B >> ~A)) is True
def test_Equivalent(): assert str(Equivalent(y, x)) == "Equivalent(x, y)"
def test_Equivalent(): assert Equivalent(A, B) == Equivalent(B, A) == Equivalent(A, B, A) assert Equivalent() is true assert Equivalent(A, A) == Equivalent(A) is true assert Equivalent(True, True) == Equivalent(False, False) is true assert Equivalent(True, False) == Equivalent(False, True) is false assert Equivalent(A, True) == A assert Equivalent(A, False) == Not(A) assert Equivalent(A, B, True) == A & B assert Equivalent(A, B, False) == ~A & ~B assert Equivalent(1, A) == A assert Equivalent(0, A) == Not(A) assert Equivalent(A, Equivalent(B, C)) != Equivalent(Equivalent(A, B), C) assert Equivalent(A < 1, A >= 1) is false assert Equivalent(A < 1, A >= 1, 0) is false assert Equivalent(A < 1, A >= 1, 1) is false assert Equivalent(A < 1, S.One > A) == Equivalent(1, 1) == Equivalent(0, 0) assert Equivalent(Equality(A, B), Equality(B, A)) is true
def test_Equivalent(self): assert Equivalent(true, false) is false assert Equivalent(0, D) is Not(D) assert Equivalent(Equivalent(A, B), C) is not Equivalent(Equivalent(C, Equivalent(A, B))) assert Equivalent(B < 1, B >= 1) is false assert Equivalent(C < 1, C >= 1, 0) is false assert Equivalent(D < 1, D >= 1, 1) is false assert Equivalent(E < 1, S(1) > E) is Equivalent(1, 1) assert Equivalent(Equality(C, D), Equality(D, C)) is true #to_nnf in Equivalent (could be in Equivalent) assert to_nnf(Equivalent(D, B, C)) == (~D | B) & (~B | C) & (~C | D)
def test_eliminate_implications(): assert eliminate_implications(Implies(A, B, evaluate=False)) == (~A) | B assert eliminate_implications(A >> (C >> Not(B))) == Or( Or(Not(B), Not(C)), Not(A)) assert eliminate_implications(Equivalent(A, B, C, D)) == \ (~A | B) & (~B | C) & (~C | D) & (~D | A)
def test_Equivalent(): assert Equivalent(A, B) == Equivalent(B, A) == Equivalent(A, B, A) assert Equivalent() is True assert Equivalent(A, A) == Equivalent(A) is True assert Equivalent(True, True) == Equivalent(False, False) is True assert Equivalent(True, False) == Equivalent(False, True) is False assert Equivalent(A, True) == A assert Equivalent(A, False) == Not(A) assert Equivalent(A, B, True) == A & B assert Equivalent(A, B, False) == ~A & ~B assert Equivalent(1, A) == A assert Equivalent(0, A) == Not(A)
def test_sympy__logic__boolalg__Equivalent(): from sympy.logic.boolalg import Equivalent assert _test_args(Equivalent(x, 2))
def get_gate_cnf_leq(self): gate_logic = None input_0 = self.gate_inputs[0].symbol if len(self.gate_inputs) > 1: input_1 = self.gate_inputs[1].symbol output = self.gate_output.symbol if re.match("^and", self.gate_type): gate_logic = And(input_0, input_1) if len(self.gate_inputs) > 2: for idx in range(2, len(self.gate_inputs)): gate_logic = And(gate_logic, self.gate_inputs[idx].symbol) # gate_logic = Xor(gate_logic,Not(self.gate_name)) elif re.match("^or", self.gate_type): gate_logic = Or(input_0, input_1) if len(self.gate_inputs) > 2: for idx in range(2, len(self.gate_inputs)): gate_logic = Or(gate_logic, self.gate_inputs[idx].symbol) # gate_logic = Xor(gate_logic,self.gate_name) elif re.match("^xor", self.gate_type): gate_logic = Xor(input_0, input_1) if len(self.gate_inputs) > 2: for idx in range(2, len(self.gate_inputs)): gate_logic = Xor(gate_logic, self.gate_inputs[idx].symbol) # gate_logic = Xor(gate_logic,self.gate_name) elif re.match("^nor", self.gate_type): gate_logic = Or(input_0, input_1) if len(self.gate_inputs) > 2: for idx in range(2, len(self.gate_inputs)): gate_logic = Or(gate_logic, self.gate_inputs[idx].symbol) gate_logic = Not(gate_logic) # gate_logic = Xor(gate_logic,self.gate_name) elif re.match("^nand", self.gate_type): gate_logic = And(input_0, input_1) if len(self.gate_inputs) > 2: for idx in range(2, len(self.gate_inputs)): gate_logic = And(gate_logic, self.gate_inputs[idx].symbol) gate_logic = Not(gate_logic) # gate_logic = Xor(gate_logic,self.gate_name) elif self.gate_type.find("inverter") != -1: gate_logic = Not(input_0) # gate_logic = Xor(gate_logic,self.gate_name) elif self.gate_type.find("buffer") != -1: gate_logic = Not(Not(input_0)) # gate_logic = Xor(gate_logic,self.gate_name) gate_logic = Xor(gate_logic, Not(self.gate_name)) self.cnf_leq = Equivalent(output, gate_logic) # print(self.cnf) self.cnf_leq = to_cnf(self.cnf_leq)