Skip to content

Commit 14889d7

Browse files
committed
partial
1 parent 161705b commit 14889d7

File tree

11 files changed

+214
-67
lines changed

11 files changed

+214
-67
lines changed

mathics/builtin/arithfns/basic.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ class Divide(BinaryOperator):
159159

160160
grouping = "Left"
161161
operator = "/"
162+
162163
rules = {
163164
"Divide[x_, y_]": "Times[x, Power[y, -1]]",
164165
"MakeBoxes[Divide[x_, y_], f:StandardForm|TraditionalForm]": (
@@ -405,13 +406,11 @@ class Power(BinaryOperator, MPMathFunction):
405406
Expression(SymbolPattern, Symbol("x"), Expression(SymbolBlank)),
406407
RationalOneHalf,
407408
): "HoldForm[Sqrt[x]]",
408-
(("InputForm",), "x_ ^ y_"): (
409+
(("InputForm", "OutputForm"), "x_ ^ y_"): (
409410
'Infix[{HoldForm[x], HoldForm[y]}, "^", 590, Right]'
410411
),
411412
("", "x_ ^ y_"): (
412-
# "PrecedenceForm[Superscript[PrecedenceForm[HoldForm[x], 590],"
413-
# " HoldForm[y]], 590]"
414-
"PrecedenceForm[Superscript[HoldForm[x],"
413+
"PrecedenceForm[Superscript[PrecedenceForm[HoldForm[x], 590],"
415414
" HoldForm[y]], 590]"
416415
),
417416
("", "x_ ^ y_?Negative"): (

mathics/builtin/forms/output.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -568,15 +568,16 @@ class OutputForm(FormBaseClass):
568568
= -Graphics-
569569
"""
570570

571+
formats = {"OutputForm[s_String]": "s"}
571572
summary_text = "plain-text output format"
572573

573-
def apply_makeboxes(self, expr, form, evaluation):
574-
"""MakeBoxes[OutputForm[expr_], form_]"""
575-
text2d = expression_to_2d_text(expr, evaluation, form).text
576-
elem1 = PaneBox(String(text2d))
577-
elem2 = Expression(SymbolOutputForm, expr)
578-
result = InterpretationBox(elem1, elem2)
579-
return result
574+
# def apply_makeboxes(self, expr, form, evaluation):
575+
# """MakeBoxes[OutputForm[expr_], form_]"""
576+
# text2d = expression_to_2d_text(expr, evaluation, form).text
577+
# elem1 = PaneBox(String(text2d))
578+
# elem2 = Expression(SymbolOutputForm, expr)
579+
# result = InterpretationBox(elem1, elem2)
580+
# return result
580581

581582

582583
class PythonForm(FormBaseClass):

mathics/builtin/layout.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,13 @@
1616
from mathics.builtin.makeboxes import MakeBoxes
1717
from mathics.builtin.options import options_to_rules
1818
from mathics.core.atoms import Real, String
19-
from mathics.core.builtin import BinaryOperator, Builtin, Operator
19+
from mathics.core.builtin import (
20+
BinaryOperator,
21+
Builtin,
22+
Operator,
23+
PostfixOperator,
24+
PrefixOperator,
25+
)
2026
from mathics.core.expression import Evaluation, Expression
2127
from mathics.core.list import ListExpression
2228
from mathics.core.symbols import Symbol
@@ -214,7 +220,7 @@ class NonAssociative(Builtin):
214220
summary_text = "non-associative operator"
215221

216222

217-
class Postfix(BinaryOperator):
223+
class Postfix(PostfixOperator):
218224
"""
219225
<url>:WMA link:https://reference.wolfram.com/language/ref/Postfix.html</url>
220226
@@ -294,7 +300,7 @@ class PrecedenceForm(Builtin):
294300
summary_text = "parenthesize with a precedence"
295301

296302

297-
class Prefix(BinaryOperator):
303+
class Prefix(PrefixOperator):
298304
"""
299305
<url>:WMA link:https://reference.wolfram.com/language/ref/Prefix.html</url>
300306

mathics/builtin/list/associations.py

Lines changed: 116 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,83 @@
1010

1111

1212
from mathics.builtin.box.layout import RowBox
13-
from mathics.core.atoms import Integer
13+
from mathics.builtin.layout import Row
14+
from mathics.core.atoms import Integer, String
1415
from mathics.core.attributes import A_HOLD_ALL_COMPLETE, A_PROTECTED
1516
from mathics.core.builtin import Builtin, Test
1617
from mathics.core.convert.expression import to_mathics_list
1718
from mathics.core.evaluation import Evaluation
1819
from mathics.core.expression import Expression
1920
from mathics.core.symbols import Symbol, SymbolTrue
20-
from mathics.core.systemsymbols import SymbolAssociation, SymbolMakeBoxes, SymbolMissing
21-
from mathics.eval.lists import list_boxes
21+
from mathics.core.systemsymbols import (
22+
SymbolAssociation,
23+
SymbolHoldForm,
24+
SymbolInputForm,
25+
SymbolMakeBoxes,
26+
SymbolMathMLForm,
27+
SymbolMissing,
28+
SymbolOutputForm,
29+
SymbolStandardForm,
30+
SymbolTeXForm,
31+
SymbolTraditionalForm,
32+
)
33+
from mathics.eval.lists import list_boxes, riffle
34+
from mathics.eval.makeboxes import do_format
35+
from mathics.eval.strings import eval_ToString
36+
37+
38+
class NotAnAssociationItem(Exception):
39+
pass
40+
41+
42+
SymbolInterpretation = Symbol("System`Interpretation")
43+
44+
ASSOCIATION_DELIMITER_FORMATS = {
45+
SymbolInputForm: {"start": String("<|"), "sep": String(", "), "end": String("|>")},
46+
SymbolOutputForm: {"start": String("<|"), "sep": String(","), "end": String("|>")},
47+
SymbolStandardForm: {
48+
"start": String("<|"),
49+
"sep": String(","),
50+
"end": String("|>"),
51+
},
52+
SymbolTraditionalForm: {
53+
"start": String("<|"),
54+
"sep": String(","),
55+
"end": String("|>"),
56+
},
57+
SymbolTeXForm: {"start": String("<|"), "sep": String(", "), "end": String("|>")},
58+
SymbolMathMLForm: {"start": String("<|"), "sep": String(","), "end": String("|>")},
59+
}
60+
61+
62+
def format_association(rules: tuple, evaluation: Evaluation, form: Symbol):
63+
"""Association[rules___]"""
64+
delimiters = ASSOCIATION_DELIMITER_FORMATS[form]
65+
66+
def yield_rules(rule_tuple):
67+
for rule in rule_tuple:
68+
if rule.has_form(("Rule", "RuleDelayed"), 2):
69+
yield rule
70+
elif rule.has_form(
71+
(
72+
"List",
73+
"Association",
74+
),
75+
None,
76+
):
77+
for subrule in yield_rules(rule.elements):
78+
yield subrule
79+
else:
80+
raise NotAnAssociationItem
81+
82+
try:
83+
items = riffle(
84+
[do_format(rule, evaluation, form) for rule in yield_rules(rules)],
85+
delimiters["sep"],
86+
)
87+
return Row(to_mathics_list(delimiters["start"], *items, delimiters["end"]))
88+
except NotAnAssociationItem:
89+
return None
2290

2391

2492
class Association(Builtin):
@@ -54,34 +122,52 @@ class Association(Builtin):
54122

55123
summary_text = "an association between keys and values"
56124

57-
def eval_makeboxes(self, rules, f, evaluation: Evaluation):
58-
"""MakeBoxes[<|rules___|>,
59-
f:StandardForm|TraditionalForm|OutputForm|InputForm]"""
60-
61-
def validate(exprs):
62-
for expr in exprs:
63-
if expr.has_form(("Rule", "RuleDelayed"), 2):
64-
pass
65-
elif expr.has_form(("List", "Association"), None):
66-
if not validate(expr.elements):
67-
return False
68-
else:
69-
return False
70-
return True
71-
72-
rules = rules.get_sequence()
73-
if self.error_idx == 0 and validate(rules) is True:
74-
expr = RowBox(*list_boxes(rules, f, evaluation, "<|", "|>"))
75-
else:
76-
self.error_idx += 1
77-
symbol = Expression(SymbolMakeBoxes, SymbolAssociation, f)
78-
expr = RowBox(
79-
symbol.evaluate(evaluation), *list_boxes(rules, f, evaluation, "[", "]")
125+
def format_association_input(self, rules, evaluation: Evaluation, expression):
126+
"""InputForm: Association[rules___]"""
127+
print("format association input", rules)
128+
formatted = format_association(
129+
rules.get_sequence(), evaluation, SymbolInputForm
130+
)
131+
if formatted is None:
132+
return None
133+
print(" formatted elements:")
134+
elements = formatted.elements[0].elements
135+
for elem in elements:
136+
print(" ", elem)
137+
elems = tuple(
138+
(
139+
eval_ToString(elem, SymbolOutputForm, "unicode", evaluation).value
140+
for elem in elements
80141
)
81-
82-
if self.error_idx > 0:
83-
self.error_idx -= 1
84-
return expr
142+
)
143+
elems = tuple((elem[1:-1] if elem[0] == '"' else elem for elem in elems))
144+
print(" elems", elems)
145+
result_str = "".join(elems)
146+
result = Expression(SymbolOutputForm, String(result_str))
147+
print(" result->", result)
148+
return result
149+
150+
def format_association_output(self, rules, evaluation: Evaluation):
151+
"""OutputForm: Association[rules___]"""
152+
return format_association(rules.get_sequence(), evaluation, SymbolOutputForm)
153+
154+
def format_association_standard(self, rules, evaluation: Evaluation):
155+
"""StandardForm: Association[rules___]"""
156+
return format_association(rules.get_sequence(), evaluation, SymbolStandardForm)
157+
158+
def format_association_traditional(self, rules, evaluation: Evaluation):
159+
"""TraditionalForm: Association[rules___]"""
160+
return format_association(
161+
rules.get_sequence(), evaluation, SymbolTraditionalForm
162+
)
163+
164+
def format_association_tex(self, rules, evaluation: Evaluation):
165+
"""TeXForm: Association[rules___]"""
166+
return format_association(rules.get_sequence(), evaluation, SymbolTeXForm)
167+
168+
def format_association_mathml(self, rules, evaluation: Evaluation):
169+
"""MathMLForm: Association[rules___]"""
170+
return format_association(rules.get_sequence(), evaluation, SymbolMathMLForm)
85171

86172
def eval(self, rules, evaluation: Evaluation):
87173
"Association[rules__]"

mathics/builtin/makeboxes.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,9 +374,9 @@ class MakeBoxes(Builtin):
374374
'MakeBoxes[Infix[head[elements], StringForm["~`1`~", head]], f]'
375375
),
376376
"MakeBoxes[expr_]": "MakeBoxes[expr, StandardForm]",
377-
"MakeBoxes[(form:StandardForm|TraditionalForm|TeXForm|"
377+
"MakeBoxes[(form:StandardForm|TraditionalForm|OutputForm|TeXForm|"
378378
"MathMLForm)[expr_], StandardForm|TraditionalForm]": ("MakeBoxes[expr, form]"),
379-
"MakeBoxes[(form:StandardForm|MathMLForm|TeXForm)[expr_], OutputForm]": "MakeBoxes[expr, form]",
379+
"MakeBoxes[(form:StandardForm|OutputForm|MathMLForm|TeXForm)[expr_], OutputForm]": "MakeBoxes[expr, form]",
380380
"MakeBoxes[(form:FullForm|InputForm)[expr_], StandardForm|TraditionalForm|OutputForm]": "StyleBox[MakeBoxes[expr, form], ShowStringCharacters->True]",
381381
"MakeBoxes[PrecedenceForm[expr_, prec_], f_]": "MakeBoxes[expr, f]",
382382
"MakeBoxes[Style[expr_, OptionsPattern[Style]], f_]": (

mathics/builtin/numbers/diffeqns.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ class DSolve(Builtin):
3131
= {{y[x] -> C[1] E ^ (-x) + C[2] E ^ x}}
3232
3333
>> DSolve[y''[x] == y[x], y, x]
34-
= {{y -> (Function[{x}, C[1] E ^ (-x) + C[2] E ^ x])}}
34+
= {{y -> Function[{x}, C[1] E ^ (-x) + C[2] E ^ x]}}
3535
3636
DSolve can also solve basic PDE
3737
>> DSolve[D[f[x, y], x] / f[x, y] + 3 D[f[x, y], y] / f[x, y] == 2, f, {x, y}]
38-
= {{f -> (Function[{x, y}, E ^ (x / 5 + 3 y / 5) C[1][3 x - y]])}}
38+
= {{f -> Function[{x, y}, E ^ (x / 5 + 3 y / 5) C[1][3 x - y]]}}
3939
4040
>> DSolve[D[f[x, y], x] x + D[f[x, y], y] y == 2, f[x, y], {x, y}]
4141
= {{f[x, y] -> 2 Log[x] + C[1][y / x]}}

mathics/builtin/recurrence.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,18 @@ class RSolve(Builtin):
4040
4141
No boundary conditions gives two general parameters:
4242
>> RSolve[{a[n + 2] == a[n]}, a, n]
43-
= {{a -> (Function[{n}, C[0] + C[1] (-1) ^ n])}}
43+
= {{a -> Function[{n}, C[0] + C[1] (-1) ^ n]}}
4444
4545
Include one boundary condition:
4646
>> RSolve[{a[n + 2] == a[n], a[0] == 1}, a, n]
4747
= ...
4848
## Order of terms depends on interpreter:
49-
## PyPy: {{a -> (Function[{n}, 1 - C[1] + C[1] -1 ^ n])}}
50-
## CPython: {{a -> (Function[{n}, 1 + C[1] -1 ^ n - C[1]])}
49+
## PyPy: {{a -> Function[{n}, 1 - C[1] + C[1] -1 ^ n]}}
50+
## CPython: {{a -> Function[{n}, 1 + C[1] -1 ^ n - C[1]]}
5151
5252
Geta "pure function" solution for a with two boundary conditions:
5353
>> RSolve[{a[n + 2] == a[n], a[0] == 1, a[1] == 4}, a, n]
54-
= {{a -> (Function[{n}, 5 / 2 - 3 (-1) ^ n / 2])}}
54+
= {{a -> Function[{n}, 5 / 2 - 3 (-1) ^ n / 2]}}
5555
"""
5656

5757
messages = {

mathics/core/builtin.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,6 +1167,12 @@ def __init__(self, *args, **kwargs):
11671167
operator = ascii_operator_to_symbol.get(self.operator, self.__class__.__name__)
11681168

11691169
if self.default_formats:
1170+
formats = {
1171+
op_pattern: "HoldForm[Infix[{%s}, %s, %d, %s]]"
1172+
% (replace_items, operator, self.precedence, self.grouping)
1173+
}
1174+
formats.update(self.formats)
1175+
self.formats = formats
11701176
formatted = "MakeBoxes[Infix[{%s}, %s, %d,%s], form]" % (
11711177
replace_items,
11721178
operator,

0 commit comments

Comments
 (0)