test_boolalg.py 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340
  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.simplify.simplify import simplify
  11. from sympy.logic.boolalg import (
  12. And, Boolean, Equivalent, ITE, Implies, Nand, Nor, Not, Or,
  13. POSform, SOPform, Xor, Xnor, conjuncts, disjuncts,
  14. distribute_or_over_and, distribute_and_over_or,
  15. eliminate_implications, is_nnf, is_cnf, is_dnf, simplify_logic,
  16. to_nnf, to_cnf, to_dnf, to_int_repr, bool_map, true, false,
  17. BooleanAtom, is_literal, term_to_integer,
  18. truth_table, as_Boolean, to_anf, is_anf, distribute_xor_over_and,
  19. anf_coeffs, ANFform, bool_minterm, bool_maxterm, bool_monomial,
  20. _check_pair, _convert_to_varsSOP, _convert_to_varsPOS, Exclusive,
  21. gateinputcount)
  22. from sympy.assumptions.cnf import CNF
  23. from sympy.testing.pytest import raises, XFAIL, slow
  24. from itertools import combinations, permutations, product
  25. A, B, C, D = symbols('A:D')
  26. a, b, c, d, e, w, x, y, z = symbols('a:e w:z')
  27. def test_overloading():
  28. """Test that |, & are overloaded as expected"""
  29. assert A & B == And(A, B)
  30. assert A | B == Or(A, B)
  31. assert (A & B) | C == Or(And(A, B), C)
  32. assert A >> B == Implies(A, B)
  33. assert A << B == Implies(B, A)
  34. assert ~A == Not(A)
  35. assert A ^ B == Xor(A, B)
  36. def test_And():
  37. assert And() is true
  38. assert And(A) == A
  39. assert And(True) is true
  40. assert And(False) is false
  41. assert And(True, True) is true
  42. assert And(True, False) is false
  43. assert And(False, False) is false
  44. assert And(True, A) == A
  45. assert And(False, A) is false
  46. assert And(True, True, True) is true
  47. assert And(True, True, A) == A
  48. assert And(True, False, A) is false
  49. assert And(1, A) == A
  50. raises(TypeError, lambda: And(2, A))
  51. raises(TypeError, lambda: And(A < 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. raises(TypeError, lambda: Or(A < 2, A))
  75. assert Or(A < 1, A >= 1) is true
  76. e = A > 1
  77. assert Or(e, e.canonical) == e
  78. g, l, ge, le = A > B, B < A, A >= B, B <= A
  79. assert Or(g, l, ge, le) == Or(g, ge)
  80. def test_Xor():
  81. assert Xor() is false
  82. assert Xor(A) == A
  83. assert Xor(A, A) is false
  84. assert Xor(True, A, A) is true
  85. assert Xor(A, A, A, A, A) == A
  86. assert Xor(True, False, False, A, B) == ~Xor(A, B)
  87. assert Xor(True) is true
  88. assert Xor(False) is false
  89. assert Xor(True, True) is false
  90. assert Xor(True, False) is true
  91. assert Xor(False, False) is false
  92. assert Xor(True, A) == ~A
  93. assert Xor(False, A) == A
  94. assert Xor(True, False, False) is true
  95. assert Xor(True, False, A) == ~A
  96. assert Xor(False, False, A) == A
  97. assert isinstance(Xor(A, B), Xor)
  98. assert Xor(A, B, Xor(C, D)) == Xor(A, B, C, D)
  99. assert Xor(A, B, Xor(B, C)) == Xor(A, C)
  100. assert Xor(A < 1, A >= 1, B) == Xor(0, 1, B) == Xor(1, 0, B)
  101. e = A > 1
  102. assert Xor(e, e.canonical) == Xor(0, 0) == Xor(1, 1)
  103. def test_rewrite_as_And():
  104. expr = x ^ y
  105. assert expr.rewrite(And) == (x | y) & (~x | ~y)
  106. def test_rewrite_as_Or():
  107. expr = x ^ y
  108. assert expr.rewrite(Or) == (x & ~y) | (y & ~x)
  109. def test_rewrite_as_Nand():
  110. expr = (y & z) | (z & ~w)
  111. assert expr.rewrite(Nand) == ~(~(y & z) & ~(z & ~w))
  112. def test_rewrite_as_Nor():
  113. expr = z & (y | ~w)
  114. assert expr.rewrite(Nor) == ~(~z | ~(y | ~w))
  115. def test_Not():
  116. raises(TypeError, lambda: Not(True, False))
  117. assert Not(True) is false
  118. assert Not(False) is true
  119. assert Not(0) is true
  120. assert Not(1) is false
  121. assert Not(2) is false
  122. def test_Nand():
  123. assert Nand() is false
  124. assert Nand(A) == ~A
  125. assert Nand(True) is false
  126. assert Nand(False) is true
  127. assert Nand(True, True) is false
  128. assert Nand(True, False) is true
  129. assert Nand(False, False) is true
  130. assert Nand(True, A) == ~A
  131. assert Nand(False, A) is true
  132. assert Nand(True, True, True) is false
  133. assert Nand(True, True, A) == ~A
  134. assert Nand(True, False, A) is true
  135. def test_Nor():
  136. assert Nor() is true
  137. assert Nor(A) == ~A
  138. assert Nor(True) is false
  139. assert Nor(False) is true
  140. assert Nor(True, True) is false
  141. assert Nor(True, False) is false
  142. assert Nor(False, False) is true
  143. assert Nor(True, A) is false
  144. assert Nor(False, A) == ~A
  145. assert Nor(True, True, True) is false
  146. assert Nor(True, True, A) is false
  147. assert Nor(True, False, A) is false
  148. def test_Xnor():
  149. assert Xnor() is true
  150. assert Xnor(A) == ~A
  151. assert Xnor(A, A) is true
  152. assert Xnor(True, A, A) is false
  153. assert Xnor(A, A, A, A, A) == ~A
  154. assert Xnor(True) is false
  155. assert Xnor(False) is true
  156. assert Xnor(True, True) is true
  157. assert Xnor(True, False) is false
  158. assert Xnor(False, False) is true
  159. assert Xnor(True, A) == A
  160. assert Xnor(False, A) == ~A
  161. assert Xnor(True, False, False) is false
  162. assert Xnor(True, False, A) == A
  163. assert Xnor(False, False, A) == ~A
  164. def test_Implies():
  165. raises(ValueError, lambda: Implies(A, B, C))
  166. assert Implies(True, True) is true
  167. assert Implies(True, False) is false
  168. assert Implies(False, True) is true
  169. assert Implies(False, False) is true
  170. assert Implies(0, A) is true
  171. assert Implies(1, 1) is true
  172. assert Implies(1, 0) is false
  173. assert A >> B == B << A
  174. assert (A < 1) >> (A >= 1) == (A >= 1)
  175. assert (A < 1) >> (S.One > A) is true
  176. assert A >> A is true
  177. def test_Equivalent():
  178. assert Equivalent(A, B) == Equivalent(B, A) == Equivalent(A, B, A)
  179. assert Equivalent() is true
  180. assert Equivalent(A, A) == Equivalent(A) is true
  181. assert Equivalent(True, True) == Equivalent(False, False) is true
  182. assert Equivalent(True, False) == Equivalent(False, True) is false
  183. assert Equivalent(A, True) == A
  184. assert Equivalent(A, False) == Not(A)
  185. assert Equivalent(A, B, True) == A & B
  186. assert Equivalent(A, B, False) == ~A & ~B
  187. assert Equivalent(1, A) == A
  188. assert Equivalent(0, A) == Not(A)
  189. assert Equivalent(A, Equivalent(B, C)) != Equivalent(Equivalent(A, B), C)
  190. assert Equivalent(A < 1, A >= 1) is false
  191. assert Equivalent(A < 1, A >= 1, 0) is false
  192. assert Equivalent(A < 1, A >= 1, 1) is false
  193. assert Equivalent(A < 1, S.One > A) == Equivalent(1, 1) == Equivalent(0, 0)
  194. assert Equivalent(Equality(A, B), Equality(B, A)) is true
  195. def test_Exclusive():
  196. assert Exclusive(False, False, False) is true
  197. assert Exclusive(True, False, False) is true
  198. assert Exclusive(True, True, False) is false
  199. assert Exclusive(True, True, True) is false
  200. def test_equals():
  201. assert Not(Or(A, B)).equals(And(Not(A), Not(B))) is True
  202. assert Equivalent(A, B).equals((A >> B) & (B >> A)) is True
  203. assert ((A | ~B) & (~A | B)).equals((~A & ~B) | (A & B)) is True
  204. assert (A >> B).equals(~A >> ~B) is False
  205. assert (A >> (B >> A)).equals(A >> (C >> A)) is False
  206. raises(NotImplementedError, lambda: (A & B).equals(A > B))
  207. def test_simplification_boolalg():
  208. """
  209. Test working of simplification methods.
  210. """
  211. set1 = [[0, 0, 1], [0, 1, 1], [1, 0, 0], [1, 1, 0]]
  212. set2 = [[0, 0, 0], [0, 1, 0], [1, 0, 1], [1, 1, 1]]
  213. assert SOPform([x, y, z], set1) == Or(And(Not(x), z), And(Not(z), x))
  214. assert Not(SOPform([x, y, z], set2)) == \
  215. Not(Or(And(Not(x), Not(z)), And(x, z)))
  216. assert POSform([x, y, z], set1 + set2) is true
  217. assert SOPform([x, y, z], set1 + set2) is true
  218. assert SOPform([Dummy(), Dummy(), Dummy()], set1 + set2) is true
  219. minterms = [[0, 0, 0, 1], [0, 0, 1, 1], [0, 1, 1, 1], [1, 0, 1, 1],
  220. [1, 1, 1, 1]]
  221. dontcares = [[0, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 1]]
  222. assert (
  223. SOPform([w, x, y, z], minterms, dontcares) ==
  224. Or(And(y, z), And(Not(w), Not(x))))
  225. assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z)
  226. minterms = [1, 3, 7, 11, 15]
  227. dontcares = [0, 2, 5]
  228. assert (
  229. SOPform([w, x, y, z], minterms, dontcares) ==
  230. Or(And(y, z), And(Not(w), Not(x))))
  231. assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z)
  232. minterms = [1, [0, 0, 1, 1], 7, [1, 0, 1, 1],
  233. [1, 1, 1, 1]]
  234. dontcares = [0, [0, 0, 1, 0], 5]
  235. assert (
  236. SOPform([w, x, y, z], minterms, dontcares) ==
  237. Or(And(y, z), And(Not(w), Not(x))))
  238. assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z)
  239. minterms = [1, {y: 1, z: 1}]
  240. dontcares = [0, [0, 0, 1, 0], 5]
  241. assert (
  242. SOPform([w, x, y, z], minterms, dontcares) ==
  243. Or(And(y, z), And(Not(w), Not(x))))
  244. assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z)
  245. minterms = [{y: 1, z: 1}, 1]
  246. dontcares = [[0, 0, 0, 0]]
  247. minterms = [[0, 0, 0]]
  248. raises(ValueError, lambda: SOPform([w, x, y, z], minterms))
  249. raises(ValueError, lambda: POSform([w, x, y, z], minterms))
  250. raises(TypeError, lambda: POSform([w, x, y, z], ["abcdefg"]))
  251. # test simplification
  252. ans = And(A, Or(B, C))
  253. assert simplify_logic(A & (B | C)) == ans
  254. assert simplify_logic((A & B) | (A & C)) == ans
  255. assert simplify_logic(Implies(A, B)) == Or(Not(A), B)
  256. assert simplify_logic(Equivalent(A, B)) == \
  257. Or(And(A, B), And(Not(A), Not(B)))
  258. assert simplify_logic(And(Equality(A, 2), C)) == And(Equality(A, 2), C)
  259. assert simplify_logic(And(Equality(A, 2), A)) is S.false
  260. assert simplify_logic(And(Equality(A, 2), A)) == And(Equality(A, 2), A)
  261. assert simplify_logic(And(Equality(A, B), C)) == And(Equality(A, B), C)
  262. assert simplify_logic(Or(And(Equality(A, 3), B), And(Equality(A, 3), C))) \
  263. == And(Equality(A, 3), Or(B, C))
  264. b = (~x & ~y & ~z) | (~x & ~y & z)
  265. e = And(A, b)
  266. assert simplify_logic(e) == A & ~x & ~y
  267. raises(ValueError, lambda: simplify_logic(A & (B | C), form='blabla'))
  268. assert simplify(Or(x <= y, And(x < y, z))) == (x <= y)
  269. assert simplify(Or(x <= y, And(y > x, z))) == (x <= y)
  270. assert simplify(Or(x >= y, And(y < x, z))) == (x >= y)
  271. # Check that expressions with nine variables or more are not simplified
  272. # (without the force-flag)
  273. a, b, c, d, e, f, g, h, j = symbols('a b c d e f g h j')
  274. expr = a & b & c & d & e & f & g & h & j | \
  275. a & b & c & d & e & f & g & h & ~j
  276. # This expression can be simplified to get rid of the j variables
  277. assert simplify_logic(expr) == expr
  278. # Test dontcare
  279. assert simplify_logic((a & b) | c | d, dontcare=(a & b)) == c | d
  280. # check input
  281. ans = SOPform([x, y], [[1, 0]])
  282. assert SOPform([x, y], [[1, 0]]) == ans
  283. assert POSform([x, y], [[1, 0]]) == ans
  284. raises(ValueError, lambda: SOPform([x], [[1]], [[1]]))
  285. assert SOPform([x], [[1]], [[0]]) is true
  286. assert SOPform([x], [[0]], [[1]]) is true
  287. assert SOPform([x], [], []) is false
  288. raises(ValueError, lambda: POSform([x], [[1]], [[1]]))
  289. assert POSform([x], [[1]], [[0]]) is true
  290. assert POSform([x], [[0]], [[1]]) is true
  291. assert POSform([x], [], []) is false
  292. # check working of simplify
  293. assert simplify((A & B) | (A & C)) == And(A, Or(B, C))
  294. assert simplify(And(x, Not(x))) == False
  295. assert simplify(Or(x, Not(x))) == True
  296. assert simplify(And(Eq(x, 0), Eq(x, y))) == And(Eq(x, 0), Eq(y, 0))
  297. assert And(Eq(x - 1, 0), Eq(x, y)).simplify() == And(Eq(x, 1), Eq(y, 1))
  298. assert And(Ne(x - 1, 0), Ne(x, y)).simplify() == And(Ne(x, 1), Ne(x, y))
  299. assert And(Eq(x - 1, 0), Ne(x, y)).simplify() == And(Eq(x, 1), Ne(y, 1))
  300. assert And(Eq(x - 1, 0), Eq(x, z + y), Eq(y + x, 0)).simplify(
  301. ) == And(Eq(x, 1), Eq(y, -1), Eq(z, 2))
  302. assert And(Eq(x - 1, 0), Eq(x + 2, 3)).simplify() == Eq(x, 1)
  303. assert And(Ne(x - 1, 0), Ne(x + 2, 3)).simplify() == Ne(x, 1)
  304. assert And(Eq(x - 1, 0), Eq(x + 2, 2)).simplify() == False
  305. assert And(Ne(x - 1, 0), Ne(x + 2, 2)).simplify(
  306. ) == And(Ne(x, 1), Ne(x, 0))
  307. def test_bool_map():
  308. """
  309. Test working of bool_map function.
  310. """
  311. minterms = [[0, 0, 0, 1], [0, 0, 1, 1], [0, 1, 1, 1], [1, 0, 1, 1],
  312. [1, 1, 1, 1]]
  313. assert bool_map(Not(Not(a)), a) == (a, {a: a})
  314. assert bool_map(SOPform([w, x, y, z], minterms),
  315. POSform([w, x, y, z], minterms)) == \
  316. (And(Or(Not(w), y), Or(Not(x), y), z), {x: x, w: w, z: z, y: y})
  317. assert bool_map(SOPform([x, z, y], [[1, 0, 1]]),
  318. SOPform([a, b, c], [[1, 0, 1]])) != False
  319. function1 = SOPform([x, z, y], [[1, 0, 1], [0, 0, 1]])
  320. function2 = SOPform([a, b, c], [[1, 0, 1], [1, 0, 0]])
  321. assert bool_map(function1, function2) == \
  322. (function1, {y: a, z: b})
  323. assert bool_map(Xor(x, y), ~Xor(x, y)) == False
  324. assert bool_map(And(x, y), Or(x, y)) is None
  325. assert bool_map(And(x, y), And(x, y, z)) is None
  326. # issue 16179
  327. assert bool_map(Xor(x, y, z), ~Xor(x, y, z)) == False
  328. assert bool_map(Xor(a, x, y, z), ~Xor(a, x, y, z)) == False
  329. def test_bool_symbol():
  330. """Test that mixing symbols with boolean values
  331. works as expected"""
  332. assert And(A, True) == A
  333. assert And(A, True, True) == A
  334. assert And(A, False) is false
  335. assert And(A, True, False) is false
  336. assert Or(A, True) is true
  337. assert Or(A, False) == A
  338. def test_is_boolean():
  339. assert isinstance(True, Boolean) is False
  340. assert isinstance(true, Boolean) is True
  341. assert 1 == True
  342. assert 1 != true
  343. assert (1 == true) is False
  344. assert 0 == False
  345. assert 0 != false
  346. assert (0 == false) is False
  347. assert true.is_Boolean is True
  348. assert (A & B).is_Boolean
  349. assert (A | B).is_Boolean
  350. assert (~A).is_Boolean
  351. assert (A ^ B).is_Boolean
  352. assert A.is_Boolean != isinstance(A, Boolean)
  353. assert isinstance(A, Boolean)
  354. def test_subs():
  355. assert (A & B).subs(A, True) == B
  356. assert (A & B).subs(A, False) is false
  357. assert (A & B).subs(B, True) == A
  358. assert (A & B).subs(B, False) is false
  359. assert (A & B).subs({A: True, B: True}) is true
  360. assert (A | B).subs(A, True) is true
  361. assert (A | B).subs(A, False) == B
  362. assert (A | B).subs(B, True) is true
  363. assert (A | B).subs(B, False) == A
  364. assert (A | B).subs({A: True, B: True}) is true
  365. """
  366. we test for axioms of boolean algebra
  367. see https://en.wikipedia.org/wiki/Boolean_algebra_(structure)
  368. """
  369. def test_commutative():
  370. """Test for commutativity of And and Or"""
  371. A, B = map(Boolean, symbols('A,B'))
  372. assert A & B == B & A
  373. assert A | B == B | A
  374. def test_and_associativity():
  375. """Test for associativity of And"""
  376. assert (A & B) & C == A & (B & C)
  377. def test_or_assicativity():
  378. assert ((A | B) | C) == (A | (B | C))
  379. def test_double_negation():
  380. a = Boolean()
  381. assert ~(~a) == a
  382. # test methods
  383. def test_eliminate_implications():
  384. assert eliminate_implications(Implies(A, B, evaluate=False)) == (~A) | B
  385. assert eliminate_implications(
  386. A >> (C >> Not(B))) == Or(Or(Not(B), Not(C)), Not(A))
  387. assert eliminate_implications(Equivalent(A, B, C, D)) == \
  388. (~A | B) & (~B | C) & (~C | D) & (~D | A)
  389. def test_conjuncts():
  390. assert conjuncts(A & B & C) == {A, B, C}
  391. assert conjuncts((A | B) & C) == {A | B, C}
  392. assert conjuncts(A) == {A}
  393. assert conjuncts(True) == {True}
  394. assert conjuncts(False) == {False}
  395. def test_disjuncts():
  396. assert disjuncts(A | B | C) == {A, B, C}
  397. assert disjuncts((A | B) & C) == {(A | B) & C}
  398. assert disjuncts(A) == {A}
  399. assert disjuncts(True) == {True}
  400. assert disjuncts(False) == {False}
  401. def test_distribute():
  402. assert distribute_and_over_or(Or(And(A, B), C)) == And(Or(A, C), Or(B, C))
  403. assert distribute_or_over_and(And(A, Or(B, C))) == Or(And(A, B), And(A, C))
  404. assert distribute_xor_over_and(And(A, Xor(B, C))) == Xor(And(A, B), And(A, C))
  405. def test_to_anf():
  406. x, y, z = symbols('x,y,z')
  407. assert to_anf(And(x, y)) == And(x, y)
  408. assert to_anf(Or(x, y)) == Xor(x, y, And(x, y))
  409. assert to_anf(Or(Implies(x, y), And(x, y), y)) == \
  410. Xor(x, True, x & y, remove_true=False)
  411. assert to_anf(Or(Nand(x, y), Nor(x, y), Xnor(x, y), Implies(x, y))) == True
  412. assert to_anf(Or(x, Not(y), Nor(x,z), And(x, y), Nand(y, z))) == \
  413. Xor(True, And(y, z), And(x, y, z), remove_true=False)
  414. assert to_anf(Xor(x, y)) == Xor(x, y)
  415. assert to_anf(Not(x)) == Xor(x, True, remove_true=False)
  416. assert to_anf(Nand(x, y)) == Xor(True, And(x, y), remove_true=False)
  417. assert to_anf(Nor(x, y)) == Xor(x, y, True, And(x, y), remove_true=False)
  418. assert to_anf(Implies(x, y)) == Xor(x, True, And(x, y), remove_true=False)
  419. assert to_anf(Equivalent(x, y)) == Xor(x, y, True, remove_true=False)
  420. assert to_anf(Nand(x | y, x >> y), deep=False) == \
  421. Xor(True, And(Or(x, y), Implies(x, y)), remove_true=False)
  422. assert to_anf(Nor(x ^ y, x & y), deep=False) == \
  423. Xor(True, Or(Xor(x, y), And(x, y)), remove_true=False)
  424. def test_to_nnf():
  425. assert to_nnf(true) is true
  426. assert to_nnf(false) is false
  427. assert to_nnf(A) == A
  428. assert to_nnf(A | ~A | B) is true
  429. assert to_nnf(A & ~A & B) is false
  430. assert to_nnf(A >> B) == ~A | B
  431. assert to_nnf(Equivalent(A, B, C)) == (~A | B) & (~B | C) & (~C | A)
  432. assert to_nnf(A ^ B ^ C) == \
  433. (A | B | C) & (~A | ~B | C) & (A | ~B | ~C) & (~A | B | ~C)
  434. assert to_nnf(ITE(A, B, C)) == (~A | B) & (A | C)
  435. assert to_nnf(Not(A | B | C)) == ~A & ~B & ~C
  436. assert to_nnf(Not(A & B & C)) == ~A | ~B | ~C
  437. assert to_nnf(Not(A >> B)) == A & ~B
  438. assert to_nnf(Not(Equivalent(A, B, C))) == And(Or(A, B, C), Or(~A, ~B, ~C))
  439. assert to_nnf(Not(A ^ B ^ C)) == \
  440. (~A | B | C) & (A | ~B | C) & (A | B | ~C) & (~A | ~B | ~C)
  441. assert to_nnf(Not(ITE(A, B, C))) == (~A | ~B) & (A | ~C)
  442. assert to_nnf((A >> B) ^ (B >> A)) == (A & ~B) | (~A & B)
  443. assert to_nnf((A >> B) ^ (B >> A), False) == \
  444. (~A | ~B | A | B) & ((A & ~B) | (~A & B))
  445. assert ITE(A, 1, 0).to_nnf() == A
  446. assert ITE(A, 0, 1).to_nnf() == ~A
  447. # although ITE can hold non-Boolean, it will complain if
  448. # an attempt is made to convert the ITE to Boolean nnf
  449. raises(TypeError, lambda: ITE(A < 1, [1], B).to_nnf())
  450. def test_to_cnf():
  451. assert to_cnf(~(B | C)) == And(Not(B), Not(C))
  452. assert to_cnf((A & B) | C) == And(Or(A, C), Or(B, C))
  453. assert to_cnf(A >> B) == (~A) | B
  454. assert to_cnf(A >> (B & C)) == (~A | B) & (~A | C)
  455. assert to_cnf(A & (B | C) | ~A & (B | C), True) == B | C
  456. assert to_cnf(A & B) == And(A, B)
  457. assert to_cnf(Equivalent(A, B)) == And(Or(A, Not(B)), Or(B, Not(A)))
  458. assert to_cnf(Equivalent(A, B & C)) == \
  459. (~A | B) & (~A | C) & (~B | ~C | A)
  460. assert to_cnf(Equivalent(A, B | C), True) == \
  461. And(Or(Not(B), A), Or(Not(C), A), Or(B, C, Not(A)))
  462. assert to_cnf(A + 1) == A + 1
  463. def test_issue_18904():
  464. x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 = symbols('x1:16')
  465. eq = (( x1 & x2 & x3 & x4 & x5 & x6 & x7 & x8 & x9 ) |
  466. ( x1 & x2 & x3 & x4 & x5 & x6 & x7 & x10 & x9 ) |
  467. ( x1 & x11 & x3 & x12 & x5 & x13 & x14 & x15 & x9 ))
  468. assert is_cnf(to_cnf(eq))
  469. raises(ValueError, lambda: to_cnf(eq, simplify=True))
  470. for f, t in zip((And, Or), (to_cnf, to_dnf)):
  471. eq = f(x1, x2, x3, x4, x5, x6, x7, x8, x9)
  472. raises(ValueError, lambda: to_cnf(eq, simplify=True))
  473. assert t(eq, simplify=True, force=True) == eq
  474. def test_issue_9949():
  475. assert is_cnf(to_cnf((b > -5) | (a > 2) & (a < 4)))
  476. def test_to_CNF():
  477. assert CNF.CNF_to_cnf(CNF.to_CNF(~(B | C))) == to_cnf(~(B | C))
  478. assert CNF.CNF_to_cnf(CNF.to_CNF((A & B) | C)) == to_cnf((A & B) | C)
  479. assert CNF.CNF_to_cnf(CNF.to_CNF(A >> B)) == to_cnf(A >> B)
  480. assert CNF.CNF_to_cnf(CNF.to_CNF(A >> (B & C))) == to_cnf(A >> (B & C))
  481. assert CNF.CNF_to_cnf(CNF.to_CNF(A & (B | C) | ~A & (B | C))) == to_cnf(A & (B | C) | ~A & (B | C))
  482. assert CNF.CNF_to_cnf(CNF.to_CNF(A & B)) == to_cnf(A & B)
  483. def test_to_dnf():
  484. assert to_dnf(~(B | C)) == And(Not(B), Not(C))
  485. assert to_dnf(A & (B | C)) == Or(And(A, B), And(A, C))
  486. assert to_dnf(A >> B) == (~A) | B
  487. assert to_dnf(A >> (B & C)) == (~A) | (B & C)
  488. assert to_dnf(A | B) == A | B
  489. assert to_dnf(Equivalent(A, B), True) == \
  490. Or(And(A, B), And(Not(A), Not(B)))
  491. assert to_dnf(Equivalent(A, B & C), True) == \
  492. Or(And(A, B, C), And(Not(A), Not(B)), And(Not(A), Not(C)))
  493. assert to_dnf(A + 1) == A + 1
  494. def test_to_int_repr():
  495. x, y, z = map(Boolean, symbols('x,y,z'))
  496. def sorted_recursive(arg):
  497. try:
  498. return sorted(sorted_recursive(x) for x in arg)
  499. except TypeError: # arg is not a sequence
  500. return arg
  501. assert sorted_recursive(to_int_repr([x | y, z | x], [x, y, z])) == \
  502. sorted_recursive([[1, 2], [1, 3]])
  503. assert sorted_recursive(to_int_repr([x | y, z | ~x], [x, y, z])) == \
  504. sorted_recursive([[1, 2], [3, -1]])
  505. def test_is_anf():
  506. x, y = symbols('x,y')
  507. assert is_anf(true) is True
  508. assert is_anf(false) is True
  509. assert is_anf(x) is True
  510. assert is_anf(And(x, y)) is True
  511. assert is_anf(Xor(x, y, And(x, y))) is True
  512. assert is_anf(Xor(x, y, Or(x, y))) is False
  513. assert is_anf(Xor(Not(x), y)) is False
  514. def test_is_nnf():
  515. assert is_nnf(true) is True
  516. assert is_nnf(A) is True
  517. assert is_nnf(~A) is True
  518. assert is_nnf(A & B) is True
  519. assert is_nnf((A & B) | (~A & A) | (~B & B) | (~A & ~B), False) is True
  520. assert is_nnf((A | B) & (~A | ~B)) is True
  521. assert is_nnf(Not(Or(A, B))) is False
  522. assert is_nnf(A ^ B) is False
  523. assert is_nnf((A & B) | (~A & A) | (~B & B) | (~A & ~B), True) is False
  524. def test_is_cnf():
  525. assert is_cnf(x) is True
  526. assert is_cnf(x | y | z) 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 False
  530. assert is_cnf(~(x & y) | z) is False
  531. def test_is_dnf():
  532. assert is_dnf(x) is True
  533. assert is_dnf(x | y | z) 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 False
  537. assert is_dnf(~(x | y) & z) is False
  538. def test_ITE():
  539. A, B, C = symbols('A:C')
  540. assert ITE(True, False, True) is false
  541. assert ITE(True, True, False) is true
  542. assert ITE(False, True, False) is false
  543. assert ITE(False, False, True) is true
  544. assert isinstance(ITE(A, B, C), ITE)
  545. A = True
  546. assert ITE(A, B, C) == B
  547. A = False
  548. assert ITE(A, B, C) == C
  549. B = True
  550. assert ITE(And(A, B), B, C) == C
  551. assert ITE(Or(A, False), And(B, True), False) is false
  552. assert ITE(x, A, B) == Not(x)
  553. assert ITE(x, B, A) == x
  554. assert ITE(1, x, y) == x
  555. assert ITE(0, x, y) == y
  556. raises(TypeError, lambda: ITE(2, x, y))
  557. raises(TypeError, lambda: ITE(1, [], y))
  558. raises(TypeError, lambda: ITE(1, (), y))
  559. raises(TypeError, lambda: ITE(1, y, []))
  560. assert ITE(1, 1, 1) is S.true
  561. assert isinstance(ITE(1, 1, 1, evaluate=False), ITE)
  562. raises(TypeError, lambda: ITE(x > 1, y, x))
  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_relational_simplification():
  879. w, x, y, z = symbols('w x y z', real=True)
  880. d, e = symbols('d e', real=False)
  881. # Test all combinations or sign and order
  882. assert Or(x >= y, x < y).simplify() == S.true
  883. assert Or(x >= y, y > x).simplify() == S.true
  884. assert Or(x >= y, -x > -y).simplify() == S.true
  885. assert Or(x >= y, -y < -x).simplify() == S.true
  886. assert Or(-x <= -y, x < y).simplify() == S.true
  887. assert Or(-x <= -y, -x > -y).simplify() == S.true
  888. assert Or(-x <= -y, y > x).simplify() == S.true
  889. assert Or(-x <= -y, -y < -x).simplify() == S.true
  890. assert Or(y <= x, x < y).simplify() == S.true
  891. assert Or(y <= x, y > x).simplify() == S.true
  892. assert Or(y <= x, -x > -y).simplify() == S.true
  893. assert Or(y <= x, -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(x < y, x >= y).simplify() == S.true
  899. assert Or(y > x, x >= y).simplify() == S.true
  900. assert Or(-x > -y, x >= y).simplify() == S.true
  901. assert Or(-y < -x, x >= y).simplify() == S.true
  902. assert Or(x < y, -x <= -y).simplify() == S.true
  903. assert Or(-x > -y, -x <= -y).simplify() == S.true
  904. assert Or(y > x, -x <= -y).simplify() == S.true
  905. assert Or(-y < -x, -x <= -y).simplify() == S.true
  906. assert Or(x < y, y <= x).simplify() == S.true
  907. assert Or(y > x, y <= x).simplify() == S.true
  908. assert Or(-x > -y, y <= x).simplify() == S.true
  909. assert Or(-y < -x, y <= x).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. # Some other tests
  915. assert Or(x >= y, w < z, x <= y).simplify() == S.true
  916. assert And(x >= y, x < y).simplify() == S.false
  917. assert Or(x >= y, Eq(y, x)).simplify() == (x >= y)
  918. assert And(x >= y, Eq(y, x)).simplify() == Eq(x, y)
  919. assert And(Eq(x, y), x >= 1, 2 < y, y >= 5, z < y).simplify() == \
  920. (Eq(x, y) & (x >= 1) & (y >= 5) & (y > z))
  921. assert Or(Eq(x, y), x >= y, w < y, z < y).simplify() == \
  922. (x >= y) | (y > z) | (w < y)
  923. assert And(Eq(x, y), x >= y, w < y, y >= z, z < y).simplify() == \
  924. Eq(x, y) & (y > z) & (w < y)
  925. # assert And(Eq(x, y), x >= y, w < y, y >= z, z < y).simplify(relational_minmax=True) == \
  926. # And(Eq(x, y), y > Max(w, z))
  927. # assert Or(Eq(x, y), x >= 1, 2 < y, y >= 5, z < y).simplify(relational_minmax=True) == \
  928. # (Eq(x, y) | (x >= 1) | (y > Min(2, z)))
  929. assert And(Eq(x, y), x >= 1, 2 < y, y >= 5, z < y).simplify() == \
  930. (Eq(x, y) & (x >= 1) & (y >= 5) & (y > z))
  931. assert (Eq(x, y) & Eq(d, e) & (x >= y) & (d >= e)).simplify() == \
  932. (Eq(x, y) & Eq(d, e) & (d >= e))
  933. assert And(Eq(x, y), Eq(x, -y)).simplify() == And(Eq(x, 0), Eq(y, 0))
  934. assert Xor(x >= y, x <= y).simplify() == Ne(x, y)
  935. assert And(x > 1, x < -1, Eq(x, y)).simplify() == S.false
  936. # From #16690
  937. assert And(x >= y, Eq(y, 0)).simplify() == And(x >= 0, Eq(y, 0))
  938. assert Or(Ne(x, 1), Ne(x, 2)).simplify() == S.true
  939. assert And(Eq(x, 1), Ne(2, x)).simplify() == Eq(x, 1)
  940. assert Or(Eq(x, 1), Ne(2, x)).simplify() == Ne(x, 2)
  941. def test_issue_8373():
  942. x = symbols('x', real=True)
  943. assert Or(x < 1, x > -1).simplify() == S.true
  944. assert Or(x < 1, x >= 1).simplify() == S.true
  945. assert And(x < 1, x >= 1).simplify() == S.false
  946. assert Or(x <= 1, x >= 1).simplify() == S.true
  947. def test_issue_7950():
  948. x = symbols('x', real=True)
  949. assert And(Eq(x, 1), Eq(x, 2)).simplify() == S.false
  950. @slow
  951. def test_relational_simplification_numerically():
  952. def test_simplification_numerically_function(original, simplified):
  953. symb = original.free_symbols
  954. n = len(symb)
  955. valuelist = list(set(combinations(list(range(-(n-1), n))*n, n)))
  956. for values in valuelist:
  957. sublist = dict(zip(symb, values))
  958. originalvalue = original.subs(sublist)
  959. simplifiedvalue = simplified.subs(sublist)
  960. assert originalvalue == simplifiedvalue, "Original: {}\nand"\
  961. " simplified: {}\ndo not evaluate to the same value for {}"\
  962. "".format(original, simplified, sublist)
  963. w, x, y, z = symbols('w x y z', real=True)
  964. d, e = symbols('d e', real=False)
  965. expressions = (And(Eq(x, y), x >= y, w < y, y >= z, z < y),
  966. And(Eq(x, y), x >= 1, 2 < y, y >= 5, z < y),
  967. Or(Eq(x, y), x >= 1, 2 < y, y >= 5, z < y),
  968. And(x >= y, Eq(y, x)),
  969. Or(And(Eq(x, y), x >= y, w < y, Or(y >= z, z < y)),
  970. And(Eq(x, y), x >= 1, 2 < y, y >= -1, z < y)),
  971. (Eq(x, y) & Eq(d, e) & (x >= y) & (d >= e)),
  972. )
  973. for expression in expressions:
  974. test_simplification_numerically_function(expression,
  975. expression.simplify())
  976. def test_relational_simplification_patterns_numerically():
  977. from sympy.core import Wild
  978. from sympy.logic.boolalg import _simplify_patterns_and, \
  979. _simplify_patterns_or, _simplify_patterns_xor
  980. a = Wild('a')
  981. b = Wild('b')
  982. c = Wild('c')
  983. symb = [a, b, c]
  984. patternlists = [[And, _simplify_patterns_and()],
  985. [Or, _simplify_patterns_or()],
  986. [Xor, _simplify_patterns_xor()]]
  987. valuelist = list(set(combinations(list(range(-2, 3))*3, 3)))
  988. # Skip combinations of +/-2 and 0, except for all 0
  989. valuelist = [v for v in valuelist if any([w % 2 for w in v]) or not any(v)]
  990. for func, patternlist in patternlists:
  991. for pattern in patternlist:
  992. original = func(*pattern[0].args)
  993. simplified = pattern[1]
  994. for values in valuelist:
  995. sublist = dict(zip(symb, values))
  996. originalvalue = original.xreplace(sublist)
  997. simplifiedvalue = simplified.xreplace(sublist)
  998. assert originalvalue == simplifiedvalue, "Original: {}\nand"\
  999. " simplified: {}\ndo not evaluate to the same value for"\
  1000. "{}".format(pattern[0], simplified, sublist)
  1001. def test_issue_16803():
  1002. n = symbols('n')
  1003. # No simplification done, but should not raise an exception
  1004. assert ((n > 3) | (n < 0) | ((n > 0) & (n < 3))).simplify() == \
  1005. (n > 3) | (n < 0) | ((n > 0) & (n < 3))
  1006. def test_issue_17530():
  1007. r = {x: oo, y: oo}
  1008. assert Or(x + y > 0, x - y < 0).subs(r)
  1009. assert not And(x + y < 0, x - y < 0).subs(r)
  1010. raises(TypeError, lambda: Or(x + y < 0, x - y < 0).subs(r))
  1011. raises(TypeError, lambda: And(x + y > 0, x - y < 0).subs(r))
  1012. raises(TypeError, lambda: And(x + y > 0, x - y < 0).subs(r))
  1013. def test_anf_coeffs():
  1014. assert anf_coeffs([1, 0]) == [1, 1]
  1015. assert anf_coeffs([0, 0, 0, 1]) == [0, 0, 0, 1]
  1016. assert anf_coeffs([0, 1, 1, 1]) == [0, 1, 1, 1]
  1017. assert anf_coeffs([1, 1, 1, 0]) == [1, 0, 0, 1]
  1018. assert anf_coeffs([1, 0, 0, 0]) == [1, 1, 1, 1]
  1019. assert anf_coeffs([1, 0, 0, 1]) == [1, 1, 1, 0]
  1020. assert anf_coeffs([1, 1, 0, 1]) == [1, 0, 1, 1]
  1021. def test_ANFform():
  1022. x, y = symbols('x,y')
  1023. assert ANFform([x], [1, 1]) == True
  1024. assert ANFform([x], [0, 0]) == False
  1025. assert ANFform([x], [1, 0]) == Xor(x, True, remove_true=False)
  1026. assert ANFform([x, y], [1, 1, 1, 0]) == \
  1027. Xor(True, And(x, y), remove_true=False)
  1028. def test_bool_minterm():
  1029. x, y = symbols('x,y')
  1030. assert bool_minterm(3, [x, y]) == And(x, y)
  1031. assert bool_minterm([1, 0], [x, y]) == And(Not(y), x)
  1032. def test_bool_maxterm():
  1033. x, y = symbols('x,y')
  1034. assert bool_maxterm(2, [x, y]) == Or(Not(x), y)
  1035. assert bool_maxterm([0, 1], [x, y]) == Or(Not(y), x)
  1036. def test_bool_monomial():
  1037. x, y = symbols('x,y')
  1038. assert bool_monomial(1, [x, y]) == y
  1039. assert bool_monomial([1, 1], [x, y]) == And(x, y)
  1040. def test_check_pair():
  1041. assert _check_pair([0, 1, 0], [0, 1, 1]) == 2
  1042. assert _check_pair([0, 1, 0], [1, 1, 1]) == -1
  1043. def test_issue_19114():
  1044. expr = (B & C) | (A & ~C) | (~A & ~B)
  1045. # Expression is minimal, but there are multiple minimal forms possible
  1046. res1 = (A & B) | (C & ~A) | (~B & ~C)
  1047. result = to_dnf(expr, simplify=True)
  1048. assert result in (expr, res1)
  1049. def test_issue_20870():
  1050. result = SOPform([a, b, c, d], [1, 2, 3, 4, 5, 6, 8, 9, 11, 12, 14, 15])
  1051. expected = ((d & ~b) | (a & b & c) | (a & ~c & ~d) |
  1052. (b & ~a & ~c) | (c & ~a & ~d))
  1053. assert result == expected
  1054. def test_convert_to_varsSOP():
  1055. assert _convert_to_varsSOP([0, 1, 0], [x, y, z]) == And(Not(x), y, Not(z))
  1056. assert _convert_to_varsSOP([3, 1, 0], [x, y, z]) == And(y, Not(z))
  1057. def test_convert_to_varsPOS():
  1058. assert _convert_to_varsPOS([0, 1, 0], [x, y, z]) == Or(x, Not(y), z)
  1059. assert _convert_to_varsPOS([3, 1, 0], [x, y, z]) == Or(Not(y), z)
  1060. def test_gateinputcount():
  1061. a, b, c, d, e = symbols('a:e')
  1062. assert gateinputcount(And(a, b)) == 2
  1063. assert gateinputcount(a | b & c & d ^ (e | a)) == 9
  1064. assert gateinputcount(And(a, True)) == 0
  1065. raises(TypeError, lambda: gateinputcount(a*b))
  1066. def test_refine():
  1067. # relational
  1068. assert not refine(x < 0, ~(x < 0))
  1069. assert refine(x < 0, (x < 0))
  1070. assert refine(x < 0, (0 > x)) is S.true
  1071. assert refine(x < 0, (y < 0)) == (x < 0)
  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(Eq(x, 0), ~(Eq(x, 0)))
  1085. assert refine(Eq(x, 0), (Eq(x, 0)))
  1086. assert refine(Eq(x, 0), (Eq(0, x))) is S.true
  1087. assert refine(Eq(x, 0), (Eq(y, 0))) == Eq(x, 0)
  1088. assert not refine(Ne(x, 0), ~(Ne(x, 0)))
  1089. assert refine(Ne(x, 0), (Ne(0, x))) is S.true
  1090. assert refine(Ne(x, 0), (Ne(x, 0)))
  1091. assert refine(Ne(x, 0), (Ne(y, 0))) == (Ne(x, 0))
  1092. # boolean functions
  1093. assert refine(And(x > 0, y > 0), (x > 0)) == (y > 0)
  1094. assert refine(And(x > 0, y > 0), (x > 0) & (y > 0)) is S.true
  1095. # predicates
  1096. assert refine(Q.positive(x), Q.positive(x)) is S.true
  1097. assert refine(Q.positive(x), Q.negative(x)) is S.false
  1098. assert refine(Q.positive(x), Q.real(x)) == Q.positive(x)
  1099. def test_relational_threeterm_simplification_patterns_numerically():
  1100. from sympy.core import Wild
  1101. from sympy.logic.boolalg import _simplify_patterns_and3
  1102. a = Wild('a')
  1103. b = Wild('b')
  1104. c = Wild('c')
  1105. symb = [a, b, c]
  1106. patternlists = [[And, _simplify_patterns_and3()]]
  1107. valuelist = list(set(combinations(list(range(-2, 3))*3, 3)))
  1108. # Skip combinations of +/-2 and 0, except for all 0
  1109. valuelist = [v for v in valuelist if any([w % 2 for w in v]) or not any(v)]
  1110. for func, patternlist in patternlists:
  1111. for pattern in patternlist:
  1112. original = func(*pattern[0].args)
  1113. simplified = pattern[1]
  1114. for values in valuelist:
  1115. sublist = dict(zip(symb, values))
  1116. originalvalue = original.xreplace(sublist)
  1117. simplifiedvalue = simplified.xreplace(sublist)
  1118. assert originalvalue == simplifiedvalue, "Original: {}\nand"\
  1119. " simplified: {}\ndo not evaluate to the same value for"\
  1120. "{}".format(pattern[0], simplified, sublist)