on 55df0fb help sign in
.travis.yml+12−39
since splitsnapshots
unifiedsplit
@@ -8,7 +8,7 @@ env:
8
8
9matrix:
9matrix:
10 include:
10 include:
11− - env: CABALVER="2.4" GHCVER="8.6.5" STACKVER="15.4" STYLISH=YES
11+ - env: CABALVER="2.4" GHCVER="8.6.5" STACKVER="14.15" STYLISH=YES
12 addons: {apt: {packages: [cabal-install-2.4,ghc-8.6.5,hscolour], sources: [hvr-ghc]}}
12 addons: {apt: {packages: [cabal-install-2.4,ghc-8.6.5,hscolour], sources: [hvr-ghc]}}
13 - env: CABALVER="2.4" GHCVER="8.2.2" TESTS="lib_doc doc"
13 - env: CABALVER="2.4" GHCVER="8.2.2" TESTS="lib_doc doc"
14 compiler: ": #GHC 8.2.2"
14 compiler: ": #GHC 8.2.2"
@@ -19,26 +19,16 @@ matrix:
19 - env: CABALVER="2.4" GHCVER="8.2.2" TESTS="test_c"
19 - env: CABALVER="2.4" GHCVER="8.2.2" TESTS="test_c"
20 compiler: ": #GHC 8.2.2"
20 compiler: ": #GHC 8.2.2"
21 addons: {apt: {packages: [cabal-install-2.4,ghc-8.2.2,cppcheck,hscolour], sources: [hvr-ghc]}}
21 addons: {apt: {packages: [cabal-install-2.4,ghc-8.2.2,cppcheck,hscolour], sources: [hvr-ghc]}}
22− - env: CABALVER="2.4" GHCVER="8.4.4" TESTS="lib_doc doc"
22+
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"
23+# - env: CABALVER="3.0" GHCVER="8.8.1" TESTS="lib_doc doc"
32− compiler: ": #GHC 8.8.3"
24+# compiler: ": #GHC 8.8.1"
33− addons: {apt: {packages: [cabal-install-3.0,ghc-8.8.3,cppcheck,hscolour], sources: [hvr-ghc]}}
25+# addons: {apt: {packages: [cabal-install-3.0,ghc-8.8.1,cppcheck,hscolour], sources: [hvr-ghc]}}
34− - env: CABALVER="3.0" GHCVER="8.8.3" TESTS="test_js"
26+# - env: CABALVER="3.0" GHCVER="8.8.1" TESTS="test_js"
35− compiler: ": #GHC 8.8.3"
27+# compiler: ": #GHC 8.8.1"
36− addons: {apt: {packages: [cabal-install-3.0,ghc-8.8.3,cppcheck,hscolour], sources: [hvr-ghc]}}
28+# addons: {apt: {packages: [cabal-install-3.0,ghc-8.8.1,cppcheck,hscolour], sources: [hvr-ghc]}}
37− - env: CABALVER="3.0" GHCVER="8.8.3" TESTS="test_c"
29+# - env: CABALVER="3.0" GHCVER="8.8.1" TESTS="test_c"
38− compiler: ": #GHC 8.8.3"
30+# compiler: ": #GHC 8.8.1"
39− addons: {apt: {packages: [cabal-install-3.0,ghc-8.8.3,cppcheck,hscolour], sources: [hvr-ghc]}}
31+# addons: {apt: {packages: [cabal-install-3.0,ghc-8.8.1,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]}}
42 fast-finish: true
32 fast-finish: true
43
33
44cache:
34cache:
@@ -57,7 +47,7 @@ before_install:
57 - unset CC
47 - unset CC
58 - if [[ $TRAVIS_OS_NAME == 'linux' ]];
48 - if [[ $TRAVIS_OS_NAME == 'linux' ]];
59 then
49 then
60− export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$HOME/.cabal/bin:$HOME/opt/scheme/bin/:$PATH;
50+ export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$HOME/.cabal/bin:$PATH;
61 export SED=sed;
51 export SED=sed;
62 export ZCAT=zcat;
52 export ZCAT=zcat;
63 fi
53 fi
@@ -72,21 +62,6 @@ before_install:
72 export PKG_CONFIG_PATH=/usr/local/opt/libffi/lib/pkgconfig:$PKG_CONFIG_PATH;
62 export PKG_CONFIG_PATH=/usr/local/opt/libffi/lib/pkgconfig:$PKG_CONFIG_PATH;
73 fi
63 fi
74 - if [ -n "$STYLISH" ]; then ./stylize.sh; exit $?; fi
64 - 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
90
65
91install:
66install:
92 - which cabal
67 - which cabal
@@ -128,7 +103,6 @@ install:
128 cp -a $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin installplan.txt $HOME/.cabsnap/;
103 cp -a $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin installplan.txt $HOME/.cabsnap/;
129 fi
104 fi
130
105
131−
132before_script:
106before_script:
133 - ORIGINAL_DIR=$(pwd)
107 - ORIGINAL_DIR=$(pwd)
134 - cabal v1-sdist
108 - cabal v1-sdist
@@ -136,7 +110,6 @@ before_script:
136 - tar -xf ${ORIGINAL_DIR}/dist/${PKGNAME}*.tar.gz
110 - tar -xf ${ORIGINAL_DIR}/dist/${PKGNAME}*.tar.gz
137 - cd ${PKGNAME}*
111 - cd ${PKGNAME}*
138script:
112script:
139− - export LD_PRELOAD=/opt/ghc/${GHCVER}/lib/ghc-${GHCVER}/rts/libffi.so.7
140###
113###
141 - echo 'Configure...' && echo -en 'travis_fold:start:script.configure\\r'
114 - echo 'Configure...' && echo -en 'travis_fold:start:script.configure\\r'
142 - cabal v1-configure -f FFI -f CI --enable-tests
115 - cabal v1-configure -f FFI -f CI --enable-tests
INSTALL.md+2−11
@@ -130,8 +130,7 @@ PKG_CONFIG_PATH=/usr/local/opt/libffi/lib/pkgconfig stack build
130## Issue with GHC on Ubuntu/Fedora
130## Issue with GHC on Ubuntu/Fedora
131
131
132There is an upstream issue with GHC on some Ubuntu and Fedora machines.
132There 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 uses the version of libFFI shipped with GHC, instead of the system version.
133+The issue is that for GHC versions greater than 8.4.X linking to libFFI is broken.
134−
135See the following GHC issue page for more information:
134See the following GHC issue page for more information:
136
135
137 <https://gitlab.haskell.org/ghc/ghc/issues/15397>
136 <https://gitlab.haskell.org/ghc/ghc/issues/15397>
@@ -142,12 +141,4 @@ Specifically, one will see an error message along the lines of:
142
141
143> error while loading shared libraries: libffi.so.7: cannot open shared object file: No such file or directory
142> error while loading shared libraries: libffi.so.7: cannot open shared object file: No such file or directory
144
143
145−A workround for this bug is to override the used libffi version (this is what we use on CI):
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.
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,6 +44,3 @@ where some interesting projects are being hosted.
44
44
45For those interested in contributing to Idris directly we kindly ask that
45For those interested in contributing to Idris directly we kindly ask that
46prospective developers please consult the [Contributing Guide](CONTRIBUTING.md) first.
46prospective 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+1−2
@@ -251,7 +251,6 @@ latex_elements = {
251# Additional stuff for the LaTeX preamble.
251# Additional stuff for the LaTeX preamble.
252'preamble': r'''
252'preamble': r'''
253\usepackage{lmodern}
253\usepackage{lmodern}
254−\usepackage{textalpha}
255\usepackage[T1]{fontenc}
254\usepackage[T1]{fontenc}
256\usepackage[utf8x]{inputenc}
255\usepackage[utf8x]{inputenc}
257\usepackage{titlesec}
256\usepackage{titlesec}
@@ -301,7 +300,7 @@ latex_elements = {
301# (source start file, target name, title,
300# (source start file, target name, title,
302# author, documentclass [howto, manual, or own class]).
301# author, documentclass [howto, manual, or own class]).
303latex_documents = [
302latex_documents = [
304− # (master_doc, 'idris.tex', u'Documentation for the Idris Language', u'The Idris Community', 'report')
303+ ('index', 'idris-documentation-complete.tex', u'Documentation for the Idris Language', u'The Idris Community', 'report'),
305 ('tutorial/index', 'idris-tutorial.tex', u'The Idris Tutorial', u'The Idris Community', 'howto'),
304 ('tutorial/index', 'idris-tutorial.tex', u'The Idris Tutorial', u'The Idris Community', 'howto'),
306]
305]
307
306
docs/effects/introduction.rst+1−2
@@ -17,8 +17,7 @@ exceptions, and verified resource management.
17This tutorial assumes familiarity with pure programming in Idris,
17This tutorial assumes familiarity with pure programming in Idris,
18as described in Sections 1–6 of the main tutorial [1]_. The examples
18as described in Sections 1–6 of the main tutorial [1]_. The examples
19presented are tested with Idris and can be found in the
19presented are tested with Idris and can be found in the
20−examples directory of the Idris repository. The ``-p effects`` flag
20+examples directory of the Idris repository.
21−is needed when starting Idris.
22
21
23Consider, for example, the following introductory function which
22Consider, for example, the following introductory function which
24illustrates the kind of properties which can be expressed in the type
23illustrates 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.
25 - Lexer - This takes the input string and turns it into a list of Tokens.
25 - Lexer - This takes the input string and turns it into a list of Tokens.
26 - Parser - This takes the list of tokens and outputs the code.
26 - Parser - This takes the list of tokens and outputs the code.
27
27
28− - .. image:: ../image/parserTopLevel.png
28+.. image:: ../image/parserTopLevel.png
29− :width: 307px
29+ :width: 307px
30− :height: 76px
30+ :height: 76px
31− :alt: diagram illustrating these stages of lexer and parser
31+ :alt: diagram illustrating these stages of lexer and parser
32
32
33The advantage of using two stages, like this, is that things like whitespace and
33The advantage of using two stages, like this, is that things like whitespace and
34comments don't need to be considered in every parser rule.
34comments don't need to be considered in every parser rule.
35
35
36−The Idris parser library differs from Parsec in that you need to say, in 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
37+Recogniser whether a rule is guaranteed to consume input. This means that the
38Idris type system prevents the construction of recognisers/rules that can't
38Idris type system prevents the construction of recognisers/rules that can't
39consume the input.
39consume the input.
40
40
41The Lexer is similar but works at the level of characters rather than tokens, and
41The Lexer is similar but works at the level of characters rather than tokens, and
42−you need to provide a TokenMap which defines how to build a token from
42+you need to provide a TokenMap which says how to build a token representation from
43a string when a rule is matched.
43a string when a rule is matched.
44
44
45The following pages contain a tutorial for the :ref:`parserLibraryLexer` and a
45The following pages contain a tutorial for the :ref:`parserLibraryLexer` and a
docs/parserLibrary/lexer.rst+19−25
@@ -10,16 +10,13 @@ module:
10
10
11 lex : TokenMap a -> String -> (List (TokenData a), (Int, Int, String))
11 lex : TokenMap a -> String -> (List (TokenData a), (Int, Int, String))
12
12
13−.. list-table::
14−
15− * - This function takes a String and returns a list of tokens. With the
13+This function takes a String and returns a list of tokens. With the tokens we
16− tokens we have indexes back to the original string which can be used
14+have indexes back to the original string which can be used in error messages:
17− in error messages:
18
15
19− - .. image:: ../image/tokenise.png
16+.. image:: ../image/tokenise.png
20− :width: 330px
17+ :width: 330px
21− :height: 73px
18+ :height: 73px
22− :alt: diagram illustrating these stages of lexer
19+ :alt: diagram illustrating these stages of lexer
23
20
24TokenMap
21TokenMap
25--------
22--------
@@ -37,24 +34,21 @@ this information:
37 (Lexer, String -> tokenType)
34 (Lexer, String -> tokenType)
38
35
39So for each Lexer in the list, if a substring in the input matches, run
36So for each Lexer in the list, if a substring in the input matches, run
40−the associated function to produce a token of type ``tokenType``
37+the associated function to produce a token of type `tokenType`
41−
42−.. list-table::
43
38
44− * - from Text.Lexer.Core
39+from Text.Lexer.Core:
45− : https://github.com/idris-lang/Idris-dev/blob/master/libs/contrib/Text/Lexer/Core.idr
46
40
47− - .. code-block:: idris
41+.. code-block:: idris
48
42
49− TokenMap : (tokenType : Type) -> Type
43+ TokenMap : (tokenType : Type) -> Type
50− TokenMap tokenType = List (Lexer, String -> tokenType)
44+ TokenMap tokenType = List (Lexer, String -> tokenType)
51
45
52− * - We can create a tokenMap by using a function like this:
46+We can create a tokenMap by using a function like this:
53
47
54− - .. code-block:: idris
48+.. code-block:: idris
55
49
56− myTokenMap : TokenMap Token
50+ myTokenMap : TokenMap Token
57− myTokenMap = [(is 'a',CharLit)]
51+ myTokenMap = [(is 'a',CharLit)]
58
52
59Once we have a TokenMap we can use it to lex many strings.
53Once we have a TokenMap we can use it to lex many strings.
60
54
@@ -80,7 +74,7 @@ combined, for example,
80
74
81.. list-table::
75.. list-table::
82
76
83− * - ``<+>`` means sequence two recognisers. If either consumes a character,
77+ * - <+> means sequence two recognisers. If either consumes a character,
84 the sequence is guaranteed to consume a character.
78 the sequence is guaranteed to consume a character.
85
79
86 - .. code-block:: idris
80 - .. code-block:: idris
@@ -89,7 +83,7 @@ combined, for example,
89 SeqEat (Pred (\ARG => intToBool (prim__eqChar ARG 'a')))
83 SeqEat (Pred (\ARG => intToBool (prim__eqChar ARG 'a')))
90 (Delay (is 'b')) : Recognise True
84 (Delay (is 'b')) : Recognise True
91
85
92− * - ``<|>`` means if both consume, the combination is guaranteed
86+ * - <|> means if both consume, the combination is guaranteed
93 to consumer a character:
87 to consumer a character:
94
88
95 - .. code-block:: idris
89 - .. code-block:: idris
@@ -167,7 +161,7 @@ able to parse simple arithmetic expressions, like this:
167so we need:
161so we need:
168
162
169- Numbers (for now integer literals are good enough).
163- Numbers (for now integer literals are good enough).
170−- Some operators (for now ``+``, ``-`` and ``*`` will do.
164+- Some operators (for now '+', '-' and '*' will do.
171- Opening and closing Parentheses.
165- Opening and closing Parentheses.
172
166
173We can define these, as tokens, like this:
167We can define these, as tokens, like this:
@@ -184,7 +178,7 @@ We can define these, as tokens, like this:
184 | EndInput
178 | EndInput
185
179
186It may help with debugging and to implement error messages to
180It may help with debugging and to implement error messages to
187−implement ``show`` for these tokens:
181+implement 'show' for these tokens:
188
182
189.. code-block:: idris
183.. code-block:: idris
190
184
docs/parserLibrary/parser.rst+112−190
@@ -3,8 +3,8 @@
3Parser
3Parser
4======
4======
5
5
6−To run the parser we call ``parse``. This requires a grammar and the output
6+To run our parser we call 'parse'. This requires a Grammar and the output
7−from the lexer (which is a list of tokens).
7+from the lexer (a list of tokens).
8
8
9.. code-block:: idris
9.. code-block:: idris
10
10
@@ -18,13 +18,13 @@ If successful this returns 'Right' with a pair of
18
18
19otherwise it returns 'Left' with the error message.
19otherwise it returns 'Left' with the error message.
20
20
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
22'Grammar' data structure. This is a combinator structure, similar in principle
22'Grammar' data structure. This is a combinator structure, similar in principle
23to the recogniser combinator for the lexer, which was discussed on the
23to the recogniser combinator for the lexer, which was discussed on the
24previous page.
24previous page.
25
25
26−As with the Recogniser the ``Grammar`` type is dependent on a boolean 'consumes'
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
27+value which allows us to ensure that complicated Grammar structures will always
28consume input.
28consume input.
29
29
30.. code-block:: idris
30.. code-block:: idris
@@ -53,13 +53,13 @@ consume input.
53 Grammar tok c1 ty -> Grammar tok c2 ty ->
53 Grammar tok c1 ty -> Grammar tok c2 ty ->
54 Grammar tok (c1 && c2) ty
54 Grammar tok (c1 && c2) ty
55
55
56−So an example of a grammer type may look something like this:
56+So an example of a Grammer type may look something like this:
57−``Grammar (TokenData ExpressionToken) True Integer``.
57+'Grammar (TokenData ExpressionToken) True Integer'.
58+
58This is a complicated type name and a given parser will need to use it a lot.
59This is a complicated type name and a given parser will need to use it a lot.
59So to reduce the amount of typing we can use the following type synonym (similar
60So to reduce the amount of typing we can use the following type synonym (similar
60to what is done in Idris 2
61to what is done in Idris 2
61: https://github.com/edwinb/Idris2/blob/master/src/Parser/Support.idr
62: https://github.com/edwinb/Idris2/blob/master/src/Parser/Support.idr
62−)
63
63
64.. code-block:: idris
64.. code-block:: idris
65
65
@@ -71,12 +71,12 @@ Parser Example
71--------------
71--------------
72
72
73On the previous page we implemented a lexer to 'lex' a very simple expression, on
73On the previous page we implemented a lexer to 'lex' a very simple expression, on
74−this page we will go on to add a parser for this running example.
74+this page we will go on to implement a parser for this running example.
75
75
76.. list-table::
76.. list-table::
77
77
78− * - The syntax we are aiming at is something
78+ * - Expressed in Backus–Naur form (BNF) the syntax we are aiming at is something
79− like this (expressed in Backus–Naur form (BNF)):
79+ like this:
80 - .. code-block:: idris
80 - .. code-block:: idris
81
81
82 <expr> ::= <integer literal>
82 <expr> ::= <integer literal>
@@ -89,8 +89,8 @@ this page we will go on to add a parser for this running example.
89
89
90.. list-table::
90.. list-table::
91
91
92− * - To start, here is a grammar to parse an integer literal (that is, a
92+ * - To start, here is a Grammar to parse an integer literal (that is, a
93− sequence of numeric characters).
93+ sequence of numbers).
94
94
95 - .. code-block:: idris
95 - .. code-block:: idris
96
96
@@ -144,7 +144,7 @@ successful, this is because we are not specifically checking for end-of-file.
144
144
145.. list-table::
145.. list-table::
146
146
147− * - The ``intLiteral`` function above uses the ``terminal`` function to
147+ * - The 'intLiteral' function above uses the 'terminal' function to
148 construct the grammar
148 construct the grammar
149 - .. code-block:: idris
149 - .. code-block:: idris
150
150
@@ -174,10 +174,10 @@ Idris 2 uses a slightly different version which stores an error message like
174 OParen => Just 0
174 OParen => Just 0
175 _ => Nothing)
175 _ => Nothing)
176
176
177−Integer value is not really relevant for parenthesis so ``0`` (zero) is used as
177+Integer value is not really relevant for parenthesis so '0' is used as
178a default value.
178a default value.
179
179
180−As before, this can be tested with a function like this:
180+As before, we can test this out with a function like this:
181
181
182.. code-block:: idris
182.. code-block:: idris
183
183
@@ -202,10 +202,10 @@ error for anything else:
202 List (TokenData ExpressionToken))
202 List (TokenData ExpressionToken))
203
203
204Now we have two Grammars we can try combining them. The following test looks
204Now 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
205+for 'openParen' followed by 'intLiteral', the two Grammars are combined using
206−``<*>``. The ``map const`` part uses the integer value from the first.
206+'<*>'. The 'map const' part uses the integer value from the first.
207
207
208−The following test is looking for ``(`` followed by a number:
208+The following test is looking for '(' followed by a number:
209
209
210.. code-block:: idris
210.. code-block:: idris
211
211
@@ -213,8 +213,8 @@ The following test is looking for ``(`` followed by a number:
213 (Integer, List (TokenData ExpressionToken))
213 (Integer, List (TokenData ExpressionToken))
214 test3 s = parse (map const openParen <*> intLiteral) (fst (lex expressionTokens s))
214 test3 s = parse (map const openParen <*> intLiteral) (fst (lex expressionTokens s))
215
215
216−We can see below that ``(`` followed by a number is successfully parsed but, as
216+We can see below that '(' followed by a number is successfully parsed but other
217−required, other token lists are not:
217+token lists are not:
218
218
219.. code-block:: idris
219.. code-block:: idris
220
220
@@ -270,87 +270,21 @@ required, other token lists are not:
270 paren : Rule Integer -> Rule Integer
270 paren : Rule Integer -> Rule Integer
271 paren exp = openParen *> exp <* closeParen
271 paren exp = openParen *> exp <* closeParen
272
272
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
274value from the inner expression.
274value from the inner expression.
275
275
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−
340.. list-table::
276.. list-table::
341
277
342− * - Now for the operations, in this case: ``+``, ``-`` and ``*``.
278+ * - Now for the operations, in this case: '+', '-' and '*'.
343− The syntax we require for these infix operators
279+ The syntax we require is that operators like '+' are infix operators, which
344− would require recursive grammars like this:
280+ would require a definition like this:
345
281
346 - .. code-block:: idris
282 - .. code-block:: idris
347
283
348− expr = expr (op "+") expr
284+ expr = (add 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.
352
285
286+This is a potentially infinite structure which is not total.
353−In order to work up to this gradually lets start with prefix operators
287+In order to work up to this gradually I will start with prefix operators
354(sometimes known as Polish notation) then modify later for infix operators.
288(sometimes known as Polish notation) then modify later for infix operators.
355
289
356.. list-table::
290.. list-table::
@@ -361,7 +295,7 @@ In order to work up to this gradually lets start with prefix operators
361
295
362 expr = (add (op "+") expr expr)
296 expr = (add (op "+") expr expr)
363
297
364−where ``op`` is defined like this:
298+where 'op' is defined like this:
365
299
366.. code-block:: idris
300.. code-block:: idris
367
301
@@ -374,13 +308,7 @@ where ``op`` is defined like this:
374
308
375.. list-table::
309.. list-table::
376
310
377− * - and ``add`` is defined like this:
311+ * - 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.
384
312
385 - .. code-block:: idris
313 - .. code-block:: idris
386
314
@@ -394,37 +322,40 @@ where ``op`` is defined like this:
394 Grammar tok ((c1 || c2) || c3) Integer
322 Grammar tok ((c1 || c2) || c3) Integer
395 add x y z = map addInt (x *> y) <*> z
323 add x y z = map addInt (x *> y) <*> z
396
324
325+Where:
397
326
327+- x is the add operator.
328+- y is the first operand.
329+- z is the second operand.
398
330
399The resulting integer will be the sum of the two operands.
331The resulting integer will be the sum of the two operands.
400
332
401−.. list-table::
333+The other operators are defined in a similar way:
402
334
403− * - The other operators are defined in a similar way:
335+.. code-block:: idris
404
336
405− - .. code-block:: idris
337+ subInt : Integer -> Integer -> Integer
338+ subInt a b = a-b
406
339
407− subInt : Integer -> Integer -> Integer
340+ export
408− subInt a b = a-b
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
409
346
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
416
347
417− multInt : Integer -> Integer -> Integer
348+ multInt : Integer -> Integer -> Integer
418− multInt a b = a*b
349+ multInt a b = a*b
419
350
420− export
351+ export
421− mult : Grammar tok c1 Integer ->
352+ mult : Grammar tok c1 Integer ->
422− Grammar tok c2 Integer ->
353+ Grammar tok c2 Integer ->
423− Grammar tok c3 Integer ->
354+ Grammar tok c3 Integer ->
424− Grammar tok ((c1 || c2) || c3) Integer
355+ Grammar tok ((c1 || c2) || c3) Integer
425− mult x y z = map multInt (x *> y) <*> z
356+ mult x y z = map multInt (x *> y) <*> z
426
357
427−So the top level ``Grammar`` can now be defined as follows. Note that this is
358+So the top level Grammar can now be defined as follows. Note that this is
428partial as it is a potentially infinite structure and so not total.
359partial as it is a potentially infinite structure and so not total.
429
360
430.. code-block:: idris
361.. code-block:: idris
@@ -477,7 +408,7 @@ Then an invalid syntax:
477 List (TokenData ExpressionToken))
408 List (TokenData ExpressionToken))
478
409
479However if we try something that is invalid, but starts with a valid token,
410However if we try something that is invalid, but starts with a valid token,
480−then it will return ``Right`` (to indicate success)
411+then it will return 'Right' (to indicate success)
481
412
482.. code-block:: idris
413.. code-block:: idris
483
414
@@ -504,8 +435,8 @@ Infix Notation
504--------------
435--------------
505
436
506So far we have implemented a prefix notation for operators (like this:
437So far we have implemented a prefix notation for operators (like this:
507−``+ expr expr``) but the aim is to implemented an infix notation (like this:
438+'+ 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
439+'expr + expr'). To do this we must be able to deal with potentially
509infinite data structures (see Codata Types here :ref:`sect-typefuns`).
440infinite data structures (see Codata Types here :ref:`sect-typefuns`).
510
441
511First alter the grammar to have infix operations:
442First alter the grammar to have infix operations:
@@ -563,10 +494,10 @@ If we have a rule like this:
563
494
564 A -> (x<*>y) <|> (x<*>z)
495 A -> (x<*>y) <|> (x<*>z)
565
496
566−If ``x<*>y`` fails but ``x<*>z`` would succeed a problem is that, ``x<*>y`` has
497+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.
498+already consumed 'x', so now 'x<*>z' will fail.
568
499
569−so we could write code to backtrack. That is ``try`` ``x<*>y`` without consuming
500+so we could write code to backtrack. That is 'try' 'x<*>y' without consuming
570so that, if the first token succeeds but the following tokens fail, then the
501so that, if the first token succeeds but the following tokens fail, then the
571first tokens would not be consumed.
502first tokens would not be consumed.
572
503
@@ -593,64 +524,52 @@ That is we convert a general context-free grammar to a LL(1) grammar. Although
593not every context-free grammar can be converted to a LL(1) grammar.
524not every context-free grammar can be converted to a LL(1) grammar.
594
525
595This still does not solve the infinite recursion issue and there is another
526This still does not solve the infinite recursion issue and there is another
596−problem: the precedence of the operators ``+``, ``-`` and ``*`` is not explicit.
527+problem: the precedence of the operators +, - and * is not explicit.
597
528
598−.. list-table::
529+To resolve this we can alter the example like this:
599
530
600− * - To resolve this we can alter the example to have a BNF like this:
531+.. code-block:: idris
601− Where braces ``{ ... }`` mean the contents can occur 1 or more times.
602
532
603− - .. code-block:: idris
533+ paren : Rule Integer -> Rule Integer
534+ paren exp = openParen *> exp <* closeParen
535+
536+ addInt : Integer -> Integer -> Integer
537+ addInt a b = a+b
604
538
605− 'expression' ::= ('+'|'-') 'term' {('+'|'-') 'term'}
539+ subInt : Integer -> Integer -> Integer
540+ subInt a b = a-b
606
541
607− 'term' ::= 'factor' {'*' 'factor'}
542+ multInt : Integer -> Integer -> Integer
543+ multInt a b = a*b
608
544
609− 'factor' ::=
545+ partial
610− number
546+ expr : Rule Integer
611− | '(' 'expression' ')'
612
547
548+ partial
549+ exprAtom : Rule Integer
550+ exprAtom = intLiteral <|> (paren expr)
613
551
614−.. code-block:: idris
552+ partial
553+ expr1 : Rule Integer
554+ expr1 = map multInt exprAtom <*> ((op "*") *> exprAtom)
615
555
556+ partial
616− expr : Rule Integer
557+ exprMult : Rule Integer
558+ exprMult = expr1 <|> exprAtom
617
559
618− factor : Rule Integer
560+ partial
619− factor = intLiteral <|> do
620− openParen
621− r <- expr
622− closeParen
623− pure r
624−
625− term : Rule Integer
561+ expr2 : Rule Integer
626− term = map multInt factor <*> (
562+ expr2 = map addInt exprMult <*> ((op "+") *> exprMult)
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))
642
563
643− lft : (ParseError (TokenData ExpressionToken)) -> IO ()
564+ partial
644− lft (Error s lst) = putStrLn ("error:"++s)
565+ exprAdd : Rule Integer
566+ exprAdd = expr2 <|> exprMult
645
567
646− rht : (Integer, List (TokenData ExpressionToken)) -> IO ()
568+ partial
647− rht i = putStrLn ("right " ++ (show i))
569+ expr3 : Rule Integer
570+ expr3 = map subInt exprAdd <*> ((op "-") *> expr)
648
571
649− main : IO ()
572+ expr = expr3 <|> exprAdd
650− main = do
651− putStr "alg>"
652− x <- getLine
653− either lft rht (calc x) -- eliminator for Either
654
573
655As the following tests show, this now handles infix operators and precedence.
574As the following tests show, this now handles infix operators and precedence.
656
575
@@ -660,41 +579,44 @@ As the following tests show, this now handles infix operators and precedence.
660
579
661 - .. code-block:: idris
580 - .. code-block:: idris
662
581
663− *algebraREPL> :exec
582+ *parserExInfix> test "2*3"
664− alg>2*3
583+ Right (6,
665− right (6, [])
584+ []) : Either (ParseError (TokenData ExpressionToken))
585+ (Integer, List (TokenData ExpressionToken))
666
586
667 * - Check that atomic number literals work:
587 * - Check that atomic number literals work:
668
588
669 - .. code-block:: idris
589 - .. code-block:: idris
670
590
671− *algebraREPL> :exec
591+ *parserExInfix> test "2"
672− alg>2
592+ Right (2,
673− right (2, [])
593+ []) : Either (ParseError (TokenData ExpressionToken))
594+ (Integer, List (TokenData ExpressionToken))
674
595
675 * - Check that '*' has a higher precedence than '+'.
596 * - Check that '*' has a higher precedence than '+'.
676
597
677 - .. code-block:: idris
598 - .. code-block:: idris
678
599
679− *algebraREPL> :exec
600+ *parserExInfix> test "2+3*4"
680− alg>2+3*4
601+ Right (14,
681− right (14, [])
602+ []) : Either (ParseError (TokenData ExpressionToken))
603+ (Integer, List (TokenData ExpressionToken))
682
604
683 * - Also '*' has a higher precedence than '+' when the order is reversed.
605 * - Also '*' has a higher precedence than '+' when the order is reversed.
684
606
685 - .. code-block:: idris
607 - .. code-block:: idris
686
608
687− *algebraREPL> :exec
609+ *parserExInfix> test "3*4+2"
688− alg>3*4+2
610+ Right (14,
689− right (14, [])
611+ []) : Either (ParseError (TokenData ExpressionToken))
612+ (Integer, List (TokenData ExpressionToken))
690
613
691 * - Also precedence can be overridden by parenthesis.
614 * - Also precedence can be overridden by parenthesis.
692
615
693 - .. code-block:: idris
616 - .. code-block:: idris
694
617
695− *algebraREPL> :exec
618+ *parserExInfix> test "(2+3)*4"
696− alg>(2+3)*4
619+ Right (20,
697− right (20, [])
620+ []) : Either (ParseError (TokenData ExpressionToken))
621+ (Integer, List (TokenData ExpressionToken))
698
622
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+35−131
@@ -8,16 +8,14 @@ discussed how to handle whitespace and comments.
8
8
9In some grammars whitespace and comments would not be considered significant and
9In some grammars whitespace and comments would not be considered significant and
10so we might be tempted not to generate any tokens for them. However, in the
10so we might be tempted not to generate any tokens for them. However, in the
11−running example, we may want to make spaces significant in the future. For
11+running example, we may want to make spaces significant. For example, we might
12−example, we might want to implement function application expressed by
12+want to implement function application expressed by juxtaposition as in
13−juxtaposition as in Haskell and Idris like this: ``f x``.
13+Haskell and Idris like this: ``f x``.
14
14
15−So, on this page, we will add a token for whitespace and comments. We will
15+Also, I'm not sure if it is an problem for error messages and so on if some
16−then consider two ways to process this:
16+text does not have corresponding tokens.
17
17
18−- Filter all whitespace tokens from the lexer results before passing to
18+So, on this page, we will add a token for whitespace and comments.
19− the parser.
20−- Process the whitespace tokens in the parser.
21
19
22Whitespace and Comments in Lexer
20Whitespace and Comments in Lexer
23--------------------------------
21--------------------------------
@@ -72,31 +70,10 @@ like this:
72 spaces : Lexer
70 spaces : Lexer
73 spaces = some space
71 spaces = some space
74
72
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−
94Whitespace and Comments in Parser
73Whitespace and Comments in Parser
95---------------------------------
74---------------------------------
96
75
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.
76+Now that there are ``Comment`` tokens the parser needs to be able to handle them.
100
77
101.. code-block:: idris
78.. code-block:: idris
102
79
@@ -108,68 +85,42 @@ which now needs to be able to handle them.
108So far we don't have any syntax that requires spaces to be significant so we
85So far we don't have any syntax that requires spaces to be significant so we
109need to define the grammar so that it will parse with, or without, spaces.
86need to define the grammar so that it will parse with, or without, spaces.
110This needs to be done in a systematic way, here I have defined the grammar so
87This needs to be done in a systematic way, here I have defined the grammar so
111−that there is an optional space to the right of every atom or operator.
88+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:
114
89
115.. code-block:: idris
90.. code-block:: idris
116
91
92+ partial
117− intLiteralC : Rule Integer
93+ exprAtom : Rule Integer
118− intLiteralC = (intLiteral <* commentSpace) <|> intLiteral
94+ exprAtom = (intLiteral <* commentSpace)
119−
95+ <|> intLiteral <|> (paren expr)
120− openParenC : Rule Integer
121− openParenC = (openParen <* commentSpace) <|> openParen
122
96
97+ partial
123− closeParenC : Rule Integer
98+ expr1 : Rule Integer
99+ expr1 = map multInt exprAtom <*> (
124− closeParenC = (closeParen <* commentSpace) <|> closeParen
100+ (((op "*") <* commentSpace) <|> (op "*"))
101+ *> exprAtom)
125
102
126− ||| like op but followed by optional comment or space
103+ partial
127− opC : String -> Rule Integer
104+ exprMult : Rule Integer
128− opC s = ((op s) <* commentSpace) <|> (op s)
105+ exprMult = expr1 <|> exprAtom
129
106
130−Then just use these functions instead of the original functions:
107+ partial
131−
108+ expr2 : Rule Integer
132−.. code-block:: idris
109+ expr2 = map addInt exprMult <*> (
110+ (((op "+") <* commentSpace) <|> (op "+"))
111+ *> exprMult)
133
112
113+ partial
134− expr : Rule Integer
114+ exprAdd : Rule Integer
115+ exprAdd = expr2 <|> exprMult
135
116
136− factor : Rule Integer
117+ partial
137− factor = intLiteralC <|> do
138− openParenC
139− r <- expr
140− closeParenC
141− pure r
142−
143− term : Rule Integer
118+ expr3 : 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 <*> (
119+ expr3 = map subInt exprAdd <*> (
153− (opC "-")
120+ (((op "-") <* commentSpace) <|> (op "-"))
154− *> term)
121+ *> expr)
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
172
122
123+ expr = expr3 <|> exprAdd
173
124
174Defining Block Structure using Indents
125Defining Block Structure using Indents
175--------------------------------------
126--------------------------------------
@@ -190,61 +141,14 @@ We can see how Idris2 does it here
190 init : IndentInfo
141 init : IndentInfo
191 init = 0
142 init = 0
192
143
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:
201
144
202−.. code-block:: idris
203
145
204− data ExpressionToken = Number Integer
205− | Operator String
206− | OParen
207− | CParen
208− | Comment String
209− | EndInput
210
146
211−A rule to consume this token is added:
212
147
213−.. code-block:: idris
214
148
215− eoi : Rule Integer
216− eoi = terminal (\x => case tok x of
217− EndInput => Just 0
218− _ => Nothing)
219
149
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:
223
150
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
242
151
243−All we have to do now is use ``exprFull`` instead of ``expr``:
244−
245−.. code-block:: idris
246
152
247− calc : String -> Either (ParseError (TokenData ExpressionToken))
248− (Integer, List (TokenData ExpressionToken))
249− calc s = parse exprFull (fst (processWhitespace (lex expressionTokens s)))
250
153
154+
docs/reference/misc.rst+5−5
@@ -115,11 +115,11 @@ Here is an example:
115 import Syntax.PreorderReasoning
115 import Syntax.PreorderReasoning
116 multThree : (a, b, c : Nat) -> a * b * c = c * a * b
116 multThree : (a, b, c : Nat) -> a * b * c = c * a * b
117 multThree a b c =
117 multThree a b c =
118− (a * b * c) ={ sym (multAssociative a b c) }=
118+ (a * b * c) ={ sym (multAssociative a b c) }=
119− (a * (b * c)) ={ cong (multCommutative b c) }=
119+ (a * (b * c)) ={ cong (multCommutative b c) }=
120− (a * (c * b)) ={ multAssociative a c b }=
120+ (a * (c * b)) ={ multAssociative a c b }=
121− (a * c * b) ={ cong {f = (* b)} (multCommutative a c) }=
121+ (a * c * b) ={ cong {f = (* b)} (multCommutative a c) }=
122− (c * a * b) QED
122+ (c * a * b) QED
123
123
124Note that the parentheses are required -- only a simple expression can
124Note that the parentheses are required -- only a simple expression can
125be on the left of ``={ }=`` or ``QED``. Also, when using preorder
125be on the left of ``={ }=`` or ``QED``. Also, when using preorder
idris-tutorial.pdf

Binary file not shown.

idris.cabal+15−31
@@ -46,19 +46,12 @@ Build-type: Custom
46
46
47Tested-With: GHC == 7.10.3, GHC == 8.0.1
47Tested-With: GHC == 7.10.3, GHC == 8.0.1
48
48
49−-- NOTE: due to https://github.com/haskell/cabal/issues/6125 the use of ** is
50−-- heavily discouraged.
51Data-files: idrisdoc/styles.css
49Data-files: idrisdoc/styles.css
52− jsrts/jsbn/*.js
50+ jsrts/**/*.js
53− jsrts/*.js
54 jsrts/jsbn/LICENSE
51 jsrts/jsbn/LICENSE
55 rts/Makefile
52 rts/Makefile
56− rts/*.c
53+ rts/**/*.c
57− rts/seL4/*.c
54+ rts/**/*.h
58− rts/arduino/*.c
59− rts/windows/*.c
60− rts/windows/*.h
61− rts/*.h
62 rts/seL4/CMakeLists.txt
55 rts/seL4/CMakeLists.txt
63 rts/seL4/README.md
56 rts/seL4/README.md
64
57
@@ -71,13 +64,8 @@ Extra-doc-files:
71 RELEASE-CHECKS.md
64 RELEASE-CHECKS.md
72 idris-tutorial.pdf
65 idris-tutorial.pdf
73 man/idris.1
66 man/idris.1
74− samples/effects/*.idr
67+ samples/**/*.idr
75− samples/misc/*.idr
76− samples/tutorial/*.idr
68+ samples/**/*.lidr
77− samples/ST/*.idr
78− samples/ST/Graphics/*.idr
79− samples/ST/Net/*.idr
80− samples/misc/*.lidr
81
69
82-- extra-source-files is generated by Setup.hs using `git --ls-files`.
70-- extra-source-files is generated by Setup.hs using `git --ls-files`.
83Extra-source-files:
71Extra-source-files:
@@ -85,20 +73,15 @@ Extra-source-files:
85 config.mk
73 config.mk
86 custom.mk-alldeps
74 custom.mk-alldeps
87 mkpkg.sh
75 mkpkg.sh
76+ stack-alt.yaml
88 stack-shell.nix
77 stack-shell.nix
89 stack.yaml
78 stack.yaml
90 stylize.sh
79 stylize.sh
91 win-release.sh
80 win-release.sh
92−
81+
93 benchmarks/*.pl
82 benchmarks/*.pl
94− benchmarks/fasta/*.idr
83+ benchmarks/**/*.idr
95− benchmarks/fasta/*.ipkg
84+ benchmarks/**/*.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
102 benchmarks/quasigroups/board
85 benchmarks/quasigroups/board
103
86
104 icons/*.png
87 icons/*.png
@@ -321,13 +304,13 @@ Library
321 Build-depends: base >=4 && <5
304 Build-depends: base >=4 && <5
322 , aeson >= 0.6 && < 1.5
305 , aeson >= 0.6 && < 1.5
323 , annotated-wl-pprint >= 0.7 && < 0.8
306 , annotated-wl-pprint >= 0.7 && < 0.8
324− , ansi-terminal < 0.11
307+ , ansi-terminal < 0.10
325 , ansi-wl-pprint < 0.7
308 , ansi-wl-pprint < 0.7
326 , array >= 0.4.0.1 && < 0.6
309 , array >= 0.4.0.1 && < 0.6
327 , base64-bytestring < 1.1
310 , base64-bytestring < 1.1
328 , binary >= 0.8.4.1 && < 0.9
311 , binary >= 0.8.4.1 && < 0.9
329 , blaze-html >= 0.6.1.3 && < 0.10
312 , blaze-html >= 0.6.1.3 && < 0.10
330− , blaze-markup >= 0.5.2.1 && < 0.10
313+ , blaze-markup >= 0.5.2.1 && < 0.9
331 , bytestring < 0.11
314 , bytestring < 0.11
332 , cheapskate >= 0.1.1.2 && < 0.2
315 , cheapskate >= 0.1.1.2 && < 0.2
333 , code-page >= 0.1 && < 0.3
316 , code-page >= 0.1 && < 0.3
@@ -338,9 +321,9 @@ Library
338 , fingertree >= 0.1.4.1 && < 0.2
321 , fingertree >= 0.1.4.1 && < 0.2
339 , haskeline >= 0.7 && < 0.8
322 , haskeline >= 0.7 && < 0.8
340 , ieee754 >= 0.7 && < 0.9
323 , ieee754 >= 0.7 && < 0.9
341− , megaparsec >= 7.0.4 && < 9
324+ , megaparsec >= 7.0.4 && < 8
342 , mtl >= 2.1 && < 2.3
325 , mtl >= 2.1 && < 2.3
343− , network >= 2.7 && < 3.1.2
326+ , network >= 2.7 && < 2.9
344 , optparse-applicative >= 0.13 && < 0.16
327 , optparse-applicative >= 0.13 && < 0.16
345 , parser-combinators >= 1.0.0
328 , parser-combinators >= 1.0.0
346 , pretty < 1.2
329 , pretty < 1.2
@@ -358,7 +341,7 @@ Library
358 , vector < 0.13
341 , vector < 0.13
359 , vector-binary-instances < 0.3
342 , vector-binary-instances < 0.3
360 , zip-archive > 0.2.3.5 && < 0.5
343 , zip-archive > 0.2.3.5 && < 0.5
361− , fsnotify >= 0.2 && < 0.4
344+ , fsnotify >= 0.2 && < 2.2
362 , async < 2.3
345 , async < 2.3
363
346
364 if !impl(ghc >= 8.0)
347 if !impl(ghc >= 8.0)
@@ -476,3 +459,4 @@ Executable idris-codegen-node
476 Default-Language: Haskell2010
459 Default-Language: Haskell2010
477 ghc-prof-options: -auto-all -caf-all
460 ghc-prof-options: -auto-all -caf-all
478 ghc-options: -threaded -rtsopts -funbox-strict-fields
461 ghc-options: -threaded -rtsopts -funbox-strict-fields
462+
libs/base/Control/Isomorphism.idr+23−20
@@ -17,22 +17,21 @@ record Iso a b where
17
17
18-- Isomorphism properties
18-- Isomorphism properties
19
19
20−||| Isomorphism is reflexive
20+||| Isomorphism is Reflexive
21isoRefl : Iso a a
21isoRefl : Iso a a
22−isoRefl = MkIso id id (\_ => Refl) (\_ => Refl)
22+isoRefl = MkIso id id (\x => Refl) (\x => Refl)
23
23
24||| Isomorphism is transitive
24||| Isomorphism is transitive
25isoTrans : Iso a b -> Iso b c -> Iso a c
25isoTrans : Iso a b -> Iso b c -> Iso a c
26isoTrans (MkIso to from toFrom fromTo) (MkIso to' from' toFrom' fromTo') =
26isoTrans (MkIso to from toFrom fromTo) (MkIso to' from' toFrom' fromTo') =
27− MkIso xto xfrom xtoFrom xfromTo where
27+ MkIso (\x => to' (to x))
28− xto : a -> c
28+ (\y => from (from' y))
29− xto = to' . to
29+ (\y => (to' (to (from (from' y)))) ={ cong (toFrom (from' y)) }=
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
30+ (to' (from' y)) ={ toFrom' y }=
34− xfromTo : (x : a) -> xfrom (xto x) = x
31+ y QED)
32+ (\x => (from (from' (to' (to x)))) ={ cong (fromTo' (to x)) }=
35− xfromTo x = rewrite fromTo' (to x) in fromTo x
33+ (from (to x)) ={ fromTo x }=
34+ x QED)
36
35
37Category Iso where
36Category Iso where
38 id = isoRefl
37 id = isoRefl
@@ -100,7 +99,8 @@ eitherBotRight = isoTrans eitherComm eitherBotLeft
100
99
101||| Isomorphism is a congruence with regards to disjunction
100||| Isomorphism is a congruence with regards to disjunction
102eitherCong : Iso a a' -> Iso b b' -> Iso (Either a b) (Either a' b')
101eitherCong : Iso a a' -> Iso b b' -> Iso (Either a b) (Either a' b')
102+eitherCong {a = a} {a' = a'} {b = b} {b' = b'}
103−eitherCong (MkIso to from toFrom fromTo)
103+ (MkIso to from toFrom fromTo)
104 (MkIso to' from' toFrom' fromTo') =
104 (MkIso to' from' toFrom' fromTo') =
105 MkIso (eitherMap to to') (eitherMap from from') ok1 ok2
105 MkIso (eitherMap to to') (eitherMap from from') ok1 ok2
106 where eitherMap : (c -> c') -> (d -> d') -> Either c d -> Either c' d'
106 where eitherMap : (c -> c') -> (d -> d') -> Either c d -> Either c' d'
@@ -143,7 +143,9 @@ pairAssoc = MkIso to from ok1 ok2
143
143
144||| Conjunction with truth is a no-op
144||| Conjunction with truth is a no-op
145pairUnitRight : Iso (a, ()) a
145pairUnitRight : Iso (a, ()) a
146−pairUnitRight = MkIso fst (\x => (x, ())) (\_ => Refl) (\(_, ()) => Refl)
146+pairUnitRight = MkIso fst (\x => (x, ())) (\x => Refl) ok
147+ where ok : (x : (a, ())) -> (fst x, ()) = x
148+ ok (x, ()) = Refl
147
149
148||| Conjunction with truth is a no-op
150||| Conjunction with truth is a no-op
149pairUnitLeft : Iso ((), a) a
151pairUnitLeft : Iso ((), a) a
@@ -159,7 +161,8 @@ pairBotRight = isoTrans pairComm pairBotLeft
159
161
160||| Isomorphism is a congruence with regards to conjunction
162||| Isomorphism is a congruence with regards to conjunction
161pairCong : Iso a a' -> Iso b b' -> Iso (a, b) (a', b')
163pairCong : Iso a a' -> Iso b b' -> Iso (a, b) (a', b')
164+pairCong {a = a} {a' = a'} {b = b} {b' = b'}
162−pairCong (MkIso to from toFrom fromTo)
165+ (MkIso to from toFrom fromTo)
163 (MkIso to' from' toFrom' fromTo') =
166 (MkIso to' from' toFrom' fromTo') =
164 MkIso to'' from'' iso1 iso2
167 MkIso to'' from'' iso1 iso2
165 where to'' : (a, b) -> (a', b')
168 where to'' : (a, b) -> (a', b')
@@ -202,7 +205,7 @@ distribLeft = MkIso to from toFrom fromTo
202
205
203||| Products distribute over sums
206||| Products distribute over sums
204distribRight : Iso (a, Either b c) (Either (a, b) (a, c))
207distribRight : Iso (a, Either b c) (Either (a, b) (a, c))
205−distribRight = (pairComm `isoTrans` distribLeft) `isoTrans` eitherCong pairComm pairComm
208+distribRight {a} {b} {c} = (pairComm `isoTrans` distribLeft) `isoTrans` eitherCong pairComm pairComm
206
209
207
210
208-- Enable preorder reasoning syntax over isomorphisms
211-- Enable preorder reasoning syntax over isomorphisms
@@ -219,7 +222,7 @@ step a iso1 iso2 = isoTrans iso1 iso2
219-- Isomorphisms over Maybe
222-- Isomorphisms over Maybe
220||| Isomorphism is a congruence with respect to Maybe
223||| Isomorphism is a congruence with respect to Maybe
221maybeCong : Iso a b -> Iso (Maybe a) (Maybe b)
224maybeCong : Iso a b -> Iso (Maybe a) (Maybe b)
222−maybeCong (MkIso to from toFrom fromTo) = MkIso (map to) (map from) ok1 ok2
225+maybeCong {a} {b} (MkIso to from toFrom fromTo) = MkIso (map to) (map from) ok1 ok2
223 where ok1 : (y : Maybe b) -> map to (map from y) = y
226 where ok1 : (y : Maybe b) -> map to (map from y) = y
224 ok1 Nothing = Refl
227 ok1 Nothing = Refl
225 ok1 (Just x) = (Just (to (from x))) ={ cong (toFrom x) }= (Just x) QED
228 ok1 (Just x) = (Just (to (from x))) ={ cong (toFrom x) }= (Just x) QED
@@ -250,7 +253,7 @@ maybeVoidUnit = (Maybe Void) ={ maybeEither }=
250 () QED
253 () QED
251
254
252eitherMaybeLeftMaybe : Iso (Either (Maybe a) b) (Maybe (Either a b))
255eitherMaybeLeftMaybe : Iso (Either (Maybe a) b) (Maybe (Either a b))
253−eitherMaybeLeftMaybe =
256+eitherMaybeLeftMaybe {a} {b} =
254 (Either (Maybe a) b) ={ eitherCongLeft maybeEither }=
257 (Either (Maybe a) b) ={ eitherCongLeft maybeEither }=
255 (Either (Either a ()) b) ={ eitherAssoc }=
258 (Either (Either a ()) b) ={ eitherAssoc }=
256 (Either a (Either () b)) ={ eitherCongRight eitherComm }=
259 (Either a (Either () b)) ={ eitherCongRight eitherComm }=
@@ -260,7 +263,7 @@ eitherMaybeLeftMaybe =
260
263
261
264
262eitherMaybeRightMaybe : Iso (Either a (Maybe b)) (Maybe (Either a b))
265eitherMaybeRightMaybe : Iso (Either a (Maybe b)) (Maybe (Either a b))
263−eitherMaybeRightMaybe =
266+eitherMaybeRightMaybe {a} {b} =
264 (Either a (Maybe b)) ={ eitherComm }=
267 (Either a (Maybe b)) ={ eitherComm }=
265 (Either (Maybe b) a) ={ eitherMaybeLeftMaybe }=
268 (Either (Maybe b) a) ={ eitherMaybeLeftMaybe }=
266 (Maybe (Either b a)) ={ maybeCong eitherComm }=
269 (Maybe (Either b a)) ={ maybeCong eitherComm }=
@@ -285,8 +288,8 @@ maybeIsoS = MkIso forth back fb bf
285 fb (FS x) = Refl
288 fb (FS x) = Refl
286
289
287finZeroBot : Iso (Fin 0) Void
290finZeroBot : Iso (Fin 0) Void
288−finZeroBot = MkIso (void . uninhabited)
291+finZeroBot = MkIso (\x => void (uninhabited x))
289− void
292+ (\x => void x)
290 (\x => void x)
293 (\x => void x)
291 (\x => void (uninhabited x))
294 (\x => void (uninhabited x))
292
295
libs/contrib/Control/Algebra/Laws.idr+80−128
@@ -6,146 +6,98 @@ import Interfaces.Verified
6
6
7%access export
7%access export
8
8
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.
9+||| A prof that -0 = 0 in any verified group.
24−inverseNeutralIsNeutral : VerifiedGroup t =>
10+inverseNeutralIsNeutral : VerifiedGroup t => inverse (the t A.neutral) = A.neutral
25− inverse (the t A.neutral) = A.neutral
26inverseNeutralIsNeutral {t} =
11inverseNeutralIsNeutral {t} =
27− let e = the t neutral in
12+ let zero = the t neutral
13+ step1 = cong {f = (<+> inverse zero)} (the (zero = zero) Refl)
28− rewrite sym $ cong {f = inverse} (groupInverseIsInverseL e) in
14+ step2 = replace {P = \x => zero <+> inverse zero = x} (groupInverseIsInverseL zero) step1
15+ in
29− rewrite monoidNeutralIsNeutralR $ inverse e in
16+ replace {P = \x => x = neutral} (monoidNeutralIsNeutralR $ inverse zero) step2
30− inverseSquaredIsIdentity e
31
17
32−||| -(x + y) = -y + -x in any verified group.
18+||| A proof that -(-x) = x in any verified group.
33−inverseOfSum : VerifiedGroup t => (l, r : t) ->
19+inverseSquaredIsIdentity : VerifiedGroup t => (x : t) -> inverse (inverse x) = x
34− inverse (l <+> r) = inverse r <+> inverse l
20+inverseSquaredIsIdentity {t} x =
35−inverseOfSum {t} l r =
36− let
37− e = the t neutral
21+ let zero = the t neutral
38− il = inverse l
22+ step1 = cong {f = (x <+>)} (groupInverseIsInverseL (inverse x))
39− ir = inverse r
23+ step2 = replace {P = \r => r = x <+> neutral} (semigroupOpIsAssociative x (inverse x) (inverse $ inverse x)) step1
40− sum = l <+> r
24+ step3 = replace {P = \r => r <+> inverse (inverse x) = x <+> neutral} (groupInverseIsInverseL x) step2
41− ilr = inverse sum
42− iril = ir <+> il
43− ile = il <+> e
44− in
45− -- expand
46− rewrite sym $ monoidNeutralIsNeutralR ilr in
25+ step4 = replace {P = \r => r = x <+> neutral} (monoidNeutralIsNeutralR (inverse $ inverse x)) step3
47− rewrite sym $ groupInverseIsInverseR r in
26+ 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
27+ replace {P = \r => inverse (inverse x) = r} (monoidNeutralIsNeutralL x) step4
61− Refl
62
28
63−||| -(x + y) = -x + -y in any verified abelian group.
29+||| A proof that -(x + y) = -x - y in any verified abelian group.
64−inverseDistributesOverGroupOp : VerifiedAbelianGroup t => (l, r : t) ->
30+inverseDistributesOverGroupOp : VerifiedAbelianGroup t => (l, r : t) -> inverse (l <+> r) = inverse l <+> inverse r
65− inverse (l <+> r) = inverse l <+> inverse r
66−inverseDistributesOverGroupOp l 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
67− rewrite abelianGroupOpIsCommutative (inverse l) (inverse r) in
44+ replace {P = \x => inverse (l <+> r) = x} (abelianGroupOpIsCommutative (inverse r) (inverse l)) step11
68− inverseOfSum l r
69
45
70−||| Anything multiplied by zero yields zero back in a verified ring.
46+||| A proof that anything multiplied by zero yields zero back.
71−multNeutralAbsorbingL : VerifiedRing t => (r : t) ->
47+multNeutralAbsorbingL : VerifiedRingWithUnity t => (r : t) -> A.neutral <.> r = A.neutral
72− A.neutral <.> r = A.neutral
73−multNeutralAbsorbingL {t} r =
48+multNeutralAbsorbingL r =
74− let
49+ let step1 = the (unity <.> r = r) (ringWithUnityIsUnityR r)
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
50+ step2 = replace {P = \x => x <.> r = r} (sym $ monoidNeutralIsNeutralR unity) step1
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
51+ step3 = replace {P = \x => x = r} (ringOpIsDistributiveR neutral unity r) step2
85− rewrite monoidNeutralIsNeutralR e in
52+ step4 = replace {P = \x => neutral <.> r <+> x = r} (ringWithUnityIsUnityR r) step3
86− groupInverseIsInverseR exr
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
87
58
88−||| Anything multiplied by zero yields zero back in a verified ring.
59+||| A proof that anything multiplied by zero yields zero back.
89−multNeutralAbsorbingR : VerifiedRing t => (l : t) ->
60+multNeutralAbsorbingR : VerifiedRingWithUnity t => (l : t) -> l <.> A.neutral = A.neutral
90− l <.> A.neutral = A.neutral
91−multNeutralAbsorbingR {t} l =
61+multNeutralAbsorbingR l =
92− let
62+ let step1 = the (l <.> unity = l) (ringWithUnityIsUnityL l)
93− e = the t neutral
63+ step2 = replace {P = \x => l <.> x = l} (sym $ monoidNeutralIsNeutralR unity) step1
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
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
103− rewrite monoidNeutralIsNeutralL e in
70+ replace {P = \x => x = neutral} (monoidNeutralIsNeutralL (l <.> neutral)) step7
104− groupInverseIsInverseL lxe
105
71
106−||| Inverse operator can be extracted before multiplication.
72+||| A proof that inverse operator can be extracted before multiplication
107||| (-x)y = -(xy)
73||| (-x)y = -(xy)
108−multInverseInversesL : VerifiedRing t => (l, r : t) ->
74+multInverseInversesL : VerifiedRingWithUnity t => (l, r : t) -> inverse l <.> r = inverse (l <.> r)
109− inverse l <.> r = inverse (l <.> r)
110multInverseInversesL l r =
75multInverseInversesL l r =
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
76+ let step1 = replace {P = \x => x <.> r = neutral} (sym $ groupInverseIsInverseL l) (multNeutralAbsorbingL r)
122− rewrite multNeutralAbsorbingL r in
77+ step2 = replace {P = \x => x = neutral} (ringOpIsDistributiveR l (inverse l) r) step1
78+ step3 = cong {f = ((inverse (l <.> r)) <+>)} step2
123− monoidNeutralIsNeutralL i_lxr
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
124
84
125−||| Inverse operator can be extracted before multiplication.
85+||| A proof that inverse operator can be extracted before multiplication
126||| x(-y) = -(xy)
86||| x(-y) = -(xy)
127−multInverseInversesR : VerifiedRing t => (l, r : t) ->
87+multInverseInversesR : VerifiedRingWithUnity t => (l, r : t) -> l <.> inverse r = inverse (l <.> r)
128− l <.> inverse r = inverse (l <.> r)
129multInverseInversesR l r =
88multInverseInversesR l r =
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
89+ let step1 = replace {P = \x => l <.> x = neutral} (sym $ groupInverseIsInverseL r) (multNeutralAbsorbingR l)
138− rewrite semigroupOpIsAssociative lxir lxr ilxr in
139− rewrite sym $ ringOpIsDistributiveL l ir r in
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
140− rewrite groupInverseIsInverseR r in
94+ step6 = replace {P = \x => x <+> l <.> inverse r = inverse (l <.> r)} (groupInverseIsInverseR (l <.> r)) step5
141− rewrite multNeutralAbsorbingR l in
95+ in
142− monoidNeutralIsNeutralR ilxr
96+ replace {P = \x => x = inverse (l <.> r)} (monoidNeutralIsNeutralR (l <.> inverse r)) step6
143
97
144−||| Multiplication of inverses is the same as multiplication of
98+||| A proof that multiplication of inverses is the same as multiplication of original
145−||| original elements.
99+||| elements. (-x)(-y) = xy
146−||| (-x)(-y) = xy
147−multNegativeByNegativeIsPositive : VerifiedRing t => (l, r : t) ->
100+multNegativeByNegativeIsPositive : VerifiedRingWithUnity t => (l, r : t) -> inverse l <.> inverse r = l <.> r
148− inverse l <.> inverse r = l <.> r
149multNegativeByNegativeIsPositive l r =
101multNegativeByNegativeIsPositive l r =
150 rewrite multInverseInversesR (inverse l) r in
102 rewrite multInverseInversesR (inverse l) r in
151 rewrite sym $ multInverseInversesL (inverse l) r in
103 rewrite sym $ multInverseInversesL (inverse l) r in
libs/contrib/Data/List/Extra.idrnew file+46
@@ -0,0 +1,46 @@
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.idrdeleted−99
@@ -1,99 +0,0 @@
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.idrdeleted−56
@@ -1,56 +0,0 @@
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+69−123
@@ -2,9 +2,18 @@ module Data.Nat.Parity
2
2
3%access public export
3%access public export
4
4
5−----------------------------------------
5+--------------------------------------------------------------------------------
6+-- Parity
7+--------------------------------------------------------------------------------
6
8
7−-- Type-level, constructive definitions of parity.
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
8
17
9||| A nat is Even when it is twice some other nat.
18||| A nat is Even when it is twice some other nat.
10Even : Nat -> Type
19Even : Nat -> Type
@@ -14,8 +23,6 @@ Even n = (half : Nat ** n = half * 2)
14Odd : Nat -> Type
23Odd : Nat -> Type
15Odd n = (haf : Nat ** n = S $ haf * 2)
24Odd n = (haf : Nat ** n = S $ haf * 2)
16
25
17−----------------------------------------
18−
19||| Two more than an Even is Even.
26||| Two more than an Even is Even.
20add2Even : Even n -> Even (2 + n)
27add2Even : Even n -> Even (2 + n)
21add2Even (half ** pf) = (S half ** cong {f = (+) 2} pf)
28add2Even (half ** pf) = (S half ** cong {f = (+) 2} pf)
@@ -45,73 +52,20 @@ succDoublePredPred {k = S _} prf = cong {f = Nat.pred} prf
45predEvenOdd : Even (S n) -> Odd n
52predEvenOdd : Even (S n) -> Odd n
46predEvenOdd (half ** pf) = (pred half ** succDoublePredPred pf)
53predEvenOdd (half ** pf) = (pred half ** succDoublePredPred pf)
47
54
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−
101||| Every nat is either Even or Odd.
55||| Every nat is either Even or Odd.
102evenOrOdd : (n : Nat) -> Either (Even n) (Odd n)
56evenOrOdd : (n : Nat) -> Either (Even n) (Odd n)
103−evenOrOdd n = case evenorodd n of
57+evenOrOdd Z = Left (0 ** Refl)
104− Left e => Left $ evenEvenConverse e
58+evenOrOdd (S k) = case evenOrOdd k of
105− Right o => Right $ oddOddConverse o
59+ Left (half ** pf) => Right (half ** cong {f = S} pf)
106−
60+ Right (haf ** pf) => Left (S haf ** cong {f = S} pf)
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
111
61
112||| No nat is both Even and Odd.
62||| No nat is both Even and Odd.
113notEvenAndOdd : Even n -> Odd n -> Void
63notEvenAndOdd : Even n -> Odd n -> Void
114−notEvenAndOdd en on = notevenandodd (evenEven en) (oddOdd on)
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)
115
69
116||| Evenness is decidable.
70||| Evenness is decidable.
117evenDec : (n : Nat) -> Dec $ Even n
71evenDec : (n : Nat) -> Dec $ Even n
@@ -125,46 +79,42 @@ oddDec n = case evenOrOdd n of
125 Left even => No $ notEvenAndOdd even
79 Left even => No $ notEvenAndOdd even
126 Right odd => Yes odd
80 Right odd => Yes odd
127
81
128−----------------------------------------
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
129
87
130−||| An Odd is the successor of an Even.
88+ ||| Odds are odd.
131−oddSuccEven : Odd n -> (m : Nat ** (n = S m, Even m))
89+ oddOdd : Odd n -> odd n = True
132−oddSuccEven (haf ** pf) = (haf * 2 ** (pf, (haf ** Refl)))
90+ oddOdd {n = Z} (_ ** pf) = absurd pf
91+ oddOdd {n = S _} pf = evenEven $ predOddEven pf
133
92
134||| Even plus Even is Even.
93||| Even plus Even is Even.
135evenPlusEven : Even j -> Even k -> Even (j + k)
94evenPlusEven : Even j -> Even k -> Even (j + k)
136evenPlusEven (half_j ** pf_j) (half_k ** pf_k) =
95evenPlusEven (half_j ** pf_j) (half_k ** pf_k) =
96+ rewrite pf_j in
97+ rewrite pf_k in
137− (half_j + half_k **
98+ (half_j + half_k **
138− rewrite pf_j in
139− rewrite pf_k in
140 sym $ multDistributesOverPlusLeft half_j half_k 2)
99 sym $ multDistributesOverPlusLeft half_j half_k 2)
141
100
142−||| Odd plus Even is Odd.
101+||| Odd plus Odd is Even.
143−oddPlusEven : Odd j -> Even k -> Odd (j + k)
102+oddPlusOdd : Odd j -> Odd k -> Even (j + k)
144−oddPlusEven oj ek =
103+oddPlusOdd (haf_j ** pf_j) (haf_k ** pf_k) =
145− let
104+ rewrite pf_j in
146− (i ** (ipj, ei)) = oddSuccEven oj
105+ rewrite pf_k in
147− (half_ik ** eik) = evenPlusEven ei ek
106+ rewrite sym $ plusSuccRightSucc (haf_j * 2) (haf_k * 2) in
148− in
107+ rewrite sym $ multDistributesOverPlusLeft haf_j haf_k 2 in
149− (half_ik **
108+ (S (haf_j + haf_k) ** Refl)
150− rewrite ipj in
151− cong {f = S} eik)
152
109
153||| Even plus Odd is Odd.
110||| Even plus Odd is Odd.
154evenPlusOdd : Even j -> Odd k -> Odd (j + k)
111evenPlusOdd : Even j -> Odd k -> Odd (j + k)
155−evenPlusOdd {j} {k} ej ok = rewrite plusCommutative j k in oddPlusEven ok ej
112+evenPlusOdd (half_j ** pf_j) (haf_k ** pf_k) =
156−
113+ rewrite pf_j in
157−||| Odd plus Odd is Even.
114+ rewrite pf_k in
158−oddPlusOdd : Odd j -> Odd k -> Even (j + k)
115+ rewrite sym $ plusSuccRightSucc (half_j * 2) (haf_k * 2) in
159−oddPlusOdd oj ok =
116+ rewrite sym $ multDistributesOverPlusLeft half_j haf_k 2 in
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)
117+ (half_j + haf_k ** Refl)
168
118
169||| A helper fact.
119||| A helper fact.
170multShuffle : (a, b, c : Nat) ->
120multShuffle : (a, b, c : Nat) ->
@@ -179,39 +129,35 @@ multShuffle a b c =
179||| Even times Even is Even.
129||| Even times Even is Even.
180evenMultEven : Even j -> Even k -> Even (j * k)
130evenMultEven : Even j -> Even k -> Even (j * k)
181evenMultEven (half_j ** pf_j) (half_k ** pf_k) =
131evenMultEven (half_j ** pf_j) (half_k ** pf_k) =
132+ rewrite pf_j in
133+ rewrite pf_k in
182− (half_j * half_k * 2 **
134+ (half_j * half_k * 2 **
183− rewrite pf_j in
184− rewrite pf_k in
185 multShuffle half_j half_k 2)
135 multShuffle half_j half_k 2)
186
136
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−
201||| Even times Odd is Even.
137||| Even times Odd is Even.
202evenMultOdd : Even j -> Odd k -> Even (j * k)
138evenMultOdd : Even j -> Odd k -> Even (j * k)
203−evenMultOdd {j} {k} ej ok = rewrite multCommutative j k in oddMultEven ok ej
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)
204
147
205||| Odd times Odd is Odd.
148||| Odd times Odd is Odd.
206oddMultOdd : Odd j -> Odd k -> Odd (j * k)
149oddMultOdd : Odd j -> Odd k -> Odd (j * k)
207−oddMultOdd oj (haf_k ** pf_k) =
150+oddMultOdd (haf_j ** pf_j) (haf_k ** pf_k) =
208 let
151 let
209− (i ** (ipj, ei)) = oddSuccEven oj
152+ haf = haf_j * haf_k * 2
210− (half_ik ** eik) = evenMultOdd ei (haf_k ** pf_k)
153+ rem = haf_j + haf_k
211 in
154 in
212− (haf_k + half_ik **
155+ rewrite pf_j in
213− rewrite multDistributesOverPlusLeft haf_k half_ik 2 in
156+ rewrite pf_k in
214− rewrite ipj in
157+ rewrite multRightSuccPlus (haf_j * 2) (haf_k * 2) in
215− rewrite eik in
158+ rewrite multShuffle haf_j haf_k 2 in
216− rewrite pf_k 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
217− Refl)
163+ (rem + haf ** Refl)
libs/contrib/contrib.ipkg+1−1
@@ -43,7 +43,7 @@ modules = CFFI
43 , Data.Heap
43 , Data.Heap
44 , Data.IOArray
44 , Data.IOArray
45 , Data.List.Zipper
45 , Data.List.Zipper
46− , Data.List.Reverse
46+ , Data.List.Extra
47
47
48 , Data.Matrix
48 , Data.Matrix
49 , Data.Matrix.Algebraic
49 , Data.Matrix.Algebraic
libs/prelude/Prelude/File.idr+2−3
@@ -150,8 +150,7 @@ do_getFileAccessTime h =
150private
150private
151do_getFileModifiedTime : Ptr -> IO Integer
151do_getFileModifiedTime : Ptr -> IO Integer
152do_getFileModifiedTime h =
152do_getFileModifiedTime h =
153− do vm <- getMyVM
154− MkRaw i <- foreign FFI_C "fileModifiedTime" (Ptr -> Ptr -> IO (Raw Integer)) vm h
153+ do MkRaw i <- foreign FFI_C "fileModifiedTime" (Ptr -> IO (Raw Integer)) h
155 pure i
154 pure i
156
155
157private
156private
@@ -176,7 +175,7 @@ export
176fileModifiedTime : File -> IO (Either FileError Integer)
175fileModifiedTime : File -> IO (Either FileError Integer)
177fileModifiedTime (FHandle h)
176fileModifiedTime (FHandle h)
178 = do s <- do_getFileModifiedTime h
177 = do s <- do_getFileModifiedTime h
179− if (s == -1)
178+ if (s < 0)
180 then Left <$> getFileError
179 then Left <$> getFileError
181 else pure (Right s)
180 else pure (Right s)
182
181
libs/prelude/Prelude/Nat.idr+61−32
@@ -512,18 +512,19 @@ plusLeftCancel (S left) right right' p =
512
512
513total plusRightCancel : (left : Nat) -> (left' : Nat) -> (right : Nat) ->
513total plusRightCancel : (left : Nat) -> (left' : Nat) -> (right : Nat) ->
514 (p : left + right = left' + right) -> left = left'
514 (p : left + right = left' + right) -> left = left'
515−plusRightCancel left left' right p =
515+plusRightCancel left left' Z p = rewrite sym (plusZeroRightNeutral left) in
516− plusLeftCancel right left left' $
516+ rewrite sym (plusZeroRightNeutral left') in
517− rewrite plusCommutative right left in
517+ p
518− rewrite plusCommutative right left' in
518+plusRightCancel left left' (S right) p =
519− p
519+ plusRightCancel left left' right
520+ (succInjective _ _ (rewrite plusSuccRightSucc left right in
521+ rewrite plusSuccRightSucc left' right in p))
520
522
521total plusLeftLeftRightZero : (left : Nat) -> (right : Nat) ->
523total plusLeftLeftRightZero : (left : Nat) -> (right : Nat) ->
522 (p : left + right = left) -> right = Z
524 (p : left + right = left) -> right = Z
523−plusLeftLeftRightZero left right p =
525+plusLeftLeftRightZero Z right p = p
524− plusLeftCancel left right Z $
526+plusLeftLeftRightZero (S left) right p =
525− rewrite plusZeroRightNeutral left in
527+ plusLeftLeftRightZero left right (succInjective _ _ p)
526− p
527
528
528-- Mult
529-- Mult
529total multZeroLeftZero : (right : Nat) -> Z * right = Z
530total multZeroLeftZero : (right : Nat) -> Z * right = Z
@@ -557,21 +558,27 @@ multCommutative (S left) right =
557 rewrite multRightSuccPlus right left in
558 rewrite multRightSuccPlus right left in
558 Refl
559 Refl
559
560
560−total multDistributesOverPlusLeft : (left : Nat) -> (centre : Nat) -> (right : Nat) ->
561− (left + centre) * right = (left * right) + (centre * right)
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−
568total multDistributesOverPlusRight : (left : Nat) -> (centre : Nat) -> (right : Nat) ->
561total multDistributesOverPlusRight : (left : Nat) -> (centre : Nat) -> (right : Nat) ->
569 left * (centre + right) = (left * centre) + (left * right)
562 left * (centre + right) = (left * centre) + (left * right)
570−multDistributesOverPlusRight left centre right =
563+multDistributesOverPlusRight Z centre right = Refl
571− rewrite multCommutative left (centre + right) in
564+multDistributesOverPlusRight (S left) centre right =
572− rewrite multCommutative left centre in
565+ let inductiveHypothesis = multDistributesOverPlusRight left centre right in
573− rewrite multCommutative left 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+
574+total multDistributesOverPlusLeft : (left : Nat) -> (centre : Nat) -> (right : Nat) ->
575+ (left + centre) * right = (left * right) + (centre * right)
574− multDistributesOverPlusLeft centre right left
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
575
582
576total multAssociative : (left : Nat) -> (centre : Nat) -> (right : Nat) ->
583total multAssociative : (left : Nat) -> (centre : Nat) -> (right : Nat) ->
577 left * (centre * right) = (left * centre) * right
584 left * (centre * right) = (left * centre) * right
@@ -583,10 +590,18 @@ multAssociative (S left) centre right =
583 Refl
590 Refl
584
591
585total multOneLeftNeutral : (right : Nat) -> 1 * right = right
592total multOneLeftNeutral : (right : Nat) -> 1 * right = right
586−multOneLeftNeutral right = plusZeroRightNeutral right
593+multOneLeftNeutral Z = Refl
594+multOneLeftNeutral (S right) =
595+ let inductiveHypothesis = multOneLeftNeutral right in
596+ rewrite inductiveHypothesis in
597+ Refl
587
598
588total multOneRightNeutral : (left : Nat) -> left * 1 = left
599total multOneRightNeutral : (left : Nat) -> left * 1 = left
589−multOneRightNeutral left = rewrite multCommutative left 1 in multOneLeftNeutral left
600+multOneRightNeutral Z = Refl
601+multOneRightNeutral (S left) =
602+ let inductiveHypothesis = multOneRightNeutral left in
603+ rewrite inductiveHypothesis in
604+ Refl
590
605
591-- Minus
606-- Minus
592total minusSuccSucc : (left : Nat) -> (right : Nat) ->
607total minusSuccSucc : (left : Nat) -> (right : Nat) ->
@@ -674,7 +689,10 @@ total powerZeroOne : (base : Nat) -> power base 0 = S Z
674powerZeroOne base = Refl
689powerZeroOne base = Refl
675
690
676total powerOneNeutral : (base : Nat) -> power base 1 = base
691total powerOneNeutral : (base : Nat) -> power base 1 = base
677−powerOneNeutral base = rewrite multCommutative base 1 in multOneLeftNeutral base
692+powerOneNeutral Z = Refl
693+powerOneNeutral (S base) =
694+ let inductiveHypothesis = powerOneNeutral base in
695+ rewrite inductiveHypothesis in Refl
678
696
679total powerOneSuccOne : (exp : Nat) -> power 1 exp = S Z
697total powerOneSuccOne : (exp : Nat) -> power 1 exp = S Z
680powerOneSuccOne Z = Refl
698powerOneSuccOne Z = Refl
@@ -683,7 +701,8 @@ powerOneSuccOne (S exp) =
683 rewrite inductiveHypothesis in Refl
701 rewrite inductiveHypothesis in Refl
684
702
685total powerSuccSuccMult : (base : Nat) -> power base 2 = mult base base
703total powerSuccSuccMult : (base : Nat) -> power base 2 = mult base base
704+powerSuccSuccMult Z = Refl
686−powerSuccSuccMult base = rewrite multOneRightNeutral base in Refl
705+powerSuccSuccMult (S base) = rewrite multOneRightNeutral base in Refl
687
706
688total powerPowerMultPower : (base : Nat) -> (exp : Nat) -> (exp' : Nat) ->
707total powerPowerMultPower : (base : Nat) -> (exp : Nat) -> (exp' : Nat) ->
689 power (power base exp) exp' = power base (exp * exp')
708 power (power base exp) exp' = power base (exp * exp')
@@ -777,24 +796,34 @@ minimumIdempotent Z = Refl
777minimumIdempotent (S k) = cong (minimumIdempotent k)
796minimumIdempotent (S k) = cong (minimumIdempotent k)
778
797
779total minimumZeroZeroRight : (right : Nat) -> minimum 0 right = Z
798total minimumZeroZeroRight : (right : Nat) -> minimum 0 right = Z
780−minimumZeroZeroRight right = Refl
799+minimumZeroZeroRight Z = Refl
800+minimumZeroZeroRight (S right) = minimumZeroZeroRight right
781
801
782total minimumZeroZeroLeft : (left : Nat) -> minimum left 0 = Z
802total minimumZeroZeroLeft : (left : Nat) -> minimum left 0 = Z
783−minimumZeroZeroLeft left = rewrite minimumCommutative left 0 in Refl
803+minimumZeroZeroLeft Z = Refl
804+minimumZeroZeroLeft (S left) = Refl
784
805
785total minimumSuccSucc : (left : Nat) -> (right : Nat) ->
806total minimumSuccSucc : (left : Nat) -> (right : Nat) ->
786 minimum (S left) (S right) = S (minimum left right)
807 minimum (S left) (S right) = S (minimum left right)
787−minimumSuccSucc left right = Refl
808+minimumSuccSucc Z Z = Refl
809+minimumSuccSucc (S left) Z = Refl
810+minimumSuccSucc Z (S right) = Refl
811+minimumSuccSucc (S left) (S right) = Refl
788
812
789total maximumZeroNRight : (right : Nat) -> maximum Z right = right
813total maximumZeroNRight : (right : Nat) -> maximum Z right = right
790−maximumZeroNRight right = Refl
814+maximumZeroNRight Z = Refl
815+maximumZeroNRight (S right) = Refl
791
816
792total maximumZeroNLeft : (left : Nat) -> maximum left Z = left
817total maximumZeroNLeft : (left : Nat) -> maximum left Z = left
793−maximumZeroNLeft left = rewrite maximumCommutative left Z in Refl
818+maximumZeroNLeft Z = Refl
819+maximumZeroNLeft (S left) = Refl
794
820
795total maximumSuccSucc : (left : Nat) -> (right : Nat) ->
821total maximumSuccSucc : (left : Nat) -> (right : Nat) ->
796 S (maximum left right) = maximum (S left) (S right)
822 S (maximum left right) = maximum (S left) (S right)
797−maximumSuccSucc left right = Refl
823+maximumSuccSucc Z Z = Refl
824+maximumSuccSucc (S left) Z = Refl
825+maximumSuccSucc Z (S right) = Refl
826+maximumSuccSucc (S left) (S right) = Refl
798
827
799total sucMaxL : (l : Nat) -> maximum (S l) l = (S l)
828total sucMaxL : (l : Nat) -> maximum (S l) l = (S l)
800sucMaxL Z = Refl
829sucMaxL Z = Refl
rts/idris_bitstring.c+2
@@ -1,3 +1,5 @@
1+#include <assert.h>
2+
1#include "idris_rts.h"
3#include "idris_rts.h"
2
4
3VAL idris_b8const(VM *vm, uint8_t a) {
5VAL idris_b8const(VM *vm, uint8_t a) {
rts/idris_rts.c+10
@@ -1158,6 +1158,16 @@ void idris_disableBuffering(void) {
1158 setvbuf(stdout, NULL, _IONBF, 0);
1158 setvbuf(stdout, NULL, _IONBF, 0);
1159}
1159}
1160
1160
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+
1161void stackOverflow(void) {
1171void stackOverflow(void) {
1162 fprintf(stderr, "Stack overflow");
1172 fprintf(stderr, "Stack overflow");
1163 exit(-1);
1173 exit(-1);
rts/idris_rts.h+4
@@ -507,6 +507,10 @@ const char *idris_getArg(int i);
507// disable stdin/stdout buffering
507// disable stdin/stdout buffering
508void idris_disableBuffering(void);
508void idris_disableBuffering(void);
509
509
510+#ifndef SEL4
511+int idris_usleep(int usec);
512+#endif // SEL4
513+
510// Handle stack overflow.
514// Handle stack overflow.
511// Just reports an error and exits.
515// Just reports an error and exits.
512
516
rts/idris_stdfgn.c+2−12
@@ -74,13 +74,13 @@ VAL fileAccessTime(void* h) {
74 }
74 }
75}
75}
76
76
77−VAL fileModifiedTime(VM* vm, void* h) {
77+VAL fileModifiedTime(void* h) {
78 FILE* f = (FILE*)h;
78 FILE* f = (FILE*)h;
79 int fd = fileno(f);
79 int fd = fileno(f);
80
80
81 struct stat buf;
81 struct stat buf;
82 if (fstat(fd, &buf) == 0) {
82 if (fstat(fd, &buf) == 0) {
83− return MKBIGUI(vm, buf.st_mtime);
83+ return MKBIGI(buf.st_mtime);
84 } else {
84 } else {
85 return MKBIGI(-1);
85 return MKBIGI(-1);
86 }
86 }
@@ -228,16 +228,6 @@ VAL idris_clock(VM* vm) {
228 return result;
228 return result;
229}
229}
230
230
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−
241VAL idris_mkFileError(VM* vm) {
231VAL idris_mkFileError(VM* vm) {
242 VAL result;
232 VAL result;
243 switch(errno) {
233 switch(errno) {
rts/idris_stdfgn.h+1−4
@@ -18,7 +18,7 @@ int fileSize(void* h);
18
18
19// Return a negative number if not a file (e.g. directory or device)
19// Return a negative number if not a file (e.g. directory or device)
20VAL fileAccessTime(void* h);
20VAL fileAccessTime(void* h);
21−VAL fileModifiedTime(VM* vm, void* h);
21+VAL fileModifiedTime(void* h);
22VAL fileStatusTime(void* h);
22VAL fileStatusTime(void* h);
23
23
24void* idris_dirOpen(char* dname);
24void* idris_dirOpen(char* dname);
@@ -54,9 +54,6 @@ char* getEnvPair(int i);
54
54
55VAL idris_time();
55VAL idris_time();
56VAL idris_clock(VM* vm);
56VAL idris_clock(VM* vm);
57−#ifndef SEL4
58−int idris_usleep(int usec);
59−#endif // SEL4
60
57
61void idris_forceGC();
58void idris_forceGC();
62
59
rts/idris_utf8.c+1
@@ -1,4 +1,5 @@
1#include "idris_utf8.h"
1#include "idris_utf8.h"
2+#include <stdio.h>
2#include <string.h>
3#include <string.h>
3#include <stdlib.h>
4#include <stdlib.h>
4
5
src/Idris/Core/TT.hs+1−1
@@ -325,7 +325,7 @@ bindTC x k = case x of
325instance Monad TC where
325instance Monad TC where
326 return x = OK x
326 return x = OK x
327 x >>= k = bindTC x k
327 x >>= k = bindTC x k
328−#if !(MIN_VERSION_base(4,13,0))
328+#if !(MIN_VERSION_base(4,12,0))
329 fail = Fail.fail
329 fail = Fail.fail
330#endif
330#endif
331
331
src/Idris/Parser/Stack.hs+1−14
@@ -5,7 +5,7 @@ Description : Idris parser stack and its primitives.
5License : BSD3
5License : BSD3
6Maintainer : The Idris Community.
6Maintainer : The Idris Community.
7-}
7-}
8−{-# LANGUAGE CPP, ConstraintKinds, FlexibleContexts, MultiParamTypeClasses #-}
8+{-# LANGUAGE ConstraintKinds, FlexibleContexts, MultiParamTypeClasses #-}
9module Idris.Parser.Stack
9module Idris.Parser.Stack
10 ( -- * Parsing
10 ( -- * Parsing
11 Parser(..)
11 Parser(..)
@@ -77,20 +77,11 @@ parseErrorOffset = P.errorOffset . parseError
77instance Message ParseError where
77instance Message ParseError where
78 messageExtent err = sourcePositionFC pos
78 messageExtent err = sourcePositionFC pos
79 where
79 where
80−#if MIN_VERSION_megaparsec(8,0,0)
81− P.PosState {P.pstateSourcePos = pos} =
82− P.reachOffsetNoLine (parseErrorOffset err) (parseErrorPosState err)
83−#else
84 (pos, _) = P.reachOffsetNoLine (parseErrorOffset err) (parseErrorPosState err)
80 (pos, _) = P.reachOffsetNoLine (parseErrorOffset err) (parseErrorPosState err)
85−#endif
86 messageText = PP.text . init . P.parseErrorTextPretty . parseError
81 messageText = PP.text . init . P.parseErrorTextPretty . parseError
87 messageSource err = Just sline
82 messageSource err = Just sline
88 where
83 where
89−#if MIN_VERSION_megaparsec(8,0,0)
90− (sline, _) = P.reachOffset (parseErrorOffset err) (parseErrorPosState err)
91−#else
92 (_, sline, _) = P.reachOffset (parseErrorOffset err) (parseErrorPosState err)
84 (_, sline, _) = P.reachOffset (parseErrorOffset err) (parseErrorPosState err)
93−#endif
94
85
95-- | A fully formatted parse error, with caret and bar, etc.
86-- | A fully formatted parse error, with caret and bar, etc.
96prettyError :: ParseError -> String
87prettyError :: ParseError -> String
@@ -98,11 +89,7 @@ prettyError = P.errorBundlePretty . unParseError
98
89
99{- * Mark and restore -}
90{- * Mark and restore -}
100
91
101−#if MIN_VERSION_megaparsec(8,0,0)
102−type Mark = P.State String Void
103−#else
104type Mark = P.State String
92type Mark = P.State String
105−#endif
106
93
107-- | Retrieve the parser state so we can restart from this point later.
94-- | Retrieve the parser state so we can restart from this point later.
108mark :: Parsing m => m Mark
95mark :: Parsing m => m Mark
stack-11.22.yamldeleted−21
@@ -1,21 +0,0 @@
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.yamldeleted−20
@@ -1,20 +0,0 @@
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.yamldeleted−17
@@ -1,17 +0,0 @@
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.yamldeleted−17
@@ -1,17 +0,0 @@
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.yamlnew file+25
@@ -0,0 +1,25 @@
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 120000 → 100644+24−1
@@ -1 +0,0 @@
1−stack-15.4.yaml
@@ -0,0 +1,24 @@
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