test_boolalg.py 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367
  1. from sympy.assumptions.ask import Q
  2. from sympy.assumptions.refine import refine
  3. from sympy.core.numbers import oo
  4. from sympy.core.relational import Equality, Eq, Ne
  5. from sympy.core.singleton import S
  6. from sympy.core.symbol import (Dummy, symbols)
  7. from sympy.functions import Piecewise
  8. from sympy.functions.elementary.trigonometric import cos, sin
  9. from sympy.sets.sets import Interval, Union
  10. from sympy.sets.contains import Contains
  11. from sympy.simplify.simplify import simplify
  12. from sympy.logic.boolalg import (
  13. And, Boolean, Equivalent, ITE, Implies, Nand, Nor, Not, Or,
  14. POSform, SOPform, Xor, Xnor, conjuncts, disjuncts,
  15. distribute_or_over_and, distribute_and_over_or,
  16. eliminate_implications, is_nnf, is_cnf, is_dnf, simplify_logic,
  17. to_nnf, to_cnf, to_dnf, to_int_repr, bool_map, true, false,
  18. BooleanAtom, is_literal, term_to_integer,
  19. truth_table, as_Boolean, to_anf, is_anf, distribute_xor_over_and,
  20. anf_coeffs, ANFform, bool_minterm, bool_maxterm, bool_monomial,
  21. _check_pair, _convert_to_varsSOP, _convert_to_varsPOS, Exclusive,
  22. gateinputcount)
  23. from sympy.assumptions.cnf import CNF
  24. from sympy.testing.pytest import raises, XFAIL, slow
  25. from itertools import combinations, permutations, product
  26. A, B, C, D = symbols('A:D')
  27. a, b, c, d, e, w, x, y, z = symbols('a:e w:z')
  28. def test_overloading():
  29. """Test that |, & are overloaded as expected"""
  30. assert A & B == And(A, B)
  31. assert A | B == Or(A, B)
  32. assert (A & B) | C == Or(And(A, B), C)
  33. assert A >> B == Implies(A, B)
  34. assert A << B == Implies(B, A)
  35. assert ~A == Not(A)
  36. assert A ^ B == Xor(A, B)
  37. def test_And():
  38. assert And() is true
  39. assert And(A) == A
  40. assert And(True) is true
  41. assert And(False) is false
  42. assert And(True, True) is true
  43. assert And(True, False) is false
  44. assert And(False, False) is false
  45. assert And(True, A) == A
  46. assert And(False, A) is false
  47. assert And(True, True, True) is true
  48. assert And(True, True, A) == A
  49. assert And(True, False, A) is false
  50. assert And(1, A) == A
  51. raises(TypeError, lambda: And(2, A))
  52. assert And(A < 1, A >= 1) is false
  53. e = A > 1
  54. assert And(e, e.canonical) == e.canonical
  55. g, l, ge, le = A > B, B < A, A >= B, B <= A
  56. assert And(g, l, ge, le) == And(ge, g)
  57. assert {And(*i) for i in permutations((l, g, le, ge))} == {And(ge, g)}
  58. assert And(And(Eq(a, 0), Eq(b, 0)), And(Ne(a, 0), Eq(c, 0))) is false
  59. def test_Or():
  60. assert Or() is false
  61. assert Or(A) == A
  62. assert Or(True) is true
  63. assert Or(False) is false
  64. assert Or(True, True) is true
  65. assert Or(True, False) is true
  66. assert Or(False, False) is false
  67. assert Or(True, A) is true
  68. assert Or(False, A) == A
  69. assert Or(True, False, False) is true
  70. assert Or(True, False, A) is true
  71. assert Or(False, False, A) == A
  72. assert Or(1, A) is true
  73. raises(TypeError, lambda: Or(2, A))
  74. assert Or(A < 1, A >= 1) is true
  75. e = A > 1
  76. assert Or(e, e.canonical) == e
  77. g, l, ge, le = A > B, B < A, A >= B, B <= A
  78. assert Or(g, l, ge, le) == Or(g, ge)
  79. def test_Xor():
  80. assert Xor() is false
  81. assert Xor(A) == A
  82. assert Xor(A, A) is false
  83. assert Xor(True, A, A) is true
  84. assert Xor(A, A, A, A, A) == A
  85. assert Xor(True, False, False, A, B) == ~Xor(A, B)
  86. assert Xor(True) is true
  87. assert Xor(False) is false
  88. assert Xor(True, True) is false
  89. assert Xor(True, False) is true
  90. assert Xor(False, False) is false
  91. assert Xor(True, A) == ~A
  92. assert Xor(False, A) == A
  93. assert Xor(True, False, False) is true
  94. assert Xor(True, False, A) == ~A
  95. assert Xor(False, False, A) == A
  96. assert isinstance(Xor(A, B), Xor)
  97. assert Xor(A, B, Xor(C, D)) == Xor(A, B, C, D)
  98. assert Xor(A, B, Xor(B, C)) == Xor(A, C)
  99. assert Xor(A < 1, A >= 1, B) == Xor(0, 1, B) == Xor(1, 0, B)
  100. e = A > 1
  101. assert Xor(e, e.canonical) == Xor(0, 0) == Xor(1, 1)
  102. def test_rewrite_as_And():
  103. expr = x ^ y
  104. assert expr.rewrite(And) == (x | y) & (~x | ~y)
  105. def test_rewrite_as_Or():
  106. expr = x ^ y
  107. assert expr.rewrite(Or) == (x & ~y) | (y & ~x)
  108. def test_rewrite_as_Nand():
  109. expr = (y & z) | (z & ~w)
  110. assert expr.rewrite(Nand) == ~(~(y & z) & ~(z & ~w))
  111. def test_rewrite_as_Nor():
  112. expr = z & (y | ~w)
  113. assert expr.rewrite(Nor) == ~(~z | ~(y | ~w))
  114. def test_Not():
  115. raises(TypeError, lambda: Not(True, False))
  116. assert Not(True) is false
  117. assert Not(False) is true
  118. assert Not(0) is true
  119. assert Not(1) is false
  120. assert Not(2) is false
  121. def test_Nand():
  122. assert Nand() is false
  123. assert Nand(A) == ~A
  124. assert Nand(True) is false
  125. assert Nand(False) is true
  126. assert Nand(True, True) is false
  127. assert Nand(True, False) is true
  128. assert Nand(False, False) is true
  129. assert Nand(True, A) == ~A
  130. assert Nand(False, A) is true
  131. assert Nand(True, True, True) is false
  132. assert Nand(True, True, A) == ~A
  133. assert Nand(True, False, A) is true
  134. def test_Nor():
  135. assert Nor() is true
  136. assert Nor(A) == ~A
  137. assert Nor(True) is false
  138. assert Nor(False) is true
  139. assert Nor(True, True) is false
  140. assert Nor(True, False) is false
  141. assert Nor(False, False) is true
  142. assert Nor(True, A) is false
  143. assert Nor(False, A) == ~A
  144. assert Nor(True, True, True) is false
  145. assert Nor(True, True, A) is false
  146. assert Nor(True, False, A) is false
  147. def test_Xnor():
  148. assert Xnor() is true
  149. assert Xnor(A) == ~A
  150. assert Xnor(A, A) is true
  151. assert Xnor(True, A, A) is false
  152. assert Xnor(A, A, A, A, A) == ~A
  153. assert Xnor(True) is false
  154. assert Xnor(False) is true
  155. assert Xnor(True, True) is true
  156. assert Xnor(True, False) is false
  157. assert Xnor(False, False) is true
  158. assert Xnor(True, A) == A
  159. assert Xnor(False, A) == ~A
  160. assert Xnor(True, False, False) is false
  161. assert Xnor(True, False, A) == A
  162. assert Xnor(False, False, A) == ~A
  163. def test_Implies():
  164. raises(ValueError, lambda: Implies(A, B, C))
  165. assert Implies(True, True) is true
  166. assert Implies(True, False) is false
  167. assert Implies(False, True) is true
  168. assert Implies(False, False) is true
  169. assert Implies(0, A) is true
  170. assert Implies(1, 1) is true
  171. assert Implies(1, 0) is false
  172. assert A >> B == B << A
  173. assert (A < 1) >> (A >= 1) == (A >= 1)
  174. assert (A < 1) >> (S.One > A) is true
  175. assert A >> A is true
  176. def test_Equivalent():
  177. assert Equivalent(A, B) == Equivalent(B, A) == Equivalent(A, B, A)
  178. assert Equivalent() is true
  179. assert Equivalent(A, A) == Equivalent(A) is true
  180. assert Equivalent(True, True) == Equivalent(False, False) is true
  181. assert Equivalent(True, False) == Equivalent(False, True) is false
  182. assert Equivalent(A, True) == A
  183. assert Equivalent(A, False) == Not(A)
  184. assert Equivalent(A, B, True) == A & B
  185. assert Equivalent(A, B, False) == ~A & ~B
  186. assert Equivalent(1, A) == A
  187. assert Equivalent(0, A) == Not(A)
  188. assert Equivalent(A, Equivalent(B, C)) != Equivalent(Equivalent(A, B), C)
  189. assert Equivalent(A < 1, A >= 1) is false
  190. assert Equivalent(A < 1, A >= 1, 0) is false
  191. assert Equivalent(A < 1, A >= 1, 1) is false
  192. assert Equivalent(A < 1, S.One > A) == Equivalent(1, 1) == Equivalent(0, 0)
  193. assert Equivalent(Equality(A, B), Equality(B, A)) is true
  194. def test_Exclusive():
  195. assert Exclusive(False, False, False) is true
  196. assert Exclusive(True, False, False) is true
  197. assert Exclusive(True, True, False) is false
  198. assert Exclusive(True, True, True) is false
  199. def test_equals():
  200. assert Not(Or(A, B)).equals(And(Not(A), Not(B))) is True
  201. assert Equivalent(A, B).equals((A >> B) & (B >> A)) is True
  202. assert ((A | ~B) & (~A | B)).equals((~A & ~B) | (A & B)) is True
  203. assert (A >> B).equals(~A >> ~B) is False
  204. assert (A >> (B >> A)).equals(A >> (C >> A)) is False
  205. raises(NotImplementedError, lambda: (A & B).equals(A > B))
  206. def test_simplification_boolalg():
  207. """
  208. Test working of simplification methods.
  209. """
  210. set1 = [[0, 0, 1], [0, 1, 1], [1, 0, 0], [1, 1, 0]]
  211. set2 = [[0, 0, 0], [0, 1, 0], [1, 0, 1], [1, 1, 1]]
  212. assert SOPform([x, y, z], set1) == Or(And(Not(x), z), And(Not(z), x))
  213. assert Not(SOPform([x, y, z], set2)) == \
  214. Not(Or(And(Not(x), Not(z)), And(x, z)))
  215. assert POSform([x, y, z], set1 + set2) is true
  216. assert SOPform([x, y, z], set1 + set2) is true
  217. assert SOPform([Dummy(), Dummy(), Dummy()], set1 + set2) is true
  218. minterms = [[0, 0, 0, 1], [0, 0, 1, 1], [0, 1, 1, 1], [1, 0, 1, 1],
  219. [1, 1, 1, 1]]
  220. dontcares = [[0, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 1]]
  221. assert (
  222. SOPform([w, x, y, z], minterms, dontcares) ==
  223. Or(And(y, z), And(Not(w), Not(x))))
  224. assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z)
  225. minterms = [1, 3, 7, 11, 15]
  226. dontcares = [0, 2, 5]
  227. assert (
  228. SOPform([w, x, y, z], minterms, dontcares) ==
  229. Or(And(y, z), And(Not(w), Not(x))))
  230. assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z)
  231. minterms = [1, [0, 0, 1, 1], 7, [1, 0, 1, 1],
  232. [1, 1, 1, 1]]
  233. dontcares = [0, [0, 0, 1, 0], 5]
  234. assert (
  235. SOPform([w, x, y, z], minterms, dontcares) ==
  236. Or(And(y, z), And(Not(w), Not(x))))
  237. assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z)
  238. minterms = [1, {y: 1, z: 1}]
  239. dontcares = [0, [0, 0, 1, 0], 5]
  240. assert (
  241. SOPform([w, x, y, z], minterms, dontcares) ==
  242. Or(And(y, z), And(Not(w), Not(x))))
  243. assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z)
  244. minterms = [{y: 1, z: 1}, 1]
  245. dontcares = [[0, 0, 0, 0]]
  246. minterms = [[0, 0, 0]]
  247. raises(ValueError, lambda: SOPform([w, x, y, z], minterms))
  248. raises(ValueError, lambda: POSform([w, x, y, z], minterms))
  249. raises(TypeError, lambda: POSform([w, x, y, z], ["abcdefg"]))
  250. # test simplification
  251. ans = And(A, Or(B, C))
  252. assert simplify_logic(A & (B | C)) == ans
  253. assert simplify_logic((A & B) | (A & C)) == ans
  254. assert simplify_logic(Implies(A, B)) == Or(Not(A), B)
  255. assert simplify_logic(Equivalent(A, B)) == \
  256. Or(And(A, B), And(Not(A), Not(B)))
  257. assert simplify_logic(And(Equality(A, 2), C)) == And(Equality(A, 2), C)
  258. assert simplify_logic(And(Equality(A, 2), A)) == And(Equality(A, 2), A)
  259. assert simplify_logic(And(Equality(A, B), C)) == And(Equality(A, B), C)
  260. assert simplify_logic(Or(And(Equality(A, 3), B), And(Equality(A, 3), C))) \
  261. == And(Equality(A, 3), Or(B, C))
  262. b = (~x & ~y & ~z) | (~x & ~y & z)
  263. e = And(A, b)
  264. assert simplify_logic(e) == A & ~x & ~y
  265. raises(ValueError, lambda: simplify_logic(A & (B | C), form='blabla'))
  266. assert simplify(Or(x <= y, And(x < y, z))) == (x <= y)
  267. assert simplify(Or(x <= y, And(y > x, z))) == (x <= y)
  268. assert simplify(Or(x >= y, And(y < x, z))) == (x >= y)
  269. # Check that expressions with nine variables or more are not simplified
  270. # (without the force-flag)
  271. a, b, c, d, e, f, g, h, j = symbols('a b c d e f g h j')
  272. expr = a & b & c & d & e & f & g & h & j | \
  273. a & b & c & d & e & f & g & h & ~j
  274. # This expression can be simplified to get rid of the j variables
  275. assert simplify_logic(expr) == expr
  276. # Test dontcare
  277. assert simplify_logic((a & b) | c | d, dontcare=(a & b)) == c | d
  278. # check input
  279. ans = SOPform([x, y], [[1, 0]])
  280. assert SOPform([x, y], [[1, 0]]) == ans
  281. assert POSform([x, y], [[1, 0]]) == ans
  282. raises(ValueError, lambda: SOPform([x], [[1]], [[1]]))
  283. assert SOPform([x], [[1]], [[0]]) is true
  284. assert SOPform([x], [[0]], [[1]]) is true
  285. assert SOPform([x], [], []) is false
  286. raises(ValueError, lambda: POSform([x], [[1]], [[1]]))
  287. assert POSform([x], [[1]], [[0]]) is true
  288. assert POSform([x], [[0]], [[1]]) is true
  289. assert POSform([x], [], []) is false
  290. # check working of simplify
  291. assert simplify((A & B) | (A & C)) == And(A, Or(B, C))
  292. assert simplify(And(x, Not(x))) == False
  293. assert simplify(Or(x, Not(x))) == True
  294. assert simplify(And(Eq(x, 0), Eq(x, y))) == And(Eq(x, 0), Eq(y, 0))
  295. assert And(Eq(x - 1, 0), Eq(x, y)).simplify() == And(Eq(x, 1), Eq(y, 1))
  296. assert And(Ne(x - 1, 0), Ne(x, y)).simplify() == And(Ne(x, 1), Ne(x, y))
  297. assert And(Eq(x - 1, 0), Ne(x, y)).simplify() == And(Eq(x, 1), Ne(y, 1))
  298. assert And(Eq(x - 1, 0), Eq(x, z + y), Eq(y + x, 0)).simplify(
  299. ) == And(Eq(x, 1), Eq(y, -1), Eq(z, 2))
  300. assert And(Eq(x - 1, 0), Eq(x + 2, 3)).simplify() == Eq(x, 1)
  301. assert And(Ne(x - 1, 0), Ne(x + 2, 3)).simplify() == Ne(x, 1)
  302. assert And(Eq(x - 1, 0), Eq(x + 2, 2)).simplify() == False
  303. assert And(Ne(x - 1, 0), Ne(x + 2, 2)).simplify(
  304. ) == And(Ne(x, 1), Ne(x, 0))
  305. assert simplify(Xor(x, ~x)) == True
  306. def test_bool_map():
  307. """
  308. Test working of bool_map function.
  309. """
  310. minterms = [[0, 0, 0, 1], [0, 0, 1, 1], [0, 1, 1, 1], [1, 0, 1, 1],
  311. [1, 1, 1, 1]]
  312. assert bool_map(Not(Not(a)), a) == (a, {a: a})
  313. assert bool_map(SOPform([w, x, y, z], minterms),
  314. POSform([w, x, y, z], minterms)) == \
  315. (And(Or(Not(w), y), Or(Not(x), y), z), {x: x, w: w, z: z, y: y})
  316. assert bool_map(SOPform([x, z, y], [[1, 0, 1]]),
  317. SOPform([a, b, c], [[1, 0, 1]])) != False
  318. function1 = SOPform([x, z, y], [[1, 0, 1], [0, 0, 1]])
  319. function2 = SOPform([a, b, c], [[1, 0, 1], [1, 0, 0]])
  320. assert bool_map(function1, function2) == \
  321. (function1, {y: a, z: b})
  322. assert bool_map(Xor(x, y), ~Xor(x, y)) == False
  323. assert bool_map(And(x, y), Or(x, y)) is None
  324. assert bool_map(And(x, y), And(x, y, z)) is None
  325. # issue 16179
  326. assert bool_map(Xor(x, y, z), ~Xor(x, y, z)) == False
  327. assert bool_map(Xor(a, x, y, z), ~Xor(a, x, y, z)) == False
  328. def test_bool_symbol():
  329. """Test that mixing symbols with boolean values
  330. works as expected"""
  331. assert And(A, True) == A
  332. assert And(A, True, True) == A
  333. assert And(A, False) is false
  334. assert And(A, True, False) is false
  335. assert Or(A, True) is true
  336. assert Or(A, False) == A
  337. def test_is_boolean():
  338. assert isinstance(True, Boolean) is False
  339. assert isinstance(true, Boolean) is True
  340. assert 1 == True
  341. assert 1 != true
  342. assert (1 == true) is False
  343. assert 0 == False
  344. assert 0 != false
  345. assert (0 == false) is False
  346. assert true.is_Boolean is True
  347. assert (A & B).is_Boolean
  348. assert (A | B).is_Boolean
  349. assert (~A).is_Boolean
  350. assert (A ^ B).is_Boolean
  351. assert A.is_Boolean != isinstance(A, Boolean)
  352. assert isinstance(A, Boolean)
  353. def test_subs():
  354. assert (A & B).subs(A, True) == B
  355. assert (A & B).subs(A, False) is false
  356. assert (A & B).subs(B, True) == A
  357. assert (A & B).subs(B, False) is false
  358. assert (A & B).subs({A: True, B: True}) is true
  359. assert (A | B).subs(A, True) is true
  360. assert (A | B).subs(A, False) == B
  361. assert (A | B).subs(B, True) is true
  362. assert (A | B).subs(B, False) == A
  363. assert (A | B).subs({A: True, B: True}) is true
  364. """
  365. we test for axioms of boolean algebra
  366. see https://en.wikipedia.org/wiki/Boolean_algebra_(structure)
  367. """
  368. def test_commutative():
  369. """Test for commutativity of And and Or"""
  370. A, B = map(Boolean, symbols('A,B'))
  371. assert A & B == B & A
  372. assert A | B == B | A
  373. def test_and_associativity():
  374. """Test for associativity of And"""
  375. assert (A & B) & C == A & (B & C)
  376. def test_or_assicativity():
  377. assert ((A | B) | C) == (A | (B | C))
  378. def test_double_negation():
  379. a = Boolean()
  380. assert ~(~a) == a
  381. # test methods
  382. def test_eliminate_implications():
  383. assert eliminate_implications(Implies(A, B, evaluate=False)) == (~A) | B
  384. assert eliminate_implications(
  385. A >> (C >> Not(B))) == Or(Or(Not(B), Not(C)), Not(A))
  386. assert eliminate_implications(Equivalent(A, B, C, D)) == \
  387. (~A | B) & (~B | C) & (~C | D) & (~D | A)
  388. def test_conjuncts():
  389. assert conjuncts(A & B & C) == {A, B, C}
  390. assert conjuncts((A | B) & C) == {A | B, C}
  391. assert conjuncts(A) == {A}
  392. assert conjuncts(True) == {True}
  393. assert conjuncts(False) == {False}
  394. def test_disjuncts():
  395. assert disjuncts(A | B | C) == {A, B, C}
  396. assert disjuncts((A | B) & C) == {(A | B) & C}
  397. assert disjuncts(A) == {A}
  398. assert disjuncts(True) == {True}
  399. assert disjuncts(False) == {False}
  400. def test_distribute():
  401. assert distribute_and_over_or(Or(And(A, B), C)) == And(Or(A, C), Or(B, C))
  402. assert distribute_or_over_and(And(A, Or(B, C))) == Or(And(A, B), And(A, C))
  403. assert distribute_xor_over_and(And(A, Xor(B, C))) == Xor(And(A, B), And(A, C))
  404. def test_to_anf():
  405. x, y, z = symbols('x,y,z')
  406. assert to_anf(And(x, y)) == And(x, y)
  407. assert to_anf(Or(x, y)) == Xor(x, y, And(x, y))
  408. assert to_anf(Or(Implies(x, y), And(x, y), y)) == \
  409. Xor(x, True, x & y, remove_true=False)
  410. assert to_anf(Or(Nand(x, y), Nor(x, y), Xnor(x, y), Implies(x, y))) == True
  411. assert to_anf(Or(x, Not(y), Nor(x, z), And(x, y), Nand(y, z))) == \
  412. Xor(True, And(y, z), And(x, y, z), remove_true=False)
  413. assert to_anf(Xor(x, y)) == Xor(x, y)
  414. assert to_anf(Not(x)) == Xor(x, True, remove_true=False)
  415. assert to_anf(Nand(x, y)) == Xor(True, And(x, y), remove_true=False)
  416. assert to_anf(Nor(x, y)) == Xor(x, y, True, And(x, y), remove_true=False)
  417. assert to_anf(Implies(x, y)) == Xor(x, True, And(x, y), remove_true=False)
  418. assert to_anf(Equivalent(x, y)) == Xor(x, y, True, remove_true=False)
  419. assert to_anf(Nand(x | y, x >> y), deep=False) == \
  420. Xor(True, And(Or(x, y), Implies(x, y)), remove_true=False)
  421. assert to_anf(Nor(x ^ y, x & y), deep=False) == \
  422. Xor(True, Or(Xor(x, y), And(x, y)), remove_true=False)
  423. # issue 25218
  424. assert to_anf(x ^ ~(x ^ y ^ ~y)) == False
  425. def test_to_nnf():
  426. assert to_nnf(true) is true
  427. assert to_nnf(false) is false
  428. assert to_nnf(A) == A
  429. assert to_nnf(A | ~A | B) is true
  430. assert to_nnf(A & ~A & B) is false
  431. assert to_nnf(A >> B) == ~A | B
  432. assert to_nnf(Equivalent(A, B, C)) == (~A | B) & (~B | C) & (~C | A)
  433. assert to_nnf(A ^ B ^ C) == \
  434. (A | B | C) & (~A | ~B | C) & (A | ~B | ~C) & (~A | B | ~C)
  435. assert to_nnf(ITE(A, B, C)) == (~A | B) & (A | C)
  436. assert to_nnf(Not(A | B | C)) == ~A & ~B & ~C
  437. assert to_nnf(Not(A & B & C)) == ~A | ~B | ~C
  438. assert to_nnf(Not(A >> B)) == A & ~B
  439. assert to_nnf(Not(Equivalent(A, B, C))) == And(Or(A, B, C), Or(~A, ~B, ~C))
  440. assert to_nnf(Not(A ^ B ^ C)) == \
  441. (~A | B | C) & (A | ~B | C) & (A | B | ~C) & (~A | ~B | ~C)
  442. assert to_nnf(Not(ITE(A, B, C))) == (~A | ~B) & (A | ~C)
  443. assert to_nnf((A >> B) ^ (B >> A)) == (A & ~B) | (~A & B)
  444. assert to_nnf((A >> B) ^ (B >> A), False) == \
  445. (~A | ~B | A | B) & ((A & ~B) | (~A & B))
  446. assert ITE(A, 1, 0).to_nnf() == A
  447. assert ITE(A, 0, 1).to_nnf() == ~A
  448. # although ITE can hold non-Boolean, it will complain if
  449. # an attempt is made to convert the ITE to Boolean nnf
  450. raises(TypeError, lambda: ITE(A < 1, [1], B).to_nnf())
  451. def test_to_cnf():
  452. assert to_cnf(~(B | C)) == And(Not(B), Not(C))
  453. assert to_cnf((A & B) | C) == And(Or(A, C), Or(B, C))
  454. assert to_cnf(A >> B) == (~A) | B
  455. assert to_cnf(A >> (B & C)) == (~A | B) & (~A | C)
  456. assert to_cnf(A & (B | C) | ~A & (B | C), True) == B | C
  457. assert to_cnf(A & B) == And(A, B)
  458. assert to_cnf(Equivalent(A, B)) == And(Or(A, Not(B)), Or(B, Not(A)))
  459. assert to_cnf(Equivalent(A, B & C)) == \
  460. (~A | B) & (~A | C) & (~B | ~C | A)
  461. assert to_cnf(Equivalent(A, B | C), True) == \
  462. And(Or(Not(B), A), Or(Not(C), A), Or(B, C, Not(A)))
  463. assert to_cnf(A + 1) == A + 1
  464. def test_issue_18904():
  465. x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 = symbols('x1:16')
  466. eq = ((x1 & x2 & x3 & x4 & x5 & x6 & x7 & x8 & x9) |
  467. (x1 & x2 & x3 & x4 & x5 & x6 & x7 & x10 & x9) |
  468. (x1 & x11 & x3 & x12 & x5 & x13 & x14 & x15 & x9))
  469. assert is_cnf(to_cnf(eq))
  470. raises(ValueError, lambda: to_cnf(eq, simplify=True))
  471. for f, t in zip((And, Or), (to_cnf, to_dnf)):
  472. eq = f(x1, x2, x3, x4, x5, x6, x7, x8, x9)
  473. raises(ValueError, lambda: to_cnf(eq, simplify=True))
  474. assert t(eq, simplify=True, force=True) == eq
  475. def test_issue_9949():
  476. assert is_cnf(to_cnf((b > -5) | (a > 2) & (a < 4)))
  477. def test_to_CNF():
  478. assert CNF.CNF_to_cnf(CNF.to_CNF(~(B | C))) == to_cnf(~(B | C))
  479. assert CNF.CNF_to_cnf(CNF.to_CNF((A & B) | C)) == to_cnf((A & B) | C)
  480. assert CNF.CNF_to_cnf(CNF.to_CNF(A >> B)) == to_cnf(A >> B)
  481. assert CNF.CNF_to_cnf(CNF.to_CNF(A >> (B & C))) == to_cnf(A >> (B & C))
  482. assert CNF.CNF_to_cnf(CNF.to_CNF(A & (B | C) | ~A & (B | C))) == to_cnf(A & (B | C) | ~A & (B | C))
  483. assert CNF.CNF_to_cnf(CNF.to_CNF(A & B)) == to_cnf(A & B)
  484. def test_to_dnf():
  485. assert to_dnf(~(B | C)) == And(Not(B), Not(C))
  486. assert to_dnf(A & (B | C)) == Or(And(A, B), And(A, C))
  487. assert to_dnf(A >> B) == (~A) | B
  488. assert to_dnf(A >> (B & C)) == (~A) | (B & C)
  489. assert to_dnf(A | B) == A | B
  490. assert to_dnf(Equivalent(A, B), True) == \
  491. Or(And(A, B), And(Not(A), Not(B)))
  492. assert to_dnf(Equivalent(A, B & C), True) == \
  493. Or(And(A, B, C), And(Not(A), Not(B)), And(Not(A), Not(C)))
  494. assert to_dnf(A + 1) == A + 1
  495. def test_to_int_repr():
  496. x, y, z = map(Boolean, symbols('x,y,z'))
  497. def sorted_recursive(arg):
  498. try:
  499. return sorted(sorted_recursive(x) for x in arg)
  500. except TypeError: # arg is not a sequence
  501. return arg
  502. assert sorted_recursive(to_int_repr([x | y, z | x], [x, y, z])) == \
  503. sorted_recursive([[1, 2], [1, 3]])
  504. assert sorted_recursive(to_int_repr([x | y, z | ~x], [x, y, z])) == \
  505. sorted_recursive([[1, 2], [3, -1]])
  506. def test_is_anf():
  507. x, y = symbols('x,y')
  508. assert is_anf(true) is True
  509. assert is_anf(false) is True
  510. assert is_anf(x) is True
  511. assert is_anf(And(x, y)) is True
  512. assert is_anf(Xor(x, y, And(x, y))) is True
  513. assert is_anf(Xor(x, y, Or(x, y))) is False
  514. assert is_anf(Xor(Not(x), y)) is False
  515. def test_is_nnf():
  516. assert is_nnf(true) is True
  517. assert is_nnf(A) is True
  518. assert is_nnf(~A) is True
  519. assert is_nnf(A & B) is True
  520. assert is_nnf((A & B) | (~A & A) | (~B & B) | (~A & ~B), False) is True
  521. assert is_nnf((A | B) & (~A | ~B)) is True
  522. assert is_nnf(Not(Or(A, B))) is False
  523. assert is_nnf(A ^ B) is False
  524. assert is_nnf((A & B) | (~A & A) | (~B & B) | (~A & ~B), True) is False
  525. def test_is_cnf():
  526. assert is_cnf(x) is True
  527. assert is_cnf(x | y | z) is True
  528. assert is_cnf(x & y & z) is True
  529. assert is_cnf((x | y) & z) is True
  530. assert is_cnf((x & y) | z) is False
  531. assert is_cnf(~(x & y) | z) is False
  532. def test_is_dnf():
  533. assert is_dnf(x) is True
  534. assert is_dnf(x | y | z) is True
  535. assert is_dnf(x & y & z) is True
  536. assert is_dnf((x & y) | z) is True
  537. assert is_dnf((x | y) & z) is False
  538. assert is_dnf(~(x | y) & z) is False
  539. def test_ITE():
  540. A, B, C = symbols('A:C')
  541. assert ITE(True, False, True) is false
  542. assert ITE(True, True, False) is true
  543. assert ITE(False, True, False) is false
  544. assert ITE(False, False, True) is true
  545. assert isinstance(ITE(A, B, C), ITE)
  546. A = True
  547. assert ITE(A, B, C) == B
  548. A = False
  549. assert ITE(A, B, C) == C
  550. B = True
  551. assert ITE(And(A, B), B, C) == C
  552. assert ITE(Or(A, False), And(B, True), False) is false
  553. assert ITE(x, A, B) == Not(x)
  554. assert ITE(x, B, A) == x
  555. assert ITE(1, x, y) == x
  556. assert ITE(0, x, y) == y
  557. raises(TypeError, lambda: ITE(2, x, y))
  558. raises(TypeError, lambda: ITE(1, [], y))
  559. raises(TypeError, lambda: ITE(1, (), y))
  560. raises(TypeError, lambda: ITE(1, y, []))
  561. assert ITE(1, 1, 1) is S.true
  562. assert isinstance(ITE(1, 1, 1, evaluate=False), ITE)
  563. assert ITE(Eq(x, True), y, x) == ITE(x, y, x)
  564. assert ITE(Eq(x, False), y, x) == ITE(~x, y, x)
  565. assert ITE(Ne(x, True), y, x) == ITE(~x, y, x)
  566. assert ITE(Ne(x, False), y, x) == ITE(x, y, x)
  567. assert ITE(Eq(S.true, x), y, x) == ITE(x, y, x)
  568. assert ITE(Eq(S.false, x), y, x) == ITE(~x, y, x)
  569. assert ITE(Ne(S.true, x), y, x) == ITE(~x, y, x)
  570. assert ITE(Ne(S.false, x), y, x) == ITE(x, y, x)
  571. # 0 and 1 in the context are not treated as True/False
  572. # so the equality must always be False since dissimilar
  573. # objects cannot be equal
  574. assert ITE(Eq(x, 0), y, x) == x
  575. assert ITE(Eq(x, 1), y, x) == x
  576. assert ITE(Ne(x, 0), y, x) == y
  577. assert ITE(Ne(x, 1), y, x) == y
  578. assert ITE(Eq(x, 0), y, z).subs(x, 0) == y
  579. assert ITE(Eq(x, 0), y, z).subs(x, 1) == z
  580. raises(ValueError, lambda: ITE(x > 1, y, x, z))
  581. def test_is_literal():
  582. assert is_literal(True) is True
  583. assert is_literal(False) is True
  584. assert is_literal(A) is True
  585. assert is_literal(~A) is True
  586. assert is_literal(Or(A, B)) is False
  587. assert is_literal(Q.zero(A)) is True
  588. assert is_literal(Not(Q.zero(A))) is True
  589. assert is_literal(Or(A, B)) is False
  590. assert is_literal(And(Q.zero(A), Q.zero(B))) is False
  591. assert is_literal(x < 3)
  592. assert not is_literal(x + y < 3)
  593. def test_operators():
  594. # Mostly test __and__, __rand__, and so on
  595. assert True & A == A & True == A
  596. assert False & A == A & False == False
  597. assert A & B == And(A, B)
  598. assert True | A == A | True == True
  599. assert False | A == A | False == A
  600. assert A | B == Or(A, B)
  601. assert ~A == Not(A)
  602. assert True >> A == A << True == A
  603. assert False >> A == A << False == True
  604. assert A >> True == True << A == True
  605. assert A >> False == False << A == ~A
  606. assert A >> B == B << A == Implies(A, B)
  607. assert True ^ A == A ^ True == ~A
  608. assert False ^ A == A ^ False == A
  609. assert A ^ B == Xor(A, B)
  610. def test_true_false():
  611. assert true is S.true
  612. assert false is S.false
  613. assert true is not True
  614. assert false is not False
  615. assert true
  616. assert not false
  617. assert true == True
  618. assert false == False
  619. assert not (true == False)
  620. assert not (false == True)
  621. assert not (true == false)
  622. assert hash(true) == hash(True)
  623. assert hash(false) == hash(False)
  624. assert len({true, True}) == len({false, False}) == 1
  625. assert isinstance(true, BooleanAtom)
  626. assert isinstance(false, BooleanAtom)
  627. # We don't want to subclass from bool, because bool subclasses from
  628. # int. But operators like &, |, ^, <<, >>, and ~ act differently on 0 and
  629. # 1 then we want them to on true and false. See the docstrings of the
  630. # various And, Or, etc. functions for examples.
  631. assert not isinstance(true, bool)
  632. assert not isinstance(false, bool)
  633. # Note: using 'is' comparison is important here. We want these to return
  634. # true and false, not True and False
  635. assert Not(true) is false
  636. assert Not(True) is false
  637. assert Not(false) is true
  638. assert Not(False) is true
  639. assert ~true is false
  640. assert ~false is true
  641. for T, F in product((True, true), (False, false)):
  642. assert And(T, F) is false
  643. assert And(F, T) is false
  644. assert And(F, F) is false
  645. assert And(T, T) is true
  646. assert And(T, x) == x
  647. assert And(F, x) is false
  648. if not (T is True and F is False):
  649. assert T & F is false
  650. assert F & T is false
  651. if F is not False:
  652. assert F & F is false
  653. if T is not True:
  654. assert T & T is true
  655. assert Or(T, F) is true
  656. assert Or(F, T) is true
  657. assert Or(F, F) is false
  658. assert Or(T, T) is true
  659. assert Or(T, x) is true
  660. assert Or(F, x) == x
  661. if not (T is True and F is False):
  662. assert T | F is true
  663. assert F | T is true
  664. if F is not False:
  665. assert F | F is false
  666. if T is not True:
  667. assert T | T is true
  668. assert Xor(T, F) is true
  669. assert Xor(F, T) is true
  670. assert Xor(F, F) is false
  671. assert Xor(T, T) is false
  672. assert Xor(T, x) == ~x
  673. assert Xor(F, x) == x
  674. if not (T is True and F is False):
  675. assert T ^ F is true
  676. assert F ^ T is true
  677. if F is not False:
  678. assert F ^ F is false
  679. if T is not True:
  680. assert T ^ T is false
  681. assert Nand(T, F) is true
  682. assert Nand(F, T) is true
  683. assert Nand(F, F) is true
  684. assert Nand(T, T) is false
  685. assert Nand(T, x) == ~x
  686. assert Nand(F, x) is true
  687. assert Nor(T, F) is false
  688. assert Nor(F, T) is false
  689. assert Nor(F, F) is true
  690. assert Nor(T, T) is false
  691. assert Nor(T, x) is false
  692. assert Nor(F, x) == ~x
  693. assert Implies(T, F) is false
  694. assert Implies(F, T) is true
  695. assert Implies(F, F) is true
  696. assert Implies(T, T) is true
  697. assert Implies(T, x) == x
  698. assert Implies(F, x) is true
  699. assert Implies(x, T) is true
  700. assert Implies(x, F) == ~x
  701. if not (T is True and F is False):
  702. assert T >> F is false
  703. assert F << T is false
  704. assert F >> T is true
  705. assert T << F is true
  706. if F is not False:
  707. assert F >> F is true
  708. assert F << F is true
  709. if T is not True:
  710. assert T >> T is true
  711. assert T << T is true
  712. assert Equivalent(T, F) is false
  713. assert Equivalent(F, T) is false
  714. assert Equivalent(F, F) is true
  715. assert Equivalent(T, T) is true
  716. assert Equivalent(T, x) == x
  717. assert Equivalent(F, x) == ~x
  718. assert Equivalent(x, T) == x
  719. assert Equivalent(x, F) == ~x
  720. assert ITE(T, T, T) is true
  721. assert ITE(T, T, F) is true
  722. assert ITE(T, F, T) is false
  723. assert ITE(T, F, F) is false
  724. assert ITE(F, T, T) is true
  725. assert ITE(F, T, F) is false
  726. assert ITE(F, F, T) is true
  727. assert ITE(F, F, F) is false
  728. assert all(i.simplify(1, 2) is i for i in (S.true, S.false))
  729. def test_bool_as_set():
  730. assert ITE(y <= 0, False, y >= 1).as_set() == Interval(1, oo)
  731. assert And(x <= 2, x >= -2).as_set() == Interval(-2, 2)
  732. assert Or(x >= 2, x <= -2).as_set() == Interval(-oo, -2) + Interval(2, oo)
  733. assert Not(x > 2).as_set() == Interval(-oo, 2)
  734. # issue 10240
  735. assert Not(And(x > 2, x < 3)).as_set() == \
  736. Union(Interval(-oo, 2), Interval(3, oo))
  737. assert true.as_set() == S.UniversalSet
  738. assert false.as_set() is S.EmptySet
  739. assert x.as_set() == S.UniversalSet
  740. assert And(Or(x < 1, x > 3), x < 2).as_set() == Interval.open(-oo, 1)
  741. assert And(x < 1, sin(x) < 3).as_set() == (x < 1).as_set()
  742. raises(NotImplementedError, lambda: (sin(x) < 1).as_set())
  743. # watch for object morph in as_set
  744. assert Eq(-1, cos(2 * x) ** 2 / sin(2 * x) ** 2).as_set() is S.EmptySet
  745. @XFAIL
  746. def test_multivariate_bool_as_set():
  747. x, y = symbols('x,y')
  748. assert And(x >= 0, y >= 0).as_set() == Interval(0, oo) * Interval(0, oo)
  749. assert Or(x >= 0, y >= 0).as_set() == S.Reals * S.Reals - \
  750. Interval(-oo, 0, True, True) * Interval(-oo, 0, True, True)
  751. def test_all_or_nothing():
  752. x = symbols('x', extended_real=True)
  753. args = x >= -oo, x <= oo
  754. v = And(*args)
  755. if v.func is And:
  756. assert len(v.args) == len(args) - args.count(S.true)
  757. else:
  758. assert v == True
  759. v = Or(*args)
  760. if v.func is Or:
  761. assert len(v.args) == 2
  762. else:
  763. assert v == True
  764. def test_canonical_atoms():
  765. assert true.canonical == true
  766. assert false.canonical == false
  767. def test_negated_atoms():
  768. assert true.negated == false
  769. assert false.negated == true
  770. def test_issue_8777():
  771. assert And(x > 2, x < oo).as_set() == Interval(2, oo, left_open=True)
  772. assert And(x >= 1, x < oo).as_set() == Interval(1, oo)
  773. assert (x < oo).as_set() == Interval(-oo, oo)
  774. assert (x > -oo).as_set() == Interval(-oo, oo)
  775. def test_issue_8975():
  776. assert Or(And(-oo < x, x <= -2), And(2 <= x, x < oo)).as_set() == \
  777. Interval(-oo, -2) + Interval(2, oo)
  778. def test_term_to_integer():
  779. assert term_to_integer([1, 0, 1, 0, 0, 1, 0]) == 82
  780. assert term_to_integer('0010101000111001') == 10809
  781. def test_issue_21971():
  782. a, b, c, d = symbols('a b c d')
  783. f = a & b & c | a & c
  784. assert f.subs(a & c, d) == b & d | d
  785. assert f.subs(a & b & c, d) == a & c | d
  786. f = (a | b | c) & (a | c)
  787. assert f.subs(a | c, d) == (b | d) & d
  788. assert f.subs(a | b | c, d) == (a | c) & d
  789. f = (a ^ b ^ c) & (a ^ c)
  790. assert f.subs(a ^ c, d) == (b ^ d) & d
  791. assert f.subs(a ^ b ^ c, d) == (a ^ c) & d
  792. def test_truth_table():
  793. assert list(truth_table(And(x, y), [x, y], input=False)) == \
  794. [False, False, False, True]
  795. assert list(truth_table(x | y, [x, y], input=False)) == \
  796. [False, True, True, True]
  797. assert list(truth_table(x >> y, [x, y], input=False)) == \
  798. [True, True, False, True]
  799. assert list(truth_table(And(x, y), [x, y])) == \
  800. [([0, 0], False), ([0, 1], False), ([1, 0], False), ([1, 1], True)]
  801. def test_issue_8571():
  802. for t in (S.true, S.false):
  803. raises(TypeError, lambda: +t)
  804. raises(TypeError, lambda: -t)
  805. raises(TypeError, lambda: abs(t))
  806. # use int(bool(t)) to get 0 or 1
  807. raises(TypeError, lambda: int(t))
  808. for o in [S.Zero, S.One, x]:
  809. for _ in range(2):
  810. raises(TypeError, lambda: o + t)
  811. raises(TypeError, lambda: o - t)
  812. raises(TypeError, lambda: o % t)
  813. raises(TypeError, lambda: o * t)
  814. raises(TypeError, lambda: o / t)
  815. raises(TypeError, lambda: o ** t)
  816. o, t = t, o # do again in reversed order
  817. def test_expand_relational():
  818. n = symbols('n', negative=True)
  819. p, q = symbols('p q', positive=True)
  820. r = ((n + q * (-n / q + 1)) / (q * (-n / q + 1)) < 0)
  821. assert r is not S.false
  822. assert r.expand() is S.false
  823. assert (q > 0).expand() is S.true
  824. def test_issue_12717():
  825. assert S.true.is_Atom == True
  826. assert S.false.is_Atom == True
  827. def test_as_Boolean():
  828. nz = symbols('nz', nonzero=True)
  829. assert all(as_Boolean(i) is S.true for i in (True, S.true, 1, nz))
  830. z = symbols('z', zero=True)
  831. assert all(as_Boolean(i) is S.false for i in (False, S.false, 0, z))
  832. assert all(as_Boolean(i) == i for i in (x, x < 0))
  833. for i in (2, S(2), x + 1, []):
  834. raises(TypeError, lambda: as_Boolean(i))
  835. def test_binary_symbols():
  836. assert ITE(x < 1, y, z).binary_symbols == {y, z}
  837. for f in (Eq, Ne):
  838. assert f(x, 1).binary_symbols == set()
  839. assert f(x, True).binary_symbols == {x}
  840. assert f(x, False).binary_symbols == {x}
  841. assert S.true.binary_symbols == set()
  842. assert S.false.binary_symbols == set()
  843. assert x.binary_symbols == {x}
  844. assert And(x, Eq(y, False), Eq(z, 1)).binary_symbols == {x, y}
  845. assert Q.prime(x).binary_symbols == set()
  846. assert Q.lt(x, 1).binary_symbols == set()
  847. assert Q.is_true(x).binary_symbols == {x}
  848. assert Q.eq(x, True).binary_symbols == {x}
  849. assert Q.prime(x).binary_symbols == set()
  850. def test_BooleanFunction_diff():
  851. assert And(x, y).diff(x) == Piecewise((0, Eq(y, False)), (1, True))
  852. def test_issue_14700():
  853. A, B, C, D, E, F, G, H = symbols('A B C D E F G H')
  854. q = ((B & D & H & ~F) | (B & H & ~C & ~D) | (B & H & ~C & ~F) |
  855. (B & H & ~D & ~G) | (B & H & ~F & ~G) | (C & G & ~B & ~D) |
  856. (C & G & ~D & ~H) | (C & G & ~F & ~H) | (D & F & H & ~B) |
  857. (D & F & ~G & ~H) | (B & D & F & ~C & ~H) | (D & E & F & ~B & ~C) |
  858. (D & F & ~A & ~B & ~C) | (D & F & ~A & ~C & ~H) |
  859. (A & B & D & F & ~E & ~H))
  860. soldnf = ((B & D & H & ~F) | (D & F & H & ~B) | (B & H & ~C & ~D) |
  861. (B & H & ~D & ~G) | (C & G & ~B & ~D) | (C & G & ~D & ~H) |
  862. (C & G & ~F & ~H) | (D & F & ~G & ~H) | (D & E & F & ~C & ~H) |
  863. (D & F & ~A & ~C & ~H) | (A & B & D & F & ~E & ~H))
  864. solcnf = ((B | C | D) & (B | D | G) & (C | D | H) & (C | F | H) &
  865. (D | G | H) & (F | G | H) & (B | F | ~D | ~H) &
  866. (~B | ~D | ~F | ~H) & (D | ~B | ~C | ~G | ~H) &
  867. (A | H | ~C | ~D | ~F | ~G) & (H | ~C | ~D | ~E | ~F | ~G) &
  868. (B | E | H | ~A | ~D | ~F | ~G))
  869. assert simplify_logic(q, "dnf") == soldnf
  870. assert simplify_logic(q, "cnf") == solcnf
  871. minterms = [[0, 1, 0, 0], [0, 1, 0, 1], [0, 1, 1, 0], [0, 1, 1, 1],
  872. [0, 0, 1, 1], [1, 0, 1, 1]]
  873. dontcares = [[1, 0, 0, 0], [1, 0, 0, 1], [1, 1, 0, 0], [1, 1, 0, 1]]
  874. assert SOPform([w, x, y, z], minterms) == (x & ~w) | (y & z & ~x)
  875. # Should not be more complicated with don't cares
  876. assert SOPform([w, x, y, z], minterms, dontcares) == \
  877. (x & ~w) | (y & z & ~x)
  878. def test_issue_25115():
  879. cond = Contains(x, S.Integers)
  880. # Previously this raised an exception:
  881. assert simplify_logic(cond) == cond
  882. def test_relational_simplification():
  883. w, x, y, z = symbols('w x y z', real=True)
  884. d, e = symbols('d e', real=False)
  885. # Test all combinations or sign and order
  886. assert Or(x >= y, x < y).simplify() == S.true
  887. assert Or(x >= y, y > x).simplify() == S.true
  888. assert Or(x >= y, -x > -y).simplify() == S.true
  889. assert Or(x >= y, -y < -x).simplify() == S.true
  890. assert Or(-x <= -y, x < y).simplify() == S.true
  891. assert Or(-x <= -y, -x > -y).simplify() == S.true
  892. assert Or(-x <= -y, y > x).simplify() == S.true
  893. assert Or(-x <= -y, -y < -x).simplify() == S.true
  894. assert Or(y <= x, x < y).simplify() == S.true
  895. assert Or(y <= x, y > x).simplify() == S.true
  896. assert Or(y <= x, -x > -y).simplify() == S.true
  897. assert Or(y <= x, -y < -x).simplify() == S.true
  898. assert Or(-y >= -x, x < y).simplify() == S.true
  899. assert Or(-y >= -x, y > x).simplify() == S.true
  900. assert Or(-y >= -x, -x > -y).simplify() == S.true
  901. assert Or(-y >= -x, -y < -x).simplify() == S.true
  902. assert Or(x < y, x >= y).simplify() == S.true
  903. assert Or(y > x, x >= y).simplify() == S.true
  904. assert Or(-x > -y, x >= y).simplify() == S.true
  905. assert Or(-y < -x, x >= y).simplify() == S.true
  906. assert Or(x < y, -x <= -y).simplify() == S.true
  907. assert Or(-x > -y, -x <= -y).simplify() == S.true
  908. assert Or(y > x, -x <= -y).simplify() == S.true
  909. assert Or(-y < -x, -x <= -y).simplify() == S.true
  910. assert Or(x < y, y <= x).simplify() == S.true
  911. assert Or(y > x, y <= x).simplify() == S.true
  912. assert Or(-x > -y, y <= x).simplify() == S.true
  913. assert Or(-y < -x, y <= x).simplify() == S.true
  914. assert Or(x < y, -y >= -x).simplify() == S.true
  915. assert Or(y > x, -y >= -x).simplify() == S.true
  916. assert Or(-x > -y, -y >= -x).simplify() == S.true
  917. assert Or(-y < -x, -y >= -x).simplify() == S.true
  918. # Some other tests
  919. assert Or(x >= y, w < z, x <= y).simplify() == S.true
  920. assert And(x >= y, x < y).simplify() == S.false
  921. assert Or(x >= y, Eq(y, x)).simplify() == (x >= y)
  922. assert And(x >= y, Eq(y, x)).simplify() == Eq(x, y)
  923. assert And(Eq(x, y), x >= 1, 2 < y, y >= 5, z < y).simplify() == \
  924. (Eq(x, y) & (x >= 1) & (y >= 5) & (y > z))
  925. assert Or(Eq(x, y), x >= y, w < y, z < y).simplify() == \
  926. (x >= y) | (y > z) | (w < y)
  927. assert And(Eq(x, y), x >= y, w < y, y >= z, z < y).simplify() == \
  928. Eq(x, y) & (y > z) & (w < y)
  929. # assert And(Eq(x, y), x >= y, w < y, y >= z, z < y).simplify(relational_minmax=True) == \
  930. # And(Eq(x, y), y > Max(w, z))
  931. # assert Or(Eq(x, y), x >= 1, 2 < y, y >= 5, z < y).simplify(relational_minmax=True) == \
  932. # (Eq(x, y) | (x >= 1) | (y > Min(2, z)))
  933. assert And(Eq(x, y), x >= 1, 2 < y, y >= 5, z < y).simplify() == \
  934. (Eq(x, y) & (x >= 1) & (y >= 5) & (y > z))
  935. assert (Eq(x, y) & Eq(d, e) & (x >= y) & (d >= e)).simplify() == \
  936. (Eq(x, y) & Eq(d, e) & (d >= e))
  937. assert And(Eq(x, y), Eq(x, -y)).simplify() == And(Eq(x, 0), Eq(y, 0))
  938. assert Xor(x >= y, x <= y).simplify() == Ne(x, y)
  939. assert And(x > 1, x < -1, Eq(x, y)).simplify() == S.false
  940. # From #16690
  941. assert And(x >= y, Eq(y, 0)).simplify() == And(x >= 0, Eq(y, 0))
  942. assert Or(Ne(x, 1), Ne(x, 2)).simplify() == S.true
  943. assert And(Eq(x, 1), Ne(2, x)).simplify() == Eq(x, 1)
  944. assert Or(Eq(x, 1), Ne(2, x)).simplify() == Ne(x, 2)
  945. def test_issue_8373():
  946. x = symbols('x', real=True)
  947. assert Or(x < 1, x > -1).simplify() == S.true
  948. assert Or(x < 1, x >= 1).simplify() == S.true
  949. assert And(x < 1, x >= 1).simplify() == S.false
  950. assert Or(x <= 1, x >= 1).simplify() == S.true
  951. def test_issue_7950():
  952. x = symbols('x', real=True)
  953. assert And(Eq(x, 1), Eq(x, 2)).simplify() == S.false
  954. @slow
  955. def test_relational_simplification_numerically():
  956. def test_simplification_numerically_function(original, simplified):
  957. symb = original.free_symbols
  958. n = len(symb)
  959. valuelist = list(set(combinations(list(range(-(n - 1), n)) * n, n)))
  960. for values in valuelist:
  961. sublist = dict(zip(symb, values))
  962. originalvalue = original.subs(sublist)
  963. simplifiedvalue = simplified.subs(sublist)
  964. assert originalvalue == simplifiedvalue, "Original: {}\nand" \
  965. " simplified: {}\ndo not evaluate to the same value for {}" \
  966. "".format(original, simplified, sublist)
  967. w, x, y, z = symbols('w x y z', real=True)
  968. d, e = symbols('d e', real=False)
  969. expressions = (And(Eq(x, y), x >= y, w < y, y >= z, z < y),
  970. And(Eq(x, y), x >= 1, 2 < y, y >= 5, z < y),
  971. Or(Eq(x, y), x >= 1, 2 < y, y >= 5, z < y),
  972. And(x >= y, Eq(y, x)),
  973. Or(And(Eq(x, y), x >= y, w < y, Or(y >= z, z < y)),
  974. And(Eq(x, y), x >= 1, 2 < y, y >= -1, z < y)),
  975. (Eq(x, y) & Eq(d, e) & (x >= y) & (d >= e)),
  976. )
  977. for expression in expressions:
  978. test_simplification_numerically_function(expression,
  979. expression.simplify())
  980. def test_relational_simplification_patterns_numerically():
  981. from sympy.core import Wild
  982. from sympy.logic.boolalg import _simplify_patterns_and, \
  983. _simplify_patterns_or, _simplify_patterns_xor
  984. a = Wild('a')
  985. b = Wild('b')
  986. c = Wild('c')
  987. symb = [a, b, c]
  988. patternlists = [[And, _simplify_patterns_and()],
  989. [Or, _simplify_patterns_or()],
  990. [Xor, _simplify_patterns_xor()]]
  991. valuelist = list(set(combinations(list(range(-2, 3)) * 3, 3)))
  992. # Skip combinations of +/-2 and 0, except for all 0
  993. valuelist = [v for v in valuelist if any(w % 2 for w in v) or not any(v)]
  994. for func, patternlist in patternlists:
  995. for pattern in patternlist:
  996. original = func(*pattern[0].args)
  997. simplified = pattern[1]
  998. for values in valuelist:
  999. sublist = dict(zip(symb, values))
  1000. originalvalue = original.xreplace(sublist)
  1001. simplifiedvalue = simplified.xreplace(sublist)
  1002. assert originalvalue == simplifiedvalue, "Original: {}\nand" \
  1003. " simplified: {}\ndo not evaluate to the same value for" \
  1004. "{}".format(pattern[0], simplified, sublist)
  1005. def test_issue_16803():
  1006. n = symbols('n')
  1007. # No simplification done, but should not raise an exception
  1008. assert ((n > 3) | (n < 0) | ((n > 0) & (n < 3))).simplify() == \
  1009. (n > 3) | (n < 0) | ((n > 0) & (n < 3))
  1010. def test_issue_17530():
  1011. r = {x: oo, y: oo}
  1012. assert Or(x + y > 0, x - y < 0).subs(r)
  1013. assert not And(x + y < 0, x - y < 0).subs(r)
  1014. raises(TypeError, lambda: Or(x + y < 0, x - y < 0).subs(r))
  1015. raises(TypeError, lambda: And(x + y > 0, x - y < 0).subs(r))
  1016. raises(TypeError, lambda: And(x + y > 0, x - y < 0).subs(r))
  1017. def test_anf_coeffs():
  1018. assert anf_coeffs([1, 0]) == [1, 1]
  1019. assert anf_coeffs([0, 0, 0, 1]) == [0, 0, 0, 1]
  1020. assert anf_coeffs([0, 1, 1, 1]) == [0, 1, 1, 1]
  1021. assert anf_coeffs([1, 1, 1, 0]) == [1, 0, 0, 1]
  1022. assert anf_coeffs([1, 0, 0, 0]) == [1, 1, 1, 1]
  1023. assert anf_coeffs([1, 0, 0, 1]) == [1, 1, 1, 0]
  1024. assert anf_coeffs([1, 1, 0, 1]) == [1, 0, 1, 1]
  1025. def test_ANFform():
  1026. x, y = symbols('x,y')
  1027. assert ANFform([x], [1, 1]) == True
  1028. assert ANFform([x], [0, 0]) == False
  1029. assert ANFform([x], [1, 0]) == Xor(x, True, remove_true=False)
  1030. assert ANFform([x, y], [1, 1, 1, 0]) == \
  1031. Xor(True, And(x, y), remove_true=False)
  1032. def test_bool_minterm():
  1033. x, y = symbols('x,y')
  1034. assert bool_minterm(3, [x, y]) == And(x, y)
  1035. assert bool_minterm([1, 0], [x, y]) == And(Not(y), x)
  1036. def test_bool_maxterm():
  1037. x, y = symbols('x,y')
  1038. assert bool_maxterm(2, [x, y]) == Or(Not(x), y)
  1039. assert bool_maxterm([0, 1], [x, y]) == Or(Not(y), x)
  1040. def test_bool_monomial():
  1041. x, y = symbols('x,y')
  1042. assert bool_monomial(1, [x, y]) == y
  1043. assert bool_monomial([1, 1], [x, y]) == And(x, y)
  1044. def test_check_pair():
  1045. assert _check_pair([0, 1, 0], [0, 1, 1]) == 2
  1046. assert _check_pair([0, 1, 0], [1, 1, 1]) == -1
  1047. def test_issue_19114():
  1048. expr = (B & C) | (A & ~C) | (~A & ~B)
  1049. # Expression is minimal, but there are multiple minimal forms possible
  1050. res1 = (A & B) | (C & ~A) | (~B & ~C)
  1051. result = to_dnf(expr, simplify=True)
  1052. assert result in (expr, res1)
  1053. def test_issue_20870():
  1054. result = SOPform([a, b, c, d], [1, 2, 3, 4, 5, 6, 8, 9, 11, 12, 14, 15])
  1055. expected = ((d & ~b) | (a & b & c) | (a & ~c & ~d) |
  1056. (b & ~a & ~c) | (c & ~a & ~d))
  1057. assert result == expected
  1058. def test_convert_to_varsSOP():
  1059. assert _convert_to_varsSOP([0, 1, 0], [x, y, z]) == And(Not(x), y, Not(z))
  1060. assert _convert_to_varsSOP([3, 1, 0], [x, y, z]) == And(y, Not(z))
  1061. def test_convert_to_varsPOS():
  1062. assert _convert_to_varsPOS([0, 1, 0], [x, y, z]) == Or(x, Not(y), z)
  1063. assert _convert_to_varsPOS([3, 1, 0], [x, y, z]) == Or(Not(y), z)
  1064. def test_gateinputcount():
  1065. a, b, c, d, e = symbols('a:e')
  1066. assert gateinputcount(And(a, b)) == 2
  1067. assert gateinputcount(a | b & c & d ^ (e | a)) == 9
  1068. assert gateinputcount(And(a, True)) == 0
  1069. raises(TypeError, lambda: gateinputcount(a * b))
  1070. def test_refine():
  1071. # relational
  1072. assert not refine(x < 0, ~(x < 0))
  1073. assert refine(x < 0, (x < 0))
  1074. assert refine(x < 0, (0 > x)) is S.true
  1075. assert refine(x < 0, (y < 0)) == (x < 0)
  1076. assert not refine(x <= 0, ~(x <= 0))
  1077. assert refine(x <= 0, (x <= 0))
  1078. assert refine(x <= 0, (0 >= x)) is S.true
  1079. assert refine(x <= 0, (y <= 0)) == (x <= 0)
  1080. assert not refine(x > 0, ~(x > 0))
  1081. assert refine(x > 0, (x > 0))
  1082. assert refine(x > 0, (0 < x)) is S.true
  1083. assert refine(x > 0, (y > 0)) == (x > 0)
  1084. assert not refine(x >= 0, ~(x >= 0))
  1085. assert refine(x >= 0, (x >= 0))
  1086. assert refine(x >= 0, (0 <= x)) is S.true
  1087. assert refine(x >= 0, (y >= 0)) == (x >= 0)
  1088. assert not refine(Eq(x, 0), ~(Eq(x, 0)))
  1089. assert refine(Eq(x, 0), (Eq(x, 0)))
  1090. assert refine(Eq(x, 0), (Eq(0, x))) is S.true
  1091. assert refine(Eq(x, 0), (Eq(y, 0))) == Eq(x, 0)
  1092. assert not refine(Ne(x, 0), ~(Ne(x, 0)))
  1093. assert refine(Ne(x, 0), (Ne(0, x))) is S.true
  1094. assert refine(Ne(x, 0), (Ne(x, 0)))
  1095. assert refine(Ne(x, 0), (Ne(y, 0))) == (Ne(x, 0))
  1096. # boolean functions
  1097. assert refine(And(x > 0, y > 0), (x > 0)) == (y > 0)
  1098. assert refine(And(x > 0, y > 0), (x > 0) & (y > 0)) is S.true
  1099. # predicates
  1100. assert refine(Q.positive(x), Q.positive(x)) is S.true
  1101. assert refine(Q.positive(x), Q.negative(x)) is S.false
  1102. assert refine(Q.positive(x), Q.real(x)) == Q.positive(x)
  1103. def test_relational_threeterm_simplification_patterns_numerically():
  1104. from sympy.core import Wild
  1105. from sympy.logic.boolalg import _simplify_patterns_and3
  1106. a = Wild('a')
  1107. b = Wild('b')
  1108. c = Wild('c')
  1109. symb = [a, b, c]
  1110. patternlists = [[And, _simplify_patterns_and3()]]
  1111. valuelist = list(set(combinations(list(range(-2, 3)) * 3, 3)))
  1112. # Skip combinations of +/-2 and 0, except for all 0
  1113. valuelist = [v for v in valuelist if any(w % 2 for w in v) or not any(v)]
  1114. for func, patternlist in patternlists:
  1115. for pattern in patternlist:
  1116. original = func(*pattern[0].args)
  1117. simplified = pattern[1]
  1118. for values in valuelist:
  1119. sublist = dict(zip(symb, values))
  1120. originalvalue = original.xreplace(sublist)
  1121. simplifiedvalue = simplified.xreplace(sublist)
  1122. assert originalvalue == simplifiedvalue, "Original: {}\nand" \
  1123. " simplified: {}\ndo not evaluate to the same value for" \
  1124. "{}".format(pattern[0], simplified, sublist)
  1125. def test_issue_25451():
  1126. x = Or(And(a, c), Eq(a, b))
  1127. assert isinstance(x, Or)
  1128. assert set(x.args) == {And(a, c), Eq(a, b)}
  1129. def test_issue_26985():
  1130. a, b, c, d = symbols('a b c d')
  1131. # Expression before applying to_anf
  1132. x = Xor(c, And(a, b), And(a, c))
  1133. y = Xor(a, b, And(a, c))
  1134. # Applying to_anf
  1135. result = Xor(Xor(d, And(x, y)), And(x, y))
  1136. result_anf = to_anf(Xor(to_anf(Xor(d, And(x, y))), And(x, y)))
  1137. assert result_anf == d
  1138. assert result == d