1 Math in Felix
Felix provides a set of symbols from \(\TeX\), \(\LaTeX\) and AmSTeX which will
display nicely with flx_web
using the excellent MathJax package
as written in Felix program code.
All symbols starting with slosh and followed by alphabetic letters are valid Felix identifiers as well as valid TeX.
Additionally Felix supports some special symbols recognized by both the language processor and MathJaX.
Felix also supports both inline and display math
using MathJaX \
( .. \
)
and \
[ .. \
]
brackets, these work in *.flx
files and in both text and code
in *.fdoc
files.
Hover over sole operators shows the Felix source code, with
math mode, a click will open a new window showing mangled source.
The flx_web
processor adds { and } braces around Felix
grouping operators in math mode, to ensure MathJaX respects
Felix grouping.
In math mode, display may fail if explicit grouping is not used where TeX expects it.
Please note it is not enough in program code that the math forms used should be both correct \TeX as well as correct Felix. Just because it looks nice doesn't mean it will compile or evaluate correctly.
1.1 Ordinary names
Any TeX name defined as class ORD in TeX can be used in Felix as an identifier. This includes all the usual Greek letters.
var \(\alpha\) = 1; fun \(\Gamma\) (x:int)=> x * x; println$ \(\Gamma\)\(\alpha\);
1.2 Ceil and Floor
Pair \lceil
,\rceil
and \lfloor
,\rfloor
,
mapped by the parser to the functions ceil
and floor
,
defined for real floating types. The result is a floating type, not an integer!
println$ \(\lceil x + 2.3 \rceil + \lfloor 2.3 \rfloor + 0.1\);
1.3 Abs and norm
Using \lvert
,\rvert
pair or \left\lvert
,\right\rvert
,
or \left|
,\right|
mapping to function abs
, defined for
integers, reals, and complex numbers.
Using \lVert
,\rVert
pair or \left\lVert
,\right\rVert
mapping to function len
, defined for container and array class
data structures and strings.
println$ \( \lvert -2.3 \rvert \); println$ \( \lvert "{\mathtt{\text{Hello}}}" \rvert \); println$ \( \lVert 1,2,3 \rVert \);
1.4 Sqrt
The square root is only available in math mode. Unless it's argument is a single symbol, grouping operators are required to get the overline in the right place.
var x = 4.0; println$ \( \sqrt {(x + 2.0 )}\);
1.5 Fractions with over
The parser recognises the \
over
binary operator with
a low precedence and maps it to the division function /
.
Correct display requires math mode.
println$ \(x + 1.0 \over 2.0\);
1.6 Bracket forms
The two bracket forms \brace
and \brack
have the same precedence as \over
and map to arbitrary
binary functions of two arguments. They require mathmode to
display correctly.
fun \(\brace\) (x:int, y:int) => x + 2 * y; fun \(\brack\) (x:int, y:int) => x + 2 * y; println$ \( 2 \brace 3 \) + \( 2 \brack 3 \);
1.7 Negated Comparisons
Felix provides syntax to negate infix predicate symbols including
comparison operators. Both not
and \not
can be used
and are semantically equivalent, however the \not
only
displays correctly in math mode preceding an operator
without a strikethrough.
println$ (1,2,3) \(\subset\) (1,2); println$ (1,2,3) \(\nsubseteq\) (1,2); println$ \( {(1,2,3)} \not \subseteq {(1,2)} \); println$ (1,2,3) not \(\subseteq\) (1,2); println$ not \( {(1,2,3)} \subseteq {(1,2)} \); println$ \( {(1,2,3)} \not \supset {(1,2)} \); println$ not \(\subset\) ((1,2,3),(1,2)); println$ 2 \(\not\)< 1;
2 Set operations
2.1 Membership
Available for all class Set
, which includes all Container
.
Defined for arrays, and most container types including
list, varray, darray, bsarray. Defined for strings and regular expressions too.
[TODO: ralist, sarray]
println$ mem (2, (1,2,34)); println$ 2 in (1,2,3,4); println$ 2 \(\in\) (1,2,3,4); println$ (1,2,3,4) \(\ni\) 2; println$ (1,2,3,4) \(\owns\) 2; println$ 5 \(\notin\) (1,2,3,4); println$ 2 \(\in\) varray (1,2,3,4); println$ 2 \(\in\) darray (1,2,3,4); println$ 2 \(\in\) list (1,2,3,4); println$ char "2" \(\in\) "1234"; println$ "abaa" \(\in\) RE2 "(a|b)*a";
2.2 Set forms
Felix provides a construction known as a set form
which defines a set like object based on a predicate.
The syntax is { pattern : type | boolexpr
} where
you can also use \{\} brackets and \|
or \mid
for the vertical bar.
Technically a set form is a value of type set_form[T]
which is an object with a method has_elt : T -> bool
.
We then provide the membership operator for set forms
so you can write code like this:
var oddints = { x : int | x % 2 == 1 }; println$ 1 \(\in\) oddints; println$ \( {(3,9)} \in {\{ x,y : {\mathtt{\text{int}}} * {\mathtt{\text{int}}} \mid x * x == y \}} \);
2.3 Set Relations
Felix defines setlike relations for where the arguments
are in both Streamable
and Set
.
In some cases
such as the subset or equal, we only require the left
operand to be in Streamable
and the right operand
to be in Set
.
The default implementation of subset or equal streams all values of the LHS container and checks if that value is in the RHS argument. This implementation is inefficient, but it does allow the RHS to be infinite, for example a regular expression.
These relations construe containers as sets and so ignore duplicates. We use the congruence operator to mean equal as sets. Two arrays, for example, may be equal as sets because they contain the same set of elements, even though the ordering is different and different elements may be duplicated, so that the arrays are not equal as arrays.
Furthermore note that the operands may be completely different data structures and thus different types, however they must support the same value type.
println$ (varray (1,2)) \(\cong\) (varray (1,2,3)); println$ (varray (1,2)) \(\cong\) (darray (1,2,2)); println$ ("aba","ababba") \(\subseteq\) RE2 "(a|b)*a"; println$ (1,2) \(\subset\) (1,2,3); println$ (1,2) \(\subseteq\) (varray (1,2,3)); println$ (1,2) \(\subseteqq\) (varray (1,2,3)); println$ (1,2) \(\subsetneq\) (varray (1,2,3)); println$ (1,2) \(\subsetneqq\) (varray (1,2,3)); println$ (1,2,3) \(\supset\) (1,2); println$ (1,2,3) \(\supseteq\) (1,2); println$ (1,2,3) \(\supseteqq\) (1,2); println$ (1,2,3) \(\supsetneq\) (1,2); println$ (1,2,3) \(\supsetneqq\) (1,2); println$ (1,2,3) \(\nsubseteq\) (1,2); println$ (1,2,3) \(\nsubseteqq\) (1,2); println$ (1,2) \(\nsupseteq\) (1,2,3); println$ (1,2) \(\nsupseteqq\) (1,2,3);
2.4 Set Operators
Felix currently provides set operators. They can be used
with sets of type in the type language as well as with
set forms. Set operators can also be used with
data structures of kind Set[C,V]
, however the result
is a set form, not a similar data structure. For example
the union of two arrays is a set form that tests if an
element is a member of one array or the other, not an array.
typedef sregints = typesetof (int, long); typedef uregints = typesetof (uint, ulong); typedef regints = sregints \(\cup\) uregints; fun f[T:regints] : T -> T = "$1+1"; println$ f 1, f 1u, f 1uL; println$ 10 \(\in\) { x : int | 2 <= x } \(\cap\) { x : int | x < 20 }; println$ 10 \(\in\) (1,2,3) \(\cup\) (9,10,11);
3 Total Order
Members of class Tord
provide fancy operators.
Note that max uses \
vee
and min uses \
wedge
and these look the same as boolean \
lor
and \
land
but they're not. The nmemonic is to recall that both set intersection
and logical conjunction make for less cases and hence \wedge
is used
for the minimum. Set union and logical disjunction are fatter and
more inclusive and so used for the maximum.
println$ 1 \(\le\) 2; println$ 2 \(\nleq\) 1; println$ 2 \(\gt\) 1; println$ 2 \(\geqslant\) 1; println$ 2 \(\wedge\) 3, 2 \(\vee\) 3;
4 Boolean
There are some fancy logic operators.
println$ \(\lnot\) (true \(\land\) true \(\lor\) false \(\implies\) false);
5 Quantifiers
Using the \prod
and \sum
symbols.
5.1 Sums and products of data
Sums and products of values of data structures.
println$ \( \sum {(1,2,3,4)} \) ; println$ \(\prod\) (1,2,3,4); println$ \(\sum\) (1,2,3,4).darray; println$ \(\prod\) (1,2,3,4).darray; println$ \(\sum\) (1,2,3,4).list; println$ \(\prod\) (1,2,3,4).list; gen odds (x:int, y:int) () = { for var i:int in x upto y do if y % 2 == 1 do yield Some i; done done return None[int]; } println$ \(\sum\) (odds (1,7));
5.2 Sums and products of functions
Forms the categorical (parallel) product or sum of a tuple of functions.
fun f (x:int) : int => x + 1; fun g (x:int): string => x.str+"!"; fun h (x:double) :string => x.str+"!"; var fgx = \(\prod\) (f,g,h); println$ fgx (1,2,3.1); var fgs = \(\sum\) (f,g,h); var d1 = (case 1 of (int + int + double)) 42; var c1 : int + string + string = fgs d1; match c1 with | case 0 i => println$ "Case 0 " + i.str; | case 1 s => println$ "Case 1 " + s; | case 2 s => println$ "Case 2 " + s; endmatch;