1#!/usr/local/bin/python3.8 2# -*- coding: utf-8 -*- 3 4 5from mathics.core.evaluation import Evaluation 6from mathics.core.expression import ( 7 Complex, 8 Expression, 9 Integer, 10 MachineReal, 11 Rational, 12 Real, 13 String, 14 Symbol, 15 SymbolFalse, 16) 17from mathics.core.definitions import Definitions 18import sys 19import unittest 20 21definitions = Definitions(add_builtin=True) 22 23 24def _symbol_truth_value(x): 25 if x.is_true(): 26 return True 27 elif isinstance(x, Symbol) and x == SymbolFalse: 28 return False 29 else: 30 return "undefined" 31 32 33def _test_group(k, *group): 34 for i, a in enumerate(group): 35 sep = "" 36 for j, b in enumerate(group): 37 if i == j: 38 continue 39 evaluation = Evaluation(definitions, catch_interrupt=False) 40 try: 41 is_same_under_sameq = Expression("SameQ", a, b).evaluate(evaluation) 42 except Exception as exc: 43 print("Exception %s" % exc) 44 info = sys.exc_info() 45 sys.excepthook(*info) 46 return False 47 48 is_same = a.sameQ(b) 49 if is_same != _symbol_truth_value(is_same_under_sameq): 50 print( 51 "%sTest failed: %s and %s are inconsistent under .sameQ() and SameQ\n" 52 % (sep, repr(a), repr(b)) 53 ) 54 return False 55 56 if is_same and hash(a) != hash(b): 57 print( 58 "%sTest failed: hashes for %s and %s must be equal but are not\n" 59 % (sep, repr(a), repr(b)) 60 ) 61 return False 62 sep = "\n" 63 64 65class HashAndSameQ(unittest.TestCase): 66 # tests that the following assumption holds: if objects are same under SameQ, their 67 # hash is always equals. this assumption is relied upon by Gather[] and similar operations 68 69 def testInteger(self): 70 _test_group(Integer(5), Integer(3242), Integer(-1372)) 71 72 def testRational(self): 73 _test_group( 74 Rational(1, 3), 75 Rational(1, 3), 76 Rational(2, 6), 77 Rational(-1, 3), 78 Rational(-10, 30), 79 Rational(10, 5), 80 ) 81 82 def testReal(self): 83 _test_group( 84 MachineReal(1.17361), 85 MachineReal(-1.42), 86 MachineReal(42.846195714), 87 MachineReal(42.846195714), 88 MachineReal(42.846195713), 89 Real("42.846195713", 18), 90 Real("-1.42", 3), 91 ) 92 93 def testComplex(self): 94 def c(i, r): 95 return Complex(MachineReal(i), MachineReal(i)) 96 97 _test_group(c(1.2, 1.2), c(0.7, 1.8), c(1.8, 0.7), c(-0.7, 1.8), c(0.7, 1.81)) 98 99 def testString(self): 100 _test_group(String("xy"), String("x"), String("xyz"), String("abc")) 101 102 def testSymbol(self): 103 _test_group(Symbol("xy"), Symbol("x"), Symbol("xyz"), Symbol("abc")) 104 105 def testAcrossTypes(self): 106 _test_group( 107 Integer(1), 108 Rational(1, 1), 109 Real(1), 110 Complex(Integer(1), Integer(1)), 111 String("1"), 112 Symbol("1"), 113 ) 114 115 def testInstances(self): 116 # duplicate instantiations of same content (like Integer 5) to test for potential instantiation randomness. 117 _test_group( 118 list( 119 map( 120 lambda f: (f(), f()), 121 ( 122 lambda: Integer(5), 123 lambda: Rational(5, 2), 124 lambda: MachineReal(5.12345678), 125 lambda: Complex(Integer(5), Integer(2)), 126 lambda: String("xy"), 127 lambda: Symbol("xy"), 128 ), 129 ) 130 ) 131 ) 132 133 134if __name__ == "__main__": 135 unittest.main() 136