Skip to content

Commit acbd7aa

Browse files
committed
merge master
2 parents dc6b4e8 + c4c64ea commit acbd7aa

28 files changed

Lines changed: 340 additions & 174 deletions

.github/workflows/osx.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,9 @@ jobs:
2424
brew install llvm@9
2525
python -m pip install --upgrade pip
2626
LLVM_CONFIG=/usr/local/Cellar/llvm@9/9.0.1_2/bin/llvm-config pip install llvmlite
27-
python -m pip install -e git://github.com/Mathics3/mathics-scanner.git#egg=Mathics_Scanner
2827
- name: Install Mathics
2928
run: |
30-
make
29+
make develop
3130
- name: Test Mathics
3231
run: |
3332
pip install pytest pexpect

.github/workflows/ubuntu.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,10 @@ jobs:
2222
run: |
2323
sudo apt-get update -qq && sudo apt-get install -qq liblapack-dev llvm-dev
2424
python -m pip install --upgrade pip
25-
python -m pip install -e git://github.com/Mathics3/mathics-scanner.git#egg=Mathics_Scanner
2625
- name: Install Mathics
2726
run: |
2827
sed -i "s/'sympy==[0-9]\.[0-9]\.[0-9]', //" setup.py
29-
make
28+
make develop
3029
- name: Test Mathics
3130
run: |
3231
pip install pytest pexpect

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ before_install:
1919
- pip install ipywidgets ipykernel requests IPython==5.0.0 langid pycountry pyenchant lxml matplotlib unittest2 pexpect
2020
- python travis.py
2121
- pip install cython
22-
- pip install -e git://github.com/Mathics3/mathics-scanner.git#egg=Mathics_Scanner
2322
install:
2423
- sed -i "s/'sympy==[0-9]\.[0-9]\.[0-9]', //" setup.py
2524
- make develop

CHANGES.rst

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,77 @@ CHANGES
44
2.0.0
55
-----
66

7-
The Django front-end has been unbundled and is a separate `PyPI installable package <https://pypi.org/project/Mathics-Django/>`_.
7+
In order to accomdate growth and increase use pieces of Mathics inside other packages, some parts of
8+
Mathics have been split off and moved to separately installable packages. In particular:
9+
10+
* The Django front-end `PyPI installable package <https://pypi.org/project/Mathics-Django/>`_.
11+
* Scanner routines and character translations tables to/from unicode and noting some character properties
12+
* Specific builtins involving heavy, non-standard routines were moved to pymathics modules.
13+
14+
15+
816

917
New builtins
10-
++++++++++++++
18+
++++++++++++
1119

