on master help sign in
35 files changed+1015−562
since splitsnapshots
unifiedsplit
.travis.yml+39−12 INSTALL.md+11−2 README.md+3 docs/conf.py+2−1 docs/effects/introduction.rst+2−1 docs/parserLibrary/introduction.rst+7−7 docs/parserLibrary/lexer.rst+25−19 docs/parserLibrary/parser.rst+190−112 docs/parserLibrary/whitespace.rst+131−35 docs/reference/misc.rst+5−5 idris-tutorial.pdf idris.cabal+31−15 libs/base/Control/Isomorphism.idr+20−23 libs/contrib/Control/Algebra/Laws.idr+128−80 libs/contrib/Data/List/Extra.idr−46 libs/contrib/Data/List/Reverse.idr+99 libs/contrib/Data/Nat/Fact.idr+56 libs/contrib/Data/Nat/Parity.idr+123−69 libs/contrib/contrib.ipkg+1−1 libs/prelude/Prelude/File.idr+3−2 libs/prelude/Prelude/Nat.idr+32−61 rts/idris_bitstring.c−2 rts/idris_rts.c−10 rts/idris_rts.h−4 rts/idris_stdfgn.c+12−2 rts/idris_stdfgn.h+4−1 rts/idris_utf8.c−1 src/Idris/Core/TT.hs+1−1 src/Idris/Parser/Stack.hs+14−1 stack-11.22.yaml+21 stack-12.26.yaml+20 stack-15.3.yaml+17 stack-15.4.yaml+17 stack-alt.yaml−25 stack.yaml+1−24
.travis.yml+39−12
@@ -8,7 +8,7 @@ env:
88
99matrix:
1010 include:
11− - env: CABALVER="2.4" GHCVER="8.6.5" STACKVER="14.15" STYLISH=YES
11+ - env: CABALVER="2.4" GHCVER="8.6.5" STACKVER="15.4" STYLISH=YES
1212 addons: {apt: {packages: [cabal-install-2.4,ghc-8.6.5,hscolour], sources: [hvr-ghc]}}
1313 - env: CABALVER="2.4" GHCVER="8.2.2" TESTS="lib_doc doc"
1414 compiler: ": #GHC 8.2.2"
@@ -19,16 +19,26 @@ matrix:
1919 - env: CABALVER="2.4" GHCVER="8.2.2" TESTS="test_c"
2020 compiler: ": #GHC 8.2.2"
2121 addons: {apt: {packages: [cabal-install-2.4,ghc-8.2.2,cppcheck,hscolour], sources: [hvr-ghc]}}
22−
23−# - env: CABALVER="3.0" GHCVER="8.8.1" TESTS="lib_doc doc"
24−# compiler: ": #GHC 8.8.1"
25−# addons: {apt: {packages: [cabal-install-3.0,ghc-8.8.1,cppcheck,hscolour], sources: [hvr-ghc]}}
26−# - env: CABALVER="3.0" GHCVER="8.8.1" TESTS="test_js"
27−# compiler: ": #GHC 8.8.1"
28−# addons: {apt: {packages: [cabal-install-3.0,ghc-8.8.1,cppcheck,hscolour], sources: [hvr-ghc]}}
29−# - env: CABALVER="3.0" GHCVER="8.8.1" TESTS="test_c"
30−# compiler: ": #GHC 8.8.1"
31−# addons: {apt: {packages: [cabal-install-3.0,ghc-8.8.1,cppcheck,hscolour], sources: [hvr-ghc]}}
22+ - env: CABALVER="2.4" GHCVER="8.4.4" TESTS="lib_doc doc"
23+ compiler: ": #GHC 8.4.4"
24+ addons: {apt: {packages: [cabal-install-2.4,ghc-8.4.4,cppcheck,hscolour], sources: [hvr-ghc]}}
25+ - env: CABALVER="2.4" GHCVER="8.4.4" TESTS="test_js"
26+ compiler: ": #GHC 8.4.4"
27+ addons: {apt: {packages: [cabal-install-2.4,ghc-8.4.4,cppcheck,hscolour], sources: [hvr-ghc]}}
28+ - env: CABALVER="2.4" GHCVER="8.4.4" TESTS="test_c"
29+ compiler: ": #GHC 8.4.4"
30+ addons: {apt: {packages: [cabal-install-2.4,ghc-8.4.4,cppcheck,hscolour], sources: [hvr-ghc]}}
31+ - env: CABALVER="3.0" GHCVER="8.8.3" TESTS="lib_doc doc"
32+ compiler: ": #GHC 8.8.3"
33+ addons: {apt: {packages: [cabal-install-3.0,ghc-8.8.3,cppcheck,hscolour], sources: [hvr-ghc]}}
34+ - env: CABALVER="3.0" GHCVER="8.8.3" TESTS="test_js"
35+ compiler: ": #GHC 8.8.3"
36+ addons: {apt: {packages: [cabal-install-3.0,ghc-8.8.3,cppcheck,hscolour], sources: [hvr-ghc]}}
37+ - env: CABALVER="3.0" GHCVER="8.8.3" TESTS="test_c"
38+ compiler: ": #GHC 8.8.3"
39+ addons: {apt: {packages: [cabal-install-3.0,ghc-8.8.3,cppcheck,hscolour], sources: [hvr-ghc]}}
40+ - env: CABALVER="3.0" GHCVER="8.8.3" IDRIS2=YES
41+ addons: {apt: {packages: [cabal-install-3.0,ghc-8.8.3], sources: [hvr-ghc]}}
3242 fast-finish: true
3343
3444cache:
@@ -47,7 +57,7 @@ before_install:
4757 - unset CC
4858 - if [[ $TRAVIS_OS_NAME == 'linux' ]];
4959 then
50− export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$HOME/.cabal/bin:$PATH;
60+ export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$HOME/.cabal/bin:$HOME/opt/scheme/bin/:$PATH;
5161 export SED=sed;
5262 export ZCAT=zcat;
5363 fi
@@ -62,6 +72,21 @@ before_install:
6272 export PKG_CONFIG_PATH=/usr/local/opt/libffi/lib/pkgconfig:$PKG_CONFIG_PATH;
6373 fi
6474 - if [ -n "$STYLISH" ]; then ./stylize.sh; exit $?; fi
75+ - if [ -n "$IDRIS2" ];
76+ then
77+ git clone https://github.com/edwinb/Idris2 &&
78+ wget https://github.com/cisco/ChezScheme/archive/v9.5.2.tar.gz &&
79+ tar xvzf v9.5.2.tar.gz &&
80+ cd ChezScheme-9.5.2 &&
81+ ./configure --threads --installprefix=$HOME/opt/scheme &&
82+ make -j install &&
83+ cd .. &&
84+ cabal v1-update &&
85+ travis_wait cabal v1-install &&
86+ cd Idris2 &&
87+ make idris2 && make base && make contrib;
88+ exit $?;
89+ fi
6590
6691install:
6792 - which cabal
@@ -103,6 +128,7 @@ install:
103128 cp -a $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin installplan.txt $HOME/.cabsnap/;
104129 fi
105130
131+
106132before_script:
107133 - ORIGINAL_DIR=$(pwd)
108134 - cabal v1-sdist
@@ -110,6 +136,7 @@ before_script:
110136 - tar -xf ${ORIGINAL_DIR}/dist/${PKGNAME}*.tar.gz
111137 - cd ${PKGNAME}*
112138script:
139+ - export LD_PRELOAD=/opt/ghc/${GHCVER}/lib/ghc-${GHCVER}/rts/libffi.so.7
113140###
114141 - echo 'Configure...' && echo -en 'travis_fold:start:script.configure\\r'
115142 - cabal v1-configure -f FFI -f CI --enable-tests
INSTALL.md+11−2
@@ -130,7 +130,8 @@ PKG_CONFIG_PATH=/usr/local/opt/libffi/lib/pkgconfig stack build
130130## Issue with GHC on Ubuntu/Fedora
131131
132132There is an upstream issue with GHC on some Ubuntu and Fedora machines.
133−The issue is that for GHC versions greater than 8.4.X linking to libFFI is broken.
133+The issue is that for GHC versions greater than 8.4.X linking to libFFI uses the version of libFFI shipped with GHC, instead of the system version.
134+
134135See the following GHC issue page for more information:
135136
136137 <https://gitlab.haskell.org/ghc/ghc/issues/15397>
@@ -141,4 +142,12 @@ Specifically, one will see an error message along the lines of:
141142
142143> error while loading shared libraries: libffi.so.7: cannot open shared object file: No such file or directory
143144
144−We have supplied an alternative stack configuration file (`stack-alt.yaml`) that will use a version of GHC prior to the upstream issue being introduced.
145+A workround for this bug is to override the used libffi version (this is what we use on CI):
146+
147+```bash
148+export LD_PRELOAD=/opt/ghc/${GHCVER}/lib/ghc-${GHCVER}/rts/libffi.so.7
149+```
150+
151+## GHC 8.6
152+
153+For reasons that haven't been investigated building the Idris compiler with GHC 8.6 leads to a compiler which doesn't pass test.
README.md+3
@@ -44,3 +44,6 @@ where some interesting projects are being hosted.
4444
4545For those interested in contributing to Idris directly we kindly ask that
4646prospective developers please consult the [Contributing Guide](CONTRIBUTING.md) first.
47+
48+[Idris 2](https://github.com/edwinb/Idris2) is an early preview of the next generation
49+of Idris, implemented in Idris.
docs/conf.py+2−1
@@ -251,6 +251,7 @@ latex_elements = {
251251# Additional stuff for the LaTeX preamble.
252252'preamble': r'''
253253\usepackage{lmodern}
254+\usepackage{textalpha}
254255\usepackage[T1]{fontenc}
255256\usepackage[utf8x]{inputenc}
256257\usepackage{titlesec}
@@ -300,7 +301,7 @@ latex_elements = {
300301# (source start file, target name, title,
301302# author, documentclass [howto, manual, or own class]).
302303latex_documents = [
303− ('index', 'idris-documentation-complete.tex', u'Documentation for the Idris Language', u'The Idris Community', 'report'),
304+ # (master_doc, 'idris.tex', u'Documentation for the Idris Language', u'The Idris Community', 'report')
304305 ('tutorial/index', 'idris-tutorial.tex', u'The Idris Tutorial', u'The Idris Community', 'howto'),
305306]
306307
docs/effects/introduction.rst+2−1
@@ -17,7 +17,8 @@ exceptions, and verified resource management.
1717This tutorial assumes familiarity with pure programming in Idris,
1818as described in Sections 1–6 of the main tutorial [1]_. The examples
1919presented are tested with Idris and can be found in the
20−examples directory of the Idris repository.
20+examples directory of the Idris repository. The ``-p effects`` flag
21+is needed when starting Idris.
2122
2223Consider, for example, the following introductory function which
2324illustrates the kind of properties which can be expressed in the type
docs/parserLibrary/introduction.rst+7−7
@@ -25,21 +25,21 @@ complicated parser can be made out of many smaller ones.
2525 - Lexer - This takes the input string and turns it into a list of Tokens.
2626 - Parser - This takes the list of tokens and outputs the code.
2727
28−.. image:: ../image/parserTopLevel.png
29− :width: 307px
30− :height: 76px
31− :alt: diagram illustrating these stages of lexer and parser
28+ - .. image:: ../image/parserTopLevel.png
29+ :width: 307px
30+ :height: 76px
31+ :alt: diagram illustrating these stages of lexer and parser
3232
3333The advantage of using two stages, like this, is that things like whitespace and
3434comments don't need to be considered in every parser rule.
3535
36−The Idris parser library differs from Parsec in that you need to say in the
37−Recogniser whether a rule is guaranteed to consume input. This means that the
36+The Idris parser library differs from Parsec in that you need to say, in the
37+Recogniser, whether a rule is guaranteed to consume input. This means that the
3838Idris type system prevents the construction of recognisers/rules that can't
3939consume the input.
4040
4141The Lexer is similar but works at the level of characters rather than tokens, and
42−you need to provide a TokenMap which says how to build a token representation from
42+you need to provide a TokenMap which defines how to build a token from
4343a string when a rule is matched.
4444
4545The following pages contain a tutorial for the :ref:`parserLibraryLexer` and a
docs/parserLibrary/lexer.rst+25−19
@@ -10,13 +10,16 @@ module:
1010
1111 lex : TokenMap a -> String -> (List (TokenData a), (Int, Int, String))
1212
13−This function takes a String and returns a list of tokens. With the tokens we
14−have indexes back to the original string which can be used in error messages:
13+.. list-table::
14+
15+ * - This function takes a String and returns a list of tokens. With the
16+ tokens we have indexes back to the original string which can be used
17+ in error messages:
1518
16−.. image:: ../image/tokenise.png
17− :width: 330px
18− :height: 73px
19− :alt: diagram illustrating these stages of lexer
19+ - .. image:: ../image/tokenise.png
20+ :width: 330px
21+ :height: 73px
22+ :alt: diagram illustrating these stages of lexer
2023
2124TokenMap
2225--------
@@ -34,21 +37,24 @@ this information:
3437 (Lexer, String -> tokenType)
3538
3639So for each Lexer in the list, if a substring in the input matches, run
37−the associated function to produce a token of type `tokenType`
40+the associated function to produce a token of type ``tokenType``
3841
39−from Text.Lexer.Core:
42+.. list-table::
4043
41−.. code-block:: idris
44+ * - from Text.Lexer.Core
45+ : https://github.com/idris-lang/Idris-dev/blob/master/libs/contrib/Text/Lexer/Core.idr
4246
43− TokenMap : (tokenType : Type) -> Type
44− TokenMap tokenType = List (Lexer, String -> tokenType)
47+ - .. code-block:: idris
4548
46−We can create a tokenMap by using a function like this:
49+ TokenMap : (tokenType : Type) -> Type
50+ TokenMap tokenType = List (Lexer, String -> tokenType)
4751
48−.. code-block:: idris
52+ * - We can create a tokenMap by using a function like this:
53+
54+ - .. code-block:: idris
4955
50− myTokenMap : TokenMap Token
51− myTokenMap = [(is 'a',CharLit)]
56+ myTokenMap : TokenMap Token
57+ myTokenMap = [(is 'a',CharLit)]
5258
5359Once we have a TokenMap we can use it to lex many strings.
5460
@@ -74,7 +80,7 @@ combined, for example,
7480
7581.. list-table::
7682
77− * - <+> means sequence two recognisers. If either consumes a character,
83+ * - ``<+>`` means sequence two recognisers. If either consumes a character,
7884 the sequence is guaranteed to consume a character.
7985
8086 - .. code-block:: idris
@@ -83,7 +89,7 @@ combined, for example,
8389 SeqEat (Pred (\ARG => intToBool (prim__eqChar ARG 'a')))
8490 (Delay (is 'b')) : Recognise True
8591
86− * - <|> means if both consume, the combination is guaranteed
92+ * - ``<|>`` means if both consume, the combination is guaranteed
8793 to consumer a character:
8894
8995 - .. code-block:: idris
@@ -161,7 +167,7 @@ able to parse simple arithmetic expressions, like this:
161167so we need:
162168
163169- Numbers (for now integer literals are good enough).
164−- Some operators (for now '+', '-' and '*' will do.
170+- Some operators (for now ``+``, ``-`` and ``*`` will do.
165171- Opening and closing Parentheses.
166172
167173We can define these, as tokens, like this:
@@ -178,7 +184,7 @@ We can define these, as tokens, like this:
178184 | EndInput
179185
180186It may help with debugging and to implement error messages to
181−implement 'show' for these tokens:
187+implement ``show`` for these tokens:
182188
183189.. code-block:: idris
184190
docs/parserLibrary/parser.rst+190−112
@@ -3,8 +3,8 @@
33Parser
44======
55
6−To run our parser we call 'parse'. This requires a Grammar and the output
7−from the lexer (a list of tokens).
6+To run the parser we call ``parse``. This requires a grammar and the output
7+from the lexer (which is a list of tokens).
88
99.. code-block:: idris
1010
@@ -18,13 +18,13 @@ If successful this returns 'Right' with a pair of
1818
1919otherwise it returns 'Left' with the error message.
2020
21−So we need to define the Grammar for our parser, this is done using the following
21+So we need to define the grammar for our parser, this is done using the following
2222'Grammar' data structure. This is a combinator structure, similar in principle
2323to the recogniser combinator for the lexer, which was discussed on the
2424previous page.
2525
26−As with the Recogniser the Grammar type is dependent on a boolean 'consumes'
27−value which allows us to ensure that complicated Grammar structures will always
26+As with the Recogniser the ``Grammar`` type is dependent on a boolean 'consumes'
27+value which allows us to ensure that complicated ``Grammar`` structures will always
2828consume input.
2929
3030.. code-block:: idris
@@ -53,13 +53,13 @@ consume input.
5353 Grammar tok c1 ty -> Grammar tok c2 ty ->
5454 Grammar tok (c1 && c2) ty
5555
56−So an example of a Grammer type may look something like this:
57−'Grammar (TokenData ExpressionToken) True Integer'.
58−
56+So an example of a grammer type may look something like this:
57+``Grammar (TokenData ExpressionToken) True Integer``.
5958This is a complicated type name and a given parser will need to use it a lot.
6059So to reduce the amount of typing we can use the following type synonym (similar
6160to what is done in Idris 2
6261: https://github.com/edwinb/Idris2/blob/master/src/Parser/Support.idr
62+)
6363
6464.. code-block:: idris
6565
@@ -71,12 +71,12 @@ Parser Example
7171--------------
7272
7373On the previous page we implemented a lexer to 'lex' a very simple expression, on
74−this page we will go on to implement a parser for this running example.
74+this page we will go on to add a parser for this running example.
7575
7676.. list-table::
7777
78− * - Expressed in Backus–Naur form (BNF) the syntax we are aiming at is something
79− like this:
78+ * - The syntax we are aiming at is something
79+ like this (expressed in Backus–Naur form (BNF)):
8080 - .. code-block:: idris
8181
8282 <expr> ::= <integer literal>
@@ -89,8 +89,8 @@ this page we will go on to implement a parser for this running example.
8989
9090.. list-table::
9191
92− * - To start, here is a Grammar to parse an integer literal (that is, a
93− sequence of numbers).
92+ * - To start, here is a grammar to parse an integer literal (that is, a
93+ sequence of numeric characters).
9494
9595 - .. code-block:: idris
9696
@@ -144,7 +144,7 @@ successful, this is because we are not specifically checking for end-of-file.
144144
145145.. list-table::
146146
147− * - The 'intLiteral' function above uses the 'terminal' function to
147+ * - The ``intLiteral`` function above uses the ``terminal`` function to
148148 construct the grammar
149149 - .. code-block:: idris
150150
@@ -174,10 +174,10 @@ Idris 2 uses a slightly different version which stores an error message like
174174 OParen => Just 0
175175 _ => Nothing)
176176
177−Integer value is not really relevant for parenthesis so '0' is used as
177+Integer value is not really relevant for parenthesis so ``0`` (zero) is used as
178178a default value.
179179
180−As before, we can test this out with a function like this:
180+As before, this can be tested with a function like this:
181181
182182.. code-block:: idris
183183
@@ -202,10 +202,10 @@ error for anything else:
202202 List (TokenData ExpressionToken))
203203
204204Now we have two Grammars we can try combining them. The following test looks
205−for 'openParen' followed by 'intLiteral', the two Grammars are combined using
206−'<*>'. The 'map const' part uses the integer value from the first.
205+for ``openParen`` followed by ``intLiteral``, the two Grammars are combined using
206+``<*>``. The ``map const`` part uses the integer value from the first.
207207
208−The following test is looking for '(' followed by a number:
208+The following test is looking for ``(`` followed by a number:
209209
210210.. code-block:: idris
211211
@@ -213,8 +213,8 @@ The following test is looking for '(' followed by a number:
213213 (Integer, List (TokenData ExpressionToken))
214214 test3 s = parse (map const openParen <*> intLiteral) (fst (lex expressionTokens s))
215215
216−We can see below that '(' followed by a number is successfully parsed but other
217−token lists are not:
216+We can see below that ``(`` followed by a number is successfully parsed but, as
217+required, other token lists are not:
218218
219219.. code-block:: idris
220220
@@ -270,21 +270,87 @@ token lists are not:
270270 paren : Rule Integer -> Rule Integer
271271 paren exp = openParen *> exp <* closeParen
272272
273−The use of '*>' and '<*' instead of '<*>' is an easy way to use the integer
273+The use of ``*>`` and ``<*`` instead of ``<*>`` is an easy way to use the integer
274274value from the inner expression.
275275
276+So lets try to use this to define a grammar which recognises either:
277+
278+- An integer literal
279+- An integer literal inside parenthesis
280+- An integer literal inside parenthesis inside parenthesis
281+- ... and so on.
282+
283+.. list-table::
284+
285+ * - This requires a recursively defined structure like this:
286+
287+ - .. code-block:: idris
288+
289+ partial
290+ expr : Rule Integer
291+ expr = intLiteral <|> (paren expr)
292+
293+This is a valid grammar because every time it is called it is guaranteed to
294+consume a token. However, as an Idris structure, it is problematic due to
295+the recursion. Defining it as partial allows it to compile but at runtime
296+we are likely to get a crash with an (unhelpful) error message like
297+``killed by signal 11``.
298+
299+So a better method is to use ``do`` notation as described in the following
300+section.
301+
302+Monadic Combinator
303+------------------
304+
305+In addition to ``<|>`` and ``<*>`` there is a ``>>=`` combinator, which is
306+defined like this:
307+
308+.. code-block:: idris
309+
310+ ||| Sequence two grammars. If either consumes some input, the sequence is
311+ ||| guaranteed to consume some input. If the first one consumes input, the
312+ ||| second is allowed to be recursive (because it means some input has been
313+ ||| consumed and therefore the input is smaller)
314+ export %inline
315+ (>>=) : {c1 : Bool} ->
316+ Grammar tok c1 a ->
317+ inf c1 (a -> Grammar tok c2 b) ->
318+ Grammar tok (c1 || c2) b
319+ (>>=) {c1 = False} = SeqEmpty
320+ (>>=) {c1 = True} = SeqEat
321+
322+.. list-table::
323+
324+ * - This allows us to use ``do`` notation for the previous parenthesis example:
325+
326+ - .. code-block:: idris
327+
328+ expr = intLiteral <|> do
329+ openParen
330+ r <- expr
331+ closeParen
332+ pure r
333+
334+This can be more flexible than using the ``<*>`` operator. Also it is defined
335+using ``Inf`` so we can implement recursively defined grammars as above.
336+
337+Implementing the Arithmetic Operators
338+-------------------------------------
339+
276340.. list-table::
277341
278− * - Now for the operations, in this case: '+', '-' and '*'.
279− The syntax we require is that operators like '+' are infix operators, which
280− would require a definition like this:
342+ * - Now for the operations, in this case: ``+``, ``-`` and ``*``.
343+ The syntax we require for these infix operators
344+ would require recursive grammars like this:
281345
282346 - .. code-block:: idris
283347
284− expr = (add expr (op "+") expr)
348+ expr = expr (op "+") expr
349+
350+As already explained, ``do`` notation can allow us to use recursive
351+definitions but not necessarily left-recursion like this.
285352
286−This is a potentially infinite structure which is not total.
287−In order to work up to this gradually I will start with prefix operators
353+In order to work up to this gradually lets start with prefix operators
288354(sometimes known as Polish notation) then modify later for infix operators.
289355
290356.. list-table::
@@ -295,7 +361,7 @@ In order to work up to this gradually I will start with prefix operators
295361
296362 expr = (add (op "+") expr expr)
297363
298−where 'op' is defined like this:
364+where ``op`` is defined like this:
299365
300366.. code-block:: idris
301367
@@ -308,7 +374,13 @@ where 'op' is defined like this:
308374
309375.. list-table::
310376
311− * - and 'add' is defined like this:
377+ * - and ``add`` is defined like this:
378+
379+ Where:
380+
381+ - x is the add operator.
382+ - y is the first operand.
383+ - z is the second operand.
312384
313385 - .. code-block:: idris
314386
@@ -322,40 +394,37 @@ where 'op' is defined like this:
322394 Grammar tok ((c1 || c2) || c3) Integer
323395 add x y z = map addInt (x *> y) <*> z
324396
325−Where:
326397
327−- x is the add operator.
328−- y is the first operand.
329−- z is the second operand.
330398
331399The resulting integer will be the sum of the two operands.
332400
333−The other operators are defined in a similar way:
401+.. list-table::
334402
335−.. code-block:: idris
403+ * - The other operators are defined in a similar way:
336404
337− subInt : Integer -> Integer -> Integer
338− subInt a b = a-b
405+ - .. code-block:: idris
339406
340− export
341− sub : Grammar tok c1 Integer ->
342− Grammar tok c2 Integer ->
343− Grammar tok c3 Integer ->
344− Grammar tok ((c1 || c2) || c3) Integer
345− sub x y z = map subInt (x *> y) <*> z
407+ subInt : Integer -> Integer -> Integer
408+ subInt a b = a-b
346409
410+ export
411+ sub : Grammar tok c1 Integer ->
412+ Grammar tok c2 Integer ->
413+ Grammar tok c3 Integer ->
414+ Grammar tok ((c1 || c2) || c3) Integer
415+ sub x y z = map subInt (x *> y) <*> z
347416
348− multInt : Integer -> Integer -> Integer
349− multInt a b = a*b
417+ multInt : Integer -> Integer -> Integer
418+ multInt a b = a*b
350419
351− export
352− mult : Grammar tok c1 Integer ->
353− Grammar tok c2 Integer ->
354− Grammar tok c3 Integer ->
355− Grammar tok ((c1 || c2) || c3) Integer
356− mult x y z = map multInt (x *> y) <*> z
420+ export
421+ mult : Grammar tok c1 Integer ->
422+ Grammar tok c2 Integer ->
423+ Grammar tok c3 Integer ->
424+ Grammar tok ((c1 || c2) || c3) Integer
425+ mult x y z = map multInt (x *> y) <*> z
357426
358−So the top level Grammar can now be defined as follows. Note that this is
427+So the top level ``Grammar`` can now be defined as follows. Note that this is
359428partial as it is a potentially infinite structure and so not total.
360429
361430.. code-block:: idris
@@ -408,7 +477,7 @@ Then an invalid syntax:
408477 List (TokenData ExpressionToken))
409478
410479However if we try something that is invalid, but starts with a valid token,
411−then it will return 'Right' (to indicate success)
480+then it will return ``Right`` (to indicate success)
412481
413482.. code-block:: idris
414483
@@ -435,8 +504,8 @@ Infix Notation
435504--------------
436505
437506So far we have implemented a prefix notation for operators (like this:
438−'+ expr expr') but the aim is to implemented an infix notation (like this:
439−'expr + expr'). To do this we must be able to deal with potentially
507+``+ expr expr``) but the aim is to implemented an infix notation (like this:
508+``expr + expr``). To do this we must be able to deal with potentially
440509infinite data structures (see Codata Types here :ref:`sect-typefuns`).
441510
442511First alter the grammar to have infix operations:
@@ -494,10 +563,10 @@ If we have a rule like this:
494563
495564 A -> (x<*>y) <|> (x<*>z)
496565
497−If 'x<*>y' fails but 'x<*>z' would succeed a problem is that, 'x<*>y' has
498−already consumed 'x', so now 'x<*>z' will fail.
566+If ``x<*>y`` fails but ``x<*>z`` would succeed a problem is that, ``x<*>y`` has
567+already consumed ``x``, so now ``x<*>z`` will fail.
499568
500−so we could write code to backtrack. That is 'try' 'x<*>y' without consuming
569+so we could write code to backtrack. That is ``try`` ``x<*>y`` without consuming
501570so that, if the first token succeeds but the following tokens fail, then the
502571first tokens would not be consumed.
503572
@@ -524,52 +593,64 @@ That is we convert a general context-free grammar to a LL(1) grammar. Although
524593not every context-free grammar can be converted to a LL(1) grammar.
525594
526595This still does not solve the infinite recursion issue and there is another
527−problem: the precedence of the operators +, - and * is not explicit.
596+problem: the precedence of the operators ``+``, ``-`` and ``*`` is not explicit.
528597
529−To resolve this we can alter the example like this:
530−
531−.. code-block:: idris
598+.. list-table::
532599
533− paren : Rule Integer -> Rule Integer
534− paren exp = openParen *> exp <* closeParen
600+ * - To resolve this we can alter the example to have a BNF like this:
601+ Where braces ``{ ... }`` mean the contents can occur 1 or more times.
535602
536− addInt : Integer -> Integer -> Integer
537− addInt a b = a+b
603+ - .. code-block:: idris
538604
539− subInt : Integer -> Integer -> Integer
540− subInt a b = a-b
605+ 'expression' ::= ('+'|'-') 'term' {('+'|'-') 'term'}
541606
542− multInt : Integer -> Integer -> Integer
543− multInt a b = a*b
607+ 'term' ::= 'factor' {'*' 'factor'}
544608
545− partial
546− expr : Rule Integer
609+ 'factor' ::=
610+ number
611+ | '(' 'expression' ')'
547612
548− partial
549− exprAtom : Rule Integer
550− exprAtom = intLiteral <|> (paren expr)
551613
552− partial
553− expr1 : Rule Integer
554− expr1 = map multInt exprAtom <*> ((op "*") *> exprAtom)
614+.. code-block:: idris
555615
556− partial
557− exprMult : Rule Integer
558− exprMult = expr1 <|> exprAtom
616+ expr : Rule Integer
559617
560− partial
561− expr2 : Rule Integer
562− expr2 = map addInt exprMult <*> ((op "+") *> exprMult)
618+ factor : Rule Integer
619+ factor = intLiteral <|> do
620+ openParen
621+ r <- expr
622+ closeParen
623+ pure r
624+
625+ term : Rule Integer
626+ term = map multInt factor <*> (
627+ (op "*")
628+ *> factor)
629+ <|> factor
630+
631+ expr = map addInt term <*> (
632+ (op "+")
633+ *> term)
634+ <|> map subInt term <*> (
635+ (op "-")
636+ *> term)
637+ <|> term
638+
639+ calc : String -> Either (ParseError (TokenData ExpressionToken))
640+ (Integer, List (TokenData ExpressionToken))
641+ calc s = parse expr (fst (lex expressionTokens s))
563642
564− partial
565− exprAdd : Rule Integer
566− exprAdd = expr2 <|> exprMult
643+ lft : (ParseError (TokenData ExpressionToken)) -> IO ()
644+ lft (Error s lst) = putStrLn ("error:"++s)
567645
568− partial
569− expr3 : Rule Integer
570− expr3 = map subInt exprAdd <*> ((op "-") *> expr)
646+ rht : (Integer, List (TokenData ExpressionToken)) -> IO ()
647+ rht i = putStrLn ("right " ++ (show i))
571648
572− expr = expr3 <|> exprAdd
649+ main : IO ()
650+ main = do
651+ putStr "alg>"
652+ x <- getLine
653+ either lft rht (calc x) -- eliminator for Either
573654
574655As the following tests show, this now handles infix operators and precedence.
575656
@@ -579,44 +660,41 @@ As the following tests show, this now handles infix operators and precedence.
579660
580661 - .. code-block:: idris
581662
582− *parserExInfix> test "2*3"
583− Right (6,
584− []) : Either (ParseError (TokenData ExpressionToken))
585− (Integer, List (TokenData ExpressionToken))
663+ *algebraREPL> :exec
664+ alg>2*3
665+ right (6, [])
586666
587667 * - Check that atomic number literals work:
588668
589669 - .. code-block:: idris
590670
591− *parserExInfix> test "2"
592− Right (2,
593− []) : Either (ParseError (TokenData ExpressionToken))
594− (Integer, List (TokenData ExpressionToken))
671+ *algebraREPL> :exec
672+ alg>2
673+ right (2, [])
595674
596675 * - Check that '*' has a higher precedence than '+'.
597676
598677 - .. code-block:: idris
599678
600− *parserExInfix> test "2+3*4"
601− Right (14,
602− []) : Either (ParseError (TokenData ExpressionToken))
603− (Integer, List (TokenData ExpressionToken))
679+ *algebraREPL> :exec
680+ alg>2+3*4
681+ right (14, [])
604682
605683 * - Also '*' has a higher precedence than '+' when the order is reversed.
606684
607685 - .. code-block:: idris
608686
609− *parserExInfix> test "3*4+2"
610− Right (14,
611− []) : Either (ParseError (TokenData ExpressionToken))
612− (Integer, List (TokenData ExpressionToken))
687+ *algebraREPL> :exec
688+ alg>3*4+2
689+ right (14, [])
613690
614691 * - Also precedence can be overridden by parenthesis.
615692
616693 - .. code-block:: idris
617694
618− *parserExInfix> test "(2+3)*4"
619− Right (20,
620− []) : Either (ParseError (TokenData ExpressionToken))
621− (Integer, List (TokenData ExpressionToken))
695+ *algebraREPL> :exec
696+ alg>(2+3)*4
697+ right (20, [])
622698
699+This is still not correct because it does not correctly parse multiple sums or terms
700+like ``1+2+3`` or ``1*2*3``.
docs/parserLibrary/whitespace.rst+131−35
@@ -8,14 +8,16 @@ discussed how to handle whitespace and comments.
88
99In some grammars whitespace and comments would not be considered significant and
1010so we might be tempted not to generate any tokens for them. However, in the
11−running example, we may want to make spaces significant. For example, we might
12−want to implement function application expressed by juxtaposition as in
13−Haskell and Idris like this: ``f x``.
11+running example, we may want to make spaces significant in the future. For
12+example, we might want to implement function application expressed by
13+juxtaposition as in Haskell and Idris like this: ``f x``.
1414
15−Also, I'm not sure if it is an problem for error messages and so on if some
16−text does not have corresponding tokens.
15+So, on this page, we will add a token for whitespace and comments. We will
16+then consider two ways to process this:
1717
18−So, on this page, we will add a token for whitespace and comments.
18+- Filter all whitespace tokens from the lexer results before passing to
19+ the parser.
20+- Process the whitespace tokens in the parser.
1921
2022Whitespace and Comments in Lexer
2123--------------------------------
@@ -70,10 +72,31 @@ like this:
7072 spaces : Lexer
7173 spaces = some space
7274
75+If these whitespace tokens are not significant, that is, they can appear
76+anywhere and they are optional then we can filter them out before the parser
77+gets them like this:
78+
79+.. code-block:: idris
80+
81+ processWhitespace : (List (TokenData ExpressionToken), Int, Int, String)
82+ -> (List (TokenData ExpressionToken), Int, Int, String)
83+ processWhitespace (x,l,c,s) = ((filter notComment x),l,c,s) where
84+ notComment : TokenData ExpressionToken -> Bool
85+ notComment t = case tok t of
86+ Comment _ => False
87+ _ => True
88+
89+ calc : String -> Either (ParseError (TokenData ExpressionToken))
90+ (Integer, List (TokenData ExpressionToken))
91+ calc s = parse expr (fst (processWhitespace (lex expressionTokens s)))
92+
93+
7394Whitespace and Comments in Parser
7495---------------------------------
7596
76−Now that there are ``Comment`` tokens the parser needs to be able to handle them.
97+If we sometimes require whitespace to be significant then we can't filter
98+them out as above. In this case the ``Comment`` tokens are sent to the parser
99+which now needs to be able to handle them.
77100
78101.. code-block:: idris
79102
@@ -85,42 +108,68 @@ Now that there are ``Comment`` tokens the parser needs to be able to handle them
85108So far we don't have any syntax that requires spaces to be significant so we
86109need to define the grammar so that it will parse with, or without, spaces.
87110This needs to be done in a systematic way, here I have defined the grammar so
88−that there is an optional space to the right of every atom or operator:
111+that there is an optional space to the right of every atom or operator.
112+First add versions of ``intLiteral`` , ``openParen`` , ``closeParen``
113+and ``op`` that allow optional spaces/comments to the right of them:
89114
90115.. code-block:: idris
91116
92− partial
93− exprAtom : Rule Integer
94− exprAtom = (intLiteral <* commentSpace)
95− <|> intLiteral <|> (paren expr)
117+ intLiteralC : Rule Integer
118+ intLiteralC = (intLiteral <* commentSpace) <|> intLiteral
119+
120+ openParenC : Rule Integer
121+ openParenC = (openParen <* commentSpace) <|> openParen
96122
97− partial
98− expr1 : Rule Integer
99− expr1 = map multInt exprAtom <*> (
100− (((op "*") <* commentSpace) <|> (op "*"))
101− *> exprAtom)
123+ closeParenC : Rule Integer
124+ closeParenC = (closeParen <* commentSpace) <|> closeParen
102125
103− partial
104− exprMult : Rule Integer
105− exprMult = expr1 <|> exprAtom
126+ ||| like op but followed by optional comment or space
127+ opC : String -> Rule Integer
128+ opC s = ((op s) <* commentSpace) <|> (op s)
106129
107− partial
108− expr2 : Rule Integer
109− expr2 = map addInt exprMult <*> (
110− (((op "+") <* commentSpace) <|> (op "+"))
111− *> exprMult)
130+Then just use these functions instead of the original functions:
131+
132+.. code-block:: idris
112133
113− partial
114− exprAdd : Rule Integer
115− exprAdd = expr2 <|> exprMult
134+ expr : Rule Integer
116135
117− partial
118− expr3 : Rule Integer
119− expr3 = map subInt exprAdd <*> (
120− (((op "-") <* commentSpace) <|> (op "-"))
121− *> expr)
136+ factor : Rule Integer
137+ factor = intLiteralC <|> do
138+ openParenC
139+ r <- expr
140+ closeParenC
141+ pure r
142+
143+ term : Rule Integer
144+ term = map multInt factor <*> (
145+ (opC "*")
146+ *> factor)
147+ <|> factor
148+
149+ expr = map addInt term <*> (
150+ (opC "+")
151+ *> term)
152+ <|> map subInt term <*> (
153+ (opC "-")
154+ *> term)
155+ <|> term
156+
157+ calc : String -> Either (ParseError (TokenData ExpressionToken))
158+ (Integer, List (TokenData ExpressionToken))
159+ calc s = parse expr (fst (lex expressionTokens s))
160+
161+ lft : (ParseError (TokenData ExpressionToken)) -> IO ()
162+ lft (Error s lst) = putStrLn ("error:"++s)
163+
164+ rht : (Integer, List (TokenData ExpressionToken)) -> IO ()
165+ rht i = putStrLn ("right " ++ (show i))
166+
167+ main : IO ()
168+ main = do
169+ putStr "alg>"
170+ x <- getLine
171+ either lft rht (calc x) -- eliminator for Either
122172
123− expr = expr3 <|> exprAdd
124173
125174Defining Block Structure using Indents
126175--------------------------------------
@@ -141,14 +190,61 @@ We can see how Idris2 does it here
141190 init : IndentInfo
142191 init = 0
143192
193+EndInput Token
194+--------------
195+
196+So far, the parser will return a successful result even if the full input
197+is not consumed. To ensure that the top level syntax is fully matched we
198+add a ``EndInput`` token to indicate the last token.
199+
200+``EndInput`` is added to the other tokens like this:
144201
202+.. code-block:: idris
145203
204+ data ExpressionToken = Number Integer
205+ | Operator String
206+ | OParen
207+ | CParen
208+ | Comment String
209+ | EndInput
146210
211+A rule to consume this token is added:
147212
213+.. code-block:: idris
148214
215+ eoi : Rule Integer
216+ eoi = terminal (\x => case tok x of
217+ EndInput => Just 0
218+ _ => Nothing)
149219
220+Instead of using ``expr`` at the top level of the syntax we can now define
221+``exprFull`` as shown here. This will make sure that only when ``EndInput``
222+is consumed will the parse be successful:
150223
224+.. code-block:: idris
225+
226+ exprFull : Rule Integer
227+ exprFull = expr <* eoi
228+
229+The following code makes sure ``EndInput`` is added to the end of the token
230+list:
231+
232+.. code-block:: idris
233+
234+ processWhitespace : (List (TokenData ExpressionToken), Int, Int, String)
235+ -> (List (TokenData ExpressionToken), Int, Int, String)
236+ processWhitespace (x,l,c,s) = ((filter notComment x)++
237+ [MkToken l c EndInput],l,c,s) where
238+ notComment : TokenData ExpressionToken -> Bool
239+ notComment t = case tok t of
240+ Comment _ => False
241+ _ => True
151242
243+All we have to do now is use ``exprFull`` instead of ``expr``:
244+
245+.. code-block:: idris
152246
247+ calc : String -> Either (ParseError (TokenData ExpressionToken))
248+ (Integer, List (TokenData ExpressionToken))
249+ calc s = parse exprFull (fst (processWhitespace (lex expressionTokens s)))
153250
154−
docs/reference/misc.rst+5−5
@@ -115,11 +115,11 @@ Here is an example:
115115 import Syntax.PreorderReasoning
116116 multThree : (a, b, c : Nat) -> a * b * c = c * a * b
117117 multThree a b c =
118− (a * b * c) ={ sym (multAssociative a b c) }=
119− (a * (b * c)) ={ cong (multCommutative b c) }=
120− (a * (c * b)) ={ multAssociative a c b }=
121− (a * c * b) ={ cong {f = (* b)} (multCommutative a c) }=
122− (c * a * b) QED
118+ (a * b * c) ={ sym (multAssociative a b c) }=
119+ (a * (b * c)) ={ cong (multCommutative b c) }=
120+ (a * (c * b)) ={ multAssociative a c b }=
121+ (a * c * b) ={ cong {f = (* b)} (multCommutative a c) }=
122+ (c * a * b) QED
123123
124124Note that the parentheses are required -- only a simple expression can
125125be on the left of ``={ }=`` or ``QED``. Also, when using preorder
idris-tutorial.pdf

Binary file not shown.

idris.cabal+31−15
@@ -46,12 +46,19 @@ Build-type: Custom
4646
4747Tested-With: GHC == 7.10.3, GHC == 8.0.1
4848
49+-- NOTE: due to https://github.com/haskell/cabal/issues/6125 the use of ** is
50+-- heavily discouraged.
4951Data-files: idrisdoc/styles.css
50− jsrts/**/*.js
52+ jsrts/jsbn/*.js
53+ jsrts/*.js
5154 jsrts/jsbn/LICENSE
5255 rts/Makefile
53− rts/**/*.c
54− rts/**/*.h
56+ rts/*.c
57+ rts/seL4/*.c
58+ rts/arduino/*.c
59+ rts/windows/*.c
60+ rts/windows/*.h
61+ rts/*.h
5562 rts/seL4/CMakeLists.txt
5663 rts/seL4/README.md
5764
@@ -64,8 +71,13 @@ Extra-doc-files:
6471 RELEASE-CHECKS.md
6572 idris-tutorial.pdf
6673 man/idris.1
67− samples/**/*.idr
68− samples/**/*.lidr
74+ samples/effects/*.idr
75+ samples/misc/*.idr
76+ samples/tutorial/*.idr
77+ samples/ST/*.idr
78+ samples/ST/Graphics/*.idr
79+ samples/ST/Net/*.idr
80+ samples/misc/*.lidr
6981
7082-- extra-source-files is generated by Setup.hs using `git --ls-files`.
7183Extra-source-files:
@@ -73,15 +85,20 @@ Extra-source-files:
7385 config.mk
7486 custom.mk-alldeps
7587 mkpkg.sh
76− stack-alt.yaml
7788 stack-shell.nix
7889 stack.yaml
7990 stylize.sh
8091 win-release.sh
81−
92+
8293 benchmarks/*.pl
83− benchmarks/**/*.idr
84− benchmarks/**/*.ipkg
94+ benchmarks/fasta/*.idr
95+ benchmarks/fasta/*.ipkg
96+ benchmarks/pidigits/*.idr
97+ benchmarks/pidigits/*.ipkg
98+ benchmarks/quasigroups/*.idr
99+ benchmarks/quasigroups/*.ipkg
100+ benchmarks/trivial/*.idr
101+ benchmarks/trivial/*.ipkg
85102 benchmarks/quasigroups/board
86103
87104 icons/*.png
@@ -304,13 +321,13 @@ Library
304321 Build-depends: base >=4 && <5
305322 , aeson >= 0.6 && < 1.5
306323 , annotated-wl-pprint >= 0.7 && < 0.8
307− , ansi-terminal < 0.10
324+ , ansi-terminal < 0.11
308325 , ansi-wl-pprint < 0.7
309326 , array >= 0.4.0.1 && < 0.6
310327 , base64-bytestring < 1.1
311328 , binary >= 0.8.4.1 && < 0.9
312329 , blaze-html >= 0.6.1.3 && < 0.10
313− , blaze-markup >= 0.5.2.1 && < 0.9
330+ , blaze-markup >= 0.5.2.1 && < 0.10
314331 , bytestring < 0.11
315332 , cheapskate >= 0.1.1.2 && < 0.2
316333 , code-page >= 0.1 && < 0.3
@@ -321,9 +338,9 @@ Library
321338 , fingertree >= 0.1.4.1 && < 0.2
322339 , haskeline >= 0.7 && < 0.8
323340 , ieee754 >= 0.7 && < 0.9
324− , megaparsec >= 7.0.4 && < 8
341+ , megaparsec >= 7.0.4 && < 9
325342 , mtl >= 2.1 && < 2.3
326− , network >= 2.7 && < 2.9
343+ , network >= 2.7 && < 3.1.2
327344 , optparse-applicative >= 0.13 && < 0.16
328345 , parser-combinators >= 1.0.0
329346 , pretty < 1.2
@@ -341,7 +358,7 @@ Library
341358 , vector < 0.13
342359 , vector-binary-instances < 0.3
343360 , zip-archive > 0.2.3.5 && < 0.5
344− , fsnotify >= 0.2 && < 2.2
361+ , fsnotify >= 0.2 && < 0.4
345362 , async < 2.3
346363
347364 if !impl(ghc >= 8.0)
@@ -459,4 +476,3 @@ Executable idris-codegen-node
459476 Default-Language: Haskell2010
460477 ghc-prof-options: -auto-all -caf-all
461478 ghc-options: -threaded -rtsopts -funbox-strict-fields
462−
libs/base/Control/Isomorphism.idr+20−23
@@ -17,21 +17,22 @@ record Iso a b where
1717
1818-- Isomorphism properties
1919
20−||| Isomorphism is Reflexive
20+||| Isomorphism is reflexive
2121isoRefl : Iso a a
22−isoRefl = MkIso id id (\x => Refl) (\x => Refl)
22+isoRefl = MkIso id id (\_ => Refl) (\_ => Refl)
2323
2424||| Isomorphism is transitive
2525isoTrans : Iso a b -> Iso b c -> Iso a c
2626isoTrans (MkIso to from toFrom fromTo) (MkIso to' from' toFrom' fromTo') =
27− MkIso (\x => to' (to x))
28− (\y => from (from' y))
29− (\y => (to' (to (from (from' y)))) ={ cong (toFrom (from' y)) }=
30− (to' (from' y)) ={ toFrom' y }=
31− y QED)
32− (\x => (from (from' (to' (to x)))) ={ cong (fromTo' (to x)) }=
33− (from (to x)) ={ fromTo x }=
34− x QED)
27+ MkIso xto xfrom xtoFrom xfromTo where
28+ xto : a -> c
29+ xto = to' . to
30+ xfrom : c -> a
31+ xfrom = from . from'
32+ xtoFrom : (z : c) -> xto (xfrom z) = z
33+ xtoFrom z = rewrite toFrom $ from' z in toFrom' z
34+ xfromTo : (x : a) -> xfrom (xto x) = x
35+ xfromTo x = rewrite fromTo' (to x) in fromTo x
3536
3637Category Iso where
3738 id = isoRefl
@@ -99,8 +100,7 @@ eitherBotRight = isoTrans eitherComm eitherBotLeft
99100
100101||| Isomorphism is a congruence with regards to disjunction
101102eitherCong : Iso a a' -> Iso b b' -> Iso (Either a b) (Either a' b')
102−eitherCong {a = a} {a' = a'} {b = b} {b' = b'}
103− (MkIso to from toFrom fromTo)
103+eitherCong (MkIso to from toFrom fromTo)
104104 (MkIso to' from' toFrom' fromTo') =
105105 MkIso (eitherMap to to') (eitherMap from from') ok1 ok2
106106 where eitherMap : (c -> c') -> (d -> d') -> Either c d -> Either c' d'
@@ -143,9 +143,7 @@ pairAssoc = MkIso to from ok1 ok2
143143
144144||| Conjunction with truth is a no-op
145145pairUnitRight : Iso (a, ()) a
146−pairUnitRight = MkIso fst (\x => (x, ())) (\x => Refl) ok
147− where ok : (x : (a, ())) -> (fst x, ()) = x
148− ok (x, ()) = Refl
146+pairUnitRight = MkIso fst (\x => (x, ())) (\_ => Refl) (\(_, ()) => Refl)
149147
150148||| Conjunction with truth is a no-op
151149pairUnitLeft : Iso ((), a) a
@@ -161,8 +159,7 @@ pairBotRight = isoTrans pairComm pairBotLeft
161159
162160||| Isomorphism is a congruence with regards to conjunction
163161pairCong : Iso a a' -> Iso b b' -> Iso (a, b) (a', b')
164−pairCong {a = a} {a' = a'} {b = b} {b' = b'}
165− (MkIso to from toFrom fromTo)
162+pairCong (MkIso to from toFrom fromTo)
166163 (MkIso to' from' toFrom' fromTo') =
167164 MkIso to'' from'' iso1 iso2
168165 where to'' : (a, b) -> (a', b')
@@ -205,7 +202,7 @@ distribLeft = MkIso to from toFrom fromTo
205202
206203||| Products distribute over sums
207204distribRight : Iso (a, Either b c) (Either (a, b) (a, c))
208−distribRight {a} {b} {c} = (pairComm `isoTrans` distribLeft) `isoTrans` eitherCong pairComm pairComm
205+distribRight = (pairComm `isoTrans` distribLeft) `isoTrans` eitherCong pairComm pairComm
209206
210207
211208-- Enable preorder reasoning syntax over isomorphisms
@@ -222,7 +219,7 @@ step a iso1 iso2 = isoTrans iso1 iso2
222219-- Isomorphisms over Maybe
223220||| Isomorphism is a congruence with respect to Maybe
224221maybeCong : Iso a b -> Iso (Maybe a) (Maybe b)
225−maybeCong {a} {b} (MkIso to from toFrom fromTo) = MkIso (map to) (map from) ok1 ok2
222+maybeCong (MkIso to from toFrom fromTo) = MkIso (map to) (map from) ok1 ok2
226223 where ok1 : (y : Maybe b) -> map to (map from y) = y
227224 ok1 Nothing = Refl
228225 ok1 (Just x) = (Just (to (from x))) ={ cong (toFrom x) }= (Just x) QED
@@ -253,7 +250,7 @@ maybeVoidUnit = (Maybe Void) ={ maybeEither }=
253250 () QED
254251
255252eitherMaybeLeftMaybe : Iso (Either (Maybe a) b) (Maybe (Either a b))
256−eitherMaybeLeftMaybe {a} {b} =
253+eitherMaybeLeftMaybe =
257254 (Either (Maybe a) b) ={ eitherCongLeft maybeEither }=
258255 (Either (Either a ()) b) ={ eitherAssoc }=
259256 (Either a (Either () b)) ={ eitherCongRight eitherComm }=
@@ -263,7 +260,7 @@ eitherMaybeLeftMaybe {a} {b} =
263260
264261
265262eitherMaybeRightMaybe : Iso (Either a (Maybe b)) (Maybe (Either a b))
266−eitherMaybeRightMaybe {a} {b} =
263+eitherMaybeRightMaybe =
267264 (Either a (Maybe b)) ={ eitherComm }=
268265 (Either (Maybe b) a) ={ eitherMaybeLeftMaybe }=
269266 (Maybe (Either b a)) ={ maybeCong eitherComm }=
@@ -288,8 +285,8 @@ maybeIsoS = MkIso forth back fb bf
288285 fb (FS x) = Refl
289286
290287finZeroBot : Iso (Fin 0) Void
291−finZeroBot = MkIso (\x => void (uninhabited x))
292− (\x => void x)
288+finZeroBot = MkIso (void . uninhabited)
289+ void
293290 (\x => void x)
294291 (\x => void (uninhabited x))
295292
libs/contrib/Control/Algebra/Laws.idr+128−80
@@ -6,98 +6,146 @@ import Interfaces.Verified
66
77%access export
88
9−||| A prof that -0 = 0 in any verified group.
10−inverseNeutralIsNeutral : VerifiedGroup t => inverse (the t A.neutral) = A.neutral
9+||| -(-x) = x in any verified group.
10+inverseSquaredIsIdentity : VerifiedGroup t => (x : t) ->
11+ inverse (inverse x) = x
12+inverseSquaredIsIdentity x =
13+ let
14+ ix = inverse x
15+ iix = inverse ix
16+ in
17+ rewrite sym $ monoidNeutralIsNeutralR iix in
18+ rewrite sym $ groupInverseIsInverseL x in
19+ rewrite sym $ semigroupOpIsAssociative x ix iix in
20+ rewrite groupInverseIsInverseL ix in
21+ monoidNeutralIsNeutralL x
22+
23+||| -0 = 0 in any verified group.
24+inverseNeutralIsNeutral : VerifiedGroup t =>
25+ inverse (the t A.neutral) = A.neutral
1126inverseNeutralIsNeutral {t} =
12− let zero = the t neutral
13− step1 = cong {f = (<+> inverse zero)} (the (zero = zero) Refl)
14− step2 = replace {P = \x => zero <+> inverse zero = x} (groupInverseIsInverseL zero) step1
15− in
16− replace {P = \x => x = neutral} (monoidNeutralIsNeutralR $ inverse zero) step2
27+ let e = the t neutral in
28+ rewrite sym $ cong {f = inverse} (groupInverseIsInverseL e) in
29+ rewrite monoidNeutralIsNeutralR $ inverse e in
30+ inverseSquaredIsIdentity e
1731
18−||| A proof that -(-x) = x in any verified group.
19−inverseSquaredIsIdentity : VerifiedGroup t => (x : t) -> inverse (inverse x) = x
20−inverseSquaredIsIdentity {t} x =
21− let zero = the t neutral
22− step1 = cong {f = (x <+>)} (groupInverseIsInverseL (inverse x))
23− step2 = replace {P = \r => r = x <+> neutral} (semigroupOpIsAssociative x (inverse x) (inverse $ inverse x)) step1
24− step3 = replace {P = \r => r <+> inverse (inverse x) = x <+> neutral} (groupInverseIsInverseL x) step2
25− step4 = replace {P = \r => r = x <+> neutral} (monoidNeutralIsNeutralR (inverse $ inverse x)) step3
26− in
27− replace {P = \r => inverse (inverse x) = r} (monoidNeutralIsNeutralL x) step4
32+||| -(x + y) = -y + -x in any verified group.
33+inverseOfSum : VerifiedGroup t => (l, r : t) ->
34+ inverse (l <+> r) = inverse r <+> inverse l
35+inverseOfSum {t} l r =
36+ let
37+ e = the t neutral
38+ il = inverse l
39+ ir = inverse r
40+ sum = l <+> r
41+ ilr = inverse sum
42+ iril = ir <+> il
43+ ile = il <+> e
44+ in
45+ -- expand
46+ rewrite sym $ monoidNeutralIsNeutralR ilr in
47+ rewrite sym $ groupInverseIsInverseR r in
48+ rewrite sym $ monoidNeutralIsNeutralL ir in
49+ rewrite sym $ groupInverseIsInverseR l in
50+ -- shuffle
51+ rewrite semigroupOpIsAssociative ir il l in
52+ rewrite sym $ semigroupOpIsAssociative iril l r in
53+ rewrite sym $ semigroupOpIsAssociative iril sum ilr in
54+ -- contract
55+ rewrite sym $ monoidNeutralIsNeutralL il in
56+ rewrite groupInverseIsInverseL sum in
57+ rewrite sym $ semigroupOpIsAssociative (ir <+> ile) l ile in
58+ rewrite semigroupOpIsAssociative l il e in
59+ rewrite groupInverseIsInverseL l in
60+ rewrite monoidNeutralIsNeutralL e in
61+ Refl
2862
29−||| A proof that -(x + y) = -x - y in any verified abelian group.
30−inverseDistributesOverGroupOp : VerifiedAbelianGroup t => (l, r : t) -> inverse (l <+> r) = inverse l <+> inverse r
31−inverseDistributesOverGroupOp {t} l r =
32− let step1 = replace {P = \x => x = neutral} (sym $ groupInverseIsInverseL (l <+> r)) $ the (the t neutral = neutral) Refl
33− step2 = cong {f = ((inverse r) <+>) . ((inverse l) <+>)} step1
34− step3 = replace {P = \x => inverse r <+> (inverse l <+> (l <+> r <+> inverse (l <+> r))) = inverse r <+> x} (monoidNeutralIsNeutralL (inverse l)) step2
35− step4 = replace {P = \x => x = inverse r <+> inverse l} (semigroupOpIsAssociative (inverse r) (inverse l) (l <+> r <+> inverse (l <+> r))) step3
36− step5 = replace {P = \x => x = inverse r <+> inverse l} (semigroupOpIsAssociative (inverse r <+> inverse l) (l <+> r) (inverse (l <+> r))) step4
37− step6 = replace {P = \x => x <+> inverse (l <+> r) = inverse r <+> inverse l} (semigroupOpIsAssociative (inverse r <+> inverse l) l r) step5
38− step7 = replace {P = \x => x <+> r <+> inverse (l <+> r) = inverse r <+> inverse l} (sym $ semigroupOpIsAssociative (inverse r) (inverse l) l) step6
39− step8 = replace {P = \x => inverse r <+> x <+> r <+> inverse (l <+> r) = inverse r <+> inverse l} (groupInverseIsInverseR l) step7
40− step9 = replace {P = \x => x <+> r <+> inverse (l <+> r) = inverse r <+> inverse l} (monoidNeutralIsNeutralL (inverse r)) step8
41− step10 = replace {P = \x => x <+> inverse (l <+> r) = inverse r <+> inverse l} (groupInverseIsInverseR r) step9
42− step11 = replace {P = \x => x = inverse r <+> inverse l} (monoidNeutralIsNeutralR (inverse (l <+> r))) step10
43− in
44− replace {P = \x => inverse (l <+> r) = x} (abelianGroupOpIsCommutative (inverse r) (inverse l)) step11
63+||| -(x + y) = -x + -y in any verified abelian group.
64+inverseDistributesOverGroupOp : VerifiedAbelianGroup t => (l, r : t) ->
65+ inverse (l <+> r) = inverse l <+> inverse r
66+inverseDistributesOverGroupOp l r =
67+ rewrite abelianGroupOpIsCommutative (inverse l) (inverse r) in
68+ inverseOfSum l r
4569
46−||| A proof that anything multiplied by zero yields zero back.
47−multNeutralAbsorbingL : VerifiedRingWithUnity t => (r : t) -> A.neutral <.> r = A.neutral
48−multNeutralAbsorbingL r =
49− let step1 = the (unity <.> r = r) (ringWithUnityIsUnityR r)
50− step2 = replace {P = \x => x <.> r = r} (sym $ monoidNeutralIsNeutralR unity) step1
51− step3 = replace {P = \x => x = r} (ringOpIsDistributiveR neutral unity r) step2
52− step4 = replace {P = \x => neutral <.> r <+> x = r} (ringWithUnityIsUnityR r) step3
53− step5 = cong {f = \x => x <+> inverse r} step4
54− step6 = replace {P = \x => x = r <+> inverse r} (sym $ semigroupOpIsAssociative (neutral <.> r) r (inverse r)) step5
55− step7 = replace {P = \x => neutral <.> r <+> x = x} (groupInverseIsInverseL r) step6
56− in
57− replace {P = \x => x = neutral} (monoidNeutralIsNeutralL (neutral <.> r)) step7
70+||| Anything multiplied by zero yields zero back in a verified ring.
71+multNeutralAbsorbingL : VerifiedRing t => (r : t) ->
72+ A.neutral <.> r = A.neutral
73+multNeutralAbsorbingL {t} r =
74+ let
75+ e = the t neutral
76+ ir = inverse r
77+ exr = e <.> r
78+ iexr = inverse exr
79+ in
80+ rewrite sym $ monoidNeutralIsNeutralR exr in
81+ rewrite sym $ groupInverseIsInverseR exr in
82+ rewrite sym $ semigroupOpIsAssociative iexr exr ((iexr <+> exr) <.> r) in
83+ rewrite groupInverseIsInverseR exr in
84+ rewrite sym $ ringOpIsDistributiveR e e r in
85+ rewrite monoidNeutralIsNeutralR e in
86+ groupInverseIsInverseR exr
5887
59−||| A proof that anything multiplied by zero yields zero back.
60−multNeutralAbsorbingR : VerifiedRingWithUnity t => (l : t) -> l <.> A.neutral = A.neutral
61−multNeutralAbsorbingR l =
62− let step1 = the (l <.> unity = l) (ringWithUnityIsUnityL l)
63− step2 = replace {P = \x => l <.> x = l} (sym $ monoidNeutralIsNeutralR unity) step1
64− step3 = replace {P = \x => x = l} (ringOpIsDistributiveL l neutral unity) step2
65− step4 = replace {P = \x => l <.> neutral <+> x = l} (ringWithUnityIsUnityL l) step3
66− step5 = cong {f = \x => x <+> inverse l} step4
67− step6 = replace {P = \x => x = l <+> inverse l} (sym $ semigroupOpIsAssociative (l <.> neutral) l (inverse l)) step5
68− step7 = replace {P = \x => l <.> neutral <+> x = x} (groupInverseIsInverseL l) step6
69− in
70− replace {P = \x => x = neutral} (monoidNeutralIsNeutralL (l <.> neutral)) step7
88+||| Anything multiplied by zero yields zero back in a verified ring.
89+multNeutralAbsorbingR : VerifiedRing t => (l : t) ->
90+ l <.> A.neutral = A.neutral
91+multNeutralAbsorbingR {t} l =
92+ let
93+ e = the t neutral
94+ il = inverse l
95+ lxe = l <.> e
96+ ilxe = inverse lxe
97+ in
98+ rewrite sym $ monoidNeutralIsNeutralL lxe in
99+ rewrite sym $ groupInverseIsInverseL lxe in
100+ rewrite semigroupOpIsAssociative (l <.> (lxe <+> ilxe)) lxe ilxe in
101+ rewrite groupInverseIsInverseL lxe in
102+ rewrite sym $ ringOpIsDistributiveL l e e in
103+ rewrite monoidNeutralIsNeutralL e in
104+ groupInverseIsInverseL lxe
71105
72−||| A proof that inverse operator can be extracted before multiplication
106+||| Inverse operator can be extracted before multiplication.
73107||| (-x)y = -(xy)
74−multInverseInversesL : VerifiedRingWithUnity t => (l, r : t) -> inverse l <.> r = inverse (l <.> r)
108+multInverseInversesL : VerifiedRing t => (l, r : t) ->
109+ inverse l <.> r = inverse (l <.> r)
75110multInverseInversesL l r =
76− let step1 = replace {P = \x => x <.> r = neutral} (sym $ groupInverseIsInverseL l) (multNeutralAbsorbingL r)
77− step2 = replace {P = \x => x = neutral} (ringOpIsDistributiveR l (inverse l) r) step1
78− step3 = cong {f = ((inverse (l <.> r)) <+>)} step2
79− step4 = replace {P = \x => inverse (l <.> r) <+> (l <.> r <+> inverse l <.> r) = x} (monoidNeutralIsNeutralL (inverse (l <.> r))) step3
80− step5 = replace {P = \x => x = inverse (l <.> r)} (semigroupOpIsAssociative (inverse (l <.> r)) (l <.> r) (inverse l <.> r)) step4
81− step6 = replace {P = \x => x <+> inverse l <.> r = inverse (l <.> r)} (groupInverseIsInverseR (l <.> r)) step5
82− in
83− replace {P = \x => x = inverse (l <.> r)} (monoidNeutralIsNeutralR (inverse l <.> r)) step6
111+ let
112+ il = inverse l
113+ lxr = l <.> r
114+ ilxr = il <.> r
115+ i_lxr = inverse lxr
116+ in
117+ rewrite sym $ monoidNeutralIsNeutralR ilxr in
118+ rewrite sym $ groupInverseIsInverseR lxr in
119+ rewrite sym $ semigroupOpIsAssociative i_lxr lxr ilxr in
120+ rewrite sym $ ringOpIsDistributiveR l il r in
121+ rewrite groupInverseIsInverseL l in
122+ rewrite multNeutralAbsorbingL r in
123+ monoidNeutralIsNeutralL i_lxr
84124
85−||| A proof that inverse operator can be extracted before multiplication
125+||| Inverse operator can be extracted before multiplication.
86126||| x(-y) = -(xy)
87−multInverseInversesR : VerifiedRingWithUnity t => (l, r : t) -> l <.> inverse r = inverse (l <.> r)
127+multInverseInversesR : VerifiedRing t => (l, r : t) ->
128+ l <.> inverse r = inverse (l <.> r)
88129multInverseInversesR l r =
89− let step1 = replace {P = \x => l <.> x = neutral} (sym $ groupInverseIsInverseL r) (multNeutralAbsorbingR l)
90− step2 = replace {P = \x => x = neutral} (ringOpIsDistributiveL l r (inverse r)) step1
91− step3 = cong {f = ((inverse (l <.> r)) <+>)} step2
92− step4 = replace {P = \x => inverse (l <.> r) <+> (l <.> r <+> l <.> inverse r) = x} (monoidNeutralIsNeutralL (inverse (l <.> r))) step3
93− step5 = replace {P = \x => x = inverse (l <.> r)} (semigroupOpIsAssociative (inverse (l <.> r)) (l <.> r) (l <.> inverse r)) step4
94− step6 = replace {P = \x => x <+> l <.> inverse r = inverse (l <.> r)} (groupInverseIsInverseR (l <.> r)) step5
95− in
96− replace {P = \x => x = inverse (l <.> r)} (monoidNeutralIsNeutralR (l <.> inverse r)) step6
130+ let
131+ ir = inverse r
132+ lxr = l <.> r
133+ lxir = l <.> ir
134+ ilxr = inverse lxr
135+ in
136+ rewrite sym $ monoidNeutralIsNeutralL lxir in
137+ rewrite sym $ groupInverseIsInverseL lxr in
138+ rewrite semigroupOpIsAssociative lxir lxr ilxr in
139+ rewrite sym $ ringOpIsDistributiveL l ir r in
140+ rewrite groupInverseIsInverseR r in
141+ rewrite multNeutralAbsorbingR l in
142+ monoidNeutralIsNeutralR ilxr
97143
98−||| A proof that multiplication of inverses is the same as multiplication of original
99−||| elements. (-x)(-y) = xy
100−multNegativeByNegativeIsPositive : VerifiedRingWithUnity t => (l, r : t) -> inverse l <.> inverse r = l <.> r
144+||| Multiplication of inverses is the same as multiplication of
145+||| original elements.
146+||| (-x)(-y) = xy
147+multNegativeByNegativeIsPositive : VerifiedRing t => (l, r : t) ->
148+ inverse l <.> inverse r = l <.> r
101149multNegativeByNegativeIsPositive l r =
102150 rewrite multInverseInversesR (inverse l) r in
103151 rewrite sym $ multInverseInversesL (inverse l) r in
libs/contrib/Data/List/Extra.idrdeleted−46
@@ -1,46 +0,0 @@
1−module Data.List.Extra
2−
3−%default total
4−%access export
5−
6−||| The final segment of the accumulator is the final segment of the result.
7−reverseOntoAcc : (xs, ys, zs : List a) ->
8− reverseOnto (ys ++ zs) xs = (reverseOnto ys xs) ++ zs
9−reverseOntoAcc [] _ _ = Refl
10−reverseOntoAcc (x :: xs) (ys) (zs) = reverseOntoAcc xs (x :: ys) zs
11−
12−||| Serves as a specification for reverseOnto.
13−reverseOntoSpec : (xs, ys : List a) -> reverseOnto xs ys = reverse ys ++ xs
14−reverseOntoSpec xs ys = reverseOntoAcc ys [] xs
15−
16−||| The reverse of an empty list is an empty list. Together with reverseCons,
17−||| serves as a specification for reverse.
18−reverseNil : reverse [] = []
19−reverseNil = Refl
20−
21−||| The reverse of a cons is the reverse of the tail followed by the head.
22−||| Together with reverseNil serves as a specification for reverse.
23−reverseCons : (x : a) -> (xs : List a) -> reverse (x::xs) = reverse xs ++ [x]
24−reverseCons x xs = reverseOntoSpec [x] xs
25−
26−||| Reversing an append is appending reversals backwards.
27−reverseAppend : (xs, ys : List a) ->
28− reverse (xs ++ ys) = reverse ys ++ reverse xs
29−reverseAppend [] ys = sym (appendNilRightNeutral (reverse ys))
30−reverseAppend (x :: xs) ys =
31− rewrite reverseCons x (xs ++ ys) in
32− rewrite reverseAppend xs ys in
33− rewrite reverseCons x xs in
34− sym $ appendAssociative (reverse ys) (reverse xs) [x]
35−
36−||| Reversing a singleton list is a no-op.
37−reverseSingletonId : (x : a) -> reverse [x] = [x]
38−reverseSingletonId _ = Refl
39−
40−||| Reversing a reverse gives the original.
41−reverseReverseId : (xs : List a) -> reverse (reverse xs) = xs
42−reverseReverseId [] = Refl
43−reverseReverseId (x :: xs) =
44− rewrite reverseCons x xs in
45− rewrite reverseAppend (reverse xs) [x] in
46− cong $ reverseReverseId xs
libs/contrib/Data/List/Reverse.idrnew file+99
@@ -0,0 +1,99 @@
1+||| Properties of the reverse function.
2+module Data.List.Reverse
3+
4+%default total
5+%access export
6+
7+||| The final segment of the accumulator is the final segment of the result.
8+reverseOntoAcc : (xs, ys, zs : List a) ->
9+ reverseOnto (ys ++ zs) xs = (reverseOnto ys xs) ++ zs
10+reverseOntoAcc [] _ _ = Refl
11+reverseOntoAcc (x :: xs) (ys) (zs) = reverseOntoAcc xs (x :: ys) zs
12+
13+||| Serves as a specification for reverseOnto.
14+reverseOntoSpec : (xs, ys : List a) -> reverseOnto xs ys = reverse ys ++ xs
15+reverseOntoSpec xs ys = reverseOntoAcc ys [] xs
16+
17+||| The reverse of an empty list is an empty list. Together with reverseCons,
18+||| serves as a specification for reverse.
19+reverseNil : reverse [] = []
20+reverseNil = Refl
21+
22+||| The reverse of a cons is the reverse of the tail followed by the head.
23+||| Together with reverseNil serves as a specification for reverse.
24+reverseCons : (x : a) -> (xs : List a) -> reverse (x::xs) = reverse xs ++ [x]
25+reverseCons x xs = reverseOntoSpec [x] xs
26+
27+||| Reversing an append is appending reversals backwards.
28+reverseAppend : (xs, ys : List a) ->
29+ reverse (xs ++ ys) = reverse ys ++ reverse xs
30+reverseAppend [] ys = sym (appendNilRightNeutral (reverse ys))
31+reverseAppend (x :: xs) ys =
32+ rewrite reverseCons x (xs ++ ys) in
33+ rewrite reverseAppend xs ys in
34+ rewrite reverseCons x xs in
35+ sym $ appendAssociative (reverse ys) (reverse xs) [x]
36+
37+||| A recursive definition of reverse.
38+reverseRec : List a -> List a
39+reverseRec [] = []
40+reverseRec (x :: xs) = reverseRec xs ++ [x]
41+
42+||| The iterative and recursive defintions of reverse are the same.
43+reverseEquiv : (xs : List a) -> reverseRec xs = reverse xs
44+reverseEquiv [] = Refl
45+reverseEquiv (x :: xs) =
46+ rewrite reverseEquiv xs in
47+ rewrite reverseAppend [x] xs in
48+ Refl
49+
50+||| Reversing a singleton list is a no-op.
51+reverseSingletonId : (x : a) -> reverse [x] = [x]
52+reverseSingletonId _ = Refl
53+
54+||| Reversing a reverse gives the original.
55+reverseReverseId : (xs : List a) -> reverse (reverse xs) = xs
56+reverseReverseId [] = Refl
57+reverseReverseId (x :: xs) =
58+ rewrite reverseCons x xs in
59+ rewrite reverseAppend (reverse xs) [x] in
60+ cong $ reverseReverseId xs
61+
62+||| Reversing onto preserves list length.
63+reverseOntoLength : (xs, acc : List a) ->
64+ length $ reverseOnto acc xs = length acc + length xs
65+reverseOntoLength [] acc = rewrite plusZeroRightNeutral (length acc) in Refl
66+reverseOntoLength (x :: xs) acc =
67+ rewrite reverseOntoLength xs (x :: acc) in
68+ plusSuccRightSucc (length acc) (length xs)
69+
70+||| Reversing preserves list length.
71+reverseLength : (xs : List a) -> length $ reverse xs = length xs
72+reverseLength xs = reverseOntoLength xs []
73+
74+||| Equal reversed lists are equal.
75+reverseEqual : (xs, ys : List a) -> reverse xs = reverse ys -> xs = ys
76+reverseEqual xs ys prf =
77+ rewrite sym $ reverseReverseId xs in
78+ rewrite prf in
79+ reverseReverseId ys
80+
81+||| Do geese see God?
82+data Palindrome : (xs : List a) -> Type where
83+ Empty : Palindrome []
84+ Single : Palindrome [_]
85+ Multi : Palindrome xs -> Palindrome $ [x] ++ xs ++ [x]
86+
87+||| A Palindrome reversed is itself.
88+palindromeReverse : (xs : List a) -> Palindrome xs -> reverse xs = xs
89+palindromeReverse [] Empty = Refl
90+palindromeReverse [_] Single = Refl
91+palindromeReverse ([x] ++ ys ++ [x]) (Multi pf) =
92+ rewrite reverseAppend ([x] ++ ys) [x] in
93+ rewrite reverseAppend [x] ys in
94+ rewrite palindromeReverse ys pf in
95+ Refl
96+
97+||| Only Palindromes are equal to their own reverse.
98+postulate -- This is a tough one. Any takers?
99+reversePalindrome : (xs : List a) -> reverse xs = xs -> Palindrome xs
libs/contrib/Data/Nat/Fact.idrnew file+56
@@ -0,0 +1,56 @@
1+||| Properties of factorial functions.
2+module Data.Nat.Fact
3+
4+%access public export
5+
6+%default total
7+
8+||| Recursive definition of factorial.
9+factRec : Nat -> Nat
10+factRec Z = 1
11+factRec (S k) = (S k) * factRec k
12+
13+||| Tail-recursive accumulator for factItr.
14+factAcc : Nat -> Nat -> Nat
15+factAcc Z acc = acc
16+factAcc (S k) acc = factAcc k $ (S k) * acc
17+
18+||| Iterative definition of factorial.
19+factItr : Nat -> Nat
20+factItr n = factAcc n 1
21+
22+----------------------------------------
23+
24+||| Multiplicand-shuffling lemma.
25+multShuffle : (a, b, c : Nat) -> a * (b * c) = b * (a * c)
26+multShuffle a b c =
27+ rewrite multAssociative a b c in
28+ rewrite multCommutative a b in
29+ sym $ multAssociative b a c
30+
31+||| Multiplication of the accumulator.
32+factAccMult : (a, b, c : Nat) ->
33+ a * factAcc b c = factAcc b (a * c)
34+factAccMult _ Z _ = Refl
35+factAccMult a (S k) c =
36+ rewrite factAccMult a k (S k * c) in
37+ rewrite multShuffle a (S k) c in
38+ Refl
39+
40+||| Addition of accumulators.
41+factAccPlus : (a, b, c : Nat) ->
42+ factAcc a b + factAcc a c = factAcc a (b + c)
43+factAccPlus Z _ _ = Refl
44+factAccPlus (S k) b c =
45+ rewrite factAccPlus k (S k * b) (S k * c) in
46+ rewrite sym $ multDistributesOverPlusRight (S k) b c in
47+ Refl
48+
49+||| The recursive and iterative definitions are the equivalent.
50+factRecItr : (n : Nat) -> factRec n = factItr n
51+factRecItr Z = Refl
52+factRecItr (S k) =
53+ rewrite factRecItr k in
54+ rewrite factAccMult k k 1 in
55+ rewrite multOneRightNeutral k in
56+ factAccPlus k 1 k
libs/contrib/Data/Nat/Parity.idr+123−69
@@ -2,18 +2,9 @@ module Data.Nat.Parity
22
33%access public export
44
5−--------------------------------------------------------------------------------
6−-- Parity
7−--------------------------------------------------------------------------------
5+----------------------------------------
86
9−mutual
10− even : Nat -> Bool
11− even Z = True
12− even (S k) = odd k
13−
14− odd : Nat -> Bool
15− odd Z = False
16− odd (S k) = even k
7+-- Type-level, constructive definitions of parity.
178
189||| A nat is Even when it is twice some other nat.
1910Even : Nat -> Type
@@ -23,6 +14,8 @@ Even n = (half : Nat ** n = half * 2)
2314Odd : Nat -> Type
2415Odd n = (haf : Nat ** n = S $ haf * 2)
2516
17+----------------------------------------
18+
2619||| Two more than an Even is Even.
2720add2Even : Even n -> Even (2 + n)
2821add2Even (half ** pf) = (S half ** cong {f = (+) 2} pf)
@@ -52,20 +45,73 @@ succDoublePredPred {k = S _} prf = cong {f = Nat.pred} prf
5245predEvenOdd : Even (S n) -> Odd n
5346predEvenOdd (half ** pf) = (pred half ** succDoublePredPred pf)
5447
48+----------------------------------------
49+
50+-- Boolean definitions of parity.
51+
52+mutual
53+ even : Nat -> Bool
54+ even Z = True
55+ even (S k) = odd k
56+
57+ odd : Nat -> Bool
58+ odd Z = False
59+ odd (S k) = even k
60+
61+----------------------------------------
62+
63+-- The boolean and type-level definitions are equivalent in the sense
64+-- that a proof of one can be gotten from a proof of the other.
65+
66+mutual
67+ ||| Evens are even.
68+ evenEven : Even n -> even n = True
69+ evenEven {n = Z} _ = Refl
70+ evenEven {n = S _} pf = oddOdd $ predEvenOdd pf
71+
72+ ||| Odds are odd.
73+ oddOdd : Odd n -> odd n = True
74+ oddOdd {n = Z} (_ ** pf) = absurd pf
75+ oddOdd {n = S _} pf = evenEven $ predOddEven pf
76+
77+mutual
78+ ||| If it's even, it's Even.
79+ evenEvenConverse : even n = True -> Even n
80+ evenEvenConverse {n = Z} prf = (0 ** Refl)
81+ evenEvenConverse {n = S k} prf =
82+ let (haf ** pf) = oddOddConverse prf in
83+ (S haf ** cong pf)
84+
85+ ||| If it's odd, it's Odd
86+ oddOddConverse : odd n = True -> Odd n
87+ oddOddConverse {n = Z} prf = absurd prf
88+ oddOddConverse {n = S k} prf =
89+ let (half ** pf) = evenEvenConverse prf in
90+ (half ** cong pf)
91+
92+----------------------------------------
93+
94+||| Every nat is either even or odd.
95+evenorodd : (n : Nat) -> Either (even n = True) (odd n = True)
96+evenorodd Z = Left Refl
97+evenorodd (S k) = case evenorodd k of
98+ Left l => Right l
99+ Right r => Left r
100+
55101||| Every nat is either Even or Odd.
56102evenOrOdd : (n : Nat) -> Either (Even n) (Odd n)
57−evenOrOdd Z = Left (0 ** Refl)
58−evenOrOdd (S k) = case evenOrOdd k of
59− Left (half ** pf) => Right (half ** cong {f = S} pf)
60− Right (haf ** pf) => Left (S haf ** cong {f = S} pf)
103+evenOrOdd n = case evenorodd n of
104+ Left e => Left $ evenEvenConverse e
105+ Right o => Right $ oddOddConverse o
106+
107+||| No nat is both even and odd.
108+notevenandodd : even n = True -> odd n = True -> Void
109+notevenandodd {n = Z} en on = absurd on
110+notevenandodd {n = S _} en on = notevenandodd on en
61111
62112||| No nat is both Even and Odd.
63113notEvenAndOdd : Even n -> Odd n -> Void
64−notEvenAndOdd {n = Z} _ (_ ** odd) = absurd odd
65−notEvenAndOdd {n = (S k)} (half ** even) (haf ** odd) =
66− notEvenAndOdd {n = k}
67− (haf ** cong {f = Nat.pred} odd)
68− (pred half ** succDoublePredPred even)
114+notEvenAndOdd en on = notevenandodd (evenEven en) (oddOdd on)
69115
70116||| Evenness is decidable.
71117evenDec : (n : Nat) -> Dec $ Even n
@@ -79,42 +125,46 @@ oddDec n = case evenOrOdd n of
79125 Left even => No $ notEvenAndOdd even
80126 Right odd => Yes odd
81127
82−mutual
83− ||| Evens are even.
84− evenEven : Even n -> even n = True
85− evenEven {n = Z} _ = Refl
86− evenEven {n = S _} pf = oddOdd $ predEvenOdd pf
128+----------------------------------------
87129
88− ||| Odds are odd.
89− oddOdd : Odd n -> odd n = True
90− oddOdd {n = Z} (_ ** pf) = absurd pf
91− oddOdd {n = S _} pf = evenEven $ predOddEven pf
130+||| An Odd is the successor of an Even.
131+oddSuccEven : Odd n -> (m : Nat ** (n = S m, Even m))
132+oddSuccEven (haf ** pf) = (haf * 2 ** (pf, (haf ** Refl)))
92133
93134||| Even plus Even is Even.
94135evenPlusEven : Even j -> Even k -> Even (j + k)
95136evenPlusEven (half_j ** pf_j) (half_k ** pf_k) =
96− rewrite pf_j in
97− rewrite pf_k in
98− (half_j + half_k **
137+ (half_j + half_k **
138+ rewrite pf_j in
139+ rewrite pf_k in
99140 sym $ multDistributesOverPlusLeft half_j half_k 2)
100141
101−||| Odd plus Odd is Even.
102−oddPlusOdd : Odd j -> Odd k -> Even (j + k)
103−oddPlusOdd (haf_j ** pf_j) (haf_k ** pf_k) =
104− rewrite pf_j in
105− rewrite pf_k in
106− rewrite sym $ plusSuccRightSucc (haf_j * 2) (haf_k * 2) in
107− rewrite sym $ multDistributesOverPlusLeft haf_j haf_k 2 in
108− (S (haf_j + haf_k) ** Refl)
142+||| Odd plus Even is Odd.
143+oddPlusEven : Odd j -> Even k -> Odd (j + k)
144+oddPlusEven oj ek =
145+ let
146+ (i ** (ipj, ei)) = oddSuccEven oj
147+ (half_ik ** eik) = evenPlusEven ei ek
148+ in
149+ (half_ik **
150+ rewrite ipj in
151+ cong {f = S} eik)
109152
110153||| Even plus Odd is Odd.
111154evenPlusOdd : Even j -> Odd k -> Odd (j + k)
112−evenPlusOdd (half_j ** pf_j) (haf_k ** pf_k) =
113− rewrite pf_j in
114− rewrite pf_k in
115− rewrite sym $ plusSuccRightSucc (half_j * 2) (haf_k * 2) in
116− rewrite sym $ multDistributesOverPlusLeft half_j haf_k 2 in
117− (half_j + haf_k ** Refl)
155+evenPlusOdd {j} {k} ej ok = rewrite plusCommutative j k in oddPlusEven ok ej
156+
157+||| Odd plus Odd is Even.
158+oddPlusOdd : Odd j -> Odd k -> Even (j + k)
159+oddPlusOdd oj ok =
160+ let
161+ (i ** (ipj, ei)) = oddSuccEven oj
162+ (haf_ik ** oik) = evenPlusOdd ei ok
163+ in
164+ (S haf_ik **
165+ rewrite ipj in
166+ rewrite oik in
167+ Refl)
118168
119169||| A helper fact.
120170multShuffle : (a, b, c : Nat) ->
@@ -129,35 +179,39 @@ multShuffle a b c =
129179||| Even times Even is Even.
130180evenMultEven : Even j -> Even k -> Even (j * k)
131181evenMultEven (half_j ** pf_j) (half_k ** pf_k) =
132− rewrite pf_j in
133− rewrite pf_k in
134− (half_j * half_k * 2 **
182+ (half_j * half_k * 2 **
183+ rewrite pf_j in
184+ rewrite pf_k in
135185 multShuffle half_j half_k 2)
136186
187+||| Odd times Even is Even.
188+oddMultEven : Odd j -> Even k -> Even (j * k)
189+oddMultEven oj (half_k ** pf_k) =
190+ let
191+ (i ** (ipj, ei)) = oddSuccEven oj
192+ (half_ik ** oik) = evenMultEven ei (half_k ** pf_k)
193+ in
194+ (half_k + half_ik **
195+ rewrite multDistributesOverPlusLeft half_k half_ik 2 in
196+ rewrite ipj in
197+ rewrite oik in
198+ rewrite pf_k in
199+ Refl)
200+
137201||| Even times Odd is Even.
138202evenMultOdd : Even j -> Odd k -> Even (j * k)
139−evenMultOdd (half_j ** pf_j) (haf_k ** pf_k) =
140− let half = half_j * haf_k * 2 in
141− rewrite pf_j in
142− rewrite pf_k in
143− rewrite multRightSuccPlus (half_j * 2) (haf_k * 2) in
144− rewrite multShuffle half_j haf_k 2 in
145− (half_j + half **
146− sym $ multDistributesOverPlusLeft half_j half 2)
203+evenMultOdd {j} {k} ej ok = rewrite multCommutative j k in oddMultEven ok ej
147204
148205||| Odd times Odd is Odd.
149206oddMultOdd : Odd j -> Odd k -> Odd (j * k)
150−oddMultOdd (haf_j ** pf_j) (haf_k ** pf_k) =
207+oddMultOdd oj (haf_k ** pf_k) =
151208 let
152− haf = haf_j * haf_k * 2
153− rem = haf_j + haf_k
209+ (i ** (ipj, ei)) = oddSuccEven oj
210+ (half_ik ** eik) = evenMultOdd ei (haf_k ** pf_k)
154211 in
155− rewrite pf_j in
156− rewrite pf_k in
157− rewrite multRightSuccPlus (haf_j * 2) (haf_k * 2) in
158− rewrite multShuffle haf_j haf_k 2 in
159− rewrite plusAssociative (haf_k * 2) (haf_j * 2) (haf * 2) in
160− rewrite sym $ multDistributesOverPlusLeft haf_k haf_j 2 in
161− rewrite plusCommutative haf_k haf_j in
162− rewrite sym $ multDistributesOverPlusLeft rem haf 2 in
163− (rem + haf ** Refl)
212+ (haf_k + half_ik **
213+ rewrite multDistributesOverPlusLeft haf_k half_ik 2 in
214+ rewrite ipj in
215+ rewrite eik in
216+ rewrite pf_k in
217+ Refl)
libs/contrib/contrib.ipkg+1−1
@@ -43,7 +43,7 @@ modules = CFFI
4343 , Data.Heap
4444 , Data.IOArray
4545 , Data.List.Zipper
46− , Data.List.Extra
46+ , Data.List.Reverse
4747
4848 , Data.Matrix
4949 , Data.Matrix.Algebraic
libs/prelude/Prelude/File.idr+3−2
@@ -150,7 +150,8 @@ do_getFileAccessTime h =
150150private
151151do_getFileModifiedTime : Ptr -> IO Integer
152152do_getFileModifiedTime h =
153− do MkRaw i <- foreign FFI_C "fileModifiedTime" (Ptr -> IO (Raw Integer)) h
153+ do vm <- getMyVM
154+ MkRaw i <- foreign FFI_C "fileModifiedTime" (Ptr -> Ptr -> IO (Raw Integer)) vm h
154155 pure i
155156
156157private
@@ -175,7 +176,7 @@ export
175176fileModifiedTime : File -> IO (Either FileError Integer)
176177fileModifiedTime (FHandle h)
177178 = do s <- do_getFileModifiedTime h
178− if (s < 0)
179+ if (s == -1)
179180 then Left <$> getFileError
180181 else pure (Right s)
181182
libs/prelude/Prelude/Nat.idr+32−61
@@ -512,19 +512,18 @@ plusLeftCancel (S left) right right' p =
512512
513513total plusRightCancel : (left : Nat) -> (left' : Nat) -> (right : Nat) ->
514514 (p : left + right = left' + right) -> left = left'
515−plusRightCancel left left' Z p = rewrite sym (plusZeroRightNeutral left) in
516− rewrite sym (plusZeroRightNeutral left') in
517− p
518−plusRightCancel left left' (S right) p =
519− plusRightCancel left left' right
520− (succInjective _ _ (rewrite plusSuccRightSucc left right in
521− rewrite plusSuccRightSucc left' right in p))
515+plusRightCancel left left' right p =
516+ plusLeftCancel right left left' $
517+ rewrite plusCommutative right left in
518+ rewrite plusCommutative right left' in
519+ p
522520
523521total plusLeftLeftRightZero : (left : Nat) -> (right : Nat) ->
524522 (p : left + right = left) -> right = Z
525−plusLeftLeftRightZero Z right p = p
526−plusLeftLeftRightZero (S left) right p =
527− plusLeftLeftRightZero left right (succInjective _ _ p)
523+plusLeftLeftRightZero left right p =
524+ plusLeftCancel left right Z $
525+ rewrite plusZeroRightNeutral left in
526+ p
528527
529528-- Mult
530529total multZeroLeftZero : (right : Nat) -> Z * right = Z
@@ -558,27 +557,21 @@ multCommutative (S left) right =
558557 rewrite multRightSuccPlus right left in
559558 Refl
560559
561−total multDistributesOverPlusRight : (left : Nat) -> (centre : Nat) -> (right : Nat) ->
562− left * (centre + right) = (left * centre) + (left * right)
563−multDistributesOverPlusRight Z centre right = Refl
564−multDistributesOverPlusRight (S left) centre right =
565− let inductiveHypothesis = multDistributesOverPlusRight left centre right in
566− rewrite inductiveHypothesis in
567− rewrite plusAssociative (plus centre (mult left centre)) right (mult left right) in
568− rewrite sym (plusAssociative centre (mult left centre) right) in
569− rewrite plusCommutative (mult left centre) right in
570− rewrite plusAssociative centre right (mult left centre) in
571− rewrite plusAssociative (plus centre right) (mult left centre) (mult left right) in
572− Refl
573−
574560total multDistributesOverPlusLeft : (left : Nat) -> (centre : Nat) -> (right : Nat) ->
575561 (left + centre) * right = (left * right) + (centre * right)
576−multDistributesOverPlusLeft Z centre right = Refl
577−multDistributesOverPlusLeft (S left) centre right =
578− let inductiveHypothesis = multDistributesOverPlusLeft left centre right in
579− rewrite inductiveHypothesis in
580− rewrite plusAssociative right (mult left right) (mult centre right) in
581− Refl
562+multDistributesOverPlusLeft Z centre right = Refl
563+multDistributesOverPlusLeft (S k) centre right =
564+ rewrite multDistributesOverPlusLeft k centre right in
565+ rewrite plusAssociative right (k * right) (centre * right) in
566+ Refl
567+
568+total multDistributesOverPlusRight : (left : Nat) -> (centre : Nat) -> (right : Nat) ->
569+ left * (centre + right) = (left * centre) + (left * right)
570+multDistributesOverPlusRight left centre right =
571+ rewrite multCommutative left (centre + right) in
572+ rewrite multCommutative left centre in
573+ rewrite multCommutative left right in
574+ multDistributesOverPlusLeft centre right left
582575
583576total multAssociative : (left : Nat) -> (centre : Nat) -> (right : Nat) ->
584577 left * (centre * right) = (left * centre) * right
@@ -590,18 +583,10 @@ multAssociative (S left) centre right =
590583 Refl
591584
592585total multOneLeftNeutral : (right : Nat) -> 1 * right = right
593−multOneLeftNeutral Z = Refl
594−multOneLeftNeutral (S right) =
595− let inductiveHypothesis = multOneLeftNeutral right in
596− rewrite inductiveHypothesis in
597− Refl
586+multOneLeftNeutral right = plusZeroRightNeutral right
598587
599588total multOneRightNeutral : (left : Nat) -> left * 1 = left
600−multOneRightNeutral Z = Refl
601−multOneRightNeutral (S left) =
602− let inductiveHypothesis = multOneRightNeutral left in
603− rewrite inductiveHypothesis in
604− Refl
589+multOneRightNeutral left = rewrite multCommutative left 1 in multOneLeftNeutral left
605590
606591-- Minus
607592total minusSuccSucc : (left : Nat) -> (right : Nat) ->
@@ -689,10 +674,7 @@ total powerZeroOne : (base : Nat) -> power base 0 = S Z
689674powerZeroOne base = Refl
690675
691676total powerOneNeutral : (base : Nat) -> power base 1 = base
692−powerOneNeutral Z = Refl
693−powerOneNeutral (S base) =
694− let inductiveHypothesis = powerOneNeutral base in
695− rewrite inductiveHypothesis in Refl
677+powerOneNeutral base = rewrite multCommutative base 1 in multOneLeftNeutral base
696678
697679total powerOneSuccOne : (exp : Nat) -> power 1 exp = S Z
698680powerOneSuccOne Z = Refl
@@ -701,8 +683,7 @@ powerOneSuccOne (S exp) =
701683 rewrite inductiveHypothesis in Refl
702684
703685total powerSuccSuccMult : (base : Nat) -> power base 2 = mult base base
704−powerSuccSuccMult Z = Refl
705−powerSuccSuccMult (S base) = rewrite multOneRightNeutral base in Refl
686+powerSuccSuccMult base = rewrite multOneRightNeutral base in Refl
706687
707688total powerPowerMultPower : (base : Nat) -> (exp : Nat) -> (exp' : Nat) ->
708689 power (power base exp) exp' = power base (exp * exp')
@@ -796,34 +777,24 @@ minimumIdempotent Z = Refl
796777minimumIdempotent (S k) = cong (minimumIdempotent k)
797778
798779total minimumZeroZeroRight : (right : Nat) -> minimum 0 right = Z
799−minimumZeroZeroRight Z = Refl
800−minimumZeroZeroRight (S right) = minimumZeroZeroRight right
780+minimumZeroZeroRight right = Refl
801781
802782total minimumZeroZeroLeft : (left : Nat) -> minimum left 0 = Z
803−minimumZeroZeroLeft Z = Refl
804−minimumZeroZeroLeft (S left) = Refl
783+minimumZeroZeroLeft left = rewrite minimumCommutative left 0 in Refl
805784
806785total minimumSuccSucc : (left : Nat) -> (right : Nat) ->
807786 minimum (S left) (S right) = S (minimum left right)
808−minimumSuccSucc Z Z = Refl
809−minimumSuccSucc (S left) Z = Refl
810−minimumSuccSucc Z (S right) = Refl
811−minimumSuccSucc (S left) (S right) = Refl
787+minimumSuccSucc left right = Refl
812788
813789total maximumZeroNRight : (right : Nat) -> maximum Z right = right
814−maximumZeroNRight Z = Refl
815−maximumZeroNRight (S right) = Refl
790+maximumZeroNRight right = Refl
816791
817792total maximumZeroNLeft : (left : Nat) -> maximum left Z = left
818−maximumZeroNLeft Z = Refl
819−maximumZeroNLeft (S left) = Refl
793+maximumZeroNLeft left = rewrite maximumCommutative left Z in Refl
820794
821795total maximumSuccSucc : (left : Nat) -> (right : Nat) ->
822796 S (maximum left right) = maximum (S left) (S right)
823−maximumSuccSucc Z Z = Refl
824−maximumSuccSucc (S left) Z = Refl
825−maximumSuccSucc Z (S right) = Refl
826−maximumSuccSucc (S left) (S right) = Refl
797+maximumSuccSucc left right = Refl
827798
828799total sucMaxL : (l : Nat) -> maximum (S l) l = (S l)
829800sucMaxL Z = Refl
rts/idris_bitstring.c−2
@@ -1,5 +1,3 @@
1−#include <assert.h>
2−
31#include "idris_rts.h"
42
53VAL idris_b8const(VM *vm, uint8_t a) {
rts/idris_rts.c−10
@@ -1158,16 +1158,6 @@ void idris_disableBuffering(void) {
11581158 setvbuf(stdout, NULL, _IONBF, 0);
11591159}
11601160
1161−#ifndef SEL4
1162−int idris_usleep(int usec) {
1163− struct timespec t;
1164− t.tv_sec = usec / 1000000;
1165− t.tv_nsec = (usec % 1000000) * 1000;
1166−
1167− return nanosleep(&t, NULL);
1168−}
1169−#endif // SEL4
1170−
11711161void stackOverflow(void) {
11721162 fprintf(stderr, "Stack overflow");
11731163 exit(-1);
rts/idris_rts.h−4
@@ -507,10 +507,6 @@ const char *idris_getArg(int i);
507507// disable stdin/stdout buffering
508508void idris_disableBuffering(void);
509509
510−#ifndef SEL4
511−int idris_usleep(int usec);
512−#endif // SEL4
513−
514510// Handle stack overflow.
515511// Just reports an error and exits.
516512
rts/idris_stdfgn.c+12−2
@@ -74,13 +74,13 @@ VAL fileAccessTime(void* h) {
7474 }
7575}
7676
77−VAL fileModifiedTime(void* h) {
77+VAL fileModifiedTime(VM* vm, void* h) {
7878 FILE* f = (FILE*)h;
7979 int fd = fileno(f);
8080
8181 struct stat buf;
8282 if (fstat(fd, &buf) == 0) {
83− return MKBIGI(buf.st_mtime);
83+ return MKBIGUI(vm, buf.st_mtime);
8484 } else {
8585 return MKBIGI(-1);
8686 }
@@ -228,6 +228,16 @@ VAL idris_clock(VM* vm) {
228228 return result;
229229}
230230
231+#ifndef SEL4
232+int idris_usleep(int usec) {
233+ struct timespec t;
234+ t.tv_sec = usec / 1000000;
235+ t.tv_nsec = (usec % 1000000) * 1000;
236+
237+ return nanosleep(&t, NULL);
238+}
239+#endif // SEL4
240+
231241VAL idris_mkFileError(VM* vm) {
232242 VAL result;
233243 switch(errno) {
rts/idris_stdfgn.h+4−1
@@ -18,7 +18,7 @@ int fileSize(void* h);
1818
1919// Return a negative number if not a file (e.g. directory or device)
2020VAL fileAccessTime(void* h);
21−VAL fileModifiedTime(void* h);
21+VAL fileModifiedTime(VM* vm, void* h);
2222VAL fileStatusTime(void* h);
2323
2424void* idris_dirOpen(char* dname);
@@ -54,6 +54,9 @@ char* getEnvPair(int i);
5454
5555VAL idris_time();
5656VAL idris_clock(VM* vm);
57+#ifndef SEL4
58+int idris_usleep(int usec);
59+#endif // SEL4
5760
5861void idris_forceGC();
5962
rts/idris_utf8.c−1
@@ -1,5 +1,4 @@
11#include "idris_utf8.h"
2−#include <stdio.h>
32#include <string.h>
43#include <stdlib.h>
54
src/Idris/Core/TT.hs+1−1
@@ -325,7 +325,7 @@ bindTC x k = case x of
325325instance Monad TC where
326326 return x = OK x
327327 x >>= k = bindTC x k
328−#if !(MIN_VERSION_base(4,12,0))
328+#if !(MIN_VERSION_base(4,13,0))
329329 fail = Fail.fail
330330#endif
331331
src/Idris/Parser/Stack.hs+14−1
@@ -5,7 +5,7 @@ Description : Idris parser stack and its primitives.
55License : BSD3
66Maintainer : The Idris Community.
77-}
8−{-# LANGUAGE ConstraintKinds, FlexibleContexts, MultiParamTypeClasses #-}
8+{-# LANGUAGE CPP, ConstraintKinds, FlexibleContexts, MultiParamTypeClasses #-}
99module Idris.Parser.Stack
1010 ( -- * Parsing
1111 Parser(..)
@@ -77,11 +77,20 @@ parseErrorOffset = P.errorOffset . parseError
7777instance Message ParseError where
7878 messageExtent err = sourcePositionFC pos
7979 where
80+#if MIN_VERSION_megaparsec(8,0,0)
81+ P.PosState {P.pstateSourcePos = pos} =
82+ P.reachOffsetNoLine (parseErrorOffset err) (parseErrorPosState err)
83+#else
8084 (pos, _) = P.reachOffsetNoLine (parseErrorOffset err) (parseErrorPosState err)
85+#endif
8186 messageText = PP.text . init . P.parseErrorTextPretty . parseError
8287 messageSource err = Just sline
8388 where
89+#if MIN_VERSION_megaparsec(8,0,0)
90+ (sline, _) = P.reachOffset (parseErrorOffset err) (parseErrorPosState err)
91+#else
8492 (_, sline, _) = P.reachOffset (parseErrorOffset err) (parseErrorPosState err)
93+#endif
8594
8695-- | A fully formatted parse error, with caret and bar, etc.
8796prettyError :: ParseError -> String
@@ -89,7 +98,11 @@ prettyError = P.errorBundlePretty . unParseError
8998
9099{- * Mark and restore -}
91100
101+#if MIN_VERSION_megaparsec(8,0,0)
102+type Mark = P.State String Void
103+#else
92104type Mark = P.State String
105+#endif
93106
94107-- | Retrieve the parser state so we can restart from this point later.
95108mark :: Parsing m => m Mark
stack-11.22.yamlnew file+21
@@ -0,0 +1,21 @@
1+#recheck extra-deps next on resolver or cabal file change
2+resolver: lts-11.22
3+
4+extra-deps:
5+- cheapskate-0.1.1.2
6+- megaparsec-7.0.5
7+- Cabal-2.4.1.0
8+- network-3.1.1.1
9+- parser-combinators-1.0.0
10+
11+flags:
12+ idris:
13+ FFI: true
14+ GMP: true
15+
16+ghc-options:
17+ idris: -fwarn-unused-imports -fwarn-unused-binds
18+
19+nix:
20+ enable: false
21+ shell-file: stack-shell.nix
stack-12.26.yamlnew file+20
@@ -0,0 +1,20 @@
1+#recheck extra-deps next on resolver or cabal file change
2+resolver: lts-12.26
3+
4+extra-deps:
5+- cheapskate-0.1.1.2
6+- megaparsec-7.0.5
7+- Cabal-2.4.1.0
8+- network-3.1.1.1
9+
10+flags:
11+ idris:
12+ FFI: true
13+ GMP: true
14+
15+ghc-options:
16+ idris: -fwarn-unused-imports -fwarn-unused-binds
17+
18+nix:
19+ enable: false
20+ shell-file: stack-shell.nix
stack-15.3.yamlnew file+17
@@ -0,0 +1,17 @@
1+#recheck extra-deps next on resolver or cabal file change
2+resolver: lts-15.3
3+
4+extra-deps:
5+- cheapskate-0.1.1.2
6+
7+flags:
8+ idris:
9+ FFI: true
10+ GMP: true
11+
12+ghc-options:
13+ idris: -fwarn-unused-imports -fwarn-unused-binds
14+
15+nix:
16+ enable: false
17+ shell-file: stack-shell.nix
stack-15.4.yamlnew file+17
@@ -0,0 +1,17 @@
1+#recheck extra-deps next on resolver or cabal file change
2+resolver: lts-15.4
3+
4+extra-deps:
5+- cheapskate-0.1.1.2
6+
7+flags:
8+ idris:
9+ FFI: true
10+ GMP: true
11+
12+ghc-options:
13+ idris: -fwarn-unused-imports -fwarn-unused-binds
14+
15+nix:
16+ enable: false
17+ shell-file: stack-shell.nix
stack-alt.yamldeleted−25
@@ -1,25 +0,0 @@
1−#recheck extra-deps next on resolver or cabal file change
2−resolver: lts-11.4
3−
4−packages:
5− - location: .
6−
7−extra-deps:
8− - network-2.8.0.0@sha256:aae171e6c6028a7791dbe4de5b9d2da398056359e3cc7927465ffa3cdae1aa0b
9− - Cabal-2.2.0.1@sha256:2a80d8fb655474f0eaeb20434c47f64f84e6302e55973056f00df8ca050b9683
10− - megaparsec-7.0.4
11− - parser-combinators-1.0.0
12− - zip-archive-0.3.3@sha256:47cf2d66cc8e237f7226837758e1b041e24048ef3820d3d10276c500edb921bf
13− - containers-0.5.11.0@sha256:28ad7337057442f75bc689315ab4ec7bdf5e6b2c39668f306672cecd82c02798
14−
15−flags:
16− idris:
17− FFI: true
18− GMP: true
19−
20−ghc-options:
21− idris: -fwarn-unused-imports -fwarn-unused-binds
22−
23−nix:
24− enable: false
25− shell-file: stack-shell.nix
stack.yamlmode 100644 → 120000+1−24
@@ -1,24 +0,0 @@
1−#recheck extra-deps next on resolver or cabal file change
2−resolver: lts-13.21
3−
4−extra-deps:
5− - network-2.8.0.0@sha256:aae171e6c6028a7791dbe4de5b9d2da398056359e3cc7927465ffa3cdae1aa0b
6− - megaparsec-7.0.4
7− - parser-combinators-1.0.0
8− - zip-archive-0.3.3@sha256:47cf2d66cc8e237f7226837758e1b041e24048ef3820d3d10276c500edb921bf
9− - containers-0.5.11.0@sha256:28ad7337057442f75bc689315ab4ec7bdf5e6b2c39668f306672cecd82c02798
10− - tasty-rerun-1.1.14@sha256:ba9c19a281535bea566e1044bc02c36ef17abcb310af4b6a149ec11780c7ce35
11− - binary-0.8.7.0@sha256:ae3e6cca723ac55c54bbb3fa771bcf18142bc727afd57818e66d6ee6c8044f12
12− - text-1.2.4.0@sha256:8c24450feb8e3bbb7ea3e17af24ef57e85db077c4bf53e5bcc345b283d1b1d5b
13−
14−flags:
15− idris:
16− FFI: true
17− GMP: true
18−
19−ghc-options:
20− idris: -fwarn-unused-imports -fwarn-unused-binds
21−
22−nix:
23− enable: false
24− shell-file: stack-shell.nix
@@ -0,0 +1 @@
1+stack-15.4.yaml