Grammar
Below is the approximate BNF grammar for Kotlinβ. This is incomplete and subject to change without notice.
#Numerical types:
1 πΉ = "True" | "False"
2 π» = "1" | ... | "9"
3 β = π» | π»"0" | π»β
4 β€ = "0" | β | -β
5 β = β | β€"/"β
6 β = β | β"."β | "-"β
7 β = β + βi
8 β = β + βi + βj + βk
9 T = πΉ | β | β€ | β | β | β | β
10 n = β < 100*
11vec = [TβΏ]
12mat = [[TβΏ]βΏ]
β To increase n, see DimGen.kt.
#DSL
1 type = "Double" | "Float" | "Int" | "BigInteger" | "BigDouble";
2 nat = "1" | ... | "99";
3 output = "Fun<" type "Real>" | "VFun<" type "Real," nat ">" | "MFun<" type "Real," nat "," nat ">";
4 int = "0" | nat int;
5 float = int "." int;
6 num = type "(" int ")" | type "(" float ")";
7 var = "x" | "y" | "z" | "ONE" | "ZERO" | "E" | "Var()";
8 signOp = "+" | "-";
9 binOp = signOp | "*" | "/" | "pow";
10 trigOp = "sin" | "cos" | "tan" | "asin" | "acos" | "atan" | "asinh" | "acosh" | "atanh";
11 unaryOp = signOp | trigOp | "sqrt" | "log" | "ln" | "exp";
12 exp = var | num | unaryOp exp | var binOp exp | "(" exp ")";
13 expList = exp | exp "," expList;
14 linOp = signOp | "*" | " dot ";
15 vec = "Vec(" expList ")" | "Vec" nat "(" expList ")";
16 vecExp = vec | signOp vecExp | exp "*" vecExp | vec linOp vecExp | vecExp ".norm(" int ")";
17 mat = "Mat" nat "x" nat "(" expList ")";
18 matExp = mat | signOp matExp | exp linOp matExp | vecExp linOp matExp | mat linOp matExp;
19 anyExp = exp | vecExp | matExp | derivative | invocation;
20 bindings = exp " to " exp | exp " to " exp "," bindings;
21 invocation = anyExp "(" bindings ")";
22 derivative = "d(" anyExp ") / d(" exp ")" | anyExp ".d(" exp ")" | anyExp ".d(" expList ")";
23 gradient = exp ".grad()";
Operational Semantics
Below we provide an operational semantics for Kotlinβ.
1 v = a | ... | z | vv
2 c = 1 | ... | 9 | cc | c.c
3 e = v | c | e β e | e β e | (e) | (e).d(v) | e(e = e)
4
5 d(e) / d(v) = e.d(v)
6 Plus(eβ, eβ) = eβ β eβ
7 Times(eβ, eβ) = eβ β eβ
8 cβ β cβ = cβ + cβ
9 cβ β cβ = cβ * cβ
10 eβ(eβ = eβ) = eβ[eβ β eβ]
11
12 (eβ β eβ).d(v) = eβ.d(v) β eβ.d(v)
13 (eβ β eβ).d(v) = eβ.d(v) β eβ β eβ β eβ.d(v)
14 vβ.d(vβ) = 1
15 vβ.d(vβ) = 0
16 c.d(v) = 0
17
18 e.d(vβ).d(vβ) = e.d(vβ).d(vβ) β
19
20(eβ β eβ)[eβ β eβ] = eβ[eβ β eβ] β eβ[eβ β eβ]
21(eβ β eβ)[eβ β eβ] = eβ[eβ β eβ] β eβ[eβ β eβ]
22 eβ[eβ β eβ] = eβ
23 eβ[eβ β eβ] = eβ
In the notation above, we use subscripts to denote conditional inequality. If we have two nonterminals with matching subscripts in the same production, i.e. eβ, eβ where m = n, then eβ = eβ must be true. If we have two nonterminals with different subscripts in the same production, i.e. eβ, eβ where m β n, either eβ = eβ or eβ β eβ may be true. Subscripts have no meaning across multiple productions.
β See Clairaut-Schwarz. Commutativity holds for twice-differentiable functions, however it is possible to have a continuously differentiable function whose partials are defined everywhere, but whose permuted partials are unequal βFΒ²/βxβy β βFΒ²/βyβx. Some examples of continuously differentiable functions whose partials do not commute may be found in Tolstov (1949, 1949).
Reduction semantics
Our reduction semantics can be described as follows:

Sub loosely corresponds to Ξ·-reduction in the untyped Ξ»-calculus, however f β Ξ© is disallowed, and we assume all variables are bound by Inv. Let us consider what happens under fβΆ {a, b, c} β¦ abc, gβΆ {a, b, c} β¦ ac under Ξ© βΆ= {(a, 1), (b, 2), (c, 2)}:

We can view the above process as acting on a dataflow graph, where Inv backpropagates Ξ©, and Sub returns concrete values Y, here depicted on g:
