diff --git a/mathics/core/assignment.py b/mathics/core/assignment.py index 9b3974871..e02a8ad99 100644 --- a/mathics/core/assignment.py +++ b/mathics/core/assignment.py @@ -176,11 +176,13 @@ def is_protected(tag: str, definitions: Definitions) -> bool: def normalize_lhs(lhs, evaluation): """ - Process the lhs in a way that + Process the lhs in a way that: + * if it is a conditional expression, reduce it to a shallow conditional expression ( Conditional[Conditional[...],tst] -> Conditional[stripped_lhs, tst]) with `stripped_lhs` the result of strip all the conditions from lhs. + * if ``stripped_lhs`` is not a ``List`` or a ``Part`` expression, evaluate the elements. diff --git a/mathics/core/builtin.py b/mathics/core/builtin.py index ace875fa2..aa2806f70 100644 --- a/mathics/core/builtin.py +++ b/mathics/core/builtin.py @@ -118,9 +118,9 @@ def __init__(self, name, count, expected): class Builtin: """ - A base class for a Built-in function symbols, like List, or - variables, like $SystemID, and Built-in Objects, like - DateTimeObject. + A base class for a Built-in function symbols, like ``List``, or + variables, like ``$SystemID``, and Built-in Objects, like + ``DateTimeObject``. Some of the class variables of the Builtin object are used to create a definition object for that built-in symbol. In particular, @@ -136,11 +136,11 @@ class Builtin: For example: - ``` + .. code-block:: python + def eval(x, evaluation): "F[x_Real]" return Expression(Symbol("G"), x*2) - ``` adds a ``FunctionApplyRule`` to the symbol's definition object that implements ``F[x_]->G[x*2]``. diff --git a/mathics/core/convert/expression.py b/mathics/core/convert/expression.py index b8acc4e31..22963851a 100644 --- a/mathics/core/convert/expression.py +++ b/mathics/core/convert/expression.py @@ -69,10 +69,13 @@ def to_mathics_list( elements_conversion_fn: Callable = from_python, ) -> ListExpression: """ - This is an expression constructor for list that can be used when the elements are not Mathics - objects. For example: - to_mathics_list(1, 2, 3) - to_mathics_list(1, 2, 3, elements_conversion_fn=Integer) + This is an expression constructor for list that can be used when + the elements are not Mathics objects. + + For example:: + + to_mathics_list(1, 2, 3) + to_mathics_list(1, 2, 3, elements_conversion_fn=Integer) """ elements_tuple, elements_properties, _ = convert_expression_elements( elements, elements_conversion_fn diff --git a/mathics/core/evaluation.py b/mathics/core/evaluation.py index 52fde33d3..e50c76b3d 100644 --- a/mathics/core/evaluation.py +++ b/mathics/core/evaluation.py @@ -541,16 +541,17 @@ def publish(self, tag: str, *args, **kwargs) -> None: class Message(_Out): def __init__(self, symbol: Union[Symbol, str], tag: str, text: str) -> None: """ - A Mathics3 message of some sort. symbol_or_string can either be a symbol or a - string. + A Mathics3 message of some sort. ``symbol`` can either + be a symbol or a string. - Symbol: classifies which predefined or variable this comes from? If there is none - use a string. - tag: a short slug string that indicates the kind of message + ``symbol``: classifies which predefined or variable this comes + from? If there is none use a string. + + ``tag``: a short slug string that indicates the kind of message In Django we need to use a string for symbol, since we need - something that is JSON serializable and a Mathics3 Symbol is not - like this. + something that is JSON serializable and a Mathics3 Symbol is + not like this. """ super(Message, self).__init__() self.is_message = True # Why do we need this? @@ -625,8 +626,10 @@ class Result: In particular, there are the following fields: result: the actual result produced. - out: a list of additional output strings. These are warning or error messages. See "form" - for exactly what they are. + + out: a list of additional output strings. These are warning or + error messages. See "form" for exactly what they are. + form: is the *format* of the result which tags the kind of result . Think of this as something like a mime/type. Some formats: diff --git a/mathics/core/expression.py b/mathics/core/expression.py index 80de31c6a..a23805a95 100644 --- a/mathics/core/expression.py +++ b/mathics/core/expression.py @@ -256,14 +256,15 @@ class Expression(BaseElement, NumericOperators, EvalMixin): function. positional Arguments: - - head -- The head of the M-Expression - - *elements - optional: the remaining elements - - *literal_values - optional: if this is not None, then all elements - are (Python) literal values and literal_values - contains these literals. + + - ``head`` -- The head of the M-Expression + - ``*elements`` - optional: the remaining elements + - ``*literal_values`` - optional: if this is not ``None``, then all elements + are (Python) literal values and ``literal_values`` contains these literals. Keyword Arguments: - - elements_properties -- properties of the collection of elements + + - ``elements_properties`` -- properties of the collection of elements """ @@ -662,35 +663,43 @@ def flatten_with_respect_to_head( self, head: Symbol, pattern_only=False, callback=None, level=100 ) -> "Expression": """ - Flatten elements in self which have `head` in them. + Flatten elements in ``self`` which have ``head`` in them. The idea is that in an expression like: Expression(Plus, 1, Expression(Plus, 2, 3), 4) - when "Plus" is specified as the head, this expression should get changed to: + when "Plus" is specified as the head, this expression should + get changed to:: Expression(Plus, 1, 2, 3, 4) - In other words, all of the Plus operands are collected to together into one operation. - This is more efficiently evaluated. Note that we only flatten Plus functions, not other functions, - whether or not they contain Plus. + In other words, all of the ``Plus`` operands are collected to + together into one operation. This is more efficiently + evaluated. Note that we only flatten ``Plus`` functions, not other + functions, whether or not they contain ``Plus``. + + So in:: - So in: Expression(Plus, Times(1, 2, Plus(3, 4))) the expression is unchanged. - head: head element to be consider flattening on. Only expressions with this will be flattened. - This is always the head element or the next head element of the expression that the - elements are drawn from + ``head``: head element to be consider flattening on. Only + expressions with this will be flattened. This is always + the head element or the next head element of the + expression that the elements are drawn from + + ``callback``: a callback function called each time a element + is flattened. + ``level``: maximum depth to flatten. This often isn't used and + seems to have been put in as a potential safety + measure possibly for the future. If you don't want a + limit on flattening pass a negative number. - callback: a callback function called each time a element is flattened. - level: maximum depth to flatten. This often isn't used and seems to have been put in - as a potential safety measure possibly for the future. If you don't want a limit - on flattening pass a negative number. - pattern_only: if True, just apply to elements that are pattern_sequence (see ExpressionPattern.get_wrappings) + ``pattern_only``: if ``True``, just apply to elements that are + pattern_sequence (see ``ExpressionPattern.get_wrappings``) """ from mathics.core.convert.expression import to_expression_with_specialization @@ -1112,7 +1121,7 @@ def has_symbol(self, symbol_name: str) -> bool: ) def restructure(self, head, elements, evaluation, structure_cache=None, deps=None): - """Faster equivalent of: Expression(head, *elements) + """Faster equivalent of: ``Expression(head, *elements)`` The caller guarantees that _all_ elements are either from self.elements (or its subtrees) or from one of the expression given @@ -1645,10 +1654,12 @@ def sort(self, pattern=False): def do_apply_rules(self, rules, evaluation, level=0, options=None): """ - for rule in rules: - result = rule.apply(self, evaluation, fully=False) - if result is not None: - return result + .. code-block:: python + + for rule in rules: + result = rule.apply(self, evaluation, fully=False) + if result is not None: + return result """ from mathics.core.convert.expression import to_expression_with_specialization diff --git a/mathics/core/list.py b/mathics/core/list.py index 496779189..b91f954dc 100644 --- a/mathics/core/list.py +++ b/mathics/core/list.py @@ -19,11 +19,13 @@ class ListExpression(Expression): A Mathics3 List is a specialization of Expression where the head is SymbolList. positional Arguments: - - *elements - optional: the remaining elements + + - ``*elements`` - optional: the remaining elements Keyword Arguments: - - elements_properties -- properties of the collection of elements - - literal_values -- if this is not None, then it is a tuple of Python values + + - ``elements_properties`` -- properties of the collection of elements + - ``literal_values`` -- if this is not ``None``, then it is a tuple of Python values """ _is_literal: bool diff --git a/mathics/core/load_builtin.py b/mathics/core/load_builtin.py index 89121915e..5170d1a12 100644 --- a/mathics/core/load_builtin.py +++ b/mathics/core/load_builtin.py @@ -237,7 +237,7 @@ def import_and_load_builtins(): def import_builtin_module(import_name: str, modules: List[ModuleType]): """ - Imports ``the list of Mathics3 Built-in modules so that inside + Imports the list of Mathics3 Built-in modules so that inside Mathics3 Builtin Functions, like Plus[], List[] are defined. List ``module_names`` is updated. diff --git a/mathics/core/rules.py b/mathics/core/rules.py index 85a5b3d17..1af7ffddc 100644 --- a/mathics/core/rules.py +++ b/mathics/core/rules.py @@ -19,16 +19,15 @@ On the other hand, suppose that we define a `FunctionApplyRule` that associates `F[x_]` with the function: -``` -... -class MyFunction(Builtin): - ... - def eval_f(self, x, evaluation) -> Optional[Expression]: - "F[x_]" # pattern part of FunctionApplyRule - if x>3: - return Expression(SymbolPower, x, Integer2) - return None -``` +.. code-block:: python + + class MyFunction(Builtin): + ... + def eval_f(self, x, evaluation) -> Optional[Expression]: + "F[x_]" # pattern part of FunctionApplyRule + if x>3: + return Expression(SymbolPower, x, Integer2) + return None Then, if we apply the rule to `F[2]`, the function is evaluated returning `None`. Then, in the evaluation loop, we get the same effect as if the pattern didn't match with the expression. The loop continues then with the next rule associated with `F`. @@ -217,14 +216,13 @@ class Rule(BaseRule): finishes. Here is an example of a Rule:: - F[x_] -> x^2 (* The same thing as: Rule[x_, x^2] *) + F[x_] -> x^2 (* The same thing as: Rule[x_, x^2] *) ``F[x_]`` is a pattern and ``x^2`` is the replacement term. When applied to the expression ``G[F[1.], F[a]]`` the result is ``G[1.^2, a^2]`` - Note: we want Rules to be serializable so that we can dump and restore Rules in order to make startup time faster. @@ -315,8 +313,8 @@ class FunctionApplyRule(BaseRule): when applied to the expression ``SetAttributes[F, NumericFunction]`` - sets the attribute ``NumericFunction`` in the definition of the symbol ``F`` and - returns Null (``SymbolNull`)`. + sets the attribute ``NumericFunction`` in the definition of the symbol + ``F`` and returns Null (``SymbolNull``). This will cause `Expression.evaluate() to perform an additional ``rewrite_apply_eval()`` step. diff --git a/mathics/core/structure.py b/mathics/core/structure.py index 3602d6afd..2f434e5fb 100644 --- a/mathics/core/structure.py +++ b/mathics/core/structure.py @@ -46,7 +46,8 @@ def slice(self, expr, py_slice): class UnlinkedStructure(Structure): """ UnlinkedStructure produces Expressions that are not linked to "origins" in terms of cache. - This produces the same thing as doing Expression(head, *elements). + + This produces the same thing as doing ``Expression(head, *elements)``. """ def __init__(self, head): diff --git a/mathics/core/symbols.py b/mathics/core/symbols.py index a612c112b..87922c9f1 100644 --- a/mathics/core/symbols.py +++ b/mathics/core/symbols.py @@ -29,17 +29,18 @@ class NumericOperators: """ This is a mixin class for Element-like objects that might have numeric values. - It adds or "mixes in" numeric functions for these objects like round_to_float(). + It adds or "mixes in" numeric functions for these objects like ``round_to_float()``. It also adds methods to the class to facilite building - ``Expression``s in the Mathics Python code using Python syntax. + ``Expression`` s in the Mathics Python code using Python syntax. - So for example, instead of writing in Python: + So for example, instead of writing in Python:: to_expression("Abs", -8) Expression(SymbolPlus, Integer1, Integer2) - you can instead have: + you can instead have:: + abs(Integer(-8)) Integer(1) + Integer(2) """