Update documenetation with new enumeration forms,

and update the reference semantics.
Other minor documentation fixes and updates.
This commit is contained in:
Rob Dockins 2021-07-20 15:54:36 -07:00
parent 914f7fbe18
commit d740442035
10 changed files with 345 additions and 197 deletions

View File

@ -25,13 +25,20 @@ Literals
number : {val, rep} Literal val rep => rep number : {val, rep} Literal val rep => rep
length : {n, a, b} (fin n, Literal n b) => [n]a -> b length : {n, a, b} (fin n, Literal n b) => [n]a -> b
// '[a..b]' is syntactic sugar for 'fromTo`{first=a,last=b}' // '[x..y]' is syntactic sugar for 'fromTo`{first=x,last=y}'
fromTo : {first, last, a} fromTo : {first, last, a}
(fin last, last >= first, (fin last, last >= first,
Literal first a, Literal last a) => Literal first a, Literal last a) =>
[1 + (last - first)]a [1 + (last - first)]a
// '[a,b..c]' is syntactic sugar for 'fromThenTo`{first=a,next=b,last=c}' // '[x .. < y]' is syntactic sugar for
// 'fromToLessThan`{first=x,bound=y}'
fromToLessThan : {first, bound, a}
(fin first, bound >= first, LiteralLessThan bound a) =>
[bound - first]a
// '[x,y..z]' is syntactic sugar for
// 'fromThenTo`{first=x,next=y,last=z}'
fromThenTo : {first, next, last, a, len} fromThenTo : {first, next, last, a, len}
( fin first, fin next, fin last ( fin first, fin next, fin last
, Literal first a, Literal next a, Literal last a , Literal first a, Literal next a, Literal last a
@ -39,10 +46,30 @@ Literals
, lengthFromThenTo first next last == len) => , lengthFromThenTo first next last == len) =>
[len]a [len]a
// '[a .. < b]` is syntactic sugar for 'fromToLessThan`{first=a,bound=b}' // '[x .. y by n]' is syntactic sugar for
fromToLessThan : {first, bound, a} // 'fromToBy`{first=x,last=y,stride=n}'.
(fin first, bound >= first, LiteralLessThan bound a) => primitive fromToBy : {first, last, stride, a}
[bound - first]a (fin last, fin stride, stride >= 1, last >= first, Literal last a) =>
[1 + (last - first)/stride]a
// '[x ..< y by n]' is syntactic sugar for
// 'fromToByLessThan`{first=x,bound=y,stride=n}'.
primitive fromToByLessThan : {first, bound, stride, a}
(fin first, fin stride, stride >= 1, bound >= first, LiteralLessThan bound a) =>
[(bound - first)/^stride]a
// '[x .. y down by n]' is syntactic sugar for
// 'fromToDownBy`{first=x,last=y,stride=n}'.
primitive fromToDownBy : {first, last, stride, a}
(fin first, fin stride, stride >= 1, first >= last, Literal first a) =>
[1 + (first - last)/stride]a
// '[x ..> y down by n]' is syntactic sugar for
// 'fromToDownByGreaterThan`{first=x,bound=y,stride=n}'.
primitive fromToDownByGreaterThan : {first, bound, stride, a}
(fin first, fin stride, stride >= 1, first >= bound, Literal first a) =>
[(first - bound)/^stride]a
Fractional Literals Fractional Literals
------------------- -------------------

Binary file not shown.

Binary file not shown.

View File