1220
- ``TimeRemaining`` and ``TimeConstrained``
1321
-``MathicsVersion`` (this is not in WL)
1422
- ``\[RadicalBox]``
15-
- ``FirstCase``, ``Lookup``
16-
- ``Catalan``, ``LerchPhi``
17-
- ``System`ConvertersDump`` context variables
23+
- ``ContinuedFraction``
24+
- ``Insert`` and ``Delete``
25+
- ``FirstCase``, ``Lookup``, ``Key``, ``Lookup`` and ``Failure``
26+
- ``ConvertCommonDumpRemoveLinearSyntax`` and ``System`ConvertersDump`` context variables
27+
- ``PossibleZeroQ`` PR #1100
28+
- ``Run``
29+
- ``SympyObject``
30+
- ``NumberQ``
31+
- ``AnglePath``, ``AnglePathFold``, ``AngleVector``
32+
- ``Haversine``, ``InverseHaversine``
33+
- ``Show``
34+
- Improving support for options in the Plot module: ``Axes``, ``Filling``, ``ImageSize``, ``Joined``
35+
- ``BoxData``, ``TextData``, ``InterpretationBox``, ``StyleBox``, ``TagBox``, ``TemplateBox``, ``ButtonBox``, ``InterpretationBox``
36+
- ``LerchPhi``
37+
38+
New Constants
39+
+++++++++++++
40+
41+
Mathematical Constants is now its own module/section. Contants have been filled out.
42+
These constants have been added:
43+
44+
- ``Catalan``
45+
- ``Glaisher``
46+
- ``Khinchin``
47+
- ``Degree``
48+
- ``GoldenRatio``
49+
- ``Khinchin``
50+
51+
52+
Many of these and the existing constants are computable via mpmath, numpy, or sympy.
53+
54+
55+
Settings through WL variables
56+
-----------------------------
57+
58+
Certain aspects of the configuration of the kernel are now controlled by variables, defined in /autoad/settings.m
59+
60+
- ``$GetTrace`` (``False`` by default). Defines if when a WL module is load through ``Get``, definitions will be traced (for debug).
61+
- ``$PreferredBackendMethod`` Set this do whether to use mpmath, numpy or Sympy for numeric and symbolic constants and methods when there is s choice (``"sympy"`` by default) (see #1124)
62+
63+
64+
Enhancements
65+
------------
66+
67+
- Add ``Method`` option "mpmath" to compute ``Eignevalues`` using mpmath (#1115).
68+
- Improving the support for OptionValue and OptionsPattern (#1113)
69+
70+
71+
Bug Fixes
72+
---------
73+
74+
There have been numerous bug is driven by working on Combinatorica V0.9 and CellsToTeX.
75+
76+
- ``Sum`` involving numeric integer bounds involving Mathics functions fixed.
77+
- ``Equal`` ``UnEqual`` testing on Strings (#1128).
1878

1979
Document updates
2080
----------------
@@ -29,6 +89,14 @@ Enhancements and Bug fixes:
2989
- ``Sum``'s lower and upper bounds values can now be Mathics expressions
3090

3191

92+
93+
Miscelanea
94+
----------
95+
96+
- Enlarge of the set of gries_schneider tests
97+
- Improvement in the way builtins modules are loaded at initialization time (#1138).
98+
99+
32100
1.1.1
33101
-----
34102

@@ -48,7 +116,7 @@ Package Updates
48116

49117
Mathics Packages added:
50118

51-
- ``DiscreteMath`CombinatoricaV0.9`` (preferred) aand
119+
- ``DiscreteMath`CombinatoricaV0.9`` (preferred) and
52120
``DiscreteMath`CombinatoricaV0.6``.
53121

54122
Both of these correspond to Steven Skiena's *older* book: "Implementing Discrete Mathematics: Combinatorics and Graph Theory" book.
@@ -90,7 +158,7 @@ New builtins:
90158
- Adding support in ``from_python()`` to convert dictionaries in list of rules.
91159
- Fix OptionsPattern associated symbols.
92160

93-
161+
94162
1.1.0
95163
-----
96164

examples/symbolic_logic/gries_schneider/test_gs.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,12 @@
66
from mathics.core.expression import Expression, Integer, Rational, Symbol
77
from mathics.core.definitions import Definitions
88
from mathics.core.evaluation import Evaluation
9-
from mathics.core.parser import SingleLineFeeder, parse
9+
from mathics.core.parser import MathicsSingleLineFeeder, parse
1010

1111
definitions = Definitions(add_builtin=True)
1212

1313
for i in range(1, 4):
1414
evaluation = Evaluation(definitions=definitions, catch_interrupt=False)
1515

16-
expr = parse(definitions, SingleLineFeeder(f"<< GS{i}.m"))
16+
expr = parse(definitions, MathicsSingleLineFeeder(f"<< GS{i}.m"))
1717
expr.evaluate(evaluation)
18-
19-

mathics/benchmark.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616

1717
import mathics
18-
from mathics.core.parser import parse, MultiLineFeeder, SingleLineFeeder
18+
from mathics.core.parser import parse, MathicsMultiLineFeeder, MathicsSingleLineFeeder
1919
from mathics.core.definitions import Definitions
2020
from mathics.core.evaluation import Evaluation
2121

@@ -126,7 +126,7 @@ def truncate_line(string):
126126

127127
def benchmark_parse(expression_string):
128128
print(" '{0}'".format(truncate_line(expression_string)))
129-
timeit(lambda: parse(definitions, SingleLineFeeder(expression_string)))
129+
timeit(lambda: parse(definitions, MathicsSingleLineFeeder(expression_string)))
130130

131131

132132
def benchmark_parse_file(fname):
@@ -140,7 +140,7 @@ def benchmark_parse_file(fname):
140140
code = f.read().decode('utf-8')
141141

142142
def do_parse():
143-
feeder = MultiLineFeeder(code)
143+
feeder = MathicsMultiLineFeeder(code)
144144
while not feeder.empty():
145145
parse(definitions, feeder)
146146
timeit(do_parse)
@@ -156,13 +156,13 @@ def benchmark_parser():
156156

157157
def benchmark_format(expression_string):
158158
print(" '{0}'".format(expression_string))
159-
expr = parse(definitions, SingleLineFeeder(expression_string))
159+
expr = parse(definitions, MathicsSingleLineFeeder(expression_string))
160160
timeit(lambda: expr.default_format(evaluation, "FullForm"))
161161

162162

163163
def benchmark_expression(expression_string):
164164
print(" '{0}'".format(expression_string))
165-
expr = parse(definitions, SingleLineFeeder(expression_string))
165+
expr = parse(definitions, MathicsSingleLineFeeder(expression_string))
166166
timeit(lambda: expr.evaluate(evaluation))
167167

168168

mathics/builtin/arithmetic.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,6 +1346,11 @@ def apply(self, expr, evaluation):
13461346

13471347
sympy_expr = expr.to_sympy()
13481348
result = _iszero(sympy_expr)
1349+
if result is None:
1350+
# try expanding the expression
1351+
exprexp = Expression("ExpandAll", expr).evaluate(evaluation)
1352+
exprexp = exprexp.to_sympy()
1353+
result = _iszero(exprexp)
13491354
if result is None:
13501355
# Can't get exact answer, so try approximate equal
13511356
numeric_val = Expression("N", expr).evaluate(evaluation)

mathics/builtin/base.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,17 @@ def get_option(options, name, evaluation, pop=False, evaluate=True):
3434
# matter. Also, the quoted string form "X" is ok. all these
3535
# variants name the same option. this matches Wolfram Language
3636
# behaviour.
37-
37+
name = strip_context(name)
3838
contexts = (s + "%s" for s in evaluation.definitions.get_context_path())
3939

4040
for variant in chain(contexts, ('"%s"',)):
4141
resolved_name = variant % name
42-
4342
if pop:
4443
value = options.pop(resolved_name, None)
4544
else:
4645
value = options.get(resolved_name)
47-
4846
if value is not None:
4947
return value.evaluate(evaluation) if evaluate else value
50-
5148
return None
5249

5350

mathics/builtin/evaluation.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,12 @@ class IterationLimit(Predefined):
110110
= $Aborted
111111
#> ClearAll[f];
112112
113-
#> ClearAll[f];
114-
#> f[x_, 0] := x; f[x_, n_] := Module[{y = x + 1}, f[y, n - 1]];
115-
#> Block[{$IterationLimit = 20}, f[0, 100]]
116-
= 100
117-
#> ClearAll[f];
113+
# FIX Later
114+
# #> ClearAll[f];
115+
# #> f[x_, 0] := x; f[x_, n_] := Module[{y = x + 1}, f[y, n - 1]];
116+
# #> Block[{$IterationLimit = 20}, f[0, 100]]
117+
# = 100
118+
# #> ClearAll[f];
118119
"""
119120

120121
name = "$IterationLimit"

mathics/builtin/files.py

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
import os.path as osp
2424
from itertools import chain
2525

26-
from mathics_scanner import TranslateError, FileLineFeeder
26+
from mathics_scanner import TranslateError
27+
from mathics.core.parser import MathicsFileLineFeeder
2728

2829
from mathics.core.expression import (
2930
Expression,
@@ -2183,7 +2184,7 @@ def check_options(options):
21832184
if trace_fn:
21842185
trace_fn(pypath)
21852186
with mathics_open(pypath, "r") as f:
2186-
feeder = FileLineFeeder(f, trace_fn)
2187+
feeder = MathicsFileLineFeeder(f, trace_fn)
21872188
while not feeder.empty():
21882189
try:
21892190
query = parse(definitions, feeder)
@@ -3812,6 +3813,8 @@ class FileHash(Builtin):
38123813
<dt>'FileHash[$file$, $type$]'
38133814
<dd>returns an integer hash of the specified $type$ for the given $file$.</dd>
38143815
<dd>The types supported are "MD5", "Adler32", "CRC32", "SHA", "SHA224", "SHA256", "SHA384", and "SHA512".</dd>
3816+
<dt>'FileHash[$file$, $type$, $format$]'
3817+
<dd>gives a hash code in the specified format.</dd>
38153818
</dl>
38163819
38173820
>> FileHash["ExampleData/sunflowers.jpg"]
@@ -3840,19 +3843,20 @@ class FileHash(Builtin):
38403843
#> FileHash["ExampleData/sunflowers.jpg", xyzsymbol]
38413844
= FileHash[ExampleData/sunflowers.jpg, xyzsymbol]
38423845
#> FileHash["ExampleData/sunflowers.jpg", "xyzstr"]
3843-
= FileHash[ExampleData/sunflowers.jpg, xyzstr]
3846+
= FileHash[ExampleData/sunflowers.jpg, xyzstr, Integer]
38443847
#> FileHash[xyzsymbol]
38453848
= FileHash[xyzsymbol]
38463849
"""
38473850

38483851
rules = {
3849-
"FileHash[filename_String]": 'FileHash[filename, "MD5"]',
3852+
"FileHash[filename_String]": 'FileHash[filename, "MD5", "Integer"]',
3853+
"FileHash[filename_String, hashtype_String]": 'FileHash[filename, hashtype, "Integer"]',
38503854
}
38513855

38523856
attributes = ("Protected", "ReadProtected")
38533857

3854-
def apply(self, filename, hashtype, evaluation):
3855-
"FileHash[filename_String, hashtype_String]"
3858+
def apply(self, filename, hashtype, format, evaluation):
3859+
"FileHash[filename_String, hashtype_String, format_String]"
38563860
py_filename = filename.get_string_value()
38573861

38583862
try:
@@ -3865,7 +3869,7 @@ def apply(self, filename, hashtype, evaluation):
38653869
e.message(evaluation)
38663870
return
38673871

3868-
return Hash.compute(lambda update: update(dump), hashtype.get_string_value())
3872+
return Hash.compute(lambda update: update(dump), hashtype.get_string_value(), format.get_string_value())
38693873

38703874

38713875
class FileDate(Builtin):
@@ -4801,6 +4805,7 @@ def apply(self, pathname, evaluation):
48014805
return SymbolTrue
48024806
return SymbolFalse
48034807

4808+
48044809
class Needs(Builtin):
48054810
"""
48064811
<dl>
@@ -4920,7 +4925,6 @@ def apply(self, context, evaluation):
49204925
curr_ctxt = evaluation.definitions.get_current_context()
49214926
contextstr = curr_ctxt + contextstr[1:]
49224927
context = String(contextstr)
4923-
49244928
if not valid_context_name(contextstr):
49254929
evaluation.message('Needs', 'ctx', Expression(
49264930
'Needs', context), 1, '`')
@@ -4930,19 +4934,11 @@ def apply(self, context, evaluation):
49304934
if test_loaded.is_true():
49314935
# Already loaded
49324936
return SymbolNull
4933-
4934-
# TODO: Figure out why this raises the message:
4935-
# "Select::normal: Nonatomic expression expected."
4936-
already_loaded = Expression('MemberQ',
4937-
Symbol('System`$Packages'), context)
4938-
already_loaded = already_loaded.evaluate(evaluation).is_true()
4939-
if already_loaded:
4940-
return SymbolNull
4941-
49424937
result = Expression('Get', context).evaluate(evaluation)
49434938

49444939
if result == SymbolFailed:
49454940
evaluation.message("Needs", "nocont", context)
49464941
return SymbolFailed
49474942

49484943
return SymbolNull
4944+

0 commit comments

Comments
 (0)