7. Reference Guide¶
7.1. Procedures¶
A procedure is a code block that will be inlined at the call-site.
-
proc name(args; localargs) { [statements] }
¶ Parameters: - args – arguments to the function
- localargs – variables local to the procedure. They will shadow existing variables.
Define a code block that will be placed inline in the code when called with
call
. All variables in the argumentsargs
are replaced.localargs
will shadow arguments from the outer scope.The code block can contain
apply
statements.proc derivative(x, n) { for $i in 1..(n+1) { id x^m? = m? * x^(m? - 1); } } expr F = u^5; apply { call derivative(u, 2); }
yields
20*u^3
7.2. User-defined functions¶
Users can define their own functions in the global scope with the following statement:
-
fn name(args) = expression;
¶ Parameters: - name – Name of the function
- args – Arguments to the function
- expression – The resulting expression
Replace the function
name
withexpression
where all occurences of theargs
are replaced by the given function arguments.Note
Functions in already existing expressions will not be automatically substitued when they are defined as custom functions at a later stage. Use
id myfunc(?a) = myfunc(?a);
to trigger the substitution.fn factorial(n) = ifelse_(n > 0, n * factorial(n-1), 1); $a = factorial(10); print $a;
yields
3628800
7.3. Statements¶
-
apply [name for F1,...,F2 exclude F3,...,] { [statements] };
¶ Parameters: - name – Optional name of the module
- statements – A list of statements that will be applied
Apply a list of statements (a module) to all active expressions. If
for F1,...,F2
is specified, the module is only applied to these expressions. It is also possible to apply the module to all expressions excluding some by usingexcluding F3,...
. Theapply
statement cannot be nested.For example:
expr F = f(5); apply { id f(x?) = f(x? + 1); id f(6) = f(3); }
The statements will be processed term by term.
-
argument f1,f2,... { [statements] }
¶ Parameters: - f1,... – Functions the statements should be applied to.
- statements – Statement block to be executed on function arguments
Execute a block of statements on the arguments of specific functions.
expr F = f(1+x,y*x); apply { argument f { id y = 5; } }
yields
F = f(1+x,5*x)
-
assign x = expr;
¶ Parameters: - x – A variable
- expr – A reFORM expression
Assign the expression to the variable
x
.$a = 1 + x; print $a;
yields
1 + x
-
attrib f = Linear + NonCommutative + Symmetric;
¶ Parameters: - f – A function name.
Assign attributes to a function. At the moment the options are
Linear
,NonCommutative
, andSymmetric
. Multiple options can be given with a+
.expr F = f(x, y); attrib f = Linear; apply { id f(x1?,x2?) = f(x1?+2,x2?+5); }
yields
+f(x,y) +f(x,5) +f(2,y) +f(2,5)
-
call proc(args);
¶ Parameters: - proc – A procedure
- args – Arguments to the procedure
Call a procedure (see Procedures) with arguments.
procedure derivative(x, n) { for $i in 1..(n+1) { id x^m? = m? * x^(m? - 1); } } expr F = u^5; apply { call derivative(u, 2); }
yields
u^3*20
-
collect fn;
¶ Parameters: - fn – A function name.
If this statement is called inside a module, it will wrap the entire term in a function
fn
. if this statement is called outside the module, it will wrap the entire expression in a functionfn
. The latter is only possible if the expression fits in memory.Note
The collect statement must currently be placed before the apply block. This will be fixed in the future.
expr F = (1+x)^4; collect f; print; apply { expand; }
yields
+f(x*4+x^2*6+x^3*4+x^4+1)
-
discard;
¶ Discard the current term.
expr F = x + y; apply { if match(x) { Discard; } }
yields
y
-
expand;
¶ Expand all structures. For example,
`(1+x)^5`
, and`(1+x)*(1+y)`
will be completely written out.expr F = (1+x)^2*(1+y); apply { expand; }
yields
+x*y*2 +x*2 +x^2 +x^2*y +y +1
-
expr name = expression;
¶ Parameters: - name – The name of a new expression
- expression – Any valid reFORM expression.
Create a new expression. An expression is processed term-by-term and can be larger than memory. Use
apply
to operate on the terms of the expression.
-
extract $i x1,...,xn;
¶ Parameters: - $i – A reFORM variable.
- x1,...,xn – A list of algebraic variables.
Construct a Horner scheme in the variables
x1
toxn
for the expression in variable$i
.$a = x + x*y + x*y*z + y*z + x^2 + x^2*y + 2; extract $a x,y; print $a;
yields
(y+1)*x^2+y*z+2+((z+1)*y+1)*x
-
fn name(args) = expression;
-
for i in lb..ub { [statements] };
¶ -
for i in {s1,s2,...} { [statements] };
Parameters: - i – The loop variable.
- lb..ub – A numerical range.
- {s1,s2,...} – A list of expressions.
Loop over a numerical range or over a list of expressions. Loops can be made both inside and outside of modules.
expr F = f(2); for $i in 1..4 { print; apply { id f($i) = f($i+1); } }
yields
F = f(2); F = f(3); F = f(4);
-
id lhs = rhs;
¶ Parameters: - lhs – Any valid reFORM expression with wildcards.
- rhs – Any valid reFORM expression with wildcards.
Apply the lhs to an active term (therefore an
id
statement needs to be in aninside
orapply
block (module).See Pattern matching for the patterns that are allowed to match.
For example:
expr F = f(5); apply { id f(x?) = f(x? + 1); }
-
if cond { [statements] } [else { [statements] } ]
¶ -
if match(expr) { [statements] } [else { [statements] } ]
-
if defined(dollar) { [statements] } [else { [statements] } ]
Parameters: - cond – A boolean condition
- match(expr) – A test to see if an expression matches
- defined(dollar) – A test to see if a dollar variable is defined
- statements – Statement block to be executed
Only execute if a condition holds. If there is an
else
block, that will only be executed ifcond
does not hold.The condition can test if a pattern exists (see frm:st:id) using the
match
option. The condition can also be a comparison of two expressions, i.e.,<=, >=, <, >, ==
.Note
Inequalities use reFORM’s internal ordering which may give unexpected results.
expr F = f(1); apply { if match(f(1)) { id f(1) = f(2); } else { id f(x?) = f(1); } if defined($a) { Multiply $a; } if f(1) < f(2) { id f(2) = f(3); } print; }
yields
f(3)
-
inside x1,x2,... { [statements] }
¶ Parameters: - x1,... – Variables the statements should be applied to.
- statements – Statement block to be executed on the terms in variables.
Execute a block of statements on specific variables.
$x = 1 + x + y*x; inside $x { id x = 5; } print $x;
yields
6 + 5*y
-
matchassign pattern { [assigns] };
¶ Parameters: - pattern – A pattern to match the current expression to.
- assigns – A list of
assign
statements.
Match the current term and use the matched wildcards in the assignment of dollar variables.
expr F = f(x,1,2,3); $a = 0; $b = 0; apply { matchassign f(y?,?b) { $a = 2*y?*f(?b); $b = y?^5; } } print $a,$b;
yields
2*f(1,2,3)*x x^5
-
maximum x;
¶ Parameters: - x – A variable
Get the maximum of the variable
x
over all terms in the module.$a = 0; apply { if match(f(1)) { $a = 2; } else { $a = 1; } maximum $a; } print $a;
yields
2
-
multiply expr;
¶ Parameters: - expr – An expression to multiply.
Multiply the expression into the current active term.
Multiply
can only be used in a module.expr F = y; apply { Multiply 1 + x; }
yields
y*(1+x)
-
print [format] [vars];
¶
-
print [format] format_string;
Parameters: - format – Optional format for printing. It can either be
Form
orMathematica
. - vars – A list of variables to print.
- format_string – a list of variables to print
Print objects or a formatted string to the screen.
If the
Print
statement without argumentsvars
orformat_string
is used in a module, the current term is printed. If it is used outside a module without these arguments, it will print all active expressions.The
format
option can be used to format the terms in a way such that it is compatible with other software. The current supported options areForm
(default) andMathematica
.If a list of variables
vars
is specified, each variable will be printed on a new line. If a format string is specified, the formatted string is printed. Variables and special objects can be printed by putting them between{ }
in the format string. Special objects are:{data_}
: print the current date and time{time_}
: print the current time{term_}
: print the current term{$a}
: print the value of$a
$a = f(x); print mathematica $a; expr F = 1 + x; apply { print; // print the current term print "{date_}: current term={term_}, $a={$a}"; } print; // print F
- format – Optional format for printing. It can either be
-
procedure name(args; localargs) { [statements] }
¶ See Procedures.
-
repeat { [statements] }
¶ Parameters: - statements – Statement block to be repeated until no terms change anymore.
Repeat a block of statements until the term does not change anymore.
The code below does a naive Fibonacci series evaluation. The repeat block will continue until none of the three
id
statements match.expr F = f(30); apply { repeat { id f(x?{>1}) = f(x? - 1) + f(x? - 2); id f(1) = 1; id f(0) = 0; } }
yields
F = f(1,x,2*y)
-
replaceby expr;
¶ Parameters: - expr – An expression
Replace the current term by
expr
.expr F = x*y + y; apply { if match(x) { ReplaceBy z; } }
yields
y + z
-
splitarg fn;
¶ Parameters: - fn – A function
Split a subexpression in a function argument into new function arguments. For example:
expr F = f(1+x+2*y); apply { splitarg f; }
yields
F = f(1,x,2*y)
-
symmetrize fn;
¶ Parameters: - fn – A function name.
Symmetrize the function arguments based on reFORM’s internal ordering.
expr F = f(3,2,x,1+y,g(5)); apply { symmetrize f; }
yields
f(g(5),y+1,x,2,3)
7.4. Functions¶
-
delta_(x1)
¶ Parameters: - x1 – A reFORM expression
Returns 1 if
x1
is 0. If it is a number other than 0, it will return 0.If
x1
is not a number, nothing happens.expr F = delta_(0)*x + delta_(1)*y + delta_(x);
yields
x + delta_(x)
-
gcd_(p1, p2)
¶ Parameters: - p1 – A multivariate polynomial with integer numbers as coefficients
- p2 – A multivariate polynomial with integer numbers as coefficients
Compute the greatest common divisor of two multivariate polynomials with integer numbers as a coefficient.
If the arguments are not valid polynomials, no replacement will be made.
expr F = gcd_(100+100*x-90*x^3-90*x^4+12*y+12*x*y+3*x^3*y^2+3*x^4*y^2, 100-100*x-90*x^3+90*x^4+12*y-12*x*y+3*x^3*y^2-3*x^4*y^2);
yields
+x^3*y^2*3 +x^3*-90 +y*12 +100
-
ifelse_(cond, truebranch, falsebranch)
¶ Parameters: - cond – A comparison, i.e.,
$a < 2
- truebranch – An expression that will be the result of the function if the condition is true
- falsebranch – An expression that will be the result of the function if the condition is false
Return
truebranch
if the conditioncond
is true andfalsebranch
if it is false. At the momentcond
should be a comparison between expressions. If the expressions are both numbers, all both equality and inequality tests are evaluted. In all other cases, only an equality test will be evaluated.Note
The expressions in both branches are not normalized (simplified), since that will take extra work (only one of the branches should be executed) and could cause infinite loops. As a result, pattern matching on the arguments of
ifelse_
will likely not work.expr F = f(5); apply { id f(n?) = ifelse_(n? <= 6, n? + 10, n?); }
yields
15
- cond – A comparison, i.e.,
-
list_(i, lb, ub, expr)
¶ Parameters: - i – A variable used as a counter
- lb – A numeric lower bound for
i
- ub – A numeric upper bound for
i
Return a list of
expr
withi
going fromlb
to (and including)ub
. This function will only be replaced when it is a function argument.expr F = f(1,2,list_($i,2,5,$i^2),3,4);
yields
f(1,2,4,9,16,25,3,4)
-
nargs_(a1,...,an)
¶ Parameters: - a1,...,an – A list of expressions
Returns the number of arguments the function has. It is especially useful in combination with the ranged wildcards.
expr F = f(1,2,3,4,5); apply { id f(?a) = nargs_(?a); }
yields
5
-
prod_(i, lb, ub, expr)
¶ Parameters: - i – A variable used as a counter
- lb – A numeric lower bound for
i
- ub – A numeric upper bound for
i
Return the product of
expr
withi
going fromlb
to (and including)ub
.expr F = prod_($i, 2, 5, $i^2);
yields
14400
-
rat_(num, den)
¶ Parameters: - num – A multivariate polynomial with integer numbers as coefficients
- den – A multivariate polynomial with integer numbers as coefficients
The
rat_
function can be used to have a ratio of multivariate polynomials as a coefficient . It will compute multivariate gcds to make sure the fraction does not grow more than necessary.If the arguments are not valid polynomials, no replacement will be made.
expr F = rat_(x^2+2*x+1,1)*rat_(1,1+x)+rat_(2,1);
yields
rat_(3+x,1)
-
sum_(i, lb, ub, expr)
¶ Parameters: - i – A variable used as a counter
- lb – A numeric lower bound for
i
- ub – A numeric upper bound for
i
Return the sum of
expr
withi
going fromlb
to (and including)ub
.expr F = sum_($i, 2, 5, $i^2);
yields
54
-
takearg_(k,a1,...,an)
¶ Parameters: - k – The index of the argument to take
- a1,...,an – Arguments
Return the
k
th argument of the lista1,...,an
. If the index is out of bounds, no substitution takes place.expr F = takearg_(2, x1, x2, x3);
yields
x2