@ -2,7 +2,8 @@
% markdown in ../../Syntax.md. If you make changes, please make them % markdown in ../../Syntax.md. If you make changes, please make them
% there and then regenerate the .tex file using the Makefile. % there and then regenerate the .tex file using the Makefile.
\section{Layout}\label{layout} \hypertarget{layout}{%
\section{Layout}\label{layout}}
Groups of declarations are organized based on indentation. Declarations Groups of declarations are organized based on indentation. Declarations
with the same indentation belong to the same group. Lines of text that with the same indentation belong to the same group. Lines of text that
@ -32,7 +33,8 @@ containing \texttt{y} and \texttt{z}. This group ends just before
\texttt{g}, because \texttt{g} is indented less than \texttt{y} and \texttt{g}, because \texttt{g} is indented less than \texttt{y} and
\texttt{z}. \texttt{z}.
\section{Comments}\label{comments} \hypertarget{comments}{%
\section{Comments}\label{comments}}
Cryptol supports block comments, which start with \texttt{/*} and end Cryptol supports block comments, which start with \texttt{/*} and end
with \texttt{*/}, and line comments, which start with \texttt{//} and with \texttt{*/}, and line comments, which start with \texttt{//} and
@ -47,7 +49,8 @@ Examples:
/* This is a /* Nested */ block comment */ /* This is a /* Nested */ block comment */
\end{verbatim} \end{verbatim}
\section{Identifiers}\label{identifiers} \hypertarget{identifiers}{%
\section{Identifiers}\label{identifiers}}
Cryptol identifiers consist of one or more characters. The first Cryptol identifiers consist of one or more characters. The first
character must be either an English letter or underscore (\texttt{\_}). character must be either an English letter or underscore (\texttt{\_}).
@ -64,8 +67,9 @@ name name1 name' longer_name
Name Name2 Name'' longerName Name Name2 Name'' longerName
\end{verbatim} \end{verbatim}
\hypertarget{keywords-and-built-in-operators}{\section{Keywords and \hypertarget{keywords-and-built-in-operators}{%
Built-in Operators}\label{keywords-and-built-in-operators}} \section{Keywords and Built-in
Operators}\label{keywords-and-built-in-operators}}
The following identifiers have special meanings in Cryptol, and may not The following identifiers have special meanings in Cryptol, and may not
be used for programmer defined names: be used for programmer defined names:
@ -73,8 +77,8 @@ be used for programmer defined names:
\begin{verbatim} \begin{verbatim}
else include property let infixl parameter else include property let infixl parameter
extern module then import infixr constraint extern module then import infixr constraint
if newtype type as infix if newtype type as infix by
private pragma where hiding primitive private pragma where hiding primitive down
\end{verbatim} \end{verbatim}
The following table contains Cryptol's operators and their associativity The following table contains Cryptol's operators and their associativity
@ -83,41 +87,40 @@ with lowest precedence operators first, and highest precedence last.
\begin{longtable}[]{@{}ll@{}} \begin{longtable}[]{@{}ll@{}}
\caption{Operator precedences.}\tabularnewline \caption{Operator precedences.}\tabularnewline
\toprule \toprule
Operator & Associativity\tabularnewline Operator & Associativity \\
\midrule \midrule
\endfirsthead \endfirsthead
\toprule \toprule
Operator & Associativity\tabularnewline Operator & Associativity \\
\midrule \midrule
\endhead \endhead
\texttt{==\textgreater{}} & right\tabularnewline \texttt{==\textgreater{}} & right \\
\texttt{\textbackslash{}/} & right\tabularnewline \texttt{\textbackslash{}/} & right \\
\texttt{/\textbackslash{}} & right\tabularnewline \texttt{/\textbackslash{}} & right \\
\texttt{==} \texttt{!=} \texttt{===} \texttt{!==} & not \texttt{==} \texttt{!=} \texttt{===} \texttt{!==} & not associative \\
associative\tabularnewline
\texttt{\textgreater{}} \texttt{\textless{}} \texttt{\textless{}=} \texttt{\textgreater{}} \texttt{\textless{}} \texttt{\textless{}=}
\texttt{\textgreater{}=} \texttt{\textless{}\$} \texttt{\textgreater{}=} \texttt{\textless{}\$}
\texttt{\textgreater{}\$} \texttt{\textless{}=\$} \texttt{\textgreater{}\$} \texttt{\textless{}=\$}
\texttt{\textgreater{}=\$} & not associative\tabularnewline \texttt{\textgreater{}=\$} & not associative \\
\texttt{\textbar{}\textbar{}} & right\tabularnewline \texttt{\textbar{}\textbar{}} & right \\
\texttt{\^{}} & left\tabularnewline \texttt{\^{}} & left \\
\texttt{\&\&} & right\tabularnewline \texttt{\&\&} & right \\
\texttt{\#} & right\tabularnewline \texttt{\#} & right \\
\texttt{\textgreater{}\textgreater{}} \texttt{\textless{}\textless{}} \texttt{\textgreater{}\textgreater{}} \texttt{\textless{}\textless{}}
\texttt{\textgreater{}\textgreater{}\textgreater{}} \texttt{\textgreater{}\textgreater{}\textgreater{}}
\texttt{\textless{}\textless{}\textless{}} \texttt{\textless{}\textless{}\textless{}}
\texttt{\textgreater{}\textgreater{}\$} & left\tabularnewline \texttt{\textgreater{}\textgreater{}\$} & left \\
\texttt{+} \texttt{-} & left\tabularnewline \texttt{+} \texttt{-} & left \\
\texttt{*} \texttt{/} \texttt{\%} \texttt{/\$} \texttt{\%\$} & \texttt{*} \texttt{/} \texttt{\%} \texttt{/\$} \texttt{\%\$} & left \\
left\tabularnewline \texttt{\^{}\^{}} & right \\
\texttt{\^{}\^{}} & right\tabularnewline \texttt{@} \texttt{@@} \texttt{!} \texttt{!!} & left \\
\texttt{@} \texttt{@@} \texttt{!} \texttt{!!} & left\tabularnewline (unary) \texttt{-} \texttt{\textasciitilde{}} & right \\
(unary) \texttt{-} \texttt{\textasciitilde{}} & right\tabularnewline
\bottomrule \bottomrule
\end{longtable} \end{longtable}
\hypertarget{built-in-type-level-operators}{%
\section{Built-in Type-level \section{Built-in Type-level
Operators}\label{built-in-type-level-operators} Operators}\label{built-in-type-level-operators}}
Cryptol includes a variety of operators that allow computations on the Cryptol includes a variety of operators that allow computations on the
numeric types used to specify the sizes of sequences. numeric types used to specify the sizes of sequences.
@ -125,29 +128,30 @@ numeric types used to specify the sizes of sequences.
\begin{longtable}[]{@{}ll@{}} \begin{longtable}[]{@{}ll@{}}
\caption{Type-level operators}\tabularnewline \caption{Type-level operators}\tabularnewline
\toprule \toprule
Operator & Meaning\tabularnewline Operator & Meaning \\
\midrule \midrule
\endfirsthead \endfirsthead
\toprule \toprule
Operator & Meaning\tabularnewline Operator & Meaning \\
\midrule \midrule
\endhead \endhead
\texttt{+} & Addition\tabularnewline \texttt{+} & Addition \\
\texttt{-} & Subtraction\tabularnewline \texttt{-} & Subtraction \\
\texttt{*} & Multiplication\tabularnewline \texttt{*} & Multiplication \\
\texttt{/} & Division\tabularnewline \texttt{/} & Division \\
\texttt{/\^{}} & Ceiling division (\texttt{/} rounded up)\tabularnewline \texttt{/\^{}} & Ceiling division (\texttt{/} rounded up) \\
\texttt{\%} & Modulus\tabularnewline \texttt{\%} & Modulus \\
\texttt{\%\^{}} & Ceiling modulus (compute padding)\tabularnewline \texttt{\%\^{}} & Ceiling modulus (compute padding) \\
\texttt{\^{}\^{}} & Exponentiation\tabularnewline \texttt{\^{}\^{}} & Exponentiation \\
\texttt{lg2} & Ceiling logarithm (base 2)\tabularnewline \texttt{lg2} & Ceiling logarithm (base 2) \\
\texttt{width} & Bit width (equal to \texttt{lg2(n+1)})\tabularnewline \texttt{width} & Bit width (equal to \texttt{lg2(n+1)}) \\
\texttt{max} & Maximum\tabularnewline \texttt{max} & Maximum \\
\texttt{min} & Minimum\tabularnewline \texttt{min} & Minimum \\
\bottomrule \bottomrule
\end{longtable} \end{longtable}
\section{Numeric Literals}\label{numeric-literals} \hypertarget{numeric-literals}{%
\section{Numeric Literals}\label{numeric-literals}}
Numeric literals may be written in binary, octal, decimal, or Numeric literals may be written in binary, octal, decimal, or
hexadecimal notation. The base of a literal is determined by its prefix: hexadecimal notation. The base of a literal is determined by its prefix:
@ -226,7 +230,8 @@ some examples:
0x_FFFF_FFEA 0x_FFFF_FFEA
\end{verbatim} \end{verbatim}
\section{Expressions}\label{expressions} \hypertarget{expressions}{%
\section{Expressions}\label{expressions}}
This section provides an overview of the Cryptol's expression syntax. This section provides an overview of the Cryptol's expression syntax.
@ -302,7 +307,8 @@ f \x -> x // call `f` with one argument `x -> x`
else z // call `+` with two arguments: `2` and `if ...` else z // call `+` with two arguments: `2` and `if ...`
\end{verbatim} \end{verbatim}
\section{Bits}\label{bits} \hypertarget{bits}{%
\section{Bits}\label{bits}}
The type \texttt{Bit} has two inhabitants: \texttt{True} and The type \texttt{Bit} has two inhabitants: \texttt{True} and
\texttt{False}. These values may be combined using various logical \texttt{False}. These values may be combined using various logical
@ -311,29 +317,30 @@ operators, or constructed as results of comparisons.
\begin{longtable}[]{@{}lll@{}} \begin{longtable}[]{@{}lll@{}}
\caption{Bit operations.}\tabularnewline \caption{Bit operations.}\tabularnewline
\toprule \toprule
Operator & Associativity & Description\tabularnewline Operator & Associativity & Description \\
\midrule \midrule
\endfirsthead \endfirsthead
\toprule \toprule
Operator & Associativity & Description\tabularnewline Operator & Associativity & Description \\
\midrule \midrule
\endhead \endhead
\texttt{==\textgreater{}} & right & Short-cut implication\tabularnewline \texttt{==\textgreater{}} & right & Short-cut implication \\
\texttt{\textbackslash{}/} & right & Short-cut or\tabularnewline \texttt{\textbackslash{}/} & right & Short-cut or \\
\texttt{/\textbackslash{}} & right & Short-cut and\tabularnewline \texttt{/\textbackslash{}} & right & Short-cut and \\
\texttt{!=} \texttt{==} & none & Not equals, equals\tabularnewline \texttt{!=} \texttt{==} & none & Not equals, equals \\
\texttt{\textgreater{}} \texttt{\textless{}} \texttt{\textless{}=} \texttt{\textgreater{}} \texttt{\textless{}} \texttt{\textless{}=}
\texttt{\textgreater{}=} \texttt{\textless{}\$} \texttt{\textgreater{}=} \texttt{\textless{}\$}
\texttt{\textgreater{}\$} \texttt{\textless{}=\$} \texttt{\textgreater{}\$} \texttt{\textless{}=\$}
\texttt{\textgreater{}=\$} & none & Comparisons\tabularnewline \texttt{\textgreater{}=\$} & none & Comparisons \\
\texttt{\textbar{}\textbar{}} & right & Logical or\tabularnewline \texttt{\textbar{}\textbar{}} & right & Logical or \\
\texttt{\^{}} & left & Exclusive-or\tabularnewline \texttt{\^{}} & left & Exclusive-or \\
\texttt{\&\&} & right & Logical and\tabularnewline \texttt{\&\&} & right & Logical and \\
\texttt{\textasciitilde{}} & right & Logical negation\tabularnewline \texttt{\textasciitilde{}} & right & Logical negation \\
\bottomrule \bottomrule
\end{longtable} \end{longtable}
\section{Multi-way Conditionals}\label{multi-way-conditionals} \hypertarget{multi-way-conditionals}{%
\section{Multi-way Conditionals}\label{multi-way-conditionals}}
The \texttt{if\ ...\ then\ ...\ else} construct can be used with The \texttt{if\ ...\ then\ ...\ else} construct can be used with
multiple branches. For example: multiple branches. For example:
@ -347,7 +354,8 @@ x = if y % 2 == 0 then 1
else 7 else 7
\end{verbatim} \end{verbatim}
\section{Tuples and Records}\label{tuples-and-records} \hypertarget{tuples-and-records}{%
\section{Tuples and Records}\label{tuples-and-records}}
Tuples and records are used for packaging multiple values together. Tuples and records are used for packaging multiple values together.
Tuples are enclosed in parentheses, while records are enclosed in curly Tuples are enclosed in parentheses, while records are enclosed in curly
@ -379,7 +387,8 @@ Ordering on tuples and records is defined lexicographically. Tuple
components are compared in the order they appear, whereas record fields components are compared in the order they appear, whereas record fields
are compared in alphabetical order of field names. are compared in alphabetical order of field names.
\subsection{Accessing Fields}\label{accessing-fields} \hypertarget{accessing-fields}{%
\subsection{Accessing Fields}\label{accessing-fields}}
The components of a record or a tuple may be accessed in two ways: via The components of a record or a tuple may be accessed in two ways: via
pattern matching or by using explicit component selectors. Explicit pattern matching or by using explicit component selectors. Explicit
@ -441,7 +450,8 @@ only the first entry in the tuple.
This behavior is quite handy when examining complex data at the REPL. This behavior is quite handy when examining complex data at the REPL.
\subsection{Updating Fields}\label{updating-fields} \hypertarget{updating-fields}{%
\subsection{Updating Fields}\label{updating-fields}}
The components of a record or a tuple may be updated using the following The components of a record or a tuple may be updated using the following
notation: notation:
@ -464,7 +474,8 @@ n = { pt = r, size = 100 } // nested record
{ n | pt.x -> x + 10 } == { pt = { x = 25, y = 20 }, size = 100 } { n | pt.x -> x + 10 } == { pt = { x = 25, y = 20 }, size = 100 }
\end{verbatim} \end{verbatim}
\section{Sequences}\label{sequences} \hypertarget{sequences}{%
\section{Sequences}\label{sequences}}
A sequence is a fixed-length collection of elements of the same type. A sequence is a fixed-length collection of elements of the same type.
The type of a finite sequence of length \texttt{n}, with elements of The type of a finite sequence of length \texttt{n}, with elements of
@ -475,19 +486,25 @@ with elements of type \texttt{a} has type \texttt{{[}inf{]}\ a}, and
\texttt{{[}inf{]}} is an infinite stream of bits. \texttt{{[}inf{]}} is an infinite stream of bits.
\begin{verbatim} \begin{verbatim}
[e1,e2,e3] // A sequence with three elements [e1,e2,e3] // A sequence with three elements
[t1 .. t3 ] // Sequence enumerations [t1 .. t2] // Enumeration
[t1, t2 .. t3 ] // Step by t2 - t1 [t1 .. <t2] // Enumeration (exclusive bound)
[e1 ... ] // Infinite sequence starting at e1 [t1 .. t2 by n] // Enumeration (stride)
[e1, e2 ... ] // Infinite sequence stepping by e2-e1 [t1 .. <t2 by n] // Enumeration (stride, ex. bound)
[t1 .. t2 down by n] // Enumeration (downward stride)
[t1 .. >t2 down by n] // Enumeration (downward stride, ex. bound)
[t1, t2 .. t3] // Enumeration (step by t2 - t1)
[ e | p11 <- e11, p12 <- e12 // Sequence comprehensions [e1 ...] // Infinite sequence starting at e1
[e1, e2 ...] // Infinite sequence stepping by e2-e1
[ e | p11 <- e11, p12 <- e12 // Sequence comprehensions
| p21 <- e21, p22 <- e22 ] | p21 <- e21, p22 <- e22 ]
x = generate (\i -> e) // Sequence from generating function x = generate (\i -> e) // Sequence from generating function
x @ i = e // Sequence with index binding x @ i = e // Sequence with index binding
arr @ i @ j = e // Two-dimensional sequence arr @ i @ j = e // Two-dimensional sequence
\end{verbatim} \end{verbatim}
Note: the bounds in finite sequences (those with \texttt{..}) are type Note: the bounds in finite sequences (those with \texttt{..}) are type
@ -497,28 +514,26 @@ expressions.
\begin{longtable}[]{@{}ll@{}} \begin{longtable}[]{@{}ll@{}}
\caption{Sequence operations.}\tabularnewline \caption{Sequence operations.}\tabularnewline
\toprule \toprule
Operator & Description\tabularnewline Operator & Description \\
\midrule \midrule
\endfirsthead \endfirsthead
\toprule \toprule
Operator & Description\tabularnewline Operator & Description \\
\midrule \midrule
\endhead \endhead
\texttt{\#} & Sequence concatenation\tabularnewline \texttt{\#} & Sequence concatenation \\
\texttt{\textgreater{}\textgreater{}} \texttt{\textless{}\textless{}} & \texttt{\textgreater{}\textgreater{}} \texttt{\textless{}\textless{}} &
Shift (right, left)\tabularnewline Shift (right, left) \\
\texttt{\textgreater{}\textgreater{}\textgreater{}} \texttt{\textgreater{}\textgreater{}\textgreater{}}
\texttt{\textless{}\textless{}\textless{}} & Rotate (right, \texttt{\textless{}\textless{}\textless{}} & Rotate (right, left) \\
left)\tabularnewline
\texttt{\textgreater{}\textgreater{}\$} & Arithmetic right shift (on \texttt{\textgreater{}\textgreater{}\$} & Arithmetic right shift (on
bitvectors only)\tabularnewline bitvectors only) \\
\texttt{@} \texttt{!} & Access elements (front, back)\tabularnewline \texttt{@} \texttt{!} & Access elements (front, back) \\
\texttt{@@} \texttt{!!} & Access sub-sequence (front, \texttt{@@} \texttt{!!} & Access sub-sequence (front, back) \\
back)\tabularnewline
\texttt{update} \texttt{updateEnd} & Update the value of a sequence at a \texttt{update} \texttt{updateEnd} & Update the value of a sequence at a
location (front, back)\tabularnewline location (front, back) \\
\texttt{updates} \texttt{updatesEnd} & Update multiple values of a \texttt{updates} \texttt{updatesEnd} & Update multiple values of a
sequence (front, back)\tabularnewline sequence (front, back) \\
\bottomrule \bottomrule
\end{longtable} \end{longtable}
@ -529,14 +544,16 @@ There are also lifted pointwise operations.
p1 # p2 // Split sequence pattern p1 # p2 // Split sequence pattern
\end{verbatim} \end{verbatim}
\section{Functions}\label{functions} \hypertarget{functions}{%
\section{Functions}\label{functions}}
\begin{verbatim} \begin{verbatim}
\p1 p2 -> e // Lambda expression \p1 p2 -> e // Lambda expression
f p1 p2 = e // Function definition f p1 p2 = e // Function definition
\end{verbatim} \end{verbatim}
\section{Local Declarations}\label{local-declarations} \hypertarget{local-declarations}{%
\section{Local Declarations}\label{local-declarations}}
\begin{verbatim} \begin{verbatim}
e where ds e where ds
@ -546,7 +563,9 @@ Note that by default, any local declarations without type signatures are
monomorphized. If you need a local declaration to be polymorphic, use an monomorphized. If you need a local declaration to be polymorphic, use an
explicit type signature. explicit type signature.
\section{Explicit Type Instantiation}\label{explicit-type-instantiation} \hypertarget{explicit-type-instantiation}{%
\section{Explicit Type
Instantiation}\label{explicit-type-instantiation}}
If \texttt{f} is a polymorphic value with type: If \texttt{f} is a polymorphic value with type:
@ -561,8 +580,9 @@ you can evaluate \texttt{f}, passing it a type parameter:
f `{ tyParam = 13 } f `{ tyParam = 13 }
\end{verbatim} \end{verbatim}
\hypertarget{demoting-numeric-types-to-values}{%
\section{Demoting Numeric Types to \section{Demoting Numeric Types to
Values}\label{demoting-numeric-types-to-values} Values}\label{demoting-numeric-types-to-values}}
The value corresponding to a numeric type may be accessed using the The value corresponding to a numeric type may be accessed using the
following notation: following notation:
@ -571,15 +591,26 @@ following notation:
`t `t
\end{verbatim} \end{verbatim}
Here \texttt{t} should be a type expression with numeric kind. The Here \texttt{t} should be a finite type expression with numeric kind.
resulting expression is a finite word, which is sufficiently large to The resulting expression will be of a numeric base type, which is
accommodate the value of the type: sufficiently large to accommodate the value of the type:
\begin{verbatim} \begin{verbatim}
`t : {n} (fin n, n >= width t) => [n] `t : {a} (Literal t a) => a
\end{verbatim} \end{verbatim}
\section{Explicit Type Annotations}\label{explicit-type-annotations} This backtick notation is syntax sugar for an application of the
\texttt{number} primtive, so the above may be written as:
\begin{verbatim}
number`{t} : {a} (Literal t a) => a
\end{verbatim}
If a type cannot be inferred from context, a suitable type will be
automatically chosen if possible, usually \texttt{Integer}.
\hypertarget{explicit-type-annotations}{%
\section{Explicit Type Annotations}\label{explicit-type-annotations}}
Explicit type annotations may be added on expressions, patterns, and in Explicit type annotations may be added on expressions, patterns, and in
argument definitions. argument definitions.
@ -592,15 +623,18 @@ p : t
f (x : t) = ... f (x : t) = ...
\end{verbatim} \end{verbatim}
\section{Type Signatures}\label{type-signatures} \hypertarget{type-signatures}{%
\section{Type Signatures}\label{type-signatures}}
\begin{verbatim} \begin{verbatim}
f,g : {a,b} (fin a) => [a] b f,g : {a,b} (fin a) => [a] b
\end{verbatim} \end{verbatim}
\section{Type Synonyms and Newtypes}\label{type-synonyms-and-newtypes} \hypertarget{type-synonyms-and-newtypes}{%
\section{Type Synonyms and Newtypes}\label{type-synonyms-and-newtypes}}
\subsection{Type synonyms}\label{type-synonyms} \hypertarget{type-synonyms}{%
\subsection{Type synonyms}\label{type-synonyms}}
\begin{verbatim} \begin{verbatim}
type T a b = [a] b type T a b = [a] b
@ -613,7 +647,8 @@ had instead written the body of the type synonym in line. Type synonyms
may mention other synonyms, but it is not allowed to create a recursive may mention other synonyms, but it is not allowed to create a recursive
collection of type synonyms. collection of type synonyms.
\subsection{Newtypes}\label{newtypes} \hypertarget{newtypes}{%
\subsection{Newtypes}\label{newtypes}}
\begin{verbatim} \begin{verbatim}
newtype NewT a b = { seq : [a]b } newtype NewT a b = { seq : [a]b }
@ -647,7 +682,8 @@ of newtypes to extract the values in the body of the type.
6 6
\end{verbatim} \end{verbatim}
\section{Modules}\label{modules} \hypertarget{modules}{%
\section{Modules}\label{modules}}
A \textbf{\emph{module}} is used to group some related definitions. Each A \textbf{\emph{module}} is used to group some related definitions. Each
file may contain at most one module. file may contain at most one module.
@ -661,7 +697,8 @@ f : [8]
f = 10 f = 10
\end{verbatim} \end{verbatim}
\section{Hierarchical Module Names}\label{hierarchical-module-names} \hypertarget{hierarchical-module-names}{%
\section{Hierarchical Module Names}\label{hierarchical-module-names}}
Module may have either simple or \textbf{\emph{hierarchical}} names. Module may have either simple or \textbf{\emph{hierarchical}} names.
Hierarchical names are constructed by gluing together ordinary Hierarchical names are constructed by gluing together ordinary
@ -680,7 +717,8 @@ when searching for module \texttt{Hash::SHA256}, Cryptol will look for a
file named \texttt{SHA256.cry} in a directory called \texttt{Hash}, file named \texttt{SHA256.cry} in a directory called \texttt{Hash},
contained in one of the directories specified by \texttt{CRYPTOLPATH}. contained in one of the directories specified by \texttt{CRYPTOLPATH}.
\section{Module Imports}\label{module-imports} \hypertarget{module-imports}{%
\section{Module Imports}\label{module-imports}}
To use the definitions from one module in another module, we use To use the definitions from one module in another module, we use
\texttt{import} declarations: \texttt{import} declarations:
@ -701,7 +739,8 @@ import M // import all definitions from `M`
g = f // `f` was imported from `M` g = f // `f` was imported from `M`
\end{verbatim} \end{verbatim}
\section{Import Lists}\label{import-lists} \hypertarget{import-lists}{%
\section{Import Lists}\label{import-lists}}
Sometimes, we may want to import only some of the definitions from a Sometimes, we may want to import only some of the definitions from a
module. To do so, we use an import declaration with an module. To do so, we use an import declaration with an
@ -725,7 +764,8 @@ Using explicit import lists helps reduce name collisions. It also tends
to make code easier to understand, because it makes it easy to see the to make code easier to understand, because it makes it easy to see the
source of definitions. source of definitions.
\section{Hiding Imports}\label{hiding-imports} \hypertarget{hiding-imports}{%
\section{Hiding Imports}\label{hiding-imports}}
Sometimes a module may provide many definitions, and we want to use most Sometimes a module may provide many definitions, and we want to use most
of them but with a few exceptions (e.g., because those would result to a of them but with a few exceptions (e.g., because those would result to a
@ -748,7 +788,8 @@ import M hiding (h) // Import everything but `h`
x = f + g x = f + g
\end{verbatim} \end{verbatim}
\section{Qualified Module Imports}\label{qualified-module-imports} \hypertarget{qualified-module-imports}{%
\section{Qualified Module Imports}\label{qualified-module-imports}}
Another way to avoid name collisions is by using a Another way to avoid name collisions is by using a
\textbf{\emph{qualified}} import. \textbf{\emph{qualified}} import.
@ -791,7 +832,8 @@ Such declarations will introduces all definitions from \texttt{A} and
\texttt{X} but to use them, you would have to qualify using the prefix \texttt{X} but to use them, you would have to qualify using the prefix
\texttt{B:::}. \texttt{B:::}.
\section{Private Blocks}\label{private-blocks} \hypertarget{private-blocks}{%
\section{Private Blocks}\label{private-blocks}}
In some cases, definitions in a module might use helper functions that In some cases, definitions in a module might use helper functions that
are not intended to be used outside the module. It is good practice to are not intended to be used outside the module. It is good practice to
@ -832,7 +874,8 @@ private
helper2 = 3 helper2 = 3
\end{verbatim} \end{verbatim}
\section{Parameterized Modules}\label{parameterized-modules} \hypertarget{parameterized-modules}{%
\section{Parameterized Modules}\label{parameterized-modules}}
\begin{verbatim} \begin{verbatim}
module M where module M where
@ -850,7 +893,9 @@ f : [n]
f = 1 + x f = 1 + x
\end{verbatim} \end{verbatim}
\section{Named Module Instantiations}\label{named-module-instantiations} \hypertarget{named-module-instantiations}{%
\section{Named Module
Instantiations}\label{named-module-instantiations}}
One way to use a parameterized module is through a named instantiation: One way to use a parameterized module is through a named instantiation:
@ -887,8 +932,9 @@ Note that the only purpose of the body of \texttt{N} (the declarations
after the \texttt{where} keyword) is to define the parameters for after the \texttt{where} keyword) is to define the parameters for
\texttt{M}. \texttt{M}.
\hypertarget{parameterized-instantiations}{%
\section{Parameterized \section{Parameterized
Instantiations}\label{parameterized-instantiations} Instantiations}\label{parameterized-instantiations}}
It is possible for a module instantiation to be itself parameterized. It is possible for a module instantiation to be itself parameterized.
This could be useful if we need to define some of a module's parameters This could be useful if we need to define some of a module's parameters
@ -923,8 +969,9 @@ In this case \texttt{N} has a single parameter \texttt{x}. The result of
instantiating \texttt{N} would result in instantiating \texttt{M} using instantiating \texttt{N} would result in instantiating \texttt{M} using
the value of \texttt{x} and \texttt{12} for the value of \texttt{y}. the value of \texttt{x} and \texttt{12} for the value of \texttt{y}.
\hypertarget{importing-parameterized-modules}{%
\section{Importing Parameterized \section{Importing Parameterized
Modules}\label{importing-parameterized-modules} Modules}\label{importing-parameterized-modules}}
It is also possible to import a parameterized module without using a It is also possible to import a parameterized module without using a
module instantiation: module instantiation:

View File

@ -22,7 +22,7 @@ Basic Syntax
Declarations Declarations
============ ============
.. code-block:: cryptol .. code-block:: cryptol
f x = x + y + z f x = x + y + z
@ -126,7 +126,8 @@ not be used for programmer defined names:
primitive primitive
parameter parameter
constraint constraint
down
by
.. _Keywords: .. _Keywords:
.. code-block:: none .. code-block:: none
@ -134,8 +135,8 @@ not be used for programmer defined names:
else include property let infixl parameter else include property let infixl parameter
extern module then import infixr constraint extern module then import infixr constraint
if newtype type as infix if newtype type as infix down
private pragma where hiding primitive private pragma where hiding primitive by
The following table contains Cryptol's operators and their The following table contains Cryptol's operators and their
@ -246,7 +247,7 @@ type is inferred from context in which the literal is used. Examples:
0b1010 // : [4], 1 * number of digits 0b1010 // : [4], 1 * number of digits
0o1234 // : [12], 3 * number of digits 0o1234 // : [12], 3 * number of digits
0x1234 // : [16], 4 * number of digits 0x1234 // : [16], 4 * number of digits
10 // : {a}. (Literal 10 a) => a 10 // : {a}. (Literal 10 a) => a
// a = Integer or [n] where n >= width 10 // a = Integer or [n] where n >= width 10
@ -356,7 +357,7 @@ in argument definitions.
then y then y
else z : Bit // the type annotation is on `z`, not the whole `if` else z : Bit // the type annotation is on `z`, not the whole `if`
[1..9 : [8]] // specify that elements in `[1..9]` have type `[8]` [1..9 : [8]] // specify that elements in `[1..9]` have type `[8]`
f (x : [8]) = x + 1 // type annotation on patterns f (x : [8]) = x + 1 // type annotation on patterns
.. todo:: .. todo::
@ -442,15 +443,23 @@ following notation:
`t `t
Here ``t`` should be a type expression with numeric kind. The resulting Here `t` should be a finite type expression with numeric kind. The resulting
expression is a finite word, which is sufficiently large to accommodate expression will be of a numeric base type, which is sufficiently large
the value of the type: to accommodate the value of the type:
.. code-block:: cryptol .. code-block:: cryptol
`t : {n} (fin n, n >= width t) => [n] `t : {a} (Literal t a) => a
This backtick notation is syntax sugar for an application of the
`number` primtive, so the above may be written as:
.. code-block:: cryptol
number`{t} : {a} (Literal t a) => a
If a type cannot be inferred from context, a suitable type will be
automatically chosen if possible, usually `Integer`.
@ -507,7 +516,7 @@ sign. Examples:
(1,2,3) // A tuple with 3 component (1,2,3) // A tuple with 3 component
() // A tuple with no components () // A tuple with no components
{ x = 1, y = 2 } // A record with two fields, `x` and `y` { x = 1, y = 2 } // A record with two fields, `x` and `y`
{} // A record with no fields {} // A record with no fields
@ -520,7 +529,7 @@ Examples:
(1,2) == (1,2) // True (1,2) == (1,2) // True
(1,2) == (2,1) // False (1,2) == (2,1) // False
{ x = 1, y = 2 } == { x = 1, y = 2 } // True { x = 1, y = 2 } == { x = 1, y = 2 } // True
{ x = 1, y = 2 } == { y = 2, x = 1 } // True { x = 1, y = 2 } == { y = 2, x = 1 } // True
@ -539,7 +548,7 @@ component selectors are written as follows:
(15, 20).0 == 15 (15, 20).0 == 15
(15, 20).1 == 20 (15, 20).1 == 20
{ x = 15, y = 20 }.x == 15 { x = 15, y = 20 }.x == 15
Explicit record selectors may be used only if the program contains Explicit record selectors may be used only if the program contains
@ -549,12 +558,12 @@ record. For example:
.. code-block:: cryptol .. code-block:: cryptol
type T = { sign : Bit, number : [15] } type T = { sign : Bit, number : [15] }
// Valid definition: // Valid definition:
// the type of the record is known. // the type of the record is known.
isPositive : T -> Bit isPositive : T -> Bit
isPositive x = x.sign isPositive x = x.sign
// Invalid definition: // Invalid definition:
// insufficient type information. // insufficient type information.
badDef x = x.f badDef x = x.f
@ -567,9 +576,9 @@ patterns use braces. Examples:
.. code-block:: cryptol .. code-block:: cryptol
getFst (x,_) = x getFst (x,_) = x
distance2 { x = xPos, y = yPos } = xPos ^^ 2 + yPos ^^ 2 distance2 { x = xPos, y = yPos } = xPos ^^ 2 + yPos ^^ 2
f p = x + y where f p = x + y where
(x, y) = p (x, y) = p
@ -605,14 +614,14 @@ notation:
r = { x = 15, y = 20 } // a record r = { x = 15, y = 20 } // a record
t = (True,True) // a tuple t = (True,True) // a tuple
n = { pt = r, size = 100 } // nested record n = { pt = r, size = 100 } // nested record
// Setting fields // Setting fields
{ r | x = 30 } == { x = 30, y = 20 } { r | x = 30 } == { x = 30, y = 20 }
{ t | 0 = False } == (False,True) { t | 0 = False } == (False,True)
// Update relative to the old value // Update relative to the old value
{ r | x -> x + 5 } == { x = 20, y = 20 } { r | x -> x + 5 } == { x = 20, y = 20 }
// Update a nested field // Update a nested field
{ n | pt.x = 10 } == { pt = { x = 10, y = 20 }, size = 100 } { n | pt.x = 10 } == { pt = { x = 10, y = 20 }, size = 100 }
{ n | pt.x -> x + 10 } == { pt = { x = 25, y = 20 }, size = 100 } { n | pt.x -> x + 10 } == { pt = { x = 25, y = 20 }, size = 100 }
@ -630,20 +639,25 @@ an infinite stream of bits.
.. code-block:: cryptol .. code-block:: cryptol
[e1,e2,e3] // A sequence with three elements [e1,e2,e3] // A sequence with three elements
[t1 .. t3 ] // Sequence enumerations
[t1, t2 .. t3 ] // Step by t2 - t1
[e1 ... ] // Infinite sequence starting at e1
[e1, e2 ... ] // Infinite sequence stepping by e2-e1
[ e | p11 <- e11, p12 <- e12 // Sequence comprehensions
| p21 <- e21, p22 <- e22 ]
x = generate (\i -> e) // Sequence from generating function
x @ i = e // Sequence with index binding
arr @ i @ j = e // Two-dimensional sequence
[t1 .. t2] // Enumeration
[t1 .. <t2] // Enumeration (exclusive bound)
[t1 .. t2 by n] // Enumeration (stride)
[t1 .. <t2 by n] // Enumeration (stride, ex. bound)
[t1 .. t2 down by n] // Enumeration (downward stride)
[t1 .. >t2 down by n] // Enumeration (downward stride, ex. bound)
[t1, t2 .. t3] // Enumeration (step by t2 - t1)
[e1 ...] // Infinite sequence starting at e1
[e1, e2 ...] // Infinite sequence stepping by e2-e1
[ e | p11 <- e11, p12 <- e12 // Sequence comprehensions
| p21 <- e21, p22 <- e22 ]
x = generate (\i -> e) // Sequence from generating function
x @ i = e // Sequence with index binding
arr @ i @ j = e // Two-dimensional sequence
Note: the bounds in finite sequences (those with `..`) are type Note: the bounds in finite sequences (those with `..`) are type
expressions, while the bounds in infinite sequences are value expressions, while the bounds in infinite sequences are value
@ -774,7 +788,7 @@ identifiers using the symbol ``::``.
.. code-block:: cryptol .. code-block:: cryptol
module Hash::SHA256 where module Hash::SHA256 where
sha256 = ... sha256 = ...
The structure in the name may be used to group together related The structure in the name may be used to group together related
@ -853,7 +867,7 @@ to use a *hiding* import:
:caption: module M :caption: module M
module M where module M where
f = 0x02 f = 0x02
g = 0x03 g = 0x03
h = 0x04 h = 0x04
@ -863,9 +877,9 @@ to use a *hiding* import:
:caption: module N :caption: module N
module N where module N where
import M hiding (h) // Import everything but `h` import M hiding (h) // Import everything but `h`
x = f + g x = f + g
@ -880,7 +894,7 @@ Another way to avoid name collisions is by using a
:caption: module M :caption: module M
module M where module M where
f : [8] f : [8]
f = 2 f = 2
@ -889,9 +903,9 @@ Another way to avoid name collisions is by using a
:caption: module N :caption: module N
module N where module N where
import M as P import M as P
g = P::f g = P::f
// `f` was imported from `M` // `f` was imported from `M`
// but when used it needs to be prefixed by the qualifier `P` // but when used it needs to be prefixed by the qualifier `P`
@ -1097,20 +1111,20 @@ a module instantiation:
.. code-block:: cryptol .. code-block:: cryptol
module M where module M where
parameter parameter
x : [8] x : [8]
y : [8] y : [8]
f : [8] f : [8]
f = x + y f = x + y
.. code-block:: cryptol .. code-block:: cryptol
module N where module N where
import `M import `M
g = f { x = 2, y = 3 } g = f { x = 2, y = 3 }
A *backtick* at the start of the name of an imported module indicates A *backtick* at the start of the name of an imported module indicates

Binary file not shown.

View File

@ -90,12 +90,14 @@ infix
primitive primitive
parameter parameter
constraint constraint
by
down
---> --->
else include property let infixl parameter else include property let infixl parameter
extern module then import infixr constraint extern module then import infixr constraint
if newtype type as infix if newtype type as infix by
private pragma where hiding primitive private pragma where hiding primitive down
The following table contains Cryptol's operators and their The following table contains Cryptol's operators and their
@ -435,19 +437,25 @@ _word_. We may abbreviate the type `[n] Bit` as `[n]`. An infinite
sequence with elements of type `a` has type `[inf] a`, and `[inf]` is sequence with elements of type `a` has type `[inf] a`, and `[inf]` is
an infinite stream of bits. an infinite stream of bits.
[e1,e2,e3] // A sequence with three elements [e1,e2,e3] // A sequence with three elements
[t1 .. t3 ] // Sequence enumerations [t1 .. t2] // Enumeration
[t1, t2 .. t3 ] // Step by t2 - t1 [t1 .. <t2] // Enumeration (exclusive bound)
[e1 ... ] // Infinite sequence starting at e1 [t1 .. t2 by n] // Enumeration (stride)
[e1, e2 ... ] // Infinite sequence stepping by e2-e1 [t1 .. <t2 by n] // Enumeration (stride, ex. bound)
[t1 .. t2 down by n] // Enumeration (downward stride)
[t1 .. >t2 down by n] // Enumeration (downward stride, ex. bound)
[t1, t2 .. t3] // Enumeration (step by t2 - t1)
[ e | p11 <- e11, p12 <- e12 // Sequence comprehensions [e1 ...] // Infinite sequence starting at e1
[e1, e2 ...] // Infinite sequence stepping by e2-e1
[ e | p11 <- e11, p12 <- e12 // Sequence comprehensions
| p21 <- e21, p22 <- e22 ] | p21 <- e21, p22 <- e22 ]
x = generate (\i -> e) // Sequence from generating function x = generate (\i -> e) // Sequence from generating function
x @ i = e // Sequence with index binding x @ i = e // Sequence with index binding
arr @ i @ j = e // Two-dimensional sequence arr @ i @ j = e // Two-dimensional sequence
Note: the bounds in finite sequences (those with `..`) are type Note: the bounds in finite sequences (those with `..`) are type
@ -508,11 +516,19 @@ following notation:
`t `t
Here `t` should be a type expression with numeric kind. The resulting Here `t` should be a finite type expression with numeric kind. The resulting
expression is a finite word, which is sufficiently large to accommodate expression will be of a numeric base type, which is sufficiently large
the value of the type: to accommodate the value of the type:
`t : {n} (fin n, n >= width t) => [n] `t : {a} (Literal t a) => a
This backtick notation is syntax sugar for an application of the
`number` primtive, so the above may be written as:
number`{t} : {a} (Literal t a) => a
If a type cannot be inferred from context, a suitable type will be
automatically chosen if possible, usually `Integer`.
Explicit Type Annotations Explicit Type Annotations
========================= =========================

Binary file not shown.

View File

@ -218,7 +218,7 @@ primitive fromToLessThan :
* Note that 'last' will only be an element of the enumeration if * Note that 'last' will only be an element of the enumeration if
* 'stride' divides 'last - first' evenly. * 'stride' divides 'last - first' evenly.
* *
* '[x .. y by n]` is syntactic sugar for 'fromToBy`{first=x,last=y,stride=n}'. * '[x .. y by n]' is syntactic sugar for 'fromToBy`{first=x,last=y,stride=n}'.
*/ */
primitive fromToBy : {first, last, stride, a} primitive fromToBy : {first, last, stride, a}
(fin last, fin stride, stride >= 1, last >= first, Literal last a) => (fin last, fin stride, stride >= 1, last >= first, Literal last a) =>
@ -230,7 +230,7 @@ primitive fromToBy : {first, last, stride, a}
* be empty. If 'bound = inf' then the sequence will be infinite, and will * be empty. If 'bound = inf' then the sequence will be infinite, and will
* eventually wrap around for bounded types. * eventually wrap around for bounded types.
* *
* '[x ..< y by n]' is syntactic sugar for 'fromToByLessThan`{first=a,bound=b,stride=n}'. * '[x ..< y by n]' is syntactic sugar for 'fromToByLessThan`{first=x,bound=y,stride=n}'.
*/ */
primitive fromToByLessThan : {first, bound, stride, a} primitive fromToByLessThan : {first, bound, stride, a}
(fin first, fin stride, stride >= 1, bound >= first, LiteralLessThan bound a) => (fin first, fin stride, stride >= 1, bound >= first, LiteralLessThan bound a) =>
@ -241,7 +241,7 @@ primitive fromToByLessThan : {first, bound, stride, a}
* Note that 'last' will only be an element of the enumeration if * Note that 'last' will only be an element of the enumeration if
* 'stride' divides 'first - last' evenly. * 'stride' divides 'first - last' evenly.
* *
* '[x .. y down by n]` is syntactic sugar for 'fromToDownBy`{first=x,last=y,stride=n}'. * '[x .. y down by n]' is syntactic sugar for 'fromToDownBy`{first=x,last=y,stride=n}'.
*/ */
primitive fromToDownBy : {first, last, stride, a} primitive fromToDownBy : {first, last, stride, a}
(fin first, fin stride, stride >= 1, first >= last, Literal first a) => (fin first, fin stride, stride >= 1, first >= last, Literal first a) =>
@ -251,7 +251,7 @@ primitive fromToDownBy : {first, last, stride, a}
* A finite sequence counting from 'first' down to (but not including) * A finite sequence counting from 'first' down to (but not including)
* 'bound' by 'stride'. * 'bound' by 'stride'.
* *
* '[x ..> y down by n]` is syntactic sugar for * '[x ..> y down by n]' is syntactic sugar for
* 'fromToDownByGreaterThan`{first=x,bound=y,stride=n}'. * 'fromToDownByGreaterThan`{first=x,bound=y,stride=n}'.
* *
* Note that if 'first = bound' the sequence will be empty. * Note that if 'first = bound' the sequence will be empty.
@ -264,7 +264,7 @@ primitive fromToDownByGreaterThan : {first, bound, stride, a}
* A finite arithmetic sequence starting with 'first' and 'next', * A finite arithmetic sequence starting with 'first' and 'next',
* stopping when the values reach or would skip over 'last'. * stopping when the values reach or would skip over 'last'.
* *
* '[a,b..c]' is syntactic sugar for 'fromThenTo`{first=a,next=b,last=c}'. * '[x,y..z]' is syntactic sugar for 'fromThenTo`{first=x,next=y,last=z}'.
*/ */
primitive fromThenTo : {first, next, last, a, len} primitive fromThenTo : {first, next, last, a, len}
( fin first, fin next, fin last ( fin first, fin next, fin last
@ -274,12 +274,12 @@ primitive fromThenTo : {first, next, last, a, len}
// Fractional Literals --------------------- // Fractional Literals ---------------------
/** 'FLiteral m n r a' asserts that the type `a' contains the /** 'FLiteral m n r a' asserts that the type 'a' contains the
fraction `m/n`. The flag `r` indicates if we should round (`r >= 1`) fraction 'm/n'. The flag 'r' indicates if we should round ('r >= 1')
or report an error if the number can't be represented exactly. */ or report an error if the number can't be represented exactly. */
primitive type FLiteral : # -> # -> # -> * -> Prop primitive type FLiteral : # -> # -> # -> * -> Prop
/** A fractional literal corresponding to `m/n` */ /** A fractional literal corresponding to 'm/n' */
primitive primitive
fraction : { m, n, r, a } FLiteral m n r a => a fraction : { m, n, r, a } FLiteral m n r a => a

View File

@ -541,7 +541,7 @@ To evaluate a primitive, we look up its implementation by name in a table.
> evalPrim :: Name -> Value > evalPrim :: Name -> Value
> evalPrim n > evalPrim n
> | Just i <- asPrim n, Just v <- Map.lookup i primTable = v > | Just i <- asPrim n, Just v <- Map.lookup i primTable = v
> | otherwise = evalPanic "evalPrim" ["Unimplemented primitive", show n] > | otherwise = evalPanic "evalPrim" ["Unimplemented primitive", show (pp n)]
Cryptol primitives fall into several groups, mostly delineated Cryptol primitives fall into several groups, mostly delineated
by corresponding type classes: by corresponding type classes:
@ -566,7 +566,9 @@ by corresponding type classes:
* Indexing: `@`, `@@`, `!`, `!!`, `update`, `updateEnd` * Indexing: `@`, `@@`, `!`, `!!`, `update`, `updateEnd`
* Enumerations: `fromTo`, `fromThenTo`, `fromToLessThan`, `infFrom`, `infFromThen` * Enumerations: `fromTo`, `fromThenTo`, `fromToLessThan`, `fromToBy`,
`fromToByLessThan`, `fromToDownBy`, `fromToDownByGreaterThan`,
`infFrom`, `infFromThen`
* Polynomials: `pmult`, `pdiv`, `pmod` * Polynomials: `pmult`, `pdiv`, `pmod`
@ -782,29 +784,71 @@ by corresponding type classes:
> -- Enumerations > -- Enumerations
> , "fromTo" ~> vFinPoly $ \first -> pure $ > , "fromTo" ~> vFinPoly $ \first -> pure $
> vFinPoly $ \lst -> pure $ > vFinPoly $ \lst -> pure $
> VPoly $ \ty -> > VPoly $ \ty -> pure $
> let f i = literal i ty > let f i = literal i ty in
> in pure (VList (Nat (1 + lst - first)) (map f [first .. lst])) > VList (Nat (1 + lst - first)) (map f [first .. lst])
>
> , "fromToLessThan" ~>
> vFinPoly $ \first -> pure $
> VNumPoly $ \bound -> pure $
> VPoly $ \ty -> pure $
> let f i = literal i ty in
> case bound of
> Inf -> VList Inf (map f [first ..])
> Nat bound' ->
> let len = bound' - first in
> VList (Nat len) (map f (genericTake len [first ..]))
>
> , "fromToBy" ~> vFinPoly $ \first -> pure $
> vFinPoly $ \lst -> pure $
> vFinPoly $ \stride -> pure $
> VPoly $ \ty -> pure $
> let f i = literal i ty in
> let vs = [ f (first + i*stride) | i <- [0..] ] in
> let len = 1 + ((lst-first) `div` stride) in
> VList (Nat len) (genericTake len vs)
>
> , "fromToByLessThan" ~>
> vFinPoly $ \first -> pure $
> VNumPoly $ \bound -> pure $
> vFinPoly $ \stride -> pure $
> VPoly $ \ty -> pure $
> let f i = literal i ty in
> let vs = [ f (first + i*stride) | i <- [0..] ] in
> case bound of
> Inf -> VList Inf vs
> Nat bound' ->
> let len = (bound'-first+stride-1) `div` stride in
> VList (Nat len) (genericTake len vs)
>
> , "fromToDownBy" ~>
> vFinPoly $ \first -> pure $
> vFinPoly $ \lst -> pure $
> vFinPoly $ \stride -> pure $
> VPoly $ \ty -> pure $
> let f i = literal i ty in
> let vs = [ f (first - i*stride) | i <- [0..] ] in
> let len = 1 + ((first-lst) `div` stride) in
> VList (Nat len) (genericTake len vs)
>
> , "fromToDownByGreaterThan" ~>
> vFinPoly $ \first -> pure $
> vFinPoly $ \lst -> pure $
> vFinPoly $ \stride -> pure $
> VPoly $ \ty -> pure $
> let f i = literal i ty in
> let vs = [ f (first - i*stride) | i <- [0..] ] in
> let len = (first-lst+stride-1) `div` stride in
> VList (Nat len) (genericTake len vs)
> >
> , "fromThenTo" ~> vFinPoly $ \first -> pure $ > , "fromThenTo" ~> vFinPoly $ \first -> pure $
> vFinPoly $ \next -> pure $ > vFinPoly $ \next -> pure $
> vFinPoly $ \_lst -> pure $ > vFinPoly $ \_lst -> pure $
> VPoly $ \ty -> pure $ > VPoly $ \ty -> pure $
> vFinPoly $ \len -> > vFinPoly $ \len -> pure $
> let f i = literal i ty
> in pure (VList (Nat len)
> (map f (genericTake len [first, next ..])))
>
> , "fromToLessThan" ~>
> vFinPoly $ \first -> pure $
> VNumPoly $ \bound -> pure $
> VPoly $ \ty ->
> let f i = literal i ty in > let f i = literal i ty in
> case bound of > VList (Nat len)
> Inf -> pure (VList Inf (map f [first ..])) > (map f (genericTake len [first, next ..]))
> Nat bound' ->
> let len = bound' - first in
> pure (VList (Nat len) (map f (genericTake len [first ..])))
> >
> , "infFrom" ~> VPoly $ \ty -> pure $ > , "infFrom" ~> VPoly $ \ty -> pure $
> VFun $ \first -> > VFun $ \first ->