Expressions

Mathematical expressions in Myokit are represented as trees of Expression objects. For example the expression 5 + 2 is represented as a Plus expression with two operands of the type Number. All expressions extend the Expression base class described below.

Creating expression trees manually is a labour-intesive process. In most cases, expressions will be created by the parser.

class myokit.Expression(operands=None)

Myokit’s most generic interface for expressions. All expressions extend this class.

Expressions are immutable objects.

Expression objects have an _rbp property determining their right binding power (myokit uses a top-down operator precedence parsing scheme) and an optional _token property that may contain the text token this expression object was originally parsed from.

Abstract class

bracket(op=None)

Checks if the given operand (which should be an operand of this expression) needs brackets around it when writing a mathematical expression.

For example, 5 + 3 will require a bracket when used in a multiplication (e.g. 2 * (5 + 3)), so calling bracket(5 + 3) on a multiplication will return True.

Alternatively, when used in a function the expression will not require brackets, as the function (e.g. sin()) already provides them, so calling bracket(5 + 3) on a function will return False.

clone(subst=None, expand=False, retain=None)

Clones this expression.

The optional argument subst can be used to pass a dictionary mapping expressions to a substitute. Any expression that finds itself listed as a key in the dictionary will return this replacement value instead.

The argument expand can be set to True to expand all variables other than states. For example, if x = 5 + 3 * y and y = z + sqrt(2) and dot(z) = ..., cloning x while expanding will yield x = 5 + 3 * (z + sqrt(2)). When expanding, all constants are converted to numerical values. To maintain some of the constants, pass in a list of variables or variable names as retain.

Substitution takes precedence over expansion: A call such as e.clone(subst={x:y}, expand=True) will replace ``x by y but not expand any names appearing in y.

code(component=None)

Returns this expression formatted in mmt syntax.

When Name objects are encountered, the fullly qualified name of the myokit.Variable that they refer to is rendered, with the following exceptions:

  • if the variable’s component matches the argument component or the variable is nested, then the local variable name is used

  • if the given component has an alias for the variable, this alias is used.

contains_type(kind)

Returns True if this expression tree contains an expression of the given type.

depends_on(lhs, deep=False)

Returns True if this Expression depends on the given LhsExpresion.

With deep=False (default), only dependencies appearing directly in the expression are checked. With deep=True the method also checks the right-hand side equation defined in the model for any Name or Derivative it encounters.

depends_on_state(deep=False)

Returns True if this Expression depends on one or more state variables.

With deep=False (default), only dependencies appearing directly in the expression are checked. With deep=True the method also checks the right-hand side equation defined in the model for any Name or Derivative it encounters.

diff(lhs, independent_states=True)

Returns an expression representing the partial derivative of this expression with respect to the expression lhs.

The argument lhs must be a Name or a InitialValue, taking derivatives with respect to a class:Derivative or PartialDerivative is not supported.

Expressions involving variables

Partial derivatives are determined recursively. If, at any point in this recursion, a Name or Derivative is encountered, this is handled in the following way:

  • The partial derivative of any Name with respect to an identical Name is 1 (without units / dimensionless).

  • The partial derivative of a Name referencing a state variable is zero if independent_states=True, but will otherwise be represented as a PartialDerivative.

  • The partial derivative of a Derivative or of a Name referencing a non-state variable, will both be determined based on the corresponding right-hand side expression. If this references the lhs, then a PartialDerivative will be returned. If it does not reference the lhs and independent_states=True, then zero will be returned. If it does not reference the lhs, but independent_states=False and one or more states are referenced, then a PartialDerivative will be returned.

  • The partial derivative of a Name referencing a bound variable is zero.

Simplification

Some effort is made to eliminate expressions that evaluate to zero, but no further simplification is performed. Multiplications by 1 are preserved as these can provide valuable unit information.

Conditional expressions

When calculating derivatives, the following simplifying assumptions are made with respect to conditional expressions:

  • When evaluating conditional expressions (If and Piecewise), the discontinuities at the condition boundaries are ignored. Instead, the method simply returns a similar conditional expression with the original operands replaced by their derivatives, e.g. if(condition, a, b) becomes if(condition, a', b').

Discontinuous functions

Similarly, some functions are discontinuous so that their derivatives are undefined at certain points, but this method returns the right-derivative for those points. In particular:

  • The true derivative of floor(x) is zero when x is not an integer and undefined if it is, but this method always returns zero.

  • Similarly, the true derivative of ceil(x) is undefined when x is an integer, but this method always returns zero.

  • The true derivative of an integer division a // b with respect to either a or b is zero when a is not an integer multiple of b, and otherwise undefined; but this method always returns zero.

  • The true derivative of the remainder operation a(x) % b(x) = a - b * floor(a / b) is da/dx - db/dx * floor(a/b) - b * d/dx floor(a/b), but (as above) this method assumes the derivative of the floor function is zero, and so will always return da/dx - db/dx * floor(a/b).

  • The true derivative of abs(f(x)) is f’(x) for x > 0, -f’(x) for x < 0, and undefined for x == 0, but this method will return f'(x) for x >= 0 and -f'(x)``s for ``x < 0.

Non-integer powers

Since a(x)^b(x) is undefined for non-integer b(x) when a(x) < 0`, the derivative of a(x)^b(x) is only defined if a(x) >= 0 or b'(x) = 0. No errors or warnings are given if the derivative is undefined, until the equations are evaluated (note that at this point evaluation of a(x)^b(x) will also fail).

eval(subst=None, precision=64)

Evaluates this expression and returns the result.

The optional argument subst can be used to pass a dictionary mapping LhsExpression objects to expressions or numbers to substitute them with.

For debugging purposes, the argument precision can be set to myokit.SINGLE_PRECISION to perform the evaluation with 32 bit floating point numbers.

Note: This operation will fail if the expression contains Name objects with a value other than an Expression or (an object that can be cast to) a float.

eval_unit(mode=1)

Evaluates the unit this expression should have, based on the units of its variables and literals.

Incompatible units may result in a myokit.IncompatibleUnitError being raised. The method for dealing with unspecified units can be set using the mode argument.

Using myokit.UNIT_STRICT any unspecified unit will be treated as dimensionless. For example adding None + [kg] will be treated as [1] + [kg] which will raise an error. Similarly, None * [m] will be taken to mean [1] * [m] which is valid, and None * None will return [1]. In strict mode, functions such as exp(), which expect dimensionless input will raise an error if given a non-dimensionless operator.

Using myokit.UNIT_TOLERANT unspecified units will try to be ignored where possible. For example, the expression None + [kg] will be treated as [kg] + [kg], while None * [m] will be read as [1] * [m] and None * None will return None. Functions such as exp() will not raise an error, but simply return a dimensionless value.

The method is intended to be used to check the units in a model, so every branch of an expression is evaluated, even if it won’t affect the final result.

In strict mode, this method will always either return a myokit.Unit or raise an myokit.IncompatibleUnitError. In tolerant mode, None will be returned if the units are unknown.

is_conditional()

Returns True if and only if this expression’s tree contains a conditional statement.

is_constant()

Returns true if this expression contains no references or only references to variables with a constant value.

is_derivative(var=None)

Returns True only if this is a time-derivative, i.e. a myokit.Derivative instance (and references the variable var, if given).

is_literal()

Returns True if this expression does not contain any references.

is_name(var=None)

Returns True only if this expression is a myokit.Name (and references the variable var, if given).

is_number(value=None)

Returns True only if this expression is a myokit.Number.

If the optional argument value is set, it will also return False if the number does not have the given value.

is_state_value()

Returns True if this expression is a Name pointing to the current value of a state variable.

operator_rep()

Returns a representation of this expression’s type. (For example ‘+’ or ‘*’)

pyfunc(use_numpy=True)

Converts this expression to Python and returns the new function’s handle.

By default, when converting mathematical functions such as log, the version from numpy (i.e. numpy.log) is used. To use the built-in math module instead, set use_numpy=False.

pystr(use_numpy=False)

Returns a string representing this expression in Python syntax.

By default, built-in functions such as ‘exp’ are converted to the Python version ‘math.exp’. To use the numpy versions, set numpy=True.

references()

Returns a set containing all references to variables made in this expression.

tree_str()

Returns a string representing the parse tree corresponding to this expression.

validate()

Validates operands, checks cycles without following references. Will raise exceptions if errors are found.

walk(allowed_types=None)

Returns an iterator over this expression tree (depth-first). This is a slow operation. Do _not_ use in performance sensitive code!

Example:

5 + (2 * sqrt(x))

1) Plus
2) Number(5)
3) Multiply
4) Number(2)
5) Sqrt
6) Name(x)

To return only expressions of certain types, pass in a sequence allowed_typess, containing all types desired in the output.

Names and numbers

The simplest types of expression are atomic expressions, which have either a definite, numerical value (Number) or point to a variable (Name).

For equations a distinction is made between what may appear on the left-hand side (lhs) and right-hand side (rhs). To indicate this difference in code, all left-hand side equations must extend the class LhsExpression.

class myokit.Number(value, unit=None)

Represents a number with an optional unit for use in Myokit expressions. All numbers used in Myokit expressions are floating point.

>>> import myokit
>>> x = myokit.Number(10)
>>> print(x)
10
>>> x = myokit.Number(5.00, myokit.units.V)
>>> print(x)
5 [V]

Arguments:

value

A numerical value (something that can be converted to a float). Number objects are immutable so no clone constructor is provided.

unit

A unit to associate with this number. If no unit is specified the number’s unit will be left undefined.

Extends: Expression

bracket(op=None)

See Expression.bracket().

clone(subst=None, expand=False, retain=None)

See Expression.clone().

convert(unit)

Returns a copy of this number in a different unit. If the two units are not compatible a myokit.IncompatibleUnitError is raised.

is_constant()

See Expression.is_constant().

is_literal()

See Expression.is_literal().

is_number(value=None)

See Expression.is_number().

unit()

Returns the unit associated with this Number or None if no unit was specified.

value()

Returns the value of this number.

class myokit.LhsExpression(operands=None)

An expression referring to the left-hand side of an equation.

Running eval() on an LhsExpression returns the evaluation of the associated right-hand side. This may result in errors if no right-hand side is defined. In other words, this will only work if the expression is embedded in a variable’s defining equation.

Abstract class, extends: Expression

is_constant()

See Expression.is_constant().

is_literal()

See Expression.is_literal().

rhs()

Returns the RHS expression equal to this LHS expression in the associated model.

var()

Returns the variable referenced by this LhsExpression.

For Name objects this will be equal to the left hand side of their defining equation, for Derivative objects this will be the variable they represent the derivative of.

class myokit.Name(value)

Represents a reference to a variable.

Extends: LhsExpression

bracket(op=None)

See Expression.bracket().

clone(subst=None, expand=False, retain=None)

See Expression.clone().

is_name(var=None)

See Expression.is_name().

is_state_value()

See: meth:Expression.is_state_value().

rhs()

See LhsExpression.rhs().

var()

See LhsExpression.var().

class myokit.Derivative(op)

Represents a reference to the time-derivative of a variable.

Extends: LhsExpression

bracket(op)

See Expression.bracket().

clone(subst=None, expand=False, retain=None)

See Expression.clone().

is_derivative(var=None)

See Expression.is_derivative().

rhs()

See LhsExpression.rhs().

var()

See LhsExpression.var().

Operators

class myokit.PrefixExpression(op)

Base class for prefix expressions: expressions with a single operand.

Abstract class, extends: Expression

bracket(op)

See Expression.bracket().

clone(subst=None, expand=False, retain=None)

See Expression.clone().

class myokit.InfixExpression(left, right)

Base class for for infix expressions: <left> operator <right>.

The order of the operands may matter, so that <left> operator <right> is not always equal to <right> operator <left>.

Abstract class, extends: Expression

bracket(op)

See Expression.bracket().

clone(subst=None, expand=False, retain=None)

See Expression.clone().

Functions

class myokit.Function(*ops)

Base class for built-in functions.

Functions have a name, which must be set to a human readable function name (usually just the function’s .mmt equivalent) and a list of integers called _nargs. Each entry in _nargs specifies a number of arguments for which the function is implemented. For example Sin has _nargs=[1] while Log has _nargs=[1,2], showing that Log can be called with either 1 or 2 arguments.

If errors occur when creating a function, an IntegrityError may be thrown.

Abstract class, extends: Expression

bracket(op=None)

See Expression.bracket().

clone(subst=None, expand=False, retain=None)

See Expression.clone().

Conditions

class myokit.Condition

Abstract class

Interface for conditional expressions that can be evaluated to True or False. Doesn’t add any methods but simply indicates that this is a condition.

class myokit.PrefixCondition(op)

Interface for prefix conditions.

Abstract class, extends: Condition, PrefixExpression

class myokit.InfixCondition(left, right)

Base class for infix expressions.

Abstract class, extends: Condition, InfixExpression

Unary plus and minus

class myokit.PrefixPlus(op)

Prefixed plus. Indicates a positive number +op.

>>> from myokit import *
>>> x = PrefixPlus(Number(10))
>>> print(x.eval())
10.0

Extends: PrefixExpression

class myokit.PrefixMinus(op)

Prefixed minus. Indicates a negative number -op.

>>> from myokit import *
>>> x = PrefixMinus(Number(10))
>>> print(x.eval())
-10.0

Extends: PrefixExpression

Addition and multiplication

class myokit.Plus(left, right)

Represents the addition of two operands: left + right.

>>> from myokit import *
>>> x = parse_expression('5 + 2')
>>> print(x.eval())
7.0

Extends: InfixExpression

class myokit.Minus(left, right)

Represents subtraction: left - right.

>>> from myokit import *
>>> x = parse_expression('5 - 2')
>>> print(x.eval())
3.0

Extends: InfixExpression

class myokit.Multiply(left, right)

Represents multiplication: left * right.

>>> from myokit import *
>>> x = parse_expression('5 * 2')
>>> print(x.eval())
10.0

Extends: InfixExpression

class myokit.Divide(left, right)

Represents division: left / right.

>>> from myokit import *
>>> x = parse_expression('5 / 2')
>>> print(x.eval())
2.5

Extends: InfixExpression

Powers and roots

class myokit.Power(left, right)

Represents exponentiation: left ^ right.

>>> import myokit
>>> x = myokit.parse_expression('5 ^ 2')
>>> print(x.eval())
25.0

Extends: InfixExpression

class myokit.Sqrt(*ops)

Represents the square root sqrt(x).

>>> import myokit
>>> x = myokit.parse_expression('sqrt(25)')
>>> print(x.eval())
5.0

Extends: Function

Logarithms and e

class myokit.Exp(*ops)

Represents a power of e. Written exp(x) in .mmt syntax.

>>> from myokit import *
>>> x = Exp(Number(1))
>>> print(round(x.eval(), 4))
2.7183

Extends: UnaryDimensionlessFunction

class myokit.Log(*ops)

With one argument log(x) represents the natural logarithm. With two arguments log(x, k) is taken to be the base k logarithm of x.

>>> from myokit import *
>>> x = Log(Number(10))
>>> print(round(x.eval(), 4))
2.3026
>>> x = Log(Exp(Number(10)))
>>> print(round(x.eval(), 1))
10.0
>>> x = Log(Number(256), Number(2))
>>> print(round(x.eval(), 1))
8.0

Extends: Function

class myokit.Log10(*ops)

Represents the base-10 logarithm log10(x).

>>> from myokit import *
>>> x = Log10(Number(100))
>>> print(round(x.eval(), 1))
2.0

Extends: UnaryDimensionlessFunction

Trigonometric functions

All trigonometric functions use angles in radians.

class myokit.Sin(*ops)

Represents the sine function sin(x).

>>> from myokit import *
>>> x = parse_expression('sin(0)')
>>> print(round(x.eval(), 1))
0.0
>>> x = Sin(Number(3.1415 / 2.0))
>>> print(round(x.eval(), 1))
1.0

Extends: UnaryDimensionlessFunction

class myokit.Cos(*ops)

Represents the cosine function cos(x).

>>> from myokit import *
>>> x = Cos(Number(0))
>>> print(round(x.eval(), 1))
1.0
>>> x = Cos(Number(3.1415 / 2.0))
>>> print(round(x.eval(), 1))
0.0

Extends: UnaryDimensionlessFunction

class myokit.Tan(*ops)

Represents the tangent function tan(x).

>>> from myokit import *
>>> x = Tan(Number(3.1415 / 4.0))
>>> print(round(x.eval(), 1))
1.0

Extends: UnaryDimensionlessFunction

class myokit.ASin(*ops)

Represents the inverse sine function asin(x).

>>> from myokit import *
>>> x = ASin(Sin(Number(1)))
>>> print(round(x.eval(), 1))
1.0

Extends: UnaryDimensionlessFunction

class myokit.ACos(*ops)

Represents the inverse cosine acos(x).

>>> from myokit import *
>>> x = ACos(Cos(Number(3)))
>>> print(round(x.eval(), 1))
3.0

Extends: UnaryDimensionlessFunction

class myokit.ATan(*ops)

Represents the inverse tangent function atan(x).

>>> from myokit import *
>>> x = ATan(Tan(Number(1)))
>>> print(round(x.eval(), 1))
1.0

If two arguments are given they are interpreted as the coordinates of a point (x, y) and the function returns this point’s angle with the (positive) x-axis. In this case, the returned value will be in the range (-pi, pi].

Extends: UnaryDimensionlessFunction

Conditional operators

class myokit.If(i, t, e)

Allows conditional functions to be defined using an if-then-else structure.

The first argument to an If function must be a condition, followed directly by an expression to use to calculate the function’s return value if this condition is True. The third and final argument specifies the expression’s value if the condition is False.

A simple example in .mmt syntax:

x = if(V < 10, 5 * V + 100, 6 * V)

Extends: Function

condition()

Returns this if-function’s condition.

is_conditional()

Returns True if and only if this expression’s tree contains a conditional statement.

piecewise()

Returns an equivalent Piecewise object.

value(which)

Returns the expression used when this if’s condition is True when called with which=True. Otherwise return the expression used when this if’s condition is False.

class myokit.Piecewise(*ops)

Allows piecewise functions to be defined.

The first argument to a Piecewise function must be a condition, followed directly by an expression to use to calculate the function’s return value if this condition is true.

Any number of condition-expression pairs can be added. If multiple conditions evaluate as true, only the first one will be used to set the return value.

The final argument should be a default expression to use if none of the conditions evaluate to True. This means the piecewise() function can have any odd number of arguments greater than 2.

A simple example in mmt syntax:

x = piecewise(
    V < 10, 5 * V + 100
    V < 20, 6 * V,
    7 * V)

This will return 5 * V + 100 for any value smaller than 10, 6 * V for any value greater or equal to 10 but smaller than 20, and 7 * V for any values greather than or equal to 20.

Extends: Function

conditions()

Returns an iterator over the conditions used by this Piecewise.

is_conditional()

Returns True if and only if this expression’s tree contains a conditional statement.

pieces()

Returns an iterator over the pieces in this Piecewise.

class myokit.Not(op)

Negates a condition. Written as not x.

>>> from myokit import *
>>> x = parse_expression('1 == 1')
>>> print(x.eval())
True
>>> y = Not(x)
>>> print(y.eval())
False
>>> x = parse_expression('(2 == 2) and not (1 > 2)')
>>> print(x.eval())
True

Extends: PrefixCondition

class myokit.Equal(left, right)

Represents an equality check x == y.

>>> from myokit import *
>>> print(parse_expression('1 == 0').eval())
False
>>> print(parse_expression('1 == 1').eval())
True

Extends: InfixCondition

class myokit.NotEqual(left, right)

Represents an inequality check x != y.

>>> from myokit import *
>>> print(parse_expression('1 != 0').eval())
True
>>> print(parse_expression('1 != 1').eval())
False

Extends: InfixCondition

class myokit.More(left, right)

Represents an is-more-than check x > y.

>>> from myokit import *
>>> print(parse_expression('5 > 2').eval())
True

Extends: InfixCondition

class myokit.Less(left, right)

Represents an is-less-than check x < y.

>>> from myokit import *
>>> print(parse_expression('5 < 2').eval())
False

Extends: InfixCondition

class myokit.MoreEqual(left, right)

Represents an is-more-than-or-equal check x > y.

>>> from myokit import *
>>> print(parse_expression('2 >= 2').eval())
True

Extends: InfixCondition

class myokit.LessEqual(left, right)

Represents an is-less-than-or-equal check x <= y.

>>> from myokit import *
>>> print(parse_expression('2 <= 2').eval())
True

Extends: InfixCondition

class myokit.And(left, right)

True if two conditions are true: x and y.

>>> from myokit import *
>>> print(parse_expression('1 == 1 and 2 == 4').eval())
False
>>> print(parse_expression('1 == 1 and 4 == 4').eval())
True

Extends: InfixCondition

class myokit.Or(left, right)

True if at least one of two conditions is true: x or y.

>>> from myokit import *
>>> print(parse_expression('1 == 1 or 2 == 4').eval())
True

Extends: InfixCondition

Discontinuous functions

class myokit.Abs(*ops)

Returns the absolute value of a number abs(x).

>>> from myokit import *
>>> x = parse_expression('abs(5)')
>>> print(x.eval())
5.0
>>> x = parse_expression('abs(-5)')
>>> print(x.eval())
5.0

Extends: Function

class myokit.Floor(*ops)

Represents a rounding towards minus infinity floor(x).

>>> from myokit import *
>>> x = Floor(Number(5.2))
>>> print(x.eval())
5.0
>>> x = Floor(Number(-5.2))
>>> print(x.eval())
-6.0

Extends: Function

class myokit.Ceil(*ops)

Represents a rounding towards positve infinity ceil(x).

>>> from myokit import *
>>> x = Ceil(Number(5.2))
>>> print(x.eval())
6.0
>>> x = Ceil(Number(-5.2))
>>> print(x.eval())
-5.0

Extends: Function

class myokit.Quotient(left, right)

Represents the quotient of a division left // right, also known as integer division.

>>> import myokit
>>> x = myokit.parse_expression('7 // 3')
>>> print(x.eval())
2.0

Note that, for negative numbers Myokit follows the convention of rounding towards negative infinity, rather than towards zero. Thus:

>>> print(myokit.parse_expression('-7 // 3').eval())
-3.0

Similarly:

>>> print(myokit.parse_expression('5 // -3').eval())
-2.0

Note that this differs from how integer division is implemented in C, which _truncates_ (round towards zero), but similar to how floor() is implemented in C, which rounds towards negative infinity.

See: https://python-history.blogspot.co.uk/2010/08/ And: https://en.wikipedia.org/wiki/Euclidean_division

Extends: InfixExpression

class myokit.Remainder(left, right)

Represents the remainder of a division (the “modulo”), expressed in mmt syntax as left % right.

>>> import myokit
>>> x = myokit.parse_expression('7 % 3')
>>> print(x.eval())
1.0

Note that, for negative numbers Myokit follows the convention of Python that the quotient is rounded to negative infinity. Thus:

>>> print(myokit.parse_expression('-7 // 3').eval())
-3.0

and therefore:

>>> print(myokit.parse_expression('-7 % 3').eval())
2.0

Similarly:

>>> print(myokit.parse_expression('5 // -3').eval())
-2.0

so that:

>>> print(myokit.parse_expression('5 % -3').eval())
-1.0

See: https://en.wikipedia.org/wiki/Modulo_operation

Extends: InfixExpression

Partial derivatives

class myokit.PartialDerivative(var1, var2)

Represents a reference to the partial derivative of one variable with respect to another.

This class is used when writing out derivatives of equations, but may _not_ appear in right-hand-side expressions for model variables!

Extends: LhsExpression

bracket(op=None)

See Expression.bracket().

clone(subst=None, expand=False, retain=None)

See Expression.clone().

dependent_expression()

Returns the expression that a derivative is taken of, i.e. “y” in “dy/dx”.

independent_expression()

Returns the expression that a derivative is taken with respect to, i.e. x in dy/dx.

rhs()

See LhsExpression.rhs().

The RHS returned in this case will be None, as there is no RHS associated with partial derivatives in the model.

var()

See LhsExpression.var().

As with time-derivatives, this returns the variable of which a derivative is taken (i.e. the dependent variable “y” in “dy/dx”).

class myokit.InitialValue(var)

Represents a reference to the initial value of a state variable.

This class is used when writing out derivatives of equations, but may _not_ appear in right-hand-side expressions for model variables!

Extends: LhsExpression

bracket(op=None)

See Expression.bracket().

clone(subst=None, expand=False, retain=None)

See Expression.clone().

rhs()

See LhsExpression.rhs().

The RHS returned in this case will be None, as there is no RHS associated with initial values in the model.

var()

See LhsExpression.var().

User-defined functions

class myokit.UserFunction(name, arguments, template)

Represents a user function.

UserFunction objects should not be created directly, but only via Model.add_function().

User functions are not Expression objects, but template expressions that are converted upon parsing. They allow common functions (for example a boltzman function) to be used in string expressions.

Arguments:

name

The user function’s name (a string)

arguments

A list of function argument names (all of type Name)

template

The Expression evaluating this function.

arguments()

Returns an iterator over this user function’s arguments.

convert(arguments)

Returns an Expression object, evaluated using the given dictionary mapping argument Name objects to expressions.